mirror of
https://github.com/espocrm/espocrm.git
synced 2026-06-28 06:56:05 +00:00
address country list
This commit is contained in:
48
application/Espo/Classes/AppParams/AddressCountryData.php
Normal file
48
application/Espo/Classes/AppParams/AddressCountryData.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2024 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\Classes\AppParams;
|
||||
|
||||
use Espo\Core\Utils\Address\CountryDataProvider;
|
||||
use Espo\Tools\App\AppParam;
|
||||
|
||||
class AddressCountryData implements AppParam
|
||||
{
|
||||
public function __construct(
|
||||
private CountryDataProvider $provider
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @return array{list: string[], preferredList: string[]}
|
||||
*/
|
||||
public function get(): array
|
||||
{
|
||||
return $this->provider->get();
|
||||
}
|
||||
}
|
||||
56
application/Espo/Classes/FieldSanitizers/StringUpperCase.php
Normal file
56
application/Espo/Classes/FieldSanitizers/StringUpperCase.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2024 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\Classes\FieldSanitizers;
|
||||
|
||||
use Espo\Core\FieldSanitize\Sanitizer;
|
||||
use Espo\Core\FieldSanitize\Sanitizer\Data;
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
class StringUpperCase implements Sanitizer
|
||||
{
|
||||
public function sanitize(Data $data, string $field): void
|
||||
{
|
||||
if (!$data->has($field)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$value = $data->get($field);
|
||||
|
||||
if (!is_string($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$value = mb_strtoupper($value);
|
||||
|
||||
$data->set($field, $value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2024 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\Classes\Select\AddressCountry;
|
||||
|
||||
use Espo\Core\Select\Order\Item;
|
||||
use Espo\Core\Select\Order\Orderer;
|
||||
use Espo\ORM\Query\Part\Order;
|
||||
use Espo\ORM\Query\SelectBuilder;
|
||||
|
||||
class PreferredNameOrderer implements Orderer
|
||||
{
|
||||
public function apply(SelectBuilder $queryBuilder, Item $item): void
|
||||
{
|
||||
$queryBuilder
|
||||
->order('isPreferred', $item->getOrder() === Order::ASC ? Order::DESC : Order::ASC)
|
||||
->order('name', $item->getOrder());
|
||||
}
|
||||
}
|
||||
50
application/Espo/Controllers/AddressCountry.php
Normal file
50
application/Espo/Controllers/AddressCountry.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2024 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\Controllers;
|
||||
|
||||
use Espo\Core\Controllers\RecordBase;
|
||||
use Espo\Tools\Address\CountryDefaultsPopulator;
|
||||
|
||||
class AddressCountry extends RecordBase
|
||||
{
|
||||
protected function checkAccess(): bool
|
||||
{
|
||||
return $this->user->isAdmin();
|
||||
}
|
||||
|
||||
public function postActionPopulateDefaults(): bool
|
||||
{
|
||||
$populate = $this->injectableFactory->create(CountryDefaultsPopulator::class);
|
||||
|
||||
$populate->populate();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
117
application/Espo/Core/Utils/Address/CountryDataProvider.php
Normal file
117
application/Espo/Core/Utils/Address/CountryDataProvider.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2024 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\Utils\Address;
|
||||
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Core\Utils\DataCache;
|
||||
use Espo\Entities\AddressCountry;
|
||||
use Espo\ORM\EntityManager;
|
||||
use Espo\ORM\Query\Part\Order;
|
||||
|
||||
class CountryDataProvider
|
||||
{
|
||||
/** @var ?array{list: string[], preferredList: string[]} */
|
||||
private ?array $data = null;
|
||||
private bool $useCache;
|
||||
|
||||
private const CACHE_KEY = 'addressCountryData';
|
||||
private const LIMIT = 500;
|
||||
|
||||
public function __construct(
|
||||
private DataCache $dataCache,
|
||||
private Config $config,
|
||||
private EntityManager $entityManager
|
||||
) {
|
||||
$this->useCache = (bool) $this->config->get('useCache');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{list: string[], preferredList: string[]}
|
||||
*/
|
||||
public function get(): array
|
||||
{
|
||||
if ($this->data === null) {
|
||||
$this->data = $this->load();
|
||||
}
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{list: string[], preferredList: string[]}
|
||||
*/
|
||||
private function load(): array
|
||||
{
|
||||
if ($this->useCache && $this->dataCache->has(self::CACHE_KEY)) {
|
||||
$list = $this->dataCache->get(self::CACHE_KEY);
|
||||
|
||||
if (
|
||||
is_array($list) ||
|
||||
is_array($list['list'] ?? null) ||
|
||||
is_array($list['preferredList'] ?? null)
|
||||
) {
|
||||
/** @var array{list: string[], preferredList: string[]} */
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
|
||||
$list = [];
|
||||
$preferredList = [];
|
||||
|
||||
/** @var iterable<AddressCountry> $collection */
|
||||
$collection = $this->entityManager
|
||||
->getRDBRepositoryByClass(AddressCountry::class)
|
||||
->sth()
|
||||
->select(['name', 'isPreferred'])
|
||||
->order('name', Order::ASC)
|
||||
->limit(0, self::LIMIT)
|
||||
->find();
|
||||
|
||||
foreach ($collection as $entity) {
|
||||
$list[] = $entity->getName();
|
||||
|
||||
if ($entity->isPreferred()) {
|
||||
$preferredList[] = $entity->getName();
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->useCache) {
|
||||
$this->dataCache->store(self::CACHE_KEY, [
|
||||
'list' => $list,
|
||||
'preferredList' => $preferredList,
|
||||
]);
|
||||
}
|
||||
|
||||
return [
|
||||
'list' => $list,
|
||||
'preferredList' => $preferredList,
|
||||
];
|
||||
}
|
||||
}
|
||||
52
application/Espo/Entities/AddressCountry.php
Normal file
52
application/Espo/Entities/AddressCountry.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2024 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\Entities;
|
||||
|
||||
use Espo\Core\ORM\Entity;
|
||||
|
||||
class AddressCountry extends Entity
|
||||
{
|
||||
public const ENTITY_TYPE = 'AddressCountry';
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->get('name');
|
||||
}
|
||||
|
||||
public function getCode(): string
|
||||
{
|
||||
return $this->get('code');
|
||||
}
|
||||
|
||||
public function isPreferred(): bool
|
||||
{
|
||||
return (bool) $this->get('isPreferred');
|
||||
}
|
||||
}
|
||||
61
application/Espo/Hooks/AddressCountry/ClearCache.php
Normal file
61
application/Espo/Hooks/AddressCountry/ClearCache.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2024 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\Hooks\AddressCountry;
|
||||
|
||||
use Espo\Core\Hook\Hook\AfterRemove;
|
||||
use Espo\Core\Hook\Hook\AfterSave;
|
||||
use Espo\Core\Utils\DataCache;
|
||||
use Espo\Entities\AddressCountry;
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\ORM\Repository\Option\RemoveOptions;
|
||||
use Espo\ORM\Repository\Option\SaveOptions;
|
||||
|
||||
/**
|
||||
* @implements AfterRemove<AddressCountry>
|
||||
* @implements AfterSave<AddressCountry>
|
||||
*/
|
||||
class ClearCache implements AfterRemove, AfterSave
|
||||
{
|
||||
private const CACHE_KEY = 'addressCountryData';
|
||||
|
||||
public function __construct(
|
||||
private DataCache $dataCache,
|
||||
) {}
|
||||
|
||||
public function afterSave(Entity $entity, SaveOptions $options): void
|
||||
{
|
||||
$this->dataCache->clear(self::CACHE_KEY);
|
||||
}
|
||||
|
||||
public function afterRemove(Entity $entity, RemoveOptions $options): void
|
||||
{
|
||||
$this->dataCache->clear(self::CACHE_KEY);
|
||||
}
|
||||
}
|
||||
1006
application/Espo/Resources/data/locale/en_US/countryList.json
Normal file
1006
application/Espo/Resources/data/locale/en_US/countryList.json
Normal file
File diff suppressed because it is too large
Load Diff
20
application/Espo/Resources/i18n/en_US/AddressCountry.json
Normal file
20
application/Espo/Resources/i18n/en_US/AddressCountry.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create AddressCountry": "Create Address Country",
|
||||
"Populate": "Populate"
|
||||
},
|
||||
"fields": {
|
||||
"code": "Code",
|
||||
"isPreferred": "Is Preferred"
|
||||
},
|
||||
"tooltips": {
|
||||
"code": "ISO 3166-1 alpha-2 code.",
|
||||
"isPreferred": "Preferred counties appear first in the picklist."
|
||||
},
|
||||
"messages": {
|
||||
"confirmPopulateDefaults": "All existing countries will be deleted, the default country list will be created. It won't be possible to revert the operation.\n\nAre you sure?"
|
||||
},
|
||||
"strings": {
|
||||
"populateDefaults": "Populate with default country list"
|
||||
}
|
||||
}
|
||||
@@ -80,6 +80,7 @@
|
||||
"Working Time Calendars": "Working Time Calendars",
|
||||
"Group Email Folders": "Group Email Folders",
|
||||
"Authentication Providers": "Authentication Providers",
|
||||
"Address Countries": "Address Countries",
|
||||
"Success": "Success",
|
||||
"Fail": "Fail",
|
||||
"Configuration Instructions": "Configuration Instructions",
|
||||
@@ -309,7 +310,8 @@
|
||||
"jobsSettings": "Job processing settings. Jobs execute tasks in the background.",
|
||||
"sms": "SMS settings.",
|
||||
"pdfTemplates": "Templates for printing to PDF.",
|
||||
"formulaSandbox": "Write and test formula scripts."
|
||||
"formulaSandbox": "Write and test formula scripts.",
|
||||
"addressCountries": "Countries available for address fields."
|
||||
},
|
||||
"keywords": {
|
||||
"settings": "system",
|
||||
|
||||
@@ -62,7 +62,8 @@
|
||||
"WorkingTimeCalendar": "Working Time Calendar",
|
||||
"WorkingTimeRange": "Working Time Exception",
|
||||
"AuthenticationProvider": "Authentication Provider",
|
||||
"GlobalStream": "Global Stream"
|
||||
"GlobalStream": "Global Stream",
|
||||
"AddressCountry": "Address Country"
|
||||
},
|
||||
"scopeNamesPlural": {
|
||||
"Note": "Notes",
|
||||
@@ -115,7 +116,8 @@
|
||||
"WorkingTimeCalendar": "Working Time Calendars",
|
||||
"WorkingTimeRange": "Working Time Exceptions",
|
||||
"AuthenticationProvider": "Authentication Providers",
|
||||
"GlobalStream": "Global Stream"
|
||||
"GlobalStream": "Global Stream",
|
||||
"AddressCountry": "Address Countries"
|
||||
},
|
||||
"labels": {
|
||||
"Previous Page": "Previous Page",
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"rows": [
|
||||
[
|
||||
{"name": "name"},
|
||||
{"name": "code"}
|
||||
],
|
||||
[
|
||||
{"name": "isPreferred"},
|
||||
false
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"rows": [
|
||||
[
|
||||
{"name": "name"},
|
||||
{"name": "code"}
|
||||
],
|
||||
[
|
||||
{"name": "isPreferred"},
|
||||
false
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,4 @@
|
||||
[
|
||||
"code",
|
||||
"isPreferred"
|
||||
]
|
||||
@@ -0,0 +1,5 @@
|
||||
[
|
||||
{"name": "name", "link": true},
|
||||
{"name": "code", "width": 20},
|
||||
{"name": "isPreferred", "width": 15}
|
||||
]
|
||||
@@ -0,0 +1,3 @@
|
||||
[
|
||||
"isPreferred"
|
||||
]
|
||||
@@ -290,6 +290,12 @@
|
||||
"iconClass": "fas fa-share-alt icon-rotate-90",
|
||||
"description": "webhooks"
|
||||
},
|
||||
{
|
||||
"url": "#Admin/addressCountries",
|
||||
"label": "Address Countries",
|
||||
"iconClass": "far fa-flag",
|
||||
"description": "addressCountries"
|
||||
},
|
||||
{
|
||||
"url": "#Admin/authenticationProviders",
|
||||
"label": "Authentication Providers",
|
||||
|
||||
@@ -4,5 +4,8 @@
|
||||
},
|
||||
"extensions": {
|
||||
"className": "Espo\\Classes\\AppParams\\Extensions"
|
||||
},
|
||||
"addressCountryData": {
|
||||
"className": "Espo\\Classes\\AppParams\\AddressCountryData"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"controller": "controllers/record",
|
||||
"duplicateDisabled": true,
|
||||
"mergeDisabled": true,
|
||||
"menu": {
|
||||
"list": {
|
||||
"dropdown": [
|
||||
{
|
||||
"name": "populateDefaults",
|
||||
"labelTranslation": "AddressCountry.strings.populateDefaults",
|
||||
"handler": "handlers/admin/address-country/populate-defaults",
|
||||
"actionFunction": "populate"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,293 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": {
|
||||
"type": "varchar",
|
||||
"required": true,
|
||||
"maxLength": 100
|
||||
},
|
||||
"code": {
|
||||
"type": "varchar",
|
||||
"required": true,
|
||||
"maxLength": 2,
|
||||
"tooltip": true,
|
||||
"pattern": "[A-Z]{2}",
|
||||
"sanitizerClassNameList": [
|
||||
"Espo\\Classes\\FieldSanitizers\\StringUpperCase"
|
||||
],
|
||||
"options": [
|
||||
"AF",
|
||||
"AX",
|
||||
"AL",
|
||||
"DZ",
|
||||
"AS",
|
||||
"AD",
|
||||
"AO",
|
||||
"AI",
|
||||
"AQ",
|
||||
"AG",
|
||||
"AR",
|
||||
"AM",
|
||||
"AW",
|
||||
"AU",
|
||||
"AT",
|
||||
"AZ",
|
||||
"BS",
|
||||
"BH",
|
||||
"BD",
|
||||
"BB",
|
||||
"BY",
|
||||
"BE",
|
||||
"BZ",
|
||||
"BJ",
|
||||
"BM",
|
||||
"BT",
|
||||
"BO",
|
||||
"BA",
|
||||
"BW",
|
||||
"BV",
|
||||
"BR",
|
||||
"IO",
|
||||
"BN",
|
||||
"BG",
|
||||
"BF",
|
||||
"BI",
|
||||
"KH",
|
||||
"CM",
|
||||
"CA",
|
||||
"CV",
|
||||
"KY",
|
||||
"CF",
|
||||
"TD",
|
||||
"CL",
|
||||
"CN",
|
||||
"CX",
|
||||
"CC",
|
||||
"CO",
|
||||
"KM",
|
||||
"CG",
|
||||
"CD",
|
||||
"CK",
|
||||
"CR",
|
||||
"CI",
|
||||
"HR",
|
||||
"CU",
|
||||
"CY",
|
||||
"CZ",
|
||||
"DK",
|
||||
"DJ",
|
||||
"DM",
|
||||
"DO",
|
||||
"EC",
|
||||
"EG",
|
||||
"SV",
|
||||
"GQ",
|
||||
"ER",
|
||||
"EE",
|
||||
"ET",
|
||||
"FK",
|
||||
"FO",
|
||||
"FJ",
|
||||
"FI",
|
||||
"FR",
|
||||
"GF",
|
||||
"PF",
|
||||
"TF",
|
||||
"GA",
|
||||
"GM",
|
||||
"GE",
|
||||
"DE",
|
||||
"GH",
|
||||
"GI",
|
||||
"GR",
|
||||
"GL",
|
||||
"GD",
|
||||
"GP",
|
||||
"GU",
|
||||
"GT",
|
||||
"GG",
|
||||
"GN",
|
||||
"GW",
|
||||
"GY",
|
||||
"HT",
|
||||
"HM",
|
||||
"VA",
|
||||
"HN",
|
||||
"HK",
|
||||
"HU",
|
||||
"IS",
|
||||
"IN",
|
||||
"ID",
|
||||
"IR",
|
||||
"IQ",
|
||||
"IE",
|
||||
"IM",
|
||||
"IL",
|
||||
"IT",
|
||||
"JM",
|
||||
"JP",
|
||||
"JE",
|
||||
"JO",
|
||||
"KZ",
|
||||
"KE",
|
||||
"KI",
|
||||
"KR",
|
||||
"KW",
|
||||
"KG",
|
||||
"LA",
|
||||
"LV",
|
||||
"LB",
|
||||
"LS",
|
||||
"LR",
|
||||
"LY",
|
||||
"LI",
|
||||
"LT",
|
||||
"LU",
|
||||
"MO",
|
||||
"MK",
|
||||
"MG",
|
||||
"MW",
|
||||
"MY",
|
||||
"MV",
|
||||
"ML",
|
||||
"MT",
|
||||
"MH",
|
||||
"MQ",
|
||||
"MR",
|
||||
"MU",
|
||||
"YT",
|
||||
"MX",
|
||||
"FM",
|
||||
"MD",
|
||||
"MC",
|
||||
"MN",
|
||||
"ME",
|
||||
"MS",
|
||||
"MA",
|
||||
"MZ",
|
||||
"MM",
|
||||
"NA",
|
||||
"NR",
|
||||
"NP",
|
||||
"NL",
|
||||
"AN",
|
||||
"NC",
|
||||
"NZ",
|
||||
"NI",
|
||||
"NE",
|
||||
"NG",
|
||||
"NU",
|
||||
"NF",
|
||||
"MP",
|
||||
"NO",
|
||||
"OM",
|
||||
"PK",
|
||||
"PW",
|
||||
"PS",
|
||||
"PA",
|
||||
"PG",
|
||||
"PY",
|
||||
"PE",
|
||||
"PH",
|
||||
"PN",
|
||||
"PL",
|
||||
"PT",
|
||||
"PR",
|
||||
"QA",
|
||||
"RE",
|
||||
"RO",
|
||||
"RU",
|
||||
"RW",
|
||||
"BL",
|
||||
"SH",
|
||||
"KN",
|
||||
"LC",
|
||||
"MF",
|
||||
"PM",
|
||||
"VC",
|
||||
"WS",
|
||||
"SM",
|
||||
"ST",
|
||||
"SA",
|
||||
"SN",
|
||||
"RS",
|
||||
"SC",
|
||||
"SL",
|
||||
"SG",
|
||||
"SK",
|
||||
"SI",
|
||||
"SB",
|
||||
"SO",
|
||||
"ZA",
|
||||
"GS",
|
||||
"ES",
|
||||
"LK",
|
||||
"SD",
|
||||
"SR",
|
||||
"SJ",
|
||||
"SZ",
|
||||
"SE",
|
||||
"CH",
|
||||
"SY",
|
||||
"TW",
|
||||
"TJ",
|
||||
"TZ",
|
||||
"TH",
|
||||
"TL",
|
||||
"TG",
|
||||
"TK",
|
||||
"TO",
|
||||
"TT",
|
||||
"TN",
|
||||
"TR",
|
||||
"TM",
|
||||
"TC",
|
||||
"TV",
|
||||
"UG",
|
||||
"UA",
|
||||
"AE",
|
||||
"GB",
|
||||
"US",
|
||||
"UM",
|
||||
"UY",
|
||||
"UZ",
|
||||
"VU",
|
||||
"VE",
|
||||
"VN",
|
||||
"VG",
|
||||
"VI",
|
||||
"WF",
|
||||
"EH",
|
||||
"YE",
|
||||
"ZM",
|
||||
"ZW"
|
||||
]
|
||||
},
|
||||
"isPreferred": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
},
|
||||
"preferredName": {
|
||||
"type": "base",
|
||||
"notStorable": true,
|
||||
"utility": true
|
||||
}
|
||||
},
|
||||
"links": {},
|
||||
"collection": {
|
||||
"orderBy": "preferredName",
|
||||
"order": "asc",
|
||||
"textFilterFields": [
|
||||
"name",
|
||||
"code"
|
||||
]
|
||||
},
|
||||
"indexes": {
|
||||
"name": {
|
||||
"unique": true,
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"noDeletedAttribute": true
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"duplicateWhereBuilderClassName": "Espo\\Classes\\DuplicateWhereBuilders\\General",
|
||||
"massActions": {
|
||||
"delete": {
|
||||
"allowed": true
|
||||
},
|
||||
"update": {
|
||||
"allowed": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"entity": true,
|
||||
"importable": true,
|
||||
"exportFormatList": ["csv"],
|
||||
"duplicateCheckFieldList": [
|
||||
"name",
|
||||
"code"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"ordererClassNameMap": {
|
||||
"preferredName": "Espo\\Classes\\Select\\AddressCountry\\PreferredNameOrderer"
|
||||
}
|
||||
}
|
||||
105
application/Espo/Tools/Address/CountryDefaultsPopulator.php
Normal file
105
application/Espo/Tools/Address/CountryDefaultsPopulator.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2024 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\Tools\Address;
|
||||
|
||||
use Espo\Core\Utils\DataCache;
|
||||
use Espo\Core\Utils\File\Manager;
|
||||
use Espo\Core\Utils\Id\RecordIdGenerator;
|
||||
use Espo\Core\Utils\Json;
|
||||
use Espo\Entities\AddressCountry;
|
||||
use Espo\ORM\EntityManager;
|
||||
use Espo\ORM\Query\DeleteBuilder;
|
||||
use RuntimeException;
|
||||
|
||||
class CountryDefaultsPopulator
|
||||
{
|
||||
private string $file = 'application/Espo/Resources/data/locale/en_US/countryList.json';
|
||||
|
||||
private const CACHE_KEY = 'addressCountryData';
|
||||
|
||||
public function __construct(
|
||||
private Manager $fileManager,
|
||||
private EntityManager $entityManager,
|
||||
private DataCache $dataCache,
|
||||
private RecordIdGenerator $recordIdGenerator
|
||||
) {}
|
||||
|
||||
public function populate(): void
|
||||
{
|
||||
if (!$this->fileManager->exists($this->file)) {
|
||||
throw new RuntimeException("No file '$this->file'.");
|
||||
}
|
||||
|
||||
$contents = $this->fileManager->getContents($this->file);
|
||||
|
||||
$dataList = Json::decode($contents, true);
|
||||
|
||||
if (!is_array($dataList)) {
|
||||
throw new RuntimeException("Bad data.");
|
||||
}
|
||||
|
||||
$collection = $this->entityManager->getCollectionFactory()->create(AddressCountry::ENTITY_TYPE);
|
||||
|
||||
foreach ($dataList as $data) {
|
||||
if (!is_array($data)) {
|
||||
throw new RuntimeException("Bad data.");
|
||||
}
|
||||
|
||||
$name = $data['name'] ?? null;
|
||||
$code = $data['code'] ?? null;
|
||||
$isPreferred = $data['isPreferred'] ?? false;
|
||||
|
||||
if (!is_string($name) || !is_string($code)) {
|
||||
throw new RuntimeException("Bad data.");
|
||||
}
|
||||
|
||||
$entity = $this->entityManager->getNewEntity(AddressCountry::ENTITY_TYPE);
|
||||
|
||||
$entity->setMultiple([
|
||||
'id' => $this->recordIdGenerator->generate(),
|
||||
'name' => $name,
|
||||
'code' => $code,
|
||||
'isPreferred' => $isPreferred,
|
||||
]);
|
||||
|
||||
$collection->append($entity);
|
||||
}
|
||||
|
||||
$this->entityManager->getQueryExecutor()->execute(
|
||||
DeleteBuilder::create()
|
||||
->from(AddressCountry::ENTITY_TYPE)
|
||||
->build()
|
||||
);
|
||||
|
||||
$this->entityManager->getMapper()->massInsert($collection);
|
||||
|
||||
$this->dataCache->clear(self::CACHE_KEY);
|
||||
}
|
||||
}
|
||||
@@ -219,6 +219,11 @@ class AdminController extends Controller {
|
||||
this.getRouter().dispatch('AuthenticationProvider', 'list', {fromAdmin: true});
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
actionAddressCountries() {
|
||||
this.getRouter().dispatch('AddressCountry', 'list', {fromAdmin: true});
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
actionEmailAddresses() {
|
||||
this.getRouter().dispatch('EmailAddress', 'list', {fromAdmin: true});
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2024 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 ActionHandler from 'action-handler';
|
||||
|
||||
class PopulateDefaultsHandler extends ActionHandler {
|
||||
|
||||
async populate() {
|
||||
const confirmMessage = this.view.translate('confirmPopulateDefaults', 'messages', 'AddressCountry');
|
||||
|
||||
await this.view.confirm(confirmMessage);
|
||||
|
||||
Espo.Ui.notify(' ... ');
|
||||
|
||||
await Espo.Ajax.postRequest('AddressCountry/action/populateDefaults');
|
||||
await this.view.collection.fetch();
|
||||
|
||||
Espo.Ui.success(this.view.translate('Done'));
|
||||
}
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
export default PopulateDefaultsHandler;
|
||||
@@ -31,12 +31,57 @@ import VarcharFieldView from 'views/fields/varchar';
|
||||
class AddressCountryFieldView extends VarcharFieldView {
|
||||
|
||||
setupOptions() {
|
||||
let countryList = this.getConfig().get('addressCountryList') || [];
|
||||
const countryList = this.getCountryList();
|
||||
|
||||
if (countryList.length) {
|
||||
this.params.options = Espo.Utils.clone(countryList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @return {string[]}
|
||||
*/
|
||||
getCountryList() {
|
||||
const list = (this.getHelper().getAppParam('addressCountryData') || {}).list || [];
|
||||
|
||||
if (list.length) {
|
||||
return list;
|
||||
}
|
||||
|
||||
return this.getConfig().get('addressCountryList') || [];
|
||||
}
|
||||
|
||||
getAutocompleteLookupFunction() {
|
||||
// noinspection JSUnresolvedReference
|
||||
const list = (this.getHelper().getAppParam('addressCountryData') || {}).preferredList || [];
|
||||
|
||||
if (!list.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const fullList = (this.params.options || []);
|
||||
|
||||
return query => {
|
||||
if (query.length === 0) {
|
||||
const result = list.map(item => ({value: item}));
|
||||
|
||||
return Promise.resolve(result);
|
||||
}
|
||||
|
||||
const queryLowerCase = query.toLowerCase();
|
||||
|
||||
const result = fullList
|
||||
.filter(item => {
|
||||
if (item.toLowerCase().indexOf(queryLowerCase) === 0) {
|
||||
return item.length !== queryLowerCase.length;
|
||||
}
|
||||
})
|
||||
.map(item => ({value: item}));
|
||||
|
||||
return Promise.resolve(result);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default AddressCountryFieldView;
|
||||
|
||||
@@ -386,7 +386,7 @@ class AddressFieldView extends BaseFieldView {
|
||||
this.$city.on('change', () => this.trigger('change'));
|
||||
this.$country.on('change', () => this.trigger('change'));
|
||||
|
||||
const countryList = this.getConfig().get('addressCountryList') || [];
|
||||
const countryList = this.getCountryList();
|
||||
const cityList = this.getConfig().get('addressCityList') || [];
|
||||
const stateList = this.getConfig().get('addressStateList') || [];
|
||||
|
||||
@@ -398,6 +398,7 @@ class AddressFieldView extends BaseFieldView {
|
||||
handleFocusMode: 1,
|
||||
focusOnSelect: true,
|
||||
lookup: countryList,
|
||||
lookupFunction: this.getCountryAutocompleteLookupFunction(countryList),
|
||||
onSelect: () => this.trigger('change'),
|
||||
});
|
||||
|
||||
@@ -610,6 +611,54 @@ class AddressFieldView extends BaseFieldView {
|
||||
field: this.name,
|
||||
}, view => view.render());
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @return {string[]}
|
||||
*/
|
||||
getCountryList() {
|
||||
const list = (this.getHelper().getAppParam('addressCountryData') || {}).list || [];
|
||||
|
||||
if (list.length) {
|
||||
return list;
|
||||
}
|
||||
|
||||
return this.getConfig().get('addressCountryList') || [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {string[]} fullList
|
||||
* @return {function(string): Promise|undefined}
|
||||
*/
|
||||
getCountryAutocompleteLookupFunction(fullList) {
|
||||
// noinspection JSUnresolvedReference
|
||||
const list = (this.getHelper().getAppParam('addressCountryData') || {}).preferredList || [];
|
||||
|
||||
if (!list.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return query => {
|
||||
if (query.length === 0) {
|
||||
const result = list.map(item => ({value: item}));
|
||||
|
||||
return Promise.resolve(result);
|
||||
}
|
||||
|
||||
const queryLowerCase = query.toLowerCase();
|
||||
|
||||
const result = fullList
|
||||
.filter(item => {
|
||||
if (item.toLowerCase().indexOf(queryLowerCase) === 0) {
|
||||
return item.length !== queryLowerCase.length;
|
||||
}
|
||||
})
|
||||
.map(item => ({value: item}));
|
||||
|
||||
return Promise.resolve(result);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default AddressFieldView;
|
||||
|
||||
Reference in New Issue
Block a user