mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-25 07:45:44 +00:00
Merge branch 'development-before-sso' of https://gitlab.com/mbugroup/lti-api into dev/teguh
This commit is contained in:
@@ -108,7 +108,6 @@ func (s transferLayingService) GetAll(c *fiber.Ctx, params *validation.Query) ([
|
||||
db = db.Where("transfer_number ILIKE ?", "%"+params.TransferNumber+"%")
|
||||
}
|
||||
|
||||
// Handle sort
|
||||
sortField := "created_at"
|
||||
if params.Sort != "" {
|
||||
sortField = params.Sort
|
||||
@@ -127,7 +126,6 @@ func (s transferLayingService) GetAll(c *fiber.Ctx, params *validation.Query) ([
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// Filter by approval status if requested
|
||||
if params.ApprovalStatus != "" {
|
||||
var filtered []entity.LayingTransfer
|
||||
approvalRepo := commonRepo.NewApprovalRepository(s.Repository.DB())
|
||||
@@ -156,7 +154,6 @@ func (s transferLayingService) GetOne(c *fiber.Ctx, id uint) (*entity.LayingTran
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Fetch and populate latest approval
|
||||
approvalRepo := commonRepo.NewApprovalRepository(s.Repository.DB())
|
||||
latestApproval, err := approvalRepo.LatestByTarget(c.Context(), string(utils.ApprovalWorkflowTransferToLaying), transferLaying.Id, nil)
|
||||
if err == nil && latestApproval != nil {
|
||||
@@ -172,7 +169,6 @@ func (s transferLayingService) GetOneWithApproval(c *fiber.Ctx, id uint) (*entit
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Return the LatestApproval that was populated in GetOne
|
||||
return transferLaying, transferLaying.LatestApproval, nil
|
||||
}
|
||||
|
||||
@@ -181,11 +177,18 @@ func (s *transferLayingService) CreateOne(c *fiber.Ctx, req *validation.Create)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := commonSvc.EnsureRelations(c.Context(),
|
||||
commonSvc.RelationCheck{Name: "Source Project Flock", ID: &req.SourceProjectFlockId, Exists: s.ProjectFlockRepo.IdExists},
|
||||
commonSvc.RelationCheck{Name: "Target Project Flock", ID: &req.TargetProjectFlockId, Exists: s.ProjectFlockRepo.IdExists},
|
||||
); err != nil {
|
||||
return nil, err
|
||||
if _, err := s.ProjectFlockRepo.GetByID(c.Context(), req.SourceProjectFlockId, nil); err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fiber.NewError(fiber.StatusNotFound, "Source Project Flock not found")
|
||||
}
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to validate source project flock")
|
||||
}
|
||||
|
||||
if _, err := s.ProjectFlockRepo.GetByID(c.Context(), req.TargetProjectFlockId, nil); err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fiber.NewError(fiber.StatusNotFound, "Target Project Flock not found")
|
||||
}
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to validate target project flock")
|
||||
}
|
||||
|
||||
for _, detail := range req.SourceKandangs {
|
||||
@@ -288,7 +291,7 @@ func (s *transferLayingService) CreateOne(c *fiber.Ctx, req *validation.Create)
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create transfer laying record")
|
||||
}
|
||||
|
||||
productWarehouseRepoTx := s.ProductWarehouseRepo.WithTxRepo(dbTransaction)
|
||||
productWarehouseRepoTx := s.ProductWarehouseRepo.WithTx(dbTransaction)
|
||||
projectFlockPopulationRepoTx := s.ProjectFlockPopulationRepo.WithTx(dbTransaction)
|
||||
|
||||
for _, sourceDetail := range req.SourceKandangs {
|
||||
@@ -320,7 +323,6 @@ func (s *transferLayingService) CreateOne(c *fiber.Ctx, req *validation.Create)
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get target project flock kandang")
|
||||
}
|
||||
|
||||
// Get warehouse for this kandang
|
||||
targetWarehouse, err := s.WarehouseRepo.GetLatestByKandangID(c.Context(), targetPFK.KandangId)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
@@ -359,7 +361,6 @@ func (s transferLayingService) UpdateOne(c *fiber.Ctx, req *validation.Update, i
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check if transfer laying exists
|
||||
_, err := s.Repository.GetByID(c.Context(), id, nil)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
@@ -368,14 +369,12 @@ func (s transferLayingService) UpdateOne(c *fiber.Ctx, req *validation.Update, i
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to get transfer laying")
|
||||
}
|
||||
|
||||
// Check if latest approval is PENDING (not approved)
|
||||
approvalRepo := commonRepo.NewApprovalRepository(s.Repository.DB())
|
||||
latestApproval, err := approvalRepo.LatestByTarget(c.Context(), string(utils.ApprovalWorkflowTransferToLaying), id, nil)
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to check approval status")
|
||||
}
|
||||
|
||||
// If latest approval exists and is APPROVED or REJECTED, cannot update
|
||||
if latestApproval != nil && latestApproval.Action != nil {
|
||||
action := string(*latestApproval.Action)
|
||||
if action == string(entity.ApprovalActionApproved) || action == string(entity.ApprovalActionRejected) {
|
||||
@@ -409,7 +408,7 @@ func (s transferLayingService) UpdateOne(c *fiber.Ctx, req *validation.Update, i
|
||||
}
|
||||
|
||||
func (s transferLayingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||
// Verify transfer laying exists
|
||||
|
||||
_, err := s.Repository.GetByID(c.Context(), id, func(db *gorm.DB) *gorm.DB {
|
||||
return db.Preload("Sources.ProductWarehouse").Preload("Targets")
|
||||
})
|
||||
@@ -420,14 +419,12 @@ func (s transferLayingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get transfer laying")
|
||||
}
|
||||
|
||||
// Check if latest approval is PENDING (not approved/rejected)
|
||||
approvalRepo := commonRepo.NewApprovalRepository(s.Repository.DB())
|
||||
latestApproval, err := approvalRepo.LatestByTarget(c.Context(), string(utils.ApprovalWorkflowTransferToLaying), id, nil)
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to check approval status")
|
||||
}
|
||||
|
||||
// If latest approval exists and is APPROVED or REJECTED, cannot delete
|
||||
if latestApproval != nil && latestApproval.Action != nil {
|
||||
action := string(*latestApproval.Action)
|
||||
if action == string(entity.ApprovalActionApproved) || action == string(entity.ApprovalActionRejected) {
|
||||
@@ -435,22 +432,19 @@ func (s transferLayingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Delete in transaction to handle cascades and qty restoration
|
||||
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
||||
// Restore source warehouse quantities
|
||||
productWarehouseRepoTx := s.ProductWarehouseRepo.WithTxRepo(dbTransaction)
|
||||
|
||||
// Get source repository for detail info
|
||||
productWarehouseRepoTx := s.ProductWarehouseRepo.WithTx(dbTransaction)
|
||||
|
||||
sourceRepoTx := repository.NewLayingTransferSourceRepository(dbTransaction)
|
||||
sources, err := sourceRepoTx.GetByLayingTransferId(c.Context(), id)
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get transfer sources")
|
||||
}
|
||||
|
||||
// Restore quantity for each source that was reduced
|
||||
for _, source := range sources {
|
||||
if source.ProductWarehouseId != nil && source.Qty > 0 {
|
||||
// Add back the quantity that was transferred
|
||||
|
||||
if err := productWarehouseRepoTx.PatchOne(c.Context(), *source.ProductWarehouseId, map[string]any{
|
||||
"quantity": gorm.Expr("quantity + ?", source.Qty),
|
||||
}, nil); err != nil {
|
||||
@@ -459,7 +453,6 @@ func (s transferLayingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Restore project flock population that was reduced
|
||||
projectFlockPopulationRepoTx := s.ProjectFlockPopulationRepo.WithTx(dbTransaction)
|
||||
for _, source := range sources {
|
||||
populations, err := projectFlockPopulationRepoTx.GetByProjectFlockKandangID(c.Context(), source.SourceProjectFlockKandangId)
|
||||
@@ -467,13 +460,12 @@ func (s transferLayingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get populations for restoration")
|
||||
}
|
||||
|
||||
// Restore to latest populations first
|
||||
remainingToRestore := source.Qty
|
||||
for i := len(populations) - 1; i >= 0 && remainingToRestore > 0; i-- {
|
||||
pop := populations[i]
|
||||
restoreAmount := remainingToRestore
|
||||
if remainingToRestore < pop.TotalQty {
|
||||
// Cap restore to what can fit in this population
|
||||
|
||||
restoreAmount = remainingToRestore
|
||||
}
|
||||
|
||||
@@ -486,7 +478,6 @@ func (s transferLayingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the transfer laying (cascade will delete sources and targets)
|
||||
if err := s.Repository.WithTx(dbTransaction).DeleteOne(c.Context(), id); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to delete transfer laying")
|
||||
}
|
||||
@@ -536,7 +527,7 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) (
|
||||
approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction))
|
||||
sourceRepoTx := repository.NewLayingTransferSourceRepository(dbTransaction)
|
||||
targetRepoTx := repository.NewLayingTransferTargetRepository(dbTransaction)
|
||||
productWarehouseRepoTx := s.ProductWarehouseRepo.WithTxRepo(dbTransaction)
|
||||
productWarehouseRepoTx := s.ProductWarehouseRepo.WithTx(dbTransaction)
|
||||
|
||||
for _, approvableID := range approvableIDs {
|
||||
transfer, err := s.Repository.GetByID(c.Context(), approvableID, nil)
|
||||
@@ -606,6 +597,7 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) (
|
||||
sourceWarehouse.ProductId,
|
||||
targetWarehouse.Id,
|
||||
target.Qty,
|
||||
actorID,
|
||||
); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create or update product warehouse")
|
||||
}
|
||||
@@ -665,9 +657,9 @@ func createApprovalTransferLaying(ctx context.Context, tx *gorm.DB, transferLayi
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *transferLayingService) getOrCreateProductWarehouse(ctx context.Context, tx *gorm.DB, productID uint, warehouseID uint, quantity float64) (*entity.ProductWarehouse, error) {
|
||||
func (s *transferLayingService) getOrCreateProductWarehouse(ctx context.Context, tx *gorm.DB, productID uint, warehouseID uint, quantity float64, actorID uint) (*entity.ProductWarehouse, error) {
|
||||
|
||||
productWarehouseRepoTx := s.ProductWarehouseRepo.WithTxRepo(tx)
|
||||
productWarehouseRepoTx := rInventory.NewProductWarehouseRepository(tx)
|
||||
|
||||
existing, err := productWarehouseRepoTx.GetProductWarehouseByProductAndWarehouseID(ctx, productID, warehouseID)
|
||||
if err == nil && existing != nil {
|
||||
@@ -685,6 +677,7 @@ func (s *transferLayingService) getOrCreateProductWarehouse(ctx context.Context,
|
||||
ProductId: productID,
|
||||
WarehouseId: warehouseID,
|
||||
Quantity: quantity,
|
||||
CreatedBy: actorID,
|
||||
}
|
||||
|
||||
if err := productWarehouseRepoTx.CreateOne(ctx, newWarehouse, nil); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user