API Set10 ◾️ Настройка порядка применения провайдеров лояльности

Публичное пространство

API Set10 ◾️ Настройка порядка применения провайдеров лояльности

Внимание!

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

https://crystals.atlassian.net/browse/SR-4807

https://crystals.atlassian.net/browse/CR-5733

Описание

Расчет скидок на кассе производится в модуле "провайдер лояльности". На кассе может присутствовать более одного провайдера лояльности:

  • SetRetail10;

  • Manzana;

  • Set API;

  • и т. п.

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

Одно из частых требований – производить фильтрацию рекламных акций (в более поздних версиях SetRetail10 рекламные акции были переименованы в кассовые механики) и применять скидку на округление только после окончания расчета скидок в цепочке.

Настройка и логика применения провайдеров лояльности к чеку

Для настройки порядка, в котором провайдеры лояльности будут применяться к чеку, а также выбора порядка применения скидок различного типа (округление, суммирующиеся всегда и т. д.), используется конфигурацонный файл /home/tc/storage/crystal-cash/modules/loyalty/ext-loyalty-providers.xml. Этот файл требуется настраивать вручную для каждой кассы.

<?xml version="1.0" encoding="UTF-8"?> <beans xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <!-- Расширенный (EXTended) список поставщиков "услуг лояльности". Или внешние (EXTernal) поставщики лояльности --> <!-- Средство для получения списка РА, что могут действовать на чек прямо сейчас --> <bean id="loy-actions-provider" class="ru.crystals.loyal.actions.provider.InMemoryLoyActionsProvider" init-method="start"> <property name="cache" ref="actions-cache"/> </bean> <!-- Реестр всех "поставщиков" "услуг лояльности". Он же - главный "калькулятор" "преференций" --> <bean id="loy-providers-registry" class="ru.crystals.loyal.providers.LoyProvidersRegistryImpl" init-method="init"> <property name="providers"> <list> <bean class="ru.crystals.loyal.providers.CustomSetLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> <property name="filter"> <bean class="ru.crystals.loyal.providers.set.filters.SetActionsAndFilter"> <property name="filters"> <list> <bean class="ru.crystals.loyal.providers.set.filters.NonWorksAnyTimeSetActionsFilter" /> <bean class="ru.crystals.loyal.providers.set.filters.NonRoundingSetActionsFilter" /> </list> </property> </bean> </property> </bean> <!-- сторонние поставщики лольяности пошли --> <ref bean="set-api-loy-provider"/> <bean class="ru.crystals.pos.loyal.ml.ManzanaLoyProvider" /> <bean class="ru.crystals.pos.loyal.sc.SCLoyProvider" /> <ref bean="loymax-loy-provider" /> <ref bean="kopilka-loy-provider" /> <ref bean="set-machine-loy-provider" /> <bean class="ru.crystals.loyal.providers.CustomSetLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> <property name="filter"> <bean class="ru.crystals.loyal.providers.set.filters.SetActionsAndFilter"> <property name="filters"> <list> <bean class="ru.crystals.loyal.providers.set.filters.WorksAnyTimeSetActionsFilter" /> <bean class="ru.crystals.loyal.providers.set.filters.NonRoundingSetActionsFilter" /> </list> </property> </bean> </property> </bean> <bean class="ru.crystals.loyal.providers.CustomSetLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> <property name="filter"> <bean class="ru.crystals.loyal.providers.set.filters.RoundingSetActionsFilter" /> </property> </bean> </list> </property> <property name="staleFeedbackSendIntervalSeconds" value="120"/> <property name="maxStaleFeedbackToSend" value="5"/> </bean> <!-- Наш (SET10) классический поставщик услуг лояльности --> <bean id="classic-set10-loy-provider" class="ru.crystals.loyal.providers.ClassicSetLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> </bean> <!-- Поставщик лояльности SetMachine --> <bean id="set-machine-loy-provider" class="ru.crystals.pos.loyal.sm.SetMachineLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> </bean> <!-- Поставщик лояльности Loymax --> <bean id="loymax-loy-provider" class="ru.crystals.pos.loyal.loymax.LoymaxLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> </bean> <!-- Поставщик лояльности Kopilka --> <bean id="kopilka-loy-provider" class="ru.crystals.pos.loyal.kopilka.KopilkaLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> </bean> <bean id="set-api-loy-provider" class="ru.crystals.pos.loyal.SetApiPluginLoyProvider" init-method="init"> <property name="actionsProvider" ref="loy-actions-provider"/> </bean> </beans>

