39 Commits

Author SHA1 Message Date
3a0e978f76 Removed an unused import from the "accounting.journal_entry.forms.line_item" module. 2023-04-08 00:44:13 +08:00
8c10d42d7b Added documentation to the currency and account parameters of the CSVRow class, and the pagination parameter of the PageParams class in the "accounting.report.reports.journal" module. 2023-04-08 00:44:13 +08:00
04ec51afbe Changed the "offsets" relationship to a pseudo property, to apply the correct but complex ordering rules. 2023-04-07 16:04:54 +08:00
fe7a8842ce Fixed the query in the JournalEntryConverter converter. 2023-04-07 15:31:06 +08:00
66daa5c42c Fixed the query in the KeepAccountWhenHavingOffset validator. 2023-04-07 15:29:17 +08:00
27fb44937d Fixed the incorrect query in the "offsets" pseudo property of the LineItemForm form. 2023-04-07 15:11:04 +08:00
7026ed3a65 Fixed the order of the items in the "offsets" pseudo property of the LineItemForm form. 2023-04-07 15:01:22 +08:00
fdd3e93778 Fixed the net balance in the line items in the journal entry detail. 2023-04-07 14:57:24 +08:00
def7559457 Fixed the #filterOptions in the JavaScript JournalEntryAccountSelector to show the "more" option when there is no matches, but it is not showing all the accounts. 2023-04-07 12:34:24 +08:00
7905820d68 Revised the imports in the "accounting.base_account.views" and "accounting.currency.views" modules. 2023-04-06 16:09:36 +08:00
7ae332c975 Moved the "Test Site and Live Demonstration" section to the front of the documentation. 2023-04-06 10:00:24 +08:00
86c5b91697 Advanced to version 1.0.1. 2023-04-06 08:43:14 +08:00
9168840e64 Fixed an error in the example configuration. 2023-04-06 08:38:39 +08:00
21b9cfa8b8 Revised the documentation. 2023-04-06 08:31:19 +08:00
b0b3b3acb1 Moved the history section out from README.rst and intro.rst, to the new history.rst. 2023-04-06 08:21:32 +08:00
cb1d254cf0 Advanced to version 1.0.0. Hooray! 2023-04-06 02:55:19 +08:00
eb9ad57e72 Updated the translation. 2023-04-06 02:55:17 +08:00
ec26f8ef4d Added the documentation. 2023-04-06 02:54:45 +08:00
7ed29115ed Revised the inclusion in the base template of the test site. 2023-04-06 02:01:05 +08:00
95955197ac Updated the copyright year in pyproject.toml. 2023-04-05 22:50:54 +08:00
d5a0f79e4b Revised the Read the Docs configuration, and removed the redundant requirements.txt for Read the Docs. 2023-04-05 22:01:53 +08:00
6aa655aa64 Replaced setup.cfg with pyproject.toml for the package settings, and rewrote the packaging rules in MANIFEST.in. 2023-04-05 19:49:52 +08:00
6e532af26e Added the Read the Docs documentation link to README.rst. 2023-04-05 14:25:33 +08:00
fa1818d124 Added the Read the Docs configuration file. 2023-04-05 14:12:46 +08:00
f21ecc2aa9 Added requirements.txt for Read the Docs. 2023-04-05 14:07:37 +08:00
5ae1ab95ae Advanced to version 0.11.1. 2023-04-05 13:00:46 +08:00
7a5b3b78fc Removed the rows with zero balance from the income statement. 2023-04-05 12:59:50 +08:00
7df4051452 Removed the rows with zero balance from the trial balance. 2023-04-05 12:56:28 +08:00
85084c68fd Removed the rows with zero balance from the balance sheet. 2023-04-05 12:29:58 +08:00
0185c16654 Advanced to version 0.11.0. 2023-04-05 09:59:23 +08:00
7dd007f3cf Revised README.rst. 2023-04-05 09:57:34 +08:00
38b8a028d5 Reversed the original line items in the original line item selector. 2023-04-05 09:25:41 +08:00
213981a8b2 Revised the style of the buttons in the description editor, to avoid overwhelming the modal when there are too many buttons. 2023-04-05 09:11:27 +08:00
a4d1789b58 Moved the income and expenses log to the first item of the report chooser. 2023-04-05 08:15:16 +08:00
91620d7db2 Revised the init_app function in the "accounting" module. 2023-04-05 08:07:17 +08:00
02fcabb0ce Updated the URI of the reports to be the default views of the application. 2023-04-05 08:06:00 +08:00
4c2dcc5070 Renamed the project from "Mia! Accounting Flask" to "Mia! Accounting". 2023-04-04 18:26:54 +08:00
c9166fda4d Fixed the order in the get_selectable_original_line_items function in the "accounting.journal_entry.utils.original_line_item" module. 2023-04-04 10:54:43 +08:00
3a0f0873e2 Added documentation to the bp, babel_js, csrf, and db variables in the test site. 2023-04-03 22:18:58 +08:00
193 changed files with 917 additions and 443 deletions

