Цены и скидки
Цены считает CRM — сайту не нужно повторять правила тарифов, особых дат и скидок. Суммы приходят строками с двумя знаками после точки ("1250.00") в валюте компании (currency). Не переводите их в number для расчётов — округление разойдётся с CRM; для показа форматируйте как есть.
Цена в каталоге: SiteUnit
У каждого объекта в units() и unit() три поля про цену ночи:
| Поле | Что значит |
|---|---|
base_price | цена ночи без скидок — «старая» цена, если есть скидка |
price | цена ночи «от» с учётом скидки, которая действует сегодня без условий; особые даты не учитываются. Нет скидки — равна base_price |
discount | скидка, которая уже вошла в price, или null |
discount — объект SiteDiscount:
| Поле | Что значит |
|---|---|
name | название скидки, его можно показать на карточке |
value_type | percent — процент, fixed — сумма за ночь |
value | размер скидки (строка) |
ends_on | последний день действия (YYYY-MM-DD) или null — бессрочно |
Как показать на карточке:
{u.discount ? (
<p>
<s>{u.base_price}</s> <strong>{u.price} {u.currency}</strong>
<span>{u.discount.name}</span>
</p>
) : (
<p>{u.price} {u.currency}</p>
)}Цена в каталоге — ориентир «от». Точную сумму за даты всегда берите из quote() или prices(): в ней учтены особые даты, условия скидок и число ночей.
Цены всех объектов на даты: prices()
prices({ check_in, check_out, guests, group_id }) отвечает списком units — по объекту SitePrice:
| Поле | Что значит |
|---|---|
available | даты свободны и условия выполнены |
subtotal | итог до скидок |
total | итог после скидок |
per_night_before | средняя цена ночи до скидок |
per_night | средняя цена ночи после скидок |
violations | почему недоступно (см. ниже) |
Если даты недоступны, суммы — null. Так каталог показывает «2 ночи — 2 400 вместо 2 600» и прячет занятые объекты.
Расчёт для одного объекта: quote()
quote({ unit_id, check_in, check_out, guests }) — тот же расчёт, что видит менеджер в CRM:
| Поле | Что значит |
|---|---|
nights | число ночей |
per_night | список ночей Night: date, base (цена ночи по тарифу), price (цена этой ночи с учётом особой даты), special_name (название особой даты или null) |
discounts | сработавшие скидки AppliedDiscount: name, amount (на сколько уменьшили итог), kind (line — на объект, deal — на всю бронь), application (auto — сработала сама) |
subtotal | итог до скидок |
total | итог к оплате |
available | нет блокирующих нарушений — можно отправлять заявку |
violations | нарушения |
Если даты заняты, ответ всё равно 200, но с available: false и списком violations — это не ошибка, а подсказка для формы.
Нарушения: violations
Каждое нарушение — { code, blocking, params }. При blocking: true заявка не будет принята (422 rental_unavailable), при false это предупреждение.
code | Что показать посетителю |
|---|---|
dates_invalid | даты заданы неверно |
occupied | даты заняты |
blocked | объект закрыт на эти даты |
min_nights | меньше минимального срока; минимум — в params |
max_guests | гостей больше, чем вмещает объект; максимум — в params |
unit_archived | объект больше не сдаётся |
Пересчитывайте quote() при каждом изменении дат и гостей в форме, а total в заявке не передавайте — CRM считает его сама и возвращает в ответе на заявку.