aboutsummaryrefslogtreecommitdiffstats
path: root/beancount_extras_kris7t/plugins/default_tolerance.py
blob: 52fa956dc93b845aeb887d636c4847464d582db9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
'''
Plugin that sets the tolerance values of balance assertions to an amount determined by the account.
'''
__copyright__ = 'Copyright (c) 2020  Kristóf Marussy <kristof@marussy.com>'
__license__ = 'GNU GPLv2'

from decimal import Decimal
from typing import Any, Dict, List, NamedTuple, Optional, Tuple

from beancount.core.data import Open, Balance, Directive, Entries, Meta

__plugins__ = ('set_tolerances_to_default',)

DEFAULT_TOLERANCE_META = 'default-balance-tolerance'


class DefaultToleranceError(NamedTuple):
    source: Optional[Meta]
    message: str
    entry: Directive


def set_tolerances_to_default(entries: Entries,
                              options_map: Dict[str, Any],
                              config_str: Optional[str] = None) -> \
                              Tuple[Entries, List[DefaultToleranceError]]:
    errors: List[DefaultToleranceError] = []
    accounts: Dict[str, Optional[Decimal]] = {}
    for entry in entries:
        if not isinstance(entry, Open):
            continue
        if tolerance := entry.meta.get(DEFAULT_TOLERANCE_META, None):
            if isinstance(tolerance, Decimal):
                accounts[entry.account] = tolerance
            else:
                errors.append(DefaultToleranceError(
                    entry.meta,
                    f'{DEFAULT_TOLERANCE_META} must be decimal, got {tolerance} instead',
                    entry))
    new_entries: Entries = []
    for entry in entries:
        if isinstance(entry, Balance) and entry.tolerance is None and entry.account in accounts:
            account_tolerance = accounts[entry.account]
            new_entries.append(entry._replace(tolerance=account_tolerance))
        else:
            new_entries.append(entry)
    return new_entries, errors