532 lines
26 KiB
Java
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;
|
|
}
|
|
}
|