Compare commits

...

146 Commits

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
yuri bc525f3047 fetchOnModelAfterRelate 2016-03-02 13:21:19 +02:00
yuri 6809181adf mass email: dont store test email 2016-03-02 13:02:44 +02:00
yuri 2c71a28421 fix use 2016-03-02 11:49:47 +02:00
yuri 82162e4fe6 fix select manager 2016-03-01 17:25:11 +02:00
yuri 03454bc309 fix portal log 2016-03-01 16:40:23 +02:00
yuri d975501f29 fix warnings 2016-03-01 16:32:37 +02:00
yuri 761356adda fix mention 2016-03-01 12:23:37 +02:00
yuri 824835a28c email template: array fields 2016-03-01 12:01:27 +02:00
yuri 252ce15973 fix email template 2016-03-01 11:55:37 +02:00
yuri 7f25dba917 v 2016-03-01 10:57:31 +02:00
yuri b5d4b8aa5a fix warning 2016-03-01 10:20:07 +02:00
yuri 39a136295a repository default options 2016-02-29 17:45:39 +02:00
yuri 6d674c007e php 7 compatibility 2016-02-29 17:01:18 +02:00
yuri 31f380a03a russian lang 2016-02-29 12:03:38 +02:00
yuri 7e23960196 v 2016-02-26 17:11:36 +02:00
yuri d3b9f2479b fix export 2016-02-26 17:11:32 +02:00
yuri c211842b52 fix metadata 2016-02-26 15:17:33 +02:00
yuri 3e11c0cfc1 fix loader 2016-02-26 12:23:53 +02:00
yuri 6747440b00 document folder customizable 2016-02-26 12:09:30 +02:00
yuri dc1c4b1e78 fix lang 2016-02-26 10:48:01 +02:00
yuri 26f2fba3ac cleanyp 2016-02-25 16:17:55 +02:00
yuri eb481c689b fix warnings 2016-02-25 16:16:40 +02:00
yuri 88c3984d35 date: ever filter 2016-02-25 13:07:50 +02:00
yuri 4eae088973 fix flotr2: remove underscore 2016-02-25 12:19:11 +02:00
yuri 60ae0fb365 fix 2016-02-25 10:28:21 +02:00
yuri ab36f41fc3 duration notStorable 2016-02-24 17:51:13 +02:00
yuri 98de243e37 Merge branch 'master' of ssh://172.20.0.1/var/git/espo/backend 2016-02-24 15:31:45 +02:00
yuri 0c6ccabbeb fix checkEntityForDuplicate 2016-02-24 15:31:26 +02:00
yuri a66e6111cb fix detail view buttons fixed possition 2016-02-24 12:11:00 +02:00
yuri caf5c8806a chart outlineColor 2016-02-24 11:43:48 +02:00
yuri 0154dfd6a1 view naming fix 2016-02-24 11:36:43 +02:00
yuri e545e68877 version 2016-02-24 10:43:43 +02:00
yuri fa24c2b7fe fix array field 2016-02-23 16:43:02 +02:00
Taras Machyshyn df2b7d9659 Merge branch 'master' of ssh://172.20.0.1/var/git/espo/backend 2016-02-23 15:58:24 +02:00
Taras Machyshyn cc395232ff Fixed ukrainian translation 2016-02-23 15:58:10 +02:00
yuri 47afb83536 fix datetime 2016-02-23 15:48:13 +02:00
yuri 02d1b50b59 view naming 2016-02-23 15:42:05 +02:00
yuri bd86eb08fa fix account list layout 2016-02-23 15:10:47 +02:00
yuri b3c1a45b72 task: add parent to filters layout 2016-02-23 12:41:34 +02:00
yuri 15678e59e2 fix search frontend 2016-02-23 12:41:00 +02:00
yuri 6fe379bab3 link multiple and attachment multiple listLayoutDisabled 2016-02-23 11:54:48 +02:00
yuri 39ecb2fd37 cleanup 2016-02-23 11:51:36 +02:00
yuri 988c0059ff import language file 2016-02-23 11:34:15 +02:00
yuri 61ff31b3b7 trim 2016-02-23 11:17:05 +02:00
yuri 7c1a098b89 change account layouts 2016-02-22 16:47:52 +02:00
yuri f843593843 add country to lead small view 2016-02-22 16:38:22 +02:00
yuri c34eb915bc fix email draft 2016-02-22 15:54:37 +02:00
yuri 9508432294 opportunity set probability if empty 2016-02-22 15:00:40 +02:00
yuri 0959962269 version 2016-02-22 14:53:05 +02:00
yuri e39a91bde6 fix view naming 2016-02-22 12:42:09 +02:00
yuri 51f5dbe25c address list view 2016-02-22 11:47:45 +02:00
yuri 6fd5c6cbe7 fix view naming 2016-02-22 11:18:07 +02:00
yuri 6622b09eaa fix issue that search input not stored 2016-02-22 11:16:47 +02:00
yuri 9bb9f066cd fix dashboard 2016-02-19 18:15:28 +02:00
yuri 03110b47df change account list layout 2016-02-19 17:41:15 +02:00
yuri 034e532e05 change contact list layout 2016-02-19 17:35:07 +02:00
yuri c306af8b4c readable date formats according to selecred date format 2016-02-19 12:21:23 +02:00
yuri bd4a784676 move readable date formats to date-time.js 2016-02-19 12:10:55 +02:00
yuri 4ca0a9dc5f fix german salutations 2016-02-19 12:03:15 +02:00
yuri c6816b01b5 bool field filter: checked by default 2016-02-19 11:51:27 +02:00
yuri bc7583ccb4 improve role table ui 2016-02-19 11:32:16 +02:00
yuri 318e43aca3 json formating 2016-02-19 10:38:05 +02:00
yuri ea992f727b admin page: move user interface upper 2016-02-18 18:19:03 +02:00
yuri 5bdb16f98c fix home icon position 2016-02-18 18:09:27 +02:00
yuri faa06993e6 cacheTimestamp fix for no cache 2016-02-18 18:06:50 +02:00
yuri f6e0d017b2 change home icon 2016-02-18 18:03:16 +02:00
yuri 8ea56a74b0 code style link 2016-02-18 17:23:18 +02:00
yuri d4c9666f85 contributing file 2016-02-18 17:19:43 +02:00
294 changed files with 10369 additions and 2219 deletions
+3
View File
@@ -0,0 +1,3 @@
Before we can merge your pull request you need to accept our CLA [here](https://github.com/espocrm/cla). It's very simple to do.
[Code Style Guidelines](https://github.com/espocrm/espocrm/wiki/Code-Style-Guidelines).
+3
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 %>',
]
}
},
@@ -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>
+5 -5
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();
}
@@ -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'));
+8 -2
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;
}
}
@@ -189,6 +189,9 @@ class Table
$valuePermissionLists->$permission = [];
}
$aclTableList = [];
$fieldTableList = [];
if (!$this->user->isAdmin()) {
$roleList = $this->getRoleList();
@@ -484,6 +487,9 @@ class Table
foreach (array_merge($mandatoryFieldData, $mandatoryScopeFieldData) as $field => $f) {
if (!in_array($field, $fieldList)) continue;
if (!isset($fieldTable->$scope)) {
$fieldTable->$scope = (object) [];
}
$fieldTable->$scope->$field = (object) [];
foreach ($this->fieldActionList as $action) {
$level = 'no';
@@ -508,7 +514,7 @@ class Table
foreach ($this->getScopeList() as $scope) {
if ($this->getMetadata()->get('scopes.' . $scope . '.disabled')) {
$aclTable->$scope = false;
$table->$scope = false;
unset($fieldTable->$scope);
}
}
+1 -1
View File
@@ -116,7 +116,7 @@ class Table extends \Espo\Core\Acl\Table
foreach ($this->getScopeList() as $scope) {
$d = $this->getMetadata()->get('scopes.' . $scope);
if ($d['disabled'] || $d['portalDisabled']) {
$aclTable->$scope = false;
$table->$scope = false;
unset($fieldTable->$scope);
}
}
+2 -3
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'];
}
+20 -5
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)
+3 -6
View File
@@ -94,9 +94,6 @@ class Entity extends \Espo\ORM\Entity
{
$columnsField = $field . 'Columns';
if (!$this->has($columnsField)) {
$this->loadLinkMultipleField($field, true);
}
if (!$this->has($columnsField)) {
return;
}
@@ -125,7 +122,7 @@ class Entity extends \Espo\ORM\Entity
if (!$this->has($idsField)) {
if (!$this->isNew()) {
$this->loadLinkMultipleField($field, true);
$this->loadLinkMultipleField($field);
} else {
$this->set($idsField, []);
}
@@ -148,7 +145,7 @@ class Entity extends \Espo\ORM\Entity
if (!$this->has($idsField)) {
if (!$this->isNew()) {
$this->loadLinkMultipleField($field, true);
$this->loadLinkMultipleField($field);
}
}
$valueList = $this->get($idsField);
@@ -166,7 +163,7 @@ class Entity extends \Espo\ORM\Entity
if (!$this->has($idsField)) {
if (!$this->isNew()) {
$this->loadLinkMultipleField($field, true);
$this->loadLinkMultipleField($field);
}
}
+2 -2
View File
@@ -45,6 +45,8 @@ class Application extends \Espo\Core\Application
throw new Error("Portal id was not passed to ApplicationPortal.");
}
$GLOBALS['log'] = $this->getContainer()->get('log');
$portal = $this->getContainer()->get('entityManager')->getEntity('Portal', $portalId);
if (!$portal) {
@@ -58,8 +60,6 @@ class Application extends \Espo\Core\Application
$this->getContainer()->setPortal($portal);
$GLOBALS['log'] = $this->getContainer()->get('log');
$this->initAutoloads();
}
@@ -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);
@@ -277,7 +277,7 @@ class Base
$foreignEntity = $defs['entity'];
if (empty($foreignEntity)) {
continue;
return;
}
$pathName = lcfirst($query->sanitize($foreignEntity . 'Path'));
@@ -906,6 +906,7 @@ class Base
$part[$item['field'] . '='] = null;
break;
case 'isNotNull':
case 'ever':
$part[$item['field'] . '!='] = null;
break;
case 'isTrue':
@@ -1068,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)
@@ -2,7 +2,8 @@
"fields": {
"name": {
"type": "varchar",
"required": true
"required": true,
"trim": true
},
"description": {
"type": "text"
@@ -28,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": {
@@ -2,7 +2,8 @@
"fields": {
"name": {
"type": "varchar",
"required": true
"required": true,
"trim": true
},
"order": {
"type": "int",
@@ -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": {
@@ -69,6 +69,14 @@ class ClientManager
return $this->basePath;
}
protected function getCacheTimestamp()
{
if (!$this->getConfig()->get('useCache')) {
return (string) time();
}
return $this->getConfig()->get('cacheTimestamp', 0);
}
public function display($runScript = null, $htmlFilePath = null, $vars = array())
{
if (is_null($runScript)) {
@@ -88,7 +96,7 @@ class ClientManager
foreach ($vars as $key => $value) {
$html = str_replace('{{'.$key.'}}', $value, $html);
}
$html = str_replace('{{cacheTimestamp}}', $this->getConfig()->get('cacheTimestamp', 0), $html);
$html = str_replace('{{cacheTimestamp}}', $this->getCacheTimestamp(), $html);
$html = str_replace('{{useCache}}', $this->getConfig()->get('useCache') ? 'true' : 'false' , $html);
$html = str_replace('{{stylesheet}}', $this->getThemeManager()->getStylesheet(), $html);
$html = str_replace('{{runScript}}', $runScript , $html);
@@ -31,7 +31,7 @@ namespace Espo\Core\Utils\Database\DBAL\FieldTypes;
use Doctrine\DBAL\Types\BooleanType;
class Bool extends BooleanType
class BoolType extends BooleanType
{
const BOOL = 'bool';
@@ -31,7 +31,7 @@ namespace Espo\Core\Utils\Database\DBAL\FieldTypes;
use Doctrine\DBAL\Types\IntegerType;
class Int extends IntegerType
class IntType extends IntegerType
{
const INTtype = 'int';
@@ -29,7 +29,7 @@
namespace Espo\Core\Utils\Database\DBAL\FieldTypes;
class JsonArray extends \Doctrine\DBAL\Types\JsonArrayType
class JsonArrayType extends \Doctrine\DBAL\Types\JsonArrayType
{
const JSON_ARRAY = 'jsonArray';
@@ -29,7 +29,7 @@
namespace Espo\Core\Utils\Database\DBAL\FieldTypes;
class JsonObject extends \Doctrine\DBAL\Types\ObjectType
class JsonObjectType extends \Doctrine\DBAL\Types\ObjectType
{
const JSON_OBJECT = 'jsonObject';
@@ -31,7 +31,7 @@ namespace Espo\Core\Utils\Database\DBAL\FieldTypes;
use Doctrine\DBAL\Types\StringType;
class Password extends StringType
class PasswordType extends StringType
{
const PASSWORD = 'password';
@@ -31,7 +31,7 @@ namespace Espo\Core\Utils\Database\DBAL\FieldTypes;
use Doctrine\DBAL\Types\StringType;
class Varchar extends StringType
class VarcharType extends StringType
{
const VARCHAR = 'varchar';
@@ -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}"
@@ -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',
@@ -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',
@@ -161,11 +161,11 @@ class Schema
$typeList = $this->getFileManager()->getFileList($path, false, '\.php$');
if ($typeList !== false) {
foreach($typeList as $name) {
$typeName = preg_replace('/\.php$/i', '', $name);
foreach ($typeList as $name) {
$typeName = preg_replace('/Type\.php$/i', '', $name);
$dbalTypeName = strtolower($typeName);
$filePath = Util::concatPath($path, $typeName);
$filePath = Util::concatPath($path, $typeName . 'Type');
$class = Util::getClassName($filePath);
if( ! Type::hasType($dbalTypeName) ) {
+14 -2
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(
+1 -1
View File
@@ -308,7 +308,7 @@ class Metadata
*
* @return bool
*/
public function delete($key1, $key2, $unsets)
public function delete($key1, $key2, $unsets = null)
{
if (!is_array($unsets)) {
$unsets = (array) $unsets;
+1 -1
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,
+4 -1
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');
@@ -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);
}
@@ -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;
}
@@ -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);
}
}
@@ -33,7 +33,7 @@ use Espo\ORM\Entity;
class Account extends \Espo\Core\ORM\Repositories\RDB
{
public function afterSave(Entity $entity, array $options)
public function afterSave(Entity $entity, array $options = array())
{
parent::afterSave($entity, $options);
@@ -33,14 +33,14 @@ use Espo\ORM\Entity;
class CaseObj extends \Espo\Core\ORM\Repositories\RDB
{
public function afterSave(Entity $entity, array $options)
public function afterSave(Entity $entity, array $options = array())
{
$result = parent::afterSave($entity, $options);
$this->handleAfterSaveContacts($entity, $options);
return $result;
}
protected function handleAfterSaveContacts(Entity $entity, array $options)
protected function handleAfterSaveContacts(Entity $entity, array $options = array())
{
$contactIdChanged = $entity->has('contactId') && $entity->get('contactId') != $entity->getFetched('contactId');
@@ -47,7 +47,7 @@ class Contact extends \Espo\Core\ORM\Repositories\RDB
";
}
public function afterSave(Entity $entity, array $options)
public function afterSave(Entity $entity, array $options = array())
{
$result = parent::afterSave($entity, $options);
$this->handleAfterSaveAccounts($entity, $options);
@@ -59,7 +59,7 @@ class Contact extends \Espo\Core\ORM\Repositories\RDB
return $result;
}
protected function handleAfterSaveAccounts(Entity $entity, array $options)
protected function handleAfterSaveAccounts(Entity $entity, array $options = array())
{
$accountIdChanged = $entity->has('accountId') && $entity->get('accountId') != $entity->getFetched('accountId');
$titleChanged = $entity->has('title') && $entity->get('title') != $entity->getFetched('title');
@@ -33,7 +33,7 @@ use Espo\ORM\Entity;
class Lead extends \Espo\Core\ORM\Repositories\RDB
{
public function afterSave(Entity $entity, array $options)
public function afterSave(Entity $entity, array $options = array())
{
parent::afterSave($entity, $options);
@@ -33,7 +33,7 @@ use Espo\ORM\Entity;
class Meeting extends \Espo\Core\ORM\Repositories\RDB
{
protected function beforeSave(Entity $entity, array $options)
protected function beforeSave(Entity $entity, array $options = array())
{
parent::beforeSave($entity, $options);
@@ -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);
@@ -33,6 +33,16 @@ use Espo\ORM\Entity;
class Opportunity extends \Espo\Core\ORM\Repositories\RDB
{
public function beforeSave(Entity $entity, array $options = array())
{
parent::beforeSave($entity, $options);
if ($entity->isNew()) {
if (!$entity->has('probability') && $entity->get('stage')) {
$probability = $this->getMetadata()->get('entityDefs.Opportunity.probabilityMap.' . $entity->get('stage'), 0);
$entity->set('probability', $probability);
}
}
}
}
@@ -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);
@@ -1,5 +1,5 @@
{
"links": {
"articles": "Knlowledge Base Articles"
"articles": "Knowledge Base Articles"
}
}
@@ -1,42 +1,80 @@
{
"fields": {
"name": "Name",
"emailAddress": "Email",
"website": "Интернет сайт",
"phoneNumber": "Phone",
"billingAddress": "Платежный адрес",
"shippingAddress": "Почтовый адрес",
"description": "Описание",
"sicCode": "SicCode",
"industry": "Промышленность",
"type": "Type",
"contactRole": "Роль"
"fields": {
"name": "Имя",
"emailAddress": "Адрес эл. почты",
"website": "Сайт",
"phoneNumber": "Телефон",
"billingAddress": "Платежный адрес",
"shippingAddress": "Почтовый адрес",
"description": "Описание",
"sicCode": "SIC код",
"industry": "Вид деятельности",
"type": "Тип",
"contactRole": "Должность",
"campaign": "Кампания",
"targetLists": "Списки целей",
"targetList": "Список целей"
},
"links": {
"contacts": "Контакты",
"opportunities": "Сделки",
"cases": "Обращения",
"documents": "Документы",
"meetingsPrimary": "Встречи (развернуто)",
"callsPrimary": "Звонки (развернуто)",
"tasksPrimary": "Задачи (развернуто)",
"emailsPrimary": "Письма (развернуто)",
"targetLists": "Списки целей",
"campaignLogRecords": "Журнал кампании",
"campaign": "Кампания",
"portalUsers": "Пользователи портала"
},
"options": {
"type": {
"Customer": "Заказчик",
"Investor": "Вкладчик",
"Partner": "Партнер",
"Reseller": "Посредник"
},
"links": {
"contacts": "Контакты",
"opportunities": "Сделки",
"cases": "Обращения",
"documents": "Documents"
},
"options": {
"type": {
"Customer": "Заказчик",
"Investor": "Вкладчик",
"Partner": "Партнер",
"Reseller": "Посредник"
},
"industry": {
"Apparel": "Одежда",
"Banking": "Банковское дело",
"Computer Software": "Программное обеспечение",
"Education": "Образование",
"Electronics": "Электроника",
"Finance": "Финансы",
"Insurance": "Страхование"
}
},
"labels": {
"Create Account": "Создать контрагента",
"Copy Billing": "Copy Billing"
"industry": {
"Agriculture": "Agriculture",
"Advertising": "Advertising",
"Apparel & Accessories": "Apparel & Accessories",
"Automotive": "Automotive",
"Banking": "Banking",
"Biotechnology": "Biotechnology",
"Building Materials & Equipment": "Building Materials & Equipment",
"Chemical": "Chemical",
"Computer": "Computer",
"Education": "Education",
"Electronics": "Electronics",
"Energy": "Energy",
"Entertainment & Leisure": "Entertainment & Leisure",
"Finance": "Finance",
"Food & Beverage": "Food & Beverage",
"Grocery": "Grocery",
"Healthcare": "Healthcare",
"Insurance": "Insurance",
"Legal": "Legal",
"Manufacturing": "Manufacturing",
"Publishing": "Publishing",
"Real Estate": "Real Estate",
"Service": "Service",
"Sports": "Sports",
"Software": "Software",
"Technology": "Technology",
"Telecommunications": "Telecommunications",
"Television": "Television",
"Transportation": "Transportation",
"Venture Capital": "Venture Capital"
}
}
},
"labels": {
"Create Account": "Создать контрагента",
"Copy Billing": "Копировать адрес"
},
"presetFilters": {
"customers": "Заказчики",
"partners": "Партнеры"
}
}
@@ -1,5 +1,6 @@
{
"layouts": {
"detailConvert": "Преобразовать потенциального клиента"
}
}
"layouts": {
"detailConvert": "Преобразовать кандидата",
"listForAccount": "Список (для контрагента)"
}
}
@@ -1,13 +1,13 @@
{
"modes": {
"month": "месяц",
"week": "неделя",
"day": "день",
"agendaWeek": "неделя",
"agendaDay": "день"
},
"labels": {
"Today": "Сегодня",
"Create": "Создать"
}
}
"modes": {
"month": "Месяц",
"week": "Неделя",
"agendaWeek": "Неделя",
"day": "День",
"agendaDay": "День"
},
"labels": {
"Today": "Сегодня",
"Create": "Создать"
}
}
@@ -1,45 +1,49 @@
{
"fields": {
"name": "Имя",
"parent": "Источник",
"status": "Статус",
"dateStart": "Дата начала",
"dateEnd": "Дата окончания",
"direction": "Категория",
"duration": "Длительность",
"description": "Описание",
"users": "Пользователи",
"contacts": "Контакты",
"leads": "Потенциальные клиенты",
"reminders": "Напоминания"
"fields": {
"name": "Название",
"parent": "Источник",
"status": "Статус",
"dateStart": "Дата начала",
"dateEnd": "Дата окончания",
"direction": "Категория",
"duration": "Длительность",
"description": "Описание",
"users": "Пользователи",
"contacts": "Контакты",
"leads": "Кандидаты",
"reminders": "Напоминания",
"account": "Контрагент"
},
"options": {
"status": {
"Planned": "Запланирован",
"Held": "Состоялся",
"Not Held": "Не состоялся"
},
"links": {
"direction": {
"Outbound": "Исходящий",
"Inbound": "Входящий"
},
"options": {
"status": {
"Planned": "Запланированный",
"Held": "Выполнен",
"Not Held": "Не состоялся"
},
"direction": {
"Outbound": "Исходящий",
"Inbound": "Входящий"
},
"acceptanceStatus": {
"None": "Нет",
"Accepted": "Принятый",
"Declined": "Отклоненный"
}
},
"labels": {
"Create Call": "Новый звонок",
"Set Held": "Был выполнен",
"Set Not Held": "Set Not Held",
"Send Invitations": "Отправить приглашения"
},
"presetFilters": {
"planned": "Запланированные",
"held": "Завершенные",
"todays": "На сегодня"
"acceptanceStatus": {
"None": "Нет",
"Accepted": "Согласен",
"Declined": "Не согласен",
"Tentative": "Есть сомнения"
}
}
},
"massActions": {
"setHeld": "Состоялось",
"setNotHeld": "Не состоялось"
},
"labels": {
"Create Call": "Создать звонок",
"Set Held": "Состоялось",
"Set Not Held": "Не состоялось",
"Send Invitations": "Отправить приглашения"
},
"presetFilters": {
"planned": "Запланированные",
"held": "Завершенные",
"todays": "На сегодня"
}
}
@@ -0,0 +1,71 @@
{
"fields": {
"name": "Название",
"description": "Описание",
"status": "Статус",
"type": "Тип",
"startDate": "Дата начала",
"endDate": "Дата окончания",
"targetLists": "Списки целей",
"excludingTargetLists": "Исключая списки целей",
"sentCount": "Отправлено",
"openedCount": "Открыто",
"clickedCount": "Проследовало по ссылке",
"optedOutCount": "Отписалось",
"bouncedCount": "Возвратов писем",
"hardBouncedCount": "Жестких возвратов",
"softBouncedCount": "Мягких возвратов",
"leadCreatedCount": "Кандидатов создано",
"revenue": "Доход",
"revenueConverted": "Доход (сконвертированный)",
"budget": "Бюджет",
"budgetConverted": "Бюджет (сконвертированный)"
},
"links": {
"targetLists": "Списки целей",
"excludingTargetLists": "Исключая списки целей",
"accounts": "Контрагенты",
"contacts": "Контакты",
"leads": "Кандидаты",
"opportunities": "Сделки",
"campaignLogRecords": "Журнал",
"massEmails": "Массовые рассылки эл. писем",
"trackingUrls": "Целевые URL-адреса"
},
"options": {
"type": {
"Email": "Эл. письмо",
"Web": "Интернет",
"Television": "Телевидение",
"Radio": "Радио",
"Newsletter": "Информационный бюллетень",
"Mail": "Письмо"
},
"status": {
"Planning": "Запланирована",
"Active": "Активна",
"Inactive": "Не активна",
"Complete": "Завершена"
}
},
"labels": {
"Create Campaign": "Создать кампанию",
"Target Lists": "Списки целей",
"Statistics": "Статистика",
"hard": "жесткий",
"soft": "мягкий",
"Unsubscribe": "Отписаться",
"Mass Emails": "Массовые рассылки эл. писем",
"Email Templates": "Шаблоны эл. писем"
},
"presetFilters": {
"active": "Активна"
},
"messages": {
"unsubscribed": "Вы были удалены из нашего списка рассылки."
},
"tooltips": {
"targetLists": "Цели которые должны получить сообщения.",
"excludingTargetLists": "Цели которые не должны получить сообщения."
}
}
@@ -0,0 +1,40 @@
{
"fields": {
"action": "Действие",
"actionDate": "Дата",
"data": "Данные",
"campaign": "Кампания",
"parent": "Цель",
"object": "Объект",
"application": "Приложение",
"queueItem": "Queue Item",
"stringData": "Строка данных",
"stringAdditionalData": "Строка дополнительных данных"
},
"links": {
"queueItem": "Queue Item",
"parent": "Источник",
"object": "Объект"
},
"options": {
"action": {
"Sent": "Отправлено",
"Opened": "Открыто",
"Opted Out": "Отписалось",
"Bounced": "Возвратов писем",
"Clicked": "Проследовало по ссылке",
"Lead Created": "Кандидатов создано"
}
},
"labels": {
"All": "Все"
},
"presetFilters": {
"sent": "Отправлено",
"opened": "Открыто",
"optedOut": "Отписалось",
"bounced": "Возвратов писем",
"clicked": "Проследовало по ссылке",
"leadCreated": "Кандидатов создано"
}
}
@@ -0,0 +1,13 @@
{
"fields": {
"url": "Целевой URL-адрес",
"urlToUse": "Код для подстановки вместо целевого URL-адреса",
"campaign": "Кампания"
},
"links": {
"campaign": "Кампания"
},
"labels": {
"Create CampaignTrackingUrl": "Создать целевой URL-адрес"
}
}
@@ -1,42 +1,57 @@
{
"fields": {
"name": "Name",
"number": "Номер",
"status": "статус",
"account": "Контрагент",
"contact": "Контакт",
"priority": "Приоритет",
"type": "Type",
"description": "Описание"
"fields": {
"name": "Название",
"number": "Номер",
"status": "Статус",
"account": "Контрагент",
"contact": "Контакт",
"contacts": "Контакты",
"priority": "Приоритет",
"type": "Тип",
"description": "Описание",
"inboundEmail": "Входящая эл. почта"
},
"links": {
"inboundEmail": "Входящая эл. почта",
"account": "Контрагент",
"contact": "Контакт (основной)",
"Contacts": "Контакты",
"meetings": "Встречи",
"calls": "Звонки",
"tasks": "Задачи",
"emails": "Эл. письма",
"articles": "Статьи базы знаний"
},
"options": {
"status": {
"New": "Новое",
"Assigned": "Назначено",
"Pending": "В ожидании",
"Closed": "Закрыто",
"Rejected": "Отклонено",
"Duplicate": "Дубликат"
},
"links": {
"priority": {
"Low": "Низкий",
"Normal": "Обычный",
"High": "Высокий",
"Urgent": "Срочно"
},
"options": {
"status": {
"New": "Новый",
"Assigned": "На рассмотрении",
"Pending": "Текущее",
"Closed": "Закрыто",
"Rejected": "Отказано",
"Duplicate": "Копия"
},
"priority" : {
"Low": "Низкий",
"Normal": "Нормальный",
"High": "Высокий",
"Urgent": "Срочно"
},
"type": {
"Question": "Вопрос",
"Incident": "Происшествие",
"Problem": "Проблема"
}
},
"labels": {
"Create Case": "Создать обращение"
},
"presetFilters": {
"open": "Открытые",
"closed": "Закрытые"
"type": {
"Question": "Вопрос",
"Incident": "Происшествие",
"Problem": "Проблема"
}
}
},
"labels": {
"Create Case": "Создать обращение",
"Close": "Закрыть",
"Reject": "Отклонить",
"Closed": "Закрыто",
"Rejected": "Отклонено"
},
"presetFilters": {
"open": "Открытые",
"closed": "Закрытые"
}
}
@@ -1,31 +1,46 @@
{
"fields": {
"name": "Name",
"emailAddress": "Email",
"title": "Название",
"account": "Контрагент",
"accounts": "Контрагенты",
"phoneNumber": "Phone",
"accountType": "Тип контрагента",
"doNotCall": "Не звонить",
"address": "Address",
"opportunityRole": "Роль сделки",
"accountRole": "Роль",
"description": "Описание"
},
"links": {
"opportunities": "Сделки",
"cases": "Обращения"
},
"labels": {
"Create Contact": "Создать контакт"
},
"options": {
"opportunityRole": {
"": "--Нет--",
"Decision Maker": "Принимающий решение",
"Evaluator": "Оценщик",
"Influencer": "Консультант"
}
"fields": {
"name": "Имя",
"emailAddress": "Адрес эл. почты",
"title": "Должность",
"accountRole": "Должность",
"account": "Контрагент",
"accounts": "Контрагенты",
"phoneNumber": "Телефон",
"accountType": "Тип контрагента",
"doNotCall": "Не звонить",
"address": "Адрес",
"opportunityRole": "Роль в сделке",
"description": "Описание",
"campaign": "Кампания",
"targetLists": "Списки целей",
"targetList": "Список целей",
"portalUser": "Пользователь портала"
},
"links": {
"opportunities": "Cделки",
"cases": "Обращения",
"targetLists": "Списки целей",
"campaignLogRecords": "Журнал кампании",
"campaign": "Кампания",
"account": "Контрагент (основной)",
"accounts": "Контрагенты",
"casesPrimary": "Обращения (основной)",
"portalUser": "Пользователь портала"
},
"labels": {
"Create Contact": "Создать контакт"
},
"options": {
"opportunityRole": {
"": "Нет",
"Decision Maker": "Принимающий решение",
"Evaluator": "Оценщик",
"Influencer": "Консультант"
}
}
},
"presetFilters": {
"portalUsers": "Пользователи порталов",
"notPortalUsers": "Не пользователи порталов"
}
}
@@ -1,32 +1,42 @@
{
"labels": {
"Create Document": "Create Document",
"Details": "Описание"
"labels": {
"Create Document": "Создать документ",
"Details": "Описание"
},
"fields": {
"name": "Название",
"status": "Статус",
"file": "Файл",
"type": "Тип",
"source": "Источник",
"publishDate": "Опубликован",
"expirationDate": "Актуален до",
"description": "Описание",
"accounts": "Контрагенты",
"folder": "Папка"
},
"links": {
"accounts": "Контрагенты",
"opportunities": "Сделки",
"folder": "Папка"
},
"options": {
"status": {
"Active": "Действующий",
"Draft": "Черновик",
"Expired": "Просрочен",
"Canceled": "Отменен"
},
"fields": {
"name": "Name",
"status": "статус",
"file": "File",
"type": "Type",
"source": "Source",
"publishDate": "Publish Date",
"expirationDate": "Expiration Date",
"description": "Описание"
},
"links": {
"accounts": "Контрагенты",
"opportunities": "Сделки"
},
"options": {
"status": {
"Active": "Активный",
"Draft": "Черновик",
"Expired": "Expired",
"Canceled": "Отменена"
}
},
"presetFilters": {
"active": "Активный",
"draft": "Черновик"
"type": {
"": "Нет",
"Contract": "Contract",
"NDA": "NDA",
"EULA": "EULA",
"License Agreement": "License Agreement"
}
}
},
"presetFilters": {
"active": "Действующий",
"draft": "Черновик"
}
}
@@ -0,0 +1,9 @@
{
"labels": {
"Create DocumentFolder": "Создать папку",
"Manage Categories": "Управление папками"
},
"links": {
"documents": "Документы"
}
}
@@ -0,0 +1,8 @@
{
"labels": {
"Create Lead": "Создать кандидата",
"Create Contact": "Создать контакт",
"Create Task": "Создать задачу",
"Create Case": "Создать обращение"
}
}
@@ -0,0 +1,28 @@
{
"fields": {
"name": "Название",
"status": "Статус",
"target": "Цель",
"sentAt": "Дата отправки",
"attemptCount": "Попыток",
"emailAddress": "Адрес эл. почты",
"massEmail": "Массовая рассылка эл. писем",
"isTest": "Тест"
},
"links": {
"target": "Цель",
"massEmail": "Массовая рассылка эл. писем"
},
"options": {
"status": {
"Pending": "В ожидании",
"Sent": "Отправлено",
"Failed": "Сбой"
}
},
"presetFilters": {
"pending": "В ожидании",
"sent": "Отправлено",
"failed": "Сбой"
}
}
@@ -1,90 +1,115 @@
{
"scopeNames": {
"Account": "Контрагент",
"Contact": "Контакт",
"Lead": "Потенциальный клиент",
"Target": "Цель",
"Opportunity": "Cделка",
"Meeting": "Встреча",
"Calendar": "Календарь",
"Call": "Вызов",
"Task": "Задача",
"Case": "Обращение",
"InboundEmail": "Входящая почта",
"Document": "Document"
},
"scopeNamesPlural": {
"Account": "Контрагенты",
"Contact": "Контакты",
"Lead": "Потенциальные клиенты",
"Target": "Цели",
"Opportunity": "Сделки",
"Meeting": "Встречи",
"Calendar": "Календарь",
"Call": "Звонки",
"Task": "Задачи",
"Case": "Обращения",
"InboundEmail": "Inbound Emails",
"Document": "Documents"
},
"dashlets": {
"Leads": "Мои потенциальные клиенты",
"Opportunities": "Мои сделки",
"Tasks": "Мои задачи",
"Cases": "Мои обращения",
"Calendar": "Календарь",
"Calls": "Мои звонки",
"Meetings": "Мои встречи",
"OpportunitiesByStage": "Сделки по стадии",
"OpportunitiesByLeadSource": "Сделки по источнику потенциального клиента",
"SalesByMonth": "Продажи по месяцам",
"SalesPipeline": "Источники продаж"
},
"labels": {
"Create InboundEmail": "Создать входящую почту",
"Activities": "Мероприятия",
"History": "История",
"Attendees": "Участники",
"Schedule Meeting": "Запланировать встречу",
"Schedule Call": "Запланировать звонок",
"Compose Email": "Создать e-mail",
"Log Meeting": "Записать встречу",
"Log Call": "Записать звонок",
"Archive Email": "Отправить письмо в архив",
"Create Task": "Создать задачу",
"Tasks": "Задачи"
},
"fields": {
"billingAddressCity": "Город",
"billingAddressCountry": "Страна",
"billingAddressPostalCode": "Почтовый индекс",
"billingAddressState": "Регион",
"billingAddressStreet": "Улица",
"addressCity": "Город",
"addressStreet": "Улица",
"addressCountry": "Страна",
"addressState": "Регион",
"addressPostalCode": "Почтовый индекс",
"shippingAddressCity": "Город доставки",
"shippingAddressStreet": "Улица доставки",
"shippingAddressCountry": "Страна доставки",
"shippingAddressState": "Регион доставки",
"shippingAddressPostalCode": "Почтовый код доставки"
},
"links": {
"contacts": "Контакты",
"opportunities": "Сделки",
"leads": "Потенциальные клиенты",
"meetings": "Встречи",
"calls": "Звонки",
"tasks": "Задачи",
"emails": "Письма",
"accounts": "Контрагенты",
"cases": "Обращения",
"documents": "Documents",
"account": "Контрагент",
"opportunity": "Cделка",
"contact": "Контакт",
"parent": "Источник"
"links": {
"parent": "Источник",
"contacts": "Контакты",
"opportunities": "Сделки",
"leads": "Кандидаты",
"meetings": "Встречи",
"calls": "Звонки",
"tasks": "Задачи",
"emails": "Эл. письма",
"accounts": "Контрагенты",
"cases": "Обращения",
"documents": "Документы",
"account": "Контрагент",
"opportunity": "Cделка",
"contact": "Контакт"
},
"scopeNames": {
"Account": "Контрагент",
"Contact": "Контакт",
"Lead": "Кандидат",
"Target": "Цель",
"Opportunity": "Cделка",
"Meeting": "Встреча",
"Calendar": "Календарь",
"Call": "Звонок",
"Task": "Задача",
"Case": "Обращение",
"Document": "Документ",
"DocumentFolder": "Папка с документами",
"Campaign": "Кампания",
"TargetList": "Список целей",
"MassEmail": "Массовая рассылка эл. писем",
"EmailQueueItem": "Email Queue Item",
"CampaignTrackingUrl": "Целевой URL-адрес",
"Activities": "Действия",
"KnowledgeBaseArticle": "Статья базы знаний",
"KnowledgeBaseCategory": "Категория базы знаний"
},
"scopeNamesPlural": {
"Account": "Контрагенты",
"Contact": "Контакты",
"Lead": "Кандидаты",
"Target": "Цели",
"Opportunity": "Сделки",
"Meeting": "Встречи",
"Calendar": "Календари",
"Call": "Звонки",
"Task": "Задачи",
"Case": "Обращения",
"Document": "Документы",
"DocumentFolder": "Папки с документами",
"Campaign": "Кампании",
"TargetList": "Списки целей",
"MassEmail": "Массовые рассылки эл. писем",
"EmailQueueItem": "Email Queue Items",
"CampaignTrackingUrl": "Целевые URL-адреса",
"Activities": "Действия",
"KnowledgeBaseArticle": "Статьи базы знаний",
"KnowledgeBaseCategory": "Категории базы знаний"
},
"dashlets": {
"Leads": "Мои кандидаты",
"Opportunities": "Мои сделки",
"Tasks": "Мои задачи",
"Cases": "Мои обращения",
"Calendar": "Календарь",
"Calls": "Мои звонки",
"Meetings": "Мои встречи",
"OpportunitiesByStage": "Сделки по стадиям",
"OpportunitiesByLeadSource": "Сделки по источнику кандидатов",
"SalesByMonth": "Продажи по месяцам",
"SalesPipeline": "Источники продаж",
"Activities": "Мои действия"
},
"labels": {
"Create InboundEmail": "Create Inbound Email",
"Activities": "Действия",
"History": "История",
"Attendees": "Участники",
"Schedule Meeting": "Запланировать встречу",
"Schedule Call": "Запланировать звонок",
"Compose Email": "Написать эл. письмо",
"Log Meeting": "Записать встречу",
"Log Call": "Записать звонок",
"Archive Email": "Отправить эл. письмо в архив",
"Create Task": "Создать задачу",
"Tasks": "Задачи"
},
"fields": {
"billingAddressCity": "Город",
"addressCity": "Город",
"billingAddressCountry": "Страна",
"addressCountry": "Страна",
"billingAddressPostalCode": "Индекс",
"addressPostalCode": "Индекс",
"billingAddressState": "Регион",
"addressState": "Регион",
"billingAddressStreet": "Улица",
"addressStreet": "Улица",
"billingAddressMap": "Карта",
"addressMap": "Карта",
"shippingAddressCity": "Город доставки",
"shippingAddressStreet": "Улица доставки",
"shippingAddressCountry": "Страна доставки",
"shippingAddressState": "Регион доставки",
"shippingAddressPostalCode": "Индекс доставки"
},
"options": {
"reminderTypes": {
"Popup": "Всплывающее окно",
"Email": "Эл. письмо"
}
}
}
}
@@ -0,0 +1,42 @@
{
"labels": {
"Create KnowledgeBaseArticle": "Создать статью",
"Any": "Любой"
},
"fields": {
"name": "Название",
"status": "Статус",
"type": "Тип",
"attachments": "Вложения",
"publishDate": "Опубликована",
"expirationDate": "Актуальна до",
"description": "Описание",
"body": "Тело",
"categories": "Категории",
"language": "Язык",
"portals": "Порталы"
},
"links": {
"cases": "Обращения",
"opportunities": "Сделки",
"categories": "Категории",
"portals": "Порталы"
},
"options": {
"status": {
"In Review": "На рассмотрении",
"Draft": "Черновик",
"Archived": "В архиве",
"Published": "Опубликована"
},
"type": {
"Article": "Статья"
}
},
"tooltips": {
"portals": "Если не пусто, то эта статья будет доступна только в указанных порталах. Если пусто, то будет доступна во всех порталах."
},
"presetFilters": {
"published": "Опубликована"
}
}
@@ -0,0 +1,9 @@
{
"labels": {
"Create KnowledgeBaseCategory": "Создать категорию",
"Manage Categories": "Управление категориями"
},
"links": {
"articles": "Статьи"
}
}
@@ -1,51 +1,62 @@
{
"labels": {
"Converted To": "Преобразован в",
"Create Lead": "Создать потенциального клиента",
"Convert": "Преобразовать"
"labels": {
"Converted To": "Преобразован в",
"Create Lead": "Создать кандидата",
"Convert": "Преобразовать"
},
"fields": {
"name": "Имя",
"emailAddress": "Адрес эл. почты",
"title": "Должность",
"website": "Сайт",
"phoneNumber": "Телефон",
"accountName": "Контрагент",
"doNotCall": "Не звонить",
"address": "Адрес",
"status": "Статус",
"source": "Источник",
"opportunityAmount": "Сумма сделки",
"opportunityAmountConverted": "Сумма сделки (сконвертированная)",
"description": "Описание",
"createdAccount": "Контрагент",
"createdContact": "Контакт",
"createdOpportunity": "Cделка",
"campaign": "Кампания",
"targetLists": "Списки целей",
"targetList": "Список целей"
},
"links": {
"targetLists": "Списки целей",
"campaignLogRecords": "Журнал кампании",
"campaign": "Кампания",
"createdAccount": "Контрагент",
"createdContact": "Контакт",
"createdOpportunity": "Cделка"
},
"options": {
"status": {
"New": "Новый",
"Assigned": "Назначен",
"In Process": "В процессе",
"Converted": "Преобразован",
"Recycled": "Удален",
"Dead": "Мертв"
},
"fields": {
"name": "Name",
"emailAddress": "Email",
"title": "Название",
"website": "Интернет сайт",
"phoneNumber": "Phone",
"accountName": "Имя контрагента",
"doNotCall": "Не звонить",
"address": "Address",
"status": "статус",
"source": "Source",
"opportunityAmount": "Сумма сделки",
"opportunityAmountConverted": "Сумма сделки (конвертирован)",
"description": "Описание",
"createdAccount": "Контрагент",
"createdContact": "Контакт",
"createdOpportunity": "Cделка"
},
"links": {
},
"options": {
"status": {
"New": "Новый",
"Assigned": "На рассмотрении",
"In Process": "В процессе",
"Converted": "Преобразовано",
"Recycled": "Восстановленный",
"Dead": "Мертв"
},
"source": {
"Call": "Вызов",
"Email": "Email",
"Existing Customer": "Existing Customer",
"Partner": "Партнер",
"Public Relations": "Public Relations",
"Web Site": "Web Site",
"Campaign": "Campaign",
"Other": "Дополнительно"
}
},
"presetFilters": {
"actual": "Актуальные",
"active": "Активные"
"source": {
"": "Нет",
"Call": "Звонок",
"Email": "Эл. письмо",
"Existing Customer": "Существующий клиент",
"Partner": "Партнер",
"Public Relations": "Связи с общественностью",
"Web Site": "Сайт",
"Campaign": "Кампания",
"Other": "Другое"
}
}
},
"presetFilters": {
"active": "Активный",
"actual": "Актуальный",
"converted": "Преобразованный"
}
}
@@ -0,0 +1,49 @@
{
"fields": {
"name": "Название",
"status": "Статус",
"storeSentEmails": "Сохранять отправленные эл. письма",
"startAt": "Дата начала",
"fromAddress": "Адрес отправителя",
"fromName": "Имя отправителя",
"replyToAddress": "Обратный адрес",
"replyToName": "Имя для обратного адреса",
"campaign": "Кампания",
"emailTemplate": "Шаблон эл. письма",
"inboundEmail": "Учетная запись эл. почты",
"targetLists": "Списки целей",
"excludingTargetLists": "Исключая списки целей",
"optOutEntirely": "Отписать навсегда"
},
"links": {
"targetLists": "Списки целей",
"excludingTargetLists": "Исключая списки целей",
"queueItems": "Queue Items",
"campaign": "Кампания",
"emailTemplate": "Шаблон эл. письма",
"inboundEmail": "Учетная запись эл. почты"
},
"options": {
"status": {
"Draft": "Черновик",
"Pending": "В ожидании",
"In Process": "В процессе",
"Complete": "Завершена",
"Canceled": "Отменена",
"Failed": "Сбой"
}
},
"labels": {
"Create MassEmail": "Создать массовую рассылку эл. писем",
"Send Test": "Отправить тестовое эл. письмо"
},
"messages": {
"selectAtLeastOneTarget": "Выберите хотя бы одну цель",
"testSent": "Должно отправиться тестовое эл. письмо"
},
"tooltips": {
"optOutEntirely": "Адреса эл. почты получателей, которые отписались будут помечены как отписавшиеся и больше не будут получать массовые рассылки эл. писем.",
"targetLists": "Цели которые должны получить сообщения.",
"excludingTargetLists": "Цели которые не должны получить сообщения."
}
}
@@ -1,40 +1,46 @@
{
"fields": {
"name": "Имя",
"parent": "Источник",
"status": "Статус",
"dateStart": "Дата начала",
"dateEnd": "Дата окончания",
"duration": "Длительность",
"description": "Описание",
"users": "Пользователи",
"contacts": "Контакты",
"leads": "Потенциальные клиенты",
"reminders": "Напоминания"
"fields": {
"name": "Название",
"parent": "Источник",
"status": "Статус",
"dateStart": "Дата начала",
"dateEnd": "Дата окончания",
"duration": "Длительность",
"description": "Описание",
"users": "Пользователи",
"contacts": "Контакты",
"leads": "Кандидаты",
"reminders": "Напоминания",
"account": "Контрагент"
},
"options": {
"status": {
"Planned": "Запланирована",
"Held": "Состоялась",
"Not Held": "Не состоялась"
},
"links": {
},
"options": {
"status": {
"Planned": "Запланированный",
"Held": "Выполнен",
"Not Held": "Не состоялся"
},
"acceptanceStatus": {
"None": "Нет",
"Accepted": "Accepted",
"Declined": "Declined"
}
},
"labels": {
"Create Meeting": "Создать встречу",
"Set Held": "Был выполнен",
"Set Not Held": "Set Not Held",
"Send Invitations": "Отправить приглашения"
},
"presetFilters": {
"planned": "Запланированные",
"held": "Завершенные",
"todays": "На сегодня"
"acceptanceStatus": {
"None": "Нет",
"Accepted": "Согласен",
"Declined": "Не согласен",
"Tentative": "Есть сомнения"
}
}
},
"massActions": {
"setHeld": "Состоялось",
"setNotHeld": "Не состоялось"
},
"labels": {
"Create Meeting": "Создать встречу",
"Set Held": "Состоялось",
"Set Not Held": "Не состоялось",
"Send Invitations": "Отправить приглашения",
"on time": "во время",
"before": "до начала"
},
"presetFilters": {
"planned": "Запланированные",
"held": "Завершенные",
"todays": "На сегодня"
}
}
@@ -1,41 +1,44 @@
{
"fields": {
"name": "Name",
"account": "Контрагент",
"stage": "Стадия",
"amount": "Сумма",
"probability": "Вероятность успеха, %",
"leadSource": "Источник потенциального клиента",
"doNotCall": "Не звонить",
"closeDate": "Дата закрытия",
"contacts": "Контакты",
"description": "Описание",
"amountConverted": "Сумма (сконвертирована)",
"amountWeightedConverted": "Amount Weighted"
},
"links": {
"contacts": "Контакты",
"documents": "Documents"
},
"options": {
"stage": {
"Prospecting": "Привлечение клиента",
"Qualification": "Оценка возможности",
"Needs Analysis": "Требует анализа",
"Value Proposition": "Выбор предложения/оферты",
"Id. Decision Makers": "Определение ответственного лица",
"Perception Analysis": "Проведение анализа",
"Proposal/Price Quote": "Отправлено предложение/оферта",
"Negotiation/Review": "Согласование/рассмотрение",
"Closed Won": "Закрыто - Успех",
"Closed Lost": "Закрыто - Провал"
}
},
"labels": {
"Create Opportunity": "Создать сделку"
},
"presetFilters": {
"open": "Открыть",
"won": "Успешные"
"fields": {
"name": "Название",
"account": "Контрагент",
"stage": "Стадия",
"amount": "Сумма",
"probability": "Вероятность успеха, %",
"leadSource": "Источник кандидата",
"doNotCall": "Не звонить",
"closeDate": "Дата закрытия",
"contacts": "Контакты",
"description": "Описание",
"amountConverted": "Сумма (сконвертированная)",
"amountWeightedConverted": "Сумма (средневзвешенная)",
"campaign": "Кампания"
},
"links": {
"contacts": "Контакты",
"documents": "Документы",
"campaign": "Кампания"
},
"options": {
"stage": {
"Prospecting": "Привлечение клиента",
"Qualification": "Оценка возможности",
"Needs Analysis": "Требует анализа",
"Value Proposition": "Выбор предложения/оферты",
"Id. Decision Makers": "Определение ответственного лица",
"Perception Analysis": "Проведение анализа",
"Proposal/Price Quote": "Отправлено предложение/оферта",
"Negotiation/Review": "Согласование/рассмотрение",
"Closed Won": "Закрыто - Успех",
"Closed Lost": "Закрыто - Провал"
}
}
},
"labels": {
"Create Opportunity": "Создать сделку"
},
"presetFilters": {
"open": "Открыть",
"won": "Успешные",
"lost": "Провальные"
}
}
@@ -0,0 +1,5 @@
{
"links": {
"articles": "Статьи базы знаний"
}
}
@@ -0,0 +1,8 @@
{
"options": {
"job": {
"ProcessMassEmail": "Отправка массовых рассылок эл. писем",
"ControlKnowledgeBaseArticleStatus": "Контроль статуса статей базы знаний"
}
}
}
@@ -1,19 +1,17 @@
{
"fields": {
"name": "Name",
"emailAddress": "Email",
"title": "Название",
"website": "Интернет сайт",
"accountName": "Имя контрагента",
"phoneNumber": "Phone",
"doNotCall": "Не звонить",
"address": "Address",
"description": "Описание"
},
"links": {
},
"labels": {
"Create Target": "Создать цель",
"Convert to Lead": "Преобразовать в потенциального клиента"
}
}
"fields": {
"name": "Имя",
"emailAddress": "Адрес эл. почты",
"title": "Должность",
"website": "Сайт",
"accountName": "Контрагент",
"phoneNumber": "Телефон",
"doNotCall": "Не звонить",
"address": "Адрес",
"description": "Описание"
},
"labels": {
"Create Target": "Создать цель",
"Convert to Lead": "Преобразовать в кандидата"
}
}
@@ -0,0 +1,32 @@
{
"fields": {
"name": "Название",
"description": "Описание",
"entryCount": "Количество",
"campaigns": "Кампании",
"endDate": "Дата окончания",
"targetLists": "Списки целей"
},
"links": {
"accounts": "Контрагенты",
"contacts": "Контакты",
"leads": "Кандидаты",
"campaigns": "Кампании",
"massEmails": "Массовые рассылки эл. писем"
},
"options": {
"type": {
"Email": "Эл. письмо",
"Web": "Интернет",
"Television": "Телевидение",
"Radio": "Радио",
"Newsletter": "Информационный бюллетень"
}
},
"labels": {
"Create TargetList": "Создать список целей",
"Opted Out": "Отписавшиеся",
"Cancel Opt-Out": "Отменить отписку",
"Opt-Out": "Отписать"
}
}
@@ -1,38 +1,45 @@
{
"fields": {
"name": "Имя",
"parent": "Источник",
"status": "Статус",
"dateStart": "Дата начала",
"dateEnd": "Date Due",
"priority": "Приоритет",
"description": "Описание",
"isOverdue": "Просрочена"
"fields": {
"name": "Название",
"parent": "Источник",
"status": "Статус",
"dateStart": "Дата начала",
"dateEnd": "Дата окончания",
"dateStartDate": "Дата начала (весь день)",
"dateEndDate": "Дата окончания (весь день)",
"priority": "Приоритет",
"description": "Описание",
"isOverdue": "Просрочена",
"account": "Контрагент",
"dateCompleted": "Дата завершения",
"attachments": "Вложения"
},
"links": {
"attachments": "Вложения"
},
"options": {
"status": {
"Not Started": "Не началась",
"Started": "Началась",
"Completed": "Завершена",
"Canceled": "Отменена",
"Deferred": "Отложена"
},
"links": {
},
"options": {
"status": {
"Not Started": "Не началась",
"Started": "Началась",
"Completed": "Завершена",
"Canceled": "Отменена"
},
"priority" : {
"Low": "Низкий",
"Normal": "Нормальный",
"High": "Высокий",
"Urgent": "Срочно"
}
},
"labels": {
"Create Task": "Создать задачу",
"Complete": "Завершить"
},
"presetFilters": {
"actual": "Актуальные",
"completed": "Завершенные",
"todays": "На сегодня",
"overdue": "Просроченные"
"priority": {
"Low": "Низкий",
"Normal": "Обычный",
"High": "Высокий",
"Urgent": "Срочно"
}
}
},
"labels": {
"Create Task": "Создать задачу",
"Complete": "Завершить"
},
"presetFilters": {
"actual": "Актуальные",
"completed": "Завершенные",
"todays": "На сегодня",
"overdue": "Просроченные"
}
}
@@ -0,0 +1,5 @@
{
"links": {
"targetLists": "Списки целей"
}
}
@@ -35,10 +35,10 @@
"Mail": "Пошта"
},
"status": {
"Planning": "Планування",
"Planning": "Запланований",
"Active": "Активний",
"Inactive": "Неактивний",
"Complete": "Повне"
"Complete": "Завершений"
}
},
"labels": {
@@ -36,7 +36,7 @@
"Create Case": "Створити кейс"
},
"presetFilters": {
"open": "Відкрити",
"open": "Відкрито",
"closed": "Закрито"
}
}
@@ -34,7 +34,7 @@
},
"labels": {
"Create Task": "Створити завдання",
"Complete": "Повне"
"Complete": "Завершити"
},
"presetFilters": {
"actual": "Актуально",
@@ -3,7 +3,7 @@
"label":"",
"rows":[
[{"name":"name"}],
[{"name":"website"}],
[{"name":"website"}, {"name": "billingAddressCountry"}],
[{"name":"emailAddress"}],
[{"name":"phoneNumber"}],
[{"name":"type"}, {"name":"industry"}]
@@ -1,6 +1,6 @@
[
{"name":"name","width":30,"link":true},
{"name":"website", "notSortable": true},
{"name":"phoneNumber", "notSortable": true},
{"name":"billingAddressCity"}
{"name":"name","link":true},
{"name":"website", "notSortable": true, "width": 25},
{"name":"type", "width": 16},
{"name":"billingAddressCountry", "width": 18}
]
@@ -1,4 +1,4 @@
[
{"name":"name","width":50,"link":"true"},
{"name":"billingAddressCity"}
{"name":"billingAddressCountry"}
]
@@ -1,6 +1,6 @@
[
{"name":"name","width":25,"link":true},
{"name":"name", "link":true},
{"name":"account","width":25},
{"name":"emailAddress", "notSortable": true},
{"name":"phoneNumber", "notSortable": true}
{"name":"emailAddress", "notSortable": true, "width": 20},
{"name":"phoneNumber", "notSortable": true, "width": 18}
]
@@ -12,7 +12,7 @@
{"name":"phoneNumber", "fullWidth": true}
],
[
{"name":"accountName", "fullWidth": true}
{"name":"accountName"}, {"name":"addressCountry"}
],
[
{"name":"title"}, {"name":"website"}
@@ -8,6 +8,7 @@
"dateEnd",
"modifiedAt",
"status",
"parent",
"priority",
"teams"
]
@@ -11,6 +11,12 @@
"scopeFieldLevel": {
"KnowledgeBaseArticle": {
"portals": false
},
"Case": {
"status": {
"read": "yes",
"edit": "no"
}
}
}
}
@@ -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"
}
}
@@ -1,51 +1,51 @@
{
"controller": "controllers/record",
"recordViews": {
"detail": "crm:views/case/record/detail"
},
"bottomPanels":{
"detail":[
]
},
"sidePanels":{
"detail":[
{
"name":"activities",
"label":"Activities",
"view":"crm:views/record/panels/activities",
"aclScope": "Activities"
},
{
"name":"history",
"label":"History",
"view":"crm:views/record/panels/history",
"aclScope": "Activities"
},
{
"name":"tasks",
"label":"Tasks",
"view":"crm:views/record/panels/tasks",
"aclScope": "Task"
}
]
},
"filterList": [
{
"name":"open"
},
{
"name":"closed",
"style": "success"
}
],
"relationshipPanels": {
"articles": {
"create": false,
"rowActionsView": "views/record/row-actions/relationship-view-and-unlink"
}
},
"boolFilterList": ["onlyMy"],
"selectDefaultFilters": {
"filter": "open"
}
"controller": "controllers/record",
"recordViews": {
"detail": "crm:views/case/record/detail"
},
"bottomPanels":{
"detail":[
]
},
"sidePanels":{
"detail":[
{
"name":"activities",
"label":"Activities",
"view":"crm:views/case/record/panels/activities",
"aclScope": "Activities"
},
{
"name":"history",
"label":"History",
"view":"crm:views/record/panels/history",
"aclScope": "Activities"
},
{
"name":"tasks",
"label":"Tasks",
"view":"crm:views/record/panels/tasks",
"aclScope": "Task"
}
]
},
"filterList": [
{
"name":"open"
},
{
"name":"closed",
"style": "success"
}
],
"relationshipPanels": {
"articles": {
"create": false,
"rowActionsView": "views/record/row-actions/relationship-view-and-unlink"
}
},
"boolFilterList": ["onlyMy"],
"selectDefaultFilters": {
"filter": "open"
}
}
@@ -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"
@@ -61,7 +61,8 @@
},
"sicCode": {
"type": "varchar",
"maxLength": 40
"maxLength": 40,
"trim": true
},
"contactRole": {
"type": "varchar",
@@ -139,7 +140,8 @@
"view": "views/fields/assigned-user"
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"targetLists": {
"type": "linkMultiple",
@@ -270,7 +272,8 @@
},
"collection": {
"sortBy": "name",
"asc": true
"asc": true,
"textFilterFields": ["name", "emailAddress"]
},
"indexes": {
"name": {
@@ -31,7 +31,8 @@
"start": "dateStart",
"end": "dateEnd",
"options": [300, 600, 900, 1800, 2700, 3600, 7200],
"default": 300
"default": 300,
"notStorable": true
},
"reminders": {
"type": "jsonArray",
@@ -108,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": {
@@ -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",
@@ -2,7 +2,8 @@
"fields": {
"name": {
"type": "varchar",
"required": true
"required": true,
"trim": true
},
"url": {
"type": "url",
@@ -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": {
@@ -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,9 +36,33 @@
"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
},
"description": {
"type": "text"
@@ -76,7 +103,7 @@
},
"accounts": {
"type": "linkMultiple",
"view": "Crm:Contact.Fields.Accounts",
"view": "crm:views/contact/fields/accounts",
"columns": {
"role": "contactRole"
}
@@ -129,7 +156,8 @@
"view": "views/fields/assigned-user"
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"targetLists": {
"type": "linkMultiple",
@@ -3,7 +3,8 @@
"name": {
"type": "varchar",
"required": true,
"view": "crm:views/document/fields/name"
"view": "crm:views/document/fields/name",
"trim": true
},
"file": {
"type": "file",
@@ -60,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",
@@ -2,7 +2,8 @@
"fields": {
"name": {
"type": "varchar",
"required": true
"required": true,
"trim": true
},
"description": {
"type": "text"
@@ -24,7 +25,8 @@
"readOnly": true
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"parent": {
"type": "link"
@@ -2,7 +2,8 @@
"fields": {
"name": {
"type": "varchar",
"required": true
"required": true,
"trim": true
},
"status": {
"type": "enum",
@@ -50,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",
@@ -2,7 +2,8 @@
"fields": {
"name": {
"type": "varchar",
"required": true
"required": true,
"trim": true
},
"description": {
"type": "text"
@@ -28,7 +29,8 @@
"required": true
},
"teams": {
"type": "linkMultiple"
"type": "linkMultiple",
"view": "views/fields/teams"
},
"parent": {
"type": "link"
@@ -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",
@@ -31,7 +31,8 @@
"start": "dateStart",
"end": "dateEnd",
"options": [900, 1800, 3600, 7200, 10800, 86400],
"default": 3600
"default": 3600,
"notStorable": true
},
"reminders": {
"type": "jsonArray",
@@ -103,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": {
@@ -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": {
@@ -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": {
@@ -2,7 +2,8 @@
"fields": {
"name": {
"type": "varchar",
"required": true
"required": true,
"trim": true
},
"entryCount": {
"type": "int",
@@ -32,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"
@@ -47,7 +47,7 @@
"type": "bool",
"readOnly": true,
"notStorable": true,
"view": "Crm:Task.Fields.IsOverdue",
"view": "crm:views/task/fields/is-overdue",
"disabled": true
},
"description": {
@@ -82,14 +82,16 @@
"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",
"sourceList": ["Document"]
"sourceList": ["Document"],
"layoutListDisabled": true
}
},
"links": {
@@ -134,9 +136,6 @@
"dateStart": {
"columns": ["dateStart", "deleted"]
},
"dateEnd": {
"columns": ["dateStart", "deleted"]
},
"status": {
"columns": ["status", "deleted"]
},
@@ -3,7 +3,7 @@
"layouts": true,
"tab": true,
"acl": true,
"aclPortal": "recordAllAccountOwnNo",
"aclPortal": "recordAllAccountNo",
"module": "Crm",
"customizable": true,
"stream": true,

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