Workflow a procesy

Jak pracovat s nástrojem Activiti?

Lenka Haringerová avatar
Autor: Lenka Haringerová
Aktualizováno před více než týdnem

Pozn.: Máte-li zájem o funkcionalitu wokflow, je potřeba oslovit našeho integračního partnera ARIT a probrat s ním konkrétní možnosti nastavení a integrace.

Základem workflow a procesů je nástroj Activiti. Jeho součástí je programátorské rozhraní Activiti REST API Toto rozhraní je přístupné na této adrese:

/c/<identifikátor firmy>/activiti/

Existují tato omezení:

  • Není podporované rozhraní /login. Používá se autorizace ABRA Flexi.

  • Není podporovaná modifikace uživatelů, skupin a členství. Vše se dělá přes rozhraní ABRA Flexi.

  • Nahrání nového procesu musí být realizováno přes ABRA Flexi (kvůli definici platností workflow). Aktualizace procesů mohou být již přes Activiti API.

API pro ABRA Flexi

Výpis definicí workflow k dané evidenci:

GET /c/<identifikátor firmy>/<evidence>/workflows.xml

Spuštění workflow

PUT /c/<identifikátor firmy>/<evidence>/<id záznamu>/workflows/<processId>/start

Při spuštění je možné také předat parametry pro workflow, které možné použít při rozhodování:

PUT /c/<identifikátor firmy>/<evidence>/<id záznamu>/workflows/<processId>/start?parametr1=value1&parametr2=value2

Seznam událostí (poznámek a úkolů) u daného objektu:

/c/<identifikátor firmy>/<evidence>/<ID záznamu>/udalost

Vypsání událostí včetně dalších atributů workflow:

/c/<identifikátor firmy>/<evidence>/<ID záznamu>/udalost.xml?includes=udalost/actRuTask

Při práci s workflow chcete obvykle úkoly pouze určitého typu:

/c/<identifikátor firmy>/<evidence>/<ID záznamu>/udalost/(typUdalosti = 'druhUdal.workflow')


Výpis všech úkolů pro konkrétní workflow:

/c/<identifikátor firmy>/udalost/(typUdalosti = 'druhUdal.workflow' and processDefinitionId = '<processId>')


Výpis všech úkolů s daným klíčem úkolu pro konkrétní workflow:

/c/<identifikátor firmy>/udalost/(typUdalosti = 'druhUdal.workflow' and processDefinitionId = '<processId>' and taskDefinitionKey = '<taskKey>')


Výpis všech úkolů, které může aktuálně přihlášený uživatel vyřešit:

/c/<identifikátor firmy>/udalost@ukoly-k-realizaci


Zaslání signálu všem běžícím workflow, které na něj může reagovat:

/c/<identifikátor firmy>/<evidence>/<ID záznamu>/workflow-signal/<signalId>?param1=value


Zaslání zprávy všem běžícím workflow, které na něj může reagovat:

/c/<identifikátor firmy>/<evidence>/<ID záznamu>/workflow-message/<messageId>?param1=value


Práce s úkolem:

/c/<identifikátor firmy>/udalost/<ID záznamu>/<operace>

claim.xml

přivlastnit si úkol

unclaim.xml

odvlastnit si úkol

complete.xml
complete.xml?param1=value…
1)

vyřešit úkol

assign.xml?username=user
1)

předat úkol uživateli user

add-comment.xml?comment=text
1)
2)

přidat komentář k úkolu

  1. Pro hodnoty parametrů obsahující jiné než povolené znaky URL (mezera, zavináč atd.), je zapotřebí provést URL encoding.

  2. Kódování textů je očekáváno v UTF-8.

Poznámka: události, které jsou typu úkol pro workflow se zruší po tom co jsou vyřešeny. Místo .xml lze také použit .json nebo hlavičku Accept.

Seznam úkolů a k nim související objekty

/c/<identifikátor firmy>/<evidence>/<ID záznamu>/udalost.xml?includes=udalost/doklFak

Objekty použitelné při rozhodování ABRA Flexi

flexibee.user(username)

Vrací uživatele s uvedeným jménem

flexibee.userQuery(username)

Vrátí dotazovací objekt uživatele s uvedeným jménem (výstup je shodný s metodou objectQuery).

flexibee.object(evidenceType)

Vrátí objekt daného typu, který je připojen k úkolu workflow

flexibee.objectQuery(evidenceType).relation(relationName).filter(filter).list()

Umožňuje filtrovat objekty v relaci.

flexibee.objectQuery(evidenceType).relationFilter(relationName).filter(filter).one()

Umožňuje vrátit první objekt ve filtrované relaci.

flexibee.objectQuery(evidenceType).relationFilter(relationName).filter(filter).sum()

Umožňuje sečíst objekty ve filtrované relaci.

flexibee.objectQuery(evidenceType).relationFilter(relationName).filter(filter).firstQuery().relation(relationName2).one()

Umožňuje zřetězit zpracování dotazování.

flexibee.objectQuery(evidenceType).relation(relationName).list()

Umožňuje filtrovat objekty v relaci.

flexibee.objectQuery(evidenceType).relation(relationName).one()

Umožňuje vrátit první objekt v relaci.

flexibee.objectQuery(evidenceType).relation(relationName).sum()

Umožňuje sečíst objekty v relaci.

flexibee.wrap(object)

Obalí objekt pomocí query (stejný výsledek jako vrací např. objectQuery). Lze pak využít sadu funkcí, které nabází query.

flexibee.query(evidenceType).filter(filter).one()

Vrátí jeden objekt daného typu, který odpovídá uvedenému filtru.

flexibee.query(evidenceType).filter(filter).firstQuery().signal('signalName')

Vyvolá signál nad všemi workflow, které běží nad zvoleným záznamem.

flexibee.query(evidenceType).filter(filter).list()

Vrátí všechny objekty daného typu, který odpovídá uvedenému filtru.

flexibee.query(evidenceType).filter(filter).count()

Vrátí počet objektů daného typu, který odpovídá uvedenému filtru.

flexibee.query(evidenceType).filter(filter).sum(propertyName)

Vrátí sum daného sloupečku pro všechny objekty daného typu, který odpovídá uvedenému filtru.

flexibee.query(evidenceType).filter(filter).max(propertyName)

Vrátí max daného sloupečku pro všechny objekty daného typu, který odpovídá uvedenému filtru.

flexibee.query(evidenceType).filter(filter).min(propertyName)

Vrátí min daného sloupečku pro všechny objekty daného typu, který odpovídá uvedenému filtru.

flexibee.query(evidenceType).filter(filter).avg(propertyName)

Vrátí avg daného sloupečku pro všechny objekty daného typu, který odpovídá uvedenému filtru.

flexibee.query(evidenceType).asc(propertyName).first()

Umožní řazení vzestupně (více na řazení v API).

flexibee.query(evidenceType).desc(propertyName).first()

Umožní řazení sestupně (více na řazení v API).

flexibee.settings()

Vrátí aktuální nastavení firmy (evidence nastaveni). Název firmy lze tedy získat např. ${flexibee.settings().nazFirmy}

flexibee.settingsForDate(dt)

Vrátí nastavení firmy (evidence nastaveni) pro daný den (obvykle datum dokladu). Název firmy lze tedy získat např. ${flexibee.settingsForDate(dt).nazFirmy}

flexibee.varName(evidenceType)

Vrátí interní název proměnné, kterou používá ABRA Flexi pro vazbu jednotlivých workflow na doklady a objekty v ABRA Flexi. Používá se obvykle při volání podprocesu.

flexibee.isDesktop()

Vrátí true pokud workflow aktuálně běží v desktopové aplikaci

flexibee.isServer()

Vrátí true pokud workflow aktuálně běží přes REST API nebo v prohlížeči

flexibee.importXml(string)

Provede import XML řetězce dle ABRA Flexi REST API. Vrací kolekci identifikátorů objektů ze XML importu.

now

Aktuální datum a čas.

authenticatedUserId

