Klasyczna integracja z SAP zaczyna się od zdefiniowania interfejsów: dla każdej funkcji powstaje klasa, a do niej struktury i mapowanie pól. Przy kilku funkcjach to działa. Przy kilkudziesięciu każda zmiana parametru w SAP oznacza regenerację kodu i nowe wydanie aplikacji magazynowej.

Studio WMS.net wywołuje funkcje SAP dynamicznie, z kodu w JavaScript albo C#, przy użyciu narzędzia SAP Connector. Programista podaje nazwę funkcji i parametry, a wynik odbiera jako zbiór nazwanych wartości. Poniżej opisano ten model, sposób testowania połączenia, przejście z SOAP oraz zasady, które chronią dynamiczne wywołania przed nadużyciem. Dobór funkcji według procesu, w tym księgowanie i zatwierdzanie, zawiera osobny tekst o odczycie i wykonywaniu funkcji w systemie SAP.

Statyczne mapowanie interfejsu a wywołanie dynamiczne

Wywołanie dynamiczne przenosi opis funkcji z czasu kompilacji do czasu działania. Aplikacja nie zna z góry struktury parametrów, tylko pobiera ją z SAP tuż przed użyciem albo trzyma w pamięci podręcznej. Różnice widać najlepiej przy zmianie funkcji po stronie SAP i przy dodawaniu nowej.

CechaKlasy generowane z interfejsuWywołanie dynamiczne
opis funkcjizapisany w kodzie w czasie kompilacjiodczytany z SAP w czasie działania
nowy parametr w SAPregeneracja klas i nowe wydaniedopisanie pola w słowniku parametrów
kontrola typówprzez kompilatorprzez walidację metadanych przed wysłaniem
nowa funkcja w aplikacjinowa klasa i nowa metodanazwa funkcji na liście dozwolonych
ryzykowolniejsze zmianywywołanie niezamierzonej funkcji

Reguła: elastyczność wywołania dynamicznego wymaga listy dozwolonych funkcji. Aplikacja, która przyjmuje dowolną nazwę funkcji z żądania, pozwala każdemu użytkownikowi uruchomić w SAP wszystko, na co ma uprawnienia konto komunikacyjne.

Odczyt interfejsu funkcji w locie

SAP Connector pozwala odczytać parametry funkcji w locie: programista pobiera listę parametrów, wypełnia je danymi z aplikacji i wywołuje zdalną funkcję bez pisania rozbudowanej konfiguracji. Opis interfejsu zawiera dla każdego parametru cztery informacje, które aplikacja wykorzystuje do walidacji.

  • Nazwa i kierunek - wskazanie, czy parametr jest wejściowy, wyjściowy, zmieniany czy tabelą.
  • Typ i długość - typ danych ABAP oraz maksymalna długość pola, także dla pól struktur.
  • Obowiązkowość - informacja, czy funkcja odrzuci wywołanie bez tego parametru.
  • Wartość domyślna - wartość, którą SAP przyjmie po stronie serwera, gdy pole pozostanie puste.
Ilustracja do tematu dynamicznej integracji aplikacji magazynowej z systemem SAP
Aplikacja pobiera opis interfejsu funkcji, a potem wypełnia parametry i odbiera wynik bez klasy generowanej dla każdej funkcji.

Typy ABAP i typy po stronie klienta

Opis interfejsu podaje typ ABAP każdego pola, a konektor przekłada go na typ używany w aplikacji. Kilka par powtarza się w prawie każdej funkcji magazynowej i każda ma swoją pułapkę.

Typ ABAPZawartośćTyp po stronie C#Pułapka
CHARtekst o stałej długościstringspacje na końcu pola nie są częścią wartości
NUMCcyfry zapisane jako tekststringzera wiodące są istotne, więc nie wolno zamieniać na liczbę
DATSdata w postaci RRRRMMDDDateTimewartość 00000000 oznacza brak daty
QUAN, CURRliczba dziesiętna z jednostką lub walutądecimaltyp double wprowadza błędy zaokrągleń przy ilościach ułamkowych

Wywołanie z kodu w C# i JavaScript

