new

msProductDiscounts

Создание скидок на товары с широкими возможностями настройки
Автор дополнения
Артур Шевченко
Пакетов
15
Закачек
3 354
Обычно отвечает в течение суток
Автор дополнения
Пакетов
15
Закачек
3 354
Обычно отвечает в течение суток
Версия 2.4.1-rc
Дата выпуска 31.07.2026
Загрузки 63
Просмотры 4 713
Внимание, этот компонент несовместим с 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}

2.4.1-rc — 31.07.2026

  • ИСПРАВЛЕНО: в фоновом режиме (cron сайта, консольные скрипты) скидки не видели родительские категории товара, а в лог ошибок на каждый товар падало «PHP warning: Invalid argument supplied for foreach()». Пакет брал предков ядровым modX::getParentIds(), который обходит карту дерева контекста, а она в API-режиме не построена: список родителей возвращался пустым, и скидка, назначенная на родительскую категорию, молча не применялась. Теперь предки считаются по собственной карте «ресурс → родитель»: один запрос на контекст, дальше подъём в памяти — в вебе это ещё и быстрее ядрового обхода (поиск по ключу вместо перебора всей карты).

2.4.0-rc — 23.07.2026

  • НОВОЕ: журнал действий менеджера со скидками и промокодами. Пакет записывает в mxLogger, кто и когда создал, изменил, удалил или продублировал скидку, а также кто создал, изменил или удалил промокод. В записи попадают пользователь (id и логин), действие, объект с его id и названием (кодом) и то, что именно изменилось: при создании и дублировании — все значения объекта, при изменении — только изменённые поля парами «было / стало», при удалении — полное состояние удалённого объекта. Для промокода так же фиксируются привязанные к нему скидки, в том числе их изменение. Значения полей сохраняются целиком, без сокращений, поэтому по журналу можно восстановить прежние настройки скидки. Время проставляет сам mxLogger. Найти записи можно по тэгам msproductdiscounts и audit, а историю конкретного объекта — по процессу mspd_discount_ или mspd_promocode_. Журнал ведётся всегда и не требует включённой отладки (mspd_debug). Если mxLogger на сайте не установлен, скидки и промокоды сохраняются как обычно — записи просто не ведутся.
  • ИСПРАВЛЕНО: при отборе скидок учитывались только первая категория товара и его первая модификация. Товар, лежащий в нескольких категориях каталога, мог не получить скидку, назначенную на «неглавную» категорию; то же касалось товаров с несколькими модификациями. Теперь берутся все категории товара вместе с их родительскими и все модификации.

2.3.0-rc — 23.07.2026

  • НОВОЕ: системное событие mspdOnGetShowPrices — точка расширения, через которую сайт может подать пакету собственную цену показа и старую цену конкретного товара. Событие возникает при подготовке ответа для каталога и карточки товара: после того как пакет применил свои скидки, но до того как посчитал строковые значения цены, поэтому перечёркнутая цена и цена со скидкой остаются единым механизмом пакета, а не рисуются сайтом отдельно. Параметры события: productData — данные товара, discounts — скидки, попавшие в показ (может быть пустым), scope — область показа (catalog или product), prices — текущая пара цен, object — экземпляр класса Discounts. Подписчик подменяет цены через $object->showPrices['price'] и $object->showPrices['old_price']; цену, которую он не тронул, пакет считает как раньше. Кейс: товар-комплект, выгода которого не выражается ни одной записью скидки — сайт считает пару цен сам и отдаёт её пакету, а показ остаётся единым.
  • НОВОЕ: свойство $object->externalPrices. Сайт, который подаёт свои цены показа, выставляет его в подписчике события mspdOnFilterIdsByDiscount. Флаг снимает ранний выход по корзине — без него товар, у которого скидок нет вовсе, до расчёта цены показа не доходит. Внимание: со снятым ранним выходом в ответ попадают и товары, о которых сервер раньше молчал, поэтому старая цена таких товаров берётся из карточки товара — если она там заполнена, а показывать её не нужно, подписчику следует обнулить её самому. Пока подписчика нет, флаг остаётся выключенным и ответ сервера не меняется.
  • ИЗМЕНЕНО: пункт меню компонента больше не возвращается в свою категорию при обновлении. Раньше обновление пакета перезаписывало пункт меню целиком, и он «уезжал» обратно из той категории, куда его перенёс администратор сайта. Теперь существующий пункт меню при обновлении не трогается совсем — сохраняются и его расположение, и порядок в списке.

