Straight port from V2 adapted for V5 field names. Creates expense receipts with dynamic line items, VAT calculation (Included/Excluded/ None at 15%), and emails HTML + PDF to Spark Receipt. Uses lazy xhtml2pdf import to avoid crashing if not installed on server. Files: forms.py (ExpenseReceiptForm + FormSet), views.py (create_receipt), create_receipt.html, receipt_email.html, receipt_pdf.html, urls.py, base.html Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1.2 KiB
1.2 KiB
Expense Receipt Feature — Design Doc
Date: 2026-02-22
Summary
Straight port of V2's expense receipt feature to V5. Single-page form at /receipts/create/ where admins and supervisors record business expenses with dynamic line items and VAT calculation. Automatically emails HTML + PDF receipt to Spark Receipt.
Files
| File | Action |
|---|---|
core/forms.py |
Add ExpenseReceiptForm + ExpenseLineItemFormSet |
core/views.py |
Add create_receipt() view |
core/urls.py |
Add /receipts/create/ route |
core/templates/core/create_receipt.html |
Create form page |
core/templates/core/email/receipt_email.html |
Create email template |
core/templates/core/pdf/receipt_pdf.html |
Create PDF template |
core/templates/base.html |
Add Receipts navbar link |
V5 Naming Adaptations
vendor->vendor_name,product->product_nameitemsrelated_name ->line_items- Choice values: Title Case ('Included') not UPPERCASE ('INCLUDED')
- Lazy xhtml2pdf import (same as payslip)
VAT Logic (15% SA rate)
- Included: Total = sum, Subtotal = Total / 1.15, VAT = Total - Subtotal
- Excluded: Subtotal = sum, VAT = Subtotal * 0.15, Total = Subtotal + VAT
- None: Subtotal = Total = sum, VAT = 0