Files
bellsystems-cp/.claude/crm-step-07.md

72 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CRM Step 07 — Frontend: Orders Module
## Context
Read `.claude/crm-build-plan.md` for full context, data models, and IMPORTANT NOTES.
Steps 0106 must be complete.
## Task
Build the Orders section.
## Files to create
### `frontend/src/crm/orders/OrderList.jsx`
- Fetch `GET /api/crm/orders` (query: status, payment_status)
- Table: Order #, Customer name (resolve from customer_id via separate fetch or denormalize), Status badge, Total, Payment status, Date
- Filter dropdowns: Status, Payment Status
- "New Order" button → `/crm/orders/new`
- Row click → `/crm/orders/:id`
### `frontend/src/crm/orders/OrderForm.jsx`
Create/edit. Receives `orderId` prop and optional `customerId` from query param.
**Sections:**
1. **Customer** — searchable dropdown (fetch `/api/crm/customers`). Shows name + organization.
2. **Order Info** — order_number (auto, editable), status (dropdown), currency
3. **Items** — dynamic list. Each item:
- type selector: console_device | product | freetext
- product: dropdown from `/api/crm/products` (auto-fills product_name, unit_price)
- console_device: text input for device_id + label
- freetext: description text input
- quantity (number), unit_price (number), serial_numbers (comma-separated)
- Remove row button
- Add Item button
4. **Pricing** — show computed subtotal (sum of qty * unit_price). Discount: type toggle (% or fixed) + value input + reason. Show computed total = subtotal - discount. These values are sent to backend as-is.
5. **Payment** — payment_status dropdown, invoice_path (nextcloud path text input)
6. **Shipping** — method, carrier, tracking_number, destination, shipped_at (date), delivered_at (date)
7. **Notes** — textarea
Save → POST or PUT. Delete with confirmation.
### `frontend/src/crm/orders/OrderDetail.jsx`
Read-only view of a single order.
- Header: order number, status badge, customer name (link to customer)
- Items table: product/description, qty, unit price, line total
- Pricing summary: subtotal, discount, total
- Shipping card: all shipping fields
- Payment card: status, invoice path (if set, show as link)
- Notes
- Edit button → OrderForm
- Back to customer button
### `frontend/src/crm/orders/index.js`
Export all components.
## Routing in `frontend/src/App.jsx`
```jsx
<Route path="/crm/orders" element={<OrderList />} />
<Route path="/crm/orders/new" element={<OrderForm />} />
<Route path="/crm/orders/:id" element={<OrderDetail />} />
<Route path="/crm/orders/:id/edit" element={<OrderForm />} />
```
## Sidebar update
Add to CRM section:
- Orders → `/crm/orders`
## Notes
- Status badge colors: draft=grey, confirmed=blue, in_production=orange, shipped=purple, delivered=green, cancelled=red
- Payment status: pending=yellow, partial=orange, paid=green
- Discount calculation: if type=percentage → total = subtotal * (1 - value/100). if type=fixed → total = subtotal - value
- When a product is selected from dropdown in item row, auto-fill unit_price from product.price (user can override)
- Order list needs customer names — either fetch all customers once and build a map, or add customer_name as a denormalized field when creating/updating orders (simpler: fetch customer list once)