Skip to content

Basic Payroll

Jani Giannoudis edited this page Feb 18, 2026 · 32 revisions

Basic Payroll Example

This example shows how to set up and test a payroll for a company that pays its employees monthly. The sample data is located in the installation folder Examples\StartPayroll. Please make sure that the Backend-Server of the Payroll Engine is available.

Payroll Model

The Payroll Engine calculates the salary with the following objects.

Payroll Model

The employees of a tenant are assigned to one or more divisions. The payroll runs refer to a division, so that an employee can be accounted for from different divisions.

Console Format

Mit der Payroll Console können die Daten in den Formaten:

  • JSON: Beispiel in Examples/StartPayroll.Json
  • YAML: Beispiel in Examples/StartPayroll.Yaml

Payroll Setup

The salary calculation can be done in three ways:

  • HTTP Rest API queries with a tool, e.g. Postman
  • Console/YAML - text editor, e.g. VS Code and transfer with the Payroll Console
  • Interactive with the web application (requires the Web Application Server)

The following steps describe how to set up the start payroll:

Step JSON Web Application REST Endpoint
Set JSON schema 01 - -
Set object creation date 02 - -
Add Tenant 04-53 Tenants > Add 1) CreateTenant
Add User 06-11 Users > Add CreateUser
Add Division 12-13 Divisons > Add CreateDivision
Add Employee 14-19 Employees > Add CreateEmployee
Add Regulation 20-44 Regulations > Add CreateRegulation
Add Case 22-34 Regulation > Cases > Add CreateCase
Add Case Field 31-43 Regulation > Case Fields > Add CreateCaseField
Add Collector 35-38 Regulation > Collectors > Add CreateCollector
Add Wage Type 39-44 Regulation > Wage Types > Add CreateWageType
Add Payroll 45-50 Payrolls > Add CreatePayroll
Add Payroll Layer 48-50 Payroll Layers > Add CreatePayrollLayer
Add Payrun 51-53 Payruns > Add CreatePayrun

1) The initial tenant must be created using the REST API or Payroll Console.

Example payroll Basic.yaml:

1   # yaml-language-server: $schema=../../Schemas/PayrollEngine.Exchange.schema.json
2   createdObjectDate: 2023-01-01T00:00:00Z
3   tenants:
4   - identifier: StartTenant
5     culture: en-US
6     users:
7     - identifier: lucy.smith@foo.com
8       firstName: Lucy
9       lastName: Smith
10      culture: en-US
11      userType: TenantAdministrator
12    divisions:
13    - name: StartDivision
14    employees:
15    - identifier: mario.nuñez@foo.com
16      firstName: Mario
17      lastName: Nuñez
18      divisions:
19      - StartDivision
20    regulations:
21    - name: StartRegulation
22      cases:
23      - name: Salary
24        caseType: Employee
25        buildExpression: "true"
26        validateExpression: "true"
27        buildActions:
28        - ^:Salary = Range(^:Salary, 500, 25000)
29        validateActions:
30        - '? Within(^:Salary, 500, 25000)'
31        fields:
32        - name: Salary
33          valueType: Money
34          timeType: CalendarPeriod
35      collectors:
36      - name: Income
37      - name: Deduction
38        negated: true
39      wageTypes:
40      - wageTypeNumber: 100
41        name: Salary
42        valueExpression: CaseValue["Salary"]
43        collectors:
44        - Income
45    payrolls:
46    - name: StartPayroll
47      divisionName: StartDivision
48      layers:
49      - regulationName: StartRegulation
50        level: 1
51    payruns:
52    - name: StartPayrun
53      payrollName: StartPayroll

