入库修改

This commit is contained in:
2026-08-20 13:34:34 +08:00
parent 3b19a1bc16
commit b139255d3b
24 changed files with 528 additions and 62 deletions
@@ -3,6 +3,7 @@ package com.baiyue.lastleg.inboundplan.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baiyue.lastleg.inboundplan.dto.InboundPlanResponse;
import com.baiyue.lastleg.inboundplan.dto.SupplementPalletRequest;
import com.baiyue.lastleg.inboundplan.entity.InboundPlan;
import com.baiyue.lastleg.inboundplan.entity.InboundPlanLine;
import com.baiyue.lastleg.inboundplan.entity.InboundPlanPallet;
@@ -37,17 +38,13 @@ public class InboundPlanService {
@Transactional
public InboundPlanResponse convert(String customerId, Long selectedOrderId) {
String containerNo = trimToNull(orderMapper.findContainerNo(customerId, selectedOrderId));
if (containerNo == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
"Order does not exist in this tenant or container number is empty");
List<SourceOrderSnapshot> orders = orderMapper.lockOrder(customerId, selectedOrderId);
if (orders == null || orders.isEmpty()) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Inbound order not found");
}
List<SourceOrderSnapshot> orders = orderMapper.lockContainerOrders(customerId, containerNo);
if (orders.isEmpty()) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Container orders not found");
}
InboundPlan existing = planMapper.findByContainer(customerId, containerNo);
String containerNo = trimToNull(orders.get(0).containerNo());
if (containerNo == null) throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Inbound order container number is empty");
InboundPlan existing = planMapper.findBySourceOrder(customerId, selectedOrderId);
if (existing != null) {
return detail(customerId, existing);
}
@@ -58,6 +55,7 @@ public class InboundPlanService {
plan.setId(IdWorker.getId());
plan.setPlanNo("LIP" + plan.getId());
plan.setCustomerId(customerId);
plan.setSourceOrderId(selectedOrderId);
plan.setContainerNo(containerNo);
plan.setStatus("PENDING_ASSIGNMENT");
plan.setLineCount(orders.size());
@@ -92,11 +90,12 @@ public class InboundPlanService {
throw new IllegalStateException("Failed to update order " + order.orderId());
}
orderMapper.insertHistory(order.orderId(), order.currentStatus(),
"Container converted to inbound plan " + plan.getPlanNo(), now);
"Inbound order converted to inbound plan " + plan.getPlanNo(), now);
}
return detail(customerId, plan);
}
@Transactional(readOnly = true)
public InboundPlanResponse detailByPlanNo(String customerId, String planNo) {
InboundPlan plan = planMapper.selectOne(new LambdaQueryWrapper<InboundPlan>()
@@ -107,6 +106,32 @@ public class InboundPlanService {
return detail(customerId, plan);
}
@Transactional
public InboundPlanResponse.Pallet supplementPallet(String customerId, String planNo, SupplementPalletRequest request) {
InboundPlan plan = planMapper.selectOne(new LambdaQueryWrapper<InboundPlan>()
.eq(InboundPlan::getCustomerId, customerId).eq(InboundPlan::getPlanNo, planNo).last("FOR UPDATE"));
if (plan == null) throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Inbound plan not found");
if ("COMPLETED".equals(plan.getStatus())) throw new ResponseStatusException(HttpStatus.CONFLICT, "Completed plan cannot add pallets");
List<InboundPlanLine> lines = lineMapper.selectList(new LambdaQueryWrapper<InboundPlanLine>()
.eq(InboundPlanLine::getPlanId, plan.getId()));
boolean destinationExists = lines.stream().anyMatch(line -> request.destinationWarehouseId().equals(line.getDestinationWarehouseId()));
if (!destinationExists) throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Destination warehouse is not part of this inbound plan");
int sequence = palletMapper.selectList(new LambdaQueryWrapper<InboundPlanPallet>()
.eq(InboundPlanPallet::getPlanId, plan.getId())).stream().map(InboundPlanPallet::getSequenceNo)
.filter(Objects::nonNull).max(Integer::compareTo).orElse(0) + 1;
InboundPlanPallet pallet = new InboundPlanPallet();
pallet.setId(IdWorker.getId()); pallet.setPlanId(plan.getId()); pallet.setPalletNo(plan.getPlanNo() + "-P" + String.format("%03d", sequence));
pallet.setDestinationWarehouseId(request.destinationWarehouseId()); pallet.setDestinationWarehouseCode(request.destinationWarehouseCode());
pallet.setDestinationWarehouseName(request.destinationWarehouseName()); pallet.setCapacityCbm(PalletAllocator.PALLET_CAPACITY_CBM);
pallet.setAllocatedVolumeCbm(BigDecimal.ZERO); pallet.setSequenceNo(sequence); pallet.setAssignmentStatus("UNASSIGNED");
pallet.setActualVolumeCbm(BigDecimal.ZERO); pallet.setActualPackageCount(0); palletMapper.insert(pallet);
plan.setPalletCount(plan.getPalletCount() + 1); plan.setUpdatedAt(LocalDateTime.now()); planMapper.updateById(plan);
return new InboundPlanResponse.Pallet(pallet.getId(), pallet.getPalletNo(), pallet.getDestinationWarehouseId(),
pallet.getDestinationWarehouseCode(), pallet.getDestinationWarehouseName(), pallet.getCapacityCbm(),
pallet.getAllocatedVolumeCbm(), pallet.getSequenceNo(), null, null, null, pallet.getAssignmentStatus(),
null, pallet.getActualVolumeCbm(), pallet.getActualPackageCount());
}
private Map<Long, InboundPlanLine> createLines(InboundPlan plan, List<SourceOrderSnapshot> orders) {
Map<Long, InboundPlanLine> result = new HashMap<>();
for (SourceOrderSnapshot order : orders) {
@@ -211,7 +236,8 @@ public class InboundPlanService {
new LambdaQueryWrapper<InboundPlanPalletAllocation>()
.eq(InboundPlanPalletAllocation::getPlanId, plan.getId())
.orderByAsc(InboundPlanPalletAllocation::getId));
return new InboundPlanResponse(plan.getId(), plan.getPlanNo(), plan.getCustomerId(), plan.getContainerNo(),
return new InboundPlanResponse(plan.getId(), plan.getPlanNo(), plan.getCustomerId(), plan.getSourceOrderId(),
plan.getContainerNo(),
plan.getStatus(), plan.getLineCount(), plan.getPalletCount(), plan.getTotalVolumeCbm(),
lines.stream().map(line -> new InboundPlanResponse.Line(line.getId(), line.getOrderId(), line.getInboundCode(), line.getFbaWarehouseCode(),
line.getDestinationWarehouseId(), line.getDestinationWarehouseCode(), line.getDestinationWarehouseName(),