Направление работ: Back Код раздела: 2.7 Объекты и предложения > Скидки Статус: черновик Ответственный: Панкова Л.А. Версия: 0.1 Обновлено: 20.07.26


1. Назначение

Скидки уменьшают стоимость заказа или другого объекта оплаты по правилам конкретного вида скидки.

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

2. Ключевые понятия

Скидка — сущность, которая уменьшает стоимость объекта оплаты при выполнении заданных условий.

Вид скидки — отдельная модель скидки со своими параметрами и правилами применения: акция, промокод, горящее предложение, скидка баллами или скидка на погашение сборов.

Объект оплаты — сущность, для которой система рассчитывает сумму к оплате.

3. Scope

Входит

S1 Скидки: общая сущность и состав поддерживаемых видов скидок.

S2 Операции над скидками: создание, изменение, архивация и восстановление.

Не входит

4. Требования

Правила и ограничения бизнеса на уровне данных, источник истины в системе.

IDТребованиеКомментарийТип требованияВесСтатус
S1: BR2.7-1Скидка должна храниться как отдельная сущность, которая уменьшает стоимость объекта оплаты.Объекты оплаты раскрываются в Back 5.1.1, а порядок расчета — в Back 4.2.Бизнес1Частично
OQ2.7-1
S1: BR2.7-2Каждая скидка должна относиться к одному поддерживаемому виду скидки.Поддерживаемые виды:
- акция
- промокод
- горящее предложение
- скидка баллами
- скидка на погашение сборов

Скидки на оплату тарифов относятся к Back 8.3.
Бизнес1Частично
OQ2.7-2
S2: BR2.7-3Система должна поддерживать создание и изменение скидок с учетом правил выбранного вида скидки.Состав параметров и ограничения операций определяются в дочерних разделах 2.7.1-2.7.4.Системное1Реализовано
OQ2.7-4, OQ2.7-6
S2: BR2.7-4Система должна поддерживать архивацию и восстановление скидок.Системное1Частично
OQ2.7-3, OQ2.7-5, OQ2.7-7

5. Открытые вопросы

Сверка с кодом: BRD 2.7 v0.1 · репозиторий booking-monorepo · commit 83423b21 / main · 26.07.26 · якорь src/services/booking.discounts Сводка: 7 вопросов (Open 5 · Подтверждено 2) Маршрутизация без сверки с гайдбуком (гайдбук не передавался).

