Compare commits

...

18 Commits
3.7.3 ... 3.7.4

Author SHA1 Message Date
yuri
0a0f8da2f4 fix auth for 5.5 2015-10-22 10:41:07 +03:00
yuri
bb5d5a0ccf text filter default search by email address 2015-10-21 17:14:57 +03:00
yuri
1bd5eac103 ver 2015-10-21 10:09:21 +03:00
yuri
61957e628b fix optOut 2015-10-21 10:07:15 +03:00
yuri
c5296bf906 typo 2015-10-20 17:52:26 +03:00
yuri
a16919f10b fix typo 2015-10-20 17:38:04 +03:00
yuri
7050757e4e fix campaign type 2015-10-20 17:22:52 +03:00
yuri
d27e9c91e7 import: dont import if no fields 2015-10-20 15:47:42 +03:00
yuri
5e1c7bce33 leads actual filter 2015-10-20 15:38:25 +03:00
yuri
a23ac54da0 email template: translate enum 2015-10-20 15:32:01 +03:00
yuri
260c050f36 fix email address 2 2015-10-20 13:01:14 +03:00
yuri
fc5c07927f fix email address case 2015-10-20 12:57:42 +03:00
yuri
d321f0d701 email invitees duplicates 2015-10-20 12:32:50 +03:00
yuri
95cbc138f7 meeting/call/task and converted leads 2015-10-20 12:27:05 +03:00
yuri
395063ea35 order global search 2015-10-20 11:42:16 +03:00
yuri
835f95eb52 email template list layout 2015-10-20 11:29:05 +03:00
yuri
c0f6c91a0e fix email draft 2015-10-20 11:26:09 +03:00
yuri
b410d0e66f todays task 2015-10-19 17:43:32 +03:00
32 changed files with 161 additions and 50 deletions

View File

@@ -55,7 +55,10 @@ class Auth extends \Slim\Middleware
}
$espoCgiAuth = $req->headers('HTTP_ESPO_CGI_AUTH');
if ( !isset($authUsername) && !isset($authPassword) && !empty($espoCgiAuth) ) {
if (empty($espoCgiAuth)) {
$espoCgiAuth = $req->headers('REDIRECT_HTTP_ESPO_CGI_AUTH');
}
if (!isset($authUsername) && !isset($authPassword) && !empty($espoCgiAuth)) {
list($authUsername, $authPassword) = explode(':' , base64_decode(substr($espoCgiAuth, 6)));
}

View File

@@ -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));
}
}

View File

@@ -75,11 +75,8 @@ class Unsubscribe extends \Espo\Core\EntryPoints\Base
$link = $m[$target->getEntityType()];
}
if ($link) {
if ($campaign) {
$targetListList = $campaign->get('targetLists');
} else {
$targetListList = $massEmail->get('targetLists');
}
$targetListList = $massEmail->get('targetLists');
foreach ($targetListList as $targetList) {
$this->getEntityManager()->getRepository('TargetList')->updateRelation($targetList, $link, $target->id, array(
'optedOut' => true

View File

@@ -35,10 +35,17 @@ class Meeting extends \Espo\Core\ORM\Repositories\RDB
if (!empty($parentId) || !empty($parentType)) {
$parent = $this->getEntityManager()->getEntity($parentType, $parentId);
if (!empty($parent)) {
$accountId = null;
if ($parent->getEntityType() == 'Account') {
$accountId = $parent->id;
} else if ($parent->has('accountId')) {
} else if ($parent->get('accountId')) {
$accountId = $parent->get('accountId');
} else if ($parent->getEntityType() == 'Lead') {
if ($parent->get('status') == 'Converted') {
if ($parent->get('createdAccountId')) {
$accountId = $parent->get('createdAccountId');
}
}
}
if (!empty($accountId)) {
$entity->set('accountId', $accountId);

View File

@@ -98,10 +98,17 @@ class Task extends \Espo\Core\ORM\Repositories\RDB
if (!empty($parentId) || !empty($parentType)) {
$parent = $this->getEntityManager()->getEntity($parentType, $parentId);
if (!empty($parent)) {
$accountId = null;
if ($parent->getEntityType() == 'Account') {
$accountId = $parent->id;
} else if ($parent->has('accountId')) {
} else if ($parent->get('accountId')) {
$accountId = $parent->get('accountId');
} else if ($parent->getEntityType() == 'Lead') {
if ($parent->get('status') == 'Converted') {
if ($parent->get('createdAccountId')) {
$accountId = $parent->get('createdAccountId');
}
}
}
if (!empty($accountId)) {
$entity->set('accountId', $accountId);

View File

@@ -56,6 +56,7 @@
},
"presetFilters": {
"active": "Aktiv",
"actual": "Tatsächlich",
"converted": "Umgewandelt"
}
}

View File

@@ -56,6 +56,7 @@
},
"presetFilters": {
"active": "Active",
"actual": "Actual",
"converted": "Converted"
}
}

View File

@@ -50,6 +50,7 @@
}
},
"presetFilters": {
"active": "Actif"
"active": "Actif",
"actual": "En cours"
}
}

View File

@@ -45,6 +45,7 @@
}
},
"presetFilters": {
"actual": "Werkelijke",
"active": "Actief"
}
}

