diff --git a/CHANGELOG.md b/CHANGELOG.md index 36c5816c..e7bdb567 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2017-10-25 v.2.2.6 +* Доработана система синхронизации оплат +* Исправлены ошибки в истории заказов + ## 2017-09-22 v.2.2.5 * Теперь учитываются группы доставки * Изменен алгоритм передачи оплат diff --git a/intaro.retailcrm/classes/general/ApiClient_v5.php b/intaro.retailcrm/classes/general/ApiClient_v5.php index 268e6244..afdffda6 100644 --- a/intaro.retailcrm/classes/general/ApiClient_v5.php +++ b/intaro.retailcrm/classes/general/ApiClient_v5.php @@ -895,7 +895,7 @@ class ApiClient ); } - if (empty($entity) || !in_array($entity, ['customer', 'order'])) { + if (empty($entity) || !in_array($entity, array('customer', 'order'))) { throw new \InvalidArgumentException( 'Parameter `entity` must contain a data & value must be `order` or `customer`' ); @@ -924,7 +924,7 @@ class ApiClient ); } - if (empty($entity) || !in_array($entity, ['customer', 'order'])) { + if (empty($entity) || !in_array($entity, array('customer', 'order'))) { throw new \InvalidArgumentException( 'Parameter `entity` must contain a data & value must be `order` or `customer`' ); @@ -953,7 +953,7 @@ class ApiClient ); } - if (empty($entity) || !in_array($entity, ['customer', 'order'])) { + if (empty($entity) || !in_array($entity, array('customer', 'order'))) { throw new \InvalidArgumentException( 'Parameter `entity` must contain a data & value must be `order` or `customer`' ); diff --git a/intaro.retailcrm/classes/general/RCrmActions.php b/intaro.retailcrm/classes/general/RCrmActions.php index 8263308e..66af6ae3 100644 --- a/intaro.retailcrm/classes/general/RCrmActions.php +++ b/intaro.retailcrm/classes/general/RCrmActions.php @@ -314,12 +314,17 @@ class RCrmActions case 'ordersEdit': case 'customersGet': case 'customersEdit': - case 'ordersPaymentEdit': return self::proxy($api, $methodApi, $method, array($params, 'externalId', $site)); - + + case 'paymentEditById': + return self::proxy($api, 'ordersPaymentEdit', $method, array($params, 'id', $site)); + + case 'paymentEditByExternalId': + return self::proxy($api, 'ordersPaymentEdit', $method, array($params, 'externalId', $site)); + default: return self::proxy($api, $methodApi, $method, array($params, $site)); - } + } } private function proxy($api, $methodApi, $method, $params) { diff --git a/intaro.retailcrm/classes/general/events/RetailCrmEvent.php b/intaro.retailcrm/classes/general/events/RetailCrmEvent.php index a3e2b38d..13ec839c 100644 --- a/intaro.retailcrm/classes/general/events/RetailCrmEvent.php +++ b/intaro.retailcrm/classes/general/events/RetailCrmEvent.php @@ -156,7 +156,11 @@ class RetailCrmEvent } else { $site = null; } - + + if ($site == null) { + return; + } + //new order? $orderCrm = RCrmActions::apiMethod($api, 'ordersGet', __METHOD__, $arOrder['ID'], $site); if (isset($orderCrm['order'])) { @@ -164,6 +168,7 @@ class RetailCrmEvent $arParams['crmOrder'] = $orderCrm['order']; } else { $methodApi = 'ordersCreate'; + $GLOBALS['RETAILCRM_ORDER_NEW_ORDER'] = true; } //user @@ -191,4 +196,174 @@ class RetailCrmEvent return true; } + + /** + * paymentSave + * + * @param object $event - Payment object + */ + + function paymentSave($event) + { + $apiVersion = COption::GetOptionString(self::$MODULE_ID, 'api_version', 0); + + if ((isset($GLOBALS['RETAIL_CRM_HISTORY']) && $GLOBALS['RETAIL_CRM_HISTORY']) || $apiVersion != 'v5') { + return; + } + + $optionsSitesList = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_SITES_LIST, 0)); + $optionsPaymentTypes = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PAYMENT_TYPES, 0)); + $optionsPayStatuses = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_PAYMENT, 0)); + + $arPayment = array( + 'ID' => $event->getId(), + 'ORDER_ID' => $event->getField('ORDER_ID'), + 'PAID' => $event->getField('PAID'), + 'PAY_SYSTEM_ID' => $event->getField('PAY_SYSTEM_ID'), + 'SUM' => $event->getField('SUM'), + 'LID' => $event->getField('LID'), + 'DATE_PAID' => $event->getField('DATE_PAID'), + 'METHOD' => $GLOBALS['RETAILCRM_ORDER_NEW_ORDER'], + ); + + try { + $newOrder = Bitrix\Sale\Order::load($arPayment['ORDER_ID']); + $arPayment['LID'] = $newOrder->getField('LID'); + } catch (Bitrix\Main\ArgumentNullException $e) { + RCrmActions::eventLog('RetailCrmHistory::orderHistory', 'Bitrix\Sale\Order::load', $e->getMessage() . ': ' . $arPayment['ORDER_ID']); + return; + } + + if(!empty($optionsSitesList) && array_key_exists($arPayment['LID'], $optionsSitesList)) { + $site = $optionsSitesList[$arPayment['LID']]; + } else { + $site = null; + } + + if ($site == null) { + return; + } + + $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); + $api = new RetailCrm\ApiClient($api_host, $api_key); + $orderCrm = RCrmActions::apiMethod($api, 'ordersGet', __METHOD__, $arPayment['ORDER_ID'], $site); + + if (isset($orderCrm['order'])) { + $payments = $orderCrm['order']['payments']; + } + + if ($arPayment['METHOD'] === true) { + if ($payments) { + foreach ($payments as $payment) { + if (!isset($payment['externalId'])) { + if ($payment['type'] == $optionsPaymentTypes[$arPayment['PAY_SYSTEM_ID']] && $payment['amount'] == $arPayment['SUM']) { + $payment['externalId'] = $arPayment['ID']; + RCrmActions::apiMethod($api, 'paymentEditById', __METHOD__, $payment, $site); + } + } + } + } + } else { + if ($payments) { + foreach ($payments as $payment) { + if (isset($payment['externalId'])) { + $paymentsExternalIds[$payment['externalId']] = $payment; + } + } + + if (!empty($arPayment['PAY_SYSTEM_ID']) && isset($optionsPaymentTypes[$arPayment['PAY_SYSTEM_ID']])) { + $paymentToCrm = array( + 'type' => $optionsPaymentTypes[$arPayment['PAY_SYSTEM_ID']], + 'amount' => $arPayment['SUM'] + ); + + if (!empty($arPayment['ID'])) { + $paymentToCrm['externalId'] = $arPayment['ID']; + } + + if (!empty($arPayment['DATE_PAID'])) { + if (is_object($arPayment['DATE_PAID'])) { + $culture = new Bitrix\Main\Context\Culture(array("FORMAT_DATETIME" => "YYYY-MM-DD HH:MI:SS")); + $paymentToCrm['paidAt'] = $arPayment['DATE_PAID']->toString($culture); + } elseif (is_string($arPayment['DATE_PAID'])) { + $paymentToCrm['paidAt'] = $arPayment['DATE_PAID']; + } + } + + if (!empty($optionsPayStatuses[$arPayment['PAID']])) { + $paymentToCrm['status'] = $optionsPayStatuses[$arPayment['PAID']]; + } + + if (!empty($arPayment['ORDER_ID'])) { + $paymentToCrm['order']['externalId'] = $arPayment['ORDER_ID']; + } + } else { + RCrmActions::eventLog('RetailCrmOrder::orderSend', 'payments', 'OrderID = ' . $arFields['ID'] . '. Payment not found.'); + } + + if (!array_key_exists($arPayment['ID'], $paymentsExternalIds)) { + RCrmActions::apiMethod($api, 'ordersPaymentCreate', __METHOD__, $paymentToCrm, $site); + } elseif (array_key_exists($arPayment['ID'], $paymentsExternalIds) && $paymentsExternalIds[$arPayment['ID']]['type'] == $optionsPaymentTypes[$arPayment['PAY_SYSTEM_ID']]) { + RCrmActions::apiMethod($api, 'paymentEditByExternalId', __METHOD__, $paymentToCrm, $site); + } elseif (array_key_exists($arPayment['ID'], $paymentsExternalIds) && $paymentsExternalIds[$arPayment['ID']]['type'] != $optionsPaymentTypes[$arPayment['PAY_SYSTEM_ID']]) { + RCrmActions::apiMethod($api, 'ordersPaymentDelete', __METHOD__, $paymentsExternalIds[$arPayment['ID']]['id']); + RCrmActions::apiMethod($api, 'ordersPaymentCreate', __METHOD__, $paymentToCrm, $site); + } + } + } + } + + /** + * paymentDelete + * + * @param object $event - Payment object + */ + + function paymentDelete($event) + { + $apiVersion = COption::GetOptionString(self::$MODULE_ID, 'api_version', 0); + + if ((isset($GLOBALS['RETAIL_CRM_HISTORY']) && $GLOBALS['RETAIL_CRM_HISTORY']) || $apiVersion != 'v5') { + return; + } + + $optionsSitesList = unserialize(COption::GetOptionString(self::$MODULE_ID, self::$CRM_SITES_LIST, 0)); + + $arPayment = array( + 'ID' => $event->getId(), + 'ORDER_ID' => $event->getField('ORDER_ID') + ); + + try { + $newOrder = Bitrix\Sale\Order::load($arPayment['ORDER_ID']); + $arPayment['LID'] = $newOrder->getField('LID'); + } catch (Bitrix\Main\ArgumentNullException $e) { + RCrmActions::eventLog('RetailCrmHistory::orderHistory', 'Bitrix\Sale\Order::load', $e->getMessage() . ': ' . $arPayment['ORDER_ID']); + return; + } + + if(!empty($optionsSitesList) && array_key_exists($arPayment['LID'], $optionsSitesList)) { + $site = $optionsSitesList[$arPayment['LID']]; + } else { + $site = null; + } + + if ($site == null) { + return; + } + + $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); + $api = new RetailCrm\ApiClient($api_host, $api_key); + $orderCrm = RCrmActions::apiMethod($api, 'ordersGet', __METHOD__, $arPayment('ORDER_ID'), $site); + + if (isset($orderCrm['order']['payments']) && $orderCrm['order']['payments']) { + foreach ($orderCrm['order']['payments'] as $payment) { + if (isset($payment['externalId']) && $payment['externalId'] == $event->getId()) { + RCrmActions::apiMethod($api, 'ordersPaymentDelete', __METHOD__, $payment['id']); + } + } + } + } } \ No newline at end of file diff --git a/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php b/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php index 4ffed512..5c29b037 100644 --- a/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php +++ b/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php @@ -503,8 +503,10 @@ class RetailCrmHistory if ($propsRemove) {//delete props foreach ($propertyCollectionArr['properties'] as $orderProp) { - $somePropValue = $propertyCollection->getItemByOrderPropertyId($orderProp['ID']); - self::setProp($somePropValue); + if ($orderProp['PROPS_GROUP_ID'] == 0) { + $somePropValue = $propertyCollection->getItemByOrderPropertyId($orderProp['ID']); + self::setProp($somePropValue); + } } $orderCrm = RCrmActions::apiMethod($api, 'orderGet', __METHOD__, $order['id']); @@ -514,8 +516,10 @@ class RetailCrmHistory $propsKey = array(); foreach ($propertyCollectionArr['properties'] as $prop) { - $propsKey[$prop['CODE']]['ID'] = $prop['ID']; - $propsKey[$prop['CODE']]['TYPE'] = $prop['TYPE']; + if ($prop['PROPS_GROUP_ID'] != 0) { + $propsKey[$prop['CODE']]['ID'] = $prop['ID']; + $propsKey[$prop['CODE']]['TYPE'] = $prop['TYPE']; + } } //fio if ($order['firstName'] || $order['lastName'] || $order['patronymic']) { @@ -585,16 +589,17 @@ class RetailCrmHistory } } } - + //optionsLegalDetails if ($optionsLegalDetails[$personType]) { foreach ($optionsLegalDetails[$personType] as $key => $orderProp) { - if (array_key_exists($key, $order)) { + if (array_key_exists($key, $order['contragent'])) { $somePropValue = $propertyCollection->getItemByOrderPropertyId($propsKey[$orderProp]['ID']); - self::setProp($somePropValue, $order[$key]); + self::setProp($somePropValue, $order['contragent'][$key]); } } } + if ($propsRemove) { $order = $orderDump; } @@ -641,7 +646,6 @@ class RetailCrmHistory } if ($product['delete']) { $item->delete(); - $basket->save(); continue; } @@ -660,8 +664,6 @@ class RetailCrmHistory $item->setField('DISCOUNT_VALUE', ''); } } - - $basket->save(); } } @@ -1187,7 +1189,7 @@ class RetailCrmHistory unset($paymentsList[$newPaymentId]); - //RCrmActions::apiMethod($api, 'ordersPaymentEdit', __METHOD__, array('id' => $paymentCrm['id'], 'externalId' => $newPaymentId)); + RCrmActions::apiMethod($api, 'ordersPaymentEdit', __METHOD__, array('id' => $paymentCrm['id'], 'externalId' => $newPaymentId)); } if ($optionsPayment[$paymentCrm['status']] == 'Y') { diff --git a/intaro.retailcrm/classes/general/order/RetailCrmOrder_v4.php b/intaro.retailcrm/classes/general/order/RetailCrmOrder_v4.php index f19cb922..f184300c 100644 --- a/intaro.retailcrm/classes/general/order/RetailCrmOrder_v4.php +++ b/intaro.retailcrm/classes/general/order/RetailCrmOrder_v4.php @@ -155,10 +155,10 @@ class RetailCrmOrder } $normalizer = new RestNormalizer(); - $order = $normalizer->normalize($order, 'ordersSend'); + $order = $normalizer->normalize($order, 'orders'); $log = new Logger(); - $log->write($order, 'order'); + $log->write($order, 'orderSend'); if($send) { if (!RCrmActions::apiMethod($api, $methodApi, __METHOD__, $order, $site)) { diff --git a/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php b/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php index 0b746209..2b22526a 100644 --- a/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php +++ b/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php @@ -179,62 +179,15 @@ class RetailCrmOrder } $normalizer = new RestNormalizer(); - $order = $normalizer->normalize($order, 'ordersSend'); + $order = $normalizer->normalize($order, 'orders'); $log = new Logger(); - $log->write($order, 'order'); + $log->write($order, 'orderSend'); if($send) { if (!RCrmActions::apiMethod($api, $methodApi, __METHOD__, $order, $site)) { return false; } - - if ($methodApi == 'ordersEdit') { - $crmPayments = array(); - if (!empty($arParams['crmOrder']['payments'])) { - foreach ($arParams['crmOrder']['payments'] as $crmPayment) { - if (isset($crmPayment['externalId'])) { - $crmPayments['externalIds'][$crmPayment['externalId']] = $crmPayment; - } else { - $crmPayments['ids'][$crmPayment['id']] = $crmPayment; - } - } - } - - foreach ($order['payments'] as $payment) { - if (isset($crmPayments['externalIds'][$payment['externalId']])) { - //update payment - if ($payment['type'] == $crmPayments['externalIds'][$payment['externalId']]['type']) { - if (RCrmActions::apiMethod($api, 'ordersPaymentEdit', __METHOD__, $payment, $site)) { - unset($crmPayments['externalIds'][$payment['externalId']]); - } - } else { - RCrmActions::apiMethod($api, 'ordersPaymentDelete', __METHOD__, $crmPayments['externalIds'][$payment['externalId']]['id']); - $payment['order']['externalId'] = $order['externalId']; - RCrmActions::apiMethod($api, 'ordersPaymentCreate', __METHOD__, $payment, $site); - unset($crmPayments['externalIds'][$payment['externalId']]); - } - } else { - //create - $payment['order']['externalId'] = $order['externalId']; - RCrmActions::apiMethod($api, 'ordersPaymentCreate', __METHOD__, $payment, $site); - } - } - - //delete in crm - if (!empty($crmPayments['ids'])) { - foreach ($crmPayments['ids'] as $payment) { - //delete - RCrmActions::apiMethod($api, 'ordersPaymentDelete', __METHOD__, $payment['id']); - } - } - if (!empty($crmPayments['externalIds'])) { - foreach ($crmPayments['externalIds'] as $payment) { - //delete - RCrmActions::apiMethod($api, 'ordersPaymentDelete', __METHOD__, $payment['id']); - } - } - } } return $order; @@ -332,6 +285,10 @@ class RetailCrmOrder $site = null; } + if ($site == null) { + continue; + } + $arCustomers = RetailCrmUser::customerSend($user, $api, $optionsContragentType[$order['PERSON_TYPE_ID']], false, $site); $arOrders = self::orderSend($order, $api, $arParams, false, $site); diff --git a/intaro.retailcrm/description.ru b/intaro.retailcrm/description.ru index 595a8834..f4a32122 100644 --- a/intaro.retailcrm/description.ru +++ b/intaro.retailcrm/description.ru @@ -1,4 +1,2 @@ -- Теперь учитываются группы доставки -- Изменен алгоритм передачи оплат -- Исправлено задваивание количества товаров в отгрузке -- Небольшие исправления +- Доработана система синхронизации оплат +- Исправлены ошибки в истории заказов \ No newline at end of file diff --git a/intaro.retailcrm/install/index.php b/intaro.retailcrm/install/index.php index d882f1b1..db336d7b 100644 --- a/intaro.retailcrm/install/index.php +++ b/intaro.retailcrm/install/index.php @@ -285,6 +285,8 @@ class intaro_retailcrm extends CModule 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']])); + } else { + $siteCode[$site['LID']] = null; } } if (count($arResult['arSites']) != count($siteCode)) { @@ -813,7 +815,9 @@ class intaro_retailcrm extends CModule RegisterModuleDependences("main", "OnAfterUserUpdate", $this->MODULE_ID, "RetailCrmEvent", "OnAfterUserUpdate"); RegisterModuleDependences("sale", "OnSaleOrderEntitySaved", $this->MODULE_ID, "RetailCrmEvent", "orderSave"); RegisterModuleDependences("sale", "OnSaleOrderEntityDelete", $this->MODULE_ID, "RetailCrmEvent", "orderDelete"); - + RegisterModuleDependences("sale", "OnSalePaymentEntitySaved", $this->MODULE_ID, "RetailCrmEvent", "paymentSave"); + RegisterModuleDependences("sale", "OnSalePaymentEntityDeleted", $this->MODULE_ID, "RetailCrmEvent", "paymentDelete"); + COption::SetOptionString($this->MODULE_ID, $this->CRM_CATALOG_BASE_PRICE, htmlspecialchars(trim($_POST['price-types']))); COption::SetOptionString($this->MODULE_ID, $this->CRM_INVENTORIES_UPLOAD, 'N'); COption::SetOptionString($this->MODULE_ID, $this->CRM_PRICES_UPLOAD, 'N'); @@ -1017,7 +1021,9 @@ class intaro_retailcrm extends CModule UnRegisterModuleDependences("sale", "OnSaleOrderEntityDelete", $this->MODULE_ID, "RetailCrmEvent", "orderDelete"); UnRegisterModuleDependences("main", "OnBeforeProlog", $this->MODULE_ID, "RetailCrmCollector", "add"); UnRegisterModuleDependences("main", "OnBeforeProlog", $this->MODULE_ID, "RetailCrmUa", "add"); - + UnRegisterModuleDependences("sale", "OnSalePaymentEntitySaved", $this->MODULE_ID, "RetailCrmEvent", "paymentSave"); + UnRegisterModuleDependences("sale", "OnSalePaymentEntityDeleted", $this->MODULE_ID, "RetailCrmEvent", "paymentDelete"); + if (CModule::IncludeModule("catalog")) { if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/include/catalog_export/' . $this->RETAIL_CRM_EXPORT . '_run.php')) { $dbProfile = CCatalogExport::GetList(array(), array("FILE_NAME" => $this->RETAIL_CRM_EXPORT)); diff --git a/intaro.retailcrm/install/version.php b/intaro.retailcrm/install/version.php index bf151eed..3f805cfc 100644 --- a/intaro.retailcrm/install/version.php +++ b/intaro.retailcrm/install/version.php @@ -1,5 +1,5 @@ "2.2.5", - "VERSION_DATE" => "2017-09-22 18:00:00" + "VERSION" => "2.2.6", + "VERSION_DATE" => "2017-09-25 12:00:00" );