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

В качестве объектов скидки могут выступать:

  • чек,
  • товарная позиция,
  • набор товаров. 

Набор – совокупность товаров, которые рассматриваются как единый объект. Наиболее распространенным вариантом набора является предоставление скидки на один вид товара при условии покупки другого. Для предоставления скидки, необходимо чтобы все элементы набора присутствовали в чеке в нужном количестве. В наборах могут участвовать все штучные и весовые товары за исключением расфасованных.

Кассовое решение поддерживает две модели скидок: объектную и традиционную табличную. Объектная модель скидок более гибкая, поскольку позволяет:

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

Табличная (традиционная) модель обладает следующими особенностями:

  • возможность заведения скидок в системе товарного учета,
  • ограниченный перечень условий скидок,
  • жестко заданный порядок применения скидок,
  • правила взаимодействия скидок задаются для объекта скидки (позиция, чек).

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

Для обеих моделей скидок независимо от выбранного объекта скидки результат воздействия распределяется по позициям.

При работе кассовой программы перечитывание дисконтной системы осуществляется при:

  • входе в терминал продаж,
  • отмене любого документа,
  • открытии чека продажи,
  • закрытии документов продажи/возврата.

Прогресс обновления дисконтной системы отображается только если в нее были внесены изменения.

Конфигурирование

Дисконтная система поставляется отдельным пакетом artix45-discountsystem.

Наличие минимальной цены влияет на методы распределения скидок на чек и наборы. Минимальные цены не учитываются на этапе расчета скидок, дополнительное ограничение минимальной цены накладывается на этапе применения. 

Сумма скидки на чек распределяется в два этапа:

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

Правила распределения остатка определяется параметром distributeReceiptDiscountFully в конфигурационном файле /linuxcash/cash/conf/ncash.ini в секции [Discount]:

  • при значении параметра true остаток скидки распределяется максимально возможными суммами, учитывая ограничения минимальной ценой товара. Выполняется только первый этап распределения скидки;
  • при значении параметра false сумма скидки на чек распределяется по позициям пропорционально их стоимости.

Размер скидки на позицию ограничивается минимальной ценой товара. В случае предоставления скидок на наборы минимальную цену на товары можно игнорировать для того, чтобы иметь возможность задавать акции вида "купи две штуки и одну получи в подарок", когда скидка назначается только на один из товаров. Возможность игнорирования минимальной цены при предоставлении скидки на наборы задается параметром ignoreMinimalPriceForKit в конфигурационном файле /linuxcash/cash/conf/ncash.ini в секции [Discount]:

  • при значении параметра true минимальная цена при применении скидки на набор игнорируется,
  • при значении параметра false скидка на комплект будет предоставлена с учетом минимальной цены на товар.

В основе дисконтной системы заложена идея использования любых доступных элементов чека (товарная позиция, дисконтная карта и т.д.) для проверки условий и вычисления ставок. Так как условия скидок могут быть сложными, то после изменения состава чека выполняется отмена ранее примененных скидок, последующий пересчет и применение новых. Пересчет скидок может занимать продолжительное время, это может происходить из-за недостатка ресурсов машины, на которой осуществляется работа, или из-за сложности самих скидок. Кассовое ПО Artix может быть настроено таким образом, чтобы расчет скидок происходил как в процессе формирования чека, так и только при переходе к оплате документа. Момент расчета скидок задается параметром recalcDiscInFormingMode в конфигурационном файле /linuxcash/cash/conf/ncash.ini в секции [Check]:

  • при значении параметра true скидки пересчитываются в режиме формирования документа,
  • при значении параметра false скидки пересчитываются при переходе в подытог.

Если расчет скидок происходит в режиме формирования документа, то пересчет скидок выполняется после:

  • добавления или сторнирования товарной позиции,
  • добавления или удаления карты,
  • изменения модификаторов (цена, количество и т.п.) товарной позиции.

При использовании акций со ставкой 0% (например, рекламных) можно контролировать запись информации о сработавшем дисконтном воздействии на позицию в БД Documents таблицу Discitem. Возможность сохранения скидки 0% на позицию в БД задается параметром saveNullDiscountForPosition в конфигурационном файле /linuxcash/cash/conf/ncash.ini в секции [Discount]:

  • при значении параметра true скидки 0% на позицию сохраняются в БД,
  • при значении параметра false скидки 0% на позицию не сохраняются в БД.

Скидка 0% на чек в БД не записывается.

Скидка более 0% на позицию, но с результатом 0 р. будет записана в БД. Например, если скидка 50%, то для позиций с ценой 0.00 или 0.01 в БД будет записываться информация о скидке.

НаименованиеТип данныхВозможные значенияОписаниеПримечания
distributeReceiptDiscountFullyлогический
  • true
  • false
