Added the "default" filter to reduce the amount of logic in the templates, which differs from the Jinja2 "default" filter in that it looks for None instead of undefined values.

This commit is contained in:
依瑪貓 2023-03-06 02:13:37 +08:00
parent 8d126e183f
commit 9450915404
14 changed files with 45 additions and 33 deletions

View File

@ -58,9 +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 from .template_filters import format_amount, format_date, default
bp.add_app_template_filter(format_amount, "accounting_format_amount") bp.add_app_template_filter(format_amount, "accounting_format_amount")
bp.add_app_template_filter(format_date, "accounting_format_date") bp.add_app_template_filter(format_date, "accounting_format_date")
bp.add_app_template_filter(default, "accounting_default")
from .template_globals import currency_options, default_currency_code from .template_globals import currency_options, default_currency_code
bp.add_app_template_global(currency_options, bp.add_app_template_global(currency_options,

View File

@ -17,8 +17,9 @@
"""The template filters. """The template filters.
""" """
from decimal import Decimal import typing as t
from datetime import date, timedelta from datetime import date, timedelta
from decimal import Decimal
from flask_babel import get_locale from flask_babel import get_locale
@ -68,3 +69,13 @@ def format_date(value: date) -> str:
return "{}/{}/{}({})".format( return "{}/{}/{}({})".format(
value.year, value.month, value.day, weekday) value.year, value.month, value.day, weekday)
return "{}/{}({})".format(value.month, value.day, weekday) return "{}/{}({})".format(value.month, value.day, weekday)
def default(value: t.Any, default_value: t.Any = "") -> t.Any:
"""Returns the default value if the given value is None.
:param value: The value.
:param default_value: The default value when the given value is None.
:return: The value, or the default value if the given value is None.
"""
return default_value if value is None else value

View File

@ -40,7 +40,7 @@ First written: 2023/2/1
<input type="hidden" name="next" value="{{ request.args["next"] }}"> <input type="hidden" name="next" value="{{ request.args["next"] }}">
{% endif %} {% endif %}
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<input id="accounting-base-code" type="hidden" name="base_code" value="{{ "" if form.base_code.data is none else form.base_code.data }}"> <input id="accounting-base-code" type="hidden" name="base_code" value="{{ form.base_code.data|accounting_default }}">
<div id="accounting-base" class="form-control accounting-clickable accounting-material-text-field {% if form.base_code.data %} accounting-not-empty {% endif %} {% if form.base_code.errors %} is-invalid {% endif %}" data-bs-toggle="modal" data-bs-target="#accounting-base-selector-modal"> <div id="accounting-base" class="form-control accounting-clickable accounting-material-text-field {% if form.base_code.data %} accounting-not-empty {% endif %} {% if form.base_code.errors %} is-invalid {% endif %}" data-bs-toggle="modal" data-bs-target="#accounting-base-selector-modal">
<label class="form-label" for="accounting-base">{{ A_("Base account") }}</label> <label class="form-label" for="accounting-base">{{ A_("Base account") }}</label>
<div id="accounting-base-content"> <div id="accounting-base-content">
@ -57,7 +57,7 @@ First written: 2023/2/1
</div> </div>
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<input id="accounting-title" class="form-control {% if form.title.errors %} is-invalid {% endif %}" type="text" name="title" value="{{ "" if form.title.data is none else form.title.data }}" placeholder=" " required="required"> <input id="accounting-title" class="form-control {% if form.title.errors %} is-invalid {% endif %}" type="text" name="title" value="{{ form.title.data|accounting_default }}" placeholder=" " required="required">
<label class="form-label" for="accounting-title">{{ A_("Title") }}</label> <label class="form-label" for="accounting-title">{{ A_("Title") }}</label>
<div id="accounting-title-error" class="invalid-feedback">{% if form.title.errors %}{{ form.title.errors[0] }}{% endif %}</div> <div id="accounting-title-error" class="invalid-feedback">{% if form.title.errors %}{{ form.title.errors[0] }}{% endif %}</div>
</div> </div>

View File

@ -40,13 +40,13 @@ First written: 2023/2/6
<input type="hidden" name="next" value="{{ request.args["next"] }}"> <input type="hidden" name="next" value="{{ request.args["next"] }}">
{% endif %} {% endif %}
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<input id="accounting-code" class="form-control {% if form.code.errors %} is-invalid {% endif %}" type="text" name="code" value="{{ "" if form.code.data is none else form.code.data }}" placeholder=" " required="required" data-exists-url="{{ url_for("accounting.currency-api.exists") }}" data-original="{% block original_code %}{% endblock %}" data-blocklist="{{ form.CODE_BLOCKLIST|tojson|forceescape }}"> <input id="accounting-code" class="form-control {% if form.code.errors %} is-invalid {% endif %}" type="text" name="code" value="{{ form.code.data|accounting_default }}" placeholder=" " required="required" data-exists-url="{{ url_for("accounting.currency-api.exists") }}" data-original="{% block original_code %}{% endblock %}" data-blocklist="{{ form.CODE_BLOCKLIST|tojson|forceescape }}">
<label class="form-label" for="accounting-code">{{ A_("Code") }}</label> <label class="form-label" for="accounting-code">{{ A_("Code") }}</label>
<div id="accounting-code-error" class="invalid-feedback">{% if form.code.errors %}{{ form.code.errors[0] }}{% endif %}</div> <div id="accounting-code-error" class="invalid-feedback">{% if form.code.errors %}{{ form.code.errors[0] }}{% endif %}</div>
</div> </div>
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<input id="accounting-name" class="form-control {% if form.name.errors %} is-invalid {% endif %}" type="text" name="name" value="{{ "" if form.name.data is none else form.name.data }}" placeholder=" " required="required"> <input id="accounting-name" class="form-control {% if form.name.errors %} is-invalid {% endif %}" type="text" name="name" value="{{ form.name.data|accounting_default }}" placeholder=" " required="required">
<label class="form-label" for="accounting-name">{{ A_("Name") }}</label> <label class="form-label" for="accounting-name">{{ A_("Name") }}</label>
<div id="accounting-name-error" class="invalid-feedback">{% if form.name.errors %}{{ form.name.errors[0] }}{% endif %}</div> <div id="accounting-name-error" class="invalid-feedback">{% if form.name.errors %}{{ form.name.errors[0] }}{% endif %}</div>
</div> </div>

View File

@ -107,7 +107,7 @@ First written: 2023/3/4
{% if period_chooser.has_data %} {% if period_chooser.has_data %}
<div class="mt-3"> <div class="mt-3">
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<input id="accounting-period-chooser-day-date" class="form-control" type="date" value="{{ "" if period.start is none else period.start }}" min="{{ period_chooser.data_start }}" required="required"> <input id="accounting-period-chooser-day-date" class="form-control" type="date" value="{{ period.start|accounting_default }}" min="{{ period_chooser.data_start }}" required="required">
<label for="accounting-period-chooser-day-date" class="form-label">{{ A_("Date") }}</label> <label for="accounting-period-chooser-day-date" class="form-label">{{ A_("Date") }}</label>
<div id="accounting-period-chooser-day-date-error" class="invalid-feedback"></div> <div id="accounting-period-chooser-day-date-error" class="invalid-feedback"></div>
</div> </div>
@ -125,13 +125,13 @@ First written: 2023/3/4
{% if period_chooser.has_data %} {% if period_chooser.has_data %}
<div class="mt-3"> <div class="mt-3">
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<input id="accounting-period-chooser-custom-start" class="form-control" type="date" value="{{ "" if period.start is none else period.start }}" min="{{ period_chooser.data_start }}" max="{{ period.end }}" required="required"> <input id="accounting-period-chooser-custom-start" class="form-control" type="date" value="{{ period.start|accounting_default }}" min="{{ period_chooser.data_start }}" max="{{ period.end }}" required="required">
<label for="accounting-period-chooser-custom-start" class="form-label">{{ A_("From") }}</label> <label for="accounting-period-chooser-custom-start" class="form-label">{{ A_("From") }}</label>
<div id="accounting-period-chooser-custom-start-error" class="invalid-feedback"></div> <div id="accounting-period-chooser-custom-start-error" class="invalid-feedback"></div>
</div> </div>
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<input id="accounting-period-chooser-custom-end" class="form-control" type="date" value="{{ "" if period.end is none else period.end }}" min="{{ period.start }}" required="required"> <input id="accounting-period-chooser-custom-end" class="form-control" type="date" value="{{ period.end|accounting_default }}" min="{{ period.start }}" required="required">
<label for="accounting-period-chooser-custom-end" class="form-label">{{ A_("To") }}</label> <label for="accounting-period-chooser-custom-end" class="form-label">{{ A_("To") }}</label>
<div id="accounting-period-chooser-custom-end-error" class="invalid-feedback"></div> <div id="accounting-period-chooser-custom-end-error" class="invalid-feedback"></div>
</div> </div>

View File

@ -165,9 +165,9 @@ First written: 2023/3/5
<tr {% if item.transaction is not none %} class="accounting-clickable accounting-table-row-link" data-href="{{ url_for("accounting.transaction.detail", txn=item.transaction)|accounting_append_next }}" {% endif %}> <tr {% if item.transaction is not none %} class="accounting-clickable accounting-table-row-link" data-href="{{ url_for("accounting.transaction.detail", txn=item.transaction)|accounting_append_next }}" {% endif %}>
<td>{{ item.date|accounting_format_date }}</td> <td>{{ item.date|accounting_format_date }}</td>
<td>{{ item.account.title|title }}</td> <td>{{ item.account.title|title }}</td>
<td>{{ "" if item.summary is none else item.summary }}</td> <td>{{ item.summary|accounting_default }}</td>
<td class="accounting-amount">{{ "" if item.income is none else item.income|accounting_format_amount }}</td> <td class="accounting-amount">{{ item.income|accounting_format_amount|accounting_default }}</td>
<td class="accounting-amount">{{ "" if item.expense is none else item.expense|accounting_format_amount }}</td> <td class="accounting-amount">{{ item.expense|accounting_format_amount|accounting_default }}</td>
<td class="accounting-amount">{{ item.balance|accounting_format_amount }}</td> <td class="accounting-amount">{{ item.balance|accounting_format_amount }}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -108,7 +108,7 @@ First written: 2023/3/4
<td>{{ item.transaction.date|accounting_format_date }}</td> <td>{{ item.transaction.date|accounting_format_date }}</td>
<td>{{ item.currency.name }}</td> <td>{{ item.currency.name }}</td>
<td>{{ item.account.title|title }}</td> <td>{{ item.account.title|title }}</td>
<td>{{ "" if item.summary is none else item.summary }}</td> <td>{{ item.summary|accounting_default }}</td>
<td class="accounting-amount">{{ "" if not item.is_debit else item.amount|accounting_format_amount }}</td> <td class="accounting-amount">{{ "" if not item.is_debit else item.amount|accounting_format_amount }}</td>
<td class="accounting-amount">{{ "" if item.is_debit else item.amount|accounting_format_amount }}</td> <td class="accounting-amount">{{ "" if item.is_debit else item.amount|accounting_format_amount }}</td>
</tr> </tr>

View File

@ -163,9 +163,9 @@ First written: 2023/3/5
{% for item in list %} {% for item in list %}
<tr {% if item.transaction is not none %} class="accounting-clickable accounting-table-row-link" data-href="{{ url_for("accounting.transaction.detail", txn=item.transaction)|accounting_append_next }}" {% endif %}> <tr {% if item.transaction is not none %} class="accounting-clickable accounting-table-row-link" data-href="{{ url_for("accounting.transaction.detail", txn=item.transaction)|accounting_append_next }}" {% endif %}>
<td>{{ item.date|accounting_format_date }}</td> <td>{{ item.date|accounting_format_date }}</td>
<td>{{ "" if item.summary is none else item.summary }}</td> <td>{{ item.summary|accounting_default }}</td>
<td class="accounting-amount">{{ "" if item.debit is none else item.debit|accounting_format_amount }}</td> <td class="accounting-amount">{{ item.debit|accounting_format_amount|accounting_default }}</td>
<td class="accounting-amount">{{ "" if item.credit is none else item.credit|accounting_format_amount }}</td> <td class="accounting-amount">{{ item.credit|accounting_format_amount|accounting_default }}</td>
<td class="accounting-amount">{{ item.balance|accounting_format_amount }}</td> <td class="accounting-amount">{{ item.balance|accounting_format_amount }}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -134,8 +134,8 @@ First written: 2023/3/5
<a class="list-group-item d-flex justify-content-between accounting-report-row accounting-trial-balance-row" href="{{ item.url }}"> <a class="list-group-item d-flex justify-content-between accounting-report-row accounting-trial-balance-row" href="{{ item.url }}">
<div>{{ item.account|title }}</div> <div>{{ item.account|title }}</div>
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<div class="accounting-amount">{{ "" if item.debit is none else item.debit|accounting_format_amount }}</div> <div class="accounting-amount">{{ item.debit|accounting_format_amount|accounting_default }}</div>
<div class="accounting-amount">{{ "" if item.credit is none else item.credit|accounting_format_amount }}</div> <div class="accounting-amount">{{ item.credit|accounting_format_amount|accounting_default }}</div>
</div> </div>
</a> </a>
{% endfor %} {% endfor %}

View File

@ -50,14 +50,14 @@ First written: 2023/2/25
entry_index = loop.index, entry_index = loop.index,
entry_id = entry_form.eid.data, entry_id = entry_form.eid.data,
only_one_entry_form = debit_forms|length == 1, only_one_entry_form = debit_forms|length == 1,
account_code_data = "" if entry_form.account_code.data is none else entry_form.account_code.data, account_code_data = entry_form.account_code.data|accounting_default,
account_code_error = entry_form.account_code.errors, account_code_error = entry_form.account_code.errors,
account_text = entry_form.account_text, account_text = entry_form.account_text,
summary_data = "" if entry_form.summary.data is none else entry_form.summary.data, summary_data = entry_form.summary.data|accounting_default,
summary_errors = entry_form.summary.errors, summary_errors = entry_form.summary.errors,
amount_data = entry_form.amount.data|accounting_txn_format_amount_input, amount_data = 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_format_amount, amount_text = entry_form.amount.data|accounting_format_amount|accounting_default("-"),
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

@ -32,7 +32,7 @@ First written: 2023/2/25
<div id="accounting-currency-{{ currency_index }}-{{ entry_type }}-{{ entry_index }}-control" class="form-control clickable d-flex justify-content-between accounting-entry-control {% if entry_errors %} is-invalid {% endif %}" data-bs-toggle="modal" data-bs-target="#accounting-entry-form-modal"> <div id="accounting-currency-{{ currency_index }}-{{ entry_type }}-{{ entry_index }}-control" class="form-control clickable d-flex justify-content-between accounting-entry-control {% if entry_errors %} is-invalid {% endif %}" data-bs-toggle="modal" data-bs-target="#accounting-entry-form-modal">
<div> <div>
<div id="accounting-currency-{{ currency_index }}-{{ entry_type }}-{{ entry_index }}-account-text" class="small">{{ account_text }}</div> <div id="accounting-currency-{{ currency_index }}-{{ entry_type }}-{{ entry_index }}-account-text" class="small">{{ account_text }}</div>
<div id="accounting-currency-{{ currency_index }}-{{ entry_type }}-{{ entry_index }}-summary-text">{{ "" if summary_data is none else summary_data }}</div> <div id="accounting-currency-{{ currency_index }}-{{ entry_type }}-{{ entry_index }}-summary-text">{{ summary_data }}</div>
</div> </div>
<div><span id="accounting-currency-{{ currency_index }}-{{ entry_type }}-{{ entry_index }}-amount-text" class="badge rounded-pill bg-primary">{{ amount_text }}</span></div> <div><span id="accounting-currency-{{ currency_index }}-{{ entry_type }}-{{ entry_index }}-amount-text" class="badge rounded-pill bg-primary">{{ amount_text }}</span></div>
</div> </div>

View File

@ -44,7 +44,7 @@ First written: 2023/2/26
{% endif %} {% endif %}
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<input id="accounting-date" class="form-control {% if form.date.errors %} is-invalid {% endif %}" type="date" name="date" value="{{ "" if form.date.data is none else form.date.data }}" placeholder=" " required="required"> <input id="accounting-date" class="form-control {% if form.date.errors %} is-invalid {% endif %}" type="date" name="date" value="{{ form.date.data|accounting_default }}" placeholder=" " required="required">
<label class="form-label" for="accounting-date">{{ A_("Date") }}</label> <label class="form-label" for="accounting-date">{{ A_("Date") }}</label>
<div id="accounting-date-error" class="invalid-feedback">{% if form.date.errors %}{{ form.date.errors[0] }}{% endif %}</div> <div id="accounting-date-error" class="invalid-feedback">{% if form.date.errors %}{{ form.date.errors[0] }}{% endif %}</div>
</div> </div>
@ -67,7 +67,7 @@ First written: 2023/2/26
</div> </div>
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<textarea id="accounting-note" class="form-control form-control-lg {% if form.note.errors %} is-invalid {% endif %}" name="note" rows="5" placeholder=" ">{{ "" if form.note.data is none else form.note.data }}</textarea> <textarea id="accounting-note" class="form-control form-control-lg {% if form.note.errors %} is-invalid {% endif %}" name="note" rows="5" placeholder=" ">{{ form.note.data|accounting_default }}</textarea>
<label class="form-label" for="accounting-note">{{ A_("Note") }}</label> <label class="form-label" for="accounting-note">{{ A_("Note") }}</label>
<div id="accounting-note-error" class="invalid-feedback">{% if form.note.errors %}{{ form.note.errors[0] }}{% endif %}</div> <div id="accounting-note-error" class="invalid-feedback">{% if form.note.errors %}{{ form.note.errors[0] }}{% endif %}</div>
</div> </div>

View File

@ -50,14 +50,14 @@ First written: 2023/2/25
entry_index = loop.index, entry_index = loop.index,
only_one_entry_form = debit_forms|length == 1, only_one_entry_form = debit_forms|length == 1,
entry_id = entry_form.eid.data, entry_id = entry_form.eid.data,
account_code_data = "" if entry_form.account_code.data is none else entry_form.account_code.data, account_code_data = entry_form.account_code.data|accounting_default,
account_code_error = entry_form.account_code.errors, account_code_error = entry_form.account_code.errors,
account_text = entry_form.account_text, account_text = entry_form.account_text,
summary_data = "" if entry_form.summary.data is none else entry_form.summary.data, summary_data = entry_form.summary.data|accounting_default,
summary_errors = entry_form.summary.errors, summary_errors = entry_form.summary.errors,
amount_data = entry_form.amount.data|accounting_txn_format_amount_input, amount_data = 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_format_amount, amount_text = entry_form.amount.data|accounting_format_amount|accounting_default("-"),
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

@ -52,14 +52,14 @@ First written: 2023/2/25
entry_index = loop.index, entry_index = loop.index,
only_one_entry_form = debit_forms|length == 1, only_one_entry_form = debit_forms|length == 1,
entry_id = entry_form.eid.data, entry_id = entry_form.eid.data,
account_code_data = "" if entry_form.account_code.data is none else entry_form.account_code.data, account_code_data = entry_form.account_code.data|accounting_default,
account_code_error = entry_form.account_code.errors, account_code_error = entry_form.account_code.errors,
account_text = entry_form.account_text, account_text = entry_form.account_text,
summary_data = "" if entry_form.summary.data is none else entry_form.summary.data, summary_data = entry_form.summary.data|accounting_default,
summary_errors = entry_form.summary.errors, summary_errors = entry_form.summary.errors,
amount_data = entry_form.amount.data|accounting_txn_format_amount_input, amount_data = 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_format_amount, amount_text = entry_form.amount.data|accounting_format_amount|accounting_default("-"),
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 %}
@ -92,14 +92,14 @@ First written: 2023/2/25
entry_type = "credit", entry_type = "credit",
entry_index = loop.index, entry_index = loop.index,
only_one_entry_form = debit_forms|length == 1, only_one_entry_form = debit_forms|length == 1,
account_code_data = "" if entry_form.account_code.data is none else entry_form.account_code.data, account_code_data = entry_form.account_code.data|accounting_default,
account_code_error = entry_form.account_code.errors, account_code_error = entry_form.account_code.errors,
account_text = entry_form.account_text, account_text = entry_form.account_text,
summary_data = "" if entry_form.summary.data is none else entry_form.summary.data, summary_data = entry_form.summary.data|accounting_default,
summary_errors = entry_form.summary.errors, summary_errors = entry_form.summary.errors,
amount_data = entry_form.amount.data|accounting_txn_format_amount_input, amount_data = 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_format_amount, amount_text = entry_form.amount.data|accounting_format_amount|accounting_default("-"),
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 %}