accrual: Clean up types and imports.

Mostly I wanted to write the documentation about groups, and then
I kept pulling the thread.
This commit is contained in:
Brett Smith 2020-06-12 13:24:25 -04:00
parent 3330c834b2
commit 5706273bbe

View file

@ -70,7 +70,6 @@ import collections
import datetime import datetime
import enum import enum
import logging import logging
import re
import sys import sys
import urllib.parse as urlparse import urllib.parse as urlparse
@ -119,9 +118,7 @@ from .. import rtutil
PROGNAME = 'accrual-report' PROGNAME = 'accrual-report'
CompoundAmount = TypeVar('CompoundAmount', data.Amount, core.Balance) PostGroups = Mapping[Optional[str], 'AccrualPostings']
PostGroups = Mapping[Optional[MetaValue], 'AccrualPostings']
RTObject = Mapping[str, str]
T = TypeVar('T') T = TypeVar('T')
logger = logging.getLogger('conservancy_beancount.reports.accrual') logger = logging.getLogger('conservancy_beancount.reports.accrual')
@ -213,7 +210,7 @@ class AccrualPostings(core.RelatedPostings):
if pred(post) and 'entity' in post.meta if pred(post) and 'entity' in post.meta
) )
def make_consistent(self) -> Iterator[Tuple[MetaValue, 'AccrualPostings']]: def make_consistent(self) -> Iterator[Tuple[str, '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)
# `'/' in self.invoice` is just our heuristic to ensure that the # `'/' in self.invoice` is just our heuristic to ensure that the
@ -221,7 +218,10 @@ class AccrualPostings(core.RelatedPostings):
# value like "FIXME". It can be refined if needed. # value like "FIXME". It can be refined if needed.
invoice_ok = isinstance(self.invoice, str) and '/' in self.invoice invoice_ok = isinstance(self.invoice, str) and '/' in self.invoice
if account_ok and entity_ok and invoice_ok: if account_ok and entity_ok and invoice_ok:
yield (self.invoice, self) # mypy loses track of the fact that self.invoice must be a str in
# this case (gated on the invoice_ok boolean) and complains it
# doesn't match the type of the return value.
yield (self.invoice, self) # type:ignore[misc]
return return
groups = collections.defaultdict(list) groups = collections.defaultdict(list)
for post in self: for post in self:
@ -696,6 +696,14 @@ def main(arglist: Optional[Sequence[str]]=None,
if not postings: if not postings:
logger.warning("no matching entries found to report") logger.warning("no matching entries found to report")
returncode |= ReturnFlag.NOTHING_TO_REPORT returncode |= ReturnFlag.NOTHING_TO_REPORT
# groups is a mapping of metadata value strings to AccrualPostings.
# The keys are basically arbitrary, the report classes don't rely on them,
# but they do help symbolize what's being grouped.
# For the outgoing approval report, groups maps rt-id link strings to
# associated accruals.
# For all other reports, groups starts by grouping postings together by
# invoice link string, then uses AccrualReport.make_consistent() to split
# out groups that need it.
groups: PostGroups groups: PostGroups
if args.report_type is None or args.report_type is ReportType.OUTGOING: if args.report_type is None or args.report_type is ReportType.OUTGOING:
groups = dict(AccrualPostings.group_by_first_meta_link(postings, 'rt-id')) groups = dict(AccrualPostings.group_by_first_meta_link(postings, 'rt-id'))