In my development of the uc_sf_account.module, which I am going to add soon to the Ubercart / Salesforce Integration package, I have come across an issue with salesforce_api_fieldmap_export_create() which would be great if it could be resolved in the Salesforce API module, rather than worked around in my code.
The issue is that there is currently no way in the Salesforce field mapping UI to specify that the value for a given field should come from another object that has been mapped. In SQL terms, this would be called a "foreign key"; in Salesforce terms, I'm talking about a field which is either lookup or master-detail and thus takes a Salesforce ID as its value.
My specific use case is exporting an OpportunityContactRole record from Salesforce using the Salesforce ID of an Ubercart order that has been mapped to an Opportunity record. Currently, in the uc_sf_order.module of Ubercart/Salesforce Integration this is tracked in an OCR node, so that the line
$ocr_object = salesforce_api_fieldmap_export_create($ocr_fieldmap_id, $ocr_node); can work.
However, the creation of a node should not be necessary. The Salesforce API module should be able to tell whether a "Create-only" field, such as OpportunityId, is the primary key (Id) for an object, or whether it is a foreign key, and if it is a foreign key, then it should provide an object to map it to the Salesforce ID of another mapped object.
I guess the only issue with this is that there would have to be a way to specify also what the Drupal ID was for which you wanted to do the export. Currently, I have the following code in uc_sf_account.module:
function _uc_sf_account_export_values($source, $field) {
$ret_val = NULL;
if($field == 'uc_sf_order_contact_sfid') {
$order_id = (isset($source->order_id) && !empty($source->order_id)) ? $source->order_id : $source->field_order_id[0]['value'];
$order_purchaser_contact_sf_info = salesforce_api_id_load('uc_order_contact', $order_id);
$ret_val = $order_purchaser_contact_sf_info->sfid;
}
elseif($field == 'uc_sf_order_account_sfid') {
$order_id = (isset($source->order_id) && !empty($source->order_id)) ? $source->order_id : $source->field_order_id[0]['value'];
$order_purchaser_sf_info = salesforce_api_id_load('uc_order_account', $order_id);
$ret_val = $order_purchaser_sf_info->sfid;
}
else {
$ret_val = NULL;
}
return $ret_val;
}
However, these mapping functions, which require the $source to be the $order object (i.e., a given Ubercart order), do not work directly for exporting an OCR, because of the following condition in salesforce_api_fieldmap_export_create():
<?php // Don't try to update or create fields to which those actions do not apply.
if ((!$updateable && !$createable)
|| (empty($drupal_data->salesforce->sfid) && !$createable)
|| (!empty($drupal_data->salesforce->sfid) && !$updateable)) {
continue;
}
It sees that there is a salesforce->sfid in the $drupal_data (since I pass in $order, like so: $ocr = salesforce_api_fieldmap_export_create($ocr_map->name, $order);), and so skips the field on export. If there were a way that I could specify in the Salesforce API that the object was derivative of another Drupal object, and thus would be created from its data, then this problem would not arise.
Comments
Comment #1
EvanDonovan commentedPossibly some kind of foreign key support would be a stepping stone on the way to resolving #785286: Provide ability to create one-to-many fieldmaps.
Comment #2
EvanDonovan commentedHere is the downstream issue that may get postponed on this: #993776: Refactor the OpportunityContactRole integration into a separate module, and make it not based on nodes.
Comment #3
Alice Heaton commentedMaybe a first helpful step for developers would be to pass the sfid when node_save is called, so that we can use node_api to pull out extra information ourselves. (I realise this is only helpful from sf -> drupal)
I opened a separate ticket about this, with a patch (as I guess it is something that could apply to other user cases, not just this one).
http://drupal.org/node/1065760
Comment #4
EvanDonovan commentedSounds like my situation in uc_sf_order could be handle by the post_export hook according to that issue.