贴标申请,仓储转运
This commit is contained in:
+232
@@ -40,6 +40,11 @@ import com.baiyue.lastleg.dropship.mapper.DropshipCartonMapper;
|
||||
import com.baiyue.lastleg.dropship.mapper.DropshipCartonSkuMapper;
|
||||
import com.baiyue.lastleg.dropship.mapper.DropshipSkuInventoryMapper;
|
||||
import com.baiyue.lastleg.dropship.model.DropshipOutboundCandidate;
|
||||
import com.baiyue.lastleg.returnreceipt.entity.ReturnInventoryCarton;
|
||||
import com.baiyue.lastleg.returnreceipt.entity.ReturnInventoryCartonItem;
|
||||
import com.baiyue.lastleg.returnreceipt.mapper.ReturnInventoryBalanceMapper;
|
||||
import com.baiyue.lastleg.returnreceipt.mapper.ReturnInventoryCartonItemMapper;
|
||||
import com.baiyue.lastleg.returnreceipt.mapper.ReturnInventoryCartonMapper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -58,9 +63,11 @@ import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
@@ -113,6 +120,9 @@ class DeliveryTransferServiceTest {
|
||||
@Mock DropshipCartonSkuMapper dropshipCartonSkus;
|
||||
@Mock DropshipSkuInventoryMapper dropshipSkuInventory;
|
||||
@Mock WarehouseTransferPalletMapper warehouseTransferPallets;
|
||||
@Mock ReturnInventoryCartonMapper returnCartons;
|
||||
@Mock ReturnInventoryCartonItemMapper returnCartonItems;
|
||||
@Mock ReturnInventoryBalanceMapper returnBalances;
|
||||
|
||||
private DeliveryTransferService service;
|
||||
@Mock com.baiyue.lastleg.fleet.trip.FleetDispatchBindingGuard fleetBindings;
|
||||
@@ -152,6 +162,228 @@ class DeliveryTransferServiceTest {
|
||||
ReflectionTestUtils.setField(service, "dropshipCartonSkus", dropshipCartonSkus);
|
||||
ReflectionTestUtils.setField(service, "dropshipSkuInventory", dropshipSkuInventory);
|
||||
ReflectionTestUtils.setField(service, "warehouseTransferPallets", warehouseTransferPallets);
|
||||
ReflectionTestUtils.setField(service, "returnCartons", returnCartons);
|
||||
ReflectionTestUtils.setField(service, "returnCartonItems", returnCartonItems);
|
||||
ReflectionTestUtils.setField(service, "returnBalances", returnBalances);
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnBoxOutboundCanSelectOneCartonFromAPallet() {
|
||||
ReturnInventoryCarton first = returnCarton("RC-1", "PAL-1");
|
||||
ReturnInventoryCarton second = returnCarton("RC-2", "PAL-1");
|
||||
when(returnCartons.lockMark("RC-1")).thenReturn(first);
|
||||
when(returnCartons.listActivePallet("WH-1", "PAL-1")).thenReturn(List.of(first, second));
|
||||
|
||||
service.createReturnOutbound("TENANT-A", "U-1",
|
||||
new DeliveryRequests.ReturnOutbound("receiver", "WH-1", "RT-1", List.of("RC-1"), null, "return-1"));
|
||||
|
||||
ArgumentCaptor<OutboundPalletItem> item = ArgumentCaptor.forClass(OutboundPalletItem.class);
|
||||
verify(outboundPallets).insert(item.capture());
|
||||
assertNull(item.getValue().getPalletNo());
|
||||
verify(outboundOrders).insert(any(OutboundOrder.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void receivedPalletIsEligibleForWholePalletOutboundButParcelIsNot() {
|
||||
ReturnInventoryCarton pallet = returnCarton("RC-PAL", "PAL-1");
|
||||
pallet.setSourceUnitType("PALLET");
|
||||
ReturnInventoryCarton parcel = returnCarton("RC-PARCEL", null);
|
||||
parcel.setSourceUnitType("PARCEL");
|
||||
when(returnCartons.findAvailable("TENANT-A", "WH-1")).thenReturn(List.of(pallet, parcel));
|
||||
|
||||
var candidates = service.returnOutboundCandidates("TENANT-A", "WH-1");
|
||||
|
||||
assertEquals(List.of("RC-PAL"), candidates.stream().map(DeliveryResponses.ReturnOutboundCandidate::cartonMark).toList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void singleSkuReturnOutboundReservesParcelAndCreatesDelivery() {
|
||||
ReturnInventoryCarton parcel = returnCarton("RC-PARCEL", null);
|
||||
parcel.setId(901L); parcel.setSourceUnitType("PARCEL"); parcel.setTotalQuantity(3L);
|
||||
ReturnInventoryCartonItem line = new ReturnInventoryCartonItem();
|
||||
line.setSkuCode("SKU-A"); line.setQuantity(3L);
|
||||
when(returnCartons.lockMark("RC-PARCEL")).thenReturn(parcel);
|
||||
when(returnCartonItems.lockCarton(901L)).thenReturn(List.of(line));
|
||||
|
||||
service.createReturnOutbound("TENANT-A", "U-1",
|
||||
new DeliveryRequests.ReturnOutbound("receiver", "WH-1", "RT-1",
|
||||
List.of("RC-PARCEL"), null, "sku-return-1", "SKU-A"));
|
||||
|
||||
ArgumentCaptor<OutboundPalletItem> item = ArgumentCaptor.forClass(OutboundPalletItem.class);
|
||||
ArgumentCaptor<DeliveryOrder> delivery = ArgumentCaptor.forClass(DeliveryOrder.class);
|
||||
verify(outboundPallets).insert(item.capture());
|
||||
verify(deliveryOrders).insert(delivery.capture());
|
||||
assertEquals("SKU-A", item.getValue().getSkuCode());
|
||||
assertEquals("RC-PARCEL", item.getValue().getCartonMarks());
|
||||
assertEquals("OUTBOUND_PENDING", parcel.getStatus());
|
||||
assertEquals("WAIT_DELIVERY", delivery.getValue().getStatus());
|
||||
assertEquals(1, delivery.getValue().getPackageCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
void singleSkuReturnOutboundRejectsMixedCarton() {
|
||||
ReturnInventoryCarton mixed = returnCarton("RC-MIXED", null);
|
||||
mixed.setId(901L); mixed.setTotalQuantity(5L);
|
||||
ReturnInventoryCartonItem skuA = new ReturnInventoryCartonItem(); skuA.setSkuCode("SKU-A"); skuA.setQuantity(3L);
|
||||
ReturnInventoryCartonItem skuB = new ReturnInventoryCartonItem(); skuB.setSkuCode("SKU-B"); skuB.setQuantity(2L);
|
||||
when(returnCartons.lockMark("RC-MIXED")).thenReturn(mixed);
|
||||
when(returnCartonItems.lockCarton(901L)).thenReturn(List.of(skuA, skuB));
|
||||
|
||||
assertEquals(409, assertThrows(ResponseStatusException.class, () -> service.createReturnOutbound("TENANT-A", "U-1",
|
||||
new DeliveryRequests.ReturnOutbound("receiver", "WH-1", "RT-1",
|
||||
List.of("RC-MIXED"), null, "sku-return-2", "SKU-A"))).getStatusCode().value());
|
||||
verify(outboundOrders, never()).insert(any(OutboundOrder.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void singleSkuReturnPickAcceptsSkuScanAndRejectsOtherSku() {
|
||||
OutboundOrder outbound = outbound(301L, null, null, "OUT-301", "sku-return-1");
|
||||
outbound.setOverseasWarehouseId("WH-1"); outbound.setOutboundType("RETURN_OUTBOUND"); outbound.setStatus("WAIT_PICK");
|
||||
OutboundPdaTask task = new OutboundPdaTask(); task.setId(701L); task.setCustomerId("TENANT-A");
|
||||
task.setOutboundOrderId(301L); task.setTaskNo("PDA-701"); task.setStatus("PENDING");
|
||||
OutboundPalletItem item = new OutboundPalletItem(); item.setId(801L); item.setCustomerId("TENANT-A");
|
||||
item.setOutboundOrderId(301L); item.setSkuCode("SKU-A"); item.setCartonMarks("RC-1");
|
||||
item.setPackageCount(1); item.setPickedPackageCount(0);
|
||||
ReturnInventoryCarton carton = returnCarton("RC-1", null); carton.setId(901L);
|
||||
carton.setStatus("OUTBOUND_PENDING"); carton.setTotalQuantity(3L);
|
||||
ReturnInventoryCartonItem line = new ReturnInventoryCartonItem(); line.setSkuCode("SKU-A"); line.setQuantity(3L);
|
||||
when(pdaTasks.lockByNoAndWarehouse("PDA-701", "WH-1")).thenReturn(task);
|
||||
when(outboundOrders.selectById(301L)).thenReturn(outbound);
|
||||
when(outboundOrders.lockByNo("TENANT-A", "OUT-301")).thenReturn(outbound);
|
||||
when(outboundPallets.selectById(801L)).thenReturn(item);
|
||||
when(outboundPallets.findByOutbound("TENANT-A", 301L)).thenReturn(List.of(item));
|
||||
when(returnCartons.lockMark("RC-1")).thenReturn(carton);
|
||||
when(returnCartonItems.lockCarton(901L)).thenReturn(List.of(line));
|
||||
when(returnBalances.shipCartonSku("TENANT-A", "WH-1", "SKU-A", 3L)).thenReturn(1);
|
||||
|
||||
assertEquals(409, assertThrows(ResponseStatusException.class, () -> service.pdaPick("WH-1", "U-1", "PDA-701",
|
||||
new DeliveryRequests.PdaPick(801L, null, 1L, "wrong-sku", List.of(), "SKU-B"))).getStatusCode().value());
|
||||
service.pdaPick("WH-1", "U-1", "PDA-701",
|
||||
new DeliveryRequests.PdaPick(801L, null, 1L, "correct-sku", List.of(), "SKU-A"));
|
||||
assertEquals("OUTBOUNDED", carton.getStatus());
|
||||
verify(returnBalances).shipCartonSku("TENANT-A", "WH-1", "SKU-A", 3L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnDeliveryDetailShowsFrozenCartonSkuAndQuantity() {
|
||||
DeliveryOrder delivery = new DeliveryOrder(); delivery.setId(501L); delivery.setCustomerId("TENANT-A");
|
||||
delivery.setDeliveryNo("DL-501"); delivery.setOutboundOrderId(301L);
|
||||
delivery.setOutboundNo("OUT-301"); delivery.setOverseasWarehouseId("WH-1");
|
||||
delivery.setDeliveryGroupKey("RETURN:RT-1"); delivery.setStatus("WAIT_DELIVERY");
|
||||
OutboundOrder outbound = outbound(301L, null, null, "OUT-301", "return-1");
|
||||
outbound.setOverseasWarehouseId("WH-1"); outbound.setOutboundType("RETURN_OUTBOUND");
|
||||
OutboundPalletItem item = new OutboundPalletItem(); item.setCartonMarks("RC-1");
|
||||
ReturnInventoryCarton carton = returnCarton("RC-1", null); carton.setId(901L);
|
||||
ReturnInventoryCartonItem line = new ReturnInventoryCartonItem();
|
||||
line.setSkuCode("SKU-A"); line.setProductNameZh("测试品"); line.setQuantity(3L);
|
||||
when(deliveryOrders.findByNo("TENANT-A", "DL-501")).thenReturn(delivery);
|
||||
when(outboundOrders.selectById(301L)).thenReturn(outbound);
|
||||
when(outboundPallets.findByOutbound("TENANT-A", 301L)).thenReturn(List.of(item));
|
||||
when(returnCartons.findCustomerMark("TENANT-A", "RC-1")).thenReturn(carton);
|
||||
when(returnCartonItems.listCarton(901L)).thenReturn(List.of(line));
|
||||
|
||||
var detail = service.deliveryDetail("TENANT-A", "DL-501");
|
||||
|
||||
assertEquals(1, detail.skus().size());
|
||||
assertEquals("SKU-A", detail.skus().get(0).skuCode());
|
||||
assertEquals(3L, detail.skus().get(0).productQuantity());
|
||||
assertEquals(1, detail.skus().get(0).packageCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnCartonPickDeductsEverySkuOnce() {
|
||||
OutboundOrder outbound = outbound(301L, null, null, "OUT-301", "return-1");
|
||||
outbound.setCustomerId("TENANT-A"); outbound.setOverseasWarehouseId("WH-1");
|
||||
outbound.setOutboundType("RETURN_OUTBOUND"); outbound.setStatus("WAIT_PICK");
|
||||
OutboundPdaTask task = new OutboundPdaTask(); task.setId(701L); task.setCustomerId("TENANT-A");
|
||||
task.setOutboundOrderId(301L); task.setTaskNo("PDA-701"); task.setStatus("PENDING");
|
||||
OutboundPalletItem item = new OutboundPalletItem(); item.setId(801L); item.setCustomerId("TENANT-A");
|
||||
item.setOutboundOrderId(301L); item.setPackageCount(1); item.setPickedPackageCount(0);
|
||||
item.setCartonMarks("RC-1"); item.setStatus("WAIT_PICK");
|
||||
ReturnInventoryCarton carton = returnCarton("RC-1", null); carton.setStatus("OUTBOUND_PENDING");
|
||||
carton.setId(901L);
|
||||
ReturnInventoryCartonItem skuA = new ReturnInventoryCartonItem(); skuA.setSkuCode("SKU-A"); skuA.setQuantity(3L);
|
||||
ReturnInventoryCartonItem skuB = new ReturnInventoryCartonItem(); skuB.setSkuCode("SKU-B"); skuB.setQuantity(2L);
|
||||
when(pdaTasks.lockByNoAndWarehouse("PDA-701", "WH-1")).thenReturn(task);
|
||||
when(outboundOrders.selectById(301L)).thenReturn(outbound);
|
||||
when(outboundOrders.lockByNo("TENANT-A", "OUT-301")).thenReturn(outbound);
|
||||
when(outboundPallets.selectById(801L)).thenReturn(item);
|
||||
when(outboundPallets.findByOutbound("TENANT-A", 301L)).thenReturn(List.of(item));
|
||||
when(returnCartons.lockMark("RC-1")).thenReturn(carton);
|
||||
when(returnCartonItems.lockCarton(901L)).thenReturn(List.of(skuA, skuB));
|
||||
when(returnBalances.shipCartonSku("TENANT-A", "WH-1", "SKU-A", 3L)).thenReturn(1);
|
||||
when(returnBalances.shipCartonSku("TENANT-A", "WH-1", "SKU-B", 2L)).thenReturn(1);
|
||||
|
||||
service.pdaPick("WH-1", "U-1", "PDA-701",
|
||||
new DeliveryRequests.PdaPick(801L, null, 1L, "scan-rc-1", List.of("RC-1")));
|
||||
|
||||
verify(returnBalances).shipCartonSku("TENANT-A", "WH-1", "SKU-A", 3L);
|
||||
verify(returnBalances).shipCartonSku("TENANT-A", "WH-1", "SKU-B", 2L);
|
||||
assertEquals("OUTBOUNDED", carton.getStatus());
|
||||
assertEquals("PICKED", item.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnPalletRejectsIndividualCartonScan() {
|
||||
OutboundOrder outbound = outbound(301L, null, null, "OUT-301", "return-2");
|
||||
outbound.setOverseasWarehouseId("WH-1"); outbound.setOutboundType("RETURN_OUTBOUND");
|
||||
OutboundPdaTask task = new OutboundPdaTask(); task.setId(701L); task.setCustomerId("TENANT-A");
|
||||
task.setOutboundOrderId(301L); task.setTaskNo("PDA-701"); task.setStatus("PENDING");
|
||||
OutboundPalletItem item = new OutboundPalletItem(); item.setId(801L); item.setCustomerId("TENANT-A");
|
||||
item.setOutboundOrderId(301L); item.setPalletNo("PAL-1"); item.setCartonMarks("RC-1");
|
||||
item.setPackageCount(1); item.setPickedPackageCount(0);
|
||||
when(pdaTasks.lockByNoAndWarehouse("PDA-701", "WH-1")).thenReturn(task);
|
||||
when(outboundOrders.selectById(301L)).thenReturn(outbound);
|
||||
when(outboundOrders.lockByNo("TENANT-A", "OUT-301")).thenReturn(outbound);
|
||||
when(outboundPallets.selectById(801L)).thenReturn(item);
|
||||
|
||||
assertEquals(409, assertThrows(ResponseStatusException.class, () -> service.pdaPick("WH-1", "U-1", "PDA-701",
|
||||
new DeliveryRequests.PdaPick(801L, null, 1L, "scan-rc-1", List.of("RC-1")))).getStatusCode().value());
|
||||
verify(returnBalances, never()).shipCartonSku(any(), any(), any(), anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnPalletScanShipsEveryCartonAndRejectsChangedPalletContents() {
|
||||
OutboundOrder outbound = outbound(301L, null, null, "OUT-301", "return-3");
|
||||
outbound.setOverseasWarehouseId("WH-1"); outbound.setOutboundType("RETURN_OUTBOUND");
|
||||
OutboundPdaTask task = new OutboundPdaTask(); task.setId(701L); task.setCustomerId("TENANT-A");
|
||||
task.setOutboundOrderId(301L); task.setTaskNo("PDA-701"); task.setStatus("PENDING");
|
||||
OutboundPalletItem item = new OutboundPalletItem(); item.setId(801L); item.setCustomerId("TENANT-A");
|
||||
item.setOutboundOrderId(301L); item.setPalletNo("PAL-1"); item.setCartonMarks("RC-1,RC-2");
|
||||
item.setPackageCount(2); item.setPickedPackageCount(0);
|
||||
ReturnInventoryCarton first = returnCarton("RC-1", "PAL-1"); first.setId(901L); first.setStatus("OUTBOUND_PENDING");
|
||||
ReturnInventoryCarton second = returnCarton("RC-2", "PAL-1"); second.setId(902L); second.setStatus("OUTBOUND_PENDING");
|
||||
ReturnInventoryCartonItem firstSku = new ReturnInventoryCartonItem(); firstSku.setSkuCode("SKU-A"); firstSku.setQuantity(3L);
|
||||
ReturnInventoryCartonItem secondSku = new ReturnInventoryCartonItem(); secondSku.setSkuCode("SKU-B"); secondSku.setQuantity(2L);
|
||||
when(pdaTasks.lockByNoAndWarehouse("PDA-701", "WH-1")).thenReturn(task);
|
||||
when(outboundOrders.selectById(301L)).thenReturn(outbound);
|
||||
when(outboundOrders.lockByNo("TENANT-A", "OUT-301")).thenReturn(outbound);
|
||||
when(outboundPallets.findByOutbound("TENANT-A", 301L)).thenReturn(List.of(item));
|
||||
when(returnCartons.listActivePallet("WH-1", "PAL-1")).thenReturn(List.of(first));
|
||||
assertEquals(409, assertThrows(ResponseStatusException.class, () -> service.pdaPickPallet("WH-1", "U-1", "PDA-701",
|
||||
"PAL-1", new DeliveryRequests.PdaPalletPick("scan-pal-1"))).getStatusCode().value());
|
||||
verify(returnBalances, never()).shipCartonSku(any(), any(), any(), anyLong());
|
||||
|
||||
when(returnCartons.listActivePallet("WH-1", "PAL-1")).thenReturn(List.of(first, second));
|
||||
when(returnCartons.lockMark("RC-1")).thenReturn(first);
|
||||
when(returnCartons.lockMark("RC-2")).thenReturn(second);
|
||||
when(returnCartonItems.lockCarton(901L)).thenReturn(List.of(firstSku));
|
||||
when(returnCartonItems.lockCarton(902L)).thenReturn(List.of(secondSku));
|
||||
when(returnBalances.shipCartonSku("TENANT-A", "WH-1", "SKU-A", 3L)).thenReturn(1);
|
||||
when(returnBalances.shipCartonSku("TENANT-A", "WH-1", "SKU-B", 2L)).thenReturn(1);
|
||||
service.pdaPickPallet("WH-1", "U-1", "PDA-701", "PAL-1", new DeliveryRequests.PdaPalletPick("scan-pal-2"));
|
||||
assertEquals("OUTBOUNDED", first.getStatus()); assertEquals("OUTBOUNDED", second.getStatus());
|
||||
assertEquals(2, item.getPickedPackageCount());
|
||||
verify(returnBalances).shipCartonSku("TENANT-A", "WH-1", "SKU-A", 3L);
|
||||
verify(returnBalances).shipCartonSku("TENANT-A", "WH-1", "SKU-B", 2L);
|
||||
}
|
||||
|
||||
private static ReturnInventoryCarton returnCarton(String mark, String palletCode) {
|
||||
ReturnInventoryCarton carton = new ReturnInventoryCarton();
|
||||
carton.setCustomerId("TENANT-A"); carton.setOverseasWarehouseId("WH-1");
|
||||
carton.setSourceReturnNo("RT-1"); carton.setSourceUnitType("BOX");
|
||||
carton.setCartonMark(mark); carton.setPalletCode(palletCode); carton.setStatus("AVAILABLE");
|
||||
return carton;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
package com.baiyue.lastleg.delivery.service;
|
||||
|
||||
import com.baiyue.lastleg.delivery.dto.DeliveryRequests;
|
||||
import com.baiyue.lastleg.delivery.entity.*;
|
||||
import com.baiyue.lastleg.delivery.mapper.*;
|
||||
import com.baiyue.lastleg.returnreceipt.entity.*;
|
||||
import com.baiyue.lastleg.returnreceipt.mapper.*;
|
||||
import com.baiyue.lastleg.returnreceipt.service.ReturnInventoryService;
|
||||
import com.baiyue.lastleg.service.LastlegOrderNoGenerator;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
import java.util.List;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
class ReturnOutboundClosureTest {
|
||||
final DeliveryTransferService service = new DeliveryTransferService();
|
||||
final OutboundOrderMapper outbounds = mock(OutboundOrderMapper.class);
|
||||
final OutboundPalletItemMapper items = mock(OutboundPalletItemMapper.class);
|
||||
final OutboundPdaTaskMapper tasks = mock(OutboundPdaTaskMapper.class);
|
||||
final DeliveryOrderMapper deliveries = mock(DeliveryOrderMapper.class);
|
||||
final ReturnInventoryCartonMapper cartons = mock(ReturnInventoryCartonMapper.class);
|
||||
final ReturnInventoryCartonItemMapper contents = mock(ReturnInventoryCartonItemMapper.class);
|
||||
final ReturnInventoryService stock = mock(ReturnInventoryService.class);
|
||||
final OutboundPdaPickMapper picks = mock(OutboundPdaPickMapper.class);
|
||||
final com.baiyue.lastleg.relabel.mapper.RelabelApplicationMapper relabelApplications = mock(com.baiyue.lastleg.relabel.mapper.RelabelApplicationMapper.class);
|
||||
final com.baiyue.lastleg.relabel.service.RelabelApplicationService relabelService = mock(com.baiyue.lastleg.relabel.service.RelabelApplicationService.class);
|
||||
ReturnInventoryCarton carton;
|
||||
|
||||
@BeforeEach void setup() {
|
||||
ReflectionTestUtils.setField(service, "outboundOrders", outbounds);
|
||||
ReflectionTestUtils.setField(service, "outboundPallets", items);
|
||||
ReflectionTestUtils.setField(service, "pdaTasks", tasks);
|
||||
ReflectionTestUtils.setField(service, "deliveryOrders", deliveries);
|
||||
ReflectionTestUtils.setField(service, "returnCartons", cartons);
|
||||
ReflectionTestUtils.setField(service, "returnCartonItems", contents);
|
||||
ReflectionTestUtils.setField(service, "returnStock", stock);
|
||||
ReflectionTestUtils.setField(service, "pdaPicks", picks);
|
||||
ReflectionTestUtils.setField(service, "relabelApplications", relabelApplications);
|
||||
ReflectionTestUtils.setField(service, "relabelService", relabelService);
|
||||
ReflectionTestUtils.setField(service, "orderNoGenerator", new LastlegOrderNoGenerator());
|
||||
ReflectionTestUtils.setField(service, "objectMapper", new ObjectMapper().findAndRegisterModules());
|
||||
carton = new ReturnInventoryCarton(); carton.setId(10L); carton.setCartonMark("RC#1-1");
|
||||
carton.setCustomerId("C1"); carton.setOverseasWarehouseId("WH1"); carton.setSourceReturnNo("RT1,RT2");
|
||||
carton.setStatus("AVAILABLE"); carton.setSourceUnitType("BOX"); carton.setTotalQuantity(6L); carton.setSkuTypes(1);
|
||||
when(cartons.lockMark(carton.getCartonMark())).thenReturn(carton);
|
||||
when(stock.matchesReturnSource(carton, "RT1")).thenReturn(true);
|
||||
ReturnInventoryCartonItem line = new ReturnInventoryCartonItem(); line.setSkuCode("SKU1"); line.setQuantity(6L);
|
||||
when(contents.lockCarton(10L)).thenReturn(List.of(line));
|
||||
}
|
||||
|
||||
DeliveryRequests.ReturnOutbound command(String sku) {
|
||||
return new DeliveryRequests.ReturnOutbound("address", "WH1", "RT1", List.of("RC#1-1"), null, "KEY1", sku);
|
||||
}
|
||||
|
||||
@Test void reservesWholeMergedBoxAndCreatesDelivery() {
|
||||
service.createReturnOutbound("C1", "USER", command(null));
|
||||
assertThat(carton.getStatus()).isEqualTo("OUTBOUND_PENDING");
|
||||
verify(items).insert(argThat((OutboundPalletItem i) -> i.getPackageCount() == 1 && "RT1,RT2".equals(i.getInboundCode())));
|
||||
verify(deliveries).insert(argThat((DeliveryOrder d) -> "WAIT_DELIVERY".equals(d.getStatus()) && d.getPackageCount() == 1));
|
||||
}
|
||||
|
||||
@Test void refusesSecondCommandForReservedBox() {
|
||||
service.createReturnOutbound("C1", "USER", command(null));
|
||||
assertThatThrownBy(() -> service.createReturnOutbound("C1", "USER", command(null)))
|
||||
.isInstanceOf(ResponseStatusException.class).hasMessageContaining("占用");
|
||||
verify(outbounds, times(1)).insert(any(OutboundOrder.class));
|
||||
}
|
||||
|
||||
@Test void preventsSingleSkuBypassingExistingBox() {
|
||||
assertThatThrownBy(() -> service.createReturnOutbound("C1", "USER", command("SKU1")))
|
||||
.isInstanceOf(ResponseStatusException.class).hasMessageContaining("按箱唛");
|
||||
verify(outbounds, never()).insert(any(OutboundOrder.class));
|
||||
}
|
||||
|
||||
@Test void singleSkuParcelReservesAndKeepsScanSku() {
|
||||
carton.setSourceUnitType("PARCEL");
|
||||
service.createReturnOutbound("C1", "USER", command("SKU1"));
|
||||
verify(items).insert(argThat((OutboundPalletItem i) -> "SKU1".equals(i.getSkuCode())));
|
||||
assertThat(carton.getStatus()).isEqualTo("OUTBOUND_PENDING");
|
||||
}
|
||||
|
||||
@Test void refusesPackingReservedQuantity() {
|
||||
ReturnInventoryCartonItem line = new ReturnInventoryCartonItem(); line.setSkuCode("SKU1");
|
||||
line.setQuantity(6L); line.setPackingReservedQuantity(1L);
|
||||
when(contents.lockCarton(10L)).thenReturn(List.of(line));
|
||||
assertThatThrownBy(() -> service.createReturnOutbound("C1", "USER", command(null)))
|
||||
.isInstanceOf(ResponseStatusException.class).hasMessageContaining("合箱计划");
|
||||
verify(outbounds, never()).insert(any(OutboundOrder.class));
|
||||
}
|
||||
|
||||
@Test void exactScanIsRequiredOnReplayAsWell() {
|
||||
OutboundPdaTask task = new OutboundPdaTask(); task.setId(20L); task.setCustomerId("C1"); task.setOutboundOrderId(30L);
|
||||
when(tasks.lockByNoAndWarehouse("TASK1", "WH1")).thenReturn(task);
|
||||
OutboundPdaPick pick = new OutboundPdaPick(); pick.setTaskId(20L); pick.setOutboundPalletItemId(40L); pick.setPackages(1L);
|
||||
when(picks.findByKey("C1", "PICK1")).thenReturn(pick);
|
||||
OutboundOrder outbound = new OutboundOrder(); outbound.setId(30L); outbound.setCustomerId("C1"); outbound.setOutboundType("RETURN_OUTBOUND");
|
||||
when(outbounds.selectById(30L)).thenReturn(outbound);
|
||||
OutboundPalletItem item = new OutboundPalletItem(); item.setId(40L); item.setCustomerId("C1"); item.setOutboundOrderId(30L);
|
||||
item.setPackageCount(1); item.setCartonMarks("RC#1-1"); when(items.selectById(40L)).thenReturn(item);
|
||||
assertThatThrownBy(() -> service.pdaPick("WH1", "USER", "TASK1",
|
||||
new DeliveryRequests.PdaPick(40L, null, 1L, "PICK1", List.of("WRONG"))))
|
||||
.isInstanceOf(ResponseStatusException.class).hasMessageContaining("指定的箱唛");
|
||||
verify(stock, never()).shipCarton(anyString(), anyString(), anyString(), anyString(), anyString(), anyLong());
|
||||
}
|
||||
|
||||
@Test void cancelsUntouchedNativeRelabelWithItsOwningApplication() {
|
||||
OutboundOrder outbound = new OutboundOrder(); outbound.setId(30L); outbound.setCustomerId("C1");
|
||||
outbound.setOutboundNo("OUT1"); outbound.setOutboundType("RELABEL_OUTBOUND"); outbound.setStatus("WAIT_PICK");
|
||||
when(outbounds.findGlobalByNo("OUT1")).thenReturn(outbound);
|
||||
when(outbounds.lockGlobalByNo("OUT1")).thenReturn(outbound);
|
||||
var application = new com.baiyue.lastleg.relabel.entity.RelabelApplication();
|
||||
application.setId(50L); application.setCustomerId("C1"); application.setRelabelNo("REL1");
|
||||
application.setOutboundOrderNo("OUT1"); application.setStatus("READY_FOR_OUTBOUND");
|
||||
when(relabelApplications.lockByOutbound("C1", "OUT1")).thenReturn(application);
|
||||
OutboundPalletItem item = new OutboundPalletItem(); item.setCartonMarks("RC#1-1"); item.setStatus("WAIT_PICK");
|
||||
item.setPickedPackageCount(0); when(items.findByOutbound("C1", 30L)).thenReturn(List.of(item));
|
||||
carton.setStatus("OUTBOUND_PENDING"); carton.setRelabelApplicationId(50L);
|
||||
service.cancelOutbound("OUT1", "OP1", new DeliveryRequests.Cancel("cancel"));
|
||||
assertThat(carton.getStatus()).isEqualTo("RELABEL_PENDING");
|
||||
assertThat(outbound.getStatus()).isEqualTo("CANCELLED");
|
||||
verify(relabelService).changeStatus(eq("C1"), eq("REL1"), eq("OP1"),
|
||||
argThat(request -> "CANCELLED".equals(request.status())));
|
||||
var sequence = inOrder(relabelApplications, outbounds, cartons, relabelService);
|
||||
sequence.verify(relabelApplications).lockByOutbound("C1", "OUT1");
|
||||
sequence.verify(outbounds).lockGlobalByNo("OUT1");
|
||||
sequence.verify(cartons).lockMark("RC#1-1");
|
||||
sequence.verify(relabelService).changeStatus(anyString(), anyString(), anyString(), any());
|
||||
}
|
||||
|
||||
@Test void cancellationRejectsPickedNativeBoxWithoutReleasingItsReservation() {
|
||||
OutboundOrder outbound = new OutboundOrder(); outbound.setId(30L); outbound.setCustomerId("C1");
|
||||
outbound.setOutboundType("RELABEL_OUTBOUND"); outbound.setStatus("WAIT_PICK");
|
||||
when(outbounds.lockGlobalByNo("OUT1")).thenReturn(outbound);
|
||||
OutboundPalletItem item = new OutboundPalletItem(); item.setStatus("WAIT_PICK"); item.setPickedPackageCount(1);
|
||||
when(items.findByOutbound("C1", 30L)).thenReturn(List.of(item));
|
||||
assertThatThrownBy(() -> service.cancelOutbound("OUT1", "OP1", new DeliveryRequests.Cancel("cancel")))
|
||||
.isInstanceOf(ResponseStatusException.class).hasMessageContaining("execution has started");
|
||||
verifyNoInteractions(relabelService);
|
||||
verify(cartons, never()).updateById(any(ReturnInventoryCarton.class));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user