201 lines
4.8 KiB
Markdown
201 lines
4.8 KiB
Markdown
|
|
# Order-Case Integration Model
|
||
|
|
|
||
|
|
## Principle
|
||
|
|
Orders are **transactional satellites** that orbit cases. They exist independently but gain process context through relations.
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
### Order Table (Future - Not in Sag Module)
|
||
|
|
```sql
|
||
|
|
CREATE TABLE orders (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
order_number VARCHAR(50) UNIQUE NOT NULL,
|
||
|
|
customer_id INT NOT NULL,
|
||
|
|
total_amount DECIMAL(10,2),
|
||
|
|
status VARCHAR(50), -- 'draft', 'sent', 'paid', etc.
|
||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
deleted_at TIMESTAMP
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
### Integration via Relations
|
||
|
|
When an Order is created from a Case:
|
||
|
|
|
||
|
|
1. **Create Order independently**
|
||
|
|
```python
|
||
|
|
order = create_order({
|
||
|
|
'customer_id': 123,
|
||
|
|
'total_amount': 1500.00
|
||
|
|
})
|
||
|
|
```
|
||
|
|
|
||
|
|
2. **Create relation to Case**
|
||
|
|
```python
|
||
|
|
create_relation({
|
||
|
|
'kilde_sag_id': case_id,
|
||
|
|
'målsag_id': None, # Relations can point to other entities
|
||
|
|
'relationstype': 'ordre',
|
||
|
|
'metadata': {'order_id': order.id}
|
||
|
|
})
|
||
|
|
```
|
||
|
|
|
||
|
|
## Valid Use Cases
|
||
|
|
|
||
|
|
### ✅ Scenario 1: Case Leads to Order
|
||
|
|
1. Customer opens case: "Need new server"
|
||
|
|
2. Tech works case, adds tags: ['hardware', 'quote_needed']
|
||
|
|
3. Salesperson closes tag 'quote_needed' by creating Order
|
||
|
|
4. Relation created: Case → Order (relationstype='ordre_oprettet')
|
||
|
|
5. Case continues with tag 'installation'
|
||
|
|
6. When installed, case closed
|
||
|
|
|
||
|
|
**Result**: Order exists, Case tracks the work process.
|
||
|
|
|
||
|
|
### ✅ Scenario 2: Order Triggers Case
|
||
|
|
1. Order created by salesperson
|
||
|
|
2. System auto-creates Case: "Deliver order #1234"
|
||
|
|
3. Relation created: Order → Case (relationstype='leverance')
|
||
|
|
4. Case gets tags: ['pick_items', 'ship', 'install']
|
||
|
|
5. Each tag closed as work progresses
|
||
|
|
6. Case closed when complete
|
||
|
|
|
||
|
|
**Result**: Order is transaction, Case is the delivery process.
|
||
|
|
|
||
|
|
### ✅ Scenario 3: Multiple Cases per Order
|
||
|
|
1. Large order for multiple items
|
||
|
|
2. Each item gets its own Case:
|
||
|
|
- Case A: "Install firewall" (relation to Order)
|
||
|
|
- Case B: "Configure switches" (relation to Order)
|
||
|
|
- Case C: "Setup monitoring" (relation to Order)
|
||
|
|
3. Each Case has independent lifecycle with tags
|
||
|
|
4. Order tracks payment/billing
|
||
|
|
5. Cases track work processes
|
||
|
|
|
||
|
|
**Result**: One transactional Order, three process Cases.
|
||
|
|
|
||
|
|
## Anti-Patterns (DO NOT)
|
||
|
|
|
||
|
|
### ❌ Anti-Pattern 1: Embedding Process in Order
|
||
|
|
```python
|
||
|
|
# WRONG - Order should NOT have workflow state
|
||
|
|
order.status = 'awaiting_installation' # This belongs in a Case tag!
|
||
|
|
```
|
||
|
|
|
||
|
|
**Fix**: Create Case with tag 'installation', link to Order.
|
||
|
|
|
||
|
|
### ❌ Anti-Pattern 2: Making Order Replace Case
|
||
|
|
```python
|
||
|
|
# WRONG - Don't create Order instead of Case
|
||
|
|
order = Order(description="Fix customer server")
|
||
|
|
```
|
||
|
|
|
||
|
|
**Fix**: Create Case, optionally link to Order if billing needed.
|
||
|
|
|
||
|
|
### ❌ Anti-Pattern 3: Storing Case ID in Order
|
||
|
|
```python
|
||
|
|
# WRONG - Don't embed references
|
||
|
|
order.case_id = 42
|
||
|
|
```
|
||
|
|
|
||
|
|
**Fix**: Use Relations table to link Order ↔ Case.
|
||
|
|
|
||
|
|
## Implementation Guidelines
|
||
|
|
|
||
|
|
### When to Create Order
|
||
|
|
- Customer needs invoice/quote
|
||
|
|
- Financial transaction required
|
||
|
|
- External system (e-conomic) integration needed
|
||
|
|
- Legal/accounting documentation
|
||
|
|
|
||
|
|
### When to Create Case
|
||
|
|
- Work needs to be tracked
|
||
|
|
- Workflow has multiple steps
|
||
|
|
- Tags represent responsibilities
|
||
|
|
- Multiple people involved
|
||
|
|
- Need audit trail of process
|
||
|
|
|
||
|
|
### When to Create Both
|
||
|
|
- Order for billing + Case for work process
|
||
|
|
- Link them via Relation
|
||
|
|
|
||
|
|
## Database Schema Addition
|
||
|
|
|
||
|
|
To support Order-Case links, add metadata to relations:
|
||
|
|
|
||
|
|
```sql
|
||
|
|
ALTER TABLE sag_relationer
|
||
|
|
ADD COLUMN metadata JSONB DEFAULT '{}';
|
||
|
|
|
||
|
|
-- Example usage:
|
||
|
|
INSERT INTO sag_relationer (kilde_sag_id, målsag_id, relationstype, metadata)
|
||
|
|
VALUES (42, NULL, 'ordre', '{"order_id": 1234, "order_number": "ORD-2025-001"}');
|
||
|
|
```
|
||
|
|
|
||
|
|
This allows relations to point to external entities (Orders) while keeping the Case model clean.
|
||
|
|
|
||
|
|
## API Contract
|
||
|
|
|
||
|
|
### Create Order from Case
|
||
|
|
```
|
||
|
|
POST /api/v1/cases/{case_id}/orders
|
||
|
|
{
|
||
|
|
"customer_id": 123,
|
||
|
|
"total_amount": 1500.00,
|
||
|
|
"description": "Server upgrade"
|
||
|
|
}
|
||
|
|
|
||
|
|
Response:
|
||
|
|
{
|
||
|
|
"order_id": 1234,
|
||
|
|
"order_number": "ORD-2025-001",
|
||
|
|
"relation_id": 56 // Auto-created relation
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### List Orders for Case
|
||
|
|
```
|
||
|
|
GET /api/v1/cases/{case_id}/orders
|
||
|
|
|
||
|
|
Response:
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"order_id": 1234,
|
||
|
|
"order_number": "ORD-2025-001",
|
||
|
|
"status": "sent",
|
||
|
|
"total_amount": 1500.00
|
||
|
|
}
|
||
|
|
]
|
||
|
|
```
|
||
|
|
|
||
|
|
### Create Case from Order
|
||
|
|
```
|
||
|
|
POST /api/v1/orders/{order_id}/cases
|
||
|
|
{
|
||
|
|
"titel": "Deliver order ORD-2025-001",
|
||
|
|
"tags": ["pick_items", "ship", "install"]
|
||
|
|
}
|
||
|
|
|
||
|
|
Response:
|
||
|
|
{
|
||
|
|
"case_id": 87,
|
||
|
|
"relation_id": 57 // Auto-created relation
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Summary
|
||
|
|
|
||
|
|
**Remember**:
|
||
|
|
- Orders = Transactions (billing, invoices, quotes)
|
||
|
|
- Cases = Processes (work, workflow, responsibilities)
|
||
|
|
- Relations = Links (give meaning to both)
|
||
|
|
|
||
|
|
**Never**:
|
||
|
|
- Put process in Order
|
||
|
|
- Put transaction in Case
|
||
|
|
- Create hard references between entities
|
||
|
|
|
||
|
|
**Always**:
|
||
|
|
- Use Relations to link
|
||
|
|
- Keep entities independent
|
||
|
|
- Let UI derive the connections
|