Skip to content

Commit

Permalink
fix: ensure independence of metadata / linking config (#27)
Browse files Browse the repository at this point in the history
* fix: ensure independence of metadata / linking config

* rfct: Address linting issues
  • Loading branch information
librarianmage authored Apr 20, 2024
1 parent e73097c commit 8867cf4
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 11 deletions.
83 changes: 83 additions & 0 deletions beancount_reds_plugins/zerosum/test_zerosum.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,3 +395,86 @@ def test_link_prefix_successfully_changed(self, entries, _, options_map):
any(link.startswith("ZSM") for link in (matched["Pay stub"].links & matched["401k statement"].links)))
self.assertFalse(
any(link.startswith("ZSM") for link in (matched["Bank account"].links & matched["401k statement"].links)))

@loader.load_doc()
def test_metadata_independent_from_linking(self, entries, _, options_map):
"""
2023-01-01 open Income:Salary
2023-01-01 open Assets:Bank:Checkings
2023-01-01 open Assets:Zero-Sum-Accounts:Checkings
2023-01-01 open Assets:Brokerage:401k
2023-01-01 open Assets:Zero-Sum-Accounts:401k
2024-02-15 * "Pay stub"
Income:Salary -1100.06 USD
Assets:Zero-Sum-Accounts:Checkings 999.47 USD
Assets:Zero-Sum-Accounts:401k 100.59 USD
2024-02-16 * "Bank account"
Assets:Bank:Checkings 999.47 USD
Assets:Zero-Sum-Accounts:Checkings
2024-02-16 * "401k statement"
Assets:Brokerage:401k 100.59 USD
Assets:Zero-Sum-Accounts:401k
"""
new_entries, _ = zerosum.zerosum(
entries, options_map,
config[:-2] + """'match_metadata': True,\n'match_metadata_name': 'MATCH',\n
'link_transactions': False,\n'link_prefix': 'ZSM'\n}""")

matched = dict(
[(m.narration, m) for m in
get_entries_with_acc_regexp(new_entries, ':ZSA-Matched')])

self.assertEqual(3, len(matched))
self.assertEqual(matched["Pay stub"].postings[1].meta['MATCH'],
matched["Bank account"].postings[1].meta['MATCH'])
self.assertEqual(matched["Pay stub"].postings[2].meta['MATCH'],
matched["401k statement"].postings[1].meta['MATCH'])

for _, m in matched.items():
self.assertFalse(any(link.startswith("ZSM") for link in m.links))

@loader.load_doc()
def test_linking_independent_from_metadata(self, entries, _, options_map):
"""
2023-01-01 open Income:Salary
2023-01-01 open Assets:Bank:Checkings
2023-01-01 open Assets:Zero-Sum-Accounts:Checkings
2023-01-01 open Assets:Brokerage:401k
2023-01-01 open Assets:Zero-Sum-Accounts:401k
2024-02-15 * "Pay stub"
Income:Salary -1100.06 USD
Assets:Zero-Sum-Accounts:Checkings 999.47 USD
Assets:Zero-Sum-Accounts:401k 100.59 USD
2024-02-16 * "Bank account"
Assets:Bank:Checkings 999.47 USD
Assets:Zero-Sum-Accounts:Checkings
2024-02-16 * "401k statement"
Assets:Brokerage:401k 100.59 USD
Assets:Zero-Sum-Accounts:401k
"""
new_entries, _ = zerosum.zerosum(
entries, options_map,
config[:-2] + """'match_metadata': False,\n'match_metadata_name': 'MATCH',\n
'link_transactions': True,\n'link_prefix': 'ZSM'\n}""")

matched = dict(
[(m.narration, m) for m in
get_entries_with_acc_regexp(new_entries, ':ZSA-Matched')])

self.assertEqual(3, len(matched))
for _, m in matched.items():
for p in m.postings:
self.assertTrue('MATCH' not in p.meta)

self.assertTrue(
any(link.startswith("ZSM") for link in (matched["Pay stub"].links & matched["Bank account"].links)))
self.assertTrue(
any(link.startswith("ZSM") for link in (matched["Pay stub"].links & matched["401k statement"].links)))
self.assertFalse(
any(link.startswith("ZSM") for link in (matched["Bank account"].links & matched["401k statement"].links)))
29 changes: 18 additions & 11 deletions beancount_reds_plugins/zerosum/zerosum.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,18 +183,21 @@


# replace the account on a given posting with a new account
def account_replace(txn, posting, new_account, match_id, matching_id_string):
def account_replace(txn, posting, new_account):
# create a new posting with the new account, then remove old and add new
# from parent transaction
if match_id:
new_posting = posting._replace(account=new_account)
txn.postings.remove(posting)
txn.postings.append(new_posting)


def metadata_update(txn, posting, match_id, matching_id_string):
if match_id and matching_id_string:
if posting.meta:
# Will overwrite an existing match (shouldn't exist)
posting.meta.update({matching_id_string: match_id})
else:
posting.meta = {matching_id_string: match_id}
new_posting = posting._replace(account=new_account)
txn.postings.remove(posting)
txn.postings.append(new_posting)


def transaction_update(txn, match_id, link_prefix):
Expand Down Expand Up @@ -274,9 +277,9 @@ def generate_match_id():
(account_name_from, account_name_to) = config_obj.pop('account_name_replace', ('', ''))
tolerance = config_obj.pop('tolerance', DEFAULT_TOLERANCE)
match_metadata = config_obj.pop('match_metadata', False)
match_metadata_name = config_obj.pop('match_metadata_name', MATCHING_ID_STRING if match_metadata else "")
match_metadata_name = config_obj.pop('match_metadata_name', MATCHING_ID_STRING)
link_transactions = config_obj.pop('link_transactions', False)
link_prefix = config_obj.pop('link_prefix', LINK_PREFIX if link_transactions else "")
link_prefix = config_obj.pop('link_prefix', LINK_PREFIX)

new_accounts = set()
zerosum_postings_count = 0
Expand Down Expand Up @@ -315,11 +318,15 @@ def generate_match_id():
# print('Match:', txn.date, match[1].date, match[1].date - txn.date,
# posting.units, posting.meta['lineno'], match[0].meta['lineno'])
match_count += 1

account_replace(txn, posting, target_account)
account_replace(match[1], match[0], target_account)

match_id = generate_match_id() if match_metadata or link_transactions else None
account_replace(txn, posting, target_account,
match_id, match_metadata_name)
account_replace(match[1], match[0], target_account,
match_id, match_metadata_name)

if match_metadata:
metadata_update(txn, posting, match_id, match_metadata_name)
metadata_update(match[1], match[0], match_id, match_metadata_name)

if link_transactions:
transaction_update(txn, match_id, link_prefix)
Expand Down

0 comments on commit 8867cf4

Please sign in to comment.