Added missing documentation to the global variables, class properties, and object properties.

This commit is contained in:
依瑪貓 2023-06-09 07:28:47 +08:00
parent 64b9c8c11f
commit 501c4b1d22
26 changed files with 103 additions and 5 deletions

View File

@ -168,7 +168,9 @@ class AccountReorderForm:
:param base: The base account.
"""
self.base: BaseAccount = base
"""The base account."""
self.is_modified: bool = False
"""Whether the order is modified."""
def save_order(self) -> None:
"""Saves the order of the account.

View File

@ -65,6 +65,7 @@ class IsDebitAccount:
:param message: The error message.
"""
self.__message: str | LazyString = message
"""The error message."""
def __call__(self, form: FlaskForm, field: StringField) -> None:
if field.data is None:
@ -85,6 +86,7 @@ class IsCreditAccount:
:param message: The error message.
"""
self.__message: str | LazyString = message
"""The error message."""
def __call__(self, form: FlaskForm, field: StringField) -> None:
if field.data is None:

View File

@ -54,7 +54,9 @@ class JournalEntryReorderForm:
:param date: The date.
"""
self.date: dt.date = date
"""The date."""
self.is_modified: bool = False
"""Whether the order is modified."""
def save_order(self) -> None:
"""Saves the order of the account.

View File

@ -166,8 +166,11 @@ class DescriptionRecurring:
:param account: The account.
"""
self.name: str = name
"""The name."""
self.account: DescriptionAccount = DescriptionAccount(account, 0)
"""The account."""
self.description_template: str = description_template
"""The description template."""
@property
def account_codes(self) -> list[str]:

View File

@ -25,8 +25,10 @@ from flask_babel import LazyString, Domain
from flask_babel_js import JAVASCRIPT, c2js
translation_dir: Path = Path(__file__).parent / "translations"
"""The directory of the translation files."""
domain: Domain = Domain(translation_directories=[translation_dir],
domain="accounting")
"""The message domain."""
def gettext(string, **variables) -> str:
@ -120,6 +122,5 @@ def init_app(app: Flask, bp: Blueprint) -> None:
:param bp: The blueprint of the accounting application.
:return: None.
"""
bp.add_url_rule("/_jstrans.js", "babel_catalog",
__babel_js_catalog_view)
bp.add_url_rule("/_jstrans.js", "babel_catalog", __babel_js_catalog_view)
app.jinja_env.globals["A_"] = domain.gettext

View File

@ -145,6 +145,7 @@ class AccountCollector:
.filter(sa.or_(Account.id.in_({x.id for x in account_balances}),
Account.base_code == "3351",
Account.base_code == "3353")).all()
"""The accounts."""
account_by_id: dict[int, Account] \
= {x.id: x for x in self.__all_accounts}
self.accounts: list[ReportAccount] \
@ -154,6 +155,7 @@ class AccountCollector:
account_by_id[x.id],
self.__period))
for x in account_balances]
"""The accounts on the balance sheet."""
self.__add_accumulated()
self.__add_current_period()
self.accounts.sort(key=lambda x: (x.account.base_code, x.account.no))

View File

@ -106,6 +106,7 @@ class Section:
"""The subsections in the section."""
self.accumulated: AccumulatedTotal \
= AccumulatedTotal(accumulated_title)
"""The accumulated total."""
@property
def total(self) -> Decimal:

View File

@ -39,8 +39,11 @@ class RecurringItem:
:param description_template: The description template.
"""
self.name: str = name
"""The name."""
self.account_code: str = account_code
"""The account code."""
self.description_template: str = description_template
"""The description template."""
@property
def account_text(self) -> str:
@ -61,8 +64,10 @@ class Recurring:
"""
self.expenses: list[RecurringItem] \
= [RecurringItem(x[0], x[1], x[2]) for x in data["expense"]]
"""The recurring expenses."""
self.incomes: list[RecurringItem] \
= [RecurringItem(x[0], x[1], x[2]) for x in data["income"]]
"""The recurring incomes."""
@property
def codes(self) -> set[str]:

View File

@ -63,6 +63,7 @@ DEFAULT_PAGE_SIZE: int = 10
"""The default page size."""
T = TypeVar("T")
"""The pagination item type."""
class Pagination(Generic[T]):

View File

