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

import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesEquipmentExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesPartService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.*;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.aspect.MonitorLog;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.shippingscan.IMesShippingScanStrategyService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.util.MesPcnException;
import cn.estsh.i3plus.ext.mes.pcn.pojo.constant.MesCommonConstant;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesSortShippingCheckModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesSortShippingModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.base.util.StringUtil;
import cn.estsh.i3plus.pojo.mes.bean.*;
import cn.estsh.i3plus.pojo.mes.bean.shipping.*;
import cn.estsh.i3plus.pojo.mes.model.MesEquipVariableRwResult;
import cn.estsh.i3plus.pojo.mes.repository.*;
import cn.estsh.i3plus.pojo.mes.repository.edi.cd.MesCimVolvoJisRackIdDetailRepository;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import cn.estsh.impp.framework.boot.exception.ImppBusiException;
import cn.estsh.impp.framework.boot.util.SpringContextsUtil;
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.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Description :宁德二次发运校验
 * @Reference :
 * @Author :
 * @CreateDate : 2024-04-26 15:38
 * @Modify:
 **/
@Service
@Slf4j
public class MesNingDeShippingCheckService implements IMesNingDeShippingCheckService {

    @Autowired
    private MesShippingOrderManagementRepository shippingOrderManagementRepository;

    @Autowired
    private MesShippingOrderManagementDetailRepository shippingOrderManagementDetailRepository;

    @Autowired
    private MesProduceSnRepository produceSnRepository;

    @Autowired
    private MesLoadingListRepository listRepository;

    @Autowired
    private MesLoadingListDetailRepository listDetailRepository;

    @Autowired
    private MesJisShippingRepository jisShippingRepository;

    @Autowired
    private IMesJisShippingService jisShippingService;
    @Autowired
    private MesLoadingListDetailRepository vehiclesOrderDetailRepository;

    @Autowired
    private MesLoadingListRepository vehiclesOrderRepository;

    @Autowired
    private MesPartShippingGroupService mesPartShippingGroupService;

    @Autowired
    private MesBallTrackRuleRepository mesBallTrackRuleRepository;

    @Autowired
    private IMesWorkOrderExtService mesWorkOrderExtService;

    @Autowired
    private IMesEquipmentExtService mesEquipmentExtService;

    @Autowired
    private IMesEquipVariableRwExtService equipVariableRwExtService;

    @Autowired
    private IMesEmergencyLocationService mesEmergencyLocationService;

    @Autowired
    private IMesShippingSnUniqueService mesShippingSnUniqueService;

    @Autowired
    private MesShippingSnUniqueRepository mesShippingSnUniqueRepository;

    @Autowired
    private IMesWorkOrderService mesWorkOrderService;

    @Autowired
    private IMesMoveRuleService mesMoveRuleService;

    @Autowired
    private IMesPartService mesPartService;

    @Autowired
    private IMesProductionRecordService mesProductionRecordService;

    @Autowired
    private IMesProduceSnExtService mesProduceSnExtService;

    @Autowired
    private MesMoveRepository moveRepository;

    @Autowired
    private MesShippingQueueRepository shippingQueueRDao;

    @Autowired
    private IMesConfigService mesConfigService;

    @Autowired
    private MesVolvoRackRepository mesVolvoRackRDao;

    @Autowired
    private MesCustSoftInfoRepository custSoftInfoRDao;

    @Autowired
    private MesCimVolvoJisRackIdDetailRepository rackIdDetailRDao;

    @Autowired
    private IMesLoadingGroupRepository mesLoadingGroupRDao;

    @Override
    public MesSortShippingCheckModel doShippingOrderNoQuery(MesShippingOrderManagement shippingOrderManagement) {
        //返回数据组装
        MesSortShippingCheckModel model = new MesSortShippingCheckModel();
        //校验发运单
        MesShippingOrderManagement orderManagement = getMesShippingOrderManagement(shippingOrderManagement, shippingOrderManagement.getShippingGroupCode());
        if(Objects.isNull(orderManagement)){
            model.setMsg(String.format("发运单【%s】已跳过，请扫描下一个发运单",shippingOrderManagement.getShippingCode()));
            return model;
        }
        MesPartShippingGroup partShippingGroup = getMesPartShippingGroup(orderManagement.getOrganizeCode(),orderManagement.getShippingGroupCode());
        //校验发运单扫描顺序
        checkShippingOrderSeq(shippingOrderManagement, orderManagement);
        //根据扫描的发运单找到是否装车配置，若是，则根据发运单查询是否生成装车单，若没生成装车单则提示此发运单配置是否装车为是,但没生成装车单，请检查数据！
//        checkLoadingList(shippingOrderManagement, orderManagement, partShippingGroup);
        if (!StringUtils.isEmpty(orderManagement.getCheckSeqCode())) {
            model.setIsScanLocationCode(true);
        }
        //发运单号
        model.setShippingCode(orderManagement.getShippingCode());
        //零件发运组
        model.setMesPartShippingGroup(partShippingGroup);
        //发运单明细
        model.setDetailList(getMesShippingOrderManagementDetails(orderManagement,model.getMesPartShippingGroup()));
        //最近扫描完成的发运单号
        MesShippingOrderManagement lastShippingOrder = getLastShippingOrder(orderManagement.getOrganizeCode());
        if (!Objects.isNull(lastShippingOrder)) {
            model.setRecentlyScanShippingCode(lastShippingOrder.getShippingCode());
        }
        model.setMsg(String.format("发运单【%s】扫描成功，请扫描条码",model.getShippingCode()));
        return model;
    }

