Proc


Szczegółowy spis treści

1 Szczegółowy spis treści

2 Wprowadzenie

2.1 Funkcja modułu i definicje podstawowych pojęć

2.2 Strona prezentująca instancje procesu

2.3 Rodzaje obiektów i ich rola w procesie

2.4 Obiekty określane dla procesu

2.4.1 Obiekt stanu

2.4.2 Obiekt błędu

2.5 Obiekty określane dla stanów i przejść

2.5.1 Obiekt prezentacji

2.5.2 Obiekt pozostania w stanie

2.5.3 Obiekt inicjalizacji stanu

2.5.4 Obiekt sprawdzania zakończenia podprocesów

2.5.5 Obiekt oczekiwania na zakończenie podprocesów

2.5.6 Obiekt przejścia

2.5.7 Obiekt warunku

2.6 System uprawnień

2.7 Sposób realizacji podprocesów

2.8 Metody przechowywania podprocesów w bazie

2.9 Zewnętrzne wykonywanie przejść

2.10 Uproszczony schemat działania funkcji executeProcess()

2.11 Transakcyjność

2.12 Cache opisu procesów

2.13 Internacjonalizacja

3 Interfejs do edycji procesów

3.1 Nazwy obiektów

3.2 Konfiguracja interfejsu

3.3 Edycja procesów

3.4 Edycja obiektów

3.5 Edycja stanów i przejść

3.6 Edycja uprawnień do stanów i przejść

4 Szczegółowy opis obiektów wykorzystywanych w procesie oraz szablony obiektów

4.1 Obiekt stanu - szczegóły

4.2 Obiekt błędu - szczegóły

4.3 Obiekt prezentacji - szczegóły

4.4 Obiekt pozostania w stanie - szczegóły

4.5 Obiekt inicjalizacji stanu - szczegóły

4.6 Obiekt sprawdzania zakończenia podprocesów - szczegóły

4.7 Obiekt oczekiwania na zakończenie podprocesów - szczegóły

4.8 Obiekt przejścia - szczegóły

4.9 Obiekt warunku - szczegóły

5 Tabele używane przez moduł proc

5.1 Schemat tabel

5.2 Tabela j_processes

5.3 Tabela j_states

5.4 Tabela j_states_p_roles oraz j_states_p_roles_owner

5.5 Tabela j_transitions

5.6 Tabela j_transitions_p_roles oraz j_transitions_p_roles_owner

5.7 Tabela j_objects

5.8 Tabela j_objects_p_objects

6 Funkcje modułu proc

6.1 Edycja i odczyt właściwości procesu

6.2 Edycja i odczyt właściwości stanu

6.3 Edycja i odczyt właściwości przejścia

6.4 Edycja i odczyt właściwości obiektów złożonych

6.5 Edycja uprawnień do stanów

6.6 Edycja uprawnień do przejść

6.7 Sprawdzanie uprawnień do stanów

6.8 Sprawdzanie uprawnień do przejść

6.9 Wykonanie procesu

6.10 Kontekst wykonania procesu

6.11 Wyświetlanie elementów html w obiekcie prezentacji (przejścia i pola ukryte)

6.12 Interfejs html

6.13 Inne funkcje

7 Tutorial - przykład

7.1 Schemat procesu

7.2 Utworzenie struktur danych dla modułu proc

7.3 Utworzenie interfejsu do edycji procesów

7.4 Utworzenie struktur danych dla instancji procesu

7.5 Utworzenie struktury katalogów i obiektów w jdesignerze oraz budowa struktury procesu

8 Informacje dodatkowe

8.1 Szczegółowy schemat wykonania funkcji executeProcess()

8.2 Skrypt tworzący tabele dla Oracle

8.3 Skrypt tworzący tabele dla PostgreSQL

8.4 Schemat tabel dla spirali


Wprowadzenie

Funkcja modułu i definicje podstawowych pojęć

Moduł proc wspomaga obsługę przetwarzania dowolnych elementów, posiadających pewien wewnętrzny stan. Zbiór możliwych stanów oraz relacje pomiędzy nimi muszą być możliwe do opisania za pomocą grafu, którego wierzchołki stanowią stany, a krawędziami są relacje pomiędzy stanami. Krawędzie będą w dalszej części opisu nazywane przejściami a graf stanów i przejść będzie określany jako proces. Proces jest realizowany w pewnym systemie. Proces stanowi więc pewien szablon, schemat możliwych zmian stanów pewnych elementów. Może istnieć wiele elementów, których stany zmieniają się w sposób określony przez proces, ale każdy z tych elementów może w pewnej wybranej chwili czasu mieć stan dowolny spośród zdefiniowanych w procesie. Elementy będą nazywane instancjami procesu.

Powodem powstania modułu była konieczność sformalizowania opisu stanów oraz przejść, co umożliwia dekompozycję procesu i powiązanie występujących w procesie czynności z konkretnymi stanami i przejściami, a tym samym pozwala zapanować nad dużą ilością czynności w procesie. Jednocześnie moduł był projektowany tak, aby w jak najmniejszym stopniu ograniczać swobodę i możliwości użytkownika podczas realizacji różnorodnych procesów.

Podstawowym zadaniem modułu proc jest wspomaganie realizacji procesów biznesowych w technologii jPalio, co określa sposób realizacji czynności w procesie. Przyjmuje się, że instancja procesu znajdująca się w określonym stanie jest w pewnien sposób prezentowana użytkownikowi systemu. Do tego celu wykorzystywana jest wybrana strona html wykonana w jPalio. Na stronie tej umieszczane są informacje związane ze stanem instancji oraz kontrolki umożliwiające użytkownikowi wyzwolenie akcji polegającej na przeniesieniu instancji procesu do innego stanu, czyli wykonanie przejścia. Wyzwolenie akcji powoduje submit formularza html na tą samą stronę jPalio, na której umieszczona była przezentacja danego stanu. Odpowiednia funkcja z modułu proc wykrywa wyzwolenie akcji, wykonuje czynności związane z przejściem i wywołuje obiekty odpowiedzialne za przezentację instancji procesu w nowym stanie. Następnie użytkownik może wykonać kolejną akcję i sekwencja czynności powtarza się. Instancja w dowolnym stanie może być prezentowana dowolną ilość razy, co oznacza, że można wielokrotnie wyświetlać prezentację instancji w danym stanie bez podejmowania żadnych akcji albo w dowolnym momencie przerwać realizację procesu, np. przechodząc do innej strony html, na następnie ponownie wyświetlając stronę z prezentacją instancji w danym stanie i wykonując kolejne akcje w procesie.

  Przykład:
  
  Pewien proces sprzedażowy składa się z czterech stanów:
  A - wprowadzenie danych klienta,
  B - wprowadzenie danych zamówienia,
  C - realizacja zamówienia,
  D - zamówienie zrealizowane,
  graf stanów jest więc bardzo prosty A -> B -> C -> D.
  Instancją procesu jest tu zamówienie klienta (zgłoszenie).
  
  Rozpoczęcie składania zamówienia przez klienta powoduje utworzenie zgłoszenia (instancji
  procesu), któremu nadawany jest stan A i przejście na stronę, na której przezentowane
  jest zgłoszenie w stanie A. Prezentacja zgłoszenia w stanie A zawiera formularz do
  wprowadzania danych klienta oraz przycisk "zapisz". Kliknięcie przycisku "zapisz"
  powoduje submit formularza na tą samą stronę, wykrycie przejścia do stanu B, wykonanie
  akcji związanej z przejściem ze stanu A do stanu B (zapis formularza z danymi klienta),
  zmianę stanu zgłoszenia z A na B oraz wyświetlenie zgłoszenia w stanie B. Prezentacja
  zgłoszenia w stanie B zawiera formularz z danymi zamówienia oraz kolejny przycisk zapisz.
  Kliknięcie przycisku "zapisz" powoduje submit formularza na tą samą stronę, wykrycie
  przejścia do stanu C, wykonanie akcji związanej z przejściem ze stanu B do stanu C
  (zapis formularza z danymi zamówienia), zmianę stanu zgłoszenia z B na C oraz
  wyświetlenie zgłoszenia w stanie C. W tym momencie klient przerywa realizację procesu,
  przechodząc na inną stronę lub zamykając okienko przeglądarki. Każde zgłoszenie dodane
  w ten sposób przez klienta oprócz stanu posiada pewien jednoznaczny identyfikator.
  
  Pracownik obsługujący proces sprzedaży dysponuje listą zgłoszeń klientów.
  Wybiera jedno ze zgłoszeń i otwiera stronę, na której będzie ono prezentowane w swoim
  bieżącym stanie, na ogół C. Do strony przekazywany jest identyfikator zgłoszenia, na
  podstawie którego moduł proc może określić stan, w jakim się ono znajduje. W stanie C
  wyświetlane są zarówno dane klienta, jak i dane zgłoszenia oraz przycisk "zgłoszenie
  zrealizowane". Pracownik wykonuje czynności związane z realizacją zamówienia i klika
  przycisk "zapisz", co powoduje submit formularza na tą samą stronę, wykrycie przejścia
  do stanu D, wykonanie akcji związanej z przejściem ze stanu C do stanu D (jeśli
  jakakolwiek jest określona), zmianę stanu zgłoszenia z C na D oraz wyświetlenie
  zgłoszenia w stanie D. W stanie D nie są określone żadne przejścia, może być tam
  prezentowane to samo co w stanie C, ale nie są wyświetlane żadne przyciski.

Moduł wymaga utworzenia w bazie tabel opisanych w rozdziale "schemat tabel". Skrypt tworzący tabele jest dostępny w rozdziale "skrypt tworzący tabele".

Strona prezentująca instancje procesu

Kod najprostszej strony, na której prezentowane są instancje procesu, wygląda następująco (przy założeniu, że wykonywany proces ma id 618):

  $// strona wyświetlająca zgłoszenia
  $// _RowID - id zgłoszenia do wyświetlenia (id instancji procesu)
  
  $=(@orderId, $toLong($toString($_RowID)) )
  $=(@executionStatus, $proc.executeProcess(618, $@orderId, (String)null) )

$proc.executeProcess() jest główną funkcją modułu proc, zawierającą dispatcher wykonujący wszystkie czynności związane z obsługą procesu oraz wywołujący obiekty wykonujące akcje w procesie.

Rodzaje obiektów i ich rola w procesie

Moduł proc wykorzystuje kilka rodzajów obiektów, realizujących różne funkcje w procesie. Obiekty te można podzielić na:

Obiekty wspólne dla procesu są pojedynczymi obiektami jpalio. Obiekty akcji dla stanów i przejść to obiekty złożone, tzn. każdy taki obiekt jest elementem złożonym z kilku obiektów jpalio, wykonywanych w określonej przez użytkownika kolejności.

Obiekty złożone zostały wprowadzone po to, aby nie powielać obiektów wykonujących pewne elementarne czynności związane ze stanami i z przejściami - można raz napisać zestaw takich obiektów a następnie budować z nich obiekty złożone dla stanów i przejść. Oczywiście podobną funkcjonalność można byłoby uzyskać bez wprowadzania obiektów złożonych, pisząc analogiczne obiekty z elementarnymi funkcjonalnościami, a następnie budując z nich funkcjonalność czynności związanej ze stanem lub przejściem wewnątrz obiektu jpalio. Rozwiązanie z obiektami złożonymi ma jednak tą zaletę, iż daje odpowiednio przeszkolonemu końcowemu użytkownikowi aplikacji możliwość modyfikacji procesu z poziomu inerfejsu.

Obiekty określane dla procesu

Są to obiekty zbudowane z pojedynczego obiektu jpalio. Dla każdego procesu jest określany tylko jeden taki obiekt każego rodzaju.

Obiekt stanu

Moduł proc pozostawia użytkownikowi pełną swobodę wyboru miejsca i sposobu przechowywania instancji procesu. Sposób przechowywania musi spełniać dwa warunki:

Najprostsza tabela spełniająca warunki przechowywania instancji procesów (np. zgłoszeń) wygląda następująco:

  create table orders (
    id number(30) not null constraints ord_id_pk primary key using index tablespace indx,
    state_nr number(12) not null
  );

Powyższe warunki wymuszają konieczność wprowadzenia pewnego interfejsu, za pomocą którego moduł proc będzie mógł odczytać lub zmienić stan instancji o danym identyfikatorze. Dlatego dla każdego procesu wymagane jest określenie tzw. obiektu stanu, który umożliwia wykonanie wymienionych operacji. Dzięki takiemu rozwiązaniu można przechowywać dane instancji w dowolnym miejscu, np. w tabeli bazodanowej lub w zmiennych sesyjnych.

  Rozwiązanie z obiektem stanu daje także możliwość realizacji fragmentów procesu bez
  zapisywania danych do bazy - można utworzyć instancję poprzez nadanie jej kolejnego
  identyfikatora oraz stanu początkowego, zapisać stan instancji w zmiennej sesyjnej
  o nazwie zawierającej identyfikator instancji i wykonywać proces do pewnego etapu,
  na którym dopiero tworzona jest właściwa instancja w bazie danych (rozwiązanie takie
  można wykorzystać np. do realizacji stron, na których klient odpowiada na pewien zestaw
  pytań przed właściwym dodaniem zgłoszenia).

Obiekt stanu może być wywoływany więcej niż raz przy jednym wyświetleniu instancji procesu. Obiekt nie powinien nic wyświetlać. Zobacz szczegóły wywołania oraz szablon obiektu stanu.

Obiekt błędu

Podczas wykonywania procesu mogą zdarzyć się dwa rodzaje błędów:

  1. błędy (np. wyjątki) wewnątrz obiektów jpalio wykonujących czynności w procesie
  2. błędy wewnętrzne modułu proc związane:
    • ze błędami struktury procesu (np. brak definicji stanu o danym numerze)
    • z działaniem obiektu stanu (np. błędne działanie obiektu stanu polegające na nie zwróceniu wartości w odpowiedniej zmiennej globalnej)
    • z przekazywaniem niezbędnych zmiennych podczas submitów formularza (np. nie przekazanie id procesu przy submicie formularza)
    • z brakiem uprawnień użytkownika do stanu

Błędy pierwszego rodzaju są ignorowane przez moduł proc, tzn. wyjątki nie są łapane i sterowanie przechodzi do obiektów wywołujących metody modułu proc.

Do obsługi błędów drugiego rodzaju przeznaczony jest obiekt błędu. Obiekt ten jest wywoływany po wykryciu błędu z parametrami umożliwiającymi obsługę błędu, np. wyświetlenie komunikatu o braku uprawnień wraz z nagłówkiem i stopką używanymi w danym systemie.

Zobacz szczegóły wywołania oraz szablon obiektu błędu.

Obiekty określane dla stanów i przejść

Do wykonania czynności związanych ze stanami moduł proc używa następujących rodzajów obiektów:

Do wykonania czynności związanych z przejściami moduł proc używa następujących rodzajów obiektów:

Ze względu na fakt, iż obiekt jpalio może być wykonywany w ramach kilku obiektów złożonych i w różnym charakterze, proponowane jest dodawanie na końcu nazwy obiektu liter w nawiasach określających, jakie mogą być funkcje obiektu. Poponowany zestaw liter umieszczony jest na powyższych listach, na początku każdej pozycji. Obiekt używany jako presentation_object, stay_in_state_object i on_transition_object powinien mieć suffix nazwy o postaci "(PSO)".

Rola obiektów różnych rodzajów została przedstawiona na poniższym schemacie przykładowego przejścia ze stanu A, B lub C do stanu D.

Rys. Rodzaje i sposób użycia obiektów dla stanów i przejść.

Obiekt prezentacji

Jest to podstawowy obiekt dla stanu. Zawsze musi być określony. Funkcją tego obiektu jest prezentacja użytkownikowi systemu instancji procesu znajdującej się w określonym stanie, co najczęściej oznacza wyświetlenie formularza z danymi klienta, zgłoszenia itp.

Formularz prezentowany użytkownikowi na ogół wymaga odczytu danych. Należy zadbać, aby zawsze przy wyświetlaniu instancji procesu wszystkie dane formularza były odczytywane i ustawiane. Wymóg ten dotyczy także pól, które mają mieć wartość pustą, trzeba je podczas odczytu danych ustawić na null. Przy otwieraniu strony, na której prezentowania jest instancja, np. z listy dostępnych instancji, takie ustawianie wartości zmiennych globalnych na null jest czynnością nadmiarową. Należy jednak pamiętać, iż wyświetlenie instancji w danym stanie może się odbywać zaraz po wykonaniu przejścia za pomocą submitu, a wtedy założenie o domyślnie pustej wartości zmiennych globalnych nie musi być prawdziwe.

  Załóżmy, że pewien proces sprzedażowy zawiera stany F i G. Obiekt prezentacji dla
  stanu F zawiera formularz danych klienta z polem input o nazwie "type". Po kliknięciu
  przycisku wyzwalającego przejście do stanu G następuje zapis danych klienta i zmiana
  stanu zgłoszenia z F na G. Obiekt prezentacji w stanie G zawiera formularz z danymi
  zamówienia. W danych zamówienia także istnieje pole "type", które nie jest
  inicjalizowane, ponieważ oczekuje się wprowadzenia jego wartości przez użytkownika.
  Jeżeli otworzymy zgłoszenie znajdujące się w stanie G z listy zgłoszeń, to pole "type"
  będzie puste i formularz zadziała zgodnie z oczekiwaniami. Jeśli zgłoszenie w stanie G
  zostanie otworzone bezpośrednio po wykonaniu przejścia ze stanu F (po submicie
  formularza z danymi klienta), to wartość pola "type" w formularzu zamówienia będzie
  taka sama, jaka została podana w polu "type" w formularzu z danymi klienta. Aby
  zapobiec takiej sytuacji, należy przy odczycie danych dla formularza w stanie G ustawić
  wartość zmiennej "type" na null.

  Nie należy więc zapominać o inicjalizacji zmiennych, nawet pustych. Błędne
  zainicjowanie zmiennej jak w przykładzie na ogół nie spowoduje katastrofy, ale
  niekiedy konsekwencje mogą być poważniejsze, w zależności od funkcji
  niezainicjalizowanych zmiennych w obiekcie prezentacji.

Jeżeli dane w formularzu są edytowane przez użytkownika systemu, a po wyzwoleniu akcji przejścia sprawdzane i zapisywane za pomocą obiektu przejścia, to pojawia się dodatkowy problem: do prawidłowej realizacji odczytu danych dla formularza w danym stanie konieczne jest wykrycie, czy poprzedzający submit spowodował zmianę stanu. Wynika to z faktu, iż sprawdzenie formularza w obiekcie przejścia może spowodować, iż zmiana stanu nie zostanie wykonana (np. z powodu błędnych danych w formularzu). Wtedy mimo wykonanego submitu, dane formularza nie powinny ponownie się odczytywać.

Najprostszym sposobem uzyskania poprawnego odczytu danych jest użycie następującej konstrukcji:

- w obiekcie stanu, w części dotyczącej zmiany stanu, należy umieścić polecenie ustawiające zmienną, która nie jest używana w żadnym innym miejscu, np: $=(stateChangeFlag, "Y") - w obiekcie prezentacji sprawdzać zmienną stateChangeFlag oraz zmienną informującą o wykonanym odczycie: ... $if( $or($isNull($readFlag), $isNotNull($stateChangeFlag)) ,{ $// odczytaj dane formularza $*sellProcess.stateF.form.read }) ... <form method="post" action="$page.url($currentPageCode())"> <input type="hidden" name="readFlag" value="Y"> </form> ... Warunek $isNull($readFlag) spowoduje odczyt danych formularza przy wyświetlaniu zgłoszenia otworzonego z listy zgłoszeń, warunek $isNotNull($stateChangeFlag) spowoduje odczyt podczas wyświetlania formularza po zmianie stanu.

Do poprawnego działania modułu proc wymagane jest, aby submitowany formularz, zawarty w obiekcie prezentacji, przekazywał dodatkowe ukryte zmienne. Odpowiednie pola hidden wyświetlane są przez funkcję proc.displayHiddenFields(), np.:

  <input type="hidden" name="ProcessExecutionInstanceId" value="2">
  <input type="hidden" name="ProcessExecutionProcessId" value="618">

Dzięki przekazaniu tych zmiennych funkcja proc.executeProcess() wywoływana na stronie prezentującej instancje procesu może po submicie określić, jakiej instancji i wykonywanej wg jakiego procesu dotyczy wywołanie funkcji (niektóre argumenty typowego wywołania, np. proc.executeProcess(681, $_RowID, (String)null), po wykonaniu submitu na ogół są równe null).

  Wywołanie funkcji proc.displayHiddenFields() wewnątrz submitowanego formularza jest
  najprostszym sposobem przekazania wymaganych zmiennych. Zaleca się jednak przekazywanie
  tych zmiennych w parametrach URLa podawanego w argumencie action znacznika <form>.
  Takie rozwiązanie jest znacznie bezpieczniejsze - na stronie chronionej uprawnieniami
  i sumą kontrolną nie jest wtedy możliwe manipulowanie identyfikatorem aktualnie
  procesowanej instancji. Przykładowe rozwiązanie tego typu może wyglądać następująco:
    <form method="post" name="orderForm" id="orderForm"
      action="$page.url($currentPageCode(), null, 
      $+(["&ProcessExecutionInstanceId=", $toString($ProcessExecutionInstanceId),
      "&ProcessExecutionProcessId=", $toString($ProcessExecutionProcessId)) ]) )">

Oprócz pól ukrytych, formularz wyświetlany przez obiekt prezentacji powinien zawierać także elementy umożliwiające wyzwolenie akcji zmiany stanu instancji. Na ogół wyświetlane są w tym celu przyciski o odpowiednich nazwach, jednak dostępne są także inne sposoby wyzwalania przejścia. Do wyświetlania omawianych elementów służą funkcje:

Każda powyższych funkcji sprawdza przed wyświetleniem każdego przejścia uprawnienia użytkownika do wykonania przejścia oraz dodatkowy warunek wyświetlania przejścia, o ile jest on określony (więcej w opisie obiektu warunku).

W wyborze jednej z powyższych funkcji może pomóc znajomość sposobu wykrywania przejścia przez funkcję executeProcess(). Aby wykryć przejście funkcja ta sprawdza zmienną o nazwie _ActionTransition. Oczekiwaną wartością zmiennej jest id przejścia z tabeli j_transitions. Jeśli zmienna ta ma wartość null, to sprawdzane są zmienne _ActionTransitionXX (gdzie XX to id przejścia) - wartość różna od null oznacza wykonanie przejścia o id zawartym w nazwie zmiennej. Zmienna _ActionTransition ma wyższy priorytet niż _ActionTransitionXX.

Wyświetlanie elementów umożliwiających wyzwolenie akcji nie jest oczywiście obowiązkowe - brak tych elementów może być zabiegiem celowym, służącym np. do uzyskania formularza tylko do odczytu dla użytkownika o zbyt małych uprawnieniach.

Wykrywanie przejść oparte o analizę bazodanowego identyfikatora przejścia przekazanego przy pomocy _ActionTransition lub_ActionTransitionXX oraz ograniczenie listy analizowanych przejść do listy przejść dostępnych w stanie bieżącym w pewnym stopniu zabezpiecza procesowanie instancji przed wielokrotnym wykonaniem akcji podczas odświeżania strony w przeglądarce. Wyjątkiem jest tu sytuacja, w której przejście jest pętlą w grafie (przejście prowadzi do tego samego stanu, w którym jest określone).

  W stanie F istnieją przejścia o identyfikatorach 7,8,9. Użytkownik systemu klika
  przycisk o nazwie _ActionTransition8 i wykonuje przejście o id=8 do stanu G. W stanie
  G istnieją przejścia o identyfikatorach 10 i 11. Wykonanie odświeżania strony w przeglądarce
  powoduje, że zostanie ponownie wysłany formularz ze stanu F z ustawioną zmienną _ActionTransition8,
  ale tym razem przejście (ani obiekt akcji w nim określony) nie wykona się, gdyż instancja procesu
  znajduje się już w stanie G, w którym nie ma przejścia o id=8. Zostanie tylko wyświetlona instancja
  procesu w stanie G.

Zobacz szczegóły wywołania oraz szablon obiektu prezentacji.

Obiekt pozostania w stanie

Obiekt pozostania w stanie służy do zakomunikowania użytkownikowi systemu, iż nie bierze on udziału w dalszym przetwarzaniu instancji procesu. Typowym zadaniem obiektu jest wyświetlenie informacji dla użytkownika systemu oraz elementu umożliwiającego przeniesienie do innego miejsca w systemie, np. strony głównej. Jest on wywoływany zamiast obiektu prezentacji, gdy w danych przejścia została zaznaczona flaga "po wykonaniu przejścia pozostań w stanie" (zobacz opis interfejsu html). Wykonywany obiekt pozostania w stanie jest określany w opisie stanu z którego nastąpiło przejście z zaznaczoną flagą pozostania w stanie.

  Typowe zastosowanie obiektu pozostania w stanie:
  W pewnym procesie użytkownik (X) systemu, np. klient, wprowadza w stanie F dane
  zamówienia i zapisuje je, wykonując przejście ze stanu F do G. Zgłoszenie w stanie G
  procesowane jest przez innego użytkownika systemu (Y), np. pracownika. Użytkownik X
  nie ma uprawnień do oglądania zgłoszeń w stanie G. Aby użytkownik X nie zobaczył
  komunikatu błędu o braku uprawnień do zgłoszeń w stanie G należy zaznaczyć w opisie
  przejścia zapisującego dane zamówienia (F->G) flagę pozostania w stanie oraz określić
  obiekt pozostania w stanie dla stanu F. Dzięki temu po zmianie stanu z F na G
  użytkownik X zobaczy obiekt pozostania w stanie z odpowiednim komunikatem (np. "Twoje
  zamówienie zostało przyjęte. Dziękujemy i zapraszamy ponownie.") oraz nie zostanie
  podjęta próba wyświetlenia zgłoszenia w stanie G, co powodowałoby błąd braku uprawnień.

Określenie obiektu w opisie stanu nie jest wymagane. Zobacz szczegóły wywołania oraz szablon obiektu pozostania w stanie.

Obiekt inicjalizacji stanu

Obiekt inicjalizacji stanu jest wykonywany po wykonaniu przejścia (przy zmianie stanu instancji na stan, dla którego obiekt inicjalizacji jest określony), ale raz na każde wykonane przejście. Zadaniem obiektu jest wykonanie czynności inicjalizacyjnych dla instancji w danym stanie, np. przygotowanie wpisów w bazie danych wymaganych przez instancję procesu na danym etapie procesowania.

  Obiekt inicjalizacji nie jest dobrym miejscem np. na odczyt danych formularza
  wyświetlanego przez obiekt prezentacji - podczas wyświetlania zgłoszenia w stanie G,
  wybranego z listy zgłoszeń, obiekt inicjalizacji nie wykona się. Zostanie natomiast
  wywołany po udanym wykonaniu przejścia ze stanu F do stanu G, ale przed wyświetleniem
  obiektu prezentacji określonego dla stanu G lub obiektu pozostania w stanie określonego
  dla stanu F.
  
  Obiektu inicjalizacji można użyć np. do przygotowania w stanie G wpisów w bazie danych,
  które są wymagane przez stan G i stany kolejne, a więc powinny istnieć już w stanie G
  np. ze względu na wyświetlanie ich wartości w formularzu, ale będą stopniowo wypełniane
  i modyfikowane podczas wykonywania akcji określonych w stanach kolejnych względem stanu G.

Określenie obiektu w opisie stanu nie jest wymagane. Obiekt nie powinien nic wyświetlać. Zobacz szczegóły wywołania oraz szablon obiektu inicjalizacji stanu.

Obiekt sprawdzania zakończenia podprocesów

Opis funkcji, jakie spełnia obiekt sprawdzania zakończenia podprocesów, zawarty jest w rozdziale Sposób realizacji podprocesów.

Określenie obiektu w opisie stanu nie jest wymagane. Obiekt nie powinien nic wyświetlać. Zobacz szczegóły wywołania oraz szablon obiektu sprawdzania zakończenia podprocesów.

Obiekt oczekiwania na zakończenie podprocesów

Opis funkcji, jakie spełnia obiekt oczekiwania na zakończenie podprocesów, zawarty jest w rozdziale Sposób realizacji podprocesów.

Określenie obiektu w opisie stanu nie jest wymagane. Zobacz szczegóły wywołania oraz szablon obiektu oczekiwania na zakończenie podprocesów.

Obiekt przejścia

Jest to obiekt, w którym wykonywane są akcje związane z przejściem. Można tu umieścić dowolną akcję, np. sprawdzenie i zapis formularza, utworzenie podprocesu, wygenerowanie zdarzania skierowanego do systemu zewnętrznego itp.

W obiekcie przejścia nie należy umieszczać akcji zmiany stanu instancji. Zmiana stanu jest wykonywana przy pomocy obiektu stanu przez moduł proc po wykonaniu obiektu przejścia.

W obiekcie przejścia istnieje możliwość ustawienia flagi informującej moduł proc o tym, iż akcja związana z przejściem nie została wykonana poprawnie (np. podano błędne dane w formularzu), a tym samym przejście nie powinno wykonać się.

Określenie obiektu w opisie przejścia nie jest wymagane. Obiekt nie powinien nic wyświetlać. Zobacz szczegóły wywołania oraz szablon obiektu przejścia.

Obiekt warunku

Obiekt warunku służy do sprawdzenia, czy można wyświetlić przejście do którego jest przypisany. Obiekt ten, o ile jest określony, jest wywoływany przez funkcje displayTransitionsButtons(), displayTransitionsOptions(), displayTransitions(), displayTransitionButton(), displayTransition().

Obiekt nie jest wywoływany w momencie wykonania przejścia.

  Obiekt warunku może służyć np. do wyświetlania wybranego przejścia tylko w pewnym
  przedziale czasowym, np. od 8 do 16. Jeżeli istotne jest, aby ten sam warunek był
  sprawdzany także w momencie wykonywania (a nie wyświetlania) przejścia, należy utworzyć
  odpowiedni obiekt przejścia.

Określenie obiektu w opisie przejścia nie jest wymagane. Jeśli nie podano obiektu, domyślnie przyjmuje się, że przejście zawsze jest możliwe (o ile user ma prawa do przejścia). Obiekt nie powinien nic wyświetlać. Zobacz szczegóły wywołania oraz szablon obiektu warunku.

System uprawnień

W module proc można określić uprawnienia zarówno do stanów jak i przejść procesu. Uprawnienia kojarzone są z rolami jpalio a nie z przywilejami. Uprawnienia są sprawdzane przez funkcje modułu proc przed wykonaniem obiektu prezentacji lub oczekiwania na zakończenie podprocesów (uprawnienia dla stanu) oraz przed wykonaniem obiektu warunku i obiektu przejścia (uprawnienia do przejścia). W przypadku, gdy użytkownik systemu nie posiada uprawnień do wyświetlenia stanu lub wykonania przejścia, wywoływany jest obiekt błędu.

Oprócz samego faktu istnienia uprawnienia do stanu i przejścia jest możliwe określenie typu uprawnienia. Typ uprawnienia jest jednoliterowy.

  Typy uprawnień można wykorzystać np. do określania sposobu wyświetlania formularza.
  Przyjmijmy, iż wykorzystywane są dwa typy uprawnień do stanu (E od "edit" i V od "view").
  Używając interfejsu do konstrukcji procesów można
  określić, że użytkownicy posiadający rolę X mają uprawnienie E do stanu F, a użytkownicy
  posiadający rolę Y mają uprawnienie V do stanu F. Używając w obiekcie prezentacji
  skojarzonym ze stanem F następującej konstrukcji:
  ...
  $=(@stateNr, $toLong($toString($3)) )
  ...
  $// sprawdź uprawnienia
  $=(isReadonly, true)
  $if( $proc.hasRightForState($user.userID(), $proc.getStateIdByNumber($proc.getProcessExecutingProcessId(),$@stateNr), "E") ,{
    $=(isReadonly, false)
  })

można sterować z poziomu interfejsu wyświetlaniem formularza do edycji albo formularza   tylko do odczytu w zależności od posiadanych przez użytkownika ról.

Moduł proc obsługuje dwa niezależne zestawy uprawnień do stanów i przejść. Funkcje związane z drugim zestawem uprawnień posiadają w swojej nazwie słowo "owner", co jest zaszłością wynikającą ze sposobu użycia drugiego zestawu uprawnień w jednym z portali, podczas rozwijania którego był rozwijany także moduł proc.

  Drugi zestaw uprawnień można wykorzystać, jeśli użytkownik ma mieć różne uprawnienia
  do dokumentów w pewnym stanie w zależności od pewnego warunku. Przykładem może być
  tu procesowanie podań, np. o urlop. Dokument taki po złożeniu zatwierdza osoba
  nadrzędna. Jeżeli zatwierdzenie dokumentu następuje w stanie F i w system pozwala
  wysłać dokument do zatwierdzenia tylko do osoby nadrzędnej, to każdy użytkownik
  powinien móc zatwierdzić wszystkie podania o urlop znajdujące się w stanie F które
  może przejrzeć oprócz tych, które sam złożył.

Sposób realizacji podprocesów

Podprocesem w module proc może być fragment procesu głównego, inny proces lub dowolny inny byt nie związany z modułem proc. Aby uprościć obsługę podprocesów, zostały wprowadzone dwa obiekty: obiekt sprawdzania zakończenia podprocesów i obiekt oczekiwania na zakończenie podprocesów. Załóżmy, iż pewien proces ma postać jak na rysunku poniżej.

Rys. Przykład procesu z podprocesami.

Przejście ze stanu A do stanu B tworzy podproces nr 2 (jest to akcja wykonywana całkowicie przez użytkownika wewnątrz obiektu przejścia). Przejście ze stanu B do stanu C tworzy podproces nr 1. Przez pewnien czas realizacja procesu głównego i podprocesów przebiega niezależnie. Konstrukcja procesu wymaga, aby przed realizacją czynności przewidzianych w dla stanu G oba podprocesy zostały zakończone, a więc przed wykonaniem obiektu prezentacji dla stanu G należy sprawdzić, czy oba podprocesy zostały zakończone. Taką funkcjonalność można osiągnąć poprzez odpowiednią konstrukcję obiektu prezentacji w stanie G, jednakże znacząco komplikuje to kod takiego obiektu. W module proc obsługą przedstawionej sytuacji zajmuje się wspomniany obiekt sprawdzania zakończenia podprocesów i obiekt oczekiwania na zakończenie podprocesów.

Obiekt sprawdzania zakończenia podprocesów jest wywoływany przed obiektem prezentacji (o ile jest określony, wywołanie następuje zarówno po zmianie stanu instancji na stan, w którym obiekt jest określony, jak i przy wyświetlaniu instancji znajdującej się w stanie, w którym obiekt jest określony). Użytkownik powinien w tym obiekcie wykonać sprawdzenie stanu podprocesów i zwrócić informację, czy zostały one zakończone czy nie. Konstrukcja warunku przez użytkownika daje pełną dowolność określenia sposobu oczekiwania na podprocesy, obiekt ten oprócz sprawdzania zakończenia podprocesów może sprawdzać także np. fakt zajścia pewnego zdarzenia w systemie zewnętrznym.

Jeśli obiekt sprawdzania zakończenia podprocesów zwróci informację, iż podprocesy zostały zakończone, to wykonywany jest obiekt prezentacji. W przeciwnym wypadku wykonywany jest obiekt oczekiwania na zakończenie podprocesów, w którym można wyświetlić użytkownikowi systemu informację o oczekiwaniu na zakończenie podprocesów, np. "Podproces nr 1 został zakończony. Zgłoszenie oczekuje na zakończenie podprocesu nr 2.".

Metody przechowywania podprocesów w bazie

Użytkownik może dowolnie przechowywać podprocesy, w sposób wynikający ze struktury systemu. Tabele przechowujące instancje procesu muszą przechowywać także numer stanu.

Struktura tabel przechowujących instancje procesu może być powiązana z procesami na wiele różnych sposobów. Najbardziej typowe przypadki przedstawione są poniżej.

Rys. Hierarchiczna struktura instancji procesu.

Organizacja hierarchiczna jest wygodna, gdy instancja procesu zawiera wiele małych podprocesów ściśle zależnych od procesu głównego. Wtedy zarówno proces główny, jak i podprocesy wygodnie jest zrealizować za pomocą jednego procesu w module proc, przy czym podprocesy określa się jako fragmenty procesu nie łączące się ze sobą ani z procesem głównym. Dla takiej struktury wystarczy jeden obiekt stanu (odczyt i zmiana stanu polega na odczycie i zapisie tego samego pola z tej samej tabeli zarówno dla wszystkich podprocesów jak i procesu głównego). Zaletą takiej struktury jest także to, że nie ma ograniczenia na głębokość zagnieżdżania podprocesów - można wykonać podproces typu "zapytanie do", który można zawierać kolejne podprocesy "zapytanie do" itd. Uzyskuje się wtedy drzewo zapytań o dowolnej głębokości, każde zapytanie procesowane niezależnie, bez modyfikacji struktury bazy. W koncepcji hierarchicznej można także przechowywać dane instancji w jednej tabeli, ale procesy zrealizować jako osobne, każdemu przypisując ten sam obiekt stanu i podając odpowiedni identyfikator procesu w wywołaniu funkcji $executeProcess(), zależny od typu instancji.

Rys. Rozproszona struktura instancji procesu.

Druga typowa struktura, przedstawiona na rysunku powyżej, powinna być używana, gdy w systemie istnieje wiele dużych procesów luźno ze sobą powiązanych. Ze względu na przechowywanie instancji procesów różnego rodzaju w osobnych tabelach, wygodnie jest zrealizować każdy proces lub podproces jako osobny proces w module proc. Wtedy dla każdego procesu w module proc można przypisać obiekt stanu czytający i zapisujący stan z odpowiedniej tabeli.

Oczywiście istnieje możliwość dowolnego łączenia powyższych koncepcji, np. zrealizowania niektórych podprocesów jako fragmentów procesów a niektórych jako niezależne procesy albo przechowywania części instancji w strukturze hierarchicznej a części w osobnych tabelach.

Zewnętrzne wykonywanie przejść

Oprócz wyzwalania przejść przez użytkownika podczas wykonania procesu możliwe jest także zewnętrzne (względem procesu) wykonanie przejść, np. przejścia wykonywane przez zadanie jpalio. Do zewnętrznego wykonania przejścia służy funkcja executeTransition(). Podczas wykonania executeTransition() sprawdzane są uprawnienia użytkownika do stanu, wykonywany jest obiekt przejścia (o ile został określony), następnie stan instancji jest zmieniany za pomocą obiektu stanu oraz wykonywany jest obiekt inicjalizacji.

Możliwe jest też przeniesienie instancji do stanu za pomocą funkcji moveInstanceToState(). Podczas przenoszenia do stanu nie są sprawdzane żadne prawa, nie jest wykonywany obiekt przejścia, a przejście pomiędzy bieżącym stanem procesu i docelowym nie musi być określone. Stan obiektu jest zmieniany za pomocą obiektu stanu. Wykonywany jest też obiekt inicjalizacji dla nowego stanu, o ile jest podany.

Zalecane jest odwoływanie się do przejść za pomocą ich identyfikatorów tekstowych (j_transitions.text_id) a nie numerycznych (j_transitions.id).

Uproszczony schemat działania funkcji executeProcess()

Uproszczony schemat działania funkcji $proc.executeProcess() umieszczony jest poniżej.

Rys. Uproszczony schemat działania funkcji executeProcess().

Dokument zawiera także szczegółowy schemat wykonania funkcji executeProcess().

Transakcyjność

Dostępne są dwie metody wykonania przejść w procesach - z zapewnieniem transakcyjności i bez.

Jeżeli transakcyjność jest włączona, to wyrzucenie wyjątku w jakimkolwiek obiekcie jpalio składającym się na obiekty przejścia lub inicjalizacji stanu spowoduje wykonanie rollbacka i wyrzucenie wyjątku przez metodę proc.executeProcess(). Przy włączonej transakcyjności podczas wykonywania przejścia można także dodawać konektory do transakcji z pomocą odpowiedniej metody modułu sql.

Bez włączonej transakcyjności wyjątki nie są przechwytywane, nie powodują przerwania wykonania przejścia a do ich obsługi używane są standardowe mechanizmy jPALIO. Każde polecenie z modułu sql jest wykonywane w osobnej, izolowanej transakcji. Wykonanie procesu bez włączonej transakcyjności może być stosowane w punktach synchronizacji procesu z systememi zewnętrznymi.

Wersję z transakcyjnością i bez przedstawia poniższy przykład:

$=(@executionStatus, $proc.executeProcess(618, $@orderId, (String)null) )  // bez transakcyjności
$=(@executionStatus, $proc.executeProcess(618, $@orderId, (String)null), true)  // z transakcyjnością

Cache opisu procesów

W obecnej wersji modułu struktura procesu nie jest buforowana, a więc większość funkcji modułu proc operuje bezpośrednio na bazie danych.

Internacjonalizacja

W obecnej wersji modułu nie są dostępne tłumaczenia standardowych komunikatów błędów.


Interfejs do edycji procesów

Moduł proc dysponuje interfejsem html pozwalającym edytować procesy, obiekty złożone oraz uprawnienia do stanów i przejść. Obiekty interfejsu zawarte są w pliku jPalio.jar, co umożliwia ich szybkie dodanie w dowolnym systemie. Należy w tym celu wykonać jednokrotnie w dowolnym obiekcie funkcję $proc.createOrReplaceHtmlInterface(). Po wykonaniu funkcji należy odświeżyć drzewo katalogów w jDesignerze. W katalogu głównym pojawi się katalog "Zarządzanie procesami", zawierający obiekty interfejsu. Aby uzyskać dostęp do stron interfejsu, należy dodać linki do stron 90010, 90020, 90030, 90050.

Interfejs oparty jest o identyfikatory obiektów i stron, a nie o kody (był tworzony dla wersji jpalio nie obsługującej jeszcze kodów). Katalogi, obiekty i strony posiadają identyfikatory > 90000.

Interfejs był testowany na bazie Oracle oraz postgreSQL.

W katalogu "Zarządzanie procesami > 03 Obiekty referencyjne dla procesów" można znaleźć przykłady obiektów różnych typów.

Nazwy obiektów

Ze względu na dużą liczbę obiektów jpalio istniejących na ogół w systemie, podczas wskazywania tychże obiektów w formularzach interfejsu zaistniała konieczność ograniczenia liczby obiektów wyświetlanych na liście. Aby obiekty jpalio były widoczne na listach, konieczne jest nadanie im określonych prefiksów w nazwie (nie w kodzie):

Zalecane jest także nadawanie nazwom obiektów odpowiednich literowych suffiksów, określonych w rozdziale "Obiekty określane dla stanów i przejść".

Konfiguracja interfejsu

Interfejs html umożliwia dostosowanie kolorów interfejsu (obiekt 90041) oraz sposobu definiowania uprawień (obiekt 90040). Różne systemy mogą używać jednego lub dwóch zestawów uprawnień. Do wskazania ilości używanych zestawów służy zmienna UseOwnerRights, null oznacza jeden zestaw uprawnień, not null dwa. W zmiennych StateRightTypes, StateRightTypesOwner, TransitionRightTypes, TransitionRightTypesOwner można określić dostępne typy uprawnień dla stanów i przejść, podanie jednej pozycji tabeli spowoduje, iż w formularzu do edycji uprawnień będą wyświetlane checkboxy, podanie większej ilości typów wygeneruje listę rozwijaną.

Edycja procesów

Edycja procesów jest dostępna na stronie 90010.

Rys. Tabela procesów.

W tabeli procesów wyświetlone są zdefiniowane procesy. Przyciski "Zablokuj" i "Odblokuj" umożliwiają zmianę statusu procesu. "Usuń" usuwa proces oraz wszystkie przypisane do niego stany, przejścia i obiekty złożone. Przycisku należy używać ze szczególną ostrożnością, gdyż akcja nie jest w żaden sposób potwierdzana. "Kopiuj" tworzy kopię procesu oraz wszystkich przypisanych do niego stanów, przejść, obiektów złożonych oraz uprawnień do stanów i przejść. Kliknięcie na nazwie procesu powoduje przeniesienie do formularza właściwości procesu.

Rys. Formularz właściwości procesu.

Formularz właściwości procesu umożliwia określenie nazwy procesu, jego identyfikatora tekstowego, oraz obiektu stanu i błędu dla procesu. Aby na liście obiektów stanu i błędu widoczne były obiekty jpalio, ich nazwa musi zaczynać się odpowiednio od "Proc state" lub "Proc error".

Edycja obiektów

Edycja obiektów jest dostępna na stronie 90020.

Rys. Tabela obiektów.

Na stronie z tabelą obiektów można dodawać, usuwać i kopiować obiekty złożone. Kliknięcie nazwy obiektu przenosi do formularza właściwości obiektu.

Rys. Formularz właściwości obiektu.

Formularz właściwości obiektu złożonego umożliwia określenie nazwy, przynależności do procesu oraz składowych obiektów jpalio. Określenie przynależności do procesu powoduje, że obiekt będzie kopiowany i usuwany razem z procesem. Obiekty nie przypisane do procesów będą wyświetlane na listach obiektów złożonych w formularzach właściwości stanów i przejść wszystkich procesów. Przycisk ze znakiem "^" służy do zmiany kolejności wykonania obiektów składowych - przesuwa dany obiekt składowy o pozycję wyżej. Wybranie pozycji na liście "nty obiekty jpalio" i zapisanie danych obiektu spowoduje pojawienie się kolejnej listy "nty obiekty jpalio", umożliwiającej dodanie następnego obiektu. Zapis pozycji "nty obiekty jpalio" z wartością pustą spowoduje usunięcie danej pozycji.

Pod formularzem właściwości obiektu wyświetlana jest tabela stanów i przejść, w których obiekt jest używany. Kliknięcie pozycji tabeli przenosi do formularza właściwości odpowiedniego stanu.

Edycja stanów i przejść

Edycja stanów i przejść jest dostępna na stronie 90030.

Rys. Tabela stanów.

Na stronie edycji stanów i przejść wyświetlane są dwie tabele. Kliknięcie pozycji w pierwszej z nich przenosi do edycji klikniętego stanu i jego przejść. Kliknięcie pozycji w drugiej tabeli pozwala edytować cały proces jednocześnie.

Rys. Formularz właściwości stanu.

Formularz właściwości stanu służy do edycji właściwości stanu i przejść z nim powiązanych. Dane przejść są wcięte względem danych stanów. Stany są wyświetlane w kolejności odpowiadającej numerowi stanu.

Znaczenie pól formularza właściwości stanu, kolejno od góry:

Znaczenie pól formularza właściwości przejścia, kolejno od góry:

Rola kontrolek umieszczonych pod tabelą stanów stanów i przejść.

Pod tabelą stanów i przejść umieszczono także dwie tabele nawigacyjne.

Służą one do szybkiego przenoszenia do edycji obiektów wykorzystywanych przez stan oraz do przenoszenia do edycji stanów, których przejścia prowadzą do bieżącego stanu lub przenoszenia do edycji stanów, do których prowadzą przejścia bieżącego stanu.

Zmiany wprowadzone w polach formularza są zapisywane tylko po kliknięciu jednego z przycisków "Zapisz zmiany". Użycie dowolnego innego przycisku lub skorzystanie z tabel nawigacyjnych powoduje utracenie wprowadzonych zmian.

Rys. Formularz uprawnień do stanu.

Powyższy formularz jest wyświetlany po kliknięciu przycisku "uprawnienia" w formularzu edycji stanu lub przejścia. Na rysunku została przedstawiona edycja uprawnień do stanu, edycja uprawnień do przejścia wygląda i jest obsługiwana analogicznie. Aby określić uprawnienia do stanu, należy wybrać dla żądanych ról typ uprawnienia z listy i kliknąć przycisk "zapisz". Akcja "odśwież" przeładowuje formularz, ignorując wprowadzone zmiany. Jeśli interfejs zostałby skonfigurowany tak, aby używać jednego typu uprawnień, zamiast list rozwijanych zostałyby wyświetlone pola wyboru typu checkbox. Zaznaczenie pola wyboru oznacza nadanie uprawnienia.

Edycja uprawnień do stanów i przejść

Edycja uprawnień do stanów i przejść jest dostępna na stronie 90050.

Rys. Formularz uprawnień.

Strona ta udostępnia znacznie wygodniejszy interfejs do edycji uprawnień niż dostępny w formularzu edycji stanów i przejść. Wyświetlane są jednocześnie uprawnienia do wszystkich stanów i przejść wybranego procesu (pole "stany i przejścia procesu") oraz wszystkich lub wybranych ról. Role można ograniczyć do pojedynczej roli za pomocą pola "uprawnienia dla roli", do wybranej roli i ról do niej podrzędnych (pole "uprawnienia dla poddrzewa ról") lub do grupy wskazanych ról (pole "uprawnienia dla wybranych ról", zaznaczanie wielu ról po poprzez klikanie z wciśniętym klawiszem shift lub ctrl). Jeśli interfejs jest skonfigurowany tak, aby używać jednego typu uprawnień dla stanów/przejść, zamiast list rozwijanych zostaną wyświetlone pola wyboru typu checkbox. Zaznaczenie pola wyboru oznacza nadanie uprawnienia. Zmiany wprowadzone w uprawnieniach są zapisywane po kliknięciu przycisku "ustaw skojarzenia", znajdującego się pod tabelą uprawnień.


Szczegółowy opis obiektów wykorzystywanych w procesie oraz szablony obiektów

Komunikacja z obiektami wywoływanymi przez funkcje modułu proc odbywa się za pomocą zmiennych globalnych jpalio, przy czym dotyczy to zarówno przekazywania wartości do obiektów jak i zwracania wartości przez obiekty. Moduł proc nie uwzględnia zwracania przez obiekty wartości za pomocą funkcji return(), gdyż jest starszy niż funkcja return(). W celu zachowania kompatybilności z istniejącymi realizacjami procesów nie wprowadzono zmian dotyczących sposobu zwracania wartości przez obiekty.

Obiekt stanu - szczegóły

Zobacz opis roli, jaką pełni obiekt.

Parametry wywołania:

0 - identyfikator instancji, której stan należy odczytać lub zapisać
1 - dodatkowy parametr procesu przekazywany każdemu z używanych obiektów (trzeci argument wywołania funkcji executeProcess())
2 - null - odczyt stanu instancji, not null - zapis (zmiana) stanu instancji, wtedy w tym parametrze przekazywany jest nowy numer stanu, który należy ustawić instancji o numerze podanym w parametrze 0
3 - null przy odczycie stanu, bieżący (zmieniany) numer stanu przy zapisie, może zostać użyty np. w celu rejestracji historii

Zmienne ustawiane przed wywołaniem obiektu:

Zmienne możliwe do ustawienia przez obiekt (przy odczycie stanu):

Zmienne możliwe do ustawienia przez obiekt (przy zapisie stanu):

 

$// ------------------------------------------------------------------------------------
$// --- obiekt stanu -------------------------------------------------------------------
$// ------------------------------------------------------------------------------------

$=(@instanceId, $toLong($toString($0)))
$=(@processExtraParam, $toString($1))
$=(@newStateNr, $toLong($toString($2)))
$=(@oldStateNr, $toLong($toString($3)))

$if( $isNull($@newStateNr) ,{ $// odczyt stanu  

  $// dodawanie zgłoszenia przy pierwszym wyświetleniu instancji
  $// dodawanie zgłoszenia można zrealizować także inaczej - np. poza procesem lub w obiekcie przejścia lub inicjalizacji stanu
  $if( $==($@instanceId,0) ,{ $// identyfikator umowny oznaczający nie istniejący jeszcze w systemie dokument
    $// dodaj zgłoszenie
    $=(ProcessExecutionInstanceId, $xxx.addOrder(...) )
    
    $// rejestracja dodania zgłoszenia w historii
    $=(@BlackHole, $history.recordChange("orders", "add", $toLong($toString($ProcessExecutionInstanceId)), (String)null, " ") )
  },{
    $// odczyt stanu
    $=(ProcessExecutionStateNr, $xxx.getOrderStateNumber($@instanceId) )
  })
  
},{

  $// zmiana stanu
  $if( $<>($@instanceId,0) ,{   $// nie zmieniaj stanu nie istniejącego dokumentu
    $// zmiana stanu
    $xxx.setOrderStateNr($@instanceId, $@newStateNr)
    
    $// rejestracja zmiany stanu w historii
    $=(BlackHole, $history.recordChange("orders", "state_nr", $@instanceId, $toString($@oldStateNr), $toString($@newStateNr) ) )
    
    $// ustawienie flagi zakończenia obiegu złoszenia
    $=(@nextStateId, $proc.getStateIdByNumber($proc.getProcessExecutingProcessId(),$@newStateNr) )
    $if( $proc.isStateLastInProcess($@nextStateId) ,{
      $xxx.setOrderStatus($@instanceId, "F")
    })
  })
  
})

 

Obiekt błędu - szczegóły

Zobacz opis roli, jaką pełni obiekt.

Parametry wywołania:

0 - identyfikator instancji procesu, której dotyczy wywołanie obiektu
1 - dodatkowy parametr procesu przekazywany każdemu z używanych obiektów (trzeci argument wywołania funkcji executeProcess())
2 - kod błędu, który wystąpił podczas wykonania procesu
3 - domyślny tekst błędu
4 - identyfikator wykonywanego procesu
5 - numer stanu, w jakim znajduje się instancja procesu
6 - identyfikator wykonywanego przejścia (o ile przejście jest wykonywane, jeśli nie to null)
7 - identyfikator stanu, do którego prowadzi wykonywane przejście

Zmienne ustawiane przed wywołaniem obiektu: brak

Zmienne możliwe do ustawienia przez obiekt: brak

Kody błędów przekazywane w 2 parametrze wywołania (nazwy błędów można także pobrać wywołując funkcję $proc.getErrorName($toLong($toString($2))) ):

0 - wykonanie poprawne (bez błędów)
1 - nie podano id procesu
2 - błędne id procesu
3 - nie podano numeru instancji do wykonania
4 - nie ustawiono obiektu stanu dla wykonywanego procesu
5 - obiekt stanu nie ustawił numeru stanu w zmiennej 'ProcessExecutionStateNr'
6 - w procesie nie zdefiniowano numeru stanu, w jakim znajduje się instancja procesu
50 - obiektu stanu nie ustawił numeru stanu w zmiennej 'ProcessExecutionStateNr'
51 - w procesie nie zdefiniowano numeru stanu, w jakim znajduje się instancja procesu
52 - nie określono obiektu wyświetlającego dla stanu
53 - brak uprawnień do wyświetlenia stanu
54 - nie określono obiektu pozostania w stanie
55 - nie określono obiektu oczekiwania na zakończenie podprocesów dla stanu,
100 - nie określono stanu następnego dla przejścia
101 - nie można ustalić numeru stanu nastepnego dla przejścia
102 - brak uprawnień do wykonania przejścia
103 - błędne text_id przejścia (wyrzucane z funkcji executeTransition() ),
104 - reserved
105 - reserved
106 - reserved
107 - nieprawidłowy numer stanu następnego (wyrzucane z funkcji moveInstanceToState())
108 - reserved
109 - reserved

 

$// ------------------------------------------------------------------------------------
$// --- obiekt błędu -------------------------------------------------------------------
$// ------------------------------------------------------------------------------------
 
$=(@instanceId, $toLong($toString($0)))
$=(@processExtraParam, $toString($1))
$=(@errorCode, $toLong($toString($2)))
$=(@defaultErrorDescription, $toString($3))
$=(@processId, $toLong($toString($4)))
$=(@stateNr, $toLong($toString($5)))
$=(@transitionId, $toLong($toString($6)))
$=(@nextStateId, $toLong($toString($7)))
 
$=(@errorString, $+(["Wystąpił błąd nr ",$toString($@errorCode)," podczas wykonywania procesu: <br>",$@defaultErrorDescription,"."]))
 
$// nagłówek
$*xxx.header
 
<center>
  <b>$@errorString</b><br>
</center>
 
<br><br>
 
<input type="button" name="action" value="Strona główna" onclick="window.location='$page.url("xxx.mainpage")';">

$// stopka
$*xxx.foot

 

Obiekt prezentacji - szczegóły

Zobacz opis roli, jaką pełni obiekt.

Parametry wywołania:

0 - charakter wywołania obiektu - "presentation_object"
1 - identyfikator instancji procesu, której dotyczy wywołanie obiektu
2 - dodatkowy parametr procesu przekazywany każdemu z używanych obiektów (trzeci argument wywołania funkcji executeProcess())
3 - numer stanu, w jakim znajduje się instancja procesu
4 - informacja wygenerowana przez obiekt on_transition_object w zmiennej ProcessExecutionTransitionInfo, (o ile przed wyświetleniem instancji było wykonywane przejście, w przeciwnym wypadku null)
5 - dodatkowy parametr stanu określony w tabeli stanów procesu (j_states.presentation_param)
6 - lista numerów pierwszych stanów podprocesów, które mogą zostać rozpoczęte w tym stanie. Jest to lista numerów oddzielonych średnikami (np.: "1;2;3"), więc do rozdzielenia numerów można użyć standardowego $split. Na ogół lista zawiera jedną wartość. Jeśli w danym stanie mogło by rozpocząć się więcej podprocesów niż jeden (lista z wieloma pozycjami), to do identyfikowania stanów początkowych podprocesów należy użyć identyfikatora tekstowego stanu (ew. nazwy lub numeru stanu - należy wybrać to pole, które dla różnych wersji tego samego procesu pozostanie niezmienione). Wartość przekazywana w tym parametrze pochodzi z j_states.starting_subpr_states

Zmienne ustawiane przed wywołaniem obiektu:

Zmienne możliwe do ustawienia przez obiekt: brak

 

$// ------------------------------------------------------------------------------------
$// --- obiekt prezentacji -------------------------------------------------------------
$// ------------------------------------------------------------------------------------

$=(@callType, $toString($0))

$if( $==($@callType,"presentation_object") ,{

  $=(@instanceId, $toLong($toString($1)))
  $=(@processExtraParam, $toString($2))
  $=(@stateNr, $toLong($toString($3)))
  $=(@lastTransitionInfo, $toString($4))
  $=(@stateExtraParam, $toString($5))
  $=(@subprocessesFirsStatesId, $toString($6))
  
  $// ----------------------------------------------------------------------------
  
  $// prosty formularz z możliwymi przejściami:

  <form method="post" action="$page.url($currentPageCode())">

    $// dodatkowe zmienne do przekazania
    <input type="hidden" name="xxx" value="yyy">
    
    $proc.displayHiddenFields()
    $proc.displayTransitionsButtons("button","    ")
    
  </form>
  
  $// ----------------------------------------------------------------------------
  
  $// formularz z odczytem i zapisem

  $// ustawienie parametrów formularza podanych w parametrze
  $proc.parseObjectParams($@stateExtraParam)
  
  $// stateChangeFlag jest ustawiane na not null w obiekcie stanu, w części dotyczącej zmiany stanu
  $if( $or($isNull($readFlag), $isNotNull($stateChangeFlag)) ,{
    $// odczyt danych formularza
    $*xxx.readFormData($@instanceId)
  })
  
  $// wyświetlenie formularza
  <form method="post" action="$page.url($currentPageCode())">
  
    <input type="hidden" name="readFlag" value="Y">
    
    ... 
    
    $proc.displayHiddenFields()
    $proc.displayTransitionsButtons("button","    ")
    
  </form>
  
})

 

Obiekt pozostania w stanie - szczegóły

Zobacz opis roli, jaką pełni obiekt.

Parametry wywołania:

0 - charakter wywołania obiektu - "stay_in_state_object"
1 - identyfikator instancji procesu, której dotyczy wywołanie obiektu
2 - dodatkowy parametr procesu przekazywany każdemu z używanych obiektów (trzeci argument wywołania funkcji executeProcess())
3 - numer stanu, w jakim znajduje się instancja procesu
4 - informacja wygenerowana przez obiekt on_transition_object w zmiennej ProcessExecutionTransitionInfo, (o ile przed wyświetleniem instancji było wykonywane przejście, w przeciwnym wypadku null)
5 - dodatkowy parametr stanu określony w tabeli stanów procesu (j_states.stay_in_state_param)

Zmienne ustawiane przed wywołaniem obiektu:

Zmienne możliwe do ustawienia przez obiekt: brak

 

$// ------------------------------------------------------------------------------------
$// --- wyswietlenie pozostania w stanie -----------------------------------------------
$// ------------------------------------------------------------------------------------

$=(@callType, $toString($0))

$if( $==($@callType,"stay_in_state_object") ,{

  $=(@instanceId, $toLong($toString($1)))
  $=(@processExtraParam, $toString($2))
  $=(@stateNr, $toLong($toString($3)))
  $=(@lastTransitionInfo, $toString($4))
  $=(@stateExtraParam, $toString($5))
  
  $// ustawienie parametrów formularza podanych w parametrze
  $proc.parseObjectParams($@stateExtraParam)
  
  $// nagłówek
  $*xxx.header

  <center>
    <b>Zgłoszenie zostało zapisane</b><br>
  </center>

  <br><br>

  <input type="button" name="action" value="Strona główna" onclick="window.location='$page.url("xxx.mainpage")';">

  $// stopka
  $*xxx.foot
  
})

 

Obiekt inicjalizacji stanu - szczegóły

Zobacz opis roli, jaką pełni obiekt.

Parametry wywołania:

0 - charakter wywołania obiektu - "state_init_object"
1 - identyfikator instancji procesu, której dotyczy wywołanie obiektu
2 - dodatkowy parametr procesu przekazywany każdemu z używanych obiektów (trzeci argument wywołania funkcji executeProcess())
3 - numer stanu, w jakim znajduje się instancja procesu
4 - informacja wygenerowana przez obiekt on_transition_object w zmiennej ProcessExecutionTransitionInfo, (o ile przed wyświetleniem instancji było wykonywane przejście, w przeciwnym wypadku null)
5 - dodatkowy parametr stanu określony w tabeli stanów procesu (j_states.init_param)
6 - numer poprzedniego stanu (z jakiego proces dotarł do bieżącego stanu)

Zmienne ustawiane przed wywołaniem obiektu:

Zmienne możliwe do ustawienia przez obiekt:

 

$// ------------------------------------------------------------------------------------
$// --- inicjalizacja stanu ------------------------------------------------------------
$// ------------------------------------------------------------------------------------

$=(@callType, $toString($0))

$if( $==($@callType,"state_init_object") ,{

  $=(@instanceId, $toLong($toString($1)))
  $=(@processExtraParam, $toString($2))
  $=(@stateNr, $toLong($toString($3)))
  $=(@lastTransitionInfo, $toString($4))
  $=(@stateExtraParam, $toString($5))
  $=(@previousStateNr, $toLong($toString($6)))

  $// wykonaj czynności inicjalizujące instancję procesu w danym stanie, np.
  $// dodawanie parametru zgłoszenia. Obiekt wykonywany jest tylko raz, przy
  $// wejściu do danego stanu, a nie przy każdym wyświetleniu zgłoszenia w danym stanie.
  ...
  
})

 

Obiekt sprawdzania zakończenia podprocesów - szczegóły

Zobacz opis roli, jaką pełni obiekt.

Parametry wywołania:

0 - charakter wywołania obiektu - "wait_for_subpr_condition"
1 - identyfikator instancji procesu, której dotyczy wywołanie obiektu
2 - dodatkowy parametr procesu przekazywany każdemu z używanych obiektów (trzeci argument wywołania funkcji executeProcess())
3 - numer stanu, w jakim znajduje się instancja procesu
4 - informacja wygenerowana przez obiekt on_transition_object w zmiennej ProcessExecutionTransitionInfo, (o ile przed wyświetleniem instancji było wykonywane przejście, w przeciwnym wypadku null)
5 - dodatkowy parametr stanu określony w tabeli stanów procesu (j_states.wait_for_subpr_param). Obiekt sprawdzania zakończenia podprocesów posiada parametr stanu wspólny z obiektem oczekiwania na zakończenie podprocesów

Zmienne ustawiane przed wywołaniem obiektu:

Zmienne możliwe do ustawienia przez obiekt:

 

$// ------------------------------------------------------------------------------------
$// --- sprawdzanie zakończenia podprocesów --------------------------------------------
$// ------------------------------------------------------------------------------------

$=(@callType, $toString($0))

$if( $==($@callType,"wait_for_subpr_condition") ,{

  $=(@instanceId, $toLong($toString($1)))
  $=(@processExtraParam, $toString($2))
  $=(@stateNr, $toLong($toString($3)))
  $=(@lastTransitionInfo, $toString($4))
  $=(@stateExtraParam, $toString($5))

  $if( podprocesy_zakończone ,{
    $=(ProcessExecutionSubprocessesFinished, "Y")
  },{
    $=(ProcessExecutionSubprocessesFinished, null)
  })

})

 

Obiekt oczekiwania na zakończenie podprocesów - szczegóły

Zobacz opis roli, jaką pełni obiekt.

Parametry wywołania:

0 - charakter wywołania obiektu - "wait_for_subpr_object"
1 - identyfikator instancji procesu, której dotyczy wywołanie obiektu
2 - dodatkowy parametr procesu przekazywany każdemu z używanych obiektów (trzeci argument wywołania funkcji executeProcess())
3 - numer stanu, w jakim znajduje się instancja procesu
4 - informacja wygenerowana przez obiekt on_transition_object w zmiennej ProcessExecutionTransitionInfo, (o ile przed wyświetleniem instancji było wykonywane przejście, w przeciwnym wypadku null)
5 - dodatkowy parametr stanu określony w tabeli stanów procesu (j_states.wait_for_subpr_param). Obiekt oczekiwania na zakończenie podprocesów posiada parametr stanu wspólny z obiektem sprawdzania zakończenia podprocesów

Zmienne ustawiane przed wywołaniem obiektu:

Zmienne możliwe do ustawienia przez obiekt: brak

 

$// ------------------------------------------------------------------------------------
$// --- oczekiwanie na zakończenie podprocesów -----------------------------------------
$// ------------------------------------------------------------------------------------

$=(@callType, $toString($0))

$if( $==($@callType,"wait_for_subpr_object") ,{

  $=(@instanceId, $toLong($toString($1)))
  $=(@processExtraParam, $toString($2))
  $=(@stateNr, $toLong($toString($3)))
  $=(@lastTransitionInfo, $toString($4))
  $=(@stateExtraParam, $toString($5))

  informacja o oczekiwaniu na zakończenia podprocesów, np. lista zakończonych i niezakończonych instancji podprocesów
   
})

 

Obiekt przejścia - szczegóły

Zobacz opis roli, jaką pełni obiekt.

Parametry wywołania:

0 - charakter wywołania obiektu - "on_transition_object"
1 - identyfikator instancji procesu, której dotyczy wywołanie obiektu
2 - dodatkowy parametr procesu przekazywany każdemu z używanych obiektów (trzeci argument wywołania funkcji executeProcess())
3 - numer stanu, w jakim znajduje się instancja procesu
4 - numer następnego stanu, w jakim znajdzie się instancja procesu
5 - dodatkowy parametr stanu określony w tabeli stanów procesu (j_transitions.objects_param)
6 - lista numerów pierwszych stanów podprocesów, które mogą zostać rozpoczęte w tym stanie. Jest to lista numerów oddzielonych średnikami (np.: "1;2;3"), więc do rozdzielenia numerów można użyć standardowego $split. Na ogół lista zawiera jedną wartość. Jeśli w danym stanie mogło by rozpocząć się więcej podprocesów niż jeden (lista z wieloma pozycjami), to do identyfikowania stanów początkowych podprocesów należy użyć identyfikatora tekstowego stanu (ew. nazwy lub numeru stanu - należy wybrać to pole, które dla różnych wersji tego samego procesu pozostanie niezmienione). Wartość przekazywana w tym parametrze pochodzi z j_states.starting_subpr_states

Zmienne ustawiane przed wywołaniem obiektu:

Zmienne możliwe do ustawienia przez obiekt:

 

$// ------------------------------------------------------------------------------------
$// --- wykonanie przejścia ------------------------------------------------------------
$// ------------------------------------------------------------------------------------

$=(@callType, $toString($0))

$if( $==($@callType,"on_transition_object") ,{

  $=(@instanceId, $toLong($toString($1)))
  $=(@processExtraParam, $toString($2))
  $=(@stateNr, $toLong($toString($3)))
  $=(@nextStateNr, $toString($4))
  $=(@stateExtraParam, $toString($5))
  $=(@subprocessesFirsStatesId, $toString($6))

  $if( dane_formularza_poprawne ,{
    $// zapisz formularz
    ...
  },{
    $// błąd w danych formularza, nie zmieniaj stanu
    $=(ProcessExecutionTransitionSuccessful, null)
    
    $=(errorString, "Proszę podac wartość w polu ...")
  })
  
})

 

Obiekt warunku - szczegóły

Zobacz opis roli, jaką pełni obiekt.

Parametry wywołania:

0 - charakter wywołania obiektu - "condition_object"
1 - identyfikator instancji procesu, której dotyczy wywołanie obiektu
2 - dodatkowy parametr procesu przekazywany każdemu z używanych obiektów (trzeci argument wywołania funkcji executeProcess())
3 - numer stanu, w jakim znajduje się instancja procesu
4 - numer następnego stanu, w jakim znajdzie się instancja procesu
5 - dodatkowy parametr stanu określony w tabeli stanów procesu (j_transitions.objects_param)
6 - lista numerów pierwszych stanów podprocesów, które mogą zostać rozpoczęte w tym stanie. Jest to lista numerów oddzielonych średnikami (np.: "1;2;3"), więc do rozdzielenia numerów można użyć standardowego $split. Na ogół lista zawiera jedną wartość. Jeśli w danym stanie mogło by rozpocząć się więcej podprocesów niż jeden (lista z wieloma pozycjami), to do identyfikowania stanów początkowych podprocesów należy użyć identyfikatora tekstowego stanu (ew. nazwy lub numeru stanu - należy wybrać to pole, które dla różnych wersji tego samego procesu pozostanie niezmienione). Wartość przekazywana w tym parametrze pochodzi z j_states.starting_subpr_states

Zmienne ustawiane przed wywołaniem obiektu:

Zmienne możliwe do ustawienia przez obiekt:

 

$// ------------------------------------------------------------------------------------
$// --- warunek wyświetlania przejścia -------------------------------------------------
$// ------------------------------------------------------------------------------------

$=(@callType, $toString($0))

$if( $==($@callType,"condition_object") ,{

  $=(@instanceId, $toLong($toString($1)))
  $=(@processExtraParam, $toString($2))
  $=(@stateNr, $toLong($toString($3)))
  $=(@nextStateNr, $toString($4))
  $=(@stateExtraParam, $toString($5))
  $=(@subprocessesFirsStatesId, $toString($6))

  $if( warunek_wyświetlania_przejścia ,{
    $// można wyświetlić przejście
    $=( ProcessExecutionTransitionPossible, "Y")
  },{
    $// nie można wyświetlić przejścia
    $=( ProcessExecutionTransitionPossible, null)
  })
  
})

 


Tabele używane przez moduł proc

Schemat tabel

Rys. Schemat tabel wykorzystywanych przez moduł proc.

Skrypt tworzący tabele jest dostępny w rozdziale "Skrypt tworzący tabele".

Tabela j_processes

W tabeli przechowywane są dane procesu.

nazwa kolumnytyp polaczy niepusteopis
id number(6) tak identyfikator procesu
status char(1) tak N - proces aktywny, L - proces zablokowany
error_object number(6) id obiektu jPALIO (z p_objects), pełniącego funkcję obiektu stanu
state_object number(6) id obiektu jPALIO (z p_objects), pełniącego funkcję obiektu błędu
name varchar2(200) tak nazwa procesu
text_id varchar2(50) tak identyfikator tekstowy procesu

Tabela j_states

W tabeli przechowywany jest opis stanów procesów.

nazwa kolumnytyp polaczy niepusteopis
id number(6) tak identyfikator stanu
not_protected char(1) not null - przejście nie chronione uprawnieniami, null - chronione
process_first_state char(1) not null - pierwszy stan procesu
subprocess_first_state char(1) not null - pierwszy stan podprocesu
process_last_state char(1) not null - ostatni stan procesu lub podprocesu
archive_state char(1) not null - flaga ustawiona, null - nie ustawiona
process_id number(6) tak id procesu, do którego należy stan
state_nr number(12) tak numer stanu w procesie (numer, który jest przechowywany razem z instancją procesu w polu określającym stan instancji)
stay_in_state_object number(6) id obiektu złozonego z j_objects, pełniącego funkcję pozostania w stanie
wait_for_subpr_condition number(6) id obiektu złozonego z j_objects, pełniącego funkcję obiektu sprawdzania zakończenia podprocesów
wait_for_subpr_object number(6) id obiektu złozonego z j_objects, pełniącego funkcję obiektu oczekiwania na zakończenie podprocesów
init_object number(6) id obiektu złozonego z j_objects, pełniącego funkcję obiektu inicjalizacji stanu
presentation_object number(6) id obiektu złozonego z j_objects, pełniącego funkcję obiektu prezentacji
position_x number(12) nie używane
position_y number(12) nie używane
name varchar2(200) tak nazwa stanu
text_id varchar2(50) identyfikator tekstowy stanu
init_param varchar2(500) parametr dla obiektu parametr dla obiektu
wait_for_subpr_param varchar2(500) parametr dla obiektu sprawdzania zakończenia podprocesów i obiektu oczekiwania na zakończenie podprocesów
presentation_param varchar2(500) parametr dla obiektu prezentacji
stay_in_state_param varchar2(500) parametr dla obiektu pozostania w stanie
page_title varchar2(200) tytuł strony ustawiany podczas wykonania procesu w zmiennych PageTitle, _PageTitle
info_str varchar2(200) informacja dla użytkownika systemu ustawiana podczas wykonania procesu w zmiennych InfoStr, _InfoStr
warning_str varchar2(200) informacja - ostrzeżenie dla użytkownika systemu ustawiana podczas wykonania procesu w zmiennych ErrorStr, _ErrorStr
starting_subpr_states varchar2(200) lista id pierwszych stanów podprocesów, które mogą zostać rozpoczęte w tym stanie. Jest to lista identyfikatorów stanów (id z j_states) oddzielonych średnikami (np.: "1;2;3")

Tabela j_states_p_roles oraz j_states_p_roles_owner

W tabelach przechowywane są uprawnienia ról jpalio do stanów procesu. Tabela j_states_p_roles przechowuje podstawowy zestaw uprawnień, a j_states_p_roles_owner dodatkowy zestaw uprawnień.

nazwa kolumnytyp polaczy niepusteopis
role_id number(6) tak identyfikator roli (z p_roles)
state_id number(6) tak identyfikator stanu (z j_states)
type char(1) tak jednoliterowy typ uprawnienia. Jeśli typy uprawnień nie są wykorzystywane (używany jest system jest uprawnienie/nie ma uprawnienia), to zawartość tego pola może być dowolna, ale musi być podana

Tabela j_transitions

W tabeli przechowywany jest opis przejść w procesach.

nazwa kolumnytyp polaczy niepusteopis
id number(6) tak identyfikator przejścia
not_protected char(1) not null - przejście nie chronione uprawnieniami, null - chronione
stay_in_state char(1) not null - po wykonaniu przejścia wyświetlany jest obiekt pozostania w stanie a nie instancja procesu w kolejnym stanie
dont_display char(1) przejście nie jest wyświetlane, ale jest istnieje i można je wykonać ręcznie
state_id number(6) tak identyfikator stanu (z j_states), do którego przypisane jest przejście (stan, z którego wychodzi przejście)
condition_object number(6) id obiektu złozonego z j_objects, pełniącego funkcję obiektu przejścia
on_transition_object number(6) id obiektu złozonego z j_objects, pełniącego funkcję obiektu warunku
next_state_id number(6) identyfikator stanu docelowego dla przejścia (z j_states)
display_order number(12) kolejność wyświetlania przejść, mniejsze numery wyświetlane są pierwsze, jeśli kilka przejść ma taką samą wartość display_order, to pierwsze wyświetlane są przejścia o niższym id
name varchar2(200) tak nazwa przejścia, wyświetlana na elementach html (np. przyciskach) wyzwalających przejście
text_id varchar2(50) identyfikator tekstowy przejścia
objects_param varchar2(500) parametr dla obiektu warunku i obiektu przejścia

Tabela j_transitions_p_roles oraz j_transitions_p_roles_owner

W tabelach przechowywane są uprawnienia ról jpalio do przejść w procesie. Tabela j_transitions_p_roles przechowuje podstawowy zestaw uprawnień, a j_transitions_p_roles_owner dodatkowy zestaw uprawnień.

nazwa kolumnytyp polaczy niepusteopis
role_id number(6) tak identyfikator roli (z p_roles)
transition_id number(6) tak identyfikator przejścia (z j_transitions)
type char(1) tak jednoliterowy typ uprawnienia. Jeśli typy uprawnień nie są wykorzystywane (używany jest system jest uprawnienie/nie ma uprawnienia), to zawartość tego pola może być dowolna, ale musi być podana

Tabela j_objects

Tabela przechowuje listę i opis obiektów złożonych.

nazwa kolumnytyp polaczy niepusteopis
id number(6) tak identyfikator obiektu złożonego
process_id number(6) przypisanie obiektu złożonego do procesu (id procesu z j_processes), null oznacza obiekt nie przypisany do żadnego procesu
name varchar2(200) tak nazwa obiektu złożonego

Tabela j_objects_p_objects

Tabela określa, z jakich obiektów jpalio składają się poszczególne obiekty złożone. W polu execute_order określona jest także kolejność wykonania obiektów jpalio podczas wykonania obiektu złożonego.

nazwa kolumnytyp polaczy niepusteopis
id number(6) tak id wpisu w j_objects_p_objects
p_object_id number(6) tak identyfikator obieku jPALIO (z p_objects)
j_object_id number(6) tak identyfikator obieku złożonego (z j_objects)
execute_order number(12) kolejność wykonania, obiekty jPALIO o mniejszych wartościach w execute_order są wykonywane pierwsze, jeśli kilka obiektów ma taką samą wartość execute_order, to pierwsze wykonywane są obiekty o niższym id w j_objects_p_objects

Funkcje modułu proc

Edycja i odczyt właściwości procesu

nazwa funkcjiopis funkcji
addProcess dodaje proces
copyProcess kopiuje proces oraz podrzędne do niego stany, przejścia, obiekty złożone oraz uprawnienia do stanów i przejść
removeProcess usuwa proces, przypisane do niego stany, przejścia oraz prawa do nich
lockProcess blokuje podany proces
unlockProcess odblokowuje podany proces
getProcessStates zwraca tablicę id stanów dostępnych w podanym procesie
getProcessErrorObject zwraca identyfikator obiektu paliowego obsługującego błędy występujące podczas realizacji procesu (id obiektu błędu)
getProcessIdByName zwraca id procesu o podanej nazwie
getProcessIdByTextId zwraca id procesu o podanym identyfikatorze tekstowym
getProcessName zwraca nazwę procesu
getProcessStateObject zwraca identyfikator obiektu paliowego realizującego odczyt i zapis stanów procesu (id obiektu stanu)
getProcessStatus zwraca status podanego procesu: N proces odblokowany, L - zablokowany
getProcessTextId zwraca tekstowy identyfikator procesu
setProcessErrorObject ustawia identyfikator obiektu paliowego obsługującego błędy występujące podczas realizacji procesu (id obiektu błędu)
setProcessName zmienia nazwę procesu na name
setProcessStateObject ustawia identyfikator obiektu paliowego realizującego odczyt i zapis stanów procesu (id obiektu stanu)
setProcessTextId ustawia tekstowy identyfikator procesu

Edycja i odczyt właściwości stanu

nazwa funkcjiopis funkcji
addState dodaje nowy stan dla podanego procesu o domyślnej nazwie "new state" i mający następny wolny numer stanu
copyState kopiuje stan w ramach procesu
removeState usuwa stan o podanym identyfikatorze
getStateTransitions zwraca tablicę id przejść dostępnych w podanym stanie
getStateIdByNumber zwraca id stanu o podanym numerze
getStateIdByTextId zwraca id stanu o podanym identyfikatorze tekstowym
getStateInfoString zwraca ciąg informacyjny dla stanu o podanym identyfikatorze
getStateInitObject zwraca id obiektu procesu inicjalizującego stan
getStateInitParam zwraca parametr obiektu procesu inicjalizującego stan o podanym identyfikatorze
getStateName zwraca nazwę stanu o podanym identyfikatorze
getStateNumber zwraca numer stanu o podanym identyfikatorze
getStatePageTitle zwraca tytuł strony dla stanu o podanym identyfikatorze
getStatePositionX zwraca pozycję x stanu na grafie stanów i przejść
getStatePositionY zwraca pozycję y stanu na grafie stanów i przejść
getStatePresentationObject zwraca id obiektu procesu wyświetlającego stan
getStatePresentationParam zwraca parametr obiektu procesu wyświetlającego stan
getStateProcessId zwraca id procesu, do którego jest przypisany stan o podanym identyfikatorze
getStateRoleOwnerRight zwraca, czy podany stan i rola paliowa są skojarzone dla użytkownika będącego właścicielem instancji
getStateRoleRight zwraca, czy podany stan i rola paliowa są skojarzone, a więc czy podana rola ma prawa do danego stanu
getStateStartingSubprocesses zwraca tablicę numerów
getStateStartingSubprocessesStr zwraca listę numerów
getStateStayInStateObject zwraca id obiektu procesu wyświetlanego przy pozostaniu w stanie
getStateStayInStateParam zwraca parametr obiektu procesu wyświetlanego przy pozostaniu w stanie
getStateTextId zwraca identyfikator tekstowy stanu o podanym id
getStateWaitForSubprCondition zwraca id obiektu procesu sprawdzającego, czy podprocesy zakończyły się
getStateWaitForSubprObject zwraca id obiektu procesu wyświetlającego stan, gdy czeka się na zakończenie podprocesów
getStateWaitForSubprParam zwraca parametr obiektu procesu wyświetlającego stan, gdy czeka się na zakończenie podprocesów
getStateWarningString zwraca ciąg z ostrzeżeniem dla stanu o podanym identyfikatorze
isStateArchive zwraca informację, czy podany stan jest stanem archiwum
isStateFirstInProcess zwraca informację, czy podany stan jest pierwszym stanem procesu
isStateFirstInSubprocess zwraca informację, czy podany stan jest pierwszym stanem podprocesu
isStateLastInProcess zwraca informację, czy podany stan jest ostatnim stanem procesu lub podprocesu
isStateNotProtected zwraca informację, czy stan nie jest chroniony
setStateArchive ustawia, czy podany stan jest stanem archiwum
setStateFirstInProcess ustawia, czy podany stan jest pierwszym stanem procesu
setStateFirstInSubprocess ustawia, czy podany stan jest pierwszym stanem podprocesu
setStateInfoString ustawia ciąg informacyjny dla stanu o podanym identyfikatorze
setStateInitObject ustawia id obiektu procesu inicjalizującego stan o podanym identyfikatorze
setStateInitParam ustawia parametr obiektu procesu inicjalizującego stan o podanym identyfikatorze
setStateLastInProcess ustawia, czy podany stan jest ostatnim stanem procesu lub podprocesu
setStateName ustawia nazwę stanu o podanym identyfikatorze
setStateNotProtected ustawia ochronę dla podanego stanu
setStateNumber ustawia numer stanu o podanym identyfikatorze
setStatePageTitle ustawia tytuł strony dla stanu o podanym identyfikatorze
setStatePosition ustawia pozycję stanu na grafie stanów i przejść
setStatePositionX ustawia pozycję x stanu na grafie stanów i przejść
setStatePositionY ustawia pozycję y stanu na grafie stanów i przejść
setStatePresentationObject ustawia id obiektu procesu wyświetlającego stan
setStatePresentationParam ustawia parametr obiektu procesu wyświetlającego stan
setStateProcessId ustawia id procesu, do którego jest przypisany stan o podanym identyfikatorze
setStateRoleOwnerRight ustawia powiązanie podanego stanu i roli paliowej
setStateRoleRight ustawia powiązanie podanego stanu i roli paliowej
setStateStartingSubprocesses ustawia tablicę numerów
setStateStartingSubprocessesStr ustawia tablicę numerów
setStateStayInStateObject ustawia id obiektu procesu wyświetlanego przy pozostaniu w stanie
setStateStayInStateParam ustawia parametr obiektu procesu wyświetlanego przy pozostaniu w stanie
setStateTextId ustawia identyfikator tekstowy stanu o podanym id
setStateWaitForSubprCondition ustawia id obiektu procesu sprawdzającego, czy podprocesy zakończyły się
setStateWaitForSubprObject ustawia id obiektu procesu wyświetlającego stan, gdy czeka się na zakończenie podprocesów
setStateWaitForSubprParam ustawia parametr obiektu procesu wyświetlającego stan, gdy czeka się na zakończenie podprocesów
setStateWarningString ustawia ciąg z ostrzeżeniem dla stanu o podanym identyfikatorze

Edycja i odczyt właściwości przejścia

nazwa funkcjiopis funkcji
addTransition tworzy nowe przejście
copyTransition kopiuje przejście o podanym id w ramach stanu
removeTransition usuwa przejście o podanym id oraz wszystkie prawa do niego
exchangeTransitionDisplayOrder zamienia wartość w polu określającym kolejność wyświetlania dwóch podanych przejść
getTransitionConditionObject zwraca id obiektu procesu określającego, czy przejście może zostac wyświetlone
getTransitionDisplayOrder zwraca numer określający kolejność wyświetlania przejść w ramach stanu dla przejścia o podanym identyfikatorze
getTransitionIdByName zwraca id przejścia o podanej nazwie
getTransitionIdByTextId zwraca id przejścia o podanym identyfikatorze numerycznym
getTransitionName zwraca nazwę przejścia o podanym identyfikatorze
getTransitionNextStateId zwraca id stanu, do którego jest prowadzi przejście o podanym identyfikatorze
getTransitionObjectsParam zwraca parametr dla obiektów condition_object oraz on_transition_object przejścia o podanym identyfikatorze
getTransitionOnTransitionObject zwraca id obiektu procesu obiektu wywoływanego podczas wykonywania podanego przejścia
getTransitionRoleOwnerRight zwraca, czy podane przejście i rola paliowa są skojarzone dla użytkownika będącego właścicielem instancji
getTransitionRoleRight zwraca, czy podane przejście i rola paliowa są skojarzone, a więc czy podana rola ma prawa do danego przejścia
getTransitionStateId zwraca id stanu, do którego jest przypisane przejście o podanym identyfikatorze
getTransitionTextId zwraca identyfikator tekstowy przejścia o podanym identyfikatorze numerycznym
isTransitionDontDisplay zwraca informację, czy przejście jest wyświetlane przez funkcję wyświetlającą możliwe przejścia, czy nie
isTransitionNotProtected zwraca informację, czy przejście nie jest chronione
isTransitionStayInState zwraca informację, czy po wykonaniu podanego przejścia należy wyświetlić obiekt pozostania w stanie, czy kolejny stan
setTransitionConditionObject ustawia id obiektu procesu określającego, czy przejście
setTransitionDisplayOrder ustawia numer określający kolejność wyświetlania przejść w ramach stanu dla przejścia o podanym identyfikatorze
setTransitionDontDisplay ustawia, czy przejście jest wyświetlane przez funkcję wyświetlającą możliwe przejścia
setTransitionName ustawia nazwę przejścia o podanym identyfikatorze
setTransitionNextStateId ustawia id stanu, do którego jest prowadzi przejście o podanym identyfikatorze
setTransitionNotProtected ustawia ochronę dla podanego przejścia
setTransitionObjectsParam ustawia parametr dla obiektów condition_object oraz on_transition_object dla przejścia o podanym identyfikatorze
setTransitionOnTransitionObject ustawia id obiektu procesu obiektu wywoływanego podczas wykonywania podanego przejścia
setTransitionRoleOwnerRight ustawia powiązanie podanego przejścia i roli paliowej
setTransitionRoleRight ustawia powiązanie podanego przejścia i roli paliowej
setTransitionStateId ustawia id stanu, do którego jest przypisane przejście o podanym identyfikatorze
setTransitionStayInState ustawia, czy po wykonaniu podanego przejścia należy wyświetlić obiekt pozostania w stanie, czy kolejny stan
setTransitionTextId ustawia identyfikator tekstowy przejścia o podanym identyfikatorze numerycznym

Edycja i odczyt właściwości obiektów złożonych

nazwa funkcjiopis funkcji
addObject tworzy obiekt procesu (obiekt złożony)
copyObject kopiuje obiekt procesu i jego skojarzenia z obiektami paliowymi
removeObject usuwa obiekt procesu i jego skojarzenia z obiektami paliowymi
addObjectsAssociation dodaje nowe skojarzenie obiektu procesu z obiektem palio
removeObjectsAssociation usuwa skojarzenie obiektu procesu z obiektem palio
exchangeObjectsExecuteOrder zamienia numer porządkowy
getObjectPalioObjects zwraca tablicę id skojarzeń obiektu procesu i obiektów paliowych dostępnych dla podanego obiektu procesu
getObjectIdByName zwraca id obiektu procesu o podanej nazwie
getObjectName zwraca nazwę obiektu procesu o podanym identyfikatorze
getObjectProcessId zwraca identyfikator procesu, do którego jest przypisany podany obiekt procesu
getObjectsExecuteOrder zwraca numer porządkowy
getObjectsPalioObjectId zwraca identyfikator obiektu paliowego dla skojarzenia obiektu procesu i obiektu paliowego o podanym id
getObjectsProcessObjectId zwraca identyfikator obiektu procesu dla skojarzenia obiektu procesu i obiektu paliowego o podanym id
setObjectName ustawia nazwę obiektu procesu o podanym identyfikatorze
setObjectProcessId ustawia identyfikator procesu, do którego jest przypisany podany obiekt procesu
setObjectsExecuteOrder ustawia numer porządkowy
setObjectsPalioObjectId ustawia identyfikator obiektu procesu dla podanego skojarzenia obiektu procesu i obiektu paliowego
setObjectsProcessObjectId ustawia identyfikator obiektu procesu dla podanego skojarzenia obiektu procesu i obiektu paliowego

Edycja uprawnień do stanów

nazwa funkcjiopis funkcji
clearStateRoleOwnerRight usuwa powiązanie podanego stanu i roli paliowej
clearStateRoleRight usuwa powiązanie podanego stanu i roli paliowej
copyStateRoleOwnerRights kopiuje prawa właściciela pomiędzy stanami
copyStateRoleRights kopiuje prawa nie właściciela pomiędzy stanami
removeStateRoleOwnerRights usuwa wszystkie prawa właściciela do stanu dla wszystkich ról
removeStateRoleRights usuwa wszystkie prawa nie właściciela do stanu dla wszystkich ról

Edycja uprawnień do przejść

nazwa funkcjiopis funkcji
clearTransitionRoleOwnerRight ustawia powiązanie podanego przejścia i roli paliowej
clearTransitionRoleRight usuwa powiązanie podanego przejścia i roli paliowej
copyTransitionRoleOwnerRights kopiuje prawa właściciela pomiędzy przejściami
copyTransitionRoleRights kopiuje prawa nie właściciela pomiędzy przejściami
removeTransitionRoleOwnerRights usuwa wszystkie prawa właściciela do przejścia dla wszystkich ról
removeTransitionRoleRights usuwa wszystkie prawa nie właściciela do przejścia dla wszystkich ról

Sprawdzanie uprawnień do stanów

nazwa funkcjiopis funkcji
hasRightForState zwraca, czy dany użytkownik ma prawo do danego stanu procesu
hasRightForStateOwner zwraca, czy dany użytkownik, będący właścicielem instancji, ma prawo do danego stanu procesu

Sprawdzanie uprawnień do przejść

nazwa funkcjiopis funkcji
hasRightForTransition zwraca, czy dany użytkownik ma prawo do danego przejścia procesu
hasRightForTransitionOwner zwraca, czy dany użytkownik, będący właścicielem instancji, ma prawo do danego przejścia procesu

Wykonanie procesu

nazwa funkcjiopis funkcji
executeProcess wykonuje podaną instancję procesu wg ścieżki określonej w procesie o podanym id
executeTransition wykonuje przejście o podanym text_id dla podanej instancji procesu
moveInstanceToState przesuwa instancję procesu do podanego stanu przy pomocy wywołania obiektu stanu

Kontekst wykonania procesu

nazwa funkcjiopis funkcji
isProcessExecuting zwraca true, jeżeli proces jest właśnie wykonywany, tzn. jeżeli właśnie jest wykonywana procedura executeprocess
getProcessExecutingInstanceId zwraca id instancji dla właśnie wykonywanego procesu
getProcessExecutingIsOwnersInstance zwraca, czy instancja właśnie wykonywanego procesu należy do zalogowanego użytkownika, czy nie
getProcessExecutingProcessId zwraca id właśnie wykonywanego procesu
getProcessExecutingStateId zwraca id stanu, w którym znajduje się instancja właśnie wykonywanego procesu
getProcessExecutingStateNr zwraca numer stanu, w którym znajduje się instancja właśnie wykonywanego procesu
getProcessExecutingTransitionId zwraca id przejścia które wykonuje instancja bieżącego procesu

Wyświetlanie elementów html w obiekcie prezentacji (przejścia i pola ukryte)

nazwa funkcjiopis funkcji
parseObjectParams ustawia parametry zawarte w przekazanym ciągu na odpowiadające im wartości
displayHiddenFields wyświetla pola typu hidden, które muszą zostać przeniesione przez formularz zawierający przyciski przejść
displayTransition wyświetla przejście o podanym text_id, dopuszczalne w bieżącym stanie
displayTransitions wyświetla dopuszczalne w bieżącym stanie przejścia - kolejno
displayTransitionButton wyświetla dopuszczalne w bieżącym stanie przejście o podanym text_id, jako przycisk
displayTransitionsButtons wyświetla dopuszczalne w bieżącym stanie przejścia jako zestaw przycisków - zobacz opis funkcji displaytransitionsbuttons
displayTransitionsOptions wyświetla dopuszczalne w bieżącym stanie przejścia jako listę opcji - zobacz opis funkcji displaytransitionsoptions

Interfejs html

nazwa funkcjiopis funkcji
createOrReplaceHtmlInterface tworzy interfejs HTML do zarządzania strukturą procesów (dodaje odpowiednie obiekty i strony jPALIO)

Inne funkcje

nazwa funkcjiopis funkcji
getErrorName podaje nazwę błędu zwróconego przez dowolną funkcję z modułu proc
getVersion zwraca numer wersji modułu

Tutorial - przykład

Poniżej podano przykład realizacji prostego procesu. Przykład nie jest opisany "krok po kroku", gdyż jego realizacja na podstawie tutoriala byłaby wtedy bardzo czasochłonna. Opisane zostało kilka pierwszych kroków, które powinien wykonać użytkownik, aby zacząć używać modułu proc. Przygotowanie odpowiednich obiektów jpalio oraz konstrukcja procesu za pomocą interfejsu html została pominięta. Zamiast opisu tych kroków pod adresem http://devel.torn.com.pl/palio/html.run?_Instance=proc_test dostępna jest instancja z realizacją procesu opisanego w przykładzie, która może być kopiowana a następnie dowolnie modyfikowana w celach szkoleniowych. Dump tej instancji dla bazy danych Oracle v10 oraz jPALIO 7.4.21 można pobrać tutaj. Dostępna jest także łatka całej instancji.

Schemat procesu

Rys. Schemat przykładowego procesu.

Przykładowy proces składa się z siedmiu stanów. Stany 100.003 i 101.001 zostały zrównoleglone na potrzeby przykładu. Przejście do stanu 100.003 powoduje utworzenie podprocesu w obiekcie inicjalizacji stanu 100.003. Stan 100.004 powinien zostać wyświetlony dopiero gdy podproces zakończy się (znajdzie się w stanie 101.002). Funkcję tą realizują określone w stanie 100.004 obiekty sprawdzania zakończenia podprocesów i oczekiwania na zakończenie podprocesów. Stany 100.005 i 101.002 są stanami końcowymi w procesie.

Utworzenie struktur danych dla modułu proc

Należy utworzyć struktury bazy danych wymagane przez moduł proc korzystając z zawartego w dokumentacji skryptu tworzącego tabele lub schematu dla Spirali.

Utworzenie interfejsu do edycji procesów

Należy jednokrotnie wykonać w dowolnym obiekcie jpalio funkcję $proc.createOrReplaceHtmlInterface() a następnie odświeżyć dane w jdesignerze.

Utworzenie struktur danych dla instancji procesu

Należy wykonać poniższy skrypt tworzący tabelę przechowującą dane instancji procesu (zgłoszeń). Skrypt dla opisanego powyżej przykładu jest przygotowany dla bazy Oracle. Struktura danych zgłoszenia jest ograniczona do jednej tabeli ze względu na maksymalne uproszczenie przykładu i nie powinna stanowić inspiracji podczas realizacji rzeczywistych procesów (dane klienta i dodatkowe parametry zgłoszenia powinny być przechowywane w osobnych tabelach).

Struktura zgłoszenia jest hierarchiczna. W zgłoszeniach podrzędnych będzie przechowywany stan podprocesu 101. Podproces 101 zostanie zamodelowany jako fragment procesu rozłączny względem procesu nadrzędnego (proces główny i podproces będą widziane przez moduł proc jako jeden proces).

 

 

create table proc_test_orders
(
 id number(20) not null constraints protesord_id_pk primary key using index tablespace indx,
 state_nr number(20) not null,
 parent_id number(20),
 customer_data varchar2(4000 byte),
 order_data varchar2(4000 byte),
 is_finished char(1 byte) not null,
 creation_date date not null,
 last_state_change date not null
) tablespace users;

alter table proc_test_orders add constraint protesord_parid_fk foreign key (parent_id) references proc_test_orders (id);

create sequence proc_test_orders_s start with 1;
 

 

Utworzenie struktury katalogów i obiektów w jdesignerze oraz budowa struktury procesu

Kroki utworzenia struktury katalogów i obiektów w jdesignerze oraz budowy struktury procesu nie zostały tutaj opisane, jednak można nauczyć się ich powielając proces dostępny na instancji wymienionej w rozdziale "tutorial - przykład". Można też wczytać łatkę w jDesignerze. Uwagi, które mogą być przydatne podczas nauki:


Informacje dodatkowe

Szczegółowy schemat wykonania funkcji executeProcess()

Rys. Schemat wykonania funkcji executeProcess() strona 1.

 

Rys. Schemat wykonania funkcji executeProcess() strona 2.

Zobacz też uproszczony schemat działania funkcji executeProcess().

Skrypt tworzący tabele dla Oracle

Skrypt tworzący tabele modułu proc w bazie Oracle można pobrać tutaj tutaj.

Skrypt tworzący tabele dla PostgreSQL

Skrypt tworzący tabele modułu proc w bazie PostgreSQL można pobrać tutaj.

Schemat tabel dla spirali

Schemat tabel dla programu Spiral można pobrać tutaj.

Schemat tabel można otworzyć w programie Spiral w wersji 0.9.1 lub w jDesignerze.