Files
portal/app/resources/js/composables/billingFormatters.ts
T
Дмитрий 0ef093f7c5 fix(billing): InvoicesTable has_pdf disabled test + formatter doc (Task 4 review)
Code-quality review fixups: тест на :disabled PDF-кнопки по has_pdf
(spec-mandated поведение без покрытия); doc-комментарий billingFormatters
дополнен InvoicesTable в списке потребителей.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 08:07:57 +03:00

43 lines
1.8 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.
/**
* Форматтеры биллинга — BillingView + TransactionsTable + InvoicesTable.
*
* Sprint 2 Plan C: status/format-функции (statusChipColor/statusLabel/
* formatLabel/formatIcon) удалены — real-API транзакции не имеют статуса
* (append-only ledger), счета — отдельный формат. txAmountClass
* перетипизирован под знак суммы.
*/
/** «5000» → «5 000 ₽» (без знака). */
export function formatPlain(cost: number): string {
return new Intl.NumberFormat('ru-RU').format(cost) + ' ₽';
}
/** Знаковый формат: «+ 5 000 ₽» / «− 6 600 ₽» / «0 ₽». */
export function formatCost(cost: number): string {
const sign = cost > 0 ? '+ ' : cost < 0 ? ' ' : '';
return sign + new Intl.NumberFormat('ru-RU').format(Math.abs(cost)) + ' ₽';
}
/** CSS-класс суммы транзакции по знаку. */
export function txAmountClass(amount: number): string {
if (amount > 0) return 'tx-amount-up';
if (amount < 0) return 'tx-amount-down';
return 'tx-amount-neutral';
}
/** Человекочитаемые лейблы для feature-слагов tariff_plans.features. */
export const FEATURE_LABELS: Record<string, string> = {
webhook: 'Webhook',
kanban: 'Канбан',
basic_analytics: 'Базовая аналитика',
advanced_analytics: 'Расширенная аналитика',
api: 'API',
'2fa': 'Двухфакторная аутентификация',
custom_domain: 'Свой домен',
};
/** Лейбл feature-слага; неизвестный слаг возвращается как есть. */
export function featureLabel(slug: string): string {
return FEATURE_LABELS[slug] ?? slug;
}