Stock Item Service
Overview
Stock Items represent the current stock state of a product in a specific warehouse.
Each Stock Item defines:
- quantity physically available (
QuantityOnHand) - quantity reserved/allocated (
QuantityAllocated) - replenishment threshold (
ReorderLevel)
Stock items are unique per (ProductId, WarehouseId) pair and are used by Inventory
to power availability checks, allocation logic and replenishment planning.
All stock item operations are tenant-aware and fully audited.
Endpoints
GET
/api/v1/StockItem/GetAllStockItemByProductId/{productId}
Returns all stock items for a given product across warehouses.
Behavior:
- Filters by
ProductId - Returns a list of
StockItemModel - Returns
200with an empty list if the product has no stock items
(service returns empty list; controller currently returns200as long as the list is not null)
Response:
List<StockItemModel>
Authorization:
- Requires Bearer Token
GET
/api/v1/StockItem/GetAllStockItemByWarehouseId/{warehouseId}
Returns all stock items stored in a specific warehouse.
Behavior:
- Filters by
WarehouseId - Supports large datasets via internal batching:
- if total count exceeds
LARGE_DATASET_THRESHOLD, the service reads in batches ofBATCH_SIZE
- if total count exceeds
- Returns a list of
StockItemModel - Returns
200with an empty list if no stock items exist in the warehouse
(service returns empty list; controller currently returns200as long as the list is not null)
Response:
List<StockItemModel>
Authorization:
- Requires Bearer Token
POST
/api/v1/StockItem/AddNewStockItem
Creates a new stock item (product stock in a warehouse).
Request body (StockItemModel):
WarehouseId(long?, required, must be > 0)ProductId(long, required, must be > 0)QuantityOnHand(decimal?, required, must be >= 0)QuantityAllocated(decimal?, required, must be >= 0)ReorderLevel(decimal?, required, must be >= 0)
Behavior:
- Validation is enforced in the service layer (
IsReadyToAdd()) - Prevents duplicates by enforcing uniqueness of
(ProductId, WarehouseId) - Successful creation writes an audit log entry
Errors:
- Returns
400if:- request body is invalid (
IsReadyToAdd()is false) - stock item already exists for
(ProductId, WarehouseId) - database insert - or other internal error occurs
- request body is invalid (
Authorization:
- Requires Bearer Token
PUT
/api/v1/StockItem/UpdateStockItemByProductId/{productId}
Updates an existing stock item for a given product and warehouse.
Route parameters:
productId(long, required)
Request body (StockItemModel):
WarehouseId(long?, required, must be > 0)QuantityOnHand(decimal?, optional)QuantityAllocated(decimal?, optional)ReorderLevel(decimal?, optional)
Behavior:
- The controller sets
ProductIdfrom the route - Validation is enforced (
IsReadyToUpdate()requiresProductId > 0andWarehouseId > 0) - Looks up stock item by
(ProductId, WarehouseId) - Updates only fields provided in body:
QuantityOnHandupdated if not nullQuantityAllocatedupdated if not nullReorderLevelupdated if not null
- Successful update writes an audit log entry
Errors:
- Returns
400if request body is invalid (IsReadyToUpdate()is false) - Returns
404if no stock item exists for(ProductId, WarehouseId)
Authorization:
- Requires Bearer Token
DELETE
/api/v1/StockItem/DeleteStockItemByProductIdAndWarehouseId/{productId}/{warehouseId}
Deletes a stock item by (ProductId, WarehouseId).
Route parameters:
productId(long, required)warehouseId(long, required)
Behavior:
- Performs a hard delete
- Successful deletion writes an audit log entry
Errors:
- Returns
404if the stock item does not exist
Authorization:
- Requires Bearer Token
Notes
- Validation is enforced in the service layer, not via model attributes
(ProductId, WarehouseId)is treated as a unique pair (duplicates are blocked)- Large warehouse reads are batched when dataset exceeds
LARGE_DATASET_THRESHOLD - All state-changing operations are audited
- Internal errors are logged and not exposed to API consumers