Added the balance sheet in the accounting application.
This commit is contained in:
		| @@ -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; | ||||
| } | ||||
|   | ||||
							
								
								
									
										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", | ||||
|          mia_core_views.todo, name="balance-sheet.home"), | ||||
|     path("balance-sheet/<str:period_spec>", | ||||
|          mia_core_views.todo, name="balance-sheet"), | ||||
|          views.balance_sheet, name="balance-sheet"), | ||||
|     path("search", | ||||
|          mia_core_views.todo, name="search"), | ||||
|     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, | ||||
|     }) | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user