Compare commits

..

179 Commits
4.0.4 ... 4.1.2

Author SHA1 Message Date
yuri
3c5fe4c778 v 2016-05-20 15:41:08 +03:00
yuri
f6f3f05aa5 fix meeting acl 2016-05-20 15:39:51 +03:00
yuri
10f34564d0 load teams for user 2016-05-20 15:38:40 +03:00
yuri
216ec2329d fix record isPermittedTeams 2016-05-20 15:30:49 +03:00
yuri
c3cb4619cf disable formatting for autoincrement 2016-05-20 11:21:06 +03:00
yuri
fcf2929b5b fix record/base 2016-05-19 17:56:19 +03:00
yuri
15c10ca553 fix notice 2016-05-18 16:38:40 +03:00
yuri
9bb417ab38 v 2016-05-18 16:32:25 +03:00
yuri
5b110ee7b2 fix warning 2016-05-18 16:30:46 +03:00
yuri
f3951966f3 fix popup 2016-05-18 16:25:20 +03:00
yuri
f580f0ba60 namimng 2016-05-18 12:34:53 +03:00
yuri
a9e4ad3833 sidePanels refactoring 2016-05-18 11:22:18 +03:00
yuri
3e6c88eb27 lead-document relationship 2016-05-17 17:16:33 +03:00
yuri
7c4ef3f00f query: use distinct instead of group by id 2016-05-17 15:51:08 +03:00
yuri
762d7f71c6 fix date time 2016-05-17 11:18:30 +03:00
yuri
50cc658c20 fix campaign image 2016-05-16 16:09:18 +03:00
yuri
21a59cb198 Merge branch 'master' of ssh://172.20.0.1/var/git/espo/backend 2016-05-16 12:56:36 +03:00
Taras Machyshyn
38ba3461be Fixed SemVer for PHP 7 2016-05-16 12:55:51 +03:00
yuri
f70ee27809 remove notes from user layout 2016-05-16 10:59:08 +03:00
yuri
674c1588d9 iOS 9 support 2016-05-13 12:40:26 +03:00
yuri
e9eb5402cc fix selector 2016-05-11 17:35:55 +03:00
yuri
7f746a72bb ui performance oprtimization 2016-05-11 16:22:02 +03:00
yuri
bde6a810c4 cleanup 2016-05-11 11:42:12 +03:00
yuri
ff3e7d1c5b fit add dashlet modal height 2016-05-11 11:41:27 +03:00
yuri
7ecb63189a fix full form from quick edit 2016-05-11 10:56:33 +03:00
yuri
eb1e16d6bd phone/email search more optimized way 2016-05-10 16:45:43 +03:00
yuri
f17b5d7244 small fix in RDB 2016-05-10 13:04:04 +03:00
yuri
a5b44e9fdf entity manager: text filter fields 2016-05-10 12:34:29 +03:00
yuri
734219dbd4 customUrl portal layout 2016-05-09 11:26:02 +03:00
yuri
45c351ab39 user entity small fixes 2016-05-09 11:22:06 +03:00
yuri
74aa55a8aa store sent emails 2016-05-09 11:19:14 +03:00
yuri
64b3a88ba0 fix shared calendar 2016-05-09 11:06:12 +03:00
yuri
08ff00f602 fix user select manager 2016-05-09 11:05:52 +03:00
yuri
0d9853311a inbox dashlet layout change 2016-05-06 12:54:24 +03:00
yuri
b1d17f9e84 fix shared calendar store 2016-05-06 12:02:00 +03:00
yuri
3a6041a8df shared calendar improvements 2016-05-06 11:57:37 +03:00
yuri
023171f19e merge 2016-05-05 15:17:29 +03:00
yuri
546fed83c8 version 4.0.6 2016-05-05 15:15:54 +03:00
yuri
6b37ce80fd fix kb 2016-05-05 15:14:32 +03:00
yuri
a98c8b3bcd naming 2016-05-05 13:08:28 +03:00
yuri
7bd3dd26cf notificationSoundsDisabled 2016-05-05 13:03:15 +03:00
yuri
fe7684b46c naming 2016-05-05 12:56:16 +03:00
yuri
ea5dcfe630 entity manager trimming 2016-05-05 12:12:40 +03:00
yuri
ad5f29338b field manager: trim 2016-05-05 11:59:35 +03:00
yuri
89d2b26613 cleanup 2016-05-05 11:10:56 +03:00
yuri
7206dc38bc meeting/call acl fix: allow read own record if no assigned 2016-05-05 11:08:26 +03:00
yuri
4b9ff21743 version 4.2.0 2016-05-04 17:05:09 +03:00
yuri
fbe7910349 merge 2016-05-04 16:32:19 +03:00
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
b64db89307 fix acl 2016-05-04 16:17:25 +03:00
yuri
cb9b7c3e72 code fix suite 2016-05-04 16:16:57 +03:00
yuri
a268962c15 dont save email reminder 2016-05-04 15:16:29 +03:00
yuri
36c1b56916 scheduled job mass update 2016-05-04 14:51:49 +03:00
yuri
39a2e30e3f version 2016-05-04 11:29:12 +03:00
yuri
b91d237f0b portal users activities 2016-05-04 11:25:12 +03:00
yuri
f7a0a0daa0 config textFilterUseContainsForVarchar 2016-05-04 10:52:25 +03:00
yuri
4f270d003b linkParent field entityList filtered by disabled 2016-05-04 10:23:34 +03:00
yuri
e3ebc8c2e2 portal customUrl and fix 2016-05-04 09:57:42 +03:00
yuri
c31c5618dd fix portal user sendPassword 2016-05-04 09:47:10 +03:00
yuri
341d5f8d7c fix InboundEmail namespace 2016-05-04 09:45:24 +03:00
yuri
04d2bd69c1 fix jobs 2016-04-29 16:40:05 +03:00
yuri
47efa792ee kb/documents buttons 2016-04-29 12:15:04 +03:00
yuri
a71c6789bc fix dateTimeOptional required 2016-04-29 11:49:50 +03:00
yuri
3a41aad935 fix job.php 2016-04-28 17:14:42 +03:00
yuri
fad56c1c0a email craetedAt filter 2016-04-28 17:09:08 +03:00
yuri
d6ad7f16c1 cron populate logic 2016-04-28 16:16:31 +03:00
yuri
ae89a9216d fix email importer 2016-04-28 15:18:14 +03:00
yuri
6927c82a0f Application setupSystemUser 2016-04-28 11:00:12 +03:00
yuri
e06b553653 fix avatar 2016-04-27 16:24:11 +03:00
yuri
e9a63c0c36 merge all links 2016-04-27 12:26:06 +03:00
yuri
582c23ecf4 metadata get by array 2016-04-27 12:24:42 +03:00
yuri
d86ff1e905 user mass update layout change 2016-04-27 11:43:33 +03:00
yuri
773bca8448 user mass update fix 2016-04-27 11:41:45 +03:00
yuri
a6258cd334 afterMassUpdate afterMassRemove methods 2016-04-27 11:41:35 +03:00
yuri
1cdf88ef9b cleanup 2016-04-27 11:41:14 +03:00
yuri
58ffbad422 fix jobs 2016-04-27 11:40:57 +03:00
yuri
aafcd5767e emails dashlet 2016-04-26 11:59:22 +03:00
yuri
2bfac8352b fix wysiwyg 2016-04-26 11:39:07 +03:00
yuri
954eff0c94 acl change 2016-04-26 11:36:42 +03:00
yuri
9692076ba8 int format 2016-04-26 11:08:30 +03:00
yuri
5ae64989eb system avatar color 2016-04-25 17:45:57 +03:00
yuri
3fd34fc48d show more after remove issue fix 2016-04-25 15:28:39 +03:00
yuri
94c207677f int count 2016-04-25 15:23:04 +03:00
yuri
39188f0b3a fix phone number import 2016-04-25 11:07:44 +03:00
yuri
7665ec2730 naming 2016-04-22 11:20:12 +03:00
yuri
bc57ac3065 fix task dashlet 2016-04-22 11:20:07 +03:00
yuri
6cf62736bb wysiwyg fix base tag 2016-04-20 17:59:46 +03:00
yuri
d5e78c1a7a field manager: foreign fielld 2016-04-20 15:37:18 +03:00
yuri
4a0aa1bca0 global search fix 2016-04-20 10:32:05 +03:00
yuri
2d06e8a801 calendar custom entity support 2016-04-19 16:32:40 +03:00
yuri
25b1479c23 fix layouts 2016-04-19 16:09:10 +03:00
yuri
09ab17f18b naming fix 2016-04-19 16:03:38 +03:00
yuri
be438a2f18 pl_PL fix 2016-04-19 11:51:48 +03:00
yuri
c9f91bb8da merge fix 2016-04-19 11:51:06 +03:00
yuri
cd01178151 fix activities service 2016-04-19 11:48:09 +03:00
yuri
3e8ed72246 mass update keep emails and phones 2016-04-19 11:32:56 +03:00
yuri
c500520130 remove dashlet confirmation 2016-04-18 16:45:48 +03:00
yuri
0fc2eb6817 fix lang 2016-04-18 16:42:43 +03:00
yuri
4db2f49233 fix json 2016-04-15 16:30:45 +03:00
yuri
8215c44be9 fix address format 2016-04-15 15:35:10 +03:00
yuri
dbee926a94 address formats 2016-04-15 15:28:54 +03:00
yuri
d85e13cae0 timeline today by default 2016-04-14 16:42:31 +03:00
yuri
370eee8d9d fix timeline lang 2016-04-14 16:34:26 +03:00
yuri
98f317cb1c calendar scope list for create 2016-04-14 12:43:17 +03:00
yuri
3ec9613b0e timeline and calendar less 2016-04-14 12:02:37 +03:00
yuri
8e27d50d5c about.tpl 2016-04-13 17:17:53 +03:00
yuri
fc50991317 fix deprecated ajax usage 2016-04-13 16:37:19 +03:00
yuri
52382bb958 fix deprecated moment usage 2016-04-13 16:22:41 +03:00
yuri
66fdd40659 timeline dashlet fix 2016-04-13 15:50:20 +03:00
yuri
f0f402a8b3 calendar timeline dashlet 2016-04-13 12:40:45 +03:00
yuri
591cbf4484 opp dashlet sorting 2016-04-13 10:00:10 +03:00
yuri
44d813bf5b fix person name template 2016-04-13 09:36:02 +03:00
yuri
fceff4ad7f calendar changes 2016-04-12 17:19:15 +03:00
yuri
f47b41928e fix view field 2016-04-12 17:14:58 +03:00
yuri
c559a97953 timeline dev 2016-04-11 17:16:14 +03:00
yuri
d1d64c84b0 fix typo 2016-04-11 12:46:16 +03:00
yuri
cb1f32ec3a Merge branch 'hotfix/4.0.5' 2016-04-11 11:36:13 +03:00
yuri
e76116810f fix calendar weekStart 2016-04-11 11:36:01 +03:00
yuri
974b69eed0 timeline dev 2016-04-08 17:20:38 +03:00
yuri
bb379c7a0e fix invitation 2016-04-08 10:30:00 +03:00
yuri
5664ede648 fix invitation 2016-04-08 10:28:31 +03:00
yuri
881a3db412 dev timeline 2016-04-08 10:26:53 +03:00
yuri
b74f1cc5d6 Merge branch 'hotfix/4.0.5' 2016-04-07 12:51:38 +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
920b6e2eba dev 2016-04-06 16:09:11 +03:00
yuri
6e7908de52 timeline dev 1 2016-04-05 16:22:13 +03:00
yuri
10de6aedbd Merge branch 'hotfix/4.0.5' 2016-04-05 11:23:46 +03:00
yuri
ce0efed7b8 fix calendar 2016-04-05 11:23:32 +03:00
yuri
204b9aa49d dev 2016-04-05 10:55:02 +03:00
yuri
ae1db7990e Merge branch 'hotfix/4.0.5' 2016-04-04 16:37:11 +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
182fc8b65e Merge branch 'hotfix/4.0.5' 2016-04-01 11:16:34 +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
c9db2687f5 fetch only header for emails w/ exceeding size 2016-03-31 12:38:37 +03:00
yuri
21252a6eb7 Merge branch 'hotfix/4.0.5' 2016-03-31 11:27:21 +03:00
yuri
1054050542 fix list modal 2 2016-03-31 11:27:12 +03:00
yuri
90e2d7ef0b cleanup 2016-03-31 11:24:56 +03:00
yuri
de9c1e7a20 merge 2016-03-31 11:24:30 +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
ffc22673f7 Merge branch 'hotfix/4.0.5' 2016-03-30 14:59:08 +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
dd55141422 Merge branch 'hotfix/4.0.5' 2016-03-30 10:36:14 +03:00
yuri
d3bcadce13 fix contact filter is empty account 2016-03-30 10:36:06 +03:00
yuri
99533a5416 dont show notification about note if no access to entity 2016-03-29 16:20:05 +03:00
yuri
4a288434bc lead - case 2016-03-29 16:00:40 +03:00
yuri
9218bce3e4 kb email addition 2016-03-29 15:36:50 +03:00
yuri
b566413b78 Merge branch 'hotfix/4.0.5' 2016-03-29 15:30:46 +03:00
yuri
f624b441e4 KB: send email 2016-03-29 15:30:01 +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
4a20d74258 Merge branch 'hotfix/4.0.4' 2016-03-25 16:02:53 +02:00
yuri
9abeb6aec8 Merge branch 'hotfix/4.0.4' 2016-03-25 05:01:28 -04:00
yuri
2ca40a6b4e Merge branch 'hotfix/4.0.4' 2016-03-23 17:01:30 +02:00
yuri
176fae228c Merge branch 'hotfix/4.0.4' 2016-03-23 16:57:33 +02:00
Yuri Kuznetsov
2a1df998eb Merge pull request #123 from ecm4u/master
allow "Ends With" and "Like (%)" on varchar field
2016-03-23 14:59:56 +02:00
yuri
78573b85b5 Merge branch 'hotfix/4.0.4' 2016-03-23 14:59:09 +02:00
yuri
2ac5695e45 case email compose fix 2016-03-22 12:02:44 +02:00
yuri
0af4ab54f9 calendar quick view 2016-03-22 11:50:46 +02:00
yuri
8da92966de Merge branch 'hotfix/4.0.4' 2016-03-22 10:41:47 +02:00
yuri
4cb42f8762 Merge branch 'hotfix/4.0.4' 2016-03-18 14:47:51 +02:00
yuri
a50361126f Merge branch 'hotfix/4.0.4' 2016-03-17 12:32:49 +02:00
yuri
037ef7ea78 Merge branch 'hotfix/4.0.4' 2016-03-16 12:49:17 +02:00
yuri
9991dd350f fix autoincrement 2016-03-16 12:48:18 +02:00
Heiko Robert
e839e505c8 en localisation for new search filter 2016-03-11 15:50:47 +01:00
Heiko Robert
7dc9c3e6b6 added search filter "Ends With", "Like" for varchar fields 2016-03-11 15:46:15 +01:00
358 changed files with 10900 additions and 2444 deletions

