Compare commits

...

71 Commits

Author SHA1 Message Date
yuri 7b098095cb v 4.0.5 2016-05-04 16:18:36 +03:00
yuri 7966be90e7 fix acl 2016-05-04 16:18:12 +03:00
yuri e76116810f fix calendar weekStart 2016-04-11 11:36:01 +03:00
yuri bb379c7a0e fix invitation 2016-04-08 10:30:00 +03:00
yuri 265ec60614 remove empty side panel box 2016-04-07 12:51:22 +03:00
yuri d79d716612 download file name escape 2016-04-07 12:51:09 +03:00
yuri aa61f322bc fix email attachment filename parsing 2016-04-07 12:50:42 +03:00
yuri c8d2f08c13 fix naming 2016-04-07 10:41:36 +03:00
yuri ce0efed7b8 fix calendar 2016-04-05 11:23:32 +03:00
yuri 18f13acfa9 assigner user field: dont display avatar in list view 2016-04-04 16:10:06 +03:00
yuri a15b247952 fix lang 2016-04-01 16:34:00 +03:00
yuri 2e457e1f6f fix entity manager link conflicts 2016-04-01 16:30:53 +03:00
yuri e0375a52f9 fix relationship manager ui 2016-04-01 16:30:38 +03:00
yuri 351a70015a fix email address and phone number duplicates 2016-04-01 12:27:52 +03:00
yuri 8faa001a56 use teams view 2016-04-01 11:34:48 +03:00
yuri 49b581dafd assigned user view 2016-04-01 11:16:25 +03:00
yuri 1319c54365 fix assignment permission no 2016-04-01 11:12:33 +03:00
yuri 1054050542 fix list modal 2 2016-03-31 11:27:12 +03:00
yuri 08b5f09c55 fix list modal 2016-03-31 11:21:46 +03:00
yuri 23a0ed86e0 cleanup 2016-03-31 10:34:50 +03:00
yuri 0ca7da454b fix notice 2016-03-31 10:33:16 +03:00
yuri 1faa75c303 add email to quick create list 2016-03-30 12:30:01 +03:00
yuri 8136eed152 orm improvements 2016-03-30 12:29:07 +03:00
yuri 13dc6f0d76 email quick create 2016-03-30 11:19:46 +03:00
yuri d3bcadce13 fix contact filter is empty account 2016-03-30 10:36:06 +03:00
yuri ebe7834092 error message if restore password with empty smtp 2016-03-28 15:34:34 +03:00
yuri 9c8f54fd24 fix send test email button 2016-03-28 15:34:01 +03:00
yuri f47915d077 fix list 2016-03-25 15:20:19 +02:00
yuri eb2305712a user smtp info 2016-03-25 12:30:10 +02:00
yuri f75414a5d2 fix intaller 2016-03-25 12:30:02 +02:00
yuri a88cb05897 fix installer 2016-03-25 11:55:30 +02:00
yuri 2435ae67c9 v 2016-03-25 11:51:02 +02:00
yuri 4c49be5203 installer fix 2016-03-25 11:50:58 +02:00
yuri 2d8a1dad80 fix installer 2016-03-25 05:30:16 -04:00
yuri a15b009133 user filters 2016-03-25 05:11:11 -04:00
yuri 25d2033b7c user select default filter active 2016-03-25 05:08:08 -04:00
yuri c509eeae49 fix notices 2016-03-25 05:01:05 -04:00
yuri 2a4b0dbcb4 remove task dublicate index 2016-03-25 04:56:47 -04:00
yuri e45a863e8d fix invitation 2016-03-24 11:27:53 +02:00
yuri c4819e29e0 fix inv email date time 2016-03-23 17:01:00 +02:00
yuri c0242a18e3 fix invitation email and email template 2016-03-23 16:57:18 +02:00
yuri 7a953c9a47 use word-break for long field 2016-03-23 16:09:07 +02:00
yuri 27cc0d812e url field title 2016-03-23 16:06:45 +02:00
yuri 7a433c1890 fix list remove 2016-03-23 13:03:44 +02:00
yuri de26d87400 list title 2016-03-23 12:02:03 +02:00
yuri 07da707503 Record controller fix sort 2016-03-23 11:40:24 +02:00
yuri b473b19b45 fix opportunity dashlet acl 2016-03-22 16:19:44 +02:00
yuri 6c291999f4 keep meeting duration if rescheduled 2016-03-22 13:07:14 +02:00
yuri 2e92d0d3a5 case email compose fix 2016-03-22 12:03:21 +02:00
yuri bc3dfc7ff9 fix warnings 2016-03-18 16:05:41 +02:00
yuri e81d5707f2 fix warnings 2016-03-18 15:26:04 +02:00
yuri 1d2e3aff89 fix job rep 2016-03-18 14:47:21 +02:00
yuri e36c8d6053 change year 2016-03-18 11:25:45 +02:00
yuri 4ea1d50caf fix detail getFieldViews 2016-03-18 11:19:14 +02:00
yuri 865a8e2abc fix E_STRICT notices 2016-03-16 17:34:50 +02:00
yuri 5783f4e708 fix autoincrement 2016-03-16 12:48:44 +02:00
yuri 557a48ec6a isDraggable 2016-03-15 16:01:43 +02:00
yuri d5fa18975e try catch for send password 2016-03-14 16:54:35 +02:00
yuri 23ee06e123 hide panels and buttons from portal user 2016-03-14 16:50:44 +02:00
yuri e47eab0ce7 fix select manager 2016-03-14 15:52:06 +02:00
yuri 17ae5b6b5a fix file permissions 2016-03-14 15:51:58 +02:00
yuri fa29bf3309 v 2016-03-14 11:43:24 +02:00
yuri 684585278d fix email import 2016-03-11 12:02:21 +02:00
yuri e303be8155 fix german salutations 2016-03-10 15:17:40 +02:00
yuri f1285f0615 fix default side panel tpl 2016-03-10 12:46:21 +02:00
yuri 3fd1974d86 fix build permissions 2016-03-09 15:57:13 +02:00
yuri d48716e65a account: text search by email address 2016-03-09 11:20:57 +02:00
yuri a0432051f4 fix lead service 2016-03-09 11:03:56 +02:00
yuri 076c3aa65b trim search 2016-03-09 10:44:32 +02:00
yuri 92abd16032 remove notification if record removed 2016-03-04 12:40:30 +02:00
yuri e6632066a6 aclPortal case: default status readOnly 2016-03-04 12:28:43 +02:00
122 changed files with 726 additions and 290 deletions
+3
View File
@@ -214,8 +214,11 @@ module.exports = function (grunt) {
},
src: [
'build/EspoCRM-<%= pkg.version %>/install',
'build/EspoCRM-<%= pkg.version %>/portal',
'build/EspoCRM-<%= pkg.version %>/api',
'build/EspoCRM-<%= pkg.version %>/api/v1',
'build/EspoCRM-<%= pkg.version %>/api/v1/portal-access',
'build/EspoCRM-<%= pkg.version %>',
]
}
},
+5 -5
View File
@@ -41,17 +41,17 @@ class Job extends \Espo\Core\Controllers\Record
}
}
public function actionCreate($params, $data)
public function actionCreate($params, $data, $request)
{
throw new Forbidden();
}
public function actionUpdate($params, $data)
public function actionUpdate($params, $data, $request)
{
throw new Forbidden();
}
public function actionPatch($params, $data)
public function actionPatch($params, $data, $request)
{
throw new Forbidden();
}
@@ -66,12 +66,12 @@ class Job extends \Espo\Core\Controllers\Record
throw new Forbidden();
}
public function actionCreateLink($params, $data)
public function actionCreateLink($params, $data, $request)
{
throw new Forbidden();
}
public function actionRemoveLink($params, $data)
public function actionRemoveLink($params, $data, $request)
{
throw new Forbidden();
}
@@ -37,9 +37,6 @@ class Notification extends \Espo\Core\Controllers\Record
public function actionList($params, $data, $request)
{
$scope = $params['scope'];
$id = $params['id'];
$userId = $this->getUser()->id;
$offset = intval($request->get('offset'));
+2 -3
View File
@@ -128,7 +128,7 @@ class Record extends Base
$where = $request->get('where');
$offset = $request->get('offset');
$maxSize = $request->get('maxSize');
$asc = $request->get('asc') === 'true';
$asc = $request->get('asc', 'true') === 'true';
$sortBy = $request->get('sortBy');
$q = $request->get('q');
$primaryFilter = $request->get('primaryFilter');
@@ -174,7 +174,7 @@ class Record extends Base
$where = $request->get('where');
$offset = $request->get('offset');
$maxSize = $request->get('maxSize');
$asc = $request->get('asc') === 'true';
$asc = $request->get('asc', 'true') === 'true';
$sortBy = $request->get('sortBy');
$q = $request->get('q');
$textFilter = $request->get('textFilter');
@@ -292,7 +292,6 @@ class Record extends Base
$params['where'] = $where;
}
if (array_key_exists('ids', $data)) {
$where = json_decode(json_encode($data['where']), true);
$params['ids'] = $data['ids'];
}
+20 -5
View File
@@ -456,22 +456,37 @@ class Importer
protected function fetchFileNameFromContentDisposition($contentDisposition)
{
$contentDisposition = preg_replace('/\\\\"/', "{{_!Q!U!O!T!E!_}}", $contentDisposition);
$fileName = false;
$m = array();
if (preg_match('/filename="?([^"]+)"?/i', $contentDisposition, $m)) {
$asterisk = false;
if (preg_match('/filename="([^"]+)";?/i', $contentDisposition, $m)) {
$fileName = $m[1];
return $fileName;
} else if (preg_match('/filename\*="?([^"]+)"?/i', $contentDisposition, $m)) {
} else if (preg_match('/filename=([^";]+);?/i', $contentDisposition, $m)) {
$fileName = $m[1];
} else if (preg_match('/filename\*[01]?="([^"]+)";?/i', $contentDisposition, $m)) {
$fileName = $m[1];
$asterisk = true;
} else if (preg_match('/filename\*[01]?=([^";]+);?/i', $contentDisposition, $m)) {
$fileName = $m[1];
$asterisk = true;
}
if ($asterisk) {
if ($fileName && stripos($fileName, "''") !== false) {
list($encoding, $fileName) = explode("''", $fileName);
$fileName = rawurldecode($fileName);
if (strtoupper($encoding) !== 'UTF-8') {
$fileName = mb_convert_encoding($fileName, 'UTF-8', $encoding);
}
return $fileName;
}
}
return false;
$fileName = str_replace('{{_!Q!U!O!T!E!_}}', '"', $fileName);
return $fileName;
}
protected function getContentFromPart($part)
@@ -29,11 +29,11 @@
namespace Espo\Core\Repositories;
use \Espo\Core\Entities\CategoryTreeItem as Entity;
use \Espo\ORM\Entity;
class CategoryTree extends \Espo\Core\ORM\Repositories\RDB
{
public function afterSave(Entity $entity, $options)
protected function afterSave(Entity $entity, array $options = array())
{
parent::afterSave($entity, $options);
@@ -86,7 +86,7 @@ class CategoryTree extends \Espo\Core\ORM\Repositories\RDB
}
}
public function afterRemove(Entity $entity, $options)
protected function afterRemove(Entity $entity, array $options = array())
{
parent::afterRemove($entity, $options);
@@ -1069,7 +1069,7 @@ class Base
public function hasLeftJoin($leftJoin, &$result)
{
return in_array($leftJoin, $result['leftJoin']);
return in_array($leftJoin, $result['leftJoins']);
}
public function addJoin($join, &$result)
@@ -29,10 +29,11 @@
"assignedUser": {
"type": "link",
"required": true,
"view": "views/fields/user"
"view": "views/fields/assigned-user"
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
}
},
"links": {
@@ -70,10 +70,11 @@
"assignedUser": {
"type": "link",
"required": false,
"view": "views/fields/user"
"view": "views/fields/assigned-user"
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
}
},
"links": {
@@ -66,7 +66,9 @@ class Currency extends Base
"<" => Util::toUnderScore($entityName) . "." . $currencyColumnName . " * {$alias}.rate < {value}",
">=" => Util::toUnderScore($entityName) . "." . $currencyColumnName . " * {$alias}.rate >= {value}",
"<=" => Util::toUnderScore($entityName) . "." . $currencyColumnName . " * {$alias}.rate <= {value}",
"<>" => Util::toUnderScore($entityName) . "." . $currencyColumnName . " * {$alias}.rate <> {value}"
"<>" => Util::toUnderScore($entityName) . "." . $currencyColumnName . " * {$alias}.rate <> {value}",
"IS NULL" => Util::toUnderScore($entityName) . "." . $currencyColumnName . ' IS NULL',
"IS NOT NULL" => Util::toUnderScore($entityName) . "." . $currencyColumnName . ' IS NOT NULL',
),
'notStorable' => true,
'orderBy' => $converedFieldName . " {direction}"
@@ -40,30 +40,41 @@ class Email extends Base
'select' => 'emailAddresses.name',
'where' =>
array (
'LIKE' => \Espo\Core\Utils\Util::toUnderScore($entityName) . ".id IN (
SELECT entity_id
FROM entity_email_address
JOIN email_address ON email_address.id = entity_email_address.email_address_id
WHERE
entity_email_address.deleted = 0 AND entity_email_address.entity_type = '{$entityName}' AND
email_address.deleted = 0 AND email_address.name LIKE {value}
)",
'=' => \Espo\Core\Utils\Util::toUnderScore($entityName) . ".id IN (
SELECT entity_id
FROM entity_email_address
JOIN email_address ON email_address.id = entity_email_address.email_address_id
WHERE
entity_email_address.deleted = 0 AND entity_email_address.entity_type = '{$entityName}' AND
email_address.deleted = 0 AND email_address.name = {value}
)",
'<>' => \Espo\Core\Utils\Util::toUnderScore($entityName) . ".id IN (
SELECT entity_id
FROM entity_email_address
JOIN email_address ON email_address.id = entity_email_address.email_address_id
WHERE
entity_email_address.deleted = 0 AND entity_email_address.entity_type = '{$entityName}' AND
email_address.deleted = 0 AND email_address.name <> {value}
)"
'LIKE' => array(
'leftJoins' => [['emailAddresses', 'emailAddressesMultiple']],
'sql' => 'emailAddressesMultiple.name LIKE {value}',
'distinct' => true
),
'=' => array(
'leftJoins' => [['emailAddresses', 'emailAddressesMultiple']],
'sql' => 'emailAddressesMultiple.name = {value}',
'distinct' => true
),
'<>' => array(
'leftJoins' => [['emailAddresses', 'emailAddressesMultiple']],
'sql' => 'emailAddressesMultiple.name <> {value}',
'distinct' => true
),
'IN' => array(
'leftJoins' => [['emailAddresses', 'emailAddressesMultiple']],
'sql' => 'emailAddressesMultiple.name IN {value}',
'distinct' => true
),
'NOT IN' => array(
'leftJoins' => [['emailAddresses', 'emailAddressesMultiple']],
'sql' => 'emailAddressesMultiple.name NOT IN {value}',
'distinct' => true
),
'IS NULL' => array(
'leftJoins' => [['emailAddresses', 'emailAddressesMultiple']],
'sql' => 'emailAddressesMultiple.name IS NULL',
'distinct' => true
),
'IS NOT NULL' => array(
'leftJoins' => [['emailAddresses', 'emailAddressesMultiple']],
'sql' => 'emailAddressesMultiple.name IS NOT NULL',
'distinct' => true
)
),
'orderBy' => 'emailAddresses.name {direction}',
),
@@ -73,7 +84,7 @@ class Email extends Base
),
),
'relations' => array(
$fieldName.'es' => array(
'emailAddresses' => array(
'type' => 'manyMany',
'entity' => 'EmailAddress',
'relationName' => 'entityEmailAddress',
@@ -40,30 +40,41 @@ class Phone extends Base
'select' => 'phoneNumbers.name',
'where' =>
array (
'LIKE' => \Espo\Core\Utils\Util::toUnderScore($entityName) . ".id IN (
SELECT entity_id
FROM entity_phone_number
JOIN phone_number ON phone_number.id = entity_phone_number.phone_number_id
WHERE
entity_phone_number.deleted = 0 AND entity_phone_number.entity_type = '{$entityName}' AND
phone_number.deleted = 0 AND phone_number.name LIKE {value}
)",
'=' => \Espo\Core\Utils\Util::toUnderScore($entityName) . ".id IN (
SELECT entity_id
FROM entity_phone_number
JOIN phone_number ON phone_number.id = entity_phone_number.phone_number_id
WHERE
entity_phone_number.deleted = 0 AND entity_phone_number.entity_type = '{$entityName}' AND
phone_number.deleted = 0 AND phone_number.name = {value}
)",
'<>' => \Espo\Core\Utils\Util::toUnderScore($entityName) . ".id IN (
SELECT entity_id
FROM entity_phone_number
JOIN phone_number ON phone_number.id = entity_phone_number.phone_number_id
WHERE
entity_phone_number.deleted = 0 AND entity_phone_number.entity_type = '{$entityName}' AND
phone_number.deleted = 0 AND phone_number.name <> {value}
)"
'LIKE' => array(
'leftJoins' => [['phoneNumbers', 'phoneNumbersMultiple']],
'sql' => 'phoneNumbersMultiple.name LIKE {value}',
'distinct' => true
),
'=' => array(
'leftJoins' => [['phoneNumbers', 'phoneNumbersMultiple']],
'sql' => 'phoneNumbersMultiple.name = {value}',
'distinct' => true
),
'<>' => array(
'leftJoins' => [['phoneNumbers', 'phoneNumbersMultiple']],
'sql' => 'phoneNumbersMultiple.name <> {value}',
'distinct' => true
),
'IN' => array(
'leftJoins' => [['phoneNumbers', 'phoneNumbersMultiple']],
'sql' => 'phoneNumbersMultiple.name IN {value}',
'distinct' => true
),
'NOT IN' => array(
'leftJoins' => [['phoneNumbers', 'phoneNumbersMultiple']],
'sql' => 'phoneNumbersMultiple.name NOT IN {value}',
'distinct' => true
),
'IS NULL' => array(
'leftJoins' => [['phoneNumbers', 'phoneNumbersMultiple']],
'sql' => 'phoneNumbersMultiple.name IS NULL',
'distinct' => true
),
'IS NOT NULL' => array(
'leftJoins' => [['phoneNumbers', 'phoneNumbersMultiple']],
'sql' => 'phoneNumbersMultiple.name IS NOT NULL',
'distinct' => true
)
),
'orderBy' => 'phoneNumbers.name {direction}',
),
@@ -73,7 +84,7 @@ class Phone extends Base
),
),
'relations' => array(
$fieldName.'s' => array(
'phoneNumbers' => array(
'type' => 'manyMany',
'entity' => 'PhoneNumber',
'relationName' => 'entityPhoneNumber',
+14 -2
View File
@@ -320,9 +320,15 @@ class EntityManager
switch ($linkType) {
case 'oneToMany':
if ($this->getMetadata()->get('entityDefs.' . $entityForeign . '.field.' . $linkForeign)) {
if ($this->getMetadata()->get('entityDefs.' . $entityForeign . '.fields.' . $linkForeign)) {
throw new Conflict('Field ['.$entityForeign.'::'.$linkForeign.'] already exists.');
}
if ($this->getMetadata()->get('entityDefs.' . $entityForeign . '.fields.' . $linkForeign . 'Id')) {
throw new Conflict('Field ['.$entityForeign.'::'.$linkForeign.'Id] already exists.');
}
if ($this->getMetadata()->get('entityDefs.' . $entityForeign . '.fields.' . $linkForeign . 'Name')) {
throw new Conflict('Field ['.$entityForeign.'::'.$linkForeign.'Name] already exists.');
}
$dataLeft = array(
'fields' => array(
$link => array(
@@ -361,9 +367,15 @@ class EntityManager
);
break;
case 'manyToOne':
if ($this->getMetadata()->get('entityDefs.' . $entity . '.field.' . $link)) {
if ($this->getMetadata()->get('entityDefs.' . $entity . '.fields.' . $link)) {
throw new Conflict('Field ['.$entity.'::'.$link.'] already exists.');
}
if ($this->getMetadata()->get('entityDefs.' . $entity . '.fields.' . $link . 'Id')) {
throw new Conflict('Field ['.$entity.'::'.$link.'Id] already exists.');
}
if ($this->getMetadata()->get('entityDefs.' . $entity . '.fields.' . $link . 'Name')) {
throw new Conflict('Field ['.$entity.'::'.$link.'Name] already exists.');
}
$dataLeft = array(
'fields' => array(
$link => array(
+1 -1
View File
@@ -93,7 +93,7 @@ return array (
'Opportunity',
),
"tabList" => ["Account", "Contact", "Lead", "Opportunity", "Calendar", "Meeting", "Call", "Task", "Case", "Email", "Document", "Campaign", "KnowledgeBaseArticle"],
"quickCreateList" => ["Account", "Contact", "Lead", "Opportunity", "Meeting", "Call", "Task", "Case"],
"quickCreateList" => ["Account", "Contact", "Lead", "Opportunity", "Meeting", "Call", "Task", "Case", "Email"],
'calendarDefaultEntity' => 'Meeting',
'exportDisabled' => false,
'assignmentEmailNotifications' => false,
+4 -1
View File
@@ -73,6 +73,9 @@ class Download extends \Espo\Core\EntryPoints\Base
throw new NotFound();
}
$outputFileName = $attachment->get('name');
$outputFileName = str_replace("\"", "\\\"", $outputFileName);
$type = $attachment->get('type');
$disposition = 'attachment';
@@ -84,7 +87,7 @@ class Download extends \Espo\Core\EntryPoints\Base
if ($type) {
header('Content-Type: ' . $type);
}
header("Content-Disposition: " . $disposition . ";filename=\"" . $attachment->get('name') . "\"");
header("Content-Disposition: " . $disposition . ";filename=\"" . $outputFileName . "\"");
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
@@ -151,7 +151,10 @@ class Notifications extends \Espo\Core\Hooks\Base
$query = $this->getEntityManager()->getQuery();
$sql = "
DELETE FROM `notification`
WHERE related_id = ".$query->quote($entity->id)." AND related_type = ".$query->quote($entity->getEntityType()) ."
WHERE
(related_id = ".$query->quote($entity->id)." AND related_type = ".$query->quote($entity->getEntityType()) .")
OR
(related_parent_id = ".$query->quote($entity->id)." AND related_parent_type = ".$query->quote($entity->getEntityType()) .")
";
$this->getEntityManager()->getPDO()->query($sql);
}
@@ -45,11 +45,9 @@ class Invitations
protected $language;
protected $fileManager;
protected $ics;
public function __construct($entityManager, $smtpParams, $mailSender, $config, $dateTime, $language, $fileManager)
public function __construct($entityManager, $smtpParams, $mailSender, $config, $dateTime, $language)
{
$this->entityManager = $entityManager;
$this->smtpParams = $smtpParams;
@@ -57,7 +55,6 @@ class Invitations
$this->config = $config;
$this->dateTime = $dateTime;
$this->language = $language;
$this->fileManager = $fileManager;
}
protected function getEntityManager()
@@ -75,17 +72,28 @@ class Invitations
$key = '{'.$field.'}';
switch ($d['type']) {
case 'datetime':
$contents = str_replace($key, $this->dateTime->convertSystemDateTime($entity->get($field)), $contents);
$value = $entity->get($field);
if ($value) {
$value = $this->dateTime->convertSystemDateTime($value);
}
$contents = str_replace($key, $value, $contents);
break;
case 'date':
$contents = str_replace($key, $this->dateTime->convertSystemDate($entity->get($field)), $contents);
$value = $entity->get($field);
if ($value) {
$value = $this->dateTime->convertSystemDate($value);
}
$contents = str_replace($key, $value, $contents);
break;
case 'jsonArray':
break;
case 'jsonObject':
break;
default:
$contents = str_replace($key, $entity->get($field), $contents);
$value = $entity->get($field);
if (is_string($value) || $value === null || is_scalar($value) || is_callable([$value, '__toString'])) {
$contents = str_replace($key, $value, $contents);
}
}
}
@@ -108,7 +116,7 @@ class Invitations
if ($uid) {
$contents = str_replace('{acceptLink}', $siteUrl . '?entryPoint=eventConfirmation&action=accept&uid=' . $uid->get('name'), $contents);
$contents = str_replace('{declineLink}', $siteUrl . '?entryPoint=eventConfirmation&action=decline&uid=' . $uid->get('name'), $contents);
$contents = str_replace('{tentativeLink}', $siteUrl . '?entryPoint=eventConfirmation&action=tentativeLink&uid=' . $uid->get('name'), $contents);
$contents = str_replace('{tentativeLink}', $siteUrl . '?entryPoint=eventConfirmation&action=tentative&uid=' . $uid->get('name'), $contents);
}
return $contents;
}
@@ -37,7 +37,7 @@ class Opportunity extends \Espo\Core\Controllers\Record
public function actionReportByLeadSource($params, $data, $request)
{
$level = $this->getAcl()->getLevel('Opportunity', 'read');
if (!$level || $level == 'own') {
if (!$level || $level == 'own' || $level == 'no') {
throw new Forbidden();
}
@@ -50,7 +50,7 @@ class Opportunity extends \Espo\Core\Controllers\Record
public function actionReportByStage($params, $data, $request)
{
$level = $this->getAcl()->getLevel('Opportunity', 'read');
if (!$level || $level == 'own') {
if (!$level || $level == 'own' || $level == 'no') {
throw new Forbidden();
}
@@ -63,7 +63,7 @@ class Opportunity extends \Espo\Core\Controllers\Record
public function actionReportSalesByMonth($params, $data, $request)
{
$level = $this->getAcl()->getLevel('Opportunity', 'read');
if (!$level || $level == 'own') {
if (!$level || $level == 'own' || $level == 'no') {
throw new Forbidden();
}
@@ -76,7 +76,7 @@ class Opportunity extends \Espo\Core\Controllers\Record
public function actionReportSalesPipeline($params, $data, $request)
{
$level = $this->getAcl()->getLevel('Opportunity', 'read');
if (!$level || $level == 'own') {
if (!$level || $level == 'own' || $level == 'no') {
throw new Forbidden();
}
@@ -93,6 +93,25 @@ class Meeting extends \Espo\Core\ORM\Repositories\RDB
}
}
}
if (!$entity->isNew()) {
if ($entity->isFieldChanged('dateStart') && $entity->isFieldChanged('dateStart') && !$entity->isFieldChanged('dateEnd')) {
$dateEndPrevious = $entity->getFetched('dateEnd');
$dateStartPrevious = $entity->getFetched('dateStart');
if ($dateStartPrevious && $dateEndPrevious) {
$dtStart = new \DateTime($dateStartPrevious);
$dtEnd = new \DateTime($dateEndPrevious);
$dt = new \DateTime($entity->get('dateStart'));
if ($dtStart && $dtEnd && $dt) {
$duration = ($dtEnd->getTimestamp() - $dtStart->getTimestamp());
$dt->modify('+' . $duration . ' seconds');
$dateEnd = $dt->format('Y-m-d H:i:s');
$entity->set('dateEnd', $dateEnd);
}
}
}
}
}
public function getEntityReminders(Entity $entity)
@@ -124,7 +143,7 @@ class Meeting extends \Espo\Core\ORM\Repositories\RDB
return $reminders;
}
protected function afterSave(Entity $entity, array $options)
protected function afterSave(Entity $entity, array $options = array())
{
parent::afterSave($entity, $options);
@@ -64,7 +64,7 @@ class Task extends \Espo\Core\ORM\Repositories\RDB
return null;
}
protected function beforeSave(Entity $entity, array $options)
protected function beforeSave(Entity $entity, array $options = array())
{
parent::beforeSave($entity, $options);
@@ -11,6 +11,12 @@
"scopeFieldLevel": {
"KnowledgeBaseArticle": {
"portals": false
},
"Case": {
"status": {
"read": "yes",
"edit": "no"
}
}
}
}
@@ -1,4 +1,8 @@
{
"controller": "controllers/record",
"acl": "crm:acl/campaign-tracking-url"
"acl": "crm:acl/campaign-tracking-url",
"recordViews": {
"edit": "crm:views/campaign-tracking-url/record/edit",
"editQuick": "crm:views/campaign-tracking-url/record/edit-small"
}
}
@@ -2,7 +2,9 @@
"controller": "controllers/record",
"acl": "crm:acl/mass-email",
"recordViews": {
"detail": "crm:views/mass-email/record/detail"
"detail": "crm:views/mass-email/record/detail",
"edit": "crm:views/mass-email/record/edit",
"editQuick": "crm:views/mass-email/record/edit-small"
},
"views": {
"detail": "crm:views/mass-email/detail"
@@ -140,7 +140,8 @@
"view": "views/fields/assigned-user"
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"targetLists": {
"type": "linkMultiple",
@@ -271,7 +272,8 @@
},
"collection": {
"sortBy": "name",
"asc": true
"asc": true,
"textFilterFields": ["name", "emailAddress"]
},
"indexes": {
"name": {
@@ -109,10 +109,11 @@
"assignedUser": {
"type": "link",
"required": true,
"view": "views/fields/user"
"view": "views/fields/assigned-user"
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
}
},
"links": {
@@ -44,10 +44,11 @@
},
"assignedUser": {
"type": "link",
"view": "views/fields/user"
"view": "views/fields/assigned-user"
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"targetLists": {
"type": "linkMultiple",
@@ -70,10 +70,11 @@
},
"assignedUser": {
"type": "link",
"view": "views/fields/user"
"view": "views/fields/assigned-user"
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
}
},
"links": {
@@ -21,8 +21,11 @@
"accountId": {
"where": {
"=": "contact.id IN (SELECT contact_id FROM account_contact WHERE deleted = 0 AND account_id = {value})",
"<>": "contact.id IN (SELECT contact_id FROM account_contact WHERE deleted = 0 AND account_id <> {value})",
"IN": "contact.id IN (SELECT contact_id FROM account_contact WHERE deleted = 0 AND account_id IN {value})",
"NOT IN": "contact.id IN (SELECT contact_id FROM account_contact WHERE deleted = 0 AND account_id NOT IN {value})"
"NOT IN": "contact.id NOT IN (SELECT contact_id FROM account_contact WHERE deleted = 0 AND account_id IN {value})",
"IS NULL": "contact.account_id IS NULL",
"IS NOT NULL": "contact.account_id IS NOT NULL"
},
"disabled": true
},
@@ -33,8 +36,31 @@
"select": "accountContact.role",
"orderBy": "accountContact.role {direction}",
"where": {
"LIKE": "contact.id IN (SELECT contact_id FROM account_contact WHERE deleted = 0 AND role LIKE {value})",
"=": "contact.id IN (SELECT contact_id FROM account_contact WHERE deleted = 0 AND role = {value})"
"LIKE": {
"leftJoins": ["accounts"],
"sql": "accountsMiddle.role LIKE {value}",
"distinct": true
},
"=": {
"leftJoins": ["accounts"],
"sql": "accountsMiddle.role = {value}",
"distinct": true
},
"<>": {
"leftJoins": ["accounts"],
"sql": "accountsMiddle.role <> {value}",
"distinct": true
},
"IS NULL": {
"leftJoins": ["accounts"],
"sql": "accountsMiddle.role IS NULL",
"distinct": true
},
"IS NOT NULL": {
"leftJoins": ["accounts"],
"sql": "accountsMiddle.role IS NOT NULL",
"distinct": true
}
},
"trim": true
},
@@ -130,7 +156,8 @@
"view": "views/fields/assigned-user"
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"targetLists": {
"type": "linkMultiple",
@@ -61,10 +61,11 @@
},
"assignedUser": {
"type": "link",
"view": "views/fields/user"
"view": "views/fields/assigned-user"
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"accounts": {
"type": "linkMultiple",
@@ -25,7 +25,8 @@
"readOnly": true
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"parent": {
"type": "link"
@@ -51,10 +51,12 @@
"readOnly": true
},
"assignedUser": {
"type": "link"
"type": "link",
"views/fields/assigned-user"
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"categories": {
"type": "linkMultiple",
@@ -29,7 +29,8 @@
"required": true
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"parent": {
"type": "link"
@@ -107,7 +107,7 @@
},
"assignedUser": {
"type": "link",
"view": "views/fields/user"
"view": "views/fields/assigned-user"
},
"acceptanceStatus": {
"type": "varchar",
@@ -115,7 +115,8 @@
"disabled": true
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"campaign": {
"type": "link",
@@ -104,10 +104,11 @@
"assignedUser": {
"type": "link",
"required": true,
"view": "views/fields/user"
"view": "views/fields/assigned-user"
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
}
},
"links": {
@@ -91,10 +91,11 @@
"assignedUser": {
"type": "link",
"required": false,
"view": "views/fields/user"
"view": "views/fields/assigned-user"
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
}
},
"links": {
@@ -83,10 +83,11 @@
},
"assignedUser": {
"type": "link",
"view": "views/fields/user"
"view": "views/fields/assigned-user"
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
}
},
"links": {
@@ -33,10 +33,11 @@
},
"assignedUser": {
"type": "link",
"view": "views/fields/user"
"view": "views/fields/assigned-user"
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"campaigns": {
"type": "link"
@@ -82,10 +82,11 @@
"assignedUser": {
"type": "link",
"required": true,
"view": "views/fields/user"
"view": "views/fields/assigned-user"
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"attachments": {
"type": "attachmentMultiple",
@@ -135,9 +136,6 @@
"dateStart": {
"columns": ["dateStart", "deleted"]
},
"dateEnd": {
"columns": ["dateStart", "deleted"]
},
"status": {
"columns": ["status", "deleted"]
},
@@ -103,7 +103,8 @@ class Activities extends \Espo\Core\Services\Base
'leftJoins' => [['users', 'usersLeft']],
'whereClause' => array(
'usersLeftMiddle.userId' => $entity->id
)
),
'customJoin' => ''
);
if (!empty($statusList)) {
@@ -142,7 +143,8 @@ class Activities extends \Espo\Core\Services\Base
'leftJoins' => [['users', 'usersLeft']],
'whereClause' => array(
'usersLeftMiddle.userId' => $entity->id
)
),
'customJoin' => ''
);
if (!empty($statusList)) {
@@ -181,7 +183,8 @@ class Activities extends \Espo\Core\Services\Base
'leftJoins' => [['users', 'usersLeft']],
'whereClause' => array(
'usersLeftMiddle.userId' => $entity->id
)
),
'customJoin' => ''
);
if (!empty($statusList)) {
@@ -225,7 +228,8 @@ class Activities extends \Espo\Core\Services\Base
'status',
'createdAt'
],
'whereClause' => array()
'whereClause' => array(),
'customJoin' => ''
);
if (!empty($statusList)) {
@@ -439,7 +443,8 @@ class Activities extends \Espo\Core\Services\Base
'status',
'createdAt'
],
'whereClause' => array()
'whereClause' => array(),
'customJoin' => ''
);
if (!empty($statusList)) {
@@ -686,7 +691,8 @@ class Activities extends \Espo\Core\Services\Base
'dateStart>=' => $from,
'dateStart<' => $to,
'usersMiddle.status!=' => 'Declined'
)
),
'customJoin' => ''
);
return $this->getEntityManager()->getQuery()->createSelectQuery('Meeting', $selectParams);
@@ -716,7 +722,8 @@ class Activities extends \Espo\Core\Services\Base
'dateStart>=' => $from,
'dateStart<' => $to,
'usersMiddle.status!=' => 'Declined'
)
),
'customJoin' => ''
);
return $this->getEntityManager()->getQuery()->createSelectQuery('Call', $selectParams);
@@ -943,8 +950,11 @@ class Activities extends \Espo\Core\Services\Base
$sth = $pdo->prepare($unionSql);
$sth->bindParam(':offset', intval($params['offset']), \PDO::PARAM_INT);
$sth->bindParam(':maxSize', intval($params['maxSize']), \PDO::PARAM_INT);
$offset = intval($params['offset']);
$maxSize = intval($params['maxSize']);
$sth->bindParam(':offset', $offset, \PDO::PARAM_INT);
$sth->bindParam(':maxSize', $maxSize, \PDO::PARAM_INT);
$sth->execute();
$rows = $sth->fetchAll(\PDO::FETCH_ASSOC);
@@ -44,7 +44,7 @@ class CaseObj extends \Espo\Services\Record
'inboundEmailId'
];
public function afterCreate($entity, array $data = array())
public function afterCreate(Entity $entity, array $data = array())
{
parent::afterCreate($entity, $data);
if (!empty($data['emailId'])) {
@@ -61,7 +61,7 @@ class Contact extends \Espo\Services\Record
return $data;
}
public function afterCreate($entity, array $data = array())
public function afterCreate(Entity $entity, array $data = array())
{
parent::afterCreate($entity, $data);
if (!empty($data['emailId'])) {
@@ -63,7 +63,7 @@ class Lead extends \Espo\Services\Record
return $data;
}
public function afterCreate($entity, array $data, $data = array())
public function afterCreate(Entity $entity, array $data = array())
{
parent::afterCreate($entity, $data);
if (!empty($data['emailId'])) {
@@ -105,8 +105,6 @@ class TargetList extends \Espo\Services\Record
protected function findLinkedEntitiesOptedOut($id, $params)
{
$collection = new \Espo\ORM\EntityCollection;
$pdo = $this->getEntityManager()->getPDO();
$query = $this->getEntityManager()->getQuery();
+2
View File
@@ -91,6 +91,8 @@ class Email extends \Espo\Core\Notificators\Base
$this->getEntityManager()->getRepository('Email')->loadFromField($entity);
}
$person = null;
$from = $entity->get('from');
if ($from) {
$person = $this->getEntityManager()->getRepository('EmailAddress')->getEntityByAddress($from, null, ['User', 'Contact', 'Lead']);
+1 -1
View File
@@ -798,7 +798,7 @@ abstract class Mapper implements IMapper
foreach ($entity->fields as $field => $fieldDefs) {
if ($entity->has($field)) {
if ($onlyStorable) {
if (!empty($fieldDefs['notStorable']) || isset($fieldDefs['source']) && $fieldDefs['source'] != 'db')
if (!empty($fieldDefs['notStorable']) || !empty($fieldDefs['autoincrement']) || isset($fieldDefs['source']) && $fieldDefs['source'] != 'db')
continue;
if ($fieldDefs['type'] == IEntity::FOREIGN)
continue;
+73 -11
View File
@@ -110,6 +110,18 @@ abstract class Base
$whereClause = $whereClause + array('deleted' => 0);
}
if (empty($params['joins'])) {
$params['joins'] = array();
}
if (empty($params['leftJoins'])) {
$params['leftJoins'] = array();
}
if (empty($params['customJoin'])) {
$params['customJoin'] = '';
}
$wherePart = $this->getWhere($entity, $whereClause, 'AND', $params);
if (empty($params['aggregation'])) {
$selectPart = $this->getSelect($entity, $params['select'], $params['distinct']);
$orderPart = $this->getOrder($entity, $params['orderBy'], $params['order']);
@@ -134,16 +146,8 @@ abstract class Base
$selectPart = $this->getAggregationSelect($entity, $params['aggregation'], $params['aggregationBy'], $aggDist);
}
if (empty($params['joins'])) {
$params['joins'] = array();
}
if (empty($params['leftJoins'])) {
$params['leftJoins'] = array();
}
$joinsPart = $this->getBelongsToJoins($entity, $params['select'], array_merge($params['joins'], $params['leftJoins']));
$wherePart = $this->getWhere($entity, $whereClause);
if (!empty($params['customWhere'])) {
$wherePart .= ' ' . $params['customWhere'];
@@ -581,7 +585,7 @@ abstract class Base
return false;
}
public function getWhere(IEntity $entity, $whereClause, $sqlOp = 'AND')
public function getWhere(IEntity $entity, $whereClause, $sqlOp = 'AND', &$params = array())
{
$whereParts = array();
@@ -630,10 +634,54 @@ abstract class Base
} else if ($operator == '<>') {
$operatorModified = 'NOT IN';
}
} else if (is_null($value)) {
if ($operator == '=') {
$operatorModified = 'IS NULL';
} else if ($operator == '<>') {
$operatorModified = 'IS NOT NULL';
}
}
if (!empty($fieldDefs['where']) && !empty($fieldDefs['where'][$operatorModified])) {
$whereParts[] = str_replace('{value}', $this->stringifyValue($value), $fieldDefs['where'][$operatorModified]);
$whereSqlPart = '';
if (is_string($fieldDefs['where'][$operatorModified])) {
$whereSqlPart = $fieldDefs['where'][$operatorModified];
} else {
if (!empty($fieldDefs['where'][$operatorModified]['sql'])) {
$whereSqlPart = $fieldDefs['where'][$operatorModified]['sql'];
}
}
if (!empty($fieldDefs['where'][$operatorModified]['leftJoins'])) {
foreach ($fieldDefs['where'][$operatorModified]['leftJoins'] as $j) {
$jAlias = $this->obtainJoinAlias($j);
foreach ($params['leftJoins'] as $jE) {
$jEAlias = $this->obtainJoinAlias($jE);
if ($jEAlias === $jAlias) {
continue 2;
}
}
$params['leftJoins'][] = $j;
}
}
if (!empty($fieldDefs['where'][$operatorModified]['joins'])) {
foreach ($fieldDefs['where'][$operatorModified]['joins'] as $j) {
$jAlias = $this->obtainJoinAlias($j);
foreach ($params['joins'] as $jE) {
$jEAlias = $this->obtainJoinAlias($jE);
if ($jEAlias === $jAlias) {
continue 2;
}
}
$params['joins'][] = $j;
}
}
if (!empty($fieldDefs['where'][$operatorModified]['customJoin'])) {
$params['customJoin'] .= ' ' . $fieldDefs['where'][$operatorModified]['customJoin'];
}
if (!empty($fieldDefs['where'][$operatorModified]['distinct'])) {
$params['distinct'] = true;
}
$whereParts[] = str_replace('{value}', $this->stringifyValue($value), $whereSqlPart);
} else {
if ($fieldDefs['type'] == IEntity::FOREIGN) {
$leftPart = '';
@@ -682,7 +730,7 @@ abstract class Base
}
}
} else {
$internalPart = $this->getWhere($entity, $value, $field);
$internalPart = $this->getWhere($entity, $value, $field, $params);
if ($internalPart) {
$whereParts[] = "(" . $internalPart . ")";
}
@@ -691,6 +739,20 @@ abstract class Base
return implode(" " . $sqlOp . " ", $whereParts);
}
public function obtainJoinAlias($j)
{
if (is_array($j)) {
if (count($j)) {
$joinAlias = $j[1];
} else {
$joinAlias = $j[0];
}
} else {
$joinAlias = $j;
}
return $joinAlias;
}
public function stringifyValue($value)
{
if (is_array($value)) {
+2 -2
View File
@@ -116,7 +116,7 @@ class Email extends \Espo\Core\ORM\Repositories\RDB
$entity->set('idHash', $idHash);
}
protected function beforeSave(Entity $entity, array $options)
protected function beforeSave(Entity $entity, array $options = array())
{
$eaRepositoty = $this->getEntityManager()->getRepository('EmailAddress');
@@ -187,7 +187,7 @@ class Email extends \Espo\Core\ORM\Repositories\RDB
}
}
protected function afterSave(Entity $entity, array $options)
protected function afterSave(Entity $entity, array $options = array())
{
parent::afterSave($entity, $options);
if (!$entity->isNew()) {
@@ -320,6 +320,7 @@ class EmailAddress extends \Espo\Core\ORM\Repositories\RDB
".$pdo->quote($emailAddress->id).",
".$pdo->quote((int)($address === $primary))."
)
ON DUPLICATE KEY UPDATE deleted = 0, `primary` = ".$pdo->quote((int)($address === $primary))."
";
$sth = $pdo->prepare($query);
$sth->execute();
+1 -1
View File
@@ -43,7 +43,7 @@ class Job extends \Espo\Core\ORM\Repositories\RDB
return $this->getInjection('config');
}
public function beforeSave(Entity $entity)
public function beforeSave(Entity $entity, array $options = array())
{
if (!$entity->has('executeTime')) {
$entity->set('executeTime', date('Y-m-d H:i:s'));
@@ -233,6 +233,7 @@ class PhoneNumber extends \Espo\Core\ORM\Repositories\RDB
".$pdo->quote($phoneNumber->id).",
".$pdo->quote((int)($number === $primary))."
)
ON DUPLICATE KEY UPDATE deleted = 0, `primary` = ".$pdo->quote((int)($number === $primary))."
";
$sth = $pdo->prepare($query);
$sth->execute();
@@ -331,8 +331,8 @@
},
"options": {
"salutationName": {
"Mr.": "Hr.",
"Ms.": "Fr.",
"Mr.": "Herr",
"Ms.": "Frau",
"Mrs.": "Frl.",
"Dr.": "Dr."
},
@@ -44,6 +44,6 @@
"messages": {
"entityCreated": "Entity has been created",
"linkAlreadyExists": "Link name conflict.",
"linkConflict": "Link with the same name already exists."
"linkConflict": "Name conflict: link or field with the same name already exists."
}
}
@@ -72,7 +72,8 @@
"userNameEmailAddressNotFound": "Username/Email Address not found",
"forbidden": "Forbidden, please try later",
"uniqueLinkHasBeenSent": "The unique URL has been sent to the specified email address.",
"passwordChangedByRequest": "Password has been changed."
"passwordChangedByRequest": "Password has been changed.",
"setupSmtpBefore": "You need to setup <a href=\"{url}\">SMTP settings</a> to make the system be able to send password in email."
},
"boolFilters": {
"onlyMyTeam": "Only My Team"
@@ -1,9 +1,11 @@
[
"teams",
"createdAt",
"emailAddress",
"title",
"isAdmin",
"isActive",
"portals",
"accounts"
"accounts",
"contact"
]
@@ -17,6 +17,7 @@
"detail": "views/email/modals/detail",
"compose": "views/modals/compose-email"
},
"quickCreateModalType": "compose",
"menu": {
"list": {
"buttons": [
@@ -14,5 +14,8 @@
"active",
"activePortal"
],
"boolFilterList": ["onlyMyTeam"]
"boolFilterList": ["onlyMyTeam"],
"selectDefaultFilters": {
"filter": "active"
}
}
@@ -183,7 +183,7 @@
"assignedUser": {
"type": "link",
"required": false,
"view": "views/fields/user"
"view": "views/fields/assigned-user"
},
"replied": {
"type": "link",
@@ -206,7 +206,8 @@
"notStorable": true
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"users": {
"type": "linkMultiple",
@@ -30,6 +30,10 @@
"related": {
"type": "linkParent",
"readOnly": true
},
"relatedParent": {
"type": "linkParent",
"readOnly": true
}
},
"links": {
@@ -39,6 +43,9 @@
},
"related": {
"type": "belongsToParent"
},
"relatedParent": {
"type": "belongsToParent"
}
},
"collection": {
@@ -91,8 +91,7 @@
"trim": true
},
"smtpServer": {
"type": "varchar",
"required": true
"type": "varchar"
},
"smtpPort": {
"type": "int",
+2 -2
View File
@@ -31,9 +31,9 @@ namespace Espo\SelectManagers;
class Email extends \Espo\Core\SelectManagers\Base
{
public function getSelectParams(array $params, $withAcl = false)
public function getSelectParams(array $params, $withAcl = false, $checkWherePermission = false)
{
$result = parent::getSelectParams($params, $withAcl);
$result = parent::getSelectParams($params, $withAcl, $checkWherePermission);
if (!$this->hasJoin('users', $result) && !$this->hasLeftJoin('users', $result)) {
$this->addLeftJoin('users', $result);
+1 -1
View File
@@ -129,7 +129,7 @@ class EmailAddress extends Record
foreach ($result as $r) {
foreach ($final as $f) {
if ($f['emailAddress'] == $r['emailAddress'] && $f['name'] == $r['name']) {
if ($f['emailAddress'] == $r['emailAddress']) {
continue 2;
}
}
+3 -1
View File
@@ -192,7 +192,9 @@ class EmailTemplate extends Record
$value = $this->getDateTime()->convertSystemDateTime($value);
}
}
$text = str_replace('{' . $type . '.' . $field . '}', $value, $text);
if (is_string($value) || $value === null || is_scalar($value) || is_callable([$value, '__toString'])) {
$text = str_replace('{' . $type . '.' . $field . '}', $value, $text);
}
}
return $text;
}
+3 -2
View File
@@ -79,19 +79,20 @@ class Notification extends \Espo\Services\Record
$now = date('Y-m-d H:i:s');
$pdo = $this->getEntityManager()->getPDO();
$sql = "INSERT INTO `notification` (`id`, `data`, `type`, `user_id`, `created_at`, `related_id`, `related_type`) VALUES ";
$sql = "INSERT INTO `notification` (`id`, `data`, `type`, `user_id`, `created_at`, `related_id`, `related_type`, `related_parent_id`, `related_parent_type`) VALUES ";
$arr = [];
foreach ($userIdList as $userId) {
if (empty($userId)) continue;
$user = $this->getEntityManager()->getEntity('User');
$user->id = $userId;
$user->setIsNew(false);
$user->setAsFetched();
if (!$this->checkUserNoteAccess($user, $note)) {
continue;
}
$id = uniqid();
$arr[] = "(".$pdo->quote($id).", ".$pdo->quote($encodedData).", ".$pdo->quote('Note').", ".$pdo->quote($userId).", ".$pdo->quote($now).", ".$pdo->quote($note->id).", ".$pdo->quote('Note').")";
$arr[] = "(".$pdo->quote($id).", ".$pdo->quote($encodedData).", ".$pdo->quote('Note').", ".$pdo->quote($userId).", ".$pdo->quote($now).", ".$pdo->quote($note->id).", ".$pdo->quote('Note').", ".$pdo->quote($note->get('parentId')).", ".$pdo->quote($note->get('parentType')).")";
}
if (empty($arr)) {
+6 -3
View File
@@ -361,13 +361,16 @@ class Record extends \Espo\Core\Services\Base
$assignedUserId = $entity->get('assignedUserId');
$assignmentPermission = $this->getAcl()->get('assignmentPermission');
if (empty($assignedUserId)) {
if ($assignmentPermission === 'no') {
return false;
}
return true;
}
$assignmentPermission = $this->getAcl()->get('assignmentPermission');
if (empty($assignmentPermission) || $assignmentPermission === true || !in_array($assignmentPermission, ['team', 'no'])) {
if ($assignmentPermission === true || !in_array($assignmentPermission, ['team', 'no'])) {
return true;
}
+2 -2
View File
@@ -1017,8 +1017,8 @@ class Stream extends \Espo\Core\Services\Base
$ignoreScopeList = [];
$scopes = $this->getMetadata()->get('scopes', array());
foreach ($scopes as $scope => $d) {
if (!$d['entity']) continue;
if (!$d['object']) continue;
if (empty($d['entity']) || !$d['entity']) continue;
if (empty($d['object']) || !$d['object']) continue;
if (!$this->getAcl()->checkScope($scope)) {
$ignoreScopeList[] = $scope;
}
+3 -1
View File
@@ -29,6 +29,8 @@
namespace Espo\Services;
use \Espo\ORM\Entity;
class Team extends Record
{
protected function init()
@@ -49,7 +51,7 @@ class Team extends Record
return $this->getInjection('fileManager');
}
public function afterUpdate(Entity $entity, array $data)
public function afterUpdate(Entity $entity, array $data = array())
{
parent::afterUpdate($entity, $data);
if (array_key_exists('rolesIds', $data)) {
+4 -2
View File
@@ -224,7 +224,9 @@ class User extends Record
if (!is_null($newPassword) && !empty($data['sendAccessInfo'])) {
if ($user->isActive()) {
$this->sendPassword($user, $newPassword);
try {
$this->sendPassword($user, $newPassword);
} catch (\Exception $e) {}
}
}
@@ -388,7 +390,7 @@ class User extends Record
$email = $this->getEntityManager()->getEntity('Email');
if (!$this->getConfig()->get('smtpServer')) {
return;
throw new Error("SMTP settings is not setup.");
}
$subject = $this->getLanguage()->translate('passwordChangeLinkEmailSubject', 'messages', 'User');
+2 -2
View File
File diff suppressed because one or more lines are too long
@@ -24,12 +24,12 @@
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
************************************************************************/
Espo.define('Crm:Views.Account.Detail', 'Views.Detail', function (Dep) {
Espo.define('crm:views/account/detail', 'views/detail', function (Dep) {
return Dep.extend({
relatedAttributeMap: {
'contacts': {
'billingAddressCity': 'addressCity',
@@ -39,9 +39,8 @@ Espo.define('Crm:Views.Account.Detail', 'Views.Detail', function (Dep) {
'billingAddressCountry': 'addressCountry',
'id': 'accountId',
'name': 'accountName'
},
},
}
}
});
});
@@ -237,7 +237,7 @@ Espo.define('crm:views/calendar/calendar', ['view', 'lib!full-calendar'], functi
if (!o.dateStartDate) {
event.start = this.getDateTime().toMoment(o.dateStart);
} else {
event.start = this.getDateTime().toMoment(o.dateStartDate);
event.start = this.getDateTime().toMomentDate(o.dateStartDate);
}
}
if (o.dateEnd) {
@@ -383,7 +383,7 @@ Espo.define('crm:views/calendar/calendar', ['view', 'lib!full-calendar'], functi
selectable: true,
selectHelper: true,
height: this.options.height || null,
firstDay: this.getPreferences().get('weekStart'),
firstDay: this.getDateTime().weekStart,
slotEventOverlap: true,
slotDuration: slotDuration,
snapDuration: this.slotDuration * 60 * 1000,
@@ -0,0 +1,37 @@
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
Espo.define('crm:views/campaign-tracking-url/record/edit-small', 'views/record/edit-small', function (Dep) {
return Dep.extend({
sideView: false
});
});
@@ -0,0 +1,37 @@
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
Espo.define('crm:views/campaign-tracking-url/record/edit', 'views/record/edit', function (Dep) {
return Dep.extend({
sideView: false
});
});
@@ -45,6 +45,8 @@ Espo.define('crm:views/case/record/panels/activities', 'crm:views/record/panels/
var emailAddress = contact.get('emailAddress');
if (emailAddress) {
attributes.to = emailAddress;
attributes.nameHash = {};
attributes.nameHash[emailAddress] = contact.get('name');
}
callback.call(this, attributes);
@@ -0,0 +1,37 @@
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
Espo.define('crm:views/mass-email/record/edit-small', 'views/record/edit-small', function (Dep) {
return Dep.extend({
sideView: false
});
});
@@ -0,0 +1,37 @@
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
Espo.define('crm:views/mass-email/record/edit', 'views/record/edit', function (Dep) {
return Dep.extend({
sideView: false
});
});
@@ -77,7 +77,7 @@ Espo.define('crm:views/record/panels/activities', ['views/record/panels/relation
'Meeting': {
rows: [
[
{name: 'ico', view: 'Crm:Fields.Ico'},
{name: 'ico', view: 'crm:views/fields/ico'},
{
name: 'name',
link: true,
@@ -92,7 +92,7 @@ Espo.define('crm:views/record/panels/activities', ['views/record/panels/relation
'Call': {
rows: [
[
{name: 'ico', view: 'Crm:Fields.Ico'},
{name: 'ico', view: 'crm:views/fields/ico'},
{
name: 'name',
link: true,
@@ -119,7 +119,7 @@ Espo.define('crm:views/record/panels/activities', ['views/record/panels/relation
this.listenToOnce(this.collection, 'sync', function () {
this.notify(false);
}.bind(this));
}, this);
this.notify('Loading...');
this.collection.fetch();
@@ -185,7 +185,6 @@ Espo.define('crm:views/record/panels/activities', ['views/record/panels/relation
this.collection.asc = this.asc;
this.collection.maxSize = this.getConfig().get('recordsPerPageSmall') || 5;
this.listenToOnce(this.collection, 'sync', function () {
this.createView('list', 'views/record/list-expanded', {
el: this.$el.selector + ' > .list-container',
@@ -194,7 +193,7 @@ Espo.define('crm:views/record/panels/activities', ['views/record/panels/relation
rowActionsView: this.rowActionsView,
checkboxes: false,
collection: this.collection,
listLayout: this.listLayout,
listLayout: this.listLayout
}, function (view) {
view.render();
});
@@ -73,7 +73,7 @@ Espo.define('crm:views/record/panels/history', 'crm:views/record/panels/activiti
'Meeting': {
rows: [
[
{name: 'ico', view: 'Crm:Fields.Ico'},
{name: 'ico', view: 'crm:views/fields/ico'},
{
name: 'name',
link: true,
@@ -89,7 +89,7 @@ Espo.define('crm:views/record/panels/history', 'crm:views/record/panels/activiti
'Call': {
rows: [
[
{name: 'ico', view: 'Crm:Fields.Ico'},
{name: 'ico', view: 'crm:views/fields/ico'},
{
name: 'name',
link: true,
@@ -105,7 +105,7 @@ Espo.define('crm:views/record/panels/history', 'crm:views/record/panels/activiti
'Email': {
rows: [
[
{name: 'ico', view: 'Crm:Fields.Ico'},
{name: 'ico', view: 'crm:views/fields/ico'},
{
name: 'name',
link: true,
+1 -1
View File
@@ -7,7 +7,7 @@
<section>
<h5>Version {{version}}</h5>
<p>
Copyright &copy; 2014-2015 EspoCRM: Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko.
Copyright &copy; 2014-2016 EspoCRM: Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko.
<br>
Website: <a href="http://www.espocrm.com">http://www.espocrm.com</a>.
</p>
+1 -1
View File
@@ -1 +1 @@
<a href="javascript:" data-email-address="{{value}}" data-action="mailTo">{{value}}</a>
<a href="javascript:" data-email-address="{{value}}" data-action="mailTo" title="{{value}}">{{value}}</a>
+1 -1
View File
@@ -1,4 +1,4 @@
{{#if idValue}}
<a href="#{{foreignScope}}/view/{{idValue}}">{{nameValue}}</a>
<a href="#{{foreignScope}}/view/{{idValue}}" title="{{nameValue}}">{{nameValue}}</a>
{{/if}}
+1 -1
View File
@@ -1 +1 @@
<a href="tel:{{value}}" data-phone-number="{{value}}" data-action="dial">{{value}}</a>
<a href="tel:{{value}}" data-phone-number="{{value}}" data-action="dial" title="{{value}}">{{value}}</a>
+1 -1
View File
@@ -1,3 +1,3 @@
{{#if value}}
<a href="{{url}}" target="_blank">{{value}}</a>
<a href="{{url}}" target="_blank" title="{{value}}">{{value}}</a>
{{/if}}
@@ -1,4 +1,4 @@
<li data-id="{{model.id}}" class="list-group-item">
<div class="cell">
<a href="javascript:" class="action{{#unless showFold}} hidden{{/unless}} small" data-action="fold" data-id="{{model.id}}"><span class="glyphicon glyphicon-chevron-down"></span></a>
<a href="javascript:" class="action{{#unless showUnfold}} hidden{{/unless}} small" data-action="unfold" data-id="{{model.id}}"><span class="glyphicon glyphicon-chevron-right"></span></a>
@@ -6,5 +6,4 @@
<a href="#{{model.name}}/view/{{model.id}}" class="link{{#if isSelected}} text-bold{{/if}}" data-id="{{model.id}}">{{name}}</a>
</div>
<div class="children{{#unless isUnfolded}} hidden{{/unless}}">{{{children}}}</div>
</li>
<div class="children{{#unless isUnfolded}} hidden{{/unless}}">{{{children}}}</div>
@@ -25,7 +25,9 @@
<ul class="list-group list-group-tree list-group-no-border">
{{#each rowList}}
<li data-id="{{./this}}" class="list-group-item">
{{{var this ../this}}}
</li>
{{/each}}
{{#unless createDisabled}}
<li class="list-group-item">
@@ -14,7 +14,7 @@
<div class="cell form-group col-sm-6 col-md-12">
<label class="control-label">{{translate 'Created'}}</label>
<div class="field">
<span data-name="createdAt">{{{createdAt}}}</span> <span class="text-muted">&raquo;</span> <span data-name="createdBy">{{{createdBy}}}</span>
<span data-name="createdAt" class="field">{{{createdAt}}}</span> <span class="text-muted">&raquo;</span> <span data-name="createdBy" class="field">{{{createdBy}}}</span>
</div>
</div>
{{/ifAttrNotEmpty}}
@@ -23,7 +23,7 @@
<div class="cell form-group col-sm-6 col-md-12">
<label class="control-label">{{translate 'Modified'}}</label>
<div class="field">
<span data-name="modifiedAt">{{{modifiedAt}}}</span> <span class="text-muted">&raquo;</span> <span data-name="modifiedBy">{{{modifiedBy}}}</span>
<span data-name="modifiedAt" class="field">{{{modifiedAt}}}</span> <span class="text-muted">&raquo;</span> <span data-name="modifiedBy" >{{{modifiedBy}}}</span>
</div>
</div>
{{/ifAttrNotEmpty}}
+1 -2
View File
@@ -260,8 +260,7 @@ Espo.define('controller', [], function () {
if (master.currentViewKey) {
this.set('storedScrollTop-' + master.currentViewKey, $(window).scrollTop());
if (this.hasStoredMainView(master.currentViewKey)) {
master.nestedViews['main'].undelegateEvents();
delete master.nestedViews['main'];
master.unchainView('main');
}
}
master.currentViewKey = storedKey;
+3 -3
View File
@@ -40,11 +40,11 @@ Espo.define('ui', [], function () {
this.height = false;
this.buttons = [];
this.removeOnClose = true;
this.graggable = false;
this.draggable = false;
this.container = 'body'
this.onRemove = function () {};
var params = ['className', 'backdrop', 'keyboard', 'closeButton', 'header', 'body', 'width', 'height', 'fitHeight', 'buttons', 'removeOnClose', 'graggable', 'container', 'onRemove'];
var params = ['className', 'backdrop', 'keyboard', 'closeButton', 'header', 'body', 'width', 'height', 'fitHeight', 'buttons', 'removeOnClose', 'draggable', 'container', 'onRemove'];
params.forEach(function (param) {
if (param in options) {
this[param] = options[param];
@@ -99,7 +99,7 @@ Espo.define('ui', [], function () {
}
}.bind(this));
if (this.graggable) {
if (this.draggable) {
this.$el.find('header').css('cursor', 'pointer');
this.$el.draggable({
handle: 'header',
@@ -338,7 +338,7 @@ Espo.define('views/admin/link-manager/modals/edit', ['views/modal', 'views/admin
if (view) {
view.disabled = true;
}
this.$el.find('.cell-' + name).css('visibility', 'hidden');
this.$el.find('.cell[data-name=' + name+']').css('visibility', 'hidden');
},
showField: function (name) {
@@ -346,7 +346,7 @@ Espo.define('views/admin/link-manager/modals/edit', ['views/modal', 'views/admin
if (view) {
view.disabled = false;
}
this.$el.find('.cell-' + name).css('visibility', 'visible');
this.$el.find('.cell[data-name=' + name+']').css('visibility', 'visible');
},
handleLinkTypeChange: function () {
+1 -1
View File
@@ -36,7 +36,7 @@ Espo.define('views/fields/user-with-avatar', 'views/fields/user', function (Dep)
data: function () {
var o = _.extend({}, Dep.prototype.data.call(this));
if (this.mode == 'detail' || this.mode == 'list') {
if (this.mode == 'detail') {
o.avatar = this.getAvatarHtml();
}
return o;
@@ -62,7 +62,7 @@ Espo.define('views/global-search/global-search', 'view', function (Dep) {
},
runSearch: function (text) {
var text = this.$input.val();
var text = this.$input.val().trim();
if (text != '' && text.length > 2) {
text = text;
this.search(text);
+3
View File
@@ -185,7 +185,10 @@ Espo.define('views/list', ['views/main', 'search-manager'], function (Dep, Searc
o[option] = this.options[option];
}, this);
var listViewName = this.getRecordViewName();
this.createView('list', listViewName, o, function (view) {
if (!this.hasParentView()) return;
view.render();
view.notify(false);
if (this.searchPanel) {
+3
View File
@@ -53,6 +53,8 @@ Espo.define('views/modal', 'view', function (Dep) {
escapeDisabled: false,
isDraggable: false,
events: {
'click .action': function (e) {
var $target = $(e.currentTarget);
@@ -135,6 +137,7 @@ Espo.define('views/modal', 'view', function (Dep) {
width: this.width,
keyboard: !this.escapeDisabled,
fitHeight: this.fitHeight,
draggable: this.isDraggable,
onRemove: function () {
this.onDialogClose();
}.bind(this)
@@ -30,7 +30,7 @@ Espo.define('Views.OutboundEmail.Fields.TestSend', 'Views.Fields.Base', function
return Dep.extend({
_template: '<button class="btn btn-default disabled" data-action="sendTestEmail">{{translate \'Send Test Email\' scope=\'Email\'}}</button>',
_template: '<button class="btn btn-default hidden" data-action="sendTestEmail">{{translate \'Send Test Email\' scope=\'Email\'}}</button>',
events: {
'click [data-action="sendTestEmail"]': function () {
@@ -44,9 +44,9 @@ Espo.define('Views.OutboundEmail.Fields.TestSend', 'Views.Fields.Base', function
checkAvailability: function () {
if (this.model.get('smtpServer')) {
this.$el.find('button').removeClass('disabled');
this.$el.find('button').removeClass('hidden');
} else {
this.$el.find('button').addClass('disabled');
this.$el.find('button').addClass('hidden');
}
},
+9 -3
View File
@@ -416,13 +416,19 @@ Espo.define('views/record/detail', ['views/record/base', 'view-record-helper'],
var fields = {};
if (this.hasView('middle')) {
_.extend(fields, Espo.Utils.clone(this.getView('middle').getFieldViews(withHidden)));
if ('getFieldViews' in this.getView('middle')) {
_.extend(fields, Espo.Utils.clone(this.getView('middle').getFieldViews(withHidden)));
}
}
if (this.hasView('side')) {
_.extend(fields, this.getView('side').getFieldViews(withHidden));
if ('getFieldViews' in this.getView('side')) {
_.extend(fields, this.getView('side').getFieldViews(withHidden));
}
}
if (this.hasView('bottom')) {
_.extend(fields, this.getView('bottom').getFieldViews(withHidden));
if ('getFieldViews' in this.getView('bottom')) {
_.extend(fields, this.getView('bottom').getFieldViews(withHidden));
}
}
return fields;
},
+3 -2
View File
@@ -161,8 +161,9 @@ Espo.define('views/record/list-tree', 'views/record/list', function (Dep) {
var count = modelList.length;
var built = 0;
modelList.forEach(function (model, i) {
this.rowList.push('row-' + i);
this.createView('row-' + i, this.itemViewName, {
var key = model.id;
this.rowList.push(key);
this.createView(key, this.itemViewName, {
model: model,
collection: this.collection,
el: this.options.el + ' ' + this.getRowSelector(model.id),
+10 -1
View File
@@ -782,6 +782,7 @@ Espo.define('views/record/list', 'view', function (Dep) {
acl: {
edit: this.getAcl().checkModel(model, 'edit')
},
el: this.options.el + ' .list-row[data-id="'+key+'"]',
optionsToPass: ['acl'],
noCache: true,
_layout: {
@@ -934,6 +935,10 @@ Espo.define('views/record/list', 'view', function (Dep) {
Espo.Ui.notify(false);
});
view.render();
this.listenToOnce(view, 'remove', function () {
this.clearView('modal');
}, this);
this.listenToOnce(view, 'after:save', function (m) {
var model = this.collection.get(m.id);
if (model) {
@@ -990,6 +995,10 @@ Espo.define('views/record/list', 'view', function (Dep) {
view.render();
this.listenToOnce(view, 'remove', function () {
this.clearView('modal');
}, this);
this.listenToOnce(view, 'after:save', function (m) {
var model = this.collection.get(m.id);
if (model) {
@@ -1057,7 +1066,7 @@ Espo.define('views/record/list', 'view', function (Dep) {
}
this.removeRowHtml(id);
var key = 'row-' + id;
var key = id;
this.clearView(key);
var index = this.rowList.indexOf(key);
if (~index) {
+1 -1
View File
@@ -610,7 +610,7 @@ Espo.define('views/record/search', 'view', function (Dep) {
},
fetch: function () {
this.textFilter = this.$el.find('input[name="textFilter"]').val();
this.textFilter = this.$el.find('input[name="textFilter"]').val().trim();
this.bool = {};
+13 -7
View File
@@ -58,13 +58,7 @@ Espo.define('views/site/navbar', 'view', function (Dep) {
'click a[data-action="quick-create"]': function (e) {
e.preventDefault();
var scope = $(e.currentTarget).data('name');
this.notify('Loading...');
this.createView('quickCreate', 'views/modals/edit', {scope: scope}, function (view) {
view.once('after:render', function () {
this.notify(false);
});
view.render();
});
this.quickCreate(scope);
},
'click .navbar-header a.minimizer': function () {
var $body = $('body');
@@ -379,6 +373,18 @@ Espo.define('views/site/navbar', 'view', function (Dep) {
});
}
return menuDefs;
},
quickCreate: function (scope) {
Espo.Ui.notify(this.translate('Loading...'));
var type = this.getMetadata().get(['clientDefs', scope, 'quickCreateModalType']) || 'edit';
var viewName = this.getMetadata().get(['clientDefs', scope, 'modalViews', type]) || 'views/modals/edit';
this.createView('quickCreate', viewName , {scope: scope}, function (view) {
view.once('after:render', function () {
Espo.Ui.notify(false);
});
view.render();
});
}
});
+18 -17
View File
@@ -40,27 +40,28 @@ Espo.define('views/user/detail', 'views/detail', function (Dep) {
action: "preferences"
});
if (!this.model.get('isPortalUser')) {
if ((this.getAcl().check('EmailAccountScope') && this.model.id == this.getUser().id) || this.getUser().isAdmin()) {
this.menu.buttons.push({
name: 'emailAccounts',
label: "Email Accounts",
style: 'default',
action: "emailAccounts"
});
}
if ((this.getAcl().check('EmailAccountScope') && this.model.id == this.getUser().id) || this.getUser().isAdmin()) {
this.menu.buttons.push({
name: 'emailAccounts',
label: "Email Accounts",
style: 'default',
action: "emailAccounts"
});
}
if (this.model.id == this.getUser().id && this.getAcl().checkScope('ExternalAccount')) {
this.menu.buttons.push({
name: 'externalAccounts',
label: 'External Accounts',
style: 'default',
action: "externalAccounts"
});
if (this.model.id == this.getUser().id && this.getAcl().checkScope('ExternalAccount')) {
this.menu.buttons.push({
name: 'externalAccounts',
label: 'External Accounts',
style: 'default',
action: "externalAccounts"
});
}
}
}
if (this.getAcl().checkScope('Calendar')) {
if (this.getAcl().checkScope('Calendar') && !this.model.get('isPortalUser')) {
var showActivities = this.getAcl().checkUserPermission(this.model);
if (!showActivities) {
if (this.getAcl().get('userPermission') === 'team') {
+5
View File
@@ -57,6 +57,11 @@ Espo.define('views/user/record/detail', 'views/record/detail', function (Dep) {
}
}
if (this.model.get('isPortalUser')) {
this.hidePanel('activities');
this.hidePanel('history');
}
if (this.model.id == this.getUser().id) {
this.listenTo(this.model, 'after:save', function () {
this.getUser().set(this.model.toJSON());

Some files were not shown because too many files have changed in this diff Show More