apskel-pos-backend/ORDER_VOID_STATUS_IMPROVEMENT.md
aditya.siregar 4f5950543e init
2025-07-18 20:10:29 +07:00

4.2 KiB

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

-- 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

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

// 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.