Preskoči na glavno vsebino

Workflow a procesy

Ako pracovať s nástrojom Activiti?

Avtor: Lenka Haringerová

💡 Ak máte záujem o funkcionalitu workflow, je potrebné osloviť nášho integračného partnera ARIT a prebrať s ním konkrétne možnosti nastavenia a integrácie.

Základom workflow a procesov je nástroj Activiti. Jeho súčasťou je programátorské rozhranie Activiti REST API, ktoré je prístupné na tejto adrese:

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

Obmedzenia oproti štandardnému Activiti

  • Nie je podporované rozhranie /login. Používa sa autorizácia ABRA Flexi.

  • Nie je podporovaná modifikácia používateľov, skupín a členstva. Všetko sa robí cez rozhranie ABRA Flexi.

  • Nahratie nového procesu musí byť realizované cez ABRA Flexi (kvôli definícii platnosti workflow). Aktualizácie procesov už môžu prebiehať cez Activiti API.


API pre ABRA Flexi

Výpis definícií workflow k danej evidencii:

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

Spustenie workflow:

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

Pri spustení je možné tiež odovzdať parametre pre workflow, ktoré je možné použiť pri rozhodovaní:

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

Udalosti a úlohy

Zoznam udalostí (poznámok a úloh) pri danom objekte — ide o reláciu udalosti na konkrétnom zázname:

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

Výpis udalostí vrátane ďalších atribútov workflow:

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

⚠️ Relácia na zázname sa volá udalosti (množné číslo) — cesta …/<ID>/udalost vracia 404. Naopak samostatná evidencia, nad ktorou sa filtruje, je udalost v jednotnom čísle. Obe podoby teda platia, ale každá na inom mieste URL.

Pri práci s workflow zvyčajne chcete úlohy iba určitého typu. Typ udalosti nesie vlastnosť typAkt, čo je väzba na evidenciu typ-aktivity; úlohy workflow majú v tejto evidencii kód ÚKOL WORKFLOW:

/c/<identifikátor firmy>/<evidence>/<ID záznamu>/udalosti/(typAkt = 'code:ÚKOL WORKFLOW')

🚨 Vlastnosť typUdalosti ani hodnota druhUdal.workflow v tomto API neexistujú — takýto filter skončí chybou 400 s hlásením „Vlastnosť 'typUdalosti' neexistuje". Používajte typAkt. Alternatívne je možné úlohy workflow vybrať podľa processDefinitionId is not null.

Výpis všetkých úloh pre konkrétne workflow:

/c/<identifikátor firmy>/udalost/(typAkt = 'code:ÚKOL WORKFLOW' and processDefinitionId = '<processId>')

Výpis všetkých úloh s daným kľúčom úlohy pre konkrétne workflow:

/c/<identifikátor firmy>/udalost/(typAkt = 'code:ÚKOL WORKFLOW' and processDefinitionId = '<processId>' and taskDefinitionKey = '<taskKey>')

Výpis všetkých úloh, ktoré môže aktuálne prihlásený používateľ vyriešiť:

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

Zoznam úloh a k nim súvisiace objekty:

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

Signály a správy

Zaslanie signálu všetkým bežiacim workflow, ktoré naň môžu reagovať:

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

Zaslanie správy všetkým bežiacim workflow, ktoré na ňu môžu reagovať:

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

Práca s úlohou

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

Operácia

Význam

claim.xml

privlastniť si úlohu

unclaim.xml

odvlastniť si úlohu

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

vyriešiť úlohu

assign.xml?username=user 1)

odovzdať úlohu používateľovi user

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

pridať komentár k úlohe

  • 1) Pre hodnoty parametrov obsahujúce iné než povolené znaky URL (medzera, zavináč a pod.) je potrebné vykonať URL encoding.

  • 2) Kódovanie textov je očakávané v UTF-8.

ℹ️ Udalosti, ktoré sú typu úloha pre workflow, sa zrušia po tom, čo sú vyriešené. Namiesto .xml je možné tiež použiť .json alebo hlavičku Accept.


Objekty použiteľné pri rozhodovaní ABRA Flexi

Výraz

Popis

flexibee.user(username)

Vráti používateľa s uvedeným menom

flexibee.userQuery(username)

Vráti dotazovací objekt používateľa s uvedeným menom (výstup je zhodný s metódou objectQuery).

flexibee.object(evidenceType)

Vráti objekt daného typu, ktorý je pripojený k úlohe workflow

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

Umožňuje filtrovať objekty v relácii.

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

Umožňuje vrátiť prvý objekt vo filtrovanej relácii.

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

Umožňuje sčítať objekty vo filtrovanej relácii.

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

Umožňuje reťaziť spracovanie dotazovania.

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

Umožňuje filtrovať objekty v relácii.

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

Umožňuje vrátiť prvý objekt v relácii.

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

Umožňuje sčítať objekty v relácii.

flexibee.wrap(object)

Obalí objekt pomocou query (rovnaký výsledok ako vracia napr. objectQuery). Následne je možné využiť sadu funkcií, ktoré ponúka query.

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

Vráti jeden objekt daného typu, ktorý zodpovedá uvedenému filtru.

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

Vyvolá signál nad všetkými workflow, ktoré bežia nad zvoleným záznamom.

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

Vráti všetky objekty daného typu, ktoré zodpovedajú uvedenému filtru.

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

Vráti počet objektov daného typu, ktoré zodpovedajú uvedenému filtru.

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

Vráti súčet daného stĺpca pre všetky objekty, ktoré zodpovedajú filtru.

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

