Categorie: workflows Bijgewerkt: 2026-04-15 workflow instructies xml assign transaction email

Workflow Instructies

Dit artikel documenteert alle beschikbare workflow instructies in Ultimo. Instructies zijn de bouwstenen van workflows: elke XML-tag binnen een <Execution> blok is een instructie. Ze zijn gegroepeerd per categorie. Zie workflow-engine voor de algemene opzet van workflows en expressions voor expression functies.


Commonbewerken

Basis instructies die in vrijwel elke workflow voorkomen.

Assignbewerken

Wijs een waarde toe aan een property van een domain object. Kan binnen en buiten een #Transaction gebruikt worden. Binnen een Transaction worden wijzigingen naar de database geschreven; buiten een Transaction alleen in het geheugen.

Let op: Gebruik Assign NIET om een status te wijzigen. Gebruik daarvoor #ChangeStatus zodat de Status Matrix en Pre/Post workflows correct worden doorlopen.

<!-- Binnen Transaction: wijzigt het domain object in de database -->
<Transaction>
    <Assign Name="Set Job.Description" Property="${Job.Description}" Value="${Job.FeedbackDescription}" />
    <Assign Name="Set DateTime" Property="${Job.PmWorkOrder.LastMaintenanceDate}" Value="${Job.FinishedDate}" />
    <Assign Name="Reset Preference" Property="${PreferredVendor.Preference}" Value="True" />
</Transaction>

<!-- Buiten Transaction: wijzigt alleen een interne property -->
<Assign Name="Set Cost property Empty" Property="${Cost}" Value="Empty" />

Attributen:


AssignTextbewerken

Wijs een String-waarde toe aan een property, specifiek voor meertalige omgevingen. Gebruik dit wanneer je een "multilingual", "neutral" of "string" waarde naar een ander type wilt converteren.

<Transaction>
    <AssignText Name="Set Job.Description" Property="${Job.Description}"
        Value="${KnowledgeTopic.Description}" SourceLanguage="EN-US" TargetLanguage="EN" />
</Transaction>

Extra attributen:


AssignWhenEmptybewerken

Wijs een waarde toe ALLEEN als de property nog leeg is. Handig voor standaardwaarden die niet overschreven mogen worden.

<AssignWhenEmpty Name="Set HoursEmployee if still empty"
    Property="${HoursEmployee}" Value="${Employee}" />

Commandbewerken

Voer een voorgedefinieerd commando uit. Commands zijn ingebouwde functionaliteitsblokken in Ultimo die niet als losse instructies beschikbaar zijn.

<Command Name="Job_CreateAndInitialize" CommandName="Job_CreateAndInitialize">
    <Parameter Name="JobCreateMethod" Direction="In"  Value="CreateApproved" />
    <Parameter Name="Job"             Direction="Out"  OutputProperty="${Job}" />
</Command>

Attributen:


Commentbewerken

Voeg commentaar toe aan de workflow XML. Wordt niet uitgevoerd maar verbetert de leesbaarheid.

<Comment Comment="Korte beschrijving"><![CDATA[Uitgebreide uitleg van het proces]]></Comment>

CreateObjectbewerken

Maak een nieuw object-instantie aan, zoals een Dictionary of Status. Niet gebruiken voor domain objects - gebruik daarvoor #Insert.

<CreateObject Name="Create status" ObjectType="Status" OutputProperty="${Status}" />
<CreateObject Name="Create dictionary" ObjectType="Dictionary[String]" OutputProperty="${StopFilter}" />

SingleItemValidationbewerken

Valideer dat een lijst precies een element bevat. Als de lijst meer elementen bevat, wordt de workflow afgebroken met een foutmelding.

<SingleItemValidation Name="Get Single Item"
    List="${ArticleSiteVendors}" OutputProperty="${ArticleSiteVendor}"
    MessageCode="0000" AllowEmpty="True" />

Attributen:


Togglebewerken

Inverteer een Boolean waarde: True wordt False en vice versa.

<Toggle Name="Toggle RegisterStock" Property="${Article.RegisterStock}" />

UserContentbewerken

Uitbreidingspunt in een workflow waar consultants en klantbeheerders eigen logica kunnen toevoegen. Zie UserContent in de workflow engine.

<UserContent Name="Pre" />
<!-- ... standaard logica ... -->
<UserContent Name="Post" />

Consultant tip: Voor Bulk workflows moet UserContent een child van ForEach zijn.


Validationbewerken

Controleer een conditie. Als de conditie false retourneert, wordt de workflow afgebroken en een foutmelding getoond.

<Validation Name="Equipment verplicht"
    Condition="${Job.Equipment} != Empty" MessageCode="9001">
    <Parameter Name="Job" Direction="In" Value="${Job}" />
</Validation>

<Validation Name="Check threshold"
    Condition="${TotalThreshold} + ${AbcCode.Threshold} &lt;= 100" MessageCode="3844">
    <Parameter Name="AbcCode" Direction="In" Value="${AbcCode}" />
</Validation>

Attributen:

Consultant tip: Validation is ideaal in UserContent Pre om extra controles toe te voegen voor een statuswijziging.


Flow controlbewerken

Instructies voor conditionele logica, lussen en flow control.

Whenbewerken

Conditionele uitvoering: de instructies binnen When worden alleen uitgevoerd als de conditie true is. Buiten een Choose gedraagt When zich als een if. Binnen een Choose als een case.

<!-- Standalone if -->
<When Name="Status change requested" Condition="${ChangeStatusTo} != Empty">
    <ChangeStatus Name="Change status" DomainObject="${Job}" NewStatus="${ChangeStatusTo}" />
</When>

<!-- Met property vergelijking -->
<When Name="Is preferred vendor" Condition="${PreferredVendor.Preference} == True">
    <WorkflowCall Name="GetPreferredVendor" WorkflowName="ArticleSiteVendor_GetPreferredVendor">
        <Parameter Name="PreferredVendor" Direction="In" Value="${PreferredVendor}" />
    </WorkflowCall>
</When>

Choose / Otherwisebewerken

If-elseif-else constructie. De eerste When waarvan de conditie true is wordt uitgevoerd. Als geen enkele When matcht, wordt Otherwise uitgevoerd.

