msProductDiscounts

Создание скидок на товары с широкими возможностями настройки
Автор дополнения
Артур Шевченко
Пакетов
11
Закачек
3 104
Обычно отвечает в течение суток
Автор дополнения
Пакетов
11
Закачек
3 104
Обычно отвечает в течение суток
Версия 2.1.7-rc
Дата выпуска 06.03.2026
Загрузки 58
Просмотры 4 129
Внимание, этот компонент несовместим с MODX 3.
Будьте внимательны при обновлении с версий 1.х.х ОБЯЗАТЕЛЬНО что-то сломается.
Требует установки SendIt
Есть встроенная работа с промокодами.
НЕ РАБОТАЕТ С MODX 3

msProductDiscounts предназначен для управления скидками на товары интернет-магазина на базе miniShop2.
Основные возможности:
  1. Скидка в виде подарка;
  2. Скидки на каждый N-ый товар;
  3. Скидки на каждую N-ую позицию в корзине
  4. Скидки по дням недели
  5. Скидки по группам пользователей
  6. Скидки по определённым датам, на определенный период или бессрочно
  7. Скидки по категориям, с возможностью исключить дочерние
  8. Скидки на определённый товар, с возможностью задать исключения по отдельным модификациям (требуется дополнение msOprionPrice2) или по опциями и основным свойствам
  9. Скидки на товары с определенными опциями и свойствами
  10. Скидки на отдельные модификации
  11. Возможность ограничить применение скидок общей суммой товаров в корзине
  12. Автоматическая актуализация корзины
  13. Возможность определить приоритетность скидок
  14. Вывод информации о скидках на странице товара
  15. Возможность привязать ресурс с подробным описанием скидки
  16. Возможность вывести информацию о скидке на странице товара
  17. Возможность задать размер скидки как в относительных единицах измерения (%) так и в абсолютных

ВИДЕО ПРЕЗЕНТАЦИЯ

Для начала работы требуется просто установить компонент и задать параметры скидки. Если в параметрах скидки есть зависимость от опций, свойств или модификаций, эта информация должна передаваться на сервер стандартными средствами miniShop2, т.е. через массив options.

Для того, чтобы работала актуализация корзины, нужно в системных настройках указать ID страницы с корзиной (mspd_cart_page).
В чанке корзины должны присутствовать следующие элементы
<span data-ms-price>{$product.price}</span>
<span data-ms-old-price>{$product.old_price}</span>
<span data-ms-cost>{$product.cost}</span>
Ключевой момент здесь это data-атрибуты любого из них может не быть, но в этом случае, информация обновляться не будет, пока не перезагрузят страницу.

С версии 1.4.1 сниппет вывода информации о скидках на конкретный товар удалён. Вместо него добавлен процессор.
Таким образом показ цены со скидкой происходит автоматически, если в чанк товара добавлены соответствующие атрибуты.
Так вся информация о товаре должна быть внутри блока с атрибутом data-mspd-product="{$id}" где $id — идентификатор товара в админке.
Блок вывода цены должен содержать атрибут data-mspd-price в качестве значения нужно указать цену товара, для старой цены data-mspd-old-price — значение старая цена.
Свойства и опции влияющие на цену нужно обозначать соответственно data-mspd-data (свойство, например артикул или цвет или вес)
и data-mspd-option (любая кастомная опция). При этом если html элемент, которому вы добавляете эти атрибуты НЕ содержит атрибута name, необходимо в качестве значения указать ключ опции или свойства,
например так: data-mspd-data=«color» или data-mspd-option=«length».
Такие свойства как
  • Производитель,
  • Страна изготовитель,
  • Новый,
  • Особый,
  • Популярный
можно не обозначать и не передавать в корзину, они проверяются по умолчанию.
Чтобы нулевая старая цена скрывалась необходимо обернуть весь блок вывода старой цены в элемент с атрибутом data-mspd-old-price-wrap и убедиться, что в стилях описан класс d-none, либо, если за визуальное скрытие элементов у вас отвечает другой класс, указать свой класс в системных настройках компонента.

Там же, в системных настройках, можно изменить время принудительной перезагрузки страницы с корзиной. Принудительная перезагрузка происходит 1 раз в сутки. Это нужно на случай если пользователь оставил вкладку браузера на длительное время, а срок действия акции закончился. Тогда принудительная перезагрузка обновит стоимость корзины. Если оставить системную настройку mspd_reload_interval пустой принудительной перезагрузки не случится.

