diff --git a/app/models/provider/llm_concept.rb b/app/models/provider/llm_concept.rb index c4ee70ef7..febc4a2c4 100644 --- a/app/models/provider/llm_concept.rb +++ b/app/models/provider/llm_concept.rb @@ -19,7 +19,7 @@ module Provider::LlmConcept raise NotImplementedError, "Subclasses must implement #enhance_provider_merchants" end - PdfProcessingResult = Data.define(:summary, :document_type, :extracted_data) + PdfProcessingResult = Data.define(:summary, :document_type, :extracted_data, :reconciliation) def supports_pdf_processing? false diff --git a/app/models/provider/openai/pdf_processor.rb b/app/models/provider/openai/pdf_processor.rb index 1cb63e773..2bace54c6 100644 --- a/app/models/provider/openai/pdf_processor.rb +++ b/app/models/provider/openai/pdf_processor.rb @@ -63,6 +63,14 @@ class Provider::Openai::PdfProcessor - Opening and closing balances (if visible) - Currency used + 4. **Reconciliation Check** (ONLY for bank_statement or credit_card_statement): + - First, use available tools to get accounts and their transactions for the relevant time period + - Match the statement to the correct account by comparing institution name, account holder, or account number + - Compare the statement closing balance with the account current balance + - Count transactions in the statement and compare with synced transaction count for that period + - Match individual transactions (by date within ±1 day, amount within ±$0.10, similar description) + - Report which transactions are new (in statement but not synced) and which are missing (synced but not in statement) + IMPORTANT GUIDELINES: - Be factual and precise - only report what you can clearly see in the document - If information is unclear or redacted, note it as "not clearly visible" or "redacted" @@ -84,6 +92,18 @@ class Provider::Openai::PdfProcessor "closing_balance": number or null, "currency": "USD/EUR/etc or null", "account_holder": "Name or null" + }, + "reconciliation": { + "performed": true|false, + "account_id": "account_id or null", + "balance_match": true|false|null, + "statement_transaction_count": number|null, + "synced_transaction_count": number|null, + "matched_count": number|null, + "new_count": number|null, + "missing_count": number|null, + "new_transactions": [{"date":"YYYY-MM-DD","amount":0.00,"description":"..."}], + "missing_transactions": [{"date":"YYYY-MM-DD","amount":0.00,"description":"..."}] } } INSTRUCTIONS @@ -226,7 +246,8 @@ class Provider::Openai::PdfProcessor PdfProcessingResult.new( summary: parsed["summary"], document_type: normalize_document_type(parsed["document_type"]), - extracted_data: parsed["extracted_data"] || {} + extracted_data: parsed["extracted_data"] || {}, + reconciliation: parsed["reconciliation"] ) end