Compare commits

...

78 Commits
4.0.1 ... 4.0.5

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
yuri
e2deaf57dd fix portal account contact select acl 2016-03-03 13:02:10 +02:00
yuri
0530d9deb8 fix case compose email 2016-03-03 12:30:58 +02:00
yuri
b57ccf0c6a fix case assigned status 2016-03-03 12:27:01 +02:00
yuri
9ea9cf693d v 2016-03-03 12:19:44 +02:00
yuri
3460931fba fix portal windows issue 2016-03-03 12:19:05 +02:00
yuri
b743d113cc fix acl 2016-03-03 12:12:13 +02:00
yuri
f810371e70 fix tabbing 2016-03-03 12:12:07 +02:00
133 changed files with 789 additions and 320 deletions

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 %>',
]
}
},

View File

@@ -5,8 +5,8 @@
<rewrite>
<rules>
<rule name="rule 1G" stopProcessing="true">
<match url="^" />
<action type="Rewrite" url="index.php" appendQueryString="true" />
<match url="^" />
<action type="Rewrite" url="index.php" appendQueryString="true" />
</rule>
</rules>
</rewrite>

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

View File

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

View File

@@ -175,7 +175,7 @@ class Table
public function getLevel($scope, $action)
{
if (isset($this->data->table->$scope)) {
if (isset($this->table->$scope->$action)) {
if (isset($this->data->table->$scope->$action)) {
return $this->data->table->$scope->$action;
}
}

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

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)

View File

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

View File

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

View File

@@ -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": {

View File

@@ -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": {

View File

@@ -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}"

View File

@@ -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',

View File

@@ -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',

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(

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,

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');

View File

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

View File

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

View File

@@ -25,7 +25,7 @@
*
* 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.
************************************************************************/
************************************************************************/
namespace Espo\Modules\Crm\Controllers;
@@ -37,52 +37,52 @@ 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();
}
$dateFrom = $request->get('dateFrom');
$dateTo = $request->get('dateTo');
return $this->getService('Opportunity')->reportByLeadSource($dateFrom, $dateTo);
}
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();
}
$dateFrom = $request->get('dateFrom');
$dateTo = $request->get('dateTo');
return $this->getService('Opportunity')->reportByStage($dateFrom, $dateTo);
}
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();
}
$dateFrom = $request->get('dateFrom');
$dateTo = $request->get('dateTo');
return $this->getService('Opportunity')->reportSalesByMonth($dateFrom, $dateTo);
return $this->getService('Opportunity')->reportSalesByMonth($dateFrom, $dateTo);
}
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();
}
$dateFrom = $request->get('dateFrom');
$dateTo = $request->get('dateTo');
return $this->getService('Opportunity')->reportSalesPipeline($dateFrom, $dateTo);
}
}

View File

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

View File

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

View File

@@ -11,6 +11,12 @@
"scopeFieldLevel": {
"KnowledgeBaseArticle": {
"portals": false
},
"Case": {
"status": {
"read": "yes",
"edit": "no"
}
}
}
}

View File

@@ -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"
}
}

View File

@@ -12,7 +12,7 @@
{
"name":"activities",
"label":"Activities",
"view":"crm:views/record/panels/activities",
"view":"crm:views/case/record/panels/activities",
"aclScope": "Activities"
},
{

View File

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

View File

@@ -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": {

View File

@@ -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": {

View File

@@ -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",

View File

@@ -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": {

View File

@@ -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",

View File

@@ -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",

View File

@@ -25,7 +25,8 @@
"readOnly": true
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"parent": {
"type": "link"

View File

@@ -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",

View File

@@ -29,7 +29,8 @@
"required": true
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"parent": {
"type": "link"

View File

@@ -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",

View File

@@ -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": {

View File

@@ -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": {

View File

@@ -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": {

View File

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

View File

@@ -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"]
},

View File

@@ -3,7 +3,7 @@
"layouts": true,
"tab": true,
"acl": true,
"aclPortal": "recordAllAccountOwnNo",
"aclPortal": "recordAllAccountNo",
"module": "Crm",
"customizable": true,
"stream": true,

View File

@@ -3,7 +3,7 @@
"layouts":true,
"tab":true,
"acl":true,
"aclPortal": "recordAllAccountContactOwnNo",
"aclPortal": "recordAllAccountContactNo",
"module":"Crm",
"customizable": true,
"stream": true,

View File

@@ -52,5 +52,22 @@ class Account extends \Espo\Core\SelectManagers\Base
);
}
protected function accessPortalOnlyAccount(&$result)
{
$d = array();
$accountIdList = $this->getUser()->getLinkMultipleIdList('accounts');
if (count($accountIdList)) {
$result['whereClause'][] = array(
'id' => $accountIdList
);
} else {
$result['whereClause'][] = array(
'id' => null
);
}
}
}

