Compare commits

...

21 Commits
4.2.4 ... 4.2.5

Author SHA1 Message Date
yuri
0ea0c09007 fix acl 2016-09-13 13:12:39 +03:00
yuri
d69f994f4c fix insert template issue with signature 2016-09-13 10:28:24 +03:00
yuri
7a2a9de174 Merge branch 'hotfix/4.2.5' of ssh://172.20.0.1/var/git/espo/backend into hotfix/4.2.5 2016-09-12 11:17:15 +03:00
Taras Machyshyn
7d2655f757 Fixed warnings on PHP 7 2016-09-07 15:04:06 +03:00
yuri
e58a4c4bbf fix stream status update message 2016-09-02 12:43:26 +03:00
yuri
8432e9dcc8 fix endWidth search 2016-08-30 13:05:41 +03:00
yuri
76602aede1 email import: fix for emails w/o subject header 2016-08-25 11:45:56 +03:00
Ayman Alkom
77411702a7 remove repeated key (#205) 2016-08-25 10:44:29 +03:00
yuri
84e587fcaf mass email: automatically fill name 2016-08-24 10:49:53 +03:00
yuri
f8e75dccdf version 2016-08-23 15:41:32 +03:00
yuri
b6eca1db17 fix email entityDefs 2016-08-23 15:39:00 +03:00
yuri
6ff414ffcd fix users teams field 2016-08-23 15:26:00 +03:00
yuri
7acbf3084d template: related attributes 2016-08-23 12:05:29 +03:00
yuri
87847446a8 css cleanup 2016-08-23 11:18:20 +03:00
yuri
59f250b386 allow template entity 2016-08-23 11:17:39 +03:00
yuri
f93ce594d0 add mobile phone type to account 2016-08-23 11:13:58 +03:00
yuri
c41f4e51e5 fix filter fields css 2016-08-23 11:01:17 +03:00
yuri
6efd355864 remove tabs 2016-08-23 10:11:37 +03:00
Ayman Alkom
7ee2ee9d35 small syntax fixes (#197)
* fix variable name

* init $number variable

* another fix
2016-08-23 10:09:15 +03:00
yuri
1f8a14aca0 fix warning 2016-08-22 15:50:21 +03:00
yuri
f518ae59c0 activities small refactoring 2016-08-22 12:27:18 +03:00
24 changed files with 192 additions and 68 deletions

View File

@@ -94,17 +94,17 @@ class Extension extends \Espo\Core\Controllers\Record
return true;
}
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();
}
@@ -139,12 +139,12 @@ class Extension 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

@@ -71,7 +71,10 @@ class Importer
$email->set('isBeingImported', true);
$subject = $message->subject;
$subject = '';
if (isset($message->subject)) {
$subject = $message->subject;
}
if (!empty($subject) && is_string($subject)) {
$subject = trim($subject);
}
@@ -151,7 +154,7 @@ class Importer
$duplicate->set('isBeingImported', true);
$this->getEntityManager()->saveEntity($duplicate);
$this->getEntityManager()->saveEntity($duplicate);
if (!empty($teamsIdList)) {
foreach ($teamsIdList as $teamId) {
@@ -168,8 +171,8 @@ class Importer
$email->set('dateSent', $dateSent);
}
} else {
$email->set('dateSent', date('Y-m-d H:i:s'));
}
$email->set('dateSent', date('Y-m-d H:i:s'));
}
if (isset($message->deliveryDate)) {
$dt = new \DateTime($message->deliveryDate);
if ($dt) {
@@ -233,6 +236,7 @@ class Importer
$reference = str_replace(array('/', '@'), " ", trim($reference, '<>'));
$parentType = $parentId = null;
$emailSent = PHP_INT_MAX;
$number = null;
$n = sscanf($reference, '%s %s %d %d espo', $parentType, $parentId, $emailSent, $number);
if ($n == 4 && $emailSent < time()) {
if (!empty($parentType) && !empty($parentId)) {
@@ -324,15 +328,15 @@ class Importer
$email->set('parentId', $account->id);
return true;
} else {
$lead = $this->getEntityManager()->getRepository('Lead')->where(array(
'emailAddress' => $emailAddress
))->findOne();
if ($lead) {
$email->set('parentType', 'Lead');
$email->set('parentId', $lead->id);
return true;
}
}
$lead = $this->getEntityManager()->getRepository('Lead')->where(array(
'emailAddress' => $emailAddress
))->findOne();
if ($lead) {
$email->set('parentType', 'Lead');
$email->set('parentId', $lead->id);
return true;
}
}
}
}

View File

@@ -169,20 +169,22 @@ class AclManager extends \Espo\Core\AclManager
return parent::get($user, $permission);
}
public function checkReadOnlyTeam(User $user, $permission)
public function checkReadOnlyTeam(User $user, $scope)
{
if ($this->checkUserIsNotPortal($user)) {
return $this->getMainManager()->checkReadOnlyTeam($user, $permission);
$data = $this->getTable($user)->getScopeData($scope);
return $this->getMainManager()->checkReadOnlyTeam($user, $data);
}
return false;
return parent::checkReadOnlyTeam($user, $scope);
}
public function checkReadOnlyOwn(User $user, $permission)
public function checkReadOnlyOwn(User $user, $scope)
{
if ($this->checkUserIsNotPortal($user)) {
return $this->getMainManager()->checkReadOnlyOwn($user, $permission);
$data = $this->getTable($user)->getScopeData($scope);
return $this->getMainManager()->checkReadOnlyOwn($user, $data);
}
return false;
return parent::checkReadOnlyOwn($user, $scope);
}
public function check(User $user, $subject, $action = null)

View File

@@ -919,7 +919,7 @@ class Base
$part[$item['field'] . '*'] = $item['value'] . '%';
break;
case 'endsWith':
$part[$item['field'] . '*'] = $item['value'] . '%';
$part[$item['field'] . '*'] = '%' . $item['value'];
break;
case 'contains':
$part[$item['field'] . '*'] = '%' . $item['value'] . '%';

View File

