Synchronizacja stanów magazynowych: dlaczego co 15 minut to za rzadko
Skąd bierze się oversell, czym różni się stan fizyczny od dostępnego, dlaczego cron co kwadrans nie wystarcza przy kilku kanałach i jak działa synchronizacja oparta na zdarzeniach i kolejkach.
Zrobimy to za Ciebie. Opisz problem, a odpowiemy w ciągu 24 godzin roboczych.
Opisz projektWiększość integracji sklepu z programem magazynowym działa według tego samego schematu: co 15 minut skrypt pobiera stany z ERP i wpisuje je do sklepu. Przez lata to wystarczało. Dziś ten sam towar sprzedaje się w sklepie, na Allegro, na dwóch marketplace’ach i w sklepie stacjonarnym jednocześnie. Piętnaście minut to czas, w którym ostatnią sztukę może kupić trzech klientów. Każdy z nich dostanie potwierdzenie, a dwóch z nich przeprosiny.
W skrócie
- Oversell, czyli sprzedaż towaru, którego nie ma, powstaje w okienku między sprzedażą w jednym kanale a aktualizacją stanu w pozostałych. Im dłuższe okienko, tym więcej takich przypadków.
- Do sklepu i marketplace’ów przesyłaj stan dostępny, nie fizyczny. Stan fizyczny nie uwzględnia rezerwacji i zamówień w kompletacji.
- Zamiast crona co kwadrans użyj zdarzeń: sprzedaż albo zmiana stanu w jednym systemie od razu wysyła komunikat do pozostałych. Kolejka pilnuje, żeby nic nie zginęło.
- Pełna synchronizacja wszystkiego raz dziennie zostaje jako kontrola. Zdarzenia aktualizują na bieżąco, pełny przebieg wyłapuje rozjazdy.
Skąd bierze się oversell
Masz jedną sztukę towaru. O 10:00 kupuje ją klient na Allegro. Cron, który przenosi stany z ERP do sklepu, uruchomił się o 9:58 i następny raz uruchomi się o 10:13. Zamówienie z Allegro trafia do ERP o 10:04, przez BaseLinker lub integrację. Do 10:13 sklep nadal pokazuje jedną sztukę. O 10:09 kupuje ją klient w sklepie. Obaj mają potwierdzenie zamówienia i obaj zapłacili.
Przy jednym kanale i dużych stanach to się prawie nie zdarza. Przy trzech kanałach, towarach w pojedynczych sztukach i promocjach, które skupiają zakupy w krótkim czasie, zdarza się codziennie. Każdy taki przypadek to anulowane zamówienie, zwrot pieniędzy w ciągu 14 dni, negatywna opinia, a na Allegro dodatkowo ryzyko dla jakości sprzedaży. Przy 20 nadsprzedażach miesięcznie koszt obsługi i utraconych klientów przekracza koszt dobrej synchronizacji w kilka miesięcy.
Stan fizyczny a stan dostępny
Drugie źródło oversellu to przesyłanie złej liczby. Program magazynowy zna stan fizyczny: ile sztuk leży na półce. Ale część z nich jest już sprzedana i czeka na pakowanie, część zarezerwowana pod zamówienie telefoniczne, część odłożona dla klienta B2B z umową. Do sklepu powinien trafiać stan dostępny, czyli fizyczny pomniejszony o to wszystko. Jeśli integracja przesyła stan fizyczny, sklep sprzedaje towar, który magazyn właśnie pakuje dla kogoś innego.
| Składnik | Wchodzi do stanu fizycznego | Wchodzi do stanu dostępnego | Uwagi |
|---|---|---|---|
| Towar na półce | tak | tak | podstawa wyliczenia |
| Zamówienia opłacone, niewysłane | tak | nie | najczęstsze źródło rozjazdu |
| Rezerwacje ręczne w ERP | tak | nie | zamówienia telefoniczne, klienci B2B |
| Towar w drodze od dostawcy | nie | zwykle nie | można pokazać jako „dostępny od” z terminem |
| Towar w magazynie reklamacji | tak, jeśli to ten sam magazyn | nie | osobny magazyn albo wyłączenie z wyliczenia |
| Bufor bezpieczeństwa | nie | odejmowany | np. 1 sztuka przy towarach sprzedawanych w kilku kanałach |
Ważne
Ustal w ERP, jak liczyć stan dostępny, zanim ktoś zaprogramuje synchronizację. Zapytaj wprost: czy zamówienia ze sklepu rezerwują towar w ERP w chwili wpłynięcia? Jeśli nie, to ERP pokazuje stan fizyczny i każda synchronizacja z niego będzie zawyżona.
Dlaczego cron co 15 minut to za rzadko, a co 1 minutę to za często
Prosta myśl: skoro 15 minut to za dużo, ustawmy cron co minutę. Przy 500 produktach to zadziała. Przy 20 000 produktów pełne pobranie i porównanie stanów trwa dłużej niż minutę, więc kolejne uruchomienia nakładają się na siebie, serwer sklepu dostaje falę zapytań, a w godzinach szczytu strona kategorii ładuje się kilka sekund. Problem nie jest w częstotliwości. Problem jest w tym, że cron pracuje na całym katalogu, zamiast na zmianach.
Druga słabość crona: nie wie, co się stało między uruchomieniami. Jeśli w ERP stan zmienił się dwa razy w ciągu kwadransa, cron widzi tylko stan końcowy, co jest w porządku. Ale jeśli serwer ERP był niedostępny przez uruchomienie, cron po prostu nic nie zrobił i nikt o tym nie wie. Następny przebieg naprawi stany, ale zamówienia, które przyszły w międzyczasie, mogły już zrobić oversell.
Zdarzenia i kolejki zamiast crona
Lepszy model wygląda tak: każda zmiana stanu to zdarzenie. Sprzedaż w sklepie, sprzedaż na Allegro, przyjęcie dostawy w ERP, korekta po inwentaryzacji. System, w którym zmiana powstała, od razu wysyła komunikat do integracji, a integracja przekazuje nowy stan dostępny do wszystkich pozostałych kanałów. Nie co 15 minut. W ciągu sekund.
Webhooki
PrestaShop i większość platform sklepowych oraz marketplace’ów potrafi wywołać adres w chwili zdarzenia: nowe zamówienie, zmiana statusu, zwrot. To są webhooki. Zamiast pytać co kwadrans „czy coś się zmieniło”, integracja dostaje informację w chwili zmiany. Programy ERP rzadziej mają webhooki, ale zwykle da się wykryć zmianę przez znacznik czasu modyfikacji albo przez mechanizm po stronie bazy, który uzgadnia się z opiekunem systemu.
Kolejka
Zdarzenia trafiają do kolejki, a nie bezpośrednio do kanałów. Kolejka daje trzy rzeczy: kolejność, bo zdarzenia dla jednego towaru wykonują się po sobie i stan końcowy jest poprawny; trwałość, bo jeśli Allegro albo sklep nie odpowiada, komunikat czeka i zostanie dostarczony; oraz powtarzalność, bo każdą nieudaną operację widać w dzienniku i da się ją uruchomić ponownie.
- Klient kupuje ostatnią sztukę w sklepie. PrestaShop wywołuje webhook z numerem zamówienia.
- Integracja odczytuje zamówienie, rezerwuje towar w ERP i wylicza nowy stan dostępny: zero.
- Do kolejki trafiają komunikaty: Allegro zero, marketplace A zero, marketplace B zero.
- Proces kolejki wysyła je po kolei. Allegro przyjmuje od razu. Marketplace B nie odpowiada, komunikat czeka i jest wysyłany ponownie po minucie.
- Dziennik pokazuje: towar X, stan 1 do 0, cztery kanały, trzy potwierdzone, jeden po powtórzeniu. Cały przebieg trwał kilkanaście sekund.
Z naszej praktyki
Sklep z częściami motocyklowymi sprzedawał przez PrestaShop, Allegro i dwa marketplace’y, z synchronizacją cronem co 15 minut. W miesiącu notował od 25 do 40 nadsprzedaży, głównie na towarach w jednej lub dwóch sztukach. Przebudowaliśmy synchronizację na webhooki ze sklepu i z BaseLinkera, kolejkę komunikatów i stan dostępny liczony z rezerwacjami w Subiekcie. Pełny przebieg porównawczy zostawiliśmy raz na noc. W pierwszym pełnym miesiącu nadsprzedaży były dwie, obie przy sprzedaży stacjonarnej, która wtedy jeszcze nie była podłączona.
Pełna synchronizacja zostaje, ale w innej roli
Zdarzenia nie zastępują pełnego porównania, tylko zmieniają jego rolę. Raz dziennie, w nocy, integracja porównuje stany dostępne w ERP ze stanami we wszystkich kanałach i raportuje rozjazdy. Zwykle wychodzą z nich błędy, które zdarzenia nie wyłapują: ktoś zmienił stan ręcznie w panelu Allegro, towar ma dwa symbole, komunikat zginął mimo kolejki. Raport trafia do jednej osoby, która wie, co z nim zrobić.
Synchronizacja stanów ma jeden cel: żeby klient nigdy nie kupił tego, czego nie dostanie. Częstotliwość crona jest tu środkiem, nie miarą jakości.
Jak przejść z crona na zdarzenia
Krok po kroku
- Policz nadsprzedaże. Z ostatnich trzech miesięcy, z podziałem na kanały. To uzasadnienie i miara sukcesu.
- Ustal stan dostępny w ERP. Co odejmować od fizycznego, czy zamówienia ze sklepu rezerwują towar, które magazyny liczyć.
- Włącz webhooki w kanałach. Sklep, BaseLinker lub bezpośrednio marketplace’y. Sprawdź, które zdarzenia są dostępne.
- Postaw kolejkę i dziennik. Komunikaty z kolejnością per towar, powtórzenia, powiadomienia, podgląd w panelu sklepu.
- Zostaw pełny przebieg nocny. Jako kontrolę z raportem rozjazdów, nie jako główny mechanizm.
- Dodaj bufor na towary krytyczne. Przy towarach w kilku kanałach i pojedynczych sztukach bufor jednej sztuki chroni przed ostatnim nierozwiązywalnym przypadkiem: dwoma zakupami w tej samej sekundzie.
Pytania, które słyszymy najczęściej
Czy BaseLinker nie załatwia tego sam?
BaseLinker synchronizuje stany między kanałami, które do niego podłączysz, i robi to dobrze. Ale źródłem stanu jest zwykle ERP, a jakość synchronizacji zależy od tego, jak często i jaki stan trafia z ERP do BaseLinkera. Tu wraca ten sam problem crona i stanu fizycznego.
Czy webhooki są bezpieczne?
Tak, jeśli adres odbiorczy sprawdza podpis albo sekret i przyjmuje tylko numer zdarzenia, a dane pobiera sam z systemu źródłowego. Nie ufamy treści webhooka, tylko sygnałowi, że coś się zmieniło.
Co się dzieje przy awarii ERP?
Zamówienia z kanałów trafiają do kolejki i czekają. Sklep i marketplace’y pracują na ostatnim znanym stanie. Po przywróceniu ERP kolejka przetwarza zdarzenia w kolejności, a nocny przebieg wyłapuje różnice.
Czy to drogie w utrzymaniu?
Kolejka i dziennik to standardowe elementy, które raz postawione działają latami. Koszt utrzymania jest niższy niż koszt obsługi nadsprzedaży, bo błędy widać od razu, a nie po reklamacji klienta.
Masz nadsprzedaże, a integracja „działa, bo cron chodzi”? Opisz kanały, program magazynowy i liczbę produktów, a zaproponujemy, jak przejść na synchronizację zdarzeniową. Zobacz, jak automatyzujemy obsługę zamówień i stanów.