Commit a682efdbcf491b73d266e350c4a469ce55fefbcc
1 parent
6a9c2c25
✨ feat(mes): 添加库存调拨事务创建逻辑,支持出入库操作
Showing
1 changed file
with
46 additions
and
4 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transfer/MesWmTransferServiceImpl.java
| @@ -11,8 +11,12 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transfer.MesWmTransferDO; | @@ -11,8 +11,12 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transfer.MesWmTransferDO; | ||
| 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transfer.MesWmTransferDetailDO; | 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transfer.MesWmTransferDetailDO; |
| 12 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transfer.MesWmTransferLineDO; | 12 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transfer.MesWmTransferLineDO; |
| 13 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.transfer.MesWmTransferMapper; | 13 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.transfer.MesWmTransferMapper; |
| 14 | +import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; | ||
| 15 | +import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; | ||
| 14 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransferStatusEnum; | 16 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransferStatusEnum; |
| 15 | import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; | 17 | import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; |
| 18 | +import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService; | ||
| 19 | +import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO; | ||
| 16 | import jakarta.annotation.Resource; | 20 | import jakarta.annotation.Resource; |
| 17 | import org.springframework.stereotype.Service; | 21 | import org.springframework.stereotype.Service; |
| 18 | import org.springframework.transaction.annotation.Transactional; | 22 | import org.springframework.transaction.annotation.Transactional; |
| @@ -20,6 +24,7 @@ import org.springframework.validation.annotation.Validated; | @@ -20,6 +24,7 @@ import org.springframework.validation.annotation.Validated; | ||
| 20 | 24 | ||
| 21 | import java.math.BigDecimal; | 25 | import java.math.BigDecimal; |
| 22 | import java.util.List; | 26 | import java.util.List; |
| 27 | +import java.util.Map; | ||
| 23 | 28 | ||
| 24 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 29 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 25 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; | 30 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| @@ -40,6 +45,8 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { | @@ -40,6 +45,8 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { | ||
| 40 | private MesWmTransferDetailService transferDetailService; | 45 | private MesWmTransferDetailService transferDetailService; |
| 41 | @Resource | 46 | @Resource |
| 42 | private MesWmMaterialStockService materialStockService; | 47 | private MesWmMaterialStockService materialStockService; |
| 48 | + @Resource | ||
| 49 | + private MesWmTransactionService wmTransactionService; | ||
| 43 | 50 | ||
| 44 | @Override | 51 | @Override |
| 45 | public Long createTransfer(MesWmTransferSaveReqVO createReqVO) { | 52 | public Long createTransfer(MesWmTransferSaveReqVO createReqVO) { |
| @@ -148,25 +155,60 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { | @@ -148,25 +155,60 @@ public class MesWmTransferServiceImpl implements MesWmTransferService { | ||
| 148 | @Override | 155 | @Override |
| 149 | @Transactional(rollbackFor = Exception.class) | 156 | @Transactional(rollbackFor = Exception.class) |
| 150 | public void finishTransfer(Long id) { | 157 | public void finishTransfer(Long id) { |
| 151 | - // 校验存在 + 待执行状态 | 158 | + // 1. 校验存在 + 待执行状态 |
| 152 | MesWmTransferDO transfer = validateTransferExistsAndApproved(id); | 159 | MesWmTransferDO transfer = validateTransferExistsAndApproved(id); |
| 153 | List<MesWmTransferLineDO> lines = transferLineService.getTransferLineListByTransferId(id); | 160 | List<MesWmTransferLineDO> lines = transferLineService.getTransferLineListByTransferId(id); |
| 154 | if (CollUtil.isEmpty(lines)) { | 161 | if (CollUtil.isEmpty(lines)) { |
| 155 | throw exception(WM_TRANSFER_NO_LINE); | 162 | throw exception(WM_TRANSFER_NO_LINE); |
| 156 | } | 163 | } |
| 157 | 164 | ||
| 158 | - // DONE @AI:库存转移涉及出入库落账与库存事务联动,当前提交先保留状态流转与冻结解冻校验,不在本轮 TODO 修复中扩展业务实现 | 165 | + // 2. 创建库存事务(调拨移出 + 调拨移入) |
| 166 | + createTransferTransactions(transfer, lines); | ||
| 159 | 167 | ||
| 160 | - // 更新状态:待执行 -> 已完成 | 168 | + // 3. 更新状态:待执行 -> 已完成 |
| 161 | transfer.setStatus(MesWmTransferStatusEnum.FINISHED.getStatus()); | 169 | transfer.setStatus(MesWmTransferStatusEnum.FINISHED.getStatus()); |
| 162 | transferMapper.updateById(transfer); | 170 | transferMapper.updateById(transfer); |
| 163 | 171 | ||
| 164 | - // 配送模式下,执行完成后解除来源库存冻结 | 172 | + // 4. 配送模式下,执行完成后解除来源库存冻结 |
| 165 | if (Boolean.TRUE.equals(transfer.getDeliveryFlag())) { | 173 | if (Boolean.TRUE.equals(transfer.getDeliveryFlag())) { |
| 166 | freezeTransferLineStocks(lines, false); | 174 | freezeTransferLineStocks(lines, false); |
| 167 | } | 175 | } |
| 168 | } | 176 | } |
| 169 | 177 | ||
| 178 | + /** | ||
| 179 | + * 创建调拨事务:基于 detail (明细) 的视角,不是纯粹的 line(行)的视角。 | ||
| 180 | + * 因为明细才代表了实际调往各个目标仓位的动作,所以每条明細产生一笔出库(MOVE_OUT)和一笔入库(MOVE_IN)。 | ||
| 181 | + */ | ||
| 182 | + private void createTransferTransactions(MesWmTransferDO transfer, List<MesWmTransferLineDO> lines) { | ||
| 183 | + // 1. 预加载所有明细,按 lineId 分组,避免 N+1 查询 | ||
| 184 | + List<MesWmTransferDetailDO> allDetails = transferDetailService.getTransferDetailListByTransferId(transfer.getId()); | ||
| 185 | + Map<Long, List<MesWmTransferDetailDO>> detailMap = CollectionUtils.convertMultiMap( | ||
| 186 | + allDetails, MesWmTransferDetailDO::getLineId); | ||
| 187 | + // 2. 遍历行和对应的明细,创建事务 | ||
| 188 | + for (MesWmTransferLineDO line : lines) { | ||
| 189 | + List<MesWmTransferDetailDO> details = detailMap.getOrDefault(line.getId(), List.of()); | ||
| 190 | + for (MesWmTransferDetailDO detail : details) { | ||
| 191 | + // 2.1 先执行出库:调拨移出(从源仓库扣减库存),出库数量基于当前明细的数量 | ||
| 192 | + Long outTransactionId = wmTransactionService.createTransaction(new MesWmTransactionSaveReqDTO() | ||
| 193 | + .setType(MesWmTransactionTypeEnum.MOVE_OUT.getType()).setItemId(line.getItemId()) | ||
| 194 | + .setQuantity(detail.getQuantity().negate()) // 库存减少(按 detail 的数量出) | ||
| 195 | + .setBatchId(line.getBatchId()) | ||
| 196 | + .setWarehouseId(line.getFromWarehouseId()).setLocationId(line.getFromLocationId()).setAreaId(line.getFromAreaId()) | ||
| 197 | + .setBizType(MesBizTypeConstants.WM_TRANSFER_OUT).setBizId(transfer.getId()) | ||
| 198 | + .setBizCode(transfer.getCode()).setBizLineId(line.getId())); | ||
| 199 | + // 2.2 再执行入库:调拨移入(向目标仓库增加库存),入库数量等于相同明细的数量 | ||
| 200 | + wmTransactionService.createTransaction(new MesWmTransactionSaveReqDTO() | ||
| 201 | + .setType(MesWmTransactionTypeEnum.MOVE_IN.getType()).setItemId(line.getItemId()) // 物料信息来自 line | ||
| 202 | + .setQuantity(detail.getQuantity()) // 库存增加(按 detail 的数量入) | ||
| 203 | + .setBatchId(line.getBatchId()) // 批次信息来自 line | ||
| 204 | + .setWarehouseId(detail.getToWarehouseId()).setLocationId(detail.getToLocationId()).setAreaId(detail.getToAreaId()) | ||
| 205 | + .setBizType(MesBizTypeConstants.WM_TRANSFER_IN).setBizId(transfer.getId()) | ||
| 206 | + .setBizCode(transfer.getCode()).setBizLineId(line.getId()) | ||
| 207 | + .setRelatedTransactionId(outTransactionId)); // 关联本次的具体出库事务 | ||
| 208 | + } | ||
| 209 | + } | ||
| 210 | + } | ||
| 211 | + | ||
| 170 | @Override | 212 | @Override |
| 171 | @Transactional(rollbackFor = Exception.class) | 213 | @Transactional(rollbackFor = Exception.class) |
| 172 | public void cancelTransfer(Long id) { | 214 | public void cancelTransfer(Long id) { |