Найти тему
Logonok

Универсальные скидки для товаров и заказов

Оглавление

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

Скидки - важный элемент маркетинга
Скидки - важный элемент маркетинга

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

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

Кроме того, почему скидки могут быть только на товары? Если покупатель заказал на большую сумму, то можно поблагодарить его за это дополнительной скидкой. Или, например, скидка за первую покупку и тому подобное. Из этого следует, что скидка должна быть отдельной сущностью с дополнительными параметрами для разных случаев применения.

Установка

Устанавливаем веб-приложение «Книжный магазин». Приложение создано на декларативном фреймворке Evado, который позволяет разрабатывать приложение прямо в браузере, а запускать его можно либо через Docker, либо в окружении сервера Node.js и базы данных MongoDB.

Обратите внимание, что в репозитории активна последняя версия приложения с уже сделанными изменения, описанными в данной статье. Исходная версия доступна по метке v2.0.0.

Запускаем приложение и переходим в модуль «Студия» для редактирования метаданных.

Метаданные

Создаем абстрактный класс «Скидка». В этом классе будут описаны общие данные для всех типов скидок. Добавляем атрибуты «Дата начала» и «Дата окончания», которые определят период действия скидки. Добавляем вещественный атрибут «Процент», который будет хранить значение скидки.

Абстрактный класс нельзя использовать для создания объектов. Он необходим для основы иерархии классов.

Переходим на вкладку «Представления» и создаем представление «Действующие скидки», которое будет фильтровать объекты скидок с датой начала меньше текущей и датой окончания - больше.

Скидки на товары и на заказ наследуются от абстрактной скидки
Скидки на товары и на заказ наследуются от абстрактной скидки

Далее создаем класс «Скидка на товар», унаследовав класс «Скидка». Добавляем атрибут «Минимальное количество», который определит минимум товара для применения ссылки. Проставляем значение по умолчанию равное одному. Далее добавляем ссылочный атрибут «Товары со скидкой», в котором будет храниться список товаров.

Переходим в класс «Товар» и добавляем атрибут «Скидка» для получения действующей скидки на товар. Указываем тип «Обратная ссылка», ссылочный класс «Скидка на товар» и ссылочный атрибут «Товары со скидкой». Кроме того, указываем фильтр скидок - дата начала должна быть меньше текущей, а дата окончания - больше.

Тип «Обратная ссылка» хранит значение связи в ссылочном классе. В данном случае, идентификатор товара, на который действует ссылка, хранится в атрибуте «Товары со скидкой» класса «Скидка на товар».

Далее создаем класс «Скидка на заказ», унаследовав класс «Скидка». Добавляем вещественный атрибут «Минимальная цена», который определит нижнюю границу суммы заказа для скидки.

Метаданные приложения готовы. Экспортируем их через верхнее меню модуля «Студия» в папку metadata/app.

Поведения

Для формирования цены с учетом скидок необходимо изменить поведения класса «Элемент заказа» и представления «Создание из корзины», которые были созданы на первом этапе разработки нашего магазина.

Поведения расширяют функционал классов и представлений необходимой логикой работы.

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

Для получения активной скидки на заказ, извлекаем объекты класса «Скидка на заказа» в представлении «Действующие скидки». Затем проверяем - соответствует ли текущая сумма заказа минимально допустимой. Если да, то уменьшаем сумму заказа на процент скидки.

Данные

Переходим в модуль «Офис» для оперирования данными и создаем скидки для товаров и заказа.

Создание скидок на товары и заказы
Создание скидок на товары и заказы

Обратите внимание, что в метаданных для пункта бокового меню «Все скидки» был задан базовый класс «Абстрактная скидка». Таким образом, в едином списке доступны скидки всех типов, а при создании новой будет предложен выбор класса.

Пользовательский интерфейс

Пользовательский интерфейс может быть реализован и вне фреймворка Evado. Для оперирования данными используются AJAX запросы к API приложения.

Для отображения товаров в публичной части приложения используются отдельные представления, которым назначены соответствующие права доступа. Кроме того, в них задано, что вместе с объектом товара возвращается связанный объект скидки (в ссылочном атрибуте «Действующая скидка» установлен флажок «Жадная загрузка») для предварительного расчета стоимости на стороне клиента.

Пользовательский интерфейс реализован на Vue.js как отдельный модуль Front.
Пользовательский интерфейс реализован на Vue.js как отдельный модуль Front.

В корзине используется запрос скидки на заказ в представлении «Действующие скидки». Если такая скидка есть, то отображается уведомление, и она учитывается при вычислении итоговой цены.

Заключение

Готовое веб-приложение магазина доступно в открытом репозитории.