Workflow Designer (UCT)
De Workflow Designer is onderdeel van de Ultimo Customisation Tool (UCT) en vormt de primaire werkplek voor het aanmaken en aanpassen van workflows. Dit artikel biedt een praktische stap-voor-stap gids voor consultants: van het openen van de designer tot het koppelen van een workflow aan een schermknop en het debuggen van het resultaat.
Zie workflow-engine voor de onderliggende werking van de workflow engine, en workflow-instructies voor alle beschikbare workflow-instructies.
Interfacebewerken
De Workflow Designer is opgedeeld in vier gebieden:
┌─────────────────────────────────────────────────────────────┐
│ Toolbar (knoppen: New, Save, Publish, Undo, Redo, ...) │
├──────────────────┬──────────────────────────────────────────┤
│ Toolbox │ Visual Designer │
│ ─────────────── │ ─────────────────────────────────────── │
│ Categorieën: │ Blokken met pijlen (visuele weergave) │
│ • Flow control │ │
│ • Data │ [Start] ──► [Actie 1] ──► [Actie 2] │
│ • UI/Dialog │ │
│ • Integration │ [XML] tab: direct XML bewerken │
│ • ... │ │
│ │ │
│ Documentatie │ │
│ (per actie) │ │
├──────────────────┴──────────────────────────────────────────┤
│ Configuration Panel (varieert per geselecteerde actie) │
└─────────────────────────────────────────────────────────────┘
Toolbar (linksboven)bewerken
Bevat standaardknoppen: New, Save, Publish, Undo/Redo, en publicatiestatus. Gebruik altijd Publish na het opslaan — zonder publicatie zijn wijzigingen niet actief in Ultimo.
Toolbox (links, onder toolbar)bewerken
Lijst van alle beschikbare actie-categorieën (Flow control, Data, UI, Integration, etc.). Klik een categorie open om de acties te zien. Elke actie heeft een inline documentatiepaneel met uitleg en voorbeeld-XML. Dit is de primaire referentie voor parameters en gebruik.
Visual Designer (rechts)bewerken
Het canvas waarop de workflow grafisch wordt weergegeven als blokken verbonden met pijlen. Klik een blok aan om het te selecteren en te configureren in het Configuration Panel. Via de XML-tab rechtsboven wissel je naar de ruwe XML-weergave — handig voor copy-paste en bulk-bewerkingen.
Configuration Panel (onder)bewerken
Toont de instellingen van het geselecteerde blok. De inhoud varieert per actie: een When-actie toont een conditieveld, een Insert-actie toont object-type en parameters. Alle wijzigingen hier worden direct in de XML verwerkt.
Entiteiten en Properties vertalenbewerken
Voordat je een workflow schrijft, moet je weten hoe een schermveld vertaalt naar een entity property. Dit doe je in drie stappen:
Stap 1 — Kolomnaam opzoeken via Technical Screen Informationbewerken
- Open het scherm in Ultimo (bijv. het Job-scherm)
- Klik op het ? icoon rechtsboven → kies Technical Screen Information
- Zoek het veld op in de lijst
- Noteer de Table (bijv.
WOTask) en Column (bijv.WOT_DESCRIPTION)
Stap 2 — Entiteitnaam opzoeken via Screen Database Objectsbewerken
- Ga in UCT naar UCT > Screen Database Objects (of Screens > zoek het scherm > tab Database Objects)
- Zoek de tabel op (bijv.
WOTask) - Noteer de bijbehorende entiteitnaam (bijv.
Job)
Stap 3 — Property naam opzoeken via Entity Overviewbewerken
- Ga in UCT naar Documentation > Entity Overview
- Zoek de entiteit op (bijv.
Job) - Zoek de kolom op (bijv.
WOT_DESCRIPTION) - Noteer de bijbehorende property name (bijv.
Description)
Resultaat: Het schermveld "Omschrijving" op het Job-scherm is in de workflow te benaderen als ${Job.Description}.
Consultant tip: Sla de Entity Overview op als bladwijzer — je gebruikt het bij elke workflow die je schrijft.
Workflow aanmaken — stap voor stapbewerken
Stap 1 — Workflow aanmaken in UCTbewerken
- Open UCT → navigeer naar Business Rules > Workflows
- Klik New
- Geef de workflow een naam volgens de naamconventie (zie workflow-engine#Workflow naamgeving)
- Voorbeelden:
Job_PostApproved,ETNCreateFollowUpJob(Standard type)
- Voorbeelden:
- Kies het juiste WorkflowType:
ChangeStatus,Standard,Bulk, ofScheduled - Sla op
Stap 2 — Variables definiëren in het Start-blokbewerken
- Klik op het Start-blok in de Visual Designer
- Ga naar het tabblad Properties in het Configuration Panel
- Voeg properties toe voor elk variabele (zie sectie Variables)
Stap 3 — Acties toevoegen vanuit de Toolboxbewerken
- Klik een actie in de Toolbox en sleep naar het canvas, of dubbelklik om toe te voegen na het geselecteerde blok
- Verbindings-pijlen worden automatisch aangemaakt
- Herhaal voor alle benodigde acties
Stap 4 — Elke actie configureren in het Configuration Panelbewerken
- Klik het actie-blok aan
- Vul de velden in het Configuration Panel in
- Gebruik
${variabelenaam}voor property-referenties,=#expressie()voor berekeningen
Stap 5 — Workflow publicerenbewerken
- Klik Save → Publish
- Controleer op publicatiefouten in het resultaatvenster
- Zonder publiceren zijn wijzigingen niet actief
Stap 6 — Toevoegen aan de Application Element Treebewerken
- Ga in UCT naar Application Element Tree
- Zoek het juiste knooppunt voor de workflow (bijv. onder de entiteit of module)
- Voeg de workflow toe als element zodat rechten beheerd kunnen worden
- Wijs rechten toe aan de relevante gebruikersgroepen
Zie configuration/application-element-tree voor details over de AET-structuur.
Stap 7 — Koppelen aan scherm (knop, veld, menu)bewerken
Zie sectie Workflow koppelen aan een schermknop.
Stap 8 — Testen in Ultimobewerken
- Open het relevante scherm in Ultimo
- Voer de actie uit die de workflow triggert
- Controleer het resultaat
- Bij fouten: gebruik de workflow-debugger of voeg
<Debug>instructies toe
Variables (Properties in Start Block)bewerken
Properties zijn de variabelen van een workflow. Ze worden gedeclareerd in het Start-blok via het Properties-tabblad. In de workflow worden ze aangesproken met ${variabelenaam}.
Attribuutveldenbewerken
| Attribuut | Waarden | Uitleg |
|---|---|---|
| Name | vrije naam | Gebruik een betekenisvolle naam, bijv. newJob, jobDescription, totalCost |
| Type | entiteit of datatype | Zie tabel hieronder |
| Accessor | Internal / Root / Required |
Bepaalt de herkomst van de waarde (zie tabel hieronder) |
| Direction | None / In |
Bepaalt of de waarde van buiten de workflow komt |
Type — veel gebruikte waardenbewerken
| Type | Gebruik |
|---|---|
Job |
Verwijzing naar een Job-record |
Equipment |
Verwijzing naar een Equipment-record |
Employee |
Verwijzing naar een Employee-record |
UltimoString |
Tekstveld |
Int32 |
Geheel getal |
Decimal |
Decimaal getal |
Boolean |
Waar/onwaar |
DateTime |
Datum en tijd |
List[Job] |
Lijst van Job-records |
Status? |
Nullable statusverwijzing |
Accessor — wanneer gebruik je wat?bewerken
| Accessor | Direction | Gebruik |
|---|---|---|
Internal |
None |
Interne variabele, wordt gevuld binnen de workflow zelf. Bijv. newJob voor een nieuw aan te maken Job. |
Root |
In |
Het hoofdobject van de schermcontext. Bijv. de Job die open staat als de gebruiker op een knop klikt. Vrijwel altijd de eerste property. |
Required |
In |
Moet door de aanroeper worden meegegeven. Typisch voor parameters die vanuit een andere workflow worden doorgegeven. |
Reference syntaxbewerken
| Syntax | Beschrijving | Voorbeeld |
|---|---|---|
${variabelenaam} |
Waarde van een property | ${Job.Description} |
${root.job.Equipment.Id} |
Property chaining via root | Navigeer van rootobject naar gerelateerd object |
=${expressie} |
Expressie als waarde | =#adddays(#{Environment.CurrentDate}, 7) |
#{Settings.Groep.Naam} |
Systeem- of procesinstelling | #{UltimoSettings.StockLevelPerSite} |
Property chaining voorbeeld:
<!-- Navigeer van Job naar Equipment naar locatie-ID -->
<Assign Name="Set location" Property="${targetLocation}" Value="${Job.Equipment.Location.Id}" />
Valkuil: Controleer altijd of tussenliggende objecten niet
Emptyzijn voor je property chaining gebruikt. EenNullReferenceExceptionis de meest voorkomende runtime-fout.
<When Name="Equipment aanwezig" Condition="${Job.Equipment} != Empty">
<Assign Name="Set location" Property="${targetLocation}" Value="${Job.Equipment.Location.Id}" />
</When>
Workflow koppelen aan een schermknopbewerken
Na het aanmaken en publiceren van een workflow koppel je deze aan een knop op een scherm via UCT > Screens.
Stap 1 — Scherm opzoekenbewerken
- Ga in UCT naar Screens
- Zoek het juiste scherm (bijv.
WOT01voor het Job-overzichtsscherm) - Open het scherm in de editor
Stap 2 — Knop toevoegen via het Buttons-tabbladbewerken
- Ga naar het tabblad Buttons
- Klik Add om een nieuwe knop toe te voegen
- Vul het Label in (de weergavenaam van de knop, bijv.
Vervolgjob aanmaken) - Sla op
Stap 3 — Knop-ID instellen (verplicht!)bewerken
- Ga naar het tabblad Settings van de knop
- Stel het ID in — dit is verplicht voor elke schermknop
- Gebruik altijd het prefix ETN gevolgd door een beschrijvende naam
- Voorbeeld:
ETNCreateFollowUpJob,ETNApproveAndNotify
- Voorbeeld:
- Het ID wordt gebruikt door de Application Element Tree voor rechtenbeheer
Valkuil: Een knop zonder ID werkt technisch, maar kan niet worden beheerd via de AET. Gebruik altijd het ETN-prefix en een unieke, beschrijvende naam.
Stap 4 — Actie koppelen via het Action-tabbladbewerken
- Ga naar het tabblad Action van de knop
- Kies als actie: Execute Workflow
- Stel de Relation in — dit is de entiteit waarvoor de workflow is (bijv.
Job) - Selecteer de workflow uit de lijst (bijv.
ETNCreateFollowUpJob) - Sla op
Stap 5 — Scherm publicerenbewerken
- Klik Publish op het schermniveau
- Test de knop in Ultimo
Volledig overzicht: tabbladen bij een schermknopbewerken
| Tabblad | Wat je hier instelt |
|---|---|
| General | Label, tooltip, icoon |
| Settings | ID (ETN-prefix!), zichtbaarheid, readonly-condities |
| Action | Actie-type (Execute Workflow), Relation, Workflow |
| Condition | Conditionele weergave (bijv. alleen tonen bij status Active) |
Default Workflows en User Content Blocksbewerken
Default workflows zijn beschermdbewerken
Standaard Ultimo-workflows hebben EditLevel="10" (alleen R&D) of ViewLevel="20" (consultants kunnen kijken, niet bewerken). Je kunt ze dus niet direct aanpassen. Zie workflow-engine#Security levels in detail.
User Content Blocks (UCB)bewerken
User Content Blocks zijn de aangewezen invoegpunten in standaard workflows waar consultants en klantbeheerders eigen logica kunnen toevoegen. Ze verschijnen als <UserContent Name="Pre" /> en <UserContent Name="Post" /> in de workflow-XML.
<Execution>
<UserContent Name="Pre" /> <!-- ← jouw logica vóór de standaard actie -->
<!-- Standaard Ultimo logica (niet aanpasbaar) -->
<Transaction>
<ChangeStatus Name="Change status" DomainObject="${Job}" NewStatus="${ChangeStatusTo}" />
</Transaction>
<UserContent Name="Post" /> <!-- ← jouw logica ná de standaard actie -->
</Execution>
UCBs worden opgeslagen als afzonderlijk bestand in de FileService: UserContent_{ActionFieldId}_{Pre|Post}.wfl. Bij een Ultimo-upgrade blijven UCBs behouden; de standaard workflow wordt overschreven.
Wanneer Pre vs Post?bewerken
| Situatie | Gebruik |
|---|---|
| Extra validatie toevoegen | Pre |
| Velden vullen voor de standaard actie | Pre |
| Record aanmaken na statuswijziging | Post |
| Email versturen na een actie | Post |
| Berekening op basis van resultaat standaard actie | Post |
Belangrijk: Properties worden NIET doorgegeven vanuit UCBbewerken
Properties die je declareert in een UCB, zijn niet automatisch beschikbaar in workflows die je vanuit die UCB aanroept via WorkflowCall. Je moet deze waarden expliciet als parameters meegeven:
<!-- In UCB: roep sub-workflow aan met expliciete parameter -->
<WorkflowCall Name="Roep sub-workflow aan" Workflow="ETNSendNotification">
<Parameter Name="TargetJob" Direction="In" Value="${Job}" />
<Parameter Name="Message" Direction="In" Value="${customMessage}" />
</WorkflowCall>
Publiceren en testenbewerken
Publicerenbewerken
Na elke wijziging in de Workflow Designer moet je publiceren:
- Save — slaat de workflow op in de database (draft)
- Publish — maakt de workflow actief in Ultimo
Zonder publiceren zijn wijzigingen niet actief. Dit is de meest vergeten stap.
Testenbewerken
- Open het relevante scherm in Ultimo
- Voer de actie uit die de workflow triggert
- Controleer of het verwachte resultaat is bereikt
- Bij onverwacht gedrag: zie workflow-debugger
Individuele acties in-/uitschakelen voor debuggingbewerken
Je kunt afzonderlijke actie-blokken tijdelijk uitschakelen:
- Selecteer een actie-blok in de Visual Designer
- Klik rechtermuisknop → Disable
- Publiceer
- Test het resultaat
- Enable de actie weer na het debuggen
Dit is handig om te isoleren welk deel van de workflow een probleem veroorzaakt.
Workflow Debuggerbewerken
De Workflow Debugger in UCT is een krachtig hulpmiddel voor het stap-voor-stap doorlopen van een workflow terwijl deze in Ultimo wordt uitgevoerd.
Locatiebewerken
UCT → Business Rules > Workflow Debugger
Gebruikbewerken
- Open de Workflow Debugger in UCT
- Klik Attach — de debugger verbindt zich met de Ultimo-sessie
- Voer de actie uit in Ultimo die de workflow triggert (bijv. klik de knop, wijzig de status)
- De workflow wordt geladen in de Debugger
- Gebruik de knoppen om stap voor stap door de acties te lopen:
- Step Over — voer de huidige actie uit, ga naar de volgende
- Step Into — stap in een aangeroepen sub-workflow
- Continue — door tot het volgende breakpoint
- Inspectering in het Watch-paneel: bekijk de huidige waarden van alle properties
- Stel breakpoints in door op het regelnummer te klikken — de workflow stopt automatisch op die regel
Breakpoints instellenbewerken
Klik op het regelnummer naast een actie-blok in de XML-weergave van de Debugger. Een rode markering verschijnt. De workflow pauzeert wanneer die actie bereikt wordt, zodat je de property-waarden kunt inspecteren.
Watch-paneelbewerken
Het Watch-paneel toont alle properties met hun huidige waarden op het moment van pauze. Dit geeft direct inzicht in:
- Of een property de verwachte waarde heeft
- Of een conditie correct evalueert
- Of een Insert-actie een nieuw object heeft aangemaakt
Recept: achterhalen welke (sub-)workflow een veld vultbewerken
Bij een onbekende of standaard-workflow wil je vaak weten welk deel een bepaald veld vult. Voorbeeld: het zetten van Priority op "Hoog" vult automatisch de TargetDate (gereed-datum) — maar via welke actie? Zo achterhaal je dat:
- Maak het doelveld leeg en attach de Debugger.
- Trigger de workflow opnieuw (zet Priority op Hoog) — de workflow laadt in de Debugger.
- Watch de doel-property (hier
TargetDate) in het Watch-paneel. - Zet twee breakpoints rond de verdachte actie: één vlak vóór en één vlak ná de WorkflowCall die je verdenkt (bijv. een sub-workflow "set planning dates by priority").
- Stap door tot het eerste breakpoint en lees de gewatchte property; ga dan voorbij de WorkflowCall en kijk of de waarde nu gevuld is. Verandert hij precies daar, dan heb je de verantwoordelijke sub-workflow gevonden.
Dit is de standaardmanier om een default-workflow te begrijpen vóór je hem uitbreidt: zodra je weet welke sub-workflow het werk doet, kun je die hergebruiken via een eigen WorkflowCall en profiteer je van Ultimo-onderhoud op die standaard-workflow.
Waarschuwing: nooit in productie activerenbewerken
KRITIEK: Activeer de Workflow Debugger NOOIT in een productieomgeving. De debugger pauzeert de workflow en wacht op input — dit blokkeert andere gebruikers die dezelfde actie uitvoeren. Gebruik de debugger uitsluitend in Development- of Test-omgevingen.
Zie workflow-debugger voor het volledige artikel over debugging-technieken en veelvoorkomende fouten.
Tips en valkuilenbewerken
Case-sensitive waardenbewerken
Status- en contextwaarden zijn case-sensitive. Gebruik altijd de exacte schrijfwijze zoals die in de documentatie of de Status Matrix staat.
<!-- FOUT -->
<When Condition="${Job.Status} == JobStatus.created">
<!-- GOED -->
<When Condition="${Job.Status} == JobStatus.Created">
Transaction verplicht voor database-operatiesbewerken
Alle acties die de database lezen of schrijven (GetList, Insert, Assign op een domain object, ChangeStatus) moeten binnen een <Transaction> blok staan.
<!-- FOUT -->
<Insert Name="Maak job aan" ObjectType="Job" OutputProperty="${newJob}">
...
</Insert>
<!-- GOED -->
<Transaction>
<Insert Name="Maak job aan" ObjectType="Job" OutputProperty="${newJob}">
...
</Insert>
</Transaction>
Dialog Container verplicht als wrapper voor invoerveldenbewerken
Als je een dialoog wilt tonen met invoervelden (bijv. een tekstveld of een dropdown), moet de dialoog een <DialogContainer> als wrapper hebben.
<Dialog Name="VraagGebruiker" TitleCode="CONFIRM">
<DialogContainer Name="Container">
<Text Name="Reden" OutputProperty="${reden}" LabelCode="REASON" Required="True" />
</DialogContainer>
</Dialog>
Button ID (ETN-prefix) verplichtbewerken
Schermknoppen zonder ID kunnen niet worden opgenomen in de Application Element Tree en zijn daarmee niet beheersbaar via rechten. Gebruik altijd het ETN-prefix:
- Goed:
ETNCreateFollowUpJob - Fout:
CreateJob,btn_1, (leeg)
Publiceren niet vergetenbewerken
Na elke wijziging in een workflow of scherm moet je publiceren. Veel "waarom werkt dit niet"-vragen zijn te herleiden tot vergeten publiceren.
ActionField workflows niet direct aanroepenbewerken
Workflows die gekoppeld zijn aan een ActionField (een standaard knop/actie in Ultimo, bijv. ActionField025 voor "Job goedkeuren") mogen niet direct worden aangeroepen via WorkflowCall. Maak in plaats daarvan een aparte Standard-workflow met de gedeelde logica, en roep die aan:
<!-- FOUT: directe aanroep van ActionField-workflow -->
<WorkflowCall Name="..." Workflow="ActionField025" />
<!-- GOED: sub-workflow met de gedeelde logica -->
<WorkflowCall Name="..." Workflow="ETNGedeeldeLogica">
<Parameter Name="Job" Direction="In" Value="${Job}" />
</WorkflowCall>
Assign vs ChangeStatus: gebruik altijd ChangeStatus voor statuswijzigingenbewerken
Assign op een statusproperty wijzigt de waarde in de database, maar omzeilt de Status Matrix — Pre/Post workflows worden niet uitgevoerd en de statusovergang is inconsistent.
<!-- FOUT: omzeilt Status Matrix en Pre/Post workflows -->
<Assign Name="Zet status" Property="${Job.Status}" Value="JobStatus.Active" />
<!-- GOED: doorloopt Status Matrix en Pre/Post workflows correct -->
<Transaction>
<ChangeStatus Name="Activeer job" DomainObject="${Job}" NewStatus="JobStatus.Active" />
</Transaction>
Volledig voorbeeld: Standard workflow voor een schermknopbewerken
Het onderstaande voorbeeld toont een complete Standard-workflow die via een schermknop een vervolgjob aanmaakt op basis van de huidige job.
<Workflow Name="ETNCreateFollowUpJob" Version="2026.04.09" WorkflowType="Standard"
AllowUserInteraction="True"
xmlns="urn:Ultimo.Framework.Workflow-mapping">
<Security EditLevel="30" ViewLevel="30" UserContentLevel="30" />
<Description>Maakt een vervolgjob aan op basis van de huidige job (schermknop)</Description>
<Properties>
<!-- Root: de Job die open staat op het scherm -->
<Property Name="Job" Type="Job" Accessor="Root" Direction="In" />
<!-- Internal: de nieuw aan te maken Job -->
<Property Name="NewJob" Type="Job" Accessor="Internal" />
<!-- Internal: invoer van gebruiker via dialoog -->
<Property Name="Reden" Type="UltimoString" Accessor="Internal" />
</Properties>
<Execution>
<!-- Stap 1: Vraag de gebruiker om een reden -->
<Dialog Name="VraagReden" TitleCode="CONFIRM">
<DialogContainer Name="Container">
<Text Name="Reden invoer"
OutputProperty="${Reden}"
LabelCode="REASON"
Required="True" />
</DialogContainer>
</Dialog>
<!-- Stap 2: Valideer dat Equipment aanwezig is -->
<Validation Name="Equipment verplicht"
Condition="${Job.Equipment} != Empty"
MessageCode="9001" />
<!-- Stap 3: Maak de vervolgjob aan -->
<Transaction>
<Insert Name="Maak vervolgjob" ObjectType="Job" OutputProperty="${NewJob}">
<Parameter Name="Status" Direction="In" Value="JobStatus.Created" />
<Parameter Name="Description" Direction="In" Value="Vervolg: ${Job.Description}" />
<Parameter Name="Equipment" Direction="In" Value="${Job.Equipment}" />
<Parameter Name="Department" Direction="In" Value="${Job.Department}" />
<Parameter Name="Site" Direction="In" Value="${Job.Site}" />
<Parameter Name="Remarks" Direction="In" Value="${Reden}" />
<Parameter Name="ScheduledStartDate" Direction="In"
Value="=#adddays(#{Environment.CurrentDate}, 7)" />
</Insert>
</Transaction>
<!-- Stap 4: Bevestig aan gebruiker -->
<Message Name="Bevestiging"
TitleCode="SUCCESS"
MessageCode="9002" />
</Execution>
</Workflow>
Gerelateerde artikelenbewerken
- workflow-engine — Triggers, werkwijze, transacties en UserContent
- workflow-instructies — Alle beschikbare instructies met XML-voorbeelden
- workflow-patronen — Veelvoorkomende praktijkpatronen
- workflow-debugger — Debugger: gebruik, breakpoints en veelvoorkomende fouten
- expressions — Expression functies en operators
- uct-overzicht — Overzicht van de Ultimo Customisation Tool
Brondatabewerken
Dit artikel beschrijft workflow-concepten en -patronen. Voor de feitelijke workflow-XML van een specifieke trigger of ActionField:
- Workflow opvragen —
lookup_workflow("<WorkflowName>")Volledige workflow-XML incl. properties en CurrentValue. Bron:workflows.xml. - Workflows doorzoeken —
find_workflows(query, entity=None)Fuzzy zoeken op naam, beschrijving of per entiteit. Bron:workflows.xml. - Alle ActionFields als index — ActionFields index
1341 gegenereerde pagina's, één per ActionField. Bron:
workflows.xml. - Entiteit-definities voor referenties in workflows —
lookup_entity("<Name>")Properties en kolomnamen van entiteiten waarnaar workflows verwijzen. Bron:Entities.xml. - Kennisbank-breed zoeken —
search(query)Doorzoekt alle wiki + reference + workflows tegelijk.