С версии 10.2.99.0 содержимое конфигурационного файла ext-loyalty-providers.xml переносится в кассовую базу данных _DB.pngcatalog в таблицу _Table.jpgsales_management_properties:

module_name

plugin_name

property_key

property_value

description

module_name

plugin_name

property_key

property_value

description

SET_DISCOUNTS

ext.loyalty.providers

(конфигурация провайдеров лояльности - ранее текстовое содержимое файла

ext-loyalty-providers.xml как оно есть, в формате xml)

Описание провайдеров лояльности (xml)

При обновлении кассы на версию 10.2.99.0 и выше содержимое файла ext-loyalty-providers.xml перенесётся в базу данных кассы автоматически в указанную таблицу. После ручного редактирования конфигурации провайдеров лояльности перезагрузите кассу.

Файл ext-loyalty-providers.xml останется на кассе, но потеряет актуальность (кроме случаев, когда конфигурация в базе данных окажется невалидной). В случае ошибки в конфигурации в базе данных используется конфигурация из файла, чтобы не сломать работу кассы.

Список и порядок применяемых провайдеров лояльности находится в секции loy-providers-registry, свойстве providers (пример секции представлен ниже). Вам всё ещё нужно регистрировать провайдер лояльности во Внешних процессингах на сервере и создавать кассовую механику его для срабатывания, чтобы расчет скидок в нем действительно был произведен. Доступные кассе провайдеры лояльности и способ их записи представлены в таблице ниже.

<bean id="loy-providers-registry" class="ru.crystals.loyal.providers.LoyProvidersRegistryImpl" init-method="init"> <property name="providers"> <list> <ref bean="soft-check-loy-provider"/> <bean class="ru.crystals.loyal.providers.CustomSetLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> <property name="filter"> <bean class="ru.crystals.loyal.providers.set.filters.SetActionsAndFilter"> <property name="filters"> <list> <bean class="ru.crystals.loyal.providers.set.filters.NonWorksAnyTimeSetActionsFilter" /> <bean class="ru.crystals.loyal.providers.set.filters.NonRoundingSetActionsFilter" /> </list> </property> </bean> </property> </bean>

Провайдер

Способ подключения в список

Провайдер

Способ подключения в список

Стандартный провайдер лояльности Set10

<ref bean="classic-set10-loy-provider"/>

Конфигурируемый провайдер лояльности Set10

Подробности в главе https://crystals.atlassian.net/wiki/spaces/SR10SUPPORT/pages/1049788761/API+Set10#%D0%9A%D0%BE%D0%BD%D1%84%D0%B8%D0%B3%D1%83%D1%80%D0%B8%D1%80%D1%83%D0%B5%D0%BC%D1%8B%D0%B9-%D0%BF%D1%80%D0%BE%D0%B2%D0%B0%D0%B9%D0%B4%D0%B5%D1%80-%D0%BB%D0%BE%D1%8F%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8-Set10

Провайдер лояльности "Копилка"

<ref bean="kopilka-loy-provider"/>

Manzana Loyalty

<bean class="ru.crystals.pos.loyal.ml.ManzanaLoyProvider" />

Loymax (не плагинный)

<ref bean="loymax-loy-provider" />

Set Machine

<ref bean="set-machine-loy-provider" />

Smart Checkout

<bean class="ru.crystals.pos.loyal.sc.SCLoyProvider" />

Set API

<ref bean="set-api-loy-provider"/>

Конфигурируемый провайдер лояльности Set10

В отличии от стандартного провайдера лояльности Set10, конфигурируемый провайдер лояльности Set10 может применять к своим кассовым механикам заданные фильтры.

Обычно такая методика используется для того, чтобы посчитать скидки Set10 первыми, не учитывая результаты кассовых механик с результатом "Округление", а затем – скидки какого-либо иного провайдера и только потом применить кассовую механику с результатом "Округление". Поэтому такой провайдер может встречаться в цепочке расчета несколько раз. Для этого провайдер может быть настроен одним или несколькими фильтрами кассовых механик.

Пример декларирования конфигурируемого провайдера лояльности Set10 для выполнения расчета рекламных акций, которые не суммируются всегда и не имеют результат типа "Округление", представлен ниже.

Если требуется отобразить суммирующиеся скидки Set10 в вашем плагине лояльности, тогда переместите в стандартном конфиге провайдер лояльности SetAPI вниз по списку после суммирующихся акций и перед акциями на округление. Ниже приведен пример:

... <ref bean="set-api-loy-provider"/> <bean class="ru.crystals.loyal.providers.CustomSetLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> <property name="filter"> <bean class="ru.crystals.loyal.providers.set.filters.RoundingSetActionsFilter" /> </property> </bean>
<bean class="ru.crystals.loyal.providers.CustomSetLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> <property name="filter"> <bean class="ru.crystals.loyal.providers.set.filters.SetActionsAndFilter"> <property name="filters"> <list> <bean class="ru.crystals.loyal.providers.set.filters.WorksAnyTimeSetActionsFilter" /> <bean class="ru.crystals.loyal.providers.set.filters.NonRoundingSetActionsFilter" /> </list> </property> </bean> </property> </bean>

Фильтры кассовых механик, которые будут применяться провайдером, декларируются в свойстве filter. Здесь можно задекларировать либо один фильтр, либо цепочку фильтров, применяемых по логическому И, ИЛИ, НЕ. Список доступных фильтров приведен ниже в таблице.

Какие акции допускает

Пример декларации

Комментарий

Какие акции допускает

Пример декларации

Комментарий

Акции, приводящие к начислению бонусов Set10

<bean class="ru.crystals.loyal.providers.set.filters.BonusAccrueSetActionsFilter" />

 

"Бонусы как скидка"

<bean class="ru.crystals.loyal.providers.set.filters.BonusDiscountSetActionsFilter" />

 

Печать купона

<bean class="ru.crystals.loyal.providers.set.filters.CouponSetActionsFilter" />

 

Оповещение о подарках

<bean class="ru.crystals.loyal.providers.set.filters.GiftNotificationSetActionsFilter" />

 

Любая кассовая механика, результатом которой не является скидка на округление

<bean class="ru.crystals.loyal.providers.set.filters.NonRoundingSetActionsFilter" />

 

Любая кассовая механика, которая не суммируется всегда

<bean class="ru.crystals.loyal.providers.set.filters.NonWorksAnyTimeSetActionsFilter" />

 

Результатом кассовой механики является "Скидка на округление"

<bean class="ru.crystals.loyal.providers.set.filters.RoundingSetActionsFilter" />

 

Кассовые механики, которые суммируются всегда

<bean class="ru.crystals.loyal.providers.set.filters.WorksAnyTimeSetActionsFilter" />

 

Комплексный фильтр кассовых механик, объединяет находящиеся в нём фильтры логическим "И". Это означает, что кассовая механика допускается к рассмотрению только при условии, что она удовлетворяет всем фильтрам данного фильтра.

<bean class="ru.crystals.loyal.providers.set.filters.SetActionsAndFilter"> <property name="filters"> <list> <bean class="ru.crystals.loyal.providers.set.filters.WorksAnyTimeSetActionsFilter" /> <bean class="ru.crystals.loyal.providers.set.filters.NonRoundingSetActionsFilter" /> </list> </property> </bean>

Для примера изображено подключение двух фильтров: "Суммируются всегда" и "Не округление".

Это означает, что задекларированный фильтр пропускает только суммирующиеся всегда кассовые механики, результатом которых не является округление.

Комплексный фильтр кассовых механик, объединяет находящиеся в нём фильтры логическим "ИЛИ". Это означает, что кассовая механика допускается к рассмотрению, если она удовлетворяет хотя бы одному фильтру.

<bean class="ru.crystals.loyal.providers.set.filters.SetActionsOrFilter"> <property name="filters"> <list> <bean class="ru.crystals.loyal.providers.set.filters.BonusAccrueSetActionsFilter" /> <bean class="ru.crystals.loyal.providers.set.filters.BonusDiscountSetActionsFilter" /> </list> </property> </bean>

Для примера изображен фильтр, пропускающий кассовые механики типа "Начисление бонусов Set 10" или "Бонусы как скидка".

Служебный фильтр, предназначен для инвертирования результата другого фильтра.

<bean class="ru.crystals.loyal.providers.set.filters.SetActionsNotFilter"> <property name="hostFilter"> <bean class="ru.crystals.loyal.providers.set.filters.WorksAnyTimeSetActionsFilter" /> </property> </bean>

На примере изображен эквивалент фильтра "Не суммирующиеся всегда".

Пример конфигурации процесса расчета скидок

Например, в SetRetail10 заведены кассовые механики, представленные в таблице. Необходимо обеспечить:

  • расчет скидок округления после всех остальных скидок;

  • расчет скидок Loymax после плагинов Set API, но до суммирующихся всегда;

  • не суммирующиеся всегда скидки считаются первыми.

Тогда конфигурационный файл цепочки провайдеров лояльности примет вид, представленный ниже в коде.

Название

Суммируется всегда

Результат

Название

Суммируется всегда

Результат

Скидка 10% безусловная

