reports: Add RelatedPostings.first_meta_links() method.
Basically moving this from AccrualPostings into the superclass.
This commit is contained in:
		
							parent
							
								
									1cbc9d3dc9
								
							
						
					
					
						commit
						f52ad4fbc1
					
				
					 3 changed files with 33 additions and 5 deletions
				
			
		| 
						 | 
					@ -193,7 +193,7 @@ class AccrualPostings(core.RelatedPostings):
 | 
				
			||||||
            norm_func = self.accrual_type.normalize_amount
 | 
					            norm_func = self.accrual_type.normalize_amount
 | 
				
			||||||
            entity_pred = lambda post: norm_func(post.units).number > 0
 | 
					            entity_pred = lambda post: norm_func(post.units).number > 0
 | 
				
			||||||
        self.entity = self._single_item(self.entities(entity_pred))
 | 
					        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())
 | 
					        self.end_balance = norm_func(self.balance_at_cost())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _single_item(self, seq: Iterable[T]) -> Union[T, Sentinel]:
 | 
					    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
 | 
					            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']]:
 | 
					    def make_consistent(self) -> Iterator[Tuple[MetaValue, 'AccrualPostings']]:
 | 
				
			||||||
        account_ok = isinstance(self.account, str)
 | 
					        account_ok = isinstance(self.account, str)
 | 
				
			||||||
        entity_ok = isinstance(self.entity, str)
 | 
					        entity_ok = isinstance(self.entity, str)
 | 
				
			||||||
| 
						 | 
					@ -506,7 +503,7 @@ class OutgoingReport(BaseReport):
 | 
				
			||||||
        self.rt_wrapper = rtutil.RT(rt_client)
 | 
					        self.rt_wrapper = rtutil.RT(rt_client)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _primary_rt_id(self, posts: AccrualPostings) -> rtutil.TicketAttachmentIds:
 | 
					    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)
 | 
					        rt_ids_count = len(rt_ids)
 | 
				
			||||||
        if rt_ids_count != 1:
 | 
					        if rt_ids_count != 1:
 | 
				
			||||||
            raise ValueError(f"{rt_ids_count} rt-id links found")
 | 
					            raise ValueError(f"{rt_ids_count} rt-id links found")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -304,6 +304,23 @@ class RelatedPostings(Sequence[data.Posting]):
 | 
				
			||||||
    def all_meta_links(self, key: MetaKey) -> Iterator[str]:
 | 
					    def all_meta_links(self, key: MetaKey) -> Iterator[str]:
 | 
				
			||||||
        return filters.iter_unique(self._all_meta_links(key))
 | 
					        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]]:
 | 
					    def iter_with_balance(self) -> Iterator[Tuple[data.Posting, Balance]]:
 | 
				
			||||||
        balance = MutableBalance()
 | 
					        balance = MutableBalance()
 | 
				
			||||||
        for post in self:
 | 
					        for post in self:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -275,6 +275,20 @@ def test_all_meta_links_preserves_order():
 | 
				
			||||||
    ) for c in '121323')
 | 
					    ) for c in '121323')
 | 
				
			||||||
    assert list(related.all_meta_links('approval')) == list('123')
 | 
					    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():
 | 
					def test_group_by_meta_zero():
 | 
				
			||||||
    assert not list(core.RelatedPostings.group_by_meta([], 'metacurrency'))
 | 
					    assert not list(core.RelatedPostings.group_by_meta([], 'metacurrency'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue