Stock Correction Mechanisms

Stock correction mechanisms for adding or removing products from parcels with automatic parcel synchronization.

Stock correction in the inventory service uses two distinct mechanisms for adding or removing products from parcels, both triggering automatic parcel synchronization events.

🔄 Stock Correction Overview

➕ Adding Stock to Parcels

Method: PARCEL_PROCESS

Purpose: Increase product quantities in a parcel

Origin: ACTIVE_STORAGE or PUFFER

Destination: RESERVED (parcel storage)

Event: Triggers ParcelItemsCorrection

➖ Removing Stock from Parcels

Method: INTERNAL_MOVE_PROCESS

Purpose: Remove or decrease product quantities from a parcel

Origin: RESERVED (parcel storage)

Destination: ACTIVE_STORAGE, PUFFER, or SCRAP

Event: Triggers ParcelItemsCorrection

📋 Process Details

Parcel Process Method (Adding Stock)

Supported Parcel Methods:

  • 🔹 SIMPLE_PRODUCT_METHOD - Basic product addition without lot tracking
  • 🔹 FEFO_LOT_METHOD - First Expired, First Out lot selection
  • 🔹 LEFO_LOT_METHOD - Last Expired, First Out lot selection
  • 🔹 EXACT_LOT_NUMBERS_METHOD - Specific lot numbers selection

Process Flow:

  1. Validates parcel process method
  2. Checks full storage quantity available
  3. Automatically selects optimal locations via sorting system
  4. Moves units from ACTIVE_STORAGE/PUFFER to RESERVED
  5. Associates products with parcel_id
  6. Updates parcel status (SENT_TO_PROCESSING or WAITING_FOR_PRODUCT)
  7. Dispatches ParcelItemsCorrection event

Internal Move Process (Removing Stock)

Allowed Operations:

  • 🔹 RESERVED → ACTIVE_STORAGE (return to general stock)
  • 🔹 RESERVED → PUFFER (move to buffer storage)
  • 🔹 RESERVED → SCRAP (mark as damaged/unusable)
  • 🔹 Inter-storage movements without parcel association

Process Flow:

  1. Validates origin and destination compatibility
  2. Requires explicit location specification (current location)
  3. Removes products from specified source location
  4. Decrements or removes parcel associations
  5. Moves products to destination storage at same location
  6. Updates transaction logs
  7. Dispatches ParcelItemsCorrection event

🎯 Event Broadcasting

ParcelItemsCorrection Event

Purpose: Synchronizes parcel contents with the parcels microservice

Queue: parcels_queue (RabbitMQ)

Triggered by: Any stock movement affecting parcel contents

Event Payload Structure:

{
    "parcel_id": 123,
    "products": [
        {
            "product_id": 456,
            "quantity": 10
        },
        {
            "product_id": 789,
            "quantity": 5
        }
    ]
}

ParcelMovementEvent

Purpose: Notifies about parcel status changes

Triggered by: Status changes during stock movements

Statuses: SENT_TO_PROCESSING, WAITING_FOR_PRODUCT, PICKING_IN_PROGRESS, etc.

⚙️ Technical Implementation

Decision Tree Routing

Stock correction uses the inventory service's decision tree system:

  • CheckProcessType: Routes PARCEL_PROCESS vs other process types
  • ParcelProcessRouter: Determines parcel method handling
  • CheckFullStorageQuantity: Validates availability for parcel processes
  • MoveUnitsToReserved: Executes parcel stock additions
  • RemoveRecordsFromOrigin/MoveRecordToDestination: Handles internal moves

Job Processing

ParcelProcessJob: Handles complex parcel operations asynchronously

  • Queue: low (RabbitMQ)
  • Delay: 500ms for processing coordination
  • Transaction-wrapped for data consistency
  • Full decision tree execution

Stock Tracking

Redis Integration: Real-time stock quantity tracking

  • Increments on movements into reservable storage
  • Decrements on movements out of reservable storage
  • Immediate availability checks for parcel processes

🎯 Usage Examples

Adding Products to Parcel

📍 Location Handling: Location fields are not required for parcel processes - the system automatically handles location assignment through the sorting system.

POST /api/storage-units/move

{
    "product_id": 123,
    "warehouse_id": 1,
    "quantity": 5,
    "process_details": {
        "type": "PARCEL_PROCESS",
        "origin": "ACTIVE_STORAGE",
        "destination": "RESERVED",
        "parcel_method": "SIMPLE_PRODUCT_METHOD",
        "parcel_id": 456,
        "is_partial_reservation_allowed": true,
        "allow_to_ship_not_filled_parcels": false
    }
}

Removing Products from Parcel

📍 Location Handling: You must specify the current location where products are located. Use the same location for both removal and placement.

Note: Automatic location detection for removals will be implemented in the future.

POST /api/storage-units/move

{
    "product_id": 123,
    "warehouse_id": 1,
    "quantity": 2,
    "location_id_to_remove": 15,
    "location_id_to_put": 15,
    "process_details": {
        "type": "INTERNAL_MOVE_PROCESS",
        "origin": "RESERVED",
        "destination": "ACTIVE_STORAGE",
        "process_reason": "Stock correction - excess quantity"
    }
}

📍 Location Handling Summary

✅ PARCEL_PROCESS (Adding)

Automatic location handling
No location fields required - sorting system handles placement

⚠️ INTERNAL_MOVE_PROCESS (Removing)

Manual location required
Must specify current product location for both removal and placement

🔍 Key Points

  • ✅ Both mechanisms automatically trigger parcel synchronization
  • ✅ All operations are transaction-wrapped for consistency
  • ✅ Real-time stock tracking via Redis
  • ✅ Full audit trail through transaction logs
  • ✅ Supports both simple products and lot-tracked items
  • ✅ Partial reservations and waiting queues supported
  • 🔄 Automatic location detection for removals planned for future release