Преглед изворни кода

Merge remote-tracking branch 'origin/mode-min-unit' into mode-min-unit

fangpy пре 5 месеци
родитељ
комит
38ebd689d8

+ 2 - 0
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/dao/ApsProcessOperationProcessEquDao.java

@@ -128,6 +128,8 @@ public interface ApsProcessOperationProcessEquDao extends BaseMapper<ApsProcessO
 
     @Select("select * from aps_process_operation_process_equ where DELETED = 0 AND PROCESSDEVICEID = #{processdeviceid} AND ID != #{apsProcessOperationProcessEquDoId} AND WAITREPORTID IS NOT NULL AND WAITREPORTID != ''")
     List<ApsProcessOperationProcessEquDo> selectHaveOtherDevice(@Param("processdeviceid") String processdeviceid,@Param("apsProcessOperationProcessEquDoId") String apsProcessOperationProcessEquDoId);
+
+    void repairePlanStartDate();
 }
 
 

+ 3 - 1
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/dao/ApsReportRecordsDao.java

@@ -59,11 +59,13 @@ public interface ApsReportRecordsDao extends BaseMapper<ApsReportRecordsDo> {
     @Update("update aps_process_operation_process_equ set BACHMATERIALPROCESS = REPLACE(REPLACE(REPLACE(BACHMATERIALPROCESS,'${inputBatchNumber},',''),',${inputBatchNumber}',''),'${inputBatchNumber}','') where DELETED = 0 AND ID IN ('${ids}')")
     void updateAllProcessEquBatchNumberByIds(@Param("inputBatchNumber") String inputBatchNumber, @Param("ids") String ids);
 
-    @Select("select * from aps_process_operation_process_equ where DELETED = 0 AND ID != #{id} AND PROCESSDEVICEID = #{processdeviceid} AND PLANSTARTDATE = #{planstartdate} AND (WAITREPORTID is null or WAITREPORTID = '') AND CLOSESTATUS = '未完工'")
+    @Select("select * from aps_process_operation_process_equ where DELETED = 0 AND ID != #{id} AND PROCESSDEVICEID = #{processdeviceid} AND PLANSTARTDATE = #{planstartdate} AND (WAITREPORTID is null or WAITREPORTID = '') AND WORKSTATUS = '待开工'")
     List<ApsProcessOperationProcessEquDo> selectOtherMergeProcessEqu(@Param("id") String id, @Param("processdeviceid") String processdeviceid, @Param("planstartdate") Date planstartdate);
 
 //    @Select("select * from aps_process_operation_process_equ where DELETED = 0 AND ID != #{id} AND PROCESSDEVICEID = #{processdeviceid} AND PLANSTARTDATE = #{planstartdate} AND WAITREPORTID is not null AND WAITREPORTID != ''")
     List<ApsProcessOperationProcessEquDo> selectOtherMergeProcessStarting(@Param("id") String id, @Param("processdeviceid") String processdeviceid);
 
     List<ProcessOutputAndInputNumber> selectInputAndOutputNumByProcessId(@Param("processIds")List<String> processIds);
+
+    List<ApsProcessOperationProcessEquDo> selectOtherMergeProcessEquByHeat(@Param("id") String id, @Param("processdeviceid") String processdeviceid, @Param("heatnumber") String heatnumber);
 }

+ 2 - 0
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/service/ApsProcessOperationProcessEquService.java

@@ -27,4 +27,6 @@ public interface ApsProcessOperationProcessEquService extends IService<ApsProces
     R splitDetails(List<ProcessOperationDetailSplitVo> processOperationDetailSplitVos);
 
     R workshopLocked(OrderLockVo orderLockVo);
+
+    R scheduling(ChangingScheduleVo req);
 }

+ 27 - 8
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/service/impl/ApsBlankOrderServiceImpl.java

@@ -976,7 +976,7 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
 
             //更新生产状态为“待发布”(20)
             List<ApsBlankOrderVo> toupstatus = apsBlankOrders.stream().filter(v ->
-                    blankids.contains(v.getId()) && (StringUtils.isBlank(v.getIfcp()) || "N".equals(v.getIfcp())))
+                            blankids.contains(v.getId()) && (StringUtils.isBlank(v.getIfcp()) || "N".equals(v.getIfcp())))
                     .collect(Collectors.toList());
             updateProductStatusByOrderIds(toupstatus);
             // 自动加锁坯料计划下的工序作业
@@ -4187,14 +4187,14 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
                 needScheduleDate = DateUtil.format(DateUtil.offsetDay(nowDate, 2), "yyyy-MM-dd");
             }
             //计算重排开始时间和结束时间
-            chongpaiStartDate = DateUtil.parse(needScheduleDate,"yyyy-MM-dd HH:mm:ss");
+            chongpaiStartDate = DateUtil.parseDate(needScheduleDate);
             chongpaiEndDate = DateUtil.endOfDay(chongpaiStartDate);
             if (ObjectUtil.isNotEmpty(hour)) {
                 chongpaiEndDate = DateUtil.offsetHour(chongpaiStartDate, hour);
             }
         } else {
-            chongpaiStartDate = DateUtil.parse(chongpaiStartDateStr,"yyyy-MM-dd HH:mm:ss");
-            chongpaiEndDate = DateUtil.parse(chongpaiEndDateStr,"yyyy-MM-dd HH:mm:ss");
+            chongpaiStartDate = DateUtil.parse(chongpaiStartDateStr, "yyyy-MM-dd HH:mm:ss");
+            chongpaiEndDate = DateUtil.parse(chongpaiEndDateStr, "yyyy-MM-dd HH:mm:ss");
             needScheduleDate = DateUtil.format(chongpaiStartDate, "yyyy-MM-dd");
         }
         if (ObjectUtil.isNotEmpty(needScheduleDate)) {
@@ -4526,6 +4526,8 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
                     String previousprocessesid = apsProcessOperationProcessEquDo.getPreviousprocessesids();
                     //当前明细对应的工序作业
                     ApsProcessOperationDo nowProcess = allProcessList.stream().filter(item -> apsProcessOperationProcessEquDo.getProcessid().equals(item.getId())).findFirst().orElse(null);
+                    //短暂需要锁定的作业明细集合,可能回滚的
+                    List<String> rollEquIdList = new LinkedList<>();
                     //是否可以解锁
                     boolean canUnLock = true;
                     //循环寻找前道明细
@@ -4550,6 +4552,12 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
                                 previousprocessesid = previousEqu.getPreviousprocessesids();
                                 nowProcess = previousProcess;
                                 notNeedUnLockList.add(previousEqu);
+                                rollEquIdList.add(previousEqu.getId());
+                                if (previousEqu.getPlanstartdate().compareTo(chongpaiStartDate) >= 0) {
+                                    List<String> finalRollEquIdList = rollEquIdList;
+                                    notNeedUnLockList = notNeedUnLockList.stream().filter(item -> !finalRollEquIdList.contains(item.getId())).collect(Collectors.toList());
+                                    rollEquIdList = new LinkedList<>();
+                                }
                                 continue;
                             }
                             //如果前道明细不是待开工,不解锁,传入排程
@@ -4583,6 +4591,7 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
                                     previousprocessesid = previousEqu.getPreviousprocessesids();
                                     nowProcess = previousProcess;
                                     notNeedUnLockList.add(previousEqu);
+                                    rollEquIdList.add(previousEqu.getId());
                                     canUnLock = false;
                                 }
                             }
@@ -4600,7 +4609,9 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
             }
             //后道明细不为空
             if (ObjectUtil.isNotEmpty(apsProcessOperationProcessEquDo.getNextprocessesids())) {
-                getNextProcess(apsProcessOperationProcessEquDo.getNextprocessesids(), needScheduleList, needScheduleIdList, allProcessEquList, allProcessEquIdList, needUnLockList, allProcessList);
+                //当前工序作业
+                ApsProcessOperationDo nowProcess = allProcessList.stream().filter(item -> item.getId().equals(apsProcessOperationProcessEquDo.getProcessid())).findFirst().orElse(null);
+                getNextProcess(apsProcessOperationProcessEquDo.getNextprocessesids(), nowProcess, needScheduleList, needScheduleIdList, allProcessEquList, allProcessEquIdList, needUnLockList, allProcessList);
             }
         }
         //查询需要清除的明细及其后续 连续的明细
