Расчет скидок по акциям от list_price

Ну когда же, ну когда же…

То, что было актуально 20 лет назад, давно забыто и устарело нещадно, но в CS-Cart практикуется и поныне.
Цена и Базовая цена. Да, базовая цена (типа цена в других магазинах) еще 10 лет назад была на исходе своей популярности. Как то: Смотрите, почем продают другие, и какие хорошие мы.
Нет этого уже давно. Нет.
А у нас есть…
При этом показывает для покупателя скидку 20%.
Но стоит применить акцию для каталога в 10% - и да, вроде бы цена стала еще ниже, только покупатель будет видеть скидку в 10%, а не в 30%. И спросит: да что это такое, что за акция такая, когда скидка уменьшается???

А теперь рассмотрим вариант, когда за основу берем list_price, и от нее ведем расчет процентов скидок (ну все, все уже так делают, только не мы!). То есть меняем назначение этой цены - это не цена в других магазинах, а наша, наша основная цена!
Тогда price - дает легкий способ задать РАЗЛИЧНУЮ скидку на разные товары, вместо того, чтобы городить кучу акций чуть ли не по акции на каждый товар (если у них разные скидки).
А если товар подпадает под акцию для каталога - то и скидка по нему рассчитается соответствующая: list_price/цена_по_акции. Закончится акция - скидка вернется к начальному значению list_price/price.

Предлагаю проголосовать

  • У меня все настроено и менять ничего не хочу
  • Считаю что list_price вообще надо убрать
  • Расчет всех скидок для каталога от list_price сильно облегчит жизнь
0 проголосовавших

Вот только сегодня тоже думал о этой проблеме. У меня на сайте при регистрации человек получает дополнительные 5%.

И вот видит человек -25%, потом логинится и видит 5%.

И Чпятница становится уже не такой яркой…

Я походу за 4й вариант - Математику в Акциях считаю надо оставить текущую (от Цены), но размер всех скидок надо транслировать на витрине и в админке, в счетах именно от ЛистПрайс.
или это и есть “Расчет всех скидок для каталога от list_price сильно облегчит жизнь”
но тогда не “Расчет”, а скорее “демонстрация покупателю”

О всем наболевшем в одном посте :clap:

Я не считаю, что list_price надо убрать. У товара должно быть 2 цены (помимо оптовых): Цена и Цена со скидкой. Чтобы назначать скидку не акциями, а каждому товару отдельно в учётной системе.
Писал много раз об этом. Не знаю, каким путём это будет сделано. Я бы просто переименовал Рекомендованную цену в Цену и сделал это поле обязательным, а Базовую - в Цену Со Скидкой и убрал обязательность её заполнения.

Сейчас, если товар не имеет скидки, мы вынуждены устанавливать и грузить из 1С одинаковые цены в Базовую и в Рекомендуемую цены. Т.к. Базовая это как бы цена со скидкой, но это поле обязательное.

И я бы хотел, чтобы скидка на товар в процентах отображалась и в корзине и при оформлении заказа.

2 лайка

У нас продавцов более 100, и каждый спрашивал что значит рекомендованная?! :expressionless:

Изменить название поля не проблема. Надо механику менять.

Согласен с вами на все 100%!

А никого больше чехарда с ценами не достала? Тогда проголосуйте “меня все устраивает”. Или я забыл пункт “не верю, что что-то будет сделано”?

ну так чтобы показать - надо посчитать )

да я ктому, что если я делаю акцию для каталога,то хотел бы чтобы она отнимала например 10% от цены, а НЕ от Рекомендованной цены. Чтобы от нее считала! А показывала от Рекомендованной.

Я тут сейчас много вариантов перебрал, какие могут быть механики. И пожалуй пришел к выводу, что с наименьшей болью и ломанием логики различных вариантов (скидка на товар, скидка на количество, акции для каталога) - именно так

Возник интересный вопрос… Если у меня для группы покупателей скидка на количество от 1 штуки, и одновременно присутствует скидка на количество от 10, от 15 итд - для всех - что будет? :slight_smile: надо поэкспериментировать

Итак, решение “в лоб” (потому как только нашел, и слишком мало тестов провел).
ПОВТОРЮСЬ, ПРОВЕРИЛ ОДНОВРЕМЕННО ДЛЯ СКИДОК ЧЕРЕЗ СТАРУЮ / НОВУЮ, ПЛЮС ОДНА АКЦИЯ ДЛЯ КАТАЛОГА.
В этом случае работает.
Файл fn.products.php, функция fn_gather_additional_products_data
у меня 4.16.2SP1, в 4.17 могут незначительно строки отличаться
строка 674-676
вместо

        if (isset($product['price']) && !isset($product['base_price'])) {
            $product['base_price'] = $product['price']; // save base price (without discounts, etc...)
        }

