Merge branch 'master' of ssh://172.20.0.1/var/git/espo/backend

This commit is contained in:
Taras Machyshyn
2018-06-26 18:02:05 +03:00
29 changed files with 134 additions and 62 deletions
+9 -1
View File
@@ -100,10 +100,10 @@ class Htmlizer
$forbidenAttributeList = $this->getAcl()->getScopeForbiddenAttributeList($entity->getEntityType(), 'read');
}
foreach ($fieldList as $field) {
if (in_array($field, $forbidenAttributeList)) continue;
$type = $entity->getAttributeType($field);
if ($type == Entity::DATETIME) {
@@ -219,6 +219,14 @@ class Htmlizer
return number_format($number, $decimals, $decimalPoint, $thousandsSeparator);
}
return '';
},
'var' => function ($context, $options) {
if ($context && isset($context[0]) && isset($context[1])) {
if (isset($context[1][$context[0]])) {
return $context[1][$context[0]];
}
}
return;
}
],
'hbhelpers' => [
+4
View File
@@ -205,6 +205,10 @@ class Importer
))->findOne();
if ($replied) {
$email->set('repliedId', $replied->id);
$repliedTeamIdList = $replied->getLinkMultipleIdList('teams');
foreach ($repliedTeamIdList as $repliedTeamId) {
$email->addLinkMultipleId('teams', $repliedTeamId);
}
}
}
+21 -4
View File
@@ -1504,7 +1504,7 @@ class Base
);
}
public function getFullTextSearchDataForTextFilter($textFilter, $stripWildcard = false)
public function getFullTextSearchDataForTextFilter($textFilter, $isAuxiliaryUse = false)
{
if (array_key_exists($textFilter, $this->fullTextSearchDataCacheHash)) {
return $this->fullTextSearchDataCacheHash[$textFilter];
@@ -1518,7 +1518,7 @@ class Base
$fieldList = $this->getTextFilterFieldList();
if ($stripWildcard) {
if ($isAuxiliaryUse) {
$textFilter = str_replace('%', '', $textFilter);
}
@@ -1562,6 +1562,8 @@ class Base
if ($useFullTextSearch) {
if (
$isAuxiliaryUse
||
mb_strpos($textFilter, ' ') === false
&&
mb_strpos($textFilter, '+') === false
@@ -1644,14 +1646,21 @@ class Base
$attributeType = $fieldDefs[$field]['type'];
}
if ($attributeType === 'int') {
if (is_numeric($textFilter)) {
$group[$field] = intval($textFilter);
}
continue;
}
if (!$skipWidlcards) {
if (
strlen($textFilter) >= $textFilterContainsMinLength
mb_strlen($textFilter) >= $textFilterContainsMinLength
&&
(
$attributeType == 'text'
||
!empty($this->textFilterUseContainsAttributeList[$field])
in_array($field, $this->textFilterUseContainsAttributeList)
||
$attributeType == 'varchar' && $this->getConfig()->get('textFilterUseContainsForVarchar')
)
@@ -1679,6 +1688,10 @@ class Base
$group[$field . '*'] = $expression;
}
if (!$forceFullTextSearch) {
$this->applyAdditionalToTextFilterGroup($textFilter, $group);
}
if (!empty($fullTextGroup)) {
$group['AND'] = $fullTextGroup;
}
@@ -1694,6 +1707,10 @@ class Base
];
}
protected function applyAdditionalToTextFilterGroup($textFilter, &$group)
{
}
public function applyAccess(&$result)
{
$this->prepareResult($result);
@@ -43,11 +43,11 @@ class HasMany extends Base
$entityName => array (
'fields' => array(
$linkName.'Ids' => array(
'type' => 'varchar',
'type' => 'jsonArray',
'notStorable' => true,
),
$linkName.'Names' => array(
'type' => 'varchar',
'type' => 'jsonObject',
'notStorable' => true,
),
),
@@ -50,11 +50,11 @@ class ManyMany extends Base
$entityName => array(
'fields' => array(
$linkName.'Ids' => array(
'type' => 'varchar',
'type' => 'jsonArray',
'notStorable' => true,
),
$linkName.'Names' => array(
'type' => 'varchar',
'type' => 'jsonObject',
'notStorable' => true,
),
),
+1 -1
View File
@@ -170,7 +170,7 @@ return array (
'inlineAttachmentUploadMaxSize' => 20,
'textFilterUseContainsForVarchar' => false,
'tabColorsDisabled' => false,
'massPrintPdfMaxCount' => 100,
'massPrintPdfMaxCount' => 50,
'isInstalled' => false
);
@@ -166,7 +166,8 @@
},
"collection": {
"sortBy": "number",
"asc": false
"asc": false,
"textFilterFields": ["name", "number"]
},
"indexes": {
"status": {
+2 -1
View File
@@ -336,7 +336,7 @@ abstract class Base
}
$columns = substr($rest, 0, $delimiterPosition);
$query = substr($rest, $delimiterPosition + 1);
$query = mb_substr($rest, $delimiterPosition + 1);
$columnList = explode(',', $columns);
@@ -837,6 +837,7 @@ abstract class Base
if (empty($isComplex)) {
if (!isset($entity->fields[$field])) {
$whereParts[] = '0';
continue;
}
@@ -340,6 +340,7 @@
"children": "Children",
"id": "ID",
"ids": "IDs",
"type": "Type",
"names": "Names",
"targetListIsOptedOut": "Is Opted Out (Target List)"
},
@@ -35,7 +35,8 @@
"layoutListDisabled": true,
"provider": "Google",
"height": 300,
"exportDisabled": true
"exportDisabled": true,
"importDisabled": true
}
},
"notMergeable":true,
@@ -8,5 +8,6 @@
"autoincrement":true,
"unique":true
},
"textFilter": true,
"readOnly": true
}
@@ -33,7 +33,8 @@
},
"converted":{
"type":"currencyConverted",
"readOnly": true
"readOnly": true,
"importDisabled": true
}
},
"filter": true,
@@ -27,5 +27,6 @@
"fieldDefs":{
"notStorable":true
},
"textFilter": true,
"personalData": true
}
@@ -31,5 +31,6 @@
}
],
"filter": true,
"textFilter": true,
"personalData": true
}
@@ -29,5 +29,6 @@
"unique": false
},
"hookClassName": "\\Espo\\Core\\Utils\\FieldManager\\Hooks\\NumberType",
"textFilter": true,
"readOnly": true
}
@@ -30,6 +30,7 @@
"filter":true,
"skipOrmDefs": true,
"personalData": true,
"textFilter": true,
"fullTextSearch": true,
"fullTextSearchColumnList": [
"first",
@@ -26,5 +26,6 @@
"notStorable":true
},
"translatedOptions": true,
"textFilter": true,
"personalData": true
}
@@ -38,5 +38,6 @@
],
"filter": true,
"personalData": true,
"textFilter": true,
"fullTextSearch": true
}
@@ -29,5 +29,6 @@
],
"filter": true,
"personalData": true,
"textFilter": true,
"fullTextSearch": true
}
@@ -36,5 +36,6 @@
"type":"text"
},
"personalData": true,
"textFilter": true,
"fullTextSearch": true
}
+3 -15
View File
@@ -270,28 +270,16 @@ class Email extends \Espo\Core\SelectManagers\Base
);
}
protected function textFilter($textFilter, &$result)
protected function applyAdditionalToTextFilterGroup($textFilter, &$group)
{
$d = array();
$d['name*'] = '%' . $textFilter . '%';
if (strlen($textFilter) >= self::MIN_LENGTH_FOR_CONTENT_SEARCH) {
$d['bodyPlain*'] = '%' . $textFilter . '%';
$d['body*'] = '%' . $textFilter . '%';
$emailAddressId = $this->getEmailAddressIdByValue($textFilter);
if ($emailAddressId) {
$this->leftJoinEmailAddress($result);
$d['fromEmailAddressId'] = $emailAddressId;
$d['emailEmailAddress.emailAddressId'] = $emailAddressId;
$group['fromEmailAddressId'] = $emailAddressId;
$group['emailEmailAddress.emailAddressId'] = $emailAddressId;
}
}
$result['whereClause'][] = array(
'OR' => $d
);
}
protected function getEmailAddressIdByValue($value)
+7
View File
@@ -2168,12 +2168,19 @@ class Record extends \Espo\Core\Services\Base
if (!empty($params['sortBy'])) {
$sortByField = $params['sortBy'];
$sortByFieldType = $this->getMetadata()->get(['entityDefs', $this->getEntityType(), 'fields', $sortByField, 'type']);
if ($sortByFieldType === 'currency') {
if (!in_array($sortByField . 'Converted', $attributeList)) {
$attributeList[] = $sortByField . 'Converted';
}
}
$sortByAttributeList = $this->getFieldManagerUtil()->getAttributeList($this->getEntityType(), $sortByField);
foreach ($sortByAttributeList as $attribute) {
if (!in_array($attribute, $attributeList) && $seed->hasAttribute($attribute)) {
$attributeList[] = $attribute;
}
}
}
foreach ($this->mandatorySelectAttributeList as $attribute) {
@@ -36,7 +36,8 @@ Espo.define('crm:views/record/row-actions/activities', 'views/record/row-actions
label: 'View',
data: {
id: this.model.id
}
},
link: '#' + this.model.name + '/view/' + this.model.id
}];
if (this.options.acl.edit) {
list.push({
@@ -44,7 +45,8 @@ Espo.define('crm:views/record/row-actions/activities', 'views/record/row-actions
label: 'Edit',
data: {
id: this.model.id
}
},
link: '#' + this.model.name + '/edit/' + this.model.id
});
if (this.model.name == 'Meeting' || this.model.name == 'Call') {
list.push({
@@ -36,7 +36,8 @@ Espo.define('crm:views/record/row-actions/history', 'views/record/row-actions/re
label: 'View',
data: {
id: this.model.id
}
},
link: '#' + this.model.name + '/view/' + this.model.id
}];
if (this.model.name == 'Email') {
list.push({
@@ -54,7 +55,8 @@ Espo.define('crm:views/record/row-actions/history', 'views/record/row-actions/re
label: 'Edit',
data: {
id: this.model.id
}
},
link: '#' + this.model.name + '/edit/' + this.model.id
}
]);
}
@@ -36,7 +36,8 @@ Espo.define('crm:views/record/row-actions/tasks', 'views/record/row-actions/rela
label: 'View',
data: {
id: this.model.id
}
},
link: '#' + this.model.name + '/view/' + this.model.id
}];
if (this.options.acl.edit) {
list.push({
@@ -44,7 +45,8 @@ Espo.define('crm:views/record/row-actions/tasks', 'views/record/row-actions/rela
label: 'Edit',
data: {
id: this.model.id
}
},
link: '#' + this.model.name + '/edit/' + this.model.id
});
if (!~['Completed', 'Canceled'].indexOf(this.model.get('status'))) {
+10
View File
@@ -161,6 +161,16 @@ Espo.define('email-helper', [], function () {
attributes['parentType'] = model.get('parentType');
}
if (model.get('teamsIds') && model.get('teamsIds').length) {
attributes.teamsIds = Espo.Utils.clone(model.get('teamsIds'));
attributes.teamsNames = Espo.Utils.clone(model.get('teamsNames') || {});
if (this.user.get('defaultTeamId')) {
attributes.teamsIds.push(this.user.get('defaultTeamId'));
attributes.teamsNames[this.user.get('defaultTeamId')] = this.user.get('defaultTeamName');
}
}
attributes.nameHash = nameHash;
attributes.repliedId = model.id;
@@ -280,9 +280,8 @@ Espo.define('views/admin/entity-manager/modals/edit-entity', ['views/modal', 'mo
});
var optionList = Object.keys(fieldDefs).filter(function (item) {
if (!~['varchar', 'wysiwyg', 'text', 'phone', 'email', 'personName', 'number'].indexOf(this.getMetadata().get(['entityDefs', scope, 'fields', item, 'type']))) {
return false;
}
var fieldType = fieldDefs[item].type;
if (!this.getMetadata().get(['fields', fieldType, 'textFilter'])) return false
if (this.getMetadata().get(['entityDefs', scope, 'fields', item, 'disabled'])) {
return false;
}
+14 -3
View File
@@ -166,7 +166,7 @@ Espo.define('views/import/step2', 'view', function (Dep) {
for (var field in defs) {
var d = defs[field];
if (!~this.allowedFieldList.indexOf(field) && (d.readOnly || d.disabled || d.importDisabled)) {
if (!~this.allowedFieldList.indexOf(field) && (d.disabled || d.importDisabled)) {
continue;
}
fieldList.push(field);
@@ -187,7 +187,7 @@ Espo.define('views/import/step2', 'view', function (Dep) {
for (var field in fields) {
var d = fields[field];
if (!~this.allowedFieldList.indexOf(field) && (((d.readOnly || d.disabled) && !d.importNotDisabled) || d.importDisabled)) {
if (!~this.allowedFieldList.indexOf(field) && (((d.disabled) && !d.importNotDisabled) || d.importDisabled)) {
continue;
}
@@ -260,6 +260,11 @@ Espo.define('views/import/step2', 'view', function (Dep) {
if (this.getMetadata().get(['entityDefs', scope, 'fields', baseField])) {
label = this.translate(baseField, 'fields', scope) + ' (' + this.translate('name', 'fields') + ')';
}
} else if (field.indexOf('Type') === field.length - 4) {
var baseField = field.substr(0, field.length - 4);
if (this.getMetadata().get(['entityDefs', scope, 'fields', baseField])) {
label = this.translate(baseField, 'fields', scope) + ' (' + this.translate('type', 'fields') + ')';
}
} else if (field.indexOf('phoneNumber') === 0) {
var phoneNumberType = field.substr(11);
var phoneNumberTypeLabel = this.getLanguage().translateOption(phoneNumberType, 'phoneNumber', scope);
@@ -300,7 +305,13 @@ Espo.define('views/import/step2', 'view', function (Dep) {
$('#default-values-container').append(html);
var type = Espo.Utils.upperCaseFirst(this.model.getFieldParam(name, 'type'));
this.createView(name, this.getFieldManager().getViewName(type), {
var viewName =
this.getMetadata().get(['entityDefs', this.scope, 'fields', name, 'view'])
||
this.getFieldManager().getViewName(type);
this.createView(name, viewName, {
model: this.model,
el: this.getSelector() + ' .field[data-name="' + name + '"]',
defs: {
+29 -21
View File
@@ -143,26 +143,7 @@ Espo.define('views/record/list', 'view', function (Dep) {
}
},
'click .select-all': function (e) {
this.checkedList = [];
if (e.currentTarget.checked) {
this.$el.find('input.record-checkbox').prop('checked', true);
this.$el.find('.actions-button').removeAttr('disabled');
this.collection.models.forEach(function (model) {
this.checkedList.push(model.id);
}, this);
this.$el.find('.list > table tbody tr').addClass('active');
} else {
if (this.allResultIsChecked) {
this.unselectAllResult();
}
this.$el.find('input.record-checkbox').prop('checked', false);
this.$el.find('.actions-button').attr('disabled', true);
this.$el.find('.list > table tbody tr').removeClass('active');
}
this.trigger('check');
this.selectAllHandler(e.currentTarget.checked);
},
'click .action': function (e) {
var $el = $(e.currentTarget);
@@ -190,6 +171,30 @@ Espo.define('views/record/list', 'view', function (Dep) {
}
},
selectAllHandler: function (isChecked) {
this.checkedList = [];
var $actionsButton = this.$el.find('.actions-button');
if (isChecked) {
this.$el.find('input.record-checkbox').prop('checked', true);
$actionsButton.removeAttr('disabled');
this.collection.models.forEach(function (model) {
this.checkedList.push(model.id);
}, this);
this.$el.find('.list > table tbody tr').addClass('active');
} else {
if (this.allResultIsChecked) {
this.unselectAllResult();
}
this.$el.find('input.record-checkbox').prop('checked', false);
$actionsButton.attr('disabled', true);
this.$el.find('.list > table tbody tr').removeClass('active');
}
this.trigger('check');
},
/**
* @param {string} or {bool} ['both', 'top', 'bottom', false, true] Where to display paginations.
*/
@@ -304,7 +309,10 @@ Espo.define('views/record/list', 'view', function (Dep) {
}
}, this);
this.$el.find('.actions-button').removeAttr('disabled');
if (this.checkAllResultMassActionList.length) {
this.$el.find('.actions-button').removeAttr('disabled');
}
this.$el.find('.list > table tbody tr').removeClass('active');
},