Categorie: workflows Bijgewerkt: 2026-05-26 workflow uct designer tutorial buttons

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

  1. Open het scherm in Ultimo (bijv. het Job-scherm)
  2. Klik op het ? icoon rechtsboven → kies Technical Screen Information
  3. Zoek het veld op in de lijst
  4. Noteer de Table (bijv. WOTask) en Column (bijv. WOT_DESCRIPTION)

Stap 2 — Entiteitnaam opzoeken via Screen Database Objectsbewerken

  1. Ga in UCT naar UCT > Screen Database Objects (of Screens > zoek het scherm > tab Database Objects)
  2. Zoek de tabel op (bijv. WOTask)
  3. Noteer de bijbehorende entiteitnaam (bijv. Job)

Stap 3 — Property naam opzoeken via Entity Overviewbewerken

  1. Ga in UCT naar Documentation > Entity Overview
  2. Zoek de entiteit op (bijv. Job)
  3. Zoek de kolom op (bijv. WOT_DESCRIPTION)
  4. 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

  1. Open UCT → navigeer naar Business Rules > Workflows
  2. Klik New
  3. Geef de workflow een naam volgens de naamconventie (zie workflow-engine#Workflow naamgeving)
    • Voorbeelden: Job_PostApproved, ETNCreateFollowUpJob (Standard type)
  4. Kies het juiste WorkflowType: ChangeStatus, Standard, Bulk, of Scheduled
  5. Sla op

Stap 2 — Variables definiëren in het Start-blokbewerken

  1. Klik op het Start-blok in de Visual Designer
  2. Ga naar het tabblad Properties in het Configuration Panel
  3. Voeg properties toe voor elk variabele (zie sectie Variables)

Stap 3 — Acties toevoegen vanuit de Toolboxbewerken

  1. Klik een actie in de Toolbox en sleep naar het canvas, of dubbelklik om toe te voegen na het geselecteerde blok
  2. Verbindings-pijlen worden automatisch aangemaakt
  3. Herhaal voor alle benodigde acties

Stap 4 — Elke actie configureren in het Configuration Panelbewerken

  1. Klik het actie-blok aan
  2. Vul de velden in het Configuration Panel in
  3. Gebruik ${variabelenaam} voor property-referenties, =#expressie() voor berekeningen

Stap 5 — Workflow publicerenbewerken

  1. Klik SavePublish
  2. Controleer op publicatiefouten in het resultaatvenster
  3. Zonder publiceren zijn wijzigingen niet actief

Stap 6 — Toevoegen aan de Application Element Treebewerken

  1. Ga in UCT naar Application Element Tree
  2. Zoek het juiste knooppunt voor de workflow (bijv. onder de entiteit of module)
  3. Voeg de workflow toe als element zodat rechten beheerd kunnen worden
  4. 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

  1. Open het relevante scherm in Ultimo
  2. Voer de actie uit die de workflow triggert
  3. Controleer het resultaat
  4. 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 Empty zijn voor je property chaining gebruikt. Een NullReferenceException is 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

  1. Ga in UCT naar Screens
  2. Zoek het juiste scherm (bijv. WOT01 voor het Job-overzichtsscherm)
  3. Open het scherm in de editor

Stap 2 — Knop toevoegen via het Buttons-tabbladbewerken

  1. Ga naar het tabblad Buttons
  2. Klik Add om een nieuwe knop toe te voegen
  3. Vul het Label in (de weergavenaam van de knop, bijv. Vervolgjob aanmaken)
  4. Sla op

Stap 3 — Knop-ID instellen (verplicht!)bewerken

  1. Ga naar het tabblad Settings van de knop
  2. Stel het ID in — dit is verplicht voor elke schermknop
  3. Gebruik altijd het prefix ETN gevolgd door een beschrijvende naam
    • Voorbeeld: ETNCreateFollowUpJob, ETNApproveAndNotify
  4. 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

  1. Ga naar het tabblad Action van de knop
  2. Kies als actie: Execute Workflow
  3. Stel de Relation in — dit is de entiteit waarvoor de workflow is (bijv. Job)
  4. Selecteer de workflow uit de lijst (bijv. ETNCreateFollowUpJob)
  5. Sla op

Stap 5 — Scherm publicerenbewerken

  1. Klik Publish op het schermniveau
  2. 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:

  1. Save — slaat de workflow op in de database (draft)
  2. Publish — maakt de workflow actief in Ultimo

Zonder publiceren zijn wijzigingen niet actief. Dit is de meest vergeten stap.

Testenbewerken

  1. Open het relevante scherm in Ultimo
  2. Voer de actie uit die de workflow triggert
  3. Controleer of het verwachte resultaat is bereikt
  4. Bij onverwacht gedrag: zie workflow-debugger

Individuele acties in-/uitschakelen voor debuggingbewerken

Je kunt afzonderlijke actie-blokken tijdelijk uitschakelen:

  1. Selecteer een actie-blok in de Visual Designer
  2. Klik rechtermuisknop → Disable
  3. Publiceer
  4. Test het resultaat
  5. 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

  1. Open de Workflow Debugger in UCT
  2. Klik Attach — de debugger verbindt zich met de Ultimo-sessie
  3. Voer de actie uit in Ultimo die de workflow triggert (bijv. klik de knop, wijzig de status)
  4. De workflow wordt geladen in de Debugger
  5. 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
  6. Inspectering in het Watch-paneel: bekijk de huidige waarden van alle properties
  7. 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:

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:

  1. Maak het doelveld leeg en attach de Debugger.
  2. Trigger de workflow opnieuw (zet Priority op Hoog) — de workflow laadt in de Debugger.
  3. Watch de doel-property (hier TargetDate) in het Watch-paneel.
  4. 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").
  5. 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:

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

Brondatabewerken

Dit artikel beschrijft workflow-concepten en -patronen. Voor de feitelijke workflow-XML van een specifieke trigger of ActionField: