fix
This commit is contained in:
1 parent
3d26b0b259
commit
0f71fff9ac
11 files changed
+873
-205
No files matched your search
@@ -25,6 +25,17 @@ interface StoredFactorState {
|
||||
|
||||
type MaybeNumber = number | null | undefined
|
||||
|
||||
const sumByNumberNullable = <T>(list: T[], pick: (item: T) => MaybeNumber): number | null => {
|
||||
let hasValid = false
|
||||
const total = sumByNumber(list, item => {
|
||||
const value = toFiniteNumberOrNull(pick(item))
|
||||
if (value == null) return null
|
||||
hasValid = true
|
||||
return value
|
||||
})
|
||||
return hasValid ? total : null
|
||||
}
|
||||
|
||||
interface ScaleRow {
|
||||
id: string
|
||||
amount: number | null
|
||||
@@ -153,6 +164,17 @@ const toStoredDetailRowsState = <TRow = unknown>(state: { detailRows?: TRow[] }
|
||||
const hasOwn = (obj: unknown, key: string) =>
|
||||
Object.prototype.hasOwnProperty.call(obj || {}, key)
|
||||
|
||||
const getRowNumberOrFallback = (
|
||||
row: Record<string, unknown> | undefined,
|
||||
key: string,
|
||||
fallback: number | null
|
||||
) => {
|
||||
if (!row) return fallback
|
||||
const value = toFiniteNumberOrNull(row[key])
|
||||
if (value != null) return value
|
||||
return hasOwn(row, key) ? null : fallback
|
||||
}
|
||||
|
||||
const toRowMap = <TRow extends { id: string }>(rows?: TRow[]) => {
|
||||
const map = new Map<string, TRow>()
|
||||
for (const row of rows || []) {
|
||||
@@ -363,32 +385,31 @@ const getOnlyCostScaleBudgetFee = (
|
||||
return /^\d+::/.test(id)
|
||||
})
|
||||
if (usePerRowCalculation) {
|
||||
return sumByNumber(sourceRows, row => {
|
||||
return sumByNumberNullable(sourceRows, row => {
|
||||
const amount = toFiniteNumberOrNull(row?.amount)
|
||||
if (amount == null) return null
|
||||
return getScaleBudgetFee({
|
||||
benchmarkBudget: getBenchmarkBudgetByAmount(amount),
|
||||
majorFactor: toFiniteNumberOrNull(row?.majorFactor) ?? defaultMajorFactor,
|
||||
consultCategoryFactor: toFiniteNumberOrNull(row?.consultCategoryFactor) ?? defaultConsultCategoryFactor,
|
||||
workStageFactor: toFiniteNumberOrNull(row?.workStageFactor) ?? 1,
|
||||
workRatio: toFiniteNumberOrNull(row?.workRatio) ?? 100
|
||||
majorFactor: getRowNumberOrFallback(row, 'majorFactor', defaultMajorFactor),
|
||||
consultCategoryFactor: getRowNumberOrFallback(row, 'consultCategoryFactor', defaultConsultCategoryFactor),
|
||||
workStageFactor: getRowNumberOrFallback(row, 'workStageFactor', 1),
|
||||
workRatio: getRowNumberOrFallback(row, 'workRatio', 100)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const totalAmount = sumByNumber(sourceRows, row =>
|
||||
const totalAmount = sumByNumberNullable(sourceRows, row =>
|
||||
typeof row?.amount === 'number' && Number.isFinite(row.amount) ? row.amount : null
|
||||
)
|
||||
if (totalAmount == null) return null
|
||||
const onlyRow =
|
||||
sourceRows.find(row => String(row?.id || '') === ONLY_COST_SCALE_ROW_ID) ||
|
||||
sourceRows.find(row => hasOwn(row, 'consultCategoryFactor') || hasOwn(row, 'majorFactor')) ||
|
||||
sourceRows[0]
|
||||
const consultCategoryFactor =
|
||||
toFiniteNumberOrNull(onlyRow?.consultCategoryFactor) ?? defaultConsultCategoryFactor
|
||||
const majorFactor =
|
||||
toFiniteNumberOrNull(onlyRow?.majorFactor) ?? defaultMajorFactor
|
||||
const workStageFactor = toFiniteNumberOrNull(onlyRow?.workStageFactor) ?? 1
|
||||
const workRatio = toFiniteNumberOrNull(onlyRow?.workRatio) ?? 100
|
||||
const consultCategoryFactor = getRowNumberOrFallback(onlyRow, 'consultCategoryFactor', defaultConsultCategoryFactor)
|
||||
const majorFactor = getRowNumberOrFallback(onlyRow, 'majorFactor', defaultMajorFactor)
|
||||
const workStageFactor = getRowNumberOrFallback(onlyRow, 'workStageFactor', 1)
|
||||
const workRatio = getRowNumberOrFallback(onlyRow, 'workRatio', 100)
|
||||
return getScaleBudgetFee({
|
||||
benchmarkBudget: getBenchmarkBudgetByAmount(totalAmount),
|
||||
majorFactor,
|
||||
@@ -405,7 +426,7 @@ const buildOnlyCostScaleDetailRows = (
|
||||
majorFactorMap?: Map<string, number | null>,
|
||||
industryId?: string | null
|
||||
) => {
|
||||
const totalAmount = sumByNumber(rowsFromDb || [], row =>
|
||||
const totalAmount = sumByNumberNullable(rowsFromDb || [], row =>
|
||||
typeof row?.amount === 'number' && Number.isFinite(row.amount) ? row.amount : null
|
||||
)
|
||||
const industryMajorEntry = getIndustryMajorEntryByIndustryId(industryId)
|
||||
@@ -413,17 +434,20 @@ const buildOnlyCostScaleDetailRows = (
|
||||
const onlyRow =
|
||||
(rowsFromDb || []).find(row => String(row?.id || '') === ONLY_COST_SCALE_ROW_ID) ||
|
||||
(rowsFromDb || []).find(row => String(row?.id || '') === onlyCostRowId)
|
||||
const consultCategoryFactor =
|
||||
toFiniteNumberOrNull(onlyRow?.consultCategoryFactor) ??
|
||||
consultCategoryFactorMap?.get(String(serviceId)) ??
|
||||
getDefaultConsultCategoryFactor(serviceId)
|
||||
const majorFactor =
|
||||
toFiniteNumberOrNull(onlyRow?.majorFactor) ??
|
||||
const consultCategoryFactor = getRowNumberOrFallback(
|
||||
onlyRow,
|
||||
'consultCategoryFactor',
|
||||
consultCategoryFactorMap?.get(String(serviceId)) ?? getDefaultConsultCategoryFactor(serviceId)
|
||||
)
|
||||
const majorFactor = getRowNumberOrFallback(
|
||||
onlyRow,
|
||||
'majorFactor',
|
||||
(industryMajorEntry ? majorFactorMap?.get(industryMajorEntry.id) ?? null : null) ??
|
||||
toFiniteNumberOrNull(industryMajorEntry?.item?.defCoe) ??
|
||||
1
|
||||
const workStageFactor = toFiniteNumberOrNull(onlyRow?.workStageFactor) ?? 1
|
||||
const workRatio = toFiniteNumberOrNull(onlyRow?.workRatio) ?? 100
|
||||
toFiniteNumberOrNull(industryMajorEntry?.item?.defCoe) ??
|
||||
1
|
||||
)
|
||||
const workStageFactor = getRowNumberOrFallback(onlyRow, 'workStageFactor', 1)
|
||||
const workRatio = getRowNumberOrFallback(onlyRow, 'workRatio', 100)
|
||||
|
||||
return [
|
||||
{
|
||||
@@ -757,7 +781,7 @@ export const getPricingMethodTotalsForService = async (params: {
|
||||
consultCategoryFactorMap,
|
||||
majorFactorMap
|
||||
)
|
||||
return sumByNumber(investRows, row => {
|
||||
return sumByNumberNullable(investRows, row => {
|
||||
if (!isCostMajorById(row.id)) return null
|
||||
if (excludeInvestmentCostAndAreaRows && isDualScaleMajorById(row.id)) return null
|
||||
return getInvestmentBudgetFee(row)
|
||||
@@ -771,13 +795,13 @@ export const getPricingMethodTotalsForService = async (params: {
|
||||
consultCategoryFactorMap,
|
||||
majorFactorMap
|
||||
)
|
||||
const landScale = sumByNumber(landRows, row => (isAreaMajorById(row.id) ? getLandBudgetFee(row) : null))
|
||||
const landScale = sumByNumberNullable(landRows, row => (isAreaMajorById(row.id) ? getLandBudgetFee(row) : null))
|
||||
|
||||
const defaultWorkloadRows = buildDefaultWorkloadRows(serviceId, consultCategoryFactorMap)
|
||||
const workload =
|
||||
defaultWorkloadRows.length === 0
|
||||
? null
|
||||
: sumByNumber(
|
||||
: sumByNumberNullable(
|
||||
workloadData?.detailRows != null
|
||||
? mergeWorkloadRows(serviceId, workloadData.detailRows as any, consultCategoryFactorMap)
|
||||
: defaultWorkloadRows,
|
||||
@@ -788,7 +812,7 @@ export const getPricingMethodTotalsForService = async (params: {
|
||||
hourlyData?.detailRows != null
|
||||
? mergeHourlyRows(hourlyData.detailRows as any)
|
||||
: buildDefaultHourlyRows()
|
||||
const hourly = sumByNumber(hourlyRows, row => calcHourlyServiceBudget(row))
|
||||
const hourly = sumByNumberNullable(hourlyRows, row => calcHourlyServiceBudget(row))
|
||||
|
||||
return {
|
||||
investScale,
|
||||
|
||||
Reference in new issue
Block a user