Added the get_summary_categories() utility and put the categories in the transaction forms in the accounting application.
This commit is contained in:
parent
12d4af06a0
commit
245e4c6573
@ -44,9 +44,7 @@ First written: 2020/7/23
|
|||||||
{# TODO: To be done #}
|
{# TODO: To be done #}
|
||||||
<input id="l10n-messages" type="hidden" value="{{ l10n_messages }}" />
|
<input id="l10n-messages" type="hidden" value="{{ l10n_messages }}" />
|
||||||
<input id="account-option-url" type="hidden" value="{% url "accounting:accounts.options" %}" />
|
<input id="account-option-url" type="hidden" value="{% url "accounting:accounts.options" %}" />
|
||||||
<input id="debit-general-categories" type="hidden" value="{{ debit_general_categories }}" />
|
<input id="summary-categories" type="hidden" value="{{ summary_categories }}" />
|
||||||
<input id="debit-travel-categories" type="hidden" value="{{ debit_travel_categories }}" />
|
|
||||||
<input id="debit-bus-categories" type="hidden" value="{{ debit_bus_categories }}" />
|
|
||||||
<div class="row form-group">
|
<div class="row form-group">
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
<label for="txn-date">{% trans "Date:" context "Accounting|" as text %}{{ text|force_escape }}</label>
|
<label for="txn-date">{% trans "Date:" context "Accounting|" as text %}{{ text|force_escape }}</label>
|
||||||
|
@ -44,9 +44,7 @@ First written: 2020/7/23
|
|||||||
{# TODO: To be done #}
|
{# TODO: To be done #}
|
||||||
<input id="l10n-messages" type="hidden" value="{{ l10n_messages }}" />
|
<input id="l10n-messages" type="hidden" value="{{ l10n_messages }}" />
|
||||||
<input id="account-option-url" type="hidden" value="{% url "accounting:accounts.options" %}" />
|
<input id="account-option-url" type="hidden" value="{% url "accounting:accounts.options" %}" />
|
||||||
<input id="credit-general-categories" type="hidden" value="{{ credit_general_categories }}" />
|
<input id="summary-categories" type="hidden" value="{{ summary_categories }}" />
|
||||||
<input id="credit-travel-categories" type="hidden" value="{{ credit_travel_categories }}" />
|
|
||||||
<input id="credit-bus-categories" type="hidden" value="{{ credit_bus_categories }}" />
|
|
||||||
<div class="row form-group">
|
<div class="row form-group">
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
<label for="txn-date">{% trans "Date:" context "Accounting|" as text %}{{ text|force_escape }}</label>
|
<label for="txn-date">{% trans "Date:" context "Accounting|" as text %}{{ text|force_escape }}</label>
|
||||||
|
@ -44,12 +44,7 @@ First written: 2020/7/23
|
|||||||
{# TODO: To be done #}
|
{# TODO: To be done #}
|
||||||
<input id="l10n-messages" type="hidden" value="{{ l10n_messages }}" />
|
<input id="l10n-messages" type="hidden" value="{{ l10n_messages }}" />
|
||||||
<input id="account-option-url" type="hidden" value="{% url "accounting:accounts.options" %}" />
|
<input id="account-option-url" type="hidden" value="{% url "accounting:accounts.options" %}" />
|
||||||
<input id="debit-general-categories" type="hidden" value="{{ debit_general_categories }}" />
|
<input id="summary-categories" type="hidden" value="{{ summary_categories }}" />
|
||||||
<input id="debit-travel-categories" type="hidden" value="{{ debit_travel_categories }}" />
|
|
||||||
<input id="debit-bus-categories" type="hidden" value="{{ debit_bus_categories }}" />
|
|
||||||
<input id="credit-general-categories" type="hidden" value="{{ credit_general_categories }}" />
|
|
||||||
<input id="credit-travel-categories" type="hidden" value="{{ credit_travel_categories }}" />
|
|
||||||
<input id="credit-bus-categories" type="hidden" value="{{ credit_bus_categories }}" />
|
|
||||||
<div class="row form-group">
|
<div class="row form-group">
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
<label for="txn-date">{% trans "Date:" context "Accounting|" as text %}{{ text|force_escape }}</label>
|
<label for="txn-date">{% trans "Date:" context "Accounting|" as text %}{{ text|force_escape }}</label>
|
||||||
|
@ -18,11 +18,14 @@
|
|||||||
"""The utilities of the accounting application.
|
"""The utilities of the accounting application.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
import json
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
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.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import pgettext
|
from django.utils.translation import pgettext
|
||||||
@ -319,6 +322,52 @@ def find_order_holes(records):
|
|||||||
record.has_order_hole = record.transaction.date in holes
|
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):
|
def fill_txn_from_post(txn_type, txn, post):
|
||||||
"""Fills the transaction from the POSTed data. The POSTed data must be
|
"""Fills the transaction from the POSTed data. The POSTed data must be
|
||||||
validated and clean at this moment.
|
validated and clean at this moment.
|
||||||
|
@ -42,7 +42,8 @@ from .models import Record, Transaction, Account
|
|||||||
from .utils import ReportUrl, get_cash_accounts, get_ledger_accounts, \
|
from .utils import ReportUrl, get_cash_accounts, get_ledger_accounts, \
|
||||||
find_imbalanced, find_order_holes, fill_txn_from_post, \
|
find_imbalanced, find_order_holes, fill_txn_from_post, \
|
||||||
sort_post_txn_records, make_txn_form_from_status, \
|
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")
|
@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)
|
form = make_txn_form_from_model(txn_type, txn)
|
||||||
return render(request, F"accounting/transactions/{txn_type}/form.html", {
|
return render(request, F"accounting/transactions/{txn_type}/form.html", {
|
||||||
"item": form,
|
"item": form,
|
||||||
|
"summary_categories": get_summary_categories,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user