优化
This commit is contained in:
1 parent
3950057707
commit
a10359f7e0
19 files changed
+349
-299
No files matched your search
@@ -1,6 +1,8 @@
|
||||
import localforage from 'localforage'
|
||||
import { expertList, getBasicFeeFromScale, majorList, serviceList, taskList } from '@/sql'
|
||||
import { addNumbers, roundTo, sumByNumber, toDecimal } from '@/lib/decimal'
|
||||
import { expertList, majorList, serviceList, taskList } from '@/sql'
|
||||
import { roundTo, sumByNumber, toDecimal } from '@/lib/decimal'
|
||||
import { toFiniteNumberOrNull } from '@/lib/number'
|
||||
import { getBenchmarkBudgetByScale, getScaleBudgetFee } from '@/lib/pricingScaleFee'
|
||||
|
||||
interface StoredDetailRowsState<T = any> {
|
||||
detailRows?: T[]
|
||||
@@ -58,12 +60,17 @@ export interface PricingMethodTotals {
|
||||
hourly: number | null
|
||||
}
|
||||
|
||||
const toFiniteNumberOrNull = (value: unknown): number | null =>
|
||||
typeof value === 'number' && Number.isFinite(value) ? value : null
|
||||
|
||||
const hasOwn = (obj: unknown, key: string) =>
|
||||
Object.prototype.hasOwnProperty.call(obj || {}, key)
|
||||
|
||||
const toRowMap = <TRow extends { id: string }>(rows?: TRow[]) => {
|
||||
const map = new Map<string, TRow>()
|
||||
for (const row of rows || []) {
|
||||
map.set(String(row.id), row)
|
||||
}
|
||||
return map
|
||||
}
|
||||
|
||||
const getDefaultConsultCategoryFactor = (serviceId: string | number) => {
|
||||
const service = (serviceList as Record<string, ServiceLite | undefined>)[String(serviceId)]
|
||||
return toFiniteNumberOrNull(service?.defCoe)
|
||||
@@ -95,10 +102,7 @@ const mergeScaleRows = (
|
||||
serviceId: string | number,
|
||||
rowsFromDb: Array<Partial<ScaleRow> & Pick<ScaleRow, 'id'>> | undefined
|
||||
): ScaleRow[] => {
|
||||
const dbValueMap = new Map<string, Partial<ScaleRow> & Pick<ScaleRow, 'id'>>()
|
||||
for (const row of rowsFromDb || []) {
|
||||
dbValueMap.set(String(row.id), row)
|
||||
}
|
||||
const dbValueMap = toRowMap(rowsFromDb)
|
||||
|
||||
const defaultConsultCategoryFactor = getDefaultConsultCategoryFactor(serviceId)
|
||||
return buildDefaultScaleRows(serviceId).map(row => {
|
||||
@@ -122,26 +126,26 @@ const mergeScaleRows = (
|
||||
})
|
||||
}
|
||||
|
||||
const getBenchmarkBudgetByAmount = (amount: MaybeNumber) => {
|
||||
const result = getBasicFeeFromScale(amount, 'cost')
|
||||
return result ? roundTo(addNumbers(result.basic, result.optional), 2) : null
|
||||
}
|
||||
const getBenchmarkBudgetByAmount = (amount: MaybeNumber) =>
|
||||
getBenchmarkBudgetByScale(amount, 'cost')
|
||||
|
||||
const getBenchmarkBudgetByLandArea = (landArea: MaybeNumber) => {
|
||||
const result = getBasicFeeFromScale(landArea, 'area')
|
||||
return result ? roundTo(addNumbers(result.basic, result.optional), 2) : null
|
||||
}
|
||||
const getBenchmarkBudgetByLandArea = (landArea: MaybeNumber) =>
|
||||
getBenchmarkBudgetByScale(landArea, 'area')
|
||||
|
||||
const getInvestmentBudgetFee = (row: ScaleRow) => {
|
||||
const benchmarkBudget = getBenchmarkBudgetByAmount(row.amount)
|
||||
if (benchmarkBudget == null || row.majorFactor == null || row.consultCategoryFactor == null) return null
|
||||
return roundTo(toDecimal(benchmarkBudget).mul(row.majorFactor).mul(row.consultCategoryFactor), 2)
|
||||
return getScaleBudgetFee({
|
||||
benchmarkBudget: getBenchmarkBudgetByAmount(row.amount),
|
||||
majorFactor: row.majorFactor,
|
||||
consultCategoryFactor: row.consultCategoryFactor
|
||||
})
|
||||
}
|
||||
|
||||
const getLandBudgetFee = (row: ScaleRow) => {
|
||||
const benchmarkBudget = getBenchmarkBudgetByLandArea(row.landArea)
|
||||
if (benchmarkBudget == null || row.majorFactor == null || row.consultCategoryFactor == null) return null
|
||||
return roundTo(toDecimal(benchmarkBudget).mul(row.majorFactor).mul(row.consultCategoryFactor), 2)
|
||||
return getScaleBudgetFee({
|
||||
benchmarkBudget: getBenchmarkBudgetByLandArea(row.landArea),
|
||||
majorFactor: row.majorFactor,
|
||||
consultCategoryFactor: row.consultCategoryFactor
|
||||
})
|
||||
}
|
||||
|
||||
const getTaskEntriesByServiceId = (serviceId: string | number) =>
|
||||
@@ -164,10 +168,7 @@ const mergeWorkloadRows = (
|
||||
serviceId: string | number,
|
||||
rowsFromDb: Array<Partial<WorkloadRow> & Pick<WorkloadRow, 'id'>> | undefined
|
||||
): WorkloadRow[] => {
|
||||
const dbValueMap = new Map<string, Partial<WorkloadRow> & Pick<WorkloadRow, 'id'>>()
|
||||
for (const row of rowsFromDb || []) {
|
||||
dbValueMap.set(String(row.id), row)
|
||||
}
|
||||
const dbValueMap = toRowMap(rowsFromDb)
|
||||
|
||||
return buildDefaultWorkloadRows(serviceId).map(row => {
|
||||
const fromDb = dbValueMap.get(row.id)
|
||||
@@ -216,10 +217,7 @@ const buildDefaultHourlyRows = (): HourlyRow[] =>
|
||||
const mergeHourlyRows = (
|
||||
rowsFromDb: Array<Partial<HourlyRow> & Pick<HourlyRow, 'id'>> | undefined
|
||||
): HourlyRow[] => {
|
||||
const dbValueMap = new Map<string, Partial<HourlyRow> & Pick<HourlyRow, 'id'>>()
|
||||
for (const row of rowsFromDb || []) {
|
||||
dbValueMap.set(String(row.id), row)
|
||||
}
|
||||
const dbValueMap = toRowMap(rowsFromDb)
|
||||
|
||||
return buildDefaultHourlyRows().map(row => {
|
||||
const fromDb = dbValueMap.get(row.id)
|
||||
@@ -239,6 +237,20 @@ const calcHourlyServiceBudget = (row: HourlyRow) => {
|
||||
return roundTo(toDecimal(row.adoptedBudgetUnitPrice).mul(row.personnelCount).mul(row.workdayCount), 2)
|
||||
}
|
||||
|
||||
const resolveScaleRows = (
|
||||
serviceId: string,
|
||||
pricingData: StoredDetailRowsState | null,
|
||||
htData: StoredDetailRowsState | null
|
||||
) => {
|
||||
if (pricingData?.detailRows != null) {
|
||||
return mergeScaleRows(serviceId, pricingData.detailRows as any)
|
||||
}
|
||||
if (htData?.detailRows != null) {
|
||||
return mergeScaleRows(serviceId, htData.detailRows as any)
|
||||
}
|
||||
return buildDefaultScaleRows(serviceId)
|
||||
}
|
||||
|
||||
export const getPricingMethodTotalsForService = async (params: {
|
||||
contractId: string
|
||||
serviceId: string | number
|
||||
@@ -258,20 +270,11 @@ export const getPricingMethodTotalsForService = async (params: {
|
||||
localforage.getItem<StoredDetailRowsState>(htDbKey)
|
||||
])
|
||||
|
||||
const investRows =
|
||||
investData?.detailRows != null
|
||||
? mergeScaleRows(serviceId, investData.detailRows as any)
|
||||
: htData?.detailRows != null
|
||||
? mergeScaleRows(serviceId, htData.detailRows as any)
|
||||
: buildDefaultScaleRows(serviceId)
|
||||
// 优先使用对应计费页的数据;不存在时回退合同段规模信息,再回退默认字典行。
|
||||
const investRows = resolveScaleRows(serviceId, investData, htData)
|
||||
const investScale = sumByNumber(investRows, row => getInvestmentBudgetFee(row))
|
||||
|
||||
const landRows =
|
||||
landData?.detailRows != null
|
||||
? mergeScaleRows(serviceId, landData.detailRows as any)
|
||||
: htData?.detailRows != null
|
||||
? mergeScaleRows(serviceId, htData.detailRows as any)
|
||||
: buildDefaultScaleRows(serviceId)
|
||||
const landRows = resolveScaleRows(serviceId, landData, htData)
|
||||
const landScale = sumByNumber(landRows, row => getLandBudgetFee(row))
|
||||
|
||||
const defaultWorkloadRows = buildDefaultWorkloadRows(serviceId)
|
||||
|
||||
Reference in new issue
Block a user