Spis treści

XML dla Workflow

Jako repozytorium i silnik bpmn używamy Activiti. Poniższa dokumentacja jest rozszerzeniem http://www.activiti.org/userguide/index.html#bpmn20 i należy się z nią wcześniej zapoznać.

Ogólny opis zawartości pliku

W pliku występują następujące znaczniki:

  1. <startEvent> - oznacza rozpoczęcie workflow i może zawierać formatkę
  2. <userTask> - oznacza pojedyncze zadania i może zawierać formatkę
  3. <documentation> - oznacza opis do zadania
  4. <extensionElements> - zawiera opisy formatki
  5. <activiti:formProperty> - zawiera opis pojedynczego pola z formatki

Przykład znacznika <startEvent>

<startEvent id="start" activiti:initiator="owner">
<extensionElements>
   <activiti:formProperty id="ID:firTytul;TYPE:FIRMATIC_FIELD;ARGS:FIR_NAME:Tytul;" name="Tytuł" type="string" />
   <activiti:formProperty id="ID:firDate_Realize;TYPE:FIRMATIC_FIELD;ARGS:FIR_NAME:Date_Realize;" name="Data realizacji" type="string" />
   <activiti:formProperty id="ID:firAPartnerIdent;TYPE:FIRMATIC_FIELD;ARGS:FIR_NAME:APartnerIdent;" name="Kontrahent symbol" type="string" />
   <activiti:formProperty id="ID:firAPartnerName;TYPE:FIRMATIC_FIELD;ARGS:FIR_NAME:APartnerName;" name="Kontrahent" type="string" />
   <activiti:formProperty id="ID:firDescription;TYPE:FIRMATIC_FIELD;ARGS:{FIR_NAME:Description, FIELD_OPT:TEXTAREA};" name="Opis" type="string" />
   <activiti:formProperty id="ID:firBtn;TYPE:FIRMATIC_SIGNAL;ARGS:KEY:306;" name="Pokaż WKT" type="string" />
</extensionElements>
</startEvent>

Wartości parametru name mogą być dowolne i nie mają wpływu na pracę workflow.

Opis znacznika <activiti:formProperty>

Jest to najważniejszy znacznik w workflow i definiuje on co będzie widział użytkownik na formatce. Istotne znaczenie mają atrybuty id i type.

Atrybuty dodatkowe:

Znaczenie poszczególnych wartości w atrybutach zostanie pokazana na przykładach:

Pole firmaticowe
<activiti:formProperty id="ID:firTytul;TYPE:FIRMATIC_FIELD;ARGS:FIR_NAME:Tytul;" name="Tytuł" type="string" />

W tym polu można używać atrybutu writable w celu ograniczenia edytowalności pola (tzn. z pola edytowalnego w firmaticu można zrobić nieedytowalne w workflow).

Pole firmaticowe odświeżane w zakładce "Informacje o procesie"

Domyślnie pola firmaticowe w zakładce „Informacje o procesie” nie są odświeżane. Można wymusić odświeżanie poprzez zastosowanie opcji MUTABLE

<activiti:formProperty id="ID:firPrefix;TYPE:FIRMATIC_FIELD;ARGS:{FIR_NAME:NumberPrefix, MUTABLE:true};" name="Prefix" type="string" />
Pole firmaticowe wyświetlane jako TextArea
<activiti:formProperty id="ID:firDescription;TYPE:FIRMATIC_FIELD;ARGS:{FIR_NAME:Description, FIELD_OPT:TEXTAREA};" name="Opis" type="string" />

Dodatkowy parametr w ARGS to FIELD_OPT.

Pole firmaticowe typu przycisk

Pole to tworzy na formatce przycisk o dowolnej nazwie. Jego kliknięcie powoduje wysłanie komunikatu do Firmatica.

<activiti:formProperty id="ID:firBtn;TYPE:FIRMATIC_SIGNAL;ARGS:{KEY:1097,CODEPROC:121};" name="Oferta" type="string" />
Pole workflow typu string
<activiti:formProperty id="ID:wp_o_1_comment;" name="Komentarz" type="string" required="true" />
Pole workflow typu string - wyświetlane jako TextArea
<activiti:formProperty id="ID:wp_o_1_comment;TYPE:TEXTAREA;" name="Komentarz" type="string" required="true" />
Pole wyboru użytkownika
<activiti:formProperty id="ID:PTP_boss;TYPE:FIRMATIC_USER;" name="Sekcja PTP" type="string" variable="PTP_boss" required="false" default="user:tadkob" />

W powyższym przykładzie wykorzystano atrybut variable, który zawsze musi mieć wartość taką jak „ID”. Jest on używany do przypisywania zadań do użytkowników za pomocą zmiennych.

Pole wyboru użytkownika z opcją DW

Jest to specjalne pole, które umożliwia dodanie nowej linii firmaticowej dla użytkownika, nawet jeżeli nie jest on przypisany do żadnego zadania.

<activiti:formProperty id="ID:dw_1;TYPE:FIRMATIC_USER;ARGS:DW:TRUE;" name="DW PT" type="string" variable="dw_1" required="false" writable="true" default="user:b" />
Pole wyboru użytkownika ze wskazaniem grupy oraz z wartością domyślną

Jest to pole wyboru użytkownika ze specjalnymi opcjami. Pierwszą z nich wskazanie listy z której można wybierać użytkowników. Drugim elementem jest wartość domyślna. Może ona zarówno określać pojedynczego użytkownika jak i całą listę.

<activiti:formProperty id="ID:user;TYPE:FIRMATIC_USER;ARGS:INNER_LIST:PTP-330;" name="Sekcja PTP-330" type="string" variable="user" required="false" writable="true" default="user:b" />
Pole wyświetlające linie 2 spraw
<activiti:formProperty id="ID:firLineAff0;TYPE:FIRMATIC_LINEAFF2;ARGS:{NUM:9, FIELD_OPT:TEXTAREA, FIELD_HEIGHT:100};" name="Komentarz do sprawy" type="string" writable="true" />
Pole typu radio button
<activiti:formProperty id="ID:nextStep;DEFAULT:;" name="Czy zakończyć?" type="enum" required="true" variable="nextStep">
	<activiti:value id="isEnd" name="Koniec sprawy" />
	<activiti:value id="answer" name="Odpowiedź do osoby" />
</activiti:formProperty>
Pole z historią zmian
<activiti:formProperty id="ID:firLog;TYPE:FIRMATIC_LINEAFF2_LOG;ARGS:{NUM:0, FIELD_OPT:TEXTAREA, FIELD_HEIGHT:100};ARGS2:{firDescription};" name="Historia zmian" type="string" writable="true" />
Pole z warunkową walidacją
<activiti:formProperty id="ID:worker;TYPE:FIRMATIC_USER;REQUIRED_IF_EXPR:{#is_to_board == 'false'};" name="Osoba odpowiedzialna" type="string" variable="worker" writable="true" />
Wartości domyślne w polach z użytkownikami

Przepływy i warunki

Ogólnie o przepływach i warunkach należy przeczytać w dokumentacji do Activiti.

W startEvent lub userTask można zdefiniować pole logiczne lub enum które będzie użyte w sterowaniu przepływem.

Przepływ po zmiennej logicznej

Najpierw w userTask definiujemy zmienną logiczną:

<activiti:formProperty id="ID:is_claim_valid;" name="Czy reklamacja zasadna?" type="boolean" variable="is_claim_valid" />

Następnie możemy zdefiniować warunek:

<sequenceFlow sourceRef="do_work" targetRef="after_worker_decision" />
 
<exclusiveGateway id="after_worker_decision" />
<sequenceFlow sourceRef="after_worker_decision" targetRef="claim_denied_work">
      <conditionExpression xsi:type="tFormalExpression">${is_claim_valid == 'false'}</conditionExpression>
</sequenceFlow>
 
<sequenceFlow sourceRef="after_worker_decision" targetRef="claim_accept_work">
      <conditionExpression xsi:type="tFormalExpression">${is_claim_valid == 'true'}</conditionExpression>
</sequenceFlow>

Przepływ po zmiennej enum

Najpierw w userTask definiujemy zmienną enum:

<activiti:formProperty id="ID:is_to_board_approval;DEFAULT:;" name="Czy skierować do zarządu?" type="enum" required="true" variable="is_to_board_approval">
	<activiti:value id="toBoard" name="Skierować do zarządu (ostateczne zatwierdzenie)" />
	<activiti:value id="sendToWorker" name="Do kolejnej osoby (opis pozycji)" />
</activiti:formProperty>

Następnie możemy zdefiniować warunek:

<sequenceFlow sourceRef="describe_invoice" targetRef="after_describe_decision" />
<exclusiveGateway id="after_describe_decision" default="after_describe_decision_flow3" />
 
<!-- do zatwierdzenia do zarządu -->
<sequenceFlow id="after_describe_decision_flow1" sourceRef="after_describe_decision" targetRef="board_approval">
	<conditionExpression xsi:type="tFormalExpression">${is_to_board_approval == 'toBoard'}</conditionExpression>
</sequenceFlow>
 
<!-- do kolejnego pracownika -->
<sequenceFlow id="after_describe_decision_flow3" sourceRef="after_describe_decision" targetRef="describe_invoice">
</sequenceFlow>