Skip to main content

Transform

The Transform task is the workflow's built-in calculation and data manipulation engine. It runs silently — no user action, no task list entry — reads values from the submission, performs an operation, and writes the result back into the submission. Downstream tasks immediately see the new value.

note

All transform results are strings, even numeric ones. If a subsequent task or form field expects a number, OSPROV will cast it correctly in most contexts, but be aware of this when debugging unexpected results.

If a transform fails, it is marked invalid and the workflow continues — it is not blocked.


The Four Transform Types

OSPROV has exactly four built-in transform types.

GenerateRunningNumber

Generates a sequential reference number built into a format string you define. Every submission that passes through increments the counter by one.

Input — a format string containing [FUNC] where the sequential number should appear, plus any placeholders or literal text:

HR/LEAVE/[YYYY]/[MM]/[FUNC]

Result: HR/LEAVE/2025/04/000023

Running Number Digits — controls zero-padding. Default is 6 (000023). Set to 4 for 0023, set to 8 for 00000023.

[FUNC] is only meaningful in GenerateRunningNumber. In any other transform type it would remain as literal text.

Counter is tied to the resolved format string

The counter increments separately for each unique resolved string. HR/LEAVE/2025/04/[FUNC] and HR/LEAVE/2025/05/[FUNC] are separate counters — each month starts fresh at 000001. This is intentional for period-based numbering. If you want a single global counter that never resets, use a format without date placeholders: LEAVE-[FUNC].


AddNumbers

Adds three values — A + B + C — and writes the sum to the output field. Blank inputs count as zero. The result is a string.

A = [unitPrice],  B = [taxAmount],  C = 0
Output → [totalCost]

The limit is three inputs. To add more values, chain two AddNumbers transforms in sequence — the first writes to an intermediate field, the second reads that field as one of its inputs.


ConcatenateStrings

Joins up to five strings into one. No separator is added automatically — include any spaces, slashes, or dashes you need as literal text in their own input slot.

A = [firstName],  B = " ",  C = [lastName]
→ "John Smith"

A = "REF-", B = [submissionId], C = "-", D = [YYYY]
→ "REF-SUB-0042-2025"

GenerateGUID

Generates a globally unique identifier. No inputs needed. Every execution produces a different value. The result is uppercase and time-sortable.

Example: 018F2A3B-4C5D-6E7F-8091-A2B3C4D5E6F7

Use when you need a guaranteed-unique reference that does not need to be human-readable — for example, a record ID for integration with an external system.


Placeholder Reference

All input fields support placeholders — text in square brackets replaced with real values at runtime.

PlaceholderValue
[fieldKey]Value of that field from the main form
[forms.2.fieldKey]Field from the 2nd supplementary form
[submissionId]Submission reference, e.g. SUB-0001
[submittedBy]Username of who submitted
[YYYY]4-digit year
[YY]2-digit year
[MM]2-digit month (01–12)
[M]Month without leading zero (1–12)
[D]2-digit day (01–31)
[FUNC]Running number — GenerateRunningNumber only
There is no [DD]

The day placeholder is [D]. If you type [DD], the system looks for a form field named DD, finds nothing, and writes an empty string. There is no error — just silent wrong output.

Date placeholder timing: Date placeholders ([YYYY], [MM], [D], etc.) reflect the moment the Transform executes — not when the form was submitted. If a workflow has a long approval process and the Transform runs in a different month from submission, [MM] will reflect the execution month. Design running number schemes with this in mind.


The Output Field

The Output field specifies where the result is written. Use the same bracket syntax:

  • [fieldKey] — writes to a main form field
  • [forms.2.fieldKey] — writes to a field in the 2nd supplementary form

The output writes directly into the submission data by key. The field does not need to have a matching form component. If no component with that key exists on the form, the value is still stored in the submission data and available to all downstream tasks — it just won't appear in any form view.

The recommended pattern is to add a Hidden field to the form with a specific key, and use that key as your output. This makes the value accessible in form views, condition tasks, and document templates without adding visible clutter to the form.


Chaining Transforms

Multiple Transform tasks can be placed in sequence. Each one sees the updated submission data from the previous one, so the output of one transform can be used as an input to the next.

Transform 1: AddNumbers
A = [unitPrice], B = [taxAmount], C = 0
Output → [totalCost]

Transform 2: ConcatenateStrings
A = "Invoice total: RM ", B = [totalCost]
Output → [invoiceSummary]

Notification: "Your request summary: [invoiceSummary]"

Adding a Transform Task to Your Workflow

  1. Drag the Transform task from the task palette onto the canvas
  2. Click the task to open its configuration panel
  3. Select the Transform type from the dropdown
  4. Fill in the input fields — use [placeholders] to reference submission data
  5. Set the Output field key where the result should be written
  6. Optionally set Title for process and Label for status

Troubleshooting

ProblemLikely cause
Transform marked invalidA placeholder referenced a field that doesn't exist, or the transform threw an unexpected error. Check all [placeholder] keys against Technical Properties (case-sensitive). Check system logs.
Output field is empty after transformAn input placeholder resolved to empty (field missing or wrong key), or the wrong key was used in Output.
[DD] producing empty output[DD] is not a date placeholder. Use [D] for the day.
Running number not incrementing[FUNC] must be present in the Input string. Without it, the counter increments internally but the number is never embedded in the result.
Running number resets unexpectedlyThe counter is keyed on the resolved format string. A month or year change produces a new string and starts a new counter. Use a format without date placeholders for a global counter.
AddNumbers giving wrong resultCheck all inputs are numeric. Blank counts as 0. Text values cast to 0. Result is a string.
Concatenate joining in wrong orderInputs A through E are joined left to right. Put literal separators (spaces, dashes, slashes) in their own input slot.
Output not visible in form viewExpected if no form component has that key. The value is still in the submission data and available to downstream tasks. Add a Hidden field with that key to make it visible.