mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
add restrict create/edit/delete depletion
This commit is contained in:
@@ -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{}{}
|
||||
|
||||
@@ -522,9 +522,6 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin
|
||||
}
|
||||
|
||||
recordingEntity = recording
|
||||
if err := s.ensurePopulationMutationAllowed(ctx, recordingEntity, "ubah"); err != nil {
|
||||
return err
|
||||
}
|
||||
pfkForRoute := recordingEntity.ProjectFlockKandang
|
||||
if pfkForRoute == nil || pfkForRoute.Id == 0 {
|
||||
fetchedPfk, fetchErr := s.ProjectFlockKandangRepo.GetByIDLight(ctx, recordingEntity.ProjectFlockKandangId)
|
||||
@@ -537,7 +534,7 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin
|
||||
}
|
||||
pfkForRoute = fetchedPfk
|
||||
}
|
||||
routePayload := buildRecordingRoutePayloadFromUpdate(req, recordingEntity)
|
||||
routePayload := buildRecordingRoutePayloadFromUpdate(req)
|
||||
if err := s.enforceTransferRecordingRoute(ctx, pfkForRoute, recordingEntity.RecordDatetime, routePayload); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -594,6 +591,9 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin
|
||||
if match {
|
||||
hasDepletionChanges = false
|
||||
} else {
|
||||
if err := s.ensurePopulationMutationAllowed(ctx, recordingEntity, "ubah"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.ensureDepletionMutationAllowed(ctx, recordingEntity, "ubah"); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -935,15 +935,15 @@ func (s recordingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||
s.Log.Errorf("Failed to find recording: %+v", err)
|
||||
return err
|
||||
}
|
||||
if err := s.ensurePopulationMutationAllowed(ctx, recording, "hapus"); err != nil {
|
||||
return err
|
||||
}
|
||||
existingDepletions, err := s.Repository.ListDepletions(tx, recording.Id)
|
||||
if err != nil {
|
||||
s.Log.Errorf("Failed to list existing depletions: %+v", err)
|
||||
return err
|
||||
}
|
||||
if len(existingDepletions) > 0 {
|
||||
if err := s.ensurePopulationMutationAllowed(ctx, recording, "hapus"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.ensureDepletionMutationAllowed(ctx, recording, "hapus"); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1376,60 +1376,34 @@ func buildRecordingRoutePayloadFromCreate(req *validation.Create) recordingRoute
|
||||
return payload
|
||||
}
|
||||
|
||||
func buildRecordingRoutePayloadFromUpdate(req *validation.Update, existing *entity.Recording) recordingRoutePayload {
|
||||
func buildRecordingRoutePayloadFromUpdate(req *validation.Update) recordingRoutePayload {
|
||||
payload := recordingRoutePayload{}
|
||||
if req == nil && existing == nil {
|
||||
if req == nil {
|
||||
return payload
|
||||
}
|
||||
|
||||
if req != nil && req.Stocks != nil {
|
||||
if req.Stocks != nil {
|
||||
for _, stock := range req.Stocks {
|
||||
if stock.Qty > 0 {
|
||||
payload.StockCount++
|
||||
}
|
||||
}
|
||||
} else if existing != nil {
|
||||
for _, stock := range existing.Stocks {
|
||||
usageQty := 0.0
|
||||
if stock.UsageQty != nil {
|
||||
usageQty = *stock.UsageQty
|
||||
}
|
||||
pendingQty := 0.0
|
||||
if stock.PendingQty != nil {
|
||||
pendingQty = *stock.PendingQty
|
||||
}
|
||||
if usageQty > 0 || pendingQty > 0 {
|
||||
payload.StockCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if req != nil && req.Depletions != nil {
|
||||
if req.Depletions != nil {
|
||||
for _, depletion := range req.Depletions {
|
||||
if depletion.Qty > 0 {
|
||||
payload.DepletionCount++
|
||||
}
|
||||
}
|
||||
} else if existing != nil {
|
||||
for _, depletion := range existing.Depletions {
|
||||
if depletion.Qty > 0 {
|
||||
payload.DepletionCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if req != nil && req.Eggs != nil {
|
||||
if req.Eggs != nil {
|
||||
for _, egg := range req.Eggs {
|
||||
if egg.Qty > 0 {
|
||||
payload.EggCount++
|
||||
}
|
||||
}
|
||||
} else if existing != nil {
|
||||
for _, egg := range existing.Eggs {
|
||||
if egg.Qty > 0 {
|
||||
payload.EggCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return payload
|
||||
|
||||
Reference in New Issue
Block a user