2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4 * SugarCRM is a customer relationship management program developed by
5 * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
7 * This program is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Affero General Public License version 3 as published by the
9 * Free Software Foundation with the addition of the following permission added
10 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
19 * You should have received a copy of the GNU Affero General Public License along with
20 * this program; if not, see http://www.gnu.org/licenses or write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
27 * The interactive user interfaces in modified source and object code versions
28 * of this program must display Appropriate Legal Notices, as required under
29 * Section 5 of the GNU Affero General Public License version 3.
31 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32 * these Appropriate Legal Notices must retain the display of the "Powered by
33 * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34 * technical reasons, the Appropriate Legal Notices must display the words
35 * "Powered by SugarCRM".
36 ********************************************************************************/
38 require_once("include/EditView/EditView2.php");
40 class ViewConvertLead extends SugarView
42 protected $fileName = "modules/Leads/metadata/convertdefs.php";
44 public function __construct(
46 $view_object_map = array()
49 parent::SugarView($bean, $view_object_map);
50 $this->medataDataFile = $this->fileName;
51 if (file_exists("custom/$this->fileName"))
53 $this->medataDataFile = "custom/$this->fileName";
58 * @see SugarView::display()
60 public function display()
62 if (!empty($_REQUEST['handle']) && $_REQUEST['handle'] == 'save')
64 return $this->handleSave();
69 // get the EditView defs to check if opportunity_name exists, for a check below for populating data
70 $opportunityNameInLayout = false;
71 $editviewFile = 'modules/Leads/metadata/editviewdefs.php';
72 $this->medataDataFile = $editviewFile;
73 if (file_exists("custom/{$editviewFile}"))
75 $this->medataDataFile = "custom/{$editviewFile}";
77 include($this->medataDataFile);
78 foreach($viewdefs['Leads']['EditView']['panels'] as $panel_index => $section){
79 foreach($section as $row_array){
80 foreach($row_array as $cell){
81 if(isset($cell['name']) && $cell['name'] == 'opportunity_name'){
82 $opportunityNameInLayout = true;
88 $this->medataDataFile = $this->fileName;
89 if (file_exists("custom/$this->fileName"))
91 $this->medataDataFile = "custom/$this->fileName";
95 $this->checkForDuplicates($this->focus);
96 $smarty = new Sugar_Smarty();
99 $ev->view = "ConvertLead";
100 echo $this->getModuleTitle();
102 require_once("include/QuickSearchDefaults.php");
103 $qsd = new QuickSearchDefaults();
104 $qsd->setFormName("ConvertLead");
106 $this->contact = new Contact();
107 $smarty->assign("contact_def", $this->contact->field_defs);
108 $smarty->assign("form_name", "ConvertLead");
109 $smarty->assign("form_id", "ConvertLead");
110 $smarty->assign("module", "Leads");
111 $smarty->assign("view", "convertlead");
112 $smarty->assign("bean", $this->focus);
113 $smarty->assign("record_id", $this->focus->id);
114 $smarty->display("modules/Leads/tpls/ConvertLeadHeader.tpl");
116 echo "<div class='edit view' style='width:auto;'>";
118 foreach($this->defs as $module => $vdef)
120 $bean = $beanList[$module];
121 $focus = new $bean();
122 $focus->fill_in_additional_detail_fields();
123 foreach($focus->field_defs as $field => $def)
125 if(isset($vdef[$ev->view]['copyData']) && $vdef[$ev->view]['copyData'])
127 if ($module == "Accounts" && $field == 'name')
129 $focus->name = $this->focus->account_name;
131 else if ($module == "Opportunities" && $field == 'amount')
133 $focus->amount = unformat_number($this->focus->opportunity_amount);
135 else if ($module == "Opportunities" && $field == 'name') {
136 if ($opportunityNameInLayout && !empty($this->focus->opportunity_name)){
137 $focus->name = $this->focus->opportunity_name;
140 else if ($field == "id")
142 //If it is not a contact, don't copy the ID from the lead
143 if ($module == "Contacts") {
144 $focus->$field = $this->focus->$field;
146 } else if (is_a($focus, "Company") && $field == 'phone_office')
148 //Special case where company and person have the same field with a different name
149 $focus->phone_office = $this->focus->phone_work;
151 else if (isset($this->focus->$field))
153 $focus->$field = $this->focus->$field;
158 //Copy over email data
159 $ev->setup($module, $focus, $this->medataDataFile, "modules/Leads/tpls/ConvertLead.tpl", false);
161 echo($ev->display(false));
162 echo($this->getValidationJS($module, $focus, $vdef[$ev->view]));
165 echo ($qsd->getQSScriptsJSONAlreadyDefined());
166 $smarty->display("modules/Leads/tpls/ConvertLeadFooter.tpl");
169 protected function getRecord()
171 $this->focus = new Lead();
172 if (isset($_REQUEST['record']))
174 $this->focus->retrieve($_REQUEST['record']);
178 protected function loadDefs()
181 include($this->medataDataFile);
182 $this->defs = $viewdefs;
186 * Returns the javascript to enable/disable validation of each module's sub-form
187 * //TODO: This should probably be on the smarty template
188 * @param $module String the target module name.
189 * @param $focus SugarBean instance of the target module.
190 * @param $focus EditView def for the module.
191 * @return String, javascript to echo to page.
193 protected function getValidationJS(
199 $validateSelect = isset($viewdef['required']) && $viewdef['required'] && !empty($viewdef['select']);
201 <script type='text/javascript'>
202 if (!SUGAR.convert) SUGAR.convert = {requiredFields: {}};
203 SUGAR.convert.toggle$module = function(){
205 inputsWithErrors = [];
206 if(!SUGAR.convert.{$module}Enabled)
208 for(var i in SUGAR.convert.requiredFields.$module)
210 addToValidate('ConvertLead', '$module' + i, 'varchar', true, SUGAR.convert.requiredFields.{$module}[i]);
213 if ($validateSelect) {
215 removeFromValidate('ConvertLead', '{$viewdef['select']}');";
219 SUGAR.convert.{$module}Enabled = true;
221 for(var i in SUGAR.convert.requiredFields.$module)
223 removeFromValidate('ConvertLead', '$module' + i);
225 if ($validateSelect) {
227 addToValidate('ConvertLead', '{$viewdef['select']}', 'varchar', true, '"
228 . translate($this->contact->field_defs[$viewdef['select']]['vname']) . "');";
231 SUGAR.convert.{$module}Enabled = false;
233 YAHOO.util.Dom.get('convert_create_{$module}').value = SUGAR.convert.{$module}Enabled;
236 if (isset($viewdef['required']) && $viewdef['required'])
238 if (!empty($viewdef['select']) && (empty($viewdef['default_action']) || $viewdef['default_action'] != 'create'))
241 SUGAR.convert.{$module}Enabled = true;";
244 YAHOO.util.Event.onDOMReady(SUGAR.convert.toggle$module);";
245 } else if (isset($viewdef['default_action']) && $viewdef['default_action'] == "create")
247 $jsOut .= "\n SUGAR.convert.{$module}Enabled = true;";
250 YAHOO.util.Event.addListener('new$module', 'click', SUGAR.convert.toggle$module);
251 SUGAR.convert.requiredFields.$module = {};";
252 foreach($focus->field_defs as $field => $def)
254 if (isset($def['required']) && $def['required'])
257 SUGAR.convert.requiredFields.$module.$field = '". translate($def['vname'], $module) . "';\n";
268 * Saves a new Contact as well as any related items passed in.
272 protected function handleSave()
274 require_once("include/formbase.php");
276 if (!empty($_REQUEST['record']))
279 $lead->retrieve($_REQUEST['record']);
285 $selectedBeans = array();
287 //Make sure the contact object is availible for relationships.
288 $beans['Contacts'] = new Contact();
289 $beans['Contacts']->id = create_guid();
290 $beans['Contacts']->new_with_id = true;
292 // Bug 39287 - Check for Duplicates on selected modules before save
293 if ( !empty($_REQUEST['selectedContact']) ) {
294 $beans['Contacts']->retrieve($_REQUEST['selectedContact']);
295 if ( !empty($beans['Contacts']->id) ) {
296 $beans['Contacts']->new_with_id = false;
297 unset($_REQUEST["convert_create_Contacts"]);
298 unset($_POST["convert_create_Contacts"]);
301 elseif (!empty($_REQUEST["convert_create_Contacts"]) && $_REQUEST["convert_create_Contacts"] != "false" && !isset($_POST['ContinueContact'])) {
302 require_once('modules/Contacts/ContactFormBase.php');
303 $contactForm = new ContactFormBase();
304 $duplicateContacts = $contactForm->checkForDuplicates('Contacts');
305 if(isset($duplicateContacts)){
306 echo $contactForm->buildTableForm($duplicateContacts, 'Contacts');
310 if ( !empty($_REQUEST['selectedAccount']) ) {
311 $_REQUEST['account_id'] = $_REQUEST['selectedAccount'];
312 unset($_REQUEST["convert_create_Accounts"]);
313 unset($_POST["convert_create_Accounts"]);
315 elseif (!empty($_REQUEST["convert_create_Accounts"]) && $_REQUEST["convert_create_Accounts"] != "false" && empty($_POST['ContinueAccount'])){
316 require_once('modules/Accounts/AccountFormBase.php');
317 $accountForm = new AccountFormBase();
318 $duplicateAccounts = $accountForm->checkForDuplicates('Accounts');
319 if(isset($duplicateAccounts)){
320 echo $accountForm->buildTableForm($duplicateAccounts);
325 foreach($this->defs as $module => $vdef)
327 //Create a new record if "create" was selected
328 if (!empty($_REQUEST["convert_create_$module"]) && $_REQUEST["convert_create_$module"] != "false")
330 //Save the new record
331 $bean = $beanList[$module];
332 if (empty($beans[$module]))
333 $beans[$module] = new $bean();
335 $this->populateNewBean($module, $beans[$module], $beans['Contacts'], $lead);
338 //If an existing bean was selected, relate it to the contact
339 else if (!empty($vdef['ConvertLead']['select'])) {
340 //Save the new record
341 $select = $vdef['ConvertLead']['select'];
342 $fieldDef = $beans['Contacts']->field_defs[$select];
343 if (!empty($fieldDef['id_name']) && !empty($_REQUEST[$fieldDef['id_name']]))
345 $beans['Contacts']->$fieldDef['id_name'] = $_REQUEST[$fieldDef['id_name']];
346 $selects[$module] = $_REQUEST[$fieldDef['id_name']];
347 if (!empty($_REQUEST[$select]))
349 $beans['Contacts']->$select = $_REQUEST[$select];
351 // Bug 39268 - Add the existing beans to a list of beans we'll potentially add the lead's activities to
352 $bean = loadBean($module);
353 $bean->retrieve($_REQUEST[$fieldDef['id_name']]);
354 $selectedBeans[$module] = $bean;
359 $this->handleActivities($lead, $beans);
360 // Bug 39268 - Add the lead's activities to the selected beans
361 $this->handleActivities($lead, $selectedBeans);
363 //Handle non-contacts relationships
364 foreach($beans as $bean)
368 if (empty($bean->assigned_user_id))
370 $bean->assigned_user_id = $lead->assigned_user_id;
372 $leadsRel = $this->findRelationship($bean, $lead);
373 if (!empty($leadsRel))
376 $bean->load_relationship ($leadsRel) ;
377 $relObject = $bean->$leadsRel->getRelationshipObject();
378 if ($relObject->relationship_type == "one-to-many" && $bean->$leadsRel->_get_bean_position())
380 $id_field = $relObject->rhs_key;
381 $lead->$id_field = $bean->id;
383 $bean->$leadsRel->add($lead->id);
387 //Special case code for opportunities->Accounts
388 if ($bean->object_name == "Opportunity" && empty($bean->account_id))
390 if( isset($beans['Accounts'])) {
391 $bean->account_id = $beans['Accounts']->id;
392 $bean->account_name = $beans['Accounts']->name;
394 else if (!empty($selects['Accounts'])){
395 $bean->account_id = $selects['Accounts'];
399 $this->copyAddressFields($bean, $beans['Contacts']);
404 { //Mark the original Lead converted
405 $lead->status = "Converted";
406 $lead->converted = '1';
407 $lead->in_workflow = true;
411 $this->displaySaveResults($beans);
414 protected function displaySaveResults(
420 foreach($beans as $bean)
422 $beanName = $bean->object_name;
423 if ( $beanName == 'Contact' && !$bean->new_with_id ) {
424 echo "<li>" . translate("LBL_EXISTING_CONTACT") . " -
425 <a href='index.php?module={$bean->module_dir}&action=DetailView&record={$bean->id}'>
426 {$bean->get_summary_text()}
430 echo "<li>" . translate("LBL_CREATED_NEW") . translate($beanName) . " -
431 <a href='index.php?module={$bean->module_dir}&action=DetailView&record={$bean->id}'>
432 {$bean->get_summary_text()}
440 protected function handleActivities(
445 global $app_list_strings;
446 $parent_types = $app_list_strings['record_type_display'];
448 $activities = $this->getActivitiesFromLead($lead);
450 foreach($beans as $module => $bean)
452 if (isset($parent_types[$module]))
454 foreach($activities as $activity)
456 $this->copyActivityAndRelateToBean($activity, $bean);
463 * Gets the list of activities related to the lead
464 * @param Lead $lead Lead to get activities from
465 * @return Array of Activity SugarBeans .
467 protected function getActivitiesFromLead(
473 global $beanList, $db;
475 $activitesList = array("Calls", "Tasks", "Meetings", "Emails", "Notes");
476 $activities = array();
478 foreach($activitesList as $module)
480 $beanName = $beanList[$module];
481 $activity = new $beanName();
482 $query = "SELECT id FROM {$activity->table_name} WHERE parent_id = '{$lead->id}' AND parent_type = 'Leads'";
483 $result = $db->query($query,true);
484 while($row = $db->fetchByAssoc($result))
486 $activity = new $beanName();
487 $activity->retrieve($row['id']);
488 $activity->fixUpFormatting();
489 $activities[] = $activity;
496 protected function copyActivityAndRelateToBean(
503 $newActivity = clone $activity;
504 $newActivity->id = create_guid();
505 $newActivity->new_with_id = true;
507 //Special case to prevent duplicated tasks from appearing under Contacts multiple times
508 if ($newActivity->module_dir == "Tasks" && $bean->module_dir != "Contacts")
510 $newActivity->contact_id = $activity->contact_name = "";
513 if ($rel = $this->findRelationship($newActivity, $bean))
515 $newActivity->load_relationship ($rel) ;
516 $relObj = $newActivity->$rel->getRelationshipObject();
517 if ( $relObj->relationship_type=='one-to-one' || $relObj->relationship_type == 'one-to-many' )
519 $key = $relObj->rhs_key;
520 $newActivity->$key = $bean->id;
522 $newActivity->$rel->add($bean->id);
523 $newActivity->parent_id = $bean->id;
524 $newActivity->parent_type = $bean->module_dir;
525 $newActivity->save();
530 * Populates the passed in Bean fron the contact and the $_REQUEST
531 * @param String $module Module of new bean
532 * @param SugarBean $bean SugarBean to be populated.
533 * @param Contact $contact Contact to relate the bean to.
535 protected function populateNewBean(
542 populateFromPost($module, $bean, true);
544 //Copy data from the contact to new bean
545 foreach($bean->field_defs as $field => $def)
547 if(!isset($_REQUEST[$module . $field]) && isset($lead->$field) && $field != 'id')
549 $bean->$field = $lead->$field;
550 if($field == 'date_entered') $bean->$field = gmdate($GLOBALS['timedate']->get_db_date_time_format()); //bug 41030
553 //Try to link to the new contact
555 if (!empty($vdef['ConvertLead']['select']))
557 $select = $vdef['ConvertLead']['select'];
558 $fieldDef = $contact->field_defs[$select];
559 if (!empty($fieldDef['id_name']))
561 $bean->id = create_guid();
562 $bean->new_with_id = true;
563 $contact->$fieldDef['id_name'] = $bean->id ;
564 if ($fieldDef['id_name'] != $select) {
565 $rname = isset($fieldDef['rname']) ? $fieldDef['rname'] : "";
566 if (!empty($rname) && isset($bean->$rname))
567 $contact->$select = $bean->$rname;
569 $contact->$select = $bean->name;
572 } else if ($module != "Contacts"){
573 $contactRel = $this->findRelationship($contact, $bean);
574 if (!empty($contactRel))
576 $bean->id = create_guid();
577 $bean->new_with_id = true;
578 $contact->load_relationship ($contactRel) ;
579 $relObject = $contact->$contactRel->getRelationshipObject();
580 if ($relObject->relationship_type == "one-to-many" && $contact->$contactRel->_get_bean_position())
582 $id_field = $relObject->rhs_key;
583 $bean->$id_field = $contact->id;
585 $contact->$contactRel->add($bean->id);
587 //Set the parent of activites to the new Contact
588 if (isset($bean->field_defs['parent_id']) && isset($bean->field_defs['parent_type']))
590 $bean->parent_id = $contact->id;
591 $bean->parent_type = "Contacts";
597 protected function copyAddressFields($bean, $contact)
599 //Copy over address info from the contact to any beans with address not set
600 foreach($bean->field_defs as $field => $def)
602 if(!isset($_REQUEST[$bean->module_dir . $field]) && strpos($field, "_address_") !== false)
605 if (strpos($field, "alt_") !== false || strpos($field, "shipping_") !== false)
609 if(strpos($field, "_address_street_2") !== false)
610 $type = "_address_street_2";
611 else if(strpos($field, "_address_street_3") !== false)
612 $type = "_address_street_3";
613 else if(strpos($field, "_address_street_4") !== false)
615 else if(strpos($field, "_address_street") !== false)
616 $type = "_address_street";
617 else if(strpos($field, "_address_city") !== false)
618 $type = "_address_city";
619 else if(strpos($field, "_address_state") !== false)
620 $type = "_address_state";
621 else if(strpos($field, "_address_postalcode") !== false)
622 $type = "_address_postalcode";
623 else if(strpos($field, "_address_country") !== false)
624 $type = "_address_country";
627 if (isset($contact->$var))
628 $bean->$field = $contact->$var;
634 protected function findRelationship(
640 require_once("modules/TableDictionary.php");
641 foreach ($from->field_defs as $field=>$def)
643 if (isset($def['type']) && $def['type'] == "link" && isset($def['relationship'])) {
644 $rel_name = $def['relationship'];
646 if (isset($dictionary[$from->object_name]['relationships']) && isset($dictionary[$from->object_name]['relationships'][$rel_name]))
648 $rel_def = $dictionary[$from->object_name]['relationships'][$rel_name];
650 else if (isset($dictionary[$to->object_name]['relationships']) && isset($dictionary[$to->object_name]['relationships'][$rel_name]))
652 $rel_def = $dictionary[$to->object_name]['relationships'][$rel_name];
654 else if (isset($dictionary[$rel_name]) && isset($dictionary[$rel_name]['relationships'])
655 && isset($dictionary[$rel_name]['relationships'][$rel_name]))
657 $rel_def = $dictionary[$rel_name]['relationships'][$rel_name];
659 if (!empty($rel_def)) {
660 if ($rel_def['lhs_module'] == $from->module_dir && $rel_def['rhs_module'] == $to->module_dir )
664 else if ($rel_def['rhs_module'] == $from->module_dir && $rel_def['lhs_module'] == $to->module_dir )
675 * @see SugarView::_getModuleTitleParams()
677 protected function _getModuleTitleParams()
680 $params = parent::_getModuleTitleParams();
681 $params[] = "<a href='index.php?module=Leads&action=DetailView&record={$this->bean->id}'>{$this->bean->name}</a>";
682 $params[] = $mod_strings['LBL_CONVERTLEAD'];
687 protected function checkForDuplicates(
691 if ($lead->status == "Converted")
693 echo ("<span class='error'>" . translate('LBL_CONVERTLEAD_WARNING'));
695 $q = "SELECT id, first_name, last_name FROM contacts WHERE first_name LIKE '{$lead->first_name}' AND last_name LIKE '{$lead->last_name}'";
696 $result = $lead->db->query($q);
697 while($row = $lead->db->fetchByAssoc($result)) {
698 $contact = new Contact();
699 $contact->retrieve($row['id']);
700 $dupes[$row['id']] = $contact->name;
704 foreach($dupes as $id => $name)
706 echo (translate('LBL_CONVERTLEAD_WARNING_INTO_RECORD') . "<a href='index.php?module=Contacts&action=DetailView&record=$id'>$name</a>");