View File

@@ -44,5 +44,22 @@ class Contact extends \Espo\Core\SelectManagers\Base
), $result);
}
protected function accessPortalOnlyContact(&$result)
{
$d = array();
$contactId = $this->getUser()->get('contactId');
if ($contactId) {
$result['whereClause'][] = array(
'id' => $contactId
);
} else {
$result['whereClause'][] = array(
'id' => null
);
}
}
}

View File

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

View File

@@ -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'])) {

View File

@@ -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'])) {

View File

@@ -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'])) {

View File

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

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

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;

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)) {

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()) {

View File

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

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'));

View File

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

View File

@@ -331,8 +331,8 @@
},
"options": {
"salutationName": {
"Mr.": "Hr.",
"Ms.": "Fr.",
"Mr.": "Herr",
"Ms.": "Frau",
"Mrs.": "Frl.",
"Dr.": "Dr."
},

View File

@@ -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."
}
}

View File

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

View File

@@ -1,9 +1,11 @@
[
"teams",
"createdAt",
"emailAddress",
"title",
"isAdmin",
"isActive",
"portals",
"accounts"
"accounts",
"contact"
]

View File

@@ -17,6 +17,7 @@
"detail": "views/email/modals/detail",
"compose": "views/modals/compose-email"
},
"quickCreateModalType": "compose",
"menu": {
"list": {
"buttons": [

View File

@@ -14,5 +14,8 @@
"active",
"activePortal"
],
"boolFilterList": ["onlyMyTeam"]
"boolFilterList": ["onlyMyTeam"],
"selectDefaultFilters": {
"filter": "active"
}
}

View File

@@ -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",

View File

@@ -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": {

View File

@@ -91,8 +91,7 @@
"trim": true
},
"smtpServer": {
"type": "varchar",
"required": true
"type": "varchar"
},
"smtpPort": {
"type": "int",

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

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

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

View File

@@ -421,6 +421,7 @@ class InboundEmail extends \Espo\Services\Record
if ($user) {
$case->set('assignedUserId', $user->id);
$case->set('status', 'Assigned');
}
}
@@ -437,6 +438,7 @@ class InboundEmail extends \Espo\Services\Record
if ($user) {
$case->set('assignedUserId', $user->id);
$case->set('status', 'Assigned');
}
}
@@ -468,19 +470,17 @@ class InboundEmail extends \Espo\Services\Record
$caseDistribution = $params['caseDistribution'];
}
$targetUserPosition = null;
if (!empty($params['targetUserPosition'])) {
$targetUserPosition = $params['targetUserPosition'];
}
$case->set('status', 'Assigned');
switch ($caseDistribution) {
case 'Direct-Assignment':
if ($userId) {
$case->set('assignedUserId', $userId);
$case->set('status', 'Assigned');
}
break;
case 'Round-Robin':

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)) {

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

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

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)) {

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');

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

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

View File

@@ -24,31 +24,33 @@
*
* 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.Case.Record.Panels.Activities', 'Crm:Views.Record.Panels.Activities', function (Dep) {
Espo.define('crm:views/case/record/panels/activities', 'crm:views/record/panels/activities', function (Dep) {
return Dep.extend({
getComposeEmailAttributes: function (data, callback) {
data = data || {};
var attributes = {
status: 'Draft',
name: '[#' + this.model.get('number') + '] ' + this.model.get('name')
};
if (this.model.get('contactId')) {
this.getModelFactory().create('Contact', function (contact) {
contact.id = this.model.get('contactId');
this.listenToOnce(contact, 'sync', function () {
var emailAddress = contact.get('emailAddress');
var emailAddress = contact.get('emailAddress');
if (emailAddress) {
attributes.to = emailAddress;
attributes.nameHash = {};
attributes.nameHash[emailAddress] = contact.get('name');
}
callback.call(this, attributes);
});
});
contact.fetch({
error: function () {
callback.call(this, attributes);
@@ -58,8 +60,7 @@ Espo.define('Crm:Views.Case.Record.Panels.Activities', 'Crm:Views.Record.Panels.
} else {
callback.call(this, attributes);
}
},
}
});
});

View File

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

View File

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

View File

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

View File

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

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>

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>

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}}

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>

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}}

View File

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

View File

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

View File

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

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;

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',

View File

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

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;

View File

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

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