template: Don't output accounts that end up having no amount.

This commit is contained in:
Brett Smith 2017-12-16 13:10:49 -05:00
parent a1f815c60b
commit e3ec03cf19
3 changed files with 38 additions and 8 deletions

View file

@ -91,12 +91,16 @@ 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 = collections.OrderedDict()
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
self.signed_currencies = set(signed_currencies) self.signed_currencies = set(signed_currencies)
self.template_name = template_name self.template_name = template_name
self._last_template_vars = object() self._last_template_vars = object()
def is_empty(self):
return not self.splits
def add(self, account, amount_expr): def add(self, account, amount_expr):
try: try:
clean_expr = AmountTokenTransformer.from_str(amount_expr).transform() clean_expr = AmountTokenTransformer.from_str(amount_expr).transform()
@ -105,6 +109,10 @@ class AccountSplitter:
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[account] = compiled_expr
self.metadata.append('')
def set_metadata(self, metadata_s):
self.metadata[-1] = metadata_s
def _currency_decimal(self, amount, currency): def _currency_decimal(self, amount, currency):
return decimal.Decimal(babel.numbers.format_currency(amount, currency, '###0.###')) return decimal.Decimal(babel.numbers.format_currency(amount, currency, '###0.###'))
@ -146,11 +154,16 @@ 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 in amounts.items(): for (account, amount), metadata in zip(amounts.items(), self.metadata):
yield ' {:45} {:>19}\n'.format( if amount == 0:
yield ''
else:
account_s = ' {:45} {:>19}\n'.format(
account.format_map(template_vars), account.format_map(template_vars),
babel.numbers.format_currency(amount, template_vars['currency'], amt_fmt), babel.numbers.format_currency(amount, template_vars['currency'], amt_fmt),
) )
metadata_s = metadata.format_map(template_vars)
yield account_s + metadata_s
def render_next(self, template_vars): def render_next(self, template_vars):
if template_vars is not self._last_template_vars: if template_vars is not self._last_template_vars:
@ -180,8 +193,7 @@ class Template:
break break
del lines[:index] del lines[:index]
self.format_funcs = [ self.format_funcs = [
'\n'.format_map, '\n{date} {payee}\n'.format_map,
'{date} {payee}\n'.format_map,
] ]
start_index = 0 start_index = 0
for index, line in enumerate(lines): for index, line in enumerate(lines):
@ -204,7 +216,10 @@ class Template:
def _add_str_func(self, str_seq): def _add_str_func(self, str_seq):
str_flat = ''.join(' ' + s for s in str_seq) str_flat = ''.join(' ' + s for s in str_seq)
if self.splitter.is_empty():
self.format_funcs.append(str_flat.format_map) self.format_funcs.append(str_flat.format_map)
else:
self.splitter.set_metadata(str_flat)
def render(self, payee, amount, currency, date=None, **template_vars): def render(self, payee, amount, currency, date=None, **template_vars):
if date is None: if date is None:

View file

@ -24,6 +24,7 @@ template =
[Multivalue] [Multivalue]
template = template =
Expenses:Taxes {tax} Expenses:Taxes {tax}
;TaxAuthority: IRS
Accrued:Accounts Receivable {amount} - {tax} Accrued:Accounts Receivable {amount} - {tax}
Income:RBI -.1*{amount} Income:RBI -.1*{amount}
Income:Donations -.9*{amount} Income:Donations -.9*{amount}

View file

@ -83,11 +83,25 @@ def test_multivalue():
"", "",
"2015/03/14 DD", "2015/03/14 DD",
" Expenses:Taxes 12.50 USD", " Expenses:Taxes 12.50 USD",
" ;TaxAuthority: IRS",
" Accrued:Accounts Receivable 137.50 USD", " Accrued:Accounts Receivable 137.50 USD",
" Income:RBI -15.00 USD", " Income:RBI -15.00 USD",
" Income:Donations -135.00 USD", " Income:Donations -135.00 USD",
] ]
def test_zeroed_account_skipped():
tmpl = template_from('Multivalue')
rendered = tmpl.render('GG', decimal.Decimal('110.00'), 'USD', DATE,
tax=decimal.Decimal(0))
lines = [normalize_whitespace(s) for s in rendered.splitlines()]
assert lines == [
"",
"2015/03/14 GG",
" Accrued:Accounts Receivable 110.00 USD",
" Income:RBI -11.00 USD",
" Income:Donations -99.00 USD",
]
@pytest.mark.parametrize('amount_expr', [ @pytest.mark.parametrize('amount_expr', [
'', '',
'name', 'name',