Av Anders Ekdahl

Förhindra översälj med rätt lagersaldo-strategi

2022-04-05

Arkitektur, Composable Commerce & Tips

I ett vanligt systemlandskap för en e-handel behöver flera system veta lagersaldot på dina artiklar. Ofta åtminstone e-handelsystemet och WMS/ERP. Så fort samma data finns i flera system så finns risken att den datan är ur synk. Helt enkelt att lagersaldot i e-handelsystemet säger en sak medan WMS:et säger något annat.

Lagersaldon är inte den enda data som finns i flera system. Ofta har du produktinformation som först kommer från ditt ERP in till ditt PIM som sen går över till ditt e-handelssystem. Den stora skillnaden är att den datan har ett tydligare och mer enkelriktat flöde. Artikeln föds i ERP och när den kommer över till PIM så är det PIM som sen äger den. E-handelsystemet tar emot datan men den ändras sällan i e-handelssystemet. Och även i mer komplexa scenarios där olika system äger och ändrar på PIM-datan så är det olika fält som de olika systemen äger. Det är uppenbart att ifall man låter samma fält ändras i flera system samtidigt så har man skapat sig en mardröm.

Det som gör lagersaldo så mycket svårare är dels att det ofta måste uppdateras i flera system, och att det finns en tidsaspekt i hur giltig datan är. När en saldouppdatering skickas från ett system till ett annat kan det saldot redan ha blivit inaktuellt pga andra ändringar som skett.

Det finns flera inriktningar här man kan ta för att undvika över/under-sälj och ha så korrekta lagersaldon som möjligt.

Alternativ 1: Realtids-kommunikation mellan system

Detta alternativ bygger på att man inte har lagersaldo utspritt i flera system, utan istället låter man sina system fråga WMS:et i realtid när man behöver veta lagersaldot. Detta alternativ låter väldigt lockande eftersom det förstås finns en enkelhet i att bara ha saldot i ett enda system. Ingen risk för krockar, ingen risk att det blir inaktuellt.

Detta är det tveklöst bästa alternativet. Men, det bygger på att ens WMS är byggt för att hantera det. Och kraven för att kunna hantera det är fler än vad man kanske tror.

För det första måste WMS:et då ha minst lika bra skalbarhets-egenskaper som ditt e-handelsystem. Om du går ut med en stor kampanj är det inte bara sajten som ska skala upp utan även WMS:et för att kunna hantera den ökade trafiken. Men inte bara det, du har dessutom gjort dig helt beroende av att WMS:et är uppe för att kunna ta emot ordrar på e-handeln. Ifall WMS:et går ner kan ingen handla. Det ställer helt andra systemkrav på WMS:et än vad det kanske är byggt för.

Även om detta alternativ bygger på att lagersaldot enbart ska finnas i WMS:et så är det en sanning med modifikation. Det som det egentligen innebär är att saldot bara förändras i WMS:et. Vill du t.ex. att dina kunder ska kunna filtrera bort produkter som inte finns i lager så behöver lagersaldot finnas i sökmotorn också. Ytterligare ett krav på WMS:et är alltså att det kan kommunicera saldo-ändringar inkrementellt till andra system via events. Många WMS har förstås stöd för det men ofta på mindre moderna sätt. Sökmotorn ska då inte bara få produkt-data från e-handelsystemet utan också lagersaldo från WMS:et. Alternativt att skicka lagersaldot till e-handelsystemet men bara se det som en läsbar kopia.

Fördelar

  • Det är konceptuellt skönt att veta att lagersaldo bara kan ändras i ett enda system. Du minimerar risken för över/under-sälj.

  • Förutsatt att ditt WMS klarar av de krav som ställs är det en sund arkitektur att låta olika system hantera indivudella delar snarare än att sprida ut det.

Nackdelar

  • WMS:et blir en single point of failure för att kunder ska kunna handla.

  • Höga krav ställs på WMS:et i form av upptid, skalbarhet och möjlighet att exponera saldo och saldo-förändringar på tekniskt moderna sätt.

  • Du kan behöva bygga integrationen mellan din e-handel och WMS:et själv. Beroende på vilket e-handelsystem du har kan detta vara en betydande och i vissa fall t.o.m. omöjlig insats.

Alternativ 2: Hantera och ändra lagersaldo i flera system parallellt

Detta alternativ låter väldigt komplicerat vid första anblick. Att flera system förändrar lagersaldo oberoende av varandra känns instinktivt som att det snabbt kommer bli fel. Och det är komplicerat men det har ett antal fördelar med sig ifall man väljer rätt strategi. Det som de flesta inte tänker på i denna lösning är att det är mycket viktigt att bara vissa uppdateringar skickas mellan system, och att man skickar förändringar snarare än hela saldot. Dvs, istället för att WMS:et skickar "nu är saldot 100" så ska det skicka "nu minskade saldot med 3". Anledningen till det är att "nu är saldot 100" är en definitiv siffra och den siffran kommer bara vara sann en viss tid. Medan "nu minskade saldot med 3" är sant för alltid och inte beroende av tid på samma sätt.

