reports: Add RelatedPostings.first_meta_links() method.

Basically moving this from AccrualPostings into the superclass.
This commit is contained in:
Brett Smith 2020-06-11 12:59:10 -04:00
parent 1cbc9d3dc9
commit f52ad4fbc1
3 changed files with 33 additions and 5 deletions

View file

@ -193,7 +193,7 @@ class AccrualPostings(core.RelatedPostings):
norm_func = self.accrual_type.normalize_amount
entity_pred = lambda post: norm_func(post.units).number > 0
self.entity = self._single_item(self.entities(entity_pred))
self.invoice = self._single_item(self.first_links('invoice'))
self.invoice = self._single_item(self.first_meta_links('invoice', None))
self.end_balance = norm_func(self.balance_at_cost())
def _single_item(self, seq: Iterable[T]) -> Union[T, Sentinel]:
@ -213,9 +213,6 @@ class AccrualPostings(core.RelatedPostings):
if pred(post) and 'entity' in post.meta
)
def first_links(self, key: MetaKey, default: Optional[str]=None) -> Iterator[Optional[str]]:
return (post.meta.first_link(key, default) for post in self)
def make_consistent(self) -> Iterator[Tuple[MetaValue, 'AccrualPostings']]:
account_ok = isinstance(self.account, str)
entity_ok = isinstance(self.entity, str)
@ -506,7 +503,7 @@ class OutgoingReport(BaseReport):
self.rt_wrapper = rtutil.RT(rt_client)
def _primary_rt_id(self, posts: AccrualPostings) -> rtutil.TicketAttachmentIds:
rt_ids = {url for url in posts.first_links('rt-id') if url is not None}
rt_ids = list(posts.first_meta_links('rt-id'))
rt_ids_count = len(rt_ids)
if rt_ids_count != 1:
raise ValueError(f"{rt_ids_count} rt-id links found")

View file

@ -304,6 +304,23 @@ class RelatedPostings(Sequence[data.Posting]):
def all_meta_links(self, key: MetaKey) -> Iterator[str]:
return filters.iter_unique(self._all_meta_links(key))
@overload
def first_meta_links(self, key: MetaKey, default: str='') -> Iterator[str]: ...
@overload
def first_meta_links(self, key: MetaKey, default: None) -> Iterator[Optional[str]]: ...
def first_meta_links(self,
key: MetaKey,
default: Optional[str]='',
) -> Iterator[Optional[str]]:
retval = filters.iter_unique(
post.meta.first_link(key, default) for post in self
)
if default == '':
retval = (s for s in retval if s)
return retval
def iter_with_balance(self) -> Iterator[Tuple[data.Posting, Balance]]:
balance = MutableBalance()
for post in self:

View file

@ -275,6 +275,20 @@ def test_all_meta_links_preserves_order():
) for c in '121323')
assert list(related.all_meta_links('approval')) == list('123')
def test_first_meta_links():
related = core.RelatedPostings(testutil.Posting(
'Assets:Cash', 10, contract=value, _meta_type=data.Metadata,
) for value in ['1 2', '', '1 3', testutil.PAST_DATE, '2 3', None])
del related[-1].meta['contract']
assert list(related.first_meta_links('contract')) == list('12')
def test_first_meta_links_fallback():
related = core.RelatedPostings(testutil.Posting(
'Assets:Cash', 10, contract=value, _meta_type=data.Metadata,
) for value in ['1 2', testutil.PAST_DATE, '1 3', None, '2 3'])
del related[-2].meta['contract']
assert list(related.first_meta_links('contract', None)) == ['1', None, '2']
def test_group_by_meta_zero():
assert not list(core.RelatedPostings.group_by_meta([], 'metacurrency'))