Przejdź do głównej zawartości

Odczyt zapasu

Większość integracji, które mylą się co do zapasu, nie myli się przy zapisie. Wyprowadzają jeszcze raz liczbę, którą moduł już publikuje, robią to odrobinę inaczej i potem nie zgadzają się z panelem.

Wszystko tutaj to odczyt. Wystarczy p2lab_stockly.viewer albo uprawnienie :read danej encji.

GET warehouse/stock/product/{productId}?page=1&limit=10 ACL: p2lab_stockly_warehouse_stock:read · najwyżej 100 wierszy na stronę

Jeden wiersz na parę (magazyn, bin), plus reguły zamawiania i liczba do zakupu, które należą do całego magazynu, a nie do strony wyników.

{
"data": [
{
"id": "0191f0…",
"productId": "0191f3…",
"warehouseId": "0191f1…",
"warehouseName": "Main warehouse",
"binLocationId": "0191f2…",
"binLocationCode": "A-01-02",
"binRole": null,
"stock": 24,
"reserved": 6,
"available": 18
}
],
"rules": {},
"purchasable": {},
"total": 3,
"page": 1,
"limit": 10
}

binRole: null to zwykły bin magazynowy. Każda inna wartość oznacza bufor; co który z nich wyklucza, opisuje model zapasu.

GET warehouse/stock/product/{productId}/summary?withVariants=1 ACL: p2lab_stockly_warehouse_stock:read

Liczby stojące za kafelkami na stronie produktu. withVariants=1 sprawia, że produkt nadrzędny sumuje swoje warianty.

{
"data": {
"total": 24, "reserved": 6, "available": 17, "backordered": 1,
"pending": 0, "warehouses": 2, "expiring": 0,
"inTransit": 0, "onOrder": 40
}
}
PoleZnaczy
totalsurowa liczba fizyczna, razem z buforami
reservedile przypisały sobie zamówienia
availableile jeszcze da się sprzedać
backorderedpopyt, którego żadna półka nie pokrywa
pendingsztuki w buforze przyjęć albo w drodze — w trakcie wchodzenia
expiringpartie z terminem w ciągu 30 dni
inTransit, onOrdernależne od innego magazynu / od dostawcy

GET warehouse/{warehouseId}/product/{productId}/available ACL: p2lab_stockly_warehouse_stock:read

Odpowiada {"available": 12} i niczym więcej. Przydaje się przy sprawdzeniu skanu albo bramce, gdzie wczytywanie wierszy i sumowanie ich lokalnie jest dodatkową pracą o ten sam wynik.

GET warehouse/stock/product/{productId}/reservations?grain=order&page=1&limit=10 ACL: p2lab_stockly_warehouse_stock:read

grainJeden wiersz na
orderzamówienie (wartość domyślna)
binmagazyn + bin + nośnik + zamówienie
backorderzamówienie, któremu wciąż należy się towar

Odpowiedź niesie data, total, totalReserved, totalBackordered, page, limit i grain, na który odpowiedziała. Nieznane grain to 400, a nie ciche podstawienie wartości domyślnej.

Wiersze pochodzą z linii rezerwacji, czyli z tych samych liczb, które sumuje kafelek Reserved w panelu: lista i kafelek mówiące co innego to właśnie ten błąd, któremu ten endpoint zapobiega.

MetodaŚcieżkaOdpowiada
GETwarehouse/stock/batches/{productId}wszystkie partie produktu, z terminami
GETwarehouse/stock/{warehouseId}/batches/{productId}to samo, w jednym magazynie
GETwarehouse/stock/placements/{productId}gdzie fizycznie leżą jego loty
GETwarehouse/stock/{warehouseId}/{binLocationId}/placements/{productId}umiejscowienia w jednym binie
GETwarehouse/stock/{warehouseId}/loose-bins/{productId}biny, w których leży luzem, poza nośnikami
GETwarehouse/{warehouseId}/stock/pickable-source/{productId}umiejscowienia, z których wolno kompletować
GETwarehouse/stock/product/{productId}/batch-historyjak zmieniały się jego partie w czasie
GETwarehouse/batch-trace/{batchNumber}gdzie powędrował jeden numer partii, w całej sieci
GETwarehouse/order-lots/{orderId}które loty wyszły z danym zamówieniem

Dwa ostatnie to dokładnie to, czego potrzebuje pytanie o wycofanie partii: odpowiadają „kto dostał tę partię” bez ręcznie pisanego złączenia.

GET|POST warehouse/stock/movements/{productId} ACL: p2lab_stockly_warehouse_stock_movement:read

Rejestr dla jednego produktu. POST przyjmuje ciało z filtrami na wypadek, gdy nie da się ich wyrazić w adresie.

Do wszystkiego o kształcie raportu rejestr jest też zwykłą encją: /api/search/p2lab-stockly-warehouse-stock-movement z własnymi filtrami i agregacjami bywa mniejszą pracą niż stronicowanie tego endpointu.

MetodaŚcieżkaOdpowiadaACL
GETwarehouse/order/{orderId}/allocationsobraz pokrycia per pozycja; z ?warehouseId= także werdykt „zostało gdzie indziej”p2lab_stockly.viewer
GETwarehouse/order/{orderId}/stock-targetsdo którego węzła przypisana jest każda pozycjap2lab_stockly_warehouse_stock:read
GETwarehouse/order/{orderId}/pick-plandokąd zostałby wysłany kompletującyp2lab_stockly_warehouse_stock:read

pick-plan to propozycja i niczego nie zapisuje, więc przydaje się do pokazania planu, zanim ktoś ruszy z miejsca.

POST warehouse/{warehouseId}/bin-options ACL: p2lab_stockly.viewer

Jedna strona pozycji do wyboru binu, z ich flagami i kolejnością, złożona po stronie serwera. Istnieje dlatego, że alternatywa, czyli ściągnięcie na klienta wszystkich binów i wszystkich wierszy zapasu magazynu i sortowanie tam, to sposób, w jaki wybór binu przestaje być używalny w prawdziwym magazynie.

Pokrewne: POST warehouse/{warehouseId}/bin-occupancy dla zapełnienia binów oraz POST warehouse/{warehouseId}/suggest-bin dla miejsca, w które trafiłoby odkładanie.

Wszystko jest encją Shopware, a /api/search/… to właściwe narzędzie do raportów, eksportów i każdego pytania z własnymi filtrami. Traci się przy tym to, co te endpointy dokładają: arytmetykę dostępności zgodną z product.stock co do wiersza, liczby rezerwacji brane z linii, a nie z bufora pochodnego, oraz sumowanie wariantów.

Dwie reguły przenoszą się tu wprost z API pakowania:

Null to nie zero. Brak wartości znaczy, że nikt jej nie zapisał: termin null to partia bez zapisanej trwałości, a nie partia przeterminowana.

Nie wyprowadzaj ponownie liczby, która ma endpoint. Jeśli liczba ma swój endpoint, czytaj endpoint. Każde lokalnie napisane „available” w historii tego modułu prędzej czy później przestało się zgadzać z tym, przeciwko któremu sklep sprzedaje.