Fixed corp address

This commit is contained in:
gleemand 2022-03-20 12:25:55 +03:00 committed by GitHub
parent cf97a5e3db
commit d8fa2abbd5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 442 additions and 28 deletions

View File

@ -6,7 +6,7 @@
Prestashop module. Prestashop module.
================= =================
Module allows integrate CMS Prestashop with [Simla.com](https://www.retailcrm.pro) ([Documentation](https://docs.retailcrm.ru/Users/Integration/SiteModules/PrestaShop) page) Module allows integrate CMS Prestashop with [Simla.com](https://simla.com) ([Documentation](https://www.simla.com/docs/Users/Integration/SiteModules/PrestaShop) page)
#### Features: #### Features:
@ -27,3 +27,7 @@ Module allows integrate CMS Prestashop with [Simla.com](https://www.retailcrm.pr
#### Customization #### Customization
You can customize your module behavior using [Custom Filters](doc/3.%20Customization/Filters.md) or [Custom Classes](doc/3.%20Customization/Classes.md) You can customize your module behavior using [Custom Filters](doc/3.%20Customization/Filters.md) or [Custom Classes](doc/3.%20Customization/Classes.md)
#### Documentation
[Here](doc/README.md) you can find more information about module setup and workflow

View File

@ -1,3 +1,5 @@
# Configuration # Configuration
1. [Connection](Connection.md) 1. [Connection](Connection.md)
2. [Payment types](Payment%20types.md)
3. [Stock](Stock.md)

View File

@ -3,4 +3,5 @@
1. [Installation](Installation.md) 1. [Installation](Installation.md)
2. [Configuration](./Configuration/README.md) 2. [Configuration](./Configuration/README.md)
3. [Upgrade](Upgrade.md) 3. [Upgrade](Upgrade.md)
4. [Catalog](Catalog.md)

View File

@ -5,4 +5,5 @@
Каждый запрос получения истории изменений сопровождается параметром _sinceId_, Который хранится в конфигурации модуля Каждый запрос получения истории изменений сопровождается параметром _sinceId_, Который хранится в конфигурации модуля
1. [Синхронизация данных клиентов](Customers.md) 1. [Синхронизация данных клиентов](Customers.md)
2. [Синхронизация данных заказов](Orders.md) 2. [Синхронизация данных заказов](Orders.md)
3. [Inventories](Inventories.md)

View File

@ -1 +1,3 @@
# CLI & Job Manager # CLI & Job Manager
1. [Job Manager](Job%20Manager.md)

View File

@ -1 +1,13 @@
# Customers # Customers
## Адреса корпоративных клиентов
Клиент считается корпоративным, если в его `invoice address` поле `company` не пустое.
При выгрузке в CRM в этом случае создается корпортаивный клиент и привязаный к нему клиент типа `Контактное лицо`.
Если при выгрузке в CRM обнаружено, что создаваемый адрес в корпоративном клиенте в CRM уже существует (проверка по `externalId` и по совпадению поля `text`), то адрес в CRM редактируется (не создается новый).
Для названия адреса корпортаивного клиента в CRM используется поле `alias` (если оно заполнено), либо поле `company`.
При создании заказа в CMS для того же клиента, но с новым названием компании, создается новая компания в первом найденном в CRM корпоративном клиенте с этим контактным лицом.

View File

@ -1 +1,8 @@
# Forward Synchronization # Forward Synchronization
1. [Abandoned carts](Abandoned%20carts.md)
2. [Customers](Customers.md)
3. [Export](Export.md)
4. [ICML](Icml.md)
5. [Orders](Orders.md)
6. [Upload](Upload.md)

View File

@ -0,0 +1,3 @@
# Pipeline
1. [Middlewares](Middlewares.md)

View File

@ -1 +1,8 @@
# Workflow # Workflow
1. [Backward Synchronization](Backward%20Synchronization/README.md)
2. [CLI & Job Manager](CLI%20&%20Job%20Manager/README.md)
3. [Forward Synchronization](Forward%20Synchronization/README.md)
4. [Pipeline](Pipeline/README.md)
5. [Templates & Views](Templates%20&%20Views/README.md)
6. [Multistore](Multistore.md)

View File

@ -1 +1,5 @@
# Customization # Customization
1. [Classes](Classes.md)
2. [Examples](Examples.md)
3. [Filters](Filters.md)

View File

@ -1 +1,6 @@
# Developers documentation # Documentation
1. [Setup](1.%20Setup/README.md)
2. [Workflow](2.%20Workflow/README.md)
3. [Customization](3.%20Customization/README.md)
4. [Known issues](4.%20Known%20issues/README.md)

View File

@ -243,6 +243,7 @@ class RetailcrmAddressBuilder extends RetailcrmAbstractDataBuilder
private function parseAddress() private function parseAddress()
{ {
$state = null; $state = null;
$name = null;
if (!empty($this->address->id_state)) { if (!empty($this->address->id_state)) {
$stateName = State::getNameById($this->address->id_state); $stateName = State::getNameById($this->address->id_state);
@ -252,6 +253,10 @@ class RetailcrmAddressBuilder extends RetailcrmAbstractDataBuilder
} }
} }
if (static::MODE_CORPORATE_CUSTOMER === $this->mode) {
$name = isset($this->address->alias) ? $this->address->alias : $this->address->company;
}
return array_filter([ return array_filter([
'index' => $this->address->postcode, 'index' => $this->address->postcode,
'city' => $this->address->city, 'city' => $this->address->city,
@ -263,6 +268,7 @@ class RetailcrmAddressBuilder extends RetailcrmAbstractDataBuilder
])), ])),
'notes' => $this->address->other, 'notes' => $this->address->other,
'region' => $state, 'region' => $state,
'name' => $name,
]); ]);
} }

