Files
baiyue-firstleg/firstleg/src/test/java/com/baiyue/firstleg/service/InboundMeasurementServiceTest.java
T
2026-08-07 20:07:30 +08:00

532 lines
26 KiB
Java

package com.baiyue.firstleg.service;
import com.baiyue.common.core.exception.BizException;
import com.baiyue.common.core.api.ApiResponse;
import com.baiyue.firstleg.client.MeasurementImageClient;
import com.baiyue.firstleg.dto.InboundMeasurementRequests;
import com.baiyue.firstleg.dto.InboundMeasurementResponses;
import com.baiyue.firstleg.entity.InboundMeasurementEntity;
import com.baiyue.firstleg.entity.InboundMeasurementItemEntity;
import com.baiyue.firstleg.entity.InboundOrderEntity;
import com.baiyue.firstleg.entity.InboundWeightResultEntity;
import com.baiyue.firstleg.entity.InboundWeightRevisionEntity;
import com.baiyue.firstleg.repository.InboundMeasurementRepository;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.mockito.ArgumentCaptor;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.context.TestPropertySource;
import java.math.BigDecimal;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
@DisplayName("平台入库测量应用服务")
@SpringJUnitConfig(InboundMeasurementService.class)
@TestPropertySource(properties = "baiyue.security.internal-service-token=internal-token")
class InboundMeasurementServiceTest {
@MockBean private InboundMeasurementRepository repository;
@MockBean private MeasurementBatchService batchService;
@MockBean private MeasurementImageClient imageClient;
@Resource private InboundMeasurementService service;
@Test
void customerCannotReadAnotherCustomersMeasurement() {
assertThatThrownBy(() -> service.detail(2L, 10L))
.isInstanceOf(BizException.class)
.hasMessageContaining("入库单不存在");
verify(repository).findInbound(2L, 10L);
verify(repository, never()).findInbound(1L, 10L);
verify(repository, never()).listWeights(anyLong(), anyLong());
}
@Test
void correctingWeightKeepsOcrOriginalAndWritesImmutableRevision() {
InboundOrderEntity inbound = inbound("MEASURING");
InboundWeightResultEntity weight = weight(20L, "12.500", "KG", "PENDING_CONFIRM", 4);
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.findWeight(1L, 10L, 20L)).thenReturn(weight);
when(repository.updateWeight(weight)).thenReturn(true);
service.correctWeightResult(1L, 10L, 20L, 9L, "操作员",
new InboundMeasurementRequests.CorrectWeightResultRequest(
4, new BigDecimal("13.200"), "kg", "秤面显示修正"));
assertThat(weight.getOcrWeightValue()).isEqualByComparingTo("12.500");
assertThat(weight.getOcrWeightUnit()).isEqualTo("KG");
assertThat(weight.getAdjustedWeightValue()).isEqualByComparingTo("13.200");
ArgumentCaptor<InboundWeightRevisionEntity> revision =
ArgumentCaptor.forClass(InboundWeightRevisionEntity.class);
verify(repository).insertRevision(revision.capture());
assertThat(revision.getValue().getRevisionNo()).isEqualTo(5);
assertThat(revision.getValue().getBeforeWeightValue()).isEqualByComparingTo("12.500");
assertThat(revision.getValue().getAfterWeightValue()).isEqualByComparingTo("13.200");
}
@Test
void detailReturnsStandardPalletRecommendationWithoutAllocatingPallet() {
when(repository.findInbound(1L, 10L)).thenReturn(inbound("MEASURE_PENDING"));
when(repository.listWeights(1L, 10L)).thenReturn(List.of());
InboundMeasurementResponses.Detail result = service.detail(1L, 10L);
assertThat(result.recommendedPalletType()).isEqualTo("STANDARD");
verify(repository, never()).updateInbound(any());
}
@Test
void creatingWeightResultNormalizesProviderConfidenceAtBusinessBoundary() {
InboundOrderEntity inbound = inbound("WAIT_MEASURE");
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
InboundMeasurementResponses.WeightResult result = service.createWeightResult(
1L, 10L, 9L,
new InboundMeasurementRequests.CreateWeightResultRequest(
120L, "FILE_WEIGHT_OCR", "285.5", new BigDecimal("285.500"), "KG",
new BigDecimal("0.5097191334")));
ArgumentCaptor<InboundWeightResultEntity> saved =
ArgumentCaptor.forClass(InboundWeightResultEntity.class);
verify(repository).insertWeight(saved.capture());
assertThat(saved.getValue().getConfidence()).isEqualByComparingTo("0.50972");
assertThat(result.confidence()).isEqualByComparingTo("0.50972");
}
@Test
void confirmingLbWeightConvertsToKgAndRecalculatesOnlyConfirmedImages() {
InboundOrderEntity inbound = inbound("WAIT_MEASURE");
InboundWeightResultEntity current = weight(20L, "10.000", "LB", "PENDING_CONFIRM", 0);
InboundWeightResultEntity previous = weight(21L, "2.000", "KG", "CONFIRMED", 1);
previous.setFinalWeightKg(new BigDecimal("2.000"));
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.findWeight(1L, 10L, 20L)).thenReturn(current);
when(repository.updateWeight(current)).thenReturn(true);
when(repository.listWeights(1L, 10L)).thenReturn(List.of(current, previous));
when(repository.updateInbound(inbound)).thenReturn(true);
InboundMeasurementResponses.WeightResult response = service.confirmWeightResult(
1L, 10L, 20L, 9L, "操作员",
new InboundMeasurementRequests.ConfirmWeightResultRequest(0, null, null, null));
assertThat(response.finalWeightKg()).isEqualByComparingTo("4.536");
assertThat(inbound.getActualGrossWeightKg()).isEqualByComparingTo("6.536");
assertThat(inbound.getProcessStatus()).isEqualTo("MEASURING");
verify(repository).insertRevision(any(InboundWeightRevisionEntity.class));
}
@ParameterizedTest
@CsvSource({
"kg,2.000",
"KGS,2.000",
"lb,0.907",
"LBS,0.907",
"' lbs ',0.907"
})
void confirmingAcceptsSupportedUnitAliases(String unit, String expectedKg) {
InboundOrderEntity inbound = inbound("WAIT_MEASURE");
InboundWeightResultEntity weight = weight(20L, "1.000", "KG", "PENDING_CONFIRM", 0);
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
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.updateInbound(inbound)).thenReturn(true);
InboundMeasurementResponses.WeightResult response = service.confirmWeightResult(
1L, 10L, 20L, 9L, "操作员",
new InboundMeasurementRequests.ConfirmWeightResultRequest(
0, new BigDecimal("2.000"), unit, "单位边界测试"));
assertThat(response.adjustedWeightUnit()).isEqualTo(
unit.trim().toUpperCase().startsWith("LB") ? "LB" : "KG");
assertThat(response.finalWeightKg()).isEqualByComparingTo(expectedKg);
assertThat(response.version()).isEqualTo(2);
}
@Test
void confirmingAcceptsSmallestRepresentableKgWeight() {
InboundOrderEntity inbound = inbound("WAIT_MEASURE");
InboundWeightResultEntity weight = weight(20L, "0.001", "KG", "PENDING_CONFIRM", 0);
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
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.updateInbound(inbound)).thenReturn(true);
InboundMeasurementResponses.WeightResult response = service.confirmWeightResult(
1L, 10L, 20L, 9L, "操作员",
new InboundMeasurementRequests.ConfirmWeightResultRequest(0, null, null, null));
assertThat(response.finalWeightKg()).isEqualByComparingTo("0.001");
assertThat(inbound.getActualGrossWeightKg()).isEqualByComparingTo("0.001");
}
@Test
void confirmingRejectsLbWeightThatRoundsToZeroKgBeforePersisting() {
InboundOrderEntity inbound = inbound("WAIT_MEASURE");
InboundWeightResultEntity weight = weight(20L, "1.000", "KG", "PENDING_CONFIRM", 0);
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.findWeight(1L, 10L, 20L)).thenReturn(weight);
assertThatThrownBy(() -> service.confirmWeightResult(
1L, 10L, 20L, 9L, "操作员",
new InboundMeasurementRequests.ConfirmWeightResultRequest(
0, new BigDecimal("0.001"), "LB", "极小重量边界测试")))
.isInstanceOf(BizException.class)
.hasMessageContaining("换算后重量不能小于 0.001 KG");
verify(repository, never()).updateWeight(any());
verify(repository, never()).insertRevision(any());
verify(repository, never()).updateInbound(any());
}
@Test
void confirmingRejectsOcrLbWeightThatRoundsToZeroKg() {
InboundOrderEntity inbound = inbound("WAIT_MEASURE");
InboundWeightResultEntity weight = weight(20L, "0.001", "LB", "PENDING_CONFIRM", 0);
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.findWeight(1L, 10L, 20L)).thenReturn(weight);
assertThatThrownBy(() -> service.confirmWeightResult(
1L, 10L, 20L, 9L, "操作员",
new InboundMeasurementRequests.ConfirmWeightResultRequest(0, null, null, null)))
.isInstanceOf(BizException.class)
.hasMessageContaining("换算后重量不能小于 0.001 KG");
verify(repository, never()).updateWeight(any());
verify(repository, never()).insertRevision(any());
verify(repository, never()).updateInbound(any());
}
@Test
void confirmingRejectsUnsupportedUnitBeforePersisting() {
InboundOrderEntity inbound = inbound("WAIT_MEASURE");
InboundWeightResultEntity weight = weight(20L, "285.500", "KG", "PENDING_CONFIRM", 0);
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.findWeight(1L, 10L, 20L)).thenReturn(weight);
assertThatThrownBy(() -> service.confirmWeightResult(
1L, 10L, 20L, 9L, "操作员",
new InboundMeasurementRequests.ConfirmWeightResultRequest(
0, new BigDecimal("286.125"), "G", "错误单位测试")))
.isInstanceOf(BizException.class)
.hasMessageContaining("重量单位仅支持 KG 或 LB");
verify(repository, never()).updateWeight(any());
verify(repository, never()).insertRevision(any());
}
@Test
void confirmingAdjustedWeightWritesCorrectionAndConfirmationInOneTransaction() {
InboundOrderEntity inbound = inbound("WAIT_MEASURE");
InboundWeightResultEntity weight = weight(20L, "285.500", "KG", "PENDING_CONFIRM", 0);
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
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.updateInbound(inbound)).thenReturn(true);
InboundMeasurementResponses.WeightResult response = service.confirmWeightResult(
1L, 10L, 20L, 9L, "操作员",
new InboundMeasurementRequests.ConfirmWeightResultRequest(
0, new BigDecimal("286.125"), "kg", "OCR 原值 285.500 KG,人工确认 286.125 KG"));
assertThat(response.adjustedWeightValue()).isEqualByComparingTo("286.125");
assertThat(response.finalWeightKg()).isEqualByComparingTo("286.125");
assertThat(response.recognitionStatus()).isEqualTo("CONFIRMED");
assertThat(response.version()).isEqualTo(2);
assertThat(inbound.getActualGrossWeightKg()).isEqualByComparingTo("286.125");
verify(repository, times(2)).updateWeight(weight);
ArgumentCaptor<InboundWeightRevisionEntity> revisions =
ArgumentCaptor.forClass(InboundWeightRevisionEntity.class);
verify(repository, times(2)).insertRevision(revisions.capture());
assertThat(revisions.getAllValues()).extracting(
InboundWeightRevisionEntity::getRevisionNo,
InboundWeightRevisionEntity::getAction)
.containsExactly(tuple(1, "CORRECT"), tuple(2, "CONFIRM"));
assertThat(revisions.getAllValues().get(0).getReason())
.isEqualTo("OCR 原值 285.500 KG,人工确认 286.125 KG");
}
@Test
void confirmingRejectsPartialAdjustmentBeforePersisting() {
InboundOrderEntity inbound = inbound("WAIT_MEASURE");
InboundWeightResultEntity weight = weight(20L, "285.500", "KG", "PENDING_CONFIRM", 0);
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.findWeight(1L, 10L, 20L)).thenReturn(weight);
assertThatThrownBy(() -> service.confirmWeightResult(
1L, 10L, 20L, 9L, "操作员",
new InboundMeasurementRequests.ConfirmWeightResultRequest(
0, new BigDecimal("286.125"), null, null)))
.isInstanceOf(BizException.class)
.hasMessageContaining("有效重量、单位和修改原因");
verify(repository, never()).updateWeight(any());
verify(repository, never()).insertRevision(any());
}
@Test
void confirmingRejectsEveryPartialAdjustmentCombinationBeforePersisting() {
InboundOrderEntity inbound = inbound("WAIT_MEASURE");
InboundWeightResultEntity weight = weight(20L, "285.500", "KG", "PENDING_CONFIRM", 0);
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.findWeight(1L, 10L, 20L)).thenReturn(weight);
List<InboundMeasurementRequests.ConfirmWeightResultRequest> partialRequests = List.of(
new InboundMeasurementRequests.ConfirmWeightResultRequest(0, null, "KG", null),
new InboundMeasurementRequests.ConfirmWeightResultRequest(0, null, null, "人工修正"),
new InboundMeasurementRequests.ConfirmWeightResultRequest(
0, new BigDecimal("286.125"), " ", " ")
);
partialRequests.forEach(request -> assertThatThrownBy(() -> service.confirmWeightResult(
1L, 10L, 20L, 9L, "操作员", request))
.isInstanceOf(BizException.class)
.hasMessageContaining("有效重量、单位和修改原因"));
verify(repository, never()).updateWeight(any());
verify(repository, never()).insertRevision(any());
verify(repository, never()).updateInbound(any());
}
@Test
void confirmingAnAlreadyConfirmedWeightWithCurrentVersionIsIdempotent() {
InboundOrderEntity inbound = inbound("MEASURING");
InboundWeightResultEntity weight = weight(20L, "285.500", "KG", "CONFIRMED", 2);
weight.setFinalWeightKg(new BigDecimal("285.500"));
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.findWeight(1L, 10L, 20L)).thenReturn(weight);
InboundMeasurementResponses.WeightResult response = service.confirmWeightResult(
1L, 10L, 20L, 9L, "操作员",
new InboundMeasurementRequests.ConfirmWeightResultRequest(2, null, null, null));
assertThat(response.recognitionStatus()).isEqualTo("CONFIRMED");
assertThat(response.version()).isEqualTo(2);
verify(repository, never()).updateWeight(any());
verify(repository, never()).insertRevision(any());
verify(repository, never()).updateInbound(any());
}
@Test
void confirmingWithStaleVersionDoesNotTreatRequestAsIdempotent() {
InboundOrderEntity inbound = inbound("MEASURING");
InboundWeightResultEntity weight = weight(20L, "285.500", "KG", "CONFIRMED", 2);
weight.setFinalWeightKg(new BigDecimal("285.500"));
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.findWeight(1L, 10L, 20L)).thenReturn(weight);
assertThatThrownBy(() -> service.confirmWeightResult(
1L, 10L, 20L, 9L, "操作员",
new InboundMeasurementRequests.ConfirmWeightResultRequest(1, null, null, null)))
.isInstanceOf(BizException.class)
.hasMessageContaining("版本已变化");
verify(repository, never()).updateWeight(any());
verify(repository, never()).insertRevision(any());
}
@Test
void confirmingAdjustedWeightStopsBeforeRecalculationWhenConfirmUpdateConflicts() {
InboundOrderEntity inbound = inbound("WAIT_MEASURE");
InboundWeightResultEntity weight = weight(20L, "285.500", "KG", "PENDING_CONFIRM", 0);
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.findWeight(1L, 10L, 20L)).thenReturn(weight);
when(repository.updateWeight(weight)).thenReturn(true, false);
assertThatThrownBy(() -> service.confirmWeightResult(
1L, 10L, 20L, 9L, "操作员",
new InboundMeasurementRequests.ConfirmWeightResultRequest(
0, new BigDecimal("286.125"), "KG", "并发冲突测试")))
.isInstanceOf(BizException.class)
.hasMessageContaining("版本已变化");
verify(repository, times(2)).updateWeight(weight);
verify(repository, times(1)).insertRevision(any(InboundWeightRevisionEntity.class));
verify(repository, never()).listWeights(anyLong(), anyLong());
verify(repository, never()).updateInbound(any());
}
@Test
void deletingPendingWeightRemovesResultAndOwnedImage() {
InboundOrderEntity inbound = inbound("MEASURING");
InboundWeightResultEntity weight = weight(20L, "285.500", "KG", "PENDING_CONFIRM", 1);
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.findWeight(1L, 10L, 20L)).thenReturn(weight);
when(repository.deleteWeight(1L, 10L, 20L, 1)).thenReturn(true);
when(imageClient.delete("internal-token", 9L, 1L, 10L, 120L))
.thenReturn(ApiResponse.success(null));
service.deleteWeightResult(1L, 10L, 20L, 1, 9L);
verify(repository).deleteWeight(1L, 10L, 20L, 1);
verify(imageClient).delete("internal-token", 9L, 1L, 10L, 120L);
verify(repository, never()).updateInbound(any());
}
@Test
void deletingLastConfirmedWeightClearsInboundTotal() {
InboundOrderEntity inbound = inbound("MEASURING");
inbound.setActualGrossWeightKg(new BigDecimal("285.500"));
InboundWeightResultEntity weight = weight(20L, "285.500", "KG", "CONFIRMED", 2);
weight.setFinalWeightKg(new BigDecimal("285.500"));
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.findWeight(1L, 10L, 20L)).thenReturn(weight);
when(repository.deleteWeight(1L, 10L, 20L, 2)).thenReturn(true);
when(repository.listWeights(1L, 10L)).thenReturn(List.of());
when(repository.updateInbound(inbound)).thenReturn(true);
when(imageClient.delete("internal-token", 9L, 1L, 10L, 120L))
.thenReturn(ApiResponse.success(null));
service.deleteWeightResult(1L, 10L, 20L, 2, 9L);
assertThat(inbound.getActualGrossWeightKg()).isNull();
verify(repository).updateInbound(inbound);
}
@Test
void deletingWeightRejectsStaleVersionBeforeCallingFileService() {
InboundOrderEntity inbound = inbound("MEASURING");
InboundWeightResultEntity weight = weight(20L, "285.500", "KG", "PENDING_CONFIRM", 2);
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.findWeight(1L, 10L, 20L)).thenReturn(weight);
assertThatThrownBy(() -> service.deleteWeightResult(1L, 10L, 20L, 1, 9L))
.isInstanceOf(BizException.class)
.hasMessageContaining("版本已变化");
verify(repository, never()).deleteWeight(anyLong(), anyLong(), anyLong(), anyInt());
verifyNoInteractions(imageClient);
}
@Test
void submitAdvancesOnlyToMeasurePendingAfterAllWeightsConfirmed() {
InboundOrderEntity inbound = inbound("MEASURING");
InboundMeasurementEntity measurement = new InboundMeasurementEntity();
measurement.setId(30L);
measurement.setTenantId(1L);
measurement.setInboundId(10L);
measurement.setStatus("DRAFT");
measurement.setVersion(2);
measurement.setTotalPackageCount(3);
measurement.setTotalVolumeCbm(new BigDecimal("1.2345"));
measurement.setVolumeWeightKg(new BigDecimal("206.162"));
InboundMeasurementItemEntity item = new InboundMeasurementItemEntity();
item.setPackageCount(3);
item.setSourceImageFileId(500L);
InboundWeightResultEntity weight = weight(20L, "20.000", "KG", "CONFIRMED", 1);
weight.setFinalWeightKg(new BigDecimal("20.000"));
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.findMeasurement(1L, 10L, 30L)).thenReturn(measurement);
when(repository.listItems(1L, 30L)).thenReturn(List.of(item));
when(repository.listWeights(1L, 10L)).thenReturn(List.of(weight));
when(repository.updateMeasurement(measurement)).thenReturn(true);
when(repository.updateInbound(inbound)).thenReturn(true);
InboundMeasurementResponses.MeasurementSubmitted result = service.submit(
1L, 10L, 9L, new InboundMeasurementRequests.SubmitRequest(30L, 2));
assertThat(result.processStatus()).isEqualTo("MEASURE_PENDING");
assertThat(result.recommendedPalletType()).isEqualTo("STANDARD");
assertThat(inbound.getMeasureReviewStatus()).isEqualTo("PENDING");
assertThat(measurement.getStatus()).isEqualTo("SUBMITTED");
assertThat(inbound.getActualGrossWeightKg()).isEqualByComparingTo("20.000");
assertThat(inbound.getActualVolumeCbm()).isEqualByComparingTo("1.2345");
}
@Test
void submitDoesNotBlockOnUnconfirmedWeight() {
InboundOrderEntity inbound = inbound("MEASURING");
InboundMeasurementEntity measurement = new InboundMeasurementEntity();
measurement.setId(30L);
measurement.setStatus("DRAFT");
measurement.setVersion(0);
InboundMeasurementItemEntity item = new InboundMeasurementItemEntity();
item.setPackageCount(3);
item.setSourceImageFileId(500L);
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.findMeasurement(1L, 10L, 30L)).thenReturn(measurement);
when(repository.listItems(1L, 30L)).thenReturn(List.of(item));
when(repository.listWeights(1L, 10L)).thenReturn(List.of(
weight(20L, "20", "KG", "PENDING_CONFIRM", 0)));
when(repository.updateMeasurement(measurement)).thenReturn(true);
when(repository.updateInbound(inbound)).thenReturn(true);
InboundMeasurementResponses.MeasurementSubmitted result = service.submit(1L, 10L, 9L,
new InboundMeasurementRequests.SubmitRequest(30L, 0));
assertThat(result.processStatus()).isEqualTo("MEASURE_PENDING");
assertThat(inbound.getActualGrossWeightKg()).isNull();
verify(repository).updateMeasurement(measurement);
verify(repository).updateInbound(inbound);
}
@Test
void editingAndResubmittingInboundMeasurementDoesNotRollBackMainStatus() {
InboundOrderEntity inbound = inbound("WAIT_SPLIT");
inbound.setMeasureReviewStatus("APPROVED");
InboundMeasurementEntity measurement = new InboundMeasurementEntity();
measurement.setId(30L);
measurement.setStatus("APPROVED");
measurement.setVersion(2);
measurement.setTotalPackageCount(4);
measurement.setTotalVolumeCbm(new BigDecimal("2.0000"));
measurement.setVolumeWeightKg(new BigDecimal("334.000"));
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.findMeasurement(1L, 10L, 30L)).thenReturn(measurement);
when(repository.listItems(1L, 30L)).thenReturn(List.of());
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));
assertThat(result.processStatus()).isEqualTo("WAIT_SPLIT");
assertThat(result.measureReviewStatus()).isEqualTo("APPROVED");
assertThat(measurement.getStatus()).isEqualTo("APPROVED");
verify(repository, never()).updateMeasurement(any());
verify(repository).updateInbound(inbound);
}
private InboundOrderEntity inbound(String status) {
InboundOrderEntity inbound = new InboundOrderEntity();
inbound.setId(10L);
inbound.setTenantId(1L);
inbound.setProcessStatus(status);
inbound.setTotalPackageCount(3);
inbound.setVersion(0);
return inbound;
}
private InboundWeightResultEntity weight(long id, String value, String unit,
String status, int version) {
InboundWeightResultEntity weight = new InboundWeightResultEntity();
weight.setId(id);
weight.setTenantId(1L);
weight.setInboundId(10L);
weight.setFileId(id + 100L);
weight.setOcrWeightValue(new BigDecimal(value));
weight.setOcrWeightUnit(unit);
weight.setRecognitionStatus(status);
weight.setVersion(version);
return weight;
}
}