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