diff --git a/CHANGELOG.md b/CHANGELOG.md index a9652650..d2ed2aed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## 2022-02-03 v.5.8.5 +* Исправление ошибка восстановления отсутствующей отгрузки во время выгрузки истории из системы +* Исправлена ошибка обработки магазинов с кодами, содержащими ".", в настройках модуля +* Исправлен баг выгрузки заказов, связанный с неверным указанием namespace для LocationTable +* При обмене данными итоговая стоимость доставки теперь указывается принудительно +* Исправлена ошибка генерации icml для проиндексированных каталогов с простыми товарами +* Исправлена ошибка выгрузки клиентов, при которой одни и те же клиенты могли попасть в лист выгрузки повторно +* Исправления в документации + ## 2021-10-15 v.5.8.4 * Исправление некорректной генерации каталога при повторных запусках генерации diff --git a/README.md b/README.md index 20d73e7e..4457e402 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Bitrix module ============= -Bitrix module for interaction with [RetailCRM](http://www.retailcrm.ru) +Bitrix module for interaction with [RetailCRM](https://www.retailcrm.ru) Module allows: @@ -19,4 +19,4 @@ Installation You should install module through [Bitrix.Marketplace](http://marketplace.1c-bitrix.ru/solutions/intaro.retailcrm/). -[Setup guide](https://docs.retailcrm.ru/ru/Users/Integration/SiteModules/1CBitrix) +[Setup guide](https://docs.retailcrm.ru/Users/Integration/SiteModules/1CBitrix) diff --git a/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php b/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php index 19a90222..b9c59a31 100644 --- a/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php +++ b/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php @@ -532,7 +532,7 @@ class RetailCrmHistory continue; } - + $site = self::getSite($order['site']); if (null === $site) { @@ -1229,7 +1229,7 @@ class RetailCrmHistory return false; } - + /** * @param string $shopCode * @@ -1238,18 +1238,18 @@ class RetailCrmHistory public static function getSite(string $shopCode): ?string { $optionsSitesList = RetailcrmConfigProvider::getSitesList(); - + if ($optionsSitesList) { $searchResult = array_search($shopCode, $optionsSitesList, true); - + return is_string($searchResult) ? $searchResult : null; } - + $defaultSite = CSite::GetDefSite(); - + return is_string($defaultSite) ? $defaultSite : null; } - + /** * @param $array * @param $value @@ -1493,7 +1493,7 @@ class RetailCrmHistory return $orders; } - + /** * Filters out history by these terms: * - Changes from current API key will be added only if CMS changes are more actual than history. @@ -1512,7 +1512,7 @@ class RetailCrmHistory $history = []; $organizedHistory = []; $notOurChanges = []; - + foreach ($historyEntries as $entry) { if (!isset($entry[$recordType]['externalId'])) { if ($entry['source'] == 'api' @@ -1522,23 +1522,23 @@ class RetailCrmHistory ) { continue; } - + $history[] = $entry; - + continue; } - + $externalId = $entry[$recordType]['externalId']; $field = $entry['field']; - + if (!isset($organizedHistory[$externalId])) { $organizedHistory[$externalId] = []; } - + if (!isset($notOurChanges[$externalId])) { $notOurChanges[$externalId] = []; } - + if ($entry['source'] == 'api' && isset($entry['apiKey']['current']) && $entry['apiKey']['current'] == true @@ -1553,16 +1553,16 @@ class RetailCrmHistory $notOurChanges[$externalId][$field] = true; } } - + unset($notOurChanges); - + foreach ($organizedHistory as $historyChunk) { $history = array_merge($history, $historyChunk); } - + return $history; } - + /** * Update shipment in order * @@ -1623,24 +1623,28 @@ class RetailCrmHistory $shipmentColl = $order->getShipmentCollection(); if ($delivery) { - if (!$update) { + //В коллекции всегда есть одна скрытая системная доставка, к которой относятся нераспределенные товары + //Поэтому, если есть только системная доставка, то нужно создать новую + if (!$update || $shipmentColl->count() === 1) { $shipment = $shipmentColl->createItem($delivery); - $shipment->setFields(array( - 'BASE_PRICE_DELIVERY' => $orderCrm['delivery']['cost'], - 'CURRENCY' => $order->getCurrency(), - 'DELIVERY_NAME' => $delivery->getName(), + $shipment->setFields([ + 'BASE_PRICE_DELIVERY' => $orderCrm['delivery']['cost'], + 'PRICE_DELIVERY' => $orderCrm['delivery']['cost'], + 'CURRENCY' => $order->getCurrency(), + 'DELIVERY_NAME' => $delivery->getName(), 'CUSTOM_PRICE_DELIVERY' => 'Y' - )); + ]); } else { foreach ($shipmentColl as $shipment) { if (!$shipment->isSystem()) { - $shipment->setFields(array( - 'BASE_PRICE_DELIVERY' => $orderCrm['delivery']['cost'], - 'CURRENCY' => $order->getCurrency(), - 'DELIVERY_ID' => $deliveryId, - 'DELIVERY_NAME' => $delivery->getName(), + $shipment->setFields([ + 'BASE_PRICE_DELIVERY' => $orderCrm['delivery']['cost'], + 'PRICE_DELIVERY' => $orderCrm['delivery']['cost'], + 'CURRENCY' => $order->getCurrency(), + 'DELIVERY_ID' => $deliveryId, + 'DELIVERY_NAME' => $delivery->getName(), 'CUSTOM_PRICE_DELIVERY' => 'Y' - )); + ]); } } } diff --git a/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php b/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php index ad6ef492..9f0e019f 100644 --- a/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php +++ b/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php @@ -11,6 +11,7 @@ use Bitrix\Sale\Order; use RetailCrm\ApiClient; use Intaro\RetailCrm\Service\ManagerService; use RetailCrm\Response\ApiResponse; +use \Bitrix\Sale\Location\Name\LocationTable as LocationTableName; IncludeModuleLangFile(__FILE__); @@ -135,12 +136,12 @@ class RetailCrmOrder } } - $location = LocationTable::getList([ + $location = LocationTableName::getList([ 'filter' => ['=LOCATION_ID' => $arLoc['CITY_ID'], 'LANGUAGE_ID' => 'ru'] ])->fetch(); if (count($countrys) > 0) { - $countryOrder = LocationTable::getList([ + $countryOrder = LocationTableName::getList([ 'filter' => ['=LOCATION_ID' => $arLoc['COUNTRY_ID'], 'LANGUAGE_ID' => 'ru'] ])->fetch(); if(isset($countrys[$countryOrder['NAME']])){ @@ -161,7 +162,7 @@ class RetailCrmOrder //deliverys if (array_key_exists($arOrder['DELIVERYS'][0]['id'], $arParams['optionsDelivTypes'])) { $order['delivery']['code'] = $arParams['optionsDelivTypes'][$arOrder['DELIVERYS'][0]['id']]; - + if (isset($arOrder['DELIVERYS'][0]['service']) && $arOrder['DELIVERYS'][0]['service'] != '') { $order['delivery']['service']['code'] = $arOrder['DELIVERYS'][0]['service']; } @@ -192,7 +193,7 @@ class RetailCrmOrder $itemId = $orderItems[$externalId]['id']; $key = array_search('bitrix', array_column($externalIds, 'code')); - + if ($externalIds[$key]['code'] === 'bitrix') { $externalIds[$key] = [ 'code' => 'bitrix', @@ -228,7 +229,7 @@ class RetailCrmOrder } $catalogProduct = CCatalogProduct::GetByID($product['PRODUCT_ID']); - + if (is_null($catalogProduct['PURCHASING_PRICE']) === false) { if ($catalogProduct['PURCHASING_CURRENCY'] && $currency != $catalogProduct['PURCHASING_CURRENCY']) { $purchasePrice = CCurrencyRates::ConvertCurrency( @@ -244,7 +245,7 @@ class RetailCrmOrder } $item['discountManualPercent'] = 0; - + if ($product['BASE_PRICE'] >= $product['PRICE']) { $item['discountManualAmount'] = self::getDiscountManualAmount($product); $item['initialPrice'] = (double) $product['BASE_PRICE']; @@ -276,7 +277,7 @@ class RetailCrmOrder //payments $payments = []; - + foreach ($arOrder['PAYMENTS'] as $payment) { $isIntegrationPayment = RetailCrmService::isIntegrationPayment($payment['PAY_SYSTEM_ID'] ?? null); @@ -457,14 +458,14 @@ class RetailCrmOrder $resCustomersCorporate[$arCustomerCorporate['nickName']] = $arCustomerCorporate; } - $email = $arCustomer['email'] ?? ''; - - if (!in_array($email, $resCustomersAdded)) { - $resCustomersAdded[] = $email; + if ( + array_key_exists('externalId', $arCustomer) + && !in_array($arCustomer['externalId'], $resCustomersAdded, true) + ) { + $resCustomersAdded[] = $arCustomer['externalId']; $resCustomers[$order['LID']][] = $arCustomer; } - $resCustomers[$order['LID']][] = $arCustomer; $ordersPack[$order['LID']][] = $arOrders; $recOrders[] = $orderId; } @@ -709,7 +710,7 @@ class RetailCrmOrder foreach ($pack as $key => $itemLoad) { $site = self::getCrmShopCodeByLid($key, $optionsSitesList); - + if (null === $site && count($optionsSitesList) > 0) { continue; } @@ -839,14 +840,14 @@ class RetailCrmOrder $sumDifference = $product->get('BASE_PRICE') - $product->get('PRICE'); return $sumDifference > 0 ? $sumDifference : 0.0; } - + $discount = (double) $product->get('DISCOUNT_PRICE'); $dpItem = $product->get('BASE_PRICE') - $product->get('PRICE'); - + if ($dpItem > 0 && $discount <= 0) { return $dpItem; } - + return $discount; } } diff --git a/intaro.retailcrm/description.ru b/intaro.retailcrm/description.ru index f937918a..2864507d 100644 --- a/intaro.retailcrm/description.ru +++ b/intaro.retailcrm/description.ru @@ -1 +1 @@ -- Исправление некорректной генерации каталога при повторных запусках генерации +- Исправления ошибок в выгрузке заказов и генерации каталога diff --git a/intaro.retailcrm/install/version.php b/intaro.retailcrm/install/version.php index 1e4503c4..1c5d0c14 100644 --- a/intaro.retailcrm/install/version.php +++ b/intaro.retailcrm/install/version.php @@ -1,6 +1,6 @@ '5.8.4', - 'VERSION_DATE' => '2021-10-15 12:00:00', + 'VERSION' => '5.8.5', + 'VERSION_DATE' => '2022-02-03 12:00:00', ]; diff --git a/intaro.retailcrm/lib/icml/icmldirector.php b/intaro.retailcrm/lib/icml/icmldirector.php index fe702980..384a0437 100644 --- a/intaro.retailcrm/lib/icml/icmldirector.php +++ b/intaro.retailcrm/lib/icml/icmldirector.php @@ -251,7 +251,7 @@ class IcmlDirector do { //Если каталог проиндексирован, у товара есть Тип и это простой товар, то просто записываем его - if ($product->productType = ProductTable::TYPE_PRODUCT) { + if ($product->productType === ProductTable::TYPE_PRODUCT) { $this->icmlWriter->writeOffers([$product]); break; } diff --git a/intaro.retailcrm/lib/icml/xmlofferbuilder.php b/intaro.retailcrm/lib/icml/xmlofferbuilder.php index 4d8d3c85..c608cfba 100644 --- a/intaro.retailcrm/lib/icml/xmlofferbuilder.php +++ b/intaro.retailcrm/lib/icml/xmlofferbuilder.php @@ -225,7 +225,7 @@ class XmlOfferBuilder { $this->xmlOffer->id = $item['ID']; $this->xmlOffer->productId = $item['ID']; - $this->xmlOffer->productType = $item['CATALOG_TYPE']; + $this->xmlOffer->productType = (int) $item['CATALOG_TYPE']; $this->xmlOffer->quantity = $item['CATALOG_QUANTITY'] ?? ''; $this->xmlOffer->url = $item['DETAIL_PAGE_URL'] ? $this->defaultServerName . $item['DETAIL_PAGE_URL'] diff --git a/intaro.retailcrm/lib/model/bitrix/xml/xmloffer.php b/intaro.retailcrm/lib/model/bitrix/xml/xmloffer.php index 54b63980..1f37e13b 100644 --- a/intaro.retailcrm/lib/model/bitrix/xml/xmloffer.php +++ b/intaro.retailcrm/lib/model/bitrix/xml/xmloffer.php @@ -125,7 +125,7 @@ class XmlOffer * \Bitrix\Catalog\ProductTable::TYPE_SKU – товар с торговыми предложениями * \Bitrix\Catalog\ProductTable::TYPE_OFFER – торговое предложение * - * @var mixed + * @var int */ public $productType; diff --git a/intaro.retailcrm/options.php b/intaro.retailcrm/options.php index 2566e857..09c87545 100644 --- a/intaro.retailcrm/options.php +++ b/intaro.retailcrm/options.php @@ -212,7 +212,7 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) { //bitrix site list $siteListArr = []; - + foreach ($arResult['arSites'] as $arSites) { if (count($arResult['arSites']) > 1) { if ($_POST['sites-id-' . $arSites['LID']]) { @@ -414,8 +414,8 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) { function maskPrice($var){ return preg_match("/^shops-price/", $var); } - $bitrixPriceShopsArr = str_replace('shops-price-', '', array_filter(array_keys($_POST), 'maskPrice')); + $bitrixPriceShopsArr = array_values(array_filter($_POST, 'maskPrice', ARRAY_FILTER_USE_KEY)); $arResult['bitrixIblocksExportList'] = RCrmActions::IblocksExportList(); foreach($arResult['bitrixIblocksExportList'] as $bitrixIblocks){ if(htmlspecialchars(trim($_POST['iblocks-prices-' . $bitrixIblocks['ID']])) === 'Y'){ @@ -486,10 +486,12 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) { $cc = 'Y'; $bitrixCorpName = htmlspecialchars(trim($_POST['nickName-corporate'])); $bitrixCorpAdres = htmlspecialchars(trim($_POST['adres-corporate'])); + function maskCorp($var) { return preg_match("/^shops-corporate/", $var); } - $bitrixCorpShopsArr = str_replace('shops-corporate-', '', array_filter(array_keys($_POST), 'maskCorp')); + + $bitrixCorpShopsArr = array_values(array_filter($_POST, 'maskCorp', ARRAY_FILTER_USE_KEY)); RegisterModuleDependences("main", "OnBeforeProlog", $mid, "RetailCrmCc", "add"); } else { @@ -1394,7 +1396,10 @@ if (isset($_POST['Update']) && ($_POST['Update'] == 'Y')) {