Направление работ: Back Код раздела: 2.7.2 Объекты и предложения > Скидки > Горящие предложения Статус: черновик Ответственный: Панкова Л.А. Версия: 0.1 Обновлено: 20.07.26
1. Назначение
Горящее предложение позволяет партнеру продать незанятый интервал площадки или услуги по сниженной цене.
Скидка применяется только к заказу, начало и окончание которого полностью совпадают с интервалом горящего предложения.
2. Ключевые понятия
Горящее предложение — скидка на конкретный незанятый временной интервал площадки или услуги.
Временной интервал — точные дата и время начала и окончания действия горящего предложения.
Стоимость времени — стоимость бронирования выбранного интервала до применения скидки.
3. Scope
Входит
S1 Горящие предложения: сущность и правило применения к заказу.
S2 Параметры и данные: площадки или услуги, интервал, размер скидки, опции и автор записи.
S3 Валидация и ограничения: обязательные поля, сроки создания, длительность действия и минимальная скидка.
Не входит
- Back 2.7 Скидки — общая модель скидок и операции над ними
- Back 2.7.1 Акции и промокоды — автоматические и ручные скидки на заказы
- Back 2.7.3 Скидки баллами — правила оплаты заказа М-баллами
- Back 2.2 Площадки партнеров — управление площадками и услугами
- Back 8.2.1 Сферы и опции — управление справочником опций и их диапазонами
- Back 3.2 Процессинг заказов — создание и обработка заказа
- Back 4.2 Стоимость заказа и позиций — расчет стоимости заказа и применение скидки
4. Требования
Правила и ограничения бизнеса на уровне данных, источник истины в системе.
| ID | Требование | Комментарий | Тип требования | Вес | Статус |
|---|---|---|---|---|---|
| S1: BR2.7.2-1 | Горящее предложение должно задавать скидку на конкретный незанятый интервал площадки или услуги. | Предложение создается партнером для продажи остатка незанятого времени по сниженной стоимости. | Бизнес | 1 | Частично OQ2.7.2-6 |
| S1: BR2.7.2-2 | Горящее предложение должно применяться только к заказу с полным совпадением начала и окончания заказа с его временным интервалом. | Частичное пересечение заказа с интервалом не активирует скидку. | Бизнес | 1 | Частично OQ2.7.2-5 |
| S2: BR2.7.2-3 | Горящее предложение должно хранить данные, необходимые для определения области и условий применения. | Состав данных: - название - площадки или услуги - размер скидки в процентах или рублях - точный временной интервал - опции и диапазоны опций - аккаунт, создавший предложение | Системное | 1 | Частично OQ2.7.2-1, OQ2.7.2-2 |
| S2: BR2.7.2-4 | Горящее предложение должно применяться ко всем опциям и диапазонам опций, если конкретные ограничения не заданы. | Опции берутся из Back 8.2.1. | Бизнес | 2 | Не реализовано OQ2.7.2-3 |
| S3: BR2.7.2-5 | Для горящего предложения обязательно должны быть заданы хотя бы одна площадка или услуга и один точный временной интервал. | Системное | 1 | Реализовано OQ2.7.2-11 | |
| S3: BR2.7.2-6 | Для одной площадки может храниться только одно горящее предложение. | Системное | 1 | Не реализовано OQ2.7.2-4 | |
| S3: BR2.7.2-7 | Горящее предложение может быть создано не ранее чем за 24 часа до начала его временного интервала. | Бизнес | 2 | Частично OQ2.7.2-7 | |
| S3: BR2.7.2-8 | Горящее предложение должно действовать только в пределах одних календарных суток. | Системное | 1 | Реализовано OQ2.7.2-10 | |
| S3: BR2.7.2-9 | Для горящего предложения может быть задан только один временной интервал. | Системное | 1 | Реализовано OQ2.7.2-10 | |
| S3: BR2.7.2-10 | Для горящего предложения должен быть задан ровно один способ расчета скидки: процент или сумма в рублях. | Размер скидки должен составлять не менее 30% от стоимости выбранного времени; для суммы в рублях система проверяет ее отношение к стоимости времени. | Системное | 1 | Частично OQ2.7.2-1 |
5. Открытые вопросы
Сверка с кодом: BRD 2.7.2 v0.1 · репозиторий
booking-monorepo· commit83423b21/main· 26.07.26 · якорьsrc/services/booking.discountsСводка: 11 вопросов (Open 9 · Подтверждено 2) Маршрутизация без сверки с гайдбуком (гайдбук не передавался).
| ID | Источник | Вопрос | Кому | Статус | Рекомендации | Итоговое решение |
|---|---|---|---|---|---|---|
| OQ2.7.2-1 | Код BR2.7.2-3, BR2.7.2-10 | Требование говорит: размер скидки горящего предложения задаётся в процентах или в рублях, ровно одним способом, и составляет не менее 30% от стоимости времени. В коде размер вообще не задаётся: при создании он жёстко проставляется в самом коде — всегда 50% и всегда процентом. Ни партнёр, ни сервисный кабинет повлиять на него не могут: в параметрах создания поля размера нет. Формально требование «ровно один способ» и порог 30% при этом не нарушаются (50% — процент, больше 30%), но выполняются они случайно, а не потому, что система это проверяет: изменить константу в коде — и никакая проверка не сработает. \ HotDiscountAggregate.cs:67 (жёстко заданные 50%), CreateHotDiscountCommand.cs (поля размера нет), AmountOrPercent.cs:11-18 (значение хранится без проверок) | Бизнес | Open | (А) Подтвердить требование (рекоменд.): размер должен настраиваться партнёром — тогда это доработка, и вместе с ней нужна проверка порога, для рублей — в отношении к стоимости времени (см. формулировку BR2.7.2-10, её придётся уточнить: как именно система узнаёт стоимость времени на момент создания предложения). (Б) Признать фиксированные 50% продуктовым решением — тогда переписать BR2.7.2-3 и BR2.7.2-10: размер не настраивается, он всегда равен 50%. Второй вариант ближе к текущему коду и заметно дешевле, но лишает партнёра управления скидкой. | |
| OQ2.7.2-2 | Код BR2.7.2-3 | Требование говорит: горящее предложение хранит название, а его область действия задаётся площадками или услугами. В коде названия у горящего предложения нет вовсе — ни поля, ни параметра при создании; в списках оно опознаётся по площадке, дате и времени. Услуг в области действия тоже нет: предложение привязано к одной площадке (и объекту, которому она принадлежит). Остальной состав данных из BR2.7.2-3 на месте: интервал, опции и автор записи хранятся. \ HotDiscountAggregate.cs:20-32 (состав полей — названия нет), CreateHotDiscountCommand.cs (параметра нет); нехватка услуг — та же, что в OQ2.7.1-6 | Бизнес | Open | (А) Подтвердить требование — тогда доработка: добавить название (нужно решить, обязательное ли оно и что показывать в интерфейсах сейчас). (Б) Снять название из BR2.7.2-3 (рекоменд., если партнёру достаточно опознавать предложение по площадке и времени) — горящее предложение живёт несколько часов, и отдельное имя для него может быть лишним. Услуги решать отдельно и вместе с OQ2.7.1-6: это общее свойство модели области действия. | |
| OQ2.7.2-3 | Код BR2.7.2-4 | Требование говорит: горящее предложение применяется ко всем опциям и диапазонам опций, если конкретные ограничения не заданы. В коде опции у предложения хранятся, но при подборе не проверяются вообще: запрос, который ищет действующее горящее предложение для заказа, фильтрует только по площадке, дате, архивности и признаку «уже использовано» — условия по опции в нём нет. У акций и промокодов такой фильтр есть, у горящих предложений — нет. Практически: предложение применится к заказу с любой опцией, даже если партнёр ограничил его конкретной. \ DiscountCalculationReadRepository.cs:277-283 (фильтр без опций) против :424-427 (как это сделано у акций); хранение опций — HotDiscountAggregate.cs:28-29 | Разработка | Open | Завести тикет в Bitrix: добавить условие по опции и диапазону в подбор горящего предложения — по образцу акций. Продуктового выбора нет: BR2.7.2-4 однозначен, поле уже настраивается и сейчас молча не работает. | |
| OQ2.7.2-4 | Код BR2.7.2-6 | Требование говорит: для одной площадки может храниться только одно горящее предложение. В коде ограничения нет: создание просто вставляет новую запись, не проверяя, есть ли у площадки уже действующее предложение. При подборе берётся первое попавшееся подходящее предложение — без сортировки и без правила выбора, — поэтому если предложений несколько, применится произвольное, а остальные будут молча игнорироваться. Ни ошибки, ни предупреждения партнёр не увидит. \ HotDiscountRepository.cs:39-45 (вставка без проверки), DiscountCalculationReadRepository.cs:277-283 (выбор первого попавшегося) | Разработка | Open | Завести тикет в Bitrix: запрещать создание второго активного горящего предложения для площадки (проверка при создании плюс, желательно, ограничение в базе — иначе параллельные запросы обойдут проверку). Продуктового выбора нет: BR2.7.2-6 однозначен. Уточнить у бизнеса стоит одно: ограничение действует на «одну площадку вообще» или «одну площадку в один день» — сейчас предложения существуют только на сегодня (см. OQ2.7.2-7). | |
| OQ2.7.2-5 | Код BR2.7.2-2 | Требование говорит: скидка применяется только к заказу, начало и окончание которого полностью совпадают с интервалом предложения; частичное пересечение скидку не активирует. В коде правило другое: предложение применяется, если заказ покрывает его интервал — то есть начинается не позже и заканчивается не раньше. Заказ на 10:00–14:00 активирует предложение на 11:00–12:00, и скидка при этом даётся только на час 11:00–12:00, а не на весь заказ. Частичное пересечение (заказ 11:30–12:30 при предложении 11:00–12:00) скидку действительно не активирует — эта часть требования соблюдена. \ GetDiscountsForOrderMultiQuery.cs:97-104 (условие «заказ покрывает интервал» и скидка на интервал предложения) | Бизнес | Open | (А) Признать поведение целевым (рекоменд.) и переписать BR2.7.2-2: предложение активируется заказом, который полностью включает его интервал, а скидка действует только на этот интервал. Так партнёр продаёт «дыру» в расписании даже клиенту, который берёт время с запасом, — это выгоднее, чем требовать точного совпадения. (Б) Ужесточить код до полного совпадения — тогда часть заказов перестанет получать скидку, и стоит заранее оценить, много ли таких. | |
| OQ2.7.2-6 | Код BR2.7.2-1 | Требование говорит: горящее предложение задаёт скидку на конкретный незанятый интервал площадки. В коде незанятость интервала при создании не проверяется: сервис скидок не обращается к заказам и не знает, свободно ли это время. Предложение можно завести на интервал, который уже забронирован; сработает оно, впрочем, только если появится заказ, покрывающий этот интервал. \ CreateHotDiscountCommandHandler.cs:43-76 (проверяются только существование площадки и права), обращений к сервису заказов в команде нет | Бизнес | Open | (А) Признать текущее поведение достаточным (рекоменд.): «незанятый интервал» — это сценарий использования, а не проверяемое правило; тогда в BR2.7.2-1 стоит убрать слово «незанятый» из нормативной части и оставить его в описании назначения. (Б) Если проверка нужна, это межсервисная доработка (обращение к заказам при создании), и её цена заметно выше пользы: интервал может стать занятым сразу после проверки, поэтому гарантии она всё равно не даст. | |
| OQ2.7.2-7 | Код BR2.7.2-7 | Требование говорит: горящее предложение может быть создано не ранее чем за 24 часа до начала его интервала. В коде ограничение получается более жёстким и другим по сути: дата предложения не задаётся вообще — при создании подставляется текущая дата, а подбор ищет предложения только на сегодня. То есть предложение всегда «на сегодня», создать его на завтра нельзя ни за 24 часа, ни за час. Правило «не ранее чем за 24 часа» при этом нигде не проверяется — оно просто недостижимо. \ HotDiscountAggregate.cs:71 (дата = сегодня), DiscountCalculationReadRepository.cs:280 (подбор только на сегодня) | Бизнес | Open | (А) Привести BRD к коду (рекоменд.): горящее предложение создаётся только на текущие сутки — это и проще для партнёра, и соответствует смыслу «горящего». Тогда BR2.7.2-7 заменяется правилом «только на сегодня», а BR2.7.2-8 становится его следствием. (Б) Если нужна возможность заводить предложение заранее (например, вечером на утро), это доработка: добавить дату в параметры создания, проверку «не ранее чем за 24 часа» и научить подбор смотреть не только на сегодня. | |
| OQ2.7.2-8 | Код вне BRD | Что нашли: горящее предложение вытесняет промокод на пересекающемся времени. При расчёте интервалы промокода обрезаются по окну горящего предложения, и если после обрезки от промокода ничего не остаётся, клиент получает отказ с текстом «Невозможно применить промокод: на это время уже действует горячая скидка». Приоритет горящего предложения над промокодом в BRD 2.7.2 не описан; в разделе про расчёт стоимости (Back 4.2) его тоже стоит проверить. \ GetDiscountsForOrderMultiQuery.cs:156-161 (обрезка), :203-208 (текст отказа), :319-331 (сама обрезка) | Бизнес | Open | (А) Признать приоритет целевым (рекоменд.) и описать его — но не здесь, а в Back 4.2, где живут правила совместного применения скидок; в 2.7.2 достаточно ссылки. (Б) Если скидки должны складываться или выбираться по максимуму — это доработка расчёта. Отдельно проверьте формулировку отказа: клиенту сообщают, что промокод не применился, но не говорят, что вместо него действует более выгодная горящая скидка. | |
| OQ2.7.2-9 | Код вне BRD | Проблема: у горящего предложения нет ни одной проверки корректности интервала. Время «с» и «по» сохраняются как есть — можно завести предложение, где окончание раньше начала или совпадает с началом; такое предложение никогда не сработает, но будет храниться и показываться. Проверок на пересечение с уже существующими предложениями той же площадки тоже нет (см. OQ2.7.2-4). \ HotDiscountAggregate.cs:59-83 (создание без проверок интервала), :97-99 (изменение — так же) | Разработка | Open | Завести тикет в Bitrix: проверять при сохранении, что окончание интервала строго позже начала. Продуктового выбора нет. Правку логично делать одним тикетом с OQ2.7.2-4 — обе про валидацию при создании горящего предложения. | |
| OQ2.7.2-10 | Код BR2.7.2-8, BR2.7.2-9 | Что подтверждено: горящее предложение по устройству модели не может выйти за одни календарные сутки и не может иметь больше одного интервала: у него хранится ровно одна дата и ровно одна пара «время с — время по», списка интервалов не предусмотрено. Подбор тоже работает в пределах одного дня. \ HotDiscountAggregate.cs:20-21 (одна дата и один интервал), DiscountCalculationReadRepository.cs:280 (подбор в пределах дня) | — | Подтверждено | Расхождения нет. | — |
| OQ2.7.2-11 | Код BR2.7.2-5 | Что подтверждено: площадка и интервал обязательны — оба передаются при создании как обязательные параметры, а существование площадки дополнительно проверяется через иерархию партнёрской зоны: если площадка не найдена, создание отклоняется с ошибкой «Площадка не найдена». Права на создание проверяются по той же площадке. \ CreateHotDiscountCommandHandler.cs:49-68 | — | Подтверждено | Расхождения нет. | — |