Preskoči na glavno vsebino

Workflow a procesy

Ako pracovať s nástrojom Activiti?

Avtor: Lenka Haringerová

Pozn.: Ak máte záujem o funkcionalitu workflow, je potrebné osloviť nášho integračného partnera ARIT a prediskutovať 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. Toto rozhranie je dostupné na tejto adrese:

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

Existujú tieto obmedzenia:

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

  • Nahranie nového procesu musí byť realizované cez ABRA Flexi (kvôli definícii platností workflow). Aktualizácie procesov môžu byť už 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é možno použiť pri rozhodovaní:

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

Zoznam udalostí (poznámok a úloh) pri danom objekte:

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

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

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

Pri práci s workflow chcete zvyčajne úlohy iba určitého typu:

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


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

/c/<identifikátor firmy>/udalost/(typUdalosti = 'druhUdal.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/(typUdalosti = 'druhUdal.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


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>

claim.xml

prisvojiť si úlohu

unclaim.xml

zrušiť priradenie úlohy

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é ako povolené znaky URL (medzera, zavináč atď.) je potrebné vykonať URL encoding.

  2. Kódovanie textov sa očakáva v UTF-8.

Poznámka: udalosti, ktoré sú typu úloha pre workflow, sa zrušia po tom, čo sú vyriešené. Namiesto .xml možno tiež použiť .json alebo hlavičku Accept.

Zoznam úloh a k nim súvisiace objekty

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

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

flexibee.user(username)

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

flexibee.userQuery(username)

Vráti dopytovací 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 zreťaziť spracovanie dopytovania.

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). Možno potom 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 daného typu, ktoré zodpovedajú uvedenému filtru.

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

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

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

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

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

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

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

Umožní zoradenie vzostupne (viac na zoradenie v API).

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

Umožní zoradenie zostupne (viac na zoradenie v API).

flexibee.settings()

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

flexibee.settingsForDate(dt)

Vráti nastavenie firmy (evidencia nastaveni) pre daný deň (zvyčajne dátum dokladu). Názov firmy možno teda získať napr. ${flexibee.settingsForDate(dt).nazFirmy}

flexibee.varName(evidenceType)

Vráti interný názov premennej, ktorú používa ABRA Flexi pre väzbu jednotlivých workflow na doklady a objekty v ABRA Flexi. 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 aktuálne 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.

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) (viac dokumentácie acitiviti).

task

Záznam activiti, ktorý reprezentuje úlohu (viac dokumentácie acitiviti).

execution

Informácie o aktuálne bežiacom workflow (viac dokumentácie acitiviti).

Volanie podprocesu

Ak voláte podproces a chcete, aby výsledné úlohy boli previazané s dokladmi, je potrebné aktivovať propagáciu väzbovej premennej do workflow. Urobíte to 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áca s používateľmi vo workflow

Ak chcete pracovať s používateľmi, existuje 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á zabraňuje jeho použitiu.

Pôvodca workflow

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

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

Aktuálny používateľ

Ak chcete úlohu priradiť 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 možno vykonať použitím flexibee-xml. Aby metóda flexibee.object() fungovala, musí byť workflow naviazané 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>

Možno tiež modifikovať viac objektov:

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

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

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

Po úspešne vykonanom XML importe bude premenná seznamId obsahovať kolekciu identifikátorov modifikovaný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, možno definíciu tasku rozšíriť o parametre 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>

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 možno klásť dopyty ABRA Flexi a reagovať na základe odpovede:

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

Možno sa pýtať 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 možno realizovať pomocou štítkov, ktoré sú priradené do jednej skupiny, u ktorej je nastavená exkluzivita (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:

<?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>
Ste s tem dobili odgovor na svoje vprašanje?