Client Scripting

The PayrollEngine.Client.Scripting library defines the complete scripting contract between the Payroll Engine backend and client tooling. It contains all scripting function classes, runtime interfaces, No-Code action infrastructure, and script parsing utilities.

All C# source files are embedded as resources in the assembly. The backend Roslyn compiler extracts them at runtime to build the compilation context in which payroll scripts are evaluated — no separate SDK installation is required on the server.


Scripting Functions

All scripting functions are defined in the PayrollEngine.Client.Scripting.Function namespace and inherit from a common base hierarchy.

Function
├── PayrollFunction
│   ├── CaseFunction
│   │   ├── CaseAvailableFunction
│   │   └── CaseChangeFunction
│   │       ├── CaseBuildFunction
│   │       └── CaseValidateFunction
│   ├── CaseRelationFunction
│   │   ├── CaseRelationBuildFunction
│   │   └── CaseRelationValidateFunction
│   └── PayrunFunction
│       ├── PayrunStartFunction
│       ├── PayrunEndFunction
│       ├── PayrunEmployeeAvailableFunction
│       ├── PayrunEmployeeStartFunction
│       ├── PayrunEmployeeEndFunction
│       ├── PayrunWageTypeAvailableFunction
│       ├── CollectorFunction
│       │   ├── CollectorStartFunction
│       │   ├── CollectorApplyFunction
│       │   └── CollectorEndFunction
│       └── WageTypeFunction
│           ├── WageTypeValueFunction
│           └── WageTypeResultFunction
└── ReportFunction
    ├── ReportBuildFunction
    ├── ReportStartFunction
    └── ReportEndFunction

Case Functions

Case functions control the lifecycle of a case input form — from visibility through field population to final validation.

Function Base Description
CaseAvailableFunction CaseFunction Determines whether a case is offered for input. Returning false hides the case from the user entirely. Typical use: role-based or condition-based availability.
CaseBuildFunction CaseChangeFunction Populates or pre-fills case fields before the form is displayed. Used to set default values, apply lookups, or derive field values from existing case data.
CaseValidateFunction CaseChangeFunction Validates case field values when the user submits the form. Can add validation issues that are shown inline.

Case Relation Functions

Case relation functions control how values are transferred and validated when one case references another via a relation.

Function Base Description
CaseRelationBuildFunction CaseRelationFunction Populates target case fields based on the source case values when a relation is applied.
CaseRelationValidateFunction CaseRelationFunction Validates the combined source/target case values within the context of the relation.

Payrun Functions

Payrun functions cover the full execution lifecycle of a payrun — from start/end events at the payrun and employee level through wage type calculation and collector aggregation.

Payrun Lifecycle

Function Base Description
PayrunStartFunction PayrunFunction Executes once at the start of the entire payrun, before any employee is processed. Used for payrun-level initialization.
PayrunEndFunction PayrunFunction Executes once at the end of the entire payrun, after all employees have been processed. Used for payrun-level finalization.
PayrunEmployeeAvailableFunction PayrunFunction Determines whether an employee participates in the current payrun. Returning false skips the employee entirely.
PayrunEmployeeStartFunction PayrunFunction Executes at the start of each employee's payrun processing. Used for per-employee initialization.
PayrunEmployeeEndFunction PayrunFunction Executes at the end of each employee's payrun processing. Used for per-employee finalization or result enrichment.
PayrunWageTypeAvailableFunction PayrunFunction Determines whether a specific wage type is evaluated for an employee in this payrun. Returning false skips the wage type calculation.

Wage Type Functions

Function Base Description
WageTypeValueFunction WageTypeFunction Calculates the numeric value of a wage type for an employee in the current period. The core calculation script — reads case values, applies rates, performs arithmetic.
WageTypeResultFunction WageTypeFunction Post-processes the calculated wage type result. Used to add custom result attributes, split results, or trigger side effects after the value is determined.

Collector Functions

Collectors aggregate wage type values across a payrun. Their functions run around the collection process for each contributing wage type.

Function Base Description
CollectorStartFunction CollectorFunction Executes when the collector is first activated in a payrun. Used to initialize collector state or set starting values.
CollectorApplyFunction CollectorFunction Executes each time a wage type value is applied to the collector. Can modify or veto the value before it is accumulated.
CollectorEndFunction CollectorFunction Executes after the last wage type has been applied. Used for final adjustments, caps, or result enrichment on the accumulated value.

Report Functions

Report functions control the three-phase execution of a report: structure definition, data retrieval, and post-processing.

