Sari la conținut

Stocuri ​

Stocul per locație pentru fiecare produs, plus o vedere agregată per produs și operațiuni de ajustare a stocului.

Endpoint-uri ​

MetodăCaleDescriere
GET/api/v1/inventoryListă paginată a rândurilor de stoc (unul per produs+locație); filtre product_id, location_id, sku, low_stock.
GET/api/v1/inventory/summaryTotal agregat per produs, peste toate locațiile.
POST/api/v1/inventory/add-stockAdaugă stoc la un produs într-o locație.
POST/api/v1/inventory/remove-stockScoate stoc dintr-un produs la o locație.

Filtre la listare (GET /api/v1/inventory) ​

ParametruTipNote
product_idintegerFiltrează după produs (products.product_id).
location_idintegerFiltrează după locație (locations.id).
skustringFiltrează după SKU-ul produsului.
low_stockbooleantrue → doar produsele sub min_stock_level (când e configurat).
per_pageintegerImplicit 100.

Total agregat (GET /api/v1/inventory/summary) ​

Un rând per produs, însumat peste toate locațiile. Fiecare rând conține product_id, total_quantity, total_reserved, available_quantity (= total − rezervat) și location_count. Obiectul product inclus aduce și price și price_eur (decimal, ca string), deci prețul e disponibil fără un apel separat per rând.

ParametruTipNote
product_idintegerFiltrează după produs (products.product_id).
searchstringCaută în name, sku, barcode (aplicat înainte de agregare, deci total reflectă rezultatul).
in_stockboolean1 → doar produse cu total_quantity > 0; 0 → doar produse cu totalul pe zero. Filtrul e agregat (HAVING), iar total / last_page reflectă setul filtrat.
per_pageintegerImplicit 100.

in_stock=0 aici ≠ pe /products

summary se construiește grupând rândurile de inventar, deci un produs fără niciun rând de stoc nu apare deloc aici. in_stock=0 înseamnă „rândurile existente însumează zero", nu „produs niciodată stocat". Pentru a prinde și produsele fără niciun rând, folosește /products?in_stock=0.

Adăugare stoc ​

Câmpuri pentru POST /api/v1/inventory/add-stock:

CâmpTipObligatoriuNote
product_idintegerdaTrebuie să existe (products.product_id).
location_idintegerdaTrebuie să existe (locations.id).
quantityinteger ≥ 1daCantitatea de adăugat.
batch_numberstring ≤ 50nuLot/șarjă.
lot_numberstring ≤ 50nu
expiry_dateYYYY-MM-DDnuData de expirare.
notestextnuNotă liberă, salvată în mișcarea de stoc.
bash
curl -X POST https://tenant.notsowms.ro/api/v1/inventory/add-stock \
  -H "Authorization: Bearer tenant.7c4a8d09ca3762af61e59520943dc26494f8941b" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": 812,
    "location_id": 14,
    "quantity": 20,
    "batch_number": "B-2026-06",
    "notes": "Recepție furnizor"
  }'

Răspuns 201 — rândul de stoc actualizat (cu produsul și locația):

json
{
  "data": {
    "id": 3391,
    "product_id": 812,
    "location_id": 14,
    "quantity": 20,
    "reserved_quantity": 0,
    "batch_number": "B-2026-06",
    "product": { "product_id": 812, "sku": "BRK-PAD-001", "name": "Plăcuțe frână față" },
    "location": { "id": 14, "location_code": "CULOAR1-RAFT-3" }
  }
}

Scoatere stoc ​

Câmpuri pentru POST /api/v1/inventory/remove-stock:

CâmpTipObligatoriuNote
product_idintegerdaTrebuie să existe (products.product_id).
location_idintegerdaTrebuie să existe (locations.id).
quantityinteger ≥ 1daCantitatea de scos.
notestextnuNotă liberă, salvată în mișcarea de stoc.

Dacă produsul nu are stoc la acea locație sau cantitatea cerută depășește stocul disponibil, primești 422:

json
{ "error": "Insufficient stock." }

Fără cod de motiv

Operațiunile de stoc nu primesc un cod de motiv de la apelant. Fiecare adăugare/scoatere se înregistrează automat în inventory_transactions (vizibil în pagina Mișcări stocuri) cu un motiv setat de server (Adăugare stoc via API / Eliminare stoc via API). Singurul text liber pe care îl poți atașa este notes.

Documentație API notso WMS