diff --git a/internal/modules/production/project_flocks/controllers/projectflock.controller.go b/internal/modules/production/project_flocks/controllers/projectflock.controller.go index 6d78520e..52d53be5 100644 --- a/internal/modules/production/project_flocks/controllers/projectflock.controller.go +++ b/internal/modules/production/project_flocks/controllers/projectflock.controller.go @@ -329,3 +329,29 @@ func (u *ProjectflockController) LookupProjectFlockKandang(c *fiber.Ctx) error { Message: "Get projectflock kandang successfully", Data: dtoResult}) } + +func (u *ProjectflockController) Resubmit(c *fiber.Ctx) error { + param := c.Params("id") + req := new(validation.Resubmit) + + id, err := strconv.Atoi(param) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, "Invalid Id") + } + if err := c.BodyParser(req); err != nil { + return fiber.NewError(fiber.StatusBadRequest, "Invalid request body") + } + + result, err := u.ProjectflockService.Resubmit(c, req, uint(id)) + if err != nil { + return err + } + + return c.Status(fiber.StatusOK). + JSON(response.Success{ + Code: fiber.StatusOK, + Status: "success", + Message: "Resubmit projectflock successfully", + Data: dto.ToProjectFlockListDTO(*result), + }) +} diff --git a/internal/modules/production/project_flocks/module.go b/internal/modules/production/project_flocks/module.go index 631aef58..acd77338 100644 --- a/internal/modules/production/project_flocks/module.go +++ b/internal/modules/production/project_flocks/module.go @@ -12,6 +12,7 @@ import ( 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" rKandang "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories" + rNonstock "gitlab.com/mbugroup/lti-api.git/internal/modules/master/nonstocks/repositories" rWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories" rProjectBudget "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories" rProjectflock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories" @@ -28,6 +29,7 @@ type ProjectflockModule struct{} func (ProjectflockModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *validator.Validate) { flockRepo := rFlock.NewFlockRepository(db) kandangRepo := rKandang.NewKandangRepository(db) + nonstockRepo := rNonstock.NewNonstockRepository(db) projectflockRepo := rProjectflock.NewProjectflockRepository(db) projectflockKandangRepo := rProjectflock.NewProjectFlockKandangRepository(db) warehouseRepo := rWarehouse.NewWarehouseRepository(db) @@ -41,7 +43,7 @@ func (ProjectflockModule) RegisterRoutes(router fiber.Router, db *gorm.DB, valid panic(fmt.Sprintf("failed to register project flock approval workflow: %v", err)) } - projectflockService := sProjectflock.NewProjectflockService(projectflockRepo, flockRepo, kandangRepo, projectflockKandangRepo, warehouseRepo, productWarehouseRepo, projectBudgetRepo, approvalService, validate) + projectflockService := sProjectflock.NewProjectflockService(projectflockRepo, flockRepo, kandangRepo, projectflockKandangRepo, warehouseRepo, productWarehouseRepo, projectBudgetRepo, nonstockRepo, approvalService, validate) userService := sUser.NewUserService(userRepo, validate) ProjectflockRoutes(router, userService, projectflockService) diff --git a/internal/modules/production/project_flocks/repositories/projectflock.repository.go b/internal/modules/production/project_flocks/repositories/projectflock.repository.go index b46cdb5c..15afaf59 100644 --- a/internal/modules/production/project_flocks/repositories/projectflock.repository.go +++ b/internal/modules/production/project_flocks/repositories/projectflock.repository.go @@ -56,7 +56,8 @@ func (r *ProjectflockRepositoryImpl) WithDefaultRelations() func(*gorm.DB) *gorm Preload("KandangHistory"). Preload("KandangHistory.Kandang"). Preload("Budgets"). - Preload("Budgets.Nonstock") + Preload("Budgets.Nonstock"). + Preload("Budgets.Nonstock.Uom") } } diff --git a/internal/modules/production/project_flocks/route.go b/internal/modules/production/project_flocks/route.go index c1e37cd5..710f5225 100644 --- a/internal/modules/production/project_flocks/route.go +++ b/internal/modules/production/project_flocks/route.go @@ -23,5 +23,6 @@ func ProjectflockRoutes(v1 fiber.Router, u user.UserService, s projectflock.Proj route.Get("/kandangs/lookup", ctrl.LookupProjectFlockKandang) route.Post("/approvals", ctrl.Approval) route.Get("/locations/:location_id/periods", ctrl.GetPeriodSummary) + route.Put("/:id/resubmit", ctrl.Resubmit) } diff --git a/internal/modules/production/project_flocks/services/projectflock.service.go b/internal/modules/production/project_flocks/services/projectflock.service.go index 26e4fdc6..f38e60dd 100644 --- a/internal/modules/production/project_flocks/services/projectflock.service.go +++ b/internal/modules/production/project_flocks/services/projectflock.service.go @@ -15,6 +15,7 @@ import ( 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" + nonstockRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/nonstocks/repositories" warehouseRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories" projectBudgetRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories" repository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories" @@ -40,6 +41,7 @@ type ProjectflockService interface { GetPeriodSummary(ctx *fiber.Ctx, locationID uint) ([]KandangPeriodSummary, error) GetProjectPeriods(ctx *fiber.Ctx, projectIDs []uint) (map[uint]int, error) Approval(ctx *fiber.Ctx, req *validation.Approve) ([]entity.ProjectFlock, error) + Resubmit(ctx *fiber.Ctx, req *validation.Resubmit, id uint) (*entity.ProjectFlock, error) } type projectflockService struct { @@ -48,6 +50,7 @@ type projectflockService struct { Repository repository.ProjectflockRepository FlockRepo flockRepository.FlockRepository KandangRepo kandangRepository.KandangRepository + NonstockRepo nonstockRepository.NonstockRepository WarehouseRepo warehouseRepository.WarehouseRepository ProductWarehouseRepo productWarehouseRepository.ProductWarehouseRepository ProjectBudgetRepo projectBudgetRepository.ProjectBudgetRepository @@ -70,6 +73,7 @@ func NewProjectflockService( warehouseRepo warehouseRepository.WarehouseRepository, productWarehouseRepo productWarehouseRepository.ProductWarehouseRepository, projectBudgetRepo projectBudgetRepository.ProjectBudgetRepository, + nonstockRepo nonstockRepository.NonstockRepository, approvalSvc commonSvc.ApprovalService, validate *validator.Validate, @@ -80,6 +84,7 @@ func NewProjectflockService( Repository: repo, FlockRepo: flockRepo, KandangRepo: kandangRepo, + NonstockRepo: nonstockRepo, WarehouseRepo: warehouseRepo, ProductWarehouseRepo: productWarehouseRepo, PivotRepo: pivotRepo, @@ -1051,6 +1056,92 @@ func (s projectflockService) kandangRepoWithTx(tx *gorm.DB) kandangRepository.Ka return kandangRepository.NewKandangRepository(s.Repository.DB()) } +func (s projectflockService) Resubmit(c *fiber.Ctx, req *validation.Resubmit, id uint) (*entity.ProjectFlock, error) { + if err := s.Validate.Struct(req); err != nil { + return nil, err + } + + actorID, err := m.ActorIDFromContext(c) + if err != nil { + return nil, err + } + + existing, err := s.Repository.GetByID(c.Context(), id, s.Repository.WithDefaultRelations()) + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, fiber.NewError(fiber.StatusNotFound, "Project flock tidak ditemukan") + } + if err != nil { + return nil, fiber.NewError(fiber.StatusInternalServerError, "Gagal mengambil data project flock") + } + + kandangIDs := uniqueUintSlice(req.KandangIds) + kandangs, err := s.KandangRepo.GetByIDs(c.Context(), kandangIDs, nil) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, fiber.NewError(fiber.StatusNotFound, "Beberapa kandang tidak ditemukan") + } + return nil, fiber.NewError(fiber.StatusInternalServerError, "Gagal mengambil data kandang") + } + if len(kandangs) != len(kandangIDs) { + return nil, fiber.NewError(fiber.StatusNotFound, "Beberapa kandang tidak ditemukan") + } + + for _, pb := range req.ProjectBudgts { + if err := commonSvc.EnsureRelations(c.Context(), + commonSvc.RelationCheck{Name: "Nonstock", ID: &pb.NonstockId, Exists: s.NonstockRepo.IdExists}, + ); err != nil { + return nil, err + } + } + + err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error { + + approvalSvc := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction)) + + var period int = 1 + if len(existing.KandangHistory) > 0 { + period = existing.KandangHistory[0].Period + } + + periods := make(map[uint]int, len(kandangIDs)) + for _, kandangID := range kandangIDs { + periods[kandangID] = period + } + + if err := s.attachKandangs(c.Context(), dbTransaction, existing.Id, kandangIDs, periods); err != nil { + return err + } + if err := s.UpsertProjectBudget(c.Context(), dbTransaction, existing.Id, req.ProjectBudgts); err != nil { + return err + } + + action := entity.ApprovalActionUpdated + _, err = approvalSvc.CreateApproval( + c.Context(), + utils.ApprovalWorkflowProjectFlock, + existing.Id, + utils.ProjectFlockStepPengajuan, + &action, + actorID, + nil, + ) + return err + }) + + if err != nil { + if fiberErr, ok := err.(*fiber.Error); ok { + return nil, fiberErr + } + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, fiber.NewError(fiber.StatusNotFound, "Project flock tidak ditemukan") + } + + return nil, fiber.NewError(fiber.StatusInternalServerError, "Gagal mengajukan ulang project flock") + } + + return s.getOneEntityOnly(c, id) +} + func (s projectflockService) UpsertProjectBudget(ctx context.Context, dbTransaction *gorm.DB, projectFlockID uint, budgets []validation.ProjectBudget) error { if len(budgets) == 0 { diff --git a/internal/modules/production/project_flocks/validations/projectflock.validation.go b/internal/modules/production/project_flocks/validations/projectflock.validation.go index bd2c3231..607daf26 100644 --- a/internal/modules/production/project_flocks/validations/projectflock.validation.go +++ b/internal/modules/production/project_flocks/validations/projectflock.validation.go @@ -43,3 +43,8 @@ type ProjectBudget struct { Price float64 `json:"price" validate:"required_strict,number,gt=0"` Qty float64 `json:"qty" validate:"required_strict,number,gt=0"` } + +type Resubmit struct { + KandangIds []uint `json:"kandang_ids" validate:"required_strict,min=1,dive,gt=0"` + ProjectBudgts []ProjectBudget `json:"project_budgets" validate:"required_strict,min=1,dive"` +}