Changeset - bc4d897c9293
[Not reviewed]
0 1 0
Ben Sturmfels (bsturmfels) - 2 years ago 2022-02-09 03:42:32
ben@sturm.com.au
reconcile: Tweak output.
1 file changed with 3 insertions and 3 deletions:
0 comments (0 inline, 0 general)
conservancy_beancount/reconcile/prototype_amex_reconciler.py
Show inline comments
...
 
@@ -83,27 +83,27 @@ def sort_records(records: List) -> List:
 
def records_match(r1: Dict, r2: Dict) -> Tuple[bool, str]:
 
    """Do these records represent the same transaction?"""
 
    date_matches_exactly = r1['date'] == r2['date']
 
    date_matches_loosly = r1['date'] >= r2['date'] - datetime.timedelta(days=3) and r1['date'] <= r2['date'] + datetime.timedelta(days=3)
 
    amount_matches = r1['amount'] == r2['amount']
 
    payee_match_quality = fuzz.token_set_ratio(r1['payee'], r2['payee'])
 
    payee_matches = payee_match_quality > 50
 
    if date_matches_exactly and amount_matches and payee_matches:
 
        return True, 'Matched'
 
    elif date_matches_loosly and amount_matches and payee_matches:
 
        return True, 'Matched +/- 3 days'
 
    elif date_matches_exactly and amount_matches:
 
        return True, f'Matched with low-payee match ({payee_match_quality}%)'
 
        return True, f'Matched ignoring payee'
 
    elif date_matches_loosly and amount_matches:
 
        return True, f'Matched +/- 3 days, low-payee match ({payee_match_quality}%)'
 
        return True, f'Matched +/- 3 days, ignoring payee'
 
    else:
 
        return False, ''
 

	
 

	
 
parser = argparse.ArgumentParser(description='Reconciliation helper')
 
parser.add_argument('--beancount-file', required=True)
 
parser.add_argument('--csv-statement', required=True)
 
parser.add_argument('--account', required=True, help='eg. Liabilities:CreditCard:AMEX')
 
parser.add_argument('--grep-output-filename')
 
# parser.add_argument('--report-group-regex')
 
parser.add_argument('--show-reconciled-matches', action='store_true')
 
args = parser.parse_args()
...
 
@@ -165,25 +165,25 @@ for r1 in statement_trans:
 
            if not r2['statement'] or args.show_reconciled_matches:
 
                    matches.append([r2['date'], f'{format_record(r1)}  →  {format_record(r2)}  ✓ {note}'])
 
            if not r2['statement']:
 
                metadata_to_apply.append((r2['filename'], r2['line'], f'    bank-statement: "{os.path.basename(args.csv_statement)}:{r2["line"]}"\n'))
 
            books_trans.remove(r2)
 
            break
 
    else:
 
        matches.append([r1['date'], f'{format_record(r1)}  →  {" ":^45}  ✗ Not in books ({os.path.basename(args.csv_statement)}:{r1["line"]})'])
 
for r2 in books_trans:
 
    matches.append([r2['date'], f'{" ":^45}  →  {format_record(r2)}  ✗ Not on statement ({os.path.basename(r2["filename"])}:{r2["line"]})'])
 

	
 
print('-' * 155)
 
print(f'{"STATEMENT":<38}            {"BOOKS":<44}   NOTES')
 
print(f'{"Statement transaction":<38}            {"Books transaction":<44}   Notes')
 
print('-' * 155)
 
for _, output in sorted(matches):
 
    print(output)
 
print('-' * 155)
 

	
 
# Write statement metadata back to books
 
if metadata_to_apply:
 
    print('Mark matched transactions as reconciled in the books? (y/N) ', end='')
 
    if input().lower() == 'y':
 
        files = {}
 
        # Query results aren't necessarily sequential in a file, so need to sort
 
        # so that our line number offsets work.
0 comments (0 inline, 0 general)