44 lines
1.2 KiB
TypeScript
44 lines
1.2 KiB
TypeScript
import Decimal from 'decimal.js'
|
|
import { isFiniteNumber } from '@/lib/number'
|
|
|
|
type MaybeNumber = number | null | undefined
|
|
type DecimalInput = Decimal.Value
|
|
|
|
export const toDecimal = (value: DecimalInput) => new Decimal(value)
|
|
|
|
export const roundTo = (value: DecimalInput, decimalPlaces = 2) =>
|
|
new Decimal(value).toDecimalPlaces(decimalPlaces, Decimal.ROUND_HALF_UP).toNumber()
|
|
|
|
const sumFiniteValues = (values: Iterable<unknown>) => {
|
|
let total = new Decimal(0)
|
|
for (const value of values) {
|
|
if (!isFiniteNumber(value)) continue
|
|
total = total.plus(value)
|
|
}
|
|
return total.toNumber()
|
|
}
|
|
|
|
export const addNumbers = (...values: MaybeNumber[]) => sumFiniteValues(values)
|
|
|
|
export const sumByNumber = <T>(list: T[], pick: (item: T) => MaybeNumber) => {
|
|
let total = new Decimal(0)
|
|
for (const item of list) {
|
|
const value = pick(item)
|
|
if (!isFiniteNumber(value)) continue
|
|
total = total.plus(value)
|
|
}
|
|
return total.toNumber()
|
|
}
|
|
|
|
export const decimalAggSum = (params: { values?: unknown[] }) => {
|
|
const values = params.values || []
|
|
let hasFinite = false
|
|
for (const value of values) {
|
|
if (!isFiniteNumber(value)) continue
|
|
hasFinite = true
|
|
break
|
|
}
|
|
if (!hasFinite) return null
|
|
return sumFiniteValues(values)
|
|
}
|