Browse Source

aps-坯料计划保存校验

sucheng 1 year ago
parent
commit
13ea5281f6

+ 82 - 16
bs-common/src/main/java/com/rongwei/safecommon/utils/SaveConstans.java

@@ -35,36 +35,36 @@ public class SaveConstans {
     /**
      * orgId和 code的对应关系
      */
-    public static final Map<String,String> ORG_CODE_MAP=new HashMap<String,String>(){{
+    public static final Map<String, String> ORG_CODE_MAP = new HashMap<String, String>() {{
         /**
          * 山东创新箔材科技有限公司
          */
-        put("0001651000000015EFDD","CXLB");
+        put("0001651000000015EFDD", "CXLB");
         /**
          * 山东创新精铝金属制造有限公司
          */
-        put("0001651000000017DRZ1","CXJL");
+        put("0001651000000017DRZ1", "CXJL");
         /**
          * 山东创新板材有限公司
          */
-        put("0001S31000000000J0TR","CXBC");
+        put("0001S31000000000J0TR", "CXBC");
     }};
     /**
      * orgId和 code的对应关系
      */
-    public static final Map<String,String> AQ_ORG_CODE_MAP=new HashMap<String,String>(){{
+    public static final Map<String, String> AQ_ORG_CODE_MAP = new HashMap<String, String>() {{
         /**
          * 山东创新箔材科技有限公司
          */
-        put("0001651000000015EFDD","LB");
+        put("0001651000000015EFDD", "LB");
         /**
          * 山东创新精铝金属制造有限公司
          */
-        put("0001651000000017DRZ1","JL");
+        put("0001651000000017DRZ1", "JL");
         /**
          * 山东创新板材有限公司
          */
-        put("0001S31000000000J0TR","BC");
+        put("0001S31000000000J0TR", "BC");
     }};
 
 
@@ -263,7 +263,6 @@ public class SaveConstans {
         public static final String DEVICE_REPEATEDLY_FAILS_TITLE = "设备部位重复故障问题提醒";
 
 
-
         /**
          * 设备报废申请审批通过通知
          */
@@ -364,7 +363,7 @@ public class SaveConstans {
          */
         public static final String EQU_SCRAP_CONTENT = "【%s】于【%s】申请【%s】【%s】【%s】使用的设备进行报废处置申请已审批通过,系统已将该设备进行标记报废标记处理,此设备的相关保养、润滑相关计划请及时进行停用处理,请大家注意。";
 
-         /**
+        /**
          * 设备部位重复故障问题提醒内容
          */
         public static final String DEVICE_REPEATEDLY_FAILS_CONTEXT = "近三个月内设备部位重复故障问题提醒说明(含三个厂,各自独立),单个工厂对相同问题重复发生请大家互相学习解决方案并加以改进,具体信息详见提醒内容中附件表格。";
@@ -418,6 +417,7 @@ public class SaveConstans {
         public static final String PLANNING_TASK_FILE_NAME = "大修任务超期未完成.xlsx";
 
     }
+
     public static class FileSuffix {
         public static final String XLS = ".xls";
         public static final String XLSX = ".xlsx";
@@ -490,6 +490,7 @@ public class SaveConstans {
     }
 
     public static final List<String> MERGE_PRODUCE_PROCESS = new ArrayList<>();
+
     static {
         MERGE_PRODUCE_PROCESS.add("");
     }
@@ -595,10 +596,11 @@ public class SaveConstans {
          */
         public static final String TO_BE_SCHEDULED = "10";
     }
+
     /**
      * 作业状态
      */
-    public static class JobStatus{
+    public static class JobStatus {
         /**
          * 待开工
          */
@@ -613,24 +615,88 @@ public class SaveConstans {
         public static final String JOBSTATUS_TO_BE_END = "已完工";
     }
 
-    public static class CloseStatus{
+    public static class CloseStatus {
         /**
          * 未完工
          */
-        public static final String UNFINISHED="未完工";
+        public static final String UNFINISHED = "未完工";
         /**
          * 已完工
          */
-        public static final String COMPLETED= "已完工";
+        public static final String COMPLETED = "已完工";
     }
 
     /**
      * 冲突描述
      */
-    public static class ConflictDescription{
+    public static class ConflictDescription {
         /**
          * 加工时间冲突描述
          */
-        public static final String CONFLICTING_PROCESSING_TIMES ="与其他作业加工时间重叠";
+        public static final String CONFLICTING_PROCESSING_TIMES = "与其他作业加工时间重叠";
+    }
+
+    /**
+     * 产品类型的外观 字典ID
+     */
+    public static class ProductionType {
+        /**
+         * 铝板ID
+         */
+        public static final String LVBAN_ID = "4a30f22e8c574b568b0715021f4641e8";
+        /**
+         * 板锭ID
+         */
+        public static final String BANDING_ID = "cc22dafdf4d845d4b9b4de23a57ab473";
+
+    }
+
+    /**
+     * 初始化数量单位
+     */
+    public static final Map<String, String> QUANTITY_UNIT_MAP = new HashMap<String, String>() {{
+        /**
+         * 公斤
+         */
+        put("kg", "公斤");
+        /**
+         * 吨
+         */
+        put("ton", "吨");
+    }};
+    /**
+     * 枚举数量单位
+     */
+    public static class CountUnit{
+        /**
+         * 千克、公斤
+         */
+        public static final String KG = "kg";
+        /**
+         * 吨
+         */
+        public static final String TON = "ton";
+    }
+
+    /**
+     * 在制品状态
+     */
+    public static class WorkInProgressStatus{
+        /**
+         * 待检验
+         */
+        public static final String WAIT_CHECK = "待检验";
+        /**
+         * 加工中
+         */
+        public static final String WORKING = "加工中";
+        /**
+         * 待加工
+         */
+        public static final String WAIT_WORK = "待加工";
+        /**
+         * 备料中
+         */
+        public static final String WAITING = "备料中";
     }
 }

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

@@ -64,4 +64,16 @@ public interface ApsBlankOrderDao extends BaseMapper<ApsBlankOrderDo> {
     List<String> getIdByLockTime(@Param("lockTime") Date LockTime,@Param("lockMark") String lockMark);
 
     int checkConflictByBlankId(@Param("blankIds") List<String> blankIds);
+
+    @Select("select * from sys_dict where DELETED = 0 AND ID = (select PID from sys_dict where DELETED = 0 AND ID = #{productionorderid}) limit 1")
+    String selectDictAboutProductType(@Param("productionorderid") String productionorderid);
+
+    @Select("SELECT apoom.OUTPUTFINISHPRODUCT FROM aps_process_operation apo LEFT JOIN aps_process_operation_out_mater apoom ON apo.ID = apoom.MAINID AND apoom.DELETED = 0 where apo.DELETED = 0 AND apoom.OUTPUTFINISHPRODUCT is not null AND apoom.OUTPUTFINISHPRODUCT != '' AND apo.BLANKID = #{id}")
+    List<String> selectProcessByBlankId(@Param("id") String id);
+
+    @Update("update aps_process_operation set SECONDROLL = SECONDROLL+1 where ID = #{processoperationid}")
+    void processAddSecondRoll(@Param("processoperationid") String processoperationid);
+
+    @Update("update aps_process_operation_process_equ set BACHMATERIALPROCESS = REPLACE(REPLACE(BACHMATERIALPROCESS,'${batchnumber},',''),',${batchnumber}','') where DELETED = 0 AND PROCESSID IN (select ID from aps_process_operation where DELETED = 0 AND PREVIOUSPROCESSID = #{processoperationid})")
+    void processDeleteBatchNumber(@Param("batchnumber") String batchnumber,@Param("processoperationid") String processoperationid);
 }

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

@@ -0,0 +1,15 @@
+package com.rongwei.bscommon.sys.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.rongwei.bsentity.domain.ApsProcessOutputProductDo;
+
+/**
+ *
+ */
+public interface ApsProcessOutputProductDao extends BaseMapper<ApsProcessOutputProductDo> {
+
+}
+
+
+
+

+ 3 - 4
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/service/ApsBlankOrderService.java

@@ -2,10 +2,7 @@ package com.rongwei.bscommon.sys.service;
 
 import com.rongwei.bsentity.domain.ApsBlankOrderDo;
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.rongwei.bsentity.vo.ApsBlankOrderVo;
-import com.rongwei.bsentity.vo.ApsPlanVo;
-import com.rongwei.bsentity.vo.OrderLockVo;
-import com.rongwei.bsentity.vo.ProductionScheduleVo;
+import com.rongwei.bsentity.vo.*;
 import com.rongwei.rwcommon.base.R;
 import java.util.List;
 import java.util.Map;
@@ -40,4 +37,6 @@ public interface ApsBlankOrderService extends IService<ApsBlankOrderDo> {
     R publishCancel(List<String> blankIds);
 
     R insertOrder(Map<String, Object> params) throws Exception;
+
+    R checkAndSaveOrUpdateBlank(CheckAndSaveOrUpdateBlankReq req);
 }

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

@@ -0,0 +1,9 @@
+package com.rongwei.bscommon.sys.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.rongwei.bsentity.domain.ApsProcessOutputProductDo;
+
+
+public interface ApsProcessOutputProductService extends IService<ApsProcessOutputProductDo> {
+
+}

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

@@ -41,8 +41,7 @@ import static com.rongwei.safecommon.utils.SaveConstans.DatePattern.DATE_PATTERN
 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.TO_BE_PUBLISHED;
-import static com.rongwei.safecommon.utils.SaveConstans.ProductionStatus.TO_BE_SCHEDULED;
+import static com.rongwei.safecommon.utils.SaveConstans.ProductionStatus.*;
 import static com.rongwei.safecommon.utils.SaveConstans.SchedulingStatus.PUBLISHED;
 
 /**
@@ -82,6 +81,10 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
     private ApsProductDetailService apsProductDetailService;
     @Autowired
     private ApsProductDetailDao apsProductDetailDao;
+    @Autowired
+    private ApsWorkInProgressInventoryService apsWorkInProgressInventoryService;
+    @Autowired
+    private ApsProcessOutputProductService apsProcessOutputProductService;
 
 
     @Override
@@ -188,24 +191,25 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
                 .set(ApsProcessOperationDo::getLockmark, LOCKMARK_Y)
                 .set(ApsProcessOperationDo::getWorkstatus, JOBSTATUS_TO_BE_START));
         // 更新坯料计划对应产品明细的生产状态为待开工
-        apsProductDetailDao.updateProductStatusByBlankId(blankIds,"30");
+        apsProductDetailDao.updateProductStatusByBlankId(blankIds, "30");
         // 更新工序作业明细的生产状态为待开工
         processOperationProcessEquService.update(new LambdaUpdateWrapper<ApsProcessOperationProcessEquDo>()
-                .in(ApsProcessOperationProcessEquDo::getBlankid,blankIds)
-                .set(ApsProcessOperationProcessEquDo::getLockmark,LOCKMARK_Y)
+                .in(ApsProcessOperationProcessEquDo::getBlankid, blankIds)
+                .set(ApsProcessOperationProcessEquDo::getLockmark, LOCKMARK_Y)
                 .set(ApsProcessOperationProcessEquDo::getWorkstatus, JOBSTATUS_TO_BE_START)
         );
         List<String> collect = apsBlankOrderDos.stream().map(ApsBlankOrderDo::getProductionorderid).distinct().collect(Collectors.toList());
         // 更新工序作业的状态
         apsProcessOperationDao.publish(collect);
         // 根据坯料ID 删除 备份数据
-        apsProcessOperationBackupDao.deletedByBlankId(blankIds,null);
-        apsProcessOperationProcessEquBackupDao.deletedByBlankId(blankIds,null);
+        apsProcessOperationBackupDao.deletedByBlankId(blankIds, null);
+        apsProcessOperationProcessEquBackupDao.deletedByBlankId(blankIds, null);
         return R.ok();
     }
 
     /**
      * 取消发布
+     *
      * @param blankIds
      * @return
      */
@@ -239,19 +243,19 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
                 .set(ApsProcessOperationDo::getLockmark, LOCKMARK_N)
                 .set(ApsProcessOperationDo::getWorkstatus, JOBSTATUS_TO_BE_START));
         // 更新坯料计划对应产品明细的生产状态为待开工
-        apsProductDetailDao.updateProductStatusByBlankId(blankIds,"20");
+        apsProductDetailDao.updateProductStatusByBlankId(blankIds, "20");
         // 更新工序作业明细的生产状态为待开工
         processOperationProcessEquService.update(new LambdaUpdateWrapper<ApsProcessOperationProcessEquDo>()
-                .in(ApsProcessOperationProcessEquDo::getBlankid,blankIds)
-                .set(ApsProcessOperationProcessEquDo::getLockmark,LOCKMARK_N)
+                .in(ApsProcessOperationProcessEquDo::getBlankid, blankIds)
+                .set(ApsProcessOperationProcessEquDo::getLockmark, LOCKMARK_N)
                 .set(ApsProcessOperationProcessEquDo::getWorkstatus, JOBSTATUS_TO_BE_START)
         );
         List<String> collect = apsBlankOrderDos.stream().map(ApsBlankOrderDo::getProductionorderid).distinct().collect(Collectors.toList());
         // 更新工序作业的状态
         apsProcessOperationDao.publishCancel(collect);
         // 根据坯料ID 删除 备份数据
-        apsProcessOperationBackupDao.deletedByBlankId(blankIds,null);
-        apsProcessOperationProcessEquBackupDao.deletedByBlankId(blankIds,null);
+        apsProcessOperationBackupDao.deletedByBlankId(blankIds, null);
+        apsProcessOperationProcessEquBackupDao.deletedByBlankId(blankIds, null);
         return R.ok();
     }
 
@@ -330,12 +334,12 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
             return R.error("坯料计划ID和解锁时间都为空");
         }
 
-        if(!blackOrderId.isEmpty()){
+        if (!blackOrderId.isEmpty()) {
             // 校验坯料计划是否开工
             Integer integer = apsBlankOrderDao.selectCount(new LambdaQueryWrapper<ApsBlankOrderDo>()
                     .in(ApsBlankOrderDo::getId, blackOrderId)
                     .in(ApsBlankOrderDo::getProductstatus, "40", "50"));
-            if(integer>0){
+            if (integer > 0) {
                 log.error("所选作业坯料计划已开工,不可以解锁");
                 return R.error("所选作业坯料计划已开工,不可以解锁");
             }
@@ -352,7 +356,7 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
             // 获取所有 待发布 待开工的 坯料计划
             blackOrderId = this.baseMapper.getIdByLockTime(date, lockMark);
         }
-        if(blackOrderId.isEmpty()){
+        if (blackOrderId.isEmpty()) {
             log.debug("暂无需要锁定或者解锁的批量计划");
             return R.ok("暂无需要锁定或者解锁的批量计划");
         }
@@ -363,7 +367,7 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
             ApsBlankOrderDo blankOrderDo = new ApsBlankOrderDo();
             blankOrderDo.setId(id);
             blankOrderDo.setLockmark(lockMark);
-            if (LOCKMARK_N.equals(lockMark)){
+            if (LOCKMARK_N.equals(lockMark)) {
                 blankOrderDo.setProductstatus("20");
             }
             blankOrderDos.add(blankOrderDo);
@@ -374,17 +378,17 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
         }
         // 工序作业锁定标识更新
         apsProcessOperationService.update(new LambdaUpdateWrapper<ApsProcessOperationDo>()
-                .set(ApsProcessOperationDo::getLockmark,lockMark)
+                .set(ApsProcessOperationDo::getLockmark, lockMark)
                 .in(ApsProcessOperationDo::getBlankid, blackOrderId));
         // 工序作业排程计划锁定
         processOperationProcessEquService.update(new LambdaUpdateWrapper<ApsProcessOperationProcessEquDo>()
-                .set(ApsProcessOperationProcessEquDo::getLockmark,lockMark)
+                .set(ApsProcessOperationProcessEquDo::getLockmark, lockMark)
                 .in(ApsProcessOperationProcessEquDo::getBlankid, blackOrderId));
-        if(LOCKMARK_N.equals(lockMark)){
-           // 更新坯料计划对应工序作业的生产状态为待发布
+        if (LOCKMARK_N.equals(lockMark)) {
+            // 更新坯料计划对应工序作业的生产状态为待发布
             apsProcessOperationService.update(new LambdaUpdateWrapper<ApsProcessOperationDo>()
-                    .in(ApsProcessOperationDo::getBlankid,blackOrderId)
-                    .set(ApsProcessOperationDo::getProcessstatus,"20"));
+                    .in(ApsProcessOperationDo::getBlankid, blackOrderId)
+                    .set(ApsProcessOperationDo::getProcessstatus, "20"));
         }
         // 回传坯料计划ID 用于前段更新锁定状态
         return R.ok(blackOrderId);
@@ -411,12 +415,12 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
      *
      * @param apsPlanVo
      */
-    public void apsScheduling(ApsPlanVo apsPlanVo) throws Exception{
+    public void apsScheduling(ApsPlanVo apsPlanVo) throws Exception {
         List<ApsBlankOrderVo> apsBlankOrders = new ArrayList<>();
-        if(apsPlanVo.getApsProductionOrders() != null){
+        if (apsPlanVo.getApsProductionOrders() != null) {
             for (ApsProductionOrderDo apsProductionOrder : apsPlanVo.getApsProductionOrders()) {
                 List<ApsBlankOrderVo> byOrderId = apsBlankOrderDao.getByOrderId(apsProductionOrder.getId());
-                if(byOrderId != null && byOrderId.size()>0){
+                if (byOrderId != null && byOrderId.size() > 0) {
                     apsBlankOrders.addAll(byOrderId);
                 }
             }
@@ -595,8 +599,8 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
         //获取备份的坯料计划ID
         Set<String> blankIds = apsProcessOperationProcessEquDos.stream().map(ApsProcessOperationProcessEquDo::getBlankid).collect(Collectors.toSet());
         ArrayList<String> blankIdList = new ArrayList<>(blankIds);
-        apsProcessOperationBackupDao.deletedByBlankId(blankIdList,null);
-        apsProcessOperationProcessEquBackupDao.deletedByBlankId(blankIdList,null);
+        apsProcessOperationBackupDao.deletedByBlankId(blankIdList, null);
+        apsProcessOperationProcessEquBackupDao.deletedByBlankId(blankIdList, null);
         //增加备份
         List<List<String>> partition1 = Lists.partition(apsProcessOperationIds, 500);
         partition1.forEach(data -> {
@@ -1101,8 +1105,8 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
      */
     private void deleteBackup(List<String> blankids, List<String> apsProductionOrderIds) {
         // 删除工序作业和工序作业明备份数据
-        apsProcessOperationBackupDao.deletedByBlankId(blankids,null);
-        apsProcessOperationProcessEquBackupDao.deletedByBlankId(blankids,null);
+        apsProcessOperationBackupDao.deletedByBlankId(blankids, null);
+        apsProcessOperationProcessEquBackupDao.deletedByBlankId(blankids, null);
         // 更工序作业生产状态=待排程,是否锁定=否,
         apsProcessOperationService.remove(new LambdaQueryWrapper<ApsProcessOperationDo>().in(ApsProcessOperationDo::getBlankid, blankids));
         // 清空作业明细
@@ -1136,4 +1140,202 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
         apsProductDetailService.updateBatchById(productDetailDoList);
 //        apsProductDetailDao.updateProductstatus(apsProductionOrderIds);
     }
+
+    @Override
+    @Transactional
+    public R checkAndSaveOrUpdateBlank(CheckAndSaveOrUpdateBlankReq req) {
+        //获取坯料计划内容
+        ApsBlankOrderDo apsBlankOrderDo = req.getApsBlankOrderDo();
+
+        //=============校验坯料长度=================
+        //如果坯料产品类型对应产品外观类型是铝板或板锭,并且坯料长度为空,则提示:坯料是铝板和板锭时长度必填
+        if (ObjectUtil.isNotEmpty(apsBlankOrderDo.getProducttypeid())) {
+            //目前数据字典存在3层关系,选择只能选择最后一层,二开查询最后一层的父节点对应数据的父节点,判断是否为铝板或板锭的主键ID
+            String pid = this.baseMapper.selectDictAboutProductType(apsBlankOrderDo.getProductionorderid());
+            //如果是铝板或板锭
+            if (ObjectUtil.isNotEmpty(pid) && (pid.equals(SaveConstans.ProductionType.BANDING_ID) || pid.equals(SaveConstans.ProductionType.LVBAN_ID))) {
+                //坯料长度为空
+                if (ObjectUtil.isEmpty(apsBlankOrderDo.getProlength())) {
+                    return R.error("坯料是铝板和板锭时长度必填");
+                }
+            }
+        }
+        //==============拼接工艺路线输出成品==============
+        //查询坯料计划对应工艺路线的输出成品
+        List<String> processOutputList = this.baseMapper.selectProcessByBlankId(apsBlankOrderDo.getId());
+        if (processOutputList != null && processOutputList.size() > 0) {
+            String outputProcessMaterial = "";
+            //排序
+            processOutputList.sort(String::compareTo);
+            for (int i = 0; i < processOutputList.size(); i++) {
+                outputProcessMaterial += "[" + (i + 1) + "]" + processOutputList.get(i);
+                if (i < processOutputList.size() - 1) {
+                    outputProcessMaterial += ",\r\n";
+                }
+            }
+            apsBlankOrderDo.setOutputmaterial(outputProcessMaterial);
+        } else {
+            return R.error("工艺路线没有输出成品");
+        }
+
+        //=============校验输出成品==============
+        //产品明细
+        List<ApsProductDetailDo> apsProductDetailDoList = req.getApsProductDetailDoList();
+        //输出成品
+        List<ApsProcessOutputProductDo> apsProcessOutputProductDoList = req.getApsProcessOutputProductDoList();
+
+        //如果坯料计划未开工(生产状态<=30)
+        if (apsBlankOrderDo.getProductstatus().compareTo(TO_BE_STARTED) <= 0) {
+            for (ApsProcessOutputProductDo apsProcessOutputProductDo : apsProcessOutputProductDoList) {
+                boolean haveProductDetail = false;
+                for (ApsProductDetailDo apsProductDetailDo : apsProductDetailDoList) {
+                    //判断是否存在对应的产品明细
+                    if (apsProcessOutputProductDo.getProductid().equals(apsProductDetailDo.getId())) {
+                        haveProductDetail = true;
+
+                        if (apsProductDetailDo.getInputmaterialdescription().equals(apsProcessOutputProductDo.getProductname())) {
+                            //如果输出单卷重<单卷重(起)或 输出单卷重>单卷重(止),错误提示:输出成品:{订单产品} 输出单卷重不符合订单要求
+                            if (apsProcessOutputProductDo.getOutputonerollweigth().compareTo(apsProductDetailDo.getSinglerollweightstart()) < 0
+                                    || apsProcessOutputProductDo.getOutputonerollweigth().compareTo(apsProductDetailDo.getSinglerollweightend()) > 0) {
+                                return R.error("输出成品:" + apsProcessOutputProductDo.getProductname() + " 输出单卷重不符合订单要求");
+                            } else {//如果对应订单产品明细的订单产品字段值不等于输出成品的订单产品字段值,错误提示:输出成品:{订单产品} 对应订单产品已修改或已删除,请重新选择订单产品
+                                return R.error("输出成品:" + apsProcessOutputProductDo.getProductname() + " 对应订单产品已修改或已删除,请重新选择订单产品");
+                            }
+                        }
+                        break;
+                    }
+                }
+                //存在对应的产品明细
+                if (haveProductDetail) {
+                    //如果输出单卷重>坯料单卷重,错误提示:输出单卷重不能超过坯料单卷重
+                    //(注意:成品重量和坯料重量单位吨和公斤需要转换后比较)
+                    //转化单卷重 单位统一为 公斤(kg)
+
+                    //输出的单卷重
+                    BigDecimal outputWeight = new BigDecimal(0);
+                    //坯料的单卷重
+                    BigDecimal blankWeight = new BigDecimal(0);
+                    //统一输出的重量
+                    //公斤/千克
+                    if (apsProcessOutputProductDo.getCountunit().equals(SaveConstans.CountUnit.KG)) {
+                        outputWeight = apsProcessOutputProductDo.getOutputonerollweigth();
+                    }
+                    //吨
+                    if (apsProcessOutputProductDo.getCountunit().equals(SaveConstans.CountUnit.TON)) {
+                        outputWeight = apsProcessOutputProductDo.getOutputonerollweigth().multiply(new BigDecimal(1000));
+                    }
+
+                    //统一坯料的重量
+                    if (apsBlankOrderDo.getNumberunit().equals(SaveConstans.CountUnit.KG)) {
+                        blankWeight = apsBlankOrderDo.getSinglerollweight();
+                    }
+                    if (apsBlankOrderDo.getNumberunit().equals(SaveConstans.CountUnit.TON)) {
+                        blankWeight = apsBlankOrderDo.getSinglerollweight().multiply(new BigDecimal(1000));
+                    }
+                    //输出单卷重>坯料单卷重
+                    if (outputWeight.compareTo(blankWeight) > 0) {
+                        return R.error("输出成品:" + apsProcessOutputProductDo.getProductname() + " 输出单卷重不能超过坯料单卷重");
+                    }
+                } else {//不存在对应的产品明细
+                    return R.error("输出成品:" + apsProcessOutputProductDo.getProductname() + " 对应订单产品已修改或已删除,请重新选择订单产品");
+                }
+            }
+        }
+
+        //不论坯料计划的状态,需要增加的判断
+        for (ApsProcessOutputProductDo apsProcessOutputProductDo : apsProcessOutputProductDoList) {
+            boolean haveProductDetail = false;
+            for (ApsProductDetailDo apsProductDetailDo : apsProductDetailDoList) {
+                //判断是否存在对应的产品明细
+                if (apsProcessOutputProductDo.getProductid().equals(apsProductDetailDo.getId())) {
+                    haveProductDetail = true;
+                    //计划输出订单重量 > 对应订单产品订单总数量;错误提示:输出成品 {订单产品} 计划输出订单重量 不能大于 订单总数量
+                    if (apsProcessOutputProductDo.getPlanoutputonerollweight().compareTo(apsProductDetailDo.getTotalordercount()) > 0) {
+                        return R.error("输出成品:" + apsProcessOutputProductDo.getProductname() + " 计划输出订单重量 不能大于 订单总数量");
+                    }
+                }
+            }
+            if (!haveProductDetail && apsProcessOutputProductDo.getPlanoutputonerollweight().compareTo(new BigDecimal(0)) > 0) {
+                return R.error("输出成品:" + apsProcessOutputProductDo.getProductname() + " 已修改或已删除,并已开工,计划输出订单重量 不能大于 0");
+            }
+        }
+
+        //===========坯料计划保存之前的校验=============
+        //校验坯料需求
+        //后台校验备料:如果是备料计划,
+        //并且保存前备料已经被其他计划员新增的备料计划选择并保存了
+        //(即:坯料的是否备料=是,并且所选在制品的备料计划ID不为空,并且不是该备料计划ID),
+        //则错误提示:所选在制品已被其他备料计划使用
+        ApsWorkInProgressInventoryDo progressWork = null;
+        if (apsBlankOrderDo.getPreparematerial().equals("是") && ObjectUtil.isNotEmpty(req.getProgressId())) {
+            progressWork = apsWorkInProgressInventoryService.getById(req.getProgressId());
+            if (ObjectUtil.isNotEmpty(progressWork.getPlanmaterialid())) {
+                return R.error("所选在制品已被其他备料计划使用");
+            }
+        }
+
+        //============校验工艺路线=============
+        //如果坯料需求的坯料输出成品字段值不等于坯料需求的工艺输出成品字段值,错误提示:工艺路线输出成品与坯料输出成品不一致
+        if (!apsBlankOrderDo.getOutputfinishproduct().equals(apsBlankOrderDo.getOutputmaterial())) {
+            return R.error("工艺路线输出成品与坯料输出成品不一致");
+        }
+        //如果坯料需求的是否备料=是,并且首道工序作业的是否坯料工序=是,错误提示:工艺路线错误,首道工序作业是坯料工序,备料不能作为输入物料
+        //是否备料
+        if (apsBlankOrderDo.getPreparematerial().equals("是")) {
+            //查询坯料计划的工序作业
+            List<ApsProcessOperationDo> processOperationList = apsProcessOperationService.list(new QueryWrapper<ApsProcessOperationDo>().lambda().eq(ApsProcessOperationDo::getBlankid, apsBlankOrderDo.getId()));
+            for (ApsProcessOperationDo processOperationDo : processOperationList) {
+                //没有前道工序作业ID
+                if (ObjectUtil.isEmpty(processOperationDo.getPreviousprocessid())) {
+                    if (processOperationDo.getIfblankprocess().equals("是")) {
+                        return R.error("工艺路线错误,首道工序作业是坯料工序,备料不能作为输入物料");
+                    }
+                    break;
+                }
+            }
+        }
+
+        //============校验工序作业=============
+        Map<String, Object> params = new HashMap<>();
+        params.put("BLANKID", apsBlankOrderDo.getId());
+        R r = apsProcessOperationService.checkOperation(params);
+        if (!(r.getCode().equals("200"))) {
+            return R.error(r.getMsg());
+        }
+
+        //更新或保存坯料计划和输出成品
+        this.saveOrUpdate(apsBlankOrderDo);
+        apsProcessOutputProductService.saveOrUpdateBatch(apsProcessOutputProductDoList);
+
+        //如果在制品不为空,并且为新增备料
+        if (ObjectUtil.isNotEmpty(req.getProgressId()) && apsBlankOrderDo.getPreparematerial().equals("是")) {
+            //将对应备料库(在制品库存表【aps_work_in_progress_inventory表】)中的备料计划ID(PLANMATERIALID)字段设置为坯料计划的ID
+            ApsWorkInProgressInventoryDo apsWorkInProgressInventoryDo = new ApsWorkInProgressInventoryDo();
+            apsWorkInProgressInventoryDo.setId(req.getProgressId());
+            apsWorkInProgressInventoryDo.setPlanmaterialid(apsBlankOrderDo.getId());
+            apsWorkInProgressInventoryDo.setWorkinprocessstatus(SaveConstans.WorkInProgressStatus.WAIT_WORK);
+            apsWorkInProgressInventoryService.updateById(apsWorkInProgressInventoryDo);
+
+            //借调逻辑
+            if (progressWork.getWorkinprocessstatus().equals(SaveConstans.WorkInProgressStatus.WAIT_WORK)) {
+                //获取该在制品的工序作业ID
+                String processoperationid = progressWork.getProcessoperationid();
+                //获取该在制品的批次号
+                String batchnumber = progressWork.getBatchnumber();
+                //该对应工序作业的已借调卷数=已借调卷数+1
+                this.baseMapper.processAddSecondRoll(processoperationid);
+                //将在制品的作业输出物料ID对应的所有后道工序作业的所有作业明细的待加工料卷批次号去掉“{批次号},”
+                this.baseMapper.processDeleteBatchNumber(batchnumber, processoperationid);
+                //处理后续工序状态
+                Map<String, Object> params2 = new HashMap<>();
+                params2.put("processId", processoperationid);
+                R r2 = apsProcessOperationService.updateBorrowProcess(params2);
+                if (!r2.getCode().equals("200")) {
+                    return R.error(r2.getMsg());
+                }
+            }
+        }
+
+        return R.ok();
+    }
 }

+ 19 - 0
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/service/impl/ApsProcessOutputProductImpl.java

@@ -0,0 +1,19 @@
+package com.rongwei.bscommon.sys.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.rongwei.bscommon.sys.dao.ApsProcessOutputProductDao;
+import com.rongwei.bscommon.sys.service.ApsProcessOutputProductService;
+import com.rongwei.bsentity.domain.ApsProcessOutputProductDo;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ */
+@Service
+public class ApsProcessOutputProductImpl extends ServiceImpl<ApsProcessOutputProductDao, ApsProcessOutputProductDo> implements ApsProcessOutputProductService {
+
+}
+
+
+
+

+ 207 - 0
cx-aps/cx-aps-entity/src/main/java/com/rongwei/bsentity/domain/ApsProcessOutputProductDo.java

@@ -0,0 +1,207 @@
+package com.rongwei.bsentity.domain;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * aps_process_output_product
+ * @author 
+ */
+@Data
+public class ApsProcessOutputProductDo implements Serializable {
+    /**
+     * 主键ID
+     */
+    private String id;
+
+    private String tenantid;
+
+    /**
+     * 扩展json格式配置
+     */
+    private String roption;
+
+    /**
+     * 是否删除Y/N
+     */
+    private String deleted;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 创建时间
+     */
+    private Date createdate;
+
+    /**
+     * 创建用户ID
+     */
+    private String createuserid;
+
+    /**
+     * 修改日期
+     */
+    private Date modifydate;
+
+    /**
+     * 修改用户ID
+     */
+    private String modifyuserid;
+
+    /**
+     * 创建人
+     */
+    private String createusername;
+
+    /**
+     * 修改人
+     */
+    private String modifyusername;
+
+    /**
+     * 所属工厂
+     */
+    private String ownedfactory;
+
+    /**
+     * 坯料计划ID
+     */
+    private String blankid;
+
+    /**
+     * 订单产品ID
+     */
+    private String productid;
+
+    /**
+     * 订单产品
+     */
+    private String productname;
+
+    /**
+     * 替代产品ID
+     */
+    private String replaceproductid;
+
+    /**
+     * 替代产品
+     */
+    private String replaceproductname;
+
+    /**
+     * 订单总数量
+     */
+    private BigDecimal ordertatal;
+
+    /**
+     * 数量单位
+     */
+    private String countunit;
+
+    /**
+     * 单卷重(起)
+     */
+    private BigDecimal onerollweigthstart;
+
+    /**
+     * 单卷重(止)
+     */
+    private BigDecimal onerollweigthend;
+
+    /**
+     * 输出单卷重
+     */
+    private BigDecimal outputonerollweigth;
+
+    /**
+     * 单卷输出卷数
+     */
+    private Integer outputonerollcount;
+
+    /**
+     * 成品备料卷数
+     */
+    private Integer hadrollcount;
+
+    /**
+     * 输出成品
+     */
+    private String outputresult;
+
+    /**
+     * 计划输出卷数
+     */
+    private Integer planoutputrollcount;
+
+    /**
+     * 计划输出订单卷数
+     */
+    private Integer planoutputorderroll;
+
+    /**
+     * 计划输出订单重量
+     */
+    private BigDecimal planoutputonerollweight;
+
+    /**
+     * 实际可输出卷数
+     */
+    private Integer actualcanoutputroll;
+
+    /**
+     * 输出不合格卷数
+     */
+    private Integer outputunqualifiedroll;
+
+    /**
+     * 可输出订单卷数
+     */
+    private Integer canoutputroll;
+
+    /**
+     * 可输出订单重量
+     */
+    private BigDecimal canoutputorderweight;
+
+    /**
+     * 物料ID
+     */
+    private String materialid;
+
+    /**
+     * 产品类型
+     */
+    private String producttype;
+
+    /**
+     * 合金
+     */
+    private String alloy;
+
+    /**
+     * 合金状态
+     */
+    private String alloystatus;
+
+    /**
+     * 厚度(mm)
+     */
+    private BigDecimal thickness;
+
+    /**
+     * 宽度(mm)
+     */
+    private BigDecimal prowidth;
+
+    /**
+     * 长度(mm)
+     */
+    private BigDecimal prolength;
+
+    private static final long serialVersionUID = 1L;
+}

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

@@ -0,0 +1,27 @@
+package com.rongwei.bsentity.vo;
+
+import com.rongwei.bsentity.domain.ApsBlankOrderDo;
+import com.rongwei.bsentity.domain.ApsProcessOutputProductDo;
+import com.rongwei.bsentity.domain.ApsProductDetailDo;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author :sc
+ * @since :2024/4/30
+ */
+@Data
+public class CheckAndSaveOrUpdateBlankReq {
+    //主表坯料计划
+    private ApsBlankOrderDo apsBlankOrderDo;
+
+    //子表输出成品
+    private List<ApsProcessOutputProductDo> apsProcessOutputProductDoList;
+
+    //订单产品明细表
+    private List<ApsProductDetailDo> apsProductDetailDoList;
+
+    //在制品ID
+    private String progressId;
+}

+ 15 - 0
cx-aps/cx-aps-server/src/main/java/com/rongwei/bsserver/controller/ApsBlankOrderController.java

@@ -3,6 +3,7 @@ package com.rongwei.bsserver.controller;
 
 import com.rongwei.bscommon.sys.service.ApsBlankOrderService;
 import com.rongwei.bsentity.vo.ApsPlanVo;
+import com.rongwei.bsentity.vo.CheckAndSaveOrUpdateBlankReq;
 import com.rongwei.bsentity.vo.OrderLockVo;
 import com.rongwei.rwcommon.base.R;
 import lombok.extern.slf4j.Slf4j;
@@ -124,5 +125,19 @@ public class ApsBlankOrderController {
             return R.error("插单异常:" + e.getMessage());
         }
     }
+
+    /**
+     * 校验和保存坯料计划
+     */
+    @PostMapping("/checkAndSaveOrUpdateBlank")
+    public R checkAndSaveOrUpdateBlank(@RequestBody CheckAndSaveOrUpdateBlankReq req){
+        try {
+            return apsBlankOrderService.checkAndSaveOrUpdateBlank(req);
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("校验和保存坯料计划异常:"+e.getMessage());
+            return R.error("校验和保存坯料计划异常:"+e.getMessage());
+        }
+    }
 }