<Choose Name="Bepaal actie">
    <When Name="X is 1" Condition="${x} == 1">
        <Assign Name="Set result" Property="${Result}" Value="1" />
    </When>
    <When Name="X is 2" Condition="${x} == 2">
        <Assign Name="Set result" Property="${Result}" Value="2" />
    </When>
    <Otherwise Name="Overig">
        <Assign Name="Set result" Property="${Result}" Value="0" />
    </Otherwise>
</Choose>

ChooseUserInteractionbewerken

Splits logica op basis van of er gebruikersinteractie beschikbaar is. Belangrijk voor workflows die zowel vanuit de UI als vanuit achtergrondprocessen (import, scheduler) kunnen draaien.

<ChooseUserInteraction Name="UI beschikbaar?">
    <WithUserInteraction Name="Met UI">
        <Dialog Name="ShowDialog" TitleCode="CONFIRM" />
    </WithUserInteraction>
    <WithoutUserInteraction Name="Zonder UI">
        <Assign Name="Standaard" Property="${Job.Description}" Value="${Job.FeedbackDescription}" />
    </WithoutUserInteraction>
</ChooseUserInteraction>

ForEachbewerken

Itereer over een lijst van items. De As property wordt automatisch aangemaakt binnen de loop en bestaat niet meer na afloop.

<ForEach Name="Keur werkorders goed" In="${CreatedWorkOrders}" As="NewWorkOrder">
    <ChangeStatus Name="Approve" DomainObject="${NewWorkOrder}" NewStatus="WorkOrderStatus.Approved" />
</ForEach>

<!-- Met conditie (filter binnen de loop) -->
<ForEach Name="Loop items" In="${AbcDeterminationList}" As="AbcDetermination"
    Condition="${AbcDetermination.Processed} == False &amp;&amp; ${Continue} == True">
    <!-- acties -->
</ForEach>

Attributen:

Patroon: bulk statuswijziging

Een veelvoorkomend patroon is het ophalen van een lijst via GetList en vervolgens de status van elk item wijzigen via ForEach + ChangeStatus:

<!-- Stap 1: haal de lijst op -->
<Transaction>
    <GetList Name="Haal te verwijderen equipment op" Type="Equipment"
        OutputProperty="${equipmentList}" OrderBy="Id">
        <Filters>
            <PropertyFilter PropertyName="Status" Operator="=" PropertyValue="EquipmentStatus.OutOfService" />
        </Filters>
    </GetList>
</Transaction>

<!-- Stap 2: verwerk elk item -->
<ForEach Name="Verwerk equipment" In="${equipmentList}" As="${equipmentItem}">
    <Transaction>
        <ChangeStatus Name="Zet naar ToDelete"
            DomainObject="${equipmentItem}"
            NewStatus="EquipmentStatus.ToDelete" />
    </Transaction>
</ForEach>

Consultant tip: Elke ChangeStatus binnen een ForEach heeft zijn eigen Transaction nodig zodat statusfouten op itemniveau worden afgehandeld zonder de hele loop af te breken.


Whilebewerken

Herhaal een blok totdat een conditie niet meer waar is. Heeft een cycle limit als beveiliging tegen oneindige lussen.

<While Name="Verwijder regels" Condition="${AllDeleted} == False" CycleLimit="2500">
    <Transaction>
        <GetList Name="Get batch" Type="InternalChargeLine" OutputProperty="${Lines}"
            OrderBy="Id" Top="${BatchSize}">
            <Filters>
                <PropertyFilter PropertyName="Id.InternalCharge" Operator="=" PropertyValue="${InternalCharge}" />
            </Filters>
        </GetList>
        <When Name="Geen regels meer" Condition="${Lines.Count} == 0">
            <Assign Name="Klaar" Property="${AllDeleted}" Value="True" />
        </When>
        <ForEach Name="Delete" In="${Lines}" As="Line">
            <DeleteObject Name="Delete" DomainObject="${Line}" />
        </ForEach>
    </Transaction>
</While>

Attributen:


Counterbewerken

Verhoog een numerieke property met een stapgrootte. Equivalent aan Assign met een expressie.

<Counter Name="index" Property="${index}" Step="2" />
<Counter Name="index terug" Property="${index}" Step="-2" />

Stopbewerken

Beeindig de workflow. Verschillende modi beschikbaar:

Mode Effect
Abort Stopt alle parent workflows, rollback transaction
EndAll Beeindig huidige en parent workflows, resultaat is succesvol
EndCurrent Beeindig alleen de actieve workflow
EndUserContent Beeindig alleen de UserContent sectie
<Stop Name="Stop" Mode="Abort" />
<Stop Name="Klaar" Mode="EndAll" />

WhenFeatureTogglebewerken

Controleer of een feature toggle actief is.

<WhenFeatureToggle Name="Check feature" Feature="ExampleFeature" />

WorkflowCallbewerken

Roep een andere workflow aan. Parameters worden doorgegeven via In/Out/InOut.

<WorkflowCall Name="Initialiseer job" WorkflowName="Job_CreateAndInitialize">
    <Parameter Name="JobCreateMethod" Direction="In"  Value="CreateApproved" />
    <Parameter Name="Job"             Direction="Out"  OutputProperty="${Job}" />
</WorkflowCall>

Attributen:

Consultant tip — ActionField workflows: Workflows waarvan de naam begint met ActionField (bijv. ActionField286) zijn container-workflows die Ultimo intern gebruikt om schermknoppen te koppelen. Roep deze nooit direct aan via WorkflowCall. Open in plaats daarvan de ActionField workflow in de Workflow Designer, zoek de sub-workflow erin die de gewenste logica bevat, en roep díe sub-workflow aan. De ActionField-wrapper bevat vaak dialogen en context-logica die niet relevant zijn als je de functionaliteit programmatisch aanroept.


Databasebewerken

Instructies voor database-operaties. Moeten altijd binnen een Transaction staan.

Transactionbewerken

Container voor alle database-operaties. Zonder Transaction kunnen GetList, Insert, ChangeStatus etc. niet worden gebruikt.

<Transaction>
    <Insert Name="Insert" ObjectType="Job" OutputProperty="${NewJob}">
        <Parameter Name="Status" Direction="In" Value="JobStatus.Created" />
    </Insert>
</Transaction>

Attributen:

Consultant tip: Gebruik ReadCommitted alleen bij bekende locking/performance problemen.


Insertbewerken

Maak een nieuw domain object aan in de database. De Id wordt automatisch gegenereerd als autokey actief is.

