package cn.estsh.i3plus.ext.mes.apiservice.serviceimpl.base.bu;

import cn.estsh.i3plus.ext.mes.api.base.IProdOrgExtService;
import cn.estsh.i3plus.ext.mes.api.base.IShiftExtService;
import cn.estsh.i3plus.ext.mes.api.base.ISxMesHttpService;
import cn.estsh.i3plus.ext.mes.api.base.bu.IBuWorkOrderExtService;
import cn.estsh.i3plus.ext.mes.api.base.bu.IBusiConfigService;
import cn.estsh.i3plus.ext.mes.api.busi.IWorkOrderLogExtService;
import cn.estsh.i3plus.ext.mes.api.busi.IWorkOrderStartService;
import cn.estsh.i3plus.ext.mes.api.busi.bu3.ISxUnbindProduceSnService;
import cn.estsh.i3plus.ext.mes.apiservice.controller.base.EmailPushService;
import cn.estsh.i3plus.ext.mes.apiservice.dao.bu3.ISxBuWorkOrderDao;
import cn.estsh.i3plus.ext.mes.apiservice.util.SxDateRangeUtils;
import cn.estsh.i3plus.ext.mes.apiservice.util.SxMesHttpUtil;
import cn.estsh.i3plus.ext.mes.icloud.sdk.IQmsReworkRangeCloud;
import cn.estsh.i3plus.ext.mes.icloud.sdk.IWmsErpHouseCheckCloud;
import cn.estsh.i3plus.ext.mes.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pojo.model.ExcelWorkOrderDto;
import cn.estsh.i3plus.ext.mes.pojo.model.GenerateWorkOrderDto;
import cn.estsh.i3plus.ext.mes.pojo.model.WorkOrderPageVo;
import cn.estsh.i3plus.ext.mes.pojo.model.WorkOrderQueryDto;
import cn.estsh.i3plus.ext.mes.pojo.model.bu3.SxOutPutStatisticsModel;
import cn.estsh.i3plus.ext.mes.pojo.model.ep.EpOutPutStatisticsModel;
import cn.estsh.i3plus.ext.mes.pojo.repository.*;
import cn.estsh.i3plus.ext.mes.pojo.util.ConvertBeanExt;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtEnumUtil;
import cn.estsh.i3plus.mes.api.iservice.busi.IDataAuthService;
import cn.estsh.i3plus.mes.api.iservice.busi.ISyncFuncService;
import cn.estsh.i3plus.mes.apiservice.util.DateUtil;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.exception.BaseImppException;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.tool.JsonUtilTool;
import cn.estsh.i3plus.platform.common.tool.MathOperation;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.platform.common.util.MesConstWords;
import cn.estsh.i3plus.pojo.base.bean.BaseResultBean;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.bean.ListPager;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.base.common.PagerHelper;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.*;
import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel;
import cn.estsh.i3plus.pojo.mes.model.MesButtonFlagModel;
import cn.estsh.i3plus.pojo.mes.repository.MesPackageDetailRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesProdBindRecordRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesWorkCenterRepository;
import cn.estsh.i3plus.pojo.mes.sqlpack.MesHqlPack;
import cn.estsh.i3plus.pojo.platform.bean.SysRole;
import cn.estsh.i3plus.pojo.wms.modelbean.MailMessageModel;
import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.util.ImppRedis;
import cn.estsh.impp.framework.boot.util.SpringContextsUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author yumingxing
 * @version 1.0
 * @date 2021/1/13 9:28
 **/
@Service
@Slf4j
public class BuWorkOrderExtService implements IBuWorkOrderExtService {

    @Autowired
    private MesWorkOrderExtRepository workOrderExtRepository;

    @Autowired
    private MesWorkOrderLogExtRepository workOrderLogRepository;
    @Autowired
    private MesPartExtRepository partExtRepository;
    @Autowired
    private MesWorkCenterRepository workCenterRepository;

    @Autowired
    private ISyncFuncService syncFuncService;

    @Autowired
    private IDataAuthService dataAuthService;

    @Autowired
    private MesAffiliatedStartConfigRepository affiliatedStartConfigRepository;

    @Autowired
    private IWorkOrderLogExtService workOrderLogExtService;

    @Autowired
    private IWmsErpHouseCheckCloud wmsErpHouseCheckCloud;

    @Autowired
    private IQmsReworkRangeCloud reworkRangeCloud;

    @Autowired
    private EmailPushService emailPushService;

    @Autowired
    private IProdOrgExtService prodOrgExtService;

    @Autowired
    private IShiftExtService shiftExtService;

    @Autowired
    private IBusiConfigService busiConfigService;

    @Autowired
    private ISxMesHttpService httpService;

    @Resource(name = MesExtConstWords.REDIS_MES)
    private ImppRedis redisMes;

    @Autowired
    private MesProdBindRecordRepository prodBindRecordRepository;

    @Autowired
    private MesProduceSnExtRepository produceSnExtRepository;

    @Autowired
    private MesPackageExtRepository packageExtRepository;

    @Autowired
    private MesPackageDetailRepository packageDetailRepository;

    @Autowired
    private MesProdBindRecordExtRepository prodBindRecordExtRepository;

    @Autowired
    private MesOutPutStatisticsRepository outPutStatisticsRepository;

    @Autowired
    private ISxUnbindProduceSnService unbindProduceSnService;

    @Autowired
    private MesUnbindProduceSnRepository unbindProduceSnRepository;

    @Autowired
    private MesUnbindProduceSnTravelRepository unbindProduceSnTravelRepository;

    @Autowired
    private ISxBuWorkOrderDao buWorkOrderDao;

    /**
     * 生成生产工单
     *
     * @param workOrderDto 生产工单
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertManualGenerate(GenerateWorkOrderDto workOrderDto) {
        MesWorkOrderExt mesWorkOrderExt = new MesWorkOrderExt();
        Double qty = workOrderDto.getQty();
        Double planQty = workOrderDto.getPlanQty();
        if(planQty > qty){
            throw new BaseImppException("计划返工数量不能大于计划生产数量");
        }
        BeanUtils.copyProperties(workOrderDto,mesWorkOrderExt);
        String userName = AuthUtil.getSessionUser().getUserName();
        String organizeCode = AuthUtil.getOrganize().getOrganizeCode();
        mesWorkOrderExt.setOrderNo(getOrderNo(userName,organizeCode));
        mesWorkOrderExt.setWorkOrderSource(MesExtEnumUtil.WORK_ORDER_SOURCE.MANUALLY_GENERATE.getValue());
        addWorkOrder(mesWorkOrderExt);
    }

    private void addWorkOrder(MesWorkOrderExt mesWorkOrderExt) {
        String organizeCode = AuthUtil.getOrganize().getOrganizeCode();
        Integer workOrderType = mesWorkOrderExt.getWorkOrderType();
        MesPartExt mesPart = getPart(mesWorkOrderExt, organizeCode);
        if(mesPart == null) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("物料【%s】不存在",mesWorkOrderExt.getPartNo())
                    .build();
        }
        //如果是返工工单 设置是否生成条码为不生成
        if (MesExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue() == workOrderType) {
            mesWorkOrderExt.setSnCreateStatus(MesExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.NO_CREATE.getValue());
        } else {
            //不是返工工单
            //判断物料是否需要生成条码
            //if (!ObjectUtils.isEmpty(mesPart))
            Integer isCreateSn = mesPart.getIsCreateSn();
            if (isCreateSn != null && CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue() == isCreateSn) {
                mesWorkOrderExt.setSnCreateStatus(MesExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.UN_CREATE.getValue());
            } else {
                mesWorkOrderExt.setSnCreateStatus(MesExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.NO_CREATE.getValue());
            }
        }

        //净水器线代码
        MesBusiConfig waterPurifierCode = busiConfigService.getBusiConfigByCfgCode(organizeCode, MesExtConstWords.WATER_PURIFIER_CODE);
        //净水器线校验计划数量必须为该机型包装数量的倍数
        List<String> waterPurifierCodeList = !Optional.ofNullable(waterPurifierCode).isPresent() || StringUtils.isEmpty(waterPurifierCode.getCfgValue()) ? new ArrayList<>() : Arrays.asList(waterPurifierCode.getCfgValue().split(MesExtConstWords.COMMA));
        if (!CollectionUtils.isEmpty(waterPurifierCodeList) && waterPurifierCodeList.contains(mesWorkOrderExt.getWorkCenterCode())) {
            MesPartExt part = getPart(mesWorkOrderExt, organizeCode);
            if (mesWorkOrderExt.getQty() % part.getQty2() != 0) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("工单【%s】计划数量必须为机型【%s】包装数量【%s】的倍数",
                                mesWorkOrderExt.getOrderNo(), part.getPartNo(), part.getQty2().toString())
                        .build();
            }

            if (mesWorkOrderExt.getPlanQty() % part.getQty2() != 0) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("工单【%s】改造数量必须为机型【%s】包装数量【%s】的倍数",
                                mesWorkOrderExt.getOrderNo(), part.getPartNo(), part.getQty2().toString())
                        .build();
            }
        }

        mesWorkOrderExt.setWorkOrderStatus(MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue());

        mesWorkOrderExt.setCreateDatetime(DateUtil.formatDate());
        mesWorkOrderExt.setOrganizeCodeExt(organizeCode);
        mesWorkOrderExt.setOrganizeCode(organizeCode);

        //获取seq逻辑
        Double maxSeq = 0D;

        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.DESC.getValue()}, new String[]{MesExtConstWords.SEQ}, packBean);
        MesWorkOrderExt workOrderSeq = workOrderExtRepository.getByProperty(packBean);
        if (null != workOrderSeq) {
            maxSeq = workOrderSeq.getSeq();
        }

        //mesWorkOrderExt.setSeq(MathOperation.add(getWorkOrderExtMaxSeq(organizeCode, 1), new Double(1)));
        mesWorkOrderExt.setSeq(maxSeq + 1);

        //获取计划日期年月的最大seq1

        DdlPackBean packBeanSeq1 = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringLikerPack(mesWorkOrderExt.getStartTime().substring(0,4)+mesWorkOrderExt.getStartTime().substring(5,7), "seq1", packBeanSeq1);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.DESC.getValue()}, new String[]{"seq1"}, packBeanSeq1);
        MesWorkOrderExt workOrderSeq1 = workOrderExtRepository.getByProperty(packBeanSeq1);

        //seq1加1
        if (null == workOrderSeq1){
            mesWorkOrderExt.setSeq1(mesWorkOrderExt.getStartTime().substring(0,4) + mesWorkOrderExt.getStartTime().substring(5,7) +"00001");
        }else {
            String maxSeq1Time = workOrderSeq1.getSeq1().substring(0,6);
            Integer maxSeq1Num = Integer.valueOf(workOrderSeq1.getSeq1().substring(6,11));
            Integer maxSeq1Num1 = maxSeq1Num + 1;
            String nowTime = TimeTool.getNowTime("yyyyMM");
            if (!maxSeq1Time.equals((mesWorkOrderExt.getStartTime().substring(0,4) + mesWorkOrderExt.getStartTime().substring(5,7)))){
                mesWorkOrderExt.setSeq1(mesWorkOrderExt.getStartTime().substring(0,4) + mesWorkOrderExt.getStartTime().substring(5,7)+"00001");
            }else {
                StringBuilder zero = new StringBuilder();
                if (maxSeq1Num1.toString().length() < 5){
                    for (int i = 0; i < 5 - maxSeq1Num1.toString().length(); i++) {
                        zero.append("0");
                    }
                }
                mesWorkOrderExt.setSeq1(maxSeq1Time +zero+ maxSeq1Num1);
            }
        }

        ConvertBean.modelInitialize(mesWorkOrderExt, AuthUtil.getSessionUser());
        mesWorkOrderExt.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
        new ConvertBeanExt(mesWorkOrderExt).convertBean(mesWorkOrderExt);
        MesWorkOrderExt workOrderExt = workOrderExtRepository.save(mesWorkOrderExt);
        insertMesWorkOrderLog(workOrderExt);
    }

    private MesPartExt getPart(MesWorkOrderExt mesWorkOrderExt, String organizeCode) {
        return partExtRepository.getByProperty(
                new String[]{MesExtConstWords.PART_NO, MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_VALID, MesExtConstWords.IS_DELETED},
                new Object[]{mesWorkOrderExt.getPartNo(), organizeCode,
                        CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                        CommonEnumUtil.IS_DEAL.NO.getValue()});
    }


    /**
     * 生产工单日志入库
     *
     * @param workOrderExt
     */
    public void insertMesWorkOrderLog(MesWorkOrderExt workOrderExt) {
        workOrderLogExtService.insertMesWorkOrderLogExt(workOrderExt);
    }



