Kartoteka ciągników i pojazdów własnych

Rola Magazyn w VSS.net ma osobną pozycję menu o nazwie Transport wewnętrzny. Otwiera ona listę „Kartoteki ciągników”, czyli rejestr pojazdów, które poruszają się po terenie zakładu i obsługują naczepy w obrębie placu. Jeden wiersz opisuje jeden ciągnik albo wózek. Polecenie Dopisz zakłada nowy wpis, a Edycja poprawia istniejący.

Według opisu produktu moduł integruje się z awizacjami i naczepami, a także z rampami, więc kartoteka nie stoi obok reszty systemu. Pozostałe słowniki roli, w tym Naczepy i Rampy, opisuje artykuł o kartotekach w systemie VSS.net. Producent publikuje też stronę o samym module transport wewnętrzny.

Kolumna kartotekiCo przechowuje i po co
Aktywneflaga wyłączająca pojazd z użycia bez kasowania wiersza
Nazwa ciągnikamarka i model, po których dyspozytor rozpoznaje sprzęt
Numer rejestracyjnytablica pojazdu, podstawowy identyfikator w rejestrze
Numer SAPnumer nadany w systemie klasy ERP, potrzebny do powiązania danych
Nr ewidencyjny i kod kreskowynumer wewnętrzny zakładu oraz kod do skanowania
Magazyn, Zapisał, Data zapisuprzypisanie do magazynu i ślad audytowy: kto oraz kiedy dodał wpis

Reguła: pojazd wycofany z użycia oznacza się jako nieaktywny, a nie usuwa, bo historia transportów nadal odwołuje się do jego wiersza.

Unikalność numeru rejestracyjnego w bazie

Kartoteka pojazdów wymaga jednej dyscypliny po stronie bazy: numer rejestracyjny nie może się powtarzać wśród pojazdów aktywnych. Zwykły indeks unikalny blokowałby jednak ponowne użycie tablicy po sprzedaży pojazdu, dlatego stosuje się indeks filtrowany. Przykład poniżej używa poglądowych nazw i nie odwzorowuje schematu VSS.net.

CREATE TABLE dbo.YardVehicle (
    VehicleId     int IDENTITY PRIMARY KEY,
    Name          nvarchar(100) NOT NULL,
    PlateNo       nvarchar(20)  NOT NULL,
    SapNo         nvarchar(30)  NULL,
    Barcode       varchar(40)   NULL,
    IsActive      bit           NOT NULL DEFAULT 1,
    CreatedBy     nvarchar(50)  NOT NULL,
    CreatedAt     datetime2(0)  NOT NULL DEFAULT SYSUTCDATETIME()
);

-- tablica unikalna tylko wśród pojazdów aktywnych
CREATE UNIQUE INDEX UX_YardVehicle_Plate_Active
    ON dbo.YardVehicle (PlateNo)
    WHERE IsActive = 1;

-- kod kreskowy unikalny, jeżeli został nadany
CREATE UNIQUE INDEX UX_YardVehicle_Barcode
    ON dbo.YardVehicle (Barcode)
    WHERE Barcode IS NOT NULL;

Składnię i ograniczenia takich indeksów opisuje dokumentacja indeksów filtrowanych w Microsoft Learn. Błąd naruszenia unikalności warto przechwycić w aplikacji i pokazać operatorowi komunikat z nazwą kolidującego pojazdu, zamiast ogólnego błędu bazy.

Ślad zmian w kartotece pojazdów

Kolumny Zapisał i Data zapisu dokumentują pierwszy wpis, ale nie mówią, kto później zmienił numer rejestracyjny albo przepiął ciągnik do innego magazynu. Do pełnej historii zmian nadają się tabele czasowe z wersjonowaniem systemowym, dostępne w SQL Server od wersji 2016. Baza sama archiwizuje poprzednie wersje wierszy, a zapytanie z klauzulą FOR SYSTEM_TIME odtwarza stan kartoteki z wybranej daty. Mechanizm opisuje dokumentacja tabel czasowych w Microsoft Learn.

Przy niewielkiej flocie rozrost tabeli historii jest znikomy, więc koszt takiego rozwiązania sprowadza się do miejsca na dysku. Zysk jest wyraźny przy sporze z przewoźnikiem albo przy audycie: można wykazać, jaki pojazd był przypisany do wizyty w danym dniu, nawet jeśli kartoteka zmieniła się później.

