Compare commits
6 Commits
4c2dcc5070
...
7dd007f3cf
Author | SHA1 | Date | |
---|---|---|---|
7dd007f3cf | |||
38b8a028d5 | |||
213981a8b2 | |||
a4d1789b58 | |||
91620d7db2 | |||
02fcabb0ce |
16
README.rst
16
README.rst
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 \
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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 %}
|
||||
|
@ -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 %}
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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 %}
|
||||
|
@ -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 %}
|
||||
|
@ -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">
|
||||
|
@ -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">
|
||||
|
@ -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."""
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user