Compare commits

...

6 Commits

19 changed files with 74 additions and 60 deletions

View File

@ -13,12 +13,21 @@ module for the Flask_ applications.
Install
=======
Install the latest source from the
`Mia! Accounting repository`_.
Install ``mia-accounting`` with ``pip``.
::
pip install git+https://github.com/imacat/mia-accounting.git
pip install mia-accounting
Usage
=====
This needs to be done. Currently, you can refer to the test site
located in the test directory on the `Mia! Accounting repository`_.
The test site is running as the
`live demonstration for Mia! Accounting`_.
Copyright
@ -48,3 +57,4 @@ Authors
.. _Flask: https://flask.palletsprojects.com
.. _Mia! Accounting repository: https://github.com/imacat/mia-accounting
.. _live demonstration for Mia! Accounting: https://accounting.imacat.idv.tw

View File

@ -47,7 +47,6 @@ def init_app(app: Flask, user_utils: UserUtilityInterface,
init_user_utils(user_utils)
bp: Blueprint = Blueprint("accounting", __name__,
url_prefix=url_prefix,
template_folder="templates",
static_folder="static")
@ -84,9 +83,9 @@ def init_app(app: Flask, user_utils: UserUtilityInterface,
journal_entry.init_app(app, bp)
from . import report
report.init_app(app, bp)
report.init_app(app, url_prefix)
from . import option
option.init_app(bp)
app.register_blueprint(bp)
app.register_blueprint(bp, url_prefix=url_prefix)

View File

@ -77,6 +77,7 @@ def get_selectable_original_line_items(
.options(selectinload(JournalEntryLineItem.currency),
selectinload(JournalEntryLineItem.account),
selectinload(JournalEntryLineItem.journal_entry)).all()
line_items.reverse()
for line_item in line_items:
line_item.net_balance = line_item.amount \
if net_balances[line_item.id] is None \

View File

@ -235,4 +235,4 @@ def __get_default_page_uri() -> str:
:return: The URI for the default page.
"""
return url_for("accounting.report.default")
return url_for("accounting-report.default")

View File

@ -17,14 +17,14 @@
"""The report management.
"""
from flask import Flask, Blueprint
from flask import Flask
def init_app(app: Flask, bp: Blueprint) -> None:
def init_app(app: Flask, url_prefix: str) -> None:
"""Initialize the application.
:param app: The Flask application.
:param bp: The blueprint of the accounting application.
:param url_prefix: The URL prefix of the accounting application.
:return: None.
"""
from .converters import PeriodConverter, IncomeExpensesAccountConverter
@ -32,4 +32,4 @@ def init_app(app: Flask, bp: Blueprint) -> None:
app.url_map.converters["ieAccount"] = IncomeExpensesAccountConverter
from .views import bp as report_bp
bp.register_blueprint(report_bp, url_prefix="/reports")
app.register_blueprint(report_bp, url_prefix=url_prefix)

View File

@ -68,9 +68,9 @@ class ReportChooser:
"""The title of the current report."""
self.is_search: bool = active_report == ReportType.SEARCH
"""Whether the current report is the search page."""
self.__reports.append(self.__journal)
self.__reports.append(self.__ledger)
self.__reports.append(self.__income_expenses)
self.__reports.append(self.__ledger)
self.__reports.append(self.__journal)
self.__reports.append(self.__trial_balance)
self.__reports.append(self.__income_statement)
self.__reports.append(self.__balance_sheet)
@ -80,28 +80,6 @@ class ReportChooser:
if self.is_search:
self.current_report = gettext("Search")
@property
def __journal(self) -> OptionLink:
"""Returns the journal.
:return: The journal.
"""
return OptionLink(gettext("Journal"), journal_url(self.__period),
self.__active_report == ReportType.JOURNAL,
fa_icon="fa-solid fa-book")
@property
def __ledger(self) -> OptionLink:
"""Returns the ledger.
:return: The ledger.
"""
return OptionLink(gettext("Ledger"),
ledger_url(self.__currency, self.__account,
self.__period),
self.__active_report == ReportType.LEDGER,
fa_icon="fa-solid fa-clipboard")
@property
def __income_expenses(self) -> OptionLink:
"""Returns the income and expenses log.
@ -118,6 +96,28 @@ class ReportChooser:
self.__active_report == ReportType.INCOME_EXPENSES,
fa_icon="fa-solid fa-money-bill-wave")
@property
def __ledger(self) -> OptionLink:
"""Returns the ledger.
:return: The ledger.
"""
return OptionLink(gettext("Ledger"),
ledger_url(self.__currency, self.__account,
self.__period),
self.__active_report == ReportType.LEDGER,
fa_icon="fa-solid fa-clipboard")
@property
def __journal(self) -> OptionLink:
"""Returns the journal.
:return: The journal.
"""
return OptionLink(gettext("Journal"), journal_url(self.__period),
self.__active_report == ReportType.JOURNAL,
fa_icon="fa-solid fa-book")
@property
def __trial_balance(self) -> OptionLink:
"""Returns the trial balance.

View File

@ -34,8 +34,8 @@ def journal_url(period: Period) \
:return: The URL of the journal.
"""
if period.is_default:
return url_for("accounting.report.journal-default")
return url_for("accounting.report.journal", period=period)
return url_for("accounting-report.journal-default")
return url_for("accounting-report.journal", period=period)
def ledger_url(currency: Currency, account: Account, period: Period) \
@ -48,9 +48,9 @@ def ledger_url(currency: Currency, account: Account, period: Period) \
:return: The URL of the ledger.
"""
if period.is_default:
return url_for("accounting.report.ledger-default",
return url_for("accounting-report.ledger-default",
currency=currency, account=account)
return url_for("accounting.report.ledger",
return url_for("accounting-report.ledger",
currency=currency, account=account,
period=period)
@ -67,11 +67,11 @@ def income_expenses_url(currency: Currency, account: CurrentAccount,
if currency.code == default_currency_code() \
and account.code == options.default_ie_account_code \
and period.is_default:
return url_for("accounting.report.default")
return url_for("accounting-report.default")
if period.is_default:
return url_for("accounting.report.income-expenses-default",
return url_for("accounting-report.income-expenses-default",
currency=currency, account=account)
return url_for("accounting.report.income-expenses",
return url_for("accounting-report.income-expenses",
currency=currency, account=account,
period=period)
@ -84,9 +84,9 @@ def trial_balance_url(currency: Currency, period: Period) -> str:
:return: The URL of the trial balance.
"""
if period.is_default:
return url_for("accounting.report.trial-balance-default",
return url_for("accounting-report.trial-balance-default",
currency=currency)
return url_for("accounting.report.trial-balance",
return url_for("accounting-report.trial-balance",
currency=currency, period=period)
@ -98,9 +98,9 @@ def income_statement_url(currency: Currency, period: Period) -> str:
:return: The URL of the income statement.
"""
if period.is_default:
return url_for("accounting.report.income-statement-default",
return url_for("accounting-report.income-statement-default",
currency=currency)
return url_for("accounting.report.income-statement",
return url_for("accounting-report.income-statement",
currency=currency, period=period)
@ -112,7 +112,7 @@ def balance_sheet_url(currency: Currency, period: Period) -> str:
:return: The URL of the balance sheet.
"""
if period.is_default:
return url_for("accounting.report.balance-sheet-default",
return url_for("accounting-report.balance-sheet-default",
currency=currency)
return url_for("accounting.report.balance-sheet",
return url_for("accounting-report.balance-sheet",
currency=currency, period=period)

View File

@ -30,7 +30,7 @@ from .reports import Journal, Ledger, IncomeExpenses, TrialBalance, \
IncomeStatement, BalanceSheet, Search
from .template_filters import format_amount
bp: Blueprint = Blueprint("report", __name__)
bp: Blueprint = Blueprint("accounting-report", __name__)
"""The view blueprint for the reports."""
bp.add_app_template_filter(format_amount, "accounting_report_format_amount")

View File

@ -316,6 +316,10 @@ a.accounting-report-table-row {
}
/* The description editor */
.accounting-description-editor-buttons {
max-height: 7rem;
overflow-y: scroll;
}
.accounting-description-editor-buttons .btn {
margin-bottom: 0.3rem;
}

View File

@ -28,7 +28,7 @@ First written: 2023/1/26
</span>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item {% if request.endpoint and request.endpoint.startswith("accounting.report.") %} active {% endif %}" href="{{ url_for("accounting.report.default") }}">
<a class="dropdown-item {% if request.endpoint and request.endpoint.startswith("accounting-report.") %} active {% endif %}" href="{{ url_for("accounting-report.default") }}">
<i class="fa-solid fa-book"></i>
{{ A_("Reports") }}
</a>

View File

@ -23,6 +23,6 @@ First written: 2023/2/25
{% block header %}{% block title %}{{ A_("Add a New Cash Disbursement Journal Entry") }}{% endblock %}{% endblock %}
{% block back_url %}{{ request.args.get("next") or url_for("accounting.report.default") }}{% endblock %}
{% block back_url %}{{ request.args.get("next") or url_for("accounting-report.default") }}{% endblock %}
{% block action_url %}{{ url_for("accounting.journal-entry.store", journal_entry_type=journal_entry_type) }}{% endblock %}

View File

@ -181,10 +181,10 @@ First written: 2023/2/28
</div>
{# The suggested accounts #}
<div class="mt-3">
<div class="mt-3 accounting-description-editor-buttons">
<button id="accounting-description-editor-{{ description_editor.debit_credit }}-account-confirmed" class="btn btn-primary mb-1 d-none" type="button"></button>
{% for account in description_editor.accounts %}
<button class="btn btn-outline-primary mb-1 d-none accounting-description-editor-{{ description_editor.debit_credit }}-account {% if account.is_need_offset %} accounting-account-is-need-offset {% endif %}" type="button" data-code="{{ account.code }}" data-text="{{ account }}">
<button class="btn btn-outline-primary d-none accounting-description-editor-{{ description_editor.debit_credit }}-account {% if account.is_need_offset %} accounting-account-is-need-offset {% endif %}" type="button" data-code="{{ account.code }}" data-text="{{ account }}">
{{ account }}
</button>
{% endfor %}

View File

@ -26,7 +26,7 @@ First written: 2023/2/26
{% block content %}
<div class="mb-3 accounting-toolbar">
<a class="btn btn-primary" role="button" href="{{ url_for("accounting.report.default")|accounting_or_next }}">
<a class="btn btn-primary" role="button" href="{{ url_for("accounting-report.default")|accounting_or_next }}">
<i class="fa-solid fa-circle-chevron-left"></i>
<span class="d-none d-md-inline">{{ A_("Back") }}</span>
</a>

View File

@ -31,7 +31,7 @@ First written: 2023/2/26
{% block content %}
<div class="mb-3 accounting-toolbar">
<a class="btn btn-primary" role="button" href="{{ url_for("accounting.report.default")|accounting_or_next }}">
<a class="btn btn-primary" role="button" href="{{ url_for("accounting-report.default")|accounting_or_next }}">
<i class="fa-solid fa-circle-chevron-left"></i>
<span class="d-none d-md-inline">{{ A_("Back") }}</span>
</a>

View File

@ -23,6 +23,6 @@ First written: 2023/2/25
{% block header %}{% block title %}{{ A_("Add a New Cash Receipt Journal Entry") }}{% endblock %}{% endblock %}
{% block back_url %}{{ request.args.get("next") or url_for("accounting.report.default") }}{% endblock %}
{% block back_url %}{{ request.args.get("next") or url_for("accounting-report.default") }}{% endblock %}
{% block action_url %}{{ url_for("accounting.journal-entry.store", journal_entry_type=journal_entry_type) }}{% endblock %}

View File

@ -23,6 +23,6 @@ First written: 2023/2/25
{% block header %}{% block title %}{{ A_("Add a New Transfer Journal Entry") }}{% endblock %}{% endblock %}
{% block back_url %}{{ request.args.get("next") or url_for("accounting.report.default") }}{% endblock %}
{% block back_url %}{{ request.args.get("next") or url_for("accounting-report.default") }}{% endblock %}
{% block action_url %}{{ url_for("accounting.journal-entry.store", journal_entry_type=journal_entry_type) }}{% endblock %}

View File

@ -19,7 +19,7 @@ search-modal.html: The search modal
Author: imacat@mail.imacat.idv.tw (imacat)
First written: 2023/3/8
#}
<form action="{{ url_for("accounting.report.search") }}" method="get" role="search" aria-labelledby="accounting-search-modal-label">
<form action="{{ url_for("accounting-report.search") }}" method="get" role="search" aria-labelledby="accounting-search-modal-label">
<div class="modal fade" id="accounting-search-modal" tabindex="-1" aria-labelledby="accounting-search-modal-label" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">

View File

@ -118,7 +118,7 @@ First written: 2023/3/8
</button>
{% endif %}
{% if use_search %}
<form class="btn btn-primary d-flex input-group" action="{{ url_for("accounting.report.search") }}" method="get" role="search" aria-labelledby="accounting-toolbar-search-label">
<form class="btn btn-primary d-flex input-group" action="{{ url_for("accounting-report.search") }}" method="get" role="search" aria-labelledby="accounting-toolbar-search-label">
<input id="accounting-toolbar-search" class="form-control form-control-sm" type="search" name="q" value="{{ request.args.q }}" placeholder=" " required="required">
<label id="accounting-toolbar-search-label" for="accounting-toolbar-search" class="input-group-text">
<button type="submit">

View File

@ -35,7 +35,7 @@ from testlib_journal_entry import NON_EMPTY_NOTE, EMPTY_NOTE, \
PREFIX: str = "/accounting/journal-entries"
"""The URL prefix for the journal entry management."""
RETURN_TO_URI: str = "/accounting/reports"
RETURN_TO_URI: str = "/accounting"
"""The URL to return to after the operation."""