-
Notifications
You must be signed in to change notification settings - Fork 0
Fix/10 bug fixes excel viewer #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -35,6 +35,8 @@ class NormalizedStatement: | |||||
| repair_log: List[str] = field(default_factory=list) | ||||||
| raw_headers: List[str] = field(default_factory=list) | ||||||
| detected_anomalies: List[Dict[str, Any]] = field(default_factory=list) | ||||||
| # Metadata integrity: stores header vs calculated discrepancy for fraud detection | ||||||
| metadata_discrepancy: Optional[Dict[str, Any]] = None | ||||||
|
|
||||||
|
|
||||||
| # Common header aliases for bank statements | ||||||
|
|
@@ -241,12 +243,12 @@ def normalize_excel_statement(content: bytes, filename: str = "") -> NormalizedS | |||||
| """ | ||||||
| Normalize a bank statement Excel file into a clean, structured format. | ||||||
|
|
||||||
| Handles the real-world messiness found in the dataset: | ||||||
| - Account 3: Multi-section file with summary + transaction sections, -61M closing balance | ||||||
| - Account 4: Mixed date formats, OCR garbage rows ("unrings ICEASE") | ||||||
| - Account 5: Comma-formatted numbers, different header names | ||||||
| - Account 8: Summary at top before transactions, synthetic text | ||||||
| - Account 9: Simple format with transaction totals embedded | ||||||
| Handles real-world messiness found in financial documents: | ||||||
| - Multi-section files with summary + transaction sections | ||||||
| - Mixed date formats, OCR garbage rows | ||||||
| - Comma-formatted numbers, varying header names | ||||||
| - Summary sections at top before transactions | ||||||
| - Embedded transaction totals and metadata rows | ||||||
| """ | ||||||
| result = NormalizedStatement() | ||||||
| result.repair_log.append(f"normalizing: {filename}") | ||||||
|
|
@@ -455,30 +457,79 @@ def normalize_excel_statement(content: bytes, filename: str = "") -> NormalizedS | |||||
| result.closing_balance = summary_closing | ||||||
| result.repair_log.append(f"closing_from_summary: {summary_closing}") | ||||||
|
|
||||||
| # Step 5: Detect summary injection anomaly (Account 3 pattern) | ||||||
| if result.closing_balance is not None and result.transactions: | ||||||
| last_balance = None | ||||||
| # Step 5: Metadata Integrity Check | ||||||
| # Compare the header/summary closing balance against the actual last | ||||||
| # transaction balance. A massive discrepancy (>1.0 AND >50x) means the | ||||||
|
||||||
| # transaction balance. A massive discrepancy (>1.0 AND >50x) means the | |
| # transaction balance. A massive discrepancy (>1.0 AND >5x) means the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extracted_fields = dict(analysis.get("extracted_fields", {}))will raiseTypeErrorif Backboard returns an explicit null forextracted_fields(the key exists but value isNone). Use a null-safe fallback before copying (e.g.,analysis_extracted = analysis.get("extracted_fields") or {}thenextracted_fields = dict(analysis_extracted)).