Нет

Скидка 10% от суммы чека

Расчет скидок в Loymax

Да

Расчет скидок в бонусной системе Loymax

Расчет скидок в плагинах Set API

Нет

Расчет скидок в одном или более подключенных плагинов Set API

Скидка 3% безусловная, всегда

Да

Скидка 3%

Округление

Да

Скидка на округление до рубля

<?xml version="1.0" encoding="UTF-8"?> <beans xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <bean id="loy-actions-provider" class="ru.crystals.loyal.actions.provider.InMemoryLoyActionsProvider" init-method="start"> <property name="cache" ref="actions-cache"/> </bean> <!-- Реестр всех "поставщиков" "услуг лояльности". Он же - главный "калькулятор" "преференций" --> <bean id="loy-providers-registry" class="ru.crystals.loyal.providers.LoyProvidersRegistryImpl" init-method="init"> <property name="providers"> <list> <!-- Первыми считаются рекламные акции Set10, которые не являются суммирующимися всегда и не производят округления--> <bean class="ru.crystals.loyal.providers.CustomSetLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> <property name="filter"> <bean class="ru.crystals.loyal.providers.set.filters.SetActionsAndFilter"> <property name="filters"> <list> <bean class="ru.crystals.loyal.providers.set.filters.NonWorksAnyTimeSetActionsFilter" /> <bean class="ru.crystals.loyal.providers.set.filters.NonRoundingSetActionsFilter" /> </list> </property> </bean> </property> </bean> <!-- Далее следует расчет скидок в Set API --> <ref bean="set-api-loy-provider"/> <!-- Расчет скидок в неплагинной (не Set API) интеграции с Loymax --> <ref bean="loymax-loy-provider" /> <!-- Расчет скидок Set10, суммирующихся всегда и не являющихся скидками на округление --> <bean class="ru.crystals.loyal.providers.CustomSetLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> <property name="filter"> <bean class="ru.crystals.loyal.providers.set.filters.SetActionsAndFilter"> <property name="filters"> <list> <bean class="ru.crystals.loyal.providers.set.filters.WorksAnyTimeSetActionsFilter" /> <bean class="ru.crystals.loyal.providers.set.filters.NonRoundingSetActionsFilter" /> </list> </property> </bean> </property> </bean> <!-- Расчет скидок на округление --> <bean class="ru.crystals.loyal.providers.CustomSetLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> <property name="filter"> <bean class="ru.crystals.loyal.providers.set.filters.RoundingSetActionsFilter" /> </property> </bean> </list> </property> <property name="staleFeedbackSendIntervalSeconds" value="120"/> <property name="maxStaleFeedbackToSend" value="5"/> </bean> <!-- Наш (SET10) классический поставщик услуг лояльности --> <bean id="classic-set10-loy-provider" class="ru.crystals.loyal.providers.ClassicSetLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> </bean> <!-- Поставщик лояльности SetMachine --> <bean id="set-machine-loy-provider" class="ru.crystals.pos.loyal.sm.SetMachineLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> </bean> <!-- Поставщик лояльности Loymax --> <bean id="loymax-loy-provider" class="ru.crystals.pos.loyal.loymax.LoymaxLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> </bean> <!-- Поставщик лояльности Kopilka --> <bean id="kopilka-loy-provider" class="ru.crystals.pos.loyal.kopilka.KopilkaLoyProvider"> <property name="actionsProvider" ref="loy-actions-provider"/> </bean> <bean id="set-api-loy-provider" class="ru.crystals.pos.loyal.SetApiPluginLoyProvider" init-method="init"> <property name="actionsProvider" ref="loy-actions-provider"/> </bean> </beans>

Таким образом, в процессе расчета скидок над чеком будут произведены следующие вариации расчета:

  1. Расчет не суммирующихся всегда неокругляющих скидок. Применена кассовая механика "Скидка 10% безусловная", сумма чека уменьшилась на 10% от первоначальной стоимости.

  2. Произведен расчет чека с скидкой 10% в плагинах Set API.

  3. В Loymax произведен расчет чека с скидкой 10% и результатом расчета скидок в Set API.

  4. К чеку с скидками 10%, Set API, Loymax применилась скидка 3% по РА "Скидка 3% безусловная, всегда".

  5. К полученному чеку применилось округление.

Обратите внимание, несмотря на то, что рекламная акция "Расчет скидок в плагинах Set API" помечена как "не суммирующаяся всегда", её расчет был выполнен до расчета только суммирующихся скидок. Так произошло потому что только провайдеры лояльности Set10 учитывают флаг суммируемости.