@ -27,6 +27,7 @@ from flask import g, Response
from flask_sqlalchemy.model import Model
T = TypeVar("T", bound=Model)
"""The user data model data type."""
class UserUtilityInterface(Generic[T], ABC):

View File

@ -28,8 +28,11 @@ from babel.messages.frontend import CommandLineInterface
from opencc import OpenCC
root_dir: Path = Path(__file__).parent.parent
"""The project root directory."""
translation_dir: Path = root_dir / "tests" / "test_site" / "translations"
"""The directory of the translation files."""
domain: str = "messages"
"""The message domain."""
@click.group()

View File

@ -28,8 +28,11 @@ from babel.messages.frontend import CommandLineInterface
from opencc import OpenCC
root_dir: Path = Path(__file__).parent.parent
"""The project root directory."""
translation_dir: Path = root_dir / "src" / "accounting" / "translations"
"""The directory of the translation files."""
domain: str = "accounting"
"""The message domain."""
@click.group()

View File

@ -73,6 +73,7 @@ class AccountTestCase(unittest.TestCase):
:return: None.
"""
self.app: Flask = create_test_app()
"""The Flask application."""
with self.app.app_context():
from accounting.models import Account, AccountL10n
@ -80,6 +81,7 @@ class AccountTestCase(unittest.TestCase):
Account.query.delete()
db.session.commit()
self.encoded_next_uri: str = encode_next(NEXT_URI)
"""The encoded next URI."""
self.client, self.csrf_token = get_client(self.app, "editor")
response: httpx.Response

View File

@ -40,6 +40,7 @@ class BaseAccountTestCase(unittest.TestCase):
:return: None.
"""
self.app: Flask = create_test_app()
"""The Flask application."""
def test_nobody(self) -> None:
"""Test the permission as nobody.

View File

@ -41,6 +41,7 @@ class ConsoleCommandTestCase(unittest.TestCase):
:return: None.
"""
self.app: Flask = create_test_app()
"""The Flask application."""
with self.app.app_context():
# Drop every accounting table, to see if accounting-init recreates

View File

@ -66,6 +66,7 @@ class CurrencyTestCase(unittest.TestCase):
:return: None.
"""
self.app: Flask = create_test_app()
"""The Flask application."""
with self.app.app_context():
from accounting.models import Currency, CurrencyL10n

View File

@ -37,12 +37,14 @@ class DescriptionEditorTestCase(unittest.TestCase):
:return: None.
"""
self.app: Flask = create_test_app()
"""The Flask application."""
with self.app.app_context():
from accounting.models import JournalEntry, JournalEntryLineItem
JournalEntry.query.delete()
JournalEntryLineItem.query.delete()
self.encoded_next_uri: str = encode_next(NEXT_URI)
"""The encoded next URI."""
self.client, self.csrf_token = get_client(self.app, "editor")

View File

@ -49,12 +49,14 @@ class CashReceiptJournalEntryTestCase(unittest.TestCase):
:return: None.
"""
self.app: Flask = create_test_app()
"""The Flask application."""
with self.app.app_context():
from accounting.models import JournalEntry, JournalEntryLineItem
JournalEntry.query.delete()
JournalEntryLineItem.query.delete()
self.encoded_next_uri: str = encode_next(NEXT_URI)
"""The encoded next URI."""
self.client, self.csrf_token = get_client(self.app, "editor")
@ -665,12 +667,14 @@ class CashDisbursementJournalEntryTestCase(unittest.TestCase):
:return: None.
"""
self.app: Flask = create_test_app()
"""The Flask application."""
with self.app.app_context():
from accounting.models import JournalEntry, JournalEntryLineItem
JournalEntry.query.delete()
JournalEntryLineItem.query.delete()
self.encoded_next_uri: str = encode_next(NEXT_URI)
"""The encoded next URI."""
self.client, self.csrf_token = get_client(self.app, "editor")
@ -1256,6 +1260,7 @@ class TransferJournalEntryTestCase(unittest.TestCase):
:return: None.
"""
self.app: Flask = create_test_app()
"""The Flask application."""
with self.app.app_context():
from accounting.models import JournalEntry, \
@ -1263,6 +1268,7 @@ class TransferJournalEntryTestCase(unittest.TestCase):
JournalEntry.query.delete()
JournalEntryLineItem.query.delete()
self.encoded_next_uri: str = encode_next(NEXT_URI)
"""The encoded next URI."""
self.client, self.csrf_token = get_client(self.app, "editor")
@ -2128,12 +2134,14 @@ class JournalEntryReorderTestCase(unittest.TestCase):
:return: None.
"""
self.app: Flask = create_test_app()
"""The Flask application."""
with self.app.app_context():
from accounting.models import JournalEntry, JournalEntryLineItem
JournalEntry.query.delete()
JournalEntryLineItem.query.delete()
self.encoded_next_uri: str = encode_next(NEXT_URI)
"""The encoded next URI."""
self.client, self.csrf_token = get_client(self.app, "editor")