Function Base Description
ReportBuildFunction ReportFunction Defines the report structure: adds or removes report parameters, adjusts queries, and controls which data sets are included based on input parameters.
ReportStartFunction ReportFunction Executes at report start after parameters are resolved. Used to prepare or transform data before the main report queries run.
ReportEndFunction ReportFunction Executes after all report queries have completed. Used to post-process result sets, merge tables, compute derived columns, or apply final formatting.

No-Code Actions

Namespace Description
PayrollEngine.Client.Scripting Action attributes (CaseAvailableActionAttribute, CaseBuildActionAttribute, …) and the ActionReflector for parsing action expressions
PayrollEngine.Action Core action infrastructure: ActionInfo, ActionIssue, ActionMethodInfo, parameter and property metadata

Actions allow payroll specialists to control object behaviour using text expressions in regulation JSON — no C# programming required.

Action syntax

Actions can be used to determine the behaviour of payroll objects, even without any programming knowledge. The following events can be controlled:

  • Case
    • Available — Availability of a case
    • Build — Case creation
    • Validate — Case validation
  • CaseRelation
    • Build — Creation of the case relation
    • Validate — Validation of the case relation creation
  • Collector
    • Start — Initialization of the collector
    • Apply — Application of wage type result 1)
    • End — Completion of the collector
  • WageType
    • Value — Wage type result 1)
    • Result — Additional wage type result

1) Function event with return value.

A list of actions is executed sequentially for each event. For events that expect a return value, the final action calculates the result.

Expression Fields

Actions are placed in the corresponding expression field of the regulation object:

Object Expression field When executed
Case availableActions Before form displays
Case buildActions While form is open
Case validateActions On form submit
WageType valueActions During payrun calculation
Collector startActions / applyActions / endActions Collector lifecycle

Important: valueActions and valueExpression are mutually exclusive. valueActions is for No-Code expressions. valueExpression is for Low-Code C# scripts. No-Code tokens (^^, ^$, ^&, ^#) are not valid C# and must never appear in valueExpression.

Action Namespace

Actions reference payroll objects by name. To distinguish objects across regulations, define a regulation namespace — it is added automatically. Cross-regulation references require the explicit namespace prefix:

# access to case field CH.Salary (regulation namespace = CH)
^^Salary
# access to case field from the DE namespace
^^DE.Salary

Action Types

Type Line start Description
Comment # Not executed
Condition ? Conditional action — guards remaining actions
Instruction (any other) Execution action — last instruction = return value

Example: overtime pay for full-time employees only:

# Guard: skip for part-time employees
? ^^EmploymentLevel >= 1.0
# Guard: only calculate when overtime hours are entered
? ^^OvertimeHours > 0
# Result: hours x hourly rate (Salary / 160h) x 1.25 surcharge
^^OvertimeHours * (^^Salary / 160) * 1.25

Action Conditions

Syntax Description Example
? <cond> Continue condition for the next action ? ^^EmploymentLevel >= 1.0
? <cond> ?= <true> Conditional action result ? PeriodStart.Month != 12 ?= 0
? <cond> ?= <true> ?! <false> Conditional action result with fallback value ? ^^TaxClass == 1 ?= 0.15 ?! 0.25

Condition expressions:

Syntax Description Example
x && y Logical AND ? ^^Salary >= 500 && ^^Salary <= 25000
x \|\| y Logical OR ? ^^EmploymentLevel < 0.1 \|\| ^^EmploymentLevel > 1.0
x ? y : z Ternary conditional ^\|TaxRate = ^^GrossIncome > 10000 ? 0.25 : 0.15

Action References

The reference to a payroll object starts with the circumflex character ^, followed by the object marker.

Syntax Target Context Object Data type Access Example
^# Lookup value Anytime All any r ^#IncomeTax(^&GrossIncome)
^^ Case value Anytime All any r ^^Salary * ^^EmploymentLevel
^: Case field Case change Case any r/w ^:Salary.Start < PeriodStart
^< Source case field Case change CaseRelation any r/w ^<EmploymentLevel < 1.0
^> Target case field Case change CaseRelation any r/w ^>Salary = ^<Salary * ^<EmploymentLevel
^\| Runtime value Payrun Collector, WageType any r/w ^\|GrossPay = ^^Salary * ^^EmploymentLevel
^@ Payrun result Payrun Collector, WageType any r/w ^@AnnualBonus = ^^Salary * 12
^$ Wage type value Payrun WageType decimal r ^$BaseSalary * 0.08
^& Collector value Payrun WageType decimal r ^&GrossIncome * ^#IncomeTax(^&GrossIncome)

Lookup Reference

Lookup values are referenced using ^#. Access is possible by key, rangeValue, or both. For JSON object lookup values, use the field parameter to access a property:

^#LookupName(key)
^#LookupName(key, field)
^#LookupName(rangeValue)
^#LookupName(rangeValue, field)
^#LookupName(key, rangeValue)
^#LookupName(key, rangeValue, field)

