init
This commit is contained in:
parent
57de17ed5f
commit
cf88a8d7f8
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2016 retailCRM
|
Copyright (c) 2016 RetailDriver LLC
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
35
README.md
Normal file
35
README.md
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
UMI.CMS module
|
||||||
|
==============
|
||||||
|
|
||||||
|
Module allows integrate UMI.CMS with [RetailCRM](http://www.retailcrm.pro)
|
||||||
|
|
||||||
|
#### Features:
|
||||||
|
|
||||||
|
* Export orders to retailCRM & fetch changes back
|
||||||
|
* Export product catalog into [ICML](http://www.retailcrm.pro/docs/Developers/ICML) format
|
||||||
|
|
||||||
|
#### Setup
|
||||||
|
|
||||||
|
* Copy directories "classes" & "images" into document root
|
||||||
|
* Go to /admin/config/modules
|
||||||
|
* Into "Modules" tab fill installation script path (classes/modules/RetailCRM/install.php)
|
||||||
|
* Press setup button
|
||||||
|
* Go to module page
|
||||||
|
* Fill you api url & api key
|
||||||
|
* Specify directories matching
|
||||||
|
|
||||||
|
#### Setting product catalog export
|
||||||
|
|
||||||
|
Add to cron:
|
||||||
|
|
||||||
|
```
|
||||||
|
* */4 * * * /usr/bin/php /path_to_site/public_html/cron.php RetailCRM icml
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Getting changes in orders
|
||||||
|
|
||||||
|
Add to cron:
|
||||||
|
|
||||||
|
```
|
||||||
|
*/7 * * * * /usr/bin/php /path_to_site/public_html/cron.php RetailCRM history
|
||||||
|
```
|
33
README.ru.md
Normal file
33
README.ru.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
UMI.CMS module
|
||||||
|
==============
|
||||||
|
|
||||||
|
Модуль интеграции UMI.CMS c [RetailCRM](http://www.retailcrm.ru)
|
||||||
|
|
||||||
|
#### Модуль позволяет:
|
||||||
|
|
||||||
|
* Экспортировать в CRM данные о заказах и клиентах и получать обратно изменения по этим данным
|
||||||
|
* Синхронизировать справочники (способы доставки и оплаты, статусы заказов и т.п.)
|
||||||
|
* Выгружать каталог товаров в формате [ICML](http://retailcrm.ru/docs/Разработчики/ФорматICML) (IntaroCRM Markup Language)
|
||||||
|
|
||||||
|
#### Настройка
|
||||||
|
|
||||||
|
* Скопируйте директории classes и images в корень сайта
|
||||||
|
* В разделе управления модулями (/admin/config/modules) укажите путь до инсталяционного файла: classes/modules/RetailCRM/install.php
|
||||||
|
* На странице настроек модуля введите API url и API ключ, после этого установите соответствие справочников
|
||||||
|
|
||||||
|
#### Выгрузка каталога
|
||||||
|
|
||||||
|
Добавьте в крон запись вида
|
||||||
|
|
||||||
|
```
|
||||||
|
* */4 * * * /usr/bin/php /path_to_site/public_html/cron.php RetailCRM icml
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Получение изменение из RetailCRM
|
||||||
|
|
||||||
|
Добавьте в крон запись вида
|
||||||
|
|
||||||
|
```
|
||||||
|
*/7 * * * * /usr/bin/php /path_to_site/public_html/cron.php RetailCRM history
|
||||||
|
```
|
||||||
|
|
241
classes/modules/RetailCRM/__admin.php
Normal file
241
classes/modules/RetailCRM/__admin.php
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class __RetailCRM_adm extends baseModuleAdmin
|
||||||
|
{
|
||||||
|
|
||||||
|
public function manage()
|
||||||
|
{
|
||||||
|
$config = mainConfiguration::getInstance();
|
||||||
|
|
||||||
|
$crmUrl = (string)$config->get('retailcrm', 'crmUrl');
|
||||||
|
$apiKey = (string)$config->get('retailcrm', 'apiKey');
|
||||||
|
|
||||||
|
$params = array(
|
||||||
|
'access' => array(
|
||||||
|
'string:crmUrl' => $crmUrl,
|
||||||
|
'string:apiKey' => $apiKey
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Костыль для локализации полей
|
||||||
|
$translations = array();
|
||||||
|
|
||||||
|
if (!empty($apiKey) && !empty($crmUrl)) {
|
||||||
|
$api = new RCrmProxy(
|
||||||
|
$config->get('retailcrm', 'crmUrl'),
|
||||||
|
$config->get('retailcrm', 'apiKey'),
|
||||||
|
__DIR__ . '/../../../retailcrm.error.log'
|
||||||
|
);
|
||||||
|
|
||||||
|
if($api->paymentTypesList() !== false) {
|
||||||
|
/*
|
||||||
|
* Order Payment Types
|
||||||
|
*/
|
||||||
|
/** @var RCrmApiClient $api */
|
||||||
|
$crmPaymentTypes = $api->paymentTypesList()->getPaymentTypes();
|
||||||
|
$umiPaymentTypes = new selector('objects');
|
||||||
|
$umiPaymentTypes->types('object-type')->name('emarket', 'payment');
|
||||||
|
|
||||||
|
$map = $this->getRelationMap($config->get('retailcrm', 'orderPaymentTypeMap'));
|
||||||
|
|
||||||
|
$orderPaymentsMapping = array();
|
||||||
|
foreach ($umiPaymentTypes->result() as $umiPaymentType) {
|
||||||
|
$umiPaymentTypeId = $umiPaymentType->getPropByName('payment_type_id')->getObjectId();
|
||||||
|
$umiPaymentTypeName = $umiPaymentType->getName();
|
||||||
|
|
||||||
|
$translations['order-payment-type-' . $umiPaymentTypeId] = $umiPaymentTypeName;
|
||||||
|
|
||||||
|
$orderPaymentsMapping['select:order-payment-type-' . $umiPaymentTypeId] = array();
|
||||||
|
$orderPaymentsMapping['select:order-payment-type-' . $umiPaymentTypeId]['value'] = $this->getRelationByMap($map,
|
||||||
|
$umiPaymentTypeId);
|
||||||
|
|
||||||
|
$orderPaymentsMapping['select:order-payment-type-' . $umiPaymentTypeId]['none'] = '';
|
||||||
|
foreach ($crmPaymentTypes as $crmPaymentType) {
|
||||||
|
$orderPaymentsMapping['select:order-payment-type-' . $umiPaymentTypeId][$crmPaymentType['code']] = $crmPaymentType['name'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$params['orderPaymentsMapping'] = $orderPaymentsMapping;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Order Delivery Type
|
||||||
|
*/
|
||||||
|
$crmDeliveryTypes = $api->deliveryTypesList()->getDeliveryTypes();
|
||||||
|
$umiDeliveryTypes = new selector('objects');
|
||||||
|
$umiDeliveryTypes->types('object-type')->name('emarket', 'delivery');
|
||||||
|
|
||||||
|
$map = $this->getRelationMap($config->get('retailcrm', 'orderDeliveryTypeMap'));
|
||||||
|
|
||||||
|
$orderDeliveryTypesMapping = array();
|
||||||
|
foreach ($umiDeliveryTypes as $umiDeliveryType) {
|
||||||
|
$umiDeliveryTypeId = $umiDeliveryType->getId();
|
||||||
|
$umiDeliveryTypeName = $umiDeliveryType->getName();
|
||||||
|
|
||||||
|
$translations['order-delivery-type-' . $umiDeliveryTypeId] = $umiDeliveryTypeName;
|
||||||
|
|
||||||
|
$orderDeliveryTypesMapping['select:order-delivery-type-' . $umiDeliveryTypeId] = array();
|
||||||
|
$orderDeliveryTypesMapping['select:order-delivery-type-' . $umiDeliveryTypeId]['value'] = $this->getRelationByMap($map,
|
||||||
|
$umiDeliveryTypeId);
|
||||||
|
|
||||||
|
$orderDeliveryTypesMapping['select:order-delivery-type-' . $umiDeliveryTypeId]['none'] = '';
|
||||||
|
foreach ($crmDeliveryTypes as $crmDeliveryType) {
|
||||||
|
$orderDeliveryTypesMapping['select:order-delivery-type-' . $umiDeliveryTypeId][$crmDeliveryType['code']] = $crmDeliveryType['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
$params['orderDeliveryTypesMapping'] = $orderDeliveryTypesMapping;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Order Payment Statuses
|
||||||
|
*/
|
||||||
|
$crmPaymentStatuses = $api->paymentStatusesList()->getPaymentStatuses();
|
||||||
|
$umiPaymentStatuses = new selector('objects');
|
||||||
|
$umiPaymentStatuses->types('object-type')->name('emarket', 'order_payment_status');
|
||||||
|
|
||||||
|
$map = $this->getRelationMap($config->get('retailcrm', 'orderPaymentStatusMap'));
|
||||||
|
|
||||||
|
$orderPaymentStatusesMapping = array();
|
||||||
|
foreach ($umiPaymentStatuses->result() as $umiPaymentStatus) {
|
||||||
|
$umiPaymentStatusId = $umiPaymentStatus->getId();
|
||||||
|
$umiPaymentStatusName = $umiPaymentStatus->getName();
|
||||||
|
|
||||||
|
$translations['order-payment-status-' . $umiPaymentStatusId] = $umiPaymentStatusName;
|
||||||
|
|
||||||
|
$orderPaymentStatusesMapping['select:order-payment-status-' . $umiPaymentStatusId] = array();
|
||||||
|
$orderPaymentStatusesMapping['select:order-payment-status-' . $umiPaymentStatusId]['value'] = $this->getRelationByMap($map,
|
||||||
|
$umiPaymentStatusId);
|
||||||
|
|
||||||
|
$orderPaymentStatusesMapping['select:order-payment-status-' . $umiPaymentStatusId]['none'] = '';
|
||||||
|
foreach ($crmPaymentStatuses as $crmPaymentStatus) {
|
||||||
|
$orderPaymentStatusesMapping['select:order-payment-status-' . $umiPaymentStatusId][$crmPaymentStatus['code']] = $crmPaymentStatus['name'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$params['orderPaymentStatusesMapping'] = $orderPaymentStatusesMapping;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Order Statuses
|
||||||
|
*/
|
||||||
|
$crmOrderStatuses = $api->statusesList()->getStatuses();
|
||||||
|
$umiOrderStatuses = new selector('objects');
|
||||||
|
$umiOrderStatuses->types('object-type')->name('emarket', 'order_status');
|
||||||
|
|
||||||
|
$map = $this->getRelationMap($config->get('retailcrm', 'orderStatusMap'));
|
||||||
|
|
||||||
|
$params['orderStatusesMapping'] = array();
|
||||||
|
foreach ($umiOrderStatuses->result() as $umiOrderStatus) {
|
||||||
|
$translations['order-status-' . $umiOrderStatus->getPropByName('codename')->getValue()] = $umiOrderStatus->getName();
|
||||||
|
|
||||||
|
$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-' . $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;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: Добавить вывод ошибки, что данные некорректные
|
||||||
|
$params['incorrect-data'] = array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$mode = getRequest("param0");
|
||||||
|
if ($mode == "do") {
|
||||||
|
$params = $this->expectParams($params);
|
||||||
|
|
||||||
|
$config->set('retailcrm', 'crmUrl', $params['access']['string:crmUrl']);
|
||||||
|
$config->set('retailcrm', 'apiKey', $params['access']['string:apiKey']);
|
||||||
|
|
||||||
|
if (!empty($params['access']['string:crmUrl']) && !empty($params['access']['string:apiKey'])) {
|
||||||
|
/*
|
||||||
|
* Order Statuses
|
||||||
|
*/
|
||||||
|
if (!empty($params['orderStatusesMapping'])) {
|
||||||
|
$orderStatusMap = array();
|
||||||
|
foreach ($params['orderStatusesMapping'] as $umiOrderStatus => $crmOrderStatus) {
|
||||||
|
$umiOrderStatus = str_replace('select:order-status-', '', $umiOrderStatus);
|
||||||
|
$orderStatusMap[] = $umiOrderStatus . ' <-> ' . $crmOrderStatus;
|
||||||
|
}
|
||||||
|
$config->set('retailcrm', 'orderStatusMap', $orderStatusMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Order Payment Types
|
||||||
|
*/
|
||||||
|
if (!empty($params['orderPaymentsMapping'])) {
|
||||||
|
$orderPaymentTypeMap = array();
|
||||||
|
foreach ($params['orderPaymentsMapping'] as $umiOrderPaymentType => $crmOrderPaymentType) {
|
||||||
|
$umiOrderPaymentType = str_replace('select:order-payment-type-', '', $umiOrderPaymentType);
|
||||||
|
$orderPaymentTypeMap[] = $umiOrderPaymentType . ' <-> ' . $crmOrderPaymentType;
|
||||||
|
}
|
||||||
|
$config->set('retailcrm', 'orderPaymentTypeMap', $orderPaymentTypeMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Order Payment Statuses
|
||||||
|
*/
|
||||||
|
if (!empty($params['orderPaymentStatusesMapping'])) {
|
||||||
|
$orderPaymentStatusMap = array();
|
||||||
|
foreach ($params['orderPaymentStatusesMapping'] as $umiOrderPaymentStatus => $crmOrderPaymentStatus) {
|
||||||
|
$umiOrderPaymentStatus = str_replace('select:order-payment-status-', '', $umiOrderPaymentStatus);
|
||||||
|
$orderPaymentStatusMap[] = $umiOrderPaymentStatus . ' <-> ' . $crmOrderPaymentStatus;
|
||||||
|
}
|
||||||
|
$config->set('retailcrm', 'orderPaymentStatusMap', $orderPaymentStatusMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Order Delivery Types
|
||||||
|
*/
|
||||||
|
if (!empty($params['orderDeliveryTypesMapping'])) {
|
||||||
|
$orderDeliveryTypeMap = array();
|
||||||
|
foreach ($params['orderDeliveryTypesMapping'] as $umiOrderDeliveryType => $crmOrderDeliveryType) {
|
||||||
|
$umiOrderDeliveryType = str_replace('select:order-delivery-type-', '', $umiOrderDeliveryType);
|
||||||
|
$orderDeliveryTypeMap[] = $umiOrderDeliveryType . ' <-> ' . $crmOrderDeliveryType;
|
||||||
|
}
|
||||||
|
$config->set('retailcrm', 'orderDeliveryTypeMap', $orderDeliveryTypeMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($params['guidesMapping'])) {
|
||||||
|
foreach ($params['guidesMapping'] as $guideName => $guideId) {
|
||||||
|
$guideName = str_replace('select:', '', $guideName);
|
||||||
|
$config->set('retailcrm', $guideName . 'GuideId', $guideId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->chooseRedirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setDataType("settings");
|
||||||
|
$this->setActionType("modify");
|
||||||
|
|
||||||
|
$data = $this->prepareData($params, "settings");
|
||||||
|
|
||||||
|
// Реалзиация костыля для локализации полей
|
||||||
|
foreach ($data['nodes:group'] as $groupKey => $group) {
|
||||||
|
foreach ($group['nodes:option'] as $optionKey => $option) {
|
||||||
|
$label = $option['attribute:label'];
|
||||||
|
|
||||||
|
if (strpos($label, 'option-') > -1) {
|
||||||
|
$optionName = str_replace('option-', '', $label);
|
||||||
|
|
||||||
|
if (isset($translations[$optionName])) {
|
||||||
|
$data['nodes:group'][$groupKey]['nodes:option'][$optionKey]['attribute:label'] = $translations[$optionName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setData($data);
|
||||||
|
$this->doData();
|
||||||
|
}
|
||||||
|
}
|
57
classes/modules/RetailCRM/__events.php
Normal file
57
classes/modules/RetailCRM/__events.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class __RetailCRM_events
|
||||||
|
{
|
||||||
|
public function onCronGenerateICML()
|
||||||
|
{
|
||||||
|
$icml = new RCrmIcml();
|
||||||
|
$icml->generateICML();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onCronSyncHistory()
|
||||||
|
{
|
||||||
|
$history = new RCrmHistory();
|
||||||
|
$history->runCustomers();
|
||||||
|
$history->runOrders();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onOrderStatusChanged(umiEventPoint $eventPoint)
|
||||||
|
{
|
||||||
|
if ($eventPoint->getMode() != 'after') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$mode = $eventPoint->getParam('old-status-id') == null ? 'create' : 'edit';
|
||||||
|
|
||||||
|
/** @var order $order */
|
||||||
|
$order = $eventPoint->getRef('order');
|
||||||
|
|
||||||
|
RCrmActions::orderSend($order->getId(), $mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onModifyProperty(umiEventPoint $eventPoint)
|
||||||
|
{
|
||||||
|
/** @var umiEventPoint $eventPoint */
|
||||||
|
if ($eventPoint->getMode() != 'after') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var umiObject $entity */
|
||||||
|
$entity = $eventPoint->getRef('entity');
|
||||||
|
|
||||||
|
RCrmActions::orderSend($entity->getId(), 'edit');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onModifyObject(umiEventPoint $eventPoint)
|
||||||
|
{
|
||||||
|
/** @var umiEventPoint $eventPoint */
|
||||||
|
if ($eventPoint->getMode() != 'after') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var umiObject $object */
|
||||||
|
$object = $eventPoint->getRef('object');
|
||||||
|
|
||||||
|
RCrmActions::orderSend($object->getId(), 'edit');
|
||||||
|
}
|
||||||
|
}
|
35
classes/modules/RetailCRM/class.php
Normal file
35
classes/modules/RetailCRM/class.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
class RetailCRM extends def_module {
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
if (cmsController::getInstance()->getCurrentMode() == "admin") {
|
||||||
|
$this->__loadLib("__admin.php");
|
||||||
|
$this->__implement("__RetailCRM_adm");
|
||||||
|
}
|
||||||
|
|
||||||
|
$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");
|
||||||
|
|
||||||
|
// Exceptions
|
||||||
|
$this->__loadLib("classes/retailcrm/RCrmCurlException.php");
|
||||||
|
$this->__loadLib("classes/retailcrm/RCrmJsonException.php");
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
$this->__loadLib("classes/retailcrm/RCrmHelpers.php");
|
||||||
|
$this->__implement("RCrmHelpers");
|
||||||
|
|
||||||
|
// Events
|
||||||
|
$this->__loadLib("__events.php");
|
||||||
|
$this->__implement("__RetailCRM_events");
|
||||||
|
}
|
||||||
|
}
|
265
classes/modules/RetailCRM/classes/retailcrm/RCrmActions.php
Normal file
265
classes/modules/RetailCRM/classes/retailcrm/RCrmActions.php
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class RCrmActions
|
||||||
|
{
|
||||||
|
public static function orderSend($orderId, $mode = 'create') {
|
||||||
|
/** @var RCrmApiClient $api */
|
||||||
|
$objects = umiObjectsCollection::getInstance();
|
||||||
|
$order = order::get($orderId);
|
||||||
|
|
||||||
|
if (!$order) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверяем был ли вызов из апи
|
||||||
|
$regedit = regedit::getInstance();
|
||||||
|
$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($order->getOrderStatus());
|
||||||
|
|
||||||
|
$retailcrm = new RetailCRM;
|
||||||
|
|
||||||
|
$relationMap = $retailcrm->getRelationMap($config->get('retailcrm', 'orderStatusMap'));
|
||||||
|
$crmOrderStatusCode = $retailcrm->getRelationByMap($relationMap, $umiOrderStatusCode);
|
||||||
|
|
||||||
|
if (!$crmOrderStatusCode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$umiOrderPaymentType = $order->getObject()->getValue('payment_id');
|
||||||
|
$relationOrderPaymentTypesMap = $retailcrm->getRelationMap($config->get('retailcrm', 'orderPaymentTypeMap'));
|
||||||
|
$crmOrderPaymentType = $retailcrm->getRelationByMap($relationOrderPaymentTypesMap, $umiOrderPaymentType);
|
||||||
|
|
||||||
|
$umiOrderPaymentStatus = $order->getObject()->getValue('payment_status_id');
|
||||||
|
$relationOrderPaymentStatusesMap = $retailcrm->getRelationMap($config->get('retailcrm', 'orderPaymentStatusMap'));
|
||||||
|
$crmOrderPaymentStatus = $retailcrm->getRelationByMap($relationOrderPaymentStatusesMap, $umiOrderPaymentStatus);
|
||||||
|
|
||||||
|
$umiOrderDeliveryId = $order->getObject()->getValue('delivery_id');
|
||||||
|
$relationOrderDeliveryTypesMap = $retailcrm->getRelationMap($config->get('retailcrm', 'orderDeliveryTypeMap'));
|
||||||
|
$crmOrderDeliveryType = $retailcrm->getRelationByMap($relationOrderDeliveryTypesMap, $umiOrderDeliveryId);
|
||||||
|
|
||||||
|
$customer = customer::get($order->getCustomerId());
|
||||||
|
$orderItems = $order->getItems();
|
||||||
|
|
||||||
|
$orderItemsToCrm = array();
|
||||||
|
|
||||||
|
foreach ($orderItems as $orderItem) {
|
||||||
|
/** @var optionedOrderItem $orderItem */
|
||||||
|
|
||||||
|
$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();
|
||||||
|
foreach ($orderItem->getOptions() as $option) {
|
||||||
|
$option = $objects->getObject($option['option-id']);
|
||||||
|
$options[] = $optionGuidesToGroups[$option->getTypeId()] . '_' . $option->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
$product = $orderItem->getItemElement();
|
||||||
|
|
||||||
|
if (!empty($options)) {
|
||||||
|
$productId = $product->getId() . '#' . implode('-', $options);
|
||||||
|
} else {
|
||||||
|
$productId = $product->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
$orderItemsToCrm[] = array(
|
||||||
|
'initialPrice' => $orderItem->getItemPrice(),
|
||||||
|
'discount' => $orderItem->getDiscount(),
|
||||||
|
'quantity' => $orderItem->getAmount(),
|
||||||
|
'productName' => $product->getName(),
|
||||||
|
'properties' => $itemProperties,
|
||||||
|
'offer' => array(
|
||||||
|
'externalId' => $productId
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* One click order */
|
||||||
|
if ($order->getObject()->getValue('purchaser_one_click') !== null) {
|
||||||
|
$oneClickObj = new umiObject($order->getObject()->getValue('purchaser_one_click'));
|
||||||
|
|
||||||
|
$orderToCrm = array(
|
||||||
|
'number' => $order->getObject()->getName(),
|
||||||
|
'externalId' => $order->getId(),
|
||||||
|
'phone' => $oneClickObj->getValue('phone'),
|
||||||
|
'customer' => array(
|
||||||
|
'externalId' => $customer->getId()
|
||||||
|
),
|
||||||
|
'paymentType' => $crmOrderPaymentType,
|
||||||
|
'paymentStatus' => $crmOrderPaymentStatus,
|
||||||
|
'status' => $crmOrderStatusCode,
|
||||||
|
'items' => $orderItemsToCrm,
|
||||||
|
'orderMethod' => 'one-click'
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
if ($order->getObject()->getValue('delivery_address') !== null) {
|
||||||
|
$deliveryObjId = $order->getObject()->getValue('delivery_address');
|
||||||
|
$deliveryObj = new umiObject($deliveryObjId);
|
||||||
|
|
||||||
|
if ($deliveryObj->getValue('country') !== false) {
|
||||||
|
$deliveryCountryObjId = $deliveryObj->getValue('country');
|
||||||
|
$deliveryCountryObj = new umiObject($deliveryCountryObjId);
|
||||||
|
$deliveryCountryIsoCode = $deliveryCountryObj->getValue('country_iso_code');
|
||||||
|
} else {
|
||||||
|
$deliveryCountryIsoCode = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$deliveryIndex = $deliveryObj->getValue('index');
|
||||||
|
$deliveryStreet = $deliveryObj->getValue('street');
|
||||||
|
$deliveryBuilding = $deliveryObj->getValue('house');
|
||||||
|
$deliveryHouse = $deliveryObj->getValue('house');
|
||||||
|
$deliveryFlat = $deliveryObj->getValue('flat');
|
||||||
|
$deliveryNotes = $deliveryObj->getValue('order_comments');
|
||||||
|
|
||||||
|
if ($deliveryObj->getValue('region') !== null) {
|
||||||
|
$deliveryRegionObj = new umiObject($deliveryObj->getValue('region'));
|
||||||
|
$deliveryRegion = $deliveryRegionObj->getName();
|
||||||
|
} else {
|
||||||
|
$deliveryRegion = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($deliveryObj->getValue('city') !== null) {
|
||||||
|
$deliveryCityObj = new umiObject($deliveryObj->getValue('city'));
|
||||||
|
$deliveryCity = $deliveryCityObj->getName();
|
||||||
|
} else {
|
||||||
|
$deliveryCity = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$addressToCrm = array(
|
||||||
|
'countryIso' => $deliveryCountryIsoCode,
|
||||||
|
'index' => $deliveryIndex,
|
||||||
|
'region' => $deliveryRegion,
|
||||||
|
'city' => $deliveryCity,
|
||||||
|
'street' => $deliveryStreet,
|
||||||
|
'building' => $deliveryBuilding,
|
||||||
|
'flat' => $deliveryFlat,
|
||||||
|
'house' => $deliveryHouse,
|
||||||
|
'notes' => $deliveryNotes
|
||||||
|
);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$addressToCrm = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$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()
|
||||||
|
),
|
||||||
|
'paymentType' => $crmOrderPaymentType,
|
||||||
|
'paymentStatus' => $crmOrderPaymentStatus,
|
||||||
|
'status' => $crmOrderStatusCode,
|
||||||
|
'items' => $orderItemsToCrm,
|
||||||
|
'delivery' => array(
|
||||||
|
'address' => $addressToCrm,
|
||||||
|
'code' => $crmOrderDeliveryType
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: есть возможность учитывать домен
|
||||||
|
$api = new RCrmProxy(
|
||||||
|
$config->get('retailcrm', 'crmUrl'),
|
||||||
|
$config->get('retailcrm', 'apiKey'),
|
||||||
|
__DIR__ . '/../../../retailcrm.error.log'
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($mode == 'create') {
|
||||||
|
$orderToCrm = self::customerPrepare($orderToCrm);
|
||||||
|
$api->ordersCreate($orderToCrm);
|
||||||
|
} else if ($mode == 'edit') {
|
||||||
|
$api->ordersEdit($orderToCrm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function customerPrepare($orderToCrm) {
|
||||||
|
$config = mainConfiguration::getInstance();
|
||||||
|
|
||||||
|
$api = new RCrmProxy(
|
||||||
|
$config->get('retailcrm', 'crmUrl'),
|
||||||
|
$config->get('retailcrm', 'apiKey'),
|
||||||
|
__DIR__ . '/../../../retailcrm.error.log'
|
||||||
|
);
|
||||||
|
|
||||||
|
$crmCustomer = $api->customersGet($orderToCrm['customer']['externalId']);
|
||||||
|
|
||||||
|
if (!$crmCustomer) {
|
||||||
|
$crmCustomers = $api->customersList(array(
|
||||||
|
'name' => $orderToCrm['phone'],
|
||||||
|
'email' => $orderToCrm['email']
|
||||||
|
));
|
||||||
|
|
||||||
|
$foundedCustomerExternalId = false;
|
||||||
|
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;
|
||||||
|
$orderToCrm['customer']['externalId'] = $crmCustomer['externalId'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$foundedCustomerExternalId) {
|
||||||
|
$crmCustomer = $crmCustomers[0];
|
||||||
|
$status = $api->customersFixExternalIds(array(
|
||||||
|
'id' => $crmCustomer['id'],
|
||||||
|
'externalId' => $crmCustomer['externalId']
|
||||||
|
));
|
||||||
|
|
||||||
|
if (!$status) {
|
||||||
|
unset($orderToCrm['customer']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$status = $api->customersCreate(array(
|
||||||
|
'externalId' => $orderToCrm['customer']['externalId'],
|
||||||
|
'firstName' => $orderToCrm['firstName'],
|
||||||
|
'lastName' => $orderToCrm['lastName'],
|
||||||
|
'patronymic' => $orderToCrm['patronymic'],
|
||||||
|
'email' => $orderToCrm['email'],
|
||||||
|
'phones' => array(
|
||||||
|
'number' => $orderToCrm['phone']
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
if (!$status) {
|
||||||
|
unset($orderToCrm['customer']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unset($orderToCrm['customer']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $orderToCrm;
|
||||||
|
}
|
||||||
|
}
|
1825
classes/modules/RetailCRM/classes/retailcrm/RCrmApiClient.php
Normal file
1825
classes/modules/RetailCRM/classes/retailcrm/RCrmApiClient.php
Normal file
File diff suppressed because it is too large
Load Diff
164
classes/modules/RetailCRM/classes/retailcrm/RCrmApiResponse.php
Normal file
164
classes/modules/RetailCRM/classes/retailcrm/RCrmApiResponse.php
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHP version 5.3
|
||||||
|
*
|
||||||
|
* Response from retailCRM API
|
||||||
|
*
|
||||||
|
* @category RetailCrm
|
||||||
|
* @package RetailCrm
|
||||||
|
* @author RetailCrm <integration@retailcrm.ru>
|
||||||
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
|
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion4
|
||||||
|
*/
|
||||||
|
class RCrmApiResponse implements ArrayAccess
|
||||||
|
{
|
||||||
|
// HTTP response status code
|
||||||
|
protected $statusCode;
|
||||||
|
|
||||||
|
// response assoc array
|
||||||
|
protected $response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ApiResponse constructor.
|
||||||
|
*
|
||||||
|
* @param int $statusCode HTTP status code
|
||||||
|
* @param mixed $responseBody HTTP body
|
||||||
|
*
|
||||||
|
* @throws RCrmJsonException
|
||||||
|
*/
|
||||||
|
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 RCrmJsonException(
|
||||||
|
"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 method name
|
||||||
|
* @param mixed $arguments method parameters
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*
|
||||||
|
* @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 property name
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function __get($name)
|
||||||
|
{
|
||||||
|
if (!isset($this->response[$name])) {
|
||||||
|
throw new InvalidArgumentException("Property \"$name\" not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->response[$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Offset set
|
||||||
|
*
|
||||||
|
* @param mixed $offset offset
|
||||||
|
* @param mixed $value value
|
||||||
|
*
|
||||||
|
* @throws BadMethodCallException
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function offsetSet($offset, $value)
|
||||||
|
{
|
||||||
|
throw new BadMethodCallException('This activity not allowed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Offset unset
|
||||||
|
*
|
||||||
|
* @param mixed $offset offset
|
||||||
|
*
|
||||||
|
* @throws BadMethodCallException
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function offsetUnset($offset)
|
||||||
|
{
|
||||||
|
throw new BadMethodCallException('This call not allowed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check offset
|
||||||
|
*
|
||||||
|
* @param mixed $offset offset
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function offsetExists($offset)
|
||||||
|
{
|
||||||
|
return isset($this->response[$offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get offset
|
||||||
|
*
|
||||||
|
* @param mixed $offset offset
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function offsetGet($offset)
|
||||||
|
{
|
||||||
|
if (!isset($this->response[$offset])) {
|
||||||
|
throw new InvalidArgumentException("Property \"$offset\" not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->response[$offset];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
class RCrmCurlException extends RuntimeException
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
175
classes/modules/RetailCRM/classes/retailcrm/RCrmHelpers.php
Normal file
175
classes/modules/RetailCRM/classes/retailcrm/RCrmHelpers.php
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class RCrmHelpers
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $orderHistory array
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getAssemblyOrder($orderHistory)
|
||||||
|
{
|
||||||
|
if (file_exists(__DIR__ . '/../../data/objects.xml')) {
|
||||||
|
$objects = simplexml_load_file(__DIR__ . '/../../data/objects.xml');
|
||||||
|
foreach ($objects->fields->field as $object) {
|
||||||
|
$fields[(string)$object["group"]][(string)$object["id"]] = (string)$object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$orders = array();
|
||||||
|
|
||||||
|
foreach ($orderHistory as $change) {
|
||||||
|
$change['order'] = $this->removeEmpty($change['order']);
|
||||||
|
|
||||||
|
$orderId = $change['order']['id'];
|
||||||
|
|
||||||
|
if (isset($change['order']['items'])) {
|
||||||
|
$items = array();
|
||||||
|
foreach ($change['order']['items'] as $item) {
|
||||||
|
if (isset($change['created'])) {
|
||||||
|
$item['created'] = 1;
|
||||||
|
}
|
||||||
|
$items[$item['id']] = $item;
|
||||||
|
}
|
||||||
|
$change['order']['items'] = $items;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($change['order']['contragent']['contragentType'])) {
|
||||||
|
$change['order']['contragentType'] = $change['order']['contragent']['contragentType'];
|
||||||
|
unset($change['order']['contragent']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($orders[$orderId])) {
|
||||||
|
$orders[$orderId] = array_merge($orders[$orderId], $change['order']);
|
||||||
|
} else {
|
||||||
|
$orders[$orderId] = $change['order'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($change['item'])) {
|
||||||
|
$itemId = $change['item']['id'];
|
||||||
|
|
||||||
|
if ($orders[$orderId]['items'][$itemId]) {
|
||||||
|
$orders[$orderId]['items'][$itemId] = array_merge($orders[$orderId]['items'][$itemId],
|
||||||
|
$change['item']);
|
||||||
|
} else {
|
||||||
|
$orders[$orderId]['items'][$itemId] = $change['item'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($change['oldValue']) && $change['field'] == 'order_product') {
|
||||||
|
$orders[$orderId]['items'][$itemId]['created'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($change['newValue']) && $change['field'] == 'order_product') {
|
||||||
|
$orders[$orderId]['items'][$itemId]['deleted'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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'] = $this->historyNewValue($change['newValue']);
|
||||||
|
} elseif (isset($fields['delivery'][$change['field']])) {
|
||||||
|
$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']]] = $this->historyNewValue($change['newValue']);
|
||||||
|
} elseif (isset($fields['customerContragent'][$change['field']])) {
|
||||||
|
$orders[$orderId][$fields['customerContragent'][$change['field']]] = $this->historyNewValue($change['newValue']);
|
||||||
|
} elseif (strripos($change['field'], 'custom_') !== false) {
|
||||||
|
$orders[$orderId]['customFields'][str_replace('custom_', '', $change['field'])] = $this->historyNewValue($change['newValue']);
|
||||||
|
} elseif (isset($fields['order'][$change['field']])) {
|
||||||
|
$orders[$orderId][$fields['order'][$change['field']]] = $this->historyNewValue($change['newValue']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($change['created'])) {
|
||||||
|
$orders[$orderId]['created'] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($change['deleted'])) {
|
||||||
|
$orders[$orderId]['deleted'] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_values($orders);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $value mixed
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function historyNewValue($value)
|
||||||
|
{
|
||||||
|
if (isset($value['code'])) {
|
||||||
|
return $value['code'];
|
||||||
|
} else {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $inputArray mixed
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
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 = $this->removeEmpty($element);
|
||||||
|
}
|
||||||
|
$outputArray[$key] = $element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $outputArray;
|
||||||
|
}
|
||||||
|
}
|
470
classes/modules/RetailCRM/classes/retailcrm/RCrmHistory.php
Normal file
470
classes/modules/RetailCRM/classes/retailcrm/RCrmHistory.php
Normal file
@ -0,0 +1,470 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class RCrmHistory
|
||||||
|
{
|
||||||
|
/** @var RCrmApiClient $api */
|
||||||
|
private $api = null;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$config = mainConfiguration::getInstance();
|
||||||
|
|
||||||
|
$this->api = new RCrmProxy(
|
||||||
|
$config->get('retailcrm', 'crmUrl'),
|
||||||
|
$config->get('retailcrm', 'apiKey'),
|
||||||
|
__DIR__ . '/../../../retailcrm.error.log'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function runOrders()
|
||||||
|
{
|
||||||
|
$retailcrm = new RetailCRM;
|
||||||
|
$regedit = regedit::getInstance();
|
||||||
|
$config = mainConfiguration::getInstance();
|
||||||
|
|
||||||
|
$historyLastId = $config->get('retailcrm', 'lastHistorySinceId');
|
||||||
|
|
||||||
|
if (!$historyLastId) {
|
||||||
|
$historyLastId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$historyPage = 1;
|
||||||
|
$historyArray = array();
|
||||||
|
|
||||||
|
do {
|
||||||
|
$response = $this->api->ordersHistory(array('sinceId' => $historyLastId), $historyPage);
|
||||||
|
$historyPage++;
|
||||||
|
|
||||||
|
if (!is_null($response) && count($response['history'])) {
|
||||||
|
$historyArray = array_merge($historyArray, $response['history']);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while ($response['pagination']['currentPage'] != $response['pagination']['totalPageCount']);
|
||||||
|
|
||||||
|
if (count($historyArray)) {
|
||||||
|
$lastChange = end($historyArray);
|
||||||
|
|
||||||
|
$crmOrders = $retailcrm->getAssemblyOrder($historyArray);
|
||||||
|
|
||||||
|
$objectTypes = umiObjectTypesCollection::getInstance();
|
||||||
|
$objects = umiObjectsCollection::getInstance();
|
||||||
|
|
||||||
|
foreach ($crmOrders as $crmOrder) {
|
||||||
|
$order = null;
|
||||||
|
|
||||||
|
if (isset($crmOrder['externalId'])) {
|
||||||
|
$order = order::get($crmOrder['externalId']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!isset($crmOrder['externalId']) || !$order) && isset($crmOrder['created'])) {
|
||||||
|
if (isset($crmOrder['deleted']) && $crmOrder['deleted']) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$order = order::create();
|
||||||
|
|
||||||
|
/* Order create date */
|
||||||
|
$order->getObject()->getPropByName('order_date')->setValue(umiDate::getTimeStamp($crmOrder['createdAt']));
|
||||||
|
|
||||||
|
$crmCustomer = $crmOrder['customer'];
|
||||||
|
if (isset($crmCustomer['externalId']) && $crmCustomer['externalId'] > 0) {
|
||||||
|
// TODO: проверить существует ли такой пользователь в системе, если нет, то создать, т.к. принимая customer externalId мы считаем, что такой пользователь уже есть
|
||||||
|
$order->getObject()->getPropByName('customer_id')->setValue($crmCustomer['externalId']);
|
||||||
|
} else {
|
||||||
|
$customer = $objects->getObjectByName($crmCustomer['id'] . '-retailcrm');
|
||||||
|
|
||||||
|
if (!$customer) {
|
||||||
|
$customerObjectTypeId = $objectTypes->getBaseType('emarket', 'customer');
|
||||||
|
|
||||||
|
$customerId = $objects->addObject(
|
||||||
|
$crmCustomer['id'] . '-retailcrm',
|
||||||
|
$customerObjectTypeId
|
||||||
|
);
|
||||||
|
|
||||||
|
$customer = $objects->getObject($customerId);
|
||||||
|
$customer->setOwnerId($objects->getObjectIdByGUID('system-guest'));
|
||||||
|
$customer->commit();
|
||||||
|
|
||||||
|
$expirations = umiObjectsExpiration::getInstance();
|
||||||
|
$expirations->add($customerId, customer::$defaultExpiration);
|
||||||
|
|
||||||
|
if (!empty($crmCustomer['firstName'])) {
|
||||||
|
$customer->getPropByName('fname')->setValue($crmCustomer['firstName']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($crmCustomer['lastName'])) {
|
||||||
|
$customer->getPropByName('lname')->setValue($crmCustomer['lastName']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($crmCustomer['patronymic'])) {
|
||||||
|
$customer->getPropByName('father_name')->setValue($crmCustomer['patronymic']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($crmCustomer['email'])) {
|
||||||
|
$customer->getPropByName('email')->setValue($crmCustomer['email']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($crmCustomer['phones']) && count($crmCustomer['phones']) > 0) {
|
||||||
|
$customer->getPropByName('phone')->setValue($crmCustomer['phones'][0]['number']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($crmCustomer['address'])) {
|
||||||
|
$deliveryTypeId = $objectTypes->getTypeIdByGUID('emarket-deliveryaddress');
|
||||||
|
|
||||||
|
$deliveryObjectId = $objects->addObject(
|
||||||
|
'Address for customer ' . $customer->getId(),
|
||||||
|
$deliveryTypeId
|
||||||
|
);
|
||||||
|
|
||||||
|
$deliveryObject = $objects->getObject($deliveryObjectId);
|
||||||
|
|
||||||
|
$crmCustomerAddress = $crmCustomer['address'];
|
||||||
|
|
||||||
|
if (!empty($crmCustomerAddress['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 ($crmCustomerAddress['countryIso'] == $countryCode) {
|
||||||
|
$deliveryObject->getPropByName('country')->setValue($country->getId());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($crmCustomerAddress['index'])) {
|
||||||
|
$deliveryObject->getPropByName('index')->setValue($crmCustomerAddress['index']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($crmCustomerAddress['region'])) {
|
||||||
|
$deliveryObject->getPropByName('region')->setValue($crmCustomerAddress['region']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($crmCustomerAddress['city'])) {
|
||||||
|
$deliveryObject->getPropByName('city')->setValue($crmCustomerAddress['city']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($crmCustomerAddress['street'])) {
|
||||||
|
$deliveryObject->getPropByName('street')->setValue($crmCustomerAddress['street']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($crmCustomerAddress['building'])) {
|
||||||
|
$deliveryObject->getPropByName('house')->setValue($crmCustomerAddress['building']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($crmCustomerAddress['flat'])) {
|
||||||
|
$deliveryObject->getPropByName('flat')->setValue($crmCustomerAddress['flat']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$deliveryAddresses = array(
|
||||||
|
0 => $deliveryObject->getId()
|
||||||
|
);
|
||||||
|
|
||||||
|
$customer->getPropByName('delivery_addresses')->setValue($deliveryAddresses);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$order->getObject()->getPropByName('customer_id')->setValue($customer->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
$orderItems = $order->getItems();
|
||||||
|
foreach ($orderItems as $orderItem) {
|
||||||
|
$order->removeItem($orderItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
$crmItems = $crmOrder['items'];
|
||||||
|
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 (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['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');
|
||||||
|
$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($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()
|
||||||
|
)
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
if (!$order) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($crmOrder['items']) && count($crmOrder['items']) > 0) {
|
||||||
|
$orderItems = $order->getItems();
|
||||||
|
foreach ($orderItems as $orderItem) {
|
||||||
|
$order->removeItem($orderItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
$crmOrderForItems = $this->api->ordersGet($crmOrder['externalId'])->getOrder();
|
||||||
|
$crmItems = $crmOrderForItems['items'];
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$customer = $objects->getObject($order->getCustomerId());
|
||||||
|
|
||||||
|
if (isset($crmOrder['phone'])) {
|
||||||
|
$customer->getPropByName('phone')->setValue($crmOrder['phone']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($crmOrder['lastName'])) {
|
||||||
|
$customer->getPropByName('lname')->setValue($crmOrder['lastName']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($crmOrder['firstName'])) {
|
||||||
|
$customer->getPropByName('fname')->setValue($crmOrder['firstName']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($crmOrder['patronymic'])) {
|
||||||
|
$customer->getPropByName('father_name')->setValue($crmOrder['patronymic']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($crmOrder['e-mail'])) {
|
||||||
|
$customer->getPropByName('e-mail')->setValue($crmOrder['e-mail']);
|
||||||
|
}
|
||||||
|
|
||||||
|
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['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 = $retailcrm->getRelationMap($config->get('retailcrm', 'orderStatusMap'));
|
||||||
|
$umiOrderStatusCode = $retailcrm->getRelationByMap($relationMap, $crmOrder['status'], true);
|
||||||
|
if ($umiOrderStatusCode) {
|
||||||
|
// меняем дату редактирования заказа, для того, чтобы его не перехватил хенлдер и не выплюнул обратно в црм
|
||||||
|
$order->getObject()->setUpdateTime(time());
|
||||||
|
$order->setOrderStatus($umiOrderStatusCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$order->refresh();
|
||||||
|
$config->set('retailcrm', 'lastHistorySinceId', $lastChange['id']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function runCustomers()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
110
classes/modules/RetailCRM/classes/retailcrm/RCrmHttpClient.php
Normal file
110
classes/modules/RetailCRM/classes/retailcrm/RCrmHttpClient.php
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHP version 5.3
|
||||||
|
*
|
||||||
|
* HTTP client
|
||||||
|
*
|
||||||
|
* @category RetailCrm
|
||||||
|
* @package RetailCrm
|
||||||
|
* @author RetailCrm <integration@retailcrm.ru>
|
||||||
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
|
* @link http://www.retailcrm.ru/docs/Developers/ApiVersion4
|
||||||
|
*/
|
||||||
|
class RCrmHttpClient
|
||||||
|
{
|
||||||
|
const METHOD_GET = 'GET';
|
||||||
|
const METHOD_POST = 'POST';
|
||||||
|
|
||||||
|
protected $url;
|
||||||
|
protected $defaultParameters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client constructor.
|
||||||
|
*
|
||||||
|
* @param string $url api url
|
||||||
|
* @param array $defaultParameters array of parameters
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make HTTP request
|
||||||
|
*
|
||||||
|
* @param string $path request url
|
||||||
|
* @param string $method (default: 'GET')
|
||||||
|
* @param array $parameters (default: array())
|
||||||
|
*
|
||||||
|
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* @throws RCrmCurlException
|
||||||
|
* @throws RCrmJsonException
|
||||||
|
*
|
||||||
|
* @return RCrmApiResponse
|
||||||
|
*/
|
||||||
|
public function makeRequest(
|
||||||
|
$path,
|
||||||
|
$method,
|
||||||
|
array $parameters = array()
|
||||||
|
) {
|
||||||
|
$allowedMethods = array(self::METHOD_GET, self::METHOD_POST);
|
||||||
|
|
||||||
|
if (!in_array($method, $allowedMethods, false)) {
|
||||||
|
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 && count($parameters)) {
|
||||||
|
$url .= '?' . http_build_query($parameters, '', '&');
|
||||||
|
}
|
||||||
|
|
||||||
|
$curlHandler = curl_init();
|
||||||
|
curl_setopt($curlHandler, CURLOPT_URL, $url);
|
||||||
|
curl_setopt($curlHandler, CURLOPT_RETURNTRANSFER, 1);
|
||||||
|
curl_setopt($curlHandler, CURLOPT_FOLLOWLOCATION, 1);
|
||||||
|
curl_setopt($curlHandler, CURLOPT_FAILONERROR, false);
|
||||||
|
curl_setopt($curlHandler, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
curl_setopt($curlHandler, CURLOPT_SSL_VERIFYHOST, false);
|
||||||
|
curl_setopt($curlHandler, CURLOPT_TIMEOUT, 30);
|
||||||
|
curl_setopt($curlHandler, CURLOPT_CONNECTTIMEOUT, 30);
|
||||||
|
|
||||||
|
if (self::METHOD_POST === $method) {
|
||||||
|
curl_setopt($curlHandler, CURLOPT_POST, true);
|
||||||
|
curl_setopt($curlHandler, CURLOPT_POSTFIELDS, $parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
$responseBody = curl_exec($curlHandler);
|
||||||
|
$statusCode = curl_getinfo($curlHandler, CURLINFO_HTTP_CODE);
|
||||||
|
$errno = curl_errno($curlHandler);
|
||||||
|
$error = curl_error($curlHandler);
|
||||||
|
|
||||||
|
curl_close($curlHandler);
|
||||||
|
|
||||||
|
if ($errno) {
|
||||||
|
throw new RCrmCurlException($error, $errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RCrmApiResponse($statusCode, $responseBody);
|
||||||
|
}
|
||||||
|
}
|
309
classes/modules/RetailCRM/classes/retailcrm/RCrmIcml.php
Normal file
309
classes/modules/RetailCRM/classes/retailcrm/RCrmIcml.php
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class RCrmIcml
|
||||||
|
{
|
||||||
|
/** @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();
|
||||||
|
|
||||||
|
$downloadPath = __DIR__ . '/../../../../../';
|
||||||
|
|
||||||
|
if (!file_exists($downloadPath)) {
|
||||||
|
mkdir($downloadPath, 0755);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dd->saveXML();
|
||||||
|
$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 = '/' . $obj->getAltName();
|
||||||
|
|
||||||
|
$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('');
|
||||||
|
}
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
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 */
|
||||||
|
if ($offerObject->getPropByName('images') !== null) {
|
||||||
|
$photos = $offerObject->getPropByName('images')->getValue();
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class RCrmJsonException extends \DomainException
|
||||||
|
{
|
||||||
|
}
|
42
classes/modules/RetailCRM/classes/retailcrm/RCrmProxy.php
Normal file
42
classes/modules/RetailCRM/classes/retailcrm/RCrmProxy.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class RequestProxy
|
||||||
|
* @package RetailCrm\Component
|
||||||
|
*/
|
||||||
|
class RCrmProxy
|
||||||
|
{
|
||||||
|
private $api;
|
||||||
|
private $log;
|
||||||
|
|
||||||
|
public function __construct($url, $key, $log)
|
||||||
|
{
|
||||||
|
$this->api = new RCrmApiClient($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 (RCrmCurlException $e) {
|
||||||
|
error_log("[$method] " . $e->getMessage() . "\n", 3, $this->log);
|
||||||
|
return false;
|
||||||
|
} catch (RCrmJsonException $e) {
|
||||||
|
error_log("[$method] " . $e->getMessage() . "\n", 3, $this->log);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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];
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
294
classes/modules/RetailCRM/classes/retailcrm/icml.php
Normal file
294
classes/modules/RetailCRM/classes/retailcrm/icml.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
100
classes/modules/RetailCRM/data/objects.xml
Normal file
100
classes/modules/RetailCRM/data/objects.xml
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<options>
|
||||||
|
<fields>
|
||||||
|
<field id="id" group="customer">id</field>
|
||||||
|
<field id="first_name" group="customer">firstName</field>
|
||||||
|
<field id="last_name" group="customer">lastName</field>
|
||||||
|
<field id="patronymic" group="customer">patronymic</field>
|
||||||
|
<field id="email" group="customer">email</field>
|
||||||
|
<field id="birthday" group="customer">birthday</field>
|
||||||
|
<field id="phones" group="customer">phones</field>
|
||||||
|
<field id="manager" group="customer">manager</field>
|
||||||
|
<field id="commentary" group="customer">commentary</field>
|
||||||
|
<field id="external_id" group="customer">externalId</field>
|
||||||
|
<field id="cumulative_discount" group="customer">cumulativeDiscount</field>
|
||||||
|
<field id="personal_discount" group="customer">personalDiscount</field>
|
||||||
|
<field id="discount_card_number" group="customer">discountCardNumber</field>
|
||||||
|
|
||||||
|
<field id="address.index" group="customerAddress">index</field>
|
||||||
|
<field id="address.country" group="customerAddress">country</field>
|
||||||
|
<field id="address.region" group="customerAddress">region</field>
|
||||||
|
<field id="address.city" group="customerAddress">city</field>
|
||||||
|
<field id="address.street" group="customerAddress">street</field>
|
||||||
|
<field id="address.building" group="customerAddress">building</field>
|
||||||
|
<field id="address.house" group="customerAddress">house</field>
|
||||||
|
<field id="address.block" group="customerAddress">block</field>
|
||||||
|
<field id="address.flat" group="customerAddress">flat</field>
|
||||||
|
<field id="address.floor" group="customerAddress">floor</field>
|
||||||
|
<field id="address.intercom_code" group="customerAddress">intercomCode</field>
|
||||||
|
<field id="address.metro" group="customerAddress">metro</field>
|
||||||
|
<field id="address.notes" group="customerAddress">notes</field>
|
||||||
|
|
||||||
|
<field id="contragent.contragent_type" group="customerContragent">contragentType</field>
|
||||||
|
<field id="contragent.legal_name" group="customerContragent">legalName</field>
|
||||||
|
<field id="contragent.legal_address" group="customerContragent">legalAddress</field>
|
||||||
|
<field id="contragent.certificate_number" group="customerContragent">certificateNumber</field>
|
||||||
|
<field id="contragent.certificate_date" group="customerContragent">certificateDate</field>
|
||||||
|
<field id="contragent.bank" group="customerContragent">bank</field>
|
||||||
|
<field id="contragent.bank_address" group="customerContragent">bankAddress</field>
|
||||||
|
<field id="contragent.corr_account" group="customerContragent">corrAccount</field>
|
||||||
|
<field id="contragent.bank_account" group="customerContragent">bankAccount</field>
|
||||||
|
|
||||||
|
<field id="id" group="order">id</field>
|
||||||
|
<field id="created_at" group="order">createdAt</field>
|
||||||
|
<field id="order_type" group="order">orderType</field>
|
||||||
|
<field id="order_method" group="order">orderMethod</field>
|
||||||
|
<field id="site" group="order">site</field>
|
||||||
|
<field id="status" group="order">status</field>
|
||||||
|
<field id="manager" group="order">manager</field>
|
||||||
|
<field id="first_name" group="order">firstName</field>
|
||||||
|
<field id="last_name" group="order">lastName</field>
|
||||||
|
<field id="patronymic" group="order">patronymic</field>
|
||||||
|
<field id="phone" group="order">phone</field>
|
||||||
|
<field id="additional_phone" group="order">additionalPhone</field>
|
||||||
|
<field id="email" group="order">email</field>
|
||||||
|
<field id="payment_type" group="order">paymentType</field>
|
||||||
|
<field id="payment_status" group="order">paymentStatus</field>
|
||||||
|
<field id="payment_detail" group="order">paymentDetail</field>
|
||||||
|
<field id="discount" group="order">discount</field>
|
||||||
|
<field id="discount_percent" group="order">discountPercent</field>
|
||||||
|
<field id="prepay_sum" group="order">prepaySum</field>
|
||||||
|
<field id="customer_comment" group="order">customerComment</field>
|
||||||
|
<field id="manager_comment" group="order">managerComment</field>
|
||||||
|
<field id="shipment_store" group="order">shipmentStore</field>
|
||||||
|
<field id="shipment_date" group="order">shipmentDate</field>
|
||||||
|
<field id="shipped" group="order">shipped</field>
|
||||||
|
<!--<field id="order_product" group="order">item</field>-->
|
||||||
|
|
||||||
|
<field id="order_product.id" group="item">id</field>
|
||||||
|
<field id="order_product.initial_price" group="item">initialPrice</field>
|
||||||
|
<field id="order_product.discount" group="item">discount</field>
|
||||||
|
<field id="order_product.discount_percent" group="item">discountPercent</field>
|
||||||
|
<field id="order_product.quantity" group="item">quantity</field>
|
||||||
|
<field id="order_product.status" group="item">status</field>
|
||||||
|
|
||||||
|
<field id="delivery_type" group="delivery">code</field>
|
||||||
|
<field id="delivery_service" group="delivery">service</field>
|
||||||
|
<field id="delivery_date" group="delivery">date</field>
|
||||||
|
<field id="delivery_time" group="delivery">time</field>
|
||||||
|
<field id="delivery_cost" group="delivery">cost</field>
|
||||||
|
<field id="delivery_net_cost" group="delivery">netCost</field>
|
||||||
|
|
||||||
|
<field id="delivery_address.country" group="orderAddress">country</field>
|
||||||
|
<field id="delivery_address.index" group="orderAddress">index</field>
|
||||||
|
<field id="delivery_address.region" group="orderAddress">region</field>
|
||||||
|
<field id="delivery_address.city" group="orderAddress">city</field>
|
||||||
|
<field id="delivery_address.street" group="orderAddress">street</field>
|
||||||
|
<field id="delivery_address.building" group="orderAddress">building</field>
|
||||||
|
<field id="delivery_address.house" group="orderAddress">house</field>
|
||||||
|
<field id="delivery_address.block" group="orderAddress">block</field>
|
||||||
|
<field id="delivery_address.flat" group="orderAddress">flat</field>
|
||||||
|
<field id="delivery_address.floor" group="orderAddress">floor</field>
|
||||||
|
<field id="delivery_address.intercom_code" group="orderAddress">intercomCode</field>
|
||||||
|
<field id="delivery_address.metro" group="orderAddress">metro</field>
|
||||||
|
<field id="delivery_address.notes" group="orderAddress">notes</field>
|
||||||
|
|
||||||
|
<field id="integration_delivery_data.status" group="integrationDelivery">status</field>
|
||||||
|
<field id="integration_delivery_data.track_number" group="integrationDelivery">trackNumber</field>
|
||||||
|
<field id="integration_delivery_data.courier" group="integrationDelivery">courier</field>
|
||||||
|
</fields>
|
||||||
|
</options>
|
15
classes/modules/RetailCRM/events.php
Normal file
15
classes/modules/RetailCRM/events.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
global $argv;
|
||||||
|
|
||||||
|
if ((!isset($argv[2]) || $argv[2] == 'icml') && !isset($_GET['module']) || (isset($_GET['action']) && $_GET['action'] == 'icml')) {
|
||||||
|
new umiEventListener('cron', 'RetailCRM', 'onCronGenerateICML');
|
||||||
|
}
|
||||||
|
|
||||||
|
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');
|
||||||
|
?>
|
28
classes/modules/RetailCRM/i18n.php
Normal file
28
classes/modules/RetailCRM/i18n.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$i18n = Array(
|
||||||
|
'option-apiKey' => 'Ключ API',
|
||||||
|
'option-crmUrl' => 'Url RetailCRM API',
|
||||||
|
|
||||||
|
'module-RetailCRM' => 'RetailCRM',
|
||||||
|
'header-RetailCRM-manage' => 'Управление',
|
||||||
|
|
||||||
|
'group-access' => 'Настройка доступа',
|
||||||
|
'group-guidesMapping' => 'Справочники',
|
||||||
|
'group-orderStatusesMapping' => 'Статусы',
|
||||||
|
'group-orderPaymentsMapping' => 'Способы оплаты',
|
||||||
|
'group-orderPaymentStatusesMapping' => 'Статусы оплаты',
|
||||||
|
'group-orderDeliveryTypesMapping' => 'Способы доставки',
|
||||||
|
'group-incorrect-data' => 'Проверьте корректность заполненных полей',
|
||||||
|
|
||||||
|
'option-country' => 'Страны',
|
||||||
|
|
||||||
|
'notification-status-payment-initialized' => 'ожидает оплаты',
|
||||||
|
'notification-status-payment-accepted' => 'оплачен',
|
||||||
|
'notification-status-payment-validated' => 'обновлен: оплата подтверждена',
|
||||||
|
'notification-status-payment-declined' => 'обновлен: оплата отклонена',
|
||||||
|
|
||||||
|
'notification-status-delivery-waiting_shipping' => 'ожидает отгрузки',
|
||||||
|
'notification-status-delivery-shipping' => 'доставляется',
|
||||||
|
'notification-status-delivery-ready' => 'доставлен',
|
||||||
|
);
|
26
classes/modules/RetailCRM/install.php
Normal file
26
classes/modules/RetailCRM/install.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$INFO = array();
|
||||||
|
|
||||||
|
$INFO['name'] = "RetailCRM"; // Имя модуля (латинское), должно совпадать с именем папки модуля
|
||||||
|
$INFO['title'] = "RetailCRM";
|
||||||
|
$INFO['description'] = "RetailCRM integration module.";
|
||||||
|
$INFO['filename'] = "modules/RetailCRM/class.php"; // Путь до файла class.php
|
||||||
|
$INFO['config'] = "0"; // Если «1», то модуль будет настраиваемый, если «0», то нет
|
||||||
|
$INFO['ico'] = "ico_PrivateOffice"; // Базовое имя файла иконки модуля
|
||||||
|
//$INFO['default_method'] = "view"; // Метод (функция) вызываемая, по умолчанию для клиентской части
|
||||||
|
$INFO['default_method_admin'] = "manage"; // Метод (функция), вызываемая, по умолчанию для админки
|
||||||
|
|
||||||
|
$INFO['func_perms'] = ""; // Массив, определяющий группы прав нашего модуля (появятся в настройках пользователя и будут влиять на доступ к методам (функциям) модуля), ключи массива вносятся в реестр иерархически.
|
||||||
|
// В данном случае мы предусмотрим, что «пользователь» сможет «админить» модуль (даем доступ к методу manage), а также просматривать его страницы (даем доступ к методу view)
|
||||||
|
$INFO['func_perms/view'] = "Просмотр страниц модуля"; //Собственно объявляем права для «клиентского метода»
|
||||||
|
$INFO['func_perms/manage'] = "Администрирование модуля"; // И для «административной части»
|
||||||
|
|
||||||
|
$COMPONENTS[0] = "./classes/modules/RetailCRM/__admin.php";
|
||||||
|
$COMPONENTS[1] = "./classes/modules/RetailCRM/__events.php";
|
||||||
|
$COMPONENTS[2] = "./classes/modules/RetailCRM/events.php";
|
||||||
|
$COMPONENTS[3] = "./classes/modules/RetailCRM/classes/retailcrm/RCrmIcml.php";
|
||||||
|
$COMPONENTS[4] = "./classes/modules/RetailCRM/classes/retailcrm/RCrmApiClient.php";
|
||||||
|
$COMPONENTS[5] = "./classes/modules/RetailCRM/classes/retailcrm/RCrmHttpClient.php";
|
||||||
|
$COMPONENTS[6] = "./classes/modules/RetailCRM/classes/retailcrm/RCrmApiResponse.php";
|
||||||
|
$COMPONENTS[7] = "./classes/modules/RetailCRM/i18n.php";
|
BIN
images/cms/admin/mac/icons/big/RetailCRM.png
Normal file
BIN
images/cms/admin/mac/icons/big/RetailCRM.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
BIN
images/cms/admin/mac/icons/medium/RetailCRM.png
Normal file
BIN
images/cms/admin/mac/icons/medium/RetailCRM.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
BIN
images/cms/admin/mac/icons/small/RetailCRM.png
Normal file
BIN
images/cms/admin/mac/icons/small/RetailCRM.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
images/cms/admin/modern/icon/RetailCRM.png
Normal file
BIN
images/cms/admin/modern/icon/RetailCRM.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
Loading…
Reference in New Issue
Block a user