API skryptów

Pobieranie danych wejściowych

Poniżej znajduje się przykładowy kod, który pokazuje, w jaki sposób można korzystać z wejścia oraz jak należy zwrócić dane.

function callService(context){
  const firstArgument = context.getFirstParameter("firstArgument");
  const firstArgumentList = context.getParameters("firstArgument");
  const keySet = context.getInputParameters().keySet();
  const comboboxLabel = context.getData("GesCombobox1","label");
  const result = "service script constant " + firstArgument + " list value: " + firstArgumentList + " and first from list: " + firstArgumentList.get(0) + " keySet " + keySet;
  return [{'output': result}];
}

Wejście do Skrypt serwisu

Jako wejście (parametr context w powyższym kodzie) znajduje się obiekt, który udostępnia następujące metody:

  • List<String> getParameters(final String name); - pobiera konkretną listę z mapy danych wejściowych,

  • String getFirstParameter(final String name); - pobiera pierwszy element z konkretnej listy z mapy danych wejściowych lub zwraca wartość "null",

  • String getFirstParameter(final String name, final String defaultIfEmpty); - pobiera pierwszy element z konkretnej listy z mapy danych wejściowych, a jeśli go nie ma lub jest pusty to zwraca wartość "defaultIfEmpty",

  • Map<String, List<String>> getInputParameters(); - zwraca całą mapę danych wejściowych, którą przechowuje,

  • String isVisible(final String id); - pobiera informację, czy komponent o wskazanym id jest widoczny,

  • String getValue(final String id); - pobiera wartość komponentu (również zmiennej sesyjnej) o wskazanym id,

  • void setValue(final String componentId, final String value); - ustawia wartość value komponentu o wskazanym componentId. Zasada podawania componentId jest taka sama jak przy getValue. Wywołując skrypt wewnątrz komponentu złożonego, w celu ustawienia wartości komponentu / zmiennej sesyjnej osadzonej w tym samym komponencie, należy componentId prefiksować znakiem @

UWAGA! Próba wykonania setValue na komponencie, który nasłuchuje na inny komponent lub na komponencie, na którego nasłuchują inne komponenty, poskutkuje rzuceniem wyjątku.

  • String getData(final String id, final String attribute); - pobiera wartość konkretnego atrybutu dla komponentu o wskazanym id

UWAGA! Możliwe do pobrania atrybuty są zależne od komponentu.

  • List<Map<String, String>> callService(String name, Map<String, List<String>> input); - umożliwia wołanie ServiceProxy,

  • ValidatorOutput validate(String name, Map<String, List<String>> input); - umożliwia wołanie walidatora

Wyjście ze Skrypt serwisu

Wynik wykonania skryptu możemy zwrócić na dwa sposoby:

  1. Lista map - tablica obiektów na wyjściu jest parsowana na listę map, po czym zostaje przetwarzana w standardowy sposób.

  2. Pojedyncza mapa - zwrotka zostaje opakowana jako lista jednoelementowa, po czym przetwarzana jest w standardowy sposób.

Wyjście z skryptu z przykładową listą:

  return [{'output': 'result1'},{'output': 'result2'},{'output': 'result3'}];

Logowanie

Logowanie danych wejściowych jest automatyczne

Logowanie ręczne powinno być zgodne z opisem w Logowanie w ScriptCode

function callService(context) {
    const sessionVariable = context.getValue("@sessionVar");
    Logger.info('Wartosc zmiennej sesyjnej [arg1={}, arg2={}]', nonsensitive('arg1 nonsensitive test'), sessionVariable);
    return [{'sessionVar':sessionVariable }];
}

Rzucanie wyjątków biznesowych

Istnieje możliwość rzucenia wyjątku biznesowego z poziomu skryptu. Przykładowy kod:

function callService(context) {
    const firstArgument = context.getFirstParameter('firstArgument');
    let builder =  context.getErrorPageDefinitionBuilder();
    builder.body('body');
    context.throwBusinessException(builder);
    return [{'firstOutput': firstArgument}];
}

Możliwe metody, które można wywołać na obiekcie context:

context.getErrorPageDefinitionBuilder() .body(string) .styleName(string) .msg(string) .pageTitle(string) .pageTitleKey(string) .sidebarSlot2TextContent(string) .sidebarSlot2(string) .sidebarSlot1TextContent(string) .sidebarSlot1(string) .retryButtonAvailable(string) .retryButtonAvailable(boolean) .logobarTitle(string) .logobarTitleKey(string) .logobarDescription(string) .bodyTextContent(string) .parameter(String key, String value) .cause(Throwable cause) .redirectUrl(string) .redirectDelayInMillis(string) .businessFormIdentifier(string)

Zapis danych tymczasowych

Możliwe jest zapisanie pewnych danych pomiędzy wywołaniami serwisu. Służy do tego obiekt registry.

