From 35c02e97ce0453b61c1a91f85d136f0f06140bb5 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 20 Jan 2026 14:50:47 +0000 Subject: [PATCH] Fix Indonesian number format parsing in transaction extraction - Update _AMOUNT_PATTERN to support comma decimal separators - Add regression tests for Indonesian format transactions - Update .gitignore to include .ruff_cache and output/ --- .gitignore | 3 +- pdfparser/utils.py | 2 +- tests/test_indonesian_format.py | 74 +++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 tests/test_indonesian_format.py diff --git a/.gitignore b/.gitignore index c0e865e..4807b5e 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,7 @@ env/ plan/ # Planning notes and drafts claude.md # AI assistant instructions .env # Environment variables (secrets) +output/ # Output directory for parsed files # Testing .pytest_cache/ @@ -52,7 +53,7 @@ htmlcov/ .hypothesis/ # Code quality tools -.ruffcache/ +.ruff_cache/ # Logs *.log diff --git a/pdfparser/utils.py b/pdfparser/utils.py index b288271..6eb8159 100644 --- a/pdfparser/utils.py +++ b/pdfparser/utils.py @@ -71,7 +71,7 @@ _WHITESPACE_PATTERN: Pattern = re.compile(r"\s+") _NUMERIC_LINE_PATTERN: Pattern = re.compile(r"^[\d,.]+\s*$") _NUMERIC_ONLY_PATTERN: Pattern = re.compile(r"^[\d,.]*$") -_AMOUNT_PATTERN: Pattern = re.compile(r"^[\d,]+\.\d{2}$") +_AMOUNT_PATTERN: Pattern = re.compile(r"^[\d,.]+[.,]\d{2}$") _USER_ID_PATTERN: Pattern = re.compile(r"^\d{6,8}$") # Summary section label patterns (compiled for extract_summary_totals) diff --git a/tests/test_indonesian_format.py b/tests/test_indonesian_format.py new file mode 100644 index 0000000..8d60247 --- /dev/null +++ b/tests/test_indonesian_format.py @@ -0,0 +1,74 @@ + +import pytest +from pdfparser.utils import extract_transactions + +class TestIndonesianFormat: + """Tests for Indonesian number format extraction.""" + + def test_extract_indonesian_format_transactions(self): + """Verify extraction of transactions with Indonesian number format.""" + text = """ +01/01/23 10:00:00 +Transfer +User123 +10.000,00 +0,00 +1.000.000,00 +""" + transactions = extract_transactions(text) + + assert len(transactions) == 1 + txn = transactions[0] + + # In this specific text layout, User123 is treated as description because + # it is not on the same line as amount and doesn't match User ID pattern. + # But crucially, '10.000,00' should be identified as DEBIT amount, + # not mistakenly as User ID. + + assert txn["debit"] == "10.000,00" + assert txn["credit"] == "0,00" + assert txn["balance"] == "1.000.000,00" + + # Ensure it wasn't misclassified as User + # (If misclassified, user would be "10.000,00" and debit would be empty) + assert txn["user"] != "10.000,00" + + def test_extract_indonesian_format_no_user_id(self): + """Verify extraction when User ID is missing and amounts are Indonesian format.""" + text = """ +01/01/23 10:00:00 +Transfer +10.000,00 +0,00 +1.000.000,00 +""" + transactions = extract_transactions(text) + + assert len(transactions) == 1 + txn = transactions[0] + + assert txn["debit"] == "10.000,00" + assert txn["credit"] == "0,00" + assert txn["balance"] == "1.000.000,00" + + # Verify it wasn't misclassified as User + assert txn["user"] == "" + + def test_extract_us_format_transactions(self): + """Verify extraction of transactions with US number format (sanity check).""" + text = """ +01/01/23 10:00:00 +Transfer +User123 +10000.00 +0.00 +1000000.00 +""" + transactions = extract_transactions(text) + + assert len(transactions) == 1 + txn = transactions[0] + + assert txn["debit"] == "10000.00" + assert txn["credit"] == "0.00" + assert txn["balance"] == "1000000.00"