Add thousand separators to all CRM price and amount inputs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-05 02:13:39 +03:30
co-authored by Cursor
parent 36e47e8af3
commit 20a9ac0d34
9 changed files with 239 additions and 25 deletions
+65
View File
@@ -39,3 +39,68 @@ export function formatCompactMoney(amount: number, currency = 'IRR'): string {
}
return formatMoney(amount, currency);
}
const PERSIAN_DIGITS = '۰۱۲۳۴۵۶۷۸۹';
const ARABIC_DIGITS = '٠١٢٣٤٥٦٧٨٩';
/** تبدیل ارقام فارسی/عربی به لاتین */
export function normalizeDigits(raw: string): string {
return raw.replace(/[۰-۹٠-٩]/g, (ch) => {
const p = PERSIAN_DIGITS.indexOf(ch);
if (p >= 0) return String(p);
return String(ARABIC_DIGITS.indexOf(ch));
});
}
/** نمایش عدد با جداکنندهٔ هزارگان (fa-IR) برای فیلدهای ورودی */
export function formatGroupedInput(value: number, maxFractionDigits = 2): string {
if (!Number.isFinite(value)) return '';
return new Intl.NumberFormat('fa-IR', {
maximumFractionDigits: maxFractionDigits,
minimumFractionDigits: 0,
}).format(value);
}
/**
* پارس متن ورودی مبلغ/قیمت.
* جداکننده‌ها و ارقام فارسی را می‌پذیرد و مقدار عددی برمی‌گرداند.
*/
export function parseMoneyNumber(raw: string, maxFractionDigits = 2): number | null {
const cleaned = normalizeDigits(raw)
.replace(/[٬,،\s]/g, '')
.replace(/٫/g, '.')
.replace(/[^\d.-]/g, '');
if (!cleaned || cleaned === '-' || cleaned === '.' || cleaned === '-.') return null;
const n = Number(cleaned);
if (!Number.isFinite(n)) return null;
if (maxFractionDigits <= 0) return Math.round(n);
const factor = 10 ** maxFractionDigits;
return Math.round(n * factor) / factor;
}
/** رشتهٔ خام بدون جداکننده برای v-modelهای متنی فرم‌ها */
export function parseMoneyToRawString(raw: string, maxFractionDigits = 2): string {
const n = parseMoneyNumber(raw, maxFractionDigits);
return n == null ? '' : String(n);
}
export function countDigitChars(value: string): number {
return normalizeDigits(value).replace(/\D/g, '').length;
}
/** موقعیت کرسر را بر اساس تعداد ارقام قبل از کرسر حفظ می‌کند */
export function caretIndexForDigitCount(formatted: string, digitCount: number): number {
if (digitCount <= 0) return 0;
let seen = 0;
const normalized = normalizeDigits(formatted);
for (let i = 0; i < normalized.length; i++) {
if (/\d/.test(normalized[i]!)) {
seen += 1;
if (seen >= digitCount) return i + 1;
}
}
return formatted.length;
}