diff --git a/application/Espo/Modules/Crm/Repositories/Opportunity.php b/application/Espo/Modules/Crm/Repositories/Opportunity.php index 725059a4eb..78312efc68 100644 --- a/application/Espo/Modules/Crm/Repositories/Opportunity.php +++ b/application/Espo/Modules/Crm/Repositories/Opportunity.php @@ -38,7 +38,9 @@ class Opportunity extends \Espo\Core\ORM\Repositories\RDB if ($entity->isNew()) { if (!$entity->has('probability') && $entity->get('stage')) { $probability = $this->getMetadata()->get('entityDefs.Opportunity.fields.stage.probabilityMap.' . $entity->get('stage'), 0); - $entity->set('probability', $probability); + if (!is_null($probability)) { + $entity->set('probability', $probability); + } } } diff --git a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Campaign.json b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Campaign.json index 371d4b907d..8b94e51ca6 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Campaign.json +++ b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Campaign.json @@ -61,6 +61,7 @@ "sentCount": { "type": "int", "notStorable": true, + "directAccessDisabled": true, "readOnly": true, "disabled": true }, @@ -68,6 +69,7 @@ "view": "crm:views/campaign/fields/int-with-percentage", "type": "int", "notStorable": true, + "directAccessDisabled": true, "readOnly": true, "disabled": true }, @@ -75,12 +77,14 @@ "view": "crm:views/campaign/fields/int-with-percentage", "type": "int", "notStorable": true, + "directAccessDisabled": true, "readOnly": true, "disabled": true }, "optedInCount": { "type": "int", "notStorable": true, + "directAccessDisabled": true, "readOnly": true, "disabled": true }, @@ -88,6 +92,7 @@ "view": "crm:views/campaign/fields/int-with-percentage", "type": "int", "notStorable": true, + "directAccessDisabled": true, "readOnly": true, "disabled": true }, @@ -95,54 +100,63 @@ "view": "crm:views/campaign/fields/int-with-percentage", "type": "int", "notStorable": true, + "directAccessDisabled": true, "readOnly": true, "disabled": true }, "hardBouncedCount": { "type": "int", "notStorable": true, + "directAccessDisabled": true, "readOnly": true, "disabled": true }, "softBouncedCount": { "type": "int", "notStorable": true, + "directAccessDisabled": true, "readOnly": true, "disabled": true }, "leadCreatedCount": { "type": "int", "notStorable": true, + "directAccessDisabled": true, "readOnly": true, "disabled": true }, "openedPercentage": { "type": "int", "notStorable": true, + "directAccessDisabled": true, "readOnly": true, "disabled": true }, "clickedPercentage": { "type": "int", "notStorable": true, + "directAccessDisabled": true, "readOnly": true, "disabled": true }, "optedOutPercentage": { "type": "int", "notStorable": true, + "directAccessDisabled": true, "readOnly": true, "disabled": true }, "bouncedPercentage": { "type": "int", "notStorable": true, + "directAccessDisabled": true, "readOnly": true, "disabled": true }, "revenue": { "type": "currency", "notStorable": true, + "directAccessDisabled": true, "readOnly": true, "disabled": true }, diff --git a/application/Espo/Resources/i18n/en_US/Admin.json b/application/Espo/Resources/i18n/en_US/Admin.json index 2f21bd280d..aee31315c9 100644 --- a/application/Espo/Resources/i18n/en_US/Admin.json +++ b/application/Espo/Resources/i18n/en_US/Admin.json @@ -202,7 +202,8 @@ "cronIsNotConfigured": "Scheduled jobs are not running. Hence inbound emails, notifications and reminders are not working. Please follow the [instructions](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab) to setup cron job.", "newVersionIsAvailable": "New EspoCRM version {latestVersion} is available.", "newExtensionVersionIsAvailable": "New {extensionName} version {latestVersion} is available.", - "uninstallConfirmation": "Are you sure you want to uninstall the extension?" + "uninstallConfirmation": "Are you sure you want to uninstall the extension?", + "upgradeInfo": "Check the documentation about how to upgrade your EspoCRM instance. Upgrading from CLI is the most preferable way." }, "descriptions": { "settings": "System settings of application.", diff --git a/application/Espo/Resources/i18n/en_US/LeadCapture.json b/application/Espo/Resources/i18n/en_US/LeadCapture.json index 654da64b3e..80d9fbb9f2 100644 --- a/application/Espo/Resources/i18n/en_US/LeadCapture.json +++ b/application/Espo/Resources/i18n/en_US/LeadCapture.json @@ -16,7 +16,8 @@ "targetTeam": "Target Team", "exampleRequestMethod": "Method", "exampleRequestUrl": "URL", - "exampleRequestPayload": "Payload" + "exampleRequestPayload": "Payload", + "duplicateCheck": "Duplicate Check" }, "links": { "targetList": "Target List", diff --git a/application/Espo/Resources/layouts/LeadCapture/detail.json b/application/Espo/Resources/layouts/LeadCapture/detail.json index de4ea0f71f..a36784680a 100644 --- a/application/Espo/Resources/layouts/LeadCapture/detail.json +++ b/application/Espo/Resources/layouts/LeadCapture/detail.json @@ -7,6 +7,7 @@ [{"name": "subscribeContactToTargetList"}, {"name": "targetList"}], [{"name": "targetTeam"}, {"name": "leadSource"}], [{"name": "fieldList", "fullWidth": true}], + [{"name": "duplicateCheck"}, false], [{"name": "apiKey", "fullWidth": true}] ] }, diff --git a/application/Espo/Resources/layouts/LeadCaptureLogRecord/detailSmall.json b/application/Espo/Resources/layouts/LeadCaptureLogRecord/detailSmall.json new file mode 100644 index 0000000000..366995b4ad --- /dev/null +++ b/application/Espo/Resources/layouts/LeadCaptureLogRecord/detailSmall.json @@ -0,0 +1,10 @@ +[ + { + "label":"", + "rows":[ + [{"name": "target"}, {"name":"leadCapture"}], + [{"name": "isCreated"}, {"name":"createdAt"}], + [{"name": "data", "fullWidth": true}] + ] + } +] diff --git a/application/Espo/Resources/layouts/LeadCaptureLogRecord/filters.json b/application/Espo/Resources/layouts/LeadCaptureLogRecord/filters.json new file mode 100644 index 0000000000..1646ce0d17 --- /dev/null +++ b/application/Espo/Resources/layouts/LeadCaptureLogRecord/filters.json @@ -0,0 +1,4 @@ +[ + "isCreated", + "createdAt" +] diff --git a/application/Espo/Resources/layouts/LeadCaptureLogRecord/listForLeadCapture.json b/application/Espo/Resources/layouts/LeadCaptureLogRecord/listForLeadCapture.json index 17942039ae..55ede72410 100644 --- a/application/Espo/Resources/layouts/LeadCaptureLogRecord/listForLeadCapture.json +++ b/application/Espo/Resources/layouts/LeadCaptureLogRecord/listForLeadCapture.json @@ -1,4 +1,5 @@ [ - {"name":"target"}, - {"name":"createdAt", "width": "30"} + {"name":"target", "notSortable": true}, + {"name":"isCreated", "width": "25", "notSortable": true}, + {"name":"createdAt", "width": "30", "notSortable": true} ] diff --git a/application/Espo/Resources/metadata/clientDefs/LeadCapture.json b/application/Espo/Resources/metadata/clientDefs/LeadCapture.json index 4f863db890..a526ebb2c5 100644 --- a/application/Espo/Resources/metadata/clientDefs/LeadCapture.json +++ b/application/Espo/Resources/metadata/clientDefs/LeadCapture.json @@ -112,7 +112,7 @@ }, "relationshipPanels": { "logRecords": { - "rowActionsView": "views/record/row-actions/remove-only", + "rowActionsView": "views/record/row-actions/view-and-remove", "layout": "listForLeadCapture", "select": false, "create": false diff --git a/application/Espo/Resources/metadata/clientDefs/LeadCaptureLogRecord.json b/application/Espo/Resources/metadata/clientDefs/LeadCaptureLogRecord.json new file mode 100644 index 0000000000..aa38b03391 --- /dev/null +++ b/application/Espo/Resources/metadata/clientDefs/LeadCaptureLogRecord.json @@ -0,0 +1,5 @@ +{ + "modalViews": { + "detail": "views/lead-capture-log-record/modals/detail" + } +} diff --git a/application/Espo/Resources/metadata/entityDefs/LeadCapture.json b/application/Espo/Resources/metadata/entityDefs/LeadCapture.json index 945755566d..7595152e13 100644 --- a/application/Espo/Resources/metadata/entityDefs/LeadCapture.json +++ b/application/Espo/Resources/metadata/entityDefs/LeadCapture.json @@ -41,6 +41,10 @@ "createdContact" ] }, + "duplicateCheck": { + "type": "bool", + "default": true + }, "optInConfirmation": { "type": "bool" }, diff --git a/application/Espo/Services/Email.php b/application/Espo/Services/Email.php index 5f28c65a54..b49129ec72 100644 --- a/application/Espo/Services/Email.php +++ b/application/Espo/Services/Email.php @@ -123,6 +123,7 @@ class Email extends Record $primaryUserAddress = strtolower($this->getUser()->get('emailAddress')); $fromAddress = strtolower($entity->get('from')); + $originalFromAddress = $entity->get('from'); if (empty($fromAddress)) { throw new Error("Can't send with empty from address."); @@ -143,7 +144,7 @@ class Email extends Record } $emailAccountService = $this->getServiceFactory()->create('EmailAccount'); - $emailAccount = $emailAccountService->findAccountForUser($this->getUser(), $fromAddress); + $emailAccount = $emailAccountService->findAccountForUser($this->getUser(), $originalFromAddress); if (!$smtpParams) { if ($emailAccount && $emailAccount->get('useSmtp')) { @@ -156,15 +157,15 @@ class Email extends Record } if ($smtpParams) { - if ($fromAddress) { - $this->applySmtpHandler($this->getUser()->id, $fromAddress, $smtpParams); + if ($emailAddress) { + $this->applySmtpHandler($this->getUser()->id, $emailAddress, $smtpParams); } $emailSender->useSmtp($smtpParams); } if (!$smtpParams) { $inboundEmailService = $this->getServiceFactory()->create('InboundEmail'); - $inboundEmail = $inboundEmailService->findSharedAccountForUser($this->getUser(), $fromAddress); + $inboundEmail = $inboundEmailService->findSharedAccountForUser($this->getUser(), $originalFromAddress); if ($inboundEmail) { $smtpParams = $inboundEmailService->getSmtpParamsFromAccount($inboundEmail); } diff --git a/application/Espo/Services/EmailAccount.php b/application/Espo/Services/EmailAccount.php index 01cb1926d2..3ad09e49ef 100644 --- a/application/Espo/Services/EmailAccount.php +++ b/application/Espo/Services/EmailAccount.php @@ -119,6 +119,7 @@ class EmailAccount extends Record $imapParams = null; if ($emailAddress && $userId) { + $emailAddress = strtolower($emailAddress); $userData = $this->getEntityManager()->getRepository('UserData')->getByUserId($userId); if ($userData) { $imapHandlers = $userData->get('imapHandlers') ?? (object) []; diff --git a/application/Espo/Services/LeadCapture.php b/application/Espo/Services/LeadCapture.php index e161f2df0a..c4a5c4cbd7 100644 --- a/application/Espo/Services/LeadCapture.php +++ b/application/Espo/Services/LeadCapture.php @@ -242,7 +242,9 @@ class LeadCapture extends Record $groupOr['phoneNumber'] = $lead->get('phoneNumber'); } - $duplicate = $this->getEntityManager()->getRepository('Lead')->where(['OR' => $groupOr])->findOne(); + if ($leadCapture->get('duplicateCheck')) { + $duplicate = $this->getEntityManager()->getRepository('Lead')->where(['OR' => $groupOr])->findOne(); + } $contact = $this->getEntityManager()->getRepository('Contact')->where(['OR' => $groupOr])->findOne(); if ($contact) { $target = $contact; diff --git a/client/modules/crm/src/views/opportunity/fields/stage.js b/client/modules/crm/src/views/opportunity/fields/stage.js index 47e72dab99..9b20374ac8 100644 --- a/client/modules/crm/src/views/opportunity/fields/stage.js +++ b/client/modules/crm/src/views/opportunity/fields/stage.js @@ -37,7 +37,10 @@ Espo.define('crm:views/opportunity/fields/stage', 'views/fields/enum', function if (this.mode != 'list') { this.on('change', function () { - this.model.set('probability', this.probabilityMap[this.model.get(this.name)]); + var probability = this.probabilityMap[this.model.get(this.name)]; + if (probability !== null && probability !== undefined) { + this.model.set('probability', probability); + } }, this); } } diff --git a/client/res/templates/admin/upgrade/index.tpl b/client/res/templates/admin/upgrade/index.tpl index e17cefe1c0..78d3719aff 100644 --- a/client/res/templates/admin/upgrade/index.tpl +++ b/client/res/templates/admin/upgrade/index.tpl @@ -1,10 +1,15 @@
{{versionMsg}}
+ {{{infoMsg}}}
+
{{backupsMsg}}