I ett löskopplat/composable systemlandskap vill man kommunicera mellan system på ett asynkront sätt. Istället för att ställa en fråga och vänta på svar mellan system så skickas events. För att få så mycket ut av en eventdriven arkitektur som möjligt behöver man minimera beroendet på när dessa events skickas och tas emot i tid. Om t.ex. orderbekräftelsemailet skickas som en följd av ett event så är det bättre ifall mailet skickas tio minuter efter ordern är lagd än att det inte skickas alls. Att man designar sitt landskap så att fördröjningar inte orsakar annat än att vissa flöden går lite långsammare.

Att skicka saldoförändringar snarare än saldon är precis en sådan sak där att skicka saldon kan orsaka fel vid fördröjningar. T.ex:

  1. Artikel A får nytt lagersaldo i WMS:et, och saldot är nu 10

  2. Lagersaldot synkas över till e-handeln

  3. En order läggs i e-handeln med två av artikel A, och ordern läggs på kö för att skickas till WMS:et

  4. E-handelsystemet räknar ner sitt saldo med två, och har nu 8 i sitt saldo medan WMS:et fortfarande har 10

  5. En kund ringer samtidigt in och vill ta bort artikel A från sin order vilket kundtjänst gör

  6. WMS:et tar tillbaka artikeln till det säljbara saldot och ser det nu som att saldot är 11

  7. WMS:et skickar till e-handeln att saldot är 11 och e-handeln räknar upp saldot från 8 till 11

  8. Ordern från punkt 3 kommer över till WMS:et som räknar ner till 9 och skickar detta till e-handeln

I detta fall har vi asynkron kommunikation mellan WMS och e-handel och det faktum att vi skickar lagersaldo snarare än förändringar gör att vi riskerar översälj mellan punkt 7 och 8. Hade vi istället vid punkt 7 skickat "saldot ska öka med 1" så hade vi sluppit översälj, eftersom e-handeln hade haft 9 i sitt saldo och WMS:et hade haft 11 i sitt saldo fram till punkt 8 var klar och båda system var i synk igen.

Att skicka förändringar är inte det enda du behöver tänka på här. Om du har ett e-handelsystem som själv håller och räknar ner saldo när ordrar läggs kan inte alla förändringar skickas till e-handeln från WMS:et eftersom vi då kommer att räkna ner dubbelt. T.ex:

  1. En order läggs på e-handeln med artikel A

  2. E-handeln räknar ner sitt saldo från 10 till 9

  3. Ordern skickas iväg till WMS:et

  4. WMS:et räknar ner sitt saldo och nu är vi duktiga och skickar ut en förändring snarare än siffra. WMS:et skickar alltså ut "artikel A ska sänkas med 1"

  5. E-handeln får meddelandet och räknar ner artikel A från 9 till 8

I detta fall skapar vi undersälj vilket inte är fullt så illa som översälj men ändå inte bra. Sättet vi löser detta på är antingen genom att WMS:et skickar ut en anledning till att saldot sänks tillsammans med förändringen, eller att WMS:et helt enkelt inte skickar sänkningar till e-handeln som görs för att e-handelsordrar läggs. Att föredra är den första, att meddelandet som skickas ut innehåller anledningen till att saldot sänks. Då kan e-handeln få in meddelandet och själv avgöra att ingen justering behöver göras.

Anledningen till att detta är att föredra är för att vi då håller systemen mer isolerade. Ifall WMS:et vet att det inte ska skicka ut meddelanden till e-handeln för e-handelsordrar så tar WMS:et på sig ansvar som egentligen inte rör WMS:et. Om e-handeln en dag ändras så att det där meddelandet faktiskt behövs så vill vi inte behöva röra WMS:et.

Fördelar

  • Isolation och lösare kopplingar mellan system ger ett sunt systemlandskap över tid

  • WMS:et behöver inte skalas upp för att hantera e-handelstrafik

  • Mindre krav ställs på WMS:et rent tekniskt i form av moderna API:er och events

Nackdelar

  • Mer komplext, WMS-teamet och e-handelsteamet måste prata ihop sig

  • Har man ingen event-arkitektur sedan innan är det ett stort steg att ta

  • Det är nästan ofrånkomligt att det faktiska saldot över tid kommer skilja mellan WMS och e-handel. Event kan missas för att system går ner, system kan innehålla buggar, etc. Denna approach kräver att man kan göra en manuell full synk av saldo på hela artikelregistret när lagret är stängt.

Alternativ 3: Håll reservationer i e-handeln istället för att räkna ner saldo

Detta alternativ är en förlängning av alternativ 2, och öppnar upp lite nya möjligheter och säkerhet men är tekniskt mer komplext.

