提交
This commit is contained in:
+14
-1
@@ -32,11 +32,19 @@ public class DeliveryTransferController {
|
|||||||
return ApiResponse.success(service.transfer(scope(user, customerId), dispatchNo, operator(user), request));
|
return ApiResponse.success(service.transfer(scope(user, customerId), dispatchNo, operator(user), request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/outbound-orders/one-click-dropship")
|
||||||
|
@Operation(summary = "Create one-click dropship outbound and push a PDA picking task")
|
||||||
|
public ApiResponse<DeliveryResponses.PdaTask> createOneClick(
|
||||||
|
@AuthenticationPrincipal AuthenticatedUser user, @RequestParam(required = false) String customerId,
|
||||||
|
@Valid @RequestBody DeliveryRequests.OneClickOutbound request) {
|
||||||
|
return ApiResponse.success(service.createOneClick(scope(user, customerId), operator(user), request));
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/outbound-orders")
|
@GetMapping("/outbound-orders")
|
||||||
public ApiResponse<PageResult<DeliveryResponses.OutboundRow>> outboundPage(
|
public ApiResponse<PageResult<DeliveryResponses.OutboundRow>> outboundPage(
|
||||||
@AuthenticationPrincipal AuthenticatedUser user, @RequestParam(required = false) String customerId,
|
@AuthenticationPrincipal AuthenticatedUser user, @RequestParam(required = false) String customerId,
|
||||||
@Valid DeliveryRequests.Query query) {
|
@Valid DeliveryRequests.Query query) {
|
||||||
return ApiResponse.success(service.outboundPage(scope(user, customerId), query));
|
return ApiResponse.success(service.outboundPage(listScope(user, customerId), query));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/outbound-orders/{outboundNo}")
|
@GetMapping("/outbound-orders/{outboundNo}")
|
||||||
@@ -73,4 +81,9 @@ public class DeliveryTransferController {
|
|||||||
private String operator(AuthenticatedUser user) {
|
private String operator(AuthenticatedUser user) {
|
||||||
return user.userId() == null ? user.username() : String.valueOf(user.userId());
|
return user.userId() == null ? user.username() : String.valueOf(user.userId());
|
||||||
}
|
}
|
||||||
|
private String listScope(AuthenticatedUser user, String requestedCustomer) {
|
||||||
|
if (user == null || user.tenantId() == null) throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
||||||
|
if ("PLATFORM".equals(user.appCode()) && user.tenantId() == 0L) return requestedCustomer == null || requestedCustomer.isBlank() ? null : requestedCustomer.trim();
|
||||||
|
return String.valueOf(user.tenantId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
package com.baiyue.lastleg.delivery.controller;
|
||||||
|
|
||||||
|
import com.baiyue.common.core.api.ApiResponse;
|
||||||
|
import com.baiyue.common.security.AuthenticatedUser;
|
||||||
|
import com.baiyue.lastleg.delivery.dto.DeliveryRequests;
|
||||||
|
import com.baiyue.lastleg.delivery.dto.DeliveryResponses;
|
||||||
|
import com.baiyue.lastleg.delivery.service.DeliveryTransferService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@ConditionalOnProperty(name="lastleg.future-outbound-api.enabled", havingValue="true")
|
||||||
|
@RequestMapping("/api/pda/v1/last-leg/outbound-tasks")
|
||||||
|
public class OutboundPdaController {
|
||||||
|
@Resource private DeliveryTransferService service;
|
||||||
|
@PostMapping("/{taskNo}/pick")
|
||||||
|
public ApiResponse<DeliveryResponses.PdaTask> pick(@AuthenticationPrincipal AuthenticatedUser user,
|
||||||
|
@PathVariable String taskNo, @RequestParam(required=false) String customerId,
|
||||||
|
@Valid @RequestBody DeliveryRequests.PdaPick request) {
|
||||||
|
return ApiResponse.success(service.pdaPick(scope(user, customerId), operator(user), taskNo, request));
|
||||||
|
}
|
||||||
|
@GetMapping
|
||||||
|
public ApiResponse<java.util.List<DeliveryResponses.PdaTask>> list(@AuthenticationPrincipal AuthenticatedUser user,
|
||||||
|
@RequestParam(required=false) String customerId, @RequestParam(required=false) String status) {
|
||||||
|
return ApiResponse.success(service.pdaTasks(scope(user, customerId), status));
|
||||||
|
}
|
||||||
|
@PostMapping("/{taskNo}/complete")
|
||||||
|
public ApiResponse<DeliveryResponses.PdaTask> complete(@AuthenticationPrincipal AuthenticatedUser user,
|
||||||
|
@PathVariable String taskNo, @RequestParam(required=false) String customerId) {
|
||||||
|
return ApiResponse.success(service.completePda(scope(user, customerId), taskNo));
|
||||||
|
}
|
||||||
|
private String scope(AuthenticatedUser user, String requested) {
|
||||||
|
if (user == null || user.tenantId() == null) throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
||||||
|
if (requested != null && !requested.isBlank()) return requested.trim();
|
||||||
|
return String.valueOf(user.tenantId());
|
||||||
|
}
|
||||||
|
private String operator(AuthenticatedUser user) { return user.userId() == null ? user.username() : String.valueOf(user.userId()); }
|
||||||
|
}
|
||||||
@@ -3,7 +3,10 @@ package com.baiyue.lastleg.delivery.dto;
|
|||||||
import jakarta.validation.constraints.Max;
|
import jakarta.validation.constraints.Max;
|
||||||
import jakarta.validation.constraints.Min;
|
import jakarta.validation.constraints.Min;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public final class DeliveryRequests {
|
public final class DeliveryRequests {
|
||||||
private DeliveryRequests() {}
|
private DeliveryRequests() {}
|
||||||
@@ -20,4 +23,13 @@ public final class DeliveryRequests {
|
|||||||
String destinationWarehouseCode) {
|
String destinationWarehouseCode) {
|
||||||
public PalletQuery { if (page == 0) page = 1; if (size == 0) size = 20; }
|
public PalletQuery { if (page == 0) page = 1; if (size == 0) size = 20; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public record OneClickOutbound(@NotBlank @Size(max=1000) String recipient,
|
||||||
|
@NotNull @Size(min=1, max=200) List<@Valid OneClickItem> items,
|
||||||
|
@Size(max=1000) String remark,
|
||||||
|
@NotBlank @Size(max=255) String idempotencyKey) {}
|
||||||
|
public record OneClickItem(@NotNull Long inventoryPositionId, @NotNull @Min(1) Long packages,
|
||||||
|
@NotBlank @Size(max=128) String sku) {}
|
||||||
|
public record PdaPick(@NotNull Long outboundPalletItemId, @NotNull Long inventoryPositionId,
|
||||||
|
@NotNull @Min(1) Long packages, @NotBlank @Size(max=255) String idempotencyKey) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,4 +17,5 @@ public final class DeliveryResponses {
|
|||||||
int packageCount, LocalDateTime createdAt) {}
|
int packageCount, LocalDateTime createdAt) {}
|
||||||
|
|
||||||
public record OutboundDetail(OutboundRow outbound, DeliveryRow delivery) {}
|
public record OutboundDetail(OutboundRow outbound, DeliveryRow delivery) {}
|
||||||
|
public record PdaTask(Long id, String taskNo, String status, String outboundNo, LocalDateTime pushedAt, LocalDateTime completedAt) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ public class OutboundOrder {
|
|||||||
private Long dispatchOrderId;
|
private Long dispatchOrderId;
|
||||||
private String dispatchNo;
|
private String dispatchNo;
|
||||||
private String overseasWarehouseId;
|
private String overseasWarehouseId;
|
||||||
|
private String outboundType;
|
||||||
|
private String recipientInfo;
|
||||||
private String status;
|
private String status;
|
||||||
private Integer packageCount;
|
private Integer packageCount;
|
||||||
private Integer palletCount;
|
private Integer palletCount;
|
||||||
|
|||||||
+3
@@ -21,6 +21,9 @@ public class OutboundPalletItem {
|
|||||||
private String destinationWarehouseCode;
|
private String destinationWarehouseCode;
|
||||||
private String destinationWarehouseName;
|
private String destinationWarehouseName;
|
||||||
private Integer packageCount;
|
private Integer packageCount;
|
||||||
|
private Integer pickedPackageCount;
|
||||||
|
private String status;
|
||||||
|
private String skuCode;
|
||||||
private String orderRefs;
|
private String orderRefs;
|
||||||
private String inboundCode;
|
private String inboundCode;
|
||||||
private LocalDateTime createdAt;
|
private LocalDateTime createdAt;
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.baiyue.lastleg.delivery.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("ll_outbound_pda_pick")
|
||||||
|
public class OutboundPdaPick {
|
||||||
|
@TableId(type = IdType.ASSIGN_ID) private Long id;
|
||||||
|
private String customerId;
|
||||||
|
private Long taskId;
|
||||||
|
private Long outboundPalletItemId;
|
||||||
|
private Long inventoryPositionId;
|
||||||
|
private Long packages;
|
||||||
|
private String idempotencyKey;
|
||||||
|
private LocalDateTime pickedAt;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.baiyue.lastleg.delivery.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("ll_outbound_pda_task")
|
||||||
|
public class OutboundPdaTask {
|
||||||
|
@TableId(type = IdType.ASSIGN_ID) private Long id;
|
||||||
|
private String customerId;
|
||||||
|
private Long outboundOrderId;
|
||||||
|
private String taskNo;
|
||||||
|
private String status;
|
||||||
|
private LocalDateTime pushedAt;
|
||||||
|
private LocalDateTime completedAt;
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
}
|
||||||
+2
@@ -14,4 +14,6 @@ public interface OutboundOrderMapper extends BaseMapper<OutboundOrder> {
|
|||||||
OutboundOrder findByIdempotency(@Param("customerId") String customerId, @Param("key") String key);
|
OutboundOrder findByIdempotency(@Param("customerId") String customerId, @Param("key") String key);
|
||||||
@Select("SELECT * FROM ll_outbound_order WHERE customer_id=#{customerId} AND dispatch_order_id=#{dispatchOrderId} LIMIT 1 FOR UPDATE")
|
@Select("SELECT * FROM ll_outbound_order WHERE customer_id=#{customerId} AND dispatch_order_id=#{dispatchOrderId} LIMIT 1 FOR UPDATE")
|
||||||
OutboundOrder lockByDispatch(@Param("customerId") String customerId, @Param("dispatchOrderId") Long dispatchOrderId);
|
OutboundOrder lockByDispatch(@Param("customerId") String customerId, @Param("dispatchOrderId") Long dispatchOrderId);
|
||||||
|
@Select("SELECT * FROM ll_outbound_order WHERE customer_id=#{customerId} AND outbound_no=#{outboundNo} LIMIT 1 FOR UPDATE")
|
||||||
|
OutboundOrder lockByNo(@Param("customerId") String customerId, @Param("outboundNo") String outboundNo);
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package com.baiyue.lastleg.delivery.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baiyue.lastleg.delivery.entity.OutboundPdaPick;
|
||||||
|
import org.apache.ibatis.annotations.*;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface OutboundPdaPickMapper extends BaseMapper<OutboundPdaPick> {
|
||||||
|
@Select("SELECT * FROM ll_outbound_pda_pick WHERE customer_id=#{customerId} AND idempotency_key=#{key} LIMIT 1")
|
||||||
|
OutboundPdaPick findByKey(@Param("customerId") String customerId, @Param("key") String key);
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package com.baiyue.lastleg.delivery.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baiyue.lastleg.delivery.entity.OutboundPdaTask;
|
||||||
|
import org.apache.ibatis.annotations.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface OutboundPdaTaskMapper extends BaseMapper<OutboundPdaTask> {
|
||||||
|
@Select("SELECT * FROM ll_outbound_pda_task WHERE customer_id=#{customerId} AND outbound_order_id=#{outboundOrderId} LIMIT 1 FOR UPDATE")
|
||||||
|
OutboundPdaTask lockByOutbound(@Param("customerId") String customerId, @Param("outboundOrderId") Long outboundOrderId);
|
||||||
|
@Select("SELECT * FROM ll_outbound_pda_task WHERE customer_id=#{customerId} AND task_no=#{taskNo} LIMIT 1 FOR UPDATE")
|
||||||
|
OutboundPdaTask lockByNo(@Param("customerId") String customerId, @Param("taskNo") String taskNo);
|
||||||
|
@Select("SELECT * FROM ll_outbound_pda_task WHERE customer_id=#{customerId} AND (#{status} IS NULL OR status=#{status}) ORDER BY pushed_at DESC LIMIT 200")
|
||||||
|
List<OutboundPdaTask> list(@Param("customerId") String customerId, @Param("status") String status);
|
||||||
|
}
|
||||||
+95
-3
@@ -22,6 +22,19 @@ import com.baiyue.lastleg.inboundplan.entity.InboundPlanLine;
|
|||||||
import com.baiyue.lastleg.inboundplan.entity.InboundPlanPalletAllocation;
|
import com.baiyue.lastleg.inboundplan.entity.InboundPlanPalletAllocation;
|
||||||
import com.baiyue.lastleg.inboundplan.mapper.InboundPlanLineMapper;
|
import com.baiyue.lastleg.inboundplan.mapper.InboundPlanLineMapper;
|
||||||
import com.baiyue.lastleg.inboundplan.mapper.InboundPlanPalletAllocationMapper;
|
import com.baiyue.lastleg.inboundplan.mapper.InboundPlanPalletAllocationMapper;
|
||||||
|
import com.baiyue.lastleg.delivery.entity.OutboundPdaTask;
|
||||||
|
import com.baiyue.lastleg.delivery.entity.OutboundPdaPick;
|
||||||
|
import com.baiyue.lastleg.delivery.mapper.OutboundPdaTaskMapper;
|
||||||
|
import com.baiyue.lastleg.delivery.mapper.OutboundPdaPickMapper;
|
||||||
|
import com.baiyue.lastleg.inventory.command.dto.InventoryCommandRequests;
|
||||||
|
import com.baiyue.lastleg.inventory.command.service.InventoryCommandService;
|
||||||
|
import com.baiyue.lastleg.inventory.entity.InventoryPosition;
|
||||||
|
import com.baiyue.lastleg.inventory.mapper.InventoryPositionMapper;
|
||||||
|
import com.baiyue.lastleg.dropship.entity.DropshipOrderProfile;
|
||||||
|
import com.baiyue.lastleg.dropship.entity.DropshipCarton;
|
||||||
|
import com.baiyue.lastleg.dropship.mapper.DropshipOrderProfileMapper;
|
||||||
|
import com.baiyue.lastleg.dropship.mapper.DropshipCartonMapper;
|
||||||
|
import com.baiyue.lastleg.dropship.mapper.DropshipSkuInventoryMapper;
|
||||||
import com.baiyue.lastleg.mapper.LastlegOrderMapper;
|
import com.baiyue.lastleg.mapper.LastlegOrderMapper;
|
||||||
import com.baiyue.lastleg.mapper.LastlegOrderStatusHistoryMapper;
|
import com.baiyue.lastleg.mapper.LastlegOrderStatusHistoryMapper;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
@@ -43,6 +56,13 @@ public class DeliveryTransferService {
|
|||||||
@Resource private OutboundOrderMapper outboundOrders;
|
@Resource private OutboundOrderMapper outboundOrders;
|
||||||
@Resource private OutboundPalletItemMapper outboundPallets;
|
@Resource private OutboundPalletItemMapper outboundPallets;
|
||||||
@Resource private DeliveryOrderMapper deliveryOrders;
|
@Resource private DeliveryOrderMapper deliveryOrders;
|
||||||
|
@Resource private OutboundPdaTaskMapper pdaTasks;
|
||||||
|
@Resource private OutboundPdaPickMapper pdaPicks;
|
||||||
|
@Resource private InventoryPositionMapper inventoryPositions;
|
||||||
|
@Resource private InventoryCommandService inventoryCommands;
|
||||||
|
@Resource private DropshipOrderProfileMapper dropshipProfiles;
|
||||||
|
@Resource private DropshipCartonMapper dropshipCartons;
|
||||||
|
@Resource private DropshipSkuInventoryMapper dropshipSkuInventory;
|
||||||
@Resource private InboundPlanPalletAllocationMapper planAllocations;
|
@Resource private InboundPlanPalletAllocationMapper planAllocations;
|
||||||
@Resource private InboundPlanLineMapper planLines;
|
@Resource private InboundPlanLineMapper planLines;
|
||||||
@Resource private LastlegOrderMapper tailOrders;
|
@Resource private LastlegOrderMapper tailOrders;
|
||||||
@@ -76,7 +96,7 @@ public class DeliveryTransferService {
|
|||||||
outbound.setId(IdWorker.getId()); outbound.setCustomerId(customerId);
|
outbound.setId(IdWorker.getId()); outbound.setCustomerId(customerId);
|
||||||
outbound.setOutboundNo("OUT" + now.format(DateTimeFormatter.BASIC_ISO_DATE) + outbound.getId());
|
outbound.setOutboundNo("OUT" + now.format(DateTimeFormatter.BASIC_ISO_DATE) + outbound.getId());
|
||||||
outbound.setDispatchOrderId(dispatch.getId()); outbound.setDispatchNo(dispatch.getDispatchNo());
|
outbound.setDispatchOrderId(dispatch.getId()); outbound.setDispatchNo(dispatch.getDispatchNo());
|
||||||
outbound.setOverseasWarehouseId(dispatch.getOverseasWarehouseId()); outbound.setStatus("WAIT_OUTBOUND");
|
outbound.setOverseasWarehouseId(dispatch.getOverseasWarehouseId()); outbound.setStatus("WAIT_OUTBOUND"); outbound.setOutboundType("DISPATCH_DELIVERY");
|
||||||
outbound.setPackageCount(items.stream().map(DispatchItem::getPackageCount).filter(Objects::nonNull).mapToInt(Integer::intValue).sum());
|
outbound.setPackageCount(items.stream().map(DispatchItem::getPackageCount).filter(Objects::nonNull).mapToInt(Integer::intValue).sum());
|
||||||
outbound.setPalletCount(items.size()); outbound.setIdempotencyKey(request.idempotencyKey().trim());
|
outbound.setPalletCount(items.size()); outbound.setIdempotencyKey(request.idempotencyKey().trim());
|
||||||
outbound.setCreatedBy(operatorId); outbound.setCreatedAt(now); outbound.setUpdatedAt(now);
|
outbound.setCreatedBy(operatorId); outbound.setCreatedAt(now); outbound.setUpdatedAt(now);
|
||||||
@@ -103,7 +123,7 @@ public class DeliveryTransferService {
|
|||||||
item.setDestinationWarehouseId(source.getDestinationWarehouseId());
|
item.setDestinationWarehouseId(source.getDestinationWarehouseId());
|
||||||
item.setDestinationWarehouseCode(source.getDestinationWarehouseCode());
|
item.setDestinationWarehouseCode(source.getDestinationWarehouseCode());
|
||||||
item.setDestinationWarehouseName(source.getDestinationWarehouseName());
|
item.setDestinationWarehouseName(source.getDestinationWarehouseName());
|
||||||
item.setPackageCount(Objects.requireNonNullElse(source.getPackageCount(), 0));
|
item.setPackageCount(Objects.requireNonNullElse(source.getPackageCount(), 0)); item.setPickedPackageCount(0); item.setStatus("WAIT_PICK");
|
||||||
item.setOrderRefs(source.getOrderRefs()); item.setInboundCode(source.getInboundCode()); item.setCreatedAt(now);
|
item.setOrderRefs(source.getOrderRefs()); item.setInboundCode(source.getInboundCode()); item.setCreatedAt(now);
|
||||||
outboundPallets.insert(item);
|
outboundPallets.insert(item);
|
||||||
}
|
}
|
||||||
@@ -121,9 +141,81 @@ public class DeliveryTransferService {
|
|||||||
return result(outbound, delivery, false);
|
return result(outbound, delivery, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public DeliveryResponses.PdaTask createOneClick(String customerId, String operatorId, DeliveryRequests.OneClickOutbound request) {
|
||||||
|
OutboundOrder existing = outboundOrders.findByIdempotency(customerId, request.idempotencyKey().trim());
|
||||||
|
if (existing != null) return taskResult(existing, pdaTasks.lockByOutbound(customerId, existing.getId()));
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
OutboundOrder outbound = new OutboundOrder();
|
||||||
|
outbound.setId(IdWorker.getId()); outbound.setCustomerId(customerId);
|
||||||
|
outbound.setOutboundNo("FBOO" + now.format(DateTimeFormatter.BASIC_ISO_DATE) + outbound.getId());
|
||||||
|
outbound.setOutboundType("ONE_CLICK_DROPSHIP"); outbound.setStatus("WAIT_PICK"); outbound.setRecipientInfo(request.recipient().trim());
|
||||||
|
outbound.setPackageCount(request.items().stream().mapToInt(i -> i.packages().intValue()).sum()); outbound.setPalletCount(request.items().size());
|
||||||
|
outbound.setIdempotencyKey(request.idempotencyKey().trim()); outbound.setCreatedBy(operatorId); outbound.setCreatedAt(now); outbound.setUpdatedAt(now);
|
||||||
|
outboundOrders.insert(outbound);
|
||||||
|
String selectedWarehouseId = null;
|
||||||
|
for (DeliveryRequests.OneClickItem input : request.items()) {
|
||||||
|
InventoryPosition position = inventoryPositions.selectById(input.inventoryPositionId());
|
||||||
|
if (position == null || !customerId.equals(position.getCustomerId())) throw notFound("Inventory position not found");
|
||||||
|
DropshipOrderProfile profile = dropshipProfiles.findPosition(customerId, position.getId());
|
||||||
|
if (profile == null) throw conflict("Selected pallet is not one-click dropship inventory");
|
||||||
|
if (selectedWarehouseId == null) selectedWarehouseId = position.getOverseasWarehouseId();
|
||||||
|
else if (!Objects.equals(selectedWarehouseId, position.getOverseasWarehouseId())) throw conflict("One outbound order must use inventory from the same overseas warehouse");
|
||||||
|
if (value(position.getAvailablePackages()) < input.packages()) throw conflict("Insufficient available inventory for pallet " + position.getPalletNo());
|
||||||
|
OutboundPalletItem item = new OutboundPalletItem(); item.setId(IdWorker.getId()); item.setCustomerId(customerId); item.setOutboundOrderId(outbound.getId());
|
||||||
|
item.setWarehousePalletId(position.getPalletId()); item.setPalletNo(position.getPalletNo()); item.setPackageCount(input.packages().intValue()); item.setPickedPackageCount(0); item.setStatus("WAIT_PICK"); item.setSkuCode(input.sku().trim()); item.setCreatedAt(now);
|
||||||
|
outboundPallets.insert(item);
|
||||||
|
}
|
||||||
|
outbound.setOverseasWarehouseId(selectedWarehouseId); outboundOrders.updateById(outbound);
|
||||||
|
OutboundPdaTask task = new OutboundPdaTask(); task.setId(IdWorker.getId()); task.setCustomerId(customerId); task.setOutboundOrderId(outbound.getId());
|
||||||
|
task.setTaskNo("PDA" + now.format(DateTimeFormatter.BASIC_ISO_DATE) + task.getId()); task.setStatus("PENDING"); task.setPushedAt(now); task.setCreatedAt(now); task.setUpdatedAt(now); pdaTasks.insert(task);
|
||||||
|
return taskResult(outbound, task);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public DeliveryResponses.PdaTask pdaPick(String customerId, String operatorId, String taskNo, DeliveryRequests.PdaPick request) {
|
||||||
|
OutboundPdaTask task = pdaTasks.lockByNo(customerId, taskNo); if (task == null) throw notFound("PDA task not found");
|
||||||
|
OutboundPdaPick replay = pdaPicks.findByKey(customerId, request.idempotencyKey().trim()); if (replay != null) return taskResult(outboundOrders.selectById(task.getOutboundOrderId()), task);
|
||||||
|
OutboundOrder outbound = outboundOrders.lockByNo(customerId, outboundNo(task.getOutboundOrderId()));
|
||||||
|
OutboundPalletItem item = outboundPallets.selectById(request.outboundPalletItemId());
|
||||||
|
if (item == null || !task.getOutboundOrderId().equals(item.getOutboundOrderId())) throw notFound("Outbound pallet item not found");
|
||||||
|
if (request.packages() > item.getPackageCount() - value(item.getPickedPackageCount())) throw conflict("Picked quantity exceeds outbound pallet quantity");
|
||||||
|
InventoryPosition selectedPosition = inventoryPositions.selectById(request.inventoryPositionId());
|
||||||
|
if (selectedPosition == null || !customerId.equals(selectedPosition.getCustomerId()) || !Objects.equals(selectedPosition.getPalletId(), item.getWarehousePalletId())) throw conflict("Scanned inventory position does not belong to the outbound pallet");
|
||||||
|
DropshipOrderProfile profile = dropshipProfiles.findPosition(customerId, request.inventoryPositionId());
|
||||||
|
if (profile == null) throw conflict("Scanned pallet is not one-click dropship inventory");
|
||||||
|
List<DropshipCarton> cartons = dropshipCartons.lockAvailable(customerId, profile.getId(), item.getSkuCode(), request.packages());
|
||||||
|
if (cartons.size() != request.packages()) throw conflict("Insufficient available one-click dropship cartons");
|
||||||
|
InventoryCommandRequests.Move move = new InventoryCommandRequests.Move(request.inventoryPositionId(), request.packages(), outbound.getOutboundNo(), outbound.getOutboundNo(), null, request.idempotencyKey() + ":ALLOCATE", null);
|
||||||
|
inventoryCommands.allocate(customerId, operatorId, move);
|
||||||
|
inventoryCommands.pick(customerId, operatorId, new InventoryCommandRequests.Move(request.inventoryPositionId(), request.packages(), outbound.getOutboundNo(), outbound.getOutboundNo(), null, request.idempotencyKey() + ":PICK", null));
|
||||||
|
inventoryCommands.ship(customerId, operatorId, new InventoryCommandRequests.Move(request.inventoryPositionId(), request.packages(), outbound.getOutboundNo(), outbound.getOutboundNo(), null, request.idempotencyKey() + ":SHIP", null));
|
||||||
|
if (dropshipSkuInventory.deduct(customerId, profile.getId(), item.getSkuCode(), request.packages()) != 1) throw conflict("Insufficient one-click dropship SKU inventory");
|
||||||
|
for (DropshipCarton carton : cartons) { carton.setStatus("SHIPPED"); carton.setOutboundOrderNo(outbound.getOutboundNo()); carton.setVersion((carton.getVersion() == null ? 0 : carton.getVersion()) + 1); carton.setUpdatedAt(LocalDateTime.now()); dropshipCartons.updateById(carton); }
|
||||||
|
OutboundPdaPick pick = new OutboundPdaPick(); pick.setId(IdWorker.getId()); pick.setCustomerId(customerId); pick.setTaskId(task.getId()); pick.setOutboundPalletItemId(item.getId()); pick.setInventoryPositionId(request.inventoryPositionId()); pick.setPackages(request.packages()); pick.setIdempotencyKey(request.idempotencyKey().trim()); pick.setPickedAt(LocalDateTime.now()); pdaPicks.insert(pick);
|
||||||
|
item.setPickedPackageCount(value(item.getPickedPackageCount()) + request.packages().intValue()); item.setStatus(item.getPickedPackageCount() >= item.getPackageCount() ? "PICKED" : "PARTIAL_PICKED"); outboundPallets.updateById(item);
|
||||||
|
task.setStatus("IN_PROGRESS"); task.setUpdatedAt(LocalDateTime.now()); pdaTasks.updateById(task);
|
||||||
|
return taskResult(outbound, task);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public DeliveryResponses.PdaTask completePda(String customerId, String taskNo) {
|
||||||
|
OutboundPdaTask task = pdaTasks.lockByNo(customerId, taskNo); if (task == null) throw notFound("PDA task not found");
|
||||||
|
OutboundOrder outbound = outboundOrders.selectById(task.getOutboundOrderId());
|
||||||
|
List<OutboundPalletItem> items = outboundPallets.findByOutbound(customerId, outbound.getId());
|
||||||
|
if (items.stream().anyMatch(i -> value(i.getPickedPackageCount()) < value(i.getPackageCount()))) throw conflict("All outbound pallets must be picked before completion");
|
||||||
|
task.setStatus("COMPLETED"); task.setCompletedAt(LocalDateTime.now()); task.setUpdatedAt(LocalDateTime.now()); pdaTasks.updateById(task); outbound.setStatus("OUTBOUNDED"); outbound.setUpdatedAt(LocalDateTime.now()); outboundOrders.updateById(outbound); return taskResult(outbound, task);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DeliveryResponses.PdaTask> pdaTasks(String customerId, String status) { return pdaTasks.list(customerId, StringUtils.hasText(status) ? status : null).stream().map(task -> taskResult(outboundOrders.selectById(task.getOutboundOrderId()), task)).toList(); }
|
||||||
|
|
||||||
|
private DeliveryResponses.PdaTask taskResult(OutboundOrder outbound, OutboundPdaTask task) { return new DeliveryResponses.PdaTask(task.getId(), task.getTaskNo(), task.getStatus(), outbound.getOutboundNo(), task.getPushedAt(), task.getCompletedAt()); }
|
||||||
|
private String outboundNo(Long id) { OutboundOrder value = outboundOrders.selectById(id); return value == null ? "" : value.getOutboundNo(); }
|
||||||
|
private int value(Integer value) { return value == null ? 0 : value; }
|
||||||
|
|
||||||
public PageResult<DeliveryResponses.OutboundRow> outboundPage(String customerId, DeliveryRequests.Query query) {
|
public PageResult<DeliveryResponses.OutboundRow> outboundPage(String customerId, DeliveryRequests.Query query) {
|
||||||
Page<OutboundOrder> page = outboundOrders.selectPage(new Page<>(query.page(), query.size()),
|
Page<OutboundOrder> page = outboundOrders.selectPage(new Page<>(query.page(), query.size()),
|
||||||
new LambdaQueryWrapper<OutboundOrder>().eq(OutboundOrder::getCustomerId, customerId)
|
new LambdaQueryWrapper<OutboundOrder>().eq(StringUtils.hasText(customerId), OutboundOrder::getCustomerId, customerId)
|
||||||
.like(StringUtils.hasText(query.documentNo()), OutboundOrder::getOutboundNo, query.documentNo())
|
.like(StringUtils.hasText(query.documentNo()), OutboundOrder::getOutboundNo, query.documentNo())
|
||||||
.eq(StringUtils.hasText(query.warehouseId()), OutboundOrder::getOverseasWarehouseId, query.warehouseId())
|
.eq(StringUtils.hasText(query.warehouseId()), OutboundOrder::getOverseasWarehouseId, query.warehouseId())
|
||||||
.eq(StringUtils.hasText(query.status()), OutboundOrder::getStatus, query.status())
|
.eq(StringUtils.hasText(query.status()), OutboundOrder::getStatus, query.status())
|
||||||
|
|||||||
+2
@@ -12,4 +12,6 @@ public interface DropshipCartonMapper extends BaseMapper<DropshipCarton> {
|
|||||||
|
|
||||||
@Select("SELECT * FROM ll_dropship_carton WHERE customer_id=#{customerId} AND order_id=#{orderId} ORDER BY profile_id,carton_sequence")
|
@Select("SELECT * FROM ll_dropship_carton WHERE customer_id=#{customerId} AND order_id=#{orderId} ORDER BY profile_id,carton_sequence")
|
||||||
List<DropshipCarton> listOrder(@Param("customerId") String customerId, @Param("orderId") Long orderId);
|
List<DropshipCarton> listOrder(@Param("customerId") String customerId, @Param("orderId") Long orderId);
|
||||||
|
@Select("SELECT * FROM ll_dropship_carton WHERE customer_id=#{customerId} AND profile_id=#{profileId} AND sku_code=#{sku} AND status='AVAILABLE' ORDER BY carton_sequence LIMIT #{packages} FOR UPDATE")
|
||||||
|
List<DropshipCarton> lockAvailable(@Param("customerId") String customerId, @Param("profileId") Long profileId, @Param("sku") String sku, @Param("packages") long packages);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -6,4 +6,6 @@ import java.util.List;
|
|||||||
public interface DropshipOrderProfileMapper extends BaseMapper<DropshipOrderProfile> {
|
public interface DropshipOrderProfileMapper extends BaseMapper<DropshipOrderProfile> {
|
||||||
@Select("SELECT * FROM ll_dropship_order_profile WHERE customer_id=#{customerId} AND order_id=#{orderId} ORDER BY source_pallet_no")
|
@Select("SELECT * FROM ll_dropship_order_profile WHERE customer_id=#{customerId} AND order_id=#{orderId} ORDER BY source_pallet_no")
|
||||||
List<DropshipOrderProfile> listOrder(@Param("customerId") String customerId, @Param("orderId") Long orderId);
|
List<DropshipOrderProfile> listOrder(@Param("customerId") String customerId, @Param("orderId") Long orderId);
|
||||||
|
@Select("SELECT * FROM ll_dropship_order_profile WHERE customer_id=#{customerId} AND inventory_position_id=#{positionId} LIMIT 1")
|
||||||
|
DropshipOrderProfile findPosition(@Param("customerId") String customerId, @Param("positionId") Long positionId);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -4,10 +4,13 @@ import com.baiyue.lastleg.dropship.entity.DropshipSkuInventory;
|
|||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import org.apache.ibatis.annotations.Select;
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
import org.apache.ibatis.annotations.Update;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface DropshipSkuInventoryMapper extends BaseMapper<DropshipSkuInventory> {
|
public interface DropshipSkuInventoryMapper extends BaseMapper<DropshipSkuInventory> {
|
||||||
@Select("SELECT * FROM ll_dropship_sku_inventory WHERE customer_id=#{customerId} AND order_id=#{orderId} ORDER BY profile_id,sku_code")
|
@Select("SELECT * FROM ll_dropship_sku_inventory WHERE customer_id=#{customerId} AND order_id=#{orderId} ORDER BY profile_id,sku_code")
|
||||||
List<DropshipSkuInventory> listOrder(@Param("customerId") String customerId, @Param("orderId") Long orderId);
|
List<DropshipSkuInventory> listOrder(@Param("customerId") String customerId, @Param("orderId") Long orderId);
|
||||||
|
@Update("UPDATE ll_dropship_sku_inventory SET package_count=package_count-#{packages},updated_at=NOW(3) WHERE customer_id=#{customerId} AND profile_id=#{profileId} AND sku_code=#{sku} AND package_count>=#{packages}")
|
||||||
|
int deduct(@Param("customerId") String customerId, @Param("profileId") Long profileId, @Param("sku") String sku, @Param("packages") long packages);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ lastleg:
|
|||||||
enabled: ${LASTLEG_DISPATCH_QUERY_API_ENABLED:true}
|
enabled: ${LASTLEG_DISPATCH_QUERY_API_ENABLED:true}
|
||||||
smart-dispatch-api:
|
smart-dispatch-api:
|
||||||
enabled: ${LASTLEG_SMART_DISPATCH_API_ENABLED:true}
|
enabled: ${LASTLEG_SMART_DISPATCH_API_ENABLED:true}
|
||||||
|
future-outbound-api:
|
||||||
|
enabled: ${LASTLEG_FUTURE_OUTBOUND_API_ENABLED:true}
|
||||||
|
|
||||||
baiyue:
|
baiyue:
|
||||||
http:
|
http:
|
||||||
|
|||||||
@@ -1103,11 +1103,13 @@ CREATE TABLE IF NOT EXISTS ll_dispatch_pda_pick_order (
|
|||||||
-- Transfer a dispatch to delivery: one outbound header, many pallet rows, one delivery header.
|
-- Transfer a dispatch to delivery: one outbound header, many pallet rows, one delivery header.
|
||||||
CREATE TABLE IF NOT EXISTS ll_outbound_order (
|
CREATE TABLE IF NOT EXISTS ll_outbound_order (
|
||||||
id BIGINT NOT NULL COMMENT '主键ID', customer_id VARCHAR(128) NOT NULL COMMENT '客户租户ID',
|
id BIGINT NOT NULL COMMENT '主键ID', customer_id VARCHAR(128) NOT NULL COMMENT '客户租户ID',
|
||||||
outbound_no VARCHAR(64) NOT NULL COMMENT '出库单号', dispatch_order_id BIGINT NOT NULL COMMENT '派车单ID', dispatch_no VARCHAR(64) NOT NULL COMMENT '派车单号',
|
outbound_no VARCHAR(64) NOT NULL COMMENT '出库单号', dispatch_order_id BIGINT NULL COMMENT '派车单ID,一件代发为空', dispatch_no VARCHAR(64) NULL COMMENT '派车单号,一件代发为空',
|
||||||
overseas_warehouse_id VARCHAR(128) NULL COMMENT '海外仓ID', status VARCHAR(32) NOT NULL DEFAULT 'WAIT_OUTBOUND' COMMENT '业务状态',
|
overseas_warehouse_id VARCHAR(128) NULL COMMENT '海外仓ID', status VARCHAR(32) NOT NULL DEFAULT 'WAIT_OUTBOUND' COMMENT '业务状态',
|
||||||
package_count INT NOT NULL DEFAULT 0 COMMENT '箱数', pallet_count INT NOT NULL DEFAULT 0 COMMENT '托盘数',
|
package_count INT NOT NULL DEFAULT 0 COMMENT '箱数', pallet_count INT NOT NULL DEFAULT 0 COMMENT '托盘数',
|
||||||
idempotency_key VARCHAR(255) NOT NULL COMMENT '业务幂等键', created_by VARCHAR(128) NULL COMMENT '创建人ID',
|
idempotency_key VARCHAR(255) NOT NULL COMMENT '业务幂等键', created_by VARCHAR(128) NULL COMMENT '创建人ID',
|
||||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
||||||
|
outbound_type VARCHAR(32) NOT NULL DEFAULT 'DISPATCH_DELIVERY' COMMENT '出库类型:派送转出库、一件代发',
|
||||||
|
recipient_info VARCHAR(1000) NULL COMMENT '一件代发收件信息',
|
||||||
PRIMARY KEY (id), UNIQUE KEY uk_ll_outbound_no (customer_id,outbound_no),
|
PRIMARY KEY (id), UNIQUE KEY uk_ll_outbound_no (customer_id,outbound_no),
|
||||||
UNIQUE KEY uk_ll_outbound_idempotency (customer_id,idempotency_key), UNIQUE KEY uk_ll_outbound_dispatch (customer_id,dispatch_order_id),
|
UNIQUE KEY uk_ll_outbound_idempotency (customer_id,idempotency_key), UNIQUE KEY uk_ll_outbound_dispatch (customer_id,dispatch_order_id),
|
||||||
KEY idx_ll_outbound_list (customer_id,status,created_at)
|
KEY idx_ll_outbound_list (customer_id,status,created_at)
|
||||||
@@ -1117,12 +1119,39 @@ CREATE TABLE IF NOT EXISTS ll_outbound_pallet_item (
|
|||||||
id BIGINT NOT NULL COMMENT '主键ID', customer_id VARCHAR(128) NOT NULL COMMENT '客户租户ID', outbound_order_id BIGINT NOT NULL COMMENT '出库单ID',
|
id BIGINT NOT NULL COMMENT '主键ID', customer_id VARCHAR(128) NOT NULL COMMENT '客户租户ID', outbound_order_id BIGINT NOT NULL COMMENT '出库单ID',
|
||||||
warehouse_pallet_id BIGINT NULL COMMENT '仓库实物托盘ID', pallet_no VARCHAR(128) NULL COMMENT '托盘号',
|
warehouse_pallet_id BIGINT NULL COMMENT '仓库实物托盘ID', pallet_no VARCHAR(128) NULL COMMENT '托盘号',
|
||||||
destination_warehouse_id VARCHAR(128) NULL COMMENT '目的仓ID', destination_warehouse_code VARCHAR(128) NULL COMMENT '目的仓编码快照', destination_warehouse_name VARCHAR(255) NULL COMMENT '目的仓名称快照',
|
destination_warehouse_id VARCHAR(128) NULL COMMENT '目的仓ID', destination_warehouse_code VARCHAR(128) NULL COMMENT '目的仓编码快照', destination_warehouse_name VARCHAR(255) NULL COMMENT '目的仓名称快照',
|
||||||
package_count INT NOT NULL DEFAULT 0 COMMENT '箱数', order_refs VARCHAR(2000) NULL COMMENT '关联订单信息', inbound_code VARCHAR(128) NULL COMMENT '入仓单号快照',
|
package_count INT NOT NULL DEFAULT 0 COMMENT '箱数', picked_package_count INT NOT NULL DEFAULT 0 COMMENT '已拣箱数', status VARCHAR(32) NOT NULL DEFAULT 'WAIT_PICK' COMMENT '拣货状态', sku_code VARCHAR(128) NULL COMMENT '一件代发SKU', order_refs VARCHAR(2000) NULL COMMENT '关联订单信息', inbound_code VARCHAR(128) NULL COMMENT '入仓单号快照',
|
||||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', PRIMARY KEY (id),
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', PRIMARY KEY (id),
|
||||||
UNIQUE KEY uk_ll_outbound_pallet (customer_id,outbound_order_id,warehouse_pallet_id),
|
UNIQUE KEY uk_ll_outbound_pallet (customer_id,outbound_order_id,warehouse_pallet_id),
|
||||||
KEY idx_ll_outbound_pallet_list (customer_id,outbound_order_id), KEY idx_ll_outbound_pallet_destination (customer_id,destination_warehouse_code)
|
KEY idx_ll_outbound_pallet_list (customer_id,outbound_order_id), KEY idx_ll_outbound_pallet_destination (customer_id,destination_warehouse_code)
|
||||||
) ENGINE=InnoDB COMMENT='出库托盘明细';
|
) ENGINE=InnoDB COMMENT='出库托盘明细';
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS ll_outbound_pda_task (
|
||||||
|
id BIGINT NOT NULL COMMENT '主键ID', customer_id VARCHAR(128) NOT NULL COMMENT '客户租户ID', outbound_order_id BIGINT NOT NULL COMMENT '出库单ID',
|
||||||
|
task_no VARCHAR(64) NOT NULL COMMENT 'PDA任务号', status VARCHAR(32) NOT NULL DEFAULT 'PENDING' COMMENT '任务状态:待拣货、拣货中、已完成',
|
||||||
|
pushed_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '推送时间', completed_at DATETIME(3) NULL COMMENT '完成时间',
|
||||||
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||||
|
PRIMARY KEY(id), UNIQUE KEY uk_ll_outbound_pda_task_order(customer_id,outbound_order_id), UNIQUE KEY uk_ll_outbound_pda_task_no(customer_id,task_no)
|
||||||
|
) ENGINE=InnoDB COMMENT='一件代发出库PDA拣货任务';
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS ll_outbound_pda_pick (
|
||||||
|
id BIGINT NOT NULL COMMENT '主键ID', customer_id VARCHAR(128) NOT NULL, task_id BIGINT NOT NULL COMMENT 'PDA任务ID', outbound_pallet_item_id BIGINT NOT NULL COMMENT '出库托盘明细ID',
|
||||||
|
inventory_position_id BIGINT NOT NULL COMMENT '库存仓位ID', packages BIGINT NOT NULL COMMENT '拣货箱数', idempotency_key VARCHAR(255) NOT NULL,
|
||||||
|
picked_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), PRIMARY KEY(id), UNIQUE KEY uk_ll_outbound_pda_pick_key(customer_id,idempotency_key)
|
||||||
|
) ENGINE=InnoDB COMMENT='一件代发出库PDA托盘拣货记录';
|
||||||
|
|
||||||
|
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_outbound_order' AND column_name='outbound_type'), 'SELECT 1', 'ALTER TABLE ll_outbound_order ADD COLUMN outbound_type VARCHAR(32) NOT NULL DEFAULT ''DISPATCH_DELIVERY'' COMMENT ''出库类型'' AFTER status'));
|
||||||
|
PREPARE outbound_upgrade_stmt FROM @ddl; EXECUTE outbound_upgrade_stmt; DEALLOCATE PREPARE outbound_upgrade_stmt;
|
||||||
|
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_outbound_pallet_item' AND column_name='sku_code'), 'SELECT 1', 'ALTER TABLE ll_outbound_pallet_item ADD COLUMN sku_code VARCHAR(128) NULL COMMENT ''一件代发SKU'' AFTER status'));
|
||||||
|
PREPARE outbound_upgrade_stmt FROM @ddl; EXECUTE outbound_upgrade_stmt; DEALLOCATE PREPARE outbound_upgrade_stmt;
|
||||||
|
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_outbound_order' AND column_name='recipient_info'), 'SELECT 1', 'ALTER TABLE ll_outbound_order ADD COLUMN recipient_info VARCHAR(1000) NULL COMMENT ''一件代发收件信息'' AFTER outbound_type'));
|
||||||
|
PREPARE outbound_upgrade_stmt FROM @ddl; EXECUTE outbound_upgrade_stmt; DEALLOCATE PREPARE outbound_upgrade_stmt;
|
||||||
|
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_outbound_pallet_item' AND column_name='picked_package_count'), 'SELECT 1', 'ALTER TABLE ll_outbound_pallet_item ADD COLUMN picked_package_count INT NOT NULL DEFAULT 0 COMMENT ''已拣箱数'' AFTER package_count'));
|
||||||
|
PREPARE outbound_upgrade_stmt FROM @ddl; EXECUTE outbound_upgrade_stmt; DEALLOCATE PREPARE outbound_upgrade_stmt;
|
||||||
|
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_outbound_pallet_item' AND column_name='status'), 'SELECT 1', 'ALTER TABLE ll_outbound_pallet_item ADD COLUMN status VARCHAR(32) NOT NULL DEFAULT ''WAIT_PICK'' COMMENT ''拣货状态'' AFTER picked_package_count'));
|
||||||
|
PREPARE outbound_upgrade_stmt FROM @ddl; EXECUTE outbound_upgrade_stmt; DEALLOCATE PREPARE outbound_upgrade_stmt;
|
||||||
|
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_outbound_order' AND column_name='dispatch_order_id' AND is_nullable='YES'), 'SELECT 1', 'ALTER TABLE ll_outbound_order MODIFY COLUMN dispatch_order_id BIGINT NULL COMMENT ''派车单ID,一件代发为空'', MODIFY COLUMN dispatch_no VARCHAR(64) NULL COMMENT ''派车单号,一件代发为空'''));
|
||||||
|
PREPARE outbound_upgrade_stmt FROM @ddl; EXECUTE outbound_upgrade_stmt; DEALLOCATE PREPARE outbound_upgrade_stmt;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS ll_delivery_order (
|
CREATE TABLE IF NOT EXISTS ll_delivery_order (
|
||||||
id BIGINT NOT NULL COMMENT '主键ID', customer_id VARCHAR(128) NOT NULL COMMENT '客户租户ID',
|
id BIGINT NOT NULL COMMENT '主键ID', customer_id VARCHAR(128) NOT NULL COMMENT '客户租户ID',
|
||||||
delivery_no VARCHAR(64) NOT NULL COMMENT '派送单号', outbound_order_id BIGINT NOT NULL COMMENT '出库单ID', outbound_no VARCHAR(64) NOT NULL COMMENT '出库单号',
|
delivery_no VARCHAR(64) NOT NULL COMMENT '派送单号', outbound_order_id BIGINT NOT NULL COMMENT '出库单ID', outbound_no VARCHAR(64) NOT NULL COMMENT '出库单号',
|
||||||
|
|||||||
@@ -3805,6 +3805,21 @@ SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE tab
|
|||||||
AND table_name='ll_cargo_discard_application' AND column_name='review_idempotency_key'),
|
AND table_name='ll_cargo_discard_application' AND column_name='review_idempotency_key'),
|
||||||
'SELECT 1', 'ALTER TABLE ll_cargo_discard_application ADD COLUMN review_idempotency_key VARCHAR(255) NULL COMMENT ''审核幂等键'' AFTER request_hash'));
|
'SELECT 1', 'ALTER TABLE ll_cargo_discard_application ADD COLUMN review_idempotency_key VARCHAR(255) NULL COMMENT ''审核幂等键'' AFTER request_hash'));
|
||||||
PREPARE phase4_discard_review_stmt FROM @ddl; EXECUTE phase4_discard_review_stmt; DEALLOCATE PREPARE phase4_discard_review_stmt;
|
PREPARE phase4_discard_review_stmt FROM @ddl; EXECUTE phase4_discard_review_stmt; DEALLOCATE PREPARE phase4_discard_review_stmt;
|
||||||
|
|
||||||
|
-- 一件代发出库与 PDA 按托盘拣货出库。
|
||||||
|
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_outbound_order' AND column_name='outbound_type'), 'SELECT 1', 'ALTER TABLE ll_outbound_order ADD COLUMN outbound_type VARCHAR(32) NOT NULL DEFAULT ''DISPATCH_DELIVERY'' COMMENT ''出库类型'' AFTER status'));
|
||||||
|
PREPARE dropship_outbound_stmt FROM @ddl; EXECUTE dropship_outbound_stmt; DEALLOCATE PREPARE dropship_outbound_stmt;
|
||||||
|
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_outbound_order' AND column_name='recipient_info'), 'SELECT 1', 'ALTER TABLE ll_outbound_order ADD COLUMN recipient_info VARCHAR(1000) NULL COMMENT ''一件代发收件信息'' AFTER outbound_type'));
|
||||||
|
PREPARE dropship_outbound_stmt FROM @ddl; EXECUTE dropship_outbound_stmt; DEALLOCATE PREPARE dropship_outbound_stmt;
|
||||||
|
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_outbound_pallet_item' AND column_name='picked_package_count'), 'SELECT 1', 'ALTER TABLE ll_outbound_pallet_item ADD COLUMN picked_package_count INT NOT NULL DEFAULT 0 COMMENT ''已拣箱数'' AFTER package_count'));
|
||||||
|
PREPARE dropship_outbound_stmt FROM @ddl; EXECUTE dropship_outbound_stmt; DEALLOCATE PREPARE dropship_outbound_stmt;
|
||||||
|
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_outbound_pallet_item' AND column_name='status'), 'SELECT 1', 'ALTER TABLE ll_outbound_pallet_item ADD COLUMN status VARCHAR(32) NOT NULL DEFAULT ''WAIT_PICK'' COMMENT ''拣货状态'' AFTER picked_package_count'));
|
||||||
|
PREPARE dropship_outbound_stmt FROM @ddl; EXECUTE dropship_outbound_stmt; DEALLOCATE PREPARE dropship_outbound_stmt;
|
||||||
|
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_outbound_pallet_item' AND column_name='sku_code'), 'SELECT 1', 'ALTER TABLE ll_outbound_pallet_item ADD COLUMN sku_code VARCHAR(128) NULL COMMENT ''一件代发SKU'' AFTER status'));
|
||||||
|
PREPARE dropship_outbound_stmt FROM @ddl; EXECUTE dropship_outbound_stmt; DEALLOCATE PREPARE dropship_outbound_stmt;
|
||||||
|
ALTER TABLE ll_outbound_order MODIFY COLUMN dispatch_order_id BIGINT NULL COMMENT '派车单ID,一件代发为空', MODIFY COLUMN dispatch_no VARCHAR(64) NULL COMMENT '派车单号,一件代发为空';
|
||||||
|
CREATE TABLE IF NOT EXISTS ll_outbound_pda_task (id BIGINT NOT NULL,customer_id VARCHAR(128) NOT NULL,outbound_order_id BIGINT NOT NULL,task_no VARCHAR(64) NOT NULL,status VARCHAR(32) NOT NULL DEFAULT 'PENDING',pushed_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),completed_at DATETIME(3) NULL,created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),PRIMARY KEY(id),UNIQUE KEY uk_ll_outbound_pda_task_order(customer_id,outbound_order_id),UNIQUE KEY uk_ll_outbound_pda_task_no(customer_id,task_no)) ENGINE=InnoDB COMMENT='一件代发出库PDA拣货任务';
|
||||||
|
CREATE TABLE IF NOT EXISTS ll_outbound_pda_pick (id BIGINT NOT NULL,customer_id VARCHAR(128) NOT NULL,task_id BIGINT NOT NULL,outbound_pallet_item_id BIGINT NOT NULL,inventory_position_id BIGINT NOT NULL,packages BIGINT NOT NULL,idempotency_key VARCHAR(255) NOT NULL,picked_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),PRIMARY KEY(id),UNIQUE KEY uk_ll_outbound_pda_pick_key(customer_id,idempotency_key)) ENGINE=InnoDB COMMENT='一件代发出库PDA托盘拣货记录';
|
||||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE()
|
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE()
|
||||||
AND table_name='ll_cargo_discard_application' AND column_name='review_request_hash'),
|
AND table_name='ll_cargo_discard_application' AND column_name='review_request_hash'),
|
||||||
'SELECT 1', 'ALTER TABLE ll_cargo_discard_application ADD COLUMN review_request_hash CHAR(64) NULL COMMENT ''审核请求内容哈希'' AFTER review_idempotency_key'));
|
'SELECT 1', 'ALTER TABLE ll_cargo_discard_application ADD COLUMN review_request_hash CHAR(64) NULL COMMENT ''审核请求内容哈希'' AFTER review_idempotency_key'));
|
||||||
|
|||||||
Reference in New Issue
Block a user