Merge branch 'dev' of http://8.163.30.128:10082/html/client-web into dev
# Conflicts: # src/modules/overseas-warehouse/api/warehouseServices.ts # src/modules/overseas-warehouse/views/WarehouseServiceView.vue
This commit is contained in:
@@ -6,9 +6,17 @@ const source = readFileSync(new URL('./inboundBilling.ts', import.meta.url), 'ut
|
||||
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)'/)
|
||||
const readSource = source.slice(source.indexOf('export async function getMerchantInboundBilling'), source.indexOf('function createFeeConfirmationKey'))
|
||||
assert.match(readSource, /url: `\/merchant\/v1\/first-leg\/orders\/\$\{orderId\}\/inbound-billing`/)
|
||||
assert.match(readSource, /method: 'GET'/)
|
||||
assert.doesNotMatch(readSource, /tenantId|method: '(?:POST|PUT|PATCH|DELETE)'/)
|
||||
})
|
||||
|
||||
test('confirms the latest customer fee version with an idempotency key', () => {
|
||||
assert.match(source, /function confirmMerchantInboundFee/)
|
||||
assert.match(source, /\/inbound-billing\/confirm/)
|
||||
assert.match(source, /headers: \{ 'Idempotency-Key': idempotencyKey \}/)
|
||||
assert.match(source, /data: \{ expectedFeeVersion \}/)
|
||||
})
|
||||
|
||||
test('sanitizes the platform-shaped response into a merchant whitelist', () => {
|
||||
|
||||
@@ -9,6 +9,9 @@ import type {
|
||||
|
||||
interface MerchantInboundBillingWireResponse {
|
||||
inbound: MerchantInboundResult
|
||||
measurementSummary: MerchantInboundBilling['measurementSummary']
|
||||
measurementItems: MerchantInboundBilling['measurementItems']
|
||||
billingBasis: MerchantInboundBilling['billingBasis']
|
||||
latestFee: MerchantInboundFeeSnapshot
|
||||
}
|
||||
|
||||
@@ -62,6 +65,8 @@ function sanitizeFee(fee: MerchantInboundFeeSnapshot): MerchantInboundFeeSnapsho
|
||||
feeStatus: fee.feeStatus,
|
||||
inboundId: fee.inboundId,
|
||||
inboundCode: fee.inboundCode,
|
||||
measurementId: fee.measurementId == null ? null : String(fee.measurementId),
|
||||
measurementSource: fee.measurementSource,
|
||||
chargeRuleId: fee.chargeRuleId,
|
||||
ruleCode: fee.ruleCode,
|
||||
chargeRuleVersion: fee.chargeRuleVersion,
|
||||
@@ -98,6 +103,43 @@ function sanitizeFee(fee: MerchantInboundFeeSnapshot): MerchantInboundFeeSnapsho
|
||||
confirmedAt: fee.confirmedAt,
|
||||
sentAt: fee.sentAt,
|
||||
nextProcessStatus: fee.nextProcessStatus,
|
||||
customerConfirmationStatus: fee.customerConfirmationStatus,
|
||||
customerConfirmedBy: fee.customerConfirmedBy == null ? null : String(fee.customerConfirmedBy),
|
||||
customerConfirmedByName: fee.customerConfirmedByName,
|
||||
customerConfirmedAt: fee.customerConfirmedAt,
|
||||
}
|
||||
}
|
||||
|
||||
function sanitizeMeasurementSummary(item: MerchantInboundBilling['measurementSummary']): MerchantInboundBilling['measurementSummary'] {
|
||||
return {
|
||||
measurementId: item.measurementId == null ? null : String(item.measurementId),
|
||||
sourceType: item.sourceType,
|
||||
measurementStatus: item.measurementStatus,
|
||||
actualPackageCount: item.actualPackageCount,
|
||||
actualGrossWeightKg: item.actualGrossWeightKg,
|
||||
actualNetWeightKg: item.actualNetWeightKg,
|
||||
actualVolumeCbm: item.actualVolumeCbm,
|
||||
volumeWeightKg: item.volumeWeightKg,
|
||||
actualGoodsName: item.actualGoodsName,
|
||||
calculationSource: item.calculationSource,
|
||||
}
|
||||
}
|
||||
|
||||
function sanitizeMeasurementItem(item: MerchantInboundBilling['measurementItems'][number]): MerchantInboundBilling['measurementItems'][number] {
|
||||
return {
|
||||
id: String(item.id),
|
||||
itemNo: item.itemNo,
|
||||
boxSpecification: item.boxSpecification,
|
||||
packageCount: item.packageCount,
|
||||
lengthCm: item.lengthCm,
|
||||
widthCm: item.widthCm,
|
||||
heightCm: item.heightCm,
|
||||
unitVolumeCbm: item.unitVolumeCbm,
|
||||
totalVolumeCbm: item.totalVolumeCbm,
|
||||
volumeWeightKg: item.volumeWeightKg,
|
||||
chargeRuleId: item.chargeRuleId == null ? null : String(item.chargeRuleId),
|
||||
coefficientMode: item.coefficientMode,
|
||||
calculationRuleVersion: item.calculationRuleVersion,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +150,9 @@ function sanitizeInboundBilling(response: MerchantInboundBillingWireResponse): M
|
||||
publicRemark: response.inbound.publicRemark,
|
||||
palletLocations: response.inbound.palletLocations.map(sanitizePalletLocation),
|
||||
},
|
||||
measurementSummary: sanitizeMeasurementSummary(response.measurementSummary),
|
||||
measurementItems: (response.measurementItems || []).map(sanitizeMeasurementItem),
|
||||
billingBasis: response.billingBasis,
|
||||
latestFee: sanitizeFee(response.latestFee),
|
||||
}
|
||||
}
|
||||
@@ -119,3 +164,19 @@ export async function getMerchantInboundBilling(orderId: string): Promise<Mercha
|
||||
})
|
||||
return sanitizeInboundBilling(response)
|
||||
}
|
||||
|
||||
function createFeeConfirmationKey(orderId: string, feeVersion: number) {
|
||||
const randomPart = globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`
|
||||
return `inbound-fee-confirm-${orderId}-${feeVersion}-${randomPart}`
|
||||
}
|
||||
|
||||
export async function confirmMerchantInboundFee(orderId: string, expectedFeeVersion: number,
|
||||
idempotencyKey = createFeeConfirmationKey(orderId, expectedFeeVersion)) {
|
||||
const response = await apiRequest<MerchantInboundFeeSnapshot>({
|
||||
method: 'POST',
|
||||
url: `/merchant/v1/first-leg/orders/${encodeURIComponent(orderId)}/inbound-billing/confirm`,
|
||||
headers: { 'Idempotency-Key': idempotencyKey },
|
||||
data: { expectedFeeVersion },
|
||||
})
|
||||
return sanitizeFee(response)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user