@@ -81,7 +81,7 @@ class Meeting extends \Espo\Core\ORM\Repositories\RDB
}
if ($entity->isNew()) {
$currentUserId = $this->getEntityManager()->getUser()->id;
if (in_array($currentUserId, $usersIds)) {
if (isset($usersIds) && in_array($currentUserId, $usersIds)) {
$usersColumns = $entity->get('usersColumns');
if (empty($usersColumns)) {
$usersColumns = new \StdClass();

View File

@@ -3,7 +3,9 @@
"label": "",
"rows": [
[
{"name": "name"},
{"name": "name"}
],
[
{"name": "status"}
],
[

View File

@@ -13,7 +13,7 @@
},
"phoneNumber": {
"type": "phone",
"typeList": ["Office", "Fax", "Other"],
"typeList": ["Office", "Mobile", "Fax", "Other"],
"defaultType": "Office"
},
"type": {

View File

@@ -9,5 +9,6 @@
"importable": true,
"notifications": true,
"calendar": true,
"activity": true,
"object": true
}

View File

@@ -9,5 +9,6 @@
"importable": true,
"notifications": true,
"calendar": true,
"activity": true,
"object": true
}

View File

@@ -668,6 +668,12 @@ class Activities extends \Espo\Core\Services\Base
$fetchAll = empty($params['scope']);
if (!$fetchAll) {
if (!$this->getMetadata()->get(['scopes', $params['scope'], 'activity'])) {
throw new Error('Entity \'' . $params['scope'] . '\' is not an activity');
}
}
$parts = array();
if ($this->getAcl()->checkScope('Meeting')) {
$parts['Meeting'] = ($fetchAll || $params['scope'] == 'Meeting') ? $this->getMeetingQuery($entity, 'NOT IN', ['Held', 'Not Held']) : [];
@@ -675,6 +681,7 @@ class Activities extends \Espo\Core\Services\Base
if ($this->getAcl()->checkScope('Call')) {
$parts['Call'] = ($fetchAll || $params['scope'] == 'Call') ? $this->getCallQuery($entity, 'NOT IN', ['Held', 'Not Held']) : [];
}
return $this->getResultFromQueryParts($parts, $scope, $id, $params);
}
@@ -689,6 +696,12 @@ class Activities extends \Espo\Core\Services\Base
$fetchAll = empty($params['scope']);
if (!$fetchAll) {
if (!$this->getMetadata()->get(['scopes', $params['scope'], 'activity'])) {
throw new Error('Entity \'' . $params['scope'] . '\' is not an activity');
}
}
$parts = array();
if ($this->getAcl()->checkScope('Meeting')) {
$parts['Meeting'] = ($fetchAll || $params['scope'] == 'Meeting') ? $this->getMeetingQuery($entity, 'IN', ['Held', 'Not Held']) : [];

View File

@@ -45,7 +45,7 @@ class Email extends \Espo\Core\ORM\Repositories\RDB
return;
}
$eaRepositoty = $this->getEntityManager()->getRepository('EmailAddress');
$eaRepository = $this->getEntityManager()->getRepository('EmailAddress');
$address = $entity->get($type);
$idList = [];
@@ -54,7 +54,7 @@ class Email extends \Espo\Core\ORM\Repositories\RDB
return trim($e);
}, explode(';', $address));
$idList = $eaRepositoty->getIdListFormAddressList($arr);
$idList = $eaRepository->getIdListFormAddressList($arr);
foreach ($idList as $id) {
$this->addUserByEmailAddressId($entity, $id, $addAssignedUser);
}
@@ -124,7 +124,7 @@ class Email extends \Espo\Core\ORM\Repositories\RDB
protected function beforeSave(Entity $entity, array $options = array())
{
$eaRepositoty = $this->getEntityManager()->getRepository('EmailAddress');
$eaRepository = $this->getEntityManager()->getRepository('EmailAddress');
if ($entity->has('attachmentsIds')) {
$attachmentsIds = $entity->get('attachmentsIds');
@@ -141,7 +141,7 @@ class Email extends \Espo\Core\ORM\Repositories\RDB
if ($entity->has('from')) {
$from = trim($entity->get('from'));
if (!empty($from)) {
$ids = $eaRepositoty->getIds(array($from));
$ids = $eaRepository->getIds(array($from));
if (!empty($ids)) {
$entity->set('fromEmailAddressId', $ids[0]);
$this->addUserByEmailAddressId($entity, $ids[0], true);

View File

@@ -51,7 +51,6 @@
"ldapUserFirstNameAttribute": "User First Name Attribute",
"ldapUserLastNameAttribute": "User Last Name Attribute",
"ldapUserEmailAddressAttribute": "User Email Address Attribute",
"ldapUserPhoneNumberAttribute": "User Phone Number Attribute",
"ldapUserTeams": "User Teams",
"ldapUserDefaultTeam": "User Default Team",
"ldapUserPhoneNumberAttribute": "User Phone Number Attribute",

View File

@@ -140,7 +140,7 @@
},
"fromEmailAddress": {
"type": "link",
"view": "views/fields/from-email-address"
"view": "views/email/fields/from-email-address"
},
"toEmailAddresses": {
"type": "linkMultiple"

View File

@@ -6,5 +6,6 @@
"aclPortal": "recordAllAccountContactOwnNo",
"notifications": true,
"object": true,
"customizable": true
"customizable": true,
"activity": true
}

View File

@@ -1,8 +1,8 @@
{
"entity": false,
"entity": true,
"layouts": false,
"tab": false,
"acl": "recordAllTeamNo",
"customizable": false,
"customizable": true,
"disabled": true
}

View File

@@ -36,10 +36,18 @@ Espo.define('crm:views/campaign/detail', 'views/detail', function (Dep) {
'targetListsIds': 'targetListsIds',
'targetListsNames': 'targetListsNames',
'excludingTargetListsIds': 'excludingTargetListsIds',
'excludingTargetListsNames': 'excludingTargetListsNames'
'excludingTargetListsNames': 'excludingTargetListsNames',
},
},
relatedAttributeFunctions: {
'massEmails': function () {
return {
name: this.model.get('name') + ' ' + this.getDateTime().getToday()
};
}
}
});
});

View File

@@ -49,7 +49,10 @@ Espo.define('views/email/record/compose', ['views/record/edit', 'views/email/rec
}
this.listenTo(this.model, 'insert-template', function (data) {
var body = this.appendSignature(data.body || '', data.isHtml);
var body = data.body;
if (this.hasSignature()) {
body = this.appendSignature(body || '', data.isHtml);
}
this.model.set('isHtml', data.isHtml);
this.model.set('name', data.subject);
this.model.set('body', '');
@@ -98,7 +101,7 @@ Espo.define('views/email/record/compose', ['views/record/edit', 'views/email/rec
},
getSignature: function () {
return this.getPreferences().get('signature');
return this.getPreferences().get('signature') || '';
},
getPlainTextSignature: function () {

View File

@@ -117,7 +117,7 @@ Espo.define('views/fields/link-multiple-with-role', 'views/fields/link-multiple'
},
getJQSelect: function (id, roleValue) {
$role = $('<select class="role form-control input-sm pull-right" data-id="'+id+'">');
var $role = $('<select class="role form-control input-sm pull-right" data-id="'+id+'">');
this.roleList.forEach(function (role) {
var selectedHtml = (role == roleValue) ? 'selected': '';
option = '<option value="'+role+'" '+selectedHtml+'>' + this.getLanguage().translateOption(role, this.roleField, this.roleFieldScope) + '</option>';
@@ -155,7 +155,9 @@ Espo.define('views/fields/link-multiple-with-role', 'views/fields/link-multiple'
'width': '92%',
'display': 'inline-block'
});
$left.append($role);
if ($role) {
$left.append($role);
}
$left.append(nameHtml);
$el.append($left);
@@ -171,19 +173,22 @@ Espo.define('views/fields/link-multiple-with-role', 'views/fields/link-multiple'
$container.append($el);
if (this.mode == 'edit') {
var fetch = function ($target) {
var value = $target.val().toString().trim();
var id = $target.data('id');
this.columns[id] = this.columns[id] || {};
this.columns[id][this.columnName] = value;
}.bind(this);
$role.on('change', function (e) {
var $target = $(e.currentTarget);
fetch($target);
this.trigger('change');
}.bind(this));
fetch($role);
if ($role) {
var fetch = function ($target) {
if (!$target || !$target.size()) return;
var value = $target.val().toString().trim();
var id = $target.data('id');
this.columns[id] = this.columns[id] || {};
this.columns[id][this.columnName] = value;
}.bind(this);
$role.on('change', function (e) {
var $target = $(e.currentTarget);
fetch($target);
this.trigger('change');
}.bind(this));
fetch($role);
}
}
return $el;
},

View File

@@ -26,11 +26,11 @@
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
Espo.define('Views.Stream.Notes.Status', 'Views.Stream.Note', function (Dep) {
Espo.define('views/stream/notes/status', 'views/stream/note', function (Dep) {
return Dep.extend({
template: 'stream.notes.status',
template: 'stream/notes/status',
messageName: 'status',
@@ -58,7 +58,7 @@ Espo.define('Views.Stream.Notes.Status', 'Views.Stream.Note', function (Dep) {
this.statusText = this.getLanguage().translateOption(value, field, this.model.get('parentType'));
this.messageData['field'] = this.translate(field, 'fields', this.model.name).toLowerCase();
this.messageData['field'] = this.translate(field, 'fields', this.model.get('parentType')).toLowerCase();
this.createMessage();
},

View File

@@ -55,17 +55,17 @@ Espo.define('views/template/fields/variables', 'views/fields/base', function (De
},
setup: function () {
this.setupFieldList();
this.setupAttributeList();
this.setupTranslatedOptions();
this.listenTo(this.model, 'change:entityType', function () {
this.setupFieldList();
if (this.isRendered()) {
this.reRender();
}
this.setupAttributeList();
this.setupTranslatedOptions();
this.reRender();
}, this);
},
setupFieldList: function () {
setupAttributeList: function () {
var entityType = this.model.get('entityType');
var attributeList = this.getFieldManager().getEntityAttributes(entityType) || [];
@@ -85,6 +85,57 @@ Espo.define('views/template/fields/variables', 'views/fields/base', function (De
attributeList.forEach(function (item) {
this.translatedOptions[item] = this.translate(item, 'fields', entityType);
}, this);
var links = this.getMetadata().get('entityDefs.' + entityType + '.links') || {};
var linkList = Object.keys(links).sort(function (v1, v2) {
return this.translate(v1, 'links', entityType).localeCompare(this.translate(v2, 'links', entityType));
}.bind(this));
linkList.forEach(function (link) {
var type = links[link].type
if (type != 'belongsTo') return;
var scope = links[link].entity;
if (!scope) return;
var attributeList = this.getFieldManager().getEntityAttributes(scope) || [];
attributeList.push('id');
if (this.getMetadata().get('entityDefs.' + scope + '.fields.name.type') == 'personName') {
attributeList.unshift('name');
};
attributeList.sort(function (v1, v2) {
return this.translate(v1, 'fields', scope).localeCompare(this.translate(v2, 'fields', scope));
}.bind(this));
attributeList.forEach(function (item) {
this.attributeList.push(link + '.' + item);
}, this);
}, this);
return this.attributeList;
},
setupTranslatedOptions: function () {
this.translatedOptions = {};
var entityType = this.model.get('entityType');
this.attributeList.forEach(function (item) {
var field = item;
var scope = entityType;
var isForeign = false;
if (~item.indexOf('.')) {
isForeign = true;
field = item.split('.')[1];
var link = item.split('.')[0];
scope = this.getMetadata().get('entityDefs.' + entityType + '.links.' + link + '.entity');
}
this.translatedOptions[item] = this.translate(field, 'fields', scope);
if (isForeign) {
this.translatedOptions[item] = this.translate(link, 'links', entityType) + '.' + this.translatedOptions[item];
}
}, this);
},
afterRender: function () {

View File

@@ -37,8 +37,8 @@ Espo.define('views/user/fields/teams', 'views/fields/link-multiple-with-role', f
this.loadRoleList(function () {
if (this.mode == 'edit') {
if (this.isRendered()) {
this.render();
if (this.isRendered() || this.isBeingRendered()) {
this.reRender();
}
}
}, this);
@@ -53,7 +53,7 @@ Espo.define('views/user/fields/teams', 'views/fields/link-multiple-with-role', f
}, this);
if (toLoad) {
this.loadRoleList(function () {
this.render();
this.reRender();
}, this);
}
}, this);
@@ -99,7 +99,15 @@ Espo.define('views/user/fields/teams', 'views/fields/link-multiple-with-role', f
},
getJQSelect: function (id, roleValue) {
var roleList = Espo.Utils.clone((this.roleListMap[id] || []));
if (!roleList.length) {
return;
};
if (roleList.length || roleValue) {
$role = $('<select class="role form-control input-sm pull-right" data-id="'+id+'">');

View File

@@ -323,7 +323,24 @@ ul.dropdown-menu > li.checkbox:last-child {
margin-bottom: 1px;
}
.field .link-container .list-group-item .form-control {
.filter > .form-group .field {
.link-container {
font-size: @font-size-small;
}
.input-group {
input {
font-size: @font-size-small;
height: @input-height-small;
}
button.btn {
font-size: @font-size-small;
height: @input-height-small;
}
}
}
.field .link
-container .list-group-item .form-control {
width: 140px !important;
}

View File

@@ -293,3 +293,12 @@
opacity: @selectize-opacity-disabled;
background-color: @selectize-color-disabled;
}
.filter > .form-group .field {
.selectize-control {
.selectize-input {
font-size: @font-size-small;
padding: 4px 5px 0px;
}
}
}

View File

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