Files
lti-api/docs/STOCK_CONSOLIDATION_GUIDE.md
T
Adnan Zahir cdcc268d89 :
2026-04-23 21:32:20 +07:00

15 KiB

Stock Consolidation Operations Guide

This guide explains how to use the warehouse consolidation commands to fix misplaced PAKAN/OVK stocks and migrate them to the correct farm-level warehouses.

Overview

The stock consolidation system handles two main scenarios:

Case Scenario Root Cause Solution
Case B Invalid kandang references Purchases pointed to warehouses with location mismatch Move unused stocks to correct farm-level warehouse
Case A General kandang cleanup Any kandang-level warehouse with unused PAKAN/OVK stocks Consolidate to farm-level warehouse

For a complete stock consolidation operation, follow this sequence:

1. find-wrong-warehouse-records    ← Diagnose issues
2. repoint-wrong-warehouse-relations  ← Fix Case B (invalid references)
3. consolidate-kandang-to-farm-stocks ← Fix Case A (general cleanup)
4. verify-stock-consolidation         ← Audit and verify results

Command Reference

1. find-wrong-warehouse-records — Diagnostic Tool

Purpose: Identify problematic warehouses and their associated stocks before making any changes.

Applies to: Both Case A and Case B scenarios

What it does:

  • Lists warehouses with location mismatches (Case B)
  • Shows stock allocations that reference wrong warehouses
  • Helps identify scope of work needed

Usage:

# Report 1: Find warehouses with location mismatches (Case B issues)
./find-wrong-warehouse-records --report=warehouses

# Report 2: Find stock allocations in wrong warehouses (Case B impact)
./find-wrong-warehouse-records --report=usage

# Filter by area
./find-wrong-warehouse-records --report=warehouses --area-name "East Region"

# Filter by kandang location
./find-wrong-warehouse-records --report=usage --kandang-location-name "Location 1"

# Filter by product type
./find-wrong-warehouse-records --report=usage --usable-type=RECORDING_STOCK

# JSON output for analysis
./find-wrong-warehouse-records --report=usage --output=json > analysis.json

Output Columns (Warehouses Report):

  • AREA: Geographic area
  • KANDANG_LOCATION: Kandang's intended location
  • KANDANG: Kandang name
  • WRONG_LOCATION: Where the warehouse actually is
  • WRONG_WAREHOUSE: Problematic warehouse name
  • CORRECT_WAREHOUSE: Where stocks should be

Output Columns (Usage Report):

  • USABLE_TYPE: RECORDING_STOCK or MARKETING_DELIVERY
  • PRODUCTS: Which products are affected
  • QTY_FROM_WRONG_STOCK: How much stock is misplaced
  • SOURCE_PURCHASES: Which purchase orders are affected

When to use:

  • Before starting any consolidation
  • To understand the scope of issues
  • To get metrics on how much stock needs moving
  • To identify which areas are most affected

2. repoint-wrong-warehouse-relations — Fix Case B (Invalid References)

Purpose: Fix purchases pointed to invalid kandang warehouses (location mismatch).

Applies to: Case B only

Cases it handles:

  • Warehouses with location_id ≠ kandang.location_id (location mismatch)
  • Only PAKAN/OVK products
  • Only unused/leftover stocks (no active allocations)
  • Moves to farm-level warehouse at correct location

What it does:

  1. Finds product_warehouses in wrong locations
  2. Consolidates duplicates into survivor warehouses
  3. Updates all references across the system
  4. Recalculates FIFO stocks if needed
  5. Optionally soft-deletes the wrong warehouse

Usage:

# Dry-run: See what would be moved (always run first!)
./repoint-wrong-warehouse-relations

# Dry-run with specific filters
./repoint-wrong-warehouse-relations --area-name "East Region"
./repoint-wrong-warehouse-relations --kandang-location-name "Location 1"

# Actually apply the migration
./repoint-wrong-warehouse-relations --apply

# Apply but keep the wrong warehouses (for audit trail)
./repoint-wrong-warehouse-relations --apply --delete-wrong-warehouses=false

# JSON output for automation/logging
./repoint-wrong-warehouse-relations --apply --output=json > migration.json

Flags:

  • --apply: Apply changes (omit for dry-run)
  • --output: table (default) or json
  • --area-name: Filter by exact area name
  • --kandang-location-name: Filter by exact location name
  • --delete-wrong-warehouses: Soft-delete wrong warehouses (default: true)
  • --db-sslmode: PostgreSQL SSL mode override (e.g., require)

Output:

Table mode shows:

  • AREA, LOCATION, KANDANG: Where the issue is
  • WRONG_WAREHOUSE: Source (will be deleted)
  • TARGET_WAREHOUSE: Destination (farm-level)
  • PRODUCT: What's being moved
  • SURVIVOR_PW / ABSORBED_PW: Consolidation details
  • NEEDS_REFLOW: Whether FIFO recalculation is needed

Summary shows:

Summary: plan_rows=15 wrong_warehouses=3 survivor_pws=12 absorbed_pws=5 
  needs_reflow_pws=3 deleted_product_warehouses=5 soft_deleted_warehouses=3

