Moved the format_amount and format_date template filters from the "accounting.transaction.template_filters" module to the "accounting.template_filters" module, and rename the filters from "accounting_txn_format_amount" and "accounting_txn_format_date" to "accounting_format_amount" and "accounting_format_date", respectively. They will not only be used in the transaction management, but also the reports.

This commit is contained in:
依瑪貓 2023-03-03 18:38:11 +08:00
parent 9065686cc5
commit cc958a39b3
15 changed files with 94 additions and 71 deletions

View File

@ -58,6 +58,10 @@ def init_app(app: Flask, user_utils: AbstractUserUtils,
template_folder="templates", template_folder="templates",
static_folder="static") static_folder="static")
from .template_filters import format_amount, format_date
bp.add_app_template_filter(format_amount, "accounting_format_amount")
bp.add_app_template_filter(format_date, "accounting_format_date")
from . import locale from . import locale
locale.init_app(app, bp) locale.init_app(app, bp)

View File

@ -0,0 +1,68 @@
# The Mia! Accounting Flask Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/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 template filters.
"""
from decimal import Decimal
from datetime import date, timedelta
from flask_babel import get_locale
from accounting.locale import gettext
def format_amount(value: Decimal | None) -> str:
"""Formats an amount for readability.
:param value: The amount.
:return: The formatted amount text.
"""
if value is None or value == 0:
return "-"
whole: int = int(value)
frac: Decimal = (value - whole).normalize()
return "{:,}".format(whole) + str(frac)[1:]
def format_date(value: date) -> str:
"""Formats a date to be human-friendly.
:param value: The date.
:return: The human-friendly date text.
"""
today: date = date.today()
if value == today:
return gettext("Today")
if value == today - timedelta(days=1):
return gettext("Yesterday")
if value == today + timedelta(days=1):
return gettext("Tomorrow")
locale = str(get_locale())
if locale == "zh" or locale.startswith("zh_"):
if value == today - timedelta(days=2):
return gettext("The day before yesterday")
if value == today + timedelta(days=2):
return gettext("The day after tomorrow")
if locale == "zh" or locale.startswith("zh_"):
weekdays = ["", "", "", "", "", "", ""]
weekday = weekdays[value.weekday()]
else:
weekday = value.strftime("%a")
if value.year != today.year:
return "{}/{}/{}({})".format(
value.year, value.month, value.day, weekday)
return "{}/{}({})".format(value.month, value.day, weekday)

View File

@ -44,14 +44,14 @@ First written: 2023/2/26
<div>{{ entry.summary }}</div> <div>{{ entry.summary }}</div>
{% endif %} {% endif %}
</div> </div>
<div>{{ entry.amount|accounting_txn_format_amount }}</div> <div>{{ entry.amount|accounting_format_amount }}</div>
</div> </div>
</li> </li>
{% endfor %} {% endfor %}
<li class="list-group-item accounting-transaction-entry accounting-transaction-entry-total"> <li class="list-group-item accounting-transaction-entry accounting-transaction-entry-total">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<div>{{ A_("Total") }}</div> <div>{{ A_("Total") }}</div>
<div>{{ currency.debit_total|accounting_txn_format_amount }}</div> <div>{{ currency.debit_total|accounting_format_amount }}</div>
</div> </div>
</li> </li>
</ul> </ul>

View File

@ -57,7 +57,7 @@ First written: 2023/2/25
summary_errors = entry_form.summary.errors, summary_errors = entry_form.summary.errors,
amount_data = "" if entry_form.amount.data is none else entry_form.amount.data|accounting_txn_format_amount_input, amount_data = "" if entry_form.amount.data is none else entry_form.amount.data|accounting_txn_format_amount_input,
amount_errors = entry_form.amount.errors, amount_errors = entry_form.amount.errors,
amount_text = entry_form.amount.data|accounting_txn_format_amount, amount_text = entry_form.amount.data|accounting_format_amount,
entry_errors = entry_form.all_errors %} entry_errors = entry_form.all_errors %}
{% include "accounting/transaction/include/form-entry-item.html" %} {% include "accounting/transaction/include/form-entry-item.html" %}
{% endwith %} {% endwith %}

View File

@ -31,7 +31,7 @@ First written: 2023/2/25
currency_code_errors = currency_form.code.errors, currency_code_errors = currency_form.code.errors,
debit_forms = currency_form.debit, debit_forms = currency_form.debit,
debit_errors = currency_form.debit_errors, debit_errors = currency_form.debit_errors,
debit_total = currency_form.form.debit_total|accounting_txn_format_amount %} debit_total = currency_form.form.debit_total|accounting_format_amount %}
{% include "accounting/transaction/expense/include/form-currency-item.html" %} {% include "accounting/transaction/expense/include/form-currency-item.html" %}
{% endwith %} {% endwith %}
{% endfor %} {% endfor %}

View File

@ -89,7 +89,7 @@ First written: 2023/2/26
</div> </div>
<div class="mb-3"> <div class="mb-3">
{{ obj.date|accounting_txn_format_date }} {{ obj.date|accounting_format_date }}
</div> </div>
{% block transaction_currencies %}{% endblock %} {% block transaction_currencies %}{% endblock %}

View File

@ -44,14 +44,14 @@ First written: 2023/2/26
<div>{{ entry.summary }}</div> <div>{{ entry.summary }}</div>
{% endif %} {% endif %}
</div> </div>
<div>{{ entry.amount|accounting_txn_format_amount }}</div> <div>{{ entry.amount|accounting_format_amount }}</div>
</div> </div>
</li> </li>
{% endfor %} {% endfor %}
<li class="list-group-item accounting-transaction-entry accounting-transaction-entry-total"> <li class="list-group-item accounting-transaction-entry accounting-transaction-entry-total">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<div>{{ A_("Total") }}</div> <div>{{ A_("Total") }}</div>
<div>{{ currency.debit_total|accounting_txn_format_amount }}</div> <div>{{ currency.debit_total|accounting_format_amount }}</div>
</div> </div>
</li> </li>
</ul> </ul>

View File

@ -57,7 +57,7 @@ First written: 2023/2/25
summary_errors = entry_form.summary.errors, summary_errors = entry_form.summary.errors,
amount_data = "" if entry_form.amount.data is none else entry_form.amount.data|accounting_txn_format_amount_input, amount_data = "" if entry_form.amount.data is none else entry_form.amount.data|accounting_txn_format_amount_input,
amount_errors = entry_form.amount.errors, amount_errors = entry_form.amount.errors,
amount_text = entry_form.amount.data|accounting_txn_format_amount, amount_text = entry_form.amount.data|accounting_format_amount,
entry_errors = entry_form.all_errors %} entry_errors = entry_form.all_errors %}
{% include "accounting/transaction/include/form-entry-item.html" %} {% include "accounting/transaction/include/form-entry-item.html" %}
{% endwith %} {% endwith %}

View File

@ -31,7 +31,7 @@ First written: 2023/2/25
currency_code_errors = currency_form.code.errors, currency_code_errors = currency_form.code.errors,
credit_forms = currency_form.credit, credit_forms = currency_form.credit,
credit_errors = currency_form.credit_errors, credit_errors = currency_form.credit_errors,
credit_total = currency_form.form.credit_total|accounting_txn_format_amount %} credit_total = currency_form.form.credit_total|accounting_format_amount %}
{% include "accounting/transaction/income/include/form-currency-item.html" %} {% include "accounting/transaction/income/include/form-currency-item.html" %}
{% endwith %} {% endwith %}
{% endfor %} {% endfor %}

View File

@ -85,7 +85,7 @@ First written: 2023/2/18
<div class="list-group"> <div class="list-group">
{% for item in list %} {% for item in list %}
<a class="list-group-item list-group-item-action" href="{{ url_for("accounting.transaction.detail", txn=item)|accounting_append_next }}"> <a class="list-group-item list-group-item-action" href="{{ url_for("accounting.transaction.detail", txn=item)|accounting_append_next }}">
{{ item.date|accounting_txn_format_date }} {{ item }} {{ item.date|accounting_format_date }} {{ item }}
</a> </a>
{% endfor %} {% endfor %}
</div> </div>

View File

@ -40,14 +40,14 @@ First written: 2023/2/26
<div>{{ entry.summary }}</div> <div>{{ entry.summary }}</div>
{% endif %} {% endif %}
</div> </div>
<div>{{ entry.amount|accounting_txn_format_amount }}</div> <div>{{ entry.amount|accounting_format_amount }}</div>
</div> </div>
</li> </li>
{% endfor %} {% endfor %}
<li class="list-group-item accounting-transaction-entry accounting-transaction-entry-total"> <li class="list-group-item accounting-transaction-entry accounting-transaction-entry-total">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<div>{{ A_("Total") }}</div> <div>{{ A_("Total") }}</div>
<div>{{ currency.debit_total|accounting_txn_format_amount }}</div> <div>{{ currency.debit_total|accounting_format_amount }}</div>
</div> </div>
</li> </li>
</ul> </ul>
@ -66,14 +66,14 @@ First written: 2023/2/26
<div>{{ entry.summary }}</div> <div>{{ entry.summary }}</div>
{% endif %} {% endif %}
</div> </div>
<div>{{ entry.amount|accounting_txn_format_amount }}</div> <div>{{ entry.amount|accounting_format_amount }}</div>
</div> </div>
</li> </li>
{% endfor %} {% endfor %}
<li class="list-group-item accounting-transaction-entry accounting-transaction-entry-total"> <li class="list-group-item accounting-transaction-entry accounting-transaction-entry-total">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<div>{{ A_("Total") }}</div> <div>{{ A_("Total") }}</div>
<div>{{ currency.debit_total|accounting_txn_format_amount }}</div> <div>{{ currency.debit_total|accounting_format_amount }}</div>
</div> </div>
</li> </li>
</ul> </ul>

View File

@ -59,7 +59,7 @@ First written: 2023/2/25
summary_errors = entry_form.summary.errors, summary_errors = entry_form.summary.errors,
amount_data = "" if entry_form.amount.data is none else entry_form.amount.data|accounting_txn_format_amount_input, amount_data = "" if entry_form.amount.data is none else entry_form.amount.data|accounting_txn_format_amount_input,
amount_errors = entry_form.amount.errors, amount_errors = entry_form.amount.errors,
amount_text = entry_form.amount.data|accounting_txn_format_amount, amount_text = entry_form.amount.data|accounting_format_amount,
entry_errors = entry_form.all_errors %} entry_errors = entry_form.all_errors %}
{% include "accounting/transaction/include/form-entry-item.html" %} {% include "accounting/transaction/include/form-entry-item.html" %}
{% endwith %} {% endwith %}
@ -99,7 +99,7 @@ First written: 2023/2/25
summary_errors = entry_form.summary.errors, summary_errors = entry_form.summary.errors,
amount_data = "" if entry_form.amount.data is none else entry_form.amount.data|accounting_txn_format_amount_input, amount_data = "" if entry_form.amount.data is none else entry_form.amount.data|accounting_txn_format_amount_input,
amount_errors = entry_form.amount.errors, amount_errors = entry_form.amount.errors,
amount_text = entry_form.amount.data|accounting_txn_format_amount, amount_text = entry_form.amount.data|accounting_format_amount,
entry_errors = entry_form.all_errors %} entry_errors = entry_form.all_errors %}
{% include "accounting/transaction/include/form-entry-item.html" %} {% include "accounting/transaction/include/form-entry-item.html" %}
{% endwith %} {% endwith %}

View File

@ -31,10 +31,10 @@ First written: 2023/2/25
currency_code_errors = currency_form.code.errors, currency_code_errors = currency_form.code.errors,
debit_forms = currency_form.debit, debit_forms = currency_form.debit,
debit_errors = currency_form.debit_errors, debit_errors = currency_form.debit_errors,
debit_total = currency_form.form.debit_total|accounting_txn_format_amount, debit_total = currency_form.form.debit_total|accounting_format_amount,
credit_forms = currency_form.credit, credit_forms = currency_form.credit,
credit_errors = currency_form.credit_errors, credit_errors = currency_form.credit_errors,
credit_total = currency_form.form.credit_total|accounting_txn_format_amount %} credit_total = currency_form.form.credit_total|accounting_format_amount %}
{% include "accounting/transaction/transfer/include/form-currency-item.html" %} {% include "accounting/transaction/transfer/include/form-currency-item.html" %}
{% endwith %} {% endwith %}
{% endfor %} {% endfor %}

View File

@ -17,16 +17,12 @@
"""The template filters for the transaction management. """The template filters for the transaction management.
""" """
from datetime import date, timedelta
from decimal import Decimal from decimal import Decimal
from html import escape from html import escape
from urllib.parse import ParseResult, urlparse, parse_qsl, urlencode, \ from urllib.parse import ParseResult, urlparse, parse_qsl, urlencode, \
urlunparse urlunparse
from flask import request from flask import request
from flask_babel import get_locale
from accounting.locale import gettext
def with_type(uri: str) -> str: def with_type(uri: str) -> str:
@ -61,19 +57,6 @@ def to_transfer(uri: str) -> str:
return urlunparse(parts) return urlunparse(parts)
def format_amount(value: Decimal | None) -> str:
"""Formats an amount for readability.
:param value: The amount.
:return: The formatted amount text.
"""
if value is None or value == 0:
return "-"
whole: int = int(value)
frac: Decimal = (value - whole).normalize()
return "{:,}".format(whole) + str(frac)[1:]
def format_amount_input(value: Decimal) -> str: def format_amount_input(value: Decimal) -> str:
"""Format an amount for an input value. """Format an amount for an input value.
@ -85,36 +68,6 @@ def format_amount_input(value: Decimal) -> str:
return str(whole) + str(frac)[1:] return str(whole) + str(frac)[1:]
def format_date(value: date) -> str:
"""Formats a date to be human-friendly.
:param value: The date.
:return: The human-friendly date text.
"""
today: date = date.today()
if value == today:
return gettext("Today")
if value == today - timedelta(days=1):
return gettext("Yesterday")
if value == today + timedelta(days=1):
return gettext("Tomorrow")
locale = str(get_locale())
if locale == "zh" or locale.startswith("zh_"):
if value == today - timedelta(days=2):
return gettext("The day before yesterday")
if value == today + timedelta(days=2):
return gettext("The day after tomorrow")
if locale == "zh" or locale.startswith("zh_"):
weekdays = ["", "", "", "", "", "", ""]
weekday = weekdays[value.weekday()]
else:
weekday = value.strftime("%a")
if value.year != today.year:
return "{}/{}/{}({})".format(
value.year, value.month, value.day, weekday)
return "{}/{}({})".format(value.month, value.day, weekday)
def text2html(value: str) -> str: def text2html(value: str) -> str:
"""Converts plain text into HTML. """Converts plain text into HTML.

View File

@ -36,18 +36,16 @@ from accounting.utils.user import get_current_user_pk
from .dispatcher import TransactionType, get_txn_type, TXN_TYPE_OBJ from .dispatcher import TransactionType, get_txn_type, TXN_TYPE_OBJ
from .forms import sort_transactions_in, TransactionReorderForm from .forms import sort_transactions_in, TransactionReorderForm
from .queries import get_transaction_query from .queries import get_transaction_query
from .template_filters import with_type, to_transfer, format_amount, \ from .template_filters import with_type, to_transfer, format_amount_input, \
format_amount_input, format_date, text2html text2html
from .template_globals import currency_options, default_currency_code from .template_globals import currency_options, default_currency_code
bp: Blueprint = Blueprint("transaction", __name__) bp: Blueprint = Blueprint("transaction", __name__)
"""The view blueprint for the transaction management.""" """The view blueprint for the transaction management."""
bp.add_app_template_filter(with_type, "accounting_txn_with_type") bp.add_app_template_filter(with_type, "accounting_txn_with_type")
bp.add_app_template_filter(to_transfer, "accounting_txn_to_transfer") bp.add_app_template_filter(to_transfer, "accounting_txn_to_transfer")
bp.add_app_template_filter(format_amount, "accounting_txn_format_amount")
bp.add_app_template_filter(format_amount_input, bp.add_app_template_filter(format_amount_input,
"accounting_txn_format_amount_input") "accounting_txn_format_amount_input")
bp.add_app_template_filter(format_date, "accounting_txn_format_date")
bp.add_app_template_filter(text2html, "accounting_txn_text2html") bp.add_app_template_filter(text2html, "accounting_txn_text2html")
bp.add_app_template_global(currency_options, "accounting_txn_currency_options") bp.add_app_template_global(currency_options, "accounting_txn_currency_options")
bp.add_app_template_global(default_currency_code, bp.add_app_template_global(default_currency_code,