feat: gate overseas receiving and harden phase4 workflows
This commit is contained in:
+1
-1
@@ -29,7 +29,7 @@ import java.util.List;
|
||||
@RestController
|
||||
@RequestMapping("/api/pda/v1/last-leg/receiving-containers")
|
||||
@Tag(name = "Overseas PDA container receiving")
|
||||
@PreAuthorize("hasAuthority('lastleg:pda:operate')")
|
||||
@PreAuthorize("hasAuthority('lastleg:pda:operate') and hasAuthority('ROLE_WAREHOUSE_PICKER')")
|
||||
public class ReceivingContainerController {
|
||||
public static final String OPERATE_PERMISSION = PdaWarehouseIdentity.OPERATE_PERMISSION;
|
||||
@Resource private ReceivingContainerService service;
|
||||
|
||||
+28
@@ -114,6 +114,33 @@ public class HttpWarehouseResourceGateway implements WarehouseResourceGateway {
|
||||
response.data().fbaWarehouseCode(), response.data().version());
|
||||
}
|
||||
|
||||
@Override
|
||||
public WarehouseLocationReference resolveLocation(long warehouseId, String locationCode) {
|
||||
WarehouseLocationResponse response = client.get()
|
||||
.uri(uri -> uri.path("/internal/v1/warehouse-resource-locks/locations/resolve/{locationCode}")
|
||||
.queryParam("warehouseId", warehouseId).build(locationCode))
|
||||
.header("X-Internal-Service-Token", internalToken).retrieve()
|
||||
.body(WarehouseLocationResponse.class);
|
||||
return location(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WarehouseLocationReference resolveLocation(long warehouseId, long locationId) {
|
||||
WarehouseLocationResponse response = client.get()
|
||||
.uri(uri -> uri.path("/internal/v1/warehouse-resource-locks/locations/{locationId}")
|
||||
.queryParam("warehouseId", warehouseId).build(locationId))
|
||||
.header("X-Internal-Service-Token", internalToken).retrieve()
|
||||
.body(WarehouseLocationResponse.class);
|
||||
return location(response);
|
||||
}
|
||||
|
||||
private WarehouseLocationReference location(WarehouseLocationResponse response) {
|
||||
if (response == null || response.data() == null) {
|
||||
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Warehouse location was not found");
|
||||
}
|
||||
return response.data();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WarehouseReference requireActiveSharedWarehouse(long warehouseId) {
|
||||
WarehouseReferenceResponse response = client.get()
|
||||
@@ -147,4 +174,5 @@ public class HttpWarehouseResourceGateway implements WarehouseResourceGateway {
|
||||
private record ReserveEnvelope(ReserveData data) {}
|
||||
private record ReserveData(long lockId) {}
|
||||
private record WarehouseReferenceResponse(String code, String message, WarehouseReference data) {}
|
||||
private record WarehouseLocationResponse(String code, String message, WarehouseLocationReference data) {}
|
||||
}
|
||||
|
||||
+8
@@ -8,6 +8,12 @@ public interface WarehouseResourceGateway {
|
||||
void scrap(String customerId, long resourceLockId);
|
||||
void scrapPallet(String customerId, long palletId);
|
||||
WarehousePalletReference resolvePallet(String palletCode);
|
||||
default WarehouseLocationReference resolveLocation(long warehouseId, String locationCode) {
|
||||
throw new UnsupportedOperationException("Warehouse location resolution is not configured");
|
||||
}
|
||||
default WarehouseLocationReference resolveLocation(long warehouseId, long locationId) {
|
||||
throw new UnsupportedOperationException("Warehouse location resolution is not configured");
|
||||
}
|
||||
default WarehouseReference requireActiveSharedWarehouse(long warehouseId) {
|
||||
throw new UnsupportedOperationException("Shared warehouse resolution is not configured");
|
||||
}
|
||||
@@ -21,4 +27,6 @@ public interface WarehouseResourceGateway {
|
||||
|
||||
record WarehouseReference(long warehouseId, String warehouseCode, String warehouseName,
|
||||
String status) { }
|
||||
record WarehouseLocationReference(long locationId, String locationCode, String locationType,
|
||||
java.math.BigDecimal maxLoadKg, String status) { }
|
||||
}
|
||||
|
||||
+18
-2
@@ -27,6 +27,7 @@ import com.baiyue.lastleg.inboundplan.pda.mapper.ReceivingContainerSessionMapper
|
||||
import com.baiyue.lastleg.inboundplan.pda.mapper.ReceivingSkuReceiptMapper;
|
||||
import com.baiyue.lastleg.mapper.LastlegOrderDetailMapper;
|
||||
import com.baiyue.lastleg.mapper.LastlegOrderMapper;
|
||||
import com.baiyue.lastleg.shipping.mapper.ContainerShippingGateMapper;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.MapperFeature;
|
||||
@@ -67,6 +68,7 @@ public class ReceivingContainerService {
|
||||
@Resource private ReceivingContainerSessionMapper sessions;
|
||||
@Resource private ReceivingContainerOperationMapper operations;
|
||||
@Resource private ReceivingSkuReceiptMapper skuReceipts;
|
||||
@Resource private ContainerShippingGateMapper shippingGates;
|
||||
@Resource private WarehouseResourceGateway warehouse;
|
||||
@Resource private UnloadPhotoFileGateway unloadPhotos;
|
||||
@Resource private InboundPdaWorkflowService workflow;
|
||||
@@ -104,7 +106,8 @@ public class ReceivingContainerService {
|
||||
public ReceivingContainerResponses.Session detail(String operatorKey, long overseasWarehouseId, String containerNo) {
|
||||
List<InboundPlan> containerPlans = requirePlans(containerNo);
|
||||
String customerId = requireSingleCustomer(containerPlans, containerNo);
|
||||
if (!eligible(containerPlans, overseasWarehouseId)) throw notFound("Container is assigned to another overseas warehouse");
|
||||
if (!warehouseEligible(containerPlans, overseasWarehouseId)) throw notFound("Container is assigned to another overseas warehouse");
|
||||
requireReceivingAvailable(customerId, containerNo);
|
||||
ReceivingContainerSession current = sessions.findActiveByOperator(activeOperatorKey(operatorKey));
|
||||
requireSessionWarehouse(current, overseasWarehouseId);
|
||||
if (current != null && !containerNo.equals(current.getContainerNo())) {
|
||||
@@ -130,7 +133,8 @@ public class ReceivingContainerService {
|
||||
}
|
||||
List<InboundPlan> containerPlans = requirePlans(containerNo);
|
||||
String customerId = requireSingleCustomer(containerPlans, containerNo);
|
||||
if (!eligible(containerPlans, overseasWarehouseId)) throw conflict("Container is assigned to another overseas warehouse");
|
||||
if (!warehouseEligible(containerPlans, overseasWarehouseId)) throw conflict("Container is assigned to another overseas warehouse");
|
||||
requireReceivingAvailable(customerId, containerNo);
|
||||
String activeOperatorKey = activeOperatorKey(operatorKey);
|
||||
ReceivingContainerSession active = sessions.lockActiveByOperator(activeOperatorKey);
|
||||
requireSessionWarehouse(active, overseasWarehouseId);
|
||||
@@ -641,6 +645,12 @@ public class ReceivingContainerService {
|
||||
}
|
||||
|
||||
private boolean eligible(List<InboundPlan> containerPlans, long overseasWarehouseId) {
|
||||
String customerId = requireSingleCustomer(containerPlans, containerPlans.get(0).getContainerNo());
|
||||
return warehouseEligible(containerPlans, overseasWarehouseId)
|
||||
&& shippingGates.receivingAvailable(customerId, containerPlans.get(0).getContainerNo()) == 1;
|
||||
}
|
||||
|
||||
private boolean warehouseEligible(List<InboundPlan> containerPlans, long overseasWarehouseId) {
|
||||
Set<Long> assigned = containerPlans.stream().map(InboundPlan::getOverseasWarehouseId)
|
||||
.filter(Objects::nonNull).collect(Collectors.toSet());
|
||||
if (assigned.size() > 1 || (!assigned.isEmpty() && containerPlans.stream()
|
||||
@@ -650,6 +660,12 @@ public class ReceivingContainerService {
|
||||
return assigned.isEmpty() || assigned.contains(overseasWarehouseId);
|
||||
}
|
||||
|
||||
private void requireReceivingAvailable(String customerId, String containerNo) {
|
||||
if (shippingGates.receivingAvailable(customerId, containerNo) != 1) {
|
||||
throw conflict("Container has not reached PICKUP_READY and is not available for overseas receiving");
|
||||
}
|
||||
}
|
||||
|
||||
private void claimReceivingWarehouse(String customerId, List<InboundPlan> containerPlans,
|
||||
WarehouseResourceGateway.WarehouseReference warehouse) {
|
||||
long overseasWarehouseId = warehouse.warehouseId();
|
||||
|
||||
Reference in New Issue
Block a user