diff --git a/src/monopoly/banks/__init__.py b/src/monopoly/banks/__init__.py index cb9fb8d..46d750d 100644 --- a/src/monopoly/banks/__init__.py +++ b/src/monopoly/banks/__init__.py @@ -2,6 +2,7 @@ from typing import Type from .base import BankBase +from .chase import Chase from .citibank import Citibank from .dbs import Dbs from .detector import BankDetector @@ -14,6 +15,7 @@ from .zkb import ZurcherKantonalBank banks: list[Type["BankBase"]] = [ + Chase, Citibank, Dbs, ExampleBank, diff --git a/src/monopoly/banks/chase/__init__.py b/src/monopoly/banks/chase/__init__.py new file mode 100644 index 0000000..8ff8ed5 --- /dev/null +++ b/src/monopoly/banks/chase/__init__.py @@ -0,0 +1,3 @@ +from .chase import Chase + +__all__ = ["Chase"] diff --git a/src/monopoly/banks/chase/chase.py b/src/monopoly/banks/chase/chase.py new file mode 100644 index 0000000..0c3f20c --- /dev/null +++ b/src/monopoly/banks/chase/chase.py @@ -0,0 +1,36 @@ +import logging +from re import compile as regex + +from monopoly.config import DateOrder, StatementConfig +from monopoly.constants import BankNames, CreditTransactionPatterns, EntryType +from monopoly.identifiers import MetadataIdentifier, TextIdentifier + +from ..base import BankBase + +logger = logging.getLogger(__name__) + + +class Chase(BankBase): + name = BankNames.CHASE + + credit = StatementConfig( + statement_type=EntryType.CREDIT, + statement_date_pattern=regex(r"Statement Date:\s+(.*)"), + statement_date_order=DateOrder("MDY"), + transaction_date_order=DateOrder("MDY"), + header_pattern=regex(r"(.*Transaction.*Merchant Name .*\$ Amount)"), + transaction_pattern=CreditTransactionPatterns.CHASE, + multiline_transactions=True, + ) + + identifiers = [ + [ + MetadataIdentifier( + format="PDF 1.7", + producer="OpenText Output Transformation Engine - 23.4", + ), + TextIdentifier("Chase"), + ] + ] + + statement_configs = [credit] diff --git a/src/monopoly/constants/date.py b/src/monopoly/constants/date.py index 9df7d11..8dd5f8b 100644 --- a/src/monopoly/constants/date.py +++ b/src/monopoly/constants/date.py @@ -36,6 +36,7 @@ class ISO8601(RegexEnum): DD_MMM_YYYY = ( rf"\b({DateFormats.DD}[-\s]{DateFormats.MMM}[,\s]{{1,2}}{DateFormats.YYYY})" ) + MM_DD = rf"\b({DateFormats.MM}[\/\-\s]{DateFormats.DD})" MMMM_DD_YYYY = ( rf"\b({DateFormats.MMMM}\s{DateFormats.DD}[,\s]{{1,2}}{DateFormats.YYYY})" ) diff --git a/src/monopoly/constants/statement.py b/src/monopoly/constants/statement.py index 48a3e53..c25c536 100644 --- a/src/monopoly/constants/statement.py +++ b/src/monopoly/constants/statement.py @@ -15,6 +15,7 @@ class EntryType(AutoEnum): class BankNames(AutoEnum): + CHASE = auto() CITIBANK = auto() DBS = auto() HSBC = auto() @@ -103,6 +104,11 @@ class CreditTransactionPatterns(RegexEnum): + SharedPatterns.DESCRIPTION + SharedPatterns.AMOUNT_EXTENDED ) + CHASE = ( + rf"(?P{ISO8601.MM_DD})\s+" + + SharedPatterns.DESCRIPTION + + SharedPatterns.AMOUNT_EXTENDED + ) CITIBANK = ( rf"(?P{ISO8601.DD_MMM})\s+" + SharedPatterns.DESCRIPTION diff --git a/src/monopoly/statements/base.py b/src/monopoly/statements/base.py index e00932b..b261e81 100644 --- a/src/monopoly/statements/base.py +++ b/src/monopoly/statements/base.py @@ -204,8 +204,7 @@ def statement_date(self) -> datetime: ) if statement_date: return statement_date - else: - logger.info("Unable to parse statement date %s", match.group(1)) + logger.info("Unable to parse statement date %s", match.group(1)) raise ValueError("Statement date not found") def get_decimal_numbers(self, lines: list[str]) -> set[float]: