优化
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import test from 'node:test'
|
||||
|
||||
const source = readFileSync(new URL('./inboundBilling.ts', import.meta.url), 'utf8')
|
||||
const typesSource = readFileSync(new URL('../types/inboundBilling.ts', import.meta.url), 'utf8')
|
||||
|
||||
test('queries the merchant order inbound-billing endpoint without tenant parameters', () => {
|
||||
assert.match(source, /url: `\/merchant\/v1\/first-leg\/orders\/\$\{orderId\}\/inbound-billing`/)
|
||||
assert.match(source, /method: 'GET'/)
|
||||
assert.doesNotMatch(source, /tenantId|method: '(?:POST|PUT|PATCH|DELETE)'/)
|
||||
})
|
||||
|
||||
test('sanitizes the platform-shaped response into a merchant whitelist', () => {
|
||||
assert.match(source, /function sanitizeInboundBilling/)
|
||||
assert.match(source, /summary: sanitizeSummary\(response\.inbound\.summary\)/)
|
||||
assert.match(source, /palletLocations: response\.inbound\.palletLocations\.map\(sanitizePalletLocation\)/)
|
||||
assert.match(source, /latestFee: sanitizeFee\(response\.latestFee\)/)
|
||||
assert.doesNotMatch(source, /\.\.\.response|\.\.\.summary|\.\.\.fee/)
|
||||
assert.doesNotMatch(source, /internalNotes|statusHistory|files/)
|
||||
})
|
||||
|
||||
test('keeps all backend Long identifiers as strings', () => {
|
||||
for (const field of ['id', 'orderId', 'warehouseId', 'palletId', 'locationId', 'feeId', 'inboundId', 'chargeRuleId', 'carrierRateId', 'customerId', 'carrierId']) {
|
||||
assert.match(typesSource, new RegExp(`${field}: string`))
|
||||
}
|
||||
assert.doesNotMatch(typesSource, /(?:id|Id): number/)
|
||||
assert.doesNotMatch(typesSource, /internalNotes|statusHistory|files/)
|
||||
})
|
||||
@@ -0,0 +1,121 @@
|
||||
import { apiRequest } from '@/api/http'
|
||||
import type {
|
||||
MerchantInboundBilling,
|
||||
MerchantInboundFeeSnapshot,
|
||||
MerchantInboundResult,
|
||||
MerchantInboundSummary,
|
||||
MerchantPalletLocation,
|
||||
} from '@/modules/first-leg/types/inboundBilling'
|
||||
|
||||
interface MerchantInboundBillingWireResponse {
|
||||
inbound: MerchantInboundResult
|
||||
latestFee: MerchantInboundFeeSnapshot
|
||||
}
|
||||
|
||||
function sanitizeSummary(summary: MerchantInboundSummary): MerchantInboundSummary {
|
||||
return {
|
||||
id: summary.id,
|
||||
orderId: summary.orderId,
|
||||
orderNo: summary.orderNo,
|
||||
inboundCode: summary.inboundCode,
|
||||
processStatus: summary.processStatus,
|
||||
feeStatus: summary.feeStatus,
|
||||
notificationStatus: summary.notificationStatus,
|
||||
warehouseName: summary.warehouseName,
|
||||
deliveryWarehouseName: summary.deliveryWarehouseName,
|
||||
destinationCode: summary.destinationCode,
|
||||
destinationName: summary.destinationName,
|
||||
totalPackageCount: summary.totalPackageCount,
|
||||
actualGrossWeightKg: summary.actualGrossWeightKg,
|
||||
actualNetWeightKg: summary.actualNetWeightKg,
|
||||
actualVolumeCbm: summary.actualVolumeCbm,
|
||||
volumeWeightKg: summary.volumeWeightKg,
|
||||
chargeableWeightKg: summary.chargeableWeightKg,
|
||||
chargeableVolumeCbm: summary.chargeableVolumeCbm,
|
||||
palletCount: summary.palletCount,
|
||||
locationCodes: summary.locationCodes,
|
||||
measureCompletedAt: summary.measureCompletedAt,
|
||||
inboundedAt: summary.inboundedAt,
|
||||
}
|
||||
}
|
||||
|
||||
function sanitizePalletLocation(item: MerchantPalletLocation): MerchantPalletLocation {
|
||||
return {
|
||||
allocationNo: item.allocationNo,
|
||||
warehouseId: item.warehouseId,
|
||||
palletId: item.palletId,
|
||||
palletCode: item.palletCode,
|
||||
palletCapacityCbm: item.palletCapacityCbm,
|
||||
allocatedVolumeCbm: item.allocatedVolumeCbm,
|
||||
allocatedPackageCount: item.allocatedPackageCount,
|
||||
locationId: item.locationId,
|
||||
locationCode: item.locationCode,
|
||||
allocationStatus: item.allocationStatus,
|
||||
}
|
||||
}
|
||||
|
||||
function sanitizeFee(fee: MerchantInboundFeeSnapshot): MerchantInboundFeeSnapshot {
|
||||
return {
|
||||
feeId: fee.feeId,
|
||||
feeNo: fee.feeNo,
|
||||
feeVersion: fee.feeVersion,
|
||||
feeStatus: fee.feeStatus,
|
||||
inboundId: fee.inboundId,
|
||||
inboundCode: fee.inboundCode,
|
||||
chargeRuleId: fee.chargeRuleId,
|
||||
ruleCode: fee.ruleCode,
|
||||
chargeRuleVersion: fee.chargeRuleVersion,
|
||||
carrierRateId: fee.carrierRateId,
|
||||
rateCode: fee.rateCode,
|
||||
carrierRateVersion: fee.carrierRateVersion,
|
||||
customerId: fee.customerId,
|
||||
customerName: fee.customerName,
|
||||
originWarehouseId: fee.originWarehouseId,
|
||||
originWarehouseName: fee.originWarehouseName,
|
||||
businessType: fee.businessType,
|
||||
channelCode: fee.channelCode,
|
||||
carrierId: fee.carrierId,
|
||||
carrierName: fee.carrierName,
|
||||
destinationCode: fee.destinationCode,
|
||||
taxMode: fee.taxMode,
|
||||
chargeMode: fee.chargeMode,
|
||||
conversionFactor: fee.conversionFactor,
|
||||
roundingScale: fee.roundingScale,
|
||||
roundingMode: fee.roundingMode,
|
||||
actualWeightKg: fee.actualWeightKg,
|
||||
actualVolumeCbm: fee.actualVolumeCbm,
|
||||
convertedQuantity: fee.convertedQuantity,
|
||||
chargeableQuantity: fee.chargeableQuantity,
|
||||
chargeUnit: fee.chargeUnit,
|
||||
unitPrice: fee.unitPrice,
|
||||
subtotalAmount: fee.subtotalAmount,
|
||||
additionalAmount: fee.additionalAmount,
|
||||
totalAmount: fee.totalAmount,
|
||||
currency: fee.currency,
|
||||
rateEffectiveFrom: fee.rateEffectiveFrom,
|
||||
rateEffectiveTo: fee.rateEffectiveTo,
|
||||
calculatedAt: fee.calculatedAt,
|
||||
confirmedAt: fee.confirmedAt,
|
||||
sentAt: fee.sentAt,
|
||||
nextProcessStatus: fee.nextProcessStatus,
|
||||
}
|
||||
}
|
||||
|
||||
function sanitizeInboundBilling(response: MerchantInboundBillingWireResponse): MerchantInboundBilling {
|
||||
return {
|
||||
inbound: {
|
||||
summary: sanitizeSummary(response.inbound.summary),
|
||||
publicRemark: response.inbound.publicRemark,
|
||||
palletLocations: response.inbound.palletLocations.map(sanitizePalletLocation),
|
||||
},
|
||||
latestFee: sanitizeFee(response.latestFee),
|
||||
}
|
||||
}
|
||||
|
||||
export async function getMerchantInboundBilling(orderId: string): Promise<MerchantInboundBilling> {
|
||||
const response = await apiRequest<MerchantInboundBillingWireResponse>({
|
||||
method: 'GET',
|
||||
url: `/merchant/v1/first-leg/orders/${orderId}/inbound-billing`,
|
||||
})
|
||||
return sanitizeInboundBilling(response)
|
||||
}
|
||||
Reference in New Issue
Block a user