/** * get special field value * * @param Tinebase_Record_Interface $_record * @param array $_param * @param string $_key * @param string $_cellType * @param array $_resolvedRecords * @return string */ public static function getSpecialFieldValue(Tinebase_Record_Interface $_record, $_param, $_key = NULL, &$_cellType = NULL, $_resolvedRecords = NULL) { if (is_null($_key)) { throw new Tinebase_Exception_InvalidArgument('Missing required parameter $key'); } $configKeysAndProps = array('status' => array('config' => Crm_Config::LEAD_STATES, 'property' => 'leadstate_id'), 'source' => array('config' => Crm_Config::LEAD_SOURCES, 'property' => 'leadsource_id'), 'type' => array('config' => Crm_Config::LEAD_TYPES, 'property' => 'leadtype_id')); switch ($_param['type']) { case 'status': case 'source': case 'type': $value = Crm_Config::getInstance()->get($configKeysAndProps[$_param['type']]['config'])->getTranslatedValue($_record->{$configKeysAndProps[$_param['type']]['property']}); break; case 'open_tasks': $value = 0; foreach ($_record->relations as $relation) { // check if is task and open if ($relation->type == 'TASK') { $idx = $_resolvedRecords['tasksStatus']->getIndexById($relation->related_record->status); if ($idx) { $status = $_resolvedRecords['tasksStatus'][$idx]; if ($status->is_open) { $value++; } } } } break; default: $value = ''; } return $value; }
/** * Returns instance of Tinebase_Config * * @return Tinebase_Config */ public static function getInstance() { if (self::$_instance === NULL) { self::$_instance = new self(); } return self::$_instance; }
/** * init favorites */ protected function _initializeFavorites() { $pfe = Tinebase_PersistentFilter::getInstance(); $commonValues = array('account_id' => NULL, 'application_id' => Tinebase_Application::getInstance()->getApplicationByName('Crm')->getId(), 'model' => 'Crm_Model_LeadFilter'); $closedStatus = Crm_Config::getInstance()->get(Crm_Config::LEAD_STATES)->records->filter('endslead', true)->id; $pfe->createDuringSetup(new Tinebase_Model_PersistentFilter(array_merge($commonValues, array('name' => Crm_Preference::DEFAULTPERSISTENTFILTER_NAME, 'description' => "All leads I have read grants for", 'filters' => array(array('field' => 'leadstate_id', 'operator' => 'notin', 'value' => $closedStatus)))))); $pfe->createDuringSetup(new Tinebase_Model_PersistentFilter(array_merge($commonValues, array('name' => "Last modified by me", 'description' => "All leads that I have last modified", 'filters' => array(array('field' => 'last_modified_by', 'operator' => 'equals', 'value' => Tinebase_Model_User::CURRENTACCOUNT)))))); $pfe->createDuringSetup(new Tinebase_Model_PersistentFilter(array_merge($commonValues, array('name' => "My leads", 'description' => "All leads that I am responsible for", 'filters' => array(array('field' => 'contact', 'operator' => 'AND', 'value' => array(array('field' => 'id', 'operator' => 'equals', 'value' => Addressbook_Model_Contact::CURRENTCONTACT)))))))); $pfe->createDuringSetup(new Tinebase_Model_PersistentFilter(array_merge($commonValues, array('name' => "Leads with overdue tasks", 'description' => "Leads with overdue tasks", 'filters' => array(array('field' => 'task', 'operator' => 'AND', 'value' => array(array('field' => 'due', 'operator' => 'before', 'value' => 'dayThis')))))))); }
/** * the constructor * * don't use the constructor. use the singleton */ private function __construct() { $this->_applicationName = 'Crm'; $this->_modelName = 'Crm_Model_Lead'; $this->_relatedObjectsToDelete = array('Tasks_Model_Task'); $this->_sendNotifications = TRUE; $this->_purgeRecords = FALSE; $this->_doRightChecks = TRUE; $this->_resolveCustomFields = TRUE; $this->_duplicateCheckFields = Crm_Config::getInstance()->get(Crm_Config::LEAD_DUP_FIELDS, array(array('relations', 'lead_name'))); $this->_duplicateCheckConfig = array('relations' => array('type' => 'CUSTOMER', 'filterField' => 'contact')); $this->_backend = new Crm_Backend_Lead(); }
/** * update from 2.1 -> 2.2 * - move leadstates/types/sources to config and remove tables * * @return void */ public function update_1() { $toUpdate = array('leadtype' => array('table' => 'metacrm_leadtype', 'cfgId' => Crm_Model_Config::LEADTYPES, 'fkName' => 'metacrm_lead::leadtype_id--metacrm_leadtype::id'), 'leadstate' => array('table' => 'metacrm_leadstate', 'cfgId' => Crm_Model_Config::LEADSTATES, 'fkName' => 'metacrm_lead::leadstate_id--metacrm_leadstate::id'), 'leadsource' => array('table' => 'metacrm_leadsource', 'cfgId' => Crm_Model_Config::LEADSOURCES, 'fkName' => 'metacrm_lead::leadsource_id--metacrm_leadsource::id')); foreach ($toUpdate as $config) { // get from db $select = $this->_db->select()->from(SQL_TABLE_PREFIX . $config['table']); $stmt = $this->_db->query($select); $queryResult = $stmt->fetchAll(); // save to config Crm_Config::getInstance()->set($config['cfgId'], Zend_Json::encode($queryResult)); // remove tables and constraints try { $this->_backend->dropForeignKey('metacrm_lead', $config['fkName']); } catch (Zend_Db_Statement_Exception $zdse) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' error dropping fk for ' . $config['table'] . ': ' . $zdse->__toString()); } $this->_backend->dropTable($config['table']); } $this->setTableVersion('metacrm_lead', '5'); $this->setApplicationVersion('Crm', '2.2'); }
/** * @see 0011234: automatically add task for responsible person on lead import */ public function testAutoTaskImport() { Crm_Config::getInstance()->set(Crm_Config::LEAD_IMPORT_AUTOTASK, true); $personalContainerOfSClever = $this->_getPersonalContainer('Tasks', $this->_personas['sclever']); $this->_setPersonaGrantsForTestContainer($personalContainerOfSClever->getId(), 'sclever', true, false); $result = $this->testImport(false); foreach ($result['results'] as $lead) { foreach ($lead->relations as $relation) { if ($relation->type === 'TASK') { $this->_tasksToDelete[] = $relation->related_id; } } } $translate = Tinebase_Translation::getTranslation('Crm'); $tasksFilter = new Tasks_Model_TaskFilter(array(array('field' => 'container_id', 'operator' => 'equals', 'value' => $personalContainerOfSClever->getId()), array('field' => 'summary', 'operator' => 'equals', 'value' => $translate->_('Edit new lead')))); $tasks = Tasks_Controller_Task::getInstance()->search($tasksFilter); $this->_tasksToDelete = array_merge($this->_tasksToDelete, $tasks->getArrayOfIds()); $this->assertEquals(1, count($tasks), 'could not find task in sclevers container: ' . print_r($personalContainerOfSClever->toArray(), true)); $task = $tasks->getFirstRecord(); $this->assertEquals($this->_personas['sclever']['accountId'], $task->organizer); $this->assertEquals('IN-PROCESS', $task->status); }
/** * special field value function * * @param Tinebase_Record_Abstract $_record * @param string $_fieldName * @return string */ protected function _addSpecialValue(Tinebase_Record_Abstract $_record, $_fieldName) { $keyFieldName = preg_replace('/_id/', 's', $_fieldName); return Crm_Config::getInstance()->get($keyFieldName)->getTranslatedValue($_record->{$_fieldName}); }
/** * @see 0011376: send mail on lead import to responsibles */ public function testEmailNotification() { $smtpConfig = Tinebase_Config::getInstance()->get(Tinebase_Config::SMTP, new Tinebase_Config_Struct())->toArray(); if (empty($smtpConfig)) { $this->markTestSkipped('No SMTP config found: this is needed to send notifications.'); } Crm_Config::getInstance()->set(Crm_Config::LEAD_IMPORT_NOTIFICATION, true); $this->testImport(false); // mark tasks for deletion $this->_searchTestTasks(Tinebase_Container::getInstance()->getDefaultContainer('Tasks_Model_Task')->getId(), 'task'); // assert emails for responsibles $messages = self::getMessages(); $this->assertGreaterThan(1, count($messages)); $translate = Tinebase_Translation::getTranslation('Crm'); $importNotifications = array(); $subjectToMatch = sprintf($translate->_('%s new leads have been imported'), 1); foreach ($messages as $message) { if ($message->getSubject() == $subjectToMatch) { $importNotifications[] = $message; } } $this->assertGreaterThan(1, count($importNotifications), 'expecting 2 or more mails (at least for unittest + sclever) / messages:' . print_r($messages, true)); $firstMessage = $importNotifications[0]; $this->assertContains('neuer lead 2', $firstMessage->getBodyText()->getContent(), 'lead name missing'); $this->assertContains('PHPUnit', $firstMessage->getBodyText()->getContent(), 'container name missing'); }
/** * do something after the import */ protected function _afterImport() { if (Crm_Config::getInstance()->get(Crm_Config::LEAD_IMPORT_NOTIFICATION) && !$this->_options['dryrun']) { $this->_sendNotificationToResponsibles(); } }
/** * get record array * * @param Crm_Model_Lead $_lead lead data * @param Zend_Locale $_locale the locale * @param Zend_Translate $_translate * @return array the record * */ protected function getRecord(Crm_Model_Lead $_lead, Zend_Locale $_locale, Zend_Translate $_translate) { $leadFields = array(array('label' => "", 'type' => 'separator'), array('label' => $_translate->_('Leadstate'), 'value' => array('leadstate_id')), array('label' => $_translate->_('Leadtype'), 'value' => array('leadtype_id')), array('label' => $_translate->_('Leadsource'), 'value' => array('leadsource_id')), array('label' => $_translate->_('Turnover'), 'value' => array('turnover')), array('label' => $_translate->_('Probability'), 'value' => array('probability')), array('label' => $_translate->_('Start'), 'value' => array('start')), array('label' => $_translate->_('End'), 'value' => array('end')), array('label' => $_translate->_('End Scheduled'), 'value' => array('end_scheduled'))); // add data to array $record = array(); foreach ($leadFields as $fieldArray) { if (!isset($fieldArray['type']) || $fieldArray['type'] !== 'separator') { $values = array(); foreach ($fieldArray['value'] as $valueFields) { $content = array(); if (is_array($valueFields)) { $keys = $valueFields; } else { $keys = array($valueFields); } foreach ($keys as $key) { if ($_lead->{$key} instanceof DateTime) { $content[] = Tinebase_Translation::dateToStringInTzAndLocaleFormat($_lead->{$key}, NULL, NULL, 'date'); } elseif (!empty($_lead->{$key})) { if ($key === 'turnover') { try { $content[] = Zend_Locale_Format::toNumber($_lead->{$key}, array('locale' => $_locale)) . " €"; } catch (Zend_Locale_Exception $zle) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Could not convert turnover: ' . $zle->getMessage()); $content[] = 'NaN'; } } elseif ($key === 'probability') { $content[] = $_lead->{$key} . " %"; } elseif ($key === 'leadstate_id') { $content[] = Crm_Config::getInstance()->get(Crm_Config::LEAD_STATES)->getTranslatedValue($_lead->leadstate_id); } elseif ($key === 'leadtype_id') { $content[] = Crm_Config::getInstance()->get(Crm_Config::LEAD_TYPES)->getTranslatedValue($_lead->leadtype_id); } elseif ($key === 'leadsource_id') { $content[] = Crm_Config::getInstance()->get(Crm_Config::LEAD_SOURCES)->getTranslatedValue($_lead->leadsource_id); } else { $content[] = $_lead->{$key}; } } } if (!empty($content)) { $glue = isset($fieldArray['glue']) ? $fieldArray['glue'] : " "; $values[] = implode($glue, $content); } } if (!empty($values)) { $record[] = array('label' => $fieldArray['label'], 'type' => isset($fieldArray['type']) ? $fieldArray['type'] : 'singleRow', 'value' => sizeof($values) === 1 ? $values[0] : $values); } } elseif (isset($fieldArray['type']) && $fieldArray['type'] === 'separator') { $record[] = $fieldArray; } } $record = $this->_addActivities($record, $_lead->notes); return $record; }
/** * save crm settings * * @param Crm_Model_Config $_settings * @return Crm_Model_Config * * @todo generalize this */ public function saveConfigSettings($_settings) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Updating Crm Settings: ' . print_r($_settings->toArray(), TRUE)); } foreach ($_settings->toArray() as $field => $value) { if ($field == 'id') { continue; } else { if ($field == 'defaults') { parent::saveConfigSettings($value); } else { Crm_Config::getInstance()->set($field, $value); } } } // invalidate cache Tinebase_Core::getCache()->remove('getCrmSettings'); Crm_Config::getInstance()->clearCache(); return $this->getConfigSettings(); }
/** * creates notification text and sends out notifications * * @todo: * - add changes to mail body * - find updater in addressbook to notify him * - add products? * - add notification levels * * @param Tinebase_Record_Interface $_lead * @param Tinebase_Model_FullUser $_updater * @param string $_action {created|changed} * @param Tinebase_Record_Interface $_oldLead * @param Array $_additionalData * @return void */ public function doSendNotifications(Tinebase_Record_Interface $_lead, Tinebase_Model_FullUser $_updater, $_action, Tinebase_Record_Interface $_oldLead = NULL, array $_additionalData = array()) { $sendOnOwnActions = Tinebase_Core::getPreference('Crm')->getValue(Crm_Preference::SEND_NOTIFICATION_OF_OWN_ACTIONS); if (!$sendOnOwnActions) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Sending of Lead notifications disabled by user.'); return; } $view = new Zend_View(); $view->setScriptPath(dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'views'); $translate = Tinebase_Translation::getTranslation('Crm'); $view->updater = $_updater; $view->lead = $_lead; $view->leadState = Crm_Config::getInstance()->get(Crm_Config::LEAD_STATES)->getTranslatedValue($_lead->leadstate_id); $view->leadType = Crm_Config::getInstance()->get(Crm_Config::LEAD_TYPES)->getTranslatedValue($_lead->leadtype_id); $view->leadSource = Crm_Config::getInstance()->get(Crm_Config::LEAD_SOURCES)->getTranslatedValue($_lead->leadsource_id); $view->container = Tinebase_Container::getInstance()->getContainerById($_lead->container_id); $view->tags = Tinebase_Tags::getInstance()->getTagsOfRecord($_lead); $view->updates = $this->_getNotificationUpdates($_lead, $_oldLead); if (isset($_lead->relations)) { $customer = $_lead->relations->filter('type', 'CUSTOMER')->getFirstRecord(); if ($customer) { $view->customer = $customer->related_record->n_fn; if (isset($customer->related_record->org_name)) { $view->customer .= ' (' . $customer->related_record->org_name . ')'; } } } if ($_lead->start instanceof DateTime) { $view->start = Tinebase_Translation::dateToStringInTzAndLocaleFormat($_lead->start, NULL, NULL, 'date'); } else { $view->start = '-'; } if ($_lead->end instanceof DateTime) { $view->leadEnd = Tinebase_Translation::dateToStringInTzAndLocaleFormat($_lead->end, NULL, NULL, 'date'); } else { $view->leadEnd = '-'; } if ($_lead->end_scheduled instanceof DateTime) { $view->ScheduledEnd = Tinebase_Translation::dateToStringInTzAndLocaleFormat($_lead->end_scheduled, NULL, NULL, 'date'); } else { $view->ScheduledEnd = '-'; } $view->lang_customer = $translate->_('Customer'); $view->lang_state = $translate->_('State'); $view->lang_type = $translate->_('Role'); $view->lang_source = $translate->_('Source'); $view->lang_start = $translate->_('Start'); $view->lang_scheduledEnd = $translate->_('Scheduled end'); $view->lang_end = $translate->_('End'); $view->lang_turnover = $translate->_('Turnover'); $view->lang_probability = $translate->_('Probability'); $view->lang_folder = $translate->_('Folder'); $view->lang_updatedBy = $translate->_('Updated by'); $view->lang_updatedFields = $translate->_('Updated Fields:'); $view->lang_updatedFieldMsg = $translate->_("'%s' changed from '%s' to '%s'."); $view->lang_tags = $translate->_('Tags'); $plain = $view->render('newLeadPlain.php'); $html = $view->render('newLeadHtml.php'); if ($_action == 'changed') { $subject = sprintf($translate->_('Lead %s has been changed'), $_lead->lead_name); } else { if ($_action == 'deleted') { $subject = sprintf($translate->_('Lead %s has been deleted'), $_lead->lead_name); } else { $subject = sprintf($translate->_('Lead %s has been created'), $_lead->lead_name); } } // create pdf try { $pdfGenerator = new Crm_Export_Pdf(); $pdfGenerator->generate($_lead); $attachment = array('rawdata' => $pdfGenerator->render(), 'filename' => $_lead->lead_name . '.pdf'); } catch (Zend_Pdf_Exception $e) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' error creating pdf: ' . $e->__toString()); $attachment = NULL; } $recipients = $this->_getNotificationRecipients($_lead); // send notification to updater in any case! if (!in_array($_updater->contact_id, $recipients->getArrayOfIds())) { $updaterContact = Addressbook_Controller_Contact::getInstance()->get($_updater->contact_id); $recipients->addRecord($updaterContact); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . $plain); } try { Tinebase_Notification::getInstance()->send(Tinebase_Core::getUser(), $recipients, $subject, $plain, $html, array($attachment)); } catch (Exception $e) { Tinebase_Core::getLogger()->warn(__CLASS__ . '::' . __METHOD__ . '::' . __LINE__ . ' ' . $e->getMessage()); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__CLASS__ . '::' . __METHOD__ . '::' . __LINE__ . ' ' . $e->getTraceAsString()); } } }
/** * (non-PHPdoc) * @see Tinebase_Backend_Sql_Abstract::_appendForeignSort() * * @todo generalize this: find a place (in model config?) for foreign record sorting information * @todo maybe we can use a temp table with joins here * @todo allow to to use it with keyfields, too (and/or switch those settings to keyfield configs) */ protected function _appendForeignSort(Tinebase_Model_Pagination $pagination, Zend_Db_Select $select) { $virtualSortColumns = array('leadstate_id' => Crm_Config::LEAD_STATES, 'leadsource_id' => Crm_Config::LEAD_SOURCES, 'leadtype_id' => Crm_Config::LEAD_TYPES); $col = $pagination->sort; if (isset($virtualSortColumns[$col])) { $config = Crm_Config::getInstance()->get($virtualSortColumns[$col]); // create cases (when => then) for sql switch (CASE) command $cases = array(); foreach ($config['records'] as $settingRecord) { $cases[$settingRecord['id']] = $settingRecord['value']; } $foreignSortCase = $this->_dbCommand->getSwitch($col, $cases); $select->columns(array('foreignSortCol' => $foreignSortCase)); $pagination->sort = 'foreignSortCol'; } }