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 | 330 | |
| 331 | 331 | // ========== MES 仓库管理-库存(1-040-703-000) ========== |
| 332 | 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 | 335 | // ========== MES 仓库管理-到货通知单(1-040-704-000) ========== |
| 335 | 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 | 5 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transfer.MesWmTransferLineDO; |
| 6 | 6 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.transfer.MesWmTransferLineMapper; |
| 7 | 7 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| 8 | +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; | |
| 8 | 9 | import jakarta.annotation.Resource; |
| 9 | 10 | import org.springframework.context.annotation.Lazy; |
| 10 | 11 | import org.springframework.stereotype.Service; |
| ... | ... | @@ -30,14 +31,20 @@ public class MesWmTransferLineServiceImpl implements MesWmTransferLineService { |
| 30 | 31 | private MesWmTransferService transferService; |
| 31 | 32 | @Resource |
| 32 | 33 | private MesMdItemService itemService; |
| 34 | + @Resource | |
| 35 | + private MesWmWarehouseAreaService warehouseAreaService; | |
| 33 | 36 | |
| 34 | 37 | @Override |
| 35 | 38 | public Long createTransferLine(MesWmTransferLineSaveReqVO createReqVO) { |
| 39 | + // 校验父数据可编辑 | |
| 36 | 40 | transferService.validateTransferEditable(createReqVO.getTransferId()); |
| 41 | + // 校验产品存在 | |
| 37 | 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 | 48 | MesWmTransferLineDO line = BeanUtils.toBean(createReqVO, MesWmTransferLineDO.class); |
| 42 | 49 | transferLineMapper.insert(line); |
| 43 | 50 | return line.getId(); |
| ... | ... | @@ -45,19 +52,26 @@ public class MesWmTransferLineServiceImpl implements MesWmTransferLineService { |
| 45 | 52 | |
| 46 | 53 | @Override |
| 47 | 54 | public void updateTransferLine(MesWmTransferLineSaveReqVO updateReqVO) { |
| 55 | + // 校验存在 | |
| 48 | 56 | validateTransferLineExists(updateReqVO.getId()); |
| 57 | + // 校验父数据可编辑 | |
| 49 | 58 | transferService.validateTransferEditable(updateReqVO.getTransferId()); |
| 59 | + // 校验产品存在 | |
| 50 | 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 | 66 | MesWmTransferLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmTransferLineDO.class); |
| 55 | 67 | transferLineMapper.updateById(updateObj); |
| 56 | 68 | } |
| 57 | 69 | |
| 58 | 70 | @Override |
| 59 | 71 | public void deleteTransferLine(Long id) { |
| 72 | + // 校验存在 | |
| 60 | 73 | validateTransferLineExists(id); |
| 74 | + // 删除 | |
| 61 | 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 | 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 | 103 | transfer.setStatus(MesWmTransferStatusEnum.UNCONFIRMED.getStatus()).setConfirmFlag(false); |
| 104 | 104 | // DONE @AI:冻结库存属于主单状态流转的一部分,保留在主单 service 统一处理 |
| 105 | 105 | freezeTransferLineStocks(lines, true); |
| 106 | 106 | } else { |
| 107 | - transfer.setStatus(MesWmTransferStatusEnum.UNSTOCK.getStatus()); | |
| 107 | + transfer.setStatus(MesWmTransferStatusEnum.APPROVING.getStatus()); | |
| 108 | 108 | } |
| 109 | 109 | transferMapper.updateById(transfer); |
| 110 | 110 | } |
| ... | ... | @@ -116,7 +116,7 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { |
| 116 | 116 | MesWmTransferDO transfer = validateTransferExistsAndConfirm(id); |
| 117 | 117 | |
| 118 | 118 | // 更新状态:待确认 -> 待上架 |
| 119 | - transfer.setStatus(MesWmTransferStatusEnum.UNSTOCK.getStatus()); | |
| 119 | + transfer.setStatus(MesWmTransferStatusEnum.APPROVING.getStatus()); | |
| 120 | 120 | transfer.setConfirmFlag(true); |
| 121 | 121 | transferMapper.updateById(transfer); |
| 122 | 122 | } |
| ... | ... | @@ -124,17 +124,24 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { |
| 124 | 124 | @Override |
| 125 | 125 | @Transactional(rollbackFor = Exception.class) |
| 126 | 126 | public void stockTransfer(Long id) { |
| 127 | - MesWmTransferDO transfer = validateTransferExistsAndUnstock(id); | |
| 127 | + // 1.1 校验存在 | |
| 128 | + MesWmTransferDO transfer = validateTransferExistsAndApproving(id); | |
| 128 | 129 | List<MesWmTransferLineDO> lines = transferLineService.getTransferLineListByTransferId(id); |
| 129 | 130 | if (CollUtil.isEmpty(lines)) { |
| 130 | 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 | 145 | transferMapper.updateById(transfer); |
| 139 | 146 | } |
| 140 | 147 | |
| ... | ... | @@ -142,7 +149,7 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { |
| 142 | 149 | @Transactional(rollbackFor = Exception.class) |
| 143 | 150 | public void finishTransfer(Long id) { |
| 144 | 151 | // 校验存在 + 待执行状态 |
| 145 | - MesWmTransferDO transfer = validateTransferExistsAndUnexecute(id); | |
| 152 | + MesWmTransferDO transfer = validateTransferExistsAndApproved(id); | |
| 146 | 153 | List<MesWmTransferLineDO> lines = transferLineService.getTransferLineListByTransferId(id); |
| 147 | 154 | if (CollUtil.isEmpty(lines)) { |
| 148 | 155 | throw exception(WM_TRANSFER_NO_LINE); |
| ... | ... | @@ -222,24 +229,24 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { |
| 222 | 229 | return transfer; |
| 223 | 230 | } |
| 224 | 231 | |
| 225 | - private MesWmTransferDO validateTransferExistsAndUnstock(Long id) { | |
| 232 | + private MesWmTransferDO validateTransferExistsAndApproving(Long id) { | |
| 226 | 233 | MesWmTransferDO transfer = transferMapper.selectById(id); |
| 227 | 234 | if (transfer == null) { |
| 228 | 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 | 240 | return transfer; |
| 234 | 241 | } |
| 235 | 242 | |
| 236 | - private MesWmTransferDO validateTransferExistsAndUnexecute(Long id) { | |
| 243 | + private MesWmTransferDO validateTransferExistsAndApproved(Long id) { | |
| 237 | 244 | MesWmTransferDO transfer = transferMapper.selectById(id); |
| 238 | 245 | if (transfer == null) { |
| 239 | 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 | 251 | return transfer; |
| 245 | 252 | } |
| ... | ... | @@ -256,19 +263,7 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { |
| 256 | 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 | 267 | private void freezeTransferLineStocks(List<MesWmTransferLineDO> lines, boolean frozen) { |
| 273 | 268 | if (CollUtil.isEmpty(lines)) { |
| 274 | 269 | return; | ... | ... |