diff --git a/ingestion/parsers.py b/ingestion/parsers.py index 3ae5d57..5e46f36 100644 --- a/ingestion/parsers.py +++ b/ingestion/parsers.py @@ -90,7 +90,7 @@ def _txt_items(text, profile, skipped): regular = [re.compile(rf'^({date_re})(.{{{body_size}}})([A-Z ]{{2}})\s+(\S+)\s+(\S+)\s*$')] if profile == 'OUROCARD_FULL_V1': regular.append(re.compile(rf'^({date_re})(.{{33}})([A-Za-z ]{{7}})\s+(\S+)\s+(\S+)\s*$')) - payment = re.compile(rf'^({date_re})\s*(PGTO DEBITO CONTA.*?)200211\s+(\S+)\s+(\S+)\s*$') + payment = re.compile(rf'^({date_re})\s*(PGTO DEBITO CONTA.*?)\s+(\S+)\s+(\S+)\s*$') section, section_count = '1', 0 for number, line in enumerate(text.splitlines(), 1): locator = f'line:{number}' @@ -117,6 +117,8 @@ def _txt_items(text, profile, skipped): skipped['balance'] += 1 else: yield ParsedItem(locator, section, match[1], match[2].rstrip(), match[4], match[5]) + elif partial and not re.match(r'^\s*(?:\d{1,2}[./]|DATA\s+DE\s+EMISS)', line, re.I): + skipped['metadata'] += 1 else: code = 'INVALID_ROW' if re.match(r'^\s*\d{1,2}[./]', line) else 'UNRECOGNIZED_LINE' yield ParsedItem(locator, section, description=line, errors=(code,)) diff --git a/tests/test_import_parsers.py b/tests/test_import_parsers.py index f3e39ad..868e559 100644 --- a/tests/test_import_parsers.py +++ b/tests/test_import_parsers.py @@ -64,6 +64,20 @@ def test_full_card_sections_installments_credit_and_payment(): assert rows[3].description == 'unknown text' +def test_partial_card_skips_metadata_and_parses_payment_with_variable_identifiers(): + parsed = parse_document(( + 'SYNTHETIC INVOICE HEADER\n' + '15/01 PGTO DEBITO CONTA 0001 123456789 123 123 -100,00 0,00\n' + ).encode(), 'OUROCARD_PARTIAL_V1', {'start_date': '2025-02-01', 'end_date': '2026-01-31'}) + + rows = normalize(parsed) + + assert parsed.skipped['metadata'] == 1 + assert len(rows) == 1 + assert rows[0].errors == () + assert rows[0].kind == 'TRANSFER' + assert rows[0].amount == '100.00' + @pytest.mark.parametrize('country', ['ESTADOS', 'Brasil']) def test_full_card_accepts_extended_country_layout(country): row = card(alternate_full_card_line(country=country))[0] @@ -75,6 +89,7 @@ def test_full_card_accepts_extended_country_layout(country): def test_card_ambiguity_bad_shapes_and_installments_block(): assert 'AMBIGUOUS_AMOUNT' in card(card_line(debit='2,00', credit='1,00'))[0].errors assert 'INVALID_ROW' in card('15.02.2026 MALFORMED')[0].errors + assert 'INVALID_ROW' in card('15/01 MALFORMED', True)[0].errors assert 'INVALID_INSTALLMENT' in card(card_line(body='LOJA PARC 3/2'))[0].errors assert 'INVALID_AMOUNT' in card(card_line(debit='1.23,00'))[0].errors