#! /usr/bin/env python3 from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base from models import Category, Transaction from helper import get_session, add_category, get_rules import sys import click import colorful as cf from prompt_toolkit.completion import FuzzyWordCompleter from prompt_toolkit.shortcuts import prompt def print_verbose(verbose, string): if verbose: print(string) @click.command(name="autosort") @click.option("--profile", "-p") @click.option("--dry-run", default=False, is_flag=True) @click.option("--verbose", "-v", default=False, is_flag=True) def command(profile, dry_run, verbose): session = get_session(profile) rules = get_rules(profile) unsorted = session.query(Transaction).filter(Transaction.category_id == None).all() print("Found {} unsorted transcations".format(len(unsorted))) matched = 0 for t in unsorted: cat_name = apply_rules(t, rules) if cat_name: short_name = t.name[:25] if len(t.name) > 25 else t.name short_desc = t.description[:45] if len(t.description) > 50 else t.description print_verbose(verbose, "{:<25} | {:<50}| {:>10}€".format(short_name, short_desc, t.amount / 100)) print_verbose(verbose, cf.green(f"Matched '{cat_name}'")) cat_id = session.query(Category).filter(Category.name == cat_name).first() if not cat_id: cat_id = add_category(cat_name, profile, session) matched += 1 t.category_id = cat_id session.add(t) print_verbose(verbose, "-" * 90) print(f"Automatically matched {matched} transactions") if not dry_run: session.commit() def apply_rules(t, rules): for r in rules: iban = r.get("iban") name_regex = r.get("name_regex") desc_regex = r.get("desc_regex") if iban: if t.iban != iban: continue if name_regex: if not name_regex.search(t.name): continue if desc_regex: if not desc_regex.search(t.description): continue return r["category"]