diff --git a/modules/i3plus-ext-mes-api/src/main/java/cn/estsh/i3plus/ext/mes/api/base/bu/IBuWorkOrderExtService.java b/modules/i3plus-ext-mes-api/src/main/java/cn/estsh/i3plus/ext/mes/api/base/bu/IBuWorkOrderExtService.java index 04ad5b2..b7a562d 100644 --- a/modules/i3plus-ext-mes-api/src/main/java/cn/estsh/i3plus/ext/mes/api/base/bu/IBuWorkOrderExtService.java +++ b/modules/i3plus-ext-mes-api/src/main/java/cn/estsh/i3plus/ext/mes/api/base/bu/IBuWorkOrderExtService.java @@ -3,7 +3,6 @@ package cn.estsh.i3plus.ext.mes.api.base.bu; import cn.estsh.i3plus.ext.mes.pojo.bean.MesUnbindProduceSn; import cn.estsh.i3plus.ext.mes.pojo.bean.MesWorkOrderExt; import cn.estsh.i3plus.ext.mes.pojo.model.*; -import cn.estsh.i3plus.ext.mes.pojo.model.bu3.SxOutPutStatisticsModel; import cn.estsh.i3plus.pojo.base.bean.ListPager; import cn.estsh.i3plus.pojo.base.common.Pager; import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder; diff --git a/modules/i3plus-ext-mes-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/apiservice/serviceimpl/base/bu/BuWorkOrderExtService.java b/modules/i3plus-ext-mes-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/apiservice/serviceimpl/base/bu/BuWorkOrderExtService.java index 310a786..fe89f8e 100644 --- a/modules/i3plus-ext-mes-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/apiservice/serviceimpl/base/bu/BuWorkOrderExtService.java +++ b/modules/i3plus-ext-mes-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/apiservice/serviceimpl/base/bu/BuWorkOrderExtService.java @@ -1,13 +1,19 @@ package cn.estsh.i3plus.ext.mes.apiservice.serviceimpl.base.bu; +import cn.estsh.i3plus.ext.mes.api.base.INumberRuleExtService; import cn.estsh.i3plus.ext.mes.api.base.IProdOrgExtService; import cn.estsh.i3plus.ext.mes.api.base.IShiftExtService; import cn.estsh.i3plus.ext.mes.api.base.ISxMesHttpService; import cn.estsh.i3plus.ext.mes.api.base.bu.IBuWorkOrderExtService; import cn.estsh.i3plus.ext.mes.api.base.bu.IBusiConfigService; +import cn.estsh.i3plus.ext.mes.api.busi.IProductEncodeCfgExtService; +import cn.estsh.i3plus.ext.mes.api.busi.ISxNumberRuleCheckAttributeService; import cn.estsh.i3plus.ext.mes.api.busi.IWorkOrderLogExtService; import cn.estsh.i3plus.ext.mes.api.busi.IWorkOrderStartService; +import cn.estsh.i3plus.ext.mes.api.busi.bu3.ISxPartExtService; import cn.estsh.i3plus.ext.mes.api.busi.bu3.ISxUnbindProduceSnService; +import cn.estsh.i3plus.ext.mes.api.busi.jx.IJxPackageExtService; +import cn.estsh.i3plus.ext.mes.api.busi.jx.IJxProduceSnService; import cn.estsh.i3plus.ext.mes.apiservice.controller.base.EmailPushService; import cn.estsh.i3plus.ext.mes.apiservice.dao.bu3.ISxBuWorkOrderDao; import cn.estsh.i3plus.ext.mes.apiservice.util.SxDateRangeUtils; @@ -20,7 +26,6 @@ import cn.estsh.i3plus.ext.mes.pojo.model.GenerateWorkOrderDto; import cn.estsh.i3plus.ext.mes.pojo.model.WorkOrderPageVo; import cn.estsh.i3plus.ext.mes.pojo.model.WorkOrderQueryDto; import cn.estsh.i3plus.ext.mes.pojo.model.bu3.SxOutPutStatisticsModel; -import cn.estsh.i3plus.ext.mes.pojo.model.ep.EpOutPutStatisticsModel; import cn.estsh.i3plus.ext.mes.pojo.repository.*; import cn.estsh.i3plus.ext.mes.pojo.util.ConvertBeanExt; import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords; @@ -126,6 +131,24 @@ public class BuWorkOrderExtService implements IBuWorkOrderExtService { private IBusiConfigService busiConfigService; @Autowired + private ISxPartExtService partExtService; + + @Autowired + private IJxPackageExtService packageExtService; + + @Autowired + private IProductEncodeCfgExtService productEncodeCfgExtService; + + @Autowired + private INumberRuleExtService numberRuleExtService; + + @Autowired + private IJxProduceSnService produceSnService; + + @Autowired + private ISxNumberRuleCheckAttributeService numberRuleCheckAttributeService; + + @Autowired private ISxMesHttpService httpService; @Resource(name = MesExtConstWords.REDIS_MES) @@ -159,6 +182,15 @@ public class BuWorkOrderExtService implements IBuWorkOrderExtService { private MesUnbindProduceSnTravelRepository unbindProduceSnTravelRepository; @Autowired + private MesReworkOrderBindSnTravelRepository reworkOrderBindSnTravelRepository; + + @Autowired + private MesSubassemblyRemadeRecordRepository subassemblyRemadeRecordRepository; + + @Autowired + private MesProduceSnRepairRepository produceSnRepairRepository; + + @Autowired private ISxBuWorkOrderDao buWorkOrderDao; /** @@ -170,17 +202,592 @@ public class BuWorkOrderExtService implements IBuWorkOrderExtService { @Transactional(rollbackFor = Exception.class) public void insertManualGenerate(GenerateWorkOrderDto workOrderDto) { MesWorkOrderExt mesWorkOrderExt = new MesWorkOrderExt(); - Double qty = workOrderDto.getQty(); - Double planQty = workOrderDto.getPlanQty(); - if(planQty > qty){ - throw new BaseImppException("计划返工数量不能大于计划生产数量"); - } + + checkReworkQty(workOrderDto); + + Object data = checkReworkOrderBindSn(workOrderDto); + BeanUtils.copyProperties(workOrderDto,mesWorkOrderExt); String userName = AuthUtil.getSessionUser().getUserName(); String organizeCode = AuthUtil.getOrganize().getOrganizeCode(); mesWorkOrderExt.setOrderNo(getOrderNo(userName,organizeCode)); mesWorkOrderExt.setWorkOrderSource(MesExtEnumUtil.WORK_ORDER_SOURCE.MANUALLY_GENERATE.getValue()); - addWorkOrder(mesWorkOrderExt); + + doBindSn(workOrderDto, insertNewWorkOrder(mesWorkOrderExt), data); + } + + private MesWorkOrderExt insertNewWorkOrder(MesWorkOrderExt mesWorkOrderExt) { + String organizeCode = AuthUtil.getOrganize().getOrganizeCode(); + Integer workOrderType = mesWorkOrderExt.getWorkOrderType(); + //如果是返工工单 设置是否生成条码为不生成 + if (MesExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue() == workOrderType) { + mesWorkOrderExt.setSnCreateStatus(MesExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.NO_CREATE.getValue()); + } else { + //不是返工工单 + MesPartExt mesPart = partExtRepository.getByProperty( + new String[]{"partNo", "organizeCode", "isValid", "isDeleted"}, + new Object[]{mesWorkOrderExt.getPartNo(), organizeCode, + CommonEnumUtil.IS_VAILD.VAILD.getValue(), + CommonEnumUtil.IS_DEAL.NO.getValue()}); + //判断物料是否需要生成条码 + if (!ObjectUtils.isEmpty(mesPart)) { + Integer isCreateSn = mesPart.getIsCreateSn(); + if (isCreateSn != null && CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue() == isCreateSn) { + mesWorkOrderExt.setSnCreateStatus(MesExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.UN_CREATE.getValue()); + } else { + mesWorkOrderExt.setSnCreateStatus(MesExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.NO_CREATE.getValue()); + } + } + } + boolean havePart = isHavePart(mesWorkOrderExt.getPartNo(), organizeCode); + if (!havePart) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode()) + .setErrorDetail("物料号[%s]不存在", + mesWorkOrderExt.getPartNo()) + .build(); + } + mesWorkOrderExt.setWorkOrderStatus(MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue()); + + mesWorkOrderExt.setOrganizeCode(organizeCode); + + mesWorkOrderExt.setSeq(MathOperation.add(getWorkOrderExtMaxSeq(organizeCode, 1), new Double(1))); + + ConvertBean.modelInitialize(mesWorkOrderExt, AuthUtil.getSessionUser()); + mesWorkOrderExt.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue()); + new ConvertBeanExt(mesWorkOrderExt).convertBean(mesWorkOrderExt); + MesWorkOrderExt workOrderExt = workOrderExtRepository.insert(mesWorkOrderExt); + insertMesWorkOrderLog(workOrderExt); + + return workOrderExt; + } + + private void doBindSn(GenerateWorkOrderDto workOrderDto, MesWorkOrderExt mesWorkOrderExt, Object data) { + + if (data == null) return; + + workOrderDto.setOrderNo(mesWorkOrderExt.getOrderNo()); + + // 10 为成品 + if (workOrderDto.getPartExt().getCategoryCode3().equals("10")) doBindProductSn(mesWorkOrderExt, data); + // 其余都为组件 + else doBindPackage(workOrderDto, workOrderDto.getPartExt()); + + } + + private void doBindProductSn(MesWorkOrderExt mesWorkOrderExt, Object data) { + + List produceSnExtList = (List) data; + + if (CollectionUtils.isEmpty(produceSnExtList)) return; + + List produceSnRepairList = new ArrayList<>(); + List reworkOrderBindSnTravelList = new ArrayList<>(); + List packageExtList = new ArrayList<>(); + + for (MesProduceSnExt produceSnExt : produceSnExtList) { + + ConvertBean.serviceModelUpdate(produceSnExt, mesWorkOrderExt.getModifyUser()); + new ConvertBeanExt(produceSnExt).convertBean(produceSnExt); + produceSnExt.setLastWorkOrderNo(mesWorkOrderExt.getOrderNo()); + produceSnExt.setSnStatus(MesExtEnumUtil.PRODUCE_SN_STATUS.REPAIR.getValue()); + produceSnExt.setRouteCode(null); + produceSnExt.setProcessCode(null); + produceSnExt.setWorkCellCode(null); + produceSnExt.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue()); + new ConvertBeanExt(produceSnExt).convertBean(produceSnExt); + + MesProduceSnRepair produceSnRepair = new MesProduceSnRepair(); + produceSnRepair.setSerialNumber(produceSnExt.getSerialNumber()); + produceSnRepair.setProductSn(produceSnExt.getProductSn()); + produceSnRepair.setPartNo(produceSnExt.getPartNo()); + produceSnRepair.setPartNameRdd(produceSnExt.getPartNameRdd()); + produceSnRepair.setWorkCenterCode(mesWorkOrderExt.getWorkCenterCode()); + produceSnRepair.setWorkOrderNo(mesWorkOrderExt.getOrderNo()); + produceSnRepair.setInitWorkOrderNo(produceSnExt.getLastWorkOrderNo()); + produceSnRepair.setSnType(MesExtEnumUtil.PRODUCE_SN_TYPE.REWORK_SN.getValue()); + produceSnRepair.setOrganizeCode(mesWorkOrderExt.getOrganizeCode()); + ConvertBean.serviceModelInitialize(produceSnRepair, mesWorkOrderExt.getModifyUser()); + produceSnRepair.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue()); + produceSnRepairList.add(produceSnRepair); + + MesReworkOrderBindSnTravel reworkOrderBindSnTravel = new MesReworkOrderBindSnTravel(); + BeanUtils.copyProperties(produceSnRepair, reworkOrderBindSnTravel); + reworkOrderBindSnTravel.setBindStatus(MesExtEnumUtil.BIND_STATUS.BINGDING.getValue()); + reworkOrderBindSnTravelList.add(reworkOrderBindSnTravel); + + + MesPackageDetail packageDetail = packageExtService.getPackageDetailByProductSn(mesWorkOrderExt.getOrganizeCode(), produceSnExt.getProductSn()); + if (null != packageDetail) { + MesPackageExt packageExt = packageExtService.getPackageByPackNo(mesWorkOrderExt.getOrganizeCode(), packageDetail.getPackageNo()); + if (null != packageExt) { + packageExt.setLastWorkOrderNo(mesWorkOrderExt.getOrderNo()); + ConvertBean.serviceModelUpdate(packageExt, mesWorkOrderExt.getModifyUser()); + packageExt.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue()); + new ConvertBeanExt(packageExt).convertBean(packageExt); + packageExtList.add(packageExt); + } + } + } + + produceSnExtRepository.saveAll(produceSnExtList); + if (!CollectionUtils.isEmpty(packageExtList)) packageExtRepository.saveAll(packageExtList); + if (!CollectionUtils.isEmpty(produceSnRepairList)) produceSnRepairRepository.saveAll(produceSnRepairList); + if (!CollectionUtils.isEmpty(reworkOrderBindSnTravelList)) reworkOrderBindSnTravelRepository.saveAll(reworkOrderBindSnTravelList); + } + + private void doBindPackage(GenerateWorkOrderDto workOrderDto, Object data) { + + List packageExtList = (List) data; + + if (CollectionUtils.isEmpty(packageExtList)) return; + + List subassemblyRemadeRecordList = new ArrayList<>(); + + for (MesPackageExt packageExt : packageExtList) { + + MesSubassemblyRemadeRecord record = new MesSubassemblyRemadeRecord(); + record.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue()); + record.setPackageNo(packageExt.getPackageNo()); + record.setLotNo(packageExt.getLotNo()); + record.setQty(0.0); + record.setInitWorkOrderNo(packageExt.getLastWorkOrderNo()); + record.setInitWorkCenterCode(packageExt.getWorkCenterCode()); + record.setInitQty(packageExt.getQty()); + record.setWorkOrderNo(workOrderDto.getOrderNo()); + record.setWorkCenterCode(workOrderDto.getWorkCenterCode()); + record.setPartNo(workOrderDto.getPartNo()); + record.setPartNameRdd(workOrderDto.getPartNameRdd()); + record.setOrganizeCode(workOrderDto.getOrganizeCode()); + ConvertBean.serviceModelInitialize(record, workOrderDto.getUserInfo()); + + subassemblyRemadeRecordList.add(record); + + } + + if (!CollectionUtils.isEmpty(subassemblyRemadeRecordList)) subassemblyRemadeRecordRepository.saveAll(subassemblyRemadeRecordList); + } + + private MesPartExt getMesPartExt(GenerateWorkOrderDto workOrderDto) { + MesPartExt partExtDb = partExtService.getPartExtByPartNo(workOrderDto.getOrganizeCode(), workOrderDto.getPartNo()); + + if (partExtDb == null) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode()) + .setErrorDetail("物料编码[%s]不存在", workOrderDto.getPartNo()) + .build(); + } + + if (StringUtils.isEmpty(partExtDb.getCategoryCode3())) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode()) + .setErrorDetail("物料编码[%s]未维护物料分类3,无法确定为成品或是组件", workOrderDto.getPartNo()) + .build(); + } + return partExtDb; + } + + private List getMesProduceSnExtList(GenerateWorkOrderDto workOrderDto, MesPartExt partExtDb) { + String ruleCode; + try { + ruleCode = productEncodeCfgExtService.getRuleCodeByMatchType( + workOrderDto.getOrganizeCode(), MesExtEnumUtil.ENCODE_CODE_TYPE.STANDARD_SERIAL_SN.getValue(), partExtDb, workOrderDto.getWorkCenterCode()); + } catch (Exception e) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode()) + .setErrorDetail("物料编码[%s]:[%s]!", workOrderDto.getPartNo(), e.getMessage()) + .build(); + } + + MesNumberRuleExt numberRuleExt = getMesNumberRuleExt(workOrderDto, ruleCode); + + checkProductSnValid(workOrderDto.getOrganizeCode(), workOrderDto.getPartNo(), workOrderDto.getProductSnStart(), workOrderDto.getProductSnEnd()); + + checkProduceNumberRuleIsValid(partExtDb, ruleCode, numberRuleExt, workOrderDto.getProductSnStart(), workOrderDto.getProductSnEnd()); + + DdlPackBean packBean = DdlPackBean.getDdlPackBean(workOrderDto.getOrganizeCode()); + DdlPreparedPack.getStringBiggerPack(workOrderDto.getProductSnStart(), MesExtConstWords.PRODUCT_SN, packBean); + DdlPreparedPack.getStringSmallerPack(workOrderDto.getProductSnEnd(), MesExtConstWords.PRODUCT_SN, packBean); + DdlPreparedPack.getStringSmallerPack(workOrderDto.getProductSnEnd(), MesExtConstWords.PRODUCT_SN, packBean); + int snCount = produceSnExtRepository.findByHqlWhereCount(packBean); + + if (snCount == 0) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode()) + .setErrorDetail("未查询到起始条码[%s]与截至条码[%s]区间条码", workOrderDto.getProductSnStart(), workOrderDto.getProductSnEnd()) + .build(); + } + + if (snCount > workOrderDto.getQty()) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode()) + .setErrorDetail("起始条码[%s]与截至条码[%s]之间存在的条码数量大于当前工单计划数量", workOrderDto.getProductSnStart(), workOrderDto.getProductSnEnd()) + .build(); + } + + List produceSnExtDbList = produceSnExtRepository.findByHqlWhere(packBean); + + checkSn(workOrderDto, produceSnExtDbList); + + //编码规则 + String[] serialNoArray = numberRuleExt.getNumberRule().split("}\\{"); + //规则属性长度拼接 + String[] ruleLengthSpiltArray = numberRuleExt.getRuleLengthSpilt().split(","); + String serialNoStr = "serialno"; + int serialNoIndex = -1; + for (int index = 0; index < serialNoArray.length; index++) { + if(serialNoArray[index].contains(serialNoStr)) serialNoIndex = index; + } + + int ruleLengthTotal = 0; + if(serialNoIndex != -1){ + for (int index = 0; index < serialNoIndex; index++) { + ruleLengthTotal += Integer.parseInt(ruleLengthSpiltArray[index]); + } + } + int finalRuleLengthTotal = ruleLengthTotal; + int finalSerialNoIndex = serialNoIndex; + + produceSnExtDbList = produceSnExtDbList.stream().sorted(Comparator.comparing(MesProduceSnExt::getProductSn)).collect(Collectors.toList()); + + Integer lastSerialNo = null; + String lastProductSn = null; + for (MesProduceSnExt produceSnExt : produceSnExtDbList) { + + int curSerialNo = Integer.parseInt(produceSnExt.getSerialNumber().substring(finalRuleLengthTotal, finalRuleLengthTotal + Integer.parseInt(ruleLengthSpiltArray[finalSerialNoIndex]))); + + if (lastSerialNo == null) { + + lastSerialNo = curSerialNo; + lastProductSn = produceSnExt.getProductSn(); + continue; + } + + if (curSerialNo - lastSerialNo !=1 ) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode()) + .setErrorDetail("上一个产品条码[%s]与产品条码[%s]流水号存在跳号", lastProductSn, produceSnExt.getProductSn()) + .build(); + } + + lastProductSn = produceSnExt.getProductSn(); + lastSerialNo = curSerialNo; + } + return produceSnExtDbList; + } + + private void checkSn(GenerateWorkOrderDto workOrderDto, List produceSnExtDbList) { + for (MesProduceSnExt produceSnExt : produceSnExtDbList) { + if (MesExtEnumUtil.PRODUCE_SN_STATUS.OFFLINE.getValue() != produceSnExt.getSnStatus()) { + if (MesExtEnumUtil.PRODUCE_SN_STATUS.REPAIR.getValue() == produceSnExt.getSnStatus()) { + + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode()) + .setErrorDetail("条码[" + produceSnExt.getProductSn() + "]状态为返工,已绑定返工工单[" + produceSnExt.getLastWorkOrderNo() + "]") + .build(); + + } else { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode()) + .setErrorDetail("条码[" + produceSnExt.getProductSn() + "]状态为[" + MesExtEnumUtil.PRODUCE_SN_STATUS.valueOfDescription(produceSnExt.getSnStatus()) + "]") + .build(); + } + } + + if (MesExtEnumUtil.PRODUCE_SN_QC_STATUS.QUALIFIED.getValue() != produceSnExt.getQcStatus()) { + + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode()) + .setErrorDetail("条码[" + produceSnExt.getProductSn() + "]质量状态为[" + MesExtEnumUtil.PRODUCE_SN_QC_STATUS.valueOfDescription(produceSnExt.getQcStatus()) + "]") + .build(); + + } + + if (MesExtEnumUtil.SN_OPERATE_TYPE.REPAIR.getValue() == produceSnExt.getOperateType()) { + + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode()) + .setErrorDetail("条码[" + produceSnExt.getProductSn() + "]操作类型为[" + MesExtEnumUtil.PRODUCE_SN_QC_STATUS.valueOfDescription(produceSnExt.getQcStatus()) + "]") + .build(); + + } + + MesProduceSnRepair produceSnRepairBySn = getProduceSnRepairBySn(workOrderDto.getOrganizeCode(), produceSnExt.getProductSn()); + + if (produceSnRepairBySn != null) { + if (StringUtils.isEmpty(produceSnRepairBySn.getOutWorkCenterTime())) { + + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode()) + .setErrorDetail("条码[" + produceSnExt.getProductSn() + "]已经绑定过其他的返工工单[" + produceSnRepairBySn.getWorkOrderNo() + "]且未下线") + .build(); + + } + } + } + } + + private MesProduceSnRepair getProduceSnRepairBySn(String organizeCode, String productSn) { + if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(productSn)) { + return null; + } + List produceSnRepairList = produceSnRepairRepository.findByProperty( + new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID, MesExtConstWords.PRODUCT_SN}, + new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), productSn}, + " order by createDatetime desc "); + return !CollectionUtils.isEmpty(produceSnRepairList) ? produceSnRepairList.get(0) : null; + } + + private void checkProduceNumberRuleIsValid(MesPartExt partExtDb, String ruleCode, MesNumberRuleExt numberRuleExt, String... productSnArr) { + + for (String productSn : productSnArr) { + Map map = new HashMap<>(); + map.put(MesExtConstWords.SERIAL_NUMBER, productSn); + map.put(MesExtConstWords.NUMBER_RULE_EXT, numberRuleExt); + map.put(MesExtConstWords.PART_EXT, partExtDb); + + Map resultMap = numberRuleCheckAttributeService.doCheckNumberRule(map); + if ((Boolean)resultMap.get(MesExtConstWords.RESULT) == false) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode()) + .setErrorDetail("条码[%s]关联物料[%s]配置的编码规则代码[%s]无效", productSn, partExtDb.getPartNo(), ruleCode) + .build(); + } + } + + } + + private void checkProductSnValid(String organizeCode, String partNo, String... produceSnArr) { + + for (String produceSn : produceSnArr) { + + MesProduceSnExt produceSnDb = produceSnService.getProduceSn(organizeCode, produceSn); + + if (produceSnDb == null) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode()) + .setErrorDetail("产品条码[%s]无效", produceSn) + .build(); + } + + if (StringUtils.isEmpty(produceSnDb.getOutWorkCenterTime())) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode()) + .setErrorDetail("产品条码[%s]未下线", produceSn) + .build(); + } + + if (!partNo.equals(produceSnDb.getPartNo())) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode()) + .setErrorDetail("产品条码[%s]关联物料编码[%s]与当前工单关联物料编码[%s]不一致", produceSn, produceSnDb.getPartNo(), partNo) + .build(); + } + } + } + + private MesNumberRuleExt getMesNumberRuleExt(GenerateWorkOrderDto workOrderDto, String ruleCode) { + MesNumberRuleExt numberRuleExt = numberRuleExtService.getNumberRuleExtByRuleCode(workOrderDto.getOrganizeCode(), ruleCode); + + if (numberRuleExt == null) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode()) + .setErrorDetail("物料编码[%s]未配置生产编码规则", workOrderDto.getPartNo()) + .build(); + } + return numberRuleExt; + } + + private Object checkReworkOrderBindSn(GenerateWorkOrderDto workOrderDto) { + + if (workOrderDto.getWorkOrderType() != MesExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue() || StringUtils.isEmpty(workOrderDto.getProductSnStart()) || StringUtils.isEmpty(workOrderDto.getProductSnEnd())) return null; + + MesPartExt partExtDb = getMesPartExt(workOrderDto); + + workOrderDto.setPartExt(partExtDb); + + // 10 为成品 + if (partExtDb.getCategoryCode3().equals("10")) return getMesProduceSnExtList(workOrderDto, partExtDb); + // 其余都是组件 + else return getMesPackageExtList(workOrderDto, partExtDb); + } + + private List getMesPackageExtList(GenerateWorkOrderDto workOrderDto, MesPartExt partExtDb) { + String ruleCode; + try { + ruleCode = productEncodeCfgExtService.getRuleCodeByMatchType( + workOrderDto.getOrganizeCode(), MesExtEnumUtil.ENCODE_CODE_TYPE.PACK_SN.getValue(), partExtDb, workOrderDto.getWorkCenterCode()); + } catch (Exception e) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode()) + .setErrorDetail("物料编码[%s]:[%s]!", workOrderDto.getPartNo(), e.getMessage()) + .build(); + } + + MesNumberRuleExt numberRuleExt = getMesNumberRuleExt(workOrderDto, ruleCode); + + checkPackageSnValid( workOrderDto, workOrderDto.getProductSnStart(), workOrderDto.getProductSnEnd()); + + checkProduceNumberRuleIsValid(partExtDb, ruleCode, numberRuleExt, workOrderDto.getProductSnStart(), workOrderDto.getProductSnEnd()); + + DdlPackBean packBean = DdlPackBean.getDdlPackBean(workOrderDto.getOrganizeCode()); + DdlPreparedPack.getStringBiggerPack(workOrderDto.getProductSnStart(), MesExtConstWords.PACKAGENO, packBean); + DdlPreparedPack.getStringSmallerPack(workOrderDto.getProductSnEnd(), MesExtConstWords.PACKAGENO, packBean); + int snCount = packageExtRepository.findByHqlWhereCount(packBean); + + checkSnCount(workOrderDto, snCount); + + List packageExtDbList = packageExtRepository.findByHqlWhere(packBean); + + Double totalQty = packageExtDbList.stream().mapToDouble(MesPackageExt::getQty).sum(); + + //List packageNoList = packageExtDbList.stream().map(MesPackageExt::getPackageNo).collect(Collectors.toList()); + + if (totalQty.compareTo(workOrderDto.getQty()) > 0) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode()) + .setErrorDetail("起始包装条码[%s]和截至包装条码[%s]包装数量总和[%s]大于工单[%s]计划数量[%s],请扣减一定数量的包装再进行绑定", workOrderDto.getProductSnStart(), workOrderDto.getProductSnEnd(), totalQty.toString(), workOrderDto.getOrderNo(), workOrderDto.getQty()) + .build(); + } + + //double boundSnQty = getBoundSnQty(workOrderDto); + + //List packSnList = workOrderDto.getPackSnList(); + //if (!CollectionUtils.isEmpty(packSnList) && !CollectionUtils.isEmpty(packageNoList)) { + // + // for (String packageNo : packSnList) { + // if (packageNoList.contains(packageNo)) { + // throw ImppExceptionBuilder.newInstance() + // .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + // .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode()) + // .setErrorDetail("包装条码[%s]已绑定至工单[%s],无需再次绑定", packageNo, workOrderDto.getOrderNo()) + // .build(); + // + // } + // } + //} + + //编码规则 + String[] serialNoArray = numberRuleExt.getNumberRule().split("}\\{"); + //规则属性长度拼接 + String[] ruleLengthSpiltArray = numberRuleExt.getRuleLengthSpilt().split(","); + String serialNoStr = "serialno"; + int serialNoIndex = -1; + for (int index = 0; index < serialNoArray.length; index++) { + if(serialNoArray[index].contains(serialNoStr)) serialNoIndex = index; + } + + int ruleLengthTotal = 0; + if(serialNoIndex != -1){ + for (int index = 0; index < serialNoIndex; index++) { + ruleLengthTotal += Integer.parseInt(ruleLengthSpiltArray[index]); + } + } + int finalRuleLengthTotal = ruleLengthTotal; + int finalSerialNoIndex = serialNoIndex; + + packageExtDbList = packageExtDbList.stream().sorted(Comparator.comparing(MesPackageExt::getPackageNo)).collect(Collectors.toList()); + + Integer lastSerialNo = null; + String lastProductSn = null; + + for (MesPackageExt packageExt : packageExtDbList) { + + int curSerialNo = Integer.parseInt(packageExt.getSerialNumber().substring(finalRuleLengthTotal, finalRuleLengthTotal + Integer.parseInt(ruleLengthSpiltArray[finalSerialNoIndex]))); + + if (lastSerialNo == null) { + + lastSerialNo = curSerialNo; + lastProductSn = packageExt.getPackageNo(); + continue; + } + + if (curSerialNo - lastSerialNo !=1 ) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode()) + .setErrorDetail("上一个包装条码[%s]与包装条码[%s]流水号存在跳号", lastProductSn, packageExt.getPackageNo()) + .build(); + } + + lastProductSn = packageExt.getPackageNo(); + lastSerialNo = curSerialNo; + } + return packageExtDbList; + } + + private void checkSnCount(GenerateWorkOrderDto workOrderDto, int snCount) { + if (snCount > workOrderDto.getQty()) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode()) + .setErrorDetail("起始条码[%s]与截至条码[%s]之间存在的条码数量大于当前工单计划数量", workOrderDto.getProductSnStart(), workOrderDto.getProductSnEnd()) + .build(); + } + + if (snCount == 0) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode()) + .setErrorDetail("未查询到起始条码[%s]与截至条码[%s]区间条码", workOrderDto.getProductSnStart(), workOrderDto.getProductSnEnd()) + .build(); + } + } + + private void checkPackageSnValid(GenerateWorkOrderDto workOrderDto, String... packageNoArr) { + + for (String packageNo : packageNoArr) { + MesPackageExt packageExt = packageExtRepository.getByProperty( + new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID, MesExtConstWords.PACKAGENO}, + new Object[]{workOrderDto.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue(), packageNo}); + + if (packageExt == null) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode()) + .setErrorDetail("包装条码[%s]无效", packageNo) + .build(); + } + + if (MesEnumUtil.PACKAGE_IS_SEALED.UNSEALED.getValue() == packageExt.getIsSealed()) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode()) + .setErrorDetail("包装条码[%s]未封箱", packageNo) + .build(); + } + + if (!workOrderDto.getPartNo().equals(packageExt.getPartNo())) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode()) + .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode()) + .setErrorDetail("包装条码[%s]关联物料编码[%s]与当前工单关联物料编码[%s]不一致", packageNo, packageExt.getPartNo(), workOrderDto.getPartNo()) + .build(); + } + } + } + + private void checkReworkQty(GenerateWorkOrderDto workOrderDto) { + if(workOrderDto.getPlanQty() > workOrderDto.getQty()) throw new BaseImppException("计划返工数量不能大于计划生产数量"); } private void addWorkOrder(MesWorkOrderExt mesWorkOrderExt) { diff --git a/modules/i3plus-ext-mes-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/apiservice/serviceimpl/base/jx/SxWorkCellTaktCollectPlcCfgService.java b/modules/i3plus-ext-mes-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/apiservice/serviceimpl/base/jx/SxWorkCellTaktCollectPlcCfgService.java index 9b543fe..00776ca 100644 --- a/modules/i3plus-ext-mes-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/apiservice/serviceimpl/base/jx/SxWorkCellTaktCollectPlcCfgService.java +++ b/modules/i3plus-ext-mes-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/apiservice/serviceimpl/base/jx/SxWorkCellTaktCollectPlcCfgService.java @@ -72,7 +72,7 @@ public class SxWorkCellTaktCollectPlcCfgService implements ISxWorkCellTaktCollec // 封装唯一校验查询条件 DdlPackBean packBean = DdlPackBean.getDdlPackBean(sxWorkCellTaktCollectPlcCfg.getOrganizeCode()); - DdlPreparedPack.getStringEqualPack(sxWorkCellTaktCollectPlcCfg.getWorkCenterCode(), MesExtConstWords.WORK_CENTER_NAME, packBean); + DdlPreparedPack.getStringEqualPack(sxWorkCellTaktCollectPlcCfg.getWorkCenterCode(), MesExtConstWords.WORK_CENTER_CODE, packBean); DdlPreparedPack.getStringEqualPack(sxWorkCellTaktCollectPlcCfg.getWorkCellCode(), MesExtConstWords.WORK_CELL_CODE, packBean); SxWorkCellTaktCollectPlcCfg sxWorkCellTaktCollectPlcCfgIsExist = workCellTaktCollectPlcCfgRepository.getByProperty(packBean); diff --git a/modules/i3plus-ext-mes-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pojo/sqlpack/MesExtHqlPack.java b/modules/i3plus-ext-mes-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pojo/sqlpack/MesExtHqlPack.java index a881143..db27914 100644 --- a/modules/i3plus-ext-mes-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pojo/sqlpack/MesExtHqlPack.java +++ b/modules/i3plus-ext-mes-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pojo/sqlpack/MesExtHqlPack.java @@ -940,7 +940,7 @@ public class MesExtHqlPack { DdlPackBean packBean = getAllBaseDataByNormalPro(workCellTaktCollectPlcCfg, workCellTaktCollectPlcCfg.getOrganizeCode()); DdlPreparedPack.getStringLikerPack(workCellTaktCollectPlcCfg.getWorkCenterCode(), MesExtConstWords.WORK_CENTER_CODE, packBean); DdlPreparedPack.getStringLikerPack(workCellTaktCollectPlcCfg.getWorkCellCode(), MesExtConstWords.WORK_CELL_CODE, packBean); - DdlPreparedPack.getNumEqualPack(workCellTaktCollectPlcCfg.getPlcCode(), MesExtConstWords.PLC_CODE, packBean); + DdlPreparedPack.getStringLikerPack(workCellTaktCollectPlcCfg.getPlcCode(), MesExtConstWords.PLC_CODE, packBean); DdlPreparedPack.getNumEqualPack(workCellTaktCollectPlcCfg.getStatus(), MesExtConstWords.STATUS, packBean); if (!StringUtils.isEmpty(workCellTaktCollectPlcCfg.getModifyDateTimeStart()) || !StringUtils.isEmpty(workCellTaktCollectPlcCfg.getModifyDateTimeEnd())) { DdlPreparedPack.timeBuilder(workCellTaktCollectPlcCfg.getModifyDateTimeStart(), workCellTaktCollectPlcCfg.getModifyDateTimeEnd(), MesExtConstWords.MODIFY_DATE_TIME, packBean, true);