[FIX/BE-US] feat adjustment location and area

This commit is contained in:
ragilap
2026-01-27 10:34:25 +07:00
parent 571f6b4bf3
commit 00cdfb692b
26 changed files with 753 additions and 600 deletions
@@ -37,19 +37,49 @@ func NewProductStockService(
}
}
func (s productStockService) withRelations(db *gorm.DB) *gorm.DB {
func (s productStockService) withRelations(db *gorm.DB, locationScope, areaScope m.ScopeFilter) *gorm.DB {
warehouseScope := func(db *gorm.DB) *gorm.DB {
if locationScope.Restrict {
db = db.Where("warehouses.location_id IN ?", locationScope.IDs)
}
if areaScope.Restrict {
db = db.Where("warehouses.area_id IN ?", areaScope.IDs)
}
return db
}
productWarehouseScope := func(db *gorm.DB) *gorm.DB {
db = db.Joins("JOIN warehouses w ON w.id = product_warehouses.warehouse_id")
if locationScope.Restrict {
db = db.Where("w.location_id IN ?", locationScope.IDs)
}
if areaScope.Restrict {
db = db.Where("w.area_id IN ?", areaScope.IDs)
}
return db
}
stockLogScope := func(db *gorm.DB) *gorm.DB {
db = db.
Joins("JOIN product_warehouses pw ON pw.id = stock_logs.product_warehouse_id").
Joins("JOIN warehouses w ON w.id = pw.warehouse_id")
if locationScope.Restrict {
db = db.Where("w.location_id IN ?", locationScope.IDs)
}
if areaScope.Restrict {
db = db.Where("w.area_id IN ?", areaScope.IDs)
}
return db.Order("stock_logs.created_at ASC")
}
return db.
Preload("CreatedUser").
Preload("Uom").
Preload("ProductCategory").
Preload("Flags").
Preload("ProductWarehouses").
Preload("ProductWarehouses.Warehouse").
Preload("ProductWarehouses", productWarehouseScope).
Preload("ProductWarehouses.Warehouse", warehouseScope).
Preload("ProductWarehouses.Warehouse.Location").
Preload("ProductWarehouses.Warehouse.Location.Area").
Preload("ProductWarehouses.StockLogs", func(db *gorm.DB) *gorm.DB {
return db.Order("created_at ASC")
}).
Preload("ProductWarehouses.StockLogs", stockLogScope).
Preload("ProductWarehouses.StockLogs.CreatedUser").
Preload("ProductSuppliers").
Preload("ProductSuppliers.Supplier", func(db *gorm.DB) *gorm.DB {
@@ -62,7 +92,7 @@ func (s productStockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]e
return nil, 0, err
}
scope, err := m.ResolveLocationScope(c, s.ProductRepository.DB())
locationScope, areaScope, err := m.ResolveLocationAreaScopes(c, s.ProductRepository.DB())
if err != nil {
return nil, 0, err
}
@@ -70,8 +100,8 @@ func (s productStockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]e
offset := (params.Page - 1) * params.Limit
productStocks, total, err := s.ProductRepository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
if scope.Restrict {
if len(scope.IDs) == 0 {
if locationScope.Restrict || areaScope.Restrict {
if (locationScope.Restrict && len(locationScope.IDs) == 0) || (areaScope.Restrict && len(areaScope.IDs) == 0) {
return db.Where("1 = 0")
}
db = db.Where(`EXISTS (
@@ -80,8 +110,12 @@ func (s productStockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]e
JOIN warehouses w ON w.id = pw.warehouse_id
WHERE pw.product_id = products.id
AND pw.qty > 0
AND w.location_id IN ?
)`, scope.IDs)
AND (? OR w.location_id IN ?)
AND (? OR w.area_id IN ?)
)`,
!locationScope.Restrict, locationScope.IDs,
!areaScope.Restrict, areaScope.IDs,
)
} else {
db = db.Where(`EXISTS (
SELECT 1
@@ -91,7 +125,7 @@ func (s productStockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]e
)`)
}
db = s.withRelations(db)
db = s.withRelations(db, locationScope, areaScope)
if params.Search != "" {
db = db.Where("products.name ILIKE ?", "%"+params.Search+"%")
}
@@ -106,13 +140,13 @@ func (s productStockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]e
}
func (s productStockService) GetOne(c *fiber.Ctx, id uint) (*entity.Product, error) {
scope, err := m.ResolveLocationScope(c, s.ProductRepository.DB())
locationScope, areaScope, err := m.ResolveLocationAreaScopes(c, s.ProductRepository.DB())
if err != nil {
return nil, err
}
if scope.Restrict {
if len(scope.IDs) == 0 {
if locationScope.Restrict || areaScope.Restrict {
if (locationScope.Restrict && len(locationScope.IDs) == 0) || (areaScope.Restrict && len(areaScope.IDs) == 0) {
return nil, fiber.NewError(fiber.StatusNotFound, "Product not found")
}
var count int64
@@ -121,7 +155,8 @@ func (s productStockService) GetOne(c *fiber.Ctx, id uint) (*entity.Product, err
Joins("JOIN warehouses w ON w.id = pw.warehouse_id").
Where("pw.product_id = ?", id).
Where("pw.qty > 0").
Where("w.location_id IN ?", scope.IDs).
Where("(? OR w.location_id IN ?)", !locationScope.Restrict, locationScope.IDs).
Where("(? OR w.area_id IN ?)", !areaScope.Restrict, areaScope.IDs).
Count(&count).Error; err != nil {
return nil, err
}
@@ -130,7 +165,9 @@ func (s productStockService) GetOne(c *fiber.Ctx, id uint) (*entity.Product, err
}
}
product, err := s.ProductRepository.GetByID(c.Context(), id, s.withRelations)
product, err := s.ProductRepository.GetByID(c.Context(), id, func(db *gorm.DB) *gorm.DB {
return s.withRelations(db, locationScope, areaScope)
})
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, fiber.NewError(fiber.StatusNotFound, "Product not found")
}