Lista transportów i wydruk CMR

Pozycja Transporty zawiera listę dostaw i odbiorów wraz z numerem awizacji i tablicą rejestracyjną oraz z przypisaną rampą. Wyniki filtruje się po datach oraz kontrahentach, a także po typie transportu. Eksport do pliku wspiera raportowanie i audyty, a polecenia Podgląd i Wydruk CMR dają szybki dostęp do szczegółów oraz do dokumentu przewozowego.

Grupa kolumnKolumny widoku tabeli
Identyfikacja wizytyKat., Status, Numer Load Plan
CzasDzień, Od, Do
Strony transportuKontrahent, Przewoźnik / kierowca (telefon)
Towar i rampaAsortyment, Rampa
NośnikiPalety IN, Palety OUT, Puste palety IN, Puste palety OUT

Cztery pola paletowe rozdzielają nośniki przyjęte i wydane w ramach wizyty. Puste palety śledzi się osobno, bo mają inny obieg rozliczeniowy niż palety z towarem. Saldo takich nośników opisuje artykuł o ewidencji palet. Zestawienie bieżących transportów wygląda podobnie, ale dotyczy wyłącznie wizyt w toku, a poniższy zrzut pokazuje je z kolumnami czasu przyjazdu i wjazdu oraz startu obsługi.

Zestawienie W trakcie realizacji w VSS.net ze statusami bramy i magazynu, godzinami przyjazdu i wjazdu oraz poleceniem Wydruk CMR
Zestawienie transportów w toku: statusy i numer Load Plan, godziny przyjazdu z wjazdem oraz polecenia Podgląd i Wydruk CMR.
Status na zestawieniuCo oznacza dla przebiegu wizyty
Brama - potwierdzenie przybyciakierowca zgłosił się na bramie, ale kolumna Wjechał jest jeszcze pusta
Brama - wjazd na teren zakładupojazd został wpuszczony, a kolumna Magazyn START pokazuje początek obsługi
Magazyn - oczekujepojazd stoi na terenie i czeka na rozpoczęcie rozładunku albo załadunku

Czas oczekiwania na terenie zakładu

Trzy kolumny czasu z zestawienia wystarczą do policzenia, gdzie pojazd traci minuty. Kolumny Przyjechał i Wjechał opisują pracę bramy, a kolumny Wjechał i Magazyn START opisują kolejkę do rampy. Zapytanie poniżej pokazuje ten rachunek na poglądowej tabeli transportów.

SELECT  v.PlateNo,
        DATEDIFF(MINUTE, t.ArrivedAt, t.GateInAt)         AS MinAtGate,
        DATEDIFF(MINUTE, t.GateInAt,  t.WarehouseStartAt) AS MinOnYard
FROM    dbo.YardTransport AS t
JOIN    dbo.YardVehicle   AS v ON v.VehicleId = t.VehicleId
WHERE   t.PlannedDay = CAST(SYSDATETIME() AS date)
  AND   t.WarehouseStartAt IS NOT NULL
ORDER BY MinOnYard DESC;

Sortowanie malejące wysuwa na górę wizyty z najdłuższym czekaniem na placu. Jeżeli ten sam pojazd pojawia się tam codziennie, przyczyną bywa niedopasowane okno czasowe, a nie praca magazynu. Zasady doboru okien opisuje artykuł o kalendarzach w VSS.net.

Kto co widzi w module transportów

Ta sama lista transportów służy kilku grupom użytkowników, ale każda z nich potrzebuje innego wycinka danych. Magazynier sprawdza status pojazdu i kolejność awizacji, operator wózka planuje rozładunki według ramp, a spedytor śledzi wyłącznie własne zlecenia. Dział IT patrzy na punkty integracji, bo od nich zależy wymiana danych z systemami zewnętrznymi.

RolaCo widzi
Magazynierstatus pojazdu z przypisaną rampą oraz kolejność awizacji na dany dzień
Operator wózka widłowegonumer rejestracyjny i rampę oraz planowaną godzinę rozładunku
Spedytor lub przewoźnikhistorię własnych awizacji wraz ze statusem realizacji oraz dokumentami CMR
Dział ITpunkty integracji API z systemami ERP i TMS

Podział odpowiada logice kont opisanej w artykule o module Administrator. Administrator nadaje zakres widoczności, więc przewoźnik nie zobaczy danych konkurencyjnej firmy, nawet gdy obie korzystają z tego samego magazynu. Wizyty bez awizacji trafiają do osobnej listy opisanej w artykule o transporcie nieawizowanym.

Historia awizacji dla spedytorów i przewoźników

Sekcja Historia wyświetla zakończone albo przetworzone awizacje firm transportowych i spedycyjnych. Użytkownik widzi tylko własne dane. Kolumny opisują numer planu załadunku i datę transportu, kontrahenta z przewoźnikiem oraz asortyment z lokalizacją i statusem realizacji. Wpisy można filtrować i sortować według dat czy numerów zamówień. Dane trafiają do plików Excel lub PDF, co ułatwia raporty i dokumentowanie przebiegu transportów.

Tabela Historia transportów w VSS.net z kolumnami czasu i kontrahenta oraz danymi kierowcy i filtrami w nagłówku
Historia transportów przewoźnika: kolumny daty i kontrahenta oraz dane kierowcy z filtrami w wierszu nagłówka.

Historia służy też do rozmów z przewoźnikami o jakości współpracy. Powtarzające się opóźnienia albo nieawizowane przyjazdy łatwo zestawić w jednym raporcie. Magazynier planujący obsadę na kolejny tydzień korzysta z tych zestawień, żeby przewidzieć obciążenie ramp w poszczególnych dniach. Szerszy kontekst funkcjonalny opisuje artykuł o module awizacji VSS.net.

Ograniczenie widoku do własnych danych

Zasadę „widzę tylko swoje” najpewniej egzekwuje się w bazie, a nie w interfejsie. Funkcja tabelaryczna z parametrem identyfikatora przewoźnika zwraca wyłącznie jego wiersze, a aplikacja przekazuje identyfikator z sesji zalogowanego konta. Przykład jest poglądowy i nie opisuje implementacji VSS.net.

CREATE FUNCTION dbo.fn_CarrierHistory (@CarrierId int)
RETURNS TABLE
AS
RETURN
    SELECT  t.LoadPlanNo, t.PlannedDay, t.CustomerName,
            t.CarrierName, t.Assortment, t.Status
    FROM    dbo.YardTransport AS t
    WHERE   t.CarrierId = @CarrierId
      AND   t.Status IN (N'Zakończona', N'Przetworzona');

Identyfikator pochodzi zawsze z sesji, nigdy z parametru zapytania przesłanego przez przeglądarkę. W przeciwnym razie przewoźnik mógłby podmienić wartość i odczytać cudzą historię.

Zaplanowane na dzisiaj i kalendarz zadań

Pozycja Zaplanowane na dzisiaj otwiera listę transportów przypisanych do bieżącej daty. Wiersz podaje numer rejestracyjny i typ operacji, kontrahenta z rampą oraz planowaną godzinę. Na początku zmiany magazynier ocenia jednym spojrzeniem, ile awizacji czeka na obsługę i czy wystarczy rąk do rozładunku w godzinach szczytu. Operator wózka dostaje z kolei kolejność zadań przypisanych do konkretnej rampy, bez telefonicznego ustalania priorytetów.

Z listy wysyła się powiadomienia SMS oraz e-mail i dodaje uwagi z załącznikami do konkretnych awizacji. Kalendarz ma widok dzienny i agendę, a także oś czasu. Wybór zależy od pytania, na które szuka się odpowiedzi.

Widok Agenda kalendarza awizacji w VSS.net z listą wizyt uporządkowaną według godzin i kolorami kontrahentów
Widok Agenda kalendarza: wizyty w kolejności godzin z oznaczeniem kolorystycznym kontrahentów.

Powiadomienia stanowią osobny temat dla programisty. Wysyłkę SMS realizuje się zwykle przez kolejkę w bazie, a nie przez wywołanie bramki operatora w trakcie zapisu awizacji. Zapis kończy się wtedy szybko, a awaria operatora nie cofa rezerwacji. Wzorzec kolejki opisuje artykuł o systemie VSS.net.

Indeks pod listę zadań na dziś

Lista zadań na bieżącą datę jest najczęściej odświeżanym zapytaniem w hali, więc powinna obsługiwać się z jednego indeksu. Indeks nieklastrowy z kluczem na dacie planowanej i statusie oraz z kolumnami dołączonymi INCLUDE pokrywa zapytanie bez odczytu tabeli głównej. Kolejność kolumn w kluczu indeksu ma znaczenie: data odcina zakres, a status zawęża wynik wewnątrz dnia.

