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

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

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

"/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 код будет примерно такой же, поэтому переписывать не буду, найти не сложно. Еще один момент - в некоторых модулях вместо "$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'] = 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 round ($product['skidka']); ?>% <span>Скидка</span> 
           </div>
          <?php } ?>

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

Добавить комментарий

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

  1. Владимир 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:43(Комментарий был изменён)
                            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:21(Комментарий был изменён)
                          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:45(Комментарий был изменён)
                                        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 #

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