Biblioteka obsługuje różne środowiska programistyczne. Programiści pracujący w C# integrują funkcje SAP z aplikacjami serwerowymi i desktopowymi, a piszący w JavaScript korzystają z nich w aplikacjach webowych. Przeglądarka nigdy nie łączy się z SAP bezpośrednio: żądanie idzie do serwera aplikacji, który trzyma dane logowania konta komunikacyjnego.

C# po stronie serwera

Warstwa serwerowa jest właściwym miejscem na listę dozwolonych funkcji oraz walidację parametrów z limitem czasu. Fragment poniżej pokazuje jej szkielet; interfejs ISapClient jest umowny i nie pochodzi z konkretnej biblioteki.

public sealed class SapGateway
{
    private static readonly HashSet<string> Allowed = new(StringComparer.OrdinalIgnoreCase)
    {
        "BAPI_MATERIAL_AVAILABILITY",
        "BAPI_WHSE_STOCK_GET_LIST"
    };

    private readonly ISapClient _client;

    public SapGateway(ISapClient client) => _client = client;

    public IReadOnlyDictionary<string, object> Call(
        string function, IDictionary<string, object> parameters, TimeSpan timeout)
    {
        if (!Allowed.Contains(function))
            throw new InvalidOperationException("Funkcja spoza listy dozwolonych: " + function);

        var meta = _client.DescribeFunction(function);   // Import, Export, Changing, Tables
        foreach (var name in parameters.Keys)
        {
            if (!meta.HasParameter(name))
                throw new ArgumentException("Nieznany parametr: " + name);
        }

        using var cts = new CancellationTokenSource(timeout);
        return _client.Invoke(function, parameters, cts.Token);
    }
}

JavaScript po stronie przeglądarki

Kod w przeglądarce wysyła żądanie asynchroniczne, więc ekran operatora nie blokuje się na czas odpowiedzi SAP. Wywołanie Fetch API zwraca obietnicę, a kod obsługi sprawdza status HTTP i komunikaty typu E oraz A z tabeli RETURN. Adres punktu końcowego w przykładzie jest umowny.

async function readAvailability(material, plant) {
  const response = await fetch('/api/sap/call', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      function: 'BAPI_MATERIAL_AVAILABILITY',
      parameters: { MATERIAL: material, PLANT: plant }
    })
  });

  if (!response.ok) {
    throw new Error('Wywołanie SAP nie powiodło się: ' + response.status);
  }

  const result = await response.json();
  const errors = (result.RETURN || []).filter(m => m.TYPE === 'E' || m.TYPE === 'A');
  return { result, errors };
}

Przy operacjach zapisu dodaje się jeszcze identyfikator operacji generowany w przeglądarce, żeby podwójne kliknięcie albo ponowienie po utracie sieci nie wysłało tego samego ruchu dwa razy. Serwer odrzuca powtórzony identyfikator, zanim żądanie dotrze do SAP.

Odpowiedź może zawierać błędy na dwóch poziomach i aplikacja rozróżnia je od razu. Błąd techniczny, na przykład brak połączenia, przekroczenie limitu czasu albo nieistniejąca funkcja, kończy się wyjątkiem i pozwala ponowić wywołanie. Błąd biznesowy, na przykład brak materiału w SAP, przychodzi w tabeli RETURN jako komunikat typu E i wymaga poprawy danych, a ponowienie nic nie da.

Testowanie połączenia i autoryzacji w SAP RFC Connector

Konfiguracja połączenia najczęściej zawodzi już na etapie testowania: od błędnych danych logowania po nieprawidłową trasę sieciową. Wbudowany test w SAP RFC Connector sprawdza adres serwera i port, a także identyfikator użytkownika z hasłem oraz pośrednictwo przez SapRouter; przy błędzie wskazuje przyczynę bez sięgania do zewnętrznych logów. Pełną listę parametrów, wraz z konfiguracją middleware, zawiera strona o połączeniu aplikacji z systemem SAP.

