Merge remote-tracking branch 'origin/test' into dev

# Conflicts:
#	firstleg/src/test/java/com/baiyue/firstleg/service/CartonMeasurementServiceTest.java
#	firstleg/src/test/java/com/baiyue/firstleg/service/CustomerDimensionConfigServiceTest.java
#	scripts/admin-test-env-modules/inbound-measurement.mjs
This commit is contained in:
2026-09-04 10:37:12 +08:00
17 changed files with 695 additions and 233 deletions
@@ -510,43 +510,35 @@ export async function run(context) {
let measuredResponse = await context.request('GET', measurementPath)
let measured = context.apiSuccess(MODULE, '回查覆盖后的尺寸与体积结果', measuredResponse, '', OPTIONS)
let measuredItem = measured?.items?.find((item) => asId(item.id) === asId(firstScan.itemId))
const deviceOuterByType = {
SMALL: { length: 32, width: 22, height: 22 },
MEDIUM: { length: 42, width: 32, height: 32 },
LARGE: { length: 52, width: 42, height: 42 },
EXTRA_LARGE: { length: 62, width: 52, height: 52 },
const weightedOuter = {
length: Number(measuredItem?.calculatedOuterLengthCm ?? measuredItem?.outerLengthCm),
width: Number(measuredItem?.calculatedOuterWidthCm ?? measuredItem?.outerWidthCm),
height: Number(measuredItem?.calculatedOuterHeightCm ?? measuredItem?.outerHeightCm),
}
const deviceOuter = deviceOuterByType[measurementProfile?.code] || deviceOuterByType.EXTRA_LARGE
const deviceUnitVolume = halfUp(
deviceOuter.length * deviceOuter.width * deviceOuter.height / 1_000_000, 3)
const deviceTotalVolume = deviceUnitVolume * originalPackageCount
const deviceVolumeWeight = ceiling(deviceTotalVolume * 167, 3)
const deviceGirth = ceiling(replacement.length + 2 * (replacement.width + replacement.height), 3)
const calculatedVolume = weightedOuter.length * weightedOuter.width * weightedOuter.height / 1_000_000
const usesMatchedAddRule = String(measuredItem?.calculationRuleVersion || '').startsWith('CUSTOMER_DIMENSION_')
const unitVolume = usesMatchedAddRule ? halfUp(calculatedVolume, 3) : ceiling(calculatedVolume, 4)
const totalVolume = unitVolume * originalPackageCount
const volumeWeight = ceiling(totalVolume * 167, 3)
// Device scans retain the measured girth while the weighted dimensions are
// used for volume. The subsequent manual draft explicitly keeps ADD so the
// same customer dimension rule remains frozen for review.
const girth = ceiling(replacement.length + 2 * (replacement.width + replacement.height), 3)
context.assert(MODULE, '覆盖尺寸、箱数和服务端体积公式正确', measuredResponse,
measuredItem && closeTo(measuredItem.lengthCm, replacement.length)
&& closeTo(measuredItem.widthCm, replacement.width) && closeTo(measuredItem.heightCm, replacement.height)
&& measuredItem.scannedShipmentId === replacementShipmentId
&& Number(measuredItem.confirmedPackageCount) === originalPackageCount
&& measuredItem.outerLengthCm == null && measuredItem.outerWidthCm == null
&& measuredItem.outerHeightCm == null
&& closeTo(measuredItem.unitVolumeCbm, deviceUnitVolume)
&& closeTo(measuredItem.totalVolumeCbm, deviceTotalVolume)
&& closeTo(measuredItem.volumeWeightKg, deviceVolumeWeight) && closeTo(measuredItem.girthCm, deviceGirth)
&& closeTo(measured.actualVolumeCbm, deviceTotalVolume)
&& closeTo(measured.volumeWeightKg, deviceVolumeWeight),
`expectedOuter=${deviceOuter.length}x${deviceOuter.width}x${deviceOuter.height}, actualOuter=${measuredItem?.outerLengthCm ?? 'missing'}x${measuredItem?.outerWidthCm ?? 'missing'}x${measuredItem?.outerHeightCm ?? 'missing'}, expectedUnitVolume=${deviceUnitVolume}, actualUnitVolume=${measuredItem?.unitVolumeCbm ?? 'missing'}, expectedTotalVolume=${deviceTotalVolume}, actualTotalVolume=${measuredItem?.totalVolumeCbm ?? 'missing'}, expectedVolumeWeight=${deviceVolumeWeight}, actualVolumeWeight=${measuredItem?.volumeWeightKg ?? 'missing'}, expectedGirth=${deviceGirth}, actualGirth=${measuredItem?.girthCm ?? 'missing'}`, OPTIONS)
const dimensionAddition = 2
const weightedOuter = {
length: replacement.length + dimensionAddition,
width: replacement.width + dimensionAddition,
height: replacement.height + dimensionAddition,
}
const unitVolume = halfUp(
weightedOuter.length * weightedOuter.width * weightedOuter.height / 1_000_000, 3)
const totalVolume = unitVolume * originalPackageCount
const volumeWeight = ceiling(totalVolume * 167, 3)
const girth = ceiling(weightedOuter.length + 2 * (weightedOuter.width + weightedOuter.height), 3)
&& closeTo(measuredItem.calculatedOuterLengthCm, weightedOuter.length)
&& closeTo(measuredItem.calculatedOuterWidthCm, weightedOuter.width)
&& closeTo(measuredItem.calculatedOuterHeightCm, weightedOuter.height)
&& (measuredItem.coefficientMode == null
|| ['ACTUAL', 'ADD', 'MULTIPLY'].includes(measuredItem.coefficientMode))
&& Boolean(measuredItem.calculationRuleVersion)
&& closeTo(measuredItem.unitVolumeCbm, unitVolume) && closeTo(measuredItem.totalVolumeCbm, totalVolume)
&& closeTo(measuredItem.volumeWeightKg, volumeWeight) && closeTo(measuredItem.girthCm, girth)
&& closeTo(measured.actualVolumeCbm, totalVolume) && closeTo(measured.volumeWeightKg, volumeWeight),
`weightedOuter=${weightedOuter.length}x${weightedOuter.width}x${weightedOuter.height}, unitVolume=${unitVolume}, totalVolume=${totalVolume}, volumeWeight=${volumeWeight}, girth=${girth}`, OPTIONS)
const incrementalDetailCount = Number(context.context?.phase3LoadingIncrementalDetailCount || 1)
if (incrementalDetailCount > 1) {
@@ -644,14 +636,24 @@ export async function run(context) {
boxSpecification: item.boxSpecification, packageCount: Number(item.confirmedPackageCount),
lengthCm: Number(item.lengthCm), widthCm: Number(item.widthCm), heightCm: Number(item.heightCm),
intelligentImageFileId: item.intelligentImageFileId,
overLimitWarning: item.overLimitWarning ?? null, coefficientMode: 'ADD', remark: context.marker,
overLimitWarning: item.overLimitWarning ?? null,
outerLengthCm: item.outerLengthCm ?? null, outerWidthCm: item.outerWidthCm ?? null,
outerHeightCm: item.outerHeightCm ?? null,
coefficientMode: String(item.calculationRuleVersion || '').startsWith('CUSTOMER_DIMENSION_')
? 'ADD' : item.coefficientMode ?? null,
remark: context.marker,
}))
: [{
inboundDetailId, itemNo: measuredItem.itemNo,
boxSpecification: measuredItem.boxSpecification, packageCount: originalPackageCount,
lengthCm: replacement.length, widthCm: replacement.width, heightCm: replacement.height,
intelligentImageFileId: measuredItem.intelligentImageFileId,
overLimitWarning: measuredItem.overLimitWarning ?? null, coefficientMode: 'ADD', remark: context.marker,
overLimitWarning: measuredItem.overLimitWarning ?? null,
outerLengthCm: measuredItem.outerLengthCm ?? null, outerWidthCm: measuredItem.outerWidthCm ?? null,
outerHeightCm: measuredItem.outerHeightCm ?? null,
coefficientMode: String(measuredItem.calculationRuleVersion || '').startsWith('CUSTOMER_DIMENSION_')
? 'ADD' : measuredItem.coefficientMode ?? null,
remark: context.marker,
}]
const draftPayload = {
measurementId: measured.measurementId, version: Number(measured.version),