Concrete examples:

# Simple key lookup: holiday allowance rate for employment class A
^#HolidayAllowance('A')
# Range lookup: income tax rate for the current gross income bracket
^#IncomeTax(^&GrossIncome)
# Range lookup with JSON field: employee social security contribution rate
^#SocialSecurity(^^Salary, 'EmployeeRate')

Case Value Reference

The ^^ syntax accesses employee or company case data. When several time values are multiplied, overlapping periods within the payroll period are handled automatically:

# Scale monthly salary by employment level
^^Salary * ^^EmploymentLevel

Time values are not supported when calculating a case field value against other payroll objects.

Collector Reference

Collectors are referenced using the ^& syntax. An optional scope selector controls the time range of the value:

Syntax Scope Description
^&Name Period (default) Collector value of the current payrun period
^&Name.Cycle Cycle Year-to-date collector value across all previous payruns in the current cycle
# Current period gross income
^&GrossIncome

# Year-to-date gross income (previous payruns in the cycle)
^&GrossIncome.Cycle

# Income tax: gross income times bracket rate from range lookup
^&GrossIncome * ^#IncomeTax(^&GrossIncome)

Wage Type Reference

Wage types are referenced using the ^$ syntax. Wage types can be identified by name or by number. An optional scope selector controls which value is returned:

Syntax Scope Description
^$Name or ^$100 Period (default) Wage type value of the current payrun period (by name or number)
^$Name.Cycle Cycle Year-to-date wage type value across all previous payruns in the current cycle
^$Name.RetroSum RetroSum Net sum of all pending retro corrections for the wage type within the current cycle
# Social security: 8% on current period base salary
^$BaseSalary * 0.08

# Reference by wage type number
^$100 * 0.08

# Year-to-date base salary (previous payruns in the cycle)
^$BaseSalary.Cycle

# Retro delta wage type: net correction for BaseSalary since last closed period
^$BaseSalary.RetroSum

Action Values

Supported value types:

Type Format
String Text with "double" or 'single' quotes
Date ISO 8601 UTC — e.g. 2026-01-16T16:06:00Z
Boolean true or false
Int Signed 32-bit integer
Decimal 16-byte floating-point number

Operators:

Syntax Description Supported types Example
+ Addition 1) String, Int, Decimal ^^Salary + ^^Bonus
- Subtraction 1) Int, Decimal ^^Salary - ^&Deductions
* Multiplication 2) Int, Decimal ^^Salary * ^^EmploymentLevel
/ Division 2) Int, Decimal ^^Salary / 160
% Remainder 2) Int, Decimal ^^OvertimeHours % 8
& Binary logical AND Boolean ^^IsActive & ^^HasContract
\| Binary logical OR Boolean ^^IsManager \| ^^IsTeamLead
< Less than Date, Int, Decimal ^^EmploymentLevel < 1.0
<= Less than or equal Date, Int, Decimal ^^Salary <= 25000
== Equal All ^^TaxClass == 1
!= Not equal All ^^TaxClass != 3
>= Greater than or equal Date, Int, Decimal ^^EmploymentLevel >= 1.0
> Greater than Date, Int, Decimal ^^Salary > 5000

1) Undefined operand value: 0. 2) Undefined operand value: 1.

Value test properties:

Property Description Result type Example
HasValue Test if value is defined Boolean ^^BonusRate.HasValue
IsNull Test if value is undefined Boolean ^^SpecialAllowance.IsNull ? 0 : ^^SpecialAllowance
IsString Test for string value Boolean ^^CostCenter.IsString
IsInt Test for integer value Boolean ^^TaxClass.IsInt
IsDecimal Test for decimal value Boolean ^^EmploymentLevel.IsDecimal
IsNumeric Test for numeric value (int or decimal) Boolean ^^ZipCode.IsNumeric
IsDateTime Test for date value Boolean ^^EntryDate.IsDateTime
IsBool Test for boolean value Boolean ^^IsActive.IsBool

Value conversion properties:

Property Description Result type Example
AsString Convert to string String ^^TaxClass.AsString
AsInt Convert to integer Int ^^EmploymentLevel.AsInt
AsDecimal Convert to decimal Decimal ^^TaxClass.AsDecimal
AsDateTime Convert to date Date ^^EntryDate.AsDateTime
AsBool Convert to boolean Boolean ^^IsActive.AsBool

Math methods (numeric values):