View File

@ -401,6 +401,7 @@ class RetailcrmHistory
$addressInvoice = $corporateCustomerBuilder->getData()->getCustomerAddress(); $addressInvoice = $corporateCustomerBuilder->getData()->getCustomerAddress();
} else { } else {
$customerBuilder = new RetailcrmCustomerBuilder(); $customerBuilder = new RetailcrmCustomerBuilder();
if ($customerId) { if ($customerId) {
$customerBuilder->setCustomer(new Customer($customerId)); $customerBuilder->setCustomer(new Customer($customerId));
} }

View File

@ -396,6 +396,8 @@ class RetailcrmOrderBuilder
*/ */
private function createCorporateIfNotExist() private function createCorporateIfNotExist()
{ {
$crmAddressId = 0;
$companyWasFound = true;
$corporateWasFound = true; $corporateWasFound = true;
$this->validateCmsCustomerInDb(); $this->validateCmsCustomerInDb();
@ -416,14 +418,33 @@ class RetailcrmOrderBuilder
$crmCorporate = $this->findCorporateCustomerByCompany($this->invoiceAddress->company); $crmCorporate = $this->findCorporateCustomerByCompany($this->invoiceAddress->company);
} }
if (empty($crmCorporate)) {
$crmCorporate = $this->findCorporateCustomerByContact($customer['id']);
if (!empty($crmCorporate)) {
$companyWasFound = false;
}
}
if (empty($crmCorporate)) { if (empty($crmCorporate)) {
$crmCorporate = $this->createCorporateCustomer($customer['externalId']); $crmCorporate = $this->createCorporateCustomer($customer['externalId']);
$corporateWasFound = false; $corporateWasFound = false;
} elseif (isset($crmCorporate['id'])) { } elseif (isset($crmCorporate['id'])) {
$this->appendAdditionalAddressToCorporate($crmCorporate['id']); $result = $this->appendAdditionalAddressToCorporate($crmCorporate['id']);
$crmAddressId = isset($result['id']) ? $result['id'] : 0;
} }
if ($corporateWasFound) { if ($corporateWasFound) {
if (!$companyWasFound) {
$company = $this->buildCorporateCompany($crmAddressId);
$this->api->customersCorporateCompaniesCreate(
$crmCorporate['id'],
$company,
'id',
$this->getApiSite()
);
}
$contactList = $this->api->customersCorporateContacts( $contactList = $this->api->customersCorporateContacts(
$crmCorporate['id'], $crmCorporate['id'],
['contactIds' => [$customer['id']]], ['contactIds' => [$customer['id']]],
@ -526,6 +547,8 @@ class RetailcrmOrderBuilder
* Append new address to corporate customer if new address is not present in corporate customer. * Append new address to corporate customer if new address is not present in corporate customer.
* *
* @param string|int $corporateId * @param string|int $corporateId
*
* @return bool|array|\RetailcrmApiResponse
*/ */
private function appendAdditionalAddressToCorporate($corporateId) private function appendAdditionalAddressToCorporate($corporateId)
{ {
@ -549,7 +572,7 @@ class RetailcrmOrderBuilder
foreach ($addresses as $addressInCrm) { foreach ($addresses as $addressInCrm) {
if (!empty($addressInCrm['externalId']) && $addressInCrm['externalId'] == $this->invoiceAddress->id) { if (!empty($addressInCrm['externalId']) && $addressInCrm['externalId'] == $this->invoiceAddress->id) {
$this->api->customersCorporateAddressesEdit( return $this->api->customersCorporateAddressesEdit(
$corporateId, $corporateId,
$addressInCrm['externalId'], $addressInCrm['externalId'],
$address, $address,
@ -557,8 +580,17 @@ class RetailcrmOrderBuilder
'externalId', 'externalId',
$this->getApiSite() $this->getApiSite()
); );
}
return; if (RetailCrmTools::clearAddress($address['text']) === RetailCrmTools::clearAddress($addressInCrm['text'])) {
return $this->api->customersCorporateAddressesEdit(
$corporateId,
$addressInCrm['id'],
$address,
'id',
'id',
$this->getApiSite()
);
} }
} }
@ -658,6 +690,32 @@ class RetailcrmOrderBuilder
return []; return [];
} }
/**
* Find corporate customer by contact id
*
* @param $contactId
*
* @return array
*/
private function findCorporateCustomerByContact($contactId)
{
$crmCorporate = $this->api->customersCorporateList([
'contactIds' => [$contactId],
]);
if ($crmCorporate instanceof RetailcrmApiResponse
&& $crmCorporate->isSuccessful()
&& $crmCorporate->offsetExists('customersCorporate')
&& 0 < count($crmCorporate['customersCorporate'])
) {
$crmCorporate = $crmCorporate['customersCorporate'];
return reset($crmCorporate);
}
return [];
}
/** /**
* Get corporate companies, extract company data by provided identifiers * Get corporate companies, extract company data by provided identifiers
* *
@ -1200,6 +1258,7 @@ class RetailcrmOrderBuilder
'birthday' => RetailcrmTools::verifyDate($object->birthday, 'Y-m-d') 'birthday' => RetailcrmTools::verifyDate($object->birthday, 'Y-m-d')
? $object->birthday : '', ? $object->birthday : '',
'sex' => '1' == $object->id_gender ? 'male' : ('2' == $object->id_gender ? 'female' : ''), 'sex' => '1' == $object->id_gender ? 'male' : ('2' == $object->id_gender ? 'female' : ''),
'isContact' => isset($address['company']),
], ],
$address $address
), function ($value) { ), function ($value) {

View File

@ -140,6 +140,36 @@ class RetailcrmTools
return 0; return 0;
} }
/**
* Clears address string from any unwanted characters (to compare)
*
* @param string $address
*
* @return string
*/
public static function clearAddress($address)
{
$replacements = [
'Š' => 'S', 'š' => 's', 'Ž' => 'Z', 'ž' => 'z', 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A',
'Å' => 'A', 'Æ' => 'A', 'Ç' => 'C', 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ì' => 'I', 'Í' => 'I',
'Î' => 'I', 'Ï' => 'I', 'Ñ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'O', 'Ø' => 'O',
'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ý' => 'Y', 'Þ' => 'B', 'ß' => 'Ss', 'à' => 'a', 'á' => 'a',
'â' => 'a', 'ã' => 'a', 'ä' => 'a', 'å' => 'a', 'æ' => 'a', 'ç' => 'c', 'è' => 'e', 'é' => 'e', 'ê' => 'e',
'ë' => 'e', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ð' => 'o', 'ñ' => 'n', 'ò' => 'o', 'ó' => 'o',
'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ø' => 'o', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ü' => 'u', 'ý' => 'y',
'þ' => 'b', 'ÿ' => 'y',
];
$result = str_replace(
[' ', '-', ',', '.', "'", '`', '/', '|', '&', '#', '^', '(', ')', chr(0xC2) . chr(0xA0)],
'',
$address
);
$result = strtr($result, $replacements);
return strtolower($result);
}
/** /**
* Returns 'true' if provided date string is valid * Returns 'true' if provided date string is valid
* *

View File

@ -38,9 +38,24 @@
class RetailcrmOrderBuilderTest extends RetailcrmTestCase class RetailcrmOrderBuilderTest extends RetailcrmTestCase
{ {
/**
* @var RetailcrmProxy
*/
private $apiMock;
protected function setUp() protected function setUp()
{ {
parent::setUp(); parent::setUp();
$this->apiMock = $this->getApiMock(
[
'method',
'credentials',
'customersCorporateAddresses',
'customersCorporateAddressesEdit',
'customersCorporateAddressesCreate',
]
);
} }
public function testInitialPriceZero() public function testInitialPriceZero()
@ -52,6 +67,86 @@ class RetailcrmOrderBuilderTest extends RetailcrmTestCase
$this->assertEquals(0, $resultItem['initialPrice']); $this->assertEquals(0, $resultItem['initialPrice']);
} }
/**
* @dataProvider buildCrmCustomerAddresses
*/
public function testBuildCrmCustomer($address, $isCorp)
{
$customer = new Customer(1);
$crmCustomer = RetailcrmOrderBuilder::buildCrmCustomer($customer, $address);
$this->assertEquals($isCorp, $crmCustomer['isContact']);
$this->assertNotEmpty($crmCustomer['email']);
}
/**
* @dataProvider appendAdditionalAddressToCorporateAddresses
*/
public function testAppendAdditionalAddressToCorporate($address, $method)
{
$this->apiClientMock->expects($this->any())
->method('credentials')
->willReturn(
new RetailcrmApiResponse(
'200',
json_encode(
[
'success' => true,
]
)
)
)
;
$this->apiClientMock->expects($this->once())
->method('customersCorporateAddresses')
->willReturn(
new RetailcrmApiResponse(
'200',
json_encode(
[
'pagination' => [
'totalPageCount' => 1,
'currentPage' => 1,
],
'addresses' => $this->getCorpAddresses(),
]
)
)
)
;
$this->apiClientMock->expects($this->once())
->method($method)
->willReturn(
new RetailcrmApiResponse(
'200',
json_encode(
[
'pagination' => [
'totalPageCount' => 1,
'currentPage' => 1,
],
'addresses' => $this->getCorpAddresses(),
]
)
)
)
;
$orderBuilder = new RetailcrmOrderBuilder();
$orderBuilder->setApi($this->apiMock);
$class = new ReflectionClass($orderBuilder);
$property = $class->getProperty('invoiceAddress');
$property->setAccessible(true);
$property->setValue($orderBuilder, $this->convertAddress($address));
$method = $class->getMethod('appendAdditionalAddressToCorporate');
$method->setAccessible(true);
$method->invoke($orderBuilder, 0);
}
public function testBuildCrmOrder() public function testBuildCrmOrder()
{ {
$order = new Order(1); $order = new Order(1);
@ -70,6 +165,50 @@ class RetailcrmOrderBuilderTest extends RetailcrmTestCase
$this->assertEquals($order->reference, $crmOrder['number']); $this->assertEquals($order->reference, $crmOrder['number']);
} }
private function convertAddress($crmAddress)
{
$address = new Address();
$address->address1 = $crmAddress['text'];
$address->alias = $crmAddress['name'];
$address->city = $crmAddress['city'];
$address->id_country = Country::getByIso($crmAddress['countryIso']);
$address->country = Country::getNameById((int) Configuration::get('PS_LANG_DEFAULT'), $address->id_country);
$address->postcode = $crmAddress['index'];
$address->company = $crmAddress['name'];
$address->id = isset($crmAddress['externalId']) ? $crmAddress['externalId'] : null;
return $address;
}
public function appendAdditionalAddressToCorporateAddresses()
{
return [
[
$this->getCorpAddresses()[0],
'customersCorporateAddressesEdit',
],
[
$this->getCorpAddresses()[1],
'customersCorporateAddressesEdit',
],
[
[
'id' => '3',
'externalId' => '30',
'index' => '423120',
'city' => 'Kazan',
'countryIso' => 'RU',
'text' => 'ul. Fuchika, d. 129',
'notes' => 'Building under the big tree',
'region' => 'Republic of Tatarstan',
'company' => 'MyCompany',
'name' => 'Home',
],
'customersCorporateAddressesCreate',
],
];
}
/** /**
* @return array * @return array
*/ */
@ -93,6 +232,22 @@ class RetailcrmOrderBuilderTest extends RetailcrmTestCase
]; ];
} }
public function buildCrmCustomerAddresses()
{
return [
[
'Address' => [
'company' => 'RetailCRM',
],
'Is corporate address?' => true,
],
[
'Address' => [],
'Is corporate address?' => false,
],
];
}
/** /**
* @return array * @return array
*/ */
@ -212,4 +367,34 @@ class RetailcrmOrderBuilderTest extends RetailcrmTestCase
return $order; return $order;
} }
private function getCorpAddresses()
{
return [
[
'id' => '1',
'externalId' => '10',
'index' => '452320',
'city' => 'Dyurtyuli',
'countryIso' => 'RU',
'text' => 'ul. Matrosova, d. 8',
'notes' => 'from 12:00 to 15:00',
'region' => 'Republic of Bashkortostan',
'company' => 'MyCompany',
'name' => 'Office',
],
[
'id' => '2',
'externalId' => '90',
'index' => '760021',
'city' => 'Cali',
'countryIso' => 'CO',
'text' => 'Av 6 A NORTE No. 28 N-10, C.P 76001',
'notes' => 'Red door next to the road',
'region' => 'Cali',
'company' => 'MyCompany',
'name' => 'Warehouse',
],
];
}
} }

