Kontraktowa logistyka magazynowa z perspektywy systemu WMS

Kontraktowa logistyka magazynowa polega na tym, że firma powierza magazynowanie i kompletację, a czasem także część transportu, operatorowi 3PL (Third-Party Logistics), który prowadzi te procesy w jednym obiekcie dla wielu zleceniodawców naraz. Dla oprogramowania oznacza to zmianę podstawowego założenia: towar w bazie nie ma jednego właściciela, więc każdy zapas i każda operacja muszą wskazywać, czyje są.

Współpracę reguluje umowa z poziomem jakości (SLA) i zasadami rozliczeń, zwykle zależnymi od liczby obsłużonych zamówień albo zajętych palet. System operatora musi więc prowadzić magazyn i jednocześnie liczyć koszty, bo bez zapisu każdej czynności faktura dla klienta jest szacunkiem. Warunkiem podpisania kontraktu bywa też integracja z ERP lub platformą sprzedażową zleceniodawcy, ponieważ ręczne raportowanie stanów przy tej skali przestaje być praktyczne.

Specjalistyczne oprogramowanie WMS dla operatorów 3PL różni się od systemu magazynu własnego w pięciu obszarach, które zestawia poniższa tabela.

ObszarMagazyn własnyOperator 3PL
Właściciel towaruJedna firma, atrybut zbędnyWielu zleceniodawców, właściciel w każdym rekordzie
Reguły procesuJeden zestaw dla całego magazynuOdrębny zestaw dla każdego klienta
RozliczeniaKoszt wewnętrzny, bez fakturyFaktura liczona z zapisanych operacji
Dostęp do danychPracownicy jednej firmyDodatkowo klienci z widokiem ograniczonym do własnego towaru
RaportyDla zarządu i kierownikówOsobny komplet dla każdego klienta, zgodny z SLA

Wielu klientów w jednej bazie danych

Klientów można rozdzielić w SQL Server na kilka sposobów. Wybór wpływa na koszt utrzymania oraz na łatwość migracji schematu przy nowej wersji systemu.

PodejścieSeparacja danychKoszt utrzymaniaKiedy się sprawdza
Osobna baza na klientaNajsilniejsza, także w kopiach zapasowychWiele baz do monitorowania i aktualizacjiKilku dużych klientów z własnymi wymaganiami audytu
Wspólna baza, kolumna OwnerIdLogiczna, wymuszana predykatamiJedna baza, jedna wersja schematuDziesiątki klientów i wspólne regały
Osobny schemat na klientaŚrednia, na poziomie uprawnień do schematuLiczba obiektów rośnie z każdym klientemUmiarkowana liczba klientów ze zmodyfikowanymi tabelami

W magazynie współdzielonym, gdzie towary różnych klientów stoją w tych samych regałach, najczęściej wybiera się wspólną bazę z kolumną OwnerId. Identyfikator właściciela zapisuje się na poziomie partii i dokumentu, dzięki czemu stan danego kontrahenta można w każdej chwili wyodrębnić z całości zapasu. Opis takiego modelu znajduje się w artykule o magazynie klienta w systemie WMS.

Ta sama kolumna zmienia definicję unikalności. Kod SKU "A100" może istnieć u dwóch klientów i oznaczać dwa różne produkty, więc indeks unikalny obejmuje parę (OwnerId, Sku), a nie sam kod.

-- przykładowy schemat, nie struktura konkretnego produktu
CREATE TABLE dbo.Items (
    ItemId  INT IDENTITY PRIMARY KEY,
    OwnerId INT           NOT NULL,   -- zleceniodawca
    Sku     NVARCHAR(40)  NOT NULL,
    Name    NVARCHAR(200) NOT NULL
);
CREATE UNIQUE INDEX UX_Items_Owner_Sku ON dbo.Items (OwnerId, Sku);
Troje osób w hali regałowej przegląda dokumenty na podkładkach, jedna z nich w kamizelce odblaskowej
Towar wielu zleceniodawców w jednym magazynie - właściciel zapasu jest atrybutem partii i dokumentu

Indeksy i rozkład danych między klientami

Kolumna OwnerId powinna otwierać klucz każdego indeksu nieklastrowego używanego przez raporty klienta, na przykład (OwnerId, LocationId) albo (OwnerId, ItemId). Wtedy zapytanie jednego klienta czyta wąski zakres indeksu, a nie cały magazyn.