Полностью распределять по позициям сумму скидки на чекПо умолчанию true
ignoreMinimalPriceForKitлогический
  • true
  • false
Игнорировать минимальную цену при применении скидки на комплектПо умолчанию true

recalcDiscInFormingMode

логический
  • true
  • false

Пересчитывать скидки в режиме формирования чека

По умолчанию true

saveNullDiscountForPositionлогический
  • true
  • false
Сохранять скидку 0% на позицию в базу данныхПо умолчанию false
Пример настроек
[Discounts]
;
; Скидки
;
... 
; Полностью распределять по позициям сумму скидки на чек
distributeReceiptDiscountFully = false
...
; Сохранять скидку 0% на позицию в базу данных
saveNullDiscountForPosition = true
; Игнорировать минимальную цену при применении скидки на комплект
ignoreMinimalPriceForKit = false

[Check]
;
; Настройки чека
;
...
; Пересчитывать скидки в режиме формирования чека, по-умолчанию true.
recalcDiscInFormingMode = true

Логирование

Сообщения системы лояльности сохраняются в логе кассовой программы /linuxcash/logs/current/terminal.log на уровне ERROR. Уровень логирования, формат сообщения и место сохранения данных могут быть изменены в файле /linuxcash/cash/discountsystems/logging.properties. Изменения вступают в силу после перезапуска кассовой программы.
Подробнее об уровнях логирования можно прочитать в статье "Логирование работы кассы". 

При установке уровня логирования DEBUG для Subsystem, Discount, Campaign работа дисконта может быть замедлена.
Пример настроек логгера
[loggers]
keys=root,suartix,sqlalchemy,Subsystem,Impact,AggregateImpact,Discount,Campaign,DiscountCondition,DiscountRate,Kit,KitLogic,Ratefunction,Conditionfunction

[handlers]
keys=fileHandler,consoleHandler

[formatters]
keys=defaultFormatter

[logger_root]
level=INFO
handlers=consoleHandler

[logger_sqlalchemy]
qualname=sqlalchemy
level=ERROR
handlers=consoleHandler
propagate=0

[logger_suartix]
qualname=suartix
level=INFO
handlers=consoleHandler
propagate=0

[logger_Subsystem]
qualname=Subsystem
level=ERROR
handlers=consoleHandler
propagate=0

[logger_Impact]
qualname=Impact
level=ERROR
handlers=consoleHandler
propagate=0

[logger_AggregateImpact]
qualname=AggregateImpact
level=ERROR
handlers=consoleHandler
propagate=0

[logger_Discount]
qualname=Discount
level=ERROR
handlers=consoleHandler
propagate=0

[logger_Campaign]
qualname=Campaign
level=ERROR
handlers=consoleHandler
propagate=0

[logger_DiscountCondition]
qualname=DiscountCondition
level=ERROR
handlers=consoleHandler
propagate=0

[logger_DiscountRate]
qualname=DiscountRate
level=ERROR
handlers=consoleHandler
propagate=0

[logger_Kit]
qualname=Kit
level=ERROR
handlers=consoleHandler
propagate=0

[logger_KitLogic]
qualname=KitLogic
level=ERROR
handlers=consoleHandler
propagate=0

[logger_Ratefunction]
qualname=Ratefunction
level=ERROR
handlers=consoleHandler
propagate=0

[logger_Conditionfunction]
qualname=Conditionfunction
level=ERROR
handlers=consoleHandler
propagate=0

[handler_consoleHandler]
class=StreamHandler
formatter=defaultFormatter
args=(sys.stdout,)

[handler_fileHandler]
class=FileHandler
formatter=defaultFormatter
args=('dm.log', 'a')

[formatter_defaultFormatter]
format=[%(levelname)s] <%(module)-9s/%(funcName)-15s:%(lineno)-3d> - %(message)s
datefmt=
class=logging.Formatter

Объектная модель

Объектная модель представляет множество дисконтных акций, которые состоят из объекта скидки, множества условий, ставки, сообщений для кассира и покупателя. Акции организуются в иерархическую структуру (дерево), в рамках одной ступени иерархии задается правило совместного применения акций. Воздействия выбираются по одному из критериев:

  • все сработавшие акции,
  • максимальная по сумме воздействия,
  • минимальная по сумме воздействия,
  • первая акция по порядку,
  • последняя акция по порядку,
  • максимум по позициям.

Определить в какой версии кассового ПО будет применена та или иная акция, можно при помощи условия:

check["version"] == u"4.6.96"

Дерево дисконта

Начиная с версии 4.6.98 в кассовой программе может быть использовано 2 дерева дисконтной системы.

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

Акции, заводимые в разных деревьях дисконта, взаимодействуют по критерию "Все сработавшие акции".

Загрузка объектной модели лояльности производится в БД Dictionaries таблицу Discountsystem:

  • в поле discsystem – первое дерево дисконта,
  • в поле seconddiscsystem – второе (дополнительное) дерево дисконта.

