Compare commits

...

10 Commits

14 changed files with 118 additions and 75 deletions

View File

@ -17,7 +17,7 @@
[metadata] [metadata]
name = mia-accounting-flask name = mia-accounting-flask
version = 0.3.0 version = 0.3.1
author = imacat author = imacat
author_email = imacat@mail.imacat.idv.tw author_email = imacat@mail.imacat.idv.tw
description = The Mia! Accounting Flask project. description = The Mia! Accounting Flask project.

View File

@ -530,17 +530,17 @@ function filterAccountOptions(prefix) {
const more = document.getElementById(prefix + "-more"); const more = document.getElementById(prefix + "-more");
const queryNoResult = document.getElementById(prefix + "-option-no-result"); const queryNoResult = document.getElementById(prefix + "-option-no-result");
const codesInUse = getAccountCodeUsedInForm(); const codesInUse = getAccountCodeUsedInForm();
let hasAnyMatched = false; let shouldAnyShow = false;
options.forEach(function (option) { options.forEach(function (option) {
const isMatched = shouldAccountOptionShow(option, more, codesInUse, query); const shouldShow = shouldAccountOptionShow(option, more, codesInUse, query);
if (isMatched) { if (shouldShow) {
option.classList.remove("d-none"); option.classList.remove("d-none");
hasAnyMatched = true; shouldAnyShow = true;
} else { } else {
option.classList.add("d-none"); option.classList.add("d-none");
} }
}); });
if (!hasAnyMatched) { if (!shouldAnyShow && more.classList.contains("d-none")) {
optionList.classList.add("d-none"); optionList.classList.add("d-none");
queryNoResult.classList.remove("d-none"); queryNoResult.classList.remove("d-none");
} else { } else {

View File

@ -21,6 +21,13 @@ First written: 2023/2/26
#} #}
{% extends "accounting/transaction/include/detail.html" %} {% extends "accounting/transaction/include/detail.html" %}
{% block to_transfer %}
<a class="btn btn-primary" href="{{ url_for("accounting.transaction.edit", txn=obj)|accounting_txn_to_transfer|accounting_inherit_next }}">
<i class="fa-solid fa-bars-staggered"></i>
{{ A_("To Transfer") }}
</a>
{% endblock %}
{% block transaction_currencies %} {% block transaction_currencies %}
{% for currency in obj.currencies %} {% for currency in obj.currencies %}
<div class="mb-3"> <div class="mb-3">
@ -43,7 +50,7 @@ First written: 2023/2/26
{% 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>{{ _("Total") }}</div> <div>{{ A_("Total") }}</div>
<div>{{ currency.debit_total|accounting_txn_format_amount }}</div> <div>{{ currency.debit_total|accounting_txn_format_amount }}</div>
</div> </div>
</li> </li>

View File

@ -55,7 +55,7 @@ First written: 2023/2/25
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 = "" if entry_form.summary.data is none else entry_form.summary.data,
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, 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_txn_format_amount,
entry_errors = entry_form.all_errors %} entry_errors = entry_form.all_errors %}

View File

@ -41,6 +41,7 @@ First written: 2023/2/26
{{ A_("Order") }} {{ A_("Order") }}
</a> </a>
{% if accounting_can_edit() %} {% if accounting_can_edit() %}
{% block to_transfer %}{% endblock %}
<button class="btn btn-danger" type="button" data-bs-toggle="modal" data-bs-target="#accounting-delete-modal"> <button class="btn btn-danger" type="button" data-bs-toggle="modal" data-bs-target="#accounting-delete-modal">
<i class="fa-solid fa-trash"></i> <i class="fa-solid fa-trash"></i>
{{ A_("Delete") }} {{ A_("Delete") }}

View File

@ -34,7 +34,7 @@ First written: 2023/2/25
<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">{{ "" if summary_data is none else 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_data }}</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>
<div id="accounting-currency-{{ currency_index }}-{{ entry_type }}-{{ entry_index }}-error" class="invalid-feedback">{% if entry_errors %}{{ entry_errors[0] }}{% endif %}</div> <div id="accounting-currency-{{ currency_index }}-{{ entry_type }}-{{ entry_index }}-error" class="invalid-feedback">{% if entry_errors %}{{ entry_errors[0] }}{% endif %}</div>
</div> </div>

View File

@ -21,6 +21,13 @@ First written: 2023/2/26
#} #}
{% extends "accounting/transaction/include/detail.html" %} {% extends "accounting/transaction/include/detail.html" %}
{% block to_transfer %}
<a class="btn btn-primary" href="{{ url_for("accounting.transaction.edit", txn=obj)|accounting_txn_to_transfer|accounting_inherit_next }}">
<i class="fa-solid fa-bars-staggered"></i>
{{ A_("To Transfer") }}
</a>
{% endblock %}
{% block transaction_currencies %} {% block transaction_currencies %}
{% for currency in obj.currencies %} {% for currency in obj.currencies %}
<div class="mb-3"> <div class="mb-3">
@ -43,7 +50,7 @@ First written: 2023/2/26
{% 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>{{ _("Total") }}</div> <div>{{ A_("Total") }}</div>
<div>{{ currency.debit_total|accounting_txn_format_amount }}</div> <div>{{ currency.debit_total|accounting_txn_format_amount }}</div>
</div> </div>
</li> </li>

View File

@ -55,7 +55,7 @@ First written: 2023/2/25
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 = "" if entry_form.summary.data is none else entry_form.summary.data,
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, 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_txn_format_amount,
entry_errors = entry_form.all_errors %} entry_errors = entry_form.all_errors %}

View File

@ -46,7 +46,7 @@ First written: 2023/2/26
{% 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>{{ _("Total") }}</div> <div>{{ A_("Total") }}</div>
<div>{{ currency.debit_total|accounting_txn_format_amount }}</div> <div>{{ currency.debit_total|accounting_txn_format_amount }}</div>
</div> </div>
</li> </li>
@ -72,7 +72,7 @@ First written: 2023/2/26
{% 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>{{ _("Total") }}</div> <div>{{ A_("Total") }}</div>
<div>{{ currency.debit_total|accounting_txn_format_amount }}</div> <div>{{ currency.debit_total|accounting_txn_format_amount }}</div>
</div> </div>
</li> </li>

View File

@ -97,7 +97,7 @@ First written: 2023/2/25
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 = "" if entry_form.summary.data is none else entry_form.summary.data,
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, 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_txn_format_amount,
entry_errors = entry_form.all_errors %} entry_errors = entry_form.all_errors %}

View File

@ -284,13 +284,11 @@ class TransactionForm(FlaskForm):
self.__set_date(obj, self.date.data) self.__set_date(obj, self.date.data)
obj.note = self.note.data obj.note = self.note.data
entries: list[JournalEntry] = obj.entries
collector_cls: t.Type[JournalEntryCollector] = self.collector collector_cls: t.Type[JournalEntryCollector] = self.collector
collector: collector_cls = collector_cls(self, obj.id, entries, collector: collector_cls = collector_cls(self, obj)
obj.currencies)
collector.collect() collector.collect()
to_delete: set[int] = {x.id for x in entries to_delete: set[int] = {x.id for x in obj.entries
if x.id not in collector.to_keep} if x.id not in collector.to_keep}
if len(to_delete) > 0: if len(to_delete) > 0:
JournalEntry.query.filter(JournalEntry.id.in_(to_delete)).delete() JournalEntry.query.filter(JournalEntry.id.in_(to_delete)).delete()
@ -373,27 +371,24 @@ T = t.TypeVar("T", bound=TransactionForm)
class JournalEntryCollector(t.Generic[T], ABC): class JournalEntryCollector(t.Generic[T], ABC):
"""The journal entry collector.""" """The journal entry collector."""
def __init__(self, form: T, txn_id: int, entries: list[JournalEntry], def __init__(self, form: T, obj: Transaction):
currencies: list[TransactionCurrency]):
"""Constructs the journal entry collector. """Constructs the journal entry collector.
:param form: The transaction form. :param form: The transaction form.
:param txn_id: The transaction ID. :param obj: The transaction.
:param entries: The existing journal entries.
:param currencies: The currencies in the transaction.
""" """
self.form: T = form self.form: T = form
"""The transaction form.""" """The transaction form."""
self.entries: list[JournalEntry] = entries self.__obj: Transaction = obj
"""The transaction object."""
self.__entries: list[JournalEntry] = list(obj.entries)
"""The existing journal entries.""" """The existing journal entries."""
self.txn_id: int = txn_id
"""The transaction ID."""
self.__entries_by_id: dict[int, JournalEntry] \ self.__entries_by_id: dict[int, JournalEntry] \
= {x.id: x for x in entries} = {x.id: x for x in self.__entries}
"""A dictionary from the entry ID to their entries.""" """A dictionary from the entry ID to their entries."""
self.__no_by_id: dict[int, int] = {x.id: x.no for x in entries} self.__no_by_id: dict[int, int] = {x.id: x.no for x in self.__entries}
"""A dictionary from the entry number to their entries.""" """A dictionary from the entry number to their entries."""
self.__currencies: list[TransactionCurrency] = currencies self.__currencies: list[TransactionCurrency] = obj.currencies
"""The currencies in the transaction.""" """The currencies in the transaction."""
self._debit_no: int = 1 self._debit_no: int = 1
"""The number index for the debit entries.""" """The number index for the debit entries."""
@ -420,7 +415,6 @@ class JournalEntryCollector(t.Generic[T], ABC):
""" """
entry: JournalEntry | None = self.__entries_by_id.get(form.eid.data) entry: JournalEntry | None = self.__entries_by_id.get(form.eid.data)
if entry is not None: if entry is not None:
self.to_keep.add(entry.id)
entry.currency_code = currency_code entry.currency_code = currency_code
form.populate_obj(entry) form.populate_obj(entry)
entry.no = no entry.no = no
@ -428,12 +422,12 @@ class JournalEntryCollector(t.Generic[T], ABC):
self.form.is_modified = True self.form.is_modified = True
else: else:
entry = JournalEntry() entry = JournalEntry()
entry.transaction_id = self.txn_id
entry.currency_code = currency_code entry.currency_code = currency_code
form.populate_obj(entry) form.populate_obj(entry)
entry.no = no entry.no = no
db.session.add(entry) self.__obj.entries.append(entry)
self.form.is_modified = True self.form.is_modified = True
self.to_keep.add(entry.id)
def _make_cash_entry(self, forms: list[JournalEntryForm], is_debit: bool, def _make_cash_entry(self, forms: list[JournalEntryForm], is_debit: bool,
currency_code: str, no: int) -> None: currency_code: str, no: int) -> None:
@ -447,14 +441,13 @@ class JournalEntryCollector(t.Generic[T], ABC):
:param no: The number of the entry. :param no: The number of the entry.
:return: None. :return: None.
""" """
candidates: list[JournalEntry] = [x for x in self.entries candidates: list[JournalEntry] = [x for x in self.__entries
if x.is_debit == is_debit if x.is_debit == is_debit
and x.currency_code == currency_code] and x.currency_code == currency_code]
entry: JournalEntry entry: JournalEntry
if len(candidates) > 0: if len(candidates) > 0:
candidates.sort(key=lambda x: x.no) candidates.sort(key=lambda x: x.no)
entry = candidates[0] entry = candidates[0]
self.to_keep.add(entry.id)
entry.account_id = Account.cash().id entry.account_id = Account.cash().id
entry.summary = None entry.summary = None
entry.amount = sum([x.amount.data for x in forms]) entry.amount = sum([x.amount.data for x in forms])
@ -464,15 +457,15 @@ class JournalEntryCollector(t.Generic[T], ABC):
else: else:
entry = JournalEntry() entry = JournalEntry()
entry.id = new_id(JournalEntry) entry.id = new_id(JournalEntry)
entry.transaction_id = self.txn_id
entry.is_debit = is_debit entry.is_debit = is_debit
entry.currency_code = currency_code entry.currency_code = currency_code
entry.account_id = Account.cash().id entry.account_id = Account.cash().id
entry.summary = None entry.summary = None
entry.amount = sum([x.amount.data for x in forms]) entry.amount = sum([x.amount.data for x in forms])
entry.no = no entry.no = no
db.session.add(entry) self.__obj.entries.append(entry)
self.form.is_modified = True self.form.is_modified = True
self.to_keep.add(entry.id)
def _sort_entry_forms(self, forms: list[JournalEntryForm]) -> None: def _sort_entry_forms(self, forms: list[JournalEntryForm]) -> None:
"""Sorts the journal entry forms. """Sorts the journal entry forms.

View File

@ -40,13 +40,28 @@ def with_type(uri: str) -> str:
return uri return uri
uri_p: ParseResult = urlparse(uri) uri_p: ParseResult = urlparse(uri)
params: list[tuple[str, str]] = parse_qsl(uri_p.query) params: list[tuple[str, str]] = parse_qsl(uri_p.query)
params = [x for x in params if x[0] != "next"] params = [x for x in params if x[0] != "as"]
params.append(("as", request.args["as"])) params.append(("as", request.args["as"]))
parts: list[str] = list(uri_p) parts: list[str] = list(uri_p)
parts[4] = urlencode(params) parts[4] = urlencode(params)
return urlunparse(parts) return urlunparse(parts)
def to_transfer(uri: str) -> str:
"""Adds the transfer transaction type to the URI.
:param uri: The URI.
:return: The result URL, with the transfer transaction type added.
"""
uri_p: ParseResult = urlparse(uri)
params: list[tuple[str, str]] = parse_qsl(uri_p.query)
params = [x for x in params if x[0] != "as"]
params.append(("as", "transfer"))
parts: list[str] = list(uri_p)
parts[4] = urlencode(params)
return urlunparse(parts)
def format_amount(value: Decimal | None) -> str: def format_amount(value: Decimal | None) -> str:
"""Formats an amount for readability. """Formats an amount for readability.
@ -60,6 +75,17 @@ def format_amount(value: Decimal | None) -> str:
return "{:,}".format(whole) + str(frac)[1:] return "{:,}".format(whole) + str(frac)[1:]
def format_amount_input(value: Decimal) -> str:
"""Format an amount for an input value.
:param value: The amount.
:return: The formatted amount text for an input value.
"""
whole: int = int(value)
frac: Decimal = (value - whole).normalize()
return str(whole) + str(frac)[1:]
def format_date(value: date) -> str: def format_date(value: date) -> str:
"""Formats a date to be human-friendly. """Formats a date to be human-friendly.

View File

@ -34,15 +34,19 @@ from accounting.utils.pagination import Pagination
from accounting.utils.permission import has_permission, can_view, can_edit from accounting.utils.permission import has_permission, can_view, can_edit
from accounting.utils.user import get_current_user_pk 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 .template import with_type, format_amount, format_date, text2html, \
currency_options, default_currency_code
from .forms import sort_transactions_in, TransactionReorderForm from .forms import sort_transactions_in, TransactionReorderForm
from .query import get_transaction_query from .query import get_transaction_query
from .template import with_type, to_transfer, format_amount, \
format_amount_input, format_date, text2html, 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(format_amount, "accounting_txn_format_amount") bp.add_app_template_filter(format_amount, "accounting_txn_format_amount")
bp.add_app_template_filter(format_amount_input,
"accounting_txn_format_amount_input")
bp.add_app_template_filter(format_date, "accounting_txn_format_date") 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")

View File

@ -8,8 +8,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Mia! Accounting Flask 0.0.0\n" "Project-Id-Version: Mia! Accounting Flask 0.0.0\n"
"Report-Msgid-Bugs-To: imacat@mail.imacat.idv.tw\n" "Report-Msgid-Bugs-To: imacat@mail.imacat.idv.tw\n"
"POT-Creation-Date: 2023-02-27 15:28+0800\n" "POT-Creation-Date: 2023-02-27 18:59+0800\n"
"PO-Revision-Date: 2023-02-27 15:29+0800\n" "PO-Revision-Date: 2023-02-27 18:59+0800\n"
"Last-Translator: imacat <imacat@mail.imacat.idv.tw>\n" "Last-Translator: imacat <imacat@mail.imacat.idv.tw>\n"
"Language: zh_Hant\n" "Language: zh_Hant\n"
"Language-Team: zh_Hant <imacat@mail.imacat.idv.tw>\n" "Language-Team: zh_Hant <imacat@mail.imacat.idv.tw>\n"
@ -61,23 +61,23 @@ msgstr "逐筆核銷"
msgid "The account is added successfully" msgid "The account is added successfully"
msgstr "科目加好了。" msgstr "科目加好了。"
#: src/accounting/account/views.py:142 #: src/accounting/account/views.py:141
msgid "The account was not modified." msgid "The account was not modified."
msgstr "科目未異動。" msgstr "科目未異動。"
#: src/accounting/account/views.py:148 #: src/accounting/account/views.py:146
msgid "The account is updated successfully." msgid "The account is updated successfully."
msgstr "科目存好了。" msgstr "科目存好了。"
#: src/accounting/account/views.py:165 #: src/accounting/account/views.py:162
msgid "The account is deleted successfully." msgid "The account is deleted successfully."
msgstr "科目刪掉了" msgstr "科目刪掉了"
#: src/accounting/account/views.py:192 src/accounting/transaction/views.py:210 #: src/accounting/account/views.py:189 src/accounting/transaction/views.py:214
msgid "The order was not modified." msgid "The order was not modified."
msgstr "順序未異動。" msgstr "順序未異動。"
#: src/accounting/account/views.py:195 src/accounting/transaction/views.py:213 #: src/accounting/account/views.py:192 src/accounting/transaction/views.py:217
msgid "The order is updated successfully." msgid "The order is updated successfully."
msgstr "順序存好了。" msgstr "順序存好了。"
@ -110,15 +110,15 @@ msgstr "請填上名稱。"
msgid "The currency is added successfully" msgid "The currency is added successfully"
msgstr "貨幣加好了。" msgstr "貨幣加好了。"
#: src/accounting/currency/views.py:145 #: src/accounting/currency/views.py:144
msgid "The currency was not modified." msgid "The currency was not modified."
msgstr "貨幣未異動。" msgstr "貨幣未異動。"
#: src/accounting/currency/views.py:151 #: src/accounting/currency/views.py:149
msgid "The currency is updated successfully." msgid "The currency is updated successfully."
msgstr "貨幣存好了。" msgstr "貨幣存好了。"
#: src/accounting/currency/views.py:167 #: src/accounting/currency/views.py:164
msgid "The currency is deleted successfully." msgid "The currency is deleted successfully."
msgstr "貨幣刪掉了" msgstr "貨幣刪掉了"
@ -185,7 +185,7 @@ msgstr "次序"
#: src/accounting/templates/accounting/account/detail.html:46 #: src/accounting/templates/accounting/account/detail.html:46
#: src/accounting/templates/accounting/currency/detail.html:42 #: src/accounting/templates/accounting/currency/detail.html:42
#: src/accounting/templates/accounting/transaction/include/detail.html:46 #: src/accounting/templates/accounting/transaction/include/detail.html:47
msgid "Delete" msgid "Delete"
msgstr "刪除" msgstr "刪除"
@ -198,7 +198,7 @@ msgstr "科目刪除確認"
#: src/accounting/templates/accounting/currency/detail.html:66 #: src/accounting/templates/accounting/currency/detail.html:66
#: src/accounting/templates/accounting/transaction/include/credit-account-modal.html:27 #: src/accounting/templates/accounting/transaction/include/credit-account-modal.html:27
#: src/accounting/templates/accounting/transaction/include/debit-account-modal.html:27 #: src/accounting/templates/accounting/transaction/include/debit-account-modal.html:27
#: src/accounting/templates/accounting/transaction/include/detail.html:70 #: src/accounting/templates/accounting/transaction/include/detail.html:71
#: src/accounting/templates/accounting/transaction/include/entry-form-modal.html:28 #: src/accounting/templates/accounting/transaction/include/entry-form-modal.html:28
msgid "Close" msgid "Close"
msgstr "關閉" msgstr "關閉"
@ -212,26 +212,26 @@ msgstr "你確定要刪掉這個科目嗎?"
#: src/accounting/templates/accounting/currency/detail.html:72 #: src/accounting/templates/accounting/currency/detail.html:72
#: src/accounting/templates/accounting/transaction/include/credit-account-modal.html:49 #: src/accounting/templates/accounting/transaction/include/credit-account-modal.html:49
#: src/accounting/templates/accounting/transaction/include/debit-account-modal.html:49 #: src/accounting/templates/accounting/transaction/include/debit-account-modal.html:49
#: src/accounting/templates/accounting/transaction/include/detail.html:76 #: src/accounting/templates/accounting/transaction/include/detail.html:77
#: src/accounting/templates/accounting/transaction/include/entry-form-modal.html:52 #: src/accounting/templates/accounting/transaction/include/entry-form-modal.html:52
msgid "Cancel" msgid "Cancel"
msgstr "取消" msgstr "取消"
#: src/accounting/templates/accounting/account/detail.html:77 #: src/accounting/templates/accounting/account/detail.html:77
#: src/accounting/templates/accounting/currency/detail.html:73 #: src/accounting/templates/accounting/currency/detail.html:73
#: src/accounting/templates/accounting/transaction/include/detail.html:77 #: src/accounting/templates/accounting/transaction/include/detail.html:78
msgid "Confirm" msgid "Confirm"
msgstr "確定" msgstr "確定"
#: src/accounting/templates/accounting/account/detail.html:94 #: src/accounting/templates/accounting/account/detail.html:94
#: src/accounting/templates/accounting/currency/detail.html:85 #: src/accounting/templates/accounting/currency/detail.html:85
#: src/accounting/templates/accounting/transaction/include/detail.html:106 #: src/accounting/templates/accounting/transaction/include/detail.html:107
msgid "Created" msgid "Created"
msgstr "建檔" msgstr "建檔"
#: src/accounting/templates/accounting/account/detail.html:95 #: src/accounting/templates/accounting/account/detail.html:95
#: src/accounting/templates/accounting/currency/detail.html:86 #: src/accounting/templates/accounting/currency/detail.html:86
#: src/accounting/templates/accounting/transaction/include/detail.html:107 #: src/accounting/templates/accounting/transaction/include/detail.html:108
msgid "Updated" msgid "Updated"
msgstr "更新" msgstr "更新"
@ -375,23 +375,23 @@ msgstr "代碼"
msgid "Name" msgid "Name"
msgstr "名稱" msgstr "名稱"
#: src/accounting/templates/accounting/include/nav.html:26 #: src/accounting/templates/accounting/include/nav.html:27
msgid "Accounting" msgid "Accounting"
msgstr "記帳" msgstr "記帳"
#: src/accounting/templates/accounting/include/nav.html:32 #: src/accounting/templates/accounting/include/nav.html:33
msgid "Transactions" msgid "Transactions"
msgstr "傳票" msgstr "傳票"
#: src/accounting/templates/accounting/include/nav.html:38 #: src/accounting/templates/accounting/include/nav.html:39
msgid "Accounts" msgid "Accounts"
msgstr "科目" msgstr "科目"
#: src/accounting/templates/accounting/include/nav.html:44 #: src/accounting/templates/accounting/include/nav.html:45
msgid "Base Accounts" msgid "Base Accounts"
msgstr "基本科目" msgstr "基本科目"
#: src/accounting/templates/accounting/include/nav.html:50 #: src/accounting/templates/accounting/include/nav.html:51
msgid "Currencies" msgid "Currencies"
msgstr "貨幣" msgstr "貨幣"
@ -425,17 +425,22 @@ msgstr "%(date)s的傳票"
msgid "Add a New Cash Expense Transaction" msgid "Add a New Cash Expense Transaction"
msgstr "新增現金支出傳票" msgstr "新增現金支出傳票"
#: src/accounting/templates/accounting/transaction/expense/detail.html:30 #: src/accounting/templates/accounting/transaction/expense/detail.html:27
#: src/accounting/templates/accounting/transaction/income/detail.html:27
msgid "To Transfer"
msgstr "改轉帳"
#: src/accounting/templates/accounting/transaction/expense/detail.html:37
#: src/accounting/templates/accounting/transaction/expense/include/form-currency-item.html:45 #: src/accounting/templates/accounting/transaction/expense/include/form-currency-item.html:45
#: src/accounting/templates/accounting/transaction/include/form.html:52 #: src/accounting/templates/accounting/transaction/include/form.html:52
#: src/accounting/templates/accounting/transaction/income/detail.html:30 #: src/accounting/templates/accounting/transaction/income/detail.html:37
#: src/accounting/templates/accounting/transaction/income/include/form-currency-item.html:45 #: src/accounting/templates/accounting/transaction/income/include/form-currency-item.html:45
msgid "Content" msgid "Content"
msgstr "內容" msgstr "內容"
#: src/accounting/templates/accounting/transaction/expense/detail.html:46 #: src/accounting/templates/accounting/transaction/expense/detail.html:53
#: src/accounting/templates/accounting/transaction/expense/include/form-currency-item.html:68 #: src/accounting/templates/accounting/transaction/expense/include/form-currency-item.html:68
#: src/accounting/templates/accounting/transaction/income/detail.html:46 #: src/accounting/templates/accounting/transaction/income/detail.html:53
#: src/accounting/templates/accounting/transaction/income/include/form-currency-item.html:68 #: src/accounting/templates/accounting/transaction/income/include/form-currency-item.html:68
#: src/accounting/templates/accounting/transaction/transfer/detail.html:49 #: src/accounting/templates/accounting/transaction/transfer/detail.html:49
#: src/accounting/templates/accounting/transaction/transfer/detail.html:75 #: src/accounting/templates/accounting/transaction/transfer/detail.html:75
@ -478,11 +483,11 @@ msgstr "更多…"
msgid "Select Debit Account" msgid "Select Debit Account"
msgstr "選擇借方科目" msgstr "選擇借方科目"
#: src/accounting/templates/accounting/transaction/include/detail.html:69 #: src/accounting/templates/accounting/transaction/include/detail.html:70
msgid "Delete Transaction Confirmation" msgid "Delete Transaction Confirmation"
msgstr "傳票刪除確認" msgstr "傳票刪除確認"
#: src/accounting/templates/accounting/transaction/include/detail.html:73 #: src/accounting/templates/accounting/transaction/include/detail.html:74
msgid "Do you really want to delete this transaction?" msgid "Do you really want to delete this transaction?"
msgstr "你確定要刪掉這張傳票嗎?" msgstr "你確定要刪掉這張傳票嗎?"
@ -552,39 +557,39 @@ msgstr "科目不是借方科目。"
msgid "This account is not for credit entries." msgid "This account is not for credit entries."
msgstr "科目不是貸方科目。" msgstr "科目不是貸方科目。"
#: src/accounting/transaction/template.py:71 #: src/accounting/transaction/template.py:97
msgid "Today" msgid "Today"
msgstr "今天" msgstr "今天"
#: src/accounting/transaction/template.py:73 #: src/accounting/transaction/template.py:99
msgid "Yesterday" msgid "Yesterday"
msgstr "昨天" msgstr "昨天"
#: src/accounting/transaction/template.py:75 #: src/accounting/transaction/template.py:101
msgid "Tomorrow" msgid "Tomorrow"
msgstr "明天" msgstr "明天"
#: src/accounting/transaction/template.py:79 #: src/accounting/transaction/template.py:105
msgid "The day before yesterday" msgid "The day before yesterday"
msgstr "前天" msgstr "前天"
#: src/accounting/transaction/template.py:81 #: src/accounting/transaction/template.py:107
msgid "The day after tomorrow" msgid "The day after tomorrow"
msgstr "後天" msgstr "後天"
#: src/accounting/transaction/views.py:104 #: src/accounting/transaction/views.py:108
msgid "The transaction is added successfully" msgid "The transaction is added successfully"
msgstr "傳票加好了。" msgstr "傳票加好了。"
#: src/accounting/transaction/views.py:158 #: src/accounting/transaction/views.py:162
msgid "The transaction was not modified." msgid "The transaction was not modified."
msgstr "傳票未異動。" msgstr "傳票未異動。"
#: src/accounting/transaction/views.py:163 #: src/accounting/transaction/views.py:167
msgid "The transaction is updated successfully." msgid "The transaction is updated successfully."
msgstr "傳票存好了。" msgstr "傳票存好了。"
#: src/accounting/transaction/views.py:179 #: src/accounting/transaction/views.py:183
msgid "The transaction is deleted successfully." msgid "The transaction is deleted successfully."
msgstr "傳票刪掉了" msgstr "傳票刪掉了"