diff --git a/src/accounting/base_account/__init__.py b/src/accounting/base_account/__init__.py index c401932..11c650b 100644 --- a/src/accounting/base_account/__init__.py +++ b/src/accounting/base_account/__init__.py @@ -27,6 +27,9 @@ def init_app(app: Flask, bp: Blueprint) -> None: :param app: The Flask application. :return: None. """ + from .converters import BaseAccountConverter + app.url_map.converters["baseAccount"] = BaseAccountConverter + from .views import bp as base_account_bp bp.register_blueprint(base_account_bp, url_prefix="/base-accounts") diff --git a/src/accounting/base_account/converters.py b/src/accounting/base_account/converters.py new file mode 100644 index 0000000..10fe5b2 --- /dev/null +++ b/src/accounting/base_account/converters.py @@ -0,0 +1,48 @@ +# The Mia! Accounting Flask Project. +# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/1 + +# 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 path converters for the base account management. + +""" +from flask import abort +from werkzeug.routing import BaseConverter + +from accounting.database import db +from accounting.models import BaseAccount + + +class BaseAccountConverter(BaseConverter): + """The account converter to convert the account code and to the + corresponding base account in the routes.""" + + def to_python(self, value: str) -> BaseAccount: + """Converts an account code to a base account. + + :param value: The account code. + :return: The corresponding base account. + """ + account: BaseAccount | None = db.session.get(BaseAccount, value) + if account is None: + abort(404) + return account + + def to_url(self, value: BaseAccount) -> str: + """Converts a base account to its code. + + :param value: The base account. + :return: The code. + """ + return value.code diff --git a/src/accounting/base_account/views.py b/src/accounting/base_account/views.py index ca13c3b..15e3872 100644 --- a/src/accounting/base_account/views.py +++ b/src/accounting/base_account/views.py @@ -39,3 +39,14 @@ def list_accounts() -> str: pagination: Pagination = Pagination[BaseAccount](accounts) return render_template("accounting/base-account/list.html", list=pagination.list, pagination=pagination) + + +@bp.get("/", endpoint="detail") +@has_permission(can_view) +def show_account_detail(account: BaseAccount) -> str: + """Shows the account detail. + + :return: The account detail. + """ + return render_template("accounting/base-account/detail.html", obj=account) + diff --git a/src/accounting/models.py b/src/accounting/models.py index 8302103..edaa90f 100644 --- a/src/accounting/models.py +++ b/src/accounting/models.py @@ -42,6 +42,8 @@ class BaseAccount(db.Model): l10n = db.relationship("BaseAccountL10n", back_populates="account", lazy=False) """The localized titles.""" + accounts = db.relationship("Account", back_populates="base") + """The descendant accounts under the base account.""" def __str__(self) -> str: """Returns the string representation of the base account. @@ -91,7 +93,7 @@ class Account(db.Model): ondelete="CASCADE"), nullable=False) """The code of the base account.""" - base = db.relationship(BaseAccount) + base = db.relationship(BaseAccount, back_populates="accounts") """The base account.""" no = db.Column(db.Integer, nullable=False, default=text("1")) """The account number under the base account.""" diff --git a/src/accounting/templates/accounting/base-account/detail.html b/src/accounting/templates/accounting/base-account/detail.html new file mode 100644 index 0000000..16da523 --- /dev/null +++ b/src/accounting/templates/accounting/base-account/detail.html @@ -0,0 +1,49 @@ +{# +The Mia! Accounting Flask Project +detail.html: The base account detail + + 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. + +Author: imacat@mail.imacat.idv.tw (imacat) +First written: 2023/2/1 +#} +{% extends "accounting/base.html" %} + +{% block header %}{% block title %}{{ obj }}{% endblock %}{% endblock %} + +{% block content %} + +
+ + + {{ A_("Back") }} + +
+ +
+ + + {% if obj.accounts %} +
+ {% for account in obj.accounts %} + + {{ account }} + + {% endfor %} +
+ {% endif %} +
+ +{% endblock %} diff --git a/src/accounting/templates/accounting/base-account/list.html b/src/accounting/templates/accounting/base-account/list.html index a091866..557e1c0 100644 --- a/src/accounting/templates/accounting/base-account/list.html +++ b/src/accounting/templates/accounting/base-account/list.html @@ -44,13 +44,13 @@ First written: 2023/1/26 {% if list %} {% include "accounting/include/pagination.html" %} - +
+ {% for item in list %} + + {{ item }} + + {% endfor %} +
{% else %}

{{ A_("There is no data.") }}

{% endif %}