From b4eca3a3f8ff9a5d5664ea0ab214fa1ceb31713d Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Fri, 18 Jul 2025 13:59:36 +0800 Subject: [PATCH] =?UTF-8?q?=E5=87=BA=E5=85=A5=E7=A7=BB=E5=BA=93=E6=92=A4?= =?UTF-8?q?=E9=94=80=E6=93=8D=E4=BD=9C=20=E8=AE=B0=E5=BD=95=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../klp/controller/WmsStockIoController.java | 20 +++++ .../com/klp/service/IWmsStockIoService.java | 10 +++ .../service/impl/WmsStockIoServiceImpl.java | 73 +++++++++++++++++++ 3 files changed, 103 insertions(+) diff --git a/klp-wms/src/main/java/com/klp/controller/WmsStockIoController.java b/klp-wms/src/main/java/com/klp/controller/WmsStockIoController.java index 7c2ec79c..8b5c1fa0 100644 --- a/klp-wms/src/main/java/com/klp/controller/WmsStockIoController.java +++ b/klp-wms/src/main/java/com/klp/controller/WmsStockIoController.java @@ -113,4 +113,24 @@ public class WmsStockIoController extends BaseController { public R audit(@NotNull(message = "主键不能为空") @PathVariable Long stockIoId) { return toAjax(iWmsStockIoService.auditStockIo(stockIoId)); } + + /** + * 撤销出入库/移库单 + */ + @SaCheckPermission("klp:stockIo:cancel") + @Log(title = "出入库单主", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PostMapping("/cancel/{stockIoId}") + public R cancel(@NotNull(message = "主键不能为空") @PathVariable Long stockIoId) { + return toAjax(iWmsStockIoService.cancelStockIo(stockIoId)); + } + + /** + * 根据ioType和stockIoId联查明细 + */ + @SaCheckPermission("klp:stockIo:detail") + @GetMapping("/detailByTypeAndId") + public R> detailByTypeAndId(@RequestParam String ioType, @RequestParam Long stockIoId) { + return R.ok(iWmsStockIoService.detailByTypeAndId(ioType, stockIoId)); + } } diff --git a/klp-wms/src/main/java/com/klp/service/IWmsStockIoService.java b/klp-wms/src/main/java/com/klp/service/IWmsStockIoService.java index 59817c25..37f79f17 100644 --- a/klp-wms/src/main/java/com/klp/service/IWmsStockIoService.java +++ b/klp-wms/src/main/java/com/klp/service/IWmsStockIoService.java @@ -51,4 +51,14 @@ public interface IWmsStockIoService { * 审核出入库/移库单,变更库存,含库存校验 */ Boolean auditStockIo(Long stockIoId); + + /** + * 撤销出入库/移库单,库存回滚 + */ + Boolean cancelStockIo(Long stockIoId); + + /** + * 根据ioType和stockIoId联查明细 + */ + java.util.List detailByTypeAndId(String ioType, Long stockIoId); } diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsStockIoServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsStockIoServiceImpl.java index 0512f02c..222837b9 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsStockIoServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsStockIoServiceImpl.java @@ -1,6 +1,7 @@ package com.klp.service.impl; import cn.hutool.core.bean.BeanUtil; +import com.klp.common.annotation.RepeatSubmit; import com.klp.common.core.page.TableDataInfo; import com.klp.common.core.domain.PageQuery; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -24,6 +25,7 @@ import java.math.BigDecimal; import java.util.List; import java.util.Map; import java.util.Collection; +import com.klp.common.exception.ServiceException; /** * 出入库单主Service业务层处理 @@ -162,6 +164,77 @@ public class WmsStockIoServiceImpl implements IWmsStockIoService { return true; } + /** + * 撤销出入库/移库单,库存回滚 + */ + @Override + @RepeatSubmit() + @Transactional(rollbackFor = Exception.class) + public Boolean cancelStockIo(Long stockIoId) { + WmsStockIo stockIo = baseMapper.selectById(stockIoId); + if (stockIo == null || stockIo.getStatus() == null || stockIo.getStatus() != 2) { + throw new ServiceException("只能撤销已审核的单据"); + } + List details = stockIoDetailMapper.selectList( + Wrappers.lambdaQuery().eq(WmsStockIoDetail::getStockIoId, stockIoId) + ); + if (details == null || details.isEmpty()) { + throw new ServiceException("单据明细不能为空"); + } + for (WmsStockIoDetail detail : details) { + String ioType = stockIo.getIoType(); + if ("in".equals(ioType)) { + // 入库撤销:目标库位库存减少 + changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), false, detail.getUnit()); + } else if ("out".equals(ioType)) { + // 出库撤销:目标库位库存增加 + changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), true, detail.getUnit()); + } else if ("transfer".equals(ioType)) { + if (detail.getFromWarehouseId() == null) { + throw new ServiceException("移库明细缺少源库位ID"); + } + // 源库位库存增加 + changeStock(detail.getFromWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), true, detail.getUnit()); + // 目标库位库存减少 + changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), false, detail.getUnit()); + } else { + throw new ServiceException("未知的出入库类型"); + } + } + // 更新单据状态为已撤销(3) + stockIo.setStatus(3); + baseMapper.updateById(stockIo); + return true; + } + + /** + * 根据ioType和stockIoId联查明细 + */ + @Override + public java.util.List detailByTypeAndId(String ioType, Long stockIoId) { + WmsStockIo stockIo = baseMapper.selectById(stockIoId); + if (stockIo == null) { + throw new ServiceException("单据不存在"); + } + if (!ioType.equals(stockIo.getIoType())) { + throw new ServiceException("单据类型不匹配"); + } + List details = stockIoDetailMapper.selectList( + Wrappers.lambdaQuery().eq(WmsStockIoDetail::getStockIoId, stockIoId) + ); + if (details == null || details.isEmpty()) { + return java.util.Collections.emptyList(); + } + // 转VO + java.util.List voList = new java.util.ArrayList<>(); + for (WmsStockIoDetail detail : details) { + com.klp.domain.vo.WmsStockIoDetailVo vo = new com.klp.domain.vo.WmsStockIoDetailVo(); + org.springframework.beans.BeanUtils.copyProperties(detail, vo); + voList.add(vo); + } + return voList; + } + /** * 库存增减,isAdd=true为增加,false为减少,减少时校验库存是否足够 */