    @Override
    public MesSortShippingCheckModel saveSn(MesSortShippingCheckModel model) {
        //校验发运单是否存在
        MesShippingOrderManagement orderManagement = checkMesShippingOrderManagement(model);
        //零件发运组
        MesPartShippingGroup shippingGroup = Objects.isNull(model.getMesPartShippingGroup()) ? getMesPartShippingGroup(orderManagement.getOrganizeCode(), orderManagement.getShippingGroupCode()) : model.getMesPartShippingGroup();
        //扫描强过码
        model.setMesPartShippingGroup(shippingGroup);
        if (!Objects.isNull(model.getIsPass()) && Objects.equals(MesPcnExtConstWords.ONE, model.getIsPass())) {
            skipShippingDetails(model, model.getUserInfo(), orderManagement);
            //扫描条码
        } else if (!Objects.isNull(model.getIsPass()) && Objects.equals(MesPcnExtConstWords.THREE, model.getIsPass())) {
            forcePassShippingDetails(model, model.getUserInfo(), orderManagement);
            //扫描条码
        } else {
            /**
             * 修复bug 44253 by castle 同Pisces，零件发运组/发运组明细可以实现“前道工艺”校验
             * 逻辑：
             *
             * 1.查询零件发运组
             *
             * 2.查询对应零件发运组详情
             *
             * 3.根据条码查询有没有在条码表中，用于判断是自制件，有则为自制件
             *
             * 4.自制件需要查看明细是否维护了 前道工艺，如果维护了则需要校验前道工艺有没有加工记录；如果明细没有维护，则找零件发运组是否维护了，维护则需要校验；两者都没有维护,则不需要校验
             *
             * 5.外协件不需要校验前道工艺
             */
            if(!checkFrontProcess(model, shippingGroup)){
                MesPcnException.throwMesBusiException("条码【%s】前道校验未通过，请检查数据",model.getSn());
            }
            if (StringUtils.isEmpty(shippingGroup.getConfirmPartType())) {
                MesPcnException.throwMesBusiException("零件发运组【%s】扫描确认方式未维护，请检查数据！");
            }
            model = ((IMesShippingScanStrategyService) SpringContextsUtil.getBean(MesExtEnumUtil.SHIPPING_GROUP_CONFIRM_PART_TYPE.valueOfServiceImpl(Integer.parseInt(shippingGroup.getConfirmPartType())))).doScan(model, orderManagement, shippingGroup);
        }
        model.setDetailList(model.getDetailList());
        //当前发运单全部扫描完成 并且不需要扫位置码
        if (model.getIsScanCount() == model.getDetailList().size() && StringUtils.isEmpty(orderManagement.getCheckSeqCode())) {
            //保存数据库
            saveDate(orderManagement, model, model.getOrganizeCode(), model.getUserInfo());
            model.setMsg(String.format("发运单【%s】已发运完成，请扫描下一个发运单",model.getShippingCode()));
        }
        return model;
    }

    private boolean checkFrontProcess(MesSortShippingCheckModel model,MesPartShippingGroup shippingGroup){
        boolean flag = false;
        String organizeCode = model.getOrganizeCode();
        //1.首先校验自制件
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(model.getSn(), "productSn", packBean);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.DESC.getValue()}, new String[]{"createDatetime"}, packBean);
        MesProduceSn produceSn = produceSnRepository.getByProperty(packBean);

        if (Objects.isNull(produceSn)) {
            //外协件不需要校验前道工艺
            flag = true;
        }else{
            //自制件校验前道工艺 零件发运组详情中的优先
            MesPartShippingGroupDetail groupDetail = mesPartShippingGroupService.getMesPartShippingGroupDetailByPartNo(organizeCode, shippingGroup.getShippingGroupCode(), produceSn.getPartNo());
            if (null == groupDetail) {
                return true;
            }
            if (!StringUtils.isEmpty(groupDetail.getFrontProcessCode())){
                Integer count = mesProductionRecordService.findFrontProcessProductionRecord(organizeCode, produceSn.getProductSn(), groupDetail.getFrontProcessCode());
                if (count > 0){
                    flag = true;
                }
            }else if (!StringUtils.isEmpty(shippingGroup.getFrontProcessCode())){
                Integer count = mesProductionRecordService.findFrontProcessProductionRecord(organizeCode, produceSn.getProductSn(), shippingGroup.getFrontProcessCode());
                if (count > 0){
                    flag = true;
                }
            }else {
                //如果都没有
                flag = true;
            }
        }
        return flag;
    }

    @Override
    public MesShippingOrderManagement queryShippingOrderNoByAutoPushOrder(String shippingGroupNo, String org) {
        //查询最近扫描完成的装车单号
        DdlPackBean orderPackBean = DdlPackBean.getDdlPackBean(org);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.SHIPPING_ORDER_STATUS.SHIPPED.getValue(), "status", orderPackBean);
        DdlPreparedPack.getStringEqualPack(shippingGroupNo, "shippingGroupCode", orderPackBean);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.ASC.getValue()}, new String[]{"seq"}, orderPackBean);
        return shippingOrderManagementRepository.getByProperty(orderPackBean);
    }

    private MesPartShippingGroup getMesPartShippingGroup(String org, String partShippingGroupCode) {
        if(StringUtil.isEmpty(org) ||StringUtil.isEmpty(partShippingGroupCode)){
            throw new ImppBusiException("零件发运组信息不存在，请检查数据！");
        }
        MesPartShippingGroup shippingGroup = mesPartShippingGroupService.getMesPartShippingGroup(org, partShippingGroupCode);
        if(Objects.isNull(shippingGroup)){
            throw new ImppBusiException(String.format("零件发运组【%s】信息不存在，请检查数据！", partShippingGroupCode));
        }
        return shippingGroup;
    }

    private MesShippingOrderManagement getMesShippingOrderManagement(MesShippingOrderManagement shippingOrderManagement, String shippingGroupCode) {
        //查询发运单信息 发运跳过
        DdlPackBean orderManagementPackBean = DdlPackBean.getDdlPackBean(shippingOrderManagement.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(shippingOrderManagement.getShippingCode(), "shippingCode", orderManagementPackBean);
        MesShippingOrderManagement orderManagement = shippingOrderManagementRepository.getByProperty(orderManagementPackBean);
        if (StringUtils.isEmpty(orderManagement)) {
            throw new ImppBusiException(String.format("【%s】此发运单不存在，请检查数据！", shippingOrderManagement.getShippingCode()));
        }
        if (!Objects.equals(orderManagement.getShippingGroupCode(), shippingGroupCode)) {
            MesPcnException.throwMesBusiException("发运单【%s】不属于发运组【%s】，请检查数据！",  orderManagement.getShippingCode(), shippingGroupCode);
        }
        //校验发运单状态 必须是已发运的状态
        if (!Stream.of(MesExtEnumUtil.SHIPPING_ORDER_STATUS.SHIPPED.getValue()).collect(Collectors.toList()).contains(orderManagement.getStatus())) {
            throw new ImppBusiException(String.format("【%s】此发运单状态为【%s】,请选择状态为【%s】状态的发运单，请检查数据！", shippingOrderManagement.getShippingCode(),
                    MesExtEnumUtil.SHIPPING_ORDER_STATUS.valueOfDescription(orderManagement.getStatus()),
                    MesExtEnumUtil.SHIPPING_ORDER_STATUS.SHIPPED.getDescription()));
        }
        //跳过
        if (Objects.equals(MesPcnExtConstWords.THREE, shippingOrderManagement.getIsPass())) {
            //跳过的单据和明细，系统默认是完成的
            orderManagement.setStatus(MesExtEnumUtil.SHIPPING_ORDER_STATUS.SECOND_SHIPPED.getValue());
            orderManagement.setRemark(MesPcnExtConstWords.SHIP_PASS);
            ConvertBean.serviceModelUpdate(orderManagement, shippingOrderManagement.getModifyUser());
            vehiclesOrderRepository.update(orderManagement);
            //明细跳过
            updateShippingOrderDetails(orderManagement.getOrganizeCode(), shippingOrderManagement.getModifyUser(), orderManagement.getId());
            return null;
        }
        return orderManagement;
    }

    private void checkShippingOrderSeq(MesShippingOrderManagement shippingOrderManagement, MesShippingOrderManagement orderManagement) {
        //最后一个扫描完成的发运单信息
        DdlPackBean orderManagementPackBean = DdlPackBean.getDdlPackBean(shippingOrderManagement.getOrganizeCode());
        DdlPreparedPack.getNumberSmallerPack(orderManagement.getSeq(), "seq", orderManagementPackBean);
        DdlPreparedPack.getStringEqualPack(orderManagement.getShippingGroupCode(), "shippingGroupCode", orderManagementPackBean);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.SHIPPING_ORDER_STATUS.SECOND_SHIPPED.getValue(), "status", orderManagementPackBean);
        DdlPreparedPack.getOrderBy("seq", CommonEnumUtil.ASC_OR_DESC.DESC.getValue(), orderManagementPackBean);
        MesShippingOrderManagement management = shippingOrderManagementRepository.getByProperty(orderManagementPackBean);
        //当前发运组是否存在比当前小的序号，且状态是未发运完成
        orderManagementPackBean = DdlPackBean.getDdlPackBean(shippingOrderManagement.getOrganizeCode());
        DdlPreparedPack.getNumberSmallerPack(orderManagement.getSeq(), "seq", orderManagementPackBean);
        if (!Objects.isNull(management)) {
            DdlPreparedPack.getNumberBiggerPack(management.getSeq(), "seq", orderManagementPackBean);
        }
        DdlPreparedPack.getStringEqualPack(orderManagement.getShippingGroupCode(), "shippingGroupCode", orderManagementPackBean);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.SHIPPING_ORDER_STATUS.SHIPPED.getValue(), "status", orderManagementPackBean);
        DdlPreparedPack.getOrderBy("seq", CommonEnumUtil.ASC_OR_DESC.ASC.getValue(), orderManagementPackBean);
        MesShippingOrderManagement shippingOrder = shippingOrderManagementRepository.getByProperty(orderManagementPackBean);
        if (!Objects.isNull(shippingOrder)) {
            //1强过
            if ((!Objects.isNull(shippingOrderManagement.getIsPass()) && Objects.equals(MesPcnExtConstWords.ONE, shippingOrderManagement.getIsPass()))) {
                orderManagement.setRemark(MesPcnExtConstWords.STRONGER_PASS);
                ConvertBean.serviceModelUpdate(orderManagement, shippingOrderManagement.getModifyUser());
                vehiclesOrderRepository.update(orderManagement);
            } else {
                throw new ImppBusiException(String.format("【%s】发运单对应排序【%s】前存在未扫描发运的发运单【%s】序号【%s】，请检查数据！",
                        orderManagement.getShippingCode(), orderManagement.getSeq(),shippingOrder.getShippingCode(),shippingOrder.getSeq()));
            }
        }
    }

