mirror of
https://github.com/espocrm/espocrm.git
synced 2026-06-28 06:56:05 +00:00
remove system email account
This commit is contained in:
@@ -36,7 +36,6 @@ use Espo\Core\Mail\Account\GroupAccount\AccountFactory as GroupAccountFactory;
|
||||
use Espo\Core\Mail\Account\PersonalAccount\AccountFactory as PersonalAccountFactory;
|
||||
use Espo\Core\Mail\ConfigDataProvider;
|
||||
use Espo\Core\Name\Field;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Entities\EmailAccount as EmailAccountEntity;
|
||||
use Espo\Entities\InboundEmail as InboundEmailEntity;
|
||||
use Espo\Entities\User;
|
||||
@@ -53,11 +52,9 @@ class SendingAccountProvider
|
||||
|
||||
public function __construct(
|
||||
private EntityManager $entityManager,
|
||||
private Config $config,
|
||||
private GroupAccountFactory $groupAccountFactory,
|
||||
private PersonalAccountFactory $personalAccountFactory,
|
||||
private AclManager $aclManager,
|
||||
private SystemSettingsAccount $systemSettingsAccount,
|
||||
private ConfigDataProvider $configDataProvider,
|
||||
) {}
|
||||
|
||||
@@ -222,12 +219,6 @@ class SendingAccountProvider
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->config->get('smtpServer')) {
|
||||
$this->system = $this->systemSettingsAccount;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$entity = $this->entityManager
|
||||
->getRDBRepositoryByClass(InboundEmailEntity::class)
|
||||
->where([
|
||||
|
||||
@@ -1,221 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2025 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://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 Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Mail\Account;
|
||||
|
||||
use Espo\Core\Field\Date;
|
||||
use Espo\Core\Field\DateTime;
|
||||
use Espo\Core\Field\Link;
|
||||
use Espo\Core\Field\LinkMultiple;
|
||||
use Espo\Core\Mail\ConfigDataProvider;
|
||||
use Espo\Core\Mail\Exceptions\NoSmtp;
|
||||
use Espo\Core\Mail\SmtpParams;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Entities\Email;
|
||||
use Espo\Entities\Settings;
|
||||
|
||||
class SystemSettingsAccount implements Account
|
||||
{
|
||||
public function __construct(
|
||||
private Config $config,
|
||||
private ConfigDataProvider $configDataProvider,
|
||||
) {}
|
||||
|
||||
public function updateFetchData(FetchData $fetchData): void {}
|
||||
|
||||
public function getConnectedAt(): ?DateTime
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function updateConnectedAt(): void
|
||||
{}
|
||||
|
||||
public function relateEmail(Email $email): void {}
|
||||
|
||||
public function getPortionLimit(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function isAvailableForFetching(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getEmailAddress(): ?string
|
||||
{
|
||||
return $this->configDataProvider->getSystemOutboundAddress();
|
||||
}
|
||||
|
||||
public function getAssignedUser(): ?Link
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getUser(): ?Link
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getUsers(): LinkMultiple
|
||||
{
|
||||
return LinkMultiple::create();
|
||||
}
|
||||
|
||||
public function getTeams(): LinkMultiple
|
||||
{
|
||||
return LinkMultiple::create();
|
||||
}
|
||||
|
||||
public function keepFetchedEmailsUnread(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFetchData(): FetchData
|
||||
{
|
||||
return FetchData::fromRaw((object) []);
|
||||
}
|
||||
|
||||
public function getFetchSince(): ?Date
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getEmailFolder(): ?Link
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getGroupEmailFolder(): ?Link
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getMonitoredFolderList(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getId(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getEntityType(): string
|
||||
{
|
||||
return Settings::ENTITY_TYPE;
|
||||
}
|
||||
|
||||
public function getHost(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getPort(): ?int
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getUsername(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getPassword(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getSecurity(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?class-string<object>
|
||||
*/
|
||||
public function getImapHandlerClassName(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getSentFolder(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function isAvailableForSending(): bool
|
||||
{
|
||||
return (bool) $this->config->get('smtpServer');
|
||||
}
|
||||
|
||||
public function storeSentEmails(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NoSmtp
|
||||
*/
|
||||
public function getSmtpParams(): ?SmtpParams
|
||||
{
|
||||
$host = $this->config->get('smtpServer');
|
||||
$port = $this->config->get('smtpPort');
|
||||
|
||||
if (!$host) {
|
||||
throw new NoSmtp("No system SMTP settings.");
|
||||
}
|
||||
|
||||
if (!$port) {
|
||||
throw new NoSmtp("No system SMTP port.");
|
||||
}
|
||||
|
||||
$params = SmtpParams::create($host, $port)
|
||||
->withSecurity($this->config->get('smtpSecurity'))
|
||||
->withAuth($this->config->get('smtpAuth'));
|
||||
|
||||
if ($params->useAuth()) {
|
||||
$password = $this->config->get('smtpPassword');
|
||||
|
||||
$params = $params
|
||||
->withUsername($this->config->get('smtpUsername'))
|
||||
->withPassword($password)
|
||||
->withAuthMechanism($this->config->get('smtpAuthMechanism') ?? 'login');
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function getImapParams(): ?ImapParams
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -31,10 +31,16 @@ namespace Espo\Core\Upgrades\Migrations\V9_1;
|
||||
|
||||
use Espo\Core\ORM\Repository\Option\SaveOption;
|
||||
use Espo\Core\Upgrades\Migration\Script;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Core\Utils\Crypt;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use Espo\Core\Utils\ObjectUtil;
|
||||
use Espo\Core\Utils\SystemUser;
|
||||
use Espo\Entities\InboundEmail;
|
||||
use Espo\Modules\Crm\Entities\KnowledgeBaseArticle;
|
||||
use Espo\ORM\EntityManager;
|
||||
use Espo\ORM\Query\Part\Condition;
|
||||
use Espo\ORM\Query\Part\Expression;
|
||||
use Espo\Tools\Email\Util;
|
||||
use stdClass;
|
||||
|
||||
@@ -43,12 +49,17 @@ class AfterUpgrade implements Script
|
||||
public function __construct(
|
||||
private EntityManager $entityManager,
|
||||
private Metadata $metadata,
|
||||
private Config $config,
|
||||
private Config\ConfigWriter $configWriter,
|
||||
private Crypt $crypt,
|
||||
private SystemUser $systemUser,
|
||||
) {}
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->processKbArticles();
|
||||
$this->processDynamicLogicMetadata();
|
||||
$this->processGroupEmailAccount();
|
||||
}
|
||||
|
||||
private function processKbArticles(): void
|
||||
@@ -104,4 +115,66 @@ class AfterUpgrade implements Script
|
||||
$this->metadata->saveCustom('clientDefs', $scope, $customClientDefs);
|
||||
}
|
||||
}
|
||||
|
||||
private function processGroupEmailAccount(): void
|
||||
{
|
||||
if (!$this->config->get('smtpServer')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$outboundEmailFromAddress = $this->config->get('outboundEmailFromAddress');
|
||||
|
||||
if (!$outboundEmailFromAddress) {
|
||||
return;
|
||||
}
|
||||
|
||||
$groupAccount = $this->entityManager
|
||||
->getRDBRepositoryByClass(InboundEmail::class)
|
||||
->where([
|
||||
'status' => InboundEmail::STATUS_ACTIVE,
|
||||
'useSmtp' => true,
|
||||
])
|
||||
->where(
|
||||
Condition::equal(
|
||||
Expression::lowerCase(
|
||||
Expression::column('emailAddress')
|
||||
),
|
||||
strtolower($outboundEmailFromAddress)
|
||||
)
|
||||
)
|
||||
->findOne();
|
||||
|
||||
$this->configWriter->set('smtpServer', null);
|
||||
|
||||
if ($groupAccount) {
|
||||
$this->configWriter->save();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$password = $this->config->get('smtpPassword');
|
||||
|
||||
$groupAccount = $this->entityManager->getRDBRepositoryByClass(InboundEmail::class)->getNew();
|
||||
|
||||
$groupAccount->setMultiple([
|
||||
'emailAddress' => $outboundEmailFromAddress,
|
||||
'name' => $outboundEmailFromAddress . ' (system)',
|
||||
'useImap' => false,
|
||||
'useSmtp' => true,
|
||||
'smtpHost' => $this->config->get('smtpServer'),
|
||||
'smtpPort' => $this->config->get('smtpPort'),
|
||||
'smtpAuth' => $this->config->get('smtpAuth'),
|
||||
'smtpAuthMechanism' => $this->config->get('smtpAuthMechanism') ?? 'login',
|
||||
'fromName' => $this->config->get('outboundEmailFromName'),
|
||||
'smtpUsername' => $this->config->get('smtpUsername'),
|
||||
'smtpPassword' => $password !== null ? $this->crypt->encrypt($password) : null,
|
||||
]);
|
||||
|
||||
$this->entityManager->saveEntity($groupAccount, [
|
||||
SaveOption::SKIP_HOOKS => true,
|
||||
SaveOption::CREATED_BY_ID => $this->systemUser->getId(),
|
||||
]);
|
||||
|
||||
$this->configWriter->save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,15 +15,9 @@
|
||||
"companyLogo": "Company Logo",
|
||||
"smsProvider": "SMS Provider",
|
||||
"outboundSmsFromNumber": "SMS From Number",
|
||||
"smtpServer": "Server",
|
||||
"smtpPort": "Port",
|
||||
"smtpAuth": "Auth",
|
||||
"smtpSecurity": "Security",
|
||||
"smtpUsername": "Username",
|
||||
"emailAddress": "Email",
|
||||
"smtpPassword": "Password",
|
||||
"outboundEmailFromName": "From Name",
|
||||
"outboundEmailFromAddress": "From Address",
|
||||
"outboundEmailFromAddress": "System Email Address",
|
||||
"outboundEmailIsShared": "Is Shared",
|
||||
"emailAddressLookupEntityTypeList": "Email address look-up scopes",
|
||||
"emailAddressSelectEntityTypeList": "Email address select scopes",
|
||||
@@ -230,8 +224,7 @@
|
||||
"emailAddressLookupEntityTypeList": "For email address autocomplete.",
|
||||
"emailAddressSelectEntityTypeList": "Entity types available when searching for an email address from a modal.",
|
||||
"emailNotificationsDelay": "A message can be edited within the specified timeframe before the notification is sent.",
|
||||
"outboundEmailFromAddress": "The system email address.",
|
||||
"smtpServer": "If empty, then Group Email Account with the corresponding email address will be used.",
|
||||
"outboundEmailFromAddress": "System emails will be sent from this email address. A [group email account](#InboundEmail) with the same email address must be set up and properly configured to send emails.",
|
||||
"busyRangesEntityList": "What will be taken into account when showing busy time ranges in scheduler & timeline.",
|
||||
"massEmailVerp": "Variable envelope return path. For better handling of bounced messages. Make sure that your SMTP provider supports it.",
|
||||
"recordsPerPage": "Number of records initially displayed in list views.",
|
||||
|
||||
@@ -8,15 +8,6 @@
|
||||
[false, {"name": "emailAddressSelectEntityTypeList"}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "SMTP",
|
||||
"rows": [
|
||||
[{"name": "smtpServer"}, {"name": "smtpPort"}],
|
||||
[{"name": "smtpAuth"}, {"name": "smtpSecurity"}],
|
||||
[{"name": "smtpUsername"}, {"name": "testSend", "customLabel": null, "view": "views/outbound-email/fields/test-send"}],
|
||||
[{"name": "smtpPassword"}, false]
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Mass Email",
|
||||
"rows": [
|
||||
|
||||
@@ -26,9 +26,26 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import TestSendView from 'views/outbound-email/fields/test-send';
|
||||
import BaseFieldView from 'views/fields/base';
|
||||
|
||||
export default class extends TestSendView {
|
||||
export default class EmailAccountTestSendFieldView extends BaseFieldView {
|
||||
|
||||
templateContent = `
|
||||
<button
|
||||
class="btn btn-default hidden"
|
||||
data-action="sendTestEmail"
|
||||
>{{translate 'Send Test Email' scope='Email'}}</button>
|
||||
`
|
||||
|
||||
setup() {
|
||||
super.setup();
|
||||
|
||||
this.addActionHandler('sendTestEmail', () => this.send());
|
||||
}
|
||||
|
||||
fetch() {
|
||||
return {};
|
||||
}
|
||||
|
||||
checkAvailability() {
|
||||
if (this.model.get('smtpHost')) {
|
||||
@@ -48,6 +65,96 @@ export default class extends TestSendView {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
enableButton() {
|
||||
this.$el.find('button').removeClass('disabled').removeAttr('disabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
disabledButton() {
|
||||
this.$el.find('button').addClass('disabled').attr('disabled', 'disabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
send() {
|
||||
const data = this.getSmtpData();
|
||||
|
||||
this.createView('popup', 'views/outbound-email/modals/test-send', {
|
||||
emailAddress: this.getUser().get('emailAddress'),
|
||||
}).then(view => {
|
||||
view.render();
|
||||
|
||||
this.listenToOnce(view, 'send', (emailAddress) => {
|
||||
this.disabledButton();
|
||||
|
||||
data.emailAddress = emailAddress;
|
||||
|
||||
Espo.Ui.notify(this.translate('Sending...'));
|
||||
|
||||
view.close();
|
||||
|
||||
Espo.Ajax.postRequest('Email/sendTest', data)
|
||||
.then(() => {
|
||||
this.enableButton();
|
||||
|
||||
Espo.Ui.success(this.translate('testEmailSent', 'messages', 'Email'));
|
||||
})
|
||||
.catch(xhr => {
|
||||
let reason = xhr.getResponseHeader('X-Status-Reason') || '';
|
||||
|
||||
reason = reason
|
||||
.replace(/ $/, '')
|
||||
.replace(/,$/, '');
|
||||
|
||||
let msg = this.translate('Error');
|
||||
|
||||
if (xhr.status !== 200) {
|
||||
msg += ' ' + xhr.status;
|
||||
}
|
||||
|
||||
if (xhr.responseText) {
|
||||
try {
|
||||
const data = /** @type {Record} */JSON.parse(xhr.responseText);
|
||||
|
||||
if (data.messageTranslation) {
|
||||
this.enableButton();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
reason = data.message || reason;
|
||||
}
|
||||
catch (e) {
|
||||
this.enableButton();
|
||||
|
||||
console.error('Could not parse error response body.');
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (reason) {
|
||||
msg += ': ' + reason;
|
||||
}
|
||||
|
||||
Espo.Ui.error(msg, true);
|
||||
console.error(msg);
|
||||
|
||||
xhr.errorIsHandled = true;
|
||||
|
||||
this.enableButton();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getSmtpData() {
|
||||
return {
|
||||
'server': this.model.get('smtpHost'),
|
||||
|
||||
@@ -1,175 +0,0 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2025 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://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 Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import BaseFieldView from 'views/fields/base';
|
||||
|
||||
export default class extends BaseFieldView {
|
||||
|
||||
templateContent =
|
||||
'<button class="btn btn-default hidden" data-action="sendTestEmail">'+
|
||||
'{{translate \'Send Test Email\' scope=\'Email\'}}</button>'
|
||||
|
||||
setup() {
|
||||
super.setup();
|
||||
|
||||
this.addActionHandler('sendTestEmail', () => this.send());
|
||||
}
|
||||
|
||||
fetch() {
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
checkAvailability() {
|
||||
if (this.model.get('smtpServer')) {
|
||||
this.$el.find('button').removeClass('hidden');
|
||||
} else {
|
||||
this.$el.find('button').addClass('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
afterRender() {
|
||||
this.checkAvailability();
|
||||
|
||||
this.stopListening(this.model, 'change:smtpServer');
|
||||
|
||||
this.listenTo(this.model, 'change:smtpServer', () => {
|
||||
this.checkAvailability();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @return {Record}
|
||||
*/
|
||||
getSmtpData() {
|
||||
return {
|
||||
'server': this.model.get('smtpServer'),
|
||||
'port': this.model.get('smtpPort'),
|
||||
'auth': this.model.get('smtpAuth'),
|
||||
'security': this.model.get('smtpSecurity'),
|
||||
'username': this.model.get('smtpUsername'),
|
||||
'password': this.model.get('smtpPassword') || null,
|
||||
'fromName': this.model.get('outboundEmailFromName'),
|
||||
'fromAddress': this.model.get('outboundEmailFromAddress'),
|
||||
'type': 'outboundEmail',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
enableButton() {
|
||||
this.$el.find('button').removeClass('disabled').removeAttr('disabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
disabledButton() {
|
||||
this.$el.find('button').addClass('disabled').attr('disabled', 'disabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
send() {
|
||||
const data = this.getSmtpData();
|
||||
|
||||
this.createView('popup', 'views/outbound-email/modals/test-send', {
|
||||
emailAddress: this.getUser().get('emailAddress')
|
||||
}, (view) => {
|
||||
view.render();
|
||||
|
||||
this.listenToOnce(view, 'send', (emailAddress) => {
|
||||
this.disabledButton();
|
||||
|
||||
data.emailAddress = emailAddress;
|
||||
|
||||
this.notify('Sending...');
|
||||
|
||||
view.close();
|
||||
|
||||
Espo.Ajax.postRequest('Email/sendTest', data)
|
||||
.then(() => {
|
||||
this.enableButton();
|
||||
|
||||
Espo.Ui.success(this.translate('testEmailSent', 'messages', 'Email'));
|
||||
})
|
||||
.catch(xhr => {
|
||||
let reason = xhr.getResponseHeader('X-Status-Reason') || '';
|
||||
|
||||
reason = reason
|
||||
.replace(/ $/, '')
|
||||
.replace(/,$/, '');
|
||||
|
||||
let msg = this.translate('Error');
|
||||
|
||||
if (xhr.status !== 200) {
|
||||
msg += ' ' + xhr.status;
|
||||
}
|
||||
|
||||
if (xhr.responseText) {
|
||||
try {
|
||||
const data = /** @type {Record} */JSON.parse(xhr.responseText);
|
||||
|
||||
if (data.messageTranslation) {
|
||||
this.enableButton();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
reason = data.message || reason;
|
||||
}
|
||||
catch (e) {
|
||||
this.enableButton();
|
||||
|
||||
console.error('Could not parse error response body.');
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (reason) {
|
||||
msg += ': ' + reason;
|
||||
}
|
||||
|
||||
Espo.Ui.error(msg, true);
|
||||
console.error(msg);
|
||||
|
||||
xhr.errorIsHandled = true;
|
||||
|
||||
this.enableButton();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ return array (
|
||||
'removeOption' => 'Test',
|
||||
'testOption' => 'Another Wrong Value',
|
||||
'testOption2' => 'Test2',
|
||||
'database' =>
|
||||
'database' =>
|
||||
array (
|
||||
'driver' => 'pdo_mysql',
|
||||
'host' => 'localhost',
|
||||
@@ -24,16 +24,16 @@ return array (
|
||||
'weekStart' => 1,
|
||||
'thousandSeparator' => ',',
|
||||
'decimalMark' => '.',
|
||||
'currencyList' =>
|
||||
'currencyList' =>
|
||||
array (
|
||||
0 => 'USD',
|
||||
1 => 'EUR',
|
||||
),
|
||||
'defaultCurrency' => 'USD',
|
||||
'currency' =>
|
||||
'currency' =>
|
||||
array (
|
||||
'base' => 'USD',
|
||||
'rate' =>
|
||||
'rate' =>
|
||||
array (
|
||||
'EUR' => '1.37',
|
||||
),
|
||||
@@ -41,38 +41,32 @@ return array (
|
||||
'outboundEmailIsShared' => true,
|
||||
'outboundEmailFromName' => 'EspoCRM',
|
||||
'outboundEmailFromAddress' => '',
|
||||
'smtpServer' => '',
|
||||
'smtpPort' => 25,
|
||||
'smtpAuth' => true,
|
||||
'smtpSecurity' => '',
|
||||
'smtpUsername' => '',
|
||||
'smtpPassword' => '',
|
||||
'languageList' =>
|
||||
'languageList' =>
|
||||
array (
|
||||
0 => 'en_US',
|
||||
),
|
||||
'language' => 'en_US',
|
||||
'logger' =>
|
||||
'logger' =>
|
||||
array (
|
||||
'path' => 'data/logs/espo.log',
|
||||
'level' => 'INFO',
|
||||
'isRotate' => true,
|
||||
'maxRotateFiles' => 5,
|
||||
),
|
||||
'defaultPermissions' =>
|
||||
'defaultPermissions' =>
|
||||
array (
|
||||
'dir' => '0775',
|
||||
'file' => '0664',
|
||||
'user' => '',
|
||||
'group' => '',
|
||||
),
|
||||
'cron' =>
|
||||
'cron' =>
|
||||
array (
|
||||
'maxJobNumber' => 15,
|
||||
'jobPeriod' => 7800,
|
||||
'minExecutionTime' => 50,
|
||||
),
|
||||
'globalSearchEntityList' =>
|
||||
'globalSearchEntityList' =>
|
||||
array (
|
||||
0 => 'Account',
|
||||
1 => 'Contact',
|
||||
@@ -80,7 +74,7 @@ return array (
|
||||
3 => 'Prospect',
|
||||
4 => 'Opportunity',
|
||||
),
|
||||
'tabList' =>
|
||||
'tabList' =>
|
||||
array (
|
||||
0 => 'Contact',
|
||||
1 => 'Account',
|
||||
@@ -93,7 +87,7 @@ return array (
|
||||
8 => 'Case',
|
||||
9 => 'Prospect',
|
||||
),
|
||||
'quickCreateList' =>
|
||||
'quickCreateList' =>
|
||||
array (
|
||||
0 => 'Account',
|
||||
1 => 'Contact',
|
||||
@@ -108,4 +102,4 @@ return array (
|
||||
'isInstalled' => true,
|
||||
);
|
||||
|
||||
?>
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user