diff --git a/internal/entities/recording.go b/internal/entities/recording.go index 404c4986..e07a0a6b 100644 --- a/internal/entities/recording.go +++ b/internal/entities/recording.go @@ -33,4 +33,10 @@ type Recording struct { Eggs []RecordingEgg `gorm:"foreignKey:RecordingId;references:Id"` LatestApproval *Approval `gorm:"-" json:"-"` + + StandardHandDay *float64 `gorm:"-"` + StandardHandHouse *float64 `gorm:"-"` + StandardFeedIntake *float64 `gorm:"-"` + StandardEggMesh *float64 `gorm:"-"` + StandardEggWeight *float64 `gorm:"-"` } diff --git a/internal/modules/production/recordings/dto/recording.dto.go b/internal/modules/production/recordings/dto/recording.dto.go index d38642b9..12222b97 100644 --- a/internal/modules/production/recordings/dto/recording.dto.go +++ b/internal/modules/production/recordings/dto/recording.dto.go @@ -30,6 +30,11 @@ type RecordingRelationDTO struct { FeedIntake float64 `json:"feed_intake"` EggMesh float64 `json:"egg_mesh"` EggWeight float64 `json:"egg_weight"` + StandardHandDay *float64 `json:"hand_day_std,omitempty"` + StandardHandHouse *float64 `json:"hand_house_std,omitempty"` + StandardFeedIntake *float64 `json:"feed_intake_std,omitempty"` + StandardEggMesh *float64 `json:"egg_mesh_std,omitempty"` + StandardEggWeight *float64 `json:"egg_weight_std,omitempty"` Approval approvalDTO.ApprovalRelationDTO `json:"approval"` } @@ -155,6 +160,11 @@ func ToRecordingRelationDTO(e entity.Recording) RecordingRelationDTO { FeedIntake: feedIntake, EggMesh: eggMesh, EggWeight: eggWeight, + StandardHandDay: e.StandardHandDay, + StandardHandHouse: e.StandardHandHouse, + StandardFeedIntake: e.StandardFeedIntake, + StandardEggMesh: e.StandardEggMesh, + StandardEggWeight: e.StandardEggWeight, Approval: latestApproval, } } diff --git a/internal/modules/production/recordings/services/recording.service.go b/internal/modules/production/recordings/services/recording.service.go index 2098aad6..a3756adf 100644 --- a/internal/modules/production/recordings/services/recording.service.go +++ b/internal/modules/production/recordings/services/recording.service.go @@ -9,6 +9,7 @@ import ( 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" + rProductionStandard "gitlab.com/mbugroup/lti-api.git/internal/modules/master/production-standards/repositories" rProjectFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories" repository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/recordings/repositories" validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/recordings/validations" @@ -121,6 +122,9 @@ func (s recordingService) GetAll(c *fiber.Ctx, params *validation.Query) ([]enti if err := s.attachLatestApprovals(c.Context(), recordings); err != nil { return nil, 0, err } + if err := s.attachProductionStandards(c.Context(), recordings); err != nil { + return nil, 0, err + } return recordings, total, nil } @@ -138,6 +142,9 @@ func (s recordingService) GetOne(c *fiber.Ctx, id uint) (*entity.Recording, erro if err := s.attachLatestApproval(c.Context(), recording); err != nil { return nil, err } + if err := s.attachProductionStandard(c.Context(), recording); err != nil { + return nil, err + } return recording, nil } @@ -255,7 +262,7 @@ func (s *recordingService) CreateOne(c *fiber.Ctx, req *validation.Create) (*ent return err } - if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(nil, mappedDepletions, nil, mappedEggs)); err != nil { + if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(nil, mappedDepletions, nil, mappedEggs)); err != nil { s.Log.Errorf("Failed to adjust product warehouses: %+v", err) return err } @@ -384,7 +391,7 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin return err } - if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(existingDepletions, mappedDepletions, nil, nil)); err != nil { + if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(existingDepletions, mappedDepletions, nil, nil)); err != nil { s.Log.Errorf("Failed to adjust product warehouses for depletions: %+v", err) return err } @@ -408,7 +415,7 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin return err } - if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(nil, nil, existingEggs, mappedEggs)); err != nil { + if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(nil, nil, existingEggs, mappedEggs)); err != nil { s.Log.Errorf("Failed to adjust product warehouses for eggs: %+v", err) return err } @@ -578,7 +585,7 @@ func (s recordingService) DeleteOne(c *fiber.Ctx, id uint) error { return err } - if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(oldDepletions, nil, oldEggs, nil)); err != nil { + if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(oldDepletions, nil, oldEggs, nil)); err != nil { return err } @@ -1008,6 +1015,84 @@ func (s *recordingService) attachLatestApproval(ctx context.Context, item *entit return nil } +type productionStandardValues struct { + HandDay *float64 + HandHouse *float64 + FeedIntake *float64 + EggMesh *float64 + EggWeight *float64 +} + +func (s *recordingService) attachProductionStandards(ctx context.Context, items []entity.Recording) error { + if len(items) == 0 { + return nil + } + + for i := range items { + if err := s.attachProductionStandard(ctx, &items[i]); err != nil { + s.Log.Warnf("Unable to load production standard for recording %d: %+v", items[i].Id, err) + } + } + return nil +} + +func (s *recordingService) attachProductionStandard(ctx context.Context, item *entity.Recording) error { + if item == nil || item.Id == 0 { + return nil + } + if item.Day == nil || *item.Day <= 0 { + return nil + } + if item.ProjectFlockKandang == nil || item.ProjectFlockKandang.ProjectFlock.Id == 0 { + return nil + } + + standardID := item.ProjectFlockKandang.ProjectFlock.ProductionStandardId + if standardID == 0 { + return nil + } + + week := ((int(*item.Day) - 1) / 7) + 1 + if week <= 0 { + return nil + } + + category := strings.ToUpper(item.ProjectFlockKandang.ProjectFlock.Category) + db := s.Repository.DB() + standardDetailRepo := rProductionStandard.NewProductionStandardDetailRepository(db) + growthDetailRepo := rProductionStandard.NewStandardGrowthDetailRepository(db) + + var standard productionStandardValues + if category == string(utils.ProjectFlockCategoryLaying) { + detail, err := standardDetailRepo.GetByStandardIDAndWeek(ctx, standardID, week) + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + return err + } + if detail != nil { + standard.HandDay = detail.TargetHenDayProduction + standard.HandHouse = detail.TargetHenHouseProduction + standard.EggWeight = detail.TargetEggWeight + standard.EggMesh = detail.TargetEggMass + } + } + + growthDetail, err := growthDetailRepo.GetByStandardIDAndWeek(ctx, standardID, week) + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + return err + } + if growthDetail != nil { + standard.FeedIntake = growthDetail.FeedIntake + } + + item.StandardHandDay = standard.HandDay + item.StandardHandHouse = standard.HandHouse + item.StandardFeedIntake = standard.FeedIntake + item.StandardEggMesh = standard.EggMesh + item.StandardEggWeight = standard.EggWeight + + return nil +} + func uniqueUintSlice(values []uint) []uint { if len(values) == 0 { return nil