apskel-pos-backend/ORDER_VOID_STATUS_IMPROVEMENT.md

120 lines
4.2 KiB
Markdown
Raw Normal View History

2025-07-18 20:10:29 +07:00
# Order Void Status Improvement
## Overview
This document describes the improved approach for handling order void status when all items are voided.
## Problem with Previous Approach
The previous implementation only set the `is_void` flag to `true` when voiding orders, but kept the original order status (e.g., "pending", "preparing", etc.). This approach had several issues:
1. **Poor Semantic Meaning**: Orders with status "pending" but `is_void = true` were confusing
2. **Difficult Querying**: Hard to filter voided orders by status alone
3. **Inconsistent State**: Order status didn't reflect the actual business state
4. **Audit Trail Issues**: No clear indication of when and why orders were voided
## Improved Approach
### 1. Status Update Strategy
When an order is voided (either entirely or when all items are voided), the system now:
- **Sets `is_void = true`** (for audit trail and void-specific operations)
- **Updates `status = 'cancelled'`** (for business logic and semantic clarity)
- **Records void metadata** (reason, timestamp, user who voided)
### 2. Benefits
#### **Clear Semantic Meaning**
- Voided orders have status "cancelled" which clearly indicates they are no longer active
- Business logic can rely on status for workflow decisions
- Frontend can easily display voided orders with appropriate styling
#### **Better Querying**
```sql
-- Find all cancelled/voided orders
SELECT * FROM orders WHERE status = 'cancelled';
-- Find all active orders (excluding voided)
SELECT * FROM orders WHERE status != 'cancelled';
-- Find voided orders with audit info
SELECT * FROM orders WHERE is_void = true;
```
#### **Consistent State Management**
- Order status always reflects the current business state
- No conflicting states (e.g., "pending" but voided)
- Easier to implement business rules and validations
#### **Enhanced Audit Trail**
- `is_void` flag for void-specific operations
- `void_reason`, `voided_at`, `voided_by` for detailed audit
- `status = 'cancelled'` for business workflow
### 3. Implementation Details
#### **New Repository Method**
```go
VoidOrderWithStatus(ctx context.Context, id uuid.UUID, status entities.OrderStatus, reason string, voidedBy uuid.UUID) error
```
This method updates both status and void flags in a single atomic transaction.
#### **Updated Processor Logic**
```go
// For "ALL" void type
if err := p.orderRepo.VoidOrderWithStatus(ctx, req.OrderID, entities.OrderStatusCancelled, req.Reason, voidedBy); err != nil {
return fmt.Errorf("failed to void order: %w", err)
}
// For "ITEM" void type when all items are voided
if allItemsVoided {
if err := p.orderRepo.VoidOrderWithStatus(ctx, req.OrderID, entities.OrderStatusCancelled, req.Reason, voidedBy); err != nil {
return fmt.Errorf("failed to void order after all items voided: %w", err)
}
}
```
#### **Database Migration**
Added migration `000021_add_paid_status_to_orders.up.sql` to include "paid" status in the constraint.
### 4. Status Flow
```
Order Created → pending
Items Added/Modified → pending
Order Processing → preparing → ready → completed
Order Voided → cancelled (with is_void = true)
```
### 5. Backward Compatibility
- Existing `is_void` flag is preserved for backward compatibility
- New approach is additive, not breaking
- Existing queries using `is_void` continue to work
- New queries can use `status = 'cancelled'` for better performance
### 6. Best Practices
#### **For Queries**
- Use `status = 'cancelled'` for business logic and filtering
- Use `is_void = true` for void-specific operations and audit trails
- Combine both when you need complete void information
#### **For Business Logic**
- Check `status != 'cancelled'` before allowing modifications
- Use `is_void` flag for void-specific validations
- Always include void reason and user for audit purposes
#### **For Frontend**
- Display cancelled orders with appropriate styling
- Show void reason and timestamp when available
- Disable actions on cancelled orders
## Conclusion
This improved approach provides better semantic meaning, easier querying, and more consistent state management while maintaining backward compatibility. The combination of status updates and void flags creates a robust system for handling order cancellations.