После применения всех дисконтных воздействий в чеке информация о примененной дисконтной системе будет записана в БД Documents таблицу Discitem поле discsystem:

  • 1 – воздействие из первого дерева дисконта,
  • 2 – воздействие из второго дерева дисконта.

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

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

Пример

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

В дисконтную систему заведено 2 акции:

  1. Предоставлять скидку 7% по карте клиента.
  2. Выдавать купон на скидку 10% при покупке на 1000 рублей.

На кассе набивается чек:

  1. Масло 200 р.
  2. Торт 600 р.
  3. Чай 200 р.

Итого: 1000 р.

С учетом скидки по карте сумма чека составит 930 р. По условию акции купон на скидку не должен быть предоставлен, т.к. сумма чека менее 1000 р.

Заведение акций в одно дерево дисконта

Т.к. акции заведены в одно дерево дисконта, акция на выдачу купона принимает сумму чека до применения скидок, т.е. 1000 р. Купон будет выдан.

Заведение акций в два дерева дисконта

Т.к. акции заведены в 2 дерева дисконта, акция на выдачу купона принимает сумму чека после применения скидок из первого дерева дисконта, т.е. 930 р. Купон не будет выдан.

Очередность акций

Начиная с версии 4.6.144 при помощи утилиты администрирования Yuki или веб-приложения Artix Loyalty Management можно настроить очередность акций.

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

  • Если у акции не задан приоритет, то происходит наследование приоритета от родительской группы.

    Пример

    Группа акций с приоритетом 1 содержит:

    • акцию №1, приоритет не задан,
    • акцию №2 с приоритетом 3,
    • акцию №3 с приоритетом 2.

    Очередность акций:

    • первой сработает акция №1 (приоритет унаследован от группы акций),
    • второй сработает акция №3 с приоритетом 2,
    • последней сработает акция №2 с приоритетом 3.
  • Если у акций внутри группы приоритет задан, а у группы акций – нет, то акции будут срабатывать в порядке очередности.

    Пример

    Группа акций, приоритет не задан, содержит:

    • акцию №1 с приоритетом 4,
    • акцию №2 с приоритетом 3,
    • акцию №3 с приоритетом 2.

    Очередность акций:

    • первой сработает акция №3 с приоритетом 2,
    • второй сработает акция №2 с приоритетом 3,
    • последней сработает акция №1 с приоритетом 4.
  • Если у акции и у группы акций не задан приоритет, то акция наследует приоритет у группы акции, стоящей выше по иерархии.

    Пример

    Родительская группа акций с приоритетом 3 содержит:

           Группу акций 1, приоритет не задан, содержит:

    • акцию №1, приоритет не задан.

           Группа акций 2 с приоритетом 2 содержит:

    • акцию №2 с приоритетом 1.

    Очередность акций:

    • первой сработает акция №2 с приоритетом 1,
    • второй сработает акция №1 (приоритет 3 унаследован от родительской группы акций).
  • Если у акций и группы акций приоритет не задан, то акции будут срабатывать по порядку согласно дереву дисконта.

Объект

В концепции объектной модели дисконта чек состоит из объектов, к которым могут быть применены воздействия (скидки). В качестве объектов скидки выступают: 

  • чек,
  • позиция,
  • набор,
  • набор с наименьшей скидкой.

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

При задании дисконтных акций на наборы с наименьшей скидкой желательно использовать объединение позиций, которое регламентируется параметром unitePositionsInKit в конфигурационном файле /linuxcash/cash/conf/ncash.ini в секции [Discount]:

  • при значении параметра true позиции, являющиеся составной частью набора объединяются в одну при условии, что у товаров совпадают код, штрих-код и цена,
  • при значении параметра false наборные позиции не объединяются.
НаименованиеТип данныхВозможные значенияОписаниеПримечания

unitePositionsInKit

логический
  • true
  • false
Объединять позиции в наборахПо умолчанию true


Пример настройки
[Discounts]
;
; Скидки
;
...
; Объединять позиции в наборах (по умолчанию true)
; unitePositionsInKit = true

Условие

Для того, чтобы к объекту было применено воздействие, необходимо выполнение всех заданных условий. Условия могут быть самыми разнообразными, от тривиального: "если сумма чека больше ...", до более изощренных – "на каждый второй товар с определенным признаком". 

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

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

В условиях скидок можно использовать объекты:

  • текущая товарная позиция (доступен при условии, что объектом скидки является товарная позиция),
  • чек (доступен всегда),
  • дисконтная карта (доступен в условиях, которые используют карту),
  • клиент (доступен в условиях, которые используют карту),
  • нажатая кнопка (ручная скидка по кнопке).

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

Ставка

