import { getBasicFeeFromScale } from '@/sql' import { addNumbers, roundTo, toDecimal } from '@/lib/decimal' import { toFiniteNumberOrNull } from '@/lib/number' type ScaleMode = 'cost' | 'area' export interface ScaleFeeSplitResult { basic: number optional: number total: number basicFormula: string optionalFormula: string } export const getBenchmarkBudgetSplitByScale = ( value: unknown, mode: ScaleMode ): ScaleFeeSplitResult | null => { const scaleValue = toFiniteNumberOrNull(value) const result = getBasicFeeFromScale(scaleValue, mode) if (!result) return null const basic = roundTo(result.basic, 2) const optional = roundTo(result.optional, 2) const basicFormula = typeof result.basicFormula === 'string' ? result.basicFormula : '' const optionalFormula = typeof result.optionalFormula === 'string' ? result.optionalFormula : '' return { basic, optional, total: roundTo(addNumbers(basic, optional), 2), basicFormula, optionalFormula } } export const getBenchmarkBudgetByScale = (value: unknown, mode: ScaleMode) => { const splitResult = getBenchmarkBudgetSplitByScale(value, mode) return splitResult ? splitResult.total : null } export const getScaleBudgetFeeSplit = (params: { benchmarkBudgetBasic: unknown benchmarkBudgetOptional: unknown majorFactor: unknown consultCategoryFactor: unknown workStageFactor?: unknown workRatio?: unknown }): ScaleFeeSplitResult | null => { const hasWorkStageFactor = Object.prototype.hasOwnProperty.call(params, 'workStageFactor') const hasWorkRatio = Object.prototype.hasOwnProperty.call(params, 'workRatio') const benchmarkBudgetBasic = toFiniteNumberOrNull(params.benchmarkBudgetBasic) const benchmarkBudgetOptional = toFiniteNumberOrNull(params.benchmarkBudgetOptional) const majorFactor = toFiniteNumberOrNull(params.majorFactor) const consultCategoryFactor = toFiniteNumberOrNull(params.consultCategoryFactor) const workStageFactor = hasWorkStageFactor ? toFiniteNumberOrNull(params.workStageFactor) : 1 const workRatio = hasWorkRatio ? toFiniteNumberOrNull(params.workRatio) : 100 if ( benchmarkBudgetBasic == null || benchmarkBudgetOptional == null || majorFactor == null || consultCategoryFactor == null || workStageFactor == null || workRatio == null ) { return null } const multiplier = toDecimal(consultCategoryFactor) .mul(majorFactor) .mul(workStageFactor) .mul(workRatio) .div(100) const roundedBenchmarkBudget = roundTo(addNumbers(benchmarkBudgetBasic, benchmarkBudgetOptional), 2) const basic = roundTo(toDecimal(benchmarkBudgetBasic).mul(multiplier), 2) const optional = roundTo(toDecimal(benchmarkBudgetOptional).mul(multiplier), 2) return { basic, optional, total: roundTo(toDecimal(roundedBenchmarkBudget).mul(multiplier), 2), basicFormula: '', optionalFormula: '' } } export const getScaleBudgetFee = (params: { benchmarkBudget: unknown majorFactor: unknown consultCategoryFactor: unknown workStageFactor?: unknown workRatio?: unknown }) => { const hasWorkStageFactor = Object.prototype.hasOwnProperty.call(params, 'workStageFactor') const hasWorkRatio = Object.prototype.hasOwnProperty.call(params, 'workRatio') const benchmarkBudget = toFiniteNumberOrNull(params.benchmarkBudget) const majorFactor = toFiniteNumberOrNull(params.majorFactor) const consultCategoryFactor = toFiniteNumberOrNull(params.consultCategoryFactor) const workStageFactor = hasWorkStageFactor ? toFiniteNumberOrNull(params.workStageFactor) : 1 const workRatio = hasWorkRatio ? toFiniteNumberOrNull(params.workRatio) : 100 if ( benchmarkBudget == null || majorFactor == null || consultCategoryFactor == null || workStageFactor == null || workRatio == null ) { return null } const roundedBenchmarkBudget = roundTo(benchmarkBudget, 2) const multiplier = toDecimal(consultCategoryFactor) .mul(majorFactor) .mul(workStageFactor) .mul(workRatio) .div(100) return roundTo(toDecimal(roundedBenchmarkBudget).mul(multiplier), 2) }