Rozkład danych w takiej tabeli jest wyraźnie nierówny: jeden duży klient może stanowić większość wierszy StockLines. Plan wykonania zbudowany przy pierwszym wywołaniu dla małego klienta bywa fatalny dla dużego (parameter sniffing). Raporty parametryzowane przez OwnerId zabezpiecza się wtedy podpowiedzią OPTION (RECOMPILE) albo osobnymi statystykami filtrowanymi dla największych właścicieli.

Wymuszanie separacji w silniku bazy

Warunek WHERE OwnerId = @OwnerId łatwo pominąć w jednym raporcie, a wtedy klient zobaczy cudzy towar. Row-Level Security (RLS), dostępne od SQL Server 2016, przenosi ten warunek do silnika: predykat filtrujący jest dopisywany do każdego odczytu z chronionej tabeli. Aplikacja po zalogowaniu użytkownika zapisuje identyfikator właściciela w kontekście sesji, a funkcja predykatu go porównuje. Szczegóły składni opisuje dokumentacja Row-Level Security w SQL Server.

CREATE SCHEMA Security;
GO
CREATE FUNCTION Security.fn_OwnerFilter (@OwnerId INT)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 AS Allowed
WHERE @OwnerId = CAST(SESSION_CONTEXT(N'OwnerId') AS INT)
   OR CAST(SESSION_CONTEXT(N'IsOperator') AS BIT) = 1;
GO
CREATE SECURITY POLICY Security.OwnerPolicy
ADD FILTER PREDICATE Security.fn_OwnerFilter(OwnerId) ON dbo.StockLines
WITH (STATE = ON);
GO
-- po zalogowaniu użytkownika portalu klienta
EXEC sp_set_session_context @key = N'OwnerId', @value = 17, @read_only = 1;

Konto operatora, którego magazynier pracuje na towarze wielu klientów, dostaje znacznik IsOperator i widzi wszystko. Konto klienta widzi wyłącznie własne wiersze, także wtedy, gdy ktoś napisze zapytanie bez filtra. Zakres uprawnień poszczególnych ról opisuje strona o rolach i użytkownikach w systemie WMS, a portal dla kontrahentów - artykuł o module internetowym dla kontrahentów.

Reguła: dokument wydania nie powstaje, gdy właściciel pozycji różni się od właściciela zlecenia.

Rozliczanie paletomiejsc i operacji

Rozliczenie 3PL składa się z dwóch strumieni danych. Składowanie liczy się w jednostkach zajętej powierzchni w czasie, a operacje sztukami wykonanych czynności. Oba strumienie muszą pochodzić z zapisów systemu, a nie z arkusza uzupełnianego na koniec miesiąca. Modele stawek stałych i transakcyjnych omawia artykuł o rozliczaniu kosztów magazynowych.

Składnik rozliczeniaJednostkaŹródło danych w WMS
Składowanie paletPaletomiejsce na dobęDobowy zrzut zajętych lokalizacji
Składowanie drobnicyMetr sześcienny na dobęObjętość z kartoteki pomnożona przez ilość
PrzyjęciePaleta lub linia dokumentu PZDokument przyjęcia
KompletacjaLinia zamówienia lub sztukaZadania kompletacji potwierdzone skanem
Usługi dodatkoweCzynność lub godzina pracyZlecenie usługi

Wiele firm łączy stawkę stałą za składowanie podstawowe z rozliczeniem transakcyjnym pozostałych operacji. Taki układ daje operatorowi przewidywalny przychód, a klientowi koszt zależny od faktycznego ruchu towaru.

Dobowy zrzut zajętości magazynu

Liczby paletomiejsc nie da się odtworzyć wstecz z bieżącego stanu, bo paleta przyjęta w poniedziałek i wydana we wtorek już nie leży w regale. Zadanie SQL Agent uruchamiane o stałej godzinie zapisuje więc zdjęcie zajętych lokalizacji do tabeli dziennej.

INSERT INTO dbo.DailyOccupancy (SnapshotDate, OwnerId, LocationId, PalletId)
SELECT CAST(SYSDATETIME() AS DATE), s.OwnerId, s.LocationId, s.PalletId
FROM dbo.StockLines AS s
WHERE s.Quantity > 0
GROUP BY s.OwnerId, s.LocationId, s.PalletId;

