CX Works

CX Works brings the most relevant leading practices to you.
It is a single portal of curated, field-tested and SAP-verified expertise for SAP Customer Experience solutions

Contact-to-Account Relationships in SAP Marketing Cloud (Part 3/5)

15 min read

Contact-to-Account Relationships in SAP Marketing Cloud | Part 3: Building the custom integration content for Business Partner Replication

Are you using SAP Marketing Cloud in a B2B scenario and your customer contacts are assigned to multiple accounts in the sales system? 

Then the following article series could help to understand the business scenarios and processes behind a B2B-oriented setup in SAP Marketing Cloud – how to build multiple relationships between contacts and accounts and how to implement following best practices in a standardized data model of a business partner over the whole system landscape.

In part 2 of this article series you have learned about the necessity of the Business Partner Entity and how to set up your SAP Marketing Cloud Tenant in order to support the B2B Contact-to-Account Relationships.  

As mentioned in the previous article, there is no standard integration content for the Business Partner Integration between SAP CRM and SAP Marketing Cloud. This is the reason why we have to build our own integration content when integrating Account-to-Contact Relationships with SAP CRM. In order to facilitate this, we can leverage existing standard integration packages between SAP CRM - SAP Cloud for CustomerSAP Cloud for Customer - SAP Marketing Cloud and SAP CRM - SAP Marketing Cloud and to built our custom integration and logic.

In this part, we will describe the approach taken for each one of the integration scenarios we have enhanced and implemented.

After reading through this article, the article series will be continued with the following parts:

Table of Contents

Business Partner Replication IFlow

In this chapter, we are looking at the Business Partner Integration. We are showing the process of transforming the IDoc Message from SAP CRM, to the SOAP Message that the Business Partner Web Service in the SAP Marketing Cloud expects. We will look into how to reuse the SAP CRM - Marketing Cloud Integration Flow for Business Partner Replication and combine this one with the mappings and logic from SAP Cloud for Customer to SAP CRM Business Partner Integration.

Step 1 - Start from SAP CRM - SMC Standard Integration IFlow

Standard Integration PackageSAP Marketing Cloud Integration with SAP Customer Relationship Management

Integration Flow: Replicate Business Partner from SAP CRM to SAP Marketing Cloud

We aim to replicate business partners from SAP CRM to SAP Marketing Cloud using the SOAP web services. Instead of starting from scratch, it's useful to start from the standard integration Flow that uses the OData service to create Interaction Contacts and utilize the parts that can be reused. Of course, not everything can be reused and requires additional changes.

Content to Reuse and Change

From the Integration Flow above, the integration content in the blue box can be reused. In this part we already have the IDOC receiver set up, we have a script that logs payloads and we have an XSLT mapping "Pre-Processing" that is responsible for filtering out specific Industry data as well as non-default and not valid address data. The last part however needs to be further adjusted as previously the SAP Marketing Cloud was only considering valid addresses. With the Business Partner Entity the behavior is slightly different, as the Business Partner also holds invalid addresses, e.g. addresses with expired validity dates or addresses which are not marked as "Standard Address". In order to successfully replicate all contacts and relations, those addresses have to be replicated to the Marketing Cloud as well. The transformation logic between Business Partner and Interaction Contact (refer to Part 2 of this article series), takes care of only replicating the valid address to the Interaction Contact.

Changes to be done

Below, the part of the Pre-Processing XSLT  that needs to be disabled.

PreProcessing
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:hci="http://sap.com/it/"> 
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:param name="exchange"/>
<xsl:param name= "IndustrySystem"/>
 
<xsl:template match="node() | @*">
    <xsl:copy>
        <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
</xsl:template>
 
<xsl:template match= "E101_EI_BUPA_INDUSTRYSECTOR[not(E101EI_STRUC_INDUSTRYSECTOR/IND_DEFAULT = 'X')]"/>
<xsl:template match= "E101_EI_BUPA_INDUSTRYSECTOR[E101EI_STRUC_INDUSTRYSECTOR/IND_DEFAULT = 'X']">
    <xsl:if test ="$IndustrySystem = E101S_EI_STRUC_INDUSTRY_KEY/KEYSYSTEM">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:if>
</xsl:template>
 
<!-- Part below is disabled to not filter any addresses -->
 