Możliwe metody, które można wywołać na obiekcie registry:

  • save(namespace, id, data) - zapis danych

  • saveVersion(namespace, id, data, version) - zapis danych z weryfikacją wersji. Jeśli pole version jest nieustawione lub jest puste - zapis bez weryfikacji. Jeśli wartość pola version nie zgadza się z aktualną wersją przechowywanych danych, wniosek zakończy się z błędem.

  • get(namespace, id) - pobranie danych

  • getVersion(namespace, id) - pobranie obiektu { data: 'zapisane dane', version: 'aktualna wersja danych' }

  • delete(namespace, id) - usuwanie danych.

Dane przechowywane są w przestrzeniach nazw (namespace w metodach) ustalanych przez administratorów. Każdej przestrzeni można ustawić czas życia danych. Domyślnie jest to 90 dni. Podanie tego samego id w ramach kilku wywołań zapisu powoduje aktualizację danych powiązanych z danym id. Wersja danych to unikalny identyfikator generowany przy każdym zapisie danych.

Obiekt to poprawnego działania wymaga działającej aplikacji EximeeRegistry.

Przykłady:

context.registry().save('test', '123123', 'dane tymczasowe');
context.registry().get('test', '123123'); // zwróci 'dane tymczasowe'
const item = context.registry().getVersion('test', '123123'); // zwróci obiekt {data,version}
context.registry().saveVersion('test','123123', 'nowe dane', item.version); // wersja zgodna zapis się uda
context.registry().saveVersion('test','123123', 'nowe dane', 'jakaś inna wersja'); // wersja niezgodna zapis się nie uda
context.registry().delete('test','123123');

Pobieranie kontekstu zalogowanego użytkownika

Istnieje możliwość pobrania kontekstu aktualnie zalogowanego użytkownika, który uzupełnia wniosek.

API
/**
 * Kontekst security formularza, zawierające dane dotyczące bezpieczeństwa. Po realizacji tego tematu będzie zawierać tożsamość aktualnego użytkownika.
 */
interface SecurityContext {
  /**
   * Tożsamość aktualnego użytkownika
   */
  getCurrentUser(): Identity | null;
}
 
interface ScriptApi {
  // ...
  /**
   * Pobranie aktualnego kontekstu użytkownika
   */
  getSecurityContext(): SecurityContext;
}
 
/**
 * Reprezentacja roli użytkownika
 */
interface Role {
  name: string;
}
 
/**
 * Reprezentacja tożsamości użytkownika
 */
interface Identity {
  /**
   * Identyfikator tożsamości użytkownika. W kontekście tego tematu zawsze 'current'
   */
  id: string;
  /**
   * Nazwa użytkownika. W kontekście tego tematu jest to SKP pracownika.
   */
  username?: string;
  /**
   * Role użytkownika
   */                              
  roles?: Role[];
 
  /**
   * Imię użytkownika
   */
  firstName?: string;
 
  /**
   * Nazwisko użytkownika
   */
  lastName?: string;
}

Podczas uruchomienia skryptu bez zalogowanego kontekstu użytkownika metoda context.getSecurityContext() zwróci wartość null

Przykładowe użycie w skrypcie kontekstu użytkownika

function callService(context) {
    context.getSecurityContext().getCurrentUser();               
  // return: { id: 'current', username: '100001', firstName: 'Jan', lastName: 'Kowalski', roles: [{name: 'role_001'}, {name: 'role_002'}] }
    // Sprawdzanie czy zalogowany użytkownik ma role "role_001".
    var czyMaRole = context.getSecurityContext().getCurrentUser().roles.map(x=> x.name).includes("role_001");
     
    // Pobranie loginu aktualnie zalogowanego użytkownika. 
    var username = context.getSecurityContext().getCurrentUser().username;
}

Pobieranie konfiguracji aplikacji

Funkcjonalność pobierania konfiguracji aplikacji jest dostępna dla skryptów (scriptService), zadań skryptowych (scriptTask) oraz walidatorów skryptowych (validationScript).

W skryptach istnieje możliwość pobrania konfiguracji aplikacji

interface Api {
    config: {
        v1: {
          get(klucz: string): string;
          getOrDefault(klucz: string, defaultValue: string): string;
        }
    }
}

Przykładowy skrypt pobierający konfiguracje:


function callService(context) {
    let value1
    try {
        value1 = api.config.v1.get("application.url");
    } catch (e) {
        value1 = "default"
    }
 
    let value2 = api.config.v1.get("application.url");
 
    let value3 = api.config.v1.getOrDefault("not_existing_key", "defaultValue")
 
    return [{'value1': value1, 'value2': value2, 'value3': value3}];
}

Przetwarzanie plików xlsx

Możliwy jest odczyt plików xlsx załączonych na wniosku. W tym celu należy skorzystać z modułu xlsx-sheet-handling-module oraz dostarczanego przez niego endpointu /xlsx/v1 - moduł aktualnie dostarczany jest niezależnie, należy wykonać odpowiednią konfiguracje dostępu do usługi w ScriptApi. Do modułu należy przekazać request:

{
    content: string
}

gdzie w content przekazujemy plik w formie base64. W takiej formie jest przekazywany do serwisu gdy zmapujemy na wejście uploader (w przypadku wielu plików w uploaderze jest to lista). W odpowiedzi otrzymamy mapę z podziałem: arkusz → wiersz → kolumna

