accrual: Outgoing report includes total at cost.
This commit is contained in:
parent
d8df34ebaf
commit
f66460f343
4 changed files with 39 additions and 4 deletions
|
@ -296,6 +296,14 @@ def outgoing_report(groups: PostGroups,
|
||||||
)
|
)
|
||||||
requestor = f'{requestor_name} <{rt_requestor["EmailAddress"]}>'.strip()
|
requestor = f'{requestor_name} <{rt_requestor["EmailAddress"]}>'.strip()
|
||||||
|
|
||||||
|
raw_balance = -related.balance()
|
||||||
|
cost_balance = -related.balance_at_cost()
|
||||||
|
cost_balance_s = cost_balance.format(None)
|
||||||
|
if raw_balance == cost_balance:
|
||||||
|
balance_s = cost_balance_s
|
||||||
|
else:
|
||||||
|
balance_s = f'{raw_balance} ({cost_balance_s})'
|
||||||
|
|
||||||
contract_links = related.all_meta_links('contract')
|
contract_links = related.all_meta_links('contract')
|
||||||
if contract_links:
|
if contract_links:
|
||||||
contract_s = ' , '.join(rt_wrapper.iter_urls(
|
contract_s = ' , '.join(rt_wrapper.iter_urls(
|
||||||
|
@ -309,7 +317,7 @@ def outgoing_report(groups: PostGroups,
|
||||||
print(
|
print(
|
||||||
"PAYMENT FOR APPROVAL:",
|
"PAYMENT FOR APPROVAL:",
|
||||||
f"REQUESTOR: {requestor}",
|
f"REQUESTOR: {requestor}",
|
||||||
f"TOTAL TO PAY: {-related.balance()}",
|
f"TOTAL TO PAY: {balance_s}",
|
||||||
f"AGREEMENT: {contract_s}",
|
f"AGREEMENT: {contract_s}",
|
||||||
f"PAYMENT TO: {ticket.get('CF.{payment-to}') or requestor_name}",
|
f"PAYMENT TO: {ticket.get('CF.{payment-to}') or requestor_name}",
|
||||||
f"PAYMENT METHOD: {ticket.get('CF.{payment-method}', '')}",
|
f"PAYMENT METHOD: {ticket.get('CF.{payment-method}', '')}",
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -5,7 +5,7 @@ from setuptools import setup
|
||||||
setup(
|
setup(
|
||||||
name='conservancy_beancount',
|
name='conservancy_beancount',
|
||||||
description="Plugin, library, and reports for reading Conservancy's books",
|
description="Plugin, library, and reports for reading Conservancy's books",
|
||||||
version='1.0.6',
|
version='1.0.7',
|
||||||
author='Software Freedom Conservancy',
|
author='Software Freedom Conservancy',
|
||||||
author_email='info@sfconservancy.org',
|
author_email='info@sfconservancy.org',
|
||||||
license='GNU AGPLv3+',
|
license='GNU AGPLv3+',
|
||||||
|
|
|
@ -73,3 +73,10 @@
|
||||||
contract: "rt:510/4000"
|
contract: "rt:510/4000"
|
||||||
Expenses:FilingFees 60.00 USD
|
Expenses:FilingFees 60.00 USD
|
||||||
Liabilities:Payable:Accounts -60.00 USD
|
Liabilities:Payable:Accounts -60.00 USD
|
||||||
|
|
||||||
|
2020-06-18 * "EuroGov" "European legal fees"
|
||||||
|
rt-id: "rt:520"
|
||||||
|
invoice: "rt:520/5200"
|
||||||
|
contract: "rt:520/5220"
|
||||||
|
Liabilities:Payable:Accounts -1,000 EUR {1.100 USD}
|
||||||
|
Expenses:FilingFees 1,000 EUR {1.100 USD}
|
||||||
|
|
|
@ -68,6 +68,7 @@ class RTClient(testutil.RTClient):
|
||||||
('6100', 'invoice may.pdf', 'application/pdf', '1.6m'),
|
('6100', 'invoice may.pdf', 'application/pdf', '1.6m'),
|
||||||
],
|
],
|
||||||
'515': [],
|
'515': [],
|
||||||
|
'520': [],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -281,7 +282,7 @@ def test_outgoing_report(accrual_postings):
|
||||||
check_output(output, [
|
check_output(output, [
|
||||||
r'^PAYMENT FOR APPROVAL:$',
|
r'^PAYMENT FOR APPROVAL:$',
|
||||||
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$',
|
||||||
fr'^AGREEMENT: {contract_url}',
|
fr'^AGREEMENT: {contract_url}',
|
||||||
r'^PAYMENT TO: Hon\. Mx\. 510$',
|
r'^PAYMENT TO: Hon\. Mx\. 510$',
|
||||||
r'^PAYMENT METHOD: payment method 510$',
|
r'^PAYMENT METHOD: payment method 510$',
|
||||||
|
@ -316,6 +317,25 @@ def test_outgoing_report_custom_field_fallbacks(accrual_postings):
|
||||||
r'^PAYMENT METHOD:\s*$',
|
r'^PAYMENT METHOD:\s*$',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
def test_outgoing_report_fx_amounts(accrual_postings):
|
||||||
|
invoice = 'rt:520/5200'
|
||||||
|
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()
|
||||||
|
rt_cache = rtutil.RT(rt_client)
|
||||||
|
accrual.outgoing_report({invoice: related}, output, errors, rt_client, rt_cache)
|
||||||
|
assert not errors.getvalue()
|
||||||
|
check_output(output, [
|
||||||
|
r'^PAYMENT FOR APPROVAL:$',
|
||||||
|
r'^REQUESTOR: Mx\. 520 <mx520@example\.org>$',
|
||||||
|
r'^TOTAL TO PAY: 1,000\.00 EUR \(\$1,100.00\)$',
|
||||||
|
])
|
||||||
|
|
||||||
def run_main(arglist, config=None):
|
def run_main(arglist, config=None):
|
||||||
if config is None:
|
if config is None:
|
||||||
config = testutil.TestConfig(
|
config = testutil.TestConfig(
|
||||||
|
@ -375,7 +395,7 @@ def test_main_outgoing_report(arglist):
|
||||||
contract_url = re.escape(f'<{rt_url}Ticket/Attachment/4000/4000/contract.pdf>')
|
contract_url = re.escape(f'<{rt_url}Ticket/Attachment/4000/4000/contract.pdf>')
|
||||||
check_output(output, [
|
check_output(output, [
|
||||||
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$',
|
||||||
r'^\s*2020-06-12\s',
|
r'^\s*2020-06-12\s',
|
||||||
r'^\s+Expenses:FilingFees\s+60\.00 USD$',
|
r'^\s+Expenses:FilingFees\s+60\.00 USD$',
|
||||||
])
|
])
|
||||||
|
|
Loading…
Reference in a new issue