fmard/pdf-api
0
1<!DOCTYPE html>2<html lang="en">3<head>4 <meta charset="UTF-8">5 <title>Proforma Invoice - {{ pi_number | default('PI-0001') }}</title>6 <style>7 * { margin: 0; padding: 0; box-sizing: border-box; }8 body {9 font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;10 padding: 40px;11 color: #1f2937;12 font-size: 13px;13 line-height: 1.5;14 }15 .header {16 display: flex;17 justify-content: space-between;18 align-items: flex-start;19 margin-bottom: 30px;20 padding-bottom: 20px;21 border-bottom: 3px solid #4f46e5;22 }23 .company-info h1 { font-size: 20px; color: #4f46e5; margin-bottom: 4px; }24 .company-info p { font-size: 12px; color: #6b7280; }25 .doc-title { text-align: right; }26 .doc-title h2 { font-size: 24px; color: #4f46e5; }27 .doc-title .subtitle {28 font-size: 11px;29 color: #6b7280;30 text-transform: uppercase;31 letter-spacing: 1px;32 margin-top: 2px;33 }34 .doc-title .number { font-size: 14px; font-weight: 600; margin-top: 4px; }35 .watermark {36 position: fixed;37 top: 50%;38 left: 50%;39 transform: translate(-50%, -50%) rotate(-30deg);40 font-size: 80px;41 color: rgba(79, 70, 229, 0.05);42 font-weight: 900;43 text-transform: uppercase;44 pointer-events: none;45 z-index: -1;46 }47 .parties {48 display: flex;49 justify-content: space-between;50 margin-bottom: 24px;51 gap: 40px;52 }53 .party-block { flex: 1; }54 .party-block h4 { font-size: 10px; text-transform: uppercase; color: #6b7280; margin-bottom: 6px; }55 .party-block p { margin-bottom: 2px; }56 .meta-bar {57 display: flex;58 gap: 30px;59 padding: 12px 16px;60 background: #eef2ff;61 border-radius: 6px;62 margin-bottom: 24px;63 }64 .meta-bar div span { display: block; font-size: 10px; color: #6b7280; text-transform: uppercase; }65 .meta-bar div strong { font-size: 13px; }66 table { width: 100%; border-collapse: collapse; margin-bottom: 20px; }67 thead th {68 background: #4f46e5;69 color: #fff;70 padding: 10px 12px;71 text-align: left;72 font-size: 11px;73 text-transform: uppercase;74 }75 thead th:nth-child(3), thead th:nth-child(4), thead th:last-child { text-align: right; }76 tbody td { padding: 10px 12px; border-bottom: 1px solid #e5e7eb; }77 tbody td:nth-child(3), tbody td:nth-child(4), tbody td:last-child { text-align: right; }78 tbody tr:nth-child(even) { background: #f9fafb; }79 .summary {80 display: flex;81 justify-content: flex-end;82 margin-bottom: 30px;83 }84 .summary-table { width: 280px; }85 .summary-table .row {86 display: flex;87 justify-content: space-between;88 padding: 6px 0;89 border-bottom: 1px solid #e5e7eb;90 font-size: 12px;91 }92 .summary-table .row.total {93 border-top: 2px solid #4f46e5;94 border-bottom: none;95 padding-top: 10px;96 font-size: 16px;97 font-weight: 700;98 color: #4f46e5;99 }100 .bank-details {101 margin-bottom: 24px;102 padding: 14px;103 background: #f9fafb;104 border-radius: 6px;105 border: 1px solid #e5e7eb;106 }107 .bank-details h4 { font-size: 11px; text-transform: uppercase; color: #6b7280; margin-bottom: 8px; }108 .bank-details p { font-size: 12px; margin-bottom: 2px; }109 .terms-section { margin-bottom: 20px; }110 .terms-section h4 { font-size: 11px; text-transform: uppercase; color: #6b7280; margin-bottom: 4px; }111 .terms-section p { font-size: 12px; color: #374151; }112 .notes { padding-top: 14px; border-top: 1px solid #e5e7eb; }113 .notes h4 { font-size: 11px; text-transform: uppercase; color: #6b7280; margin-bottom: 4px; }114 .notes p { font-size: 12px; color: #374151; }115 </style>116</head>117<body>118 <div class="watermark">Proforma</div>119 120 <div class="header">121 <div class="company-info">122 <h1>{{ company_name | default('Your Company Name') }}</h1>123 <p>{{ company_address | default('123 Business Street, City, Country') }}</p>124 </div>125 <div class="doc-title">126 <h2>Proforma Invoice</h2>127 <div class="subtitle">Not a tax invoice</div>128 <div class="number">#{{ pi_number | default('PI-0001') }}</div>129 </div>130 </div>131 132 <div class="parties">133 <div class="party-block">134 <h4>Bill To</h4>135 <p><strong>{{ client_name | default('Client Name') }}</strong></p>136 <p>{{ client_address | default('Client Address') }}</p>137 </div>138 </div>139 140 <div class="meta-bar">141 <div><span>PI Number</span><strong>{{ pi_number | default('PI-0001') }}</strong></div>142 <div><span>Date</span><strong>{{ date | default('2025-01-01') }}</strong></div>143 <div><span>Payment Terms</span><strong>{{ payment_terms | default('Net 30') }}</strong></div>144 </div>145 146 <table>147 <thead>148 <tr>149 <th>#</th>150 <th>Description</th>151 <th>Qty</th>152 <th>Price</th>153 <th>Amount</th>154 </tr>155 </thead>156 <tbody>157 {% set ns = namespace(subtotal=0) %}158 {% for item in items | default([{'description': 'Product/Service', 'quantity': 1, 'price': 1000}]) %}159 {% set line_total = item.quantity * item.price %}160 {% set ns.subtotal = ns.subtotal + line_total %}161 <tr>162 <td>{{ loop.index }}</td>163 <td>{{ item.description }}</td>164 <td>{{ item.quantity }}</td>165 <td>{{ "{:,.2f}".format(item.price) }}</td>166 <td>{{ "{:,.2f}".format(line_total) }}</td>167 </tr>168 {% endfor %}169 </tbody>170 </table>171 172 {% set tax = ns.subtotal * (tax_rate | default(0)) / 100 %}173 {% set shipping = shipping_cost | default(0) %}174 {% set grand_total = ns.subtotal + tax + shipping %}175 176 <div class="summary">177 <div class="summary-table">178 <div class="row"><span>Subtotal</span><span>{{ "{:,.2f}".format(ns.subtotal) }}</span></div>179 {% if tax_rate | default(0) > 0 %}180 <div class="row"><span>Tax ({{ tax_rate }}%)</span><span>{{ "{:,.2f}".format(tax) }}</span></div>181 {% endif %}182 {% if shipping > 0 %}183 <div class="row"><span>Shipping</span><span>{{ "{:,.2f}".format(shipping) }}</span></div>184 {% endif %}185 <div class="row total"><span>Total</span><span>{{ "{:,.2f}".format(grand_total) }}</span></div>186 </div>187 </div>188 189 {% if bank_details | default('') %}190 <div class="bank-details">191 <h4>Bank Details</h4>192 <p>{{ bank_details }}</p>193 </div>194 {% endif %}195 196 {% if payment_terms | default('') %}197 <div class="terms-section">198 <h4>Payment Terms</h4>199 <p>{{ payment_terms }}</p>200 </div>201 {% endif %}202 203 {% if notes | default('') %}204 <div class="notes">205 <h4>Notes</h4>206 <p>{{ notes }}</p>207 </div>208 {% endif %}209</body>210</html>