@@ -4728,6 +4739,7 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
 
     //迭代处理寻找下道明细
     private void getNextProcess(String nextprocessesids,
+                                ApsProcessOperationDo nowProcess,
                                 List<ApsProcessOperationProcessEquDo> needScheduleList,
                                 List<String> needScheduleIdList,
                                 List<ApsProcessOperationProcessEquDo> allProcessEquList,
@@ -4743,15 +4755,22 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
                 //下一个明细
                 ApsProcessOperationProcessEquDo nextEqu = allProcessEquList.stream().filter(item -> item.getId().equals(nextProcessEquId)).findFirst().orElse(null);
                 if (ObjectUtil.isNotEmpty(nextEqu)) {
+                    String nextNewProcessesids = nextEqu.getNextprocessesids();
                     //查询对应明细的工序作业
                     ApsProcessOperationDo nextProcess = allProcessList.stream().filter(item -> item.getId().equals(nextEqu.getProcessid())).findFirst().orElse(null);
                     if (ObjectUtil.isNotEmpty(nextProcess)
-                            && !Arrays.asList("铸轧", "成退", "小卷成退", "中退").contains(nextProcess.getProcess())) {
+                            && !Arrays.asList("铸轧", "成退", "小卷成退", "中退").contains(nextProcess.getProcess())
+                            && nextProcess.getProcess().equals(nowProcess.getProcess())
+                            && (ObjectUtil.isEmpty(nextProcess.getMinflowwaitmin()) || nextProcess.getMinflowwaitmin().compareTo(new BigDecimal(1440)) < 0)) {
                         needUnLockList.add(nextEqu);
                         if (ObjectUtil.isNotEmpty(nextEqu.getNextprocessesids())) {
-                            String nextNewProcessesids = nextEqu.getNextprocessesids();
-                            getNextProcess(nextNewProcessesids, needScheduleList, needScheduleIdList, allProcessEquList, allProcessEquIdList, needUnLockList, allProcessList);
+                            getNextProcess(nextNewProcessesids, nextProcess, needScheduleList, needScheduleIdList, allProcessEquList, allProcessEquIdList, needUnLockList, allProcessList);
                         }
+                        return;
+                    } else {
+                        //如果下道作业和当前作业不同,结束,后续全部不解锁
+                        //有最小等待时间,并且>=1440,后续全部不解锁
+                        return;
                     }
                 }
             }

+ 147 - 32
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/service/impl/ApsProcessOperationProcessEquServiceImpl.java

@@ -389,12 +389,12 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
                     processEqus.setProcessworkshop(changingWiresVo.getWorkshopName());
                     processEqus.setProcessdeviceid(changingWiresVo.getEquId());
                     processEqus.setProcessdevice(changingWiresVo.getEquName());
-                    if (equIds.contains(changingWiresVo.getEquId())){
+                    if (equIds.contains(changingWiresVo.getEquId())) {
                         ApsProcessOperationEquDo apsProcessOperationEquDo = processOperationEquDos.stream().filter(item -> item.getResourceid().equals(changingWiresVo.getEquId())).findFirst().orElse(null);
                         if (ObjectUtil.isNotEmpty(apsProcessOperationEquDo)) {
                             processEqus.setRollerid(apsProcessOperationEquDo.getRollerid());
                         }
-                    }else {
+                    } else {
                         processEqus.setRollerid("");
                     }
                     // 计划开工时间=计划开工时间-开工时间间隔
@@ -451,12 +451,12 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
                         newProcessEqu.setProcessworkshop(changingWiresVo.getWorkshopName());
                         newProcessEqu.setProcessdeviceid(changingWiresVo.getEquId());
                         newProcessEqu.setProcessdevice(changingWiresVo.getEquName());
-                        if (equIds.contains(changingWiresVo.getEquId())){
+                        if (equIds.contains(changingWiresVo.getEquId())) {
                             ApsProcessOperationEquDo apsProcessOperationEquDo = processOperationEquDos.stream().filter(item -> item.getResourceid().equals(changingWiresVo.getEquId())).findFirst().orElse(null);
                             if (ObjectUtil.isNotEmpty(apsProcessOperationEquDo)) {
                                 newProcessEqu.setRollerid(apsProcessOperationEquDo.getRollerid());
                             }
-                        }else {
+                        } else {
                             processEqus.setRollerid("");
                         }
                         newProcessEqu.setActualstartdate(null);
@@ -607,7 +607,7 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
         }
     }
 