<!--
<xsl:template match= "E101BUS_EI_BUPA_ADDRESS[not(E101US_EI_BUPA_ADDRESS_DATA/E101_EI_BUPA_POSTAL_ADDRESS/E101BUS_EI_STRUC_ADDRESS/STANDARDADDRESS = 'X' and CURRENTLY_VALID = 'X' )]"/>
<xsl:template match= "E102BUS_EI_BUPA_TELEPHONE[not(E102S_EI_BUPA_TELEPHONE_CON/E102BUS_EI_STRUC_TEL_DATA/R_3_USER = '1' or E102S_EI_BUPA_TELEPHONE_CON/E102BUS_EI_STRUC_TEL_DATA/R_3_USER = '3')]"/>
<xsl:template match= "E102BUS_EI_BUPA_SMTP[not(E102BUS_EI_BUPA_SMTP_CON/E102BUS_EI_STRUC_SMTP_DATA/STD_NO = 'X')]"/>
<xsl:template match= "E102BUS_EI_BUPA_FAX[not(E102BUS_EI_BUPA_FAX_CON/E102BUS_EI_STRUC_FAX_DATA/STD_NO = 'X')]"/>
<xsl:template match= "E102BUS_EI_BUPA_URI[not(E102BUS_EI_BUPA_URI_CON/E102BUS_EI_STRUC_URI_DATA/STD_NO = 'X')]"/>
-->
 
</xsl:stylesheet>

Content to replace

The content in the red box in the IFlow Screenshot is the one we need to replace with a Mapping from IDOC to the SOAP Web Service structure. Also, the Request-Reply step is not supported for SOAP adapters and therefore we need to replace it with an End Message Event. 

As mentioned in the introduction of this chapter, this new mapping does not have to be built from scratch either and we can reuse an already existing mapping from the standard business partner replication from SAP CRM - SAP Cloud for Customer standard integration flow as a starting point.

Step 2 - Leverage SAP CRM - SAP Cloud for Customer Business Partner Replication Standard Integration content

Standard Integration PackageSAP Cloud for Customer Integration with SAP CRM

Integration Flow: Replicate Business Partner and Business Partner Confirmation from SAP Business Suite

Content to Reuse and Change

From the above integration flow we can reuse the highlighted mapping, splitter and gather steps.

We can reuse the mapping because both SAP Marketing Cloud and SAP Cloud for Customer business partner integration flows use the same IDOC message type "CRMXIF_PARTNER_SAVE_M03" and the same SOAP web service "BusinessPartnerSUITEBulkReplicateRequest". Therefore we can take it as a starting point for the mapping that we are going to replace in the Integration Flow we customized in step one. The IDOC splitter and gather steps can be reused to process each IDOC from bulk message individually and prevent context issues on the mapping before we gather the mapped messages to send as bulk to SAP Marketing Cloud.

After reusing the above content the Integration flow from step one should look close to the next example.

Changes to be done

  • Gather changes - On the gather step we will use a different aggregation strategy from the one used in the SAP CRM - SAP Cloud for Customer standard integration flow. We will use the Combine at XPath algorithm and below you can find the used XPaths:

  • Namespace mapping - Our XPath contains the "ns0" namespace and therefore we will add this namespace to the IFlow Runtime Configuration under Namespace Mapping field:

Step 3 - Add support for Bulk messages after Gather Step

With our new aggregation strategy at XPath we will lose the bulk message header, therefore we will add two further steps. One content modifier to store the header properties before the gather step and a XSLT mapping to restore it afterward.

After adding these two steps the IFlow should look like this: 

Additional Steps

Content Modifier - Store header properties

  • RecipientParty - XPath - java.lang.String - /ns0:BusinessPartnerSUITEBulkReplicateRequest/MessageHeader/RecipientParty/InternalID

  • SenderParty - XPath - java.lang.String - /ns0:BusinessPartnerSUITEBulkReplicateRequest/MessageHeader/SenderParty/InternalID

  • CreationDateTime - XPath - java.lang.String - /ns0:BusinessPartnerSUITEBulkReplicateRequest/MessageHeader/CreationDateTime

  • UUID - XPath - java.lang.String - /ns0:BusinessPartnerSUITEBulkReplicateRequest/MessageHeader/UUID

  • ID - XPath - java.lang.String - /ns0:BusinessPartnerSUITEBulkReplicateRequest/MessageHeader/ID

