template: Let users split an account multiple times per template.

This commit is contained in:
Brett Smith 2017-12-27 11:39:34 -05:00
parent 9f720527f1
commit 40552d665a

View file

@ -94,7 +94,7 @@ class AccountSplitter:
def __init__(self, signed_currencies, signed_currency_fmt, unsigned_currency_fmt, def __init__(self, signed_currencies, signed_currency_fmt, unsigned_currency_fmt,
template_name): template_name):
self.splits = collections.OrderedDict() self.splits = []
self.metadata = [] self.metadata = []
self.signed_currency_fmt = signed_currency_fmt self.signed_currency_fmt = signed_currency_fmt
self.unsigned_currency_fmt = unsigned_currency_fmt self.unsigned_currency_fmt = unsigned_currency_fmt
@ -112,7 +112,7 @@ class AccountSplitter:
except (SyntaxError, tokenize.TokenError, ValueError) as error: except (SyntaxError, tokenize.TokenError, ValueError) as error:
raise errors.UserInputConfigurationError(error.args[0], amount_expr) raise errors.UserInputConfigurationError(error.args[0], amount_expr)
else: else:
self.splits[account] = compiled_expr self.splits.append((account, compiled_expr))
self.metadata.append('') self.metadata.append('')
def set_metadata(self, metadata_s): def set_metadata(self, metadata_s):
@ -125,12 +125,12 @@ class AccountSplitter:
cmp_func = operator.lt if to_amount > 0 else operator.gt cmp_func = operator.lt if to_amount > 0 else operator.gt
should_balance = functools.partial(cmp_func, 0) should_balance = functools.partial(cmp_func, 0)
remainder = to_amount remainder = to_amount
to_account = None balance_index = None
for account, amount in amounts.items(): for index, (_, amount) in enumerate(amounts):
if should_balance(amount): if should_balance(amount):
remainder -= amount remainder -= amount
to_account = account balance_index = index
if to_account is None: if balance_index is None:
pass pass
elif (abs(remainder) / abs(to_amount)) >= decimal.Decimal('.1'): elif (abs(remainder) / abs(to_amount)) >= decimal.Decimal('.1'):
raise errors.UserInputConfigurationError( raise errors.UserInputConfigurationError(
@ -138,16 +138,17 @@ class AccountSplitter:
self.template_name, self.template_name,
) )
else: else:
amounts[to_account] += remainder account_name, start_amount = amounts[balance_index]
amounts[balance_index] = (account_name, start_amount + remainder)
def _build_amounts(self, template_vars): def _build_amounts(self, template_vars):
amount_vars = {k: v for k, v in template_vars.items() if isinstance(v, decimal.Decimal)} amount_vars = {k: v for k, v in template_vars.items() if isinstance(v, decimal.Decimal)}
amount_vars['Decimal'] = decimal.Decimal amount_vars['Decimal'] = decimal.Decimal
amounts = collections.OrderedDict( amounts = [
(account, self._currency_decimal(eval(amount_expr, amount_vars), (account, self._currency_decimal(eval(amount_expr, amount_vars),
template_vars['currency'])) template_vars['currency']))
for account, amount_expr in self.splits.items() for account, amount_expr in self.splits
) ]
self._balance_amounts(amounts, template_vars['amount']) self._balance_amounts(amounts, template_vars['amount'])
self._balance_amounts(amounts, -template_vars['amount']) self._balance_amounts(amounts, -template_vars['amount'])
return amounts return amounts
@ -158,7 +159,7 @@ class AccountSplitter:
amt_fmt = self.signed_currency_fmt amt_fmt = self.signed_currency_fmt
else: else:
amt_fmt = self.unsigned_currency_fmt amt_fmt = self.unsigned_currency_fmt
for (account, amount), metadata in zip(amounts.items(), self.metadata): for (account, amount), metadata in zip(amounts, self.metadata):
if amount == 0: if amount == 0:
yield '' yield ''
else: else: