Program do zarządzania dostawami - od zamówienia zakupu do przyjęcia
Dostawa zaczyna się w ERP jako zamówienie zakupu, a kończy w magazynie jako dokument przyjęcia. Między tymi punktami działa program do zarządzania dostawami, który pilnuje terminu i statusu dostawy. Bez niego odpowiedź na pytanie, gdzie jest towar z zamówienia, wymaga telefonu do dostawcy.
Z punktu widzenia danych dostawa ma cztery daty, które rzadko się pokrywają. Rozbieżność między nimi jest najcenniejszą informacją, bo pokazuje opóźnienie, zanim pojazd stanie pod bramą.
- Data zamówiona - termin z zamówienia zakupu, który ustala dział zakupów.
- Data potwierdzona - termin, który obiecał dostawca po przyjęciu zamówienia.
- Okno awizowane - rezerwacja czasu na rampie, którą zatwierdza logistyka magazynu.
- Czas przyjazdu - moment zarejestrowany przy bramie, czyli rzeczywisty początek obsługi.
| Etap | Zdarzenie | Źródło danych | Status w programie |
|---|---|---|---|
| Zamówienie | utworzenie zamówienia zakupu | ERP | zaplanowana |
| Awizacja | zatwierdzenie okna na rampie | dostawca lub logistyka | awizowana |
| Przyjazd | wjazd pojazdu na teren | brama, ochrona | na terenie |
| Rozładunek | rozpoczęcie obsługi przy rampie | magazynier | w rozładunku |
| Przyjęcie | zamknięcie dokumentu PZ | WMS | przyjęta |
Reguła: status dostawy zmienia się wyłącznie przez zdarzenie, a nie przez ręczną edycję pola.
Reguła wynika z konieczności odtworzenia historii. Gdy status jest polem edytowanym, po sporze z przewoźnikiem nie wiadomo, kto i kiedy go zmienił. Gdy status wynika z dziennika zdarzeń, każda zmiana ma czas i autora.
System zarządzania dostawami - statusy i zdarzenia
System zarządzania dostawami przechowuje dziennik zdarzeń zamiast jednego pola statusu. Każde zdarzenie to osobny wiersz z typem zdarzenia i czasem, a autor zapisuje się w osobnej kolumnie. Aktualny status jest po prostu ostatnim zdarzeniem dostawy, a historia pozostaje nienaruszona.
CREATE TABLE dbo.DeliveryEvent (
EventId BIGINT IDENTITY(1,1) PRIMARY KEY,
DeliveryId INT NOT NULL,
EventType VARCHAR(20) NOT NULL, -- PLANNED, ARRIVED, UNLOADING, RECEIVED, CANCELLED
EventAt DATETIME2(0) NOT NULL DEFAULT SYSUTCDATETIME(),
UserName NVARCHAR(60) NULL
);
CREATE INDEX IX_DeliveryEvent_Delivery
ON dbo.DeliveryEvent (DeliveryId, EventId) INCLUDE (EventType, EventAt);
SELECT d.DeliveryId, e.EventType AS CurrentStatus, e.EventAt
FROM dbo.Delivery AS d
CROSS APPLY (
SELECT TOP (1) EventType, EventAt
FROM dbo.DeliveryEvent
WHERE DeliveryId = d.DeliveryId
ORDER BY EventId DESC
) AS e;
Przykład ma charakter poglądowy, a nazwy tabel są przykładowe. Indeks złożony zaczyna się od kolumny DeliveryId, więc dla każdej dostawy SQL Server wykonuje jedno wyszukiwanie i czyta ostatni wpis. Kolumny w klauzuli INCLUDE sprawiają, że zapytanie nie sięga do indeksu klastrowego, co przy tysiącach dostaw dziennie robi różnicę w czasie odpowiedzi.
Zapis zdarzenia i zmiana dokumentu powiązanego, na przykład utworzenie przyjęcia w WMS, powinny odbyć się w jednej transakcji. Gdy oba zapisy przebiegają osobno, po awarii między nimi dostawa ma status przyjętej, a magazyn nie ma dokumentu. Szczegółowy model statusów awizacji od strony przewoźnika opisuje artykuł awizacja transportu - statusy, zmiany, API.
Planowanie dostaw na podstawie zamówień zakupu
Planowanie dostaw zaczyna się od zamówień, które jeszcze nie mają okna. Program tworzy z nich listę propozycji z liczbą palet i przewidywanym czasem rozładunku. Dostawca wybiera termin z wolnych okien, a długość rezerwacji wynika z ładunku, a nie z jego deklaracji.
Okno czasowe ma pojemność, czyli największą liczbę pojazdów obsługiwanych jednocześnie na rampie. Gdy dostawcy rezerwują ostatnie wolne miejsce w tej samej sekundzie, zapis wymaga blokady zakresu, inaczej obaj dostają potwierdzenie. Zasady doboru długości okien omawia artykuł o oknach czasowych, a ogólne podejście do harmonogramu dostaw przedstawia strona planowanie dostaw.
Celem planowania jest płaski rozkład obciążenia. Jeżeli wszystkie dostawy z zamówień tygodnia przyjeżdżają w poniedziałek rano, rampy stoją puste od środy. Przesunięcie części dostawców na słabsze dni jest tańsze niż dodatkowa zmiana na przyjęciach.
| Parametr planowania | Skąd pochodzi | Skutek dla okna |
|---|---|---|
| Liczba palet | zamówienie zakupu lub awizo ASN | długość rezerwacji |
| Rodzaj pojazdu | zgłoszenie dostawcy | dobór rampy i sprzętu |
| Wymagana temperatura | karta towaru | rampa z uszczelnieniem |
| Godziny pracy magazynu | ustawienia obiektu | granice dostępnych okien |

Dostawców cyklicznych warto obsługiwać szablonem. Dostawca, który przyjeżdża co wtorek i piątek o tej samej porze, nie zakłada każdej wizyty osobno, a system rezerwuje okna w wybrane dni tygodnia na kolejne tygodnie z góry.
Moduł awizacji w Studio VSS.net pozwala dostawcy zarezerwować okno przez przeglądarkę lub aplikację na smartfonie, a magazynowi oglądać zajętość w kalendarzu ramp. Zasady tej sekcji opisuje serwis producenta na stronie planowanie dostaw do magazynu, a szczegóły modułu znajdują się w artykule o oprogramowaniu do zarządzania dostawami VSS.net.
Oprogramowanie do zarządzania dostawami - śledzenie i opóźnienia
Oprogramowanie do zarządzania dostawami klasyfikuje każdą dostawę względem okna. Dostawa bez przyjazdu po zakończeniu okna jest spóźniona, dostawa z przyjazdem poza oknem jest po terminie, a przyjazd przed oknem oznacza pojazd, który musi poczekać. Klasyfikację najlepiej liczyć w bazie. Wtedy raporty i ekran dyspozytora dostają ten sam wynik.
SELECT DeliveryId, PlannedFrom, PlannedTo, ArrivedAt,
CASE
WHEN ArrivedAt IS NULL AND SYSUTCDATETIME() > PlannedTo THEN N'spóźniona'
WHEN ArrivedAt > PlannedTo THEN N'po terminie'
WHEN ArrivedAt < PlannedFrom THEN N'przed oknem'
WHEN ArrivedAt IS NOT NULL THEN N'w oknie'
ELSE N'oczekiwana'
END AS Punctuality
FROM dbo.Delivery
WHERE PlannedFrom >= CAST(SYSUTCDATETIME() AS DATE);
| Klasyfikacja | Warunek | Reakcja logistyki |
|---|---|---|
| oczekiwana | okno jeszcze trwa, brak przyjazdu | brak, obserwacja |
| spóźniona | okno minęło, brak przyjazdu | kontakt z dostawcą i zwolnienie okna |
| po terminie | przyjazd po końcu okna | nowe okno lub obsługa w miarę możliwości rampy |
| przed oknem | przyjazd przed początkiem okna | oczekiwanie na placu lub wcześniejsza obsługa |
Wszystkie znaczniki czasu zapisuje się w UTC, a na czas lokalny przelicza się dopiero przy wyświetlaniu. Pozwala to uniknąć błędów przy zmianie czasu z letniego na zimowy, kiedy jedna godzina w nocy pojawia się dwa razy. Do przeliczenia służy klauzula AT TIME ZONE opisana w dokumentacji AT TIME ZONE w Microsoft Learn.
Po stronie przeglądarki ekran dyspozytora odświeża się przez zapytanie AJAX. Poniższy przykład w jQuery pobiera dzisiejsze dostawy co minutę i buduje wiersze tabeli przez metodę text(), dzięki czemu nazwa dostawcy z apostrofem lub znacznikiem nie zepsuje strony. Adres interfejsu jest przykładowy.
function refreshDeliveries() {
$.getJSON('/api/deliveries/today').done(function (rows) {
var $body = $('#deliveries tbody').empty();
$.each(rows, function (i, r) {
$('<tr>').addClass(r.punctuality)
.append($('<td>').text(r.supplier))
.append($('<td>').text(r.plannedFrom))
.append($('<td>').text(r.status))
.appendTo($body);
});
});
}
setInterval(refreshDeliveries, 60000);
Metoda opisana w dokumentacji jQuery.getJSON zwraca obiekt jqXHR z metodami done() i fail(), więc błąd sieci obsługuje się w osobnym wywołaniu. Powiadomienie o opóźnieniu trafia do kierowcy i dostawcy jako wiadomość SMS lub e-mail, a dyspozytor widzi pojazd na mapie placu opisanej w artykule o wizualizacji zajętości miejsc parkingowych.
Dane dostawy i dokument przyjęcia
Dostawa niesie dane, które magazyn wykorzysta przy przyjęciu: numer zamówienia, listę pozycji z ilościami i numery jednostek logistycznych. Jeżeli dostawca wysyła awizo wysyłki w formacie DESADV, program tworzy z niego awizację bez ręcznego przepisywania. Przy przyjęciu skaner porównuje odczytane numery SSCC z listą z awizacji, a wynik trafia do dokumentu PZ.
| Rozbieżność | Jak jest wykrywana | Typowa reakcja |
|---|---|---|
| Brak palety z listy | numer SSCC z awizacji nie został zeskanowany | przyjęcie niepełne i reklamacja ilościowa |
| Paleta spoza listy | zeskanowany numer nie występuje w awizacji | wstrzymanie jednostki do wyjaśnienia |
| Inny indeks towaru | kod na etykiecie różni się od pozycji zamówienia | odrzucenie pozycji lub korekta zamówienia |
| Uszkodzenie opakowania | uwaga magazyniera przy pozycji | protokół rozbieżności ze zdjęciem |

