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 datetime
|
||||||
import decimal
|
import decimal
|
||||||
import functools
|
import functools
|
||||||
|
import re
|
||||||
|
|
||||||
from beancount.core import account as bc_account
|
from beancount.core import account as bc_account
|
||||||
from beancount.core import amount as bc_amount
|
from beancount.core import amount as bc_amount
|
||||||
|
@ -213,6 +214,13 @@ class Metadata(MutableMapping[MetaKey, MetaValue]):
|
||||||
for common parsing and query tasks.
|
for common parsing and query tasks.
|
||||||
"""
|
"""
|
||||||
__slots__ = ('meta',)
|
__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:
|
def __init__(self, source: MutableMapping[MetaKey, MetaValue]) -> None:
|
||||||
self.meta = source
|
self.meta = source
|
||||||
|
@ -256,6 +264,22 @@ class Metadata(MutableMapping[MetaKey, MetaValue]):
|
||||||
except (IndexError, TypeError):
|
except (IndexError, TypeError):
|
||||||
return default
|
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):
|
class PostingMeta(Metadata):
|
||||||
"""Combined access to posting metadata with its parent transaction 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]]):
|
class AgingODS(core.BaseODS[AccrualPostings, Optional[data.Account]]):
|
||||||
|
DOC_COLUMNS = [
|
||||||
|
'rt-id',
|
||||||
|
'invoice',
|
||||||
|
'approval',
|
||||||
|
'contract',
|
||||||
|
'purchase-order',
|
||||||
|
]
|
||||||
COLUMNS = [
|
COLUMNS = [
|
||||||
'Date',
|
'Date',
|
||||||
'Entity',
|
data.Metadata.human_name('entity'),
|
||||||
'Invoice Amount',
|
'Invoice Amount',
|
||||||
'Booked Amount',
|
'Booked Amount',
|
||||||
'Project',
|
data.Metadata.human_name('project'),
|
||||||
'Ticket',
|
*(data.Metadata.human_name(key) for key in DOC_COLUMNS),
|
||||||
'Invoice',
|
|
||||||
'Approval',
|
|
||||||
'Contract',
|
|
||||||
'Purchase Order',
|
|
||||||
]
|
]
|
||||||
COL_COUNT = len(COLUMNS)
|
COL_COUNT = len(COLUMNS)
|
||||||
|
|
||||||
|
@ -410,11 +413,8 @@ class AgingODS(core.BaseODS[AccrualPostings, Optional[data.Account]]):
|
||||||
amount_cell,
|
amount_cell,
|
||||||
self.balance_cell(row.end_balance),
|
self.balance_cell(row.end_balance),
|
||||||
self.multiline_cell(sorted(projects)),
|
self.multiline_cell(sorted(projects)),
|
||||||
self.meta_links_cell(row.all_meta_links('rt-id')),
|
*(self.meta_links_cell(row.all_meta_links(key))
|
||||||
self.meta_links_cell(row.all_meta_links('invoice')),
|
for key in self.DOC_COLUMNS),
|
||||||
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')),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -89,3 +89,17 @@ def test_first_link_bad_type_default(simple_txn, meta_value):
|
||||||
simple_txn.meta['badmeta'] = meta_value
|
simple_txn.meta['badmeta'] = meta_value
|
||||||
meta = data.PostingMeta(simple_txn, 1)
|
meta = data.PostingMeta(simple_txn, 1)
|
||||||
assert meta.first_link('badmeta', '_') == '_'
|
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