aboutsummaryrefslogtreecommitdiffstats
path: root/beancount_extras_kris7t/plugins/default_tolerance.py
diff options
context:
space:
mode:
Diffstat (limited to 'beancount_extras_kris7t/plugins/default_tolerance.py')
-rw-r--r--beancount_extras_kris7t/plugins/default_tolerance.py47
1 files changed, 47 insertions, 0 deletions
diff --git a/beancount_extras_kris7t/plugins/default_tolerance.py b/beancount_extras_kris7t/plugins/default_tolerance.py
new file mode 100644
index 0000000..52fa956
--- /dev/null
+++ b/beancount_extras_kris7t/plugins/default_tolerance.py
@@ -0,0 +1,47 @@
1'''
2Plugin that sets the tolerance values of balance assertions to an amount determined by the account.
3'''
4__copyright__ = 'Copyright (c) 2020 Kristóf Marussy <kristof@marussy.com>'
5__license__ = 'GNU GPLv2'
6
7from decimal import Decimal
8from typing import Any, Dict, List, NamedTuple, Optional, Tuple
9
10from beancount.core.data import Open, Balance, Directive, Entries, Meta
11
12__plugins__ = ('set_tolerances_to_default',)
13
14DEFAULT_TOLERANCE_META = 'default-balance-tolerance'
15
16
17class DefaultToleranceError(NamedTuple):
18 source: Optional[Meta]
19 message: str
20 entry: Directive
21
22
23def set_tolerances_to_default(entries: Entries,
24 options_map: Dict[str, Any],
25 config_str: Optional[str] = None) -> \
26 Tuple[Entries, List[DefaultToleranceError]]:
27 errors: List[DefaultToleranceError] = []
28 accounts: Dict[str, Optional[Decimal]] = {}
29 for entry in entries:
30 if not isinstance(entry, Open):
31 continue
32 if tolerance := entry.meta.get(DEFAULT_TOLERANCE_META, None):
33 if isinstance(tolerance, Decimal):
34 accounts[entry.account] = tolerance
35 else:
36 errors.append(DefaultToleranceError(
37 entry.meta,
38 f'{DEFAULT_TOLERANCE_META} must be decimal, got {tolerance} instead',
39 entry))
40 new_entries: Entries = []
41 for entry in entries:
42 if isinstance(entry, Balance) and entry.tolerance is None and entry.account in accounts:
43 account_tolerance = accounts[entry.account]
44 new_entries.append(entry._replace(tolerance=account_tolerance))
45 else:
46 new_entries.append(entry)
47 return new_entries, errors