Как изменить логику формирование цены в OpenCart
Какая логика формирование цены на товар в OpenCart и зачем её менять?
Отвечу на первый вопрос…, логика очень простая, к товару вы добавляете различные опции, будь то select (выбор), image (выбор с картинкой), checkbox (флажок), radio (радио кнопка). К каждой опции вы можете добавить её стоимость, например для опции “Комплектация” типа checkbox, я добавил стоимость к каждой опции: 10, 20 и 25 рублей:
Это означает, если покупатель выберет данную опцию, то к стоимости товара прибавляется стоимость данной опции. В панели адмнистратора, вы можете выбрать вместо “+” знак “-“, тогда при выборе опции от стоимости товара будет отниматься стоимость опции. В интернете существует модули для OpenCart, позволяющие добавить знак “*” и “/”, т.е. результирующая стоимость будет получается путем умножением или делением стоимости товара к стоимости опции.
Если есть такие возможности, то зачем что-то менять?
Я тоже так думал, но однажды, выполняя заказ на мебельный интернет-магазин для OpenCart. Заказчик попросил меня сделать следующие: “Я хочу, что-бы у каждого товара, был выбор комплектации, выбор габарита и выбор материала.”
Поясню для наглядности с помощью картинки:
Синия стрелка – это выбор габаритов, т.е. опция radio, красная стрелка – это выбор материалов, т.е. опция image и зеленая – это выбор комплектации, т.е. checkbox.
При выборе габаритов устанавливается стилизованная зеленая галка, при выборе комплектации устанавливается стандартный флажок в квадрат. При выборе “Основной материал” снизу выдвигался каталог материалов, т.е. просто показываются опции image, аналогично при выборе “Материал компаньон”. Все просто и сделать это не трудно, достаточно немного по колдовать с CSS.
Теперь как формируется цена. При выборе габарита, к цене товара прибавлялась надбавка, с этим справляется стандартная логика формирования цены OpenCart, просто указываем напротив каждой опции его стоимость как на первом рисунке. Также и с комплектацией, при выборе “вешалок” и “штанга для вещей” к стоимости товара прибавлялась стоимость данных опций, тут все стандартно и просто.
Проблемы возникли, когда заказчик захотел: “пусть при выборе материалов к стоимости товара прибавляется не каждый а максимальный по стоимости“. Т.е. если пользователь выбрал материал из “Основных материалов” за 200 рублей, а из “Материалов компаньона” выбрал материал за 500 рублей, то к стоимости товара должно прибавится не +700 рублей как обычно, а +500 рублей (т.е. прибавляется максимальная выбранная опция).
Это стандартный механизм формирование стоимости OpenCart сделать не мог, а заказ нужно было выполнять…
Как бы просто это не казалось, ответ не лежит на поверхности.
Поиски в интернете результата не давали, модулей решение данной проблемы вы тоже не найдете, на форумах вам возможно подскажут сменить CMS как не годную. Я решил данную проблему и хочу подсказать её вам, давайте разберемся где в OpenCart находится логика формирование стоимости товара и как её изменять
Как изменить логику формирования стоимости товара?
Стоимость товара формируется в системной файле движка
\system\library\cart.php
За прибавление к стоимости товара стоимость выбранных опций на странице отвечает большой цикл:
foreach ($options as $product_option_id => $option_value) { ... ... ... }
В нем находятся IF-ы, для каждого типа опций, т.е. для select, image, checkbox и т.д. В каждом IF-е, есть кусок кода, отвечающий как раз логику формирование цены, т.е. если мы выбрали “+” в настройках опции (см. первый рисунок) то к текущей стоимости прибавится стоимость опции, если минус, то от текущей отнимется:
if ($option_value_query->row['price_prefix'] == '+') { $option_price += $option_value_query->row['price']; } elseif ($option_value_query->row['price_prefix'] == '-') { $option_price -= $option_value_query->row['price']; }
Вот эту логику можно изменять, для каждого типа опции.
Например для нашего случая, нам нужно изменить логику формирования цены для опций типа “image” (выбор материалов). Нужно сделать так, что-бы цена копилась в неком массиве, а после “большого цикла” foreach добавить к стоимости товара максимум из этого массива.
Реализуется это так, перед “большим циклом” foreach ($options as $product_option_id => $option_value) {
добавляем объявление массива и переменную счетчик, т.е должно получится так:
$count=0; /* счетчик индекса массива */ $option_temp= array(); /* массив куда быдем класть стоимость выбранных опций-image (выбранных материалов) */ foreach ($options as $product_option_id => $option_value) { ... ... ... }
А в IF отвечающий за тип image
if ($option_query->row['type'] == ‘select’ || $option_query->row['type'] == ‘radio’ || $option_query->row['type'] == ‘image’) {
нужно вместо стандартного if-а
написать модернезированный для нашего случая
if ($option_value_query->row['price_prefix'] == '+') { if($option_query->row['type'] == 'image') { /* если тип image, стоимость выбранных опций кладем в массив */ $option_temp[$count]=$option_value_query->row['price']; /* кладем в массив стоимость выбранных опций image */ $count++; /* прибавляем к счетчику */ } else { /* если иной другой тип (т.е. select,radio) то поступаем стандартно, суммируем */ $option_price += $option_value_query->row['price']; } } elseif ($option_value_query->row['price_prefix'] == '-') { $option_price -= $option_value_query->row['price']; }
Добавим после “большого цикла” foreach ($options as $product_option_id => $option_value) {
следующий код:
$option_price+=max($option_temp); /* к текущей стоимости прибавляем максимум от выбранных опций - image (материалы) */
Что в итоге?
В итоге я показал вам, где мы можем изменять логику формирования стоимости товара. Например как для моего случая, все опции просто прибавляются к стоимости товара как и раньше, кроме image, в нем прибавляется лишь максимальная из выбранных.
К сожалению есть и минусы, измененный системный файл “\system\library\cart.php” при обновление OpenCart скорее всего будут заменены более свежими, поэтому данные изменения придется делать заново. Но для данной CMS это единственный способ.