package com.rongwei.bscommon.sys.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rongwei.bscommon.sys.dao.*;
import com.rongwei.bscommon.sys.service.*;
import com.rongwei.bsentity.domain.*;

import com.rongwei.bsentity.vo.*;
import com.rongwei.rwadmincommon.system.vo.SysUserVo;
import com.rongwei.rwcommon.base.R;
import com.rongwei.rwcommon.base.exception.CustomException;
import com.rongwei.rwcommon.utils.SecurityUtil;
import com.rongwei.rwcommon.utils.StringUtils;
import com.rongwei.rwcommonentity.commonservers.vo.SysSerialVo;
import com.rongwei.safecommon.fegin.CXAdminFeginClient;
import com.rongwei.safecommon.utils.CXCommonUtils;
import com.rongwei.safecommon.utils.SaveConstans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 *
 */
@Service
public class ApsReportRecordsServiceImpl extends ServiceImpl<ApsReportRecordsDao, ApsReportRecordsDo>
        implements ApsReportRecordsService {
    @Autowired
    private ApsReportOutputService apsReportOutputService;
    @Autowired
    private ApsReportCheckoutService apsReportCheckoutService;
    @Autowired
    private ApsReportMachiningService apsReportMachiningService;
    @Autowired
    private ApsWorkInProgressInventoryService apsWorkInProgressInventoryService;
    @Autowired
    private ApsProcessOperationProcessEquService apsProcessOperationProcessEquService;
    @Resource
    private ApsProcessOperationProcessEquDao apsProcessOperationProcessEquDao;
    @Resource
    private ApsProcessOperationDao apsProcessOperationDao;
    @Autowired
    private ApsProcessOperationService apsProcessOperationService;
    @Autowired
    private ApsProductionOrderService apsProductionOrderService;
    @Autowired
    private ApsBlankOrderService apsBlankOrderService;
    @Autowired
    private ApsProcessOperationOutMaterService apsProcessOperationOutMaterService;
    @Autowired
    private ApsAlloyService apsAlloyService;
    @Autowired
    private ApsAlloyCompositionService apsAlloyCompositionService;
    @Autowired
    private ApsReportBlankCompentService apsReportBlankCompentService;
    @Resource
    private CXAdminFeginClient cxAdminFeginClient;
    @Autowired
    private ApsCraftStepService apsCraftStepService;
    @Autowired
    private ApsCraftEquService apsCraftEquService;
    @Autowired
    private ReportCheckServiceImpl reportCheckService;
    @Resource
    private ApsProcessOutputProductDao apsProcessOutputProductDao;

    @Override
    @Transactional
    public R cancelRecord(Map<String, String> req) {
        String recordId;
        try {
            recordId = req.get("ID");
        } catch (Exception e) {
            e.printStackTrace();
            return R.error("报工记录ID错误");
        }
        //查询报工详情
        ApsReportRecordsDo recordsDo = this.getById(recordId);
        if (ObjectUtil.isEmpty(recordsDo)) {
            return R.error("报工记录未找到");
        }
        //删除报工记录
        this.removeById(recordId);
        //删除报工输出物料
        apsReportOutputService.remove(new QueryWrapper<ApsReportOutputDo>().lambda().eq(ApsReportOutputDo::getMainid, recordId));
        //删除报工加工参数
        apsReportMachiningService.remove(new QueryWrapper<ApsReportMachiningDo>().lambda().eq(ApsReportMachiningDo::getMainid, recordId));
        //删除报工检查项
        apsReportCheckoutService.remove(new QueryWrapper<ApsReportCheckoutDo>().lambda().eq(ApsReportCheckoutDo::getMainid, recordId));

        //更新输入物料在制品：如果输入物料有批次号，并且在制品库存中有输入物料批次号的在制品，则更新该在制品的在制品状态=待加工
        if (ObjectUtil.isNotEmpty(recordsDo.getBatchnumber())) {
            ApsWorkInProgressInventoryDo apsWorkInProgressInventoryDo = new ApsWorkInProgressInventoryDo();
            apsWorkInProgressInventoryDo.setWorkinprocessstatus("待加工");
            apsWorkInProgressInventoryService.update(apsWorkInProgressInventoryDo, new QueryWrapper<ApsWorkInProgressInventoryDo>().lambda().eq(ApsWorkInProgressInventoryDo::getBatchnumber, recordsDo.getBatchnumber()));
        }

        //更新工序作业和作业明细
        //明细的已开工卷数=已开工卷数-1 ;明细的待报工记录ID=（空），设备的带报工记录ID=（空）；工序作业的已开工卷数-1

        //工序作业ID
        String processoperationid = recordsDo.getProcessoperationid();
        //工序作业明细ID
        String processequid = recordsDo.getProcessequid();

        //更新该工序作业的作业明细的作业状态字段、已开工卷数、明细的待报工记录ID=（空），加工中批次号=(空)
        apsProcessOperationProcessEquDao.updateByCancelRecord(processequid);

        //更新该工序作业的已开工卷数-1
        apsProcessOperationDao.updateByCancelRecord(processoperationid);

        //查询作业明细详情
        ApsProcessOperationProcessEquDo equDo = apsProcessOperationProcessEquDao.selectById(processequid);

        //更新设备的待报工记录ID
        apsProcessOperationProcessEquDao.updateEquByCancelRecord(equDo.getProcessdeviceid());

        //作业明细的作业状态
        /**
         * 如果已开工卷数=0，则=待开工；
         * 如果已开工卷数>0，并且完工状态=未完工，则=加工中；（先更新完工状态）
         * 如果未完工卷数=0，并且完工状态=已完工，则=已完工（先更新完工状态）
         */
        ApsProcessOperationProcessEquDo apsProcessOperationProcessEquDo = new ApsProcessOperationProcessEquDo();
        apsProcessOperationProcessEquDo.setId(equDo.getId());
        if (equDo.getStartingroll() == 0) {
            apsProcessOperationProcessEquDo.setWorkstatus("待开工");
            apsProcessOperationProcessEquDo.setActualstartdate(null);
        }
        if (equDo.getStartingroll() > 0 && equDo.getClosestatus().equals("未完工")) {
            apsProcessOperationProcessEquDo.setWorkstatus("加工中");
        }
        if (ObjectUtil.isNotEmpty(equDo.getUnfinishroll()) && equDo.getUnfinishroll() == 0) {
            apsProcessOperationProcessEquDo.setWorkstatus("已完工");
        }

        /**
         * 如果输入物料有批次号，则
         */
        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());
            }
        }

        apsProcessOperationProcessEquDao.updateById(apsProcessOperationProcessEquDo);

        //更新其余信息
        CommonUpdateProductionStatusReq commonUpdateProductionStatusReq = new CommonUpdateProductionStatusReq();
        commonUpdateProductionStatusReq.setProcessOperationEquId(equDo.getId());
        apsProcessOperationProcessEquService.updateProductionStatus(commonUpdateProductionStatusReq);

        return R.ok();
    }

    @Override
    @Transactional
    public R startReport(StartRePortReq req) {

//        //根据设备ID查询对应车间代号和设备代号
//        OrganizationCodeAndDeviceCodeVo organizationCodeAndDeviceCodeVo = this.baseMapper.selectOrganizationCodeAndDeviceCode(req.getProcessdeviceid());
//        if(ObjectUtil.isEmpty(organizationCodeAndDeviceCodeVo)){
//            return R.error("未找到对应的车间代号和设备代号");
//        }
        //根据作业明细ID查询作业明细详情
        ApsProcessOperationProcessEquDo apsProcessOperationProcessEquDo = apsProcessOperationProcessEquService.getById(req.getUseDeviceId());
        //查询工序作业的详情
        ApsProcessOperationDo apsProcessOperationDo = apsProcessOperationService.getById(apsProcessOperationProcessEquDo.getProcessid());
        //查询坯料计划的详情
        ApsBlankOrderDo apsBlankOrderDo = apsBlankOrderService.getById(apsProcessOperationDo.getBlankid());
        //查询订单的详情
        ApsProductionOrderDo apsProductionOrderDo = apsProductionOrderService.getById(apsBlankOrderDo.getProductionorderid());


        //获取当前用户相关信息
        SysUserVo currentUser = CXCommonUtils.getCurrentUser();
        String tenantId = currentUser.getOrganizationDoList().get(0).getFullpid().split(",")[1];

        //查询此工序对应工艺步骤中，对应设备的设备参数
        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)) {
            //查询设备参数子表
            ApsCraftEquDo apsCraftEquDo = apsCraftEquService.getOne(new QueryWrapper<ApsCraftEquDo>().lambda().eq(ApsCraftEquDo::getMainid, craftStepDo.getId()).eq(ApsCraftEquDo::getResourceid, apsProcessOperationProcessEquDo.getProcessdeviceid()).eq(ApsCraftEquDo::getTenantid, tenantId));
            if (ObjectUtil.isNotEmpty(apsCraftEquDo)) {
                equparames = apsCraftEquDo.getEquparames();
            }
        }


        //新增主表报工记录信息
        ApsReportRecordsDo apsReportRecordsDo = new ApsReportRecordsDo();
        apsReportRecordsDo.setId(SecurityUtil.getUUID());
        apsReportRecordsDo.setTenantid(tenantId);
        //工序作业ID
        apsReportRecordsDo.setProcessoperationid(apsProcessOperationDo.getId());
        //作业明细ID
        apsReportRecordsDo.setProcessequid(apsProcessOperationProcessEquDo.getId());
        //输入物料的批次号
        apsReportRecordsDo.setBatchnumber(req.getInputBatchNumber());
        //实际输入物料
        apsReportRecordsDo.setActualinputmaterial(apsProcessOperationDo.getPlaninput());
        //主操作员
        apsReportRecordsDo.setChiefoperatorid(currentUser.getId());
        apsReportRecordsDo.setChiefoperatorname(currentUser.getName());
        //开工时间
        apsReportRecordsDo.setStartworktime(DateUtil.date());
