mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-25 07:45:44 +00:00
feat(BE-47,48,49,50): implement inventory adjustment system
- Extend DB schema with product_warehouses and stock_logs tables - Implement stock adjustment API (increase/decrease operations) - Add comprehensive validation for all adjustment operations - Implement audit log system for each adjustment with history tracking - Include transaction handling, DTOs, seeders, and proper error handling - Add adjustment history API with pagination and filtering TODO: Integration testing pending
This commit is contained in:
-1
@@ -26,7 +26,6 @@ func (u *ProductWarehouseController) GetAll(c *fiber.Ctx) error {
|
||||
query := &validation.Query{
|
||||
Page: c.QueryInt("page", 1),
|
||||
Limit: c.QueryInt("limit", 10),
|
||||
Search: c.Query("search", ""),
|
||||
ProductId: uint(c.QueryInt("product_id", 0)),
|
||||
WarehouseId: uint(c.QueryInt("warehouse_id", 0)),
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ type ProductWarehouseBaseDTO struct {
|
||||
Id uint `json:"id"`
|
||||
ProductId uint `json:"product_id"`
|
||||
WarehouseId uint `json:"warehouse_id"`
|
||||
Quantity int `json:"quantity"`
|
||||
Quantity float64 `json:"quantity"`
|
||||
}
|
||||
|
||||
type ProductWarehouseListDTO struct {
|
||||
|
||||
+9
@@ -14,6 +14,7 @@ type ProductWarehouseRepository interface {
|
||||
IsProductExist(ctx context.Context, productId uint) (bool, error)
|
||||
IsWarehouseExist(ctx context.Context, warehouseId uint) (bool, error)
|
||||
ExistsByID(ctx context.Context, id uint) (bool, error)
|
||||
GetProductWarehouseByProductAndWarehouseID(ctx context.Context, productId, warehouseId uint) (*entity.ProductWarehouse, error)
|
||||
}
|
||||
|
||||
type ProductWarehouseRepositoryImpl struct {
|
||||
@@ -51,3 +52,11 @@ func (r *ProductWarehouseRepositoryImpl) IsWarehouseExist(ctx context.Context, w
|
||||
func (r *ProductWarehouseRepositoryImpl) ExistsByID(ctx context.Context, id uint) (bool, error) {
|
||||
return repository.Exists[entity.ProductWarehouse](ctx, r.db, id)
|
||||
}
|
||||
|
||||
func (r *ProductWarehouseRepositoryImpl) GetProductWarehouseByProductAndWarehouseID(ctx context.Context, productId, warehouseId uint) (*entity.ProductWarehouse, error) {
|
||||
var productWarehouse entity.ProductWarehouse
|
||||
if err := r.DB().WithContext(ctx).Where("product_id = ? AND warehouse_id = ?", productId, warehouseId).First(&productWarehouse).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &productWarehouse, nil
|
||||
}
|
||||
|
||||
@@ -58,13 +58,6 @@ func (s productWarehouseService) GetAll(c *fiber.Ctx, params *validation.Query)
|
||||
db = db.Where("warehouse_id = ?", params.WarehouseId)
|
||||
}
|
||||
|
||||
// Search in related product or warehouse names
|
||||
if params.Search != "" {
|
||||
db = db.Joins("LEFT JOIN products ON products.id = product_warehouse.product_id").
|
||||
Joins("LEFT JOIN warehouses ON warehouses.id = product_warehouse.warehouse_id").
|
||||
Where("products.name ILIKE ? OR warehouses.name ILIKE ?", "%"+params.Search+"%", "%"+params.Search+"%")
|
||||
}
|
||||
|
||||
return db.Order("created_at DESC").Order("updated_at DESC")
|
||||
})
|
||||
|
||||
|
||||
+10
-11
@@ -1,21 +1,20 @@
|
||||
package validation
|
||||
|
||||
type Create struct {
|
||||
ProductId uint `json:"product_id" validate:"required,number,min=1"`
|
||||
WarehouseId uint `json:"warehouse_id" validate:"required,number,min=1"`
|
||||
Quantity int `json:"quantity" validate:"required,number,min=0"`
|
||||
ProductId uint `json:"product_id" validate:"required,number,min=1"`
|
||||
WarehouseId uint `json:"warehouse_id" validate:"required,number,min=1"`
|
||||
Quantity float64 `json:"quantity" validate:"required,number,min=0"`
|
||||
}
|
||||
|
||||
type Update struct {
|
||||
ProductId *uint `json:"product_id,omitempty" validate:"omitempty,number,min=1"`
|
||||
WarehouseId *uint `json:"warehouse_id,omitempty" validate:"omitempty,number,min=1"`
|
||||
Quantity *int `json:"quantity,omitempty" validate:"omitempty,number,min=0"`
|
||||
ProductId *uint `json:"product_id,omitempty" validate:"omitempty,number,min=1"`
|
||||
WarehouseId *uint `json:"warehouse_id,omitempty" validate:"omitempty,number,min=1"`
|
||||
Quantity *float64 `json:"quantity,omitempty" validate:"omitempty,number,min=0"`
|
||||
}
|
||||
|
||||
type Query struct {
|
||||
Page int `query:"page" validate:"omitempty,number,min=1"`
|
||||
Limit int `query:"limit" validate:"omitempty,number,min=1,max=100"`
|
||||
Search string `query:"search" validate:"omitempty,max=50"`
|
||||
ProductId uint `query:"product_id" validate:"omitempty,number,min=1"`
|
||||
WarehouseId uint `query:"warehouse_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"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user