mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-24 15:25:43 +00:00
FIX[BE]: fix error handling on chickin service to better handler
This commit is contained in:
@@ -152,7 +152,7 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
|
|||||||
for _, productWarehouse := range productWarehouses {
|
for _, productWarehouse := range productWarehouses {
|
||||||
availableQty, err := s.calculateAvailableQuantity(c, req.ProjectFlockKandangId, &productWarehouse, category)
|
availableQty, err := s.calculateAvailableQuantity(c, req.ProjectFlockKandangId, &productWarehouse, category)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Log.Warnf("Failed to calculate available quantity for product warehouse %d: %v", productWarehouse.Id, err)
|
return nil, fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to calculate available quantity for product warehouse %d", productWarehouse.Id))
|
||||||
}
|
}
|
||||||
|
|
||||||
if availableQty <= 0 {
|
if availableQty <= 0 {
|
||||||
@@ -189,12 +189,12 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
|
|||||||
productWarehouseTx := s.ProductWarehouseRepo.WithTx(dbTransaction)
|
productWarehouseTx := s.ProductWarehouseRepo.WithTx(dbTransaction)
|
||||||
|
|
||||||
if err := s.Repository.WithTx(dbTransaction).CreateMany(c.Context(), newChikins, nil); err != nil {
|
if err := s.Repository.WithTx(dbTransaction).CreateMany(c.Context(), newChikins, nil); err != nil {
|
||||||
return err
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create chickins")
|
||||||
}
|
}
|
||||||
|
|
||||||
latest, err := approvalSvcTx.LatestByTarget(c.Context(), utils.ApprovalWorkflowProjectFlockKandang, projectFlockKandang.Id, nil)
|
latest, err := approvalSvcTx.LatestByTarget(c.Context(), utils.ApprovalWorkflowProjectFlockKandang, projectFlockKandang.Id, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get latest approval")
|
||||||
}
|
}
|
||||||
|
|
||||||
if category == string(utils.ProjectFlockCategoryLaying) {
|
if category == string(utils.ProjectFlockCategoryLaying) {
|
||||||
@@ -218,17 +218,29 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
|
|||||||
}
|
}
|
||||||
|
|
||||||
if latest == nil {
|
if latest == nil {
|
||||||
if _, err := approvalSvcTx.CreateApproval(c.Context(), utils.ApprovalWorkflowProjectFlockKandang, projectFlockKandang.Id, utils.ProjectFlockKandangStepPengajuan, &approvalAction, actorID, nil); err != nil {
|
if _, err := approvalSvcTx.CreateApproval(
|
||||||
lower := strings.ToLower(err.Error())
|
c.Context(),
|
||||||
if !(strings.Contains(lower, "duplicate") || strings.Contains(lower, "unique constraint") || strings.Contains(lower, "23505")) {
|
utils.ApprovalWorkflowProjectFlockKandang,
|
||||||
return err
|
projectFlockKandang.Id,
|
||||||
|
utils.ProjectFlockKandangStepPengajuan,
|
||||||
|
&approvalAction,
|
||||||
|
actorID,
|
||||||
|
nil); err != nil {
|
||||||
|
if !errors.Is(err, gorm.ErrDuplicatedKey) {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create approval")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if latest.StepNumber != uint16(utils.ProjectFlockKandangStepPengajuan) {
|
} else if latest.StepNumber != uint16(utils.ProjectFlockKandangStepPengajuan) {
|
||||||
if _, err := approvalSvcTx.CreateApproval(c.Context(), utils.ApprovalWorkflowProjectFlockKandang, projectFlockKandang.Id, utils.ProjectFlockKandangStepPengajuan, &approvalAction, actorID, nil); err != nil {
|
if _, err := approvalSvcTx.CreateApproval(
|
||||||
lower := strings.ToLower(err.Error())
|
c.Context(),
|
||||||
if !(strings.Contains(lower, "duplicate") || strings.Contains(lower, "unique constraint") || strings.Contains(lower, "23505")) {
|
utils.ApprovalWorkflowProjectFlockKandang,
|
||||||
return err
|
projectFlockKandang.Id,
|
||||||
|
utils.ProjectFlockKandangStepPengajuan,
|
||||||
|
&approvalAction,
|
||||||
|
actorID,
|
||||||
|
nil); err != nil {
|
||||||
|
if !errors.Is(err, gorm.ErrDuplicatedKey) {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create approval")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -236,7 +248,10 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fiber.NewError(fiber.StatusBadRequest, err.Error())
|
if fiberErr, ok := err.(*fiber.Error); ok {
|
||||||
|
return nil, fiberErr
|
||||||
|
}
|
||||||
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create chickins")
|
||||||
}
|
}
|
||||||
|
|
||||||
result := make([]entity.ProjectChickin, 0, len(newChikins))
|
result := make([]entity.ProjectChickin, 0, len(newChikins))
|
||||||
@@ -324,7 +339,6 @@ func (s chickinService) calculateAvailableQuantity(ctx *fiber.Ctx, projectFlockK
|
|||||||
totalPopulation += pop.TotalQty
|
totalPopulation += pop.TotalQty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chickins, err := s.Repository.GetByProjectFlockKandangID(ctx.Context(), projectFlockKandangID)
|
chickins, err := s.Repository.GetByProjectFlockKandangID(ctx.Context(), projectFlockKandangID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for _, chickin := range chickins {
|
for _, chickin := range chickins {
|
||||||
@@ -334,7 +348,6 @@ func (s chickinService) calculateAvailableQuantity(ctx *fiber.Ctx, projectFlockK
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
availableQty = productWarehouse.Quantity - totalPopulation - totalPendingQty
|
availableQty = productWarehouse.Quantity - totalPopulation - totalPendingQty
|
||||||
if availableQty < 0 {
|
if availableQty < 0 {
|
||||||
availableQty = 0
|
availableQty = 0
|
||||||
@@ -397,7 +410,6 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
|
|||||||
productWarehouseTx := s.ProductWarehouseRepo.WithTx(dbTransaction)
|
productWarehouseTx := s.ProductWarehouseRepo.WithTx(dbTransaction)
|
||||||
|
|
||||||
for _, approvableID := range approvableIDs {
|
for _, approvableID := range approvableIDs {
|
||||||
|
|
||||||
actorID := uint(1) // todo nanti ambil dari auth context
|
actorID := uint(1) // todo nanti ambil dari auth context
|
||||||
if _, err := approvalSvc.CreateApproval(
|
if _, err := approvalSvc.CreateApproval(
|
||||||
c.Context(),
|
c.Context(),
|
||||||
@@ -408,19 +420,13 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
|
|||||||
actorID,
|
actorID,
|
||||||
req.Notes,
|
req.Notes,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create approval")
|
||||||
lower := strings.ToLower(err.Error())
|
|
||||||
if !(strings.Contains(lower, "duplicate") || strings.Contains(lower, "unique constraint") || strings.Contains(lower, "23505")) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if action == entity.ApprovalActionApproved {
|
if action == entity.ApprovalActionApproved {
|
||||||
|
|
||||||
chickins, err := chickinRepoTx.GetByProjectFlockKandangID(c.Context(), approvableID)
|
chickins, err := chickinRepoTx.GetByProjectFlockKandangID(c.Context(), approvableID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to get chickins for approval %d", approvableID))
|
||||||
}
|
}
|
||||||
|
|
||||||
kandangForApproval, err := s.ProjectflockKandangRepo.GetByID(c.Context(), approvableID)
|
kandangForApproval, err := s.ProjectflockKandangRepo.GetByID(c.Context(), approvableID)
|
||||||
@@ -428,7 +434,7 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
|
|||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("ProjectFlockKandang %d not found", approvableID))
|
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("ProjectFlockKandang %d not found", approvableID))
|
||||||
}
|
}
|
||||||
return err
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get ProjectFlockKandang")
|
||||||
}
|
}
|
||||||
|
|
||||||
category := strings.ToUpper(strings.TrimSpace(kandangForApproval.ProjectFlock.Category))
|
category := strings.ToUpper(strings.TrimSpace(kandangForApproval.ProjectFlock.Category))
|
||||||
@@ -439,41 +445,38 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
|
|||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("Warehouse for kandang %d not found", kandangForApproval.KandangId))
|
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("Warehouse for kandang %d not found", kandangForApproval.KandangId))
|
||||||
}
|
}
|
||||||
return err
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get warehouse")
|
||||||
}
|
}
|
||||||
|
|
||||||
targetPW, err := s.getOrCreateProductWarehouse(c, warehouse.Id, "PULLET", dbTransaction, actorID)
|
targetPW, err := s.getOrCreateProductWarehouse(c, warehouse.Id, "PULLET", dbTransaction, actorID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get/create PULLET product warehouse: %w", err)
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get/create PULLET product warehouse")
|
||||||
}
|
}
|
||||||
if err := s.convertChickinsToTarget(c, chickins, targetPW, dbTransaction, actorID); err != nil {
|
if err := s.convertChickinsToTarget(c, chickins, targetPW, dbTransaction, actorID); err != nil {
|
||||||
return err
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to convert chickins to target")
|
||||||
}
|
}
|
||||||
} else if category == string(utils.ProjectFlockCategoryLaying) {
|
} else if category == string(utils.ProjectFlockCategoryLaying) {
|
||||||
|
|
||||||
warehouse, err := s.WarehouseRepo.GetByKandangID(c.Context(), kandangForApproval.KandangId)
|
warehouse, err := s.WarehouseRepo.GetByKandangID(c.Context(), kandangForApproval.KandangId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("Warehouse for kandang %d not found", kandangForApproval.KandangId))
|
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("Warehouse for kandang %d not found", kandangForApproval.KandangId))
|
||||||
}
|
}
|
||||||
return err
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get warehouse")
|
||||||
}
|
}
|
||||||
|
|
||||||
targetPW, err := s.getOrCreateProductWarehouse(c, warehouse.Id, "PULLET", dbTransaction, actorID)
|
targetPW, err := s.getOrCreateProductWarehouse(c, warehouse.Id, "PULLET", dbTransaction, actorID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get/create PULLET product warehouse: %w", err)
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get/create PULLET product warehouse")
|
||||||
}
|
}
|
||||||
if err := s.convertChickinsToTarget(c, chickins, targetPW, dbTransaction, actorID); err != nil {
|
if err := s.convertChickinsToTarget(c, chickins, targetPW, dbTransaction, actorID); err != nil {
|
||||||
return err
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to convert chickins to target")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if action == entity.ApprovalActionRejected {
|
if action == entity.ApprovalActionRejected {
|
||||||
|
|
||||||
chickins, err := chickinRepoTx.GetPendingByProjectFlockKandangID(c.Context(), approvableID)
|
chickins, err := chickinRepoTx.GetPendingByProjectFlockKandangID(c.Context(), approvableID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get pending chickins for rejection %d: %w", approvableID, err)
|
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to get pending chickins for rejection %d", approvableID))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(chickins) == 0 {
|
if len(chickins) == 0 {
|
||||||
@@ -485,7 +488,7 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
|
|||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("ProjectFlockKandang %d not found", approvableID))
|
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("ProjectFlockKandang %d not found", approvableID))
|
||||||
}
|
}
|
||||||
return err
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get ProjectFlockKandang")
|
||||||
}
|
}
|
||||||
|
|
||||||
categoryForRejection := strings.ToUpper(strings.TrimSpace(kandangForRejection.ProjectFlock.Category))
|
categoryForRejection := strings.ToUpper(strings.TrimSpace(kandangForRejection.ProjectFlock.Category))
|
||||||
@@ -499,15 +502,14 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
|
|||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("Product warehouse %d not found during rejection", chickin.ProductWarehouseId))
|
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("Product warehouse %d not found during rejection", chickin.ProductWarehouseId))
|
||||||
}
|
}
|
||||||
return fmt.Errorf("failed to restore product warehouse quantity for chickin %d: %w", chickin.Id, err)
|
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to restore product warehouse quantity for chickin %d", chickin.Id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := chickinRepoTx.DeleteOne(c.Context(), chickin.Id); err != nil {
|
if err := chickinRepoTx.DeleteOne(c.Context(), chickin.Id); err != nil {
|
||||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return fmt.Errorf("failed to delete rejected chickin %d: %w", chickin.Id, err)
|
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to delete rejected chickin %d", chickin.Id))
|
||||||
}
|
}
|
||||||
s.Log.Infof("chickin %d already deleted during rejection", chickin.Id)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -519,9 +521,6 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
|
|||||||
if fiberErr, ok := err.(*fiber.Error); ok {
|
if fiberErr, ok := err.(*fiber.Error); ok {
|
||||||
return nil, fiberErr
|
return nil, fiberErr
|
||||||
}
|
}
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return nil, fiber.NewError(fiber.StatusNotFound, "Chickin not found")
|
|
||||||
}
|
|
||||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to record approval")
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to record approval")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,7 +528,7 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
|
|||||||
for _, kandangID := range approvableIDs {
|
for _, kandangID := range approvableIDs {
|
||||||
var chickins []entity.ProjectChickin
|
var chickins []entity.ProjectChickin
|
||||||
if err := s.Repository.DB().WithContext(c.Context()).Where("project_flock_kandang_id = ?", kandangID).Find(&chickins).Error; err != nil {
|
if err := s.Repository.DB().WithContext(c.Context()).Where("project_flock_kandang_id = ?", kandangID).Find(&chickins).Error; err != nil {
|
||||||
return nil, err
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to load approved chickins")
|
||||||
}
|
}
|
||||||
updated = append(updated, chickins...)
|
updated = append(updated, chickins...)
|
||||||
}
|
}
|
||||||
@@ -608,7 +607,6 @@ func (s *chickinService) convertChickinsToTarget(ctx *fiber.Ctx, chickins []enti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add to target product warehouse
|
|
||||||
if err := productWarehouseTx.PatchOne(ctx.Context(), targetPW.Id, map[string]any{
|
if err := productWarehouseTx.PatchOne(ctx.Context(), targetPW.Id, map[string]any{
|
||||||
"quantity": gorm.Expr("quantity + ?", quantityToConvert),
|
"quantity": gorm.Expr("quantity + ?", quantityToConvert),
|
||||||
}, nil); err != nil {
|
}, nil); err != nil {
|
||||||
@@ -627,11 +625,7 @@ func (s *chickinService) convertChickinsToTarget(ctx *fiber.Ctx, chickins []enti
|
|||||||
CreatedBy: actorID,
|
CreatedBy: actorID,
|
||||||
}
|
}
|
||||||
if err := ProjectFlockPopulationRepotx.CreateOne(ctx.Context(), population, nil); err != nil {
|
if err := ProjectFlockPopulationRepotx.CreateOne(ctx.Context(), population, nil); err != nil {
|
||||||
lower := strings.ToLower(err.Error())
|
return err
|
||||||
if !(strings.Contains(lower, "duplicate") || strings.Contains(lower, "unique constraint") || strings.Contains(lower, "23505")) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
s.Log.Infof("ignored duplicate population for chickin %d: %v", chickin.Id, err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user