//        //报工时间
//        apsReportRecordsDo.setReportworktime(DateUtil.date());
        //报工状态
        apsReportRecordsDo.setReportworkstatus("已开工");
        apsReportRecordsDo.setCheckstatus("待检验");
        //设备参数
        apsReportRecordsDo.setDeviceparm(equparames);

        //保存主表
        this.save(apsReportRecordsDo);

        //=================更新工序作业明细的报工ID、已开工卷数============
        //将报工记录ID存入工序作业的设备子表中
        ApsProcessOperationProcessEquDo needUpdateProcessOperationProcessEqu = new ApsProcessOperationProcessEquDo();
        needUpdateProcessOperationProcessEqu.setId(apsProcessOperationProcessEquDo.getId());

        //更新待报工记录ID
        needUpdateProcessOperationProcessEqu.setWaitreportid(apsReportRecordsDo.getId());
        //获取作业明细的已开工卷数
        Integer startingroll = apsProcessOperationProcessEquDo.getStartingroll();
        Integer newStartingRoll = startingroll + 1;
        //更新已开工卷数
        needUpdateProcessOperationProcessEqu.setStartingroll(newStartingRoll);
        if (newStartingRoll.equals(1)) {
            //更新实际开工时间
            needUpdateProcessOperationProcessEqu.setActualstartdate(DateUtil.date());
        }
        //加工中批次号
        if (ObjectUtil.isNotEmpty(req.getInputBatchNumber())) {
            needUpdateProcessOperationProcessEqu.setDoingbatchnumber(req.getInputBatchNumber());
        }
        //更新工序作业明细的完工状态和作业状态
        if (apsProcessOperationProcessEquDo.getWorkstatus().equals("待开工")) {
            needUpdateProcessOperationProcessEqu.setWorkstatus("加工中");
        }
        apsProcessOperationProcessEquService.updateById(needUpdateProcessOperationProcessEqu);

        //===============更新工序作业==================
        this.baseMapper.updateProcessActualStartDate(apsProcessOperationDo.getId());

        //=============更新设备的报工记录ID=============
        this.baseMapper.updateDeviceWaitReportId(apsReportRecordsDo.getId(), apsProcessOperationProcessEquDo.getProcessdeviceid());

        //==========输入物料有批次号==============
        if (ObjectUtil.isNotEmpty(req.getInputBatchNumber())) {
            //如果该工序作业没有前道工序作业
//            if (ObjectUtil.isEmpty(apsProcessOperationDo.getPreviousprocessid())) {
//                //该工序作业的待加工料卷批次号去掉“{批次号}，”或者“,{批次号}”
//                this.baseMapper.updateBatchMaterialProcess(req.getInputBatchNumber(), apsProcessOperationProcessEquDo.getId());
//            } else {//如果该工序作业有前道工序作业
//                //前道工序作业 的 所有后道工序作业（包含本工序作业【即所有与本工序同级的工序作业】） 的待加工料卷批次号去掉“{批次号}，”或者“,{批次号}”
//                //查询前道工序作业的所有后道工序作业
//                List<ApsProcessOperationDo> nextProcessList = apsProcessOperationService.list(new QueryWrapper<ApsProcessOperationDo>().lambda().eq(ApsProcessOperationDo::getPreviousprocessid, apsProcessOperationDo.getPreviousprocessid()));
//                String collect = nextProcessList.stream().map(ApsProcessOperationDo::getId).collect(Collectors.joining("','"));
//                String processIds = "'" + collect + "'";
//                this.baseMapper.updateBatchMaterialProcessBatch(req.getInputBatchNumber(), processIds);
//            }
            /**
             * 如果该工序作业明细有前道工序作业明细，
             * 则将前道工序作业明细的所有后道工序作业明细的待加工料卷批次号去掉“{批次号}，”
             */
            if (ObjectUtil.isNotEmpty(apsProcessOperationProcessEquDo.getPreviousprocessesids())) {
                this.baseMapper.updateAllProcessEquBatchNumber(req.getInputBatchNumber(), apsProcessOperationProcessEquDo.getPreviousprocessesids());
            }
        }

        //==========输出物料子表信息============
        InsertMyReportOutputReq req2 = new InsertMyReportOutputReq();
        req2.setProcessId(apsProcessOperationDo.getId());
        req2.setIfBlankProcess(apsProcessOperationDo.getIfblankprocess());
        req2.setBlankType(apsBlankOrderDo.getBlanktype());
        req2.setMainId(apsReportRecordsDo.getId());
        req2.setLevel(apsProcessOperationDo.getLevel());
        R r = apsReportOutputService.insertMyReportOutputWithOutBatchNumber(req2);
        if (!r.getCode().equals("200")) {
            return R.error(r.getMsg());
        }

        //=============加工参数子表信息、检查项目子表信息================
        if (ObjectUtil.isNotEmpty(apsProcessOperationDo.getProcess())) {
            //根据工序查询其工序的加工参数
            List<ApsParameterDo> parameterDoList = this.baseMapper.selectApsParameterByProcess(apsProcessOperationDo.getProcess());
            List<ApsReportMachiningDo> needInsertApsReportMachingList = new LinkedList<>();
            if (ObjectUtil.isNotEmpty(parameterDoList)) {
                for (ApsParameterDo apsParameterDo : parameterDoList) {
                    if (ObjectUtil.isEmpty(apsParameterDo)) {
                        continue;
                    }
                    ApsReportMachiningDo apsReportMachiningDo = new ApsReportMachiningDo();
                    apsReportMachiningDo.setId(SecurityUtil.getUUID());
                    apsReportMachiningDo.setTenantid(tenantId);
                    apsReportMachiningDo.setMainid(apsReportRecordsDo.getId());
                    apsReportMachiningDo.setMatching(apsParameterDo.getParameter());
                    needInsertApsReportMachingList.add(apsReportMachiningDo);
                }
                if (ObjectUtil.isNotEmpty(needInsertApsReportMachingList)) {
                    apsReportMachiningService.saveBatch(needInsertApsReportMachingList);
                }
            }

            //根据工序查询其工序的检查项目
            List<ApsCheckParameterDo> checkParameterDoList = this.baseMapper.selectApsCheckParameterByProcess(apsProcessOperationDo.getProcess());
            List<ApsReportCheckoutDo> needInsertApsReportCheckList = new LinkedList<>();
            if (ObjectUtil.isNotEmpty(checkParameterDoList)) {
                for (ApsCheckParameterDo apsCheckParameterDo : checkParameterDoList) {
                    if (ObjectUtil.isEmpty(apsCheckParameterDo)) {
                        continue;
                    }
                    ApsReportCheckoutDo apsReportCheckoutDo = new ApsReportCheckoutDo();
                    apsReportCheckoutDo.setId(SecurityUtil.getUUID());
                    apsReportCheckoutDo.setTenantid(tenantId);
                    apsReportCheckoutDo.setMainid(apsReportRecordsDo.getId());
                    apsReportCheckoutDo.setCheckitem(apsCheckParameterDo.getCheckparameter());
                    needInsertApsReportCheckList.add(apsReportCheckoutDo);
                }
                if (ObjectUtil.isNotEmpty(needInsertApsReportCheckList)) {
                    apsReportCheckoutService.saveBatch(needInsertApsReportCheckList);
                }
            }

        }
        //=============坯料成分子表信息=============
        //工序作业的是否坯料工序=是 时，根据客户合金成分设置自动生成
        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.getInputBatchNumber();
            //查询上一个的报工ID
            String lastReportRecordId = this.baseMapper.selectLastReoprtRecordByBatchNumber(inputBatchNumber);
            //查询上一个报工的坯料成分
            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);
        }
        //更新生产状态
        CommonUpdateProductionStatusReq req3 = new CommonUpdateProductionStatusReq();
        req3.setProcessOperationEquId(apsProcessOperationProcessEquDo.getId());
        R r2 = apsProcessOperationProcessEquService.updateProductionStatus(req3);
        if (!r2.getCode().equals("200")) {
            return R.error(r2.getMsg());
        }

        return R.ok(apsReportRecordsDo);
    }

    @Override
    @Transactional
    public R saveReport(SaveReportReq req) {
        //报工主表
        ApsReportRecordsDo apsReportRecordsDo = req.getApsReportRecordsDo();
        //报工输出物料
        List<ApsReportOutputDo> apsReportOutputDoList = req.getApsReportOutputDoList();
        //报工加工参数
        List<ApsReportMachiningDo> apsReportMachiningDoList = req.getApsReportMachiningDoList();
        //报工坯料成分
        List<ApsReportBlankCompentDo> apsReportBlankCompentDoList = req.getApsReportBlankCompentDoList();

        //没有新增，只会更新
        apsReportRecordsDo.setCheckstatus("待检验");

        if (ObjectUtil.isNotEmpty(apsReportOutputDoList)) {
            apsReportOutputService.updateBatchById(apsReportOutputDoList);
        }
        if (ObjectUtil.isNotEmpty(apsReportMachiningDoList)) {
            apsReportMachiningService.updateBatchById(apsReportMachiningDoList);
        }
        if (ObjectUtil.isNotEmpty(apsReportBlankCompentDoList)) {
            apsReportBlankCompentService.updateBatchById(apsReportBlankCompentDoList);
        }

        //查询当前的报工记录信息
        ApsReportRecordsDo nowReportRecordsDo = this.getById(apsReportRecordsDo.getId());

        //查询对应的工序作业信息
        ApsProcessOperationDo apsProcessOperationDo = apsProcessOperationService.getById(nowReportRecordsDo.getProcessoperationid());
        //查询对应的工序作业明细信息
        ApsProcessOperationProcessEquDo apsProcessOperationProcessEquDo = apsProcessOperationProcessEquService.getById(nowReportRecordsDo.getProcessequid());
        //查询对应的坯料计划信息
        ApsBlankOrderDo apsBlankOrderDo = apsBlankOrderService.getById(apsProcessOperationDo.getBlankid());
        //查询对应的订单评审信息
        ApsProductionOrderDo apsProductionOrderDo = apsProductionOrderService.getById(apsBlankOrderDo.getProductionorderid());

        //=============更新作业明细信息=============
        //更新待报工记录ID、已报工卷数
        //已报工卷数
        Integer reportroll = apsProcessOperationProcessEquDo.getReportroll();
        ApsProcessOperationProcessEquDo needUpdateProcessOperationProcessEquDo = new ApsProcessOperationProcessEquDo();
        needUpdateProcessOperationProcessEquDo.setId(apsProcessOperationProcessEquDo.getId());
        //已报工卷数+1
        needUpdateProcessOperationProcessEquDo.setReportroll(reportroll + 1);
        /**
         * 更新作业明细的完工状态
         * 如果未完工卷数=0，或者工序作业已完工状态=已完工，则=已完工
         * 如果未完工卷数>0，并且工序作业已完工状态=未完工，则=未完工
         */
        //计划加工卷数
        Integer planprocessrall = apsProcessOperationProcessEquDo.getPlanprocessrall();
        //未完工卷数=计划加工卷数-已报工卷数
        int unfinishroll = planprocessrall - needUpdateProcessOperationProcessEquDo.getReportroll();
        if (unfinishroll <= 0 || apsProcessOperationDo.getClosestatus().equals("已完工")) {
            needUpdateProcessOperationProcessEquDo.setClosestatus("已完工");
            //已完工时更新完工时间
            needUpdateProcessOperationProcessEquDo.setActualfinishdate(DateUtil.date());
        }
        if (unfinishroll > 0 && apsProcessOperationDo.getClosestatus().equals("未完工")) {
            needUpdateProcessOperationProcessEquDo.setClosestatus("未完工");
        }

        //带报工记录ID清空
        needUpdateProcessOperationProcessEquDo.setWaitreportid("");
        if (apsProcessOperationProcessEquDo.getClosestatus().equals("未完工") && apsProcessOperationProcessEquDo.getStartingroll() > 0) {
            needUpdateProcessOperationProcessEquDo.setWorkstatus("加工中");
        }
        if (ObjectUtil.isNotEmpty(unfinishroll) && unfinishroll == 0) {
            needUpdateProcessOperationProcessEquDo.setWorkstatus("已完工");
        }

        //清空加工中批次号
        needUpdateProcessOperationProcessEquDo.setDoingbatchnumber("");
        apsProcessOperationProcessEquService.updateById(needUpdateProcessOperationProcessEquDo);

        //==============更新工序作业信息==============
        this.baseMapper.updateProcessReportRoll(apsProcessOperationDo.getId());

        //=============更新设备的报工记录ID===========
        this.baseMapper.updateDeviceWorkId(apsProcessOperationProcessEquDo.getProcessdeviceid());

        //============保存（报工）时，生成炉号和批次号=============
        //获取设备/炉 的炉号（每月、每个设备/炉 更新）
        String heatNumber;//初始化炉号
        //调用通用接口生成炉号
        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 = codeData.get("code").toString();

        apsReportRecordsDo.setHeatnumber(heatNumber);
        //报工状态
        apsReportRecordsDo.setReportworkstatus("已报工");
        //如过报工时间为空，填入当前时间
        if (ObjectUtil.isEmpty(apsReportRecordsDo.getReportworktime())) {
            apsReportRecordsDo.setReportworktime(DateUtil.date());
        }

        this.updateById(apsReportRecordsDo);

        //物理删除原来的报工记录输出物料
        this.baseMapper.deleteOutputmaterialbyMainId(apsReportRecordsDo.getId());

        OrganizationCodeAndDeviceCodeVo organizationCodeAndDeviceCodeVo = this.baseMapper.selectOrganizationCodeAndDeviceCode(apsProcessOperationProcessEquDo.getProcessdeviceid());
        if (ObjectUtil.isEmpty(organizationCodeAndDeviceCodeVo)) {
            return R.error("未找到对应的车间代号和设备代号");
        }
        InsertMyReportOutputReq insertMyReportOutputReq = new InsertMyReportOutputReq();
        insertMyReportOutputReq.setMainId(apsReportRecordsDo.getId());
        insertMyReportOutputReq.setProcessId(apsProcessOperationDo.getId());
        insertMyReportOutputReq.setIfBlankProcess(apsProcessOperationDo.getIfblankprocess());
        insertMyReportOutputReq.setDeviceId(apsProcessOperationProcessEquDo.getProcessdeviceid());
        insertMyReportOutputReq.setMark(organizationCodeAndDeviceCodeVo.getOrganizationCode());
        insertMyReportOutputReq.setYearCode((DateUtil.year(DateUtil.date()) % 100) + "");
        insertMyReportOutputReq.setMonthCode(SaveConstans.MONTH_CODE_LIST.get(DateUtil.month(DateUtil.date())));
        insertMyReportOutputReq.setEquipmentCode(organizationCodeAndDeviceCodeVo.getDeviceCode());
        insertMyReportOutputReq.setHeatNumber(heatNumber);
        insertMyReportOutputReq.setInputBatchNumber(apsReportRecordsDo.getBatchnumber());
        insertMyReportOutputReq.setBlankType(apsBlankOrderDo.getBlanktype());
        insertMyReportOutputReq.setLevel(apsProcessOperationDo.getLevel());

        R r = apsReportOutputService.insertMyReportOutput(insertMyReportOutputReq);
        if (!r.getCode().equals("200")) {
            return R.error(r.getMsg());
        }

        //查询新的输出物料
        List<ApsReportOutputDo> newOutputDos = apsReportOutputService.list(new QueryWrapper<ApsReportOutputDo>().lambda().eq(ApsReportOutputDo::getMainid, apsReportRecordsDo.getId()));
        //填补对应的检验等级和是否合格
        if (apsReportOutputDoList.size() == newOutputDos.size()) {
            for (int i = 0; i < newOutputDos.size(); i++) {
                newOutputDos.get(i).setInsepctionlevel(apsReportOutputDoList.get(i).getInsepctionlevel());
                newOutputDos.get(i).setQualified(apsReportOutputDoList.get(i).getQualified());
            }
        }
        //更新输出物料
        apsReportOutputService.updateBatchById(newOutputDos);

        //=================新增在制品库存=================
        //查询报工记录对应的物料子表
        List<ApsReportOutputDo> apsReportOutputDos = apsReportOutputService.list(new QueryWrapper<ApsReportOutputDo>().lambda().eq(ApsReportOutputDo::getMainid, apsReportRecordsDo.getId()));

        if (ObjectUtil.isNotEmpty(apsReportOutputDos)) {
            //如果主表的批次号不为空，查找 在制品库存中是否有此 批次号 的数据，有 复制并删除原数据，坯料批次号 等坯料数据不变，其余数据变更
            if (ObjectUtil.isNotEmpty(apsReportRecordsDo.getBatchnumber())) {
                ApsWorkInProgressInventoryDo apsWorkInProgressInventoryDo = apsWorkInProgressInventoryService.getOne(new QueryWrapper<ApsWorkInProgressInventoryDo>().lambda().eq(ApsWorkInProgressInventoryDo::getDeleted, "0").eq(ApsWorkInProgressInventoryDo::getBatchnumber, apsReportRecordsDo.getBatchnumber()));
                //不为空，则删除数据（逻辑删除）
                if (ObjectUtil.isNotEmpty(apsWorkInProgressInventoryDo)) {
                    apsWorkInProgressInventoryService.removeById(apsWorkInProgressInventoryDo.getId());
                }
                //增加或者复制在制品库存
                addOrCopyWorkInProgress(apsReportOutputDos,
                        apsWorkInProgressInventoryDo,
                        apsProcessOperationProcessEquDo,
                        apsProcessOperationDo,
                        organizationCodeAndDeviceCodeVo,
                        apsProductionOrderDo,
                        apsBlankOrderDo);
            } else {
                addOrCopyWorkInProgress(apsReportOutputDos,
                        null,
                        apsProcessOperationProcessEquDo,
                        apsProcessOperationDo,
                        organizationCodeAndDeviceCodeVo,
                        apsProductionOrderDo,
                        apsBlankOrderDo);
            }

            //更新物料子表 对应 工序作业输出物料 的已输出卷数
            for (ApsReportOutputDo apsReportOutputDo : apsReportOutputDos) {
                //需要更新（+1）的工序作业输出物料ID
                String outputid = apsReportOutputDo.getOutputid();
                apsProcessOutputProductDao.updateRollNumById(outputid);
            }
        }

        //=========更新生产状态等=============
        //更新生产状态
        CommonUpdateProductionStatusReq req3 = new CommonUpdateProductionStatusReq();
        req3.setProcessOperationEquId(apsProcessOperationProcessEquDo.getId());
        R r2 = apsProcessOperationProcessEquService.updateProductionStatus(req3);
        if (!r2.getCode().equals("200")) {
            return R.error(r2.getMsg());
        }

        //===========提交校验================
        //如果输出物料中不存在 检验等级 为 待判 的，则直接提交校验
        //获取当前的输出物料
        List<ApsReportOutputDo> outputDos = apsReportOutputService.list(new QueryWrapper<ApsReportOutputDo>().lambda().eq(ApsReportOutputDo::getMainid, apsReportRecordsDo.getId()));
        List<ApsReportOutputDo> collect = outputDos.stream().filter(item -> item.getInsepctionlevel().equals(SaveConstans.CheckLevel.WAITING_JUDGMENT)).collect(Collectors.toList());
        if (collect.size() > 0) {
            return R.ok();
        }
        //遍历输出物料 拼接输出物料描述，并更新
        for (ApsReportOutputDo outputDo : outputDos) {
            ApsReportOutputDo needUpdate = new ApsReportOutputDo();
            needUpdate.setId(outputDo.getId());
            String outputdesc = "";
            outputdesc += outputDo.getOutputmaterial().split(" ")[0];
            outputdesc += " 厚" + outputDo.getThickness() + "*宽" + outputDo.getWidth();
            if (ObjectUtil.isNotEmpty(outputDo.getLength())) {
                outputdesc += "*长" + outputDo.getLength();
            }
            outputdesc += " mm " + outputDo.getWeight() + "吨";
            needUpdate.setOutputdesc(outputdesc);
            apsReportOutputService.updateById(needUpdate);
        }
        //调用提交检验接口
        R r1 = reportCheckService.updateRelevantInformation(apsReportRecordsDo.getId());
        if (!r1.getCode().equals("200")) {
            throw new CustomException(r1.getMsg());
        }
        //当前登录人
        SysUserVo currentUser = CXCommonUtils.getCurrentUser();
        //更新检查记录的检验人、检验时间
        ApsReportRecordsDo needUpdate = new ApsReportRecordsDo();
        needUpdate.setId(apsReportRecordsDo.getId());
        needUpdate.setCheckid(currentUser.getId());
        needUpdate.setCheckusername(currentUser.getName());
        needUpdate.setCheckdate(DateUtil.date());
        this.updateById(needUpdate);

        return R.ok();
    }

    private void addOrCopyWorkInProgress(List<ApsReportOutputDo> apsReportOutputDos,
                                         ApsWorkInProgressInventoryDo apsWorkInProgressInventoryDo,
                                         ApsProcessOperationProcessEquDo apsProcessOperationProcessEquDo,
                                         ApsProcessOperationDo apsProcessOperationDo,
                                         OrganizationCodeAndDeviceCodeVo organizationCodeAndDeviceCodeVo,
                                         ApsProductionOrderDo apsProductionOrderDo,
                                         ApsBlankOrderDo apsBlankOrderDo) {
        List<ApsWorkInProgressInventoryDo> needAddWorkInProgressInventoryList = new LinkedList<>();
        for (ApsReportOutputDo apsReportOutputDo : apsReportOutputDos) {
            ApsWorkInProgressInventoryDo workInProgressInventoryDo = new ApsWorkInProgressInventoryDo();
            workInProgressInventoryDo.setId(SecurityUtil.getUUID());
            //获取当前用户相关信息
            SysUserVo currentUser = CXCommonUtils.getCurrentUser();
            String tenantId = currentUser.getOrganizationDoList().get(0).getFullpid().split(",")[1];
            workInProgressInventoryDo.setTenantid(tenantId);
            //报工输出物料的批次号
            workInProgressInventoryDo.setBlankbatchnumber(apsReportOutputDo.getOutputnumber());
            //报工输出物料的主键ID
            workInProgressInventoryDo.setBlankid(apsReportOutputDo.getId());
            //报工输出物料的报工物料描述
            workInProgressInventoryDo.setBlankname(apsReportOutputDo.getOutputmaterial());
            //报工对应工序作业的坯料计划的坯料类型
            workInProgressInventoryDo.setBlanktype(apsBlankOrderDo.getBlanktype());
            if (ObjectUtil.isNotEmpty(apsWorkInProgressInventoryDo)) {
                workInProgressInventoryDo.setBlankbatchnumber(apsWorkInProgressInventoryDo.getBlankbatchnumber());
                workInProgressInventoryDo.setBlankid(apsWorkInProgressInventoryDo.getBlankid());
                workInProgressInventoryDo.setBlankname(apsWorkInProgressInventoryDo.getBlankname());
                workInProgressInventoryDo.setBlanktype(apsWorkInProgressInventoryDo.getBlanktype());
            }
            //报工记录对应的作业明细ID
            workInProgressInventoryDo.setProcessoperationequid(apsProcessOperationProcessEquDo.getId());
            //报工记录对应的工序作业ID
            workInProgressInventoryDo.setProcessoperationid(apsProcessOperationDo.getId());
            //报工记录ID
            workInProgressInventoryDo.setWorkreportrecordid(apsProcessOperationProcessEquDo.getWaitreportid());
            //报工记录输出物料对应的工序作业输出物料的主键ID
            workInProgressInventoryDo.setJoboutputmaterialid(apsReportOutputDo.getOutputid());
            //报工记录输出物料的主键ID
            workInProgressInventoryDo.setReportoutputmaterialid(apsReportOutputDo.getId());
            //输出物料的批次号
            workInProgressInventoryDo.setBatchnumber(apsReportOutputDo.getOutputnumber());
            //报工记录输出物料的报工物料描述
            workInProgressInventoryDo.setWorkinprocess(apsReportOutputDo.getOutputmaterial());
            //报工记录的报工日期
            workInProgressInventoryDo.setProductdate(DateUtil.date());
            //报工记录对应工序作业的加工设备所属工厂名称
            workInProgressInventoryDo.setProductfactory(organizationCodeAndDeviceCodeVo.getOwnedFactory());
            //报工记录对应工序作业明细的加工车间
            workInProgressInventoryDo.setProductworkshop(apsProcessOperationProcessEquDo.getProcessworkshop());
            //报工记录对应工序作业明细的加工设备
            workInProgressInventoryDo.setProductdevice(apsProcessOperationProcessEquDo.getProcessdevice());
            //工序作业的客户名称
            workInProgressInventoryDo.setCustomername(apsProductionOrderDo.getCustomname());
            //报工记录对应工序作业的订单号
            workInProgressInventoryDo.setOrdernumber(apsProductionOrderDo.getOrderno());
            workInProgressInventoryDo.setWorkinprocessstatus("待检验");

            needAddWorkInProgressInventoryList.add(workInProgressInventoryDo);
        }
        if (ObjectUtil.isNotEmpty(needAddWorkInProgressInventoryList)) {
            apsWorkInProgressInventoryService.saveBatch(needAddWorkInProgressInventoryList);
        }
    }

}




