Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ensure independence of metadata / linking config #27

Merged
merged 2 commits into from
Apr 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading