1
This commit is contained in:
1 parent
62546bc937
commit
33913c29d2
9 files changed
+1153
-239
No files matched your search
@@ -22,6 +22,7 @@ interface WorkloadRow {
|
||||
id: string
|
||||
conversion: number | null
|
||||
workload: number | null
|
||||
basicFee: number | null
|
||||
budgetAdoptedUnitPrice: number | null
|
||||
consultCategoryFactor: number | null
|
||||
}
|
||||
@@ -159,6 +160,7 @@ const buildDefaultWorkloadRows = (serviceId: string | number): WorkloadRow[] =>
|
||||
id: `task-${taskId}-${order}`,
|
||||
conversion: toFiniteNumberOrNull(task.conversion),
|
||||
workload: null,
|
||||
basicFee: null,
|
||||
budgetAdoptedUnitPrice: toFiniteNumberOrNull(task.defPrice),
|
||||
consultCategoryFactor: defaultConsultCategoryFactor
|
||||
}))
|
||||
@@ -177,23 +179,35 @@ const mergeWorkloadRows = (
|
||||
return {
|
||||
...row,
|
||||
workload: toFiniteNumberOrNull(fromDb.workload),
|
||||
basicFee: toFiniteNumberOrNull(fromDb.basicFee),
|
||||
budgetAdoptedUnitPrice: toFiniteNumberOrNull(fromDb.budgetAdoptedUnitPrice),
|
||||
consultCategoryFactor: toFiniteNumberOrNull(fromDb.consultCategoryFactor)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const calcWorkloadServiceFee = (row: WorkloadRow) => {
|
||||
const calcWorkloadBasicFee = (row: WorkloadRow) => {
|
||||
if (
|
||||
row.budgetAdoptedUnitPrice == null ||
|
||||
row.conversion == null ||
|
||||
row.workload == null ||
|
||||
row.consultCategoryFactor == null
|
||||
row.workload == null
|
||||
) {
|
||||
return null
|
||||
}
|
||||
return roundTo(
|
||||
toDecimal(row.budgetAdoptedUnitPrice).mul(row.conversion).mul(row.workload).mul(row.consultCategoryFactor),
|
||||
toDecimal(row.budgetAdoptedUnitPrice).mul(row.conversion).mul(row.workload),
|
||||
2
|
||||
)
|
||||
}
|
||||
|
||||
const calcWorkloadServiceFee = (row: WorkloadRow) => {
|
||||
if (row.consultCategoryFactor == null) {
|
||||
return null
|
||||
}
|
||||
const basicFee = row.basicFee ?? calcWorkloadBasicFee(row)
|
||||
if (basicFee == null) return null
|
||||
return roundTo(
|
||||
toDecimal(basicFee).mul(row.consultCategoryFactor),
|
||||
2
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,10 +4,70 @@ import { toFiniteNumberOrNull } from '@/lib/number'
|
||||
|
||||
type ScaleMode = 'cost' | 'area'
|
||||
|
||||
export const getBenchmarkBudgetByScale = (value: unknown, mode: ScaleMode) => {
|
||||
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)
|
||||
return result ? roundTo(addNumbers(result.basic, result.optional), 2) : null
|
||||
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
|
||||
}): ScaleFeeSplitResult | null => {
|
||||
const benchmarkBudgetBasic = toFiniteNumberOrNull(params.benchmarkBudgetBasic)
|
||||
const benchmarkBudgetOptional = toFiniteNumberOrNull(params.benchmarkBudgetOptional)
|
||||
const majorFactor = toFiniteNumberOrNull(params.majorFactor)
|
||||
const consultCategoryFactor = toFiniteNumberOrNull(params.consultCategoryFactor)
|
||||
|
||||
if (
|
||||
benchmarkBudgetBasic == null ||
|
||||
benchmarkBudgetOptional == null ||
|
||||
majorFactor == null ||
|
||||
consultCategoryFactor == null
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
const basic = roundTo(toDecimal(benchmarkBudgetBasic).mul(majorFactor).mul(consultCategoryFactor), 2)
|
||||
const optional = roundTo(toDecimal(benchmarkBudgetOptional).mul(majorFactor).mul(consultCategoryFactor), 2)
|
||||
|
||||
return {
|
||||
basic,
|
||||
optional,
|
||||
total: roundTo(addNumbers(basic, optional), 2),
|
||||
basicFormula: '',
|
||||
optionalFormula: ''
|
||||
}
|
||||
}
|
||||
|
||||
export const getScaleBudgetFee = (params: {
|
||||
|
||||
Reference in new issue
Block a user