@@ -63,11 +63,6 @@ ACCOUNTS = [
'Liabilities:Payable:Vacation',
]
CONSISTENT_METADATA = [
'contract',
'purchase-order',
class AgingRow(NamedTuple):
date: datetime.date
entity: Sequence[str]
@@ -271,26 +266,6 @@ def test_accrual_postings_consistent_account(acct_name):
])
related = accrual.AccrualPostings(data.Posting.from_txn(txn))
assert related.account == acct_name
assert related.accounts == {acct_name}
@pytest.mark.parametrize('meta_key,acct_name', testutil.combine_values(
CONSISTENT_METADATA,
ACCOUNTS,
))
def test_accrual_postings_consistent_metadata(meta_key, acct_name):
meta_value = f'{meta_key}.pdf'
meta = {
meta_key: meta_value,
'invoice': f'invoice with {meta_key}.pdf',
}
txn = testutil.Transaction(postings=[
(acct_name, 70, meta),
(acct_name, 35, meta),
attr_name = meta_key.replace('-', '_')
assert getattr(related, attr_name) == meta_value
assert getattr(related, f'{attr_name}s') == {meta_value}
def test_accrual_postings_entity():
@@ -299,8 +274,8 @@ def test_accrual_postings_entity():
(ACCOUNTS[0], -10, {'entity': 'Payee10'}),
assert related.accrued_entities == {'Accruee'}
assert related.paid_entities == {'Payee10', 'Payee15'}
assert related.entity == 'Accruee'
assert set(related.entities()) == {'Accruee', 'Payee10', 'Payee15'}
def test_accrual_postings_entities():
@@ -333,107 +308,6 @@ def test_accrual_postings_inconsistent_account():
assert related.account is related.INCONSISTENT
assert related.accounts == set(ACCOUNTS)
def test_accrual_postings_inconsistent_metadata(meta_key, acct_name):
invoice = 'invoice with {meta_key}.pdf'
(acct_name, 20, {'invoice': invoice, meta_key: meta_value}),
(acct_name, 35, {'invoice': invoice}),
assert getattr(related, attr_name) is related.INCONSISTENT
assert getattr(related, f'{attr_name}s') == {meta_value, None}
@pytest.mark.parametrize('meta_key,account', testutil.combine_values(
def test_consistency_check_when_consistent(meta_key, account):
invoice = f'test-{meta_key}-invoice'
meta_value = f'test-{meta_key}-value'
'invoice': invoice,
(account, 100, meta),
(account, -100, meta),
assert not list(related.report_inconsistencies())
['approval', 'entity', 'fx-rate', 'statement'],
def test_consistency_check_ignored_metadata(meta_key, account):
(account, 100, {'invoice': invoice, meta_key: 'credit'}),
(account, -100, {'invoice': invoice, meta_key: 'debit'}),
def test_consistency_check_when_inconsistent(meta_key, account):
(account, 100, {'invoice': invoice, meta_key: 'credit', 'lineno': 1}),
(account, -100, {'invoice': invoice, meta_key: 'debit', 'lineno': 2}),
errors = list(related.report_inconsistencies())
for exp_lineno, (actual, exp_msg) in enumerate(itertools.zip_longest(errors, [
f'inconsistent {meta_key} for invoice {invoice}: credit',
f'inconsistent {meta_key} for invoice {invoice}: debit',
]), 1):
assert actual.message == exp_msg
assert actual.entry is txn
assert actual.source.get('lineno') == exp_lineno
def test_consistency_check_cost():
account = ACCOUNTS[0]
invoice = 'test-cost-invoice'
(account, 100, 'EUR', ('1.1251', 'USD'), {'invoice': invoice, 'lineno': 1}),
(account, -100, 'EUR', ('1.125', 'USD'), {'invoice': invoice, 'lineno': 2}),
for post, err in itertools.zip_longest(txn.postings, errors):
assert err.message == f'inconsistent cost for invoice {invoice}: {post.cost}'
assert err.entry is txn
assert err.source.get('lineno') == post.meta['lineno']
def test_make_consistent_not_needed():
main_meta = {
'entity': 'ConsistentTest',
'invoice': 'Invoices/ConsistentDoc.pdf',
other_meta = {key: f'{key}.pdf' for key in CONSISTENT_METADATA}
# We intentionally make inconsistencies in "minor" metadata that shouldn't
# split out the group.
(ACCOUNTS[0], 20, {**main_meta, **other_meta}),
(ACCOUNTS[0], 25, {**main_meta}),
consistent = related.make_consistent()
actual_key, actual_postings = next(consistent)
assert actual_key == main_meta['invoice']
assert actual_postings is related
assert next(consistent, None) is None
@pytest.mark.parametrize('acct_name,invoice,day', testutil.combine_values(
@@ -495,8 +369,10 @@ def test_make_consistent_across_entity(acct_name):
assert len(consistent) == 3
for key, posts in consistent.items():
assert len(posts) == 1
assert len(posts.accrued_entities) == 1
assert next(posts.entities()) in key
entities = posts.entities()
assert next(entities, None) == posts.entity
assert next(entities, None) is None
assert posts.entity in key
@pytest.mark.parametrize('acct_name', ACCOUNTS)
def test_make_consistent_entity_differs_accrual_payment(acct_name):