====== Наценка на товары ======
Некоторые интернет-магазины предлагают различные опциональные дополнительные услуги для заказываемых товаров, эти услуги выбираются пользователем на этапе оформления заказа в корзине и влияют на окончательную стоимость заказа. Например, интернет-магазин по продаже какого-то сложного оборудования может предлагать услугу по настройке оборудования, за которую к товарам должна добавляться наценка.
{{:private:koding:hostcms:shop:cart:pasted:20170123-125133.png}}
Для реализации подобного механизма можно использовать данное решение.
Стандартного механизма для хранения наценки по каждому товару в корзине и заказе не предусмотрено, поэтому необходимо придумать механизм хранения этой информации. Изначально, когда заказ еще не создан будем хранить информацию о наценках в сессии, когда пользователь оформит заказ эта информация запишется в доп. свойство заказа и с помощью наблюдателей будет прикрепляться к товарам заказа. Цена товаров, для которых будет выбрана наценка, будет подменятся с помощью наблюдателя при выводе корзины, будут учитываться данные сессии или данные из доп. свойства заказа.
===== Константы =====
Добавляем константу ''MARKUP_FOR_TEST_PRODUCTS'' со значением равным величину наценки.
===== Доп. свойство для заказа ====
Идем в заказы интернет-магазина и добавляем новое доп. свойство с названием «Системная информация о наценках», типом «Большое текстовое поле» и XML-тегом ''markups'', запрещаем множественные значения. Это поле будет использоваться решением для хранения информации о наценках на товары заказа.
===== XSL-шаблон =====
В XSL-шаблон корзины добавить колонку для выбора товаров для наценки, например, так:
===== Наблюдатели =====
Для начала необходимо загрузить 4 наблюдателя.
==== Наблюдатель для вывода наценки в заказе и ЦА (1) ====
* Загружаем файл: [[private:koding:hostcms:modules:shop:cart:markup:additionalfields.php|/modules/shop/order/item/observer/additionalfields.php]]
* Добавляем в bootstrap.php:Core_Event::attach('shop_order_item.onCallmarkup', array('Shop_Order_Item_Observer_AdditionalFields', 'onCallmarkup'));
==== Наблюдатель для подмены цены товара (2) ====
Загружаем файл: [[private:koding:hostcms:modules:shop:cart:markup:addmarkuptoprice.php|/modules/shop/item/controller/observer/addmarkuptoprice.php]]
==== Наблюдатель для прикрепления наценки к корзине (3) ====
Загружаем файл: [[private:koding:hostcms:modules:shop:cart:markup:attachmarkup.php|/modules/shop/cart/controller/show/observer/attachmarkup.php]]
===== Формы центра администрирования =====
Идем в раздел Системы → Формы центра администрирования, находим форму «Список товаров в заказе», добавляем к ней поле новое поле «Наценка» с ключевым полем ''markup'' и типом «Вычисляемое поле (Используется обратный вызов функции)».
Это поле будет формироваться наблюдателем (1), подключенным в bootstrap.php и в центре администрирования должно выглядеть так:
{{:private:koding:hostcms:shop:cart:pasted:20170123-150540.png}}
* Необходимо обратить внимание, что стоимость товара здесь выводится с учетом наценки, а наценка выступает в качестве информационного поля. Для вывода цены без наценки можно использовать метод ''Shop_Order_Item_Observer_AdditionalFields::onCallprice_without_markup'', создав аналогично полю ''markup'' поле ''price_without_markup'', а оригинальное поле с ценой из форм ЦА удалить. При этом в карточке товара в заказе все равно будет выводится цена товара с наценкой.
===== ТДС корзины =====
==== Настройки страницы ====
- Код вывода краткой корзины оборачиваем в наблюдатель:
Core_Event::attach('Shop_Item_Controller.onAfterCalculatePrice', array('Shop_Item_Controller_Observer_AddMarkupToPrice', 'onAfterCalculatePrice'));После вывода:Core_Event::detach('Shop_Item_Controller.onAfterCalculatePrice', array('
Shop_Item_Controller_Observer_AddMarkupToPrice', 'onAfterCalculatePrice'));Должно быть так:Core_Event::attach('Shop_Item_Controller.onAfterCalculatePrice', array('Shop_Item_Controller_Observer_AddMarkupToPrice', 'onAfterCalculatePrice'));
$Shop_Cart_Controller_Show
->xsl(
Core_Entity::factory('Xsl')->getByName(
Core_Array::get(Core_Page::instance()->libParams, 'littleCartXsl')
)
)
->couponText(Core_Array::get($_SESSION, 'coupon_text'))
->show();
Core_Event::detach('Shop_Item_Controller.onAfterCalculatePrice', array('Shop_Item_Controller_Observer_AddMarkupToPrice', 'onAfterCalculatePrice'));
- В настройках ТДС в коде пересчета/обновления корзины добавляем код для обработки добавленного чекбокса. Перед циклом добавляем:
$aMarkups = Core_Array::getSession('hostcmsCartMarkups', array());Внутри цикла:
$markup = Core_Array::getRequest('markup_' . $oShop_Cart->shop_item_id);
if (!is_null($markup))
{
$aMarkups[$oShop_Cart->shop_item_id] = MARKUP_FOR_TEST_PRODUCTS;
}
elseif (isset($aMarkups[$oShop_Cart->shop_item_id]))
{
unset($aMarkups[$oShop_Cart->shop_item_id]);
}После цикла:
$_SESSION['hostcmsCartMarkups'] = $aMarkups;
==== Код страницы ====
- Перед оператором switch для разделения на шаги:Core_Event::attach('Shop_Item_Controller.onAfterCalculatePrice', array('Shop_Item_Controller_Observer_AddMarkupToPrice', 'onAfterCalculatePrice'));После:Core_Event::detach('Shop_Item_Controller.onAfterCalculatePrice', array('Shop_Item_Controller_Observer_AddMarkupToPrice', 'onAfterCalculatePrice'));
- На 4-ом шаге внутри условия:if ($_SESSION['hostcmsOrder']['shop_payment_system_id'])
{Перед вызовом ''Shop_Payment_System_Handler::execute'' добавляем:$oShopOrderPropertyList = Core_Entity::factory('Shop_Order_Property_List', $oShop->id);
$oProperty = $oShopOrderPropertyList->Properties->getByTagName('markups');
if ($oProperty)
{
$_SESSION['hostcmsOrder']['properties'][] = $aProperty = array($oProperty->id, json_encode($_SESSION['hostcmsCartMarkups'], JSON_PRETTY_PRINT));
}
Core_Event::attach('shop_order_item.onBeforeRedeclaredGetXml', array('Shop_Order_Item_Observer_AdditionalFields', 'onBeforeRedeclaredGetXml'));После вызова:Core_Event::detach('shop_order_item.onBeforeRedeclaredGetXml', array('Shop_Order_Item_Observer_AdditionalFields', 'onBeforeRedeclaredGetXml'));
$_SESSION['hostcmsCartMarkups'] = array();
- Для ветки ''default'' перед выводом корзины добавляем:Core_Event::attach('Shop_Cart_Controller_Show.onBeforeRedeclaredShow', array('Shop_Cart_Controller_Show_Observer_AttachMarkup', 'onBeforeRedeclaredShow'));После:Core_Event::detach('Shop_Cart_Controller_Show.onBeforeRedeclaredShow', array('Shop_Cart_Controller_Show_Observer_AttachMarkup', 'onBeforeRedeclaredShow'));
===== Основной макет =====
Если в основном макете есть вывод краткой корзины, то его также нужно обернуть в следующий наблюдатель:
Core_Event::attach('Shop_Item_Controller.onAfterCalculatePrice', array('Shop_Item_Controller_Observer_AddMarkupToPrice', 'onAfterCalculatePrice'));После вывода:Core_Event::detach('Shop_Item_Controller.onAfterCalculatePrice', array('
Shop_Item_Controller_Observer_AddMarkupToPrice', 'onAfterCalculatePrice'));Страницу создал Максим Засорин 23.01.17 в 12:33