<Insert Name="Insert Incident" ObjectType="Incident" OutputProperty="${Incident}">
    <Parameter Name="Context"       Direction="In" Value="${IncidentContext}" />
    <Parameter Name="Status"        Direction="In" Value="IncidentStatus.None" />
    <Parameter Name="Description"   Direction="In" Value="${Job.Description}" />
    <Parameter Name="ReportDate"    Direction="In" Value="${Job.StatusCreatedReportDate}" />
    <Parameter Name="ReportEmployee" Direction="In" Value="${Job.ReportForeignKeyEmployee}" />
    <Parameter Name="Site"          Direction="In" Value="${Job.Site}" />
</Insert>

Attributen:

Praktische tips — parameter voorbeelden:

<Transaction>
    <Insert Name="Nieuwe job aanmaken" ObjectType="Job" OutputProperty="${newJob}">
        <Parameter Name="Status"      Direction="In" Value="JobStatus.Created" />
        <Parameter Name="Context"     Direction="In" Value="jobContext.cd" />
        <Parameter Name="Description" Direction="In" Value="${omschrijving}" />
        <Parameter Name="Site"        Direction="In" Value="${Job.Site}" />
    </Insert>
</Transaction>

Consultant tip: Geef altijd minimaal Status én Context mee bij een Insert. Zonder Context kan Ultimo de juiste schermen, rechten en procesflows niet bepalen, wat tot onverwacht gedrag leidt.


Updatebewerken

Werk meerdere properties van een domain object bij in een instructie. Vervangt meerdere Assign instructies.

<Update Name="SetJobProperties" DomainObject="${Job}">
    <Parameter Name="Context" Direction="In" Value="JobContext.TD" />
    <Parameter Name="Status"  Direction="In" Value="JobStatus.Created" />
</Update>

Copybewerken

Kopieer properties van het ene domain object naar het andere. De objecten hoeven niet van hetzelfde type te zijn, maar de property-namen en datatypes moeten overeenkomen.

<Copy Name="Copy CustomColumns" Source="${Job.ServiceDeskReportType}" Target="${Job}"
    CopyType="OnlySetIfEmpty" CustomOnly="True" />

Attributen:


ChangeStatusbewerken

Wijzig de status van een domain object via de Status Matrix. De matrix bepaalt of de overgang is toegestaan en welke Pre/Post workflows worden uitgevoerd.

<ChangeStatus Name="Activate" DomainObject="${Job}" NewStatus="JobStatus.Active" />
<ChangeStatus Name="Copy status" DomainObject="${Job2}" NewStatus="${Job1.Status}" />

Attributen:

Belangrijk: Gebruik ALTIJD ChangeStatus voor statuswijzigingen — gebruik nooit Assign om een statusproperty direct te overschrijven. ChangeStatus doorloopt de Status Matrix (controleert of de overgang is toegestaan), voert Pre/Post workflows uit en registreert de statushistorie. Een Assign omzeilt al deze validaties en achtergrondbewerkingen, wat leidt tot inconsistente data en ontbrekende history-regels.


DeleteObjectbewerken

Verwijder een domain object. Dit omvat trash + delete, inclusief Pre/Post workflows.

Volgorde: StatusMatrix validatie -> PreTrash -> Status naar Trash -> PostTrash -> PreDelete -> Daadwerkelijke delete.

<DeleteObject Name="Delete" DomainObject="${Job}" />

TrashObjectbewerken

Markeer een domain object als verwijderd (soft delete). Het object kan nog hersteld worden.

<TrashObject Name="TrashJob" DomainObject="${Job}" />

UntrashObjectbewerken

Herstel een naar de prullenbak verplaatst domain object.

<UntrashObject Name="UntrashJob" DomainObject="${Job}" />

GetItembewerken

Haal exact een domain object op uit de database. Het resultaat MOET precies 1 record bevatten.

<GetItem Name="Get default status" Type="DefaultProgressStatusContextRecordStatus"
    OutputProperty="${DefaultStatus}">
    <Filters>
        <PropertyFilter PropertyName="Id.DefaultProgressStatusContext.Id"
            Operator="=" PropertyValue="${Job.ServiceDeskReportType.SetContext}" />
        <PropertyFilter PropertyName="Id.Status" Operator="=" PropertyValue="1" />
    </Filters>
</GetItem>

Praktische tips:

<GetItem Name="Haal equipment op via job" Type="Equipment"
    OutputProperty="${gekoppeldEquipment}">
    <Filters>
        <PropertyFilter PropertyName="Id" Operator="=" PropertyValue="${root.job.Equipment.Id}" />
    </Filters>
</GetItem>

GetListbewerken

Haal meerdere domain objects op als lijst. De OutputProperty moet van type List[...] zijn.

<GetList Name="Get subjobs" Type="Job" OutputProperty="${SubjobList}"
    OrderBy="ScheduledStartDate" OrderDirection="Ascending">
    <Filters>
        <PropertyFilter PropertyName="Multijob" Operator="=" PropertyValue="${Job}" />
        <PropertyFilter PropertyName="ScheduledStartDate" Operator="<"
            PropertyValue="${Job.ScheduledStartDate}" />
    </Filters>
</GetList>

Attributen:

Praktische tips:

<GetList Name="Gewijzigde equipment laatste 2 dagen" Type="Equipment"
    OutputProperty="${equipmentList}" OrderBy="Id">
    <Filters>
        <BetweenFilter PropertyName="ModificationDate"
            LowValue="=startOfDay(addDays(now(), -2))"
            HighValue="=startOfDay(now())" />
        <PropertyFilter PropertyName="Status" Operator="=" PropertyValue="EquipmentStatus.Active" />
    </Filters>
</GetList>
<When Name="Lijst heeft resultaten" Condition="${equipmentList.Count} > 0">
    <!-- verwerk de lijst -->
</When>

GetCountbewerken

Tel het aantal records dat aan de filter voldoet.

<GetCount Name="Tel subjobs" Type="Job" OutputProperty="${SubJobCount}">
    <Filters>
        <PropertyFilter PropertyName="Multijob" Operator="=" PropertyValue="${Job}" />
    </Filters>
</GetCount>

GetSum / GetMax / GetMinbewerken

Aggregatiefuncties op een specifieke property.

<GetSum Name="Sum Quantity" Type="ObjectBatch" OutputProperty="${SumQuantity}" PropertyName="QuantityOut">
    <Filters>
        <PropertyFilter PropertyName="JobMaterial" Operator="=" PropertyValue="${JobMaterial}" />
    </Filters>
