feat(wms): 实现调拨分包打印功能

- 新增调拨分包打印相关接口和实现
- 增加调拨任务创建、查询、更新和删除功能
- 实现触发打印条码和验证可打印性功能
- 优化调拨明细查询,增加已分包数量字段
master
zangch@mesnac.com 3 months ago
parent 06957a151f
commit e0b13ae13b

@ -1,26 +1,27 @@
package org.dromara.wms.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.wms.domain.vo.WmsAllocateTaskVo;
import org.dromara.wms.domain.bo.WmsAllocateTaskBo;
import org.dromara.wms.service.IWmsAllocateTaskService;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController;
import org.dromara.wms.domain.bo.WmsAllocateTaskBo;
import org.dromara.wms.domain.vo.WmsAllocateTaskVo;
import org.dromara.wms.service.IWmsAllocateTaskService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
*
@ -108,10 +109,93 @@ public class WmsAllocateTaskController extends BaseController {
/**
*
*/
@GetMapping("/getWmsAllocateTaskList")
public R<List<WmsAllocateTaskVo>> getWmsAllocateTaskList(WmsAllocateTaskBo bo) {
List<WmsAllocateTaskVo> list = wmsAllocateTaskService.queryList(bo);
return R.ok(list);
}
/**
*
*/
@SaCheckPermission("wms:wmsAllocateTask:print")
@Log(title = "调拨分包打印", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/packagePrint")
public R<Void> packagePrint(@RequestBody WmsAllocateTaskBo bo) {
return toAjax(wmsAllocateTaskService.allocatePackagePrint(
bo.getAllocateCode(),
bo.getAoDId(),
bo.getPackageQtyList(),
bo.getSplitPackageCount(),
bo.getPrintCopies()));
}
/**
*
*/
@SaCheckPermission("wms:wmsAllocateTask:query")
@GetMapping("/queryTasksByDetailId/{aoDId}")
public R<List<WmsAllocateTaskVo>> queryTasksByDetailId(@PathVariable Long aoDId) {
List<WmsAllocateTaskVo> list = wmsAllocateTaskService.queryTasksByDetailId(aoDId);
return R.ok(list);
}
/**
*
*/
@SaCheckPermission("wms:wmsAllocateTask:query")
@PostMapping("/validatePrintable")
public R<Boolean> validatePrintable(@RequestBody WmsAllocateTaskBo bo) {
return R.ok(wmsAllocateTaskService.validatePrintable(bo.getAoDId()));
}
/**
*
*/
// @SaCheckPermission("wms:wmsAllocateTask:print")
@Log(title = "触发打印条码", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/triggerPrint/{allocateTaskId}")
public R<Void> triggerPrint(@PathVariable Long allocateTaskId) {
return toAjax(wmsAllocateTaskService.triggerPrint(allocateTaskId));
}
/**
*
*/
@SaCheckPermission("wms:wmsAllocateTask:edit")
@Log(title = "重新创建调拨任务", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/recreateTasks")
public R<Void> recreateTasks(@RequestBody WmsAllocateTaskBo bo) {
return toAjax(wmsAllocateTaskService.recreateAllocateTasks(
bo.getAoDId(),
bo.getPackageQtyList(),
bo.getSplitPackageCount()));
}
/**
*
*/
@SaCheckPermission("wms:wmsAllocateTask:edit")
@Log(title = "修改调拨任务条码", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/updateBarcode")
public R<Void> updateTaskBarcode(@RequestBody WmsAllocateTaskBo bo) {
return toAjax(wmsAllocateTaskService.updateTaskBarcode(
bo.getAllocateTaskId(),
bo.getBatchCode(),
bo.getMaterialQty()));
}
/**
*
*/
@SaCheckPermission("wms:wmsAllocateTask:remove")
@Log(title = "删除调拨任务", businessType = BusinessType.DELETE)
@DeleteMapping("/deleteTasksByDetailId/{aoDId}")
public R<Void> deleteTasksByDetailId(@PathVariable Long aoDId) {
return toAjax(wmsAllocateTaskService.deleteTasksByDetailId(aoDId));
}
}

@ -50,6 +50,13 @@ public class WmsAllocateOrderDetail {
* erp
*/
private Long erpSynchronousQty;
/**
*
*/
@TableField(exist = false)
private BigDecimal printedQty;
/**
* id
*/

@ -153,7 +153,4 @@ public class WmsInstockPrint{
@TableField(exist = false)
private String materialCategoryName;//字段映射
}

@ -57,6 +57,12 @@ public class WmsAllocateOrderDetailBo extends BaseEntity {
*/
// @NotNull(message = "erp同步数量不能为空", groups = { AddGroup.class, EditGroup.class })
private Long erpSynchronousQty;
/**
*
*/
private BigDecimal printedQty;
private String tenantId;
/**

@ -9,6 +9,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
@ -102,5 +103,20 @@ public class WmsAllocateTaskBo extends BaseEntity {
*/
private Long aoDId;
/**
*
*/
private Integer splitPackageCount;
/**
*
*/
private Integer printCopies;
/**
*
*/
private List<Integer> packageQtyList;
}

@ -66,6 +66,12 @@ public class WmsAllocateOrderDetailVo implements Serializable {
*/
@ExcelProperty(value = "erp同步数量")
private Long erpSynchronousQty;
/**
*
*/
@ExcelProperty(value = "已分包数量")
private BigDecimal printedQty;
/**
* id
*/

@ -9,7 +9,7 @@ import org.dromara.wms.domain.WmsInstockOrder;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
@ -86,6 +86,9 @@ public class WmsInstockOrderVo implements Serializable {
@ExcelProperty(value = "仓库ID")
private Long warehouseId;
@ExcelProperty(value = "入库单子表")
private List<WmsInstockDetailVo> excelDetailList;
/**
* id
*/

@ -66,4 +66,69 @@ public interface IWmsAllocateTaskService {
* @return
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
*
*
* @param allocateCode
* @param aoDId ID
* @param packageQtyList
* @param splitPackageCount
* @param printCopies
* @return
*/
Boolean allocatePackagePrint(String allocateCode, Long aoDId, List<Integer> packageQtyList,
Integer splitPackageCount, Integer printCopies);
/**
*
*
* @param allocateTaskId ID
* @return
*/
Boolean triggerPrint(Long allocateTaskId);
/**
*
*
* @param aoDId ID
* @param packageQtyList
* @param splitPackageCount
* @return
*/
Boolean recreateAllocateTasks(Long aoDId, List<Integer> packageQtyList, Integer splitPackageCount);
/**
*
*
* @param allocateTaskId ID
* @param batchCode
* @param materialQty
* @return
*/
Boolean updateTaskBarcode(Long allocateTaskId, String batchCode, Long materialQty);
/**
*
*
* @param aoDId ID
* @return
*/
List<WmsAllocateTaskVo> queryTasksByDetailId(Long aoDId);
/**
*
*
* @param aoDId ID
* @return
*/
Boolean validatePrintable(Long aoDId);
/**
*
*
* @param aoDId ID
* @return
*/
Boolean deleteTasksByDetailId(Long aoDId);
}

@ -10,15 +10,26 @@ import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.dromara.wms.domain.bo.WmsAllocateTaskBo;
import org.dromara.wms.domain.vo.WmsAllocateTaskVo;
import org.dromara.wms.domain.WmsAllocateTask;
import org.dromara.wms.domain.WmsAllocateOrderDetail;
import org.dromara.wms.domain.BaseMaterialInfo;
import org.dromara.wms.mapper.WmsAllocateTaskMapper;
import org.dromara.wms.service.IWmsAllocateTaskService;
import org.dromara.wms.service.IWmsAllocateOrderDetailService;
import org.dromara.wms.service.IBaseMaterialInfoService;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.core.exception.ServiceException;
import org.springframework.beans.BeanUtils;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.Date;
import java.math.BigDecimal;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Service
@ -31,6 +42,14 @@ import java.util.Collection;
public class WmsAllocateTaskServiceImpl implements IWmsAllocateTaskService {
private final WmsAllocateTaskMapper baseMapper;
private final IWmsAllocateOrderDetailService allocateOrderDetailService;
private final IBaseMaterialInfoService baseMaterialInfoService;
private static final AtomicInteger sequence = new AtomicInteger(1);
public static Integer nextSequence() {
return sequence.incrementAndGet();
}
/**
*
@ -140,8 +159,295 @@ public class WmsAllocateTaskServiceImpl implements IWmsAllocateTaskService {
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
// 校验调拨任务是否已开始执行
List<WmsAllocateTask> tasks = baseMapper.selectByIds(ids);
for (WmsAllocateTask task : tasks) {
if ("1".equals(task.getInboundStatus()) || "2".equals(task.getInboundStatus())) {//入库状态(0-待入库,1-已入库,2-入库中)
throw new ServiceException("调拨任务[" + task.getAllocateCode() + "]已开始执行,不允许删除");
}
}
}
return baseMapper.deleteByIds(ids) > 0;
}
/**
*
*
* @param allocateCode
* @param aoDId ID
* @param packageQtyList
* @param splitPackageCount
* @param printCopies
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean allocatePackagePrint(String allocateCode, Long aoDId, List<Integer> packageQtyList,
Integer splitPackageCount, Integer printCopies) {
// 获取调拨明细
org.dromara.wms.domain.vo.WmsAllocateOrderDetailVo detailVo = allocateOrderDetailService.queryById(aoDId);
if (detailVo == null) {
throw new ServiceException("调拨明细不存在");
}
// 获取物料信息
org.dromara.wms.domain.vo.BaseMaterialInfoVo materialInfoVo = null;
if (detailVo.getMaterialId() != null) {
materialInfoVo = baseMaterialInfoService.queryById(detailVo.getMaterialId());
}
// 检查是否已经打印过
List<WmsAllocateTaskVo> existingTasks = queryTasksByDetailId(aoDId);
if (!existingTasks.isEmpty()) {
throw new ServiceException("该调拨明细已经打印过,不允许重复打印");
}
int splitInt = splitPackageCount != null ? splitPackageCount : 1;
int copiesInt = printCopies != null ? printCopies : 1;
// 获取当前打印序列
Integer printSeq = nextSequence();
String baseOrder = generateOrder(printSeq);
BigDecimal totalPackaged = BigDecimal.ZERO;
if (splitInt > 1) {
// 分包逻辑 - 统一处理模式
if (packageQtyList == null || packageQtyList.size() != splitInt) {
throw new ServiceException("分包数量列表与分包数量不匹配");
}
// 验证每包数量总计是否等于调拨数量
BigDecimal totalCustomQty = packageQtyList.stream()
.map(BigDecimal::valueOf)
.reduce(BigDecimal.ZERO, BigDecimal::add);
if (totalCustomQty.compareTo(detailVo.getAllocateOrderQty()) != 0) {
throw new ServiceException("分包数量总计必须等于调拨数量" + detailVo.getAllocateOrderQty() + ",当前总计:" + totalCustomQty);
}
// 遍历packageQtyList创建打印记录
for (int i = 1; i <= splitInt; i++) {
String order = baseOrder + String.format("%03d", i);
String batchCode = generateBatchCode(allocateCode, materialInfoVo != null ? materialInfoVo.getMaterialCode() : "", order);
BigDecimal currentPackageQty = BigDecimal.valueOf(packageQtyList.get(i - 1)); // 当前包的物料数量
WmsAllocateTask task = createAllocateTask(detailVo, materialInfoVo, allocateCode, batchCode, currentPackageQty.longValue(), 1L, aoDId);
baseMapper.insert(task);
totalPackaged = totalPackaged.add(currentPackageQty);
}
} else {
// 重复打印逻辑split == 1
if (copiesInt < 1) {
copiesInt = 1;
}
String batchCode = generateBatchCode(allocateCode, materialInfoVo != null ? materialInfoVo.getMaterialCode() : "", baseOrder);
WmsAllocateTask task = createAllocateTask(detailVo, materialInfoVo, allocateCode, batchCode,
detailVo.getAllocateOrderQty().longValue(), (long) copiesInt, aoDId);
baseMapper.insert(task);
totalPackaged = detailVo.getAllocateOrderQty(); // 全部调拨数量都被打印
}
// 更新调拨明细的已分包数量
org.dromara.wms.domain.bo.WmsAllocateOrderDetailBo detailBo = new org.dromara.wms.domain.bo.WmsAllocateOrderDetailBo();
detailBo.setAoDId(detailVo.getAoDId());
detailBo.setPrintedQty(totalPackaged);
allocateOrderDetailService.updateByBo(detailBo);
return true;
}
/**
*
*/
private WmsAllocateTask createAllocateTask(org.dromara.wms.domain.vo.WmsAllocateOrderDetailVo detailVo,
org.dromara.wms.domain.vo.BaseMaterialInfoVo materialInfoVo,
String allocateCode, String batchCode, Long materialQty,
Long apportionQty, Long aoDId) {
WmsAllocateTask task = new WmsAllocateTask();
task.setAllocateCode(allocateCode);
task.setBatchCode(batchCode);
task.setMaterialQty(materialQty); // 每包的物料数量
task.setApportionQty(apportionQty); // 打印的包数
task.setMaterialId(detailVo.getMaterialId());
task.setInboundStatus("0"); // 入库状态(0-待入库,1-已入库,2-入库中)
task.setAoDId(aoDId);
// 填充物料信息
if (materialInfoVo != null) {
task.setMaterialId(materialInfoVo.getMaterialId());
task.setMaterialCode(materialInfoVo.getMaterialCode());
task.setMaterialName(materialInfoVo.getMaterialName());
task.setMaterialSpe(materialInfoVo.getMaterialSpec());
task.setUnitName(materialInfoVo.getUnitName());
}
return task;
}
/**
*
*
* @param aoDId ID
* @return
*/
@Override
public List<WmsAllocateTaskVo> queryTasksByDetailId(Long aoDId) {
MPJLambdaWrapper<WmsAllocateTask> lqw = JoinWrappers.lambda(WmsAllocateTask.class)
.selectAll(WmsAllocateTask.class)
.eq(WmsAllocateTask::getAoDId, aoDId)
.orderByDesc(WmsAllocateTask::getCreateTime);
return baseMapper.selectVoList(lqw);
}
/**
*
*
* @param aoDId ID
* @return
*/
@Override
public Boolean validatePrintable(Long aoDId) {
// 检查是否已经打印过
List<WmsAllocateTaskVo> existingTasks = queryTasksByDetailId(aoDId);
return existingTasks.isEmpty();
}
/**
*
*
* @param allocateTaskId ID
* @return
*/
@Override
public Boolean triggerPrint(Long allocateTaskId) {
WmsAllocateTask task = baseMapper.selectById(allocateTaskId);
if (task == null) {
throw new ServiceException("调拨任务不存在");
}
// 检查任务状态
if ("1".equals(task.getInboundStatus()) || "2".equals(task.getInboundStatus())) {//入库状态(0-待入库,1-已入库,2-入库中)
throw new ServiceException("该任务已开始执行,不允许重复打印");
}
// TODO: 这里可以集成实际的打印机接口
// 暂时只记录日志
System.out.println("触发打印任务: " + task.getBatchCode() + ", 数量: " + task.getMaterialQty());
return true;
}
/**
*
*
* @param aoDId ID
* @param packageQtyList
* @param splitPackageCount
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean recreateAllocateTasks(Long aoDId, List<Integer> packageQtyList, Integer splitPackageCount) {
// 先删除现有的任务
deleteTasksByDetailId(aoDId);
// 获取调拨明细
org.dromara.wms.domain.vo.WmsAllocateOrderDetailVo detailVo = allocateOrderDetailService.queryById(aoDId);
if (detailVo == null) {
throw new ServiceException("调拨明细不存在");
}
// 重新创建任务
return allocatePackagePrint(detailVo.getAllocateCode(), aoDId, packageQtyList, splitPackageCount, 1);
}
/**
*
*
* @param allocateTaskId ID
* @param batchCode
* @param materialQty
* @return
*/
@Override
public Boolean updateTaskBarcode(Long allocateTaskId, String batchCode, Long materialQty) {
WmsAllocateTask task = baseMapper.selectById(allocateTaskId);
if (task == null) {
throw new ServiceException("调拨任务不存在");
}
// 检查任务状态
if ("1".equals(task.getInboundStatus()) || "2".equals(task.getInboundStatus())) {//入库状态(0-待入库,1-已入库,2-入库中)
throw new ServiceException("该任务已开始执行,不允许修改");
}
// 更新任务信息
task.setBatchCode(batchCode);
task.setMaterialQty(materialQty);
return baseMapper.updateById(task) > 0;
}
/**
*
*
* @param aoDId ID
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteTasksByDetailId(Long aoDId) {
MPJLambdaWrapper<WmsAllocateTask> wrapper = JoinWrappers.lambda(WmsAllocateTask.class)
.eq(WmsAllocateTask::getAoDId, aoDId);
List<WmsAllocateTask> tasks = baseMapper.selectList(wrapper);
// 检查是否有已开始执行的任务
for (WmsAllocateTask task : tasks) {
if ("1".equals(task.getInboundStatus()) || "2".equals(task.getInboundStatus())) {//入库状态(0-待入库,1-已入库,2-入库中)
throw new ServiceException("存在已开始执行的任务,不允许删除");
}
}
if (!tasks.isEmpty()) {
List<Long> taskIds = tasks.stream().map(WmsAllocateTask::getAllocateTaskId).toList();
int deleteCount = baseMapper.deleteByIds(taskIds);
// 更新调拨明细的已分包数量
org.dromara.wms.domain.vo.WmsAllocateOrderDetailVo detailVo = allocateOrderDetailService.queryById(aoDId);
if (detailVo != null) {
org.dromara.wms.domain.bo.WmsAllocateOrderDetailBo detailBo = new org.dromara.wms.domain.bo.WmsAllocateOrderDetailBo();
detailBo.setAoDId(detailVo.getAoDId());
detailBo.setPrintedQty(BigDecimal.ZERO);
allocateOrderDetailService.updateByBo(detailBo);
}
return deleteCount > 0;
}
return true;
}
/**
*
*/
private String generateOrder(Integer value) {
if (value.toString().length() < 3) {
return String.format("%03d", value);
} else if (value.toString().length() == 3) {
return value.toString();
}
return value.toString();
}
/**
*
*/
private String generateBatchCode(String allocateCode, String materialCode, String order) {
return allocateCode + materialCode + order;
}
}

Loading…
Cancel
Save