2
.gitignore vendored
View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/1/27
# Copyright (c) 2022 imacat.

40
.readthedocs.yaml Normal file
View File

@ -0,0 +1,40 @@
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/4/5
# 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.
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.11"
# Build documentation in the docs/ directory with Sphinx
# If using Sphinx, optionally build your docs in additional formats such as PDF
formats: all
# Optionally declare the Python requirements required to build your docs
python:
install:
- method: pip
path: .

View File

@ -1,4 +1,4 @@
# The Mia! Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2022/8/21
# Copyright (c) 2022-2023 imacat.
@ -15,17 +15,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
recursive-include src/accounting/static *
exclude src/accounting/static/js/dummy.js
include src/accounting/translations/*
include src/accounting/translations/*/LC_MESSAGES/*
include docs/*
include docs/source/*
include docs/source/_static/*
include docs/source/_templates/*
include tests/*
recursive-include src/accounting/templates *
recursive-include src/accounting/translations *
recursive-include src/accounting/data *
recursive-include docs *
recursive-exclude docs/build *
recursive-include tests *
exclude tests/test_temp.py
include tests/test_site/*
include tests/test_site/static/*
include tests/test_site/templates/*
include tests/test_site/translations/*
include tests/test_site/translations/*/LC_MESSAGES/*
recursive-exclude tests *.pyc
recursive-exclude tests/instance *

View File

@ -1,24 +1,176 @@
=====================
Mia! Accounting Flask
=====================
===============
Mia! Accounting
===============
Description
===========
This is the Mia! Accounting Flask project. It is an accounting
module for the Flask_ applications.
*Mia! Accounting* is an accounting module for Flask_ applications.
It implements `double-entry bookkeeping`_, and generates the following
accounting reports:
* Trial balance
* Income statement
* Balance sheet
In addition, *Mia! Accounting* tracks offsets for unpaid payables and
receivables.
Install
=======
Installation
============
Install the latest source from the
`Mia! Accounting Flask repository`_.
Install *Mia! Accounting* with ``pip``:
::
pip install git+https://gitea.imacat.idv.tw/imacat/mia-accounting-flask.git
pip install mia-accounting
You may also download the from the `PyPI project page`_ or the
`release page`_ on the `Git repository`_.
Test Site and Live Demonstration
================================
You may find a working example in the `test site`_ in the
`source distribution`_. It is the simplest website that works with
*Mia! Accounting*. It is used in the automatic tests. It is the same
code run for `live demonstration`_.
If you do not have a running Flask application or do not know how to
start one, you may start with the test site.
Prerequisites
=============
You need a running Flask application with database user login.
The primary key of the user data model must be integer.
The following front-end JavaScript libraries must be loaded. You may
download it locally or use CDN_.
* Bootstrap_ 5.2.3 or above
* FontAwesome_ 6.2.1 or above
* `Decimal.js`_ 6.4.3 or above
* `Tempus-Dominus`_ 6.4.3 or above
Configuration
=============
You need to pass the Flask *app* and an implementation of
`UserUtilityInterface`_ to the `init_app`_ function.
``UserUtilityInterface`` contains everything *Mia! Accounting* needs.
The following is an example configuration for *Mia! Accounting*.
::
from flask import Response, redirect
from .auth import current_user()
from .modules import User
def create_app(test_config=None) -> Flask:
app: Flask = Flask(__name__)
... (Configuration of SQLAlchemy, CSRF, Babel_JS, ... etc) ...
import accounting
class UserUtils(accounting.UserUtilityInterface[User]):
def can_view(self) -> bool:
return True
def can_edit(self) -> bool:
return "editor" in current_user().roles
def can_admin(self) -> bool:
return current_user().is_admin
def unauthorized(self) -> Response:
return redirect("/login")
@property
def cls(self) -> t.Type[User]:
return User
@property
def pk_column(self) -> Column:
return User.id
@property
def current_user(self) -> User | None:
return current_user()
def get_by_username(self, username: str) -> User | None:
return User.query.filter(User.username == username).first()
def get_pk(self, user: User) -> int:
return user.id
accounting.init_app(app, UserUtils())
... (Any other configuration) ...
return app
Database Initialization
=======================
After the configuration, you need to run
`flask_sqlalchemy.SQLAlchemy.create_all`_ to create the
database tables that *Mia! Accounting* uses.
*Mia! Accounting* adds three console commands:
* ``accounting-init-base``
* ``accounting-init-accounts``
* ``accounting-init-currencies``
After database tables are created, run
``accounting-init-base`` first, and then the other two commands.
::
% flask --app myapp accounting-init-base
% flask --app myapp accounting-init-accounts
% flask --app myapp accounting-init-currencies
Navigation Menu
===============
Include the navigation menu in the `Bootstrap navigation bar`_ in your
base template:
::
<nav class="navbar navbar-expand-lg bg-body-tertiary bg-dark navbar-dark">
<div class="container-fluid">
...
<div id="collapsible-navbar" class="collapse navbar-collapse">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
...
{% include "accounting/include/nav.html" %}
...
</ul>
...
</div>
</div>
</nav>
Check your Flask application and see how it works.
Documentation
=============
Refer to the `documentation on Read the Docs`_.
Copyright
@ -46,5 +198,22 @@ Authors
| imacat@mail.imacat.idv.tw
| 2023/1/27
.. _Flask: https://flask.palletsprojects.com
.. _Mia! Accounting Flask repository: https://gitea.imacat.idv.tw/imacat/mia-accounting-flask
.. _double-entry bookkeeping: https://en.wikipedia.org/wiki/Double-entry_bookkeeping
.. _test site: https://github.com/imacat/mia-accounting/tree/main/tests/test_site
.. _source distribution: https://pypi.org/project/mia-accounting/#files
.. _live demonstration: https://accounting.imacat.idv.tw
.. _PyPI project page: https://pypi.org/project/mia-accounting
.. _release page: https://github.com/imacat/mia-accounting/releases
.. _Git repository: https://github.com/imacat/mia-accounting
.. _CDN: https://en.wikipedia.org/wiki/Content_delivery_network
.. _Bootstrap: https://getbootstrap.com
.. _FontAwesome: https://fontawesome.com
.. _Decimal.js: https://mikemcl.github.io/decimal.js
.. _Tempus-Dominus: https://getdatepicker.com
.. _UserUtilityInterface: https://mia-accounting.readthedocs.io/en/latest/accounting.utils.html#accounting.utils.user.UserUtilityInterface
.. _init_app: https://mia-accounting.readthedocs.io/en/latest/accounting.html#accounting.init_app
.. _flask_sqlalchemy.SQLAlchemy.create_all: https://flask-sqlalchemy.palletsprojects.com/en/3.0.x/api/#flask_sqlalchemy.SQLAlchemy.create_all
.. _Bootstrap navigation bar: https://getbootstrap.com/docs/5.3/components/navbar/
.. _documentation on Read the Docs: https://mia-accounting.readthedocs.io

View File

@ -10,10 +10,10 @@ sys.path.insert(0, os.path.abspath('../../src/'))
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = 'Mia! Accounting Flask'
project = 'Mia! Accounting'
copyright = '2023, imacat'
author = 'imacat'
release = '0.10.0'
release = '1.0.1'
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

61
docs/source/examples.rst Normal file
View File

@ -0,0 +1,61 @@
Examples
========
.. _example-userutils:
An Example Configuration
------------------------
The following is an example configuration for *Mia! Accounting*.
::
from flask import Response, redirect
from .auth import current_user()
from .modules import User
def create_app(test_config=None) -> Flask:
app: Flask = Flask(__name__)
... (Configuration of SQLAlchemy, CSRF, Babel_JS, ... etc) ...
import accounting
class UserUtils(accounting.UserUtilityInterface[User]):
def can_view(self) -> bool:
return True
def can_edit(self) -> bool:
return "editor" in current_user().roles
def can_admin(self) -> bool:
return current_user().is_admin
def unauthorized(self) -> Response:
return redirect("/login")
@property
def cls(self) -> t.Type[User]:
return User
@property
def pk_column(self) -> Column:
return User.id
@property
def current_user(self) -> User | None:
return current_user()
def get_by_username(self, username: str) -> User | None:
return User.query.filter(User.username == username).first()
def get_pk(self, user: User) -> int:
return user.id
accounting.init_app(app, UserUtils())
... (Any other configuration) ...
return app

57
docs/source/history.rst Normal file
View File

@ -0,0 +1,57 @@
History
=======
I created my own private accounting application in Perl_/mod_perl_ in
2007, as part of my personal website. The first revision was made
using Perl/Mojolicious_ in 2019, with the aim of making it
mobile-friendly using Bootstrap_, and with modern back-end and
front-end technologies such as jQuery.
The second revision was done in Python_/Django_ in 2020, as I was
looking to change my career from PHP_/Laravel_ to Python, but lacked
experience with large Python projects. I needed something in my
portfolio and decided to work on the somewhat outdated Mojolicious
project.
Despite having no prior experience with Django, I spent two months
working late nights to create the `Mia! Accounting Django`_
application. It took me another 1.5 months to make it an independent
module, which I later released as an open source project on PyPI.
The application worked nicely for my household bookkeeping for two
years. However, new demands arose over time, especially with tracking
payables and receivables. This was critical `during the pandemic`_ as
more payments were made online with credit cards.
The biggest issue I encountered was with
`Django's MTV architectural pattern`_. Django takes over the control
flow. I had to override several parts of the `class-based views`_ for
different but yet simple control flow logic. In the end, it became
very difficult to track whether things went wrong because I overrode
something or because it just wouldn't work with the basic assumption
of the class-based views. By the time I realized it, it was too late
for me to drop Django's MTV and rewrite everything from class-based
views to function-based views.
Therefore, I decided to turn to microframeworks_ like Flask_. After
working with modularized Flask and FastAPI_ applications for two
years, I returned to the project and wrote its third revision using
Flask in 2023.
.. _Perl: https://www.perl.org
.. _mod_perl: https://perl.apache.org
.. _Mojolicious: https://mojolicious.org
.. _Bootstrap: https://getbootstrap.com
.. _jQuery: https://jquery.com
.. _Python: https://www.python.org
.. _Django: https://www.djangoproject.com
.. _PHP: https://www.php.net
.. _Laravel: https://laravel.com
.. _Mia! Accounting Django: https://github.com/imacat/mia-accounting-django
.. _during the pandemic: https://en.wikipedia.org/wiki/COVID-19_pandemic
.. _FastAPI: https://fastapi.tiangolo.com
.. _Django's MTV architectural pattern: https://docs.djangoproject.com/en/dev/faq/general/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names
.. _class-based views: https://docs.djangoproject.com/en/4.2/topics/class-based-views/
.. _microframeworks: https://en.wikipedia.org/wiki/Microframework
.. _Flask: https://flask.palletsprojects.com

View File

@ -1,15 +1,20 @@
.. Mia! Accounting Flask documentation master file, created by
.. Mia! Accounting documentation master file, created by
sphinx-quickstart on Fri Jan 27 12:20:04 2023.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Mia! Accounting Flask's documentation!
=================================================
Welcome to Mia! Accounting's documentation!
===========================================
.. toctree::
:maxdepth: 2
:caption: Contents:
intro
accounting
examples
history
Indices and tables

136
docs/source/intro.rst Normal file
View File

@ -0,0 +1,136 @@
Introduction
============
*Mia! Accounting* is an accounting module for Flask_ applications.
It implements `double-entry bookkeeping`_, and generates the following
accounting reports:
* Trial balance
* Income statement
* Balance sheet
In addition, *Mia! Accounting* tracks offsets for unpaid payables and
receivables.
Installation
------------
Install *Mia! Accounting* with ``pip``:
::
pip install mia-accounting
You may also download the from the `PyPI project page`_ or the
`release page`_ on the `Git repository`_.
Test Site and Live Demonstration
--------------------------------
You may find a working example in the `test site`_ in the
`source distribution`_. It is the simplest website that works with
*Mia! Accounting*. It is used in the automatic tests. It is the same
code run for `live demonstration`_.
If you do not have a running Flask application or do not know how to
start one, you may start with the test site.
Prerequisites
-------------
You need a running Flask application with database user login.
The primary key of the user data model must be integer.
The following front-end JavaScript libraries must be loaded. You may
download it locally or use CDN_.
* Bootstrap_ 5.2.3 or above
* FontAwesome_ 6.2.1 or above
* `Decimal.js`_ 6.4.3 or above
* `Tempus-Dominus`_ 6.4.3 or above
Configuration
-------------
You need to pass the Flask *app* and an implementation of
:py:class:`accounting.utils.user.UserUtilityInterface` to the
:py:func:`accounting.init_app` function. ``UserUtilityInterface``
contains everything *Mia! Accounting* needs.
See an example in :ref:`example-userutils`.
Database Initialization
-----------------------
After the configuration, you need to run
`flask_sqlalchemy.SQLAlchemy.create_all`_ to create the
database tables that *Mia! Accounting* uses.
*Mia! Accounting* adds three console commands:
* ``accounting-init-base``
* ``accounting-init-accounts``
* ``accounting-init-currencies``
After database tables are created, run
``accounting-init-base`` first, and then the other two commands.
::
% flask --app myapp accounting-init-base
% flask --app myapp accounting-init-accounts
% flask --app myapp accounting-init-currencies
Navigation Menu
---------------
Include the navigation menu in the `Bootstrap navigation bar`_ in your
base template:
::
<nav class="navbar navbar-expand-lg bg-body-tertiary bg-dark navbar-dark">
<div class="container-fluid">
...
<div id="collapsible-navbar" class="collapse navbar-collapse">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
...
{% include "accounting/include/nav.html" %}
...
</ul>
...
</div>
</div>
</nav>
Check your Flask application and see how it works.
Documentation
-------------
Refer to the `documentation on Read the Docs`_.
.. _Flask: https://flask.palletsprojects.com
.. _double-entry bookkeeping: https://en.wikipedia.org/wiki/Double-entry_bookkeeping
.. _test site: https://github.com/imacat/mia-accounting/tree/main/tests/test_site
.. _source distribution: https://pypi.org/project/mia-accounting/#files
.. _live demonstration: https://accounting.imacat.idv.tw
.. _PyPI project page: https://pypi.org/project/mia-accounting
.. _release page: https://github.com/imacat/mia-accounting/releases
.. _Git repository: https://github.com/imacat/mia-accounting
.. _CDN: https://en.wikipedia.org/wiki/Content_delivery_network
.. _Bootstrap: https://getbootstrap.com
.. _FontAwesome: https://fontawesome.com
.. _Decimal.js: https://mikemcl.github.io/decimal.js
.. _Tempus-Dominus: https://getdatepicker.com
.. _flask_sqlalchemy.SQLAlchemy.create_all: https://flask-sqlalchemy.palletsprojects.com/en/3.0.x/api/#flask_sqlalchemy.SQLAlchemy.create_all
.. _Bootstrap navigation bar: https://getbootstrap.com/docs/5.3/components/navbar/
.. _documentation on Read the Docs: https://mia-accounting.readthedocs.io

View File

@ -1,7 +1,7 @@
# The Mia! Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2022/8/21
# Copyright (c) 2022 imacat.
# Copyright (c) 2022-2023 imacat.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -15,6 +15,51 @@
# See the License for the specific language governing permissions and
# limitations under the License.
[project]
name = "mia-accounting"
version = "1.0.1"
description = "A Flask accounting module."
readme = "README.rst"
requires-python = ">=3.11"
authors = [
{name = "imacat", email = "imacat@mail.imacat.idv.tw"},
]
keywords = ["mia", "accounting", "flask"]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: Apache Software License",
"Operating System :: OS Independent",
"Framework :: Flask",
"Topic :: Office/Business :: Financial :: Accounting",
]
dependencies = [
"flask",
"Flask-SQLAlchemy",
"Flask-WTF",
"Flask-Babel >= 3",
"Flask-Babel-JS",
]
[project.optional-dependencies]
test = [
"unittest",
"httpx",
"OpenCC",
]
[project.urls]
"Documentation" = "https://mia-accounting.readthedocs.io"
"Repository" = "https://github.com/imacat/mia-accounting"
"Bug Tracker" = "https://github.com/imacat/mia-accounting/issues"
"Demonstration" = "https://accounting.imacat.idv.tw"
[build-system]
requires = ["setuptools>=42"]
build-backend = "setuptools.build_meta"
[tool.setuptools.exclude-package-data]
"*" = [
"babel.cfg",
"*.pot",
"*.po",
]

View File

@ -1,56 +0,0 @@
# The Mia! Flask Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2022/8/21
# Copyright (c) 2022-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.
[metadata]
name = mia-accounting-flask
version = 0.10.0
author = imacat
author_email = imacat@mail.imacat.idv.tw
description = The Mia! Accounting Flask project.
long_description = file: README.rst
long_description_content_type = text/x-rst
url = https://github.com/imacat/mia-accounting-flask
project_urls =
Bug Tracker = https://github.com/imacat/mia-accounting-flask/issues
classifiers =
Programming Language :: Python :: 3
License :: OSI Approved :: Apache Software License
Operating System :: OS Independent
Framework :: Flask
Topic :: Office/Business :: Financial :: Accounting
[options]
package_dir =
= src
python_requires = >=3.11
install_requires =
flask
Flask-SQLAlchemy
Flask-WTF
Flask-Babel >= 3
Flask-Babel-JS
tests_require =
unittest
httpx
OpenCC
[options.package_data]
accounting =
static/**
templates/**
translations/*/LC_MESSAGES/*.mo
data/**

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/1/25
# Copyright (c) 2023 imacat.
@ -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

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/1/30
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/1/30
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/1/31
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/1
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/1/30
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/1/30
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/1/25
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/1/25
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/1
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/1/26
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/1/26
# Copyright (c) 2023 imacat.
@ -22,6 +22,7 @@ from flask import Blueprint, render_template
from accounting.models import BaseAccount
from accounting.utils.pagination import Pagination
from accounting.utils.permission import has_permission, can_view
from .queries import get_base_account_query
bp: Blueprint = Blueprint("base-account", __name__)
"""The view blueprint for the base account management."""
@ -34,7 +35,6 @@ def list_accounts() -> str:
:return: The account list.
"""
from .queries import get_base_account_query
accounts: list[BaseAccount] = get_base_account_query()
pagination: Pagination = Pagination[BaseAccount](accounts)
return render_template("accounting/base-account/list.html",

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/6
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/6
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/6
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/6
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/6
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/6
# Copyright (c) 2023 imacat.
@ -34,6 +34,7 @@ from accounting.utils.pagination import Pagination
from accounting.utils.permission import has_permission, can_view, can_edit
from accounting.utils.user import get_current_user_pk
from .forms import CurrencyForm
from .queries import get_currency_query
bp: Blueprint = Blueprint("currency", __name__)
"""The view blueprint for the currency management."""
@ -48,7 +49,6 @@ def list_currencies() -> str:
:return: The currency list.
"""
from .queries import get_currency_query
currencies: list[Currency] = get_currency_query()
pagination: Pagination = Pagination[Currency](currencies)
return render_template("accounting/currency/list.html",

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/22
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/18
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/19
# Copyright (c) 2023 imacat.
@ -23,6 +23,7 @@ from flask import abort
from sqlalchemy.orm import selectinload
from werkzeug.routing import BaseConverter
from accounting import db
from accounting.models import JournalEntry, JournalEntryLineItem
from accounting.utils.journal_entry_types import JournalEntryType
@ -37,13 +38,7 @@ class JournalEntryConverter(BaseConverter):
:param value: The journal entry ID.
:return: The corresponding journal entry.
"""
journal_entry: JournalEntry | None = JournalEntry.query\
.join(JournalEntryLineItem)\
.filter(JournalEntry.id == value)\
.options(selectinload(JournalEntry.line_items)
.selectinload(JournalEntryLineItem.offsets)
.selectinload(JournalEntryLineItem.journal_entry))\
.first()
journal_entry: JournalEntry | None = db.session.get(JournalEntry, value)
if journal_entry is None:
abort(404)
return journal_entry

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/10
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/10
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/18
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/10
# Copyright (c) 2023 imacat.
@ -31,7 +31,7 @@ from accounting import db
from accounting.forms import ACCOUNT_REQUIRED, AccountExists, IsDebitAccount, \
IsCreditAccount
from accounting.locale import lazy_gettext
from accounting.models import Account, JournalEntryLineItem
from accounting.models import Account, JournalEntry, JournalEntryLineItem
from accounting.template_filters import format_amount
from accounting.utils.cast import be
from accounting.utils.random_id import new_id
@ -127,10 +127,8 @@ class KeepAccountWhenHavingOffset:
assert isinstance(form, LineItemForm)
if field.data is None or form.id.data is None:
return
line_item: JournalEntryLineItem | None = db.session\
.query(JournalEntryLineItem)\
.filter(JournalEntryLineItem.id == form.id.data)\
.options(selectinload(JournalEntryLineItem.offsets)).first()
line_item: JournalEntryLineItem | None \
= db.session.get(JournalEntryLineItem, form.id.data)
if line_item is None or len(line_item.offsets) == 0:
return
if field.data != line_item.account_code:
@ -344,14 +342,13 @@ class LineItemForm(FlaskForm):
def get_offsets() -> list[JournalEntryLineItem]:
if not self.is_need_offset or self.id.data is None:
return []
return JournalEntryLineItem.query\
return JournalEntryLineItem.query.join(JournalEntry)\
.filter(JournalEntryLineItem.original_line_item_id
== self.id.data)\
.order_by(JournalEntry.date, JournalEntry.no,
JournalEntryLineItem.no)\
.options(selectinload(JournalEntryLineItem.journal_entry),
selectinload(JournalEntryLineItem.account),
selectinload(JournalEntryLineItem.offsets)
.selectinload(
JournalEntryLineItem.journal_entry)).all()
selectinload(JournalEntryLineItem.account)).all()
setattr(self, "__offsets", get_offsets())
return getattr(self, "__offsets")

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/10
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/25
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/10
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/10
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/27
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/15
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/19
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/10
# Copyright (c) 2023 imacat.
@ -72,11 +72,12 @@ def get_selectable_original_line_items(
line_items: list[JournalEntryLineItem] = JournalEntryLineItem.query\
.filter(JournalEntryLineItem.id.in_({x for x in net_balances}))\
.join(JournalEntry)\
.order_by(JournalEntry.date, JournalEntryLineItem.is_debit,
JournalEntryLineItem.no)\
.order_by(JournalEntry.date, JournalEntry.no,
JournalEntryLineItem.is_debit, JournalEntryLineItem.no)\
.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

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/18
# Copyright (c) 2023 imacat.
@ -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

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/1/25
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/1/25
# Copyright (c) 2023 imacat.
@ -660,12 +660,8 @@ class JournalEntryLineItem(db.Model):
nullable=True)
"""The ID of the original line item."""
original_line_item = db.relationship("JournalEntryLineItem",
back_populates="offsets",
remote_side=id, passive_deletes=True)
"""The original line item."""
offsets = db.relationship("JournalEntryLineItem",
back_populates="original_line_item")
"""The offset items."""
currency_code = db.Column(db.String,
db.ForeignKey(Currency.code, onupdate="CASCADE"),
nullable=False)
@ -758,6 +754,21 @@ class JournalEntryLineItem(db.Model):
"""
setattr(self, "__net_balance", net_balance)
@property
def offsets(self) -> list[t.Self]:
"""Returns the offset items.
:return: The offset items.
"""
if not hasattr(self, "__offsets"):
cls: t.Type[t.Self] = self.__class__
offsets: list[t.Self] = cls.query.join(JournalEntry)\
.filter(JournalEntryLineItem.original_line_item_id == self.id)\
.order_by(JournalEntry.date, JournalEntry.no,
cls.is_debit, cls.no).all()
setattr(self, "__offsets", offsets)
return getattr(self, "__offsets")
@property
def query_values(self) -> list[str]:
"""Returns the values to be queried.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/22
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/22
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/22
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/3
# Copyright (c) 2023 imacat.
@ -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

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/3
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/9
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/4
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/4
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/4
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/4
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/4
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/4
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/4
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/7
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/7
# Copyright (c) 2023 imacat.
@ -137,6 +137,7 @@ class AccountCollector:
.join(JournalEntry).join(Account)\
.filter(*conditions)\
.group_by(Account.id, Account.base_code, Account.no)\
.having(balance_func != 0)\
.order_by(Account.base_code, Account.no)
account_balances: list[sa.Row] \
= db.session.execute(select_balance).all()

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/7
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/7
# Copyright (c) 2023 imacat.
@ -269,6 +269,7 @@ class IncomeStatement(BaseReport):
.join(JournalEntry).join(Account)\
.filter(*conditions)\
.group_by(Account.id)\
.having(balance_func != 0)\
.order_by(Account.base_code, Account.no)
balances: list[sa.Row] = db.session.execute(select_balances).all()
accounts: dict[int, Account] \

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/7
# Copyright (c) 2023 imacat.
@ -77,6 +77,8 @@ class CSVRow(BaseCSVRow):
"""Constructs a row in the CSV.
:param journal_entry_date: The journal entry date.
:param currency: The currency.
:param account: The account.
:param description: The description.
:param debit: The debit amount.
:param credit: The credit amount.
@ -116,6 +118,7 @@ class PageParams(BasePageParams):
"""Constructs the HTML page parameters.
:param period: The period.
:param pagination: The pagination.
:param line_items: The line items.
"""
self.period: Period = period

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/7
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/8
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/7
# Copyright (c) 2023 imacat.
@ -191,6 +191,7 @@ class TrialBalance(BaseReport):
.join(JournalEntry).join(Account)\
.filter(*conditions)\
.group_by(Account.id)\
.having(balance_func != 0)\
.order_by(Account.base_code, Account.no)
balances: list[sa.Row] = db.session.execute(select_balances).all()
accounts: dict[int, Account] \

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/7
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/7
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/6
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/8
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/7
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/5
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/4
# Copyright (c) 2023 imacat.
@ -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

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/4
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/9
# Copyright (c) 2023 imacat.
@ -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

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/3
# Copyright (c) 2023 imacat.
@ -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

@ -1,4 +1,4 @@
/* The Mia! Accounting Flask Project
/* The Mia! Accounting Project
* style.css: The style sheet for the accounting application.
*/
@ -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

