168 lines
8.0 KiB
Java
168 lines
8.0 KiB
Java
package com.baiyue.firstleg.service;
|
|
|
|
import com.baiyue.common.core.exception.BizException;
|
|
import com.baiyue.firstleg.dto.MeasurementBatchCommand;
|
|
import com.baiyue.firstleg.domain.CustomerDimensionBoxType;
|
|
import com.baiyue.firstleg.entity.CustomerDimensionConfigEntity;
|
|
import com.baiyue.firstleg.entity.InboundMeasurementEntity;
|
|
import com.baiyue.firstleg.entity.InboundMeasurementItemEntity;
|
|
import com.baiyue.firstleg.entity.InboundOrderEntity;
|
|
import com.baiyue.firstleg.repository.InboundMeasurementRepository;
|
|
import com.baiyue.firstleg.repository.CustomerDimensionConfigRepository;
|
|
import jakarta.annotation.Resource;
|
|
import org.junit.jupiter.api.BeforeEach;
|
|
import org.junit.jupiter.api.DisplayName;
|
|
import org.junit.jupiter.api.Test;
|
|
import org.mockito.ArgumentCaptor;
|
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
|
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
|
|
|
import java.math.BigDecimal;
|
|
import java.time.LocalDateTime;
|
|
import java.util.List;
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
import static org.mockito.ArgumentMatchers.any;
|
|
import static org.mockito.Mockito.mock;
|
|
import static org.mockito.Mockito.never;
|
|
import static org.mockito.Mockito.verify;
|
|
import static org.mockito.Mockito.when;
|
|
|
|
@DisplayName("测量批次共享领域服务")
|
|
@SpringJUnitConfig({MeasurementBatchService.class, CustomerDimensionWeightingService.class})
|
|
class MeasurementBatchServiceTest {
|
|
@MockBean private InboundMeasurementRepository repository;
|
|
@MockBean private CustomerDimensionConfigRepository dimensionConfigs;
|
|
@Resource private MeasurementBatchService service;
|
|
|
|
@BeforeEach
|
|
void setUp() {
|
|
when(repository.findInbound(1L, 10L)).thenReturn(inbound());
|
|
when(dimensionConfigs.findAll(1L)).thenReturn(dimensionRules(1L));
|
|
org.mockito.Mockito.doAnswer(invocation -> {
|
|
InboundMeasurementEntity entity = invocation.getArgument(0);
|
|
entity.setId(100L);
|
|
return null;
|
|
}).when(repository).insertMeasurement(any());
|
|
}
|
|
|
|
@Test
|
|
void manualAndExternalUseSameTablesAndExternalSaveNeverAdvancesInbound() {
|
|
MeasurementBatchCommand command = new MeasurementBatchCommand(
|
|
1L, 10L, null, 0, "THIRD_PARTY", "DEVICE_VENDOR", "EVENT-001",
|
|
"D-01", "YW-01", LocalDateTime.now(), "{}", null, null, null,
|
|
null, 0L, List.of(item(null)));
|
|
|
|
InboundMeasurementEntity saved = service.saveBatch(command);
|
|
|
|
assertThat(saved.getSourceType()).isEqualTo("THIRD_PARTY");
|
|
assertThat(saved.getStatus()).isEqualTo("RECEIVED");
|
|
assertThat(saved.getTotalPackageCount()).isEqualTo(2);
|
|
ArgumentCaptor<List<InboundMeasurementItemEntity>> items = ArgumentCaptor.forClass(List.class);
|
|
verify(repository).replaceItems(org.mockito.ArgumentMatchers.eq(1L),
|
|
org.mockito.ArgumentMatchers.eq(100L), items.capture());
|
|
assertThat(items.getValue().get(0).getUnitVolumeCbm()).isEqualByComparingTo("0.0510");
|
|
assertThat(items.getValue().get(0).getTotalVolumeCbm()).isEqualByComparingTo("0.1020");
|
|
assertThat(items.getValue().get(0).getOuterLengthCm()).isEqualByComparingTo("44.000");
|
|
assertThat(items.getValue().get(0).getOuterWidthCm()).isEqualByComparingTo("34.000");
|
|
assertThat(items.getValue().get(0).getOuterHeightCm()).isEqualByComparingTo("34.000");
|
|
assertThat(items.getValue().get(0).getCalculationRuleVersion())
|
|
.isEqualTo("CUSTOMER_DIMENSION_MEDIUM_V0");
|
|
assertThat(items.getValue().get(0).getGirthCm()).isEqualByComparingTo("140.000");
|
|
verify(repository, never()).updateInbound(any());
|
|
}
|
|
|
|
@Test
|
|
void manualDraftCalculatesVolumeAndVolumeWeightOnServer() {
|
|
MeasurementBatchCommand command = new MeasurementBatchCommand(
|
|
1L, 10L, null, 0, "MANUAL", "PLATFORM", null, null, null,
|
|
LocalDateTime.now(), null, "CKW-1", new BigDecimal("20"),
|
|
new BigDecimal("0.1"), "服装", 9L, List.of(item(new BigDecimal("3.25"))));
|
|
|
|
InboundMeasurementEntity saved = service.saveBatch(command);
|
|
|
|
assertThat(saved.getStatus()).isEqualTo("DRAFT");
|
|
assertThat(saved.getTotalVolumeCbm()).isEqualByComparingTo("0.1020");
|
|
assertThat(saved.getVolumeWeightKg()).isEqualByComparingTo("17.034");
|
|
ArgumentCaptor<List<InboundMeasurementItemEntity>> items = ArgumentCaptor.forClass(List.class);
|
|
verify(repository).replaceItems(org.mockito.ArgumentMatchers.eq(1L),
|
|
org.mockito.ArgumentMatchers.eq(100L), items.capture());
|
|
assertThat(items.getValue().get(0).getInboundDetailId()).isEqualTo(80001L);
|
|
}
|
|
|
|
@Test
|
|
void staleDraftVersionIsRejectedBeforeReplacingItems() {
|
|
InboundMeasurementEntity existing = new InboundMeasurementEntity();
|
|
existing.setId(100L);
|
|
existing.setTenantId(1L);
|
|
existing.setInboundId(10L);
|
|
existing.setSourceType("MANUAL");
|
|
existing.setStatus("DRAFT");
|
|
existing.setVersion(3);
|
|
when(repository.findMeasurement(1L, 10L, 100L)).thenReturn(existing);
|
|
MeasurementBatchCommand command = new MeasurementBatchCommand(
|
|
1L, 10L, 100L, 2, "MANUAL", "PLATFORM", null, null, null,
|
|
LocalDateTime.now(), null, null, null, null, null, 9L,
|
|
List.of(item(BigDecimal.ONE)));
|
|
|
|
assertThatThrownBy(() -> service.saveBatch(command))
|
|
.isInstanceOf(BizException.class)
|
|
.hasMessageContaining("其他人修改");
|
|
verify(repository, never()).replaceItems(
|
|
org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong(), any());
|
|
}
|
|
|
|
@Test
|
|
void approvedManualMeasurementCanBeEditedAsDraftBeforeReviewCompletes() {
|
|
InboundMeasurementEntity existing = new InboundMeasurementEntity();
|
|
existing.setId(100L);
|
|
existing.setTenantId(1L);
|
|
existing.setInboundId(10L);
|
|
existing.setSourceType("MANUAL");
|
|
existing.setStatus("APPROVED");
|
|
existing.setVersion(3);
|
|
when(repository.findMeasurement(1L, 10L, 100L)).thenReturn(existing);
|
|
when(repository.updateMeasurement(existing)).thenReturn(true);
|
|
|
|
MeasurementBatchCommand command = new MeasurementBatchCommand(
|
|
1L, 10L, 100L, 3, "MANUAL", "PLATFORM", null, null, null,
|
|
LocalDateTime.now(), null, "CKW-2", new BigDecimal("21"),
|
|
new BigDecimal("0.2"), "服装", 9L, List.of(item(BigDecimal.ONE)));
|
|
|
|
InboundMeasurementEntity saved = service.saveBatch(command);
|
|
|
|
assertThat(saved.getStatus()).isEqualTo("DRAFT");
|
|
verify(repository).updateMeasurement(existing);
|
|
verify(repository).replaceItems(org.mockito.ArgumentMatchers.eq(1L),
|
|
org.mockito.ArgumentMatchers.eq(100L), any());
|
|
}
|
|
|
|
private MeasurementBatchCommand.Item item(BigDecimal unitWeight) {
|
|
return new MeasurementBatchCommand.Item(
|
|
80001L, "001", "A", 2, new BigDecimal("40"), new BigDecimal("30"),
|
|
new BigDecimal("20"), 500L, null,
|
|
new BigDecimal("41"), new BigDecimal("31"), new BigDecimal("21"), "备注");
|
|
}
|
|
|
|
private InboundOrderEntity inbound() {
|
|
InboundOrderEntity inbound = new InboundOrderEntity();
|
|
inbound.setId(10L);
|
|
inbound.setTenantId(1L);
|
|
inbound.setProcessStatus("WAIT_MEASURE");
|
|
inbound.setVersion(0);
|
|
return inbound;
|
|
}
|
|
|
|
private List<CustomerDimensionConfigEntity> dimensionRules(long tenantId) {
|
|
return java.util.Arrays.stream(CustomerDimensionBoxType.values()).map(type -> {
|
|
CustomerDimensionConfigEntity rule = new CustomerDimensionConfigEntity();
|
|
rule.setTenantId(tenantId); rule.setBoxType(type); rule.setVersion(0);
|
|
rule.setInnerLengthCm(type.defaultLengthCm()); rule.setInnerWidthCm(type.defaultWidthCm());
|
|
rule.setInnerHeightCm(type.defaultHeightCm());
|
|
rule.setEdgeAdditionCm(new BigDecimal("2.000"));
|
|
return rule;
|
|
}).toList();
|
|
}
|
|
}
|