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

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

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

"/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 для блока с товаром. Для похожих товаров на этой странице изменения будут аналогичны категориям и модулям.

Еще 4 материала, которые возможно Вам понравятся:

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

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

  1. саша 24 октября 2016, 07:34
    в категории нормалньо выводит, на продукте ошибка

    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
      Это похоже для похожих товаров в карточке… Немного выше видимо нет:
      $skidka = 100-($product_info['special']/($product_info['price']/100));
      1. саша 24 октября 2016, 09:06
        нет в контроллере только один массив
        $this->data['products'][] = array(
        и он ругается на 'skidka' => $skidka,
        1. Владимир 24 октября 2016, 09:11
          он говорит, что "$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
            теперь выдает ошибки
            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
              Сбросьте контроллер на vl@onenv.ru, поправлю
    2. Максим Невмержицкий 12 сентября 2016, 22:54
      Помогите решить, у меня опенкарт 2 и немогу вывести на странице с акциями скидки((
      1. Владимир 15 сентября 2016, 03:00
        А что именно не получается, какие ошибки? Там нет ничего особенного…
        1. Максим Невмержицкий 15 сентября 2016, 10:15
          semechki.all-landing.com/specials/ — вот посмотрите там какая-то ошибка выскакивает
          Notice: Undefined index: skidka in
          Версия ocStore 2.1.0.2.1
          1. Владимир 15 сентября 2016, 10:20
            Ошибка не полностью, но в контроллере видимо не находит… проверьте есть ли в $this->data['products'][] = array(
            1. Максим Невмержицкий 15 сентября 2016, 10:42
              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 — У меня ничего не отобразилось. Вот сейчас сделал так как Вы писали изначально и процентов вообще нету

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

                есть
        2. sasha 29 августа 2016, 09:29
          подскажите как это сделать для featured products, там товары выводятся через админку в ручную, и данный способ не работает, т.к. видима нет цикла товаров
          1. Владимир 01 сентября 2016, 09:26
            Цикл тем не менее есть, да и не причем здесь это… дело скорее всего дело в переменных, где то $product_info, где то $result. Переписал, теперь думаю понятнее и правильнее стало.
          2. Виталий 02 августа 2016, 13:35
            Скидки конечно есть, могу файлики прислать — посмотрите что не так. сайт biomaniya.net
            1. Виталий 02 августа 2016, 10:02
              Что-то у меня не получается — все делаю как написано но ничего не отображается.
              1. Владимир 02 августа 2016, 10:07
                В смысле не отображаются скидки, или пустая страница? А ошибки есть какие? В общем то все должно быть, если товару назначена скидка, проверено… на странице товара со скидкой, на странице категории — нигде нет? А скидка у товара есть?
              2. Takasu 06 октября 2015, 03:20
                Спасибо за статью, очень помогла. Правда немного не понял зачем все так усложнять и копаться в контроллере)
                Использовал только этот кусок, просто подставил переменные и все отлично работает
                $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
                  $product['price2']; и $product['special2']; изначально ведь не существует… нужно что бы получить «чистую» цифру без конвертации
                  1. Takasu 06 октября 2015, 07:29
                    Логично что не существует, мне не понятно было зачем их определять) У меня задача немного другая, сумма скидки должна считаться исходя именно из 2 цифр цены, неважно в какой валюте, хотя и валюта то всего одна)
                    1. Вова Ленский 06 октября 2015, 07:43(Комментарий был изменён)
                      для этого я бы иначе сделал. На примере товара, в категории все по аналогии. В контроллере (там где special) добавить:

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

                      будет выводить сумму со всеми знаками и с учетом валюты выбранной…
                      1. Takasu 06 октября 2015, 07:49
                        Это вроде как получиться в деньгах, а мне нужно в процентах)
                        Да неважно на самом деле, и так отлично работает, меня интересовал по сути только алгоритм расчета, так как тот что я придумал сразу (a/b*100) в некоторых случаях выдавал не то что нужно…
                        1. Вова Ленский 06 октября 2015, 07:53
                          Неверно понял про сумму скидки) Хорошо что пригодилось решение, правда его можно упростить сделав в категориях/модулях по аналогии с товаром — меньше кода
                          1. Takasu 06 октября 2015, 07:56
                            В любом случае спасибо)
                2. unlocked 18 августа 2015, 20:30
                  Вы бы версию движка указывали.
                  На последней двойке не работает.
                  1. Вова Ленский 19 августа 2015, 06:21(Комментарий был изменён)
                    Это для версии 1.5. Что касается двойки… там кое где есть изменения, но если делать по аналогии все должно получиться. Для модулей и страницы категории осталось все примерно как и было, должно работать…
                  2. Александр 16 июля 2015, 17:34
                    Сделал для товаров, страницы вообще перестали открываться ((( завтра еще буду пробовать смотреть.
                    1. Владимир 17 июля 2015, 08:24
                      белый экран - ошибка php. проверю чуть позже на тестовом
                    2. Александр 16 июля 2015, 05:42
                      Классный вариант, но на 1.5.4 не работает :sad: все сделал, по инструкции. При перезагрузке страницы отображается в фоне кружок со скидкой 10% и потом перекрывается шапкой, а на товаре нет ничего((
                      1. Владимир 16 июля 2015, 05:45
                        пропишите для блока с товаром position:relative; т.е. нужно задать точку отсчета, иначе все стикеры собьются в кучу.
                        1. Александр 16 июля 2015, 05:48
                          Спасибо за оперативность! а есть значение в какое место css вставлять изменения?
                          1. Владимир 16 июля 2015, 05:53
                            В самом файле не важно, но лучше добавить к уже существующим свойствам для блока.. потом найти легче
                            1. Александр 16 июля 2015, 06:18
                              так правильно?
                              /* 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
                                Да, если не отображает как надо, покажите сайт - подскажу
                                1. Александр 16 июля 2015, 06:45(Комментарий был изменён)
                                  Владимир, ekowebshop.com/airwick_lime_basilik_180g
                                  только я там уже в stylesheet поменял немного. Но все равно не отображает. Считает все верно, но не показывает.
                                  1. Владимир 16 июля 2015, 07:25
                                    так.. процент только в левом блоке нужен?
                                    тогда добавьте для .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
                                      СПАСИБО! в карточке товара он тоже нужен! по идее там ширина блока позволяет, но скидка все равно не отображается
                                      1. Владимир 16 июля 2015, 07:30
                                        там нужно править контроллер и шаблон товара.. пока там не выводится
                                        1. Александр 16 июля 2015, 07:32
                                          В контроллер и шаблон все изменения внес сразу
                                          1. Владимир 16 июля 2015, 08:17
                                            Дописал. Не проверял, пробуйте.. если не сработает - пишите
                                            1. Александр 16 июля 2015, 08:20
                                              А куда Вы дописали? :oops: в статье тот- же текст
                                              1. Владимир 16 июля 2015, 08:23
                                                разве? "Изменения для страницы товара
                                                ......."
                                                1. Александр 16 июля 2015, 08:31
                                                  :lol: не обновил страницу. Спасибо Вам большое!
                                                  1. Владимир 16 июля 2015, 17:14
                                                    Получилось ли?
                                            2. Владимир 16 июля 2015, 07:40
                                              там есть отличия.. сейчас напишу для товара
                        2. Иван 15 февраля 2015, 18:35
                          Отличная статья!