Compare commits

...

19 Commits
5.7.2 ... 5.7.3

Author SHA1 Message Date
yuri
8199692df7 calendar ui fixes 2019-10-15 16:38:08 +03:00
yuri
1d3a340d3a duplicate returnUrl 2019-10-15 15:19:53 +03:00
yuri
d664f29388 fix 2019-10-15 14:04:00 +03:00
yuri
4d0e1af000 save and continue action 2019-10-15 14:00:55 +03:00
yuri
97ea0c71e1 fix handle action 2019-10-15 14:00:45 +03:00
yuri
d9fbcda231 lanf 2019-10-15 11:57:28 +03:00
yuri
f4b5cfa5b6 add global search test 2019-10-15 11:43:37 +03:00
yuri
4391c7a7ac fix test 2019-10-15 11:43:27 +03:00
yuri
6c14f390f6 fix global search 2019-10-15 11:31:08 +03:00
yuri
4a6829cf10 fix output 2019-10-15 11:15:45 +03:00
yuri
2b6c493be5 fix link parent 2019-10-14 13:24:42 +03:00
yuri
597406f70d fix test 2019-10-14 13:00:31 +03:00
yuri
110e2fbc37 string pos formula function 2019-10-14 12:32:30 +03:00
yuri
3e1fab487a htmlizer ifInArray 2019-10-14 11:30:50 +03:00
yuri
c76e34fe81 fix enum 2019-10-11 15:49:53 +03:00
yuri
eb922103a8 v 2019-10-11 13:02:04 +03:00
yuri
9b946c6a1f compose email layout columns 2019-10-11 13:01:45 +03:00
yuri
e2df819e57 call allow 0 duration 2019-10-11 11:17:21 +03:00
yuri
9b00d50079 fix select manager user from team 2019-10-11 10:50:25 +03:00
29 changed files with 483 additions and 78 deletions

View File

@@ -0,0 +1,51 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2019 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: https://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.
************************************************************************/
namespace Espo\Core\Formula\Functions\StringGroup;
use \Espo\Core\Exceptions\Error;
class PosType extends \Espo\Core\Formula\Functions\Base
{
public function process(\StdClass $item)
{
$args = $item->value ?? [];
if (count($args) < 2) throw new Error("Bad arguments passed to function string\\pos.");
$string = $this->evaluate($args[0]);
$needle = $this->evaluate($args[1]);
if (!is_string($string)) {
return false;
}
return mb_strpos($string, $needle);
}
}

View File

@@ -300,7 +300,19 @@ class Htmlizer
} else {
return $context['inverse'] ? $context['inverse']() : '';
}
}
},
'ifInArray' => function () {
$args = func_get_args();
$context = $args[count($args) - 1];
$array = $args[1] ?? [];
if (in_array($args[0], $array)) {
return $context['fn']();
} else {
return $context['inverse'] ? $context['inverse']() : '';
}
},
]
]);

View File

