diff --git a/conservancy_beancount/reports/accrual.py b/conservancy_beancount/reports/accrual.py index 3d1fbd1a4ed6d47c99100db575ee52fcc96a310a..155cc12b2c4b5380842e8b43d7eb28b8cde8bc73 100644 --- a/conservancy_beancount/reports/accrual.py +++ b/conservancy_beancount/reports/accrual.py @@ -296,6 +296,14 @@ def outgoing_report(groups: PostGroups, ) 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') if contract_links: contract_s = ' , '.join(rt_wrapper.iter_urls( @@ -309,7 +317,7 @@ def outgoing_report(groups: PostGroups, print( "PAYMENT FOR APPROVAL:", f"REQUESTOR: {requestor}", - f"TOTAL TO PAY: {-related.balance()}", + f"TOTAL TO PAY: {balance_s}", f"AGREEMENT: {contract_s}", f"PAYMENT TO: {ticket.get('CF.{payment-to}') or requestor_name}", f"PAYMENT METHOD: {ticket.get('CF.{payment-method}', '')}", diff --git a/setup.py b/setup.py index f7a92f163dc01c5199c97e0d9afd93d3ef1330d0..40b8b8f28eacc9a2fbb91f6c81da38554f2d9a6f 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ from setuptools import setup setup( name='conservancy_beancount', description="Plugin, library, and reports for reading Conservancy's books", - version='1.0.6', + version='1.0.7', author='Software Freedom Conservancy', author_email='info@sfconservancy.org', license='GNU AGPLv3+', diff --git a/tests/books/accruals.beancount b/tests/books/accruals.beancount index 58b5284a1ed52218153ae6f4b0b4968edf251b64..01f8ee2d573e86d62886147f6ea42fa264a83115 100644 --- a/tests/books/accruals.beancount +++ b/tests/books/accruals.beancount @@ -73,3 +73,10 @@ contract: "rt:510/4000" Expenses:FilingFees 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} diff --git a/tests/test_reports_accrual.py b/tests/test_reports_accrual.py index 5356285a09b2e71aa0b7d148fa79032bd2604a70..f0f2e7358e755e2a0eebbd133d7b6692b9396f79 100644 --- a/tests/test_reports_accrual.py +++ b/tests/test_reports_accrual.py @@ -68,6 +68,7 @@ class RTClient(testutil.RTClient): ('6100', 'invoice may.pdf', 'application/pdf', '1.6m'), ], '515': [], + '520': [], } @@ -281,7 +282,7 @@ def test_outgoing_report(accrual_postings): check_output(output, [ r'^PAYMENT FOR APPROVAL:$', r'^REQUESTOR: Mx\. 510 $', - r'^TOTAL TO PAY: 280\.00 USD$', + r'^TOTAL TO PAY: \$280\.00$', fr'^AGREEMENT: {contract_url}', r'^PAYMENT TO: Hon\. Mx\. 510$', r'^PAYMENT METHOD: payment method 510$', @@ -316,6 +317,25 @@ def test_outgoing_report_custom_field_fallbacks(accrual_postings): 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 $', + r'^TOTAL TO PAY: 1,000\.00 EUR \(\$1,100.00\)$', + ]) + def run_main(arglist, config=None): if config is None: 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>') check_output(output, [ r'^REQUESTOR: Mx\. 510 $', - r'^TOTAL TO PAY: 280\.00 USD$', + r'^TOTAL TO PAY: \$280\.00$', r'^\s*2020-06-12\s', r'^\s+Expenses:FilingFees\s+60\.00 USD$', ])