</GetSum>

<GetMax Name="Max price" Type="Article" OutputProperty="${MaxPrice}" PropertyName="Price" />
<GetMin Name="Min score" Type="RiskClass" OutputProperty="${MinScore}" PropertyName="FromScore" />

GetGroupedListbewerken

Haal een gegroepeerde lijst op. Output type is GroupedList[GroupKey, ItemType].

<GetGroupedList Name="Materials per warehouse" Type="JobMaterial"
    OutputProperty="${GroupedMaterials}" GroupBy="Warehouse" OrderBy="Id">
    <Joins>
        <Join Name="Warehouse" Alias="warehouse" Type="LeftOuterJoin" />
    </Joins>
    <Filters>
        <PropertyFilter PropertyName="Id.Job" Operator="=" PropertyValue="${Job}" />
    </Filters>
</GetGroupedList>

Query / Subquerybewerken

Voer een geavanceerde query uit met custom projectie (specifieke kolommen).

<Query Name="GetDepartments" Type="Department" OrderBy="Id" OrderDirection="Ascending"
    OutputProperty="${DepartmentResult}">
    <Properties>
        <Property Name="Id" Alias="DepartmentId" Type="GroupProperty" />
        <Property Name="emp2.Description" Alias="Description" Type="GroupProperty" />
    </Properties>
</Query>

IsReferredTobewerken

Controleer of een domain object door andere objecten wordt gerefereerd.

<IsReferredTo Name="Check references" DomainObject="${Job}" OutputProperty="${JobIsUsed}"
    ExcludeTrashedRecords="True" />

Flushbewerken

Schrijf in-memory wijzigingen naar de database, zonder de transaction te beeindigen. Kan geheugen vrijmaken bij grote operaties.

<Flush Comment="Write changes to DB" />

Logbewerken

Schrijf een bericht naar een logbestand. Configureer de log via log.config.

<Log Name="Log" Description="New job created" LogName="Workflow" Type="Information">
    <Parameter Name="NumberOfRecords" Direction="In" Value="${NumberOfRecords}" />
</Log>

Log types: Information, Warning, Error


Filtersbewerken

Filters worden gebruikt binnen GetItem, GetList, GetCount, GetSum, GetMax, GetMin en GetGroupedList.

PropertyFilterbewerken

De meest gebruikte filter. Vergelijkt een property met een waarde.

<PropertyFilter PropertyName="Status" Operator="=" PropertyValue="JobStatus.Active" />
<PropertyFilter PropertyName="Equipment" Operator="!=" PropertyValue="Empty" />

Operators: =, !=, >, <, >=, <=, Like


CombinedFilterbewerken

Combineer meerdere filters met AND of OR.

<CombinedFilter FilterOperator="And">
    <PropertyFilter PropertyName="Id.Job" Operator="=" PropertyValue="${Job}" />
    <PropertyFilter PropertyName="Status" Operator="=" PropertyValue="JobMaterialStatus.Created" />
</CombinedFilter>

<CombinedFilter FilterOperator="Or">
    <PropertyFilter PropertyName="Status" Operator="=" PropertyValue="JobStatus.Active" />
    <PropertyFilter PropertyName="Status" Operator="=" PropertyValue="JobStatus.Finished" />
</CombinedFilter>

InFilterbewerken

Filter op meerdere waarden tegelijk (SQL IN clausule).

<InFilter PropertyName="Status" Values="JobStatus.Active, JobStatus.Closed" />
<InFilter PropertyName="Id" Values="${WorkPeriodIds}" />

NotFilterbewerken

Inverteer een filter (SQL NOT).

<NotFilter>
    <PropertyFilter PropertyName="Id.ProgressStatusNextAvailable" Operator="="
        PropertyValue="${DefaultAvailable}" />
</NotFilter>

DateFilter / DatePartFilterbewerken

Filter op datum of een deel van een datum.

<DateFilter PropertyName="ActivateDate" Operator="=" PropertyValue="#{Environment.CurrentDate}" />
<DatePartFilter PropertyName="DepreciationStartDate" Operator="!=" PropertyValue="1" DatePart="Day" />

DatePart waarden: Hour, Day, Week, Month, Quarter, Year


BetweenFilterbewerken

Filter op een bereik (inclusief grenzen).

<BetweenFilter PropertyName="${Job.Cost}" LowValue="1000" HighValue="2000" />

PropertyEmptyFilterbewerken

Filter op lege waarden.

<PropertyEmptyFilter PropertyName="Description" />

WhenFilterbewerken

Conditionele filter: wordt alleen toegepast als de conditie waar is.

<WhenFilter Condition="${UseSiteFilter} == True">
    <PropertyFilter PropertyName="Site" Operator="=" PropertyValue="${Job.Site}" />
</WhenFilter>

DistanceFilterbewerken

Filter op geografische afstand in meters.

<DistanceFilter FirstLatitude="52.123" FirstLongitude="5.456"
    SecondLatitude="52.789" SecondLongitude="5.012" Operator="<" Distance="1000" />

Joinsbewerken

Joins worden gebruikt binnen Get-instructies om gerelateerde entiteiten mee te laden.

<GetList Name="Get items" Type="JobMaterial" OutputProperty="${Materials}">
    <Joins>
        <Join Name="Warehouse" Alias="warehouse" Type="LeftOuterJoin" />
        <Join Name="Article"   Alias="article"   Type="InnerJoin" />
    </Joins>
    <Filters>
        <PropertyFilter PropertyName="article.Description" Operator="Like" PropertyValue="%" />
    </Filters>
</GetList>

Join types: InnerJoin, LeftOuterJoin


Communicationbewerken

Instructies voor communicatie: emails, reminders, afspraken.

Emailbewerken

Verstuur een email op basis van een TextTemplate. De template wordt uit de database gehaald via de code.

Belangrijk: emails versturen werkt altijd in twee stappen. Eerst maak je de email aan als Concept (Concept="True" + OutputProperty), dan zet je de status naar Draft via ChangeStatus. Zonder deze twee stappen wordt de email niet verzonden. Beide stappen moeten binnen dezelfde Transaction staan.