View File

@@ -34,7 +34,7 @@ module.exports = function (grunt) {
'client/lib/jquery.autocomplete.js',
'client/lib/bootstrap.min.js',
'client/lib/bootstrap-datepicker.js',
'client/lib/bull.min.js',
'client/lib/bull.js',
'client/src/namespace.js',
'client/src/exceptions.js',
'client/src/loader.js',

View File

@@ -78,6 +78,9 @@ class EntityManager extends \Espo\Core\Controllers\Base
if (!empty($data['sortDirection'])) {
$params['asc'] = $data['sortDirection'] === 'asc';
}
if (isset($data['textFilterFields']) && is_array($data['textFilterFields'])) {
$params['textFilterFields'] = $data['textFilterFields'];
}
$result = $this->getContainer()->get('entityManagerUtil')->create($name, $type, $params);

View File

@@ -97,8 +97,6 @@ class Table
throw new Error('User must be fetched before ACL check.');
}
$this->user->loadLinkMultipleField('teams');
if ($fileManager) {
$this->fileManager = $fileManager;
}
@@ -119,7 +117,7 @@ class Table
protected function initCacheFilePath()
{
$this->cacheFilePath = 'data/cache/application/acl/' . $this->user->id . '.php';
$this->cacheFilePath = 'data/cache/application/acl/' . $this->getUser()->id . '.php';
}
protected function getUser()
@@ -192,7 +190,7 @@ class Table
$aclTableList = [];
$fieldTableList = [];
if (!$this->user->isAdmin()) {
if (!$this->getUser()->isAdmin()) {
$roleList = $this->getRoleList();
foreach ($roleList as $role) {
@@ -242,7 +240,7 @@ class Table
$this->fillFieldTableQuickAccess();
if (!$this->user->isAdmin()) {
if (!$this->getUser()->isAdmin()) {
foreach ($this->valuePermissionList as $permission) {
$this->data->$permission = $this->mergeValueList($valuePermissionLists->$permission, $this->metadata->get('app.'.$this->type.'.default.' . $permission, 'yes'));
if ($this->metadata->get('app.'.$this->type.'.mandatory.' . $permission)) {
@@ -266,11 +264,17 @@ class Table
$roleList = [];
$userRoleList = $this->getUser()->get('roles');
if (!(is_array($userRoleList) || $userRoleList instanceof \Traversable)) {
throw new Error();
}
foreach ($userRoleList as $role) {
$roleList[] = $role;
}
$teamList = $this->getUser()->get('teams');
if (!(is_array($teamList) || $teamList instanceof \Traversable)) {
throw new Error();
}
foreach ($teamList as $team) {
$teamRoleList = $team->get('roles');
foreach ($teamRoleList as $role) {
@@ -396,7 +400,7 @@ class Table
protected function applyDefault(&$table, &$fieldTable)
{
if ($this->user->isAdmin()) {
if ($this->getUser()->isAdmin()) {
return;
}
@@ -461,7 +465,7 @@ class Table
protected function applyMandatory(&$table, &$fieldTable)
{
if ($this->user->isAdmin()) {
if ($this->getUser()->isAdmin()) {
return;
}
@@ -508,7 +512,7 @@ class Table
protected function applyDisabled(&$table, &$fieldTable)
{
if ($this->user->isAdmin()) {
if ($this->getUser()->isAdmin()) {
return;
}

View File

@@ -98,7 +98,10 @@ class AclManager
protected function getTable(User $user)
{
$key = spl_object_hash($user);
$key = $user->id;
if (empty($key)) {
$key = spl_object_hash($user);
}
if (empty($this->tableHashMap[$key])) {
$config = $this->getContainer()->get('config');

View File

@@ -76,11 +76,17 @@ class Table extends \Espo\Core\Acl\Table
$roleList = [];
$userRoleList = $this->getUser()->get('portalRoles');
if (!(is_array($userRoleList) || $userRoleList instanceof \Traversable)) {
throw new Error();
}
foreach ($userRoleList as $role) {
$roleList[] = $role;
}
$portalRoleList = $this->getPortal()->get('portalRoles');
if (!(is_array($portalRoleList) || $portalRoleList instanceof \Traversable)) {
throw new Error();
}
foreach ($portalRoleList as $role) {
$roleList[] = $role;
}
@@ -115,7 +121,7 @@ class Table extends \Espo\Core\Acl\Table
{
foreach ($this->getScopeList() as $scope) {
$d = $this->getMetadata()->get('scopes.' . $scope);
if ($d['disabled'] || $d['portalDisabled']) {
if (!empty($d['disabled']) || !empty($d['portalDisabled'])) {
$table->$scope = false;
unset($fieldTable->$scope);
}

View File

@@ -323,5 +323,12 @@ class Application
}
return null;
}
public function setupSystemUser()
{
$user = $this->getContainer()->get('entityManager')->getEntity('User', 'system');
$this->getContainer()->setUser($user);
$this->getContainer()->get('entityManager')->setUser($user);
}
}

View File

@@ -200,7 +200,9 @@ class Container
$this->get('entityManager'),
$this->get('user'),
$this->get('acl'),
$this->get('metadata')
$this->get('aclManager'),
$this->get('metadata'),
$this->get('config')
);
}

View File

@@ -64,7 +64,7 @@ class Record extends Base
return $service;
}
public function actionRead($params)
public function actionRead($params, $data, $request)
{
$id = $params['id'];
$entity = $this->getRecordService()->getEntity($id);
@@ -410,17 +410,18 @@ class Record extends Base
throw new BadRequest();
}
if (empty($data['targetId']) || empty($data['sourceIds']) || !is_array($data['sourceIds'])) {
if (empty($data['targetId']) || empty($data['sourceIds']) || !is_array($data['sourceIds']) || !($data['attributes'] instanceof \StdClass)) {
throw new BadRequest();
}
$targetId = $data['targetId'];
$sourceIds = $data['sourceIds'];
$attributes = get_object_vars($data['attributes']);
if (!$this->getAcl()->check($this->name, 'edit')) {
throw new Forbidden();
}
return $this->getRecordService()->merge($targetId, $sourceIds);
return $this->getRecordService()->merge($targetId, $sourceIds, $attributes);
}
}

View File

@@ -35,15 +35,21 @@ use Espo\Core\Exceptions\NotFound;
class CronManager
{
private $container;
private $config;
private $fileManager;
private $entityManager;
private $scheduledJobUtil;
const PENDING = 'Pending';
const RUNNING = 'Running';
const SUCCESS = 'Success';
const FAILED = 'Failed';
protected $lastRunTime = 'data/cache/application/cronLastRunTime.php';
@@ -149,19 +155,15 @@ class CronManager
$this->setLastRunTime(time());
$entityManager = $this->getEntityManager();
$cronJob = $this->getCronJob();
$cronScheduledJob = $this->getCronScheduledJob();
//Check scheduled jobs and create related jobs
$this->getCronJob()->markFailedJobs();
$this->getCronJob()->updateFailedJobAttempts();
$this->createJobsFromScheduledJobs();
$this->getCronJob()->removePendingJobDuplicates();
$pendingJobs = $cronJob->getPendingJobs();
$pendingJobList = $this->getCronJob()->getPendingJobList();
foreach ($pendingJobs as $job) {
$jobEntity = $entityManager->getEntity('Job', $job['id']);
foreach ($pendingJobList as $job) {
$jobEntity = $this->getEntityManager()->getEntity('Job', $job['id']);
if (!isset($jobEntity)) {
$GLOBALS['log']->error('CronManager: empty Job entity ['.$job['id'].'].');
@@ -169,7 +171,7 @@ class CronManager
}
$jobEntity->set('status', self::RUNNING);
$entityManager->saveEntity($jobEntity);
$this->getEntityManager()->saveEntity($jobEntity);
$isSuccess = true;
@@ -187,11 +189,10 @@ class CronManager
$status = $isSuccess ? self::SUCCESS : self::FAILED;
$jobEntity->set('status', $status);
$entityManager->saveEntity($jobEntity);
$this->getEntityManager()->saveEntity($jobEntity);
//set status in the schedulerJobLog
if (!empty($job['scheduled_job_id'])) {
$cronScheduledJob->addLogRecord($job['scheduled_job_id'], $status);
$this->getCronScheduledJob()->addLogRecord($job['scheduled_job_id'], $status, null, $job['target_id'], $job['target_type']);
}
}
}
@@ -213,12 +214,20 @@ class CronManager
}
$jobClass = new $className($this->container);
$method = $this->getScheduledJobUtil()->getMethodName();
$method = 'run';
if (!method_exists($jobClass, $method)) {
throw new NotFound();
}
$jobClass->$method();
$data = null;
if (!empty($job['data'])) {
$data = $job['data'];
if (Json::isJSON($data)) {
$data = Json::decode($data, true);
}
}
$jobClass->$method($data, $job['target_id'], $job['target_type']);
}
/**
@@ -248,7 +257,7 @@ class CronManager
$data = Json::decode($data, true);
}
$service->$serviceMethod($data);
$service->$serviceMethod($data, $job['target_id'], $job['target_type']);
}
/**
@@ -258,55 +267,56 @@ class CronManager
*/
protected function createJobsFromScheduledJobs()
{
$entityManager = $this->getEntityManager();
$activeScheduledJobList = $this->getCronScheduledJob()->getActiveScheduledJobList();
$activeScheduledJobs = $this->getCronScheduledJob()->getActiveJobs();
$cronJob = $this->getCronJob();
$runningScheduledJobs = $cronJob->getActiveJobs('scheduled_job_id', self::RUNNING, PDO::FETCH_COLUMN);
$createdJobs = array();
foreach ($activeScheduledJobs as $scheduledJob) {
if (in_array($scheduledJob['id'], $runningScheduledJobs)) {
continue;
}
$runningScheduledJobIdList = $this->getCronJob()->getRunningScheduledJobIdList();
$createdJobIdList = array();
foreach ($activeScheduledJobList as $scheduledJob) {
$scheduling = $scheduledJob['scheduling'];
$cronExpression = \Cron\CronExpression::factory($scheduling);
try {
$prevDate = $cronExpression->getPreviousRunDate()->format('Y-m-d H:i:s');
$previousDate = $cronExpression->getPreviousRunDate()->format('Y-m-d H:i:s');
} catch (\Exception $e) {
$GLOBALS['log']->error('CronManager: ScheduledJob ['.$scheduledJob['id'].']: CronExpression - Impossible CRON expression ['.$scheduling.']');
continue;
}
if ($cronExpression->isDue()) {
$prevDate = date('Y-m-d H:i:s');
$previousDate = date('Y-m-d H:i:s');
}
$existsJob = $cronJob->getJobByScheduledJob($scheduledJob['id'], $prevDate);
if (!isset($existsJob) || empty($existsJob)) {
//create a new job
$jobEntity = $entityManager->getEntity('Job');
$jobEntity->set(array(
'name' => $scheduledJob['name'],
'status' => self::PENDING,
'scheduledJobId' => $scheduledJob['id'],
'executeTime' => $prevDate,
'method' => $scheduledJob['job'],
));
$jobEntityId = $entityManager->saveEntity($jobEntity);
if (!empty($jobEntityId)) {
$createdJobs[] = $jobEntityId;
$className = $this->getScheduledJobUtil()->get($scheduledJob['job']);
if ($className) {
if (method_exists($className, 'prepare')) {
$implementation = new $className($this->container);
$implementation->prepare($scheduledJob, $previousDate);
continue;
}
}
if (in_array($scheduledJob['id'], $runningScheduledJobIdList)) {
continue;
}
$existingJob = $this->getCronJob()->getJobByScheduledJob($scheduledJob['id'], $previousDate);
if ($existingJob) continue;
$jobEntity = $this->getEntityManager()->getEntity('Job');
$jobEntity->set(array(
'name' => $scheduledJob['name'],
'status' => self::PENDING,
'scheduledJobId' => $scheduledJob['id'],
'executeTime' => $previousDate,
'method' => $scheduledJob['job']
));
$this->getEntityManager()->saveEntity($jobEntity);
$createdJobIdList[] = $jobEntity->id;
}
return $createdJobs;
return $createdJobIdList;
}
}

View File

@@ -70,7 +70,5 @@ abstract class Base
$this->container = $container;
}
abstract public function run();
}

View File

@@ -71,7 +71,7 @@ class Importer
return $this->filtersMatcher;
}
public function importMessage($message, $assignedUserId = null, $teamsIdList = [], $userIdList = [], $filterList = [])
public function importMessage($message, $assignedUserId = null, $teamsIdList = [], $userIdList = [], $filterList = [], $fetchOnlyHeader = false)
{
try {
$email = $this->getEntityManager()->getEntity('Email');
@@ -166,28 +166,37 @@ class Importer
$inlineIds = array();
if ($message->isMultipart()) {
foreach (new \RecursiveIteratorIterator($message) as $part) {
$this->importPartDataToEmail($email, $part, $inlineIds);
if (!$fetchOnlyHeader) {
if ($message->isMultipart()) {
foreach (new \RecursiveIteratorIterator($message) as $part) {
$this->importPartDataToEmail($email, $part, $inlineIds);
}
} else {
$this->importPartDataToEmail($email, $message, $inlineIds, 'text/plain');
}
if (!$email->get('body') && $email->get('bodyPlain')) {
$email->set('body', $email->get('bodyPlain'));
}
$body = $email->get('body');
if (!empty($body)) {
foreach ($inlineIds as $cid => $attachmentId) {
if (strpos($body, 'cid:' . $cid) !== false) {
$body = str_replace('cid:' . $cid, '?entryPoint=attachment&id=' . $attachmentId, $body);
} else {
$email->addLinkMultipleId('attachments', $attachmentId);
}
}
$email->set('body', $body);
}
if ($this->getFiltersMatcher()->matchBody($email, $filterList)) {
return false;
}
} else {
$this->importPartDataToEmail($email, $message, $inlineIds, 'text/plain');
}
if (!$email->get('body') && $email->get('bodyPlain')) {
$email->set('body', $email->get('bodyPlain'));
}
$body = $email->get('body');
if (!empty($body)) {
foreach ($inlineIds as $cid => $attachmentId) {
$body = str_replace('cid:' . $cid, '?entryPoint=attachment&id=' . $attachmentId, $body);
}
$email->set('body', $body);
}
if ($this->getFiltersMatcher()->matchBody($email, $filterList)) {
return false;
$email->set('body', '(Not fetched)');
$email->set('isHtml', false);
}
$parentFound = false;
@@ -352,6 +361,8 @@ class Importer
} else if (strpos(strtolower($part->ContentDisposition), 'inline') === 0) {
$contentDisposition = 'inline';
}
} else if (isset($part->contentID)) {
$contentDisposition = 'inline';
}
if (empty($type)) {
@@ -395,7 +406,6 @@ class Importer
$contentId = null;
if ($contentDisposition) {
if ($contentDisposition === 'attachment') {
$fileName = $this->fetchFileNameFromContentDisposition($part->ContentDisposition);
if ($fileName) {
@@ -454,26 +464,61 @@ class Importer
} catch (\Exception $e) {}
}
protected function fetchFileNameFromContentDisposition($contentDisposition)
protected function decodeAttachmentFileName($fileName)
{
$m = array();
if (preg_match('/filename="?([^"]+)"?/i', $contentDisposition, $m)) {
$fileName = $m[1];
return $fileName;
} else if (preg_match('/filename\*[01]?="?([^"]+)"?/i', $contentDisposition, $m)) {
$fileName = $m[1];
if ($fileName) {
if (stripos($fileName, "''") !== false) {
list($encoding, $fileName) = explode("''", $fileName);
$fileName = rawurldecode($fileName);
if (strtoupper($encoding) !== 'UTF-8') {
$fileName = mb_convert_encoding($fileName, 'UTF-8', $encoding);
}
if ($fileName && stripos($fileName, "''") !== false) {
list($encoding, $fileName) = explode("''", $fileName);
$fileName = rawurldecode($fileName);
if (strtoupper($encoding) !== 'UTF-8') {
if ($encoding) {
$fileName = mb_convert_encoding($fileName, 'UTF-8', $encoding);
}
return $fileName;
}
}
return false;
return $fileName;
}
protected function fetchFileNameFromContentDisposition($contentDisposition)
{
$contentDisposition = preg_replace('/\\\\"/', "{{_!Q!U!O!T!E!_}}", $contentDisposition);
$fileName = false;
$m = array();
if (preg_match('/filename="([^"]+)";?/i', $contentDisposition, $m)) {
$fileName = $m[1];
} else if (preg_match('/filename=([^";]+);?/i', $contentDisposition, $m)) {
$fileName = $m[1];
} else if (preg_match('/filename\*="([^"]+)";?/i', $contentDisposition, $m)) {
$fileName = $m[1];
$fileName = $this->decodeAttachmentFileName($fileName);
} else if (preg_match('/filename\*=([^";]+);?/i', $contentDisposition, $m)) {
$fileName = $m[1];
$fileName = $this->decodeAttachmentFileName($fileName);
} else {
$fileName = '';
foreach (['0', '1'] as $i) {
if (preg_match('/filename\*'.$i.'[\*]?="([^"]+)";?/i', $contentDisposition, $m)) {
$part = $m[1];
$fileName .= $part;
} else if (preg_match('/filename\*'.$i.'[\*]?=([^";]+);?/i', $contentDisposition, $m)) {
$part = $m[1];
$fileName .= $part;
}
}
if ($fileName === '') {
$fileName = null;
} else {
$fileName = $this->decodeAttachmentFileName($fileName);
}
}
if ($fileName) {
$fileName = str_replace('{{_!Q!U!O!T!E!_}}', '"', $fileName);
}
return $fileName;
}
protected function getContentFromPart($part)

View File

@@ -72,7 +72,10 @@ class AclManager extends \Espo\Core\AclManager
protected function getTable(User $user)
{
$key = spl_object_hash($user);
$key = $user->id;
if (empty($key)) {
$key = spl_object_hash($user);
}
if (empty($this->tableHashMap[$key])) {
$config = $this->getContainer()->get('config');

View File

@@ -43,12 +43,14 @@ class SelectManagerFactory
private $metadata;
public function __construct($entityManager, \Espo\Entities\User $user, Acl $acl, $metadata)
public function __construct($entityManager, \Espo\Entities\User $user, Acl $acl, AclManager $aclManager, Utils\Metadata $metadata, Utils\Config $config)
{
$this->entityManager = $entityManager;
$this->user = $user;
$this->acl = $acl;
$this->aclManager = $aclManager;
$this->metadata = $metadata;
$this->config = $config;
}
public function create($entityType)
@@ -68,7 +70,7 @@ class SelectManagerFactory
}
}
$selectManager = new $className($this->entityManager, $this->user, $this->acl, $this->metadata);
$selectManager = new $className($this->entityManager, $this->user, $this->acl, $this->aclManager, $this->metadata, $this->config);
$selectManager->setEntityType($entityType);
return $selectManager;

View File

@@ -33,6 +33,9 @@ use \Espo\Core\Exceptions\Error;
use \Espo\Core\Exceptions\Forbidden;
use \Espo\Core\Acl;
use \Espo\Core\AclManager;
use \Espo\Core\Utils\Metadata;
use \Espo\Core\Utils\Config;
class Base
{
@@ -48,6 +51,8 @@ class Base
protected $metadata;
private $config;
private $seed = null;
private $userTimeZone = null;
@@ -56,13 +61,15 @@ class Base
const MIN_LENGTH_FOR_CONTENT_SEARCH = 4;
public function __construct($entityManager, \Espo\Entities\User $user, Acl $acl, $metadata)
public function __construct($entityManager, \Espo\Entities\User $user, Acl $acl, AclManager $aclManager, Metadata $metadata, Config $config)
{
$this->entityManager = $entityManager;
$this->user = $user;
$this->acl = $acl;
$this->aclManager = $aclManager;
$this->metadata = $metadata;
$this->config = $config;
}
protected function getEntityManager()
@@ -80,6 +87,16 @@ class Base
return $this->acl;
}
protected function getConfig()
{
return $this->config;
}
protected function getAclManager()
{
return $this->aclManager;
}
public function setEntityType($entityType)
{
$this->entityType = $entityType;
@@ -875,6 +892,9 @@ class Base
case 'startsWith':
$part[$item['field'] . '*'] = $item['value'] . '%';
break;
case 'endsWith':
$part[$item['field'] . '*'] = $item['value'] . '%';
break;
case 'contains':
$part[$item['field'] . '*'] = '%' . $item['value'] . '%';
break;
@@ -1163,15 +1183,21 @@ class Base
$d = array();
foreach ($fieldList as $field) {
$expression = $textFilter . '%';
if (
strlen($textFilter) >= self::MIN_LENGTH_FOR_CONTENT_SEARCH
&&
!empty($fieldDefs[$field]['type']) && $fieldDefs[$field]['type'] == 'text'
(
!empty($fieldDefs[$field]['type']) && $fieldDefs[$field]['type'] == 'text'
||
$this->getConfig()->get('textFilterUseContainsForVarchar')
)
) {
$d[$field . '*'] = '%' . $textFilter . '%';
$expression = '%' . $textFilter . '%';
} else {
$d[$field . '*'] = $textFilter . '%';
$expression = $textFilter . '%';
}
$d[$field . '*'] = $expression;
}
$result['whereClause'][] = array(
'OR' => $d

View File

@@ -29,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": {

View File

@@ -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": {

View File

@@ -32,7 +32,7 @@ use Espo\Core\Utils\Util;
use Espo\Core\Utils\System;
use Espo\Core\Utils\Json;
use Espo\Core\Exceptions\Error;
use vierbergenlars\SemVer;
use Composer\Semver\Semver;
abstract class Base
{
@@ -221,20 +221,12 @@ abstract class Base
$versionList = (array) $versionList;
}
try {
$semver = new SemVer\version($currentVersion);
} catch (\Exception $e) {
$GLOBALS['log']->error('Cannot recognize currentVersion ['.$currentVersion.'], error: '.$e->getMessage().'.');
return false;
}
foreach ($versionList as $version) {
$isInRange = false;
try {
$isInRange = $semver->satisfies(new SemVer\expression($version));
$isInRange = Semver::satisfies($currentVersion, $version);
} catch (\Exception $e) {
$GLOBALS['log']->error('Version identification error: '.$e->getMessage().'.');
$GLOBALS['log']->error('SemVer: Version identification error: '.$e->getMessage().'.');
}
if ($isInRange) {

View File

@@ -163,6 +163,8 @@ class Auth
return false;
}
$user->set('portalId', $this->getPortal()->id);
} else {
$user->loadLinkMultipleField('teams');
}
$this->getEntityManager()->setUser($user);

View File

@@ -69,20 +69,18 @@ class Job
*
* @return array
*/
public function getPendingJobs()
public function getPendingJobList()
{
/** Mark Failed old jobs and remove pending duplicates */
$this->markFailedJobs();
$this->markJobAttempts();
$this->removePendingJobDuplicates();
$jobConfigs = $this->getConfig()->get('cron');
$limit = !empty($jobConfigs['maxJobNumber']) ? intval($jobConfigs['maxJobNumber']) : 0;
$jobList = $this->getActiveJobs();
$jobList = $this->getJobList(CronManager::PENDING, $limit);
$runningScheduledJobs = $this->getActiveJobs('scheduled_job_id', CronManager::RUNNING, PDO::FETCH_COLUMN);
$runningScheduledJobIdList = $this->getRunningScheduledJobIdList();
$list = array();
$list = [];
foreach ($jobList as $row) {
if (!in_array($row['scheduled_job_id'], $runningScheduledJobs)) {
if (!in_array($row['scheduled_job_id'], $runningScheduledJobIdList)) {
$list[] = $row;
}
}
@@ -90,32 +88,63 @@ class Job
return $list;
}
/**
* Get active Jobs, which execution date in jobPeriod time
*
* @param string $displayColumns
* @param string $status
*
* @return array
*/
public function getActiveJobs($displayColumns = '*', $status = CronManager::PENDING, $fetchMode = PDO::FETCH_ASSOC)
public function getRunningScheduledJobIdList()
{
$jobConfigs = $this->getConfig()->get('cron');
$currentTime = time();
$limit = empty($jobConfigs['maxJobNumber']) ? '' : 'LIMIT '.$jobConfigs['maxJobNumber'];
$query = "SELECT " . $displayColumns . " FROM job WHERE
`status` = '" . $status . "'
AND execute_time <= '".date('Y-m-d H:i:s', $currentTime)."'
AND deleted = 0
ORDER BY execute_time ASC ".$limit;
$list = [];
$pdo = $this->getEntityManager()->getPDO();
$query = "
SELECT scheduled_job_id FROM job
WHERE
`status` = 'Running' AND
scheduled_job_id IS NOT NULL AND
target_id IS NULL AND
deleted = 0
ORDER BY execute_time
";
$sth = $pdo->prepare($query);
$sth->execute();
$rows = $sth->fetchAll($fetchMode);
$rowList = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach ($rowList as $row) {
$list[] = $row['scheduled_job_id'];
}
return $list;
}
/**
* Get job list, which execution date in jobPeriod time
*
* @param string $status
* @param int $limit
*
* @return array
*/
public function getJobList($status = CronManager::PENDING, $limit = null)
{
$currentTime = time();
$pdo = $this->getEntityManager()->getPDO();
$query = "
SELECT * FROM job
WHERE
`status` = " . $pdo->quote($status) . "
AND execute_time <= '".date('Y-m-d H:i:s', $currentTime)."'
AND deleted = 0
ORDER BY execute_time ASC
";
if ($limit) {
$query .= " LIMIT " . $limit ;
}
$sth = $pdo->prepare($query);
$sth->execute();
$rows = $sth->fetchAll(PDO::FETCH_ASSOC);
return $rows;
}
@@ -133,13 +162,17 @@ class Job
$dateObj = new \DateTime($time);
$timeWithoutSeconds = $dateObj->format('Y-m-d H:i:');
$query = "SELECT * FROM job WHERE
scheduled_job_id = '".$scheduledJobId."'
AND execute_time LIKE '".$timeWithoutSeconds."%'
AND deleted = 0
LIMIT 1";
$pdo = $this->getEntityManager()->getPDO();
$query = "
SELECT * FROM job
WHERE
scheduled_job_id = ".$pdo->quote($scheduledJobId)."
AND execute_time LIKE ". $pdo->quote($timeWithoutSeconds . '%') . "
AND deleted = 0
LIMIT 1
";
$sth = $pdo->prepare($query);
$sth->execute();
@@ -153,7 +186,7 @@ class Job
*
* @return void
*/
protected function markFailedJobs()
public function markFailedJobs()
{
$jobConfigs = $this->getConfig()->get('cron');
@@ -162,9 +195,11 @@ class Job
$pdo = $this->getEntityManager()->getPDO();
$select = "SELECT id, scheduled_job_id, execute_time FROM `job` WHERE
(`status` = '" . CronManager::RUNNING ."')
AND execute_time < '".date('Y-m-d H:i:s', $periodTime)."' ";
$select = "
SELECT id, scheduled_job_id, execute_time, target_id, target_type FROM `job`
WHERE
`status` = '" . CronManager::RUNNING ."' AND execute_time < '".date('Y-m-d H:i:s', $periodTime)."'
";
$sth = $pdo->prepare($select);
$sth->execute();
@@ -173,7 +208,11 @@ class Job
$jobData[$row['id']] = $row;
}
$update = "UPDATE job SET `status` = '". CronManager::FAILED ."' WHERE id IN ('".implode("', '", array_keys($jobData))."')";
$update = "
UPDATE job
SET `status` = '". CronManager::FAILED ."'
WHERE id IN ('".implode("', '", array_keys($jobData))."')
";
$sth = $pdo->prepare($update);
$sth->execute();
@@ -181,7 +220,7 @@ class Job
$cronScheduledJob = $this->getCronScheduledJob();
foreach ($jobData as $jobId => $job) {
if (!empty($job['scheduled_job_id'])) {
$cronScheduledJob->addLogRecord($job['scheduled_job_id'], CronManager::FAILED, $job['execute_time']);
$cronScheduledJob->addLogRecord($job['scheduled_job_id'], CronManager::FAILED, $job['execute_time'], $job['target_id'], $job['target_type']);
}
}
}
@@ -191,38 +230,50 @@ class Job
*
* @return void
*/
protected function removePendingJobDuplicates()
public function removePendingJobDuplicates()
{
$pdo = $this->getEntityManager()->getPDO();
$query = "SELECT scheduled_job_id FROM job
WHERE
scheduled_job_id IS NOT NULL
AND `status` = '".CronManager::PENDING."'
AND execute_time <= '".date('Y-m-d H:i:s')."'
AND deleted = 0
GROUP BY scheduled_job_id
HAVING count( * ) > 1
ORDER BY execute_time ASC";
$query = "
SELECT scheduled_job_id
FROM job
WHERE
scheduled_job_id IS NOT NULL AND
`status` = '".CronManager::PENDING."' AND
execute_time <= '".date('Y-m-d H:i:s')."' AND
target_id IS NULL AND
deleted = 0
GROUP BY scheduled_job_id
HAVING count( * ) > 1
ORDER BY execute_time ASC
";
$sth = $pdo->prepare($query);
$sth->execute();
$duplicateJobs = $sth->fetchAll(PDO::FETCH_ASSOC);
$duplicateJobList = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach ($duplicateJobs as $row) {
foreach ($duplicateJobList as $row) {
if (!empty($row['scheduled_job_id'])) {
/* no possibility to use limit in update or subqueries */
$query = "SELECT id FROM `job` WHERE scheduled_job_id = '" . $row['scheduled_job_id'] . "'
AND `status` = '" . CronManager::PENDING ."'
ORDER BY execute_time
DESC LIMIT 1, 100000 ";
$query = "
SELECT id FROM `job`
WHERE
scheduled_job_id = '" . $row['scheduled_job_id'] . "' AND
`status` = '" . CronManager::PENDING ."'
ORDER BY execute_time
DESC LIMIT 1, 100000
";
$sth = $pdo->prepare($query);
$sth->execute();
$jobIds = $sth->fetchAll(PDO::FETCH_COLUMN);
$update = "UPDATE job SET deleted = 1 WHERE
id IN ('". implode("', '", $jobIds)."') ";
$update = "
UPDATE job
SET deleted = 1
WHERE
id IN ('". implode("', '", $jobIds)."')
";
$sth = $pdo->prepare($update);
$sth->execute();
@@ -235,13 +286,16 @@ class Job
*
* @return void
*/
protected function markJobAttempts()
public function updateFailedJobAttempts()
{
$query = "SELECT * FROM job WHERE
`status` = '" . CronManager::FAILED . "'
AND deleted = 0
AND execute_time <= '".date('Y-m-d H:i:s')."'
AND attempts > 0";
$query = "
SELECT * FROM job
WHERE
`status` = '" . CronManager::FAILED . "' AND
deleted = 0 AND
execute_time <= '".date('Y-m-d H:i:s')."' AND
attempts > 0
";
$pdo = $this->getEntityManager()->getPDO();
$sth = $pdo->prepare($query);
@@ -255,12 +309,14 @@ class Job
$attempts = $row['attempts'] - 1;
$failedAttempts = $row['failed_attempts'] + 1;
$update = "UPDATE job SET
`status` = '" . CronManager::PENDING ."',
attempts = '".$attempts."',
failed_attempts = '".$failedAttempts."'
WHERE
id = '".$row['id']."'
$update = "
UPDATE job
SET
`status` = '" . CronManager::PENDING ."',
attempts = '".$attempts."',
failed_attempts = '".$failedAttempts."'
WHERE
id = '".$row['id']."'
";
$pdo->prepare($update)->execute();
}

View File

@@ -59,11 +59,14 @@ class ScheduledJob
*
* @return array
*/
public function getActiveJobs()
public function getActiveScheduledJobList()
{
$query = "SELECT * FROM scheduled_job WHERE
`status` = 'Active'
AND deleted = 0";
$query = "
SELECT * FROM scheduled_job
WHERE
`status` = 'Active' AND
deleted = 0
";
$pdo = $this->getEntityManager()->getPDO();
$sth = $pdo->prepare($query);
@@ -87,7 +90,7 @@ class ScheduledJob
*
* @return string ID of created ScheduledJobLogRecord
*/
public function addLogRecord($scheduledJobId, $status, $runTime = null)
public function addLogRecord($scheduledJobId, $status, $runTime = null, $targetId = null, $targetType = null)
{
if (!isset($runTime)) {
$runTime = date('Y-m-d H:i:s');
@@ -96,6 +99,11 @@ class ScheduledJob
$entityManager = $this->getEntityManager();
$scheduledJob = $entityManager->getEntity('ScheduledJob', $scheduledJobId);
if (!$scheduledJob) {
return;
}
$scheduledJob->set('lastRun', $runTime);
$entityManager->saveEntity($scheduledJob);
@@ -105,6 +113,8 @@ class ScheduledJob
'name' => $scheduledJob->get('name'),
'status' => $status,
'executionTime' => $runTime,
'targetId' => $targetId,
'targetType' => $targetType
));
$scheduledJobLogId = $entityManager->saveEntity($scheduledJobLog);

View File

@@ -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}"

View File

@@ -48,22 +48,36 @@ class Email extends Base
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}
)"
'=' => 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 +87,7 @@ class Email extends Base
),
),
'relations' => array(
$fieldName.'es' => array(
'emailAddresses' => array(
'type' => 'manyMany',
'entity' => 'EmailAddress',
'relationName' => 'entityEmailAddress',

View File

@@ -48,22 +48,36 @@ class Phone extends Base
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}
)"
'=' => 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 +87,7 @@ class Phone extends Base
),
),
'relations' => array(
$fieldName.'s' => array(
'phoneNumbers' => array(
'type' => 'manyMany',
'entity' => 'PhoneNumber',
'relationName' => 'entityPhoneNumber',

View File

@@ -82,6 +82,8 @@ class EntityManager
throw new Error();
}
$name = trim($name);
$normalizedName = Util::normilizeClassName($name);
$contents = "<" . "?" . "php\n\n".
@@ -217,6 +219,15 @@ class EntityManager
$this->getMetadata()->set('entityDefs', $name, $entityDefsData);
}
if (isset($data['textFilterFields'])) {
$entityDefsData = array(
'collection' => array(
'textFilterFields' => $data['textFilterFields']
)
);
$this->getMetadata()->set('entityDefs', $name, $entityDefsData);
}
$this->getMetadata()->save();
$this->getLanguage()->save();
@@ -270,9 +281,9 @@ class EntityManager
$linkType = $params['linkType'];
$entity = $params['entity'];
$link = $params['link'];
$link = trim($params['link']);
$entityForeign = $params['entityForeign'];
$linkForeign = $params['linkForeign'];
$linkForeign = trim($params['linkForeign']);
$label = $params['label'];
$labelForeign = $params['labelForeign'];
@@ -320,9 +331,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 +378,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(

View File

@@ -89,6 +89,7 @@ class FieldManager
public function update($name, $fieldDefs, $scope)
{
$name = trim($name);
/*Add option to metadata to identify the custom field*/
if (!$this->isCore($name, $scope)) {
$fieldDefs[$this->customOptionName] = true;

View File

@@ -249,7 +249,7 @@ class Manager
public function putContentsJson($path, $data)
{
if (!Utils\Json::isJSON($data)) {
$data = Utils\Json::encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
$data = Utils\Json::encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
return $this->putContents($path, $data, LOCK_EX);
@@ -290,7 +290,7 @@ class Manager
$data = Utils\Util::merge($savedDataArray, $newDataArray);
if ($isReturnJson) {
$data = Utils\Json::encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
$data = Utils\Json::encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
if ($isPhp) {

View File

@@ -187,7 +187,7 @@ class Metadata
/**
* Get Metadata
*
* @param string $key
* @param mixed string|array $key
* @param mixed $default
*
* @return array

View File

@@ -449,7 +449,7 @@ class Util
* Return values of defined $key.
*
* @param array $array
* @param string $key Ex. of key is "entityDefs", "entityDefs.User"
* @param mixed array|string $key Ex. of key is "entityDefs", "entityDefs.User"
* @param mixed $default
* @return mixed
*/
@@ -459,7 +459,11 @@ class Util
return $array;
}
$keys = explode('.', $key);
if (is_array($key)) {
$keys = $key;
} else {
$keys = explode('.', $key);
}
$lastItem = $array;
foreach($keys as $keyName) {

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,
@@ -113,6 +113,7 @@ return array (
'authTokenLifetime' => 0,
'authTokenMaxIdleTime' => 120,
'userNameRegularExpression' => '[^a-z0-9\-@_\.\s]',
'addressFormat' => 1,
'displayListViewRecordCount' => true,
'dashboardLayout' => [
(object) [

View File

@@ -40,7 +40,9 @@ class Avatar extends Image
public static $notStrictAuth = true;
private $colorList = [
protected $systemColor = [212,114,155];
protected $colorList = [
[111,168,214],
[237,197,85],
[212,114,155],
@@ -73,7 +75,6 @@ class Avatar extends Image
$userId = $_GET['id'];
$user = $this->getEntityManager()->getEntity('User', $userId);
if (!$user) {
throw new NotFound();
@@ -106,9 +107,14 @@ class Avatar extends Image
header('Cache-Control: max-age=360000, must-revalidate');
header('Content-Type: image/png');
ob_clean();
flush();
echo $identicon->getImageData($userId, $width, $this->getColor($userId));
$hash = $userId;
$color = $this->getColor($userId);
if ($hash === 'system') {
$color = $this->systemColor;
}
$imgContent = $identicon->getImageData($hash, $width, $color);
echo $imgContent;
exit;
}
}

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');

View File

@@ -0,0 +1,39 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* 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\Modules\Crm\Acl;
use \Espo\Entities\User;
use \Espo\ORM\Entity;
class Call extends Meeting
{
}

View File

@@ -0,0 +1,54 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* 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\Modules\Crm\Acl;
use \Espo\Entities\User;
use \Espo\ORM\Entity;
class Meeting extends \Espo\Core\Acl\Base
{
public function checkEntityRead(User $user, Entity $entity, $data)
{
if ($this->checkEntity($user, $entity, $data, 'read')) {
return true;
}
if (is_object($data)) {
if ($data->read === 'own' || $data->read === 'team') {
if ($entity->hasLinkMultipleId('users', $user->id)) {
return true;
}
}
}
return false;
}
}

View File

@@ -116,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;
}

View File

@@ -136,13 +136,10 @@ class EmailReminder
$email->set('subject', $subject);
$email->set('body', $body);
$email->set('isHtml', true);
$this->getEntityManager()->saveEntity($email);
$emailSender = $this->mailSender;
$emailSender->send($email);
$this->getEntityManager()->removeEntity($email);
}
}

View File

@@ -35,6 +35,9 @@ use \Espo\Core\Exceptions\Error,
class Activities extends \Espo\Core\Controllers\Base
{
protected $maxCalendarRange = 123;
protected $maxSizeLimit = 200;
public function actionListCalendarEvents($params, $data, $request)
{
@@ -49,18 +52,38 @@ class Activities extends \Espo\Core\Controllers\Base
throw new BadRequest();
}
$service = $this->getService('Activities');
$userId = $request->get('userId');
if (!$userId) {
$userId = $this->getUser()->id;
if (strtotime($to) - strtotime($from) > $this->maxCalendarRange * 24 * 3600) {
throw new Forbidden('Too long range.');
}
$service = $this->getService('Activities');
$scopeList = null;
if ($request->get('scopeList') !== null) {
$scopeList = explode(',', $request->get('scopeList'));
}
$userId = $request->get('userId');
$userIdList = $request->get('userIdList');
if ($userIdList) {
$userIdList = explode(',', $userIdList);
$resultList = [];
foreach ($userIdList as $userId) {
$userResultList = $service->getEvents($userId, $from, $to, $scopeList);
foreach ($userResultList as $item) {
$item['userId'] = $userId;
$resultList[] = $item;
}
}
return $resultList;
} else {
if (!$userId) {
$userId = $this->getUser()->id;
}
}
return $service->getEvents($userId, $from, $to, $scopeList);
}
@@ -76,6 +99,13 @@ class Activities extends \Espo\Core\Controllers\Base
$offset = intval($request->get('offset'));
$maxSize = intval($request->get('maxSize'));
if (empty($maxSize)) {
$maxSize = $this->maxSizeLimit;
}
if ($maxSize > $this->maxSizeLimit) {
throw new Forbidden("Max should should not exceed " . $this->maxSizeLimit . ". Use pagination (offset, limit).");
}
return $service->getUpcomingActivities($userId, array(
'offset' => $offset,
'maxSize' => $maxSize
@@ -131,6 +161,13 @@ class Activities extends \Espo\Core\Controllers\Base
$sortBy = $request->get('sortBy');
$where = $request->get('where');
if (empty($maxSize)) {
$maxSize = $this->maxSizeLimit;
}
if ($maxSize > $this->maxSizeLimit) {
throw new Forbidden("Max should should not exceed " . $this->maxSizeLimit . ". Use pagination (offset, limit).");
}
$scope = null;
if (is_array($where) && !empty($where[0]) && $where[0] !== 'false') {
$scope = $where[0];

View File

@@ -31,5 +31,13 @@ namespace Espo\Modules\Crm\Controllers;
class KnowledgeBaseArticle extends \Espo\Core\Controllers\Record
{
public function postActionGetCopiedAttachments($params, $data, $request)
{
if (empty($data['id'])) {
throw new BadRequest();
}
$id = $data['id'];
return $this->getRecordService()->getCopiedAttachments($id);
}
}

View File

@@ -81,6 +81,17 @@ class CampaignTrackOpened extends \Espo\Core\EntryPoints\Base
}
$campaignService = $this->getServiceFactory()->create('Campaign');
$campaignService->logOpened($campaignId, $queueItemId, $target, null, $queueItem->get('isTest'));
header('Content-Type: image/png');
$img = imagecreatetruecolor(1, 1);
imagesavealpha($img, true);
$color = imagecolorallocatealpha($img, 0, 0, 0, 127);
imagefill($img, 0, 0, $color);
imagepng($img);
imagecolordeallocate($background);
imagedestroy( $tt_image );
}
}

View File

@@ -29,20 +29,61 @@
namespace Espo\Modules\Crm\Jobs;
use \Espo\Core\Exceptions;
use \Espo\Core\Exceptions\Error;
class CheckEmailAccounts extends \Espo\Core\Jobs\Base
{
public function run()
public function run($data, $targetId)
{
if (!$targetId) {
throw new Error();
}
$service = $this->getServiceFactory()->create('EmailAccount');
$collection = $this->getEntityManager()->getRepository('EmailAccount')->where(array('status' => 'Active'))->find();
$entity = $this->getEntityManager()->getEntity('EmailAccount', $targetId);
if (!$entity) {
throw new Error("Job CheckEmailAccounts '".$targetId."': EmailAccount does not exist.");
};
if ($entity->get('status') !== 'Active') {
throw new Error("Job CheckEmailAccounts '".$targetId."': EmailAccount is not active.");
}
try {
$service->fetchFromMailServer($entity);
} catch (\Exception $e) {
throw new Error('Job CheckEmailAccounts '.$entity->id.': [' . $e->getCode() . '] ' .$e->getMessage());
}
return true;
}
public function prepare($data, $executeTime)
{
$collection = $this->getEntityManager()->getRepository('EmailAccount')->where(array(
'status' => 'Active'
))->find();
foreach ($collection as $entity) {
try {
$service->fetchFromMailServer($entity);
} catch (\Exception $e) {
$GLOBALS['log']->error('Job CheckEmailAccounts '.$entity->id.': [' . $e->getCode() . '] ' .$e->getMessage());
}
$running = $this->getEntityManager()->getRepository('Job')->where(array(
'scheduledJobId' => $data['id'],
'status' => ['Running', 'Pending'],
'targetType' => 'EmailAccount',
'targetId' => $entity->id
))->findOne();
if ($running) continue;
$job = $this->getEntityManager()->getEntity('Job');
$jobEntity = $this->getEntityManager()->getEntity('Job');
$jobEntity->set(array(
'name' => $data['name'],
'scheduledJobId' => $data['id'],
'executeTime' => $executeTime,
'method' => 'CheckEmailAccounts',
'targetType' => 'EmailAccount',
'targetId' => $entity->id
));
$this->getEntityManager()->saveEntity($jobEntity);
}
return true;

View File

@@ -83,7 +83,7 @@ class Meeting extends \Espo\Core\ORM\Repositories\RDB
$usersColumns = new \StdClass();
}
if ($usersColumns instanceof \StdClass) {
if (!($usersColumns->$currentUserId instanceof \StdClass)) {
if (empty($usersColumns->$currentUserId) || !($usersColumns->$currentUserId instanceof \StdClass)) {
$usersColumns->$currentUserId = new \StdClass();
}
if (empty($usersColumns->$currentUserId->status)) {

View File

@@ -1,7 +1,8 @@
{
"labels": {
"Create DocumentFolder": "Vytvořit složku",
"Manage Categories": "Spravovat složky"
"Manage Categories": "Spravovat složky",
"documents": "Dokumenty"
},
"links": {
"documents": "Dokumenty"

View File

@@ -1,7 +1,8 @@
{
"labels": {
"Create DocumentFolder": "Dokumente Ordner erstellen",
"Manage Categories": "Ordner verwalten"
"Manage Categories": "Ordner verwalten",
"Documents": "Dokumente"
},
"links": {
"documents": "Dokumente"

View File

@@ -4,10 +4,17 @@
"week": "Week",
"day": "Day",
"agendaWeek": "Week",
"agendaDay": "Day"
"agendaDay": "Day",
"timeline": "Timeline"
},
"labels": {
"Today": "Today",
"Create": "Create"
"Create": "Create",
"Shared": "Shared",
"Add User": "Add User",
"current": "current",
"time": "time",
"User List": "User List",
"Manage Users": "Manage Users"
}
}

View File

@@ -9,7 +9,8 @@
"priority": "Priority",
"type": "Type",
"description": "Description",
"inboundEmail": "Inbound Email"
"inboundEmail": "Inbound Email",
"lead": "Lead"
},
"links": {
"inboundEmail": "Inbound Email",
@@ -20,7 +21,8 @@
"calls": "Calls",
"tasks": "Tasks",
"emails": "Emails",
"articles": "Knowledge Base Articles"
"articles": "Knowledge Base Articles",
"lead": "Lead"
},
"options": {
"status": {

View File

@@ -18,7 +18,8 @@
"links": {
"accounts": "Accounts",
"opportunities": "Opportunities",
"folder": "Folder"
"folder": "Folder",
"leads": "Leads"
},
"options": {
"status": {

View File

@@ -1,7 +1,8 @@
{
"labels": {
"Create DocumentFolder": "Create Document Folder",
"Manage Categories": "Manage Folders"
"Manage Categories": "Manage Folders",
"Documents": "Documents"
},
"links": {
"documents": "Documents"

View File

@@ -89,7 +89,7 @@
"shippingAddressCountry": "Country (Shipping)",
"shippingAddressState": "State (Shipping)",
"shippingAddressPostalCode": "Postal Code (Shipping)",
"shippingAddressState": "Map (Shipping)"
"shippingAddressMap": "Map (Shipping)"
},
"links": {
"contacts": "Contacts",

View File

@@ -1,7 +1,8 @@
{
"labels": {
"Create KnowledgeBaseArticle": "Create Article",
"Any": "Any"
"Any": "Any",
"Send in Email": "Send in Email"
},
"fields": {
"name": "Name",

View File

@@ -1,7 +1,8 @@
{
"labels": {
"Create KnowledgeBaseCategory": "Create Category",
"Manage Categories": "Manage Categories"
"Manage Categories": "Manage Categories",
"Articles": "Articles"
},
"links": {
"articles": "Articles"

View File

@@ -31,7 +31,9 @@
"campaign": "Campaign",
"createdAccount": "Account",
"createdContact": "Contact",
"createdOpportunity": "Opportunity"
"createdOpportunity": "Opportunity",
"cases": "Cases",
"documents": "Documents"
},
"options": {
"status": {

View File

@@ -1,7 +1,8 @@
{
"labels": {
"Create DocumentFolder": "Crear Carpeta de Documentos",
"Manage Categories": "Administrar Carpetas"
"Manage Categories": "Administrar Carpetas",
"Documents": "Documentos"
},
"links": {
"documents": "Documentos"

View File

@@ -1,7 +1,8 @@
{
"labels": {
"Create DocumentFolder": "Create Document Folder",
"Manage Categories": "Manage Folders"
"Manage Categories": "Manage Folders",
"Documents": "Documenten"
},
"links": {
"documents": "Documenten"

View File

@@ -1,40 +1,80 @@
{
"fields": {
"name": "Imię",
"emailAddress": "E-mail",
"website": "Strona Internetowa",
"phoneNumber": "Telefon",
"billingAddress": "Adres Firmy",
"shippingAddress": "Adres Dostawy",
"description": "Opis ",
"sicCode": "PKD",
"industry": "Branża",
"type": "Rodzaj",
"contactRole": "Rola"
"fields": {
"name": "Nazwa",
"emailAddress": "E-mail",
"website": "Strona Internetowa",
"phoneNumber": "Telefon",
"billingAddress": "Adres Firmy",
"shippingAddress": "Adres Dostawy",
"description": "Opis ",
"sicCode": "PKD",
"industry": "Branża",
"type": "Rodzaj",
"contactRole": "Rola",
"campaign": "Kampania",
"targetLists": "Listy docelowe",
"targetList": "Lista docelowa"
},
"links": {
"contacts": "Kontakty",
"opportunities": "Szanse sprzedaży",
"cases": "Sprawy",
"documents": "Dokumenty",
"meetingsPrimary": "Spotkania (rozwinięte)",
"callsPrimary": "Rozmowy (rozwinięte)",
"tasksPrimary": "Zadania (rozwinięte)",
"emailsPrimary": "Wiadomości (rozwinięte)",
"targetLists": "Listy docelowe",
"campaignLogRecords": "Log kampanii",
"campaign": "Kampania",
"portalUsers": "Portal Users"
},
"options": {
"type": {
"Customer": "Klient",
"Investor": "Inwestor",
"Partner": "Partner",
"Reseller": "Sprzedawca"
},
"links": {
"contacts": "Kontakty",
"opportunities": "Szanse Sprzedaży",
"cases": "Zlecenia"
},
"options": {
"type": {
"Customer": "Klient",
"Investor": "Inwestor",
"Partner": "Partner",
"Reseller": "Sprzedawca"
},
"industry": {
"Apparel": "Odzież",
"Banking": "Bankowość",
"Computer Software": "Oprogramowanie Komputerowe",
"Education": "Edukacja",
"Electronics": "Elektronika",
"Finance": "Finanse",
"Insurance": "Ubezpieczenia"
}
},
"labels": {
"Create Account": "Utwórz Konto"
"industry": {
"Agriculture": "Agriculture",
"Advertising": "Reklamy",
"Apparel & Accessories": "Wystrój i akcesoria",
"Automotive": "Motoryzacja",
"Banking": "Bankowość",
"Biotechnology": "Biotechnologia",
"Building Materials & Equipment": "Materiały budowlane i wyposażenie",
"Chemical": "Chemia",
"Computer": "Komputery",
"Education": "Edukacja",
"Electronics": "Elektronika",
"Energy": "Energetyka",
"Entertainment & Leisure": "Rozrywka",
"Finance": "Finanse",
"Food & Beverage": "Jedzenie i napoje",
"Grocery": "Sklep spożywczy",
"Healthcare": "Opieka zdrowotna",
"Insurance": "Ubezpieczenia",
"Legal": "Legal",
"Manufacturing": "Manufacturing",
"Publishing": "Publishing",
"Real Estate": "Real Estate",
"Service": "Service",
"Sports": "Sport",
"Software": "Software",
"Technology": "Technologia",
"Telecommunications": "Telekomunikacja",
"Television": "Telewizja",
"Transportation": "Transport",
"Venture Capital": "Venture Capital"
}
}
},
"labels": {
"Create Account": "Utwórz Konto",
"Copy Billing": "Copy Billing"
},
"presetFilters": {
"customers": "Klienci",
"partners": "Partnerzy"
}
}

View File

@@ -0,0 +1,6 @@
{
"layouts": {
"detailConvert": "Convert Lead",
"listForAccount": "List (for Account)"
}
}

View File

@@ -1,13 +1,13 @@
{
"modes": {
"month": "Miesiąc",
"week": "Tydzień",
"day": "Dzień",
"agendaWeek": "Tydzień",
"agendaDay": "Dzień"
},
"labels": {
"Today": "Dziś",
"Create": "Utwórz"
}
}
"modes": {
"month": "Miesiąc",
"week": "Tydzień",
"agendaWeek": "Tydzień",
"day": "Dzień",
"agendaDay": "Dzień"
},
"labels": {
"Today": "Dziś",
"Create": "Utwórz"
}
}

View File

@@ -1,39 +1,49 @@
{
"fields": {
"name": "Imię",
"parent": "Konto",
"status": "Status",
"dateStart": "Data Startu",
"dateEnd": "Data Zakończenia",
"direction": "Kierunek",
"duration": "Czas",
"description": "Opis ",
"users": "Użytkownik",
"contacts": "Kontakty",
"leads": "Potencjalne Kontakty"
"fields": {
"name": "Nazwa",
"parent": "Rodzic",
"status": "Status",
"dateStart": "Data rozpoczęcia",
"dateEnd": "Data zakończenia",
"direction": "Kierunek",
"duration": "Czas",
"description": "Opis ",
"users": "Użytkownik",
"contacts": "Kontakty",
"leads": "Potencjalne Kontakty",
"reminders": "Przypomnienia",
"account": "Klient"
},
"options": {
"status": {
"Planned": "Planowane",
"Held": "Odbyło się",
"Not Held": "Nie odbyło się"
},
"links": {
"direction": {
"Outbound": "Wychodzący",
"Inbound": "Przychodzący"
},
"options": {
"status": {
"Planned": "Planowane",
"Held": "Zatrzymany",
"Not Held": "Nie zatrzymany"
},
"direction": {
"Outbound": "Wychodzący",
"Inbound": "Przychodzący"
}
},
"labels": {
"Create Call": "Utwórz Telefon",
"Set Held": "Ustaw Zatrzymanie",
"Set Not Held": "Ustaw nie Zatrzymany",
"Send Invitations": "Wyślij Powiadomienie"
},
"presetFilters": {
"planned": "Planowane",
"held": "Zatrzymany",
"todays": "Dzisiaj"
"acceptanceStatus": {
"None": "Brak",
"Accepted": "Zaakceptowany",
"Declined": "Odrzucony",
"Tentative": "Niepewny"
}
}
},
"massActions": {
"setHeld": "Odbyło się",
"setNotHeld": "Nie odbyło się"
},
"labels": {
"Create Call": "Utwórz Telefon",
"Set Held": "Odbyło się",
"Set Not Held": "Nie odbyło się",
"Send Invitations": "Wyślij Powiadomienie"
},
"presetFilters": {
"planned": "Planowane",
"held": "Odbyło się",
"todays": "Dzisiaj"
}
}

View File

@@ -0,0 +1,71 @@
{
"fields": {
"name": "Nazwa",
"description": "Opis",
"status": "Status",
"type": "Typ",
"startDate": "Data rozpoczęcia",
"endDate": "Data zakończenia",
"targetLists": "Listy docelowe",
"excludingTargetLists": "Excluding Target Lists",
"sentCount": "Wysłano",
"openedCount": "Otwarty",
"clickedCount": "Kliknięte",
"optedOutCount": "Wypisany",
"bouncedCount": "Odrzucone",
"hardBouncedCount": "Twarde odrzucenie",
"softBouncedCount": "Miękkie odrzucenie",
"leadCreatedCount": "Leads Created",
"revenue": "Zwrot",
"revenueConverted": "Zwrot (skonwertowany)",
"budget": "Budżet",
"budgetConverted": "Budżet (skonwertowany)"
},
"links": {
"targetLists": "Listy docelowe",
"excludingTargetLists": "Excluding Target Lists",
"accounts": "Klienci",
"contacts": "Kontakty",
"leads": "Potencjalne kontakty",
"opportunities": "Szanse sprzedaży",
"campaignLogRecords": "Log",
"massEmails": "Poczta masowa",
"trackingUrls": "Adresy śledzenia"
},
"options": {
"type": {
"Email": "E-mail",
"Web": "Strona internetowa",
"Television": "Telewizja",
"Radio": "Radio",
"Newsletter": "Newsletter",
"Mail": "Wiadomość"
},
"status": {
"Planning": "Planowanie",
"Active": "Aktywny",
"Inactive": "Nieaktywny",
"Complete": "Gotowe"
}
},
"labels": {
"Create Campaign": "Utwórz kampanię",
"Target Lists": "Listy docelowe",
"Statistics": "Statystyki",
"hard": "twardy",
"soft": "miękki",
"Unsubscribe": "Wypisz się",
"Mass Emails": "Poczta masowa",
"Email Templates": "Szablony wiadomości"
},
"presetFilters": {
"active": "Aktywny"
},
"messages": {
"unsubscribed": "Zostałeś wypisany z naszej listy mailingowej."
},
"tooltips": {
"targetLists": "Adresaci, którzy powinni otrzymać wiadomości.",
"excludingTargetLists": "Adresaci, którzy nie powinni otrzymać wiadomości."
}
}

View File

@@ -0,0 +1,40 @@
{
"fields": {
"action": "Akcja",
"actionDate": "Data",
"data": "Dane",
"campaign": "Kampania",
"parent": "Cel",
"object": "Obiekt",
"application": "Aplikacja",
"queueItem": "Element kolejki",
"stringData": "Dane tekstowe",
"stringAdditionalData": "Dodatkowe dane tekstowe"
},
"links": {
"queueItem": "Element kolejki",
"parent": "Rodzic",
"object": "Obiekt"
},
"options": {
"action": {
"Sent": "Wysłano",
"Opened": "Otwarty",
"Opted Out": "Wypisany",
"Bounced": "Odrzucone",
"Clicked": "Kliknięte",
"Lead Created": "Lead Created"
}
},
"labels": {
"All": "Wszystko"
},
"presetFilters": {
"sent": "Wysłano",
"opened": "Otwarty",
"optedOut": "Wypisany",
"bounced": "Odrzucone",
"clicked": "Kliknięte",
"leadCreated": "Lead Created"
}
}

View File

@@ -0,0 +1,13 @@
{
"fields": {
"url": "URL",
"urlToUse": "Kod do wstawienia zamiast URL",
"campaign": "Kampania"
},
"links": {
"campaign": "Kampania"
},
"labels": {
"Create CampaignTrackingUrl": "Utwórz adres śledzenia"
}
}

View File

@@ -1,42 +1,57 @@
{
"fields": {
"name": "Imię",
"number": "Numer",
"status": "Status",
"account": "Konto",
"contact": "Kontakty",
"priority": "Pryjorytet",
"type": "Rodzaj",
"description": "Opis "
"fields": {
"name": "Nazwa",
"number": "Numer",
"status": "Status",
"account": "Klient",
"contact": "Kontakty",
"contacts": "Kontakty",
"priority": "Priorytet",
"type": "Rodzaj",
"description": "Opis ",
"inboundEmail": "Wiadomość przychodząca"
},
"links": {
"inboundEmail": "Wiadomość przychodząca",
"account": "Klient",
"contact": "Contact (Primary)",
"Contacts": "Kontakty",
"meetings": "Spotkania",
"calls": "Rozmowy",
"tasks": "Zadania",
"emails": "Wiadomości",
"articles": "Artykuły bazy wiedzy"
},
"options": {
"status": {
"New": "Nowy",
"Assigned": "Przypisany",
"Pending": "Oczekiwanie",
"Closed": "Zamknięty",
"Rejected": "Odrzucony",
"Duplicate": "Powielony"
},
"links": {
"priority": {
"Low": "Niski",
"Normal": "Normalny",
"High": "Wysoki",
"Urgent": "Pilne"
},
"options": {
"status": {
"New": "Nowy",
"Assigned": "Przypisany",
"Pending": "Oczekuje",
"Closed": "Zamknięty",
"Rejected": "Odrzucony",
"Duplicate": "Powielony"
},
"priority" : {
"Low": "Niski",
"Normal": "Normalny",
"High": "Wysoki",
"Urgent": "Pilne"
},
"type": {
"Question": "Pytanie",
"Incident": "Zdarzenie",
"Problem": "Problem"
}
},
"labels": {
"Create Case": "Utwórz Sprawę"
},
"presetFilters": {
"open": "Otwórz",
"closed": "Zamknięty"
"type": {
"Question": "Pytanie",
"Incident": "Zdarzenie",
"Problem": "Problem"
}
}
},
"labels": {
"Create Case": "Utwórz sprawę",
"Close": "Zamknij",
"Reject": "Odrzuć",
"Closed": "Zamknięty",
"Rejected": "Odrzucony"
},
"presetFilters": {
"open": "Otwórz",
"closed": "Zamknięty"
}
}

View File

@@ -1,31 +1,46 @@
{
"fields": {
"name": "Imię",
"emailAddress": "E-mail",
"title": "Tytuł",
"account": "Konto",
"accounts": "Klienci",
"phoneNumber": "Telefon",
"accountType": "Typ Klienta",
"doNotCall": "Nie Dzwoń",
"address": "Adres",
"opportunityRole": "Rola Szansy Sprzedaży",
"accountRole": "Rola",
"description": "Opis "
},
"links": {
"opportunities": "Szanse Sprzedaży",
"cases": "Zlecenia"
},
"labels": {
"Create Contact": "Utwórz Kontakt"
},
"options": {
"opportunityRole": {
"": "--NIC--",
"Decision Maker": "Osoba Decyzyjna",
"Evaluator": "Oceniający",
"Influencer": "Wpływający"
}
"fields": {
"name": "Nazwa",
"emailAddress": "E-mail",
"title": "Tytuł",
"accountRole": "Tytuł",
"account": "Klient",
"accounts": "Klienci",
"phoneNumber": "Telefon",
"accountType": "Typ Klienta",
"doNotCall": "Nie Dzwoń",
"address": "Adres",
"opportunityRole": "Rola szansy sprzedaży",
"description": "Opis ",
"campaign": "Kampania",
"targetLists": "Listy docelowe",
"targetList": "Lista docelowa",
"portalUser": "Portal User"
},
"links": {
"opportunities": "Szanse sprzedaży",
"cases": "Sprawy",
"targetLists": "Listy docelowe",
"campaignLogRecords": "Log kampanii",
"campaign": "Kampania",
"account": "Konto (podstawowe)",
"accounts": "Klienci",
"casesPrimary": "Cases (Primary)",
"portalUser": "Portal User"
},
"labels": {
"Create Contact": "Utwórz Kontakt"
},
"options": {
"opportunityRole": {
"": "--NIC--",
"Decision Maker": "Osoba Decyzyjna",
"Evaluator": "Oceniający",
"Influencer": "Wpływający"
}
}
},
"presetFilters": {
"portalUsers": "Portal Users",
"notPortalUsers": "Not Portal Users"
}
}

View File

@@ -0,0 +1,42 @@
{
"labels": {
"Create Document": "Utwórz dokument",
"Details": "Szczegóły"
},
"fields": {
"name": "Nazwa",
"status": "Status",
"file": "Plik",
"type": "Typ",
"source": "Źródło",
"publishDate": "Data publikacji",
"expirationDate": "Data przedawnienia",
"description": "Opis",
"accounts": "Klienci",
"folder": "Katalog"
},
"links": {
"accounts": "Klienci",
"opportunities": "Szanse sprzedaży",
"folder": "Katalog"
},
"options": {
"status": {
"Active": "Aktywny",
"Draft": "Szkic",
"Expired": "Przedawniony",
"Canceled": "Anulowane"
},
"type": {
"": "Brak",
"Contract": "Kontrakt",
"NDA": "NDA",
"EULA": "EULA",
"License Agreement": "Postanowienia licencyjne"
}
},
"presetFilters": {
"active": "Aktywny",
"draft": "Szkic"
}
}

View File

@@ -0,0 +1,10 @@
{
"labels": {
"Create DocumentFolder": "Utwórz folder dokumentów",
"Manage Categories": "Zarządzaj katalogami",
"Documents": "Dokumenty"
},
"links": {
"documents": "Dokumenty"
}
}

View File

@@ -0,0 +1,8 @@
{
"labels": {
"Create Lead": "Utwórz potencjalny kontakt",
"Create Contact": "Utwórz kontakt",
"Create Task": "Utwórz zadanie",
"Create Case": "Utwórz sprawę"
}
}

View File

@@ -0,0 +1,28 @@
{
"fields": {
"name": "Nazwa",
"status": "Status",
"target": "Cel",
"sentAt": "Data wysłania",
"attemptCount": "Próby",
"emailAddress": "Adres e-mail",
"massEmail": "Poczta masowa",
"isTest": "Testowa"
},
"links": {
"target": "Cel",
"massEmail": "Poczta masowa"
},
"options": {
"status": {
"Pending": "Oczekiwanie",
"Sent": "Wysłano",
"Failed": "Niepowodzenie"
}
},
"presetFilters": {
"pending": "Oczekiwanie",
"sent": "Wysłano",
"failed": "Niepowodzenie"
}
}

View File

@@ -1,81 +1,115 @@
{
"scopeNames": {
"Account": "Konto",
"Contact": "Kontakty",
"Lead": "Potencjalny Kontakt",
"Target": "Cel",
"Opportunity": "Szansa Sprzedaży",
"Meeting": "Spotkanie",
"Calendar": "Kalendarz",
"Call": "Telefon",
"Task": "Zadanie",
"Case": "Sprawa",
"InboundEmail": "Poczta Przychodząca"
},
"scopeNamesPlural": {
"Account": "Klienci",
"Contact": "Kontakty",
"Lead": "Potencjalne Kontakty",
"Target": "Cele",
"Opportunity": "Szanse Sprzedaży",
"Meeting": "Spotkania",
"Calendar": "Kalendarz",
"Call": "Telefony",
"Task": "Zadania",
"Case": "Zlecenia",
"InboundEmail": "Poczta Przychodząca"
},
"dashlets": {
"Leads": "Moje Potencjalne Kontakty",
"Opportunities": "Moje Szanse Sprzedaży",
"Tasks": "Moje Zadania",
"Cases": "Moje Zlecenia",
"Calendar": "Kalendarz",
"Calls": "Moje Telefony",
"Meetings": "Moje Spotkania",
"OpportunitiesByStage": "Szansa Sprzedaży/Etap/",
"OpportunitiesByLeadSource": "Szansa Sprzedaży/Potencjalny kontakt/",
"SalesByMonth": "Sprzedaż Miesięczna",
"SalesPipeline": "Lejek Sprzedaży"
},
"labels": {
"Create InboundEmail": "Utwórz Pocztę Przychodzącą",
"Activities": "Aktywności",
"History": "Historia",
"Attendees": "Uczestnicy",
"Schedule Meeting": "Zaplanuj Spotkanie",
"Schedule Call": "Zaplanuj Telefon",
"Compose Email": "Utwórz Wiadomość",
"Log Meeting": "Zarejestruj Spotkanie",
"Log Call": "Zarejestruj Telefon",
"Archive Email": "Archiwizuj e-mail",
"Create Task": "Utwórz Zadanie",
"Tasks": "Zadania"
},
"fields": {
"billingAddressCity": "Miasto",
"billingAddressCountry": "Kraj",
"billingAddressPostalCode": "Kod Pocztowy",
"billingAddressState": "Województwo",
"billingAddressStreet": "Ulica",
"addressCity": "Miasto",
"addressStreet": "Ulica",
"addressCountry": "Kraj",
"addressState": "Województwo",
"addressPostalCode": "Kod Pocztowy",
"shippingAddressCity": "City (Shipping)",
"shippingAddressStreet": "Street (Shipping)",
"shippingAddressCountry": "Country (Shipping)",
"shippingAddressState": "State (Shipping)",
"shippingAddressPostalCode": "Postal Code (Shipping)"
},
"links": {
"contacts": "Kontakty",
"opportunities": "Szanse Sprzedaży",
"leads": "Potencjalne Kontakty",
"meetings": "Spotkania",
"calls": "Telefony",
"tasks": "Zadania",
"emails": "Emails"
"links": {
"parent": "Rodzic",
"contacts": "Kontakty",
"opportunities": "Szanse sprzedaży",
"leads": "Potencjalne Kontakty",
"meetings": "Spotkania",
"calls": "Rozmowy",
"tasks": "Zadania",
"emails": "Wiadomości",
"accounts": "Klienci",
"cases": "Sprawy",
"documents": "Dokumenty",
"account": "Klient",
"opportunity": "Szansa sprzedaży",
"contact": "Kontakt"
},
"scopeNames": {
"Account": "Klient",
"Contact": "Kontakty",
"Lead": "Potencjalny Kontakt",
"Target": "Cel",
"Opportunity": "Szansa sprzedaży",
"Meeting": "Spotkanie",
"Calendar": "Kalendarz",
"Call": "Rozmowa",
"Task": "Zadanie",
"Case": "Sprawa",
"Document": "Dokument",
"DocumentFolder": "Folder dokumentu",
"Campaign": "Kampania",
"TargetList": "Lista docelowa",
"MassEmail": "Poczta masowa",
"EmailQueueItem": "Element kolejki wiadomości",
"CampaignTrackingUrl": "Adres śledzenia",
"Activities": "Aktywności",
"KnowledgeBaseArticle": "Artykuł bazy wiedzy",
"KnowledgeBaseCategory": "Kategoria bazy wiedzy"
},
"scopeNamesPlural": {
"Account": "Klienci",
"Contact": "Kontakty",
"Lead": "Potencjalne Kontakty",
"Target": "Cele",
"Opportunity": "Szanse sprzedaży",
"Meeting": "Spotkania",
"Calendar": "Kalendarz",
"Call": "Rozmowy",
"Task": "Zadania",
"Case": "Sprawy",
"Document": "Dokumenty",
"DocumentFolder": "Foldery dokumentów",
"Campaign": "Kampanie",
"TargetList": "Listy docelowe",
"MassEmail": "Wiadomości masowe",
"EmailQueueItem": "Elementy kolejki wiadomości",
"CampaignTrackingUrl": "Adresy śledzenia",
"Activities": "Aktywności",
"KnowledgeBaseArticle": "Baza wiedzy",
"KnowledgeBaseCategory": "Kategorie bazy wiedzy"
},
"dashlets": {
"Leads": "Moje Potencjalne Kontakty",
"Opportunities": "Moje Szanse Sprzedaży",
"Tasks": "Moje Zadania",
"Cases": "Moje Zlecenia",
"Calendar": "Kalendarz",
"Calls": "Moje Telefony",
"Meetings": "Moje Spotkania",
"OpportunitiesByStage": "Szanse według etapu",
"OpportunitiesByLeadSource": "Szanse według potencjalnych kontaktów",
"SalesByMonth": "Sprzedaż Miesięczna",
"SalesPipeline": "Lejek Sprzedaży",
"Activities": "Moje aktywności"
},
"labels": {
"Create InboundEmail": "Utwórz pocztę przychodzącą",
"Activities": "Aktywności",
"History": "Historia",
"Attendees": "Uczestnicy",
"Schedule Meeting": "Zaplanuj Spotkanie",
"Schedule Call": "Zaplanuj Telefon",
"Compose Email": "Utwórz Wiadomość",
"Log Meeting": "Zarejestruj Spotkanie",
"Log Call": "Zarejestruj Telefon",
"Archive Email": "Archiwizuj e-mail",
"Create Task": "Utwórz zadanie",
"Tasks": "Zadania"
},
"fields": {
"billingAddressCity": "Miasto",
"addressCity": "Miasto",
"billingAddressCountry": "Kraj",
"addressCountry": "Kraj",
"billingAddressPostalCode": "Kod Pocztowy",
"addressPostalCode": "Kod Pocztowy",
"billingAddressState": "Województwo",
"addressState": "Województwo",
"billingAddressStreet": "Ulica",
"addressStreet": "Ulica",
"billingAddressMap": "Mapa",
"addressMap": "Mapa",
"shippingAddressCity": "Miasto (dostawy)",
"shippingAddressStreet": "Ulica (dostawy)",
"shippingAddressCountry": "Country (Shipping)",
"shippingAddressState": "State (Shipping)",
"shippingAddressPostalCode": "Kod pocztowy (dostawy)"
},
"options": {
"reminderTypes": {
"Popup": "Wyskakujące okienko",
"Email": "E-mail"
}
}
}
}

View File

@@ -0,0 +1,42 @@
{
"labels": {
"Create KnowledgeBaseArticle": "Utwórz artykuł",
"Any": "Dowolny"
},
"fields": {
"name": "Nazwa",
"status": "Status",
"type": "Typ",
"attachments": "Załączniki",
"publishDate": "Data publikacji",
"expirationDate": "Data przedawnienia",
"description": "Opis",
"body": "Treść",
"categories": "Kategorie",
"language": "Język",
"portals": "Portale"
},
"links": {
"cases": "Sprawy",
"opportunities": "Szanse sprzedaży",
"categories": "Kategorie",
"portals": "Portale"
},
"options": {
"status": {
"In Review": "W recenzji",
"Draft": "Szkic",
"Archived": "Zarchiwizowany",
"Published": "Opublikowane"
},
"type": {
"Article": "Artykuł"
}
},
"tooltips": {
"portals": "If not empty then this article will be available only in specified portals. If empty then it will available in all portals."
},
"presetFilters": {
"published": "Published"
}
}

View File

@@ -0,0 +1,9 @@
{
"labels": {
"Create KnowledgeBaseCategory": "Utwórz kategorię",
"Manage Categories": "Manage Categories"
},
"links": {
"articles": "Artykuły"
}
}

View File

@@ -1,50 +1,62 @@
{
"labels": {
"Converted To": "Przekształcony w ",
"Create Lead": "Utwórz Potencjalny Kontakt",
"Convert": "Przekształć"
"labels": {
"Converted To": "Przekształcony w ",
"Create Lead": "Utwórz potencjalny kontakt",
"Convert": "Przekształć"
},
"fields": {
"name": "Nazwa",
"emailAddress": "E-mail",
"title": "Tytuł",
"website": "Strona Internetowa",
"phoneNumber": "Telefon",
"accountName": "Nazwa Konta",
"doNotCall": "Nie Dzwoń",
"address": "Adres",
"status": "Status",
"source": "Źródło",
"opportunityAmount": "Wartość szansy sprzedaży",
"opportunityAmountConverted": "Wartość szansy sprzedaży (konwertowana)",
"description": "Opis ",
"createdAccount": "Klient",
"createdContact": "Kontakty",
"createdOpportunity": "Szansa sprzedaży",
"campaign": "Kampania",
"targetLists": "Listy docelowe",
"targetList": "Lista docelowa"
},
"links": {
"targetLists": "Listy docelowe",
"campaignLogRecords": "Log kampanii",
"campaign": "Kampania",
"createdAccount": "Klient",
"createdContact": "Kontakt",
"createdOpportunity": "Szansa sprzedaży"
},
"options": {
"status": {
"New": "Nowy",
"Assigned": "Przypisany",
"In Process": "W trakcie",
"Converted": "Przekształcony",
"Recycled": "Usunięty",
"Dead": "Martwy"
},
"fields": {
"name": "Imię",
"emailAddress": "E-mail",
"title": "Tytuł",
"website": "Strona Internetowa",
"phoneNumber": "Telefon",
"accountName": "Nazwa Konta",
"doNotCall": "Nie Dzwoń",
"address": "Adres",
"status": "Status",
"source": "Źródło",
"opportunityAmount": "Wartość Szansy Sprzewdaży",
"opportunityAmountConverted": "Opportunity Amount (converted)",
"description": "Opis ",
"createdAccount": "Konto",
"createdContact": "Kontakty",
"createdOpportunity": "Szansa Sprzedaży"
},
"links": {
},
"options": {
"status": {
"New": "Nowy",
"Assigned": "Przypisany",
"In Process": "W trakcie",
"Converted": "Przekształcony",
"Recycled": "Usunięty",
"Dead": "Martwy"
},
"source": {
"Call": "Telefon",
"Email": "E-mail",
"Existing Customer": "Istniejący klient",
"Partner": "Partner",
"Public Relations": "Relacje",
"Web Site": "Stwona Internetowa",
"Campaign": "Kampania",
"Other": "Inny"
}
},
"presetFilters": {
"active": "Aktywny"
"source": {
"": "Brak",
"Call": "Rozmowa",
"Email": "E-mail",
"Existing Customer": "Istniejący klient",
"Partner": "Partner",
"Public Relations": "Relacje",
"Web Site": "Stwona Internetowa",
"Campaign": "Kampania",
"Other": "Inny"
}
}
},
"presetFilters": {
"active": "Aktywny",
"actual": "Bieżący",
"converted": "Przekształcony"
}
}

View File

@@ -0,0 +1,49 @@
{
"fields": {
"name": "Nazwa",
"status": "Status",
"storeSentEmails": "Zapisz wysłane wiadomości",
"startAt": "Data rozpoczęcia",
"fromAddress": "Z adresu",
"fromName": "Od",
"replyToAddress": "Reply-to Address",
"replyToName": "Reply-to Name",
"campaign": "Kampania",
"emailTemplate": "Szablon wiadomości",
"inboundEmail": "Konto pocztowe",
"targetLists": "Listy docelowe",
"excludingTargetLists": "Excluding Target Lists",
"optOutEntirely": "Wypisz się całkowicie"
},
"links": {
"targetLists": "Listy docelowe",
"excludingTargetLists": "Excluding Target Lists",
"queueItems": "Elementy kolejki",
"campaign": "Kampania",
"emailTemplate": "Szablon wiadomości",
"inboundEmail": "Konto pocztowe"
},
"options": {
"status": {
"Draft": "Szkic",
"Pending": "Oczekiwanie",
"In Process": "W trakcie",
"Complete": "Gotowe",
"Canceled": "Anulowane",
"Failed": "Niepowodzenie"
}
},
"labels": {
"Create MassEmail": "Utwórz wiadomość masową",
"Send Test": "Wyślij test"
},
"messages": {
"selectAtLeastOneTarget": "Wybierz przynajmniej jeden cel.",
"testSent": "Wiadomość testowa powinna być wysłana"
},
"tooltips": {
"optOutEntirely": "Email addresses of recipients that unsubscribed will be marked as opted out and they will not receive any mass emails anymore.",
"targetLists": "Adresaci, którzy powinni otrzymać wiadomości.",
"excludingTargetLists": "Adresaci, którzy nie powinni otrzymać wiadomości."
}
}

View File

@@ -1,36 +1,46 @@
{
"fields": {
"name": "Imię",
"parent": "Konto",
"status": "Status",
"dateStart": "Data Startu",
"dateEnd": "Data Zakończenia",
"duration": "Czas",
"description": "Opis ",
"users": "Użytkownik",
"contacts": "Kontakty",
"leads": "Potencjalne Kontakty"
"fields": {
"name": "Nazwa",
"parent": "Rodzic",
"status": "Status",
"dateStart": "Data rozpoczęcia",
"dateEnd": "Data zakończenia",
"duration": "Czas",
"description": "Opis ",
"users": "Użytkownik",
"contacts": "Kontakty",
"leads": "Potencjalne Kontakty",
"reminders": "Przypomnienia",
"account": "Klient"
},
"options": {
"status": {
"Planned": "Planowane",
"Held": "Odbyło się",
"Not Held": "Nie odbyło się"
},
"links": {
},
"options": {
"status": {
"Planned": "Planowane",
"Held": "Zatrzymany",
"Not Held": "Nie zatrzymany"
}
},
"labels": {
"Create Meeting": "Utwórz Spotkanie",
"Set Held": "Ustaw Zatrzymanie",
"Set Not Held": "Ustaw nie Zatrzymany",
"Send Invitations": "Wyślij Powiadomienie",
"Saved as Held": "Zapisz jako zatrzymany",
"Saved as Not Held": "Zapisz jako nie utrzymany"
},
"presetFilters": {
"planned": "Planowane",
"held": "Zatrzymany",
"todays": "Dzisiaj"
"acceptanceStatus": {
"None": "Brak",
"Accepted": "Zaakceptowany",
"Declined": "Odrzucony",
"Tentative": "Niepewny"
}
}
},
"massActions": {
"setHeld": "Odbyło się",
"setNotHeld": "Nie odbyło się"
},
"labels": {
"Create Meeting": "Utwórz Spotkanie",
"Set Held": "Odbyło się",
"Set Not Held": "Nie odbyło się",
"Send Invitations": "Wyślij Powiadomienie",
"on time": "na czas",
"before": "przed"
},
"presetFilters": {
"planned": "Planowane",
"held": "Odbyło się",
"todays": "Dzisiaj"
}
}

View File

@@ -1,39 +1,44 @@
{
"fields": {
"name": "Imię",
"account": "Konto",
"stage": "Estap",
"amount": "Wartość",
"probability": "Prawdopodobieństwo, %",
"leadSource": "Zródło Potencjalnego Kontaktu",
"doNotCall": "Nie Dzwoń",
"closeDate": "Data Zamknięcia",
"contacts": "Kontakty",
"description": "Opis ",
"amountConverted": "Amount (converted)"
},
"links": {
"contacts": "Kontakty"
},
"options": {
"stage": {
"Prospecting": "I Spotkanie",
"Qualification": "Kwalifikacja",
"Needs Analysis": "Dodatkowa Analiza",
"Value Proposition": "Oferta Produktowa",
"Id. Decision Makers": "Oferta przekazna do osoby decyzyjnej",
"Perception Analysis": "Perception Analysis",
"Proposal/Price Quote": "Oferta Cenowa",
"Negotiation/Review": "Negocjacje ",
"Closed Won": "Zakończone Wygrane",
"Closed Lost": "Zakończone Przegrane"
}
},
"labels": {
"Create Opportunity": "Utwórz Szanse"
},
"presetFilters": {
"open": "Otwórz",
"won": "Wygrane"
"fields": {
"name": "Nazwa",
"account": "Klient",
"stage": "Etap",
"amount": "Wartość",
"probability": "Prawdopodobieństwo, %",
"leadSource": "Zródło Potencjalnego Kontaktu",
"doNotCall": "Nie Dzwoń",
"closeDate": "Data Zamknięcia",
"contacts": "Kontakty",
"description": "Opis ",
"amountConverted": "Wartość (konwertowana)",
"amountWeightedConverted": "Wartość ważona",
"campaign": "Kampania"
},
"links": {
"contacts": "Kontakty",
"documents": "Dokumenty",
"campaign": "Kampania"
},
"options": {
"stage": {
"Prospecting": "I Spotkanie",
"Qualification": "Kwalifikacja",
"Needs Analysis": "Dodatkowa Analiza",
"Value Proposition": "Oferta Produktowa",
"Id. Decision Makers": "Oferta przekazna do osoby decyzyjnej",
"Perception Analysis": "Perception Analysis",
"Proposal/Price Quote": "Oferta Cenowa",
"Negotiation/Review": "Negocjacje ",
"Closed Won": "Zakończone Wygrane",
"Closed Lost": "Zakończone Przegrane"
}
}
},
"labels": {
"Create Opportunity": "Utwórz Szanse"
},
"presetFilters": {
"open": "Otwórz",
"won": "Wygrane",
"lost": "Utracone"
}
}

View File

@@ -0,0 +1,5 @@
{
"links": {
"articles": "Artykuły bazy wiedzy"
}
}

View File

@@ -0,0 +1,8 @@
{
"options": {
"job": {
"ProcessMassEmail": "Wyślij wiadomości masowe",
"ControlKnowledgeBaseArticleStatus": "Control Knowledge Base Article Status"
}
}
}

View File

@@ -1,19 +1,17 @@
{
"fields": {
"name": "Imię",
"emailAddress": "E-mail",
"title": "Tytuł",
"website": "Strona Internetowa",
"accountName": "Nazwa Konta",
"phoneNumber": "Telefon",
"doNotCall": "Nie Dzwoń",
"address": "Adres",
"description": "Opis "
},
"links": {
},
"labels": {
"Create Target": "Utwórz Cel",
"Convert to Lead": "Przekształć w Potencjalny Kontakt"
}
}
"fields": {
"name": "Nazwa",
"emailAddress": "E-mail",
"title": "Tytuł",
"website": "Strona Internetowa",
"accountName": "Nazwa Konta",
"phoneNumber": "Telefon",
"doNotCall": "Nie Dzwoń",
"address": "Adres",
"description": "Opis "
},
"labels": {
"Create Target": "Utwórz Cel",
"Convert to Lead": "Przekształć w Potencjalny Kontakt"
}
}

View File

@@ -0,0 +1,32 @@
{
"fields": {
"name": "Nazwa",
"description": "Opis",
"entryCount": "Ilość jednostek",
"campaigns": "Kampanie",
"endDate": "Data zakończenia",
"targetLists": "Listy docelowe"
},
"links": {
"accounts": "Klienci",
"contacts": "Kontakty",
"leads": "Leads",
"campaigns": "Kampanie",
"massEmails": "Wiadomości masowe"
},
"options": {
"type": {
"Email": "E-mail",
"Web": "Strona internetowa",
"Television": "Telewizja",
"Radio": "Radio",
"Newsletter": "Newsletter"
}
},
"labels": {
"Create TargetList": "Create Target List",
"Opted Out": "Wypisany",
"Cancel Opt-Out": "Cancel Opt-Out",
"Opt-Out": "Wypisz się"
}
}

View File

@@ -1,37 +1,45 @@
{
"fields": {
"name": "Imię",
"parent": "Konto",
"status": "Status",
"dateStart": "Data Startu",
"dateEnd": "Data Zwrotu",
"priority": "Pryjorytet",
"description": "Opis ",
"isOverdue": "Przegrzany"
"fields": {
"name": "Nazwa",
"parent": "Rodzic",
"status": "Status",
"dateStart": "Data rozpoczęcia",
"dateEnd": "Data zwrotu",
"dateStartDate": "Data rozpoczęcia",
"dateEndDate": "Data zakończenia",
"priority": "Pryjorytet",
"description": "Opis ",
"isOverdue": "Przegrzany",
"account": "Klient",
"dateCompleted": "Data ukończenia",
"attachments": "Załączniki"
},
"links": {
"attachments": "Załączniki"
},
"options": {
"status": {
"Not Started": "Nie Rozpoczęte",
"Started": "Rozpoczęte",
"Completed": "Ukończone",
"Canceled": "Anulowane",
"Deferred": "Opóźniony"
},
"links": {
},
"options": {
"status": {
"Not Started": "Nie Rozpoczęte",
"Started": "Rozpoczęte",
"Completed": "Ukończone",
"Canceled": "Anulowane"
},
"priority" : {
"Low": "Niski",
"Normal": "Normalny",
"High": "Wysoki",
"Urgent": "Pilne"
}
},
"labels": {
"Create Task": "Utwórz Zadanie"
},
"presetFilters": {
"active": "Aktywny",
"completed": "Ukończone",
"todays": "Dzisiaj",
"overdue": "Przegrzane"
"priority": {
"Low": "Niski",
"Normal": "Normalny",
"High": "Wysoki",
"Urgent": "Pilne"
}
}
},
"labels": {
"Create Task": "Utwórz zadanie",
"Complete": "Gotowe"
},
"presetFilters": {
"actual": "Bieżący",
"completed": "Ukończone",
"todays": "Dzisiaj",
"overdue": "Przegrzane"
}
}

View File

@@ -0,0 +1,5 @@
{
"links": {
"targetLists": "Listy docelowe"
}
}

View File

@@ -1,7 +1,8 @@
{
"labels": {
"Create DocumentFolder": "Создать папку",
"Manage Categories": "Управление папками"
"Manage Categories": "Управление папками",
"Documents": "Документы"
},
"links": {
"documents": "Документы"

View File

@@ -2,10 +2,10 @@
{
"label":"",
"rows":[
[{"name":"name"}],
[{"name":"name", "fullWidth": true}],
[{"name":"website"}, {"name": "billingAddressCountry"}],
[{"name":"emailAddress"}],
[{"name":"phoneNumber"}],
[{"name":"emailAddress", "fullWidth": true}],
[{"name":"phoneNumber", "fullWidth": true}],
[{"name":"type"}, {"name":"industry"}]
]
}

View File

@@ -2,9 +2,9 @@
{
"label": "",
"rows": [
[{"name":"name"}],
[{"name":"name", "fullWidth": true}],
[{"name":"type"}, {"name":"status"}],
[{"name":"endDate"}]
[{"name":"endDate", "fullWidth": true}]
]
}
]

View File

@@ -2,10 +2,10 @@
{
"label": "",
"rows": [
[{"name":"name"}],
[{"name":"accounts"}],
[{"name":"emailAddress"}],
[{"name":"phoneNumber"}]
[{"name":"name", "fullWidth": true}],
[{"name":"accounts", "fullWidth": true}],
[{"name":"emailAddress", "fullWidth": true}],
[{"name":"phoneNumber", "fullWidth": true}]
]
}
]

View File

@@ -3,7 +3,7 @@
"label": "",
"rows": [
[{"name":"file"}, {"name":"source"}],
[{"name":"name"}],
[{"name":"name", "fullWidth": true}],
[{"name":"status"}, {"name":"folder"}]
]
}

View File

@@ -5,8 +5,8 @@
[{"name":"name", "fullWidth": true}],
[{"name":"account", "fullWidth": true}],
[{"name":"stage"}, {"name":"closeDate"}],
[{"name":"amount"}],
[{"name":"description"}]
[{"name":"amount", "fullWidth": true}],
[{"name":"description", "fullWidth": true}]
]
}
]

View File

@@ -1 +1,9 @@
[{"label":"","rows":[[{"name":"name"}],[{"name":"emailAddress"}],[{"name":"phoneNumber"}]]}]
[
{
"label":"",
"rows":
[
[{"name":"name", "fullWidth": true}],[{"name":"emailAddress", "fullWidth": true}],[{"name":"phoneNumber", "fullWidth": true}]
]
}
]

View File

@@ -2,7 +2,9 @@
{
"label": "",
"rows": [
[{"name":"name"}]
[{"name":"name", "fullWidth": true}],
[{"name":"entryCount", "fullWidth": true}],
[{"name":"description", "fullWidth": true}]
]
}
]

View File

@@ -3,5 +3,9 @@
"path": "client/modules/crm/lib/fullcalendar.min.js",
"exportsTo": "$",
"exportsAs": "fullCalendar"
},
"vis": {
"path": "client/modules/crm/lib/vis.min.js",
"exportsAs": "vis"
}
}

View File

@@ -2,6 +2,6 @@
"event": {
"url": "Activities/action/popupNotifications",
"interval": 15,
"view": "Crm:Meeting.PopupNotification"
"view": "crm:views/meeting/popup-notification"
}
}

View File

@@ -6,6 +6,7 @@
},
"scopeList": ["Meeting", "Call", "Task"],
"allDayScopeList": ["Task"],
"modeList": ["month", "agendaWeek", "agendaDay"],
"modeList": ["month", "agendaWeek", "agendaDay", "timeline"],
"canceledStatusList": ["Not Held", "Canceled"],
"completedStatusList": ["Held", "Completed"]
}

View File

@@ -1,5 +1,6 @@
{
"controller": "controllers/record",
"acl": "crm:acl/call",
"views":{
"detail":"crm:views/call/detail"
},

View File

@@ -1,4 +1,12 @@
{
"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"
},
"defaultSidePanel": {
"edit": false,
"editSmall": false
}
}

View File

@@ -41,7 +41,8 @@
"relationshipPanels": {
"articles": {
"create": false,
"rowActionsView": "views/record/row-actions/relationship-view-and-unlink"
"recordListView": "crm:views/knowledge-base-article/record/list-for-case",
"rowActionsView": "crm:views/knowledge-base-article/record/row-actions/for-case"
}
},
"boolFilterList": ["onlyMy"],

View File

@@ -9,6 +9,13 @@
"link": "#DocumentFolder\/list",
"acl": "read",
"style": "default"
},
{
"label": "Documents",
"link": "#Document",
"acl": "read",
"style": "default",
"aclScope": "Document"
}
]
},
@@ -19,6 +26,13 @@
"link": "#DocumentFolder",
"acl": "read",
"style": "default"
},
{
"label": "Documents",
"link": "#Document",
"acl": "read",
"style": "default",
"aclScope": "Document"
}
]
}

View File

@@ -5,7 +5,8 @@
},
"recordViews":{
"editQuick":"crm:views/knowledge-base-article/record/edit-quick",
"detailQuick":"crm:views/knowledge-base-article/record/detail-quick"
"detailQuick":"crm:views/knowledge-base-article/record/detail-quick",
"detail":"crm:views/knowledge-base-article/record/detail"
},
"modalViews": {
"select": "crm:views/knowledge-base-article/modals/select-records"

View File

@@ -9,6 +9,13 @@
"link": "#KnowledgeBaseCategory\/list",
"acl": "read",
"style": "default"
},
{
"label": "Articles",
"link": "#KnowledgeBaseArticle",
"acl": "read",
"style": "default",
"aclScope": "KnowledgeBaseArticle"
}
]
},
@@ -19,6 +26,13 @@
"link": "#KnowledgeBaseCategory",
"acl": "read",
"style": "default"
},
{
"label": "Articles",
"link": "#KnowledgeBaseArticle",
"acl": "read",
"style": "default",
"aclScope": "KnowledgeBaseArticle"
}
]
}

View File

@@ -2,11 +2,17 @@
"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"
},
"defaultSidePanel": {
"edit": false,
"editSmall": false
},
"formDependency": {
"status": {
"map": {

View File

@@ -1,5 +1,6 @@
{
"controller": "controllers/record",
"acl": "crm:acl/meeting",
"views":{
"detail":"crm:views/meeting/detail"
},

View File

@@ -12,7 +12,7 @@
},
"displayRecords": {
"type": "enumInt",
"options": [3,4,5,10,15,20,30]
"options": [3,4,5,10,15,20,30,50]
}
},
"defaults": {

View File

@@ -2,6 +2,7 @@
"view":"crm:views/dashlets/calendar",
"aclScope": "Calendar",
"options": {
"view": "crm:views/dashlets/options/calendar",
"fields": {
"title": {
"type": "varchar",
@@ -19,7 +20,13 @@
},
"mode": {
"type": "enum",
"options": ["basicWeek", "agendaWeek", "month"]
"options": ["basicWeek", "agendaWeek", "timeline", "month", "basicDay", "agendaDay"]
},
"users": {
"type": "linkMultiple",
"entity": "User",
"view": "views/fields/assigned-users",
"sortable": true
}
},
"defaults": {
@@ -37,6 +44,10 @@
[
{"name": "mode"},
{"name": "enabledScopeList"}
],
[
{"name": "users"},
false
]
]
}

View File

@@ -14,7 +14,7 @@
},
"displayRecords": {
"type": "enumInt",
"options": [3,4,5,10,15]
"options": [3,4,5,10,15,20,30]
}
},
"defaults": {

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