perf: use container finance aggregate
This commit is contained in:
@@ -113,13 +113,27 @@ export interface ContainerCostAllocation {
|
||||
|
||||
export interface ContainerCostDetail {
|
||||
id: string
|
||||
costNo: string
|
||||
costType: string
|
||||
costOrigin: string
|
||||
sourceFeeId: string | null
|
||||
sourceFeeVersion: number
|
||||
containerId: string | null
|
||||
supplierName: string | null
|
||||
feeItemName: string
|
||||
amount: number
|
||||
currency: string
|
||||
status: string
|
||||
allocations: ContainerCostAllocation[]
|
||||
}
|
||||
|
||||
export interface ContainerSettlementDetails {
|
||||
customerId: string
|
||||
containerId: string
|
||||
settledSourceFeeIds: string[]
|
||||
costs: ContainerCostDetail[]
|
||||
}
|
||||
|
||||
const id = (value: unknown) => value == null ? '' : String(value)
|
||||
const numberValue = (value: unknown) => Number.isFinite(Number(value)) ? Number(value) : 0
|
||||
const supplierCategories: SupplierCategory[] = ['BOOKING', 'CUSTOMS', 'TRUCKING', 'CERTIFICATE']
|
||||
@@ -229,16 +243,23 @@ export async function uploadContainerFeePaymentVoucher(customerId: string, file:
|
||||
return { fileId, fileName: String(raw.fileName || raw.file_name || file.name) }
|
||||
}
|
||||
|
||||
export async function listContainerCostDetails(customerId: string, containerId: string): Promise<ContainerCostDetail[]> {
|
||||
const response = await http.get<ApiEnvelope<Record<string, unknown>[]>, ApiEnvelope<Record<string, unknown>[]>>('/platform/finance/v1/cost-entries', { params: { customerId } })
|
||||
const costs = unwrapApiResponse(response).filter((raw) => id(raw.customerId) === customerId && id(raw.containerId) === containerId)
|
||||
return Promise.all(costs.map(async (raw) => {
|
||||
const costId = id(raw.id)
|
||||
const detailResponse = await http.get<ApiEnvelope<{ cost: Record<string, unknown>; allocations: Record<string, unknown>[] }>, ApiEnvelope<{ cost: Record<string, unknown>; allocations: Record<string, unknown>[] }>>(`/platform/finance/v1/cost-entries/${encodeURIComponent(costId)}`, { params: { customerId } })
|
||||
const detail = unwrapApiResponse(detailResponse)
|
||||
if (id(detail.cost.id) !== costId || id(detail.cost.customerId) !== customerId || id(detail.cost.containerId) !== containerId) {
|
||||
throw new Error('Finance 成本详情与柜次或客户上下文不一致')
|
||||
export async function getContainerSettlementDetails(customerId: string, containerId: string): Promise<ContainerSettlementDetails> {
|
||||
const response = await http.get<ApiEnvelope<Record<string, unknown>>, ApiEnvelope<Record<string, unknown>>>('/platform/finance/v1/container-settlement-details', { params: { customerId, containerId } })
|
||||
const raw = unwrapApiResponse(response)
|
||||
if (id(raw.customerId) !== customerId || id(raw.containerId) !== containerId) throw new Error('Finance 聚合结果与柜次或客户上下文不一致')
|
||||
const costs = (Array.isArray(raw.costs) ? raw.costs : []).map((value) => {
|
||||
const cost = value as Record<string, unknown>
|
||||
if (id(cost.containerId) !== containerId) throw new Error('Finance 聚合成本与柜次上下文不一致')
|
||||
return {
|
||||
id: id(cost.costId), costNo: String(cost.costNo || ''), costType: String(cost.costType || ''), costOrigin: String(cost.costOrigin || ''),
|
||||
sourceFeeId: cost.sourceFeeId == null ? null : id(cost.sourceFeeId), sourceFeeVersion: numberValue(cost.sourceFeeVersion),
|
||||
containerId: cost.containerId == null ? null : id(cost.containerId), supplierName: cost.supplierName == null ? null : String(cost.supplierName),
|
||||
feeItemName: String(cost.feeItemName || ''), amount: numberValue(cost.amount), currency: String(cost.currency || ''), status: String(cost.status || ''),
|
||||
allocations: (Array.isArray(cost.allocations) ? cost.allocations : []).map((value) => {
|
||||
const allocation = value as Record<string, unknown>
|
||||
return { id: id(allocation.allocationId), orderId: id(allocation.orderId), inboundId: allocation.inboundId == null ? null : id(allocation.inboundId), volumeCbm: numberValue(allocation.volumeCbm), totalVolumeCbm: numberValue(allocation.totalVolumeCbm), allocationRate: numberValue(allocation.allocationRate), allocatedAmount: numberValue(allocation.allocatedAmount), roundingAdjustment: Boolean(allocation.roundingAdjustment) }
|
||||
}),
|
||||
}
|
||||
return { id: costId, containerId: detail.cost.containerId == null ? null : id(detail.cost.containerId), supplierName: detail.cost.supplierName == null ? null : String(detail.cost.supplierName), feeItemName: String(detail.cost.feeItemName || ''), amount: numberValue(detail.cost.payableAmount), allocations: (detail.allocations || []).map((item) => ({ id: id(item.id), orderId: id(item.orderId), inboundId: item.inboundId == null ? null : id(item.inboundId), volumeCbm: numberValue(item.volumeCbm), totalVolumeCbm: numberValue(item.totalVolumeCbm), allocationRate: numberValue(item.allocationRate), allocatedAmount: numberValue(item.allocatedAmount), roundingAdjustment: Boolean(item.roundingAdjustment) })) }
|
||||
}))
|
||||
})
|
||||
return { customerId, containerId, settledSourceFeeIds: (Array.isArray(raw.settledSourceFeeIds) ? raw.settledSourceFeeIds : []).map(id), costs }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user