data: Add Metadata.human_name() classmethod.

This commit is contained in:
Brett Smith 2020-06-14 06:21:30 -04:00
parent 9a7b9de08d
commit 71d671e493
3 changed files with 50 additions and 12 deletions

View file

@ -23,6 +23,7 @@ import collections
import datetime
import decimal
import functools
import re
from beancount.core import account as bc_account
from beancount.core import amount as bc_amount
@ -213,6 +214,13 @@ class Metadata(MutableMapping[MetaKey, MetaValue]):
for common parsing and query tasks.
"""
__slots__ = ('meta',)
_HUMAN_NAMES: MutableMapping[MetaKey, str] = {
# Initialize this dict with special cases.
# We use it as a cache for other metadata names as they're queried.
'check-id': 'Check Number',
'paypal-id': 'PayPal ID',
'rt-id': 'Ticket',
}
def __init__(self, source: MutableMapping[MetaKey, MetaValue]) -> None:
self.meta = source
@ -256,6 +264,22 @@ class Metadata(MutableMapping[MetaKey, MetaValue]):
except (IndexError, TypeError):
return default
@classmethod
def human_name(cls, key: MetaKey) -> str:
"""Return the "human" version of a metadata name
This is usually the metadata key with punctuation replaced with spaces,
and then titlecased, with a few special cases. The return value is
suitable for using in reports.
"""
try:
retval = cls._HUMAN_NAMES[key]
except KeyError:
retval = key.replace('-', ' ').title()
retval = re.sub(r'\bId$', 'ID', retval)
cls._HUMAN_NAMES[key] = retval
return retval
class PostingMeta(Metadata):
"""Combined access to posting metadata with its parent transaction metadata

View file

@ -273,17 +273,20 @@ class BaseReport:
class AgingODS(core.BaseODS[AccrualPostings, Optional[data.Account]]):
DOC_COLUMNS = [
'rt-id',
'invoice',
'approval',
'contract',
'purchase-order',
]
COLUMNS = [
'Date',
'Entity',
data.Metadata.human_name('entity'),
'Invoice Amount',
'Booked Amount',
'Project',
'Ticket',
'Invoice',
'Approval',
'Contract',
'Purchase Order',
data.Metadata.human_name('project'),
*(data.Metadata.human_name(key) for key in DOC_COLUMNS),
]
COL_COUNT = len(COLUMNS)
@ -410,11 +413,8 @@ class AgingODS(core.BaseODS[AccrualPostings, Optional[data.Account]]):
amount_cell,
self.balance_cell(row.end_balance),
self.multiline_cell(sorted(projects)),
self.meta_links_cell(row.all_meta_links('rt-id')),
self.meta_links_cell(row.all_meta_links('invoice')),
self.meta_links_cell(row.all_meta_links('approval')),
self.meta_links_cell(row.all_meta_links('contract')),
self.meta_links_cell(row.all_meta_links('purchase-order')),
*(self.meta_links_cell(row.all_meta_links(key))
for key in self.DOC_COLUMNS),
)

View file

@ -89,3 +89,17 @@ def test_first_link_bad_type_default(simple_txn, meta_value):
simple_txn.meta['badmeta'] = meta_value
meta = data.PostingMeta(simple_txn, 1)
assert meta.first_link('badmeta', '_') == '_'
@pytest.mark.parametrize('meta_name,expected', [
('approval', 'Approval'),
('bank-id', 'Bank ID'),
('bank-statement', 'Bank Statement'),
('check-id', 'Check Number'),
('paypal-id', 'PayPal ID'),
('purchase-order', 'Purchase Order'),
('receipt', 'Receipt'),
('rt-id', 'Ticket'),
('tax-statement', 'Tax Statement'),
])
def test_human_name(meta_name, expected):
assert data.Metadata.human_name(meta_name) == expected