View File

@ -46,15 +46,18 @@ class OffsetTestCase(unittest.TestCase):
:return: None.
"""
self.app: Flask = create_test_app()
"""The Flask application."""
with self.app.app_context():
from accounting.models import JournalEntry, JournalEntryLineItem
JournalEntry.query.delete()
JournalEntryLineItem.query.delete()
self.encoded_next_uri: str = encode_next(NEXT_URI)
"""The encoded next URI."""
self.client, self.csrf_token = get_client(self.app, "editor")
self.data: OffsetTestData = OffsetTestData(self.app, "editor")
"""The offset test data."""
self.data.populate()
def test_add_receivable_offset(self) -> None:
@ -807,18 +810,22 @@ class OffsetTestData(BaseTestData):
50, [JournalEntryCurrencyData(
"USD", [self.l_r_or1d, self.l_r_or4d],
[self.l_r_or1c, self.l_r_or4c])])
"""The receivable original journal entry #1."""
self.j_r_or2: JournalEntryData = JournalEntryData(
30, [JournalEntryCurrencyData(
"USD", [self.l_r_or2d, self.l_r_or3d],
[self.l_r_or2c, self.l_r_or3c])])
"""The receivable original journal entry #2."""
self.j_p_or1: JournalEntryData = JournalEntryData(
40, [JournalEntryCurrencyData(
"USD", [self.l_p_or1d, self.l_p_or4d],
[self.l_p_or1c, self.l_p_or4c])])
"""The payable original journal entry #1."""
self.j_p_or2: JournalEntryData = JournalEntryData(
20, [JournalEntryCurrencyData(
"USD", [self.l_p_or2d, self.l_p_or3d],
[self.l_p_or2c, self.l_p_or3c])])
"""The payable original journal entry #2."""
self._add_journal_entry(self.j_r_or1)
self._add_journal_entry(self.j_r_or2)
@ -863,23 +870,29 @@ class OffsetTestData(BaseTestData):
self.j_r_of1: JournalEntryData = JournalEntryData(
25, [JournalEntryCurrencyData(
"USD", [self.l_r_of1d], [self.l_r_of1c])])
"""The offset journal entry to the receivable #1."""
self.j_r_of2: JournalEntryData = JournalEntryData(
20, [JournalEntryCurrencyData(
"USD", [self.l_r_of2d, self.l_r_of3d, self.l_r_of4d],
[self.l_r_of2c, self.l_r_of3c, self.l_r_of4c])])
"""The offset journal entry to the receivable #2."""
self.j_r_of3: JournalEntryData = JournalEntryData(
15, [JournalEntryCurrencyData(
"USD", [self.l_r_of5d], [self.l_r_of5c])])
"""The offset journal entry to the receivable #3."""
self.j_p_of1: JournalEntryData = JournalEntryData(
15, [JournalEntryCurrencyData(
"USD", [self.l_p_of1d], [self.l_p_of1c])])
"""The offset journal entry to the payable #1."""
self.j_p_of2: JournalEntryData = JournalEntryData(
10, [JournalEntryCurrencyData(
"USD", [self.l_p_of2d, self.l_p_of3d, self.l_p_of4d],
[self.l_p_of2c, self.l_p_of3c, self.l_p_of4c])])
"""The offset journal entry to the payable #2."""
self.j_p_of3: JournalEntryData = JournalEntryData(
5, [JournalEntryCurrencyData(
"USD", [self.l_p_of5d], [self.l_p_of5c])])
"""The offset journal entry to the payable #3."""
self._add_journal_entry(self.j_r_of1)
self._add_journal_entry(self.j_r_of2)

View File