XSLT Mapping - Restore header properties

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://sap.com/xi/SAPGlobal20/Global">
	<xsl:param name="ID"/>
	<xsl:param name="UUID"/>
	<xsl:param name="CreationDateTime"/>
	<xsl:param name="SenderParty"/>
	<xsl:param name="RecipientParty"/>
	
	<xsl:template match="/">
		<ns0:BusinessPartnerSUITEBulkReplicateRequest xmlns:ns0="http://sap.com/xi/SAPGlobal20/Global">
		
			<MessageHeader>
				<ID>
					<xsl:value-of select="$ID"/>
				</ID>
				
				<UUID>
					<xsl:value-of select="$UUID"/>
				</UUID>
				
				<CreationDateTime>
					<xsl:value-of select="$CreationDateTime"/>
				</CreationDateTime>
				
				<SenderBusinessSystemID>
				    <xsl:value-of select="$SenderParty"/>
				</SenderBusinessSystemID>
				
		        <RecipientBusinessSystemID>
		            <xsl:value-of select="$RecipientParty"/>
		        </RecipientBusinessSystemID>
				
				<SenderParty>
					<InternalID schemeID="BusinessSystemID" schemeAgencyID="310">
					    <xsl:value-of select="$SenderParty"/>
					</InternalID>
				</SenderParty>
				
				<RecipientParty>
					<InternalID schemeID="BusinessSystemID" schemeAgencyID="310">
						<xsl:value-of select="$RecipientParty"/>
					</InternalID>
				</RecipientParty>
	
				
			</MessageHeader>
			
			
            <xsl:copy-of select="ns0:BusinessPartnerSUITEBulkReplicateRequest/BusinessPartnerSUITEReplicateRequestMessage"/>
			
			
		</ns0:BusinessPartnerSUITEBulkReplicateRequest>
	</xsl:template>
	
	<xsl:template match="@* | node()">
		<xsl:copy>
			<xsl:apply-templates select="@* | node()"/>
		</xsl:copy>
	</xsl:template>
	
</xsl:stylesheet>

At this point, the design of the integration content is mostly done in terms of integration steps. Now the focus shifts to the mapping that we reused from the SAP CRM - SAP Cloud for Customer standard integration flow. This has to be adapted in order to transfer the correct information to the SAP Marketing Cloud. The SAP Cloud for Customer mapping contains data mapped that is relevant from a sales and service perspective but might not be relevant for marketing purposes.

Step 4 - Replace SAP Cloud for Customer SOAP service WSDL with SAP Marketing Cloud Soap Service WSDL

Changes to be done

Get SAP Marketing Cloud WSDL

In order to start adapting that mapping the first change to be done is to replace the message WSDL for the SAP Marketing Cloud SOAP based web service we are going to use. Although it's the "same" as the one used in SAP Cloud for Customer (BusinessPartnerSUITEBulkReplicateRequest) the messages might not be exactly the same.

To do so we should download it from SAP Marketing Cloud Communication Arrangement SAP_COM_0475 - SAP Business Partner Integration by clicking on the WSDL download button for the Business Partner - Replicate from Client to SAP S/4HANA Cloud service.

Replace WSDL in Message Mapping

After downloading the WSDL you will have to upload it to the message mapping of our Iflow:

Go to the message mapping edit and replace the target message:

Now that we have the correct target message WSDL we will see that some previous mappings are no longer supported, these have to be removed in the first step. 

Step 5 - Update mappings leveraging SAP Cloud for Customer -SAP Marketing Cloud Business Partner Replication standard integration content

The next section shows the detailed changes that were required for the implementation of the scenario. Please consider that additional mappings might be needed for your specific scenario.

Mappings to Update by Sections

Message header

Section: /ns0:BusinessPartnerSUITEBulkReplicateRequest/MessageHeader & /ns0:BusinessPartnerSUITEBulkReplicateRequest/BusinessPartnerSUITEReplicateRequestMessage/MessageHeader

  • ID

  • UUID


Business Partner 

Section: /ns0:BusinessPartnerSUITEBulkReplicateRequest/BusinessPartnerSUITEReplicateRequestMessage/BusinessPartner/

  • @actionCode

    • Disable the Field

  • @reconciliationPeriodCounterValue

    • 1

  • @addressInformationListCompleteTransmissionIndicator

    • true

  • @bankDetailsListCompleteTransmissionIndicator

    • false

  • @commonListCompleteTransmissionIndicator

    • Remove mapping

  • @industrySectorListCompleteTransmissionIndicator

    • false

  • @taxNumberListCompleteTransmissionIndicator

    • Remove mapping

  • UUID

