Revised so that the settings of the accounting application are optional now, and will not raise errors when they are not set correctly.

This commit is contained in:
依瑪貓 2020-08-12 00:20:02 +08:00
parent 71b4ee5184
commit 7fcfc00e30
2 changed files with 108 additions and 27 deletions

View File

@ -38,6 +38,12 @@ from mia_core.utils import new_pk
from .forms import TransactionForm, RecordForm from .forms import TransactionForm, RecordForm
from .models import Account, Transaction, Record from .models import Account, Transaction, Record
DEFAULT_CASH_ACCOUNT = "1111"
CASH_SHORTCUT_ACCOUNTS = ["0", "1111"]
DEFAULT_LEDGER_ACCOUNT = "1111"
PAYABLE_ACCOUNTS = ["2141", "21413"]
EQUIPMENT_ACCOUNTS = ["1441"],
class MonthlySummary: class MonthlySummary:
"""A summary record. """A summary record.
@ -84,11 +90,8 @@ class ReportUrl:
def __init__(self, cash=None, ledger=None, period=None): def __init__(self, cash=None, ledger=None, period=None):
self._period = Period() if period is None else period self._period = Period() if period is None else period
self._cash = Account.objects.get( self._cash = get_default_cash_account() if cash is None else cash
code=settings.ACCOUNTING["DEFAULT_CASH_ACCOUNT"])\ self._ledger = get_default_ledger_account()\
if cash is None else cash
self._ledger = Account.objects.get(
code=settings.ACCOUNTING["DEFAULT_LEDGER_ACCOUNT"])\
if ledger is None else ledger if ledger is None else ledger
def cash(self): def cash(self):
@ -245,6 +248,52 @@ def get_cash_accounts():
return accounts return accounts
def get_default_cash_account():
"""Returns the default cash account.
Returns:
Account: The default cash account.
"""
try:
code = settings.ACCOUNTING["DEFAULT_CASH_ACCOUNT"]
except AttributeError:
code = DEFAULT_CASH_ACCOUNT
except TypeError:
code = DEFAULT_CASH_ACCOUNT
except KeyError:
code = DEFAULT_CASH_ACCOUNT
if code == "0":
return Account(code="0", title=_("current assets and liabilities"))
try:
return Account.objects.get(code=code)
except Account.DoesNotExist:
pass
try:
return Account.objects.get(code=DEFAULT_CASH_ACCOUNT)
except Account.DoesNotExist:
pass
return Account(code="0", title=_("current assets and liabilities"))
def get_cash_shortcut_accounts():
"""Returns the codes of the shortcut cash accounts.
Returns:
list[str]: The codes of the shortcut cash accounts.
"""
try:
accounts = settings.ACCOUNTING["CASH_SHORTCUT_ACCOUNTS"]
except AttributeError:
return CASH_SHORTCUT_ACCOUNTS
except TypeError:
return CASH_SHORTCUT_ACCOUNTS
except KeyError:
return CASH_SHORTCUT_ACCOUNTS
if not isinstance(accounts, list):
return CASH_SHORTCUT_ACCOUNTS
return accounts
def get_ledger_accounts(): def get_ledger_accounts():
"""Returns the accounts for the ledger. """Returns the accounts for the ledger.
@ -265,6 +314,31 @@ def get_ledger_accounts():
ORDER BY s.code""")) ORDER BY s.code"""))
def get_default_ledger_account():
"""Returns the default ledger account.
Returns:
Account: The default ledger account.
"""
try:
code = settings.ACCOUNTING["DEFAULT_CASH_ACCOUNT"]
except AttributeError:
code = DEFAULT_CASH_ACCOUNT
except TypeError:
code = DEFAULT_CASH_ACCOUNT
except KeyError:
code = DEFAULT_CASH_ACCOUNT
try:
return Account.objects.get(code=code)
except Account.DoesNotExist:
pass
try:
return Account.objects.get(code=DEFAULT_LEDGER_ACCOUNT)
except Account.DoesNotExist:
pass
return None
def find_imbalanced(records): def find_imbalanced(records):
""""Finds the records with imbalanced transactions, and sets their """"Finds the records with imbalanced transactions, and sets their
is_balanced attribute. is_balanced attribute.
@ -312,15 +386,21 @@ def find_payable_records(account, records):
account (Account): The current ledger account. account (Account): The current ledger account.
records (list[Record]): The accounting records. records (list[Record]): The accounting records.
""" """
if "PAYABLE_ACCOUNTS" not in settings.ACCOUNTING: try:
payable_accounts = settings.ACCOUNTING["PAYABLE_ACCOUNTS"]
except AttributeError:
return return
if not isinstance(settings.ACCOUNTING["PAYABLE_ACCOUNTS"], list): except TypeError:
return return
if account.code not in settings.ACCOUNTING["PAYABLE_ACCOUNTS"]: except KeyError:
return
if not isinstance(payable_accounts, list):
return
if account.code not in payable_accounts:
return return
rows = Record.objects\ rows = Record.objects\
.filter( .filter(
account__code__in=settings.ACCOUNTING["PAYABLE_ACCOUNTS"], account__code__in=payable_accounts,
summary__isnull=False)\ summary__isnull=False)\
.values("account__code", "summary")\ .values("account__code", "summary")\
.annotate( .annotate(
@ -341,15 +421,21 @@ def find_existing_equipments(account, records):
account (Account): The current ledger account. account (Account): The current ledger account.
records (list[Record]): The accounting records. records (list[Record]): The accounting records.
""" """
if "EQUIPMENT_ACCOUNTS" not in settings.ACCOUNTING: try:
equipment_accounts = settings.ACCOUNTING["EQUIPMENT_ACCOUNTS"]
except AttributeError:
return return
if not isinstance(settings.ACCOUNTING["EQUIPMENT_ACCOUNTS"], list): except TypeError:
return return
if account.code not in settings.ACCOUNTING["EQUIPMENT_ACCOUNTS"]: except KeyError:
return
if not isinstance(equipment_accounts, list):
return
if account.code not in equipment_accounts:
return return
rows = Record.objects\ rows = Record.objects\
.filter( .filter(
account__code__in=settings.ACCOUNTING["EQUIPMENT_ACCOUNTS"], account__code__in=equipment_accounts,
summary__isnull=False)\ summary__isnull=False)\
.values("account__code", "summary")\ .values("account__code", "summary")\
.annotate( .annotate(

View File

@ -49,7 +49,9 @@ from .utils import get_cash_accounts, get_ledger_accounts, \
find_imbalanced, find_order_holes, fill_txn_from_post, \ find_imbalanced, find_order_holes, fill_txn_from_post, \
sort_post_txn_records, make_txn_form_from_status, \ sort_post_txn_records, make_txn_form_from_status, \
make_txn_form_from_model, make_txn_form_from_post, MonthlySummary, \ make_txn_form_from_model, make_txn_form_from_post, MonthlySummary, \
get_summary_categories, find_payable_records, find_existing_equipments get_summary_categories, find_payable_records, find_existing_equipments, \
get_default_cash_account, get_default_ledger_account, \
get_cash_shortcut_accounts
@method_decorator(require_GET, name="dispatch") @method_decorator(require_GET, name="dispatch")
@ -60,11 +62,7 @@ class CashDefaultView(RedirectView):
pattern_name = "accounting:cash" pattern_name = "accounting:cash"
def get_redirect_url(self, *args, **kwargs): def get_redirect_url(self, *args, **kwargs):
code = settings.ACCOUNTING["DEFAULT_CASH_ACCOUNT"] kwargs["account"] = get_default_cash_account()
kwargs["account"] = Account(
code="0",
title=_("current assets and liabilities"),
) if code == "0" else Account.objects.get(code=code)
kwargs["period"] = Period.default_spec() kwargs["period"] = Period.default_spec()
return super().get_redirect_url(*args, **kwargs) return super().get_redirect_url(*args, **kwargs)
@ -164,7 +162,7 @@ def cash(request, account, period):
find_imbalanced(records) find_imbalanced(records)
find_order_holes(records) find_order_holes(records)
accounts = get_cash_accounts() accounts = get_cash_accounts()
shortcut_accounts = settings.ACCOUNTING["CASH_SHORTCUT_ACCOUNTS"] shortcut_accounts = get_cash_shortcut_accounts()
return render(request, "accounting/cash.html", { return render(request, "accounting/cash.html", {
"record_list": records, "record_list": records,
"pagination": pagination, "pagination": pagination,
@ -183,8 +181,7 @@ class CashSummaryDefaultView(RedirectView):
pattern_name = "accounting:cash-summary" pattern_name = "accounting:cash-summary"
def get_redirect_url(self, *args, **kwargs): def get_redirect_url(self, *args, **kwargs):
kwargs["account"] = Account.objects.get( kwargs["account"] = get_default_cash_account()
code=settings.ACCOUNTING["DEFAULT_CASH_ACCOUNT"])
return super().get_redirect_url(*args, **kwargs) return super().get_redirect_url(*args, **kwargs)
@ -262,7 +259,7 @@ def cash_summary(request, account):
pagination = Pagination(request, months, True) pagination = Pagination(request, months, True)
except PaginationException as e: except PaginationException as e:
return redirect(e.url) return redirect(e.url)
shortcut_accounts = settings.ACCOUNTING["CASH_SHORTCUT_ACCOUNTS"] shortcut_accounts = get_cash_shortcut_accounts()
return render(request, "accounting/cash-summary.html", { return render(request, "accounting/cash-summary.html", {
"month_list": pagination.items, "month_list": pagination.items,
"pagination": pagination, "pagination": pagination,
@ -281,8 +278,7 @@ class LedgerDefaultView(RedirectView):
pattern_name = "accounting:ledger" pattern_name = "accounting:ledger"
def get_redirect_url(self, *args, **kwargs): def get_redirect_url(self, *args, **kwargs):
kwargs["account"] = Account.objects.get( kwargs["account"] = get_default_ledger_account()
code=settings.ACCOUNTING["DEFAULT_LEDGER_ACCOUNT"])
kwargs["period"] = Period.default_spec() kwargs["period"] = Period.default_spec()
return super().get_redirect_url(*args, **kwargs) return super().get_redirect_url(*args, **kwargs)
@ -359,8 +355,7 @@ class LedgerSummaryDefaultView(RedirectView):
pattern_name = "accounting:ledger-summary" pattern_name = "accounting:ledger-summary"
def get_redirect_url(self, *args, **kwargs): def get_redirect_url(self, *args, **kwargs):
kwargs["account"] = Account.objects.get( kwargs["account"] = get_default_ledger_account()
code=settings.ACCOUNTING["DEFAULT_LEDGER_ACCOUNT"])
return super().get_redirect_url(*args, **kwargs) return super().get_redirect_url(*args, **kwargs)