''' Plugin that sets the tolerance values of balance assertions to an amount determined by the account. ''' __copyright__ = 'Copyright (c) 2020 Kristóf Marussy ' __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