package com.sw.mes.wipstorage.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sw.mes.base.factory.init.entity.ClassMonitorModelLog;
import com.sw.mes.base.factory.init.entity.CrystalMaterialRelation;
import com.sw.mes.base.factory.init.entity.Equipment;
import com.sw.mes.base.factory.init.entity.FactoryModel;
import com.sw.mes.base.factory.init.service.ClassMonitorModelLogService;
import com.sw.mes.base.factory.init.service.CrystalMaterialRelationService;
import com.sw.mes.base.factory.init.service.EquipmentService;
import com.sw.mes.base.factory.inspect.entity.DefaultSample;
import com.sw.mes.base.factory.inspect.service.DefaultSampleService;
import com.sw.mes.base.factory.material.entity.MaterialModel;
import com.sw.mes.base.factory.material.service.MaterialModelService;
import com.sw.mes.base.global.GlobalSwitch;
import com.sw.mes.base.global.GlobalSwitchNamespace;
import com.sw.mes.base.global.GlobalSwitch;
import com.sw.mes.base.global.SwitchConfig;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.entity.SysLog;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.base.system.service.SysLogService;
import com.sw.mes.base.workinprocess.dao.PlanProcessingOrderDao;
import com.sw.mes.base.workinprocess.dao.WipStorageDao;
import com.sw.mes.base.workinprocess.dto.PlanProcessingOrderWipStorageDto;
import com.sw.mes.base.workinprocess.dto.ProcessingOrderNewDto;
import com.sw.mes.base.workinprocess.entity.PlanProcessingOrder;
import com.sw.mes.base.workinprocess.entity.ProcessLog;
import com.sw.mes.base.workinprocess.entity.WipStorage;
import com.sw.mes.base.workinprocess.service.PlanProcessingOrderService;
import com.sw.mes.base.workinprocess.service.ProcessLogService;
import com.sw.mes.base.workinprocess.service.WipStorageService;
import com.sw.mes.core.api.system.FbFeignClients;
import com.sw.mes.core.api.system.StoreFeignClients;
import com.sw.mes.core.constant.Constants;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.dto.BackcutInspectionDto;
import com.sw.mes.core.dto.EapCutCraftDto;
import com.sw.mes.core.dto.FbScheduleDto;
import com.sw.mes.core.dto.WarehouseModelDto;
import com.sw.mes.core.dto.sap.ReportSapGoodsmvtDto;
import com.sw.mes.core.dto.sap.SendReportSapGoodsmvtDto;
import com.sw.mes.core.dto.store.*;
import com.sw.mes.core.entity.FbCheckOutData;
import com.sw.mes.core.enums.EnumValues;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultCode;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.core.utils.BeanUtil;
import com.sw.mes.core.utils.IpUtils;
import com.sw.mes.core.utils.NumberUtil;
import com.sw.mes.core.utils.ThreadManager;
import com.sw.mes.enumvalue.EnumValuesServer;
import com.sw.mes.grade.service.GradeService;
import com.sw.mes.inspect.entity.YbInspectData;
import com.sw.mes.inspect.service.YbInspectDataService;
import com.sw.mes.sap.entity.ReportSapGoodsmvt;
import com.sw.mes.sap.entity.ReportSapWorkinghours;
import com.sw.mes.sap.service.ReportSapGoodsmvtService;
import com.sw.mes.sap.service.ReportSapWorkinghoursService;
import com.sw.mes.utils.StringUtils;
import com.sw.mes.wipstorage.service.WipStorageYbService;
import com.sw.mes.yb.mcs.service.PublishRankResultService;
import com.sw.mes.yb.pad.dao.SectionNoDetailDao;
import com.sw.mes.yb.pad.entity.*;
import com.sw.mes.yb.pad.service.*;
import com.sw.mes.yb.pc.dao.SectionDAO;
import com.sw.mes.yb.pc.service.SectionService;
import com.sw.mes.yb.pc.service.SpellInfoService;
import com.sw.mes.yb.plan.entity.ProductionOrder;
import com.sw.mes.yb.plan.service.ProductionOrderService;
import com.sw.mes.yb.production.entity.LongCrystal;
import com.sw.mes.yb.production.service.LongCrystalService;
import com.sw.mes.yb.seed.enums.InputBillStatusEnum;
import com.sw.mes.yb.turnstore.entity.ProductionBindingTrayLog;
import com.sw.mes.yb.turnstore.service.ProductionBindingTrayLogService;
import com.sw.mes.yb.turnstore.service.TurnstoreInItemService;
import lombok.extern.slf4j.Slf4j;
import org.apache.xmlbeans.impl.xb.xsdschema.Public;
import org.modelmapper.ModelMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import static com.sw.mes.base.global.GlobalSwitchNamespace.CODE_SWITCH;

@Slf4j
@Service
@Transactional
public class WipStorageYbServiceImpl implements WipStorageYbService {
    @Autowired
    private DictionaryItemService dictionaryItemService;
    @Autowired
    private SectionNoDetailService sectionNoDetailService;
    @Autowired
    private ProductionPaintingLineService productionPaintingLineService;
    @Autowired
    private FbFeignClients fbFeignClients;
    @Autowired
    private WipStorageService wipStorageService;
    @Autowired
    private ProductionRecutService productionRecutService;
    @Autowired
    private PlanProcessingOrderService planProcessingOrderService;
    @Autowired
    private ProductionPaintingLineDetailService productionPaintingLineDetailService;
    @Autowired
    private SectionNoDetailDao sectionNoDetailDao;
    @Autowired
    private RecutDetailService recutDetailService;
    @Autowired
    private FbReCutService fbReCutService;
    @Autowired
    private WipStorageYbService wipStorageYbService;
    @Autowired
    private YbInspectDataService inspectDataBaseService;
    @Autowired
    private ClassMonitorModelLogService classMonitorModelLogService;

    @Autowired
    private SpellInfoService spellInfoService;

    @Autowired
    private TurnstoreInItemService turnstoreInItemService;

    @Autowired
    private PublishRankResultService publishRankResultService;

    @Autowired
    private SectionDAO sectionDAO;

    @Autowired
    private SectionService sectionService;

    @Autowired
    private FbFeignClients fbFeignService;

    @Autowired
    private ProcessLogService processLogService;

    @Autowired
    private PlanProcessingOrderDao planProcessingOrderDao;

    @Autowired
    private WipStorageDao dao;

    @Autowired
    private ReportSapGoodsmvtService reportSapGoodsmvtService;

    @Autowired
    private LongCrystalService longCrystalService;

    @Autowired
    private YbInspectDataService ybInspectDataService;

    @Autowired
    private StoreFeignClients storeFeignClients;

    @Autowired
    private ModelMapper modelMapper;

    @Autowired
    private MaterialModelService materialModelService;


    @Autowired
    private ReportSapWorkinghoursService reportSapWorkinghoursService;

    @Autowired
    private EquipmentService equipmentService;

    @Autowired
    private DefaultSampleService defaultSampleService;

    @Autowired
    private CrystalMaterialRelationService crystalMaterialRelationService;

    @Autowired
    private GradeService gradeService;


    @Autowired
    private ProductionBindingTrayLogService productionBindingTrayLogService;

    @Autowired
    private SysLogService sysLogService;

    @Autowired
    private ProductionOrderService productionOrderService;

//    @Autowired
//    private ReportSapRecordService reportSapRecordService;

    /**
     * 截断过站信息处理过站，同时长传截断信息
     *
     * @param planProcessingOrderWipStorageDto
     * @return
     */
    @Override
    public Result execJd(PlanProcessingOrderWipStorageDto planProcessingOrderWipStorageDto, boolean sendEapCutCraft) {
        List<ProcessingOrderNewDto> processingOrderNewDtos = new ArrayList<>();
        PlanProcessingOrder planProcessingOrder = planProcessingOrderWipStorageDto.getPlanProcessingOrder();
        //长棒截断
        if (planProcessingOrder.getOrderType() == EnumValuesFactory.PlanProcessingOrderOrderType.单晶.getKey()) {
            //圆棒画线记录
            ProductionPaintingLine productionPaintingLine = productionPaintingLineService.findByCrystalNo(planProcessingOrderWipStorageDto.getPlanProcessingOrder().getCode());
            if (productionPaintingLine == null) {
                throw new BusinessException("画线信息不能为空，请检查数据");
            }
            List<SectionNoDetail> sectionNoDetails = sectionNoDetailService.findByCrystalIdAndParentId(planProcessingOrderWipStorageDto.getPlanProcessingOrder().getGoodsId(), 0L);
            if (sectionNoDetails.size() == 0) {
                //查询是不是全是回收料
                List<ProductionPaintingLineDetail> productionPaintingLineDetailList = productionPaintingLineDetailService.findByOperateDrawId(productionPaintingLine.getId());
                if (!CollectionUtils.isEmpty(productionPaintingLineDetailList)){
                    Boolean materialRecycledFlag = true;
                    for (ProductionPaintingLineDetail productionPaintingLineDetail : productionPaintingLineDetailList){
                        if (null != productionPaintingLineDetail.getType() && EnumValuesServer.LineType.回收料.getKey() != productionPaintingLineDetail.getType()){
                            materialRecycledFlag = false;
                        }
                    }
                    if (materialRecycledFlag){
                        //全是回收料：记录单晶工时（毛棒截断时间）
                        //报工时：上报SAP
                        try {
                            SwitchConfig config = GlobalSwitch.switchConfig(CODE_SWITCH, "crystalCutOffWorkHour", false);
                            if( config.isEnable()){
                                List<PlanProcessingOrder> planProcessingOrders = planProcessingOrderDao.findByCodeOrderByIdDesc(planProcessingOrderWipStorageDto.getPlanProcessingOrder().getCode());
                                if (planProcessingOrders.size() == 0) {
                                    throw new BusinessException("工单号【" + planProcessingOrderWipStorageDto.getPlanProcessingOrder().getCode() + "】不存在");
                                }
                                PlanProcessingOrder planProcessingOrder1 = planProcessingOrders.get(0);
                                WipStorage currentWipStorageL = planProcessingOrder1.getWipStorage();

                                Result<FbScheduleDto> fbScheduleDtoResult = fbFeignClients.findByDeviceNo(currentWipStorageL.getEquipmentCode());
                                if (null != fbScheduleDtoResult && ResultCode.SUCCESS.getCode() == fbScheduleDtoResult.getCode() && null != fbScheduleDtoResult.getData()) {
                                    FbScheduleDto fbScheduleDtoResultData = fbScheduleDtoResult.getData();
                                    CrystalMaterialRelation crystalMaterialRelation = new CrystalMaterialRelation();
                                    crystalMaterialRelation.setOrderNo(fbScheduleDtoResultData.getOrderNo());
                                    LongCrystal byCrystalNo = longCrystalService.findByCrystalNo(planProcessingOrderWipStorageDto.getPlanProcessingOrder().getCode());
                                    extracted(planProcessingOrderWipStorageDto.getPlanProcessingOrder().getCode(), byCrystalNo, crystalMaterialRelation, new Date());
                                } else {
                                    throw new BusinessException("设备排程未维护，请先维护排程信息。设备编号为：" + currentWipStorageL.getEquipmentCode());
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            log.info("截断工时：" + e.getMessage());
                        }
                        return wipStorageService.outStation(productionPaintingLine.getCrystalNo(),"-2",null,false,"划线回收料完单！");
                    }else {
                        throw new BusinessException("长棒的划线信息不存在，请检查数据");
                    }
                }else {
                    throw new BusinessException("长棒的划线信息不存在，请检查数据");
                }
            }
            setProcessingOrderNewDto(processingOrderNewDtos, sectionNoDetails);
            return getResult(sendEapCutCraft, processingOrderNewDtos, planProcessingOrder, productionPaintingLine, null, null, null);
        }
        //晶段反切截断
        else if (planProcessingOrder.getOrderType() == EnumValuesFactory.PlanProcessingOrderOrderType.晶段.getKey()) {
            //圆棒反切画线记录
            ProductionBackCuttingRecord productionBackCuttingRecord;
            if (planProcessingOrder.getMaterialType() == EnumValuesFactory.MaterialType.圆棒.getKey()) {
                productionBackCuttingRecord = productionRecutService.findBySegmentNo(planProcessingOrder.getCode());
                if (productionBackCuttingRecord == null) {
                    throw new BusinessException(planProcessingOrder.getCode() + "不存在未切断的反切划线信息，请检查数据");
                }
                if (StringUtils.isNotBlank(productionBackCuttingRecord.getSectionCompose()) && StringUtils.isNotBlank(productionBackCuttingRecord.getUuid())) {
                    // 拼棒过截断站
                    return execYbJdV2(planProcessingOrder, productionBackCuttingRecord, sendEapCutCraft);
                } else {
                    // 非拼棒过截断站
                    execYbJd(planProcessingOrder, productionBackCuttingRecord, sendEapCutCraft);

                    //处理返切不复测业务逻辑
                    if (productionBackCuttingRecord.getIsNotReTest()) {
                        Map<String, YbInspectData> inspectMaps = new HashMap<>();
                        //根据晶段编号 最后一条记录 查询圆棒检验记录
                        YbInspectData ybInspectData = ybInspectDataService.findBySectionNo(planProcessingOrder.getCode());
                        if (null == ybInspectData) {
                            throw new BusinessException(planProcessingOrder.getCode() + ",检验记录不存在，请先核对单晶数据是否人为删除！");
                        }
                        //1.根据原有圆棒检验记录中 掺杂剂，规格 找到对应的默认值
                        DefaultSample defaultSample = defaultSampleService.findByDopantLikeAndSpecificationsLikeAndProductTypeLike(ybInspectData.getDopant(), ybInspectData.getProductTypeSecond(), ybInspectData.getProductType());
                        if (null == defaultSample) {
                            throw new BusinessException(planProcessingOrder.getCode() + ",圆棒返切中样片默认值维护不存在，请先配置样片默认值");
                        }
                        if (productionBackCuttingRecord.getCause() != null && productionBackCuttingRecord.getCause().contains("返切不复测")) {
                            Boolean headFlag = planProcessingOrder.getCode().endsWith("T");
                            Boolean tailFlag = planProcessingOrder.getCode().endsWith("A");
                            //根据晶段所在晶棒的编码查询整棒中所有晶段
                            List<YbInspectData> sectionNos = ybInspectDataService.getInspectDatasByCrystalNo(ybInspectData.getCrystalNo());
                            //全部赋默认值
                            for (YbInspectData inspect : sectionNos) {
                                if (headFlag) {
                                    inspect.setOxygenContentHead(NumberUtil.Object2BigDecimal(defaultSample.getOxygenCenterHead(), null));
                                    inspect.setOxygenContentFirsta(NumberUtil.Object2BigDecimal(defaultSample.getOxygenCenterHead(), null));
                                    //注释W氧含量中心 赋默认值
                                    // inspect.setOxygenContentTail(NumberUtil.Object2BigDecimal(defaultSample.getOxygenCenterTail(), null));
                                }
                                if (tailFlag) {
                                    //inspect.setCarbonContentHead(NumberUtil.Object2BigDecimal(defaultSample.getCarbonCenterHead(), null));
                                    inspect.setCarbonContentTail(NumberUtil.Object2BigDecimal(defaultSample.getCarbonCenterTail(), null));
                                    inspect.setOxygenContentEndb(NumberUtil.Object2BigDecimal(defaultSample.getCarbonCenterTail(), null));
                                }
                                //添加判断，站点在检验需要评级
                                List<WipStorage> wipStorageList = wipStorageService.findByProcessingByOrderCode(inspect.getSectionNo());
                                if (!CollectionUtils.isEmpty(wipStorageList)) {
                                    WipStorage wipStorage = wipStorageList.get(0);
                                    if (StringUtils.equals(wipStorage.getProcessName(), EnumValuesFactory.WipStorageCode.圆棒检验.getValue())) {
                                        inspectMaps.put(inspect.getSectionNo(), inspect);
                                    }
                                }
                            }
                        }
                        //重新设置返切后长度
                       /* ybInspectData.setActualLength(productionBackCuttingRecord.getBackLength());
                        List<DictionaryItem> dictionaryItems = dictionaryItemService.findByThemeValueAndItemName(Constants.WEIGHT_RATIO, ybInspectData.getProductTypeSecond(), true);
                        if (!CollectionUtils.isEmpty(dictionaryItems)) {
                            BigDecimal weightLossCoefficient = NumberUtil.Object2BigDecimal(dictionaryItems.get(0).getValue());
                            if (null != weightLossCoefficient && weightLossCoefficient.compareTo(BigDecimal.ONE) > 0) {
                                ybInspectData.setTheoryWeight(productionBackCuttingRecord.getBackLength().divide(weightLossCoefficient, 2, RoundingMode.CEILING));
                            }
                        }*/
                        //调整业务，新增返切编号单晶
                        YbInspectData ybInspectDataBackNew = new YbInspectData();
                        BeanUtil.copyBeanPropWithNullValue(ybInspectDataBackNew, ybInspectData, "id");
                        //返切编号加一
                        ybInspectDataBackNew.setSectionNo(ybInspectData.getSectionNo() + "1");
                        ybInspectDataBackNew.setActualLength(productionBackCuttingRecord.getBackLength());
                        List<DictionaryItem> dictionaryItems = dictionaryItemService.findByThemeValueAndItemName(Constants.WEIGHT_RATIO, ybInspectDataBackNew.getProductTypeSecond(), true);
                        if (!CollectionUtils.isEmpty(dictionaryItems)) {
                            BigDecimal weightLossCoefficient = NumberUtil.Object2BigDecimal(dictionaryItems.get(0).getValue());
                            if (null != weightLossCoefficient && weightLossCoefficient.compareTo(BigDecimal.ONE) > 0) {
                                ybInspectDataBackNew.setTheoryWeight(productionBackCuttingRecord.getBackLength().divide(weightLossCoefficient, 3,  RoundingMode.HALF_UP));
                            }
                        }
                        ybInspectDataBackNew.setBackCut(0);
                        ybInspectDataBackNew.setOxygenContentHead(NumberUtil.Object2BigDecimal(defaultSample.getOxygenCenterHead(), null));
                        //注释W氧含量中心 赋默认值
                        // ybInspectDataBackNew.setOxygenContentTail(NumberUtil.Object2BigDecimal(defaultSample.getOxygenCenterTail(), null));
                      /*  ybInspectDataBackNew.setCarbonContentHead(NumberUtil.Object2BigDecimal(defaultSample.getCarbonCenterHead(), null));
                        ybInspectDataBackNew.setCarbonContentTail(NumberUtil.Object2BigDecimal(defaultSample.getCarbonCenterTail(), null));*/

                        ybInspectDataService.saveOrUpdate(ybInspectDataBackNew);

                        inspectMaps.put(ybInspectDataBackNew.getSectionNo(), ybInspectDataBackNew);

                        //重新评级 未确认是否重新评级，需求说不需要，开发说需要。未讨论出最终结果
                        if (inspectMaps.size() != 0) {
                            gradeService.execGrade(inspectMaps);
                        }
                        //过站 - 圆棒检验 进站
                        //先出返切站点，再进圆棒检验
                        wipStorageService.inStation(ybInspectDataBackNew.getSectionNo(), ybInspectDataBackNew.getDeviceNo(), false);
//                    	wipStorageService.inStation(planProcessingOrder.getCode(), planProcessingOrder.getEquipmentCode(),false);
                    }else {
                        //添加字段,过滤掉未检验返切数据
                        if (null == productionBackCuttingRecord.getInspectionMark() || productionBackCuttingRecord.getInspectionMark() == 0){

                            //反切碳氧和电阻少子赋值
                            if (StringUtils.isNotBlank(productionBackCuttingRecord.getCause())){
                                DictionaryItem dictionaryItem = dictionaryItemService.findNameByThemeValueAndItemValueAndEnable(Constants.YB_RECUT_TYPE, productionBackCuttingRecord.getCause(),true);
                                if (null != dictionaryItem){
                                    YbInspectData ybInspectData = ybInspectDataService.findBySectionNo(planProcessingOrder.getCode());
                                    if (null == ybInspectData) {
                                        throw new BusinessException(planProcessingOrder.getCode() + ",检验记录不存在，请先核对单晶数据是否人为删除！");
                                    }
                                    List<ProductionPaintingLineDetail> byOperateDrawId = productionPaintingLineDetailService.findByOperateReversecutDrawId(productionBackCuttingRecord.getId());
                                    this.handleReverseOxygenAndResistance(dictionaryItem,byOperateDrawId,ybInspectData);
                                }
                            }

                        }
                    }
                    return ResultGenerator.success();
                }
            } else {
                //方棒反切画线记录
                ReCut reCut = fbReCutService.findBySectionNoAndStatus(planProcessingOrder.getCode(), 0);
                if (reCut == null || reCut.getStatus()) {
                    throw new BusinessException(planProcessingOrder.getCode() + "不存在未切断的反切划线信息，请检查数据");
                }
                List<ProductionPaintingLineDetail> recutDetail = productionPaintingLineDetailService.findByOperateRecutDrawIdFb(reCut.getId());

//                boolean backCutType = reCut.getRecutType() == 2;
//                if (backCutType) {
                setProcessingOrderNewDtoV2(processingOrderNewDtos, recutDetail);
//                } else {
//                    for (ProductionPaintingLineDetail productionPaintingLineDetail : recutDetail) {
//                        if (productionPaintingLineDetail.getType() == EnumValuesServer.LineType.晶段.getKey()) {
//                            planProcessingOrder.setWeight(productionPaintingLineDetail.getWeight());
//                            planProcessingOrder.setLength(productionPaintingLineDetail.getLength());
//                            break;
//                        }
//                    }
//                }
                reCut.setStatus(true);
                fbReCutService.saveOrUpdate(reCut);
                Result result = getResult(sendEapCutCraft, processingOrderNewDtos, planProcessingOrder, null, null, reCut, null);
                //返切自动进站添加
                if (GlobalSwitch.enable(GlobalSwitchNamespace.NAMESPACE_YB_CHECK, "AutomaticReturnStationCheck", true)) {
                    this.handleAutomaticVerificationGeneration(reCut,recutDetail);
                }
                return result;            }
        } else {
            throw new BusinessException("该工单不支持过截断站");
        }
    }

    private void handleAutomaticVerificationGeneration(ReCut reCut,List<ProductionPaintingLineDetail> recutDetail){
        if (null == reCut || CollectionUtils.isEmpty(recutDetail) ||
                !StringUtils.equals(reCut.getProcessCode(), EnumValuesFactory.WipStorageCode.方棒检验.getValue())){
            return;
        }
        String segmentNo = reCut.getSegmentNo();
        List<BackcutInspectionDto> saveInfo = new ArrayList<>();
        for (ProductionPaintingLineDetail productionPaintingLineDetail : recutDetail){
            if (null != productionPaintingLineDetail.getType() && productionPaintingLineDetail.getType() == EnumValuesServer.LineType.晶段.getKey()){
                BackcutInspectionDto backcutInspectionDto = new BackcutInspectionDto();
                backcutInspectionDto.setSectionNo(segmentNo);
                backcutInspectionDto.setNo(productionPaintingLineDetail.getNo());
                backcutInspectionDto.setWeight(productionPaintingLineDetail.getWeight());
                backcutInspectionDto.setLength(productionPaintingLineDetail.getLength());
                backcutInspectionDto.setDiameter(productionPaintingLineDetail.getDiameter());
                backcutInspectionDto.setIsCut(productionPaintingLineDetail.getIsCut());
                backcutInspectionDto.setType(productionPaintingLineDetail.getType());
                backcutInspectionDto.setRemark(productionPaintingLineDetail.getRemark());
                backcutInspectionDto.setCheckUserName(BaseContextHandler.getUsername());
                saveInfo.add(backcutInspectionDto);
            }
        }
        if (saveInfo.size() == 0){
            return;
        }
        fbFeignClients.saveBackcutInspection(saveInfo);
        for (BackcutInspectionDto backcutInspectionDto : saveInfo){
            //进站操作
            wipStorageService.inStation(backcutInspectionDto.getNo(), null, false);
        }
    }

    private void handleReverseOxygenAndResistance(DictionaryItem dictionaryItem, List<ProductionPaintingLineDetail> handleDetail,YbInspectData ybInspectData){
        if (null == dictionaryItem || CollectionUtils.isEmpty(handleDetail) || null == ybInspectData){
            log.info("handleReverseOxygenAndResistance 方法传入参数为空！");
            return;
        }
        List<DictionaryItem> dictionaryItems = dictionaryItemService.findByThemeValueAndItemName(Constants.WEIGHT_RATIO, ybInspectData.getProductTypeSecond(), true);
        if (CollectionUtils.isEmpty(dictionaryItems)){
            log.info("理论重量系数为空！");
            return;
        }
        BigDecimal weightLossCoefficient = NumberUtil.Object2BigDecimal(dictionaryItems.get(0).getValue());
        Boolean signEntry = StringUtils.equals(dictionaryItem.getExtendValue1(),"0");
        if (StringUtils.isNotBlank(dictionaryItem.getExtendValue1()) && signEntry){
            this.hadleYbInspectDataNew(handleDetail,ybInspectData,weightLossCoefficient,dictionaryItem.getExtendValue());
        }
    }

    private void hadleYbInspectDataNew(List<ProductionPaintingLineDetail> handleDetail,YbInspectData ybInspectData, BigDecimal weightLossCoefficient, String extendValue1){
        if (CollectionUtils.isEmpty(handleDetail) || null == ybInspectData || null == weightLossCoefficient){
            return;
        }
        DefaultSample defaultSample = defaultSampleService.findByDopantLikeAndSpecificationsLikeAndProductTypeLike(ybInspectData.getDopant(), ybInspectData.getProductTypeSecond(), ybInspectData.getProductType());
        Date date = new Date();
        handleDetail.forEach(productionPaintingLineDetail -> {
            if (productionPaintingLineDetail.getType() == EnumValuesServer.LineType.晶段.getKey()){
                YbInspectData ybInspectDataNew = new YbInspectData();
                switch (extendValue1){
                    case "1":
                        BeanUtil.copyProperties(ybInspectData, ybInspectDataNew, "id", "productLevel", "checkReback", "reduceCrystalLength");
                        break;
                    case "2":
                        BeanUtil.copyProperties(ybInspectData, ybInspectDataNew, "id", "productLevel", "checkReback", "reduceCrystalLength","oxygenContentHead");
                        break;
                    case "3":
                        BeanUtil.copyProperties(ybInspectData, ybInspectDataNew, "id", "productLevel", "checkReback", "reduceCrystalLength","oxygenContentHead");
                        ybInspectDataNew.setOxygenContentHead(NumberUtil.Object2BigDecimal(defaultSample.getOxygenCenterHead(), null));
                        break;
                    case "4":
                        BeanUtil.copyProperties(ybInspectData, ybInspectDataNew, "id", "productLevel", "checkReback", "reCheckType", "reduceCrystalLength",
                                "materialLoss", "meanResistivityA", "meanCarrierLifetimeA", "resistivityAOne", "resistivityATwo", "resistivityAThree", "carrierLifetimeAOne",
                                "carrierLifetimeATwo", "carrierLifetimeAThree","meanResistivityB", "meanCarrierLifetimeB", "resistivityBOne", "resistivityBTwo", "resistivityBThree",
                                "carrierLifetimeBOne", "carrierLifetimeBTwo", "carrierLifetimeBThree");
                        break;
                    case "5":
                        BeanUtil.copyProperties(ybInspectData, ybInspectDataNew, "id", "productLevel", "checkReback", "reduceCrystalLength","carbonContentTail");
                        break;
                    default:
                        break;
                }
                ybInspectDataNew.setSectionNo(productionPaintingLineDetail.getNo());
                ybInspectDataNew.setBackCut(1);
                ybInspectDataNew.setCheckoutName(EnumValues.CheckoutName.返切复检.getValue());
                ybInspectDataNew.setReCheckType(String.valueOf(NumberUtil.String2Integer(ybInspectData.getReCheckType(), 0) + 1));
                ybInspectDataNew.setActualLength(productionPaintingLineDetail.getLength());
                if (null != productionPaintingLineDetail.getLength()){
                    ybInspectDataNew.setTheoryWeight(productionPaintingLineDetail.getLength().divide(weightLossCoefficient, 3, RoundingMode.HALF_UP));
                    ybInspectDataNew.setActualWeight(productionPaintingLineDetail.getLength().divide(weightLossCoefficient, 3, RoundingMode.HALF_UP));
                }
                ybInspectDataNew.setCreateTime(date);
                ybInspectDataNew.setUpdateTime(date);
                if (StringUtils.isBlank(ybInspectDataNew.getUpdateUser())){
                    ybInspectDataNew.setUpdateUser("自动修改");
                }
                ybInspectDataNew.setInspector(BaseContextHandler.getUsername());
                ybInspectDataService.saveDataAndGrade(ybInspectDataNew);
                wipStorageService.inStation(ybInspectDataNew.getSectionNo(), null, false);
            }
        });
    }

    private Result getResult(boolean sendEapCutCraft, List<ProcessingOrderNewDto> processingOrderNewDtos, PlanProcessingOrder planProcessingOrder, ProductionPaintingLine productionPaintingLine, ProductionBackCuttingRecord productionBackCuttingRecord, ReCut reCut, Integer backCutType) {
//        /**
//         * 不需要产生子批
//         */
//        if (backCutType != null && (backCutType == 3 || backCutType == 2)) {
//            planProcessingOrderService.createPlanProcessingOrder(planProcessingOrder, null, null);
//            //2022-09-26 赵文杰： 将过截断站点的，不产生子批的晶段改反切状态改为false.
//            inspectDataBaseService.updateIsCutBack(0, planProcessingOrder.getCode());
//            Result result = wipStorageService.outStation(planProcessingOrder.getCode(), backCutType == 3 ? "-2" : null, null);
//            if (result.getCode() == ResultCode.SUCCESS.getCode()) {
//                if (sendEapCutCraft) {
//                    return sendEapCutCraft(planProcessingOrder, productionPaintingLine, productionBackCuttingRecord, reCut);
//                }
//            } else {
//                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//            }
//            return result;
//        } else {
        if (backCutType != null && backCutType == 3) {
            String processingOrderCode = planProcessingOrder.getCode();
            List<PlanProcessingOrder> planProcessingOrders = planProcessingOrderDao.findByCodeOrderByIdDesc(processingOrderCode);
            if (planProcessingOrders.size() == 0) {
                throw new BusinessException("工单号【" + processingOrderCode + "】不存在");
            }
            WipStorage wipStorage;
            PlanProcessingOrder planProcessingOrder1 = planProcessingOrders.get(0);
            if (true) {
                if (planProcessingOrder1.getStatus() != EnumValuesFactory.PlanProcessingOrderStatus.加工中.getKey()) {
                    if (!true) {
                        throw new BusinessException("【" + processingOrderCode + "】该工单处于" + EnumValuesFactory.PlanProcessingOrderStatus.getText(planProcessingOrder1.getStatus()) + "，无法操作出站");
                    }
                }
                wipStorage = planProcessingOrder1.getWipStorage();
                if (wipStorage == null) {
                    throw new BusinessException("【" + processingOrderCode + "】该工单没有正在加工记录");
                }
                if (wipStorage.getStatus() == EnumValuesFactory.WipStorageStatus.已出站.getKey()) {
                    throw new BusinessException("【" + processingOrderCode + "】该工单的" + wipStorage.getProcessName() + "工序已是出站状态");
                }
                if (wipStorage.getStatus() == EnumValuesFactory.WipStorageStatus.待进站.getKey()) {
                    throw new BusinessException("【" + processingOrderCode + "】该工单的【" + wipStorage.getProcessName() + "工序为待进站状态，无法操作出站");
                }
            } else {
                wipStorage = planProcessingOrder1.getWipStorage();
                if (wipStorage == null) {
                    throw new BusinessException("【" + processingOrderCode + "】该工单没有正在加工记录");
                }
            }

            if (true) { //true当前工单出站，停止当前工单
                WipStorage currentWipStorage = new WipStorage();
                BeanUtils.copyProperties(wipStorage, currentWipStorage);
                currentWipStorage.setEndTime(new Date());
                currentWipStorage.setStatus(EnumValuesFactory.WipStorageStatus.已出站.getKey());
                currentWipStorage.setOutUserName(BaseContextHandler.getUsername());
                currentWipStorage.setOutUserId(BaseContextHandler.getUserID());
                dao.save(currentWipStorage);
                FactoryModel factoryModel = wipStorageService.getFactoryModel(currentWipStorage.getProcessId(), currentWipStorage.getProcessName());
                processLogService.createProcessLog(currentWipStorage.getProcessingOrderId(), currentWipStorage.getProcessingOrderCode(), currentWipStorage.getEquipmentId(), currentWipStorage.getEquipmentCode(), factoryModel.getName(), 0, "【" + factoryModel.getName() + "】工序出站");

                planProcessingOrder1.setStatus(EnumValuesFactory.PlanProcessingOrderStatus.加工完成.getKey());
                planProcessingOrder1.setRemarks("该晶棒已反切，并截断出站，工单已结束");
                planProcessingOrderService.saveOrUpdate(planProcessingOrder1);
                return ResultGenerator.success();
            }
        } else

        /**
         * 产生子批
         */
            if (processingOrderNewDtos.size() == 0) {
                throw new BusinessException("画线信息不能为空，请检查数据");
            }
        Map<String, String> flowLineLables = new HashMap<>();
        String route = "A";
        if (null != reCut) {

            if (StringUtils.equals(reCut.getProcessCode(), EnumValuesFactory.WipStorageCode.方棒检验.getValue())) {
                route = "B";
            } else if (StringUtils.equals(reCut.getProcessCode(), EnumValuesFactory.WipStorageCode.开方.getValue())) {
                route = "C";
            } else if (StringUtils.equals(reCut.getProcessCode(), EnumValuesFactory.WipStorageCode.磨倒.getValue())) {
                route = "A";
            }
        }
        String finalRoute = route;
        processingOrderNewDtos.forEach(processingOrderNewDto -> flowLineLables.put(processingOrderNewDto.getCode(), finalRoute));


        Result result = wipStorageService.outStation2(planProcessingOrder.getCode(), processingOrderNewDtos, true, flowLineLables);
        if (result.getCode() == ResultCode.SUCCESS.getCode()) {
            if (sendEapCutCraft) {
                return sendEapCutCraft(planProcessingOrder, productionPaintingLine, productionBackCuttingRecord, reCut);
            }

//            SwitchConfig config = GlobalSwitch.switchConfig(CODE_SWITCH, "knifeOffset", false);
//
//            if (config != null && config.isEnable()) {
//                RecutDetail recutDetail = recutDetailService.findBySectionNoFb(planProcessingOrder.getCode());
//                if(null != recutDetail){
//                    //todo 和良正确认下上报的记录表（共用一张表）
//                    //todo 冲销的时候 调用sap的接口不能执行入库逻辑
//                    //todo 和良正做好记录
//                    //todo 工时问题
//                    /**
//                     * 这里目前想到的场景，用于判断是否触发下面这段逻辑
//                     * 1、合格方棒上报后人工操作方棒返切需要冲销
//                     * 2、评级为返切的方棒没上报过，不需要执行这里的冲销
//                     * 3、合格方棒未上报操作了返切，不需要执行这里的冲销
//                     *
//                     * 以下逻辑：记录表里未查询到上报记录就不会执行冲销的逻辑
//                     */
//                    ReportSapGoodsmvt sapGoodsmvt = reportSapGoodsmvtService.findByCrystalNoAndBwartAndProcName(planProcessingOrder.getCode(), "101", "刀剖收货");
//                    ReportSapRecord reportSapRecordWeight = reportSapRecordService.findByFbSectionNoAndBwartAndProcNameAndPushType(planProcessingOrder.getCode(), "101", "刀剖收货", "报工");
//                    if (null != sapGoodsmvt || null != reportSapRecordWeight){
//                        Result<FbCheckOutData> fbCheckOutDataByFbSectionNo = fbFeignClients.findFbCheckOutDataByFbSectionNo(planProcessingOrder.getCode());
//                        if (fbCheckOutDataByFbSectionNo.getCode() == ResultCode.SUCCESS.getCode()) {
//                            FbCheckOutData data = fbCheckOutDataByFbSectionNo.getData();
//                            WarehouseOutputBillBo warehouseOutputBillBo = new WarehouseOutputBillBo();
//                            warehouseOutputBillBo.setType("方棒返切冲销出库");
//                            warehouseOutputBillBo.setAutoAudit(true);
//                            List<WarehouseOutputBillDetailBo> warehouseOutputBillDetailBoList = new ArrayList<>();
//                            WarehouseOutputBillDetailBo warehouseOutputBillDetailBo = new WarehouseOutputBillDetailBo();
//                            warehouseOutputBillDetailBo.setBatchNo(data.getBatchNo());
//                            warehouseOutputBillDetailBo.setMaterialModelCode(data.getMaterialCode());
//
//                            String warehouseCode = null;
//                            Equipment byCode = equipmentService.findByCode(planProcessingOrder.getCode().substring(6, 11));
//                            if (null != byCode) {
//                                DictionaryItem warehouseLocation = dictionaryItemService.findByThemeValueAndNameAndValueAndEnable("WarehouseLocation", byCode.getArea(), byCode.getSeries(), true);
//                                if (null != warehouseLocation) {
//                                    warehouseCode = warehouseLocation.getExtendValue1();
//                                }
//                            }
//                            warehouseOutputBillDetailBo.setWarehouseCode(warehouseCode);
//                            //重量用之前上报的重量
//                            BigDecimal weight;
//                            if(data.getWeight().compareTo(new BigDecimal(0)) > 0){
//                                weight = new BigDecimal(0).subtract(data.getWeight());
//                            } else {
//                                weight = new BigDecimal(0).subtract(data.getTheoryWeightFb());
//                            }
//                            if(null != reportSapRecordWeight){
//                                weight = new BigDecimal(0).subtract(reportSapRecordWeight.getCount());
//                            }
//
//                            warehouseOutputBillDetailBo.setRequireCount(weight);
//                            warehouseOutputBillDetailBo.setOutputCount(weight);
//                            warehouseOutputBillDetailBo.setCrystalNo(planProcessingOrder.getCode());
//                            warehouseOutputBillDetailBoList.add(warehouseOutputBillDetailBo);
//                            warehouseOutputBillBo.setOutputBillDetails(warehouseOutputBillDetailBoList);
//
//                            //线边仓出库
//                            Result<String> stringResult = storeFeignClients.outputApply(warehouseOutputBillBo);
//                            if (stringResult.getCode() == ResultCode.SUCCESS.getCode()) {
//                                Result sendSquareRodInfoResult;
//                                BigDecimal bigDecimal;
//                                if(data.getWeight().compareTo(new BigDecimal(0)) > 0){
//                                    bigDecimal = data.getWeight();
//                                } else {
//                                    bigDecimal = data.getTheoryWeightFb();
//                                }
//                                //保存上报记录
//                                ReportSapRecord reportSapRecord = new ReportSapRecord();
//                                reportSapRecord.setBatcnNo(data.getBatchNo());
//                                reportSapRecord.setBwart("102");
//                                reportSapRecord.setCount(new BigDecimal(0).subtract(bigDecimal));
//                                reportSapRecord.setFbSectionNo(planProcessingOrder.getCode());
//                                reportSapRecord.setMaterialCode(data.getMaterialCode());
//                                reportSapRecord.setOrderNo(data.getOrderNo());
//                                reportSapRecord.setProcName("刀剖收货");
//                                reportSapRecord.setPushTime(new Date());
//                                reportSapRecord.setPushType("冲销");
//                                reportSapRecord.setUnit("KG");
//                                reportSapRecord.setUser(BaseContextHandler.getUsername());
//                                reportSapRecordService.saveOrUpdate(reportSapRecord);
//
//                                //sap冲销
//                                sendSquareRodInfoResult = ybInspectDataService.sendSquareWriteOffAccounts(planProcessingOrder.getCode(), recutDetail.getSectionNo(), new BigDecimal(0).subtract(bigDecimal), BaseContextHandler.getUsername(), "102");
//                                log.info("方棒上报SAP数据结果为:{}", JSONObject.toJSONString(sendSquareRodInfoResult));
//                                if (null == sendSquareRodInfoResult) {
//                                    throw new RuntimeException("SAP产出返回为空！");
//                                }
//                                if (ResultCode.SUCCESS.getCode() != sendSquareRodInfoResult.getCode()) {
//                                    throw new RuntimeException("SAP产出上报失败，异常信息为：" + sendSquareRodInfoResult.getMessage());
//                                }
//                            } else {
//                                throw new RuntimeException("线边仓出库失败，异常信息为：" + stringResult.getMessage());
//                            }
//
//                        } else {
//                            throw new RuntimeException("方棒检验数据查询失败，异常信息为：" + fbCheckOutDataByFbSectionNo.getMessage());
//                        }
//                    }
//                }
//            }

        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return result;
//        }
    }

    private List<SectionNoDetail> execYbJd(PlanProcessingOrder planProcessingOrder, ProductionBackCuttingRecord productionBackCuttingRecord, boolean sendEapCutCraft) {
        List<ProcessingOrderNewDto> processingOrderNewDtos = new ArrayList<>();
        SectionNoDetail section = sectionNoDetailService.findBySectionNo(planProcessingOrder.getCode());
        // 0：不合格反切，1：分段反切，2：拼棒中，未反切的晶段，直接过站，3：全部为回收料，晶段直接报废
        if (productionBackCuttingRecord.getIsInheritSample() != null) {
            productionRecutService.savePieceAndSectionNoDetail(productionBackCuttingRecord, section);
        }
        // 0：不合格反切，1：分段反切，2：拼棒中，未反切的晶段，直接过站，3：全部为回收料，晶段直接报废
        Integer backCutType = productionBackCuttingRecord.getBackCutType();
        List<SectionNoDetail> sectionNoDetails = new LinkedList<>();
        if (backCutType == 2) {
            SectionNoDetail sectionNoDetail = sectionNoDetailService.get(planProcessingOrder.getGoodsId());
            planProcessingOrder.setWeight(sectionNoDetail.getWeight());
            planProcessingOrder.setLength(sectionNoDetail.getLength());
            sectionNoDetails.add(sectionNoDetail);
        } else if (backCutType != 3) {
            sectionNoDetails = sectionNoDetailService.findByParentId(planProcessingOrder.getGoodsId());
            if (sectionNoDetails.size() == 0) {
                throw new BusinessException("的反切划线信息不存在，请检查数据");
            }
            setProcessingOrderNewDto(processingOrderNewDtos, sectionNoDetails);
        } else if (backCutType == 3) {
            sectionNoDetails = sectionNoDetailService.findByParentId(planProcessingOrder.getGoodsId());
            if (sectionNoDetails.size() == 0) {
                throw new BusinessException("的反切划线信息不存在，请检查数据");
            }
            setProcessingOrderNewDto(processingOrderNewDtos, sectionNoDetails);
        }
        productionBackCuttingRecord.setStatus(true);
        productionRecutService.saveOrUpdate(productionBackCuttingRecord);
        //处理开方退料闭环
        //turnstoreInItemService.updateDealBySectionNoAndWithdrawingType(productionBackCuttingRecord.getSegmentNo(), Arrays.asList("退库反切复检".split(",")));
//        if (!productionBackCuttingRecord.getCause().contains("返切不复测")){
        Result result = getResult(sendEapCutCraft, processingOrderNewDtos, planProcessingOrder, null, productionBackCuttingRecord, null, backCutType);
        if (result.getCode() != ResultCode.SUCCESS.getCode()) {
            log.error("execYbJd：" + result.getMessage());
        }
//        }
        return sectionNoDetails;
    }

    /**
     * 拼棒反切过站
     *
     * @param planProcessingOrder
     * @param productionBackCuttingRecord
     * @param sendEapCutCraft
     */
    private Result execYbJdV2(PlanProcessingOrder planProcessingOrder, ProductionBackCuttingRecord productionBackCuttingRecord, boolean sendEapCutCraft) {
        List<ProductionBackCuttingRecord> productionBackCuttingRecords = productionRecutService.findByUuid(productionBackCuttingRecord.getUuid());
        Map<String, List<SectionNoDetail>> stringListMap = new HashMap<>();
        for (ProductionBackCuttingRecord productionBackCuttingRecord1 : productionBackCuttingRecords) {
            if (planProcessingOrder.getCode().equals(productionBackCuttingRecord1.getSegmentNo())) {
                List<SectionNoDetail> sectionNoDetails = execYbJd(planProcessingOrder, productionBackCuttingRecord1, sendEapCutCraft);
                stringListMap.put(planProcessingOrder.getCode(), sectionNoDetails);
            } else {
                PlanProcessingOrderWipStorageDto result = wipStorageService.selectWipStorage(productionBackCuttingRecord1.getSegmentNo(), EnumValuesFactory.WipStorageCode.圆棒截断.getKey(), true);
                List<SectionNoDetail> sectionNoDetails = execYbJd(result.getPlanProcessingOrder(), productionBackCuttingRecord1, sendEapCutCraft);
                stringListMap.put(result.getPlanProcessingOrder().getCode(), sectionNoDetails);
            }
        }
        List<String> positionsArr = new LinkedList<>();
        if (StringUtils.isNotBlank(productionBackCuttingRecord.getPositions())) {
            positionsArr = Arrays.asList(productionBackCuttingRecord.getPositions().split(","));
        }
        List<String> sectionComposeArr = new LinkedList<>();
        if (StringUtils.isNotBlank(productionBackCuttingRecord.getSectionCompose())) {
            sectionComposeArr = Arrays.asList(productionBackCuttingRecord.getSectionCompose().split(","));
        }
        //旧的拼棒关系进行解绑
        extracted(sectionComposeArr, productionBackCuttingRecord.getSectionCompose());
        LinkedHashSet<String> sectionComposeArrNew = new LinkedHashSet<>();
        for (int index = 1; index < sectionComposeArr.size(); index++) {
            if (!positionsArr.contains(index + "")) {
                //第一颗的最后一颗
                String sectionNoOne = stringListMap.get(sectionComposeArr.get(index - 1)).get(stringListMap.get(sectionComposeArr.get(index - 1)).size() - 1).getSectionNo();
                //第二颗的第一颗
                String sectionNoTwo = stringListMap.get(sectionComposeArr.get(index)).get(0).getSectionNo();
                if (!sectionComposeArr.contains(sectionNoOne)) {
                    throw new BusinessException(sectionNoOne + "没有检验数据，无法自动拼棒");
                }
                sectionComposeArrNew.add(sectionNoOne);
                if (!sectionComposeArr.contains(sectionNoTwo)) {
                    throw new BusinessException(sectionNoTwo + "没有检验数据，无法自动拼棒");
                }
                sectionComposeArrNew.add(sectionNoTwo);
            } else {
                // 提交现有的拼棒反切
                if (sectionComposeArrNew.size() > 1) {
                    sectionService.stickTogetherV2(new LinkedList<>(sectionComposeArrNew), 0);
                }
                sectionComposeArrNew = new LinkedHashSet<>();
            }
        }
        // 提交现有的拼棒反切
        if (sectionComposeArrNew.size() > 1) {
            sectionService.stickTogetherV2(new LinkedList<>(sectionComposeArrNew), 0);
        }
        return ResultGenerator.success();
    }


    private void extracted(List<String> sectionNos, String sectionNoGroup) {
        //删除拼圆棒中间表
        spellInfoService.deleteBySectionNos(sectionNos);
        String sectionType = "非标棒";
        //2022年4月5日10:14:40，修改方棒检验数据库，修复解绑圆棒，方棒反切无法操作，暂时没做工单类型区分，原本功能检验暂时也做更改，因为部分单晶站点过不去，需要重新绑定
        inspectDataBaseService.updateSticksCountFbSectionNoListFromYb(sectionNos, 1, null, sectionType, null);
        //更改圆棒检验拼棒字段，并且重新下发评级
        List<YbInspectData> inspectDataBases = new ArrayList<>();
        for (String sectionNo : sectionNos) {
            YbInspectData inspectDataBase = inspectDataBaseService.findBySectionNo(sectionNo);
            inspectDataBase.setSticksCount(1);
            inspectDataBase.setSpellBarLength(null);
            inspectDataBase.setSectionType(sectionType);
            inspectDataBase.setSectionCompose(null);
            inspectDataBases.add(inspectDataBase);
        }
        //优先保存，确保保存成功，在重新下发评级
        inspectDataBaseService.saveAll(inspectDataBases);
        sectionDAO.updateStateBySectionNoGroup(sectionNoGroup, BaseContextHandler.getUserID(), BaseContextHandler.getUsername(), new Date(), "拼棒反切");
        //重新下发评级，圆棒评级下发
        for (YbInspectData inspectDataBase : inspectDataBases) {
            publishRankResultService.publishRankResult(inspectDataBase, inspectDataBase.getActualWeight(), inspectDataBase.getTheoryWeight());
        }
    }

    private void setProcessingOrderNewDtoV2(List<ProcessingOrderNewDto> processingOrderNewDtos, List<ProductionPaintingLineDetail> productionPaintingLineDetails) {
        for (ProductionPaintingLineDetail sectionNoDetail : productionPaintingLineDetails) {
            if (sectionNoDetail.getType() == EnumValuesServer.LineType.晶段.getKey()) {
                ProcessingOrderNewDto processingOrderNewDto = new ProcessingOrderNewDto();
                processingOrderNewDto.setCode(sectionNoDetail.getNo());
                processingOrderNewDto.setLength(sectionNoDetail.getLength());
                processingOrderNewDto.setWeight(sectionNoDetail.getWeight());
                RecutDetail recutDetail = recutDetailService.findBySectionNoFb(sectionNoDetail.getNo());
                if (recutDetail != null) {
                    processingOrderNewDto.setGoodsId(recutDetail.getId());
                }
                processingOrderNewDto.setOrderType(EnumValuesFactory.PlanProcessingOrderOrderType.晶段.getKey());
                processingOrderNewDtos.add(processingOrderNewDto);
            }
        }
    }


    private void setProcessingOrderNewDtoV3(List<ProcessingOrderNewDto> processingOrderNewDtos, ProductionPaintingLineDetail productionPaintingLineDetail) {
        if (productionPaintingLineDetail.getType() == EnumValuesServer.LineType.晶段.getKey()) {
            ProcessingOrderNewDto processingOrderNewDto = new ProcessingOrderNewDto();
            processingOrderNewDto.setCode(productionPaintingLineDetail.getNo());
            processingOrderNewDto.setLength(productionPaintingLineDetail.getLength());
            processingOrderNewDto.setWeight(productionPaintingLineDetail.getWeight());
            RecutDetail recutDetail = recutDetailService.findBySectionNoFb(productionPaintingLineDetail.getNo());
            if (recutDetail != null) {
                processingOrderNewDto.setGoodsId(recutDetail.getId());
            }
            processingOrderNewDto.setOrderType(EnumValuesFactory.PlanProcessingOrderOrderType.晶段.getKey());
            processingOrderNewDtos.add(processingOrderNewDto);
        }
    }


    @Override
    public void setProcessingOrderNewDto(List<ProcessingOrderNewDto> processingOrderNewDtos, List<SectionNoDetail> sectionNoDetails) {
        for (SectionNoDetail sectionNoDetail : sectionNoDetails) {
            ProcessingOrderNewDto processingOrderNewDto = new ProcessingOrderNewDto();
            processingOrderNewDto.setCode(sectionNoDetail.getSectionNo());
            processingOrderNewDto.setLength(sectionNoDetail.getLength());
            ProductionPaintingLineDetail bySegmentNo = productionPaintingLineDetailService.findBySegmentNo(sectionNoDetail.getSectionNo());
            if (bySegmentNo == null) {
                throw new BusinessException("未查询到画线信息");
            }
            if (sectionNoDetail.getWeight() != null) {
                processingOrderNewDto.setWeight(sectionNoDetail.getWeight());
            } else {
                //重量为空根据系数计算理论重量
                DictionaryItem weightRatio = dictionaryItemService.findByThemeValueAndNameAndEnable("WeightRatio", sectionNoDetail.getSpecs(), true);
                if (weightRatio == null) {
                    throw new BusinessException("【" + sectionNoDetail.getSpecs() + "】规格重量理论系数未配置");
                }
                try {
                    processingOrderNewDto.setWeight(bySegmentNo.getLength().divide(new BigDecimal(weightRatio.getValue()), 3, RoundingMode.HALF_UP));
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new BusinessException("计算理论重量失败：规格为：【" + sectionNoDetail.getSpecs() + "】,系数为：【" + weightRatio.getValue() + "】长度为：【" + bySegmentNo.getLength() + "】");
                }
            }
            processingOrderNewDto.setGoodsId(sectionNoDetail.getId());
            processingOrderNewDto.setOrderType(EnumValuesFactory.PlanProcessingOrderOrderType.晶段.getKey());
            processingOrderNewDto.setIsCut(bySegmentNo.getIsCut());
            if (null != sectionNoDetail.getSectionType() && sectionNoDetail.getSectionType().equals(EnumValuesServer.LineType.回收料.getValue())) {
                continue;
            }
            processingOrderNewDtos.add(processingOrderNewDto);
        }
    }

    @Override
    public Result execKfOut(List<String> sectionNoArr, PlanProcessingOrderWipStorageDto result, String flowLineLable, String wipStorageCode) {
        for (String sectionNo : sectionNoArr) {
            if (StringUtils.isNotBlank(sectionNo) && result.getPlanProcessingOrder().getCode().equals(sectionNo)) {
                wipStorageYbService.execKfOut(sectionNo, flowLineLable, result.getPlanProcessingOrder());
            } else {
                PlanProcessingOrderWipStorageDto resultOther = wipStorageService.selectWipStorage(sectionNo, wipStorageCode, true);
                FactoryModel factoryModelOther = wipStorageService.getFactoryModel(resultOther.getWipStorage().getProcessId(), resultOther.getWipStorage().getProcessName());
                if (factoryModelOther != null && factoryModelOther.getCode().equals(EnumValuesFactory.WipStorageCode.开方.getKey())) {
                    wipStorageYbService.execKfOut(sectionNo, flowLineLable, resultOther.getPlanProcessingOrder());
                } else {
                    throw new BusinessException("【" + sectionNo + "】：拼棒中的，这个编号不在开方站点");
                }
            }
        }
        return ResultGenerator.success();
    }

    /**
     * 获取折重系数
     *
     * @param diameter
     * @return
     */
    private BigDecimal getWeightLossCoefficient(String diameter) {
        List<DictionaryItem> dictionaryItems = dictionaryItemService.findByThemeValueAndItemName(Constants.WEIGHT_RATIO, diameter, true);
        if (dictionaryItems.size() == 0) {
            throw new BusinessException("请配置【" + diameter + "】规格的理论重量系数");
        }
        BigDecimal weightLossCoefficient = NumberUtil.Object2BigDecimal(dictionaryItems.get(0).getValue());
        if (weightLossCoefficient == null || weightLossCoefficient.compareTo(new BigDecimal(0)) < 0) {
            throw new BusinessException("【" + dictionaryItems.get(0).getValue() + "】理论重量系数格式不正确，只能为大于0的数字类型");
        }
        return weightLossCoefficient;
    }

    /**
     * 截断出站，上传加工记录
     *
     * @param
     * @return
     */
    private Result sendEapCutCraft(PlanProcessingOrder planProcessingOrder, ProductionPaintingLine productionPaintingLine, ProductionBackCuttingRecord productionBackCuttingRecord, ReCut reCut) {
        EapCutCraftDto eapCutCraftDto = new EapCutCraftDto();
        //设备
        eapCutCraftDto.setEquipNo(planProcessingOrder.getWipStorage().getEquipmentCode());
        //单晶编号
        eapCutCraftDto.setRoundSn(planProcessingOrder.getCode());
        //截断出站时间
        eapCutCraftDto.setEndCut(new Date());
        eapCutCraftDto.setStartCut(new Date());
        //截断出站操作人
        eapCutCraftDto.setCutOperator(BaseContextHandler.getUsername());
        //截断出站操作人班组
        eapCutCraftDto.setShift(BaseContextHandler.getUserTeamGroup());
        //判断单晶来源1:炉次 2:单晶 3: 晶段
        eapCutCraftDto.setType(planProcessingOrder.getOrderType());
        //物料类型 0：圆棒，1：方棒
        eapCutCraftDto.setCrystalType(planProcessingOrder.getMaterialType());
        ClassMonitorModelLog byTeamName = classMonitorModelLogService.findByTeamName(eapCutCraftDto.getShift());
        if (byTeamName != null) {
            eapCutCraftDto.setUserRealName(byTeamName.getUserRealName());
        }
        //查询数据字典长度范围对照表 product_length
        DictionaryItem item = null;
        if (eapCutCraftDto.getRoundSn() != null && eapCutCraftDto.getRoundSn().length() > 7) {
            //获取
            String str = eapCutCraftDto.getRoundSn().substring(5, 8);
            item = dictionaryItemService.findByThemeValueAndNameAndEnable("WeightFractions", str, true);
        }
        //长晶棒过截断
        if (eapCutCraftDto.getType() != null && eapCutCraftDto.getType() == 2) {
            if (productionPaintingLine != null) {
                if (item != null) {
                    BigDecimal lineLength = productionPaintingLine.getValidLength() == null ? BigDecimal.valueOf(0) : productionPaintingLine.getValidLength();
                    BigDecimal xiShu = BigDecimal.valueOf(Double.parseDouble(item.getValue()));
                    eapCutCraftDto.setTheoryWeight(lineLength.divide(xiShu, 2, BigDecimal.ROUND_HALF_UP));
                }
                //晶棒长度
                eapCutCraftDto.setRoundLength(productionPaintingLine.getValidLength());
                int SliceNum = 0;
                List<ProductionPaintingLineDetail> byOperateDrawId = productionPaintingLineDetailService.findByOperateDrawId(productionPaintingLine.getId());
                if (byOperateDrawId != null) {
                    eapCutCraftDto.setNormalNum(byOperateDrawId.size() - 1);
                    for (ProductionPaintingLineDetail productionPaintingLineDetail : byOperateDrawId) {
                        if (productionPaintingLineDetail.getType() != null && productionPaintingLineDetail.getType() == 1) {
                            SliceNum++;
                        }
                    }
                    eapCutCraftDto.setLineNum(byOperateDrawId.size());
                }
                eapCutCraftDto.setKnifeNum(productionPaintingLine.getLineNum());
                eapCutCraftDto.setSliceNum(SliceNum);
                eapCutCraftDto.setIsCut(1);
            }
        }
        // 圆棒晶段反切过截断
        else if (eapCutCraftDto.getType() != null && eapCutCraftDto.getCrystalType() != null && eapCutCraftDto.getType() == 3 && eapCutCraftDto.getCrystalType() == 0) {
            if (productionBackCuttingRecord != null) {
                if (item != null) {
                    BigDecimal lineLength = productionBackCuttingRecord.getBarLength() == null ? BigDecimal.valueOf(0) : productionBackCuttingRecord.getBarLength();
                    BigDecimal xiShu = BigDecimal.valueOf(Double.parseDouble(item.getValue()));
                    eapCutCraftDto.setTheoryWeight(lineLength.divide(xiShu, 2, BigDecimal.ROUND_HALF_UP));
                }
                //晶棒长度
                eapCutCraftDto.setRoundLength(productionBackCuttingRecord.getBarLength());
                eapCutCraftDto.setReverseNum(productionBackCuttingRecord.getKnifeNum());
                int sliceNum = 0;
                int knifeNum = 0;
                List<ProductionPaintingLineDetail> list = productionPaintingLineDetailService.findByOperateReversecutDrawId(productionBackCuttingRecord.getId());
                if (list != null) {
                    eapCutCraftDto.setLineNum(list.size());
                    for (ProductionPaintingLineDetail productionPaintingLineDetail : list) {
                        if (productionPaintingLineDetail.getType() != null && productionPaintingLineDetail.getType() == 1) {
                            sliceNum++;
                        }
                        if (productionPaintingLineDetail.getType() != null && productionPaintingLineDetail.getType() == 0) {
                            knifeNum++;
                        }
                    }
                }
                eapCutCraftDto.setKnifeNum(knifeNum);
                eapCutCraftDto.setSliceNum(sliceNum);
                eapCutCraftDto.setCause(productionBackCuttingRecord.getCause());
                eapCutCraftDto.setIsCut(0);
            }
        }
        // 方棒晶段反切过截断
        else if (eapCutCraftDto.getType() != null && eapCutCraftDto.getCrystalType() != null && eapCutCraftDto.getType() == 3 && eapCutCraftDto.getCrystalType() == 1) {
            if (reCut != null) {
                if (item != null) {
                    BigDecimal lineLength = reCut.getSegmentNoLength() == null ? BigDecimal.valueOf(0) : reCut.getSegmentNoLength();
                    BigDecimal xiShu = BigDecimal.valueOf(Double.parseDouble(item.getValue()));
                    eapCutCraftDto.setTheoryWeight(lineLength.divide(xiShu, 2, BigDecimal.ROUND_HALF_UP));
                }
                //晶棒长度
                eapCutCraftDto.setRoundLength(reCut.getSegmentNoLength());
                eapCutCraftDto.setReverseNum(reCut.getCutNum() != null && isInteger(reCut.getCutNum()) ? Integer.parseInt(reCut.getCutNum()) : 0);
                int sliceNum = 0;
                int knifeNum = 0;
                List<ProductionPaintingLineDetail> list = productionPaintingLineDetailService.findByOperateRecutDrawIdFb(reCut.getId());
                if (list != null) {
                    eapCutCraftDto.setLineNum(list.size());
                    for (ProductionPaintingLineDetail productionPaintingLineDetail : list) {
                        if (productionPaintingLineDetail.getType() != null && productionPaintingLineDetail.getType() == 1) {
                            sliceNum++;
                        }
                        if (productionPaintingLineDetail.getType() != null && productionPaintingLineDetail.getType() == 0) {
                            knifeNum++;
                        }
                    }
                }
                eapCutCraftDto.setKnifeNum(knifeNum);
                eapCutCraftDto.setSliceNum(sliceNum);
                eapCutCraftDto.setCause(reCut.getReason());
                eapCutCraftDto.setIsCut(0);
            }
        }
        //截断信息上传
        Result cutCraftArtificialUpload = fbFeignClients.cutCraftArtificialUpload(eapCutCraftDto);
        //截断信息上传失败，手动回滚过站信息
        if (cutCraftArtificialUpload.getCode() != ResultCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultGenerator.fail("截断信息上传失败：" + cutCraftArtificialUpload.getMessage());
        }
        return cutCraftArtificialUpload;
    }

    /**
     * 判断字符串是否是整数
     */
    private boolean isInteger(String value) {
        try {
            Integer.parseInt(value);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * pad 通用进站
     *
     * @param deviceCode     设备编号
     * @param wipStorageCode 站点代码
     * @return
     */
    @Override
    public Result padInStation(List<String> processingOrderCodes, String deviceCode, String wipStorageCode) {
        Map<String, PlanProcessingOrderWipStorageDto> planProcessingOrderWipStorageDtoMap = new HashMap<>();
        for (String processingOrderCode : processingOrderCodes) {
            PlanProcessingOrderWipStorageDto planProcessingOrderWipStorageDto = wipStorageService.selectWipStorage(processingOrderCode, wipStorageCode, false);
            planProcessingOrderWipStorageDtoMap.put(processingOrderCode, planProcessingOrderWipStorageDto);
        }
        Date date = new Date();
        for (String processingOrderCode : processingOrderCodes) {

            Result<FbScheduleDto> fbScheduleDtoResult = fbFeignClients.findByDeviceNo(deviceCode);
            if (StringUtils.equals(wipStorageCode, EnumValuesFactory.WipStorageCode.毛棒截断.getKey()) || StringUtils.equals(wipStorageCode, EnumValuesFactory.WipStorageCode.开方.getKey())) {
                CrystalMaterialRelation crystalMaterialRelation = null;
                if (null != fbScheduleDtoResult && ResultCode.SUCCESS.getCode() == fbScheduleDtoResult.getCode() && null != fbScheduleDtoResult.getData()) {
                    FbScheduleDto fbScheduleDtoResultData = fbScheduleDtoResult.getData();
                    crystalMaterialRelation = new CrystalMaterialRelation();
                    crystalMaterialRelation.setDeviceNo(deviceCode);
                    crystalMaterialRelation.setSectionNo(processingOrderCode);
                    crystalMaterialRelation.setDeviceType(StringUtils.equals(wipStorageCode, EnumValuesFactory.WipStorageCode.毛棒截断.getKey()) ? EnumValuesFactory.DeviceCategory.截断机.getKey() : EnumValuesFactory.DeviceCategory.开方机.getKey());
                    crystalMaterialRelation.setMaterialCode(fbScheduleDtoResultData.getMatnr());
                    crystalMaterialRelation.setOrderNo(fbScheduleDtoResultData.getOrderNo());
                    crystalMaterialRelation.setGmtCreate(date);
                    if (null != fbScheduleDtoResultData.getMaterialModelId()) {
                        crystalMaterialRelation.setMaterialModelId(fbScheduleDtoResultData.getMaterialModelId());
                    }
                } else {
                    throw new BusinessException("设备排程未维护，请先维护排程信息。设备编号为：" + deviceCode);
                }
                //先报工
                this.handleReportConsumption(processingOrderCode, wipStorageCode, deviceCode, fbScheduleDtoResult,crystalMaterialRelation);
            }

            Result result = wipStorageService.inStation(processingOrderCode, deviceCode);
            if (result.getCode() == ResultCode.SUCCESS.getCode()) {
                if (EnumValuesFactory.WipStorageCode.圆棒截断.getKey().equals(wipStorageCode) || StringUtils.equals(wipStorageCode, EnumValuesFactory.WipStorageCode.毛棒截断.getKey())) {
                    //送验车解绑
                    wipStorageService.unbinding(processingOrderCode);

                    //添加解绑记录
                    ProductionBindingTrayLog productionBindingTrayLog = productionBindingTrayLogService.findByCrystalNo(processingOrderCode);
                    if (null != productionBindingTrayLog) {
                        ProductionBindingTrayLog productionBindingTrayLogNew = new ProductionBindingTrayLog();
                        BeanUtil.copyBeanPropWithNullValue(productionBindingTrayLogNew, productionBindingTrayLog, "id");
                        productionBindingTrayLogNew.setIsBinding(2);
                        productionBindingTrayLogNew.setBindingTime(date);
                        productionBindingTrayLogNew.setBindingPeople(BaseContextHandler.getUsername());
                        productionBindingTrayLogNew.setReason("截断过站解绑");
                        productionBindingTrayLogService.saveOrUpdate(productionBindingTrayLogNew);
                    }


                    /**
                     * 截断进站，发送加工记录
                     */
                    EapCutCraftDto eapCutCraftDto = new EapCutCraftDto();
                    //设备
                    eapCutCraftDto.setEquipNo(deviceCode);
                    //单晶编号
                    eapCutCraftDto.setRoundSn(processingOrderCode);
                    //截断出站时间
                    eapCutCraftDto.setStartCut(new Date());
                    //晶棒长度
                    eapCutCraftDto.setRoundLength(planProcessingOrderWipStorageDtoMap.get(processingOrderCode).getPlanProcessingOrder().getLength());

                    try {
                        String no = processingOrderCode.substring(0, 16);
                        LongCrystal byCrystalNo = longCrystalService.findByCrystalNo(no);
                        //重量
                        DictionaryItem weightRatio = dictionaryItemService.findByThemeValueAndNameAndEnable("WeightRatio", byCrystalNo.getSpecs(), true);
                        if (null != weightRatio && com.sw.mes.core.utils.StringUtils.isNotBlank(weightRatio.getValue())){
                            eapCutCraftDto.setTheoryWeight(eapCutCraftDto.getRoundLength().divide(new BigDecimal(weightRatio.getValue()), 3, BigDecimal.ROUND_HALF_UP));
                        }
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                    //截断出站操作人
                    eapCutCraftDto.setCutUpOperator(BaseContextHandler.getUsername());
                    //截断出站操作人班组
                    eapCutCraftDto.setShift(BaseContextHandler.getUserTeamGroup());
                    //判断单晶来源
                    eapCutCraftDto.setType(planProcessingOrderWipStorageDtoMap.get(processingOrderCode).getPlanProcessingOrder().getOrderType());
                    //物料类型 0：圆棒，1：方棒
                    eapCutCraftDto.setCrystalType(planProcessingOrderWipStorageDtoMap.get(processingOrderCode).getPlanProcessingOrder().getMaterialType());
                    //截断信息上传
                    Result cutCraftArtificialUpload = fbFeignClients.cutCraftArtificialUpload(eapCutCraftDto);
                    //截断信息上传失败，手动回滚过站信息
                    if (cutCraftArtificialUpload.getCode() != ResultCode.SUCCESS.getCode()) {
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        return ResultGenerator.fail("截断信息上传失败：" + result.getMessage());
                    }
                } else if (EnumValuesFactory.WipStorageCode.开方.getKey().equals(wipStorageCode)
                        || EnumValuesFactory.WipStorageCode.磨倒.getKey().equals(wipStorageCode)
                ) {
                    EapCutCraftDto eapCutCraftDto = new EapCutCraftDto();
                    //设备
                    eapCutCraftDto.setEquipNo(deviceCode);
                    //单晶编号
                    eapCutCraftDto.setRoundSn(processingOrderCode);
                    eapCutCraftDto.setStartCut(new Date());
                    eapCutCraftDto.setWipStorageCode(wipStorageCode);
                    eapCutCraftDto.setCutUpOperator(BaseContextHandler.getUsername());
                    Result cutCraftArtificialUpload = fbFeignClients.openGrinding(eapCutCraftDto);
                }
            } else {
                throw new BusinessException(result.getMessage());
            }
        }
        return ResultGenerator.success();
    }

    @Override
    public Result execKfOut(String processingOrderCode, String flowLineLable, PlanProcessingOrder planProcessingOrder) {
        Result outResult = wipStorageService.outStation(processingOrderCode, flowLineLable, null);
        if (outResult.getCode() == ResultCode.SUCCESS.getCode()) {
            //开方出站，工单类型变为方棒工单
            planProcessingOrder.setMaterialType(EnumValuesFactory.MaterialType.方棒.getKey());
        /*    //调整重量，开方出站 使用方棒折算系数
            YbInspectData bySectionNo = ybInspectDataService.findBySectionNo(processingOrderCode);
            if (null != bySectionNo){
                List<DictionaryItem> dictionaryItems = dictionaryItemService.findByThemeValueAndItemName(Constants.THEORETICAL_WEIGHT_COEFFICIENTFB, bySectionNo.getProductTypeSecond(), true);
                if (!CollectionUtils.isEmpty(dictionaryItems)) {
                    BigDecimal weightLossCoefficient = NumberUtil.Object2BigDecimal(dictionaryItems.get(0).getValue());
                    if (null != weightLossCoefficient && weightLossCoefficient.compareTo(BigDecimal.ONE) > 0) {
                        if (null != planProcessingOrder.getLength()){
                            planProcessingOrder.setWeight(planProcessingOrder.getLength().divide(weightLossCoefficient, 3, RoundingMode.HALF_UP));
                        }
                    }
                }
            }*/
            planProcessingOrderService.createPlanProcessingOrder(planProcessingOrder, null, null);
            // 找到对应圆棒信息
            List<SectionNoDetail> sectionNoDetails = this.sectionNoDetailDao.findBySectionNo(processingOrderCode);
            if (sectionNoDetails != null && sectionNoDetails.size() > 0) {
                SectionNoDetail sectionNoDetail = sectionNoDetails.get(0);
                RecutDetail recutDetail = recutDetailService.findBySectionNoFb(sectionNoDetail.getSectionNo());
                // 进入开方加工，添加方棒追溯表
                if (recutDetail == null) {
                    recutDetail = new RecutDetail();
                }
                // 圆棒编号
                recutDetail.setSectionNo(processingOrderCode);
                // 方棒编号
                recutDetail.setSectionNoFb(processingOrderCode);
                // 圆棒id
                recutDetail.setYbId(sectionNoDetail.getId());
                // 晶棒id
                recutDetail.setCrystalId(sectionNoDetail.getCrystalId());
                recutDetail.setCreateDate(new Date());
                recutDetail.setCreateUser(BaseContextHandler.getUsername());
                // 保存数据
                recutDetailService.saveOrUpdate(recutDetail);
            }
        }
        return outResult;
    }

    @Override
    public List<String> getSectionNos(Integer materialType, String sectionNo) {
        String sectionCompose;
        List<String> sectionNoArr = new LinkedList<>();
        if (materialType == EnumValuesFactory.MaterialType.圆棒.getKey()) {
            sectionCompose = inspectDataBaseService.getSectionComposeBySectionNo(sectionNo);
        } else {
            Result<String> resultSectionCompose = fbFeignService.getSectionComposeBySectionNo(sectionNo);
            if (resultSectionCompose.getCode() != ResultCode.SUCCESS.getCode()) {
                throw new BusinessException(resultSectionCompose.getMessage());
            }
            sectionCompose = resultSectionCompose.getData();
        }
        if (StringUtils.isNotBlank(sectionCompose)) {
            String[] sectionComposeArr = sectionCompose.split(",");
            sectionNoArr = Arrays.asList(sectionComposeArr);
        } else {
            sectionNoArr.add(sectionNo);
        }
        return sectionNoArr;
    }

    /**
     * 处理截断和开方上报数据
     *
     * @param processingOrderCode
     * @param position
     */
    private void handleReportConsumption(String processingOrderCode, String position, String deviceCode, Result<FbScheduleDto> result,CrystalMaterialRelation crystalMaterialRelationNew) {
        if (null == result || null == result.getData()) {
            throw new BusinessException("设备排程未维护，请先维护排程信息。设备编号为：" + deviceCode);
        }
        FbScheduleDto scheduleDto = result.getData();
        //截断上报
        if (StringUtils.equals(position, EnumValuesFactory.WipStorageCode.毛棒截断.getKey())) {
            LongCrystal byCrystalNo = longCrystalService.findByCrystalNo(processingOrderCode);
            if (null == byCrystalNo || null == byCrystalNo.getWeight()) {
                throw new BusinessException("该设备不存在长晶记录或长晶重量。设备编号为：" + deviceCode);
            }
            // 添加定向非定向 卡控
            this.handleDirectionalControl(byCrystalNo.getOrderNo(),scheduleDto.getOrderNo(),deviceCode);
            this.handleReportSap(result, "截断成品仓", byCrystalNo, processingOrderCode, deviceCode, byCrystalNo.getWeight(), EnumValuesFactory.WipStorageCode.毛棒截断.getValue());
            if (null != crystalMaterialRelationNew){
                //规格添加
                crystalMaterialRelationNew.setSpecs(byCrystalNo.getSpecs());
                crystalMaterialRelationNew.setBatchNo(byCrystalNo.getBatchNo());
                crystalMaterialRelationNew.setWeight( byCrystalNo.getWeight());
                crystalMaterialRelationNew.setReportStatus(EnumValuesFactory.ReportStatusSap.REPORTED.getKey());
                crystalMaterialRelationService.saveOrUpdate(crystalMaterialRelationNew);
            }
        } else if (StringUtils.equals(position, EnumValuesFactory.WipStorageCode.开方.getKey())) {
            YbInspectData bySectionNo = ybInspectDataService.findBySectionNo(processingOrderCode);
            LongCrystal byCrystalNo = longCrystalService.findByCrystalNo(bySectionNo.getCrystalNo());
            String weigth = (null != bySectionNo.getActualWeight() ? bySectionNo.getActualWeight().toString() : bySectionNo.getTheoryWeight().toString());
            CrystalMaterialRelation crystalMaterialRelationFind = crystalMaterialRelationService.findBySectionNo(processingOrderCode);
            if (null == bySectionNo) {
                throw new BusinessException("该设备不存在圆棒检验数据。设备编号为：" + deviceCode);
            }
            if (null == byCrystalNo) {
                throw new BusinessException("该设备圆棒检验数据的长晶棒数据不存在。设备编号为：" + deviceCode);
            }
            //下工序材料仓
            String umlgo = null;
            //成品仓
            String warehouseCode = "";
            //材料仓
            String warehouseCodeMaterial = "";
            Equipment byCode = equipmentService.findByCode(deviceCode);
            if (null != byCode) {
                DictionaryItem warehouseLocation = dictionaryItemService.findByThemeValueAndNameAndValueAndEnable("WarehouseLocation", byCode.getArea(), byCode.getSeries(), true);
                if (null != warehouseLocation) {
                    warehouseCode = warehouseLocation.getExtendValue1();
                    umlgo = warehouseLocation.getExtendValue2();
                    warehouseCodeMaterial = warehouseLocation.getExtendValue();
                }
            }
            CrystalMaterialRelation crystalMaterialRelation = crystalMaterialRelationService.findBySectionNo(bySectionNo.getCrystalNo());
            if (null == crystalMaterialRelation) {
                throw new BusinessException("未经过截断机，排程订单未关联，请核对数据！");
            }
            // 添加定向非定向 卡控
            this.handleDirectionalControl(crystalMaterialRelation.getOrderNo(),scheduleDto.getOrderNo(),deviceCode);
            if (null != crystalMaterialRelationFind && null != crystalMaterialRelationFind.getReportStatus() && crystalMaterialRelationFind.getReportStatus().equals(EnumValuesFactory.ReportStatusSap.REPORTED.getKey())){
                log.info("该单晶已上报，请勿重复上报，单晶编号为：{}",processingOrderCode);
            }else {
                Result<WarehouseInputReturnDto> warehouseInputReturnDtoResult = this.sendWarehouseInputBillBo(byCrystalNo, null != bySectionNo.getActualWeight() ? bySectionNo.getActualWeight() : bySectionNo.getTheoryWeight(), InputBillStatusEnum.截断入库.getValue(), umlgo, warehouseCode, crystalMaterialRelation,processingOrderCode);
                if (null == warehouseInputReturnDtoResult) {
                    throw new BusinessException("设备入库申请失败，返回为空");
                }
                if (warehouseInputReturnDtoResult.getCode() != ResultCode.SUCCESS.getCode()) {
                    log.info("线边仓出库失败:{}", warehouseInputReturnDtoResult.getMessage());
                    throw new BusinessException("设备入库申请失败，异常信息为：" + warehouseInputReturnDtoResult.getMessage());
                }
                String batchNo = byCrystalNo.getBatchNo();
                if (StringUtils.isNotBlank(batchNo) && batchNo.startsWith("TCN") && batchNo.length() >= 10) {
                    batchNo = batchNo.substring(0, 1) + "J" + batchNo.substring(2, 10);
                }
                this.sendReportSapGoodsmvt("101", byCode.getSeries(), crystalMaterialRelation.getOrderNo(), crystalMaterialRelation.getMaterialCode(), batchNo, weigth, "KG", "5041", warehouseCode, processingOrderCode, umlgo, EnumValuesFactory.WipStorageCode.开方.getValue(), deviceCode,null);

                FbScheduleDto fbScheduleDto = result.getData();
                //SAP 消耗
                this.sendReportSapGoodsmvt("261", byCode.getSeries(), fbScheduleDto.getOrderNo(), crystalMaterialRelation.getMaterialCode(), batchNo, weigth, "KG", "5041", warehouseCodeMaterial, processingOrderCode, null, EnumValuesFactory.WipStorageCode.开方.getValue(), deviceCode,null);

            }

            if (null != crystalMaterialRelationNew){
                //规格添加
                crystalMaterialRelationNew.setSpecs(bySectionNo.getProductTypeSecond());
                crystalMaterialRelationNew.setBatchNo(byCrystalNo.getBatchNo());
                crystalMaterialRelationNew.setWeight(bySectionNo.getTheoryWeight());
                crystalMaterialRelationNew.setReportStatus(EnumValuesFactory.ReportStatusSap.REPORTED.getKey());
                crystalMaterialRelationService.saveOrUpdate(crystalMaterialRelationNew);
            }
            Date date = new Date();
            //报工时：上报SAP
            try {
                SwitchConfig config = GlobalSwitch.switchConfig(CODE_SWITCH, "cutOffWorkHour", false);
                if( config.isEnable()){
                    extracted(processingOrderCode, byCrystalNo, crystalMaterialRelation, date);
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.info("截断工时：" + e.getMessage());
            }
            //消耗
            //this.handleReportSap(result, "开方材料仓", byCrystalNo, processingOrderCode,deviceCode,null != bySectionNo.getActualWeight() ? bySectionNo.getActualWeight() :  bySectionNo.getTheoryWeight(),EnumValuesFactory.WipStorageCode.开方.getValue());
        }
    }

    public void extracted(String processingOrderCode, LongCrystal byCrystalNo, CrystalMaterialRelation crystalMaterialRelation, Date date) {
        //需要判断是否都已经到了开方进站  如果合格晶段都有开方待进站，那么就可以计算总工时进行上报
        List<ProductionPaintingLineDetail> productionPaintingLineDetails = productionPaintingLineDetailService.findByTypeAndCrystalTypeAndCrystalId(0, 0, byCrystalNo.getId());
        if(null == productionPaintingLineDetails || productionPaintingLineDetails.size() < 1){
            log.info("截断工时：划线信息没有晶段");
            //报工毛棒截断工时
            long crystalTime = getStationTime(byCrystalNo.getCrystalNo(), "【毛棒截断】工序进站", "【毛棒截断】工序出站成功，当前工艺已结束");

            ReportSapWorkinghours reportSapWorkinghours = new ReportSapWorkinghours();
            String cnfTime = new BigDecimal(crystalTime).divide(new BigDecimal(3600000), 2, RoundingMode.HALF_UP).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
            reportSapWorkinghours.setCnfTimeUom("H");
            reportSapWorkinghours.setCnfTime(cnfTime);
            reportSapWorkinghours.setStatus(false);
            reportSapWorkinghours.setPlant("5041");
            //工单编号：截断工单
            reportSapWorkinghours.setProductionOrderId(crystalMaterialRelation.getOrderNo());
            reportSapWorkinghours.setCnfDate(date);
            reportSapWorkinghours.setProcName("截断工时");
            reportSapWorkinghours.setRemark(byCrystalNo.getCrystalNo());
            reportSapWorkinghours.setCrystalNo(byCrystalNo.getCrystalNo());
            reportSapWorkinghoursService.findByRemarkAndProcName(byCrystalNo.getCrystalNo(), "截断工时");
            return;
        }
        List<String> collect = productionPaintingLineDetails.stream().map(ProductionPaintingLineDetail::getNo).collect(Collectors.toList());
        List<YbInspectData> collect1 = ybInspectDataService.findBySections(collect);
        List<YbInspectData> bySections = collect1.stream().filter(ybInspectData -> null != ybInspectData.getProductLevel()).collect(Collectors.toList());
        if(bySections.size() < collect.size()){
            log.info("截断工时：已评级圆棒数量少于晶段数量");
            return;
        }
        List<String> sectionNos = new ArrayList<>();
        if(null != bySections && bySections.size() > 0){
            sectionNos = bySections.stream().filter(ybInspectData -> ybInspectData.getGradeType().equals("正常")).map(YbInspectData::getSectionNo).collect(Collectors.toList());
        }
        int count = 0;
        log.info("截断工时：评级类型为正常的晶棒" + sectionNos);

        if(null != sectionNos && sectionNos.size() > 0){
            List<String> noList = new ArrayList<>();
            for (String sectionNo : sectionNos) {
                if(processingOrderCode.equals(sectionNo)){
                    continue;
                }
                ProcessLog processLogs = processLogService.findByProcessingOrderCodeAndProcessLogName(sectionNo, "【圆棒检验】工序出站，进入【刀剖】工序待进站");
                if(null != processLogs){
                    noList.add(sectionNo);
                    count++;
                }
            }
            log.info("截断工时：已进入刀剖待进站的数量" + count);
            if(count + 1 >= sectionNos.size()){
                //1、计算毛棒截断工时：截断出站时间-截断进站时间
                long crystalTime = getStationTime(byCrystalNo.getCrystalNo(), "【毛棒截断】工序进站", "【毛棒截断】工序出站");
                log.info("截断工时：毛棒截断时间：" + crystalTime);
                //2、计算每段的截断工时：每段的刀剖进站时间-截断出站时间
                for (String no : noList) {
                    //每段截断出站时间可以是圆棒检验待进站时间
                    long time = getStationTime1(no, "【毛棒截断】工序进站", "【刀剖】工序进站", byCrystalNo.getCrystalNo());
                    log.info("截断工时：编号：{}，晶段截断时间：{}，毛棒截断时间：{}", no, crystalTime, time);
                    crystalTime = crystalTime + time;
                }
                ProcessLog crystalInProcessLogs = processLogService.findByProcessingOrderCodeAndProcessLogName(byCrystalNo.getCrystalNo(), "【毛棒截断】工序进站");
                if(null != crystalInProcessLogs && null != crystalInProcessLogs.getCreateTime()){
                    long time = crystalInProcessLogs.getCreateTime().getTime();
                    long time1 = System.currentTimeMillis();
                    long l = time1 - time;
                    crystalTime = crystalTime + l;
                }
                //3、报工时
                ReportSapWorkinghours reportSapWorkinghours = new ReportSapWorkinghours();
                String cnfTime = new BigDecimal(crystalTime).divide(new BigDecimal(3600000), 2, RoundingMode.HALF_UP).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
                reportSapWorkinghours.setCnfTimeUom("H");
                reportSapWorkinghours.setCnfTime(cnfTime);
                reportSapWorkinghours.setStatus(false);
                reportSapWorkinghours.setPlant("5041");
                //工单编号：截断工单
                reportSapWorkinghours.setProductionOrderId(crystalMaterialRelation.getOrderNo());
                reportSapWorkinghours.setCnfDate(date);
                reportSapWorkinghours.setProcName("截断工时");
                reportSapWorkinghours.setRemark(byCrystalNo.getCrystalNo());
                reportSapWorkinghours.setCrystalNo(byCrystalNo.getCrystalNo());
                ReportSapWorkinghours byCrystalNoAndBwart = reportSapWorkinghoursService.findByRemarkAndProcName(byCrystalNo.getCrystalNo(), "截断工时");
                if (null != byCrystalNoAndBwart) {
                    SysLog syslog = new SysLog();
                    syslog.setCreateTime(new Date());
                    syslog.setType("info");
                    syslog.setCreateUserName("SYSTEM");
                    syslog.setName("截断工时");
                    syslog.setContent(JSON.toJSONString(reportSapWorkinghours));
                    syslog.setResult("截断工时：晶棒【" + byCrystalNo.getCrystalNo() + "】已经报过工时");
                    syslog.setMethodName("handleReportConsumption()");
                    syslog.setServerAddr("");
                    syslog.setReqType("HTTP");
                    syslog.setReqIp(IpUtils.getLocalIP());
                    sysLogService.save(syslog);
                    return;
                } else {
                    reportSapWorkinghoursService.saveOrUpdate(reportSapWorkinghours);
                }
            }
        }
    }

    /**
     * 非定向：NULL，非定向
     * @param orderNoPreviousProcess
     * @param orderNo
     */
    private void handleDirectionalControl(String orderNoPreviousProcess,String orderNo,String deviceCode){
        if (StringUtils.isNotBlank(orderNoPreviousProcess) && StringUtils.isNotBlank(orderNo)){

            //添加卡控开关
            if (GlobalSwitch.enable(GlobalSwitchNamespace.NAMESPACE_YB_CHECK, "DirectionalControlSwitch", false)) {
                return;
            }
            ProductionOrder productionOrderPreviousProcess = productionOrderService.findByAufnr(orderNoPreviousProcess);
            Assert.notNull(productionOrderPreviousProcess, " 单晶生产订单记录不存在，订单号为：" + orderNoPreviousProcess );
            ProductionOrder productionOrder = productionOrderService.findByAufnr(orderNo);
            Assert.notNull(productionOrder, " 单晶生产订单记录不存在，计划订单号为：" + orderNo );
            // 非定向 空匹配，其它定向标识需要一致
            if (((StringUtils.isBlank(productionOrderPreviousProcess.getZorientationind()) || StringUtils.equals(productionOrderPreviousProcess.getZorientationind(),"非定向"))
                    && (StringUtils.isBlank(productionOrder.getZorientationind()) || StringUtils.equals(productionOrder.getZorientationind(),"非定向")))
                || StringUtils.equals(productionOrderPreviousProcess.getZorientationind(),productionOrder.getZorientationind())){
                return;
            }
            throw new RuntimeException("该设备:" + deviceCode + " 计划工单：" + orderNo + " 定向标识:" + productionOrder.getZorientationind()
                    + "，与当前物料订单：" + orderNoPreviousProcess + " 定向标识:" + productionOrderPreviousProcess.getZorientationind() + " 不一致，不允许该设备过站!");
        }
    }

    @Override
    public long getStationTime(String code, String inStation, String outStation) {
        ProcessLog crystalInProcessLogs = processLogService.findByProcessingOrderCodeAndProcessLogName(code, inStation);
        if(null != crystalInProcessLogs){
            long startTime = crystalInProcessLogs.getCreateTime().getTime();
            ProcessLog crystalOutProcessLogs = processLogService.findByProcessingOrderCodeAndProcessLogName(code, outStation);
            if(null != crystalOutProcessLogs){
                long endTime = crystalOutProcessLogs.getCreateTime().getTime();
                long crystalTime = endTime - startTime;
                return crystalTime;
            }
            return 0;
        }
        return 0;
    }

    public long getStationTime1(String code, String inStation, String outStation, String crystalNo) {
        ProcessLog crystalInProcessLogs = processLogService.findByProcessingOrderCodeAndProcessLogName(crystalNo, inStation);
        if(null != crystalInProcessLogs){
            long startTime = crystalInProcessLogs.getCreateTime().getTime();
            ProcessLog crystalOutProcessLogs = processLogService.findByProcessingOrderCodeAndProcessLogName(code, outStation);
            if(null != crystalOutProcessLogs){
                long endTime = crystalOutProcessLogs.getCreateTime().getTime();
                long crystalTime = endTime - startTime;
                return crystalTime;
            }
            return 0;
        }
        return 0;
    }

    private void handleReportSap(Result<FbScheduleDto> result, String type, LongCrystal byCrystalNo, String processingOrderCode, String deviceCode, BigDecimal weigth, String procName) {
        CrystalMaterialRelation crystalMaterialRelation = crystalMaterialRelationService.findBySectionNo(processingOrderCode);
        if (null != crystalMaterialRelation && null != crystalMaterialRelation.getReportStatus() && crystalMaterialRelation.getReportStatus().equals(EnumValuesFactory.ReportStatusSap.REPORTED.getKey())){
            log.info("该单晶已上报，请勿重复上报，单晶编号为：{}",processingOrderCode);
            return;
        }

        FbScheduleDto fbScheduleDto = result.getData();
        WarehouseOutputBillBo outputBillBo = new WarehouseOutputBillBo();
        outputBillBo.setType(type);
        outputBillBo.setAutoAudit(true);
        outputBillBo.setDestination("车间");
        List<WarehouseOutputBillDetailBo> outputBillDetailBos = new ArrayList<>();
        //WarehouseOutputBillDetailBo warehouseOutputBillDetailBo = modelMapper.map(fbScheduleDto,WarehouseOutputBillDetailBo.class);
        WarehouseOutputBillDetailBo warehouseOutputBillDetailBo = new WarehouseOutputBillDetailBo();
        //出库使用划线数据
        MaterialModel materialModel = materialModelService.findByCode(byCrystalNo.getProductCode());
        if (null == materialModel) {
            throw new RuntimeException("物料主数据为空！");
        }
        warehouseOutputBillDetailBo.setMaterialModelId(Long.valueOf(materialModel.getId()));
        warehouseOutputBillDetailBo.setMaterialModelCode(materialModel.getCode());
        warehouseOutputBillDetailBo.setMaterialModelName(materialModel.getName());
        warehouseOutputBillDetailBo.setCrystalNo(processingOrderCode);


        String batchNo = byCrystalNo.getBatchNo();
        if (StringUtils.isNotBlank(batchNo) && batchNo.startsWith("TCN") && batchNo.length() >= 10) {
            batchNo = batchNo.substring(0, 1) + "J" + batchNo.substring(2, 10);
        }
        warehouseOutputBillDetailBo.setBatchNo(batchNo);
        warehouseOutputBillDetailBo.setUnitName("KG");
        warehouseOutputBillDetailBo.setRequireCount(weigth);
        //warehouseOutputBillDetailBo.setBatchNo(fbScheduleDto.getOrderNo());
//        warehouseOutputBillDetailBo.setUniqueCode(processingOrderCode);
        outputBillDetailBos.add(warehouseOutputBillDetailBo);
        outputBillBo.setOutputBillDetails(outputBillDetailBos);
        Equipment byCode = equipmentService.findByCode(deviceCode);
        String warehouseCode = "";
        String warehouseName = "";
        if (null != byCode) {
            DictionaryItem warehouseLocation = dictionaryItemService.findByThemeValueAndNameAndValueAndEnable("WarehouseLocation", byCode.getArea(), byCode.getSeries(), true);
            if (null != warehouseLocation) {
                warehouseCode = warehouseLocation.getExtendValue();
                warehouseName = warehouseLocation.getExtendValue2();
            }
        }
        outputBillBo.setRemark(processingOrderCode);
        warehouseOutputBillDetailBo.setWarehouseName(warehouseName);
        warehouseOutputBillDetailBo.setWarehouseCode(warehouseName);
        Result<WarehouseModelDto> warehouseModelDtoResult = storeFeignClients.getCode(warehouseName);
        if (warehouseModelDtoResult.getCode() == ResultCode.SUCCESS.getCode()) {
            warehouseOutputBillDetailBo.setWarehouseId(warehouseModelDtoResult.getData().getId());
        }
        Result<WarehouseInputReturnDto> resultStore = storeFeignClients.outputApplyData(outputBillBo);
        log.info("线边仓出库:{}", JSONObject.toJSONString(outputBillBo));
        if (null == resultStore || resultStore.getCode() != ResultCode.SUCCESS.getCode()) {
            log.info("线边仓出库失败:{}", resultStore.getMessage());
            throw new BusinessException("线边仓出库失败， 库位为：" + warehouseName + ", 异常信息为：" + resultStore.getMessage());
        }
        //调整为长晶棒料号
        this.sendReportSapGoodsmvt("261", byCode.getSeries(), fbScheduleDto.getOrderNo(), byCrystalNo.getProductCode(), batchNo, weigth.toString(), "KG", "5041", warehouseCode, processingOrderCode, null, procName, deviceCode,null);
    }

    /**
     * @param bwart 移动类型
     * @param kostl 成本中心
     * @param aufnr SAP生产订单
     * @param matnr 物料编码
     * @param charg 批次号
     * @param menge 数量
     * @param meins 单位
     */
    @Override
    public void sendReportSapGoodsmvt(String bwart, String kostl, String aufnr, String matnr, String charg, String menge, String meins, String werks, String lgort, String crystalNo, String umlgo, String procName, String deviceNo,String againNum) {
        ReportSapGoodsmvt reportSap = new ReportSapGoodsmvt();
        reportSap.setBwart(bwart);
        //reportSap.setKostl(kostl);
        reportSap.setAufnr(aufnr);
        reportSap.setMatnr(matnr);
        reportSap.setCharg(charg);
        reportSap.setMenge(menge);
        reportSap.setWerks(werks);
        reportSap.setLgort(lgort);
        reportSap.setMeins(meins);
        reportSap.setDeviceNo(deviceNo);
        reportSap.setCrystalNo(crystalNo);
        reportSap.setBldat(new Date());
        String procNameAllocate = "";
        String procNameIn = "";
        String procNameOut = "";
        switch (procName) {
            case "划线":
                procNameAllocate = "毛棒调拨";
                procNameIn = "单晶收货";
                reportSap.setOther1(againNum);
                break;
            case "刀剖":
                procNameAllocate = "截断调拨";
                procNameIn = "截断收货";
                procNameOut = "刀剖消耗";
                break;
            case "毛棒截断":
                procNameOut = "截断消耗";
                break;
            case "方棒检验":
                procNameAllocate = "刀剖调拨";
                procNameIn = "刀剖收货";
                break;
            default:
                procNameAllocate = procName;
                procNameIn = procName;
                procNameOut = procName;

        }
        reportSap.setProcName(procNameIn);
        if (StringUtils.equals("261", bwart)) {
            reportSap.setProcName(procNameOut);
        }
        log.info("最终上报SAP的数据：" + reportSap);
        reportSapGoodsmvtService.saveOrUpdate(reportSap);

        //排除成品调拨
        if (StringUtils.isNotBlank(umlgo) && StringUtils.equals("101", bwart) && !StringUtils.equals("方棒检验", procName)) {
            ReportSapGoodsmvt reportSapAllocate = new ReportSapGoodsmvt();
            //BeanUtil.copyBeanPropWithNullValue(reportSapAllocate, reportSap, "id");
            reportSapAllocate.setMatnr(matnr);
            reportSapAllocate.setCharg(charg);
            reportSapAllocate.setMenge(menge);
            reportSapAllocate.setWerks(werks);
            reportSapAllocate.setLgort(lgort);
            reportSapAllocate.setMeins(meins);
            reportSapAllocate.setDeviceNo(deviceNo);
            reportSapAllocate.setCrystalNo(crystalNo);
            reportSapAllocate.setBldat(new Date());
            reportSapAllocate.setUmlgo(umlgo);
            //报销编号调整 由Z41 -> 311
            reportSapAllocate.setBwart("311");
            reportSapAllocate.setAufnr(null);
            reportSapAllocate.setUmwrk("5041");
            reportSapAllocate.setDeviceNo(deviceNo);
            reportSapAllocate.setUmcha(charg);
            reportSapAllocate.setProcName(procNameAllocate);
            reportSapGoodsmvtService.saveOrUpdate(reportSapAllocate);
        }
    }

    @Override
    public void sendReportSapGoodsmvtList(List<SendReportSapGoodsmvtDto> list){
        if(null != list && list.size() > 0){
            for (SendReportSapGoodsmvtDto reportSapGoodsmvtDto : list) {
                this.sendReportSapGoodsmvt(reportSapGoodsmvtDto.getBwart(), reportSapGoodsmvtDto.getSeries(), reportSapGoodsmvtDto.getOrderNo(), reportSapGoodsmvtDto.getMaterialCode(), reportSapGoodsmvtDto.getBatchNo(), reportSapGoodsmvtDto.getWeight(),
                        reportSapGoodsmvtDto.getMeins(), reportSapGoodsmvtDto.getWerks(), reportSapGoodsmvtDto.getLgort(), reportSapGoodsmvtDto.getCrystalNo(), reportSapGoodsmvtDto.getUmlgo(), reportSapGoodsmvtDto.getProcName(), reportSapGoodsmvtDto.getDeviceNo(),null);
            }
        }
    }

    @Override
    public Result sendWarehouseInputBillBo(LongCrystal longCrystal, BigDecimal weight, String type, String umlgo, String warehouseCode, CrystalMaterialRelation crystalMaterialRelation,String sectionNo) {

        String username = BaseContextHandler.getUsername();
        WarehouseInputBillBo warehouseInputBillBo = new WarehouseInputBillBo();
        warehouseInputBillBo.setCreateUserName(username);
        warehouseInputBillBo.setCreateUserId(BaseContextHandler.getUserID());
        warehouseInputBillBo.setType(type);

        String batchNo = longCrystal.getBatchNo();
        if (StringUtils.isNotBlank(batchNo) && batchNo.startsWith("TCN") && batchNo.length() >= 10) {
            batchNo = batchNo.substring(0, 1) + "J" + batchNo.substring(2, 10);
        }
        warehouseInputBillBo.setRemark(batchNo);
        warehouseInputBillBo.setAutomaticOut(true);
        warehouseInputBillBo.setAutoAudit(true);
        if (StringUtils.isBlank(longCrystal.getProductCode())) {
            throw new RuntimeException("料号为空！");
        }
        MaterialModel materialModel = null;
        if (null != crystalMaterialRelation && null != crystalMaterialRelation.getMaterialModelId()) {
            materialModel = materialModelService.get(crystalMaterialRelation.getMaterialModelId());
        } else {
            materialModel = materialModelService.findByCode(longCrystal.getProductCode());
        }
        //MaterialModel byCode = materialModelService.findByCode(longCrystal.getProductCode());
        if (null == materialModel) {
            throw new RuntimeException("物料主数据为空！");
        }
        List<WarehouseInputBillDetailBo> inputBillDetails = new ArrayList<>();
        WarehouseInputBillDetailBo warehouseInputBillDetailBo = new WarehouseInputBillDetailBo();
        warehouseInputBillDetailBo.setCount(weight);
        warehouseInputBillDetailBo.setMaterialModelId(Long.valueOf(materialModel.getId()));
        warehouseInputBillDetailBo.setMaterialModelCode(materialModel.getCode());
       /* Result<WarehouseModelDto> warehouseCodeResult = storeFeignClients.getCode(warehouseCode);
        if (warehouseCodeResult.getCode() == ResultCode.SUCCESS.getCode()){
            warehouseInputBillDetailBo.setWarehouseId(warehouseCodeResult.getData().getId());
        }*/
//        warehouseInputBillDetailBo.setUniqueCode(longCrystal.getCrystalNo());
        warehouseInputBillDetailBo.setWarehouseCode(warehouseCode);
        warehouseInputBillDetailBo.setWarehouseName(warehouseCode);
        Result<WarehouseModelDto> codeResult = storeFeignClients.getCode(warehouseCode);
        if (codeResult.getCode() == ResultCode.SUCCESS.getCode()) {
            warehouseInputBillDetailBo.setWarehouseId(codeResult.getData().getId());
        }
        warehouseInputBillDetailBo.setMaterialModelName(materialModel.getName());
        warehouseInputBillDetailBo.setWeight(weight);
        if (null != materialModel.getMaterialType()) {
            warehouseInputBillDetailBo.setMaterialTypeName(materialModel.getMaterialType().getName());
        }

        warehouseInputBillDetailBo.setBatchNo(batchNo);
        if (null != materialModel.getUnit()) {
            warehouseInputBillDetailBo.setUnitName(materialModel.getUnit().getName());
        }
        warehouseInputBillDetailBo.setSupplier(materialModel.getSupplier());
        warehouseInputBillDetailBo.setSpecification(materialModel.getSpecification());
        warehouseInputBillDetailBo.setMaterialTh(materialModel.getNumberOfDrawings());
        if (null != crystalMaterialRelation){
            warehouseInputBillDetailBo.setCrystalNo(crystalMaterialRelation.getSectionNo());
        }else {
            warehouseInputBillDetailBo.setCrystalNo(longCrystal.getCrystalNo());
        }
        if (StringUtils.isNotBlank(sectionNo)){
            warehouseInputBillDetailBo.setCrystalNo(sectionNo);
        }
        inputBillDetails.add(warehouseInputBillDetailBo);
        warehouseInputBillBo.setInputBillDetails(inputBillDetails);
//        Result<WarehouseInputReturnDto> warehouseInputReturnDtoResult = storeFeignClients.inputApplyData(warehouseInputBillBo);
//        if (StringUtils.isNotBlank(umlgo) && null != warehouseInputReturnDtoResult && warehouseInputReturnDtoResult.getCode() == ResultCode.SUCCESS.getCode()){
        WarehouseAllotBillDto warehouseAllotBillDto = new WarehouseAllotBillDto();
        warehouseAllotBillDto.setCreateUserName(username);
        warehouseAllotBillDto.setRemark(longCrystal.getCrystalNo());
        if (type.equals(InputBillStatusEnum.毛棒入库.getValue())){
            warehouseAllotBillDto.setAllotType("毛棒调拨");
        }else if (type.equals(InputBillStatusEnum.截断入库.getValue())){
            warehouseAllotBillDto.setAllotType("截断调拨");
        }else {
            warehouseAllotBillDto.setAllotType(type);
        }

        warehouseAllotBillDto.setCreateUserId(BaseContextHandler.getUserID());
        List<WarehouseAllotBillDetailDto> allotBillDetailDtos = new ArrayList<>();
        WarehouseAllotBillDetailDto warehouseAllotBillDetailDto = new WarehouseAllotBillDetailDto();
        BeanUtil.copyBeanPropWithNullValue(warehouseAllotBillDetailDto, warehouseInputBillDetailBo, "id");
        warehouseAllotBillDetailDto.setAllotWarehouseName(umlgo);
        warehouseAllotBillDetailDto.setAllotWarehouseCode(umlgo);
        //warehouseAllotBillDetailDto.setUniqueCode(longCrystal.getCrystalNo());
        Result<WarehouseModelDto> umlgoResult = storeFeignClients.getCode(umlgo);
        if (umlgoResult.getCode() == ResultCode.SUCCESS.getCode()) {
            warehouseAllotBillDetailDto.setAllotWarehouseId(umlgoResult.getData().getId());
        }
        if (null != crystalMaterialRelation){
            warehouseAllotBillDetailDto.setCrystalNo(crystalMaterialRelation.getSectionNo());
        }else {
            warehouseAllotBillDetailDto.setCrystalNo(longCrystal.getCrystalNo());
        }
        if (StringUtils.isNotBlank(sectionNo)){
            warehouseAllotBillDetailDto.setCrystalNo(sectionNo);
        }
        allotBillDetailDtos.add(warehouseAllotBillDetailDto);
        warehouseAllotBillDto.setAllotBillDetailDtos(allotBillDetailDtos);
        warehouseAllotBillDto.setAutoAudit(true);
//            Result allotBill = storeFeignClients.createAllotBill(warehouseAllotBillDto);
        StoreDto storeDto = new StoreDto();
        storeDto.setWarehouseAllotBillDto(warehouseAllotBillDto);
        storeDto.setInputBillBo(warehouseInputBillBo);

        //调拨出库
        if (null != crystalMaterialRelation) {
            if (null == crystalMaterialRelation.getMaterialModelId()) {
                throw new RuntimeException("未找到截断入库关联物料数据为空！");
            }

            WarehouseOutputBillBo outputBillBo = new WarehouseOutputBillBo();
            outputBillBo.setType(type);
            outputBillBo.setDestination("车间");
            outputBillBo.setAutoAudit(true);
            outputBillBo.setCreateUserName(username);
            List<WarehouseOutputBillDetailBo> warehouseOutputBillDetailBos = new ArrayList<>();
            WarehouseOutputBillDetailBo warehouseOutputBillDetailBo = new WarehouseOutputBillDetailBo();
            warehouseOutputBillDetailBo.setMaterialModelCode(materialModel.getCode());
            warehouseOutputBillDetailBo.setMaterialModelId(Long.valueOf(materialModel.getId()));
            warehouseOutputBillDetailBo.setMaterialModelName(materialModel.getName());
            if (null != materialModel.getMaterialType()) {
                warehouseOutputBillDetailBo.setMaterialTypeName(materialModel.getMaterialType().getName());
            }
            if (StringUtils.isNotBlank(crystalMaterialRelation.getSectionNo())) {
                outputBillBo.setRemark(crystalMaterialRelation.getSectionNo());
                warehouseAllotBillDto.setRemark(crystalMaterialRelation.getSectionNo());
                warehouseInputBillBo.setRemark(crystalMaterialRelation.getSectionNo());
                //warehouseOutputBillDetailBo.setCrystalNo(crystalMaterialRelation.getSectionNo());
                warehouseOutputBillDetailBo.setCrystalNo(sectionNo);
                //warehouseOutputBillDetailBo.setUniqueCode(crystalMaterialRelation.getSectionNo());
            }
            warehouseOutputBillDetailBo.setSpecification(materialModel.getSpecification());

            if (null != materialModel.getUnit()) {
                warehouseOutputBillDetailBo.setUnitName(materialModel.getUnit().getName());
            }
            warehouseOutputBillDetailBo.setMaterialTh(materialModel.getNumberOfDrawings());
            warehouseOutputBillDetailBo.setSupplier(materialModel.getSupplier());
            if (umlgoResult.getCode() == ResultCode.SUCCESS.getCode()) {
                warehouseOutputBillDetailBo.setWarehouseId(umlgoResult.getData().getId());
            }
            warehouseOutputBillDetailBo.setBatchNo(batchNo);
            warehouseOutputBillDetailBo.setWarehouseName(umlgo);
            warehouseOutputBillDetailBo.setUnitName("KG");
            warehouseOutputBillDetailBo.setRequireCount(weight);
//            warehouseOutputBillDetailBo.setUniqueCode(processingOrderCode);
            warehouseOutputBillDetailBos.add(warehouseOutputBillDetailBo);
            outputBillBo.setOutputBillDetails(warehouseOutputBillDetailBos);
            storeDto.setOutputBillBo(outputBillBo);
        }
        log.info("创建入库单AND调拨单AND出库单接口:{}", JSONObject.toJSONString(storeDto));
        long l = System.currentTimeMillis();
        Result inputAndAllotAndOut = storeFeignClients.createInputAndAllotAndOut(storeDto);
        log.info("接口耗时：{}", System.currentTimeMillis() - l);
       /*     if (null == allotBill || allotBill.getCode() != ResultCode.SUCCESS.getCode()){
                throw new RuntimeException("线边仓调拨失败！返回异常为：" + allotBill.getMessage());
            }
//        }*/
        return inputAndAllotAndOut;
    }

    public static void main(String[] args) {
        long crystalTime = 2000;
        log.info("截断工时：毛棒截断时间：" + crystalTime);
        //2、计算每段的截断工时：每段的刀剖进站时间-截断出站时间
        for (int i = 0; i < 2; i++) {
            //每段截断出站时间可以是圆棒检验待进站时间
            long time = 1000;
            crystalTime = crystalTime + time;
        }

    }
}
