Skip to content

Advanced Payroll

Jani Giannoudis edited this page Jul 31, 2023 · 11 revisions

Advanced Payroll Example

This example shows how payroll is divided into several regulations. For this purpose, the start example Examples\StartPayroll is extended by two regulations:

  • Insurance regulation with income-dependent contribution
  • Company regulation with company-specific benefits

In the last step, both regulations are tested automatically.

Insurance Regulation

An insurance company offers its services on the basis of the monthly wage:

Class Start End Rate
A 1 2999 30
B 3000 5999 45
C 6000 open 60

Example insurance regulation Insurance.json:

1  {
2    "$schema": "../../Schemas/PayrollEngine.Exchange.schema.json",
3    "createdObjectDate": "2023-01-01T00:00:00.0Z",
4    "tenants": [
5      {
6        "identifier": "StartTenant",
7        "updateMode": "NoUpdate",
8        "regulations": [
9          {
10            "name": "InsuranceRegulation",
11            "baseRegulations": [
12              "StartRegulation"
13            ],
14            "sharedRegulation": true,
15            "lookups": [
16              {
17                "name": "InsuranceRate",
18                "values": [
19                  {
20                    "key": "A",
21                    "rangeValue": 1,
22                    "value": "30"
23                  },
24                  {
25                    "key": "B",
26                    "rangeValue": 3000,
27                    "value": "45"
28                  },
29                  {
30                    "key": "C",
31                    "rangeValue": 6000,
32                    "value": "60"
33                  }
34                ]
35              }
36            ],
37            "wageTypes": [
38              {
39                "wageTypeNumber": 200,
40                "name": "InsuranceRate",
41                "valueExpression": "GetRangeLookup<decimal>(\"InsuranceRate\", WageType[100])",
42                "collectors": [
43                  "Deduction"
44                ]
45              }
46            ]
47          }
48        ],
49        "payrolls": [
50          {
51            "name": "StartPayroll",
52            "updateMode": "NoUpdate",
53            "layers": [
54              {
55                "level": 2,
56                "regulationName": "InsuranceRegulation"
57              }
58           ]
59         }
60       ]
61     }
62   ]
63 }

The insurance regulation in detail:

  • 2: Path to the JSON schema (adapt this to your local environment)
  • 7: Do not update the tenant (see Basic-Payroll Test)
  • 10: The regulation name
  • 11-13: The base regulation dependencies
  • 14: Activate Shared Regulation this regulation
  • 16-35: The insurance rate lookup
  • 21/26/31: The insurance rate salary range value
  • 22/27/32: The insurance rate value
  • 38-45: The insurance wage type
  • 39: The insurance rate wage type number 200, controls the process order of the payrun
  • 41: The benefit wage type value expression: calculated from the lookup value
  • 43: The wage type collector Deduction
  • 54-57: The insurance payroll layer
  • 55: The insurance regulation payroll level 2

With the command 2 Insurance.Setup.cmd the Payroll Console sends the data of the JSON file to the backend.

Company Regulation

The employee may receive a benefit/bonus contribution several times a month.

Example company regulation Company.json:

1 {
2   "$schema": "../../Schemas/PayrollEngine.Exchange.schema.json",
3   "createdObjectDate": "2023-01-01T00:00:00.0Z",
4   "tenants": [
5     {
6       "identifier": "StartTenant",
7       "updateMode": "NoUpdate",
8       "regulations": [
9         {
10           "name": "CompanyRegulation",
11           "baseRegulations": [
12             "InsuranceRegulation"
13           ],
14           "cases": [
15             {
16               "name": "Benefit",
17               "caseType": "Employee",
18               "fields": [
19                 {
20                   "name": "Benefit",
21                   "valueType": "Money",
22                   "timeType": "Moment"
23                 }
24               ]
25             }
26           ],
27           "wageTypes": [
28             {
29               "wageTypeNumber": 100.1,
30               "name": "Benefit",
31               "valueExpression": "CaseValue[\"Benefit\"]",
32               "collectors": [
33                 "Income"
34               ]
35             }
36           ]
37         }
38       ],
39       "payrolls": [
40         {
41           "name": "StartPayroll",
42           "updateMode": "NoUpdate",
43           "layers": [
44             {
45               "level": 3,
46               "regulationName": "CompanyRegulation"
47             }
48           ]
49         }
50       ]
51     }
52   ]
53 }

Regulation in detail:

  • 2: Path to the JSON schema (adapt this to your local environment)
  • 7: Do not update the tenant (see Basic-Payroll Test)
  • 10: The regulation name
  • 11-13: The base regulations
  • 15-25: The benefit case
  • 21: The benefit case field time type moment
  • 28-32: The benefit wage type
  • 29: The benefit wage type number 100.1, controls the process order of the payrun
  • 31: The benefit wage type value expression: calculated from case value
  • 33: The wage type collector Income
  • 44-47: The insurance payroll layer
  • 45: The company regulation payroll level 3

With the command 3 Company.Setup.cmd the Payroll Console sends the data of the JSON file to the backend.

Payroll Test

The following test Company.Test.et.json checks all regulations:

1  {
2    "$schema": "../../Schemas/PayrollEngine.Exchange.schema.json",
3    "tenants": [
4      {
5        "identifier": "StartTenant",
6        "updateMode": "NoUpdate",
7        "payrolls": [
8          {
9            "name": "StartPayroll",
10            "updateMode": "NoUpdate",
11            "cases": [
12              {
13                "userIdentifier": "lucy.smith@foo.com",
14                "employeeIdentifier": "mario.nuñez@foo.com",
15                "divisionName": "StartDivision",
16                "case": {
17                  "caseName": "Salary",
18                  "values": [
19                    {
20                      "caseFieldName": "Salary",
21                      "value": "5000",
22                      "start": "2023-01-01T00:00:00.0Z",
23                      "created": "2022-11-04T00:00:00.0Z"
24                    }
25                  ]
26                }
27              },
28              {
29                "userIdentifier": "lucy.smith@foo.com",
30                "employeeIdentifier": "mario.nuñez@foo.com",
31                "divisionName": "StartDivision",
32                "reason": "Project A",
33                "case": {
34                  "caseName": "Benefit",
35                  "values": [
36                    {
37                      "caseFieldName": "Benefit",
38                      "value": "225",
39                      "start": "2023-01-14T00:00:00.0Z",
40                      "created": "2022-12-12T00:00:00.0Z"
41                    }
42                  ]
43                }
44              },
45              {
46                "userIdentifier": "lucy.smith@foo.com",
47                "employeeIdentifier": "mario.nuñez@foo.com",
48                "divisionName": "StartDivision",
49                "reason": "Project B",
50                "case": {
51                  "caseName": "Benefit",
52                  "values": [
53                    {
54                      "caseFieldName": "Benefit",
55                      "value": "250",
56                      "start": "2023-01-26T00:00:00.0Z",
57                      "created": "2022-01-14T00:00:00.0Z"
58                    }
59                  ]
60                }
61              }
62            ]
63          }
64        ],
65        "payrunJobInvocations": [
66          {
67            "name": "StartPayrunJob.Jan23",
68            "payrunName": "StartPayrun",
69            "userIdentifier": "lucy.smith@foo.com",
70            "employeeIdentifiers": [
71              "mario.nuñez@foo.com"
72            ],
73            "reason": "Test Payrun Jan 23",
74            "jobStatus": "Complete",
75            "periodStart": "2023-01-01T00:00:00.0Z",
76            "evaluationDate": "2023-02-01T00:00:00.0Z"
77          }
78        ],
79        "payrollResults": [
80          {
81            "payrunJobName": "StartPayrunJob.Jan23",
82            "employeeIdentifier": "mario.nuñez@foo.com",
83            "wageTypeResults": [
84              {
85                "wageTypeNumber": 100,
86                "value": 5000
87              },
88              {
89                "wageTypeNumber": 100.1,
90                "value": 475
91              },
92              {
93                "wageTypeNumber": 200,
94                "value": 45
95              }
96            ],
97            "collectorResults": [
98              {
99                "collectorName": "Income",
100                "value": 5475
101              },
102              {
103                "collectorName": "Deduction",
104                "value": -45
105              }
106            ]
107          }
108        ]
109      }
110    ]
111  }

Regulation in detail:

  • 2: Path to the JSON schema (adapt this to your local environment)
  • 6: Do not update the tenant (see Basic-Payroll Test)
  • 10: Do not update the payroll (see Basic-Payroll Test)
  • 12-27: Salary case: 5'000 start 1st Jan. 23
  • 28-44: Benefit project A: 225, 14th Jan. 23
  • 45-61: Benefit project B: 250, 26th Jan. 23
  • 66-77: Start payrun job Jan. 23
  • 80-107: Test results payrun job Jan. 23
  • 86: The expected salary wage type (100) value 5'000
  • 90: The expected insurance wage type (200) value 45 (Class B)
  • 94: The expected benefit wage type (300) value 475 (225 + 250)
  • 100: The expected colletor (Income) value 5'475 (5'000 + 475)
  • 104: The expected colletor (Deduction) value -45 (negated)

The command 3 Company.Test.cmd runs the test on a copy of the employee mario.nuñez@foo.com.

Next steps