93 lines
2.6 KiB
TypeScript
93 lines
2.6 KiB
TypeScript
const PERSIAN_DIGITS = '۰۱۲۳۴۵۶۷۸۹'
|
||
|
||
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.replace(/\d/g, (d) => PERSIAN_DIGITS[Number(d)] ?? d)
|
||
}
|
||
|
||
export function usePrice(price: number, digit = true, unit = 'ریال') {
|
||
price = price ?? 0
|
||
const formatted = formatGroupedPrice(price, digit)
|
||
return `${formatted} ${unit}`
|
||
}
|
||
|
||
export function usePriceWithoutType(price?: number, digit = true) {
|
||
return formatGroupedPrice(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
|
||
} | null
|
||
}
|
||
|
||
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 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 '۰'
|
||
return formatGroupedPrice(Number(num.toFixed(3)), false)
|
||
}
|