Files
portal/app/resources/js/utils/pricingTiers.ts
T
Дмитрий a7a4e7356a fix(admin): клиентский диапазон ступеней в тарифной сетке + живой предпросмотр в редакторе
Админка показывала сырую ширину ступени (leads_in_tier: 250/500/1000...),
а кабинет клиента — накопительный диапазон (1-250, 251-750...). Одни и те же
данные, но выглядят как разные тарифы; в форме редактирования подпись
'Лидов в ступени' читается как потолок, а система понимает её как ширину -
ловушка при смене цен.

Логика денег не менялась. Изменён только показ в админке:
- колонка 'Диапазон у клиента' в активной сетке;
- живой предпросмотр диапазона в форме редактирования;
- расчёт диапазона вынесен в общий utils/pricingTiers.ts, чтобы админка
  и кабинет больше не расходились.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 15:10:08 +03:00

34 lines
1.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Единый источник истины для показа объёмных ступеней тарифа.
*
* В БД у каждой ступени хранится ШИРИНА (`leads_in_tier`) — сколько лидов
* помещается именно в эту ступень, а НЕ «до какого лида она действует».
* Живой расчёт списаний (PricingTierResolver / BalanceToLeadsConverter)
* накапливает эти ширины: tier 1 = 1..w1, tier 2 = w1+1..w1+w2, и т.д.
*
* Эта функция переводит ширину в тот накопительный диапазон, который видит
* клиент в кабинете. Держим её в ОДНОМ месте, чтобы админка и кабинет никогда
* не разошлись в цифрах.
*/
export interface TierWidth {
leads_in_tier: number | null;
}
/**
* Диапазон номеров лидов для ступени с индексом `idx` (0-based) в массиве
* ступеней, отсортированном по возрастанию tier_no.
*
* Пример (ширины 250/500/…): idx=0 → «1250», idx=1 → «251750».
* Последняя ступень (`leads_in_tier === null`) → «19251+».
*/
export function tierRangeText(tiers: ReadonlyArray<TierWidth>, idx: number): string {
let start = 1;
for (let i = 0; i < idx; i++) {
const cap = tiers[i].leads_in_tier;
if (cap !== null) start += cap;
}
const cap = tiers[idx].leads_in_tier;
if (cap === null) return `${start}+`;
return `${start}${start + cap - 1}`;
}