feat(BE-48): auto-create product_warehouse on stock adjustment & remove unused APIs

- Change logic: automatically create product_warehouse if it does not exist during stock adjustment
- Remove unnecessary/unused API endpoints
- Ensure adjustment process continues even if product_warehouse was not previously available
This commit is contained in:
aguhh18
2025-10-13 11:38:05 +07:00
parent ce28429efd
commit 5283aed996
8 changed files with 69 additions and 207 deletions
@@ -7,6 +7,7 @@ import (
sAdjustment "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/adjustments/services"
rProductWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
rproduct "gitlab.com/mbugroup/lti-api.git/internal/modules/master/products/repositories"
rWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
rStockLogs "gitlab.com/mbugroup/lti-api.git/internal/modules/shared/stock-logs/repositories"
@@ -21,8 +22,9 @@ func (AdjustmentModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validat
warehouseRepo := rWarehouse.NewWarehouseRepository(db)
productWarehouseRepo := rProductWarehouse.NewProductWarehouseRepository(db)
userRepo := rUser.NewUserRepository(db)
productRepo := rproduct.NewProductRepository(db)
adjustmentService := sAdjustment.NewAdjustmentService(stockLogsRepo, warehouseRepo, productWarehouseRepo, validate)
adjustmentService := sAdjustment.NewAdjustmentService(productRepo, stockLogsRepo, warehouseRepo, productWarehouseRepo, validate)
userService := sUser.NewUserService(userRepo, validate)
AdjustmentRoutes(router, userService, adjustmentService)
@@ -7,6 +7,7 @@ import (
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/adjustments/validations"
ProductWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
productRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/master/products/repositories"
warehouseRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
stockLogsRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/shared/stock-logs/repositories"
"gitlab.com/mbugroup/lti-api.git/internal/utils"
@@ -29,15 +30,17 @@ type adjustmentService struct {
StockLogsRepository stockLogsRepo.StockLogRepository
WarehouseRepo warehouseRepo.WarehouseRepository
ProductWarehouseRepo ProductWarehouse.ProductWarehouseRepository
ProductRepo productRepo.ProductRepository
}
func NewAdjustmentService(stockLogsRepo stockLogsRepo.StockLogRepository, warehouseRepo warehouseRepo.WarehouseRepository, productWarehouseRepo ProductWarehouse.ProductWarehouseRepository, validate *validator.Validate) AdjustmentService {
func NewAdjustmentService(productRepo productRepo.ProductRepository, stockLogsRepo stockLogsRepo.StockLogRepository, warehouseRepo warehouseRepo.WarehouseRepository, productWarehouseRepo ProductWarehouse.ProductWarehouseRepository, validate *validator.Validate) AdjustmentService {
return &adjustmentService{
Log: utils.Log,
Validate: validate,
StockLogsRepository: stockLogsRepo,
WarehouseRepo: warehouseRepo,
ProductWarehouseRepo: productWarehouseRepo,
ProductRepo: productRepo,
}
}
@@ -74,14 +77,27 @@ func (s *adjustmentService) Adjustment(c *fiber.Ctx, req *validation.Create) (*e
}
ctx := c.Context()
productWarehouseExists, err := s.ProductWarehouseRepo.ProductWarehouseExists(ctx, uint(req.ProductID), uint(req.WarehouseID), nil)
isProductExist, err := s.ProductRepo.IdExists(c.Context(), uint(req.ProductID))
if err != nil {
return nil, err
s.Log.Errorf("Failed to check product existence: %+v", err)
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to validate product")
}
if !productWarehouseExists {
return nil, fiber.NewError(fiber.StatusBadRequest, "Product warehouse not found")
if !isProductExist {
return nil, fiber.NewError(fiber.StatusBadRequest, "Product not found")
}
isWarehouseExist, err := s.WarehouseRepo.IdExists(c.Context(), uint(req.WarehouseID))
if err != nil {
s.Log.Errorf("Failed to check warehouse existence: %+v", err)
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to validate warehouse")
}
if !isWarehouseExist {
return nil, fiber.NewError(fiber.StatusBadRequest, "Warehouse not found")
}
if req.Quantity <= 0 {
return nil, fiber.NewError(fiber.StatusBadRequest, "Quantity must be greater than zero")
}
transactionType := strings.ToUpper(req.TransactionType)
if transactionType != entity.TransactionTypeIncrease && transactionType != entity.TransactionTypeDecrease {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid transaction type")
@@ -89,16 +105,33 @@ func (s *adjustmentService) Adjustment(c *fiber.Ctx, req *validation.Create) (*e
var createdLogId uint
isProductWarehouseExist, err := s.ProductWarehouseRepo.ProductWarehouseExistByProductAndWarehouseID(ctx, uint(req.ProductID), uint(req.WarehouseID))
if err != nil {
s.Log.Errorf("Failed to check product warehouse existence: %+v", err)
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to validate product warehouse")
}
if !isProductWarehouseExist {
newPW := &entity.ProductWarehouse{
ProductId: uint(req.ProductID),
WarehouseId: uint(req.WarehouseID),
Quantity: 0,
CreatedBy: 1, // TODO: should Get from auth middleware
}
if err := s.ProductWarehouseRepo.CreateOne(ctx, newPW, nil); err != nil {
s.Log.Errorf("Failed to create product warehouse: %+v", err)
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create product warehouse")
}
s.Log.Infof("Product warehouse created: %+v", newPW.Id)
}
err = s.StockLogsRepository.DB().WithContext(ctx).Transaction(func(tx *gorm.DB) error {
// Get product warehouse by product id and warehouse id (read operation, no transaction needed)
productWarehouse, err := s.ProductWarehouseRepo.GetProductWarehouseByProductAndWarehouseID(ctx, uint(req.ProductID), uint(req.WarehouseID))
if err != nil {
return err
s.Log.Errorf("Failed to get product warehouse: %+v", err)
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get product warehouse")
}
if productWarehouse == nil {
return fiber.NewError(fiber.StatusBadRequest, "Product warehouse not found")
}
s.Log.Infof("Product Warehouse found: %+v", productWarehouse.Id)
afterQuantity := productWarehouse.Quantity
if transactionType == entity.TransactionTypeIncrease {
@@ -135,7 +168,6 @@ func (s *adjustmentService) Adjustment(c *fiber.Ctx, req *validation.Create) (*e
}
s.Log.Infof("Product warehouse quantity updated: %+v", productWarehouse.Id)
// Set createdLogId to get the log with relations after transaction
createdLogId = newLog.Id
return nil
})