Отображение скидки в процентах

Отображение скидки в процентах

Небольшая модификация, позволяющая отобразить размер скидки в процентах. Пример для модулей "последние товары" и "специальные предложения", аналогично делается и для других страниц.

Для примера использую модуль вывода товаров с акциями. Необходимо отредактировать два файла:

"/catalog/controller/module/special.php" и "/catalog/view/theme/default/template/module/special.tpl"

Для подсчета процентов будет использована основная стоимость товара (без скидки) и стоимость товара по акции. Стоимость товара в шаблон выводится с символами валюты, а для подсчета нужна стоимость в виде чисел, соответственно редактируем контроллер.

Изменения для модулей и категорий

1. Изменения в контроллере. (/catalog/controller/module/special.php)

Находим:

if ((float)$result['special']) {
$special = $this->currency->format($this->tax->calculate($result['special'], $result['tax_class_id'], $this->config->get('config_tax')));
} else {
$special = false;
}

И меняем на:

if ((float)$result['special']) { 
$special = $this->currency->format($this->tax->calculate($result['special'], $result['tax_class_id'], $this->config->get('config_tax')));
$skidka = round(100-($result['special']/($result['price']/100)))
} else {
$skidka = false;
$special = false;
}

Затем:

$this->data['products'][] = array(
				'product_id' => $result['product_id'],
				'thumb'   	 => $image,
				'name'    	 => $result['name'],
				'price'   	 => $price,
				'special' 	 => $special,
				'rating'     => $rating,
				'reviews'    => sprintf($this->language->get('text_reviews'), (int)$result['reviews']),
				'href'    	 => $this->url->link('product/product', 'product_id=' . $result['product_id'])
			);

Меняем на:

$this->data['products'][] = array(
				'product_id' => $result['product_id'],
				'thumb'   	 => $image,
				'name'    	 => $result['name'],
				'price'   	 => $price,
				'special' 	 => $special,
				'skidka' 	 => $skidka,
				'rating'     => $rating,
				'reviews'    => sprintf($this->language->get('text_reviews'), (int)$result['reviews']),
				'href'    	 => $this->url->link('product/product', 'product_id=' . $result['product_id'])
			);

Opencart 2

Для Opencart 2 код будет примерно такой же, поэтому переписывать не буду, найти не сложно. Еще один момент - в некоторых модулях вместо "$result" может использоваться "$product_info", соответственно тогда вычислять нужно так:

$skidka = 100-($product_info['special']/($product_info['price']/100));

2. Изменения в шаблоне (/catalog/view/theme/default/template/module/special.tpl):

После:

<span class="price-old"><?php echo $product['price']; ?></span> <span class="price-new"><?php echo $product['special']; ?></span>

Добавляем:

<div class="procent"><?php echo $product['skidka']; ?> % <span>Скидка</span></div>

3. Немного изменений в css:

