<?xml version="1.0" encoding="utf-8" ?>
<html xmlns="
http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<style type="text/css">
/*
:Author: David Goodger (
goodger@python.org)
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See 
https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
  border: 0 }
table.borderless td, table.borderless th {
  /* Override padding for "table.docutils td" with "! important".
     The right padding separates the table cells. */
  padding: 0 0.5em 0 0 ! important }
.first {
  /* Override more specific margin styles with "! important". */
  margin-top: 0 ! important }
.last, .with-subtitle {
  margin-bottom: 0 ! important }
.hidden {
  display: none }
.subscript {
  vertical-align: sub;
  font-size: smaller }
.superscript {
  vertical-align: super;
  font-size: smaller }
a.toc-backref {
  text-decoration: none ;
  color: black }
blockquote.epigraph {
  margin: 2em 5em ; }
dl.docutils dd {
  margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
  overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
  font-weight: bold }
*/
div.abstract {
  margin: 2em 5em }
div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
   compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
  margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
  margin-top: 0.5em }
*/
div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }
div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }
div.figure {
  margin-left: 2em ;
  margin-right: 2em }
div.footer, div.header {
  clear: both;
  font-size: smaller }
div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }
div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }
div.sidebar {
  margin: 0 0 0.5em 1em ;
  border: medium outset ;
  padding: 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }
div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }
div.system-messages {
  margin: 5em }
div.system-messages h1 {
  color: red }
div.system-message {
  border: medium outset ;
  padding: 1em }
div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }
div.topic {
  margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
  margin-top: 0.4em }
h1.title {
  text-align: center }
h2.subtitle {
  text-align: center }
hr.docutils {
  width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
  clear: left ;
  float: left ;
  margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
  clear: right ;
  float: right ;
  margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
  display: block;
  margin-left: auto;
  margin-right: auto;
}
table.align-center {
  margin-left: auto;
  margin-right: auto;
}
.align-left {
  text-align: left }
.align-center {
  clear: both ;
  text-align: center }
.align-right {
  text-align: right }
/* reset inner alignment in figures */
div.align-right {
  text-align: inherit }
/* div.align-center * { */
/*   text-align: left } */
.align-top    {
  vertical-align: top }
.align-middle {
  vertical-align: middle }
.align-bottom {
  vertical-align: bottom }
ol.simple, ul.simple {
  margin-bottom: 1em }
ol.arabic {
  list-style: decimal }
ol.loweralpha {
  list-style: lower-alpha }
ol.upperalpha {
  list-style: upper-alpha }
ol.lowerroman {
  list-style: lower-roman }
ol.upperroman {
  list-style: upper-roman }
p.attribution {
  text-align: right ;
  margin-left: 50% }
p.caption {
  font-style: italic }
p.credits {
  font-style: italic ;
  font-size: smaller }
p.label {
  white-space: nowrap }
p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }
p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }
p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }
p.topic-title {
  font-weight: bold }
pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
  margin-left: 2em ;
  margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
  font-family: sans-serif ;
  font-style: oblique }
span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }
span.interpreted {
  font-family: sans-serif }
span.option {
  white-space: nowrap }
span.pre {
  white-space: pre }
span.problematic {
  color: red }
span.section-subtitle {
  /* font-size relative to parent (h1..h6 element) */
  font-size: 80% }
table.citation {
  border-left: solid 1px gray;
  margin-left: 1px }
table.docinfo {
  margin: 2em 4em }
table.docutils {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }
table.footnote {
  border-left: solid 1px black;
  margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap ;
  padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
  border: 0px;
  border-top: 2px solid;
  border-bottom: 2px solid;
  border-collapse: collapse;
}
table.docutils.booktabs * {
  border: 0px;
}
table.docutils.booktabs th {
  border-bottom: thin solid;
  text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
  font-size: 100% }
ul.auto-toc {
  list-style-type: none }
</style>
</head>
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.
 
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
 
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.
 
 
</html>