From 245e4c6573fc6b45ca7d35a5ced3b8c0ea5921dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=9D=E7=91=AA=E8=B2=93?= Date: Tue, 4 Aug 2020 09:55:27 +0800 Subject: [PATCH] Added the get_summary_categories() utility and put the categories in the transaction forms in the accounting application. --- .../accounting/transactions/expense/form.html | 4 +- .../accounting/transactions/income/form.html | 4 +- .../transactions/transfer/form.html | 7 +-- accounting/utils.py | 51 ++++++++++++++++++- accounting/views.py | 4 +- 5 files changed, 56 insertions(+), 14 deletions(-) diff --git a/accounting/templates/accounting/transactions/expense/form.html b/accounting/templates/accounting/transactions/expense/form.html index 340a49f..36c60fc 100644 --- a/accounting/templates/accounting/transactions/expense/form.html +++ b/accounting/templates/accounting/transactions/expense/form.html @@ -44,9 +44,7 @@ First written: 2020/7/23 {# TODO: To be done #} - - - +
diff --git a/accounting/templates/accounting/transactions/income/form.html b/accounting/templates/accounting/transactions/income/form.html index ab6b86a..34bc60f 100644 --- a/accounting/templates/accounting/transactions/income/form.html +++ b/accounting/templates/accounting/transactions/income/form.html @@ -44,9 +44,7 @@ First written: 2020/7/23 {# TODO: To be done #} - - - +
diff --git a/accounting/templates/accounting/transactions/transfer/form.html b/accounting/templates/accounting/transactions/transfer/form.html index 5c56408..7bf3599 100644 --- a/accounting/templates/accounting/transactions/transfer/form.html +++ b/accounting/templates/accounting/transactions/transfer/form.html @@ -44,12 +44,7 @@ First written: 2020/7/23 {# TODO: To be done #} - - - - - - +
diff --git a/accounting/utils.py b/accounting/utils.py index 9dde5e8..ecfd6f2 100644 --- a/accounting/utils.py +++ b/accounting/utils.py @@ -18,11 +18,14 @@ """The utilities of the accounting application. """ +import json import re from django.conf import settings from django.core.exceptions import ObjectDoesNotExist -from django.db.models import Q, Sum, Case, When, F, Count, Max, Min +from django.db.models import Q, Sum, Case, When, F, Count, Max, Min, Value, \ + CharField +from django.db.models.functions import StrIndex, Left from django.urls import reverse from django.utils import timezone from django.utils.translation import pgettext @@ -319,6 +322,52 @@ def find_order_holes(records): record.has_order_hole = record.transaction.date in holes +def get_summary_categories(): + """Finds and returns the summary categories and their corresponding account + hints. + + Returns: + dict[str,str]: The summary categories and their account hints, by + 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\ + .filter( + ~Q(account__code__startswith="114"), + ~Q(account__code__startswith="214"), + ~Q(account__code__startswith="128"), + ~Q(account__code__startswith="228"), + filters[cat_type])\ + .annotate(category=Left("summary", + StrIndex("summary", Value("—")) - 1, + output_field=CharField()))\ + .values("category", "account__code", "is_credit")\ + .annotate(count=Count("category"))\ + .order_by("category", "is_credit", "-count", "account__code") + for row in rows: + rec_type = "credit" if row["is_credit"] else "debit" + if cat_type not in categories[rec_type]: + categories[rec_type][cat_type] = {} + if row["category"] not in categories[rec_type][cat_type]: + categories[rec_type][cat_type][row["category"]]\ + = row["account__code"] + return {F"{r}-{t}": json.dumps( + [{"category": c, "account": categories[r][t][c]} + for c in categories[r][t]]) + for r in categories + for t in categories[r]} + + def fill_txn_from_post(txn_type, txn, post): """Fills the transaction from the POSTed data. The POSTed data must be validated and clean at this moment. diff --git a/accounting/views.py b/accounting/views.py index 02e709c..fb5ab9f 100644 --- a/accounting/views.py +++ b/accounting/views.py @@ -42,7 +42,8 @@ from .models import Record, Transaction, Account from .utils import ReportUrl, get_cash_accounts, get_ledger_accounts, \ find_imbalanced, find_order_holes, fill_txn_from_post, \ sort_post_txn_records, make_txn_form_from_status, \ - make_txn_form_from_model, make_txn_form_from_post, MonthlySummary + make_txn_form_from_model, make_txn_form_from_post, MonthlySummary, \ + get_summary_categories @method_decorator(require_GET, name="dispatch") @@ -836,6 +837,7 @@ def txn_edit(request, txn_type, txn=None): form = make_txn_form_from_model(txn_type, txn) return render(request, F"accounting/transactions/{txn_type}/form.html", { "item": form, + "summary_categories": get_summary_categories, })