""" UNLIMITED KEYS S.R.L. store profile for OCR extraction. Key duplication service. Notable for CASH (NUMERAR) payments. """ import re from decimal import Decimal, InvalidOperation from typing import List, Dict, Any from .base import BaseStoreProfile from . import ProfileRegistry @ProfileRegistry.register class UnlimitedKeysProfile(BaseStoreProfile): """ UNLIMITED KEYS S.R.L. - standard TVA profile with NUMERAR payment. Key characteristics: - Standard TVA format (single rate, any percentage) - Key duplication service - NUMERAR (cash) payment common - different from most stores! - May also accept CARD """ CUI_LIST = ["18993187"] NAME_PATTERNS = ["UNLIMITED KEYS", "UNLIMITED", "UNL1MITED", "UNLIMITED KEYS SRL"] STORE_NAME = "UNLIMITED KEYS S.R.L." # Standard TVA patterns (flexible - accepts any rate) TVA_PATTERNS = [ # "TVA A: XX% = YY,YY" or "TVA-A XX% YY,YY" r'TVA\s*[-:]?\s*([A-D])\s*:?\s*(\d{1,2})\s*%\s*[=:]?\s*([\d.,]+)', # "A - XX,XX% = YY,YY" r'([A-D])\s*[-:]\s*(\d{1,2})[.,]?\d{0,2}\s*%\s*[=:]?\s*([\d.,]+)', # "TVA XX% YY,YY" (simple format without code) r'TVA\s+(\d{1,2})\s*%\s*([\d.,]+)', ] def extract_tva_entries(self, text: str) -> List[dict]: """ Extract TVA entries from receipt text. Args: text: Raw OCR text from receipt Returns: List of TVA entries with code, percent, and amount """ entries = [] seen = set() # Try coded patterns first for pattern in self.TVA_PATTERNS[:2]: for match in re.finditer(pattern, text, re.IGNORECASE): try: code = match.group(1).upper() percent = int(match.group(2)) amount = self._parse_decimal(match.group(3)) if amount and amount > 0: entry_key = (code, percent) if entry_key not in seen: entries.append({ 'code': code, 'percent': percent, 'amount': amount }) seen.add(entry_key) except (ValueError, InvalidOperation, IndexError): continue # Fallback to simple format if not entries: simple_pattern = self.TVA_PATTERNS[2] for match in re.finditer(simple_pattern, text, re.IGNORECASE): try: percent = int(match.group(1)) amount = self._parse_decimal(match.group(2)) if amount and amount > 0: entries.append({ 'code': 'A', 'percent': percent, 'amount': amount }) break except (ValueError, InvalidOperation): continue return entries def get_validation_hints(self) -> Dict[str, Any]: """Return UNLIMITED KEYS-specific validation hints.""" return { "has_multi_rate_tva": False, "card_equals_total": False, # May be NUMERAR (cash) "has_client_cui": True, # May have client CUI "has_efactura": False, "is_non_vat_payer": False, "common_payment": "NUMERAR", # Cash payments common }