diff --git a/CHANGELOG.md b/CHANGELOG.md index 76cafb77..0d100498 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## 2015-02-20 v.1.1.0 +* Модуль переведен на новую версию API +* Добавлена поддержка реквизитов юр. лиц +* Добавлена многосайтовость +* Добавлена выборочная загрузка заказов из настроек модуля +* Оптимизирована загрузка старых заказов +* Исправлена ошибка с удалением id товара в заказе +* Исправлена ошибка пустого $_SERVER['SERVER_NAME'] при экспорте каталога +* Исправлена ошибка с неправильной скидкой у товара при наличии копеек +* Исправлена ошибка с пропаданием автоматических служб доставок из настроек модуля +* Исправлена неправильная выгрузка сервисов для служб доставок +* Исправлено не правильное определение местоположения +* Рефакторинг модуля ## 2015-02-13 v.1.0.16 * Все действия агента происходят от имени retailcrm ## 2015-02-12 v.1.0.16 diff --git a/intaro.intarocrm/classes/general/Exception/ApiException.php b/intaro.intarocrm/classes/general/Exception/ApiException.php deleted file mode 100644 index 75e4d8d0..00000000 --- a/intaro.intarocrm/classes/general/Exception/ApiException.php +++ /dev/null @@ -1,6 +0,0 @@ -serverName . '/upload/' . $file['SUBDIR'] . '/' . $file['FILE_NAME'] ; } @@ -500,7 +501,7 @@ class ICMLLoader { } $offer .= "" . $this->PrepareValue($arOffer["PICTURE"]) . "\n"; - $offer .= "" . ($_SERVER["HTTPS"] == 'on' ? "https://" : "http://") . $_SERVER['SERVER_NAME'] . $this->PrepareValue($arOffer['DETAIL_PAGE_URL']) . "\n"; + $offer .= "" . ($_SERVER["HTTPS"] == 'on' ? "https://" : "http://") . $this->serverName . $this->PrepareValue($arOffer['DETAIL_PAGE_URL']) . "\n"; $offer .= "" . $this->PrepareValue($arOffer['PRICE']) . "\n"; if ($arOffer['PURCHASE_PRICE'] && $this->loadPurchasePrice) { diff --git a/intaro.intarocrm/classes/general/ICrmOrderActions.php b/intaro.intarocrm/classes/general/ICrmOrderActions.php old mode 100755 new mode 100644 index 6f9c4c9b..854555bc --- a/intaro.intarocrm/classes/general/ICrmOrderActions.php +++ b/intaro.intarocrm/classes/general/ICrmOrderActions.php @@ -11,13 +11,13 @@ class ICrmOrderActions protected static $CRM_PAYMENT_STATUSES = 'pay_statuses_arr'; protected static $CRM_PAYMENT = 'payment_arr'; //order payment Y/N protected static $CRM_ORDER_LAST_ID = 'order_last_id'; - protected static $CRM_ORDER_SITES = 'sites_ids'; + protected static $CRM_SITES_LIST = 'sites_list'; protected static $CRM_ORDER_PROPS = 'order_props'; + protected static $CRM_LEGAL_DETAILS = 'legal_details'; + protected static $CRM_CUSTOM_FIELDS = 'custom_fields'; + protected static $CRM_CONTRAGENT_TYPE = 'contragent_type'; protected static $CRM_ORDER_FAILED_IDS = 'order_failed_ids'; protected static $CRM_ORDER_HISTORY_DATE = 'order_history_date'; - protected static $CRM_MULTISHIP_INTEGRATION_CODE = 'multiship'; - protected static $MUTLISHIP_DELIVERY_TYPE = 'mlsp'; - protected static $MULTISHIP_MODULE_VER = 'multiship.v2'; const CANCEL_PROPERTY_CODE = 'INTAROCRM_IS_CANCELED'; @@ -27,24 +27,17 @@ class ICrmOrderActions * @param $failed -- flag to export failed orders * @return boolean */ - public static function uploadOrders($pSize = 50, $failed = false) { - - // COption::SetOptionString(self::$MODULE_ID, self::$CRM_ORDER_LAST_ID, 0); // -- for test + public static function uploadOrders($pSize = 50, $failed = false, $orderList = false) { if (!CModule::IncludeModule("iblock")) { - //handle err self::eventLog('ICrmOrderActions::uploadOrders', 'iblock', 'module not found'); return true; } - if (!CModule::IncludeModule("sale")) { - //handle err self::eventLog('ICrmOrderActions::uploadOrders', 'sale', 'module not found'); return true; } - if (!CModule::IncludeModule("catalog")) { - //handle err self::eventLog('ICrmOrderActions::uploadOrders', 'catalog', 'module not found'); return true; } @@ -53,300 +46,274 @@ class ICrmOrderActions $resCustomers = array(); $lastUpOrderId = COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_LAST_ID, 0); - $lastOrderId = 0; - $failedIds = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_FAILED_IDS, 0)); - if (!$failedIds) - $failedIds = array(); - $dbOrder = CSaleOrder::GetList(array("ID" => "ASC"), array('>ID' => $lastUpOrderId)); - $dbFailedOrder = CSaleOrder::GetList(array("ID" => "ASC"), array('ID' => $failedIds)); + $arFilter = array(); + $arCount = false; + if ($failed == true && $failedIds !== false && count($failedIds) > 0) { + $arFilter['ID'] = $failedIds; + } elseif ($orderList !== false && count($orderList) > 0) { + $arFilter['ID'] = $orderList; + } else { + $arFilter['>ID'] = $lastUpOrderId; + $arCount['nTopCount'] = $pSize; + } + + if ( (isset($arFilter['ID']) && count($arFilter['ID']) > 0) || isset($arFilter['>ID']) ) { + $dbOrder = CSaleOrder::GetList(array("ID" => "ASC"), $arFilter, false, $arCount); + if ($dbOrder->SelectedRowsCount() <= 0) { + return false; + } + } else { + return false; + } $api_host = COption::GetOptionString(self::$MODULE_ID, self::$CRM_API_HOST_OPTION, 0); $api_key = COption::GetOptionString(self::$MODULE_ID, self::$CRM_API_KEY_OPTION, 0); - //saved cat params + $optionsSitesList = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_SITES_LIST, 0)); $optionsOrderTypes = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_TYPES_ARR, 0)); $optionsDelivTypes = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_DELIVERY_TYPES_ARR, 0)); $optionsPayTypes = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PAYMENT_TYPES, 0)); $optionsPayStatuses = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PAYMENT_STATUSES, 0)); // --statuses $optionsPayment = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PAYMENT, 0)); - $optionsSites = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_SITES, 0)); $optionsOrderProps = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_PROPS, 0)); + $optionsLegalDetails = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_LEGAL_DETAILS, 0)); + $optionsContragentType = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_CONTRAGENT_TYPE, 0)); + $optionsCustomFields = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_CUSTOM_FIELDS, 0)); - $api = new IntaroCrm\RestApi($api_host, $api_key); + $api = new RetailCrm\RestApi($api_host, $api_key); $arParams = array( - 'optionsOrderTypes' => $optionsOrderTypes, - 'optionsDelivTypes' => $optionsDelivTypes, - 'optionsPayTypes' => $optionsPayTypes, - 'optionsPayStatuses' => $optionsPayStatuses, - 'optionsPayment' => $optionsPayment, - 'optionSites' => $optionsSites, - 'optionsOrderProps' => $optionsOrderProps + 'optionsOrderTypes' => $optionsOrderTypes, + 'optionsDelivTypes' => $optionsDelivTypes, + 'optionsPayTypes' => $optionsPayTypes, + 'optionsPayStatuses' => $optionsPayStatuses, + 'optionsPayment' => $optionsPayment, + 'optionsOrderProps' => $optionsOrderProps, + 'optionsLegalDetails' => $optionsLegalDetails, + 'optionsContragentType' => $optionsContragentType, + 'optionsSitesList' => $optionsSitesList , + 'optionsCustomFields' => $optionsCustomFields, ); - if (!$failed) { - - //packmode - - $orderCount = 0; - - while ($arOrder = $dbOrder->GetNext()) { // here orders by id asc - if (is_array($optionsSites)) - if (!empty($optionsSites)) - if (!in_array($arOrder['LID'], $optionsSites)) - continue; - - $result = self::orderCreate($arOrder, $api, $arParams); - - if (!$result['order'] || !$result['customer']) - continue; - - $orderCount++; - - $resOrders[] = $result['order']; - $resCustomers[] = $result['customer']; - - $lastOrderId = $arOrder['ID']; - - if ($orderCount >= $pSize) { - - try { - $customers = $api->customerUpload($resCustomers); - } catch (\IntaroCrm\Exception\ApiException $e) { - self::eventLog( - 'ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::customerUpload', - $e->getCode() . ': ' . $e->getMessage() - ); - - if($e->getCode() != 201) - if($e->getCode() != 460) - return false; - } catch (\IntaroCrm\Exception\CurlException $e) { - self::eventLog( - 'ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::customerUpload::CurlException', - $e->getCode() . ': ' . $e->getMessage() - ); - - return false; - } - - try { - $orders = $api->orderUpload($resOrders); - } catch (\IntaroCrm\Exception\ApiException $e) { - self::eventLog( - 'ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::orderUpload', - $e->getCode() . ': ' . $e->getMessage() - ); - - if($e->getCode() != 201) - if($e->getCode() != 460) - return false; - } catch (\IntaroCrm\Exception\CurlException $e) { - self::eventLog( - 'ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::orderUpload::CurlException', - $e->getCode() . ': ' . $e->getMessage() - ); - - return false; - } - - if ($lastOrderId) - COption::SetOptionString(self::$MODULE_ID, self::$CRM_ORDER_LAST_ID, $lastOrderId); - - return true; // end of pack - } - } - if (!empty($resOrders)) { - try { - $customers = $api->customerUpload($resCustomers); - } catch (\IntaroCrm\Exception\ApiException $e) { - self::eventLog( - 'ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::customerUpload', - $e->getCode() . ': ' . $e->getMessage() - ); - - if($e->getCode() != 201) - if($e->getCode() != 460) - return false; - } catch (\IntaroCrm\Exception\CurlException $e) { - self::eventLog( - 'ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::customerUpload::CurlException', - $e->getCode() . ': ' . $e->getMessage() - ); - - return false; - } - - try { - $orders = $api->orderUpload($resOrders); - } catch (\IntaroCrm\Exception\ApiException $e) { - self::eventLog( - 'ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::orderUpload', - $e->getCode() . ': ' . $e->getMessage() - ); - - if($e->getCode() != 201) - if($e->getCode() != 460) - return false; - } catch (\IntaroCrm\Exception\CurlException $e) { - self::eventLog( - 'ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::orderUpload::CurlException', - $e->getCode() . ': ' . $e->getMessage() - ); - - return false; - } + $recOrders = array(); + while ($arOrder = $dbOrder->GetNext()) { + $result = self::orderCreate($arOrder, $api, $arParams); + if (!$result['order'] || !$result['customer']){ + continue; } - if ($lastOrderId) - COption::SetOptionString(self::$MODULE_ID, self::$CRM_ORDER_LAST_ID, $lastOrderId); - - } else { - - // failed orders upload - $orderCount = 0; - $recOrders = array(); - - while ($arOrder = $dbFailedOrder->GetNext()) { // here orders by id asc - if (is_array($optionsSites)) - if (!empty($optionsSites)) - if (!in_array($arOrder['LID'], $optionsSites)) - continue; - - $result = self::orderCreate($arOrder, $api, $arParams); - - if (!$result['order'] || !$result['customer']) - continue; - - $orderCount++; - - $resOrders[] = $result['order']; - $resCustomers[] = $result['customer']; - - $recOrders[] = $arOrder['ID']; - - if ($orderCount >= $pSize) { - try { - $customers = $api->customerUpload($resCustomers); - } catch (\IntaroCrm\Exception\ApiException $e) { - self::eventLog( - 'ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::customerUpload', - $e->getCode() . ': ' . $e->getMessage() - ); - - if($e->getCode() != 201) - if($e->getCode() != 460) - return false; - } catch (\IntaroCrm\Exception\CurlException $e) { - self::eventLog( - 'ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::customerUpload::CurlException', - $e->getCode() . ': ' . $e->getMessage() - ); - - return false; - } - - try { - $orders = $api->orderUpload($resOrders); - } catch (\IntaroCrm\Exception\ApiException $e) { - self::eventLog( - 'ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::orderUpload', - $e->getCode() . ': ' . $e->getMessage() - ); - - if($e->getCode() != 201) - if($e->getCode() != 460) - return false; - } catch (\IntaroCrm\Exception\CurlException $e) { - self::eventLog( - 'ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::orderUpload::CurlException', - $e->getCode() . ': ' . $e->getMessage() - ); - - return false; - } - - if (!empty($recOrders)) { - $failedIds = array_merge(array_diff($failedIds, $recOrders)); // clear success ids - COption::SetOptionString(self::$MODULE_ID, self::$CRM_ORDER_FAILED_IDS, serialize($failedIds)); - } - - return true; // end of pack - } - } - if (!empty($resOrders)) { - try { - $customers = $api->customerUpload($resCustomers); - } catch (\IntaroCrm\Exception\ApiException $e) { - self::eventLog( - 'ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::customerUpload', - $e->getCode() . ': ' . $e->getMessage() - ); - - if($e->getCode() != 201) - if($e->getCode() != 460) - return false; - } catch (\IntaroCrm\Exception\CurlException $e) { - self::eventLog( - 'ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::customerUpload::CurlException', - $e->getCode() . ': ' . $e->getMessage() - ); + $resOrders[$arOrder['LID']][] = $result['order']; + $resCustomers[$arOrder['LID']][] = $result['customer']; + $recOrders[] = $arOrder['ID']; + } + if(count($resOrders) > 0){ + foreach($resCustomers as $key => $customerLoad){ + $site = count($optionsSitesList) > 1 ? $optionsSitesList[$key] : null; + if (self::apiMethod($api, 'customerUpload', __METHOD__, $customerLoad, $site) === false) { return false; } - - try { - $orders = $api->orderUpload($resOrders); - } catch (\IntaroCrm\Exception\ApiException $e) { - self::eventLog( - 'ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::orderUpload', - $e->getCode() . ': ' . $e->getMessage() - ); - - if($e->getCode() != 201) - if($e->getCode() != 460) - return false; - } catch (\IntaroCrm\Exception\CurlException $e) { - self::eventLog( - 'ICrmOrderActions::uploadOrders', 'IntaroCrm\RestApi::orderUpload::CurlException', - $e->getCode() . ': ' . $e->getMessage() - ); - - return false; + if (count($optionsSitesList) > 1) { + time_nanosleep(0, 250000000); } } - - if (!empty($recOrders)) { - $failedIds = array_merge(array_diff($failedIds, $recOrders)); // clear success ids - COption::SetOptionString(self::$MODULE_ID, self::$CRM_ORDER_FAILED_IDS, serialize($failedIds)); + foreach($resOrders as $key => $orderLoad){ + $site = count($optionsSitesList) > 1 ? $optionsSitesList[$key] : null; + if (self::apiMethod($api, 'orderUpload', __METHOD__, $orderLoad, $site) === false) { + return false; + } + if (count($optionsSitesList) > 1) { + time_nanosleep(0, 250000000); + } + } + if ($failed == true && $failedIds !== false && count($failedIds) > 0) { + COption::SetOptionString(self::$MODULE_ID, self::$CRM_ORDER_FAILED_IDS, serialize(array_diff($failedIds, $recOrders))); + } elseif ($lastUpOrderId < max($recOrders) && $orderList === false) { + COption::SetOptionString(self::$MODULE_ID, self::$CRM_ORDER_LAST_ID, max($recOrders)); } } - return true; //all ok! + return true; } - protected static function updateCancelProp($arProduct, $value) { - $propUpdated = false; - foreach($arProduct['PROPS'] as $key => $item) { - if ($item['CODE'] == self::CANCEL_PROPERTY_CODE) { - $arProduct['PROPS'][$key]['VALUE'] = $value; - $propUpdated = true; - break; + /** + * + * Creates order or returns array of order and customer for mass upload + * + * @param array $arFields + * @param $api + * @param $arParams + * @param $send + * @return boolean + * @return array - array('order' = $order, 'customer' => $customer) + */ + public static function orderCreate($arFields, $api, $arParams, $send = false, $site = null) { + if(!$api || empty($arParams)) { // add cond to check $arParams + return false; + } + if (empty($arFields)) { + self::eventLog('ICrmOrderActions::orderCreate', 'empty($arFields)', 'incorrect order'); + return false; + } + + if (isset($arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']]['city']) == false) { + $rsOrderProps = CSaleOrderPropsValue::GetList(array(), array('ORDER_ID' => $arFields['ID'], 'CODE' => 'LOCATION')); + $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']]['city'] = $rsOrderProps->SelectedRowsCount() < 1 ? 'CITY' : 'LOCATION'; + } + + $normalizer = new RestNormalizer(); + $normalizer->setValidation(__DIR__ . '/config/retailcrm.json'); + + $customer = array(); + + if ($arFields['CANCELED'] == 'Y') { + $arFields['STATUS_ID'] = $arFields['CANCELED'].$arFields['CANCELED']; + } + + $order = array( + 'number' => $arFields['ACCOUNT_NUMBER'], + 'externalId' => $arFields['ID'], + 'createdAt' => new \DateTime($arFields['DATE_INSERT']), + 'customerId' => $arFields['USER_ID'], + 'discount' => $arFields['DISCOUNT_VALUE'], + 'markDateTime' => $arFields['DATE_MARKED'], + 'paymentType' => isset($arParams['optionsPayTypes'][$arFields['PAY_SYSTEM_ID']]) ? + $arParams['optionsPayTypes'][$arFields['PAY_SYSTEM_ID']] : '', + 'paymentStatus' => isset($arParams['optionsPayment'][$arFields['PAYED']]) ? + $arParams['optionsPayment'][$arFields['PAYED']] : '', + 'orderType' => isset($arParams['optionsOrderTypes'][$arFields['PERSON_TYPE_ID']]) ? + $arParams['optionsOrderTypes'][$arFields['PERSON_TYPE_ID']] : '', + 'contragentType' => isset($arParams['optionsContragentType'][$arFields['PERSON_TYPE_ID']]) ? + $arParams['optionsContragentType'][$arFields['PERSON_TYPE_ID']] : '', + 'status' => isset($arParams['optionsPayStatuses'][$arFields['STATUS_ID']]) ? + $arParams['optionsPayStatuses'][$arFields['STATUS_ID']] : '', + 'statusComment' => $arFields['REASON_CANCELED'], + 'customerComment' => $arFields['USER_DESCRIPTION'], + 'managerComment' => $arFields['COMMENTS'], + 'delivery' => array( + 'cost' => $arFields['PRICE_DELIVERY'] + ), + ); + + $rsOrderProps = CSaleOrderPropsValue::GetList(array(), array('ORDER_ID' => $arFields['ID'])); + while ($ar = $rsOrderProps->Fetch()) { + if ($search = array_search($ar['CODE'], $arParams['optionsLegalDetails'][$arFields['PERSON_TYPE_ID']])) { + $order[$search] = $ar['VALUE']; + $customer[$search] = $ar['VALUE']; + } elseif ($search = array_search($ar['CODE'], $arParams['optionsCustomFields'][$arFields['PERSON_TYPE_ID']])) { + $order['customFields'][$search] = $ar['VALUE']; + } elseif ($search = array_search($ar['CODE'], $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']])) { + if (in_array($search, array('fio', 'phone', 'email'))) { + if ($search == 'fio') { + $order = array_merge($order, self::explodeFIO($ar['VALUE'])); + } else { + $order[$search] = $ar['VALUE']; + } + } else { + $prop = CSaleOrderProps::GetByID($ar['ORDER_PROPS_ID']); + if ($prop['TYPE'] == 'LOCATION') { + $ar['VALUE'] = CSaleLocation::GetByID( + method_exists('CSaleLocation', 'getLocationIDbyCODE') ? + CSaleLocation::getLocationIDbyCODE($ar['VALUE']) : $ar['VALUE'] + ); + $ar['VALUE'] = $ar['VALUE']['CITY_NAME_LANG']; + } + + $order['delivery']['address'][$search] = $ar['VALUE']; + } + } + } + if (strpos($arFields['DELIVERY_ID'], ":") !== false){ + $arFields["DELIVERY_ID"] = explode(":", $arFields["DELIVERY_ID"], 2); + if ($arDeliveryType = CSaleDeliveryHandler::GetBySID(reset($arFields["DELIVERY_ID"]))->GetNext()) { + if (array_key_exists(end($arFields["DELIVERY_ID"]), $arDeliveryType['PROFILES'])) { + $arFields["DELIVERY_SERVICE"] = array( + 'code' => implode('-', $arFields["DELIVERY_ID"]), + 'name' => $arDeliveryType['PROFILES'][end($arFields["DELIVERY_ID"])]['TITLE'] + ); + } + } + $arFields["DELIVERY_ID"] = reset($arFields["DELIVERY_ID"]); + } + + if (array_key_exists($arFields['DELIVERY_ID'], $arParams['optionsDelivTypes'])) { + $order['delivery']['code'] = $arParams['optionsDelivTypes'][$arFields["DELIVERY_ID"]]; + if (isset($arFields["DELIVERY_SERVICE"])) { + $order['delivery']['service'] = $arFields["DELIVERY_SERVICE"]; } } - if (!$propUpdated) { - $arProduct['PROPS'][] = array( - 'NAME' => GetMessage('PRODUCT_CANCEL'), - 'CODE' => self::CANCEL_PROPERTY_CODE, - 'VALUE' => $value, - 'SORT' => 10, + $rsOrderBasket = CSaleBasket::GetList(array('ID' => 'ASC'), array('ORDER_ID' => $arFields['ID'])); + while ($p = $rsOrderBasket->Fetch()) { + $item = array( + 'quantity' => $p['QUANTITY'], + 'productId' => $p['PRODUCT_ID'], + 'productName' => $p['NAME'], + 'comment' => $p['NOTES'], + 'discount' => $p['DISCOUNT_PRICE'] ); + + $propCancel = CSaleBasket::GetPropsList(array(), array('BASKET_ID' => $p['ID'], 'CODE' => self::CANCEL_PROPERTY_CODE))->Fetch(); + if ($propCancel && !(int)$propCancel['VALUE']) { + $item['initialPrice'] = (double) $p['PRICE'] + (double) $p['DISCOUNT_PRICE']; + } + + $order['items'][] = $item; } - return $arProduct; + $arUser = CUser::GetByID($arFields['USER_ID'])->Fetch(); + + $customer = array( + 'externalId' => $arFields['USER_ID'], + 'lastName' => $arUser['LAST_NAME'], + 'firstName' => $arUser['NAME'], + 'patronymic' => $arUser['SECOND_NAME'], + 'phones' => array( + array('number' => $arUser['PERSONAL_PHONE']), + array('number' => $arUser['WORK_PHONE']) + ), + 'createdAt' => new \DateTime($arUser['DATE_REGISTER']), + 'contragentType' => $arParams['optionsContragentType'][$arFields['PERSON_TYPE_ID']] + ); + + if(function_exists('intarocrm_get_order_type')) { + $orderType = intarocrm_get_order_type($arFields); + if ($orderType) { + $order['orderType'] = $orderType; + } + } + if (function_exists('intarocrm_before_order_send')) { + $newResOrder = intarocrm_before_order_send($resOrder); + if (is_array($newResOrder) && !empty($newResOrder)) { + $resOrder = $newResOrder; + } + } + + $customer = $normalizer->normalize($customer, 'customers'); + $order = $normalizer->normalize($order, 'orders'); + $site = null; + if (isset($arParams['optionsSitesList']) && is_array($arParams['optionsSitesList']) && + array_key_exists($arFields['LID'], $arParams['optionsSitesList'])) { + $site = $arParams['optionsSitesList'][$arFields['LID']]; + } + + if($send) { + if (!self::apiMethod($api, 'customerEdit', __METHOD__, $customer, $site)) { + return false; + } + if ($orderEdit = self::apiMethod($api, 'orderEdit', __METHOD__, $order, $site)) { + return $orderEdit; + } else { + return false; + } + } + + return array( + 'order' => $order, + 'customer' => $customer + ); } /** @@ -363,97 +330,84 @@ class ICrmOrderActions if (!CModule::IncludeModule("iblock")) { self::eventLog('ICrmOrderActions::orderHistory', 'iblock', 'module not found'); - return true; + return false; } - if (!CModule::IncludeModule("sale")) { self::eventLog('ICrmOrderActions::orderHistory', 'sale', 'module not found'); - return true; + return false; } - if (!CModule::IncludeModule("catalog")) { self::eventLog('ICrmOrderActions::orderHistory', 'catalog', 'module not found'); - return true; + return false; } - $defaultSiteId = 0; - $rsSites = CSite::GetList($by, $sort, array('DEF' => 'Y')); - while ($ar = $rsSites->Fetch()) { - $defaultSiteId = $ar['LID']; - break; - } - $api_host = COption::GetOptionString(self::$MODULE_ID, self::$CRM_API_HOST_OPTION, 0); $api_key = COption::GetOptionString(self::$MODULE_ID, self::$CRM_API_KEY_OPTION, 0); - //saved cat params (crm -> bitrix) $optionsOrderTypes = array_flip(unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_TYPES_ARR, 0))); $optionsDelivTypes = array_flip(unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_DELIVERY_TYPES_ARR, 0))); $optionsPayTypes = array_flip(unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PAYMENT_TYPES, 0))); $optionsPayStatuses = array_flip(unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PAYMENT_STATUSES, 0))); // --statuses $optionsPayment = array_flip(unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PAYMENT, 0))); - $optionsSites = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_SITES, 0)); $optionsOrderProps = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_PROPS, 0)); + $optionsLegalDetails = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_LEGAL_DETAILS, 0)); + $optionsContragentType = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_CONTRAGENT_TYPE, 0)); + $optionsSitesList = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_SITES_LIST, 0)); + $optionsCustomFields = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_CUSTOM_FIELDS, 0)); - $api = new IntaroCrm\RestApi($api_host, $api_key); + foreach ($optionsOrderProps as $code => $value) { + if (isset($optionsLegalDetails[$code])) { + $optionsOrderProps[$code] = array_merge($optionsOrderProps[$code], $optionsLegalDetails[$code]); + } + if (isset($optionsCustomFields[$code])) { + $optionsOrderProps[$code] = array_merge($optionsOrderProps[$code], $optionsCustomFields[$code]); + } + $optionsOrderProps[$code]['location'] = 'LOCATION'; + if (array_search('CITY', $optionsOrderProps[$code]) == false) { + $optionsOrderProps[$code]['city'] = 'CITY'; + } + if (array_search('ZIP', $optionsOrderProps[$code]) == false) { + $optionsOrderProps[$code]['index'] = 'ZIP'; + } + } + + $api = new RetailCrm\RestApi($api_host, $api_key); $dateStart = COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_HISTORY_DATE, null); - if(!$dateStart) { + if (is_null($dateStart)) { $dateStart = new \DateTime(); $dateStart = $dateStart->format('Y-m-d H:i:s'); } try { $orderHistory = $api->orderHistory($dateStart); - } catch (\IntaroCrm\Exception\ApiException $e) { + } catch (\RetailCrm\Exception\CurlException $e) { self::eventLog( - 'ICrmOrderActions::orderHistory', 'IntaroCrm\RestApi::orderHistory', + 'ICrmOrderActions::orderHistory', 'RetailCrm\RestApi::orderHistory::CurlException', $e->getCode() . ': ' . $e->getMessage() ); - return true; - } catch (\IntaroCrm\Exception\CurlException $e) { - self::eventLog( - 'ICrmOrderActions::orderHistory', 'IntaroCrm\RestApi::orderHistory::CurlException', - $e->getCode() . ': ' . $e->getMessage() - ); - - return true; + return false; } + $orderHistory = isset($orderHistory->orders) ? $orderHistory->orders : array(); + $dateFinish = $api->getGeneratedAt(); - - // default orderType - $defaultOrderType = 1; - - // if it not a ph. entity - $dbOrderTypesList = CSalePersonType::GetList( - array( - "SORT" => "ASC", - "NAME" => "ASC" - ), - array( - "ACTIVE" => "Y", - ), - false, - false, - array() - ); - - if ($arOrderTypesList = $dbOrderTypesList->Fetch()) - $defaultOrderType = $arOrderTypesList['ID']; - - // apiv3 ! - if (!$dateFinish) { + if (is_null($dateFinish) || $dateFinish == false) { $dateFinish = new \DateTime(); } + $defaultOrderType = 1; + $dbOrderTypesList = CSalePersonType::GetList(array(), array("ACTIVE" => "Y")); + if ($arOrderTypesList = $dbOrderTypesList->Fetch()) { + $defaultOrderType = $arOrderTypesList['ID']; + } + $GLOBALS['INTARO_CRM_FROM_HISTORY'] = true; - // pushing existing orders foreach ($orderHistory as $order) { - if(function_exists('intarocrm_order_pre_persist')) { + if (function_exists('intarocrm_order_pre_persist')) { $order = intarocrm_order_pre_persist($order); } @@ -492,6 +446,7 @@ class ICrmOrderActions break; default: $login = uniqid('user_' . time()) . '@crm.com'; + break; } } @@ -509,9 +464,7 @@ class ICrmOrderActions "PASSWORD" => $userPassword, "CONFIRM_PASSWORD" => $userPassword ); - $registeredUserID = $newUser->Add($arFields); - if ($registeredUserID === false) { self::eventLog('ICrmOrderActions::orderHistory', 'CUser::Register', 'Error register user'); continue; @@ -519,16 +472,9 @@ class ICrmOrderActions try { $api->customerFixExternalIds(array(array('id' => $order['customer']['id'], 'externalId' => $registeredUserID))); - } catch (\IntaroCrm\Exception\ApiException $e) { + } catch (\RetailCrm\Exception\CurlException $e) { self::eventLog( - 'ICrmOrderActions::orderHistory', 'IntaroCrm\RestApi::customerFixExternalIds', - $e->getCode() . ': ' . $e->getMessage() - ); - - continue; - } catch (\IntaroCrm\Exception\CurlException $e) { - self::eventLog( - 'ICrmOrderActions::orderHistory', 'IntaroCrm\RestApi::customerFixExternalIds::CurlException', + 'ICrmOrderActions::orderHistory', 'RetailCrm\RestApi::customerFixExternalIds::CurlException', $e->getCode() . ': ' . $e->getMessage() ); @@ -541,8 +487,8 @@ class ICrmOrderActions // new order $newOrderFields = array( - 'LID' => $defaultSiteId, - 'PERSON_TYPE_ID' => ($optionsOrderTypes[$order['orderType']]) ? $optionsOrderTypes[$order['orderType']] : $defaultOrderType, + 'LID' => CSite::GetDefSite(), + 'PERSON_TYPE_ID' => isset($optionsOrderTypes[$order['orderType']]) ? $optionsOrderTypes[$order['orderType']] : $defaultOrderType, 'PAYED' => 'N', 'CANCELED' => 'N', 'STATUS_ID' => 'N', @@ -556,20 +502,18 @@ class ICrmOrderActions 'USER_DESCRIPTION' => '' ); + if(count($optionsSitesList) > 1 && $lid = array_search($order['site'], $optionsSitesList)){ + $newOrderFields['LID'] = $lid; + } + $externalId = CSaleOrder::Add($newOrderFields); + if (!isset($order['externalId'])) { try { $api->orderFixExternalIds(array(array('id' => $order['id'], 'externalId' => $externalId))); - } catch (\IntaroCrm\Exception\ApiException $e) { + } catch (\RetailCrm\Exception\CurlException $e) { self::eventLog( - 'ICrmOrderActions::orderHistory', 'IntaroCrm\RestApi::orderFixExternalIds', - $e->getCode() . ': ' . $e->getMessage() - ); - - continue; - } catch (\IntaroCrm\Exception\CurlException $e) { - self::eventLog( - 'ICrmOrderActions::orderHistory', 'IntaroCrm\RestApi::orderFixExternalIds::CurlException', + 'ICrmOrderActions::orderHistory', 'RetailCrm\RestApi::orderFixExternalIds::CurlException', $e->getCode() . ': ' . $e->getMessage() ); @@ -606,238 +550,93 @@ class ICrmOrderActions } $rsOrderProps = CSaleOrderPropsValue::GetList(array(), array('ORDER_ID' => $arFields['ID'])); - + $arUpdateProps = array(); while ($ar = $rsOrderProps->Fetch()) { - if (isset($order['delivery']) && isset($order['delivery']['address']) && $order['delivery']['address']) { - switch ($ar['CODE']) { - case $optionsOrderProps[$arFields['PERSON_TYPE_ID']]['index']: - if (isset($order['delivery']['address']['index'])) { - CSaleOrderPropsValue::Update($ar['ID'], array('VALUE' => self::fromJSON($order['delivery']['address']['index']))); - } - break; - case ($ar['CODE'] == 'CITY') || ($ar['CODE'] == 'LOCATION'): - if (isset($order['delivery']['address']['city'])) { - $prop = CSaleOrderProps::GetByID($ar['ORDER_PROPS_ID']); + $prop = CSaleOrderProps::GetByID($ar['ORDER_PROPS_ID']); + $arUpdateProps[ $ar['CODE'] ] = array('ID' => $ar['ID'], 'TYPE' => $prop['TYPE'], 'VALUE' => $ar['VALUE']); + } - if($prop['TYPE'] == 'LOCATION') { - $cityId = self::getLocationCityId(self::fromJSON($order['delivery']['address']['city'])); - if (!$cityId) { - break; - } + $order['fio'] = trim( + implode( + ' ', + array( + isset($order['lastName']) ? $order['lastName'] : '', + isset($order['firstName']) ? $order['firstName'] : '', + isset($order['patronymic']) ? $order['patronymic'] : '', + ) + ) + ); - CSaleOrderPropsValue::Update($ar['ID'], array('VALUE' => $cityId)); - break; - } + if (isset($order['delivery']['address']['city'])) { + $order['location'] = $order['delivery']['address']['city']; + } - CSaleOrderPropsValue::Update($ar['ID'], array('VALUE' => self::fromJSON($order['delivery']['address']['city']))); - } - break; - case $optionsOrderProps[$arFields['PERSON_TYPE_ID']]['text']: - if (isset($order['delivery']['address']['text'])) { - CSaleOrderPropsValue::Update($ar['ID'], array('VALUE' => self::fromJSON($order['delivery']['address']['text']))); - } - break; - } - - if (count($optionsOrderProps[$arFields['PERSON_TYPE_ID']]) > 4) { - switch ($ar['CODE']) { - case $optionsOrderProps[$arFields['PERSON_TYPE_ID']]['street']: if (isset($order['delivery']['address']['street'])) - CSaleOrderPropsValue::Update($ar['ID'], array('VALUE' => self::fromJSON($order['delivery']['address']['street']))); - break; - case $optionsOrderProps[$arFields['PERSON_TYPE_ID']]['building']: if (isset($order['delivery']['address']['building'])) - CSaleOrderPropsValue::Update($ar['ID'], array('VALUE' => self::fromJSON($order['delivery']['address']['building']))); - break; - case $optionsOrderProps[$arFields['PERSON_TYPE_ID']]['flat']: if (isset($order['delivery']['address']['flat'])) - CSaleOrderPropsValue::Update($ar['ID'], array('VALUE' => self::fromJSON($order['delivery']['address']['flat']))); - break; - case $optionsOrderProps[$arFields['PERSON_TYPE_ID']]['intercomcode']: if (isset($order['delivery']['address']['intercomcode'])) - CSaleOrderPropsValue::Update($ar['ID'], array('VALUE' => self::fromJSON($order['delivery']['address']['intercomcode']))); - break; - case $optionsOrderProps[$arFields['PERSON_TYPE_ID']]['floor']: if (isset($order['delivery']['address']['floor'])) - CSaleOrderPropsValue::Update($ar['ID'], array('VALUE' => self::fromJSON($order['delivery']['address']['floor']))); - break; - case $optionsOrderProps[$arFields['PERSON_TYPE_ID']]['block']: if (isset($order['delivery']['address']['block'])) - CSaleOrderPropsValue::Update($ar['ID'], array('VALUE' => self::fromJSON($order['delivery']['address']['block']))); - break; - case $optionsOrderProps[$arFields['PERSON_TYPE_ID']]['house']: if (isset($order['delivery']['address']['house'])) - CSaleOrderPropsValue::Update($ar['ID'], array('VALUE' => self::fromJSON($order['delivery']['address']['house']))); - break; + if (isset($order['orderType']) && isset($optionsOrderTypes[ $order['orderType'] ])) { + if (isset($optionsOrderProps[$arFields['PERSON_TYPE_ID']])) { + foreach ($optionsOrderProps[$arFields['PERSON_TYPE_ID']] as $code => $value) { + if (in_array($code, array_keys($order)) === false && isset($optionsOrderProps[$optionsOrderTypes[$order['orderType']]][$code])) { + $order[ $code ] = $arUpdateProps[$optionsOrderProps[$arFields['PERSON_TYPE_ID']][$code]]['VALUE']; } } } - switch ($ar['CODE']) { - case $optionsOrderProps[$arFields['PERSON_TYPE_ID']]['fio']: - $contactName = array(); // cleanup - if (isset($order['lastName'])) { - $contactName['lastName'] = self::fromJSON($order['lastName']); - } - if (isset($order['firstName'])) { - $contactName['firstName'] = self::fromJSON($order['firstName']); - } - if (isset($order['patronymic'])) { - $contactName['patronymic'] = self::fromJSON($order['patronymic']); - } - if (!isset($contactName) || empty($contactName)) { - break; - } + //update ordertype + CSaleOrder::Update($order['externalId'], array('PERSON_TYPE_ID' => $optionsOrderTypes[ $order['orderType'] ])); - CSaleOrderPropsValue::Update($ar['ID'], array('VALUE' => implode(" ", $contactName))); - break; - case $optionsOrderProps[$arFields['PERSON_TYPE_ID']]['phone']: - if (isset($order['phone'])) { - CSaleOrderPropsValue::Update($ar['ID'], array('VALUE' => self::fromJSON($order['phone']))); - } - break; - case $optionsOrderProps[$arFields['PERSON_TYPE_ID']]['email']: - if (isset($order['email'])) { - CSaleOrderPropsValue::Update($ar['ID'], array('VALUE' => self::fromJSON($order['email']))); - } - break; + $arProp = CSaleOrderProps::GetList(array(), array('PERSON_TYPE_ID' => $optionsOrderTypes[ $order['orderType'] ])); + $typeParam = array(); + while ($ar = $arProp->Fetch()) { + $typeParam[ $ar['CODE'] ] = $ar['CODE']; } - - } - - // here check if smth wasnt added or new propetties - if (isset($order['delivery']) && isset($order['delivery']['address']) && count($order['delivery']['address']) > 0) { - if (isset($order['delivery']['address']['index'])) { - self::addOrderProperty($optionsOrderProps[$arFields['PERSON_TYPE_ID']]['index'], - self::fromJSON($order['delivery']['address']['index']), $order['externalId']); - } - - if (isset($order['delivery']['address']['city'])) { - self::addOrderProperty($optionsOrderProps[$arFields['PERSON_TYPE_ID']]['city'], self::fromJSON($order['delivery']['address']['city']), $order['externalId']); - self::addOrderProperty('CITY', self::fromJSON($order['delivery']['address']['city']), $order['externalId']); - - $cityId = self::getLocationCityId(self::fromJSON($order['delivery']['address']['city'])); - if ($cityId) { - self::addOrderProperty('LOCATION', $cityId, $order['externalId']); - } else { - self::addOrderProperty('LOCATION', 0, $order['externalId']); - } - } - - if (isset($order['delivery']['address']['text'])) { - self::addOrderProperty($optionsOrderProps[$arFields['PERSON_TYPE_ID']]['text'], self::fromJSON($order['delivery']['address']['text']), $order['externalId']); - } - - if (count($optionsOrderProps[$arFields['PERSON_TYPE_ID']]) > 4) { - if (isset($order['delivery']['address']['street'])) { - self::addOrderProperty($optionsOrderProps[$arFields['PERSON_TYPE_ID']]['street'], - self::fromJSON($order['delivery']['address']['street']), $order['externalId']); - } - - if (isset($order['delivery']['address']['building'])) { - self::addOrderProperty($optionsOrderProps[$arFields['PERSON_TYPE_ID']]['building'], - self::fromJSON($order['delivery']['address']['bulding']), $order['externalId']); - } - - if (isset($order['delivery']['address']['flat'])) { - self::addOrderProperty($optionsOrderProps[$arFields['PERSON_TYPE_ID']]['flat'], - self::fromJSON($order['delivery']['address']['flat']), $order['externalId']); - } - - if (isset($order['delivery']['address']['intercomcode'])) { - self::addOrderProperty($optionsOrderProps[$arFields['PERSON_TYPE_ID']]['intercomcode'], - self::fromJSON($order['delivery']['address']['intercomcode']), $order['externalId']); - } - - if (isset($order['delivery']['address']['floor'])) { - self::addOrderProperty($optionsOrderProps[$arFields['PERSON_TYPE_ID']]['floor'], - self::fromJSON($order['delivery']['address']['floor']), $order['externalId']); - } - - if (isset($order['delivery']['address']['block'])) { - self::addOrderProperty($optionsOrderProps[$arFields['PERSON_TYPE_ID']]['block'], - self::fromJSON($order['delivery']['address']['block']), $order['externalId']); - } - - if (isset($order['delivery']['address']['house'])) { - self::addOrderProperty($optionsOrderProps[$arFields['PERSON_TYPE_ID']]['house'], - self::fromJSON($order['delivery']['address']['house']), $order['externalId']); + foreach (array_diff_key($arUpdateProps, $typeParam) as $code => $param) { + if (isset($arUpdateProps[$code])) { + CSaleOrderPropsValue::Delete($param['ID']); } } + $arFields['PERSON_TYPE_ID'] = $optionsOrderTypes[ $order['orderType'] ]; } - if (isset($order['phone'])) { - self::addOrderProperty($optionsOrderProps[$arFields['PERSON_TYPE_ID']]['phone'], - self::fromJSON($order['phone']), $order['externalId']); - } - - if (isset($order['email'])) - self::addOrderProperty($optionsOrderProps[$arFields['PERSON_TYPE_ID']]['email'], - self::fromJSON($order['email']), $order['externalId']); - - $contactName = array(); // cleanup - if (isset($order['firstName'])) { - $contactName['firstName'] = self::fromJSON($order['firstName']); - } - if (isset($order['lastName'])) { - $contactName['lastName'] = self::fromJSON($order['lastName']); - } - if (isset($order['patronymic'])) { - $contactName['patronymic'] = self::fromJSON($order['patronymic']); - } - - if (isset($contactName) && !empty($contactName)) { - self::addOrderProperty($optionsOrderProps[$arFields['PERSON_TYPE_ID']]['fio'], - implode(" ", $contactName), $order['externalId']); - } + array_walk_recursive( + self::clearArr($order), + 'self::recursiveUpdate', + array( + 'update' => $arUpdateProps, + 'type' => $arFields['PERSON_TYPE_ID'], + 'options' => $optionsOrderProps, + 'orderId' => $order['externalId'] + ) + ); foreach($order['items'] as $item) { - // del from basket if(isset($item['deleted']) && $item['deleted']) { - $p = CSaleBasket::GetList( - array('PRODUCT_ID' => 'ASC'), - array('ORDER_ID' => $order['externalId'], 'PRODUCT_ID' => $item['id']))->Fetch(); - - if ($p) { + if ($p = CSaleBasket::GetList(array(), array('ORDER_ID' => $order['externalId'], 'PRODUCT_ID' => $item['id']))->Fetch()) { CSaleBasket::Delete($p['ID']); } - - continue; - } - - if (!isset($item['offer']) && !isset($item['offer']['externalId'])) { continue; } - $p = CSaleBasket::GetList( - array('PRODUCT_ID' => 'ASC'), - array('ORDER_ID' => $order['externalId'], 'PRODUCT_ID' => $item['offer']['externalId']) - )->Fetch(); + if (isset($item['offer']) === false && isset($item['offer']['externalId']) === false) { + continue; + } - if (!$p) { + $p = CSaleBasket::GetList(array(),array('ORDER_ID' => $order['externalId'], 'PRODUCT_ID' => $item['offer']['externalId']))->Fetch(); + + if ($p == false) { $p = CIBlockElement::GetByID($item['offer']['externalId'])->Fetch(); - // select iblock to obtain an CATALOG_XML_ID $iblock = CIBlock::GetByID($p['IBLOCK_ID'])->Fetch(); $p['CATALOG_XML_ID'] = $iblock['XML_ID']; - // product field XML_ID is called PRODUCT_XML_ID in basket $p['PRODUCT_XML_ID'] = $p['XML_ID']; unset($p['XML_ID']); - } else { - //for basket props updating (in props we save cancel status) - $propResult = CSaleBasket::GetPropsList( - array(''), - array('BASKET_ID' => $p['ID']), - false, - false, - array('NAME', 'CODE', 'VALUE', 'SORT') - ); - - while($r = $propResult->Fetch()) { + } elseif ($propResult = CSaleBasket::GetPropsList(array(''),array('BASKET_ID' => $p['ID']))) { + while ($r = $propResult->Fetch()) { $p['PROPS'][] = $r; } } - // change existing basket items $arProduct = array(); - // create new - if(isset($item['created']) && $item['created']) { - + if (isset($item['created']) && $item['created'] == true) { $productPrice = GetCatalogProductPrice($item['offer']['externalId'], 1); - $arProduct = array( 'FUSER_ID' => $userId, 'ORDER_ID' => $order['externalId'], @@ -857,73 +656,43 @@ class ICrmOrderActions 'PRODUCT_XML_ID' => $p['PRODUCT_XML_ID'], 'CUSTOM_PRICE' => 'Y' ); + } + if (isset($item['isCanceled']) == false) { if (isset($item['initialPrice']) && $item['initialPrice']) { $arProduct['PRICE'] = (double) $item['initialPrice']; } - if (isset($item['discount'])) { $arProduct['DISCOUNT_PRICE'] = $item['discount']; } - if (isset($item['discountPercent'])) { $arProduct['DISCOUNT_VALUE'] = $item['discountPercent']; - $newPrice = floor ($arProduct['PRICE'] / 100 * (100 - $arProduct['DISCOUNT_VALUE'])); + $newPrice = round($arProduct['PRICE'] / 100 * (100 - $arProduct['DISCOUNT_VALUE']), 2); $arProduct['DISCOUNT_PRICE'] = $arProduct['DISCOUNT_PRICE'] + $arProduct['PRICE'] - $newPrice; } - if(isset($item['discount']) || isset($item['discountPercent'])) { $arProduct['PRICE'] -= $arProduct['DISCOUNT_PRICE']; } - if (isset($item['offer']['name']) && $item['offer']['name']) { $arProduct['NAME'] = self::fromJSON($item['offer']['name']); } - - if (isset($item['isCanceled'])) { - //for product excluding from order - $arProduct['PRICE'] = 0; - $arProduct = self::updateCancelProp($arProduct, 1); - } - - CSaleBasket::Add($arProduct); - continue; - } - - $arProduct['PROPS'] = $p['PROPS']; - - if (!isset($item['isCanceled'])) { - // update old - if (isset($item['initialPrice']) && $item['initialPrice']) { - $arProduct['PRICE'] = (double) $item['initialPrice']; - } - - if (isset($item['discount'])) { - $arProduct['DISCOUNT_PRICE'] = $item['discount']; - } - - if (isset($item['discountPercent'])) { - $arProduct['DISCOUNT_VALUE'] = $item['discountPercent']; - $newPrice = floor ($arProduct['PRICE'] / 100 * (100 - $arProduct['DISCOUNT_VALUE'])); - $arProduct['DISCOUNT_PRICE'] = $arProduct['DISCOUNT_PRICE'] + $arProduct['PRICE'] - $newPrice; - } - - if(isset($item['discount']) || isset($item['discountPercent'])) { - $arProduct['PRICE'] -= $arProduct['DISCOUNT_PRICE']; - } - $arProduct = self::updateCancelProp($arProduct, 0); - } else { - //for product excluding from order + } elseif (isset($item['isCanceled'])) { $arProduct['PRICE'] = 0; $arProduct = self::updateCancelProp($arProduct, 1); } + if (isset($item['created']) && $item['created'] == true) { + CSaleBasket::Add($arProduct); + continue; + } + if (count($p['PROPS']) > 0) { + $arProduct['PROPS'] = $p['PROPS']; + } if (isset($item['quantity']) && $item['quantity']) { $arProduct['QUANTITY'] = $item['quantity']; } - if (isset($item['offer']['name']) && $item['offer']['name']) { $arProduct['NAME'] = self::fromJSON($item['offer']['name']); } @@ -932,32 +701,28 @@ class ICrmOrderActions CSaleBasket::DeleteAll($userId); } - if (!isset($order['delivery']) || !isset($order['delivery']['cost'])) { + if (isset($order['delivery']) === false || isset($order['delivery']['cost']) === false) { $order['delivery']['cost'] = $arFields['PRICE_DELIVERY']; } - if (!isset($order['summ']) || (isset($order['summ']) && !$order['summ'] && $order['summ'] !== 0)) { + if (isset($order['summ']) === false || $order['summ'] <= 0) { $order['summ'] = $arFields['PRICE'] - $arFields['PRICE_DELIVERY']; } $wasCanaceled = $arFields['CANCELED'] == 'Y' ? true : false; - $resultDeliveryTypeId = $optionsDelivTypes[$order['delivery']['code']]; - - if(isset($order['delivery']['service']) && !empty($order['delivery']['service'])) { - if (strpos($order['delivery']['service']['code'], "-") !== false) - $deliveryServiceCode = explode("-", $order['delivery']['service']['code'], 2); - - if ($deliveryServiceCode) - $resultDeliveryTypeId = $resultDeliveryTypeId . ':' . $deliveryServiceCode[1]; + if (isset($optionsDelivTypes[$order['delivery']['code']])) { + $resultDeliveryTypeId = $optionsDelivTypes[$order['delivery']['code']]; + } else { + $resultDeliveryTypeId = isset($order['delivery']['service']) && isset($order['delivery']['service']['code']) ? + reset(explode(":", $arFields['DELIVERY_ID'], 1)) : + $arFields['DELIVERY_ID']; } - if(isset($order['delivery']) && $order['delivery'] && isset($order['delivery']['integrationCode']) && - $order['delivery']['integrationCode'] == self::$CRM_MULTISHIP_INTEGRATION_CODE && - isset($order['delivery']['data']) && $order['delivery']['data'] && - isset($order['delivery']['data']['service']) && $order['delivery']['data']['service']) { - if(CModule::IncludeModule(self::$MULTISHIP_MODULE_VER)) { - $resultDeliveryTypeId = $resultDeliveryTypeId . ':' . $order['delivery']['data']['service']; + if(isset($order['delivery']['service']) && isset($order['delivery']['service']['code'])) { + $deliveryHandler = reset(CSaleDeliveryHandler::GetBySID($resultDeliveryTypeId)->arResult); + if (count($deliveryHandler) > 0 && array_key_exists($order['delivery']['service']['code'], $deliveryHandler['PROFILES'])) { + $resultDeliveryTypeId = $resultDeliveryTypeId . ':' . $order['delivery']['service']['code']; } } @@ -989,13 +754,9 @@ class ICrmOrderActions // set STATUS_ID CSaleOrder::StatusOrder($order['externalId'], $optionsPayStatuses[$order['status']]); - // uncancel order - if($wasCanaceled && ($optionsPayStatuses[$order['status']] != 'YY')) { + if($wasCanaceled && $optionsPayStatuses[ $order['status'] ] != 'YY') { CSaleOrder::CancelOrder($order['externalId'], "N", $order['statusComment']); - } - - // cancel order - if($optionsPayStatuses[$order['status']] == 'YY') { + } elseif ($optionsPayStatuses[ $order['status'] ] == 'YY') { CSaleOrder::CancelOrder($order['externalId'], "Y", $order['statusComment']); } } @@ -1012,7 +773,7 @@ class ICrmOrderActions } } - if (count($orderHistory)) { + if (count($orderHistory) > 0) { COption::SetOptionString(self::$MODULE_ID, self::$CRM_ORDER_HISTORY_DATE, $dateFinish->format('Y-m-d H:i:s')); } @@ -1021,6 +782,83 @@ class ICrmOrderActions return true; } + protected static function recursiveUpdate($value, $code, $param) + { + $value = self::fromJSON($value); + if (in_array($code, array('customer', 'items')) === false && isset($param['options'][$param['type']][$code])) { + self::updateProps($value, $code, $param); + } + } + + protected static function updateProps($value, $code, $param) + { + if ($value == '' || !CModule::IncludeModule('sale')) { + return false; + } + $add = false; + if (isset($param['update'][ $param['options'][$param['type']][$code] ]) == false) { + if ($arProp = CSaleOrderProps::GetList(array(), array('CODE' => $param['options'][$param['type']][$code]))->Fetch()) { + $param['update'][ $param['options'][$param['type']][$code] ] = array( + 'NAME' => $arProp['NAME'], + 'CODE' => $arProp['CODE'], + 'ORDER_PROPS_ID' => $arProp['ID'], + 'TYPE' => $arProp['TYPE'], + 'ORDER_ID' => $param['orderId'], + 'VALUE' => '' + ); + $add = true; + } else { + return false; + } + } + + if ($param['update'][ $param['options'][$param['type']][$code] ]['TYPE'] == 'LOCATION') { + $value = self::getLocation($value); + if ($value == false) { + return false; + } + } + + if ($param['update'][ $param['options'][$param['type']][$code] ]['VALUE'] != $value) { + if ($add === true) { + $param['update'][ $param['options'][$param['type']][$code] ]['VALUE'] = $value; + CSaleOrderPropsValue::Add($param['update'][ $param['options'][$param['type']][$code] ]); + } else { + CSaleOrderPropsValue::Update($param['update'][ $param['options'][$param['type']][$code] ]['ID'], array('VALUE' => $value)); + } + } + } + + protected static function updateCancelProp($arProduct, $value) { + if (isset($arProduct['PROPS'])) { + foreach($arProduct['PROPS'] as $key => $item) { + if ($item['CODE'] == self::CANCEL_PROPERTY_CODE) { + $arProduct['PROPS'][$key]['VALUE'] = $value; + break; + } + } + $arProduct['PROPS'][] = array( + 'NAME' => GetMessage('PRODUCT_CANCEL'), + 'CODE' => self::CANCEL_PROPERTY_CODE, + 'VALUE' => $value, + 'SORT' => 10, + ); + } + + return $arProduct; + } + + public static function getLocation($value) { + if (is_string($value) === false) { + return false; + } elseif ($location = CSaleLocation::GetList(array(), array("LID" => LANGUAGE_ID, "CITY_NAME" => $value))->Fetch()) { + return method_exists('CSaleLocation', 'getLocationCODEbyID') ? + CSaleLocation::getLocationCODEbyID($location['ID']) : $location['ID']; + } else { + return false; + } + } + /** * * w+ event in bitrix log @@ -1072,318 +910,6 @@ class ICrmOrderActions return 'ICrmOrderActions::orderAgent();'; } - /** - * - * Creates order or returns array of order and customer for mass upload - * - * @param array $arFields - * @param $api - * @param $arParams - * @param $send - * @return boolean - * @return array - array('order' = $order, 'customer' => $customer) - */ - public static function orderCreate($arFields, $api, $arParams, $send = false) { - if(!$api || empty($arParams)) { // add cond to check $arParams - return false; - } - - if (empty($arFields)) { - //handle err - self::eventLog('ICrmOrderActions::orderCreate', 'empty($arFields)', 'incorrect order'); - - return false; - } - - $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']); - $lastName = self::toJSON($arUser['LAST_NAME']); - $patronymic = self::toJSON($arUser['SECOND_NAME']); - - // convert encoding for comment - $statusComment = self::toJson($arFields['REASON_CANCELED']); - $customerComment = self::toJson($arFields['USER_DESCRIPTION']); - $managerComment = self::toJson($arFields['COMMENTS']); - - $phones = array(); - - $phonePersonal = array( - 'number' => self::toJSON($arUser['PERSONAL_PHONE']), - 'type' => 'mobile' - ); - - if($phonePersonal['number']) - $phones[] = $phonePersonal; - - $phoneWork = array( - 'number' => self::toJSON($arUser['WORK_PHONE']), - 'type' => 'work' - ); - - if($phoneWork['number']) - $phones[] = $phoneWork; - - $customer = self::clearArr(array( - 'externalId' => $arFields['USER_ID'], - 'lastName' => $lastName, - 'firstName' => $firstName, - 'patronymic' => $patronymic, - 'phones' => $phones, - 'createdAt' => $createdAt - )); - - // delivery types - $arId = array(); - if (strpos($arFields['DELIVERY_ID'], ":") !== false) - $arId = explode(":", $arFields["DELIVERY_ID"]); - - if ($arId) - $resultDeliveryTypeId = $arId[0]; - else - $resultDeliveryTypeId = $arFields['DELIVERY_ID']; - - // deliveryService - $deliveryService = array(); - if(count($arId) > 1) { - $dbDeliveryType = CSaleDeliveryHandler::GetBySID($arId[0]); - - if ($arDeliveryType = $dbDeliveryType->GetNext()) { - foreach($arDeliveryType['PROFILES'] as $id => $profile) { - if($id == $arId[1]) { - $deliveryService = array( - 'code' => $arId[0] . '-' . $id, - 'name' => $profile['TITLE'] - ); - } - } - } - } - - $resOrder = array(); - $resOrderDeliveryAddress = array(); - $contactNameArr = array(); - - $rsOrderProps = CSaleOrderPropsValue::GetList(array(), array('ORDER_ID' => $arFields['ID'])); - while ($ar = $rsOrderProps->Fetch()) { - switch ($ar['CODE']) { - case $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']]['index']: $resOrderDeliveryAddress['index'] = self::toJSON($ar['VALUE']); - break; - case 'CITY': - $prop = CSaleOrderProps::GetByID($ar['ORDER_PROPS_ID']); - if($prop['TYPE'] == 'LOCATION') { - $resOrderDeliveryAddress['city'] = CSaleLocation::GetByID($ar['VALUE']); - $resOrderDeliveryAddress['city'] = self::toJSON($resOrderDeliveryAddress['city']['CITY_NAME_LANG']); - break; - } - $resOrderDeliveryAddress['city'] = self::toJSON($ar['VALUE']); - break; - case $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']]['text']: $resOrderDeliveryAddress['text'] = self::toJSON($ar['VALUE']); - break; - case 'LOCATION': if(!isset($resOrderDeliveryAddress['city']) && !$resOrderDeliveryAddress['city']) { - $prop = CSaleOrderProps::GetByID($ar['ORDER_PROPS_ID']); - if($prop['TYPE'] == 'LOCATION') { - $resOrderDeliveryAddress['city'] = CSaleLocation::GetByID($ar['VALUE']); - $resOrderDeliveryAddress['city'] = self::toJSON($resOrderDeliveryAddress['city']['CITY_NAME_LANG']); - break; - } - $resOrderDeliveryAddress['city'] = self::toJSON($ar['VALUE']); - break; - } - break; - case $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']]['fio']: $contactNameArr = self::explodeFIO($ar['VALUE']); - break; - case $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']]['phone']: $resOrder['phone'] = $ar['VALUE']; - break; - case $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']]['email']: $resOrder['email'] = $ar['VALUE']; - break; - } - - if (count($arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']]) > 4) { - switch ($ar['CODE']) { - case $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']]['street']: $resOrderDeliveryAddress['street'] = self::toJSON($ar['VALUE']); - break; - case $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']]['building']: $resOrderDeliveryAddress['building'] = self::toJSON($ar['VALUE']); - break; - case $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']]['flat']: $resOrderDeliveryAddress['flat'] = self::toJSON($ar['VALUE']); - break; - case $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']]['intercomcode']: $resOrderDeliveryAddress['intercomcode'] = self::toJSON($ar['VALUE']); - break; - case $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']]['floor']: $resOrderDeliveryAddress['floor'] = self::toJSON($ar['VALUE']); - break; - case $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']]['block']: $resOrderDeliveryAddress['block'] = self::toJSON($ar['VALUE']); - break; - case $arParams['optionsOrderProps'][$arFields['PERSON_TYPE_ID']]['house']: $resOrderDeliveryAddress['house'] = self::toJSON($ar['VALUE']); - break; - } - } - } - - $items = array(); - - $rsOrderBasket = CSaleBasket::GetList(array('ID' => 'ASC'), array('ORDER_ID' => $arFields['ID'])); - while ($p = $rsOrderBasket->Fetch()) { - //for basket props updating (in props we save cancel status) - $propCancel = CSaleBasket::GetPropsList( - array(), - array('BASKET_ID' => $p['ID'], 'CODE' => self::CANCEL_PROPERTY_CODE) - )->Fetch(); - - if ($propCancel) { - $propCancel = (int)$propCancel['VALUE']; - } - - $pr = CCatalogProduct::GetList(array(), array('ID' => $p['PRODUCT_ID']))->Fetch(); - - if(!$pr) { - $pr = ''; - unset($item['productId']); - } else $pr = $pr['PURCHASING_PRICE']; - - $item = array( - 'discountPercent' => 0, - 'quantity' => $p['QUANTITY'], - 'productId' => $p['PRODUCT_ID'], - 'productName' => self::toJSON($p['NAME']), - 'comment' => $p['NOTES'], - ); - - //if it is canceled product don't send price - if (!$propCancel) { - $item['initialPrice'] = (double) $p['PRICE'] + (double) $p['DISCOUNT_PRICE']; - $item['discount'] = $p['DISCOUNT_PRICE']; - } - - $items[] = $item; - } - - if($arFields['CANCELED'] == 'Y') - $arFields['STATUS_ID'] = $arFields['CANCELED'].$arFields['CANCELED']; - - $createdAt = new \DateTime($arFields['DATE_INSERT']); - $createdAt = $createdAt->format('Y-m-d H:i:s'); - - $delivery = array( - 'code' => $arParams['optionsDelivTypes'][$resultDeliveryTypeId], - 'service' => ($arParams['optionsDelivTypes'][$resultDeliveryTypeId]) ? $deliveryService : '', - 'address' => $resOrderDeliveryAddress, - 'cost' => $arFields['PRICE_DELIVERY'] - ); - - if($arParams['optionsDelivTypes'][$resultDeliveryTypeId] == self::$MUTLISHIP_DELIVERY_TYPE) { - if(CModule::IncludeModule(self::$MULTISHIP_MODULE_VER)) { - $multishipArr = DBOrdersMlsp::GetByOI($arFields['ID']); - $delivery['data'] = array('ms_id' => $multishipArr['MULTISHIP_ID']); - $delivery['integrationCode'] = 'multiship'; - } - } - - $resOrder = array( - 'customer' => $customer, - 'number' => $arFields['ACCOUNT_NUMBER'], - 'phone' => $resOrder['phone'], - 'email' => $resOrder['email'], - 'summ' => $arFields['PRICE'], - 'markDateTime' => $arFields['DATE_MARKED'], - 'externalId' => $arFields['ID'], - 'customerId' => $arFields['USER_ID'], - 'paymentType' => $arParams['optionsPayTypes'][$arFields['PAY_SYSTEM_ID']], - 'paymentStatus' => $arParams['optionsPayment'][$arFields['PAYED']], - 'orderType' => $arParams['optionsOrderTypes'][$arFields['PERSON_TYPE_ID']], - 'status' => $arParams['optionsPayStatuses'][$arFields['STATUS_ID']], - 'statusComment' => $statusComment, - 'customerComment' => $customerComment, - 'managerComment' => $managerComment, - 'createdAt' => $createdAt, - 'delivery' => $delivery, - 'discount' => $arFields['DISCOUNT_VALUE'], - 'items' => $items - ); - - if(isset($arParams['optionsSites']) && is_array($arParams['optionsSites']) - && in_array($arFields['LID'], $arParams['optionsSites'])) - $resOrder['site'] = $arFields['LID']; - - // parse fio - if(count($contactNameArr) > 0) { - $resOrder = array_merge($resOrder, $contactNameArr); - } - - // custom orderType function - if(function_exists('intarocrm_get_order_type')) { - $orderType = intarocrm_get_order_type($arFields); - if($orderType) - $resOrder['orderType'] = $orderType; - else - $orderType['orderType'] = 'new'; - } - - // custom order & customer fields function - if(function_exists('intarocrm_before_order_send')) { - $newResOrder = intarocrm_before_order_send($resOrder); - - if(is_array($newResOrder) && !empty($newResOrder)) - $resOrder = $newResOrder; - - } - - $resOrder = self::clearArr($resOrder); - - if(isset($resOrder['customer']) && is_array($resOrder['customer']) && !empty($resOrder['customer'])) { - $customer = $resOrder['customer']; - unset($resOrder['customer']); - } - - if($send) { - - try { - $customer = $api->customerEdit($customer); - } catch (\IntaroCrm\Exception\ApiException $e) { - self::eventLog( - 'ICrmOrderActions::orderCreate', 'IntaroCrm\RestApi::customerEdit', - $e->getCode() . ': ' . $e->getMessage() - ); - - return false; - } catch (\IntaroCrm\Exception\CurlException $e) { - self::eventLog( - 'ICrmOrderActions::orderCreate', 'IntaroCrm\RestApi::customerEdit::CurlException', - $e->getCode() . ': ' . $e->getMessage() - ); - - return false; - } - - try { - return $api->orderEdit($resOrder); - } catch (\IntaroCrm\Exception\ApiException $e) { - self::eventLog( - 'ICrmOrderActions::orderCreate', 'IntaroCrm\RestApi::orderEdit', - $e->getCode() . ': ' . $e->getMessage() - ); - - return false; - } catch (\IntaroCrm\Exception\CurlException $e) { - self::eventLog( - 'ICrmOrderActions::orderCreate', 'IntaroCrm\RestApi::orderEdit::CurlException', - $e->getCode() . ': ' . $e->getMessage() - ); - - return false; - } - } - - return array( - 'order' => $resOrder, - 'customer' => $customer - ); - } - /** * removes all empty fields from arrays * working with nested arrs @@ -1432,7 +958,7 @@ class ICrmOrderActions } public static function explodeFIO($fio) { - $newFio = empty($fio) ? false : explode(" ", self::toJSON($fio), 3); + $newFio = empty($fio) ? false : explode(" ", $fio, 3); $result = array(); switch (count($newFio)) { default: @@ -1444,14 +970,14 @@ class ICrmOrderActions break; case 2: $result = array( - 'lastName' => $newFio[1], - 'firstName' => $newFio[0] + 'lastName' => $newFio[0], + 'firstName' => $newFio[1] ); break; case 3: $result = array( - 'lastName' => $newFio[1], - 'firstName' => $newFio[0], + 'lastName' => $newFio[0], + 'firstName' => $newFio[1], 'patronymic' => $newFio[2] ); break; @@ -1460,37 +986,37 @@ class ICrmOrderActions return $result; } - public static function addOrderProperty($code, $value, $order) { - if (!$code) - return; + public static function apiMethod($api, $methodApi, $method, $params, $site = null) { + switch($methodApi){ + case 'ordersGet': + case 'orderEdit': + case 'customerGet': + case 'customerEdit': + try { + $result = $api->$methodApi($params, 'externalId', $site); + } catch (\RetailCrm\Exception\CurlException $e) { + self::eventLog( + __CLASS__.'::'.$method, 'RetailCrm\RestApi::'.$methodApi.'::CurlException', + $e->getCode() . ': ' . $e->getMessage() + ); - if (!CModule::IncludeModule('sale')) - return; + return false; + } + return $result; + + default: + try { + $result = $api->$methodApi($params, $site); + } catch (\RetailCrm\Exception\CurlException $e) { + self::eventLog( + __CLASS__.'::'.$method, 'RetailCrm\RestApi::'.$methodApi.'::CurlException', + $e->getCode() . ': ' . $e->getMessage() + ); - if ($arProp = CSaleOrderProps::GetList(array(), array('CODE' => $code))->Fetch()) { - return CSaleOrderPropsValue::Add(array( - 'NAME' => $arProp['NAME'], - 'CODE' => $arProp['CODE'], - 'ORDER_PROPS_ID' => $arProp['ID'], - 'ORDER_ID' => $order, - 'VALUE' => $value, - )); - } - } - - public static function getLocationCityId($cityName) { - if(!$cityName) - return; - - $dbLocation = CSaleLocation::GetList( - array( - "SORT" => "ASC", - "CITY_NAME_LANG" => "ASC" - ), - array("LID" => "ru", "CITY_NAME" => $cityName), false, false, array()); - - if($location = $dbLocation->Fetch()) - return $location['ID']; + return false; + } + return $result; + } } } @@ -1498,7 +1024,6 @@ class RetailUser extends CUser { public function GetID() { - $rsUser = CUser::GetList(($by='ID'), ($order='DESC'), array('LOGIN' => 'retailcrm%')); if ($arUser = $rsUser->Fetch()) { return $arUser['ID']; diff --git a/intaro.intarocrm/classes/general/Response/ApiResponse.php b/intaro.intarocrm/classes/general/Response/ApiResponse.php new file mode 100644 index 00000000..3997a725 --- /dev/null +++ b/intaro.intarocrm/classes/general/Response/ApiResponse.php @@ -0,0 +1,127 @@ +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]; + } +} diff --git a/intaro.intarocrm/classes/general/RestApi.php b/intaro.intarocrm/classes/general/RestApi.php index b201f748..15f9434d 100644 --- a/intaro.intarocrm/classes/general/RestApi.php +++ b/intaro.intarocrm/classes/general/RestApi.php @@ -1,25 +1,52 @@ apiUrl = $crmUrl.'/api/v'.$this->apiVersion.'/'; - $this->apiKey = $apiKey; - $this->parameters = array('apiKey' => $this->apiKey); + if ('/' != substr($url, strlen($url) - 1, 1)) { + $url .= '/'; + } + + $url = $url . 'api/' . self::VERSION; + + if (false === stripos($url, 'https://')) { + throw new \InvalidArgumentException('API schema requires HTTPS protocol'); + } + + $this->url = $url; + $this->defaultParameters = array('apiKey' => $apiKey); + $this->siteCode = $site; } /* Методы для работы с заказами */ @@ -28,82 +55,99 @@ class RestApi * * @param string $id - идентификатор заказа * @param string $by - поиск заказа по id или externalId - * @return array - информация о заказе + * @param string $site - символьный код сайта + * @return ApiResponse - информация о заказе */ - public function orderGet($id, $by = 'externalId') + public function ordersGet($id, $by = 'externalId', $site = null) { - $url = $this->apiUrl.'orders/'.$id; - - if ($by != 'externalId') - $this->parameters['by'] = $by; - $result = $this->curlRequest($url); - return $result; + $this->checkIdParameter($by); + + return $this->makeRequest("/orders/$id", self::METHOD_GET, $this->fillSite($site, array( + 'by' => $by + ))); } /** * Создание заказа * - * @param array $order- информация о заказе - * @return array + * @param array $order - информация о заказе + * @param string $site - символьный код сайта + * @return ApiResponse */ - public function orderCreate($order) + public function ordersCreate($order, $site = null) { - $dataJson = json_encode($order); - $this->parameters['order'] = $dataJson; - - $url = $this->apiUrl.'orders/create'; - $result = $this->curlRequest($url, 'POST'); - return $result; + if (!sizeof($order)) { + throw new \InvalidArgumentException('Parameter `order` must contains a data'); + } + + return $this->makeRequest("/orders/create", self::METHOD_POST, $this->fillSite($site, array( + 'order' => json_encode($order) + ))); } /** * Изменение заказа * - * @param array $order- информация о заказе - * @return array + * @param array $order - информация о заказе + * @param string $by - изменение заказа по id или externalId + * @param string $site - символьный код сайта + * @return ApiResponse */ - public function orderEdit($order) + public function orderEdit($order, $by = 'externalId', $site = null) { - $dataJson = json_encode($order); - $this->parameters['order'] = $dataJson; - - $url = $this->apiUrl.'orders/'.$order['externalId'].'/edit'; - $result = $this->curlRequest($url, 'POST'); - return $result; + 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->makeRequest( + "/orders/" . $order[$by] . "/edit", + self::METHOD_POST, + $this->fillSite($site, array( + 'order' => json_encode($order), + 'by' => $by, + )) + ); } /** * Пакетная загрузка заказов * * @param array $orders - массив заказов - * @return array + * @param string $site - символьный код сайта + * @return ApiResponse */ - public function orderUpload($orders) + public function orderUpload($orders, $site = null) { - $dataJson = json_encode($orders); - $this->parameters['orders'] = $dataJson; - - $url = $this->apiUrl.'orders/upload'; - $result = $this->curlRequest($url, 'POST'); - if (is_null($result) && isset($result['uploadedOrders'])) - return $result['uploadedOrders']; - return $result; + if (!sizeof($orders)) { + throw new \InvalidArgumentException('Parameter `orders` must contains array of the orders'); + } + + return $this->makeRequest("/orders/upload", self::METHOD_POST, $this->fillSite($site, array( + 'orders' => json_encode($orders), + ))); } /** * Обновление externalId у заказов с переданными id * - * @param array $orders- массив, содержащий id и externalId заказа - * @return array + * @param array $order - массив, содержащий id и externalId заказа + * @return ApiResponse */ public function orderFixExternalIds($order) { - $dataJson = json_encode($order); - $this->parameters['orders'] = $dataJson; - - $url = $this->apiUrl.'orders/fix-external-ids'; - $result = $this->curlRequest($url, 'POST'); - return $result; + if (!sizeof($order)) { + throw new \InvalidArgumentException('Method parameter must contains at least one IDs pair'); + } + + return $this->makeRequest("/orders/fix-external-ids", self::METHOD_POST, array( + 'orders' => json_encode($order), + )); } /** @@ -113,18 +157,35 @@ class RestApi * @param \DateTime|string|int $endDate - конечная дата и время выборки (Y-m-d H:i:s) * @param int $limit - ограничение на размер выборки * @param int $offset - сдвиг - * @return array - массив заказов + * @param bool $skipMyChanges + * @return ApiResponse */ - public function orderHistory($startDate = null, $endDate = null, $limit = 100, $offset = 0) - { - $url = $this->apiUrl.'orders/history'; - $this->parameters['startDate'] = $this->ensureDateTime($startDate); - $this->parameters['endDate'] = $this->ensureDateTime($endDate); - $this->parameters['limit'] = $limit; - $this->parameters['offset'] = $offset; - - $result = $this->curlRequest($url); - return $result; + public function orderHistory( + $startDate = null, + $endDate = null, + $limit = 100, + $offset = 0, + $skipMyChanges = true + ) { + $parameters = array(); + + if ($startDate) { + $parameters['startDate'] = $this->ensureDateTime($startDate); + } + if ($endDate) { + $parameters['endDate'] = $this->ensureDateTime($endDate); + } + if ($limit) { + $parameters['limit'] = (int) $limit; + } + if ($offset) { + $parameters['offset'] = (int) $offset; + } + if ($skipMyChanges) { + $parameters['skipMyChanges'] = (bool) $skipMyChanges; + } + + return $this->makeRequest('/orders/history', self::METHOD_GET, $parameters); } /* Методы для работы с клиентами */ @@ -133,356 +194,380 @@ class RestApi * * @param string $id - идентификатор * @param string $by - поиск заказа по id или externalId + * @param string $site - символьный код сайта * @return array - информация о клиенте */ - public function customerGet($id, $by = 'externalId') + public function customerGet($id, $by = 'externalId', $site = null) { - $url = $this->apiUrl.'customers/'.$id; - if ($by != 'externalId') - $this->parameters['by'] = $by; - $result = $this->curlRequest($url); - return $result; + $this->checkIdParameter($by); + + return $this->makeRequest("/customers/$id", self::METHOD_GET, $this->fillSite($site, array( + 'by' => $by + ))); } /** * Получение списка клиентов в соответсвии с запросом * - * @param string $phone - телефон - * @param string $email - почтовый адрес - * @param string $fio - фио пользователя + * @param array $filter - фильтры + * @param int $page - страница * @param int $limit - ограничение на размер выборки - * @param int $offset - сдвиг - * @return array - массив клиентов + * @return ApiResponse */ - public function customers($phone = null, $email = null, $fio = null, $limit = 200, $offset = 0) + public function customersList(array $filter = array(), $page = null, $limit = null) { - $url = $this->apiUrl.'customers'; - if($phone) $this->parameters['phone'] = $phone; - if($email) $this->parameters['email'] = $email; - if($fio) $this->parameters['fio'] = $fio; - $this->parameters['limit'] = $limit; - $this->parameters['offset'] = $offset; - - $result = $this->curlRequest($url); - return $result; - } + $parameters = array(); + + if (sizeof($filter)) { + $parameters['filter'] = $filter; + } + + if (null !== $page) { + $parameters['page'] = (int) $page; + } + + if (null !== $limit) { + $parameters['limit'] = (int) $limit; + } + + return $this->makeRequest('/customers', self::METHOD_GET, $parameters); + } /** * Создание клиента * * @param array $customer - информация о клиенте - * @return array + * @param string $site - символьный код сайта + * @return ApiResponse */ - public function customerCreate($customer) + public function customersCreate(array $customer, $site = null) { - $dataJson = json_encode($customer); - $this->parameters['customer'] = $dataJson; - - $url = $this->apiUrl.'customers/create'; - $result = $this->curlRequest($url, 'POST'); - return $result; + if (!sizeof($customer)) { + throw new \InvalidArgumentException('Parameter `customer` must contains a data'); + } + + return $this->makeRequest("/customers/create", self::METHOD_POST, $this->fillSite($site, array( + 'customer' => json_encode($customer) + ))); } /** * Редактирование клиента * * @param array $customer - информация о клиенте - * @return array + * @param string $by - изменение клиента по id или externalId + * @param string $site - символьный код сайта + * @return ApiResponse */ - public function customerEdit($customer) + public function customerEdit($customer, $by = 'externalId', $site = null) { - $dataJson = json_encode($customer); - $this->parameters['customer'] = $dataJson; - - $url = $this->apiUrl.'customers/'.$customer['externalId'].'/edit'; - $result = $this->curlRequest($url, 'POST'); - return $result; + 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->makeRequest( + "/customers/" . $customer[$by] . "/edit", + self::METHOD_POST, + $this->fillSite($site, array( + 'customer' => json_encode($customer), + 'by' => $by, + ) + )); } /** * Пакетная загрузка клиентов * * @param array $customers - массив клиентов - * @return array + * @param string $site - символьный код сайта + * @return ApiResponse */ - public function customerUpload($customers) + public function customerUpload($customers, $site = null) { - $dataJson = json_encode($customers); - $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; + if (!sizeof($customers)) { + throw new \InvalidArgumentException('Parameter `customers` must contains array of the customers'); + } + + return $this->makeRequest("/customers/upload", self::METHOD_POST, $this->fillSite($site, array( + 'customers' => json_encode($customers), + ))); } /** * Обновление externalId у клиентов с переданными id * - * @param array $customers- массив, содержащий id и externalId заказа + * @param array $customers - массив, содержащий id и externalId заказа * @return array */ public function customerFixExternalIds($customers) { - $dataJson = json_encode($customers); - $this->parameters['customers'] = $dataJson; - - $url = $this->apiUrl.'customers/fix-external-ids'; - $result = $this->curlRequest($url, 'POST'); - return $result; - } - - /** - * Получение списка заказов клиента - * - * @param string $id - идентификатор клиента - * @param string $by - поиск заказа по id или externalId - * @param \DateTime|string|int $startDate - начальная дата выборки (Y-m-d H:i:s) - * @param \DateTime|string|int $endDate - конечная дата выборки (Y-m-d H:i:s) - * @param int $limit - ограничение на размер выборки - * @param int $offset - сдвиг - * @return array - массив заказов - */ - public function customerOrdersList($id, $startDate = null, $endDate = null, - $limit = 100, $offset = 0, $by = 'externalId') - { - $url = $this->apiUrl.'customers/'.$id.'/orders'; - if ($by != 'externalId') - $this->parameters['by'] = $by; - $this->parameters['startDate'] = $this->ensureDateTime($startDate); - $this->parameters['endDate'] = $this->ensureDateTime($endDate); - $this->parameters['limit'] = $limit; - $this->parameters['offset'] = $offset; - - $result = $this->curlRequest($url); - return $result; + if (!sizeof($customers)) { + throw new \InvalidArgumentException('Method parameter must contains at least one IDs pair'); + } + + return $this->makeRequest("/customers/fix-external-ids", self::METHOD_POST, array( + 'customers' => json_encode($customers), + )); } /* Методы для работы со справочниками */ + /** * Получение списка типов доставки * - * @return array - массив типов доставки + * @return ApiResponse */ public function deliveryTypesList() { - $url = $this->apiUrl.'reference/delivery-types'; - $result = $this->curlRequest($url); - return $result; + return $this->makeRequest('/reference/delivery-types', self::METHOD_GET); } /** * Редактирование типа доставки * - * @param array $deliveryType - информация о типе доставки - * @return array + * @param array $delivery - информация о типе доставки + * @return ApiResponse */ - public function deliveryTypeEdit($deliveryType) + public function deliveryTypeEdit($delivery) { - $dataJson = json_encode($deliveryType); - $this->parameters['deliveryType'] = $dataJson; - - $url = $this->apiUrl.'reference/delivery-types/'.$deliveryType['code'].'/edit'; - $result = $this->curlRequest($url, 'POST'); - return $result; + if (!isset($delivery['code'])) { + throw new \InvalidArgumentException('Data must contain "code" parameter.'); + } + + return $this->makeRequest( + '/reference/delivery-types/' . $delivery['code'] . '/edit', + self::METHOD_POST, + array( + 'deliveryType' => json_encode($delivery) + ) + ); } /** * Получение списка служб доставки * - * @return array - массив типов доставки + * @return ApiResponse */ public function deliveryServicesList() { - $url = $this->apiUrl.'reference/delivery-services'; - $result = $this->curlRequest($url); - return $result; + return $this->makeRequest('/reference/delivery-services', self::METHOD_GET); } /** * Редактирование службы доставки * - * @param array $deliveryService - информация о типе доставки - * @return array + * @param array $delivery - информация о типе доставки + * @return ApiResponse */ - public function deliveryServiceEdit($deliveryService) + public function deliveryServiceEdit($delivery) { - $dataJson = json_encode($deliveryService); - $this->parameters['deliveryService'] = $dataJson; - - $url = $this->apiUrl.'reference/delivery-services/'.$deliveryService['code'].'/edit'; - $result = $this->curlRequest($url, 'POST'); - return $result; + if (!isset($delivery['code'])) { + throw new \InvalidArgumentException('Data must contain "code" parameter.'); + } + + return $this->makeRequest( + '/reference/delivery-services/' . $delivery['code'] . '/edit', + self::METHOD_POST, + array( + 'deliveryService' => json_encode($delivery) + ) + ); } /** * Получение списка типов оплаты * - * @return array - массив типов оплаты + * @return ApiResponse */ public function paymentTypesList() { - $url = $this->apiUrl.'reference/payment-types'; - $result = $this->curlRequest($url); - return $result; + return $this->makeRequest('/reference/payment-types', self::METHOD_GET); } /** * Редактирование типа оплаты * * @param array $paymentType - информация о типе оплаты - * @return array + * @return ApiResponse */ public function paymentTypesEdit($paymentType) { - $dataJson = json_encode($paymentType); - $this->parameters['paymentType'] = $dataJson; - - $url = $this->apiUrl.'reference/payment-types/'.$paymentType['code'].'/edit'; - $result = $this->curlRequest($url, 'POST'); - return $result; + if (!isset($paymentType['code'])) { + throw new \InvalidArgumentException('Data must contain "code" parameter.'); + } + + return $this->makeRequest( + '/reference/payment-types/' . $paymentType['code'] . '/edit', + self::METHOD_POST, + array( + 'paymentType' => json_encode($paymentType) + ) + ); } /** * Получение списка статусов оплаты * - * @return array - массив статусов оплаты + * @return ApiResponse */ public function paymentStatusesList() { - $url = $this->apiUrl.'reference/payment-statuses'; - $result = $this->curlRequest($url); - return $result; + return $this->makeRequest('/reference/payment-statuses', self::METHOD_GET); } /** * Редактирование статуса оплаты * * @param array $paymentStatus - информация о статусе оплаты - * @return array + * @return ApiResponse */ public function paymentStatusesEdit($paymentStatus) { - $dataJson = json_encode($paymentStatus); - $this->parameters['paymentStatus'] = $dataJson; - - $url = $this->apiUrl.'reference/payment-statuses/'.$paymentStatus['code'].'/edit'; - $result = $this->curlRequest($url, 'POST'); - return $result; + if (!isset($paymentStatus['code'])) { + throw new \InvalidArgumentException('Data must contain "code" parameter.'); + } + + return $this->makeRequest( + '/reference/payment-statuses/' . $paymentStatus['code'] . '/edit', + self::METHOD_POST, + array( + 'paymentStatus' => json_encode($paymentStatus) + ) + ); } /** * Получение списка типов заказа * - * @return array - массив типов заказа + * @return ApiResponse */ public function orderTypesList() { - $url = $this->apiUrl.'reference/order-types'; - $result = $this->curlRequest($url); - return $result; + return $this->makeRequest('/reference/order-types', self::METHOD_GET); } /** * Редактирование типа заказа * * @param array $orderType - информация о типе заказа - * @return array + * @return ApiResponse */ public function orderTypesEdit($orderType) { - $dataJson = json_encode($orderType); - $this->parameters['orderType'] = $dataJson; - - $url = $this->apiUrl.'reference/order-types/'.$orderType['code'].'/edit'; - $result = $this->curlRequest($url, 'POST'); - return $result; + if (!isset($orderType['code'])) { + throw new \InvalidArgumentException('Data must contain "code" parameter.'); + } + + return $this->makeRequest( + '/reference/order-types/' . $orderType['code'] . '/edit', + self::METHOD_POST, + array( + 'orderType' => json_encode($orderType) + ) + ); } /** * Получение списка способов оформления заказа * - * @return array - массив способов оформления заказа + * @return ApiResponse */ public function orderMethodsList() { - $url = $this->apiUrl.'reference/order-methods'; - $result = $this->curlRequest($url); - return $result; + return $this->makeRequest('/reference/order-methods', self::METHOD_GET); } /** * Редактирование способа оформления заказа * * @param array $orderMethod - информация о способе оформления заказа - * @return array + * @return ApiResponse */ public function orderMethodsEdit($orderMethod) { - $dataJson = json_encode($orderMethod); - $this->parameters['orderMethod'] = $dataJson; - - $url = $this->apiUrl.'reference/order-methods/'.$orderMethod['code'].'/edit'; - $result = $this->curlRequest($url, 'POST'); - return $result; + if (!isset($orderMethod['code'])) { + throw new \InvalidArgumentException('Data must contain "code" parameter.'); + } + + return $this->makeRequest( + '/reference/order-methods/' . $orderMethod['code'] . '/edit', + self::METHOD_POST, + array( + 'orderMethod' => json_encode($orderMethod) + ) + ); } /** * Получение списка статусов заказа * - * @return array - массив статусов заказа + * @return ApiResponse */ public function orderStatusesList() { - $url = $this->apiUrl.'reference/statuses'; - $result = $this->curlRequest($url); - return $result; + return $this->makeRequest('/reference/statuses', self::METHOD_GET); + } + + /** + * Получение списка сайтов + * + * @return ApiResponse + */ + public function sitesList() + { + return $this->makeRequest('/reference/sites', self::METHOD_GET); } /** * Редактирование статуса заказа * * @param array $status - информация о статусе заказа - * @return array + * @return ApiResponse */ public function orderStatusEdit($status) { - $dataJson = json_encode($status); - $this->parameters['status'] = $dataJson; - - $url = $this->apiUrl.'reference/statuses/'.$status['code'].'/edit'; - $result = $this->curlRequest($url, 'POST'); - return $result; + if (!isset($status['code'])) { + throw new \InvalidArgumentException('Data must contain "code" parameter.'); + } + + return $this->makeRequest( + '/reference/statuses/' . $status['code'] . '/edit', + self::METHOD_POST, + array( + 'status' => json_encode($status) + ) + ); } /** * Получение списка групп статусов заказа * - * @return array - массив групп статусов заказа + * @return ApiResponse */ public function orderStatusGroupsList() { - $url = $this->apiUrl.'reference/status-groups'; - $result = $this->curlRequest($url); - return $result; + return $this->makeRequest('/reference/status-groups', self::METHOD_GET); } /** * Обновление статистики * - * @return array - статус вып обновления + * @return ApiResponse */ public function statisticUpdate() { - $url = $this->apiUrl.'statistic/update'; - $result = $this->curlRequest($url); - return $result; + return $this->makeRequest('/statistic/update', self::METHOD_GET); } /** @@ -492,7 +577,7 @@ class RestApi { return $this->generatedAt; } - + protected function ensureDateTime($value) { if ($value instanceof \DateTime) { @@ -503,79 +588,102 @@ class RestApi return $value; } - - protected function getErrorMessage($response) + + /** + * Check ID parameter + * + * @param string $by + * @return bool + */ + protected function checkIdParameter($by) { - $str = ''; - if (isset($response['message'])) - $str = $response['message']; - elseif (isset($response[0]['message'])) - $str = $response[0]['message']; - elseif (isset($response['error']) && isset($response['error']['message'])) - $str = $response['error']['message']; - elseif (isset($response['errorMsg'])) - $str = $response['errorMsg']; - - if (isset($response['errors']) && sizeof($response['errors'])) { - foreach ($response['errors'] as $error) - $str .= '. ' . $error; + $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; + } + + /** + * Make HTTP request + * + * @param string $path + * @param string $method (default: 'GET') + * @param array $parameters (default: array()) + * @param int $timeout + * @return ApiResponse + */ + public function makeRequest($path, $method, $parameters = array(), $timeout = 30) + { + $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) + )); } - if (!strlen($str)) - return 'Application Error'; + $parameters = array_merge($this->defaultParameters, $parameters); - return $str; - } - - protected function curlRequest($url, $method = 'GET', $format = 'json') - { - if ($method == 'GET' && !is_null($this->parameters)) - $url .= '?'.http_build_query($this->parameters); + $path = $this->url . $path; + if (self::METHOD_GET === $method && sizeof($parameters)) { + $path .= '?' . http_build_query($parameters); + } $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_FAILONERROR, FALSE); - //curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// allow redirects + curl_setopt($ch, CURLOPT_URL, $path); + curl_setopt($ch, CURLOPT_FAILONERROR, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return into a variable - curl_setopt($ch, CURLOPT_TIMEOUT, 30); // times out after 30s - //curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_TIMEOUT, (int) $timeout); // times out after 30s + // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + // curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // allow redirects - - if ($method == 'POST') - { + if (self::METHOD_POST === $method) { curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $this->parameters); + curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters); } - $response = curl_exec($ch); + $responseBody = curl_exec($ch); $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - unset($this->parameters); - /* Сброс массива с параметрами */ - $this->parameters = array('apiKey' => $this->apiKey); $errno = curl_errno($ch); $error = curl_error($ch); curl_close($ch); - if ($errno) - throw new Exception\CurlException($error, $errno); - - $result = json_decode($response, true); - - if ($statusCode >= 400 || isset($result['success']) && $result['success'] === false) { - throw new Exception\ApiException($this->getErrorMessage($result), $statusCode); + if ($errno) { + throw new CurlException($error, $errno); } - + + $result = json_decode($responseBody, true); + if (isset($result['generatedAt'])) { $this->generatedAt = new \DateTime($result['generatedAt']); unset($result['generatedAt']); } - - unset($result['success']); - - if (count($result) == 0) - return true; - - return reset($result); + + return new ApiResponse($statusCode, $responseBody); } } diff --git a/intaro.intarocrm/classes/general/RestNormalizer.php b/intaro.intarocrm/classes/general/RestNormalizer.php new file mode 100644 index 00000000..31bd5370 --- /dev/null +++ b/intaro.intarocrm/classes/general/RestNormalizer.php @@ -0,0 +1,412 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Dmitry Mamontov nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package restnormalizer + * @author Dmitry Mamontov + * @copyright 2015 Dmitry Mamontov + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @since File available since Release 1.0.0 + */ + + /** + * RestNormalizer - The main class + * + * @author Dmitry Mamontov + * @copyright 2015 Dmitry Mamontov + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: 1.0.0 + * @link https://github.com/dmamontov/restnormalizer/ + * @since Class available since Release 1.0.0 + */ + +class RestNormalizer +{ + /** + * Cleanup of null values + * @var boolean + * @access public + */ + public $clear = true; + + /** + * Sorted file validation + * @var array + * @access private + */ + private $validation = array(); + + /** + * File validation + * @var array + * @access private + */ + private $originalValidation = array(); + + /** + * Class constructor + * @return void + * @access public + * @final + */ + final public function __construct() + { + if (function_exists('date_default_timezone_set') && function_exists('date_default_timezone_get')) { + date_default_timezone_set(@date_default_timezone_get()); + } + } + + /** + * Installation file validation + * @param string $file The path to the file validation + * @return void + * @access public + * @final + */ + final public function setValidation($file) + { + if (is_null($file) || is_file($file) === false + || json_decode(file_get_contents($file)) === null + || $this->parseConfig($file) === false) { + ICrmOrderActions::eventLog('RestNormalizer', 'intaro.intarocrm', 'Incorrect file normalize.'); + return false; + } + } + + /** + * Parsing the file validation + * @param string $file The path to the file validation + * @return boolean + * @access private + * @final + */ + final private function parseConfig($file) + { + if (json_decode(file_get_contents($file)) !== null) { + $this->originalValidation = json_decode(file_get_contents($file), true); + return true; + } else { + return false; + } + } + + /** + * Starting the process of normalization of the data + * @param array $data The key is to sort the data validation + * @param string $key Data normalization + * @return array + * @access public + * @final + */ + final public function normalize($data, $key = false) + { + if (is_string($data)) { + $data = json_decode($data, true); + } + + if (is_string($key) && isset($this->originalValidation[ $key ])) { + $this->validation = $this->originalValidation[ $key ]; + } else { + $this->validation = $this->originalValidation; + } + + if (!is_array($data) || count($data) < 1) { + ICrmOrderActions::eventLog('RestNormalizer', 'intaro.intarocrm', 'Incorrect data array.'); + return false; + } + + return $this->formatting($data); + } + + /** + * Data formatting + * @param array $data The key is to sort the data validation + * @param boolean $skip Skip perform methods intended for the first run + * @return array + * @access private + * @final + */ + final private function formatting($data, $skip = false) + { + $formatted = array(); + + foreach ($data as $code => $value) { + + if (isset($this->validation[ $code ]) && $this->validation[ $code ]['type'] == 'skip') { + $formatted[ $code ] = $value; + }elseif (isset($this->validation[ $code ]) && is_array($value) === false) { + $formatted[ $code ] = $this->setFormat($value, $this->validation[ $code ]); + } elseif (is_array($value)) { + $formatted[ $code ] = $this->formatting($value, true); + } + + if ($formatted[ $code ] === null || $formatted[ $code ] == '' || count($formatted[ $code ]) < 1) { + if ($this->clear === true) { + unset($formatted[ $code ]); + } + + if (isset($this->validation[ $code ]['required']) && $this->validation[ $code ]['required'] === true) { + $formatted = array(); + break; + } + } + + } + + if ($skip === false) { + foreach ($this->validation as $code => $valid) { + if (isset($valid['required']) && $valid['required'] === true && isset($formatted[ $code ]) === false) { + ICrmOrderActions::eventLog('RestNormalizer', 'intaro.intarocrm', "NOT VALID: $code"); + } + } + + $formatted = $this->multiConvert($formatted); + } + + return count($formatted) < 1 ? false : $formatted; + } + + /** + * Formatting data depending on the type + * @param mixed $data The value to be formatted + * @param array $validation The data for the current data type validation + * @return mixed + * @access private + * @final + */ + final private function setFormat($data, $validation) + { + $format = null; + + switch ($validation['type']) { + case 'string': + $format = $this->setString($data, $validation); + break; + case 'int': + $format = $this->setInt($data, $validation); + break; + case 'double': + $format = $this->setDouble($data, $validation); + break; + case 'bool': + $format = $this->setBool($data, $validation); + break; + case 'datetime': + $format = $this->setDateTime($data, $validation); + break; + case 'enum': + $format = $this->setEnum($data, $validation); + break; + } + + return $format; + } + + /** + * Formatting data for strings + * @param string $data String to formatting + * @param array $validation The data for the current data type validation + * @return string + * @access private + * @final + */ + final private function setString($data, $validation) + { + $data = trim((string) $data); + + if (isset($validation['default']) && is_string($validation['default']) && trim($validation['default']) != '' + && ($data == '' || is_string($data) === false)) { + $data = trim($validation['default']); + } elseif ($data == '' || is_string($data) === false) { + return null; + } elseif (isset($validation['min']) && mb_strlen($data) < $validation['min']) { + $pad = isset($validation['pad']) && mb_strlen($validation['pad']) == 1 ? $validation['pad'] : ' '; + $data .= str_repeat($pad, $validation['min'] - mb_strlen($data)); + }elseif (isset($validation['max']) && mb_strlen($data) > $validation['max']) { + $data = mb_substr($data, 0, $validation['max']); + } + + return (string) $data; + } + + /** + * Formatting data for integers + * @param integer $data Integer to formatting + * @param array $validation The data for the current data type validation + * @return integer + * @access private + * @final + */ + final private function setInt($data, $validation) + { + if (isset($validation['default']) && is_numeric($validation['default']) && is_numeric($data) === false) { + $data = $validation['default']; + } elseif (is_numeric($data) === false) { + return null; + } elseif (isset($validation['min']) && $data < $validation['min']) { + $data += $validation['min'] - $data; + } elseif (isset($validation['max']) && $data > $validation['max']) { + $data -= $data - $validation['max']; + } + + return (int) $data; + } + + /** + * Formatting data for floating-point numbers + * @param float $data Floating-point number to formatting + * @param array $validation The data for the current data type validation + * @return float + * @access private + * @final + */ + final private function setDouble($data, $validation) + { + if (isset($validation['default']) && is_numeric($validation['default']) && is_numeric($data) === false) { + $data = $validation['default']; + } elseif (is_numeric($data) === false) { + return null; + } elseif (isset($validation['min']) && $data < $validation['min']) { + $data += $validation['min'] - $data; + } elseif (isset($validation['max']) && $data > $validation['max']) { + $data -= $data - $validation['max']; + } + + if (isset($validation['decimals'])) { + $data = number_format($data, $validation['decimals'], '.', ''); + } + + return (double) $data; + } + + /** + * Formatting data for logical values + * @param boolean $data Boolean value to formatting + * @param array $validation The data for the current data type validation + * @return boolean + * @access private + * @final + */ + final private function setBool($data, $validation) + { + if (isset($validation['default']) && is_bool($validation['default']) && is_bool($data) === false) { + $data = $validation['default']; + } elseif (is_bool($data) === false) { + return null; + } + + return (bool) $data; + } + + /** + * Formatting data for date and time + * @param mixed $data Date and time of to formatting + * @param array $validation The data for the current data type validation + * @param boolean $skip Skip perform methods intended for the first run + * @return mixed + * @access private + * @final + */ + final private function setDateTime($data, $validation, $skip = false) + { + if (is_a($data, 'DateTime') && isset($validation['format'])) { + $data = (string) $data->format($validation['format']); + } elseif (is_string($data) && isset($validation['format']) && strtotime($data) !== false) { + $data = (string) date($validation['format'], strtotime($data)); + } elseif (is_numeric($data) && isset($validation['format'])) { + $data = (string) date($validation['format'], (int) $data); + } elseif (is_numeric($data)) { + $data = (int) $data; + } elseif (isset($validation['format'])) { + $data = (string) date($validation['format']); + } elseif (isset($validation['default']) && $skip === false) { + $data = $this->setDateTime(time(), $validation, true); + } else { + return null; + } + + return $data; + } + + /** + * Formatting data for enum + * @param string $data Enum to formatting + * @param array $validation The data for the current data type validation + * @return string + * @access private + * @final + */ + final private function setEnum($data, $validation) + { + if (isset($validation['values']) === false || count($validation['values']) < 1) { + return null; + } elseif (isset($validation['default']) && in_array($validation['default'], $validation['values']) === false) { + return null; + } elseif (in_array($data, $validation['values']) === false + && isset($validation['default']) && in_array($validation['default'], $validation['values'])) { + $data = $validation['default']; + } elseif (in_array($data, $validation['values']) === false) { + return null; + } + + return $data; + } + + /** + * Installing the specified encoding + * @param array $data The original dataset + * @return array + * @access private + * @final + */ + final private function multiConvert($data) + { + global $APPLICATION; + + if (is_array($data)) { + foreach ($data as $code => $value) { + $data[$APPLICATION->ConvertCharset($code, SITE_CHARSET, 'utf-8')] = is_array($value) + ? $this->multiConvert($value) + : $APPLICATION->ConvertCharset($value, SITE_CHARSET, 'utf-8'); + } + return $data; + } else { + return $APPLICATION->ConvertCharset($data, SITE_CHARSET, 'utf-8'); + } + + return $data; + } +} +?> \ No newline at end of file diff --git a/intaro.intarocrm/classes/general/config/options.xml b/intaro.intarocrm/classes/general/config/options.xml new file mode 100644 index 00000000..95c4ce1f --- /dev/null +++ b/intaro.intarocrm/classes/general/config/options.xml @@ -0,0 +1,41 @@ + + + + Физ. лицо + Юр. лицо + ИП + + + Ф.И.О. + Телефон + E-mail + Адрес (строкой) + Город + Индекс + Улица + Строение + Квартира + Домофон + Этаж + Подъезд + Строение / корпус + + Полное наименование + Адрес регистрации (Юридический адрес) + ИНН + ОКПО + БИК + Банк + Адрес банка + Корреспондентский счет + Расчетный счет + + КПП + ОГРН + + ОГРНИП + Номер свидетельства + Дата свидетельства + + + \ No newline at end of file diff --git a/intaro.intarocrm/classes/general/config/retailcrm.json b/intaro.intarocrm/classes/general/config/retailcrm.json new file mode 100644 index 00000000..43155083 --- /dev/null +++ b/intaro.intarocrm/classes/general/config/retailcrm.json @@ -0,0 +1,379 @@ +{ + "customers": { + "externalId": { + "type": "string", + "required": true + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "patronymic": { + "type": "string" + }, + "email": { + "type": "string" + }, + "number": { + "type": "string" + }, + "site": { + "type": "string" + }, + "index": { + "type": "string" + }, + "country": { + "type": "string" + }, + "region": { + "type": "string" + }, + "city": { + "type": "string" + }, + "street": { + "type": "string" + }, + "building": { + "type": "string" + }, + "flat": { + "type": "string" + }, + "intercomCode": { + "type": "string" + }, + "floor": { + "type": "int" + }, + "block": { + "type": "int" + }, + "house": { + "type": "string" + }, + "metro": { + "type": "string" + }, + "notes": { + "type": "string" + }, + "text": { + "type": "string" + }, + "createdAt": { + "type": "datetime", + "format": "Y-m-d H:i:s" + }, + "vip": { + "type": "bool", + "default": false + }, + "bad": { + "type": "bool", + "default": false + }, + "commentary": { + "type": "string" + }, + "customFields": { + "type": "skip" + }, + "contragentType": { + "type": "enum", + "default": "individual", + "values": ["individual", "legal-entity", "enterpreneur"] + }, + "legalName": { + "type": "string" + }, + "legalAddress": { + "type": "string" + }, + "INN": { + "type": "string" + }, + "OKPO": { + "type": "string" + }, + "KPP": { + "type": "string" + }, + "OGRN": { + "type": "string" + }, + "OGRNIP": { + "type": "string" + }, + "certificateNumber": { + "type": "string" + }, + "certificateDate": { + "type": "datetime", + "format": "Y-m-d" + }, + "BIK": { + "type": "string" + }, + "bank": { + "type": "string" + }, + "bankAddress": { + "type": "string" + }, + "corrAccount": { + "type": "string" + }, + "bankAccount": { + "type": "string" + }, + "managerId": { + "type": "int" + } + }, + "orders": { + "number": { + "type": "string" + }, + "externalId": { + "type": "string", + "required": true + }, + "createdAt": { + "type": "datetime", + "format": "Y-m-d H:i:s" + }, + "discount": { + "type": "double", + "default": 0, + "min": 0, + "decimals": 2 + }, + "discountPercent": { + "type": "double", + "default": 0, + "max": 100, + "min": 0, + "decimals": 2 + }, + "mark": { + "type": "int", + "max": 10, + "min": 0 + }, + "markDatetime": { + "type": "datetime", + "format": "Y-m-d H:i:s" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "patronymic": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "additionalPhone": { + "type": "string" + }, + "email": { + "type": "string" + }, + "site": { + "type": "string" + }, + "call": { + "type": "bool", + "default": false + }, + "expired": { + "type": "bool", + "default": false + }, + "customerComment": { + "type": "string" + }, + "managerComment": { + "type": "string" + }, + "paymentDetail": { + "type": "string" + }, + "statusComment": { + "type": "string" + }, + "customFields": { + "type": "skip" + }, + "contragentType": { + "type": "enum", + "default": "individual", + "values": ["individual", "legal-entity", "enterpreneur"] + }, + "legalName": { + "type": "string" + }, + "legalAddress": { + "type": "string" + }, + "INN": { + "type": "string" + }, + "OKPO": { + "type": "string" + }, + "KPP": { + "type": "string" + }, + "OGRN": { + "type": "string" + }, + "OGRNIP": { + "type": "string" + }, + "certificateNumber": { + "type": "string" + }, + "certificateDate": { + "type": "datetime", + "format": "Y-m-d" + }, + "BIK": { + "type": "string" + }, + "bank": { + "type": "string" + }, + "bankAddress": { + "type": "string" + }, + "corrAccount": { + "type": "string" + }, + "bankAccount": { + "type": "string" + }, + "orderType": { + "type": "string" + }, + "orderMethod": { + "type": "string" + }, + "customerId": { + "type": "string" + }, + "managerId": { + "type": "int" + }, + "paymentType": { + "type": "string" + }, + "paymentStatus": { + "type": "string" + }, + "status": { + "type": "string" + }, + "sourceId": { + "type": "string" + }, + "initialPrice": { + "type": "double", + "default": 0, + "min": 0, + "decimals": 2 + }, + "quantity": { + "type": "double", + "default": 1, + "min": 1, + "decimals": 1 + }, + "properties": { + "type": "skip" + }, + "productId": { + "type": "string" + }, + "productName": { + "type": "string" + }, + "comment": { + "type": "string" + }, + "purchasePrice": { + "type": "double", + "default": 0, + "min": 0, + "decimals": 1 + }, + "code": { + "type": "string" + }, + "integrationCode": { + "type": "string" + }, + "data": { + "type": "skip" + }, + "service": { + "type": "skip" + }, + "cost": { + "type": "string" + }, + "date": { + "type": "datetime", + "format": "Y-m-d" + }, + "index": { + "type": "string" + }, + "country": { + "type": "string" + }, + "region": { + "type": "string" + }, + "city": { + "type": "string" + }, + "street": { + "type": "string" + }, + "building": { + "type": "string" + }, + "flat": { + "type": "string" + }, + "intercomCode": { + "type": "string" + }, + "floor": { + "type": "int" + }, + "block": { + "type": "int" + }, + "house": { + "type": "string" + }, + "metro": { + "type": "string" + }, + "notes": { + "type": "string" + }, + "text": { + "type": "string" + } + } +} \ No newline at end of file diff --git a/intaro.intarocrm/classes/general/events/ICrmOrderEvent.php b/intaro.intarocrm/classes/general/events/ICrmOrderEvent.php index 0bc1adbf..3fc2b04f 100644 --- a/intaro.intarocrm/classes/general/events/ICrmOrderEvent.php +++ b/intaro.intarocrm/classes/general/events/ICrmOrderEvent.php @@ -14,7 +14,11 @@ class ICrmOrderEvent { protected static $CRM_PAYMENT = 'payment_arr'; //order payment Y/N protected static $CRM_ORDER_LAST_ID = 'order_last_id'; protected static $CRM_ORDER_PROPS = 'order_props'; + protected static $CRM_LEGAL_DETAILS = 'legal_details'; + protected static $CRM_CUSTOM_FIELDS = 'custom_fields'; + protected static $CRM_CONTRAGENT_TYPE = 'contragent_type'; protected static $CRM_ORDER_FAILED_IDS = 'order_failed_ids'; + protected static $CRM_SITES_LIST = 'sites_list'; /** * onBeforeOrderAdd @@ -54,13 +58,12 @@ class ICrmOrderEvent { * @param mixed $arFields - Order arFields */ function onUpdateOrder($ID, $arFields) { - if(isset($GLOBALS['INTARO_CRM_ORDER_ADD']) && $GLOBALS['INTARO_CRM_ORDER_ADD']) return; if(isset($GLOBALS['INTARO_CRM_ORDER_RESERVE']) && $GLOBALS['INTARO_CRM_ORDER_RESERVE']) return; - + if(isset($GLOBALS['INTARO_CRM_FROM_HISTORY']) && $GLOBALS['INTARO_CRM_FROM_HISTORY']) return; @@ -125,8 +128,7 @@ class ICrmOrderEvent { ICrmOrderActions::eventLog('ICrmOrderEvent::writeDataOnOrderCreate', 'catalog', 'module not found'); return true; } - - $GLOBALS['INTARO_CRM_ORDER_ADD'] = false; + $GLOBALS['INTARO_CRM_FROM_HISTORY'] = false; $api_host = COption::GetOptionString(self::$MODULE_ID, self::$CRM_API_HOST_OPTION, 0); @@ -138,21 +140,29 @@ class ICrmOrderEvent { $optionsPayTypes = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PAYMENT_TYPES, 0)); $optionsPayStatuses = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PAYMENT_STATUSES, 0)); // --statuses $optionsPayment = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PAYMENT, 0)); + $optionsSitesList = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_SITES_LIST, 0)); $optionsOrderProps = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_PROPS, 0)); + $optionsLegalDetails = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_LEGAL_DETAILS, 0)); + $optionsContragentType = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_CONTRAGENT_TYPE, 0)); + $optionsCustomFields = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_CUSTOM_FIELDS, 0)); - $api = new IntaroCrm\RestApi($api_host, $api_key); + $api = new RetailCrm\RestApi($api_host, $api_key); $arParams = ICrmOrderActions::clearArr(array( - 'optionsOrderTypes' => $optionsOrderTypes, - 'optionsDelivTypes' => $optionsDelivTypes, - 'optionsPayTypes' => $optionsPayTypes, - 'optionsPayStatuses' => $optionsPayStatuses, - 'optionsPayment' => $optionsPayment, - 'optionsOrderProps' => $optionsOrderProps + 'optionsOrderTypes' => $optionsOrderTypes, + 'optionsDelivTypes' => $optionsDelivTypes, + 'optionsPayTypes' => $optionsPayTypes, + 'optionsPayStatuses' => $optionsPayStatuses, + 'optionsPayment' => $optionsPayment, + 'optionsOrderProps' => $optionsOrderProps, + 'optionsLegalDetails' => $optionsLegalDetails, + 'optionsContragentType' => $optionsContragentType, + 'optionsSitesList' => $optionsSitesList, + 'optionsCustomFields' => $optionsCustomFields )); - + $arOrder = CSaleOrder::GetById($ID); - + if (is_array($arFields) && !empty($arFields)) { $arFieldsNew = array( @@ -168,9 +178,13 @@ class ICrmOrderEvent { $arFieldsNew = array_merge($arFieldsNew, $arFields); $arOrder = $arFieldsNew; } - - $result = ICrmOrderActions::orderCreate($arOrder, $api, $arParams, true); - + if(count($optionsSitesList)>1){ + $result = ICrmOrderActions::orderCreate($arOrder, $api, $arParams, true, $optionsSitesList[$arOrder['LID']]); + } + else{ + $result = ICrmOrderActions::orderCreate($arOrder, $api, $arParams, true); + } + if(!$result) { ICrmOrderActions::eventLog('ICrmOrderEvent::writeDataOnOrderCreate', 'ICrmOrderActions::orderCreate', 'error during creating order'); return false; @@ -217,7 +231,7 @@ class ICrmOrderEvent { //saved cat params $optionsPayStatuses = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PAYMENT_STATUSES, 0)); // --statuses - $api = new IntaroCrm\RestApi($api_host, $api_key); + $api = new RetailCrm\RestApi($api_host, $api_key); $order = array(); @@ -239,14 +253,9 @@ class ICrmOrderEvent { try { $api->orderEdit($order); - } catch (\IntaroCrm\Exception\ApiException $e) { + } catch (\RetailCrm\Exception\CurlException $e) { ICrmOrderActions::eventLog( - 'ICrmOrderEvent::onSaleCancelOrder', 'IntaroCrm\RestApi::orderEdit', - $e->getCode() . ': ' . $e->getMessage() - ); - } catch (\IntaroCrm\Exception\CurlException $e) { - ICrmOrderActions::eventLog( - 'ICrmOrderEvent::onSaleCancelOrder', 'IntaroCrm\RestApi::orderEdit::CurlException', + 'ICrmOrderEvent::onSaleCancelOrder', 'RetailCrm\RestApi::orderEdit::CurlException', $e->getCode() . ': ' . $e->getMessage() ); } @@ -291,7 +300,7 @@ class ICrmOrderEvent { //saved cat params $optionsPayment = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PAYMENT, 0)); - $api = new IntaroCrm\RestApi($api_host, $api_key); + $api = new RetailCrm\RestApi($api_host, $api_key); $order = array( 'externalId' => (int) $ID, @@ -302,14 +311,9 @@ class ICrmOrderEvent { try { $api->orderEdit($order); - } catch (\IntaroCrm\Exception\ApiException $e) { + } catch (\RetailCrm\Exception\CurlException $e) { ICrmOrderActions::eventLog( - 'ICrmOrderEvent::onSalePayOrder', 'IntaroCrm\RestApi::orderEdit', - $e->getCode() . ': ' . $e->getMessage() - ); - } catch (\IntaroCrm\Exception\CurlException $e) { - ICrmOrderActions::eventLog( - 'ICrmOrderEvent::onSalePayOrder', 'IntaroCrm\RestApi::orderEdit::CurlException', + 'ICrmOrderEvent::onSalePayOrder', 'RetailCrm\RestApi::orderEdit::CurlException', $e->getCode() . ': ' . $e->getMessage() ); } diff --git a/intaro.intarocrm/description.ru b/intaro.intarocrm/description.ru new file mode 100644 index 00000000..52611166 --- /dev/null +++ b/intaro.intarocrm/description.ru @@ -0,0 +1,13 @@ +- API +- . +- +- +- +- +- id +- $_SERVER['SERVER_NAME'] +- +- +- +- +- \ No newline at end of file diff --git a/intaro.intarocrm/export/export_run.php b/intaro.intarocrm/export/export_run.php index 160ea9db..983905a2 100644 --- a/intaro.intarocrm/export/export_run.php +++ b/intaro.intarocrm/export/export_run.php @@ -10,6 +10,13 @@ if (!CModule::IncludeModule("catalog")) if (!CModule::IncludeModule("intaro.intarocrm")) return; +$rsSites = CSite::GetList($by, $sort, array('ACTIVE' => 'Y')); +while ($ar = $rsSites->Fetch()){ + if($ar['DEF'] == 'Y'){ + $SERVER_NAME = $ar['SERVER_NAME'];//разделить потом с учетом многосайтовости + } +} + $iblockProperties = Array( "article" => "article", "manufacturer" => "manufacturer", @@ -69,6 +76,7 @@ $loader->propertiesUnitSKU = $IBLOCK_PROPERTY_UNIT_SKU; $loader->propertiesProduct = $IBLOCK_PROPERTY_PRODUCT; $loader->propertiesUnitProduct = $IBLOCK_PROPERTY_UNIT_PRODUCT; $loader->filename = $SETUP_FILE_NAME; +$loader->serverName = $SERVER_NAME; $loader->application = $APPLICATION; $loader->loadPurchasePrice = $LOAD_PURCHASE_PRICE == 'Y'; $loader->Load(); \ No newline at end of file diff --git a/intaro.intarocrm/include.php b/intaro.intarocrm/include.php old mode 100755 new mode 100644 index d836cd19..8d2ce2c0 --- a/intaro.intarocrm/include.php +++ b/intaro.intarocrm/include.php @@ -2,11 +2,13 @@ CModule::AddAutoloadClasses( 'intaro.intarocrm', // module name array ( - 'IntaroCrm\RestApi' => 'classes/general/RestApi.php', - 'ICrmOrderActions' => 'classes/general/ICrmOrderActions.php', - 'ICMLLoader' => 'classes/general/ICMLLoader.php', - 'ICrmOrderEvent' => 'classes/general/events/ICrmOrderEvent.php', - 'IntaroCrm\Exception\ApiException' => 'classes/general/Exception/ApiException.php', - 'IntaroCrm\Exception\CurlException' => 'classes/general/Exception/CurlException.php' + 'RestNormalizer' => 'classes/general/RestNormalizer.php', + 'RetailCrm\RestApi' => 'classes/general/RestApi.php', + 'RetailCrm\Response\ApiResponse' => 'classes/general/Response/ApiResponse.php', + 'ICrmOrderActions' => 'classes/general/ICrmOrderActions.php', + 'ICMLLoader' => 'classes/general/ICMLLoader.php', + 'ICrmOrderEvent' => 'classes/general/events/ICrmOrderEvent.php', + 'RetailCrm\Exception\InvalidJsonException' => 'classes/general/Exception/InvalidJsonException.php', + 'RetailCrm\Exception\CurlException' => 'classes/general/Exception/CurlException.php', ) ); \ No newline at end of file diff --git a/intaro.intarocrm/install/index.php b/intaro.intarocrm/install/index.php old mode 100755 new mode 100644 index 653541f7..64df00a7 --- a/intaro.intarocrm/install/index.php +++ b/intaro.intarocrm/install/index.php @@ -24,6 +24,7 @@ class intaro_intarocrm extends CModule { var $INTARO_CRM_EXPORT = 'intarocrm'; var $CRM_API_HOST_OPTION = 'api_host'; var $CRM_API_KEY_OPTION = 'api_key'; + var $CRM_SITES_LIST= 'sites_list'; var $CRM_ORDER_TYPES_ARR = 'order_types_arr'; var $CRM_DELIVERY_TYPES_ARR = 'deliv_types_arr'; var $CRM_DELIVERY_SERVICES_ARR = 'deliv_services_arr'; @@ -31,8 +32,10 @@ class intaro_intarocrm extends CModule { var $CRM_PAYMENT_STATUSES = 'pay_statuses_arr'; var $CRM_PAYMENT = 'payment_arr'; //order payment Y/N var $CRM_ORDER_LAST_ID = 'order_last_id'; - var $CRM_ORDER_SITES = 'sites_ids'; var $CRM_ORDER_PROPS = 'order_props'; + var $CRM_LEGAL_DETAILS = 'legal_details'; + var $CRM_CUSTOM_FIELDS = 'custom_fields'; + var $CRM_CONTRAGENT_TYPE = 'contragent_type'; var $CRM_ORDER_DISCHARGE = 'order_discharge'; var $CRM_ORDER_FAILED_IDS = 'order_failed_ids'; var $CRM_ORDER_HISTORY_DATE = 'order_history_date'; @@ -47,7 +50,7 @@ class intaro_intarocrm extends CModule { include($path . "/version.php"); $this->MODULE_VERSION = $arModuleVersion["VERSION"]; $this->MODULE_VERSION_DATE = $arModuleVersion["VERSION_DATE"]; - $this->MODULE_NAME = GetMessage('MODULE_NAME'); + $this->MODULE_NAME = GetMessage('INTARO_MODULE_NAME'); $this->MODULE_DESCRIPTION = GetMessage('MODULE_DESCRIPTION'); $this->PARTNER_NAME = GetMessage('MODULE_PARTNER_NAME'); $this->PARTNER_URI = GetMessage('MODULE_PARTNER_URI'); @@ -73,77 +76,55 @@ class intaro_intarocrm extends CModule { } include($this->INSTALL_PATH . '/../classes/general/RestApi.php'); + include($this->INSTALL_PATH . '/../classes/general/Response/ApiResponse.php'); include($this->INSTALL_PATH . '/../classes/general/ICrmOrderActions.php'); include($this->INSTALL_PATH . '/../classes/general/ICMLLoader.php'); - include($this->INSTALL_PATH . '/../classes/general/Exception/ApiException.php'); + include($this->INSTALL_PATH . '/../classes/general/Exception/InvalidJsonException.php'); include($this->INSTALL_PATH . '/../classes/general/Exception/CurlException.php'); + include($this->INSTALL_PATH . '/../classes/general/RestNormalizer.php'); $step = intval($_REQUEST['step']); - $arResult['orderProps'] = array( - array( - 'NAME' => GetMessage('FIO'), - 'ID' => 'fio' - ), - array( - 'NAME' => GetMessage('PHONE'), - 'ID' => 'phone' - ), - array( - 'NAME' => GetMessage('EMAIL'), - 'ID' => 'email' - ), - array( - 'NAME' => GetMessage('ADDRESS'), - 'ID' => 'text' - ), - // address - /* array( - 'NAME' => GetMessage('COUNTRY'), - 'ID' => 'country' - ), - array( - 'NAME' => GetMessage('REGION'), - 'ID' => 'region' - ), - array( - 'NAME' => GetMessage('CITY'), - 'ID' => 'city' - ), */ - array( - 'NAME' => GetMessage('ZIP'), - 'ID' => 'index' - ), - array( - 'NAME' => GetMessage('STREET'), - 'ID' => 'street' - ), - array( - 'NAME' => GetMessage('BUILDING'), - 'ID' => 'building' - ), - array( - 'NAME' => GetMessage('FLAT'), - 'ID' => 'flat' - ), - array( - 'NAME' => GetMessage('INTERCOMCODE'), - 'ID' => 'intercomcode' - ), - array( - 'NAME' => GetMessage('FLOOR'), - 'ID' => 'floor' - ), - array( - 'NAME' => GetMessage('BLOCK'), - 'ID' => 'block' - ), - array( - 'NAME' => GetMessage('HOUSE'), - 'ID' => 'house' - ) - ); + if (file_exists($_SERVER["DOCUMENT_ROOT"] . '/bitrix/modules/intaro.intarocrm/classes/general/config/options.xml')) { + $options = simplexml_load_file($_SERVER["DOCUMENT_ROOT"] . '/bitrix/modules/intaro.intarocrm/classes/general/config/options.xml'); + foreach($options->contragents->contragent as $contragent) + { + $type["NAME"] = $APPLICATION->ConvertCharset((string)$contragent, 'utf-8', SITE_CHARSET); + $type["ID"] = (string)$contragent["id"]; + $arResult['contragentType'][] = $type; + unset ($type); + } + foreach($options->fields->field as $field) + { + $type["NAME"] = $APPLICATION->ConvertCharset((string)$field, 'utf-8', SITE_CHARSET); + $type["ID"] = (string)$field["id"]; + + if ($field["group"] == 'custom') { + $arResult['customFields'][] = $type; + } elseif(!$field["group"]){ + $arResult['orderProps'][] = $type; + } else{ + $groups = explode(",", (string)$field["group"]); + foreach($groups as $group){ + $type["GROUP"][] = trim($group); + } + $arResult['legalDetails'][] = $type; + } + unset($type); + } + } + + if($step == 11){ + $arResult['arSites'] = array(); + $rsSites = CSite::GetList($by, $sort, array('ACTIVE' => 'Y')); + while ($ar = $rsSites->Fetch()){ + $arResult['arSites'][] = $ar; + } + if(count($arResult['arSites'])<2){ + $step = 2; + } + } if ($step <= 1) { if (!CModule::IncludeModule("sale")) { $arResult['errCode'] = 'ERR_SALE'; @@ -158,14 +139,80 @@ class intaro_intarocrm extends CModule { } $arResult['arSites'] = array(); - $rsSites = CSite::GetList($by, $sort, array()); + $rsSites = CSite::GetList($by, $sort, array('ACTIVE' => 'Y')); while ($ar = $rsSites->Fetch()) $arResult['arSites'][] = $ar; $APPLICATION->IncludeAdminFile( GetMessage('MODULE_INSTALL_TITLE'), $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step1.php' ); - } else if ($step == 2) { + } else if ($step == 11) { + //new page + if (!CModule::IncludeModule("sale")) { + $arResult['errCode'] = 'ERR_SALE'; + } + + if (!CModule::IncludeModule("iblock")) { + $arResult['errCode'] = 'ERR_IBLOCK'; + } + + if (!CModule::IncludeModule("catalog")) { + $arResult['errCode'] = 'ERR_CATALOG'; + } + + if (isset($arResult['errCode']) && $arResult['errCode']) { + $APPLICATION->IncludeAdminFile( + GetMessage('MODULE_INSTALL_TITLE'), + $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step1.php' + ); + return; + } + + $api_host = htmlspecialchars(trim($_POST[$this->CRM_API_HOST_OPTION])); + $api_key = htmlspecialchars(trim($_POST[$this->CRM_API_KEY_OPTION])); + + // form correct url + $api_host = parse_url($api_host); + if($api_host['scheme'] != 'https') $api_host['scheme'] = 'https'; + $api_host = $api_host['scheme'] . '://' . $api_host['host']; + + if (!$api_host || !$api_key) { + $arResult['errCode'] = 'ERR_FIELDS_API_HOST'; + $APPLICATION->IncludeAdminFile( + GetMessage('MODULE_INSTALL_TITLE'), + $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step1.php' + ); + return; + } + + $this->INTARO_CRM_API = new RetailCrm\RestApi($api_host, $api_key); + //api key ok and sites list + try { + $arResult['sitesList'] = $this->INTARO_CRM_API->sitesList()->sites; + } catch (\RetailCrm\Exception\CurlException $e) { + ICrmOrderActions::eventLog( + 'intaro.crm/install/index.php', 'RetailCrm\RestApi::sitesList', + $e->getCode() . ': ' . $e->getMessage() + ); + + $arResult['errCode'] = 'ERR_' . $e->getCode(); + + $APPLICATION->IncludeAdminFile( + GetMessage('MODULE_INSTALL_TITLE'), + $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step1.php' + ); + + return; + } + + COption::SetOptionString($this->MODULE_ID, $this->CRM_API_HOST_OPTION, $api_host); + COption::SetOptionString($this->MODULE_ID, $this->CRM_API_KEY_OPTION, $api_key); + + $APPLICATION->IncludeAdminFile( + GetMessage('MODULE_INSTALL_TITLE'), + $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step11.php' + ); + } else if ($step == 2) {//доставки, оплаты, типы заказов if (!CModule::IncludeModule("sale")) { $arResult['errCode'] = 'ERR_SALE'; @@ -179,11 +226,6 @@ class intaro_intarocrm extends CModule { $arResult['errCode'] = 'ERR_CATALOG'; } - $arResult['arSites'] = array(); - $rsSites = CSite::GetList($by, $sort, array()); - while ($ar = $rsSites->Fetch()) - $arResult['arSites'][] = $ar; - if (isset($arResult['errCode']) && $arResult['errCode']) { $APPLICATION->IncludeAdminFile( GetMessage('MODULE_INSTALL_TITLE'), @@ -191,29 +233,35 @@ class intaro_intarocrm extends CModule { ); return; } - + + $arResult['arSites'] = array(); + $rsSites = CSite::GetList($by, $sort, array('ACTIVE' => 'Y')); + while ($ar = $rsSites->Fetch()){ + if(!$ar["SERVER_NAME"]){ + $arResult['errCode'] = 'URL_NOT_FOUND'; + $APPLICATION->IncludeAdminFile( + GetMessage('MODULE_INSTALL_TITLE'), + $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step1.php' + ); + return; + } + else{ + $arResult['arSites'][] = $ar; + } + } + if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') && isset($_POST['ajax']) && ($_POST['ajax'] == 1)) { $api_host = COption::GetOptionString($this->MODULE_ID, $this->CRM_API_HOST_OPTION, 0); $api_key = COption::GetOptionString($this->MODULE_ID, $this->CRM_API_KEY_OPTION, 0); - $this->INTARO_CRM_API = new \IntaroCrm\RestApi($api_host, $api_key); + $this->INTARO_CRM_API = new \RetailCrm\RestApi($api_host, $api_key); //prepare crm lists try { - $arResult['orderTypesList'] = $this->INTARO_CRM_API->orderTypesList(); - } catch (\IntaroCrm\Exception\ApiException $e) { + $arResult['orderTypesList'] = $this->INTARO_CRM_API->orderTypesList()->orderTypes; + } catch (\RetailCrm\Exception\CurlException $e) { ICrmOrderActions::eventLog( - 'intaro.crm/install/index.php', 'IntaroCrm\RestApi::orderTypesList', - $e->getCode() . ': ' . $e->getMessage() - ); - - $APPLICATION->RestartBuffer(); - header('Content-Type: application/x-javascript; charset=' . LANG_CHARSET); - die(json_encode(array("success" => false))); - - } catch (\IntaroCrm\Exception\CurlException $e) { - ICrmOrderActions::eventLog( - 'intaro.crm/install/index.php', 'IntaroCrm\RestApi::orderTypesList::CurlException', + 'intaro.crm/install/index.php', 'RetailCrm\RestApi::orderTypesList::CurlException', $e->getCode() . ': ' . $e->getMessage() ); @@ -223,21 +271,15 @@ class intaro_intarocrm extends CModule { } try { - $arResult['deliveryTypesList'] = $this->INTARO_CRM_API->deliveryTypesList(); - $arResult['deliveryServicesList'] = $this->INTARO_CRM_API->deliveryServicesList(); - $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 - } catch (\IntaroCrm\Exception\ApiException $e) { + $arResult['deliveryTypesList'] = $this->INTARO_CRM_API->deliveryTypesList()->deliveryTypes; + $arResult['deliveryServicesList'] = $this->INTARO_CRM_API->deliveryServicesList()->deliveryServices; + $arResult['paymentTypesList'] = $this->INTARO_CRM_API->paymentTypesList()->paymentTypes; + $arResult['paymentStatusesList'] = $this->INTARO_CRM_API->paymentStatusesList()->paymentStatuses; // --statuses + $arResult['paymentList'] = $this->INTARO_CRM_API->orderStatusesList()->statuses; + $arResult['paymentGroupList'] = $this->INTARO_CRM_API->orderStatusGroupsList()->statusGroups; // -- statuses groups + } catch (\RetailCrm\Exception\CurlException $e) { ICrmOrderActions::eventLog( - 'intaro.crm/install/index.php', 'IntaroCrm\RestApi::*List', - $e->getCode() . ': ' . $e->getMessage() - ); - - } catch (\IntaroCrm\Exception\CurlException $e) { - ICrmOrderActions::eventLog( - 'intaro.crm/install/index.php', 'IntaroCrm\RestApi::*List::CurlException', + 'intaro.crm/install/index.php', 'RetailCrm\RestApi::*List::CurlException', $e->getCode() . ': ' . $e->getMessage() ); } @@ -287,7 +329,8 @@ class intaro_intarocrm extends CModule { 'NAME' => 'ASC' ), array( - 'ACTIVE' => 'Y' + 'ACTIVE' => 'Y', + 'SITE_ID' => $arResult['arSites'][0]['LID'] ) ); @@ -485,86 +528,82 @@ class intaro_intarocrm extends CModule { header('Content-Type: application/x-javascript; charset=' . LANG_CHARSET); die(json_encode(array("success" => true, "result" => $input))); } + + if(count($arResult['arSites'])>1){ + // api load + $api_host = COption::GetOptionString($this->MODULE_ID, $this->CRM_API_HOST_OPTION, 0); + $api_key = COption::GetOptionString($this->MODULE_ID, $this->CRM_API_KEY_OPTION, 0); - $api_host = htmlspecialchars(trim($_POST[$this->CRM_API_HOST_OPTION])); - $api_key = htmlspecialchars(trim($_POST[$this->CRM_API_KEY_OPTION])); + foreach($arResult['arSites'] as $site){ + if($_POST['sites-id-'.$site['LID']] && !empty($_POST['sites-id-'.$site['LID']])){ + $siteCode[$site['LID']] = htmlspecialchars(trim($_POST['sites-id-'.$site['LID']])); + } + } + if (count($arResult['arSites'])!=count($siteCode)) { + $arResult['errCode'] = 'ERR_FIELDS_API_HOST'; + $APPLICATION->IncludeAdminFile( + GetMessage('MODULE_INSTALL_TITLE'), + $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step11.php' + ); + return; + } - // empty == select all - $orderSites = array(); - /* foreach ($_POST[$this->CRM_ORDER_SITES] as $site) { - $orderSites[] = htmlspecialchars(trim($site)); - } */ + $this->INTARO_CRM_API = new \RetailCrm\RestApi($api_host, $api_key); + COption::SetOptionString($this->MODULE_ID, $this->CRM_SITES_LIST, serialize($siteCode)); + } + else{//если 1 сайт + $api_host = htmlspecialchars(trim($_POST[$this->CRM_API_HOST_OPTION])); + $api_key = htmlspecialchars(trim($_POST[$this->CRM_API_KEY_OPTION])); - // form correct url - $api_host = parse_url($api_host); - if($api_host['scheme'] != 'https') $api_host['scheme'] = 'https'; - $api_host = $api_host['scheme'] . '://' . $api_host['host']; + // form correct url + $api_host = parse_url($api_host); + if($api_host['scheme'] != 'https') $api_host['scheme'] = 'https'; + $api_host = $api_host['scheme'] . '://' . $api_host['host']; - if (!$api_host || !$api_key) { - $arResult['errCode'] = 'ERR_FIELDS_API_HOST'; - $APPLICATION->IncludeAdminFile( - GetMessage('MODULE_INSTALL_TITLE'), + if (!$api_host || !$api_key) { + $arResult['errCode'] = 'ERR_FIELDS_API_HOST'; + $APPLICATION->IncludeAdminFile( + GetMessage('MODULE_INSTALL_TITLE'), + $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step1.php' + ); + return; + } + + $this->INTARO_CRM_API = new \RetailCrm\RestApi($api_host, $api_key); + + try { + $this->INTARO_CRM_API->paymentStatusesList()->paymentStatuses; + } catch (\RetailCrm\Exception\CurlException $e) { + ICrmOrderActions::eventLog( + 'intaro.crm/install/index.php', 'RetailCrm\RestApi::paymentStatusesList::CurlException', + $e->getCode() . ': ' . $e->getMessage() + ); + + $arResult['errCode'] = 'ERR_' . $e->getCode(); + + $APPLICATION->IncludeAdminFile( + GetMessage('MODULE_INSTALL_TITLE'), $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step1.php' - ); - return; + ); + + return; + } + COption::SetOptionString($this->MODULE_ID, $this->CRM_API_HOST_OPTION, $api_host); + COption::SetOptionString($this->MODULE_ID, $this->CRM_API_KEY_OPTION, $api_key); } - - $this->INTARO_CRM_API = new \IntaroCrm\RestApi($api_host, $api_key); - - try { - $this->INTARO_CRM_API->paymentStatusesList(); - } catch (\IntaroCrm\Exception\ApiException $e) { - ICrmOrderActions::eventLog( - 'intaro.crm/install/index.php', 'IntaroCrm\RestApi::paymentStatusesList', - $e->getCode() . ': ' . $e->getMessage() - ); - - $arResult['errCode'] = 'ERR_' . $e->getCode(); - - $APPLICATION->IncludeAdminFile( - GetMessage('MODULE_INSTALL_TITLE'), - $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step1.php' - ); - - return; - } catch (\IntaroCrm\Exception\CurlException $e) { - ICrmOrderActions::eventLog( - 'intaro.crm/install/index.php', 'IntaroCrm\RestApi::paymentStatusesList::CurlException', - $e->getCode() . ': ' . $e->getMessage() - ); - - $arResult['errCode'] = 'ERR_' . $e->getCode(); - - $APPLICATION->IncludeAdminFile( - GetMessage('MODULE_INSTALL_TITLE'), - $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step1.php' - ); - - return; - } - - COption::SetOptionString($this->MODULE_ID, $this->CRM_API_HOST_OPTION, $api_host); - COption::SetOptionString($this->MODULE_ID, $this->CRM_API_KEY_OPTION, $api_key); - COption::SetOptionString($this->MODULE_ID, $this->CRM_ORDER_SITES, serialize($orderSites)); - + //prepare crm lists - try { - $arResult['orderTypesList'] = $this->INTARO_CRM_API->orderTypesList(); - $arResult['deliveryTypesList'] = $this->INTARO_CRM_API->deliveryTypesList(); - $arResult['deliveryServicesList'] = $this->INTARO_CRM_API->deliveryServicesList(); - $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 - } catch (\IntaroCrm\Exception\ApiException $e) { + try { + $arResult['orderTypesList'] = $this->INTARO_CRM_API->orderTypesList()->orderTypes; + $arResult['deliveryTypesList'] = $this->INTARO_CRM_API->deliveryTypesList()->deliveryTypes; + $arResult['deliveryServicesList'] = $this->INTARO_CRM_API->deliveryServicesList()->deliveryServices; + $arResult['paymentTypesList'] = $this->INTARO_CRM_API->paymentTypesList()->paymentTypes; + $arResult['paymentStatusesList'] = $this->INTARO_CRM_API->paymentStatusesList()->paymentStatuses; // --statuses + $arResult['paymentList'] = $this->INTARO_CRM_API->orderStatusesList()->statuses; + $arResult['paymentGroupList'] = $this->INTARO_CRM_API->orderStatusGroupsList()->statusGroups; // -- statuses groups + } catch (\RetailCrm\Exception\CurlException $e) { ICrmOrderActions::eventLog( - 'intaro.crm/install/index.php', 'IntaroCrm\RestApi::*List', - $e->getCode() . ': ' . $e->getMessage() - ); - - } catch (\IntaroCrm\Exception\CurlException $e) { - ICrmOrderActions::eventLog( - 'intaro.crm/install/index.php', 'IntaroCrm\RestApi::*List::CurlException', + 'intaro.crm/install/index.php', 'RetailCrm\RestApi::*List::CurlException', $e->getCode() . ': ' . $e->getMessage() ); } @@ -607,7 +646,8 @@ class intaro_intarocrm extends CModule { 'NAME' => 'ASC' ), array( - 'ACTIVE' => 'Y' + 'ACTIVE' => 'Y', + 'SITE_ID' => $arResult['arSites'][0]['LID'] ) ); @@ -659,7 +699,7 @@ class intaro_intarocrm extends CModule { GetMessage('MODULE_INSTALL_TITLE'), $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step2.php' ); - } else if ($step == 3) { + } else if ($step == 3) {//сопостовление свойств заказа if (!CModule::IncludeModule("sale")) { //handler } @@ -674,7 +714,7 @@ class intaro_intarocrm extends CModule { // api load $api_host = COption::GetOptionString($this->MODULE_ID, $this->CRM_API_HOST_OPTION, 0); $api_key = COption::GetOptionString($this->MODULE_ID, $this->CRM_API_KEY_OPTION, 0); - $this->INTARO_CRM_API = new \IntaroCrm\RestApi($api_host, $api_key); + $this->INTARO_CRM_API = new \RetailCrm\RestApi($api_host, $api_key); //bitrix orderTypesList -- personTypes $dbOrderTypesList = CSalePersonType::GetList( @@ -705,15 +745,20 @@ class intaro_intarocrm extends CModule { "ACTIVE" => "Y", ), false, false, array() ); - + //bitrix deliveryServicesList + $rsSites = CSite::GetList($by, $sort, array()); + while ($ar = $rsSites->Fetch()){ + $arResult['arSites'][] = $ar; + } $dbDeliveryServicesList = CSaleDeliveryHandler::GetList( array( 'SORT' => 'ASC', 'NAME' => 'ASC' ), array( - 'ACTIVE' => 'Y' + 'ACTIVE' => 'Y', + 'SITE_ID' => $arResult['arSites'][0]['LID'] ) ); @@ -760,15 +805,9 @@ class intaro_intarocrm extends CModule { 'description' => ICrmOrderActions::toJSON($arDeliveryTypesList['DESCRIPTION']), 'paymentTypes' => '' ))); - } catch (\IntaroCrm\Exception\ApiException $e) { + } catch (\RetailCrm\Exception\CurlException $e) { ICrmOrderActions::eventLog( - 'intaro.crm/install/index.php', 'IntaroCrm\RestApi::deliveryTypeEdit', - $e->getCode() . ': ' . $e->getMessage() - ); - - } catch (\IntaroCrm\Exception\CurlException $e) { - ICrmOrderActions::eventLog( - 'intaro.crm/install/index.php', 'IntaroCrm\RestApi::deliveryTypeEdit::CurlException', + 'intaro.crm/install/index.php', 'RetailCrm\RestApi::deliveryTypeEdit::CurlException', $e->getCode() . ': ' . $e->getMessage() ); } @@ -790,21 +829,14 @@ class intaro_intarocrm extends CModule { 'description' => ICrmOrderActions::toJSON($arDeliveryTypesList['DESCRIPTION']), 'paymentTypes' => '' ))); - } catch (\IntaroCrm\Exception\ApiException $e) { + } catch (\RetailCrm\Exception\CurlException $e) { ICrmOrderActions::eventLog( - 'intaro.crm/install/index.php', 'IntaroCrm\RestApi::deliveryTypeEdit', - $e->getCode() . ': ' . $e->getMessage() - ); - - } catch (\IntaroCrm\Exception\CurlException $e) { - ICrmOrderActions::eventLog( - 'intaro.crm/install/index.php', 'IntaroCrm\RestApi::deliveryTypeEdit::CurlException', + 'intaro.crm/install/index.php', 'RetailCrm\RestApi::deliveryTypeEdit::CurlException', $e->getCode() . ': ' . $e->getMessage() ); } foreach($arDeliveryServicesList['PROFILES'] as $id => $profile) { - // send to crm try { $this->INTARO_CRM_API->deliveryServiceEdit(ICrmOrderActions::clearArr(array( @@ -812,13 +844,7 @@ class intaro_intarocrm extends CModule { 'name' => ICrmOrderActions::toJSON($profile['TITLE']), 'deliveryType' => $arDeliveryServicesList['SID'] ))); - } catch (\IntaroCrm\Exception\ApiException $e) { - ICrmOrderActions::eventLog( - 'intaro.crm/install/index.php', 'IntaroCrm\RestApi::deliveryServiceEdit', - $e->getCode() . ': ' . $e->getMessage() - ); - - } catch (\IntaroCrm\Exception\CurlException $e) { + } catch (\RetailCrm\Exception\CurlException $e) { ICrmOrderActions::eventLog( 'intaro.crm/install/index.php', 'IntaroCrm\RestApi::deliveryServiceEdit::CurlException', $e->getCode() . ': ' . $e->getMessage() @@ -892,7 +918,7 @@ class intaro_intarocrm extends CModule { GetMessage('MODULE_INSTALL_TITLE'), $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step3.php' ); - } else if ($step == 4) { + } else if ($step == 4) {//выгрузка старых заказов if (!CModule::IncludeModule("sale")) { //handler } @@ -904,8 +930,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)) { + if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') && isset($_POST['ajax']) && ($_POST['ajax'] == 1)) { ICrmOrderActions::uploadOrders(); // each 50 $lastUpOrderId = COption::GetOptionString($this->MODULE_ID, $this->CRM_ORDER_LAST_ID, 0); @@ -966,14 +991,43 @@ class intaro_intarocrm extends CModule { $orderPropsArr[$orderType['ID']] = $_orderPropsArr; } + //legal details props + $legalDetailsArr = array(); + foreach ($orderTypesList as $orderType) { + $_legalDetailsArr = array(); + foreach ($arResult['legalDetails'] as $legalDetails) { + + $_legalDetailsArr[$legalDetails['ID']] = htmlspecialchars(trim($_POST['legal-detail-' . $legalDetails['ID'] . '-' . $orderType['ID']])); + } + $legalDetailsArr[$orderType['ID']] = $_legalDetailsArr; + } + + $customFieldsArr = array(); + foreach ($orderTypesList as $orderType) { + $_customFieldsArr = array(); + foreach ($arResult['customFields'] as $custom) { + $_customFieldsArr[$custom['ID']] = htmlspecialchars(trim($_POST['custom-fields-' . $custom['ID'] . '-' . $orderType['ID']])); + } + $customFieldsArr[$orderType['ID']] = $_customFieldsArr; + } + + //contragents type list + $contragentTypeArr = array();//сделать проверки + foreach ($orderTypesList as $orderType) { + $contragentTypeArr[$orderType['ID']] = htmlspecialchars(trim($_POST['contragent-type-' . $orderType['ID']])); + } + COption::SetOptionString($this->MODULE_ID, $this->CRM_ORDER_PROPS, serialize(ICrmOrderActions::clearArr($orderPropsArr))); - + COption::SetOptionString($this->MODULE_ID, $this->CRM_CUSTOM_FIELDS, serialize(ICrmOrderActions::clearArr($customFieldsArr))); + COption::SetOptionString($this->MODULE_ID, $this->CRM_LEGAL_DETAILS, serialize(ICrmOrderActions::clearArr($legalDetailsArr))); + COption::SetOptionString($this->MODULE_ID, $this->CRM_CONTRAGENT_TYPE, serialize(ICrmOrderActions::clearArr($contragentTypeArr))); + $APPLICATION->IncludeAdminFile( GetMessage('MODULE_INSTALL_TITLE'), $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step4.php' ); - } else if ($step == 5) { + } else if ($step == 5) {//экспорт каталога if (!CModule::IncludeModule("iblock")) { $arResult['errCode'] = 'ERR_IBLOCK'; } @@ -996,7 +1050,7 @@ class intaro_intarocrm extends CModule { GetMessage('MODULE_INSTALL_TITLE'), $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/step5.php' ); - } else if ($step == 6) { + } else if ($step == 6) {//регистрация модуля if (!CModule::IncludeModule("iblock")) { $arResult['errCode'] = 'ERR_IBLOCK'; @@ -1114,7 +1168,13 @@ class intaro_intarocrm extends CModule { $this->CopyFiles(); if (isset($_POST['LOAD_NOW'])) { - + $rsSites = CSite::GetList($by, $sort, array('ACTIVE' => 'Y')); + while ($ar = $rsSites->Fetch()){ + if($ar['DEF'] == 'Y'){ + $SERVER_NAME = $ar['SERVER_NAME'];//разделить потом с учетом многосайтовости + } + } + $loader = new ICMLLoader(); $loader->iblocks = $iblocks; $loader->propertiesUnitProduct = $propertiesUnitProduct; @@ -1122,6 +1182,7 @@ class intaro_intarocrm extends CModule { $loader->propertiesUnitSKU = $propertiesUnitSKU; $loader->propertiesSKU = $propertiesSKU; $loader->filename = $filename; + $loader->serverName = $SERVER_NAME; $loader->application = $APPLICATION; $loader->Load(); @@ -1239,18 +1300,12 @@ class intaro_intarocrm extends CModule { $api_host = COption::GetOptionString($this->MODULE_ID, $this->CRM_API_HOST_OPTION, 0); $api_key = COption::GetOptionString($this->MODULE_ID, $this->CRM_API_KEY_OPTION, 0); - $this->INTARO_CRM_API = new \IntaroCrm\RestApi($api_host, $api_key); + $this->INTARO_CRM_API = new \RetailCrm\RestApi($api_host, $api_key); try { $this->INTARO_CRM_API->statisticUpdate(); - } catch (\IntaroCrm\Exception\ApiException $e) { + } catch (\RetailCrm\Exception\CurlException $e) { ICrmOrderActions::eventLog( - 'intaro.crm/install/index.php', 'IntaroCrm\RestApi::statisticUpdate', - $e->getCode() . ': ' . $e->getMessage() - ); - - } catch (\IntaroCrm\Exception\CurlException $e) { - ICrmOrderActions::eventLog( - 'intaro.crm/install/index.php', 'IntaroCrm\RestApi::statisticUpdate::CurlException', + 'intaro.crm/install/index.php', 'RetailCrm\RestApi::statisticUpdate::CurlException', $e->getCode() . ': ' . $e->getMessage() ); } @@ -1280,6 +1335,10 @@ class intaro_intarocrm extends CModule { COption::RemoveOption($this->MODULE_ID, $this->CRM_ORDER_LAST_ID); COption::RemoveOption($this->MODULE_ID, $this->CRM_ORDER_SITES); COption::RemoveOption($this->MODULE_ID, $this->CRM_ORDER_PROPS); + COption::RemoveOption($this->MODULE_ID, $this->CRM_LEGAL_DETAILS); + COption::RemoveOption($this->MODULE_ID, $this->CRM_CONTRAGENT_TYPE); + COption::RemoveOption($this->MODULE_ID, $this->CRM_CUSTOM_FIELDS); + COption::RemoveOption($this->MODULE_ID, $this->CRM_SITES_LIST); COption::RemoveOption($this->MODULE_ID, $this->CRM_ORDER_DISCHARGE); COption::RemoveOption($this->MODULE_ID, $this->CRM_ORDER_FAILED_IDS); COption::RemoveOption($this->MODULE_ID, $this->CRM_ORDER_HISTORY_DATE); diff --git a/intaro.intarocrm/install/retailcrm/agent.php b/intaro.intarocrm/install/retailcrm/agent.php deleted file mode 100644 index d24b259a..00000000 --- a/intaro.intarocrm/install/retailcrm/agent.php +++ /dev/null @@ -1,2 +0,0 @@ -"> - + @@ -26,9 +26,6 @@ - @@ -40,16 +37,6 @@ -
 

