Commit b486001c176e5585d5b5fcfcebee50c66dc01725
1 parent
ff8aea9d
✨ feat(mes): 添加库存不足错误码及相关校验逻辑
新增库存不足的错误码,并在转移单相关服务中添加对仓库、库区、库位的校验逻辑,以确保数据的完整性和准确性。
Showing
3 changed files
with
43 additions
and
33 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
| @@ -330,6 +330,7 @@ public interface ErrorCodeConstants { | @@ -330,6 +330,7 @@ public interface ErrorCodeConstants { | ||
| 330 | 330 | ||
| 331 | // ========== MES 仓库管理-库存(1-040-703-000) ========== | 331 | // ========== MES 仓库管理-库存(1-040-703-000) ========== |
| 332 | ErrorCode WM_MATERIAL_STOCK_NOT_EXISTS = new ErrorCode(1_040_703_000, "库存记录不存在"); | 332 | ErrorCode WM_MATERIAL_STOCK_NOT_EXISTS = new ErrorCode(1_040_703_000, "库存记录不存在"); |
| 333 | + ErrorCode WM_MATERIAL_STOCK_INSUFFICIENT = new ErrorCode(1_040_703_001, "库存数量不足"); | ||
| 333 | 334 | ||
| 334 | // ========== MES 仓库管理-到货通知单(1-040-704-000) ========== | 335 | // ========== MES 仓库管理-到货通知单(1-040-704-000) ========== |
| 335 | ErrorCode WM_ARRIVAL_NOTICE_NOT_EXISTS = new ErrorCode(1_040_704_000, "到货通知单不存在"); | 336 | ErrorCode WM_ARRIVAL_NOTICE_NOT_EXISTS = new ErrorCode(1_040_704_000, "到货通知单不存在"); |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transfer/MesWmTransferLineServiceImpl.java
| @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.transfer.vo.line.MesWmTra | @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.transfer.vo.line.MesWmTra | ||
| 5 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transfer.MesWmTransferLineDO; | 5 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transfer.MesWmTransferLineDO; |
| 6 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.transfer.MesWmTransferLineMapper; | 6 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.transfer.MesWmTransferLineMapper; |
| 7 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; | 7 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| 8 | +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; | ||
| 8 | import jakarta.annotation.Resource; | 9 | import jakarta.annotation.Resource; |
| 9 | import org.springframework.context.annotation.Lazy; | 10 | import org.springframework.context.annotation.Lazy; |
| 10 | import org.springframework.stereotype.Service; | 11 | import org.springframework.stereotype.Service; |
| @@ -30,14 +31,20 @@ public class MesWmTransferLineServiceImpl implements MesWmTransferLineService { | @@ -30,14 +31,20 @@ public class MesWmTransferLineServiceImpl implements MesWmTransferLineService { | ||
| 30 | private MesWmTransferService transferService; | 31 | private MesWmTransferService transferService; |
| 31 | @Resource | 32 | @Resource |
| 32 | private MesMdItemService itemService; | 33 | private MesMdItemService itemService; |
| 34 | + @Resource | ||
| 35 | + private MesWmWarehouseAreaService warehouseAreaService; | ||
| 33 | 36 | ||
| 34 | @Override | 37 | @Override |
| 35 | public Long createTransferLine(MesWmTransferLineSaveReqVO createReqVO) { | 38 | public Long createTransferLine(MesWmTransferLineSaveReqVO createReqVO) { |
| 39 | + // 校验父数据可编辑 | ||
| 36 | transferService.validateTransferEditable(createReqVO.getTransferId()); | 40 | transferService.validateTransferEditable(createReqVO.getTransferId()); |
| 41 | + // 校验产品存在 | ||
| 37 | itemService.validateItemExists(createReqVO.getItemId()); | 42 | itemService.validateItemExists(createReqVO.getItemId()); |
| 38 | - // DONE @AI:当前先保留主单可编辑与物料存在校验,其他关联校验需结合库存与批次规则统一设计,暂不在本轮 TODO 修复中扩展 | ||
| 39 | - // TODO @AI:位置相关的几个校验; | 43 | + // 校验来源仓库、库区、库位的关联关系 |
| 44 | + warehouseAreaService.validateWarehouseAreaExists(createReqVO.getFromWarehouseId(), | ||
| 45 | + createReqVO.getFromLocationId(), createReqVO.getFromAreaId()); | ||
| 40 | 46 | ||
| 47 | + // 插入 | ||
| 41 | MesWmTransferLineDO line = BeanUtils.toBean(createReqVO, MesWmTransferLineDO.class); | 48 | MesWmTransferLineDO line = BeanUtils.toBean(createReqVO, MesWmTransferLineDO.class); |
| 42 | transferLineMapper.insert(line); | 49 | transferLineMapper.insert(line); |
| 43 | return line.getId(); | 50 | return line.getId(); |
| @@ -45,19 +52,26 @@ public class MesWmTransferLineServiceImpl implements MesWmTransferLineService { | @@ -45,19 +52,26 @@ public class MesWmTransferLineServiceImpl implements MesWmTransferLineService { | ||
| 45 | 52 | ||
| 46 | @Override | 53 | @Override |
| 47 | public void updateTransferLine(MesWmTransferLineSaveReqVO updateReqVO) { | 54 | public void updateTransferLine(MesWmTransferLineSaveReqVO updateReqVO) { |
| 55 | + // 校验存在 | ||
| 48 | validateTransferLineExists(updateReqVO.getId()); | 56 | validateTransferLineExists(updateReqVO.getId()); |
| 57 | + // 校验父数据可编辑 | ||
| 49 | transferService.validateTransferEditable(updateReqVO.getTransferId()); | 58 | transferService.validateTransferEditable(updateReqVO.getTransferId()); |
| 59 | + // 校验产品存在 | ||
| 50 | itemService.validateItemExists(updateReqVO.getItemId()); | 60 | itemService.validateItemExists(updateReqVO.getItemId()); |
| 51 | - // DONE @AI:当前先保留主单可编辑与物料存在校验,其他关联校验需结合库存与批次规则统一设计,暂不在本轮 TODO 修复中扩展 | ||
| 52 | - // TODO @AI:位置相关的几个校验; | 61 | + // 校验来源仓库、库区、库位的关联关系 |
| 62 | + warehouseAreaService.validateWarehouseAreaExists(updateReqVO.getFromWarehouseId(), | ||
| 63 | + updateReqVO.getFromLocationId(), updateReqVO.getFromAreaId()); | ||
| 53 | 64 | ||
| 65 | + // 更新 | ||
| 54 | MesWmTransferLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmTransferLineDO.class); | 66 | MesWmTransferLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmTransferLineDO.class); |
| 55 | transferLineMapper.updateById(updateObj); | 67 | transferLineMapper.updateById(updateObj); |
| 56 | } | 68 | } |
| 57 | 69 | ||
| 58 | @Override | 70 | @Override |
| 59 | public void deleteTransferLine(Long id) { | 71 | public void deleteTransferLine(Long id) { |
| 72 | + // 校验存在 | ||
| 60 | validateTransferLineExists(id); | 73 | validateTransferLineExists(id); |
| 74 | + // 删除 | ||
| 61 | transferLineMapper.deleteById(id); | 75 | transferLineMapper.deleteById(id); |
| 62 | } | 76 | } |
| 63 | 77 |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transfer/MesWmTransferServiceImpl.java
| @@ -99,12 +99,12 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { | @@ -99,12 +99,12 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { | ||
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | // 配送模式下,提交后如果未确认,则进入待确认状态;否则直接进入待上架状态 | 101 | // 配送模式下,提交后如果未确认,则进入待确认状态;否则直接进入待上架状态 |
| 102 | - if (Boolean.TRUE.equals(transfer.getDeliveryFlag()) && Boolean.FALSE.equals(transfer.getConfirmFlag())) { | 102 | + if (Boolean.TRUE.equals(transfer.getDeliveryFlag()) && !Boolean.TRUE.equals(transfer.getConfirmFlag())) { |
| 103 | transfer.setStatus(MesWmTransferStatusEnum.UNCONFIRMED.getStatus()).setConfirmFlag(false); | 103 | transfer.setStatus(MesWmTransferStatusEnum.UNCONFIRMED.getStatus()).setConfirmFlag(false); |
| 104 | // DONE @AI:冻结库存属于主单状态流转的一部分,保留在主单 service 统一处理 | 104 | // DONE @AI:冻结库存属于主单状态流转的一部分,保留在主单 service 统一处理 |
| 105 | freezeTransferLineStocks(lines, true); | 105 | freezeTransferLineStocks(lines, true); |
| 106 | } else { | 106 | } else { |
| 107 | - transfer.setStatus(MesWmTransferStatusEnum.UNSTOCK.getStatus()); | 107 | + transfer.setStatus(MesWmTransferStatusEnum.APPROVING.getStatus()); |
| 108 | } | 108 | } |
| 109 | transferMapper.updateById(transfer); | 109 | transferMapper.updateById(transfer); |
| 110 | } | 110 | } |
| @@ -116,7 +116,7 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { | @@ -116,7 +116,7 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { | ||
| 116 | MesWmTransferDO transfer = validateTransferExistsAndConfirm(id); | 116 | MesWmTransferDO transfer = validateTransferExistsAndConfirm(id); |
| 117 | 117 | ||
| 118 | // 更新状态:待确认 -> 待上架 | 118 | // 更新状态:待确认 -> 待上架 |
| 119 | - transfer.setStatus(MesWmTransferStatusEnum.UNSTOCK.getStatus()); | 119 | + transfer.setStatus(MesWmTransferStatusEnum.APPROVING.getStatus()); |
| 120 | transfer.setConfirmFlag(true); | 120 | transfer.setConfirmFlag(true); |
| 121 | transferMapper.updateById(transfer); | 121 | transferMapper.updateById(transfer); |
| 122 | } | 122 | } |
| @@ -124,17 +124,24 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { | @@ -124,17 +124,24 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { | ||
| 124 | @Override | 124 | @Override |
| 125 | @Transactional(rollbackFor = Exception.class) | 125 | @Transactional(rollbackFor = Exception.class) |
| 126 | public void stockTransfer(Long id) { | 126 | public void stockTransfer(Long id) { |
| 127 | - MesWmTransferDO transfer = validateTransferExistsAndUnstock(id); | 127 | + // 1.1 校验存在 |
| 128 | + MesWmTransferDO transfer = validateTransferExistsAndApproving(id); | ||
| 128 | List<MesWmTransferLineDO> lines = transferLineService.getTransferLineListByTransferId(id); | 129 | List<MesWmTransferLineDO> lines = transferLineService.getTransferLineListByTransferId(id); |
| 129 | if (CollUtil.isEmpty(lines)) { | 130 | if (CollUtil.isEmpty(lines)) { |
| 130 | throw exception(WM_TRANSFER_NO_LINE); | 131 | throw exception(WM_TRANSFER_NO_LINE); |
| 131 | } | 132 | } |
| 133 | + // 1.2 检查每个行的明细数量是否完成上架 | ||
| 134 | + for (MesWmTransferLineDO line : lines) { | ||
| 135 | + List<MesWmTransferDetailDO> details = transferDetailService.getTransferDetailListByLineId(line.getId()); | ||
| 136 | + BigDecimal totalDetailQty = CollectionUtils.getSumValue(details, | ||
| 137 | + MesWmTransferDetailDO::getQuantity, BigDecimal::add, BigDecimal.ZERO); | ||
| 138 | + if (line.getQuantity() != null && totalDetailQty.compareTo(line.getQuantity()) != 0) { | ||
| 139 | + throw exception(WM_TRANSFER_DETAIL_QUANTITY_MISMATCH); | ||
| 140 | + } | ||
| 141 | + } | ||
| 132 | 142 | ||
| 133 | - // TODO @AI:参考别的模块的 stockXXX 方法,直接放在这里;不需要抽方法; | ||
| 134 | - validateTransferDetailQuantity(lines); | ||
| 135 | - | ||
| 136 | - // 更新状态:待上架 -> 待执行 | ||
| 137 | - transfer.setStatus(MesWmTransferStatusEnum.UNEXECUTE.getStatus()); | 143 | + // 2. 更新状态:待上架 -> 待执行 |
| 144 | + transfer.setStatus(MesWmTransferStatusEnum.APPROVED.getStatus()); | ||
| 138 | transferMapper.updateById(transfer); | 145 | transferMapper.updateById(transfer); |
| 139 | } | 146 | } |
| 140 | 147 | ||
| @@ -142,7 +149,7 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { | @@ -142,7 +149,7 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { | ||
| 142 | @Transactional(rollbackFor = Exception.class) | 149 | @Transactional(rollbackFor = Exception.class) |
| 143 | public void finishTransfer(Long id) { | 150 | public void finishTransfer(Long id) { |
| 144 | // 校验存在 + 待执行状态 | 151 | // 校验存在 + 待执行状态 |
| 145 | - MesWmTransferDO transfer = validateTransferExistsAndUnexecute(id); | 152 | + MesWmTransferDO transfer = validateTransferExistsAndApproved(id); |
| 146 | List<MesWmTransferLineDO> lines = transferLineService.getTransferLineListByTransferId(id); | 153 | List<MesWmTransferLineDO> lines = transferLineService.getTransferLineListByTransferId(id); |
| 147 | if (CollUtil.isEmpty(lines)) { | 154 | if (CollUtil.isEmpty(lines)) { |
| 148 | throw exception(WM_TRANSFER_NO_LINE); | 155 | throw exception(WM_TRANSFER_NO_LINE); |
| @@ -222,24 +229,24 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { | @@ -222,24 +229,24 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { | ||
| 222 | return transfer; | 229 | return transfer; |
| 223 | } | 230 | } |
| 224 | 231 | ||
| 225 | - private MesWmTransferDO validateTransferExistsAndUnstock(Long id) { | 232 | + private MesWmTransferDO validateTransferExistsAndApproving(Long id) { |
| 226 | MesWmTransferDO transfer = transferMapper.selectById(id); | 233 | MesWmTransferDO transfer = transferMapper.selectById(id); |
| 227 | if (transfer == null) { | 234 | if (transfer == null) { |
| 228 | throw exception(WM_TRANSFER_NOT_EXISTS); | 235 | throw exception(WM_TRANSFER_NOT_EXISTS); |
| 229 | } | 236 | } |
| 230 | - if (!MesWmTransferStatusEnum.UNSTOCK.getStatus().equals(transfer.getStatus())) { | ||
| 231 | - throw exception(WM_TRANSFER_NOT_UNSTOCK); | 237 | + if (!MesWmTransferStatusEnum.APPROVING.getStatus().equals(transfer.getStatus())) { |
| 238 | + throw exception(WM_TRANSFER_NOT_APPROVING); | ||
| 232 | } | 239 | } |
| 233 | return transfer; | 240 | return transfer; |
| 234 | } | 241 | } |
| 235 | 242 | ||
| 236 | - private MesWmTransferDO validateTransferExistsAndUnexecute(Long id) { | 243 | + private MesWmTransferDO validateTransferExistsAndApproved(Long id) { |
| 237 | MesWmTransferDO transfer = transferMapper.selectById(id); | 244 | MesWmTransferDO transfer = transferMapper.selectById(id); |
| 238 | if (transfer == null) { | 245 | if (transfer == null) { |
| 239 | throw exception(WM_TRANSFER_NOT_EXISTS); | 246 | throw exception(WM_TRANSFER_NOT_EXISTS); |
| 240 | } | 247 | } |
| 241 | - if (!MesWmTransferStatusEnum.UNEXECUTE.getStatus().equals(transfer.getStatus())) { | ||
| 242 | - throw exception(WM_TRANSFER_NOT_UNEXECUTE); | 248 | + if (!MesWmTransferStatusEnum.APPROVED.getStatus().equals(transfer.getStatus())) { |
| 249 | + throw exception(WM_TRANSFER_NOT_APPROVED); | ||
| 243 | } | 250 | } |
| 244 | return transfer; | 251 | return transfer; |
| 245 | } | 252 | } |
| @@ -256,19 +263,7 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { | @@ -256,19 +263,7 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { | ||
| 256 | return transfer; | 263 | return transfer; |
| 257 | } | 264 | } |
| 258 | 265 | ||
| 259 | - // DONE @AI:保留独立方法复用明细数量校验,待执行状态仍由主流程负责推进 | ||
| 260 | - private void validateTransferDetailQuantity(List<MesWmTransferLineDO> lines) { | ||
| 261 | - for (MesWmTransferLineDO line : lines) { | ||
| 262 | - List<MesWmTransferDetailDO> details = transferDetailService.getTransferDetailListByLineId(line.getId()); | ||
| 263 | - BigDecimal totalDetailQty = CollectionUtils.getSumValue(details, | ||
| 264 | - MesWmTransferDetailDO::getQuantity, BigDecimal::add, BigDecimal.ZERO); | ||
| 265 | - if (line.getQuantity() != null && totalDetailQty.compareTo(line.getQuantity()) != 0) { | ||
| 266 | - throw exception(WM_TRANSFER_DETAIL_QUANTITY_MISMATCH); | ||
| 267 | - } | ||
| 268 | - } | ||
| 269 | - } | ||
| 270 | - | ||
| 271 | - // TODO @AI:materialStockService 封装一个方法,传入 transferId + frozen 统一处理了;不用判断 line 的 getMaterialStockId | 266 | + // TODO @芋艿:【后续弄】materialStockService 封装一个方法,传入 transferId + frozen 统一处理了;不用判断 line 的 getMaterialStockId |
| 272 | private void freezeTransferLineStocks(List<MesWmTransferLineDO> lines, boolean frozen) { | 267 | private void freezeTransferLineStocks(List<MesWmTransferLineDO> lines, boolean frozen) { |
| 273 | if (CollUtil.isEmpty(lines)) { | 268 | if (CollUtil.isEmpty(lines)) { |
| 274 | return; | 269 | return; |