1
0
mirror of synced 2025-02-16 15:03:14 +03:00

Service for manager sync

* added service for manager sync
* added manager event handler in history uploading methods
* deleted logger dependence from repository
* extract config provider proxy methods from repository to service
This commit is contained in:
Сергей Чазов 2021-08-19 15:46:03 +03:00 committed by GitHub
parent c731fae369
commit 8458360a30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 641 additions and 481 deletions

View File

@ -59,28 +59,24 @@ class ApiClient
/** /**
* Returns users list * Returns users list
* *
* @param array $filter * @param array $filter
* @param null $page * @param int|null $page
* @param null $limit * @param int|null $limit
*
* @throws \RetailCrm\Exception\InvalidJsonException
* @throws \RetailCrm\Exception\CurlException
* @throws \InvalidArgumentException
* *
* @return ApiResponse * @return ApiResponse
*/ */
public function usersList(array $filter = array(), $page = null, $limit = null) public function usersList(array $filter = [], int $page = null, int $limit = null): ApiResponse
{ {
$parameters = array(); $parameters = [];
if (count($filter)) { if (count($filter)) {
$parameters['filter'] = $filter; $parameters['filter'] = $filter;
} }
if (null !== $page) { if (null !== $page) {
$parameters['page'] = (int) $page; $parameters['page'] = $page;
} }
if (null !== $limit) { if (null !== $limit) {
$parameters['limit'] = (int) $limit; $parameters['limit'] = $limit;
} }
return $this->client->makeRequest( return $this->client->makeRequest(

View File

@ -1,4 +1,7 @@
<?php <?php
use Intaro\RetailCrm\Service\ManagerService;
IncludeModuleLangFile(__FILE__); IncludeModuleLangFile(__FILE__);
class RCrmActions class RCrmActions
{ {
@ -186,11 +189,11 @@ class RCrmActions
* *
* @return self name * @return self name
*/ */
public static function uploadOrdersAgent() public static function uploadOrdersAgent()
{ {
RetailCrmOrder::uploadOrders(); RetailCrmOrder::uploadOrders();
$failedIds = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_FAILED_IDS, 0)); $failedIds = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_FAILED_IDS, 0));
if (is_array($failedIds) && !empty($failedIds)) { if (is_array($failedIds) && !empty($failedIds)) {
RetailCrmOrder::uploadOrders(50, true); RetailCrmOrder::uploadOrders(50, true);
} }
@ -206,10 +209,13 @@ class RCrmActions
*/ */
public static function orderAgent() public static function orderAgent()
{ {
if (COption::GetOptionString('main', 'agents_use_crontab', 'N') != 'N') { if (COption::GetOptionString('main', 'agents_use_crontab', 'N') !== 'N') {
define('NO_AGENT_CHECK', true); define('NO_AGENT_CHECK', true);
} }
$service = ManagerService::getInstance();
$service->synchronizeManagers();
RetailCrmHistory::customerHistory(); RetailCrmHistory::customerHistory();
RetailCrmHistory::orderHistory(); RetailCrmHistory::orderHistory();
self::uploadOrdersAgent(); self::uploadOrdersAgent();
@ -354,10 +360,16 @@ class RCrmActions
return $string; return $string;
} }
public static function explodeFIO($fio) /**
* @param string|null $fio
*
* @return array
*/
public static function explodeFio(?string $fio): array
{ {
$result = array(); $result = [];
$fio = preg_replace('|[\s]+|s', ' ', trim($fio)); $fio = preg_replace('|[\s]+|s', ' ', trim($fio));
if (empty($fio)) { if (empty($fio)) {
return $result; return $result;
} else { } else {
@ -367,23 +379,23 @@ class RCrmActions
switch (count($newFio)) { switch (count($newFio)) {
default: default:
case 0: case 0:
$result['firstName'] = $fio; $result['firstName'] = $fio;
break; break;
case 1: case 1:
$result['firstName'] = $newFio[0]; $result['firstName'] = $newFio[0];
break; break;
case 2: case 2:
$result = array( $result = [
'lastName' => $newFio[0], 'lastName' => $newFio[0],
'firstName' => $newFio[1] 'firstName' => $newFio[1],
); ];
break; break;
case 3: case 3:
$result = array( $result = [
'lastName' => $newFio[0], 'lastName' => $newFio[0],
'firstName' => $newFio[1], 'firstName' => $newFio[1],
'patronymic' => $newFio[2] 'patronymic' => $newFio[2],
); ];
break; break;
} }

View File

@ -11,6 +11,7 @@
namespace RetailCrm\Response; namespace RetailCrm\Response;
use InvalidArgumentException;
use RetailCrm\Exception\InvalidJsonException; use RetailCrm\Exception\InvalidJsonException;
/** /**
@ -166,7 +167,7 @@ class ApiResponse implements \ArrayAccess
public function offsetGet($offset) public function offsetGet($offset)
{ {
if (!isset($this->response[$offset])) { if (!isset($this->response[$offset])) {
throw new \InvalidArgumentException("Property \"$offset\" not found"); throw new InvalidArgumentException("Property \"$offset\" not found");
} }
return $this->response[$offset]; return $this->response[$offset];

View File

@ -243,15 +243,33 @@ class RetailcrmConfigProvider
*/ */
public static function getSiteName(): string public static function getSiteName(): string
{ {
$sitename = COption::GetOptionString('main', 'site_name'); $siteName = COption::GetOptionString('main', 'site_name');
if (!$sitename) { if (!$siteName) {
return ''; return '';
} }
return $sitename; return $siteName;
} }
/**
* @return mixed
*/
public static function getUsersMap()
{
return static::getUnserializedOption(RetailcrmConstants::CRM_USERS_MAP);
}
/**
* @param array|null $userMap
*
* @return bool
*/
public static function setUsersMap(?array $userMap): bool
{
return static::setOption(RetailcrmConstants::CRM_USERS_MAP, serialize($userMap));
}
/** /**
* setOnlineConsultantScript * setOnlineConsultantScript
* *
@ -772,9 +790,9 @@ class RetailcrmConfigProvider
* @param bool $desc * @param bool $desc
* @param string $site * @param string $site
*/ */
private static function setOption($name, $value = "", $desc = false, $site = "") private static function setOption($name, string $value = '', bool $desc = false, string $site = ''): bool
{ {
COption::SetOptionString( return COption::SetOptionString(
RetailcrmConstants::MODULE_ID, RetailcrmConstants::MODULE_ID,
$name, $name,
$value, $value,

View File

@ -76,4 +76,6 @@ class RetailcrmConstants
public const CRM_ONLINE_CONSULTANT = 'online_consultant'; public const CRM_ONLINE_CONSULTANT = 'online_consultant';
public const CRM_ONLINE_CONSULTANT_SCRIPT = 'online_consultant_script'; public const CRM_ONLINE_CONSULTANT_SCRIPT = 'online_consultant_script';
public const CRM_PURCHASE_PRICE_NULL = 'purchasePrice_null'; public const CRM_PURCHASE_PRICE_NULL = 'purchasePrice_null';
public const CRM_USERS_MAP = 'crm_users_map';
public const BITRIX_USER_ID_PREFIX = 'bitrixUserId-';
} }

View File

@ -1,5 +1,7 @@
<?php <?php
use Intaro\RetailCrm\Service\ManagerService;
/** /**
* Class RetailCrmEvent * Class RetailCrmEvent
*/ */
@ -140,7 +142,6 @@ class RetailCrmEvent
return false; return false;
} }
$arOrder = RetailCrmOrder::orderObjToArr($obOrder); $arOrder = RetailCrmOrder::orderObjToArr($obOrder);
$api = new RetailCrm\ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey()); $api = new RetailCrm\ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey());
@ -413,6 +414,11 @@ class RetailCrmEvent
} }
} }
if (isset($arOrder['RESPONSIBLE_ID']) && !empty($arOrder['RESPONSIBLE_ID'])) {
$managerService = ManagerService::getInstance();
$arParams['managerId'] = $managerService->getManagerCrmId($arOrder['RESPONSIBLE_ID']);
}
//order //order
$resultOrder = RetailCrmOrder::orderSend($arOrder, $api, $arParams, true, $site, $methodApi); $resultOrder = RetailCrmOrder::orderSend($arOrder, $api, $arParams, true, $site, $methodApi);

View File

@ -521,7 +521,7 @@ class RetailCrmHistory
} }
} }
$fio = RCrmActions::explodeFIO($fio); $fio = RCrmActions::explodeFio($fio);
$newFio = array(); $newFio = array();
if ($fio) { if ($fio) {
$newFio[] = isset($order['lastName']) ? RCrmActions::fromJSON($order['lastName']) : (isset($fio['lastName']) ? $fio['lastName'] : ''); $newFio[] = isset($order['lastName']) ? RCrmActions::fromJSON($order['lastName']) : (isset($fio['lastName']) ? $fio['lastName'] : '');

View File

@ -1,4 +1,18 @@
<?php <?php
use Bitrix\Main\ArgumentException;
use Bitrix\Main\ArgumentNullException;
use Bitrix\Main\Context;
use Bitrix\Sale\Basket;
use Bitrix\Sale\Delivery\Services\EmptyDeliveryService;
use Bitrix\Sale\Delivery\Services\Manager;
use Bitrix\Sale\Fuser;
use Bitrix\Sale\Internals\PaymentTable;
use Bitrix\Sale\Location\Search\Finder;
use Bitrix\Sale\Order;
use Bitrix\Sale\OrderUserProperties;
use Intaro\RetailCrm\Service\ManagerService;
IncludeModuleLangFile(__FILE__); IncludeModuleLangFile(__FILE__);
class RetailCrmHistory class RetailCrmHistory
{ {
@ -174,7 +188,7 @@ class RetailCrmHistory
retailCrmAfterCustomerSave($customer); retailCrmAfterCustomerSave($customer);
} }
} }
$customerBuilder->reset(); $customerBuilder->reset();
} }
@ -192,11 +206,24 @@ class RetailCrmHistory
} }
} }
public static function orderHistory() /**
* @return bool
* @throws \Bitrix\Main\ArgumentException
* @throws \Bitrix\Main\ArgumentNullException
* @throws \Bitrix\Main\ArgumentOutOfRangeException
* @throws \Bitrix\Main\ArgumentTypeException
* @throws \Bitrix\Main\NotImplementedException
* @throws \Bitrix\Main\NotSupportedException
* @throws \Bitrix\Main\ObjectException
* @throws \Bitrix\Main\ObjectNotFoundException
* @throws \Bitrix\Main\ObjectPropertyException
* @throws \Bitrix\Main\SystemException
*/
public static function orderHistory(): bool
{ {
global $USER; global $USER;
if (is_object($USER) == false) { if (is_object($USER) === false) {
$USER = new RetailUser(); $USER = new RetailUser();
} }
@ -227,11 +254,11 @@ class RetailCrmHistory
while (true) { while (true) {
$orderHistory = RCrmActions::apiMethod($api, 'ordersHistory', __METHOD__, $historyFilter); $orderHistory = RCrmActions::apiMethod($api, 'ordersHistory', __METHOD__, $historyFilter);
$orderH = isset($orderHistory['history']) ? $orderHistory['history'] : array(); $orderH = $orderHistory['history'] ?? [];
Logger::getInstance()->write($orderH, 'orderHistory'); Logger::getInstance()->write($orderH, 'orderHistory');
if (count($orderH) == 0) { if (count($orderH) === 0) {
if ($orderHistory['history']['totalPageCount'] > $orderHistory['history']['currentPage']) { if ($orderHistory['history']['totalPageCount'] > $orderHistory['history']['currentPage']) {
$historyFilter['page'] = $orderHistory['history']['currentPage'] + 1; $historyFilter['page'] = $orderHistory['history']['currentPage'] + 1;
@ -265,30 +292,7 @@ class RetailCrmHistory
if (isset($order['deleted'])) { if (isset($order['deleted'])) {
if (isset($order['externalId'])) { if (isset($order['externalId'])) {
try { self::cancelOrder($order['externalId']);
$newOrder = Bitrix\Sale\Order::load($order['externalId']);
} catch (Bitrix\Main\ArgumentNullException $e) {
RCrmActions::eventLog(
'RetailCrmHistory::orderHistory',
'Bitrix\Sale\Order::load',
$e->getMessage() . ': ' . $order['externalId']
);
continue;
}
if (!$newOrder instanceof \Bitrix\Sale\Order) {
RCrmActions::eventLog(
'RetailCrmHistory::orderHistory',
'Bitrix\Sale\Order::load',
'Error order load: ' . $order['externalId']
);
continue;
}
$newOrder->setField('CANCELED', 'Y');
$newOrder->save();
} }
continue; continue;
@ -317,7 +321,7 @@ class RetailCrmHistory
$corporateCustomerBuilder = new CorporateCustomerBuilder(); $corporateCustomerBuilder = new CorporateCustomerBuilder();
$corporateContact = array(); $corporateContact = array();
$orderCustomerExtId = isset($order['customer']['externalId']) ? $order['customer']['externalId'] : null; $orderCustomerExtId = $order['customer']['externalId'] ?? null;
$corporateCustomerBuilder->setOrderCustomerExtId($orderCustomerExtId) $corporateCustomerBuilder->setOrderCustomerExtId($orderCustomerExtId)
->setContragentTypes($contragentTypes) ->setContragentTypes($contragentTypes)
->setDataCrm($order) ->setDataCrm($order)
@ -329,9 +333,7 @@ class RetailCrmHistory
if (isset($order['contact']['email'])) { if (isset($order['contact']['email'])) {
$corporateContact = $order['contact']; $corporateContact = $order['contact'];
$orderCustomerExtId = isset($corporateContact['externalId']) $orderCustomerExtId = $corporateContact['externalId'] ?? null;
? $corporateContact['externalId']
: null;
$corporateCustomerBuilder->setCorporateContact($corporateContact) $corporateCustomerBuilder->setCorporateContact($corporateContact)
->setOrderCustomerExtId($orderCustomerExtId); ->setOrderCustomerExtId($orderCustomerExtId);
@ -359,9 +361,7 @@ class RetailCrmHistory
if ($response && isset($response['customer'])) { if ($response && isset($response['customer'])) {
$corporateContact = $response['customer']; $corporateContact = $response['customer'];
$orderCustomerExtId = isset($corporateContact['externalId']) $orderCustomerExtId = $corporateContact['externalId'] ?? null;
? $corporateContact['externalId']
: null;
$corporateCustomerBuilder->setCorporateContact($corporateContact) $corporateCustomerBuilder->setCorporateContact($corporateContact)
->setOrderCustomerExtId($orderCustomerExtId); ->setOrderCustomerExtId($orderCustomerExtId);
} }
@ -467,7 +467,7 @@ class RetailCrmHistory
if (RetailCrmOrder::isOrderCorporate($order) && !empty($order['company'])) { if (RetailCrmOrder::isOrderCorporate($order) && !empty($order['company'])) {
$buyerProfile = $corporateCustomerBuilder->getBuyerProfile()->getObjectToArray(); $buyerProfile = $corporateCustomerBuilder->getBuyerProfile()->getObjectToArray();
$buyerProfileToAppend = Bitrix\Sale\OrderUserProperties::getList(array( $buyerProfileToAppend = OrderUserProperties::getList(array(
"filter" => $buyerProfile "filter" => $buyerProfile
))->fetch(); ))->fetch();
@ -475,23 +475,29 @@ class RetailCrmHistory
$buyerProfileInstance = new CSaleOrderUserProps(); $buyerProfileInstance = new CSaleOrderUserProps();
if ($buyerProfileInstance->Add($buyerProfile)) { if ($buyerProfileInstance->Add($buyerProfile)) {
$buyerProfileToAppend = Bitrix\Sale\OrderUserProperties::getList(array( $buyerProfileToAppend = OrderUserProperties::getList(array(
"filter" => $buyerProfile "filter" => $buyerProfile
))->fetch(); ))->fetch();
} }
} }
} }
$newOrder = Bitrix\Sale\Order::create($site, $orderCustomerExtId, $currency); $newOrder = Order::create($site, $orderCustomerExtId, $currency);
if (isset($buyerProfileToAppend['ID']) && isset($optionsLegalDetails['legalName'])) { if (array_key_exists('managerId', $order)) {
$newOrder->setFields(array( $service = ManagerService::getInstance();
$optionsLegalDetails['legalName'] => $buyerProfileToAppend['NAME'],
'PERSON_TYPE_ID' => $buyerProfileToAppend['PERSON_TYPE_ID'] $newOrder->setField('RESPONSIBLE_ID', $service->getManagerBitrixId($order['managerId']));
));
} }
if (!is_object($newOrder) || !$newOrder instanceof \Bitrix\Sale\Order) { if (isset($buyerProfileToAppend['ID']) && isset($optionsLegalDetails['legalName'])) {
$newOrder->setFields([
$optionsLegalDetails['legalName'] => $buyerProfileToAppend['NAME'],
'PERSON_TYPE_ID' => $buyerProfileToAppend['PERSON_TYPE_ID'],
]);
}
if (!is_object($newOrder) || !$newOrder instanceof Order) {
RCrmActions::eventLog( RCrmActions::eventLog(
'RetailCrmHistory::orderHistory', 'RetailCrmHistory::orderHistory',
'Bitrix\Sale\Order::create', 'Bitrix\Sale\Order::create',
@ -510,8 +516,8 @@ class RetailCrmHistory
if ($order['externalId'] && is_numeric($order['externalId'])) { if ($order['externalId'] && is_numeric($order['externalId'])) {
try { try {
$newOrder = Bitrix\Sale\Order::load($order['externalId']); $newOrder = Order::load($order['externalId']);
} catch (Bitrix\Main\ArgumentNullException $e) { } catch (ArgumentNullException $e) {
RCrmActions::eventLog( RCrmActions::eventLog(
'RetailCrmHistory::orderHistory', 'RetailCrmHistory::orderHistory',
'Bitrix\Sale\Order::load', 'Bitrix\Sale\Order::load',
@ -522,7 +528,7 @@ class RetailCrmHistory
} }
} }
if (!isset($newOrder) || $newOrder === null) { if (!isset($newOrder)) {
RCrmActions::eventLog( RCrmActions::eventLog(
'RetailCrmHistory::orderHistory', 'RetailCrmHistory::orderHistory',
'Bitrix\Sale\Order::load', 'Bitrix\Sale\Order::load',
@ -532,6 +538,12 @@ class RetailCrmHistory
continue; continue;
} }
if (array_key_exists('managerId', $order)) {
$service = ManagerService::getInstance();
$newOrder->setField('RESPONSIBLE_ID', $service->getManagerBitrixId($order['managerId']));
}
if ($optionsSitesList) { if ($optionsSitesList) {
$site = array_search($order['site'], $optionsSitesList); $site = array_search($order['site'], $optionsSitesList);
} else { } else {
@ -661,35 +673,37 @@ class RetailCrmHistory
// fio // fio
if ($order['firstName'] || $order['lastName'] || $order['patronymic']) { if ($order['firstName'] || $order['lastName'] || $order['patronymic']) {
$fio = ''; $fio = '';
foreach ($propertyCollectionArr['properties'] as $prop) { foreach ($propertyCollectionArr['properties'] as $prop) {
if (in_array($optionsOrderProps[$personType]['fio'], $prop)) { if (in_array($optionsOrderProps[$personType]['fio'], $prop)) {
$getFio = $newOrder->getPropertyCollection()->getItemByOrderPropertyId($prop['ID']); $getFio = $newOrder->getPropertyCollection()->getItemByOrderPropertyId($prop['ID']);
if (method_exists($getFio, 'getValue')) { if (method_exists($getFio, 'getValue')) {
$fio = $getFio->getValue(); $fio = $getFio->getValue();
} }
} }
} }
$fio = RCrmActions::explodeFIO($fio); $fio = RCrmActions::explodeFio($fio);
$newFio = array(); $newFio = array();
if ($fio) { if ($fio) {
$newFio[] = isset($order['lastName']) $newFio[] = isset($order['lastName'])
? RCrmActions::fromJSON($order['lastName']) ? RCrmActions::fromJSON($order['lastName'])
: (isset($fio['lastName']) ? $fio['lastName'] : ''); : ($fio['lastName'] ?? '');
$newFio[] = isset($order['firstName']) $newFio[] = isset($order['firstName'])
? RCrmActions::fromJSON($order['firstName']) ? RCrmActions::fromJSON($order['firstName'])
: (isset($fio['firstName']) ? $fio['firstName'] : ''); : ($fio['firstName'] ?? '');
$newFio[] = isset($order['patronymic']) $newFio[] = isset($order['patronymic'])
? RCrmActions::fromJSON($order['patronymic']) ? RCrmActions::fromJSON($order['patronymic'])
: (isset($fio['patronymic']) ? $fio['patronymic'] : ''); : ($fio['patronymic'] ?? '');
$order['fio'] = trim(implode(' ', $newFio));
} else { } else {
$newFio[] = isset($order['lastName']) ? RCrmActions::fromJSON($order['lastName']) : ''; $newFio[] = isset($order['lastName']) ? RCrmActions::fromJSON($order['lastName']) : '';
$newFio[] = isset($order['firstName']) ? RCrmActions::fromJSON($order['firstName']) : ''; $newFio[] = isset($order['firstName']) ? RCrmActions::fromJSON($order['firstName']) : '';
$newFio[] = isset($order['patronymic']) ? RCrmActions::fromJSON($order['patronymic']) : ''; $newFio[] = isset($order['patronymic']) ? RCrmActions::fromJSON($order['patronymic']) : '';
$order['fio'] = trim(implode(' ', $newFio));
} }
$order['fio'] = trim(implode(' ', $newFio));
} }
if (array_key_exists('fio', $order)) { if (array_key_exists('fio', $order)) {
@ -739,10 +753,10 @@ class RetailCrmHistory
$parameters['filter']['NAME.LANGUAGE_ID'] = 'ru'; $parameters['filter']['NAME.LANGUAGE_ID'] = 'ru';
try { try {
if ( !isset($location) ) { if (!isset($location)) {
$location = \Bitrix\Sale\Location\Search\Finder::find( $location = Finder::find(
$parameters, $parameters,
array('USE_INDEX' => false, 'USE_ORM' => false) ['USE_INDEX' => false, 'USE_ORM' => false]
)->fetch(); )->fetch();
} }
@ -750,7 +764,7 @@ class RetailCrmHistory
->getItemByOrderPropertyId($propsKey[$orderProp]['ID']); ->getItemByOrderPropertyId($propsKey[$orderProp]['ID']);
self::setProp($somePropValue, $location['CODE']); self::setProp($somePropValue, $location['CODE']);
} catch (\Bitrix\Main\ArgumentException $argumentException) { } catch (ArgumentException $argumentException) {
RCrmActions::eventLog( RCrmActions::eventLog(
'RetailCrmHistory::orderHistory', 'RetailCrmHistory::orderHistory',
'RetailCrmHistory::setProp', 'RetailCrmHistory::setProp',
@ -818,9 +832,7 @@ class RetailCrmHistory
$somePropValue, $somePropValue,
RCrmActions::fromJSON( RCrmActions::fromJSON(
$key == 'legalAddress' $key == 'legalAddress'
? (isset($order['company']['address']['text']) ? ($order['company']['address']['text'] ?? '')
? $order['company']['address']['text']
: '')
: $order['company'][$key] : $order['company'][$key]
) )
); );
@ -850,14 +862,14 @@ class RetailCrmHistory
$basket = $newOrder->getBasket(); $basket = $newOrder->getBasket();
if (!$basket) { if (!$basket) {
$basket = Bitrix\Sale\Basket::create($site); $basket = Basket::create($site);
$newOrder->setBasket($basket); $newOrder->setBasket($basket);
} }
$fUserId = $basket->getFUserId(true); $fUserId = $basket->getFUserId(true);
if (!$fUserId) { if (!$fUserId) {
$fUserId = Bitrix\Sale\Fuser::getIdByUserId($order['customer']['externalId']); $fUserId = Fuser::getIdByUserId($order['customer']['externalId']);
$basket->setFUserId($fUserId); $basket->setFUserId($fUserId);
} }
@ -1010,7 +1022,6 @@ class RetailCrmHistory
if (!$item) { if (!$item) {
if ($product['delete']) { if ($product['delete']) {
continue; continue;
} }
@ -1124,7 +1135,7 @@ class RetailCrmHistory
} }
} }
if ($itemUpdate === true && $newOrder->getField('CANCELED') != 'Y') { if ($itemUpdate === true && $newOrder->getField('CANCELED') !== 'Y') {
self::shipmentItemReset($newOrder); self::shipmentItemReset($newOrder);
} }
@ -1161,7 +1172,7 @@ class RetailCrmHistory
$newOrder->setField('PRICE', $orderSumm); $newOrder->setField('PRICE', $orderSumm);
self::orderSave($newOrder); self::orderSave($newOrder);
if ($optionsOrderNumbers == 'Y' && isset($order['number'])) { if ($optionsOrderNumbers === 'Y' && isset($order['number'])) {
$newOrder->setField('ACCOUNT_NUMBER', $order['number']); $newOrder->setField('ACCOUNT_NUMBER', $order['number']);
self::orderSave($newOrder); self::orderSave($newOrder);
} }
@ -1191,7 +1202,7 @@ class RetailCrmHistory
); );
if ($paymentId) { if ($paymentId) {
\Bitrix\Sale\Internals\PaymentTable::update($paymentId, array('XML_ID' => '')); PaymentTable::update($paymentId, array('XML_ID' => ''));
} }
} }
} }
@ -1257,7 +1268,7 @@ class RetailCrmHistory
public static function assemblyCustomer($customerHistory) public static function assemblyCustomer($customerHistory)
{ {
$customerHistory = self::filterHistory($customerHistory, 'customer'); $customerHistory = self::filterHistory($customerHistory, 'customer');
$server = \Bitrix\Main\Context::getCurrent()->getServer()->getDocumentRoot(); $server = Context::getCurrent()->getServer()->getDocumentRoot();
$fields = array(); $fields = array();
if (file_exists($server . '/bitrix/modules/intaro.retailcrm/classes/general/config/objects.xml')) { if (file_exists($server . '/bitrix/modules/intaro.retailcrm/classes/general/config/objects.xml')) {
$objects = simplexml_load_file($server . '/bitrix/modules/intaro.retailcrm/classes/general/config/objects.xml'); $objects = simplexml_load_file($server . '/bitrix/modules/intaro.retailcrm/classes/general/config/objects.xml');
@ -1326,7 +1337,7 @@ class RetailCrmHistory
public static function assemblyOrder($orderHistory) public static function assemblyOrder($orderHistory)
{ {
$orderHistory = self::filterHistory($orderHistory, 'order'); $orderHistory = self::filterHistory($orderHistory, 'order');
$server = \Bitrix\Main\Context::getCurrent()->getServer()->getDocumentRoot(); $server = Context::getCurrent()->getServer()->getDocumentRoot();
if (file_exists($server . '/bitrix/modules/intaro.retailcrm/classes/general/config/objects.xml')) { if (file_exists($server . '/bitrix/modules/intaro.retailcrm/classes/general/config/objects.xml')) {
$objects = simplexml_load_file( $objects = simplexml_load_file(
@ -1342,8 +1353,10 @@ class RetailCrmHistory
foreach ($orderHistory as $change) { foreach ($orderHistory as $change) {
$change['order'] = self::removeEmpty($change['order']); $change['order'] = self::removeEmpty($change['order']);
if ($change['order']['items']) { if ($change['order']['items']) {
$items = array(); $items = [];
foreach ($change['order']['items'] as $item) { foreach ($change['order']['items'] as $item) {
if (isset($change['created'])) { if (isset($change['created'])) {
$item['create'] = 1; $item['create'] = 1;
@ -1357,6 +1370,10 @@ class RetailCrmHistory
$orders[$change['order']['id']]['number'] = $change['newValue']; $orders[$change['order']['id']]['number'] = $change['newValue'];
} }
if ($change['field'] == 'manager') {
$orders[$change['order']['id']]['managerId'] = $change['newValue'];
}
if (isset($change['oldValue']) && $change['field'] == 'customer') { if (isset($change['oldValue']) && $change['field'] == 'customer') {
$orders[$change['order']['id']]['customer'] = $change['newValue']; $orders[$change['order']['id']]['customer'] = $change['newValue'];
} }
@ -1562,8 +1579,8 @@ class RetailCrmHistory
$update = false; $update = false;
} }
$crmCode = isset($orderCrm['delivery']['code']) ? $orderCrm['delivery']['code'] : false; $crmCode = $orderCrm['delivery']['code'] ?? false;
$noDeliveryId = \Bitrix\Sale\Delivery\Services\EmptyDeliveryService::getEmptyDeliveryServiceId(); $noDeliveryId = EmptyDeliveryService::getEmptyDeliveryServiceId();
if ($crmCode === false || !isset($optionsDelivTypes[$crmCode])) { if ($crmCode === false || !isset($optionsDelivTypes[$crmCode])) {
$deliveryId = $noDeliveryId; $deliveryId = $noDeliveryId;
@ -1571,10 +1588,10 @@ class RetailCrmHistory
$deliveryId = $optionsDelivTypes[$crmCode]; $deliveryId = $optionsDelivTypes[$crmCode];
if (isset($orderCrm['delivery']['service']['code'])) { if (isset($orderCrm['delivery']['service']['code'])) {
$deliveryCode = \Bitrix\Sale\Delivery\Services\Manager::getCodeById($deliveryId); $deliveryCode = Manager::getCodeById($deliveryId);
$serviceCode = $orderCrm['delivery']['service']['code']; $serviceCode = $orderCrm['delivery']['service']['code'];
$service = \Bitrix\Sale\Delivery\Services\Manager::getService($deliveryId); $service = Manager::getService($deliveryId);
if (is_object($service)) { if (is_object($service)) {
$services = $service->getProfilesList(); $services = $service->getProfilesList();
if (!array_key_exists($serviceCode, $services)) { if (!array_key_exists($serviceCode, $services)) {
@ -1585,7 +1602,7 @@ class RetailCrmHistory
if ($deliveryCode) { if ($deliveryCode) {
try { try {
$deliveryService = \Bitrix\Sale\Delivery\Services\Manager::getObjectByCode($deliveryCode . ':' . $serviceCode); $deliveryService = Manager::getObjectByCode($deliveryCode . ':' . $serviceCode);
} catch (Bitrix\Main\SystemException $systemException) { } catch (Bitrix\Main\SystemException $systemException) {
RCrmActions::eventLog('RetailCrmHistory::deliveryEdit', '\Bitrix\Sale\Delivery\Services\Manager::getObjectByCode', $systemException->getMessage()); RCrmActions::eventLog('RetailCrmHistory::deliveryEdit', '\Bitrix\Sale\Delivery\Services\Manager::getObjectByCode', $systemException->getMessage());
} }
@ -1597,7 +1614,7 @@ class RetailCrmHistory
} }
} }
$delivery = \Bitrix\Sale\Delivery\Services\Manager::getObjectById($deliveryId); $delivery = Manager::getObjectById($deliveryId);
$shipmentColl = $order->getShipmentCollection(); $shipmentColl = $order->getShipmentCollection();
if ($delivery) { if ($delivery) {
@ -1910,39 +1927,45 @@ class RetailCrmHistory
return $val; return $val;
} }
}
class RetailUser extends CUser /**
{ * @param int $externalId
public function GetID() *
* @return void
*/
public static function cancelOrder(int $externalId)
{ {
$rsUser = CUser::GetList(($by = 'ID'), ($order = 'DESC'), array('LOGIN' => 'retailcrm')); try {
$newOrder = Order::load($externalId);
if ($arUser = $rsUser->Fetch()) { } catch (ArgumentNullException $e) {
return $arUser['ID']; RCrmActions::eventLog(
} else { 'RetailCrmHistory::orderHistory',
$retailUser = new CUser; 'Bitrix\Sale\Order::load',
$e->getMessage() . ': ' . $externalId
$userPassword = uniqid();
$arFields = array(
"NAME" => 'retailcrm',
"LAST_NAME" => 'retailcrm',
"EMAIL" => 'retailcrm@retailcrm.com',
"LOGIN" => 'retailcrm',
"LID" => "ru",
"ACTIVE" => "Y",
"GROUP_ID" => array(2),
"PASSWORD" => $userPassword,
"CONFIRM_PASSWORD" => $userPassword
); );
$id = $retailUser->Add($arFields);
if (!$id) { return;
return null; }
} else {
return $id; if (!$newOrder instanceof Order) {
} RCrmActions::eventLog(
'RetailCrmHistory::orderHistory',
'Bitrix\Sale\Order::load',
'Error order load: ' . $externalId
);
return;
}
try {
$newOrder->setField('CANCELED', 'Y');
$newOrder->save();
} catch (Exception $exception) {
RCrmActions::eventLog(
'RetailCrmHistory::orderHistory',
'Bitrix\Sale\Order::cancelOrder',
'Error order canceled: ' . $externalId
);
} }
} }
} }

View File

@ -0,0 +1,43 @@
<?php
/**
* Class RetailUser
*/
class RetailUser extends CUser
{
/**
* @return int|mixed|string|null
*/
public function GetID()
{
$rsUser = CUser::GetList(($by = 'ID'), ($order = 'DESC'), ['LOGIN' => 'retailcrm']);
if ($arUser = $rsUser->Fetch()) {
return $arUser['ID'];
} else {
$retailUser = new CUser;
$userPassword = uniqid();
$arFields = [
"NAME" => 'retailcrm',
"LAST_NAME" => 'retailcrm',
"EMAIL" => 'retailcrm@retailcrm.com',
"LOGIN" => 'retailcrm',
"LID" => "ru",
"ACTIVE" => "Y",
"GROUP_ID" => [2],
"PASSWORD" => $userPassword,
"CONFIRM_PASSWORD" => $userPassword,
];
$id = $retailUser->Add($arFields);
if (!$id) {
return null;
} else {
return $id;
}
}
}
}

View File

@ -86,7 +86,7 @@ class RetailCrmOrder
} elseif ($search = array_search($prop['CODE'], $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']])) {//other } elseif ($search = array_search($prop['CODE'], $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']])) {//other
if (in_array($search, array('fio', 'phone', 'email'))) {//fio, phone, email if (in_array($search, array('fio', 'phone', 'email'))) {//fio, phone, email
if ($search == 'fio') { if ($search == 'fio') {
$order = array_merge($order, RCrmActions::explodeFIO($prop['VALUE'][0]));//add fio fields $order = array_merge($order, RCrmActions::explodeFio($prop['VALUE'][0]));//add fio fields
} elseif ($search == 'email' && mb_strlen($prop['VALUE'][0]) > 100) { } elseif ($search == 'email' && mb_strlen($prop['VALUE'][0]) > 100) {
continue; continue;
} else { } else {

View File

@ -1,35 +1,53 @@
<?php <?php
use Bitrix\Main\Context;
use Bitrix\Main\Context\Culture;
use Bitrix\Main\UserTable; use Bitrix\Main\UserTable;
use Bitrix\Sale\Delivery\Services\Manager;
use Bitrix\Sale\Internals\Fields; use Bitrix\Sale\Internals\Fields;
use Bitrix\Sale\Location\LocationTable;
use Bitrix\Sale\Order; use Bitrix\Sale\Order;
use Bitrix\Sale\OrderTable;
use RetailCrm\ApiClient; use RetailCrm\ApiClient;
use Intaro\RetailCrm\Service\ManagerService;
use RetailCrm\Response\ApiResponse;
IncludeModuleLangFile(__FILE__); IncludeModuleLangFile(__FILE__);
/**
* Class RetailCrmOrder
*/
class RetailCrmOrder class RetailCrmOrder
{ {
/** /**
* *
* Creates order or returns order for mass upload * Creates order or returns order for mass upload
* *
* @param array $arFields * @param array $arOrder
* @param $api * @param $api
* @param $arParams * @param $arParams
* @param bool $send * @param bool $send
* @param null $site * @param null $site
* @param string $methodApi * @param string $methodApi
* *
* @return boolean * @return boolean|array
* @throws \Bitrix\Main\ArgumentException * @throws \Bitrix\Main\ArgumentException
* @throws \Bitrix\Main\ObjectPropertyException * @throws \Bitrix\Main\ObjectPropertyException
* @throws \Bitrix\Main\SystemException * @throws \Bitrix\Main\SystemException
*/ */
public static function orderSend($arFields, $api, $arParams, $send = false, $site = null, $methodApi = 'ordersEdit') public static function orderSend(
{ array $arOrder,
$api,
$arParams,
bool $send = false,
$site = null,
string $methodApi = 'ordersEdit'
) {
if (!$api || empty($arParams)) { // add cond to check $arParams if (!$api || empty($arParams)) { // add cond to check $arParams
return false; return false;
} }
if (empty($arFields)) {
if (empty($arOrder)) {
RCrmActions::eventLog('RetailCrmOrder::orderSend', 'empty($arFields)', 'incorrect order'); RCrmActions::eventLog('RetailCrmOrder::orderSend', 'empty($arFields)', 'incorrect order');
return false; return false;
} }
@ -38,23 +56,20 @@ class RetailCrmOrder
$currency = RetailcrmConfigProvider::getCurrencyOrDefault(); $currency = RetailcrmConfigProvider::getCurrencyOrDefault();
$optionCorpClient = RetailcrmConfigProvider::getCorporateClientStatus(); $optionCorpClient = RetailcrmConfigProvider::getCorporateClientStatus();
$order = array( $order = [
'number' => $arFields['NUMBER'], 'number' => $arOrder['NUMBER'],
'externalId' => $arFields['ID'], 'externalId' => $arOrder['ID'],
'createdAt' => $arFields['DATE_INSERT'], 'createdAt' => $arOrder['DATE_INSERT'],
'customer' => isset($arParams['customerCorporate']) 'customer' => isset($arParams['customerCorporate'])
? array('id' => $arParams['customerCorporate']['id']) ? ['id' => $arParams['customerCorporate']['id']]
: array('externalId' => $arFields['USER_ID']), : ['externalId' => $arOrder['USER_ID']],
'orderType' => isset($arParams['optionsOrderTypes'][$arFields['PERSON_TYPE_ID']]) ? 'orderType' => $arParams['optionsOrderTypes'][$arOrder['PERSON_TYPE_ID']] ?? '',
$arParams['optionsOrderTypes'][$arFields['PERSON_TYPE_ID']] : '', 'status' => $arParams['optionsPayStatuses'][$arOrder['STATUS_ID']] ?? '',
'status' => isset($arParams['optionsPayStatuses'][$arFields['STATUS_ID']]) ? 'customerComment' => $arOrder['USER_DESCRIPTION'],
$arParams['optionsPayStatuses'][$arFields['STATUS_ID']] : '', 'managerComment' => $arOrder['COMMENTS'],
'customerComment' => $arFields['USER_DESCRIPTION'], 'managerId' => $arParams['managerId'] ?? null,
'managerComment' => $arFields['COMMENTS'], 'delivery' => ['cost' => $arOrder['PRICE_DELIVERY']],
'delivery' => array( ];
'cost' => $arFields['PRICE_DELIVERY']
),
);
if (isset($arParams['contactExId'])) { if (isset($arParams['contactExId'])) {
$order['contact']['externalId'] = $arParams['contactExId']; $order['contact']['externalId'] = $arParams['contactExId'];
@ -76,7 +91,7 @@ class RetailCrmOrder
$order['customer']['browserId'] = $_COOKIE['_rc']; $order['customer']['browserId'] = $_COOKIE['_rc'];
} }
$order['contragent']['contragentType'] = $arParams['optionsContragentType'][$arFields['PERSON_TYPE_ID']]; $order['contragent']['contragentType'] = $arParams['optionsContragentType'][$arOrder['PERSON_TYPE_ID']];
if ($methodApi == 'ordersEdit') { if ($methodApi == 'ordersEdit') {
$order['discountManualAmount'] = 0; $order['discountManualAmount'] = 0;
@ -84,19 +99,19 @@ class RetailCrmOrder
} }
//fields //fields
foreach ($arFields['PROPS']['properties'] as $prop) { foreach ($arOrder['PROPS']['properties'] as $prop) {
if (!empty($arParams['optionsLegalDetails']) if (!empty($arParams['optionsLegalDetails'])
&& $search = array_search($prop['CODE'], $arParams['optionsLegalDetails'][$arFields['PERSON_TYPE_ID']]) && $search = array_search($prop['CODE'], $arParams['optionsLegalDetails'][$arOrder['PERSON_TYPE_ID']])
) { ) {
$order['contragent'][$search] = $prop['VALUE'][0];//legal order data $order['contragent'][$search] = $prop['VALUE'][0];//legal order data
} elseif (!empty($arParams['optionsCustomFields']) } elseif (!empty($arParams['optionsCustomFields'])
&& $search = array_search($prop['CODE'], $arParams['optionsCustomFields'][$arFields['PERSON_TYPE_ID']]) && $search = array_search($prop['CODE'], $arParams['optionsCustomFields'][$arOrder['PERSON_TYPE_ID']])
) { ) {
$order['customFields'][$search] = $prop['VALUE'][0];//custom properties $order['customFields'][$search] = $prop['VALUE'][0];//custom properties
} elseif ($search = array_search($prop['CODE'], $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']])) {//other } elseif ($search = array_search($prop['CODE'], $arParams['optionsOrderProps'][$arOrder['PERSON_TYPE_ID']])) {//other
if (in_array($search, array('fio', 'phone', 'email'))) {//fio, phone, email if (in_array($search, array('fio', 'phone', 'email'))) {//fio, phone, email
if ($search == 'fio') { if ($search == 'fio') {
$order = array_merge($order, RCrmActions::explodeFIO($prop['VALUE'][0]));//add fio fields $order = array_merge($order, RCrmActions::explodeFio($prop['VALUE'][0]));//add fio fields
} elseif ($search == 'email' && mb_strlen($prop['VALUE'][0]) > 100) { } elseif ($search == 'email' && mb_strlen($prop['VALUE'][0]) > 100) {
continue; continue;
} else { } else {
@ -109,10 +124,10 @@ class RetailCrmOrder
} }
} else {//address } else {//address
if ($prop['TYPE'] == 'LOCATION' && isset($prop['VALUE'][0]) && $prop['VALUE'][0] != '') { if ($prop['TYPE'] == 'LOCATION' && isset($prop['VALUE'][0]) && $prop['VALUE'][0] != '') {
$arLoc = \Bitrix\Sale\Location\LocationTable::getByCode($prop['VALUE'][0])->fetch(); $arLoc = LocationTable::getByCode($prop['VALUE'][0])->fetch();
if ($arLoc) { if ($arLoc) {
$server = \Bitrix\Main\Context::getCurrent()->getServer()->getDocumentRoot(); $server = Context::getCurrent()->getServer()->getDocumentRoot();
$countrys = array(); $countrys = [];
if (file_exists($server . '/bitrix/modules/intaro.retailcrm/classes/general/config/country.xml')) { if (file_exists($server . '/bitrix/modules/intaro.retailcrm/classes/general/config/country.xml')) {
$countrysFile = simplexml_load_file($server . '/bitrix/modules/intaro.retailcrm/classes/general/config/country.xml'); $countrysFile = simplexml_load_file($server . '/bitrix/modules/intaro.retailcrm/classes/general/config/country.xml');
@ -121,9 +136,9 @@ class RetailCrmOrder
} }
} }
$location = \Bitrix\Sale\Location\Name\LocationTable::getList(array( $location = \Bitrix\Sale\Location\Name\LocationTable::getList([
'filter' => array('=LOCATION_ID' => $arLoc['CITY_ID'], 'LANGUAGE_ID' => 'ru') 'filter' => ['=LOCATION_ID' => $arLoc['CITY_ID'], 'LANGUAGE_ID' => 'ru'],
))->fetch(); ])->fetch();
if (count($countrys) > 0) { if (count($countrys) > 0) {
$countryOrder = \Bitrix\Sale\Location\Name\LocationTable::getList(array( $countryOrder = \Bitrix\Sale\Location\Name\LocationTable::getList(array(
@ -145,10 +160,10 @@ class RetailCrmOrder
} }
//deliverys //deliverys
if (array_key_exists($arFields['DELIVERYS'][0]['id'], $arParams['optionsDelivTypes'])) { if (array_key_exists($arOrder['DELIVERYS'][0]['id'], $arParams['optionsDelivTypes'])) {
$order['delivery']['code'] = $arParams['optionsDelivTypes'][$arFields['DELIVERYS'][0]['id']]; $order['delivery']['code'] = $arParams['optionsDelivTypes'][$arOrder['DELIVERYS'][0]['id']];
if (isset($arFields['DELIVERYS'][0]['service']) && $arFields['DELIVERYS'][0]['service'] != '') { if (isset($arOrder['DELIVERYS'][0]['service']) && $arOrder['DELIVERYS'][0]['service'] != '') {
$order['delivery']['service']['code'] = $arFields['DELIVERYS'][0]['service']; $order['delivery']['service']['code'] = $arOrder['DELIVERYS'][0]['service'];
} }
} }
@ -168,7 +183,7 @@ class RetailCrmOrder
} }
//basket //basket
foreach ($arFields['BASKET'] as $position => $product) { foreach ($arOrder['BASKET'] as $position => $product) {
$itemId = null; $itemId = null;
$externalId = $position . "_" . $product['PRODUCT_ID']; $externalId = $position . "_" . $product['PRODUCT_ID'];
@ -197,15 +212,15 @@ class RetailCrmOrder
); );
} }
$item = array( $item = [
'externalIds' => $externalIds, 'externalIds' => $externalIds,
'quantity' => $product['QUANTITY'], 'quantity' => $product['QUANTITY'],
'offer' => array( 'offer' => [
'externalId' => $product['PRODUCT_ID'], 'externalId' => $product['PRODUCT_ID'],
'xmlId' => $product['PRODUCT_XML_ID'] 'xmlId' => $product['PRODUCT_XML_ID'],
), ],
'productName' => $product['NAME'] 'productName' => $product['NAME'],
); ];
if (isset($itemId)) { if (isset($itemId)) {
$item['id'] = $itemId; $item['id'] = $itemId;
@ -259,8 +274,9 @@ class RetailCrmOrder
$integrationPayment = RetailcrmConfigProvider::getIntegrationPaymentTypes(); $integrationPayment = RetailcrmConfigProvider::getIntegrationPaymentTypes();
//payments //payments
$payments = array(); $payments = [];
foreach ($arFields['PAYMENTS'] as $payment) {
foreach ($arOrder['PAYMENTS'] as $payment) {
if (!empty($payment['PAY_SYSTEM_ID']) && isset($arParams['optionsPayTypes'][$payment['PAY_SYSTEM_ID']])) { if (!empty($payment['PAY_SYSTEM_ID']) && isset($arParams['optionsPayTypes'][$payment['PAY_SYSTEM_ID']])) {
$pm = array( $pm = array(
'type' => $arParams['optionsPayTypes'][$payment['PAY_SYSTEM_ID']] 'type' => $arParams['optionsPayTypes'][$payment['PAY_SYSTEM_ID']]
@ -289,26 +305,25 @@ class RetailCrmOrder
RCrmActions::eventLog( RCrmActions::eventLog(
'RetailCrmOrder::orderSend', 'RetailCrmOrder::orderSend',
'payments', 'payments',
'OrderID = ' . $arFields['ID'] . '. Payment not found.' 'OrderID = ' . $arOrder['ID'] . '. Payment not found.'
); );
continue;
} }
} }
if (count($payments) > 0) { if (count($payments) > 0) {
$order['payments'] = $payments; $order['payments'] = $payments;
} }
//send //send
if (function_exists('retailCrmBeforeOrderSend')) { if (function_exists('retailCrmBeforeOrderSend')) {
$newResOrder = retailCrmBeforeOrderSend($order, $arFields); $newResOrder = retailCrmBeforeOrderSend($order, $arOrder);
if (is_array($newResOrder) && !empty($newResOrder)) { if (is_array($newResOrder) && !empty($newResOrder)) {
$order = $newResOrder; $order = $newResOrder;
} elseif ($newResOrder === false) { } elseif ($newResOrder === false) {
RCrmActions::eventLog( RCrmActions::eventLog(
'RetailCrmOrder::orderSend', 'RetailCrmOrder::orderSend',
'retailCrmBeforeOrderSend()', 'retailCrmBeforeOrderSend()',
'OrderID = ' . $arFields['ID'] . '. Sending canceled after retailCrmBeforeOrderSend' 'OrderID = ' . $arOrder['ID'] . '. Sending canceled after retailCrmBeforeOrderSend'
); );
return false; return false;
@ -336,17 +351,17 @@ class RetailCrmOrder
/** /**
* Mass order uploading, without repeating; always returns true, but writes error log * Mass order uploading, without repeating; always returns true, but writes error log
* *
* @param int $pSize * @param int $pSize
* @param bool $failed -- flag to export failed orders * @param bool $failed -- flag to export failed orders
* @param bool $orderList * @param array|null $orderList
* *
* @return boolean * @return boolean
* @throws \Bitrix\Main\ArgumentException
* @throws \Bitrix\Main\ArgumentNullException * @throws \Bitrix\Main\ArgumentNullException
* @throws \Bitrix\Main\ObjectPropertyException * @throws \Bitrix\Main\ObjectPropertyException
* @throws \Bitrix\Main\SystemException * @throws \Bitrix\Main\SystemException
* @throws \Bitrix\Main\ArgumentException
*/ */
public static function uploadOrders($pSize = 50, $failed = false, $orderList = false) public static function uploadOrders(int $pSize = 50, bool $failed = false, array $orderList = []): bool
{ {
if (!RetailcrmDependencyLoader::loadDependencies()) { if (!RetailcrmDependencyLoader::loadDependencies()) {
return true; return true;
@ -363,15 +378,15 @@ class RetailCrmOrder
if ($failed == true && $failedIds !== false && count($failedIds) > 0) { if ($failed == true && $failedIds !== false && count($failedIds) > 0) {
$orderIds = $failedIds; $orderIds = $failedIds;
} elseif ($orderList !== false && count($orderList) > 0) { } elseif (count($orderList) > 0) {
$orderIds = $orderList; $orderIds = $orderList;
} else { } else {
$dbOrder = \Bitrix\Sale\Internals\OrderTable::GetList(array( $dbOrder = OrderTable::GetList([
'order' => array("ID" => "ASC"), 'order' => ["ID" => "ASC"],
'filter' => array('>ID' => $lastUpOrderId), 'filter' => ['>ID' => $lastUpOrderId],
'limit' => $pSize, 'limit' => $pSize,
'select' => array('ID') 'select' => ['ID'],
)); ]);
while ($arOrder = $dbOrder->fetch()) { while ($arOrder = $dbOrder->fetch()) {
$orderIds[] = $arOrder['ID']; $orderIds[] = $arOrder['ID'];
@ -412,15 +427,16 @@ class RetailCrmOrder
foreach ($orderIds as $orderId) { foreach ($orderIds as $orderId) {
$site = null; $site = null;
$id = Order::load($orderId); $orderObj = Order::load($orderId);
if (!$id) { if (!$orderObj) {
continue; continue;
} }
$arCustomer = []; $arCustomer = [];
$arCustomerCorporate = []; $arCustomerCorporate = [];
$order = self::orderObjToArr($id); $order = self::orderObjToArr($orderObj);
$user = UserTable::getById($order['USER_ID'])->fetch();
$site = RetailCrmOrder::getSite($order['LID'], $optionsSitesList); $site = RetailCrmOrder::getSite($order['LID'], $optionsSitesList);
if (true === $site) { if (true === $site) {
@ -429,6 +445,11 @@ class RetailCrmOrder
self::createCustomerForOrder($api, $arCustomer, $arCustomerCorporate,$arParams, $order, $site); self::createCustomerForOrder($api, $arCustomer, $arCustomerCorporate,$arParams, $order, $site);
if (isset($order['RESPONSIBLE_ID']) && !empty($order['RESPONSIBLE_ID'])) {
$managerService = ManagerService::getInstance();
$arParams['managerId'] = $managerService->getManagerCrmId((int) $order['RESPONSIBLE_ID']);
}
$arOrders = self::orderSend($order, $api, $arParams, false, $site,'ordersCreate'); $arOrders = self::orderSend($order, $api, $arParams, false, $site,'ordersCreate');
if (!$arCustomer || !$arOrders) { if (!$arCustomer || !$arOrders) {
@ -498,6 +519,7 @@ class RetailCrmOrder
* @throws \Bitrix\Main\ArgumentException * @throws \Bitrix\Main\ArgumentException
* @throws \Bitrix\Main\ObjectPropertyException * @throws \Bitrix\Main\ObjectPropertyException
* @throws \Bitrix\Main\SystemException * @throws \Bitrix\Main\SystemException
* @throws \Exception
*/ */
public static function createCustomerForOrder( public static function createCustomerForOrder(
ApiClient $api, ApiClient $api,
@ -602,7 +624,7 @@ class RetailCrmOrder
$customerLegalName, $customerLegalName,
$orderData['delivery']['address']['text'], $orderData['delivery']['address']['text'],
$api, $api,
$site = null null
); );
} elseif (array_key_exists($customerLegalName, $resCustomersCorporate)) { } elseif (array_key_exists($customerLegalName, $resCustomersCorporate)) {
$createResponse = $api->customersCorporateCreate( $createResponse = $api->customersCorporateCreate(
@ -660,11 +682,11 @@ class RetailCrmOrder
/** /**
* @param string $key * @param string $key
* @param array $optionsSitesList * @param array $optionsSitesList
* *
* @return false|mixed|null * @return false|mixed|null
*/ */
public static function getSite($key, $optionsSitesList) public static function getSite(string $key, array $optionsSitesList)
{ {
if ($optionsSitesList) { if ($optionsSitesList) {
if (array_key_exists($key, $optionsSitesList) && $optionsSitesList[$key] != null) { if (array_key_exists($key, $optionsSitesList) && $optionsSitesList[$key] != null) {
@ -678,17 +700,17 @@ class RetailCrmOrder
} }
/** /**
* @param array $pack * @param array $pack
* @param string $method * @param string $method
* @param string $keyResponse * @param string $keyResponse
* @param RetailCrm\ApiClient $api * @param RetailCrm\ApiClient $api
* @param array $optionsSitesList * @param array $optionsSitesList
* *
* @return array|false * @return array|false
*/ */
public static function uploadItems($pack, $method, $keyResponse, $api, $optionsSitesList) public static function uploadItems(array $pack, string $method, string $keyResponse, ApiClient $api, array $optionsSitesList)
{ {
$uploaded = array(); $uploaded = [];
$sizePack = 50; $sizePack = 50;
foreach ($pack as $key => $itemLoad) { foreach ($pack as $key => $itemLoad) {
@ -716,7 +738,7 @@ class RetailCrmOrder
return false; return false;
} }
if ($response instanceof \RetailCrm\Response\ApiResponse) { if ($response instanceof ApiResponse) {
if ($response->offsetExists($keyResponse)) { if ($response->offsetExists($keyResponse)) {
$uploaded = array_merge($uploaded, $response[$keyResponse]); $uploaded = array_merge($uploaded, $response[$keyResponse]);
} }
@ -750,10 +772,10 @@ class RetailCrmOrder
* @return array * @return array
* @throws \Bitrix\Main\SystemException * @throws \Bitrix\Main\SystemException
*/ */
public static function orderObjToArr($obOrder) public static function orderObjToArr(Order $obOrder): array
{ {
$culture = new \Bitrix\Main\Context\Culture(array("FORMAT_DATETIME" => "Y-m-d HH:i:s")); $culture = new Culture(['FORMAT_DATETIME' => 'Y-m-d HH:i:s']);
$arOrder = array( $arOrder = [
'ID' => $obOrder->getId(), 'ID' => $obOrder->getId(),
'NUMBER' => $obOrder->getField('ACCOUNT_NUMBER'), 'NUMBER' => $obOrder->getField('ACCOUNT_NUMBER'),
'LID' => $obOrder->getSiteId(), 'LID' => $obOrder->getSiteId(),
@ -762,16 +784,17 @@ class RetailCrmOrder
'USER_ID' => $obOrder->getUserId(), 'USER_ID' => $obOrder->getUserId(),
'PERSON_TYPE_ID' => $obOrder->getPersonTypeId(), 'PERSON_TYPE_ID' => $obOrder->getPersonTypeId(),
'CURRENCY' => $obOrder->getCurrency(), 'CURRENCY' => $obOrder->getCurrency(),
'PAYMENTS' => array(), 'PAYMENTS' => [],
'DELIVERYS' => array(), 'DELIVERYS' => [],
'PRICE_DELIVERY' => $obOrder->getDeliveryPrice(), 'PRICE_DELIVERY' => $obOrder->getDeliveryPrice(),
'PROPS' => $obOrder->getPropertyCollection()->getArray(), 'PROPS' => $obOrder->getPropertyCollection()->getArray(),
'DISCOUNTS' => $obOrder->getDiscount()->getApplyResult(), 'DISCOUNTS' => $obOrder->getDiscount()->getApplyResult(),
'BASKET' => array(), 'BASKET' => [],
'USER_DESCRIPTION' => $obOrder->getField('USER_DESCRIPTION'), 'USER_DESCRIPTION' => $obOrder->getField('USER_DESCRIPTION'),
'COMMENTS' => $obOrder->getField('COMMENTS'), 'COMMENTS' => $obOrder->getField('COMMENTS'),
'REASON_CANCELED' => $obOrder->getField('REASON_CANCELED') 'REASON_CANCELED' => $obOrder->getField('REASON_CANCELED'),
); 'RESPONSIBLE_ID' => $obOrder->getField('RESPONSIBLE_ID'),
];
$shipmentList = $obOrder->getShipmentCollection(); $shipmentList = $obOrder->getShipmentCollection();
@ -781,18 +804,19 @@ class RetailCrmOrder
} }
if ($shipmentData->getDeliveryId()) { if ($shipmentData->getDeliveryId()) {
$delivery = \Bitrix\Sale\Delivery\Services\Manager::getById($shipmentData->getDeliveryId()); $delivery = Manager::getById($shipmentData->getDeliveryId());
$siteDeliverys = RCrmActions::DeliveryList(); $siteDeliverys = RCrmActions::DeliveryList();
foreach ($siteDeliverys as $siteDelivery) { foreach ($siteDeliverys as $siteDelivery) {
if ($siteDelivery['ID'] == $delivery['ID'] && $siteDelivery['PARENT_ID'] == 0) { if ($siteDelivery['ID'] == $delivery['ID'] && $siteDelivery['PARENT_ID'] == 0) {
unset($delivery['PARENT_ID']); unset($delivery['PARENT_ID']);
} }
} }
if ($delivery['PARENT_ID']) { if ($delivery['PARENT_ID']) {
$servise = explode(':', $delivery['CODE']); $service = explode(':', $delivery['CODE']);
$shipment = array('id' => $delivery['PARENT_ID'], 'service' => $servise[1]); $shipment = ['id' => $delivery['PARENT_ID'], 'service' => $service[1]];
} else { } else {
$shipment = array('id' => $delivery['ID']); $shipment = ['id' => $delivery['ID']];
} }
$arOrder['DELIVERYS'][] = $shipment; $arOrder['DELIVERYS'][] = $shipment;
} }
@ -812,7 +836,7 @@ class RetailCrmOrder
return $arOrder; return $arOrder;
} }
/** /**
* @param \Bitrix\Sale\Internals\Fields $product * @param \Bitrix\Sale\Internals\Fields $product
* *

View File

@ -0,0 +1,14 @@
<?php
namespace RetailCrm\Component\Exception;
use Exception;
/**
* Class FailedDbOperationException
*
* @package RetailCrm\Component\Exception
*/
class FailedDbOperationException extends Exception
{
}

View File

@ -0,0 +1,3 @@
<?php
$MESS['REP_ERR'] = 'Ошибка репозитория в методе #METHOD#';

View File

@ -0,0 +1,67 @@
<?php
namespace Intaro\RetailCrm\Repository;
use Bitrix\Main\ORM\Objectify\EntityObject;
use Bitrix\Main\UserTable;
use RetailCrm\Component\Exception\FailedDbOperationException;
use RetailcrmConfigProvider;
use RetailcrmConstants;
/**
* Class ManagerRepository
*
* @package Intaro\RetailCrm\Repository
*/
class ManagerRepository
{
/**
* @param array $newMatches
*
* @return void
* @throws \RetailCrm\Component\Exception\FailedDbOperationException
*/
public function addManagersToMapping(array $newMatches): void
{
$usersMap = RetailcrmConfigProvider::getUsersMap();
if (is_array($usersMap)) {
$recordData = array_merge($usersMap, $newMatches);
} else {
$recordData = $newMatches;
}
if (!RetailcrmConfigProvider::setUsersMap($recordData)) {
throw new FailedDbOperationException();
}
}
/**
* @param string $email
*
* @return int|null
* @throws \Bitrix\Main\ArgumentException
* @throws \Bitrix\Main\ObjectPropertyException
* @throws \Bitrix\Main\SystemException
*/
public function getManagerBitrixIdByEmail(string $email): ?int
{
/** @var \Bitrix\Main\ORM\Objectify\EntityObject $user */
$user = UserTable::query()
->addSelect('ID')
->where('EMAIL', $email)
->exec()
->fetchObject();
if ($user instanceof EntityObject) {
$userId = $user->get('ID');
if (is_int($userId) && $userId > 0) {
return $userId;
}
}
return null;
}
}

View File

@ -0,0 +1,202 @@
<?php
namespace Intaro\RetailCrm\Service;
use Bitrix\Main\ArgumentException;
use Bitrix\Main\ObjectPropertyException;
use Bitrix\Main\SystemException;
use Intaro\RetailCrm\Repository\ManagerRepository;
use InvalidArgumentException;
use Logger;
use RetailCrm\ApiClient;
use RetailCrm\Component\Exception\FailedDbOperationException;
use RetailcrmConfigProvider;
use RetailcrmConstants;
/**
* Отвечает за работу с ответственными лицами в заказах
*
* Class ManagerService
*
* @package Intaro\RetailCrm\Service
*/
class ManagerService
{
protected static $instance;
/**
* @var \Intaro\RetailCrm\Repository\ManagerRepository
*/
private $repository;
/**
* @var \RetailCrm\ApiClient
*/
private $client;
/**
* @var \Logger
*/
private $logger;
/**
* ManagerService constructor.
*/
private function __construct()
{
$this->client = new ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey());
$this->repository = new ManagerRepository();
$this->logger = Logger::getInstance();
}
/**
* @return \Intaro\RetailCrm\Service\ManagerService
*
* TODO заменить вызов на сервис-локатор, когда он приедет
*/
public static function getInstance(): ManagerService
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Синхронизирует пользователей CRM и Битрикс
*/
public function synchronizeManagers(): void
{
$currentPage = 1;
RetailcrmConfigProvider::setUsersMap([]);
do {
$crmUsers = $this->getCrmUsersPage($currentPage);
$matchesArray = $this->findMatchesInBitrix($crmUsers);
if (!empty($matchesArray)) {
try {
$this->repository->addManagersToMapping($matchesArray);
} catch (FailedDbOperationException $exception) {
$this->logger->write(GetMessage('REP_ERR', ['#METHOD#' => __METHOD__]),'serviceErrors');
}
}
$currentPage++;
} while (count($crmUsers) > 0);
}
/**
* @param string $bitrixUserId
*
* @return int|null
*/
public function getManagerCrmId(string $bitrixUserId): ?int
{
$usersMap = RetailcrmConfigProvider::getUsersMap();
return $usersMap[RetailcrmConstants::BITRIX_USER_ID_PREFIX . $bitrixUserId] ?? null;
}
/**
* @param int|null $crmManagerId
*
* @return int
*/
public function getManagerBitrixId(?int $crmManagerId): ?int
{
$usersMap = RetailcrmConfigProvider::getUsersMap();
if (!is_array($usersMap) || count($usersMap) === 0) {
return null;
}
$flipUserMap = array_flip($usersMap);
if (!isset($flipUserMap[$crmManagerId])) {
return null;
}
$managerId = str_replace(RetailcrmConstants::BITRIX_USER_ID_PREFIX, '', $flipUserMap[$crmManagerId]);
if (empty($managerId)) {
return null;
}
return (int) $managerId;
}
/**
* @param int $pageNumber
*
* @return array
*/
private function getCrmUsersPage(int $pageNumber): array
{
$response = $this->client->usersList([], $pageNumber);
if (!$response->isSuccessful()) {
return [];
}
try {
$users = $response->offsetGet('users');
if (is_array($users)) {
return $users;
}
return [];
} catch (InvalidArgumentException $exception) {
return [];
}
}
/**
* @param array $crmUsers
*
* @return array
*/
private function findMatchesInBitrix(array $crmUsers): array
{
$matchesUsers = [];
foreach ($crmUsers as $crmUser) {
$matchesUser = $this->getMatchesForCrmUser($crmUser);
if (count($matchesUser) > 0) {
$bitrixId = RetailcrmConstants::BITRIX_USER_ID_PREFIX . $matchesUser['bitrixUserId'];
$matchesUsers[$bitrixId] = $matchesUser['crmUserId'];
}
}
return $matchesUsers;
}
/**
* @param array $crmUser
*
* @return array
*/
private function getMatchesForCrmUser(array $crmUser): array
{
if (!empty($crmUser['email']) && !empty($crmUser['id'])) {
try {
$bitrixUserId = $this->repository->getManagerBitrixIdByEmail($crmUser['email']);
if (is_int($bitrixUserId)) {
return [
'bitrixUserId' => $bitrixUserId,
'crmUserId' => $crmUser['id']
];
}
} catch (ObjectPropertyException | ArgumentException | SystemException $e) {
$this->logger->write(GetMessage('REP_ERR', ['#METHOD#' => __METHOD__]), 'serviceErrors');
}
}
return [];
}
}

View File

@ -1,251 +0,0 @@
<?php
/**
* Class RetailCrmOrderTest
*/
use \Bitrix\Main\Loader;
use \Bitrix\Main\Application;
class RetailCrmOrderTest extends BitrixTestCase
{
protected $retailCrmOrder;
protected $test;
/**
* @inheritdoc
*/
public function setUp()
{
parent::setUp();
$cache = Application::getInstance()->getManagedCache();
$cache->clean('b_option:intaro.retailcrm');
$this->retailCrmOrder = \Mockery::mock('RetailCrmOrder');
COption::SetOptionString('intaro.retailcrm', 'api_version', 'v5');
CModule::IncludeModule('intaro.retailcrm');
RetailcrmConfigProvider::setPaymentTypes(['bitrixPayment' => 'crmPayment']);
RetailcrmConfigProvider::setIntegrationPaymentTypes(['crmPayment']);
}
public function testModuleInstalled()
{
$this->assertTrue(Loader::includeModule("intaro.retailcrm"));
}
/**
* @param $pSize
* @param $failed
* @param $orderList
*
* @dataProvider getData
*/
public function testUploadOrders($pSize, $failed, $orderList)
{
$this->assertEquals(50, $pSize);
$this->assertFalse($failed);
if ($orderList) {
$this->assertEquals(3, sizeof($orderList));
$this->retailCrmOrder->shouldReceive('uploadOrders')
->andReturn(
array(
array('id' => 001, 'externalId' => 2),
array('id' => 002, 'externalId' => 3),
array('id' => 003, 'externalId' => 4)
)
);
$result = $this->retailCrmOrder->uploadOrders();
foreach ($result as $key => $order) {
$this->assertEquals($order["externalId"], $orderList[$key]);
}
} else {
$this->assertFalse($orderList);
}
}
/**
* @return array
*/
public function getData()
{
return [
[
'pSize' => 50,
'failed' => false,
'orderList' => false
],
[
'pSize' => 50,
'failed' => false,
'orderList' => array(2,3,4)
]
];
}
/**
* @param $pack
* @param $method
* @param $keyResponse
* @param $apiMock
* @param $optionsSitesList
*
* @dataProvider getDataUpload
*/
public function testUploadItems($pack, $method, $keyResponse, $apiMock, $optionsSitesList)
{
$responseBody1 = '';
for ($i = 1; $i < 51; $i++) {
$responseBody1 .= "{\"id\":".$i.",\"externalId\":".$i."},";
}
$responseBody1 = substr($responseBody1,0,-1);
$responseBody1 ='{
"success":true,
"'.$keyResponse.'":['.$responseBody1.']
}';
$responseBody2 ='{
"success":true,
"uploadedCustomers":[
{"id":51,"externalId":"51"}
]
}';
$apiMock->shouldReceive($method)
->andReturn(
new \RetailCrm\Response\ApiResponse(
200,
$responseBody1
),
new \RetailCrm\Response\ApiResponse(
200,
$responseBody2
)
);
$test = new RetailCrmOrder();
$result = $test::uploadItems($pack, $method, $keyResponse, $apiMock, $optionsSitesList);
$this->assertEquals(sizeof($pack['s1']), sizeof($result));
}
/**
* @return mixed
*/
public function getCustomerList()
{
$faker = Faker\Factory::create();
$customerList = [];
for ($i = 1; $i < 52; $i++) {
$customerList['s1'][$i]['externalId'] = $i;
$customerList['s1'][$i]['email'] = $faker->email;
$customerList['s1'][$i]['createdAt'] = $faker->date('Y-m-d H:i:s');
$customerList['s1'][$i]['subscribed'] = '';
$customerList['s1'][$i]['contragent'] = ['contragentType' => 'individual'];
$customerList['s1'][$i]['firstName'] = $faker->firstName;
$customerList['s1'][$i]['lastName'] = $faker->lastName;
}
return $customerList;
}
/**
* @return array
*/
public function getDataUpload()
{
return [
[
'pack' => $this->getCustomerList(),
'customersUpload',
'uploadedCustomers',
'api'=>\Mockery::mock('RetailCrm\ApiClient'),
'optionsSitesList'=>[]
],
[
'pack'=> [],
'ordersUpload',
'uploadedOrders',
'api'=>\Mockery::mock('RetailCrm\ApiClient'),
'optionsSitesList'=>[]
]
];
}
/**
* @param array $arFields
* @param array $arParams
* @param string $methodApi
* @param array $expected
*
* @dataProvider orderSendProvider
*/
public function testOrderSend($arFields, $arParams, $methodApi, $expected)
{
$orderSend = RetailCrmOrder::orderSend(
$arFields,
new stdClass(),
$arParams,
false,
null,
$methodApi
);
$this->assertEquals($expected['payments'][0], $orderSend['payments'][0]);
}
/**
* @return array[]
*/
public function orderSendProvider()
{
$arFields = [
'ID' => 1,
'NUMBER' => 1,
'USER_ID' => 1,
'STATUS_ID' => 1,
'PERSON_TYPE_ID' => 'individual',
'DATE_INSERT' => '2015-02-22 00:00:00',
'USER_DESCRIPTION' => 'userComment',
'COMMENTS' => 'managerComment',
'PRICE_DELIVERY' => '100',
'PROPS' => ['properties' => []],
'DELIVERYS' => [[
'id' => 'test',
'service' => 'service'
]],
'BASKET' => [],
'PAYMENTS' => [[
'ID' => 1,
'PAY_SYSTEM_ID' => 'bitrixPayment',
'SUM' => 1000,
'DATE_PAID' => '2021-02-08 10:36:16',
'PAID' => 'paid'
]]
];
$arParams = [
'optionsPayTypes' => ['bitrixPayment' => 'crmPayment'],
'optionsPayment' => ['paid' => 'Y']
];
return [[
'arFields' => $arFields,
'arParams' => $arParams,
'methodApi' => 'ordersCreate',
'expected' => [
'number' => strval($arFields['NUMBER']),
'externalId' => strval($arFields['ID']),
'payments' => [[
'type' => $arParams['optionsPayTypes'][$arFields['PAYMENTS'][0]['PAY_SYSTEM_ID']],
'externalId' => RCrmActions::generatePaymentExternalId($arFields['PAYMENTS'][0]['ID']),
'paidAt' => '2021-02-08 10:36:16'
]]
],
]];
}
}