<!-- Twee-stappen patroon: Email aanmaken als Concept, dan naar Draft zetten -->
<Transaction>
    <Email Name="EmailToVendor" From="#{UltimoSettings.EmailSender}"
        To="${Job.Vendor.EmailAddress}" RelatedSubjects="${Job}"
        EmailTemplateCode="00000000031" Concept="True" OutputProperty="${Email}">
        <Parameters>
            <Parameter Name="Job" Direction="In" Value="${Job}" />
        </Parameters>
        <Attachments>
            <Attachment Data="${ReportData}" />
        </Attachments>
    </Email>
    <ChangeStatus Name="ChangeStatusEmail" DomainObject="${Email}"
        NewStatus="EmailStatus.Draft" />
</Transaction>

Vereiste property-declaratie:

De OutputProperty ${Email} moet als property zijn gedeclareerd. In een standaard workflow:

<Property Name="Email" Type="Email" Accessor="Internal" />

In een UserContent Block (UCB): declareer de property in het UCB Properties tab (rechterkant in de Workflow Designer), type Email, accessor Internal.

Attributen:

Email statussen:

Consultant tip: Gebruik #{UltimoSettings.EmailSender} als From-adres, niet #{Settings.EmailSender}. Dit is wat de standaard Ultimo workflows gebruiken (zie bijv. ActionField667). Vergeet niet de Email property te declareren — zonder OutputProperty kan de ChangeStatus naar Draft niet werken. Beide instructies (Email + ChangeStatus) moeten in dezelfde Transaction staan.

Reminderbewerken

Stuur een interne reminder (notificatie) naar een of meer medewerkers.

<Reminder Name="Stuur herinnering" Recipients="${Recipients}"
    Priority="${Priority}" ReminderTemplateCode="0000"
    RelatedSubjects="${Job}" EnablePushNotifications="True" />

CreateAppointment / UpdateAppointmentbewerken

Maak of wijzig een afspraak in een externe agenda via email.

<CreateAppointment Name="Plan afspraak" From="#{Settings.EmailSender}"
    To="${Job.Employee}" StartDate="${Job.ScheduledStartDate}"
    EndDate="=#addminutes(${Job.ScheduledStartDate}, 30)"
    Location="Werkplaats A" RelatedSubjects="${Job}" TemplateCode="0000"
    OutputProperty="${Appointment}" />

Dialogbewerken

Instructies voor gebruikersinteractie via dialogen. Alleen beschikbaar als AllowUserInteraction="True".

Dialogbewerken

Toon een dialoogvenster aan de gebruiker.

<Dialog Name="VraagNaam" TitleCode="ASKFORNAME" AllowCancel="True">
    <Container Border="True">
        <Text Name="NewName" Value="${OriginalName}" OutputProperty="${NewName}"
            LabelCode="NAME" Required="True" />
    </Container>
</Dialog>

Dialog controlsbewerken

Beschikbare controls binnen een Dialog:

Control Beschrijving
Text Tekstveld
TextArea Groot tekstveld (meerdere regels)
Number Numeriek veld
Date Datumkiezer
DateTime Datum+tijd kiezer
Time Tijdkiezer
Duration Duur (uren:minuten)
CheckBox Vinkje
CheckBoxGroup Groep vinkjes
RadioGroup Keuzerondjes
ComboBox Keuzelijst
SelectionList Selectielijst uit database
EmailAddress Email-adres selectie
FileSelector Bestand uploaden
Signature Digitale handtekening
Location Locatiekiezer
Html HTML-teksteditor
Password Wachtwoordveld
Literal Alleen-lezen tekst
ListSelector Lijst met bron- en doellijst
SelectionPeriod Periodeselectie

Voorbeeld met meerdere controls:

<Dialog Name="UrenRegistratie" TitleCode="HOURREGISTRATION">
    <Container TitleCode="DETAILS" Border="True">
        <SelectionList Name="Employee" OutputProperty="${SelectedEmployee}"
            ColumnName="EmpId" Required="True" LabelCode="EMPLOYEE" />
        <Number Name="Hours" OutputProperty="${Hours}" LabelCode="HOURS"
            DecimalPrecision="2" MinValue="0" />
        <DateTime Name="StartDate" OutputProperty="${StartDate}"
            LabelCode="STARTDATE" Required="True" IntervalMinutes="15" />
        <TextArea Name="Remark" OutputProperty="${Remark}" LabelCode="REMARK"
            TextAreaRows="4" />
    </Container>
</Dialog>

Configuratiedetails per control:

<Dialog Name="KiesEquipment" TitleCode="SEL_EQUIPMENT" AllowCancel="True">
    <Container Border="True">
        <SelectionList Name="Equipment" OutputProperty="${geselecteerdEquipment}"
            ColumnName="EqmId" LabelCode="EQUIPMENT" Required="True"
            SqlWhereClause="EqmContext = 1 AND EqmStatus = 10" />
    </Container>
</Dialog>

Consultant tip: Gebruik Ctrl+drag in de Workflow Designer om bestaande blokken (inclusief hun kinderen) te kopiëren naar een andere positie in de workflow. Dit bespaart tijd bij terugkerende patronen zoals Container + SelectionList.

Dialog validatiebewerken

<Validations>
    <ValidationExpression Name="Check waarden ingevuld"
        Condition="${Hours} != Empty || ${FixedPrice} != Empty"
        MessageCode="1030" ValidationType="Error" TriggerType="OnClose" />
    <ValidationWorkflow Name="Validate status"
        WorkflowName="Validation_ChangeProgressStatus">
        <Parameter Name="NewProgressStatus" Direction="In" Value="${NewStatus}" />
    </ValidationWorkflow>
</Validations>

Dialog updatesbewerken

Gebruik UpdateWorkflow om dialoog-waarden dynamisch bij te werken:

<Updates>
    <UpdateWorkflow Name="Get defaults" WorkflowName="Dialog_GetDefaults">
        <Parameter Name="Employee" Direction="In" Value="${Employee}" />
        <Parameter Name="DefaultCategory" Direction="Out" OutputProperty="${DefaultCategory}" />
    </UpdateWorkflow>
</Updates>

User Inputbewerken

Messagebewerken

Toon een meldingsbericht aan de gebruiker.

<Message Name="Bevestiging" MessageCode="0169">
    <Parameter Name="WorkOrder" Direction="In" Value="${WorkOrder}" />
</Message>

Questionbewerken

Stel een Ja/Nee (of Ja/Nee/Annuleer) vraag.

<Question Name="Bevestig" Type="YesNo" MessageCode="0000"
    Default="Yes" OutputProperty="${QuestionResult}" />

ContinuationQuestionbewerken

Ja/Nee vraag waarbij "Nee" de workflow afbreekt.