Method Description Result type Example
Round(decimals?, rounding?) Round decimal value Decimal ^^Salary.Round(2)
RoundUp(step?) Round up Decimal ^^Salary.RoundUp()
RoundDown(step?) Round down Decimal ^^Salary.RoundDown()
Truncate(step?) Truncate decimal Decimal ^^OvertimeHours.Truncate()
Power(factor) Power Decimal ^^CompoundRate.Power(12)
Abs() Absolute value Decimal ^^RetroCorrection.Abs()
Sqrt() Square root Decimal ^^VarianceAmount.Sqrt()

Runtime Properties

The following function properties are available in read mode within an action:

Property Description Data type Function
UserIdentifier User identifier String All
UserCulture User culture String All
SelfServiceUser Test for self-service user Boolean All
EmployeeIdentifier Employee identifier String PayrollFunction
Namespace Regulation namespace String PayrollFunction
CycleStart Payroll cycle start date Date PayrollFunction
CycleEnd Payroll cycle end date Date PayrollFunction
CycleDays Payroll cycle day count Decimal PayrollFunction
EvaluationDate Payroll evaluation date Date PayrollFunction
PeriodStart Payroll period start date Date PayrollFunction
PeriodEnd Payroll period end date Date PayrollFunction
PayrunName Payrun name String PayrunFunction
IsRetroPayrun Test for retro payrun Boolean PayrunFunction
IsCycleRetroPayrun Test for cycle retro payrun Boolean PayrunFunction
Forecast Forecast name String PayrunFunction
IsForecast Test for forecast payrun Boolean PayrunFunction
PeriodName Payrun period name String PayrunFunction
CollectorName Collector name String CollectorFunction
CollectMode Collect mode String CollectorFunction
Negated Test for negated collector Boolean CollectorFunction
CollectorThreshold Threshold value Decimal CollectorFunction
CollectorMinResult Minimum allowed result Decimal CollectorFunction
CollectorMaxResult Maximum allowed result Decimal CollectorFunction
CollectorResult Collector result value Decimal CollectorFunction
CollectorCount Collected values count Decimal CollectorFunction
CollectorSummary Summary of collected values Decimal CollectorFunction
CollectorMinimum Minimum collected value Decimal CollectorFunction
CollectorMaximum Maximum collected value Decimal CollectorFunction
CollectorAverage Average of collected values Decimal CollectorFunction
WageTypeNumber Wage type number Decimal CollectorApplyFunction, WageTypeFunction
WageTypeName Wage type name String CollectorApplyFunction, WageTypeFunction
WageTypeValue Wage type value Decimal CollectorApplyFunction, WageTypeResultFunction
WageTypeDescription Wage type description String WageTypeFunction
WageTypeCalendar Wage type calendar String WageTypeFunction
ExecutionCount Wage type value execution count Int WageTypeValueFunction

All derived functions inherit access to their parent function's properties. For example, all payrun functions can access PayrollFunction properties.

Integrated Actions

The Payroll Engine provides a library of predefined actions. Selected examples:

Action Description
ApplyRangeLookupValue(key, rangeValue, field) Apply a range value to lookup brackets considering the lookup range mode
Concat(str1, ..., strN) Concatenate multiple strings
Contains(test, sel, ..., selN) Test if a value belongs to a specific value domain
IIf(expression, onTrue, onFalse) Return one of two values depending on an expression
Log(message, level?) Log a message
Min(left, right) Get the minimum of two values
Max(left, right) Get the maximum of two values
Range(value, min, max) Clamp a value within a range

See the full integrated action reference for all available actions. Custom actions can be added via Low-Code; see Custom Actions.


Core Scripting Types

Namespace Description
PayrollEngine.Client.Scripting Central scripting types: CaseObject, PayrollValue, CasePayrollValue, DatePeriod, function and script attributes
PayrollEngine.Client.Scripting.Report Report-specific types used within report functions

Client Infrastructure

Namespace Description
PayrollEngine.Client HTTP client (PayrollHttpClient), API endpoint definitions, console base classes, configuration
PayrollEngine.Client.Model Payroll domain model: Tenant, Employee, Case, CaseField, WageType, Collector, Payrun, …
PayrollEngine.Client.Exchange Exchange import/export model and visitor pattern for regulation data
PayrollEngine.Client.QueryExpression Fluent query expression builder for REST API filter parameters
PayrollEngine.Client.Command CLI command base classes
PayrollEngine.Client.Script Script parsers for extracting function code from regulation objects during import/export

Shared Core

Namespace Description
PayrollEngine Fundamental shared types: enumerations, extensions, calendar utilities, value types
PayrollEngine.Data Data handling utilities
PayrollEngine.Document Document model types
PayrollEngine.IO IO utilities
PayrollEngine.Serialization JSON serialization helpers

Links

  • Scripting Documentation
  • Repository
  • NuGet
  • Edit this page
☀
☾
Back to top Generated by DocFX