Merged the "accounting.base_account.models" and "accounting.account.models" modules into the new "accounting.modules" module, so that the data models can reference one another.

This commit is contained in:
依瑪貓 2023-02-01 15:44:58 +08:00
parent e9f6b769f4
commit e29b99b0a7
12 changed files with 62 additions and 90 deletions

View File

@ -25,8 +25,7 @@ import click
from flask.cli import with_appcontext from flask.cli import with_appcontext
from accounting.database import db, user_utils from accounting.database import db, user_utils
from .models import Account, AccountL10n from accounting.models import BaseAccount, Account, AccountL10n
from ..base_account import BaseAccount
AccountData = tuple[int, str, int, str, str, str, bool] AccountData = tuple[int, str, int, str, str, str, bool]
"""The format of the account data, as a list of (ID, base account code, number, """The format of the account data, as a list of (ID, base account code, number,

View File

@ -20,7 +20,7 @@
from flask import abort from flask import abort
from werkzeug.routing import BaseConverter from werkzeug.routing import BaseConverter
from .models import Account from accounting.models import Account
class AccountConverter(BaseConverter): class AccountConverter(BaseConverter):

View File

@ -22,12 +22,11 @@ from flask_wtf import FlaskForm
from wtforms import StringField, BooleanField from wtforms import StringField, BooleanField
from wtforms.validators import DataRequired, ValidationError from wtforms.validators import DataRequired, ValidationError
from accounting.base_account import BaseAccount
from accounting.database import db, user_utils from accounting.database import db, user_utils
from accounting.locale import lazy_gettext from accounting.locale import lazy_gettext
from accounting.models import BaseAccount, Account
from accounting.utils.random_id import new_id from accounting.utils.random_id import new_id
from accounting.utils.strip_text import strip_text from accounting.utils.strip_text import strip_text
from .models import Account
class BaseAccountExists: class BaseAccountExists:

View File

@ -20,8 +20,8 @@
import sqlalchemy as sa import sqlalchemy as sa
from flask import request from flask import request
from accounting.models import Account, AccountL10n
from accounting.utils.query import parse_query_keywords from accounting.utils.query import parse_query_keywords
from .models import Account, AccountL10n
def get_account_query() -> list[Account]: def get_account_query() -> list[Account]:

View File

@ -25,10 +25,10 @@ from werkzeug.datastructures import ImmutableMultiDict
from accounting.database import db from accounting.database import db
from accounting.locale import lazy_gettext from accounting.locale import lazy_gettext
from accounting.models import Account, BaseAccount
from accounting.utils.pagination import Pagination from accounting.utils.pagination import Pagination
from accounting.utils.permission import can_view, has_permission, can_edit from accounting.utils.permission import can_view, has_permission, can_edit
from .forms import AccountForm, sort_accounts_in from .forms import AccountForm, sort_accounts_in
from .models import Account
bp: Blueprint = Blueprint("account", __name__) bp: Blueprint = Blueprint("account", __name__)
"""The view blueprint for the account management.""" """The view blueprint for the account management."""
@ -41,7 +41,6 @@ def list_accounts() -> str:
:return: The account list. :return: The account list.
""" """
from .models import BaseAccount
from .query import get_account_query from .query import get_account_query
accounts: list[BaseAccount] = get_account_query() accounts: list[BaseAccount] = get_account_query()
pagination: Pagination = Pagination[BaseAccount](accounts) pagination: Pagination = Pagination[BaseAccount](accounts)

View File

@ -19,8 +19,6 @@
""" """
from flask import Flask, Blueprint from flask import Flask, Blueprint
from .models import BaseAccount
def init_app(app: Flask, bp: Blueprint) -> None: def init_app(app: Flask, bp: Blueprint) -> None:
"""Initialize the application. """Initialize the application.

View File

@ -21,7 +21,7 @@ import click
from flask.cli import with_appcontext from flask.cli import with_appcontext
from accounting.database import db from accounting.database import db
from .models import BaseAccount, BaseAccountL10n from accounting.models import BaseAccount, BaseAccountL10n
BaseAccountData = tuple[int, str, str, str] BaseAccountData = tuple[int, str, str, str]
"""The format of the base account data, as a list of (code, English, """The format of the base account data, as a list of (code, English,

View File

@ -1,73 +0,0 @@
# The Mia! Accounting Flask Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/1/25
# Copyright (c) 2023 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 data models for the base account management.
"""
from flask import current_app
from flask_babel import get_locale
from accounting.database import db
class BaseAccount(db.Model):
"""A base account."""
__tablename__ = "accounting_base_accounts"
"""The table name."""
code = db.Column(db.String, nullable=False, primary_key=True)
"""The code."""
title_l10n = db.Column("title", db.String, nullable=False)
"""The title."""
l10n = db.relationship("BaseAccountL10n", back_populates="account",
lazy=False)
"""The localized titles."""
def __str__(self) -> str:
"""Returns the string representation of the base account.
:return: The string representation of the base account.
"""
return F"{self.code} {self.title}"
@property
def title(self) -> str:
"""Returns the title in the current locale.
:return: The title in the current locale.
"""
current_locale = str(get_locale())
if current_locale == current_app.config["BABEL_DEFAULT_LOCALE"]:
return self.title_l10n
for l10n in self.l10n:
if l10n.locale == current_locale:
return l10n.title
return self.title_l10n
class BaseAccountL10n(db.Model):
"""A localized base account title."""
__tablename__ = "accounting_base_accounts_l10n"
"""The table name."""
account_code = db.Column(db.String, db.ForeignKey(BaseAccount.code,
ondelete="CASCADE"),
nullable=False, primary_key=True)
"""The code of the account."""
account = db.relationship(BaseAccount, back_populates="l10n")
"""The account."""
locale = db.Column(db.String, nullable=False, primary_key=True)
"""The locale."""
title = db.Column(db.String, nullable=False)
"""The localized title."""

View File

@ -20,8 +20,8 @@
import sqlalchemy as sa import sqlalchemy as sa
from flask import request from flask import request
from accounting.models import BaseAccount, BaseAccountL10n
from accounting.utils.query import parse_query_keywords from accounting.utils.query import parse_query_keywords
from .models import BaseAccount, BaseAccountL10n
def get_base_account_query() -> list[BaseAccount]: def get_base_account_query() -> list[BaseAccount]:

View File

@ -19,6 +19,7 @@
""" """
from flask import Blueprint, render_template from flask import Blueprint, render_template
from accounting.models import BaseAccount
from accounting.utils.pagination import Pagination from accounting.utils.pagination import Pagination
from accounting.utils.permission import has_permission, can_view from accounting.utils.permission import has_permission, can_view
@ -33,7 +34,6 @@ def list_accounts() -> str:
:return: The account list. :return: The account list.
""" """
from .models import BaseAccount
from .query import get_base_account_query from .query import get_base_account_query
accounts: list[BaseAccount] = get_base_account_query() accounts: list[BaseAccount] = get_base_account_query()
pagination: Pagination = Pagination[BaseAccount](accounts) pagination: Pagination = Pagination[BaseAccount](accounts)

View File

@ -1,5 +1,5 @@
# The Mia! Accounting Flask Project. # The Mia! Accounting Flask Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/1/30 # Author: imacat@mail.imacat.idv.tw (imacat), 2023/1/25
# Copyright (c) 2023 imacat. # Copyright (c) 2023 imacat.
# #
@ -14,7 +14,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
"""The data models for the account management. """The data models.
""" """
import re import re
@ -25,13 +25,62 @@ from flask import current_app
from flask_babel import get_locale from flask_babel import get_locale
from sqlalchemy import text from sqlalchemy import text
from accounting.base_account import BaseAccount
from accounting.database import db, user_utils from accounting.database import db, user_utils
user_cls: db.Model = user_utils.cls user_cls: db.Model = user_utils.cls
user_pk_column: db.Column = user_utils.pk_column user_pk_column: db.Column = user_utils.pk_column
class BaseAccount(db.Model):
"""A base account."""
__tablename__ = "accounting_base_accounts"
"""The table name."""
code = db.Column(db.String, nullable=False, primary_key=True)
"""The code."""
title_l10n = db.Column("title", db.String, nullable=False)
"""The title."""
l10n = db.relationship("BaseAccountL10n", back_populates="account",
lazy=False)
"""The localized titles."""
def __str__(self) -> str:
"""Returns the string representation of the base account.
:return: The string representation of the base account.
"""
return F"{self.code} {self.title}"
@property
def title(self) -> str:
"""Returns the title in the current locale.
:return: The title in the current locale.
"""
current_locale = str(get_locale())
if current_locale == current_app.config["BABEL_DEFAULT_LOCALE"]:
return self.title_l10n
for l10n in self.l10n:
if l10n.locale == current_locale:
return l10n.title
return self.title_l10n
class BaseAccountL10n(db.Model):
"""A localized base account title."""
__tablename__ = "accounting_base_accounts_l10n"
"""The table name."""
account_code = db.Column(db.String, db.ForeignKey(BaseAccount.code,
ondelete="CASCADE"),
nullable=False, primary_key=True)
"""The code of the account."""
account = db.relationship(BaseAccount, back_populates="l10n")
"""The account."""
locale = db.Column(db.String, nullable=False, primary_key=True)
"""The locale."""
title = db.Column(db.String, nullable=False)
"""The localized title."""
class Account(db.Model): class Account(db.Model):
"""An account.""" """An account."""
__tablename__ = "accounting_accounts" __tablename__ = "accounting_accounts"

View File

@ -54,7 +54,8 @@ class BaseAccountTestCase(unittest.TestCase):
:return: None. :return: None.
""" """
from accounting.base_account.models import BaseAccount, BaseAccountL10n from accounting.models import BaseAccountL10n
from accounting.models import BaseAccount
runner: FlaskCliRunner = self.app.test_cli_runner() runner: FlaskCliRunner = self.app.test_cli_runner()
result: Result = runner.invoke(args="accounting-init-base") result: Result = runner.invoke(args="accounting-init-base")
self.assertEqual(result.exit_code, 0) self.assertEqual(result.exit_code, 0)