# 19 — Finance & Accounting **Status**: Not Started **Depends On**: 05 — Delivery Ride Execution, 06 — Sale Ride Execution, 18 — Returns & Claims Management --- ## Goal Covers [mainPlan.md §13](./mainPlan.md#13-finance--accounting) beyond what [06_sale_ride.md](./06_sale_ride.md) already scoped for field invoices (`createInvoice`/`recordPayment` there are the van-sale-specific case; this step is the general warehouse-fulfilled-order invoicing path plus GL posting and reporting). --- ## Background / Context `convertOrderToInvoice` is referenced from [05_delivery_ride.md](./05_delivery_ride.md) but has no home until this step. There is no invoice, payment, or GL entity for warehouse-fulfilled (non-field-sale) orders today. --- ## Data Model Changes ### Invoice `OrderId` (nullable if it originates from a field invoice instead), `StoreId`, `TotalAmount`, `TaxAmount`, `Status` (`Issued`, `PartiallyPaid`, `Paid`), `IssuedAt`. ### Payment `InvoiceId`, `Amount`, `Method`, `CollectedAt` — same shape as the `Payment Record` in [06_sale_ride.md](./06_sale_ride.md); consider whether to unify into one table keyed by a generic `InvoiceId` covering both field invoices and warehouse invoices. ### GL Posting `TransactionId`, `Account`, `DebitAmount`, `CreditAmount`, `PostedAt`. --- ## API Endpoints | Function reference | Endpoint intent | |---|---| | `createInvoice(orderId)` | `POST /api/orders/{id}/invoice` — the warehouse-fulfilled counterpart to [06_sale_ride.md](./06_sale_ride.md)'s field invoice creation | | `recordPayment(invoiceId, amount, method)` | Current implemented path is `POST /api/sales/{saleId:guid}/payments` for field-sale collections; `POST /api/invoices/{id}/payments` remains the target endpoint for this future invoice-based finance step | | `postToGeneralLedger(transactionId)` | Internal — triggered on invoice/payment/credit-note events | | `generateTaxInvoice(invoiceId, jurisdiction)` | `GET /api/invoices/{id}/tax-invoice?jurisdiction=...` | | `getFinancialReport(entityId, period, reportType)` | `GET /api/finance/reports?entityId=...&period=...&reportType=...` | --- ## Business Rules - `Store.OutstandingBalance` (from [12_store_management.md](./12_store_management.md)) is maintained by this step's invoice/payment events, not edited directly. - `postToGeneralLedger` must be idempotent per `TransactionId` — replays must not double-post. --- ## Open Questions - Should field invoices ([06_sale_ride.md](./06_sale_ride.md)) and warehouse invoices share one `Invoice` table, or stay as separate entities that both feed the same GL posting logic? - Is e-invoicing (`generateTaxInvoice` for a specific jurisdiction like GST/VAT) an actual near-term requirement, or speculative until a specific market is targeted? --- ## Implementation Notes > Fill this section in during planning discussion before writing any code.