From a18df0e928866d8e82c958011d31258443257c82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=9D=E7=91=AA=E8=B2=93?= Date: Tue, 21 Jul 2020 00:31:31 +0800 Subject: [PATCH] Added the balance sheet in the accounting application. --- accounting/static/accounting/css/report.css | 4 +- .../templates/accounting/balance-sheet.html | 330 ++++++++++++++++++ accounting/urls.py | 2 +- accounting/views/__init__.py | 72 ++++ 4 files changed, 405 insertions(+), 3 deletions(-) create mode 100644 accounting/templates/accounting/balance-sheet.html diff --git a/accounting/static/accounting/css/report.css b/accounting/static/accounting/css/report.css index 770d775..5861d6c 100644 --- a/accounting/static/accounting/css/report.css +++ b/accounting/static/accounting/css/report.css @@ -152,7 +152,7 @@ } .balance-sheet-table tbody { } -.balance-sheet-table .second-level-header { +.balance-sheet-table .group-title { font-size: 1.1em; font-weight: bolder; } @@ -181,7 +181,7 @@ font-weight: bolder; border-bottom: thick double slategray; } -.balance-sheet-list .second-level-header { +.balance-sheet-list .group-title { font-size: 1.1em; font-weight: bolder; } diff --git a/accounting/templates/accounting/balance-sheet.html b/accounting/templates/accounting/balance-sheet.html new file mode 100644 index 0000000..5b97c4f --- /dev/null +++ b/accounting/templates/accounting/balance-sheet.html @@ -0,0 +1,330 @@ +{% extends "base.html" %} +{% comment %} +The Mia Accounting Application +cash.html: The template for the cash account 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/20 +{% endcomment %} +{% load static %} +{% load i18n %} +{% load humanize %} +{% load mia_core %} +{% load accounting %} + +{% block settings %} + {% blocktrans asvar title with period=period.description context "Accounting|" %}Balance Sheet in {{ period }}{% endblocktrans %} + {% setvar "title" title %} + {% setvar "use_period_chooser" True %} + {% static "accounting/css/report.css" as css %} + {% setvar "css" css %} +{% endblock %} + +{% block content %} + +
+
+ + +
+ {% with current_report_icon="fas fa-balance-scale" %} + {% trans "Balance Sheet" context "Accounting|" as current_report_title %} + {% include "accounting/include/report-chooser.html" %} + {% endwith %} + +
+ +{% include "mia_core/include/period-chooser.html" %} + +{# The table for large screens #} +
+
+

{{ title|escape }}

+
+ +
+
+ + + + + + + + {% for group in section_1.groups %} + + + + + + {% for item in group.details %} + + + + + + {% endfor %} + {% endfor %} + +
{{ section_1.title|title }}
{{ group.title|title }}
{{ item.title|title }}
{{ item.balance|accounting_amount }} + + + {% trans "View" context "Accounting|" as text %}{{ text|force_escape }} + +
+
+ +
+ + + + + + + + {% for group in section_2.groups %} + + + + + + {% for item in group.details %} + + + + + + {% endfor %} + {% endfor %} + + + + + + + +
{{ section_2.title|title }}
{{ group.title|title }}
{{ item.title|title }}
{{ item.balance|accounting_amount }} + + + {% trans "View" context "Accounting|" as text %}{{ text|force_escape }} + +
{% trans "Total" context "Accounting|" as text %}{{ text|force_escape }} + {{ section_2.balance|accounting_amount }} +
+ + + + + + + + + {% for group in section_3.groups %} + + + + + + {% for item in group.details %} + + + + + + {% endfor %} + {% endfor %} + + + + + + + +
{{ section_3.title|title }}
{{ group.title|title }}
{{ item.title|title }}
{{ item.balance|accounting_amount }} + + + {% trans "View" context "Accounting|" as text %}{{ text|force_escape }} + +
{% trans "Total" context "Accounting|" as text %}{{ text|force_escape }} + {{ section_3.balance|accounting_amount }} +
+
+
+ +
+
+ + + + + + + +
{% trans "Total" context "Accounting|" as text %}{{ text|force_escape }} + {{ section_1.balance|accounting_amount }} +
+
+ +
+ + + + + + + +
{% trans "Total" context "Accounting|" as text %}{{ text|force_escape }} + {{ section_2.balance|add:section_3.balance|accounting_amount }} +
+
+
+
+ +{# The list for small screens #} +
+
+

{{ title|escape }}

+
+ +
+
+
    +
  • + {{ section_1.title|title }} +
  • + {% for group in section_1.groups %} +
  • + {{ group.title|title }} +
  • + {% for item in group.details %} +
  • + + {{ item.title|title }} +
    + + {{ item.balance|accounting_amount }} + +
    +
    +
  • + {% endfor %} + {% endfor %} +
  • + {% trans "Total" context "Accounting|" as text %}{{ text|force_escape }} + + {{ section_1.balance|accounting_amount }} + +
  • +
+
+ +
+
    +
  • + {{ section_2.title|title }} +
  • + {% for group in section_2.groups %} +
  • + {{ group.title|title }} +
  • + {% for item in group.details %} +
  • + + {{ item.title|title }} +
    + + {{ item.balance|accounting_amount }} + +
    +
    +
  • + {% endfor %} + {% endfor %} +
  • + {% trans "Total" context "Accounting|" as text %}{{ text|force_escape }} + + {{ section_2.balance|accounting_amount }} + +
  • +
+ +
    +
  • + {{ section_3.title|title }} +
  • + {% for group in section_3.groups %} +
  • + {{ group.title|title }} +
  • + {% for item in group.details %} +
  • + + {{ item.title|title }} +
    + + {{ item.balance|accounting_amount }} + +
    +
    +
  • + {% endfor %} + {% endfor %} +
  • + {% trans "Total" context "Accounting|" as text %}{{ text|force_escape }} + + {{ section_3.balance|accounting_amount }} + +
  • +
+ +
    +
  • + {% trans "Total" context "Accounting|" as text %}{{ text|force_escape }} + + {{ section_2.balance|add:section_3.balance|accounting_amount }} + +
  • +
+
+
+
+ +{% endblock %} diff --git a/accounting/urls.py b/accounting/urls.py index 244bf52..7313d9f 100644 --- a/accounting/urls.py +++ b/accounting/urls.py @@ -71,7 +71,7 @@ urlpatterns = [ path("balance-sheet", mia_core_views.todo, name="balance-sheet.home"), path("balance-sheet/", - mia_core_views.todo, name="balance-sheet"), + views.balance_sheet, name="balance-sheet"), path("search", mia_core_views.todo, name="search"), path("transactions//create", diff --git a/accounting/views/__init__.py b/accounting/views/__init__.py index 8286729..52fb9d9 100644 --- a/accounting/views/__init__.py +++ b/accounting/views/__init__.py @@ -637,4 +637,76 @@ def income_statement(request, period_spec): }) +@require_GET +@digest_login_required +def balance_sheet(request, period_spec): + """The balance sheet.""" + # The period + period = _get_period(period_spec) + # The accounts + accounts = list( + Subject.objects + .filter(Q(record__transaction__date__lte=period.end), + (Q(code__startswith="1") + | Q(code__startswith="2") + | Q(code__startswith="3")), + ~Q(code="3351")) + .annotate( + balance=Sum(Case( + When(record__is_credit=True, then=-1), + default=1) * F("record__amount"))) + .filter(balance__isnull=False)) + balance = Record.objects\ + .filter( + Q(transaction__date__lt=period.start) + & ~((Q(subject__code__startswith="1") + | Q(subject__code__startswith="2") + | Q(subject__code__startswith="3")) + & ~Q(subject__code="3351")))\ + .aggregate( + balance=Sum(Case( + When(is_credit=True, then=-1), + default=1) * F("amount")))["balance"] + if balance is not None and balance != 0: + brought_forward = Subject.objects.get(code="3351") + brought_forward.balance = -balance + accounts.append(brought_forward) + balance = Record.objects\ + .filter( + Q(transaction__date__gte=period.start) + & Q(transaction__date__lte=period.end) + & ~((Q(subject__code__startswith="1") + | Q(subject__code__startswith="2") + | Q(subject__code__startswith="3")) + & ~Q(subject__code="3351")))\ + .aggregate( + balance=Sum(Case( + When(is_credit=True, then=-1), + default=1) * F("amount")))["balance"] + if balance is not None and balance != 0: + net_income = Subject.objects.get(code="3353") + net_income.balance = -balance + accounts.append(net_income) + groups = list(Subject.objects.filter( + code__in=[x.code[:2] for x in accounts])) + sections = list(Subject.objects.filter( + Q(code="1") | Q(code="2") | Q(code="3")).order_by("code")) + for section in sections: + section.groups = [x for x in groups + if x.code[:1] == section.code] + for group in section.groups: + group.details = [x for x in accounts + if x.code[:2] == group.code] + group.balance = sum([x.balance + for x in group.details]) + section.balance = sum([x.balance for x in section.groups]) + by_code = {x.code: x for x in sections} + return render(request, "accounting/balance-sheet.html", { + "section_1": by_code["1"], + "section_2": by_code["2"], + "section_3": by_code["3"], + "reports": ReportUrl(period=period), + "period": period, + }) +