{
    "arkusz": {
        "1": {
            "A": { "test"
                }
            }
    }
}

Przykład:

function callService(context) {
    let files = context.getParameters("uploader");
 
    if (files.size() === 0) {
        return [{}];
    }
 
    let header = {};
    let body = {'content': files.get(0)}
 
    try {
        let response = api.rest.v1.post('excelDocument', { pathParams: ['xlsx', 'v1'] }, header , body);
     
        return [{'output': JSON.stringify(response.body)}];
    } catch (error) {
        Logger.info(error );
        return [{'output': 'Wystapil blad'}];
    }
 
}

Pobieranie zawartości Treści

Z poziomu skryptu można pobrać zawartość artefaktu Treść (textContent) utworzoną w Eximee Designer, wykorzystując do tego funkcję: api.repository.v1.textContent. Funkcja ta zwraca obiekt, który posiada treści dla każdego ze zdefiniowanych tłumaczeń. By pobrać treść dla danego tłumaczenia używamy funkcji language. Przykład użycia:

const nazwaArtefaktu = "stopka";
const wersjaArtefaktu = "*";
const jezyk = "pl";
 
const artefaktTresci = api.repository.v1.textContent(nazwaArtefaktu, wersjaArtefaktu);
const stopkaPl = artefaktTresci.language(jezyk).text();

Jeśli nie mamy pewności, że podane przez nas parametry są prawidłowe, możemy obsłużyć wyjątki używając try catch:

const nazwaArtefaktu = "stopka";
const wersjaArtefaktu = "*";
const jezyk = "pl";
 
let artefaktTresci;
try {
    artefaktTresci = api.repository.v1.textContent(nazwaArtefaktu, wersjaArtefaktu);
} catch (error) {
    return [{'output': "Brak artefaktu o nazwie: " + nazwaArtefaktu + " i wersji: " + wersjaArtefaktu}]
}
 
let stopkaPl;   
try {
    stopkaPl = artefaktTresci.language(jezyk).text();  
} catch (error) {
    return [{'output': "W artefakcie nie znaleziono tłumaczenia dla języka: " + jezyk}];
}
 
return [{'output': stopkaPl}];

Operacje matematyczne w ScriptCode

Więcej informacji w Operacje matematyczne w ScriptCode

Operacje i dostęp do danych procesu

Więcej informacji w Operacje i dostęp do danych procesu

Pobieranie statusów wniosków

Więcej informacji w Pobieranie statusów wniosków

Model danych

Więcej informacji w API modelu danych

Inne przykłady

Zasilenie komponentu Pole wyboru wartości z listy (Combobox)

Skrypt zasila Pole wyboru wartości z listy (Combobox) na podstawie przekazanego parametru 'locale'.

Wyjścia id, label, oraz description należy podpiąć pod odpowiednie pola comboboxa, kolejno id, text, oraz description.

Skrypt zasilający combobox:

function callService(context) {
    const locale = context.getFirstParameter('locale');
    if (locale === 'pl') {
        return [
            { 'id': 1, 'label': 'Wartosc 1', 'description': 'Opis 1', },
            { 'id': 2, 'label': 'Wartosc 2', 'description': 'Opis 2' }
        ];
    } else if (locale === 'en') {
        return [
            { 'id': 1, 'label': 'Label 1', 'description': 'Description 1', },
            { 'id': 2, 'label': 'Label 2', 'description': 'Description 2' }
        ];
    } else {
        return [
            { 'id': 1, 'label': 'Wartosc domslnego tlumaczenia 1', 'description': 'Opis 1', },
            { 'id': 2, 'label': 'Wartosc domslnego tlumaczenia 2', 'description': 'Opis 2' }
        ];
    }
}

Pobieranie nazwy plików z komponentu Załączniki

Skrypt wykorzystuje metodę getData(), która pobiera wartość konkretnego atrybutu dla komponentu o wskazanym id. Dla komponentu Załączniki nazwy dodanych plików określane są za pomocą atrybutu fileNames i przychodzą z wniosku jako string w formacie JSON (np. ["name1.png", "name2.png"]), dlatego konieczne jest przekształcenie tego stringa w obiekt za pomocą metody JSON.parse.

function callService(context) {
    const zalacznik1 = JSON.parse(context.getData("@GesUploadFile1", "fileNames"));
    const zalacznik2 = JSON.parse(context.getData("@GesUploadFile2", "fileNames"));
}

Pobieranie wartości Pola wyboru wartości z listy (Comboboxa) z sekcji powtarzalnej

Skrypt wykorzystuje metodę getData(), która pobiera wartość konkretnego atrybutu, dla komponentu o wskazanym id. Dla komponentu Pole wyboru wartości z listy wartości (etykiety) danych kluczy określane są za pomocą atrybutu label.

for (let i=0; i<10; i++)  {
        let id = "GesRepeatableSection1.row" + i + ".GesCombobox1";
        let etykieta = context.getData(id, "label");
}

Last updated

Was this helpful?