Added PeriodConverter to convert a period specification to a period, and applied it in the URL patterns.
This commit is contained in:
parent
01dbd7e60b
commit
f9a9a99246
@ -73,13 +73,13 @@ First written: 2020/7/1
|
|||||||
<div class="dropdown-menu account-picker">
|
<div class="dropdown-menu account-picker">
|
||||||
<div class="dropdown-header">{% trans "Shortcuts" context "Accounting|Account|" as text %}{{ text|force_escape }}</div>
|
<div class="dropdown-header">{% trans "Shortcuts" context "Accounting|Account|" as text %}{{ text|force_escape }}</div>
|
||||||
{% for account in shortcut_accounts %}
|
{% for account in shortcut_accounts %}
|
||||||
<a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}>" href="{% url "accounting:cash" account.code period.spec %}">
|
<a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}>" href="{% url "accounting:cash" account.code period %}">
|
||||||
{{ account.title|title }}
|
{{ account.title|title }}
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<div class="dropdown-header">{% trans "All" context "Accounting|Account|" as text %}{{ text|force_escape }}</div>
|
<div class="dropdown-header">{% trans "All" context "Accounting|Account|" as text %}{{ text|force_escape }}</div>
|
||||||
{% for account in all_accounts %}
|
{% for account in all_accounts %}
|
||||||
<a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}>" href="{% url "accounting:cash" account.code period.spec %}">
|
<a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}>" href="{% url "accounting:cash" account.code period %}">
|
||||||
{{ account.code }} {{ account.title|title }}
|
{{ account.code }} {{ account.title|title }}
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% 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 {% if item.balance < 0 %} text-danger {% endif %}">{{ item.balance|accounting_amount }}</td>
|
||||||
<td class="amount"></td>
|
<td class="amount"></td>
|
||||||
<td class="actions">
|
<td class="actions">
|
||||||
<a href="{% url "accounting:ledger" item.code period.spec %}" class="btn btn-info" role="button">
|
<a href="{% url "accounting:ledger" item.code period %}" class="btn btn-info" role="button">
|
||||||
<i class="fas fa-eye"></i>
|
<i class="fas fa-eye"></i>
|
||||||
<span class="d-none d-lg-inline">{% trans "View" context "Accounting|" as text %}{{ text|force_escape }}</span>
|
<span class="d-none d-lg-inline">{% trans "View" context "Accounting|" as text %}{{ text|force_escape }}</span>
|
||||||
</a>
|
</a>
|
||||||
@ -172,7 +172,7 @@ First written: 2020/7/19
|
|||||||
</li>
|
</li>
|
||||||
{% for item in group.details %}
|
{% for item in group.details %}
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center account">
|
<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.spec %}">
|
<a class="list-group-item-action" href="{% url "accounting:ledger" item.code period %}">
|
||||||
{{ item.title|title }}
|
{{ item.title|title }}
|
||||||
<div class="float-right">
|
<div class="float-right">
|
||||||
<span class="badge {% if item.balance < 0 %} badge-warning {% else %} badge-secondary {% endif %} badge-pill">
|
<span class="badge {% if item.balance < 0 %} badge-warning {% else %} badge-secondary {% endif %} badge-pill">
|
||||||
|
@ -72,7 +72,7 @@ First written: 2020/7/16
|
|||||||
</button>
|
</button>
|
||||||
<div class="dropdown-menu account-picker">
|
<div class="dropdown-menu account-picker">
|
||||||
{% for account in accounts %}
|
{% for account in accounts %}
|
||||||
<a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}" href="{% url "accounting:ledger" account.code period.spec %}">
|
<a class="dropdown-item {% if account.code == current_account.code %} active {% endif %}" href="{% url "accounting:ledger" account.code period %}">
|
||||||
{{ account.code }} {{ account.title|title }}
|
{{ account.code }} {{ account.title|title }}
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -101,7 +101,7 @@ First written: 2020/7/19
|
|||||||
<td class="amount">{{ item.debit|accounting_amount }}</td>
|
<td class="amount">{{ item.debit|accounting_amount }}</td>
|
||||||
<td class="amount">{{ item.credit|accounting_amount }}</td>
|
<td class="amount">{{ item.credit|accounting_amount }}</td>
|
||||||
<td class="actions">
|
<td class="actions">
|
||||||
<a href="{% url "accounting:ledger" item.code period.spec %}" class="btn btn-info" role="button">
|
<a href="{% url "accounting:ledger" item.code period %}" class="btn btn-info" role="button">
|
||||||
<i class="fas fa-eye"></i>
|
<i class="fas fa-eye"></i>
|
||||||
<span class="d-none d-lg-inline">{% trans "View" context "Accounting|" as text %}{{ text|force_escape }}</span>
|
<span class="d-none d-lg-inline">{% trans "View" context "Accounting|" as text %}{{ text|force_escape }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -21,8 +21,10 @@
|
|||||||
|
|
||||||
from django.urls import path, register_converter
|
from django.urls import path, register_converter
|
||||||
|
|
||||||
|
from mia_core.period import Period
|
||||||
from . import views
|
from . import views
|
||||||
from mia_core import views as mia_core_views
|
from mia_core import views as mia_core_views
|
||||||
|
from .models import Transaction
|
||||||
from .views import reports
|
from .views import reports
|
||||||
|
|
||||||
|
|
||||||
@ -39,11 +41,50 @@ class TransactionTypeConverter:
|
|||||||
|
|
||||||
register_converter(TransactionTypeConverter, "txn-type")
|
register_converter(TransactionTypeConverter, "txn-type")
|
||||||
|
|
||||||
|
|
||||||
|
class PeriodConverter:
|
||||||
|
"""The path converter for the period."""
|
||||||
|
regex = ".+"
|
||||||
|
|
||||||
|
def to_python(self, value):
|
||||||
|
"""Returns the period by the period specification.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value (str): The period specification.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Period: The period.
|
||||||
|
"""
|
||||||
|
first_txn = Transaction.objects.order_by("date").first()
|
||||||
|
data_start = first_txn.date if first_txn is not None else None
|
||||||
|
last_txn = Transaction.objects.order_by("-date").first()
|
||||||
|
data_end = last_txn.date if last_txn is not None else None
|
||||||
|
period = Period(value, data_start, data_end)
|
||||||
|
if period.error is not None:
|
||||||
|
raise ValueError
|
||||||
|
return period
|
||||||
|
|
||||||
|
def to_url(self, value):
|
||||||
|
"""Returns the specification of a period.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value (Period|str): The period.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The period specification.
|
||||||
|
"""
|
||||||
|
if isinstance(value, Period):
|
||||||
|
return value.spec
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
register_converter(PeriodConverter, "period")
|
||||||
|
|
||||||
app_name = "accounting"
|
app_name = "accounting"
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", views.home, name="home"),
|
path("", views.home, name="home"),
|
||||||
path("cash", reports.cash_default, name="cash.home"),
|
path("cash", reports.cash_default, name="cash.home"),
|
||||||
path("cash/<str:account_code>/<str:period_spec>",
|
path("cash/<str:account_code>/<period:period>",
|
||||||
reports.cash, name="cash"),
|
reports.cash, name="cash"),
|
||||||
path("cash-summary",
|
path("cash-summary",
|
||||||
reports.cash_summary_default, name="cash-summary.home"),
|
reports.cash_summary_default, name="cash-summary.home"),
|
||||||
@ -51,7 +92,7 @@ urlpatterns = [
|
|||||||
reports.cash_summary, name="cash-summary"),
|
reports.cash_summary, name="cash-summary"),
|
||||||
path("ledger",
|
path("ledger",
|
||||||
reports.ledger_default, name="ledger.home"),
|
reports.ledger_default, name="ledger.home"),
|
||||||
path("ledger/<str:account_code>/<str:period_spec>",
|
path("ledger/<str:account_code>/<period:period>",
|
||||||
reports.ledger, name="ledger"),
|
reports.ledger, name="ledger"),
|
||||||
path("ledger-summary",
|
path("ledger-summary",
|
||||||
reports.ledger_summary_default, name="ledger-summary.home"),
|
reports.ledger_summary_default, name="ledger-summary.home"),
|
||||||
@ -59,19 +100,19 @@ urlpatterns = [
|
|||||||
reports.ledger_summary, name="ledger-summary"),
|
reports.ledger_summary, name="ledger-summary"),
|
||||||
path("journal",
|
path("journal",
|
||||||
reports.journal_default, name="journal.home"),
|
reports.journal_default, name="journal.home"),
|
||||||
path("journal/<str:period_spec>",
|
path("journal/<period:period>",
|
||||||
reports.journal, name="journal"),
|
reports.journal, name="journal"),
|
||||||
path("trial-balance",
|
path("trial-balance",
|
||||||
reports.trial_balance_default, name="trial-balance.home"),
|
reports.trial_balance_default, name="trial-balance.home"),
|
||||||
path("trial-balance/<str:period_spec>",
|
path("trial-balance/<period:period>",
|
||||||
reports.trial_balance, name="trial-balance"),
|
reports.trial_balance, name="trial-balance"),
|
||||||
path("income-statement",
|
path("income-statement",
|
||||||
reports.income_statement_default, name="income-statement.home"),
|
reports.income_statement_default, name="income-statement.home"),
|
||||||
path("income-statement/<str:period_spec>",
|
path("income-statement/<period:period>",
|
||||||
reports.income_statement, name="income-statement"),
|
reports.income_statement, name="income-statement"),
|
||||||
path("balance-sheet",
|
path("balance-sheet",
|
||||||
reports.balance_sheet_default, name="balance-sheet.home"),
|
reports.balance_sheet_default, name="balance-sheet.home"),
|
||||||
path("balance-sheet/<str:period_spec>",
|
path("balance-sheet/<period:period>",
|
||||||
reports.balance_sheet, name="balance-sheet"),
|
reports.balance_sheet, name="balance-sheet"),
|
||||||
path("search",
|
path("search",
|
||||||
reports.search, name="search"),
|
reports.search, name="search"),
|
||||||
|
@ -71,7 +71,7 @@ class ReportUrl:
|
|||||||
def cash(self):
|
def cash(self):
|
||||||
return reverse(
|
return reverse(
|
||||||
"accounting:cash",
|
"accounting:cash",
|
||||||
args=[self._cash_account.code, self._period.spec])
|
args=[self._cash_account.code, self._period])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cash_summary(self):
|
def cash_summary(self):
|
||||||
@ -82,7 +82,7 @@ class ReportUrl:
|
|||||||
def ledger(self):
|
def ledger(self):
|
||||||
return reverse(
|
return reverse(
|
||||||
"accounting:ledger",
|
"accounting:ledger",
|
||||||
args=[self._ledger_account.code, self._period.spec])
|
args=[self._ledger_account.code, self._period])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ledger_summary(self):
|
def ledger_summary(self):
|
||||||
@ -92,19 +92,19 @@ class ReportUrl:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def journal(self):
|
def journal(self):
|
||||||
return reverse("accounting:journal", args=[self._period.spec])
|
return reverse("accounting:journal", args=[self._period])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def trial_balance(self):
|
def trial_balance(self):
|
||||||
return reverse(
|
return reverse(
|
||||||
"accounting:trial-balance", args=[self._period.spec])
|
"accounting:trial-balance", args=[self._period])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def income_statement(self):
|
def income_statement(self):
|
||||||
return reverse(
|
return reverse(
|
||||||
"accounting:income-statement", args=[self._period.spec])
|
"accounting:income-statement", args=[self._period])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def balance_sheet(self):
|
def balance_sheet(self):
|
||||||
return reverse(
|
return reverse(
|
||||||
"accounting:balance-sheet", args=[self._period.spec])
|
"accounting:balance-sheet", args=[self._period])
|
||||||
|
@ -59,19 +59,17 @@ def cash_default(request):
|
|||||||
|
|
||||||
@require_GET
|
@require_GET
|
||||||
@digest_login_required
|
@digest_login_required
|
||||||
def cash(request, account_code, period_spec):
|
def cash(request, account_code, period):
|
||||||
"""The cash account.
|
"""The cash account.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
request (HttpRequest) The request.
|
request (HttpRequest) The request.
|
||||||
account_code (str): The code of the specified account.
|
account_code (str): The code of the specified account.
|
||||||
period_spec (str): The period specification.
|
period (Period): The period.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
HttpResponse: The response.
|
HttpResponse: The response.
|
||||||
"""
|
"""
|
||||||
# The period
|
|
||||||
period = _get_period(period_spec)
|
|
||||||
# The account
|
# The account
|
||||||
accounts = _cash_accounts()
|
accounts = _cash_accounts()
|
||||||
current_account = None
|
current_account = None
|
||||||
@ -295,19 +293,17 @@ def ledger_default(request):
|
|||||||
|
|
||||||
@require_GET
|
@require_GET
|
||||||
@digest_login_required
|
@digest_login_required
|
||||||
def ledger(request, account_code, period_spec):
|
def ledger(request, account_code, period):
|
||||||
"""The ledger.
|
"""The ledger.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
request (HttpRequest) The request.
|
request (HttpRequest) The request.
|
||||||
account_code (str): The code of the specified account.
|
account_code (str): The code of the specified account.
|
||||||
period_spec (str): The period specification.
|
period (Period): The period.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
HttpResponse: The response.
|
HttpResponse: The response.
|
||||||
"""
|
"""
|
||||||
# The period
|
|
||||||
period = _get_period(period_spec)
|
|
||||||
# The account
|
# The account
|
||||||
accounts = _ledger_accounts()
|
accounts = _ledger_accounts()
|
||||||
current_account = None
|
current_account = None
|
||||||
@ -458,18 +454,16 @@ def journal_default(request):
|
|||||||
|
|
||||||
@require_GET
|
@require_GET
|
||||||
@digest_login_required
|
@digest_login_required
|
||||||
def journal(request, period_spec):
|
def journal(request, period):
|
||||||
"""The journal.
|
"""The journal.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
request (HttpRequest) The request.
|
request (HttpRequest) The request.
|
||||||
period_spec (str): The period specification.
|
period (Period): The period.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
HttpResponse: The response.
|
HttpResponse: The response.
|
||||||
"""
|
"""
|
||||||
# The period
|
|
||||||
period = _get_period(period_spec)
|
|
||||||
# The accounting records
|
# The accounting records
|
||||||
records = Record.objects\
|
records = Record.objects\
|
||||||
.filter(
|
.filter(
|
||||||
@ -547,18 +541,16 @@ def trial_balance_default(request):
|
|||||||
|
|
||||||
@require_GET
|
@require_GET
|
||||||
@digest_login_required
|
@digest_login_required
|
||||||
def trial_balance(request, period_spec):
|
def trial_balance(request, period):
|
||||||
"""The trial balance.
|
"""The trial balance.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
request (HttpRequest) The request.
|
request (HttpRequest) The request.
|
||||||
period_spec (str): The period specification.
|
period (Period): The period.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
HttpResponse: The response.
|
HttpResponse: The response.
|
||||||
"""
|
"""
|
||||||
# The period
|
|
||||||
period = _get_period(period_spec)
|
|
||||||
# The accounts
|
# The accounts
|
||||||
nominal = list(
|
nominal = list(
|
||||||
Account.objects
|
Account.objects
|
||||||
@ -658,18 +650,16 @@ def income_statement_default(request):
|
|||||||
|
|
||||||
@require_GET
|
@require_GET
|
||||||
@digest_login_required
|
@digest_login_required
|
||||||
def income_statement(request, period_spec):
|
def income_statement(request, period):
|
||||||
"""The income statement.
|
"""The income statement.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
request (HttpRequest) The request.
|
request (HttpRequest) The request.
|
||||||
period_spec (str): The period specification.
|
period (Period): The period.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
HttpResponse: The response.
|
HttpResponse: The response.
|
||||||
"""
|
"""
|
||||||
# The period
|
|
||||||
period = _get_period(period_spec)
|
|
||||||
# The accounts
|
# The accounts
|
||||||
accounts = list(
|
accounts = list(
|
||||||
Account.objects
|
Account.objects
|
||||||
@ -745,18 +735,16 @@ def balance_sheet_default(request):
|
|||||||
|
|
||||||
@require_GET
|
@require_GET
|
||||||
@digest_login_required
|
@digest_login_required
|
||||||
def balance_sheet(request, period_spec):
|
def balance_sheet(request, period):
|
||||||
"""The balance sheet.
|
"""The balance sheet.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
request (HttpRequest) The request.
|
request (HttpRequest) The request.
|
||||||
period_spec (str): The period specification.
|
period (Period): The period.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
HttpResponse: The response.
|
HttpResponse: The response.
|
||||||
"""
|
"""
|
||||||
# The period
|
|
||||||
period = _get_period(period_spec)
|
|
||||||
# The accounts
|
# The accounts
|
||||||
accounts = list(
|
accounts = list(
|
||||||
Account.objects
|
Account.objects
|
||||||
@ -774,7 +762,7 @@ def balance_sheet(request, period_spec):
|
|||||||
.order_by("code"))
|
.order_by("code"))
|
||||||
for account in accounts:
|
for account in accounts:
|
||||||
account.url = reverse(
|
account.url = reverse(
|
||||||
"accounting:ledger", args=[account.code, period.spec])
|
"accounting:ledger", args=(account.code, period))
|
||||||
balance = Record.objects\
|
balance = Record.objects\
|
||||||
.filter(
|
.filter(
|
||||||
Q(transaction__date__lt=period.start)
|
Q(transaction__date__lt=period.start)
|
||||||
@ -790,7 +778,7 @@ def balance_sheet(request, period_spec):
|
|||||||
brought_forward = Account.objects.get(code="3351")
|
brought_forward = Account.objects.get(code="3351")
|
||||||
brought_forward.balance = -balance
|
brought_forward.balance = -balance
|
||||||
brought_forward.url = reverse(
|
brought_forward.url = reverse(
|
||||||
"accounting:income-statement", args=[period.spec])
|
"accounting:income-statement", args=(period,))
|
||||||
accounts.append(brought_forward)
|
accounts.append(brought_forward)
|
||||||
balance = Record.objects\
|
balance = Record.objects\
|
||||||
.filter(
|
.filter(
|
||||||
@ -808,7 +796,7 @@ def balance_sheet(request, period_spec):
|
|||||||
net_income = Account.objects.get(code="3353")
|
net_income = Account.objects.get(code="3353")
|
||||||
net_income.balance = -balance
|
net_income.balance = -balance
|
||||||
net_income.url = reverse(
|
net_income.url = reverse(
|
||||||
"accounting:income-statement", args=[period.spec])
|
"accounting:income-statement", args=(period,))
|
||||||
accounts.append(net_income)
|
accounts.append(net_income)
|
||||||
groups = list(Account.objects.filter(
|
groups = list(Account.objects.filter(
|
||||||
code__in=[x.code[:2] for x in accounts]))
|
code__in=[x.code[:2] for x in accounts]))
|
||||||
@ -861,22 +849,6 @@ def search(request):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def _get_period(period_spec):
|
|
||||||
"""Obtains the period helper.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
period_spec (str): The period specification.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Period: The period helper.
|
|
||||||
"""
|
|
||||||
first_txn = Transaction.objects.order_by("date").first()
|
|
||||||
data_start = first_txn.date if first_txn is not None else None
|
|
||||||
last_txn = Transaction.objects.order_by("-date").first()
|
|
||||||
data_end = last_txn.date if last_txn is not None else None
|
|
||||||
return Period(period_spec, data_start, data_end)
|
|
||||||
|
|
||||||
|
|
||||||
def _cash_accounts():
|
def _cash_accounts():
|
||||||
"""Returns the cash accounts.
|
"""Returns the cash accounts.
|
||||||
|
|
||||||
|
@ -102,6 +102,10 @@ class Period:
|
|||||||
def description(self):
|
def description(self):
|
||||||
return self._period.description
|
return self._period.description
|
||||||
|
|
||||||
|
@property
|
||||||
|
def error(self):
|
||||||
|
return self._period.error
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_last_month_start():
|
def _get_last_month_start():
|
||||||
"""Returns the first day of the last month.
|
"""Returns the first day of the last month.
|
||||||
|
@ -86,7 +86,7 @@ def url_period(context, period_spec):
|
|||||||
request.resolver_match.app_name,
|
request.resolver_match.app_name,
|
||||||
request.resolver_match.url_name)
|
request.resolver_match.url_name)
|
||||||
kwargs = request.resolver_match.kwargs
|
kwargs = request.resolver_match.kwargs
|
||||||
kwargs["period_spec"] = period_spec
|
kwargs["period"] = period_spec
|
||||||
return reverse(view_name, kwargs=kwargs)
|
return reverse(view_name, kwargs=kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user