Merge remote-tracking branch 'origin/test' into dev
# Conflicts: # lastleg-service/src/main/java/com/baiyue/lastleg/service/LoadingCompletedConsumer.java # lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/gateway/HttpWarehouseResourceGatewayTest.java # warehouse-overseas-service/src/main/java/com/baiyue/warehouse/service/WarehousePalletBatchService.java
This commit is contained in:
+10
-3
@@ -147,13 +147,20 @@ public class HttpWarehouseResourceGateway implements WarehouseResourceGateway {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT,
|
||||
"Reserved pallet customer binding is invalid");
|
||||
}
|
||||
WarehousePalletData pallet = lookupPallet(palletCode).data();
|
||||
if (pallet.id() != palletId || pallet.warehouseId() != warehouseId || pallet.locationId() != locationId
|
||||
WarehousePalletReference pallet;
|
||||
try {
|
||||
pallet = reference(lookupPallet(palletCode).data());
|
||||
} catch (ResponseStatusException exception) {
|
||||
if (exception.getStatusCode().value() != 404) throw exception;
|
||||
// 已生成计划可能保留早期展示码;确认过的资源绑定仍是唯一可信物理身份。
|
||||
pallet = resolvePallet(palletId);
|
||||
}
|
||||
if (pallet.palletId() != palletId || pallet.warehouseId() != warehouseId || pallet.locationId() != locationId
|
||||
|| !"OCCUPIED".equals(pallet.status())) {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT,
|
||||
"Scanned pallet does not match the reserved inbound plan resource");
|
||||
}
|
||||
return reference(pallet);
|
||||
return pallet;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-1
@@ -58,7 +58,8 @@ public interface WarehouseResourceGateway {
|
||||
java.math.BigDecimal maxLoadKg, String status) { }
|
||||
record PalletBatchEnsure(long warehouseId, String batchKey, List<PalletBatchItemRequest> items) { }
|
||||
record PalletBatchItemRequest(long customerId, String businessKey, String inboundPlanNo,
|
||||
int sequenceNo, String palletType, String fbaWarehouseCode) { }
|
||||
int sequenceNo, String palletType, String fbaWarehouseCode,
|
||||
String palletCode) { }
|
||||
record PalletBatchCommand(long warehouseId, String batchKey, String commandKey) { }
|
||||
record PalletBatchCompensation(long warehouseId, String batchKey, String commandKey, String reason) { }
|
||||
record PalletBatchResponse(long batchId, String batchKey, String status, int attemptNo,
|
||||
|
||||
+8
-3
@@ -117,7 +117,7 @@ public class ContainerInboundPlanConversionCoordinator {
|
||||
preparation.warehouseId(), command.getBatchKey(), preparation.items().stream().map(item ->
|
||||
new WarehouseResourceGateway.PalletBatchItemRequest(Long.parseLong(item.customerId()),
|
||||
item.businessKey(), item.planNo(), item.globalSequenceNo(), "STANDARD",
|
||||
item.fbaWarehouseCode())).toList());
|
||||
item.fbaWarehouseCode(), item.palletCode())).toList());
|
||||
WarehouseResourceGateway.PalletBatchResponse reservation;
|
||||
try {
|
||||
reservation = warehouse.ensurePalletBatch(ensure);
|
||||
@@ -207,10 +207,15 @@ public class ContainerInboundPlanConversionCoordinator {
|
||||
.flatMap(group -> group.orders().stream()).filter(item -> "READY".equals(item.readiness())).toList()) {
|
||||
long planId = IdWorker.getId();
|
||||
String planNo = numbers.next("INBOUND_PLAN", order.destinationWarehouseCode(), planId);
|
||||
List<String> sourcePalletNos = plans.sourcePalletNos(
|
||||
order.customerId(), Long.parseLong(order.orderId()), order.orderType());
|
||||
if (sourcePalletNos.size() != order.suggestedPalletCount()) {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT, "头程托盘码数量与柜级预览不一致");
|
||||
}
|
||||
for (int localSequence = 1; localSequence <= order.suggestedPalletCount(); localSequence++) {
|
||||
items.add(new PreparedItem(order.customerId(), Long.parseLong(order.orderId()), planId, planNo,
|
||||
localSequence, ++globalSequence, "CIP:" + generationId + ":" + globalSequence,
|
||||
trimToNull(order.fbaWarehouseCode())));
|
||||
trimToNull(order.fbaWarehouseCode()), sourcePalletNos.get(localSequence - 1)));
|
||||
}
|
||||
}
|
||||
Preparation preparation = new Preparation(warehouseId, List.copyOf(items));
|
||||
@@ -373,5 +378,5 @@ public class ContainerInboundPlanConversionCoordinator {
|
||||
public record Preparation(long warehouseId, List<PreparedItem> items) { }
|
||||
public record PreparedItem(String customerId, long orderId, long planId, String planNo,
|
||||
int localSequenceNo, int globalSequenceNo, String businessKey,
|
||||
String fbaWarehouseCode) { }
|
||||
String fbaWarehouseCode, String palletCode) { }
|
||||
}
|
||||
|
||||
+20
-1
@@ -27,6 +27,7 @@ import com.baiyue.lastleg.dropship.service.DropshipOrderService;
|
||||
import com.baiyue.common.event.ContainerNumbers;
|
||||
import com.baiyue.lastleg.entity.LastlegOrderCommandRecord;
|
||||
import com.baiyue.lastleg.mapper.LastlegOrderCommandRecordMapper;
|
||||
import com.baiyue.lastleg.mapper.LastlegSourcePalletMapper;
|
||||
import com.baiyue.lastleg.inboundplan.pda.gateway.WarehouseResourceGateway;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -65,8 +66,16 @@ public class InboundPlanService {
|
||||
@Resource private DropshipOrderService dropshipOrders;
|
||||
@Resource private WarehouseResourceGateway warehouseGateway;
|
||||
@Resource private LastlegOrderCommandRecordMapper commandMapper;
|
||||
@Resource private LastlegSourcePalletMapper sourcePalletMapper;
|
||||
@Resource private ObjectMapper objectMapper;
|
||||
|
||||
public List<String> sourcePalletNos(String customerId, long orderId, String orderType) {
|
||||
return "ONE_CLICK_DROPSHIP".equals(orderType)
|
||||
? dropshipOrders.palletSnapshots(customerId, orderId).stream()
|
||||
.map(DropshipPalletSnapshot::sourcePalletNo).toList()
|
||||
: sourcePalletMapper.palletNos(customerId, orderId);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public InboundPlanResponse convertManual(ManualInboundPlanRequest request, String idempotencyKey,
|
||||
String operatorId) {
|
||||
@@ -393,6 +402,10 @@ public class InboundPlanService {
|
||||
PalletAllocator.Result allocation = wholePallets == null && manual == null ? PalletAllocator.allocate(orders.stream()
|
||||
.map(order -> new PalletAllocator.LineInput(order.orderId(), warehouseKey(order), volume(order),
|
||||
order.packageCount(), order.recommendedPalletCount())).toList()) : null;
|
||||
if (allocation != null && sourcePalletNos != null && !sourcePalletNos.isEmpty()
|
||||
&& sourcePalletNos.size() != allocation.pallets().size()) {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT, "头程托盘码数量与尾程计划托盘数不一致");
|
||||
}
|
||||
if (wholePallets != null) validateWholePallets(orders, wholePallets);
|
||||
plan.setPalletCount(manual != null ? manual.palletCount()
|
||||
: wholePallets == null ? allocation.pallets().size() : wholePallets.size());
|
||||
@@ -479,6 +492,7 @@ public class InboundPlanService {
|
||||
List<Integer> pendingIndexes = new ArrayList<>();
|
||||
List<List<SourceOrderSnapshot>> snapshots = new ArrayList<>();
|
||||
List<List<WholePalletInput>> wholePallets = new ArrayList<>();
|
||||
List<List<String>> standardPalletNos = new ArrayList<>();
|
||||
for (int index = 0; index < refs.size(); index++) {
|
||||
InboundPlanOrderMapper.ContainerOrderRef ref = refs.get(index);
|
||||
InboundPlan existing = existingPlans.get(index);
|
||||
@@ -517,6 +531,11 @@ public class InboundPlanService {
|
||||
validateWholePallets(orders, sourcePallets);
|
||||
}
|
||||
wholePallets.add(sourcePallets);
|
||||
List<String> standardNos = "ONE_CLICK_DROPSHIP".equals(ref.orderType()) ? List.of()
|
||||
: sourcePalletMapper.palletNos(ref.customerId(), ref.orderId());
|
||||
if (sourcePallets == null && standardNos.isEmpty()) throw new ResponseStatusException(
|
||||
HttpStatus.CONFLICT, "散货订单缺少头程托盘码快照");
|
||||
standardPalletNos.add(standardNos);
|
||||
}
|
||||
requireSingleWarehouseId(warehouseIds);
|
||||
|
||||
@@ -531,7 +550,7 @@ public class InboundPlanService {
|
||||
Map<Integer, WarehouseResourceGateway.PalletBatchItem> reserved = prepared == null ? Map.of()
|
||||
: prepared.pallets().stream().collect(Collectors.toMap(PreparedPallet::sequenceNo,
|
||||
PreparedPallet::reservation));
|
||||
created.put(refIndex, createPlan(ref.customerId(), ref.orderId(), snapshots.get(pendingIndex), List.of(),
|
||||
created.put(refIndex, createPlan(ref.customerId(), ref.orderId(), snapshots.get(pendingIndex), standardPalletNos.get(pendingIndex),
|
||||
wholePallets.get(pendingIndex), null, null, prepared, reserved));
|
||||
}
|
||||
List<InboundPlanResponse> result = new ArrayList<>(refs.size());
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.baiyue.lastleg.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Insert;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface LastlegSourcePalletMapper {
|
||||
@Insert("""
|
||||
INSERT INTO ll_order_source_pallet
|
||||
(id,customer_id,order_id,source_pallet_no,sequence_no,source_event_id,created_at)
|
||||
VALUES (#{id},#{customerId},#{orderId},#{palletNo},#{sequenceNo},#{eventId},CURRENT_TIMESTAMP(3))
|
||||
""")
|
||||
int insert(@Param("id") long id, @Param("customerId") String customerId,
|
||||
@Param("orderId") long orderId, @Param("palletNo") String palletNo,
|
||||
@Param("sequenceNo") int sequenceNo, @Param("eventId") String eventId);
|
||||
|
||||
@Select("""
|
||||
SELECT source_pallet_no FROM ll_order_source_pallet
|
||||
WHERE customer_id=#{customerId} AND order_id=#{orderId}
|
||||
ORDER BY sequence_no,id
|
||||
""")
|
||||
List<String> palletNos(@Param("customerId") String customerId, @Param("orderId") long orderId);
|
||||
}
|
||||
+15
@@ -45,6 +45,7 @@ public class LoadingCompletedConsumer {
|
||||
@Resource private DropshipOrderService dropshipOrders;
|
||||
@Resource private InventoryCommandService inventory;
|
||||
@Resource private ContainerShippingGateMapper shippingGates;
|
||||
@Resource private LastlegSourcePalletMapper sourcePallets;
|
||||
|
||||
@Transactional(isolation = Isolation.READ_COMMITTED)
|
||||
public int consume(EventEnvelope envelope) {
|
||||
@@ -278,6 +279,20 @@ public class LoadingCompletedConsumer {
|
||||
|
||||
Map<String, List<String>> dropshipLabels = "ONE_CLICK_DROPSHIP".equals(orderType)
|
||||
&& "OVERSEAS".equals(destinationType) ? dropshipReceivingLabels(source, rawSource) : Map.of();
|
||||
if ("FIRST_LEG".equals(orderType) && event.eventVersion() >= 2) {
|
||||
List<FirstLegLoadingPlanCompletedV1.PalletSnapshot> pallets = source.pallets() == null ? List.of() : source.pallets();
|
||||
Set<String> palletNos = new HashSet<>();
|
||||
for (int palletIndex = 0; palletIndex < pallets.size(); palletIndex++) {
|
||||
String palletNo = pallets.get(palletIndex).palletNo();
|
||||
if (palletNo == null || palletNo.isBlank() || palletNo.length() > 128 || !palletNos.add(palletNo)) {
|
||||
throw new IllegalArgumentException("散货来源托盘码为空、重复或过长");
|
||||
}
|
||||
sourcePallets.insert(IdWorker.getId(), customerId, order.getId(), palletNo.trim(), palletIndex + 1, event.eventId());
|
||||
}
|
||||
if (!pallets.isEmpty() && order.getPalletCount() > 0 && pallets.size() != order.getPalletCount()) {
|
||||
throw new IllegalArgumentException("散货来源托盘码数量与托盘数不一致");
|
||||
}
|
||||
}
|
||||
for(var item:source.items()) {
|
||||
LastlegOrderDetail detail=new LastlegOrderDetail();
|
||||
detail.setCustomerId(customerId);
|
||||
|
||||
@@ -112,6 +112,22 @@ CREATE TABLE IF NOT EXISTS ll_order (
|
||||
KEY idx_ll_order_container_progress(source_container_booking_id,estimated_warehouse_at,created_at,id)
|
||||
) ENGINE=InnoDB COMMENT='尾程订单主表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ll_order_source_pallet (
|
||||
id BIGINT NOT NULL COMMENT '来源托盘快照ID',
|
||||
customer_id VARCHAR(128) NOT NULL COMMENT '客户隔离键',
|
||||
order_id BIGINT NOT NULL COMMENT '尾程订单ID',
|
||||
source_pallet_no VARCHAR(128) NOT NULL COMMENT '头程冻结托盘码',
|
||||
sequence_no INT NOT NULL COMMENT '订单内稳定顺序',
|
||||
source_event_id VARCHAR(128) NOT NULL COMMENT '来源装柜完成事件ID',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
PRIMARY KEY(id),
|
||||
UNIQUE KEY uk_ll_source_pallet_no(source_pallet_no),
|
||||
UNIQUE KEY uk_ll_source_pallet_sequence(customer_id,order_id,sequence_no),
|
||||
KEY idx_ll_source_pallet_order(customer_id,order_id),
|
||||
CONSTRAINT fk_ll_source_pallet_order FOREIGN KEY(order_id) REFERENCES ll_order(id)
|
||||
) ENGINE=InnoDB COMMENT='头程交接的不可变托盘码快照';
|
||||
|
||||
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_order' AND column_name='pallet_merge_batch_id'), 'SELECT 1', 'ALTER TABLE ll_order ADD COLUMN pallet_merge_batch_id VARCHAR(64) NULL COMMENT ''平台预标记合托分组号'' AFTER pallet_merge_flag'));
|
||||
PREPARE ll_order_merge_batch_ddl FROM @ddl; EXECUTE ll_order_merge_batch_ddl; DEALLOCATE PREPARE ll_order_merge_batch_ddl;
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_order' AND column_name='hold_chargeable'), 'SELECT 1', 'ALTER TABLE ll_order ADD COLUMN hold_chargeable TINYINT NOT NULL DEFAULT 0 COMMENT ''当前暂扣是否计费:0否1是'' AFTER detained'));
|
||||
|
||||
+19
-1
@@ -3,6 +3,7 @@ package com.baiyue.lastleg.inboundplan.pda.gateway;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.test.web.client.MockRestServiceServer;
|
||||
import org.springframework.web.client.RestClient;
|
||||
@@ -116,6 +117,23 @@ class HttpWarehouseResourceGatewayTest {
|
||||
server.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveReservedFallsBackToConfirmedPhysicalBindingForEarlierPlanDisplayCode() {
|
||||
server.expect(requestTo("http://warehouse/internal/v1/warehouse-pallets/resolve/IP-ACY2-20260909-166786-P001"))
|
||||
.andRespond(withStatus(HttpStatus.NOT_FOUND));
|
||||
server.expect(requestTo("http://warehouse/internal/v1/warehouse-pallets/resolve/id/31"))
|
||||
.andRespond(withSuccess("""
|
||||
{"code":"200","data":{"palletId":31,"palletCode":"PLT-US-LAX-01-31",
|
||||
"warehouseId":21,"locationId":41,"status":"OCCUPIED","version":3,
|
||||
"reservable":false,"reservationBlockReason":"PALLET_NOT_IDLE"}}
|
||||
""", MediaType.APPLICATION_JSON));
|
||||
|
||||
var result = gateway.resolveReservedPallet("IP-ACY2-20260909-166786-P001", "11", 21L, 31L, 41L, 51L);
|
||||
|
||||
assertThat(result.palletId()).isEqualTo(31L);
|
||||
server.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveReservedRejectsDifferentPhysicalBinding() {
|
||||
server.expect(requestTo("http://warehouse/internal/v1/warehouse-pallets/resolve/PAL-RESERVED"))
|
||||
@@ -221,7 +239,7 @@ class HttpWarehouseResourceGatewayTest {
|
||||
|
||||
var result = gateway.ensurePalletBatch(new WarehouseResourceGateway.PalletBatchEnsure(31L, "BATCH-1",
|
||||
List.of(new WarehouseResourceGateway.PalletBatchItemRequest(
|
||||
100L, "CIP:1:1", "IP-21", 1, "STANDARD", "ONT8"))));
|
||||
100L, "CIP:1:1", "IP-21", 1, "STANDARD", "ONT8", "CONT-ONT8-001"))));
|
||||
|
||||
assertThat(result.batchId()).isEqualTo(41L);
|
||||
assertThat(result.items().get(0).resourceLockId()).isEqualTo(71L);
|
||||
|
||||
+4
-2
@@ -117,7 +117,7 @@ class ContainerInboundPlanConversionCoordinatorTest {
|
||||
@Test
|
||||
void reservationMustMatchEveryStableItemIdentity() throws Exception {
|
||||
var expected = new ContainerInboundPlanConversionCoordinator.PreparedItem(
|
||||
"100", 11L, 21L, "IP-21", 1, 1, "CIP:1:1", "ONT8");
|
||||
"100", 11L, 21L, "IP-21", 1, 1, "CIP:1:1", "ONT8", "CONT-ONT8-001");
|
||||
var preparation = new ContainerInboundPlanConversionCoordinator.Preparation(31L, List.of(expected));
|
||||
var response = new WarehouseResourceGateway.PalletBatchResponse(41L, "BATCH-1", "RESERVED", 1,
|
||||
false, List.of(new WarehouseResourceGateway.PalletBatchItem(
|
||||
@@ -239,6 +239,8 @@ class ContainerInboundPlanConversionCoordinatorTest {
|
||||
when(plans.previewContainer(BOOKING_ID)).thenReturn(preview);
|
||||
when(numbers.next(eq("INBOUND_PLAN"), any(String.class), any(Long.class)))
|
||||
.thenReturn("IP-FBA", "IP-OVERSEAS");
|
||||
when(plans.sourcePalletNos("100", 11L, "ONE_CLICK_DROPSHIP")).thenReturn(List.of("MSCU6639870-ABE3-001"));
|
||||
when(plans.sourcePalletNos("200", 12L, "ONE_CLICK_DROPSHIP")).thenReturn(List.of("MSCU6639870-US-LAX-01-001"));
|
||||
|
||||
ContainerPlanConversionCommand command = ReflectionTestUtils.invokeMethod(coordinator, "prepareCommand",
|
||||
1L, 2L, BOOKING_ID, "FIRST-KEY", request,
|
||||
@@ -291,7 +293,7 @@ class ContainerInboundPlanConversionCoordinatorTest {
|
||||
|
||||
private void setOnePreparedItem(ContainerPlanConversionCommand command) throws Exception {
|
||||
var item = new ContainerInboundPlanConversionCoordinator.PreparedItem(
|
||||
"100", 11L, 21L, "IP-21", 1, 1, "CIP:1:1", "ONT8");
|
||||
"100", 11L, 21L, "IP-21", 1, 1, "CIP:1:1", "ONT8", "CONT-ONT8-001");
|
||||
command.setPreparationJson(objectMapper.writeValueAsString(
|
||||
new ContainerInboundPlanConversionCoordinator.Preparation(31L, List.of(item))));
|
||||
}
|
||||
|
||||
+6
@@ -18,6 +18,7 @@ import com.baiyue.lastleg.dropship.model.DropshipPalletSnapshot;
|
||||
import com.baiyue.lastleg.dropship.service.DropshipOrderService;
|
||||
import com.baiyue.lastleg.inboundplan.pda.gateway.WarehouseResourceGateway;
|
||||
import com.baiyue.lastleg.mapper.LastlegOrderCommandRecordMapper;
|
||||
import com.baiyue.lastleg.mapper.LastlegSourcePalletMapper;
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -38,6 +39,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -55,6 +57,7 @@ class InboundPlanServiceTest {
|
||||
@Mock DropshipOrderService dropshipOrders;
|
||||
@Mock WarehouseResourceGateway warehouseGateway;
|
||||
@Mock LastlegOrderCommandRecordMapper commandMapper;
|
||||
@Mock LastlegSourcePalletMapper sourcePalletMapper;
|
||||
|
||||
private InboundPlanService service;
|
||||
|
||||
@@ -70,11 +73,14 @@ class InboundPlanServiceTest {
|
||||
ReflectionTestUtils.setField(service, "dropshipOrders", dropshipOrders);
|
||||
ReflectionTestUtils.setField(service, "warehouseGateway", warehouseGateway);
|
||||
ReflectionTestUtils.setField(service, "commandMapper", commandMapper);
|
||||
ReflectionTestUtils.setField(service, "sourcePalletMapper", sourcePalletMapper);
|
||||
ReflectionTestUtils.setField(service, "objectMapper", JsonMapper.builder().findAndAddModules().build());
|
||||
ReflectionTestUtils.setField(service, "orderNoGenerator", new com.baiyue.lastleg.service.LastlegOrderNoGenerator());
|
||||
org.mockito.Mockito.lenient().when(lineMapper.selectList(any())).thenReturn(List.of());
|
||||
org.mockito.Mockito.lenient().when(palletMapper.selectList(any())).thenReturn(List.of());
|
||||
org.mockito.Mockito.lenient().when(allocationMapper.selectList(any())).thenReturn(List.of());
|
||||
org.mockito.Mockito.lenient().when(sourcePalletMapper.palletNos(any(), anyLong()))
|
||||
.thenAnswer(invocation -> List.of("MSCU6639870-WH-" + invocation.getArgument(1)));
|
||||
org.mockito.Mockito.lenient().when(orderMapper.findReceivingWarehouse(any(), any())).thenReturn(
|
||||
new InboundPlanOrderMapper.ReceivingWarehouseSnapshot(
|
||||
"193000000000200003", "US-LAX-01", "洛杉矶仓"));
|
||||
|
||||
Reference in New Issue
Block a user