EC Time – Tipps and hints Nr. 5: how to accrual vacation time accounts based on EC time sheet data
this blog describes how to set up a mechanism in EC Time Management that allows to do time account accruals based on recorded hours / days in the time sheet.
Before I start, I first need to write a bit on theory and describe the different ways that exist in Time Management in general to create postings to a time account.
I don´t know in detail how other time management software is handling this, but I know in detail how it is done in SAP ERP Time management, Business byDesign Time Management and of course in our new EC Time Management. I assume other time management solution do this the same way cause these are usually generic business processes independent from a specific software solution.
And the 3 ways of building leave entitlements are:
1. Via an time account accruals engine in a leave management component
This is usually done for leave entitlements based on solid regulations and an employees master data. Usually they are done for recurring time accounts (yearly for example) and are used for generating vacation / leave entitlements based on your contractual working days per week or full time / part time status. In Germany these are for example at least 20 days vacation for a full time employee working a 5-days week. But it can be of course more depending on trade union contracts, company agreements and personell factors like age, service age and other parameters.
This kind of time account accrual can be done by a leave management solution stand alone.
2. Time account postings based on recorded working time or overtime
There are time management processes where an leave entitlement solemly build on employees master data is not sufficient. Employees record their working time and when they have “flextime” or “Gleitzeit” the recorded hours are compared with the duration of the planned working time. Is it less a minus posting is booked to the time account, if it is more then the employee has worked longer than planned and a plus posting is done – and usually no overtime payment is paid for this. Cause the employee can work less the following days / weeks and compensate “flexibly” the too many hours worked (don´t want to call it “overtime” cause normally overtime is associated with a higher payment). There can be of course boundaries – like only the hours performed within a “flextime bandwidth” count, or the time account can only go up to 35hours per month and each plus hour more is then really overtime and paid with an premium and many variations more.
But the important part is: an accruals calculation engine is not needed here. Usually this can be calculated by time valuation alone. The recorded hours are calculated (breaks deducted, times outside a flextime bandwidth capped….) and a direct posting to a time account is performed from the time valuation engine. A pure leave management application can´t do this.
Same is true for the time off in lieu hours. You need to calculate first overtime based on the recorded hours. Overtime by day, week, month or a combination of it, calculate a premium payment (which can be different if the overtime is performed on a Sunday, public holiday (even difference amongst public holidays exist), during night hours and then either the full overtime (base hours plus premium pay) is posted to a time off in lieu account, or only a portion of it (premium part banked, base hours paid out)
This can´t be done by a time accounts accrual engine or with a standalone absence management tool. Time Valuation is needed for this and of course the recording and valuation of the hours worked.
If you want to post overtime into different time accounts, like overtime on Sunday in Time account 1, Overtime on public holiday in time account 2 and normal overtime in Time account 3, then please don´t use the approach described here, but better use this approach:
3. Accruals done by an accrual engine based on hours recorded
And finally, there is the mixed version. You need a time valuation to calculate a value based on the hours recorded, days worked or something else based on the attendance time an employee records AND this value needs to be used by an accruals engine to apply accrual calculation rules and employees master data to generate a leave entitlement.
And up to now the latter was not possible in EC Time. But with our earlier introduced time collectors and some enhancements to them it is now possible.
In some countries it is a common business process to use recorded attendance time in order to use them for daily, weekly or monthly time account vacation accruals. Means the time account accrual engine shall be fed by time sheet data.
In France for example an employee gets only a monthly vacation accrual (but the real entitlement is granted only the following year) when he has worked at least 20 days in the month.
In Australia for each worked day (including some absences but excluding other absence types) employees get an accrual of 0.416438356 hours annual leave.
In some US state you get 1 hour of sick leave for each 30 hours worked.
And there are many more business use cases where a regular leave entitlement is calculated based on the hours / days worked.
So, in short words: it is necessary for the time account accruals engine to consume hours worked recorded in the time sheet.
This is possible with some configuration.
The time account accrual engine reads an object called “accrual base calculation”. This can be used when customers use 3rd party attendance systems but want to do the time account accrual in EC Time. The hours worked can be uploaded via this object for the time account accrual calculation.
But what when the attendance time is recorded in EC Time Sheet? Can those hours be used for time account accrual engine as well?
Yes, we can. It is a bit tricky cause you need to use integration center, but it is possible. We use the integration center for it and the already existing “accrual base calculation” object. However, the “accrual base calculation” object needs the data in a specific format. The data needs to be in the structure of the object which is:
- External code
- actual quantity
- quantity 1 – 5
Check the documentation of this object here:
Hence we need to massage a little bit the time sheet output that it fulfills the format requirement of this object.
Lets take the Australian leave accrual use case as an example.
Employees accrual per each day worked a small portion for their yearly leave entitlement.
So lets take the example in Australia where for a day worked 30 minutes or 0.416438356 hours vacation are granted. In real life, it is a bit more complex cause some specific absence days count as “day worked” as well, and for part time employees it works differently, but this is only a question on how detailed the configuration is. Lets use an easy example, cause I want to show only the principle on how this is set up.
For collecting the attendance days we need a time collector in the time sheet. First step is hence configuring a time collector:
Step 1: Configure a time collector
When you want to use time sheet hours and especially when you want to count number of days on which an employee has performed work, you need to configure a time collector. Please check my other blogs on how to set up a collector in detail.
The collector is of the type “counted events” and we count therein per month the days on which an employee has attendance times (if you want to add specific absence days to it, just use different input time type groups for the collector).
So we got a time type group filled daily for a month by time valuation based on times recorded in the EC Time Sheet.
Time collector looks like this:
Note, that we marked the time collector as UI Component = Yes, so an employee can easily check real time on the Time Sheet UI the actual value of the month.
The time valuation rule that counts all worked day per month to fill the collector looks like this:
The ‘above’ group is the time type group we just created. The input group(s) depend on your already available time type groups. Since the resulting time type group is a collector for counted events, it does not matter how many hours or minutes are recorded, it only matters the fact that one (or multiple) time recordings exist on a day. With the threshold of 0 the valuation will count every day where there is at least one minute of working time for example.
Assign this evaluation rule to a time recording profile and this in turn needs to be assigned to an employee.
After you have done so, you can check in the employees time sheet (or via the time sheet trace feature), whether the time collector works as expected. If you open the time sheet for the user, you should find a link to display the time collectors at the lower left of the screen. Using this link should display the newly defined time collector.
Step 2: Configuring the Integration Center
Now the tricky part is how to extract the value of the time type group out of the time valuation to feed the accrual engine. This can be done with the Integration Center. Here is a step to step description:
Access the integration center.
Click on “My Integrations” and create a new integration scenario by clicking the +create button and select “more integration types”.
Choose on the next pop up
- as trigger type “scheduled”
- as destination type “SuccessFactors”
- as source type “SuccessFactors”
- and as Format “Odata v2”.This means it is going to be an internal MDF to MDF integration which makes some things easier.
On the next screen choose Time Collectors as the base object for the integration. Cause you want to use the time collector we have created above, the one that counts the overtime days per month.
Now you come into a guided activity. Step one here is that you need to give an integration name for your scenario.
Afterwards you need to define and configure the fields that you want to have in your integration scenario.
Select as target object the “accrual calculation base” object. This is the object of the time account accrual engine to upload external accrual base values.
Now we come to the formatting topic. The accrual calculation base object needs as external code the form userid_YYYY-MM-DD. In order to get the field mapping in the appropriate format, we need to make this field as an “calculated field”. You do so by marking the external code field and clicking on the little calculator symbol.
On the following pop-up make exactly this entries:
- Field Value = User (userId) from Time Collector (select the drop down menu and select ‘Associate Field’, then select the User field from the Entity Tree View)
- Concatenate/Append _ (select the operation and enter an underscore in the next field)
- Concatenate/Append Valid to (endDate) from Time Collector
- Remove All T00:00:00Z (select that operation and enter the string ‘T00:00:00Z’ in the next field)
You can test the format output in the calculation trace. Should look like this:
Check if the result has the desired format. In my example it is: chekhov_2017-09-30.
So it is exactly the userid_YYYY-MM-DD format that the accrual base object needs. Luckily ;-).
But we are not yet finished with the field formatting. We need to tackle the other fields as well. But these are simple field associations for:
- Actual Quantity ← Collector Value
- Date ← Valid To
- User ← User
As a last step, make sure that the Operation for the Accrual Calculation Base is set to Upsert MuLTIPLE.
Please note: please choose UPSERT MULTIPLE instead of UPSERT SINGLE as shown in the screenshot. This makes the process more faster and performant.
Step 4: Filtering the Time Collectors
For the planned integration scenario, we have to filter the time collectors according to their external code – we only want to use our new time collector ‘COL – Working Days per Month’. A second filter needs to be defined to only read those time collectors, which contain the final value for that collector. Since Time Collectors are saved per time sheet, they have a field named Last Posting Date, which contains the end date of the time sheet for which the time collector’s value was calculated for or the End Date of the time collector, if its period ends in the middle of a time sheet. For the creation of accruals from time collectors, we are only interested in the end value of the time collector. This is the case for those collectors where the Last Posting Date is the same as the period End Date of the collector. Therefore, we add a ‘Calculated Filter’ to filter out all time collectors, where those two fields are not the same.
The Calculated Filter for the Last Posting Date looks like follows:
With these settings, you can run the integration scenario to test whether it creates the desired results. In the case of our example, this means it will create objects of type Accrual Calculation Base for each instance of a time collector with name where the Last Posting Date is equal to the Valid to date.
Step 5: Time Account Setup
The setup of the time account which will receive the accruals based on time collectors is the same as for any time account for ‘Accruals on Actuals’. That is, the time account type must have the field Accruals Based On set to ‘Recorded Times’.
If employees have time types in their time profile, which deduct from time accounts of that time account type, the Accrual Calculation Base objects, which are created with the new integration scenario will be automatically considered on the next accrual generation run.
What you will setup for the accrual run, is the actual factor to post to the time account for each time collector. This means, the factor of 0.416438356 hours for each working day will be used in an Accrual Rule for this time account type. A possible Accrual Rule could look like this:
Step 6: Making it Happen
For testing the integration scenario, you probably used the option ‘Run Now’ in the Review and Run section. To let the system perform the integration scenario automatically, you will want to set a schedule for it.
Basically, you can schedule the scenario to run at arbitrary intervals, depending on the specific use case you need to configure. However, you need to make sure that only those Time Collectors are processed, which were created or changed since the last time the integration scenario was processed. You can do that by setting an additional filter for the objects, you want to select:
Use a Time-Based Filter, which selects only objects, which were modified since the last run time of the scenario. This reduces too many data volume and you get even those collectors that have changed based on amended time sheets or retro-active changes in the time sheet.
The accrual calculation base object gets filled. When you got retro active changes the old values in this object get overwritten and the accrual calculation run automatically runs from this period onwards again.
That´s it. Enjoy.
Many thanks to Hagen Eck for delivering the input.
7. To be considered in the time account accrual
Just added this one, cause there are some things you need to pay attention for in the time account setup and accrual.
When you use this kind of accrual variant – instead of the normal accrual where you get for each month or for each year vacation independent from your actual hours worked – you need to configure your time account in a specific way. Choose in the time account type (manage data) daily accrual as accrual frequency and accruals based on recorded times, not “standard accrual”:
We provide a dedicated time account accrual run for this scenario. The accrual change scenario is “Accruals on reported times” and not “accrual” like for a “normal” accrual run. Keep this in mind when monitoring the jobs via “Manage time off calendars”.
This change scenario runs then daily based on the “Trigger TLM task job” that needs to be switch on in provisioning. The TLM trigger task job is the main job for Time Management, doing lots of things not only the accrual. So, please ensure that this job is switched on (but it should be already, otherwise lots of things won´t work in your system).