diff --git a/conservancy_beancount/reconcile/statement_reconciler.py b/conservancy_beancount/reconcile/statement_reconciler.py index 057e3452af38e40e8bfbc37c206ff9286b0a1375..034d33a5bfeec74b0873b3f7886ce382270184ca 100644 --- a/conservancy_beancount/reconcile/statement_reconciler.py +++ b/conservancy_beancount/reconcile/statement_reconciler.py @@ -625,6 +625,24 @@ def process_unmatched(statement_trans: List[dict], books_trans: List[dict]) -> L return matches +def format_output(matches, begin_date, end_date, csv_statement, show_reconciled_matches) -> str: + with io.StringIO() as out: + match_output = format_matches(matches, csv_statement, show_reconciled_matches) + _, total_missing_from_books, total_missing_from_statement = totals(matches) + print('-' * 155, file=out) + statement_heading = f'Statement transactions {begin_date} to {end_date}' + print(f'{statement_heading:<52} {"Books transactions":<58} Notes', file=out) + print('-' * 155, file=out) + for _, output in sorted(match_output, key=lambda x: x[0]): + print(output, file=out) + print('-' * 155, file=out) + print(f'Sub-total not on statement: {total_missing_from_statement:12,.2f}', file=out) + print(f'Sub-total not in books: {total_missing_from_books:12,.2f}', file=out) + print(f'Total: {total_missing_from_statement + total_missing_from_books:12,.2f}', file=out) + print('-' * 155, file=out) + return out.getvalue() + + def main(arglist: Optional[Sequence[str]] = None, stdout: TextIO = sys.stdout, stderr: TextIO = sys.stderr, @@ -689,19 +707,7 @@ def main(arglist: Optional[Sequence[str]] = None, matches.extend(unmatched) # Print out results of our matching. - match_output = format_matches(matches, args.csv_statement, args.show_reconciled_matches) - _, total_missing_from_books, total_missing_from_statement = totals(matches) - print('-' * 155) - statement_heading = f'Statement transactions {begin_date} to {end_date}' - print(f'{statement_heading:<52} {"Books transactions":<58} Notes') - print('-' * 155) - for _, output in sorted(match_output, key=lambda x: x[0]): - print(output) - print('-' * 155) - print(f'Sub-total not on statement: {total_missing_from_statement:12,.2f}') - print(f'Sub-total not in books: {total_missing_from_books:12,.2f}') - print(f'Total: {total_missing_from_statement + total_missing_from_books:12,.2f}') - print('-' * 155) + print(format_output(matches, begin_date, end_date, args.csv_statement, args.show_reconciled_matches)) # Write statement metadata back to the books. metadata_to_apply = [] diff --git a/tests/test_reconcile.py b/tests/test_reconcile.py index 9d58eb77b0cc60b95ca147939bdfcfc192d0c661..292de3648d6476d04415aba9ffc7300da6fe9dc9 100644 --- a/tests/test_reconcile.py +++ b/tests/test_reconcile.py @@ -7,6 +7,7 @@ import textwrap from conservancy_beancount.reconcile.statement_reconciler import ( date_proximity, + format_output, match_statement_and_books, metadata_for_match, payee_match, @@ -379,3 +380,11 @@ def test_handles_fr_csv(): }, ] assert read_fr_csv(io.StringIO(CSV)) == expected + + +def test_format_output(): + statement = [S1] + books = [B1] + matches, _, _ = match_statement_and_books(statement, books) + output = format_output(matches, datetime.date(2022, 1, 1), datetime.date(2022, 2, 1), 'test.csv', True) + assert '2022-01-01: 10.00 Patreon / Patreon / 12345 → 2022-01-01: 10.00 Patreon ✓ Matched' in output