From abd0b85220efc2f58a6e7b556037d3b5109a7085 Mon Sep 17 00:00:00 2001 From: JKingsnorth Date: Thu, 18 Aug 2016 15:52:01 +0100 Subject: [PATCH] CRM-19179: Allow primary location block to be changed during manual merge --- CRM/Dedupe/Merger.php | 26 ++++- templates/CRM/Contact/Form/Merge.tpl | 162 +++++++++++++++------------ 2 files changed, 112 insertions(+), 76 deletions(-) diff --git a/CRM/Dedupe/Merger.php b/CRM/Dedupe/Merger.php index 78460f923f..625756223c 100644 --- a/CRM/Dedupe/Merger.php +++ b/CRM/Dedupe/Merger.php @@ -1237,6 +1237,9 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m // Add checkbox to migrate data from 'other' to 'main' $elements[] = array('advcheckbox', "move_location_{$blockName}_{$count}"); + // Add checkbox to set the 'other' location as primary + $elements[] = array('advcheckbox', "location_blocks[$blockName][$count][set_other_primary]", NULL, ts('Set as primary')); + // Flag up this field to skipMerge function (@todo: do we need to?) $migrationInfo["move_location_{$blockName}_{$count}"] = 1; @@ -1275,7 +1278,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m // @todo Check this logic out $migrationInfo['location_blocks'][$blockName][$count]['locTypeId'] = $thisLocId; if ($blockName != 'address') { - $elements[] = array('advcheckbox', "location_blocks[{$blockName}][$count][operation]", NULL, ts('add new')); + $elements[] = array('advcheckbox', "location_blocks[{$blockName}][$count][operation]", NULL, ts('Add new')); // always use add operation $migrationInfo['location_blocks'][$blockName][$count]['operation'] = 1; } @@ -2083,6 +2086,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m continue; } $daoName = 'CRM_Core_DAO_' . $locationBlocks[$name]['label']; + $changePrimary = FALSE; $primaryDAOId = (array_key_exists($name, $primaryBlockIds)) ? array_pop($primaryBlockIds[$name]) : NULL; $billingDAOId = (array_key_exists($name, $billingBlockIds)) ? array_pop($billingBlockIds[$name]) : NULL; @@ -2110,10 +2114,26 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m $otherBlockDAO->{$locationBlocks[$name]['hasType']} = $typeTypeId; } - // if main contact already has primary & billing, set the flags to 0. - if ($primaryDAOId) { + // If we're deliberately setting this as primary then add the flag + // and remove it from the current primary location (if there is one). + // But only once for each entity. + $set_primary = CRM_Utils_Array::value('set_other_primary', $migrationInfo['location_blocks'][$name][$blkCount]); + if (!$changePrimary && $set_primary == "1"){ + $otherBlockDAO->is_primary = 1; + if ($primaryDAOId) { + $removePrimaryDAO = new $daoName(); + $removePrimaryDAO->id = $primaryDAOId; + $removePrimaryDAO->is_primary = 0; + $blocksDAO[$name]['update'][$primaryDAOId] = $removePrimaryDAO; + } + $changePrimary = TRUE; + } + // Otherwise, if main contact already has primary, set it to 0. + elseif ($primaryDAOId) { $otherBlockDAO->is_primary = 0; } + + // If the main contact already has a billing location, set this to 0. if ($billingDAOId) { $otherBlockDAO->is_billing = 0; } diff --git a/templates/CRM/Contact/Form/Merge.tpl b/templates/CRM/Contact/Form/Merge.tpl index c43ff4a0d2..733b515399 100644 --- a/templates/CRM/Contact/Form/Merge.tpl +++ b/templates/CRM/Contact/Form/Merge.tpl @@ -147,22 +147,27 @@ {/if} {* Display the overwrite/add/add new label *} - - {if $row.main} - - {* Display whether it is primary *} - {if $row.main_is_primary == "1"} - Primary  + + + + {if $row.main && $row.main_is_primary == "1"}Primary{/if} + + + + + {if $row.main}({ts}overwrite{/ts}){else}({ts}add{/ts}){/if} + + + {if $row.main && ($blockName eq 'email' || $blockName eq 'phone')} + {$form.location_blocks.$blockName.$blockId.operation.html} {/if} - ({ts}overwrite{/ts}) - {if $blockName eq 'email' || $blockName eq 'phone' } - {$form.location_blocks.$blockName.$blockId.operation.html}  - {/if} -
- {else} - ({ts}add{/ts})  - {/if} + + {if $blockName neq 'website' && (($row.main && $row.main_is_primary != "1") || !$row.main)} + {$form.location_blocks.$blockName.$blockId.set_other_primary.html} + {/if} + +
@@ -232,76 +237,97 @@ var allBlock = {/literal}{$mainLocBlock}{literal}; /** - * Triggered when a 'location' or 'type' destination is changed. + * Triggered when a 'location' or 'type' destination is changed, and when + * the operation or 'set primary' checkboxes are changed. + * * Check to see if the 'main' contact record has a corresponding location * block when the destination of a field is changed. Allow existing location * fields to be overwritten with data from the 'other' contact. * - * @param blockname string + * @param blockName string * The name of the entity. - * @param element object - * The element that was changed (location or type dropdown) * @param blockId int * The block ID being affected - * @param type string - * Location or type (locTypeId / typeTypeId) */ - function mergeBlock(blockname, element, blockId, type) { + function updateMainLocationBlock(blockName, blockId) { // Get type of select list that's been changed (location or type) - var locTypeId = ''; - var typeTypeId = ''; - - // If the location was changed, lookup the type if it exists - if (type == 'locTypeId') { - locTypeId = element.value; - typeTypeId = CRM.$( 'select#location_blocks_' + blockname + '_' + blockId + '_typeTypeId' ).val(); - } - - // Otherwise the type was changed, lookup the location if it exists - else { - locTypeId = CRM.$( 'select#location_blocks_' + blockname + '_' + blockId + '_locTypeId' ).val(); - typeTypeId = element.value; - } + var locTypeId = CRM.$('select#location_blocks_' + blockName + '_' + blockId + '_locTypeId').val(); + var typeTypeId = CRM.$('select#location_blocks_' + blockName + '_' + blockId + '_typeTypeId').val(); // @todo Fix this 'special handling' for websites (no location id) - if (!locTypeId) { locTypeId = 0; } + if (!locTypeId) { + locTypeId = 0; + } // Look for a matching block on the main contact var mainBlockId = 0; var mainBlockDisplay = ''; - var mainBlock = findBlock(blockname, locTypeId, typeTypeId); - - // Create appropriate label / add new link after changing the block - if (mainBlock == false) { - label = '({/literal}{ts}add{/ts}{literal})'; - } - else { - // Set display and ID + var mainBlock = findBlock(blockName, locTypeId, typeTypeId); + if (mainBlock != false) { mainBlockDisplay = mainBlock['display']; mainBlockId = mainBlock['id']; + } + + // Update main location display and id + CRM.$("input[name='location_blocks[" + blockName + "][" + blockId + "][mainContactBlockId]']").val(mainBlockId); + CRM.$("#main_" + blockName + "_" + blockId).html(mainBlockDisplay); - // Set label - var label = ''; + // Update controls area - // Check if the main location is primary - if (mainBlock['is_primary'] == "1") { - label += 'Primary '; + // Get the parent block once for speed + var this_controls = CRM.$("#main_" + blockName + "_" + blockId + "_overwrite"); + + // Update primary label + if (mainBlock != false && mainBlock['is_primary'] == '1') { + this_controls.find(".location_primary").text('Primary'); + } + else { + this_controls.find(".location_primary").text(''); + } + + // Update operation description + var operation_description = "{/literal}{ts}add{/ts}{literal}"; + var add_new_check_length = this_controls.find(".location_operation_checkbox input:checked").length; + if (mainBlock != false) { + if (add_new_check_length > 0) { + operation_description = "{/literal}{ts}add new{/ts}{literal}"; } + else { + operation_description = "{/literal}{ts}overwrite{/ts}{literal}"; + } + } + this_controls.find(".location_operation_description").text("(" + operation_description + ")"); + + // Skip if the 'add new' or 'set primary' checkboxes were clicked + if (event.target.id.match(/(operation|set_other_primary)/) === null) { + // Display 'Add new' checkbox if there is a main block, and this is an + // email or phone type. + if (mainBlock != false && (blockName == 'email' || blockName == 'phone')) { + var op_id = 'location_blocks[' + blockName + '][' + blockId + '][operation]'; + this_controls.find(".location_operation_checkbox").html( + '' + ); + } + else { + this_controls.find(".location_operation_checkbox").html(''); + } + } - // Display the action - label += '({/literal}{ts}overwrite{/ts}{literal}) '; - if (blockname == 'email' || blockname == 'phone') { - var opLabel = 'location_blocks[' + blockname + '][' + blockId + '][operation]'; - label += '
'; + // Skip if 'set primary' was clicked + if (event.target.id.match(/(set_other_primary)/) === null) { + // Display 'Set primary' checkbox if applicable + if (blockName != 'website' && (mainBlock == false || mainBlock['is_primary'] != "1" || add_new_check_length > 0)) { + var prim_id = 'location_blocks[' + blockName + '][' + blockId + '][set_other_primary]'; + this_controls.find(".location_set_other_primary").html( + '' + ); + } + else { + this_controls.find(".location_set_other_primary").html(''); } - label += '
'; } - // Update DOM - CRM.$( "input[name='location_blocks[" + blockname + "][" + blockId + "][mainContactBlockId]']" ).val( mainBlockId ); - CRM.$( "#main_" + blockname + "_" + blockId ).html( mainBlockDisplay ); - CRM.$( "#main_" + blockname + "_" + blockId + "_overwrite" ).html( label ); } /** @@ -340,16 +366,6 @@ CRM.$(function($) { - $('body').on('change', "input[id*='[operation]']", function() { - var originalHtml = $(this).prevAll('span.action_label').html(); - if ($(this).is(":checked")) { - $(this).prevAll('span.action_label').html(originalHtml.replace('({/literal}{ts}overwrite{/ts}{literal})', '({/literal}{ts}add new{/ts}{literal})')); - } - else { - $(this).prevAll('span.action_label').html(originalHtml.replace('({/literal}{ts}add new{/ts}{literal})', '({/literal}{ts}overwrite{/ts}{literal})')); - } - }); - $('table td input.form-checkbox').each(function() { var ele = null; var element = $(this).attr('id').split('_',3); @@ -379,12 +395,12 @@ }); // Call mergeBlock whenever a location type is changed - jQuery('select[id^="location_blocks_"]').change(function(){ + $('body').on('change', 'select[id$="locTypeId"],select[id$="typeTypeId"],input[id$="[operation]"],input[id$="[set_other_primary]"]', function(){ // All the information we need is held in the id, separated by underscores - var idSplit = this.id.split('_'); + var nameSplit = this.name.split('['); // Lookup the main value, if any are available - if (allBlock[idSplit[2]] != undefined) { - mergeBlock(idSplit[2], this, idSplit[3], idSplit[4]); + if (allBlock[nameSplit[1].slice(0, -1)] != undefined) { + updateMainLocationBlock(nameSplit[1].slice(0, -1), nameSplit[2].slice(0, -1)); } }); -- 2.25.1