CREATE NONCLUSTERED INDEX IX_YardTransport_PlannedDay
    ON dbo.YardTransport (PlannedDay, Status)
    INCLUDE (VehicleId, CustomerName, RampCode, PlannedFrom);

SELECT  t.PlannedFrom, t.RampCode, t.CustomerName, t.Status
FROM    dbo.YardTransport AS t
WHERE   t.PlannedDay = CAST(SYSDATETIME() AS date)
  AND   t.Status IN (N'Awizowany', N'Oczekuje')
ORDER BY t.PlannedFrom;

Plan wykonania takiego zapytania powinien pokazać operator Index Seek bez wyszukiwania kluczy. Jeżeli w planie pojawia się Key Lookup, do indeksu brakuje kolumny, którą lista wyświetla.

Moduł API i wymiana danych z systemami zewnętrznymi

Interfejs API pozwala wymieniać dane awizacji i harmonogramów oraz statusy transportów z systemami ERP i TMS, a także z WMS i CRM. Obsługuje też aplikacje przewoźników. Komunikacja odbywa się w technologii REST API, a szczegółowy kontrakt punktów końcowych opisuje dokumentacja, na przykład w formacie Swagger. Przewoźnik może przez API wysyłać awizacje i pobierać stan realizacji, a także rezerwować okna czasowe bez logowania do panelu.

Po stronie kodu wywołanie sprowadza się do zapytania HTTP z nagłówkiem uwierzytelniającym i obsługą kodu odpowiedzi. Tabela poniżej zbiera typowy układ operacji w interfejsach REST, a kody odpowiedzi ilustrują konwencję, nie kontrakt VSS.net. Poniższy fragment C# ilustruje ogólny wzorzec pobrania listy awizacji z dnia. Adres i nazwy pól są przykładowe i nie stanowią specyfikacji API VSS.net.

using var client = new HttpClient
{
    BaseAddress = new Uri("https://example.com/api/")
};
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", token);

HttpResponseMessage response =
    await client.GetAsync("appointments?date=2026-09-30");
response.EnsureSuccessStatusCode();

string json = await response.Content.ReadAsStringAsync();

Klasę opisuje dokumentacja HttpClient w Microsoft Learn. W aplikacji produkcyjnej klient powinien żyć dłużej niż pojedyncze wywołanie, bo tworzenie go przy każdym żądaniu wyczerpuje gniazda sieciowe. Więcej o integracji z magazynem opisuje artykuł o łączeniu VSS z WMS i ERP przy przyjęciach.

Operacja REST (wzorzec)Typowe użycie i kod odpowiedzi
GET na kolekcji awizacjipobranie listy z filtrem daty, odpowiedź 200
POST na kolekcji awizacjizałożenie nowej awizacji, odpowiedź 201 z adresem zasobu
PUT lub PATCH na awizacjizmiana terminu albo danych kierowcy, odpowiedź 200 lub 409 przy zajętym oknie
DELETE na awizacjianulowanie wizyty, odpowiedź 204

Reguła: zanim integracja API zacznie zasilać TMS lub ERP, trzeba uporządkować kartoteki pojazdów i ramp, bo błędne dane źródłowe trafią do wszystkich połączonych systemów.

Moduł dla spedycji i przewoźników

Dla spedycji i przewoźników system udostępnia tworzenie awizacji i ustalanie godzin przyjazdu, a także przypisywanie ramp. Przewoźnicy przeglądają kalendarz zadań i potwierdzają realizację. Uzupełniają też dane pojazdów oraz kierowców. Dostęp ogranicza się do własnych danych, co chroni informacje handlowe pozostałych kontrahentów. Strona Spedycja i przewoźnicy opisuje moduł od strony producenta.

Moduł domyka proces, który zaczyna się w kartotece pojazdów, a kończy na zamknięciu awizacji. Kierowca wjeżdża na teren, obsługa rampy zamyka wizytę, a wpis trafia do historii. Ten sam wątek z perspektywy floty własnej rozwija artykuł o transporcie wewnętrznym w VSS.net. Planowanie dostaw, z którego wynikają okna dla przewoźników, opisuje tekst o planowaniu dostaw do magazynu.

Statusy transportów i ich zmiany, także zbiorcze, porządkuje artykuł o awizacji transportu, a platformę jako całość przedstawia strona o VSS.net.