Skip to content

Custom Actions

Jani Giannoudis edited this page Jan 7, 2026 · 13 revisions

Custom Actions

The Payroll Engine provides case actions to control and validate user input. The existing case actions can be extended with the regulation object Script.

  1. implement case action in C#
  2. insert action in regulation
  3. test action
  4. use action

In the following tutorial example, an action is created to validate the company ID. It is to be checked whether the checksum of the company ID complies with the ISO 7064 standard.

Case Action

The case action consists of metadata in the form of C# attributes and the implementation. For validation actions, errors are included with the AddIssue method. The case action consists of the implementation and the metadata in the form of C# attributes.

1  namespace PayrollEngine.Client.Scripting.Function;
2  public partial class CaseValidateFunction
3  {
4      [ActionIssue("InvalidUId", "(0) with invalid UID: (1)", 2)]
5      [ActionParameter("caseFieldName", "The case field name")]
6      [ActionParameter("uid", "The UID text")]
7      [CaseValidateAction("CheckUId", "Validate for the Swiss company id (UID)")]
8      public bool CheckUId(string caseFieldName, string uid)
9      {
10          // extract check value
11          var checkValue = uid.RemoveFromStart("CHE-").Replace(".", string.Empty);
12          try
13          {
14              // ISO 7064 digit check with modulus, radix, character-set and double-check-digit option
15              new CheckDigit(11, 1, "0123456789", false).Check(checkValue);
16              return true;
17          }
18          catch (CheckDigitException)
19          {
20              LogError($"Invalid Uid check value {checkValue}.");
21              AddCaseAttributeIssue("InvalidUId", caseFieldName, $"Invalid UId: {uid},");
22          }
23          return false;
24      }
25  }

The code in detail:

  • 2-25: Function class extension
  • 4: Issue registration Invalid id (meta data)
  • 5: Parameter registration for the case field name (meta data)
  • 6: Parameter registration for the UID to test (meta data)
  • 7: Action registration inclduing the action name and description (meta data)
  • 11: Action registration with the key CheckUId (meta data)
  • 11-23: Action implementation
  • 16: Valid UID result
  • 20: Log validation error (optional)
  • 21: Add digit check issue
  • 23: Invalid UID result

You can also use the predefine digit checks Mod11Radix2, Mod37Radix2, Mod97Radix10, Mod661Radix26, Mod1271Radix36.

Regulation Action

Next, the script with the validation function is included in the regulation:

1  "regulations": [
2    {
3      "name": "ActionRegulation",
4      "lookups": [
5        {
6          "name": "MyActions.Actions",
7          "values": [
8            {
9              "key": "InvalidUId",
10              "value": "(0) is invalid: (1)",
11              "valueLocalizations": {
12                "de": "(0) ist ungültig: (1)"
12              }
13            }
14          ]
15        }
16      ],
17      "cases": [
18        {
19          "name": "UId",
20          "caseType": "Employee",
21          "defaultReason": "Test UId",
22          "validateActions": [
23            "? CheckUId('UId', ^:UId)"
24          ],
25          "fields": [
26            {
27              "name": "UId",
28              "valueType": "String",
29              "timeType": "Period",
30              "valueMandatory": true,
31              "defaultStart": "today",
32              "attributes": {
33                "input.valueMask": "CHE-000.000.000",
34                "input.valueHelp": "Format CHE-123.456.789"
35              }
36            }
37          ]
38        }
39      ],
40      "scripts": [
41        {
42          "name": "MyActions",
43          "functionTypes": [
44            "CaseValidate"
45          ],
46          "valueFile": "Scripts/CaseValidateFunction.cs"
47        }
48      ]
49    }
50  ]

The structure of the regulation in detail:

  • 4-16: Lookups for the localisation of the validation messages
  • 6: The lookup name according to the convention ActionNamespace.Action
  • 27-39: The case with the field UId
  • 23: Use of the case action CheckUId (seeAction-Syntax)
  • 41-47: Registration of the case validation function script
  • 44: Using script for case validate functions
  • 46: Local script source file

Action Test

The validation action UId is checked with the following test:

1  {
2    "$schema": "../../Schemas/PayrollEngine.CaseTest.schema.json",
3    "testName": "Test.UId",
4    "tenantIdentifier": "ActionTenant",
5    "userIdentifier": "lucy.smith@foo.com",
6    "employeeIdentifier": "mario.nuñez@foo.com",
7    "payrollName": "ActionPayroll",
8    "validateTests": [
9      {
10       "testName": "UId.Valid.999999996.Test",
11       "input": {
12         "userIdentifier": "lucy.smith@foo.com",
13         "employeeIdentifier": "mario.nuñez@foo.com",
14         "divisionName": "ActionDivision",
15         "case": {
16           "caseName": "UId",
17           "values": [
18             {
19               "caseFieldName": "UId",
20               "value": "999999996"
21             }
22           ]
23         }
24       },
25       "output": {
26         "values": [
27           {
28             "caseFieldName": "UId",
29             "value": "999999996"
30           }
31         ]
32       }
33     },
34     {
35       "testName": "UId.Invalid.999999997.Test",
36       "input": {
37         "userIdentifier": "lucy.smith@foo.com",
38         "employeeIdentifier": "mario.nuñez@foo.com",
39         "divisionName": "ActionDivision",
40         "case": {
41           "caseName": "UId",
42           "values": [
43             {
44               "caseFieldName": "UId",
45               "value": "999999997"
46             }
47           ]
48         }
49       },
50       "output": {
51         "issues": [
52           {
53             "caseFieldName": "UId",
54             "issueType" : "CaseInvalid",
55             "number": 400
56           }
57         ]
58       }
59     }
60   ]
61 }

The data in detail:

  • 9-33: Test with valid UId
  • 20: The simulated case value 999999996
  • 29: The expected case value 9999996
  • 34-59: Test with invalid UId
  • 45: The simulated case value 999999997
  • 55: The expected HTTP error 400

Command to execute the test

PayrollConsole CaseTest Test.et.json

Action Usage

Finally, the validation also takes effect in the web application with a corresponding error message.

Case Validation

Next steps

  • Resources with documents, blogs, tests and examples

Clone this wiki locally