Fix transfer to laying delete and fix chikin delete with response recording

This commit is contained in:
ragilap
2026-03-09 13:10:06 +07:00
parent 45cc057dd4
commit 3a8cc47fa0
14 changed files with 1091 additions and 86 deletions
@@ -86,6 +86,8 @@ type RecordingRelationDTO struct {
EggWeight float64 `json:"egg_weight"`
PopulationCanChange bool `json:"population_can_change"`
TransferExecuted *bool `json:"transfer_executed,omitempty"`
IsTransition bool `json:"is_transition"`
IsLaying bool `json:"is_laying"`
Approval approvalDTO.ApprovalRelationDTO `json:"approval"`
}
@@ -247,6 +249,8 @@ func toRecordingRelationDTO(e entity.Recording) RecordingRelationDTO {
EggWeight: floatValue(e.EggWeight),
PopulationCanChange: boolValueDefault(e.PopulationCanChange, true),
TransferExecuted: e.TransferExecuted,
IsTransition: boolValueDefault(e.IsTransition, false),
IsLaying: boolValueDefault(e.IsLaying, false),
Approval: latestApproval,
}
}
@@ -125,6 +125,7 @@ func (RecordingModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate
nonstockRepo,
projectFlockPopulationRepo,
recordingRepo,
transferLayingRepo,
approvalService,
validate,
)
@@ -185,12 +185,14 @@ func (s recordingService) GetAll(c *fiber.Ctx, params *validation.Query) ([]enti
rate := recordingutil.ComputeDepletionRate(prev, current, totalChick)
recordings[i].DepletionRate = &rate
populationCanChange, transferExecuted, _, _, stateErr := s.evaluatePopulationMutationState(c.Context(), &recordings[i])
populationCanChange, transferExecuted, isTransition, isLaying, _, _, stateErr := s.evaluatePopulationMutationState(c.Context(), &recordings[i])
if stateErr != nil {
return nil, 0, stateErr
}
recordings[i].PopulationCanChange = boolPtr(populationCanChange)
recordings[i].TransferExecuted = boolPtr(transferExecuted)
recordings[i].IsTransition = boolPtr(isTransition)
recordings[i].IsLaying = boolPtr(isLaying)
}
return recordings, total, nil
}
@@ -251,12 +253,14 @@ func (s recordingService) GetOne(c *fiber.Ctx, id uint) (*entity.Recording, erro
recording.DepletionRate = &rate
}
populationCanChange, transferExecuted, _, _, stateErr := s.evaluatePopulationMutationState(c.Context(), recording)
populationCanChange, transferExecuted, isTransition, isLaying, _, _, stateErr := s.evaluatePopulationMutationState(c.Context(), recording)
if stateErr != nil {
return nil, stateErr
}
recording.PopulationCanChange = boolPtr(populationCanChange)
recording.TransferExecuted = boolPtr(transferExecuted)
recording.IsTransition = boolPtr(isTransition)
recording.IsLaying = boolPtr(isLaying)
return recording, nil
}
@@ -990,46 +994,58 @@ func (s *recordingService) resolveRecordingCategory(ctx context.Context, recordi
return strings.ToUpper(strings.TrimSpace(pfk.ProjectFlock.Category)), nil
}
func (s *recordingService) evaluatePopulationMutationState(ctx context.Context, recording *entity.Recording) (bool, bool, *entity.LayingTransfer, time.Time, error) {
func (s *recordingService) evaluatePopulationMutationState(ctx context.Context, recording *entity.Recording) (bool, bool, bool, bool, *entity.LayingTransfer, time.Time, error) {
if recording == nil || recording.ProjectFlockKandangId == 0 || s.TransferLayingRepo == nil {
return true, false, nil, time.Time{}, nil
return true, false, false, false, nil, time.Time{}, nil
}
category, err := s.resolveRecordingCategory(ctx, recording)
if err != nil {
s.Log.Errorf("Failed to resolve recording category for population mutation check (recording=%d): %+v", recording.Id, err)
return true, false, nil, time.Time{}, fiber.NewError(fiber.StatusInternalServerError, "Gagal memvalidasi perubahan populasi recording")
}
if category != strings.ToUpper(string(utils.ProjectFlockCategoryGrowing)) {
return true, false, nil, time.Time{}, nil
return true, false, false, false, nil, time.Time{}, fiber.NewError(fiber.StatusInternalServerError, "Gagal memvalidasi perubahan populasi recording")
}
transfer, err := s.TransferLayingRepo.GetLatestApprovedBySourceKandang(ctx, recording.ProjectFlockKandangId)
var transfer *entity.LayingTransfer
switch category {
case strings.ToUpper(string(utils.ProjectFlockCategoryGrowing)):
transfer, err = s.TransferLayingRepo.GetLatestApprovedBySourceKandang(ctx, recording.ProjectFlockKandangId)
case strings.ToUpper(string(utils.ProjectFlockCategoryLaying)):
transfer, err = s.TransferLayingRepo.GetLatestApprovedByTargetKandang(ctx, recording.ProjectFlockKandangId)
default:
return true, false, false, false, nil, time.Time{}, nil
}
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return true, false, nil, time.Time{}, nil
return true, false, false, false, nil, time.Time{}, nil
}
s.Log.Errorf("Failed to resolve approved transfer by source kandang for recording %d: %+v", recording.Id, err)
return true, false, nil, time.Time{}, fiber.NewError(fiber.StatusInternalServerError, "Gagal memvalidasi perubahan populasi recording")
s.Log.Errorf("Failed to resolve approved transfer for recording %d: %+v", recording.Id, err)
return true, false, false, false, nil, time.Time{}, fiber.NewError(fiber.StatusInternalServerError, "Gagal memvalidasi perubahan populasi recording")
}
if transfer == nil {
return true, false, nil, time.Time{}, nil
return true, false, false, false, nil, time.Time{}, nil
}
transferDate := transferPhysicalMoveDate(transfer)
if transferDate.IsZero() {
return true, false, transfer, transferDate, nil
return true, false, false, false, transfer, transferDate, nil
}
transferExecuted := transfer.ExecutedAt != nil && !transfer.ExecutedAt.IsZero()
recordDate := normalizeDateOnlyUTC(recording.RecordDatetime)
populationCanChange := !(transferExecuted && !recordDate.Before(transferDate))
_, economicCutoffDate := transferRecordingWindow(transfer)
isTransition := !recordDate.Before(transferDate) && recordDate.Before(economicCutoffDate)
isLaying := !recordDate.Before(economicCutoffDate)
return populationCanChange, transferExecuted, transfer, transferDate, nil
populationCanChange := true
if category == strings.ToUpper(string(utils.ProjectFlockCategoryGrowing)) {
populationCanChange = !(transferExecuted && !recordDate.Before(transferDate))
}
return populationCanChange, transferExecuted, isTransition, isLaying, transfer, transferDate, nil
}
func (s *recordingService) ensurePopulationMutationAllowed(ctx context.Context, recording *entity.Recording, operation string) error {
populationCanChange, _, transfer, transferDate, err := s.evaluatePopulationMutationState(ctx, recording)
populationCanChange, _, _, _, transfer, transferDate, err := s.evaluatePopulationMutationState(ctx, recording)
if err != nil {
return err
}
@@ -1590,7 +1606,7 @@ func (s *recordingService) computeAndUpdateMetrics(ctx context.Context, tx *gorm
var feedIntake float64
if remainingChick > 0 && usageInGrams > 0 {
feedIntake = (usageInGrams / remainingChick) * 1000
feedIntake = usageInGrams / remainingChick
updates["feed_intake"] = feedIntake
recording.FeedIntake = &feedIntake
} else {