# Invoice Pattern Skill

This skill defines the standard for implementing invoice-like forms (Invoice, Estimate, Job Card, Purchase Order, Bill, etc.) in the carage-erp dashboard. All such forms must follow this pattern for layout, discount/tax handling, and summary calculation. The current Invoice form is the canonical reference.

---

## 1. Layout
- **Two-column grid:**
  - **Main column (9/12):**
    - Subject, invoice number/title
    - Status select, Discount Type select
    - Conditional Transaction Discount field
    - Line item selectors: Parts, Services, Expense Items (with optional line-level discount)
    - Notes, Terms & Conditions
    - Submit button
  - **Sidebar column (3/12):**
    - Invoice date, Due date
    - Customer, Vehicle selectors
    - Tax select (see below)
    - Department, Payment Terms, Invoice Sequence, Insurance fields
    - Summary card (see below)

## 2. Discount Implementation
- **Discount Type:**
  - Field: `discount` (enum: 'no', 'line_item_level', 'transaction_level')
  - Select field in main column
- **Transaction-level Discount:**
  - Field: `discount_amount` (number)
  - Only shown when `discount === "transaction_level"`
- **Line-level Discount:**
  - Each line item (parts, services, expenses) has `discount_amount` field
  - Only shown when `discount === "line_item_level"`
- **Payload Mapping:**
  - Only include `discount_amount` at transaction level if `discount === "transaction_level"`
  - Only include per-line `discount_amount` if `discount === "line_item_level"`

## 3. Tax Type Implementation
- **Tax Field:**
  - Field: `tax` (relationFieldSchema: `{ value: string, label: string } | null`)
  - Uses `RhfAsyncSelectField` in sidebar
  - `mapOption`: `{ value: String(item.id), label: `${item.title} (${item.rate}%)` }`
  - The selected tax's rate is parsed from the label string in the summary (regex: `/\((\d+(?:\.\d+)?)%\)/`)

## 4. Summary Implementation
- **Summary Card:**
  - Always rendered in the sidebar below the Details card
  - Uses `InvoiceFormSummary` (form-aware adapter)
  - `InvoiceFormSummary` flattens all line items, reads discount/tax fields, and passes them to `useDocumentTotals` hook
  - `useDocumentTotals` (pure hook) computes subtotal, discounts, tax, and total
  - `DocumentTotalsSummary` (pure display component) renders the summary

---

## Reference: Invoice Form
- See `apps/dashboard/modules/invoices/invoice-form.tsx` for the canonical implementation.
- Schema: `apps/dashboard/modules/invoices/invoice.schema.ts`
- Summary logic: `apps/dashboard/modules/invoices/invoice-form-summary.tsx`, `shared/hooks/use-document-totals.ts`, `shared/components/document-totals-summary.tsx`

---

## Required for All Invoice-like Forms
- Follow the above layout and field conventions
- Use the same discount/tax logic and summary calculation
- Use the same field and payload mapping patterns
- Use the same summary component structure

---

## Example: Tax Field (in sidebar)
```tsx
<RhfAsyncSelectField
  name="tax"
  label="Tax"
  placeholder="Select tax rate"
  queryKey={[TAX_ROUTES.INDEX]}
  listFn={() => api.taxes.list()}
  mapOption={(item: any) => ({
    value: String(item.id),
    label: item.title ? `${item.title} (${item.rate}%)` : `#${item.id}`,
  })}
  {...STORE_OBJECT}
/>
```

## Example: Discount Type Select (in main column)
```tsx
<RhfSelectField name="discount" label="Discount Type" options={DISCOUNT_OPTIONS} />
```

## Example: Summary Card
```tsx
<div className="mt-4">
  <InvoiceFormSummary />
</div>
```
