reports.accrual: Outgoing report uses payment-to custom field. RT#10656.

This commit is contained in:
Brett Smith 2020-05-16 11:31:00 -04:00
parent 3c77f8b3c7
commit 55de5627f2
3 changed files with 35 additions and 8 deletions

View file

@ -218,10 +218,10 @@ def outgoing_report(groups: PostGroups,
rt_requestor = None rt_requestor = None
if rt_requestor is None: if rt_requestor is None:
requestor = '' requestor = ''
payee = '' requestor_name = ''
else: else:
requestor = '{RealName} <{EmailAddress}>'.format_map(rt_requestor) requestor = '{RealName} <{EmailAddress}>'.format_map(rt_requestor)
payee = rt_requestor['RealName'] requestor_name = rt_requestor['RealName']
contract_links = related.all_meta_links('contract') contract_links = related.all_meta_links('contract')
if contract_links: if contract_links:
@ -232,15 +232,14 @@ def outgoing_report(groups: PostGroups,
contract_s = "NO CONTRACT GOVERNS THIS TRANSACTION" contract_s = "NO CONTRACT GOVERNS THIS TRANSACTION"
projects = [v for v in related.meta_values('project') projects = [v for v in related.meta_values('project')
if isinstance(v, str)] if isinstance(v, str)]
payment_method = ticket.get('CF.{payment-method}', '')
print( print(
"PAYMENT FOR APPROVAL:", "PAYMENT FOR APPROVAL:",
f"REQUESTOR: {requestor}", f"REQUESTOR: {requestor}",
f"TOTAL TO PAY: {-related.balance()}", f"TOTAL TO PAY: {-related.balance()}",
f"AGREEMENT: {contract_s}", f"AGREEMENT: {contract_s}",
f"PAYMENT TO: {payee}", f"PAYMENT TO: {ticket.get('CF.{payment-to}', requestor_name)}",
f"PAYMENT METHOD: {payment_method}", f"PAYMENT METHOD: {ticket.get('CF.{payment-method}', '')}",
f"PROJECT: {', '.join(projects)}", f"PROJECT: {', '.join(projects)}",
"\nBEANCOUNT ENTRIES:", "\nBEANCOUNT ENTRIES:",
sep='\n', file=out_file, sep='\n', file=out_file,

View file

@ -312,7 +312,7 @@ def test_outgoing_report(accrual_postings):
r'^REQUESTOR: Mx\. 510 <mx510@example\.org>$', r'^REQUESTOR: Mx\. 510 <mx510@example\.org>$',
r'^TOTAL TO PAY: 280\.00 USD$', r'^TOTAL TO PAY: 280\.00 USD$',
fr'^AGREEMENT: {contract_url}', fr'^AGREEMENT: {contract_url}',
r'^PAYMENT TO: Mx\. 510$', r'^PAYMENT TO: Hon\. Mx\. 510$',
r'^PAYMENT METHOD: payment method 510$', r'^PAYMENT METHOD: payment method 510$',
r'^BEANCOUNT ENTRIES:$', r'^BEANCOUNT ENTRIES:$',
# For each transaction, check for the date line, a metadata, and the # For each transaction, check for the date line, a metadata, and the
@ -325,6 +325,29 @@ def test_outgoing_report(accrual_postings):
r'^\s+Expenses:FilingFees\s+60\.00 USD$', r'^\s+Expenses:FilingFees\s+60\.00 USD$',
]) ])
def test_outgoing_report_custom_field_fallbacks(accrual_postings):
invoice = 'rt:510/6100'
related = core.RelatedPostings(
post for post in accrual_postings
if post.meta.get('invoice') == invoice
and post.account.is_under('Assets:Receivable', 'Liabilities:Payable')
)
output = io.StringIO()
errors = io.StringIO()
rt_client = RTClient(want_cfs=False)
rt_cache = rtutil.RT(rt_client)
accrual.outgoing_report({invoice: related}, output, errors, rt_client, rt_cache)
assert not errors.getvalue()
rt_url = rt_client.DEFAULT_URL[:-9]
rt_id_url = re.escape(f'<{rt_url}Ticket/Display.html?id=510>')
contract_url = re.escape(f'<{rt_url}Ticket/Attachment/4000/4000/contract.pdf>')
check_output(output, [
r'^PAYMENT FOR APPROVAL:$',
r'^REQUESTOR: Mx\. 510 <mx510@example\.org>$',
r'^PAYMENT TO: Mx\. 510$',
r'^PAYMENT METHOD:\s*$',
])
def run_main(arglist, config): def run_main(arglist, config):
output = io.StringIO() output = io.StringIO()
errors = io.StringIO() errors = io.StringIO()

View file

@ -281,6 +281,7 @@ class RTClient:
skip_login=False, skip_login=False,
verify_cert=True, verify_cert=True,
http_auth=None, http_auth=None,
want_cfs=True,
): ):
self.url = url self.url = url
if http_auth is None: if http_auth is None:
@ -294,6 +295,7 @@ class RTClient:
self.auth_method = type(http_auth).__name__ self.auth_method = type(http_auth).__name__
self.login_result = True self.login_result = True
self.last_login = None self.last_login = None
self.want_cfs = want_cfs
def login(self, login=None, password=None): def login(self, login=None, password=None):
if login is None and password is None: if login is None and password is None:
@ -339,15 +341,18 @@ class RTClient:
ticket_id_s = str(ticket_id) ticket_id_s = str(ticket_id)
if ticket_id_s not in self.TICKET_DATA: if ticket_id_s not in self.TICKET_DATA:
return None return None
return { retval = {
'id': 'ticket/{}'.format(ticket_id_s), 'id': 'ticket/{}'.format(ticket_id_s),
'numerical_id': ticket_id_s, 'numerical_id': ticket_id_s,
'CF.{payment-method}': f'payment method {ticket_id_s}',
'Requestors': [ 'Requestors': [
f'mx{ticket_id_s}@example.org', f'mx{ticket_id_s}@example.org',
'requestor2@example.org', 'requestor2@example.org',
], ],
} }
if self.want_cfs:
retval['CF.{payment-method}'] = f'payment method {ticket_id_s}'
retval['CF.{payment-to}'] = f'Hon. Mx. {ticket_id_s}'
return retval
def get_user(self, user_id): def get_user(self, user_id):
user_id_s = str(user_id) user_id_s = str(user_id)