View File

@@ -48,6 +48,7 @@
}
},
"presetFilters": {
"actual": "Atual",
"active": "Ativo"
}
}

View File

@@ -45,6 +45,7 @@
}
},
"presetFilters": {
"active": "Активный"
"actual": "Актуальные",
"active": "Активные"
}
}

View File

@@ -30,8 +30,8 @@
"Complete": "Завершить"
},
"presetFilters": {
"actual": "Actual",
"completed": "Завершена",
"actual": "Актуальные",
"completed": "Завершенные",
"todays": "На сегодня",
"overdue": "Просроченные"
}

View File

@@ -90,7 +90,7 @@
},
"filterList": [
{
"name":"active"
"name":"actual"
},
{
"name":"converted",

View File

@@ -11,7 +11,8 @@
},
"type": {
"type": "enum",
"options": ["Email", "Newsletter", "Web", "Television", "Radio", "Mail"]
"options": ["Email", "Newsletter", "Web", "Television", "Radio", "Mail"],
"default": "Email"
},
"startDate": {
"type": "date"

View File

@@ -238,7 +238,8 @@
},
"collection": {
"sortBy": "name",
"asc": true
"asc": true,
"textFilterFields": ["name", "emailAddress"]
},
"indexes": {
"firstName": {

View File

@@ -255,7 +255,7 @@
"collection": {
"sortBy": "createdAt",
"asc": false,
"textFilterFields": ["name", "accountName"]
"textFilterFields": ["name", "accountName", "emailAddress"]
},
"indexes": {
"firstName": {

View File

@@ -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(

View File

@@ -71,6 +71,15 @@ class Task extends \Espo\Core\SelectManagers\Base
];
}
protected function filterTodays(&$result)
{
$result['whereClause'][] = $this->convertDateTimeWhere(array(
'type' => 'today',
'field' => 'dateEnd',
'timeZone' => $this->getUserTimeZone()
));
}
protected function convertDateTimeWhere($item)
{
$result = parent::convertDateTimeWhere($item);

View File

@@ -243,10 +243,10 @@ class MassEmail extends \Espo\Services\Record
$this->setFailed($massEmail);
return;
}
$attachmetList = $emailTemplate->get('attachmets');
$attachmentList = $emailTemplate->get('attachments');
foreach ($queueItemList as $queueItem) {
$this->sendQueueItem($queueItem, $massEmail, $emailTemplate, $attachmetList, $campaign, $isTest);
$this->sendQueueItem($queueItem, $massEmail, $emailTemplate, $attachmentList, $campaign, $isTest);
}
if (!$isTest) {
@@ -328,7 +328,7 @@ class MassEmail extends \Espo\Services\Record
return $email;
}
protected function sendQueueItem(Entity $queueItem, Entity $massEmail, Entity $emailTemplate, $attachmetList = [], $campaign = null, $isTest = false)
protected function sendQueueItem(Entity $queueItem, Entity $massEmail, Entity $emailTemplate, $attachmentList = [], $campaign = null, $isTest = false)
{
$target = $this->getEntityManager()->getEntity($queueItem->get('targetType'), $queueItem->get('targetId'));
if (!$target || !$target->id || !$target->get('emailAddress')) {
@@ -379,7 +379,7 @@ class MassEmail extends \Espo\Services\Record
$header->setId($queueItem->id);
$message->getHeaders()->addHeader($header);
$this->getMailSender()->useGlobal()->send($email, $params, $message, $attachmetList);
$this->getMailSender()->useGlobal()->send($email, $params, $message, $attachmentList);
$emailObject = $emailTemplate;
if ($massEmail->get('storeSentEmails')) {

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -1,3 +1,4 @@
[
{"name": "name", "width": 90, "link": true}
{"name": "name", "link": true},
{"name": "assignedUser", "width": 20}
]

View File

@@ -0,0 +1,4 @@
[
{"name": "name", "link": true},
{"name": "assignedUser", "width": 30}
]

View File

@@ -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);
}

View File

@@ -95,7 +95,15 @@ class GlobalSearch extends \Espo\Core\Services\Base
$row = $sth->fetch(\PDO::FETCH_ASSOC);
$totalCount = $row['COUNT'];
$unionSql .= " ORDER BY name";
if (count($entityTypeList)) {
$entityListQuoted = [];
foreach ($entityTypeList as $entityType) {
$entityListQuoted[] = $pdo->quote($entityType);
}
$unionSql .= " ORDER BY FIELD(entityType, ".implode(', ', $entityListQuoted)."), name";
} else {
$unionSql .= " ORDER BY name";
}
$unionSql .= " LIMIT :offset, :maxSize";
$sth = $pdo->prepare($unionSql);

View File

@@ -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'];

View File

@@ -56,7 +56,7 @@ Espo.define('Crm:Views.Dashlets.Leads', 'Views.Dashlets.Abstract.RecordList', fu
bool: {
onlyMy: true,
},
primary: 'active'
primary: 'actual'
},
},

View File

@@ -29,7 +29,7 @@ Espo.define('crm:views/mass-email/record/row-actions/for-campaign', 'views/recor
if (this.options.acl.edit && !~['Complete'].indexOf(this.model.get('status'))) {
actionList.unshift({
action: 'sendTest',
label: 'Sent Test',
label: 'Send Test',
data: {
id: this.model.id
}

View File

@@ -255,6 +255,19 @@ Espo.define('views/email/detail', ['views/detail', 'email-helper'], function (De
this.model.set('status', 'Sent');
$send.remove();
this.menu = this.backedMenu;
if (record.mode !== 'detail') {
record.setDetailMode();
record.setFieldReadOnly('dateSent');
record.setFieldReadOnly('name');
record.setFieldReadOnly('attachments');
record.setFieldReadOnly('isHtml');
record.setFieldReadOnly('from');
record.setFieldReadOnly('to');
record.setFieldReadOnly('cc');
record.setFieldReadOnly('bcc');
}
}, this);
this.listenToOnce(record, 'cancel:save', function () {

View File

@@ -161,6 +161,10 @@ Espo.define('views/email/record/detail', 'views/record/detail', function (Dep) {
afterRender: function () {
Dep.prototype.afterRender.call(this);
if (this.model.get('status') === 'Draft') {
this.setFieldReadOnly('dateSent');
}
if (this.isRestricted) {
this.handleAttachmentField();
this.listenTo(this.model, 'change:attachmentsIds', function () {

View File

@@ -55,6 +55,10 @@ Espo.define('views/email/record/edit', ['views/record/edit', 'views/email/record
afterRender: function () {
Dep.prototype.afterRender.call(this);
if (this.model.get('status') === 'Draft') {
this.setFieldReadOnly('dateSent');
}
this.handleAttachmentField();
this.listenTo(this.model, 'change:attachmentsIds', function () {
this.handleAttachmentField();

View File

@@ -1,6 +1,6 @@
{
"name": "espocrm",
"version": "3.7.3",
"version": "3.7.4",
"description": "",
"main": "index.php",
"repository": {