Стандартный скрипт показывает цену со скидкой и старую цену. Однако может возникнуть необходимость показывать ещё какую-то информацию о скидках на данный товар.
Для этого есть событие в JavaScript (с версии 1.4.1) mspd-get-discounts
document.addEventListener('mspd-get-discounts', e => {
    console.log(e.detail);
    // e.detail.response - ответ сервера с реальной ценой, ценой со скидкой/скидками и списком всех применённых скидок
    // e.detail.wrapper - блок-обёртка товара обозначенная атрибутом data-mspd-product
    // e.detail.price - цена от которой рассчитывалась скидка
    // e.detail.target - элемент вызвавший событие
    // e.detail.object - объект JS класса mspdGetDiscounts можно использовать его метод форматирования цены
    //e.detail.object.formatPrice(e.detail.response.discount_price, e.detail.object.config.price_format, e.detail.object.config.price_format_no_zeros)
    });

Для работы с msOprionsPrice2 необходимо внутри блока с data-mspd-product добавить
<input type="hidden" name="options[modification]">

Пример страницы товара
{'!msOptionsPrice.initialize' | snippet:[]}

<div class="text-center text-md-left mb-2 mb-md-0">
    {if $_modx->resource.new?}
        <span class="badge badge-secondary badge-pill col-auto">{'ms2_frontend_new' | lexicon}</span>
    {/if}
    {if $_modx->resource.popular?}
        <span class="badge badge-secondary badge-pill col-auto">{'ms2_frontend_popular' | lexicon}</span>
    {/if}
    {if $_modx->resource.favorite?}
        <span class="badge badge-secondary badge-pill col-auto">{'ms2_frontend_favorite' | lexicon}</span>
    {/if}
</div>
<div id="msProduct" class="row align-items-center" itemtype="http://schema.org/Product" itemscope>
    <meta itemprop="name" content="{$_modx->resource.pagetitle}">
    <meta itemprop="description" content="{$_modx->resource.description ?: $_modx->resource.pagetitle}">
    <div class="col-12 col-md-6">
        {'!msGallery' | snippet : []}
    </div>
    <div class="col-12 col-md-6" itemtype="http://schema.org/AggregateOffer" itemprop="offers" itemscope data-mspd-observe>
        <meta itemprop="category" content="{$_modx->resource.parent | resource: "pagetitle"}">
        <meta itemprop="offerCount" content="1">
        <meta itemprop="price" content="{$price | replace:" ":""}">
        <meta itemprop="lowPrice" content="{$price | replace:" ":""}">
        <meta itemprop="priceCurrency" content="RUR">
        

        <form class="form-horizontal ms2_form msoptionsprice-product" method="post" data-mspd-product="{$_modx->resource.id}">
            <input type="text" name="options[modification]" value="0" data-mspd-option>
            <h1 class="text-center text-md-left msoptionsprice-name msoptionsprice-[[*id]]">{$_modx->resource.pagetitle}</h1>
            <input type="hidden" name="id" value="{$_modx->resource.id}"/>

            <div class="form-group row align-items-center">
                <label class="col-6 col-md-3 text-right text-md-left col-form-label">{'ms2_product_article' | lexicon}:</label>
                <div class="col-6 col-md-9 msoptionsprice-article msoptionsprice-[[*id]]">
                    {$article ?: '-'}
                </div>
            </div>
            <div class="form-group row align-items-center">
                <label class="col-6 col-md-3 text-right text-md-left col-form-label">{'ms2_product_price' | lexicon}:</label>
                <div class="col-6 col-md-9">
                    <span class="msoptionsprice-cost msoptionsprice-[[*id]]" data-mspd-price="{$_modx->resource.price}">{$_modx->resource.price}</span> {'ms2_frontend_currency' | lexicon}
                    <span data-mspd-old-price-wrap class="old_price {$old_price == 0 ? 'd-none' : ''}">
                    <span class=" ml-2 msoptionsprice-old-cost msoptionsprice-[[*id]]" data-mspd-old-price="{$_modx->resource.old_price}">{$_modx->resource.old_price}</span>
                    {'ms2_frontend_currency' | lexicon}
                    </span>
                    
                </div>
            </div>
            <div class="form-group row align-items-center">
                <label class="col-6 col-md-3 text-right text-md-left col-form-label" for="product_price">{'ms2_cart_count' | lexicon}:</label>
                <div class="col-6 col-md-9">
                    <div class="input-group">
                        <input type="number" name="count" id="product_price" class="form-control col-md-6" value="1"/>
                        <div class="input-group-append">
                            <span class="input-group-text">{'ms2_frontend_count_unit' | lexicon}</span>
                        </div>
                    </div>
                </div>
            </div>
            <div class="form-group row align-items-center">
                <label class="col-6 col-md-3 text-right text-md-left col-form-label">{'ms2_product_weight' | lexicon}:</label>
                <div class="col-6 col-md-9">
                    <span class="msoptionsprice-mass msoptionsprice-[[*id]]" data-mspd-data="weight">{$weight}</span> {'ms2_frontend_weight_unit' | lexicon}
                </div>
            </div>

            <div class="form-group row align-items-center">
                <label class="col-6 col-md-3 text-right text-md-left col-form-label">{'ms2_product_made_in' | lexicon}:</label>
                <div class="col-6 col-md-9">
                    {$made_in ?: '-'}
                </div>
            </div>

            {'msOptions' | snippet : [
                'options' => 'color,size,test_5,test_6'
            ]}

            {'msProductOptions' | snippet : []}

            <div class="form-group row align-items-center">
                <div class="col-12 offset-md-3 col-md-9 text-center text-md-left">
                    <button type="submit" class="btn btn-primary" name="ms2_action" value="cart/add">
                        {'ms2_frontend_add_to_cart' | lexicon}
                    </button>
                </div>
            </div>
        </form>

    </div>
