Рецепт: как сделать скидку 10% при стоимости заказа от 2000 руб.?

9.5/10 оценка (4 голосов)

Элемент скидки в JBZoo решает определенные задачи. Но что делать, если хочется что-то особое?

Тогда напишите свой элемент с любой логикой — это просто, даже если вы плаваете в PHP.

Рецепт: как сделать скидку 10% при стоимости заказа от 2000 руб.?

Что понадобится?

  • Руки и голова
  • Немного терпения, чтобы дочитать этот гайд.
  • От 5 минут времени на программирование.
  • Элементарные основы PHP.
  • Сайт на основе версии JBZoo 220+

Элементы — это строительные блоки конструктора

Почти все расширения в Zoo и JBZoo — элементы. Принцип работы изнутри у них одинаковый, несмотря на свое разное предназначение. Это очень удобно, потому что если вы научитесь делать один вид элементов, то легко сможете и любой другой.

Например, бывают элементы скидок и валидаторов корзины. И те и другие отличаются лишь одной функцией — у первого она считает скидку, у второго проверяет валидность. Все остальное у них работает одинаково и API полностью сопадает. Сюда входит рендеринг, редактирование, работа с настройками, все переменные и методы внутри расширения. Обо всех общих функциях мы позаботились за вас.

Другими словами, если вы хоть раз писали элемент для ZOO и никогда не видели JBZoo, то вы уже знаете наш API. Давайте рассмотрим это на примере элемента скидки.

Где лежат элементы скидок?

Все элементы корзины находятся здесь:

/media/zoo/applications/jbuniversal/cart-elements

(далее этот путь будем писать как *).

Они строго разделены по папкам-типам (своему предназначению).

Т. к. нас интересует скидка, то выберем одну из папок:

  • modifierItemPrice — скидка на определенный товар или группу (до добавления в корзину)
  • modifierOrderPrice — скидка применяется на весь заказ сразу после вычисления предварительной суммы.

Для нашей задачи подходит вторая папка, т. к. мы рассматриваем скидку на весь заказ.

Анатомия элемента

Минимальный набор для любого элемента — это…

  • element.xml — набор настроек и мета-информация (название, автор, версия).
  • element.php — вся логика элемента

Остальное папки опциональны:

  • assets — статическое содержимое, т.е. JavaScript, CSS и картинки
  • tmpl — шаблоны
  • language — локализации

Иногда бывают другие файлы и папки, но это уже особенности конкретного элемента.

Пишем свой элемент скидки

Назовем его MyDiscount. Тогда для удобства используем псевдоним (алиас) mydiscount. Это важное слово, которое обязательно пропишите в определенных местах (их рассмотрим ниже), иначе система его не найдет.

Создаем два новых файла

*/modifierorderprice/mydiscount/mydiscount.php

*/modifierorderprice/mydiscount/mydiscount.xml

В mydiscount.xml добавьте типичный набор мета-данных. Напишите сюда свои контакты и описания:

<?xml version="1.0" encoding="utf-8"?>
<element type="element" group="Core" hidden="false">
    <name>My Discount</name>
    <author>SmetDenis</author>
    <creationDate>2015</creationDate>
    <copyright>Copyright (C) JBZoo.com</copyright>
    <authorEmail>denis@jbzoo.com</authorEmail>
    <authorUrl>http://jbzoo.com</authorUrl>
    <version>1.0</version>
    <description>Simple example</description>
</element>

Все сводится к работе одного метода — getRate(). Его задача вернуть положительное (для наценки) или отрицательное (для скидки) число, которое затем будет добавлено к обрабатываемой сумме (товара или всего заказа).

Мы хотим добавить скидку 10%, если сумма за все товары больше 2000 рублей. Открываем файл mydiscount.php, добавляем туда код:

<?php

class JBCartElementModifierOrderPriceMydiscount extends JBCartElementModifierOrderPrice
{ 

    public function getRate()
    {
        $orderSum = $this->_order->getTotalForItems(); // сумма за все товары (без доставки и прочего)
        $discount = 0;

        if ($orderSum->compare('2000rub', '>=')) { // сравниваем c 2000 рублей
            $discount = '10%'; // скидка, если сумма больше
        }

        return $this->_order->val($discount)->negative(); 
    }

}

Функция должна вернуть объект денег, который создается с помощью val() из строки. Т.к. мы говорим о скидке, то нужно получить отрицательное значение. Это сделает negative(). Обратите внимание, что имя класса составное JBCartElement + ModifierOrderPrice + Mydiscount. Регистр именования класса нас не сильно волнует.

Наше расширение сводится к тому, чтобы правильно написать одну единственную функцию, где единственная задача — вернуть размер скидки. Все остальное за вас сделает JBZoo. А именно — выведет значение в деталях заказа, на странице корзины, добавит динамику на JS, сохранит в базе, учтет валюту. Если очень хочется кастомизировать, например, вывод в форме заказа, то достаточно просто переопределить метод render().

Мне кажется, с этим справится любой джуниор, кто хоть немного видел PHP.

На нашем гитахабе вы сможете найти расширенный вариант этого элемента. Все тоже самое, только мы вынесли в настройки сумму и процент. Если присмотритесь, то работа с настройками точно такая же как в любом другом элементе ZOO.

Почему мы работаем с объектами, а не числами?

От товара до создания заказа сумма (та, что к оплате) может претерпевать огромное количество изменений. Все зависит от настроек вашего магазина. Допустим, у нас есть такой сложный вариант

  • Товар стоит 100 грн.
  • Добавляем его в корзину 5 шт (500 грн).
  • Добавляем другой товар за 100 руб, 4 штуки.
  • Срабатывает модификатор скидки для второго товара если кол-во больше 3-х (-10%).
  • Человек в корзине указывает промо код (-15% ко всему заказу).
  • Вычисляется сумма доставки через «Новую почту» (+58 грн).
  • Клиент оплачивает через PayPal в долларах по курсу сайта.


Получаем примерную формулу (на пальцах):
Сумма заказа = (((100uah * 5) + ((100rub * 4) - 10%) - 15%) + 58uah) => usd

Если развернуть все вычисления, то получим огромную портянку кода, где большая часть — вызов конвертации валюты и вычисления процентов. Всю эту кучу кода скрывает объект JBCartValue. Он важен в работе сайта и полностью зависит от настроек валюты. Поэтому, мы акцентируем на них большое внимание.

JBCartValue является предшественником нашей библиотеки SimpleTypes. Они имеют очень похожее API. Пример вы можете посмотреть здесь. В следующих статьях мы рассмотрим работу с денежными суммами более подробно.

Вступайте в группу ВКонтакте, подписывайтесь на наш твиттер, чтобы не пропустить полезные статьи.

9.5 1217
Корзина, Цена
  • Алмаз
    Алмаз
    25 Июнь 2016 at 14:24
     ↑  +1  ↓  Ответить

    Отличный материал. Спасибо

Оставить комментарий