mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-23 06:45:43 +00:00
[FIX/BE-US] feat adjustment location and area
This commit is contained in:
@@ -74,6 +74,10 @@ func (s *adjustmentService) withRelations(db *gorm.DB) *gorm.DB {
|
||||
}
|
||||
|
||||
func (s *adjustmentService) GetOne(c *fiber.Ctx, id uint) (*entity.AdjustmentStock, error) {
|
||||
if err := m.EnsureStockLogAccess(c, s.StockLogsRepository.DB(), id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
adjustmentStock, err := s.AdjustmentStockRepository.GetByStockLogID(c.Context(), id)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
@@ -95,6 +99,9 @@ func (s *adjustmentService) Adjustment(c *fiber.Ctx, req *validation.Create) (*e
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := m.EnsureWarehouseAccess(c, s.WarehouseRepo.DB(), uint(req.WarehouseID)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := common.EnsureRelations(c.Context(),
|
||||
common.RelationCheck{Name: "Product", ID: &req.ProductID, Exists: s.ProductRepo.IdExists},
|
||||
common.RelationCheck{Name: "Warehouse", ID: &req.WarehouseID, Exists: s.WarehouseRepo.IdExists},
|
||||
@@ -304,6 +311,19 @@ func (s *adjustmentService) AdjustmentHistory(c *fiber.Ctx, query *validation.Qu
|
||||
Preload("ProductWarehouse.Product").
|
||||
Preload("ProductWarehouse.Warehouse")
|
||||
|
||||
scope, scopeErr := m.ResolveLocationScope(c, s.AdjustmentStockRepository.DB())
|
||||
if scopeErr != nil {
|
||||
return nil, 0, scopeErr
|
||||
}
|
||||
if scope.Restrict {
|
||||
if len(scope.IDs) == 0 {
|
||||
return []*entity.AdjustmentStock{}, 0, nil
|
||||
}
|
||||
q = q.Joins("JOIN product_warehouses pw_scope ON pw_scope.id = adjustment_stocks.product_warehouse_id").
|
||||
Joins("JOIN warehouses w_scope ON w_scope.id = pw_scope.warehouse_id")
|
||||
q = m.ApplyScopeFilter(q, scope, "w_scope.location_id")
|
||||
}
|
||||
|
||||
if query.ProductID > 0 {
|
||||
q = q.Joins("JOIN stock_logs ON stock_logs.id = adjustment_stocks.stock_log_id").
|
||||
Joins("JOIN product_warehouses ON product_warehouses.id = stock_logs.product_warehouse_id").
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
+8
-6
@@ -8,6 +8,7 @@ import (
|
||||
service "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/services"
|
||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/validations"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/response"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
@@ -24,12 +25,13 @@ func NewProductWarehouseController(productWarehouseService service.ProductWareho
|
||||
|
||||
func (u *ProductWarehouseController) GetAll(c *fiber.Ctx) error {
|
||||
query := &validation.Query{
|
||||
Page: c.QueryInt("page", 1),
|
||||
Limit: c.QueryInt("limit", 10),
|
||||
ProductId: uint(c.QueryInt("product_id", 0)),
|
||||
WarehouseId: uint(c.QueryInt("warehouse_id", 0)),
|
||||
Flags: c.Query("flags", ""),
|
||||
KandangId: uint(c.QueryInt("kandang_id", 0)),
|
||||
Page: c.QueryInt("page", 1),
|
||||
Limit: c.QueryInt("limit", 10),
|
||||
ProductId: uint(c.QueryInt("product_id", 0)),
|
||||
WarehouseId: uint(c.QueryInt("warehouse_id", 0)),
|
||||
Flags: c.Query("flags", ""),
|
||||
KandangId: uint(c.QueryInt("kandang_id", 0)),
|
||||
TransferContext: c.Query(utils.TransferContextKey, ""),
|
||||
}
|
||||
|
||||
if query.Page < 1 || query.Limit < 1 {
|
||||
|
||||
+39
-17
@@ -7,11 +7,11 @@ import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/sirupsen/logrus"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
||||
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
|
||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/validations"
|
||||
kandangrepo "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||
m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -54,9 +54,17 @@ func (s productWarehouseService) GetAll(c *fiber.Ctx, params *validation.Query)
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
scope, err := m.ResolveLocationScope(c, s.Repository.DB())
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
applyScope := true
|
||||
if params.TransferContext == utils.TransferContextInventoryTransfer {
|
||||
applyScope = !m.HasPermission(c, m.P_TransferCreateOne)
|
||||
}
|
||||
var scope m.ScopeFilter
|
||||
var err error
|
||||
if applyScope {
|
||||
scope, err = m.ResolveLocationScope(c, s.Repository.DB())
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
}
|
||||
|
||||
if params.ProductId > 0 {
|
||||
@@ -96,12 +104,15 @@ func (s productWarehouseService) GetAll(c *fiber.Ctx, params *validation.Query)
|
||||
productWarehouses, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
|
||||
db = s.withRelations(db)
|
||||
|
||||
if scope.Restrict {
|
||||
if len(scope.IDs) == 0 {
|
||||
return db.Where("1 = 0")
|
||||
db = db.Joins("JOIN warehouses w_scope ON product_warehouses.warehouse_id = w_scope.id").
|
||||
Where("w_scope.deleted_at IS NULL")
|
||||
if applyScope {
|
||||
if scope.Restrict {
|
||||
if len(scope.IDs) == 0 {
|
||||
return db.Where("1 = 0")
|
||||
}
|
||||
db = db.Where("w_scope.location_id IN ?", scope.IDs)
|
||||
}
|
||||
db = db.Joins("JOIN warehouses w_scope ON product_warehouses.warehouse_id = w_scope.id").
|
||||
Where("w_scope.location_id IN ?", scope.IDs)
|
||||
}
|
||||
|
||||
if params.ProductId != 0 {
|
||||
@@ -130,19 +141,30 @@ func (s productWarehouseService) GetAll(c *fiber.Ctx, params *validation.Query)
|
||||
}
|
||||
|
||||
func (s productWarehouseService) GetOne(c *fiber.Ctx, id uint) (*entity.ProductWarehouse, error) {
|
||||
scope, err := m.ResolveLocationScope(c, s.Repository.DB())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
applyScope := true
|
||||
if c.Query(utils.TransferContextKey, "") == utils.TransferContextInventoryTransfer {
|
||||
applyScope = !m.HasPermission(c, m.P_TransferCreateOne)
|
||||
}
|
||||
var scope m.ScopeFilter
|
||||
var err error
|
||||
if applyScope {
|
||||
scope, err = m.ResolveLocationScope(c, s.Repository.DB())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
productWarehouse, err := s.Repository.GetByID(c.Context(), id, func(db *gorm.DB) *gorm.DB {
|
||||
db = s.withRelations(db)
|
||||
if scope.Restrict {
|
||||
if len(scope.IDs) == 0 {
|
||||
return db.Where("1 = 0")
|
||||
db = db.Joins("JOIN warehouses w_scope ON product_warehouses.warehouse_id = w_scope.id").
|
||||
Where("w_scope.deleted_at IS NULL")
|
||||
if applyScope {
|
||||
if scope.Restrict {
|
||||
if len(scope.IDs) == 0 {
|
||||
return db.Where("1 = 0")
|
||||
}
|
||||
db = db.Where("w_scope.location_id IN ?", scope.IDs)
|
||||
}
|
||||
db = db.Joins("JOIN warehouses w_scope ON product_warehouses.warehouse_id = w_scope.id").
|
||||
Where("w_scope.location_id IN ?", scope.IDs)
|
||||
}
|
||||
return db
|
||||
})
|
||||
|
||||
+7
-6
@@ -13,10 +13,11 @@ type Update struct {
|
||||
}
|
||||
|
||||
type Query struct {
|
||||
Page int `query:"page" validate:"omitempty,number,min=1"`
|
||||
Limit int `query:"limit" validate:"omitempty,number,min=1,max=100"`
|
||||
ProductId uint `query:"product_id" validate:"omitempty,number,min=1"`
|
||||
WarehouseId uint `query:"warehouse_id" validate:"omitempty,number,min=1"`
|
||||
Flags string `query:"flags" validate:"omitempty"`
|
||||
KandangId uint `query:"kandang_id" validate:"omitempty,number,min=1"`
|
||||
Page int `query:"page" validate:"omitempty,number,min=1"`
|
||||
Limit int `query:"limit" validate:"omitempty,number,min=1,max=100"`
|
||||
ProductId uint `query:"product_id" validate:"omitempty,number,min=1"`
|
||||
WarehouseId uint `query:"warehouse_id" validate:"omitempty,number,min=1"`
|
||||
Flags string `query:"flags" validate:"omitempty"`
|
||||
KandangId uint `query:"kandang_id" validate:"omitempty,number,min=1"`
|
||||
TransferContext string `query:"transfer_context" validate:"omitempty,oneof=inventory_transfer"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user