Added the balance sheet in the accounting application.
This commit is contained in:
parent
c2c8ee66ab
commit
a18df0e928
@ -152,7 +152,7 @@
|
|||||||
}
|
}
|
||||||
.balance-sheet-table tbody {
|
.balance-sheet-table tbody {
|
||||||
}
|
}
|
||||||
.balance-sheet-table .second-level-header {
|
.balance-sheet-table .group-title {
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
}
|
}
|
||||||
@ -181,7 +181,7 @@
|
|||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
border-bottom: thick double slategray;
|
border-bottom: thick double slategray;
|
||||||
}
|
}
|
||||||
.balance-sheet-list .second-level-header {
|
.balance-sheet-list .group-title {
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
}
|
}
|
||||||
|
330
accounting/templates/accounting/balance-sheet.html
Normal file
330
accounting/templates/accounting/balance-sheet.html
Normal file
@ -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 %}
|
||||||
|
|
||||||
|
<div class="btn-group btn-actions">
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
|
||||||
|
<i class="fas fa-edit"></i>
|
||||||
|
{% trans "New" context "Accounting|" as text %}
|
||||||
|
{{ text|force_escape }}
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu">
|
||||||
|
{% url "accounting:transaction.create" "expense" as url %}
|
||||||
|
<a class="dropdown-item" href="{% url_query url r=request.get_full_path %}">
|
||||||
|
{% trans "Cash Expense" context "Accounting|" as text %}
|
||||||
|
{{ text|force_escape }}
|
||||||
|
</a>
|
||||||
|
{% url "accounting:transaction.create" "income" as url %}
|
||||||
|
<a class="dropdown-item" href="{% url_query url r=request.get_full_path %}">
|
||||||
|
{% trans "Cash Income" context "Accounting|" as text %}
|
||||||
|
{{ text|force_escape }}
|
||||||
|
</a>
|
||||||
|
{% url "accounting:transaction.create" "transfer" as url %}
|
||||||
|
<a class="dropdown-item" href="{% url_query url r=request.get_full_path %}">
|
||||||
|
{% trans "Transfer" context "Accounting|" as text %}
|
||||||
|
{{ text|force_escape }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% with current_report_icon="fas fa-balance-scale" %}
|
||||||
|
{% trans "Balance Sheet" context "Accounting|" as current_report_title %}
|
||||||
|
{% include "accounting/include/report-chooser.html" %}
|
||||||
|
{% endwith %}
|
||||||
|
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#period-modal">
|
||||||
|
<i class="far fa-calendar-alt"></i>
|
||||||
|
<span class="d-none d-md-inline">{{ period.description }}</span>
|
||||||
|
<span class="d-md-none">{% trans "Period" context "Period|" as text %}{{ text|force_escape }}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% include "mia_core/include/period-chooser.html" %}
|
||||||
|
|
||||||
|
{# The table for large screens #}
|
||||||
|
<div class="d-none d-lg-block report-block report-block-lg">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<h2>{{ title|escape }}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<table class="table table-borderless table-hover table-sm balance-sheet-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th colspan="3" scope="col">{{ section_1.title|title }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for group in section_1.groups %}
|
||||||
|
<tr class="group-title">
|
||||||
|
<td><div>{{ group.title|title }}</div></td>
|
||||||
|
<td class="amount"></td>
|
||||||
|
<td class="actions"></td>
|
||||||
|
</tr>
|
||||||
|
{% for item in group.details %}
|
||||||
|
<tr>
|
||||||
|
<td><div class="subject">{{ item.title|title }}</div></td>
|
||||||
|
<td class="amount {% if item.balance < 0 %} text-danger {% endif %}">{{ item.balance|accounting_amount }}</td>
|
||||||
|
<td class="actions">
|
||||||
|
<a href="{% url "accounting:ledger" item.code period.spec %}" class="btn btn-info" role="button">
|
||||||
|
<i class="fas fa-eye"></i>
|
||||||
|
{% trans "View" context "Accounting|" as text %}{{ text|force_escape }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<table class="table table-borderless table-hover table-sm balance-sheet-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th colspan="3" scope="col">{{ section_2.title|title }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for group in section_2.groups %}
|
||||||
|
<tr class="group-title">
|
||||||
|
<td><div>{{ group.title|title }}</div></td>
|
||||||
|
<td class="amount"></td>
|
||||||
|
<td class="actions"></td>
|
||||||
|
</tr>
|
||||||
|
{% for item in group.details %}
|
||||||
|
<tr>
|
||||||
|
<td><div class="subject">{{ item.title|title }}</div></td>
|
||||||
|
<td class="amount {% if item.balance < 0 %} text-danger {% endif %}">{{ item.balance|accounting_amount }}</td>
|
||||||
|
<td class="actions">
|
||||||
|
<a href="{% url "accounting:ledger" item.code period.spec %}" class="btn btn-info" role="button">
|
||||||
|
<i class="fas fa-eye"></i>
|
||||||
|
{% trans "View" context "Accounting|" as text %}{{ text|force_escape }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr class="total">
|
||||||
|
<td>{% trans "Total" context "Accounting|" as text %}{{ text|force_escape }}</td>
|
||||||
|
<td class="amount {% if section_2.balance < 0 %} text-danger {% endif %}">
|
||||||
|
{{ section_2.balance|accounting_amount }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table class="table table-borderless table-hover table-sm balance-sheet-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th colspan="3" scope="col">{{ section_3.title|title }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for group in section_3.groups %}
|
||||||
|
<tr class="group-title">
|
||||||
|
<td><div>{{ group.title|title }}</div></td>
|
||||||
|
<td class="amount"></td>
|
||||||
|
<td class="actions"></td>
|
||||||
|
</tr>
|
||||||
|
{% for item in group.details %}
|
||||||
|
<tr>
|
||||||
|
<td><div class="subject">{{ item.title|title }}</div></td>
|
||||||
|
<td class="amount {% if item.balance < 0 %} text-danger {% endif %}">{{ item.balance|accounting_amount }}</td>
|
||||||
|
<td class="actions">
|
||||||
|
<a href="{% url "accounting:ledger" item.code period.spec %}" class="btn btn-info" role="button">
|
||||||
|
<i class="fas fa-eye"></i>
|
||||||
|
{% trans "View" context "Accounting|" as text %}{{ text|force_escape }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr class="total">
|
||||||
|
<td>{% trans "Total" context "Accounting|" as text %}{{ text|force_escape }}</td>
|
||||||
|
<td class="amount {% if section_3.balance < 0 %} text-danger {% endif %}">
|
||||||
|
{{ section_3.balance|accounting_amount }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6 assets-total">
|
||||||
|
<table class="table table-borderless table-hover table-sm balance-sheet-total-table">
|
||||||
|
<tfoot>
|
||||||
|
<tr class="total">
|
||||||
|
<td class="align-middle">{% trans "Total" context "Accounting|" as text %}{{ text|force_escape }}</td>
|
||||||
|
<td class="text-right align-middle font-italic {% if section_1.balance < 0 %} text-danger {% endif %}">
|
||||||
|
{{ section_1.balance|accounting_amount }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-6 liabilities-total">
|
||||||
|
<table class="table table-borderless table-hover table-sm balance-sheet-total-table">
|
||||||
|
<tfoot>
|
||||||
|
<tr class="total">
|
||||||
|
<td class="align-middle">{% trans "Total" context "Accounting|" as text %}{{ text|force_escape }}</td>
|
||||||
|
<td class="text-right align-middle font-italic {% if section_2.balance|add:section_3.balance < 0 %} text-danger {% endif %}">
|
||||||
|
{{ section_2.balance|add:section_3.balance|accounting_amount }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# The list for small screens #}
|
||||||
|
<div class="d-lg-none report-block report-block-sm">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<h2>{{ title|escape }}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ul class="list-group balance-sheet-list">
|
||||||
|
<li class="list-group-item section-title">
|
||||||
|
{{ section_1.title|title }}
|
||||||
|
</li>
|
||||||
|
{% for group in section_1.groups %}
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-center group-title">
|
||||||
|
{{ group.title|title }}
|
||||||
|
</li>
|
||||||
|
{% for item in group.details %}
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-center subject">
|
||||||
|
<a class="list-group-item-action" href="{% url "accounting:ledger" item.code period.spec %}">
|
||||||
|
{{ item.title|title }}
|
||||||
|
<div class="float-right">
|
||||||
|
<span class="badge {% if item.balance < 0 %} badge-warning {% else %} badge-secondary {% endif %} badge-pill">
|
||||||
|
{{ item.balance|accounting_amount }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-center grand-total">
|
||||||
|
{% trans "Total" context "Accounting|" as text %}{{ text|force_escape }}
|
||||||
|
<span class="badge {% if section_1.balance < 0 %} badge-danger {% else %} badge-info {% endif %} badge-pill">
|
||||||
|
{{ section_1.balance|accounting_amount }}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ul class="list-group balance-sheet-list">
|
||||||
|
<li class="list-group-item section-title">
|
||||||
|
{{ section_2.title|title }}
|
||||||
|
</li>
|
||||||
|
{% for group in section_2.groups %}
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-center group-title">
|
||||||
|
{{ group.title|title }}
|
||||||
|
</li>
|
||||||
|
{% for item in group.details %}
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-center subject">
|
||||||
|
<a class="list-group-item-action" href="{% url "accounting:ledger" item.code period.spec %}">
|
||||||
|
{{ item.title|title }}
|
||||||
|
<div class="float-right">
|
||||||
|
<span class="badge {% if item.balance < 0 %} badge-warning {% else %} badge-secondary {% endif %} badge-pill">
|
||||||
|
{{ item.balance|accounting_amount }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-center total">
|
||||||
|
{% trans "Total" context "Accounting|" as text %}{{ text|force_escape }}
|
||||||
|
<span class="badge {% if section_2.balance < 0 %} badge-danger {% else %} badge-info {% endif %} badge-pill">
|
||||||
|
{{ section_2.balance|accounting_amount }}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul class="list-group balance-sheet-list">
|
||||||
|
<li class="list-group-item section-title">
|
||||||
|
{{ section_3.title|title }}
|
||||||
|
</li>
|
||||||
|
{% for group in section_3.groups %}
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-center group-title">
|
||||||
|
{{ group.title|title }}
|
||||||
|
</li>
|
||||||
|
{% for item in group.details %}
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-center subject">
|
||||||
|
<a class="list-group-item-action" href="{% url "accounting:ledger" item.code period.spec %}">
|
||||||
|
{{ item.title|title }}
|
||||||
|
<div class="float-right">
|
||||||
|
<span class="badge {% if item.balance < 0 %} badge-warning {% else %} badge-secondary {% endif %} badge-pill">
|
||||||
|
{{ item.balance|accounting_amount }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-center total">
|
||||||
|
{% trans "Total" context "Accounting|" as text %}{{ text|force_escape }}
|
||||||
|
<span class="badge {% if section_3.balance < 0 %} badge-danger {% else %} badge-info {% endif %} badge-pill">
|
||||||
|
{{ section_3.balance|accounting_amount }}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul class="list-group balance-sheet-list">
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-center grand-total">
|
||||||
|
{% trans "Total" context "Accounting|" as text %}{{ text|force_escape }}
|
||||||
|
<span class="badge {% if section_2.balance|add:section_3.balance < 0 %} badge-danger {% else %} badge-info {% endif %} badge-pill">
|
||||||
|
{{ section_2.balance|add:section_3.balance|accounting_amount }}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -71,7 +71,7 @@ urlpatterns = [
|
|||||||
path("balance-sheet",
|
path("balance-sheet",
|
||||||
mia_core_views.todo, name="balance-sheet.home"),
|
mia_core_views.todo, name="balance-sheet.home"),
|
||||||
path("balance-sheet/<str:period_spec>",
|
path("balance-sheet/<str:period_spec>",
|
||||||
mia_core_views.todo, name="balance-sheet"),
|
views.balance_sheet, name="balance-sheet"),
|
||||||
path("search",
|
path("search",
|
||||||
mia_core_views.todo, name="search"),
|
mia_core_views.todo, name="search"),
|
||||||
path("transactions/<txn-type:type>/create",
|
path("transactions/<txn-type:type>/create",
|
||||||
|
@ -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,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user