2
votes

I need Contacts shared over S2S from Org A to Org B to automatically show up in Org B under the correct (previously shared) Account.

My goal is to publish Account A1 and its related Contacts from Org A, and have them all automatically show up in Org B (no manual intervention required) with the same Account/Contact relationship preserved.

I was sure I had done this previously, but it is possible that the last few times I did this was with custom master-detail records.

Can someone clarify if this is actually possible, or does S2S only support this for true custom master-detail relationships?

So far I have tried both manual sharing ("forward to connections" - with and without the "forward related records" checkbox) and automatic (via PartnerNetworkConnection in Account and/or Contact after update and/or after insert trigger) sharing. I've also tried both contact then account, and account then contact. I've also tried checking and unchecking the "auto-accept" of Contact, and even un-mapping it, in the naive hope that would result in the

If I use a trigger to auto-send a contact and populate ParentRecordId on the PartnerNetworkRecordConnection record, the Contact gets shared but not auto-accepted, and I have to manually map it to an Account. If I share it without the ParentRecordId specified, it does get auto-accepted, but without any Account. The "forward to connections" with "forward related records" checkbox from Account seems to do the same thing - the account and all children contacts get forwarded, but the Contact records don't get auto-accepted.

I was certain Salesforce-to-Salesforce handled this, but I can't find any further info about it. Anyone have a recipe that works for auto-sharing and auto-accepting accounts with related contacts?

In case it is a code oversight (I very much doubt it), here is the code I use to share Contacts. It is loosely based on the "Best Practices for Salesforce to Salesforce" code examples (http://wiki.developerforce.com/page/Best_Practices_for_Salesforce_to_Salesforce)

public static void share(List<Contact> triggerNew) {
    // Define connection id
    Id networkId = ConnectionHelper.getConnectionId('Some Partner Connection');

    Set<Id> localContactAccountSet = new Set<Id>();
    List<Contact> localContactSet = new List<Contact>();
    Set<Id> sharedAccountSet = new Set<Id>();

    // only share records created in this org, do not add contacts received from another org.
    for (Contact ct : triggerNew) {
        if (ct.ConnectionReceivedId == null) {
            localContactAccountSet.add(ct.AccountId);
            localContactSet.add(ct);
        }       
    }

    if (localContactAccountSet.size() > 0) {
        List<PartnerNetworkRecordConnection> newConns = new List<PartnerNetworkRecordConnection>();

        // Get the contact account's partner network record connections
        for (PartnerNetworkRecordConnection accountSharingRecord : [SELECT p.Status, p.LocalRecordId, p.ConnectionId FROM PartnerNetworkRecordConnection p WHERE p.LocalRecordId IN :localContactAccountSet]) {
            // for each partner connection record for contact's account, check if it is active 
            if ((accountSharingRecord.status.equalsignorecase('Sent') || accountSharingRecord.status.equalsignorecase('Received')) && (accountSharingRecord.ConnectionId == networkId)) {
                sharedAccountSet.add(accountSharingRecord.LocalRecordId); 
            }
        }

        if (sharedAccountSet.size() > 0) {
            for (Contact ct : localContactSet) {
                if (sharedAccountSet.contains(ct.AccountId)) {
                    PartnerNetworkRecordConnection newConnection =
                      new PartnerNetworkRecordConnection(
                          ConnectionId = networkId,
                          LocalRecordId = ct.Id,
                          SendClosedTasks = false,
                          SendOpenTasks = false,
                          SendEmails = false,
                          ParentRecordId = ct.AccountId);

                    newConns.add(newConnection);
                }
            }

            if (newConns.size() > 0 ) {
               database.insert(newConns);
            }
        }
    }
}
1
I've followed the official(wiki.developerforce.com/page/…) doc and it worked fine for me. I've published Accounts and Contacts, then subscribe those objects checking "Automatically map fields" option. Are you sure that you don't have a lookup ID?Martin Borthiry

1 Answers

2
votes

UPDATE: issue resolved.

Turned out that Contact had a long-unused and forgotten custom Lookup(Account) field on it. Deleting this field fixed the issue and caused both Accounts and Contacts to be auto-accepted.

Thanks to Salesforce for their VERY swift response on this that helped me fix the issue.

And as a friendly reminder: multiple lookup relationships on child objects will prevent auto-accept from happening on child objects. This is in the documentation but failed to occur to me during diagnosis.