Compare commits

...

23 Commits

Author SHA1 Message Date
yuri 901bee6d3f fix campaign 2015-10-15 11:52:25 +03:00
yuri 72a0415207 fix orderBy by alias 2015-10-14 13:03:08 +03:00
yuri de69652137 fix id in model.set 2015-10-14 11:35:21 +03:00
yuri 1cd2d6b35e target lists field not importable 2015-10-12 10:43:50 +03:00
yuri 9888ec8a6f fix global searct 2015-10-12 10:30:16 +03:00
yuri ea5321577a fix target list import 2015-10-08 17:55:48 +03:00
yuri 23c772e029 fix config 2015-10-07 16:53:22 +03:00
yuri e67387d9ea additionalSelectColumns 2015-10-07 15:00:03 +03:00
yuri 2156094407 cleanup 2015-10-07 12:21:59 +03:00
yuri 03d5bf1ef2 tree impr 2015-10-07 12:18:01 +03:00
yuri 42f57409c8 list tree imp 2015-10-07 12:08:11 +03:00
yuri 69d7ce408d fix preferences layout 2015-10-07 11:24:52 +03:00
yuri 15b3c0440c lead converted panel change 2015-10-07 10:56:56 +03:00
yuri e1f0715c4d email import: relate to converted entity if lead is converted 2015-10-07 10:35:07 +03:00
yuri 15aec72e97 fix double quick view 2015-10-07 10:33:47 +03:00
yuri 66eade5db7 v 2015-10-07 10:20:37 +03:00
yuri 3d89e25349 label 2015-10-05 14:36:52 +03:00
yuri 7c890aa83a fix empty tablist 2015-10-02 17:23:02 +03:00
yuri 62a29c86ab fix record controller 2015-10-02 15:27:34 +03:00
yuri bd57b6bb8e detailLayout param 2 2015-10-02 15:10:13 +03:00
yuri 9ab1d16ea0 detailLayout param 2015-10-02 15:09:39 +03:00
yuri 435aa28ca2 iconHtml for menu items 2015-10-01 13:11:05 +03:00
yuri 4bd375f154 fix notice 2015-09-30 17:22:15 +03:00
34 changed files with 222 additions and 96 deletions
@@ -29,7 +29,7 @@ class GlobalSearch extends \Espo\Core\Controllers\Base
{
public function actionSearch($params, $data, $request)
{
$query = $params['query'];
$query = $request->get('q');
$offset = intval($request->get('offset'));
$maxSize = intval($request->get('maxSize'));
@@ -170,6 +170,7 @@ class Record extends Base
$asc = $request->get('asc') === 'true';
$sortBy = $request->get('sortBy');
$q = $request->get('q');
$textFilter = $request->get('textFilter');
if (empty($maxSize)) {
$maxSize = self::MAX_SIZE_LIMIT;
+22
View File
@@ -194,6 +194,28 @@ class Importer
$n = sscanf($reference, '%s %s %d %d espo', $parentType, $parentId, $emailSent, $number);
if ($n == 4 && $emailSent < time()) {
if (!empty($parentType) && !empty($parentId)) {
if ($parentType == 'Lead') {
$parent = $this->getEntityManager()->getEntity('Lead', $parentId);
if ($parent && $parent->get('status') == 'Converted') {
if ($parent->get('createdAccountId')) {
$account = $this->getEntityManager()->getEntity('Account', $parent->get('createdAccountId'));
if ($account) {
$parentType = 'Account';
$parentId = $account->id;
}
} else {
if ($this->getConfig()->get('b2cMode')) {
if ($parent->get('createdContactId')) {
$contact = $this->getEntityManager()->getEntity('Contact', $parent->get('createdContactId'));
if ($contact) {
$parentType = 'Contact';
$parentId = $contact->id;
}
}
}
}
}
}
$email->set('parentType', $parentType);
$email->set('parentId', $parentId);
$parentFound = true;
+12 -2
View File
@@ -150,7 +150,17 @@ class Config
$removeData = empty($this->removeData) ? null : $this->removeData;
$result = $this->getFileManager()->mergePhpContents($this->configPath, $values, $removeData);
$data = include($this->configPath);
foreach ($values as $key => $value) {
$data[$key] = $value;
}
foreach ($removeData as $key) {
unset($data[$key]);
}
$result = $this->getFileManager()->putPhpContents($this->configPath, $data);
if ($result) {
$this->changedData = array();
@@ -220,7 +230,7 @@ class Config
$restrictItems = $this->getRestrictItems($isAdmin);
$values = array();
foreach($data as $key => $item) {
foreach ($data as $key => $item) {
if (!in_array($key, $restrictItems)) {
$values[$key]= $item;
}
@@ -45,7 +45,7 @@ class Contact extends \Espo\Core\ORM\Repositories\RDB
$result = parent::afterSave($entity, $options);
$this->handleAfterSaveAccounts($entity, $options);
if ($entity->has('targetListId') && $entity->isNew()) {
if ($entity->has('targetListId')) {
$this->relate($entity, 'targetLists', $entity->get('targetListId'));
}
@@ -24,7 +24,8 @@
{
"name":"statistics",
"label":"Statistics",
"view":"Crm:Campaign.Record.Panels.Statistics"
"view":"Crm:Campaign.Record.Panels.Statistics",
"hidden": true
}
]
},
@@ -29,12 +29,9 @@
{
"name":"convertedTo",
"label":"Converted To",
"view": "Record.Panels.Side",
"view": "crm:views/lead/record/panels/converted-to",
"notRefreshable": true,
"hidden": true,
"options": {
"fieldList": ["createdAccount", "createdContact", "createdOpportunity"]
}
"hidden": true
},
{
"name":"activities",
@@ -51,6 +48,33 @@
"label":"Tasks",
"view":"Crm:Record.Panels.Tasks"
}
],
"edit": [
{
"name":"convertedTo",
"label":"Converted To",
"view": "crm:views/lead/record/panels/converted-to",
"notRefreshable": true,
"hidden": true
}
],
"detailSmall": [
{
"name":"convertedTo",
"label":"Converted To",
"view": "crm:views/lead/record/panels/converted-to",
"notRefreshable": true,
"hidden": true
}
],
"editSmall": [
{
"name":"convertedTo",
"label":"Converted To",
"view": "crm:views/lead/record/panels/converted-to",
"notRefreshable": true,
"hidden": true
}
]
},
"relationshipPanels": {
@@ -131,6 +131,7 @@
"layoutDetailDisabled": true,
"layoutListDisabled": true,
"layoutMassUpdateDisabled": true,
"importDisabled": true,
"noLoad": true
},
"targetList": {
@@ -399,7 +399,6 @@ class MassEmail extends \Espo\Services\Record
} catch (\Exception $e) {
if ($queueItem->get('attemptCount') >= self::MAX_ATTEMPT_COUNT) {
$this->setQueueItemFailed($queueItem);
$queueItem->set('status', 'Failed');
}
$this->getEntityManager()->saveEntity($queueItem);
+7 -1
View File
@@ -113,6 +113,12 @@ abstract class Base
}
}
if (!empty($params['additionalSelectColumns']) && is_array($params['additionalSelectColumns'])) {
foreach ($params['additionalSelectColumns'] as $column => $field) {
$selectPart .= ", " . $column . " AS `{$field}`";
}
}
} else {
$aggDist = false;
if ($params['distinct'] && $params['aggregation'] == 'COUNT') {
@@ -427,7 +433,7 @@ abstract class Base
{
if (strpos($orderBy, '.') !== false) {
list($alias, $field) = explode('.', $orderBy);
$fieldPath = $this->toDb($alias) . '.' . $this->toDb($this->sanitize($field));
$fieldPath = $this->sanitize($alias) . '.' . $this->toDb($this->sanitize($field));
} else {
$fieldPath = $this->getFieldPath($entity, $orderBy);
}
@@ -39,6 +39,7 @@
},
"messages": {
"entityCreated": "Entity has been created",
"linkAlreadyExists": "Link name conflict."
"linkAlreadyExists": "Link name conflict.",
"linkConflict": "Link with the same name already exists."
}
}
@@ -43,10 +43,6 @@
{
"name": "defaultReminders"
}
],
[
{"name":"theme"},
false
]
]
},
+2 -3
View File
@@ -87,12 +87,11 @@
},
{
"route":"/GlobalSearch/:query",
"route":"/GlobalSearch",
"method":"get",
"params":{
"controller":"GlobalSearch",
"action":"search",
"query": ":query"
"action":"search"
}
},
@@ -154,7 +154,6 @@ class EmailTemplate extends Record
protected function parseText($type, Entity $entity, $text)
{
$fieldList = array_keys($entity->getFields());
$fieldList[] = $id;
foreach ($fieldList as $field) {
$value = $entity->get($field);
if (is_object($value)) {
@@ -30,7 +30,6 @@
this.menu.buttons.push({
'label': 'Send Invitations',
'action': 'sendInvitations',
icon: 'glyphicon glyphicon-send',
'acl': 'edit',
});
}
@@ -25,31 +25,6 @@ Espo.define('Crm:Views.Lead.Record.DetailSide', 'Views.Record.DetailSide', funct
setupPanels: function () {
/*var panel = {
name: 'convertedTo',
label: 'Converted To',
view: 'Record.Panels.Side',
notRefreshable: true,
options: {
fieldList: [],
mode: 'detail',
}
};
panel.options.fieldList.push('createdAccount');
panel.options.fieldList.push('createdContact');
panel.options.fieldList.push('createdOpportunity');
this.panels = Espo.Utils.clone(this.panels);
this.panels.splice(1, 0, panel);*/
}
});
@@ -0,0 +1,45 @@
/************************************************************************
* 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/.
************************************************************************/
Espo.define('crm:views/lead/record/panels/converted-to', 'views/record/panels/side', function (Dep) {
return Dep.extend({
setup: function () {
this.fieldList = [];
if (this.getAcl().check('Account')) {
this.fieldList.push('createdAccount');
}
if (this.getAcl().check('Contact')) {
this.fieldList.push('createdContact');
}
if (this.getAcl().check('Opportunity')) {
this.fieldList.push('createdOpportunity');
}
Dep.prototype.setup.call(this);
}
});
});
@@ -30,7 +30,6 @@ Espo.define('Crm:Views.Meeting.Detail', 'Views.Detail', function (Dep) {
this.menu.buttons.push({
'label': 'Send Invitations',
'action': 'sendInvitations',
icon: 'glyphicon glyphicon-send',
'acl': 'edit',
});
}
@@ -30,7 +30,7 @@ Espo.define('Crm:Views.Task.Detail', 'Views.Detail', function (Dep) {
this.menu.buttons.push({
'label': 'Complete',
'action': 'setCompleted',
icon: 'glyphicon glyphicon-ok',
'iconHtml': '<span class="glyphicon glyphicon-ok"></span>',
'acl': 'edit',
});
}
+2 -1
View File
@@ -6,6 +6,7 @@
<div class="header-buttons btn-group pull-right">
{{#each items.buttons}}
<a {{#if link}}href="{{link}}"{{else}}href="javascript:"{{/if}} class="btn btn-{{#if style}}{{style}}{{else}}default{{/if}} action{{#if hidden}} hidden{{/if}}" data-action="{{name}}"{{#each data}} data-{{@key}}="{{./this}}"{{/each}}>
{{#if iconHtml}}{{{iconHtml}}}{{/if}}
{{#if html}}{{{html}}}{{else}}{{translate label scope=../../scope}}{{/if}}
</a>
{{/each}}
@@ -30,7 +31,7 @@
</button>
<ul class="dropdown-menu pull-right">
{{#each items.dropdown}}
<li class="{{#if hidden}}hidden{{/if}}"><a {{#if link}}href="{{link}}"{{else}}href="javascript:"{{/if}} class="action" data-action="{{name}}"{{#each data}} data-{{@key}}="{{./this}}"{{/each}}>{{#if html}}{{{html}}}{{else}}{{translate label scope=../../../scope}}{{/if}}</a></li>
<li class="{{#if hidden}}hidden{{/if}}"><a {{#if link}}href="{{link}}"{{else}}href="javascript:"{{/if}} class="action" data-action="{{name}}"{{#each data}} data-{{@key}}="{{./this}}"{{/each}}>{{#if iconHtml}}{{{iconHtml}}} {{/if}}{{#if html}}{{{html}}}{{else}}{{translate label scope=../../../scope}}{{/if}}</a></li>
{{/each}}
</ul>
</div>
+12
View File
@@ -42,6 +42,18 @@ Espo.define('model', [], function () {
Dep.prototype.initialize.call(this);
},
set: function (key, val, options) {
if (typeof key === 'object') {
var o = key;
if (this.idAttribute in o) {
this.id = o[this.idAttribute];
}
} else if (key === 'id') {
this.id = val;
}
return Dep.prototype.set.call(this, key, val, options);
},
get: function (key) {
if (key === 'id' && this.id) {
return this.id;
@@ -19,11 +19,11 @@
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
Espo.define('Views.GlobalSearch.GlobalSearch', 'View', function (Dep) {
Espo.define('views/global-search/global-search', 'view', function (Dep) {
return Dep.extend({
template: 'global-search.global-search',
template: 'global-search/global-search',
events: {
'keypress #global-search-input': function (e) {
@@ -63,7 +63,7 @@ Espo.define('Views.GlobalSearch.GlobalSearch', 'View', function (Dep) {
},
search: function (text) {
this.collection.url = this.collection.urlRoot = 'GlobalSearch/' + text;
this.collection.url = this.collection.urlRoot = 'GlobalSearch?q=' + encodeURIComponent(text);
this.showPanel();
},
+1 -1
View File
@@ -19,7 +19,7 @@
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
Espo.define('Views.Import.Detail', 'Views.Detail', function (Dep) {
Espo.define('views/import/detail', 'views/detail', function (Dep) {
return Dep.extend({
+2 -2
View File
@@ -18,11 +18,11 @@
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
Espo.define('Views.Import.Index', 'View', function (Dep) {
Espo.define('views/import/index', 'view', function (Dep) {
return Dep.extend({
template: 'import.index',
template: 'import/index',
data: function () {
return {
+1 -1
View File
@@ -19,7 +19,7 @@
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
Espo.define('Views.Import.List', 'Views.List', function (Dep) {
Espo.define('views/import/list', 'views/list', function (Dep) {
return Dep.extend({
+3 -2
View File
@@ -18,11 +18,12 @@
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
Espo.define('Views.Import.Step1', 'View', function (Dep) {
Espo.define('views/import/step1', 'view', function (Dep) {
return Dep.extend({
template: 'import.step-1',
template: 'import/step-1',
events: {
'change #import-file': function (e) {
+3 -2
View File
@@ -18,11 +18,12 @@
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
Espo.define('Views.Import.Step2', 'View', function (Dep) {
Espo.define('views/import/step2', 'view', function (Dep) {
return Dep.extend({
template: 'import.step-2',
template: 'import/step-2',
events: {
'click button[data-action="back"]': function () {
+14 -1
View File
@@ -34,6 +34,8 @@ Espo.define('views/record/detail', 'views/record/base', function (Dep) {
gridLayout: null,
detailLayout: null,
/**
* @property {string} or {bool} ['both', 'top', 'bottom', false, true] Where to display buttons.
*/
@@ -338,6 +340,8 @@ Espo.define('views/record/detail', 'views/record/base', function (Dep) {
this.layoutName = this.options.layoutName || this.layoutName;
this.detailLayout = this.options.detailLayout || this.detailLayout;
this.type = this.options.type || this.type;
this.buttons = this.options.buttons || this.buttons;
@@ -627,10 +631,19 @@ Espo.define('views/record/detail', 'views/record/base', function (Dep) {
return;
}
if (this.detailLayout) {
this.gridLayout = {
type: 'record',
layout: this.convertDetailLayout(this.detailLayout)
};
callback(this.gridLayout);
return;
}
this._helper.layoutManager.get(this.model.name, this.layoutName, function (simpleLayout) {
this.gridLayout = {
type: 'record',
layout: this.convertDetailLayout(simpleLayout),
layout: this.convertDetailLayout(simpleLayout)
};
callback(this.gridLayout);
}.bind(this));
@@ -19,16 +19,18 @@
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
Espo.define('Views.Record.ListTreeItem', 'View', function (Dep) {
Espo.define('views/record/list-tree-item', 'view', function (Dep) {
return Dep.extend({
template: 'record.list-tree-item',
template: 'record/list-tree-item',
isEnd: false,
level: 0,
listViewName: 'views/record/list-tree',
data: function () {
return {
name: this.model.get('name'),
@@ -120,7 +122,7 @@ Espo.define('Views.Record.ListTreeItem', 'View', function (Dep) {
view.render();
};
}
this.createView('children', 'Record.ListTree', {
this.createView('children', this.listViewName, {
collection: childCollection,
el: this.options.el + ' > .children',
createDisabled: this.options.createDisabled,
+18 -12
View File
@@ -19,11 +19,11 @@
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
Espo.define('Views.Record.ListTree', 'Views.Record.List', function (Dep) {
Espo.define('views/record/list-tree', 'views/record/list', function (Dep) {
return Dep.extend({
template: 'record.list-tree',
template: 'record/list-tree',
showMore: false,
@@ -53,6 +53,8 @@ Espo.define('Views.Record.ListTree', 'Views.Record.List', function (Dep) {
level: 0,
itemViewName: 'views/record/list-tree-item',
data: function () {
var data = Dep.prototype.data.call(this);
data.createDisabled = this.createDisabled;
@@ -151,7 +153,7 @@ Espo.define('Views.Record.ListTree', 'Views.Record.List', function (Dep) {
var built = 0;
modelList.forEach(function (model, i) {
this.rows.push('row-' + i);
this.createView('row-' + i, 'Record.ListTreeItem', {
this.createView('row-' + i, this.itemViewName, {
model: model,
collection: this.collection,
el: this.options.el + ' ' + this.getRowSelector(model.id),
@@ -186,14 +188,22 @@ Espo.define('Views.Record.ListTree', 'Views.Record.List', function (Dep) {
return this.options.el + ' li[data-id="' + model.id + '"] span.cell-' + item.name;
},
getCreateAttributes: function () {
return {};
},
actionCreate: function (data, e) {
e.stopPropagation();
var parentId = null;
var parentName = null;
var attributes = this.getCreateAttributes();
attributes.order = this.collection.length + 1;
attributes.parentId = null;
attributes.parentName = null;
if (this.model) {
parentId = this.model.id;
parentName = this.model.get('name');
attributes.parentId = this.model.id;
attributes.parentName = this.model.get('name');
}
var scope = this.collection.name;
@@ -201,11 +211,7 @@ Espo.define('Views.Record.ListTree', 'Views.Record.List', function (Dep) {
var viewName = this.getMetadata().get('clientDefs.' + scope + '.modalViews.edit') || 'Modals.Edit';
this.createView('quickCreate', viewName, {
scope: scope,
attributes: {
parentId: parentId,
parentName: parentName,
order: this.collection.length + 1
}
attributes: attributes
}, function (view) {
view.render();
this.listenToOnce(view, 'after:save', function (model) {
@@ -17,49 +17,58 @@
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
Espo.define('Views.Settings.Fields.CurrencyRates', 'Views.Fields.Base', function (Dep) {
************************************************************************/
Espo.define('views/settings/fields/currency-rates', 'views/fields/base', function (Dep) {
return Dep.extend({
editTemplate: 'settings.fields.currency-rates.edit',
editTemplate: 'settings/fields/currency-rates/edit',
data: function () {
var baseCurrency = this.model.get('baseCurrency');
var currencyRates = this.model.get('currencyRates') || {};
var rateValues = {};
this.model.get('currencyList').forEach(function (currency) {
if (currency != baseCurrency) {
rateValues[currency] = currencyRates[currency] || 1.00;
}
}, this);
return {
rateValues: rateValues
};
},
setup: function () {
},
fetch: function () {
var data = {};
var currencyRates = {};
var baseCurrency = this.model.get('baseCurrency');
this.model.get('currencyList').forEach(function (currency) {
var currencyList = this.model.get('currencyList') || [];
currencyList.forEach(function (currency) {
if (currency != baseCurrency) {
currencyRates[currency] = parseFloat(this.$el.find('input[data-currency="'+currency+'"]').val() || 1);
}
}, this);
delete currencyRates[baseCurrency];
for (var c in currencyRates) {
if (!~currencyList.indexOf(c)) {
delete currencyRates[c];
}
}
data[this.name] = currencyRates;
return data;
},
}
});
});
+2
View File
@@ -93,6 +93,8 @@ Espo.define('Views.Site.Navbar', 'View', function (Dep) {
var tabList = this.getPreferences().get('useCustomTabList') ? this.getPreferences().get('tabList') : this.getConfig().get('tabList');
tabList = tabList || [];
this.tabList = tabList.filter(function (scope) {
if (this.getMetadata().get('scopes.' + scope + '.acl')) {
return this.getAcl().check(scope);
+3 -1
View File
@@ -111,7 +111,9 @@ Espo.define('views/stream/list', 'views/record/list-expanded', function (Dep) {
});
},
actionViewRecord: function (data) {
actionViewRecord: function (data, e) {
e.stopPropagation();
var id = data.id;
var scope = data.scope;
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "espocrm",
"version": "3.7.1",
"version": "3.7.2",
"description": "",
"main": "index.php",
"repository": {