Files @ 93fffe6666ec
Branch filter:

Location: NPO-Accounting/import2ledger/tests/test_templates.py - annotation

Brett Smith
importers: New importer for North Bay Python invoices.

This probably has no use outside Conservancy.
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
a1f815c60b03
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
093834dd15db
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
093834dd15db
093834dd15db
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
5c73c40bccfe
3b821cbbee95
3b821cbbee95
3b821cbbee95
3b821cbbee95
3b821cbbee95
3b821cbbee95
3b821cbbee95
3b821cbbee95
3b821cbbee95
3b821cbbee95
e3ec03cf1933
3b821cbbee95
3b821cbbee95
3b821cbbee95
3b821cbbee95
a1f815c60b03
e3ec03cf1933
e3ec03cf1933
e3ec03cf1933
e3ec03cf1933
e3ec03cf1933
e3ec03cf1933
e3ec03cf1933
e3ec03cf1933
e3ec03cf1933
e3ec03cf1933
e3ec03cf1933
e3ec03cf1933
e3ec03cf1933
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
a1f815c60b03
import configparser
import datetime
import decimal
import pathlib

import pytest
from import2ledger import errors, template

from . import DATA_DIR, normalize_whitespace

DATE = datetime.date(2015, 3, 14)

config = configparser.ConfigParser(comment_prefixes='#')
with pathlib.Path(DATA_DIR, 'templates.ini').open() as conffile:
    config.read_file(conffile)

def template_from(section_name, *args, **kwargs):
    return template.Template(config[section_name]['template'], *args, **kwargs)

def assert_easy_render(tmpl, entity, amount, currency, expect_date, expect_amt):
    rendered = tmpl.render(entity, decimal.Decimal(amount), currency, DATE)
    lines = [normalize_whitespace(s) for s in rendered.splitlines()]
    assert lines == [
        "",
        "{} {}".format(expect_date, entity),
        "  Accrued:Accounts Receivable  " + expect_amt,
        "  Income:Donations  " + expect_amt.replace(amount, "-" + amount),
    ]

def test_easy_template():
    tmpl = template_from('Simplest')
    assert_easy_render(tmpl, 'JJ', '5.99', 'CAD', '2015/03/14', '5.99 CAD')

def test_date_formatting():
    tmpl = template_from('Simplest', date_fmt='%Y-%m-%d')
    assert_easy_render(tmpl, 'KK', '6.99', 'CAD', '2015-03-14', '6.99 CAD')

def test_currency_formatting():
    tmpl = template_from('Simplest', signed_currencies=['USD'])
    assert_easy_render(tmpl, 'CC', '7.99', 'USD', '2015/03/14', '$7.99')

def test_complex_template():
    template_vars = {
        'entity': 'T-T',
        'program': 'Spectrum Defense',
        'txid': 'ABCDEF',
    }
    tmpl = template_from('Complex', date_fmt='%Y-%m-%d', signed_currencies=['USD'])
    rendered = tmpl.render('TT', decimal.Decimal('125.50'), 'USD', DATE, **template_vars)
    lines = [normalize_whitespace(s) for s in rendered.splitlines()]
    assert lines == [
        "",
        "2015-03-14 TT",
        "  ;Tag: Value",
        "  ;TransactionID: ABCDEF",
        "  Accrued:Accounts Receivable  $125.50",
        "  ;Entity: Supplier",
        "  Income:Donations:Spectrum Defense  $-119.85",
        "  ;Program: Spectrum Defense",
        "  ;Entity: T-T",
        "  Income:Donations:General  $-5.65",
        "  ;Entity: T-T",
    ]

def test_balancing():
    tmpl = template_from('FiftyFifty')
    rendered = tmpl.render('FF', decimal.Decimal('1.01'), 'USD', DATE)
    lines = [normalize_whitespace(s) for s in rendered.splitlines()]
    assert lines == [
        "",
        "2015/03/14 FF",
        "  Accrued:Accounts Receivable  1.01 USD",
        "  Income:Donations  -0.50 USD",
        "  Income:Sales  -0.51 USD",
    ]

def test_multivalue():
    tmpl = template_from('Multivalue')
    rendered = tmpl.render('DD', decimal.Decimal('150.00'), 'USD', DATE,
                           tax=decimal.Decimal('12.50'))
    lines = [normalize_whitespace(s) for s in rendered.splitlines()]
    assert lines == [
        "",
        "2015/03/14 DD",
        "  Expenses:Taxes  12.50 USD",
        "  ;TaxAuthority: IRS",
        "  Accrued:Accounts Receivable  137.50 USD",
        "  Income:RBI  -15.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', [
    '',
    'name',
    '-',
    '()',
    '+()',
    '{}',
    '{{}}',
    '{()}',
    '{name',
    'name}',
    '{42}',
    '(5).real',
    '{amount.real}',
    '{amount.is_nan()}',
    '{Decimal}',
    '{FOO}',
])
def test_bad_amount_expression(amount_expr):
    with pytest.raises(errors.UserInputError):
        template.Template(" Income  " + amount_expr)