@ -41,11 +41,13 @@ class OptionTestCase(unittest.TestCase):
:return: None.
"""
self.app: Flask = create_test_app()
"""The Flask application."""
with self.app.app_context():
from accounting.models import Option
Option.query.delete()
self.encoded_next_uri: str = encode_next(NEXT_URI)
"""The encoded next URI."""
self.client, self.csrf_token = get_client(self.app, "admin")

View File

@ -42,6 +42,7 @@ class ReportTestCase(unittest.TestCase):
:return: None.
"""
self.app: Flask = create_test_app()
"""The Flask application."""
with self.app.app_context():
from accounting.models import JournalEntry, JournalEntryLineItem

View File

@ -57,13 +57,20 @@ class JournalEntryLineItemData:
:param original_line_item: The original journal entry line item.
"""
self.journal_entry: JournalEntryData | None = None
"""The journal entry data."""
self.id: int = -1
"""The journal entry line item ID."""
self.no: int = -1
"""The line item number under the journal entry and debit or credit."""
self.original_line_item: JournalEntryLineItemData | None \
= original_line_item
"""The original journal entry line item."""
self.account: str = account
"""The account code."""
self.description: str | None = description
"""The description."""
self.amount: Decimal = Decimal(amount)
"""The amount."""
def form(self, prefix: str, debit_credit: str, index: int,
is_update: bool) -> dict[str, str]:
@ -101,8 +108,11 @@ class JournalEntryCurrencyData:
:param credit: The credit line items.
"""
self.code: str = currency
"""The currency code."""
self.debit: list[JournalEntryLineItemData] = debit
"""The debit line items."""
self.credit: list[JournalEntryLineItemData] = credit
"""The credit line items."""
def form(self, index: int, is_update: bool) -> dict[str, str]:
"""Returns the currency as form data.
@ -131,9 +141,13 @@ class JournalEntryData:
:param currencies: The journal entry currency data.
"""
self.id: int = -1
"""The journal entry ID."""
self.days: int = days
"""The number of days before today."""
self.currencies: list[JournalEntryCurrencyData] = currencies
"""The journal entry currency data."""
self.note: str | None = None
"""The note."""
for currency in self.currencies:
for line_item in currency.debit:
line_item.journal_entry = self
@ -190,13 +204,17 @@ class BaseTestData(ABC):
:param username: The username.
"""
self._app: Flask = app
"""The Flask application."""
with self._app.app_context():
current_user: User | None = User.query\
.filter(User.username == username).first()
assert current_user is not None
self.__current_user_id: int = current_user.id
"""The current user ID."""
self.__journal_entries: list[dict[str, Any]] = []
"""The data of the journal entries."""
self.__line_items: list[dict[str, Any]] = []
"""The data of the journal entry line items."""
self._init_data()
@abstractmethod

View File

@ -26,6 +26,7 @@ from werkzeug.datastructures import LanguageAccept
from accounting.utils.next_uri import or_next
bp: Blueprint = Blueprint("locale", __name__, url_prefix="/")
"""The blueprint for the localization."""
def get_locale():

View File

@ -29,6 +29,7 @@ from .lib import Accounts, JournalEntryLineItemData, JournalEntryData, \
JournalEntryCurrencyData, BaseTestData
bp: Blueprint = Blueprint("reset", __name__, url_prefix="/")
"""The blueprint for the data reset."""
@bp.get("reset", endpoint="reset-page")

View File

@ -42,12 +42,14 @@ class UnmatchedOffsetTestCase(unittest.TestCase):
:return: None.
"""
self.app: Flask = create_test_app()
"""The Flask application."""
with self.app.app_context():
from accounting.models import JournalEntry, JournalEntryLineItem
JournalEntry.query.delete()
JournalEntryLineItem.query.delete()
self.encoded_next_uri: str = encode_next(NEXT_URI)
"""The encoded next URI."""
self.client, self.csrf_token = get_client(self.app, "editor")
@ -410,18 +412,22 @@ class DifferentTestData(BaseTestData):
50, [JournalEntryCurrencyData(
"USD", [self.l_r_or1d, self.l_r_or4d],
[self.l_r_or1c, self.l_r_or4c])])
"""The receivable original journal entry #1."""
self.j_r_or2: JournalEntryData = JournalEntryData(
30, [JournalEntryCurrencyData(
"USD", [self.l_r_or2d, self.l_r_or3d],
[self.l_r_or2c, self.l_r_or3c])])
"""The receivable original journal entry #2"""
self.j_p_or1: JournalEntryData = JournalEntryData(
40, [JournalEntryCurrencyData(
"USD", [self.l_p_or1d, self.l_p_or4d],
[self.l_p_or1c, self.l_p_or4c])])
"""The payable original journal entry #1."""
self.j_p_or2: JournalEntryData = JournalEntryData(
20, [JournalEntryCurrencyData(
"USD", [self.l_p_or2d, self.l_p_or3d],
[self.l_p_or2c, self.l_p_or3c])])
"""The payable original journal entry #2."""
self._add_journal_entry(self.j_r_or1)
self._add_journal_entry(self.j_r_or2)
@ -456,23 +462,29 @@ class DifferentTestData(BaseTestData):
self.j_r_of1: JournalEntryData = JournalEntryData(
25, [JournalEntryCurrencyData(
"USD", [self.l_r_of1d], [self.l_r_of1c])])
"""The offset journal entry to the receivable #1."""
self.j_r_of2: JournalEntryData = JournalEntryData(
20, [JournalEntryCurrencyData(
"USD", [self.l_r_of2d, self.l_r_of3d, self.l_r_of4d],
[self.l_r_of2c, self.l_r_of3c, self.l_r_of4c])])
"""The offset journal entry to the receivable #2."""
self.j_r_of3: JournalEntryData = JournalEntryData(
15, [JournalEntryCurrencyData(
"USD", [self.l_r_of5d], [self.l_r_of5c])])
"""The offset journal entry to the receivable #3."""
self.j_p_of1: JournalEntryData = JournalEntryData(
15, [JournalEntryCurrencyData(
"USD", [self.l_p_of1d], [self.l_p_of1c])])
"""The offset journal entry to the payable #1."""
self.j_p_of2: JournalEntryData = JournalEntryData(
10, [JournalEntryCurrencyData(
"USD", [self.l_p_of2d, self.l_p_of3d, self.l_p_of4d],
[self.l_p_of2c, self.l_p_of3c, self.l_p_of4c])])
"""The offset journal entry to the payable #2."""
self.j_p_of3: JournalEntryData = JournalEntryData(
5, [JournalEntryCurrencyData(
"USD", [self.l_p_of5d], [self.l_p_of5c])])
"""The offset journal entry to the payable #3."""
self._add_journal_entry(self.j_r_of1)
self._add_journal_entry(self.j_r_of2)

