diff --git a/internal/entities/projectflock_kandang.go b/internal/entities/projectflock_kandang.go index 0ce4fc25..5fa20404 100644 --- a/internal/entities/projectflock_kandang.go +++ b/internal/entities/projectflock_kandang.go @@ -10,8 +10,9 @@ type ProjectFlockKandang struct { ClosedAt *time.Time `gorm:"index"` CreatedAt time.Time `gorm:"autoCreateTime"` - ProjectFlock ProjectFlock `gorm:"foreignKey:ProjectFlockId;references:Id"` - Kandang Kandang `gorm:"foreignKey:KandangId;references:Id"` - Chickins []ProjectChickin `gorm:"foreignKey:ProjectFlockKandangId;references:Id"` - LatestApproval *Approval `gorm:"-" json:"-"` + ProjectFlock ProjectFlock `gorm:"foreignKey:ProjectFlockId;references:Id"` + Kandang Kandang `gorm:"foreignKey:KandangId;references:Id"` + Chickins []ProjectChickin `gorm:"foreignKey:ProjectFlockKandangId;references:Id"` + LatestProjectFlockApproval *Approval `gorm:"-" json:"-"` + LatestChickinApproval *Approval `gorm:"-" json:"-"` } diff --git a/internal/modules/production/project-flock-kandangs/dto/project_flock_kandang.dto.go b/internal/modules/production/project-flock-kandangs/dto/project_flock_kandang.dto.go index 58f04f1b..452cc7b3 100644 --- a/internal/modules/production/project-flock-kandangs/dto/project_flock_kandang.dto.go +++ b/internal/modules/production/project-flock-kandangs/dto/project_flock_kandang.dto.go @@ -28,14 +28,14 @@ type ProjectFlockKandangRelationDTO struct { type ProjectFlockDTO struct { projectFlockDTO.ProjectFlockRelationDTO - Area *areaDTO.AreaRelationDTO `json:"area,omitempty"` - Category string `json:"category"` - Fcr *fcrDTO.FcrRelationDTO `json:"fcr,omitempty"` + Area *areaDTO.AreaRelationDTO `json:"area,omitempty"` + Category string `json:"category"` + Fcr *fcrDTO.FcrRelationDTO `json:"fcr,omitempty"` ProductionStandard *productionStandardDTO.ProductionStandardRelationDTO `json:"production_standard,omitempty"` - Location *locationDTO.LocationRelationDTO `json:"location,omitempty"` - CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + Location *locationDTO.LocationRelationDTO `json:"location,omitempty"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type ProductWarehouseDTO struct { @@ -51,11 +51,12 @@ type AvailableQtyDTO struct { type ProjectFlockKandangListDTO struct { ProjectFlockKandangRelationDTO - ProjectFlock *ProjectFlockDTO `json:"project_flock,omitempty"` - Kandang *kandangDTO.KandangRelationDTO `json:"kandang,omitempty"` - CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"` - CreatedAt time.Time `json:"created_at"` - Approval *approvalDTO.ApprovalRelationDTO `json:"approval,omitempty"` + ProjectFlock *ProjectFlockDTO `json:"project_flock,omitempty"` + Kandang *kandangDTO.KandangRelationDTO `json:"kandang,omitempty"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"` + CreatedAt time.Time `json:"created_at"` + Approval *approvalDTO.ApprovalRelationDTO `json:"approval,omitempty"` + ChickinApproval *approvalDTO.ApprovalRelationDTO `json:"chickin_approval,omitempty"` } type ProjectFlockKandangDetailDTO struct { @@ -105,7 +106,8 @@ func ToProjectFlockKandangDetailDTOWithAvailableQty(e entity.ProjectFlockKandang Kandang: toKandangRelation(e.Kandang), CreatedAt: e.CreatedAt, CreatedUser: toCreatedUserDTO(e.ProjectFlock), - Approval: toApprovalDTO(e), + Approval: toApprovalDTOSelector(e, func(x entity.ProjectFlockKandang) *entity.Approval { return x.LatestProjectFlockApproval }), + ChickinApproval: toApprovalDTOSelector(e, func(x entity.ProjectFlockKandang) *entity.Approval { return x.LatestChickinApproval }), } return ProjectFlockKandangDetailDTO{ @@ -124,9 +126,11 @@ func toKandangRelation(kandang entity.Kandang) *kandangDTO.KandangRelationDTO { return &mapped } -func toApprovalDTO(e entity.ProjectFlockKandang) *approvalDTO.ApprovalRelationDTO { - if e.LatestApproval != nil { - mapped := approvalDTO.ToApprovalDTO(*e.LatestApproval) +func toApprovalDTOSelector( + e entity.ProjectFlockKandang, selector func(entity.ProjectFlockKandang) *entity.Approval) *approvalDTO.ApprovalRelationDTO { + approval := selector(e) + if approval != nil { + mapped := approvalDTO.ToApprovalDTO(*approval) return &mapped } return nil @@ -145,18 +149,11 @@ func ToProjectFlockKandangListDTO(e entity.ProjectFlockKandang) ProjectFlockKand Kandang: toKandangRelation(e.Kandang), CreatedAt: e.CreatedAt, CreatedUser: toCreatedUserDTO(e.ProjectFlock), - Approval: toApprovalDTO(e), + Approval: toApprovalDTOSelector(e, func(x entity.ProjectFlockKandang) *entity.Approval { return x.LatestProjectFlockApproval }), + ChickinApproval: toApprovalDTOSelector(e, func(x entity.ProjectFlockKandang) *entity.Approval { return x.LatestChickinApproval }), } } -func ToProjectFlockKandangListDTOs(e []entity.ProjectFlockKandang) []ProjectFlockKandangListDTO { - result := make([]ProjectFlockKandangListDTO, len(e)) - for i, r := range e { - result[i] = ToProjectFlockKandangListDTO(r) - } - return result -} - func toCreatedUserDTO(pf entity.ProjectFlock) *userDTO.UserRelationDTO { if pf.CreatedUser.Id != 0 { mapped := userDTO.ToUserRelationDTO(pf.CreatedUser) @@ -187,7 +184,6 @@ func toAvailableQtyDTOsFromMap(chickins []entity.ProjectChickin, availableQtyMap return nil } - // First, build map from chickins pwMap := make(map[uint]*entity.ProductWarehouse) for _, chickin := range chickins { if chickin.ProductWarehouse != nil && chickin.ProductWarehouse.Id != 0 { @@ -195,7 +191,6 @@ func toAvailableQtyDTOsFromMap(chickins []entity.ProjectChickin, availableQtyMap } } - // Then, add productWarehouses that are not in chickins yet for i := range productWarehouses { if _, exists := pwMap[productWarehouses[i].Id]; !exists { pwMap[productWarehouses[i].Id] = &productWarehouses[i] @@ -204,7 +199,7 @@ func toAvailableQtyDTOsFromMap(chickins []entity.ProjectChickin, availableQtyMap result := make([]AvailableQtyDTO, 0, len(availableQtyMap)) for pwId, availableQty := range availableQtyMap { - // Skip jika available qty = 0 + if availableQty <= 0 { continue } diff --git a/internal/modules/production/project-flock-kandangs/services/project_flock_kandang.service.go b/internal/modules/production/project-flock-kandangs/services/project_flock_kandang.service.go index 92ff2748..6f019ffa 100644 --- a/internal/modules/production/project-flock-kandangs/services/project_flock_kandang.service.go +++ b/internal/modules/production/project-flock-kandangs/services/project_flock_kandang.service.go @@ -98,23 +98,8 @@ func (s projectFlockKandangService) GetAll(c *fiber.Ctx, params *validation.Quer } if s.ApprovalSvc != nil { - projectFlockKandangIDs := make([]uint, len(projectFlockKandangs)) - for i, pfk := range projectFlockKandangs { - projectFlockKandangIDs[i] = pfk.Id - } - - approvalMap, err := s.ApprovalSvc.LatestByTargets(c.Context(), utils.ApprovalWorkflowProjectFlockKandang, projectFlockKandangIDs, func(db *gorm.DB) *gorm.DB { - return db.Preload("ActionUser") - }) - if err != nil { - s.Log.Warnf("Failed to fetch approvals for projectFlockKandangs: %+v", err) - } else { - for i := range projectFlockKandangs { - if approval, ok := approvalMap[projectFlockKandangs[i].Id]; ok { - projectFlockKandangs[i].LatestApproval = approval - } - } - } + s.fetchProjectFlockApprovals(c, projectFlockKandangs) + s.fetchChickinApprovals(c, projectFlockKandangs) } return projectFlockKandangs, total, nil @@ -130,14 +115,8 @@ func (s projectFlockKandangService) GetOne(c *fiber.Ctx, id uint) (*entity.Proje } if len(projectFlockKandang.Chickins) > 0 && s.ApprovalSvc != nil { - latest, err := s.ApprovalSvc.LatestByTarget(c.Context(), utils.ApprovalWorkflowProjectFlockKandang, projectFlockKandang.Id, nil) - if err != nil { - s.Log.Errorf("Failed to fetch latest kandang approval for projectFlockKandang %d: %+v", projectFlockKandang.Id, err) - } - - if latest != nil { - projectFlockKandang.LatestApproval = latest - } + s.fetchProjectFlockApproval(c, projectFlockKandang) + s.fetchChickinApproval(c, projectFlockKandang) } availableQtyMap, err := s.getAvailableQuantities(c, projectFlockKandang) @@ -164,6 +143,68 @@ func (s projectFlockKandangService) GetOne(c *fiber.Ctx, id uint) (*entity.Proje return projectFlockKandang, availableQtyMap, productWarehouses, nil } +func (s projectFlockKandangService) fetchProjectFlockApprovals(c *fiber.Ctx, projectFlockKandangs []entity.ProjectFlockKandang) { + projectFlockKandangIDs := make([]uint, len(projectFlockKandangs)) + for i, pfk := range projectFlockKandangs { + projectFlockKandangIDs[i] = pfk.Id + } + + approvalMap, err := s.ApprovalSvc.LatestByTargets(c.Context(), utils.ApprovalWorkflowProjectFlockKandang, projectFlockKandangIDs, func(db *gorm.DB) *gorm.DB { + return db.Preload("ActionUser") + }) + if err != nil { + s.Log.Warnf("Failed to fetch approvals for projectFlockKandangs: %+v", err) + } else { + for i := range projectFlockKandangs { + if approval, ok := approvalMap[projectFlockKandangs[i].Id]; ok { + projectFlockKandangs[i].LatestProjectFlockApproval = approval + } + } + } +} + +func (s projectFlockKandangService) fetchChickinApprovals(c *fiber.Ctx, projectFlockKandangs []entity.ProjectFlockKandang) { + projectFlockKandangIDs := make([]uint, len(projectFlockKandangs)) + for i, pfk := range projectFlockKandangs { + projectFlockKandangIDs[i] = pfk.Id + } + + chickinApprovalMap, err := s.ApprovalSvc.LatestByTargets(c.Context(), utils.ApprovalWorkflowChickin, projectFlockKandangIDs, func(db *gorm.DB) *gorm.DB { + return db.Preload("ActionUser") + }) + if err != nil { + s.Log.Warnf("Failed to fetch chickin approvals for projectFlockKandangs: %+v", err) + } else { + for i := range projectFlockKandangs { + if approval, ok := chickinApprovalMap[projectFlockKandangs[i].Id]; ok { + projectFlockKandangs[i].LatestChickinApproval = approval + } + } + } +} + +func (s projectFlockKandangService) fetchProjectFlockApproval(c *fiber.Ctx, projectFlockKandang *entity.ProjectFlockKandang) { + latest, err := s.ApprovalSvc.LatestByTarget(c.Context(), utils.ApprovalWorkflowProjectFlockKandang, projectFlockKandang.Id, nil) + if err != nil { + s.Log.Errorf("Failed to fetch latest kandang approval for projectFlockKandang %d: %+v", projectFlockKandang.Id, err) + } + + if latest != nil { + projectFlockKandang.LatestProjectFlockApproval = latest + } +} + +func (s projectFlockKandangService) fetchChickinApproval(c *fiber.Ctx, projectFlockKandang *entity.ProjectFlockKandang) { + latestChickin, err := s.ApprovalSvc.LatestByTarget(c.Context(), utils.ApprovalWorkflowChickin, projectFlockKandang.Id, nil) + if err != nil { + s.Log.Errorf("Failed to fetch latest chickin approval for projectFlockKandang %d: %+v", projectFlockKandang.Id, err) + } + + if latestChickin != nil { + projectFlockKandang.LatestChickinApproval = latestChickin + } +} + func (s projectFlockKandangService) getAvailableQuantities(c *fiber.Ctx, projectFlockKandang *entity.ProjectFlockKandang) (map[uint]float64, error) { if projectFlockKandang.Kandang.Id == 0 || s.WarehouseRepo == nil || s.ProductWarehouseRepo == nil { return nil, nil