Vráti maximum daného stĺpca pre všetky objekty, ktoré zodpovedajú filtru.

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

Vráti minimum daného stĺpca pre všetky objekty, ktoré zodpovedajú filtru.

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

Vráti priemer daného stĺpca pre všetky objekty, ktoré zodpovedajú filtru.

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

Umožní zoradenie vzostupne.

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

Umožní zoradenie zostupne.

flexibee.settings()

Vráti aktuálne nastavenie firmy (evidencia nastaveni). Názov firmy je teda možné získať napr. ${flexibee.settings().nazFirmy}

flexibee.settingsForDate(dt)

Vráti nastavenie firmy pre daný deň (zvyčajne dátum dokladu), napr. ${flexibee.settingsForDate(dt).nazFirmy}

flexibee.varName(evidenceType)

Vráti interný názov premennej, ktorú používa ABRA Flexi na väzbu jednotlivých workflow na doklady a objekty. Používa sa zvyčajne pri volaní podprocesu.

flexibee.isDesktop()

Vráti true, ak workflow aktuálne beží v desktopovej aplikácii.

flexibee.isServer()

Vráti true, ak workflow beží cez REST API alebo v prehliadači.

flexibee.importXml(string)

Vykoná import XML reťazca podľa ABRA Flexi REST API. Vracia kolekciu identifikátorov objektov z XML importu.

Premenné

Premenná

Popis

now

Aktuálny dátum a čas.

authenticatedUserId

Meno aktuálne prihláseného používateľa. Pre viac informácií je potrebné použiť flexibee.user(authenticatedUserId) — pozri dokumentáciu Activiti.

task

Záznam Activiti, ktorý reprezentuje úlohu (pozri dokumentáciu Activiti).

execution

Informácie o aktuálne bežiacom workflow (pozri dokumentáciu Activiti).


Volanie podprocesu

Ak voláte podproces a chcete, aby výsledné úlohy boli previazané s dokladmi, je potrebné aktivovať propagáciu väzobnej premennej do workflow. Urobíte to takto:

<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áca s používateľmi vo workflow

Ak chcete pracovať s používateľmi, máte niekoľko nasledujúcich možností.

⚠️ Dajte si pozor, aby ste v rámci definície používateľov nepoužili znak čiarky (,). Activiti má chybu, ktorá bráni jeho použitiu.

Pôvodca workflow

Pri štarte workflow nadefinujte premennú initiator. Tú potom môžete použiť ako názov používateľa na priradenie úlohy.

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

Aktuálny používateľ

Ak chcete úlohu prideliť rovnakému používateľovi, ktorý vykonal aktuálnu operáciu, použite premennú authenticatedUserId.

Konkrétny používateľ

Pri spracovaní môžete použiť konkrétneho používateľa. Môžete tiež vyhľadať používateľa podľa určitých kritérií (napr. štítok):

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

Alebo používateľskú väzbu:

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


Modifikácia dokladov

Niekedy je potrebné pri spracovaní workflow modifikovať jeden alebo viac dokladov. To je možné vykonať pomocou flexibee-xml. Aby metóda flexibee.object() fungovala, musí byť workflow naviazané na tento dokument.

<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>

Je možné tiež modifikovať viac objektov:

<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ískanie identifikátorov modifikovaných objektov

Pomocou premennej idsVar je možné získať kolekciu identifikátorov, ktoré boli modifikované XML importom.

<serviceTask id="import" activiti:class="flexibee-xml">
…
<extensionElements>
<activiti:field name="idsVar" stringValue="seznamId" />
</extensionElements>
</serviceTask>

Po úspešne vykonanom XML importe bude premenná seznamId obsahovať kolekciu identifikátorov zmodifikovaných objektov.

Spracovanie chýb pri importe XML

Ak nastane chyba pri importe XML v tasku typu flexibee-xml, spracovanie workflow je prerušené výnimkou WSBusinessRTException. Výnimka obsahuje popis chyby a zobrazí sa v GUI ako chybový dialóg.

Ak má workflow pokračovať aj pri chybe v importe, je možné definíciu tasku rozšíriť o parametre errorVar a errorMessageVar:

<serviceTask id="storno" activiti:class="flexibee-xml">
…
<extensionElements>
<activiti:field name="errorVar" stringValue="wasError" />
<activiti:field name="errorMessageVar" stringValue="errorMessage" />
</extensionElements>
</serviceTask>

Premenná

Dátový typ

Popis

errorVar

Boolean

Definuje názov premennej (napr. wasError), kam sa uloží príznak výskytu chýb pri importe.

errorMessageVar

String

Definuje názov premennej (napr. errorMessage), kam sa uloží text popisujúci chyby importu.


Podmienené vetvenie na základe objektov

Vo workflow je možné klásť otázky ABRA Flexi a reagovať na základe odpovede:

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

Je možné pýtať sa aj všeobecne, napr. koľko neuhradených faktúr je u firmy, ktorá je uvedená pri aktuálnej faktúre:

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


Prenášanie stavu workflow do dokladu

Niekedy je potrebné na základe stavu workflow meniť aj stav dokladu. To je možné realizovať pomocou štítkov, ktoré sú pridelené do jednej skupiny, pri ktorej je nastavená exkluzivita (potom pri nastavení nového štítku z rovnakej skupiny dôjde k zrušeniu ostatných). Realizácia je potom opäť pomocou flexibee-xml, ktoré zavoláte pri každej zmene stavu workflow:

<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>


Súvisiace

Ste s tem dobili odgovor na svoje vprašanje?