package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi;

import cn.estsh.i3plus.ext.mes.pcn.api.base.*;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IProduceSnExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IProductEncodeCfgExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IWorkCellPrintRecordService;
import cn.estsh.i3plus.ext.mes.pcn.api.job.ISxWorkOrderAutoCreateSnService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.dao.IProduceSnRepairDao;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.print.strategy.SxPrintPackageSingleTemplateService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.print.strategy.SxPrintSnSingleTemplateService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.print.strategy.SxPrintTemplateDispatchService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.print.strategy.SxPrintTemplateStrategyContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.sqlpack.MesPcnExtHqlPack;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.ConvertBeanExt;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtEnumUtil;
import cn.estsh.i3plus.mes.pcn.api.iservice.busi.ISyncFuncService;
import cn.estsh.i3plus.mes.pcn.util.PcnHttpUtil;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
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.util.MesPcnConstWords;
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.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesPackageDetail;
import cn.estsh.i3plus.pojo.mes.bean.MesRouteProcess;
import cn.estsh.i3plus.pojo.mes.bean.MesRouteProcessCell;
import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel;
import cn.estsh.i3plus.pojo.mes.repository.MesPackageDetailRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesRouteProcessCellRepository;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import com.alibaba.fastjson.JSONObject;
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.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author wangjie
 * @version 1.0
 * @date 2021/1/13 9:28
 **/
@Slf4j
@Service
public class ProduceSnExtService implements IProduceSnExtService {

    @Autowired
    private MesWorkOrderExtRepository workOrderExtRepository;

    @Autowired
    private ISxWorkOrderExtService workOrderExtService;

    @Autowired
    private MesProduceSnExtRepository produceSnExtRepository;

    @Autowired
    private ISxWorkOrderAutoCreateSnService workOrderAutoCreateSnService;

    @Autowired
    private IPartExtService partExtService;

    @Autowired
    private IProduceSnRepairDao produceSnRepairDao;

    @Autowired
    private IProdPackExtService prodPackExtService;

    @Autowired
    private IProductEncodeCfgExtService productEncodeCfgExtService;

    @Autowired
    private ISyncFuncService syncFuncService;

    @Autowired
    private SxPrintTemplateStrategyContext printTemplateStrategyContext;

    @Autowired
    private MesRouteProcessCellRepository routeProcessCellRepository;

    @Autowired
    private IRouteProcessExtService routeProcessExtService;

    @Autowired
    private SxPrintTemplateDispatchService printTemplateDispatchService;

    @Autowired
    private MesPackageExtRepository packageExtRepository;

    @Autowired
    private IWorkCellPrintRecordService workCellPrintRecordService;

    @Autowired
    private MesProdBindRecordExtRepository prodBindRecordExtRepository;

    @Autowired
    private MesProdUnbindRecordRepository prodUnbindRecordRepository;

    @Autowired
    private MesProduceSnTravelExtRepository produceSnTravelExtRepository;

    @Autowired
    private MesPackageDetailRepository packageDetailRepository;

    @Autowired
    private ISxPcnHttpService pcnHttpService;

