Morffeus Docs
ENSR morffeus.com

Zalihe

Zalihe su u Morffeusu količina po varijanti proizvoda po magacinu. Vaš ERP ili magacinski sistem ostaje izvor istine. Izmene šaljete preko PUT /int/stocks, a magacin postavljate na prebrojane količine preko POST /stock/reconcile. Čitanja vam vraćaju brojeve sabrane po magacinima i podeljene po prodavnicama.

Kako se redovi uparuju#

Naše identifikatore nikad ne šaljete. Svaki red imenuje varijantu i magacin onako kako ih zna vaš sistem, a mi ih pronalazimo:

Svaki red uspeva ili ne uspeva za sebe. Red koji imenuje varijantu ili magacin koji ne možemo da nađemo, ili koji bi količinu spustio ispod minimuma, vraća se u failed sa razlogom. Ostali redovi se upisuju. Odgovor je 200 u oba slučaja, zato uvek pročitajte failed.

Objekat zaliha#

Ono što PUT /int/stocks vraća za svaki upisani red. Jedan objekat po varijanti po magacinu.

PoljeOpis
idintegerNaš identifikator reda zaliha.
product_variant_idintegerNaš identifikator varijante.
product_idintegerNaš identifikator proizvoda kome varijanta pripada.
warehouse_idintegerNaš identifikator magacina. warehouse_code koji ste poslali nalazi se u objektu magacina.
quantitynumberKoličina na stanju u jedinici mere varijante. Decimale su dozvoljene.
min_qtynumber · podrazumevano 0Najmanja količina do koje ovaj red može da stigne. Izmena koja bi quantity spustila ispod nje ne uspeva, pa sa podrazumevanom vrednošću 0 zalihe ne mogu da odu u minus.
track_stockbooleantrue za redove napravljene preko ovog API-ja.
app_idintegerVaša aplikacija.
updated_by_user_idinteger · može biti nullKorisnik koji stoji iza poslednje izmene, kad ga znamo. null posle izmene preko PUT /int/stocks.
inserted_at, updated_atdatetime · ISO 8601, UTCKada je red napravljen i kada je poslednji put izmenjen. Šalje se bez pomaka, na primer 2026-09-30T09:41:12.

Izmena stanja zaliha#

PUT /api/v2/int/stocks

Menja zalihe jedne ili više varijanti u jednom ili više magacina. Red za varijantu koja u tom magacinu još nema zalihe pravi red zaliha sa količinom koju pošaljete. Red za postojeći red zaliha mu dodaje poslatu količinu. Redovi koje izostavite ostaju netaknuti.

Količina se dodaje, ne postavlja. Kad pošaljete 5 za red koji ima 40, ostaje 45, a isti paket poslat dvaput računa se dvaput. Da biste poslali ukupne količine koje vaš sistem ima, koristite Usklađivanje magacina, ili pošaljite razliku u odnosu na ono što ste poslali poslednji put.

Čitanja zaliha, GET /stocks i GET /stocks/aggregate, odmah pokazuju izmenu. Liste proizvoda, i prodavnica napravljena na njima, čitaju zalihe iz keša pretrage koji izmenu preuzima pri sledećem zakazanom osvežavanju. Kretanje zaliha se ne beleži; kad vam treba istorija, umesto toga knjižite kretanja zaliha.

Parametri tela zahteva

ParametarOpis
stocksobaveznoniz objekataJedna stavka po varijanti po magacinu.
stocks[].codejedno odstringŠifra varijante, ista vrednost kao code na varijanti proizvoda.
stocks[].barcodejedno odstringBarkod sačuvan na varijanti.
stocks[].external_refjedno odstringVaš sopstveni identifikator varijante, onako kako je poslat uz proizvod.
stocks[].warehouse_codeobaveznostringŠifra magacina. Šifra koju ne možemo da nađemo obara red.
stocks[].quantityobaveznonumberZa novi red zaliha, njegova količina. Za postojeći red, iznos koji se dodaje; pošaljite negativan broj da biste zalihe umanjili.
stocks[].min_qtynumber · podrazumevano 0Minimum za novi red zaliha. Zanemaruje se kad red postoji.

Vraća

data.success: upisani objekti zaliha. data.failed: jedna stavka za svaki red koji nije upisan, sa redom koji ste poslali u input i razlogom u error.message, na primer product variant or warehouse not found. Red koji bi pao ispod minimuma ne uspeva sa porukom koja sadrži quantitybelowminqty. Nijedna lista ne čuva redosled kojim ste slali, zato neuspehe uparujte po input.

Greške

