Commerce Cloud Exporting Integration Object using Delta Detection
Tags: commerce, sap, integration
Published: 2023-04-28 19:51:51


Recently I have been involved in integrating SAP Commerce Cloud to SAP Kyma application.

# Idea
[SAP Commerce Cloud](https://www.sap.com/products/crm/commerce-cloud.html) should expose information on any product price updates.

As a solution we have chosen SAP Commerce Integration Objects to be used for that, as it export data without any code change. Defining object was a breeze and went swiftly. It is automatically bound to existing objects and allows you to extend data via relations.

> Commerce Integration objects are exported in OData format which is nicely consumed by existing [OData libraries](https://www.odata.org/libraries/) e.g. [Apache Olingo](https://olingo.apache.org/).

# Integration Object

Intention was to notify Kyma app on any product price change, that is why we have build integration based on `PriceRow` as a root object.


```csv
INSERT_UPDATE IntegrationObject ; code[unique = true] ; integrationType(code)
                                ; SupplementalProductData            ; INBOUND              
                                
INSERT_UPDATE IntegrationObjectItem ; integrationObject(code)[unique = true] ; code[unique = true] ; type(code)     ; root[default = false] ; itemTypeMatch(code)     
                                    ; SupplementalProductData                               ; Currency            ; Currency       ;                       ; ALL_SUB_AND_SUPER_TYPES ;  
                                    ; SupplementalProductData                               ; PriceRow            ; PriceRow       ; true                  ; ALL_SUB_AND_SUPER_TYPES ;  
                                    ; SupplementalProductData                               ; Catalog             ; Catalog        ;                       ; ALL_SUB_AND_SUPER_TYPES ;  
                                    ; SupplementalProductData                               ; CatalogVersion      ; CatalogVersion ;                       ; ALL_SUB_AND_SUPER_TYPES ;  
                                    
INSERT_UPDATE IntegrationObjectItemAttribute ; integrationObjectItem(integrationObject(code), code)[unique = true] ; attributeName[unique = true] ; attributeDescriptor(enclosingType(code), qualifier) ; returnIntegrationObjectItem(integrationObject(code), code) ; unique[default = false] ; autoCreate[default = false]
                                             ; SupplementalProductData:Currency                                    ; isocode                      ; Currency:isocode                                    ;                                                            ; true
                                             ; SupplementalProductData:PriceRow                                    ; currency                     ; PriceRow:currency                                   ; SupplementalProductData:Currency
                                             ; SupplementalProductData:PriceRow                                    ; net                          ; PriceRow:net                                        ;                                                            ; true
                                             ; SupplementalProductData:PriceRow                                    ; productId                    ; PriceRow:productId                                  ;                                                            ; true
                                             ; SupplementalProductData:PriceRow                                    ; catalogVersion               ; PriceRow:catalogVersion                             ; SupplementalProductData:CatalogVersion                                    ; true
                                             ; SupplementalProductData:PriceRow                                    ; price                        ; PriceRow:price                                      ;                                                            ; true
                                             ; SupplementalProductData:Catalog                                     ; id                           ; Catalog:id                                          ;                                                            ; true
                                             ; SupplementalProductData:CatalogVersion                              ; catalog                      ; CatalogVersion:catalog                              ; SupplementalProductData:Catalog                                           ; true
                                             ; SupplementalProductData:CatalogVersion                              ; version                      ; CatalogVersion:version                              ;                                                            ; true


# Inbound channel to allow for testing values with a REST client like Postman
INSERT_UPDATE InboundChannelConfiguration ; integrationObject(code)[unique = true] ; authenticationType(code)
                                          ; SupplementalProductData                               ; BASIC                   

```

Above you can find definition of my object.
I do not create that in text editor like crazy savage, but from Backoffice using *Integration UI Tool*

> *Integration UI Tool* is provided by extensions: `integrationmonitoringbackoffice` and `outboundsyncbackoffice`.


![Backoffice Integration Object Definition](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j3bzm6wa7t55b7l8omlb.png)




## Sending Object to the world

Now to push all the changes to the world, it is required to define endpoint, authentication (if needed) and define cronjob. For that particular cronjob below I have not defined trigger, but that is another step not related to Integration Services per se.

```csv

##for btp we need oauth credential. That comes with Kyma and has to be generated before
INSERT_UPDATE OAuthClientDetails; clientId[unique = true]; oAuthUrl                                                 ; scope             ; authorizedGrantTypes ; clientSecret
                                ; {clientID}             ; https://oauth2.{instance}.kyma.ondemand.com/oauth2/token  ; write,read        ; client_credentials   ; {clientSecret}

INSERT_UPDATE ConsumedOAuthCredential; id[unique = true]                              ; clientId   ; clientSecret; oAuthUrl;
                                     ; SupplementalProductDataConsumedOAuthCredential ; {clientID} ; {clientSecret}       ; https://oauth2.{instance}.kyma.ondemand.com/oauth2/token

# Note: name and specUrl or specData attribute values are required in order to create the Endpoint, but does not affect outboundSync functionality.
INSERT_UPDATE Endpoint; id[unique = true]                       ; version[unique = true]; name                          ; specUrl
                      ; SupplementalProductDataOutboundEndpoint ; endpoint_version_1.0  ; SupplementalPricesOutboundEndpoint ; https://{BTPTenantURL}/{service}/odata2/supplemental/{accountName}/{locale}/{countryIsocode}

INSERT_UPDATE DestinationTarget; id[unique = true]
                               ; SupplementalProductDataOutboundTarget

INSERT_UPDATE ConsumedDestination; id[unique = true]                                  ; url                                                       ; endpoint(id, version)                              ; destinationTarget(id)       ; credential(id)
                                 ; SupplementalProductDataOutboundConsumedDestination ; https://{BTPTenantURL}/{service}/odata2/supplemental/{accountName}/{locale}/{countryIsocode} ; SupplementalProductDataOutboundEndpoint:endpoint_version_1.0 ; SupplementalProductDataOutboundTarget ; SupplementalProductDataConsumedOAuthCredential

# Then to create the OutboundChannelConfiguration, OutboundSyncStreamConfigurationContainer, OutboundSyncStreamConfiguration(s), OutboundSyncJob & OutboundSyncCronJob either import:
INSERT_UPDATE OutboundChannelConfiguration; code[unique = true]                          ; integrationObject(code); destination(id)                               ; autoGenerate; batch
                                          ; SupplementalProductDataOutboundChannelConfig ; SupplementalProductData               ; SupplementalProductDataOutboundConsumedDestination ; true        ; true

# Update the job session attributes
INSERT_UPDATE OutboundSyncJob; code[unique = true]                             ; sessionLanguage(isocode); sessionCurrency(isocode); sessionUser(uid)
                             ; SupplementalProductDataOutboundChannelConfigJob ; en                      ; USD                     ; admin

INSERT_UPDATE OutboundSyncCronJob; code[unique = true]                                 ; sessionLanguage(isocode); sessionCurrency(isocode); sessionUser(uid)
                                 ; SupplementalProductDataOutboundChannelConfigCronJob ; en                      ; USD                     ; admin

# Update the stream whereClause to only send online products that are approved
UPDATE OutboundSyncStreamConfiguration; streamId[unique = true]
                                      ; SupplementalProductDataOutboundChannelConfig_PriceRow_Stream

```

Template has been built based on SAP Help articles:
[Outbound Sync Implementation](https://help.sap.com/docs/SAP_COMMERCE/50c996852b32456c96d3161a95544cdb/4e1b6c2520e847e28da789501f0f606d.html)