Customer change logic

This commit is contained in:
Pavel 2020-07-08 16:09:45 +03:00 committed by GitHub
parent c90adf1913
commit a62b0e77cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 2988 additions and 314 deletions

3
.gitignore vendored
View File

@ -4,4 +4,5 @@ retailcrm/views/css/less/*.map
retailcrm/views/css/*.css
retailcrm/views/css/*.map
!retailcrm/views/css/*.min.css
retailcrm/config_*.xml
retailcrm/config_*.xml
coverage.xml

View File

@ -0,0 +1,52 @@
<?php
/**
* MIT License
*
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
* @license https://opensource.org/licenses/MIT The MIT License
*
* Don't forget to prefix your containers with your own identifier
* to avoid any conflicts with others containers.
*/
abstract class RetailcrmAbstractBuilder
{
/**
* Checks if there is a key in the array and returns if there is an element array if not the default value
*
* @param string $key
* @param string $default
*
* @return mixed
*/
protected function arrayValue($key, $default = '--')
{
return isset($this->dataCrm[$key]) && !empty($this->dataCrm[$key]) ? $this->dataCrm[$key] : $default;
}
}

View File

@ -0,0 +1,70 @@
<?php
/**
* MIT License
*
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
* @license https://opensource.org/licenses/MIT The MIT License
*
* Don't forget to prefix your containers with your own identifier
* to avoid any conflicts with others containers.
*/
interface RetailcrmBuilderInterface
{
/**
* Get result build
*
* @return mixed
*/
public function getData();
/**
* Set data array customerHistory
*
* @param array $dataCrm
*
* @return RetailcrmBuilderInterface
*/
public function setDataCrm($dataCrm);
/**
* Build result
*
* @return \RetailcrmBuilderInterface
*/
public function build();
/**
* Create new object
*
* @return mixed
*/
public function reset();
}

View File

@ -129,16 +129,24 @@ class RetailcrmCli
}
}
/**
* Shutdown handler. Moved here in order to keep compatibility with older PHP versions.
*
* @param mixed $error
*/
public function cleanupOnShutdown($error)
{
if (null !== $error) {
self::clearCurrentJob(null);
}
}
/**
* This will register shutdown handler which will clean lock before shutdown
*/
private function setCleanupOnShutdown()
{
RetailcrmJobManager::setCustomShutdownHandler(function ($error) {
if (null !== $error) {
self::clearCurrentJob(null);
}
});
RetailcrmJobManager::setCustomShutdownHandler(array($this, 'cleanupOnShutdown'));
}
/**
@ -156,17 +164,17 @@ class RetailcrmCli
$result ? 'true' : 'false'
));
} catch (\Exception $exception) {
if ($exception instanceof RetailcrmJobManagerException && !empty($exception->getPrevious())) {
if ($exception instanceof RetailcrmJobManagerException && $exception->getPrevious() instanceof \Exception) {
$this->printStack($exception->getPrevious());
} else {
$this->printStack($exception);
}
self::clearCurrentJob($jobName);
} finally {
if (isset($result) && $result) {
self::clearCurrentJob($jobName);
}
}
if (isset($result) && $result) {
self::clearCurrentJob($jobName);
}
}

View File

@ -0,0 +1,207 @@
<?php
/**
* MIT License
*
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
* @license https://opensource.org/licenses/MIT The MIT License
*
* Don't forget to prefix your containers with your own identifier
* to avoid any conflicts with others containers.
*/
class RetailcrmCorporateCustomerBuilder extends RetailcrmAbstractBuilder implements RetailcrmBuilderInterface
{
/**
* @var Customer|CustomerCore $corporateCustomer Corporate customer
*/
private $corporateCustomer;
/**
* @var RetailcrmBuilderInterface $customerBuilder Customer builder
*/
private $customerBuilder;
/**
* @var array $dataCrm customerHistory
*/
protected $dataCrm;
/**
* @var string $companyName
*/
private $companyName;
/**
* @var string $companyInn
*/
protected $companyInn;
/**
* @var Address|AddressCore $corporateAddress
*/
private $corporateAddress;
/**
* RetailcrmCorporateCustomerBuilder constructor.
*/
public function __construct()
{
$this->reset();
}
/**
* @param RetailcrmBuilderInterface $customerBuilder
* @return RetailcrmCorporateCustomerBuilder
*/
public function setCustomerBuilder($customerBuilder)
{
$this->customerBuilder = $customerBuilder;
return $this;
}
/**
* @param Customer $corporateCustomer Corporate customer
* @return RetailcrmCorporateCustomerBuilder
*/
public function setCustomer($corporateCustomer)
{
$this->corporateCustomer = $corporateCustomer;
return $this;
}
/**
* @param string $companyName
* @return RetailcrmCorporateCustomerBuilder
*/
public function setCompanyName($companyName)
{
$this->companyName = $companyName;
return $this;
}
/**
* @param string $companyInn
* @return RetailcrmCorporateCustomerBuilder
*/
public function setCompanyInn($companyInn)
{
$this->companyInn = $companyInn;
return $this;
}
/**
* @param Address|AddressCore $corporateAddress
* @return RetailcrmCorporateCustomerBuilder
*/
public function setCorporateAddress($corporateAddress)
{
$this->corporateAddress = $corporateAddress;
return $this;
}
/**
* Set data in address, name and inn company corporate customer
*
* @param array $dataCrm
* @return RetailcrmCorporateCustomerBuilder
*/
public function extractCompanyDataFromOrder($dataCrm)
{
$this->setCompanyName(isset($dataCrm['company']['name']) ? $dataCrm['company']['name'] : '');
if (isset($dataCrm['company']['contragent']) && !empty($dataCrm['company']['contragent']['INN'])) {
$this->setCompanyInn($dataCrm['company']['contragent']['INN']);
}
return $this;
}
public function setDataCrm($dataCrm)
{
$this->dataCrm = $dataCrm;
return $this;
}
public function getData()
{
return new RetailcrmCustomerBuilderResult($this->corporateCustomer, $this->corporateAddress);
}
public function reset()
{
$this->corporateCustomer = new Customer();
$this->customerBuilder = null;
$this->corporateAddress = null;
return $this;
}
/**
* Build customer for corporate customer
*/
private function buildCustomer()
{
if (empty($this->customerBuilder)) {
$this->customerBuilder = new RetailcrmCustomerBuilder();
}
if (!empty($this->dataCrm)) {
$this->customerBuilder->setDataCrm($this->dataCrm);
}
if (isset($this->dataCrm['address'])) {
$this->customerBuilder->build();
}
$this->corporateCustomer = $this->customerBuilder->getData()->getCustomer();
$this->corporateAddress = $this->customerBuilder->getData()->getCustomerAddress();
}
public function build()
{
$this->buildCustomer();
if (!empty($this->corporateAddress)) {
if (empty($this->corporateAddress->alias) || $this->corporateAddress->alias == 'default') {
$this->corporateAddress->alias = '--';
}
$this->corporateAddress->vat_number = !empty($this->companyInn) ? $this->companyInn : '';
$this->corporateAddress->company = !empty($this->companyName) ? $this->companyName : '';
if (!empty($this->companyName) && (empty($this->corporateCustomer->firstname) || $this->corporateCustomer->firstname == '--')) {
$this->corporateCustomer->firstname = $this->companyName;
}
}
return $this;
}
}

View File

@ -0,0 +1,196 @@
<?php
/**
* MIT License
*
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
* @license https://opensource.org/licenses/MIT The MIT License
*
* Don't forget to prefix your containers with your own identifier
* to avoid any conflicts with others containers.
*/
class RetailcrmCustomerAddressBuilder extends RetailcrmAbstractBuilder implements RetailcrmBuilderInterface
{
/**
* @var Address|AddressCore customerAddress
*/
private $customerAddress;
/**
* @var array $dataCrm
*/
private $dataCrm;
/**
* @var int $idCustomer
*/
private $idCustomer;
/**
* @var string $firstName
*/
private $firstName;
/**
* @var string $lastName
*/
private $lastName;
/**
* @var string $phone
*/
private $phone;
/**
* @var string $alias
*/
private $alias;
/**
* RetailcrmCustomerAddressBuilder constructor.
*/
public function __construct()
{
$this->reset();
}
/**
* @param Address|AddressCore $customerAddress
* @return RetailcrmCustomerAddressBuilder
*/
public function setCustomerAddress($customerAddress)
{
$this->customerAddress = $customerAddress;
return $this;
}
public function setDataCrm($dataCrm)
{
$this->dataCrm = $dataCrm;
return $this;
}
/**
* @param int $idCustomer
* @return RetailcrmCustomerAddressBuilder
*/
public function setIdCustomer($idCustomer)
{
$this->idCustomer = $idCustomer;
return $this;
}
/**
* @param string $alias
* @return RetailcrmCustomerAddressBuilder
*/
public function setAlias($alias)
{
$this->alias = $alias;
return $this;
}
/**
* @param string $firstName
* @return RetailcrmCustomerAddressBuilder
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
return $this;
}
/**
* @param string $lastName
* @return RetailcrmCustomerAddressBuilder
*/
public function setLastName($lastName)
{
$this->lastName = $lastName;
return $this;
}
/**
* @param string $phone
* @return RetailcrmCustomerAddressBuilder
*/
public function setPhone($phone)
{
$this->phone = $phone;
return $this;
}
public function getData()
{
if (!empty($this->customerAddress)) {
return $this->customerAddress;
}
return array();
}
public function reset()
{
$this->customerAddress = new Address();
return $this;
}
public function build()
{
if (empty($this->customerAddress)) {
$this->customerAddress = new Address();
}
$this->customerAddress->id_customer = $this->idCustomer;
$this->customerAddress->alias = !empty($this->alias) ? $this->alias : 'default';
$this->customerAddress->lastname = $this->lastName;
$this->customerAddress->firstname = $this->firstName;
$this->customerAddress->address1 = isset($this->dataCrm['text']) ? $this->dataCrm['text'] : '--';
$this->customerAddress->id_country = isset($this->dataCrm['countryIso'])
? Country::getByIso($this->dataCrm['countryIso'])
: Configuration::get('PS_COUNTRY_DEFAULT');
if (isset($this->dataCrm['region'])) {
$state = State::getIdByName($this->dataCrm['region']);
if (!empty($state)) {
$this->customerAddress->id_state = $state;
}
}
$this->customerAddress->city = isset($this->dataCrm['city']) ? $this->dataCrm['city'] : '--';
$this->customerAddress->postcode = isset($this->dataCrm['index']) ? $this->dataCrm['index'] : '';
$this->customerAddress->phone = !empty($this->phone) ? $this->phone : '';
return $this;
}
}

View File