    private void updateWorkOrder(MesWorkOrderExt mesWorkOrderExt, boolean flag) {
        //在更新时导入的工单如果状态不是创建或暂停的工单，进行异常提醒。
        Integer workOrderStatus = mesWorkOrderExt.getWorkOrderStatus();
        boolean isCreate = MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue() == workOrderStatus;
        boolean isPause = MesExtEnumUtil.WORK_ORDER_STATUS.PAUSE.getValue() == workOrderStatus;
        //从SAP获取的订单如果状态不是创建或者暂停的工单，忽略更新。
        if (isCreate || isPause) {
            mesWorkOrderExt.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
            if(mesWorkOrderExt.getWorkOrderType() != MesExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue()){
                MesPartExt mesPart = partExtRepository.getByProperty(
                        new String[]{MesExtConstWords.PART_NO, MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_VALID, MesExtConstWords.IS_DELETED},
                        new Object[]{mesWorkOrderExt.getPartNo(), mesWorkOrderExt.getOrganizeCode(),
                                CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                                CommonEnumUtil.IS_DEAL.NO.getValue()});
                if(mesPart.getIsCreateSn() == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()){
                    mesWorkOrderExt.setSnCreateStatus(MesExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.UN_CREATE.getValue());
                }else{
                    mesWorkOrderExt.setSnCreateStatus(MesExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.NO_CREATE.getValue());
                }
            }
            new ConvertBeanExt(mesWorkOrderExt).convertBean(mesWorkOrderExt);
            MesWorkOrderExt workOrderExt = workOrderExtRepository.save(mesWorkOrderExt);
            insertMesWorkOrderLog(workOrderExt);
        } else {
            if (flag) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("工单【%s】不是创建或暂停的工单,不能被更新",
                                mesWorkOrderExt.getOrderNo())
                        .build();
            }

        }

    }

    private MesWorkOrderExt isHaveWorkOrder(String orderNo, String organizeCode) {
        MesWorkOrderExt mesWorkOrderExt = workOrderExtRepository.getByProperty(
                new String[]{MesConstWords.ORGANIZE_CODE, MesConstWords.IS_DELETED, MesConstWords.IS_VALID, "orderNo"},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), orderNo});
        if (null == mesWorkOrderExt) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单【%s】无效", orderNo)
                    .build();
        }
        return  mesWorkOrderExt;
    }

    /**
     * excel导入生成生产工单
     *
     * @param mesWorkOrderExtList mes工作单et列表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importGenerate(List<ExcelWorkOrderDto> mesWorkOrderExtList) {


        MesWorkCenter mesWorkCenter = null;

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sf = new SimpleDateFormat("yyyy/MM/dd");
        SimpleDateFormat sf1 = new SimpleDateFormat("yyyy-MM-dd");
        MesPart mesPart;

        Integer i = 2;

        String organizeCode = AuthUtil.getOrganizeCode();
        if (CollectionUtils.isEmpty(mesWorkOrderExtList)) {
            return;
        }
        for (ExcelWorkOrderDto excelWorkOrderDto : mesWorkOrderExtList) {

            //判断数量是否为0
            if (excelWorkOrderDto.getQty() == null || excelWorkOrderDto.getQty() <= 0) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("第【%s】行的数量【%s】必须大于0", i,
                                excelWorkOrderDto.getQty())
                        .build();
            }

            //判断日期格式是否正确,正确则转换格式
            try {
                String startTime = excelWorkOrderDto.getStartTime();
                String endTime = excelWorkOrderDto.getEndTime();
                if (startTime.contains("/")) {
                    excelWorkOrderDto.setStartTime(sdf.format(sf.parse(startTime)));
                } else {
                    if (startTime.contains(",")) {
                        startTime = startTime.replace(",", "");
                    }
                    excelWorkOrderDto.setStartTime(sdf.format(org.apache.poi.ss.usermodel.DateUtil.getJavaDate(Double.parseDouble(startTime))));
                }

                if (endTime.contains("/")) {
                    excelWorkOrderDto.setEndTime(sdf.format(sf.parse(endTime)));
                } else {
                    if (endTime.contains(",")) {
                        endTime = endTime.replace(",", "");
                    }
                    excelWorkOrderDto.setEndTime(sdf.format(org.apache.poi.ss.usermodel.DateUtil.getJavaDate(Double.parseDouble(endTime))));
                }


            } catch (ParseException e) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("第【%s】行的时间格式不正确，应该为yyyy/MM/dd格式", i)
                        .build();
            }

            //根据零件号查询零件信息
            mesPart = partExtRepository.getByProperty(
                    new String[]{"partNo", "organizeCode", "isValid", "isDeleted"},
                    new Object[]{excelWorkOrderDto.getPartNo(), organizeCode,
                            CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                            CommonEnumUtil.IS_DEAL.NO.getValue()});

            if (mesPart == null) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("第【%s】行的零件号【%s】在零件信息中不存在数据", i, excelWorkOrderDto.getPartNo())
                        .build();
            }

            //根据产线获取产线信息
            mesWorkCenter = workCenterRepository.getByProperty(
                    new String[]{"workVer", "organizeCode", "isValid", "isDeleted"},
                    new Object[]{excelWorkOrderDto.getWorkVer(), organizeCode,
                            CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                            CommonEnumUtil.IS_DEAL.NO.getValue()});

            if (mesWorkCenter == null) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("第【%s】行的产线代码【%s】在产线信息中不存在数据", i, excelWorkOrderDto.getWorkVer())
                        .build();
            }

            MesWorkOrderExt mesWorkOrderExt = new MesWorkOrderExt();

            String orderNo = excelWorkOrderDto.getOrderNo();
            MesWorkOrderExt haveWorkOrder = isHaveWorkOrder(orderNo, organizeCode);

            if(haveWorkOrder !=null){
                BeanUtils.copyProperties(excelWorkOrderDto, haveWorkOrder);
                ConvertBean.modelInitialize(haveWorkOrder, AuthUtil.getSessionUser());
                updateWorkOrder(haveWorkOrder, false);
            } else {
                BeanUtils.copyProperties(excelWorkOrderDto, mesWorkOrderExt);
                mesWorkOrderExt.setWorkCenterCode(mesWorkCenter.getWorkCenterCode());
                mesWorkOrderExt.setAreaCode(mesWorkCenter.getAreaCode());
                mesWorkOrderExt.setWorkOrderSource(MesExtEnumUtil.WORK_ORDER_SOURCE.IMPORT_GENERATE.getValue());
                mesWorkOrderExt.setWorkOrderType(MesExtEnumUtil.WORK_ORDER_TYPE.STANDARD_ORDER.getValue());
                addWorkOrder(mesWorkOrderExt);
            }

            i++;

        }
    }

    /**
     * sop同步接口生成生产工单 todo(同步接口还未开发)
     *
     * @param mesWorkOrderExtList mes工作单ext列表
     */
    @Override
    public void sopGenerate(List<MesWorkOrderExt> mesWorkOrderExtList) {

    }

    /**
     * 调整工作顺序
     *
     * @param generateWorkOrderDto 生成工作单dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void adjustWorkOrder(GenerateWorkOrderDto generateWorkOrderDto) {
        String orderNo = generateWorkOrderDto.getOrderNo();
        String organizeCode = AuthUtil.getOrganize().getOrganizeCode();
        MesWorkOrderExt mesWorkOrderExt = isHaveWorkOrder(orderNo, organizeCode);
        if(mesWorkOrderExt == null){
            throw new BaseImppException("工单不存在");
        }
        //计划返工数量不能大于计划生产数量
        Double qty = generateWorkOrderDto.getQty();
        Double planQty = generateWorkOrderDto.getPlanQty();
        if (planQty > qty) {
            throw new BaseImppException("计划返工数量不能大于计划生产数量");
        }


        //调整后的计划数量不能低于当前生产的数量
        Double completeQty = mesWorkOrderExt.getCompleteQty();
        if (qty < completeQty) {
            throw new BaseImppException("调整后的计划数量不能低于当前生产的数量");
        }
        mesWorkOrderExt.setAreaCode(generateWorkOrderDto.getAreaCode());
        mesWorkOrderExt.setWorkCenterCode(generateWorkOrderDto.getWorkCenterCode());
        mesWorkOrderExt.setWorkCenterName(generateWorkOrderDto.getWorkCenterName());
        mesWorkOrderExt.setQty(generateWorkOrderDto.getQty());
        mesWorkOrderExt.setPlanQty(generateWorkOrderDto.getPlanQty());
        mesWorkOrderExt.setWorkOrderType(generateWorkOrderDto.getWorkOrderType());
        mesWorkOrderExt.setMemo(generateWorkOrderDto.getMemo());
        mesWorkOrderExt.setStartTime(generateWorkOrderDto.getStartTime());
        mesWorkOrderExt.setEndTime(generateWorkOrderDto.getEndTime());
        mesWorkOrderExt.setErpWarehouse(generateWorkOrderDto.getErpWarehouse());

        ConvertBean.modelUpdate(mesWorkOrderExt, AuthUtil.getSessionUser());
        updateWorkOrder(mesWorkOrderExt, true);
    }

    /**
     * 工单新增/编辑-校验
     *
     * @param organizeCode 组织代码
     */
    private boolean isHavePart(String partNo, String organizeCode) {
        MesPart mesPart = partExtRepository.getByProperty(
                new String[]{MesConstWords.ORGANIZE_CODE, MesConstWords.IS_DELETED, MesConstWords.IS_VALID, "partNo"},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(),CommonEnumUtil.IS_VAILD.VAILD.getValue(), partNo});
        return null != mesPart;
    }


    private String getOrderNo(String userName, String organizeCode) {
        String orderNo = "";
        BaseResultBean oneCodeResult = syncFuncService.syncSerialNo(new GenSerialNoModel(MesExtEnumUtil.COMMON_SN.WC_NO.getCode()), userName, organizeCode, 1);
        if (oneCodeResult != null && oneCodeResult.isSuccess()) {
            orderNo = oneCodeResult.getResultList().get(0).toString();
        } else {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.CLOUD_CALL_EXCEPTION.getCode())
                    .setErrorDetail("生成唯一工单号失败")
                    .build();
        }
        return orderNo;
    }


    /**
     * 生产工单分页查询
     *
     * @param workOrderQueryDto 查询参数
     * @param pager             分页参数
     * @return {@link ListPager<MesWorkOrderExt>}
     */
    @Override
    public ListPager<WorkOrderPageVo> getListPageByCondition(WorkOrderQueryDto workOrderQueryDto, Pager pager) {
        String organizeCode = AuthUtil.getOrganize().getOrganizeCode();
        DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
        if (!ObjectUtils.isEmpty(workOrderQueryDto)) {
            DdlPreparedPack.getStringEqualPack(workOrderQueryDto.getWorkCenterCode(), MesExtConstWords.WORK_CENTER_CODE, ddlPackBean);
            DdlPreparedPack.getStringLikerPack(workOrderQueryDto.getOrderNo(), MesExtConstWords.ORDER_NO, ddlPackBean);
            DdlPreparedPack.getStringLikerPack(workOrderQueryDto.getPartNo(), MesExtConstWords.PART_NO, ddlPackBean);
            DdlPreparedPack.getStringLikerPack(workOrderQueryDto.getCreateUser(), MesExtConstWords.CREATE_USER, ddlPackBean);
            DdlPreparedPack.getStringLikerPack(workOrderQueryDto.getErpWarehouse(), MesExtConstWords.ERP_WARE_HOUSE, ddlPackBean);
            DdlPreparedPack.getNumEqualPack(workOrderQueryDto.getWorkOrderStatus(), MesExtConstWords.WORK_ORDER_STATUS, ddlPackBean);
            DdlPreparedPack.getNumEqualPack(workOrderQueryDto.getWorkOrderType(), MesExtConstWords.WORK_ORDER_TYPE, ddlPackBean);
            DdlPreparedPack.getIsNotNull(MesExtConstWords.WORK_CENTER_CODE, ddlPackBean);
            if (!StringUtils.isEmpty(workOrderQueryDto.getStartTimeStart()) || !StringUtils.isEmpty(workOrderQueryDto.getStartTimeEnd())) {
                DdlPreparedPack.timeBuilder(workOrderQueryDto.getStartTimeStart(), workOrderQueryDto.getStartTimeEnd(), MesExtConstWords.START_TIME, ddlPackBean, true);
            }
            if (!StringUtils.isEmpty(workOrderQueryDto.getEndTimeStart()) || !StringUtils.isEmpty(workOrderQueryDto.getEndTimeEnd())) {
                DdlPreparedPack.timeBuilder(workOrderQueryDto.getEndTimeStart(), workOrderQueryDto.getEndTimeEnd(), MesExtConstWords.END_TIME, ddlPackBean, true);
            }
            if (StringUtils.isEmpty(workOrderQueryDto.getOrderByParam())) {
                DdlPreparedPack.getOrderByPack(new Object[]{MesEnumUtil.ASC_OR_DESC.DESC.getValue()}, new String[]{MesExtConstWords.MODIFY_DATE_TIME}, ddlPackBean);
            } else {
                if (workOrderQueryDto.getOrderByParam().equals(MesExtConstWords.SEQ) ||
                        workOrderQueryDto.getOrderByParam().equals(MesExtConstWords.ORDER_NO) ) {
                    DdlPreparedPack.getOrderByPack(new Object[]{workOrderQueryDto.getAscOrDesc()}, new String[]{workOrderQueryDto.getOrderByParam()}, ddlPackBean);
                } else {
                    DdlPreparedPack.getOrderByPack(
                            new Object[]{workOrderQueryDto.getAscOrDesc(), MesEnumUtil.ASC_OR_DESC.ASC.getValue()},
                            new String[]{workOrderQueryDto.getOrderByParam(), MesExtConstWords.SEQ}, ddlPackBean);
                }
            }
        }

        pager = PagerHelper.getPager(pager, workOrderExtRepository.findByHqlWhereCount(ddlPackBean));

        List<MesWorkOrderExt> mesWorkOrderExtList = workOrderExtRepository.findByHqlWherePage(ddlPackBean, pager);
        List<WorkOrderPageVo> workOrderPageVos = JSON.parseObject(JSON.toJSONString(mesWorkOrderExtList), new TypeReference<List<WorkOrderPageVo>>() {
        });

        if (!CollectionUtils.isEmpty(workOrderPageVos)) {
            List<String> workCenterCodeList = workOrderPageVos.stream()
                    .filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkCenterCode()))).map(WorkOrderPageVo::getWorkCenterCode).collect(Collectors.toList());
            Map<String, String> workCenterCodeMap = null;
            if (!CollectionUtils.isEmpty(workCenterCodeList)) {
                DdlPackBean ddl = DdlPackBean.getDdlPackBean(organizeCode);
                DdlPreparedPack.getInPackList(workCenterCodeList, MesExtConstWords.WORK_CENTER_CODE, ddl);
                List<MesWorkCenter> workCenterList = workCenterRepository.findByHqlWhere(ddl);
                workCenterCodeMap = workCenterList.stream().filter(o -> null != o).collect(Collectors.toMap(MesWorkCenter::getWorkCenterCode, MesWorkCenter::getWorkCenterName));
            }

            for (WorkOrderPageVo workOrderPageVo : workOrderPageVos) {
                Integer workOrderStatus = workOrderPageVo.getWorkOrderStatus();
                String workOrderStatusName = MesExtEnumUtil.WORK_ORDER_STATUS.valueOfDescription(workOrderStatus);
                workOrderPageVo.setWorkOrderStatusName(workOrderStatusName);

                Integer workOrderType = workOrderPageVo.getWorkOrderType();
                String workOrderTypeName = MesExtEnumUtil.WORK_ORDER_TYPE.valueOfDescription(workOrderType);
                workOrderPageVo.setWorkOrderTypeName(workOrderTypeName);

                workOrderPageVo.setWorkOrderSourceName(MesExtEnumUtil.WORK_ORDER_SOURCE.valueOfDescription(workOrderPageVo.getWorkOrderSource()));

                if (CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr().equals(workOrderPageVo.getOutPutFlag())) {
                    workOrderPageVo.setOutPutFlagName(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getDescription());
                } else {
                    workOrderPageVo.setOutPutFlagName(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getDescription());
                }

                if(!StringUtils.isEmpty(workOrderPageVo.getWorkCenterCode()) && !CollectionUtils.isEmpty(workCenterCodeMap)){
                    workOrderPageVo.setWorkCenterName(workCenterCodeMap.get(workOrderPageVo.getWorkCenterCode()));
                }
                //mes生产工单页面按钮控制
                workOrderPageVo.setMesButtonFlagModel(this.getMesButtonFlagModel(workOrderPageVo));
            }

        }
        return  new ListPager(workOrderPageVos, pager);
    }

    @Override
    public ListPager<WorkOrderPageVo> getWorkOrderListByPager(WorkOrderQueryDto workOrderQueryDto, Pager pager) {
        String organizeCode = AuthUtil.getOrganize().getOrganizeCode();
        workOrderQueryDto.setOrganizeCode(organizeCode);
        pager = PagerHelper.getPager(pager, buWorkOrderDao.queryWorkOrderPagerCount(workOrderQueryDto).intValue());

        List<WorkOrderPageVo> workOrderPageVos = buWorkOrderDao.queryWorkOrderPager(workOrderQueryDto, pager);
        //List<WorkOrderPageVo> workOrderPageVos = JSON.parseObject(JSON.toJSONString(mesWorkOrderExtList), new TypeReference<List<WorkOrderPageVo>>() {
        //});

        if (!CollectionUtils.isEmpty(workOrderPageVos)) {
            List<String> workCenterCodeList = workOrderPageVos.stream()
                    .filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkCenterCode()))).map(WorkOrderPageVo::getWorkCenterCode).collect(Collectors.toList());
            Map<String, String> workCenterCodeMap = null;
            if (!CollectionUtils.isEmpty(workCenterCodeList)) {
                DdlPackBean ddl = DdlPackBean.getDdlPackBean(organizeCode);
                DdlPreparedPack.getInPackList(workCenterCodeList, MesExtConstWords.WORK_CENTER_CODE, ddl);
                List<MesWorkCenter> workCenterList = workCenterRepository.findByHqlWhere(ddl);
                workCenterCodeMap = workCenterList.stream().filter(o -> null != o).collect(Collectors.toMap(MesWorkCenter::getWorkCenterCode, MesWorkCenter::getWorkCenterName));
            }

            for (WorkOrderPageVo workOrderPageVo : workOrderPageVos) {
                Integer workOrderStatus = workOrderPageVo.getWorkOrderStatus();
                String workOrderStatusName = MesExtEnumUtil.WORK_ORDER_STATUS.valueOfDescription(workOrderStatus);
                workOrderPageVo.setWorkOrderStatusName(workOrderStatusName);

                Integer workOrderType = workOrderPageVo.getWorkOrderType();
                String workOrderTypeName = MesExtEnumUtil.WORK_ORDER_TYPE.valueOfDescription(workOrderType);
                workOrderPageVo.setWorkOrderTypeName(workOrderTypeName);

                workOrderPageVo.setWorkOrderSourceName(MesExtEnumUtil.WORK_ORDER_SOURCE.valueOfDescription(workOrderPageVo.getWorkOrderSource()));

                if (CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr().equals(workOrderPageVo.getOutPutFlag())) {
                    workOrderPageVo.setOutPutFlagName(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getDescription());
                } else {
                    workOrderPageVo.setOutPutFlagName(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getDescription());
                }

                if(!StringUtils.isEmpty(workOrderPageVo.getWorkCenterCode()) && !CollectionUtils.isEmpty(workCenterCodeMap)){
                    workOrderPageVo.setWorkCenterName(workCenterCodeMap.get(workOrderPageVo.getWorkCenterCode()));
                }
                //mes生产工单页面按钮控制
                workOrderPageVo.setMesButtonFlagModel(this.getMesButtonFlagModel(workOrderPageVo));
            }

        }
        return  new ListPager(workOrderPageVos, pager);
    }


    /**
     * mes生产工单页面按钮控制
     *
     * @param workOrderPageVo
     * @return
     */
    private MesButtonFlagModel getMesButtonFlagModel(WorkOrderPageVo workOrderPageVo) {
        if (workOrderPageVo == null) {
            return null;
        }
        Double completeQty = StringUtils.isEmpty(workOrderPageVo.getCompleteQty()) ? 0 : workOrderPageVo.getCompleteQty();

        MesButtonFlagModel mesButtonFlagModel = new MesButtonFlagModel();
        Integer workOrderStatus = workOrderPageVo.getWorkOrderStatus();

        //编辑：创建状态
        if (MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue() == workOrderStatus) {
            mesButtonFlagModel.setUpdateButton(true);
            mesButtonFlagModel.setTransmitButton(true);
        }

        if (MesExtEnumUtil.WORK_ORDER_STATUS.LANDED.getValue() == workOrderStatus) {
            mesButtonFlagModel.setStartUpButton(true);
            mesButtonFlagModel.setSuspendButton(true);
        }
        if (MesExtEnumUtil.WORK_ORDER_STATUS.PAUSE.getValue() == workOrderStatus) {
            mesButtonFlagModel.setStartUpButton(true);
            mesButtonFlagModel.setCloseButton(true);
        }
        if (MesExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue() == workOrderStatus) {
            mesButtonFlagModel.setSuspendButton(true);
        }
        return mesButtonFlagModel;
    }

    /**
     * 停止工作订单
     *
     * @param orderNo 订单编号
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void stopWorkOrder(String orderNo) {
        String organizeCode = AuthUtil.getOrganize().getOrganizeCode();
        MesWorkOrderExt haveWorkOrder = isHaveWorkOrder(orderNo, organizeCode);
        if (ObjectUtils.isEmpty(haveWorkOrder)) {
            throw new BaseImppException("工单不存在");
        }
        Integer workOrderStatus = haveWorkOrder.getWorkOrderStatus();
        boolean isCreate = MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue() == workOrderStatus;
        boolean isLanded = MesExtEnumUtil.WORK_ORDER_STATUS.LANDED.getValue() == workOrderStatus;
        boolean isOpen = MesExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue() == workOrderStatus;
        if (isCreate || isLanded || isOpen) {
            ConvertBean.serviceModelUpdate(haveWorkOrder, AuthUtil.getSessionUser().getUserName());
            haveWorkOrder.setWorkOrderStatus(MesExtEnumUtil.WORK_ORDER_STATUS.PAUSE.getValue());
            haveWorkOrder.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
            new ConvertBeanExt(haveWorkOrder).convertBean(haveWorkOrder);
            MesWorkOrderExt mesWorkOrderExt = workOrderExtRepository.save(haveWorkOrder);
            insertMesWorkOrderLog(mesWorkOrderExt);
        } else {
            throw new BaseImppException("只有创建,下达,启动才可以暂停");
        }
    }

    /**
     * 启动工单
     *
     * @param orderNo 订单编号
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void startWorkOrder(String orderNo) {
        String organizeCode = AuthUtil.getOrganize().getOrganizeCode();
        MesWorkOrderExt haveWorkOrder = isHaveWorkOrder(orderNo, organizeCode);
        if (ObjectUtils.isEmpty(haveWorkOrder)) {
            throw new BaseImppException("工单不存在");
        }
        Integer workOrderStatus = haveWorkOrder.getWorkOrderStatus();
        boolean isLanded = MesExtEnumUtil.WORK_ORDER_STATUS.LANDED.getValue() == workOrderStatus;
        boolean isPause = MesExtEnumUtil.WORK_ORDER_STATUS.PAUSE.getValue() == workOrderStatus;

        if (isLanded) {
            MesWorkOrderExt mesWorkOrderExt = saveWorkOrder(MesExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue(), haveWorkOrder);
            //生成点检单
            insertMesWorkOrderLog(mesWorkOrderExt);
        } else {
            if (isPause) {
                //更改未暂停前状态
                //获取暂停前的状态
                DdlPackBean ddlPackBean = new DdlPackBean();
                DdlPreparedPack.getStringEqualPack(orderNo,"orderNo",ddlPackBean);
                List<MesWorkOrderLogExt> mesWorkOrderLogs = workOrderLogRepository.findByHqlWhere(ddlPackBean);
                if (!CollectionUtils.isEmpty(mesWorkOrderLogs)) {
                    int size = mesWorkOrderLogs.size();
                    if(size>1){
                        MesWorkOrderLog mesWorkOrderLog = mesWorkOrderLogs.get(size - 1);
                        Integer workOrderStatus1 = mesWorkOrderLog.getWorkOrderStatus();
                        boolean isPause1 = MesExtEnumUtil.WORK_ORDER_STATUS.PAUSE.getValue() == workOrderStatus1;
                        if(isPause1){
                            MesWorkOrderLog mesWorkOrderLog2 = mesWorkOrderLogs.get(size - 2);
                            Integer workOrderStatus2 = mesWorkOrderLog2.getWorkOrderStatus();
                            haveWorkOrder.setWorkOrderStatus(workOrderStatus2);
                            ConvertBean.serviceModelUpdate(haveWorkOrder, AuthUtil.getSessionUser().getUserName());
                            haveWorkOrder.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
                            new ConvertBeanExt(haveWorkOrder).convertBean(haveWorkOrder);
                            workOrderExtRepository.save(haveWorkOrder);
                        }
                    }
                }

            }else{
                throw new BaseImppException("工单不满足启动条件,不能被启动");
            }
        }
    }

    /**
     * 生产工单状态批量调整
     *
     * @param workOrderStatus 状态
     * @param orderNoList     工单号
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void updateWorkOrderStatus(Integer workOrderStatus, List<String> orderNoList) {
        String organizeCode = AuthUtil.getOrganize().getOrganizeCode();

        //获取所有数据
        List<MesWorkOrderExt> mesWorkOrderList = queryWorkOrderByOrderNoList(orderNoList, organizeCode);

        workOrderValidVerify(workOrderStatus, mesWorkOrderList);

        List<MesAffiliatedStartConfig> mesAffiliatedStartConfigs = queryMesAffiliatedStartConfigs(organizeCode);

        //MesBusiConfig waterPurifierCode = busiConfigService.getBusiConfigByCfgCode(organizeCode, MesExtConstWords.WATER_PURIFIER_CODE);
        Map<String, MesWorkCenterExt> workCenterExtMap = null;
        // 一个工单号下的多个工单
        for (MesWorkOrderExt mesWorkOrder : mesWorkOrderList) {
            //启动
            if (MesExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue() == workOrderStatus) {

                boolean isLanded = MesExtEnumUtil.WORK_ORDER_STATUS.LANDED.getValue() == mesWorkOrder.getWorkOrderStatus();
                boolean isPause = MesExtEnumUtil.WORK_ORDER_STATUS.PAUSE.getValue() == mesWorkOrder.getWorkOrderStatus();

                if (isLanded) {
                    //调用启动工单附属启动的方法
                    //校验是否存在已经启动的工单
                    List<MesWorkOrderExt> mesWorkOrderListByWorkCenterCode = queryLandedWorkOrderList(organizeCode, mesWorkOrder.getWorkCenterCode());
                    if (!CollectionUtils.isEmpty(mesWorkOrderListByWorkCenterCode)) {
                        mesWorkOrderListByWorkCenterCode.sort(Comparator.comparing(MesWorkOrderExt::getSeq));
                        MesWorkOrderExt mesWorkOrderExt = mesWorkOrderListByWorkCenterCode.get(0);
                        if (!mesWorkOrder.getOrderNo().equals(mesWorkOrderExt.getOrderNo())) {
                            throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                                    .setErrorDetail("工单号【%s】的工单不是产线下当前排序最前的，不能启动", mesWorkOrder.getOrderNo())
                                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                                    .setErrorSolution("校验生产工单表数据")
                                    .build();
                        }
                    }

                    for (MesAffiliatedStartConfig mesAffiliatedStartConfig : mesAffiliatedStartConfigs) {
                        try {
                            IWorkOrderStartService workOrderStartService = (IWorkOrderStartService) SpringContextsUtil.getBean(mesAffiliatedStartConfig.getAffiliatedStartClass());
                            workOrderStartService.execute(mesWorkOrder);
                        } catch (Exception e) {
                            log.error(e.getMessage());
                            StackTraceElement[] stackTrace = e.getStackTrace();
                            log.error(Arrays.toString(stackTrace));
                        }
                    }
                } else {
                    if (isPause) {
                        //更改未暂停前状态
                        //获取暂停前的状态
                        List<MesWorkOrderLogExt> mesWorkOrderLogs = getMesWorkOrderLogExts(mesWorkOrder);
                        if (!CollectionUtils.isEmpty(mesWorkOrderLogs)) {
                            mesWorkOrderLogs.sort(Comparator.comparing(MesWorkOrderLog::getModifyDatetime).reversed());
                            MesWorkOrderLog mesWorkOrderLogTemp = mesWorkOrderLogs.get(0);
                            Integer workOrderStatusTemp = mesWorkOrderLogTemp.getWorkOrderStatus();
                            saveWorkOrder(workOrderStatusTemp, mesWorkOrder);
                            if (workOrderStatusTemp == MesExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue()) {
                                for (MesAffiliatedStartConfig mesAffiliatedStartConfig : mesAffiliatedStartConfigs) {
                                    try {
                                        IWorkOrderStartService workOrderStartService = (IWorkOrderStartService) SpringContextsUtil.getBean(mesAffiliatedStartConfig.getAffiliatedStartClass());
                                        workOrderStartService.execute(mesWorkOrder);
                                    } catch (Exception e) {
                                        log.error(e.getMessage());
                                    }
                                }
                            }
                            insertMesWorkOrderLog(mesWorkOrder);
                            continue;
                        }

                    } else {
                        throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                                .setErrorDetail("工单号【%s】的工单状态不是下达或暂停状态，不能启动", mesWorkOrder.getOrderNo())
                                .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                                .setErrorSolution("校验生产工单表数据")
                                .build();
                    }
                }

//            } else if (MesExtEnumUtil.WORK_ORDER_STATUS.CANCEL.getValue() == workOrderStatus) {
//                //取消
//                //校验工单是否是创建/下达/启动（还未开始生产，即完成数=0的）状态
//                if (MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue() != mesWorkOrder.getWorkOrderStatus() &&
//                        MesExtEnumUtil.WORK_ORDER_STATUS.LANDED.getValue() != mesWorkOrder.getWorkOrderStatus() &&
//                        (MesExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue() != mesWorkOrder.getWorkOrderStatus() ||
//                                completeQty.compareTo((double) 0) > 0)) {
//                    throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
//                            .setErrorDetail("工单号【%s】的工单状态不是创建或下达或启动且完成数为0的状态，不能取消", mesWorkOrder.getOrderNo())
//                            .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
//                            .setErrorSolution("校验生产工单表数据")
//                            .build();
//                }

                try {
                    if( TimeTool.getSecoundsBetweenTime(4, mesWorkOrder.getStartTime(), TimeTool.getNowTime(true)) == 1 &&
                            StringUtils.isEmpty(mesWorkOrder.getReusePlanDatetime())){
                        mesWorkOrder.setReusePlanDatetime(TimeTool.getNowTime(true));
                        mesWorkOrder.setReusePlanCompleteQty(BigDecimal.valueOf(mesWorkOrder.getQty()).subtract(BigDecimal.valueOf(mesWorkOrder.getCompleteQty())).doubleValue());
                    }
                } catch (ParseException e) {
                    log.info("启动工单时计算计划时间与工单启动时间失败");
                }

            } else if (MesExtEnumUtil.WORK_ORDER_STATUS.PAUSE.getValue() == workOrderStatus) {
                //暂停
                //校验工单是否是启动状态
                boolean isCreate = MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue() == mesWorkOrder.getWorkOrderStatus();
                boolean isLanded = MesExtEnumUtil.WORK_ORDER_STATUS.LANDED.getValue() == mesWorkOrder.getWorkOrderStatus();
                boolean isOpen = MesExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue() == mesWorkOrder.getWorkOrderStatus();
                if (!isCreate && !isLanded && !isOpen) {
                    throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                            .setErrorDetail("工单号【%s】的工单状态不是启动,下达,创建状态，不能暂停", mesWorkOrder.getOrderNo())
                            .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                            .setErrorSolution("校验生产工单表数据")
                            .build();
                }
            } else if (MesExtEnumUtil.WORK_ORDER_STATUS.CLOSE.getValue() == workOrderStatus) {
                //String nowTime = TimeTool.getNowTime(true);
                //关闭
                //修改返工工单状态
                if(mesWorkOrder.getWorkOrderType() == MesExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue()) {
                    //List<String> waterPurifierCodeList = !Optional.ofNullable(waterPurifierCode).isPresent() || StringUtils.isEmpty(waterPurifierCode.getCfgValue()) ? new ArrayList<>() : Arrays.asList(waterPurifierCode.getCfgValue().split(MesExtConstWords.COMMA));
                    //if(CollectionUtils.isEmpty(waterPurifierCodeList) || !waterPurifierCodeList.contains(mesWorkOrder.getWorkCenterCode())) {
                    //    // 手动点击完成工单,存在未下线条码
                    //    if(!mesWorkOrder.getQty().equals(mesWorkOrder.getCompleteQty())) {
                    //        List<MesProduceSnRepair> produceSnRepairList = queryProduceSnRepairList(organizeCode, mesWorkOrder.getOrderNo());
                    //        if(!CollectionUtils.isEmpty(produceSnRepairList)) {
                    //            // 未下线条码
                    //            produceSnRepairList = produceSnRepairList.stream().filter(o -> StringUtils.isEmpty(o.getOutWorkCenterTime())).collect(Collectors.toList());
                    //
                    //            if(!CollectionUtils.isEmpty(produceSnRepairList)){
                    //                List<String> serialNumberList = produceSnRepairList.stream().map(MesProduceSnRepair::getSerialNumber).collect(Collectors.toList());
                    //
                    //                //updateProduceSnRepairAndPackageAndReworkRangeAndProdBindRecord(organizeCode, serialNumberList, nowTime);
                    //
                    //                updatePackage(organizeCode, serialNumberList);
                    //
                    //                unbindReworkRangeList(organizeCode, mesWorkOrder, serialNumberList);
                    //
                    //                clearProdBindRecord(organizeCode, mesWorkOrder, nowTime, serialNumberList);
                    //
                    //                produceSnRepairList.forEach(o -> {
                    //                    o.setIsDeleted(CommonEnumUtil.IS_DEAL.YES.getValue());
                    //                    o.setModifyUser(AuthUtil.getSessionUser().getUserName());
                    //                    o.setModifyDatetime(nowTime);
                    //                    o.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
                    //                });
                    //                produceSnRepairRepository.saveAll(produceSnRepairList);
                    //            }
                    //        }
                    //    }
                    //}

                    //reworkOrderRepository.updateByProperties(new String[]{MesExtConstWords.REWORK_ORDER_NO}, new Object[]{mesWorkOrder.getOrderNo()},
                    //        new String[]{ MesExtConstWords.WORK_ORDER_STATUS, MesExtConstWords.SYSTEM_SYNC_STATUS, MesExtConstWords.MODIFY_USER, MesExtConstWords.MODIFY_DATE_TIME},
                    //        new Object[]{MesExtEnumUtil.WORK_ORDER_STATUS.CLOSE.getValue(), MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue(), AuthUtil.getSessionUser().getUserName(), TimeTool.getNowTime(true)});
                }

            } else if (MesExtEnumUtil.WORK_ORDER_STATUS.REMOVE.getValue() == workOrderStatus) {
                //删除
                if (mesWorkOrder.getCompleteQty() > 0){
                    throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                            .setErrorDetail("工单号【%s】的完成数量大于0，不能删除", mesWorkOrder.getOrderNo())
                            .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                            .setErrorSolution("校验生产工单表数据")
                            .build();
                }else if(mesWorkOrder.getCompleteQty() == 0){
                    // 要自动解绑已绑定的关键件 看一下是什么
                    unbindProdBind(organizeCode, mesWorkOrder);
                }
            } else if (MesExtEnumUtil.WORK_ORDER_STATUS.LANDED.getValue() == workOrderStatus) {
                //下达 ： 校验WMS的存储区是否存在
                checkWmsErpHouseIsExist(organizeCode, mesWorkOrder);

                if (StringUtils.isEmpty(mesWorkOrder.getReserved1()) || StringUtils.isEmpty(mesWorkOrder.getReserved2())) {
                    if (CollectionUtils.isEmpty(workCenterExtMap)) workCenterExtMap = new HashMap<>();
                    MesWorkCenterExt workCenterExt;
                    if (workCenterExtMap.containsKey(mesWorkOrder.getWorkCenterCode())) workCenterExt = workCenterExtMap.get(mesWorkOrder.getWorkCenterCode());
                    else {
                        workCenterExt = prodOrgExtService.getWorkCenterExt(organizeCode, mesWorkOrder.getWorkCenterCode());
                        workCenterExtMap.put(mesWorkOrder.getWorkCenterCode(), workCenterExt);
                    }
                    if (null != workCenterExt) {
                        mesWorkOrder.setReserved1(workCenterExt.getCategoryCode());
                        mesWorkOrder.setReserved2(workCenterExt.getCareerCode());
                    }
                }
            }

            MesWorkOrderExt mesWorkOrderDb = saveWorkOrder(workOrderStatus, mesWorkOrder);

            //生产工单日志
            this.insertMesWorkOrderLog(mesWorkOrderDb);
        }

        //if (workOrderStatus == MesExtEnumUtil.WORK_ORDER_STATUS.CLOSE.getValue() || workOrderStatus == MesExtEnumUtil.WORK_ORDER_STATUS.REMOVE.getValue()) {
        //    List<String> workOrderNoList = mesWorkOrderList.stream().filter(o -> o.getWorkOrderType() != MesExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue()).map(MesWorkOrderExt::getOrderNo).collect(Collectors.toList());
        //    if (!CollectionUtils.isEmpty(workOrderNoList)) {
        //        String requestUrl = httpService.getRequestUrl(organizeCode, MesExtConstWords.BU_GATEWAY_HOST_PCN, MesExtConstWords.PCN_UNBIND_SN_BY_WORK_ORDER_WITH_DATA_URL);
        //        Map<String, String> params = new HashMap<>();
        //        params.put(MesExtConstWords.WORK_ORDER_NO, JSONObject.toJSONString(workOrderNoList));
        //        params.put(MesExtConstWords.ORGANIZE_CODE, organizeCode);
        //        params.put("nowTime", TimeTool.getNowTime(true));
        //        params.put(MesExtConstWords.USER_NAME, AuthUtil.getSessionUser().getUserName());
        //        params.put(MesExtConstWords.STATUS, MesExtEnumUtil.WORK_ORDER_STATUS.CLOSE.getValue() + "");
        //        String data = SxMesHttpUtil.doPost(requestUrl, params);
        //
        //        BaseResultBean baseResultBean = null;
        //        if (!StringUtils.isEmpty(data)) {
        //            baseResultBean = JsonUtilTool.decode(data, BaseResultBean.class);
        //        } else {
        //            log.error("工单完成或删除解绑未下线条码 HTTP[{}]调用PCN接口失败", requestUrl);
        //            throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
        //                    .setErrorDetail("工单完成或删除解绑未下线条码 HTTP调用PCN接口失败")
        //                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
        //                    .build();
        //        }
        //        if (!baseResultBean.success) {
        //            throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
        //                    .setErrorDetail(baseResultBean.getErrorMsg())
        //                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
        //                    .build();
        //        }
        //    }
        //}
        //
        //if (workOrderStatus == MesExtEnumUtil.WORK_ORDER_STATUS.CLOSE.getValue()) {
        //    List<String> reworkOrderNoList = mesWorkOrderList.stream().filter(o -> o.getWorkOrderType() == MesExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue()).map(MesWorkOrderExt::getOrderNo).collect(Collectors.toList());
        //    if (!CollectionUtils.isEmpty(reworkOrderNoList)) {
        //        String requestUrl = httpService.getRequestUrl(organizeCode, MesExtConstWords.BU_GATEWAY_HOST_PCN, MesExtConstWords.PCN_UPDATE_REWORK_ORDER_WITH_DATA_URL);
        //        Map<String, String> params = new HashMap<>();
        //        params.put(MesExtConstWords.REWORK_ORDER_NO, JSONObject.toJSONString(reworkOrderNoList));
        //        params.put(MesExtConstWords.ORGANIZE_CODE, organizeCode);
        //        params.put("nowTime", TimeTool.getNowTime(true));
        //        params.put(MesExtConstWords.USER_NAME, AuthUtil.getSessionUser().getUserName());
        //        params.put(MesExtConstWords.STATUS, MesExtEnumUtil.WORK_ORDER_STATUS.CLOSE.getValue() + "");
        //        String data = SxMesHttpUtil.doPost(requestUrl, params);
        //        log.info("修改返工工单状态 参数{} --- 结果:{}", params, data);
        //        BaseResultBean baseResultBean = null;
        //        if (!StringUtils.isEmpty(data)) {
        //            baseResultBean = JsonUtilTool.decode(data, BaseResultBean.class);
        //        } else {
        //            log.error("修改返工工单状态 HTTP[{}]调用PCN接口失败", requestUrl);
        //            throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
        //                    .setErrorDetail("修改返工工单状态 HTTP调用PCN接口失败")
        //                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
        //                    .build();
        //        }
        //        if (!baseResultBean.success) {
        //            throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
        //                    .setErrorDetail(baseResultBean.getErrorMsg())
        //                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
        //                    .build();
        //        }
        //    }
        //}
        ////返工工单下达进行邮件推送
        //reworkOrderEmailPush(workOrderStatus, organizeCode, mesWorkOrderList);

    }

    private void clearProdBindRecord(String organizeCode, MesWorkOrderExt mesWorkOrder, String nowTime, List<String> serialNumberList) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(mesWorkOrder.getOrderNo(), MesExtConstWords.WORK_ORDER_NO, packBean);
        DdlPreparedPack.getInPackList(serialNumberList, MesExtConstWords.SERIAL_NUMBER, packBean);
        List<MesProdBindRecordExt> prodBindRecordExtList = prodBindRecordExtRepository.findByHqlWhere(packBean);
        prodBindRecordExtList.forEach(o -> {
            o.setIsDeletedExt(MesExtEnumUtil.IS_VAILD.VAILD.getValue());
            o.setIsValidExt(MesExtEnumUtil.IS_VAILD.INVAILD.getValue());
            o.setModifyDatetimeExt(nowTime);
            o.setModifyDatetime(nowTime);
            o.setModifyUser(AuthUtil.getSessionUser().getUserName());
            o.setModifyUserExt(AuthUtil.getSessionUser().getUserName());
        });

        prodBindRecordExtRepository.saveAll(prodBindRecordExtList);
    }

    private void unbindReworkRangeList(String organizeCode, MesWorkOrderExt mesWorkOrder, List<String> serialNumberList) {

        BaseResultBean baseResultBean = reworkRangeCloud.unbindReworkRangeList(mesWorkOrder.getOrderNo(), serialNumberList, organizeCode, AuthUtil.getSessionUser().getUserName());
        if (!baseResultBean.success) {
            throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail(baseResultBean.getErrorMsg())
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .build();
        }
        //DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        //DdlPreparedPack.getStringEqualPack(mesWorkOrder.getOrderNo(), MesExtConstWords.REWORK_ORDER_NO, packBean);
        //List<MesReworkRange> reworkRangeList = reworkRangeRepository.findByHqlWhere(packBean);
        //
        //reworkRangeList = reworkRangeList.stream().filter(o -> serialNumberList.contains(o.getSerialNumber())).collect(Collectors.toList());
        //
        //reworkRangeList.forEach(o-> {
        //    o.setModifyUser(AuthUtil.getSessionUser().getUserName());
        //    o.setModifyDatetime(nowTime);
        //    o.setBindStatus(MesExtEnumUtil.PACKAGE_BIND_STATUS.BINGDING.getValue());
        //    o.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
        //    o.setReworkOrderNo("");
        //});
        //
        //reworkRangeRepository.saveAll(reworkRangeList);
    }

    private void updatePackage(String organizeCode, List<String> serialNumberList) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackList(serialNumberList, MesExtConstWords.SERIAL_NUMBER, packBean);
        List<MesPackageDetail> packageDetailList = packageDetailRepository.findByHqlWhere(packBean);
        List<String> packageNoList = packageDetailList.stream().map(MesPackageDetail::getPackageNo).distinct().collect(Collectors.toList());

        packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackList(packageNoList, MesExtConstWords.PACKAGENO, packBean);
        List<MesPackageExt> packageExtList = packageExtRepository.findByHqlWhere(packBean);
        packageExtList.forEach(o -> {
            o.setLastWorkOrderNo(o.getWorkOrderNo());
        });
        packageExtRepository.saveAll(packageExtList);
    }

    private void updateProduceSnRepairAndPackageAndReworkRangeAndProdBindRecord(String organizeCode, List<String> serialNumberList, String nowTime) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackList(serialNumberList, MesExtConstWords.SERIAL_NUMBER, packBean);
        List<MesProduceSnExt> produceSnExtList = produceSnExtRepository.findByHqlWhere(packBean);
        //String nowTime = TimeTool.getNowTime(true);
        produceSnExtList.forEach(o -> {
            o.setSnStatus(MesExtEnumUtil.PRODUCE_SN_STATUS.OFFLINE.getValue());
            //o.setModifyUserExt(AuthUtil.getSessionUser().getUserName());
            //o.setModifyDatetimeExt(nowTime);
            //o.setModifyUser(AuthUtil.getSessionUser().getUserName());
            //o.setModifyDatetime(nowTime);
            o.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
            o.setSystemSyncStatusExt(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
        });
        produceSnExtRepository.saveAll(produceSnExtList);

        String requestUrl = httpService.getRequestUrl(organizeCode, MesExtConstWords.BU_GATEWAY_HOST_PCN, MesExtConstWords.PCN_UPDATE_REWORK_ORDER_STATUS_URL);
        Map<String, String> params = new HashMap<>();
        params.put(MesExtConstWords.SERIAL_NUMBER, JSONObject.toJSONString(serialNumberList));
        params.put(MesExtConstWords.ORGANIZE_CODE, organizeCode);
        params.put("nowTime", organizeCode);
        String data = SxMesHttpUtil.doPost(requestUrl, params);

        BaseResultBean baseResultBean = null;
        if (!StringUtils.isEmpty(data)) {
            baseResultBean = JsonUtilTool.decode(data, BaseResultBean.class);
        } else {
            log.error("修改返工条码和包装条码 HTTP[{}]调用PCN接口失败", requestUrl);
            throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("修改返工条码和包装条码 HTTP调用PCN接口失败")
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .build();
        }
        if (!baseResultBean.success) {
            throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail(baseResultBean.getErrorMsg())
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .build();
        }
    }

    private List<MesProduceSnRepair> queryProduceSnRepairList(String organizeCode, String orderNo) {

        String requestUrl = httpService.getRequestUrl(organizeCode, MesExtConstWords.BU_GATEWAY_HOST_PCN, MesExtConstWords.PCN_UPDATE_REWORK_ORDER_STATUS_URL);
        Map<String, String> params = new HashMap<>();
        params.put(MesExtConstWords.REWORK_ORDER_NO, orderNo);
        params.put(MesExtConstWords.ORGANIZE_CODE, organizeCode);
        String data = SxMesHttpUtil.doPost(requestUrl, params);

        BaseResultBean baseResultBean = null;
        if (!StringUtils.isEmpty(data)) {
            baseResultBean = JsonUtilTool.decode(data, BaseResultBean.class);
        } else {
            log.error("修改返工工单状态 HTTP[{}]调用PCN接口失败", requestUrl);
            throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("修改返工工单状态 HTTP调用PCN接口失败")
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .build();
        }
        if (!baseResultBean.success) {
            throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail(baseResultBean.getErrorMsg())
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .build();
        }

        List<MesProduceSnRepair> produceSnRepairList = new ArrayList<>();
        if (null != baseResultBean && baseResultBean.success
                && null != baseResultBean.getResultList() && baseResultBean.getResultList().size() > 0) {
            List<LinkedHashMap> resultObject = (List<LinkedHashMap>) baseResultBean.getResultList();
            produceSnRepairList = JsonUtilTool.toList(JSONObject.toJSONString(resultObject), MesProduceSnRepair.class);
        }

        //DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        //DdlPreparedPack.getStringEqualPack(orderNo, MesExtConstWords.WORK_ORDER_NO, packBean);
        //return produceSnRepairRepository.findByHqlWhere(packBean);

        return produceSnRepairList;
    }

    private void unbindProdBind(String organizeCode, MesWorkOrderExt mesWorkOrder) {
        DdlPackBean packBeanBind = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(mesWorkOrder.getOrderNo(),MesExtConstWords.WORK_ORDER_NO,packBeanBind);
        List<MesProdBindRecord> prodBindRecordList = prodBindRecordRepository.findByHqlWhere(packBeanBind);
        prodBindRecordList.forEach(p -> p.setActionType(MesEnumUtil.MES_ACTION_TYPE.UNTYING.getValue()));
        prodBindRecordRepository.saveAll(prodBindRecordList);
    }

    private MesWorkOrderExt saveWorkOrder(Integer workOrderStatus, MesWorkOrderExt mesWorkOrder) {
        mesWorkOrder.setWorkOrderStatus(workOrderStatus);
        ConvertBean.serviceModelUpdate(mesWorkOrder, AuthUtil.getSessionUser().getUserName());
        mesWorkOrder.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
        new ConvertBeanExt(mesWorkOrder).convertBean(mesWorkOrder);
        return workOrderExtRepository.save(mesWorkOrder);
    }

    private void checkWmsErpHouseIsExist(String organizeCode, MesWorkOrderExt mesWorkOrder) {
        BaseResultBean baseResultBean =  wmsErpHouseCheckCloud.getWmsZone(mesWorkOrder.getErpWarehouse(), organizeCode);
        if (null == baseResultBean) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("调用校验WMS存储区微服接口失败,BaseResultBean对象为NULL")
                    .build();
        }
        if (!baseResultBean.success) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail(baseResultBean.errorMsg)
                    .build();
        }
    }

    private List<MesWorkOrderLogExt> getMesWorkOrderLogExts(MesWorkOrderExt mesWorkOrder) {
        DdlPackBean ddlPackBean = new DdlPackBean();
        DdlPreparedPack.getStringEqualPack(mesWorkOrder.getOrderNo(),MesExtConstWords.ORDER_NO,ddlPackBean);
        DdlPreparedPack.getNumNOEqualPack(mesWorkOrder.getWorkOrderStatus(),MesExtConstWords.WORK_ORDER_STATUS,ddlPackBean);
        List<MesWorkOrderLogExt> mesWorkOrderLogs = workOrderLogRepository.findByHqlWhere(ddlPackBean);
        return mesWorkOrderLogs;
    }

    private List<MesAffiliatedStartConfig> queryMesAffiliatedStartConfigs(String organizeCode) {
        DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
        return affiliatedStartConfigRepository.findByHqlWhere(ddlPackBean);
    }

    private List<MesWorkOrderExt> queryLandedWorkOrderList(String organizeCode, String workCenterCode) {
        DdlPackBean packBean = MesHqlPack.getMesAllData(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, packBean);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.WORK_ORDER_STATUS.LANDED.getValue(), MesExtConstWords.WORK_ORDER_STATUS, packBean);
        return workOrderExtRepository.findByHqlWhere(packBean);
    }

    private List<MesWorkOrderExt> queryWorkOrderByOrderNoList(List<String> orderNoList, String organizeCode) {
        DdlPackBean packBean = MesHqlPack.getAllBaseData(organizeCode);
        DdlPreparedPack.getInPackList(orderNoList, MesExtConstWords.ORDER_NO, packBean);
        List<MesWorkOrderExt> mesWorkOrderList = workOrderExtRepository.findByHqlWhere(packBean);
        return mesWorkOrderList;
    }

    private void workOrderValidVerify(Integer workOrderStatus, List<MesWorkOrderExt> mesWorkOrderList) {
        if (CollectionUtils.isEmpty(mesWorkOrderList)) {
            throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION_DATA_ERROR.getCode())
                    .setErrorDetail("数据不存在")
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorSolution("校验生产工单表数据")
                    .build();
        }

        Optional<MesWorkOrderExt> optional = mesWorkOrderList.stream().filter(o -> (null != o && StringUtils.isEmpty(o.getWorkCenterCode()))).findFirst();
        if (null != optional && optional.isPresent()) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]未关联生产线", optional.get().getOrderNo())
                    .build();
        }

        Map<Integer, List<MesWorkOrderExt>> listMap = mesWorkOrderList.stream().filter(Objects::nonNull)
                .collect(Collectors.groupingBy(MesWorkOrderExt::getWorkOrderStatus));
        if (CollectionUtils.isEmpty(listMap)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("记录不存在")
                    .build();
        } else {
            if (listMap.size() > 1) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("只能批量%s状态一样的生产工单", MesExtEnumUtil.WORK_ORDER_STATUS.valueOfDescription(workOrderStatus))
                        .build();
            } else if (listMap.size() == 1 && MesExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue() == workOrderStatus) {
                Map<String, List<MesWorkOrderExt>> listMapWorkCenterCode = mesWorkOrderList.stream().filter(Objects::nonNull)
                        .collect(Collectors.groupingBy(MesWorkOrderExt::getWorkCenterCode));
                for (List<MesWorkOrderExt> list : listMapWorkCenterCode.values()) {
                    //相同产线下是否存在多个工单
                    Map<String, List<MesWorkOrder>> orderNoMap = list.stream().filter(Objects::nonNull)
                            .collect(Collectors.groupingBy(MesWorkOrder::getOrderNo));
                    if (!CollectionUtils.isEmpty(orderNoMap) && orderNoMap.size() > 1) {
                        throw ImppExceptionBuilder.newInstance().setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                                .setErrorDetail("同生产线下只能启动一条工单")
                                .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                                .build();
                    }
                }
            }
        }
    }

    private void reworkOrderEmailPush(Integer workOrderStatus, String organizeCode, List<MesWorkOrderExt> mesWorkOrderList) {
        List<MesWorkOrderExt> reworkOrderExt = mesWorkOrderList.stream().filter(o -> o.getWorkOrderType() == MesExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue()).collect(Collectors.toList());
        if(workOrderStatus == MesExtEnumUtil.WORK_ORDER_STATUS.LANDED.getValue() && !CollectionUtils.isEmpty(reworkOrderExt)){
            // 返工工单下达进行邮件推送
            MesBusiConfig reworkLandedEmailTitle = busiConfigService.getBusiConfigByCfgCode(organizeCode, "REWORK_LANDED_EMAIL_TITLE");
            MesBusiConfig reworkLandedEmailUrl = busiConfigService.getBusiConfigByCfgCode(organizeCode, "REWORK_LANDED_EMAIL_URL");
            if(!Optional.ofNullable(reworkLandedEmailUrl).isPresent()){
                log.error("返工工单下达邮件推送地址未维护，需要在业务配置维护配置代码为[REWORK_LANDED_EMAIL_URL]的邮箱地址");
                return;
            }
            StringBuilder content = new StringBuilder("<p>尊敬的SFP用户</p> <p>您好！</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下述返工工单已下发，请及时查看！</p>");
            for (MesWorkOrderExt workOrderExt : reworkOrderExt) {
                content.append("<p>返工型号：").append(workOrderExt.getPartNo()).append("，返工工单号：").append(workOrderExt.getOrderNo()).append("，返工数量：").append(workOrderExt.getQty()).append("</p>");
            }
            content.append("<p>Regards，</p><p>SFP-Team</p>");
            // 发送邮件
            MailMessageModel pushModel = new MailMessageModel();

            pushModel.setTitle(Optional.ofNullable(reworkLandedEmailTitle).isPresent() ? reworkLandedEmailTitle.getCfgValue() : "");
            pushModel.setPathUrl(reworkLandedEmailUrl.getCfgValue());
            pushModel.setContent(content.toString());
            emailPushService.sendPush(pushModel);
        }
    }

    @Override
    public List<MesWorkOrderExt> findMesWorkOrderBySeqAsc(MesWorkOrder mesWorkOrder) {
        List<MesWorkOrderExt> workOrderList = null;
        DdlPackBean packBean = new DdlPackBean();
        String partNoList = null;
        String partNameList = null;
        DdlPreparedPack.getStringEqualPack(mesWorkOrder.getWorkCenterCode(), MesExtConstWords.WORK_CENTER_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(mesWorkOrder.getOrganizeCode(), MesExtConstWords.ORGANIZE_CODE, packBean);
        //DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue(), MesExtConstWords.WORK_ORDER_STATUS, packBean);
        DdlPreparedPack.getNumEqualPack(CommonEnumUtil.VALID, MesExtConstWords.IS_VALID, packBean);
        DdlPreparedPack.getNumEqualPack(CommonEnumUtil.FALSE, MesExtConstWords.IS_DELETED, packBean);
        DdlPreparedPack.timeBuilder(
                mesWorkOrder.getStartTimeStart(),
                mesWorkOrder.getStartTimeEnd(),
                "startTime", packBean, false);
        List<SysRole> roles = AuthUtil.getSessionUser().getUser().getRoleList();
        for (SysRole role : roles) {
            dataAuthService.getDataAuth(role.getId(), MesWorkOrder.class.getSimpleName(), AuthUtil.getOrganize().getOrganizeCode(), packBean);
        }
        packBean.setWhereAppend(packBean.getWhereAppend() + " group by orderNo");
        if (!StringUtils.isEmpty(mesWorkOrder.getOrderByParam())){
            DdlPreparedPack.getOrderByPack(new Object[]{mesWorkOrder.getAscOrDesc()}, new String[]{mesWorkOrder.getOrderByParam()}, packBean);
        }else {
            DdlPreparedPack.getOrderByPack(new Object[]{MesEnumUtil.ASC_OR_DESC.ASC.getValue()}, new String[]{"seq1"}, packBean);
        }
        List<MesWorkOrderExt> mesWorkOrderList = workOrderExtRepository.findByHqlWhere(packBean);

        if (!CollectionUtils.isEmpty(mesWorkOrderList)) {
            for (MesWorkOrderExt workOrder : mesWorkOrderList) {
                partNoList = "";
                partNameList = "";
                //根据工单号查询工单信息集合
                workOrderList = workOrderExtRepository.findByProperty(
                        new String[]{MesExtConstWords.ORDER_NO, MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_VALID, MesExtConstWords.IS_DELETED},
                        new Object[]{workOrder.getOrderNo(), workOrder.getOrganizeCode(),
                                CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                                CommonEnumUtil.IS_DEAL.NO.getValue()});

                int i = 1;
                for (MesWorkOrder workOrder1 : workOrderList) {
                    if (workOrderList.size() == i) {
                        partNoList = partNoList + workOrder1.getPartNo();
                        partNameList = partNameList + workOrder1.getPartNameRdd();
                    } else {
                        partNoList = partNoList + workOrder1.getPartNo() + ",";
                        partNameList = partNameList + workOrder1.getPartNameRdd() + ",";
                    }
                    i++;
                }
                workOrder.setPartNoList(partNoList);
                workOrder.setPartNameList(partNameList);
            }
        }

        return mesWorkOrderList;
    }

    private String getPlanEndTime(String planStartTime, Integer seconds, Integer qty, Integer i) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        seconds = seconds * qty;
        Date afterDate = null;
        try {
            afterDate = new Date(sdf.parse(planStartTime).getTime() + seconds * 1000);
        } catch (ParseException e) {
            if (i == 0) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("日期解析失败，请检查参数")
                        .build();
            } else {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("第【%s】行的日期解析失败，请检查参数", i)
                        .build();
            }

        }
        return sdf.format(afterDate);
    }

    @Override
    public synchronized Double getWorkOrderExtMaxSeq(String organizeCode, Integer count) {
        String key = new StringJoiner(MesExtConstWords.COLON).add(organizeCode).add(MesExtConstWords.WORK_ORDER_MAX_SEQ).toString();
        count = StringUtils.isEmpty(count) ? 1 : count;

        Double maxSeq = (Double) redisMes.getObject(key);
        maxSeq = StringUtils.isEmpty(maxSeq) ? new Double(0) : maxSeq;

        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.DESC.getValue()}, new String[]{MesExtConstWords.SEQ}, packBean);
        MesWorkOrderExt workOrderExt = workOrderExtRepository.getByProperty(packBean);
        if (null != workOrderExt) {
            if (MathOperation.compareTo(maxSeq, workOrderExt.getSeq()) < 0) {
                maxSeq = workOrderExt.getSeq();
            }
        }

        String maxSeqTime = maxSeq.toString().substring(0,6);
        String nowTime = TimeTool.getNowTime("yyyyMM");
        if (!maxSeqTime.equals(nowTime)){
            maxSeq = Double.valueOf(nowTime+"0001");
        }

        redisMes.putObject(key, MathOperation.add(maxSeq, new Double(count)), MesEnumUtil.EXPIRE_TIME.NEVER.getValue());
        return maxSeq;
    }

    @Override
    public void updateOrderSeq(Long orderNo, Long nextOrderNo, String workCenterCode, String organizeCode, String userName) {

        DdlPackBean packBeanCenter = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, packBeanCenter);
        MesWorkCenter workCenter = workCenterRepository.getByProperty(packBeanCenter);

        if (null != workCenterCode && null == workCenter){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("未查询到产线【%s】请重新输入产线查询",workCenterCode)
                    .build();
        }

        //查询所有工单
        DdlPackBean packBeanOrderAll = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, packBeanOrderAll);
        List<MesWorkOrderExt> orderAll = workOrderExtRepository.findByHqlWhere(packBeanOrderAll);

        //找出要调序的工单
        MesWorkOrderExt orderNow = orderAll.stream().filter(item -> item.getId().compareTo(orderNo) == 0).findFirst().get();
        if (null == orderNow){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("调序工单【%s】信息不存在", orderNow)
                    .build();
        }
        if (StringUtils.isEmpty(orderNow.getSeq())){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("调序工单【%s】生产排序字段为空", orderNow)
                    .build();
        }

        MesWorkOrderExt orderNext = null;
        //查询调序位置的下一个工单
        if (!StringUtils.isEmpty(nextOrderNo)){
            orderNext = orderAll.stream().filter(item -> item.getId().compareTo(nextOrderNo) == 0).findFirst().get();
            if (null == orderNext){
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("调序工单【%s】信息不存在", nextOrderNo)
                        .build();
            }
            if (StringUtils.isEmpty(orderNext.getSeq())){
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("调序工单【%s】生产排序字段为空", nextOrderNo)
                        .build();
            }

        }

        if (orderNow.getWorkOrderStatus().compareTo(MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue()) != 0){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("仅可调序创建状态的工单")
                    .build();
        }

        List<MesWorkOrderExt> collect = null;
        if (StringUtils.isEmpty(nextOrderNo)){
            collect = orderAll.stream().filter(o -> orderNow.getSeq() < o.getSeq() && o.getWorkOrderStatus().compareTo(MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue()) != 0 && o.getWorkOrderStatus().compareTo(MesExtEnumUtil.WORK_ORDER_STATUS.REMOVE.getValue()) != 0).collect(Collectors.toList());
        }else {
            if (orderNow.getSeq() < orderNext.getSeq()){
                MesWorkOrderExt finalOrderNext = orderNext;
                collect = orderAll.stream().filter(o -> orderNow.getSeq() <= o.getSeq() && o.getSeq() < finalOrderNext.getSeq() && o.getWorkOrderStatus().compareTo(MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue()) != 0 && o.getWorkOrderStatus().compareTo(MesExtEnumUtil.WORK_ORDER_STATUS.REMOVE.getValue()) != 0).collect(Collectors.toList());
            }else {
                MesWorkOrderExt finalOrderNext1 = orderNext;
                collect = orderAll.stream().filter(o -> orderNow.getSeq() >= o.getSeq() && o.getSeq() >= finalOrderNext1.getSeq() && o.getWorkOrderStatus().compareTo(MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue()) != 0 && o.getWorkOrderStatus().compareTo(MesExtEnumUtil.WORK_ORDER_STATUS.REMOVE.getValue()) != 0).collect(Collectors.toList());
            }
        }

        if (!CollectionUtils.isEmpty(collect)){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单调序位置之间有非创建状态的工单，不可调序")
                    .build();
        }

        List<MesWorkOrderExt> beforeList = null;
        List<MesWorkOrderExt> afterList = null;
        List<Double> seqList = null;
        List<String> seq1List = null;

        if (StringUtils.isEmpty(nextOrderNo) || orderNow.getSeq() < orderNext.getSeq()){
            //向下调序 取包括本工单的之后的所有工单
            beforeList = orderAll.stream().filter(o -> o.getSeq() >= orderNow.getSeq()).collect(Collectors.toList());
            //通过seq排序
            //beforeList = beforeList.stream().sorted(Comparator.comparing(MesWorkOrderExt::getSeq)).collect(Collectors.toList());
            seqList = beforeList.stream().sorted(Comparator.comparing(MesWorkOrderExt::getSeq)).map(MesWorkOrderExt::getSeq).collect(Collectors.toList());
            seq1List = beforeList.stream().sorted(Comparator.comparing(MesWorkOrderExt::getSeq1)).map(MesWorkOrderExt::getSeq1).collect(Collectors.toList());
            //去掉调序工单
            afterList = beforeList.stream().filter(o -> !o.getId().equals(orderNo)).collect(Collectors.toList());
            //通过seq排序
            afterList = afterList.stream().sorted(Comparator.comparing(MesWorkOrderExt::getSeq)).collect(Collectors.toList());
            if (StringUtils.isEmpty(nextOrderNo)){
                //直接插入末尾
                afterList.add(orderNow);
            }else{
                //讲工单插入到调序位置下一个工单的上一个位置
                int size = afterList.size();
                for (int i = 0; i < size; i++) {
                    if (afterList.get(i).getId().equals(nextOrderNo)){
                        afterList.add((i),orderNow);
                        break;
                    }
                }
            }
        }else {
            //向上调序 取爆火下一个工单的之后的所有工单
            MesWorkOrderExt finalOrderNext2 = orderNext;
            beforeList = orderAll.stream().filter(o -> o.getSeq() >= finalOrderNext2.getSeq()).collect(Collectors.toList());
            //通过seq排序
            //beforeList = beforeList.stream().sorted(Comparator.comparing(MesWorkOrderExt::getSeq)).collect(Collectors.toList());
            seqList = beforeList.stream().sorted(Comparator.comparing(MesWorkOrderExt::getSeq)).map(MesWorkOrderExt::getSeq).collect(Collectors.toList());
            seq1List = beforeList.stream().sorted(Comparator.comparing(MesWorkOrderExt::getSeq1)).map(MesWorkOrderExt::getSeq1).collect(Collectors.toList());
            //去掉调序工单
            afterList = beforeList.stream().filter(o -> !o.getId().equals(orderNo)).collect(Collectors.toList());
            //通过seq排序
            afterList = afterList.stream().sorted(Comparator.comparing(MesWorkOrderExt::getSeq)).collect(Collectors.toList());
            //添加调序工单到开头
            afterList.add(0,orderNow);
        }

        if (!CollectionUtils.isEmpty(beforeList) && !CollectionUtils.isEmpty(afterList)){
            for (int i = 0; i < afterList.size(); i++) {
                MesWorkOrderExt orderAfter = afterList.get(i);
                orderAfter.setSeq(seqList.get(i));
                orderAfter.setSeq1(seq1List.get(i));
                orderAfter.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
                ConvertBean.serviceModelUpdate(orderAfter, userName);
                new ConvertBeanExt(orderAfter).convertBean(orderAfter);
                workOrderExtRepository.update(orderAfter);
            }
        }

/*

        if (null == orderNo) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("少参数1")
                    .build();
        }

        //查询所有工单
        DdlPackBean packBeanOrderAll = DdlPackBean.getDdlPackBean(organizeCode);
        List<MesWorkOrderExt> orderAll = workOrderExtRepository.findByHqlWhere(packBeanOrderAll);

        */
