From 11aacd5803e3f83b046669b6a2ab9bc79dec6576 Mon Sep 17 00:00:00 2001 From: abijah Date: Fri, 2 Jul 2010 20:52:00 +0000 Subject: [PATCH] Modified customer merge functionality to leave everything from the destination customer in-tact, and simply add on contacts from the source customer, if requested. This simplifies things significantly, and also the paradigm shift of starting the operation from the destination customer allows us to merge multiple customers into one with ease (no need to dig around for each source customer before clicking merge) git-svn-id: file:///svn-source/pmgr/branches/v0.3_work@995 97e9348a-65ac-dc4b-aefc-98561f571b83 --- site/controllers/customers_controller.php | 9 +- site/models/customer.php | 123 +++++++++------------- site/views/customers/merge.ctp | 114 +++----------------- site/views/elements/contacts.ctp | 3 +- 4 files changed, 72 insertions(+), 177 deletions(-) diff --git a/site/controllers/customers_controller.php b/site/controllers/customers_controller.php index bab2c95..3a794b4 100644 --- a/site/controllers/customers_controller.php +++ b/site/controllers/customers_controller.php @@ -466,9 +466,9 @@ class CustomersController extends AppController { $customer = $customer['Customer']; if (empty($customer)) $this->INTERNAL_ERROR("Customer $id does not exist"); - $this->set('src_customer', $customer); - $this->set('src_name', $customer['name']); - $this->set('src_id', $id); + $this->set('dst_customer', $customer); + $this->set('dst_name', $customer['name']); + $this->set('dst_id', $id); } else { $this->INTERNAL_ERROR("Merge called with invalid customer"); @@ -483,8 +483,7 @@ class CustomersController extends AppController { $post = $this->params['form']; $this->Customer->merge($post['dst-id'], $post['src-id'], - unserialize($post['contact-ids']), - $post['primary-contact-id']); + unserialize($post['contact-ids'])); $this->redirect(array('action'=>'view', $post['dst-id'])); } diff --git a/site/models/customer.php b/site/models/customer.php index b76facf..a01f8ba 100644 --- a/site/models/customer.php +++ b/site/models/customer.php @@ -20,7 +20,13 @@ class Customer extends AppModel { ), 'Lease', 'StatementEntry', - 'ContactsCustomer', + 'ContactsCustomer' => array( + // It would be nice to claim a dependency here, which would + // simplify deletion of a customer. However, for this to work + // Cake must have a primaryKey as a single field. This table + // makes use of a complex key, so we're out of luck. + /* 'dependent' => true, */ + ), 'Transaction', 'Tender', @@ -290,91 +296,54 @@ class Customer extends AppModel { * - Merges two customers into one */ - function merge($dst_id, $src_id, $contacts, $primary_contact_id) { - $this->prEnter(compact('dst_id', 'src_id', 'contacts', 'primary_contact_id')); - - $contacts = array_unique($contacts, SORT_NUMERIC); - if (!in_array($primary_contact_id, $contacts)) - return $this->prReturn(false); - - $all_contacts = array(); - - $result = $this->find('all', - array('link' => array('ContactsCustomer'), - 'fields' => array('ContactsCustomer.contact_id', 'ContactsCustomer.type'), - 'conditions' => array(array('id' => $src_id, - 'ContactsCustomer.active' => true)))); - $this->pr(17, compact('result')); - - foreach ($result AS $contact) { - $this->pr(17, compact('contact'), "Add contact"); - $all_contacts[$contact['ContactsCustomer']['contact_id']] = $contact['ContactsCustomer']; - } + function merge($dst_id, $src_id, $contacts) { + $this->prEnter(compact('dst_id', 'src_id', 'contacts')); + // Get the entire list of destination customer contacts + $dst_contacts = array(); $result = $this->find('all', array('link' => array('ContactsCustomer'), 'fields' => array('ContactsCustomer.contact_id', 'ContactsCustomer.type'), 'conditions' => array(array('id' => $dst_id, 'ContactsCustomer.active' => true)))); - /* array('link' => array('Contact'), */ - /* 'fields' => array('Contact.id'), */ - /* 'conditions' => array(array('Customer.id' => $src_id)))); */ - $this->pr(17, compact('result')); - foreach ($result AS $contact) { - $this->pr(17, compact('contact'), "Add contact"); - $all_contacts[$contact['ContactsCustomer']['contact_id']] = $contact['ContactsCustomer']; + $dst_contacts[$contact['ContactsCustomer']['contact_id']] = $contact['ContactsCustomer']; } + $this->pr(17, compact('dst_contacts')); - $this->pr(17, compact('all_contacts')); + // Get the entire list of source customer contacts + $src_contacts = array(); + $result = $this->find('all', + array('link' => array('ContactsCustomer'), + 'fields' => array('ContactsCustomer.contact_id', 'ContactsCustomer.type'), + 'conditions' => array(array('id' => $src_id, + 'ContactsCustomer.active' => true)))); + foreach ($result AS $contact) { + $src_contacts[$contact['ContactsCustomer']['contact_id']] = $contact['ContactsCustomer']; + } + $this->pr(17, compact('src_contacts')); - foreach ($contacts AS $cid) { - if (!array_key_exists($cid, $all_contacts)) + // Verify the contacts list are all valid source customer contacts + foreach ($contacts AS $contact_id) { + if (!array_key_exists($contact_id, $src_contacts)) return $this->prReturn(false); } - $this->id = $dst_id; - $this->recursive = -1; - //$this->recursive = 1; - $this->read(); + // Remove any contacts which are already destination customer contacts + $contacts = array_diff($contacts, array_keys($dst_contacts)); - $this->pr(17, $this->data); - - if (!empty($primary_contact_id)) - $this->data['Customer']['primary_contact_id'] = $primary_contact_id; - - $this->data['Contact'] = array(); - foreach ($contacts AS $contact_id) - $this->data['Contact'][] = array('id' => $contact_id, - 'ContactsCustomer' => - array('customer_id' => $dst_id) + - $all_contacts[$contact_id]); - - /* $this->data['ContactsCustomer'] = array(); */ - /* foreach ($contacts AS $contact_id) { */ - /* $this->data['ContactsCustomer'][] = */ - /* //array('ContactsCustomer' => */ - /* array('customer_id' => $dst_id) + */ - /* $all_contacts[$contact_id] */ - /* //); */ - /* } */ - - $this->pr(17, $this->data); - -/* $this->ContactsCustomer->deleteAll */ -/* (array('customer_id' => $id), false); */ - - //$this->recursive = 1; - if (!$this->saveAll($this->data, array('validate' => false))) { - return $this->prReturn(false); - } - - // At this point, since we've saved data to customer, - // we'll proceed forward as much as possible, even - // if we encounter an error. For now, we'll assume - // the operation will succeed. + // For now, we'll assume the operation will succeed. $ret = true; + // Add each desired source customer contact to the destination customer + foreach ($contacts AS $contact_id) { + $CM = new ContactsCustomer(); + if (!$CM->save(array('customer_id' => $dst_id) + + $src_contacts[$contact_id], false)) { + $ret = false; + } + } + $this->Lease->updateAll (array('Lease.customer_id' => $dst_id), array('Lease.customer_id' => $src_id) @@ -398,23 +367,31 @@ class Customer extends AppModel { // Make sure our lease counts, etc are correct $this->update($dst_id); + // Delete the old customer $this->pr(12, compact('src_id'), "Delete Customer"); $this->delete($src_id); - foreach (array_diff_key($all_contacts, array_flip($contacts)) AS $contact_id) { + // Delete all the orphaned customers + foreach (array_diff(array_keys($src_contacts), $contacts) AS $contact_id) { // Delete un-used or duplicate contacts - // REVISIT 20100716: + // REVISIT 20100702: // Not sure if we really want to do this. // On the one hand, they're probably really redundant, // and only clutter up the list of all contacts. On the // other hand, it destroys data, not only losing the // history, but making it difficult to recover if the - // merge is a mistake. + // merge is a mistake. Additionally, we need to do + // extra checking to ensure that the contact is not + // in use by some other customer. // We need some sort of Contact.deleted field... $this->pr(12, compact('contact_id'), "Delete Contact"); $this->Contact->delete($contact_id); } + // Finally, delete all customer contact relationships + $this->ContactsCustomer->deleteAll + (array('customer_id' => $src_id), false); + // Return the result return $this->prReturn($ret); } diff --git a/site/views/customers/merge.ctp b/site/views/customers/merge.ctp index 746e689..40b7220 100644 --- a/site/views/customers/merge.ctp +++ b/site/views/customers/merge.ctp @@ -20,40 +20,12 @@ Configure::write('debug', '0'); // pre-submit callback function verifyRequest() { - var pid; - var rows; - - if (!$("#dst-customer-id").val()) { - alert("Must select destination customer"); - return false; - } - - pid = $('#').getGridParam('selrow'); - if (!pid) { - alert("Must select a primary contact"); + if (!$("#src-customer-id").val()) { + alert("Must select source customer"); return false; } rows = $('#').getGridParam('selarrrow'); - if (!rows.length) { - alert("Must select at least one contact"); - return false; - } - - var found = false; - for (var i=0; i < rows.length; ++i) { - if (pid == rows[i]) { - found = true; - break; - } - } - - if (!found) { - alert("Primary contact is not a member of the selected contacts"); - return false; - } - - $('#').val(pid); $('#').val(serialize(rows)); // return false to prevent the form from being submitted; @@ -61,21 +33,11 @@ function verifyRequest() { return true; } -// Reset the form -function resetForm() { - $('#payment-entry-id').val(1); - $('#payments').html(''); - - //updateContacts(); -} - function updateContacts() { $('#contacts-jqGrid').clearGridData(); var filter = new Array(); - //filter['ContactsCustomer.customer_id'] = ; - //filter['ContactsCustomer.customer_id'] = $("#dst-customer-id").val(); - filter['ContactsCustomer.customer_id'] = new Array(, $("#dst-customer-id").val()); + filter['ContactsCustomer.customer_id'] = $("#src-customer-id").val(); var dynamic_post = new Array(); dynamic_post['filter'] = filter; @@ -84,26 +46,16 @@ function updateContacts() { $('#contacts-jqGrid') .setGridParam({ page: 1 }) .trigger("reloadGrid"); - - $('#primary-contacts-jqGrid').setPostDataItem('dynamic_post_replace', serialize(dynamic_post)); - $('#primary-contacts-jqGrid') - .setGridParam({ page: 1 }) - .trigger("reloadGrid"); - - /* var gridstate = $('#contacts-jqGrid').getGridParam('gridstate'); */ - /* var gridstate = $('#primary-contacts-jqGrid').getGridParam('gridstate'); */ - /* if (gridstate == 'hidden') */ - /* $('#contacts .HeaderButton').click(); */ } function onRowSelect(grid_id, customer_id) { //$('#output-debug').append("select: "+grid_id+"; "+customer_id+"
\n"); // Set the item id that will be returned with the form - $("#dst-customer-id").val(customer_id); + $("#src-customer-id").val(customer_id); // Get the item name from the grid - $("#dst-customer-name").html($(grid_id).getCell(customer_id, "Customer-name")); + $("#src-customer-name").html($(grid_id).getCell(customer_id, "Customer-name")); updateContacts(); @@ -118,7 +70,7 @@ function onGridState(grid_id, state) { $(".customer-selection-valid").hide(); } else { - if ($("#dst-customer-id").val() > 0) { + if ($("#src-customer-id").val() > 0) { $(".customer-selection-invalid").hide(); $(".customer-selection-valid").show(); } else { @@ -128,10 +80,6 @@ function onGridState(grid_id, state) { } } -/* function onContactsGridLoadComplete() { */ -/* var userdata = $('#contacts-jqGrid').getGridParam('userData'); */ -/* } */ - --> create(null, array('id' => 'customer-merge-form', 'action' => 'mergeFinal')))."\n"; -echo ''."\n"; -echo ''."\n"; +echo ''."\n"; +echo ''."\n"; echo $this->element('customers', array ('config' => array @@ -154,7 +102,6 @@ echo $this->element('customers', array 'grid_div_class' => 'text-below', 'caption' => ('Select Customer'), - //'grid_setup' => array('hiddengrid' => isset($customer['id'])), 'grid_events' => array('onSelectRow' => array('ids' => 'if (ids != null){onRowSelect("#"+$(this).attr("id"), ids);}'), @@ -162,7 +109,7 @@ echo $this->element('customers', array array('gridstate' => 'onGridState("#"+$(this).attr("id"), gridstate)'), ), - //'action' => 'current', + 'filter' => array('Customer.id !=' => $dst_id), //'nolinks' => true, 'limit' => 10, ))); @@ -170,7 +117,7 @@ echo $this->element('customers', array echo ('
' . '' . '