rewrite: Add docstring with user documentation.
This commit is contained in:
parent
3219bf89d2
commit
e60078933d
1 changed files with 127 additions and 1 deletions
|
@ -1,4 +1,130 @@
|
|||
"""rewrite.py - Post rewriting for financial reports"""
|
||||
"""rewrite.py - Post rewriting for financial reports
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
There are some kinds of posting metadata that's too impractical to write when
|
||||
you enter it the books. For example, the ``expense-type`` of employee payroll
|
||||
is usually determined by the employee's records or estimate at the end of the
|
||||
year. It isn't known when payroll expenses are posted throughout the year, and
|
||||
then there's too many of them to go back and code it manually.
|
||||
|
||||
Rewrite rules solve this problem. They provide a mechanism to make safe, bulk
|
||||
transformations to postings just after they're loaded and before they're
|
||||
reported. They let you fill in the gaps between the data in the books and
|
||||
different reporting requirements.
|
||||
|
||||
Most reporting tools load rewrite rules written in YAML, so the examples in
|
||||
this documentation are written that way. (If you're developing reporting tools,
|
||||
note RewriteRule accepts a native Python dictionary.) One typical rule looks
|
||||
like::
|
||||
|
||||
if:
|
||||
- SUBJECT OP VALUE
|
||||
[- SUBJECT2 OP2 VALUE2
|
||||
- …]
|
||||
action1:
|
||||
- SUBJECT OP VALUE
|
||||
[- SUBJECT2 OP2 VALUE2
|
||||
- …]
|
||||
[action2:
|
||||
- …
|
||||
…]
|
||||
|
||||
A ruleset, as in a YAML file, is just an array of hashes like this.
|
||||
|
||||
Conditions and Actions
|
||||
----------------------
|
||||
|
||||
The hash must have at least two keys. One of them must be ``if``, and its value
|
||||
is an array of condition strings. The rest can have any name you like and are
|
||||
actions. Each action transforms an original posting that matched the ``if``
|
||||
conditions and yields a new posting from it. The value is an array of action
|
||||
strings. Conditions and actions are written the same way;
|
||||
conditions just use test operators, while actions use assignment operators.
|
||||
|
||||
Subjects
|
||||
--------
|
||||
|
||||
There are two kinds of subjects, attributes and metadata.
|
||||
|
||||
Attributes start with a ``.`` and access data directly on the posting line,
|
||||
or from the parent transaction line. You can use these attributes:
|
||||
|
||||
================ =======================================================
|
||||
Name Description
|
||||
================ =======================================================
|
||||
``.account`` The name of the account on the posting line
|
||||
---------------- -------------------------------------------------------
|
||||
``.date`` The date of the posting's transaction. When you work on
|
||||
a date, write the value in ISO ``YYYY-MM-DD`` format.
|
||||
---------------- -------------------------------------------------------
|
||||
``.number`` The number part of the posting's position;
|
||||
i.e., the amount without the currency.
|
||||
================ =======================================================
|
||||
|
||||
Any other string is a metadata key. As usual, if a condition tries to read
|
||||
metadata that does not exist on the posting, it will fall back to checking the
|
||||
transaction. Metadata values are always treated as strings. NOTE: This means
|
||||
comparisons against non-string metadata values, like dates and amounts, might
|
||||
not work the way you want.
|
||||
|
||||
Condition Operators
|
||||
-------------------
|
||||
|
||||
Conditions can always use Python's basic comparison operators:
|
||||
``== != < <= > >=``. You can also use the following:
|
||||
|
||||
================ =======================================================
|
||||
Name Description
|
||||
================ =======================================================
|
||||
``.account in`` The value is parsed as a space-separated list of
|
||||
account names. The condition matches when the posting's
|
||||
account is any of those named accounts, or any of their
|
||||
respective subaccounts.
|
||||
================ =======================================================
|
||||
|
||||
Action Operators
|
||||
----------------
|
||||
|
||||
You can set ``.account`` and any metadata with ``=``. Values are always treated
|
||||
as strings.
|
||||
|
||||
You can also transform the posting's number using ``.number *= NUMBER``. This
|
||||
is mainly used to divide the posting's amount across multiple actions in one
|
||||
rule.
|
||||
|
||||
Execution
|
||||
---------
|
||||
|
||||
When rewrite rules are applied to postings, the first rule whose condition
|
||||
matches "wins." When a source posting matches a rule's conditions, its actions
|
||||
are applied, and the transformed posting(s) replace the source posting.
|
||||
No more rewrite rules are considered for either the original source posting
|
||||
or the transformed posting(s).
|
||||
|
||||
Validations
|
||||
-----------
|
||||
|
||||
Rewrite rules are validated to help ensure that you don't break the fundamental
|
||||
accounting equation, Equity = Assets - Liabilities.
|
||||
|
||||
* If an action assigns to ``.account``, there must also be a condition to check
|
||||
that the ``.account`` is in the same category, using ``==`` or ``in``.
|
||||
You cannot change an Asset into a Liability or Equity, and so on.
|
||||
|
||||
* All actions in a rewrite rule must multiply ``.number`` by a total of 1.
|
||||
(Actions that don't explicitly multiply the number are understood to
|
||||
multiply it by 1.) For example, a rewrite rule can have two actions that
|
||||
each multiply the number by .5, or one by .8 and the other by .2. It
|
||||
cannot have two actions that each multiply the number by 1, or .3,
|
||||
etc. Otherwise, the different postings of a transaction would not balance.
|
||||
|
||||
* You cannot assign to ``.date`` at all. Otherwise, you might separate postings
|
||||
of the same transaction in time, and the accounting equation would not hold
|
||||
during the time gap.
|
||||
|
||||
"""
|
||||
# Copyright © 2020 Brett Smith
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
|
|
Loading…
Reference in a new issue