Opłatę za składowanie wylicza się z tej tabeli. Każdy wiersz jest jedną paletą w jednej dobie, więc wystarczy policzyć wiersze klienta w okresie i pomnożyć przez stawkę z cennika.

SELECT o.OwnerId,
       COUNT(*) AS PalletDays,
       COUNT(*) * r.RatePerPalletDay AS StorageFee
FROM dbo.DailyOccupancy AS o
JOIN dbo.OwnerRates AS r
  ON r.OwnerId = o.OwnerId
WHERE o.SnapshotDate >= '2026-09-01'
  AND o.SnapshotDate <  '2026-10-01'
GROUP BY o.OwnerId, r.RatePerPalletDay;

Reguła: paletę przyjętą i wydaną tego samego dnia cennik liczy jako jedną dobę składowania.

Operacje i usługi dodatkowe

Operacje liczy się z tabeli zdarzeń, w której każda czynność ma właściciela i typ, a przy zapisie dostaje znacznik czasu. Zestawienie miesięczne grupuje ją po kliencie i typie operacji. Usługi o wartości dodanej wchodzą do rozliczenia jako odrębne zlecenia z liczbą wykonanych czynności:

  • Etykietowanie - naklejenie etykiety klienta lub etykiety logistycznej na jednostce, liczone od sztuki albo od palety.
  • Personalizacja opakowań - zmiana opakowania zbiorczego lub dołożenie wkładki, rozliczana od zlecenia.
  • Drobny montaż - łączenie zestawów z kilku indeksów, wyceniane od zestawu.
  • Obsługa zwrotów - przyjęcie zwrotu konsumenckiego z kontrolą stanu oraz decyzją o powrocie na stan, liczone od sztuki.
Pracownica w mundurze z odblaskami odbiera wydruk z drukarki stojącej w hali magazynowej
Dokument rozliczeniowy dla klienta powstaje z zapisanych operacji i zrzutu dobowego, bez ręcznego zestawienia

Zamknięcie okresu i korekty

Po wystawieniu faktury okres rozliczeniowy zamyka się w systemie. Dokument korygujący z datą wsteczną nie zmienia już zrzutów dobowych ani sum operacji z zamkniętego miesiąca, tylko tworzy pozycję korygującą w okresie bieżącym. Klient dostaje wtedy fakturę zgodną z załączonym zestawieniem, a operator zachowuje możliwość odtworzenia każdej kwoty z zapisów.

Spory dotyczą najczęściej liczby paletodni po zwrocie lub reklamacji, więc zestawienie powinno wskazywać numery palet i daty przyjęcia oraz wydania. Wiersz faktury bez takiego odnośnika jest trudny do obrony.

Odrębne reguły dla każdego klienta

Ten sam magazyn obsługuje klientów o różnych wymaganiach, więc reguły procesu przypisuje się do właściciela towaru, a nie do całej instalacji. Konfiguracja obejmuje metodę kompletacji, na przykład falową lub strefową, oraz priorytety wysyłek. Osobno ustawia się progi alarmowe zapasu i zasadę rotacji FIFO lub FEFO. Standard wypracowany dla e-commerce rzadko działa bez zmian w logistyce produkcyjnej lub farmaceutycznej.

Wymagania branż różnią się mechanizmami, które system musi egzekwować:

  • E-commerce - krótki czas realizacji zamówienia i masowe zwroty. Do tego dochodzą integracje z wieloma platformami sprzedażowymi oraz kurierami.
  • FMCG i branża spożywcza - kontrola dat przydatności i rotacja FEFO, a przy towarach chłodzonych ciągłość łańcucha temperatury; opisane w artykule o logistyce w branży spożywczej.
  • Farmacja i kosmetyki - pełna identyfikowalność partii produkcyjnych i zgodność z Dobrą Praktyką Dystrybucyjną.
  • Produkcja i handel B2B - zaopatrzenie linii w komponenty just-in-time oraz duże, nieregularne zamówienia paletowe.

Operator obsługujący kilka branż jednocześnie utrzymuje w systemie osobny profil dla każdego zleceniodawcy. Błędne przypisanie towaru do niewłaściwego zlecenia kończy się reklamacją, więc skanowanie na terminalach mobilnych potwierdza każdą czynność w chwili jej wykonania.