@ -1,4 +1,4 @@
/* The Mia! Accounting Flask Project
/* The Mia! Accounting Project
* account-form.js: The JavaScript for the account form
*/

View File

@ -1,4 +1,4 @@
/* The Mia! Accounting Flask Project
/* The Mia! Accounting Project
* account-order.js: The JavaScript for the account order
*/

View File

@ -1,4 +1,4 @@
/* The Mia! Accounting Flask Project
/* The Mia! Accounting Project
* currency-form.js: The JavaScript for the currency form
*/

View File

@ -1,4 +1,4 @@
/* The Mia! Accounting Flask Project
/* The Mia! Accounting Project
* description-editor.js: The JavaScript for the description editor
*/

View File

@ -1,4 +1,4 @@
/* The Mia! Accounting Flask Project
/* The Mia! Accounting Project
* drag-and-drop-reorder.js: The JavaScript for the reorder a list with drag-and-drop
*/

View File

@ -1,4 +1,4 @@
/* The Mia! Accounting Flask Project
/* The Mia! Accounting Project
* journal-entry-account-selector.js: The JavaScript for the account selector of the journal entry form
*/
@ -123,7 +123,7 @@ class JournalEntryAccountSelector {
option.setShown(false);
}
}
if (!isAnyMatched) {
if (!isAnyMatched && this.#isShowMore) {
this.#optionList.classList.add("d-none");
this.#queryNoResult.classList.remove("d-none");
} else {

View File

@ -1,4 +1,4 @@
/* The Mia! Accounting Flask Project
/* The Mia! Accounting Project
* journal-entry-form.js: The JavaScript for the journal entry form
*/

View File

@ -1,4 +1,4 @@
/* The Mia! Accounting Flask Project
/* The Mia! Accounting Project
* journal-entry-line-item-editor.js: The JavaScript for the journal entry line item editor
*/

View File

@ -1,4 +1,4 @@
/* The Mia! Accounting Flask Project
/* The Mia! Accounting Project
* journal-entry-order.js: The JavaScript for the journal entry order
*/

View File

@ -1,4 +1,4 @@
/* The Mia! Accounting Flask Project
/* The Mia! Accounting Project
* material-fab-speed-dial.js: The JavaScript for the speed dial for the material floating buttons
*/

View File

@ -1,4 +1,4 @@
/* The Mia! Accounting Flask Project
/* The Mia! Accounting Project
* account-form.js: The JavaScript for the account form
*/

View File

@ -1,4 +1,4 @@
/* The Mia! Accounting Flask Project
/* The Mia! Accounting Project
* original-line-item-selector.js: The JavaScript for the original line item selector
*/

View File

@ -1,4 +1,4 @@
/* The Mia! Accounting Flask Project
/* The Mia! Accounting Project
* period-chooser.js: The JavaScript for the period chooser
*/

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/25
# Copyright (c) 2023 imacat.

View File

@ -1,4 +1,4 @@
# The Mia! Accounting Flask Project.
# The Mia! Accounting Project.
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/3/3
# Copyright (c) 2023 imacat.

View File

@ -1,5 +1,5 @@
{#
The Mia! Accounting Flask Project
The Mia! Accounting Project
create.html: The account creation form
Copyright (c) 2023 imacat.

View File

@ -1,5 +1,5 @@
{#
The Mia! Accounting Flask Project
The Mia! Accounting Project
detail.html: The account detail
Copyright (c) 2023 imacat.

View File

@ -1,5 +1,5 @@
{#
The Mia! Accounting Flask Project
The Mia! Accounting Project
edit.html: The account edit form
Copyright (c) 2023 imacat.

View File

@ -1,5 +1,5 @@
{#
The Mia! Accounting Flask Project
The Mia! Accounting Project
form.html: The account form
Copyright (c) 2023 imacat.

View File

@ -1,5 +1,5 @@
{#
The Mia! Accounting Flask Project
The Mia! Accounting Project
list.html: The account list
Copyright (c) 2023 imacat.

View File

@ -1,5 +1,5 @@
{#
The Mia! Accounting Flask Project
The Mia! Accounting Project
order.html: The order of the accounts under a same base account
Copyright (c) 2023 imacat.

Some files were not shown because too many files have changed in this diff Show More