Rewrote the get_summary_categories() utility to only query once in the accounting application.

This commit is contained in:
依瑪貓 2020-08-04 23:26:30 +08:00
parent 8f90912146
commit 66c08fd413

View File

@ -330,42 +330,39 @@ def get_summary_categories():
dict[str,str]: The summary categories and their account hints, by dict[str,str]: The summary categories and their account hints, by
their record types and category types. their record types and category types.
""" """
filters = {
"general": Q(summary__contains="") & ~Q(summary__regex=".+—.+→.+"),
"travel": Q(summary__regex=".+—.+→.+")
& ~Q(summary__regex=".+—.+—.+→.+"),
"bus": Q(summary__regex=".+—.+—.+→.+"),
}
categories = {
"credit": {},
"debit": {},
}
for cat_type in filters:
rows = Record.objects\ rows = Record.objects\
.filter( .filter(Q(summary__contains=""),
~Q(account__code__startswith="114"), ~Q(account__code__startswith="114"),
~Q(account__code__startswith="214"), ~Q(account__code__startswith="214"),
~Q(account__code__startswith="128"), ~Q(account__code__startswith="128"),
~Q(account__code__startswith="228"), ~Q(account__code__startswith="228"))\
filters[cat_type])\ .annotate(rec_type=Case(When(is_credit=True, then=Value("credit")),
.annotate(category=Left("summary", default=Value("debit"),
output_field=CharField()),
cat_type=Case(
When(summary__regex=".+—.+—.+→.+", then=Value("bus")),
When(summary__regex=".+—.+→.+", then=Value("travel")),
default=Value("general"),
output_field=CharField()),
category=Left("summary",
StrIndex("summary", Value("")) - 1, StrIndex("summary", Value("")) - 1,
output_field=CharField()))\ output_field=CharField()))\
.values("category", "account__code", "is_credit")\ .values("rec_type", "cat_type", "category", "account__code")\
.annotate(count=Count("category"))\ .annotate(count=Count("category"))\
.order_by("category", "is_credit", "-count", "account__code") .order_by("rec_type", "cat_type", "category", "-count",
"account__code")
# Sorts the rows by the record type and the category type
categories = {}
for row in rows: for row in rows:
rec_type = "credit" if row["is_credit"] else "debit" key = "%s-%s" % (row["rec_type"], row["cat_type"])
if cat_type not in categories[rec_type]: if key not in categories:
categories[rec_type][cat_type] = {} categories[key] = {}
if row["category"] not in categories[rec_type][cat_type]: # Keeps only the first account with most records
categories[rec_type][cat_type][row["category"]]\ if row["category"] not in categories[key]:
= row["account__code"] categories[key][row["category"]] = row["account__code"]
return {F"{r}-{t}": json.dumps( # Converts the dictionary to a list, as the category may not be US-ASCII
[{"category": c, "account": categories[r][t][c]} return {t: [[c, categories[t][c]] for c in categories[t]]
for c in categories[r][t]]) for t in categories.keys()}
for r in categories
for t in categories[r]}
def fill_txn_from_post(txn_type, txn, post): def fill_txn_from_post(txn_type, txn, post):