Применение только одной бОльшей (самой большой) скидки в КОРЗИНЕ и в ЗАКАЗЕ по каждому товару в отдельности
Золин Иван
Дата последнего входа:
17 суток назад
Страницы:1
Применение только одной бОльшей (самой большой) скидки в КОРЗИНЕ и в ЗАКАЗЕ по каждому товару в отдельности, Выбор бОльшей скидки в корзине и в заказе из накопительной, скидки на товар и правила корзины
Решение основывается на применение к товару кастомной цены.
1) Создаём файл largeDiscount.php для Class'a, к которому будем обращаться. Я ранее фигурировал в веб-студии WebIndigo, прост оставлю название класса этим словом, а так не важно.
3) Создаём файл admin_header.php для добавления кнопок в редактирование заказа из админки и их события:
/bitrix/php_interface/admin_header.php
Внутри его код:
Код
<? if (basename($_SERVER['PHP_SELF']) == 'sale_order_edit.php') { ?>
<sc ript src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></sc ript>
<? } ?>
<sc ript>
BX.ready(function () {
<? if (basename($_SERVER['PHP_SELF']) == 'sale_order_edit.php') {?>
$('.adm-detail-toolbar').find('.adm-detail-toolbar-right').append("<a href='jav * ascript:void(0)' oncl ick='shturmavik.resetDiscount(<?=$_REQUEST['ID']?>)' class='adm-btn'>1. Сброс бОльшей скидки</a><a href='jav * ascript:void(0)' oncl ick='BX.Sale.Admin.OrderEditPage.onRefreshOrderDataAndSave();' class='adm-btn'>2. Пересчитать</a><a href='jav * ascript:void(0)' oncl ick='shturmavik.recalculate(<?=$_REQUEST['ID']?>)' class='adm-btn'>3. ПРименить бОльшую скидку</a>");
<? } ?>
});
var shturmavik = {
resetDiscount: function (id) {
var post = {};
post['orderId'] = id;
post['action_manual'] = 'resetDiscount';
BX.ajax.post(
'/local/php_interface/include/Webindigo/largeDiscount.php',
post,
function (data) {
if (data == 1) {
location.reload();
}
console.log(data);
}
);
},
recalculate: function (id) {
var post = {};
post['orderId'] = id;
post['action_manual'] = 'recalculate';
BX.ajax.post(
'/local/php_interface/include/Webindigo/largeDiscount.php',
post,
function (data) {
if (data == 1) {
location.reload();
}
console.log(data);
}
);
},
}
</sc ript>
4) В яваскрипте шаблона добавляем функцию: (Пример: /local/templates/ВшШаблон/js/script.js)
Код
function refreshBasket() {
var post = {};
post['action_manual'] = 'customRefresh';
BX.ajax.post(
'/local/php_interface/include/Webindigo/largeDiscount.php',
post,
function (data) {
console.log(data);
}
);
}
5) Функция вызывается при добавлении товара в корзину.
Я добавил код в catalog.item и в catalog.element в конец функции basket: function () {...} Код такой:
Код
setTimeout(function(){refreshBasket();}, 1000)
6) Шаблон компонента sale.basket.basket должен быть в вашем пространстве имён. Пример:
в файл mutator.php добавляем строки выделенные моим комментом.
Код
<? if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();
use Bitrix\Main\Localization\Loc;
use Bitrix\Sale\PriceMaths;
/**
*
* This file modifies result for every request (including AJAX).
* Use it to edit output result for "{{ mustache }}" templates.
*
* @var array $result
*/
//1-й кусок - начало
//подключаем файл с логикой замены скидок - начало
if (count($this->basketItems) > 0)
{
Webindigo\CustomDiscount::largeDiscount('basket', \Bitrix\Sale\Fuser::getId());
}
//1-й кусок - конец
$mobileColumns = isset($this->arParams['COLUMNS_LIST_MOBILE'])
? $this->arParams['COLUMNS_LIST_MOBILE']
: $this->arParams['COLUMNS_LIST'];
$mobileColumns = array_fill_keys($mobileColumns, true);
$result['BASKET_ITEM_RENDER_DATA'] = array();
foreach ($this->basketItems as $row)
{
//2-й кусок - начало
//дополнительно три строки для просчета скидочной цены
$row['DISCOUNT_PRICE'] = (int)$row['BASE_PRICE'] - (int)$row['PRICE'];
$row['DISCOUNT_PRICE_FORMATED'] = (int)$row['BASE_PRICE'] - (int)$row['PRICE'] . ' р.';
$sum_discount_price_formated = ceil(((int)$row['SUM_FULL_PRICE'] - (int)$row['SUM_VALUE']) / 10) * 10;
$row['SUM_DISCOUNT_PRICE_FORMATED'] = number_format($sum_discount_price_formated, 0, ',', ' ') . ' р.';
//2-й кусок - конец
$rowData = array(
'ID' => $row['ID'],
'PRODUCT_ID' => $row['PRODUCT_ID'],
'NAME' => isset($row['~NAME']) ? $row['~NAME'] : $row['NAME'],
'QUANTITY' => $row['QUANTITY'],
...
...
...
...
Сюда /local/templates/ВашШаблон/components/bitrix/sale.basket.basket/.default/js/component.js
Добавляем в функции addCouponAction: function(event) и removeCouponAction: function() перезагрузку страницы в конец условия if (...){...в конец внутрь скобок }кодом
Код
setTimeout(function(){location.reload()}, 1000);
7) В правилах корзины раздела Маркетинг - Товарный маркетинг ставим у всех:
приоритет и сортировку по цифру ОДИН;
убираем обе галочки Прекратить ....;
8) При добавлении в корзину сразу идёт применение большей скидки. А если добавляем или удаляем купон, то идет перезагрузка и пересчёт.
В админке при редактировании заказа появляются три кнопки вверху, которые позволяют отменить бОльшую скидку или применить + важно делать всегда Пересчитать.
Если хотите применить купон к заказу, к уже сформировавшейся бОльшей скидке, то надо сделать сброс бОльшей скидки (увидите кнопку в админке в заказе, когда нажмёте Изменить заказ). Дальше Пересчитать -> Применить -> Вставить купон -> Пересчитать -> Применить.
И вот с этого момента можно сделать просчет. Бывает есть накопительная, правило корзины и еще скидка на товар.
Главное соблюдать последовательность, но она простая. Всё работает на данный момент идеально. Как будут изменения, я буду править всё выше написанное.
Даже для CUSTOM_PRICE = Y необходимо соблюдать условие BASE_PRICE = PRICE + DISCOUNT_PRICE. У вас оно нарушено. Обработку округлений в случае касмотных цен так же необходимо самому. Но основная проблема - ваша реализация не может работать с дополнительными условиями правил корзины (например, по числу позиций, их стоимости, etc).
Не надо сверлить зубы через задний проход дрелью от Сваровски
Даже для CUSTOM_PRICE = Y необходимо соблюдать условие BASE_PRICE = PRICE + DISCOUNT_PRICE. У вас оно нарушено. Обработку округлений в случае касмотных цен так же необходимо самому. Но основная проблема - ваша реализация не может работать с дополнительными условиями правил корзины (например, по числу позиций, их стоимости, etc).
На данный момент в объекте корзины текущего пользователя каждый товар имеет BASE_PRICE адекватную. А именно пример
Код
[PRICE] => 158.0000
[CUSTOM_PRICE] => Y
[BASE_PRICE] => 200.0000
По округлению цен, то разработчики смогут настроить для своего клиенты индивидуальные просчёты.
Правила корзины отрабатывают тоже - проверял несколько вариантов условий.
Покажите значение DISCOUNT_PRICE для вашего примера.
Проверил десяток вариантов. При передаче CUSTOM_PRICE = Y, DISCOUNT_PRICE всегда в ноль ставится в результате, а BASE_PRICE всегда в свою цену, которая без скидок. А стоит вернуть CUSTOM_PRICE = N, то появляется DISCOUNT_PRICE со значением скидки.
Пытался ими манипулировать, но выполняя все вычисления всегда у меня DISCOUNT_PRICE в ноль.
Я бы копнул ещё дальше, чтобы универсальным сделать, но мне нужны примеры, где есть конкретный неточный просчёт.
Так что кто применит этот код и у кого закосячит, разберусь. А так пока вот два сайта интернет-магазина с менеджерам работают с данным функционалом. По 20-40 заказов в день.
Жуков Евгений, я очень вам благодарен за комментарии.
Золин Иван написал: Я бы копнул ещё дальше, чтобы универсальным сделать, но мне нужны примеры, где есть конкретный неточный просчёт
Насколько помню, должны быть проблемы при печати чеков. Выполнение условия BASE_PRICE = PRICE + DISCOUNT_PRICE вне зависимости от значения CUSTOM_PRICE - это жесткое требование.
Цитата
Золин Иван написал: При передаче CUSTOM_PRICE = Y, DISCOUNT_PRICE всегда в ноль ставится в результате
Где? В базе после оформления заказа или в корзине? Если второе - это особенность компонента.
Цитата
Золин Иван написал: По округлению цен, то разработчики смогут настроить для своего клиенты индивидуальные просчёты.
Могут. Просто предупредите, что штатное округление с вашим решением не будет работать.
Не надо сверлить зубы через задний проход дрелью от Сваровски
Золин Иван написал: Я бы копнул ещё дальше, чтобы универсальным сделать, но мне нужны примеры, где есть конкретный неточный просчёт
Насколько помню, должны быть проблемы при печати чеков. Выполнение условия BASE_PRICE = PRICE + DISCOUNT_PRICE вне зависимости от значения CUSTOM_PRICE - это жесткое требование.
Цитата
Золин Иван написал: При передаче CUSTOM_PRICE = Y, DISCOUNT_PRICE всегда в ноль ставится в результате
Где? В базе после оформления заказа или в корзине? Если второе - это особенность компонента.
В метод getDataForCheck() '/bitrix/modules/sale/lib/cashbox/check.php' прилетает:
Код
'CUSTOM_PRICE' => 'Y',
'BASE_PRICE' => '180.0000', - то есть базовая цена есть
DISCOUNT_PRICE передаёт ноль и я не передам в его чек из-за особенности работы модуля.
Видим метод extractDataFromEntitiesInternal(array $entities) и код здесь /bitrix/modules/sale/lib/cashbox/check.php
написал: Что ни будь поменялось за это время? штатно появилась такая возможность? :/
Не я отключил этот функционал у себя и не развиваю. А на стороне битрикса надо пользоваться тем, что есть из коробки. Иначе будут конфликты в скидках
Страницы:1
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».