Stages and Workflows
The steps of the form processing workflow ("stages") can be defined by a JSON file. This file is named "stages.json" and can be provided as part of your template definition.
Note: "Stages" require a Server version 7.2.* or higher AND an App version 7.3 or higher!
JSON File
The JSON file serves as the "configuration file" for stages and workflows initialized by clicking the toolbar button "Approve".
Unless a stages.json file is provided, the Form Definition is processed in "stage 1" with all default settings.
The JSON file consists of two objects: stages and workflows.
The stage definition must include a next definition, specifying what should happen if a stage is approved (Form.Status == Approved). The form will progress to the next stage when all defined workflows of the current stage have successfully completed, or it will finish if only one stage is defined.
{
    "stages": {
        "stage_1": {
            "first": true,
            "label": "Stage 1",
            "appKioskMode": false,
            "next": {
                "stage": "stage_2",
                "workflows": ["wf_pdf","wf_cond1" "wf_email1", "wf_grp1", "wf_excel" ],
                "buttonLabel": "Approve Stage 1: {{field_id}}",
                "dialogTitle": "Approve dialog title",
                "dialogMessage": "Message text of the approve dialog - Finishing {{field_id}}"
            },
            "stateChanges": {
                "Group": {
                    "workflows": [ "wf_email1" ]
                }
            }
        },
        "stage_ ...": {
        },
        "stage_final": {
            "label": "Stage final",
            "next": {
                "workflows": [ "wf_archive" ]
            }
        }
    },
    "workflows": {
        "wf_pdf": {
            "type": "pdf",
            "create": true
        },
        "wf_email1": {
            "type": "email",
            "to": "office@icomedias.com",
            "subject": "New HybridForms process created ",
            "body": "A new HybridForms process was created.",
            "erroraction": "ignore",
            "errorfeedback": "Notification could not be sent",
            "errornotify": "admin@icomedias.com",
            "filename": "email-filename.pdf",
            "attachPDF": true,
            "attachImages": true,
            "attachimage":"form-logo.png"
        },
        "wf_email2" : {
            "type": "email",
            "to": "office@icomedias.com",
            "subject": "A new form",
            "template": "mailtemplate.txt"
        },
        "wf_grp1": {
            "type": "setgroup",
            "group": "icoad\\ag-sachbearbeiter"
        },
         "wf_current_grp": {
            "type": "setcurrentgroup",
            "group": "icoad\\ag-mitarbeiter"
        },
        "wf_archive": {
            "type": "setstatus",
            "status": "Archived"
        },
        "wf_current_archived": {
            "type": "setcurrentstatus",
            "status": "Archived"
        },
        "wf_cond1": {
            "type": "condition",
            "condition": "{field} != True"
        },
        "wf_newValue": {
            "type": "setfield",
            "field": "fieldID",
            "value": "new Value"
        },
        "wf_newCheckboxValue": {
            "type": "setfield",
            "field": "fieldID",
            "value": "{true}"
        },
        "wf_newRadioboxValue": {
            "type": "setfield",
            "field": "fieldID",
            "value": "{null}"
        },
        "wf-newform": {
            "type": "newform",
            "title": "{Title}",
            "template": "bc40e199-e8a1-4a4f-9b53-a5e8f16154c0",
            "status": "Edit",
            "stage": "S1",
            "owner": "user@hybridforms.net",
            "group": "hf-group",
            "fields": {
                "name" : "{name_textfield}",
                "date": "{work_date}"
            }
        },
        "wf_owner": {
            "type": "setowner",
            "owner": "{fieldValueUPN}"
        },
        "wf_current_owner": {
            "type": "setcurrentowner",
            "owner": "{Editor}"
        },
        "wf_excel": {
            "type": "createexcel",
            "template": "excel_template.xlsx",
            "filename": "form.xlsx",
            "errorNotify": "admin@icomedias.com",
            "errorFeedback": "Fehler beim Erzeugen des Excel"
        }
    }
}
Workflows executed by finishing a "one-stage" Form Item must be defined inside a stages.json as well, simply skip the entry "stage" inside the "next" object.
"S1": {
    "first": true,
    "label": "Default Stage",
    "next": {
        "workflows": ["wf_email"]
    }
}
If the stage enging is enabled, the App kiosk mode is disabled by default. The App kiosk mode could be activated for a specific stage.
Stages and workflows can also be created and edited in the Admin UI. Go to the FormDefinition template, in the section "stages" click the "Edit"-button.


