function formatGroupedPrice(price: string | number | null | undefined, digit: boolean) { let value = price === null || price === undefined ? '' : String(price) if (digit) { value = value.replace(/\B(?=(\d{3})+(?!\d))/g, ',') } return value } /** مبلغ ریالی — بدون اعشار، گرد به بالا */ export function ceilRial(price?: number | string | null): number { const num = Number(price ?? 0) if (!Number.isFinite(num)) { return 0 } return Math.ceil(num) } export function formatNumber(value: string | number | null | undefined, grouped = false): string { return formatGroupedPrice(value, grouped) } export function usePrice(price: number, digit = true, unit = 'ریال') { const formatted = formatGroupedPrice(ceilRial(price), digit) return `${formatted} ${unit}` } export function usePriceWithoutType(price?: number, digit = true) { return formatGroupedPrice(ceilRial(price), digit) } export function useTowDecimal(num: string | number): string | number { const temp = num.toString().match(/^-?\d+(?:\.\d{0,2})?/) if (temp && temp.length > 0) return formatGroupedPrice(temp[0], false) return formatGroupedPrice(Math.round(+num * 100) / 100, false) } export function formatSignedPercentChange(value: number): string { if (!value) return '0%' const formatted = useTowDecimal(Math.abs(value)) const prefix = value > 0 ? '+' : '-' return `${prefix}${formatted}%` } export function useFormat(num: string | number, unit = '') { return usePrice(Math.abs(+useTowDecimal(num)), true, unit) } type TransactionPriceSource = { cash?: number | null gold?: number | null order?: { price?: number | null total_price?: number | null amount?: number | null sts?: number | null sts_str?: string | number | null payment_sts?: number | null } | null withdraw?: { sts?: number | null sts_str?: string | number | null } | null order_id?: number | null } const ORDER_STATUS_LABELS: Record = { 1: 'باز', 2: 'موفق', 3: 'ناموفق', } export function getTransactionTradePrice(item: TransactionPriceSource): number { const orderPrice = Number(item.order?.price) if (Number.isFinite(orderPrice) && orderPrice > 0) { return Math.round(orderPrice) } const cashAmount = Math.abs(Number(item.cash) || 0) const goldAmount = Math.abs(Number(item.gold) || 0) || Math.abs(Number(item.order?.amount) || 0) if (goldAmount > 0 && cashAmount > 0) { return Math.round(cashAmount / goldAmount) } const totalPrice = Number(item.order?.total_price) if (Number.isFinite(totalPrice) && totalPrice > 0) { return Math.round(totalPrice) } return 0 } export function resolveTransactionStatusLabel(item?: TransactionPriceSource | null): string { if (!item) return '' const raw = item.order?.sts_str ?? item.withdraw?.sts_str if (typeof raw === 'string') { const trimmed = raw.trim() if (trimmed && trimmed !== 'بدون مقدار') { return trimmed } } if (typeof raw === 'number' || (typeof raw === 'string' && /^\d+$/.test(String(raw).trim()))) { const mapped = ORDER_STATUS_LABELS[Number(raw)] if (mapped) return mapped } const sts = item.order?.sts ?? item.withdraw?.sts if (sts != null && ORDER_STATUS_LABELS[Number(sts)]) { return ORDER_STATUS_LABELS[Number(sts)] } if (item.order_id && Number(item.order?.payment_sts) === 4) { return 'موفق' } return '' } export function getTransactionGoldAmount(item: TransactionPriceSource): number { const gold = Number(item.gold) || 0 if (Math.abs(gold) > 0) { return gold } const orderAmount = Number(item.order?.amount) || 0 if (orderAmount > 0) { const cash = Number(item.cash) || 0 if (cash < 0) return orderAmount if (cash > 0) return -orderAmount return orderAmount } return gold } export function formatGoldAmount(amount?: number | null): string { const num = Number(amount) if (!Number.isFinite(num)) return '0' return formatGroupedPrice(Number(num.toFixed(3)), false) } /** وزن فلز (گرم/کیلو) — بدون گرد کردن به بالا (برخلاف usePriceWithoutType) */ export function formatWeightAmount(amount?: number | null): string { return formatGoldAmount(amount) }