feat: separate container fee workbenches
This commit is contained in:
@@ -72,17 +72,17 @@ describe('container fee API', () => {
|
||||
|
||||
it('maps settled fees and allocation rows from one container aggregate request', async () => {
|
||||
const get = vi.spyOn(http, 'get').mockResolvedValue({ code: '200', data: {
|
||||
customerId: 11, containerId: 99, settledSourceFeeIds: [7],
|
||||
costs: [{ costId: 81, costNo: 'COST-81', costType: 'TRUCKING', costOrigin: 'CONTAINER_FEE', sourceFeeId: 7, sourceFeeVersion: 2, containerId: 99, supplierName: '承运商A', feeItemName: '拖车费', amount: 300, currency: 'CNY', status: 'CONFIRMED', allocations: [{ allocationId: 1, orderId: 8, inboundId: 9, volumeCbm: 2, totalVolumeCbm: 5, allocationRate: 0.4, allocatedAmount: 120, roundingAdjustment: false }] }],
|
||||
customerId: 11, containerBookingId: 99, settledSourceFeeIds: [7],
|
||||
costs: [{ costId: 81, costNo: 'COST-81', costType: 'TRUCKING', costOrigin: 'CONTAINER_FEE', sourceFeeId: 7, sourceFeeVersion: 2, containerBookingId: 99, supplierName: '承运商A', feeItemName: '拖车费', amount: 300, currency: 'CNY', status: 'CONFIRMED', allocations: [{ allocationId: 1, orderId: 8, inboundId: 9, volumeCbm: 2, totalVolumeCbm: 5, allocationRate: 0.4, allocatedAmount: 120, roundingAdjustment: false }] }],
|
||||
} })
|
||||
const result = await getContainerSettlementDetails('11', '99')
|
||||
expect(result).toMatchObject({ customerId: '11', containerId: '99', settledSourceFeeIds: ['7'], costs: [{ id: '81', sourceFeeId: '7', amount: 300, allocations: [{ id: '1', orderId: '8', inboundId: '9', allocatedAmount: 120 }] }] })
|
||||
expect(get).toHaveBeenCalledWith('/platform/finance/v1/container-settlement-details', { params: { customerId: '11', containerId: '99' } })
|
||||
expect(result).toMatchObject({ customerId: '11', containerBookingId: '99', settledSourceFeeIds: ['7'], costs: [{ id: '81', containerBookingId: '99', sourceFeeId: '7', amount: 300, allocations: [{ id: '1', orderId: '8', inboundId: '9', allocatedAmount: 120 }] }] })
|
||||
expect(get).toHaveBeenCalledWith('/platform/finance/v1/container-settlement-details', { params: { customerId: '11', containerBookingId: '99' } })
|
||||
expect(get).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('fails closed when the Finance aggregate does not echo the selected customer and container', async () => {
|
||||
vi.spyOn(http, 'get').mockResolvedValue({ code: '200', data: { customerId: 12, containerId: 99, settledSourceFeeIds: [], costs: [] } })
|
||||
vi.spyOn(http, 'get').mockResolvedValue({ code: '200', data: { customerId: 12, containerBookingId: 99, settledSourceFeeIds: [], costs: [] } })
|
||||
await expect(getContainerSettlementDetails('11', '99')).rejects.toThrow('Finance 聚合结果与柜次或客户上下文不一致')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -118,7 +118,7 @@ export interface ContainerCostDetail {
|
||||
costOrigin: string
|
||||
sourceFeeId: string | null
|
||||
sourceFeeVersion: number
|
||||
containerId: string | null
|
||||
containerBookingId: string | null
|
||||
supplierName: string | null
|
||||
feeItemName: string
|
||||
amount: number
|
||||
@@ -129,7 +129,7 @@ export interface ContainerCostDetail {
|
||||
|
||||
export interface ContainerSettlementDetails {
|
||||
customerId: string
|
||||
containerId: string
|
||||
containerBookingId: string
|
||||
settledSourceFeeIds: string[]
|
||||
costs: ContainerCostDetail[]
|
||||
}
|
||||
@@ -243,17 +243,17 @@ export async function uploadContainerFeePaymentVoucher(customerId: string, file:
|
||||
return { fileId, fileName: String(raw.fileName || raw.file_name || file.name) }
|
||||
}
|
||||
|
||||
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 } })
|
||||
export async function getContainerSettlementDetails(customerId: string, containerBookingId: string): Promise<ContainerSettlementDetails> {
|
||||
const response = await http.get<ApiEnvelope<Record<string, unknown>>, ApiEnvelope<Record<string, unknown>>>('/platform/finance/v1/container-settlement-details', { params: { customerId, containerBookingId } })
|
||||
const raw = unwrapApiResponse(response)
|
||||
if (id(raw.customerId) !== customerId || id(raw.containerId) !== containerId) throw new Error('Finance 聚合结果与柜次或客户上下文不一致')
|
||||
if (id(raw.customerId) !== customerId || id(raw.containerBookingId) !== containerBookingId) 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 聚合成本与柜次上下文不一致')
|
||||
if (id(cost.containerBookingId) !== containerBookingId) 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),
|
||||
containerBookingId: cost.containerBookingId == null ? null : id(cost.containerBookingId), 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>
|
||||
@@ -261,5 +261,5 @@ export async function getContainerSettlementDetails(customerId: string, containe
|
||||
}),
|
||||
}
|
||||
})
|
||||
return { customerId, containerId, settledSourceFeeIds: (Array.isArray(raw.settledSourceFeeIds) ? raw.settledSourceFeeIds : []).map(id), costs }
|
||||
return { customerId, containerBookingId, settledSourceFeeIds: (Array.isArray(raw.settledSourceFeeIds) ? raw.settledSourceFeeIds : []).map(id), costs }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user