Added the income statement in the accounting application.
This commit is contained in:
parent
6a9eb5ed0e
commit
175e28f862
198
accounting/templates/accounting/income-statement.html
Normal file
198
accounting/templates/accounting/income-statement.html
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
{% 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/1
|
||||||
|
{% endcomment %}
|
||||||
|
{% load static %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load humanize %}
|
||||||
|
{% load mia_core %}
|
||||||
|
{% load accounting %}
|
||||||
|
|
||||||
|
{% block settings %}
|
||||||
|
{% blocktrans asvar title with period=period.description context "Accounting|" %}Income Statement 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-file-invoice" %}
|
||||||
|
{% trans "Income Statement" 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" %}
|
||||||
|
|
||||||
|
{% if item_list %}
|
||||||
|
{# The table for large screens #}
|
||||||
|
<div class="d-none d-sm-block report-block report-block-lg">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<h2>{{ title }}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<table class="table table-borderless table-hover table-sm income-statement-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col"></th>
|
||||||
|
<th class="amount" colspan="2" scope="col">{% trans "Amount" context "Period|" as text %}{{ text|force_escape }}</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for section in item_list %}
|
||||||
|
<tr class="first-level-header">
|
||||||
|
<td><div>{{ section.title|title|escape }}</div></td>
|
||||||
|
<td class="amount"></td>
|
||||||
|
<td class="amount"></td>
|
||||||
|
<td class="actions"></td>
|
||||||
|
</tr>
|
||||||
|
{% for group in section.groups %}
|
||||||
|
<tr class="second-level-header">
|
||||||
|
<td><div class="second-level-header">{{ group.title|title|escape }}</div></td>
|
||||||
|
<td class="amount"></td>
|
||||||
|
<td class="amount"></td>
|
||||||
|
<td class="actions"></td>
|
||||||
|
</tr>
|
||||||
|
{% for item in group.details %}
|
||||||
|
<tr>
|
||||||
|
<td><div class="subject">{{ item.title|title|escape }}</div></td>
|
||||||
|
<td class="amount {% if item.balance < 0 %} text-danger {% endif %}">{{ item.balance|accounting_amount }}</td>
|
||||||
|
<td class="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>
|
||||||
|
<span class="d-none d-lg-inline">{% trans "View" context "Accounting|" as text %}{{ text|force_escape }}</span>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
<tr class="total">
|
||||||
|
<td><div>{% trans "Total" context "Period|" as text %}{{ text|force_escape }}</div></td>
|
||||||
|
<td class="amount"></td>
|
||||||
|
<td class="amount {% if group.total < 0 %} text-danger {% endif %}">{{ group.total|accounting_amount }}</td>
|
||||||
|
<td class="actions"></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% if section.cumulative_total is not None %}
|
||||||
|
<tr class="cum-total">
|
||||||
|
<td><div>{{ section.cumulative_total.title|title|escape }}</div></td>
|
||||||
|
<td class="amount"></td>
|
||||||
|
<td class="amount {% if section.cumulative_total.total < 0 %} text-danger {% endif %}">{{ section.cumulative_total.total|accounting_amount }}</td>
|
||||||
|
<td class="actions"></td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# The list for small screens #}
|
||||||
|
{% comment %}
|
||||||
|
<div class="d-sm-none report-block report-block-sm">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<h2>{{ title }}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<ul class="list-group income-statement-list">
|
||||||
|
{% for item in item_list %}
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-center <%=$record->class%>">
|
||||||
|
% if (!defined $record->class && defined $record->subject->code) {
|
||||||
|
<a class="list-group-item-action" href="<%=url_for("acct.ledger", {"subject_code" => $record->subject->code})%>">
|
||||||
|
<%=$record->subject->title%>
|
||||||
|
<div class="float-right">
|
||||||
|
% if (defined $record->amount) {
|
||||||
|
<span class="badge <%=$record->amount < 0? "badge-warning": "badge-secondary"%> badge-pill">
|
||||||
|
<%=format_amount($record->amount)%>
|
||||||
|
</span>
|
||||||
|
% }
|
||||||
|
% if (defined $record->total) {
|
||||||
|
<span class="badge <%=$record->total < 0? "badge-danger": "badge-info"%> badge-pill">
|
||||||
|
<%=format_amount($record->total)%>
|
||||||
|
</span>
|
||||||
|
% }
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
% } else {
|
||||||
|
<%=$record->subject->title%>
|
||||||
|
<div class="float-right">
|
||||||
|
% if (defined $record->amount) {
|
||||||
|
<span class="badge <%=$record->amount < 0? "badge-warning": "badge-secondary"%> badge-pill">
|
||||||
|
<%=format_amount($record->amount)%>
|
||||||
|
</span>
|
||||||
|
% }
|
||||||
|
% if (defined $record->total) {
|
||||||
|
<span class="badge <%=$record->total < 0? "badge-danger": "badge-info"%> badge-pill">
|
||||||
|
<%=format_amount($record->total)%>
|
||||||
|
</span>
|
||||||
|
% }
|
||||||
|
</div>
|
||||||
|
% }
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endcomment %}
|
||||||
|
{% else %}
|
||||||
|
<p>{{ _("There is currently no data.")|force_escape }}</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -67,7 +67,7 @@ urlpatterns = [
|
|||||||
path("income-statement",
|
path("income-statement",
|
||||||
mia_core_views.todo, name="income-statement.home"),
|
mia_core_views.todo, name="income-statement.home"),
|
||||||
path("income-statement/<str:period_spec>",
|
path("income-statement/<str:period_spec>",
|
||||||
mia_core_views.todo, name="income-statement"),
|
views.income_statement, name="income-statement"),
|
||||||
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>",
|
||||||
|
@ -575,3 +575,66 @@ def trial_balance(request, period_spec):
|
|||||||
"reports": ReportUrl(period=period),
|
"reports": ReportUrl(period=period),
|
||||||
"period": period,
|
"period": period,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@require_GET
|
||||||
|
@digest_login_required
|
||||||
|
def income_statement(request, period_spec):
|
||||||
|
"""The income statement."""
|
||||||
|
# The period
|
||||||
|
period = _get_period(period_spec)
|
||||||
|
# The accounts
|
||||||
|
accounts = list(
|
||||||
|
Subject.objects.filter(
|
||||||
|
Q(record__transaction__date__gte=period.start),
|
||||||
|
Q(record__transaction__date__lte=period.end),
|
||||||
|
~(Q(code__startswith="1")
|
||||||
|
| Q(code__startswith="2")
|
||||||
|
| Q(code__startswith="3")))
|
||||||
|
.annotate(
|
||||||
|
balance=Sum(Case(
|
||||||
|
When(record__is_credit=True, then=1),
|
||||||
|
default=-1) * F("record__amount")))
|
||||||
|
.filter(balance__isnull=False))
|
||||||
|
groups = list(Subject.objects.filter(
|
||||||
|
code__in=[x.code[:2] for x in accounts]))
|
||||||
|
sections = list(Subject.objects.filter(
|
||||||
|
Q(code="4") | Q(code="5") | Q(code="6")
|
||||||
|
| Q(code="7") | Q(code="8") | Q(code="9")).order_by("code"))
|
||||||
|
cumulative_accounts = {
|
||||||
|
"4": None,
|
||||||
|
"5": Subject(title=pgettext("Accounting|", "Gross Income")),
|
||||||
|
"6": Subject(title=pgettext("Accounting|", "Operating Income")),
|
||||||
|
"7": Subject(title=pgettext("Accounting|", "Before Tax Income")),
|
||||||
|
"8": Subject(title=pgettext("Accounting|", "After Tax Income")),
|
||||||
|
"9": Subject.objects.get(code="3353"),
|
||||||
|
}
|
||||||
|
cumulative_total = 0
|
||||||
|
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 = None
|
||||||
|
group.total = sum([x.balance
|
||||||
|
for x in group.details])
|
||||||
|
section.balance = None
|
||||||
|
section.total = sum([x.total for x in section.groups])
|
||||||
|
cumulative_total = cumulative_total + section.total
|
||||||
|
if section.code in cumulative_accounts:
|
||||||
|
if cumulative_accounts[section.code] is None:
|
||||||
|
section.cumulative_total = None
|
||||||
|
else:
|
||||||
|
section.cumulative_total\
|
||||||
|
= cumulative_accounts[section.code]
|
||||||
|
section.cumulative_total.balance = None
|
||||||
|
section.cumulative_total.total = cumulative_total
|
||||||
|
return render(request, "accounting/income-statement.html", {
|
||||||
|
"item_list": sections,
|
||||||
|
"reports": ReportUrl(period=period),
|
||||||
|
"period": period,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user