</div>
<div class="mt-3">
    {$_modx->resource.content}
</div>
!!! ВАЖНО При использовании msOptionsPrice2 атрибут data-mspd-product и класс msoptionsprice-product должны принадлежать одному HTML элементу. Атрибут data-mspd-old-price-wrap должен быть непосредственным родителем для элемента с атрибутом data-mspd-old-price.

[УСТАРЕЛО с версии 1.4.1]
Пример вызова сниппет для показа скидок на текущий товар (данный вызов следует размещать на странице товара). Вызов написан для Fenom
{set $discounts = '!getProductDiscounts' | snippet:[
            'id' => $_modx->resource.id,
            'tpl' => '',
            'tplEmpty' => '@INLINE Скидки для данного товара не найдены.',
            'price' => $_modx->resource.price,
            'weight' => $_modx->resource.weight,
            'options' => ['color'=>'','size'=>'','test_5'=>'','test_6' => '', 'modification' => 1],
            'data' => ['article' => ''],
            'total_cost' => 999999
 ]}
 {$discounts | print}

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[2.1.7-rc] - 2025-12-26 - 06.03.2026

  • Уменьшил размер ключа для промокода.
  • Добавил новый тип скидки "Подарок" (unit "g") — автоматическое добавление товара-подарка в корзину.
  • Добавил поддержку модификаций msOptionPrice в качестве подарка (чекбокс gift_class_key).
  • Добавил системную настройку mspd_gift_price для указания цены подарка в корзине.
  • Добавил учёт manyBehaviour и apply_type для подарочных скидок.
  • Добавил исключение подарков из подсчёта позиций, количества и стоимости корзины.
  • Добавил автоматическое удаление подарка из корзины при несоответствии условиям скидки.
  • Добавил панель "Произвольные условия" (ключ-значение) в настройках скидки.
  • Добавил поддержку кастомных значений для чекбоксов в админке (data-checked-value, data-unchecked-value).

[2.1.6-rc] - 2025-12-06 - 2025-12-24

  • Исправил чанк информации о скидке.
  • Исправил применение скидок при указании отношения к количеству "кратно"
  • Добавил округление.

[2.1.5-rc] - 2025-10-20 - 2025-12-06

  • Добавил задержку после применения или отмены промокода перед получением данных корзины.
  • Перенёс переопределение корзины в метод applyDiscounts.
  • Добавил прерывание проверки соответствия условий скидки конкретному товару при нахождении первого несоответствия
  • Исправил ошибку связанную с удалением неподходящих скидок.
  • Изменил значение defaultEngine в файле msproductdiscounts.mysql.schema.xml на InnoDB

[2.1.4-rc] - 2025-10-14

  • Исправил ошибку в методах cancelPromocode и applyPromocode

[2.1.3-rc] - 2025-09-30 - 2025-10-01

  • Разделил загрузку вебконфига и файла js для возможности раздельного подключения.
  • Добавил явное преобразование типов при передачи значений метод formatPrice

[2.1.2-rc] - 2025-09-23

  • Добавил возможность отключения проверки общих условий при показе скидок без применения при помощи системной настройки mspd_check_common_conditions_on_show.

[2.1.1-rc] - 2025-09-19

  • Добавил проверку общих условий при показе скидок без применения.

[2.1.0-rc12] - 2025-08-17

  • Добавил явное приведение типов для статусов.

[2.1.0-rc11] - 2025-08-03

  • Мелкие правки.

[2.1.0-rc10] - 2025-08-02

  • Добавил в системное событие mspdOnBeforeApplyDiscount.

[2.1.0-rc9] - 2025-08-02

  • Добавил в JS событие mspd:on:get:productdata.

[2.1.0-rc8] - 2025-08-02

  • Установил глобальную переменную msProductDiscounts в JS.

[2.1.0-rc7] - 2025-08-02

  • Добавил удаление активных скидок для которых нет товаров.
  • Сделал наличие JS miniShop2 необязательным.

[2.1.0-rc6] - 2025-05-13 - 2025-05-17

  • Добавил проверку на наличие старой цены перед расчётом скидки.
  • Добавил приведение типов в методе checkCommonConditions.
  • Поменял discount_total на discount_cost.
  • Добавил возможность делать скидки с учётом наличия акционных товаров в корзине.

