rehan953 commited on
Commit
f67813a
·
verified ·
1 Parent(s): 211851b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -0
app.py CHANGED
@@ -2643,6 +2643,88 @@ def _split_fused_date_transaction_header(grid):
2643
  new_grid.append(split_row)
2644
  return new_grid
2645
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2646
  def normalize_html_tables(text: str) -> str:
2647
  """
2648
  For every <table>...</table>:
@@ -2694,6 +2776,10 @@ def normalize_html_tables(text: str) -> str:
2694
  # Fix NF-2: split fused "Date Transaction Detail" header/cell.
2695
  grid = _split_fused_date_transaction_header(grid)
2696
 
 
 
 
 
2697
  # Fix 8: split fused multi-keyword header cell (First Horizon Bank)
2698
  grid = _split_fused_multicolumn_header(grid)
2699
 
 
2643
  new_grid.append(split_row)
2644
  return new_grid
2645
 
2646
+ def _normalize_fused_date_posted_amount_table(grid):
2647
+ """
2648
+ Normalize 2-column OCR tables with fused header like:
2649
+ col1: "Date posted Transaction description [Reference number]"
2650
+ col2: "Amount"
2651
+ into stable 3-column transaction layout:
2652
+ Date | Transaction Description | Amount
2653
+ Strict guard: only activates on that specific fused-header signature.
2654
+ """
2655
+ if not grid or len(grid) < 2:
2656
+ return grid
2657
+
2658
+ ncols = max(len(r) for r in grid if isinstance(r, list))
2659
+ if ncols < 2:
2660
+ return grid
2661
+
2662
+ def _row_cells(r):
2663
+ return [str(c or "").strip() for c in (r + [""] * (ncols - len(r)))]
2664
+
2665
+ hdr_idx = None
2666
+ for ri in range(min(6, len(grid))):
2667
+ cells = _row_cells(grid[ri])
2668
+ row_text = " ".join(cells).lower()
2669
+ if (
2670
+ "date posted transaction description" in row_text
2671
+ and "amount" in row_text
2672
+ ):
2673
+ hdr_idx = ri
2674
+ break
2675
+ if hdr_idx is None:
2676
+ return grid
2677
+
2678
+ date_re = re.compile(r"^\d{1,2}[/-]\d{1,2}(?:[/-]\d{2,4})?$")
2679
+ out = []
2680
+
2681
+ for ri, row in enumerate(grid):
2682
+ cells = _row_cells(row)
2683
+ if ri == hdr_idx:
2684
+ out.append(["Date", "Transaction Description", "Amount"])
2685
+ continue
2686
+ if ri < hdr_idx:
2687
+ # Keep pre-header text as non-transaction row.
2688
+ joined = " ".join(c for c in cells if c).strip()
2689
+ out.append(["", joined, ""])
2690
+ continue
2691
+
2692
+ c1 = cells[0].strip()
2693
+ c2 = cells[1].strip() if len(cells) > 1 else ""
2694
+
2695
+ # Skip duplicated inline sub-headers that often appear in fused OCR tables.
2696
+ lower_c1 = c1.lower()
2697
+ if (
2698
+ lower_c1.startswith("date posted transaction description")
2699
+ or lower_c1 in {"ach additions", "ach deductions", "other additions", "other deductions", "service charges and fees"}
2700
+ ):
2701
+ continue
2702
+
2703
+ date = ""
2704
+ desc = c1
2705
+ if c1:
2706
+ parts = c1.split()
2707
+ if parts and date_re.match(parts[0]):
2708
+ date = parts[0]
2709
+ desc = " ".join(parts[1:]).strip()
2710
+
2711
+ # If amount is empty in column 2, try extracting trailing amount from description.
2712
+ amount = c2
2713
+ if not amount and desc:
2714
+ m = re.search(r"(-?\$?\d{1,3}(?:,\d{3})*(?:\.\d{2})-?)\s*$", desc)
2715
+ if m:
2716
+ amount = m.group(1)
2717
+ desc = desc[:m.start()].strip()
2718
+
2719
+ if not (date or desc or amount):
2720
+ continue
2721
+ out.append([date, desc, amount])
2722
+
2723
+ # Keep at least header + 1 row to avoid degrading clean tables on accidental match.
2724
+ if len(out) < 2:
2725
+ return grid
2726
+ return out
2727
+
2728
  def normalize_html_tables(text: str) -> str:
2729
  """
2730
  For every <table>...</table>:
 
2776
  # Fix NF-2: split fused "Date Transaction Detail" header/cell.
2777
  grid = _split_fused_date_transaction_header(grid)
2778
 
2779
+ # Fix 11: normalize fused "Date posted Transaction description ... / Amount"
2780
+ # two-column tables into stable Date/Description/Amount structure.
2781
+ grid = _normalize_fused_date_posted_amount_table(grid)
2782
+
2783
  # Fix 8: split fused multi-keyword header cell (First Horizon Bank)
2784
  grid = _split_fused_multicolumn_header(grid)
2785