пишем

        if (isset($product['price']) && !isset($product['base_price'])) {
            $product['base_price'] = $product['list_price']; // save base price (without discounts, etc...)
        }

этим мы показываем зачеркнутой list_price
Далее
строки 745-749

            // Change price
            if (isset($product['price']) && empty($product['modifiers_price'])) {
                $product['base_modifier'] = fn_apply_options_modifiers($selected_options, $product['base_price'], 'P', array(), array('product_data' => $product));
                $old_price = $product['price'];
                $product['price'] = fn_apply_options_modifiers($selected_options, $product['price'], 'P', array(), array('product_data' => $product));

Здесь

$old_price = $product['price'];

заменил на

$old_price = $product['list_price'];

Эта правка оказывает влияние также на отображение зачеркнутой цены.

И последнее
после строк 796-799

            if (empty($product['discount']) && !empty($product['list_price']) && !empty($product['price']) && floatval($product['price']) && $product['list_price'] > $product['price']) {
                $product['list_discount'] = fn_format_price($product['list_price'] - $product['price']);
                $product['list_discount_prc'] = sprintf('%d', round($product['list_discount'] * 100 / $product['list_price']));
            }

добавил еще строчку, получилось:

            if (empty($product['discount']) && !empty($product['list_price']) && !empty($product['price']) && floatval($product['price']) && $product['list_price'] > $product['price']) {
                $product['list_discount'] = fn_format_price($product['list_price'] - $product['price']);
                $product['list_discount_prc'] = sprintf('%d', round($product['list_discount'] * 100 / $product['list_price']));
            }
if (!empty($product['list_price']) && !empty($product['price']) && floatval($product['price']) && $product['list_price'] > $product['price']) {
$product['discount_prc']= sprintf('%d', round(fn_format_price($product['list_price'] - $product['price']) * 100 / $product['list_price']));    
} 

Проверил - процент скидки считается от list_price, зачеркнута - list_price, цена - с учетом разницы list_price/price и скидка по акции для каталога применена к price - всё как изначально и хотелось!

Но надо еще потестировать.
Поэтому если у кого есть тестовые установки и желание - приглашаю принять участие.

PS Предполагаю, что $product[‘discount_prc’] не рассчитывается, а берется значение, указанное в акции как бонус в процентах от цены, но еще поищу, может все-таки где-то рассчитывается выше по вызовам.

1 лайк

Ну вобщем потестировал, еще покопался…
Прав был Даниил Баженов лет десять назад - цены и акции в ядре настолько глубоко увязли, что лезть в эти дебри будет только безумец…

1 лайк

так не пытаться уже тестировать или шансы есть, что будет работать?

Да там жесть творится. В каталоге показывает общую скидку 28%, на карточке товара 26. На одном товаре вообще в карточке показывает 0%, когда в каталоге - 55%. Никакой системы не вижу.

1 лайк

Спасибо вам за труды!

Ну я всё же заморочился :rofl:
Уж больно много я теряю, исключив из использования пару list_price / price

ИТАК

я решил, что плевать с ним, с расчетом, как там будет показываться в корзине, в заказе и в счете - это дело второе. Главное - на странице категории и детальной странице товара показать ДЕЙСТВИТЕЛЬНУЮ, верную и ПОЛНУЮ скидку на товар, то есть от list_price.

Нам нужен только один файл - /design/themes/responsive/templates/common/product_data.tpl
Находим блок начинающийся строкой (у меня строка 240)

{********************** Old Price *****************}

и в нем наш новый код дожен выглядеть так:

{********************** Old Price *****************}
{capture name="old_price_`$obj_id`"}
    {if $show_price_values && $show_old_price}
        <span class="cm-reload-{$obj_prefix}{$obj_id}" id="old_price_update_{$obj_prefix}{$obj_id}">
            {hook name="products:old_price"}        
            {$list_price="SELECT list_price FROM ?:products WHERE product_id = ?i"|db_get_field:$product.product_id}
            {if $product.discount || $product.list_discount}
                <span class="ty-list-price ty-nowrap" id="line_old_price_{$obj_prefix}{$obj_id}">{if $details_page}{__("old_price")}: {/if}<span class="ty-strike">{include file="common/price.tpl" value=$list_price span_id="old_price_`$obj_prefix``$obj_id`" class="ty-list-price ty-nowrap"}</span></span>
            {/if}
            {*if $product.discount}
                {if !$product.included_tax}
                    <span class="ty-list-price ty-nowrap" id="line_old_price_{$obj_prefix}{$obj_id}">{if $details_page}{__("old_price")}: {/if}<span class="ty-strike">{include file="common/price.tpl" value=$product.list_price|default:$product.list_price - $product.tax_value span_id="old_price_`$obj_prefix``$obj_id`" class="ty-list-price ty-nowrap"}</span></span>
                {else}
                    <span class="ty-list-price ty-nowrap" id="line_old_price_{$obj_prefix}{$obj_id}">{if $details_page}{__("old_price")}: {/if}<span class="ty-strike">{include file="common/price.tpl" value=$product.original_price|default:$product.base_price span_id="old_price_`$obj_prefix``$obj_id`" class="ty-list-price ty-nowrap"}</span></span>
                {/if}
            {elseif $product.list_discount}
                {if !$product.included_tax}
                    <span class="ty-list-price ty-nowrap" id="line_list_price_{$obj_prefix}{$obj_id}">{if $details_page}<span class="list-price-label">{__("list_price")}:</span> {/if}<span class="ty-strike">{include file="common/price.tpl" value=$product.base_price - $product.tax_value span_id="list_price_`$obj_prefix``$obj_id`" class="ty-list-price ty-nowrap"}</span></span>
                {else}
                    <span class="ty-list-price ty-nowrap" id="line_list_price_{$obj_prefix}{$obj_id}">{if $details_page}<span class="list-price-label">{__("list_price")}:</span> {/if}<span class="ty-strike">{include file="common/price.tpl" value=$product.base_price span_id="list_price_`$obj_prefix``$obj_id`" class="ty-list-price ty-nowrap"}</span></span>
                {/if}
            {/if*}
            {/hook}
        <!--old_price_update_{$obj_prefix}{$obj_id}--></span>
    {/if}
{/capture}

здесь нами добавлена 6, 7, 8 и 9-я строки. строки с 10 по 22-ю исключаем, обнеся их смарти-комментарием. Конечно здесь есть хук и можно вынести в модуль оверрайдом хука, но ниже нам надо еще переписать лейбл скидки, и там хука нет, поэтому всё равно в этот файл придется вносить правки.

Идем дальше, и ищем блок, начинающийся строкой (у меня строка 364)

{************************************ Discount label ****************************}

здесь мы вставляем код

{************************************ Discount label ****************************}
{capture name="discount_label_`$obj_prefix``$obj_id`"}
    {if $show_discount_label && ($product.discount_prc || $product.list_discount_prc) && $show_price_values}
        <span class="ty-discount-label cm-reload-{$obj_prefix}{$obj_id}" id="discount_label_update_{$obj_prefix}{$obj_id}">
        {$discount=(($list_price-$price)*100/$list_price)|round}
        <span class="ty-discount-label__item" id="line_prc_discount_value_{$obj_prefix}{$obj_id}"><span class="ty-discount-label__value" id="prc_discount_value_label_{$obj_prefix}{$obj_id}">{__("save_discount")} {$discount}%</span></span>
{*            <span class="ty-discount-label__item" id="line_prc_discount_value_{$obj_prefix}{$obj_id}"><span class="ty-discount-label__value" id="prc_discount_value_label_{$obj_prefix}{$obj_id}">{__("save_discount")} {if $product.discount}{$product.discount_prc}{else}{$product.list_discount_prc}{/if}%</span></span>*}
        <!--discount_label_update_{$obj_prefix}{$obj_id}--></span>
    {/if}
{/capture}
{if $no_capture}
    {$capture_name = "discount_label_`$obj_prefix``$obj_id`"}
    {$smarty.capture.$capture_name nofilter}
{/if}

наши добавленные строки 5-я и 6-я, а 7-ю строку - оборачиваем в смарти-комментарий

ТЕСТЫ

Категории:

категория 1
--- категория 1.1
категория 2

товар 1:
Рекомендованная цена 120000 Цена 100000
Категория 1
В оптовых скидках - 10% для Зарегистрированных от 1 шт
товар 2:
Рекомендованная цена 450000 Цена 155000
Категория 1, категория 1.1
товар 3:
Рекомендованная цена 77000 Цена 77000
Категория 1

Можно усложнить код шаблона, но я не стал - главное условие сейчас, чтобы Рекомендованная цена нигде не была равна нулю. То есть, если скидки в каталоге нет - просто ставим
Рекомендованная цена = Цена

Акции для каталога

Скидка на 5000:
Условие - товар в категории 1.1
Бонус - скидка на товар в размере 5000 Р

Скидка 25%:
Условие - Группа покупателя - Зарегистрированные
Бонус - скидка на товар в размере 25%

Вобщем, что в каталоге, что в карточке товара пока показывает всё верно

2 лайка

Парни, давайте скинемся и @alex_vp купим Оскар, действительно огромное вам спасибо за ваши труды! Низкий поклон :clap:

Пока рано ))
В принципе, знаю как убрать обязательное заполнение рекомендованной цены, но это еще одно условие и еще один sql запрос из шаблона. но видимо придется вставить.

Хотя сейчас смотрю как вынести расчеты в хук к функции fn_gather_additional_products_data доп полями массива $product и пользовать именно их в шаблоне.
Но это чуть позже…

Думаю к вам ТП и не присоединиться для упрощения решения данной проблемы ))