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

import cn.estsh.i3plus.ext.mes.pcn.api.base.INumberRuleExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.IPartExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.ISxWorkOrderExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.*;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.bu.bu3.IMesOuterPackageService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.dao.bu3.IOuterPackageDao;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.print.strategy.*;
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.model.bu.QualityAssureIndiaModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.bu3.InnerPackageModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.MesOuterPackageDetailRepository;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.MesOuterPackageRepository;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.MesPackageExtRepository;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.MesPrinterCfgRepository;
import cn.estsh.i3plus.ext.mes.pcn.pojo.sqlpack.MesPcnExtHqlPack;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtEnumUtil;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
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.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.List;
import java.util.Map;
import java.util.stream.Collectors;

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

    @Autowired
    private IProduceSnExtService produceSnExtService;

    @Autowired
    private ISxWorkOrderExtService workOrderExtService;

    @Autowired
    private SxPrintTemplateStrategyContext printTemplateStrategyContext;

    @Autowired
    private MesPackageExtRepository packageExtRepository;

    @Autowired
    private IPartExtService partExtService;

    @Autowired
    private SxPrintTemplateDispatchService printTemplateDispatchService;

    @Autowired
    private MesPrinterCfgRepository printerCfgRepository;

    @Autowired
    private IPackageExtService packageExtService;

    @Autowired
    private IWorkCellPrintRecordService workCellPrintRecordService;

    @Autowired
    private IProductEncodeCfgExtService productEncodeCfgExtService;

    @Autowired
    private INumberRuleExtService numberRuleExtService;

    @Autowired
    private MesOuterPackageRepository outerPackageRepository;

    @Autowired
    private IMesOuterPackageService outerPackageService;

    @Autowired
    private MesOuterPackageDetailRepository outerPackageDetailRepository;

    @Autowired
    private IOuterPackageDao outerPackageDao;

    @Override
    public List<MesPrinterCfg> queryPrinterCfgList(String organizeCode) {
        return printerCfgRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue()});
    }

    @Override
    public ListPager queryPatchProdSnByPager(MesProduceSnExt produceSnExt, Pager pager) {
        if (StringUtils.isEmpty(produceSnExt.getWorkOrderNo()) && StringUtils.isEmpty(produceSnExt.getSerialNumber())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("请选择工单或输入产品条码")
                    .build();
        }
        return produceSnExtService.queryProduceSnExtByPager(produceSnExt, pager);
    }

    @Override
    public List<Map<String, Object>> doPatchPrintProdSn(SxPrintTemplateModel model) {
        List<MesProduceSnExt> produceSnExtList;
        if (!StringUtils.isEmpty(model.getWorkOrderNo())) {
            MesWorkOrderExt workOrderExt = workOrderExtService.getWorkOrderExtByOrderNo(model.getOrganizeCode(), model.getWorkOrderNo());
            produceSnExtList = produceSnExtService.getSnListByOrderNo(model, workOrderExt);
        } else {
            produceSnExtList = produceSnExtService.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 = produceSnExtService.packSxPrintTemplateModel(model.getOrganizeCode(), produceSnExtList, produceSnExtList.get(0).getProcessLabelTemplate(), partExt, order,1, MesPcnExtEnumUtil.PRINT_QUEUE_TYPE.PROD_SN.getValue());

        List<Map<String, Object>> resultMapList;
        try {
            resultMapList = printTemplateStrategyContext.getPrintTemplateService(printTemplateModel, SxPrintSnSingleTemplateService.class);
        } catch (Exception e) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("模板错误,请检查模板配置")
                    .build();
        }
        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);

        return resultMapList;
    }

    @Override
    public List<Map<String, Object>> doPatchPrintQualityAssure(SxPrintTemplateModel model) {
        List<MesProduceSnExt> produceSnExtList = produceSnExtService.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 = produceSnExtService.packSxPrintTemplateModel(model.getOrganizeCode(), produceSnExtList, produceSnExtList.get(0).getQualityAssureTemplate(), partExt, order, 1, MesPcnExtEnumUtil.PRINT_QUEUE_TYPE.QUALITY_ASSURE.getValue());

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

        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.QUALITY_ASSURE.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);

        return resultMapList;
    }

    @Override
    public List<Map<String, Object>> doPatchPrintBigProcess(SxPrintTemplateModel model) {
        List<MesProduceSnExt> produceSnExtList = produceSnExtService.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());

        if(partExt == null){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("工单关联的物料不存在")
                    .build();
        }

        if(bigProcessPrintCheck(model.getOrganizeCode(), partExt.getPartNo()) == false){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("该条码未维护大本体条码匹配类型，不需要进行打印")
                    .build();
        }

        SxPrintTemplateModel printTemplateModel = produceSnExtService.packSxPrintTemplateModel(model.getOrganizeCode(), produceSnExtList, produceSnExtList.get(0).getBigProcessLabelTemplate(), partExt, order, 1, MesPcnExtEnumUtil.PRINT_QUEUE_TYPE.BIG_PROCESS.getValue());

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

        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.BIG_PROCESS.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);

        return resultMapList;
    }

    @Override
    public ListPager queryPatchPackSnByPager(MesPackageExt pack, Pager pager) {
        if (!StringUtils.isEmpty(pack.getSerialNumber())) {
            MesPackageDetail packageDetail = packageExtService.getPackageDetailBySn(pack.getOrganizeCode(), pack.getSerialNumber());
            if (null == packageDetail) {
                pager = PagerHelper.getPager(pager, 0);
                return new ListPager(new ArrayList(), pager);
            }
            if (StringUtils.isEmpty(pack.getWorkOrderNo()) && StringUtils.isEmpty(pack.getPackageNo())) {
                MesPackageExt packageExt = packageExtService.getPackageByPackNo(pack.getOrganizeCode(), packageDetail.getPackageNo());
                if (null == packageExt) {
                    pager = PagerHelper.getPager(pager, 0);
                    return new ListPager(new ArrayList(), pager);
                }
                List<MesPackageExt> packageExtList = new ArrayList<>();
                packageExtList.add(packageExt);
                pager = PagerHelper.getPager(pager, 1);
                return new ListPager(packageExtList, pager);
            } else {
                DdlPackBean hqlPack = MesPcnExtHqlPack.getPackageExt(pack);
                pager = PagerHelper.getPager(pager, packageExtRepository.findByHqlWhereCount(hqlPack));
                hqlPack.setOrderByStr(" order by modifyDatetime desc ");
                List<MesPackageExt> packageExtList = packageExtRepository.findByHqlWherePage(hqlPack, pager);
                MesPackageDetail finalPackageDetail = packageDetail;
                packageExtList = CollectionUtils.isEmpty(packageExtList) ? new ArrayList<>() :
                        packageExtList.stream().filter(o -> (null != o && o.getPackageNo().equals(finalPackageDetail.getPackageNo()))).collect(Collectors.toList());
                pager = PagerHelper.getPager(pager, packageExtList.size());
                return new ListPager(packageExtList, pager);
            }
        } else {
            DdlPackBean hqlPack = MesPcnExtHqlPack.getPackageExt(pack);
            pager = PagerHelper.getPager(pager, packageExtRepository.findByHqlWhereCount(hqlPack));
            hqlPack.setOrderByStr(" order by modifyDatetime desc ");
            List<MesPackageExt> packageExtList = packageExtRepository.findByHqlWherePage(hqlPack, pager);
            return new ListPager(packageExtList, pager);
        }
    }

    @Override
    public List<Map<String, Object>> doPatchPrintPackSn(SxPrintTemplateModel model) {
        List<MesPackageExt> packageList = getPackageListByIdList(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();
        }

        SxPrintTemplateModel printTemplateModel = packSxPrintTemplateModel(model.getOrganizeCode(), packageList, 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("模板错误,请检查模板配置")
                    .build();
        }

        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);

        return resultMapList;
    }

    @Override
    public List<Map<String, Object>> doPatchPrintQualityAssureIndia(QualityAssureIndiaModel model) {

        if (model.getIndiaModel().getSnStartNum().length() < 8 || model.getIndiaModel().getSnEndNum().length() < 8){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("起始值和结束值长度错误")
                    .build();
        }

        String snStartNum = model.getIndiaModel().getSnStartNum();
        String snEndNum = model.getIndiaModel().getSnEndNum();
        String prodSn = model.getIndiaModel().getProdSn();
        String snStartNumnum = snStartNum.substring(snStartNum.length()-8,snStartNum.length());
        String snEndNumnum = snEndNum.substring(snEndNum.length()-8,snEndNum.length());
        Integer startToEndNum = Integer.parseInt(snEndNumnum) - Integer.parseInt(snStartNumnum) + 1;

        //获取条码
        /*DdlPackBean packBeanSn = MesPcnHqlPack.getAllBaseData(model.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(prodSn, "serialNumber", packBeanSn);
        MesProduceSnExt produceSn = produceSnExtRepository.getByProperty(packBeanSn);*/

        MesProduceSnExt produceSn = produceSnExtService.getProduceSnExtBySn(model.getOrganizeCode(), prodSn);

        MesPartExt partExt = partExtService.getPartExt(model.getOrganizeCode(), produceSn.getPartNo());

        //通过物料获取编码规则
        String ruleCode = productEncodeCfgExtService.getRuleCodeByMatchType(model.getOrganizeCode(), 10, partExt, produceSn.getWorkCenterCode());
        MesNumberRuleExt numberRuleExt = numberRuleExtService.getNumberRuleExtByRuleCode(model.getOrganizeCode(), ruleCode);

        //编码规则
        String numberRule = numberRuleExt.getNumberRule();
        String ruleLengthSpilt = numberRuleExt.getRuleLengthSpilt();
        numberRule = numberRule.substring(1,numberRule.length()-1);
        String[] numberRuleSplit = numberRule.split("}\\{");

        String[] ruleLengthSpiltSpilt = ruleLengthSpilt.split(",");

        Integer snNumLength = 0;
        for (int i = 0; i < numberRuleSplit.length; i++) {
            if (numberRuleSplit[i].equals("serialno") || numberRuleSplit[i].equals("SERIALNO")){
                snNumLength = Integer.valueOf(ruleLengthSpiltSpilt[i]);
            }
        }

        if (prodSn.length() < snNumLength){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("条码长度错误")
                    .build();
        }

        //条码流水号
        String snNumNum = prodSn.substring(prodSn.length()-snNumLength,prodSn.length());
        String snNumQian = prodSn.substring(0,prodSn.length()-snNumLength);

        Integer snNumLengthEnd = Integer.parseInt(snNumNum)+startToEndNum - 1;

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

        String snNumEnd = snNumQian+zero+snNumLengthEnd.toString();

        //是否能查询到最后一个条码
        MesProduceSnExt produceSnEnd = produceSnExtService.getProduceSnExtBySn(model.getOrganizeCode(), snNumEnd);
        if (null == produceSnEnd){
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("请检查起始值和结束值是否对应条码数量"+"起始值：【"+snStartNum+"】结束值：【"+snEndNum+"】条码：【"+prodSn+"】最后一个条码：【"+snNumEnd+"】工厂代码：【"+model.getOrganizeCode()+"】")
                    .build();
        }

        //质保书前缀
        String startNumQian = snStartNum.substring(0,snStartNum.length()-8);

        ArrayList<ProduceSnExtModel> snList = new ArrayList<>();
        //List<String> snList = new ArrayList();
        //List<String> codeList = new ArrayList();
        for (int i = 0; i < startToEndNum; i++) {
            ProduceSnExtModel prodSnModel = new ProduceSnExtModel();
            Integer snNum = Integer.parseInt(snNumNum) + i;
            StringBuilder zero1 = new StringBuilder();
            if (snNum.toString().length() < snNumLength){
                for (int j = 0; j < snNumLength - snNum.toString().length(); j++) {
                    zero1.append("0");
                }
            }
            prodSnModel.setSerialNumber(snNumQian + zero1 + snNum.toString());
            //查询条码
            MesProduceSnExt produceSnExtBySn = produceSnExtService.getProduceSnExtBySn(model.getOrganizeCode(), snNumQian + zero1 + snNum.toString());
            prodSnModel.setQualityAssureTemplate(produceSnExtBySn.getQualityAssureTemplate());
            //snList.add(snNumQian + zero1 + snNum.toString());

            Integer codeNum = Integer.parseInt(snStartNumnum) +i;
            StringBuilder zero2 = new StringBuilder();
            if (codeNum.toString().length() < 8){
                for (int j = 0; j < 8 - codeNum.toString().length(); j++) {
                    zero2.append("0");
                }
            }
            prodSnModel.setQualityAssureCode(startNumQian + zero2 + codeNum.toString());
            snList.add(prodSnModel);
            //codeList.add(startNumQian + zero2 + codeNum.toString());
        }

        /*List<MesProduceSnExt> produceSnExtList = produceSnExtService.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();
        }*/

        //SxPrintTemplateModel printTemplateModel = produceSnExtService.packSxPrintTemplateModel(model.getOrganizeCode(), produceSnExtList, produceSnExtList.get(0).getQualityAssureTemplate(), partExt, 1);
        SxPrintTemplateModel printTemplateModel = new SxPrintTemplateModel();
        printTemplateModel.setOrganizeCode(model.getOrganizeCode());
        printTemplateModel.setLabelTemplate(printTemplateDispatchService.getLabelTemplate(produceSn.getQualityAssureTemplate()));
        printTemplateModel.setPart(partExt);

        ProduceSnExtModel produceSnExtModel = new ProduceSnExtModel();
        BeanUtils.copyProperties(produceSn,produceSnExtModel);
        printTemplateModel.setSn(produceSnExtModel);
        printTemplateModel.setSnList(snList);

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

        /*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.QUALITY_ASSURE.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);*/

        return resultMapList;
    }

    @Override
    public List<Map<String, Object>> doPatchPrintBigPackSn(SxPrintTemplateModel model) {
        List<MesOuterPackage> bigPackageList = getBigPackageListByIdList(model);
        if (CollectionUtils.isEmpty(bigPackageList)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("暂无条码,不能补打")
                    .build();
        }

        SxPrintTemplateModel printTemplateModel = packBigPackSxPrintTemplateModel(model.getOrganizeCode(), bigPackageList, MesPcnExtEnumUtil.PRINT_QUEUE_TYPE.BIG_PACK_SN.getValue());

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

        MesWorkCellPrintRecord workCellPrintRecord = new MesWorkCellPrintRecord();
        workCellPrintRecord.setObjectCode("MesOuterPackage");
        workCellPrintRecord.setObjectName("大包装条码");
        workCellPrintRecord.setSourceModule("松下补打");
        workCellPrintRecord.setPrintCount(bigPackageList.size());
        workCellPrintRecord.setWorkOrderNo(bigPackageList.get(0).getWorkOrderNo());
        workCellPrintRecord.setWorkCenterCode(bigPackageList.get(0).getWorkCenterCode());
        workCellPrintRecord.setPartNo(bigPackageList.get(0).getPartNo());
        workCellPrintRecord.setPartNameRdd(bigPackageList.get(0).getPartNameRdd());
        workCellPrintRecord.setTagType(MesPcnExtEnumUtil.PRINT_QUEUE_TYPE.BIG_PACK_SN.getValue());
        List<PrintRecordModel> printRecordModelList = new ArrayList<>();
        bigPackageList.stream().filter(o -> null != o).forEach(o -> {
            printRecordModelList.add(new PrintRecordModel(o.getId(), o.getOuterPackageNo()));
        });
        workCellPrintRecord.setPrintIds(JSONObject.toJSONString(printRecordModelList));
        workCellPrintRecord.setOrganizeCode(model.getOrganizeCode());
        ConvertBean.serviceModelInitialize(workCellPrintRecord, model.getUserInfo());
        workCellPrintRecordService.insertWorkCellPrintRecordNoRollback(workCellPrintRecord);

        return resultMapList;
    }

    @Override
    public ListPager queryPatchBigPackSnByPager(MesOuterPackageDetail outerPackageDetail, Pager pager) {
        if (!StringUtils.isEmpty(outerPackageDetail.getInnerPackageNo())) {
            MesOuterPackageDetail outerPackageDetailDb = outerPackageService.getBindingOutPackageDetailByInnerSn(outerPackageDetail.getOrganizeCode(), outerPackageDetail.getInnerPackageNo());
            if (null == outerPackageDetailDb) {
                pager = PagerHelper.getPager(pager, 0);
                return new ListPager(new ArrayList(), pager);
            }
            if (StringUtils.isEmpty(outerPackageDetail.getWorkOrderNo()) && StringUtils.isEmpty(outerPackageDetail.getOuterPackageNo())) {
                MesOuterPackage outerPackage = outerPackageService.getOutPackageBySn(outerPackageDetail.getOrganizeCode(), outerPackageDetailDb.getOuterPackageNo());
                if (null == outerPackage) {
                    pager = PagerHelper.getPager(pager, 0);
                    return new ListPager(new ArrayList(), pager);
                }
                List<MesOuterPackage> outerPackagesList = new ArrayList<>();
                outerPackagesList.add(outerPackage);
                packMesOuterPackage(outerPackageDetail, outerPackagesList);
                pager = PagerHelper.getPager(pager, 1);
                return new ListPager(outerPackagesList, pager);
            } else {
                DdlPackBean hqlPack = MesPcnExtHqlPack.getOutPackage(outerPackageDetail);
                pager = PagerHelper.getPager(pager, outerPackageRepository.findByHqlWhereCount(hqlPack));
                hqlPack.setOrderByStr(" order by modifyDatetime desc ");
                List<MesOuterPackage> outPackageList = outerPackageRepository.findByHqlWherePage(hqlPack, pager);
                MesOuterPackageDetail finalPackageDetail = outerPackageDetailDb;
                outPackageList = CollectionUtils.isEmpty(outPackageList) ? new ArrayList<>() :
                        outPackageList.stream().filter(o -> (null != o && o.getOuterPackageNo().equals(finalPackageDetail.getOuterPackageNo()))).collect(Collectors.toList());

                packMesOuterPackage(outerPackageDetail, outPackageList);

                pager = PagerHelper.getPager(pager, outPackageList.size());
                return new ListPager(outPackageList, pager);
            }
        } else {
            DdlPackBean hqlPack = MesPcnExtHqlPack.getOutPackage(outerPackageDetail);
            pager = PagerHelper.getPager(pager, outerPackageRepository.findByHqlWhereCount(hqlPack));
            hqlPack.setOrderByStr(" order by modifyDatetime desc ");
            List<MesOuterPackage> outPackageList = outerPackageRepository.findByHqlWherePage(hqlPack, pager);
            packMesOuterPackage(outerPackageDetail, outPackageList);
            return new ListPager(outPackageList, pager);
        }
    }

    private void packMesOuterPackage(MesOuterPackageDetail outerPackageDetail, List<MesOuterPackage> outPackageList) {
        if (!CollectionUtils.isEmpty(outPackageList)) {
            List<String> outerPackageNoList = outPackageList.stream().map(MesOuterPackage::getOuterPackageNo).collect(Collectors.toList());
            Map<String, List<MesOuterPackageDetail>> outerPackageDetailMap = getOuterPackageDetailMap(outerPackageNoList, outerPackageDetail.organizeCode);
            if (!CollectionUtils.isEmpty(outerPackageDetailMap)) {
                outPackageList.stream().forEach(outerPackage -> {
                    if (outerPackageDetailMap.containsKey(outerPackage.getOuterPackageNo())) {
                        List<String> innerPackageNoList = outerPackageDetailMap.get(outerPackage.getOuterPackageNo()).stream().map(MesOuterPackageDetail::getInnerPackageNo).collect(Collectors.toList());
                        StringBuffer innerOuterPackageNos = new StringBuffer();
                        innerPackageNoList.stream().forEach(innerPackageNo -> {
                            innerOuterPackageNos.append(innerPackageNo);
                            innerOuterPackageNos.append(MesPcnExtConstWords.COMMA);
                        });
                        innerOuterPackageNos.deleteCharAt(innerOuterPackageNos.length() - 1);
                        outerPackage.setInnerPackageNo(innerOuterPackageNos.toString());
                    }
                });
            }
        }
    }

    private Map<String, List<MesOuterPackageDetail>> getOuterPackageDetailMap(List<String> outerPackageNoList, String organizeCode){
        List<MesOuterPackageDetail> mesOuterPackageDetails = queryOuterPackageDetailByNoList(outerPackageNoList, organizeCode);
        return CollectionUtils.isEmpty(mesOuterPackageDetails) ? null : mesOuterPackageDetails.stream().collect(Collectors.groupingBy(MesOuterPackageDetail::getOuterPackageNo));
    }

    private List<MesOuterPackageDetail> queryOuterPackageDetailByNoList(List<String> outerPackageNoList, String organizeCode){
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackList(outerPackageNoList, MesPcnExtConstWords.OUTER_PACKAGE_NO, packBean);
        DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.PACKAGE_BIND_STATUS.BINGDING.getValue(), MesPcnExtConstWords.BIND_STATUS, packBean);
        return outerPackageDetailRepository.findByHqlWhere(packBean);
    }

    @Override
    public List<InnerPackageModel> queryPatchPackSnByOuterPackNo(MesOuterPackageDetail outerPackageDetail) {
        return outerPackageDao.getPackageListByOuterPackageNo(outerPackageDetail.getOrganizeCode(), outerPackageDetail.getOuterPackageNo());
    }


    private List<MesPackageExt> getPackageListByIdList(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;
    }

    private List<MesOuterPackage> getBigPackageListByIdList(SxPrintTemplateModel model) {
        List<MesOuterPackage> bigPackageList = null;
        if (!CollectionUtils.isEmpty(model.getIdList())) {
            for (Long id : model.getIdList()) {
                if (StringUtils.isEmpty(id)) {
                    continue;
                }
                MesOuterPackage bigPack = outerPackageRepository.getById(id);
                if (null != bigPack) {
                    if (CollectionUtils.isEmpty(bigPackageList)) {
                        bigPackageList = new ArrayList<>();
                    }
                    bigPackageList.add(bigPack);
                }
            }
        }
        return bigPackageList;
    }

    public SxPrintTemplateModel packSxPrintTemplateModel(String organizeCode, List<MesPackageExt> packageList, Integer printType) {
        SxPrintTemplateModel printTemplateModel = new SxPrintTemplateModel();
        printTemplateModel.setOrganizeCode(organizeCode);
        printTemplateModel.setLabelTemplate(printTemplateDispatchService.getLabelTemplate(packageList.get(0).getPackageLabelTemplate()));
        printTemplateModel.setPart(partExtService.getPartExt(organizeCode, packageList.get(0).getPartNo()));
        List<PackageExtModel> packList = new ArrayList<>();
        for (MesPackageExt packDb : packageList) {
            if (null == packDb) {
                continue;
            }
            PackageExtModel pack = new PackageExtModel();
            BeanUtils.copyProperties(packDb, pack, MesPcnExtConstWords.ID);
            packList.add(pack);
        }
        printTemplateModel.setPackList(packList);

        printTemplateDispatchService.packTemplateModel(printTemplateModel, printTemplateModel.getPart().getPartNo(), printType, organizeCode);

        return printTemplateModel;
    }

    public SxPrintTemplateModel packBigPackSxPrintTemplateModel(String organizeCode, List<MesOuterPackage> bigPackageList, Integer printType) {
        SxPrintTemplateModel printTemplateModel = new SxPrintTemplateModel();
        printTemplateModel.setOrganizeCode(organizeCode);
        printTemplateModel.setLabelTemplate(printTemplateDispatchService.getLabelTemplate(bigPackageList.get(0).getPackageLabelTemplate()));
        printTemplateModel.setPart(partExtService.getPartExt(organizeCode, bigPackageList.get(0).getPartNo()));
        List<BigOuterPackageModel> packList = new ArrayList<>();
        for (MesOuterPackage packDb : bigPackageList) {
            if (null == packDb) {
                continue;
            }
            BigOuterPackageModel pack = new BigOuterPackageModel();
            BeanUtils.copyProperties(packDb, pack, MesPcnExtConstWords.ID);
            packList.add(pack);
        }
        printTemplateModel.setBigOuterPackageList(packList);

        printTemplateDispatchService.packTemplateModel(printTemplateModel, printTemplateModel.getPart().getPartNo(), printType, organizeCode);

        return printTemplateModel;
    }

    private Boolean bigProcessPrintCheck(String organizeCode, String partNo){
        MesPartExt partExt = partExtService.getPartExt(organizeCode, partNo);
        if(partExt.getBigProcessMatchType() == null || partExt.getBigProcessMatchType() == 0){
            return false;
        }else{
            return true;
        }
    }

}
