Added CashAccountConverter and LedgerAccountConverter and applied them in the URL patterns of the accounting application.
This commit is contained in:
		| @@ -18,7 +18,10 @@ | ||||
| """The URL converters. | ||||
|  | ||||
| """ | ||||
| from accounting.models import Transaction | ||||
|  | ||||
| from django.utils.translation import pgettext | ||||
|  | ||||
| from accounting.models import Transaction, Record, Account | ||||
| from mia_core.period import Period | ||||
|  | ||||
|  | ||||
| @@ -67,3 +70,75 @@ class PeriodConverter: | ||||
|         if isinstance(value, Period): | ||||
|             return value.spec | ||||
|         return value | ||||
|  | ||||
|  | ||||
| class CashAccountConverter: | ||||
|     """The path converter for the cash account.""" | ||||
|     regex = "0|(11|12|21|22)[1-9]{1,3}" | ||||
|  | ||||
|     def to_python(self, value): | ||||
|         """Returns the cash account by the account code. | ||||
|  | ||||
|         Args: | ||||
|             value (str): The account code. | ||||
|  | ||||
|         Returns: | ||||
|             Account: The account. | ||||
|         """ | ||||
|         if value == "0": | ||||
|             return Account( | ||||
|                 code="0", | ||||
|                 title=pgettext( | ||||
|                     "Accounting|", "current assets and liabilities"), | ||||
|             ) | ||||
|         try: | ||||
|             account = Account.objects.get(code=value) | ||||
|         except Account.DoesNotExist: | ||||
|             raise ValueError | ||||
|         if Record.objects.filter(account=account).count() == 0: | ||||
|             raise ValueError | ||||
|         return account | ||||
|  | ||||
|     def to_url(self, value): | ||||
|         """Returns the code of an account. | ||||
|  | ||||
|         Args: | ||||
|             value (Account): The account. | ||||
|  | ||||
|         Returns: | ||||
|             str: The account code. | ||||
|         """ | ||||
|         return value.code | ||||
|  | ||||
|  | ||||
| class LedgerAccountConverter: | ||||
|     """The path converter for the ledger account.""" | ||||
|     regex = "[1-9]{1,5}" | ||||
|  | ||||
|     def to_python(self, value): | ||||
|         """Returns the ledger accountby the account code. | ||||
|  | ||||
|         Args: | ||||
|             value (str): The account code. | ||||
|  | ||||
|         Returns: | ||||
|             Account: The account. | ||||
|         """ | ||||
|         try: | ||||
|             account = Account.objects.get(code=value) | ||||
|         except Account.DoesNotExist: | ||||
|             raise ValueError | ||||
|         if Record.objects.filter(account__code__startswith=value).count() == 0: | ||||
|             raise ValueError | ||||
|         return account | ||||
|  | ||||
|     def to_url(self, value): | ||||
|         """Returns the code of an account. | ||||
|  | ||||
|         Args: | ||||
|             value (Account): The account. | ||||
|  | ||||
|         Returns: | ||||
|             str: The account code. | ||||
|         """ | ||||
|         return value.code | ||||
|   | ||||
| @@ -72,13 +72,13 @@ First written: 2020/7/15 | ||||
|     <div class="dropdown-menu account-picker"> | ||||
|       <div class="dropdown-header">{% trans "Shortcuts" context "Accounting|Account|" as text %}{{ text|force_escape }}</div> | ||||
|       {% for account in shortcut_accounts %} | ||||
|         <a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}>" href="{% url "accounting:cash-summary" account.code %}"> | ||||
|         <a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}>" href="{% url "accounting:cash-summary" account %}"> | ||||
|           {{ account.title|title }} | ||||
|         </a> | ||||
|       {% endfor %} | ||||
|       <div class="dropdown-header">{% trans "All" context "Accounting|Account|" as text %}{{ text|force_escape }}</div> | ||||
|       {% for account in all_accounts %} | ||||
|         <a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}>" href="{% url "accounting:cash-summary" account.code %}"> | ||||
|         <a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}>" href="{% url "accounting:cash-summary" account %}"> | ||||
|           {{ account.code }} {{ account.title|title }} | ||||
|         </a> | ||||
|       {% endfor %} | ||||
| @@ -111,7 +111,7 @@ First written: 2020/7/15 | ||||
|           <td class="amount {% if item.cumulative_balance < 0 %} text-danger {% endif %}">{{ item.cumulative_balance|accounting_amount }}</td> | ||||
|           <td class="actions"> | ||||
|             {% if item.month is not None %} | ||||
|               <a class="btn btn-info" role="button" href="{% url "accounting:cash" current_account.code item.month|date:"Y-m" %}"> | ||||
|               <a class="btn btn-info" role="button" href="{% url "accounting:cash" current_account item.month|date:"Y-m" %}"> | ||||
|                 <i class="fas fa-eye"></i> | ||||
|                 <span class="d-none d-lg-inline">{% trans "View" context "Accounting|" as text %}{{ text|force_escape }}</span> | ||||
|               </a> | ||||
| @@ -127,7 +127,7 @@ First written: 2020/7/15 | ||||
|     {% for item in item_list %} | ||||
|       <li class="list-group-item {% if item.balance < 0 %} list-group-item-danger {% endif %}"> | ||||
|         {% if item.month is not None %} | ||||
|           <a class="list-group-item-action d-flex justify-content-between align-items-center" href="{% url "accounting:cash" current_account.code item.month|date:"Y-m" %}"> | ||||
|           <a class="list-group-item-action d-flex justify-content-between align-items-center" href="{% url "accounting:cash" current_account item.month|date:"Y-m" %}"> | ||||
|             {{ item.label }} | ||||
|             <div> | ||||
|               <span class="badge badge-success badge-pill"> | ||||
|   | ||||
| @@ -73,13 +73,13 @@ First written: 2020/7/1 | ||||
|     <div class="dropdown-menu account-picker"> | ||||
|       <div class="dropdown-header">{% trans "Shortcuts" context "Accounting|Account|" as text %}{{ text|force_escape }}</div> | ||||
|       {% for account in shortcut_accounts %} | ||||
|         <a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}>" href="{% url "accounting:cash" account.code period %}"> | ||||
|         <a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}>" href="{% url "accounting:cash" account period %}"> | ||||
|           {{ account.title|title }} | ||||
|         </a> | ||||
|       {% endfor %} | ||||
|       <div class="dropdown-header">{% trans "All" context "Accounting|Account|" as text %}{{ text|force_escape }}</div> | ||||
|       {% for account in all_accounts %} | ||||
|         <a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}>" href="{% url "accounting:cash" account.code period %}"> | ||||
|         <a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}>" href="{% url "accounting:cash" account period %}"> | ||||
|           {{ account.code }} {{ account.title|title }} | ||||
|         </a> | ||||
|       {% endfor %} | ||||
|   | ||||
| @@ -112,7 +112,7 @@ First written: 2020/7/19 | ||||
|                     <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 %}" class="btn btn-info" role="button"> | ||||
|                       <a href="{% url "accounting:ledger" item period %}" 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> | ||||
| @@ -172,7 +172,7 @@ First written: 2020/7/19 | ||||
|               </li> | ||||
|               {% for item in group.details %} | ||||
|                 <li class="list-group-item d-flex justify-content-between align-items-center account"> | ||||
|                   <a class="list-group-item-action" href="{% url "accounting:ledger" item.code period %}"> | ||||
|                   <a class="list-group-item-action" href="{% url "accounting:ledger" item period %}"> | ||||
|                     {{ item.title|title }} | ||||
|                     <div class="float-right"> | ||||
|                       <span class="badge {% if item.balance < 0 %} badge-warning {% else %} badge-secondary {% endif %} badge-pill"> | ||||
|   | ||||
| @@ -71,7 +71,7 @@ First written: 2020/7/16 | ||||
|     </button> | ||||
|     <div class="dropdown-menu account-picker"> | ||||
|       {% for account in accounts %} | ||||
|         <a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}>" href="{% url "accounting:ledger-summary" account.code %}"> | ||||
|         <a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}>" href="{% url "accounting:ledger-summary" account %}"> | ||||
|           {{ account.title|title }} | ||||
|         </a> | ||||
|       {% endfor %} | ||||
| @@ -104,7 +104,7 @@ First written: 2020/7/16 | ||||
|           <td class="amount {% if item.cumulative_balance < 0 %} text-danger {% endif %}">{{ item.cumulative_balance|accounting_amount }}</td> | ||||
|           <td class="actions"> | ||||
|             {% if item.month is not None %} | ||||
|               <a class="btn btn-info" role="button" href="{% url "accounting:ledger" current_account.code item.month|date:"Y-m" %}"> | ||||
|               <a class="btn btn-info" role="button" href="{% url "accounting:ledger" current_account item.month|date:"Y-m" %}"> | ||||
|                 <i class="fas fa-eye"></i> | ||||
|                 <span class="d-none d-lg-inline">{% trans "View" context "Accounting|" as text %}{{ text|force_escape }}</span> | ||||
|               </a> | ||||
| @@ -120,7 +120,7 @@ First written: 2020/7/16 | ||||
|     {% for item in item_list %} | ||||
|       <li class="list-group-item {% if current_account.code|first in "12" and item.balance < 0 %} list-group-item-danger {% endif %}"> | ||||
|         {% if item.month is not None %} | ||||
|           <a class="list-group-item-action d-flex justify-content-between align-items-center" href="{% url "accounting:ledger" current_account.code item.month|date:"Y-m" %}"> | ||||
|           <a class="list-group-item-action d-flex justify-content-between align-items-center" href="{% url "accounting:ledger" current_account item.month|date:"Y-m" %}"> | ||||
|             {{ item.label }} | ||||
|             <div> | ||||
|               <span class="badge badge-success badge-pill"> | ||||
|   | ||||
| @@ -72,7 +72,7 @@ First written: 2020/7/16 | ||||
|     </button> | ||||
|     <div class="dropdown-menu account-picker"> | ||||
|       {% for account in accounts %} | ||||
|         <a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}" href="{% url "accounting:ledger" account.code period %}"> | ||||
|         <a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}" href="{% url "accounting:ledger" account period %}"> | ||||
|           {{ account.code }} {{ account.title|title }} | ||||
|         </a> | ||||
|       {% endfor %} | ||||
|   | ||||
| @@ -101,7 +101,7 @@ First written: 2020/7/19 | ||||
|                 <td class="amount">{{ item.debit|accounting_amount }}</td> | ||||
|                 <td class="amount">{{ item.credit|accounting_amount }}</td> | ||||
|                 <td class="actions"> | ||||
|                   <a href="{% url "accounting:ledger" item.code period %}" class="btn btn-info" role="button"> | ||||
|                   <a href="{% url "accounting:ledger" item period %}" 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> | ||||
| @@ -133,7 +133,7 @@ First written: 2020/7/19 | ||||
|         <ul class="list-group d-lg-none trial-balance-list"> | ||||
|           {% for item in item_list %} | ||||
|             <li class="list-group-item"> | ||||
|               <a class="list-group-item-action d-flex justify-content-between align-items-center" href="{% url "accounting:ledger" item.code period.spec %}"> | ||||
|               <a class="list-group-item-action d-flex justify-content-between align-items-center" href="{% url "accounting:ledger" item period.spec %}"> | ||||
|                 {{ item.title }} | ||||
|                 <div> | ||||
|                   {% if item.debit is not None %} | ||||
|   | ||||
| @@ -26,26 +26,27 @@ from . import views, converters | ||||
| from .views import reports | ||||
|  | ||||
| register_converter(converters.TransactionTypeConverter, "txn-type") | ||||
|  | ||||
| register_converter(converters.PeriodConverter, "period") | ||||
| register_converter(converters.CashAccountConverter, "cash-account") | ||||
| register_converter(converters.LedgerAccountConverter, "ledger-account") | ||||
|  | ||||
| app_name = "accounting" | ||||
| urlpatterns = [ | ||||
|     path("", views.home, name="home"), | ||||
|     path("cash", reports.cash_default, name="cash.home"), | ||||
|     path("cash/<str:account_code>/<period:period>", | ||||
|     path("cash/<cash-account:account>/<period:period>", | ||||
|          reports.cash, name="cash"), | ||||
|     path("cash-summary", | ||||
|          reports.cash_summary_default, name="cash-summary.home"), | ||||
|     path("cash-summary/<str:account_code>", | ||||
|     path("cash-summary/<cash-account:account>", | ||||
|          reports.cash_summary, name="cash-summary"), | ||||
|     path("ledger", | ||||
|          reports.ledger_default, name="ledger.home"), | ||||
|     path("ledger/<str:account_code>/<period:period>", | ||||
|     path("ledger/<ledger-account:account>/<period:period>", | ||||
|          reports.ledger, name="ledger"), | ||||
|     path("ledger-summary", | ||||
|          reports.ledger_summary_default, name="ledger-summary.home"), | ||||
|     path("ledger-summary/<str:account_code>", | ||||
|     path("ledger-summary/<ledger-account:account>", | ||||
|          reports.ledger_summary, name="ledger-summary"), | ||||
|     path("journal", | ||||
|          reports.journal_default, name="journal.home"), | ||||
|   | ||||
| @@ -48,8 +48,8 @@ class ReportUrl: | ||||
|         balance_sheet (str): The URL of the balance sheet. | ||||
|     """ | ||||
|     _period = None | ||||
|     _cash_account = None | ||||
|     _ledger_account = None | ||||
|     _cash = None | ||||
|     _ledger = None | ||||
|  | ||||
|     def __init__(self, **kwargs): | ||||
|         if "period" in kwargs: | ||||
| @@ -57,54 +57,46 @@ class ReportUrl: | ||||
|         else: | ||||
|             self._period = Period() | ||||
|         if "cash" in kwargs: | ||||
|             self._cash_account = kwargs["cash"] | ||||
|             self._cash = kwargs["cash"] | ||||
|         else: | ||||
|             self._cash_account = Account.objects.get( | ||||
|             self._cash = Account.objects.get( | ||||
|                 code=settings.ACCOUNTING["DEFAULT_CASH_ACCOUNT"]) | ||||
|         if "ledger" in kwargs: | ||||
|             self._ledger_account = kwargs["ledger"] | ||||
|             self._ledger = kwargs["ledger"] | ||||
|         else: | ||||
|             self._ledger_account = Account.objects.get( | ||||
|             self._ledger = Account.objects.get( | ||||
|                 code=settings.ACCOUNTING["DEFAULT_LEDGER_ACCOUNT"]) | ||||
|  | ||||
|     @property | ||||
|     def cash(self): | ||||
|         return reverse( | ||||
|             "accounting:cash", | ||||
|             args=[self._cash_account.code, self._period]) | ||||
|             "accounting:cash", args=(self._cash, self._period)) | ||||
|  | ||||
|     @property | ||||
|     def cash_summary(self): | ||||
|         return reverse( | ||||
|             "accounting:cash-summary", args=[self._cash_account.code]) | ||||
|         return reverse("accounting:cash-summary", args=(self._cash,)) | ||||
|  | ||||
|     @property | ||||
|     def ledger(self): | ||||
|         return reverse( | ||||
|             "accounting:ledger", | ||||
|             args=[self._ledger_account.code, self._period]) | ||||
|             "accounting:ledger", args=(self._ledger, self._period)) | ||||
|  | ||||
|     @property | ||||
|     def ledger_summary(self): | ||||
|         return reverse( | ||||
|             "accounting:ledger-summary", | ||||
|             args=[self._ledger_account.code]) | ||||
|         return reverse("accounting:ledger-summary", args=(self._ledger,)) | ||||
|  | ||||
|     @property | ||||
|     def journal(self): | ||||
|         return reverse("accounting:journal", args=[self._period]) | ||||
|         return reverse("accounting:journal", args=(self._period,)) | ||||
|  | ||||
|     @property | ||||
|     def trial_balance(self): | ||||
|         return reverse( | ||||
|             "accounting:trial-balance", args=[self._period]) | ||||
|         return reverse("accounting:trial-balance", args=(self._period,)) | ||||
|  | ||||
|     @property | ||||
|     def income_statement(self): | ||||
|         return reverse( | ||||
|             "accounting:income-statement", args=[self._period]) | ||||
|         return reverse("accounting:income-statement", args=(self._period,)) | ||||
|  | ||||
|     @property | ||||
|     def balance_sheet(self): | ||||
|         return reverse( | ||||
|             "accounting:balance-sheet", args=[self._period]) | ||||
|         return reverse("accounting:balance-sheet", args=(self._period,)) | ||||
|   | ||||
| @@ -51,35 +51,28 @@ def cash_default(request): | ||||
|         HttpResponseRedirect: The redirection to the default account | ||||
|             and month. | ||||
|     """ | ||||
|     account_code = settings.ACCOUNTING["DEFAULT_CASH_ACCOUNT"] | ||||
|     account = Account.objects.get( | ||||
|         code=settings.ACCOUNTING["DEFAULT_CASH_ACCOUNT"]) | ||||
|     period_spec = dateformat.format(timezone.localdate(), "Y-m") | ||||
|     return HttpResponseRedirect( | ||||
|         reverse("accounting:cash", args=(account_code, period_spec))) | ||||
|         reverse("accounting:cash", args=(account, period_spec))) | ||||
|  | ||||
|  | ||||
| @require_GET | ||||
| @digest_login_required | ||||
| def cash(request, account_code, period): | ||||
| def cash(request, account, period): | ||||
|     """The cash account. | ||||
|  | ||||
|     Args: | ||||
|         request (HttpRequest) The request. | ||||
|         account_code (str): The code of the specified account. | ||||
|         account (Account): The account. | ||||
|         period (Period): The period. | ||||
|  | ||||
|     Returns: | ||||
|         HttpResponse: The response. | ||||
|     """ | ||||
|     # The account | ||||
|     accounts = _cash_accounts() | ||||
|     current_account = None | ||||
|     for account in accounts: | ||||
|         if account.code == account_code: | ||||
|             current_account = account | ||||
|     if current_account is None: | ||||
|         raise Http404() | ||||
|     # The accounting records | ||||
|     if current_account.code == "0": | ||||
|     if account.code == "0": | ||||
|         records = list( | ||||
|             Record.objects | ||||
|             .filter( | ||||
| @@ -114,14 +107,14 @@ def cash(request, account_code, period): | ||||
|                 Q(transaction__in=Transaction.objects.filter( | ||||
|                     Q(date__gte=period.start), | ||||
|                     Q(date__lte=period.end), | ||||
|                     Q(record__account__code__startswith=account_code))), | ||||
|                 ~Q(account__code__startswith=account_code)) | ||||
|                     Q(record__account__code__startswith=account.code))), | ||||
|                 ~Q(account__code__startswith=account.code)) | ||||
|             .order_by("transaction__date", "transaction__ord", | ||||
|                       "is_credit", "ord")) | ||||
|         balance_before = Record.objects\ | ||||
|             .filter( | ||||
|                 transaction__date__lt=period.start, | ||||
|                 account__code__startswith=current_account.code)\ | ||||
|                 account__code__startswith=account.code)\ | ||||
|             .aggregate( | ||||
|                 balance=Coalesce(Sum(Case(When( | ||||
|                     is_credit=True, then=-1), | ||||
| @@ -133,7 +126,7 @@ def cash(request, account_code, period): | ||||
|         record.balance = balance | ||||
|     record_sum = Record( | ||||
|         transaction=Transaction(date=records[-1].transaction.date), | ||||
|         account=current_account, | ||||
|         account=account, | ||||
|         summary=pgettext("Accounting|", "Total"), | ||||
|         balance=balance | ||||
|     ) | ||||
| @@ -152,13 +145,14 @@ def cash(request, account_code, period): | ||||
|     records = pagination.items | ||||
|     _find_imbalanced(records) | ||||
|     _find_order_holes(records) | ||||
|     accounts = _cash_accounts() | ||||
|     shortcut_accounts = settings.ACCOUNTING["CASH_SHORTCUT_ACCOUNTS"] | ||||
|     return render(request, "accounting/cash.html", { | ||||
|         "item_list": records, | ||||
|         "pagination": pagination, | ||||
|         "current_account": current_account, | ||||
|         "current_account": account, | ||||
|         "period": period, | ||||
|         "reports": ReportUrl(cash=current_account, period=period), | ||||
|         "reports": ReportUrl(cash=account, period=period), | ||||
|         "shortcut_accounts": [x for x in accounts | ||||
|                               if x.code in shortcut_accounts], | ||||
|         "all_accounts": [x for x in accounts | ||||
| @@ -178,33 +172,28 @@ def cash_summary_default(request): | ||||
|     Returns: | ||||
|         HttpResponseRedirect: The redirection to the default account. | ||||
|     """ | ||||
|     account_code = settings.ACCOUNTING["DEFAULT_CASH_ACCOUNT"] | ||||
|     account = Account.objects.get( | ||||
|         code=settings.ACCOUNTING["DEFAULT_CASH_ACCOUNT"]) | ||||
|     return HttpResponseRedirect( | ||||
|         reverse("accounting:cash-summary", args=(account_code,))) | ||||
|         reverse("accounting:cash-summary", args=(account,))) | ||||
|  | ||||
|  | ||||
| @require_GET | ||||
| @digest_login_required | ||||
| def cash_summary(request, account_code): | ||||
| def cash_summary(request, account): | ||||
|     """The cash account summary. | ||||
|  | ||||
|     Args: | ||||
|         request (HttpRequest) The request. | ||||
|         account_code (str): The code of the specified account. | ||||
|         account (Account): The account. | ||||
|  | ||||
|     Returns: | ||||
|         HttpResponse: The response. | ||||
|     """ | ||||
|     # The account | ||||
|     accounts = _cash_accounts() | ||||
|     current_account = None | ||||
|     for account in accounts: | ||||
|         if account.code == account_code: | ||||
|             current_account = account | ||||
|     if current_account is None: | ||||
|         raise Http404() | ||||
|     # The month summaries | ||||
|     if current_account.code == "0": | ||||
|     if account.code == "0": | ||||
|         months = [RecordSummary(**x) for x in Record.objects | ||||
|                   .filter( | ||||
|                     Q(transaction__in=Transaction.objects.filter( | ||||
| @@ -233,8 +222,8 @@ def cash_summary(request, account_code): | ||||
|         months = [RecordSummary(**x) for x in Record.objects | ||||
|                   .filter( | ||||
|                     Q(transaction__in=Transaction.objects.filter( | ||||
|                         record__account__code__startswith=account_code)), | ||||
|                     ~Q(account__code__startswith=account_code)) | ||||
|                         record__account__code__startswith=account.code)), | ||||
|                     ~Q(account__code__startswith=account.code)) | ||||
|                   .annotate(month=TruncMonth("transaction__date")) | ||||
|                   .values("month") | ||||
|                   .order_by("month") | ||||
| @@ -264,8 +253,8 @@ def cash_summary(request, account_code): | ||||
|     return render(request, "accounting/cash-summary.html", { | ||||
|         "item_list": pagination.items, | ||||
|         "pagination": pagination, | ||||
|         "current_account": current_account, | ||||
|         "reports": ReportUrl(cash=current_account), | ||||
|         "current_account": account, | ||||
|         "reports": ReportUrl(cash=account), | ||||
|         "shortcut_accounts": [x for x in accounts if | ||||
|                               x.code in shortcut_accounts], | ||||
|         "all_accounts": [x for x in accounts if | ||||
| @@ -286,54 +275,46 @@ def ledger_default(request): | ||||
|         HttpResponseRedirect: The redirection to the default account | ||||
|             and month. | ||||
|     """ | ||||
|     account_code = settings.ACCOUNTING["DEFAULT_LEDGER_ACCOUNT"] | ||||
|     account = Account.objects.get( | ||||
|         code=settings.ACCOUNTING["DEFAULT_LEDGER_ACCOUNT"]) | ||||
|     period_spec = dateformat.format(timezone.localdate(), "Y-m") | ||||
|     return HttpResponseRedirect( | ||||
|         reverse("accounting:ledger", | ||||
|                 args=(account_code, period_spec))) | ||||
|         reverse("accounting:ledger", args=(account, period_spec))) | ||||
|  | ||||
|  | ||||
| @require_GET | ||||
| @digest_login_required | ||||
| def ledger(request, account_code, period): | ||||
| def ledger(request, account, period): | ||||
|     """The ledger. | ||||
|  | ||||
|     Args: | ||||
|         request (HttpRequest) The request. | ||||
|         account_code (str): The code of the specified account. | ||||
|         account (Account): The account. | ||||
|         period (Period): The period. | ||||
|  | ||||
|     Returns: | ||||
|         HttpResponse: The response. | ||||
|     """ | ||||
|     # The account | ||||
|     accounts = _ledger_accounts() | ||||
|     current_account = None | ||||
|     for account in accounts: | ||||
|         if account.code == account_code: | ||||
|             current_account = account | ||||
|     if current_account is None: | ||||
|         raise Http404() | ||||
|     # The accounting records | ||||
|     records = list( | ||||
|         Record.objects | ||||
|         .filter( | ||||
|             transaction__date__gte=period.start, | ||||
|             transaction__date__lte=period.end, | ||||
|             account__code__startswith=current_account.code) | ||||
|             account__code__startswith=account.code) | ||||
|         .order_by("transaction__date", "transaction__ord", "is_credit", "ord")) | ||||
|     if re.match("^[1-3]", current_account.code) is not None: | ||||
|     if re.match("^[1-3]", account.code) is not None: | ||||
|         balance = Record.objects\ | ||||
|             .filter( | ||||
|                 transaction__date__lt=period.start, | ||||
|                 account__code__startswith=current_account.code)\ | ||||
|                 account__code__startswith=account.code)\ | ||||
|             .aggregate( | ||||
|                 balance=Coalesce(Sum(Case(When( | ||||
|                     is_credit=True, then=-1), | ||||
|                     default=1) * F("amount")), 0))["balance"] | ||||
|         record_brought_forward = Record( | ||||
|             transaction=Transaction(date=period.start), | ||||
|             account=current_account, | ||||
|             account=account, | ||||
|             summary=pgettext("Accounting|", "Brought Forward"), | ||||
|             is_credit=balance < 0, | ||||
|             amount=abs(balance), | ||||
| @@ -355,10 +336,10 @@ def ledger(request, account_code, period): | ||||
|     return render(request, "accounting/ledger.html", { | ||||
|         "item_list": records, | ||||
|         "pagination": pagination, | ||||
|         "current_account": current_account, | ||||
|         "current_account": account, | ||||
|         "period": period, | ||||
|         "reports": ReportUrl(ledger=current_account, period=period), | ||||
|         "accounts": accounts, | ||||
|         "reports": ReportUrl(ledger=account, period=period), | ||||
|         "accounts": _ledger_accounts(), | ||||
|     }) | ||||
|  | ||||
|  | ||||
| @@ -374,35 +355,27 @@ def ledger_summary_default(request): | ||||
|     Returns: | ||||
|         HttpResponseRedirect: The redirection to the default account. | ||||
|     """ | ||||
|     account_code = settings.ACCOUNTING["DEFAULT_LEDGER_ACCOUNT"] | ||||
|     print(account_code) | ||||
|     account = Account.objects.get( | ||||
|         code=settings.ACCOUNTING["DEFAULT_LEDGER_ACCOUNT"]) | ||||
|     return HttpResponseRedirect( | ||||
|         reverse("accounting:ledger-summary", args=(account_code,))) | ||||
|         reverse("accounting:ledger-summary", args=(account,))) | ||||
|  | ||||
|  | ||||
| @require_GET | ||||
| @digest_login_required | ||||
| def ledger_summary(request, account_code): | ||||
| def ledger_summary(request, account): | ||||
|     """The ledger summary report. | ||||
|  | ||||
|     Args: | ||||
|         request (HttpRequest) The request. | ||||
|         account_code (str): The code of the specified account. | ||||
|         account (Account): The account. | ||||
|  | ||||
|     Returns: | ||||
|         HttpResponse: The response. | ||||
|     """ | ||||
|     # The account | ||||
|     accounts = _ledger_accounts() | ||||
|     current_account = None | ||||
|     for account in accounts: | ||||
|         if account.code == account_code: | ||||
|             current_account = account | ||||
|     if current_account is None: | ||||
|         raise Http404() | ||||
|     # The month summaries | ||||
|     months = [RecordSummary(**x) for x in Record.objects | ||||
|               .filter(account__code__startswith=current_account.code) | ||||
|               .filter(account__code__startswith=account.code) | ||||
|               .annotate(month=TruncMonth("transaction__date")) | ||||
|               .values("month") | ||||
|               .order_by("month") | ||||
| @@ -431,9 +404,9 @@ def ledger_summary(request, account_code): | ||||
|     return render(request, "accounting/ledger-summary.html", { | ||||
|         "item_list": pagination.items, | ||||
|         "pagination": pagination, | ||||
|         "current_account": current_account, | ||||
|         "reports": ReportUrl(ledger=current_account), | ||||
|         "accounts": accounts, | ||||
|         "current_account": account, | ||||
|         "reports": ReportUrl(ledger=account), | ||||
|         "accounts": _ledger_accounts(), | ||||
|     }) | ||||
|  | ||||
|  | ||||
| @@ -763,8 +736,7 @@ def balance_sheet(request, period): | ||||
|         .filter(balance__isnull=False) | ||||
|         .order_by("code")) | ||||
|     for account in accounts: | ||||
|         account.url = reverse( | ||||
|             "accounting:ledger", args=(account.code, period)) | ||||
|         account.url = reverse("accounting:ledger", args=(account, period)) | ||||
|     balance = Record.objects\ | ||||
|         .filter( | ||||
|             Q(transaction__date__lt=period.start) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user