diff --git a/application/Espo/Entities/EmailAddress.php b/application/Espo/Entities/EmailAddress.php index 261cbe4a83..2ebed5330a 100644 --- a/application/Espo/Entities/EmailAddress.php +++ b/application/Espo/Entities/EmailAddress.php @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU General Public License * along with EspoCRM. If not, see http://www.gnu.org/licenses/. - ************************************************************************/ + ************************************************************************/ namespace Espo\Entities; @@ -33,7 +33,6 @@ class EmailAddress extends \Espo\Core\ORM\Entity throw new Error("Not valid email address '{$value}'"); } $this->valuesContainer['name'] = $value; - $this->set('lower', strtolower($value)); - } - + $this->set('lower', strtolower($value)); + } } diff --git a/application/Espo/Modules/Crm/Resources/i18n/de_DE/Lead.json b/application/Espo/Modules/Crm/Resources/i18n/de_DE/Lead.json index 556aefc303..930f6fe148 100644 --- a/application/Espo/Modules/Crm/Resources/i18n/de_DE/Lead.json +++ b/application/Espo/Modules/Crm/Resources/i18n/de_DE/Lead.json @@ -56,6 +56,7 @@ }, "presetFilters": { "active": "Aktiv", + "actual": "Tatsächlich", "converted": "Umgewandelt" } } diff --git a/application/Espo/Modules/Crm/Resources/i18n/en_US/Lead.json b/application/Espo/Modules/Crm/Resources/i18n/en_US/Lead.json index d522bbb363..94f6b6e22a 100644 --- a/application/Espo/Modules/Crm/Resources/i18n/en_US/Lead.json +++ b/application/Espo/Modules/Crm/Resources/i18n/en_US/Lead.json @@ -56,6 +56,7 @@ }, "presetFilters": { "active": "Active", + "actual": "Actual", "converted": "Converted" } } diff --git a/application/Espo/Modules/Crm/Resources/i18n/fr_FR/Lead.json b/application/Espo/Modules/Crm/Resources/i18n/fr_FR/Lead.json index 46d25df8eb..c50a9f02fc 100644 --- a/application/Espo/Modules/Crm/Resources/i18n/fr_FR/Lead.json +++ b/application/Espo/Modules/Crm/Resources/i18n/fr_FR/Lead.json @@ -50,6 +50,7 @@ } }, "presetFilters": { - "active": "Actif" + "active": "Actif", + "actual": "En cours" } } diff --git a/application/Espo/Modules/Crm/Resources/i18n/nl_NL/Lead.json b/application/Espo/Modules/Crm/Resources/i18n/nl_NL/Lead.json index 589c00cbde..c8d24af157 100644 --- a/application/Espo/Modules/Crm/Resources/i18n/nl_NL/Lead.json +++ b/application/Espo/Modules/Crm/Resources/i18n/nl_NL/Lead.json @@ -56,6 +56,7 @@ }, "presetFilters": { "active": "Actief", - "converted": "Geconverteerd" + "converted": "Geconverteerd", + "actual": "Werkelijke" } } diff --git a/application/Espo/Modules/Crm/Resources/i18n/pt_BR/Lead.json b/application/Espo/Modules/Crm/Resources/i18n/pt_BR/Lead.json index 4c327167f7..b692802c81 100644 --- a/application/Espo/Modules/Crm/Resources/i18n/pt_BR/Lead.json +++ b/application/Espo/Modules/Crm/Resources/i18n/pt_BR/Lead.json @@ -48,6 +48,7 @@ } }, "presetFilters": { + "actual": "Atual", "active": "Ativo" } } diff --git a/application/Espo/Modules/Crm/Resources/i18n/ru_RU/Lead.json b/application/Espo/Modules/Crm/Resources/i18n/ru_RU/Lead.json index 2346ef6b7b..0b551cdb09 100644 --- a/application/Espo/Modules/Crm/Resources/i18n/ru_RU/Lead.json +++ b/application/Espo/Modules/Crm/Resources/i18n/ru_RU/Lead.json @@ -45,6 +45,7 @@ } }, "presetFilters": { - "active": "Активный" + "actual": "Актуальные", + "active": "Активные" } } diff --git a/application/Espo/Modules/Crm/Resources/i18n/ru_RU/Task.json b/application/Espo/Modules/Crm/Resources/i18n/ru_RU/Task.json index 5cc7ab6809..99f4cd7774 100644 --- a/application/Espo/Modules/Crm/Resources/i18n/ru_RU/Task.json +++ b/application/Espo/Modules/Crm/Resources/i18n/ru_RU/Task.json @@ -30,8 +30,8 @@ "Complete": "Завершить" }, "presetFilters": { - "actual": "Actual", - "completed": "Завершена", + "actual": "Актуальные", + "completed": "Завершенные", "todays": "На сегодня", "overdue": "Просроченные" } diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Lead.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Lead.json index b4f7324813..b966230de3 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Lead.json +++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Lead.json @@ -90,7 +90,7 @@ }, "filterList": [ { - "name":"active" + "name":"actual" }, { "name":"converted", diff --git a/application/Espo/Modules/Crm/SelectManagers/Lead.php b/application/Espo/Modules/Crm/SelectManagers/Lead.php index d35b9e05e5..bb0243854c 100644 --- a/application/Espo/Modules/Crm/SelectManagers/Lead.php +++ b/application/Espo/Modules/Crm/SelectManagers/Lead.php @@ -31,6 +31,13 @@ class Lead extends \Espo\Core\SelectManagers\Base ); } + protected function filterActual(&$result) + { + $result['whereClause'][] = array( + 'status!=' => ['Converted', 'Recycled', 'Dead'] + ); + } + protected function filterConverted(&$result) { $result['whereClause'][] = array( diff --git a/application/Espo/Modules/Crm/Services/Meeting.php b/application/Espo/Modules/Crm/Services/Meeting.php index 35bad77f99..b41d29af64 100644 --- a/application/Espo/Modules/Crm/Services/Meeting.php +++ b/application/Espo/Modules/Crm/Services/Meeting.php @@ -81,19 +81,30 @@ class Meeting extends \Espo\Services\Record { $invitationManager = $this->getInvitationManager(); + $emailHash = array(); + $users = $entity->get('users'); foreach ($users as $user) { - $invitationManager->sendInvitation($entity, $user, 'users'); + if ($user->get('emailAddress') && !array_key_exists($user->get('emailAddress'), $emailHash)) { + $invitationManager->sendInvitation($entity, $user, 'users'); + $emailHash[$user->get('emailAddress')] = true; + } } $contacts = $entity->get('contacts'); foreach ($contacts as $contact) { - $invitationManager->sendInvitation($entity, $contact, 'contacts'); + if ($contact->get('emailAddress') && !array_key_exists($contact->get('emailAddress'), $emailHash)) { + $invitationManager->sendInvitation($entity, $contact, 'contacts'); + $emailHash[$user->get('emailAddress')] = true; + } } $leads = $entity->get('leads'); foreach ($leads as $lead) { - $invitationManager->sendInvitation($entity, $lead, 'leads'); + if ($lead->get('emailAddress') && !array_key_exists($lead->get('emailAddress'), $emailHash)) { + $invitationManager->sendInvitation($entity, $lead, 'leads'); + $emailHash[$user->get('emailAddress')] = true; + } } return true; diff --git a/application/Espo/Repositories/EmailAddress.php b/application/Espo/Repositories/EmailAddress.php index 3669ec0bba..3af843786a 100644 --- a/application/Espo/Repositories/EmailAddress.php +++ b/application/Espo/Repositories/EmailAddress.php @@ -65,7 +65,7 @@ class EmailAddress extends \Espo\Core\ORM\Repositories\RDB $pdo = $this->getEntityManager()->getPDO(); $sql = " - SELECT email_address.name, email_address.invalid, email_address.opt_out AS optOut, entity_email_address.primary + SELECT email_address.name, email_address.lower, email_address.invalid, email_address.opt_out AS optOut, entity_email_address.primary FROM entity_email_address JOIN email_address ON email_address.id = entity_email_address.email_address_id AND email_address.deleted = 0 WHERE @@ -80,6 +80,7 @@ class EmailAddress extends \Espo\Core\ORM\Repositories\RDB foreach ($rows as $row) { $obj = new \StdClass(); $obj->emailAddress = $row['name']; + $obj->lower = $row['lower']; $obj->primary = ($row['primary'] == '1') ? true : false; $obj->optOut = ($row['optOut'] == '1') ? true : false; $obj->invalid = ($row['invalid'] == '1') ? true : false; @@ -180,22 +181,25 @@ class EmailAddress extends \Espo\Core\ORM\Repositories\RDB foreach ($emailAddressData as $row) { $key = $row->emailAddress; if (!empty($key)) { + $key = strtolower($key); $hash[$key] = array( 'primary' => $row->primary ? true : false, 'optOut' => $row->optOut ? true : false, 'invalid' => $row->invalid ? true : false, + 'emailAddress' => $row->emailAddress ); } } $hashPrev = array(); foreach ($previousEmailAddressData as $row) { - $key = $row->emailAddress; + $key = $row->lower; if (!empty($key)) { $hashPrev[$key] = array( 'primary' => $row->primary ? true : false, 'optOut' => $row->optOut ? true : false, 'invalid' => $row->invalid ? true : false, + 'emailAddress' => $row->emailAddress ); } } @@ -216,7 +220,10 @@ class EmailAddress extends \Espo\Core\ORM\Repositories\RDB if (array_key_exists($key, $hashPrev)) { $new = false; - $changed = $hash[$key]['optOut'] != $hashPrev[$key]['optOut'] || $hash[$key]['invalid'] != $hashPrev[$key]['invalid']; + $changed = + $hash[$key]['optOut'] != $hashPrev[$key]['optOut'] || + $hash[$key]['invalid'] != $hashPrev[$key]['invalid'] || + $hash[$key]['emailAddress'] !== $hashPrev[$key]['emailAddress']; if ($hash[$key]['primary']) { if ($hash[$key]['primary'] == $hashPrev[$key]['primary']) { $primary = false; @@ -259,6 +266,7 @@ class EmailAddress extends \Espo\Core\ORM\Repositories\RDB $emailAddress->set(array( 'optOut' => $hash[$address]['optOut'], 'invalid' => $hash[$address]['invalid'], + 'name' => $hash[$address]['emailAddress'] )); $this->save($emailAddress); } @@ -270,16 +278,21 @@ class EmailAddress extends \Espo\Core\ORM\Repositories\RDB $emailAddress = $this->get(); $emailAddress->set(array( - 'name' => $address, + 'name' => $hash[$address]['emailAddress'], 'optOut' => $hash[$address]['optOut'], 'invalid' => $hash[$address]['invalid'], )); $this->save($emailAddress); } else { - if ($emailAddress->get('optOut') != $hash[$address]['optOut'] || $emailAddress->get('invalid') != $hash[$address]['invalid']) { + if ( + $emailAddress->get('optOut') != $hash[$address]['optOut'] || + $emailAddress->get('invalid') != $hash[$address]['invalid'] || + $emailAddress->get('emailAddress') != $hash[$address]['emailAddress'] + ) { $emailAddress->set(array( 'optOut' => $hash[$address]['optOut'], 'invalid' => $hash[$address]['invalid'], + 'name' => $hash[$address]['emailAddress'] )); $this->save($emailAddress); } diff --git a/application/Espo/Services/EmailTemplate.php b/application/Espo/Services/EmailTemplate.php index 02c692b0f1..43df24fadf 100644 --- a/application/Espo/Services/EmailTemplate.php +++ b/application/Espo/Services/EmailTemplate.php @@ -36,6 +36,7 @@ class EmailTemplate extends Record { $this->dependencies[] = 'fileManager'; $this->dependencies[] = 'dateTime'; + $this->dependencies[] = 'language'; } protected function getFileManager() @@ -48,6 +49,11 @@ class EmailTemplate extends Record return $this->injections['dateTime']; } + protected function getLanguage() + { + return $this->getInjection('language'); + } + public function parseTemplate(Entity $emailTemplate, array $params = array(), $copyAttachments = false) { $entityHash = array(); @@ -160,10 +166,16 @@ class EmailTemplate extends Record continue; } - if ($entity->fields[$field]['type'] == 'date') { - $value = $this->getDateTime()->convertSystemDateToGlobal($value); - } else if ($entity->fields[$field]['type'] == 'datetime') { - $value = $this->getDateTime()->convertSystemDateTimeToGlobal($value); + $fieldType = $this->getMetadata()->get('entityDefs.' . $entity->getEntityType() .'.fields.' . $field . '.type'); + + if ($fieldType === 'enum') { + $value = $this->getLanguage()->translateOption($value, $field, $entity->getEntityType()); + } else { + if ($entity->fields[$field]['type'] == 'date') { + $value = $this->getDateTime()->convertSystemDateToGlobal($value); + } else if ($entity->fields[$field]['type'] == 'datetime') { + $value = $this->getDateTime()->convertSystemDateTimeToGlobal($value); + } } $text = str_replace('{' . $type . '.' . $field . '}', $value, $text); } diff --git a/application/Espo/Services/Import.php b/application/Espo/Services/Import.php index 565e5b5976..239216dfd6 100644 --- a/application/Espo/Services/Import.php +++ b/application/Espo/Services/Import.php @@ -257,7 +257,7 @@ class Import extends \Espo\Services\Record return true; } - public function import($scope, array $fields, $attachmentId, array $params = array()) + public function import($scope, array $importFieldList, $attachmentId, array $params = array()) { $delimiter = ','; if (!empty($params['fieldDelimiter'])) { @@ -297,7 +297,7 @@ class Import extends \Espo\Services\Record if (count($arr) == 1 && empty($arr[0])) { continue; } - $r = $this->importRow($scope, $fields, $arr, $params); + $r = $this->importRow($scope, $importFieldList, $arr, $params); if (empty($r)) { continue; } @@ -334,7 +334,7 @@ class Import extends \Espo\Services\Record ); } - public function importRow($scope, array $fields, array $row, array $params = array()) + public function importRow($scope, array $importFieldList, array $row, array $params = array()) { $id = null; $action = 'create'; @@ -342,15 +342,19 @@ class Import extends \Espo\Services\Record $action = $params['action']; } + if (empty($importFieldList)) { + return; + } + if (in_array($action, ['createAndUpdate', 'update'])) { if (!empty($params['updateBy']) && is_array($params['updateBy'])) { $updateByFieldList = []; $whereClause = array(); foreach ($params['updateBy'] as $i) { - if (array_key_exists($i, $fields)) { - $updateByFieldList[] = $fields[$i]; - $whereClause[$fields[$i]] = $row[$i]; + if (array_key_exists($i, $importFieldList)) { + $updateByFieldList[] = $importFieldList[$i]; + $whereClause[$importFieldList[$i]] = $row[$i]; } } } @@ -399,7 +403,7 @@ class Import extends \Espo\Services\Record } } - foreach ($fields as $i => $field) { + foreach ($importFieldList as $i => $field) { if (!empty($field)) { $value = $row[$i]; if ($field == 'id') { @@ -457,7 +461,7 @@ class Import extends \Espo\Services\Record $isPrimary = false; if (empty($phoneNumberData)) { $phoneNumberData = []; - if (!in_array('phoneNumber', $fields)) { + if (!in_array('phoneNumber', $importFieldList)) { $isPrimary = true; } } @@ -475,7 +479,7 @@ class Import extends \Espo\Services\Record } } - foreach ($fields as $i => $field) { + foreach ($importFieldList as $i => $field) { if (array_key_exists($field, $fieldsDefs) && $fieldsDefs[$field]['type'] == Entity::FOREIGN) { if ($entity->has($field)) { $relation = $fieldsDefs[$field]['relation']; diff --git a/frontend/client/modules/crm/src/views/dashlets/leads.js b/frontend/client/modules/crm/src/views/dashlets/leads.js index 7b56ad7f9d..fa85764ae9 100644 --- a/frontend/client/modules/crm/src/views/dashlets/leads.js +++ b/frontend/client/modules/crm/src/views/dashlets/leads.js @@ -56,7 +56,7 @@ Espo.define('Crm:Views.Dashlets.Leads', 'Views.Dashlets.Abstract.RecordList', fu bool: { onlyMy: true, }, - primary: 'active' + primary: 'actual' }, },