@@ -356,12 +356,16 @@ class Base
if ($relationType == 'belongsTo') {
$key = $seed->getRelationParam($link, 'key');
$aliasName = 'usersTeams' . ucfirst($link);
$aliasName = 'usersTeams' . ucfirst($link) . strval(rand(10000, 99999));
$result['customJoin'] .= "
JOIN team_user AS {$aliasName}Middle ON {$aliasName}Middle.user_id = ".$query->toDb($seed->getEntityType()).".".$query->toDb($key)." AND {$aliasName}Middle.deleted = 0
JOIN team AS {$aliasName} ON {$aliasName}.deleted = 0 AND {$aliasName}Middle.team_id = {$aliasName}.id
";
$this->addLeftJoin([
'TeamUser',
$aliasName . 'Middle',
[
$aliasName . 'Middle.userId:' => $key,
$aliasName . 'Middle.deleted' => false,
]
], $result);
$result['whereClause'][] = [
$aliasName . 'Middle.teamId' => $idsValue

View File

@@ -71,7 +71,7 @@ class Output
echo $data;
}
public function processError(string $message = 'Error', int $statusCode = 500, bool $toPrint = false, $exception = null)
public function processError(string $message = 'Error', $statusCode = 500, bool $toPrint = false, $exception = null)
{
$currentRoute = $this->getSlim()->router()->getCurrentRoute();
@@ -99,7 +99,7 @@ class Output
$this->displayError($message, $statusCode, $toPrint, $exception);
}
public function displayError(string $text, int $statusCode = 500, bool $toPrint = false, $exception = null)
public function displayError(string $text, $statusCode = 500, bool $toPrint = false, $exception = null)
{
$logLevel = 'error';
$messageLineFile = null;

View File

@@ -23,6 +23,7 @@
"dateEnd": {
"type": "datetime",
"required": true,
"view": "crm:views/call/fields/date-end",
"after": "dateStart"
},
"duration": {

View File

@@ -56,7 +56,20 @@
"Portal Users": "Usuarios del portal",
"Action History": "Histórico",
"Label Manager": "Etiquetas",
"Permissions": "Permisos"
"Auth Log": "Registros de autenticación",
"Lead Capture": "Captura de Posible cliente",
"Attachments": "Adjuntos",
"API Users": "Usuarios de API",
"Template Manager": "Gestor de plantillas",
"System Requirements": "Requerimientos del sistema",
"PHP Settings": "Configuraciones PHP",
"Database Settings": "Configuraciones de la Base de Datos",
"Permissions": "Permisos",
"Success": "Éxito",
"Fail": "Falló",
"is recommended": "es recomendado",
"extension is missing": "no se encuentra la extensión",
"PDF Templates": "Plantillas PDF"
},
"layouts": {
"list": "Lista",
@@ -159,8 +172,7 @@
"installExtension": "La extensión {name} {version} está lista para ser instalada.",
"upgradeBackup": "Recomendamos hacer una copia de seguridad de los archivos y datos de EspoCRM antes de actualizar.",
"thousandSeparatorEqualsDecimalMark": "El símbolo de separador de miles no puede ser el mismo que el de punto decimal.",
"userHasNoEmailAddress": "El usuario no tiene dirección de correo electrónico.",
"newVersionIsAvailable": "La nueva versión de EspoCRM {latestVersion} está disponible."
"userHasNoEmailAddress": "El usuario no tiene dirección de correo electrónico."
},
"descriptions": {
"settings": "Ajustes generales del sistema.",
@@ -191,7 +203,17 @@
"entityManager": "Crear y editar entidades personalizadas. Administrar campos y relaciones.",
"emailFilters": "Filtros para los correos entrantes.",
"actionHistory": "Registro de las acciones del usuario.",
"labelManager": "Personaliza las etiquetas de las aplicaciones."
"labelManager": "Personaliza las etiquetas de las aplicaciones.",
"authLog": "Historial de acceso.",
"leadCapture": "Puntos de acceso al API para Web-to-Lead.",
"attachments": "Todos los archivos adjuntos almacenados en el sistema.",
"templateManager": "Personalice las plantillas de mensajes.",
"systemRequirements": "Requerimientos del sistema para EspoCRM.",
"apiUsers": "Usuarios separados para propósitos de integraciones.",
"jobs": "Los trabajos que ejecutan tareas en segundo plano.",
"pdfTemplates": "Plantillas para impresión en PDF.",
"webhooks": "Administre webhooks.",
"dashboardTemplates": "Implemente paneles para los usuarios."
},
"options": {
"previewSize": {

View File

@@ -328,14 +328,14 @@
},
"notificationMessages": {
"assign": "{entityType} {entity} ha sido asignado a usted",
"emailReceived": "Correo recibido de: <strong>{from}</strong>.",
"entityRemoved": "{user} ha eliminado: <strong>[{entityType}]</strong> {entity}"
"emailReceived": "Correo recibido de: {from}",
"entityRemoved": "{user} ha eliminado: {entityType} {entity}"
},
"streamMessages": {
"post": "{user} ha publicado en: <strong>[{entityType}]</strong> {entity}",
"attach": "{user} ha añadido un archivo adjunto en: <strong>[{entityType}]</strong> {entity}",
"status": "{user} ha actualizado el campo <strong>{field}</strong> en: <strong>[{entityType}]</strong> {entity}",
"update": "{user} ha actualizado: <strong>[{entityType}]</strong> {entity}",
"post": "{user} ha publicado en: {entityType} {entity}",
"attach": "{user} ha añadido un archivo adjunto en: {entityType} {entity}",
"status": "{user} ha actualizado el campo {field} en: {entityType} {entity}",
"update": "{user} ha actualizado: {entityType} {entity}",
"postTargetTeam": "{user} ha publicado en el equipo {target}",
"postTargetTeams": "{user} ha publicado en los equipos {target}",
"postTargetPortal": "{user} ha publicado en el portal {target}",
@@ -344,47 +344,47 @@
"postTargetYou": "{user} ha publicado pora usted",
"postTargetYouAndOthers": "{user} ha publicado para {target} y para usted",
"postTargetAll": "{user} ha publicado para todos",
"mentionInPost": "{user} ha mencionado a {mentioned} en: <strong>[{entityType}]</strong> {entity}",
"mentionYouInPost": "{user} te ha mencionado en: <strong>[{entityType}]</strong> {entity}",
"mentionInPost": "{user} ha mencionado a {mentioned} en: {entityType} {entity}",
"mentionYouInPost": "{user} te ha mencionado en: {entityType} {entity}",
"mentionInPostTarget": "{user} ha mencionado a {mentioned} en la publicación",
"mentionYouInPostTarget": "{user} te ha mencionado en la publicación para {target}",
"mentionYouInPostTargetAll": "{user} te ha mencionado en una publicación para todos",
"mentionYouInPostTargetNoTarget": "{user} te ha mencionado en una publicación",
"create": "{user} ha creado: <strong>[{entityType}]</strong> {entity}",
"createThis": "{user} ha creado: <strong>{entityType}</strong>",
"create": "{user} ha creado: {entityType} {entity}",
"createThis": "{user} ha creado: {entityType}",
"createAssignedThis": "{user} ha creado y se lo ha asignado a {assignee}: {entityType}",
"createAssigned": "{user} ha creado y se lo ha asignado a {assignee}: <strong>[{entityType}]</strong> {entity}",
"assign": "{user} ha asignado: <strong>[{entityType}]</strong> {entity} a {assignee}",
"createAssigned": "{user} ha creado y se lo ha asignado a {assignee}: {entityType} {entity}",
"assign": "{user} ha asignado: {entityType} {entity} a {assignee}",
"assignThis": "{user} ha asignado {entityType} a {assignee}",
"postThis": "{user} ha publicado",
"attachThis": "{user} ha adjuntado",
"statusThis": "{user} ha actualizado el campo <strong>{field}</strong>",
"statusThis": "{user} ha actualizado el campo {field}",
"updateThis": "{user} ha actualizado: {entityType}",
"createRelatedThis": "{user} ha creado: <strong>[{relatedEntityType}]</strong> {relatedEntity}, enlazado a {entityType}",
"createRelated": "{user} ha creado: <strong>[{relatedEntityType}]</strong> {relatedEntity} enlazado a <strong>[{entityType}]</strong> {entity}",
"relate": "{user} ha enlazado <strong>[{relatedEntityType}]</strong> {relatedEntity} a <strong>[{entityType}] {entity}",
"createRelatedThis": "{user} ha creado: {relatedEntityType} {relatedEntity}, enlazado a {entityType}",
"createRelated": "{user} ha creado: {relatedEntityType} {relatedEntity} enlazado a {entityType} {entity}",
"relate": "{user} ha enlazado {relatedEntityType} {relatedEntity} a {entityType} {entity}",
"relateThis": "{user} vinculado {relatedEntityType} {relatedEntity} con este {entityType}",
"emailReceivedFromThis": "Correo recibido de: <strong>{from}</strong>.",
"emailReceivedFromThis": "Correo recibido de: {from}",
"emailReceivedInitialFromThis": "Correo recibido de {from}, se ha creado: {entityType}",
"emailReceivedThis": "Correo recibido",
"emailReceivedInitialThis": "Correo recibido, se ha creado: {entityType}",
"emailReceivedFrom": "Correo recibido de {from}, relacionado a: <strong>[{entityType}]</strong> {entity}",
"emailReceivedFromInitial": "Correo recibido de {from}, se ha creado: <strong>[{entityType}]<strong>\n {entityType}",
"emailReceivedInitialFrom": "Correo recibido de {from}, se ha creado: <strong>[{entityType}]<strong>\n {entityType}",
"emailReceivedFrom": "Correo recibido de {from}, relacionado a: {entityType} {entity}",
"emailReceivedFromInitial": "Correo recibido de {from}, se ha creado: {entityType} {entityType}",
"emailReceivedInitialFrom": "Correo recibido de {from}, se ha creado: {entityType} {entityType}",
"emailReceived": "El correo {email} ha sido recibido para el {entityType} {entity}",
"emailReceivedInitial": "Correo recibido, se ha creado: <strong>[{entityType}]<strong>\n {entityType}",
"emailSent": "{by} ha enviado un correo relacionado a: <strong>[{entityType}]</strong> {entity}",
"emailReceivedInitial": "Correo recibido, se ha creado: {entityType} {entityType}",
"emailSent": "{by} ha enviado un correo relacionado a: {entityType} {entity}",
"emailSentThis": "{by} ha enviado un correo",
"postTargetSelf": "{user} se ha enviado un mensaje a sí mismo",
"postTargetSelfAndOthers": "{user} ha publicado para {target} y para sí mismo",
"createAssignedYou": "{user} ha creado y te lo ha asignado: <strong>[{entityType}]</strong> {entity}",
"createAssignedYou": "{user} ha creado y te lo ha asignado: {entityType} {entity}",
"createAssignedThisSelf": "{user} ha creado y se ha asignado a sí mismo: {entityType}",
"createAssignedSelf": "{user} ha creado y se ha asignado a sí mismo: <strong>[{entityType}]</strong> {entity}",
"assignYou": "{user} te ha asignado <strong>[{entityType}]<strong> {entity} a ti",
"createAssignedSelf": "{user} ha creado y se ha asignado a sí mismo: {entityType} {entity}",
"assignYou": "{user} te ha asignado {entityType} {entity} a ti",
"assignThisVoid": "{user} ha desasignado: {entityType}",
"assignVoid": "{user} ha desasignado: <strong>[{entityType}]</strong> {entity}",
"assignVoid": "{user} ha desasignado: {entityType} {entity}",
"assignThisSelf": "{user} se ha asignado así mismo: {entityType}",
"assignSelf": "{user} se ha asignado así mismo: <strong>[{entityType}]</strong> {entity}"
"assignSelf": "{user} se ha asignado así mismo: {entityType} {entity}"
},
"lists": {
"monthNames": [

View File

@@ -147,7 +147,6 @@
"upgradeBackup": "We adviseren om eerst een backup te maken van uw EspoCRM bestanden en data, alvorens te upgraden.",
"thousandSeparatorEqualsDecimalMark": "Het duizendtal scheidingsteken mag niet hetzelfde zijn als het decimaalteken.",
"userHasNoEmailAddress": "Gebruiker heeft geen emailadres.",
"newVersionIsAvailable": "Nieuwe EspoCRM-versie {latestVersion} is beschikbaar.",
"uninstallConfirmation": "Weet je zeker dat je de extensie wilt verwijderen?",
"cronIsNotConfigured": "Geplande taken zijn niet actief. Vandaar dat inkomende e-mails, meldingen en herinneringen niet werken. Volg de [instructies] (https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab) om cron-taak in te stellen.",
"newExtensionVersionIsAvailable": "Nieuwe versie {extensionName} {latestVersion} is beschikbaar.",

View File

@@ -184,10 +184,9 @@
"upgradeBackup": "Перед обновлением рекомендуется сделать резервную копию ваших файлов и данных EspoCRM.",
"thousandSeparatorEqualsDecimalMark": "Разделитель тысячных не может быть таким же, как разделитель десятичных.",
"userHasNoEmailAddress": "У пользователя нет адреса эл. почты.",
"newVersionIsAvailable": "Новая версия EspoCRM {latestVersion} доступна.",
"uninstallConfirmation": "Вы действительно хотите удалить расширение?",
"cronIsNotConfigured": "Запланированные задания не выполняются. Следовательно, входящие письма, уведомления и напоминания не работают. Пожалуйста, следуйте инструкциям [https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab) для установки cron job.",
"newExtensionVersionIsAvailable": "Новая {extensionName} версия {lastVersion} доступна."
"newExtensionVersionIsAvailable": "Новая {extensionName} версия {latestVersion} доступна."
},
"descriptions": {
"settings": "Системные настройки.",

View File

@@ -1,18 +1,21 @@
[
{
"label":"",
"rows":[
"columns": [
[
{
"name":"from",
"view": "views/email/fields/compose-from-address"
},
{"name":"cc"}
{"name":"to"}
],
[
{"name":"to"},
{"name":"cc"},
{"name":"bcc"}
],
]
]
},
{
"rows": [
[
{
"name": "parent"
@@ -22,9 +25,9 @@
"view":"views/email/fields/select-template"
}
],
[{"name":"subject","fullWidth":true}],
[{"name":"body","fullWidth":true}],
[{"name":"attachments"},{"name":"isHtml"}]
[{"name":"subject","fullWidth": true}],
[{"name":"body","fullWidth": true}],
[{"name":"attachments"}, {"name":"isHtml"} ]
]
}
]

View File

@@ -97,6 +97,14 @@ class GlobalSearch extends \Espo\Core\Services\Base
$selectParams['orderBy'] = [['name']];
}
if ($this->getMetadata()->get(['entityDefs', $entityType, 'fields', 'name', 'type']) === 'personName') {
$selectParams['select'][] = 'firstName';
$selectParams['select'][] = 'lastName';
} else {
$selectParams['select'][] = ['VALUE:', 'firstName'];
$selectParams['select'][] = ['VALUE:', 'lastName'];
}
$selectParams['offset'] = 0;
$selectParams['limit'] = $offset + $maxSize + 1;

View File

@@ -3,18 +3,20 @@
{{#if header}}
<div class="row button-container">
<div class="col-sm-4 col-xs-6">
<div class="col-sm-4 col-xs-5">
<div class="btn-group range-switch-group">
<button class="btn btn-text btn-icon" data-action="prev"><span class="fas fa-chevron-left"></span></button>
<button class="btn btn-text btn-icon" data-action="next"><span class="fas fa-chevron-right"></span></button>
</div>
<button class="btn btn-text strong" data-action="today">{{translate 'Today' scope='Calendar'}}</button>
<button class="btn btn-text strong" data-action="today" title="{{todayLabel}}">
<span class="hidden-sm hidden-xs">{{todayLabel}}</span><span class="visible-sm visible-xs">{{todayLabelShort}}</span>
</button>
<button class="btn btn-text{{#unless isCustomView}} hidden{{/unless}} btn-icon" data-action="editCustomView" title="{{translate 'Edit'}}"><span class="fas fa-pencil-alt fa-sm"></span></button>
</div>
<div class="date-title col-sm-4 col-xs-6"><h4><span style="cursor: pointer;" data-action="refresh" title="{{translate 'Refresh'}}"></span></h4></div>
<div class="date-title col-sm-4 col-xs-7"><h4><span style="cursor: pointer;" data-action="refresh" title="{{translate 'Refresh'}}"></span></h4></div>
<div class="col-sm-4 col-xs-12">
<div class="btn-group pull-right mode-buttons">

View File

@@ -26,7 +26,7 @@
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
Espo.define('crm:views/calendar/calendar', ['view', 'lib!full-calendar'], function (Dep, FullCalendar) {
define('crm:views/calendar/calendar', ['view', 'lib!full-calendar'], function (Dep, FullCalendar) {
return Dep.extend({
@@ -56,7 +56,7 @@ Espo.define('crm:views/calendar/calendar', ['view', 'lib!full-calendar'], functi
titleFormat: {
month: 'MMMM YYYY',
week: 'MMMM D, YYYY',
week: 'MMMM YYYY',
day: 'dddd, MMMM D, YYYY'
},
@@ -66,6 +66,8 @@ Espo.define('crm:views/calendar/calendar', ['view', 'lib!full-calendar'], functi
header: this.header,
isCustomViewAvailable: this.isCustomViewAvailable,
isCustomView: this.isCustomView,
todayLabel: this.translate('Today', 'labels', 'Calendar'),
todayLabelShort: this.translate('Today', 'labels', 'Calendar').substr(0, 2),
};
},
@@ -286,7 +288,7 @@ Espo.define('crm:views/calendar/calendar', ['view', 'lib!full-calendar'], functi
var title;
if (viewName == 'week') {
title = $.fullCalendar.formatRange(view.start, view.end, this.titleFormat[viewName], ' - ');
title = $.fullCalendar.formatRange(view.start, view.end, this.titleFormat[viewName], ' ');
} else {
title = view.intervalStart.format(this.titleFormat[viewName]);
}

View File

@@ -0,0 +1,50 @@
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2019 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: https://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.
************************************************************************/
define('crm:views/call/fields/date-end', 'views/fields/datetime', function (Dep) {
return Dep.extend({
validateAfter: function () {
var field = this.model.getFieldParam(this.name, 'after');
if (field) {
var value = this.model.get(this.name);
var otherValue = this.model.get(field);
if (value && otherValue) {
if (moment(value).unix() < moment(otherValue).unix()) {
var msg = this.translate('fieldShouldAfter', 'messages').replace('{field}', this.getLabelText())
.replace('{otherField}', this.translate(field, 'fields', this.model.name));
this.showValidationMessage(msg);
return true;
}
}
}
},
});
});

View File

@@ -16,7 +16,11 @@
<div class="panel-heading"><h4 class="panel-title"><%= panelLabelString %></h4></div>
<% } %>
<div class="panel-body panel-body-form">
<% _.each(panel.rows, function (row, rowNumber) { %>
<% var rows = panel.rows || [] %>
<% var columns = panel.columns || [] %>
<% _.each(rows, function (row, rowNumber) { %>
<div class="row">
<% var columnCount = row.length; %>
<% _.each(row, function (cell, cellNumber) { %>
@@ -90,6 +94,78 @@
<% }); %>
</div>
<% }); %>
<%
var columnCount = columns.length;
if (columnCount) {
%>
<div class="row">
<%
}
%>
<% _.each(columns, function (column, columnNumber) { %>
<%
var spanClass;
if (!columnCount) return;
if (columnCount === 1 || column.fullWidth) {
spanClass = 'col-sm-12';
} else if (columnCount === 2) {
if (column.span === 2) {
spanClass = 'col-sm-12';
} else {
spanClass = 'col-sm-6';
}
} else if (columnCount === 3) {
if (column.span === 2) {
spanClass = 'col-sm-8';
} else if (column.span === 3) {
spanClass = 'col-sm-12';
} else {
spanClass = 'col-sm-4';
}
} else if (columnCount === 4) {
if (column.span === 2) {
spanClass = 'col-sm-6';
} else if (column.span === 3) {
spanClass = 'col-sm-9';
} else if (column.span === 4) {
spanClass = 'col-sm-12';
} else {
spanClass = 'col-md-3 col-sm-6';
}
} else {
spanClass = 'col-sm-12';
}
%>
<div class="column <%= spanClass %>">
<% _.each(column, function (cell, cellNumber) { %>
<div class="cell form-group<% if (cell.field) { %>{{#if hiddenFields.<%= cell.field %>}} hidden-cell{{/if}}<% } %>" data-name="<%= cell.field %>">
<% if (!cell.noLabel) { %><label class="control-label<% if (cell.field) { %>{{#if hiddenFields.<%= cell.field %>}} hidden{{/if}}<% } %>" data-name="<%= cell.field %>"><span class="label-text"><%
if ('customLabel' in cell) {
print (cell.customLabel);
} else {
print ("{{translate \""+cell.field+"\" scope=\""+model.name+"\" category='fields'}}");
}
%></span></label><% } %>
<div class="field<% if (cell.field) { %>{{#if hiddenFields.<%= cell.field %>}} hidden{{/if}}<% } %>" data-name="<%= cell.field %>"><%
if ('customCode' in cell) {
print (cell.customCode);
} else {
print ("{{{this."+cell.name+"}}}");
}
%></div>
</div>
<% }); %>
</div>
<% }); %>
<%
if (columnCount) {
%>
</div>
<%
}
%>
</div>
</div>
<% }); %>

View File

@@ -1,4 +1,5 @@
<div class="input-group input-group-link-parent">
{{#if foreignScopeList.length}}
<span class="input-group-btn">
<select class="form-control" data-name="{{typeName}}">
{{options foreignScopeList foreignScope category='scopeNames'}}
@@ -9,5 +10,8 @@
<button data-action="selectLink" class="btn btn-default btn-icon" type="button" tabindex="-1" title="{{translate 'Select'}}"><i class="fas fa-angle-up"></i></button>
<button data-action="clearLink" class="btn btn-default btn-icon" type="button" tabindex="-1"><i class="fas fa-times"></i></button>
</span>
{{else}}
{{translate 'None'}}
{{/if}}
</div>
<input type="hidden" data-name="{{idName}}" value="{{idValue}}">

View File

@@ -58,7 +58,15 @@ define('utils', [], function () {
if ($dropdown.length) {
var $dropdownToggle = $dropdown.parent().find('[data-toggle="dropdown"]');
if ($dropdownToggle.length) {
var isDisabled = false;
if ($dropdownToggle.attr('disabled')) {
isDisabled = true;
$dropdownToggle.removeAttr('disabled').removeClass('disabled');
}
$dropdownToggle.dropdown('toggle');
if (isDisabled) {
$dropdownToggle.attr('disabled', 'disabled').addClass('disabled');
}
}
}
}

View File

@@ -345,11 +345,10 @@ define('views/detail', 'views/main', function (Dep) {
this.getRouter().dispatch(this.scope, 'create', {
attributes: attributes,
returnUrl: this.getRouter().getCurrentUrl(),
});
this.getRouter().navigate(url, {trigger: false});
}.bind(this));
},
});

View File

@@ -25,7 +25,8 @@
* 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('views/fields/duration', 'views/fields/enum', function (Dep) {
define('views/fields/duration', 'views/fields/enum', function (Dep) {
return Dep.extend({
@@ -111,7 +112,7 @@ Espo.define('views/fields/duration', 'views/fields/enum', function (Dep) {
stringifyDuration: function (seconds) {
if (!seconds) {
return '';
return '0';
}
var d = seconds;
var days = Math.floor(d / (86400));
@@ -242,7 +243,7 @@ Espo.define('views/fields/duration', 'views/fields/enum', function (Dep) {
updateDuration: function () {
var seconds = this.seconds;
if (seconds <= 0) {
if (seconds < 0) {
if (this.mode == 'edit') {
this.$duration.val('');
} else {

View File

@@ -110,7 +110,7 @@ define('views/fields/enum', ['views/fields/base', 'lib!Selectize'], function (De
}
if (this.params.isSorted && this.translatedOptions) {
this.params.options = Espo.Utils.clone(this.params.options);
this.params.options = Espo.Utils.clone(this.params.options) || [];
this.params.options = this.params.options.sort(function (v1, v2) {
return (this.translatedOptions[v1] || v1).localeCompare(this.translatedOptions[v2] || v2);
}.bind(this));

View File

@@ -26,7 +26,7 @@
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
Espo.define('views/fields/link-parent', 'views/fields/base', function (Dep) {
define('views/fields/link-parent', 'views/fields/base', function (Dep) {
return Dep.extend({
@@ -65,6 +65,7 @@ Espo.define('views/fields/link-parent', 'views/fields/base', function (Dep) {
if ((this.mode == 'detail' || this.mode == 'list' && this.displayScopeColorInListMode) && this.foreignScope) {
iconHtml = this.getHelper().getScopeColorIconHtml(this.foreignScope);
}
return _.extend({
idName: this.idName,
nameName: this.nameName,
@@ -103,11 +104,6 @@ Espo.define('views/fields/link-parent', 'views/fields/base', function (Dep) {
if (!this.getMetadata().get(['scopes', item, 'disabled'])) return true;
}, this);
if (this.mode == 'edit' && this.foreignScopeList.length == 0) {
throw new Error('Bad parent link defenition. Model list is empty.');
}
this.foreignScope = this.model.get(this.typeName) || this.foreignScopeList[0];
this.listenTo(this.model, 'change:' + this.typeName, function () {

View File

@@ -118,6 +118,8 @@ define('views/record/detail', ['views/record/base', 'view-record-helper'], funct
convertCurrencyAction: true,
saveAndContinueEditingAction: false,
events: {
'click .button-container .action': function (e) {
Espo.Utils.handleAction(this, e);
@@ -163,6 +165,10 @@ define('views/record/detail', ['views/record/base', 'view-record-helper'], funct
$(window).scrollTop(0);
},
actionSaveAndContinueEditing: function () {
this.save(null, true);
},
actionSelfAssign: function () {
var attributes = {
assignedUserId: this.getUser().id,
@@ -348,6 +354,13 @@ define('views/record/detail', ['views/record/base', 'view-record-helper'], funct
}, this);
}, this);
}
if (this.saveAndContinueEditingAction) {
this.dropdownEditItemList.push({
name: 'saveAndContinueEditing',
label: 'Save & Continue Editing',
});
}
}
},
@@ -1353,11 +1366,18 @@ define('views/record/detail', ['views/record/base', 'view-record-helper'], funct
}
}
for (var i in simplifiedLayout[p].rows) {
var lType = 'rows';
if (simplifiedLayout[p].columns) {
lType = 'columns';
panel.columns = [];
}
for (var i in simplifiedLayout[p][lType]) {
var row = [];
for (var j in simplifiedLayout[p].rows[i]) {
var cellDefs = simplifiedLayout[p].rows[i][j];
for (var j in simplifiedLayout[p][lType][i]) {
var cellDefs = simplifiedLayout[p][lType][i][j];
if (cellDefs == false) {
row.push(false);
@@ -1401,7 +1421,7 @@ define('views/record/detail', ['views/record/base', 'view-record-helper'], funct
var fullWidth = cellDefs.fullWidth || false;
if (!fullWidth) {
if (simplifiedLayout[p].rows[i].length == 1) {
if (simplifiedLayout[p][lType][i].length == 1) {
fullWidth = true;
}
}
@@ -1455,7 +1475,7 @@ define('views/record/detail', ['views/record/base', 'view-record-helper'], funct
row.push(cell);
}
panel.rows.push(row);
panel[lType].push(row);
}
layout.push(panel);
}

View File

@@ -81,7 +81,18 @@ define('views/record/edit', 'views/record/detail', function (Dep) {
this.populateDefaults();
}
Dep.prototype.setupBeforeFinal.call(this);
}
},
setupActionItems: function () {
Dep.prototype.setupActionItems.call(this);
if (this.saveAndContinueEditingAction) {
this.dropdownItemList.push({
name: 'saveAndContinueEditing',
label: 'Save & Continue Editing',
});
}
},
});
});

View File

@@ -3174,7 +3174,10 @@ table.table-admin-panel {
margin-top: 6px;
h4 {
margin-top: 0;
font-size: 15px;
}
white-space: nowrap;
overflow: hidden;
}
}

View File

@@ -99,7 +99,7 @@
"modRewriteInstruction": {
"apache": {
"windows": "<br> <pre>1. Encontrar el archivo httpd.conf (generalmente lo encontrará en una carpeta llamada conf, config o o algo similar a esas líneas)<br>\n2. Dentro del archivo httpd.conf descomentamos la línea LoadModule rewrite_module modules/mod_rewrite.so (eliminar el '#' que está al comienzo de la línea)<br>\n3. También encuentre que la línea ClearModuleList no esté comentada después busque y asegurese que la línea AddModule mod_rewrite.c no está comentada tampoco.\n</pre>",
"linux": "<br> <br>1. Habilita \"mod_rewrite\". Para hacerlo, ejecute esos comandos en un Terminal: <pre>{APACHE1}</pre><br> 2. Habilita el soporte de .htaccess. Agregue/edite los ajustes de configuración del Servidor (/etc/apache/apache2.conf, /etc/httpd/conf/httpd.conf): <pre>{APACHE2}</pre>\nLuego ejecuta este comando en un Terminal: <pre>{APACHE3}</pre> <br>3. Intente agregar la ruta RewriteBase, abra un archivo {API_PATH} .htaccess y reemplace la siguiente línea: <pre>{APACHE4}</ pre> a <pre>{APACHE5}</ pre> <br> Para obtener más información, visite la guía <a href=\"https://www.espocrm.com/documentation/administration/apache-server-configuration/\" target=\"_blank\"> configuración del servidor Apache para EspoCRM </a>. <br> <br>"
"linux": "<br> <br>1. Habilita \"mod_rewrite\". Para hacerlo, ejecute esos comandos en un Terminal: <pre>{APACHE1}</pre><br> 2. Habilita el soporte de .htaccess. Agregue/edite los ajustes de configuración del Servidor (/etc/apache/apache2.conf, /etc/httpd/conf/httpd.conf): <pre>{APACHE2}</pre>\nLuego ejecuta este comando en un Terminal: <pre>{APACHE3}</pre> <br>3. Intente agregar la ruta RewriteBase, abra un archivo {API_PATH} .htaccess y reemplace la siguiente línea: <pre>{APACHE4}</pre> a <pre>{APACHE5}</pre> <br> Para obtener más información, visite la guía <a href=\"https://www.espocrm.com/documentation/administration/apache-server-configuration/\" target=\"_blank\"> configuración del servidor Apache para EspoCRM </a>. <br> <br>"
},
"nginx": {
"linux": "<br>\n<pre>\n{NGINX}\n</pre> <br> Para obtener más información, visite la guía <a href=\"https://www.espocrm.com/documentation/administration/nginx-server-configuration/\" target=\"_blank\"> configuración del servidor Nginx para EspoCRM </a>. <br> <br> <br>",

View File

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

View File

@@ -0,0 +1,93 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2019 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: https://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.
************************************************************************/
namespace tests\integration\Espo\GlobalSearch;
class GlobalSearchTest extends \tests\integration\Core\BaseTestCase
{
public function testSearch1()
{
$app = $this->createApplication();
$em = $app->getContainer()->get('entityManager');
$team = $em->createEntity('Team', [
'name' => 'test',
]);
$contact = $em->createEntity('Contact', [
'lastName' => '1',
'teamsIds' => [$team->id],
]);
$account = $em->createEntity('Account', [
'name' => '1',
'teamsIds' => [$team->id],
]);
$account = $em->createEntity('Account', [
'name' => '2',
'teamsIds' => [$team->id],
]);
$account = $em->createEntity('Account', [
'name' => '1',
]);
$this->createUser([
'userName' => 'tester',
'teamsIds' => [$team->id],
], [
'data' => [
'Account' => [
'create' => 'no',
'read' => 'team',
'edit' => 'no',
'delete' => 'no',
'stream' => 'no',
],
'Contact' => [
'create' => 'no',
'read' => 'team',
'edit' => 'no',
'delete' => 'no',
'stream' => 'no',
],
],
]);
$this->auth('tester');
$app = $this->createApplication(true);
$service = $app->getContainer()->get('serviceFactory')->create('GlobalSearch');
$result = $service->find('1', 0, 10);
$this->assertEquals(2, count($result['list']));
}
}

View File

@@ -27,7 +27,7 @@
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace tests\integration\Espo\Attachment;
namespace tests\integration\Espo\LeadCapture;
class LeadCaptureTest extends \tests\integration\Core\BaseTestCase
{

View File

@@ -2816,6 +2816,47 @@ class FormulaTest extends \PHPUnit\Framework\TestCase
$this->assertEquals('12', $actual);
}
function testPos()
{
$item = json_decode('
{
"type": "string\\\\pos",
"value": [
{
"type": "value",
"value": "1234"
},
{
"type": "value",
"value": 23
}
]
}
');
$actual = $this->formula->process($item, $this->entity);
$this->assertEquals(1, $actual);
$item = json_decode('
{
"type": "string\\\\pos",
"value": [
{
"type": "value",
"value": "1234"
},
{
"type": "value",
"value": 54
}
]
}
');
$actual = $this->formula->process($item, $this->entity);
$this->assertFalse($actual);
}
function testBundle()
{
$item = json_decode('