SAP Integration Suite, SAP SuccessFactors Employee Central

Determining Primary vs. Secondary Employment in SAP SuccessFactors with SAP Integration Suite

In SAP SuccessFactors, managing employee employment records can involve multiple assignments. As a result, it’s important to differentiate between primary and secondary contracts. In this blog, I’ll walk you through what I consider the easiest methods to determine whether an employee’s employment is primary or secondary, using various SuccessFactors API entities.

Introduction

Why It’s Important:

In many HR systems, employees can have multiple employment contracts. Identifying the primary contract is critical for processes such as payroll, benefits, and performance reviews. In SAP SuccessFactors, determining whether a contract is primary can be done in several ways, depending on the data model and integration requirements.

Overview:

There are various ways to determine the primary employment contract in SAP SuccessFactors. These methods range from querying OData API calls to utilizing specific fields or conditions based on the employee’s data.

Understanding the Data Model in SAP SuccessFactors

EmpEmployment Entity:

This entity holds essential employment data for an employee, such as employment status, job title, and user ID. The EmpEmployment entity can often link to multiple secondary assignments (contracts).

SecondaryAssignments Entity:

This entity contains additional employment records beyond the primary one, allowing an employee to hold more than one contract. We often need to filter for the primary assignment within this entity.

PersonNav and PerPerson:

These fields help navigate the relationships between employees and their assignments, making it easy to access data for secondary assignments.

Example for Identifying the Primary Contract

Example Scenario:

Suppose you have an integration with SAP Integration Suite running every hour, which exports changed employee data and uploads it to an external payroll system. However, the payroll system should only process primary employment records.

Solution:

You can leverage the EmpEmployment and SecondaryAssignments entities to determine whether an employment record is primary. After filtering out secondary assignments, you can export only the primary contracts.

Steps to Identify Primary Employment Contract:

  1. Query EmpEmployment for Employee Data:
    Start by retrieving the employment data for an employee by querying the EmpEmployment entity. This data typically contains general employment information such as the employee’s ID and employment status.
  2. Check for Secondary Contracts:
    Query the SecondaryAssignments entity to retrieve all secondary assignments related to the employee. If the employee has a secondary contract, you need to exclude it from the export process. This can be done in Groovy script.
  3. Export Primary Contracts Only:
    After filtering out secondary assignments, you can create a file for the primary employment records, which are then ready for payroll processing.

Simplified Example to Get Data for an Employee with Multiple Employment Records:

In a real-world scenario, you would filter based on the lastModifiedDateTime field. Here’s an example query to retrieve data for a specific user with multiple employment records:

https://<datacenter>.sapsf.eu/odata/v2?$select=personIdExternal,userId,startDate,personNav/secondaryAssignmentsNav/allSfProcesses/SecondaryAssignments_effectiveStartDate,personNav/secondaryAssignmentsNav/allSfProcesses/SecondaryAssignments_externalCode,personNav/secondaryAssignmentsNav/allSfProcesses/externalCode,personNav/secondaryAssignmentsNav/allSfProcesses/usersSysId&$expand=personNav/secondaryAssignmentsNav/allSfProcesses,personNav/secondaryAssignmentsNav,personNav&$filter=userId eq '112665'

Response Example:

<EmpEmployment>
	<EmpEmployment>
		<personNav>
			<PerPerson>
				<secondaryAssignmentsNav>
					<SecondaryAssignments>
						<allSfProcesses>
							<SecondaryAssignmentsItem>
								<SecondaryAssignments_effectiveStartDate>2025-05-29T00:00:00.000</SecondaryAssignments_effectiveStartDate>
								<SecondaryAssignments_externalCode>103802</SecondaryAssignments_externalCode>
								<usersSysId>112665</usersSysId>
								<externalCode>f51d499a542e485b924352d8040a2fcf</externalCode>
							</SecondaryAssignmentsItem>
						</allSfProcesses>
					</SecondaryAssignments>
				</secondaryAssignmentsNav>
			</PerPerson>
		</personNav>
		<personIdExternal>103802</personIdExternal>
		<userId>112665</userId>
		<startDate>2025-05-29T00:00:00.000</startDate>
	</EmpEmployment>
</EmpEmployment>

Groovy Script to Identify Primary Employment

Here is a Groovy script to help determine whether the employee has a primary employment record based on the presence of secondary assignments.

The goal of the script is to determine whether an employment record is primary or secondary. This is done by comparing the userId from the EmpEmployment entity with the usersSysId from the secondaryAssignmentsNav entity. If the userId is not found in the secondaryAssignments, it means the employment record is a primary contract. If the userId is found in the secondaryAssignments, it is considered a secondary contract.

import com.sap.gateway.ip.core.customdev.util.Message;

def Message processData(Message message) {

  // Get the body of the incoming message as a Reader (XML data)

  def body = message.getBody(java.io.Reader);

  // Parse the XML body of the message using XmlSlurper

  def xml = new XmlSlurper().parse(body);

  // Loop through all the children elements of the XML (typically these would be multiple records)

  xml.children().each {
    xmlItem ->

      // Set paths for EmpEmployment and PerPerson using navigation properties

      def EmpEmployment = xmlItem;

    def PerPerson = EmpEmployment?.personNav?.PerPerson

    // Get the userId from the EmpEmployment record, or set it to an empty string if not present

    def userId = EmpEmployment ? EmpEmployment?.userId?.text() ? : "" : ""

    // Check for multiple secondary contracts by checking if 'usersSysId' exists

    def isPrimaryContract = true // Assume it is a primary contract initially

    def multipleContactUserIds = PerPerson?.secondaryAssignmentsNav?.
    '**'.findAll {
      node -> node.name() == 'usersSysId'
    }*.text();

    // If there are multiple secondary contracts, check if the current userId is part of the secondary assignments

    if (multipleContactUserIds.size() > 0) {

      if (multipleContactUserIds.contains(userId)) {

        isPrimaryContract = false // Set to false if userId is found in the secondary assignments

      }

    }

    // Print whether the contract is primary or not (for debugging or logging purposes)

    println isPrimaryContract

  }

  // Return the processed message

  return message;

}

Conclusion

By using the EmpEmployment and SecondaryAssignments entities, you can effectively determine whether an employee’s contract is primary or secondary. Filtering out secondary assignments allows you to focus on primary contracts, ensuring that only the relevant employment records are processed for payroll or other HR operations.

Rating: 5 / 5 (1 votes)