TestCo sprawdzaTypowa przyczyna niepowodzenia
adres serwera i portosiągalność serwera aplikacyjnego SAP z serwera WMSzapora lub port z numerem innej instancji (33NN)
dane logowaniakonto komunikacyjne oraz mandant z językiem sesjinieprawidłowe hasło albo literówka w numerze mandanta
SapRouterpoprawność ciągu trasy przez routerbrak wpisu na liście dozwolonych połączeń routera
autoryzacja funkcjiprawo do wywołania danej funkcji i strukturyrola bez obiektu S_RFC dla grupy funkcji

Po nawiązaniu połączenia sprawdza się dostęp do funkcji i struktur. Gdy konto nie ma uprawnień, komunikat pojawia się od razu, a błąd wychodzi na jaw na etapie wdrożenia, a nie po uruchomieniu produkcyjnym. Szczegółowe dane techniczne narzędzia opisuje strona SAP Connector w serwisie produktowym.

Konto komunikacyjne

Integracja korzysta z osobnego konta z rolą ograniczoną do wywoływanych funkcji. Konto osobiste administratora nie nadaje się do tego celu, bo ślad audytowy w SAP przestaje odróżniać wywołania aplikacji od pracy człowieka.

Konwersja zapytań SOAP na wywołania SAP Connector

Wiele firm nadal komunikuje się z SAP przez SOAP. Protokół ma swoje zalety, ale każda zmiana wywołania wymaga pracy z komunikatem XML i definicją usługi. Wywołanie przez konektor redukuje tę pracę do nazwy funkcji i słownika parametrów.

Co upraszcza się po przejściu z SOAP

Komunikat SOAP ma postać koperty XML z nagłówkiem i treścią, opisanej kontraktem WSDL, zgodnie ze specyfikacją SOAP 1.2 organizacji W3C. Programista buduje ją ręcznie albo generuje klasy z WSDL. Konektor zastępuje to wywołaniem metody z parametrami i zwraca odpowiedź bez pisania kodu obsługującego niskopoziomowe szczegóły protokołu.

ElementWywołanie przez SOAPWywołanie przez SAP Connector
komunikatkoperta XML z nagłówkiem i treściąnazwa funkcji i słownik parametrów
kontraktplik WSDL wymagający aktualizacji przy zmianieopis interfejsu funkcji pobierany z SAP
typy danychschemat XML mapowany na typy klientatypy ABAP mapowane na typy .NET lub JavaScript
diagnostykaodpowiedź typu Faulttabela RETURN oraz wyjątek biblioteki

Migracja etapami bez przestoju aplikacji

Przejście nie wymaga jednorazowej przebudowy architektury. Firma przenosi wywołania pojedynczo i porównuje wyniki z dotychczasową ścieżką, aż przestaje znajdować różnice.

  • Inwentarz wywołań - lista funkcji wywoływanych dziś przez SOAP wraz z częstością użycia.
  • Pierwsza funkcja - przepisanie jednej funkcji odczytowej, bo błąd odczytu nie zmienia danych w SAP.
  • Praca równoległa - wysyłanie żądania obiema ścieżkami i porównanie odpowiedzi w dzienniku.
  • Wyłączenie SOAP - wycofanie starej ścieżki dla funkcji, dla której wyniki zgadzały się przez ustalony okres.

Reguła: funkcje zapisujące przenosi się dopiero po odczytowych, a każde wywołanie zapisujące dostaje identyfikator operacji, żeby praca równoległa nie utworzyła dwóch dokumentów.

Funkcje z poziomu WMS a funkcje wywoływane bezpośrednio w SAP

Przed wyborem sposobu integracji rozstrzyga się, które czynności wykonuje się w magazynie, a które pozostają w SAP. Zestawienie porządkuje najczęstsze przypadki.

Obszar działaniaZ poziomu WMSBezpośrednio w SAP
aktualizacja stanów magazynowychautomatyczna po każdej operacji na haliwymaga ręcznego wglądu w moduł MM
wywołanie funkcji RFCdynamiczne, z kodu aplikacjiprzez transakcje i raporty ABAP
dokumenty magazynowegenerowane w interfejsie WMSprzez odrębne transakcje SAP
test połączenia i autoryzacjiwbudowany mechanizm SAP RFC Connectorkonfiguracja po stronie administratora SAP

