贴标申请,仓储转运
This commit is contained in:
+18
-6
@@ -1,24 +1,36 @@
|
||||
package com.baiyue.lastleg.palletops.dto;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
public final class PalletOperationResponses {
|
||||
private PalletOperationResponses() { }
|
||||
public record RelabelSource(long positionId, long positionVersion, String palletCode,
|
||||
public record RelabelSource(
|
||||
@JsonSerialize(using = ToStringSerializer.class) long positionId,
|
||||
long positionVersion,
|
||||
@JsonSerialize(using = ToStringSerializer.class) long palletId, String palletCode,
|
||||
String locationCode, String inboundCode, long stockPackages,
|
||||
long movablePackages, List<String> cartonMarks) { }
|
||||
|
||||
public record InventoryLine(String customerId, String customerName, long balanceId, long positionId,
|
||||
public record InventoryLine(String customerId, String customerName,
|
||||
@JsonSerialize(using = ToStringSerializer.class) long balanceId,
|
||||
@JsonSerialize(using = ToStringSerializer.class) long positionId,
|
||||
String inboundCode, String skuCode, String productName,
|
||||
long availablePackages, long holdPackages, long allocatedPackages,
|
||||
long pickedPackages, long receivingPackages, long positionVersion) { }
|
||||
public record PalletContent(long palletId, String palletCode, String status, int palletVersion,
|
||||
Long locationId, String locationCode, String destinationWarehouseCode,
|
||||
public record PalletContent(@JsonSerialize(using = ToStringSerializer.class) long palletId,
|
||||
String palletCode, String status, int palletVersion,
|
||||
@JsonSerialize(using = ToStringSerializer.class) Long locationId,
|
||||
String locationCode, String destinationWarehouseCode,
|
||||
long totalPackages, List<InventoryLine> inventory) { }
|
||||
public record PrintablePallet(long palletId, String palletCode, int palletVersion,
|
||||
public record PrintablePallet(@JsonSerialize(using = ToStringSerializer.class) long palletId,
|
||||
String palletCode, int palletVersion,
|
||||
String relabelNo, String printableHtml) { }
|
||||
public record Operation(long operationId, String operationType, String idempotencyKey,
|
||||
public record Operation(@JsonSerialize(using = ToStringSerializer.class) long operationId,
|
||||
String operationType, String idempotencyKey,
|
||||
String status, boolean replayed, LocalDateTime completedAt,
|
||||
List<PalletContent> pallets) {
|
||||
public Operation asReplay() {
|
||||
|
||||
+12
-1
@@ -2,6 +2,7 @@ package com.baiyue.lastleg.palletops.gateway;
|
||||
|
||||
import com.baiyue.lastleg.config.LastlegRestClientFactory;
|
||||
import com.baiyue.lastleg.config.LastlegRestClientProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -30,7 +31,14 @@ public class HttpPalletPhysicalGateway implements PalletPhysicalGateway {
|
||||
|
||||
@Override
|
||||
public PalletReference ensureRelabelPallet(long warehouseId, String businessId) {
|
||||
Map<String, Object> body = Map.of("warehouseId", warehouseId, "businessId", businessId);
|
||||
return ensureRelabelPallet(warehouseId, businessId, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PalletReference ensureRelabelPallet(long warehouseId, String businessId, String fbaWarehouseCode) {
|
||||
Map<String, Object> body = new LinkedHashMap<>();
|
||||
body.put("warehouseId", warehouseId); body.put("businessId", businessId);
|
||||
if (fbaWarehouseCode != null && !fbaWarehouseCode.isBlank()) body.put("fbaWarehouseCode", fbaWarehouseCode.trim());
|
||||
ResolveEnvelope response = client.post().uri("/internal/v1/warehouse-pallets/ensure-relabel")
|
||||
.header("X-Internal-Service-Token", internalToken).body(body).retrieve()
|
||||
.onStatus(HttpStatusCode::isError, (request, result) -> {
|
||||
@@ -117,7 +125,10 @@ public class HttpPalletPhysicalGateway implements PalletPhysicalGateway {
|
||||
}).toBodilessEntity();
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
private record ResolveEnvelope(String code, String message, PalletReference data) { }
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
private record LocationEnvelope(LocationReference data) { }
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
private record TransitionEnvelope(Transition data) { }
|
||||
}
|
||||
|
||||
+6
@@ -1,7 +1,12 @@
|
||||
package com.baiyue.lastleg.palletops.gateway;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
public interface PalletPhysicalGateway {
|
||||
PalletReference ensureRelabelPallet(long warehouseId, String businessId);
|
||||
default PalletReference ensureRelabelPallet(long warehouseId, String businessId, String fbaWarehouseCode) {
|
||||
return ensureRelabelPallet(warehouseId, businessId);
|
||||
}
|
||||
PalletReference resolve(String palletCode);
|
||||
PalletReference resolve(long palletId);
|
||||
LocationReference resolveLocation(long warehouseId, long locationId);
|
||||
@@ -9,6 +14,7 @@ public interface PalletPhysicalGateway {
|
||||
String operationKey, String reason);
|
||||
void compensate(long warehouseId, Transition transition);
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
record PalletReference(long palletId, String palletCode, long warehouseId, Long locationId,
|
||||
String status, String fbaWarehouseCode, java.math.BigDecimal unitPrice, int version) {
|
||||
public PalletReference(long palletId, String palletCode, long warehouseId, Long locationId,
|
||||
|
||||
+168
-9
@@ -18,6 +18,11 @@ import com.baiyue.lastleg.relabel.entity.RelabelItem;
|
||||
import com.baiyue.lastleg.relabel.mapper.RelabelApplicationMapper;
|
||||
import com.baiyue.lastleg.relabel.mapper.RelabelItemMapper;
|
||||
import com.baiyue.lastleg.relabel.service.RelabelPalletMutationService;
|
||||
import com.baiyue.lastleg.returnreceipt.entity.ReturnInventoryCarton;
|
||||
import com.baiyue.lastleg.returnreceipt.entity.ReturnInventoryCartonItem;
|
||||
import com.baiyue.lastleg.returnreceipt.mapper.ReturnInventoryBalanceMapper;
|
||||
import com.baiyue.lastleg.returnreceipt.mapper.ReturnInventoryCartonMapper;
|
||||
import com.baiyue.lastleg.returnreceipt.mapper.ReturnInventoryCartonItemMapper;
|
||||
import com.baiyue.lastleg.pda.security.PdaWarehouseIdentity;
|
||||
import com.baiyue.lastleg.pda.warehouse.service.PdaWarehouseService;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
@@ -48,6 +53,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class PdaPalletOperationService {
|
||||
@@ -61,6 +67,9 @@ public class PdaPalletOperationService {
|
||||
@Resource private RelabelApplicationMapper relabelApplications;
|
||||
@Resource private RelabelItemMapper relabelItems;
|
||||
@Resource private RelabelPalletMutationService relabelPalletMutations;
|
||||
@Resource private ReturnInventoryCartonMapper returnCartons;
|
||||
@Resource private ReturnInventoryCartonItemMapper returnCartonItems;
|
||||
@Resource private ReturnInventoryBalanceMapper returnBalances;
|
||||
private TransactionTemplate transaction;
|
||||
private TransactionTemplate newTransaction;
|
||||
|
||||
@@ -85,6 +94,26 @@ public class PdaPalletOperationService {
|
||||
Set<String> boundMarks = boundRelabelMarks(app);
|
||||
List<RelabelItem> items = relabelItems.selectList(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<RelabelItem>()
|
||||
.eq("application_id", app.getId()).eq("customer_id", app.getCustomerId()));
|
||||
if (!items.isEmpty() && items.stream().allMatch(item -> item.getReturnCartonId() != null)) {
|
||||
List<PalletOperationResponses.RelabelSource> result = new ArrayList<>();
|
||||
Map<Long, List<RelabelItem>> byCarton = items.stream().filter(item -> !boundMarks.contains(item.getCartonMark())).collect(Collectors.groupingBy(
|
||||
RelabelItem::getReturnCartonId, LinkedHashMap::new, Collectors.toList()));
|
||||
for (var entry : byCarton.entrySet()) {
|
||||
ReturnInventoryCarton carton = returnCartons.selectById(entry.getKey());
|
||||
if (carton == null || !Objects.equals(carton.getCustomerId(), app.getCustomerId())
|
||||
|| !Objects.equals(carton.getOverseasWarehouseId(), app.getOverseasWarehouseId())
|
||||
|| !Objects.equals(carton.getStatus(), "RELABEL_PENDING"))
|
||||
throw conflict("退货换标来源托盘不存在或已被占用");
|
||||
PalletPhysicalGateway.PalletReference pallet = physical.resolve(carton.getPalletCode());
|
||||
if (pallet == null || pallet.warehouseId() != identity.overseasWarehouseId())
|
||||
throw conflict("退货换标来源托盘不属于当前仓库");
|
||||
long quantity = value(carton.getTotalQuantity());
|
||||
result.add(new PalletOperationResponses.RelabelSource(carton.getId(), 0L,
|
||||
pallet.palletId(), pallet.palletCode(), null, carton.getSourceBatchNo(), quantity, quantity,
|
||||
entry.getValue().stream().map(RelabelItem::getCartonMark).filter(Objects::nonNull).toList()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
Map<Long, List<RelabelItem>> byBalance = new LinkedHashMap<>();
|
||||
for (RelabelItem item : items) {
|
||||
InventoryPosition anchor = positions.selectById(item.getSourceInventoryPositionId());
|
||||
@@ -99,7 +128,7 @@ public class PdaPalletOperationService {
|
||||
long ownHold = group.stream().filter(item -> Objects.equals(item.getSourceInventoryPositionId(), row.getPositionId()))
|
||||
.mapToLong(item -> value(item.getNotifiedPackageCount())).sum();
|
||||
result.add(new PalletOperationResponses.RelabelSource(row.getPositionId(), value(row.getVersion()),
|
||||
row.getPalletNo(), row.getWarehouseLocationCode(), row.getInboundCode(),
|
||||
row.getPalletId(), row.getPalletNo(), row.getWarehouseLocationCode(), row.getInboundCode(),
|
||||
value(row.getAvailablePackages()) + value(row.getHoldPackages()) + value(row.getAllocatedPackages())
|
||||
+ value(row.getPickedPackages()),
|
||||
value(row.getAvailablePackages()) + Math.min(ownHold, value(row.getHoldPackages())),
|
||||
@@ -118,15 +147,22 @@ public class PdaPalletOperationService {
|
||||
throw conflict("换标单不属于 Token 冻结的海外仓");
|
||||
}
|
||||
String key = required(request.idempotencyKey(), "幂等键不能为空");
|
||||
String destination = relabelItems.selectList(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<RelabelItem>()
|
||||
.eq("application_id", application.getId()).eq("customer_id", application.getCustomerId()))
|
||||
.stream().map(RelabelItem::getDestinationFbaWarehouseCode).filter(value -> value != null && !value.isBlank())
|
||||
.distinct().reduce((left, right) -> { throw conflict("同一换标单只能绑定一个 FBA 目的仓"); }).orElse(null);
|
||||
PalletPhysicalGateway.PalletReference pallet = physical.ensureRelabelPallet(identity.overseasWarehouseId(),
|
||||
relabelNo + ":" + key);
|
||||
relabelNo + ":" + key, destination);
|
||||
String code = HtmlUtils.htmlEscape(pallet.palletCode());
|
||||
String order = HtmlUtils.htmlEscape(relabelNo);
|
||||
String fbaValue = destination == null ? pallet.fbaWarehouseCode() : destination;
|
||||
String fba = HtmlUtils.htmlEscape(fbaValue == null ? "" : fbaValue);
|
||||
if (fba == null || fba.isBlank()) fba = "待绑定";
|
||||
String html = "<!doctype html><html><head><meta charset=\"UTF-8\"><title>" + code
|
||||
+ "</title><style>@page{size:100mm 70mm;margin:4mm}body{font-family:Arial,sans-serif;text-align:center;margin:0}"
|
||||
+ "h1{font-size:24px;margin:8mm 0 4mm;letter-spacing:0}.code{font-size:18px;font-weight:700;word-break:break-all}"
|
||||
+ ".ref{font-size:12px;margin-top:6mm}</style></head><body><h1>托盘标签</h1><div class=\"code\">"
|
||||
+ code + "</div><div class=\"ref\">换标单:" + order + "</div></body></html>";
|
||||
+ code + "</div><div class=\"ref\">换标单:" + order + "<br>FBA目的仓:" + fba + "</div></body></html>";
|
||||
return new PalletOperationResponses.PrintablePallet(pallet.palletId(), pallet.palletCode(), pallet.version(),
|
||||
relabelNo, html);
|
||||
}
|
||||
@@ -205,8 +241,10 @@ public class PdaPalletOperationService {
|
||||
Map<Long, Long> packagesByPosition = new LinkedHashMap<>();
|
||||
Map<Long, List<RelabelItem>> itemsByPosition = new LinkedHashMap<>();
|
||||
Map<Long, InventoryPosition> anchors = new LinkedHashMap<>();
|
||||
InventoryPosition actual = request.actualSource() == null ? null : positions.selectById(request.actualSource().positionId());
|
||||
if (request.actualSource() != null && (actual == null
|
||||
boolean returnRelabel = selected.stream().allMatch(item -> item.getReturnCartonId() != null);
|
||||
InventoryPosition actual = returnRelabel || request.actualSource() == null
|
||||
? null : positions.selectById(request.actualSource().positionId());
|
||||
if (!returnRelabel && request.actualSource() != null && (actual == null
|
||||
|| !Objects.equals(actual.getCustomerId(), application.getCustomerId())
|
||||
|| !Objects.equals(actual.getPalletId(), source.palletId())
|
||||
|| !Objects.equals(actual.getOverseasWarehouseId(), application.getOverseasWarehouseId())
|
||||
@@ -219,13 +257,17 @@ public class PdaPalletOperationService {
|
||||
if ("PROCESSING".equals(application.getStatus())) {
|
||||
var workTask = relabelWorkTasks.find(application.getCustomerId(), application.getId());
|
||||
for (RelabelItem item : selected) {
|
||||
Long completed = relabelWorkFacts.selectCount(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<com.baiyue.lastleg.relabel.pda.entity.PdaRelabelUnitFact>()
|
||||
.eq("task_id", workTask.getId()).eq("customer_id", application.getCustomerId())
|
||||
.eq("item_id", item.getId()).eq("result", "RELABELLED"));
|
||||
if (completed == null || completed < value(item.getNotifiedPackageCount()))
|
||||
long completed = relabelWorkFacts.selectList(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<com.baiyue.lastleg.relabel.pda.entity.PdaRelabelUnitFact>()
|
||||
.eq("task_id", workTask.getId()).eq("customer_id", application.getCustomerId())
|
||||
.eq("item_id", item.getId()).eq("result", "RELABELLED"))
|
||||
.stream().mapToLong(fact -> fact.getQuantity() == null ? 1L : fact.getQuantity()).sum();
|
||||
if (completed < value(item.getNotifiedPackageCount()))
|
||||
throw conflict("请先完成本箱全部换标作业,再进行组托");
|
||||
}
|
||||
}
|
||||
if (returnRelabel) {
|
||||
return bindReturnRelabelPallet(identity, application, selected, source, target, request);
|
||||
}
|
||||
for (RelabelItem item : selected) {
|
||||
if (item.getSourceInventoryPositionId() == null || item.getNotifiedPackageCount() == null
|
||||
|| item.getNotifiedPackageCount() <= 0) throw conflict("换标箱唛缺少库存位置或箱数快照");
|
||||
@@ -265,6 +307,107 @@ public class PdaPalletOperationService {
|
||||
reason, relabelPlan);
|
||||
}
|
||||
|
||||
private PalletOperationResponses.Operation bindReturnRelabelPallet(PdaWarehouseIdentity identity,
|
||||
RelabelApplication application, List<RelabelItem> selected,
|
||||
PalletPhysicalGateway.PalletReference source, PalletPhysicalGateway.PalletReference target,
|
||||
PalletOperationRequests.RelabelDisassemble request) {
|
||||
requireRelabelDestination(identity.overseasWarehouseId(), selected, target);
|
||||
Set<String> alreadyBound = boundRelabelMarks(application);
|
||||
if (selected.stream().map(RelabelItem::getCartonMark).anyMatch(alreadyBound::contains))
|
||||
throw conflict("退货换标箱已在本轮完成组托,请刷新后重试");
|
||||
long quantity = 0;
|
||||
List<ReturnInventoryCarton> cartons = new ArrayList<>();
|
||||
for (RelabelItem item : selected) {
|
||||
ReturnInventoryCarton carton = returnCartons.lockId(item.getReturnCartonId());
|
||||
if (carton == null || !Objects.equals(carton.getCustomerId(), application.getCustomerId())
|
||||
|| !Objects.equals(carton.getPalletCode(), source.palletCode())
|
||||
|| !Objects.equals(carton.getRelabelApplicationId(), application.getId())
|
||||
|| !Objects.equals(carton.getStatus(), "RELABEL_PENDING"))
|
||||
throw conflict("退货换标来源托盘或库存状态已变化,请刷新后重试");
|
||||
quantity += value(item.getNotifiedPackageCount());
|
||||
cartons.add(carton);
|
||||
}
|
||||
if (request.actualSource() == null || request.actualSource().positionId() != cartons.get(0).getId()
|
||||
|| request.actualSource().packages() != quantity)
|
||||
throw conflict("退货换标拆出数量必须等于本批已完成贴标数量");
|
||||
String key = required(request.idempotencyKey(), "幂等键不能为空");
|
||||
String requestHash = hash(request);
|
||||
PdaPalletOperation operation = begin(identity, "RELABEL_PALLET_DISASSEMBLE", key, requestHash);
|
||||
if ("COMPLETED".equals(operation.getStatus())) return read(operation).asReplay();
|
||||
physical.apply(identity.overseasWarehouseId(), target, "OCCUPIED", target.locationId(), key, "退货换标组托");
|
||||
return transaction.execute(status -> {
|
||||
for (int index = 0; index < cartons.size(); index++) {
|
||||
RelabelItem item = selected.get(index);
|
||||
ReturnInventoryCarton carton = returnCartons.lockId(item.getReturnCartonId());
|
||||
if (carton == null || !Objects.equals(carton.getCustomerId(), application.getCustomerId())
|
||||
|| !Objects.equals(carton.getPalletCode(), source.palletCode())
|
||||
|| !Objects.equals(carton.getRelabelApplicationId(), application.getId())
|
||||
|| !"RELABEL_PENDING".equals(carton.getStatus()))
|
||||
throw conflict("退货换标来源库存已变化,请刷新后重试");
|
||||
long move = value(item.getNotifiedPackageCount());
|
||||
if (move <= 0 || move > value(carton.getTotalQuantity())) throw conflict("来源托盘可拆数量不足");
|
||||
if (move < value(carton.getTotalQuantity())) {
|
||||
splitReturnRelabelCarton(application, item, carton, target, move);
|
||||
} else {
|
||||
carton.setPalletCode(target.palletCode());
|
||||
carton.setDestinationWarehouseCode(item.getDestinationFbaWarehouseCode());
|
||||
carton.setRelabelStatus("PROCESSING");
|
||||
carton.setUpdatedAt(LocalDateTime.now());
|
||||
returnCartons.updateById(carton);
|
||||
}
|
||||
}
|
||||
recordReturnRelabelBinding(identity, application, selected, target.palletCode());
|
||||
List<PalletOperationResponses.PalletContent> contents = List.of(
|
||||
content(identity.overseasWarehouseId(), physical.resolve(source.palletCode())),
|
||||
content(identity.overseasWarehouseId(), physical.resolve(target.palletCode())));
|
||||
PalletOperationResponses.Operation result = new PalletOperationResponses.Operation(operation.getId(),
|
||||
operation.getOperationType(), key, "COMPLETED", false, LocalDateTime.now(), contents);
|
||||
operation.setStatus("COMPLETED"); operation.setResultJson(write(result));
|
||||
operation.setUpdatedAt(result.completedAt()); mapper.updateById(operation);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
/** Keep the unlabelled remainder on its original pallet; move only the confirmed SKU pieces. */
|
||||
private void splitReturnRelabelCarton(RelabelApplication application, RelabelItem item,
|
||||
ReturnInventoryCarton source, PalletPhysicalGateway.PalletReference target, long quantity) {
|
||||
if (relabelItems.selectList(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<RelabelItem>()
|
||||
.eq("application_id", application.getId()).eq("return_carton_id", source.getId())).size() != 1)
|
||||
throw conflict("来源托盘包含多项换标任务,不能按单 SKU 拆分,请核对库存");
|
||||
List<ReturnInventoryCartonItem> lines = returnCartonItems.lockCarton(source.getId());
|
||||
if (lines.size() != 1 || !item.getSkuCode().equalsIgnoreCase(lines.get(0).getSkuCode())
|
||||
|| value(lines.get(0).getQuantity()) != value(source.getTotalQuantity()))
|
||||
throw conflict("来源托盘包含其他 SKU,不能按单 SKU 拆分,请核对库存");
|
||||
long remaining = value(source.getTotalQuantity()) - quantity;
|
||||
ReturnInventoryCartonItem sourceLine = lines.get(0);
|
||||
sourceLine.setQuantity(remaining);
|
||||
if (returnCartonItems.updateById(sourceLine) != 1
|
||||
|| returnCartons.releasePartial(source.getId(), application.getCustomerId(), application.getId(), remaining) != 1)
|
||||
throw conflict("来源托盘数量已变化,请刷新后重试");
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
long targetId = IdWorker.getId();
|
||||
ReturnInventoryCarton moved = new ReturnInventoryCarton();
|
||||
moved.setId(targetId); moved.setCustomerId(source.getCustomerId());
|
||||
moved.setOverseasWarehouseId(source.getOverseasWarehouseId());
|
||||
moved.setSourceBatchNo(source.getSourceBatchNo()); moved.setSourceReturnNo(source.getSourceReturnNo());
|
||||
moved.setPalletCode(target.palletCode()); moved.setCartonMark("RL-CARTON-" + targetId);
|
||||
moved.setDestinationWarehouseCode(item.getDestinationFbaWarehouseCode());
|
||||
moved.setRelabelApplicationId(application.getId()); moved.setRelabelNo(application.getRelabelNo());
|
||||
moved.setRelabelStatus("PROCESSING"); moved.setStatus("RELABEL_PENDING");
|
||||
moved.setSkuTypes(1); moved.setTotalQuantity(quantity);
|
||||
moved.setCreatedAt(now); moved.setUpdatedAt(now);
|
||||
if (returnCartons.insert(moved) != 1) throw conflict("新托盘库存创建失败");
|
||||
ReturnInventoryCartonItem targetLine = new ReturnInventoryCartonItem();
|
||||
targetLine.setId(IdWorker.getId()); targetLine.setCartonId(targetId);
|
||||
targetLine.setCustomerId(source.getCustomerId()); targetLine.setSkuCode(sourceLine.getSkuCode());
|
||||
targetLine.setProductNameZh(sourceLine.getProductNameZh()); targetLine.setQuantity(quantity);
|
||||
if (returnCartonItems.insert(targetLine) != 1
|
||||
|| returnBalances.adjustCartonQuantity(source.getCustomerId(), source.getOverseasWarehouseId(),
|
||||
sourceLine.getSkuCode(), 1) != 1) throw conflict("退货库存拆分记账失败");
|
||||
item.setReturnCartonId(targetId);
|
||||
if (relabelItems.updateById(item) != 1) throw conflict("换标单来源托盘更新失败");
|
||||
}
|
||||
|
||||
public PalletOperationResponses.Operation swap(PdaWarehouseIdentity identity,
|
||||
PalletOperationRequests.Swap request) {
|
||||
PalletOperationResponses.Operation replay = replayIfPresent(identity, "PALLET_SWAP",
|
||||
@@ -610,6 +753,22 @@ public class PdaPalletOperationService {
|
||||
relabelWorkHistory.insert(record);
|
||||
}
|
||||
|
||||
private void recordReturnRelabelBinding(PdaWarehouseIdentity identity, RelabelApplication app,
|
||||
List<RelabelItem> items, String targetPallet) {
|
||||
var task = relabelWorkTasks.find(app.getCustomerId(), app.getId());
|
||||
if (task == null) throw conflict("退货换标作业任务不存在,不能记录组托");
|
||||
var record = new com.baiyue.lastleg.relabel.pda.entity.PdaRelabelHistory();
|
||||
record.setId(IdWorker.getId()); record.setTaskId(task.getId()); record.setApplicationId(app.getId());
|
||||
record.setCustomerId(app.getCustomerId()); record.setAction("PALLET_BIND");
|
||||
record.setFromStatus(task.getStatus()); record.setToStatus(task.getStatus());
|
||||
record.setOperatorKey(identity.operatorKey()); record.setOperatorName(identity.operatorName());
|
||||
record.setCreatedAt(LocalDateTime.now());
|
||||
record.setDetailJson(write(Map.of("round", Objects.toString(task.getReviewedAt(), "INITIAL"),
|
||||
"cartonMarks", items.stream().map(RelabelItem::getCartonMark).toList(),
|
||||
"targetPallets", List.of(targetPallet))));
|
||||
relabelWorkHistory.insert(record);
|
||||
}
|
||||
|
||||
private void requireRelabelWork(PdaWarehouseIdentity identity, RelabelApplication application) {
|
||||
if (application == null || !Set.of("PROCESSING", "READY_FOR_OUTBOUND").contains(application.getStatus()))
|
||||
throw conflict("当前换标状态不能组托");
|
||||
|
||||
Reference in New Issue
Block a user