贴标申请,仓储转运
This commit is contained in:
+24
@@ -895,6 +895,30 @@ class RelabelApplicationServiceTest {
|
||||
return app;
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnSkuRelabelRejectsQuantityBeyondSelectedSourceBox() {
|
||||
var cartonMapper = org.mockito.Mockito.mock(com.baiyue.lastleg.returnreceipt.mapper.ReturnInventoryCartonMapper.class);
|
||||
var lineMapper = org.mockito.Mockito.mock(com.baiyue.lastleg.returnreceipt.mapper.ReturnInventoryCartonItemMapper.class);
|
||||
ReflectionTestUtils.setField(service, "returnCartons", cartonMapper);
|
||||
ReflectionTestUtils.setField(service, "returnCartonItems", lineMapper);
|
||||
var carton = new com.baiyue.lastleg.returnreceipt.entity.ReturnInventoryCarton();
|
||||
carton.setId(901L); carton.setCustomerId("10001"); carton.setOverseasWarehouseId("WH-1");
|
||||
carton.setCartonMark("RETURN-BOX-1"); carton.setStatus("AVAILABLE"); carton.setSourceUnitType("BOX");
|
||||
var line = new com.baiyue.lastleg.returnreceipt.entity.ReturnInventoryCartonItem();
|
||||
line.setSkuCode("SKU-A"); line.setQuantity(5L); line.setPackingReservedQuantity(0L);
|
||||
when(cartonMapper.lockId(901L)).thenReturn(carton);
|
||||
when(lineMapper.lockCarton(901L)).thenReturn(List.of(line));
|
||||
var detail = new RelabelRequests.Item(null, null, null, "SKU-A", null, null, null,
|
||||
"Return goods", 1, 1, "RT-1", null, "NEW-A", null, null,
|
||||
null, null, null, "RETURN-BOX-1", null, null, "SKU_LABEL",
|
||||
List.of(new RelabelRequests.SkuItem("SKU-A", "NEW-A", 6, null)), 901L);
|
||||
var request = new RelabelRequests.Create("RT-1", "WH-1", LocalDateTime.now().plusDays(1),
|
||||
"Li", "13800000000", null, null, "return-over-quantity", List.of(detail), null, false);
|
||||
var error = assertThrows(ResponseStatusException.class, () -> service.create("10001", "operator-1", request));
|
||||
assertTrue(error.getReason().contains("超过来源箱可用数量"));
|
||||
verify(applications, never()).insert(any(RelabelApplication.class));
|
||||
}
|
||||
|
||||
private void stubDetail(RelabelApplication application) {
|
||||
when(applications.findNo(application.getCustomerId(), application.getRelabelNo())).thenReturn(application);
|
||||
when(items.selectList(any())).thenReturn(List.of(item(31L, application.getId(), "SKU-A", 10, 6)));
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.baiyue.lastleg.returnreceipt.controller;
|
||||
|
||||
import com.baiyue.common.security.AuthenticatedUser;
|
||||
import com.baiyue.lastleg.returnreceipt.dto.ReturnOrderRequests;
|
||||
import com.baiyue.lastleg.returnreceipt.service.ReturnReceiptService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
class MerchantReturnOrderControllerTest {
|
||||
@Test
|
||||
void putRoutesEditedForecastToAuthenticatedCustomer() throws Exception {
|
||||
var service = mock(ReturnReceiptService.class);
|
||||
var controller = new MerchantReturnOrderController();
|
||||
ReflectionTestUtils.setField(controller, "service", service);
|
||||
var user = new AuthenticatedUser(1L, 100L, 100L, 1L, "tester", "MERCHANT", "WEB", Set.of());
|
||||
var mvc = MockMvcBuilders.standaloneSetup(controller).setCustomArgumentResolvers(new HandlerMethodArgumentResolver() {
|
||||
public boolean supportsParameter(MethodParameter parameter) {
|
||||
return parameter.getParameterType() == AuthenticatedUser.class;
|
||||
}
|
||||
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
|
||||
NativeWebRequest request, WebDataBinderFactory factory) {
|
||||
return user;
|
||||
}
|
||||
}).build();
|
||||
mvc.perform(put("/api/merchant/v1/last-leg/return-orders/RT-TEST")
|
||||
.contentType("application/json")
|
||||
.content("""
|
||||
{"overseasWarehouseId":"WH-1","warehouseContactName":"Updated contact",
|
||||
"warehouseContactPhone":"123456","customerReferenceNo":"REF-NEW",
|
||||
"needRelabel":true,"remark":"Updated remark","idempotencyKey":"edit-test",
|
||||
"items":[{"skuCode":"SKU-NEW","productNameZh":"Updated product","expectedQuantity":25}]}
|
||||
"""))
|
||||
.andExpect(status().isOk());
|
||||
verify(service).updatePending(eq("100"), eq("RT-TEST"), eq(new ReturnOrderRequests.Create(
|
||||
"WH-1", "Updated contact", "123456", "REF-NEW", true, "Updated remark", "edit-test",
|
||||
java.util.List.of(new ReturnOrderRequests.Item("SKU-NEW", "Updated product", 25)))));
|
||||
verifyNoMoreInteractions(service);
|
||||
}
|
||||
}
|
||||
+28
@@ -70,6 +70,7 @@ class ReturnReceiptServiceTest {
|
||||
@Mock RelabelItemMapper relabelItems;
|
||||
@Mock FbaWarehouseValidator fbaWarehouseValidator;
|
||||
@Mock RelabelPhotoFileGateway photoFiles;
|
||||
@Mock com.baiyue.lastleg.service.ReturnOrderReferenceResolver returnOrderReferences;
|
||||
|
||||
ReturnReceiptService service;
|
||||
PdaWarehouseIdentity identity;
|
||||
@@ -91,6 +92,7 @@ class ReturnReceiptServiceTest {
|
||||
ReflectionTestUtils.setField(service, "relabelApplications", relabelApplications);
|
||||
ReflectionTestUtils.setField(service, "relabelItems", relabelItems);
|
||||
ReflectionTestUtils.setField(service, "fbaWarehouseValidator", fbaWarehouseValidator);
|
||||
ReflectionTestUtils.setField(service, "returnOrderReferences", returnOrderReferences);
|
||||
identity = new PdaWarehouseIdentity("operator-1", "仓管员", 10L);
|
||||
}
|
||||
|
||||
@@ -110,6 +112,32 @@ class ReturnReceiptServiceTest {
|
||||
assertEquals(90L, result.receivedQuantity());
|
||||
}
|
||||
|
||||
@Test
|
||||
void detailReturnsMeasurementsForBothPalletsAndDoesNotAddRepeatedCarrierVolume() {
|
||||
ReturnOrder order = order("RT-TWO-PALLETS", "10", "COMPLETED", 10, 10);
|
||||
when(orders.findNo("customer-1", "RT-TWO-PALLETS")).thenReturn(order);
|
||||
ReturnReceipt first = measuredReceipt(1L, "PLT-A", "111", "11", "12");
|
||||
ReturnReceipt second = measuredReceipt(2L, "PLT-B", "11", "21", "32");
|
||||
ReturnReceipt earlier = measuredReceipt(3L, "PLT-A", "100", "10", "10");
|
||||
when(receipts.listOrder(order.getId())).thenReturn(List.of(second, first, earlier));
|
||||
var result = service.detail("customer-1", "RT-TWO-PALLETS");
|
||||
assertEquals(2, result.pallets().size());
|
||||
var palletA = result.pallets().stream().filter(row -> "PLT-A".equals(row.palletCode())).findFirst().orElseThrow();
|
||||
var palletB = result.pallets().stream().filter(row -> "PLT-B".equals(row.palletCode())).findFirst().orElseThrow();
|
||||
assertThat(palletA.volumeCbm()).isEqualByComparingTo("0.014652");
|
||||
assertThat(palletB.volumeCbm()).isEqualByComparingTo("0.007392");
|
||||
assertThat(palletA.length()).isEqualByComparingTo("111");
|
||||
assertThat(palletB.weight()).isEqualByComparingTo("11");
|
||||
}
|
||||
|
||||
private ReturnReceipt measuredReceipt(long id, String code, String length, String width, String height) {
|
||||
ReturnReceipt receipt = new ReturnReceipt(); receipt.setId(id); receipt.setUnitType("PALLET"); receipt.setUnitCode(code);
|
||||
receipt.setPalletCode(code); receipt.setTotalBoxCount(2L); receipt.setReceiptNo("RR-" + id);
|
||||
receipt.setLength(new java.math.BigDecimal(length)); receipt.setWidth(new java.math.BigDecimal(width));
|
||||
receipt.setHeight(new java.math.BigDecimal(height)); receipt.setWeight(new java.math.BigDecimal("11"));
|
||||
return receipt;
|
||||
}
|
||||
|
||||
@Test
|
||||
void merchantPhotoDownloadUsesAuthenticatedCustomerAndResolvedReturnOrder() {
|
||||
ReflectionTestUtils.setField(service, "photoFiles", photoFiles);
|
||||
|
||||
@@ -74,6 +74,7 @@ class LastlegOrderServiceTest {
|
||||
@Mock ContainerArrivalTimeOperationMapper containerArrivalTimeOperations;
|
||||
@Mock WarehouseResourceGateway warehouseResourceGateway;
|
||||
@Mock ContainerShippingGateMapper containerShippingGates;
|
||||
@Mock ReturnOrderReferenceResolver returnOrderReferences;
|
||||
LastlegOrderService service;
|
||||
|
||||
@Test
|
||||
@@ -105,7 +106,10 @@ class LastlegOrderServiceTest {
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
com.baomidou.mybatisplus.core.metadata.TableInfoHelper.initTableInfo(
|
||||
new org.apache.ibatis.builder.MapperBuilderAssistant(new org.apache.ibatis.session.Configuration(), ""), LastlegOrder.class);
|
||||
service = new LastlegOrderService();
|
||||
ReflectionTestUtils.setField(service, "returnOrderReferences", returnOrderReferences);
|
||||
ReflectionTestUtils.setField(service, "orderMapper", orders);
|
||||
ReflectionTestUtils.setField(service, "detailMapper", details);
|
||||
ReflectionTestUtils.setField(service, "historyMapper", histories);
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.baiyue.lastleg.service;
|
||||
|
||||
import com.baiyue.lastleg.entity.LastlegOrder;
|
||||
import com.baiyue.lastleg.fleet.customer.FleetCustomerDirectory;
|
||||
import com.baiyue.lastleg.inboundplan.pda.gateway.WarehouseResourceGateway;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import java.util.List;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
class ReturnOrderReferenceResolverTest {
|
||||
@Test
|
||||
void directoryFailureBlocksNewSnapshotButDoesNotHideHistoricalOrders() {
|
||||
var customers = mock(FleetCustomerDirectory.class);
|
||||
var warehouses = mock(WarehouseResourceGateway.class);
|
||||
when(customers.find("1")).thenThrow(new org.springframework.web.server.ResponseStatusException(org.springframework.http.HttpStatus.SERVICE_UNAVAILABLE));
|
||||
when(warehouses.requireActiveSharedWarehouse(10L)).thenReturn(new WarehouseResourceGateway.WarehouseReference(10L, "USLAX01", "洛杉矶仓", "ACTIVE"));
|
||||
var resolver = new ReturnOrderReferenceResolver(customers, warehouses);
|
||||
org.junit.jupiter.api.Assertions.assertThrows(org.springframework.web.server.ResponseStatusException.class, () -> resolver.populate(List.of(order())));
|
||||
var historical = order();
|
||||
resolver.populateForRead(List.of(historical));
|
||||
assertEquals("洛杉矶仓", historical.getOverseasWarehouseName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolvesMissingReturnReferencesOncePerCustomerAndWarehouseAndPreservesSnapshots() {
|
||||
var customers = mock(FleetCustomerDirectory.class);
|
||||
var warehouses = mock(WarehouseResourceGateway.class);
|
||||
when(customers.find("1")).thenReturn(new FleetCustomerDirectory.Customer("1", "C1", "测试货主", null, null));
|
||||
when(warehouses.requireActiveSharedWarehouse(10L)).thenReturn(new WarehouseResourceGateway.WarehouseReference(10L, "USLAX01", "洛杉矶仓", "ACTIVE"));
|
||||
LastlegOrder first = order(), second = order(), frozen = order();
|
||||
frozen.setCustomerName("原货主快照"); frozen.setOverseasWarehouseCode("OLD"); frozen.setOverseasWarehouseName("原仓库快照");
|
||||
|
||||
new ReturnOrderReferenceResolver(customers, warehouses).populate(List.of(first, second, frozen));
|
||||
|
||||
assertEquals("测试货主", first.getCustomerName());
|
||||
assertEquals("USLAX01", second.getOverseasWarehouseCode());
|
||||
assertEquals("洛杉矶仓", second.getOverseasWarehouseName());
|
||||
assertEquals("原货主快照", frozen.getCustomerName());
|
||||
assertEquals("原仓库快照", frozen.getOverseasWarehouseName());
|
||||
verify(customers, times(1)).find("1");
|
||||
verify(warehouses, times(1)).requireActiveSharedWarehouse(10L);
|
||||
}
|
||||
|
||||
private LastlegOrder order() {
|
||||
var order = new LastlegOrder(); order.setOrderType("RETURN_RELABEL");
|
||||
order.setCustomerId("1"); order.setOverseasWarehouseId("10"); return order;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user