Invoice generation in SaaS applications doesn’t have to be tedious. With reportgen.io, you can automate the entire process, offering dynamic, scalable, and secure solutions. Whether you're working on a single invoice or handling bulk generation, reportgen.io’s modern API is built to make developers’ lives easier.
This guide walks you through the steps of integrating reportgen.io into your SaaS application for dynamic invoice generation, complete with advanced templating and efficient API calls.
Step 1: Define a Dynamic Template with Conditional Logic
Invoices are more than just a list of numbers; they must reflect accurate calculations, dynamic line items, and conditional elements like VAT. With reportgen.io, you can use templating engines such as EJS to create powerful, flexible templates.
Here’s an example template that:
- Iterates through line items dynamically.
- Calculates VAT conditionally based on the input percentage.
- Includes subtotals and totals.
EJS Template Example
<html>
<body>
<h1>Invoice for <%= CustomerName %></h1>
<table border="1" style="border-collapse: collapse; width: 100%;">
<thead>
<tr>
<th>Description</th>
<th>Quantity</th>
<th>Price</th>
<th>Subtotal</th>
</tr>
</thead>
<tbody>
<% LineItems.forEach(item => { %>
<tr>
<td><%= item.description %></td>
<td><%= item.quantity %></td>
<td><%= item.price.toFixed(2) %></td>
<td><%= (item.quantity * item.price).toFixed(2) %></td>
</tr>
<% }); %>
</tbody>
</table>
<p>Subtotal: $<%= Subtotal.toFixed(2) %></p>
<% if (VATPercentage > 0) { %>
<p>VAT (<%= (VATPercentage * 100).toFixed(1) %>%): $<%= (Subtotal * VATPercentage).toFixed(2) %></p>
<% } %>
<p><strong>Total: $<%= Total.toFixed(2) %></strong></p>
</body>
</html>
This template ensures flexibility and clarity, allowing you to dynamically populate all values, including VAT percentages and line items.
Step 2: Write Python Functions
To make the implementation reusable and scalable, we’ll create functions that:
- Dynamically calculate invoice data.
- Handle synchronous PDF generation for immediate needs.
- Use asynchronous generation for bulk operations.
Step 2.1: A Function to Generate Dynamic Data
This function calculates the subtotal, VAT, and total dynamically based on the provided line items and VAT percentage.
def generate_invoice_data(customer_name, line_items, vat_percentage):
subtotal = sum(item['quantity'] * item['price'] for item in line_items)
vat_amount = subtotal * vat_percentage
total = subtotal + vat_amount
return {
"CustomerName": customer_name,
"LineItems": line_items,
"Subtotal": subtotal,
"VATPercentage": vat_percentage,
"Total": total
}
Step 2.2: A Function for Synchronous PDF Generation
Synchronous generation is best for smaller workloads or when you need the invoice immediately. This function sends the request and saves the PDF locally.
import requests
def generate_pdf_sync(api_key, template, data):
url = "https://reportgen.io/api/v1/generate-pdf-sync"
headers = {"X-API-Key": f"{api_key}", "Content-Type": "application/json"}
payload = {"html_template": template, "data": data, "engine": "ejs"}
response = requests.post(url, json=payload, headers=headers)
if response.status_code == 200:
with open("invoice_sync.pdf", "wb") as file:
file.write(response.content)
print("Invoice generated successfully as 'invoice_sync.pdf'.")
else:
print(f"Failed to generate PDF: {response.status_code} - {response.text}")
Step 2.3: A Function for Asynchronous PDF Generation
Asynchronous generation is ideal for handling bulk operations or when the task isn’t time-sensitive. This function queues the PDF generation and returns a report_id
for tracking.
def generate_pdf_async(api_key, template, data):
url = "https://reportgen.io/api/v1/generate-pdf-async"
headers = {"X-API-Key": f"{api_key}", "Content-Type": "application/json"}
payload = {"html_template": template, "data": data, "engine": "ejs"}
response = requests.post(url, json=payload, headers=headers)
if response.status_code == 200:
report_id = response.json().get("report_id")
print(f"Invoice queued successfully. Report ID: {report_id}")
return report_id
else:
print(f"Failed to queue PDF generation: {response.status_code} - {response.text}")
Step 3: Usage
Example Input
Here’s an example of how to call the functions with dynamic data, but it doesn't include the functions. You can simply copy them over.
api_key = "YOUR_API_KEY"
template = """
<html>
<body>
<h1>Invoice for <%= CustomerName %></h1>
<table border="1" style="border-collapse: collapse; width: 100%;">
<thead>
<tr>
<th>Description</th>
<th>Quantity</th>
<th>Price</th>
<th>Subtotal</th>
</tr>
</thead>
<tbody>
<% LineItems.forEach(item => { %>
<tr>
<td><%= item.description %></td>
<td><%= item.quantity %></td>
<td><%= item.price.toFixed(2) %></td>
<td><%= (item.quantity * item.price).toFixed(2) %></td>
</tr>
<% }); %>
</tbody>
</table>
<p>Subtotal: $<%= Subtotal.toFixed(2) %></p>
<% if (VATPercentage > 0) { %>
<p>VAT (<%= (VATPercentage * 100).toFixed(1) %>%): $<%= (Subtotal * VATPercentage).toFixed(2) %></p>
<% } %>
<p><strong>Total: $<%= Total.toFixed(2) %></strong></p>
</body>
</html>
"""
line_items = [
{"description": "DevOps monthly", "quantity": 1, "price": 5000.0},
{"description": "SysAdmin hours", "quantity": 10, "price": 35.0},
]
vat_percentage = 0.22 # Dynamic VAT percentage
customer_name = "John Doe"
data = generate_invoice_data(customer_name, line_items, vat_percentage)
# Sync
generate_pdf_sync(api_key, template, data)
# Or async:
report_id = generate_pdf_async(api_key, template, data)
print(f"Track your report status using this ID: {report_id}")
Why Choose reportgen.io?
- Dynamic Powerhouse: Unlike competitors, reportgen.io empowers you to generate complex documents with dynamic data, conditional logic, and flexibility in templates.
- Built for Scalability: Handle large volumes of PDF generation asynchronously without performance bottlenecks.
- Developer-Centric: We prioritize ease of use, robust documentation, and advanced templating options like EJS and Handlebars.
- Secure & Modern: With Cloudflare-backed security and data privacy, reportgen.io ensures your sensitive data is always protected.
- Competitive Edge: reportgen.io offers simplicity without compromising on advanced features and flexibility, giving you the best of both worlds.
Next Steps
- Implement integrations with services like Novu.co for automated invoice emailing.
- Attach payment links using Stripe or PayPal APIs for seamless transactions.
- Enhance workflows by incorporating invoice tracking and CRM updates with HubSpot or Salesforce.
Start leveraging reportgen.io to elevate your SaaS application's automation game today! 🚀
đź’» Source code can be found on GitHub
👉 Ready to make your PDFs not suck? Try it free at reportgen.io
You get 150 reports for free each month, no credit card required.
👥 Have a better way to write this code? Drop it in the comments below. I always love a good code review!
Top comments (0)