View File

@ -42,14 +42,6 @@ if (class_exists('LegacyTests\Unit\ContextMocker')) {
abstract class RetailcrmTestCase extends \PHPUnit\Framework\TestCase abstract class RetailcrmTestCase extends \PHPUnit\Framework\TestCase
{ {
/**
* @var RetailcrmProxy
*/
private $apiMock;
/**
* @var PHPUnit_Framework_MockObject_MockObject
*/
protected $apiClientMock; protected $apiClientMock;
protected $contextMock; protected $contextMock;
@ -68,10 +60,10 @@ abstract class RetailcrmTestCase extends \PHPUnit\Framework\TestCase
{ {
$this->apiClientMock = $this->apiMockBuilder($methods)->getMock(); $this->apiClientMock = $this->apiMockBuilder($methods)->getMock();
$this->apiMock = new RetailcrmProxy('https://test.test', 'test_key'); $apiMock = new RetailcrmProxy('https://test.test', 'test_key');
$this->apiMock->setClient($this->apiClientMock); $apiMock->setClient($this->apiClientMock);
return $this->apiMock; return $apiMock;
} }
protected function setConfig() protected function setConfig()

View File

@ -51,6 +51,11 @@ class RetailcrmAddressBuilderTest extends RetailcrmTestCase
{ {
parent::setUp(); parent::setUp();
$this->address = $this->prepareAddress();
}
private function prepareAddress()
{
$this->defaultLang = (int) Configuration::get('PS_LANG_DEFAULT'); $this->defaultLang = (int) Configuration::get('PS_LANG_DEFAULT');
$address = new Address(); $address = new Address();
$address->id_state = State::getIdByName('Alabama'); $address->id_state = State::getIdByName('Alabama');
@ -65,7 +70,36 @@ class RetailcrmAddressBuilderTest extends RetailcrmTestCase
$address->phone = '123'; $address->phone = '123';
$address->phone_mobile = '123'; $address->phone_mobile = '123';
$address->postcode = '333000'; $address->postcode = '333000';
$this->address = $address;
return $address;
}
/**
* @dataProvider parseAddresses
*/
public function testParseAddress($address, $mode, $addressName)
{
$addressBuilder = new RetailcrmAddressBuilder();
$class = new ReflectionClass($addressBuilder);
$property = $class->getProperty('address');
$property->setAccessible(true);
$property->setValue($addressBuilder, $address);
$property = $class->getProperty('mode');
$property->setAccessible(true);
$property->setValue($addressBuilder, $mode);
$method = $class->getMethod('parseAddress');
$method->setAccessible(true);
$result = $method->invoke($addressBuilder);
if (RetailcrmAddressBuilder::MODE_CORPORATE_CUSTOMER === $mode) {
$this->assertArrayHasKey('name', $result);
$this->assertEquals($addressName, $result['name']);
} else {
$this->assertArrayNotHasKey('name', $result);
}
} }
public function testBuildRegular() public function testBuildRegular()
@ -178,6 +212,39 @@ class RetailcrmAddressBuilderTest extends RetailcrmTestCase
} }
} }
public function parseAddresses()
{
$addressWithAlias = $this->prepareAddress();
$addressWithAlias->alias = 'test_alias';
$addressWithCompany = $this->prepareAddress();
unset($addressWithCompany->alias);
$addressWithCompany->company = 'test_company';
return [
[
'Address' => $addressWithAlias,
'Mode' => RetailcrmAddressBuilder::MODE_CORPORATE_CUSTOMER,
'Address name' => $addressWithAlias->alias,
],
[
'Address' => $addressWithCompany,
'Mode' => RetailcrmAddressBuilder::MODE_CORPORATE_CUSTOMER,
'Address name' => $addressWithCompany->company,
],
[
'Address' => $addressWithAlias,
'Mode' => RetailcrmAddressBuilder::MODE_CUSTOMER,
'Address name' => null,
],
[
'Address' => $addressWithCompany,
'Mode' => RetailcrmAddressBuilder::MODE_CUSTOMER,
'Address name' => null,
],
];
}
public function getAddressLines() public function getAddressLines()
{ {
return [ return [

View File

@ -38,6 +38,32 @@
class RetailcrmToolsTest extends RetailcrmTestCase class RetailcrmToolsTest extends RetailcrmTestCase
{ {
/**
* @dataProvider clearAddresses
*/
public function testClearAddress($address, $result)
{
$this->assertEquals($result, RetailcrmTools::clearAddress($address));
}
public function clearAddresses()
{
return [
[
'Calle 66 # 11 -27, Casa || Casa',
'calle661127casacasa',
],
[
'Calle 111 # 7c 10 || 202 torre 6',
'calle1117c10202torre6',
],
[
'Bogotá, D.C. Calle 4B 20-85 || 312',
'bogotadccalle4b2085312',
],
];
}
/** /**
* @dataProvider equalCustomerAddresses * @dataProvider equalCustomerAddresses
*/ */
@ -49,7 +75,7 @@ class RetailcrmToolsTest extends RetailcrmTestCase
public function equalCustomerAddresses() public function equalCustomerAddresses()
{ {
return [ return [
'Equal addresses' => [ 'equal_addresses' => [
[ [
'phones' => [ 'phones' => [
['number' => '111'], ['number' => '111'],
@ -72,7 +98,7 @@ class RetailcrmToolsTest extends RetailcrmTestCase
], ],
true, true,
], ],
'Changed phone' => [ 'changed_phone' => [
[ [
'phones' => [ 'phones' => [
['number' => '222'], ['number' => '222'],
@ -95,7 +121,7 @@ class RetailcrmToolsTest extends RetailcrmTestCase
], ],
false, false,
], ],
'Changed index' => [ 'changed_index' => [
[ [
'phones' => [ 'phones' => [
['number' => '111'], ['number' => '111'],
@ -118,7 +144,7 @@ class RetailcrmToolsTest extends RetailcrmTestCase
], ],
false, false,
], ],
'Reduced address' => [ 'reduced_address' => [
[ [
'phones' => [ 'phones' => [
['number' => '111'], ['number' => '111'],
@ -139,7 +165,7 @@ class RetailcrmToolsTest extends RetailcrmTestCase
], ],
false, false,
], ],
'Expanded address' => [ 'expanded_address' => [
[ [
'phones' => [ 'phones' => [
['number' => '111'], ['number' => '111'],
@ -160,7 +186,7 @@ class RetailcrmToolsTest extends RetailcrmTestCase
], ],
false, false,
], ],
'Reduced phone' => [ 'reduced_phone' => [
[ [
'phones' => [ 'phones' => [
['number' => '111'], ['number' => '111'],
@ -184,7 +210,7 @@ class RetailcrmToolsTest extends RetailcrmTestCase
], ],
false, false,
], ],
'Expanded phone' => [ 'expanded_phone' => [
[ [
'phones' => [ 'phones' => [
['number' => '111'], ['number' => '111'],
@ -208,7 +234,7 @@ class RetailcrmToolsTest extends RetailcrmTestCase
], ],
false, false,
], ],
'Replaced field' => [ 'replaced_field' => [
[ [
'phones' => [ 'phones' => [
['number' => '111'], ['number' => '111'],