diff --git a/application/Espo/Controllers/Layout.php b/application/Espo/Controllers/Layout.php index 76e65e2079..a14eaf149f 100644 --- a/application/Espo/Controllers/Layout.php +++ b/application/Espo/Controllers/Layout.php @@ -25,6 +25,7 @@ namespace Espo\Controllers; use Espo\Core\Utils as Utils; use \Espo\Core\Exceptions\NotFound; use \Espo\Core\Exceptions\Error; +use \Espo\Core\Exceptions\Forbidden; class Layout extends \Espo\Core\Controllers\Base { @@ -39,6 +40,10 @@ class Layout extends \Espo\Core\Controllers\Base public function actionUpdate($params, $data) { + if (!$this->getUser()->isAdmin()) { + throw new Forbidden(); + } + $result = $this->getContainer()->get('layout')->set($data, $params['scope'], $params['name']); if ($result === false) { diff --git a/application/Espo/Controllers/Notification.php b/application/Espo/Controllers/Notification.php index 3c2f82379b..03811feadf 100644 --- a/application/Espo/Controllers/Notification.php +++ b/application/Espo/Controllers/Notification.php @@ -54,7 +54,13 @@ class Notification extends \Espo\Core\Controllers\Base public function actionNotReadCount() { $userId = $this->getUser()->id; - return $this->getService('Notification')->getNotReadCount($userId); + return $this->getService('Notification')->getNotReadCount($userId); + } + + public function actionMarkAllRead($params, $data, $request) + { + $userId = $this->getUser()->id; + return $this->getService('Notification')->markAllRead($userId); } } diff --git a/application/Espo/Core/SelectManagers/Base.php b/application/Espo/Core/SelectManagers/Base.php index 74c73a6fff..a6c1aa47f8 100644 --- a/application/Espo/Core/SelectManagers/Base.php +++ b/application/Espo/Core/SelectManagers/Base.php @@ -176,18 +176,23 @@ class Base } $result['whereClause']['assignedUserId'] = $this->user->id; } - if ($this->acl->checkReadOnlyTeam($this->entityName)) { + if (!$this->user->isAdmin() && $this->acl->checkReadOnlyTeam($this->entityName)) { if (!array_key_exists('whereClause', $result)) { $result['whereClause'] = array(); } + $result['distinct'] = true; if (!array_key_exists('joins', $result)) { $result['joins'] = array(); } if (!in_array('teams', $result['joins'])) { - $result['joins'][] = 'teams'; + $result['leftJoins'][] = 'teams'; } - $result['whereClause']['Team.id'] = $this->user->get('teamsIds'); + $result['whereClause']['OR'] = array( + 'Team.id' => $this->user->get('teamsIds'), + 'assignedUserId' => $this->user->id + ); + //$result['whereClause']['Team.id'] = $this->user->get('teamsIds'); } } diff --git a/application/Espo/Core/Services/Base.php b/application/Espo/Core/Services/Base.php index f9c7a202fd..d28a8afb23 100644 --- a/application/Espo/Core/Services/Base.php +++ b/application/Espo/Core/Services/Base.php @@ -26,7 +26,11 @@ use \Espo\Core\Interfaces\Injectable; abstract class Base implements Injectable { - protected $dependencies = array(); + protected $dependencies = array( + 'config', + 'entityManager', + 'user', + ); protected $injections = array(); @@ -53,5 +57,20 @@ abstract class Base implements Injectable { return $this->dependencies; } + + protected function getEntityManager() + { + return $this->getInjection('entityManager'); + } + + protected function getConfig() + { + return $this->getInjection('config'); + } + + protected function getUser() + { + return $this->getInjection('user'); + } } diff --git a/application/Espo/Core/defaults/config.php b/application/Espo/Core/defaults/config.php index 724829e55f..02cb39afac 100644 --- a/application/Espo/Core/defaults/config.php +++ b/application/Espo/Core/defaults/config.php @@ -90,6 +90,9 @@ return array ( "tabList" => array("Account", "Contact", "Lead", "Opportunity", "Calendar", "Meeting", "Call", "Task", "Case", "Email"), "quickCreateList" => array("Account", "Contact", "Lead", "Opportunity", "Meeting", "Call", "Task", "Case"), 'calendarDefaultEntity' => 'Meeting', + 'disableExport' => false, + 'assignmentEmailNotifications' => false, + 'assignmentEmailNotificationsEntityList' => array('Lead', 'Opportunity', 'Task', 'Case'), 'isInstalled' => false, ); diff --git a/application/Espo/Hooks/Common/AssignmentEmailNotification.php b/application/Espo/Hooks/Common/AssignmentEmailNotification.php new file mode 100644 index 0000000000..4191222c62 --- /dev/null +++ b/application/Espo/Hooks/Common/AssignmentEmailNotification.php @@ -0,0 +1,58 @@ +getConfig()->get('assignmentEmailNotifications') + && + in_array($entity->getEntityName(), $this->getConfig()->get('assignmentEmailNotificationsEntityList', array())) + ) { + + $userId = $entity->get('assignedUserId'); + if (!empty($userId) && $userId != $this->getUser()->id && $entity->isFieldChanged('assignedUserId')) { + $job = $this->getEntityManager()->getEntity('Job'); + $job->set(array( + 'serviceName' => 'EmailNotification', + 'method' => 'notifyAboutAssignmentJob', + 'data' => json_encode(array( + 'userId' => $userId, + 'assignerUserId' => $this->getUser()->id, + 'entityId' => $entity->id, + 'entityType' => $entity->getEntityName() + )), + 'executeTime' => date('Y-m-d H:i:s'), + )); + $this->getEntityManager()->saveEntity($job); + } + } + } + +} + diff --git a/application/Espo/Modules/Crm/Resources/i18n/en_US/Global.json b/application/Espo/Modules/Crm/Resources/i18n/en_US/Global.json index 4e8e1d3355..d224ea2e32 100644 --- a/application/Espo/Modules/Crm/Resources/i18n/en_US/Global.json +++ b/application/Espo/Modules/Crm/Resources/i18n/en_US/Global.json @@ -31,6 +31,8 @@ "Tasks": "My Tasks", "Cases": "My Cases", "Calendar": "Calendar", + "Calls": "My Calls", + "Meetings": "My Meetings", "OpportunitiesByStage": "Opportunities by Stage", "OpportunitiesByLeadSource": "Opportunities by Lead Source", "SalesByMonth": "Sales by Month", diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Calendar.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Calendar.json index 35cd5348b4..70b0e1c73d 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Calendar.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Calendar.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.Calendar"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Calls.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Calls.json new file mode 100644 index 0000000000..78a2f1b939 --- /dev/null +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Calls.json @@ -0,0 +1 @@ +{"view":"Crm:Dashlets.Calls"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Cases.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Cases.json index 35cd5348b4..f518fbab1e 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Cases.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Cases.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.Cases"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Leads.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Leads.json index 35cd5348b4..595862a3cf 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Leads.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Leads.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.Leads"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Meetings.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Meetings.json new file mode 100644 index 0000000000..17838c2e56 --- /dev/null +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Meetings.json @@ -0,0 +1 @@ +{"view":"Crm:Dashlets.Meetings"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Opportunities.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Opportunities.json index 35cd5348b4..524c074c7a 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Opportunities.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Opportunities.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.Opportunities"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/OpportunitiesByLeadSource.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/OpportunitiesByLeadSource.json index 35cd5348b4..7b8d988fd7 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/OpportunitiesByLeadSource.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/OpportunitiesByLeadSource.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.OpportunitiesByLeadSource"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/OpportunitiesByStage.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/OpportunitiesByStage.json index 35cd5348b4..3e75625357 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/OpportunitiesByStage.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/OpportunitiesByStage.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.OpportunitiesByStage"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/SalesByMonth.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/SalesByMonth.json index 35cd5348b4..cff85c9eb0 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/SalesByMonth.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/SalesByMonth.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.SalesByMonth"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/SalesPipeline.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/SalesPipeline.json index 35cd5348b4..f312aa2101 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/SalesPipeline.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/SalesPipeline.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.SalesPipeline"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Tasks.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Tasks.json index 35cd5348b4..c9d63fc12a 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Tasks.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Tasks.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.Tasks"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Call.json b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Call.json index 8e58a5235d..6106cc7bbc 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Call.json +++ b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Call.json @@ -52,7 +52,8 @@ }, "contacts": { "type": "linkMultiple", - "disabled": true + "disabled": true, + "view": "Crm:Meeting.Fields.Contacts" }, "leads": { "type": "linkMultiple", diff --git a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Meeting.json b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Meeting.json index 2d6b57a976..b0a6e1b7aa 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Meeting.json +++ b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Meeting.json @@ -47,7 +47,8 @@ }, "contacts": { "type": "linkMultiple", - "disabled": true + "disabled": true, + "view": "Crm:Meeting.Fields.Contacts" }, "leads": { "type": "linkMultiple", diff --git a/application/Espo/Modules/Crm/Services/Lead.php b/application/Espo/Modules/Crm/Services/Lead.php index e2e6f0c329..2128af3cbd 100644 --- a/application/Espo/Modules/Crm/Services/Lead.php +++ b/application/Espo/Modules/Crm/Services/Lead.php @@ -25,6 +25,8 @@ namespace Espo\Modules\Crm\Services; use \Espo\Core\Exceptions\Error; use \Espo\Core\Exceptions\Forbidden; +use \Espo\ORM\Entity; + class Lead extends \Espo\Services\Record { protected function getDuplicateWhereClause(Entity $entity) diff --git a/application/Espo/ORM/DB/Mapper.php b/application/Espo/ORM/DB/Mapper.php index 37d7df2584..26473aa5c4 100644 --- a/application/Espo/ORM/DB/Mapper.php +++ b/application/Espo/ORM/DB/Mapper.php @@ -1098,7 +1098,9 @@ abstract class Mapper implements IMapper if ($operator == '<>') { $oppose = 'NOT'; } + if (!empty($valArr)) { $whereParts[] = $leftPart . " {$oppose} IN " . "(" . implode(',', $valArr) . ")"; + } } } } else { diff --git a/application/Espo/Resources/i18n/en_US/Admin.json b/application/Espo/Resources/i18n/en_US/Admin.json index cefff21850..93e8161d0e 100644 --- a/application/Espo/Resources/i18n/en_US/Admin.json +++ b/application/Espo/Resources/i18n/en_US/Admin.json @@ -113,7 +113,7 @@ "fieldManager": "Create new fields or customize existing ones.", "userInterface": "Configure UI.", "authTokens": "Active auth sessions. IP address and last access date.", - "authentication": "Authentication setttings." + "authentication": "Authentication settings." }, "options": { "previewSize": { diff --git a/application/Espo/Resources/i18n/en_US/Global.json b/application/Espo/Resources/i18n/en_US/Global.json index 844cce3b28..4894bf19c6 100644 --- a/application/Espo/Resources/i18n/en_US/Global.json +++ b/application/Espo/Resources/i18n/en_US/Global.json @@ -114,7 +114,8 @@ "Administration": "Administration", "Run Import": "Run Import", "Duplicate": "Duplicate", - "Notifications": "Notifications" + "Notifications": "Notifications", + "Mark all read": "Mark all read" }, "messages": { "notModified": "You have not modified the record", @@ -130,7 +131,13 @@ "fieldShouldBeBetween": "{field} should be between {min} and {max}", "fieldShouldBeLess": "{field} should be less then {value}", "fieldShouldBeGreater": "{field} should be greater then {value}", - "fieldBadPasswordConfirm": "{field} confirmed improperly" + "fieldBadPasswordConfirm": "{field} confirmed improperly", + "assignmentEmailNotificationSubject": "EspoCRM {entityType}: {Entity.name}", + "assignmentEmailNotificationBody": "{assignerUserName} has assigned {entityType} '{Entity.name}' to you\n\n{recordUrl}", + "confirmation": "Are you sure?", + "removeRecordConfirmation": "Are you sure you want to remove the record?", + "unlinkRecordConfirmation": "Are you sure you want to unlink relationship?", + "removeSelectedRecordsConfirmation": "Are you sure you want to remove selected records?" }, "boolFilters": { "onlyMy": "Only My", diff --git a/application/Espo/Resources/i18n/en_US/Preferences.json b/application/Espo/Resources/i18n/en_US/Preferences.json index a67dae5202..93fdd7cd55 100644 --- a/application/Espo/Resources/i18n/en_US/Preferences.json +++ b/application/Espo/Resources/i18n/en_US/Preferences.json @@ -19,7 +19,9 @@ "smtpPassword": "Password", "smtpEmailAddress": "Email Address", - "exportDelimiter": "Export Delimiter" + "exportDelimiter": "Export Delimiter", + + "receiveAssignmentEmailNotifications": "Receive Email Notifications upon Assignment" }, "links": { }, @@ -28,5 +30,8 @@ "0": "Sunday", "1": "Monday" } + }, + "labels": { + "Notifications": "Notifications" } } diff --git a/application/Espo/Resources/i18n/en_US/Role.json b/application/Espo/Resources/i18n/en_US/Role.json index 0227aa422a..fce516a200 100644 --- a/application/Espo/Resources/i18n/en_US/Role.json +++ b/application/Espo/Resources/i18n/en_US/Role.json @@ -28,5 +28,8 @@ "read": "Read", "edit": "Edit", "delete": "Delete" + }, + "messages": { + "changesAfterClearCache": "All changes in an access control will be applied after cache will be cleared." } } diff --git a/application/Espo/Resources/i18n/en_US/Settings.json b/application/Espo/Resources/i18n/en_US/Settings.json index ef0fb441d5..51ce8dc499 100644 --- a/application/Espo/Resources/i18n/en_US/Settings.json +++ b/application/Espo/Resources/i18n/en_US/Settings.json @@ -47,7 +47,9 @@ "ldapUserLoginFilter": "User Login Filter", "ldapAccountDomainNameShort": "Account Domain Name Short", "ldapOptReferrals": "Opt Referrals", - "disableExport": "Disable Export (only admin is allowed)" + "disableExport": "Disable Export (only admin is allowed)", + "assignmentEmailNotifications": "Send Email Notifications upon Assignment", + "assignmentEmailNotificationsEntityList": "Entities to Notify About" }, "options": { "weekStart": { @@ -59,6 +61,7 @@ "System": "System", "Locale": "Locale", "SMTP": "SMTP", - "Configuration": "Configuration" + "Configuration": "Configuration", + "Notifications": "Notifications" } } diff --git a/application/Espo/Resources/layouts/Preferences/detail.json b/application/Espo/Resources/layouts/Preferences/detail.json index 6ea25698d2..2caa3668b3 100644 --- a/application/Espo/Resources/layouts/Preferences/detail.json +++ b/application/Espo/Resources/layouts/Preferences/detail.json @@ -28,5 +28,11 @@ "rows": [ [{"name": "exportDelimiter"}] ] + }, + { + "label": "Notifications", + "rows": [ + [{"name": "receiveAssignmentEmailNotifications"}] + ] } ] diff --git a/application/Espo/Resources/layouts/Settings/outboundEmail.json b/application/Espo/Resources/layouts/Settings/outboundEmail.json index 639bd1fcc8..6c03e2a432 100644 --- a/application/Espo/Resources/layouts/Settings/outboundEmail.json +++ b/application/Espo/Resources/layouts/Settings/outboundEmail.json @@ -14,5 +14,11 @@ [{"name": "outboundEmailFromName"}, {"name": "outboundEmailFromAddress"}], [{"name": "outboundEmailIsShared"}] ] + }, + { + "label": "Notifications", + "rows": [ + [{"name": "assignmentEmailNotifications"}, {"name": "assignmentEmailNotificationsEntityList"}] + ] } ] diff --git a/application/Espo/Resources/metadata/clientDefs/Role.json b/application/Espo/Resources/metadata/clientDefs/Role.json index e5f3a2976e..555b981242 100644 --- a/application/Espo/Resources/metadata/clientDefs/Role.json +++ b/application/Espo/Resources/metadata/clientDefs/Role.json @@ -11,5 +11,8 @@ "teams":{ "create":false } - } + }, + "views": { + "list": "Role.List" + } } diff --git a/application/Espo/Resources/metadata/entityDefs/Preferences.json b/application/Espo/Resources/metadata/entityDefs/Preferences.json index db9270a58d..c7bff38bf6 100644 --- a/application/Espo/Resources/metadata/entityDefs/Preferences.json +++ b/application/Espo/Resources/metadata/entityDefs/Preferences.json @@ -83,6 +83,10 @@ "default": ",", "required": true, "maxLength": 1 + }, + "receiveAssignmentEmailNotifications": { + "type": "bool", + "default": true } } } diff --git a/application/Espo/Resources/metadata/entityDefs/Settings.json b/application/Espo/Resources/metadata/entityDefs/Settings.json index d44bd9fcad..61ec23f914 100644 --- a/application/Espo/Resources/metadata/entityDefs/Settings.json +++ b/application/Espo/Resources/metadata/entityDefs/Settings.json @@ -187,6 +187,14 @@ "disableExport": { "type": "bool", "default": false + }, + "assignmentEmailNotifications": { + "type": "bool", + "default": false + }, + "assignmentEmailNotificationsEntityList": { + "type": "array", + "translation": "Global.scopeNamesPlural" } } } diff --git a/application/Espo/Services/EmailNotification.php b/application/Espo/Services/EmailNotification.php new file mode 100644 index 0000000000..a60d77cc6e --- /dev/null +++ b/application/Espo/Services/EmailNotification.php @@ -0,0 +1,118 @@ +dependencies[] = 'metadata'; + $this->dependencies[] = 'mailSender'; + $this->dependencies[] = 'language'; + } + + protected function getMailSender() + { + return $this->getInjection('mailSender'); + } + + protected function getMetadata() + { + return $this->getInjection('metadata'); + } + + protected function getLanguage() + { + return $this->getInjection('language'); + } + + protected function replaceMessageVariables($text, $entity, $user, $assignerUser) + { + $recordUrl = $this->getConfig()->get('siteUrl') . '#' . $entity->getEntityName() . '/view/' . $entity->id; + + $text = str_replace('{userName}', $user->get('name'), $text); + $text = str_replace('{assignerUserName}', $assignerUser->get('name'), $text); + $text = str_replace('{recordUrl}', $recordUrl, $text); + $text = str_replace('{entityType}', $this->getLanguage()->translate($entity->getEntityName(), 'scopeNames'), $text); + + $fields = $entity->getFields(); + foreach ($fields as $field => $d) { + $text = str_replace('{Entity.' . $field . '}', $entity->get($field), $text); + } + + return $text; + } + + public function notifyAboutAssignmentJob($data) + { + $userId = $data['userId']; + $assignerUserId = $data['assignerUserId']; + $entityId = $data['entityId']; + $entityType = $data['entityType']; + + $user = $this->getEntityManager()->getEntity('User', $userId); + + $prefs = $this->getEntityManager()->getEntity('Preferences', $userId); + + if (!$prefs) { + return true; + } + + if (!$prefs->get('receiveAssignmentEmailNotifications')) { + return true; + } + + $assignerUser = $this->getEntityManager()->getEntity('User', $assignerUserId); + $entity = $this->getEntityManager()->getEntity($entityType, $entityId); + + if ($user && $entity && $assignerUser && $entity->get('assignedUserId') == $userId) { + $emailAddress = $user->get('emailAddress'); + if (!empty($emailAddress)) { + $email = $this->getEntityManager()->getEntity('Email'); + + $subject = $this->getLanguage()->translate('assignmentEmailNotificationSubject', 'messages', $entity->getEntityName()); + $body = $this->getLanguage()->translate('assignmentEmailNotificationBody', 'messages', $entity->getEntityName()); + + $subject = $this->replaceMessageVariables($subject, $entity, $user, $assignerUser); + $body = $this->replaceMessageVariables($body, $entity, $user, $assignerUser); + + $email->set(array( + 'subject' => $subject, + 'body' => $body, + 'isHtml' => false, + 'to' => $emailAddress + )); + + $this->getMailSender()->send($email); + } + } + + return true; + } +} + diff --git a/application/Espo/Services/GlobalSearch.php b/application/Espo/Services/GlobalSearch.php index 675284e905..693874346d 100644 --- a/application/Espo/Services/GlobalSearch.php +++ b/application/Espo/Services/GlobalSearch.php @@ -28,8 +28,7 @@ use \Espo\Core\Exceptions\NotFound; use Espo\ORM\Entity; class GlobalSearch extends \Espo\Core\Services\Base -{ - +{ protected $dependencies = array( 'entityManager', 'user', @@ -48,11 +47,6 @@ class GlobalSearch extends \Espo\Core\Services\Base { return $this->injections['entityManager']; } - - protected function getUser() - { - return $this->injections['user']; - } protected function getAcl() { @@ -62,12 +56,7 @@ class GlobalSearch extends \Espo\Core\Services\Base protected function getMetadata() { return $this->injections['metadata']; - } - - protected function getConfig() - { - return $this->injections['config']; - } + } public function find($query, $offset) { diff --git a/application/Espo/Services/Import.php b/application/Espo/Services/Import.php index 6f6b12dd48..120efd2e97 100644 --- a/application/Espo/Services/Import.php +++ b/application/Espo/Services/Import.php @@ -64,21 +64,11 @@ class Import extends \Espo\Core\Services\Base { return $this->injections['selectManagerFactory']; } - - protected function getEntityManager() - { - return $this->injections['entityManager']; - } protected function getFileManager() { return $this->injections['fileManager']; } - - protected function getUser() - { - return $this->injections['user']; - } protected function getAcl() { @@ -90,11 +80,6 @@ class Import extends \Espo\Core\Services\Base return $this->injections['metadata']; } - protected function getConfig() - { - return $this->injections['config']; - } - protected function getServiceFactory() { return $this->injections['serviceFactory']; diff --git a/application/Espo/Services/Notification.php b/application/Espo/Services/Notification.php index 842616d114..fb282af174 100644 --- a/application/Espo/Services/Notification.php +++ b/application/Espo/Services/Notification.php @@ -84,6 +84,14 @@ class Notification extends \Espo\Core\Services\Base ))->count(); } + public function markAllRead($userId) + { + $pdo = $this->getEntityManager()->getPDO(); + $sql = "UPDATE notification SET `read` = 1 WHERE user_id = ".$pdo->quote($userId)." AND `read` = 0"; + $pdo->prepare($sql)->execute(); + return true; + } + public function getList($userId, array $params = array()) { $searchParams = array(); diff --git a/application/Espo/Services/Record.php b/application/Espo/Services/Record.php index e74ff6dfd3..641341938c 100644 --- a/application/Espo/Services/Record.php +++ b/application/Espo/Services/Record.php @@ -73,11 +73,6 @@ class Record extends \Espo\Core\Services\Base { $this->entityName = $entityName; } - - protected function getEntityManager() - { - return $this->injections['entityManager']; - } protected function getServiceFactory() { @@ -88,11 +83,6 @@ class Record extends \Espo\Core\Services\Base { return $this->injections['selectManagerFactory']; } - - protected function getUser() - { - return $this->injections['user']; - } protected function getAcl() { @@ -102,12 +92,7 @@ class Record extends \Espo\Core\Services\Base protected function getFileManager() { return $this->injections['fileManager']; - } - - protected function getConfig() - { - return $this->injections['config']; - } + } protected function getPreferences() { diff --git a/application/Espo/Services/Stream.php b/application/Espo/Services/Stream.php index c78daed86a..6ee24a7be9 100644 --- a/application/Espo/Services/Stream.php +++ b/application/Espo/Services/Stream.php @@ -63,20 +63,11 @@ class Stream extends \Espo\Core\Services\Base protected $dependencies = array( 'entityManager', + 'config', 'user', 'metadata', 'acl' ); - - protected function getEntityManager() - { - return $this->injections['entityManager']; - } - - protected function getUser() - { - return $this->injections['user']; - } protected function getAcl() { diff --git a/diff.js b/diff.js index 1c801fc0f9..73fb3b1f62 100644 --- a/diff.js +++ b/diff.js @@ -70,10 +70,13 @@ execute('git diff --name-only ' + versionFrom, function (stdout) { var d = new Date(); - var dateN = ((d.getMonth() + 1).toString()); + var monthN = ((d.getMonth() + 1).toString()); + monthN = monthN.length == 1 ? '0' + monthN : monthN; + + var dateN = d.getDate().toString(); dateN = dateN.length == 1 ? '0' + dateN : dateN; - var date = d.getFullYear().toString() + '-' + dateN + '-' + (d.getDate()).toString(); + var date = d.getFullYear().toString() + '-' + monthN + '-' + dateN.toString(); execute('git tag', function (stdout) { var versionList = []; diff --git a/frontend/client/modules/crm/res/templates/calendar/calendar.tpl b/frontend/client/modules/crm/res/templates/calendar/calendar.tpl index d6dad6632d..2f16796625 100644 --- a/frontend/client/modules/crm/res/templates/calendar/calendar.tpl +++ b/frontend/client/modules/crm/res/templates/calendar/calendar.tpl @@ -17,7 +17,7 @@