При внедрении бонусной системы в связке «1С — Интернет-магазин» разработчики часто сталкиваются с проблемой временного лага. Когда покупатель оформляет заказ на сайте и применяет накопленные баллы, фактическая отгрузка и создание документа РеализацияТоваровУслуг в 1С могут произойти спустя часы или даже дни. Если баллы не заморозить сразу, клиент сможет потратить их повторно. Разберем архитектурные варианты решения этой задачи, структуру регистров и алгоритмы управления резервами.
Проанализируем классическую схему резервирования. Чтобы избежать ручных корректировок через документы начисления и списания, процесс разделяется на три ключевых этапа:
ЗаказПокупателя блокирует указанное количество баллов клиента.РеализацияТоваровУслуг списывает заблокированные бонусы с основного баланса и одновременно закрывает резерв.Рассмотрим, как правильно организовать учет остатков и резервов в типовых и доработанных конфигурациях (например, УТП, УТ или КА).
Вместо хранения признаков блокировки в текстовых реквизитах справочников целесообразно использовать регистры накопления. Выделим два основных подхода:
Используются два независимых регистра накопления остатков:
НачисленныеБонусы (измерения: Контрагент / БонуснаяКарта; ресурсы: СуммаБонусов) — отражает фактический баланс клиента.РезервыБонусов (измерения: Контрагент, ДокументРезерва; ресурсы: СуммаБонусов) — хранит информацию о замороженных баллах под конкретные заказы.Формула расчета доступного остатка для выгрузки на сайт:
ДоступныеБонусы = ОстатокНачисленные - ОстатокРезервы
В основной регистр остатков добавляется измерение Состояние со значениями перечисления Доступно и ВРезерве. При оформлении заказа выполняется переброска: расход со статуса Доступно и приход на статус ВРезерве.
Выясним причину, почему стандартное проведение документа не всегда подходит. В ряде бизнес-процессов заказы из интернет-магазина загружаются в 1С непроведенными и проходят предварительную модерацию оператором. Если проведение документа запрещено до подтверждения остатков на складе, запись в регистры накопления стандартным путем не сработает.
В такой ситуации разберем два технических решения:
Создается непериодический регистр сведений РезервированиеБонусовПоЗаказам с измерениями Контрагент, ЗаказПокупателя и ресурсом СуммаБонусов. Запись в регистр выполняется в процедуре ПриЗаписи документа заказа независимо от признака проведения. При переводе заказа в статус «Отменен» запись удаляется или очищается.
Бизнес-процесс перестраивается так, чтобы загружаемый заказ сразу проводился, но имел статус «Новый» / «В обработке». В модуле проведения документа ЗаказПокупателя формируются движения только по регистру РезервыБонусов, без резервирования товаров на складах, если это требуется регламентом компании.
Посмотрим, как документ РеализацияТоваровУслуг должен обрабатывать списание заблокированных бонусов при частичных и полных отгрузках:
// В обработке проведения документа РеализацияТоваровУслуг
Если ЗначениеЗаполнено(Сделка) И ОплатаБонусами > 0 Тогда
// 1. Окончательное списание с основного счета бонусов
Движение = Движения.НачисленныеБонусы.ДобавитьРасход();
Движение.Период = Дата;
Движение.Контрагент = Контрагент;
Движение.СуммаБонусов = ОплатаБонусами;
// 2. Закрытие резерва, установленного заказом
ДвижениеРезерв = Движения.РезервыБонусов.ДобавитьРасход();
ДвижениеРезерв.Период = Дата;
ДвижениеРезерв.Контрагент = Контрагент;
ДвижениеРезерв.ДокументРезерва = Сделка;
ДвижениеРезерв.СуммаБонусов = ОплатаБонусами;
КонецЕсли;
Если сумма реализации уменьшилась (например, из-за отсутствия части позиций на складе), списание бонусов корректируется пропорционально. Оставшаяся часть резерва по документу ЗаказПокупателя автоматически закрывается корректирующим движением расхода по регистру резервов при финальном закрытии заказа, возвращая неиспользованные баллы на свободный остаток покупателя.
При пакетном обмене по расписанию (раз в 30 минут) сохраняется риск повторного списания, если покупатель оформляет несколько заказов подряд. Для полного исключения коллизий разберем внедрение прямого взаимодействия через HTTP-сервисы в 1С:
HoldBonuses, передавая идентификатор клиента, сумму и номер корзины.ЗаказПокупателя.