msProductDiscounts

Создание скидок на товары с широкими возможностями настройки
Автор дополнения
Артур Шевченко
Пакетов
6
Закачек
1 916
Обычно отвечает в течение недели
Автор дополнения
Пакетов
6
Закачек
1 916
Обычно отвечает в течение недели
Версия 1.4.7-pl
Дата выпуска 25.12.2023
Загрузки 24
Просмотры 1 896
Внимание, этот компонент требует версию PHP 7.0 или выше! Если ваш сайт использует PHP ниже требуемого, установка этого дополнения может его сломать.
Внимание, этот компонент требует версию MODX не ниже 2.6 !
НЕ РАБОТАЕТ С MODX 3

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

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

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

[1.4.2] Добавлена поддержка ajax пагинации в pdoPage.

Добавлено событие mspd-cart-update в JS для работы с результатами актуализации корзины. Добавлено событие mspd-get-discounts в JS для работы с оповещением пользователя о доступных скидках.

Добавлена возможность установить временной интервал для принудительной перезагрузки корзины на случай если пользователь оставил открытой страницу браузера с корзиной на долгое время. Принудительная перезагрузка осуществляется 1 раз в сутки. Интервал не должен превышать 1 минуты, т.е. примерно так 01:00-01:01

Сниппет вывода информации о скидках на конкретный товар удалён. Вместо него добавлен процессор. Таким образом показ цены со скидкой происходит автоматически, если в чанк товара добавлены соответствующие атрибуты. Так вся информация о товаре должна быть внутри блока с атрибутом 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". Такие свойства как Производитель, Страна изготовитель, Новый, Особый, Популярный можно не обозначать и не передавать в корзину, они проверяются по умолчанию.

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