Updated product_warehouse refs:
  fifo_stock_v2_operation_log.product_warehouse_id=8
  fifo_stock_v2_reflow_checkpoints.product_warehouse_id=3
  purchase_items.warehouse_id=12

Updated warehouse refs:
  purchase_items.warehouse_id=12

Safety Features:

  • Dry-run first: Always preview before applying
  • Prechecks: Verifies no blocked references or FIFO conflicts
  • Atomic transactions: All-or-nothing database updates
  • Reference verification: Confirms all references were updated
  • Stock log recalculation: Ensures FIFO accuracy after moves

3. consolidate-kandang-to-farm-stocks — Fix Case A (General Cleanup)

Purpose: Consolidate ALL kandang-level PAKAN/OVK stocks to farm-level warehouse.

Applies to: Case A only

Cases it handles:

  • ALL kandang-level warehouses (type ≠ 'LOKASI')
  • Only PAKAN/OVK products
  • Only unused/leftover stocks (no active allocations)
  • Moves to farm-level warehouse regardless of warehouse validity
  • No location validation (processes all kandang warehouses)

What it does:

  1. Finds all kandang-level warehouses with unused stocks
  2. Consolidates duplicates into survivor warehouses
  3. Updates all references across the system
  4. Recalculates FIFO stocks if needed
  5. Optionally soft-deletes the kandang warehouse

Usage:

# Dry-run: See what would be consolidated
./consolidate-kandang-to-farm-stocks

# Dry-run with filters
./consolidate-kandang-to-farm-stocks --area-name "East Region"
./consolidate-kandang-to-farm-stocks --kandang-location-name "Location 1"

# Actually apply the consolidation
./consolidate-kandang-to-farm-stocks --apply

# Apply but keep kandang warehouses
./consolidate-kandang-to-farm-stocks --apply --delete-kandang-warehouses=false

# JSON output for logging
./consolidate-kandang-to-farm-stocks --apply --output=json > consolidation.json

Flags:

  • --apply: Apply changes (omit for dry-run)
  • --output: table (default) or json
  • --area-name: Filter by exact area name
  • --kandang-location-name: Filter by exact location name
  • --delete-kandang-warehouses: Soft-delete kandang warehouses (default: true)
  • --db-sslmode: PostgreSQL SSL mode override

Output Format:

Similar to Case B, shows:

  • Source kandang warehouse → Destination farm warehouse
  • Product and quantity details
  • Consolidation and FIFO reflow information

Key Differences from Case B:

Aspect Case B Case A
Scope Wrong-location warehouses only ALL kandang-level warehouses
Validation Checks location mismatch No validation checks
When to use After finding mismatches General cleanup/consolidation
Risk level Lower (targeted fix) Higher (broader scope)

4. verify-stock-consolidation — Audit and Verify

Purpose: Verify that stock consolidations were successful and no stocks were lost.

Applies to: Both Case A and Case B (post-migration verification)

What it checks:

Source Warehouse Verification

Ensures deleted warehouses are clean:

  • CLEAN: No remaining stock or purchase references
  • DIRTY: Still has orphaned data (migration incomplete)

Destination Warehouse Verification

Ensures farm-level warehouses received stocks correctly:

  • MATCHED: Quantity in product_warehouse matches stock_logs
  • DISCREPANCY: Quantity mismatch (data integrity issue!)
  • EMPTY: No stocks (correct if nothing was supposed to move)

Orphaned Reference Detection

Finds any remaining references to deleted warehouses in:

  • purchase_items.warehouse_id
  • stock_transfers.from/to_warehouse_id
  • fifo_stock_v2_operation_log.warehouse_id

Usage:

# Verify all consolidations (Case A + B together)
./verify-stock-consolidation

# Verify only Case B results
./verify-stock-consolidation --verify-case=B

# Verify only Case A results
./verify-stock-consolidation --verify-case=A

# Filter by area
./verify-stock-consolidation --area-name "East Region"

# Filter by location
./verify-stock-consolidation --kandang-location-name "Location 1"

# JSON output for reporting
./verify-stock-consolidation --output=json > verification_report.json

Flags:

  • --verify-case: A, B, or all (default)
  • --output: table (default) or json
  • --area-name: Filter by exact area name
  • --kandang-location-name: Filter by exact location name
  • --db-sslmode: PostgreSQL SSL mode override

Output Sections:

1. Source Warehouses

AREA    LOKASI      KANDANG    WAREHOUSE     CASE  DELETED_AT   STOCK  PURCHASES  STATUS
Area A  Location 1  Kandang A  KWH-A-01      A     2026-04-23   0.000  0          CLEAN
Area A  Location 1  Kandang B  WH-WRONG-001  B     2026-04-23   2.500  1          DIRTY ❌

2. Destination Warehouses