@ -0,0 +1,161 @@
<?php
/**
* MIT License
*
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
* @license https://opensource.org/licenses/MIT The MIT License
*
* Don't forget to prefix your containers with your own identifier
* to avoid any conflicts with others containers.
*/
class RetailcrmCustomerBuilder extends RetailcrmAbstractBuilder implements RetailcrmBuilderInterface
{
/** @var Customer|CustomerCore $customer Customer */
private $customer;
/** @var Address|AddressCore|null $customerAddress Address */
private $customerAddress;
/** @var array $dataCrm customerHistory */
protected $dataCrm;
/** @var RetailcrmBuilderInterface $addressBuilder Address builder */
private $addressBuilder;
public function __construct()
{
$this->reset();
}
/**
* @param Customer|CustomerCore $customer
* @return RetailcrmCustomerBuilder
*/
public function setCustomer($customer)
{
$this->customer = $customer;
return $this;
}
/**
* @param RetailcrmBuilderInterface $addressBuilder
* @return RetailcrmCustomerBuilder
*/
public function setAddressBuilder($addressBuilder)
{
$this->addressBuilder = $addressBuilder;
return $this;
}
public function setDataCrm($dataCrm)
{
$this->dataCrm = $dataCrm;
return $this;
}
public function getData()
{
return new RetailcrmCustomerBuilderResult($this->customer, $this->customerAddress);
}
public function reset()
{
$this->customer = new Customer();
$this->customerAddress = null;
$this->addressBuilder = null;
return $this;
}
/**
* Build address for customer
*/
public function buildAddress()
{
if (empty($this->addressBuilder)) {
$this->addressBuilder = new RetailcrmCustomerAddressBuilder();
}
if (isset($this->dataCrm['address'])) {
$this->addressBuilder
->setIdCustomer($this->arrayValue('externalId', 0))
->setDataCrm($this->dataCrm['address'])
->setFirstName($this->arrayValue('firstName'))
->setLastName($this->arrayValue('lastName'))
->setPhone( isset($this->dataCrm['phones'][0]['number'])
&& !empty($this->dataCrm['phones'][0]['number'])
? $this->dataCrm['phones'][0]['number'] : '')
->build();
$this->customerAddress = $this->addressBuilder->getData();
} else {
$this->customerAddress = null;
}
}
public function build()
{
if (isset($this->dataCrm['externalId'])) {
$this->customer->id = $this->dataCrm['externalId'];
}
$this->customer->firstname = $this->arrayValue('firstName');
$this->customer->lastname = $this->arrayValue('lastName');
if (isset($this->dataCrm['subscribed']) && $this->dataCrm['subscribed'] == false) {
$this->customer->newsletter = false;
}
if (empty($this->customer->id_shop)) {
$this->customer->id_shop = Context::getContext()->shop->id;
}
$this->customer->birthday = $this->arrayValue('birthday', '');
if (isset($this->dataCrm['sex'])) {
$this->customer->id_gender = $this->dataCrm['sex'] == 'male' ? 1 : 2;
}
$this->buildAddress();
if (isset($this->dataCrm['email']) && Validate::isEmail($this->dataCrm['email'])) {
$this->customer->email = $this->dataCrm['email'];
} else {
$this->customer->email = RetailcrmTools::createPlaceholderEmail($this->arrayValue('firstName', microtime()));
}
if (empty($this->customer->passwd )) {
$this->customer->passwd = Tools::substr(str_shuffle(Tools::strtolower(sha1(rand() . time()))), 0, 5);
}
return $this;
}
}

View File

@ -0,0 +1,74 @@
<?php
/**
* MIT License
*
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
* @license https://opensource.org/licenses/MIT The MIT License
*
* Don't forget to prefix your containers with your own identifier
* to avoid any conflicts with others containers.
*/
class RetailcrmCustomerBuilderResult
{
/** @var Customer|CustomerCore $customer */
private $customer;
/**@var Address|AddressCore|null $customerAddress */
private $customerAddress;
/**
* RetailcrmCustomerBuilderResult constructor.
*
* @param Customer|CustomerCore $customer
* @param Address|AddressCore|null $customerAddress
*/
public function __construct($customer, $customerAddress)
{
$this->customer = $customer;
$this->customerAddress = $customerAddress;
}
/**
* @return Customer|CustomerCore
*/
public function getCustomer()
{
return $this->customer;
}
/**
* @return Address|AddressCore|null
*/
public function getCustomerAddress()
{
return $this->customerAddress;
}
}

View File

@ -0,0 +1,447 @@
<?php
/**
* MIT License
*
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
* @license https://opensource.org/licenses/MIT The MIT License
*
* Don't forget to prefix your containers with your own identifier
* to avoid any conflicts with others containers.
*/
class RetailcrmCustomerSwitcher implements RetailcrmBuilderInterface
{
/**
* @var \RetailcrmCustomerSwitcherState $data
*/
private $data;
/**
* @var \RetailcrmCustomerSwitcherResult|null $result
*/
private $result;
/** @var bool $isContact */
private $isContact;
/**
* RetailcrmCustomerSwitcher constructor.
*/
public function __construct()
{
$this->reset();
}
/**
* In fact, this will execute customer change in provided order.
*
* @return $this|\RetailcrmBuilderInterface
*/
public function build()
{
$this->data->validate();
$this->debugLogState();
$newCustomer = $this->data->getNewCustomer();
$newContact = $this->data->getNewContact();
$newCompany = $this->data->getNewCompanyName();
$companyAddress = $this->data->getCompanyAddress();
if (!empty($newCustomer)) {
RetailcrmLogger::writeDebugArray(
__METHOD__,
array(
'Changing to individual customer for order',
$this->data->getOrder()->id
)
);
$this->isContact = false;
$this->processChangeToRegular($this->data->getOrder(), $newCustomer);
if (!empty($this->result)) {
$this->result->getAddress()->company = '';
}
} else {
if (!empty($newContact)) {
RetailcrmLogger::writeDebugArray(
__METHOD__,
array(
'Changing to contact person customer for order',
$this->data->getOrder()->id
)
);
$this->isContact = true;
$this->processChangeToRegular($this->data->getOrder(), $newContact);
}
if (!empty($newCompany)) {
RetailcrmLogger::writeDebug(
__METHOD__,
sprintf(
'Replacing old order id=`%d` company `%s` with new company `%s`',
$this->data->getOrder()->id,
self::getOrderCompany($this->data->getOrder()),
$newCompany
)
);
$this->processCompanyChange();
}
if (!empty($companyAddress)) {
$this->processCompanyAddress();
}
}
return $this;
}
/**
* Change order customer to regular one
*
* @param \Order $order
* @param array $newCustomer
*/
protected function processChangeToRegular($order, $newCustomer)
{
$customer = null;
$address = null;
$orderShippingAddress = $this->data->getCrmOrderShippingAddress();
if ((!isset($newCustomer['address']) || empty($newCustomer['address'])) && !empty($orderShippingAddress)) {
$newCustomer['address'] = $orderShippingAddress;
}
$builder = new RetailcrmCustomerBuilder();
$builder->setDataCrm($newCustomer);
RetailcrmLogger::writeDebugArray(
__METHOD__,
array(
'Switching in order',
$order->id,
'to',
$newCustomer
)
);
if (isset($newCustomer['externalId'])) {
RetailcrmLogger::writeDebug(__METHOD__, sprintf(
'Switching to existing customer id=%s',
$newCustomer['externalId']
));
$customer = new Customer($newCustomer['externalId']);
if (!empty($customer->id)) {
$order->id_customer = $customer->id;
$address = $this->getCustomerAddress($customer, $builder->build()->getData()->getCustomerAddress());
$this->processCustomerAddress($customer, $address);
} else {
RetailcrmLogger::writeDebug(__METHOD__, sprintf(
'Customer id=%s was not found, skipping...',
$newCustomer['externalId']
));
}
}
if (empty($customer) || empty($customer->id)) {
RetailcrmLogger::writeDebug(__METHOD__, "Customer wasn't found, generating new...");
$result = $builder->build()->getData();
$customer = $result->getCustomer();
$address = $this->getCustomerAddress($customer, $result->getCustomerAddress());
RetailcrmLogger::writeDebugArray(__METHOD__, array('Result:', array(
'customer' => RetailcrmTools::dumpEntity($customer),
'address' => RetailcrmTools::dumpEntity($address)
)));
}
$this->result = new RetailcrmCustomerSwitcherResult($customer, $address, $order);
}
/**
* Process company address.
*/
protected function processCompanyAddress()
{
$companyAddress = $this->data->getCompanyAddress();
$customer = $this->data->getOrder()->getCustomer();
$address = new Address($this->data->getOrder()->id_address_invoice);
if (!empty($companyAddress)) {
$firstName = '--';
$lastName = '--';
$billingPhone = $address->phone;
if (empty($billingPhone)) {
$billingPhone = $address->phone_mobile;
}
if (!empty($this->result)) {
$customer = $this->result->getCustomer();
}
if (empty($customer)) {
$customer = $this->data->getOrder()->getCustomer();
}
if (!empty($customer)) {
$firstName = !empty($customer->firstname) ? $customer->firstname : '--';
$lastName = !empty($customer->lastname) ? $customer->lastname : '--';
}
$builder = new RetailcrmCustomerAddressBuilder();
$address = $builder
->setDataCrm($companyAddress)
->setFirstName($firstName)
->setLastName($lastName)
->setPhone($billingPhone)
->setAlias('--')
->build()
->getData();
$address->company = $this->data->getNewCompanyName();
RetailcrmTools::assignAddressIdsByFields($customer, $address);
}
if (empty($this->result)) {
$this->result = new RetailcrmCustomerSwitcherResult($customer, $address, $this->data->getOrder());
} else {
$this->result->setAddress($address);
}
}
/**
* This will update company in the address.
*/
protected function processCompanyChange()
{
$customer = $this->data->getOrder()->getCustomer();
$address = new Address($this->data->getOrder()->id_address_invoice);
if (!empty($this->result)) {
$newAddress = $this->result->getAddress();
$newCustomer = $this->result->getCustomer();
if (!empty($newAddress) && empty($companyAddress)) {
$address = $newAddress;
}
if (!empty($newCustomer)) {
$customer = $newCustomer;
}
}
$oldId = $address->id;
$address->alias = '--';
$address->company = $this->data->getNewCompanyName();
RetailcrmTools::assignAddressIdsByFields($customer, $address);
if (empty($oldId) || $oldId == $address->id) {
$address->id = 0;
}
if (empty($this->result)) {
$this->result = new RetailcrmCustomerSwitcherResult($customer, $address, $this->data->getOrder());
}
}
/**
* @return $this|\RetailcrmBuilderInterface
*/
public function reset()
{
$this->data = new RetailcrmCustomerSwitcherState();
$this->result = null;
return $this;
}
/**
* Interface method implementation
*
* @param array $data
*
* @return $this|\RetailcrmBuilderInterface
*/
public function setDataCrm($data)
{
if (is_array($data)) {
$data = reset($data);
}
return $this->setData($data);
}
/**
* Set initial state into component
*
* @param \RetailcrmCustomerSwitcherState $data
*
* @return $this|\RetailcrmBuilderInterface
*/
public function setData($data)
{
if (!($data instanceof RetailcrmCustomerSwitcherState)) {
throw new \InvalidArgumentException('Invalid data type');
}
$this->data = $data;
return $this;
}
/**
* @return \RetailcrmCustomerSwitcherResult|null
*/
public function getResult()
{
return $this->result;
}
/**
* @return \RetailcrmCustomerSwitcherState
*/
public function getData()
{
return $this->data;
}
/**
* Debug log for component state
*/
private function debugLogState()
{
if (RetailcrmTools::isDebug()) {
RetailcrmLogger::writeDebugArray(__METHOD__, array('state', array(
'newCustomer' => $this->data->getNewCustomer(),
'newContact' => $this->data->getNewContact(),
'newCompanyName' => $this->data->getNewCompanyName(),
'companyAddress' => $this->data->getCompanyAddress(),
'order' => RetailcrmTools::dumpEntity($this->data->getOrder()),
)));
}
}
/**
* Returns placeholder address if customer hasn't one; returns address without any changes otherwise.
*
* @param \Customer|\CustomerCore $customer
* @param Address|\AddressCore|null $address
*
* @return \Address|\AddressCore|array|mixed
*/
private function getCustomerAddress($customer, $address)
{
if (empty($address)) {
if ($this->isContact) {
$address = $this->createPlaceholderAddress($customer, '--');
} else {
$address = $this->createPlaceholderAddress($customer);
}
}
return $address;
}
/**
* Process address fields for existing customer.
*
* @param Customer|\CustomerCore $customer
* @param Address|\AddressCore $address
*/
private function processCustomerAddress($customer, $address)
{
if ($this->isContact) {
$newCompany = $this->data->getNewCompanyName();
RetailcrmLogger::writeDebug(__METHOD__, 'Processing address for a contact person');
if ($address->alias == '' || $address->alias == 'default') {
$address->alias = '--';
}
if (!empty($newCompany)) {
$address->company = $newCompany;
} else {
$oldAddress = new Address($this->data->getOrder()->id_address_invoice);
if ($oldAddress->company) {
$address->company = $oldAddress->company;
}
}
RetailcrmTools::assignAddressIdsByFields($customer, $address);
RetailcrmLogger::writeDebug(__METHOD__, sprintf('Address id=%d', $address->id));
} else {
RetailcrmLogger::writeDebug(__METHOD__, 'Processing address for an individual');
RetailcrmTools::searchIndividualAddress($customer);
if (empty($address->id)) {
$address->alias = 'default';
RetailcrmTools::assignAddressIdsByFields($customer, $address);
}
RetailcrmLogger::writeDebug(__METHOD__, sprintf('Address id=%d', $address->id));
}
}
/**
* Builds placeholder address for customer if he doesn't have address.
*
* @param \Customer $customer
* @param string $alias
*
* @return \Address|\AddressCore|array|mixed
*/
private function createPlaceholderAddress($customer, $alias = 'default')
{
$addressBuilder = new RetailcrmCustomerAddressBuilder();
return $addressBuilder
->setIdCustomer($customer->id)
->setFirstName($customer->firstname)
->setLastName($customer->lastname)
->setAlias($alias)
->build()
->getData();
}
/**
* Returns company name from order.
*
* @param \Order $order
*
* @return string
*/
private static function getOrderCompany($order)
{
if (!empty($order) && !empty($order->id_address_invoice)) {
$address = new Address($order->id_address_invoice);
return $address->company;
}
return '';
}
}