diff --git a/intaro.intarocrm/install/step11.php b/intaro.intarocrm/install/step11.php new file mode 100644 index 00000000..af6bfb5e --- /dev/null +++ b/intaro.intarocrm/install/step11.php @@ -0,0 +1,53 @@ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
 
+ +
+
+
+
+ " class="adm-btn-save"> +
+
+
+
\ No newline at end of file diff --git a/intaro.intarocrm/install/step2.php b/intaro.intarocrm/install/step2.php old mode 100755 new mode 100644 diff --git a/intaro.intarocrm/install/step3.php b/intaro.intarocrm/install/step3.php old mode 100755 new mode 100644 index 46bc838c..6a94c8fa --- a/intaro.intarocrm/install/step3.php +++ b/intaro.intarocrm/install/step3.php @@ -19,7 +19,6 @@ $defaultOrderProps = array( 'email' => 'EMAIL' ) ); - ?> @@ -60,6 +75,21 @@ $defaultOrderProps = array( + + + + + + + + + @@ -71,23 +101,78 @@ $defaultOrderProps = array( + 3) echo 'class="address-detail-' . $bitrixOrderType['ID'] . '"'; if(($countProps > 3) && (count($defaultOrderProps[$bitrixOrderType['ID']]) < 6)) echo 'style="display:none;"';?>> - - - - - - + + + + + + + 0):?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/intaro.intarocrm/install/unstep1.php b/intaro.intarocrm/install/unstep1.php old mode 100755 new mode 100644 diff --git a/intaro.intarocrm/install/version.php b/intaro.intarocrm/install/version.php index 8237d382..84c7a46f 100644 --- a/intaro.intarocrm/install/version.php +++ b/intaro.intarocrm/install/version.php @@ -1,5 +1,6 @@ "1.0.15", - "VERSION_DATE" => "2014-11-27 16:00:00" + "VERSION" => "1.1.0", + "VERSION_DATE" => "2015-03-03 16:21:38" ); + diff --git a/intaro.intarocrm/lang/ru/install/index.php b/intaro.intarocrm/lang/ru/install/index.php old mode 100755 new mode 100644 index bc394e36..29de5b63 --- a/intaro.intarocrm/lang/ru/install/index.php +++ b/intaro.intarocrm/lang/ru/install/index.php @@ -1,15 +1,14 @@ Интеграция).'; $MESS ['INFO_3'] = 'Код сайта в 1С-Битрикс должен совпадать с кодом сайта в retailCRM (Администрирование > Магазины).'; \ No newline at end of file diff --git a/intaro.intarocrm/lang/ru/install/step11.php b/intaro.intarocrm/lang/ru/install/step11.php new file mode 100644 index 00000000..64b4072e --- /dev/null +++ b/intaro.intarocrm/lang/ru/install/step11.php @@ -0,0 +1,11 @@ + GetMessage('FIO'), - 'ID' => 'fio' - ), - array( - 'NAME' => GetMessage('PHONE'), - 'ID' => 'phone' - ), - array( - 'NAME' => GetMessage('EMAIL'), - 'ID' => 'email' - ), - array( - 'NAME' => GetMessage('ADDRESS'), - 'ID' => 'text' - ), - // address - /* array( - 'NAME' => GetMessage('COUNTRY'), - 'ID' => 'country' - ), - array( - 'NAME' => GetMessage('REGION'), - 'ID' => 'region' - ), - array( - 'NAME' => GetMessage('CITY'), - 'ID' => 'city' - ),*/ - array( - 'NAME' => GetMessage('ZIP'), - 'ID' => 'index' - ), - array( - 'NAME' => GetMessage('STREET'), - 'ID' => 'street' - ), - array( - 'NAME' => GetMessage('BUILDING'), - 'ID' => 'building' - ), - array( - 'NAME' => GetMessage('FLAT'), - 'ID' => 'flat' - ), - array( - 'NAME' => GetMessage('INTERCOMCODE'), - 'ID' => 'intercomcode' - ), - array( - 'NAME' => GetMessage('FLOOR'), - 'ID' => 'floor' - ), - array( - 'NAME' => GetMessage('BLOCK'), - 'ID' => 'block' - ), - array( - 'NAME' => GetMessage('HOUSE'), - 'ID' => 'house' - ) -); +if (file_exists($_SERVER["DOCUMENT_ROOT"] . '/bitrix/modules/intaro.intarocrm/classes/general/config/options.xml')) { + $options = simplexml_load_file($_SERVER["DOCUMENT_ROOT"] . '/bitrix/modules/intaro.intarocrm/classes/general/config/options.xml'); + + foreach($options->contragents->contragent as $contragent) + { + $type["NAME"] = $APPLICATION->ConvertCharset((string)$contragent, 'utf-8', SITE_CHARSET); + $type["ID"] = (string)$contragent["id"]; + $arResult['contragentType'][] = $type; + unset ($type); + } + foreach($options->fields->field as $field) + { + $type["NAME"] = $APPLICATION->ConvertCharset((string)$field, 'utf-8', SITE_CHARSET); + $type["ID"] = (string)$field["id"]; + + if ($field["group"] == 'custom') { + $arResult['customFields'][] = $type; + } elseif(!$field["group"]){ + $arResult['orderProps'][] = $type; + } else{ + $groups = explode(",", (string)$field["group"]); + foreach ($groups as $group) { + $type["GROUP"][] = trim($group); + } + $arResult['legalDetails'][] = $type; + } + unset($type); + } +} +//else error + +$arResult['arSites'] = array(); + +$rsSites = CSite::GetList($by, $sort, array('ACTIVE' => 'Y')); +while ($ar = $rsSites->Fetch()){ + $arResult['arSites'][] = $ar; +} //ajax update deliveryServices if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') && isset($_POST['ajax']) && ($_POST['ajax'] == 1)) { @@ -99,23 +77,13 @@ if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && (strtolower($_SERVER['HTTP_X_RE $api_host = COption::GetOptionString($mid, $CRM_API_HOST_OPTION, 0); $api_key = COption::GetOptionString($mid, $CRM_API_KEY_OPTION, 0); - $api = new IntaroCrm\RestApi($api_host, $api_key); + $api = new RetailCrm\RestApi($api_host, $api_key); try { $api->paymentStatusesList(); - } catch (\IntaroCrm\Exception\ApiException $e) { + } catch (\RetailCrm\Exception\CurlException $e) { ICrmOrderActions::eventLog( - 'intaro.crm/options.php', 'IntaroCrm\RestApi::paymentStatusesList', - $e->getCode() . ': ' . $e->getMessage() - ); - - $APPLICATION->RestartBuffer(); - header('Content-Type: application/x-javascript; charset=' . LANG_CHARSET); - die(json_encode(array('success' => false, 'errMsg' => $e->getCode()))); - - } catch (\IntaroCrm\Exception\CurlException $e) { - ICrmOrderActions::eventLog( - 'intaro.crm/options.php', 'IntaroCrm\RestApi::paymentStatusesList::CurlException', + 'intaro.crm/options.php', 'RetailCrm\RestApi::paymentStatusesList::CurlException', $e->getCode() . ': ' . $e->getMessage() ); @@ -133,7 +101,8 @@ if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && (strtolower($_SERVER['HTTP_X_RE 'NAME' => 'ASC' ), array( - 'ACTIVE' => 'Y' + 'ACTIVE' => 'Y', + 'SITE_ID' => $arResult['arSites'][0]['LID'] ) ); @@ -154,15 +123,9 @@ if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && (strtolower($_SERVER['HTTP_X_RE 'name' => ICrmOrderActions::toJSON($profile['TITLE']), 'deliveryType' => $arDeliveryServicesList['SID'] ))); - } catch (\IntaroCrm\Exception\ApiException $e) { + } catch (\RetailCrm\Exception\CurlException $e) { ICrmOrderActions::eventLog( - 'intaro.crm/options.php', 'IntaroCrm\RestApi::deliveryServiceEdit', - $e->getCode() . ': ' . $e->getMessage() - ); - - } catch (\IntaroCrm\Exception\CurlException $e) { - ICrmOrderActions::eventLog( - 'intaro.crm/options.php', 'IntaroCrm\RestApi::deliveryServiceEdit::CurlException', + 'intaro.crm/options.php', 'RetailCrm\RestApi::deliveryServiceEdit::CurlException', $e->getCode() . ': ' . $e->getMessage() ); } @@ -176,33 +139,83 @@ if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && (strtolower($_SERVER['HTTP_X_RE die(json_encode(array('success' => true))); } +//upload orders after install module +if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') && isset($_POST['ajax']) && $_POST['ajax'] == 2){ + $step = $_POST['step']; + $orders = $_POST['orders']; + $countStep = 50; // 50 orders on step + + if($orders){ + $ordersArr = explode(',', $orders); + $orders = array(); + foreach($ordersArr as $_ordersArr){ + $ordersList = explode('-', trim($_ordersArr)); + if(count($ordersList) > 1){ + for($i = (int)trim($ordersList[0]); $i <= (int)trim($ordersList[count($ordersList) - 1]); $i++){ + $orders[] = $i; + } + } else{ + $orders[] = (int)$ordersList[0]; + } + } + + $splitedOrders = array_chunk($orders, $countStep); + $stepOrders = $splitedOrders[$step]; + + ICrmOrderActions::uploadOrders($countStep, false, $stepOrders); + + $percent = round((($step * $countStep + count($stepOrders)) * 100 / count($orders)), 1); + $step++; + + if(!$splitedOrders[$step]){ + $step='end'; + } + + $res = array("step" => $step, "percent" => $percent, 'stepOrders' => $stepOrders); + } else{ + $orders = array(); + + for($i = 1; $i <= $countStep; $i++){ + $orders[] = $i + $step * $countStep; + } + + ICrmOrderActions::uploadOrders($countStep, false, $orders); + + $step++; + $countLeft = (int) CSaleOrder::GetList(array("ID" => "ASC"), array('>ID' => $step * $countStep), array()); + $countAll = (int) CSaleOrder::GetList(array("ID" => "ASC"), array(), array()); + $percent = round(100 - ($countLeft * 100 / $countAll), 1); + + if($countLeft == 0){ + $step = 'end'; + } + + $res = array("step" => $step, "percent" => $percent, 'stepOrders' => $orders); + } + + $APPLICATION->RestartBuffer(); + header('Content-Type: application/x-javascript; charset=' . LANG_CHARSET); + die(json_encode($res)); +} + //update connection settings if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) { $api_host = htmlspecialchars(trim($_POST['api_host'])); $api_key = htmlspecialchars(trim($_POST['api_key'])); - - // if empty so select all? or exception --not obligatory - $orderSites = array(); - /*foreach ($_POST[$CRM_ORDER_SITES] as $site) { - $orderSites[] = htmlspecialchars(trim($site)); - }*/ + + //bitrix site list + $siteListArr = array(); + foreach ($arResult['arSites'] as $arSites) { + $siteListArr[$arSites['LID']] = htmlspecialchars(trim($_POST['sites-id-' . $arSites['LID']])); + } if($api_host && $api_key) { - $api = new IntaroCrm\RestApi($api_host, $api_key); + $api = new RetailCrm\RestApi($api_host, $api_key); try { $api->paymentStatusesList(); - } catch (\IntaroCrm\Exception\ApiException $e) { + } catch (\RetailCrm\Exception\CurlException $e) { ICrmOrderActions::eventLog( - 'intaro.crm/options.php', 'IntaroCrm\RestApi::paymentStatusesList', - $e->getCode() . ': ' . $e->getMessage() - ); - - $uri .= '&errc=ERR_' . $e->getCode(); - LocalRedirect($uri); - - } catch (\IntaroCrm\Exception\CurlException $e) { - ICrmOrderActions::eventLog( - 'intaro.crm/options.php', 'IntaroCrm\RestApi::paymentStatusesList::CurlException', + 'intaro.crm/options.php', 'RetailCrm\RestApi::paymentStatusesList::CurlException', $e->getCode() . ': ' . $e->getMessage() ); @@ -267,7 +280,8 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) { 'NAME' => 'ASC' ), array( - 'ACTIVE' => 'Y' + 'ACTIVE' => 'Y', + 'SITE_ID' => $arResult['arSites'][0]['LID'] ) ); @@ -349,22 +363,51 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) { $propsCount = 0; $_orderPropsArr = array(); foreach ($arResult['orderProps'] as $orderProp) { - if ((!(int) htmlspecialchars(trim($_POST['address-detail-' . $orderType['ID']]))) && $propsCount > 4) + if ((!(int) htmlspecialchars(trim($_POST['address-detail-' . $orderType['ID']]))) && $propsCount > 4){ break; + } $_orderPropsArr[$orderProp['ID']] = htmlspecialchars(trim($_POST['order-prop-' . $orderProp['ID'] . '-' . $orderType['ID']])); $propsCount++; } $orderPropsArr[$orderType['ID']] = $_orderPropsArr; } + //legal details props + $legalDetailsArr = array(); + foreach ($orderTypesList as $orderType) { + $_legalDetailsArr = array(); + foreach ($arResult['legalDetails'] as $legalDetails) { + $_legalDetailsArr[$legalDetails['ID']] = htmlspecialchars(trim($_POST['legal-detail-' . $legalDetails['ID'] . '-' . $orderType['ID']])); + } + $legalDetailsArr[$orderType['ID']] = $_legalDetailsArr; + } + + $customFieldsArr = array(); + foreach ($orderTypesList as $orderType) { + $_customFieldsArr = array(); + foreach ($arResult['customFields'] as $custom) { + $_customFieldsArr[$custom['ID']] = htmlspecialchars(trim($_POST['custom-fields-' . $custom['ID'] . '-' . $orderType['ID']])); + } + $customFieldsArr[$orderType['ID']] = $_customFieldsArr; + } + + //contragents type list + $contragentTypeArr = array(); + foreach ($orderTypesList as $orderType) { + $contragentTypeArr[$orderType['ID']] = htmlspecialchars(trim($_POST['contragent-type-' . $orderType['ID']])); + } + + COption::SetOptionString($mid, $CRM_SITES_LIST, serialize(ICrmOrderActions::clearArr($siteListArr))); COption::SetOptionString($mid, $CRM_ORDER_TYPES_ARR, serialize(ICrmOrderActions::clearArr($orderTypesArr))); COption::SetOptionString($mid, $CRM_DELIVERY_TYPES_ARR, serialize(ICrmOrderActions::clearArr($deliveryTypesArr))); COption::SetOptionString($mid, $CRM_PAYMENT_TYPES, serialize(ICrmOrderActions::clearArr($paymentTypesArr))); COption::SetOptionString($mid, $CRM_PAYMENT_STATUSES, serialize(ICrmOrderActions::clearArr($paymentStatusesArr))); COption::SetOptionString($mid, $CRM_PAYMENT, serialize(ICrmOrderActions::clearArr($paymentArr))); - COption::SetOptionString($mid, $CRM_ORDER_SITES, serialize(ICrmOrderActions::clearArr($orderSites))); COption::SetOptionString($mid, $CRM_ORDER_DISCHARGE, $orderDischarge); - COption::SetOptionString($mid, $CRM_ORDER_PROPS, serialize(ICrmOrderActions::clearArr($orderPropsArr))); + COption::SetOptionString($mid, $CRM_ORDER_PROPS, serialize(ICrmOrderActions::clearArr($orderPropsArr))); + COption::SetOptionString($mid, $CRM_CONTRAGENT_TYPE, serialize(ICrmOrderActions::clearArr($contragentTypeArr))); + COption::SetOptionString($mid, $CRM_LEGAL_DETAILS, serialize(ICrmOrderActions::clearArr($legalDetailsArr))); + COption::SetOptionString($mid, $CRM_CUSTOM_FIELDS, serialize(ICrmOrderActions::clearArr($customFieldsArr))); $uri .= '&ok=Y'; LocalRedirect($uri); @@ -372,33 +415,21 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) { $api_host = COption::GetOptionString($mid, $CRM_API_HOST_OPTION, 0); $api_key = COption::GetOptionString($mid, $CRM_API_KEY_OPTION, 0); - $api = new IntaroCrm\RestApi($api_host, $api_key); - - $arResult['arSites'] = array(); - $rsSites = CSite::GetList($by, $sort, array()); - while ($ar = $rsSites->Fetch()) - $arResult['arSites'][] = $ar; + $api = new RetailCrm\RestApi($api_host, $api_key); //prepare crm lists try { - $arResult['orderTypesList'] = $api->orderTypesList(); - $arResult['deliveryTypesList'] = $api->deliveryTypesList(); - $arResult['deliveryServicesList'] = $api->deliveryServicesList(); - $arResult['paymentTypesList'] = $api->paymentTypesList(); - $arResult['paymentStatusesList'] = $api->paymentStatusesList(); // --statuses - $arResult['paymentList'] = $api->orderStatusesList(); - $arResult['paymentGroupList'] = $api->orderStatusGroupsList(); // -- statuses groups - } catch (\IntaroCrm\Exception\ApiException $e) { + $arResult['orderTypesList'] = $api->orderTypesList()->orderTypes; + $arResult['deliveryTypesList'] = $api->deliveryTypesList()->deliveryTypes; + $arResult['deliveryServicesList'] = $api->deliveryServicesList()->deliveryServices; + $arResult['paymentTypesList'] = $api->paymentTypesList()->paymentTypes; + $arResult['paymentStatusesList'] = $api->paymentStatusesList()->paymentStatuses; // --statuses + $arResult['paymentList'] = $api->orderStatusesList()->statuses; + $arResult['paymentGroupList'] = $api->orderStatusGroupsList()->statusGroups; // -- statuses groups + $arResult['sitesList'] = $api->sitesList()->sites; + } catch (\RetailCrm\Exception\CurlException $e) { ICrmOrderActions::eventLog( - 'intaro.crm/options.php', 'IntaroCrm\RestApi::*List', - $e->getCode() . ': ' . $e->getMessage() - ); - - echo CAdminMessage::ShowMessage(GetMessage('ERR_' . $e->getCode())); - - } catch (\IntaroCrm\Exception\CurlException $e) { - ICrmOrderActions::eventLog( - 'intaro.crm/options.php', 'IntaroCrm\RestApi::*List::CurlException', + 'intaro.crm/options.php', 'RetailCrm\RestApi::*List::CurlException', $e->getCode() . ': ' . $e->getMessage() ); @@ -410,16 +441,16 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) { array( "SORT" => "ASC", "NAME" => "ASC" - ), + ), array( "ACTIVE" => "Y", ), false, false, array() - ); + ); - if ($arOrderTypesList = $dbOrderTypesList->Fetch()) { + if ($arOrderTypesList = $dbOrderTypesList->Fetch()) { do { $arResult['bitrixOrderTypesList'][] = $arOrderTypesList; } while ($arOrderTypesList = $dbOrderTypesList->Fetch()); @@ -452,7 +483,8 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) { 'NAME' => 'ASC' ), array( - 'ACTIVE' => 'Y' + 'ACTIVE' => 'Y', + 'SITE_ID' => $arResult['arSites'][0]['LID'] ) ); @@ -511,16 +543,19 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) { while ($arProp = $dbProp->GetNext()) { $arResult['arProp'][$arProp['PERSON_TYPE_ID']][] = $arProp; } - + //saved cat params $optionsOrderTypes = unserialize(COption::GetOptionString($mid, $CRM_ORDER_TYPES_ARR, 0)); $optionsDelivTypes = unserialize(COption::GetOptionString($mid, $CRM_DELIVERY_TYPES_ARR, 0)); $optionsPayTypes = unserialize(COption::GetOptionString($mid, $CRM_PAYMENT_TYPES, 0)); $optionsPayStatuses = unserialize(COption::GetOptionString($mid, $CRM_PAYMENT_STATUSES, 0)); // --statuses $optionsPayment = unserialize(COption::GetOptionString($mid, $CRM_PAYMENT, 0)); - $optionsSites = unserialize(COption::GetOptionString($mid, $CRM_ORDER_SITES, 0)); + $optionsSitesList = unserialize(COption::GetOptionString($mid, $CRM_SITES_LIST, 0)); $optionsDischarge = COption::GetOptionString($mid, $CRM_ORDER_DISCHARGE, 0); - $optionsOrderProps = unserialize(COption::GetOptionString($mid, $CRM_ORDER_PROPS, 0)); + $optionsOrderProps = unserialize(COption::GetOptionString($mid, $CRM_ORDER_PROPS, 0)); + $optionsContragentType = unserialize(COption::GetOptionString($mid, $CRM_CONTRAGENT_TYPE, 0)); + $optionsLegalDetails = unserialize(COption::GetOptionString($mid, $CRM_LEGAL_DETAILS, 0)); + $optionsCustomFields = unserialize(COption::GetOptionString($mid, $CRM_CUSTOM_FIELDS, 0)); $isCustomOrderType = function_exists('intarocrm_set_order_type') || function_exists('intarocrm_get_order_type'); @@ -564,8 +599,24 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) { $('tr.address-detail-' + orderType).show('slow'); else if(parseInt($(this).val()) === 0) $('tr.address-detail-' + orderType).hide('slow'); + }); + + $('tr.contragent-type select').change(function(){ + splitName = $(this).attr('name').split('-'); + contragentType = $(this).val(); + orderType = splitName[2]; + + $('tr.legal-detail-' + orderType).hide(); + $('.legal-detail-title-' + orderType).hide(); + + $('tr.legal-detail-' + orderType).each(function(){ + if($(this).hasClass(contragentType)){ + $(this).show(); + $('.legal-detail-title-' + orderType).show(); + } }); - }); + }); + }); $('input[name="update-delivery-services"]').live('click', function() { BX.showWait(); @@ -617,16 +668,27 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) { - + + + BeginNextTab(); ?> @@ -760,8 +822,21 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) { - - + + + + + + + + + @@ -788,7 +863,58 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) { + 0):?> + + + + + + + + + + + + + + + + + + + > + + + + + + + + > + + + + + + + + + BeginNextTab(); ?> @@ -803,9 +929,173 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) { Buttons(); ?> - - + + End(); ?> - + + - \ No newline at end of file + + + + + +
+
+ +
+ + + + + + + + + +
+
+
+ +
+
+
+
0%
+
+ 0% +
+
+
+
+
+
+ +
+
+
+
+ diff --git a/intaro.intarocrm/updater.php b/intaro.intarocrm/updater.php new file mode 100644 index 00000000..b775734c --- /dev/null +++ b/intaro.intarocrm/updater.php @@ -0,0 +1,87 @@ +apiUrl.'reference/sites'; + $result = $this->curlRequest($url); + return $result; + } +} +$mid = 'intaro.intarocrm'; +$CRM_API_HOST_OPTION = 'api_host'; +$CRM_API_KEY_OPTION = 'api_key'; +$CRM_CONTRAGENT_TYPE = 'contragent_type'; +$CRM_SITES_LIST= 'sites_list'; + +$api_host = COption::GetOptionString($mid, $CRM_API_HOST_OPTION, 0); +$api_key = COption::GetOptionString($mid, $CRM_API_KEY_OPTION, 0); +$api = new RestApiSite($api_host, $api_key); + +if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/intaro.intarocrm/classes/general/agent.php')) { + unlink($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/intaro.intarocrm/classes/general/agent.php'); +} +if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/intaro.intarocrm/classes/general/Exception/ApiException.php')) { + unlink($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/intaro.intarocrm/classes/general/Exception/ApiException.php'); +} +if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/retailcrm')) { + removeDirectory($_SERVER['DOCUMENT_ROOT'] . '/retailcrm'); +} + +//sites +$rsSites = CSite::GetList($by, $sort, array('ACTIVE' => 'Y')); +while ($ar = $rsSites->Fetch()){ + $arSites[] = $ar; +} +if(count($arSites)>1){ + try { + $sitesList = $api->sitesList(); + } catch (\IntaroCrm\Exception\CurlException $e) { + ICrmOrderActions::eventLog( + 'intaro.crm/updater.php', 'RetailCrm\RestApi::sitesList::CurlException', + $e->getCode() . ': ' . $e->getMessage() + ); + return; + } + foreach ($arResult['arSites'] as $arSites) { + $siteListArr[$arSites['LID']] = $sitesList[0]['code']; + } + COption::SetOptionString($mid, $CRM_SITES_LIST, serialize(ICrmOrderActions::clearArr($siteListArr))); +} + +//contragents type list +$dbOrderTypesList = CSalePersonType::GetList( + array( + "SORT" => "ASC", + "NAME" => "ASC" + ), + array( + "ACTIVE" => "Y", + ), + false, + false, + array() +); + +$orderTypesList = array(); +while ($arOrderTypesList = $dbOrderTypesList->Fetch()){ + $orderTypesList[] = $arOrderTypesList; +} +$contragentTypeArr = array(); +foreach ($orderTypesList as $orderType) { + $contragentTypeArr[$orderType['ID']] = 'individual'; +} +COption::SetOptionString($mid, $CRM_CONTRAGENT_TYPE, serialize(ICrmOrderActions::clearArr($contragentTypeArr))); + +function removeDirectory($dir) { + if ($objs = glob($dir."/*")) { + foreach($objs as $obj) { + is_dir($obj) ? removeDirectory($obj) : unlink($obj); + } + } + rmdir($dir); +}