rehan953 commited on
Commit
1729896
·
verified ·
1 Parent(s): 882ba3a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -4
app.py CHANGED
@@ -99,6 +99,71 @@ def _build_table_from_entries(entries: List[dict]) -> str:
99
  return "\n".join(table)
100
 
101
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  def _normalize_transactions(text: str) -> str:
103
  """
104
  Convert loose transaction lines into structured markdown tables using:
@@ -119,8 +184,9 @@ def _normalize_transactions(text: str) -> str:
119
  if in_section and (line.strip() == "" or line.strip().startswith("Subtotal")):
120
  if table_buffer:
121
  clean_rows = []
122
- for raw in table_buffer:
123
- normalized = " ".join(raw.split())
 
124
  match = pattern.search(normalized)
125
  if match:
126
  date, desc, amount = match.groups()
@@ -143,8 +209,9 @@ def _normalize_transactions(text: str) -> str:
143
 
144
  if table_buffer:
145
  clean_rows = []
146
- for raw in table_buffer:
147
- normalized = " ".join(raw.split())
 
148
  match = pattern.search(normalized)
149
  if match:
150
  date, desc, amount = match.groups()
 
99
  return "\n".join(table)
100
 
101
 
102
+ def _is_transaction_start(line: str) -> bool:
103
+ return bool(re.match(r"\d{2}/\d{2}", line.strip()))
104
+
105
+
106
+ def _ends_with_amount(text: str) -> bool:
107
+ return bool(re.search(r"\d{1,3}(?:,\d{3})*\.\d{2}$", text.strip()))
108
+
109
+
110
+ def _is_noise_line(line: str) -> bool:
111
+ s = line.strip().lower()
112
+ if not s:
113
+ return True
114
+ if s == "---page-separator---":
115
+ return True
116
+ if "call 1-800-937-2000" in s:
117
+ return True
118
+ if s in ("<table border=\"1\"><tr><td></td></tr></table>", "<table><tr><td></td></tr></table>"):
119
+ return True
120
+ return False
121
+
122
+
123
+ def _merge_transaction_lines(rows: List[str]) -> List[str]:
124
+ """
125
+ Step 1/2: Merge multiline OCR rows into single transaction rows.
126
+ A new row begins when a line starts with MM/DD.
127
+ """
128
+ merged: List[str] = []
129
+ current = ""
130
+
131
+ for raw in rows:
132
+ line = " ".join(raw.strip().split())
133
+ if not line or _is_noise_line(line):
134
+ continue
135
+
136
+ if _is_transaction_start(line):
137
+ if current:
138
+ merged.append(current.strip())
139
+ current = line
140
+ else:
141
+ if current:
142
+ current += " " + line
143
+ else:
144
+ current = line
145
+
146
+ if current:
147
+ merged.append(current.strip())
148
+
149
+ return merged
150
+
151
+
152
+ def _repair_orphan_amounts(rows: List[str]) -> List[str]:
153
+ """
154
+ Step 3: Attach lines without ending amount to prior transaction line when possible.
155
+ """
156
+ fixed: List[str] = []
157
+ for line in rows:
158
+ if _ends_with_amount(line):
159
+ fixed.append(line)
160
+ elif fixed:
161
+ fixed[-1] = f"{fixed[-1]} {line}".strip()
162
+ else:
163
+ fixed.append(line)
164
+ return fixed
165
+
166
+
167
  def _normalize_transactions(text: str) -> str:
168
  """
169
  Convert loose transaction lines into structured markdown tables using:
 
184
  if in_section and (line.strip() == "" or line.strip().startswith("Subtotal")):
185
  if table_buffer:
186
  clean_rows = []
187
+ merged_rows = _merge_transaction_lines(table_buffer)
188
+ repaired_rows = _repair_orphan_amounts(merged_rows)
189
+ for normalized in repaired_rows:
190
  match = pattern.search(normalized)
191
  if match:
192
  date, desc, amount = match.groups()
 
209
 
210
  if table_buffer:
211
  clean_rows = []
212
+ merged_rows = _merge_transaction_lines(table_buffer)
213
+ repaired_rows = _repair_orphan_amounts(merged_rows)
214
+ for normalized in repaired_rows:
215
  match = pattern.search(normalized)
216
  if match:
217
  date, desc, amount = match.groups()