diff --git a/src/monopoly/pipeline.py b/src/monopoly/pipeline.py index 6950f6ac..37dba6a4 100644 --- a/src/monopoly/pipeline.py +++ b/src/monopoly/pipeline.py @@ -1,5 +1,6 @@ import csv import logging +import re from pathlib import Path from typing import Optional, Type @@ -8,6 +9,7 @@ from monopoly.banks import BankBase from monopoly.config import DateOrder +from monopoly.constants.date import DateFormats from monopoly.generic import GenericBank, GenericStatementHandler from monopoly.handler import StatementHandler from monopoly.pdf import PdfPage, PdfParser @@ -73,18 +75,27 @@ def convert_date(transaction: Transaction, transaction_date_order: DateOrder): e.g. if the statement month is Jan/Feb 2024, transactions from Oct/Nov/Dec should be attributed to the previous year. """ - if str(statement_date.year) not in transaction.date: - transaction.date += f" {statement_date.year}" + # do not include year if transaction already includes date + has_year = bool(re.search(DateFormats.YYYY, transaction.date)) + + if not has_year and str(statement_date.year) not in transaction.date: + transaction.date = f"{transaction.date} {statement_date.year}" + parsed_date = parse( - transaction.date, - settings=transaction_date_order.settings, + transaction.date, settings=transaction_date_order.settings ) - if parsed_date: - if statement_date.month in (1, 2) and parsed_date.month > 2: - parsed_date = parsed_date.replace(year=parsed_date.year - 1) - return parsed_date.isoformat()[:10] - raise RuntimeError("Could not convert date") + if not parsed_date: + raise RuntimeError("Could not convert date") + + if ( + statement_date.month in (1, 2) + and parsed_date.month > 2 + and not has_year + ): + parsed_date = parsed_date.replace(year=parsed_date.year - 1) + + return parsed_date.isoformat()[:10] logger.debug("Transforming dates to ISO 8601") diff --git a/tests/integration/banks/test_date_handling.py b/tests/integration/banks/test_date_handling.py index c984cfed..8d218669 100644 --- a/tests/integration/banks/test_date_handling.py +++ b/tests/integration/banks/test_date_handling.py @@ -5,6 +5,27 @@ from monopoly.statements import BaseStatement, Transaction +def test_transform_yyyy_transaction(statement: BaseStatement): + raw_transactions = [ + Transaction( + transaction_date="01/12/2023", + description="FAIRPRICE FINEST", + amount="18.49", + ), + ] + statement.transactions = raw_transactions + statement.statement_date = datetime(2024, 1, 1) + statement.config.transaction_date_order = DateOrder("DMY") + transformed_transactions = Pipeline.transform(statement) + expected_transactions = [ + Transaction( + transaction_date="2023-12-01", description="FAIRPRICE FINEST", amount=18.49 + ), + ] + + assert transformed_transactions == expected_transactions + + def test_transform_cross_year(statement: BaseStatement): raw_transactions = [ Transaction(