[2.1.0-rc5] - 2025-05-05

  • Добавил проверку $order_id при удалении привязки промокода к заказу.
  • Добавил обработку колбэков минишопа для получения скидок в каталоге.

[2.1.0-rc4] - 2025-05-02 - 2025-05-04

  • Добавил фильтр скидок на странице редактирования промокода.
  • Добавил возможность переходить к редактированию скидки со страницы редактирования промокода.
  • Добавил системное событие mspdOnBeforeGetPromocode.
  • Добавил системное событие mspdOnGetWebConfig.
  • Сделал рефакторинг JavaScript.
  • Добавил зависимость от компонента SendIt.
  • Вынес шаблон информации о скидках в чанк.
  • Добавил сниппет mspdConnector.
  • Переписал сниппет msCart так чтобы он корректно отображал данные товара со скидкой в корзине.

[2.1.0-rc3] - 2025-05-02

  • Добавил фильтр промокодов по названию скидки

[2.1.0-rc2] - 2025-05-02

  • Доработал совместную работу обычных скидок и скидок по промокодам.

[2.1.0-rc1] - 2025-04-29

  • Добавил возможность создавать промокоды.

[2.0.0-rc5] - 2025-04-11

  • Добавил подключение пакета в процессор поиска совпадений.
  • Улучшил совместимость с msAltCart.
  • Добавил системные события mspdOnGetProductDiscounts и mspdOnBeforeCheckDiscount
  • Добавил куку mspd_context для сохранения текущего контекста
  • Добавил событие mspdOnBeforeGetDiscounts

[2.0.0-rc4] - 2025-04-08

  • Исправил метод сброса корзины при отсутствии скидок

[2.0.0-rc3] - 2025-02-15

  • Исправил условие в методе checkCommonConditions()

[2.0.0-rc2] - 2025-02-08

  • Добавил проверку общих параметров скидок таких как отношение к количеству и минимальная сумма

[2.0.0-rc1] - 2024-09-15

  • Added parameter showHidden in category tree.
  • Fix some bugs in JS
  • Add check in get conditions method.
  • Fixed the error of passing parameters from the mspdOnCheckDiscount plugin.
  • Fixed error on check allowed resources.
  • Fixed an error where the processor returns an empty result if no discounts are found
  • Add for product in cart information about value and unit of discount
  • Change way to get original price
  • Exclude class mspdPeriod from the list of checked classes

[2.0.0-rc] - 2024-09-14

  • Added limit, offset and context parameters to discounts.
  • Added composer autoloader.
  • Rewrite base class for discounts.
  • Exclude using Session for keeping discounts.
  • No compatibility with previous versions.
  • No compatibility with other discount components

[1.4.7] - 2023-12-25

  • Added the data-mspd-cart-row="${key}" attribute to indicate a separate item in the cart
  • Аdded support for multiple shopping carts
  • The mspd_cart_page system setting has been replaced with mspd_tpls_with_cart

[1.4.6] - 2023-03-25

  • Fixed bug with rename manager path
  • Fixed bug with week day check

[1.4.5] - 2023-03-17

  • Fixed bug on remove additional objects

[1.4.4] - 2023-02-25

  • Аdded output of information about the discount
  • Fixed bug with clearing the resource field
  • Fixed the error of multiple application of discounts
  • Added automatic activation and deactivation of discounts
  • Changed the minimum validity period to 1 hour
  • Fixed bug Clean button

Added

  • session cleanup

[1.4.3] - 2022-12-26

Fixed some bugs

[1.4.2] - 2022-12-25

Fixed some bugs

Added

  • Support for ajax pagination in pdoPage

[1.4.1] - 2022-12-24

Added

  • JS Event mspd-get-discounts
  • Processor GetProductDiscountsProcessor
  • Reload cart interval

Removed

  • Snippet getProductDiscounts

[1.3.1] - 2022-12-04

Added

  • Mass deletion of conditions

Changed

  • Fixed a bug with updating the cart

[1.2.3] - 2022-12-04

Added

  • "discount_price" parameter to the getProductDiscounts snippet
  • Bread crumbs for categories

Changed

  • Product search
  • Build package

[1.2.0] - 2022-12-03

Added

  • Search for products with msearch2 if it is installed
  • Category tree
  • Processors: /mgr/products/, /mgr/exproducts/, /mgr/categories/ and /mgr/excategories/

Changed

  • Selecting a resource with a description of the discount

Removed

  • Some modal windows on discount manage page
  • Processors: /mgr/product/, /mgr/exproduct/, /mgr/category/ and /mgr/excategory/

[1.0.1] - 2022-12-01

  • Initial release.

Последние обсуждения в сообществе MODX.pro