120 lines
4.3 KiB
Python
120 lines
4.3 KiB
Python
from fpdf import FPDF
|
|
|
|
class InvoicePDF(FPDF):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.set_auto_page_break(auto=True, margin=15)
|
|
self.add_page()
|
|
self.set_font("Arial", size=12)
|
|
|
|
def header(self):
|
|
self.set_font("Arial", style="B", size=14)
|
|
self.cell(0, 10, "Invoice", border=False, ln=True, align="C")
|
|
self.ln(10)
|
|
|
|
def footer(self):
|
|
self.set_y(-30)
|
|
self.set_font("Arial", size=10)
|
|
self.cell(0, 10, f"Page {self.page_no()}", align="C")
|
|
|
|
def add_invoice_details(self, details):
|
|
self.set_font("Arial", size=12)
|
|
self.cell(100, 10, f"Invoice Number: {details['invoice_number']}")
|
|
self.cell(0, 10, f"Date: {details['date']}", ln=True)
|
|
self.cell(100, 10, f"Due Date: {details['due_date']}", ln=True)
|
|
self.ln(10)
|
|
|
|
def add_client_details(self, client):
|
|
self.set_font("Arial", style="B", size=12)
|
|
self.cell(0, 10, "Bill To:", ln=True)
|
|
self.set_font("Arial", size=12)
|
|
self.cell(0, 10, client['name'], ln=True)
|
|
self.cell(0, 10, client['address'], ln=True)
|
|
self.cell(0, 10, client['email'], ln=True)
|
|
self.ln(10)
|
|
|
|
def add_items_table(self, items):
|
|
self.set_font("Arial", style="B", size=12)
|
|
self.cell(80, 10, "Item Description", border=1, align="C")
|
|
self.cell(30, 10, "Quantity", border=1, align="C")
|
|
self.cell(40, 10, "Unit Price", border=1, align="C")
|
|
self.cell(40, 10, "Total", border=1, align="C", ln=True)
|
|
|
|
self.set_font("Arial", size=12)
|
|
for item in items:
|
|
self.cell(80, 10, item["description"], border=1)
|
|
self.cell(30, 10, str(item["quantity"]), border=1, align="C")
|
|
self.cell(40, 10, f"${item['unit_price']:.2f}", border=1, align="R")
|
|
self.cell(40, 10, f"${item['total']:.2f}", border=1, align="R", ln=True)
|
|
|
|
self.ln(10)
|
|
|
|
def add_totals(self, subtotal, tax_rate, tax, total_due):
|
|
self.set_font("Arial", style="B", size=12)
|
|
self.cell(0, 10, f"Subtotal: ${subtotal:.2f}", ln=True, align="R")
|
|
self.cell(0, 10, f"Tax ({tax_rate}%): ${tax:.2f}", ln=True, align="R")
|
|
self.cell(0, 10, f"Total Due: ${total_due:.2f}", ln=True, align="R")
|
|
|
|
def add_payment_details(self, payment_details):
|
|
self.ln(10)
|
|
self.set_font("Arial", style="B", size=12)
|
|
self.cell(0, 10, "Payment Details:", ln=True)
|
|
self.set_font("Arial", size=12)
|
|
self.cell(0, 10, f"Bank Name: {payment_details['bank_name']}", ln=True)
|
|
self.cell(0, 10, f"Account Number: {payment_details['account_number']}", ln=True)
|
|
self.cell(0, 10, f"SWIFT Code: {payment_details['swift_code']}", ln=True)
|
|
|
|
def add_signature(self, signature_path, signer_name):
|
|
self.ln(20)
|
|
self.cell(0, 10, "Authorized Signature:", ln=True)
|
|
# Add signature image
|
|
self.image(signature_path, x=10, y=self.get_y(), w=50) # Adjust `x`, `y`, `w` as needed
|
|
self.ln(30)
|
|
# Add signer name
|
|
self.set_font("Arial", style="I", size=12)
|
|
self.cell(0, 10, signer_name, ln=True)
|
|
|
|
# Example data
|
|
invoice_details = {
|
|
"invoice_number": "INV-12345",
|
|
"date": "2024-12-29",
|
|
"due_date": "2025-01-15",
|
|
}
|
|
|
|
client_details = {
|
|
"name": "John Doe",
|
|
"address": "123 Example St, City, Country",
|
|
"email": "john.doe@example.com",
|
|
}
|
|
|
|
items = [
|
|
{"description": "Web Development", "quantity": 1, "unit_price": 1500, "total": 1500},
|
|
{"description": "Hosting", "quantity": 12, "unit_price": 10, "total": 120},
|
|
]
|
|
|
|
subtotal = 1620
|
|
tax_rate = 5
|
|
tax = 81
|
|
total_due = 1701
|
|
|
|
payment_details = {
|
|
"bank_name": "Example Bank",
|
|
"account_number": "123456789",
|
|
"swift_code": "EXAMP123",
|
|
}
|
|
|
|
signature_path = "/content/signature.png" # Path to the signature image
|
|
signer_name = "Jane Smith"
|
|
|
|
# Generate PDF
|
|
pdf = InvoicePDF()
|
|
pdf.add_invoice_details(invoice_details)
|
|
pdf.add_client_details(client_details)
|
|
pdf.add_items_table(items)
|
|
pdf.add_totals(subtotal, tax_rate, tax, total_due)
|
|
pdf.add_payment_details(payment_details)
|
|
pdf.add_signature(signature_path, signer_name)
|
|
pdf.output("invoice_with_signature.pdf")
|
|
|
|
print("Invoice with signature generated as 'invoice_with_signature.pdf'")
|