[FEAT/BE] wiring recording,transfer_stock,transfer_laying,marketing for consumer chick in project flock population

This commit is contained in:
ragilap
2026-03-04 12:41:26 +07:00
parent 80135466df
commit d334f46829
17 changed files with 513 additions and 11 deletions
@@ -98,6 +98,7 @@ func (RecordingModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate
projectFlockKandangRepo,
projectFlockPopulationRepo,
chickinDetailRepo,
transferLayingRepo,
validate,
fifoStockV2Service,
)
@@ -10,6 +10,7 @@ import (
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
fifoV2 "gitlab.com/mbugroup/lti-api.git/internal/common/service/fifo_stock_v2"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
rProductWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
@@ -23,6 +24,7 @@ import (
rStockLogs "gitlab.com/mbugroup/lti-api.git/internal/modules/shared/repositories"
"gitlab.com/mbugroup/lti-api.git/internal/utils"
approvalutils "gitlab.com/mbugroup/lti-api.git/internal/utils/approvals"
fifo "gitlab.com/mbugroup/lti-api.git/internal/utils/fifo"
recordingutil "gitlab.com/mbugroup/lti-api.git/internal/utils/recording"
"github.com/go-playground/validator/v10"
@@ -416,6 +418,10 @@ func (s *recordingService) CreateOne(c *fiber.Ctx, req *validation.Create) (*ent
if err := s.reflowApplyRecordingDepletionsIn(ctx, tx, mappedDepletions); err != nil {
return err
}
if err := s.Repository.ResyncProjectFlockPopulationUsage(ctx, tx, createdRecording.ProjectFlockKandangId); err != nil {
s.Log.Errorf("Failed to resync project flock population usage: %+v", err)
return err
}
mappedEggs := recordingutil.MapEggs(createdRecording.Id, createdRecording.CreatedBy, req.Eggs)
if err := s.Repository.CreateEggs(tx, mappedEggs); err != nil {
@@ -951,6 +957,13 @@ func (s *recordingService) enforceTransferRecordingRoute(
return fiber.NewError(fiber.StatusInternalServerError, "Gagal memvalidasi transfer laying")
}
if transfer != nil && transfer.ExecutedAt != nil && !transfer.ExecutedAt.IsZero() {
return fiber.NewError(
fiber.StatusBadRequest,
"Project flock kandang sudah dipindahkan ke laying",
)
}
effectiveDate := effectiveTransferDate(transfer)
if effectiveDate.IsZero() {
return nil
@@ -1835,6 +1848,14 @@ func (s *recordingService) reflowApplyRecordingDepletionsOut(
}
s.logDepletionTrace("reflow_apply:done", *refreshed, fmt.Sprintf("desired=%.3f used=%.3f pending=%.3f", desired, refreshed.UsageQty, refreshed.PendingQty))
consumeQty := refreshed.UsageQty
if refreshed.PendingQty > 0 {
consumeQty += refreshed.PendingQty
}
if err := s.allocatePopulationForDepletion(ctx, tx, *refreshed, consumeQty); err != nil {
return err
}
logDecrease := refreshed.UsageQty
if refreshed.PendingQty > 0 {
logDecrease += refreshed.PendingQty
@@ -1894,11 +1915,15 @@ func (s *recordingService) reflowResetRecordingDepletionsOut(
return errors.New("stock log repository is not available")
}
logState := newRecordingStockLogState()
stockAllocationRepo := commonRepo.NewStockAllocationRepository(tx)
for _, depletion := range depletions {
if depletion.Id == 0 {
continue
}
if err := stockAllocationRepo.ReleaseByUsable(ctx, fifo.UsableKeyRecordingDepletion.String(), depletion.Id, nil, nil); err != nil {
return err
}
s.logDepletionTrace("reflow_reset:start", depletion, "")
sourceWarehouseID := uint(0)
@@ -1979,6 +2004,58 @@ func (s *recordingService) reflowResetRecordingDepletionsOut(
return nil
}
func (s *recordingService) allocatePopulationForDepletion(
ctx context.Context,
tx *gorm.DB,
depletion entity.RecordingDepletion,
consumeQty float64,
) error {
if consumeQty <= 0 {
return nil
}
if tx == nil {
return errors.New("transaction is required")
}
sourceWarehouseID := uint(0)
if depletion.SourceProductWarehouseId != nil {
sourceWarehouseID = *depletion.SourceProductWarehouseId
}
if sourceWarehouseID == 0 {
return fiber.NewError(fiber.StatusBadRequest, "Source product warehouse populasi tidak ditemukan")
}
var projectFlockKandangID uint
if err := tx.WithContext(ctx).
Table("recordings").
Select("project_flock_kandangs_id").
Where("id = ?", depletion.RecordingId).
Scan(&projectFlockKandangID).Error; err != nil {
return err
}
if projectFlockKandangID == 0 {
return fiber.NewError(fiber.StatusBadRequest, "Project flock kandang tidak ditemukan untuk depletion")
}
populations, err := s.ProjectFlockPopulationRepo.GetByProjectFlockKandangIDAndProductWarehouseID(ctx, projectFlockKandangID, sourceWarehouseID)
if err != nil {
return err
}
if len(populations) == 0 {
return fiber.NewError(fiber.StatusBadRequest, "Populasi tidak ditemukan untuk depletion")
}
return fifoV2.AllocatePopulationConsumption(
ctx,
tx,
populations,
sourceWarehouseID,
fifo.UsableKeyRecordingDepletion.String(),
depletion.Id,
consumeQty,
)
}
func (s *recordingService) reflowApplyRecordingDepletionsIn(
ctx context.Context,
tx *gorm.DB,