test(firstleg): harden measurement demo package
This commit is contained in:
+46
-7
@@ -234,6 +234,38 @@ class InboundMeasurementServiceTest {
|
||||
assertThat(result.confidence()).isEqualByComparingTo("0.50972");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ocrFailureCreatesManualWeightThatCanBeAdjustedAndConfirmed() {
|
||||
InboundOrderEntity inbound = inbound("WAIT_MEASURE");
|
||||
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
|
||||
|
||||
InboundMeasurementResponses.WeightResult created = service.createWeightResult(
|
||||
1L, 10L, 9L,
|
||||
new InboundMeasurementRequests.CreateWeightResultRequest(
|
||||
120L, 501L, "FILE_WEIGHT_OCR", null, null, null, null));
|
||||
|
||||
assertThat(created.recognitionStatus()).isEqualTo("NEEDS_MANUAL");
|
||||
ArgumentCaptor<InboundWeightResultEntity> saved =
|
||||
ArgumentCaptor.forClass(InboundWeightResultEntity.class);
|
||||
verify(repository).insertWeight(saved.capture());
|
||||
InboundWeightResultEntity weight = saved.getValue();
|
||||
weight.setId(20L);
|
||||
when(repository.findWeight(1L, 10L, 20L)).thenReturn(weight);
|
||||
when(repository.updateWeight(weight)).thenReturn(true);
|
||||
when(repository.listWeights(1L, 10L)).thenReturn(List.of(weight));
|
||||
when(repository.updateInboundWeightSummary(inbound)).thenReturn(true);
|
||||
|
||||
InboundMeasurementResponses.WeightResult confirmed = service.confirmWeightResult(
|
||||
1L, 10L, 20L, 9L, "操作员",
|
||||
new InboundMeasurementRequests.ConfirmWeightResultRequest(
|
||||
0, new BigDecimal("30.000"), "KG", "OCR失败后人工确认"));
|
||||
|
||||
assertThat(confirmed.recognitionStatus()).isEqualTo("CONFIRMED");
|
||||
assertThat(confirmed.grossWeightKg()).isEqualByComparingTo("30.000");
|
||||
assertThat(confirmed.netWeightKg()).isEqualByComparingTo("11.500");
|
||||
verify(repository, org.mockito.Mockito.times(2)).insertRevision(any(InboundWeightRevisionEntity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void weightPalletOptionsUsesInboundWarehouseWithoutCustomerScope() {
|
||||
InboundOrderEntity inbound = inbound("WAIT_MEASURE");
|
||||
@@ -799,9 +831,13 @@ class InboundMeasurementServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void editingAndResubmittingInboundMeasurementDoesNotRollBackMainStatus() {
|
||||
void approvedMeasurementCannotBeResubmittedOrMutateFrozenTotals() {
|
||||
InboundOrderEntity inbound = inbound("WAIT_SPLIT");
|
||||
inbound.setMeasureReviewStatus("APPROVED");
|
||||
inbound.setActualGrossWeightKg(new BigDecimal("40.000"));
|
||||
inbound.setActualNetWeightKg(new BigDecimal("30.000"));
|
||||
inbound.setActualVolumeCbm(new BigDecimal("2.0000"));
|
||||
inbound.setVolumeWeightKg(new BigDecimal("334.000"));
|
||||
InboundMeasurementEntity measurement = new InboundMeasurementEntity();
|
||||
measurement.setId(30L);
|
||||
measurement.setStatus("APPROVED");
|
||||
@@ -815,14 +851,17 @@ class InboundMeasurementServiceTest {
|
||||
when(repository.listWeights(1L, 10L)).thenReturn(List.of());
|
||||
when(repository.updateInbound(inbound)).thenReturn(true);
|
||||
|
||||
InboundMeasurementResponses.MeasurementSubmitted result = service.submit(1L, 10L, 9L,
|
||||
new InboundMeasurementRequests.SubmitRequest(30L, 2));
|
||||
assertThatThrownBy(() -> service.submit(1L, 10L, 9L,
|
||||
new InboundMeasurementRequests.SubmitRequest(30L, 2)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("审核完成");
|
||||
|
||||
assertThat(result.processStatus()).isEqualTo("WAIT_SPLIT");
|
||||
assertThat(result.measureReviewStatus()).isEqualTo("APPROVED");
|
||||
assertThat(measurement.getStatus()).isEqualTo("APPROVED");
|
||||
assertThat(inbound.getActualGrossWeightKg()).isEqualByComparingTo("40.000");
|
||||
assertThat(inbound.getActualNetWeightKg()).isEqualByComparingTo("30.000");
|
||||
assertThat(inbound.getActualVolumeCbm()).isEqualByComparingTo("2.0000");
|
||||
assertThat(inbound.getVolumeWeightKg()).isEqualByComparingTo("334.000");
|
||||
verify(repository, never()).updateMeasurement(any());
|
||||
verify(repository).updateInbound(inbound);
|
||||
verify(repository, never()).updateInbound(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+49
-4
@@ -91,6 +91,7 @@ class MeasurementReviewServiceTest {
|
||||
InboundMeasurementItemEntity item = new InboundMeasurementItemEntity();
|
||||
item.setPackageCount(5);
|
||||
item.setTotalVolumeCbm(new BigDecimal("0.7480"));
|
||||
item.setVolumeWeightKg(new BigDecimal("124.916"));
|
||||
when(fixture.repository.listMeasurementItems(10001L, 20L)).thenReturn(List.of(item));
|
||||
when(fixture.repository.transitionReview(10001L, 10L, 9L, 3, true, 20L)).thenReturn(1);
|
||||
when(fixture.repository.transitionMeasurement(10001L, 10L, 20L, "APPROVED")).thenReturn(1);
|
||||
@@ -118,6 +119,40 @@ class MeasurementReviewServiceTest {
|
||||
verify(fixture.repository, never()).transitionReview(anyLong(), anyLong(), anyLong(), anyInt(), anyBoolean(), anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("多SKU测量行的箱数、重量、体积和体积重守恒后才能进入WAIT_SPLIT")
|
||||
void shouldApproveMultipleCargoLinesOnlyWhenAllFrozenTotalsMatch() {
|
||||
Fixture fixture = fixture(false);
|
||||
InboundMeasurementItemEntity first = measurementItem(2, "0.3000", "50.100");
|
||||
InboundMeasurementItemEntity second = measurementItem(3, "0.4480", "74.816");
|
||||
when(fixture.repository.listMeasurementItems(10001L, 20L)).thenReturn(List.of(first, second));
|
||||
when(fixture.repository.transitionReview(10001L, 10L, 9L, 3, true, 20L)).thenReturn(1);
|
||||
when(fixture.repository.transitionMeasurement(10001L, 10L, 20L, "APPROVED")).thenReturn(1);
|
||||
|
||||
fixture.service.approve(10001L, 9L, "审核员", 10L, "approve-multi-sku",
|
||||
new MeasurementReviewRequest(20L, 3, null));
|
||||
|
||||
ArgumentCaptor<InboundStatusHistoryEntity> history =
|
||||
ArgumentCaptor.forClass(InboundStatusHistoryEntity.class);
|
||||
verify(fixture.repository).insertHistory(history.capture());
|
||||
assertThat(history.getValue().getToStatus()).isEqualTo("WAIT_SPLIT");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("体积或体积重任一层汇总不一致时审核零写入")
|
||||
void shouldRejectApprovalWhenVolumeSnapshotDoesNotConserve() {
|
||||
Fixture fixture = fixture(false);
|
||||
fixture.order.setActualVolumeCbm(new BigDecimal("0.7479"));
|
||||
|
||||
assertThatThrownBy(() -> fixture.service.approve(10001L, 9L, "审核员", 10L,
|
||||
"approve-volume-mismatch", new MeasurementReviewRequest(20L, 3, null)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("体积和体积重");
|
||||
|
||||
verify(fixture.repository, never()).transitionReview(anyLong(), anyLong(), anyLong(), anyInt(), anyBoolean(), anyLong());
|
||||
verify(fixture.repository, never()).transitionMeasurement(anyLong(), anyLong(), anyLong(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("驳回原因必填且状态推进为测量驳回")
|
||||
void shouldRequireRejectReason() {
|
||||
@@ -217,13 +252,15 @@ class MeasurementReviewServiceTest {
|
||||
order.setTotalPackageCount(5);
|
||||
order.setActualGrossWeightKg(new BigDecimal("1787.500"));
|
||||
order.setActualNetWeightKg(new BigDecimal("1747.500"));
|
||||
order.setActualVolumeCbm(new BigDecimal("0.7480"));
|
||||
order.setVolumeWeightKg(new BigDecimal("124.916"));
|
||||
InboundMeasurementEntity measurement = new InboundMeasurementEntity();
|
||||
measurement.setId(20L);
|
||||
measurement.setStatus("SUBMITTED");
|
||||
InboundMeasurementItemEntity item = new InboundMeasurementItemEntity();
|
||||
item.setPackageCount(5);
|
||||
item.setTotalVolumeCbm(new BigDecimal("0.7480"));
|
||||
item.setVolumeWeightKg(new BigDecimal("124.916"));
|
||||
measurement.setTotalPackageCount(5);
|
||||
measurement.setTotalVolumeCbm(new BigDecimal("0.7480"));
|
||||
measurement.setVolumeWeightKg(new BigDecimal("124.916"));
|
||||
InboundMeasurementItemEntity item = measurementItem(5, "0.7480", "124.916");
|
||||
when(repository.findOwned(10001L, 10L)).thenReturn(order);
|
||||
when(repository.findMeasurement(10001L, 10L, 20L)).thenReturn(measurement);
|
||||
when(repository.listMeasurementItems(10001L, 20L)).thenReturn(List.of(item));
|
||||
@@ -236,6 +273,14 @@ class MeasurementReviewServiceTest {
|
||||
return new Fixture(service, repository, idempotency, order, measurement);
|
||||
}
|
||||
|
||||
private InboundMeasurementItemEntity measurementItem(int packages, String volume, String volumeWeight) {
|
||||
InboundMeasurementItemEntity item = new InboundMeasurementItemEntity();
|
||||
item.setPackageCount(packages);
|
||||
item.setTotalVolumeCbm(new BigDecimal(volume));
|
||||
item.setVolumeWeightKg(new BigDecimal(volumeWeight));
|
||||
return item;
|
||||
}
|
||||
|
||||
private InboundWeightResultEntity confirmedWeight(String grossWeightKg, String netWeightKg) {
|
||||
InboundWeightResultEntity weight = new InboundWeightResultEntity();
|
||||
weight.setRecognitionStatus("CONFIRMED");
|
||||
|
||||
Reference in New Issue
Block a user