Deep Dive into Salesforce to Salesforce Connection

Salesforce Connections are used to share data/records between 2  salesforce org of yours or with Partner.



Terminology we need to understand more about salesforce connection and how it works.
  • Source Org = Org which is used to share records and its data.
  • Target Org =  Org which receive shared record.
  • Connection User = A user under this operation of sharing and receiving are performed is known as "Connection User" with Profile "Partner Network".

Settings and Configuration 
In Setup : 
  • go to Salesforce to Salesforce, and enable it first to use.
  • Click on All Tabs at the navigation bar and look for Connections tab
  • Click on  New Button to create a new Connection.
  • Fill Contact (mandatory), Account, Connection Owner.
Based on Contact Email Id, a Connection Invite email is sent to that mail id and that person/Partner User has to click on a link received in email and that link direct to login to sf org for login to their own org which will serve the purpose of Target org and on successful login, establish the Connection between 2 orgs.
- Post this, we can see Connection entry there.

Related Objects and Fields

PartnerNetworkConnection:  Connection record of Partner network
PartnerNetworkRecordConnection : When a record is shared or received a new record is created under this object.
It has a few key fields.
  • ConnectionId : Id of Partner Connection through which record is shared or Received.
  • PartnerRecordId: Id of shared/Received Record at Source Org side ( Record Id in Connection Org).
  • LocalRecordId: Shared Record Id at own Org.
  • ParentRecordId: Record Id of Parent in case shared record is child. (Eg: Opportunity Id when the shared record is  OpportunityLineItem)
  • RelatedRecords: It can be used to shared child record with Comma seperated API names at the time of DML.
  • Status Active (received), Active (sent), Connected, Inactive, Inactive (converted), Inactive (deleted), Pending (sent)

There are 2 fields found at each object and become useful to track which connection it sent to or received from.
ConnectionReceivedId: Id of Connection org from where Record is received.

ConnectionSentId: Id of connection org where Record is sent.



Almost all Standard Objects and Custom Objects records can be shared.
Not all field type data can be shared, like Rich Text Area, System Audit Fields, 

At the Record Detail page, we do have External Sharing related List. which depicts if this record is shared or not, what is sharing status, and to which Connection it is shared.

External Sharing Related List at Record Detail Page



How Record is shared to another system/target org/Partner Org:

1. By Manual :
At each record detail page (Only for objects which are selected for Publishing Records and its fields), we can see External related list or if not related list can be enabled by editing page layout.  By clicking on the button "Forward this Opportunity" at the external sharing related list, we can see the next screen. 
- Choose the Connection to which record need to be shared.(target org).
- Below a few checkboxes are available to share related records along with parent record.






2. By Configuration
    (a) Flow:

We can launch an automated flow from a custom button or Process builder.
and a record is shared to target Partner org.

ConnectionId and LocalRecordId is a must while other Fields are optional and depends on the type of operation/scenario needed.

On Successful record creation at Record Detail page, we can see the status of record shared at External Sharing related List.



3. By Customization ( Code)


List ListConct = [select id from PartnerNetworkConnection
where connectionName = 'connectionName' and connectionStatus = 'Accepted' LIMIT 1];


PartnerNetworkRecordConnection objPNRC=
new PartnerNetworkRecordConnection(
ConnectionId = ListConct[0].Id,
LocalRecordId = recordid,
ParentRecordId = ParentId, //(optional and depends on scenerio)
RelatedRecords = 'Attachment, Contacts',
SendClosedTasks = false, //optional
SendOpenTasks = false, //optional
SendEmails = false ); //optional



Common Apex Exception and How to Overcome


1 INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, Insufficient access on the entity.

When you are trying to share a record for which you are not the owner and have less access on record than the owner. If you sharing Chid record for which you are the owner and but not the owner of its parent, you still face the issue.


2. INVALID_NETWORK_PARTNER_STATUS, invalid status for partner network operation
One of the reason :
When you are sharing child record with Parentid but dependent lookup/master record is necessary and not present in the target org. this error appears.
Eg: Sharing OpportunityLineItem record with ParentId of Oppid, but Product record is not available in the target system, this error comes always.
To fix this, first share Product record or make sure Product records are shared already.



3. DUPLICATE VALUE, tduplicate value found : duplicate value on record with id
This comes when we share multiple objects record using apex code with same ParentId in same list.
and Order of record in list is like this:
If list first has Object Record which has field value of RelatedRecords = 'Attachment'
and after that list has object record which has unshared Reference Record. (record which cause exception no 2 listed above).
Code Eg:

List<PartnerNetworkRecordConnection> lstPNRC = new List();

for (CustomObject obj: ListCustomObject) {
    PartnerNetworkRecordConnection objPNRC =
        new PartnerNetworkRecordConnection(
            ConnectionId = ListConct[0].Id,
            LocalRecordId = obj.Id,
            ParentRecordId = OpporId,
            RelatedRecords = 'Attachment');

    listPNRC.add(objPNRC);
}


/******* Opportunity Line Items Sharing ********/
//Cause of exception no 2
for (OpportunityLineItem objOLI: OpportunityLineItems) {
    PartnerNetworkRecordConnection newOptyConnection =
        new PartnerNetworkRecordConnection(
            ConnectionId = ListConct[0].Id,
            LocalRecordId = objOLI.Id,
            ParentRecordId = OpporId);

    lstPNRC.add(objOLI);
}

//This will give  exception no 3 due to exception no 2.   
insert lstPNRC;

The solution to this is to Keep a separate list for PNRC record which has the RelatedRecord field and separate list for which has lookup/reference field dependency.

How to Set up Debug log for Connection user
Go through salesforce article to do this :
https://help.salesforce.com/articleView?id=000333602&type=1&mode=1


Record Receiving at target org
After a record is shared from one org, another org receives it. If at connection setting we have chosen to accept Record automatically it receives it own. If not chooses we have to accept the record manually by going to a particular object tab.
Like in below image If we look at Opportunity from Connection, we have to manually accept records from there.


Shoot me up for any questions or issues related to Salesforce to Salesforce Connection.

Comments

Popular posts from this blog

How to change/update the profile of a User in Salesforce from apex code

File Migration from One Salesforce Org to Another Org using Skyvia