View File

@ -76,137 +76,70 @@ class RetailcrmHistory
Configuration::updateValue('RETAILCRM_LAST_CUSTOMERS_SYNC', $end['id']);
$customersHistory = RetailcrmHistoryHelper::assemblyCustomer($historyChanges);
RetailcrmLogger::writeDebugArray(__METHOD__, array('Assembled history:', $customersHistory));
foreach ($customersHistory as $customerHistory) {
$syncAddressFIO = false;
if (isset($customerHistory['deleted']) && $customerHistory['deleted']) {
continue;
}
$customerBuilder = new RetailcrmCustomerBuilder();
$customerBuilder->setDataCrm($customerHistory);
if (isset($customerHistory['externalId'])) {
$customer = new Customer($customerHistory['externalId']);
$customerData = self::$api->customersGet($customerHistory['externalId'], 'externalId');
$foundCustomer = new Customer($customerHistory['externalId']);
$customerAddress = new Address(RetailcrmTools::searchIndividualAddress($foundCustomer));
$addressBuilder = new RetailcrmCustomerAddressBuilder();
if (isset($customerHistory['firstName'])) {
$customer->firstname = $customerHistory['firstName'];
}
$addressBuilder
->setCustomerAddress($customerAddress);
if (isset($customerHistory['lastName'])) {
$customer->lastname = $customerHistory['lastName'];
}
$customerBuilder
->setCustomer($foundCustomer)
->setAddressBuilder($addressBuilder)
->setDataCrm($customerData['customer'])
->build();
if (isset($customerHistory['birthday'])) {
$customer->birthday = $customerHistory['birthday'];
}
if (isset($customerHistory['email']) && Validate::isEmail($customerHistory['email'])) {
$customer->email = $customerHistory['email'];
}
if (empty($customer->passwd)) {
$customer->passwd = md5(time());
}
// Only sync subscription status if customer was marked as unsubscribed in retailCRM.
if (isset($customerHistory['subscribed']) && $customerHistory['subscribed'] == false) {
$customer->newsletter = false;
}
$customer = $customerBuilder->getData()->getCustomer();
$address = $customerBuilder->getData()->getCustomerAddress();
if (self::loadInCMS($customer, 'update') === false) {
continue;
}
if ($syncAddressFIO) {
$customerAddresses = $customer->getAddresses(static::$default_lang);
if (!empty($address)) {
RetailcrmTools::assignAddressIdsByFields($customer, $address);
foreach ($customerAddresses as $addressArray) {
if (isset($addressArray['alias']) && $addressArray['alias'] == 'default') {
$cmsAddress = new Address($addressArray['id_address']);
$cmsAddress->firstname = $customer->firstname;
$cmsAddress->lastname = $customer->lastname;
self::loadInCMS($cmsAddress, 'update');
break;
}
if (self::loadInCMS($address, 'update') === false) {
continue;
}
}
} else {
if (!isset($customerHistory['firstName'])) {
continue;
}
$customerBuilder->build();
$customer = new Customer();
$customer->firstname = $customerHistory['firstName'];
$customer->lastname = isset($customerHistory['lastName']) ? $customerHistory['lastName'] : '--';
$customer->id_lang = self::$default_lang;
$customer->newsletter = false;
if (isset($customerHistory['birthday'])) {
$customer->birthday = $customerHistory['birthday'];
}
if (isset($customerHistory['sex'])) {
$customer->id_gender = $customerHistory['sex'] == 'male' ? 1 : 2;
}
if (isset($customerHistory['email']) && Validate::isEmail($customerHistory['email'])) {
$customer->email = $customerHistory['email'];
} else {
$customer->email = RetailcrmTools::createPlaceholderEmail($customerHistory['firstName']);
}
$customer->passwd = Tools::substr(str_shuffle(Tools::strtolower(sha1(rand() . time()))), 0, 5);
$customer = $customerBuilder->getData()->getCustomer();
if (self::loadInCMS($customer, 'add') === false) {
continue;
}
if (isset($customerHistory['address'])) {
$customerAddress = new Address();
$customerAddress->id_customer = $customer->id;
$customerAddress->alias = 'default';
$customerAddress->lastname = $customer->lastname;
$customerAddress->firstname = $customer->firstname;
if (isset($customerHistory['address']['countryIso'])) {
$customerAddress->id_country = Country::getByIso($customerHistory['address']['countryIso']);
}
if (isset($customerHistory['address']['region'])) {
$customerAddress->id_state = State::getIdByName($customerHistory['address']['region']);
}
$customerAddress->city = isset($customerHistory['address']['city']) ? $customerHistory['address']['city'] : '--';
$customerAddress->address1 = isset($customerHistory['address']['text']) ? $customerHistory['address']['text'] : '--';
if (isset($customerHistory['phones'])) {
// Can be returned as string, beware!
if (is_array($customerHistory['phones'])) {
$phone = reset($customerHistory['phones']);
} else {
$phone = $customerHistory['phones'];
}
$customerAddress->phone = $phone['number'];
}
if (isset($customerHistory['address']['index'])) {
$customerAddress->postcode = $customerHistory['address']['index'];
}
if (self::loadInCMS($customerAddress, 'add') === false) {
continue;
}
}
$customerFix[] = array(
'id' => $customerHistory['id'],
'externalId' => $customer->id
);
$customer->update();
if (isset($customerHistory['address'])) {
$address = $customerBuilder->getData()->getCustomerAddress();
$address->id_customer = $customer->id;
if (self::loadInCMS($address, 'add') === false) {
continue;
}
}
}
}
@ -230,7 +163,6 @@ class RetailcrmHistory
public static function ordersHistory()
{
$default_currency = (int) Configuration::get('PS_CURRENCY_DEFAULT');
$default_country = (int) Configuration::get('PS_COUNTRY_DEFAULT');
$lastSync = Configuration::get('RETAILCRM_LAST_ORDERS_SYNC');
$lastDate = Configuration::get('RETAILCRM_LAST_SYNC');
@ -279,6 +211,7 @@ class RetailcrmHistory
$deliveryDefault = json_decode(Configuration::get('RETAILCRM_API_DELIVERY_DEFAULT'), true);
$paymentDefault = json_decode(Configuration::get('RETAILCRM_API_PAYMENT_DEFAULT'), true);
$orders = RetailcrmHistoryHelper::assemblyOrder($historyChanges);
RetailcrmLogger::writeDebugArray(__METHOD__, array('Assembled history:', $orders));
foreach ($orders as $order_history) {
if (isset($order_history['deleted']) && $order_history['deleted'] == true) {
@ -374,8 +307,9 @@ class RetailcrmHistory
}
}
$address = new Address();
$customer = null;
$customerId = null;
$builtFromContact = false;
if ($order['customer']['type'] == 'customer_corporate'
&& RetailcrmTools::isCorporateEnabled()
@ -387,126 +321,93 @@ class RetailcrmHistory
}
if (empty($customerId) && !empty($order['contact']['email'])) {
$customerData = Customer::getCustomersByEmail($order['contact']['email']);
$customerData = is_array($customerData) ? reset($customerData) : array();
$customer = Customer::getCustomersByEmail($order['contact']['email']);
$customer = is_array($customer) ? reset($customer) : array();
if (array_key_exists('id_customer', $customerData)) {
$customerId = $customerData['id_customer'];
if (array_key_exists('id_customer', $customer)) {
$customerId = $customer['id_customer'];
}
}
} elseif (array_key_exists('externalId', $order['customer'])) {
$customerId = Customer::customerIdExistsStatic($order['customer']['externalId']);
$customerBuilder = new RetailcrmCustomerBuilder();
$customerBuilder->setCustomer(new Customer($customerId));
}
if (empty($customerId)) {
$firstName = '';
$lastName = '';
$email = '';
if (!empty($order['company']) && RetailcrmTools::isCorporateEnabled()) {
$corporateCustomerBuilder = new RetailcrmCorporateCustomerBuilder();
$dataOrder = array_merge(
$order['contact'],
array('address' => $order['company']['address'])
);
if ($order['customer']['type'] == 'customer_corporate') {
if (!empty($order['contact'])) {
$contact = $order['contact'];
$firstName = $contact['firstName'];
$lastName = !empty($contact['lastName']) ? $contact['lastName'] : '--';
$email =
Validate::isEmail(isset($contact['email']) ? $contact['email'] : '')
? $contact['email']
: RetailcrmTools::createPlaceholderEmail($contact['firstName']);
$builtFromContact = true;
} elseif (!empty($order['customer']['nickName'])) {
$firstName = $order['customer']['nickName'];
$lastName = '--';
$email = Validate::isEmail(
isset($order['customer']['email']) ? $order['customer']['email'] : ''
$corporateCustomerBuilder
->setCustomer(new Customer($customerId))
->setDataCrm($dataOrder)
->extractCompanyDataFromOrder($order)
->build();
$customer = $corporateCustomerBuilder->getData()->getCustomer();
$address = $corporateCustomerBuilder->getData()->getCustomerAddress();
} else {
$customerBuilder = new RetailcrmCustomerBuilder();
$customerBuilder
->setDataCrm($order['customer'])
->build();
$customer = $customerBuilder->getData()->getCustomer();
if (!empty($address)) {
$address = $customerBuilder->getData()->getCustomerAddress();
}
}
if (!empty($customer->email)) {
$customer->id = self::getCustomerIdByEmail($customer->email);
}
if (self::loadInCMS($customer, 'save') === false) {
continue;
}
if (!empty($address)) {
$address->id_customer = $customer->id;
RetailcrmTools::assignAddressIdsByFields($customer, $address);
if (empty($address->id)) {
RetailcrmLogger::writeDebug(
__METHOD__,
sprintf(
'<Customer ID: %d> %s::%s',
$address->id_customer,
get_class($address),
'add'
)
? $order['customer']['email']
: RetailcrmTools::createPlaceholderEmail($order['customer']['nickName']);
);
$address->add();
if (!empty($order['company']) && RetailcrmTools::isCorporateEnabled()) {
self::$api->customersCorporateAddressesEdit(
$order['customer']['id'],
$order['company']['address']['id'],
array_merge($order['company']['address'], array('externalId' => $address->id)),
'id',
'id'
);
time_nanosleep(0, 20000000);
}
} else {
$firstName = $order['customer']['firstName'];
$lastName = !empty($order['customer']['lastName'])
? $order['customer']['lastName']
: '--';
$email = Validate::isEmail(
isset($order['customer']['email']) ? $order['customer']['email'] : ''
)
? $order['customer']['email']
: RetailcrmTools::createPlaceholderEmail($order['customer']['firstName']);
RetailcrmLogger::writeDebug(
__METHOD__,
sprintf('<%d> %s::%s', $address->id, get_class($address), 'save')
);
$address->save();
}
/** @var Customer|\CustomerCore $customer */
$customer = new Customer();
$customer->firstname = $firstName;
$customer->lastname = $lastName;
$customer->email = $email;
$customer->passwd = Tools::substr(
str_shuffle(Tools::strtolower(sha1(rand() . time()))),
0,
5
);
if (self::loadInCMS($customer, 'add') === false) {
continue;
}
array_push(
$customerFix,
array(
'id' => $builtFromContact ? $order['contact']['id'] : $order['customer']['id'],
'externalId' => $customer->id
)
);
} else {
/** @var Customer|\CustomerCore $customer */
$customer = new Customer($customerId);
}
/** @var Address|\AddressCore $address */
$address = new Address();
$address->id_customer = $customer->id;
$address->id_country = $default_country;
$address->lastname = $customer->lastname;
$address->firstname = $customer->firstname;
$address->alias = 'default';
$address->postcode = isset($order['delivery']['address']['index']) ? $order['delivery']['address']['index'] : '--';
$address->city = !empty($order['delivery']['address']['city']) ?
$order['delivery']['address']['city'] : '--';
$address->address1 = !empty($order['delivery']['address']['text']) ?
$order['delivery']['address']['text'] : '--';
$address->phone = isset($order['phone']) ? $order['phone'] : '';
if (!empty($order['company'])
&& !empty($order['company']['contragent'])
&& !empty($order['company']['contragent']['legalName'])
) {
$address->company = $order['company']['contragent']['legalName'];
if (!empty($order['company']['contragent']['INN'])) {
$address->vat_number = $order['company']['contragent']['INN'];
}
}
static::assignAddressIdByFields($customer, $address);
if (empty($address->id)) {
RetailcrmLogger::writeDebug(
__METHOD__,
sprintf(
'<Customer ID: %d> %s::%s',
$address->id_customer,
get_class($address),
'add'
)
);
$address->add();
} else {
RetailcrmLogger::writeDebug(
__METHOD__,
sprintf('<%d> %s::%s', $address->id, get_class($address), 'save')
);
$address->save();
}
$cart = new Cart();
@ -538,7 +439,6 @@ class RetailcrmHistory
}
$productId = explode('#', $item['offer']['externalId']);
$product = array();
$product['id_product'] = (int) $productId[0];
$product['id_product_attribute'] = !empty($productId[1]) ? $productId[1] : 0;
@ -576,13 +476,16 @@ class RetailcrmHistory
$newOrder->id_currency = $default_currency;
$newOrder->id_lang = self::$default_lang;
$newOrder->id_customer = (int) $customer->id;
if (isset($deliveryType)) {
$newOrder->id_carrier = (int) $deliveryType;
}
if (isset($paymentType)) {
$newOrder->payment = $paymentType;
$newOrder->module = $paymentId;
}
$newOrder->total_paid = $order['summ'] + $order['delivery']['cost'];
$newOrder->total_paid_tax_incl = $order['summ'] + $order['delivery']['cost'];
$newOrder->total_paid_tax_excl = $order['summ'] + $order['delivery']['cost'];
@ -593,6 +496,7 @@ class RetailcrmHistory
$newOrder->total_shipping_tax_incl = $order['delivery']['cost'];
$newOrder->total_shipping_tax_excl = $order['delivery']['cost'];
$newOrder->conversion_rate = 1.000000;
if (isset($orderStatus)) {
$newOrder->current_state = (int) $orderStatus;
$newOrderHistoryRecord = new OrderHistory(
@ -601,9 +505,11 @@ class RetailcrmHistory
Context::getContext()->shop->id
);
}
if (!empty($order['delivery']['date'])) {
$newOrder->delivery_date = $order['delivery']['date'];
}
$newOrder->date_add = $order['createdAt'];
$newOrder->date_upd = $order['createdAt'];
$newOrder->invoice_date = $order['createdAt'];
@ -705,6 +611,7 @@ class RetailcrmHistory
__METHOD__,
sprintf('Error adding order id=%d: %s', $order['id'], $e->getMessage())
);
RetailcrmLogger::writeNoCaller($e->getTraceAsString());
}
@ -716,6 +623,7 @@ class RetailcrmHistory
) {
$ptype = $payment['type'];
$ptypes = $references->getSystemPaymentModules();
if ($payments[$ptype] != null) {
foreach ($ptypes as $pay) {
if ($pay['code'] == $payments[$ptype]) {
@ -763,7 +671,6 @@ class RetailcrmHistory
);
$carrier->add(false, false);
/*
* collect order ids for single fix request
*/
@ -773,11 +680,13 @@ class RetailcrmHistory
* Create order details
*/
$orderDetail = new OrderDetail();
$orderDetail->createList($newOrder, $cart, $newOrder->current_state, $product_list);
if (!empty($customerFix)) {
self::$api->customersFixExternalIds($customerFix);
}
if (!empty($orderFix)) {
self::$api->ordersFixExternalIds($orderFix);
}
@ -793,6 +702,38 @@ class RetailcrmHistory
}
$orderToUpdate = new Order((int) $order['externalId']);
self::handleCustomerDataChange($orderToUpdate, $order);
/*
* check delivery changes
*/
if (isset($order['status']) && isset($order['delivery'])) {
if ($order['status'] == 'new') {
$customerData = self::$api->customersGet($orderToUpdate->id_customer, 'externalId');
$customerForAddress = $customerData['customer'];
$customerBuilder = new RetailcrmCustomerBuilder();
if (isset($customerData['customer']['address'])) {
$customerForAddress['address'] = array_replace(
$customerData['customer']['address'],
$order['delivery']['address']
);
} else {
$customerForAddress['address'] = $order['delivery']['address'];
}
$customerBuilder
->setDataCrm($customerForAddress)
->build();
$address = $customerBuilder->getData()->getCustomerAddress();
$address->id = $orderToUpdate->id_address_delivery;
$address->update();
$orderToUpdate->update();
}
}
/*
* check delivery type
@ -946,6 +887,175 @@ class RetailcrmHistory
}
}
/**
* Returns retailCRM order by id or by externalId.
* It returns only order data, not ApiResponse or something.
*
* @param string $id Order identifier
* @param string $by Search field (default: 'externalId')
*
* @return array
*/
protected static function getCRMOrder($id, $by = 'externalId')
{
$crmOrderResponse = self::$api->ordersGet($id, $by);
if (!empty($crmOrderResponse)
&& $crmOrderResponse->isSuccessful()
&& $crmOrderResponse->offsetExists('order')
) {
return (array) $crmOrderResponse['order'];
}
return array();
}
/**
* Sets all needed data for customer switch to switcher state
*
* @param array $crmCustomer
* @param \RetailcrmCustomerSwitcherState $data
* @param bool $isContact
*/
protected static function prepareChangeToIndividual($crmCustomer, $data, $isContact = false)
{
RetailcrmLogger::writeDebugArray(
__METHOD__,
array(
'Using this individual person data in order to set it into order,',
$data->getOrder()->id,
': ',
$crmCustomer
)
);
if ($isContact) {
$data->setNewContact($crmCustomer);
} else {
$data->setNewCustomer($crmCustomer);
}
}
/**
* Handle customer data change (from individual to corporate, company change, etc)
*
* @param \Order $order
* @param array $historyOrder
*
* @return bool True if customer change happened; false otherwise.
*/
private static function handleCustomerDataChange($order, $historyOrder)
{
$handled = false;
$crmOrder = array();
$newCustomerId = null;
$switcher = new RetailcrmCustomerSwitcher();
$data = new RetailcrmCustomerSwitcherState();
$data->setOrder($order);
RetailcrmLogger::writeDebug(
__METHOD__,
$historyOrder
);
if (isset($historyOrder['customer'])) {
$crmOrder = self::getCRMOrder($historyOrder['id'], 'id');
if (empty($crmOrder)) {
RetailcrmLogger::writeCaller(__METHOD__, sprintf(
'Cannot get order data from retailCRM. Skipping customer change. History data: %s',
print_r($historyOrder, true)
));
return false;
}
$newCustomerId = $historyOrder['customer']['id'];
$isChangedToRegular = RetailcrmTools::isCustomerChangedToRegular($historyOrder);
$isChangedToCorporate = RetailcrmTools::isCustomerChangedToLegal($historyOrder);
if (!$isChangedToRegular && !$isChangedToCorporate) {
$isChangedToCorporate = RetailcrmTools::isCrmOrderCorporate($crmOrder);
$isChangedToRegular = !$isChangedToCorporate;
}
if ($isChangedToRegular) {
self::prepareChangeToIndividual(
RetailcrmTools::arrayValue($crmOrder, 'customer', array()),
$data
);
}
}
if (isset($historyOrder['contact'])) {
$newCustomerId = $historyOrder['contact']['id'];
if (empty($crmOrder)) {
$crmOrder = self::getCRMOrder($historyOrder['id'], 'id');
}
if (empty($crmOrder)) {
RetailcrmLogger::writeCaller(__METHOD__, sprintf(
'Cannot get order data from retailCRM. Skipping customer change. History data: %s',
print_r($historyOrder, true)
));
return false;
}
if (RetailcrmTools::isCrmOrderCorporate($crmOrder)) {
self::prepareChangeToIndividual(
RetailcrmTools::arrayValue($crmOrder, 'contact', array()),
$data,
true
);
$data->setNewCustomer(array());
}
}
if (isset($historyOrder['company'])) {
if (!empty($crmOrder['company'])) {
$data->setNewCompany($crmOrder['company']);
} else {
$data->setNewCompany($historyOrder['company']);
}
}
if (!empty($crmOrder) && !empty($crmOrder['delivery']) && !empty($crmOrder['delivery']['address'])) {
$data->setCrmOrderShippingAddress($crmOrder['delivery']['address']);
}
if ($data->feasible()) {
try {
$result = $switcher->setData($data)
->build()
->getResult();
$result->save();
$handled = true;
} catch (\Exception $exception) {
$errorMessage = sprintf(
'Error switching order externalId=%s to customer id=%s (new company: id=%s %s). Reason: %s',
$historyOrder['externalId'],
$newCustomerId,
isset($historyOrder['company']) ? $historyOrder['company']['id'] : '',
isset($historyOrder['company']) ? $historyOrder['company']['name'] : '',
$exception->getMessage()
);
RetailcrmLogger::writeCaller(__METHOD__, $errorMessage);
RetailcrmLogger::writeDebug(__METHOD__, sprintf(
'%s%s%s',
$errorMessage,
PHP_EOL,
$exception->getTraceAsString()
));
$handled = false;
}
}
return $handled;
}
/**
* Updates items in order via history
*
@ -1191,6 +1301,7 @@ class RetailcrmHistory
);
$orderdb = new Order($orderDetail->id_order);
foreach ($orderdb->getProducts() as $item) {
if (isset($item['product_attribute_id']) && $item['product_attribute_id'] > 0) {
$productId = $item['product_id'] . '#' . $item['product_attribute_id'];
@ -1321,29 +1432,28 @@ class RetailcrmHistory
*/
private static function loadInCMS($object, $action)
{
$prefix = $object->id;
if (empty($object->id)) {
if (property_exists(get_class($object), 'id_customer')) {
$prefix = sprintf('Customer ID: %d', $object->id_customer);
}
if (property_exists(get_class($object), 'id_order')) {
$prefix = sprintf('Order ID: %d', $object->id_order);
}
}
RetailcrmLogger::writeDebug(
__METHOD__,
sprintf(
'<%s> %s::%s',
$prefix,
get_class($object),
$action
)
);
try {
$prefix = $object->id;
if (empty($object->id)) {
if (property_exists(get_class($object), 'id_customer')) {
$prefix = sprintf('Customer ID: %d', $object->id_customer);
}
if (property_exists(get_class($object), 'id_order')) {
$prefix = sprintf('Order ID: %d', $object->id_order);
}
}
RetailcrmLogger::writeDebug(
__METHOD__,
sprintf(
'<%s> %s::%s',
$prefix,
get_class($object),
$action
)
);
$object->$action();
} catch (PrestaShopException $e) {
RetailcrmLogger::writeCaller(
@ -1432,42 +1542,25 @@ class RetailcrmHistory
}
/**
* Assign address ID from customer addresses
* Returns customer ID by email if such customer was found in the DB.
*
* @param Customer|CustomerCore $customer
* @param Address|\AddressCore $address
* @param string $customerEmail
*
* @return int
*/
private static function assignAddressIdByFields($customer, &$address)
private static function getCustomerIdByEmail($customerEmail)
{
$checkMapping = array(
'id_customer',
'id_country',
'lastname',
'firstname',
'alias',
'postcode',
'city',
'address1',
'phone',
'company',
'vat_number'
);
if (!empty($customerEmail)) {
$item = Customer::getCustomersByEmail($customerEmail);
// Assigns id to $address if same address was found in customer
foreach ($customer->getAddresses(static::$default_lang) as $customerInnerAddress) {
/** @var Address|\AddressCore $customerAddress */
$customerAddress = new Address($customerInnerAddress['id_address']);
if (is_array($item) && count($item) > 0) {
$item = reset($item);
foreach ($checkMapping as $field) {
if ($customerAddress->$field != $address->$field) {
continue 2;
}
return (int) $item['id_customer'];
}
$address->id = $customerInnerAddress['id_address'];
break;
}
return 0;
}
/**
@ -1582,3 +1675,4 @@ class RetailcrmHistory
}
}
}

View File

@ -204,6 +204,11 @@ class RetailcrmHistoryHelper {
$customers[$change['customer']['id']]['subscribed'] = true;
}
}
// Sometimes address can be found in this key.
if (isset($change['address'])) {
$customers[$change['customer']['id']]['address'] = $change['address'];
}
}
return $customers;

View File

@ -172,7 +172,9 @@ class RetailcrmJobManager
$lastRuns[$job] = new \DateTime('now');
}
} catch (\Exception $exception) {
if ($exception instanceof RetailcrmJobManagerException && !empty($exception->getPrevious())) {
if ($exception instanceof RetailcrmJobManagerException
&& $exception->getPrevious() instanceof \Exception
) {
static::handleError(
$exception->getPrevious()->getFile(),
$exception->getPrevious()->getMessage(),
@ -189,10 +191,10 @@ class RetailcrmJobManager
}
self::clearCurrentJob($job);
} finally {
if (isset($result) && $result) {
self::clearCurrentJob($job);
}
}
if (isset($result) && $result) {
self::clearCurrentJob($job);
}
}
@ -393,20 +395,25 @@ class RetailcrmJobManager
}
}
/**
* Wrapper for shutdown handler. Moved here in order to keep compatibility with older PHP versions.
*/
public static function shutdownHandlerWrapper()
{
$error = error_get_last();
if(null !== $error && $error['type'] === E_ERROR) {
self::defaultShutdownHandler($error);
}
}
/**
* Register default shutdown handler (should be be called before any job execution)
*/
private static function registerShutdownHandler()
{
if (!self::$shutdownHandlerRegistered) {
register_shutdown_function(function() {
$error = error_get_last();
if(null !== $error && $error['type'] === E_ERROR) {
self::defaultShutdownHandler($error);
}
});
register_shutdown_function(array('RetailcrmJobManager', 'shutdownHandlerWrapper'));
self::$shutdownHandlerRegistered = true;
}
}

View File

@ -139,6 +139,32 @@ class RetailcrmLogger
}
}
/**
* Debug log record with multiple entries
*
* @param string $caller
* @param array|string $messages
*/
public static function writeDebugArray($caller, $messages)
{
if (RetailcrmTools::isDebug()) {
if (!empty($caller) && !empty($messages)) {
$result = is_array($messages) ? substr(
array_reduce(
$messages,
function ($carry, $item) {
$carry .= ' ' . print_r($item, true);
return $carry;
}
),
1
) : $messages;
self::writeDebug($caller, $result);
}
}
}
/**
* Returns log file path
*

View File

@ -42,6 +42,21 @@ class RetailcrmTools
*/
static $currentStatusCode;
/** @var int */
public static $default_lang;
/**
* @return int
*/
public static function defaultLang()
{
if (empty(self::$default_lang)) {
self::$default_lang = (int) Configuration::get('PS_LANG_DEFAULT');
}
return self::$default_lang;
}
/**
* Returns true if corporate customers are enabled in settings
*
@ -59,7 +74,7 @@ class RetailcrmTools
*
* @return bool
*/
public static function isCustomerCorporate(Customer $customer)
public static function isCustomerCorporate($customer)
{
$addresses = $customer->getAddresses((int)Configuration::get('PS_LANG_DEFAULT'));
@ -92,6 +107,38 @@ class RetailcrmTools
return $address instanceof Address && !empty($address->company);
}
/**
* Returns true if provided crm order is corporate
*
* @param array $order
*
* @return bool
*/
public static function isCrmOrderCorporate($order)
{
return isset($order['customer']['type']) && $order['customer']['type'] == 'customer_corporate';
}
/**
* Search address for individual customer (not corporate one)
*
* @param Customer|CustomerCore $customer
*
* @return int
*/
public static function searchIndividualAddress($customer)
{
if (!empty($customer->id)) {
foreach ($customer->getAddresses(self::defaultLang()) as $addressArray) {
if ($addressArray['alias'] == 'default') {
return (int) $addressArray['id_address'];
}
}
}
return 0;
}
/**
* Returns 'true' if provided date string is valid
*
@ -132,6 +179,44 @@ class RetailcrmTools
return $ids;
}
/**
* Dumps entity using it's definition mapping.
*
* @param \ObjectModel $object
*
* @return array|string
*/
public static function dumpEntity($object)
{
if (empty($object)) {
ob_start();
var_dump($object);
return (string) ob_get_clean();
}
$data = array();
$type = get_class($object);
if (property_exists($type, 'definition')) {
$defs = $type::$definition;
if (!empty($defs['fields'])) {
if (property_exists($object, 'id')) {
$data['id'] = $object->id;
}
foreach (array_keys($defs['fields']) as $field) {
if (property_exists($object, $field)) {
$data[$field] = $object->$field;
}
}
}
}
return $data;
}
/**
* Converts CMS address to CRM address
*
@ -466,6 +551,78 @@ class RetailcrmTools
return $code;
}
/**
* This assertion returns true if customer was changed from legal entity to individual person.
* It doesn't return true if customer was changed from one individual person to another.
*
* @param array $assembledOrder Order data, assembled from history
*
* @return bool True if customer in order was changed from corporate to regular
*/
public static function isCustomerChangedToRegular($assembledOrder)
{
return isset($assembledOrder['contragentType']) && $assembledOrder['contragentType'] == 'individual';
}
/**
* This assertion returns true if customer was changed from individual person to a legal entity.
* It doesn't return true if customer was changed from one legal entity to another.
*
* @param array $assembledOrder Order data, assembled from history
*
* @return bool True if customer in order was changed from corporate to regular
*/
public static function isCustomerChangedToLegal($assembledOrder)
{
return isset($assembledOrder['contragentType']) && $assembledOrder['contragentType'] == 'legal-entity';
}
/**
* Get value by key from array if it exists, returns default value otherwise.
*
* @param array|\ArrayObject|\ArrayAccess $arr
* @param string $key
* @param string $def
*
* @return mixed|string
*/
public static function arrayValue($arr, $key, $def = '')
{
if (!is_array($arr) && !($arr instanceof ArrayObject) && !($arr instanceof ArrayAccess)) {
return $def;
}
if (!array_key_exists($key, $arr) && !empty($arr[$key])) {
return $def;
}
return isset($arr[$key]) ? $arr[$key] : $def;
}
/**
* Assign address ID and customer ID from customer addresses.
* Customer ID in the address isn't checked (it will be set to id from provided customer, even if it doesn't have ID yet).
*
* @param Customer|CustomerCore $customer
* @param Address|\AddressCore $address
*/
public static function assignAddressIdsByFields($customer, $address)
{
RetailcrmLogger::writeDebugArray(__METHOD__, array('Called with customer', $customer->id, 'and address', self::dumpEntity($address)));
foreach ($customer->getAddresses(self::defaultLang()) as $customerInnerAddress) {
$customerAddress = new Address($customerInnerAddress['id_address']);
if (self::isAddressesEqualByFields($address, $customerAddress)) {
if ($address->id_customer != $customerAddress->id_customer) {
$address->id_customer = $customerAddress->id_customer;
}
$address->id = $customerAddress->id;
}
}
}
/**
* Starts JobManager with list of pre-registered jobs
*
@ -480,4 +637,47 @@ class RetailcrmTools
'RetailcrmInventoriesEvent' => new \DateInterval('PT15M')
));
}
/**
* Returns true if mapped fields in address are equal. Returns false otherwise.
*
* @param \Address $first
* @param \Address $second
*
* @return bool
*/
protected static function isAddressesEqualByFields($first, $second)
{
$equal = true;
$checkMapping = array(
'alias',
'id_country',
'lastname',
'firstname',
'postcode',
'city',
'address1',
'phone',
'company',
'vat_number'
);
foreach ($checkMapping as $field) {
if ($first->$field != $second->$field) {
$equal = false;
RetailcrmLogger::writeDebugArray(__METHOD__, array(
'first' => self::dumpEntity($first),
'second' => self::dumpEntity($second),
'field' => array(
'name' => $field,
'firstValue' => $first->$field,
'secondValue' => $second->$field
)
));
break;
}
}
return $equal;
}
}

View File

@ -0,0 +1,142 @@
<?php
/**
* MIT License
*
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
* @license https://opensource.org/licenses/MIT The MIT License
*
* Don't forget to prefix your containers with your own identifier
* to avoid any conflicts with others containers.
*/
class RetailcrmCustomerSwitcherResult
{
/** @var \Customer */
private $customer;
/** @var \Address */
private $address;
/** @var \Order $order */
private $order;
/**
* RetailcrmCustomerSwitcherResult constructor.
*
* @param \Customer $customer
* @param \Address $address
* @param \Order $order
*/
public function __construct($customer, $address, $order)
{
$this->customer = $customer;
$this->order = $order;
$this->address = $address;
if (!($this->customer instanceof Customer) || !($this->order instanceof Order)) {
throw new \InvalidArgumentException(sprintf('Incorrect data provided to %s', __CLASS__));
}
}
/**
* @return \Customer
*/
public function getCustomer()
{
return $this->customer;
}
/**
* @return \Address
*/
public function getAddress()
{
return $this->address;
}
/**
* @param \Address $address
*
* @return RetailcrmCustomerSwitcherResult
*/
public function setAddress($address)
{
$this->address = $address;
return $this;
}
/**
* @return \Order
*/
public function getOrder()
{
return $this->order;
}
/**
* Save customer (if exists) and order.
*
* @return $this
* @throws \PrestaShopException
*/
public function save()
{
RetailcrmLogger::writeDebugArray(
__METHOD__,
array(
'Saving customer, address and order:',
array(
'customer' => RetailcrmTools::dumpEntity($this->customer),
'address' => RetailcrmTools::dumpEntity($this->address),
'order' => RetailcrmTools::dumpEntity($this->order)
)
)
);
if (!empty($this->customer)) {
$this->customer->save();
if (!empty($this->address) && !empty($this->customer->id)) {
$this->address->id_customer = $this->customer->id;
$this->address->save();
if (!empty($this->order) && !empty($this->address->id)) {
$this->order->id_customer = $this->customer->id;
$this->order->id_address_invoice = $this->address->id;
$this->order->id_address_delivery = $this->address->id;
$this->order->save();
} else {
$this->address->delete();
}
}
}
return $this;
}
}

View File

@ -0,0 +1,231 @@
<?php
/**
* MIT License
*
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
* @license https://opensource.org/licenses/MIT The MIT License
*
* Don't forget to prefix your containers with your own identifier
* to avoid any conflicts with others containers.
*/
class RetailcrmCustomerSwitcherState
{
/** @var \Order $order */
private $order;
/** @var array */
private $newCustomer;
/** @var array */
private $newContact;
/** @var string $newCompanyName */
private $newCompanyName;
/** @var array $companyAddress */
private $companyAddress;
/** @var array $crmOrderShippingAddress */
private $crmOrderShippingAddress;
/**
* @return \Order
*/
public function getOrder()
{
return $this->order;
}
/**
* @param \Order $order
*
* @return RetailcrmCustomerSwitcherState
*/
public function setOrder($order)
{
$this->order = $order;
return $this;
}
/**
* @return array
*/
public function getNewCustomer()
{
return $this->newCustomer;
}
/**
* @param array $newCustomer
*
* @return RetailcrmCustomerSwitcherState
*/
public function setNewCustomer($newCustomer)
{
$this->newCustomer = $newCustomer;
return $this;
}
/**
* @return array
*/
public function getNewContact()
{
return $this->newContact;
}
/**
* @param array $newContact
*
* @return RetailcrmCustomerSwitcherState
*/
public function setNewContact($newContact)
{
$this->newContact = $newContact;
return $this;
}
/**
* @return string
*/
public function getNewCompanyName()
{
return $this->newCompanyName;
}
/**
* @param string $newCompanyName
*
* @return RetailcrmCustomerSwitcherState
*/
public function setNewCompanyName($newCompanyName)
{
$this->newCompanyName = $newCompanyName;
return $this;
}
/**
* @return array
*/
public function getCompanyAddress()
{
return $this->companyAddress;
}
/**
* @param array $companyAddress
*
* @return RetailcrmCustomerSwitcherState
*/
public function setCompanyAddress($companyAddress)
{
$this->companyAddress = $companyAddress;
return $this;
}
/**
* @param array $newCompany
*
* @return RetailcrmCustomerSwitcherState
*/
public function setNewCompany($newCompany)
{
if (isset($newCompany['name'])) {
$this->setNewCompanyName($newCompany['name']);
}
if (isset($newCompany['address']) && !empty($newCompany['address'])) {
$this->setCompanyAddress($newCompany['address']);
}
return $this;
}
/**
* @return array
*/
public function getCrmOrderShippingAddress()
{
return $this->crmOrderShippingAddress;
}
/**
* @param array $crmOrderShippingAddress
*
* @return RetailcrmCustomerSwitcherState
*/
public function setCrmOrderShippingAddress($crmOrderShippingAddress)
{
$this->crmOrderShippingAddress = $crmOrderShippingAddress;
return $this;
}
/**
* Returns true if current state may be processable (e.g. when customer or related data was changed).
* It doesn't guarantee state validity.
*
* @return bool
*/
public function feasible()
{
return !(empty($this->newCustomer) && empty($this->newContact) && empty($this->newCompanyName));
}
/**
* Throws an exception if state is not valid
*
* @throws \InvalidArgumentException
* @return void
*/
public function validate()
{
if (empty($this->order)) {
throw new \InvalidArgumentException('Empty Order.');
}
if (empty($this->newCustomer) && empty($this->newContact) && empty($this->newCompanyName)) {
throw new \InvalidArgumentException('New customer, new contact and new company is empty.');
}
if (!empty($this->newCustomer) && !empty($this->newContact)) {
RetailcrmLogger::writeDebugArray(
__METHOD__,
array(
'State data (customer and contact):' . PHP_EOL,
$this->getNewCustomer(),
$this->getNewContact()
)
);
throw new \InvalidArgumentException(
'Too much data in state - cannot determine which customer should be used.'
);
}
}
}

View File

@ -0,0 +1,8 @@
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Location: ../");
exit;

View File

@ -59,6 +59,7 @@
<field id="order_method" group="order">orderMethod</field>
<field id="site" group="order">site</field>
<field id="status" group="order">status</field>
<field id="customer" group="order">customer</field>
<field id="manager" group="order">manager</field>
<field id="first_name" group="order">firstName</field>
<field id="last_name" group="order">lastName</field>
@ -75,6 +76,8 @@
<field id="manager_comment" group="order">managerComment</field>
<field id="shipment_store" group="order">shipmentStore</field>
<field id="shipment_date" group="order">shipmentDate</field>
<field id="contact" group="order">contact</field>
<field id="company" group="order">company</field>
<field id="shipped" group="order">shipped</field>
<!--<field id="order_product" group="order">item</field>-->

View File

@ -0,0 +1,144 @@
<?php
class RetailcrmCorporateCustomerBuilderTest extends RetailcrmTestCase
{
protected $corporateCustomer;
public function setUp()
{
parent::setUp();
}
public function testBuild()
{
$this->corporateCustomer = new RetailcrmCorporateCustomerBuilder();
$this->corporateCustomer
->setDataCrm($this->getDataCrm())
->build();
$result = new RetailcrmCustomerBuilderResult(null, null);
$this->assertInstanceOf(get_class($result), $this->corporateCustomer->getData());
}
public function testGetData()
{
$this->corporateCustomer = new RetailcrmCorporateCustomerBuilder();
$this->corporateCustomer
->setDataCrm($this->getDataCrm())
->build();
$builtCustomer = $this->corporateCustomer->getData()->getCustomer();
$builtAddress = $this->corporateCustomer->getData()->getCustomerAddress();
$this->assertTrue($builtCustomer instanceof Customer
|| $builtCustomer instanceof CustomerCore);
$this->assertTrue($builtAddress instanceof Address
|| $builtAddress instanceof AddressCore);
}
public function testCorrectDataCorporateCustomer()
{
$this->corporateCustomer = new RetailcrmCorporateCustomerBuilder();
$this->corporateCustomer
->setDataCrm($this->getDataCrm())
->setCustomer($this->getDataBuilder())
->setCompanyName('Test')
->setCompanyInn(5666)
->build();
$customerResult = $this->corporateCustomer->getData()->getCustomer();
$this->assertEquals('April', $customerResult->firstname);
$this->assertEquals('Iphone', $customerResult->lastname);
$this->assertEquals(false, $customerResult->newsletter);
$this->assertEquals('1997-04-09', $customerResult->birthday);
$this->assertEquals(2, $customerResult->id_gender);
$this->assertEquals('hello@world.ru', $customerResult->email);
$addressResult = $this->corporateCustomer->getData()->getCustomerAddress();
$this->assertEquals(Country::getByIso('RU'), $addressResult->id_country);
$this->assertEquals('г. Москва', $addressResult->city);
$this->assertEquals('Test', $addressResult->company);
$this->assertEquals(5666, $addressResult->vat_number);
}
private function getDataBuilder() {
return array(
'type' => 'customer_corporate',
'id' => 9090,
'nickName' => 'TestName',
'mainAddress' => array(
'id' => 4001,
'name' => 'Test'
),
'createdAt' => '2020-02-17 07:44:31',
'vip' => false,
'bad' => false,
'site' => 'opencart',
'tags' => array(),
'marginSumm' => 0,
'totalSumm' => 0,
'averageSumm' => 0,
'ordersCount' => 0,
'costSumm' => 0,
'customFields' => array(),
'personalDiscount' => 0,
'mainCustomerContact' => array(
'id' => 37,
'customer' => array(
'id' => 9089
),
'companies' => array()
),
'mainCompany' => array(
'id' => 34,
'name' => 'Test',
'contragentInn' => 5666
)
);
}
private function getDataCrm() {
return array(
'type' => 'customer',
'id' => 9000,
'externalId' => '1777754',
'isContact' => false,
'createdAt' => '2020-04-09 16:55:59',
'vip' => true,
'bad' => true,
'site' => '127-0-0-1-8080',
'contragent' => array(
'contragentType' => 'individual'
),
'tags' => array(),
'marginSumm' => 0,
'totalSumm' => 0,
'averageSumm' => 0,
'ordersCount' => 0,
'costSumm' => 0,
'customFields' => array(),
'personalDiscount' => 0,
'address' => array(
'id' => 9718,
'countryIso' => 'RU',
'region' => 'Moscow',
'city' => 'г. Москва',
'index' => '344004',
'text' => 'MAY'
),
'segments' => array(),
'firstName' => 'April',
'lastName' => 'Iphone',
'email' => 'hello@world.ru',
'sex' => 'female',
'birthday' =>'1997-04-09'
);
}
}

View File

@ -0,0 +1,67 @@
<?php
class RetailcrmCustomerAddressBuilderTest extends RetailcrmTestCase
{
protected $customerAddress;
protected $customer;
public function setUp()
{
parent::setUp();
}
public function testBuild()
{
$this->customerAddress = new RetailcrmCustomerAddressBuilder();
$this->customerAddress
->setDataCrm($this->getDataBuilder())
->build();
$this->assertNotEmpty($this->customerAddress->getData());
}
public function setCustomerAddress()
{
$this->customerAddress = new RetailcrmCustomerAddressBuilder();
$this->customerAddress
->setCustomerAddress(new AddressCore(9999))
->build();
$this->assertNotEmpty($this->customerAddress->getData());
}
public function testCorrectDataAddress()
{
$this->customerAddress = new RetailcrmCustomerAddressBuilder();
$this->customerAddress
->setDataCrm($this->getDataBuilder())
->setFirstName('Test')
->setLastName('Test2')
->setPhone('+7999999999')
->build();
$addressResult = $this->customerAddress->getData();
$this->assertEquals('Test', $addressResult->firstname);
$this->assertEquals('Test2', $addressResult->lastname);
$this->assertEquals(Country::getByIso('RU'), $addressResult->id_country);
$this->assertEquals('г. Москва', $addressResult->city);
$this->assertEquals(State::getIdByName('Moscow'), $addressResult->id_state);
$this->assertEquals('344004', $addressResult->postcode);
$this->assertEquals('+7999999999', $addressResult->phone);
}
private function getDataBuilder() {
return array(
'id' => 9718,
'countryIso' => 'RU',
'region' => 'Moscow',
'city' => 'г. Москва',
'index' => '344004',
'text' => 'MAY'
);
}
}

View File

@ -0,0 +1,124 @@
<?php
class RetailcrmCustomerBuilderTest extends RetailcrmTestCase
{
protected $customer;
public function setUp()
{
parent::setUp();
}
public function testBuild()
{
$this->customer = new RetailcrmCustomerBuilder();
$this->customer
->setDataCrm($this->getDataCrm())
->build();
$result = new RetailcrmCustomerBuilderResult(null, null);
$this->assertInstanceOf(get_class($result), $this->customer->getData());
}
public function testSetCustomer()
{
$this->customer = new RetailcrmCustomerBuilder();
$this->customer
->setCustomer(new Customer(9719))
->build();
$this->assertNotEmpty($this->customer->getData());
}
public function testGetData()
{
$this->customer = new RetailcrmCustomerBuilder();
$this->customer
->setDataCrm($this->getDataCrm())
->build();
$builtCustomer = $this->customer->getData()->getCustomer();
$builtAddress = $this->customer->getData()->getCustomerAddress();
$this->assertTrue($builtCustomer instanceof Customer
|| $builtCustomer instanceof CustomerCore);
$this->assertTrue($builtAddress instanceof Address
|| $builtAddress instanceof AddressCore);
}
public function testBuildAddress()
{
$this->customer = new RetailcrmCustomerBuilder();
$this->customer->buildAddress();
$this->assertEquals(null, $this->customer->getData()->getCustomerAddress());
}
public function testCorrectDataCustomer()
{
$this->customer = new RetailcrmCustomerBuilder();
$this->customer
->setDataCrm($this->getDataCrm())
->build();
$customerResult = $this->customer->getData()->getCustomer();
$this->assertEquals('April', $customerResult->firstname);
$this->assertEquals('Iphone', $customerResult->lastname);
$this->assertEquals(false, $customerResult->newsletter);
$this->assertEquals('1997-04-09', $customerResult->birthday);
$this->assertEquals(2, $customerResult->id_gender);
$this->assertEquals('hello@world.ru', $customerResult->email);
$addressResult = $this->customer->getData()->getCustomerAddress();
$this->assertEquals(Country::getByIso('RU'), $addressResult->id_country);
$this->assertEquals('г. Москва', $addressResult->city);
}
private function getDataCrm() {
return array(
'type' => 'customer',
'id' => 9000,
'externalId' => '1777754',
'isContact' => false,
'createdAt' => '2020-04-09 16:55:59',
'vip' => true,
'bad' => true,
'site' => '127-0-0-1-8080',
'contragent' => array(
'contragentType' => 'individual'
),
'tags' => array(),
'marginSumm' => 0,
'totalSumm' => 0,
'averageSumm' => 0,
'ordersCount' => 0,
'costSumm' => 0,
'customFields' => array(),
'personalDiscount' => 0,
'address' => array(
'id' => 9718,
'countryIso' => 'RU',
'region' => 'Moscow',
'city' => 'г. Москва',
'index' => '344004',
'text' => 'MAY'
),
'segments' => array(),
'firstName' => 'April',
'lastName' => 'Iphone',
'email' => 'hello@world.ru',
'sex' => 'female',
'birthday' =>'1997-04-09'
);
}
}

View File

@ -30,4 +30,11 @@ class RetailcrmTestHelper
'SELECT MAX(id_order) FROM `' . _DB_PREFIX_ . 'orders`'
);
}
public static function getMaxCustomerId()
{
return Db::getInstance()->getValue(
'SELECT MAX(id_customer) FROM `' . _DB_PREFIX_ . 'customer`'
);
}
}

View File

@ -16,8 +16,10 @@ class RetailcrmHistoryTest extends RetailcrmTestCase
'customersHistory',
'ordersHistory',
'ordersGet',
'customersGet',
'customersFixExternalIds',
'ordersFixExternalIds'
'ordersFixExternalIds',
'customersCorporateAddressesEdit'
)
)
->getMock();
@ -32,7 +34,75 @@ class RetailcrmHistoryTest extends RetailcrmTestCase
$this->setConfig();
}
public function testOrderCreate()
public function testCustomersHistory()
{
$this->apiMock->expects($this->any())
->method('customersHistory')
->willReturn(
new RetailcrmApiResponse(
'200',
json_encode(
$this->getHistoryDataNewCustomer()
)
)
);
RetailcrmHistory::$default_lang = (int)Configuration::get('PS_LANG_DEFAULT');
RetailcrmHistory::$api = $this->apiMock;
$externalId = isset($this->getApiCustomer()['externalId']) ? $this->getApiCustomer()['externalId'] : null;
if (!empty($externalId))
{
$oldCustomer = new Customer($externalId);
RetailcrmHistory::customersHistory();
$newCustomer = new Customer($externalId);
$this->assertNotEquals($oldCustomer, $newCustomer);
} else {
$oldLastId = RetailcrmTestHelper::getMaxCustomerId();
RetailcrmHistory::customersHistory();
$newLastId = RetailcrmTestHelper::getMaxCustomerId();
$this->assertTrue($newLastId > $oldLastId);
}
$this->assertEquals(true, RetailcrmHistory::customersHistory());
}
public function orderCreate($apiMock)
{
RetailcrmHistory::$default_lang = (int)Configuration::get('PS_LANG_DEFAULT');
RetailcrmHistory::$api = $apiMock;
$oldLastId = RetailcrmTestHelper::getMaxOrderId();
RetailcrmHistory::ordersHistory();
$newLastId = RetailcrmTestHelper::getMaxOrderId();
$this->assertTrue($newLastId > $oldLastId);
$order = new Order($newLastId);
$this->assertInstanceOf('Order', $order);
}
public function switchCustomer()
{
RetailcrmHistory::$default_lang = (int)Configuration::get('PS_LANG_DEFAULT');
RetailcrmHistory::$api = $this->apiMock;
$history = $this->getHistoryExistOrder();
$newId = $history['history'][0]['newValue']['externalId'];
RetailcrmHistory::ordersHistory();
$order = new Order((int) $history['history'][0]['order']['externalId']);
$this->assertTrue($newId == $order->id_customer);
}
public function testOrderSwitchCustomer()
{
$this->apiMock->expects($this->any())
->method('ordersHistory')
@ -40,10 +110,11 @@ class RetailcrmHistoryTest extends RetailcrmTestCase
new RetailcrmApiResponse(
'200',
json_encode(
$this->getHistoryDataNewOrder()
$this->getHistoryExistOrder()
)
)
);
$this->apiMock->expects($this->any())
->method('ordersGet')
->willReturn(
@ -57,19 +128,95 @@ class RetailcrmHistoryTest extends RetailcrmTestCase
)
);
RetailcrmHistory::$default_lang = (int)Configuration::get('PS_LANG_DEFAULT');
RetailcrmHistory::$api = $this->apiMock;
$this->switchCustomer();
}
$oldLastId = RetailcrmTestHelper::getMaxOrderId();
RetailcrmHistory::ordersHistory();
$newLastId = RetailcrmTestHelper::getMaxOrderId();
$this->assertNotEquals($oldLastId, $newLastId);
$this->assertTrue($newLastId > $oldLastId);
public function testOrderSwitchCorporateCustomer()
{
$this->apiMock->expects($this->any())
->method('ordersHistory')
->willReturn(
new RetailcrmApiResponse(
'200',
json_encode(
$this->getHistoryExistOrder()
)
)
);
$order = new Order($newLastId);
$this->apiMock->expects($this->any())
->method('ordersGet')
->willReturn(
new RetailcrmApiResponse(
'200',
json_encode(
array(
'order' => $this->getApiOrderWitchCorporateCustomer()
)
)
)
);
$this->assertInstanceOf('Order', $order);
$this->switchCustomer();
}
public function testOrderCreate()
{
$this->apiMock->expects($this->any())
->method('ordersHistory')
->willReturn(
new RetailcrmApiResponse(
'200',
json_encode(
$this->getHistoryDataNewOrder($this->getApiOrder())
)
)
);
$this->apiMock->expects($this->any())
->method('ordersGet')
->willReturn(
new RetailcrmApiResponse(
'200',
json_encode(
array(
'order' => $this->getApiOrder()
)
)
)
);
$this->orderCreate($this->apiMock);
}
public function testOrderCreateWithCorporateCustomer()
{
$this->apiMock->expects($this->any())
->method('ordersHistory')
->willReturn(
new RetailcrmApiResponse(
'200',
json_encode(
$this->getHistoryDataNewOrder($this->getApiOrderWitchCorporateCustomer())
)
)
);
$this->apiMock->expects($this->any())
->method('ordersGet')
->willReturn(
new RetailcrmApiResponse(
'200',
json_encode(
array(
'order' => $this->getApiOrderWitchCorporateCustomer()
)
)
)
);
$this->orderCreate($this->apiMock);
}
public function testPaymentStatusUpdate()
@ -93,7 +240,45 @@ class RetailcrmHistoryTest extends RetailcrmTestCase
RetailcrmHistory::ordersHistory();
}
private function getHistoryDataNewOrder()
private function getHistoryExistOrder()
{
return array(
'success' => true,
'history' => array(
array(
'id' => 19752,
'createdAt' => '2018-01-01 00:00:00',
'source' => 'api',
'field' => 'customer',
'apiKey' => array('current' => false),
'oldValue' => array(
'id' => 7778,
'externalId' => '1',
'site' => '127.0.0.1:8000'
),
'newValue' => array(
'id' => 7777,
'externalId' => '777',
'site' => '127.0.0.1:8000'
),
'order' => array(
'id' => 6025,
'externalId' => '1',
'site' => '127.0.0.1:8000',
'status' => 'new'
)
)
),
'pagination' => array(
'limit' => 20,
'totalCount' => 1,
'currentPage' => 1,
'totalPageCount' => 1
)
);
}
private function getHistoryDataNewOrder($orderData)
{
return array(
'success' => true,
@ -111,14 +296,14 @@ class RetailcrmHistoryTest extends RetailcrmTestCase
'newValue' => array(
'code' => 'new'
),
'order' => $this->getApiOrder()
'order' => $orderData
)
),
"pagination" => array(
"limit" => 20,
"totalCount" => 1,
"currentPage" => 1,
"totalPageCount" => 1
'pagination' => array(
'limit' => 20,
'totalCount' => 1,
'currentPage' => 1,
'totalPageCount' => 1
)
);
}
@ -147,6 +332,7 @@ class RetailcrmHistoryTest extends RetailcrmTestCase
'customer' => array(
'segments' => array(),
'id' => 1,
'externalId' => '777',
'type' => 'customer',
'firstName' => 'Test',
'lastName' => 'Test',
@ -160,6 +346,7 @@ class RetailcrmHistoryTest extends RetailcrmTestCase
)
),
'address' => array(
'id_customer' => 2222,
'index' => '111111',
'countryIso' => 'RU',
'region' => 'Test region',
@ -191,6 +378,7 @@ class RetailcrmHistoryTest extends RetailcrmTestCase
'cost' => 100,
'netCost' => 0,
'address' => array(
'id_customer' => 2222,
'index' => '111111',
'countryIso' => 'RU',
'region' => 'Test region',
@ -238,15 +426,159 @@ class RetailcrmHistoryTest extends RetailcrmTestCase
return $order;
}
private function getApiOrderWitchCorporateCustomer()
{
$orderWithCorporateCustomer = array(
'slug' => 1,
'id' => 2,
'number' => '1C',
'orderType' => 'eshop-individual',
'orderMethod' => 'phone',
'countryIso' => 'RU',
'createdAt' => '2018-01-01 00:00:00',
'statusUpdatedAt' => '2018-01-01 00:00:00',
'summ' => 100,
'totalSumm' => 100,
'prepaySum' => 0,
'purchaseSumm' => 50,
'markDatetime' => '2018-01-01 00:00:00',
'firstName' => 'Test',
'lastName' => 'Test',
'phone' => '80000000000',
'call' => false,
'expired' => false,
'customer' => array(
'segments' => array(),
'id' => 1,
'externalId' => '777',
'type' => 'customer_corporate',
'firstName' => 'Test',
'lastName' => 'Test',
'email' => 'email@test.ru',
'phones' => array(
array(
'number' => '111111111111111'
),
array(
'number' => '+7111111111'
)
),
'address' => array(
'id' => 2345,
'id_customer' => 2222,
'index' => '111111',
'countryIso' => 'RU',
'region' => 'Test region',
'city' => 'Test',
'text' => 'Test text address'
),
'createdAt' => '2018-01-01 00:00:00',
'managerId' => 1,
'vip' => false,
'bad' => false,
'site' => 'test-com',
'contragent' => array(
'contragentType' => 'individual'
),
'personalDiscount' => 0,
'cumulativeDiscount' => 0,
'marginSumm' => 58654,
'totalSumm' => 61549,
'averageSumm' => 15387.25,
'ordersCount' => 4,
'costSumm' => 101,
'customFields' => array(
'custom' => 'test'
)
),
'contact' => array(
'id' => 1,
'externalId' => '7777',
'type' => 'customer_corporate',
'managerId' => 23,
'isContact' => true,
'vip' => false,
'bad' => false,
),
'contragent' => array(),
'delivery' => array(
'code' => 'delivery',
'cost' => 100,
'netCost' => 0,
'address' => array(
'id_customer' => 2222,
'index' => '111111',
'countryIso' => 'RU',
'region' => 'Test region',
'city' => 'Test',
'text' => 'Test text address'
)
),
'company' => array(
'id' => 7777,
'contragent' => array(
'legalName' => 'test',
'INN' => '255222'
),
'address' => array(
'id' => 1,
'id_customer' => 2222,
'index' => '111111',
'countryIso' => 'RU',
'region' => 'Test region',
'city' => 'Test',
'text' => 'Test text address'
)
),
'site' => 'test-com',
'status' => 'new',
'items' => array(
array(
'id' => 160,
'initialPrice' => 100,
'createdAt' => '2018-01-01 00:00:00',
'quantity' => 1,
'status' => 'new',
'offer' => array(
'id' => 1,
'externalId' => $this->product['id'],
'xmlId' => '1',
'name' => 'Test name',
'vatRate' => 'none'
),
'properties' => array(),
'purchasePrice' => 50
),
array_merge(RetailcrmOrderBuilder::getGiftItem(10), array('id' => 25919))
),
'fromApi' => false,
'length' => 0,
'width' => 0,
'height' => 0,
'shipmentStore' => 'main',
'shipped' => false,
'customFields' => array(),
'uploadedToExternalStoreSystem' => false
);
$orderWithCorporateCustomer['payments'][] = array(
'id' => 97,
'type' => 'cheque',
'amount' => 210
);
return $orderWithCorporateCustomer;
}
private function getUpdatePaymentStatus($orderId)
{
return array(
'success' => true,
"pagination" => array(
"limit" => 20,
"totalCount" => 1,
"currentPage" => 1,
"totalPageCount" => 1
'pagination' => array(
'limit' => 20,
'totalCount' => 1,
'currentPage' => 1,
'totalPageCount' => 1
),
'history' => array(
array(
@ -317,4 +649,72 @@ class RetailcrmHistoryTest extends RetailcrmTestCase
)
);
}
private function getHistoryDataNewCustomer()
{
return array(
'success' => true,
'history' => array(
array(
'id' => 1,
'createdAt' => '2018-01-01 00:00:00',
'created' => true,
'source' => 'api',
'field' => 'id',
'oldValue' => null,
'newValue' => 4949,
'customer' => $this->getApiCustomer()
)
),
'pagination' => array(
'limit' => 20,
'totalCount' => 1,
'currentPage' => 1,
'totalPageCount' => 1
)
);
}
private function getApiCustomer()
{
return array(
'type' => 'customer',
'id' => 1,
'externalId' => '1',
'isContact' => false,
'createdAt' => '2020-05-08 03:00:38',
'vip' => false,
'bad' => false,
'site' => 'example.com',
'contragent'=> array(
'contragentType'=> 'individual'
),
'tags' => array(),
'marginSumm' => 0,
'totalSumm' => 0,
'averageSumm' => 0,
'ordersCount' => 0,
'costSumm' => 0,
'customFields' => [],
'personalDiscount' => 0,
'address' => array(
'id_customer' => 2222,
'id' => 4053,
'countryIso' => 'RU',
'index' => '2170',
'city' => 'Moscow',
'street' => 'Good',
'building' => '17',
'text' => 'Good, д. 17'
),
'segments' => array(),
'email' => 'test@example.com',
'firstName' => 'Test',
'lastName' => 'Test',
'phones' => array(
'number' => '+79999999999'
)
);
}
}