Add tags to mapping

This commit is contained in:
2025-03-02 20:24:47 -05:00
parent 35e1c1039e
commit 3e4a284692
5 changed files with 44 additions and 39 deletions

View File

@@ -52,6 +52,19 @@ class Config(BaseModel):
categories: List[str] categories: List[str]
class Mapping(BaseModel):
"""Class for transaction mapping from mappings file."""
class Config:
extra = "forbid"
account2: str
count: int = 1
narration: Optional[str] = None
payee: Optional[str] = None
tags: Optional[List[str]] = None
class Transaction(BaseModel): class Transaction(BaseModel):
"""Class for ledger transaction to render into ldg file.""" """Class for ledger transaction to render into ldg file."""
@@ -67,17 +80,4 @@ class Transaction(BaseModel):
description: str description: str
csv_file: str csv_file: str
row: str row: str
narration: Optional[str] = None mapping: Optional[Mapping] = None
payee: Optional[str] = None
class Mapping(BaseModel):
"""Class for transaction mapping from mappings file."""
class Config:
extra = "forbid"
account2: str
count: int = 1
narration: Optional[str] = None
payee: Optional[str] = None

View File

@@ -28,9 +28,7 @@ def get_sort_categories():
def add_account2(transactions: List[Transaction], categories: List[str]): def add_account2(transactions: List[Transaction], categories: List[str]):
unmapped_transactions = list( unmapped_transactions = list(filter(lambda t: t.mapping == None, transactions))
filter(lambda t: t.account2 == UNKNOWN_CATEGORY, transactions)
)
if len(unmapped_transactions) == 0: if len(unmapped_transactions) == 0:
return return
sort_categories = get_sort_categories() sort_categories = get_sort_categories()

View File

@@ -74,13 +74,7 @@ def apply_mappings(transactions: List[Transaction], mappings: Dict[str, Mapping]
mapping.count > 0 mapping.count > 0
), f"{mapping} used by {t} but count is not greater than '0'." ), f"{mapping} used by {t} but count is not greater than '0'."
mapping.count -= 1 mapping.count -= 1
t.account2 = mapping.account2 t.mapping = mapping
if mapping.narration:
t.narration = mapping.narration
if mapping.payee:
t.payee = mapping.payee
else: else:
logging.warning(f"No mapping for '{t}'.") logging.warning(f"No mapping for '{t}'.")

View File

@@ -81,9 +81,9 @@ def write_mappings(transactions: List[Transaction], mappings_file: Path):
) )
mappings[t.row] = mapping mappings[t.row] = mapping
mappings = {k: v.dict() for k, v in mappings.items()} mappings = {k: v.model_dump(exclude_none=True) for k, v in mappings.items()}
with open(mappings_file, "w") as f: with open(mappings_file, "w") as f:
json.dump(mappings, f, indent=4) json.dump(mappings, f, indent=2)
def read_mappings(mappings_file: Path) -> Dict[str, Mapping]: def read_mappings(mappings_file: Path) -> Dict[str, Mapping]:

View File

@@ -5,7 +5,7 @@ from toldg.models import Config, Transaction
from toldg.utils import category_to_bean from toldg.utils import category_to_bean
BEANCOUNT_TRANSACTION_TEMPLATE = """ BEANCOUNT_TRANSACTION_TEMPLATE = """
{t.date} * {t.description} {t.date} * {description}{tags}
{t.account2:<40} {t.debit:<6} {t.currency} {t.account2:<40} {t.debit:<6} {t.currency}
{t.account1:<40} {t.credit:<6} {t.currency} {t.account1:<40} {t.credit:<6} {t.currency}
""" """
@@ -13,28 +13,41 @@ BEANCOUNT_TRANSACTION_TEMPLATE = """
def format(t): def format(t):
t.date = t.date.replace("/", "-") t.date = t.date.replace("/", "-")
if t.narration and t.payee:
# A transaction may have an optional “payee” and/or a “narration.” tags = ""
t.description = f'"{t.payee}" "{t.narration}"' description = None
elif t.narration: if t.mapping:
# If you place a single string on a transaction line, it becomes its narration: m = t.mapping
t.description = f'"{t.narration}"' t.account2 = m.account2
elif t.payee:
# If you want to set just a payee, put an empty narration string: if m.narration and m.payee:
t.description = f'"{t.payee}" ""' # A transaction may have an optional “payee” and/or a “narration.”
else: description = f'"{m.payee}" "{m.narration}"'
t.description = f'"{t.description}"' elif m.narration:
# If you place a single string on a transaction line, it becomes its narration:
description = f'"{m.narration}"'
elif m.payee:
# If you want to set just a payee, put an empty narration string:
description = f'"{m.payee}" ""'
if m.tags:
tags = " #" + " #".join(m.tags)
if description is None:
description = f'"{t.description}"'
if not t.debit.startswith("-"): if not t.debit.startswith("-"):
t.debit = " " + t.debit t.debit = " " + t.debit
if not t.credit.startswith("-"): if not t.credit.startswith("-"):
t.credit = " " + t.credit t.credit = " " + t.credit
t.account1 = category_to_bean(t.account1) t.account1 = category_to_bean(t.account1)
t.account2 = category_to_bean(t.account2) t.account2 = category_to_bean(t.account2)
if t.currency == "EUR": if t.currency == "EUR":
t.debit = t.debit.replace(".", "|").replace(",", ".").replace("|", ",") t.debit = t.debit.replace(".", "|").replace(",", ".").replace("|", ",")
t.credit = t.credit.replace(".", "|").replace(",", ".").replace("|", ",") t.credit = t.credit.replace(".", "|").replace(",", ".").replace("|", ",")
return BEANCOUNT_TRANSACTION_TEMPLATE.format(t=t) return BEANCOUNT_TRANSACTION_TEMPLATE.format(
t=t, description=description, tags=tags
)
def render_to_file(transactions: List[Transaction], config: Config): def render_to_file(transactions: List[Transaction], config: Config):