-    private void checkSomeNewInspection(ApsProcessOperationProcessEquDo apsProcessOperationProcessEquDo,List<String> affectedIdList) {
+    private void checkSomeNewInspection(ApsProcessOperationProcessEquDo apsProcessOperationProcessEquDo, List<String> affectedIdList) {
         /*
         如果加工设备不是工序作业指定的可选设备,记录冲突:加工设备不是工艺要求的可选设备
         如果作业明细计划开工时间<前道作业明细计划完工时间,记录冲突:计划开工时间早于前道计划完工时间
@@ -1084,7 +1084,7 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
                 // 增加受影响的工序作业信息
                 affectedIdList.addAll(checkProcessingTimeConflict(apsProcessOperationProcessEquDo, oldPlanstartdate,
                         oldPlanenddate, oldEquId, apsProcessOperationDo.getProcessway(), new ArrayList<>()));
-            }else {
+            } else {
                 this.updateById(apsProcessOperationProcessEquDo);
             }
 //            this.updateById(apsProcessOperationProcessEquDo);
@@ -1743,35 +1743,75 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
     public void inspectionEquipmentIsAvailable(ApsProcessOperationProcessEquDo processEquDo,
                                                String equId, Date startDate, Date endDate,
                                                List<String> affectedIdList) {
-        // 查询当前设备是否存在不可用设备的停机时间为空的数据
-        List<ApsEquipmentCalendarDo> nullSdTimeList = apsEquipmentCalendarService.list(new LambdaQueryWrapper<ApsEquipmentCalendarDo>()
+        // 查询当前设备 在开始时间之后,是否存在不可用设备数据
+        List<ApsEquipmentCalendarDo> equUnUseList = apsEquipmentCalendarService.list(new LambdaQueryWrapper<ApsEquipmentCalendarDo>()
                 .eq(ApsEquipmentCalendarDo::getProcessdeviceid, equId)
-                .isNull(ApsEquipmentCalendarDo::getSdendtime));
-        List<ApsEquipmentCalendarDo> list = new ArrayList<>();
-        //注意不可用结束时间为空,表示后面一直不可用
-        if (nullSdTimeList.isEmpty()) {
-            // 查询当前设备当前时间段是否存在不可用设备
-            list = apsEquipmentCalendarService.list(new LambdaQueryWrapper<ApsEquipmentCalendarDo>()
-                    .eq(ApsEquipmentCalendarDo::getProcessdeviceid, equId)
-                    .and(wapper -> wapper.apply("{0}   BETWEEN sdstarttime AND sdendtime", startDate)
-                            .or()
-                            .apply("{0}   BETWEEN sdstarttime AND sdendtime", endDate)));
-        } else {
-            list = apsEquipmentCalendarService.list(new LambdaQueryWrapper<ApsEquipmentCalendarDo>()
-                    .eq(ApsEquipmentCalendarDo::getProcessdeviceid, equId)
-                    .and(wapper -> wapper.apply("sdstarttime<={0}", startDate)
-                            .or()
-                            .apply("sdstarttime<={0}", endDate)));
-        }
-        String newConflictdes;
-        if (list.isEmpty()) {
+                .le(ApsEquipmentCalendarDo::getSdstarttime, startDate));
+        String newConflictdes = processEquDo.getConflictdes();
+        //时间不可用是否有冲突
+        boolean isAdd = false;
+        for (ApsEquipmentCalendarDo apsEquipmentCalendarDo : equUnUseList) {
+            Date sdstarttime = apsEquipmentCalendarDo.getSdstarttime();
+            Date sdendtime = apsEquipmentCalendarDo.getSdendtime();
+
+            //没有结束时间,表示开始时间以后都不可用
+            if (ObjectUtil.isEmpty(sdendtime)) {
+                //计划结束时间在不可用片段
+                if (endDate.after(sdstarttime)) {
+                    apsConflictLogService.recordLog(processEquDo.getId(),
+                            apsEquipmentCalendarDo.getId(), EQUIPMENT_RUN_TIME, 1, null);
+                    newConflictdes = addNewConflictsDesc(processEquDo.getConflictdes(), EQUIPMENT_RUN_TIME);
+                    isAdd = true;
+                    break;
+                } else {
+                    isAdd = false;
+                }
+            } else {
+                //计划开始时间/计划结束时间在停用开始时间和停用结束时间之间
+                if ((startDate.after(sdstarttime) && startDate.before(sdendtime))
+                        || (endDate.after(sdstarttime) && endDate.before(sdendtime))) {
+                    apsConflictLogService.recordLog(processEquDo.getId(),
+                            apsEquipmentCalendarDo.getId(), EQUIPMENT_RUN_TIME, 1, null);
+                    newConflictdes = addNewConflictsDesc(processEquDo.getConflictdes(), EQUIPMENT_RUN_TIME);
+                    isAdd = true;
+                    break;
+                }
+                isAdd = false;
+            }
+        }
+        if (!isAdd) {
             apsConflictLogService.recordLog(processEquDo.getId(), "", EQUIPMENT_RUN_TIME, 2, null);
             newConflictdes = removeConflictsDesc(processEquDo.getConflictdes(), EQUIPMENT_RUN_TIME);
-        } else {
-            apsConflictLogService.recordLog(processEquDo.getId(),
-                    list.stream().map(ApsEquipmentCalendarDo::getId).collect(Collectors.joining(",")), EQUIPMENT_RUN_TIME, 1, null);
-            newConflictdes = addNewConflictsDesc(processEquDo.getConflictdes(), EQUIPMENT_RUN_TIME);
         }
+//        //查询其中没有停机结束时间的数据
+//        List<ApsEquipmentCalendarDo> nullSdEndTimeList = equUnUseList.stream().filter(item -> ObjectUtil.isEmpty(item.getSdendtime())).collect(Collectors.toList());
+//
+//
+//        List<ApsEquipmentCalendarDo> list = new ArrayList<>();
+//        //注意不可用结束时间为空,表示后面一直不可用
+//        if (nullSdTimeList.isEmpty()) {
+//            // 查询当前设备当前时间段是否存在不可用设备
+//            list = apsEquipmentCalendarService.list(new LambdaQueryWrapper<ApsEquipmentCalendarDo>()
+//                    .eq(ApsEquipmentCalendarDo::getProcessdeviceid, equId)
+//                    .and(wapper -> wapper.apply("{0}   BETWEEN sdstarttime AND sdendtime", startDate)
+//                            .or()
+//                            .apply("{0}   BETWEEN sdstarttime AND sdendtime", endDate)));
+//        } else {
+//            list = apsEquipmentCalendarService.list(new LambdaQueryWrapper<ApsEquipmentCalendarDo>()
+//                    .eq(ApsEquipmentCalendarDo::getProcessdeviceid, equId)
+//                    .and(wapper -> wapper.apply("sdstarttime<={0}", startDate)
+//                            .or()
+//                            .apply("sdstarttime<={0}", endDate)));
+//        }
+//
+//        if (list.isEmpty()) {
+//            apsConflictLogService.recordLog(processEquDo.getId(), "", EQUIPMENT_RUN_TIME, 2, null);
+//            newConflictdes = removeConflictsDesc(processEquDo.getConflictdes(), EQUIPMENT_RUN_TIME);
+//        } else {
+//            apsConflictLogService.recordLog(processEquDo.getId(),
+//                    list.stream().map(ApsEquipmentCalendarDo::getId).collect(Collectors.joining(",")), EQUIPMENT_RUN_TIME, 1, null);
+//            newConflictdes = addNewConflictsDesc(processEquDo.getConflictdes(), EQUIPMENT_RUN_TIME);
+//        }
         this.update(new LambdaUpdateWrapper<ApsProcessOperationProcessEquDo>()
                 .eq(ApsProcessOperationProcessEquDo::getId, processEquDo.getId())
                 .set(ApsProcessOperationProcessEquDo::getConflictdes, newConflictdes)
@@ -1781,7 +1821,7 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
         );
         processEquDo.setConflictdes(newConflictdes);
         //新增的冲突判断
-        checkSomeNewInspection(processEquDo,affectedIdList);
+        checkSomeNewInspection(processEquDo, affectedIdList);
     }
 
     /**
@@ -2003,6 +2043,81 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
         return apsBlankOrderService.processDetailLock(orderLockVo);
     }
 
+    @Override
+    public R scheduling(ChangingScheduleVo req) {
+        ApsUtils.checkScheduling(null);
+
+        Date processingTime = req.getProcessingTime();
+        if (processingTime.before(DateUtil.date())) {
+            return R.error("开始时间必须大于当前时间");
+        }
+
+        //作业明细集合
+        List<String> processEquIdList = req.getProcessEquIdList();
+        List<ApsProcessOperationProcessEquDo> apsProcessOperationProcessEquDos = apsProcessOperationProcessEquService.listByIds(processEquIdList).stream().collect(Collectors.toList());
+        //作业ID集合
+        List<String> processIdList = apsProcessOperationProcessEquDos.stream().map(ApsProcessOperationProcessEquDo::getProcessid).distinct().collect(Collectors.toList());
+        //可选设备
+        List<ApsProcessOperationEquDo> processOperationEquDos = apsProcessOperationEquService.list(new LambdaQueryWrapper<ApsProcessOperationEquDo>().in(ApsProcessOperationEquDo::getMainid, processIdList));
+
+        List<String> blankIdList = apsProcessOperationProcessEquDos.stream().map(ApsProcessOperationProcessEquDo::getBlankid).distinct().collect(Collectors.toList());
+        apsProcessOperationProcessEquDos.sort(Comparator.comparing(ApsProcessOperationProcessEquDo::getPlanstartdate));
+        //需要更新的集合
+//        List<ApsProcessOperationProcessEquDo> needUpdateList = new LinkedList<>();
+        //下一道明细的开始时间
+        Date nextStartDate = req.getProcessingTime();
+        for (ApsProcessOperationProcessEquDo apsProcessOperationProcessEquDo : apsProcessOperationProcessEquDos) {
+            Date planstartdate = apsProcessOperationProcessEquDo.getPlanstartdate();
+            Date planenddate = apsProcessOperationProcessEquDo.getPlanenddate();
+            String processdeviceid = apsProcessOperationProcessEquDo.getProcessdeviceid();
+            ApsProcessOperationProcessEquDo needUpdate = new ApsProcessOperationProcessEquDo();
+            needUpdate.setId(apsProcessOperationProcessEquDo.getId());
+            needUpdate.setProcessdeviceid(req.getEquId());
+            needUpdate.setProcessdevice(req.getEquName());
+            //对应的辊赋值
+            String processid = apsProcessOperationProcessEquDo.getProcessid();
+            List<ApsProcessOperationEquDo> myEquList = processOperationEquDos.stream().filter(item -> item.getMainid().equals(processid)).collect(Collectors.toList());
+            if (myEquList.isEmpty()) {
+                needUpdate.setRollerid("");
+            } else {
+                ApsProcessOperationEquDo apsProcessOperationEquDo = myEquList.stream().filter(item -> item.getResourceid().equals(req.getEquId())).findFirst().orElse(null);
+                if (ObjectUtil.isEmpty(apsProcessOperationEquDo)) {
+                    needUpdate.setRollerid("");
+                } else {
+                    needUpdate.setRollerid(apsProcessOperationEquDo.getRollerid());
+                }
+            }
+
+            needUpdate.setProcessworkshopid(req.getWorkshopId());
+            needUpdate.setProcessworkshop(req.getWorkshopName());
+            needUpdate.setPlanstartdate(nextStartDate);
+            needUpdate.setPlanenddate(DateUtil.offsetSecond(nextStartDate, (int) DateUtil.between(planstartdate, planenddate, DateUnit.SECOND)));
+            nextStartDate = needUpdate.getPlanenddate();
+//            needUpdateList.add(needUpdate);
+            apsProcessOperationProcessEquService.updateById(needUpdate);
+            apsProcessOperationProcessEquDo.setProcessdeviceid(needUpdate.getProcessdeviceid());
+            apsProcessOperationProcessEquDo.setProcessdevice(needUpdate.getProcessdevice());
+            apsProcessOperationProcessEquDo.setRollerid(needUpdate.getRollerid());
+            apsProcessOperationProcessEquDo.setProcessworkshopid(needUpdate.getProcessworkshopid());
+            apsProcessOperationProcessEquDo.setProcessworkshop(needUpdate.getProcessworkshop());
+            apsProcessOperationProcessEquDo.setPlanstartdate(needUpdate.getPlanstartdate());
+            apsProcessOperationProcessEquDo.setPlanenddate(needUpdate.getPlanenddate());
+            checkProcessingTimeConflict(apsProcessOperationProcessEquDo,
+                    planstartdate, planenddate, processdeviceid, "非合并加工", new LinkedList<>());
+            // 判断是否存在设备不可用
+            apsProcessOperationProcessEquDo = this.getById(apsProcessOperationProcessEquDo.getId());
+            inspectionEquipmentIsAvailable(apsProcessOperationProcessEquDo,
+                    apsProcessOperationProcessEquDo.getProcessdeviceid(),
+                    apsProcessOperationProcessEquDo.getPlanstartdate(),
+                    apsProcessOperationProcessEquDo.getPlanenddate(),
+                    new LinkedList<>());
+        }
+        blankIdList.forEach(item -> apsBlankOrderService.updateBlankDeliveryDate(null, item));
+
+
+        return R.ok();
+    }
+
 
 }
 

+ 143 - 258
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/service/impl/ApsReportRecordsServiceImpl.java

@@ -1,6 +1,7 @@
 package com.rongwei.bscommon.sys.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
@@ -259,64 +260,10 @@ public class ApsReportRecordsServiceImpl extends ServiceImpl<ApsReportRecordsDao
         //查询作业明细详情
         ApsProcessOperationProcessEquDo equDo = apsProcessOperationProcessEquDao.selectById(processequid);
 
-//        //更新设备的待报工记录ID
-//        apsProcessOperationProcessEquDao.updateEquByCancelRecord(recordId, equDo.getProcessdeviceid());
-
-//        //作业明细的作业状态
-//        /**
-//         * 如果已开工卷数=0,则=待开工;
-//         * 如果已开工卷数>0,并且完工状态=未完工,则=加工中;(先更新完工状态)
-//         * 如果未完工卷数=0,并且完工状态=已完工,则=已完工(先更新完工状态)
-//         */
-//        LambdaUpdateWrapper<ApsProcessOperationProcessEquDo> set = new UpdateWrapper<ApsProcessOperationProcessEquDo>().lambda();
-//        if (equDo.getStartingroll() == 0) {
-//            set.set(ApsProcessOperationProcessEquDo::getWorkstatus, "待开工");
-//            set.set(ApsProcessOperationProcessEquDo::getActualstartdate, null);
-//        }
-//        if (equDo.getStartingroll() > 0 && equDo.getClosestatus().equals("未完工")) {
-//            set.set(ApsProcessOperationProcessEquDo::getWorkstatus, "加工中");
-//        }
-//        if (ObjectUtil.isNotEmpty(equDo.getUnfinishroll()) && equDo.getUnfinishroll() == 0) {
-//            set.set(ApsProcessOperationProcessEquDo::getWorkstatus, "已完工");
-//        }
-
         /**
          * 如果输入物料有批次号,则
          */
         if (ObjectUtil.isNotEmpty(recordsDo.getBatchnumber())) {
-//            //查询工序作业
-//            ApsProcessOperationDo apsProcessOperationDo = apsProcessOperationService.getById(processoperationid);
-//            //没有前道工序
-//            if (ObjectUtil.isEmpty(apsProcessOperationDo.getPreviousprocessid())) {
-//                apsProcessOperationDao.updateBatchNumberByProcessId(recordsDo.getBatchnumber(), processoperationid);
-//            }
-//            //有前道工序
-//            if (ObjectUtil.isNotEmpty(apsProcessOperationDo.getPreviousprocessid())) {
-//                //查询所有同级工序
-//                List<ApsProcessOperationDo> list = apsProcessOperationService.list(new QueryWrapper<ApsProcessOperationDo>().lambda().eq(ApsProcessOperationDo::getPreviousprocessid, apsProcessOperationDo.getPreviousprocessid()));
-//                List<String> processIdList = list.stream().map(ApsProcessOperationDo::getId).collect(Collectors.toList());
-//                if (StringUtils.isNotBlank(recordsDo.getBatchnumber())) {
-//                    //更新所有同级工序作业的明细,增加批次号
-//                    apsProcessOperationDao.updateBatchNumberByProcessList(recordsDo.getBatchnumber(), processIdList);
-//                }
-//
-//            }
-//            /**
-//             * 如果该工序作业明细有前道工序作业明细,则将前道工序作业明细的所有后道工序作业明细的待加工料卷批次号加上“{批次号},”
-//             */
-//            if (ObjectUtil.isNotEmpty(equDo.getPreviousprocessesids()) && ObjectUtil.isNotEmpty(recordsDo.getBatchnumber())) {
-//                apsProcessOperationDao.updateBatchNumberByPrevious(recordsDo.getBatchnumber(), equDo.getPreviousprocessesids());
-//            }
-//            /**
-//             * 如果该工序作业明细没有前道工序作业明细,则该作业明细对应作业的所有作业明细的待加工料卷批次号加上“{批次号},”
-//             */
-//            if (ObjectUtil.isEmpty(equDo.getPreviousprocessesids()) && ObjectUtil.isNotEmpty(recordsDo.getBatchnumber())) {
-//                //更新坯料计划的第一道工序作业的所有工序作业明细的待加工料卷批次号=领料批次号逗号拼接
-//                apsProcessOperationProcessEquService.update(new UpdateWrapper<ApsProcessOperationProcessEquDo>().lambda()
-//                        .setSql("BACHMATERIALPROCESS = IF(BACHMATERIALPROCESS is null || BACHMATERIALPROCESS = '','" + String.join(",", batchNumberList) + "',CONCAT(BACHMATERIALPROCESS,'," + String.join(",", batchNumberList) + "'))")
-//                        .eq(ApsProcessOperationProcessEquDo::getDeleted, "0")
-//                        .eq(ApsProcessOperationProcessEquDo::getProcessid, recordsDo.getProcessoperationid()));
-//            }
             /**
              * 需求变更:将当前作业明细的待加工料卷批次号加上“{批次号}”
              */
@@ -336,10 +283,20 @@ public class ApsReportRecordsServiceImpl extends ServiceImpl<ApsReportRecordsDao
                 this.cancelNumber(equDo);
             }
         }
-
-        //如果当前工序作业明细  不存在(其他合并工序作业明细,并且其他合并作业明细的 待报工记录ID 不为空) 则炉号-1
-        List<ApsProcessOperationProcessEquDo> equDoMergeStartingList = this.baseMapper.selectOtherMergeProcessStarting(equDo.getId(), equDo.getProcessdeviceid());
-        if (equDoMergeStartingList.size() <= 0) {
+        // 如果作业的加工方式是合并加工,
+        // 并且没有其他同设备同炉次的报工记录已经开工或报工,
+        // 则报工记录对应开工时间的月份,加工设备对应熔炉的该月该熔炉的炉次号减1
+        if (apsProcessOperationDo.getProcessway().equals("合并加工")) {
+            List<ApsProcessOperationProcessEquDo> equDoMergeStartingList = this.baseMapper.selectOtherMergeProcessEquByHeat(equDo.getId(), equDo.getProcessdeviceid(), recordsDo.getHeatnumber());
+            if (equDoMergeStartingList.size() <= 0) {
+                //炉号-1
+                //加工设备ID
+                String processdeviceid = equDo.getProcessdeviceid();
+                //在流水表中的 标识
+                String moduleCode = "aps_report_output_heat_" + processdeviceid;
+                apsProcessOperationProcessEquDao.updateSerialNumber(moduleCode, 1);
+            }
+        } else {
             //炉号-1
             //加工设备ID
             String processdeviceid = equDo.getProcessdeviceid();
@@ -454,63 +411,26 @@ public class ApsReportRecordsServiceImpl extends ServiceImpl<ApsReportRecordsDao
                 List<ApsProcessOperationProcessEquDo> sameDeviceList = apsProcessOperationProcessEquDao.selectHaveOtherDevice(processdeviceid, apsProcessOperationProcessEquDoId);
                 if (!sameDeviceList.isEmpty()) {
                     //判断被占用的是否都是合并加工的
-                    List<String> processIdList = sameDeviceList.stream().map(ApsProcessOperationProcessEquDo::getProcessid).collect(Collectors.toList());
-                    List<ApsProcessOperationDo> apsProcessOperationDos = new ArrayList<>(apsProcessOperationService.listByIds(processIdList));
-                    long count = apsProcessOperationDos.stream().filter(item -> !item.getProcessway().equals("合并加工")).count();
+                    // 如果作业的加工方式是合并加工,
+                    // 并且工序作业明细加工设备已有其他作业明细正在加工(待报工记录ID不为空),
+                    // 并且正在加工的作业明细同炉次(原计划开工时间相同)有其他作业明细已经报工,
+                    // 则错误提示:正在加工的炉次还未报工完,不能开工新的炉次
+                    long count = sameDeviceList.stream().filter(item -> ObjectUtil.isNotEmpty(item.getOldplanstartdate()) && item.getOldplanstartdate().equals(apsProcessOperationProcessEquDo.getPlanstartdate())).count();
+//                    List<String> processIdList = sameDeviceList.stream().map(ApsProcessOperationProcessEquDo::getProcessid).collect(Collectors.toList());
+//                    List<ApsProcessOperationDo> apsProcessOperationDos = new ArrayList<>(apsProcessOperationService.listByIds(processIdList));
+//                    long count = apsProcessOperationDos.stream().filter(item -> !item.getProcessway().equals("合并加工")).count();
                     if (count > 0) {
-                        log.error("存在其他已占用设备:{},不为合并加工工序的作业:{}", processdeviceid, processIdList);
+                        log.error("存在其他已占用设备:{},不为合并加工工序(原计划开工时间相同)的作业,计划开工时间:{}", processdeviceid, apsProcessOperationProcessEquDo.getPlanstartdate());
                         return R.error("该设备当前加工中的作业还未报工,不能开工新的作业");
                     }
                 }
             }
-//            //存在计划开工时间不同(非合并作业) 并且加工设备正在使用的作业明细数量
-//            int count = apsProcessOperationProcessEquDao.selectOtherDeviceCount(processdeviceid, apsProcessOperationProcessEquDoId, apsProcessOperationProcessEquDo.getPlanstartdate());
-//            if (count > 0) {
-//                return R.error("该设备当前加工中的作业还未报工,不能开工新的作业");
-//            }
-//            List<ApsProcessOperationProcessEquDo> list = apsProcessOperationProcessEquDao.selectOtherDeviceList(processdeviceid, apsProcessOperationProcessEquDoId);
-////        List<ApsProcessOperationProcessEquDo> list = apsProcessOperationProcessEquService.list(
-////                new QueryWrapper<ApsProcessOperationProcessEquDo>().lambda()
-////                        .eq(ApsProcessOperationProcessEquDo::getProcessdeviceid, processdeviceid)//当前工序作业的作业明细的 加工设备
-////                        .ne(ApsProcessOperationProcessEquDo::getId, apsProcessOperationProcessEquDoId)//对应的其他工序作业的作业明细
-////                        .isNotNull(ApsProcessOperationProcessEquDo::getWaitreportid)//待报工记录ID不为空
-////        );
-//            //存在已使用,判断是否是合并作业 (计划开工时间相同)
-//            if (ObjectUtil.isNotEmpty(list)) {
-//                //已开工的作业明细的计划开工时间
-//                Date planstartdate = list.get(0).getPlanstartdate();
-//                //开工时间不用
-//                if (planstartdate.compareTo(apsProcessOperationProcessEquDo.getPlanstartdate()) != 0) {
-//                    return R.error("该设备当前加工中的作业还未报工,不能开工新的作业");
-//                }
-//            }
-
 
-//        //设备的待加工ID
-//        String waitReportId = organizationCodeAndDeviceCodeVo.getWaitReportId();
-//        //如果工序作业加工设备已有其他作业状态为已开工,错误提示:该设备当前加工中的作业还未报工,不能开工新的作业
-//        if (ObjectUtil.isNotEmpty(waitReportId)) {
-//            String oldWaitReportId = waitReportId.split(",")[0];
-//            //查询当前报工的工序作业明细详情
-//            ApsReportRecordsDo apsReportRecordsDo = this.getById(oldWaitReportId);
-//            String processequid = apsReportRecordsDo.getProcessequid();
-//            ApsProcessOperationProcessEquDo doingProcessEqu = apsProcessOperationProcessEquService.getById(processequid);
-//            //计划开工时间不相等,表示不是合并工序
-//            if (doingProcessEqu.getPlanstartdate().compareTo(apsProcessOperationProcessEquDo.getPlanstartdate()) != 0) {
-//                return R.error("该设备当前加工中的作业还未报工,不能开工新的作业");
-//            }
-//        }
-
-
-            //获取当前用户相关信息
-//            SysUserVo currentUser = CXCommonUtils.getCurrentUser();
             String tenantId = CXCommonUtils.getCurrentUserFactoryId(currentUser);
 
             //查询此工序对应工艺步骤中,对应设备的设备参数
             String equparames = "";
             //查询工序步骤
-//        String process = apsProcessOperationDo.getProcess();
-//        String processname = apsProcessOperationDo.getProcessname();
             String stepnum = apsProcessOperationDo.getStepnum();
             ApsCraftStepDo craftStepDo = apsCraftStepService.getOne(new QueryWrapper<ApsCraftStepDo>().lambda().eq(ApsCraftStepDo::getStepnum, stepnum));
             if (ObjectUtil.isNotEmpty(craftStepDo)) {
@@ -552,7 +472,55 @@ public class ApsReportRecordsServiceImpl extends ServiceImpl<ApsReportRecordsDao
              * 新增需求:新增字段保存
              */
             insertReportNew(apsReportRecordsDo, apsProductionOrderDo, apsBlankOrderDo, apsProcessOperationDo, apsProcessOperationProcessEquDo, aspCheckItemsDo);
+            //============开工时,生成炉号和批次号=============
+            //获取设备/炉 的炉号(每月、每个设备/炉 更新)
+            String heatNumber = "";//初始化炉号
+            //如果作业明细对应作业的加工方式=合并加工,
+            // 并且该设备有其他作业明细的报工记录的报工状态=已开工,
+            // 则炉次号=该合并作业明细的报工状态是已开工的报工记录的炉次号
+            boolean createNewHeat = false;
+            //合并作业明细的实际开工时间
+            Date mergeActualStartDate = DateUtil.date();
+            if (apsProcessOperationDo.getProcessway().equals("合并加工")) {
+                List<ApsProcessOperationProcessEquDo> apsProcessEquMergeStartingList = this.baseMapper.selectOtherMergeProcessStarting(apsProcessOperationProcessEquDo.getId(), apsProcessOperationProcessEquDo.getProcessdeviceid());
+                if (!apsProcessEquMergeStartingList.isEmpty()) {
+                    //合并工序作业明细
+                    ApsProcessOperationProcessEquDo equDo = apsProcessEquMergeStartingList.get(0);
+                    //查询该合并工序作业明细的待报工记录ID
+                    String waitreportid = equDo.getWaitreportid();
+                    mergeActualStartDate = equDo.getActualstartdate();
+                    //待报工记录详情
+                    ApsReportRecordsDo aDo = this.getById(waitreportid);
+                    heatNumber = aDo.getHeatnumber();
+                } else {
+                    createNewHeat = true;
+                }
+            } else {
+                createNewHeat = true;
+            }
+            if (createNewHeat) {
+                //调用通用接口生成炉号
+                SysSerialVo vo = new SysSerialVo();
+                vo.setModulecode("aps_report_output_heat_" + apsProcessOperationProcessEquDo.getProcessdeviceid());
+                vo.setRuleTemplateStr("@{serialNumber:#000}");
+                vo.setResetrule("date:yyyyMM");
+                vo.setIfautomaticreset("y");
+                vo.setInitValue(0L);
+//                Map<String, Object> codeData = cxAdminFeginClient.getSerialNumberCode(vo).getData();
+                heatNumber = sysSerialNumberService.getCodeByTemplate(vo);
+                if (StringUtils.isNotBlank(heatNumber)) {
+                    //判断如果heatNumber如果为000时再次调用序列号接口/修复跨月流水号问题
+                    if ("000".equals(heatNumber)) {
+//                        codeData = cxAdminFeginClient.getSerialNumberCode(vo).getData();
+                        heatNumber = sysSerialNumberService.getCodeByTemplate(vo);
+                    }
+                }
+            }
+
+            apsReportRecordsDo.setHeatnumber(heatNumber);
 
+            //保存主表
+            this.save(apsReportRecordsDo);
             //=================更新工序作业明细的报工ID、已开工卷数============
             //将报工记录ID存入工序作业的设备子表中
             ApsProcessOperationProcessEquDo needUpdateProcessOperationProcessEqu = new ApsProcessOperationProcessEquDo();
@@ -567,9 +535,20 @@ public class ApsReportRecordsServiceImpl extends ServiceImpl<ApsReportRecordsDao
             needUpdateProcessOperationProcessEqu.setStartingroll(newStartingRoll);
             if (newStartingRoll.equals(1)) {
                 //更新实际开工时间
+                Date startWorkTime = DateUtil.date();
+                //如果炉次号是新开的炉次号,则实际开工时间=报工记录的开工时间;
+                //如果炉次号是已开工的炉次号,则实际开工时间=该合并作业明细的实际开工时间;
+                if (createNewHeat) {
+                    if (ObjectUtil.isEmpty(apsReportRecordsDo.getStartworktime())) {
+                        startWorkTime = apsReportRecordsDo.getStartworktime();
+                    }
+                } else {
+                    startWorkTime = mergeActualStartDate;
+                }
+
                 needUpdateProcessOperationProcessEqu.setOldplanstartdate(apsProcessOperationProcessEquDo.getPlanstartdate());
                 needUpdateProcessOperationProcessEqu.setOldplanenddate(apsProcessOperationProcessEquDo.getPlanenddate());
-                needUpdateProcessOperationProcessEqu.setActualstartdate(DateUtil.date());
+                needUpdateProcessOperationProcessEqu.setActualstartdate(startWorkTime);
                 needUpdateProcessOperationProcessEqu.setPlanenddate(DateUtil.offsetMinute(needUpdateProcessOperationProcessEqu.getActualstartdate(), (int) DateUtil.between(apsProcessOperationProcessEquDo.getPlanstartdate(), apsProcessOperationProcessEquDo.getPlanenddate(), DateUnit.MINUTE)));
                 needUpdateProcessOperationProcessEqu.setPlanstartdate(needUpdateProcessOperationProcessEqu.getActualstartdate());
             }
@@ -709,42 +688,7 @@ public class ApsReportRecordsServiceImpl extends ServiceImpl<ApsReportRecordsDao
 //        if (!r.getCode().equals("200")) {
 //            return R.error(r.getMsg());
 //        }
-            //============开工时,生成炉号和批次号=============
-            //获取设备/炉 的炉号(每月、每个设备/炉 更新)
-            String heatNumber;//初始化炉号
-            //如果存在其他合并工序,并且其他合并工序已开工,则不去生成新的 炉次号 使用其他合并工序的 开工记录的 炉次号
-            List<ApsProcessOperationProcessEquDo> apsProcessEquMergeStartingList = this.baseMapper.selectOtherMergeProcessStarting(apsProcessOperationProcessEquDo.getId(), apsProcessOperationProcessEquDo.getProcessdeviceid());
-
-            if (apsProcessEquMergeStartingList.size() > 0) {
-                //合并工序作业明细
-                ApsProcessOperationProcessEquDo equDo = apsProcessEquMergeStartingList.get(0);
-                //查询该合并工序作业明细的待报工记录ID
-                String waitreportid = equDo.getWaitreportid();
-                //待报工记录详情
-                ApsReportRecordsDo aDo = this.getById(waitreportid);
-                heatNumber = aDo.getHeatnumber();
-            } else {
-                //调用通用接口生成炉号
-                SysSerialVo vo = new SysSerialVo();
-                vo.setModulecode("aps_report_output_heat_" + apsProcessOperationProcessEquDo.getProcessdeviceid());
-                vo.setRuleTemplateStr("@{serialNumber:#000}");
-                vo.setResetrule("date:yyyyMM");
-                vo.setIfautomaticreset("y");
-                vo.setInitValue(0L);
-//                Map<String, Object> codeData = cxAdminFeginClient.getSerialNumberCode(vo).getData();
-                heatNumber = sysSerialNumberService.getCodeByTemplate(vo);
-                if (StringUtils.isNotBlank(heatNumber)) {
-                    //判断如果heatNumber如果为000时再次调用序列号接口/修复跨月流水号问题
-                    if ("000".equals(heatNumber)) {
-//                        codeData = cxAdminFeginClient.getSerialNumberCode(vo).getData();
-                        heatNumber = sysSerialNumberService.getCodeByTemplate(vo);
-                    }
-                }
-            }
 
-            apsReportRecordsDo.setHeatnumber(heatNumber);
-            //保存主表
-            this.save(apsReportRecordsDo);
 
             OrganizationCodeAndDeviceCodeVo organizationCodeAndDeviceCodeVo = this.baseMapper.selectOrganizationCodeAndDeviceCode(apsProcessOperationProcessEquDo.getProcessdeviceid());
 
@@ -1084,8 +1028,12 @@ public class ApsReportRecordsServiceImpl extends ServiceImpl<ApsReportRecordsDao
             //未完工卷数-已取消卷数
             int needDoRoll = unfinishroll - apsProcessOperationProcessEquDo.getCancelroll();
             if (needDoRoll <= 0) {
+                Date finishWorkTime = DateUtil.date();
+                if (ObjectUtil.isEmpty(apsReportRecordsDo.getReportworktime())) {
+                    finishWorkTime = apsReportRecordsDo.getReportworktime();
+                }
                 processEquWrapper.set(ApsProcessOperationProcessEquDo::getClosestatus, "已完工")
-                        .set(ApsProcessOperationProcessEquDo::getActualfinishdate, DateUtil.date())
+                        .set(ApsProcessOperationProcessEquDo::getActualfinishdate, finishWorkTime)
                         .set(ApsProcessOperationProcessEquDo::getWorkstatus, "已完工");
             }
             if (needDoRoll > 0) {
@@ -1140,10 +1088,13 @@ public class ApsReportRecordsServiceImpl extends ServiceImpl<ApsReportRecordsDao
             } else {
                 if (newLeaveWaitJobRoll == 0) {
                     processEquWrapper.set(ApsProcessOperationProcessEquDo::getClosestatus, "已完工");
-                    Date now = new Date();
-                    processEquWrapper.set(ApsProcessOperationProcessEquDo::getActualfinishdate, now);
-                    processEquWrapper.set(ApsProcessOperationProcessEquDo::getPlanstartdate, DateUtil.offsetMinute(now, -1 * (int) DateUtil.between(apsProcessOperationProcessEquDo.getPlanenddate(), apsProcessOperationProcessEquDo.getPlanstartdate(), DateUnit.MINUTE)));
-                    processEquWrapper.set(ApsProcessOperationProcessEquDo::getPlanenddate, now);
+                    Date finishWorkTime = DateUtil.date();
+                    if (ObjectUtil.isEmpty(apsReportRecordsDo.getStartworktime())) {
+                        finishWorkTime = apsReportRecordsDo.getStartworktime();
+                    }
+                    processEquWrapper.set(ApsProcessOperationProcessEquDo::getActualfinishdate, finishWorkTime);
+                    processEquWrapper.set(ApsProcessOperationProcessEquDo::getPlanstartdate, DateUtil.offsetMinute(finishWorkTime, -1 * (int) DateUtil.between(apsProcessOperationProcessEquDo.getPlanenddate(), apsProcessOperationProcessEquDo.getPlanstartdate(), DateUnit.MINUTE)));
+                    processEquWrapper.set(ApsProcessOperationProcessEquDo::getPlanenddate, finishWorkTime);
 
                 }
             }
@@ -1487,17 +1438,19 @@ public class ApsReportRecordsServiceImpl extends ServiceImpl<ApsReportRecordsDao
         String processequid = req.getProcessequid();
         //当前报工的作业明细的详情
         ApsProcessOperationProcessEquDo apsProcessOperationProcessEquDo = apsProcessOperationProcessEquService.getById(processequid);
-        //查询其他 与当前作业明细计划开工时间相同,并且未开工(待报工记录ID为空)的作业明细
-        List<ApsProcessOperationProcessEquDo> list = this.baseMapper.selectOtherMergeProcessEqu(apsProcessOperationProcessEquDo.getId(), apsProcessOperationProcessEquDo.getProcessdeviceid(), apsProcessOperationProcessEquDo.getPlanstartdate());
+        //当前报工的作业详情
+        ApsProcessOperationDo apsProcessOperationDo = apsProcessOperationService.getById(apsProcessOperationProcessEquDo.getProcessid());
         CheckMergeProcessResopnse res = new CheckMergeProcessResopnse();
-        if (list.size() > 0) {
-            //查询当前工序作业明细的工序详情
-            ApsProcessOperationDo apsProcessOperationDo = apsProcessOperationService.getById(req.getProcessoperationid());
-            res.setNeedWarning(true);
-            res.setWarningMessage("该合并作业" + apsProcessOperationDo.getProcess() + "还有其他作业需要一起开工,请及时开工");
-            return R.ok(res);
+        //该作业的加工方式是合并加工,
+        if (apsProcessOperationDo.getProcessway().equals("合并加工")) {
+            // 并且有其他未开工的计划开工时间=该报工作业明细原计划开工时间的作业明细
+            List<ApsProcessOperationProcessEquDo> list = this.baseMapper.selectOtherMergeProcessEqu(apsProcessOperationProcessEquDo.getId(), apsProcessOperationProcessEquDo.getProcessdeviceid(), apsProcessOperationProcessEquDo.getOldplanstartdate());
+            if (!list.isEmpty()) {
+                res.setNeedWarning(true);
+                res.setWarningMessage("该合并作业" + apsProcessOperationDo.getProcess() + "还有其他作业需要一起开工,请及时开工");
+                return R.ok(res);
+            }
         }
-
         return R.ok(res);
     }
 
@@ -1619,19 +1572,31 @@ public class ApsReportRecordsServiceImpl extends ServiceImpl<ApsReportRecordsDao
 
             //============开工时,生成炉号和批次号=============
             //获取设备/炉 的炉号(每月、每个设备/炉 更新)
-            String heatNumber;//初始化炉号
-            //如果存在其他合并工序,并且其他合并工序已开工,则不去生成新的 炉次号 使用其他合并工序的 开工记录的 炉次号
-            List<ApsProcessOperationProcessEquDo> apsProcessEquMergeStartingList = this.baseMapper.selectOtherMergeProcessStarting(apsProcessOperationProcessEquDo.getId(), apsProcessOperationProcessEquDo.getProcessdeviceid());
-
-            if (apsProcessEquMergeStartingList.size() > 0) {
-                //合并工序作业明细
-                ApsProcessOperationProcessEquDo equDo = apsProcessEquMergeStartingList.get(0);
-                //查询该合并工序作业明细的待报工记录ID
-                String waitreportid = equDo.getWaitreportid();
-                //待报工记录详情
-                ApsReportRecordsDo aDo = this.getById(waitreportid);
-                heatNumber = aDo.getHeatnumber();
+            String heatNumber = "";//初始化炉号
+            //如果作业明细对应作业的加工方式=合并加工,
+            // 并且该设备有其他作业明细的报工记录的报工状态=已开工,
+            // 则炉次号=该合并作业明细的报工状态是已开工的报工记录的炉次号
+            boolean createNewHeat = false;
+            //合并作业明细的实际开工时间
+            Date mergeActualStartDate = DateUtil.date();
+            if (apsProcessOperationDo.getProcessway().equals("合并加工")) {
+                List<ApsProcessOperationProcessEquDo> apsProcessEquMergeStartingList = this.baseMapper.selectOtherMergeProcessStarting(apsProcessOperationProcessEquDo.getId(), apsProcessOperationProcessEquDo.getProcessdeviceid());
+                if (!apsProcessEquMergeStartingList.isEmpty()) {
+                    //合并工序作业明细
+                    ApsProcessOperationProcessEquDo equDo = apsProcessEquMergeStartingList.get(0);
+                    //查询该合并工序作业明细的待报工记录ID
+                    String waitreportid = equDo.getWaitreportid();
+                    mergeActualStartDate = equDo.getActualstartdate();
+                    //待报工记录详情
+                    ApsReportRecordsDo aDo = this.getById(waitreportid);
+                    heatNumber = aDo.getHeatnumber();
+                } else {
+                    createNewHeat = true;
+                }
             } else {
+                createNewHeat = true;
+            }
+            if (createNewHeat) {
                 //调用通用接口生成炉号
                 SysSerialVo vo = new SysSerialVo();
                 vo.setModulecode("aps_report_output_heat_" + apsProcessOperationProcessEquDo.getProcessdeviceid());
@@ -1790,72 +1755,6 @@ public class ApsReportRecordsServiceImpl extends ServiceImpl<ApsReportRecordsDao
                     apsReportBlankCompentService.saveBatch(needAddList);
                 }
             }
-//            //工序作业的是否坯料工序=是 时,根据客户合金成分设置自动生成
-//            if (apsProcessOperationDo.getIfblankprocess().equals("是")) {
-//                //工序作业的合金
-//                String metal = apsProcessOperationDo.getMetal();
-//                //订单的客户ID
-//                String customid = apsProductionOrderDo.getCustomid();
-//                String alloyId = "";
-//                //查询合金对应的所有主表信息
-//                List<ApsAlloyDo> apsAlloyDoList = apsAlloyService.list(new QueryWrapper<ApsAlloyDo>().lambda().eq(ApsAlloyDo::getAlloy, metal));
-//                if (ObjectUtil.isNotEmpty(apsAlloyDoList)) {
-//                    //查询客户标准
-//                    List<ApsAlloyDo> collect = apsAlloyDoList.stream().filter(item -> ObjectUtil.isNotEmpty(item.getCustomerid()) && item.getCustomerid().contains(customid)).collect(Collectors.toList());
-//                    if (ObjectUtil.isNotEmpty(collect)) {
-//                        alloyId = collect.get(0).getId();
-//                    } else {//查询国标
-//                        List<ApsAlloyDo> collect1 = apsAlloyDoList.stream().filter(item -> ObjectUtil.isEmpty(item.getCustomerid())).collect(Collectors.toList());
-//                        if (ObjectUtil.isNotEmpty(collect1)) {
-//                            alloyId = collect1.get(0).getId();
-//                        }
-//                    }
-//                }
-//                //查询合金成分要求
-//                if (ObjectUtil.isNotEmpty(alloyId)) {
-//                    List<ApsAlloyCompositionDo> apsAlloyCompositionDoList = apsAlloyCompositionService.list(new QueryWrapper<ApsAlloyCompositionDo>().lambda().eq(ApsAlloyCompositionDo::getAlloyid, alloyId));
-//
-//                    if (ObjectUtil.isNotEmpty(apsAlloyCompositionDoList)) {
-//                        List<ApsReportBlankCompentDo> needInsertApsReportBlankCompentList = new LinkedList<>();
-//                        for (ApsAlloyCompositionDo apsAlloyCompositionDo : apsAlloyCompositionDoList) {
-//                            ApsReportBlankCompentDo apsReportBlankCompentDo = new ApsReportBlankCompentDo();
-//                            apsReportBlankCompentDo.setId(SecurityUtil.getUUID());
-//                            apsReportBlankCompentDo.setTenantid(tenantId);
-//                            apsReportBlankCompentDo.setMainid(apsReportRecordsDo.getId());
-//                            apsReportBlankCompentDo.setCompent(apsAlloyCompositionDo.getIngredient());
-//                            apsReportBlankCompentDo.setStartproportion(apsAlloyCompositionDo.getLeftproportion());
-//                            apsReportBlankCompentDo.setEndproportion(apsAlloyCompositionDo.getRightproportion());
-//                            needInsertApsReportBlankCompentList.add(apsReportBlankCompentDo);
-//                        }
-//                        if (ObjectUtil.isNotEmpty(needInsertApsReportBlankCompentList)) {
-//                            apsReportBlankCompentService.saveBatch(needInsertApsReportBlankCompentList);
-//                        }
-//
-//                    }
-//                }
-//            } else {//不是坯料工序,根据输入物料批次号,查询来源报工的坯料成分,copy一份
-//                String inputBatchNumber = req.getInputBatchNumberList().get(0);
-//                //查询上一个的报工ID
-//                String lastReportRecordId = this.baseMapper.selectLastReoprtRecordByBatchNumber(inputBatchNumber);
-//                if (ObjectUtil.isNotEmpty(lastReportRecordId)) {
-//                    //查询上一个报工的坯料成分
-//                    List<ApsReportBlankCompentDo> apsReportBlankCompentDoList = apsReportBlankCompentService.list(new QueryWrapper<ApsReportBlankCompentDo>().lambda().eq(ApsReportBlankCompentDo::getMainid, lastReportRecordId));
-//                    //复制新增
-//                    List<ApsReportBlankCompentDo> needAddList = new LinkedList<>();
-//                    for (ApsReportBlankCompentDo apsReportBlankCompentDo : apsReportBlankCompentDoList) {
-//                        ApsReportBlankCompentDo needAdd = new ApsReportBlankCompentDo();
-//                        needAdd.setId(SecurityUtil.getUUID());
-//                        needAdd.setTenantid(tenantId);
-//                        needAdd.setMainid(apsReportRecordsDo.getId());
-//                        needAdd.setCompent(apsReportBlankCompentDo.getCompent());
-//                        needAdd.setStartproportion(apsReportBlankCompentDo.getStartproportion());
-//                        needAdd.setEndproportion(apsReportBlankCompentDo.getEndproportion());
-//                        needAdd.setActualproportion(apsReportBlankCompentDo.getActualproportion());
-//                        needAddList.add(needAdd);
-//                    }
-//                    apsReportBlankCompentService.saveBatch(needAddList);
-//                }
-//            }
 
             /**
              * 检查每个输入批次号,
@@ -1863,31 +1762,6 @@ public class ApsReportRecordsServiceImpl extends ServiceImpl<ApsReportRecordsDao
              * 查找输入物料所有后道作业明细,即前道作业明细的所有后道作业明细中,
              * 其工序作业的输入物料ID和报工记录的工序作业的输入物料ID相同的所有作业明细,将这些作业明细的待加工料卷批次号去掉“{输入批次号},”
              */
-            //更新待加工料卷批次号
-//            if (ObjectUtil.isNotEmpty(apsProcessOperationProcessEquDo.getPreviousprocessesids())) {
-//                List<ApsProcessOperationProcessEquDo> needUpdateBatchNumber = apsProcessOperationProcessEquService.list(new QueryWrapper<ApsProcessOperationProcessEquDo>().lambda().eq(ApsProcessOperationProcessEquDo::getPreviousprocessesids, apsProcessOperationProcessEquDo.getPreviousprocessesids()));
-//                if (ObjectUtil.isNotEmpty(needUpdateBatchNumber)) {
-//                    List<ApsProcessOperationProcessEquDo> needUpdateList = new LinkedList<>();
-//
-//                    for (ApsProcessOperationProcessEquDo processOperationProcessEquDo : needUpdateBatchNumber) {
-//                        List<String> oldList = new LinkedList<>();
-//                        //原待加工批次号不为空
-//                        if (ObjectUtil.isNotEmpty(processOperationProcessEquDo.getBachmaterialprocess())) {
-//                            oldList = new LinkedList<>(Arrays.asList(processOperationProcessEquDo.getBachmaterialprocess().split(",")));
-//                            oldList.removeAll(inputBatchNumberList);
-//
-//                            String newBatch = String.join(",", oldList);
-//                            ApsProcessOperationProcessEquDo needUpdate = new ApsProcessOperationProcessEquDo();
-//                            needUpdate.setId(processOperationProcessEquDo.getId());
-//                            needUpdate.setBachmaterialprocess(newBatch);
-//                            needUpdateList.add(needUpdate);
-//                        }
-//                    }
-//                    if (ObjectUtil.isNotEmpty(needUpdateList)) {
-//                        apsProcessOperationProcessEquService.updateBatchById(needUpdateList);
-//                    }
-//                }
-//            }
             /**
              * 需求变更:待加工料卷批次号已经分配到对应作业明细不用删除兄弟作业明细的待加工料卷批次号仅删除当前作业作业明细的待加工料卷批次号
              * 检查完待加工料卷批次号是否改变后,立即更新待加工料卷批次号
@@ -1932,9 +1806,20 @@ public class ApsReportRecordsServiceImpl extends ServiceImpl<ApsReportRecordsDao
              * 作业状态=加工中
              */
             if (apsProcessOperationProcessEquDo.getStartingroll().equals(0)) {
+                //更新实际开工时间
+                Date startWorkTime = DateUtil.date();
+                //如果炉次号是新开的炉次号,则实际开工时间=报工记录的开工时间;
+                //如果炉次号是已开工的炉次号,则实际开工时间=该合并作业明细的实际开工时间;
+                if (createNewHeat) {
+                    if (ObjectUtil.isEmpty(apsReportRecordsDo.getStartworktime())) {
+                        startWorkTime = apsReportRecordsDo.getStartworktime();
+                    }
+                } else {
+                    startWorkTime = mergeActualStartDate;
+                }
                 needUpdateProcessEqu.setOldplanstartdate(apsProcessOperationProcessEquDo.getPlanstartdate());
                 needUpdateProcessEqu.setOldplanenddate(apsProcessOperationProcessEquDo.getPlanenddate());
-                needUpdateProcessEqu.setActualstartdate(DateUtil.date());
+                needUpdateProcessEqu.setActualstartdate(startWorkTime);
                 needUpdateProcessEqu.setPlanenddate(DateUtil.offsetMinute(needUpdateProcessEqu.getActualstartdate(), (int) DateUtil.between(apsProcessOperationProcessEquDo.getPlanstartdate(), apsProcessOperationProcessEquDo.getPlanenddate(), DateUnit.MINUTE)));
                 needUpdateProcessEqu.setPlanstartdate(needUpdateProcessEqu.getActualstartdate());
                 needUpdateProcessEqu.setWorkstatus("加工中");

+ 6 - 1
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/service/impl/ApsServiceImpl.java

@@ -11,6 +11,7 @@ import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.rongwei.bscommon.sys.dao.ApsBlankOrderDao;
+import com.rongwei.bscommon.sys.dao.ApsProcessOperationProcessEquDao;
 import com.rongwei.bscommon.sys.fegin.RwApsServer;
 import com.rongwei.bscommon.sys.service.*;
 import com.rongwei.bsentity.domain.*;
@@ -81,6 +82,8 @@ public class ApsServiceImpl implements ApsService {
     private ApsProcessOperationEquService apsProcessOperationEquService;
     @Autowired
     private ApsProcessOperationProcessEquService apsProcessOperationProcessEquService;
+    @Autowired
+    private ApsProcessOperationProcessEquDao apsProcessOperationProcessEquDao;
 
     /**
      * Aps排程
@@ -782,6 +785,8 @@ public class ApsServiceImpl implements ApsService {
                 } else {
                     apsBlankOrderService.apsAfter(productionScheduleRetVo, apsBlankOrders, currentUser, apsType);
                 }
+                //还原排程过程中,开工/报工的作业的计划时间
+                apsProcessOperationProcessEquDao.repairePlanStartDate();
 
                 if (StrUtil.isNotBlank(productionScheduleRetVo.getMsg())) {
                     // 排程异常后恢复历史排程结果为锁定状态
@@ -1055,7 +1060,7 @@ public class ApsServiceImpl implements ApsService {
 
             String[] sbIds = canchoosedeviceid.split(",");
             for (String equIds : sbIds) {
-                if (equIds.equals("0001be252874536843730b100017")) {
+                if (equIds.equals("0001be252874536843730b100190")) {
                     System.out.println(equIds);
                 }
                 String eqDateKey = apsPlanStartDateStr + " *** " + equIds;

+ 2 - 1
cx-aps/cx-aps-common/src/main/resources/mybatis/ApsBlankOrderDao.xml

@@ -507,7 +507,8 @@
                              INTERVAL GREATEST(ifnull(apo.MINFLOWWAITMIN,0), -- 最小流转等待时间
                                                if(apope.PROCESSWORKSHOPID!=preapope.PROCESSWORKSHOPID,#{workshopcross}, -- 车间流转时间
                                                   if(apope.PROCESSDEVICEID!=preapope.PROCESSDEVICEID,#{workshopin},0))) MINUTE -- 机台流转时间
-                    ) &lt;= #{chongpaiEndDate}) -- 调度结束时间之前可以开工
+                    ) &lt;= #{chongpaiEndDate} -- 调度结束时间之前可以开工
+                    AND DATE_ADD(preapope.PLANENDDATE, INTERVAL apo.MAXFLOWWAITMIN MINUTE) >= #{chongpaiStartDate})
             )
     </select>
     <select id="selectNeedRescheduleEqu3"

+ 22 - 0
cx-aps/cx-aps-common/src/main/resources/mybatis/ApsProcessOperationProcessEquDao.xml

@@ -387,6 +387,28 @@
             )
         </where>
     </update>
+    <update id="repairePlanStartDate">
+        update aps_process_operation_process_equ set
+         PLANENDDATE = ACTUALFINISHDATE,
+         PLANSTARTDATE = DATE_SUB(ACTUALFINISHDATE,INTERVAL TIMESTAMPDIFF(SECOND,OLDPLANSTARTDATE,OLDPLANENDDATE) SECOND)
+        where DELETED = 0
+          AND ACTUALFINISHDATE is not null
+          AND OLDPLANSTARTDATE is not null
+          AND OLDPLANENDDATE is not null
+          AND PLANENDDATE is not null
+          AND ACTUALFINISHDATE != PLANENDDATE;
+
+        update aps_process_operation_process_equ set
+         PLANSTARTDATE = ACTUALSTARTDATE,
+         PLANENDDATE = DATE_ADD(ACTUALSTARTDATE,INTERVAL TIMESTAMPDIFF(SECOND,OLDPLANSTARTDATE,OLDPLANENDDATE) SECOND)
+        where DELETED = 0
+          AND ACTUALFINISHDATE is null
+          AND ACTUALSTARTDATE is not null
+          AND OLDPLANSTARTDATE is not null
+          AND OLDPLANENDDATE is not null
+          AND PLANSTARTDATE is not null
+          AND ACTUALSTARTDATE != PLANSTARTDATE
+    </update>
     <select id="getOptionalEquipmentById" resultType="com.rongwei.bsentity.vo.OptionalEquipmentVo">
         SELECT
         CONCAT(aci.USEDEPTID, '/', aci.ID ) AS value ,

+ 14 - 2
cx-aps/cx-aps-common/src/main/resources/mybatis/ApsReportRecordsDao.xml

@@ -68,13 +68,25 @@
             apope.*
         FROM
             aps_process_operation_process_equ apope
-                JOIN aps_process_operation apo ON apope.PROCESSID = apo.ID AND apo.DELETED = 0
         WHERE
             apope.DELETED = 0
           AND apope.PROCESSDEVICEID = #{processdeviceid}
           AND apope.ID != #{id}
           AND apope.WAITREPORTID IS NOT NULL
           AND apope.WAITREPORTID != ''
-          AND apo.PROCESSWAY = '合并加工'
+    </select>
+    <select id="selectOtherMergeProcessEquByHeat"
+            resultType="com.rongwei.bsentity.domain.ApsProcessOperationProcessEquDo">
+        SELECT
+            apope.*
+        FROM
+            aps_process_operation_process_equ apope
+                LEFT JOIN aps_report_records arr ON arr.DELETED = 0 AND apope.ID = arr.PROCESSEQUID
+        WHERE
+            apope.DELETED = 0
+          AND apope.PROCESSDEVICEID = #{processdeviceid}
+          AND apope.ID != #{id}
+          AND apope.WORKSTATUS != '待开工'
+          AND arr.HEATNUMBER = #{heatnumber}
     </select>
 </mapper>

+ 45 - 0
cx-aps/cx-aps-entity/src/main/java/com/rongwei/bsentity/vo/ChangingScheduleVo.java

@@ -0,0 +1,45 @@
+package com.rongwei.bsentity.vo;
+
+import lombok.Data;
+
+import javax.validation.constraints.Future;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author :sc
+ * @since :2025/2/25
+ */
+@Data
+public class ChangingScheduleVo {
+    //明细ID集合
+    private List<String> processEquIdList;
+
+    /**
+     * 设备ID
+     */
+    @NotBlank(message = "设备必填")
+    private String equId;
+    /**
+     * 设备名称
+     */
+    @NotBlank(message = "设备必填")
+    private String equName;
+    /**
+     * 车间ID
+     */
+    @NotBlank(message = "车间必填")
+    private String workshopId;
+    /**
+     * 车间名称
+     */
+    @NotBlank(message = "车间必填")
+    private String workshopName;
+    /**
+     * 加工时间必填
+     */
+    @NotNull(message = "加工时间必填")
+    private Date processingTime;
+}

+ 11 - 0
cx-aps/cx-aps-server/src/main/java/com/rongwei/bsserver/controller/ApsProcessOperationProcessEquController.java

@@ -67,6 +67,17 @@ public class ApsProcessOperationProcessEquController {
         log.info("开始进行换线作业");
         return apsProcessOperationProcessEquService.changingWires(changingWiresVos);
     }
+    /**
+     * 排单
+     *
+     * @param req
+     * @return
+     */
+    @PostMapping("/scheduling")
+    public R scheduling(@RequestBody @Validated ChangingScheduleVo req) {
+        log.info("开始进行排单作业");
+        return apsProcessOperationProcessEquService.scheduling(req);
+    }
 
     /**
      * 换线获取可选设备