Replaced the views of the default accounting reports with class-based redirect views in the accounting application.

This commit is contained in:
依瑪貓 2020-07-30 00:10:11 +08:00
parent e64089f06f
commit a8058209bd
2 changed files with 243 additions and 285 deletions

View File

@ -20,8 +20,11 @@
""" """
from django.urls import path, register_converter from django.urls import path, register_converter
from django.views.decorators.http import require_GET
from django.views.generic import RedirectView
from mia_core import views as mia_core_views from mia_core import views as mia_core_views
from mia_core.digest_auth import digest_login_required
from . import converters, views from . import converters, views
register_converter(converters.PeriodConverter, "period") register_converter(converters.PeriodConverter, "period")
@ -33,36 +36,41 @@ register_converter(converters.DateConverter, "date")
app_name = "accounting" app_name = "accounting"
urlpatterns = [ urlpatterns = [
path("", views.home, name="home"), path("", require_GET(digest_login_required(RedirectView.as_view(
path("cash", views.cash_default, name="cash.home"), query_string = True,
pattern_name = "accounting:cash.home",
))), name="home"),
path("cash",
views.CashDefaultView.as_view(), name="cash.home"),
path("cash/<cash-account:account>/<period:period>", path("cash/<cash-account:account>/<period:period>",
views.cash, name="cash"), views.cash, name="cash"),
path("cash-summary", path("cash-summary",
views.cash_summary_default, name="cash-summary.home"), views.CashSummaryDefaultView.as_view(), name="cash-summary.home"),
path("cash-summary/<cash-account:account>", path("cash-summary/<cash-account:account>",
views.cash_summary, name="cash-summary"), views.cash_summary, name="cash-summary"),
path("ledger", path("ledger",
views.ledger_default, name="ledger.home"), views.LedgerDefaultView.as_view(), name="ledger.home"),
path("ledger/<ledger-account:account>/<period:period>", path("ledger/<ledger-account:account>/<period:period>",
views.ledger, name="ledger"), views.ledger, name="ledger"),
path("ledger-summary", path("ledger-summary",
views.ledger_summary_default, name="ledger-summary.home"), views.LedgerSummaryDefaultView.as_view(), name="ledger-summary.home"),
path("ledger-summary/<ledger-account:account>", path("ledger-summary/<ledger-account:account>",
views.ledger_summary, name="ledger-summary"), views.ledger_summary, name="ledger-summary"),
path("journal", path("journal",
views.journal_default, name="journal.home"), views.JournalDefaultView.as_view(), name="journal.home"),
path("journal/<period:period>", path("journal/<period:period>",
views.journal, name="journal"), views.journal, name="journal"),
path("trial-balance", path("trial-balance",
views.trial_balance_default, name="trial-balance.home"), views.TrialBalanceDefaultView.as_view(), name="trial-balance.home"),
path("trial-balance/<period:period>", path("trial-balance/<period:period>",
views.trial_balance, name="trial-balance"), views.trial_balance, name="trial-balance"),
path("income-statement", path("income-statement",
views.income_statement_default, name="income-statement.home"), views.IncomeStatementDefaultView.as_view(),
name="income-statement.home"),
path("income-statement/<period:period>", path("income-statement/<period:period>",
views.income_statement, name="income-statement"), views.income_statement, name="income-statement"),
path("balance-sheet", path("balance-sheet",
views.balance_sheet_default, name="balance-sheet.home"), views.BalanceSheetDefaultView.as_view(), name="balance-sheet.home"),
path("balance-sheet/<period:period>", path("balance-sheet/<period:period>",
views.balance_sheet, name="balance-sheet"), views.balance_sheet, name="balance-sheet"),
path("search", path("search",

View File

@ -24,11 +24,12 @@ from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db.models import Sum, Case, When, F, Q from django.db.models import Sum, Case, When, F, Q
from django.db.models.functions import TruncMonth, Coalesce from django.db.models.functions import TruncMonth, Coalesce
from django.http import HttpResponseRedirect
from django.shortcuts import render from django.shortcuts import render
from django.urls import reverse from django.urls import reverse
from django.utils.decorators import method_decorator
from django.utils.translation import pgettext, gettext_noop from django.utils.translation import pgettext, gettext_noop
from django.views.decorators.http import require_GET, require_POST from django.views.decorators.http import require_GET, require_POST
from django.views.generic import RedirectView
from mia_core.digest_auth import digest_login_required from mia_core.digest_auth import digest_login_required
from mia_core.period import Period from mia_core.period import Period
@ -40,39 +41,18 @@ from .utils import ReportUrl, get_cash_accounts, get_ledger_accounts, \
sort_form_transaction_records, fill_transaction_from_previous_form sort_form_transaction_records, fill_transaction_from_previous_form
# noinspection PyUnusedLocal @method_decorator(require_GET, name="dispatch")
@require_GET @method_decorator(digest_login_required, name="dispatch")
@digest_login_required class CashDefaultView(RedirectView):
def home(request): """The default cash account."""
"""The accounting home page. query_string = True
pattern_name = "accounting:cash"
Args: def get_redirect_url(self, *args, **kwargs):
request (HttpRequest) The request. kwargs["account"] = Account.objects.get(
code=settings.ACCOUNTING["DEFAULT_CASH_ACCOUNT"])
Returns: kwargs["period"] = Period.default_spec()
HttpResponseRedirect: The redirection to the default return super().get_redirect_url(*args, **kwargs)
accounting report.
"""
return HttpResponseRedirect(reverse("accounting:cash.home"))
# noinspection PyUnusedLocal
@require_GET
@digest_login_required
def cash_default(request):
"""The default cash account.
Args:
request (HttpRequest) The request.
Returns:
HttpResponseRedirect: The redirection to the default account
and month.
"""
account = Account.objects.get(
code=settings.ACCOUNTING["DEFAULT_CASH_ACCOUNT"])
return HttpResponseRedirect(
reverse("accounting:cash", args=(account, Period.default_spec())))
@require_GET @require_GET
@ -92,7 +72,7 @@ def cash(request, account, period):
if account.code == "0": if account.code == "0":
records = list( records = list(
Record.objects Record.objects
.filter( .filter(
Q(transaction__in=Transaction.objects.filter( Q(transaction__in=Transaction.objects.filter(
Q(date__gte=period.start), Q(date__gte=period.start),
Q(date__lte=period.end), Q(date__lte=period.end),
@ -104,38 +84,38 @@ def cash(request, account, period):
~Q(account__code__startswith="12"), ~Q(account__code__startswith="12"),
~Q(account__code__startswith="21"), ~Q(account__code__startswith="21"),
~Q(account__code__startswith="22")) ~Q(account__code__startswith="22"))
.order_by("transaction__date", "transaction__ord", .order_by("transaction__date", "transaction__ord",
"is_credit", "ord")) "is_credit", "ord"))
balance_before = Record.objects\ balance_before = Record.objects \
.filter( .filter(
Q(transaction__date__lt=period.start), Q(transaction__date__lt=period.start),
(Q(account__code__startswith="11") | (Q(account__code__startswith="11") |
Q(account__code__startswith="12") | Q(account__code__startswith="12") |
Q(account__code__startswith="21") | Q(account__code__startswith="21") |
Q(account__code__startswith="21")))\ Q(account__code__startswith="21"))) \
.aggregate( .aggregate(
balance=Coalesce(Sum(Case( balance=Coalesce(Sum(Case(
When(is_credit=True, then=-1), When(is_credit=True, then=-1),
default=1) * F("amount")), 0))["balance"] default=1) * F("amount")), 0))["balance"]
else: else:
records = list( records = list(
Record.objects Record.objects
.filter( .filter(
Q(transaction__in=Transaction.objects.filter( Q(transaction__in=Transaction.objects.filter(
Q(date__gte=period.start), Q(date__gte=period.start),
Q(date__lte=period.end), Q(date__lte=period.end),
Q(record__account__code__startswith=account.code))), Q(record__account__code__startswith=account.code))),
~Q(account__code__startswith=account.code)) ~Q(account__code__startswith=account.code))
.order_by("transaction__date", "transaction__ord", .order_by("transaction__date", "transaction__ord",
"is_credit", "ord")) "is_credit", "ord"))
balance_before = Record.objects\ balance_before = Record.objects \
.filter( .filter(
transaction__date__lt=period.start, transaction__date__lt=period.start,
account__code__startswith=account.code)\ account__code__startswith=account.code) \
.aggregate( .aggregate(
balance=Coalesce(Sum(Case(When( balance=Coalesce(Sum(Case(When(
is_credit=True, then=-1), is_credit=True, then=-1),
default=1) * F("amount")), 0))["balance"] default=1) * F("amount")), 0))["balance"]
balance = balance_before balance = balance_before
for record in records: for record in records:
sign = 1 if record.is_credit else -1 sign = 1 if record.is_credit else -1
@ -177,22 +157,17 @@ def cash(request, account, period):
}) })
# noinspection PyUnusedLocal @method_decorator(require_GET, name="dispatch")
@require_GET @method_decorator(digest_login_required, name="dispatch")
@digest_login_required class CashSummaryDefaultView(RedirectView):
def cash_summary_default(request): """The default cash account summary."""
"""The default cash account summary. query_string = True
pattern_name = "accounting:cash-summary"
Args: def get_redirect_url(self, *args, **kwargs):
request (HttpRequest) The request. kwargs["account"] = Account.objects.get(
code=settings.ACCOUNTING["DEFAULT_CASH_ACCOUNT"])
Returns: return super().get_redirect_url(*args, **kwargs)
HttpResponseRedirect: The redirection to the default account.
"""
account = Account.objects.get(
code=settings.ACCOUNTING["DEFAULT_CASH_ACCOUNT"])
return HttpResponseRedirect(
reverse("accounting:cash-summary", args=(account,)))
@require_GET @require_GET
@ -212,48 +187,48 @@ def cash_summary(request, account):
# The month summaries # The month summaries
if account.code == "0": if account.code == "0":
months = [RecordSummary(**x) for x in Record.objects months = [RecordSummary(**x) for x in Record.objects
.filter( .filter(
Q(transaction__in=Transaction.objects.filter( Q(transaction__in=Transaction.objects.filter(
Q(record__account__code__startswith="11") | Q(record__account__code__startswith="11") |
Q(record__account__code__startswith="12") | Q(record__account__code__startswith="12") |
Q(record__account__code__startswith="21") | Q(record__account__code__startswith="21") |
Q(record__account__code__startswith="22"))), Q(record__account__code__startswith="22"))),
~Q(account__code__startswith="11"), ~Q(account__code__startswith="11"),
~Q(account__code__startswith="12"), ~Q(account__code__startswith="12"),
~Q(account__code__startswith="21"), ~Q(account__code__startswith="21"),
~Q(account__code__startswith="22")) ~Q(account__code__startswith="22"))
.annotate(month=TruncMonth("transaction__date")) .annotate(month=TruncMonth("transaction__date"))
.values("month") .values("month")
.order_by("month") .order_by("month")
.annotate( .annotate(
debit=Coalesce( debit=Coalesce(
Sum(Case(When(is_credit=False, then=F("amount")))), Sum(Case(When(is_credit=False, then=F("amount")))),
0), 0),
credit=Coalesce( credit=Coalesce(
Sum(Case(When(is_credit=True, then=F("amount")))), Sum(Case(When(is_credit=True, then=F("amount")))),
0), 0),
balance=Sum(Case( balance=Sum(Case(
When(is_credit=False, then=-F("amount")), When(is_credit=False, then=-F("amount")),
default=F("amount"))))] default=F("amount"))))]
else: else:
months = [RecordSummary(**x) for x in Record.objects months = [RecordSummary(**x) for x in Record.objects
.filter( .filter(
Q(transaction__in=Transaction.objects.filter( Q(transaction__in=Transaction.objects.filter(
record__account__code__startswith=account.code)), record__account__code__startswith=account.code)),
~Q(account__code__startswith=account.code)) ~Q(account__code__startswith=account.code))
.annotate(month=TruncMonth("transaction__date")) .annotate(month=TruncMonth("transaction__date"))
.values("month") .values("month")
.order_by("month") .order_by("month")
.annotate( .annotate(
debit=Coalesce( debit=Coalesce(
Sum(Case(When(is_credit=False, then=F("amount")))), Sum(Case(When(is_credit=False, then=F("amount")))),
0), 0),
credit=Coalesce( credit=Coalesce(
Sum(Case(When(is_credit=True, then=F("amount")))), Sum(Case(When(is_credit=True, then=F("amount")))),
0), 0),
balance=Sum(Case( balance=Sum(Case(
When(is_credit=False, then=-F("amount")), When(is_credit=False, then=-F("amount")),
default=F("amount"))))] default=F("amount"))))]
cumulative_balance = 0 cumulative_balance = 0
for month in months: for month in months:
cumulative_balance = cumulative_balance + month.balance cumulative_balance = cumulative_balance + month.balance
@ -279,23 +254,18 @@ def cash_summary(request, account):
}) })
# noinspection PyUnusedLocal @method_decorator(require_GET, name="dispatch")
@require_GET @method_decorator(digest_login_required, name="dispatch")
@digest_login_required class LedgerDefaultView(RedirectView):
def ledger_default(request): """The default ledger."""
"""The default ledger. query_string = True
pattern_name = "accounting:ledger"
Args: def get_redirect_url(self, *args, **kwargs):
request (HttpRequest) The request. kwargs["account"] = Account.objects.get(
code=settings.ACCOUNTING["DEFAULT_LEDGER_ACCOUNT"])
Returns: kwargs["period"] = Period.default_spec()
HttpResponseRedirect: The redirection to the default account return super().get_redirect_url(*args, **kwargs)
and month.
"""
account = Account.objects.get(
code=settings.ACCOUNTING["DEFAULT_LEDGER_ACCOUNT"])
return HttpResponseRedirect(
reverse("accounting:ledger", args=(account, Period.default_spec())))
@require_GET @require_GET
@ -314,20 +284,21 @@ def ledger(request, account, period):
# The accounting records # The accounting records
records = list( records = list(
Record.objects Record.objects
.filter( .filter(
transaction__date__gte=period.start, transaction__date__gte=period.start,
transaction__date__lte=period.end, transaction__date__lte=period.end,
account__code__startswith=account.code) account__code__startswith=account.code)
.order_by("transaction__date", "transaction__ord", "is_credit", "ord")) .order_by("transaction__date", "transaction__ord", "is_credit",
"ord"))
if re.match("^[1-3]", account.code) is not None: if re.match("^[1-3]", account.code) is not None:
balance = Record.objects\ balance = Record.objects \
.filter( .filter(
transaction__date__lt=period.start, transaction__date__lt=period.start,
account__code__startswith=account.code)\ account__code__startswith=account.code) \
.aggregate( .aggregate(
balance=Coalesce(Sum(Case(When( balance=Coalesce(Sum(Case(When(
is_credit=True, then=-1), is_credit=True, then=-1),
default=1) * F("amount")), 0))["balance"] default=1) * F("amount")), 0))["balance"]
record_brought_forward = Record( record_brought_forward = Record(
transaction=Transaction(date=period.start), transaction=Transaction(date=period.start),
account=account, account=account,
@ -359,22 +330,17 @@ def ledger(request, account, period):
}) })
# noinspection PyUnusedLocal @method_decorator(require_GET, name="dispatch")
@require_GET @method_decorator(digest_login_required, name="dispatch")
@digest_login_required class LedgerSummaryDefaultView(RedirectView):
def ledger_summary_default(request): """The default ledger summary."""
"""The default ledger summary. query_string = True
pattern_name = "accounting:ledger-summary"
Args: def get_redirect_url(self, *args, **kwargs):
request (HttpRequest) The request. kwargs["account"] = Account.objects.get(
code=settings.ACCOUNTING["DEFAULT_LEDGER_ACCOUNT"])
Returns: return super().get_redirect_url(*args, **kwargs)
HttpResponseRedirect: The redirection to the default account.
"""
account = Account.objects.get(
code=settings.ACCOUNTING["DEFAULT_LEDGER_ACCOUNT"])
return HttpResponseRedirect(
reverse("accounting:ledger-summary", args=(account,)))
@require_GET @require_GET
@ -391,20 +357,20 @@ def ledger_summary(request, account):
""" """
# The month summaries # The month summaries
months = [RecordSummary(**x) for x in Record.objects months = [RecordSummary(**x) for x in Record.objects
.filter(account__code__startswith=account.code) .filter(account__code__startswith=account.code)
.annotate(month=TruncMonth("transaction__date")) .annotate(month=TruncMonth("transaction__date"))
.values("month") .values("month")
.order_by("month") .order_by("month")
.annotate( .annotate(
debit=Coalesce( debit=Coalesce(
Sum(Case(When(is_credit=False, then=F("amount")))), Sum(Case(When(is_credit=False, then=F("amount")))),
0), 0),
credit=Coalesce( credit=Coalesce(
Sum(Case(When(is_credit=True, then=F("amount")))), Sum(Case(When(is_credit=True, then=F("amount")))),
0), 0),
balance=Sum(Case( balance=Sum(Case(
When(is_credit=False, then=F("amount")), When(is_credit=False, then=F("amount")),
default=-F("amount"))))] default=-F("amount"))))]
cumulative_balance = 0 cumulative_balance = 0
for month in months: for month in months:
cumulative_balance = cumulative_balance + month.balance cumulative_balance = cumulative_balance + month.balance
@ -426,20 +392,16 @@ def ledger_summary(request, account):
}) })
# noinspection PyUnusedLocal @method_decorator(require_GET, name="dispatch")
@require_GET @method_decorator(digest_login_required, name="dispatch")
@digest_login_required class JournalDefaultView(RedirectView):
def journal_default(request): """The default journal."""
"""The default journal. query_string = True
pattern_name = "accounting:journal"
Args: def get_redirect_url(self, *args, **kwargs):
request (HttpRequest) The request. kwargs["period"] = Period.default_spec()
return super().get_redirect_url(*args, **kwargs)
Returns:
HttpResponseRedirect: The redirection to the default month.
"""
return HttpResponseRedirect(
reverse("accounting:journal", args=(Period.default_spec(),)))
@require_GET @require_GET
@ -455,23 +417,23 @@ def journal(request, period):
HttpResponse: The response. HttpResponse: The response.
""" """
# The accounting records # The accounting records
records = Record.objects\ records = Record.objects \
.filter( .filter(
transaction__date__gte=period.start, transaction__date__gte=period.start,
transaction__date__lte=period.end)\ transaction__date__lte=period.end) \
.order_by("transaction__date", "transaction__ord", "is_credit", "ord") .order_by("transaction__date", "transaction__ord", "is_credit", "ord")
# The brought-forward records # The brought-forward records
brought_forward_accounts = Account.objects\ brought_forward_accounts = Account.objects \
.filter( .filter(
Q(code__startswith="1") Q(code__startswith="1")
| Q(code__startswith="2") | Q(code__startswith="2")
| Q(code__startswith="3"))\ | Q(code__startswith="3")) \
.annotate(balance=Sum( .annotate(balance=Sum(
Case( Case(
When(record__is_credit=True, then=-1), When(record__is_credit=True, then=-1),
default=1 default=1
) * F("record__amount"), ) * F("record__amount"),
filter=Q(record__transaction__date__lt=period.start)))\ filter=Q(record__transaction__date__lt=period.start))) \
.filter(~Q(balance=0)) .filter(~Q(balance=0))
debit_records = [Record( debit_records = [Record(
transaction=Transaction(date=period.start), transaction=Transaction(date=period.start),
@ -501,8 +463,8 @@ def journal(request, period):
is_credit=True, is_credit=True,
amount=sum_debits - sum_credits amount=sum_debits - sum_credits
)) ))
records = list(debit_records) + list(credit_records)\ records = list(debit_records) + list(credit_records) \
+ list(records) + list(records)
pagination = Pagination(request, records, True) pagination = Pagination(request, records, True)
return render(request, "accounting/journal.html", { return render(request, "accounting/journal.html", {
"item_list": pagination.items, "item_list": pagination.items,
@ -512,20 +474,16 @@ def journal(request, period):
}) })
# noinspection PyUnusedLocal @method_decorator(require_GET, name="dispatch")
@require_GET @method_decorator(digest_login_required, name="dispatch")
@digest_login_required class TrialBalanceDefaultView(RedirectView):
def trial_balance_default(request): """The default trial balance."""
"""The default trial balance. query_string = True
pattern_name = "accounting:trial-balance"
Args: def get_redirect_url(self, *args, **kwargs):
request (HttpRequest) The request. kwargs["period"] = Period.default_spec()
return super().get_redirect_url(*args, **kwargs)
Returns:
HttpResponseRedirect: The redirection to the default month.
"""
return HttpResponseRedirect(
reverse("accounting:trial-balance", args=(Period.default_spec(),)))
@require_GET @require_GET
@ -543,58 +501,58 @@ def trial_balance(request, period):
# The accounts # The accounts
nominal = list( nominal = list(
Account.objects Account.objects
.filter( .filter(
Q(record__transaction__date__gte=period.start), Q(record__transaction__date__gte=period.start),
Q(record__transaction__date__lte=period.end), Q(record__transaction__date__lte=period.end),
~(Q(code__startswith="1") ~(Q(code__startswith="1")
| Q(code__startswith="2") | Q(code__startswith="2")
| Q(code__startswith="3"))) | Q(code__startswith="3")))
.annotate( .annotate(
balance=Sum(Case( balance=Sum(Case(
When(record__is_credit=True, then=-1), When(record__is_credit=True, then=-1),
default=1) * F("record__amount"))) default=1) * F("record__amount")))
.filter(balance__isnull=False) .filter(balance__isnull=False)
.annotate( .annotate(
debit=Case( debit=Case(
When(balance__gt=0, then=F("balance")), When(balance__gt=0, then=F("balance")),
default=None), default=None),
credit=Case( credit=Case(
When(balance__lt=0, then=-F("balance")), When(balance__lt=0, then=-F("balance")),
default=None)) default=None))
.order_by("code")) .order_by("code"))
real = list( real = list(
Account.objects Account.objects
.filter( .filter(
Q(record__transaction__date__lte=period.end), Q(record__transaction__date__lte=period.end),
(Q(code__startswith="1") (Q(code__startswith="1")
| Q(code__startswith="2") | Q(code__startswith="2")
| Q(code__startswith="3")), | Q(code__startswith="3")),
~Q(code="3351")) ~Q(code="3351"))
.annotate( .annotate(
balance=Sum(Case( balance=Sum(Case(
When(record__is_credit=True, then=-1), When(record__is_credit=True, then=-1),
default=1) * F("record__amount"))) default=1) * F("record__amount")))
.filter(balance__isnull=False) .filter(balance__isnull=False)
.annotate( .annotate(
debit=Case( debit=Case(
When(balance__gt=0, then=F("balance")), When(balance__gt=0, then=F("balance")),
default=None), default=None),
credit=Case( credit=Case(
When(balance__lt=0, then=-F("balance")), When(balance__lt=0, then=-F("balance")),
default=None)) default=None))
.order_by("code")) .order_by("code"))
balance = Record.objects\ balance = Record.objects \
.filter( .filter(
(Q(transaction__date__lt=period.start) (Q(transaction__date__lt=period.start)
& ~(Q(account__code__startswith="1") & ~(Q(account__code__startswith="1")
| Q(account__code__startswith="2") | Q(account__code__startswith="2")
| Q(account__code__startswith="3"))) | Q(account__code__startswith="3")))
| (Q(transaction__date__lte=period.end) | (Q(transaction__date__lte=period.end)
& Q(account__code="3351")))\ & Q(account__code="3351"))) \
.aggregate( .aggregate(
balance=Sum(Case( balance=Sum(Case(
When(is_credit=True, then=-1), When(is_credit=True, then=-1),
default=1) * F("amount")))["balance"] default=1) * F("amount")))["balance"]
if balance is not None and balance != 0: if balance is not None and balance != 0:
brought_forward = Account.objects.get(code="3351") brought_forward = Account.objects.get(code="3351")
if balance > 0: if balance > 0:
@ -620,20 +578,16 @@ def trial_balance(request, period):
}) })
# noinspection PyUnusedLocal @method_decorator(require_GET, name="dispatch")
@require_GET @method_decorator(digest_login_required, name="dispatch")
@digest_login_required class IncomeStatementDefaultView(RedirectView):
def income_statement_default(request): """The default income statement."""
"""The default income statement. query_string = True
pattern_name = "accounting:income-statement"
Args: def get_redirect_url(self, *args, **kwargs):
request (HttpRequest) The request. kwargs["period"] = Period.default_spec()
return super().get_redirect_url(*args, **kwargs)
Returns:
HttpResponseRedirect: The redirection to the default month.
"""
return HttpResponseRedirect(
reverse("accounting:income-statement", args=(Period.default_spec(),)))
@require_GET @require_GET
@ -651,18 +605,18 @@ def income_statement(request, period):
# The accounts # The accounts
accounts = list( accounts = list(
Account.objects Account.objects
.filter( .filter(
Q(record__transaction__date__gte=period.start), Q(record__transaction__date__gte=period.start),
Q(record__transaction__date__lte=period.end), Q(record__transaction__date__lte=period.end),
~(Q(code__startswith="1") ~(Q(code__startswith="1")
| Q(code__startswith="2") | Q(code__startswith="2")
| Q(code__startswith="3"))) | Q(code__startswith="3")))
.annotate( .annotate(
balance=Sum(Case( balance=Sum(Case(
When(record__is_credit=True, then=1), When(record__is_credit=True, then=1),
default=-1) * F("record__amount"))) default=-1) * F("record__amount")))
.filter(balance__isnull=False) .filter(balance__isnull=False)
.order_by("code")) .order_by("code"))
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]))
sections = list(Account.objects.filter( sections = list(Account.objects.filter(
@ -689,7 +643,7 @@ def income_statement(request, period):
section.total = sum([x.total for x in section.groups]) section.total = sum([x.total for x in section.groups])
cumulative_total = cumulative_total + section.total cumulative_total = cumulative_total + section.total
if section.code in cumulative_accounts: if section.code in cumulative_accounts:
section.cumulative_total\ section.cumulative_total \
= cumulative_accounts[section.code] = cumulative_accounts[section.code]
section.cumulative_total.balance = None section.cumulative_total.balance = None
section.cumulative_total.total = cumulative_total section.cumulative_total.total = cumulative_total
@ -704,20 +658,16 @@ def income_statement(request, period):
}) })
# noinspection PyUnusedLocal @method_decorator(require_GET, name="dispatch")
@require_GET @method_decorator(digest_login_required, name="dispatch")
@digest_login_required class BalanceSheetDefaultView(RedirectView):
def balance_sheet_default(request): """The default balance sheet."""
"""The default balance sheet. query_string = True
pattern_name = "accounting:balance-sheet"
Args: def get_redirect_url(self, *args, **kwargs):
request (HttpRequest) The request. kwargs["period"] = Period.default_spec()
return super().get_redirect_url(*args, **kwargs)
Returns:
HttpResponseRedirect: The redirection to the default month.
"""
return HttpResponseRedirect(
reverse("accounting:balance-sheet", args=(Period.default_spec(),)))
@require_GET @require_GET
@ -735,49 +685,49 @@ def balance_sheet(request, period):
# The accounts # The accounts
accounts = list( accounts = list(
Account.objects Account.objects
.filter( .filter(
Q(record__transaction__date__lte=period.end), Q(record__transaction__date__lte=period.end),
(Q(code__startswith="1") (Q(code__startswith="1")
| Q(code__startswith="2") | Q(code__startswith="2")
| Q(code__startswith="3")), | Q(code__startswith="3")),
~Q(code="3351")) ~Q(code="3351"))
.annotate( .annotate(
balance=Sum(Case( balance=Sum(Case(
When(record__is_credit=True, then=-1), When(record__is_credit=True, then=-1),
default=1) * F("record__amount"))) default=1) * F("record__amount")))
.filter(balance__isnull=False) .filter(balance__isnull=False)
.order_by("code")) .order_by("code"))
for account in accounts: for account in accounts:
account.url = reverse("accounting:ledger", args=(account, period)) account.url = reverse("accounting:ledger", args=(account, period))
balance = Record.objects\ balance = Record.objects \
.filter( .filter(
Q(transaction__date__lt=period.start) Q(transaction__date__lt=period.start)
& ~((Q(account__code__startswith="1") & ~((Q(account__code__startswith="1")
| Q(account__code__startswith="2") | Q(account__code__startswith="2")
| Q(account__code__startswith="3")) | Q(account__code__startswith="3"))
& ~Q(account__code="3351")))\ & ~Q(account__code="3351"))) \
.aggregate( .aggregate(
balance=Sum(Case( balance=Sum(Case(
When(is_credit=True, then=-1), When(is_credit=True, then=-1),
default=1) * F("amount")))["balance"] default=1) * F("amount")))["balance"]
if balance is not None and balance != 0: if balance is not None and balance != 0:
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,)) "accounting:income-statement", args=(period,))
accounts.append(brought_forward) accounts.append(brought_forward)
balance = Record.objects\ balance = Record.objects \
.filter( .filter(
Q(transaction__date__gte=period.start) Q(transaction__date__gte=period.start)
& Q(transaction__date__lte=period.end) & Q(transaction__date__lte=period.end)
& ~((Q(account__code__startswith="1") & ~((Q(account__code__startswith="1")
| Q(account__code__startswith="2") | Q(account__code__startswith="2")
| Q(account__code__startswith="3")) | Q(account__code__startswith="3"))
& ~Q(account__code="3351")))\ & ~Q(account__code="3351"))) \
.aggregate( .aggregate(
balance=Sum(Case( balance=Sum(Case(
When(is_credit=True, then=-1), When(is_credit=True, then=-1),
default=1) * F("amount")))["balance"] default=1) * F("amount")))["balance"]
if balance is not None and balance != 0: if balance is not None and balance != 0:
net_income = Account.objects.get(code="3353") net_income = Account.objects.get(code="3353")
net_income.balance = balance net_income.balance = balance