2.2.0-rc — 21.07.2026

  • НОВОЕ: у каждой скидки появились настройки показа — «Показ в каталоге», «Показ в карточке» и «Описание акции». Каждая принимает три значения: «По умолчанию» (как раньше — по системным настройкам), «Показывать» и «Не показывать». Раньше показом скидок в списках товаров управляли только глобальные mspd_show_for_all и mspd_check_common_conditions_on_show: включив показ ради одной акции, приходилось включать его для всех скидок сразу. «Показывать» означает, что скидка участвует в расчёте цены для показа независимо от корзины: цена со скидкой и зачёркнутая старая цена видны даже при пустой корзине и невыполненных общих условиях (сумма, количество). «Не показывать» убирает скидку из показа совсем, в том числе при mspd_show_for_all=1. Настройки влияют только на показ — корзина продолжает считать фактические скидки по прежним правилам, поэтому у скрытой в каталоге скидки цена в корзине может отличаться от показанной. Кейс: «Товары недели» показывают старую и новую цену в каталоге, а «−20% на вторую единицу» в списке товаров не показывается.
  • НОВОЕ: каталог и карточка товара различаются атрибутом data-mspd-scope на обёртке товара или любом его предке: значение product — карточка товара, всё остальное (и отсутствие атрибута) — каталог. Шаблоны без атрибута работают как раньше.
  • НОВОЕ: системная настройка mspd_show_discount_info (по умолчанию «Да») — дефолт показа описания акции для скидок, у которых эта настройка оставлена в значении «По умолчанию». Раньше инфоблок по mspd_info_tpl выводился всегда и отключить его было нечем.
  • Обновление БД: у скидок появились поля show_in_catalog, show_in_product, show_description (по умолчанию 0 — «По умолчанию»), поэтому на уже работающих сайтах поведение не меняется. Затрагивает: модель mspdDiscount, Discounts::filterIdsByDiscount, Discounts::getProductDiscounts, Base::initialize, шаблон управления скидкой, js-модуль Discounts.

2.1.22-rc — 21.07.2026

  • НОВОЕ: тип применения «Суммируется с другими» (apply_type=3). Такая скидка не участвует в эксклюзивном отсечении: если у товара есть скидка «Только эту скидку», суммируемая всё равно применяется поверх неё. Работает только при mspd_many_behaviour=3 — при других значениях пакет применяет одну скидку-победителя, и суммируемая в расчёт не попадает. Порядок применения в корзине: обычные скидки → «Все кроме этой» → «Суммируется с другими». Благодаря такому порядку суммируемая скидка не отбирает у «Все кроме этой» её товары: для отбора товар по-прежнему считается «без скидки», если получил только суммируемую. Математика — каскад от текущей цены, как и у остальных скидок: 1000 ₽ при основной 10% и суммируемой 5% даёт 855 ₽, а не 850 ₽. Превью карточек товара показывает ту же цену, что даст корзина: суммируемая скидка добавляется в стек последней и не влияет на показ «Все кроме этой». Кейс: «coming_soon 5%» поверх основной скидки и поверх эксклюзивных «Товаров недели». Затрагивает: Discounts::filterDiscountsByApplyType, Discounts::applyDiscounts, Discounts::filterIdsByDiscount, шаблон управления скидкой.

2.1.21-rc — 17.07.2026

  • FIX: промокод больше не «слетает» при применении/отмене через браузер. Причина — гонка сессии: фронт после applypromocode параллельно слал getDiscounts + getCart, и их запись в незалоченную сессию MODX затирала только что записанный промокод ($_SESSION['mspd']). Теперь applypromocode/cancelpromocode сами возвращают пересчитанную корзину (products/totals/giftsChanged) в своём ответе, а фронт рендерит из него без отдельных follow-up-запросов — гоняющегося запроса больше нет. Затрагивает: сниппет mspdConnector, JS-модуль promocodes.js (successHandler).

2.1.20-rc — 16.07.2026

  • ИЗМЕНЕНИЕ ПОВЕДЕНИЯ: тип применения «Все кроме этой» (apply_type=2) теперь учитывает ФАКТИЧЕСКИ применённые скидки, а не применимые по условиям. Такая скидка применяется после остальных и только к товарам, не получившим скидку в текущем пересчёте корзины. Раньше она отбрасывалась, если у товара были другие подходящие по условиям скидки — даже когда те не дали товару никакой выгоды (например, из-за отступа). Кейс: промокод со скидкой «Все кроме этой» теперь даёт выгоду товарам, оставшимся без основной акции. В превью карточек такая скидка не стекуется с другими. Работает при mspd_many_behaviour=3.

