1
0
Fork 0
mirror of synced 2025-04-20 01:10:55 +00:00

Compare commits

..

No commits in common. "master" and "v1.0.0" have entirely different histories.

25 changed files with 1829 additions and 464 deletions

View file

@ -23,7 +23,7 @@ Module allows integrate UMI.CMS with [RetailCRM](http://www.retailcrm.pro)
Add to cron:
```
0 */4 * * * /usr/bin/php /path_to_site/public_html/cron.php RetailCRM icml
* */4 * * * /usr/bin/php /path_to_site/public_html/cron.php RetailCRM icml
```
#### Getting changes in orders

View file

@ -20,7 +20,7 @@ UMI.CMS module
Добавьте в крон запись вида
```
0 */4 * * * /usr/bin/php /path_to_site/public_html/cron.php RetailCRM icml
* */4 * * * /usr/bin/php /path_to_site/public_html/cron.php RetailCRM icml
```
#### Получение изменение из RetailCRM

32
classes/modules/RetailCRM/__admin.php Executable file → Normal file
View file

@ -23,7 +23,8 @@ abstract class __RetailCRM_adm extends baseModuleAdmin
if (!empty($apiKey) && !empty($crmUrl)) {
$api = new RCrmProxy(
$config->get('retailcrm', 'crmUrl'),
$config->get('retailcrm', 'apiKey')
$config->get('retailcrm', 'apiKey'),
__DIR__ . '/../../../retailcrm.error.log'
);
if($api->paymentTypesList() !== false) {
@ -35,7 +36,7 @@ abstract class __RetailCRM_adm extends baseModuleAdmin
$umiPaymentTypes = new selector('objects');
$umiPaymentTypes->types('object-type')->name('emarket', 'payment');
$map = RCrmHelpers::getRelationMap($config->get('retailcrm', 'orderPaymentTypeMap'));
$map = $this->getRelationMap($config->get('retailcrm', 'orderPaymentTypeMap'));
$orderPaymentsMapping = array();
foreach ($umiPaymentTypes->result() as $umiPaymentType) {
@ -45,7 +46,7 @@ abstract class __RetailCRM_adm extends baseModuleAdmin
$translations['order-payment-type-' . $umiPaymentTypeId] = $umiPaymentTypeName;
$orderPaymentsMapping['select:order-payment-type-' . $umiPaymentTypeId] = array();
$orderPaymentsMapping['select:order-payment-type-' . $umiPaymentTypeId]['value'] = RCrmHelpers::getRelationByMap($map,
$orderPaymentsMapping['select:order-payment-type-' . $umiPaymentTypeId]['value'] = $this->getRelationByMap($map,
$umiPaymentTypeId);
$orderPaymentsMapping['select:order-payment-type-' . $umiPaymentTypeId]['none'] = '';
@ -62,7 +63,7 @@ abstract class __RetailCRM_adm extends baseModuleAdmin
$umiDeliveryTypes = new selector('objects');
$umiDeliveryTypes->types('object-type')->name('emarket', 'delivery');
$map = RCrmHelpers::getRelationMap($config->get('retailcrm', 'orderDeliveryTypeMap'));
$map = $this->getRelationMap($config->get('retailcrm', 'orderDeliveryTypeMap'));
$orderDeliveryTypesMapping = array();
foreach ($umiDeliveryTypes as $umiDeliveryType) {
@ -72,7 +73,7 @@ abstract class __RetailCRM_adm extends baseModuleAdmin
$translations['order-delivery-type-' . $umiDeliveryTypeId] = $umiDeliveryTypeName;
$orderDeliveryTypesMapping['select:order-delivery-type-' . $umiDeliveryTypeId] = array();
$orderDeliveryTypesMapping['select:order-delivery-type-' . $umiDeliveryTypeId]['value'] = RCrmHelpers::getRelationByMap($map,
$orderDeliveryTypesMapping['select:order-delivery-type-' . $umiDeliveryTypeId]['value'] = $this->getRelationByMap($map,
$umiDeliveryTypeId);
$orderDeliveryTypesMapping['select:order-delivery-type-' . $umiDeliveryTypeId]['none'] = '';
@ -90,7 +91,7 @@ abstract class __RetailCRM_adm extends baseModuleAdmin
$umiPaymentStatuses = new selector('objects');
$umiPaymentStatuses->types('object-type')->name('emarket', 'order_payment_status');
$map = RCrmHelpers::getRelationMap($config->get('retailcrm', 'orderPaymentStatusMap'));
$map = $this->getRelationMap($config->get('retailcrm', 'orderPaymentStatusMap'));
$orderPaymentStatusesMapping = array();
foreach ($umiPaymentStatuses->result() as $umiPaymentStatus) {
@ -100,7 +101,7 @@ abstract class __RetailCRM_adm extends baseModuleAdmin
$translations['order-payment-status-' . $umiPaymentStatusId] = $umiPaymentStatusName;
$orderPaymentStatusesMapping['select:order-payment-status-' . $umiPaymentStatusId] = array();
$orderPaymentStatusesMapping['select:order-payment-status-' . $umiPaymentStatusId]['value'] = RCrmHelpers::getRelationByMap($map,
$orderPaymentStatusesMapping['select:order-payment-status-' . $umiPaymentStatusId]['value'] = $this->getRelationByMap($map,
$umiPaymentStatusId);
$orderPaymentStatusesMapping['select:order-payment-status-' . $umiPaymentStatusId]['none'] = '';
@ -117,29 +118,26 @@ abstract class __RetailCRM_adm extends baseModuleAdmin
$umiOrderStatuses = new selector('objects');
$umiOrderStatuses->types('object-type')->name('emarket', 'order_status');
$map = RCrmHelpers::getRelationMap($config->get('retailcrm', 'orderStatusMap'));
$map = $this->getRelationMap($config->get('retailcrm', 'orderStatusMap'));
$params['orderStatusesMapping'] = array();
foreach ($umiOrderStatuses->result() as $umiOrderStatus) {
$codeName = $umiOrderStatus->getValue('codename');
$translations['order-status-' . $umiOrderStatus->getPropByName('codename')->getValue()] = $umiOrderStatus->getName();
$translations['order-status-' . $codeName] = $umiOrderStatus->getName();
$params['orderStatusesMapping']['select:order-status-' . $codeName] = array();
$params['orderStatusesMapping']['select:order-status-' . $codeName]['value'] = RCrmHelpers::getRelationByMap($map, $codeName);
$params['orderStatusesMapping']['select:order-status-' . $codeName]['none'] = '';
$params['orderStatusesMapping']['select:order-status-' . $umiOrderStatus->getPropByName('codename')->getValue()] = array();
$params['orderStatusesMapping']['select:order-status-' . $umiOrderStatus->getPropByName('codename')->getValue()]['value'] = $this->getRelationByMap($map,
$umiOrderStatus->getPropByName('codename')->getValue());
$params['orderStatusesMapping']['select:order-status-' . $umiOrderStatus->getPropByName('codename')->getValue()]['none'] = '';
foreach ($crmOrderStatuses as $crmOrderStatus) {
$params['orderStatusesMapping']['select:order-status-' . $codeName][$crmOrderStatus['code']] = $crmOrderStatus['name'];
$params['orderStatusesMapping']['select:order-status-' . $umiOrderStatus->getPropByName('codename')->getValue()][$crmOrderStatus['code']] = $crmOrderStatus['name'];
}
}
$params['guidesMapping']['select:country'] = array();
$params['guidesMapping']['select:country']['value'] = $config->get('retailcrm', 'countryGuideId');
$params['guidesMapping']['select:country']['none'] = '';
$objectTypes = umiObjectTypesCollection::getInstance();
foreach ($objectTypes->getGuidesList() as $guideId => $guideName) {
$params['guidesMapping']['select:country'][$guideId] = $guideName;
}

0
classes/modules/RetailCRM/__events.php Executable file → Normal file
View file

37
classes/modules/RetailCRM/class.php Executable file → Normal file
View file

@ -4,33 +4,32 @@ class RetailCRM extends def_module {
{
parent::__construct();
if (cmsController::getInstance()->getCurrentMode() == 'admin') {
$this->__loadLib('__admin.php');
$this->__implement('__RetailCRM_adm');
if (cmsController::getInstance()->getCurrentMode() == "admin") {
$this->__loadLib("__admin.php");
$this->__implement("__RetailCRM_adm");
}
// Подключаем модуль интернет магазина
cmsController::getInstance()->getModule("emarket");
$this->__loadLib("../emarket/includes.php");
// RetailCRM classes
$this->__loadLib('classes/retailcrm/RCrmActions.php');
$this->__loadLib('classes/retailcrm/RCrmApiClient.php');
$this->__loadLib('classes/retailcrm/RCrmApiResponse.php');
$this->__loadLib('classes/retailcrm/RCrmHistory.php');
$this->__loadLib('classes/retailcrm/RCrmHttpClient.php');
$this->__loadLib('classes/retailcrm/RCrmIcml.php');
$this->__loadLib('classes/retailcrm/RCrmProxy.php');
$this->__loadLib("classes/retailcrm/RCrmActions.php");
$this->__loadLib("classes/retailcrm/RCrmApiClient.php");
$this->__loadLib("classes/retailcrm/RCrmApiResponse.php");
$this->__loadLib("classes/retailcrm/RCrmHistory.php");
$this->__loadLib("classes/retailcrm/RCrmHttpClient.php");
$this->__loadLib("classes/retailcrm/RCrmIcml.php");
$this->__loadLib("classes/retailcrm/RCrmProxy.php");
// Exceptions
$this->__loadLib('classes/retailcrm/RCrmCurlException.php');
$this->__loadLib('classes/retailcrm/RCrmJsonException.php');
$this->__loadLib("classes/retailcrm/RCrmCurlException.php");
$this->__loadLib("classes/retailcrm/RCrmJsonException.php");
// Helpers
$this->__loadLib('classes/retailcrm/RCrmHelpers.php');
$this->__implement('RCrmHelpers');
$this->__loadLib("classes/retailcrm/RCrmHelpers.php");
$this->__implement("RCrmHelpers");
// Events
$this->__loadLib('__events.php');
$this->__implement('__RetailCRM_events');
$this->__loadLib("__events.php");
$this->__implement("__RetailCRM_events");
}
}

View file

@ -2,82 +2,75 @@
class RCrmActions
{
/**
* @param int $orderId
*/
public static function orderSend($orderId) {
public static function orderSend($orderId, $mode = 'create') {
/** @var RCrmApiClient $api */
$objects = umiObjectsCollection::getInstance();
$orderObj = order::get($orderId);
$order = order::get($orderId);
if (!$orderObj) {
if (!$order) {
return;
}
// Проверяем был ли вызов из апи
$regedit = regedit::getInstance();
$time = $regedit->getVal('//modules/RetailCRM/IgnoreObjectUpdateEvent/' . $orderObj->getObject()->getId());
if ($time == $orderObj->getObject()->getUpdateTime() OR $time + 1 == $orderObj->getObject()->getUpdateTime()) {
$time = $regedit->getVal('//modules/RetailCRM/IgnoreObjectUpdateEvent/' . $order->getObject()->getId());
if ($time == $order->getObject()->getUpdateTime() OR $time + 1 == $order->getObject()->getUpdateTime()) {
return;
}
$config = mainConfiguration::getInstance();
$umiOrderStatusCode = order::getCodeByStatus($orderObj->getOrderStatus());
$umiOrderStatusCode = order::getCodeByStatus($order->getOrderStatus());
$relationMap = RCrmHelpers::getRelationMap($config->get('retailcrm', 'orderStatusMap'));
$crmOrderStatusCode = RCrmHelpers::getRelationByMap($relationMap, $umiOrderStatusCode);
$retailcrm = new RetailCRM;
$relationMap = $retailcrm->getRelationMap($config->get('retailcrm', 'orderStatusMap'));
$crmOrderStatusCode = $retailcrm->getRelationByMap($relationMap, $umiOrderStatusCode);
if (!$crmOrderStatusCode) {
return;
}
$umiOrderPaymentType = $orderObj->getObject()->getValue('payment_id');
$relationOrderPaymentTypesMap = RCrmHelpers::getRelationMap($config->get('retailcrm', 'orderPaymentTypeMap'));
$crmOrderPaymentType = RCrmHelpers::getRelationByMap($relationOrderPaymentTypesMap, $umiOrderPaymentType);
$umiOrderPaymentType = $order->getObject()->getValue('payment_id');
$relationOrderPaymentTypesMap = $retailcrm->getRelationMap($config->get('retailcrm', 'orderPaymentTypeMap'));
$crmOrderPaymentType = $retailcrm->getRelationByMap($relationOrderPaymentTypesMap, $umiOrderPaymentType);
$umiOrderPaymentStatus = $orderObj->getObject()->getValue('payment_status_id');
$relationOrderPaymentStatusesMap = RCrmHelpers::getRelationMap($config->get('retailcrm', 'orderPaymentStatusMap'));
$crmOrderPaymentStatus = RCrmHelpers::getRelationByMap($relationOrderPaymentStatusesMap, $umiOrderPaymentStatus);
$umiOrderPaymentStatus = $order->getObject()->getValue('payment_status_id');
$relationOrderPaymentStatusesMap = $retailcrm->getRelationMap($config->get('retailcrm', 'orderPaymentStatusMap'));
$crmOrderPaymentStatus = $retailcrm->getRelationByMap($relationOrderPaymentStatusesMap, $umiOrderPaymentStatus);
$umiOrderDeliveryId = $orderObj->getObject()->getValue('delivery_id');
$relationOrderDeliveryTypesMap = RCrmHelpers::getRelationMap($config->get('retailcrm', 'orderDeliveryTypeMap'));
$crmOrderDeliveryType = RCrmHelpers::getRelationByMap($relationOrderDeliveryTypesMap, $umiOrderDeliveryId);
$umiOrderDeliveryId = $order->getObject()->getValue('delivery_id');
$relationOrderDeliveryTypesMap = $retailcrm->getRelationMap($config->get('retailcrm', 'orderDeliveryTypeMap'));
$crmOrderDeliveryType = $retailcrm->getRelationByMap($relationOrderDeliveryTypesMap, $umiOrderDeliveryId);
$customer = new umiObject($orderObj->getCustomerId());
$orderItemsObj = $orderObj->getItems();
$customer = customer::get($order->getCustomerId());
$orderItems = $order->getItems();
$orderItems = array();
$orderItemsToCrm = array();
foreach ($orderItemsObj as $orderItem) {
foreach ($orderItems as $orderItem) {
/** @var optionedOrderItem $orderItem */
$itemProperties = array();
if (get_class($orderItem) == 'optionedOrderItem') {
foreach ($orderItem->getOptions() as $option) {
$option = new umiObject($option['option-id']);
$itemProperties[] = array(
'name' => $option->getType()->getName(),
'value' => $option->getName()
);
}
$itemProperties = array();
foreach ($orderItem->getOptions() as $option) {
$option = new umiObject($option['option-id']);
$itemProperties[] = array(
'name' => $option->getType()->getName(),
'value' => $option->getName()
);
}
$optionGroups = $orderItem->getItemElement()->getObject()->getType()->getFieldsGroupByName('catalog_option_props')->getFields();
$optionGuidesToGroups = array();
foreach ($optionGroups as $optionGroup) {
/** @var umiField $optionGroup */
$optionGuidesToGroups[$optionGroup->getGuideId()] = $optionGroup->getId();
}
$options = array();
if (get_class($orderItem) == 'optionedOrderItem') {
foreach ($orderItem->getOptions() as $option) {
$option = $objects->getObject($option['option-id']);
$options[] = $optionGuidesToGroups[$option->getTypeId()] . '_' . $option->getId();
}
foreach ($orderItem->getOptions() as $option) {
$option = $objects->getObject($option['option-id']);
$options[] = $optionGuidesToGroups[$option->getTypeId()] . '_' . $option->getId();
}
$product = $orderItem->getItemElement();
@ -88,25 +81,11 @@ class RCrmActions
$productId = $product->getId();
}
if (get_class($orderItem) == 'optionedOrderItem') {
$productName = $product->getName();
} else {
$productName = $orderItem->getName();
}
if ($orderItem->getDiscount()) {
$discount = $orderItem->getDiscount();
} else if ($orderItem->getValue('item_discount_value')) {
$discount = $orderItem->getValue('item_discount_value');
} else {
$discount = 0;
}
$orderItems[] = array(
$orderItemsToCrm[] = array(
'initialPrice' => $orderItem->getItemPrice(),
'discount' => $discount,
'discount' => $orderItem->getDiscount(),
'quantity' => $orderItem->getAmount(),
'productName' => $productName,
'productName' => $product->getName(),
'properties' => $itemProperties,
'offer' => array(
'externalId' => $productId
@ -115,36 +94,31 @@ class RCrmActions
}
/* One click order */
if ($orderObj->getObject()->getValue('purchaser_one_click') !== null) {
$oneClickObj = new umiObject($orderObj->getObject()->getValue('purchaser_one_click'));
if ($order->getObject()->getValue('purchaser_one_click') !== null) {
$oneClickObj = new umiObject($order->getObject()->getValue('purchaser_one_click'));
$order = array(
'number' => $orderObj->getObject()->getValue('number'),
'externalId' => $orderObj->getId(),
'lastName' => $oneClickObj->getValue('lname'),
'firstName' => $oneClickObj->getValue('fname'),
'patronymic' => $oneClickObj->getValue('father_name'),
$orderToCrm = array(
'number' => $order->getObject()->getName(),
'externalId' => $order->getId(),
'phone' => $oneClickObj->getValue('phone'),
'customer' => array(
'externalId' => $customer->getId()
),
'items' => $orderItems,
'paymentType' => $crmOrderPaymentType,
'paymentStatus' => $crmOrderPaymentStatus,
'status' => $crmOrderStatusCode,
'items' => $orderItemsToCrm,
'orderMethod' => 'one-click'
);
} else {
if ($orderObj->getObject()->getValue('delivery_address') !== null) {
$deliveryObjId = $orderObj->getObject()->getValue('delivery_address');
if ($order->getObject()->getValue('delivery_address') !== null) {
$deliveryObjId = $order->getObject()->getValue('delivery_address');
$deliveryObj = new umiObject($deliveryObjId);
if ($deliveryObj->getValue('country') !== null) {
if ($deliveryObj->getValue('country') !== false) {
$deliveryCountryObjId = $deliveryObj->getValue('country');
try {
$deliveryCountryObj = new umiObject($deliveryCountryObjId);
$deliveryCountryIsoCode = $deliveryCountryObj->getValue('country_iso_code');
} catch (Exception $e) {
$deliveryCountryIsoCode = '';
}
$deliveryCountryObj = new umiObject($deliveryCountryObjId);
$deliveryCountryIsoCode = $deliveryCountryObj->getValue('country_iso_code');
} else {
$deliveryCountryIsoCode = '';
}
@ -157,28 +131,20 @@ class RCrmActions
$deliveryNotes = $deliveryObj->getValue('order_comments');
if ($deliveryObj->getValue('region') !== null) {
try {
$deliveryRegionObj = new umiObject($deliveryObj->getValue('region'));
$deliveryRegion = $deliveryRegionObj->getName();
} catch (Exception $e) {
$deliveryRegion = $deliveryObj->getValue('region');
}
$deliveryRegionObj = new umiObject($deliveryObj->getValue('region'));
$deliveryRegion = $deliveryRegionObj->getName();
} else {
$deliveryRegion = '';
}
if ($deliveryObj->getValue('city') !== null) {
try {
$deliveryCityObj = new umiObject($deliveryObj->getValue('city'));
$deliveryCity = $deliveryCityObj->getName();
} catch (Exception $e) {
$deliveryCity = $deliveryObj->getValue('city');
}
$deliveryCityObj = new umiObject($deliveryObj->getValue('city'));
$deliveryCity = $deliveryCityObj->getName();
} else {
$deliveryCity = '';
}
$deliveryAddress = array(
$addressToCrm = array(
'countryIso' => $deliveryCountryIsoCode,
'index' => $deliveryIndex,
'region' => $deliveryRegion,
@ -189,142 +155,111 @@ class RCrmActions
'house' => $deliveryHouse,
'notes' => $deliveryNotes
);
} else {
$deliveryAddress = array();
$addressToCrm = array();
}
$order = array(
'number' => $orderObj->getObject()->getValue('number'),
'externalId' => $orderObj->getId(),
$orderToCrm = array(
'number' => $order->getObject()->getName(),
'externalId' => $order->getId(),
'lastName' => $customer->getValue('lname'),
'firstName' => $customer->getValue('fname'),
'patronymic' => $customer->getValue('father_name'),
'phone' => $customer->getValue('phone'),
'email' => $customer->getValue('email'),
'customer' => array(
'externalId' => $customer->getId()
),
'items' => $orderItems,
'paymentType' => $crmOrderPaymentType,
'paymentStatus' => $crmOrderPaymentStatus,
'status' => $crmOrderStatusCode,
'items' => $orderItemsToCrm,
'delivery' => array(
'address' => $deliveryAddress,
'address' => $addressToCrm,
'code' => $crmOrderDeliveryType
)
);
}
if ($crmOrderStatusCode && $crmOrderStatusCode != 'none') {
$order['status'] = $crmOrderStatusCode;
}
if ($crmOrderDeliveryType && $crmOrderDeliveryType != 'none') {
$order['delivery']['code'] = $crmOrderDeliveryType;
}
if ($crmOrderPaymentType && $crmOrderPaymentType != 'none') {
$order['paymentType'] = $crmOrderPaymentType;
}
if ($crmOrderPaymentStatus && $crmOrderPaymentStatus != 'none') {
$order['paymentStatus'] = $crmOrderPaymentStatus;
}
if ($customer->getTypeGUID() == 'emarket-customer') {
$email = $customer->getValue('email');
} else if ($customer->getTypeGUID() == 'users-user') {
$email = $customer->getValue('e-mail');
} else {
$email = '';
}
if ($email = filter_var($email, FILTER_VALIDATE_EMAIL)) {
$order['email'] = $email;
}
if ($deliveryCost = $orderObj->getValue('delivery_price')) {
$order['delivery']['cost'] = $deliveryCost;
}
// TODO: есть возможность учитывать домен
$api = new RCrmProxy(
$config->get('retailcrm', 'crmUrl'),
$config->get('retailcrm', 'apiKey')
$config->get('retailcrm', 'apiKey'),
__DIR__ . '/../../../retailcrm.error.log'
);
$response = $api->ordersGet($order['externalId']);
$order = self::customerPrepare($order);
if ($response->isSuccessful()) {
$api->ordersEdit($order);
} else {
$api->ordersCreate($order);
if ($mode == 'create') {
$orderToCrm = self::customerPrepare($orderToCrm);
$api->ordersCreate($orderToCrm);
} else if ($mode == 'edit') {
$api->ordersEdit($orderToCrm);
}
}
/**
* @param array $order
* @return array
*/
public static function customerPrepare(array $order) {
public static function customerPrepare($orderToCrm) {
$config = mainConfiguration::getInstance();
/** @var RCrmApiClient $api */
$api = new RCrmProxy(
$config->get('retailcrm', 'crmUrl'),
$config->get('retailcrm', 'apiKey')
$config->get('retailcrm', 'apiKey'),
__DIR__ . '/../../../retailcrm.error.log'
);
$crmCustomer = $api->customersGet(
$order['customer']['externalId']
);
$crmCustomer = $api->customersGet($orderToCrm['customer']['externalId']);
if (!$crmCustomer->isSuccessful()) {
if (!$crmCustomer) {
$crmCustomers = $api->customersList(array(
'name' => $order['phone'],
'email' => $order['email']
'name' => $orderToCrm['phone'],
'email' => $orderToCrm['email']
));
$foundedCustomerExternalId = false;
if ($crmCustomers->isSuccessful()) {
$crmCustomers = $crmCustomers->offsetGet('customers');
if ($crmCustomers) {
/** @var RCrmApiResponse $crmCustomers */
$crmCustomers = $crmCustomers->getCustomers();
if (count($crmCustomers) > 0) {
foreach ($crmCustomers as $crmCustomer) {
if (isset($crmCustomer['externalId']) && $crmCustomer['externalId'] > 0) {
$foundedCustomerExternalId = true;
$order['customer']['externalId'] = $crmCustomer['externalId'];
$orderToCrm['customer']['externalId'] = $crmCustomer['externalId'];
break;
}
}
if (!$foundedCustomerExternalId) {
$crmCustomer = $crmCustomers[0];
$status = $api->customersFixExternalIds(array(
'id' => $crmCustomers[0]['id'],
'externalId' => $crmCustomers[0]['externalId']
'id' => $crmCustomer['id'],
'externalId' => $crmCustomer['externalId']
));
if (!$status->isSuccessful()) {
unset($order['customer']);
if (!$status) {
unset($orderToCrm['customer']);
}
}
} else {
$status = $api->customersCreate(array(
'externalId' => $order['customer']['externalId'],
'firstName' => $order['firstName'],
'lastName' => $order['lastName'],
'patronymic' => $order['patronymic'],
'email' => $order['email'],
'externalId' => $orderToCrm['customer']['externalId'],
'firstName' => $orderToCrm['firstName'],
'lastName' => $orderToCrm['lastName'],
'patronymic' => $orderToCrm['patronymic'],
'email' => $orderToCrm['email'],
'phones' => array(
'number' => $order['phone']
'number' => $orderToCrm['phone']
)
));
if (!$status->isSuccessful()) {
unset($order['customer']);
if (!$status) {
unset($orderToCrm['customer']);
}
}
} else {
unset($order['customer']);
unset($orderToCrm['customer']);
}
}
return $order;
return $orderToCrm;
}
}
}

View file

View file

View file

View file

@ -1,13 +1,13 @@
<?php
class RCrmHelpers
abstract class RCrmHelpers
{
/**
* @param $mapArr array
* @return array
*/
public static function getRelationMap($mapArr)
public function getRelationMap($mapArr)
{
if (empty($mapArr)) {
return array();
@ -28,7 +28,7 @@ class RCrmHelpers
* @param $reversed bool
* @return string|null
*/
public static function getRelationByMap($map, $item, $reversed = false)
public function getRelationByMap($map, $item, $reversed = false)
{
if (!$reversed) {
if (isset($map[$item]) && !empty($map[$item])) {
@ -50,7 +50,7 @@ class RCrmHelpers
* @param $orderHistory array
* @return array
*/
public static function getAssemblyOrder($orderHistory)
public function getAssemblyOrder($orderHistory)
{
if (file_exists(__DIR__ . '/../../data/objects.xml')) {
$objects = simplexml_load_file(__DIR__ . '/../../data/objects.xml');
@ -62,7 +62,7 @@ class RCrmHelpers
$orders = array();
foreach ($orderHistory as $change) {
$change['order'] = self::removeEmpty($change['order']);
$change['order'] = $this->removeEmpty($change['order']);
$orderId = $change['order']['id'];
@ -106,24 +106,24 @@ class RCrmHelpers
$orders[$orderId]['items'][$itemId]['deleted'] = true;
}
if (!$orders[$orderId]['items'][$itemId]['created'] && isset($fields['item']) && $fields['item'][$change['field']]) {
if (!$orders[$orderId]['items'][$itemId]['created'] && $fields['item'][$change['field']]) {
$orders[$orderId]['items'][$itemId][$fields['item'][$change['field']]] = $change['newValue'];
}
} else {
if (isset($fields['delivery'][$change['field']]) && $fields['delivery'][$change['field']] == 'service') {
$orders[$orderId]['delivery']['service']['code'] = self::historyNewValue($change['newValue']);
$orders[$orderId]['delivery']['service']['code'] = $this->historyNewValue($change['newValue']);
} elseif (isset($fields['delivery'][$change['field']])) {
$orders[$orderId]['delivery'][$fields['delivery'][$change['field']]] = self::historyNewValue($change['newValue']);
$orders[$orderId]['delivery'][$fields['delivery'][$change['field']]] = $this->historyNewValue($change['newValue']);
} elseif (isset($fields['orderAddress'][$change['field']])) {
$orders[$orderId]['delivery']['address'][$fields['orderAddress'][$change['field']]] = $change['newValue'];
} elseif (isset($fields['integrationDelivery'][$change['field']])) {
$orders[$orderId]['delivery']['service'][$fields['integrationDelivery'][$change['field']]] = self::historyNewValue($change['newValue']);
$orders[$orderId]['delivery']['service'][$fields['integrationDelivery'][$change['field']]] = $this->historyNewValue($change['newValue']);
} elseif (isset($fields['customerContragent'][$change['field']])) {
$orders[$orderId][$fields['customerContragent'][$change['field']]] = self::historyNewValue($change['newValue']);
$orders[$orderId][$fields['customerContragent'][$change['field']]] = $this->historyNewValue($change['newValue']);
} elseif (strripos($change['field'], 'custom_') !== false) {
$orders[$orderId]['customFields'][str_replace('custom_', '', $change['field'])] = self::historyNewValue($change['newValue']);
$orders[$orderId]['customFields'][str_replace('custom_', '', $change['field'])] = $this->historyNewValue($change['newValue']);
} elseif (isset($fields['order'][$change['field']])) {
$orders[$orderId][$fields['order'][$change['field']]] = self::historyNewValue($change['newValue']);
$orders[$orderId][$fields['order'][$change['field']]] = $this->historyNewValue($change['newValue']);
}
if (isset($change['created'])) {
@ -143,7 +143,7 @@ class RCrmHelpers
* @param $value mixed
* @return string
*/
public static function historyNewValue($value)
public function historyNewValue($value)
{
if (isset($value['code'])) {
return $value['code'];
@ -156,14 +156,14 @@ class RCrmHelpers
* @param $inputArray mixed
* @return array
*/
public static function removeEmpty($inputArray)
public function removeEmpty($inputArray)
{
$outputArray = array();
if (!empty($inputArray)) {
foreach ($inputArray as $key => $element) {
if (!empty($element) || $element === 0 || $element === '0') {
if (is_array($element)) {
$element = self::removeEmpty($element);
$element = $this->removeEmpty($element);
}
$outputArray[$key] = $element;
}

View file

@ -5,21 +5,20 @@ class RCrmHistory
/** @var RCrmApiClient $api */
private $api = null;
/**
* RCrmHistory constructor.
*/
public function __construct()
{
$config = mainConfiguration::getInstance();
$this->api = new RCrmProxy(
$config->get('retailcrm', 'crmUrl'),
$config->get('retailcrm', 'apiKey')
$config->get('retailcrm', 'apiKey'),
__DIR__ . '/../../../retailcrm.error.log'
);
}
public function runOrders()
{
$retailcrm = new RetailCRM;
$regedit = regedit::getInstance();
$config = mainConfiguration::getInstance();
@ -36,7 +35,7 @@ class RCrmHistory
$response = $this->api->ordersHistory(array('sinceId' => $historyLastId), $historyPage);
$historyPage++;
if ($response->isSuccessful() && count($response['history'])) {
if (!is_null($response) && count($response['history'])) {
$historyArray = array_merge($historyArray, $response['history']);
} else {
break;
@ -46,7 +45,7 @@ class RCrmHistory
if (count($historyArray)) {
$lastChange = end($historyArray);
$crmOrders = RCrmHelpers::getAssemblyOrder($historyArray);
$crmOrders = $retailcrm->getAssemblyOrder($historyArray);
$objectTypes = umiObjectTypesCollection::getInstance();
$objects = umiObjectsCollection::getInstance();
@ -66,32 +65,12 @@ class RCrmHistory
$order = order::create();
/* Order create date */
$order->getObject()->setValue('order_date', umiDate::getTimeStamp($crmOrder['createdAt']));
$order->getObject()->getPropByName('order_date')->setValue(umiDate::getTimeStamp($crmOrder['createdAt']));
if (!empty($crmOrder['number'])) {
$order->setName($crmOrder['number']);
} else {
$order->generateNumber();
$order->setName($order->getName() . ' ' . $crmOrder['id'] . "-retailcrm");
}
$this->api->ordersFixExternalIds(array(
array(
'id' => $crmOrder['id'],
'externalId' => $order->getId()
)
));
}
if (!$order) {
continue;
}
if (isset($crmOrder['customer'])) {
$crmCustomer = $crmOrder['customer'];
if (isset($crmCustomer['externalId']) && $crmCustomer['externalId'] > 0) {
// TODO: проверить существует ли такой пользователь в системе, если нет, то создать, т.к. принимая customer externalId мы считаем, что такой пользователь уже есть
$order->getObject()->setValue('customer_id', $crmCustomer['externalId']);
$order->getObject()->getPropByName('customer_id')->setValue($crmCustomer['externalId']);
} else {
$customer = $objects->getObjectByName($crmCustomer['id'] . '-retailcrm');
@ -111,31 +90,23 @@ class RCrmHistory
$expirations->add($customerId, customer::$defaultExpiration);
if (!empty($crmCustomer['firstName'])) {
$customer->setValue('fname', $crmCustomer['firstName']);
$customer->getPropByName('fname')->setValue($crmCustomer['firstName']);
}
if (!empty($crmCustomer['lastName'])) {
$customer->setValue('lname', $crmCustomer['lastName']);
$customer->getPropByName('lname')->setValue($crmCustomer['lastName']);
}
if (!empty($crmCustomer['patronymic'])) {
$customer->setValue('father_name', $crmCustomer['patronymic']);
$customer->getPropByName('father_name')->setValue($crmCustomer['patronymic']);
}
if (!empty($crmCustomer['email'])) {
if ($customer->getTypeGUID() == 'emarket-customer') {
$customer->setValue('email', $crmCustomer['email']);
} else {
if ($customer->getTypeGUID() == 'users-user') {
$customer->setValue('e-mail', $crmCustomer['email']);
} else {
$customer->setValue('email', $crmCustomer['email']);
}
}
$customer->getPropByName('email')->setValue($crmCustomer['email']);
}
if (isset($crmCustomer['phones']) && count($crmCustomer['phones']) > 0) {
$customer->setValue('phone', $crmCustomer['phones'][0]['number']);
$customer->getPropByName('phone')->setValue($crmCustomer['phones'][0]['number']);
}
if (isset($crmCustomer['address'])) {
@ -162,61 +133,56 @@ class RCrmHistory
$countryCode = $country->getValue('country_iso_code');
if ($crmCustomerAddress['countryIso'] == $countryCode) {
$deliveryObject->setValue('country', $country->getId());
$deliveryObject->getPropByName('country')->setValue($country->getId());
break;
}
}
}
if (!empty($crmCustomerAddress['index'])) {
$deliveryObject->setValue('index', $crmCustomerAddress['index']);
$deliveryObject->getPropByName('index')->setValue($crmCustomerAddress['index']);
}
if (!empty($crmCustomerAddress['region'])) {
$deliveryObject->setValue('region', $crmCustomerAddress['region']);
$deliveryObject->getPropByName('region')->setValue($crmCustomerAddress['region']);
}
if (!empty($crmCustomerAddress['city'])) {
$deliveryObject->setValue('city', $crmCustomerAddress['city']);
$deliveryObject->getPropByName('city')->setValue($crmCustomerAddress['city']);
}
if (!empty($crmCustomerAddress['street'])) {
$deliveryObject->setValue('street', $crmCustomerAddress['street']);
$deliveryObject->getPropByName('street')->setValue($crmCustomerAddress['street']);
}
if (!empty($crmCustomerAddress['building'])) {
$deliveryObject->setValue('house', $crmCustomerAddress['building']);
$deliveryObject->getPropByName('house')->setValue($crmCustomerAddress['building']);
}
if (!empty($crmCustomerAddress['flat'])) {
$deliveryObject->setValue('flat', $crmCustomerAddress['flat']);
$deliveryObject->getPropByName('flat')->setValue($crmCustomerAddress['flat']);
}
$deliveryAddresses = array(
0 => $deliveryObject->getId()
);
$customer->setValue('delivery_addresses', $deliveryAddresses);
$customer->getPropByName('delivery_addresses')->setValue($deliveryAddresses);
}
}
$order->getObject()->setValue('customer_id', $customer->getId());
$order->getObject()->getPropByName('customer_id')->setValue($customer->getId());
}
}
if (isset($crmOrder['items']) && count($crmOrder['items']) > 0) {
$orderItems = $order->getItems();
foreach ($orderItems as $orderItem) {
$order->removeItem($orderItem);
}
$crmOrderForItems = $this->api->ordersGet($crmOrder['externalId'])->offsetGet('order');
$crmItems = $crmOrderForItems['items'];
$crmItems = $crmOrder['items'];
foreach ($crmItems as $crmItem) {
if (isset($crmItem['deleted']) && $crmItem['deleted'] == true) {
continue;
}
if (!isset($crmItem['offer']['externalId'])) {
continue;
}
@ -229,7 +195,6 @@ class RCrmHistory
$itemOptions = $data[1];
$itemOptions = explode('-', $itemOptions);
foreach ($itemOptions as $itemOption) {
$itemOption = explode('_', $itemOption);
$itemOptionGroupId = $itemOption[0];
@ -244,121 +209,247 @@ class RCrmHistory
/** @var optionedOrderItem $orderItem */
$orderItem->setAmount($crmItem['quantity']);
$order->appendItem($orderItem);
}
}
$customer = $objects->getObject($order->getCustomerId());
if (isset($crmOrder['phone'])) {
$customer->setValue('phone', $crmOrder['phone']);
}
if (isset($crmOrder['lastName'])) {
$customer->setValue('lname', $crmOrder['lastName']);
}
if (isset($crmOrder['firstName'])) {
$customer->setValue('fname', $crmOrder['firstName']);
}
if (isset($crmOrder['patronymic'])) {
$customer->setValue('father_name', $crmOrder['patronymic']);
}
if (!empty($crmCustomer['email'])) {
if ($customer->getTypeGUID() == 'emarket-customer') {
$customer->setValue('email', $crmCustomer['email']);
} else if ($customer->getTypeGUID() == 'users-user') {
$customer->setValue('e-mail', $crmCustomer['email']);
} else {
$customer->setValue('email', $crmCustomer['email']);
if (isset($crmOrder['paymentType'])) {
$relationOrderPaymentTypesMap = $retailcrm->getRelationMap($config->get('retailcrm', 'orderPaymentTypeMap'));
$umiOrderPaymentType = $retailcrm->getRelationByMap($relationOrderPaymentTypesMap, $crmOrder['paymentType'], true);
$order->getObject()->getPropByName('payment_id')->setValue($umiOrderPaymentType);
}
}
if (isset($crmOrder['paymentType'])) {
$relationOrderPaymentTypesMap = RCrmHelpers::getRelationMap($config->get('retailcrm', 'orderPaymentTypeMap'));
$umiOrderPaymentType = RCrmHelpers::getRelationByMap($relationOrderPaymentTypesMap, $crmOrder['paymentType'], true);
$order->getObject()->setValue('payment_id', $umiOrderPaymentType);
}
if (isset($crmOrder['paymentStatus'])) {
$relationOrderPaymentStatusesMap = $retailcrm->getRelationMap($config->get('retailcrm', 'orderPaymentStatusMap'));
$umiOrderPaymentStatus = $retailcrm->getRelationByMap($relationOrderPaymentStatusesMap, $crmOrder['paymentStatus'], true);
$order->getObject()->getPropByName('payment_status_id')->setValue($umiOrderPaymentStatus);
}
if (isset($crmOrder['paymentStatus'])) {
$relationOrderPaymentStatusesMap = RCrmHelpers::getRelationMap($config->get('retailcrm', 'orderPaymentStatusMap'));
$umiOrderPaymentStatus = RCrmHelpers::getRelationByMap($relationOrderPaymentStatusesMap, $crmOrder['paymentStatus'], true);
$order->getObject()->setValue('payment_status_id', $umiOrderPaymentStatus);
}
if (isset($crmOrder['delivery']['code'])) {
$relationOrderDeliveryTypesMap = $retailcrm->getRelationMap($config->get('retailcrm', 'orderDeliveryTypeMap'));
$umiOrderDeliveryType = $retailcrm->getRelationByMap($relationOrderDeliveryTypesMap, $crmOrder['delivery']['code'], true);
$order->getObject()->getPropByName('delivery_id')->setValue($umiOrderDeliveryType);
}
if (isset($crmOrder['delivery']['cost'])) {
$order->getObject()->setValue('delivery_price', $crmOrder['delivery']['cost']);
}
if (isset($crmOrder['delivery']['address']) && count($crmOrder['delivery']['address'])) {
$crmDeliveryAddress = $crmOrder['delivery']['address'];
if (isset($crmOrder['delivery']['code'])) {
$relationOrderDeliveryTypesMap = RCrmHelpers::getRelationMap($config->get('retailcrm', 'orderDeliveryTypeMap'));
$umiOrderDeliveryType = RCrmHelpers::getRelationByMap($relationOrderDeliveryTypesMap, $crmOrder['delivery']['code'], true);
$order->getObject()->setValue('delivery_id', $umiOrderDeliveryType);
}
if (isset($crmOrder['delivery']['address']) && count($crmOrder['delivery']['address'])) {
$crmDeliveryAddress = $crmOrder['delivery']['address'];
$deliveryTypeId = $objectTypes->getTypeIdByGUID('emarket-deliveryaddress');
$deliveryObject = $objects->getObjectByName('Address for order ' . $order->getId());
if (!$deliveryObject) {
$deliveryTypeId = $objectTypes->getTypeIdByGUID('emarket-deliveryaddress');
$deliveryObjectId = $objects->addObject('Address for order ' . $order->getId(), $deliveryTypeId);
$deliveryObject = $objects->getObject($deliveryObjectId);
if (!empty($crmDeliveryAddress['countryIso'])) {
$selector = new selector('objects');
try {
$selector->types('object-type')->id($config->get('retailcrm', 'countryGuideId'));
$countries = $selector->result();
foreach ($countries as $country) {
/** @var umiObject $country */
$countryCode = $country->getValue('country_iso_code');
if ($crmDeliveryAddress['countryIso'] == $countryCode) {
$deliveryObject->getPropByName('country')->setValue($country->getId());
break;
}
}
} catch (selectorException $e) {}
}
if (!empty($crmDeliveryAddress['index'])) {
$deliveryObject->getPropByName('index')->setValue($crmDeliveryAddress['index']);
}
if (!empty($crmDeliveryAddress['region'])) {
$deliveryObject->getPropByName('region')->setValue($crmDeliveryAddress['region']);
}
if (!empty($crmDeliveryAddress['city'])) {
$deliveryObject->getPropByName('city')->setValue($crmDeliveryAddress['city']);
}
if (!empty($crmDeliveryAddress['street'])) {
$deliveryObject->getPropByName('street')->setValue($crmDeliveryAddress['street']);
}
if (!empty($crmDeliveryAddress['building'])) {
$deliveryObject->getPropByName('house')->setValue($crmDeliveryAddress['building']);
}
if (!empty($crmDeliveryAddress['flat'])) {
$deliveryObject->getPropByName('flat')->setValue($crmDeliveryAddress['flat']);
}
$order->getObject()->getPropByName('delivery_address')->setValue($deliveryObject->getId());
}
if (!empty($crmDeliveryAddress['countryIso'])) {
$selector = new selector('objects');
$selector->types('object-type')->id($config->get('retailcrm', 'countryGuideId'));
if (!empty($crmOrder['number'])) {
$order->setName($crmOrder['number']);
} else {
$order->generateNumber();
$order->setName($order->getName() . ' ' . $crmOrder['id'] . "-retailcrm");
}
$countries = $selector->result();
$this->api->ordersFixExternalIds(array(
array(
'id' => $crmOrder['id'],
'externalId' => $order->getId()
)
));
} else {
if (!$order) {
continue;
}
foreach ($countries as $country) {
/** @var umiObject $country */
if (isset($crmOrder['items']) && count($crmOrder['items']) > 0) {
$orderItems = $order->getItems();
foreach ($orderItems as $orderItem) {
$order->removeItem($orderItem);
}
$countryCode = $country->getValue('country_iso_code');
$crmOrderForItems = $this->api->ordersGet($crmOrder['externalId'])->getOrder();
$crmItems = $crmOrderForItems['items'];
if ($crmDeliveryAddress['countryIso'] == $countryCode) {
$deliveryObject->setValue('country', $country->getId());
break;
foreach ($crmItems as $crmItem) {
if (isset($crmItem['deleted']) && $crmItem['deleted'] == true) {
continue;
}
if (!isset($crmItem['offer']['externalId'])) {
continue;
}
if (mb_strpos($crmItem['offer']['externalId'], '#')) {
$data = explode('#', $crmItem['offer']['externalId']);
$itemId = $data[0];
$orderItem = orderItem::create($itemId);
$itemOptions = $data[1];
$itemOptions = explode('-', $itemOptions);
foreach ($itemOptions as $itemOption) {
$itemOption = explode('_', $itemOption);
$itemOptionGroupId = $itemOption[0];
$itemOptionValue = $itemOption[1];
$itemOptionObject = new umiField($itemOptionGroupId);
$orderItem->appendOption($itemOptionObject->getName(), $itemOptionValue);
}
} else {
$orderItem = orderItem::create($crmItem['offer']['externalId']);
}
/** @var optionedOrderItem $orderItem */
$orderItem->setAmount($crmItem['quantity']);
$order->appendItem($orderItem);
}
}
if (!empty($crmDeliveryAddress['index'])) {
$deliveryObject->setValue('index', $crmDeliveryAddress['index']);
$customer = $objects->getObject($order->getCustomerId());
if (isset($crmOrder['phone'])) {
$customer->getPropByName('phone')->setValue($crmOrder['phone']);
}
if (!empty($crmDeliveryAddress['region'])) {
$deliveryObject->setValue('region', $crmDeliveryAddress['region']);
if (isset($crmOrder['lastName'])) {
$customer->getPropByName('lname')->setValue($crmOrder['lastName']);
}
if (!empty($crmDeliveryAddress['city'])) {
$deliveryObject->setValue('city', $crmDeliveryAddress['city']);
if (isset($crmOrder['firstName'])) {
$customer->getPropByName('fname')->setValue($crmOrder['firstName']);
}
if (!empty($crmDeliveryAddress['street'])) {
$deliveryObject->setValue('street', $crmDeliveryAddress['street']);
if (isset($crmOrder['patronymic'])) {
$customer->getPropByName('father_name')->setValue($crmOrder['patronymic']);
}
if (!empty($crmDeliveryAddress['building'])) {
$deliveryObject->setValue('house', $crmDeliveryAddress['building']);
if (isset($crmOrder['e-mail'])) {
$customer->getPropByName('e-mail')->setValue($crmOrder['e-mail']);
}
if (!empty($crmDeliveryAddress['flat'])) {
$deliveryObject->setValue('flat', $crmDeliveryAddress['flat']);
if (isset($crmOrder['paymentType'])) {
$relationOrderPaymentTypesMap = $retailcrm->getRelationMap($config->get('retailcrm', 'orderPaymentTypeMap'));
$umiOrderPaymentType = $retailcrm->getRelationByMap($relationOrderPaymentTypesMap, $crmOrder['paymentType'], true);
$order->getObject()->getPropByName('payment_id')->setValue($umiOrderPaymentType);
}
$order->getObject()->setValue('delivery_address', $deliveryObject->getId());
if (isset($crmOrder['paymentStatus'])) {
$relationOrderPaymentStatusesMap = $retailcrm->getRelationMap($config->get('retailcrm', 'orderPaymentStatusMap'));
$umiOrderPaymentStatus = $retailcrm->getRelationByMap($relationOrderPaymentStatusesMap, $crmOrder['paymentStatus'], true);
$order->getObject()->getPropByName('payment_status_id')->setValue($umiOrderPaymentStatus);
}
if (isset($crmOrder['delivery']['code'])) {
$relationOrderDeliveryTypesMap = $retailcrm->getRelationMap($config->get('retailcrm', 'orderDeliveryTypeMap'));
$umiOrderDeliveryType = $retailcrm->getRelationByMap($relationOrderDeliveryTypesMap, $crmOrder['delivery']['code'], true);
$order->getObject()->getPropByName('delivery_id')->setValue($umiOrderDeliveryType);
}
if (isset($crmOrder['delivery']['address']) && count($crmOrder['delivery']['address'])) {
$crmDeliveryAddress = $crmOrder['delivery']['address'];
$deliveryTypeId = $objectTypes->getTypeIdByGUID('emarket-deliveryaddress');
$deliveryObject = $objects->getObjectByName('Address for order ' . $order->getId());
if (!$deliveryObject) {
$deliveryObjectId = $objects->addObject('Address for order ' . $order->getId(), $deliveryTypeId);
$deliveryObject = $objects->getObject($deliveryObjectId);
}
if (!empty($crmDeliveryAddress['countryIso'])) {
$selector = new selector('objects');
$selector->types('object-type')->id($config->get('retailcrm', 'countryGuideId'));
$countries = $selector->result();
foreach ($countries as $country) {
/** @var umiObject $country */
$countryCode = $country->getValue('country_iso_code');
if ($crmDeliveryAddress['countryIso'] == $countryCode) {
$deliveryObject->getPropByName('country')->setValue($country->getId());
break;
}
}
}
if (!empty($crmDeliveryAddress['index'])) {
$deliveryObject->getPropByName('index')->setValue($crmDeliveryAddress['index']);
}
if (!empty($crmDeliveryAddress['region'])) {
$deliveryObject->getPropByName('region')->setValue($crmDeliveryAddress['region']);
}
if (!empty($crmDeliveryAddress['city'])) {
$deliveryObject->getPropByName('city')->setValue($crmDeliveryAddress['city']);
}
if (!empty($crmDeliveryAddress['street'])) {
$deliveryObject->getPropByName('street')->setValue($crmDeliveryAddress['street']);
}
if (!empty($crmDeliveryAddress['building'])) {
$deliveryObject->getPropByName('house')->setValue($crmDeliveryAddress['building']);
}
if (!empty($crmDeliveryAddress['flat'])) {
$deliveryObject->getPropByName('flat')->setValue($crmDeliveryAddress['flat']);
}
$order->getObject()->getPropByName('delivery_address')->setValue($deliveryObject->getId());
}
}
if (!$order) {
continue;
}
$regedit->setVal('//modules/RetailCRM/IgnoreObjectUpdateEvent/' . $order->getObject()->getId(), time());
if (isset($crmOrder['status'])) {
$relationMap = RCrmHelpers::getRelationMap($config->get('retailcrm', 'orderStatusMap'));
$umiOrderStatusCode = RCrmHelpers::getRelationByMap($relationMap, $crmOrder['status'], true);
$relationMap = $retailcrm->getRelationMap($config->get('retailcrm', 'orderStatusMap'));
$umiOrderStatusCode = $retailcrm->getRelationByMap($relationMap, $crmOrder['status'], true);
if ($umiOrderStatusCode) {
// меняем дату редактирования заказа, для того, чтобы его не перехватил хенлдер и не выплюнул обратно в црм
$order->getObject()->setUpdateTime(time());
@ -376,4 +467,4 @@ class RCrmHistory
{
}
}
}

View file

View file

@ -18,14 +18,8 @@ class RCrmIcml
$domainsCollection = domainsCollection::getInstance();
$domainsCollectionList = $domainsCollection->getList();
$domainCollection = $domainsCollectionList[1];
if (mainConfiguration::getInstance()->get('system', 'server-protocol')) {
$serverProtocol = mainConfiguration::getInstance()->get('system', 'server-protocol');
} else {
$serverProtocol = 'http';
}
$this->shopUrl = $serverProtocol . '://' . $domainCollection->getHost();
$serverProtocol = mainConfiguration::getInstance()->get('system', 'server-protocol') . '://';
$this->shopUrl = $serverProtocol . $domainCollection->getHost();
}
public function generateICML()
@ -98,15 +92,12 @@ class RCrmIcml
{
$url = '/' . $obj->getAltName();
$ids = array($obj->getRel());
$parent = new umiHierarchyElement($obj->getRel());
while (true) {
$url = '/' . $parent->getAltName() . $url;
if ($parent->getRel() != 0 && !in_array($parent->getRel(), $ids)) {
if ($parent->getRel() != 0) {
$parent = new umiHierarchyElement($parent->getRel());
array_push($ids, $parent->getRel());
} else {
break;
}
@ -287,7 +278,9 @@ class RCrmIcml
if (is_array($photos) && count($photos)) {
$photo = reset($photos);
$photoPath = $this->shopUrl . $photo->getFilePath(true);
$e->appendChild($this->dd->createElement('picture'))->appendChild($this->dd->createTextNode($photoPath));
$e->appendChild($this->dd->createElement('picture'))
->appendChild($this->dd->createTextNode($photoPath));
}
}
@ -313,4 +306,4 @@ class RCrmIcml
}
}
}
}
}

View file

100
classes/modules/RetailCRM/classes/retailcrm/RCrmProxy.php Executable file → Normal file
View file

@ -7,104 +7,36 @@
class RCrmProxy
{
private $api;
private $log;
/**
* Методы API которые не надо логировать
* @var array
*/
private $ignoreMethods = array(
'customersList',
'customersGet',
'ordersList',
'ordersGet',
);
/**
* Методы API трассировку которых надо логировать
* @var array
*/
private $traceMethods = array(
'customersCreate',
'customersEdit',
'ordersCreate',
'ordersEdit',
);
/**
* RCrmProxy constructor.
* @param string $apiUrl
* @param string $apiKey
*/
public function __construct($apiUrl, $apiKey)
public function __construct($url, $key, $log)
{
$this->api = new RCrmApiClient($apiUrl, $apiKey);
$this->api = new RCrmApiClient($url, $key);
$this->log = $log;
}
/**
* @param $method
* @param $arguments
* @return bool|RCrmApiResponse
*/
public function __call($method, $arguments)
{
$accessLog = date('H:m:i') . ' [' . $method . '] -> ' . json_encode($arguments) . "\n";
error_log($accessLog, 3, $this->log);
try {
$response = call_user_func_array(array($this->api, $method), $arguments);
if (!in_array($method, $this->ignoreMethods)) {
$this->writeLog($method, $response);
if (!$response->isSuccessful()) {
error_log("[$method] " . $response->getErrorMsg() . "\n", 3, $this->log);
if (isset($response['errors'])) {
$error = implode("\n", $response['errors']);
error_log($error . "\n", 3, $this->log);
}
$response = false;
}
return $response;
} catch (RCrmCurlException $e) {
$this->writeLog($method, $e->getMessage());
error_log("[$method] " . $e->getMessage() . "\n", 3, $this->log);
return false;
} catch (RCrmJsonException $e) {
$this->writeLog($method, $e->getMessage());
error_log("[$method] " . $e->getMessage() . "\n", 3, $this->log);
return false;
}
}
/**
* @param string $method
* @param mixed $data
* @return bool
*/
private function writeLog($method, $data)
{
$path = realpath(__DIR__ . '/../../logs/');
$file = $path . '/' . $method . '.log';
if (!file_exists($path)) {
mkdir($path);
}
if (file_exists($file)) {
if (filesize($file) > 1024 * 1024 * 10) {
unlink($file);
}
}
$logArray = array(
'time' => date('Y-m-d H:i:s'),
'data' => $data
);
if (in_array($method, $this->traceMethods)) {
$traces = debug_backtrace();
foreach ($traces as $i => $trace) {
if ($i == 0) {
unset($traces[$i]);
continue;
}
unset($traces[$i]['args']);
unset($traces[$i]['object']);
}
$logArray['trace'] = array_reverse($traces);
}
return file_put_contents($file, print_r($logArray, true) . "\n\n", FILE_APPEND);
}
}

View file

@ -0,0 +1,811 @@
<?php
/**
* retailCRM API client class
*/
class RetailcrmApiClient
{
const VERSION = 'v3';
protected $client;
/**
* Site code
*/
protected $siteCode;
/**
* Client creating
*
* @param string $url
* @param string $apiKey
* @param string $site
* @return mixed
*/
public function __construct($url, $apiKey, $site = null)
{
if ('/' != substr($url, strlen($url) - 1, 1)) {
$url .= '/';
}
$url = $url . 'api/' . self::VERSION;
$this->client = new RetailcrmHttpClient($url, array('apiKey' => $apiKey));
$this->siteCode = $site;
}
/**
* Create a order
*
* @param array $order
* @param string $site (default: null)
* @return RetailcrmApiResponse
*/
public function ordersCreate(array $order, $site = null)
{
if (!sizeof($order)) {
throw new InvalidArgumentException('Parameter `order` must contains a data');
}
return $this->client->makeRequest("/orders/create", RetailcrmHttpClient::METHOD_POST, $this->fillSite($site, array(
'order' => json_encode($order)
)));
}
/**
* Edit a order
*
* @param array $order
* @param string $by
* @param string $site (default: null)
* @return RetailcrmApiResponse
*/
public function ordersEdit(array $order, $by = 'externalId', $site = null)
{
if (!sizeof($order)) {
throw new InvalidArgumentException('Parameter `order` must contains a data');
}
$this->checkIdParameter($by);
if (!isset($order[$by])) {
throw new InvalidArgumentException(sprintf('Order array must contain the "%s" parameter.', $by));
}
return $this->client->makeRequest(
"/orders/" . $order[$by] . "/edit",
RetailcrmHttpClient::METHOD_POST,
$this->fillSite($site, array(
'order' => json_encode($order),
'by' => $by,
))
);
}
/**
* Upload array of the orders
*
* @param array $orders
* @param string $site (default: null)
* @return RetailcrmApiResponse
*/
public function ordersUpload(array $orders, $site = null)
{
if (!sizeof($orders)) {
throw new InvalidArgumentException('Parameter `orders` must contains array of the orders');
}
return $this->client->makeRequest("/orders/upload", RetailcrmHttpClient::METHOD_POST, $this->fillSite($site, array(
'orders' => json_encode($orders),
)));
}
/**
* Get order by id or externalId
*
* @param string $id
* @param string $by (default: 'externalId')
* @param string $site (default: null)
* @return RetailcrmApiResponse
*/
public function ordersGet($id, $by = 'externalId', $site = null)
{
$this->checkIdParameter($by);
return $this->client->makeRequest("/orders/$id", RetailcrmHttpClient::METHOD_GET, $this->fillSite($site, array(
'by' => $by
)));
}
/**
* Returns a orders history
*
* @param DateTime $startDate (default: null)
* @param DateTime $endDate (default: null)
* @param int $limit (default: 100)
* @param int $offset (default: 0)
* @param bool $skipMyChanges (default: true)
* @return RetailcrmApiResponse
*/
public function ordersHistory(
DateTime $startDate = null,
DateTime $endDate = null,
$limit = 100,
$offset = 0,
$skipMyChanges = true
) {
$parameters = array();
if ($startDate) {
$parameters['startDate'] = $startDate->format('Y-m-d H:i:s');
}
if ($endDate) {
$parameters['endDate'] = $endDate->format('Y-m-d H:i:s');
}
if ($limit) {
$parameters['limit'] = (int) $limit;
}
if ($offset) {
$parameters['offset'] = (int) $offset;
}
if ($skipMyChanges) {
$parameters['skipMyChanges'] = (bool) $skipMyChanges;
}
return $this->client->makeRequest('/orders/history', RetailcrmHttpClient::METHOD_GET, $parameters);
}
/**
* Returns filtered orders list
*
* @param array $filter (default: array())
* @param int $page (default: null)
* @param int $limit (default: null)
* @return RetailcrmApiResponse
*/
public function ordersList(array $filter = array(), $page = null, $limit = null)
{
$parameters = array();
if (sizeof($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest('/orders', RetailcrmHttpClient::METHOD_GET, $parameters);
}
/**
* Returns statuses of the orders
*
* @param array $ids (default: array())
* @param array $externalIds (default: array())
* @return RetailcrmApiResponse
*/
public function ordersStatuses(array $ids = array(), array $externalIds = array())
{
$parameters = array();
if (sizeof($ids)) {
$parameters['ids'] = $ids;
}
if (sizeof($externalIds)) {
$parameters['externalIds'] = $externalIds;
}
return $this->client->makeRequest('/orders/statuses', RetailcrmHttpClient::METHOD_GET, $parameters);
}
/**
* Save order IDs' (id and externalId) association in the CRM
*
* @param array $ids
* @return RetailcrmApiResponse
*/
public function ordersFixExternalIds(array $ids)
{
if (!sizeof($ids)) {
throw new InvalidArgumentException('Method parameter must contains at least one IDs pair');
}
return $this->client->makeRequest("/orders/fix-external-ids", RetailcrmHttpClient::METHOD_POST, array(
'orders' => json_encode($ids),
));
}
/**
* Get orders assembly history
*
* @param array $filter (default: array())
* @param int $page (default: null)
* @param int $limit (default: null)
* @return RetailcrmApiResponse
*/
public function ordersPacksHistory(array $filter = array(), $page = null, $limit = null)
{
$parameters = array();
if (sizeof($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest('/orders/packs/history', RetailcrmHttpClient::METHOD_GET, $parameters);
}
/**
* Create a customer
*
* @param array $customer
* @param string $site (default: null)
* @return RetailcrmApiResponse
*/
public function customersCreate(array $customer, $site = null)
{
if (!sizeof($customer)) {
throw new InvalidArgumentException('Parameter `customer` must contains a data');
}
return $this->client->makeRequest("/customers/create", RetailcrmHttpClient::METHOD_POST, $this->fillSite($site, array(
'customer' => json_encode($customer)
)));
}
/**
* Edit a customer
*
* @param array $customer
* @param string $by (default: 'externalId')
* @param string $site (default: null)
* @return RetailcrmApiResponse
*/
public function customersEdit(array $customer, $by = 'externalId', $site = null)
{
if (!sizeof($customer)) {
throw new InvalidArgumentException('Parameter `customer` must contains a data');
}
$this->checkIdParameter($by);
if (!isset($customer[$by])) {
throw new InvalidArgumentException(sprintf('Customer array must contain the "%s" parameter.', $by));
}
return $this->client->makeRequest(
"/customers/" . $customer[$by] . "/edit",
RetailcrmHttpClient::METHOD_POST,
$this->fillSite(
$site,
array(
'customer' => json_encode($customer),
'by' => $by
)
)
);
}
/**
* Upload array of the customers
*
* @param array $customers
* @param string $site (default: null)
* @return RetailcrmApiResponse
*/
public function customersUpload(array $customers, $site = null)
{
if (!sizeof($customers)) {
throw new InvalidArgumentException('Parameter `customers` must contains array of the customers');
}
return $this->client->makeRequest("/customers/upload", RetailcrmHttpClient::METHOD_POST, $this->fillSite($site, array(
'customers' => json_encode($customers),
)));
}
/**
* Get customer by id or externalId
*
* @param string $id
* @param string $by (default: 'externalId')
* @param string $site (default: null)
* @return RetailcrmApiResponse
*/
public function customersGet($id, $by = 'externalId', $site = null)
{
$this->checkIdParameter($by);
return $this->client->makeRequest("/customers/$id", RetailcrmHttpClient::METHOD_GET, $this->fillSite($site, array(
'by' => $by
)));
}
/**
* Returns filtered customers list
*
* @param array $filter (default: array())
* @param int $page (default: null)
* @param int $limit (default: null)
* @return RetailcrmApiResponse
*/
public function customersList(array $filter = array(), $page = null, $limit = null)
{
$parameters = array();
if (sizeof($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest('/customers', RetailcrmHttpClient::METHOD_GET, $parameters);
}
/**
* Save customer IDs' (id and externalId) association in the CRM
*
* @param array $ids
* @return RetailcrmApiResponse
*/
public function customersFixExternalIds(array $ids)
{
if (!sizeof($ids)) {
throw new InvalidArgumentException('Method parameter must contains at least one IDs pair');
}
return $this->client->makeRequest("/customers/fix-external-ids", RetailcrmHttpClient::METHOD_POST, array(
'customers' => json_encode($ids),
));
}
/**
* Get purchace prices & stock balance
*
* @param array $filter (default: array())
* @param int $page (default: null)
* @param int $limit (default: null)
* @param string $site (default: null)
* @return RetailcrmApiResponse
*/
public function storeInventories(array $filter = array(), $page = null, $limit = null, $site = null)
{
$parameters = array();
if (sizeof($filter)) {
$parameters['filter'] = $filter;
}
if (null !== $page) {
$parameters['page'] = (int) $page;
}
if (null !== $limit) {
$parameters['limit'] = (int) $limit;
}
return $this->client->makeRequest('/store/inventories', RetailcrmHttpClient::METHOD_GET, $this->fillSite($site, $parameters));
}
/**
* Upload store inventories
*
* @param array $offers
* @param string $site (default: null)
* @return RetailcrmApiResponse
*/
public function storeInventoriesUpload(array $offers, $site = null)
{
if (!sizeof($offers)) {
throw new InvalidArgumentException('Parameter `offers` must contains array of the customers');
}
return $this->client->makeRequest(
"/store/inventories/upload",
RetailcrmHttpClient::METHOD_POST,
$this->fillSite($site, array('offers' => json_encode($offers)))
);
}
/**
* Returns deliveryServices list
*
* @return RetailcrmApiResponse
*/
public function deliveryServicesList()
{
return $this->client->makeRequest('/reference/delivery-services', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns deliveryTypes list
*
* @return RetailcrmApiResponse
*/
public function deliveryTypesList()
{
return $this->client->makeRequest('/reference/delivery-types', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns orderMethods list
*
* @return RetailcrmApiResponse
*/
public function orderMethodsList()
{
return $this->client->makeRequest('/reference/order-methods', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns orderTypes list
*
* @return RetailcrmApiResponse
*/
public function orderTypesList()
{
return $this->client->makeRequest('/reference/order-types', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns paymentStatuses list
*
* @return RetailcrmApiResponse
*/
public function paymentStatusesList()
{
return $this->client->makeRequest('/reference/payment-statuses', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns paymentTypes list
*
* @return RetailcrmApiResponse
*/
public function paymentTypesList()
{
return $this->client->makeRequest('/reference/payment-types', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns productStatuses list
*
* @return RetailcrmApiResponse
*/
public function productStatusesList()
{
return $this->client->makeRequest('/reference/product-statuses', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns statusGroups list
*
* @return RetailcrmApiResponse
*/
public function statusGroupsList()
{
return $this->client->makeRequest('/reference/status-groups', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns statuses list
*
* @return RetailcrmApiResponse
*/
public function statusesList()
{
return $this->client->makeRequest('/reference/statuses', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns sites list
*
* @return RetailcrmApiResponse
*/
public function sitesList()
{
return $this->client->makeRequest('/reference/sites', RetailcrmHttpClient::METHOD_GET);
}
/**
* Returns stores list
*
* @return RetailcrmApiResponse
*/
public function storesList()
{
return $this->client->makeRequest('/reference/stores', RetailcrmHttpClient::METHOD_GET);
}
/**
* Edit deliveryService
*
* @param array $data delivery service data
* @return RetailcrmApiResponse
*/
public function deliveryServicesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/delivery-services/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'deliveryService' => json_encode($data)
)
);
}
/**
* Edit deliveryType
*
* @param array $data delivery type data
* @return RetailcrmApiResponse
*/
public function deliveryTypesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/delivery-types/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'deliveryType' => json_encode($data)
)
);
}
/**
* Edit orderMethod
*
* @param array $data order method data
* @return RetailcrmApiResponse
*/
public function orderMethodsEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/order-methods/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'orderMethod' => json_encode($data)
)
);
}
/**
* Edit orderType
*
* @param array $data order type data
* @return RetailcrmApiResponse
*/
public function orderTypesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/order-types/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'orderType' => json_encode($data)
)
);
}
/**
* Edit paymentStatus
*
* @param array $data payment status data
* @return RetailcrmApiResponse
*/
public function paymentStatusesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/payment-statuses/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'paymentStatus' => json_encode($data)
)
);
}
/**
* Edit paymentType
*
* @param array $data payment type data
* @return RetailcrmApiResponse
*/
public function paymentTypesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/payment-types/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'paymentType' => json_encode($data)
)
);
}
/**
* Edit productStatus
*
* @param array $data product status data
* @return RetailcrmApiResponse
*/
public function productStatusesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/product-statuses/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'productStatus' => json_encode($data)
)
);
}
/**
* Edit order status
*
* @param array $data status data
* @return RetailcrmApiResponse
*/
public function statusesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/statuses/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'status' => json_encode($data)
)
);
}
/**
* Edit site
*
* @param array $data site data
* @return RetailcrmApiResponse
*/
public function sitesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
return $this->client->makeRequest(
'/reference/sites/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'site' => json_encode($data)
)
);
}
/**
* Edit store
*
* @param array $data site data
* @return RetailcrmApiResponse
*/
public function storesEdit(array $data)
{
if (!isset($data['code'])) {
throw new InvalidArgumentException('Data must contain "code" parameter.');
}
if (!isset($data['name'])) {
throw new InvalidArgumentException('Data must contain "name" parameter.');
}
return $this->client->makeRequest(
'/reference/stores/' . $data['code'] . '/edit',
RetailcrmHttpClient::METHOD_POST,
array(
'store' => json_encode($data)
)
);
}
/**
* Update CRM basic statistic
*
* @return RetailcrmApiResponse
*/
public function statisticUpdate()
{
return $this->client->makeRequest('/statistic/update', RetailcrmHttpClient::METHOD_GET);
}
/**
* Return current site
*
* @return string
*/
public function getSite()
{
return $this->siteCode;
}
/**
* Set site
*
* @param string $site
* @return void
*/
public function setSite($site)
{
$this->siteCode = $site;
}
/**
* Check ID parameter
*
* @param string $by
* @return bool
*/
protected function checkIdParameter($by)
{
$allowedForBy = array('externalId', 'id');
if (!in_array($by, $allowedForBy)) {
throw new InvalidArgumentException(sprintf(
'Value "%s" for parameter "by" is not valid. Allowed values are %s.',
$by,
implode(', ', $allowedForBy)
));
}
return true;
}
/**
* Fill params by site value
*
* @param string $site
* @param array $params
* @return array
*/
protected function fillSite($site, array $params)
{
if ($site) {
$params['site'] = $site;
} elseif ($this->siteCode) {
$params['site'] = $this->siteCode;
}
return $params;
}
}

View file

@ -0,0 +1,122 @@
<?php
/**
* Response from retailCRM API
*/
class RetailcrmApiResponse implements ArrayAccess
{
// HTTP response status code
protected $statusCode;
// response assoc array
protected $response;
public function __construct($statusCode, $responseBody = null)
{
$this->statusCode = (int) $statusCode;
if (!empty($responseBody)) {
$response = json_decode($responseBody, true);
if (!$response && JSON_ERROR_NONE !== ($error = json_last_error())) {
throw new InvalidJsonException(
"Invalid JSON in the API response body. Error code #$error",
$error
);
}
$this->response = $response;
}
}
/**
* Return HTTP response status code
*
* @return int
*/
public function getStatusCode()
{
return $this->statusCode;
}
/**
* HTTP request was successful
*
* @return bool
*/
public function isSuccessful()
{
return $this->statusCode < 400;
}
/**
* Allow to access for the property throw class method
*
* @param string $name
* @return mixed
*/
public function __call($name, $arguments)
{
// convert getSomeProperty to someProperty
$propertyName = strtolower(substr($name, 3, 1)) . substr($name, 4);
if (!isset($this->response[$propertyName])) {
throw new InvalidArgumentException("Method \"$name\" not found");
}
return $this->response[$propertyName];
}
/**
* Allow to access for the property throw object property
*
* @param string $name
* @return mixed
*/
public function __get($name)
{
if (!isset($this->response[$name])) {
throw new InvalidArgumentException("Property \"$name\" not found");
}
return $this->response[$name];
}
/**
* @param mixed $offset
* @param mixed $value
*/
public function offsetSet($offset, $value)
{
throw new BadMethodCallException('This activity not allowed');
}
/**
* @param mixed $offset
*/
public function offsetUnset($offset)
{
throw new BadMethodCallException('This call not allowed');
}
/**
* @param mixed $offset
* @return bool
*/
public function offsetExists($offset)
{
return isset($this->response[$offset]);
}
/**
* @param mixed $offset
* @return mixed
*/
public function offsetGet($offset)
{
if (!isset($this->response[$offset])) {
throw new InvalidArgumentException("Property \"$offset\" not found");
}
return $this->response[$offset];
}
}

View file

@ -0,0 +1,41 @@
<?php
abstract class RetailcrmHelpers {
/**
* @param $mapArr array
* @return array
*/
public function getRelationMap($mapArr) {
if(empty($mapArr)) return array();
$map = array();
foreach ($mapArr as $mapItem) {
$mapItem = explode(' <-> ', $mapItem);
$map[$mapItem[0]] = $mapItem[1];
}
return $map;
}
/**
* @param $map array
* @param $item string
* @param $reversed bool
* @return string|null
*/
public function getRelationByMap($map, $item, $reversed = false) {
if(!$reversed) {
if(isset($map[$item]) && !empty($map[$item]))
return $map[$item];
else
return null;
} else {
foreach ($map as $umiStatusOrder => $crmStatusOrder) {
if($crmStatusOrder == $item)
return $umiStatusOrder;
}
return null;
}
}
}

View file

@ -0,0 +1,113 @@
<?php
/**
* HTTP client
*/
class RetailcrmHttpClient
{
const METHOD_GET = 'GET';
const METHOD_POST = 'POST';
protected $url;
protected $defaultParameters;
protected $retry;
public function __construct($url, array $defaultParameters = array())
{
if (false === stripos($url, 'https://')) {
throw new InvalidArgumentException('API schema requires HTTPS protocol');
}
$this->url = $url;
$this->defaultParameters = $defaultParameters;
$this->retry = 0;
}
/**
* Make HTTP request
*
* @param string $path
* @param string $method (default: 'GET')
* @param array $parameters (default: array())
* @param int $timeout
* @param bool $verify
* @param bool $debug
* @return RetailcrmApiResponse
*/
public function makeRequest(
$path,
$method,
array $parameters = array(),
$timeout = 30,
$verify = false,
$debug = false
) {
$allowedMethods = array(self::METHOD_GET, self::METHOD_POST);
if (!in_array($method, $allowedMethods)) {
throw new InvalidArgumentException(sprintf(
'Method "%s" is not valid. Allowed methods are %s',
$method,
implode(', ', $allowedMethods)
));
}
$parameters = array_merge($this->defaultParameters, $parameters);
$url = $this->url . $path;
if (self::METHOD_GET === $method && sizeof($parameters)) {
$url .= '?' . http_build_query($parameters, '', '&');
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_FAILONERROR, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verify);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $verify);
if (!$debug) {
curl_setopt($ch, CURLOPT_TIMEOUT, (int) $timeout);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, (int) $timeout);
} else {
curl_setopt($ch, CURLOPT_TIMEOUT_MS, (int) $timeout + ($this->retry * 2000));
}
if (self::METHOD_POST === $method) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
}
$responseBody = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$errno = curl_errno($ch);
$error = curl_error($ch);
curl_close($ch);
if ($errno && in_array($errno, array(6, 7, 28, 34, 35)) && $this->retry < 3) {
$errno = null;
$error = null;
$this->retry += 1;
$this->makeRequest(
$path,
$method,
$parameters,
$timeout,
$verify,
$debug
);
}
if ($errno) {
throw new CurlException($error, $errno);
}
return new RetailcrmApiResponse($statusCode, $responseBody);
}
public function getRetry()
{
return $this->retry;
}
}

View file

@ -0,0 +1,39 @@
<?php
/**
* Class RequestProxy
* @package RetailCrm\Component
*/
class RetailcrmProxy
{
private $api;
private $log;
public function __construct($url, $key, $log)
{
$this->api = new RetailcrmApiClient($url, $key);
$this->log = $log;
}
public function __call($method, $arguments)
{
$accessLog = date('H:m:i') . ' [' . $method . '] -> ' . json_encode($arguments) . "\n";
error_log($accessLog, 3, $this->log);
try {
$response = call_user_func_array(array($this->api, $method), $arguments);
if (!$response->isSuccessful()) {
error_log("[$method] " . $response->getErrorMsg() . "\n", 3, $this->log);
if (isset($response['errors'])) {
$error = implode("\n", $response['errors']);
error_log($error . "\n", 3, $this->log);
}
$response = false;
}
return $response;
} catch (CurlException $e) {
error_log("[$method] " . $e->getMessage() . "\n", 3, $this->log);
return false;
} catch (InvalidJsonException $e) {
error_log("[$method] " . $e->getMessage() . "\n", 3, $this->log);
return false;
}
}
}

View file

@ -0,0 +1,294 @@
<?php
class RetailCRMIcmlCreator
{
/** @var DOMDocument $dd */
protected $dd;
/** @var DOMElement $eCategories */
protected $eCategories;
/** @var DOMElement $eOffers */
protected $eOffers;
/** @var string $shopName */
protected $shopName = 'shop';
/** @var string $shopUrl */
protected $shopUrl;
public function __construct()
{
$domainsCollection = domainsCollection::getInstance();
$domainsCollectionList = $domainsCollection->getList();
$domainCollection = $domainsCollectionList[1];
$serverProtocol = mainConfiguration::getInstance()->get('system', 'server-protocol') . '://';
$this->shopUrl = $serverProtocol . $domainCollection->getHost();
}
public function generateICML()
{
$string = '<?xml version="1.0" encoding="UTF-8"?>
<yml_catalog date="'.date('Y-m-d H:i:s').'">
<shop>
<name>'.$this->shopName.'</name>
<categories/>
<offers/>
</shop>
</yml_catalog>
';
$xml = new SimpleXMLElement(
$string,
LIBXML_NOENT |LIBXML_NOCDATA | LIBXML_COMPACT | LIBXML_PARSEHUGE
);
$this->dd = new DOMDocument();
$this->dd->preserveWhiteSpace = false;
$this->dd->formatOutput = true;
$this->dd->loadXML($xml->asXML());
$this->eCategories = $this->dd
->getElementsByTagName('categories')->item(0);
$this->eOffers = $this->dd
->getElementsByTagName('offers')->item(0);
$this->addCategories();
$this->addOffers();
$this->dd->saveXML();
$downloadPath = __DIR__ . '/../../../../../';
if (!file_exists($downloadPath)) {
mkdir($downloadPath, 0755);
}
$this->dd->save($downloadPath . 'retailcrm.xml');
}
/**
*
*/
private function addCategories()
{
$categories = new selector('pages');
$categories->types('hierarchy-type')->name('catalog', 'category');
$result = $categories->result();
foreach($result as $category) {
/** @var umiHierarchyElement $category */
/** @var DOMElement $e */
$e = $this->eCategories->appendChild(
$this->dd->createElement(
'category', $category->getName()
)
);
$e->setAttribute('id', $category->getId());
if ($category->getRel() > 0) {
$e->setAttribute('parentId', $category->getRel());
}
}
}
private function getObjectUrl(umiHierarchyElement $obj) {
$url = '';
$url = '/' . $obj->getAltName() . $url;
$parent = new umiHierarchyElement($obj->getRel());
while(true) {
$url = '/' . $parent->getAltName() . $url;
if($parent->getRel() != 0) {
$parent = new umiHierarchyElement($parent->getRel());
} else {
break;
}
}
$url = $this->shopUrl . $url;
return $url;
}
private function getCombinationsFromMultyArray($sourceData) {
$sourceDataKeys = array();
foreach ($sourceData as $key=>$value) {
$sourceDataKeys[] = $key;
}
$data = array();
$data[] = '';
for($i = 0; $i < count($sourceData); $i++) {
$oldData = $data;
$data = array();
foreach($oldData as $value) {
foreach ($sourceData[$sourceDataKeys[$i]] as $value2) {
$data[] = (!empty($value) ? $value.',' : '') . $sourceDataKeys[$i] . '-' . $value2;
}
}
}
$resultData = array();
foreach ($data as $value) {
$items = explode(',', $value);
$columns = array();
foreach ($items as $item) {
$item = explode('-', $item);
$columns[$item[0]] = $item[1];
}
$resultData[] = $columns;
}
return $resultData;
}
private function addOffers()
{
$offers = new selector('pages');
$offers->types('hierarchy-type')->name('catalog', 'object');
$result = $offers->result();
foreach ($result as $offer) {
/** @var umiHierarchyElement $offer */
$objects = umiObjectsCollection::getInstance();
$offerObject = new umiObject($offer->getObjectId());
/** @var umiFieldsGroup $optionsObject */
$optionsObject = $offerObject->getType()->getFieldsGroupByName('catalog_option_props');
$options = array();
$optionValues = array();
$optionGroups = array();
$optionPrices = array();
foreach ($optionsObject->getFields() as $optionField) {
/** @var umiField $optionField */
$optionGroups[$optionField->getId()] = $optionField;
$values = $offerObject->getValue($optionField->getName());
foreach ($values as $value) {
$valueObject = $objects->getObject($value['rel']);
$options[$optionField->getId()][] = $valueObject->getId();
$optionPrices[$valueObject->getId()] = $value['float'];
$optionValues[$valueObject->getId()] = $valueObject;
}
}
if(count($options))
$offerOptions = $this->getCombinationsFromMultyArray($options);
else {
// Если нет опционных товаров(товарных предложений) передаём массив с 1 пустым элементом - базовый товар
$offerOptions = array();
$offerOptions[] = '';
}
foreach ($offerOptions as $offerOption) {
if(!empty($offerOption)) {
$options = array();
foreach ($offerOption as $offerOptionId => $offerOptionValue) {
$options[] = $offerOptionId . '_' . $offerOptionValue;
}
$offerId = $offer->getId() . '#' . implode('-', $options);
} else
$offerId = $offer->getId();
/** @var DOMElement $e */
$e = $this->eOffers->appendChild($this->dd->createElement('offer'));
$e->setAttribute('id', $offerId);
$e->setAttribute('productId', $offer->getId());
$quantity = $offerObject->getPropByName('common_quantity')->getValue();
$e->setAttribute('quantity', !empty($quantity) ? $quantity : 0);
/**
* Offer activity
*/
$activity = $offer->getIsActive() == 1 ? 'Y' : 'N';
$e->appendChild(
$this->dd->createElement('productActivity')
)->appendChild(
$this->dd->createTextNode($activity)
);
/**
* Offer category
*/
$e->appendChild($this->dd->createElement('categoryId'))
->appendChild(
$this->dd->createTextNode($offer->getRel())
);
/**
* Name & price
*/
if(!empty($offerOption)) {
$options = array();
foreach ($offerOption as $offerOptionId => $offerOptionValue) {
$options[] = $optionGroups[$offerOptionId]->getTitle() . ': ' . $optionValues[$offerOptionValue]->getName();
}
$offerName = $offer->getName() . ' (' . implode(', ', $options) . ')';
} else
$offerName = $offer->getName();
$e->appendChild($this->dd->createElement('name'))
->appendChild($this->dd->createTextNode($offerName));
$e->appendChild($this->dd->createElement('productName'))
->appendChild($this->dd->createTextNode($offer->getName()));
$price = $offerObject->getPropByName('price')->getValue();
if(!empty($offerOption)) {
foreach ($offerOption as $offerOptionId => $offerOptionValue) {
$price += $optionPrices[$offerOptionValue];
}
}
$e->appendChild($this->dd->createElement('price'))
->appendChild($this->dd->createTextNode($price));
/**
* Options
*/
if(!empty($offerOption)) {
$options = array();
foreach ($offerOption as $offerOptionId => $offerOptionValue) {
$option = $this->dd->createElement('param');
$option->setAttribute('code', $optionGroups[$offerOptionId]->getName());
$option->setAttribute('name', $optionGroups[$offerOptionId]->getTitle());
$option->appendChild($this->dd->createTextNode($optionValues[$offerOptionValue]->getName()));
$e->appendChild($option);
}
}
/**
* Image
*/
/** @var umiImageFile $photo */
$photo = $offerObject->getPropByName('photo')->getValue();
$photoPath = $photo->getFilePath(true);
$photoFullPath = $this->shopUrl . $photoPath;
$e->appendChild($this->dd->createElement('picture'))
->appendChild($this->dd->createTextNode($photoFullPath));
/**
* Url
*/
$url = $this->getObjectUrl($offer);
$e->appendChild($this->dd->createElement('url'))
->appendChild(
$this->dd->createTextNode($url)
);
/**
* Additional characteristics
*/
if ($offerObject->getPropByName('weight')) {
$weight = $this->dd->createElement('param');
$weight->setAttribute('code', 'weight');
$weight->setAttribute('name', 'Вес');
$weight->appendChild($this->dd->createTextNode($offerObject->getPropByName('weight')->getValue() * 1000));
$e->appendChild($weight);
}
}
}
}
}
?>

0
classes/modules/RetailCRM/data/objects.xml Executable file → Normal file
View file

19
classes/modules/RetailCRM/events.php Executable file → Normal file
View file

@ -1,18 +1,15 @@
<?php
$eventHandlers = array(
'icml' => 'onCronGenerateICML',
'history' => 'onCronSyncHistory',
);
global $argv;
if (isset($_SERVER['argv']) && (isset($_SERVER['argv'][2]) || isset($eventHandlers[$_SERVER['argv'][2]]))) {
new umiEventListener('cron', 'RetailCRM', $eventHandlers[$_SERVER['argv'][2]]);
if ((!isset($argv[2]) || $argv[2] == 'icml') && !isset($_GET['module']) || (isset($_GET['action']) && $_GET['action'] == 'icml')) {
new umiEventListener('cron', 'RetailCRM', 'onCronGenerateICML');
}
if (isset($_GET['action']) && isset($eventHandlers[$_GET['action']])) {
new umiEventListener('cron', 'RetailCRM', $eventHandlers[$_GET['action']]);
if ((!isset($argv[2]) || $argv[2] == 'history') && !isset($_GET['module']) || (isset($_GET['action']) && $_GET['action'] == 'history')) {
new umiEventListener('cron', 'RetailCRM', 'onCronSyncHistory');
}
new umiEventListener('systemModifyPropertyValue', 'RetailCRM', 'onModifyProperty');
new umiEventListener('systemModifyObject', 'RetailCRM', 'onModifyObject');
new umiEventListener('order-status-changed', 'RetailCRM', 'onOrderStatusChanged');
?>
?>

0
classes/modules/RetailCRM/i18n.php Executable file → Normal file
View file

0
classes/modules/RetailCRM/install.php Executable file → Normal file
View file