StatusKada
200I kad neki ili svi redovi ne uspeju. Oni su u data.failed.
400Telo zahteva nema niz stocks.
401Token nedostaje ili je opozvan. Telo navodi polje token.
PUT/int/stocks
curl -X PUT "https://api.morffeus.com/api/v2/int/stocks" \
  -H "Authorization: Bearer $MORFFEUS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "stocks": [
      { "code": "SKU-1001", "warehouse_code": "WH-NS",
        "quantity": 42, "min_qty": 5 },
      { "barcode": "8600123456789", "warehouse_code": "WH-BG",
        "quantity": -3 },
      { "external_ref": "ERP-778", "warehouse_code": "WH-NS",
        "quantity": 12.5 }
    ]
  }'
const res = await fetch('https://api.morffeus.com/api/v2/int/stocks', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.MORFFEUS_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    stocks: [
      { code: 'SKU-1001', warehouse_code: 'WH-NS',
        quantity: 42, min_qty: 5 },
      { barcode: '8600123456789', warehouse_code: 'WH-BG',
        quantity: -3 },
      { external_ref: 'ERP-778', warehouse_code: 'WH-NS',
        quantity: 12.5 },
    ],
  }),
});
const { data } = await res.json();
if (data.failed.length) console.warn(data.failed);
Odgovor200 OK
{
  "data": {
    "success": [
      {
        "id": 5102,
        "product_variant_id": 91388,
        "product_id": 48377,
        "warehouse_id": 17,
        "quantity": 20.5,
        "min_qty": 0.0,
        "track_stock": true,
        "app_id": 12,
        "updated_by_user_id": null,
        "inserted_at": "2026-08-14T07:02:55",
        "updated_at": "2026-09-30T09:41:12"
      },
      {
        "id": 5101,
        "product_variant_id": 91120,
        "quantity": 42.0,
        "min_qty": 5.0,
        …
      }
    ],
    "failed": [
      {
        "input": {
          "barcode": "8600123456789",
          "warehouse_code": "WH-BG",
          "quantity": -3
        },
        "error": {
          "message": "product variant or warehouse not found"
        }
      }
    ]
  }
}
Greška401 Unauthorized
{
  "errors": {
    "token": "API.Autorization.Unauthorized"
  }
}

Lista zaliha#

GET /api/v2/stocks

Redovi zaliha aplikacije, po jedan za svaku varijantu u svakom magacinu, sa poljima detalja proizvoda. Koristite ga da proverite sinhronizaciju, ne za stalno ispitivanje: kad vam treba šta se promenilo od nekog trenutka, čitajte kretanje zaliha.

Parametri upita

ParametarOpis
warehouseIdintegerSamo redovi ovog magacina. Magacin druge aplikacije daje 400.
productIdintegerSamo redovi ovog proizvoda.
productVariantIdintegerSamo redovi ove varijante.
language_idinteger · podrazumevano jezik tokenaJezik za measuring_unit_short.
showPerWarehouseoznakaSvakom redu dodaje warehouse_code. Uključuje ga bilo koja vrednost, i false, pa ga izostavite kad vam ne treba.
offsetinteger · podrazumevano 0Koliko redova da se preskoči i koliko da se vrati. Vrednost koja nije ceo broj od nule naviše vraća se na podrazumevanu. Pogledajte paginaciju.
limitinteger · podrazumevano 30

Četiri parametra id-jeva moraju biti celi brojevi. Onaj koji nije odbija se sa 400, a prazan se zanemaruje.

Vraća

data: listu redova, poređanih po proizvodu, svaki sa id (red zaliha), product_id, quantity, min_qty, measuring_unit_short (kratak naziv jedinice mere), warehouse_code kad ga tražite, i poljima detalja proizvoda onako kako ih vaša aplikacija definiše. Nema broja stranica ni ukupnog broja: tražite sledeću stranicu dok ne dobijete manje redova od limit.

Greške

StatusKada
400Parametar id-ja nije ceo broj: Stocks.InvalidWarehouseId, Stocks.InvalidProductId, Stocks.InvalidProductVariantId ili Stocks.InvalidLanguageId, svi navedeni zajedno. Magacin nije vaš: Warehouses.ErrorAppId.
401Token nedostaje ili je opozvan. Pogledajte Autentifikaciju.
GET/stocks
curl -G "https://api.morffeus.com/api/v2/stocks" \
  -H "Authorization: Bearer $MORFFEUS_TOKEN" \
  -d "warehouseId=17" -d "showPerWarehouse=true" -d "limit=2"
Odgovor200 OK
{
  "data": [
    {
      "id": 5101,
      "product_id": 48213,
      "warehouse_code": "WH-NS",
      "quantity": 42.0,
      "min_qty": 5.0,
      "measuring_unit_short": "pcs",
      "name": "Espresso beans 1 kg"
    },
    {
      "id": 5102,
      "product_id": 48377,
      "warehouse_code": "WH-NS",
      "quantity": 20.5,
      "min_qty": 0.0,
      "measuring_unit_short": "kg",
      "name": "House blend, loose"
    }
  ]
}
Greška400 Bad Request
{
  "errors": {
    "stocks": ["Stocks.InvalidWarehouseId"]
  }
}