Ett problem med att skicka saldoförändringar snarare än definitiva siffror är att det aldrig är helt säkert att göra en full synk från WMS:et till e-handeln. Åtminstone inte utan att stänga ner e-handeln till att inte ta emot fler ordrar. Enda tillfället då det är säkert är ifall man vet alla alla ordrar är skickade från e-handeln och alla meddelande-köer är tomma. Om man har Norden som kundbas kanske det är tänkbart att göra på natten men ju mer global man blir desto sämre skalar det.

I detta alternativ så tillåter vi definitiva saldon igen, att WMS:et skickar "100 i saldo för artikel A" istället för "artikal A ska sänkas med 1". Allra helst ska meddelandet från WMS:et innehålla all den informationen. Dvs, totalt saldo, förändring och anledning till förändring. Då kan mottagande system själv ta beslut.

Anledningen till att vi tillåter det igen är för att i detta alternativ räknar vi inte ner saldot när en order läggs i e-handeln utan skapar istället en lagerreservation kopplad till ordern. Och det effektiva saldot ur e-handelns perspektiv är WMS:ets saldo minus reservationer som WMS:et ännu inte tagit emot. Flödet blir istället så här:

  1. Både e-handeln och WMS:et har saldo 10 för artikel A

  2. Order O1 läggs på e-handeln med artikel A

  3. En lagerreservation för order O1 skapas i e-handeln som säger att 1 av artikel A är reserverad

  4. Det effektiva saldot för e-handeln blir 9 även fast saldot fortfarande är 10 precis som i WMS:et

  5. Ordern skickas iväg till WMS:et

  6. WMS:et räknar ner sitt saldo och skickar ut ett meddelande som säger att order O1 är mottagen

  7. E-handeln släpper reservationen på O1

  8. Här kan vi sen välja ifall vi vill att e-handeln själv ska räkna ner sitt saldo i samband med att reservationen släpps eller om WMS:et skickar ut en sänkning. Om vi låter WMS:et göra det är det väldigt viktigt att det meddelandet kommer före eller samtidigt som order-meddelandet. Annars släpper vi reservationen vilket ökar det effektiva saldot fram tills vi får meddelandet om att det ska räknas ner.

Den stora poängen här är alltså att även fast vi låter både e-handeln och WMS:et räkna ner saldo så har vi brutit upp det till två delar där de två systemen ändrar på var sin del. På så sätt tar vi bort risker med timing av när de olika systemen skap uppdatera saldot.

Fördelar

  • Detta alternativ har alla fördelar som alternativ 2 har

  • Vi har minskat risken att saldon skiljer sig mellan WMS och e-handel eftersom vi skiljer på saldo och reservationer och låter WMS:et styra saldot

  • Reservationer gör det enklare att hantera avbrutna ordrar eftersom vi vet hur en avbruten order påverkar lager. Finns det en reservation så ska den släppas. Finns ingen reservation så behöver vi inte göra något. Utan reservationer kan det vara oklart ifall en avbruten order ska påverka saldot.

  • En full synk av WMS:ets saldo till e-handeln kan köras när som helst eftersom vi skiljt på saldo och effektivt saldo i e-handeln.

Nackdelar

  • Krävs i princip en egen implementation av detta. Jag har hittils inte stött på någon e-handelsplattform som stödjer detta flöde (rätta mig om jag har fel!).

Vad ska jag välja?

Dessa alternativ är listade i stigande krad av komplexitet men också i stigande grad ökad säkerhet. Inget av dem är rätt eller fel och de kan alla tre göra att du kan sova gott om natten med rätt implementation.

Alternativ 1 är främst om du inte har stora mängder trafik eller ifall ditt WMS klarar av det och är byggt för det. Det är en strategi som ofta passar antingen lite mindre e-handlare utan stora mängder trafik, eller väldigt stora e-handlare som har ett WMS som är byggt för att kunna hantera det.

Alternativ 2 är en modell som kan passas in i de flesta e-handelsystem och WMS, och en bra start när du vill frikoppla dina system från varandra.

Alternativ 3 passar främst dig som är beredd att bygga egna lösningar för att sy ihop dina system eftersom detta alternativ inte finns out-of-the-box.

Anders Ekdahl

Anders är hjärnan bakom de tekniska e-handels-ramverken som tagit Nordic Nest, Lyko, NA-KD, Filippa K, Kicks, m.fl. från lovande digitala initiativ till ledande e-handelsaktörer.

I sin roll som CTO och chefsarkitekt för Sveriges främsta e-handelskonsult har han lett över 200 utvecklare till framgång. Med sin förmåga att kombinera teknik, strategi och affärsvärde har Anders en djup insikt om vad du som e-handlare behöver för att nå och överträffa dina mål.

Epost: epost

Commerce Mind

Commerce Mind är ett oberoende specialistföretag inom e-handel. Vi hjälper dig med allt från KPIer till teknik och arkitektur till processutveckling och upphandling.

Läs mer om vårt erbjudande här

Tveka inte på att kontakta oss ifall du vill röra dig snabbare.