AREA    LOKASI      FARM_WAREHOUSE  PRODUCT    QTY     LOGS_TOTAL  LOGS  STATUS
Area A  Location 1  FWH-LOC-001     PAKAN A    2.500   2.500       3     MATCHED ✅
Area A  Location 1  FWH-LOC-001     OVK B      5.000   4.999       5     DISCREPANCY ❌

3. Orphaned References (if any)

TABLE              COLUMN              COUNT  WAREHOUSE_IDS
purchase_items     warehouse_id        3      1001, 1002, 1003
stock_transfers    from_warehouse_id   1      1001

4. Summary

Source Warehouses: 10 total, 8 clean, 2 dirty
Destination Warehouses: 15 total, 14 matching, 1 discrepancy
Orphaned References: 4
Overall Status: FAIL ❌

Interpreting Results:

Scenario Meaning Action
Overall Status: PASS All migrations successful No action needed
Dirty Source Warehouses Stocks not fully moved Re-run repoint/consolidate
Discrepancy Destinations Quantity mismatch Investigate data integrity
Orphaned References Broken references remain Manual cleanup needed

Complete Workflow Example

Scenario: Consolidate East Region stocks

# Step 1: Understand the scope (Case B issues)
./find-wrong-warehouse-records --report=warehouses --area-name "East Region"
./find-wrong-warehouse-records --report=usage --area-name "East Region"

# Review the output to understand:
# - How many wrong warehouses
# - How much stock needs moving
# - Which products are affected

# Step 2: Fix Case B (invalid kandang references)
./repoint-wrong-warehouse-relations --area-name "East Region"
# Review dry-run output

./repoint-wrong-warehouse-relations --apply --area-name "East Region"
# Watch for summary - should show successful updates

# Step 3: Fix Case A (general kandang cleanup)
./consolidate-kandang-to-farm-stocks --area-name "East Region"
# Review dry-run output

./consolidate-kandang-to-farm-stocks --apply --area-name "East Region"
# Watch for summary - should show consolidation complete

# Step 4: Verify everything worked
./verify-stock-consolidation --area-name "East Region"
# Should show:
# - All source warehouses: CLEAN
# - All destination warehouses: MATCHED
# - Orphaned references: 0
# - Overall Status: PASS ✅

Flags Reference

Common Flags (All Commands)

Flag Description Example
--output Output format --output=json
--area-name Filter by area --area-name "East Region"
--kandang-location-name Filter by location --kandang-location-name "Location 1"
--db-sslmode PostgreSQL SSL mode --db-sslmode=require

Migration-Specific Flags

Command Flag Description
repoint-wrong-warehouse-relations --apply Apply changes
repoint-wrong-warehouse-relations --delete-wrong-warehouses Delete wrong warehouses (default: true)
consolidate-kandang-to-farm-stocks --apply Apply changes
consolidate-kandang-to-farm-stocks --delete-kandang-warehouses Delete kandang warehouses (default: true)
verify-stock-consolidation --verify-case Verify specific case (A, B, or all)

Best Practices

Before Running Any Command

  1. Back up the database — These operations modify stock data
  2. Run in dry-run mode first — Always preview changes before applying
  3. Check during low-traffic periods — Avoid peak hours
  4. Have a rollback plan — Know how to restore from backup if needed

When Running Migrations

  1. Start small — Use --area-name to test on one area first
  2. Check the summary — Verify numbers make sense
  3. Watch for errors — Stop if you see unexpected error messages
  4. Run verification immediately after — Don't wait to verify

Red Flags (Stop and Investigate)

  • More rows affected than expected
  • Negative quantities or zero counts where expecting data
  • Errors about blocked references
  • FIFO conflicts or in-flight artifacts
  • Very large numbers in NEEDS_REFLOW

JSON Output for Automation

All commands support --output=json for:

  • Piping to other tools
  • Parsing in scripts
  • Generating reports
  • Integration with monitoring systems
# Example: Extract all affected warehouses to CSV
./find-wrong-warehouse-records --report=warehouses --output=json \
  | jq -r '.rows[] | [.area_name, .kandang_name, .wrong_warehouse_name] | @csv' \
  > affected_warehouses.csv

Troubleshooting

Issue: "No wrong warehouse relations found"

  • Cause: No matching Case B issues in the filter scope
  • Solution: Remove filters or use different criteria

Issue: "found X rows still point to wrong warehouses"

  • Cause: References not fully migrated
  • Solution: Check for blocked references, re-run command

Issue: "discrepancy_destinations > 0" in verification

  • Cause: Quantity mismatch in farm warehouse
  • Solution: Investigate manually or rollback and retry

Issue: "DIRTY source warehouses" in verification

  • Cause: Deleted warehouses still have stock/references
  • Solution: May need manual cleanup or re-run migrations

Performance Notes

  • Commands use efficient SQL queries with proper filtering
  • Large operations (100K+ rows) may take a few minutes
  • Use area/location filters to reduce scope for testing
  • Dry-runs don't modify database and complete quickly

Support

For issues or questions:

  1. Review the relevant section of this guide
  2. Check the command output for specific error messages
  3. Run verification to diagnose state issues
  4. Contact the development team with JSON outputs from failed operations