Customer
  • Remove all mappings except for this flags, that should be kept false.

Section: /ns0:BusinessPartnerSUITEBulkReplicateRequest/BusinessPartnerSUITEReplicateRequestMessage/BusinessPartner/Customer/

  • @accountingInformationListCompleteTransmissionIndicator

  • @salesArrangementListCompleteTransmissionIndicator

  • @unloadingPointsListCompleteTransmissionIndicator

  • @taxClassificationListCompleteTransmissionIndicator

  • @taxGroupingListCompleteTransmissionIndicator

Address Information

Section: /ns0:BusinessPartnerSUITEBulkReplicateRequest/BusinessPartnerSUITEReplicateRequestMessage/BusinessPartner/AddressInformation/Address/

  • @emailListCompleteTransmissionIndicator

    • true

  • @facsimileListCompleteTransmissionIndicator

    • true

  • @organisationNameListCompleteTransmissionIndicator

    • false

  • @personNameListCompleteTransmissionIndicator

    • false

  • @postalAddressListCompleteTransmissionIndicator

    • false

  • @telephoneListCompleteTransmissionIndicator

    • false

  • @webListCompleteTransmissionIndicator

    • false

  • @actionCode

    • Remove Mapping

  • OrganisationName[1]

    • Disable Mapping

  • PostalAddress/AddressRepresentationCode

    • Remove Mapping

  • PostalAddress/RegionCode

    • Here the mapping that existed in the original data mapping to the OData service has to be recreated (the original can be used as an example) since value mapping needs to be used for correct region mapping.

  • PostalAddress/AdditionalCityName

    • Remove Mapping

  • PostalAddress[1]

    • Remove Mapping

Common

Section: /ns0:BusinessPartnerSUITEBulkReplicateRequest/BusinessPartnerSUITEReplicateRequestMessage/BusinessPartner/Common/

  • Person/Name/FormOfAddressCode

    • Here the mapping that existed in the original data mapping to the OData service has to be recreated (the original can be used as an example) since value mapping needs to be used to map the Form of Address Code correctly.

  • Person/Name/AcademicTitleCode

    • Mapped to a constant 0002 in our scenario but if comes with data can be left mapped.

Identification

Section: /ns0:BusinessPartnerSUITEBulkReplicateRequest/BusinessPartnerSUITEReplicateRequestMessage/BusinessPartner/Identification/

  • PartyIdentifierTypeCode

    • Mapping has to be updated with a value mapping to be able to support the BP Identification category coming from SAP CRM to avoid conflicts with the SAP CRM - SAP C4C integration that was already existing in Customer Landscape (this might differ in other implementations).

  • BusinessPartnerID

    • Business Partner ID in order to be correctly mapped we had to compare the Identification Category with Z006 instead of CRM002 (this might differ in other implementations)

IndustrySector

Section: /ns0:BusinessPartnerSUITEBulkReplicateRequest/BusinessPartnerSUITEReplicateRequestMessage/BusinessPartner/IndustrySector/

  • @actionCode

    • Remove mapping

Text Collection

Section: /ns0:BusinessPartnerSUITEBulkReplicateRequest/BusinessPartnerSUITEReplicateRequestMessage/BusinessPartner/TextCollection

  • Remove All mappings, not relevant for our scenario neither available in target structure.

Tax Collection

  • /ns0:BusinessPartnerSUITEBulkReplicateRequest/BusinessPartnerSUITEReplicateRequestMessage/BusinessPartner/TaxNumber

    • Remove All mappings, not relevant for our scenario but might be relevant for others.

After completing the above changes in the mapping and after all setup is done in SAP Marketing Cloud and SAP CRM (see Part 5 of this article series) you should be ready to receive Business Partners in SAP Marketing Cloud from this IFlow point of view. Nevertheless, this will still fail since in order to close the process loop a confirmation IFlow is required by SAP Marketing Cloud to be able to send the new IDs created in SAP Marketing Cloud back to SAP CRM.

Conclusion

This part of the article series focussed on the details of the Business Partner IFlow. We saw how the existing integration content can be reused in order to build the integration between SAP CRM and the SAP Marketing Cloud for the Business Partner Entity. The next part of this article series will describe the Business Partner Confirmation in more detail.

This article series consists of the following articles:


Overlay