Files @ 32fc4517a054
Branch filter:

Location: NPO-Accounting/conservancy_beancount/tests/test_reconcile.py - annotation

bsturmfels
reconcile: show check number, remove duplicate words in payee.
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
32fc4517a054
32fc4517a054
32fc4517a054
32fc4517a054
32fc4517a054
32fc4517a054
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
32fc4517a054
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
32fc4517a054
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
32fc4517a054
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
32fc4517a054
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
32fc4517a054
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
32fc4517a054
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
32fc4517a054
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
32fc4517a054
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
32fc4517a054
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
32fc4517a054
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
d8f4eac53bb7
32fc4517a054
32fc4517a054
32fc4517a054
32fc4517a054
import datetime
import decimal

from conservancy_beancount.reconcile.prototype_amex_reconciler import (
    match_statement_and_books,
    remove_payee_junk,
    date_proximity,
    remove_duplicate_words,
)

S1 = {
    'date': datetime.date(2022, 1, 1),
    'amount': decimal.Decimal('10.00'),
    'payee': 'Patreon         / Patreon   / 123456/ ST-A1B2C3D4G5H6       /',
    'check_id': '',
    'line': 222,
}
S2 = {
    'date': datetime.date(2022, 1, 2),
    'amount': decimal.Decimal('20.00'),
    'payee': 'BT*LINODE           PHILADELPHIA        P',
    'check_id': '',
    'line': 333,
}
S3 = {
    'date': datetime.date(2022, 1, 3),
    'amount': decimal.Decimal('30.00'),
    'payee': 'USPS PO 4067540039 0PORTLAND            OR',
    'check_id': '',
    'line': 444,
}

B1 = {
    'date': datetime.date(2022, 1, 1),
    'amount': decimal.Decimal('10.00'),
    'payee': 'Patreon',
    'check_id': '',
    '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',
    'check_id': '',
    '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',
    'check_id': '',
    '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',
    'check_id': '',
    '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',
    'check_id': '',
    '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',
    'check_id': '',
    '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',
    'check_id': '',
    '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


def test_remove_duplicate_words():
    assert remove_duplicate_words('Hi Foo Kow FOO') == 'Hi Foo Kow'