Jméno aktuálně přihlášeného uživatele (pro více informací je nutné použít flexibee.user(authenticatedUserId) (více dokumentace acitiviti).

task

Záznam activiti, který reprezentuje úkol (více dokumentace acitiviti).

execution

Informace o aktuálně běžícím workflow (více dokumentace acitiviti).

Volání podprocesu

Pokud voláte podproces a chtete, aby výsledné úkoly byly provázány k dokladům, je nutné aktivovat propagaci vazební proměnné do workflow. To učiníte takto:

<?xml version="1.0"?>
<callActivity id="callSubProcess" calledElement="checkCreditProcess">
<extensionElements>
<activiti:in source="${flexibee.varName('faktura-prijata')}" target="${flexibee.varName('faktura-prijata')}"/>
<activiti:in source="initiator" target="initiator"/>
</extensionElements>
</callActivity>

Práce s uživateli ve workflow

Pokud chcete pracovat s uživateli, je několik následujících možností. Dejte si pozor, abyste v rámci definice uživatelů nepoužili znak čárky (,). Activiti má chybu, která zabraňuje jeho použití.

Původce workflow

Při startu workflow nadefinujte proměnnou initiator. Tu pak můžete použít jako název uživatele pro přidělení úkolu.

<startEvent id="theStart" activiti:initiator="initiator">

Aktuální uživatel

Pokud chcete úkol přidělit stejnému uživateli, který provedl aktuální operaci, použijte proměnnou authenticatedUserId.

Konkrétní uživatel

Při zpracování můžete použít konkrétního uživatele. Můžete také vyhledat uživatele podle určitých kritérií (např. štítek):

<formalExpression>${flexibee.query('uzivatele').relation('stitek = "code:PRACOVNIK"').one().kod}</formalExpression>


Nebo uživatelskou vazbu:

<formalExpression>${flexibee.userQuery(initiator).relation('uzivatelske-vazby').filter('typVazby = "code:NADRIZENY"').one().kod}</formalExpression>


Modifikace dokladů

Někdy je nutné při zpracování workflow modifikovat jeden nebo více dokladů. To lze provést použitím flexibee-xml. Aby metoda flexibee.object() fungovala, musí být workflow navázané na tento dokument.

<?xml version="1.0"?>
<serviceTask id="storno" activiti:class="flexibee-xml">
<extensionElements>
<activiti:field name="object" expression="${flexibee.object('faktura-vydana')}"/>
<activiti:field name="xml">
<activiti:expression>
<![CDATA[ <winstrom><faktura-vydana action="storno"></faktura-vydana></winstrom> ]]>
</activiti:expression>
</activiti:field>
</extensionElements>
</serviceTask>

Lze také modifikovat více objektů:

<?xml version="1.0"?>
<serviceTask id="storno" activiti:class="flexibee-xml">
<extensionElements>
<activiti:field name="xml">
<activiti:expression>
<![CDATA[ <winstrom><faktura-vydana action="storno"><id>code:FAV0001/2013</id></faktura-vydana><faktura-vydana action="storno"><id>code:FAV0002/2013</id></faktura-vydana></winstrom> ]]>
</activiti:expression>
</activiti:field>
</extensionElements>
</serviceTask>

Získání identifikátorů modifikovaných objektů

Pomocí proměnné idsVar lze získat kolekci identifikátorů, které byly modifikovány XML importem.

<?xml version="1.0"?>
<serviceTask id="import" activiti:class="flexibee-xml"> &#x2026;
<extensionElements>
<activiti:field name="idsVar" stringValue="seznamId"/>
</extensionElements>
</serviceTask>

Po úspěšně vykonaném XML importu pak bude proměnná seznamId obsahovat kolekci identifikátorů zmodifikovaných objektů.

Zpracování chyb při importu XML

Pokud nastane chyba při importu XML v tasku typu flexibee-xml, je zpracování workflow přerušeno výjimkou WSBusinessRTException. Výjimka obsahuje popis chyby a zobrazí se v GUI jako chybový dialog.

Pokud má workflow pokračovat i při chybě v importu, lze definici tasku rozšířit o parametry errorVar a errorMessageVar:

<?xml version="1.0"?>
<serviceTask id="storno" activiti:class="flexibee-xml"> &#x2026;
<extensionElements>
<activiti:field name="errorVar" stringValue="wasError"/>
<activiti:field name="errorMessageVar" stringValue="errorMessage"/>
</extensionElements>
</serviceTask>

proměnná

datový typ

popis

errorVar

Boolean

definuje název proměnné (např. wasError), kam se uloží příznak výskytu chyb při importu

errorMessageVar

String

definuje název proměnné (např. errorMessage), kam se uloží text popisující chyby importu

Podmíněné větvení na základě objektů

Ve workflow lze pokládat dotazy ABRA Flexi a reagovat na základě odpovědi:

${flexibee.object('objednavka-prijata').sumCelkem > 1000}

Lze se ptát i obecně, např. kolik neuhrazených faktur je u firmy, která je uvedena u aktuální faktury.:

${flexibee.query('faktura-vydana').filter('stavUhrK != "stavUhr.uhrazeno" and stavUhrK != "stavUhr.uhrazenoRucne" and firma='.concat(flexibee.object('faktura-vydana').firma.id)).sum('sumCelkem') > 1000}


Přenášení stavu workflow do dokladu

Někdy je nutné na základě stavu workflow měnit i stav dokladu. To lze realizovat pomocí štítků, které jsou přiděleny do jedné skupiny u které je nastavena exkluzivita (pak při nastavení nového štítku ze stejné skupiny dojde ke zrušení ostatních). Realizace je pak opět pomocí flexibee-xml, které zavoláte při každé změně stavu workflow:

<?xml version="1.0"?>
<serviceTask id="storno" activiti:class="flexibee-xml">
<extensionElements>
<activiti:field name="object" expression="${flexibee.object('faktura-vydana')}"/>
<activiti:field name="xml">
<activiti:expression>
<![CDATA[ <winstrom><faktura-vydana><stitky>SCHVÁLENO</stitky></faktura-vydana></winstrom> ]]>
</activiti:expression>
</activiti:field>
</extensionElements>
</serviceTask>
Dostali jste odpověď na svou otázku?