View File

@ -41,6 +41,7 @@ class NextUriTestCase(unittest.TestCase):
:return: None.
"""
self.app: Flask = create_test_app()
"""The Flask application."""
def test_next_uri(self) -> None:
"""Tests the next URI utilities with the next URI.
@ -177,7 +178,7 @@ class PaginationTestCase(unittest.TestCase):
"""The test case for pagination."""
class Params:
"""The testing parameters."""
"""The testing pagination parameters."""
def __init__(self, items: list[int], is_reversed: bool | None,
result: list[int], is_paged: bool):
@ -189,9 +190,13 @@ class PaginationTestCase(unittest.TestCase):
:param is_paged: Whether we need pagination.
"""
self.items: list[int] = items
"""All the items in the list."""
self.is_reversed: bool | None = is_reversed
"""Whether the default page is the last page."""
self.result: list[int] = result
"""The expected items on the page."""
self.is_paged: bool = is_paged
"""Whether we need pagination."""
def setUp(self) -> None:
"""Sets up the test.
@ -200,7 +205,9 @@ class PaginationTestCase(unittest.TestCase):
:return: None.
"""
self.app: Flask = create_test_app()
self.params = self.Params([], None, [], True)
"""The Flask application."""
self.params: PaginationTestCase.Params = self.Params([], None, [], True)
"""The testing pagination parameters."""
@self.app.get("/test-pagination")
def test_pagination_view() -> str:
@ -215,7 +222,9 @@ class PaginationTestCase(unittest.TestCase):
self.assertEqual(pagination.list, self.params.result)
return ""
self.client = httpx.Client(app=self.app, base_url=TEST_SERVER)
self.client: httpx.Client = httpx.Client(app=self.app,
base_url=TEST_SERVER)
"""The user client."""
self.client.headers["Referer"] = TEST_SERVER
def __test_success(self, query: str, items: range,