exportstatement / tests /generators /make_multipage_bf.py
rudrahf's picture
Claude Opus 4.8 (1M context)
Initial commit β€” Export Bank Statement extractor (FastAPI)
0ebef7d
Raw History Blame Contribute Delete
2.78 kB
"""Repro fixture: ONE statement spread over several pages, repeating its account
header and a 'Balance Brought Forward' line on every page (as many real bank
PDFs β€” incl. the Indian statement that exposed this β€” do).
The engine must treat this as a SINGLE statement, not one-per-page.
"""
from pathlib import Path
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import (
PageBreak,
Paragraph,
SimpleDocTemplate,
Spacer,
Table,
TableStyle,
)
OUT = Path(__file__).resolve().parents[1] / "fixtures" / "multipage_bf.pdf"
def money(cents: int) -> str:
return f"{cents / 100:,.2f}"
def main():
styles = getSampleStyleSheet()
rows_per_page, pages = 10, 3
opening = 5_000_000
running = opening
credits = debits = 0
txn = 0
story = []
for p in range(pages):
# repeated per-page header β€” the over-sectioning trigger
story.append(Paragraph("Account: 555000111 - ACME CURRENT ACCOUNT", styles["Normal"]))
story.append(Paragraph("Account Holder: ACME TRADING LTD", styles["Normal"]))
if p == 0:
story.append(Paragraph(f"Opening Balance: {money(opening)}", styles["Normal"]))
else:
story.append(Paragraph(f"Balance Brought Forward: {money(running)}", styles["Normal"]))
story.append(Spacer(1, 8))
data = [["Date", "Description", "Debit", "Credit", "Balance"]]
for _ in range(rows_per_page):
txn += 1
if txn % 3 == 0:
amt = 150_000
running += amt
credits += amt
data.append([f"2024-07-{txn:02d}", f"DEPOSIT {txn}", "", money(amt), money(running)])
else:
amt = 40_000
running -= amt
debits += amt
data.append([f"2024-07-{txn:02d}", f"PAYMENT {txn}", money(amt), "", money(running)])
t = Table(data, repeatRows=1)
t.setStyle(TableStyle([
("GRID", (0, 0), (-1, -1), 0.5, colors.grey),
("BACKGROUND", (0, 0), (-1, 0), colors.lightgrey),
("FONTSIZE", (0, 0), (-1, -1), 8),
]))
story.append(t)
if p == pages - 1:
story.append(Spacer(1, 8))
story.append(Paragraph(f"Closing Balance: {money(running)}", styles["Normal"]))
story.append(PageBreak())
SimpleDocTemplate(str(OUT), pagesize=A4).build(story)
print(f"wrote {OUT}")
print(f"{txn} txns across {pages} pages β€” ONE logical statement")
print(f"opening {money(opening)} + credits {money(credits)} - debits {money(debits)} = closing {money(running)}")
if __name__ == "__main__":
main()