    @Override
    public List<MesProduceSnExt> getProduceSnExtListByOrderNo(String organizeCode, String workOrderNo) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workOrderNo)) {
            return null;
        }
        return produceSnExtRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_ORDER_NO},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workOrderNo});
    }

    @Override
    public List<MesProduceSnExt> getProduceSnExtListByOrderNoAndSnType(String organizeCode, String workOrderNo, Integer snType) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workOrderNo) ) {
            return null;
        }
        return produceSnExtRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_ORDER_NO,MesPcnExtConstWords.SN_TYPE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workOrderNo,snType});
    }

    @Override
    public MesProduceSnExt getProduceSnExtByOrderNo(String organizeCode, String workOrderNo) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workOrderNo)) {
            return null;
        }
        return produceSnExtRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_ORDER_NO},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workOrderNo});
    }

    @Override
    public List<MesProduceSnExt> getProduceSnExtListByLastOrderNo(String organizeCode, String lastWorkOrderNo) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(lastWorkOrderNo)) {
            return null;
        }
        return produceSnExtRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.LAST_WORK_ORDER_NO},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), lastWorkOrderNo});
    }

    @Override
    public ListPager<MesProduceSnExt> queryProduceSnExtByPager(MesProduceSnExt produceSnExt, Pager pager) {
        DdlPackBean hqlPack = MesPcnExtHqlPack.getProduceSnExt(produceSnExt);
        pager = PagerHelper.getPager(pager, produceSnExtRepository.findByHqlWhereCount(hqlPack));
        hqlPack.setOrderByStr(" order by serialNumber asc ");
        return new ListPager(produceSnExtRepository.findByHqlWherePage(hqlPack, pager), pager);
    }

    @Override
    public ListPager<ProduceSnExtModel> queryProduceSnExtByWorkOrderTypeByPager(ProduceSnExtModel produceSnExtModel, Pager pager) {
        List<ProduceSnExtModel> modelList = new ArrayList<>();
        if (MesPcnExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue() != produceSnExtModel.getWorkOrderType()) {
            DdlPackBean hqlPack = DdlPackBean.getDdlPackBean(produceSnExtModel.getOrganizeCode());
            DdlPreparedPack.getStringEqualPack(produceSnExtModel.getWorkOrderNo(), MesPcnExtConstWords.WORK_ORDER_NO, hqlPack);
            pager = PagerHelper.getPager(pager, produceSnExtRepository.findByHqlWhereCount(hqlPack));
            hqlPack.setOrderByStr(" order by serialNumber asc ");
            List<MesProduceSnExt> produceSnExtList = produceSnExtRepository.findByHqlWherePage(hqlPack, pager);
            if (!CollectionUtils.isEmpty(produceSnExtList)) {
                for (MesProduceSnExt item : produceSnExtList) {
                    if (null == item) {
                        continue;
                    }
                    ProduceSnExtModel model = new ProduceSnExtModel();
                    BeanUtils.copyProperties(item, model);
                    modelList.add(model);
                }
            }
        } else {
            pager = PagerHelper.getPager(pager, produceSnRepairDao.queryProduceSnRepairByPagerCount(produceSnExtModel));
            modelList = produceSnRepairDao.queryProduceSnRepairByPager(produceSnExtModel , pager);
        }
        return new ListPager(modelList, pager);
    }


    @Override
    public synchronized void doWorkOrderCreateSn(Boolean flag, Object... param) {
        if (flag) {
            workOrderAutoCreateSnService.doWorkOrderAutoCreateSn((String) param[0]);
        } else {
            doWorkOrderHandCreateSn((Long) param[0], (String) param[1], (String) param[2]);
        }
    }

    private void doWorkOrderHandCreateSn(Long id, String organizeCode, String userInfo) {
        log.info("手动生成条码开始,执行工单ID[{}]", id);
        MesWorkOrderExt workOrder = getWorkOrderById(id, organizeCode);
        log.info("手动生成条码开始,执行工单ID[{}],工单号[{}]", id, workOrder.getOrderNo());
        MesPartExt partDb = partExtService.getPartExt(workOrder.getOrganizeCode(), workOrder.getPartNo());
        doCheckWorkOrderIsExistSn(workOrder, partDb, userInfo);
        MesProdPackExt prodPackDb = getProdPack(organizeCode, workOrder.getOrderNo(), partDb.getPartNo(), partDb.getPptCode());
        log.info("手动生成条码通过工单及物料校验,执行工单ID[{}],工单号[{}]", id, workOrder.getOrderNo());
        doHandCreateSn(workOrder, partDb, prodPackDb, userInfo);
        log.info("手动生成条码修改工单条码生成状态,执行工单ID[{}],工单号[{}]", id, workOrder.getOrderNo());
        workOrderExtService.saveSnCreateStatus(workOrder, userInfo, MesPcnExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.CREATED.getValue());
    }

    private MesWorkOrderExt getWorkOrderById(Long id, String organizeCode) {
        MesWorkOrderExt workOrder = workOrderExtRepository.getById(id);
        if (null == workOrder ||
                (CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue() == workOrder.getIsDeleted() ||
                        CommonEnumUtil.IS_VAILD.INVAILD.getValue() == workOrder.getIsValid())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("ID[%s]数据无效", id)
                    .build();
        }
        if (!organizeCode.equals(workOrder.getOrganizeCode())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]不属于[%s]工厂", id, organizeCode)
                    .build();
        }
        if (MesPcnExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue() == workOrder.getWorkOrderType()) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]类型为[%s],不能生成条码",
                            workOrder.getOrderNo(), MesPcnExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getDescription())
                    .build();
        }
        if (MesPcnExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.NO_CREATE.getValue() == workOrder.getSnCreateStatus() ||
                MesPcnExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.CREATED.getValue() == workOrder.getSnCreateStatus()) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s][%s]条码,操作失败",
                            workOrder.getOrderNo(), MesPcnExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.valueOfDescription(workOrder.getSnCreateStatus()))
                    .build();
        }
        return workOrder;
    }

    private MesWorkOrderExt getWorkOrderByIdPackage(Long id, String organizeCode) {
        MesWorkOrderExt workOrder = workOrderExtRepository.getById(id);
        if (null == workOrder ||
                (CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue() == workOrder.getIsDeleted() ||
                        CommonEnumUtil.IS_VAILD.INVAILD.getValue() == workOrder.getIsValid())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("ID[%s]数据无效", id)
                    .build();
        }
        if (!organizeCode.equals(workOrder.getOrganizeCode())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]不属于[%s]工厂", id, organizeCode)
                    .build();
        }
        if (MesPcnExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue() == workOrder.getWorkOrderType()) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]类型为[%s],不能生成条码",
                            workOrder.getOrderNo(), MesPcnExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getDescription())
                    .build();
        }
        /*if (MesPcnExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.NO_CREATE.getValue() == workOrder.getSnCreateStatus() ||
                MesPcnExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.CREATED.getValue() == workOrder.getSnCreateStatus()) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s][%s]条码,操作失败",
                            workOrder.getOrderNo(), MesPcnExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.valueOfDescription(workOrder.getSnCreateStatus()))
                    .build();
        }*/
        return workOrder;
    }

    private void doCheckWorkOrderIsExistSn(MesWorkOrderExt workOrder, MesPartExt partDb, String userInfo) {
        if (null == partDb) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("工单[%s]关联的物料号[%s]无效", workOrder.getOrderNo(), workOrder.getPartNo())
                    .build();
        }
        if (StringUtils.isEmpty(partDb.getIsCreateSn())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]关联的物料号[%s]未维护是否生成条码标识", workOrder.getOrderNo(), workOrder.getPartNo())
                    .build();
        }
        if (CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue() == partDb.getIsCreateSn()) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]关联的物料号[%s]不支持生成条码", workOrder.getOrderNo(), workOrder.getPartNo())
                    .build();
        }
        List<MesProduceSnExt> produceSnExtList = getProduceSnExtListByOrderNo(workOrder.getOrganizeCode(), workOrder.getOrderNo());
        if (!CollectionUtils.isEmpty(produceSnExtList)) {
            if (produceSnExtList.size() == workOrder.getQty().intValue()) {
                workOrderExtService.saveSnCreateStatusNewRequires(workOrder, userInfo, MesPcnExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.CREATED.getValue());
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("工单[%s]已经生成过条码,操作失败", workOrder.getOrderNo())
                        .build();
            }
            //else {
            //    throw ImppExceptionBuilder.newInstance()
            //            .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
            //            .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
            //            .setErrorDetail("工单[%s]已经生成过条码,但是请注意生成的条码数量[%s]与工单数量[%s]不一致",
            //                    workOrder.getOrderNo(), produceSnExtList.size(), workOrder.getQty())
            //            .build();
            //}
        }
        if (StringUtils.isEmpty(partDb.getProcessMatchType())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]关联的物料号[%s]未维护过程编码匹配类型", workOrder.getOrderNo(), workOrder.getPartNo())
                    .build();
        }
        if (null == MesPcnExtEnumUtil.ENCODE_MATCH_TYPE.getByValue(partDb.getProcessMatchType())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]关联的物料号[%s]未维护有效的过程编码匹配类型", workOrder.getOrderNo(), workOrder.getPartNo())
                    .build();
        }
    }

    private MesProdPackExt getProdPack(String organizeCode, String orderNo, String partNo, String pptCode) {
        MesProdPackExt prodPackDb = prodPackExtService.getProdPackExt(organizeCode, partNo, pptCode);
        if (null == prodPackDb || StringUtils.isEmpty(prodPackDb.getProcessLabelTemplate())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]关联的物料号[%s]未在产品包装关系中维护过程标签模板", orderNo, partNo)
                    .build();
        }
        return prodPackDb;
    }

    private int getProduceSnNum(MesWorkOrderExt workOrder) {

        String requestUrl = pcnHttpService.getRequestUrl(workOrder.getOrganizeCode(), MesPcnExtConstWords.GET_PRODUCE_SN_NUM);
        log.info("getProduceSnNum --- 获取URL：{}",requestUrl);
        Map<String, String> params = new HashMap<>();
        params.put(MesPcnExtConstWords.WORK_ORDER_NO, workOrder.getOrderNo());
        params.put(MesPcnExtConstWords.ORGANIZE_CODE, workOrder.getOrganizeCode());
        String data = PcnHttpUtil.doPost(requestUrl, params);
        BaseResultBean baseResultBean = null;
        if (!StringUtils.isEmpty(data)) {
            baseResultBean = JsonUtilTool.decode(data, BaseResultBean.class);
        } else {
            log.error("getProduceSnNum --- HTTP[{}]调用主接口失败", requestUrl);
        }

        int produceSnNum = 0;
        if (null != baseResultBean && baseResultBean.success) {
            produceSnNum = (int)baseResultBean.getResultObject();
        } else {
            log.error("getProduceSnNum --- HTTP[{}]调用主接口失败 baseResultBean:{}", requestUrl, baseResultBean);
        }
        return produceSnNum;
    }

    private void doHandCreateSn(MesWorkOrderExt workOrder, MesPartExt partDb, MesProdPackExt prodPackDb, String userInfo) {
        List<MatchRuleCodeModel> codeTypeList = workOrderAutoCreateSnService.getCodeType(workOrder, getProduceSnNum(workOrder));
        if (CollectionUtils.isEmpty(codeTypeList)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]类型未匹配到条码类型,请检查工单类型是否有效", workOrder.getOrderNo())
                    .build();
        }

        for (MatchRuleCodeModel model : codeTypeList) {
            if (null == model) {
                continue;
            }
            log.info("手动生成条码开始创建[{}]条码,执行工单ID[{}],工单号[{}]", MesPcnExtEnumUtil.ENCODE_CODE_TYPE.valueOfDescription(model.getCodeType()), workOrder.getId(), workOrder.getOrderNo());
            String ruleCode = productEncodeCfgExtService.getRuleCodeByMatchType(workOrder.getOrganizeCode(), model.getCodeType(), partDb, workOrder.getWorkCenterCode());
            GenSerialNoModel genSerialNoModel = workOrderAutoCreateSnService.doPackGenSerialNoModel(workOrder, ruleCode, partDb, workOrder.getStartTime());
            if (null == genSerialNoModel) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("工单[%s]编码规则封装入参属性失败", workOrder.getOrderNo())
                        .build();
            }
            if (StringUtils.isEmpty(model.getCount()) || model.getCount().compareTo(0) <= 0) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("请检查工单[%s]数量", workOrder.getOrderNo())
                        .build();
            }
            log.info("手动生成条码正在生成[{}]条码,数量[{}],执行工单ID[{}],工单号[{}]", MesPcnExtEnumUtil.ENCODE_CODE_TYPE.valueOfDescription(model.getCodeType()), model.getCount(), workOrder.getId(), workOrder.getOrderNo());
            BaseResultBean<String> resultBean = syncFuncService.syncSerialNo(genSerialNoModel, userInfo, workOrder.getOrganizeCode(), model.getCount());
            if (resultBean != null && resultBean.isSuccess()) {
                log.info("手动生成条码生成[{}]条码成功,数量[{}],执行工单ID[{}],工单号[{}]", MesPcnExtEnumUtil.ENCODE_CODE_TYPE.valueOfDescription(model.getCodeType()), model.getCount(), workOrder.getId(), workOrder.getOrderNo());
                if (CollectionUtils.isEmpty(resultBean.getResultList())) {
                    throw ImppExceptionBuilder.newInstance()
                            .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                            .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                            .setErrorDetail("工单[%s]批量生成过程条码时没有返回过程条码集合,操作失败", workOrder.getOrderNo())
                            .build();
                }
                log.info("手动生成条码生成[{}]条码成功,执行工单ID[{}],工单号[{}],数量[{}],条码区间[{}~{}]", MesPcnExtEnumUtil.ENCODE_CODE_TYPE.valueOfDescription(model.getCodeType()),
                        workOrder.getId(), workOrder.getOrderNo(), model.getCount(), resultBean.getResultList().get(0), resultBean.getResultList().get(resultBean.getResultList().size() - 1));
                if(StringUtils.isEmpty(resultBean.getResultList().get(0))){
                    throw ImppExceptionBuilder.newInstance()
                            .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                            .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                            .setErrorDetail("物料[%S]关联生产编码规则错误,请重新设置", workOrder.getPartNo())
                            .build();
                }
                workOrderAutoCreateSnService.insertProduceSnExt(resultBean.getResultList(), workOrder, partDb, model.getCodeType(), prodPackDb, userInfo);
            } else {
                log.error("手动生成条码生成[{}]条码失败,执行工单ID[{}],工单号[{}]", MesPcnExtEnumUtil.ENCODE_CODE_TYPE.valueOfDescription(model.getCodeType()), workOrder.getId(), workOrder.getOrderNo());
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("工单[%s]批量生成过程条码失败", workOrder.getOrderNo())
                        .build();
            }
        }
    }

    @Override
    public List<Map<String, Object>> doWorkOrderPrintSn(SxPrintTemplateModel model) {
        List<MesProduceSnExt> produceSnExtList;
        if (!StringUtils.isEmpty(model.getWorkOrderNo())) {
            MesWorkOrderExt workOrderExt = workOrderExtService.getWorkOrderExtByOrderNo(model.getOrganizeCode(), model.getWorkOrderNo());
            produceSnExtList = getSnListByOrderNo(model, workOrderExt);
        } else {
            produceSnExtList = getSnListByIdList(model);
        }
        if (CollectionUtils.isEmpty(produceSnExtList)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("暂无条码,不能打印")
                    .build();
        }

        MesPartExt partExt = partExtService.getPartExt(model.getOrganizeCode(), produceSnExtList.get(0).getPartNo());

        MesWorkOrderExt order = workOrderExtService.getWorkOrderExtByOrderNo(model.getOrganizeCode(), produceSnExtList.get(0).getWorkOrderNo());

        SxPrintTemplateModel printTemplateModel = packSxPrintTemplateModel(model.getOrganizeCode(), produceSnExtList, produceSnExtList.get(0).getProcessLabelTemplate(), partExt, order, partExt.getSnPrintTimes() != null && partExt.getSnPrintTimes() >1 ? partExt.getSnPrintTimes() : 1, MesPcnExtEnumUtil.PRINT_QUEUE_TYPE.PROD_SN.getValue());

        List<Map<String, Object>> resultMapList;
        try {
            resultMapList = printTemplateStrategyContext.getPrintTemplateService(printTemplateModel, SxPrintSnSingleTemplateService.class);
            if(!CollectionUtils.isEmpty(resultMapList)){
                resultMapList.get(0).put("snPrintColumnNumber", partExt.getSnPrintColumnNumber() != null && partExt.getSnPrintColumnNumber() > 1 ? partExt.getSnPrintColumnNumber() : 1);
            }
        } catch (Exception e) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("模板错误,请检查模板配置")
                    .build();
        }

        savePrintStatus(produceSnExtList, model.getUserInfo());

        saveWorkCellPrintRecord(produceSnExtList, model, partExt.getSnPrintTimes() != null && partExt.getSnPrintTimes() > 1 ? partExt.getSnPrintTimes() : 1);

        log.info("469手动打印跟踪，机构{}--打印人{}---打印信息{}--传入参数{}",model.getOrganizeCode(),model.getUserInfo(),JSONObject.toJSONString(resultMapList),JSONObject.toJSONString(model));

        return resultMapList;
    }

    private void saveWorkCellPrintRecord(List<MesProduceSnExt> produceSnExtList, SxPrintTemplateModel model, Integer getSnPrintTimes){
        for (int i = 0; i < getSnPrintTimes; i++) {
            MesWorkCellPrintRecord workCellPrintRecord = new MesWorkCellPrintRecord();
            workCellPrintRecord.setObjectCode("MesProduceSnExt");
            workCellPrintRecord.setObjectName("产品条码");
            workCellPrintRecord.setSourceModule("生产工单");
            workCellPrintRecord.setPrintCount(produceSnExtList.size());
            workCellPrintRecord.setWorkOrderNo(produceSnExtList.get(0).getWorkOrderNo());
            workCellPrintRecord.setWorkCenterCode(produceSnExtList.get(0).getWorkCenterCode());
            workCellPrintRecord.setPartNo(produceSnExtList.get(0).getPartNo());
            workCellPrintRecord.setPartNameRdd(produceSnExtList.get(0).getPartNameRdd());
            workCellPrintRecord.setTagType(MesPcnExtEnumUtil.PRINT_QUEUE_TYPE.PROD_SN.getValue());
            List<PrintRecordModel> printRecordModelList = new ArrayList<>();
            produceSnExtList.stream().filter(o -> null != o).forEach(o -> {
                printRecordModelList.add(new PrintRecordModel(o.getId(), o.getSerialNumber()));
            });
            workCellPrintRecord.setPrintIds(JSONObject.toJSONString(printRecordModelList));
            workCellPrintRecord.setOrganizeCode(model.getOrganizeCode());
            ConvertBean.serviceModelInitialize(workCellPrintRecord, model.getUserInfo());
            workCellPrintRecordService.insertWorkCellPrintRecordNoRollback(workCellPrintRecord);
        }
    }

    private void savePrintStatus(List<MesProduceSnExt> produceSnExtList, String userInfo) {
        for (MesProduceSnExt sn : produceSnExtList) {
            if (null != sn && MesPcnExtEnumUtil.PRODUCE_SN_PRINT_STATUS.UNPRINT.getValue() == sn.getPrintStatus()) {
                sn.setPrintStatus(MesPcnExtEnumUtil.PRODUCE_SN_PRINT_STATUS.PRINTED.getValue());
                ConvertBean.serviceModelUpdate(sn, userInfo);
                sn.setSystemSyncStatus(MesPcnExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
                new ConvertBeanExt(sn).convertBean(sn);
                produceSnExtRepository.save(sn);
            }
        }
    }

    private void savePackagePrintStatus(List<MesPackageExt> packageList, String userInfo) {
        for (MesPackageExt pack : packageList) {
            if (null != pack && MesPcnExtEnumUtil.PRODUCE_SN_PRINT_STATUS.UNPRINT.getValue() == pack.getPrintStatus()) {
                pack.setPrintStatus(MesPcnExtEnumUtil.PRODUCE_SN_PRINT_STATUS.PRINTED.getValue());
                ConvertBean.serviceModelUpdate(pack, userInfo);
                pack.setSystemSyncStatus(MesPcnExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
                new ConvertBeanExt(pack).convertBean(pack);
                packageExtRepository.save(pack);
            }
        }
    }

    @Override
    public SxPrintTemplateModel packSxPrintTemplateModel(String organizeCode, List<MesProduceSnExt> produceSnExtList, String templateCode, MesPartExt partExt, MesWorkOrderExt order, Integer snPrintTimes, Integer printType) {
        SxPrintTemplateModel printTemplateModel = new SxPrintTemplateModel();
        printTemplateModel.setOrganizeCode(organizeCode);
        printTemplateModel.setLabelTemplate(printTemplateDispatchService.getLabelTemplate(templateCode));
        printTemplateModel.setPart(partExt);
        List<ProduceSnExtModel> snList = new ArrayList<>();
        for (MesProduceSnExt produceSn : produceSnExtList) {
            if (null == produceSn) {
                continue;
            }

            for (int i = 0; i < snPrintTimes; i++) {
                ProduceSnExtModel sn = new ProduceSnExtModel();
                BeanUtils.copyProperties(produceSn, sn, MesPcnExtConstWords.ID);
                snList.add(sn);
            }

        }
        printTemplateModel.setSnList(snList);

        printTemplateDispatchService.packTemplateModel(printTemplateModel, partExt.getPartNo(), printType, organizeCode);
        return printTemplateModel;
    }

    @Override
    public List<MesProduceSnExt> getSnListByOrderNo(SxPrintTemplateModel model, MesWorkOrderExt workOrderExt) {
        List<MesProduceSnExt> produceSnExtList = null;
        if (null != workOrderExt && MesPcnExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.CREATED.getValue() == workOrderExt.getSnCreateStatus()) {
            DdlPackBean packBean = DdlPackBean.getDdlPackBean(model.getOrganizeCode());
            DdlPreparedPack.getStringEqualPack(workOrderExt.getOrderNo(), MesPcnExtConstWords.WORK_ORDER_NO, packBean);
            if (!StringUtils.isEmpty(model.getAscOrDesc()) && !StringUtils.isEmpty(model.getOrderByParam())) {
                DdlPreparedPack.getOrderByPack(new Object[]{model.getAscOrDesc()}, new String[]{model.getOrderByParam()}, packBean);
            }
            produceSnExtList = produceSnExtRepository.findByHqlWhere(packBean);
        }
        return produceSnExtList;
    }

    @Override
    public List<MesProduceSnExt> getSnListByIdList(SxPrintTemplateModel model) {
        List<MesProduceSnExt> produceSnExtList = null;
        if (!CollectionUtils.isEmpty(model.getIdList())) {
            for (Long id : model.getIdList()) {
                if (StringUtils.isEmpty(id)) {
                    continue;
                }
                MesProduceSnExt produceSnExt = produceSnExtRepository.getById(id);
                if (null != produceSnExt) {
                    if (CollectionUtils.isEmpty(produceSnExtList)) {
                        produceSnExtList = new ArrayList<>();
                    }
                    produceSnExtList.add(produceSnExt);
                }
            }
        }
        return produceSnExtList;
    }

    @Override
    public MesProduceSnExt getProduceSnExtBySn(String organizeCode, String serialNumber) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(serialNumber)) {
            return null;
        }
        return produceSnExtRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.SERIAL_NUMBER},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), serialNumber});
    }

    @Override
    public MesProduceSnExt getProduceSnExtByProductSn(String organizeCode, String productSn) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(productSn)) {
            return null;
        }
        return produceSnExtRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.PRODUCT_SN},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), productSn});
    }

    @Override
    public MesProduceSnExt getProduceSnExtBySnAndOrderNo(String organizeCode, String serialNumber, String workOrderNo) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(serialNumber) || StringUtils.isEmpty(workOrderNo)) {
            return null;
        }
        return produceSnExtRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.SERIAL_NUMBER, MesPcnExtConstWords.WORK_ORDER_NO},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), serialNumber, workOrderNo});
    }

    @Override
    public void packSnExtProcess(MesProduceSnExt produceSnExt, String organizeCode, String workCenterCode, String workCellCode) {
        if (null != produceSnExt && !StringUtils.isEmpty(organizeCode) && !StringUtils.isEmpty(workCenterCode) && !StringUtils.isEmpty(workCellCode)) {
            MesRouteProcessCell processCell = routeProcessCellRepository.getByProperty(
                    new String[]{MesPcnConstWords.ORGANIZE_CODE, MesPcnConstWords.IS_DELETED, MesPcnConstWords.IS_VALID, MesPcnConstWords.WORK_CENTER_CODE, MesPcnConstWords.WORK_CELL_CODE},
                    new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workCenterCode, workCellCode});

            if (null != processCell) {
                produceSnExt.setProcessCode(processCell.getProcessCode());

                MesRouteProcess routeProcess = routeProcessExtService.getRouteProcessByCode(organizeCode, processCell.getRouteCode(), processCell.getProcessCode());
                if (null != routeProcess) {
                    produceSnExt.setNextProcessCode(routeProcess.getNextProcess());
                }
            }

            //返工工单不变更工位
            if (StringUtils.isEmpty(produceSnExt.getLastWorkOrderNo()) || produceSnExt.getLastWorkOrderNo().equals(produceSnExt.getWorkOrderNo())) {
                produceSnExt.setWorkCenterCode(workCenterCode);
                produceSnExt.setWorkCellCode(workCellCode);
            }
        }
    }

    @Override
    public void doWorkOrderHandCreatePackage(Long id, String organizeCode, String userInfo) {
        MesWorkOrderExt workOrder = getWorkOrderByIdPackage(id, organizeCode);
        MesPartExt partDb = partExtService.getPartExt(workOrder.getOrganizeCode(), workOrder.getPartNo());
        if (null == partDb) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("工单[%s]关联的物料号[%s]无效", workOrder.getOrderNo(), workOrder.getPartNo())
                    .build();
        }
        if (!MesPcnExtEnumUtil.CATEGORY_CODE_2.OUTSIDE.getValue().equals(partDb.getCategoryCode2())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]关联的物料号[%s]基础信息物料分类2未维护成JX内制", workOrder.getOrderNo(), workOrder.getPartNo())
                    .build();
        }

        if (partDb.getQty2() <= 0) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("该产品[%s]未维护包装数量", workOrder.getPartNo())
                    .build();
        }

        List<MesPackageExt> packageList = getPackageListByOrderNo(workOrder.getOrganizeCode(), workOrder.getOrderNo());
        if (!CollectionUtils.isEmpty(packageList)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]已经生成过包装条码,操作失败", workOrder.getOrderNo())
                    .build();
        }

        if (StringUtils.isEmpty(partDb.getPackageMatchType())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]关联的物料号[%s]未维护包装编码匹配类型", workOrder.getOrderNo(), workOrder.getPartNo())
                    .build();
        }
        if (null == MesPcnExtEnumUtil.ENCODE_MATCH_TYPE.getByValue(partDb.getPackageMatchType())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]关联的物料号[%s]未维护有效的包装编码匹配类型", workOrder.getOrderNo(), workOrder.getPartNo())
                    .build();
        }

        //查询包装关系
        MesProdPackExt prodPackDb = prodPackExtService.getProdPackExt(organizeCode, partDb.getPartNo(), partDb.getPptCode());
        if (null == prodPackDb || StringUtils.isEmpty(prodPackDb.getPackLabelTemplate())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]关联的物料号[%s]未在产品包装关系中维护包装标签模板", workOrder.getOrderNo(), workOrder.getPartNo())
                    .build();
        }

        //获得工单类型
        MatchRuleCodeModel codeType = null;
        //余量
        double num = 0;
        switch (MesPcnExtEnumUtil.WORK_ORDER_TYPE.getByValue(workOrder.getWorkOrderType())) {
            case ATTEMPT_ORDER:
            case STANDARD_ORDER:
                //生成包装条码的数量
                int count = 0;
                while (true) {
                    count++;
                    //工单数量
                    Double qty = workOrder.getQty();
                    //包装数量
                    Double qty2 = partDb.getQty2();

                    num = MathOperation.sub(qty, qty2 * count);
                    int compareTo = MathOperation.compareTo(num, new Double(0));
                    if (compareTo == 0) {
                        break;
                    } else if (compareTo == -1) {
                        //计算余量
                        num = MathOperation.sub(qty, qty2 * (count - 1));
                        break;
                    }
                }
                codeType = new MatchRuleCodeModel(MesPcnExtEnumUtil.ENCODE_CODE_TYPE.PACK_SN.getValue(), count);
                break;
            default:
                break;
        }

        if (null == codeType) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]类型未匹配到条码类型,请检查工单类型是否有效", workOrder.getOrderNo())
                    .build();
        }

        String ruleCode = productEncodeCfgExtService.getRuleCodeByMatchType(workOrder.getOrganizeCode(), codeType.getCodeType(), partDb, workOrder.getWorkCenterCode());
        GenSerialNoModel genSerialNoModel = workOrderAutoCreateSnService.doPackGenSerialNoModel(workOrder, ruleCode, partDb, null);
        //genSerialNoModel.setDynamicRule(workOrder.getOrderNo());
        if (null == genSerialNoModel) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]编码规则封装入参属性失败", workOrder.getOrderNo())
                    .build();
        }
        if (StringUtils.isEmpty(codeType.getCount()) || codeType.getCount().compareTo(0) <= 0) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("请检查工单[%s]数量", workOrder.getOrderNo())
                    .build();
        }
        genSerialNoModel.setPartNo(partDb.getPartNo());
        BaseResultBean<String> resultBean = syncFuncService.syncSerialNo(genSerialNoModel, userInfo, workOrder.getOrganizeCode(), codeType.getCount());
        if (resultBean != null && resultBean.isSuccess()) {
            if (CollectionUtils.isEmpty(resultBean.getResultList())) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("工单[%s]批量生成包装条码时没有返回包装条码集合,操作失败", workOrder.getOrderNo())
                        .build();
            }
            workOrderAutoCreateSnService.insertPackage(resultBean.getResultList(), workOrder, partDb, codeType.getCodeType(), prodPackDb, num, userInfo);
        } else {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]批量生成包装条码失败", workOrder.getOrderNo())
                    .build();
        }
    }

    @Override
    public String getWorkOrderCreatePackageQty(Long id, String organizeCode, String userInfo) {
        MesWorkOrderExt workOrder = getWorkOrderByIdPackage(id, organizeCode);
        MesPartExt partDb = partExtService.getPartExt(workOrder.getOrganizeCode(), workOrder.getPartNo());
        if (null == partDb) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("工单[%s]关联的物料号[%s]无效", workOrder.getOrderNo(), workOrder.getPartNo())
                    .build();
        }
        if (!MesPcnExtEnumUtil.CATEGORY_CODE_2.OUTSIDE.getValue().equals(partDb.getCategoryCode2())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]关联的物料号[%s]基础信息物料分类2未维护成JX内制", workOrder.getOrderNo(), workOrder.getPartNo())
                    .build();
        }

        if (partDb.getQty2() <= 0) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("该产品[%s]未维护包装数量", workOrder.getPartNo())
                    .build();
        }

        List<MesPackageExt> packageList = getPackageListByOrderNo(workOrder.getOrganizeCode(), workOrder.getOrderNo());
        if (!CollectionUtils.isEmpty(packageList)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]已经生成过包装条码,操作失败", workOrder.getOrderNo())
                    .build();
        }

        if (StringUtils.isEmpty(partDb.getPackageMatchType())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]关联的物料号[%s]未维护包装编码匹配类型", workOrder.getOrderNo(), workOrder.getPartNo())
                    .build();
        }
        if (null == MesPcnExtEnumUtil.ENCODE_MATCH_TYPE.getByValue(partDb.getPackageMatchType())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]关联的物料号[%s]未维护有效的包装编码匹配类型", workOrder.getOrderNo(), workOrder.getPartNo())
                    .build();
        }

        //查询包装关系
        MesProdPackExt prodPackDb = prodPackExtService.getProdPackExt(organizeCode, partDb.getPartNo(), partDb.getPptCode());
        if (null == prodPackDb || StringUtils.isEmpty(prodPackDb.getPackLabelTemplate())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]关联的物料号[%s]未在产品包装关系中维护包装标签模板", workOrder.getOrderNo(), workOrder.getPartNo())
                    .build();
        }

        //进行弹框二次提示“包装数量为***，可产生N个包装条码，&&&“
        String msg = "";

        //获得工单类型
        MatchRuleCodeModel codeType = null;
        //余量
        double margin = 0;

        switch (MesPcnExtEnumUtil.WORK_ORDER_TYPE.getByValue(workOrder.getWorkOrderType())) {
            case ATTEMPT_ORDER:
            case STANDARD_ORDER:
                //生成包装条码的数量
                int count = 0;
                while (true) {
                    count++;
                    //工单数量
                    Double qty = workOrder.getQty();
                    //包装数量
                    Double qty2 = partDb.getQty2();

                    margin = MathOperation.sub(qty, qty2 * count);
                    int compareTo = MathOperation.compareTo(margin, new Double(0));
                    if (compareTo == 0) {
                        msg = "包装数量为" + qty + "，可产生" + count + "个包装条码，无尾箱数";
                        break;
                    } else if (compareTo == -1) {
                        //计算余量
                        margin = MathOperation.sub(qty, qty2 * (count - 1));
                        msg = "包装数量为" + qty + "，可产生" + count + "个包装条码，尾箱数为" + margin;
                        break;
                    }
                }

                codeType = new MatchRuleCodeModel(MesPcnExtEnumUtil.ENCODE_CODE_TYPE.PACK_SN.getValue(), count);
                break;
            default:
                break;
        }

        if (null == codeType) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]类型未匹配到条码类型,请检查工单类型是否有效", workOrder.getOrderNo())
                    .build();
        }

        return msg;
    }

    @Override
    public ListPager queryPackageByPager(MesPackageExt pack, Pager pager) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(pack.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(pack.getWorkOrderNo(), MesPcnExtConstWords.WORK_ORDER_NO, packBean);
        DdlPreparedPack.getStringEqualPack(pack.getPackageNo(), MesPcnExtConstWords.PACKAGENO, packBean);

        pager = PagerHelper.getPager(pager, packageExtRepository.findByHqlWhereCount(packBean));
        packBean.setOrderByStr(" order by packageNo asc ");
        return new ListPager(packageExtRepository.findByHqlWherePage(packBean, pager), pager);
    }

    @Override
    public List<Map<String, Object>> doWorkOrderPrintPackageNo(SxPrintTemplateModel model) {
        List<MesPackageExt> packageList;
        if (!StringUtils.isEmpty(model.getWorkOrderNo())) {
            MesWorkOrderExt workOrderExt = workOrderExtService.getWorkOrderExtByOrderNo(model.getOrganizeCode(), model.getWorkOrderNo());
            packageList = getPackageListByOrderNo(model, workOrderExt);
        } else {
            packageList = getPackageNoListByIdList(model);
        }
        if (CollectionUtils.isEmpty(packageList)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("暂无包装条码,不能打印")
                    .build();
        }

        MesPartExt partExt = partExtService.getPartExt(model.getOrganizeCode(), packageList.get(0).getPartNo());

        SxPrintTemplateModel printTemplateModel = packSxPackagePrintTemplateModel(model.getOrganizeCode(), packageList, packageList.get(0).getPackageLabelTemplate(), partExt, partExt.getPackNoPrintTimes() != null && partExt.getPackNoPrintTimes() > 1 ? partExt.getPackNoPrintTimes() : 1, MesPcnExtEnumUtil.PRINT_QUEUE_TYPE.PACK_SN.getValue());

        List<Map<String, Object>> resultMapList;
        try {
            resultMapList = printTemplateStrategyContext.getPrintTemplateService(printTemplateModel, SxPrintPackageSingleTemplateService.class);
        } catch (Exception e) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("模板错误,请检查模板配置;详细报错原因：%s",e.getMessage())
                    .build();
        }

        savePackagePrintStatus(packageList, model.getUserInfo());

        saveCellPrintRecordService(packageList, model, partExt.getPackNoPrintTimes() != null && partExt.getPackNoPrintTimes() > 0 ? partExt.getPackNoPrintTimes() : 1);

        return resultMapList;
    }

    private void saveCellPrintRecordService(List<MesPackageExt> packageList, SxPrintTemplateModel model, Integer packNoPrintTimes){
        for (int num = 0; num < packNoPrintTimes; num++) {
            MesWorkCellPrintRecord workCellPrintRecord = new MesWorkCellPrintRecord();
            workCellPrintRecord.setObjectCode("MesPackageExt");
            workCellPrintRecord.setObjectName("包装条码");
            workCellPrintRecord.setSourceModule("生产工单");
            workCellPrintRecord.setPrintCount(packageList.size());
            workCellPrintRecord.setWorkOrderNo(packageList.get(0).getWorkOrderNo());
            workCellPrintRecord.setWorkCenterCode(packageList.get(0).getWorkCenterCode());
            workCellPrintRecord.setPartNo(packageList.get(0).getPartNo());
            workCellPrintRecord.setPartNameRdd(packageList.get(0).getPartNameRdd());
            workCellPrintRecord.setTagType(MesPcnExtEnumUtil.PRINT_QUEUE_TYPE.PACK_SN.getValue());
            List<PrintRecordModel> printRecordModelList = new ArrayList<>();
            packageList.stream().filter(o -> null != o).forEach(o -> {
                printRecordModelList.add(new PrintRecordModel(o.getId(), o.getPackageNo()));
            });
            workCellPrintRecord.setPrintIds(JSONObject.toJSONString(printRecordModelList));
            workCellPrintRecord.setOrganizeCode(model.getOrganizeCode());
            ConvertBean.serviceModelInitialize(workCellPrintRecord, model.getUserInfo());
            workCellPrintRecordService.insertWorkCellPrintRecordNoRollback(workCellPrintRecord);
        }
    }

    @Override
    public List<MesPackageExt> getPackageListByOrderNo(SxPrintTemplateModel model, MesWorkOrderExt workOrderExt) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(model.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(workOrderExt.getOrderNo(), MesPcnExtConstWords.WORK_ORDER_NO, packBean);
        if (!StringUtils.isEmpty(model.getAscOrDesc()) && !StringUtils.isEmpty(model.getOrderByParam())) {
            DdlPreparedPack.getOrderByPack(new Object[]{model.getAscOrDesc()}, new String[]{model.getOrderByParam()}, packBean);
        }
        return packageExtRepository.findByHqlWhere(packBean);
    }

    @Override
    public List<MesPackageExt> getPackageNoListByIdList(SxPrintTemplateModel model) {
        List<MesPackageExt> packageList = null;
        if (!CollectionUtils.isEmpty(model.getIdList())) {
            for (Long id : model.getIdList()) {
                if (StringUtils.isEmpty(id)) {
                    continue;
                }
                MesPackageExt pack = packageExtRepository.getById(id);
                if (null != pack) {
                    if (CollectionUtils.isEmpty(packageList)) {
                        packageList = new ArrayList<>();
                    }
                    packageList.add(pack);
                }
            }
        }
        return packageList;
    }

    @Override
    public SxPrintTemplateModel packSxPackagePrintTemplateModel(String organizeCode, List<MesPackageExt> packageList, String templateCode, MesPartExt partExt, Integer packNoPrintTimes, Integer printType) {
        SxPrintTemplateModel printTemplateModel = new SxPrintTemplateModel();
        printTemplateModel.setOrganizeCode(organizeCode);
        printTemplateModel.setLabelTemplate(printTemplateDispatchService.getLabelTemplate(templateCode));
        printTemplateModel.setPart(partExt);
        List<PackageExtModel> packageExtModelList = new ArrayList<>();
        for (MesPackageExt pack : packageList) {
            if (null == pack) {
                continue;
            }

            for (int num = 0; num < packNoPrintTimes; num++) {
                PackageExtModel packageExtModel = new PackageExtModel();
                BeanUtils.copyProperties(pack, packageExtModel, MesPcnExtConstWords.ID);
                packageExtModelList.add(packageExtModel);
            }

        }
        printTemplateDispatchService.packTemplateModel(printTemplateModel, partExt.getPartNo(), MesPcnExtEnumUtil.PRINT_QUEUE_TYPE.PACK_SN.getValue(), organizeCode);

        printTemplateModel.setPackList(packageExtModelList);
        return printTemplateModel;
    }

    @Override
    public Boolean checkWorkOrderUnBindSnIsValid(String organizeCode ,String workOrderNo) {

        if(StringUtils.isEmpty(workOrderNo)){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("生产工单号输入空")
                    .build();
        }

        if(StringUtils.isEmpty(organizeCode)){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("工厂代码不能为空")
                    .build();
        }

        MesWorkOrderExt workOrderDb = workOrderExtService.getWorkOrderExtByOrderNo(organizeCode, workOrderNo);

        if(workOrderDb == null){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("工单号[%s]不存在",workOrderNo)
                    .build();
        }



        MesPartExt partDb = partExtService.getPartExt(organizeCode, workOrderDb.getPartNo());

        if(partDb == null){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("工单[%s]维护的物料[%s]不存在",workOrderNo,workOrderDb.getPartNo())
                    .build();
        }

        if(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue() == partDb.getIsCreateSn()){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("该工单下的条码不允许解绑")
                    .build();
        }

        MesProduceSnExt produceSnExt = new MesProduceSnExt();
        produceSnExt.setOrganizeCode(organizeCode);
        produceSnExt.setWorkOrderNo(workOrderNo);
//        queryProduceSnExtByPager(produceSnExt, Pager);

        return null;
    }

    @Override
    public ListPager<MesProduceSnExt> queryProduceSnList(String organizeCode ,String workOrderNo, Pager pager){
        MesWorkOrderExt workOrderDb = workOrderExtService.getWorkOrderExtByOrderNo(organizeCode, workOrderNo);

        if(workOrderDb == null){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("工单号[%s]不存在",workOrderNo)
                    .build();
        }

        if(workOrderDb.getWorkOrderType() == MesPcnExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue()){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("该工单为返工工单,不允许解绑")
                    .build();
        }

        MesPartExt partDb = partExtService.getPartExt(organizeCode, workOrderDb.getPartNo());

        if(partDb == null){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("工单[%s]维护的物料[%s]不存在",workOrderNo,workOrderDb.getPartNo())
                    .build();
        }

        if(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue() == partDb.getIsCreateSn()){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("该工单下的条码不允许解绑")
                    .build();
        }

        MesProduceSnExt produceSnExt = new MesProduceSnExt();
        produceSnExt.setOrganizeCode(organizeCode);
        produceSnExt.setWorkOrderNo(workOrderNo);
        return queryProduceSnExtOnlyCreateAndProcessByPager(produceSnExt, pager);
    }

    @Override
    public Boolean workOrderUnBindSn(String organizeCode, String modifyUser, String workOrderNo, String serialNumber, Boolean keyPiecesIsBindFlag) {

        if (StringUtils.isEmpty(serialNumber)){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("产品条码为空")
                    .build();
        }

        MesProduceSnExt produceSnExtDb = getProduceSnExtBySn(organizeCode, serialNumber);

        if(produceSnExtDb == null){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("该产品条码不存在")
                    .build();
        }

        MesWorkOrderExt workOrderExt = workOrderExtService.getWorkOrderExtByOrderNo(organizeCode, produceSnExtDb.getWorkOrderNo());
        if(workOrderExt == null){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("当前条码为无效条码")
                    .build();
        }

        if(!workOrderExt.getOrderNo().equals(workOrderNo)){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("当前条码关联工单[%]与当前工单[%s]不一致", workOrderExt.getOrderNo(), workOrderNo)
                    .build();
        }

        if(workOrderExt.getWorkOrderType() == MesPcnExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue()){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("该条码关联的工单为返工工单,不允许解绑")
                    .build();
        }

        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(serialNumber, MesPcnExtConstWords.SERIAL_NUMBER, packBean);
        List<MesProdBindRecordExt> prodBindRecordExtListDb = prodBindRecordExtRepository.findByHqlWhere(packBean);

        if(keyPiecesIsBindFlag == null){
            if(CollectionUtils.isEmpty(prodBindRecordExtListDb)){
                return false;
            }else{
                return true;
            }
        }else {
            if((!CollectionUtils.isEmpty(prodBindRecordExtListDb)) != keyPiecesIsBindFlag){
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                        .setErrorDetail("是否绑定关键件标志值与实际值不相符")
                        .build();
            }
        }

        Boolean failFlag = false;
        switch (MesPcnExtEnumUtil.PRODUCE_SN_STATUS.getByValue(produceSnExtDb.getSnStatus())){
            case CREATE:
                failFlag = true;break;
            case PROCESS:
                failFlag = true;break;
        }
        if(failFlag == false){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("当前条码状态为[%s],不允许解绑", MesPcnExtEnumUtil.PRODUCE_SN_STATUS.valueOfDescription(produceSnExtDb.getSnStatus()))
                    .build();
        }

        // 改变工单条码生成状态未  30-不生成
        workOrderExt.setSnCreateStatus(MesPcnExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.NO_CREATE.getValue());
        ConvertBean.serviceModelUpdate(workOrderExt, modifyUser);
        new ConvertBeanExt(workOrderExt).convertBean(workOrderExt);
        workOrderExtRepository.save(workOrderExt);

        produceSnExtDb.setIsValid(MesPcnExtEnumUtil.IS_VAILD.INVAILD.getValue());
        ConvertBean.serviceModelUpdate(produceSnExtDb, modifyUser);
        new ConvertBeanExt(produceSnExtDb).convertBean(produceSnExtDb);
        produceSnExtRepository.save(produceSnExtDb);
        for (MesProdBindRecordExt prodBindRecordExt : prodBindRecordExtListDb) {
            prodBindRecordExt.setActionType(MesPcnExtEnumUtil.MES_ACTION_TYPE.UNTYING.getValue());
            ConvertBean.serviceModelUpdate(prodBindRecordExt, modifyUser);
            new ConvertBeanExt(prodBindRecordExt).convertBean(prodBindRecordExt);
        }
        if(!CollectionUtils.isEmpty(prodBindRecordExtListDb)){
            prodBindRecordExtRepository.saveAll(prodBindRecordExtListDb);
        }

        MesProdUnbindRecord prodUnbindRecord = new MesProdUnbindRecord();
        BeanUtils.copyProperties(produceSnExtDb, prodUnbindRecord, MesPcnExtConstWords.ID);
        prodUnbindRecord.setPartName(produceSnExtDb.getPartNameRdd());
        ConvertBean.serviceModelInitialize(prodUnbindRecord, modifyUser);
        prodUnbindRecord.setOrganizeCode(organizeCode);
        prodUnbindRecord.setSystemSyncStatus(MesPcnExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
        prodUnbindRecordRepository.save(prodUnbindRecord);


        packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(serialNumber, MesPcnExtConstWords.SERIAL_NUMBER, packBean);
        MesPackageDetail packageDetailDb = packageDetailRepository.getByProperty(packBean);

        if(packageDetailDb != null){
            packageDetailDb.setIsValid(CommonEnumUtil.IS_VAILD.INVAILD.getValue());
            ConvertBean.serviceModelUpdate(packageDetailDb, modifyUser);
            packageDetailRepository.save(packageDetailDb);
        }

        packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(packageDetailDb.getPackageNo(), MesPcnExtConstWords.PACKAGENO, packBean);
        MesPackageExt packageExtDb = packageExtRepository.getByProperty(packBean);

        if(packageExtDb != null){
            packageExtDb.setIsValid(CommonEnumUtil.IS_VAILD.INVAILD.getValue());
            ConvertBean.serviceModelUpdate(packageExtDb, modifyUser);
            packageExtDb.setModifyDatetimeExt(packageExtDb.getModifyDatetime());
            new ConvertBeanExt(packageExtDb).convertBean(packageExtDb);
            packageExtRepository.save(packageExtDb);
        }

        packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(produceSnExtDb.getSerialNumber(), MesPcnExtConstWords.SERIAL_NUMBER, packBean);
        List<MesProduceSnTravelExt> produceSnTravelExts = produceSnTravelExtRepository.findByHqlWhere(packBean);

        if(!CollectionUtils.isEmpty(produceSnTravelExts)){
            produceSnTravelExts.stream().forEach(mesProduceSnTravelExt -> {
                mesProduceSnTravelExt.setIsValid(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue());
                ConvertBean.serviceModelUpdate(mesProduceSnTravelExt, modifyUser);
                new ConvertBeanExt(mesProduceSnTravelExt).convertBean(mesProduceSnTravelExt);
            });
            produceSnTravelExtRepository.saveAll(produceSnTravelExts);
        }

        if(workOrderExt.getSnCreateStatus() != MesPcnExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.NO_CREATE.getValue()){
            workOrderExtService.saveSnCreateStatus(workOrderExt, modifyUser, MesPcnExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.NO_CREATE.getValue());
        }

        return null;
    }

    @Override
    public ListPager<MesProduceSnExt> queryProduceSnExtOnlyCreateAndProcessByPager(MesProduceSnExt produceSnExt, Pager pager) {
        List<Integer> snStatus = Stream.of(MesPcnExtEnumUtil.PRODUCE_SN_STATUS.CREATE.getValue(), MesPcnExtEnumUtil.PRODUCE_SN_STATUS.PROCESS.getValue()).collect(Collectors.toList());
        DdlPackBean hqlPack = MesPcnExtHqlPack.getProduceSnExtOnlyCreateAndProcess(produceSnExt,snStatus);
        pager = PagerHelper.getPager(pager, produceSnExtRepository.findByHqlWhereCount(hqlPack));
        hqlPack.setOrderByStr(" order by serialNumber asc ");
        return new ListPager(produceSnExtRepository.findByHqlWherePage(hqlPack, pager), pager);
    }

    @Override
    public MesProduceSnExt getInvalidProduceSnExtBySn(String organizeCode, String serialNumber) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(serialNumber)) {
            return null;
        }
        return produceSnExtRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.SERIAL_NUMBER},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.INVAILD.getValue(), serialNumber});
    }

    @Override
    public MesProduceSnExt insertProduceSnExt(MesProduceSnExt produceSnExt) {
        return produceSnExtRepository.save(produceSnExt);
    }

    public List<MesPackageExt> getPackageListByOrderNo(String organizeCode, String workOrderNo) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workOrderNo)) {
            return null;
        }
        return packageExtRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_ORDER_NO},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workOrderNo});
    }

}