/*//*
/筛选出最大seq
        Double seqMax = orderAll.stream().max(Comparator.comparing(MesWorkOrderExt::getSeq)).get().getSeq();*//*


        //找出要调序的工单
        DdlPackBean packBeanOrderLast = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getNumEqualPack(orderNo, MesExtConstWords.ID, packBeanOrderLast);
        MesWorkOrderExt orderNow = workOrderExtRepository.getByProperty(packBeanOrderLast);

        if (null == orderNow){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("少参数2")
                    .build();
        }

        if (!orderNow.getWorkOrderStatus().equals(MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue())){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("仅可调序创建状态的工单")
                    .build();
        }

        */
/*List<MesWorkOrderExt> collect = orderAll.stream().filter(item -> item.getId().equals(orderNo)).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(collect)){
            orderNow = collect.get(0);
        }*//*

        //没有下一个工单直接+1 (找到最后一个工单)
        if (null == nextOrderNo){
            MesWorkOrderExt mesWorkOrder = orderAll.stream().filter(Objects::nonNull).filter(item -> item.getSeq() != null).max(Comparator.comparing(MesWorkOrderExt::getSeq)).get();

            orderNow.setSeq(mesWorkOrder.getSeq() + 1);

            //获取seq1的序号
            Integer seq1Num = Integer.parseInt(mesWorkOrder.getSeq1().substring(6, 11));
            String seq1Head = mesWorkOrder.getSeq1().substring(0, 6);
            seq1Num = seq1Num + 1;

            StringBuilder zero = new StringBuilder();
            if (seq1Num.toString().length() < 5){
                for (int i = 0; i < 5 - seq1Num.toString().length(); i++) {
                    zero.append("0");
                }
            }

            orderNow.setSeq1(seq1Head + zero + seq1Num.toString());

            workOrderExtRepository.update(orderNow);
            return;
        }

        //查询下一个工单
        //MesWorkOrderExt orderNext = orderAll.stream().filter(item -> item.getId().compareTo(nextOrderNo) == 0).findFirst().get();

        DdlPackBean packBeanOrderNext = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getNumEqualPack(nextOrderNo, MesExtConstWords.ID, packBeanOrderNext);
        MesWorkOrderExt orderNext = workOrderExtRepository.getByProperty(packBeanOrderNext);

        //查询出大于等于下一个工单的所有工单
        List<MesWorkOrderExt> orderChange = orderAll.stream().filter(o -> o.getSeq() >= orderNext.getSeq()).collect(Collectors.toList());

        //获取seq1集合
        List<String> seq1List = orderChange.stream().sorted(Comparator.comparing(MesWorkOrderExt::getSeq1)).map(MesWorkOrderExt::getSeq1).collect(Collectors.toList());


        //List<MesWorkOrderExt> collect = orderChange.stream().filter(o -> !o.getWorkOrderStatus().equals(MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue())).collect(Collectors.toList());
        List<MesWorkOrderExt> collect = null;
        if (orderNow.getSeq() < orderNext.getSeq()){
            collect = orderAll.stream().filter(o -> orderNow.getSeq() < o.getSeq() && o.getSeq() < orderNext.getSeq()).collect(Collectors.toList());
        }else {
            collect = orderAll.stream().filter(o -> orderNow.getSeq() > o.getSeq() && o.getSeq() >= orderNext.getSeq()).collect(Collectors.toList());
        }

        if (!CollectionUtils.isEmpty(collect)){
            collect = collect.stream().filter(o -> !o.getWorkOrderStatus().equals(MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue())).collect(Collectors.toList());
        }

        if (!CollectionUtils.isEmpty(collect)){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单调序位置之间有非创建状态的工单，不可调序")
                    .build();
        }

        //请去掉本工单
        List<MesWorkOrderExt> orderChanges = orderChange.stream().filter(o -> !o.getId().equals(orderNo)).collect(Collectors.toList());

        //通过seq排序
        orderChanges = orderChanges.stream().sorted(Comparator.comparing(MesWorkOrderExt::getSeq)).collect(Collectors.toList());

        //插入排序工单
        orderChanges.add(0,orderNow);

        Double seq1 = orderNow.getSeq();
        Double seq2 = orderNext.getSeq();

        //循环建立seq
        Double seq = orderNext.getSeq();
        for (int i = 0; i < orderChanges.size(); i++) {
            if (seq1 < seq2){
                if (i == 0){
                    orderChanges.get(i).setSeq1(orderNext.getSeq1());
                }else {
                    String head = seq1List.get(i - 1).substring(0, 6);
                    Integer num = Integer.parseInt(seq1List.get(i - 1).substring(6,11));
                    num = num + 1;

                    StringBuilder zero = new StringBuilder();
                    if (num.toString().length() < 5){
                        for (int j = 0; j < 5 - num.toString().length(); j++) {
                            zero.append("0");
                        }
                    }

                    orderChanges.get(i).setSeq1(head + zero + num.toString());
                }
            }else {
                orderChanges.get(i).setSeq1(seq1List.get(i));
            }
            orderChanges.get(i).setSeq(seq);
            orderChanges.get(i).setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
            orderChanges.get(i).setSystemSyncStatusExt(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
            workOrderExtRepository.update(orderChanges.get(i));
            seq += 1;
        }
*/

    }

    @Override
    public void doUpdateWorkOrderIsUseCompleteQty(String workOrderNo, String workTime, String shiftCode, String outPutFlag, String organizeCode, String userName) {

        MesWorkOrderExt workOrderExt = workOrderExtRepository.getByProperty(
                new String[]{MesExtConstWords.ORDER_NO, MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_VALID, MesExtConstWords.IS_DELETED},
                new Object[]{workOrderNo, organizeCode,
                        CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                        CommonEnumUtil.IS_DEAL.NO.getValue()});

        if (workOrderExt == null) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单号【%s】不存在", workOrderNo)
                    .build();
        }

        workOrderExt.setOutPutFlag(outPutFlag);
        ConvertBean.serviceModelUpdate(workOrderExt, userName);
        workOrderExtRepository.save(workOrderExt);
        if (!StringUtils.isEmpty(workTime) && !StringUtils.isEmpty(shiftCode)) {
            MesOutPutStatistics outPutStatisticsDb = outPutStatisticsRepository.getByProperty(
                    new String[]{MesExtConstWords.WORK_ORDER_NO, MesExtConstWords.WORK_TIME, MesExtConstWords.SHIFT_CODE, MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_VALID, MesExtConstWords.IS_DELETED},
                    new Object[]{workOrderNo, workTime, shiftCode, organizeCode,
                            CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                            CommonEnumUtil.IS_DEAL.NO.getValue()});

            if (outPutStatisticsDb == null) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("工单号【%s】作业时间【%s】班次代码【%s】产量统计不存在", workOrderNo, workTime, shiftCode)
                        .build();
            }

            outPutStatisticsDb.setOutPutFlag(outPutFlag);

            outPutStatisticsRepository.save(outPutStatisticsDb);
        }

    }

    @Override
    public Map<String, Object> getProductionBatchByWorkOrderNo(String workOrderNo, String organizeCode) {

        Map<String, Object> resultMap = new HashMap<>();
        List<MesOutPutStatistics> outPutStatisticsList = outPutStatisticsRepository.findByProperty(
                new String[]{MesExtConstWords.WORK_ORDER_NO, MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_VALID, MesExtConstWords.IS_DELETED},
                new Object[]{workOrderNo, organizeCode,
                        CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                        CommonEnumUtil.IS_DEAL.NO.getValue()});

        if (CollectionUtils.isEmpty(outPutStatisticsList)) {
            resultMap.put("flag", "false");
            resultMap.put("content", String.format("工单号[%s]暂无产量,是否使用产量作为计划数量", workOrderNo));
            return resultMap;
        }

        String workCenterCode = outPutStatisticsList.get(0).getWorkCenterCode();

        List<SxOutPutStatisticsModel> outPutStatisticsModelList = new ArrayList<>();

        Map<String, String> shiftNameMap = shiftExtService.queryShiftNameMapByWorkCenterCode(organizeCode, workCenterCode);
        for (MesOutPutStatistics mesOutPutStatistics : outPutStatisticsList) {
            SxOutPutStatisticsModel outPutStatisticsModel = new SxOutPutStatisticsModel();
            BeanUtils.copyProperties(mesOutPutStatistics, outPutStatisticsModel);
            outPutStatisticsModel.setShiftName(shiftNameMap.containsKey(outPutStatisticsModel.getShiftCode()) ? shiftNameMap.get(outPutStatisticsModel.getShiftCode()) : outPutStatisticsModel.getShiftCode());
            if (CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr().equals(outPutStatisticsModel.getOutPutFlag())) {
                outPutStatisticsModel.setOutPutFlagName(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getDescription());
            } else {
                outPutStatisticsModel.setOutPutFlagName(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getDescription());
            }
            outPutStatisticsModelList.add(outPutStatisticsModel);
        }

        resultMap.put("flag", "success");
        resultMap.put("content", outPutStatisticsModelList);
        return resultMap;
    }

    @Override
    public List<MesUnbindProduceSn> queryMesUnbindSnList(MesUnbindProduceSn produceSn) {
        produceSn.setBindStatus(MesExtEnumUtil.BIND_STATUS.UNBIND.getValue());
        if (!StringUtils.isEmpty(produceSn.getStartTimeStart()) && !StringUtils.isEmpty(produceSn.getStartTimeEnd())) {
            produceSn.setCreateDateTimeStart(produceSn.getStartTimeStart());
            produceSn.setCreateDateTimeEnd(produceSn.getStartTimeEnd());
        } else {
            String curMonth = TimeTool.getNowTime(MesExtConstWords.DATE_FORMAT_YM);
            produceSn.setCreateDateTimeStart(curMonth + MesExtConstWords.APPEND_ONE_DAY_ZERO_HH_MM_SS);
            produceSn.setCreateDateTimeEnd(SxDateRangeUtils.getLastDayTimeOfMonth(curMonth));
        }
        return unbindProduceSnService.queryUnbindProduceSn(produceSn);
    }

    @Override
    public void doBindUnbindSnByOrderNo(List<String> produceSnList, String orderNo, String organizeCode, String userName) {

        MesWorkOrderExt workOrderExt = workOrderExtRepository.getByProperty(
                new String[]{MesExtConstWords.ORDER_NO, MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_VALID, MesExtConstWords.IS_DELETED},
                new Object[]{orderNo, organizeCode,
                        CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                        CommonEnumUtil.IS_DEAL.NO.getValue()});

        if (workOrderExt == null) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单号【%s】不存在", orderNo)
                    .build();
        }

        List<MesProduceSnExt> produceSnExtList = produceSnExtRepository.findByProperty(
                new String[]{MesExtConstWords.WORK_ORDER_NO, MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_VALID, MesExtConstWords.IS_DELETED},
                new Object[]{orderNo, organizeCode,
                        CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                        CommonEnumUtil.IS_DEAL.NO.getValue()});

        Map<String, MesUnbindProduceSn> mesUnbindProduceSnMapBySn = unbindProduceSnService.queryUnbindProduceSnBySnMap(produceSnList, organizeCode);
        if (CollectionUtils.isEmpty(mesUnbindProduceSnMapBySn)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("条码不存在已解绑条码队列中")
                    .build();
        }

        for (String sn : produceSnList) {
            MesUnbindProduceSn mesUnbindProduceSn = mesUnbindProduceSnMapBySn.get(sn);
            if (mesUnbindProduceSn == null) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("条码%s不存在已解绑条码队列中，请重新查询条码勾选绑定", sn)
                        .build();
            } else if (mesUnbindProduceSn.getBindStatus() == MesExtEnumUtil.BIND_STATUS.BINGDING.getValue()) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("条码%s已与工单%s绑定，请重新查询条码勾选绑定", sn, mesUnbindProduceSn.getWorkOrderNo())
                        .build();
            }
        }

        List<MesUnbindProduceSn> unbindProduceSns = mesUnbindProduceSnMapBySn.values().stream().collect(Collectors.toList());
        int snNum = unbindProduceSns.size();

        Double qty = MathOperation.sub(MathOperation.sub(workOrderExt.getQty(), workOrderExt.getPlanQty()), produceSnExtList.size());
        if (snNum > qty) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("当前勾选条码数量%s大于工单可绑定条码数据%s，请重新查询条码勾选绑定", snNum + "", qty.intValue() + "")
                    .build();
        }

        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackList(produceSnList, MesExtConstWords.SERIAL_NUMBER, packBean);
        List<MesProduceSnExt> produceSnExtDbList = produceSnExtRepository.findByHqlWhere(packBean);

        produceSnExtDbList.forEach( o -> {
            o.setWorkOrderNo(orderNo);
            o.setLastWorkOrderNo(orderNo);
            o.setWorkCenterCode(workOrderExt.getWorkCenterCode());
            o.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
            ConvertBean.serviceModelUpdate(o,userName);
            new ConvertBeanExt(o).convertBean(o);
        });

        List<MesUnbindProduceSnTravel> unbindProduceSnTravels = new ArrayList<>();
        unbindProduceSns.forEach(o -> {
            o.setBindStatus(MesExtEnumUtil.BIND_STATUS.BINGDING.getValue());
            o.setWorkOrderNo(orderNo);
            o.setStartTime(workOrderExt.getStartTime());
            o.setWorkCenterCode(workOrderExt.getWorkCenterCode());
            o.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
            ConvertBean.serviceModelUpdate(o, userName);
            MesUnbindProduceSnTravel unbindProduceSnTravel = new MesUnbindProduceSnTravel();
            BeanUtils.copyProperties(o, unbindProduceSnTravel, MesExtConstWords.ID, MesExtConstWords.CREATE_USER, MesExtConstWords.CREATE_DATE_TIME, MesExtConstWords.MODIFY_USER, MesExtConstWords.MODIFY_DATE_TIME);
            ConvertBean.serviceModelInitialize(unbindProduceSnTravel, userName);
            unbindProduceSnTravels.add(unbindProduceSnTravel);
        });

        if (MathOperation.sub(MathOperation.sub(workOrderExt.getQty(), workOrderExt.getPlanQty()), MathOperation.add(produceSnExtList.size(), snNum)) == 0.0) {
            workOrderExt.setSnCreateStatus(MesExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.CREATED.getValue());
            new ConvertBeanExt(workOrderExt).convertBean(workOrderExt);
            workOrderExtRepository.save(workOrderExt);
        }

        produceSnExtRepository.saveAll(produceSnExtList);
        unbindProduceSnRepository.saveAll(unbindProduceSns);
        unbindProduceSnTravelRepository.saveAll(unbindProduceSnTravels);
    }




}
