package dto import ( "time" "gitlab.com/mbugroup/lti-api.git/internal/config" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" approvalDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/approvals/dto" areaDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/areas/dto" kandangDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/dto" locationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations/dto" nonstockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/nonstocks/dto" productionStandardDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/production-standards/dto" // pfutils "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/utils" userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto" "gitlab.com/mbugroup/lti-api.git/internal/utils" approvalutils "gitlab.com/mbugroup/lti-api.git/internal/utils/approvals" ) type ProjectFlockRelationDTO struct { Id uint `json:"id"` Period int `json:"period"` FlockName string `json:"flock_name"` } type ProjectFlockListDTO struct { ProjectFlockRelationDTO Area *areaDTO.AreaRelationDTO `json:"area,omitempty"` Category string `json:"category"` StandardFcr *float64 `json:"standard_fcr,omitempty"` ProductionStandard *productionStandardDTO.ProductionStandardRelationDTO `json:"production_standard,omitempty"` Location *locationDTO.LocationRelationDTO `json:"location,omitempty"` Kandangs []KandangWithProjectFlockIdDTO `json:"kandangs,omitempty"` ProjectBudgets []ProjectBudgetDTO `json:"project_budgets,omitempty"` CreatedUser *userDTO.UserRelationDTO `json:"created_user"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` Approval approvalDTO.ApprovalRelationDTO `json:"approval"` } type KandangWithProjectFlockIdDTO struct { kandangDTO.KandangRelationDTO ProjectFlockKandangId uint `json:"project_flock_kandang_id"` Period int `json:"period"` ClosedAt *time.Time `json:"closed_at,omitempty"` } type ProjectFlockDetailDTO struct { ProjectFlockListDTO } type KandangPeriodSummaryDTO struct { Id uint `json:"id"` Name string `json:"name"` Period int `json:"period"` } type ProjectBudgetDTO struct { Id uint `json:"id"` Qty float64 `json:"qty"` Price float64 `json:"price"` Nonstock *nonstockDTO.NonstockRelationDTO `json:"nonstock,omitempty"` } func ToProjectFlockListDTOWithPeriod(e entity.ProjectFlock, period int) ProjectFlockListDTO { var createdUser *userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { mapped := userDTO.ToUserRelationDTO(e.CreatedUser) createdUser = &mapped } var kandangSummaries []KandangWithProjectFlockIdDTO if len(e.Kandangs) > 0 { kandangSummaries = make([]KandangWithProjectFlockIdDTO, len(e.Kandangs)) for i, kandang := range e.Kandangs { var ( pfkId uint period int closedAt *time.Time ) for _, kh := range e.KandangHistory { if kh.KandangId == kandang.Id { pfkId = kh.Id period = kh.Period closedAt = kh.ClosedAt break } } mapped := kandangDTO.ToKandangRelationDTO(kandang) if closedAt != nil { // Jangan ubah tabel kandang, hanya override status di response. mapped.Status = string(utils.KandangStatusNonActive) } kandangSummaries[i] = KandangWithProjectFlockIdDTO{ KandangRelationDTO: mapped, ProjectFlockKandangId: pfkId, Period: period, ClosedAt: closedAt, } } } var areaSummary *areaDTO.AreaRelationDTO if e.Area.Id != 0 { mapped := areaDTO.ToAreaRelationDTO(e.Area) areaSummary = &mapped } var productionStandardSummary *productionStandardDTO.ProductionStandardRelationDTO if e.ProductionStandard.Id != 0 { mapped := productionStandardDTO.ToProductionStandardRelationDTO(e.ProductionStandard) productionStandardSummary = &mapped } var locationSummary *locationDTO.LocationRelationDTO if e.Location.Id != 0 { mapped := locationDTO.ToLocationRelationDTO(e.Location) locationSummary = &mapped } // Jika period tidak di-pass secara eksplisit (0), derive dari KandangHistory if period == 0 && len(e.KandangHistory) > 0 { period = e.KandangHistory[0].Period } latestApproval := defaultProjectFlockLatestApproval(e) if e.LatestApproval != nil { snapshot := approvalDTO.ToApprovalDTO(*e.LatestApproval) latestApproval = snapshot } return ProjectFlockListDTO{ ProjectFlockRelationDTO: createProjectFlockRelationDTO(e, period), Area: areaSummary, Kandangs: kandangSummaries, ProjectBudgets: ToProjectBudgetDTOs(e.Budgets), Category: e.Category, StandardFcr: resolveProjectFlockStandardFcr(e), ProductionStandard: productionStandardSummary, Location: locationSummary, CreatedAt: e.CreatedAt, UpdatedAt: e.UpdatedAt, CreatedUser: createdUser, Approval: latestApproval, } } func ToProjectFlockListDTOs(items []entity.ProjectFlock) []ProjectFlockListDTO { result := make([]ProjectFlockListDTO, len(items)) for i, item := range items { result[i] = ToProjectFlockListDTOWithPeriod(item, 0) } return result } func ToProjectFlockListDTO(e entity.ProjectFlock) ProjectFlockListDTO { return ToProjectFlockListDTOWithPeriod(e, 0) } func ToProjectFlockListDTOsWithPeriods(items []entity.ProjectFlock, periods map[uint]int) []ProjectFlockListDTO { result := make([]ProjectFlockListDTO, len(items)) for i, item := range items { p := 0 if periods != nil { if v, ok := periods[item.Id]; ok { p = v } } result[i] = ToProjectFlockListDTOWithPeriod(item, p) } return result } func ToProjectFlockDetailDTO(e entity.ProjectFlock) ProjectFlockDetailDTO { return ProjectFlockDetailDTO{ ProjectFlockListDTO: ToProjectFlockListDTOWithPeriod(e, 0), } } func defaultProjectFlockLatestApproval(e entity.ProjectFlock) approvalDTO.ApprovalRelationDTO { result := approvalDTO.ApprovalRelationDTO{} step := utils.ProjectFlockStepPengajuan if step > 0 { result.StepNumber = uint16(step) if label, ok := approvalutils.ApprovalStepName(utils.ApprovalWorkflowProjectFlock, step); ok { result.StepName = label } else if label, ok := utils.ProjectFlockApprovalSteps[step]; ok { result.StepName = label } } if e.CreatedUser.Id != 0 { result.ActionBy = userDTO.ToUserRelationDTO(e.CreatedUser) } else if e.CreatedBy != 0 { result.ActionBy = userDTO.UserRelationDTO{ Id: e.CreatedBy, IdUser: int64(e.CreatedBy), } } return result } func createProjectFlockRelationDTO(e entity.ProjectFlock, period int) ProjectFlockRelationDTO { return ProjectFlockRelationDTO{ Id: e.Id, Period: period, FlockName: e.FlockName, } } func resolveProjectFlockStandardFcr(e entity.ProjectFlock) *float64 { if e.ProductionStandard.Id == 0 || len(e.ProductionStandard.ProductionStandardDetails) == 0 { return nil } week := 1 if e.Category == string(utils.ProjectFlockCategoryLaying) { week = config.LayingWeekStart() } for _, detail := range e.ProductionStandard.ProductionStandardDetails { if detail.Week == week && detail.StandardFCR != nil { return detail.StandardFCR } } return nil } func ToProjectBudgetDTO(e entity.ProjectBudget) ProjectBudgetDTO { var nonstockRef *nonstockDTO.NonstockRelationDTO if e.Nonstock != nil && e.Nonstock.Id != 0 { mapped := nonstockDTO.ToNonstockRelationDTO(*e.Nonstock) nonstockRef = &mapped } return ProjectBudgetDTO{ Id: e.Id, Qty: e.Qty, Price: e.Price, Nonstock: nonstockRef, } } func ToProjectBudgetDTOs(e []entity.ProjectBudget) []ProjectBudgetDTO { result := make([]ProjectBudgetDTO, len(e)) for i, r := range e { result[i] = ToProjectBudgetDTO(r) } return result }