package com.chinaztt.mes.quality.utils; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.BooleanUtil; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.chinaztt.mes.basic.entity.Location; import com.chinaztt.mes.basic.entity.WorkstationLocation; import com.chinaztt.mes.basic.mapper.LocationMapper; import com.chinaztt.mes.basic.mapper.WorkstationLocationMapper; import com.chinaztt.mes.common.numgen.NumberGenerator; import com.chinaztt.mes.quality.dto.DockingIfsConditionActiveDTO; import com.chinaztt.mes.quality.dto.TestReportDockingIfsConditionDTO; import com.chinaztt.mes.quality.entity.Apply; import com.chinaztt.mes.quality.entity.ApplyPart; import com.chinaztt.mes.quality.entity.FinishedProdInspQtyChangeEvent; import com.chinaztt.mes.quality.entity.Report; import com.chinaztt.mes.quality.mapper.ApplyPartMapper; import com.chinaztt.mes.quality.mapper.FinishedProdInspQtyChangeEventMapper; import com.chinaztt.mes.quality.mapper.QualityMainIfsReportMapper; import com.chinaztt.mes.quality.mapper.ReportMapper; import com.chinaztt.mes.quality.service.impl.ApplyPartServiceImpl; import com.chinaztt.mes.warehouse.entity.Stock; import com.chinaztt.mes.warehouse.mapper.StockMapper; import com.chinaztt.mes.warehouse.util.StockUtils; import com.chinaztt.mes.warehouse.util.TransactionType; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashSet; import java.util.List; /** * @Author: cxf * @Date: 2021/06/01 16:00 */ @Service @AllArgsConstructor public class ReportUtils { private NumberGenerator reportNumberGenerator; private ReportMapper reportMapper; private WorkstationLocationMapper workstationLocationMapper; private LocationMapper locationMapper; private QualityMainIfsReportMapper qualityMainIfsReportMapper; private ApplyPartMapper applyPartMapper; private StockUtils stockUtils; private StockMapper stockMapper; private FinishedProdInspQtyChangeEventMapper finishedProdInspQtyChangeEventMapper; public void checkReportNo(Report report) { if (StringUtils.isBlank(report.getReportNo())) { // 1. 自动生成编号 report.setReportNo(reportNumberGenerator.generateNumberWithPrefix(Report.DIGIT, Report.PREFIX, Report::getReportNo)); } // 2.判断是否重复(无论是自定义的编号,还是自动生成的编号都需经过编号校重) List repeatNos = reportMapper.selectList(Wrappers.query().lambda().eq(Report::getReportNo, report.getReportNo()).ne(Report::getId, report.getId())); if (CollectionUtil.isNotEmpty(repeatNos)) { throw new RuntimeException("编号重复"); } } /** * 根据产出明细系统编号判断产出对应的工序是否是最后一道工序 * @param systemNo 产出明细系统编号 * @return true:是最后一道工序;false:非最后一道工序 */ public Boolean isProdOutLastOperationBySystemNo(String systemNo){ List booleanList = reportMapper.isProdOutLastOperationBySystemNo(systemNo); if(CollectionUtil.isEmpty(booleanList)){ throw new RuntimeException("根据产出系统编号=" + systemNo + "->缺少关联条件->无法判断是否是最后一道工序的产出"); }else if(booleanList.size() > 1){ throw new RuntimeException("根据产出系统编号=" + systemNo + "查询出多个工艺工序关系"); }else{ return booleanList.get(0); } } /** * 根据产出系统编号查询工单对应的ifs合格品接收库位 * @param systemNo * @return */ public String getIfsLocationArrivedBySystemNo(String systemNo){ Long mesLocId = workstationLocationMapper.selectQualifiedLocationIdBySystemNo(systemNo); if(mesLocId == null){ throw new RuntimeException("产出系统号=" + systemNo + "->对应工单无合格品库位id信息"); } Location location = locationMapper.selectById(mesLocId); if(StringUtils.isBlank(location.getIfsLocation())){ throw new RuntimeException("该工单对应的合格库位未匹配ifs库位"); }else{ return location.getIfsLocation(); } } /** * 根据产出系统编号、汇报材料id获取检测汇报对接ifs条件结果 * @param systemNo 产出系统编号 * @param applyPartId 汇报材料id * @return */ public TestReportDockingIfsConditionDTO getDockingIfsCondition(String systemNo,Long applyPartId){ if(StringUtils.isBlank(systemNo)){ throw new RuntimeException("根据产出系统编号获取对接ifs总条件结果状态->系统编号传参为空"); } //1.报检类型为产出报检 //2.汇报类型为非成品检&&非批次首检&&非首检&&非erp报检 //3.产出物料需要检测 //4.产出物料不是虚拟件 //5.产出工序是工艺路线中最后一道工序 DockingIfsConditionActiveDTO dockingIfsConditionActiveDTO = reportMapper.getDockingIfsConditionActive(applyPartId); if(dockingIfsConditionActiveDTO == null){ throw new RuntimeException("根据产出系统编号获取对接ifs总条件结果状态->数据异常->无法获取结果"); } if(dockingIfsConditionActiveDTO.getPlanningMethod() == null || dockingIfsConditionActiveDTO.getReportType() == null){ throw new RuntimeException("根据产出系统编号获取对接ifs总条件结果状态->数据异常->无法获取检测汇报类型||无法获取零件计划方法"); } TestReportDockingIfsConditionDTO testReportDockingIfsConditionDTO = new TestReportDockingIfsConditionDTO(); // 找出所有检测规则 List rules = applyPartMapper.selectTestRulesBySystemNo(systemNo); // 如果单独做成品检 if (rules.size() == 1 && dockingIfsConditionActiveDTO.getReportType().equals(Apply.PRODUCT_APPLY)) { // 获取是否为工序库存 List operationStockStatus = applyPartMapper.selectStockOperationStatus(systemNo); // 如果是工序库存,不进行对接 if (CollectionUtil.isNotEmpty(operationStockStatus) && BooleanUtil.isFalse(operationStockStatus.get(0))) { dockingIfsConditionActiveDTO.setMainSwitch(true); } else { dockingIfsConditionActiveDTO.setMainSwitch(false); } } else if(!dockingIfsConditionActiveDTO.getIsErp() && dockingIfsConditionActiveDTO.getInspection() && dockingIfsConditionActiveDTO.getIsLast()){ if(dockingIfsConditionActiveDTO.getPlanningMethod().equals("K") || dockingIfsConditionActiveDTO.getPlanningMethod().equals("P")){ dockingIfsConditionActiveDTO.setMainSwitch(false); }else if(dockingIfsConditionActiveDTO.getReportType().equals("00outputfirst")|| dockingIfsConditionActiveDTO.getReportType().equals("03erp")|| dockingIfsConditionActiveDTO.getReportType().equals("06finishedproduct")|| dockingIfsConditionActiveDTO.getReportType().equals("07batchfirst")){ dockingIfsConditionActiveDTO.setMainSwitch(false); }else{ dockingIfsConditionActiveDTO.setMainSwitch(true); } } else{ dockingIfsConditionActiveDTO.setMainSwitch(false); } if(dockingIfsConditionActiveDTO.getMainSwitch() && !dockingIfsConditionActiveDTO.getProdOutIfsSync()){ testReportDockingIfsConditionDTO.setIsShopOrderRec(true);//需要对接ifs车间订单接收 } if(dockingIfsConditionActiveDTO.getMainSwitch() && dockingIfsConditionActiveDTO.getProdOutIfsSync()){ testReportDockingIfsConditionDTO.setIsShopOrderCancelRec(true);//需要对接ifs车间订单取消接收 } if(false){//取消通过工序报工关系对应表记录是否存在判断工序报工开关状态,改为直接通过总开关及车间订单中是否工序报工字段状态判断 if(dockingIfsConditionActiveDTO.getMainSwitch() && !qualityMainIfsReportMapper.isAlReportOperationBySystemNo(applyPartId) && dockingIfsConditionActiveDTO.getIsReportOperation()){ testReportDockingIfsConditionDTO.setIsReportOperation(true);//需要对接ifs工序报工 } if(dockingIfsConditionActiveDTO.getMainSwitch() && qualityMainIfsReportMapper.isAlReportOperationBySystemNo(applyPartId) && dockingIfsConditionActiveDTO.getIsReportOperation()){ testReportDockingIfsConditionDTO.setIsCancelReportOperation(true);//需要对接ifs取消工序报工 } } if(dockingIfsConditionActiveDTO.getMainSwitch() && dockingIfsConditionActiveDTO.getIsReportOperation()){ testReportDockingIfsConditionDTO.setIsReportOperation(true);//需要对接ifs工序报工 testReportDockingIfsConditionDTO.setIsCancelReportOperation(true);//需要对接ifs取消工序报工 } return testReportDockingIfsConditionDTO;//返回封装好的条件结果 } /** * 根据产出系统编号、汇报材料id获取检测汇报对接ifs条件结果 * @param systemNo 产出系统编号 * @param applyPartId 汇报材料id * @return */ public TestReportDockingIfsConditionDTO getDockingIfsConditionV2(String systemNo,Long applyPartId){ if(StringUtils.isBlank(systemNo)){ throw new RuntimeException("根据产出系统编号获取对接ifs总条件结果状态->系统编号传参为空"); } //1.报检类型为产出报检 //2.汇报类型为非成品检&&非批次首检&&非首检&&非erp报检 //3.产出物料需要检测 //4.产出物料不是虚拟件 //5.产出工序是工艺路线中最后一道工序 DockingIfsConditionActiveDTO dockingIfsConditionActiveDTO = reportMapper.getDockingIfsConditionActive(applyPartId); if(dockingIfsConditionActiveDTO == null){ throw new RuntimeException("根据产出系统编号获取对接ifs总条件结果状态->数据异常->无法获取结果"); } if(dockingIfsConditionActiveDTO.getPlanningMethod() == null || dockingIfsConditionActiveDTO.getReportType() == null){ throw new RuntimeException("根据产出系统编号获取对接ifs总条件结果状态->数据异常->无法获取检测汇报类型||无法获取零件计划方法"); } TestReportDockingIfsConditionDTO testReportDockingIfsConditionDTO = new TestReportDockingIfsConditionDTO(); // 找出所有检测规则 List rules = applyPartMapper.selectTestRulesBySystemNo(systemNo); // 如果单独做成品检 if (rules.size() == 1 && dockingIfsConditionActiveDTO.getReportType().equals(Apply.PRODUCT_APPLY)) { // 获取是否为工序库存 List operationStockStatus = applyPartMapper.selectStockOperationStatus(systemNo); // 如果是工序库存,不进行对接 if (CollectionUtil.isNotEmpty(operationStockStatus) && BooleanUtil.isFalse(operationStockStatus.get(0))) { dockingIfsConditionActiveDTO.setMainSwitch(true); } else { dockingIfsConditionActiveDTO.setMainSwitch(false); } } else if(!dockingIfsConditionActiveDTO.getIsErp() && dockingIfsConditionActiveDTO.getInspection() && dockingIfsConditionActiveDTO.getIsLast()){ if(dockingIfsConditionActiveDTO.getPlanningMethod().equals("K") || dockingIfsConditionActiveDTO.getPlanningMethod().equals("P")){ dockingIfsConditionActiveDTO.setMainSwitch(false); }else if(dockingIfsConditionActiveDTO.getReportType().equals("00outputfirst")|| dockingIfsConditionActiveDTO.getReportType().equals("03erp")|| dockingIfsConditionActiveDTO.getReportType().equals("07batchfirst")){ dockingIfsConditionActiveDTO.setMainSwitch(false); }else{ dockingIfsConditionActiveDTO.setMainSwitch(true); } } else{ dockingIfsConditionActiveDTO.setMainSwitch(false); } if(dockingIfsConditionActiveDTO.getMainSwitch() && !dockingIfsConditionActiveDTO.getProdOutIfsSync()){ testReportDockingIfsConditionDTO.setIsShopOrderRec(true);//需要对接ifs车间订单接收 } if(dockingIfsConditionActiveDTO.getMainSwitch() && dockingIfsConditionActiveDTO.getProdOutIfsSync()){ testReportDockingIfsConditionDTO.setIsShopOrderCancelRec(true);//需要对接ifs车间订单取消接收 } if(false){//取消通过工序报工关系对应表记录是否存在判断工序报工开关状态,改为直接通过总开关及车间订单中是否工序报工字段状态判断 if(dockingIfsConditionActiveDTO.getMainSwitch() && !qualityMainIfsReportMapper.isAlReportOperationBySystemNo(applyPartId) && dockingIfsConditionActiveDTO.getIsReportOperation()){ testReportDockingIfsConditionDTO.setIsReportOperation(true);//需要对接ifs工序报工 } if(dockingIfsConditionActiveDTO.getMainSwitch() && qualityMainIfsReportMapper.isAlReportOperationBySystemNo(applyPartId) && dockingIfsConditionActiveDTO.getIsReportOperation()){ testReportDockingIfsConditionDTO.setIsCancelReportOperation(true);//需要对接ifs取消工序报工 } } if(dockingIfsConditionActiveDTO.getMainSwitch() && dockingIfsConditionActiveDTO.getIsReportOperation()){ testReportDockingIfsConditionDTO.setIsReportOperation(true);//需要对接ifs工序报工 testReportDockingIfsConditionDTO.setIsCancelReportOperation(true);//需要对接ifs取消工序报工 } return testReportDockingIfsConditionDTO;//返回封装好的条件结果 } /** * 根据产出系统唯一编号移库(针对成品检) * @param systemNo 产出系统编号 * @param lotBatchNo 批次号 * @param qtyArrived 合格数量 * @param unqualifiedArrived 不合格数量 * @param dir 业务类型码 * @param reportId 检测汇报id * @param applyPartId 汇报材料id */ public void autoMoveStockFinishedProduct(String systemNo, String lotBatchNo, BigDecimal qtyArrived, BigDecimal unqualifiedArrived, BigDecimal scrapArrived, String dir, Long reportId,Long applyPartId,Long replacePartId){ //根据系统唯一编号查出零件id Long partId = applyPartMapper.selectPartIdBySystemNo(systemNo); if (partId == null) { throw new RuntimeException("移库对象零件查无零件基础数据"); } //根据产出系统唯一编号查出对应工作站的库位 Long inspectionLocationId = workstationLocationMapper.selectBySystemNo(systemNo, WorkstationLocation.INSPECTION_LOCATION);//产出待检库位 Long disqualifiedLocationId = workstationLocationMapper.selectBySystemNo(systemNo, WorkstationLocation.DISQUALIFIED_LOCATION);//产出不合格品库位 //Long qualifiedLocationId = workstationLocationMapper.selectBySystemNo(systemNo, WorkstationLocation.QUALIFIED_LOCATION); // 获取成品待检库位 Long toQualifiedLocationId = workstationLocationMapper.selectFinishToQualifiedLocationIdBySystemNo(systemNo); //合格库位取工单中库位(一个工作站可能会配置多个合格品库位) Long qualifiedLocationId = workstationLocationMapper.selectQualifiedLocationIdBySystemNo(systemNo);//合格品库位 if (inspectionLocationId != null && disqualifiedLocationId != null && qualifiedLocationId != null) { //判断合格数量是否变更 BigDecimal qtyChange = BigDecimal.ZERO; if (toQualifiedLocationId != null) { qtyChange =getQtyArrivedChange(partId, toQualifiedLocationId, systemNo, lotBatchNo, qtyArrived, dir, reportId, applyPartId); }else { qtyChange =getQtyArrivedChange(partId, qualifiedLocationId, systemNo, lotBatchNo, qtyArrived, dir, reportId, applyPartId); } switch(qtyChange.compareTo(BigDecimal.ZERO)){ case 0: // 合格数量没有变化,且配置了待检成品库,则移到合格库 if (null != toQualifiedLocationId) { if (org.apache.commons.lang3.StringUtils.equals(dir, ApplyPartServiceImpl.MOVELIBRARY)) { if (replacePartId != null) { stockUtils.replaceMove(partId, systemNo, lotBatchNo, qtyArrived, toQualifiedLocationId, qualifiedLocationId, replacePartId); } else { stockUtils.localMove(partId, systemNo, lotBatchNo, qtyArrived, toQualifiedLocationId, qualifiedLocationId); } } else { if (replacePartId != null) { stockUtils.replaceMove(replacePartId, systemNo, lotBatchNo, qtyArrived, qualifiedLocationId, toQualifiedLocationId, partId); } else { stockUtils.localMove(partId, systemNo, lotBatchNo, qtyArrived, qualifiedLocationId, toQualifiedLocationId); } } } break;//合格数量没有变更 case 1: //将变更的数量有合格品库位移至不合格品库位 //合格数量变少 case -1: FinishedProdInspQtyChangeEvent finishedProdInspQtyChangeEvent = new FinishedProdInspQtyChangeEvent(); //合格数量变多 if(dir.equals(ApplyPartServiceImpl.MOVELIBRARY)){ if (null != toQualifiedLocationId) { // 配置了待检成品库,合格数量发生变化,发生变化的数量为不合格数量,移入不合格库;剩余数量为合格数量,移入合格库 if (replacePartId != null) { stockUtils.replaceMove(replacePartId, systemNo, lotBatchNo, qtyChange, toQualifiedLocationId, disqualifiedLocationId, partId); } else { stockUtils.localMove(partId, systemNo, lotBatchNo, qtyChange, toQualifiedLocationId, disqualifiedLocationId); } // 有合格数量 if (qtyArrived.compareTo(BigDecimal.ZERO) != 0) { stockUtils.localMove(partId, systemNo, lotBatchNo, qtyArrived, toQualifiedLocationId, qualifiedLocationId); finishedProdInspQtyChangeEvent.setReportId(reportId); finishedProdInspQtyChangeEvent.setApplyPartId(applyPartId); finishedProdInspQtyChangeEvent.setSystemNo(systemNo); finishedProdInspQtyChangeEvent.setQtyChange(qtyArrived); finishedProdInspQtyChangeEventMapper.insert(finishedProdInspQtyChangeEvent); } } else { //将变更的数量由合格品库位移至不合格品库位 if (replacePartId != null) { stockUtils.replaceMove(partId, systemNo, lotBatchNo, qtyChange, qualifiedLocationId, disqualifiedLocationId, replacePartId); } else { stockUtils.localMove(partId, systemNo, lotBatchNo, qtyChange, qualifiedLocationId, disqualifiedLocationId); } } //创建合格数量变更事件记录 finishedProdInspQtyChangeEvent.setReportId(reportId); finishedProdInspQtyChangeEvent.setApplyPartId(applyPartId); finishedProdInspQtyChangeEvent.setSystemNo(systemNo); finishedProdInspQtyChangeEvent.setQtyChange(qtyChange); finishedProdInspQtyChangeEventMapper.insert(finishedProdInspQtyChangeEvent); }else if(dir.equals(ApplyPartServiceImpl.UNMOVELIBRARY)){ // 配置了待检成品库,将原来提交时,移入合格库位和不合格库位的数量还原到待检成品库 if (null != toQualifiedLocationId) { if (replacePartId != null) { stockUtils.replaceMove(replacePartId, systemNo, lotBatchNo, qtyChange, disqualifiedLocationId, toQualifiedLocationId, partId); } else { stockUtils.localMove(partId, systemNo, lotBatchNo, qtyChange, disqualifiedLocationId, toQualifiedLocationId); } if (qtyArrived.compareTo(BigDecimal.ZERO) != 0) { if (replacePartId != null) { stockUtils.replaceMove(replacePartId, systemNo, lotBatchNo, qtyArrived, qualifiedLocationId, toQualifiedLocationId, partId); } else { stockUtils.localMove(partId, systemNo, lotBatchNo, qtyArrived, qualifiedLocationId, toQualifiedLocationId); } } }else { //将变更的数量由不合格品库位移至合格品库位 if (replacePartId != null) { stockUtils.replaceMove(replacePartId, systemNo, lotBatchNo, qtyChange, disqualifiedLocationId, qualifiedLocationId, partId); } else { stockUtils.localMove(partId, systemNo, lotBatchNo, qtyChange, disqualifiedLocationId, qualifiedLocationId); } } //删除合格数量变更事件记录 finishedProdInspQtyChangeEventMapper.delByGroupUniqueKey(reportId,applyPartId,systemNo); }else{ throw new RuntimeException("移库方向码异常->异常码=" + dir); } break; default: throw new RuntimeException("成品检移库->合格数量变更值与0比较发生异常"); } } } public void autoMoveStockFinishedProductV2(ApplyPart applyPart, String dir){ //根据系统唯一编号查出零件id Long partId = applyPart.getPartId(); if (partId == null) { throw new RuntimeException("移库对象零件查无零件基础数据"); } //根据产出系统唯一编号查出对应工作站的库位 Long inspectionLocationId = workstationLocationMapper.selectBySystemNo(applyPart.getSystemNo(), WorkstationLocation.INSPECTION_LOCATION);//产出待检库位 Long disqualifiedLocationId = workstationLocationMapper.selectBySystemNo(applyPart.getSystemNo(), WorkstationLocation.DISQUALIFIED_LOCATION);//产出不合格品库位 //Long qualifiedLocationId = workstationLocationMapper.selectBySystemNo(systemNo, WorkstationLocation.QUALIFIED_LOCATION); // 获取成品待检库位 Long toQualifiedLocationId = workstationLocationMapper.selectFinishToQualifiedLocationIdBySystemNo(applyPart.getSystemNo()); //合格库位取工单中库位(一个工作站可能会配置多个合格品库位) Long qualifiedLocationId = workstationLocationMapper.selectQualifiedLocationIdBySystemNo(applyPart.getSystemNo());//合格品库 // 如果存在源库位则使用源库位 if (applyPart.getSourceLocationId() != null) { toQualifiedLocationId = applyPart.getSourceLocationId(); disqualifiedLocationId = applyPart.getTargetUnqualifiedLocationId() == null ? -1 : applyPart.getTargetUnqualifiedLocationId(); qualifiedLocationId = applyPart.getTargetQualifiedLocationId() == null ? -1 : applyPart.getTargetQualifiedLocationId(); } if (toQualifiedLocationId != null && disqualifiedLocationId != null && qualifiedLocationId != null) { if(dir.equals(ApplyPartServiceImpl.MOVELIBRARY)){ // 待检移合格 if (new BigDecimal(applyPart.getQtyArrived()).compareTo(BigDecimal.ZERO) == 1) { // 如果有替代件,则替代件移库 if (applyPart.getReplacePartId() != null) { stockUtils.replaceMove(partId, applyPart.getSystemNo(), applyPart.getLotBatchNo(), new BigDecimal(applyPart.getQtyArrived()), toQualifiedLocationId, qualifiedLocationId, applyPart.getReplacePartId()); } else { stockUtils.localMove(partId, applyPart.getSystemNo(), applyPart.getLotBatchNo(), new BigDecimal(applyPart.getQtyArrived()), toQualifiedLocationId, qualifiedLocationId); } } // 待检移不合格 if (new BigDecimal(applyPart.getUnqualifiedArrived()).compareTo(BigDecimal.ZERO) == 1) { if (applyPart.getReplacePartId() != null) { stockUtils.replaceMove(partId, applyPart.getSystemNo(), applyPart.getLotBatchNo(), new BigDecimal(applyPart.getUnqualifiedArrived()), toQualifiedLocationId, disqualifiedLocationId, applyPart.getReplacePartId()); } else { stockUtils.localMove(partId, applyPart.getSystemNo(), applyPart.getLotBatchNo(), new BigDecimal(applyPart.getUnqualifiedArrived()), toQualifiedLocationId, disqualifiedLocationId); } } // 报废库存发放 if (applyPart.getScrapArrived() != null && applyPart.getScrapArrived().compareTo(BigDecimal.ZERO) > 0) { Stock stock = stockMapper.selectOne(Wrappers.lambdaQuery().eq(Stock::getPartId, partId) .eq(Stock::getLocationId,toQualifiedLocationId) .eq(Stock::getPartBatchNo,applyPart.getLotBatchNo()) .eq(Stock::getSystemNo,applyPart.getSystemNo())); stockUtils.updateById(stock.getId(), applyPart.getScrapArrived().negate(), BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, null, TransactionType.SCRAP.getValue()); } }else if(dir.equals(ApplyPartServiceImpl.UNMOVELIBRARY)){ // 合格移待检 if (new BigDecimal(applyPart.getQtyArrived()).compareTo(BigDecimal.ZERO) == 1) { if (applyPart.getReplacePartId() != null) { stockUtils.replaceMove(applyPart.getReplacePartId(), applyPart.getSystemNo(), applyPart.getLotBatchNo(), new BigDecimal(applyPart.getQtyArrived()), qualifiedLocationId, toQualifiedLocationId, partId); } else { stockUtils.localMove(partId, applyPart.getSystemNo(), applyPart.getLotBatchNo(), new BigDecimal(applyPart.getQtyArrived()), qualifiedLocationId, toQualifiedLocationId); } } // 不合格移待检 if (new BigDecimal(applyPart.getUnqualifiedArrived()).compareTo(BigDecimal.ZERO) == 1) { if (applyPart.getReplacePartId() != null) { stockUtils.replaceMove(applyPart.getReplacePartId(), applyPart.getSystemNo(), applyPart.getLotBatchNo(), new BigDecimal(applyPart.getUnqualifiedArrived()), disqualifiedLocationId, toQualifiedLocationId, partId); } else { stockUtils.localMove(partId, applyPart.getSystemNo(), applyPart.getLotBatchNo(), new BigDecimal(applyPart.getUnqualifiedArrived()), disqualifiedLocationId, toQualifiedLocationId); } } // 报废库存撤回 if (applyPart.getScrapArrived() != null && applyPart.getScrapArrived().compareTo(BigDecimal.ZERO) > 0) { Stock stock = stockMapper.selectOne(Wrappers.lambdaQuery().eq(Stock::getPartId, partId) .eq(Stock::getLocationId,toQualifiedLocationId) .eq(Stock::getPartBatchNo,applyPart.getLotBatchNo()) .eq(Stock::getSystemNo,applyPart.getSystemNo())); stockUtils.updateById(stock.getId(), applyPart.getScrapArrived(), BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, null, TransactionType.CANCEL_SCRAP.getValue()); } }else{ throw new RuntimeException("移库方向码异常!异常码--" + dir); } } else { throw new RuntimeException("移库对象零件查无工作站库位缺失"); } } /** * 获取合格数量在成品检及非成品检中的改变量 * @param partId 零件id * @param qualifiedLocationId 合格品库位id * @param systemNo 产出系统编号 * @param lotBatchNo 产出批次号 * @param qtyArrived 当前检测合格数量 * @param dir 业务类别代码 * @param reportId 检测汇报id * @param applyPartId 汇报材料id * @return 返回当前库存中合格数量-当前检测中合格数量差 */ public BigDecimal getQtyArrivedChange(Long partId,Long qualifiedLocationId, String systemNo, String lotBatchNo, BigDecimal qtyArrived, String dir,Long reportId,Long applyPartId){ if(dir.equals(ApplyPartServiceImpl.MOVELIBRARY)){ List stockList = stockMapper.selectList(Wrappers.lambdaQuery().eq(Stock::getPartId,partId).eq(Stock::getSystemNo,systemNo).eq(Stock::getPartBatchNo,lotBatchNo).eq(Stock::getLocationId,qualifiedLocationId)); if(stockList.size() == 0){ throw new RuntimeException("成品检移库->产出系统编号=" + systemNo + "->移库对象不存在"); }else if(stockList.size() > 1){ throw new RuntimeException("成品检移库->零件id=" + partId + "->产出系统号=" + systemNo + "->批次号=" + lotBatchNo + "->库位id=" + qualifiedLocationId + "->唯一键重复"); }else{ return stockList.get(0).getStockQuantity().subtract(qtyArrived);//返回合格数量变更数量 } }else if(dir.equals(ApplyPartServiceImpl.UNMOVELIBRARY)){ //库存表在正向操作时已经被校正,逆向不能拿本身跟本身去比较差异,需要通过校正事件记录表中的数据去多校正进行逆向操作 List finishedProdInspQtyChangeEventList = finishedProdInspQtyChangeEventMapper.selectList(Wrappers.lambdaQuery().eq(FinishedProdInspQtyChangeEvent::getReportId,reportId).eq(FinishedProdInspQtyChangeEvent::getApplyPartId,applyPartId).eq(FinishedProdInspQtyChangeEvent::getSystemNo,systemNo)); if(CollectionUtils.isEmpty(finishedProdInspQtyChangeEventList)){ return BigDecimal.ZERO; }else if(finishedProdInspQtyChangeEventList.size() > 1){ throw new RuntimeException("数据异常->成品检合格数量改变事件记录表数据重复"); }else{ return finishedProdInspQtyChangeEventList.get(0).getQtyChange();//返回合格数量变更数量 } }else{ throw new RuntimeException("移库业务类别码=" + dir + "->非法"); } } /** * 根据检测汇报id校验汇报明细的工序是否一致 * @param reportId 检测汇报id */ public void checkOperationNoIsSame(Long reportId){ if(null != reportId){ List applyPartList = applyPartMapper.selectListByReportId(reportId); HashSet operationNos = new HashSet<>(); if(CollectionUtils.isNotEmpty(applyPartList)){ for(ApplyPart applyPart : applyPartList){ operationNos.add(applyPartMapper.selectOperationNoBySystemNo(applyPart.getSystemNo())); } if(null == operationNos){ throw new RuntimeException("系统数据异常 -> 工序编号获取失败"); }else if(operationNos.size() != 1){ throw new RuntimeException("汇报零件工序不一致 -> " + operationNos.toString()); } // 增加校验检测规则是否一致 List testRules = new ArrayList<>(); for(ApplyPart applyPart : applyPartList){ List rules = applyPartMapper.selectTestRulesBySystemNo(applyPart.getSystemNo()); if(CollectionUtils.isEmpty(testRules)){ testRules.addAll(rules); } if(!testRules.containsAll(rules)){ throw new RuntimeException("汇报零件检测规则不一致"); } } } } } }