|
@@ -29,12 +29,14 @@ import cn.iocoder.yudao.module.pms.dal.dataobject.iotmaintenancebom.IotMaintenan
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotmainworkorder.IotMainWorkOrderDO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotmainworkorderbom.IotMainWorkOrderBomDO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotmainworkorderbommaterial.IotMainWorkOrderBomMaterialDO;
|
|
|
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotoutbound.IotOutboundDO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.IotDeviceMapper;
|
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.iotlockstock.IotLockStockMapper;
|
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.iotmaintenancebom.IotMaintenanceBomMapper;
|
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.iotmainworkorder.IotMainWorkOrderMapper;
|
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.iotmainworkorderbom.IotMainWorkOrderBomMapper;
|
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.iotmainworkorderbommaterial.IotMainWorkOrderBomMaterialMapper;
|
|
|
+import cn.iocoder.yudao.module.pms.dal.mysql.iotoutbound.IotOutboundMapper;
|
|
|
import cn.iocoder.yudao.module.pms.dal.redis.BizNoRedisDAO;
|
|
|
import cn.iocoder.yudao.module.pms.service.IotDeviceService;
|
|
|
import cn.iocoder.yudao.module.pms.service.iotdevicerunlog.IotDeviceRunLogService;
|
|
@@ -93,6 +95,8 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
|
|
|
private IotDeviceMapper iotDeviceMapper;
|
|
|
@Resource
|
|
|
private DeptService deptService;
|
|
|
+ @Resource
|
|
|
+ private IotOutboundMapper iotOutboundMapper;
|
|
|
|
|
|
@Override
|
|
|
public Long createIotMainWorkOrder(IotMainWorkOrderSaveReqVO createReqVO) {
|
|
@@ -1241,6 +1245,8 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
|
|
|
Set<Long> storageLocationIds = new HashSet<>();
|
|
|
Set<String> materialCodes = new HashSet<>();
|
|
|
Map<String, BigDecimal> lockStockPair = new HashMap<>();
|
|
|
+ // key工厂id-成本中心id-物料编码-bomId value保养项物料对象
|
|
|
+ Map<String, IotMainWorkOrderBomMaterialSaveReqVO> bomMaterialPair = new HashMap<>();
|
|
|
// 标识保养项是否已经添加了物料
|
|
|
Set<Long> bomNodeIds = new HashSet<>();
|
|
|
AtomicBoolean mainCompleted = new AtomicBoolean(true);
|
|
@@ -1254,7 +1260,7 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
|
|
|
Set<Long> mctBomNodeIds = new HashSet<>();
|
|
|
workOrderMaterials.forEach(material -> {
|
|
|
if (ObjUtil.isEmpty(material.getId())) {
|
|
|
- // 兼容保养工单中部分保养项保养完成 部分保养项 延期保养的情况 这里只新增延期保养 或正常 保养的物料
|
|
|
+ // 兼容保养工单中部分保养项保养完成 部分保养项延期保养的情况 这里只新增延期保养 或 正常保养的物料
|
|
|
IotMainWorkOrderBomMaterialDO tempMaterial = BeanUtils.toBean(material, IotMainWorkOrderBomMaterialDO.class);
|
|
|
tempMaterial.setWorkOrderId(mainWorkOrder.getId());
|
|
|
workOrderBomMaterialDOS.add(tempMaterial);
|
|
@@ -1272,8 +1278,11 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
|
|
|
if (ObjUtil.isNotEmpty(material.getMaterialCode())) {
|
|
|
materialCodes.add(material.getMaterialCode());
|
|
|
}
|
|
|
+ String uniqueKey = StrUtil.join("-", material.getFactoryId(),
|
|
|
+ material.getCostCenterId(), material.getMaterialCode(), material.getBomNodeId());
|
|
|
String tempKey = material.getFactoryId() + String.valueOf(material.getCostCenterId())
|
|
|
+ material.getMaterialCode();
|
|
|
+ // 扣减库存使用 合并不同保养项下的相同物料
|
|
|
if (lockStockPair.containsKey(tempKey)) {
|
|
|
BigDecimal tempQuantity = lockStockPair.get(tempKey);
|
|
|
BigDecimal totalQuantity = tempQuantity.add(material.getQuantity());
|
|
@@ -1281,6 +1290,8 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
|
|
|
} else {
|
|
|
lockStockPair.put(tempKey, material.getQuantity());
|
|
|
}
|
|
|
+ // 记录出库使用 记录保养项id
|
|
|
+ bomMaterialPair.put(uniqueKey, material);
|
|
|
}
|
|
|
}
|
|
|
});
|
|
@@ -1442,12 +1453,13 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
|
|
|
// 如果在填报工单时 填写了 保养项 中的 ‘运行时间周期(H)’ 保存时需要同步到 保养工单 关联的 保养计划的 对应的保养项的 ‘运行时间周期(H)’
|
|
|
// 包含 延时保养 的情况
|
|
|
// 只扣减本地库存 不处理SAP库存
|
|
|
+ // 保养基于单设备 出库时记录 单设备所属的部门id(即保养工单的部门id)
|
|
|
if (CollUtil.isNotEmpty(factoryIds) && CollUtil.isNotEmpty(costCenterIds) && CollUtil.isNotEmpty(materialCodes)) {
|
|
|
IotLockStockPageReqVO reqVO = new IotLockStockPageReqVO();
|
|
|
reqVO.setFactoryIds(factoryIds);
|
|
|
reqVO.setCostCenterIds(costCenterIds);
|
|
|
reqVO.setMaterialCodes(materialCodes);
|
|
|
- processLockStock(reqVO, lockStockPair);
|
|
|
+ processLockStock(reqVO, lockStockPair, updateObj, bomMaterialPair);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1456,23 +1468,54 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
|
|
|
* @param reqVO
|
|
|
* @param lockStockPair
|
|
|
*/
|
|
|
- private void processLockStock(IotLockStockPageReqVO reqVO, Map<String, BigDecimal> lockStockPair){
|
|
|
+ private void processLockStock(IotLockStockPageReqVO reqVO, Map<String, BigDecimal> lockStockPair,
|
|
|
+ IotMainWorkOrderDO workOrder, Map<String, IotMainWorkOrderBomMaterialSaveReqVO> bomMaterialPair) {
|
|
|
List<IotLockStockDO> lockStocks = iotLockStockMapper.selectList(reqVO);
|
|
|
List<IotLockStockDO> tobeUpdatedLockStocks = new ArrayList<>();
|
|
|
+ List<IotOutboundDO> outbounds = new ArrayList<>();
|
|
|
if (CollUtil.isNotEmpty(lockStocks)) {
|
|
|
lockStocks.forEach(lockStock -> {
|
|
|
String tempKey = lockStock.getFactoryId() + String.valueOf(lockStock.getCostCenterId())
|
|
|
+ lockStock.getMaterialCode();
|
|
|
+ BigDecimal outQuantity = lockStockPair.get(tempKey);
|
|
|
if (lockStockPair.containsKey(tempKey)) {
|
|
|
- lockStock.setQuantity(lockStock.getQuantity().subtract(lockStockPair.get(tempKey)));
|
|
|
+ lockStock.setQuantity(lockStock.getQuantity().subtract(outQuantity));
|
|
|
tobeUpdatedLockStocks.add(lockStock);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
+ // 记录出库 最好是保存 保养项id 方便后续统计 数据分析
|
|
|
+ if (CollUtil.isNotEmpty(bomMaterialPair)) {
|
|
|
+ bomMaterialPair.forEach((k,v) -> {
|
|
|
+ // k工厂id-成本中心id-物料编码-bomId
|
|
|
+ // 每个物料都对应一条出库记录
|
|
|
+ IotOutboundDO outbound = new IotOutboundDO();
|
|
|
+ outbound.setDeptId(workOrder.getDeptId());
|
|
|
+ outbound.setFactoryId(v.getFactoryId());
|
|
|
+ outbound.setCostCenterId(v.getCostCenterId());
|
|
|
+ outbound.setBomNodeId(v.getBomNodeId());
|
|
|
+ outbound.setMaterialCode(v.getMaterialCode());
|
|
|
+ outbound.setMaterialName(v.getMaterialName());
|
|
|
+ outbound.setQuantity(v.getQuantity());
|
|
|
+ outbound.setUnitPrice(v.getUnitPrice());
|
|
|
+ outbound.setUnit(v.getUnit());
|
|
|
+ outbound.setType(2);
|
|
|
+ outbound.setDeliveryTime(LocalDateTime.now());
|
|
|
+ outbound.setReason("保养");
|
|
|
+ outbound.setCreator(workOrder.getCreator());
|
|
|
+ outbound.setUpdater(workOrder.getUpdater());
|
|
|
+ outbounds.add(outbound);
|
|
|
+ });
|
|
|
+ }
|
|
|
if (CollUtil.isNotEmpty(tobeUpdatedLockStocks)) {
|
|
|
// 扣减本地库存
|
|
|
iotLockStockMapper.updateBatch(tobeUpdatedLockStocks);
|
|
|
}
|
|
|
+ // 添加出库记录
|
|
|
+ if (CollUtil.isNotEmpty(outbounds)) {
|
|
|
+ iotOutboundMapper.insertBatch(outbounds);
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -1582,7 +1625,10 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
|
|
|
Set<Long> costCenterIds = new HashSet<>();
|
|
|
Set<Long> storageLocationIds = new HashSet<>();
|
|
|
Set<String> materialCodes = new HashSet<>();
|
|
|
+ // key工厂id-成本中心id-物料编码-bomId value物料数量
|
|
|
Map<String, BigDecimal> lockStockPair = new HashMap<>();
|
|
|
+ // key工厂id-成本中心id-物料编码-bomId value保养项物料对象
|
|
|
+ Map<String, IotMainWorkOrderBomMaterialSaveReqVO> bomMaterialPair = new HashMap<>();
|
|
|
workOrderMaterials.forEach(material -> {
|
|
|
IotMainWorkOrderBomMaterialDO tempMaterial = BeanUtils.toBean(material, IotMainWorkOrderBomMaterialDO.class);
|
|
|
tempMaterial.setWorkOrderId(order.getId());
|
|
@@ -1600,8 +1646,11 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
|
|
|
if (ObjUtil.isNotEmpty(material.getMaterialCode())) {
|
|
|
materialCodes.add(material.getMaterialCode());
|
|
|
}
|
|
|
+ // 有可能不同保养项使用了相同的物料 所以扣减本地库存 和 记录出库时 相同的成本中心物料有可能分开出库
|
|
|
+ String uniqueKey = StrUtil.join("-", material.getFactoryId(),
|
|
|
+ material.getCostCenterId(), material.getMaterialCode(), material.getBomNodeId());
|
|
|
String tempKey = material.getFactoryId() + String.valueOf(material.getCostCenterId())
|
|
|
- + material.getMaterialCode();
|
|
|
+ + material.getMaterialCode() + material.getBomNodeId() ;
|
|
|
if (lockStockPair.containsKey(tempKey)) {
|
|
|
BigDecimal tempQuantity = lockStockPair.get(tempKey);
|
|
|
BigDecimal totalQuantity = tempQuantity.add(material.getQuantity());
|
|
@@ -1609,17 +1658,18 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
|
|
|
} else {
|
|
|
lockStockPair.put(tempKey, material.getQuantity());
|
|
|
}
|
|
|
+ // 记录出库 需要保养项id
|
|
|
+ bomMaterialPair.put(uniqueKey, material);
|
|
|
}
|
|
|
});
|
|
|
iotMainWorkOrderBomMaterialMapper.insertBatch(workOrderBomMaterialDOS);
|
|
|
- // 只扣减本地库存 不处理SAP库存
|
|
|
+ // 只扣减本地库存 不处理SAP库存 同时 记录出库
|
|
|
if (CollUtil.isNotEmpty(factoryIds) && CollUtil.isNotEmpty(costCenterIds) && CollUtil.isNotEmpty(materialCodes)) {
|
|
|
IotLockStockPageReqVO reqVO = new IotLockStockPageReqVO();
|
|
|
reqVO.setFactoryIds(factoryIds);
|
|
|
reqVO.setCostCenterIds(costCenterIds);
|
|
|
reqVO.setMaterialCodes(materialCodes);
|
|
|
- processLockStock(reqVO, lockStockPair);
|
|
|
- // 记录出库
|
|
|
+ processLockStock(reqVO, lockStockPair, order, bomMaterialPair);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1816,6 +1866,69 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
|
|
|
return CollUtil.isNotEmpty(workOrderBomS) ? workOrderBomS : new ArrayList<>();
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public void historyWorkOrderOutbound() {
|
|
|
+ // 查询历史已经执行完成的保养工单 将保养工单关联的物料 添加出库记录
|
|
|
+ // 查询已经执行完成的保养工单
|
|
|
+ // 查询保养工单明细 status=1 记录 即查询出所有已经保养完成的保养项 但是保养工单不一定执行完成
|
|
|
+ IotMainWorkOrderBomPageReqVO bomReqVO = new IotMainWorkOrderBomPageReqVO();
|
|
|
+ bomReqVO.setStatus(1);
|
|
|
+ List<IotMainWorkOrderBomDO> workOrderBoms = iotMainWorkOrderBomMapper.selectList(bomReqVO);
|
|
|
+ if (CollUtil.isNotEmpty(workOrderBoms)) {
|
|
|
+ List<IotOutboundDO> outbounds = new ArrayList<>();
|
|
|
+ Set<Long> workOrderIds = new HashSet<>();
|
|
|
+ Set<Long> bomNodeIds = new HashSet<>();
|
|
|
+ workOrderBoms.forEach(bom -> {
|
|
|
+ workOrderIds.add(bom.getWorkOrderId());
|
|
|
+ bomNodeIds.add(bom.getBomNodeId());
|
|
|
+ });
|
|
|
+ if (CollUtil.isNotEmpty(workOrderIds) && CollUtil.isNotEmpty(bomNodeIds)) {
|
|
|
+ // 查询保养工单id
|
|
|
+ IotMainWorkOrderPageReqVO orderReqVO = new IotMainWorkOrderPageReqVO();
|
|
|
+ orderReqVO.setWorkOrderIds(new ArrayList<>(workOrderIds));
|
|
|
+ List<IotMainWorkOrderDO> finishedOrders = iotMainWorkOrderMapper.selectList(orderReqVO);
|
|
|
+ Map<Long, Long> orderDeptPair = new HashMap<>();
|
|
|
+ if (CollUtil.isNotEmpty(finishedOrders)) {
|
|
|
+ finishedOrders.forEach(order -> {
|
|
|
+ orderDeptPair.put(order.getId(), order.getDeptId());
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // 查询保养工单明细关联的所有物料
|
|
|
+ IotMainWorkOrderBomMaterialPageReqVO reqVO = new IotMainWorkOrderBomMaterialPageReqVO();
|
|
|
+ reqVO.setWorkOrderIds(new ArrayList<>(workOrderIds));
|
|
|
+ reqVO.setBomNodeIds(new ArrayList<>(bomNodeIds));
|
|
|
+ List<IotMainWorkOrderBomMaterialDO> bomMaterials = iotMainWorkOrderBomMaterialMapper.selectList(reqVO);
|
|
|
+ if (CollUtil.isNotEmpty(bomMaterials)) {
|
|
|
+ bomMaterials.forEach(material -> {
|
|
|
+ if ("本地库存".equals(material.getMaterialSource())) {
|
|
|
+ IotOutboundDO outbound = new IotOutboundDO();
|
|
|
+ if (orderDeptPair.containsKey(material.getWorkOrderId())) {
|
|
|
+ outbound.setDeptId(orderDeptPair.get(material.getWorkOrderId()));
|
|
|
+ }
|
|
|
+ outbound.setBomNodeId(material.getBomNodeId());
|
|
|
+ outbound.setFactoryId(material.getFactoryId());
|
|
|
+ outbound.setCostCenterId(material.getCostCenterId());
|
|
|
+ outbound.setMaterialCode(material.getMaterialCode());
|
|
|
+ outbound.setMaterialName(material.getMaterialName());
|
|
|
+ outbound.setQuantity(material.getQuantity());
|
|
|
+ outbound.setUnitPrice(material.getUnitPrice());
|
|
|
+ outbound.setUnit(material.getUnit());
|
|
|
+ outbound.setType(2);
|
|
|
+ outbound.setDeliveryTime(LocalDateTime.now());
|
|
|
+ outbound.setReason("保养");
|
|
|
+ outbound.setCreator(material.getCreator());
|
|
|
+ outbound.setUpdater(material.getUpdater());
|
|
|
+ outbounds.add(outbound);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (CollUtil.isNotEmpty(outbounds)) {
|
|
|
+ iotOutboundMapper.insertBatch(outbounds);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private static class Triple<A, B, C> {
|
|
|
private final A first;
|
|
|
private final B second;
|