import datetime import decimal from conservancy_beancount.reconcile.prototype_amex_reconciler import match_statement_and_books2 as match_statement_and_books, remove_payee_junk, date_proximity S1 = { 'date': datetime.date(2022, 1, 1), 'amount': decimal.Decimal('10.00'), 'payee': 'Patreon / Patreon / 123456/ ST-A1B2C3D4G5H6 /', 'line': 222, } S2 = { 'date': datetime.date(2022, 1, 2), 'amount': decimal.Decimal('20.00'), 'payee': 'BT*LINODE PHILADELPHIA P', 'line': 333, } S3 = { 'date': datetime.date(2022, 1, 3), 'amount': decimal.Decimal('30.00'), 'payee': 'USPS PO 4067540039 0PORTLAND OR', 'line': 444, } B1 = { 'date': datetime.date(2022, 1, 1), 'amount': decimal.Decimal('10.00'), 'payee': 'Patreon', 'entity': '', 'check_id': None, 'filename': '2022/imports.beancount', 'line': 777, 'bank_statement': "Financial/Bank-Statements/AMEX/2022-01-12_AMEX_statement.pdf" } B2 = { 'date': datetime.date(2022, 1, 2), 'amount': decimal.Decimal('20.00'), 'payee': 'Linode', 'entity': '', 'check_id': None, 'filename': '2022/main.beancount', 'line': 888, 'bank_statement': "Financial/Bank-Statements/AMEX/2022-01-12_AMEX_statement.pdf" } B3_next_day = { 'date': datetime.date(2022, 1, 4), 'amount': decimal.Decimal('30.00'), 'payee': 'USPS', 'entity': '', 'check_id': None, 'filename': '2022/main.beancount', 'line': 999, 'bank_statement': "Financial/Bank-Statements/AMEX/2022-01-12_AMEX_statement.pdf" } B3_next_week = { 'date': datetime.date(2022, 1, 10), 'amount': decimal.Decimal('30.00'), 'payee': 'USPS', 'entity': '', 'check_id': None, 'filename': '2022/main.beancount', 'line': 999, 'bank_statement': "Financial/Bank-Statements/AMEX/2022-01-12_AMEX_statement.pdf" } B3_mismatch_amount = { 'date': datetime.date(2022, 1, 3), 'amount': decimal.Decimal('31.00'), 'payee': 'USPS', 'entity': '', 'check_id': None, 'filename': '2022/main.beancount', 'line': 999, 'bank_statement': "Financial/Bank-Statements/AMEX/2022-01-12_AMEX_statement.pdf" } B3_payee_mismatch_1 = { 'date': datetime.date(2022, 1, 3), 'amount': decimal.Decimal('30.00'), 'payee': 'Credit X', 'entity': '', 'check_id': None, 'filename': '2022/main.beancount', 'line': 999, 'bank_statement': "Financial/Bank-Statements/AMEX/2022-01-12_AMEX_statement.pdf" } B3_payee_mismatch_2 = { 'date': datetime.date(2022, 1, 3), 'amount': decimal.Decimal('30.00'), 'payee': 'Credit Y', 'entity': '', 'check_id': None, 'filename': '2022/main.beancount', 'line': 999, 'bank_statement': "Financial/Bank-Statements/AMEX/2022-01-12_AMEX_statement.pdf" } def test_one_exact_match(): statement = [S1] books = [B1] assert match_statement_and_books(statement, books) == [ ([S1], [B1], []), ] def test_multiple_exact_matches(): statement = [S1, S2] books = [B1, B2] assert match_statement_and_books(statement, books) == [ ([S1], [B1], []), ([S2], [B2], []), ] def test_one_mismatch(): statement = [S1] books = [] assert match_statement_and_books(statement, books) == [ ([S1], [], ['no match']), ] def test_multiple_mismatches(): statement = [S1] books = [B2] assert match_statement_and_books(statement, books) == [ ([S1], [], ['no match']), ([], [B2], ['no match']), ] def test_next_day_matches(): statement = [S3] books = [B3_next_day] assert match_statement_and_books(statement, books) == [ ([S3], [B3_next_day], ['+/- 1 days']), ] def test_next_week_matches(): statement = [S3] books = [B3_next_week] assert match_statement_and_books(statement, books) == [ ([S3], [B3_next_week], ['+/- 7 days']), ] def test_incorrect_amount_does_not_match(): statement = [S3] books = [B3_mismatch_amount] assert match_statement_and_books(statement, books) == [ ([S3], [], ['no match']), ([], [B3_mismatch_amount], ['no match']), ] def test_payee_mismatch_ok_when_only_one_that_amount_and_date(): statement = [S3] books = [B3_payee_mismatch_1] assert match_statement_and_books(statement, books) == [ ([S3], [B3_payee_mismatch_1], ['payee mismatch', 'only one decent match']), ] def test_payee_mismatch_not_ok_when_multiple_that_amount_and_date(): statement = [S3] books = [B3_payee_mismatch_1, B3_payee_mismatch_2] match = match_statement_and_books(statement, books) assert match == [ ([S3], [], ['no match']), ([], [B3_payee_mismatch_1], ['no match']), ([], [B3_payee_mismatch_2], ['no match']), ] # def test_subset_sum_with_same_date_and_payee(): def test_remove_payee_junk(): assert remove_payee_junk('WIDGETSRUS INC PAYMENT 1') == 'WIDGETSRUS' assert remove_payee_junk('0000010017') == '10017' def test_date_proximity(): assert date_proximity(datetime.date(2021, 8, 23), datetime.date(2021, 8, 23)) == 1.0 assert date_proximity(datetime.date(2021, 8, 23), datetime.date(2021, 8, 23) - datetime.timedelta(days=30)) == 0.5 assert date_proximity(datetime.date(2021, 8, 23), datetime.date(2021, 8, 23) - datetime.timedelta(days=60)) == 0.0