From a2066979c1af83b9ed1c244e4ab1f569c2fe24cd Mon Sep 17 00:00:00 2001 From: ragilap Date: Mon, 29 Dec 2025 19:04:10 +0700 Subject: [PATCH] feat(BE-281): adjustment uniformity for make unique for week,projectflockandang, and date --- .../modules/production/uniformities/module.go | 4 +- .../services/uniformity.service.go | 101 +++++++++++++++--- 2 files changed, 92 insertions(+), 13 deletions(-) diff --git a/internal/modules/production/uniformities/module.go b/internal/modules/production/uniformities/module.go index 1032cdcf..27a73fbc 100644 --- a/internal/modules/production/uniformities/module.go +++ b/internal/modules/production/uniformities/module.go @@ -10,6 +10,7 @@ import ( commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository" commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service" + rProjectFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories" rUniformity "gitlab.com/mbugroup/lti-api.git/internal/modules/production/uniformities/repositories" sUniformity "gitlab.com/mbugroup/lti-api.git/internal/modules/production/uniformities/services" @@ -24,6 +25,7 @@ func (UniformityModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validat uniformityRepo := rUniformity.NewUniformityRepository(db) documentRepo := commonRepo.NewDocumentRepository(db) approvalRepo := commonRepo.NewApprovalRepository(db) + projectFlockKandangRepo := rProjectFlock.NewProjectFlockKandangRepository(db) userRepo := rUser.NewUserRepository(db) documentSvc, err := commonSvc.NewDocumentServiceFromConfig(context.Background(), documentRepo) @@ -36,7 +38,7 @@ func (UniformityModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validat panic(fmt.Sprintf("failed to register uniformity approval workflow: %v", err)) } - uniformityService := sUniformity.NewUniformityService(uniformityRepo, documentSvc, approvalRepo, approvalSvc, validate) + uniformityService := sUniformity.NewUniformityService(uniformityRepo, documentSvc, approvalRepo, approvalSvc, projectFlockKandangRepo, validate) userService := sUser.NewUserService(userRepo, validate) UniformityRoutes(router, userService, uniformityService) diff --git a/internal/modules/production/uniformities/services/uniformity.service.go b/internal/modules/production/uniformities/services/uniformity.service.go index 871f4816..6f8ba6ac 100644 --- a/internal/modules/production/uniformities/services/uniformity.service.go +++ b/internal/modules/production/uniformities/services/uniformity.service.go @@ -14,6 +14,7 @@ import ( commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" m "gitlab.com/mbugroup/lti-api.git/internal/middleware" + rProjectFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories" repository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/uniformities/repositories" validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/uniformities/validations" "gitlab.com/mbugroup/lti-api.git/internal/utils" @@ -39,12 +40,13 @@ type UniformityService interface { } type uniformityService struct { - Log *logrus.Logger - Validate *validator.Validate - Repository repository.UniformityRepository - DocumentSvc commonSvc.DocumentService - ApprovalRepo commonRepo.ApprovalRepository - ApprovalSvc commonSvc.ApprovalService + Log *logrus.Logger + Validate *validator.Validate + Repository repository.UniformityRepository + DocumentSvc commonSvc.DocumentService + ApprovalRepo commonRepo.ApprovalRepository + ApprovalSvc commonSvc.ApprovalService + ProjectFlockKandangRepo rProjectFlock.ProjectFlockKandangRepository } func NewUniformityService( @@ -52,15 +54,17 @@ func NewUniformityService( documentSvc commonSvc.DocumentService, approvalRepo commonRepo.ApprovalRepository, approvalSvc commonSvc.ApprovalService, + projectFlockKandangRepo rProjectFlock.ProjectFlockKandangRepository, validate *validator.Validate, ) UniformityService { return &uniformityService{ - Log: utils.Log, - Validate: validate, - Repository: repo, - DocumentSvc: documentSvc, - ApprovalRepo: approvalRepo, - ApprovalSvc: approvalSvc, + Log: utils.Log, + Validate: validate, + Repository: repo, + DocumentSvc: documentSvc, + ApprovalRepo: approvalRepo, + ApprovalSvc: approvalSvc, + ProjectFlockKandangRepo: projectFlockKandangRepo, } } @@ -121,6 +125,9 @@ func (s *uniformityService) CreateOne(c *fiber.Ctx, req *validation.Create, file if err := s.Validate.Struct(req); err != nil { return nil, err } + if s.ProjectFlockKandangRepo == nil { + return nil, fiber.NewError(fiber.StatusInternalServerError, "Project flock kandang repository not available") + } if file == nil { return nil, fiber.NewError(fiber.StatusBadRequest, "document is required") @@ -131,6 +138,16 @@ func (s *uniformityService) CreateOne(c *fiber.Ctx, req *validation.Create, file return nil, fiber.NewError(fiber.StatusBadRequest, "date must be in YYYY-MM-DD format") } + if err := commonSvc.EnsureRelations( + c.Context(), + commonSvc.RelationCheck{Name: "Project Flock Kandang", ID: &req.ProjectFlockKandangId, Exists: s.ProjectFlockKandangRepo.IdExists}, + ); err != nil { + return nil, err + } + if err := s.ensureUniqueUniformity(c.Context(), 0, req.ProjectFlockKandangId, req.Week, &uniformDate); err != nil { + return nil, err + } + if len(rows) == 0 { parsedRows, err := s.ParseBodyWeightExcel(c, file) if err != nil { @@ -212,6 +229,7 @@ func (s uniformityService) UpdateOne(c *fiber.Ctx, req *validation.Update, id ui } updateBody := make(map[string]any) + var uniformDate *time.Time if req.Date != nil { parsed, err := time.Parse("2006-01-02", *req.Date) @@ -219,14 +237,51 @@ func (s uniformityService) UpdateOne(c *fiber.Ctx, req *validation.Update, id ui return nil, fiber.NewError(fiber.StatusBadRequest, "date must be in YYYY-MM-DD format") } updateBody["uniform_date"] = parsed + uniformDate = &parsed } if req.ProjectFlockKandangId != nil { + if s.ProjectFlockKandangRepo == nil { + return nil, fiber.NewError(fiber.StatusInternalServerError, "Project flock kandang repository not available") + } + if err := commonSvc.EnsureRelations( + c.Context(), + commonSvc.RelationCheck{Name: "Project Flock Kandang", ID: req.ProjectFlockKandangId, Exists: s.ProjectFlockKandangRepo.IdExists}, + ); err != nil { + return nil, err + } updateBody["project_flock_kandang_id"] = *req.ProjectFlockKandangId } if req.Week != nil { updateBody["week"] = *req.Week } + if req.Date != nil || req.ProjectFlockKandangId != nil || req.Week != nil { + current, err := s.Repository.GetByID(c.Context(), id, nil) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, fiber.NewError(fiber.StatusNotFound, "Uniformity not found") + } + return nil, err + } + targetDate := uniformDate + if targetDate == nil { + targetDate = current.UniformDate + } + targetWeek := current.Week + if req.Week != nil { + targetWeek = *req.Week + } + targetPFKID := current.ProjectFlockKandangId + if req.ProjectFlockKandangId != nil { + targetPFKID = *req.ProjectFlockKandangId + } + if targetDate != nil { + if err := s.ensureUniqueUniformity(c.Context(), id, targetPFKID, targetWeek, targetDate); err != nil { + return nil, err + } + } + } + if file != nil { if s.DocumentSvc == nil { return nil, fiber.NewError(fiber.StatusInternalServerError, "Document service not available") @@ -331,6 +386,28 @@ func (s uniformityService) UpdateOne(c *fiber.Ctx, req *validation.Update, id ui return s.GetOne(c, id) } +func (s *uniformityService) ensureUniqueUniformity(ctx context.Context, id uint, projectFlockKandangID uint, week int, uniformDate *time.Time) error { + if projectFlockKandangID == 0 || week == 0 || uniformDate == nil || uniformDate.IsZero() { + return nil + } + + query := s.Repository.DB().WithContext(ctx). + Model(&entity.ProjectFlockKandangUniformity{}). + Where("project_flock_kandang_id = ? AND week = ? AND uniform_date = ?", projectFlockKandangID, week, *uniformDate) + if id != 0 { + query = query.Where("id <> ?", id) + } + + var count int64 + if err := query.Count(&count).Error; err != nil { + return fiber.NewError(fiber.StatusInternalServerError, "Failed to validate uniformity uniqueness") + } + if count > 0 { + return fiber.NewError(fiber.StatusConflict, "Uniformity already exists for the same project flock kandang, week, and date") + } + return nil +} + func (s uniformityService) DeleteOne(c *fiber.Ctx, id uint) error { if err := s.Repository.DeleteOne(c.Context(), id); err != nil { if errors.Is(err, gorm.ErrRecordNotFound) {