add restrict create/edit/delete depletion

This commit is contained in:
ragilap
2026-03-14 15:38:47 +07:00
parent 29956528e5
commit 5ba10113c3
12 changed files with 1099 additions and 109 deletions
@@ -646,24 +646,72 @@ func (s *chickinService) ensureNoDownstreamConsumptionForDelete(ctx context.Cont
}
var rows []downstreamRow
if err := db.Table("stock_allocations sa").
Select("sa.usable_type, sa.usable_id").
Joins("JOIN project_flock_populations pfp ON pfp.id = sa.stockable_id").
Where("pfp.project_chickin_id = ?", chickinID).
Where("pfp.deleted_at IS NULL").
Where("sa.stockable_type = ?", fifo.StockableKeyProjectFlockPopulation.String()).
Where("sa.status = ?", entity.StockAllocationStatusActive).
Where("sa.allocation_purpose = ?", entity.StockAllocationPurposeConsume).
Where("sa.deleted_at IS NULL").
Where("sa.usable_type IN ?", []string{
fifo.UsableKeyMarketingDelivery.String(),
fifo.UsableKeyRecordingDepletion.String(),
fifo.UsableKeyStockTransferOut.String(),
fifo.UsableKeyAdjustmentOut.String(),
fifo.UsableKeyTransferToLayingOut.String(),
}).
Group("sa.usable_type, sa.usable_id").
Scan(&rows).Error; err != nil {
dependencyTypes := []string{
fifo.UsableKeyMarketingDelivery.String(),
fifo.UsableKeyRecordingStock.String(),
fifo.UsableKeyRecordingDepletion.String(),
fifo.UsableKeyStockTransferOut.String(),
fifo.UsableKeyAdjustmentOut.String(),
fifo.UsableKeyTransferToLayingOut.String(),
}
query := `
WITH chickin_sources AS (
SELECT DISTINCT sa.stockable_type, sa.stockable_id
FROM stock_allocations sa
WHERE sa.usable_type = ?
AND sa.usable_id = ?
AND sa.status = ?
AND sa.allocation_purpose = ?
AND sa.deleted_at IS NULL
),
downstream_by_population AS (
SELECT sa.usable_type, sa.usable_id
FROM project_flock_populations pfp
JOIN stock_allocations sa
ON sa.stockable_type = ?
AND sa.stockable_id = pfp.id
WHERE pfp.project_chickin_id = ?
AND pfp.deleted_at IS NULL
AND sa.status = ?
AND sa.allocation_purpose = ?
AND sa.deleted_at IS NULL
AND sa.usable_type IN ?
),
downstream_by_source AS (
SELECT sa.usable_type, sa.usable_id
FROM chickin_sources cs
JOIN stock_allocations sa
ON sa.stockable_type = cs.stockable_type
AND sa.stockable_id = cs.stockable_id
WHERE sa.status = ?
AND sa.allocation_purpose = ?
AND sa.deleted_at IS NULL
AND sa.usable_type IN ?
)
SELECT dep.usable_type, dep.usable_id
FROM (
SELECT usable_type, usable_id FROM downstream_by_population
UNION
SELECT usable_type, usable_id FROM downstream_by_source
) dep
`
if err := db.Raw(
query,
fifo.UsableKeyProjectChickin.String(),
chickinID,
entity.StockAllocationStatusActive,
entity.StockAllocationPurposeConsume,
fifo.StockableKeyProjectFlockPopulation.String(),
chickinID,
entity.StockAllocationStatusActive,
entity.StockAllocationPurposeConsume,
dependencyTypes,
entity.StockAllocationStatusActive,
entity.StockAllocationPurposeConsume,
dependencyTypes,
).Scan(&rows).Error; err != nil {
s.Log.Errorf("Failed to validate downstream consumption for chickin %d: %+v", chickinID, err)
return fiber.NewError(fiber.StatusInternalServerError, "Gagal memvalidasi transaksi turunan chickin")
}
@@ -682,7 +730,7 @@ func (s *chickinService) ensureNoDownstreamConsumptionForDelete(ctx context.Cont
switch row.UsableType {
case fifo.UsableKeyMarketingDelivery.String():
marketingIDs[row.UsableID] = struct{}{}
case fifo.UsableKeyRecordingDepletion.String():
case fifo.UsableKeyRecordingStock.String(), fifo.UsableKeyRecordingDepletion.String():
recordingIDs[row.UsableID] = struct{}{}
case fifo.UsableKeyStockTransferOut.String():
transferIDs[row.UsableID] = struct{}{}