Результатом применения скидки является воздействие. Ставка скидки определяет тип скидки и правила расчета размера воздействия. Воздействия применяются к объекту скидки, правило расчета суммы зависит от типа ставки:

  • процентная, сумма скидки вычисляется как процент от суммы объекта скидки
    СуммаСоСкидкой = Сумма - (Сумма * (ПроцентСкидки / 100)),
  • абсолютная, сумма скидки равна указанной ставке: 
    СуммаСоСкидкой = Сумма - СуммаСкидки;

    В случае применения абсолютной скидки к позиции ее размер не зависит от количества товара в данной позиции. 
  • индексная, сумма вычисляется как разность стоимости объекта и стоимости объекта при выборе указанной колонки цен (для товарных позиций): 
    СуммаСоСкидкой = Количество * (Цена - ИндекснаяЦена),
  • расчетная, размер ставки рассчитывается по произвольно заданному условию.

Расчет размеров воздействий выполняется дисконтной системой, в кассовую программу передаются примененные воздействия и их абсолютные значения (суммы). Кассовая программа может накладывать дополнительное условие на итоговую цену товара: итоговая цена после применения скидок должна быть выше или равна минимальной цене товара.

Для отдельных акций дисконтная система позволяет игнорировать ограничение минимальной цены товара.

Сообщения

Кроме воздействий, дисконтная система позволяет формировать сообщения для покупателя и кассира. Сообщения из всех акций консолидируются с сообщениями из внешней системы лояльности и передаются в программу общим блоком.

Сообщение для кассира отображается на экране однократно или каждый раз перед переходом к оплате чека. Данное поведение регулируется параметром alwaysShowCashierMessages в конфигурационном файле /linuxcash/cash/conf/ncash.ini в секции [Check]:

  • при значении параметра true сообщение для кассира отображается каждый раз перед переходом к оплате чека, если чек был изменен при возврате в режим формирования,
  • при значении параметра false сообщение для кассира отображается однократно перед переходом к оплате чека.
НаименованиеТип данныхВозможные значенияОписаниеПримечания

alwaysShowCashierMessages

логический
  • true
  • false
Всегда показывать сообщение кассиру при переходе в подытогПо умолчанию false

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

Традиционная модель

Преимуществом традиционной модели является возможность ведения условий в системе товарного учета, недостаток модели – ограниченные возможности по заданию условий скидок. Традиционная модель наиболее совместима с дисконтной системой Штрих-М:кассир. Выгружать условия скидок для традиционной модели можно во всех конвертерах, которые позволяют загружать скидки в кассу, наиболее полно загрузка условий реализована в форматах AIF и Штрих-М.

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

Объект "старый дисконт" является метаобъектом. Для объекта данного вида выполняется вызов традиционной модели для расчета скидок, результат возвращается в виде множества объектов и примененных к ним воздействий.

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

В расчете может участвовать только одна карта.

Поиск условия для вычисления скидки по карте выполняется в следующем порядке:

  1. Наборы.
  2. Автоматические скидки:
    • скидки на позицию без карты (вид карты равен 0),
    • скидки на чек без карты (вид карты равен 0),
    • скидки по карте.
  3. Накопительные скидки.
  4. Фиксированные скидки.

Подбор скидки прекращается при обнаружении подходящего условия.

Для определения механизмов взаимодействия скидок используется ряд параметров, которые задаются в конфигурационном файле /linuxcash/cash/conf/ncash.ini в секции [Discounts].

Параметры взаимодействия скидок

НаименованиеТип данныхВозможные значенияОписаниеПримечания
discModeстроковый
  • all
  • over
  • deny

Способ взаимодействия скидок на чек

  • all – суммирование скидок,
  • over – применение последней скидки,
  • deny – использование первой примененной скидки.
По умолчанию over
discPositionModeстроковый
  • all
  • over
  • max
  • deny

Способ взаимодействия скидок на позицию

  • all – суммирование скидок,
  • over – применение последней скидки,
  • max – применение наибольшей из скидок,
  • deny – использование первой примененной скидки.

По умолчанию deny

pos2CheckDiscRelстроковый
  • add
  • deny

Взаимодействие скидок на чек и на позицию

  • add – применять скидку на чек всегда,
  • deny – применять скидку на чек, если не применены скидки на позицию.
По умолчанию deny
Пример настроек
[Discounts]
;
; Скидки
;

... 
; способ воздействия скидок на чек
discMode = "all"
 
; способ воздействия скидок на на позицию
discPositionMode = "deny"
 
; отношение скидки на чек к скидке на позиции
pos2CheckDiscRel = "add"
...

Вывод скидки на экран

Наименование скидки, примененной к позиции, отображается в левой нижней части экрана в области информации о товаре. В случае, если к позиции было применено несколько скидок, то отображается первая примененная. Скидка на мелочь не учитывается.

Функция реализована только для GUI.
  • No labels