From 70c3f0136875c96e7a6749385863c8ab766527c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=9D=E7=91=AA=E8=B2=93?= Date: Fri, 17 Jul 2020 00:12:30 +0800 Subject: [PATCH] Added the ledger summary in the accounting application. --- accounting/models.py | 5 +- .../templates/accounting/ledger_summary.html | 169 ++++++++++++++++++ accounting/urls.py | 2 +- accounting/views/__init__.py | 50 ++++++ 4 files changed, 221 insertions(+), 5 deletions(-) create mode 100644 accounting/templates/accounting/ledger_summary.html diff --git a/accounting/models.py b/accounting/models.py index c301b64..d4d25d2 100644 --- a/accounting/models.py +++ b/accounting/models.py @@ -324,6 +324,7 @@ class RecordSummary(models.Model): month = models.DateField(primary_key=True) credit_amount = models.PositiveIntegerField() debit_amount = models.PositiveIntegerField() + balance = models.IntegerField() _label = None @@ -337,10 +338,6 @@ class RecordSummary(models.Model): def label(self, value): self._label = value - @property - def balance(self): - return self.credit_amount - self.debit_amount - _cumulative_balance = None @property diff --git a/accounting/templates/accounting/ledger_summary.html b/accounting/templates/accounting/ledger_summary.html new file mode 100644 index 0000000..a1db151 --- /dev/null +++ b/accounting/templates/accounting/ledger_summary.html @@ -0,0 +1,169 @@ +{% extends "base.html" %} +{% comment %} +The Mia Accounting Application +ledger_summary.html: The template for the ledger summary reports + + Copyright (c) 2020 imacat. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +Author: imacat@mail.imacat.idv.tw (imacat) +First written: 2020/7/17 +{% endcomment %} +{% load i18n %} +{% load humanize %} +{% load mia_core %} +{% load accounting %} + +{% block settings %} + {% blocktrans asvar title with subject=current_subject.title|title context "Accounting|" %}Ledger Summary for {{ subject }}{% endblocktrans %} + {% setvar "title" title %} +{% endblock %} + +{% block content %} + +
+
+ + +
+ {% with current_report_icon="fas fa-file-invoice-dollar" %} + {% trans "Ledger Summary" context "Accounting|" as current_report_title %} + {% include "accounting/include/report-chooser.html" %} + {% endwith %} +
+ + +
+
+ +{% if records %} + {% include "mia_core/include/pagination.html" %} + + {# The table for large screens #} + + + + + + + + + + + + + {% for record in records %} + + + + + + + + + {% endfor %} + +
{% trans "Month" context "Accounting|" as text %}{{ text|force_escape }}{% trans "Debit" context "Accounting|" as text %}{{ text|force_escape }}{% trans "Credit" context "Accounting|" as text %}{{ text|force_escape }}{% trans "Balance" context "Accounting|" as text %}{{ text|force_escape }}{% trans "Cumulative Balance" context "Accounting|" as text %}{{ text|force_escape }}{% trans "View" context "Accounting|" as text %}{{ text|force_escape }}
{{ record.label }}{{ record.debit_amount|accounting_amount }}{{ record.credit_amount|accounting_amount }}{{ record.balance|accounting_amount }}{{ record.cumulative_balance|accounting_amount }} + {% if record.month is not None %} + + + {% trans "View" context "Accounting|" as text %}{{ text|force_escape }} + + {% endif %} +
+ + {# The list for small screens #} + +{% else %} +

{{ _("There is currently no data.")|force_escape }}

+{% endif %} + +{% endblock %} diff --git a/accounting/urls.py b/accounting/urls.py index 38908a0..3ea8884 100644 --- a/accounting/urls.py +++ b/accounting/urls.py @@ -55,7 +55,7 @@ urlpatterns = [ path("ledger-summary", mia_core_views.todo, name="ledger-summary.home"), path("ledger-summary/", - mia_core_views.todo, name="ledger-summary"), + views.ledger_summary, name="ledger-summary"), path("journal", mia_core_views.todo, name="journal.home"), path("journal/", diff --git a/accounting/views/__init__.py b/accounting/views/__init__.py index f82d1eb..3a076e9 100644 --- a/accounting/views/__init__.py +++ b/accounting/views/__init__.py @@ -455,3 +455,53 @@ def ledger(request, subject_code, period_spec): "reports": ReportUrl(ledger=current_subject, period=period), "subjects": subjects, }) + + +def ledger_summary(request, subject_code): + """The ledger summary report.""" + # The subject + subjects = _ledger_subjects() + current_subject = None + for subject in subjects: + if subject.code == subject_code: + current_subject = subject + if current_subject is None: + raise Http404() + if connection.vendor == "postgresql": + month_definition = "CAST(DATE_TRUNC('month', t.date) AS date)" + elif connection.vendor == "sqlite": + month_definition = "DATE(t.date, 'start of month')" + else: + month_definition = None + # The SQL query + records = list(RecordSummary.objects.raw( + f"""SELECT + {month_definition} AS month, + SUM(CASE WHEN r.is_credit THEN 0 ELSE r.amount END) AS debit_amount, + SUM(CASE WHEN r.is_credit THEN r.amount ELSE 0 END) AS credit_amount, + SUM(CASE WHEN r.is_credit THEN -1 ELSE 1 END * r.amount) AS balance +FROM accounting_records AS r + INNER JOIN accounting_transactions AS t ON r.transaction_sn = t.sn + INNER JOIN accounting_subjects AS s ON r.subject_sn = s.sn +WHERE s.code LIKE %s +GROUP BY month +ORDER BY month""", + [current_subject.code + "%"])) + cumulative_balance = 0 + for record in records: + cumulative_balance = cumulative_balance + record.balance + record.cumulative_balance = cumulative_balance + records.append(RecordSummary( + label=pgettext("Accounting|", "Total"), + credit_amount=sum([x.credit_amount for x in records]), + debit_amount=sum([x.debit_amount for x in records]), + cumulative_balance=cumulative_balance, + )) + pagination = Pagination(request, records, True) + return render(request, "accounting/ledger_summary.html", { + "records": pagination.records, + "pagination": pagination, + "current_subject": current_subject, + "reports": ReportUrl(cash=current_subject), + "subjects": subjects, + })