Ukupno po magacinima#

GET /api/v2/stocks/aggregate

Količine na stanju, rezervisane i raspoložive za jednu varijantu, ili za svaku aktivnu varijantu proizvoda, sabrane po magacinima aplikacije i podeljene po varijanti i po prodavnici. Rezervisano je ono što drže naplate u toku i otpisi zaliha. Raspoloživo je stanje umanjeno za rezervisano, nikad ispod nule. To je broj koji prikazujete kad proizvod nije vezan za jednu prodavnicu.

Parametri upita

ParametarOpis
productVariantIdjedno odintegerJedna varijanta. Ima prednost kad pošaljete oba.
productIdjedno odintegerSvaka aktivna varijanta ovog proizvoda.

Vraća

data.kpis: ukupne vrednosti, sa brojem magacina i prodavnica koji za to imaju redove zaliha. data.by_variant: ukupno po varijanti, po našem identifikatoru varijante. data.app_locations: ukupno po prodavnici, svaka sa svojim magacinima. Bez ijednog od dva parametra poziv vraća 400.

Odgovor200 OK
{
  "data": {
    "kpis": {
      "on_hand": 62.5,
      "reserved": 2.0,
      "available": 60.5,
      "warehouses": 2,
      "locations": 2
    },
    "by_variant": {
      "91120": { "on_hand": 62.5, "reserved": 2, "available": 60.5 }
    },
    "app_locations": [
      {
        "id": 31, "name": "Novi Sad centre",
        "on_hand": 42, "reserved": 2, "available": 40,
        "warehouses": [
          { "id": 17, "name": "Novi Sad",
            "on_hand": 42, "reserved": 2, "available": 40 }
        ]
      },
      { "id": 32, "name": "Belgrade west", … }
    ]
  }
}
Greška400 Bad Request
{
  "errors": {
    "stocks": ["Stocks.ProductVariantIdRequired"]
  }
}

Usklađivanje magacina#

POST /api/v2/stock/reconcile

Postavlja varijante koje navedete u jednom magacinu na količine koje ste prebrojali. Svaku poredimo sa onim što magacin ima i razlike knjižimo kao jedno kretanje zaliha, pa izmena ostaje u istoriji, a liste proizvoda se odmah osvežavaju. Koristite ga posle popisa, ili kad god vaš sistem šalje ukupne količine umesto izmena.

Varijante koje izostavite zadržavaju svoju količinu. Usklađivanje postavlja samo ono što navedete. Varijante uparuje samo po šifri, poslatoj kao sku. Poznata šifra bez zaliha u magacinu prvo dobija red zaliha koji počinje od nule.

Parametri tela zahteva

ParametarOpis
warehouse_codeobaveznostringMagacin koji se usklađuje.
productsobaveznoniz objekataJedna stavka po varijanti.
products[].skuobaveznostringŠifra varijante.
products[].quantityobaveznonumberKoličina koju ste prebrojali.
stock_movement_numberstringVaša oznaka kretanja zaliha. Ako je izostavite, napravićemo jednu od 12 znakova.
descriptionstring · podrazumevano "Product stock adjustment"Opis kretanja zaliha.

Vraća

data.failed: stavke koje nismo mogli da primenimo, svaka sa stavkom koju ste poslali u product i razlogom u error, na primer Could not find any product or variant with SKU: SKU-9999. Stavke čija se količina već poklapa preskaču se. Prazna lista znači da je svaka stavka primenjena.

Greške

StatusKada
404U vašoj aplikaciji nema magacina sa ovim warehouse_code.
422warehouse_code nije string, ili products nije lista.
POST/stock/reconcile
curl -X POST "https://api.morffeus.com/api/v2/stock/reconcile" \
  -H "Authorization: Bearer $MORFFEUS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "warehouse_code": "WH-NS",
    "stock_movement_number": "COUNT-2026-09",
    "products": [
      { "sku": "SKU-1001", "quantity": 40 },
      { "sku": "SKU-1002", "quantity": 7 },
      { "sku": "SKU-9999", "quantity": 3 }
    ]
  }'
Odgovor200 OK
{
  "data": {
    "failed": [
      {
        "product": { "sku": "SKU-9999", "quantity": 3 },
        "error": "Could not find any product or variant with SKU: SKU-9999"
      }
    ]
  }
}
Poslednja izmena 1. oktobra 2026. · API v2 Nešto nije u redu na ovoj stranici?