<ContinuationQuestion Name="Doorgaan?" MessageCode="0846">
    <Parameter Name="Article" Direction="In" Value="${JobMaterial.Article}" />
</ContinuationQuestion>

SystemDialogbewerken

Toon een systeemdialoog (bijv. een selectiescherm).

<SystemDialog Name="Kies Equipment" DialogName="SelectDomainObject">
    <Parameter Name="EntityName"   Direction="In" Value="Equipment" />
    <Parameter Name="SqlWhereClause" Direction="In" Value="EqmContext = 1" />
    <Parameter Name="DomainObject" Direction="Out" OutputProperty="${SelectedEquipment}" />
</SystemDialog>

Viewbewerken

Open een scherm na een workflow-actie.

<View Name="Open job" ViewName="DataEntryScreen">
    <Parameter Name="DomainObject" Direction="In" Value="${CreatedJob}" />
    <Parameter Name="ScreenName"   Direction="In" Value="${FormName}" />
</View>

Volledige parameterlijst:

Parameter Richting Beschrijving Voorbeeld
DomainObject In Het te openen record ${newJob}
ScreenName In Schermcode (zie Screens in UCT) job03
CreateNewRecord In False als het record al via Insert is aangemaakt; True voor een nieuw leeg scherm False
OpenNewWindow In True om het scherm in een nieuwe browsertab te openen True
FocusEditableField In True om de cursor direct in het eerste bewerkbare veld te plaatsen True

Voorbeeld na Insert:

<View Name="Open nieuw job-scherm" ViewName="DataEntryScreen">
    <Parameter Name="DomainObject"       Direction="In" Value="${newJob}" />
    <Parameter Name="ScreenName"         Direction="In" Value="job03" />
    <Parameter Name="CreateNewRecord"    Direction="In" Value="False" />
    <Parameter Name="OpenNewWindow"      Direction="In" Value="True" />
    <Parameter Name="FocusEditableField" Direction="In" Value="True" />
</View>

Consultant tip: Gebruik CreateNewRecord="False" altijd na een Insert — anders probeert Ultimo opnieuw een record aan te maken op het openingsscherm, wat een dubbel record of een fout veroorzaakt.


VerifyElectronicSignaturebewerken

Vraag de gebruiker om een elektronische handtekening (wachtwoord + reden).

<VerifyElectronicSignature Name="Verifieer" />

Import / Exportbewerken

Importbewerken

Importeer data vanuit XML of CSV.

<Import Name="Import data" Data="${Input}" OutputProperty="${Output}"
    RollbackOnError="True" ProcessObjects="True" Culture="NL" />

Attributen:


Exportbewerken

Exporteer data naar XML of CSV.

<Export Type="${ExportConnector.EntityToExport}" Data="${Data}"
    OutputProperty="${Output}" ExportFormat="${ExportConnector.FileType}"
    Culture="${ExportConnector.Culture}" Encoding="${ExportConnector.OutputEncoding}"
    Separator="${ExportConnector.CsvSeparator}" />

Documentbewerken

CreateDocument / DocumentGridPagebewerken

Maak een Excel of XML document met data.

<CreateDocument Name="Export" DocumentType="Excel" FileName="Export.xlsx"
    ConvertHtmlToPlainText="True">
    <DocumentGridPage Name="Cost overzicht" PageTitle="Kosten" Type="Cost"
        ViewfieldConfiguration="default">
        <Properties>
            <Property Name="Id" Alias="CostId" Type="Property" />
            <Property Name="Context" Alias="Context" Type="Property" />
        </Properties>
    </DocumentGridPage>
</CreateDocument>

Downloadbewerken

Download een bestand uit de FileService. De workflow stopt na het downloaden.

<Download Name="Download rapport" FileName="Documents\Rapport.pdf" />

Filebewerken

Instructies voor bestandsbeheer in de Ultimo FileService.

Instructie Beschrijving
OpenFile Open een bestand als stream
SaveFile Sla een bestand op
CopyFile Kopieer een bestand
MoveFile Verplaats/hernoem een bestand
DeleteFile Verwijder een bestand
FileExists Controleer of bestand bestaat
CreateFolder Maak een map aan
CopyDirectory Kopieer een map
MoveFolder Verplaats/hernoem een map
DeleteFolder Verwijder een map
FolderExists Controleer of map bestaat
GetFileList Lijst van bestanden in een map

OpenFilebewerken

Open een bestand uit de FileService als stream. Alle bestanden moeten binnen de FileServiceData-locatie staan.

<OpenFile Name="Open" FileName="Documents\input.txt" OutputProperty="${Stream}" Encoding="utf-8" />

Attributen:


SaveFilebewerken

Sla een bestand op in de FileService. Data moet van het type DocumentContainer zijn.

<SaveFile Name="Save" FileName="Documents\Report.pdf" Data="${ReportStream}" />

CopyFilebewerken

Kopieer een bestand naar een nieuwe locatie in de FileService.

<CopyFile Name="Copy" SourceFile="${Source.ImageFile}" TargetFile="${Target.ImageFile}" />

MoveFilebewerken

Verplaats of hernoem een bestand in de FileService.

<MoveFile Name="Move" SourceFile="Import\input.xml" TargetFile="Import\processed\input.xml" />

DeleteFilebewerken

Verwijder een bestand uit de FileService. Kan niet ongedaan worden gemaakt.

<DeleteFile Name="Delete" FileName="Import\${ConnectorId}\Input\upload" />

FileExistsbewerken

Controleer of een bestand bestaat in de FileService.

<FileExists Name="Check" FileName="${Dir}\${FileName}" OutputProperty="${Exists}" />

GetFileListbewerken

Haal een lijst van bestandsnamen op uit een map in de FileService.

<GetFileList Name="Get files" OutputProperty="${Files}" FolderName="Workflows"
    SearchPattern="*.wfl" OrderBy="Name" />

Attributen:


CreateFolderbewerken

Maak een nieuwe map aan in de FileService.

<CreateFolder Name="MaakMap" FolderName="Documents" />

CopyDirectorybewerken

Kopieer een map inclusief inhoud naar een nieuwe locatie.

<CopyDirectory Name="Copy" SourceDirectory="${SourceDirectory}" TargetDirectory="${TargetDirectory}" />

MoveFolderbewerken

Verplaats of hernoem een map in de FileService.

<MoveFolder Name="Move" OriginalFolderName="${OldName}" NewFolderName="${NewName}" />

