SAP - Managing futur job_information in IDN Connector

Hello everyone :nerd_face:

Context

We recently deployed SAP SuccessFactor within our IT services and encountered a problem with the provisioning of users who had several job_information within SAP when the HR department anticipated changes to users (transfers or manager changes for example). The direct effect was that IDN carried out the changes in our user’s identity (authoritative source) as soon as these job_information were modified, without taking into account the start_date specified by the HR department, with the consequence that rights were lost/accessed.

Objectives

  • Do not process SAP data if job_information has a start_date in the future, except if all job_information are in the future (allows you to retrieve information for a user soon to join the company without waiting until D1 of his arrival).
  • Recover the last job_information with a start_date in the past.

Resources

I’ve found several resources on the forum or in the documentation, but these are not complete and do not fully meet my needs:

The latter gives examples of how to use Xpath (v2.0) to filter the results obtained by the SAP connector but which didn’t work in my environment :thinking:

Testing xPath

Testing a new Xpath via xpather.com:

New Xpath and explanation :

if (count(//employment_information/job_information[xs:date(start_date) le current-date()]) eq 0) then
(//employment_information/job_information/job_title)[last()]
else (//employment_information/job_information[xs:date(start_date) le current-date()]/job_title)[1]

If there are no job_information with a start_date in the past:

  • Retrieves the job_title of the most recent job_information in the future for upcoming arrivals.

Otherwise:

  • Retrieves the job_title of the most recent job_information with a start_date in the past.

Use Case 1: User with job_information in the past AND in the future

  • Objective: Assuming it’s 24/04/2024, IDN should retrieve the job_information with the most recent start_date in the past, where the user James BOND is titled as “Senior Spy”.

  • Test Data:

<sfobject>
	<id>007</id>
	<type>CompoundEmployee</type>
	<person>
		<personal_information>
			[*REDACTED*]
			<business_first_name>James</business_first_name>
			<business_last_name>BOND</business_last_name>
			<start_date>2023-01-01</start_date>
		</personal_information>
		<employment_information>
			[*REDACTED*]
			<start_date>2023-01-01</start_date>
			<user_id>007</user_id>
			<job_information>
				[*REDACTED*]
				<job_title>Spy Chief Officer</job_title>
				<start_date>2025-01-01</start_date>
			</job_information>
			<job_information>
				[*REDACTED*]
				<job_title>Senior Spy</job_title>
				<start_date>2024-01-01</start_date>
			</job_information>
			<job_information>
				[*REDACTED*]
				<job_title>Junior Spy</job_title>
				<start_date>2023-01-01</start_date>
			</job_information>
		</employment_information>
	</person>
</sfobject>

Use Case 2: User with job_information in the past only

  • Objective: Assuming it’s 24/04/2024, IDN should retrieve the job_information with the most recent start_date in the past, where the user James BOND is “Senior Spy”.

  • Test Data:

<sfobject>
	<id>007</id>
	<type>CompoundEmployee</type>
	<person>
		<personal_information>
			[*REDACTED*]
			<business_first_name>James</business_first_name>
			<business_last_name>BOND</business_last_name>
			<start_date>2023-01-01</start_date>
		</personal_information>
		<employment_information>
			[*REDACTED*]
			<start_date>2023-01-01</start_date>
			<user_id>007</user_id>
			<job_information>
				[*REDACTED*]
				<job_title>Senior Spy</job_title>
				<start_date>2024-01-01</start_date>
			</job_information>
			<job_information>
				[*REDACTED*]
				<job_title>Junior Spy</job_title>
				<start_date>2023-01-01</start_date>
			</job_information>
		</employment_information>
	</person>
</sfobject>

Use Case 3: User with job_information in the future only (upcoming arrival)

  • Objective: Assuming it’s 24/04/2024, IDN should retrieve the job_information with the closest start_date in the future, where the user James BOND is “Junior Spy”.

  • Test Data:

<sfobject>
	<id>007</id>
	<type>CompoundEmployee</type>
	<person>
		<personal_information>
			[*REDACTED*]
			<business_first_name>James</business_first_name>
			<business_last_name>BOND</business_last_name>
			<start_date>2023-01-01</start_date>
		</personal_information>
		<employment_information>
			[*REDACTED*]
			<start_date>2023-01-01</start_date>
			<user_id>007</user_id>
			<job_information>
				[*REDACTED*]
				<job_title>Senior Spy</job_title>
				<start_date>2026-01-01</start_date>
			</job_information>
			<job_information>
				[*REDACTED*]
				<job_title>Junior Spy</job_title>
				<start_date>2025-01-01</start_date>
			</job_information>
		</employment_information>
	</person>
</sfobject>

Modifying the SAP Connector in IDN to Address the Problem

  1. Set Up the SAP Connector:
    Navigate to Admin > Connections > Sources > SAP_SuccessFactors in IDN.

  2. Edit Configuration:
    Click on the “edit configuration” button.

  3. Access Advanced Settings:
    Go to the “Advanced Settings” tab, where you’ll find “Attribute Mapping”.

  4. Modify the XPath:
    Replace your current XPath with the following expression:

    if (count(//employment_information/job_information[xs:date(start_date) le current-date()]) eq 0) then (//employment_information/job_information/job_title)[last()] else (//employment_information/job_information[xs:date(start_date) le current-date()]/job_title)[1]
    

  1. Adjusting the “job_title” Attribute:
    You’ll need to adjust the "job_title" attribute to suit your needs. Below is an example of how the connector might look after the modification:

    Example of post-modification connector setup:
    - Connector Name: SAP_SuccessFactors
    - Attribute: job_title
    - Original XPath : /person/employment_information/job_information/job_title
    - XPath Modified: if (count(//employment_information/job_information[xs:date(start_date) le current-date()]) eq 0) then (//employment_information/job_information/job_title)[last()] else (//employment_information/job_information[xs:date(start_date) le current-date()]/job_title)[1]
    

End

I hope it will be useful to others,

If you have any questions or comments, I’d be delighted to hear from you,

Have a nice day,

Thomas

4 Likes

Hi @tdelorge-mmb
Since you are adding below XPATH, The last part “/job_title)[1]” seems static, You are always choosing the second job_title. How do you know that second job_title is always the correct one ?

  • XPath Modified: if (count(//employment_information/job_information[xs:date(start_date) le current-date()]) eq 0) then (//employment_information/job_information/job_title)[last()] else (//employment_information/job_information[xs:date(start_date) le current-date()]/job_title)[1]

Hi Chhiring,

[1] is a false friend here, the list in XPath seem like to start at index 1 and not index 0 as usual programmation languages :


But this [1] it’s not mandatory in fact because IDN select himself the first item of the result list : 8 results for job_title in the past, but IDN just bring the last one in the user account (most recent, order made by SAP API)

2 Likes

so are you saying SAP successfactor API order them by most recent automatically OR is there something needs to be done to order them by most recent ?

SAP API output are ordered by start_date attribute within <job_information> from newest to older

1 Like

Hello Thomas,

Thank you for your insightful post regarding future-dated assignments in SuccessFactors.

Recently, I transitioned the authoritative source of one of my clients From Web Service to SuccessFactors, and I encountered the same issue you described where current employee information could not be retrieved due to future-dated assignments.
Following the logic you provided, I adjusted the SFAPI endpoint to compare by date, successfully resolving the issue and retrieving the HR data as intended.

However, I have a question to another thing.
Does this behavior of retrieving future-dated data only apply to fields related to job events?
For example, in the case of employeeStatus, which is utilized as a cloudLifeCycle field, it is part of the SF connector basis schema and therefore cannot be directly managed through the SFAPI endpoint.

Looking forward to your insights.

Best regards,
Jaewon

I had the same question and would like to know if this was answered. @jwshin @ThomasMoore

Hi Shreelakshmi,

  1. Create a new custom attribute say customStatus in SAP source
  2. Change the xpath expressions to the active or terminated based on start data etc into it(basically whatever logic you need into it)
  3. In Sap idenity profiles lifecyle tab, use a trasnform like lookup to corelate the status in the customStatus attribute into lifecycle state.

Hope this helps.

Thank you for responding @rahulb635 . So, from your explanation, what I understand, Any attribute that is part of the OOTB connector schema, its SFAPI path cannot be overriden through the advanced settings- explicitly adding the same schema attribute with the Xpath 2.0 that we want. The connector does not pick this new Xpath 2.0. So the only solution is to create a new custom schema attribute and add the required Xpath 2.0.

Regards,

Shree

1 Like

Hi @tdelorge-mmb Thank you for sharing this detailed information. I have a follow up here. How do we handle multiple future events with same start_date (effective Date). How does this XPath handle it in that scenario. Say the HR updated event change in the morning with start_date as Aug 1st 2026 and then a position title change in afternoon with same start_date as Aug 1st 2026. Any insights on this is appreciated.

Good question.

Because the XML engine parses from top to bottom, index [1] naturally grabs Position 1 in the XML layout. So Thomas original xpath should work

Thanks Rahul. But my question is what about the event change that has the same start_date. If only Position record is picked each time, wouldnt the connector ignore the morning event change even on full aggregation? @rahulb635

Hi Shreelaxmi,

during a full aggregation, SailPoint reads the entire history timeline array at once.

It doesn’t process the morning event and skip the afternoon one; instead, the XPath evaluates the entire stack and deliberately selects index [1], which holds the afternoon event (the highest sequence number).

This is the desired behavior because the afternoon event represents the final, accurate state of the identity for that day. The morning event is effectively an intermediate state that has already been superseded