Changeset - 8333ed887646
[Not reviewed]
0 2 0
Brett Smith - 4 years ago 2020-06-15 15:20:30
brettcsmith@brettcsmith.org
reports: Add RelatedPostings.group_by_account() classmethod.
2 files changed with 24 insertions and 0 deletions:
0 comments (0 inline, 0 general)
conservancy_beancount/reports/core.py
Show inline comments
...
 
@@ -265,24 +265,30 @@ class RelatedPostings(Sequence[data.Posting]):
 

	
 
    @classmethod
 
    def _group_by(cls: Type[RelatedType],
 
                  postings: Iterable[data.Posting],
 
                  key: Callable[[data.Posting], T],
 
    ) -> Iterator[Tuple[T, RelatedType]]:
 
        mapping: Dict[T, List[data.Posting]] = collections.defaultdict(list)
 
        for post in postings:
 
            mapping[key(post)].append(post)
 
        for value, posts in mapping.items():
 
            yield value, cls(posts, _can_own=True)
 

	
 
    @classmethod
 
    def group_by_account(cls: Type[RelatedType],
 
                         postings: Iterable[data.Posting],
 
    ) -> Iterator[Tuple[data.Account, RelatedType]]:
 
        return cls._group_by(postings, operator.attrgetter('account'))
 

	
 
    @classmethod
 
    def group_by_meta(cls: Type[RelatedType],
 
                      postings: Iterable[data.Posting],
 
                      key: MetaKey,
 
                      default: Optional[MetaValue]=None,
 
    ) -> Iterator[Tuple[Optional[MetaValue], RelatedType]]:
 
        """Relate postings by metadata value
 

	
 
        This method takes an iterable of postings and returns a mapping.
 
        The keys of the mapping are the values of post.meta.get(key, default).
 
        The values are RelatedPostings instances that contain all the postings
 
        that had that same metadata value.
tests/test_reports_related_postings.py
Show inline comments
...
 
@@ -389,12 +389,30 @@ def test_group_by_first_meta_link_bad_type(link_swap_posts):
 
def test_group_by_first_meta_link(link_swap_posts):
 
    actual_all = dict(core.RelatedPostings.group_by_first_meta_link(
 
        iter(link_swap_posts), 'rt-id',
 
    ))
 
    assert len(actual_all) == 2
 
    for key, expect_account in [
 
            ('rt:12', 'Assets:Receivable:Accounts'),
 
            ('rt:16', 'Liabilities:Payable:Accounts'),
 
    ]:
 
        actual = actual_all.get(key, '')
 
        assert len(actual) == 2
 
        assert all(post.account == expect_account for post in actual)
 

	
 
def test_group_by_account():
 
    entries = [
 
        testutil.Transaction(postings=[
 
            ('Income:Donations', -10),
 
            ('Assets:Cash', 10),
 
        ]),
 
        testutil.Transaction(postings=[
 
            ('Income:Donations', -20),
 
            ('Assets:Cash', 20),
 
        ]),
 
    ]
 
    postings = data.Posting.from_entries(entries)
 
    actual = dict(core.RelatedPostings.group_by_account(postings))
 
    assert len(actual) == 2
 
    for key, related in actual.items():
 
        assert len(related) == 2
 
        assert all(post.account == key for post in related)
0 comments (0 inline, 0 general)