fix(lastleg): resolve actual overseas receiving warehouse
This commit is contained in:
+2
-5
@@ -12,14 +12,11 @@ public interface InboundCodeRelationshipMapper {
|
|||||||
@Select("SELECT o.customer_id AS customerId,o.customer_name AS customerName,o.order_no AS orderNo," +
|
@Select("SELECT o.customer_id AS customerId,o.customer_name AS customerName,o.order_no AS orderNo," +
|
||||||
"o.current_status AS orderStatus,p.plan_no AS planNo,p.status AS planStatus," +
|
"o.current_status AS orderStatus,p.plan_no AS planNo,p.status AS planStatus," +
|
||||||
"COALESCE(p.status,o.current_status) AS receivingStatus," +
|
"COALESCE(p.status,o.current_status) AS receivingStatus," +
|
||||||
"COALESCE(b.overseas_warehouse_id,o.overseas_warehouse_id,CAST(p.overseas_warehouse_id AS CHAR)) AS overseasWarehouseId," +
|
"CAST(p.overseas_warehouse_id AS CHAR) AS overseasWarehouseId " +
|
||||||
"b.overseas_warehouse_code AS overseasWarehouseCode," +
|
|
||||||
"COALESCE(b.overseas_warehouse_name,o.overseas_warehouse_name) AS overseasWarehouseName " +
|
|
||||||
"FROM ll_order o " +
|
"FROM ll_order o " +
|
||||||
"LEFT JOIN ll_inbound_plan_line l ON l.customer_id=o.customer_id AND l.order_id=o.id AND l.inbound_code=o.inbound_code " +
|
"LEFT JOIN ll_inbound_plan_line l ON l.customer_id=o.customer_id AND l.order_id=o.id AND l.inbound_code=o.inbound_code " +
|
||||||
"LEFT JOIN ll_inbound_plan p ON p.customer_id=o.customer_id AND p.id=l.plan_id " +
|
"LEFT JOIN ll_inbound_plan p ON p.customer_id=o.customer_id AND p.id=l.plan_id " +
|
||||||
"LEFT JOIN ll_inventory_balance b ON b.customer_id=o.customer_id AND b.inbound_order_id=o.id AND b.inbound_code=o.inbound_code " +
|
"WHERE o.inbound_code=#{inboundCode} ORDER BY o.customer_id,o.id,p.id")
|
||||||
"WHERE o.inbound_code=#{inboundCode} ORDER BY o.customer_id,o.id,p.id,b.id")
|
|
||||||
List<InboundCodeRelationshipRows.Base> bases(@Param("inboundCode") String inboundCode);
|
List<InboundCodeRelationshipRows.Base> bases(@Param("inboundCode") String inboundCode);
|
||||||
|
|
||||||
@Select("SELECT DISTINCT r.pallet_no FROM ll_inbound_stock_receipt r " +
|
@Select("SELECT DISTINCT r.pallet_no FROM ll_inbound_stock_receipt r " +
|
||||||
|
|||||||
-2
@@ -15,8 +15,6 @@ public final class InboundCodeRelationshipRows {
|
|||||||
private String planStatus;
|
private String planStatus;
|
||||||
private String receivingStatus;
|
private String receivingStatus;
|
||||||
private String overseasWarehouseId;
|
private String overseasWarehouseId;
|
||||||
private String overseasWarehouseCode;
|
|
||||||
private String overseasWarehouseName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
+18
-8
@@ -3,6 +3,7 @@ package com.baiyue.lastleg.inventory.query.service;
|
|||||||
import com.baiyue.lastleg.inventory.query.dto.InboundCodeRelationshipResponse;
|
import com.baiyue.lastleg.inventory.query.dto.InboundCodeRelationshipResponse;
|
||||||
import com.baiyue.lastleg.inventory.query.mapper.InboundCodeRelationshipMapper;
|
import com.baiyue.lastleg.inventory.query.mapper.InboundCodeRelationshipMapper;
|
||||||
import com.baiyue.lastleg.inventory.query.model.InboundCodeRelationshipRows;
|
import com.baiyue.lastleg.inventory.query.model.InboundCodeRelationshipRows;
|
||||||
|
import com.baiyue.lastleg.inboundplan.pda.gateway.WarehouseResourceGateway;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -14,6 +15,7 @@ import java.util.Objects;
|
|||||||
@Service
|
@Service
|
||||||
public class InboundCodeRelationshipService {
|
public class InboundCodeRelationshipService {
|
||||||
@Resource private InboundCodeRelationshipMapper mapper;
|
@Resource private InboundCodeRelationshipMapper mapper;
|
||||||
|
@Resource private WarehouseResourceGateway warehouse;
|
||||||
|
|
||||||
public InboundCodeRelationshipResponse find(String inboundCode) {
|
public InboundCodeRelationshipResponse find(String inboundCode) {
|
||||||
String normalized = required(inboundCode);
|
String normalized = required(inboundCode);
|
||||||
@@ -30,10 +32,6 @@ public class InboundCodeRelationshipService {
|
|||||||
"customer name");
|
"customer name");
|
||||||
String warehouseId = unique(bases.stream().map(InboundCodeRelationshipRows.Base::getOverseasWarehouseId).toList(),
|
String warehouseId = unique(bases.stream().map(InboundCodeRelationshipRows.Base::getOverseasWarehouseId).toList(),
|
||||||
"overseas warehouse ID");
|
"overseas warehouse ID");
|
||||||
String warehouseCode = unique(bases.stream().map(InboundCodeRelationshipRows.Base::getOverseasWarehouseCode).toList(),
|
|
||||||
"overseas warehouse code");
|
|
||||||
String warehouseName = unique(bases.stream().map(InboundCodeRelationshipRows.Base::getOverseasWarehouseName).toList(),
|
|
||||||
"overseas warehouse name");
|
|
||||||
List<InboundCodeRelationshipResponse.TaillegOrder> orders = bases.stream()
|
List<InboundCodeRelationshipResponse.TaillegOrder> orders = bases.stream()
|
||||||
.filter(value -> trim(value.getOrderNo()) != null)
|
.filter(value -> trim(value.getOrderNo()) != null)
|
||||||
.map(value -> new InboundCodeRelationshipResponse.TaillegOrder(
|
.map(value -> new InboundCodeRelationshipResponse.TaillegOrder(
|
||||||
@@ -50,14 +48,26 @@ public class InboundCodeRelationshipService {
|
|||||||
value.getProductNameZh(), value.getProductNameEn(), number(value.getPackageCount()))).toList();
|
value.getProductNameZh(), value.getProductNameEn(), number(value.getPackageCount()))).toList();
|
||||||
String status = unique(bases.stream().map(InboundCodeRelationshipRows.Base::getReceivingStatus).toList(),
|
String status = unique(bases.stream().map(InboundCodeRelationshipRows.Base::getReceivingStatus).toList(),
|
||||||
"overseas receiving status");
|
"overseas receiving status");
|
||||||
InboundCodeRelationshipResponse.OverseasWarehouse warehouse = warehouseId == null
|
InboundCodeRelationshipResponse.OverseasWarehouse warehouseView = resolveWarehouse(warehouseId);
|
||||||
&& warehouseCode == null && warehouseName == null ? null
|
|
||||||
: new InboundCodeRelationshipResponse.OverseasWarehouse(warehouseId, warehouseCode, warehouseName);
|
|
||||||
return new InboundCodeRelationshipResponse(normalized, true,
|
return new InboundCodeRelationshipResponse(normalized, true,
|
||||||
new InboundCodeRelationshipResponse.Customer(customerId, customerName), warehouse, status,
|
new InboundCodeRelationshipResponse.Customer(customerId, customerName), warehouseView, status,
|
||||||
orders, plans, mapper.palletCodes(customerId, normalized), inventory);
|
orders, plans, mapper.palletCodes(customerId, normalized), inventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private InboundCodeRelationshipResponse.OverseasWarehouse resolveWarehouse(String warehouseId) {
|
||||||
|
if (warehouseId == null) return null;
|
||||||
|
final long id;
|
||||||
|
try {
|
||||||
|
id = Long.parseLong(warehouseId);
|
||||||
|
} catch (NumberFormatException exception) {
|
||||||
|
throw new ResponseStatusException(HttpStatus.CONFLICT,
|
||||||
|
"Inbound code has invalid overseas warehouse ID snapshot");
|
||||||
|
}
|
||||||
|
WarehouseResourceGateway.WarehouseReference value = warehouse.requireActiveSharedWarehouse(id);
|
||||||
|
return new InboundCodeRelationshipResponse.OverseasWarehouse(
|
||||||
|
String.valueOf(value.warehouseId()), value.warehouseCode(), value.warehouseName());
|
||||||
|
}
|
||||||
|
|
||||||
private static InboundCodeRelationshipResponse empty(String inboundCode) {
|
private static InboundCodeRelationshipResponse empty(String inboundCode) {
|
||||||
return new InboundCodeRelationshipResponse(inboundCode, false, null, null, null,
|
return new InboundCodeRelationshipResponse(inboundCode, false, null, null, null,
|
||||||
List.of(), List.of(), List.of(), List.of());
|
List.of(), List.of(), List.of(), List.of());
|
||||||
|
|||||||
+4
-2
@@ -13,7 +13,9 @@ class InboundCodeRelationshipMapperContractTest {
|
|||||||
String sql = String.join(" ", InboundCodeRelationshipMapper.class
|
String sql = String.join(" ", InboundCodeRelationshipMapper.class
|
||||||
.getMethod("bases", String.class).getAnnotation(Select.class).value());
|
.getMethod("bases", String.class).getAnnotation(Select.class).value());
|
||||||
|
|
||||||
assertThat(sql).contains("ll_order", "ll_inbound_plan", "ll_inventory_balance");
|
assertThat(sql)
|
||||||
assertThat(sql).doesNotContain("customerId}", "warehouse.", "iam.");
|
.contains("ll_order", "ll_inbound_plan", "CAST(p.overseas_warehouse_id AS CHAR)")
|
||||||
|
.doesNotContain("o.source_warehouse_id", "o.overseas_warehouse_id",
|
||||||
|
"ll_inventory_balance", "customerId}", "warehouse.", "iam.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-1
@@ -2,6 +2,7 @@ package com.baiyue.lastleg.inventory.query.service;
|
|||||||
|
|
||||||
import com.baiyue.lastleg.inventory.query.mapper.InboundCodeRelationshipMapper;
|
import com.baiyue.lastleg.inventory.query.mapper.InboundCodeRelationshipMapper;
|
||||||
import com.baiyue.lastleg.inventory.query.model.InboundCodeRelationshipRows;
|
import com.baiyue.lastleg.inventory.query.model.InboundCodeRelationshipRows;
|
||||||
|
import com.baiyue.lastleg.inboundplan.pda.gateway.WarehouseResourceGateway;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
@@ -23,12 +24,14 @@ import static org.mockito.Mockito.when;
|
|||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class InboundCodeRelationshipServiceTest {
|
class InboundCodeRelationshipServiceTest {
|
||||||
@Mock InboundCodeRelationshipMapper mapper;
|
@Mock InboundCodeRelationshipMapper mapper;
|
||||||
|
@Mock WarehouseResourceGateway warehouse;
|
||||||
private InboundCodeRelationshipService service;
|
private InboundCodeRelationshipService service;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
service = new InboundCodeRelationshipService();
|
service = new InboundCodeRelationshipService();
|
||||||
ReflectionTestUtils.setField(service, "mapper", mapper);
|
ReflectionTestUtils.setField(service, "mapper", mapper);
|
||||||
|
ReflectionTestUtils.setField(service, "warehouse", warehouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -49,6 +52,9 @@ class InboundCodeRelationshipServiceTest {
|
|||||||
void relationshipUsesBusinessNumbersAndKeepsLongIdentifiersAsStrings() {
|
void relationshipUsesBusinessNumbersAndKeepsLongIdentifiersAsStrings() {
|
||||||
InboundCodeRelationshipRows.Base row = base("2092618717861048321", "Customer A");
|
InboundCodeRelationshipRows.Base row = base("2092618717861048321", "Customer A");
|
||||||
when(mapper.bases("NYEXX2608300001")).thenReturn(List.of(row, row));
|
when(mapper.bases("NYEXX2608300001")).thenReturn(List.of(row, row));
|
||||||
|
when(warehouse.requireActiveSharedWarehouse(193000000000200003L)).thenReturn(
|
||||||
|
new WarehouseResourceGateway.WarehouseReference(
|
||||||
|
193000000000200003L, "US-LAX-01", "洛杉矶一号仓", "ACTIVE"));
|
||||||
when(mapper.palletCodes("2092618717861048321", "NYEXX2608300001"))
|
when(mapper.palletCodes("2092618717861048321", "NYEXX2608300001"))
|
||||||
.thenReturn(List.of("PAL-LAX-001"));
|
.thenReturn(List.of("PAL-LAX-001"));
|
||||||
InboundCodeRelationshipRows.InventorySku sku = new InboundCodeRelationshipRows.InventorySku();
|
InboundCodeRelationshipRows.InventorySku sku = new InboundCodeRelationshipRows.InventorySku();
|
||||||
@@ -60,6 +66,8 @@ class InboundCodeRelationshipServiceTest {
|
|||||||
assertThat(result.found()).isTrue();
|
assertThat(result.found()).isTrue();
|
||||||
assertThat(result.customer().customerId()).isEqualTo("2092618717861048321");
|
assertThat(result.customer().customerId()).isEqualTo("2092618717861048321");
|
||||||
assertThat(result.overseasWarehouse().warehouseId()).isEqualTo("193000000000200003");
|
assertThat(result.overseasWarehouse().warehouseId()).isEqualTo("193000000000200003");
|
||||||
|
assertThat(result.overseasWarehouse().warehouseCode()).isEqualTo("US-LAX-01");
|
||||||
|
assertThat(result.overseasWarehouse().warehouseName()).isEqualTo("洛杉矶一号仓");
|
||||||
assertThat(result.taillegOrders()).extracting("orderNo").containsExactly("LMO-260830-0001");
|
assertThat(result.taillegOrders()).extracting("orderNo").containsExactly("LMO-260830-0001");
|
||||||
assertThat(result.taillegOrders()).extracting("orderStatus").containsExactly("INBOUND_PLANNED");
|
assertThat(result.taillegOrders()).extracting("orderStatus").containsExactly("INBOUND_PLANNED");
|
||||||
assertThat(result.inboundPlans()).extracting("planNo").containsExactly("LIP-260830-0001");
|
assertThat(result.inboundPlans()).extracting("planNo").containsExactly("LIP-260830-0001");
|
||||||
@@ -81,6 +89,21 @@ class InboundCodeRelationshipServiceTest {
|
|||||||
verify(mapper, never()).inventory(anyString(), anyString());
|
verify(mapper, never()).inventory(anyString(), anyString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void orderWithoutAClaimedPlanDoesNotExposeDomesticSourceWarehouseAsOverseas() {
|
||||||
|
InboundCodeRelationshipRows.Base row = base("2092618717861048321", "Customer A");
|
||||||
|
row.setOverseasWarehouseId(null);
|
||||||
|
when(mapper.bases("NYEXX2608300027")).thenReturn(List.of(row));
|
||||||
|
when(mapper.palletCodes("2092618717861048321", "NYEXX2608300027")).thenReturn(List.of());
|
||||||
|
when(mapper.inventory("2092618717861048321", "NYEXX2608300027")).thenReturn(List.of());
|
||||||
|
|
||||||
|
var result = service.find("NYEXX2608300027");
|
||||||
|
|
||||||
|
assertThat(result.found()).isTrue();
|
||||||
|
assertThat(result.overseasWarehouse()).isNull();
|
||||||
|
verifyNoInteractions(warehouse);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void blankAndOversizedInboundCodesAreRejected() {
|
void blankAndOversizedInboundCodesAreRejected() {
|
||||||
assertThatThrownBy(() -> service.find(" ")).isInstanceOf(ResponseStatusException.class)
|
assertThatThrownBy(() -> service.find(" ")).isInstanceOf(ResponseStatusException.class)
|
||||||
@@ -96,7 +119,6 @@ class InboundCodeRelationshipServiceTest {
|
|||||||
value.setOrderNo("LMO-260830-0001"); value.setOrderStatus("INBOUND_PLANNED");
|
value.setOrderNo("LMO-260830-0001"); value.setOrderStatus("INBOUND_PLANNED");
|
||||||
value.setPlanNo("LIP-260830-0001"); value.setPlanStatus("COMPLETED");
|
value.setPlanNo("LIP-260830-0001"); value.setPlanStatus("COMPLETED");
|
||||||
value.setReceivingStatus("COMPLETED"); value.setOverseasWarehouseId("193000000000200003");
|
value.setReceivingStatus("COMPLETED"); value.setOverseasWarehouseId("193000000000200003");
|
||||||
value.setOverseasWarehouseCode("US-LAX-01"); value.setOverseasWarehouseName("洛杉矶一号仓");
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user