File size: 2,778 Bytes
0ebef7d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
"""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()