Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -24,6 +24,7 @@ Primary goals for reconcile rate:
|
|
| 24 |
- Fix 13: collapse Date|Description|Amount|Description|Amount tables to 3 columns; fix fused
|
| 25 |
Beginning/Ending balance rows (UCB-style wide summary tables)
|
| 26 |
- Fix 14: UCB 3-col tables where Beginning Balance amount is fused into description and Amount is $0.00
|
|
|
|
| 27 |
- Post-pass: drop later duplicate subset Date|Description|Amount tables (repeated deposit blocks)
|
| 28 |
"""
|
| 29 |
|
|
@@ -2863,6 +2864,60 @@ def _normalize_ucb_three_col_beginning_balance_fusion(grid):
|
|
| 2863 |
return out if changed else grid
|
| 2864 |
|
| 2865 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2866 |
def _normalize_fused_date_posted_amount_table(grid):
|
| 2867 |
"""
|
| 2868 |
Normalize 2-column OCR tables with fused header like:
|
|
@@ -2995,6 +3050,8 @@ def normalize_html_tables(text: str) -> str:
|
|
| 2995 |
grid = _normalize_double_desc_amount_header_table(grid)
|
| 2996 |
# Fix 14: same bank, 3-col OCR fused Beginning Balance + $0.00 amount column.
|
| 2997 |
grid = _normalize_ucb_three_col_beginning_balance_fusion(grid)
|
|
|
|
|
|
|
| 2998 |
|
| 2999 |
grid = _drop_truly_empty_columns(grid)
|
| 3000 |
grid = _merge_blank_header_text_columns(grid)
|
|
|
|
| 24 |
- Fix 13: collapse Date|Description|Amount|Description|Amount tables to 3 columns; fix fused
|
| 25 |
Beginning/Ending balance rows (UCB-style wide summary tables)
|
| 26 |
- Fix 14: UCB 3-col tables where Beginning Balance amount is fused into description and Amount is $0.00
|
| 27 |
+
- Fix 15: UCB (and similar) 3-col rows where Date+Description are fused in col1 and Amount sits in col2 with col3 empty
|
| 28 |
- Post-pass: drop later duplicate subset Date|Description|Amount tables (repeated deposit blocks)
|
| 29 |
"""
|
| 30 |
|
|
|
|
| 2864 |
return out if changed else grid
|
| 2865 |
|
| 2866 |
|
| 2867 |
+
def _fix_three_col_date_desc_amount_left_shift(grid):
|
| 2868 |
+
"""
|
| 2869 |
+
Fix 15: OCR shifts transaction rows one column left:
|
| 2870 |
+
col0 = "02/24/2025 ITM DEPOSIT", col1 = "$1,440.00", col2 = empty
|
| 2871 |
+
Expected: Date | Description | Amount
|
| 2872 |
+
Activates only on Date|Description|Amount headers and strict money in col1 with empty col2.
|
| 2873 |
+
"""
|
| 2874 |
+
if not grid or len(grid) < 2:
|
| 2875 |
+
return grid
|
| 2876 |
+
|
| 2877 |
+
def _tight(s):
|
| 2878 |
+
return re.sub(r"\s+", "", str(s or "").strip().lower())
|
| 2879 |
+
|
| 2880 |
+
h0 = [str(c or "").strip() for c in grid[0]]
|
| 2881 |
+
if len(h0) < 3:
|
| 2882 |
+
return grid
|
| 2883 |
+
if _tight(h0[0]) != "date" or _tight(h0[1]) != "description" or _tight(h0[2]) != "amount":
|
| 2884 |
+
return grid
|
| 2885 |
+
|
| 2886 |
+
date_then_desc = re.compile(
|
| 2887 |
+
r"^(\d{1,2}/\d{1,2}/\d{2,4})\s+(.+)$"
|
| 2888 |
+
)
|
| 2889 |
+
money_re = re.compile(r"^-?\$?\d{1,3}(?:,\d{3})*(?:\.\d{2})-?$")
|
| 2890 |
+
|
| 2891 |
+
out = [list(grid[0])]
|
| 2892 |
+
changed = False
|
| 2893 |
+
for row in grid[1:]:
|
| 2894 |
+
cells = [str(c or "").strip() for c in row]
|
| 2895 |
+
while len(cells) < 3:
|
| 2896 |
+
cells.append("")
|
| 2897 |
+
c0, c1, c2 = cells[0], cells[1], cells[2]
|
| 2898 |
+
if not c0:
|
| 2899 |
+
out.append([c0, c1, c2])
|
| 2900 |
+
continue
|
| 2901 |
+
m = date_then_desc.match(c0)
|
| 2902 |
+
if not m:
|
| 2903 |
+
out.append([c0, c1, c2])
|
| 2904 |
+
continue
|
| 2905 |
+
desc_part = (m.group(2) or "").strip()
|
| 2906 |
+
if not desc_part:
|
| 2907 |
+
out.append([c0, c1, c2])
|
| 2908 |
+
continue
|
| 2909 |
+
if not (c1 and money_re.match(c1.strip())):
|
| 2910 |
+
out.append([c0, c1, c2])
|
| 2911 |
+
continue
|
| 2912 |
+
if c2 and str(c2).strip():
|
| 2913 |
+
out.append([c0, c1, c2])
|
| 2914 |
+
continue
|
| 2915 |
+
out.append([m.group(1).strip(), desc_part, c1.strip()])
|
| 2916 |
+
changed = True
|
| 2917 |
+
|
| 2918 |
+
return out if changed else grid
|
| 2919 |
+
|
| 2920 |
+
|
| 2921 |
def _normalize_fused_date_posted_amount_table(grid):
|
| 2922 |
"""
|
| 2923 |
Normalize 2-column OCR tables with fused header like:
|
|
|
|
| 3050 |
grid = _normalize_double_desc_amount_header_table(grid)
|
| 3051 |
# Fix 14: same bank, 3-col OCR fused Beginning Balance + $0.00 amount column.
|
| 3052 |
grid = _normalize_ucb_three_col_beginning_balance_fusion(grid)
|
| 3053 |
+
# Fix 15: "Deposits (continued)" etc. — date+desc in col1, amount in col2, empty col3.
|
| 3054 |
+
grid = _fix_three_col_date_desc_amount_left_shift(grid)
|
| 3055 |
|
| 3056 |
grid = _drop_truly_empty_columns(grid)
|
| 3057 |
grid = _merge_blank_header_text_columns(grid)
|