data: Add Metadata.human_name() classmethod.
This commit is contained in:
parent
9a7b9de08d
commit
71d671e493
3 changed files with 50 additions and 12 deletions
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue