瀏覽代碼

Merge branch 'refs/heads/mode-min-unit' into mode-min-unit-xh

xiahan 1 年之前
父節點
當前提交
caf361ef93

+ 4 - 0
bs-common/src/main/java/com/rongwei/safecommon/utils/SaveConstans.java

@@ -787,6 +787,10 @@ public class SaveConstans {
          * 与加工设备其他作业加工时间重叠
          */
         public static final String EQ_TIME_CROSS = "与加工设备其他作业加工时间重叠";
+        /**
+         * 超出承诺交货期
+         */
+        public static final String EXCEEDING_THE_PROMISED_DELIVERY_DEADLINE = "超出承诺交货期";
 
     }
 

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

@@ -7,6 +7,7 @@ import com.rongwei.bsentity.domain.ApsProcessOperationProcessEquDo;
 import com.rongwei.bsentity.domain.AspCheckItemsDo;
 import com.rongwei.bsentity.vo.ApsBlankOrderVo;
 import com.rongwei.bsentity.vo.BlankIdAndProcessStatusVo;
+import com.rongwei.bsentity.vo.UpdateBlankDeliveryDateVo;
 import com.rongwei.bsentity.vo.WashingMetal;
 import org.apache.ibatis.annotations.Delete;
 import org.apache.ibatis.annotations.Param;
@@ -112,4 +113,6 @@ public interface ApsBlankOrderDao extends BaseMapper<ApsBlankOrderDo> {
 
     @Update("update aps_process_operation_process_equ set BACHMATERIALPROCESS = REPLACE(REPLACE(REPLACE(BACHMATERIALPROCESS,'${batchnumber},',''),',${batchnumber}',''),'${batchnumber}','') where DELETED = 0 AND PREVIOUSPROCESSESIDS = #{processoperationequid} AND PROCESSID IN (select ID from aps_process_operation where DELETED = 0 AND PLANINPUTID = #{joboutputmaterialid})")
     void updateBatchNumberByBorrow(@Param("batchnumber") String batchnumber, @Param("processoperationequid") String processoperationequid, @Param("joboutputmaterialid") String joboutputmaterialid);
+
+    List<UpdateBlankDeliveryDateVo> getBlankDeliveryDate(@Param("blankId") String blankId);
 }

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

@@ -30,7 +30,6 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import com.rongwei.bscommon.sys.service.ApsService;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -40,12 +39,13 @@ import java.util.*;
 import java.util.stream.Collectors;
 
 import static com.rongwei.bscommon.sys.service.impl.ApsProductionOrderServiceImpl.ERROR_MSG;
+import static com.rongwei.bscommon.sys.utils.ApsUtils.addNewConflictsDesc;
 import static com.rongwei.safecommon.utils.SaveConstans.DatePattern.DATE_PATTERN_YMDHMS;
+import static com.rongwei.safecommon.utils.SaveConstans.ForcedConflictsDescription.EXCEEDING_THE_PROMISED_DELIVERY_DEADLINE;
 import static com.rongwei.safecommon.utils.SaveConstans.JobStatus.JOBSTATUS_TO_BE_START;
 import static com.rongwei.safecommon.utils.SaveConstans.LockmarkType.LOCKMARK_N;
 import static com.rongwei.safecommon.utils.SaveConstans.LockmarkType.LOCKMARK_Y;
 import static com.rongwei.safecommon.utils.SaveConstans.ProductionStatus.*;
-
 import static com.rongwei.safecommon.utils.SaveConstans.SchedulstatusTyep.*;
 
 /**
@@ -2002,8 +2002,8 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
              * 如果有坯料计划的承诺交货期-止 < 排程交货期,错误提示:第{几}个坯料计划的承诺交货期-止不能早于排程交货期{排程交货期}
              */
             if (req.getCheckDevice()) {
-                if (ObjectUtil.isEmpty(apsBlankOrderDo.getPromisedateend())) {
-                    return R.error("请填写所有坯料计划的承诺交货期-止");
+                if (ObjectUtil.isEmpty(apsBlankOrderDo.getPromisedatestart()) || ObjectUtil.isEmpty(apsBlankOrderDo.getPromisedateend())) {
+                    return R.error("请填写所有坯料计划的承诺交货期");
                 }
                 if (ObjectUtil.isEmpty(apsBlankOrderDo.getScheduledateend())) {
                     return R.error("第" + j + "个坯料计划 排程交货期-止不能为空");
@@ -2532,4 +2532,67 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
         }
 
     }
+
+    /**
+     * 更新坯料计划交货期并增加响应冲突描述
+     *
+     * @return
+     */
+    public void updateBlankDeliveryDate(ApsBlankOrderDo apsBlankOrderDo, String id) {
+        if (apsBlankOrderDo == null) {
+            apsBlankOrderDo = this.getById(id);
+        }
+        if (apsBlankOrderDo == null) {
+            log.error("无法获取到坯料计划信息");
+            throw new CustomException("无法获取到坯料计划信息");
+        }
+        List<UpdateBlankDeliveryDateVo> blankDeliveryDate = this.getBaseMapper().getBlankDeliveryDate(apsBlankOrderDo.getId());
+        if (blankDeliveryDate.isEmpty()) {
+            return;
+        }
+        if(blankDeliveryDate.size()==1){
+            blankDeliveryDate.add(blankDeliveryDate.get(0));
+        }
+        // 排程交货期-起
+        Date startDate = timeAddHour(blankDeliveryDate.get(0).getPlanenddate(), blankDeliveryDate.get(0).getDeliverytime());
+        //排程交货期-止
+        Date endDate = timeAddHour(blankDeliveryDate.get(1).getPlanenddate(), blankDeliveryDate.get(0).getDeliverytime());
+        // 更新数据
+        this.update(new LambdaUpdateWrapper<ApsBlankOrderDo>().eq(ApsBlankOrderDo::getId, apsBlankOrderDo.getId())
+                .set(BaseDo::getDeleted, 0)
+                .set(apsBlankOrderDo.getPromisedatestart() == null, ApsBlankOrderDo::getPromisedatestart, timeAddHour(startDate, 48))
+                .set(apsBlankOrderDo.getPromisedateend() == null, ApsBlankOrderDo::getPromisedateend, timeAddHour(endDate, 48)));
+        apsBlankOrderDo.setPromisedatestart(timeAddHour(startDate, 48));
+        apsBlankOrderDo.setPromisedateend(timeAddHour(endDate, 48));
+        List<String> updateIds= new ArrayList<>();
+        if(startDate.compareTo(apsBlankOrderDo.getPromisedatestart())>0){
+            updateIds.add(blankDeliveryDate.get(0).getId());
+        }
+        if(endDate.compareTo(apsBlankOrderDo.getPromisedateend())>0){
+            updateIds.add(blankDeliveryDate.get(1).getId());
+        }
+        if(updateIds.isEmpty()){
+            return;
+        }
+        List<ApsProcessOperationProcessEquBackupDo> equBackupDos = apsProcessOperationProcessEquBackupDao.selectBatchIds(updateIds);
+        equBackupDos.forEach(data->{
+            data.setConflictdes(addNewConflictsDesc(data.getConflictdes(),EXCEEDING_THE_PROMISED_DELIVERY_DEADLINE));
+            if(StringUtils.isBlank(data.getConflictdes())&& StringUtils.isBlank(data.getSoftconflictdes())){
+                data.setHasconflict("n");
+            }else{
+                data.setHasconflict("y");
+            }
+        });
+        if(!equBackupDos.isEmpty()){
+            apsProcessOperationProcessEquBackupService.updateBatchById(equBackupDos);
+        }
+
+    }
+
+    public Date timeAddHour(Date date, int hour) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.add(Calendar.HOUR_OF_DAY, hour);
+        return calendar.getTime();
+    }
 }

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

@@ -31,6 +31,7 @@ import java.util.*;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 
+import static com.rongwei.bscommon.sys.utils.ApsUtils.addNewConflictsDesc;
 import static com.rongwei.safecommon.utils.SaveConstans.ForcedConflictsDescription.EQUIPMENT_RUN_TIME;
 import static com.rongwei.safecommon.utils.SaveConstans.ForcedConflictsDescription.EQ_TIME_CROSS;
 import static com.rongwei.safecommon.utils.SaveConstans.JobStatus.*;
@@ -44,13 +45,14 @@ import static com.rongwei.safecommon.utils.SaveConstans.ProductionStatus.*;
 @Service
 public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsProcessOperationProcessEquDao, ApsProcessOperationProcessEquDo>
         implements ApsProcessOperationProcessEquService {
+    public static final String CHANGING_WIRES_ERROR_MSG = "订单%s-%s的作业%s已完工,不能换线";
     private final Logger log = LoggerFactory.getLogger(this.getClass().getName());
     @Autowired
     private ApsProcessOperationProcessEquDao apsProcessOperationProcessEquDao;
     @Autowired
     private ApsProcessOperationService apsProcessOperationService;
     @Autowired
-    private ApsBlankOrderService apsBlankOrderService;
+    private ApsBlankOrderServiceImpl apsBlankOrderService;
     @Autowired
     private ApsProductionOrderService apsProductionOrderService;
     @Autowired
@@ -264,8 +266,6 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
             log.error("换线作业的工序作业不为空");
             return R.error("工序作业不能为空");
         }
-        // 对数据按照
-
         // 工序作业明细ID
         List<String> detailIds = changingWiresVos.stream().map(ChangingWiresVo::getId).collect(Collectors.toList());
         if (detailIds.isEmpty()) {
@@ -284,7 +284,6 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
             log.error("本次换线操作存在无法获取作业明细的数据");
             return R.error("本次换线操作存在无法获取作业明细的数据!请联系系统管理员");
         }
-
         // 校验是否存在已完工的工序作业
         boolean hasCompletedWork = apsProcessOperationProcessEquDos.stream()
                 .anyMatch(info -> JOBSTATUS_TO_BE_END.equals(info.getWorkstatus()));
@@ -307,10 +306,27 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
             ApsProcessOperationProcessEquDo processEqus = apsProcessOperationProcessEquDos.stream()
                     .filter(info -> changingWiresVo.getId().equals(info.getId()))
                     .findFirst().orElse(null);
+            if (processEqus == null) {
+                log.error("无法根据ID:{}找到对应的工序作业明细信息", changingWiresVo.getId());
+                throw new RuntimeException("无法获取到正确的工序作业明细信息");
+            }
+            // 加工中切设备不变  不更新作业
+            if (JOBSTATUS_TO_BE_STARTING.equals(processEqus.getWorkstatus()) &&
+                    processEqus.getProcessdeviceid().equals(changingWiresVo.getEquId())) {
+                log.debug("该工序作业明细:{}加工中且设备未发生变化无需换线", processEqus.getId());
+                return;
+            }
+            // 加工卷数 = 已报工卷数+已取消卷数时 不更新作业
+            if (processEqus.getPlanprocessrall() == processEqus.getStartingroll() + processEqus.getCancelroll()) {
+                log.debug("该工序作业明细:{}已全部报工无需换线", processEqus.getId());
+                return;
+            }
 
             // 获取该工序作业最早的计划开始时间
             Date planstartdate = processEqus.getPlanstartdate();
-
+            Date planenddate = processEqus.getPlanenddate();
+            ApsProcessOperationDo apsProcessOperationDo = apsProcessOperationService.getById(processEqus.getProcessid());
+            String processWay = apsProcessOperationDo.getProcessway();
             // 待开工的直接修改
             if (JOBSTATUS_TO_BE_START.equals(processEqus.getWorkstatus())) {
                 // 待开工的工序作业明细 直接更换加工设备 和车间
@@ -324,6 +340,8 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
                 processEqus.setPlanenddate(new Date(processEqus.getPlanenddate().getTime() - timeInterval));
                 checkConflictVos.add(new CheckConflictVo(processEqus.getId(), processEqus.getProcessdeviceid(),
                         processEqus.getPlanstartdate(), processEqus.getPlanenddate()));
+                // 校验可用时间
+                affectedIdList.addAll(checkProcessingTimeConflict(processEqus, planstartdate, planenddate, processWay));
                 // 判断是否存在设备不可用
                 inspectionEquipmentIsAvailable(processEqus, processEqus.getProcessdeviceid(), processEqus.getPlanstartdate()
                         , processEqus.getPlanenddate());
@@ -361,6 +379,8 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
                 // 判断是否存在设备不可用
                 inspectionEquipmentIsAvailable(saveProcessEqu, saveProcessEqu.getProcessdeviceid(), saveProcessEqu.getPlanstartdate()
                         , saveProcessEqu.getPlanenddate());
+                // 校验时间重叠问题
+                affectedIdList.addAll(checkProcessingTimeConflict(saveProcessEqu, planstartdate, planenddate, processWay));
                 saveList.add(saveProcessEqu);
                 /************更新原数据的数量信息***********************/
                 // 更新计划完工时间
@@ -370,20 +390,36 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
                 processEqus.setPlanprocessrall(processEqus.getStartingroll());
                 // 更新未完工卷数
                 processEqus.setUnfinishroll(processEqus.getPlanprocessrall() - processEqus.getReportroll());
+                // 作业状态
                 processEqus.setWorkstatus(processEqus.getUnfinishroll() == 0 ? JOBSTATUS_TO_BE_END : JOBSTATUS_TO_BE_STARTING);
-                processEqus.setClosestatus(processEqus.getUnfinishroll() > 0 ? SaveConstans.CloseStatus.UNFINISHED : SaveConstans.CloseStatus.COMPLETED);
+                /**
+                 * 更新完工状态
+                 * 如果作业明细的完工状态=未完工,并且作业明细的已开工卷数=0,则作业状态=待开工;
+                 * 如果作业明细的完工状态=未完工,并且作业明细的已开工卷数>0,则作业状态=加工中;
+                 * 如果作业明细的完工状态=已完工,则作业状态=已完工
+                 */
+                if (JOBSTATUS_TO_BE_END.equals(processEqus.getWorkstatus())) {
+                    processEqus.setClosestatus(JOBSTATUS_TO_BE_END);
+                } else {
+                    processEqus.setClosestatus(processEqus.getStartingroll() > 0 ? JOBSTATUS_TO_BE_STARTING : JOBSTATUS_TO_BE_START);
+                }
+                // 校验可用时间
+                affectedIdList.addAll(checkProcessingTimeConflict(processEqus, planstartdate, planenddate, processWay));
                 // 判断是否存在设备不可用
                 inspectionEquipmentIsAvailable(processEqus, processEqus.getProcessdeviceid(), processEqus.getPlanstartdate()
                         , processEqus.getPlanenddate());
                 saveList.add(processEqus);
             }
+            // 更新坯料交货期
+            apsBlankOrderService. updateBlankDeliveryDate(null,apsProcessOperationDo.getBlankid());
         });
         // 换线拆单后 需要校验 是否存在冲突 如果存在冲突 提示
         if (!checkConflictVos.isEmpty()) {
             List<String> promptInformation = this.baseMapper.checkConflict(checkConflictVos);
             if (!promptInformation.isEmpty()) {
                 log.error("存在冲突的工序作业");
-                return R.error(promptInformation.get(0));
+                return R.error("换线后存在冲突");
+                //return R.error(promptInformation.get(0));
             }
         }
         if (emptyBackup.get()) {
@@ -391,7 +427,10 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
             // 删除工序作业备份
             ApsUtils.clearBackup(currentUser);
         }
-        this.saveOrUpdateBatch(saveList);
+        if(!saveList.isEmpty()){
+            this.saveOrUpdateBatch(saveList);
+        }
+
 
         // 重新获取甘特图数据并返回前段
         return R.ok(ganttService.getListById(affectedIdList));
@@ -399,7 +438,7 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
 
     /**
      * 计算计划完工时间
-     * = 计划开工时间+加工时长*已开工卷数/计划加工卷数
+     * = 计划开工时间+加工时长*(已开工卷数/计划加工卷数)
      *
      * @param planStartTime
      * @param processingTime
@@ -462,39 +501,19 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
             }
             // 当前工序的加工方式
             String processway = operationDo.getProcessway();
+            Date oldPlanStartdate = processEquDo.getPlanstartdate();
+            Date oldPlanEnddate = processEquDo.getPlanenddate();
 
-            // 获取更新之前的存在冲突的工序作业
-            List<ApsProcessOperationProcessEquDo> beforeUpdatingConflictId = this.baseMapper.getConflictId(changeStartTimeVo.getEquId(), changeStartTimeVo.getId(),
-                    processEquDo.getPlanstartdate(), processEquDo.getPlanenddate(), processway);
-            affectedIdList.addAll(beforeUpdatingConflictId.stream().map(ApsProcessOperationProcessEquDo::getId).collect(Collectors.toList()));
-            // 找到更新时间之后存在冲突的工序作业
-            List<ApsProcessOperationProcessEquDo> afterTheUpdateConflictId = this.baseMapper.getConflictId(changeStartTimeVo.getEquId(), changeStartTimeVo.getId(),
-                    changeStartTimeVo.getPlanStartTime(), changeStartTimeVo.getPlanEndTime(), processway);
-            affectedIdList.addAll(afterTheUpdateConflictId.stream().map(ApsProcessOperationProcessEquDo::getId).collect(Collectors.toList()));
-            if (!beforeUpdatingConflictId.isEmpty()) {
-                updateProcessEquBeforeAddConflictsDesc(beforeUpdatingConflictId, EQ_TIME_CROSS, processway);
-            }
+            processEquDo.setPlanstartdate(changeStartTimeVo.getPlanStartTime());
+            processEquDo.setPlanenddate(changeStartTimeVo.getPlanEndTime());
+            affectedIdList.addAll(checkProcessingTimeConflict(processEquDo, oldPlanStartdate, oldPlanEnddate, processway));
 
-            if (!afterTheUpdateConflictId.isEmpty()) {
-                processEquDo.setHasconflict(LOCKMARK_Y);
-                // 更当前工序作业增加新的冲突
-                String newConflictsDesc = addNewConflictsDesc(processEquDo.getConflictdes(), EQ_TIME_CROSS);
-                processEquDo.setConflictdes(newConflictsDesc);
-                updateProcessEquAfterAddConflictsDesc(afterTheUpdateConflictId, EQ_TIME_CROSS);
-            } else {
-                String newConflictsDesc = removeConflictsDesc(processEquDo.getConflictdes(), EQ_TIME_CROSS);
-                processEquDo.setConflictdes(newConflictsDesc);
-                processEquDo.setHasconflict(StringUtils.isBlank(processEquDo.getConflictdes()) &&
-                        StringUtils.isBlank(processEquDo.getSoftconflictdes()) ?
-                        LOCKMARK_N : LOCKMARK_Y);
-            }
             // 判断是否存在设备不可用
             inspectionEquipmentIsAvailable(processEquDo, changeStartTimeVo.getEquId(), changeStartTimeVo.getPlanStartTime()
                     , changeStartTimeVo.getPlanEndTime());
-
-            processEquDo.setPlanstartdate(changeStartTimeVo.getPlanStartTime());
-            processEquDo.setPlanenddate(changeStartTimeVo.getPlanEndTime());
             this.updateById(processEquDo);
+            // 更新坯料交货期
+            apsBlankOrderService. updateBlankDeliveryDate(null,operationDo.getBlankid());
         });
         // 返回受影响的数据
         return R.ok(this.ganttService.getListById(affectedIdList));
@@ -559,41 +578,21 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
             long timeInterval = DateUtil.between(planStartTime, oldPlanstartdate, DateUnit.SECOND, false);
             apsProcessOperationProcessEquDo.setPlanstartdate(planStartTime);
             // 自动计算计划完工时间=原完工时间+新计划开工时间-原计划开工时间
-            apsProcessOperationProcessEquDo.setPlanenddate(new Date(apsProcessOperationProcessEquDo.getPlanenddate().getTime() + jobDetailsVo.getPlanStartTime().getTime() - oldPlanstartdate.getTime()));
-            // 获取更新之前的存在冲突的工序作业
-            List<ApsProcessOperationProcessEquDo> beforeUpdatingConflictId = this.baseMapper.getConflictId(
-                    oldEquId, id, oldPlanstartdate, oldPlanenddate,apsProcessOperationDo.getProcessway());
-            affectedIdList.addAll(beforeUpdatingConflictId.stream().map(ApsProcessOperationProcessEquDo::getId).collect(Collectors.toList()));
-            // 找到更新时间之后存在冲突的工序作业
-            List<ApsProcessOperationProcessEquDo> afterTheUpdateConflictId = this.baseMapper.getConflictId(
-                    apsProcessOperationProcessEquDo.getProcessdeviceid(), id,
-                    apsProcessOperationProcessEquDo.getPlanstartdate(), apsProcessOperationProcessEquDo.getPlanenddate(),
-                    apsProcessOperationDo.getProcessway());
-            affectedIdList.addAll(afterTheUpdateConflictId.stream().map(ApsProcessOperationProcessEquDo::getId).collect(Collectors.toList()));
-            if (!beforeUpdatingConflictId.isEmpty()) {
-                updateProcessEquBeforeAddConflictsDesc(beforeUpdatingConflictId, EQ_TIME_CROSS,apsProcessOperationDo.getProcessway());
-            }
-
-            if (!afterTheUpdateConflictId.isEmpty()) {
-                apsProcessOperationProcessEquDo.setHasconflict(LOCKMARK_Y);
-                // 更当前工序作业增加新的冲突
-                String newConflictsDesc = addNewConflictsDesc(apsProcessOperationProcessEquDo.getConflictdes(), EQ_TIME_CROSS);
-                apsProcessOperationProcessEquDo.setConflictdes(newConflictsDesc);
-                updateProcessEquAfterAddConflictsDesc(afterTheUpdateConflictId, EQ_TIME_CROSS);
-                this.updateBatchById(afterTheUpdateConflictId);
-            } else {
-                // 更当前工序作业增加新的冲突
-                String newConflictsDesc = removeConflictsDesc(apsProcessOperationProcessEquDo.getConflictdes(), EQ_TIME_CROSS);
-                apsProcessOperationProcessEquDo.setConflictdes(newConflictsDesc);
-                apsProcessOperationProcessEquDo.setHasconflict(StringUtils.isBlank(apsProcessOperationProcessEquDo.getConflictdes()) &&
-                        StringUtils.isBlank(apsProcessOperationProcessEquDo.getSoftconflictdes()) ?
-                        LOCKMARK_N : LOCKMARK_Y);
-            }
+            apsProcessOperationProcessEquDo.setPlanenddate(new Date(apsProcessOperationProcessEquDo.getPlanenddate().getTime() +
+                    jobDetailsVo.getPlanStartTime().getTime() - oldPlanstartdate.getTime()));
+            // 增加受影响的工序作业信息
+            affectedIdList.addAll(checkProcessingTimeConflict(apsProcessOperationProcessEquDo, oldPlanstartdate,
+                    oldPlanenddate, apsProcessOperationDo.getProcessway()));
         }
+
         // 判断是否存在设备不可用
         inspectionEquipmentIsAvailable(apsProcessOperationProcessEquDo, apsProcessOperationProcessEquDo.getProcessdeviceid()
                 , apsProcessOperationProcessEquDo.getPlanstartdate(), apsProcessOperationProcessEquDo.getPlanenddate());
+
         this.updateById(apsProcessOperationProcessEquDo);
+        // 更新坯料交货期
+        apsBlankOrderService. updateBlankDeliveryDate(null,apsProcessOperationDo.getBlankid());
+
         return R.ok(this.ganttService.getListById(affectedIdList));
     }
 
@@ -760,7 +759,7 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
      * @param removeConflictsDesc      需要被删除的冲突描述
      */
     public void updateProcessEquBeforeAddConflictsDesc(List<ApsProcessOperationProcessEquDo> beforeUpdatingConflictId,
-                                                       String removeConflictsDesc,String processway) {
+                                                       String removeConflictsDesc, String processway) {
         if (beforeUpdatingConflictId.isEmpty()) {
             return;
         }
@@ -800,24 +799,6 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
         this.updateBatchById(afterTheUpdateConflictId);
     }
 
-    /**
-     * 增加 新的冲突
-     *
-     * @param oldConflictDesc 工序作业的旧冲突
-     * @param newConflictDesc 需要新增的冲突
-     * @return
-     */
-    public String addNewConflictsDesc(String oldConflictDesc, String newConflictDesc) {
-        if (StringUtils.isBlank(oldConflictDesc)) {
-            return newConflictDesc;
-        }
-        List<String> conflictdeList = new ArrayList<>(Arrays.asList(oldConflictDesc.split(";")));
-        if (!conflictdeList.contains(newConflictDesc)) {
-            conflictdeList.add(newConflictDesc);
-        }
-        return CollUtil.join(conflictdeList, ";");
-    }
-
     /**
      * 删除旧冲突
      *
@@ -858,6 +839,53 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
         processEquDo.setConflictdes(newConflictdes);
         processEquDo.setHasconflict(StringUtils.isBlank(newConflictdes) && StringUtils.isBlank(processEquDo.getSoftconflictdes()) ? LOCKMARK_N : LOCKMARK_Y);
     }
+
+    /**
+     * 校验加工时间是否重叠
+     *
+     * @param apsProcessOperationProcessEquDo 当前工序作业
+     * @param oldPlanstartdate                原来的加工开始时间
+     * @param oldPlanenddate                  原来的加工结束时间
+     * @param currentProcessWay               当前工序的加工方式
+     * @return
+     */
+    public List<String> checkProcessingTimeConflict(ApsProcessOperationProcessEquDo apsProcessOperationProcessEquDo,
+                                                    Date oldPlanstartdate, Date oldPlanenddate, String currentProcessWay) {
+        // 受影响的工序作业Id
+        List<String> affectedIdList = new ArrayList<>();
+        // 获取更新之前的存在冲突的工序作业
+        List<ApsProcessOperationProcessEquDo> beforeUpdatingConflictId = this.baseMapper.getConflictId(
+                apsProcessOperationProcessEquDo.getProcessdeviceid(), apsProcessOperationProcessEquDo.getId(),
+                oldPlanstartdate, oldPlanenddate, currentProcessWay);
+
+        affectedIdList.addAll(beforeUpdatingConflictId.stream().map(ApsProcessOperationProcessEquDo::getId).collect(Collectors.toList()));
+        // 找到更新时间之后存在冲突的工序作业
+        List<ApsProcessOperationProcessEquDo> afterTheUpdateConflictId = this.baseMapper.getConflictId(
+                apsProcessOperationProcessEquDo.getProcessdeviceid(), apsProcessOperationProcessEquDo.getId(),
+                apsProcessOperationProcessEquDo.getPlanstartdate(), apsProcessOperationProcessEquDo.getPlanenddate(),
+                currentProcessWay);
+        affectedIdList.addAll(afterTheUpdateConflictId.stream().map(ApsProcessOperationProcessEquDo::getId).collect(Collectors.toList()));
+        if (!beforeUpdatingConflictId.isEmpty()) {
+            updateProcessEquBeforeAddConflictsDesc(beforeUpdatingConflictId, EQ_TIME_CROSS, currentProcessWay);
+        }
+
+        if (!afterTheUpdateConflictId.isEmpty()) {
+            apsProcessOperationProcessEquDo.setHasconflict(LOCKMARK_Y);
+            // 更当前工序作业增加新的冲突
+            String newConflictsDesc = addNewConflictsDesc(apsProcessOperationProcessEquDo.getConflictdes(), EQ_TIME_CROSS);
+            apsProcessOperationProcessEquDo.setConflictdes(newConflictsDesc);
+            updateProcessEquAfterAddConflictsDesc(afterTheUpdateConflictId, EQ_TIME_CROSS);
+            this.updateBatchById(afterTheUpdateConflictId);
+        } else {
+            // 更当前工序作业增加新的冲突
+            String newConflictsDesc = removeConflictsDesc(apsProcessOperationProcessEquDo.getConflictdes(), EQ_TIME_CROSS);
+            apsProcessOperationProcessEquDo.setConflictdes(newConflictsDesc);
+            apsProcessOperationProcessEquDo.setHasconflict(StringUtils.isBlank(apsProcessOperationProcessEquDo.getConflictdes()) &&
+                    StringUtils.isBlank(apsProcessOperationProcessEquDo.getSoftconflictdes()) ?
+                    LOCKMARK_N : LOCKMARK_Y);
+        }
+        return affectedIdList;
+    }
 }
 
 

+ 33 - 3
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/service/impl/ApsProcessOperationServiceImpl.java

@@ -88,7 +88,7 @@ public class ApsProcessOperationServiceImpl extends ServiceImpl<ApsProcessOperat
     @Autowired
     private ApsProductionOrderService apsProductionOrderService;
     @Autowired
-    private ApsBlankOrderService apsBlankOrderService;
+    private ApsBlankOrderServiceImpl apsBlankOrderService;
     @Autowired
     private AspCheckItemsService aspCheckItemsService;
     @Autowired
@@ -97,8 +97,6 @@ public class ApsProcessOperationServiceImpl extends ServiceImpl<ApsProcessOperat
     @Autowired
     private ApsProcessOperationBackupDao apsProcessOperationBackupDao;
     @Autowired
-    private ApsProcessOperationProcessEquDao apsProcessOperationProcessEquDao;
-    @Autowired
     private ApsProcessOperationProcessEquBackupDao apsProcessOperationProcessEquBackupDao;
     @Autowired
     private ApsScheduleConfigService apsScheduleConfigService;
@@ -1496,6 +1494,11 @@ public class ApsProcessOperationServiceImpl extends ServiceImpl<ApsProcessOperat
         if (!equSaveList.isEmpty()) {
             apsProcessOperationProcessEquService.saveOrUpdateBatch(equSaveList, 100);
         }
+        apsProcessOperationBackupDos.stream().map(ApsProcessOperationBackupDo::getBlankid).forEach(data->{
+            // 更新坯料交货期
+            apsBlankOrderService.updateBlankDeliveryDate(null,data);
+        });
+
         return R.ok();
     }
 
@@ -1950,6 +1953,16 @@ public class ApsProcessOperationServiceImpl extends ServiceImpl<ApsProcessOperat
                 apsProcessOperationProcessEquDoList.add(processOperationProcessEquDo);
             }
 
+            //作业计划开工时间=所有作业明细最早计划开工时间
+            Optional<Date> minDate = apsProcessOperationProcessEquDos.stream()
+                    .map(ApsProcessOperationProcessEquDo::getPlanstartdate).min(Comparator.naturalOrder());
+            apsProcessOperationDo.setPlanstartdate(new Date(minDate.get().getTime()));
+
+            //作业计划完工时间=所有作业明细最晚计划完工时间
+            Optional<Date> maxDate = apsProcessOperationProcessEquDos.stream()
+                    .map(ApsProcessOperationProcessEquDo::getPlanenddate).max(Comparator.naturalOrder());
+            apsProcessOperationDo.setPlanenddate(new Date(maxDate.get().getTime()));
+
             boolean bool1 = apsProcessOperationService.saveOrUpdate(apsProcessOperationDo);
             boolean bool2 = apsProcessOperationOutMaterService.saveOrUpdateBatch(apsProcessOperationOutMaterDoList);
             boolean bool3 = true;
@@ -1963,6 +1976,23 @@ public class ApsProcessOperationServiceImpl extends ServiceImpl<ApsProcessOperat
             apsProcessOperationProcessEquService.updateProductionStatus(req);
 
             if (bool1 && bool2 && bool3) {
+                String blanckId = apsProcessOperationDo.getBlankid();
+                List<String> blankIds = Arrays.asList(blanckId.split(","));
+                String processId = apsProcessOperationDo.getId();
+                List<String> processIds = Arrays.asList(processId.split(","));
+                //先清除该坯料计划的排程结果备份
+                apsProcessOperationBackupDao.deletedByBlankId(blankIds, null);
+                apsProcessOperationProcessEquBackupDao.deletedByBlankId(blankIds, null);
+
+                //再备份工序作业及作业明细
+                SysUserVo currentUser = CXCommonUtils.getCurrentUser();
+                apsProcessOperationBackupDao.processOperationBackup(processIds,
+                        currentUser == null ? "" : currentUser.getId(),
+                        currentUser == null ? "" : currentUser.getName());
+                apsProcessOperationProcessEquBackupDao.processOperationEquCopy(processIds,
+                        currentUser == null ? "" : currentUser.getId(),
+                        currentUser == null ? "" : currentUser.getName());
+
                 //更新坯料计划的所选工艺路线相关信息
                 ApsCraftRouteDo apsCraftRouteDo = null;
                 if (StringUtils.isNotBlank(craftrouteid)) {

+ 22 - 1
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/utils/ApsUtils.java

@@ -1,5 +1,6 @@
 package com.rongwei.bscommon.sys.utils;
 
+import cn.hutool.core.collection.CollUtil;
 import com.rongwei.bscommon.sys.dao.ApsProcessOperationBackupDao;
 import com.rongwei.bscommon.sys.dao.ApsProcessOperationProcessEquBackupDao;
 import com.rongwei.rwadmincommon.system.vo.SysUserVo;
@@ -14,6 +15,10 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.PostConstruct;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * ApsUtils class
@@ -78,6 +83,22 @@ public class ApsUtils {
     }
 
 
-
+    /**
+     * 增加 新的冲突
+     *
+     * @param oldConflictDesc 工序作业的旧冲突
+     * @param newConflictDesc 需要新增的冲突
+     * @return
+     */
+    public static String addNewConflictsDesc(String oldConflictDesc, String newConflictDesc) {
+        if (StringUtils.isBlank(oldConflictDesc)) {
+            return newConflictDesc;
+        }
+        List<String> conflictdeList = new ArrayList<>(Arrays.asList(oldConflictDesc.split(";")));
+        if (!conflictdeList.contains(newConflictDesc)) {
+            conflictdeList.add(newConflictDesc);
+        }
+        return conflictdeList.stream().distinct().filter(StringUtils::isNotBlank).collect(Collectors.joining(","));
+    }
 
 }

+ 31 - 0
cx-aps/cx-aps-common/src/main/resources/mybatis/ApsBlankOrderDao.xml

@@ -190,4 +190,35 @@
                 AND (CONFLICTDES is not null AND  CONFLICTDES !='' )
             </where>
     </select>
+    <select id="getBlankDeliveryDate" resultType="com.rongwei.bsentity.vo.UpdateBlankDeliveryDateVo">
+        SELECT
+            a.*
+        FROM
+            (
+                SELECT
+                    ROW_NUMBER() OVER ( ORDER BY apope.PLANENDDATE ASC ) AS rn_asc,
+                    ROW_NUMBER() OVER ( ORDER BY apope.PLANENDDATE DESC ) AS rn_desc,
+                    apope.PLANENDDATE,
+                    apope.ID,
+                    apo1.DELIVERYTIME, abo.PROMISEDATESTART,
+                    abo.PROMISEDATEEND,
+                    abo.ID AS BLANKID
+                FROM
+                    aps_blank_order abo
+                        LEFT JOIN aps_process_operation apo ON apo.BLANKID = abo.ID
+                        AND abo.DELETED = '0'
+                        LEFT JOIN aps_process_operation_out_mater apoom ON apoom.MAINID = apo.ID
+                        AND apoom.DELETED = '0'
+                        LEFT JOIN aps_process_operation_process_equ apope ON apo.ID = apope.PROCESSID
+                        AND apope.DELETED = '0'
+                        LEFT JOIN aps_production_order apo1 ON abo.PRODUCTIONORDERID = apo1.ID
+                        AND apo1.DELETED = '0'
+                WHERE
+                    apo.DELETED = '0'
+                  AND apope.DELETED = '0'
+                  AND apoom.PLANPRODROLLNUM > 0
+                  AND abo.ID = #{blankId}
+            ) a
+        where a.rn_asc=1 or a.rn_desc=1 order by a.PLANENDDATE
+    </select>
 </mapper>

+ 4 - 1
cx-aps/cx-aps-common/src/main/resources/mybatis/ApsProcessOperationProcessEquDao.xml

@@ -164,6 +164,7 @@
         a1.SOFTCONFLICTDES,
         a1.nextprocessesids,
         a1.previousprocessesids,
+        a1.CANCELROLL,
         a2.ID as processid,
         a2.PLANINPUT AS INMATERCONDITION,
         a2.PROCESSSTATUS,
@@ -234,7 +235,7 @@
             </if>
             <if test="processids != null ">and a1.PROCESSID in (${processids})</if>
         </where>
-        order by a1.PROCESSWORKSHOP,a1.PROCESSDEVICE,a1.PLANSTARTDATE asc,a1.PLANENDDATE
+        order by a1.PROCESSWORKSHOP,a1.PROCESSDEVICE,a1.PLANSTARTDATE asc,a1.PLANENDDATE desc
     </select>
     <select id="selectNeedUpdate" resultType="com.rongwei.bsentity.vo.CommonUpdateProductionStatusReq">
         SELECT
@@ -440,6 +441,8 @@
         WHERE
             a1.DELETED = '0'
           and a1.TENANTID=#{factoryId}
+          and (a1.PROCESSDEVICE is not null and a1.PROCESSDEVICE !='' )
+          and (a1.PROCESSWORKSHOP is not null and a1.PROCESSWORKSHOP !='' )
         ORDER BY
             a1.PROCESSWORKSHOP,
             b.CHECKITEMTYPE,

+ 23 - 19
cx-aps/cx-aps-entity/src/main/java/com/rongwei/bsentity/vo/GanttVos.java

@@ -22,8 +22,8 @@ public class GanttVos {
     private String productname;
     /**
      * 计划加工卷数
-      */
-    private Integer planprocessrall =0;
+     */
+    private Integer planprocessrall = 0;
     /**
      * 生产状态
      */
@@ -75,19 +75,23 @@ public class GanttVos {
     /**
      * 已开工
      */
-    private Integer startingroll =0;
+    private Integer startingroll = 0;
     /**
      * 已报工
      */
-    private Integer reportroll =0;
+    private Integer reportroll = 0;
     /**
      * 已检验
      */
-    private Integer checkoutroll =0;
+    private Integer checkoutroll = 0;
     /**
      * 未完工
      */
-    private Integer unfinishroll =0;
+    private Integer unfinishroll = 0;
+    /**
+     * 已取消卷数
+     */
+    private Integer cancelroll = 0;
     /**
      * 作业状态
      */
@@ -99,7 +103,7 @@ public class GanttVos {
     /**
      * 客户简称
      */
-    private String customerabbreviation="";
+    private String customerabbreviation = "";
     /**
      * 工序作业ID
      */
@@ -122,7 +126,7 @@ public class GanttVos {
     @Deprecated
     private Date promisedeliverydate;
     /**
-     *  排程交货日期
+     * 排程交货日期
      */
     private Date scheduledeliverydate;
 
@@ -152,22 +156,22 @@ public class GanttVos {
      */
     private String hasconflict;
     /**
-     *非强制冲突描述
+     * 非强制冲突描述
      */
-    private String conflictdes ="";
+    private String conflictdes = "";
 
     /**
      * 强制冲突描述
      */
-    private String softconflictdes  ="";
+    private String softconflictdes = "";
     /**
      * 输入物料描述
      */
-    private String inmatercondition="";
+    private String inmatercondition = "";
     /**
      * 客户订单号
      */
-    private String customorderno="";
+    private String customorderno = "";
     /**
      * 批量需求的输出订单产品
      */
@@ -184,11 +188,11 @@ public class GanttVos {
     /**
      * 输入批次号
      */
-    private String inputnumber="";
+    private String inputnumber = "";
     /**
      * 输出批次号
      */
-    private String outputnumber="";
+    private String outputnumber = "";
     /**
      * 承诺交货日期-起
      */
@@ -200,17 +204,17 @@ public class GanttVos {
     /**
      * 后道工序作业明细ID
      */
-    private String nextprocessesids="";
+    private String nextprocessesids = "";
     /**
      * 前道工序作业明细ID
      */
-    private String previousprocessesids="";
+    private String previousprocessesids = "";
     /**
      * 产线名称
      */
-    private String productlinename="";
+    private String productlinename = "";
     /**
      * 产线ID
      */
-    private String productlineid="";
+    private String productlineid = "";
 }

+ 27 - 0
cx-aps/cx-aps-entity/src/main/java/com/rongwei/bsentity/vo/UpdateBlankDeliveryDateVo.java

@@ -0,0 +1,27 @@
+package com.rongwei.bsentity.vo;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * UpdateBlankDeliveryDateVo class
+ *
+ * @author XH
+ * @date 2024/08/05
+ */
+@Data
+public class UpdateBlankDeliveryDateVo {
+    // 工序作业明细ID
+    private String id;
+    // 工序作业对应的计划完工时间
+    private Date planenddate;
+    // 送货时长
+    private int deliverytime=0;
+    // 承诺交货期-起
+    private Date promisedatestart;
+    // 承诺交货期-止
+    private Date promisedateend;
+    // 坯料计划ID
+    private String blankid;
+}