From 6b5d27ae8e992e7eae86ffd414d6330b117d67c6 Mon Sep 17 00:00:00 2001 From: aguhh18 Date: Tue, 11 Nov 2025 12:16:39 +0700 Subject: [PATCH] feat[BE]: add flock response to project flock and projectflockkandang getone and getall API --- .../project_flock_kandang.controller.go | 13 ++- .../dto/project_flock_kandang.dto.go | 24 ++++- .../project-flock-kandangs/module.go | 4 +- .../services/project_flock_kandang.service.go | 62 ++++++++++--- .../controllers/projectflock.controller.go | 24 +++-- .../project_flocks/dto/projectflock.dto.go | 64 +++++++++----- .../services/projectflock.service.go | 87 ++++++++++++++++--- 7 files changed, 220 insertions(+), 58 deletions(-) diff --git a/internal/modules/production/project-flock-kandangs/controllers/project_flock_kandang.controller.go b/internal/modules/production/project-flock-kandangs/controllers/project_flock_kandang.controller.go index 94316dce..d65cedfd 100644 --- a/internal/modules/production/project-flock-kandangs/controllers/project_flock_kandang.controller.go +++ b/internal/modules/production/project-flock-kandangs/controllers/project_flock_kandang.controller.go @@ -4,6 +4,7 @@ import ( "math" "strconv" + flockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto" "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project-flock-kandangs/dto" service "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project-flock-kandangs/services" validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project-flock-kandangs/validations" @@ -40,14 +41,18 @@ func (u *ProjectFlockKandangController) GetAll(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusBadRequest, "page and limit must be greater than 0") } - results, totalResults, err := u.ProjectFlockKandangService.GetAll(c, query) + results, totalResults, flockMap, err := u.ProjectFlockKandangService.GetAll(c, query) if err != nil { return err } data := make([]dto.ProjectFlockKandangListDTO, 0) for _, result := range results { - data = append(data, dto.ToProjectFlockKandangListDTO(result)) + var flock *flockDTO.FlockBaseDTO + if flockMap != nil { + flock = flockMap[result.ProjectFlock.Id] + } + data = append(data, dto.ToProjectFlockKandangListDTOWithFlock(result, flock)) } return c.Status(fiber.StatusOK). @@ -73,7 +78,7 @@ func (u *ProjectFlockKandangController) GetOne(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusBadRequest, "Invalid Id") } - result, availableQtys, productWarehouses, err := u.ProjectFlockKandangService.GetOne(c, uint(id)) + result, availableQtys, productWarehouses, flock, err := u.ProjectFlockKandangService.GetOne(c, uint(id)) if err != nil { return err } @@ -83,6 +88,6 @@ func (u *ProjectFlockKandangController) GetOne(c *fiber.Ctx) error { Code: fiber.StatusOK, Status: "success", Message: "Get projectFlockKandang successfully", - Data: dto.ToProjectFlockKandangDetailDTOWithAvailableQty(*result, availableQtys, productWarehouses), + Data: dto.ToProjectFlockKandangDetailDTOWithAvailableQtyAndFlock(*result, availableQtys, productWarehouses, flock), }) } 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 35bf615d..5d8e6628 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 @@ -87,6 +87,7 @@ func toProjectFlockDTO(pf *projectFlockDTO.ProjectFlockListDTO) *ProjectFlockDTO Id: pf.Id, Name: pf.FlockName, Period: pf.Period, + Flock: pf.Flock, Area: pf.Area, Category: pf.Category, Fcr: pf.Fcr, @@ -98,9 +99,13 @@ func toProjectFlockDTO(pf *projectFlockDTO.ProjectFlockListDTO) *ProjectFlockDTO } func ToProjectFlockKandangDetailDTOWithAvailableQty(e entity.ProjectFlockKandang, availableQtyMap map[uint]float64, productWarehouses []entity.ProductWarehouse) ProjectFlockKandangDetailDTO { + return ToProjectFlockKandangDetailDTOWithAvailableQtyAndFlock(e, availableQtyMap, productWarehouses, nil) +} + +func ToProjectFlockKandangDetailDTOWithAvailableQtyAndFlock(e entity.ProjectFlockKandang, availableQtyMap map[uint]float64, productWarehouses []entity.ProductWarehouse, flock *flockDTO.FlockBaseDTO) ProjectFlockKandangDetailDTO { var projectFlockSummary *projectFlockDTO.ProjectFlockListDTO if e.ProjectFlock.Id != 0 { - mapped := projectFlockDTO.ToProjectFlockListDTO(e.ProjectFlock) + mapped := projectFlockDTO.ToProjectFlockListDTO(e.ProjectFlock, flock) projectFlockSummary = &mapped } @@ -132,6 +137,17 @@ func toKandangDTO(kandang entity.Kandang) *KandangDTO { } } +func toFlockDTO(flock *entity.Flock) *flockDTO.FlockBaseDTO { + if flock == nil || flock.Id == 0 { + return nil + } + + return &flockDTO.FlockBaseDTO{ + Id: flock.Id, + Name: flock.Name, + } +} + func toApprovalDTO(e entity.ProjectFlockKandang) *approvalDTO.ApprovalBaseDTO { if e.LatestApproval != nil { mapped := approvalDTO.ToApprovalDTO(*e.LatestApproval) @@ -141,9 +157,13 @@ func toApprovalDTO(e entity.ProjectFlockKandang) *approvalDTO.ApprovalBaseDTO { } func ToProjectFlockKandangListDTO(e entity.ProjectFlockKandang) ProjectFlockKandangListDTO { + return ToProjectFlockKandangListDTOWithFlock(e, nil) +} + +func ToProjectFlockKandangListDTOWithFlock(e entity.ProjectFlockKandang, flock *flockDTO.FlockBaseDTO) ProjectFlockKandangListDTO { var projectFlockSummary *projectFlockDTO.ProjectFlockListDTO if e.ProjectFlock.Id != 0 { - mapped := projectFlockDTO.ToProjectFlockListDTO(e.ProjectFlock) + mapped := projectFlockDTO.ToProjectFlockListDTOWithFlock(e.ProjectFlock, flock) projectFlockSummary = &mapped } diff --git a/internal/modules/production/project-flock-kandangs/module.go b/internal/modules/production/project-flock-kandangs/module.go index 160cec5e..3e7e8fa0 100644 --- a/internal/modules/production/project-flock-kandangs/module.go +++ b/internal/modules/production/project-flock-kandangs/module.go @@ -13,6 +13,7 @@ import ( commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository" commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service" rProductWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories" + rFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories" rWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories" "gitlab.com/mbugroup/lti-api.git/internal/utils" @@ -28,6 +29,7 @@ func (ProjectFlockKandangModule) RegisterRoutes(router fiber.Router, db *gorm.DB userRepo := rUser.NewUserRepository(db) warehouseRepo := rWarehouse.NewWarehouseRepository(db) productWarehouseRepo := rProductWarehouse.NewProductWarehouseRepository(db) + flockRepo := rFlock.NewFlockRepository(db) approvalRepo := commonRepo.NewApprovalRepository(db) approvalService := commonSvc.NewApprovalService(approvalRepo) @@ -36,7 +38,7 @@ func (ProjectFlockKandangModule) RegisterRoutes(router fiber.Router, db *gorm.DB panic(fmt.Sprintf("failed to register project flock kandang approval workflow: %v", err)) } - projectFlockKandangService := sProjectFlockKandang.NewProjectFlockKandangService(projectFlockKandangRepo, approvalService, warehouseRepo, productWarehouseRepo, projectFlockPopulationRepo, validate) + projectFlockKandangService := sProjectFlockKandang.NewProjectFlockKandangService(projectFlockKandangRepo, approvalService, warehouseRepo, productWarehouseRepo, projectFlockPopulationRepo, flockRepo, validate) userService := sUser.NewUserService(userRepo, validate) ProjectFlockKandangRoutes(router, userService, projectFlockKandangService) 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 11e8b0d5..349eca4d 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 @@ -6,9 +6,12 @@ import ( commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" rProductWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories" + flockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto" + flockRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories" rWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories" validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project-flock-kandangs/validations" repository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories" + pfutils "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/utils" "gitlab.com/mbugroup/lti-api.git/internal/utils" "github.com/go-playground/validator/v10" @@ -18,8 +21,8 @@ import ( ) type ProjectFlockKandangService interface { - GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlockKandang, int64, error) - GetOne(ctx *fiber.Ctx, id uint) (*entity.ProjectFlockKandang, map[uint]float64, []entity.ProductWarehouse, error) + GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlockKandang, int64, map[uint]*flockDTO.FlockBaseDTO, error) + GetOne(ctx *fiber.Ctx, id uint) (*entity.ProjectFlockKandang, map[uint]float64, []entity.ProductWarehouse, *flockDTO.FlockBaseDTO, error) } // Note: map[uint]float64 adalah mapping dari ProductWarehouse ID ke calculated available quantity @@ -32,9 +35,10 @@ type projectFlockKandangService struct { WarehouseRepo rWarehouse.WarehouseRepository ProductWarehouseRepo rProductWarehouse.ProductWarehouseRepository PopulationRepo repository.ProjectFlockPopulationRepository + FlockRepo flockRepository.FlockRepository } -func NewProjectFlockKandangService(repo repository.ProjectFlockKandangRepository, approvalSvc commonSvc.ApprovalService, warehouseRepo rWarehouse.WarehouseRepository, productWarehouseRepo rProductWarehouse.ProductWarehouseRepository, populationRepo repository.ProjectFlockPopulationRepository, validate *validator.Validate) ProjectFlockKandangService { +func NewProjectFlockKandangService(repo repository.ProjectFlockKandangRepository, approvalSvc commonSvc.ApprovalService, warehouseRepo rWarehouse.WarehouseRepository, productWarehouseRepo rProductWarehouse.ProductWarehouseRepository, populationRepo repository.ProjectFlockPopulationRepository, flockRepo flockRepository.FlockRepository, validate *validator.Validate) ProjectFlockKandangService { return &projectFlockKandangService{ Log: utils.Log, Validate: validate, @@ -43,12 +47,13 @@ func NewProjectFlockKandangService(repo repository.ProjectFlockKandangRepository WarehouseRepo: warehouseRepo, ProductWarehouseRepo: productWarehouseRepo, PopulationRepo: populationRepo, + FlockRepo: flockRepo, } } -func (s projectFlockKandangService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlockKandang, int64, error) { +func (s projectFlockKandangService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlockKandang, int64, map[uint]*flockDTO.FlockBaseDTO, error) { if err := s.Validate.Struct(params); err != nil { - return nil, 0, err + return nil, 0, nil, err } offset := (params.Page - 1) * params.Limit @@ -57,7 +62,7 @@ func (s projectFlockKandangService) GetAll(c *fiber.Ctx, params *validation.Quer if err != nil { s.Log.Errorf("Failed to get projectFlockKandangs: %+v", err) - return nil, 0, err + return nil, 0, nil, err } if s.ApprovalSvc != nil { @@ -80,16 +85,36 @@ func (s projectFlockKandangService) GetAll(c *fiber.Ctx, params *validation.Quer } } - return projectFlockKandangs, total, nil + // Fetch Flock master data for each ProjectFlockKandang + flockMap := make(map[uint]*flockDTO.FlockBaseDTO) + for i := range projectFlockKandangs { + if projectFlockKandangs[i].ProjectFlock.Id != 0 { + baseName := pfutils.DeriveBaseName(projectFlockKandangs[i].ProjectFlock.FlockName) + if baseName != "" { + flock, err := s.FlockRepo.GetByName(c.Context(), baseName) + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + s.Log.Warnf("Failed to fetch flock %q: %+v", baseName, err) + } else if flock != nil { + // Convert to DTO and store in map with ProjectFlockId as key + flockMap[projectFlockKandangs[i].ProjectFlock.Id] = &flockDTO.FlockBaseDTO{ + Id: flock.Id, + Name: flock.Name, + } + } + } + } + } + + return projectFlockKandangs, total, flockMap, nil } -func (s projectFlockKandangService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlockKandang, map[uint]float64, []entity.ProductWarehouse, error) { +func (s projectFlockKandangService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlockKandang, map[uint]float64, []entity.ProductWarehouse, *flockDTO.FlockBaseDTO, error) { projectFlockKandang, err := s.Repository.GetByID(c.Context(), id) if errors.Is(err, gorm.ErrRecordNotFound) { - return nil, nil, nil, fiber.NewError(fiber.StatusNotFound, "ProjectFlockKandang not found") + return nil, nil, nil, nil, fiber.NewError(fiber.StatusNotFound, "ProjectFlockKandang not found") } if err != nil { - return nil, nil, nil, err + return nil, nil, nil, nil, err } if len(projectFlockKandang.Chickins) > 0 && s.ApprovalSvc != nil { @@ -123,8 +148,23 @@ func (s projectFlockKandangService) GetOne(c *fiber.Ctx, id uint) (*entity.Proje productWarehouses = []entity.ProductWarehouse{} } } + var flockResult *flockDTO.FlockBaseDTO + if projectFlockKandang.ProjectFlock.Id != 0 { + baseName := pfutils.DeriveBaseName(projectFlockKandang.ProjectFlock.FlockName) + if baseName != "" { + flock, err := s.FlockRepo.GetByName(c.Context(), baseName) + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + s.Log.Warnf("Failed to fetch flock %q: %+v", baseName, err) + } else if flock != nil { + flockResult = &flockDTO.FlockBaseDTO{ + Id: flock.Id, + Name: flock.Name, + } + } + } + } - return projectFlockKandang, availableQtyMap, productWarehouses, nil + return projectFlockKandang, availableQtyMap, productWarehouses, flockResult, nil } func (s projectFlockKandangService) getAvailableQuantities(c *fiber.Ctx, projectFlockKandang *entity.ProjectFlockKandang) (map[uint]float64, error) { diff --git a/internal/modules/production/project_flocks/controllers/projectflock.controller.go b/internal/modules/production/project_flocks/controllers/projectflock.controller.go index cf2dff05..67b04f99 100644 --- a/internal/modules/production/project_flocks/controllers/projectflock.controller.go +++ b/internal/modules/production/project_flocks/controllers/projectflock.controller.go @@ -7,6 +7,7 @@ import ( "strconv" "strings" + flockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto" "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/dto" service "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/services" validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/validations" @@ -84,11 +85,20 @@ func (u *ProjectflockController) GetAll(c *fiber.Ctx) error { query.KandangIds = ids } - result, totalResults, err := u.ProjectflockService.GetAll(c, query) + result, totalResults, flockMap, err := u.ProjectflockService.GetAll(c, query) if err != nil { return err } + data := make([]dto.ProjectFlockListDTO, 0) + for _, projectFlock := range result { + var flock *flockDTO.FlockBaseDTO + if flockMap != nil { + flock = flockMap[projectFlock.Id] + } + data = append(data, dto.ToProjectFlockListDTO(projectFlock, flock)) + } + return c.Status(fiber.StatusOK). JSON(response.SuccessWithPaginate[dto.ProjectFlockListDTO]{ Code: fiber.StatusOK, @@ -100,7 +110,7 @@ func (u *ProjectflockController) GetAll(c *fiber.Ctx) error { TotalPages: int64(math.Ceil(float64(totalResults) / float64(query.Limit))), TotalResults: totalResults, }, - Data: dto.ToProjectFlockListDTOs(result), + Data: data, }) } @@ -112,7 +122,7 @@ func (u *ProjectflockController) GetOne(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusBadRequest, "Invalid Id") } - result, err := u.ProjectflockService.GetOne(c, uint(id)) + result, flock, err := u.ProjectflockService.GetOne(c, uint(id)) if err != nil { return err } @@ -122,7 +132,7 @@ func (u *ProjectflockController) GetOne(c *fiber.Ctx) error { Code: fiber.StatusOK, Status: "success", Message: "Get projectflock successfully", - Data: dto.ToProjectFlockListDTO(*result), + Data: dto.ToProjectFlockListDTO(*result, flock), }) } @@ -143,7 +153,7 @@ func (u *ProjectflockController) CreateOne(c *fiber.Ctx) error { Code: fiber.StatusCreated, Status: "success", Message: "Create projectflock successfully", - Data: dto.ToProjectFlockListDTO(*result), + Data: dto.ToProjectFlockListDTO(*result, nil), }) } @@ -170,7 +180,7 @@ func (u *ProjectflockController) UpdateOne(c *fiber.Ctx) error { Code: fiber.StatusOK, Status: "success", Message: "Update projectflock successfully", - Data: dto.ToProjectFlockListDTO(*result), + Data: dto.ToProjectFlockListDTO(*result, nil), }) } @@ -210,7 +220,7 @@ func (u *ProjectflockController) Approval(c *fiber.Ctx) error { message = "Submit projectflock approval successfully" ) if len(results) == 1 { - data = dto.ToProjectFlockListDTO(results[0]) + data = dto.ToProjectFlockListDTO(results[0], nil) } else { message = "Submit projectflock approvals successfully" data = dto.ToProjectFlockListDTOs(results) diff --git a/internal/modules/production/project_flocks/dto/projectflock.dto.go b/internal/modules/production/project_flocks/dto/projectflock.dto.go index ce9be3d3..2230d865 100644 --- a/internal/modules/production/project_flocks/dto/projectflock.dto.go +++ b/internal/modules/production/project_flocks/dto/projectflock.dto.go @@ -25,7 +25,7 @@ type ProjectFlockBaseDTO struct { type ProjectFlockListDTO struct { ProjectFlockBaseDTO - // Flock *flockDTO.FlockBaseDTO `json:"flock,omitempty"` + Flock *flockDTO.FlockBaseDTO `json:"flock,omitempty"` Area *areaDTO.AreaBaseDTO `json:"area,omitempty"` Category string `json:"category"` Fcr *fcrDTO.FcrBaseDTO `json:"fcr,omitempty"` @@ -51,7 +51,7 @@ type FlockPeriodDTO struct { NextPeriod int `json:"next_period"` } -func ToProjectFlockListDTO(e entity.ProjectFlock) ProjectFlockListDTO { +func ToProjectFlockListDTO(e entity.ProjectFlock, flock *flockDTO.FlockBaseDTO) ProjectFlockListDTO { var createdUser *userDTO.UserBaseDTO if e.CreatedUser.Id != 0 { mapped := userDTO.ToUserBaseDTO(e.CreatedUser) @@ -62,7 +62,7 @@ func ToProjectFlockListDTO(e entity.ProjectFlock) ProjectFlockListDTO { if len(e.Kandangs) > 0 { kandangSummaries = make([]KandangWithProjectFlockIdDTO, len(e.Kandangs)) for i, kandang := range e.Kandangs { - // Find project_flock_kandang_id dari KandangHistory + var pfkId uint for _, kh := range e.KandangHistory { if kh.KandangId == kandang.Id { @@ -77,12 +77,6 @@ func ToProjectFlockListDTO(e entity.ProjectFlock) ProjectFlockListDTO { } } - // var flockSummary *flockDTO.FlockBaseDTO - // if baseName := pfutils.DeriveBaseName(e.FlockName); baseName != "" { - // summary := flockDTO.FlockBaseDTO{Id: 0, Name: baseName} - // flockSummary = &summary - // } - var areaSummary *areaDTO.AreaBaseDTO if e.Area.Id != 0 { mapped := areaDTO.ToAreaBaseDTO(e.Area) @@ -101,6 +95,11 @@ func ToProjectFlockListDTO(e entity.ProjectFlock) ProjectFlockListDTO { locationSummary = &mapped } + var flockSummary *flockDTO.FlockBaseDTO + if flock != nil && flock.Id != 0 { + flockSummary = flock + } + latestApproval := defaultProjectFlockLatestApproval(e) if e.LatestApproval != nil { snapshot := approvalDTO.ToApprovalDTO(*e.LatestApproval) @@ -109,30 +108,51 @@ func ToProjectFlockListDTO(e entity.ProjectFlock) ProjectFlockListDTO { return ProjectFlockListDTO{ ProjectFlockBaseDTO: createProjectFlockBaseDTO(e), - // Flock: flockSummary, - Area: areaSummary, - Kandangs: kandangSummaries, - Category: e.Category, - Fcr: fcrSummary, - Location: locationSummary, - CreatedAt: e.CreatedAt, - UpdatedAt: e.UpdatedAt, - CreatedUser: createdUser, - Approval: latestApproval, + Flock: flockSummary, + Area: areaSummary, + Kandangs: kandangSummaries, + Category: e.Category, + Fcr: fcrSummary, + Location: locationSummary, + CreatedAt: e.CreatedAt, + UpdatedAt: e.UpdatedAt, + CreatedUser: createdUser, + Approval: latestApproval, } } +func ToProjectFlockListDTOWithFlock(e entity.ProjectFlock, flock *flockDTO.FlockBaseDTO) ProjectFlockListDTO { + return ToProjectFlockListDTO(e, flock) +} + func ToProjectFlockListDTOs(items []entity.ProjectFlock) []ProjectFlockListDTO { result := make([]ProjectFlockListDTO, len(items)) for i, item := range items { - result[i] = ToProjectFlockListDTO(item) + result[i] = ToProjectFlockListDTO(item, nil) } return result } -func ToProjectFlockDetailDTO(e entity.ProjectFlock) ProjectFlockDetailDTO { +func ToProjectFlockListDTOsWithFlocks(items []entity.ProjectFlock, flocks map[uint]*entity.Flock) []ProjectFlockListDTO { + result := make([]ProjectFlockListDTO, len(items)) + for i, item := range items { + var flock *flockDTO.FlockBaseDTO + if flocks != nil { + if f := flocks[item.Id]; f != nil { + flock = &flockDTO.FlockBaseDTO{ + Id: f.Id, + Name: f.Name, + } + } + } + result[i] = ToProjectFlockListDTOWithFlock(item, flock) + } + return result +} + +func ToProjectFlockDetailDTO(e entity.ProjectFlock, flock *flockDTO.FlockBaseDTO) ProjectFlockDetailDTO { return ProjectFlockDetailDTO{ - ProjectFlockListDTO: ToProjectFlockListDTO(e), + ProjectFlockListDTO: ToProjectFlockListDTO(e, flock), } } diff --git a/internal/modules/production/project_flocks/services/projectflock.service.go b/internal/modules/production/project_flocks/services/projectflock.service.go index 9b5b4750..715fb1fb 100644 --- a/internal/modules/production/project_flocks/services/projectflock.service.go +++ b/internal/modules/production/project_flocks/services/projectflock.service.go @@ -11,6 +11,7 @@ import ( commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" productWarehouseRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories" + flockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto" flockRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories" kandangRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories" warehouseRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories" @@ -27,8 +28,8 @@ import ( ) type ProjectflockService interface { - GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlock, int64, error) - GetOne(ctx *fiber.Ctx, id uint) (*entity.ProjectFlock, error) + GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlock, int64, map[uint]*flockDTO.FlockBaseDTO, error) + GetOne(ctx *fiber.Ctx, id uint) (*entity.ProjectFlock, *flockDTO.FlockBaseDTO, error) CreateOne(ctx *fiber.Ctx, req *validation.Create) (*entity.ProjectFlock, error) UpdateOne(ctx *fiber.Ctx, req *validation.Update, id uint) (*entity.ProjectFlock, error) GetAvailableDocQuantity(ctx *fiber.Ctx, kandangID uint) (float64, error) @@ -92,9 +93,9 @@ func (s projectflockService) withRelations(db *gorm.DB) *gorm.DB { Preload("KandangHistory.Kandang") } -func (s projectflockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlock, int64, error) { +func (s projectflockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlock, int64, map[uint]*flockDTO.FlockBaseDTO, error) { if err := s.Validate.Struct(params); err != nil { - return nil, 0, err + return nil, 0, nil, err } if params.Page <= 0 { @@ -110,7 +111,7 @@ func (s projectflockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]e if err != nil { s.Log.Errorf("Failed to get projectflocks: %+v", err) - return nil, 0, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flocks") + return nil, 0, nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flocks") } if s.ApprovalSvc != nil && len(projectflocks) > 0 { @@ -133,10 +134,28 @@ func (s projectflockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]e } } - return projectflocks, total, nil + flockMap := make(map[uint]*flockDTO.FlockBaseDTO) + for i := range projectflocks { + if projectflocks[i].FlockName != "" { + baseName := pfutils.DeriveBaseName(projectflocks[i].FlockName) + if baseName != "" { + flock, err := s.FlockRepo.GetByName(c.Context(), baseName) + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + s.Log.Warnf("Failed to fetch flock %q: %+v", baseName, err) + } else if flock != nil { + flockMap[projectflocks[i].Id] = &flockDTO.FlockBaseDTO{ + Id: flock.Id, + Name: flock.Name, + } + } + } + } + } + + return projectflocks, total, flockMap, nil } -func (s projectflockService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlock, error) { +func (s projectflockService) getOneEntityOnly(c *fiber.Ctx, id uint) (*entity.ProjectFlock, error) { projectflock, err := s.Repository.GetByID(c.Context(), id, s.Repository.WithDefaultRelations()) if errors.Is(err, gorm.ErrRecordNotFound) { return nil, fiber.NewError(fiber.StatusNotFound, "Projectflock not found") @@ -165,6 +184,52 @@ func (s projectflockService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlock return projectflock, nil } +func (s projectflockService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlock, *flockDTO.FlockBaseDTO, error) { + projectflock, err := s.Repository.GetByID(c.Context(), id, s.Repository.WithDefaultRelations()) + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, nil, fiber.NewError(fiber.StatusNotFound, "Projectflock not found") + } + if err != nil { + s.Log.Errorf("Failed get projectflock by id: %+v", err) + return nil, nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flock") + } + + if s.ApprovalSvc != nil { + approvals, err := s.ApprovalSvc.ListByTarget(c.Context(), s.approvalWorkflow, id, func(db *gorm.DB) *gorm.DB { + return db.Preload("ActionUser") + }) + if err != nil { + s.Log.Warnf("Unable to load approvals for projectflock %d: %+v", id, err) + } else if len(approvals) > 0 { + if projectflock.LatestApproval == nil { + latest := approvals[len(approvals)-1] + projectflock.LatestApproval = &latest + } + } else { + projectflock.LatestApproval = nil + } + } + + // Fetch Flock master data for this ProjectFlock + var flockResult *flockDTO.FlockBaseDTO + if projectflock.FlockName != "" { + baseName := pfutils.DeriveBaseName(projectflock.FlockName) + if baseName != "" { + flock, err := s.FlockRepo.GetByName(c.Context(), baseName) + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + s.Log.Warnf("Failed to fetch flock %q: %+v", baseName, err) + } else if flock != nil { + flockResult = &flockDTO.FlockBaseDTO{ + Id: flock.Id, + Name: flock.Name, + } + } + } + } + + return projectflock, flockResult, nil +} + func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (*entity.ProjectFlock, error) { if err := s.Validate.Struct(req); err != nil { return nil, err @@ -275,7 +340,7 @@ func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (* return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create project flock") } - return s.GetOne(c, createBody.Id) + return s.getOneEntityOnly(c, createBody.Id) } func (s projectflockService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uint) (*entity.ProjectFlock, error) { @@ -387,7 +452,7 @@ func (s projectflockService) UpdateOne(c *fiber.Ctx, req *validation.Update, id hasChanges := hasBodyChanges || hasKandangChanges if !hasChanges { - return s.GetOne(c, id) + return s.getOneEntityOnly(c, id) } err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error { @@ -510,7 +575,7 @@ func (s projectflockService) UpdateOne(c *fiber.Ctx, req *validation.Update, id return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to update project flock") } - return s.GetOne(c, id) + return s.getOneEntityOnly(c, id) } func (s projectflockService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entity.ProjectFlock, error) { @@ -600,7 +665,7 @@ func (s projectflockService) Approval(c *fiber.Ctx, req *validation.Approve) ([] updated := make([]entity.ProjectFlock, 0, len(approvableIDs)) for _, approvableID := range approvableIDs { - project, err := s.GetOne(c, approvableID) + project, err := s.getOneEntityOnly(c, approvableID) if err != nil { return nil, err }