===============
Mia! Accounting
===============


Description
===========

*Mia! Accounting* is an accounting module for Flask_ applications.
It is designed both for mobile and desktop environments.  It
implements `double-entry bookkeeping`_.  It generates the following
accounting reports:

* Trial balance
* Income statement
* Balance sheet

In addition, *Mia! Accounting* tracks offsets for unpaid payables and
receivables.


Live Demonstration and Test Site
================================

There is a `live demonstration`_ for *Mia! Accounting*.  It runs the
same code as the `test site`_ in the `source distribution`_.  It is
the simplest website that works with *Mia! Accounting*.  It is also
used in the automatic tests.

If you do not have a running Flask application or do not know how to
start one, you may start with the test site.


Installation
============

Install *Mia! Accounting* with ``pip``:

::

    pip install mia-accounting

You may also download from the `PyPI project page`_ or the
`release page`_ on the `Git repository`_.


Prerequisites
=============

You need a running Flask application with database user login.
The primary key of the user data model must be integer.  You also
need at least one user.

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, run the ``accounting-init-db`` console
command to initialize the accounting database.  You need to specify
the username of a user as the data creator.

::

    % flask --app myapp accounting-init-db -u username


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
=========

 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.


Authors
=======

| imacat
| imacat@mail.imacat.idv.tw
| 2023/1/27


.. _Flask: https://flask.palletsprojects.com
.. _double-entry bookkeeping: https://en.wikipedia.org/wiki/Double-entry_bookkeeping
.. _live demonstration: https://accounting.imacat.idv.tw
.. _test site: https://github.com/imacat/mia-accounting/tree/main/tests/test_site
.. _source distribution: https://pypi.org/project/mia-accounting/#files
.. _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
.. _Bootstrap navigation bar: https://getbootstrap.com/docs/5.3/components/navbar/
.. _documentation on Read the Docs: https://mia-accounting.readthedocs.io