DeleteFolderbewerken

Verwijder een map uit de FileService.

<DeleteFolder Name="Delete" FolderName="${FullPath}" />

FolderExistsbewerken

Controleer of een map bestaat in de FileService.

<FolderExists Name="Check" FolderName="Documents" OutputProperty="${FolderExists}" />

Printbewerken

Druk data af naar een printer geconfigureerd in UCT.

<Print Name="Print" PrinterId="0001" FileName="Documents\Order.pdf"
    Landscape="False" Data="${Data}" />

Attributen:


Reportbewerken

CreateReportbewerken

Genereer een rapport (Crystal Reports) in verschillende formaten.

<CreateReport Name="Genereer rapport" ReportName="job01" ReportType="Pdf"
    OutputProperty="${ReportData}" ShowTrashedRecords="False">
    <CollectInput Name="Input" DialogTitleCode="CRITERIA">
        <CollectInputFormula Name="F1" ColumnName="EqmId" Operator="Like"
            ResultType="string" SqlWhereClause="EqmContext = 1" />
    </CollectInput>
    <ReportParameter Name="P1" Value="${Job.Id}" />
    <ReportFormulaValue Name="F1" ColumnName="JobId" Operator="=" Value="${Job.Id}" ResultType="string" />
</CreateReport>

ReportType opties: Pdf, Word, Excel, ExcelDataOnly, Rtf, EditableRtf, Csv, Html, Xml


Printbewerken

Druk data af naar een printer (geconfigureerd in UCT).

<Print Name="Print" PrinterId="0001" FileName="Documents\Order.pdf"
    Landscape="False" Data="${Data}" />

Textbewerken

FormatTextbewerken

Formatteer tekst via de template engine. Gebruik een TextCode uit de database of een inline template.

<FormatText Name="Format label" TextCode="ARCGISCONDITIONPEROBJECT"
    OutputProperty="${Title}" />

<FormatText Name="Format warning" TextCode="2938" OutputProperty="${Warning}">
    <Parameters>
        <Parameter Name="Reservation" Direction="In" Value="${Reservation}" />
    </Parameters>
</FormatText>

CheckFormatText / UnformatTextbewerken

Reguliere expressies: valideer of parseer tekst.

<!-- Valideer met regex -->
<CheckFormatText Name="Check URL" Text="${Url}"
    Mask="^https?://.*$" CaseSensitive="False" OutputProperty="${IsValid}" />

<!-- Parseer tekst met regex groepen -->
<UnformatText Name="Extract filename" Text="${UploadedFile}" Mask="[^\\]*$"
    CaseSensitive="False" OutputProperty="${FileName}">
    <Parameter Name="0" Direction="Out" OutputProperty="${FileName}" />
</UnformatText>

XMLbewerken

XmlParser / CsvToXmlParserbewerken

Parseer XML of CSV naar een XmlDocumentContainer voor verdere verwerking.

<XmlParser Name="Parse XML" Input="${Input}" OutputProperty="${XmlDoc}" />

<CsvToXmlParser Name="Parse CSV" Input="${Input}" Separator=";" Type="Employee"
    OutputProperty="${XmlDoc}" Encoding="UTF-8" Action="InsertOrUpdate" HasHeaderLine="True" />

XmlTransformbewerken

Transformeer XML met een XSLT stylesheet.

<XmlTransform Name="Transform" Input="${XmlDoc}" XsltName="import.xslt"
    OutputProperty="${TransformedDoc}" Encoding="UTF-8" />

XmlValidationbewerken

Valideer XML tegen een XSD schema.

<XmlValidation Name="Validate" Input="${XmlDoc}" XsdName="schema.xsd" />

Listbewerken

AddToList / RemoveFromListbewerken

Voeg items toe aan of verwijder items uit een lijst.

<AddToList Name="Voeg toe" List="${Articles}" Item="${Article}" />
<RemoveFromList Name="Verwijder" List="${Jobs}" Item="${Job}" />

Filterbewerken

Filter een lijst op basis van een conditie.

<Filter Name="Niet-lege items" InList="${InList}" OutList="${ResultList}"
    As="${value}" Condition="${value} != Empty" />

Mathbewerken

Add / Subtractbewerken

Reken met twee numerieke waarden.

<Add Name="Verhoog teller" ValueLeft="${Counter}" ValueRight="1" OutputProperty="${Counter}" />
<Subtract Name="Bereken verschil" ValueLeft="100" ValueRight="${Used}" OutputProperty="${Remaining}" />

Data (Test)bewerken

Instructies voor het beheren van testdata in scenario-tests.

InsertTestDatabewerken

Maak testdata aan voor een scenario. De testdata wordt automatisch verwijderd wanneer het scenario klaar is. Benader testdata via ${TestData.[Name]}. Naamconventie: recordtype-prefix gevolgd door twee cijfers in lowercase, bijv. emp01, job01, eqm01.

<InsertTestData Name="OBJ1" ObjectType="Job" />
<!-- Benader via ${TestData.OBJ1} -->

Attributen:

Let op: Bij een compound key hoeft alleen de LineId leeg gelaten te worden; de Id wordt automatisch gegenereerd.


SetRelationbewerken

Stel een relatie in op een testdata-object. Gebruik dit voor properties die niet gezet kunnen worden tijdens creatie, of voor circulaire referenties.

<SetRelation Name="Set Multijob" Relation="${TestData.Job.Multijob}" Value="${TestData.Job}" />

Attributen:


Datebewerken

CalculateWeekOfYearbewerken

Bereken het weeknummer van een datum.

<CalculateWeekOfYear Name="Weeknummer" Date="#{Environment.CurrentDate}" WeekOfYear="${WeekDate}" />

Debugbewerken

Debugbewerken

Toon een debug-bericht. Alleen in Development/Test omgevingen. De workflow stopt bij het debug-bericht.

<Debug Name="Debug" Message="${Job.HoursCalculated}" />
<Debug Name="Debug expression" Message="#{Environment.CurrentDateTime}" />
<Debug Name="Debug berekening" Message="#round(3.33335, 2)" />

Consultant tip: Verwijder altijd Debug instructies voor deployment naar productie. In productie zorgt Debug voor een foutmelding.


Gerelateerde artikelenbewerken


Custom Workflow XML: Hash en Security attributenbewerken