//    private void checkLoadingList(MesShippingOrderManagement shippingOrderManagement, MesShippingOrderManagement orderManagement, MesPartShippingGroup partShippingGroup) {
//        if (Objects.equals(orderManagement.getIsLoading(), MesCommonConstant.TRUE_INTEGER)) {
//            //查询装车单明细
//            DdlPackBean packBean = DdlPackBean.getDdlPackBean(orderManagement.getOrganizeCode());
//            DdlPreparedPack.getStringEqualPack(orderManagement.getShippingCode(),"shippingCode",packBean);
//            MesLoadingListDetail listDetail = listDetailRepository.getByProperty(packBean);
//            if(Objects.isNull(listDetail)){
//                throw new ImppBusiException(String.format("【%s】此发运单配置是否装车为是,但没绑定装车单号，请检查数据！", shippingOrderManagement.getShippingCode()));
//            }
//            packBean = DdlPackBean.getDdlPackBean(orderManagement.getOrganizeCode());
//            DdlPreparedPack.getNumEqualPack(listDetail.getPid(), "id", packBean);
//            MesLoadingList loadingList = listRepository.getByProperty(packBean);
//            if(Objects.isNull(loadingList)){
//                throw new ImppBusiException(String.format("【%s】此发运单配置是否装车为是,但没生成装车单，请检查数据！", shippingOrderManagement.getShippingCode()));
//            }
//            //判断是否先装车
//            if (mesPartShippingGroupService.isFirstInstall(partShippingGroup, loadingList)) {
//                //若没进行装车校验，则提示【%s】此发运单对应的【%s】此装车单状态为【%s】，请选择状态为【%s】的数据
//                if (loadingList.getStatus() != MesExtEnumUtil.MES_LOADING_STATUS.SCANNED.getValue()) {
//                    throw new ImppBusiException(String.format("【%s】此发运单对应的【%s】此装车单状态为【%s】，请选择状态为【%s】的数据！请检查数据！",
//                            shippingOrderManagement.getShippingCode(), loadingList.getOrderCode(),
//                            MesExtEnumUtil.MES_LOADING_STATUS.valueOfDescription(loadingList.getStatus()),
//                            MesExtEnumUtil.MES_LOADING_STATUS.SCANNED.getDescription()));
//                }
//            }
//        }
//    }

    private List<MesShippingOrderManagementDetail> getMesShippingOrderManagementDetails(MesShippingOrderManagement orderManagement,MesPartShippingGroup mesPartShippingGroup) {
        //45550 PDA-MES-PDA发运扫描排序方式修改
        List<MesConfig> shippingBusiSoftCfgList = mesConfigService.getConfigList(orderManagement.getOrganizeCode(),
                MesCommonConstant.SHIPPING_BUSI_SOFT_CFG, mesPartShippingGroup.getShippingGroupCode(), null);
        DdlPackBean orderDetailPackBean = DdlPackBean.getDdlPackBean(orderManagement.getOrganizeCode());
        DdlPreparedPack.getNumEqualPack(orderManagement.getId(), "pid", orderDetailPackBean);
        DdlPreparedPack.getNumberSmallerPack(MesExtEnumUtil.SHIPPING_ORDER_DETAIL_SHIPPING_STATUS.CLOSE.getValue(),"status",orderDetailPackBean);
        if (CollectionUtils.isEmpty(shippingBusiSoftCfgList)) {
            DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.ASC.getValue()}, new String[]{"custInfoSeq"}, orderDetailPackBean);
        }else {
            MesConfig mesConfig = shippingBusiSoftCfgList.get(0);
            if (!Objects.isNull(mesConfig) &&
                    !StringUtils.isEmpty(mesConfig.getCfgValue()) &&
                    "logic_seq".equals(mesConfig.getCfgValue())) {
                DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.ASC.getValue()}, new String[]{"logicSeq"}, orderDetailPackBean);
            }
        }
        List<MesShippingOrderManagementDetail> detailList = shippingOrderManagementDetailRepository.findByHqlWhere(orderDetailPackBean);
        if(CollectionUtils.isEmpty(detailList)){
            throw new ImppBusiException(String.format("发运单【%s】明细信息不存在，请检查数据！", orderManagement.getShippingCode()));
        }
        //已扫描数据
        detailList.forEach(k -> {
            if (Objects.equals(k.getSecondScanFlg(), MesCommonConstant.TRUE_INTEGER)){
                k.setIsScanFlg(MesCommonConstant.TRUE_INTEGER);
            }
        });

        //序号，总成类型顺序
        if(!Objects.isNull(mesPartShippingGroup.getScanSeqWay()) && !StringUtil.isEmpty(mesPartShippingGroup.getPartType()) && mesPartShippingGroup.getScanSeqWay() == MesExtEnumUtil.SHIPPING_GROUP_SCAN_CONFIRM_SEQ_MODE.SHIPPING_GROUP_SCAN_CONFIRM_SEQ_MODE_40.getValue()){
            return mesShippingOrderManagementDetailsSort(mesPartShippingGroup, detailList);
        }

        return detailList;
    }

    private List<MesShippingOrderManagementDetail> mesShippingOrderManagementDetailsSort(MesPartShippingGroup mesPartShippingGroup, List<MesShippingOrderManagementDetail> detailList) {
        List<MesShippingOrderManagementDetail> resultDetails = new ArrayList<>();
        Map<Long, List<MesShippingOrderManagementDetail>> detailMap = detailList.stream().collect(Collectors.groupingBy(MesShippingOrderManagementDetail::getCustInfoSeq));
        List<String> partTypeList = Arrays.asList(mesPartShippingGroup.getPartType().split(MesPcnExtConstWords.COMMA));
        for (Long seq : detailMap.keySet()) {
            List<MesShippingOrderManagementDetail> details = detailMap.get(seq);
            if (details.size() > MesPcnExtConstWords.ONE) {
                Map<String, List<MesShippingOrderManagementDetail>> containsMap = details.stream().filter(t -> partTypeList.contains(t.getPartTypeCode())).collect(Collectors.groupingBy(MesShippingOrderManagementDetail::getPartTypeCode));
                List<MesShippingOrderManagementDetail> noContains = details.stream().filter(t -> !partTypeList.contains(t.getPartTypeCode())).collect(Collectors.toList());
                //按照维护的总成类型显示
                for (String type : partTypeList){
                    if (!Objects.isNull(containsMap) && containsMap.containsKey(type)){
                        resultDetails.addAll(containsMap.get(type));
                    }
                }
                //相同seq，总成类型未维护放在最后面显示
                if (!CollectionUtils.isEmpty(noContains)){
                    resultDetails.addAll(noContains);
                }
            } else {
                resultDetails.addAll(details);
            }
        }
        return resultDetails;
    }

    private MesShippingOrderManagement getLastShippingOrder(String organizeCode) {
        DdlPackBean recentlyOrderPackBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.SHIPPING_ORDER_STATUS.SHIPPED.getValue(), "status", recentlyOrderPackBean);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.DESC.getValue()}, new String[]{"modifyDatetime"}, recentlyOrderPackBean);
        return  shippingOrderManagementRepository.getByProperty(recentlyOrderPackBean);
    }

    private void updateOrderManagementDetails(String userInfo, MesShippingOrderManagement orderManagement, MesShippingOrderManagementDetail detail, MesExtEnumUtil.SHIPPING_ORDER_DETAIL_SHIPPING_STATUS status) {
        detail.setIsScanFlg(MesCommonConstant.TRUE_INTEGER);
        detail.setSecondScanFlg(MesCommonConstant.TRUE_INTEGER);
        detail.setStatus(status.getValue());
        detail.setRemark(MesPcnExtConstWords.STRONGER_PASS);
        //根据是否启动记忆判断 若启用记忆，则根据保存数据库
        if (!StringUtils.isEmpty(orderManagement.getIsEnableMemory()) && Objects.equals(orderManagement.getIsEnableMemory(), MesCommonConstant.TRUE_INTEGER)) {
            //若发运单状态为已发运 则写入开始扫描时间
            if (!StringUtils.isEmpty(orderManagement.getStatus()) && orderManagement.getStatus() == MesExtEnumUtil.SHIPPING_ORDER_STATUS.SHIPPED.getValue()) {
                orderManagement.setStartScanTime(TimeTool.getNowTime(true));
            }
            //发运单状态
//            orderManagement.setStatus(MesExtEnumUtil.SHIPPING_ORDER_STATUS.SHIPPING.getValue());
            orderManagement.setSystemSyncStatus(CommonEnumUtil.FALSE);
            ConvertBean.serviceModelUpdate(orderManagement, userInfo);
            update(orderManagement);
            //发运单明细
            detail.setActualQty(1);
            detail.setSystemSyncStatus(CommonEnumUtil.FALSE);
            ConvertBean.serviceModelUpdate(detail, userInfo);
            updateDetail(detail);
        }
    }

    private MesSortShippingCheckModel skipShippingDetails(MesSortShippingCheckModel model, String userInfo, MesShippingOrderManagement orderManagement) {
        Optional<MesShippingOrderManagementDetail> shippingOrderManagementDetailOptional = model.getDetailList().stream().filter(t -> !Objects.equals(t.getIsScanFlg(), MesCommonConstant.TRUE_INTEGER)).findFirst();
        if(!shippingOrderManagementDetailOptional.isPresent()){
            throw new ImppBusiException(String.format("【%s】明细已全部扫描完成，请检查数据！", orderManagement.getShippingCode()));
        }
        //更新明细
        updateOrderManagementDetails(userInfo, orderManagement, shippingOrderManagementDetailOptional.get(), MesExtEnumUtil.SHIPPING_ORDER_DETAIL_SHIPPING_STATUS.SKIP);
        return model;
    }

    private MesSortShippingCheckModel forcePassShippingDetails(MesSortShippingCheckModel model, String userInfo, MesShippingOrderManagement orderManagement) {
        Optional<MesShippingOrderManagementDetail> shippingOrderManagementDetailOptional = model.getDetailList().stream().filter(t -> !Objects.equals(t.getSecondScanFlg(), MesCommonConstant.TRUE_INTEGER)).findFirst();
        if(!shippingOrderManagementDetailOptional.isPresent()){
            throw new ImppBusiException(String.format("【%s】明细已全部扫描完成，请检查数据！", orderManagement.getShippingCode()));
        }
        for (MesShippingOrderManagementDetail detail : model.getDetailList()) {
            if (Objects.equals(detail.getSecondScanFlg(), MesCommonConstant.TRUE_INTEGER) && Objects.equals(detail.getBarcode(), model.getSn())) {
                throw new ImppBusiException(String.format("【%s】条码已进行二次发运扫描，请检查数据！", model.getSn()));
            }
        }
        MesProduceSn produceSn = checkSecondSn(model);
        //更新明细
        MesShippingOrderManagementDetail detail = shippingOrderManagementDetailOptional.get();
        detail.setBarcode(model.getSn());
        updateOrderManagementDetails(userInfo, orderManagement, detail, MesExtEnumUtil.SHIPPING_ORDER_DETAIL_SHIPPING_STATUS.SHIPPINGED);
        return model;
    }

    /**
     * 检查二次发运时的条码状态
     * @param model 请求参数
     */
    private MesProduceSn checkSecondSn(MesSortShippingCheckModel model) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(model.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(model.getSn(), "productSn", packBean);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.DESC.getValue()}, new String[]{"createDatetime"}, packBean);
        MesProduceSn produceSn = produceSnRepository.getByProperty(packBean);
        if (produceSn == null) {
            throw new ImppBusiException(String.format("【%s】此条码无效,请检查数据！", model.getSn()));
        }

        //校验产品条码状态 必须是状态为已下线条码
        if (produceSn.getSnStatus() != MesExtEnumUtil.PRODUCE_SN_STATUS.OFFLINE.getValue() && produceSn.getSnStatus() != MesExtEnumUtil.PRODUCE_SN_STATUS.CREATE.getValue() && produceSn.getSnStatus() != MesExtEnumUtil.PRODUCE_SN_STATUS.SHIPPED.getValue()) {
            throw new ImppBusiException(String.format("【%s】此条码状态为【%s】,请选择状态为【%s】或【%s】或【%s】状态的条码，请检查数据！", model.getSn(), MesExtEnumUtil.PRODUCE_SN_STATUS.valueOfDescription(produceSn.getSnStatus()),
                    MesExtEnumUtil.PRODUCE_SN_STATUS.OFFLINE.getDescription(), MesExtEnumUtil.PRODUCE_SN_STATUS.CREATE.getDescription(), MesExtEnumUtil.PRODUCE_SN_STATUS.SHIPPED.getValue()));
        }
        //校验产品质量状态 必须是状态为合格条码
        List<Integer> statusList = Stream.of(MesExtEnumUtil.PRODUCE_QC_STATUS.QUALIFIED.getValue(), MesExtEnumUtil.PRODUCE_QC_STATUS.SUSPICIOUS_TO_QUALIFIED.getValue()).collect(Collectors.toList());
        if (!statusList.contains(produceSn.getQcStatus())){
            throw new ImppBusiException(String.format("【%s】此条码质量状态为【%s】,请选择【%s】状态的条码，请检查数据！", model.getSn(), MesExtEnumUtil.PRODUCE_QC_STATUS.valueOfDescription(produceSn.getQcStatus()),
                    MesExtEnumUtil.PRODUCE_QC_STATUS.QUALIFIED.getDescription()));
        }
        return produceSn;
    }

    private MesShippingOrderManagement checkMesShippingOrderManagement(MesSortShippingCheckModel model) {
        //校验发运单是否存在
        DdlPackBean orderManagementPackBean = DdlPackBean.getDdlPackBean(model.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(model.getShippingCode(), "shippingCode", orderManagementPackBean);
        MesShippingOrderManagement orderManagement = shippingOrderManagementRepository.getByProperty(orderManagementPackBean);
        if (StringUtils.isEmpty(orderManagement)) {
            throw new ImppBusiException(String.format("【%s】此发运单不存在，请检查数据！", model.getShippingCode()));
        }
        return orderManagement;
    }

    public void saveDate(MesShippingOrderManagement orderManagement, MesSortShippingCheckModel model, String organizeCode, String userInfo) {
        //发运单状态修改为校验完成
        orderManagement.setSystemSyncStatus(CommonEnumUtil.FALSE);
        orderManagement.setStatus(MesExtEnumUtil.SHIPPING_ORDER_STATUS.SECOND_SHIPPED.getValue());
        orderManagement.setEndScanTime(TimeTool.getNowTime(true));

        //零件发运组
        MesPartShippingGroup shippingGroup = Objects.isNull(model.getMesPartShippingGroup()) ? getMesPartShippingGroup(orderManagement.getOrganizeCode(), orderManagement.getShippingGroupCode()) : model.getMesPartShippingGroup();

        //发运单明细状态修改为校验完成
        DdlPackBean orderManagementDetailPackBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getNumEqualPack(orderManagement.getId(), "pid", orderManagementDetailPackBean);
        List<MesShippingOrderManagementDetail> orderManagementDetailList = shippingOrderManagementDetailRepository.findByHqlWhere(orderManagementDetailPackBean);
        List<MesShippingOrderManagementDetail> detailList = model.getDetailList();
        Map<Long, List<MesShippingOrderManagementDetail>> custInfoSeqMap = detailList.stream().collect(Collectors.groupingBy(MesShippingOrderManagementDetail::getId));

        //获取工单信息
        MesSortShippingModel sortShippingModel = getMesSortShippingModel(orderManagement.getShippingGroupCode(), organizeCode, detailList.stream().map(MesShippingOrderManagementDetail::getVisualOrderNo).filter(visualOrderNo -> !StringUtil.isEmptyAndNull(visualOrderNo)).collect(Collectors.toList()));
        //查询条码信息
        Map<String, List<MesProduceSn>> produceSnByCustSnMap = getProduceSnByCustSnMap(orderManagement.getIsEnableMemory(), organizeCode, detailList.stream().map(MesShippingOrderManagementDetail::getBarcode).filter(barCode -> !StringUtil.isEmptyAndNull(barCode)).collect(Collectors.toList()));

        final String confirmPartType = getConfirmPartType(orderManagement);
        List<MesProduceSn> produceSnList = new ArrayList<>();
        List<String> workOrderNoList = new ArrayList<>();
        List<MesShippingSnUnique> mesShippingSnUniqueList = new ArrayList<>();
        List<MesJisShipping> shippingList = new ArrayList<>();
        for (MesShippingOrderManagementDetail detail : orderManagementDetailList) {
            if (!Objects.equals(orderManagement.getIsEnableMemory(), MesCommonConstant.TRUE_INTEGER)) {
                BeanUtils.copyProperties(custInfoSeqMap.get(detail.getId()).iterator().next(), detail);
            } else if (!StringUtil.isEmpty(detail.getBarcode()) && detail.getBarcode().contains(MesPcnExtConstWords.COMMA)) {
                detail.setVisualOrderNo(detail.getBarcode().split(MesPcnExtConstWords.COMMA)[MesPcnExtConstWords.ZERO]);
            }
            //更新条码信息，更新目视单信息
            if(!StringUtils.isEmpty(detail.getBarcode()) && !Objects.equals(orderManagement.getIsEnableMemory(), MesCommonConstant.TRUE_INTEGER)){
                if (!Objects.isNull(produceSnByCustSnMap) && produceSnByCustSnMap.containsKey(detail.getBarcode())) {
                    MesProduceSn produceSn = produceSnByCustSnMap.get(detail.getBarcode()).iterator().next();
                    produceSn.setSnStatus(MesExtEnumUtil.PRODUCE_SN_STATUS.SHIPPED.getValue());
                    produceSn.setSystemSyncStatus(CommonEnumUtil.FALSE);
                    produceSn.setSystemSyncDatetime(MesPcnExtConstWords.EMPTY);
                    ConvertBean.serviceModelUpdate(produceSn, userInfo);
                    produceSnList.add(produceSn);
                } else {
                    //记录唯一性校验表
                    mesShippingSnUniqueList.add(mesShippingSnUniqueService.getMesShippingSnUnique(organizeCode, detail.getBarcode(), orderManagement.getShippingCode(), userInfo));
                }
                //更新工单
                if(!StringUtils.isEmpty(detail.getVisualOrderNo())){
                    workOrderNoList.add(detail.getVisualOrderNo());
                    //更新应急件库位管理库存出库
                    mesEmergencyLocationService.doShippingStockOutOnline(organizeCode, detail.getVisualOrderNo(), userInfo, true);
                    // 保存到发运队列，后续发运单的条码会拼接，而保存到发运队列中的为拼接前的数据，因此要在拼接前调用。
                    saveShippingQueue(orderManagement, detail, userInfo);
                    if (!Objects.equals(confirmPartType, String.valueOf(MesExtEnumUtil.SHIPPING_GROUP_CONFIRM_PART_TYPE.SHIPPING_GROUP_CONFIRM_PART_TYPE_40.getValue()))) {
                        if (Objects.equals(confirmPartType, String.valueOf(MesExtEnumUtil.SHIPPING_GROUP_CONFIRM_PART_TYPE.SHIPPING_GROUP_CONFIRM_PART_TYPE_50.getValue()))) {
                            detail.setBarcode(detail.getBarcode() + "," + detail.getPartPosition());
                        } else {
                            //条码格式(扫描目视单,扫描条码)
                            detail.setBarcode(new StringJoiner(MesPcnExtConstWords.COMMA).add(detail.getVisualOrderNo()).add(detail.getBarcode()).toString());
                        }
                    }
                }
            }
            //客供品移库
            customerSupplyMove(sortShippingModel, detail);

            detail.setIsValid(CommonEnumUtil.VALID);
            detail.setSystemSyncStatus(CommonEnumUtil.FALSE);
            detail.setActualQty(MesPcnExtConstWords.ONE);
            ConvertBean.serviceModelUpdate(detail, userInfo);
        }
        //保存唯一性表
        if(!CollectionUtils.isEmpty(mesShippingSnUniqueList)){
            mesShippingSnUniqueRepository.saveAll(mesShippingSnUniqueList);
        }
        //更新条码
        if(!CollectionUtils.isEmpty(produceSnList)){
            produceSnRepository.saveAll(produceSnList);
        }
        //更新工单状态为已发运
        if(!CollectionUtils.isEmpty(workOrderNoList)){
            mesWorkOrderExtService.updateMesWorkOrderOrderStatusShippingByWorkOrderNo(organizeCode, workOrderNoList, userInfo);
        }
        //更新发运单
        ConvertBean.serviceModelUpdate(orderManagement,userInfo);
        update(orderManagement);
        //不记忆时更新明细
        if (!StringUtils.isEmpty(orderManagement.getIsEnableMemory()) && !Objects.equals(orderManagement.getIsEnableMemory(), MesCommonConstant.TRUE_INTEGER)){
            shippingOrderManagementDetailRepository.saveAll(orderManagementDetailList);
        }
        if (StringUtils.isEmpty(orderManagement.getOrderCode()) || StringUtils.isEmpty(orderManagement.getLoadingListId())) {
            //发送数据给辊道线
            sendShippingFinishedCmd(model, organizeCode);
            //保存当前发运单明细
            List<MesJisShipping> mesJisShippings = getMesJisShippings(orderManagement, orderManagementDetailList, userInfo);
            if (!CollectionUtils.isEmpty(mesJisShippings)) {
                shippingList.addAll(mesJisShippings);
            }
        }
        //发运结果回传
        if(!CollectionUtils.isEmpty(shippingList)){
            jisShippingRepository.saveAll(shippingList);
        }

    }

    private void sendShippingFinishedCmd(MesSortShippingCheckModel model, String organizeCode) {
        if (!Objects.isNull(model.getMesPartShippingGroup()) && !StringUtil.isEmpty(model.getMesPartShippingGroup().getEquipmentCode())) {
            //辊道设备配置
            MesBallTrackRule rule = getMesBallTrackRule(model, organizeCode);
            //设备变量
            MesEquipmentVariable mesEquipmentVariable = mesEquipmentExtService.getMesEquipmentVariable(organizeCode, rule.getEquipmentCode(), rule.getEquipVariableId());
            if (Objects.isNull(mesEquipmentVariable)) {
                MesPcnException.throwMesBusiException("设备【%s】设备变量ID【%s】信息不存在，请检查", rule.getEquipmentCode(), rule.getEquipVariableId());
            }
            //设备通道
            MesEquipmentChannel mesEquipmentChannel = mesEquipmentExtService.getMesEquipmentChannel(organizeCode, rule.getEquipmentCode(), mesEquipmentVariable.getChannel());
            if (Objects.isNull(mesEquipmentChannel)) {
                MesPcnException.throwMesBusiException("设备【%s】设备通道【%s】信息不存在，请检查", rule.getEquipmentCode(), mesEquipmentVariable.getChannel());
            }
            //写入
            MesEquipVariableRwResult equipVariableRwResult = equipVariableRwExtService.writeVariable(rule.getEquipVariableValue(), mesEquipmentVariable, mesEquipmentChannel.getKepwareFlag());
            if (!equipVariableRwResult.getIsSuccessed()) {
                MesPcnException.throwMesBusiException(String.format("设备【%s】:发运成功指令发送失败!原因:%s", mesEquipmentChannel.getEquipmentName(), JSONObject.toJSONString(equipVariableRwResult)));
            }
        }
    }

    private MesBallTrackRule getMesBallTrackRule(MesSortShippingCheckModel model, String organizeCode) {
        DdlPackBean bean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(model.getMesPartShippingGroup().getEquipmentCode(), "equipmentCode", bean);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.BALL_TRACK_TYPE.BALL_TRACK_TYPE_30.getValue(), "ballTrackType", bean);
        MesBallTrackRule rule = mesBallTrackRuleRepository.getByProperty(bean);
        if (Objects.isNull(rule) || Objects.isNull(rule.getEquipVariableId())) {
            MesPcnException.throwMesBusiException("设备【%s】辊道设备配置信息不存在，请检查", model.getMesPartShippingGroup().getEquipmentCode());
        }
        return rule;
    }

    @Override
    public List<MesJisShipping> getMesJisShippings(MesShippingOrderManagement mesShippingOrderManagement,List<MesShippingOrderManagementDetail> shippingOrderManagementDetails,String userName) {
        if (CollectionUtils.isEmpty(shippingOrderManagementDetails)) {
            DdlPackBean detailPackBean = DdlPackBean.getDdlPackBean(mesShippingOrderManagement.getOrganizeCode());
            DdlPreparedPack.getNumEqualPack(mesShippingOrderManagement.getId(), "pid", detailPackBean);
            DdlPreparedPack.getNumberSmallerPack(MesExtEnumUtil.SHIPPING_ORDER_DETAIL_SHIPPING_STATUS.SKIP.getValue(), "status", detailPackBean);
            shippingOrderManagementDetails = shippingOrderManagementDetailRepository.findByHqlWhere(detailPackBean);
        }
        //当前装车单所有发运单明细 需要报工的数据
        return jisShippingService.getJisShipping(mesShippingOrderManagement, shippingOrderManagementDetails, userName);
    }

    @Override
    @MonitorLog
    public void update(MesShippingOrderManagement item) {
        shippingOrderManagementRepository.update(item);
    }

    @Override
    @MonitorLog
    public void updateDetail(MesShippingOrderManagementDetail item) {
        shippingOrderManagementDetailRepository.update(item);
    }

    @Override
    public void checkPassword(String password, String organizeCode) {
        String configPassword = mesConfigService.getCfgValue(organizeCode, MesCommonConstant.SECOND_SHIPPING_CHECK_PASSWORD);
        if (!Objects.equals(password, configPassword)) {
            MesPcnException.throwMesBusiException("密码错误，请重新输入！");
        }
    }

    private void updateShippingOrderDetails(String organizeCode, String userName, long id) {
        if(StringUtils.isEmpty(id) || StringUtils.isEmpty(organizeCode)) {
            return;
        }
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getNumEqualPack(id, "pid",packBean);
        shippingOrderManagementDetailRepository.updateByProperties(new String[]{"modifyUser", "modifyDatetime", "status","remark"},
                new Object[]{userName, TimeTool.getNowTime(true), MesExtEnumUtil.SHIPPING_ORDER_DETAIL_SHIPPING_STATUS.SKIP.getValue(), MesPcnExtConstWords.SHIP_PASS}, packBean);
    }

    private MesSortShippingModel getMesSortShippingModel(String shippingGroupCode, String organizeCode, List<String> orderNoList) {
        MesSortShippingModel sortShippingModel = new MesSortShippingModel();
        if (!CollectionUtils.isEmpty(orderNoList)) {
            sortShippingModel.setMesWorkOrderList(mesWorkOrderExtService.getWorkOrderList(organizeCode, orderNoList));
            sortShippingModel.setMesWorkOrderPartList(mesWorkOrderService.findMesWorkOrderPartByOrderNo(organizeCode, orderNoList));
            sortShippingModel.setMesProductionRecordList(mesProductionRecordService.findProductionRecordList(organizeCode, orderNoList, MesExtEnumUtil.MES_REPORT_TYPE.CUSTOMER_SUPPLY_MOVE.getValue()));
        }
        sortShippingModel.setMesPartList(mesPartService.findMesPartByPartNo(sortShippingModel.getPartNoAllList(), organizeCode));
        sortShippingModel.setMesMoveRuleList(mesMoveRuleService.findMesMoveRuleByPartProdGroupCode(shippingGroupCode, organizeCode,MesExtEnumUtil.MOVE_RULE_GROUP_TYPE.MOVE_RULE_GROUP_TYPE_10.getValue()));

        return sortShippingModel;
    }

    private Map<String, List<MesProduceSn>> getProduceSnByCustSnMap(Integer isEnableMemory, String organizeCode, List<String> custSnList) {
        Map<String, List<MesProduceSn>> produceSnByCustSnMap = null;
        if (!Objects.equals(isEnableMemory, MesCommonConstant.TRUE_INTEGER)) {
            produceSnByCustSnMap = mesProduceSnExtService.getProduceSnByCustSnMap(organizeCode, custSnList);
        }
        return produceSnByCustSnMap;
    }

    private void customerSupplyMove(MesSortShippingModel sortShippingModel, MesShippingOrderManagementDetail detail) {
        detail.setSaveFlag(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue());
        // 宁德配置了移库规则为二次发运后，则第一次发运时不写入jis_Shipping表，二次发运才写入，否则第一次写入，二次发运后不写入。
        if (!CollectionUtils.isEmpty(sortShippingModel.getMesMoveRuleList())) {
            MesMoveRule moveRule = sortShippingModel.getMesMoveRuleList().get(0);
            if (moveRule != null && Objects.equals(moveRule.getMoveNum(), MesExtEnumUtil.MOVE_RULE_MOVE_NUM.MOVE_RULE_MOVE_NUM_40.getValue())) {
                detail.setSaveFlag(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
            }
        }
    }

    private void doCreateReworkMove(String organizeCode,String userName, String srcLocate, String destLocate, String workCenterCode, String partNo, double qty, String sn) {
        MesPartSap mesPartSap = mesPartService.getMesPartSapByPartNo(partNo, organizeCode);
        MesMove move = new MesMove();
        move.setMatnr(mesPartSap.getPartNo());
        move.setOrganizeCode(organizeCode);
        move.setFactoryCode(organizeCode);
        move.setLgort(srcLocate);
        move.setUmlgo(destLocate);
        move.setPartInspectionId(0L);
        move.setMenge(qty);
        move.setMeins(mesPartSap.getUnit());
        move.setPostDate(TimeTool.getToday());
        move.setPostTime(TimeTool.getTimeShortWithColon());
        move.setMoveType(MesExtEnumUtil.MOVE_TYPE.RETURN_MOVE.getValue());
        move.setProductSn(sn);
        move.setWorkCenter(workCenterCode);
        ConvertBean.serviceModelInitialize(move, userName);
        moveRepository.insert(move);
    }

    private void saveShippingQueue(MesShippingOrderManagement orderManagement, MesShippingOrderManagementDetail detail, String userInfo) {
        if (StringUtil.isEmpty(detail.getVin())) {
            MesPcnException.throwMesBusiException("发运单【%s】零件号【%s】vin号为空，请检查数据", orderManagement.getShippingCode(), detail.getPartNo());
        }
        final boolean matchCfgValue = mesConfigService.checkCfgValueIsContainItem(orderManagement.getOrganizeCode(), MesPcnExtConstWords.MES_SHIPPING_QUEUE_SAVE_CFG, MesPcnExtConstWords.MES_SHIPPING_QUEUE_SAVE_CFG, null, ",", orderManagement.getShippingGroupCode());
        if (!matchCfgValue) {
            return;
        }
        int limitValue = 0;
        List<MesConfig> limitConfig = mesConfigService.getConfigList(orderManagement.getOrganizeCode(), MesPcnExtConstWords.MES_SHIPPING_QUEUE_SAVE_CFG, "LIMIT", null);
        if (!CollectionUtils.isEmpty(limitConfig)) {
            String strLimitValue = limitConfig.get(0).getCfgValue();
            if (!StringUtil.isEmpty(strLimitValue)) {
                try {
                    limitValue = Integer.parseInt(strLimitValue);
                } catch (Exception ignored) {

                }
            }
        }
        if (limitValue > 0) {
            DdlPackBean packBean = DdlPackBean.getDdlPackBean(orderManagement.getOrganizeCode());
            DdlPreparedPack.getStringEqualPack(orderManagement.getShippingGroupCode(), "shippingGroupCode", packBean);
            DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.QUEUE_ORDER_STATUS.CREATE.getValue(), "queueStatus", packBean);
            int count = shippingQueueRDao.findByHqlWhereCount(packBean);
            if (count >= limitValue) {
                MesPcnException.throwMesBusiException("当前发运组【%s】的发运队列已满，请稍后重试！", orderManagement.getShippingGroupCode());
            }
        }

        MesShippingQueue mesShippingQueue = new MesShippingQueue();
        mesShippingQueue.setOrganizeCode(orderManagement.getOrganizeCode());
        mesShippingQueue.setShippingCode(orderManagement.getShippingCode());
        mesShippingQueue.setShippingGroupCode(orderManagement.getShippingGroupCode());
        mesShippingQueue.setShippingType(orderManagement.getShippingType());
        mesShippingQueue.setWorkOrderNo(detail.getVisualOrderNo());
        mesShippingQueue.setCustSn(detail.getBarcode());
        mesShippingQueue.setPartNo(detail.getPartNo());
        mesShippingQueue.setPartName(detail.getPartName());
        mesShippingQueue.setVin(detail.getVin());
        mesShippingQueue.setQueueStatus(MesExtEnumUtil.QUEUE_ORDER_STATUS.CREATE.getValue());
        ConvertBean.serviceModelInitialize(mesShippingQueue, userInfo);
        shippingQueueRDao.insert(mesShippingQueue);
    }

    private String getConfirmPartType(MesShippingOrderManagement orderManagement) {
        if (StringUtils.isEmpty(orderManagement.getShippingGroupCode())) {
            return "";
        }
        MesPartShippingGroup shippingGroup = mesPartShippingGroupService.getMesPartShippingGroup(orderManagement.getOrganizeCode(), orderManagement.getShippingGroupCode());
        if (shippingGroup == null) {
            return "";
        }
        return shippingGroup.getConfirmPartType();
    }
}
