filters: Add remove_opening_balance_txn.
This commit is contained in:
parent
32b62df540
commit
a008a09477
2 changed files with 54 additions and 0 deletions
|
@ -16,17 +16,24 @@
|
|||
|
||||
import re
|
||||
|
||||
from beancount.core import data as bc_data
|
||||
|
||||
from . import data
|
||||
from . import rtutil
|
||||
|
||||
from typing import (
|
||||
cast,
|
||||
Iterable,
|
||||
Optional,
|
||||
Pattern,
|
||||
Union,
|
||||
)
|
||||
from .beancount_types import (
|
||||
Directive,
|
||||
Entries,
|
||||
MetaKey,
|
||||
MetaValue,
|
||||
Transaction,
|
||||
)
|
||||
|
||||
Postings = Iterable[data.Posting]
|
||||
|
@ -56,3 +63,29 @@ def filter_for_rt_id(postings: Postings, ticket_id: Union[int, str]) -> Postings
|
|||
"""
|
||||
regexp = rtutil.RT.metadata_regexp(ticket_id, first_link_only=True)
|
||||
return filter_meta_match(postings, 'rt-id', regexp)
|
||||
|
||||
def remove_opening_balance_txn(entries: Entries) -> Optional[Transaction]:
|
||||
"""Remove an opening balance transaction from entries returned by Beancount
|
||||
|
||||
Returns the removed transaction if found, or None if not.
|
||||
Note that it modifies the ``entries`` argument in-place.
|
||||
|
||||
This function is useful for tools like accrual-report that are more
|
||||
focused on finding and reporting related transactions than providing
|
||||
total account balances, etc. Since the opening balance transaction does not
|
||||
provide the same metadata documentation as typical transactions, it's
|
||||
typically easiest to filter it out before cross-referencing transactions by
|
||||
metadata.
|
||||
|
||||
Note that this function only removes a single transaction, because that's
|
||||
fastest for the common case.
|
||||
"""
|
||||
for index, entry in enumerate(entries):
|
||||
if isinstance(entry, bc_data.Transaction):
|
||||
entry = cast(Transaction, entry)
|
||||
if data.is_opening_balance_txn(entry):
|
||||
break
|
||||
else:
|
||||
return None
|
||||
del entries[index]
|
||||
return entry
|
||||
|
|
|
@ -134,3 +134,24 @@ def test_filter_for_rt_id_uses_first_link_only():
|
|||
postings = data.Posting.from_entries(entries)
|
||||
actual = filters.filter_for_rt_id(postings, 350)
|
||||
check_filter(actual, entries, ()),
|
||||
|
||||
@pytest.mark.parametrize('opening_txn', [
|
||||
testutil.OpeningBalance(),
|
||||
None,
|
||||
])
|
||||
def test_remove_opening_balance_txn(opening_txn):
|
||||
entries = [
|
||||
testutil.Transaction(postings=[
|
||||
(account, amount),
|
||||
('Assets:Checking', -amount),
|
||||
])
|
||||
for account, amount in [
|
||||
('Income:Donations', -50),
|
||||
('Expenses:Other', 75),
|
||||
]]
|
||||
if opening_txn is not None:
|
||||
entries.insert(1, opening_txn)
|
||||
actual = filters.remove_opening_balance_txn(entries)
|
||||
assert actual is opening_txn
|
||||
assert len(entries) == 2
|
||||
assert opening_txn not in entries
|
||||
|
|
Loading…
Reference in a new issue