Bij het aanmaken van custom workflows in Ultimo worden door de workflow engine automatisch extra attributen toegevoegd aan de XML. Consultants en AI-assistenten moeten hier rekening mee houden bij het genereren van workflow XML.

Hash attribuutbewerken

Ultimo gebruikt een Hash attribuut op het <Workflow> element om de integriteit van de workflow te valideren bij import.

Hash-algoritme (reverse engineered en geverifieerd):

SHA1( UTF-8 bytes van de volledige XML, zonder BOM, zonder het Hash="..." attribuut )

Concreet:

  1. Neem de volledige workflow XML
  2. Verwijder het Hash="..." attribuut (inclusief de spatie ervoor)
  3. Encodeer als UTF-8 (zonder BOM)
  4. Bereken SHA1 → uppercase hex string

Python implementatie:

import hashlib
import re

def compute_ultimo_hash(xml_text: str) -> str:
    """Bereken Ultimo workflow hash. Input: XML string zonder BOM."""
    no_hash = re.sub(r' Hash="[^"]*"', '', xml_text)
    return hashlib.sha1(no_hash.encode('utf-8')).hexdigest().upper()

def add_hash_to_workflow(xml_text: str) -> str:
    """Voeg Hash attribuut toe aan workflow XML. Normaliseert naar CRLF."""
    xml_text = xml_text.replace('\r\n', '\n').replace('\r', '\n').replace('\n', '\r\n')
    h = compute_ultimo_hash(xml_text)
    if 'Hash="' in xml_text:
        return re.sub(r'Hash="[^"]*"', f'Hash="{h}"', xml_text)
    else:
        return xml_text.replace('<Workflow ', f'<Workflow Hash="{h}" ', 1)

Belangrijk:

Security EditLevel en ViewLevelbewerken

Ultimo past de <Security> attributen aan op basis van het UCT-autorisatieniveau van de ingelogde gebruiker:

<!-- Standaard workflows (door Ultimo R&D) -->
<Security EditLevel="10" ViewLevel="20" UserContentLevel="30" />

<!-- Custom workflows (opgeslagen door consultant, typisch level 12+) -->
<Security EditLevel="12" ViewLevel="26" UserContentLevel="26" />

MessageCode 2060 als generiek berichtbewerken

Bij custom workflows gebruik je MessageCode 2060 als generiek bericht met een vrije Message parameter:

<Message Name="Done" MessageCode="2060">
    <Parameter Name="Message" Direction="In" Value="Mijn custom bericht" />
</Message>

<Validation Name="Check" Condition="${X} != Empty" MessageCode="2060">
    <Parameter Name="Message" Direction="In" Value="X mag niet leeg zijn." />
</Validation>

<ContinuationQuestion Name="Bevestig" MessageCode="2060">
    <Parameter Name="Message" Direction="In" Value="Weet je het zeker?" />
</ContinuationQuestion>

Gebruik NIET MessageCode 0480 — die wordt door Ultimo geïnterpreteerd als "Dit actieveld is vervallen".

Hash attribuutbewerken

Ultimo voegt automatisch een Hash attribuut toe aan het <Workflow> element:

<Workflow Hash="00D95683F9D076F0B399A30AF8A077A3097A0CAA" Name="_MijnWorkflow" ...>

Security EditLevel en ViewLevelbewerken

Ultimo past ook de <Security> attributen aan op basis van het niveau van de gebruiker die de workflow opslaat:

<!-- Standaard workflows (door Ultimo R&D) -->
<Security EditLevel="10" ViewLevel="20" UserContentLevel="30" />

<!-- Custom workflows (opgeslagen door consultant, typisch level 12+) -->
<Security EditLevel="12" ViewLevel="26" UserContentLevel="26" />

De levels worden automatisch ingesteld op basis van het UCT-autorisatieniveau van de ingelogde gebruiker.

Praktische gevolgen voor het genereren van workflow XMLbewerken

  1. Hash NIET meegeven — Ultimo voegt deze automatisch toe bij opslaan
  2. Security levels worden automatisch gezet — gebruik standaard EditLevel="10" ViewLevel="20" UserContentLevel="30" in templates
  3. Properties worden alfabetisch gesorteerd door Ultimo bij opslaan — de volgorde in broncode maakt niet uit
  4. Bij het kopiëren van workflows tussen omgevingen wordt de hash opnieuw berekend

Voorbeeld: workflow XML vóór opslaan (door consultant/AI gegenereerd)bewerken

<Workflow Name="_MijnCustomWorkflow" Version="2025.07.28" WorkflowType="Standard" xmlns="urn:Ultimo.Framework.Workflow-mapping">
    <Security EditLevel="10" ViewLevel="20" UserContentLevel="30" />
    <Description>Mijn beschrijving</Description>
    <Properties>
        <Property Name="MyEntity" Type="Job" Accessor="Root" Direction="In" />
    </Properties>
    <Execution>
        <UserContent Name="Pre" />
        <!-- logica -->
        <UserContent Name="Post" />
    </Execution>
</Workflow>

Dezelfde workflow XML ná opslaan door Ultimobewerken

<Workflow Hash="A1B2C3D4E5F6..." Name="_MijnCustomWorkflow" Version="2025.07.28" WorkflowType="Standard" xmlns="urn:Ultimo.Framework.Workflow-mapping">
    <Security EditLevel="12" ViewLevel="26" UserContentLevel="26" />
    <Description>Mijn beschrijving</Description>
    <Properties>
        <Property Name="MyEntity" Type="Job" Accessor="Root" Direction="In" />
    </Properties>
    <Execution>
        <UserContent Name="Pre" />
        <!-- logica -->
        <UserContent Name="Post" />
    </Execution>
</Workflow>

MessageCode 2060 als generiek berichtbewerken

Bij custom workflows gebruik je MessageCode 2060 als generiek bericht met een vrije Message parameter:

<Message Name="Done" MessageCode="2060">
    <Parameter Name="Message" Direction="In" Value="Mijn custom bericht" />
</Message>

<Validation Name="Check" Condition="${X} != Empty" MessageCode="2060">
    <Parameter Name="Message" Direction="In" Value="X mag niet leeg zijn." />
</Validation>

<ContinuationQuestion Name="Bevestig" MessageCode="2060">
    <Parameter Name="Message" Direction="In" Value="Weet je het zeker?" />
</ContinuationQuestion>

Gebruik NIET MessageCode 0480 — die wordt door Ultimo geïnterpreteerd als "Dit actieveld is vervallen".

Brondatabewerken

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