Stock Transaction Service
Overview
Stock Transactions represent historical stock movements for products in warehouses.
Each Stock Transaction records:
- quantity change (
QtyChange) - reason for the movement (
ReasonCode) - reference type and ID linking to the source document (
RefType,RefId) - timestamp of the movement (
OccurredAt) - user who initiated the transaction (
CreatedBy)
Stock transactions are tied to existing stock items via (ProductId, WarehouseId) pair and provide
a complete audit trail of all inventory movements. They power reporting, reconciliation and
stock history tracking.
All stock transaction operations are tenant-aware and fully audited.
Endpoints
GET
/api/v1/StockTransactions/product/{productId}
Returns the full stock allocation history for a product — every stock transaction across all of its variants, in one call. Intended for a product-level "stock history" view.
Route parameters:
productId(long, required)
Behavior:
- Filters by
ProductIddirectly (a transaction'sProductIdis set at creation time, independent of which variant it's for) - Includes the variant's SKU (
VariantSku) alongside each transaction, resolved via the transaction'sProductVariantId - Ordered newest first (
OccurredAtdescending) - Returns
200with an empty list if the product has no stock transactions
Response:
List<StockTransactionModel>(see Stock Transaction Model — includesVariantSku)
Authorization:
- Requires Bearer Token
POST
/api/v1/StockTransactions
Creates a new stock transaction (records a stock movement).
Request body (StockTransactionModel):
WarehouseId(long, required, must be > 0)ProductId(long, required, must be > 0)QtyChange(decimal, required, must not be 0)ReasonCode(string, required, must not be null)RefType(string?, optional)RefId(string?, optional)OccurredAt(DateTime, required)CreatedBy(string?, optional)
Behavior:
- Validation is enforced in the service layer (
IsReadyToAdd()) IsReadyToAdd()validates:WarehouseId > 0ProductId > 0QtyChange != 0
- Verifies that a stock item exists for
(ProductId, WarehouseId)before creating transaction - Records the stock movement with all provided details
- Successful creation writes an audit log entry
Errors:
- Returns
400if:- request body is invalid (
IsReadyToAdd()is false) ReasonCodeis null or empty- no stock item exists for
(ProductId, WarehouseId) - database insert - or other internal error occurs
- request body is invalid (
Response:
200 OKwith message:"New supplier added successfully"(note: message should reference "stock transaction")400 Bad Requestwith message:"Add new supplier failed"(note: message should reference "stock transaction")
Authorization:
- Requires Bearer Token
Notes
- Validation is enforced in the service layer, not via model attributes
- Stock transactions require an existing stock item for the
(ProductId, WarehouseId)pair QtyChangecan be positive (stock in) or negative (stock out), but cannot be zeroReasonCodeis mandatory (enforced at service level, not byIsReadyToAdd())- All transactions are immutable once created (no update or delete endpoints)
- Transactions provide complete audit trail for inventory movements
- Internal errors are logged and not exposed to API consumers