| | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock.MesWmMaterialStockFreezeClaimMapper; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO; |
| | |
| | | |
| | | @Resource |
| | | private MesWmMaterialStockMapper materialStockMapper; |
| | | @Resource |
| | | private MesWmMaterialStockFreezeClaimMapper freezeClaimMapper; |
| | | |
| | | @Resource |
| | | private MesMdmItemService mdmItemService; |
| | |
| | | MesMdItemDO item = mdItemService.getItem(pageReqVO.getItemId()); |
| | | if (item != null && item.getMdmItemId() != null) { |
| | | itemIds = SetUtils.asSet(item.getMdmItemId()); |
| | | } else { |
| | | return PageResult.empty(); |
| | | } |
| | | } |
| | | // 1.3 解析 virtualFilter:转换为虚拟仓 warehouseId |
| | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateMaterialStockFrozen(MesWmMaterialStockFreezeReqVO updateReqVO) { |
| | | // 校验存在 |
| | | validateMaterialStockExists(updateReqVO.getId()); |
| | | |
| | | // 更新冻结状态 |
| | | materialStockMapper.updateById(new MesWmMaterialStockDO() |
| | | .setId(updateReqVO.getId()).setFrozen(updateReqVO.getFrozen())); |
| | | setMaterialStockFreeze(List.of(updateReqVO.getId()), "MANUAL", 0L, updateReqVO.getFrozen()); |
| | | } |
| | | |
| | | @Override |
| | | public void updateMaterialStockFrozen(Collection<Long> ids, boolean frozen) { |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void setMaterialStockFreeze(Collection<Long> ids, String sourceType, Long sourceId, boolean frozen) { |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return; |
| | | } |
| | | materialStockMapper.updateByIds(ids, new MesWmMaterialStockDO().setFrozen(frozen)); |
| | | // 按 ID 固定顺序加锁,避免两个任务同时冻结相同库存时产生锁顺序反转。 |
| | | for (Long stockId : ids.stream().filter(Objects::nonNull).distinct().sorted().toList()) { |
| | | MesWmMaterialStockDO stock = materialStockMapper.lockById(stockId); |
| | | if (stock == null) { |
| | | throw exception(WM_MATERIAL_STOCK_NOT_EXISTS); |
| | | } |
| | | if (frozen) { |
| | | freezeClaimMapper.acquire(stockId, sourceType, sourceId); |
| | | } else { |
| | | freezeClaimMapper.release(stockId, sourceType, sourceId); |
| | | } |
| | | boolean effectiveFrozen = freezeClaimMapper.countByStockId(stockId) > 0; |
| | | if (!Objects.equals(stock.getFrozen(), effectiveFrozen)) { |
| | | materialStockMapper.updateById(new MesWmMaterialStockDO() |
| | | .setId(stockId).setFrozen(effectiveFrozen)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | |
| | | } else { |
| | | // 出库时校验批次存在 |
| | | if (batchId != null) { |
| | | batchService.validateBatchExists(batchId, reqVO.getItemId()); |
| | | batchCode = batchService.validateBatchExists(batchId, reqVO.getItemId()).getCode(); |
| | | } |
| | | } |
| | | |
| | |
| | | * @return 批次记录(物料未启用批次管理时返回 null) |
| | | */ |
| | | private MesWmBatchDO resolveBatch(MesWmMaterialStockAdjustReqVO reqVO, MesMdmItemDO item) { |
| | | // 1. 物料未启用批次管理,返回 null |
| | | if (Boolean.FALSE.equals(item.getIsBatchManaged())) { |
| | | return null; |
| | | // 即使物料未启用普通批次管理,也要保留并校验盘号追溯批次。 |
| | | if (reqVO.getBatchId() != null) { |
| | | MesWmBatchDO existing = batchService.validateBatchExists(reqVO.getBatchId(), reqVO.getItemId()); |
| | | if (StrUtil.isNotBlank(reqVO.getReelNo()) |
| | | && !Objects.equals(StrUtil.trim(reqVO.getReelNo()), StrUtil.trim(existing.getReelNo()))) { |
| | | throw exception(WM_BATCH_REEL_MISMATCH); |
| | | } |
| | | return existing; |
| | | } |
| | | |
| | | // 2. 传入 batchId,校验并返回已有批次 |
| | | if (reqVO.getBatchId() != null) { |
| | | return batchService.validateBatchExists(reqVO.getBatchId(), reqVO.getItemId()); |
| | | // 1. 未指定追溯批次且物料未启用批次管理,返回 null |
| | | if (Boolean.FALSE.equals(item.getIsBatchManaged()) && StrUtil.isBlank(reqVO.getReelNo())) { |
| | | return null; |
| | | } |
| | | |
| | | // 3. 未传 batchId,自动创建批次 |
| | | MesWmBatchGenerateReqVO batchReqVO = new MesWmBatchGenerateReqVO() |
| | | .setItemId(reqVO.getItemId()) |
| | | .setBatchCode(reqVO.getBatchCode()) |
| | | .setReelNo(StrUtil.trimToNull(reqVO.getReelNo())) |
| | | .setVendorId(reqVO.getVendorId()) |
| | | .setProduceDate(reqVO.getProduceDate() != null ? reqVO.getProduceDate().atStartOfDay() : null) |
| | | .setExpireDate(reqVO.getExpireDate() != null ? reqVO.getExpireDate().atStartOfDay() : null) |