Wynik operacji na hali trafia do SAP od razu po jej zamknięciu, więc stany magazynowe w obu systemach zgadzają się bez okresowej synchronizacji wsadowej. Dokumenty powstają w miejscu, gdzie pracuje operator, a operacje magazynowe nie wymagają przełączania się na ekrany SAP GUI.

Przykład wywołania funkcji odczytowej w praktyce

Poniższy scenariusz pokazuje przebieg od strony programisty, który pracuje przy wdrożeniu systemu WMS zintegrowanego z SAP. Aplikacja WMS wywołuje funkcję RFC, która zwraca stan magazynowy indeksu materiałowego.

Przykład

Kod w JavaScript ustawia parametry wejściowe (numer materiału i magazyn), przekazuje je do SAP Connector, a potem odczytuje z odpowiedzi bieżący stan wraz z jednostką miary i lokalizacją składowania. Nie powstaje dodatkowa warstwa pośrednia ani ręczne mapowanie struktur RFC.

Ilustracja do tematu integracji programu magazynowego z systemem SAP i wymiany danych w obu kierunkach
Odczyt i potwierdzenie ruchu korzystają z tego samego mechanizmu wywołania; różni je funkcja i zatwierdzenie zmian.

Operator na terminalu czeka na odpowiedź, więc odczyt wywołuje się synchronicznie i z krótkim limitem czasu. Zapis, który może potrwać dłużej, warto zakolejkować w bazie WMS i potwierdzać asynchronicznie, a ekran operatora pokazuje wtedy status oczekiwania zamiast blokować pracę. Podział na te dwa tryby ustala się osobno dla każdej funkcji.

Ten sam mechanizm obsługuje wywołanie zwrotne: potwierdzenie wydania towaru w SAP zaraz po zamknięciu zlecenia w zintegrowanym systemie magazynowym. Obie strony pracują na tych samych, aktualnych danych, bez opóźnień wynikających z paczkowej synchronizacji. Warianty pośrednie, na przykład kolejkę IDoc dla dużych wolumenów, porównuje tekst o integracji WMS z SAP, a architekturę z pośrednikami opisuje strona integracja z SAP.

Utrzymanie wywołań dynamicznych po zmianach w SAP

Wywołanie dynamiczne zdejmuje z programisty regenerację klas, ale nie zdejmuje odpowiedzialności za zmiany po stronie SAP. Aktualizacja wersji albo modyfikacja funkcji przez konsultanta zmienia interfejs bez ostrzeżenia dla aplikacji, więc potrzebne są cztery mechanizmy kontrolne, które zestawia poniższa lista.

  • Pamięć podręczna metadanych - opis interfejsu odświeżany po zmianie wersji SAP albo według harmonogramu, a nie przy każdym wywołaniu.
  • Dziennik wywołań - nazwa funkcji oraz czas odpowiedzi, a także typ komunikatu RETURN, dostępne do analizy po błędzie.
  • Limity czasu i sesji - ograniczenie liczby równoległych sesji RFC oraz czasu oczekiwania na odpowiedź.
  • Test po aktualizacji - zestaw wywołań kontrolnych uruchamiany na środowisku testowym po każdej zmianie w SAP.

Wraz z dziennikiem warto śledzić rozkład czasów odpowiedzi, bo wolna funkcja odczytowa bywa pierwszym sygnałem, że po stronie SAP pojawiła się blokada albo brakuje indeksu. Przy przejściu na nowszą wersję SAP część funkcji bywa oznaczona jako przestarzała albo zastąpiona inną, dlatego zestaw wywołań kontrolnych obejmuje każdą funkcję z listy dozwolonych. Jeśli aplikacja ma obsługiwać wiele systemów SAP, każde połączenie dostaje własny profil, a środowisko testowe różni się od produkcyjnego numerem mandanta. Szerszy kontekst rozwiązań integracyjnych, także dla aplikacji spoza magazynu, opisuje strona o integracji aplikacji webowych.