The payroll definition in detail:

  • 1: Path to the JSON schema (adapt this to your local environment)
  • 2: Default creation date for each object
  • 4: The unique tenant identifier StartTenant
  • 5: The tenant culture en-US
  • 7: The user identifier lucy.smith@foo.com
  • 10: The user culture en-US
  • 11: The user type TenantAdministrator
  • 13: The division identifier StartDivision
  • 19: The employee's assignment to the division(s)
  • 21: The regulation identifier StartRegulation
  • 23: The Salary case name
  • 24: The case type employee (other types: global, national and company)
  • 28: Case buld action: ensure salary is within the valid range
  • 30: Case buld action: validate salary range
  • 33: The case field value type: Money
  • 34: The case field time type calendar period
  • 36: The income collector
  • 37: The deduction collector
  • 38: Negated deduction collector
  • 40: Wage type number 100, controls the process order of the payrun
  • 42: Wage type value expression: calculated from case value
  • 44: Wage type collector Income
  • 46: Payroll assignment to the division
  • 49: Payroll layer assignment to the regulation
  • 53: Payrun assignment to the payroll

The fields Identifier, Name and WageTypeNumber must each be unique.

With the command 1 Basic.Setup.pecmd the Payroll Console sends the data of the YAML file to the backend.

Payroll Test

The payroll test is carried out in three steps:

Step Description YAML
1 Add employee case Salary 10-16
2 Add payrun job for January 2023 18-27
3 Test the payrun wage type and collector results 28-37

Exampe payroll test Basic.Test.et.yaml:

1   # yaml-language-server: $schema=../../Schemas/PayrollEngine.Exchange.schema.json
2   tenants:
3   - identifier: StartTenant
4     payrolls:
5     - name: StartPayroll
6       cases:
7       - userIdentifier: lucy.smith@foo.com
8         employeeIdentifier: mario.nuñez@foo.com
9         divisionName: StartDivision
10        case:
11          caseName: Salary
12          values:
13          - caseFieldName: Salary
14            value: "5000"
15            start: 2023-01-01T00:00:00Z
16            created: 2022-11-04T00:00:00Z
17      updateMode: NoUpdate
18    payrunJobInvocations:
19    - name: StartPayrunJob.Jan23
20      payrunName: StartPayrun
21      userIdentifier: lucy.smith@foo.com
22      jobStatus: Complete
23      periodStart: 2023-01-01T00:00:00Z
24      evaluationDate: 2023-02-01T00:00:00Z
25      reason: Test Payrun Jan 23
26      employeeIdentifiers:
27      - mario.nuñez@foo.com
28    payrollResults:
29    - payrunJobName: StartPayrunJob.Jan23
30      employeeIdentifier: mario.nuñez@foo.com
31      wageTypeResults:
32      - wageTypeNumber: 100
33        value: 5000
34      collectorResults:
35      - collectorName: Income
36        value: 5000
37      - collectorName: Deduction
38    updateMode: NoUpdate

Der payroll test in detail:

  • 1: Path to the JSON schema (adjust this to your local environment)
  • 5: Payroll name
  • 8: The employee of the case
  • 9: The division(s) of the employee's case
  • 10: The new employee's salary
  • 14: The salary value
  • 15: The salary start date
  • 16: The creation date of the change, simulation of the previous salary change
  • 17: Prevent payroll update 1)
  • 19: Payrun job name
  • 20: Payrun job assignment to the payrun
  • 22: Complete the payrun job, test scenario
  • 23: Payrun period date
  • 24: Payrun execution date, simulation of past payrun execution
  • 27: Employee(s) of the payrun job
  • 29: Name of the payrun job to be tested
  • 30: Employee to test the result
  • 32: Wage type to be tested
  • 33: The expected wage type (100) value 5'000
  • 35: The expected colletor (Income) value 5'000
  • 37: The expected colletor (Deduction) value 0
  • 38: Prevent tenant update 1)

1) The UpdateMode offers the possibility to split an object into several YAML files. In the root YAML, the base structure (tenant, regulation...) is defined, the child objects are managed in separate YAML files and deactivate the update mode for the base objects. When importing, the root object remains unchanged, only the child objects with active update mode are updated.

The command 1 Basic.Test.pecmd runs the test on a copy of the employee mario.nuñez@foo.com.

Next steps

Clone this wiki locally