2020-07-23 01:22:11 +08:00
|
|
|
# The accounting application of the Mia project.
|
|
|
|
# by imacat <imacat@mail.imacat.idv.tw>, 2020/7/23
|
|
|
|
|
|
|
|
# Copyright (c) 2020 imacat.
|
|
|
|
#
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
|
# You may obtain a copy of the License at
|
|
|
|
#
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
#
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
# See the License for the specific language governing permissions and
|
|
|
|
# limitations under the License.
|
|
|
|
|
|
|
|
"""The URL converters.
|
|
|
|
|
|
|
|
"""
|
2020-07-23 23:01:19 +08:00
|
|
|
import datetime
|
|
|
|
import re
|
2020-07-23 08:33:53 +08:00
|
|
|
|
2020-08-06 00:41:29 +08:00
|
|
|
from django.utils.translation import gettext as _
|
2020-07-23 08:33:53 +08:00
|
|
|
|
2020-07-23 14:26:05 +08:00
|
|
|
from .models import Transaction, Record, Account
|
2020-07-23 01:22:11 +08:00
|
|
|
from mia_core.period import Period
|
|
|
|
|
|
|
|
|
|
|
|
class TransactionTypeConverter:
|
|
|
|
"""The path converter for the transaction types."""
|
|
|
|
regex = "income|expense|transfer"
|
|
|
|
|
|
|
|
def to_python(self, value):
|
|
|
|
return value
|
|
|
|
|
|
|
|
def to_url(self, value):
|
|
|
|
return value
|
|
|
|
|
|
|
|
|
|
|
|
class PeriodConverter:
|
|
|
|
"""The path converter for the period."""
|
2020-07-23 22:13:17 +08:00
|
|
|
regex = ("([0-9]{4}(-[0-9]{2}(-[0-9]{2})?)?)|"
|
|
|
|
"([0-9]{4}(-[0-9]{2}(-[0-9]{2})?)?)?-"
|
|
|
|
"([0-9]{4}(-[0-9]{2}(-[0-9]{2})?)?)?")
|
2020-07-23 01:22:11 +08:00
|
|
|
|
|
|
|
def to_python(self, value):
|
|
|
|
"""Returns the period by the period specification.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
value (str): The period specification.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
Period: The period.
|
2020-08-03 21:42:51 +08:00
|
|
|
|
|
|
|
Raises:
|
|
|
|
ValueError: When the period specification is invalid.
|
2020-07-23 01:22:11 +08:00
|
|
|
"""
|
|
|
|
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
|
2020-08-03 21:42:51 +08:00
|
|
|
# Raises ValueError
|
|
|
|
return Period(value, data_start, data_end)
|
2020-07-23 01:22:11 +08:00
|
|
|
|
|
|
|
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
|
2020-07-23 08:33:53 +08:00
|
|
|
|
|
|
|
|
2020-07-23 23:01:19 +08:00
|
|
|
class DateConverter:
|
|
|
|
"""The path converter for the date."""
|
|
|
|
regex = "([0-9]{4})-([0-9]{2})-([0-9]{2})"
|
|
|
|
|
|
|
|
def to_python(self, value):
|
|
|
|
"""Returns the date by the date specification.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
value (str): The date specification.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
datetime.date: The date.
|
|
|
|
"""
|
|
|
|
m = re.match("^([0-9]{4})-([0-9]{2})-([0-9]{2})$", value)
|
|
|
|
year = int(m.group(1))
|
|
|
|
month = int(m.group(2))
|
|
|
|
day = int(m.group(3))
|
|
|
|
return datetime.date(year, month, day)
|
|
|
|
|
|
|
|
def to_url(self, value):
|
|
|
|
"""Returns the specification of a date.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
value (datetime.date): The date.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
str: The date specification.
|
|
|
|
"""
|
|
|
|
return value.strftime("%Y-%m-%d")
|
|
|
|
|
|
|
|
|
2020-08-07 10:10:33 +08:00
|
|
|
class AccountConverter:
|
|
|
|
"""The path converter for the account."""
|
|
|
|
regex = "[1-9]{1,5}"
|
|
|
|
|
|
|
|
def to_python(self, value):
|
|
|
|
"""Returns the account by the account code.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
value (str): The account code.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
Account: The account.
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
return Account.objects.get(code=value)
|
|
|
|
except Account.DoesNotExist:
|
|
|
|
raise ValueError
|
|
|
|
|
|
|
|
def to_url(self, value):
|
|
|
|
"""Returns the code of an account.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
value (Account): The account.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
str: The account code.
|
|
|
|
"""
|
|
|
|
return value.code
|
|
|
|
|
|
|
|
|
2020-07-23 08:33:53 +08:00
|
|
|
class CashAccountConverter:
|
|
|
|
"""The path converter for the cash account."""
|
|
|
|
regex = "0|(11|12|21|22)[1-9]{1,3}"
|
|
|
|
|
2020-08-13 07:25:35 +08:00
|
|
|
def to_python(self, value: str) -> Account:
|
2020-07-23 08:33:53 +08:00
|
|
|
"""Returns the cash account by the account code.
|
|
|
|
|
|
|
|
Args:
|
2020-08-13 07:25:35 +08:00
|
|
|
value: The account code.
|
2020-07-23 08:33:53 +08:00
|
|
|
|
|
|
|
Returns:
|
2020-08-13 07:25:35 +08:00
|
|
|
The account.
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
ValueError: When the value is invalid
|
2020-07-23 08:33:53 +08:00
|
|
|
"""
|
|
|
|
if value == "0":
|
|
|
|
return Account(
|
|
|
|
code="0",
|
2020-08-06 00:41:29 +08:00
|
|
|
title=_("current assets and liabilities"),
|
2020-07-23 08:33:53 +08:00
|
|
|
)
|
|
|
|
try:
|
|
|
|
account = Account.objects.get(code=value)
|
|
|
|
except Account.DoesNotExist:
|
|
|
|
raise ValueError
|
|
|
|
if Record.objects.filter(account=account).count() == 0:
|
|
|
|
raise ValueError
|
|
|
|
return account
|
|
|
|
|
2020-08-13 07:25:35 +08:00
|
|
|
def to_url(self, value: Account) -> str:
|
2020-07-23 08:33:53 +08:00
|
|
|
"""Returns the code of an account.
|
|
|
|
|
|
|
|
Args:
|
2020-08-13 07:25:35 +08:00
|
|
|
value: The account.
|
2020-07-23 08:33:53 +08:00
|
|
|
|
|
|
|
Returns:
|
2020-08-13 07:25:35 +08:00
|
|
|
The account code.
|
2020-07-23 08:33:53 +08:00
|
|
|
"""
|
|
|
|
return value.code
|
|
|
|
|
|
|
|
|
|
|
|
class LedgerAccountConverter:
|
|
|
|
"""The path converter for the ledger account."""
|
|
|
|
regex = "[1-9]{1,5}"
|
|
|
|
|
2020-08-13 07:25:35 +08:00
|
|
|
def to_python(self, value: str) -> Account:
|
2020-07-23 18:37:29 +08:00
|
|
|
"""Returns the ledger account by the account code.
|
2020-07-23 08:33:53 +08:00
|
|
|
|
|
|
|
Args:
|
2020-08-13 07:25:35 +08:00
|
|
|
value: The account code.
|
2020-07-23 08:33:53 +08:00
|
|
|
|
|
|
|
Returns:
|
2020-08-13 07:25:35 +08:00
|
|
|
The account.
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
ValueError: When the value is invalid
|
2020-07-23 08:33:53 +08:00
|
|
|
"""
|
|
|
|
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
|
|
|
|
|
2020-08-13 07:25:35 +08:00
|
|
|
def to_url(self, value: Account) -> str:
|
2020-07-23 08:33:53 +08:00
|
|
|
"""Returns the code of an account.
|
|
|
|
|
|
|
|
Args:
|
2020-08-13 07:25:35 +08:00
|
|
|
value: The account.
|
2020-07-23 08:33:53 +08:00
|
|
|
|
|
|
|
Returns:
|
2020-08-13 07:25:35 +08:00
|
|
|
The account code.
|
2020-07-23 08:33:53 +08:00
|
|
|
"""
|
|
|
|
return value.code
|
2020-07-23 22:02:26 +08:00
|
|
|
|
|
|
|
|
|
|
|
class TransactionConverter:
|
|
|
|
"""The path converter for the accounting transactions."""
|
|
|
|
regex = "[1-9][0-9]{8}"
|
|
|
|
|
2020-08-13 07:25:35 +08:00
|
|
|
def to_python(self, value: str) -> Transaction:
|
2020-07-23 22:02:26 +08:00
|
|
|
"""Returns the transaction by the transaction ID.
|
|
|
|
|
|
|
|
Args:
|
2020-08-13 07:25:35 +08:00
|
|
|
value: The transaction ID.
|
2020-07-23 22:02:26 +08:00
|
|
|
|
|
|
|
Returns:
|
2020-08-13 07:25:35 +08:00
|
|
|
The account.
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
ValueError: When the value is invalid
|
2020-07-23 22:02:26 +08:00
|
|
|
"""
|
|
|
|
try:
|
2020-07-23 23:20:10 +08:00
|
|
|
return Transaction.objects.get(pk=value)
|
2020-07-23 22:02:26 +08:00
|
|
|
except Transaction.DoesNotExist:
|
|
|
|
raise ValueError
|
|
|
|
|
2020-08-13 07:25:35 +08:00
|
|
|
def to_url(self, value: Transaction) -> str:
|
2020-08-13 07:57:29 +08:00
|
|
|
"""Returns the ID of a transaction.
|
2020-07-23 22:02:26 +08:00
|
|
|
|
|
|
|
Args:
|
2020-08-13 07:25:35 +08:00
|
|
|
value: The transaction.
|
2020-07-23 22:02:26 +08:00
|
|
|
|
|
|
|
Returns:
|
2020-08-13 07:25:35 +08:00
|
|
|
The transaction ID.
|
2020-07-23 22:02:26 +08:00
|
|
|
"""
|
2020-07-23 23:15:33 +08:00
|
|
|
return value.pk
|