fix over consume by code, revert migration overconsume sell

This commit is contained in:
giovanni
2026-06-06 07:49:34 +07:00
parent 6d2b6a0cb8
commit 33bae94d43
4 changed files with 85 additions and 2 deletions
@@ -972,6 +972,19 @@ func (s deliveryOrdersService) consumeDeliveryStock(ctx context.Context, tx *gor
if err := deliveryProductRepo.UpdateOne(ctx, deliveryProduct.Id, deliveryProduct, nil); err != nil {
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update delivery product")
}
if requestedQty > 0 {
available, err := s.checkAvailableStockQty(ctx, tx, marketingProduct.ProductWarehouseId)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, "Gagal memeriksa ketersediaan stok")
}
if requestedQty > available {
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf(
"Stok tidak mencukupi: dibutuhkan %g, tersedia %g",
requestedQty, available,
))
}
}
if err := reflowMarketingScope(
ctx,
s.FifoStockV2Svc,
@@ -1505,3 +1518,28 @@ func uniqueUintIDs(ids []uint) []uint {
}
return result
}
// checkAvailableStockQty returns the net available qty for a product warehouse:
// gross qty (product_warehouses.qty) minus the sum of active CONSUME allocations
// in stock_allocations. This gives the true available stock accounting for all
// other delivery orders that have already consumed from the same warehouse.
func (s deliveryOrdersService) checkAvailableStockQty(ctx context.Context, tx *gorm.DB, productWarehouseId uint) (float64, error) {
var pw entity.ProductWarehouse
if err := tx.WithContext(ctx).Select("qty").First(&pw, productWarehouseId).Error; err != nil {
return 0, err
}
var usedQty float64
if err := tx.WithContext(ctx).Raw(`
SELECT COALESCE(SUM(qty), 0)
FROM stock_allocations
WHERE stockable_type = 'product_warehouses'
AND stockable_id = ?
AND status = 'ACTIVE'
AND allocation_purpose = 'CONSUME'
`, productWarehouseId).Scan(&usedQty).Error; err != nil {
return 0, err
}
return pw.Quantity - usedQty, nil
}