diff --git a/README.md b/README.md index c49f316a..6550f2bb 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,13 @@ Bitrix module ============= -Bitrix module for interaction with IntaroCRM through REST API. +Bitrix module for interaction with [IntaroCRM](http://www.intarocrm.com) through [REST API](http://docs.intarocrm.ru/rest-api/). Module allows: -* Send to IntaroCRM new orders and changes for old orders from Bitrix -* Load from IntaroCRM changes for old orders to Bitrix +* Send to IntaroCRM new orders * Configure relations between dictionaries of IntaroCRM and Bitrix (statuses, payments, delivery types and etc) -* Generate extended YML (YandexML) for catalog loading by IntaroCRM +* Generate [ICML](http://docs.intarocrm.ru/index.php?n=Пользователи.ФорматICML) (IntaroCRM Markup Language) for catalog loading by IntaroCRM Installation ------------- diff --git a/intaro.intarocrm/classes/general/ICrmOrderActions.php b/intaro.intarocrm/classes/general/ICrmOrderActions.php index 39e438f8..7fde6192 100755 --- a/intaro.intarocrm/classes/general/ICrmOrderActions.php +++ b/intaro.intarocrm/classes/general/ICrmOrderActions.php @@ -90,7 +90,7 @@ class ICrmOrderActions self::eventLog('ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::orderUpload', $api->getLastError()); if ($api->getStatusCode() != 460) // some orders were sent - return false; // in pack mode return errors + return true; } } @@ -120,9 +120,10 @@ class ICrmOrderActions if($api->getStatusCode() != 460) // some orders were sent return false; // in pack mode return errors - } - COption::SetOptionString(self::$MODULE_ID, self::$CRM_ORDER_LAST_ID, $lastOrderId); + if($lastOrderId) + COption::SetOptionString(self::$MODULE_ID, self::$CRM_ORDER_LAST_ID, $lastOrderId); + } return true; // end of pack } @@ -147,7 +148,7 @@ class ICrmOrderActions return true; //all ok! } - + /** * * w+ event in bitrix log @@ -193,6 +194,9 @@ class ICrmOrderActions $rsUser = CUser::GetByID($arFields['USER_ID']); $arUser = $rsUser->Fetch(); + + $createdAt = new \DateTime($arUser['DATE_REGISTER']); + $createdAt = $createdAt->format('Y-m-d H:i:s'); // push customer (for crm) $firstName = self::toJSON($arUser['NAME']); @@ -216,7 +220,8 @@ class ICrmOrderActions 'lastName' => $lastName, 'firstName' => $firstName, 'patronymic' => $patronymic, - 'phones' => $phones + 'phones' => $phones, + 'createdAt' => $createdAt )); $customer = $api->customerEdit($result); @@ -251,7 +256,7 @@ class ICrmOrderActions break; case 'ADDRESS': $resOrderDeliveryAddress['text'] = self::toJSON($ar['VALUE']); break; - case 'FIO': $resOrder['contactName'] = self::toJSON($ar['VALUE']); + case 'FIO': $resOrder['contactName'] = explode(" ", self::toJSON($ar['VALUE'])); break; case 'PHONE': $resOrder['phone'] = $ar['VALUE']; break; @@ -269,7 +274,10 @@ class ICrmOrderActions $pr = $pr['PURCHASING_PRICE']; else $pr = ''; - + + if($p['DISCOUNT_VALUE']) + $p['DISCOUNT_PRICE'] = null; + $items[] = array( 'initialPrice' => (double) $p['PRICE'] + (double) $p['DISCOUNT_PRICE'], 'purchasePrice' => $pr, @@ -284,12 +292,13 @@ class ICrmOrderActions if($arFields['CANCELED'] == 'Y') $arFields['STATUS_ID'] = $arFields['CANCELED']; - $createdAt = \datetime::createfromformat('Y-m-d H:i:s', $arFields['DATE_INSERT']); - if($createdAt) - $createdAt = $createdAt->format('d-m-Y H:i:s'); + $createdAt = new \DateTime($arFields['DATE_INSERT']); + $createdAt = $createdAt->format('Y-m-d H:i:s'); $resOrder = self::clearArr(array( - 'contactName' => $resOrder['contactName'], + 'firstName' => $resOrder['contactName'][0], + 'lastName' => $resOrder['contactName'][1], + 'patronymic' => $resOrder['contactName'][2], 'phone' => $resOrder['phone'], 'email' => $resOrder['email'], 'deliveryCost' => $arFields['PRICE_DELIVERY'], diff --git a/intaro.intarocrm/classes/general/RestApi.php b/intaro.intarocrm/classes/general/RestApi.php index 7e2711cb..c8f85181 100644 --- a/intaro.intarocrm/classes/general/RestApi.php +++ b/intaro.intarocrm/classes/general/RestApi.php @@ -6,7 +6,8 @@ class RestApi protected $apiUrl; protected $apiKey; protected $apiVersion = '1'; - protected $lastError; + + protected $response; protected $statusCode; protected $parameters; @@ -30,16 +31,23 @@ class RestApi /* Получение кода статуса и сообщения об ошибке */ public function getLastError() { - if (!is_null($this->lastError)) - return $this->statusCode . ' ' . $this->lastError; + if (isset($this->response['errorMsg']) && isset($this->response['errors'])) + { + $result = $this->statusCode . ' ' . $this->response['errorMsg']; + foreach ($this->response['errors'] as $error) + $result .= ' ' . $error; + } + elseif (isset($this->response['errorMsg'])) + $result = $this->statusCode . ' ' . $this->response['errorMsg']; else - return null; + $result = null; + return $result; } /* Псообщения об ошибке */ public function getLastErrorMessage() { - return $this->lastError; + return $this->response['errorMsg']; } @@ -94,7 +102,7 @@ class RestApi } /** - * Загрузка нескольких заказов + * Пакетная загрузка заказов * * @param array $orders - массив заказов * @return array @@ -106,6 +114,8 @@ class RestApi $url = $this->apiUrl.'orders/upload'; $result = $this->curlRequest($url, 'POST'); + if (is_null($result) && isset($result['uploadedOrders'])) + return $result['uploadedOrders']; return $result; } @@ -154,10 +164,8 @@ class RestApi public function orderHistory($startDate = null, $endDate = null, $limit = 100, $offset = 0) { $url = $this->apiUrl.'orders/history'; - if($startDate) - $this->parameters['startDate'] = $startDate; - if($endDate) - $this->parameters['endDate'] = $endDate; + $this->parameters['startDate'] = $startDate; + $this->parameters['endDate'] = $endDate; $this->parameters['limit'] = $limit; $this->parameters['offset'] = $offset; @@ -215,6 +223,26 @@ class RestApi return $result; } + /** + * Пакетная загрузка клиентов + * + * @param array $customers - массив клиентов + * @return array + */ + public function customerUpload($customers) + { + $dataJson = json_encode($customers); + $dataJson = str_replace(self::$jsonReplaceSource, self::$jsonReplaceTarget, + $dataJson); + $this->parameters['customers'] = $dataJson; + + $url = $this->apiUrl.'customers/upload'; + $result = $this->curlRequest($url, 'POST'); + if (is_null($result) && isset($result['uploaded'])) + return $result['uploaded']; + return $result; + } + /** * Удаление клиента * @@ -414,9 +442,18 @@ class RestApi $result = $this->curlRequest($url); return $result; } - - - + + /** + * Обновление статистики + * + * @return array - статус вып обновления + */ + public function statisticUpdate() + { + $url = $this->apiUrl.'statistic/update'; + $result = $this->curlRequest($url); + return $result; + } protected function curlRequest($url, $method = 'GET', $format = 'json') { @@ -444,22 +481,21 @@ class RestApi if (curl_errno($ch)) { - $this->lastError = 'Curl error: ' . curl_error($ch); + $this->response = array('errorMsg' => 'Curl error: ' . curl_error($ch)); return null; } curl_close($ch); $result = (array)json_decode($response, true); + $this->response = $result; if ($result['success'] == false) - { - $this->lastError = $result['errorMsg']; return null; - } - $this->lastError = null; unset($result['success']); if (count($result) == 0) return true; return reset($result); } -} \ No newline at end of file +} + +?> \ No newline at end of file diff --git a/intaro.intarocrm/install/export/intarocrm_setup.php b/intaro.intarocrm/install/export/intarocrm_setup.php index 003e9293..6679189a 100755 --- a/intaro.intarocrm/install/export/intarocrm_setup.php +++ b/intaro.intarocrm/install/export/intarocrm_setup.php @@ -124,7 +124,7 @@ if ($STEP==1) - " size="50"> + " size="50">

@@ -150,8 +150,8 @@ if ($STEP==1) - "> - + "> + "> diff --git a/intaro.intarocrm/install/index.php b/intaro.intarocrm/install/index.php index 76b802ca..dc5166e0 100755 --- a/intaro.intarocrm/install/index.php +++ b/intaro.intarocrm/install/index.php @@ -59,6 +59,7 @@ class intaro_intarocrm extends CModule global $APPLICATION, $step, $arResult; include($this->INSTALL_PATH . '/../classes/general/RestApi.php'); + include($this->INSTALL_PATH . '/../classes/general/ICrmOrderActions.php'); $step = intval($_REQUEST['step']); @@ -141,6 +142,7 @@ class intaro_intarocrm extends CModule $arResult['paymentTypesList'] = $this->INTARO_CRM_API->paymentTypesList(); $arResult['paymentStatusesList'] = $this->INTARO_CRM_API->paymentStatusesList(); // --statuses $arResult['paymentList'] = $this->INTARO_CRM_API->orderStatusesList(); + $arResult['paymentGroupList'] = $this->INTARO_CRM_API->orderStatusGroupsList(); // -- statuses groups //bitrix orderTypesList -- personTypes $dbOrderTypesList = CSalePersonType::GetList( @@ -233,9 +235,7 @@ class intaro_intarocrm extends CModule } if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') - && isset($_POST['ajax']) && ($_POST['ajax'] == 1)) { - include($this->INSTALL_PATH . '/../classes/general/ICrmOrderActions.php'); - + && isset($_POST['ajax']) && ($_POST['ajax'] == 1)) { ICrmOrderActions::uploadOrders(true); // each 50 $lastUpOrderId = COption::GetOptionString($this->MODULE_ID, $this->CRM_ORDER_LAST_ID, 0); @@ -249,8 +249,14 @@ class intaro_intarocrm extends CModule $percent = 100 - round(($countLeft * 100 / $countAll), 1); - if(!$countLeft) + if(!$countLeft) { + $api_host = COption::GetOptionString($mid, $this->CRM_API_HOST_OPTION, 0); + $api_key = COption::GetOptionString($mid, $this->CRM_API_KEY_OPTION, 0); + $this->INTARO_CRM_API = new \IntaroCrm\RestApi($api_host, $api_key); + $this->INTARO_CRM_API->statisticUpdate(); $finish = 1; + } + $APPLICATION->RestartBuffer(); header('Content-Type: application/x-javascript; charset='.LANG_CHARSET); @@ -359,25 +365,6 @@ class intaro_intarocrm extends CModule COption::SetOptionString($this->MODULE_ID, $this->CRM_PAYMENT_STATUSES, serialize($paymentStatusesArr)); COption::SetOptionString($this->MODULE_ID, $this->CRM_PAYMENT, serialize($paymentArr)); COption::SetOptionString($this->MODULE_ID, $this->CRM_ORDER_LAST_ID, 0); - /*RegisterModule($this->MODULE_ID); - - //agent - $dateAgent = new DateTime(); - $intAgent = new DateInterval('PT600S'); // PT60S - 60 sec; 600 - 600 sec - $dateAgent->add($intAgent); - - CAgent::AddAgent( - "ICrmOrderActions::uploadOrdersAgent();", - $this->MODULE_ID, - "N", - 600, // interval - 10 mins - $dateAgent->format('d.m.Y H:i:s'), // date of first check - "Y", // агент активен - $dateAgent->format('d.m.Y H:i:s'), // date of first start - 30 - ); - - $this->CopyFiles(); */ $APPLICATION->IncludeAdminFile( GetMessage('MODULE_INSTALL_TITLE'), @@ -445,7 +432,7 @@ class intaro_intarocrm extends CModule } function DeleteFiles() { - unlink($_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/include/catalog_export/crm_run.php'); - unlink($_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/include/catalog_export/crm_setup.php'); + unlink($_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/include/catalog_export/intarocrm_run.php'); + unlink($_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/include/catalog_export/intarocrm_setup.php'); } } \ No newline at end of file diff --git a/intaro.intarocrm/install/step2.php b/intaro.intarocrm/install/step2.php index 9fc1efd6..4be9c242 100755 --- a/intaro.intarocrm/install/step2.php +++ b/intaro.intarocrm/install/step2.php @@ -24,7 +24,7 @@ $defaultPayTypes = array ( ); $defaultPayStatuses = array ( - 'N' => 'in-processing', + 'N' => 'new', 'P' => 'approval', 'F' => 'complete', 'Y' => 'cancel-other' @@ -106,12 +106,16 @@ $defaultPayment = array( diff --git a/intaro.intarocrm/install/step3.php b/intaro.intarocrm/install/step3.php index d4b7ac47..5a5658fb 100755 --- a/intaro.intarocrm/install/step3.php +++ b/intaro.intarocrm/install/step3.php @@ -73,23 +73,31 @@ IncludeModuleLangFile(__FILE__); $(document).ready(function() { var globStop = false; + $('#percent').width($('.instal-progress-bar-outer').width()); + + $(window).resize(function(){ // strechin progress bar + $('#percent').width($('.instal-progress-bar-outer').width()); + }); + // orderUpload function function orderUpload(finish) { if(globStop) return false; if(finish == 1) { - $('#status').text(''); + $('#status').text(''); BX.closeWait(); $('input[name="inst"]').css('opacity', '1').removeAttr('disabled'); + $('input[name="stop"]').css('opacity', '0.5').attr('disabled', 'disabled'); + $('input[name="stop"]').attr('value', ''); return true; // exit from function, end recursion } var handlerUrl = $(this).parents('form').attr('action'); - var step = $('input[name="continue"]').val(); - var id = $('input[name="id"]').val(); - var install = $('input[name="install"]').val(); - var sessid = BX.bitrix_sessid(); + var step = $('input[name="continue"]').val(); + var id = $('input[name="id"]').val(); + var install = $('input[name="install"]').val(); + var sessid = BX.bitrix_sessid(); var data = 'install=' + install +'&step=' + step + '&sessid=' + sessid + '&id=' + id + '&ajax=1&finish=' + finish; @@ -107,6 +115,16 @@ IncludeModuleLangFile(__FILE__); orderUpload(response.finish); // wait until next response + }, + error: function () { + BX.closeWait(); + $('input[name="inst"]').css('opacity', '1').removeAttr('disabled'); + $('input[name="stop"]').attr('name', 'start'); + $('input[name="stop"]').attr('value', ''); + $('#status').text(''); + globStop = true; + + alert(''); } }); } diff --git a/intaro.intarocrm/install/version.php b/intaro.intarocrm/install/version.php index f1760bb4..14200c58 100755 --- a/intaro.intarocrm/install/version.php +++ b/intaro.intarocrm/install/version.php @@ -1,5 +1,5 @@ '0.3.5', - 'VERSION_DATE' => '2013-07-24 18:27:00', + 'VERSION' => '0.3.6', + 'VERSION_DATE' => '2013-07-29 12:29:00', ); diff --git a/intaro.intarocrm/lang/ru/install/step2.php b/intaro.intarocrm/lang/ru/install/step2.php index 691c1f45..cad51a52 100755 --- a/intaro.intarocrm/lang/ru/install/step2.php +++ b/intaro.intarocrm/lang/ru/install/step2.php @@ -7,7 +7,7 @@ $MESS ['PAYMENT_TYPES_LIST'] = 'Способы оплаты'; $MESS ['PAYMENT_STATUS_LIST'] = 'Статусы'; $MESS ['ORDER_TYPES_LIST'] = 'Типы заказа'; $MESS ['PAYMENT_LIST'] = 'Оплата'; -$MESS ['PAYMENT_Y'] = 'Флаг «Отменен»'; +$MESS ['PAYMENT_Y'] = 'Оплачен'; $MESS ['PAYMENT_N'] = 'Не оплачен'; -$MESS ['CANCELED'] = 'Отменен'; +$MESS ['CANCELED'] = 'Флаг «Отменен»'; $MESS ['INFO_1'] = ' Задайте соответствие между справочниками 1C-Битрикс и справочниками IntaroCRM.'; \ No newline at end of file diff --git a/intaro.intarocrm/lang/ru/install/step3.php b/intaro.intarocrm/lang/ru/install/step3.php index 624acc2c..ff5fc8fe 100755 --- a/intaro.intarocrm/lang/ru/install/step3.php +++ b/intaro.intarocrm/lang/ru/install/step3.php @@ -1,11 +1,12 @@ paymentTypesList(); $arResult['paymentStatusesList'] = $api->paymentStatusesList(); // --statuses $arResult['paymentList'] = $api->orderStatusesList(); + $arResult['paymentGroupList'] = $api->orderStatusGroupsList(); // -- statuses groups //check connection & apiKey valid if ((int) $api->getStatusCode() != 200) @@ -336,11 +337,15 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) {