Stage Object
Configure a stage object by specifying a custom name (e.g. "stage_1" ) and the values for the keys label, next, stagechanges and once first.
The key-value pairs label, next and first are required and first must be unique.
| Property | Type | How to use | Description | 
|---|---|---|---|
| first | Boolean | "first": true | Specify the stage where to start. | 
| label | String | "label": "Stage 1" | Set the ID/name of the stage used in your form for conditions. | 
| appKioskMode | Boolean | "appKioskMode": false | De/activate App Kiosk Mode button for this stage. App Kiosk Mode must be enabled for form (App Kiosk Mode). Default value is true. | 
| next | Object | "next": { } | Define the options of the workflows initialized by finishing the stage. | 
| ../stage | String | "next": {"stage":"stage_final"} | Set the stage processed next. | 
| ../workflows | JSON Array | "next": {"workflows": ["wf_pdf","wf_cond1" "wf_email1", "wf_grp1"] } | Specify the workflows invoked by finishing the stage. | 
| ../buttonLabel | String | "next": {"buttonLabel":"Approve Stage 1: {{field_id}}"} | For better usability define an appropriate label of the "Approve" button in the form toolbar for each stage. {{field_id}} placeholder gets replaced by list data value. | 
| ../dialogTitle | String | "next": {"dialogTitle": "Approve dialog title"} | Specify the title of the approve dialog for each stage. {{field_id}} placeholder gets replaced by list data value. | 
| ../dialogMessage | String | "next": {"dialogMessage": "Message text of the approve dialog"} | Specify the approve dialog message text for each stage. {{field_id}} placeholder gets replaced by list data value. | 
| stateChanges | Object | "stateChanges": { "Group": {"workflows": [ "wf_email1" ] } } | Define the workflows invoked by changing the form's status in the stage's life cycle. | 
Workflow Object
Define all your workflows invoked by stage or status changes.
These workflows can be used multiple times and can be of different types: conditions, requests, emails sent or changes of the Form Item meta data (e.g the owner or the assigned group).
The workflows are processed in order of the JSON array position. A workflow of "type": "condition" is applied to all following workflows until a new condition is defined.
in the example {"workflows": ["wf_pdf","wf_cond1", "wf_email1", "wf_grp1"]} the condition of the workflow "wf_cond1" controls the execution of workflow "wf_email1" and "wf_group".
Workflow Definitions
Common
Common options for every workflow option typically include type specifications and error handling mechanisms (such as retries, logging, and notifications).
type - required
"type": "pdf"stringerrorAction
"errorAction": "ignore / status=Edit[, stage] / fields={fieldname: fieldvalue, ...}"stringerrorFeedback
"errorFeedback": "Email dispatch failed."stringerrorNotify
"errorNotify": "admin@domain.net"stringerrorNotifySubject
"errorNotifySubject": "Workflow error"stringerrorNotifyTemplate
"errorNotifyTemplate": "errortemplate.txt"stringtype: pdf
create
false, if you want to prevent PDF creation at this time of workflow processing."create": falsebooleantype: copypdf
target
"target": "stage2.pdf"stringtype: condition
condition
==) or inequality (!=), please use uppercase for testing boolean values (True / False). To check if a form field value is null or empty compare the form field to a fake (i.e. not existing) form field."condition": "{field} != True"stringtype: createexcel
Creates an excel with data of the form based on an excel template file that contains form field replacers. These replacers are contained in double curly braces, eg: {{field_id}}, in an excel cell. 
filename
"filename": "form.xlsx"stringtemplate
"template": "excel_template.xlsx"stringtype: email
templateFile - required
"templateFile ": "mailtemplate.txt"stringto - required
"to": "{email-address1},{email-address2}"stringattachDocuments
"attachDocuments": "^stage2.pdf$, ^uploadedDocument.docx$"stringattachimage
"attachimage": "form-logo.png"stringattachImages
"attachImages": truebooleanattachPDF
"attachPDF": truebooleanattachTemplateFiles
"attachTemplateFiles": ["Example.pdf"]Arraybcc
"bcc": "{email-address1},{email-address2}"stringbody
"body": "A new form {title} has been approved"stringbodyFile
"bodyFile ": "mailtemplate.txt"stringcc
"cc": "{email-address1},{email-address2}"stringfilename
"filename": "attachFile.pdf"stringtype: newform
fields
"fields": {"name" : "{name_textfield}", "date": "{work_date}",...}{ [key: string]: string }group
"group": "hf-group"stringowner
"owner": "user@hybridforms.net"stringtemplate
"template": "bc40e199-e8a1-4a4f-9b53-a5e8f16154c0"stringtitle
"title": "{Title}"stringtype: request
clientId
"clientId": "exampleId"stringclientSecret
"clientSecret": "exampleSecret"stringfields
"fields": {"fld1":"result_data_fld1",...}{ [key: string]: string }headers
"headers": {"X-Access-Token":"1234",...}{ [key: string]: string }impersonate
"impersonate": falsebooleanmessage
"message": "Status code '{result_returnCode}' returned by service. Error: {result_message}"stringmetaData
"metaData": "https://adfs.example.com/adfs/.well-known/openid-configuration"stringpassword
"password": "examplePassword"stringrequestType
"requestType": "POST"stringresourceId
"resourceId": "ClientID"booleansuccess
"success": "{result_returnCode}==0"stringtimeout
"timeout": 300numberuserName
"userName": "exampleUser"stringtype: xmlrequest
Send XML formated data to the service.
clientId
"clientId": "exampleId"stringclientSecret
"clientSecret": "exampleSecret"stringfields
"fields": {"fld1":"result_data_fld1",...}{ [key: string]: string }headers
"headers": {"X-Access-Token":"1234",...}{ [key: string]: string }impersonate
"impersonate": falsebooleanmessage
"message": "Status code '{result_returnCode}' returned by service. Error: {result_message}"stringmetaData
"metaData": "https://adfs.example.com/adfs/.well-known/openid-configuration"stringpassword
"password": "examplePassword"stringrequestType
"requestType": "POST"stringresourceId
"resourceId": "ClientID"booleansuccess
"success": "{result_returnCode}==0"stringtimeout
"timeout": 300numbertransformFile
"transformFile": "nameofxsltemplate.xslt"stringuserName
"userName": "exampleUser"stringtype: jsonrequest
Send JSON data to the service.
clientId
"clientId": "exampleId"stringclientSecret
"clientSecret": "exampleSecret"stringfields
"fields": {"fld1":"result_data_fld1",...}{ [key: string]: string }format
"format": "Minimal/Brief/Full/Repeating"stringheaders
"headers": {"X-Access-Token":"1234",...}{ [key: string]: string }impersonate
"impersonate": falsebooleanincludeCharset
"includeCharset": truebooleanincludeFiles
"includeFiles": truebooleanmessage
"message": "Status code '{result_returnCode}' returned by service. Error: {result_message}"stringmetaData
"metaData": "https://adfs.example.com/adfs/.well-known/openid-configuration"stringpassword
"password": "examplePassword"stringrequestType
"requestType": "POST"stringresourceId
"resourceId": "ClientID"booleansuccess
"success": "{result_returnCode}==0"stringtimeout
"timeout": 300numberuserName
"userName": "exampleUser"stringtype: execute
Call an executable or a script on the server. Special parameter {PDF} refers to the path of a copy of the form.pdf file. 
arguments
"arguments": "{templateId} {itemId}"stringprogram
"program": "path_to_script_on_server"stringtype: setowner
owner
"owner": "{field}"stringtype: setcurrentowner
owner
"owner": "{field}"stringtype: setstatus
status
"status ": "Archived"stringtype: setcurrentstatus
status
"status ": "Archived"stringtype: setgroup
group
"group": "grp_admin"stringtype: setcurrentgroup
group
"group": "grp_admin"stringtype: setfield
value
"new value" or by referencing a field value {{another fieldID}} or set the value of RadioBoxes or CheckBoxes using the variant {true}, {false} or {null}"value" : "new value"stringtype: setfeedback
feedback
"feedback" : "Feedback message"stringtype: stagechange
stage
"stage": "stage_3"stringWorkflow Data
Besides any form field value (i.e addressed by {form field id} ) you can use the following server meta data:
| Property | Description | 
|---|---|
| Author | The name of the user who created the form | 
| AuthorEmail | Email of this user (if any) | 
| AuthorID | The ID (UPN) of the user who created the form | 
| ClientId | The ID of the sub system the form belongs to | 
| Created | Creation date of the form item (datetime in UTC format) | 
| Created_Date | Creation date of the form item - dateOnly | 
| Created_HFLocal | "Local" creation time of the form item | 
| Created_Time | Creation time of the form item | 
| Culture | The HF.Culture field from the form definition | 
| DisplayVersion | The version of the form at the time of PDF generation/of the workflow action | 
| Editor | The user who last changed the form | 
| EditorEmail | Email of this user (if any) | 
| EditorID | The ID (UPN) of the user who last changed the form | 
| Group | The name of the currently assigned group. | 
| ItemID | HF.ItemID field | 
| Modified | Date of the last modification of the form item (datetime in UTC format) | 
| Modified_Date | Date of the last modification of the form item - dateOnly | 
| Modified_Time | Only the time of the last modification of the form item | 
| Modified_HFLocal | The "local" time of the last modification of the form item | 
| Owner | The user who owns the form - this must not be the editor!! | 
| OwnerEmail | Email of this user (if any) | 
| OwnerID | The ID (UPN) of the user who owns the form | 
| ReachoutUrl | Url to Reachout form | 
| ReachoutConfirm | Url to Reachout confirm form | 
| ServerUrl | Base url of HybridForms server | 
| StageID | The id of the current form stage | 
| StageLabel | The label of the current form stage | 
| Status | Value of the HF.Status field | 
| TemplateID | HF.FormID of the form definition | 
| TemplateName | The name of the form definition | 
| Title | The form "Title" | 
| Version | The current version number of the Form Item | 
Note: You can use all these server meta data to generate a PDF filename except the time values because of the time format - a colon is not allowed!
Form Definition
Conditions
The visibility of HybridForms elements (e.g. pages, tabs, blocks, fields, etc.) can be defined by a new condition type "stage". The "val" configures the relevant stages.
<form>
    ...
    <li
        data-hf-title="Repair"
        data-hf-condition='{
            "cond": [{
                "type": "stage",
                "id": "stage_2",
                "val": true
            }],
            "else": "readonly"
        }'
    >
        <a href="#repair-block1"></a>
        <a href="#repair-block2"></a>
    </li>
    <li>...</li>
</form>
list-/headerTemplate
The stage id and stage label can be used by the list-/headerTemplate as well. Access the information by "data.stage.id" and "data.stage.label".
<form>
    ...
    <span data-hf-bind="textContent: data.stage.id"></span>
    <span data-hf-bind="textContent: data.stage.label"></span>
    ...
</form>
Images in mailtemplate.txt
Attached images can be referenced inside your email body by the HTML tag img and the path prefix `cid.
<img src="cid:logo.png" />