Obsługę przyjęcia po stronie magazynu opisuje artykuł o awizacjach dostaw do magazynu. Skanowanie na terminalu z systemem Android omawia tekst o aplikacji magazynowej na Androida. W obu miejscach zasada jest ta sama: rozbieżność zapisuje się w chwili wykrycia, a nie po zakończeniu rozładunku.
Zasada: przyjęcie zamyka się na liczbach ze skanera, a nie na liczbach z awizacji.
Osobnego traktowania wymaga pojazd bez awizacji. Ochrona rejestruje go jako wjazd nieawizowany, a logistyka decyduje, czy dla niego znajdzie się okno, czy dostawca ma poczekać. Taki wpis też trafia do historii, więc raport pokazuje, jaki odsetek ruchu omija kalendarz i którzy dostawcy robią to najczęściej.
Dostawy częściowe i pozycje zamówienia
Jedno zamówienie zakupu rzadko dociera jednym pojazdem. Dostawca dzieli ilość na kilka dostaw, część pozycji przychodzi z opóźnieniem, a część zostaje anulowana. Program musi więc łączyć dostawy z zamówieniem na poziomie pozycji, a nie nagłówka.
Saldo pozycji liczy się jako różnica między ilością zamówioną a sumą ilości przyjętych we wszystkich dostawach. Poniższe zapytanie zwraca pozycje z niedoborem i jest podstawą listy do ponaglenia dostawcy. Nazwy tabel są przykładowe.
SELECT ol.OrderId, ol.LineNo, ol.QtyOrdered,
ISNULL(SUM(dl.QtyReceived), 0) AS QtyReceived,
ol.QtyOrdered - ISNULL(SUM(dl.QtyReceived), 0) AS QtyOpen
FROM dbo.PurchaseOrderLine AS ol
LEFT JOIN dbo.DeliveryLine AS dl
ON dl.OrderId = ol.OrderId AND dl.LineNo = ol.LineNo
GROUP BY ol.OrderId, ol.LineNo, ol.QtyOrdered
HAVING ol.QtyOrdered > ISNULL(SUM(dl.QtyReceived), 0);
Złączenie LEFT JOIN zachowuje pozycje bez żadnej dostawy, które przy INNER JOIN zniknęłyby z wyniku. To najczęstszy błąd w raportach otwartych zamówień: pozycja, której dostawca jeszcze nie wysłał, wypada z zestawienia i wygląda jak zrealizowana.
Role i powiadomienia w programie do dostaw
Dostawca powinien widzieć tylko własne dostawy, a magazyn wszystkie. Uprawnienia przypisuje się rolom, a nie osobom, bo konta przewoźników zmieniają się częściej niż zakres ich pracy. Konfigurację ról opisuje artykuł o awizacjach VSS.net.
| Rola | Co widzi i robi | Powiadomienia |
|---|---|---|
| Dostawca lub przewoźnik | własne dostawy, zakładanie awizacji, zmiana okna do terminu granicznego | potwierdzenie rezerwacji, zmiana terminu |
| Logistyka | zatwierdzanie i przesuwanie okien we wszystkich dostawach | spóźnienia, dostawy bez awizacji |
| Ochrona | lista pojazdów oczekujących na wjazd, rejestracja przyjazdu | brak |
| Magazyn | dostawy przypisane do ramp oraz rejestracja początku i końca rozładunku | zbliżająca się dostawa |
Powiadomienia mają sens wtedy, gdy wynikają z reguły, a nie z każdego zdarzenia. Reguła typu spóźnienie ponad próg minut uruchamia wiadomość SMS lub e-mail do kierowcy i do logistyki, a próg ustala się w parametrach obiektu. Zbyt liczne komunikaty uczą odbiorców ich ignorowania.
Reguła: powiadomienie trafia do osoby, która może zareagować, a nie do wszystkich uczestników dostawy.
Wskaźniki terminowości dostaw
Program dostarcza wskaźniki dopiero wtedy, gdy zdarzenia mają znaczniki czasu. Podstawowym miernikiem jest odsetek dostaw przyjętych w oknie, a rozszerzeniem wskaźnik OTIF, czyli dostawa na czas i w pełnej ilości. Oba liczy się z dziennika zdarzeń i z dokumentów przyjęcia.
- Terminowość okna - udział dostaw z przyjazdem mieszczącym się w awizowanym oknie.
- Średni czas obsługi - różnica między rozpoczęciem a zakończeniem rozładunku na rampie.
- Obciążenie bram w tygodniu - liczba dostaw na bramę w kolejnych dniach, podstawa do przesuwania dostawców.
- Wjazdy nieawizowane - udział pojazdów, które ominęły kalendarz, liczony z historii wizyt.
Dwa czasy warto rozdzielać. Czas oczekiwania od wjazdu do przydzielenia rampy obciąża organizację placu, a czas rozładunku obciąża proces przyjęcia. Rozliczenie przestojów z przewoźnikiem opiera się na obu, dlatego znaczniki czasu z bramy i z rampy muszą pochodzić z zegara jednego serwera, a nie z urządzeń z rozjechanym czasem.
Wskaźniki mają sens per dostawca. Jedna średnia dla całego magazynu ukrywa dostawcę, który spóźnia się co tydzień, za średnią z dziesięciu punktualnych. Zestawienie miesięczne z listą dostawców posortowaną według odsetka spóźnień daje logistyce podstawę do rozmowy o zmianie okna lub umowy.
Integracja programu do dostaw z ERP i WMS
Program do zarządzania dostawami nie zastępuje ERP ani WMS, tylko łączy je w miejscu, gdzie żaden z nich nie sięga. ERP zna zamówienie, WMS zna przyjęcie, a pomiędzy nimi jest pojazd na placu. Awizacja może powstać z zamówienia zakupu albo z awizo wysyłki, a zatwierdzona trafia do WMS jako oczekujące zlecenie przyjęcia.
VSS.net wymienia dane z ERP przez API i EDI, a zmiany statusów w WMS, na przykład zakończenie rozładunku, wracają do awizacji i dalej do ERP. Mechanizm przedstawia artykuł o tym, jak VSS łączy się z WMS i ERP przy przyjęciach, a system magazynowy po drugiej stronie opisuje strona Studio WMS.net.
| Kierunek | Dane | Wyzwalacz |
|---|---|---|
| ERP do programu dostaw | zamówienie zakupu lub awizo ASN | zatwierdzenie zamówienia |
| Program dostaw do WMS | zatwierdzona awizacja z pozycjami | zatwierdzenie okna |
| WMS do programu dostaw | zakończenie rozładunku i przyjęcia | zamknięcie dokumentu PZ |
| Program dostaw do ERP | status i czas zdarzenia | każde zdarzenie dostawy |
Każdy komunikat powinien mieć identyfikator dokumentu źródłowego, bo ERP po przekroczeniu limitu czasu połączenia wysyła ten sam dokument ponownie. Unikalny indeks na parze system źródłowy i numer dokumentu zamienia drugie wysłanie w aktualizację istniejącej dostawy. Bez niego w kalendarzu pojawiają się duplikaty, które zajmują okna na rampach.
Druga część zabezpieczenia to ponawianie. Gdy interfejs ERP nie odpowiada, komunikaty zostają w kolejce, a łącznik ponawia próbę w rosnących odstępach, na przykład po minucie i po kwadransie. Po kilku nieudanych próbach komunikat trafia do listy błędów, którą przegląda administrator, a magazyn pracuje dalej na danych z ostatniej udanej wymiany.




