"""Parses BoursoBank account statements.""" import datetime as dt import logging import re from decimal import Decimal from pypdf import PdfReader from rich.console import Console from rich.table import Table from rich import print as rich_print from rich.panel import Panel __version__ = "0.4" DATE_RE = r"([0-9]{1,2}/[0-9]{2}/[0-9]{2,4})" HEADER_VALUE_PATTERN = rf"""\s* (?P{DATE_RE})\s+ (?P[0-9]{{5}}\s+[0-9]{{5}}\s+[0-9]{{11}}\s+[0-9]{{2}})\s+ ( (?P[A-Z]{{3}}) | (?P[0-9]{{4}}\*{{8}}[0-9]{{4}}) )\s+ (?P(du)?\s+{DATE_RE}\s+(au\s+)?{DATE_RE})\s+ """ RE_CARD_OWNER = [ # First pattern is tried first re.compile(r"Porteur\s+de\s+la\s+carte\s+:\s+(?P.*)$", flags=re.M), re.compile( r"44\s+rue\s+Traversiere\s+CS\s+80134\s+92772\s+" r"Boulogne-Billancourt\s+Cedex\s+(?P.*)$", flags=re.M, ), ] logger = logging.getLogger(__name__) def parse_decimal(amount: str): """Parse a French amount like 1.234,56 to a Decimal instance.""" return Decimal(amount.replace(".", "").replace(",", ".")) class Line: """Represents one line (debit or credit) in a bank statement.""" PATTERN = re.compile( rf"\s+(?P{DATE_RE})\s*(?P