暂存提交
This commit is contained in:
+35
@@ -0,0 +1,35 @@
|
||||
package com.baiyue.lastleg.dropship;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class DropshipSchemaContractTest {
|
||||
@Test
|
||||
void baselineAndIncrementalSqlKeepContainerAndMultiPalletIndexes() throws Exception {
|
||||
String baseline = Files.readString(
|
||||
Path.of("src", "main", "resources", "db", "lastleg.sql"), StandardCharsets.UTF_8).toLowerCase();
|
||||
String migration = Files.readString(
|
||||
Path.of("..", "scripts", "db", "incremental.sql"), StandardCharsets.UTF_8).toLowerCase();
|
||||
|
||||
assertThat(baseline).contains(
|
||||
"key idx_ll_order_container(customer_id,container_no)",
|
||||
"unique key uk_ll_dropship_profile_order_pallet(customer_id,order_id,source_pallet_no)",
|
||||
"unique key uk_ll_dropship_sku_inventory(profile_id,sku_code)",
|
||||
"key idx_ll_dropship_profile_order(customer_id,order_id)",
|
||||
"warehouse_pallet_id bigint null comment '仓库实物托盘id'",
|
||||
"pallet_no varchar(128) null comment '托盘号'",
|
||||
"status varchar(32) not null default 'pending_inbound'");
|
||||
assertThat(migration).contains(
|
||||
"add key idx_ll_order_container (customer_id,container_no)",
|
||||
"add unique key uk_ll_dropship_profile_order_pallet(customer_id,order_id,source_pallet_no)",
|
||||
"add unique key uk_ll_dropship_sku_profile(profile_id,sku_code)",
|
||||
"add key idx_ll_dropship_profile_order(customer_id,order_id)",
|
||||
"modify column warehouse_pallet_id bigint null",
|
||||
"modify column pallet_no varchar(128) null");
|
||||
}
|
||||
}
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
package com.baiyue.lastleg.dropship.service;
|
||||
|
||||
import com.baiyue.lastleg.dropship.dto.DropshipRequests;
|
||||
import com.baiyue.lastleg.dropship.entity.DropshipOrderProfile;
|
||||
import com.baiyue.lastleg.dropship.entity.DropshipSkuInventory;
|
||||
import com.baiyue.lastleg.dropship.entity.DropshipCarton;
|
||||
import com.baiyue.lastleg.dropship.entity.DropshipCartonLedger;
|
||||
import com.baiyue.lastleg.dropship.mapper.DropshipCartonLedgerMapper;
|
||||
import com.baiyue.lastleg.dropship.mapper.DropshipCartonMapper;
|
||||
import com.baiyue.lastleg.dropship.mapper.DropshipOrderProfileMapper;
|
||||
import com.baiyue.lastleg.dropship.mapper.DropshipSkuInventoryMapper;
|
||||
import com.baiyue.lastleg.entity.LastlegOrder;
|
||||
import com.baiyue.lastleg.inboundplan.pda.gateway.WarehouseResourceGateway;
|
||||
import com.baiyue.lastleg.inboundplan.pda.entity.InboundStockReceipt;
|
||||
import com.baiyue.lastleg.mapper.LastlegOrderMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class DropshipOrderServiceTest {
|
||||
@Mock private LastlegOrderMapper orders;
|
||||
@Mock private DropshipOrderProfileMapper profiles;
|
||||
@Mock private DropshipSkuInventoryMapper skuInventory;
|
||||
@Mock private DropshipCartonMapper cartons;
|
||||
@Mock private DropshipCartonLedgerMapper ledger;
|
||||
@Mock private WarehouseResourceGateway warehouse;
|
||||
@InjectMocks private DropshipOrderService service;
|
||||
|
||||
@Test
|
||||
void receivesMultiplePalletsForOneInboundOrder() {
|
||||
LastlegOrder order = new LastlegOrder();
|
||||
order.setId(10L);
|
||||
order.setCustomerId("C-1");
|
||||
order.setOrderType("ONE_CLICK_DROPSHIP");
|
||||
order.setOrderNo("LL-10");
|
||||
order.setPackageCount(3);
|
||||
order.setProductQuantity(30);
|
||||
when(orders.selectById(10L)).thenReturn(order);
|
||||
when(profiles.listOrder("C-1", 10L)).thenReturn(List.of());
|
||||
|
||||
DropshipRequests.Receive request = new DropshipRequests.Receive("C-1", 10L, 20L, "EVENT-1",
|
||||
List.of(
|
||||
new DropshipRequests.Pallet("SOURCE-P-1", List.of(
|
||||
new DropshipRequests.SkuPackages("SKU-A", "Product A", 2, 20,
|
||||
List.of("MARK-1", "MARK-2")))),
|
||||
new DropshipRequests.Pallet("SOURCE-P-2", List.of(
|
||||
new DropshipRequests.SkuPackages("SKU-A", "Product A", 1, 10,
|
||||
List.of("MARK-3"))))));
|
||||
|
||||
assertThat(service.receive(request)).isEqualTo(3);
|
||||
verifyNoInteractions(warehouse);
|
||||
verify(profiles, times(2)).insert(any(DropshipOrderProfile.class));
|
||||
verify(skuInventory, times(2)).insert(any(DropshipSkuInventory.class));
|
||||
verify(cartons, times(3)).insert(any(DropshipCarton.class));
|
||||
verify(ledger, times(3)).insert(any(DropshipCartonLedger.class));
|
||||
|
||||
ArgumentCaptor<DropshipOrderProfile> profilesCaptor = ArgumentCaptor.forClass(DropshipOrderProfile.class);
|
||||
verify(profiles, times(2)).insert(profilesCaptor.capture());
|
||||
assertThat(profilesCaptor.getAllValues()).extracting(DropshipOrderProfile::getSourcePalletNo)
|
||||
.containsExactly("SOURCE-P-1", "SOURCE-P-2");
|
||||
assertThat(profilesCaptor.getAllValues()).extracting(DropshipOrderProfile::getCustomerId)
|
||||
.containsOnly("C-1");
|
||||
assertThat(profilesCaptor.getAllValues()).extracting(DropshipOrderProfile::getStatus)
|
||||
.containsOnly("PENDING_INBOUND");
|
||||
assertThat(profilesCaptor.getAllValues()).extracting(DropshipOrderProfile::getWarehousePalletId)
|
||||
.containsOnlyNulls();
|
||||
ArgumentCaptor<DropshipCarton> cartonCaptor = ArgumentCaptor.forClass(DropshipCarton.class);
|
||||
verify(cartons, times(3)).insert(cartonCaptor.capture());
|
||||
assertThat(cartonCaptor.getAllValues()).extracting(DropshipCarton::getStatus)
|
||||
.containsOnly("PENDING_INBOUND");
|
||||
ArgumentCaptor<DropshipCartonLedger> ledgerCaptor = ArgumentCaptor.forClass(DropshipCartonLedger.class);
|
||||
verify(ledger, times(3)).insert(ledgerCaptor.capture());
|
||||
assertThat(ledgerCaptor.getAllValues()).extracting(DropshipCartonLedger::getOperationType)
|
||||
.containsOnly("SNAPSHOT_CREATED");
|
||||
assertThat(ledgerCaptor.getAllValues()).extracting(DropshipCartonLedger::getDeltaPackages)
|
||||
.containsOnly(0L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void activatesMultiplePalletsOnlyAfterPdaStockIn() {
|
||||
DropshipOrderProfile first = profile(1L, "SOURCE-P-1");
|
||||
DropshipOrderProfile second = profile(2L, "SOURCE-P-2");
|
||||
when(profiles.listOrder("C-1", 10L)).thenReturn(List.of(first, second));
|
||||
DropshipCarton firstCarton = carton(11L, 1L, "MARK-1");
|
||||
DropshipCarton secondCarton = carton(12L, 2L, "MARK-2");
|
||||
when(cartons.listProfile("C-1", 1L)).thenReturn(List.of(firstCarton));
|
||||
when(cartons.listProfile("C-1", 2L)).thenReturn(List.of(secondCarton));
|
||||
|
||||
service.activateAfterStockIn("C-1", 10L, 50L, List.of(
|
||||
receipt(101L, "WH-P-1", 201L, 1), receipt(102L, "WH-P-2", 202L, 1)));
|
||||
|
||||
assertThat(first.getStatus()).isEqualTo("ACTIVE");
|
||||
assertThat(first.getWarehousePalletId()).isEqualTo(101L);
|
||||
assertThat(firstCarton.getStatus()).isEqualTo("AVAILABLE");
|
||||
assertThat(firstCarton.getWarehousePalletId()).isEqualTo(101L);
|
||||
verify(profiles, times(2)).updateById(any(DropshipOrderProfile.class));
|
||||
verify(cartons, times(2)).updateById(any(DropshipCarton.class));
|
||||
ArgumentCaptor<DropshipCartonLedger> facts = ArgumentCaptor.forClass(DropshipCartonLedger.class);
|
||||
verify(ledger, times(2)).insert(facts.capture());
|
||||
assertThat(facts.getAllValues()).extracting(DropshipCartonLedger::getOperationType).containsOnly("STOCK_IN");
|
||||
assertThat(facts.getAllValues()).extracting(DropshipCartonLedger::getDeltaPackages).containsOnly(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void repeatedPdaActivationIsANoOp() {
|
||||
DropshipOrderProfile active = profile(1L, "SOURCE-P-1");
|
||||
active.setStatus("ACTIVE");
|
||||
when(profiles.listOrder("C-1", 10L)).thenReturn(List.of(active));
|
||||
|
||||
service.activateAfterStockIn("C-1", 10L, 50L,
|
||||
List.of(receipt(101L, "WH-P-1", 201L, 1)));
|
||||
|
||||
verify(profiles, never()).updateById(any(DropshipOrderProfile.class));
|
||||
verify(cartons, never()).updateById(any(DropshipCarton.class));
|
||||
verify(ledger, never()).insert(any(DropshipCartonLedger.class));
|
||||
}
|
||||
|
||||
private static DropshipOrderProfile profile(long id, String sourcePalletNo) {
|
||||
DropshipOrderProfile profile = new DropshipOrderProfile();
|
||||
profile.setId(id); profile.setCustomerId("C-1"); profile.setOrderId(10L);
|
||||
profile.setSourcePalletNo(sourcePalletNo); profile.setStatus("PENDING_INBOUND"); profile.setVersion(0L);
|
||||
return profile;
|
||||
}
|
||||
|
||||
private static DropshipCarton carton(long id, long profileId, String mark) {
|
||||
DropshipCarton carton = new DropshipCarton();
|
||||
carton.setId(id); carton.setCustomerId("C-1"); carton.setOrderId(10L); carton.setProfileId(profileId);
|
||||
carton.setCartonMark(mark); carton.setSkuCode("SKU-A"); carton.setStatus("PENDING_INBOUND"); carton.setVersion(0L);
|
||||
return carton;
|
||||
}
|
||||
|
||||
private static InboundStockReceipt receipt(long palletId, String palletNo, long positionId, long packages) {
|
||||
InboundStockReceipt receipt = new InboundStockReceipt();
|
||||
receipt.setOrderId(10L); receipt.setWarehousePalletId(palletId); receipt.setPalletNo(palletNo);
|
||||
receipt.setInventoryPositionId(positionId); receipt.setReceivedPackages(packages);
|
||||
return receipt;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user