Invoice / pdf_export.py
Corin1998's picture
Upload 7 files
9f4d112 verified
# pdf_export.py
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import mm
from reportlab.lib import colors
from reportlab.pdfgen import canvas
from reportlab.platypus import Table, TableStyle, SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
def write_invoice_pdf(path, invoice, items, customer, totals):
doc = SimpleDocTemplate(path, pagesize=A4,
rightMargin=20*mm, leftMargin=20*mm,
topMargin=20*mm, bottomMargin=20*mm)
styles = getSampleStyleSheet()
story = []
title = "請求書" if invoice.status != "draft" else "請求書(下書き)"
story.append(Paragraph(title, styles["Title"]))
story.append(Spacer(1, 6))
# ヘッダ情報
header = [
["請求書番号", str(invoice.id)],
["発行日", str(invoice.issue_date)],
["支払期日", str(invoice.due_date or "記載なし")],
["ステータス", invoice.status],
]
t = Table(header, colWidths=[30*mm, 120*mm])
t.setStyle(TableStyle([("BOX", (0,0), (-1,-1), 0.25, colors.black),
("BACKGROUND", (0,0), (0,-1), colors.whitesmoke),
("VALIGN",(0,0),(-1,-1),"MIDDLE")]))
story.append(t)
story.append(Spacer(1, 8))
# 請求先
to_table = [
["請求先", customer.name if customer else f"Customer #{invoice.customer_id}"],
["住所", (customer.address or "") if customer else ""],
["メール", (customer.email or "") if customer else ""],
]
tt = Table(to_table, colWidths=[30*mm, 120*mm])
tt.setStyle(TableStyle([("BOX", (0,0), (-1,-1), 0.25, colors.black),
("BACKGROUND", (0,0), (0,-1), colors.whitesmoke)]))
story.append(tt)
story.append(Spacer(1, 8))
# 明細
data = [["内容", "数量", "単価", "税率", "金額"]]
for it in items:
line = it.quantity * it.unit_price
data.append([it.description, f"{it.quantity}", f"{it.unit_price:.2f}", f"{it.tax_rate*100:.0f}%", f"{line:.2f}"])
tbl = Table(data, colWidths=[70*mm, 20*mm, 25*mm, 20*mm, 35*mm])
tbl.setStyle(TableStyle([
("GRID", (0,0), (-1,-1), 0.25, colors.black),
("BACKGROUND", (0,0), (-1,0), colors.lightgrey),
("ALIGN", (1,1), (-1,-1), "RIGHT"),
("ALIGN", (0,0), (0,-1), "LEFT"),
]))
story.append(tbl)
story.append(Spacer(1, 8))
# 合計
sum_table = [
["小計", f"{totals.subtotal:.2f}"],
["税額", f"{totals.tax:.2f}"],
["合計", f"{totals.total:.2f}"],
]
st = Table(sum_table, colWidths=[40*mm, 35*mm])
st.setStyle(TableStyle([
("GRID", (0,0), (-1,-1), 0.25, colors.black),
("BACKGROUND", (0,2), (-1,2), colors.yellow),
("ALIGN", (1,0), (1,-1), "RIGHT"),
]))
story.append(st)
# 備考
if invoice.notes:
story.append(Spacer(1, 8))
story.append(Paragraph(f"備考:{invoice.notes}", styles["Normal"]))
doc.build(story)