Raporty i dostęp klienta do danych

Klient korzystający z outsourcingu oczekuje trzech odpowiedzi bez telefonu do magazynu: ile ma towaru, co się z nim działo i w jakim statusie są jego zamówienia. Portal działa w przeglądarce, wymaga indywidualnego loginu, a transmisję szyfruje TLS. Część wdrożeń umożliwia też eksport stanów i historii zamówień do plików CSV lub XLSX.

RaportZawartośćKiedy powstaje
Stan zapasówLokalizacje i partie z ilościami na wskazany dzieńNa żądanie klienta
Ruchy magazynoweWszystkie ruchy towaru w okresie, od przyjęcia po wydanieCodziennie lub co tydzień
Realizacja zamówieńTerminowość wysyłek i dokładność kompletacji względem SLACo miesiąc
RozliczeniePaletodni i operacje z zastosowanymi stawkamiNa koniec okresu rozliczeniowego

Każdy raport pobiera parametr OwnerId z sesji użytkownika, więc ten sam szablon obsługuje wszystkich klientów. Konto portalowe ma rolę tylko do odczytu, bez prawa zapisu w tabelach operacyjnych, a wszystkie zapytania klienta przechodzą przez widoki ograniczone predykatem RLS. Dzięki temu nawet błąd w szablonie raportu nie ujawni danych innego zleceniodawcy. Budowę takich zestawień w SSRS opisuje artykuł o SQL Report Builder, a zasady bieżącej ewidencji ilościowej - strona o stanach magazynowych.

Trzy osoby w hali z regałami analizują wydruki i dokumenty na podkładkach
Przegląd raportów z klientem - stan zapasów i realizacja SLA pochodzą z jednej bazy

Wskaźniki SLA policzone z danych systemu

Kontrola operatora jest pośrednia: klient nie stoi przy regale, więc ocenia pracę po wskaźnikach z umowy. Wskaźnik ma sens tylko wtedy, gdy definicja jest zapisana w umowie i policzalna z bazy. Terminowość wysyłek to udział zamówień wydanych przed godziną graniczną w liczbie zamówień z tego dnia. Dokładność kompletacji to udział linii wysłanych bez reklamacji w liczbie wszystkich linii.

Umowa powinna też opisywać sposób raportowania i procedurę reklamacyjną na wypadek niezgodności oraz zabezpieczenie ciągłości dostaw przy awarii systemu lub szczycie zamówień. Przed podpisaniem kontraktu klient może zażądać wglądu w raporty SLA z bieżących wdrożeń i planu awaryjnego. Uzależnienie całej logistyki od jednego operatora bywa równie ryzykowne jak sztywny magazyn własny, dlatego część firm dzieli regiony sprzedaży lub kategorie asortymentu między dwóch dostawców. Kryteria wyboru partnera opisuje artykuł o modelach współpracy i wyborze operatora logistycznego.

Reguła: wskaźnik SLA bez zapisanej definicji i źródła w bazie jest przedmiotem sporu, a nie miarą jakości.

Ślad każdej zmiany stanu pozwala rozstrzygać takie spory na podstawie zapisów, a mechanizmy kontroli opisuje artykuł o kontroli nad towarami w systemie WMS.

Integracja z systemami zleceniodawcy

Każdy klient ma własny profil integracji: format dokumentów, kanał wymiany (REST albo plik), harmonogram i reguły obsługi wyjątków. W Studio WMS.net konfiguruje się mapowanie dokumentów, harmonogram wymiany danych i reguły błędów wspólnie z zespołem wdrożeniowym na etapie analizy przedwdrożeniowej. Informacje o produkcie zawiera serwis Studio WMS.net.

Operator z kilkudziesięcioma klientami utrzymuje więc kilkadziesiąt takich profili, a błąd jednego nie może zatrzymać pozostałych. W praktyce oznacza to osobną kolejkę wiadomości albo osobny katalog wymiany dla każdego zleceniodawcy oraz osobny licznik błędów. Wadliwy plik jednego klienta trafia wtedy do jego katalogu wyjątków, a pozostali klienci pracują bez przerwy. Techniki kolejkowania, powtórzeń bez dublowania dokumentów i obsługi błędów opisuje artykuł o integracji WMS z ERP.