IDИсточникВопросКомуСтатусРекомендацииИтоговое решение
OQ2.7-1Код BR2.7-1Требование говорит: скидка хранится как отдельная сущность, которая уменьшает стоимость объекта оплаты. В коде единой сущности «Скидка» нет: есть три независимые сущности со своими таблицами и своим набором полей — акция, промокод и горящее предложение. Общего родителя, общего идентификатора и общего списка «все скидки заказа» не существует; то, что в расчёте выглядит как единый список скидок, собирается на лету из трёх разных запросов. Понятия «объект оплаты» в сервисе скидок тоже нет: скидка привязана к заказу и всегда разложена на две составляющие — «на время» и «на позиции», каждая со своей суммой или процентом. \ AutoDiscountAggregate.cs:28, ManualDiscountAggregate.cs, HotDiscountAggregate.cs (три сущности); GetDiscountsForOrderMultiQuery.cs:103, :168-175, :277-284 (сборка списка из трёх источников); AutoDiscountAggregate.cs:33-34 (две составляющие скидки)БизнесOpen(А) Признать текущую модель целевой (рекоменд.) и переписать BR2.7-1 в терминах кода: скидка — не одна сущность, а семейство видов, и уменьшает она не «объект оплаты», а две составляющие заказа — время и позиции. Тогда же стоит внести в BRD вторую ось классификации «на время / на позиции»: она есть в коде, влияет на расчёт и сейчас в документе не описана вовсе. (Б) Настаивать на единой сущности — это крупная переработка сервиса скидок, оправданная только если планируются общие операции над всеми видами скидок сразу.
OQ2.7-2Код BR2.7-2Требование говорит: каждая скидка относится к одному из пяти видов — акция, промокод, горящее предложение, скидка баллами, скидка на погашение сборов. В коде видов три: ручная (промокод), автоматическая (акция) и горячая (горящее предложение). Скидок баллами и скидок на погашение сборов в сервисе скидок нет вообще — баллы и сборы живут отдельными сущностями в сервисе клиентов и скидками не считаются: у них своя модель, свои операции и своя история начислений. Кроме того, «вид» — это не поле сущности: он существует только как признак в ответе расчёта, а при хранении вид определяется тем, в какой таблице лежит запись. \ DiscountType.cs:9-22 (три значения); booking.clients/…/PointsAggregate/, …/ForfeitAggregate/ (баллы и сборы вне скидок); признак вида проставляется только при чтении — DiscountCalculationReadRepository.cs:106, :260БизнесOpen(А) Привести BRD к коду (рекоменд.): описать в BR2.7-2 три вида скидок, а баллы и сборы вынести из перечня видов, оставив ссылки на их разделы (2.7.3, 2.7.4) как на смежные механизмы уменьшения суммы к оплате. (Б) Оставить пятивидовую модель как целевую — тогда нужно решение, планируется ли переносить баллы и сборы в сервис скидок; без этого дочерние разделы 2.7.3 и 2.7.4 будут сверяться против чужого сервиса, а требование останется нереализуемым в текущей архитектуре. Вопрос стоит закрыть до сверки 2.7.3.
OQ2.7-3Код BR2.7-4Требование говорит: система поддерживает архивацию и восстановление скидок. В коде это верно для акций и промокодов, а у горящих предложений восстановления нет: изменение принимает только перевод в архив, обратный перевод не предусмотрен. Причина в том, что у горящих предложений архив означает не «скрыто», а «уже использовано»: при применении к заказу предложение само становится архивным, и снять этот признак можно только отменой использования. Дополнительно архивация горящего предложения — единственная из трёх, которая не публикует событие, поэтому смежные сервисы о ней не узнают. \ HotDiscountAggregate.cs:109-112 (только перевод в архив), :30 (комментарий «архивное = использовано»), :116-131 (применение архивирует), :133-144 (снятие использования — единственный путь назад), :146-151 (архивация без события) против AutoDiscountAggregate.cs:172-183 и ManualDiscountAggregate.cs:156-160, :282-286РазработкаOpenЗавести тикет в Bitrix: развести у горящих предложений два разных смысла признака архивности — «использовано» и «убрано партнёром» — либо явно задокументировать, что к горящим предложениям BR2.7-4 не применяется. Отдельным пунктом — публиковать событие при архивации, как у остальных видов. Продуктового выбора здесь нет, но перед правкой стоит уточнить у бизнеса, нужна ли партнёру возможность убрать горящее предложение вручную (см. 2.7.2).
OQ2.7-4Код BR2.7-3Проблема: создание акции с пустой областью действия (не выбран ни объект, ни площадка) завершается технической ошибкой вместо понятного отказа. Доменный метод создания в этом случае возвращает «ничего», обработчик этого не проверяет и сразу обращается к результату — получается обращение к пустой ссылке, транзакция откатывается, а наружу уходит системная ошибка без объяснения причины. \ AutoDiscountAggregate.cs:398-399 (возврат «ничего» при пустой области), CreateAutoDiscountCommandHandler.cs:79-106 (результат не проверяется)РазработкаOpenЗавести тикет в Bitrix: проверять результат создания и возвращать понятную ошибку «не выбран объект или площадка». Продуктового выбора нет. Заодно проверить симметричный путь у промокодов и горящих предложений — там проверка области действия устроена иначе.
OQ2.7-5Код вне BRDЧто нашли: кроме архивации, у акций и промокодов есть физическое удаление — запись стирается из базы. Оно разрешено только если скидкой ещё ни разу не воспользовались; при попытке удалить использованную скидку возвращается отказ «Нельзя удалить скидку». В BRD такой операции нет: BR2.7-4 описывает только архивацию и восстановление. У горящих предложений удаления нет. \ DeleteAutoDiscountCommandHandler.cs:43-51, DeleteManualDiscountCommandHandler.csБизнесOpen(А) Признать удаление целевым (рекоменд.) и внести его в BR2.7-4 вместе с условием «только для неиспользованных скидок» — поведение осмысленное: ошибочно заведённую скидку логично удалить, а не хранить в архиве. (Б) Если удаление нежелательно (например, ради полноты аудита), ставить задачу на его отключение. Заодно уточните, нужно ли удаление у горящих предложений — сейчас их поведение отличается от остальных видов без описанной причины.
OQ2.7-6Код BR2.7-3Что подтверждено: создание и изменение реализованы отдельно для каждого вида скидки, с учётом его правил. У акций при создании проверяется уникальность названия в партнёрской зоне и отсутствие пересечения с уже заведёнными скидками (по датам, времени, клиентам, позициям и области действия). У промокодов три отдельных пути создания — из кабинета партнёра, из сервисного кабинета и внутренний. У горящих предложений изменение запрещено после использования. \ CreateAutoDiscountCommandHandler.cs:52-77, CreateManualDiscountCommandHandler.cs (три варианта: LK / Service / Internal), HotDiscountAggregate.cs:91-94ПодтвержденоРасхождения нет.
OQ2.7-7Код BR2.7-4Что подтверждено: у акций и промокодов архивация и восстановление реализованы полностью — обе операции меняют признак архивности, фиксируют, кто и когда изменил запись, и публикуют события для смежных сервисов; управлять ими можно через обычное изменение скидки. \ AutoDiscountAggregate.cs:172-183 и :362-369, ManualDiscountAggregate.cs:156-160, :282-286, :385ПодтвержденоРасхождения нет.

Подстраницы