Добрый день.
У нас CS-Cart 4.12.2 RU. Используются модули поставщиков (версии 1.0) и синхронизации с RetailCRM ([Beta] версии 1.0).
Если добавить в заказ несколько товаров с разными поставщиками (допустим, разных поставщиков N штук), у которых разные способы доставки, то при каждой синхронизации (которая затронет заказ, если он в RetailCRM редактировался) количество выбранных доставок будет увеличиваться в N×количество_выбранных_способов_доставки_на_момент_перед_синхронизацией раз.
ПОЧЕМУ ЭТО ПРОИСХОДИТ
Если в заказе есть товары с разными поставщиками, создаётся несколько групп товаров [‘product_groups’], каждый со своими способами доставки [‘product_groups’][‘chosen_shippings’].
При синхронизации вызывается функция syncOrder, которая описана в файле
/app/addons/retailcrm/Tygh/Addons/Retailcrm/Service.php
В этом файле вызовом функции fn_form_cart формируется корзина заказа:
if ($order['order_id'] && !fn_form_cart($order['order_id'], $cart, $auth)) { $this->logger->error( sprintf('Order #%d not found.', $order['order_id']), __METHOD__ ); return false; }
Чуть ниже сохраняются способы доставки в переменную $shippings:
$shippings = isset($cart[‘shipping’]) ? $cart[‘shipping’] : array();
Затем обнуляется подмассив product_groups:
$cart[‘product_groups’] = array();
Ещё ниже видим код, где каждой группе товаров прописывается значение $shippings, т.е. по сути значение $cart[‘shipping’].
if (!isset($order['shipping_ids']) || $order['shipping_ids'] == reset($chosen_shipping_ids)) { $cart['shipping'] = $shippings; foreach ($cart['product_groups'] as &$product_group) { $product_group['chosen_shippings'] = $shippings; } unset($product_group); }
Ответвление 1: как из таблицы cscart_order_data вытаскивается значение shipping. Значение $cart[‘shipping’] появляется в функции fn_get_order_info. Путь такой: syncOrder вызывает fn_form_cart, тот вызывает fn_get_order_info. Вот код из fn_get_order_info:
// Get shipping information if (!empty($additional_data[OrderDataTypes::SHIPPING])) { $order['shipping'] = unserialize($additional_data[OrderDataTypes::SHIPPING]);
Ответвление 2: вернёмся к syncOrder и проследим, как будет сохраняться OrderDataTypes::SHIPPING. Путь такой: syncOrder вызывает fn_update_order, тот fn_update_order_data, в котором есть такой код:
// Save shipping information $chosen_shippings = array(); foreach ($cart['product_groups'] as $group) { $group_shipping = !empty($group['chosen_shippings']) ? $group['chosen_shippings'] : array(); $chosen_shippings = array_merge($chosen_shippings, $group_shipping); } fn_apply_stored_shipping_rates($cart, $order_id); $_data[] = array ( 'order_id' => $order_id, 'type' => OrderDataTypes::SHIPPING, //shipping information 'data' => serialize($chosen_shippings), );
Как видим, в shipping попадает объединённый массив всех chosen_shippings разных групп товаров заказа.
Отмечу, что в том же fn_update_order_data отдельно прекрасно сохраняется OrderDataTypes::GROUPS, а в fn_get_order_info также прекрасно обратно вытаскивается и записывается в подмассив product_groups.
В итоге получаем такой цикл:
- Из базы берётся значение OrderDataTypes::SHIPPING и записывается в [‘shipping’]
- В список способов доставки каждой группы товаров [‘product_groups’][‘chosen_shippings’] записывается список способов доставки из [shipping].
- Перед сохранением в базу происходит объединение способов доставки каждой группы товаров и записывается в OrderDataTypes::SHIPPING.
На каждой итерации количество доставок вырастает в количество групп товаров раз.
КАК ВОСПРОИЗВЕСТИ ПРОБЛЕМУ
Имеет товары Т1 и Т2, поставщики П1 и П2 и способы доставки Д1 и Д2. Товару Т1 прописываем поставщика П1, к которому привязываем способ доставки Д1. Товару Т2 прописываем поставщика П2, к которому привязываем способ доставки Д2.
Способу доставки Д1 проставляем соответствие со способом доставки в RetailCRM, Д2 не проставляем.
Идём на витрину, добавляем Т1 и Т2 в корзину, выбираем способы доставки Д1 и Д2, размещаем заказ.
Заходим в RetailCRM, меняем в заказе что-нибудь (например, комментарий оператора), сохраняем.
Ждём синхронизацию или вызываем её вручную.
Наблюдаем в админке cs-cart’а у нашего заказа задвоение способов доставки.
СОБСТВЕННО, ВОПРОС
Как исправить баг? я закомментировал эту строку в orderSync:
// $cart['product_groups'] = array();
и здесь одну:
if (!isset($order['shipping_ids']) || $order['shipping_ids'] == reset($chosen_shipping_ids)) { $cart['shipping'] = $shippings; foreach ($cart['product_groups'] as &$product_group) { // $product_group['chosen_shippings'] = $shippings; } unset($product_group); }
Догадываюсь, что это было не просто так написано. Как исправить, чтобы работало во всех случаях без сбоев?