38686-vm/docs/plans/2026-02-22-expense-receipt-design.md
Konrad du Plessis fc63d972b1 Add expense receipt feature: form, view, templates, email + PDF
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>
2026-02-22 21:38:14 +02:00

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_name
  • items related_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