feat(BE-281): adjustment uniformity for make unique for week,projectflockandang, and date

This commit is contained in:
ragilap
2025-12-29 19:04:10 +07:00
parent 8dfb224614
commit a2066979c1
2 changed files with 92 additions and 13 deletions
@@ -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)
@@ -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) {