优化
This commit is contained in:
+28
@@ -0,0 +1,28 @@
|
||||
package com.baiyue.firstleg.repository;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class InboundCartonLabelSqlContractTest {
|
||||
@Test
|
||||
void baseSchemaAndExistingDatabaseMigrationKeepStableCartonKeys() throws Exception {
|
||||
String schema = resource("db/phase2-inbound-schema.sql");
|
||||
String migration = resource("db/phase2-inbound-carton-label.sql");
|
||||
|
||||
assertThat(schema).contains("CREATE TABLE IF NOT EXISTS fl_inbound_carton_label")
|
||||
.contains("UNIQUE KEY uk_carton_label_box_code (tenant_id, box_code)")
|
||||
.contains("UNIQUE KEY uk_carton_label_index (tenant_id, inbound_id, carton_index)")
|
||||
.contains("inbound_detail_id BIGINT UNSIGNED NOT NULL");
|
||||
assertThat(migration).contains("CREATE TABLE IF NOT EXISTS fl_inbound_carton_label")
|
||||
.contains("固定二维码内容:入仓码#总箱数-箱下标")
|
||||
.contains("idx_carton_label_detail (tenant_id, inbound_id, inbound_detail_id)");
|
||||
}
|
||||
|
||||
private String resource(String path) throws Exception {
|
||||
return new ClassPathResource(path).getContentAsString(StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
package com.baiyue.firstleg.service;
|
||||
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.firstleg.client.OrderCargoClient;
|
||||
import com.baiyue.firstleg.entity.InboundCartonLabelEntity;
|
||||
import com.baiyue.firstleg.entity.InboundOrderEntity;
|
||||
import com.baiyue.firstleg.repository.InboundCartonLabelRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
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.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class InboundCartonLabelServiceTest {
|
||||
@Mock private InboundCartonLabelRepository repository;
|
||||
@Mock private OrderCargoClient orderCargoClient;
|
||||
private InboundCartonLabelService service;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
service = new InboundCartonLabelService();
|
||||
ReflectionTestUtils.setField(service, "repository", repository);
|
||||
ReflectionTestUtils.setField(service, "orderCargoClient", orderCargoClient);
|
||||
ReflectionTestUtils.setField(service, "internalToken", "internal-token");
|
||||
}
|
||||
|
||||
@Test
|
||||
void firstAllocationUsesCargoOrderAndFreezesEveryPhysicalCarton() {
|
||||
InboundOrderEntity inbound = inbound();
|
||||
when(repository.lockInbound(10001L, 70001L)).thenReturn(inbound);
|
||||
when(repository.findByInbound(10001L, 70001L)).thenReturn(new ArrayList<>());
|
||||
var second = cargo(80002L, 2, 2, "50", "30", "20");
|
||||
var first = cargo(80001L, 1, 3, "60", "40", "30");
|
||||
when(orderCargoClient.listForCartonLabels("internal-token", 10001L, 60001L))
|
||||
.thenReturn(ApiResponse.success(List.of(second, first)));
|
||||
List<InboundCartonLabelEntity> inserted = new ArrayList<>();
|
||||
org.mockito.Mockito.doAnswer(invocation -> {
|
||||
inserted.add(invocation.getArgument(0));
|
||||
return null;
|
||||
}).when(repository).insert(any());
|
||||
|
||||
var batch = service.getOrCreate(10001L, 70001L);
|
||||
|
||||
assertThat(batch.totalCount()).isEqualTo(5);
|
||||
assertThat(batch.labels()).extracting(label -> label.boxCode())
|
||||
.containsExactly("PCHK2608040174#5-1", "PCHK2608040174#5-2", "PCHK2608040174#5-3",
|
||||
"PCHK2608040174#5-4", "PCHK2608040174#5-5");
|
||||
assertThat(batch.labels()).extracting(label -> label.inboundDetailId())
|
||||
.containsExactly(80001L, 80001L, 80001L, 80002L, 80002L);
|
||||
assertThat(batch.labels().get(0).boxSpecification()).isEqualTo("60x40x30cm");
|
||||
assertThat(batch.labels().get(0).cartonText()).isEqualTo("CTNS:5-1");
|
||||
assertThat(inserted).hasSize(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void repeatedAndPartialPrintsReadFrozenMappingWithoutReallocation() {
|
||||
InboundOrderEntity inbound = inbound();
|
||||
List<InboundCartonLabelEntity> existing = labels(inbound, 5);
|
||||
when(repository.lockInbound(10001L, 70001L)).thenReturn(inbound);
|
||||
when(repository.findByInbound(10001L, 70001L)).thenReturn(existing);
|
||||
|
||||
var batch = service.list(10001L, 70001L, List.of(5, 2, 2));
|
||||
|
||||
assertThat(batch.totalCount()).isEqualTo(5);
|
||||
assertThat(batch.labels()).extracting(label -> label.cartonIndex()).containsExactly(2, 5);
|
||||
verify(orderCargoClient, never()).listForCartonLabels(any(String.class),
|
||||
org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong());
|
||||
verify(repository, never()).insert(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolvesBoxCodeInsideCustomerBoundary() {
|
||||
InboundCartonLabelEntity label = labels(inbound(), 1).get(0);
|
||||
when(repository.findByBoxCode(10001L, "PCHK2608040174#1-1")).thenReturn(label);
|
||||
|
||||
var resolved = service.resolveByBoxCode(10001L, " PCHK2608040174#1-1 ");
|
||||
|
||||
assertThat(resolved.inboundId()).isEqualTo(70001L);
|
||||
assertThat(resolved.orderId()).isEqualTo(60001L);
|
||||
assertThat(resolved.inboundDetailId()).isEqualTo(80001L);
|
||||
assertThat(resolved.cartonIndex()).isEqualTo(1);
|
||||
verify(repository).findByBoxCode(10001L, "PCHK2608040174#1-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void refusesFirstAllocationAfterMeasurementSubmission() {
|
||||
InboundOrderEntity inbound = inbound();
|
||||
inbound.setProcessStatus("MEASURE_PENDING");
|
||||
when(repository.lockInbound(10001L, 70001L)).thenReturn(inbound);
|
||||
when(repository.findByInbound(10001L, 70001L)).thenReturn(List.of());
|
||||
|
||||
assertThatThrownBy(() -> service.getOrCreate(10001L, 70001L))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("不允许首次生成箱号");
|
||||
verify(orderCargoClient, never()).listForCartonLabels(any(String.class),
|
||||
org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong());
|
||||
}
|
||||
|
||||
private InboundOrderEntity inbound() {
|
||||
InboundOrderEntity inbound = new InboundOrderEntity();
|
||||
inbound.setId(70001L);
|
||||
inbound.setTenantId(10001L);
|
||||
inbound.setOrderId(60001L);
|
||||
inbound.setInboundCode("PCHK2608040174");
|
||||
inbound.setProcessStatus("WAIT_MEASURE");
|
||||
inbound.setWarehouseName("MCC1");
|
||||
inbound.setChannelName("洛杉矶普船海卡");
|
||||
return inbound;
|
||||
}
|
||||
|
||||
private OrderCargoClient.CargoLabelBinding cargo(long id, int itemNo, int count,
|
||||
String length, String width, String height) {
|
||||
return new OrderCargoClient.CargoLabelBinding(id, 60001L, itemNo, "货物" + itemNo, count,
|
||||
new BigDecimal(length), new BigDecimal(width), new BigDecimal(height));
|
||||
}
|
||||
|
||||
private List<InboundCartonLabelEntity> labels(InboundOrderEntity inbound, int total) {
|
||||
List<InboundCartonLabelEntity> values = new ArrayList<>();
|
||||
for (int index = 1; index <= total; index++) {
|
||||
InboundCartonLabelEntity label = new InboundCartonLabelEntity();
|
||||
label.setId((long) index);
|
||||
label.setTenantId(inbound.getTenantId());
|
||||
label.setInboundId(inbound.getId());
|
||||
label.setOrderId(inbound.getOrderId());
|
||||
label.setInboundDetailId(80001L);
|
||||
label.setCargoItemNo(1);
|
||||
label.setCargoName("货物1");
|
||||
label.setDetailPackageCount(total);
|
||||
label.setInboundCode(inbound.getInboundCode());
|
||||
label.setBoxCode(inbound.getInboundCode() + "#" + total + "-" + index);
|
||||
label.setTotalCartonCount(total);
|
||||
label.setCartonIndex(index);
|
||||
label.setBoxSpecification("60x40x30cm");
|
||||
label.setLengthCm(new BigDecimal("60"));
|
||||
label.setWidthCm(new BigDecimal("40"));
|
||||
label.setHeightCm(new BigDecimal("30"));
|
||||
values.add(label);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user