diff --git a/conservancy_beancount/reports/core.py b/conservancy_beancount/reports/core.py index d2cc864..48ba9c4 100644 --- a/conservancy_beancount/reports/core.py +++ b/conservancy_beancount/reports/core.py @@ -274,6 +274,12 @@ class RelatedPostings(Sequence[data.Posting]): 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], diff --git a/tests/test_reports_related_postings.py b/tests/test_reports_related_postings.py index 49f0534..bb4cdad 100644 --- a/tests/test_reports_related_postings.py +++ b/tests/test_reports_related_postings.py @@ -398,3 +398,21 @@ def test_group_by_first_meta_link(link_swap_posts): 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)