.procent { position: absolute; top: 5px; left: 5px; background: rgba(255, 0, 0, 0.57); border-radius: 50px; width: 100px; height: 75px; padding-top: 25px; text-align: center; font-size: 30px; color: #fff; text-shadow: 0px 0px 5px #520202; }
.procent span {display: block; font-size: 15px;}
.box-product > div:hover .procent {box-shadow: 0px 0px 5px #FDDF00;}

Учитывая, что для ".procent" было задано абсолютное позиционирование, добавим для блока с товаром "position:relative"

.box-product > div{ position: relative;}

Результат:

Изменения для карточки товара

Что касается страницы товара, здесь будут небольшие отличия. Так же немного изменю код

1. Контроллер - /catalog/controller/product/product.php

Находим:

if ((float)$product_info['special']) {
				$this->data['special'] = $this->currency->format($this->tax->calculate($product_info['special'], $product_info['tax_class_id'], $this->config->get('config_tax')));
			} else {
				$this->data['special'] = false;
			}

И меняем на:

if ((float)$product_info['special']) {
				$this->data['special'] = $this->currency->format($this->tax->calculate($product_info['special'], $product_info['tax_class_id'], $this->config->get('config_tax')));
$this->data['skidka'] = round(100-($product_info['special']/($product_info['price']/100)));
			} else {
				$this->data['special'] = false;
	$this->data['skidka'] = false;
			}

Для Opencart 2:

$data['skidka'] = 100-($product_info['special']/($product_info['price']/100));

2. Теперь шаблон товара (/catalog/view/theme/default/template/product/product.tpl):

Находим:

   <?php if (!$product['special']) { ?>
          <?php echo $product['price']; ?>
          <?php } else { ?>
          <span class="price-old"><?php echo $product['price']; ?></span> <span class="price-new"><?php echo $product['special']; ?></span>
          <?php } ?>

И меняем на:

              <?php if (!$product['special']) { ?>
          <?php echo $product['price']; ?>
          <?php } else { ?>
          <span class="price-old"><?php echo $product['price']; ?></span> <span class="price-new"><?php echo $product['special']; ?></span>
           <div class="procent">
           <?php echo $product['skidka']; ?>% <span>Скидка</span> 
           </div>
          <?php } ?>

Не забываем добавить position:relative для блока с товаром. Для похожих товаров на этой странице изменения будут аналогичны категориям и модулям.

Opencart 3

Изменения коснутся только шаблонов, нужно переписать под новый шаблонизатор. Пример для контроллера и шаблона товара (product.php, product.twig), только на этот раз на примере основной цены.

Для начала добавим скидку в контроллер

if ((float)$product_info['special']) {
				$data['special'] = $this->currency->format($this->tax->calculate($product_info['special'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']);
				/*++++*/$data['skidka'] = round(100-($product_info['special']/($product_info['price']/100)));/*++++*/
			} else {
				$data['special'] = false;
				/*++++*/$data['skidka'] = false;/*++++*/
			}

Изменения отмечены /*++++*/

Теперь карточка товара, в нужном месте:

{% if skidka %}
<div class="procent">{{ skidka }}</div>
{% endif %}
Сказать $пасибо

Комментарии ()

  1. 222 14 августа 2019, 18:17
    0

    На Опенкарт 3 есть решение?

    1. Владимир 15 августа 2019, 00:41
      0

      Добавил. Там разница в шаблонах только из за использования twig

    2. Владимир 20 апреля 2017, 02:02
      0

      Статья огонь, но на OCStore 2.1.0.2.1 не работает (

      1. Владимир 20 апреля 2017, 14:53
        0

        подскажите, с чем может быть связано, делаю все по описанию, но результата не вижу, ес-но кэш чищу

        1. Владимир 07 мая 2017, 03:21
          0

          Оказывается менять special.tpl надо не только в module, но и в product, тогда выводит

          1. Владимир 07 мая 2017, 17:48
            0

            (extension)/module/special — модуль
            product/special — страница с товарами со скидкой
            В общем то разные вещи

            1. Владимир 07 мая 2017, 17:51
              0

              Код отличается, однако по другому не работает, с чем связано понятия не имею

      2. Svetka0403 06 апреля 2017, 03:46
        0

        В категориях все вывелось без проблем, а в товаре скидку не считает, пишет 0%. Ошибок не выдает
        Подскажите пожалуйста что не так? Вот код

        1. Mehanic 16 марта 2017, 19:11
          0

          Не хватает знака; в 1 пункте после $skidka = round(100-($result['special']/($result['price']/100)))

          1. саша 24 октября 2016, 07:34
            0

            в категории нормалньо выводит, на продукте ошибка

            Notice: Undefined variable: skidka in Z:\home\rue21\www\catalog\controller\product\product.php on line 440Notice:
            $data['products'][] = array(

            'skidka' => $skidka,

            1. Владимир 24 октября 2016, 07:49
              0

              Это похоже для похожих товаров в карточке… Немного выше видимо нет:

              $skidka = 100-($product_info['special']/($product_info['price']/100));

              1. саша 24 октября 2016, 09:06
                0

                нет в контроллере только один массив
                $this->data['products'][] = array(
                и он ругается на 'skidka' => $skidka,

                1. Владимир 24 октября 2016, 09:11
                  0

                  он говорит, что "$skidka" найти не может.
                  Чуть выше найдите:

                  if ((float)$result['special']) {
                  					$special = $this->currency->format($this->tax->calculate($result['special'], $result['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']);
                  				} else {
                  					$special = false;
                  				}
                  И замените на:
                  if ((float)$result['special']) {
                  					$special = $this->currency->format($this->tax->calculate($result['special'], $result['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']);
                  $skidka = 100-($result['special']/($result['price']/100));
                  				} else {
                  					$special = false;
                  $skidka = false;
                  				}

                  1. саша 24 октября 2016, 09:19
                    0

                    теперь выдает ошибки
                    Notice: Undefined index: special in Z:\home\rue21\www\catalog\controller\product\product.php on line 313
                    Notice: Undefined variable: special in Z:\home\rue21\www\catalog\view\theme\default\template\product\product.tpl on line 135

                    1. Владимир 24 октября 2016, 09:25
                      0

                      Сбросьте контроллер на vl@onenv.ru, поправлю

            2. Максим Невмержицкий 12 сентября 2016, 22:54
              0

              Помогите решить, у меня опенкарт 2 и немогу вывести на странице с акциями скидки((

              1. Владимир 15 сентября 2016, 03:00
                0

                А что именно не получается, какие ошибки? Там нет ничего особенного…

                1. Максим Невмержицкий 15 сентября 2016, 10:15
                  0

                  semechki.all-landing.com/specials/ — вот посмотрите там какая-то ошибка выскакивает
                  Notice: Undefined index: skidka in
                  Версия ocStore 2.1.0.2.1

                  1. Владимир 15 сентября 2016, 10:20
                    0

                    Ошибка не полностью, но в контроллере видимо не находит… проверьте есть ли в $this->data['products'][] = array(

                    1. Максим Невмержицкий 15 сентября 2016, 10:25
                      0
                      1. Максим Невмержицкий 15 сентября 2016, 10:42
                        0

                        1) а также хотел узнать я прописал <?php echo $product['skidka']; ?> % Скидка по пути /catalog/view/theme/МОЯТЕМА/template/product/special.tpl — и оно с ошибкой но вывелось на товаре,

                        2) Просто когда я прописал <?php echo $product['skidka']; ?> % Скидка в /catalog/view/theme/default/template/module/special.tpl — У меня ничего не отобразилось. Вот сейчас сделал так как Вы писали изначально и процентов вообще нету

                2. sasha 29 августа 2016, 09:29
                  0

                  подскажите как это сделать для featured products, там товары выводятся через админку в ручную, и данный способ не работает, т.к. видима нет цикла товаров

                  1. Владимир 01 сентября 2016, 09:26
                    0

                    Цикл тем не менее есть, да и не причем здесь это… дело скорее всего дело в переменных, где то $product_info, где то $result. Переписал, теперь думаю понятнее и правильнее стало.

                  2. Виталий 02 августа 2016, 13:35
                    0

                    Скидки конечно есть, могу файлики прислать — посмотрите что не так. сайт biomaniya.net

                    1. Виталий 02 августа 2016, 10:02
                      0

                      Что-то у меня не получается — все делаю как написано но ничего не отображается.

                      1. Владимир 02 августа 2016, 10:07
                        0

                        В смысле не отображаются скидки, или пустая страница? А ошибки есть какие? В общем то все должно быть, если товару назначена скидка, проверено… на странице товара со скидкой, на странице категории — нигде нет? А скидка у товара есть?

                      2. Takasu 06 октября 2015, 03:20
                        0

                        Спасибо за статью, очень помогла. Правда немного не понял зачем все так усложнять и копаться в контроллере)
                        Использовал только этот кусок, просто подставил переменные и все отлично работает

                        $num[0]=$product['price2'];  //Стоимость без скидки
                        $num[1]=$product['special2'];  //Стоимость по акции
                        $procent=$num[0]/100;
                        $result=100-($num[1]/$procent); //вычисляем процент
                        echo round ($result); ?> % <span>Скидка</span> <!-- Выводим процент с округлением используя функцию round-->

                        1. Вова Ленский 06 октября 2015, 07:23
                          0

                          $product['price2']; и $product['special2']; изначально ведь не существует… нужно что бы получить «чистую» цифру без конвертации

                          1. Takasu 06 октября 2015, 07:29
                            0

                            Логично что не существует, мне не понятно было зачем их определять) У меня задача немного другая, сумма скидки должна считаться исходя именно из 2 цифр цены, неважно в какой валюте, хотя и валюта то всего одна)

                            1. Вова Ленский 06 октября 2015, 07:431
                              0

                              для этого я бы иначе сделал. На примере товара, в категории все по аналогии. В контроллере (там где special) добавить:

                              $this->data['skidka'] = $this->currency->format($product_info['price']-$product_info['special']);
                              потом в tpl в нужном месте — echo $skidka

                              будет выводить сумму со всеми знаками и с учетом валюты выбранной…

                              1. Takasu 06 октября 2015, 07:49
                                0

                                Это вроде как получиться в деньгах, а мне нужно в процентах)
                                Да неважно на самом деле, и так отлично работает, меня интересовал по сути только алгоритм расчета, так как тот что я придумал сразу (a/b*100) в некоторых случаях выдавал не то что нужно…

                                1. Вова Ленский 06 октября 2015, 07:53
                                  0

                                  Неверно понял про сумму скидки) Хорошо что пригодилось решение, правда его можно упростить сделав в категориях/модулях по аналогии с товаром — меньше кода

                                  1. Takasu 06 октября 2015, 07:56
                                    0

                                    В любом случае спасибо)

                        2. unlocked 18 августа 2015, 20:30
                          0

                          Вы бы версию движка указывали.
                          На последней двойке не работает.

                          1. Вова Ленский 19 августа 2015, 06:211
                            0

                            Это для версии 1.5. Что касается двойки… там кое где есть изменения, но если делать по аналогии все должно получиться. Для модулей и страницы категории осталось все примерно как и было, должно работать…

                          2. Александр 16 июля 2015, 17:34
                            0

                            Сделал для товаров, страницы вообще перестали открываться ((( завтра еще буду пробовать смотреть.

                            1. Владимир 17 июля 2015, 08:24
                              0

                              белый экран - ошибка php. проверю чуть позже на тестовом

                            2. Александр 16 июля 2015, 05:42
                              0

                              Классный вариант, но на 1.5.4 не работает :sad: все сделал, по инструкции. При перезагрузке страницы отображается в фоне кружок со скидкой 10% и потом перекрывается шапкой, а на товаре нет ничего((

                              1. Владимир 16 июля 2015, 05:45
                                0

                                пропишите для блока с товаром position:relative; т.е. нужно задать точку отсчета, иначе все стикеры собьются в кучу.

                                1. Александр 16 июля 2015, 05:48
                                  0

                                  Спасибо за оперативность! а есть значение в какое место css вставлять изменения?

                                  1. Владимир 16 июля 2015, 05:53
                                    0

                                    В самом файле не важно, но лучше добавить к уже существующим свойствам для блока.. потом найти легче

                                    1. Александр 16 июля 2015, 06:18
                                      0

                                      так правильно?
                                      /* box products - procent */
                                      .procent { position: absolute; top: 5px; left: 5px; background: rgba(255, 0, 0, 0.57); border-radius: 50px; width: 100px; height: 75px; padding-top: 25px; text-align: center; font-size: 30px; color: #fff; text-shadow: 0px 0px 5px #520202; }
                                      .procent span {display: block; font-size: 15px;}

                                      /* box products */
                                      .box-product {
                                      width: 100%;
                                      overflow: hidden;
                                      }
                                      .box-product > div {
                                      width: 155px;
                                      display: inline-block;
                                      vertical-align: top;
                                      margin-right: 9px;
                                      margin-bottom: 20px;
                                      text-align: center;
                                      hover .procent {box-shadow: 0px 0px 5px #FDDF00;}
                                      position: relative;
                                      }

                                      1. Владимир 16 июля 2015, 06:38
                                        0

                                        Да, если не отображает как надо, покажите сайт - подскажу

                                        1. Александр 16 июля 2015, 06:451
                                          0

                                          Владимир, ekowebshop.com/airwick_lime_basilik_180g
                                          только я там уже в stylesheet поменял немного. Но все равно не отображает. Считает все верно, но не показывает.

                                          1. Владимир 16 июля 2015, 07:25
                                            0

                                            так.. процент только в левом блоке нужен?
                                            тогда добавьте для .box-lsb > div (строка 760) position:relative;

                                            Сам блок слишком узкий.. смотрите сами, я бы сделал так:
                                            /*добавить в css*/
                                            #column-left .box .box-content {padding:10px 5px;}
                                            #column-left .box-lsb > div {width: 158px; margin: 0px 0px 10px 0px;
                                            border: 1px solid #F7A4A4; height: 163px; position:relative; overflow:hidden;}

                                            далее сама скидка.. в таком виде не пойдет, т.к. размер блока очень мал.. попробуйте такой вариант:
                                            .procent {
                                            position: absolute; z-index: 100; background-color: #ff0505;
                                            color: #fff;
                                            -webkit-transform: rotate(315deg);
                                            -moz-transform: rotate(315deg);
                                            -ms-transform: rotate(315deg);
                                            -o-transform: rotate(315deg);
                                            transform: rotate(315deg);
                                            font-size: 18px; top: -8px; width: 85px; height: 23px; left: -31px; text-align: center;
                                            padding-top: 20px;
                                            }

                                            далее в самом коде скидки замените:
                                            echo round ($result); ?> % Скидка
                                            на
                                            echo '-'.round ($result); ?>%
                                            Должно получиться так:
                                            [img]http://httpmaster.ru/skidka.jpg[/img]

                                            1. Александр 16 июля 2015, 07:28
                                              0

                                              СПАСИБО! в карточке товара он тоже нужен! по идее там ширина блока позволяет, но скидка все равно не отображается

                                              1. Владимир 16 июля 2015, 07:30
                                                0

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

                                                1. Александр 16 июля 2015, 07:32
                                                  0

                                                  В контроллер и шаблон все изменения внес сразу

                                                  1. Владимир 16 июля 2015, 07:40
                                                    0

                                                    там есть отличия.. сейчас напишу для товара

                                                    1. Владимир 16 июля 2015, 08:17
                                                      0

                                                      Дописал. Не проверял, пробуйте.. если не сработает - пишите

                                                      1. Александр 16 июля 2015, 08:20
                                                        0

                                                        А куда Вы дописали? :oops: в статье тот- же текст

                                                        1. Владимир 16 июля 2015, 08:23
                                                          0

                                                          разве? "Изменения для страницы товара
                                                          ......."

                                                          1. Александр 16 июля 2015, 08:31
                                                            0

                                                            :lol: не обновил страницу. Спасибо Вам большое!

                                                            1. Владимир 16 июля 2015, 17:14
                                                              0

                                                              Получилось ли?

                                2. Иван 15 февраля 2015, 18:35
                                  0

                                  Отличная статья!