2.1.19-rc — 16.07.2026

  • Включающие «Произвольные условия» скидки (Discounts::checkProductOptions) теперь проверяются все, а не только первое: условия группируются по ключу, внутри одного ключа — ИЛИ, между ключами — И. Раньше цикл завершался return на первой строке, и несколько include-условий не работали (в т.ч. нельзя было ограничить скидку несколькими контекстами через context_key). Exclude-условия — без изменений. Тест: dev/tests/check-product-options.php (13 кейсов).

2.1.18-rc — 16.06.2026

  • Исправлена ошибка mixed content в админке: из URL подключаемых mgr-скриптов в контроллерах (getdiscounts, getpromocodes, discount/manage, promocode/manage) убран лишний слеш после {$assetsUrl}. Переменная уже оканчивается на js/, поэтому в import ... from "{$assetsUrl}/mgr/..." получался двойной слеш js//mgr/.... Теперь путь корректный — js/mgr/....

2.1.17-rc — 16.06.2026

  • Логирование переведено на mxLogger. Отладочная трассировка скидок ($this->modx->log под mspd_debug) теперь делегируется сервису mxLogger через новый класс MsProductDiscounts\Logger и фасад Base::log(). Если mxLogger не установлен — записи молча пропускаются.
  • Новая настройка mspd_log_level (минимальный уровень debug|info|warning|error, по умолчанию error; единый приёмник mxLogger, включено из коробки), консистентно с mxlogger.min_level. Переключатель mspd_debug сохранён.
  • Тэги: базовые msproductdiscounts + cart, этап discount. process_uid воронки — по сессии. Ранее негейтнутые вызовы $this->modx->log (например дамп SQL) теперь тоже под гейтом mspd_debug.
  • ВНИМАНИЕ: перед сборкой настройку mspd_log_level создать в менеджере (namespace msproductdiscounts) — сборка тянет настройки из БД стенда.

2.1.16-rc — 23.04.2026

  • Улучшил совместимость с msAltCart: корзина теперь обновляется по событиям msac:row:add/replace/remove:after, когда msAltCart активен, стандартный ms2-колбэк пропускается во избежание двойного запроса и гонок.
  • Сделал свойство $apply в Discounts nullable (?bool), чтобы плагины на событиях mspdOnBeforeCheckDiscount/mspdOnCheckDiscount могли безопасно сбрасывать флаг применения скидки.

2.1.15-rc — 14.04.2026

  • Исправлена потеря скидок по промокодам: дисконтированные цены теперь сохраняются в сессию перед обработкой подарков, что предотвращает перезатирание цен при перечитывании корзины.

2.1.14-rc — 16.03.2026

  • Исправление ошибок

2.1.13-rc — 14.03.2026

  • Добавил поддержку мультиконтекстных подарков: товар-подарок автоматически резолвится в текущий контекст по связующему полю (настройка mspd_gift_link_field).
  • Добавил поддержку резолва модификаций подарков в другой контекст по набору опций.
  • Добавил проверку соответствия товара-подарка текущему контексту перед добавлением в корзину.

2.1.12-rc — 14.03.2026

  • Перевёл добавление и удаление подарков на стандартные методы miniShop2 (cart->add/cart->remove) с защитой от рекурсии через статический флаг.
  • Добавил флаг giftsChanged в ответ коннектора getcart для отслеживания операций с подарками.
  • Добавил вызов window.msAltCart.updateCarts() при изменении подарков в корзине.
  • Добавил событие mspd:gift:manage для кастомной обработки изменений подарков на фронтенде.
  • Добавил версионирование подключаемых JS-модулей (?v=) на основе времени последнего изменения файлов.

2.1.11-rc — 14.03.2026

  • Убрал округление строк при получении статуса корзины в коннекторе.

2.1.10-rc — 13.03.2026

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

2.1.9-rc — 12.03.2026

  • Добавил раздельные permissions для скидок (mspd_discounts) и промокодов (mspd_promocodes).
  • Добавил проверку permissions в контроллерах скидок и промокодов.
  • Добавил резольвер для регистрации permissions в AdministratorTemplate и политике Administrator.
  • Добавил установку permissions на пунктах меню.

2.1.8-rc — 10.03.2026

  • Добавил приведение к float в Discounts::applyDiscount()

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