data: Add Posting.from_entries() method.
This commit is contained in:
parent
3000aeee09
commit
8d584734ec
2 changed files with 39 additions and 0 deletions
|
@ -40,6 +40,7 @@ from typing import (
|
||||||
)
|
)
|
||||||
|
|
||||||
from .beancount_types import (
|
from .beancount_types import (
|
||||||
|
Directive,
|
||||||
MetaKey,
|
MetaKey,
|
||||||
MetaValue,
|
MetaValue,
|
||||||
Posting as BasePosting,
|
Posting as BasePosting,
|
||||||
|
@ -294,6 +295,19 @@ class Posting(BasePosting):
|
||||||
for index, post in enumerate(txn.postings):
|
for index, post in enumerate(txn.postings):
|
||||||
yield cls.from_beancount(txn, index, post)
|
yield cls.from_beancount(txn, index, post)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_entries(cls, entries: Iterable[Directive]) -> Iterable['Posting']:
|
||||||
|
"""Yield an enhanced Posting object for every posting in these entries"""
|
||||||
|
for entry in entries:
|
||||||
|
# Because Beancount's own Transaction class isn't type-checkable,
|
||||||
|
# we can't statically check this. Might as well rely on duck
|
||||||
|
# typing while we're at it: just try to yield postings from
|
||||||
|
# everything, and ignore entries that lack a postings attribute.
|
||||||
|
try:
|
||||||
|
yield from cls.from_txn(entry) # type:ignore[arg-type]
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def balance_of(txn: Transaction,
|
def balance_of(txn: Transaction,
|
||||||
*preds: Callable[[Account], Optional[bool]],
|
*preds: Callable[[Account], Optional[bool]],
|
||||||
|
|
|
@ -18,6 +18,8 @@ import pytest
|
||||||
|
|
||||||
from . import testutil
|
from . import testutil
|
||||||
|
|
||||||
|
from beancount.core import data as bc_data
|
||||||
|
|
||||||
from conservancy_beancount import data
|
from conservancy_beancount import data
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
@ -57,3 +59,26 @@ def test_from_txn(simple_txn):
|
||||||
assert all(source[x] == post[x] for x in range(len(source) - 1))
|
assert all(source[x] == post[x] for x in range(len(source) - 1))
|
||||||
assert isinstance(post.account, data.Account)
|
assert isinstance(post.account, data.Account)
|
||||||
assert post.meta['note'] # Only works with PostingMeta
|
assert post.meta['note'] # Only works with PostingMeta
|
||||||
|
|
||||||
|
def test_from_entries_two_txns(simple_txn):
|
||||||
|
entries = [simple_txn, simple_txn]
|
||||||
|
sources = [post for txn in entries for post in txn.postings]
|
||||||
|
for source, post in zip(sources, data.Posting.from_entries(entries)):
|
||||||
|
assert all(source[x] == post[x] for x in range(len(source) - 1))
|
||||||
|
assert isinstance(post.account, data.Account)
|
||||||
|
assert post.meta['note'] # Only works with PostingMeta
|
||||||
|
|
||||||
|
def test_from_entries_mix_txns_and_other_directives(simple_txn):
|
||||||
|
meta = {
|
||||||
|
'filename': __file__,
|
||||||
|
'lineno': 75,
|
||||||
|
}
|
||||||
|
entries = [
|
||||||
|
bc_data.Commodity(meta, testutil.FY_START_DATE, 'EUR'),
|
||||||
|
bc_data.Commodity(meta, testutil.FY_START_DATE, 'USD'),
|
||||||
|
simple_txn,
|
||||||
|
]
|
||||||
|
for source, post in zip(simple_txn.postings, data.Posting.from_entries(entries)):
|
||||||
|
assert all(source[x] == post[x] for x in range(len(source) - 1))
|
||||||
|
assert isinstance(post.account, data.Account)
|
||||||
|
assert post.meta['note'] # Only works with PostingMeta
|
||||||
|
|
Loading…
Reference in a new issue