package com.sw.mes.yb.production.service.impl;


import com.sw.mes.base.factory.init.entity.MachineCapacityInfo;
import com.sw.mes.base.factory.init.service.EquipmentService;
import com.sw.mes.base.factory.init.service.MachineCapacityInfoService;
import com.sw.mes.base.factory.init.service.MachineCapacityService;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.base.workinprocess.dao.WipStorageDao;
import com.sw.mes.base.workinprocess.dto.CurrentWipStorageStatusDto;
import com.sw.mes.base.workinprocess.entity.PlanProcessingOrder;
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.config.rabbit.InspectDataBaseChangeAsync;
import com.sw.mes.core.annotation.ServiceLogs;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.enums.SectionIndexRangeEnum;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.core.utils.DateUtil;
import com.sw.mes.outside.service.EapService;
import com.sw.mes.utils.StringUtils;
import com.sw.mes.yb.pad.entity.ProductionPaintingLine;
import com.sw.mes.yb.pad.service.ProductionPaintingLineService;
import com.sw.mes.yb.plan.entity.ProductionOrder;
import com.sw.mes.yb.plan.entity.ProductionSchedule;
import com.sw.mes.yb.plan.service.ProductionOrderService;
import com.sw.mes.yb.plan.service.ProductionScheduleService;
import com.sw.mes.yb.production.dao.LongCrystalDao;
import com.sw.mes.yb.production.dto.*;
import com.sw.mes.yb.production.entity.AgainTask;
import com.sw.mes.yb.production.entity.InspectionRecord;
import com.sw.mes.yb.production.entity.LongCrystal;
import com.sw.mes.yb.production.entity.ProcessWorkingHours;
import com.sw.mes.yb.production.service.*;
import com.sw.mes.yb.turnstore.service.ProductionBindingTrayLogService;
import com.sw.mes.yb.turnstore.service.ProductionBindingTrayService;
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.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

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


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@Service
@Transactional
public class LongCrystalServiceImpl extends BaseServiceImpl<LongCrystal> implements LongCrystalService {
    LongCrystalDao dao;

    @Autowired
    public void setDao(LongCrystalDao dao) {
        super.setBaseDao(dao);
        this.dao = dao;
    }

    @Autowired
    private AgainTaskService againTaskService;

    @Autowired
    private InspectDataBaseChangeAsync inspectDataBaseChangeAsync;

    @Autowired
    private ProductionPaintingLineService productionPaintingLineService;

    @Autowired
    private WipStorageService wipStorageService;

    @Autowired
    private WipStorageDao wipStorageDao;

    @Autowired
    private InspectionRecordService inspectionRecordService;

    @Autowired
    private PlanProcessingOrderService planProcessingOrderService;

    @Autowired
    private EapService eapService;

    @Autowired
    private ProductionBindingTrayService productionBindingTrayService;

    @Autowired
    private ProductionBindingTrayLogService productionBindingTrayLogService;

    @Autowired
    private ProcessLogService processLogService;

    @Autowired
    private LongCrystalService longCrystalService;

    @Autowired
    private ProductionScheduleService productionScheduleService;

    @Autowired
    private ProductionOrderService productionOrderService;

    @Autowired
    private MachineCapacityService machineCapacityService;

    @Autowired
    private MachineCapacityInfoService machineCapacityInfoService;

    @Autowired
    private DictionaryItemService dictionaryItemService;

    @Autowired
    private AgainTaskDetailService againTaskDetailService;

    @Autowired
    private LoadingTaskService loadingTaskService;

    @Autowired
    private RecycledMaterialManageService recycledMaterialManageService;

    @Autowired
    private EquipmentService equipmentService;

    @Autowired
    private ProcessWorkingHoursService processWorkingHoursService;

    @Override
    public LongCrystal getLastCrystalNo(String equipmentCode) {
        return dao.getLastCrystalNo(equipmentCode);
    }

    @Override
    public List<LongCrystalExcelDto> giveSomeValues(List<LongCrystalDto> longCrystalDto) {

        List<LongCrystalExcelDto> longCrystalExcelDtos = new ArrayList<>();
        for (LongCrystalDto crystalDto : longCrystalDto) {
            LongCrystalExcelDto longCrystalExcelDto = new LongCrystalExcelDto();
            BeanUtils.copyProperties(crystalDto, longCrystalExcelDto);
            //产出日期
            if (null != crystalDto.getGmtCreate() && null != crystalDto.getGmtCreate()) {
                longCrystalExcelDto.setGmtCreateDate(DateUtil.getFormatTime(crystalDto.getGmtCreate()));
            }
            //收尾方式，导出时候显示中文
            DictionaryItem windUpDictionaryItem = dictionaryItemService.findByValueAndThemeId(crystalDto.getWindUp(), 181);
            if (null != windUpDictionaryItem) {
                longCrystalExcelDto.setWindUp(windUpDictionaryItem.getName());
            }
            //完结标识，导出时显示中文
            DictionaryItem closureIdentificationThemeItem = dictionaryItemService.findByValueAndThemeId(crystalDto.getClosureIdentification(), 298);
            if (null != closureIdentificationThemeItem) {
                longCrystalExcelDto.setClosureIdentification(closureIdentificationThemeItem.getName());
            }
            //完结时间，从单晶生产产量报表(逻辑)里取
            if (crystalDto.getIsDone() == 1) {
                longCrystalExcelDto.setClosureTime(crystalDto.getGmtCreate());
            }
            //划线日期
            if (null != crystalDto.getLineStartTime() && null != crystalDto.getLineStartTime()) {
                longCrystalExcelDto.setLineStartTimeDate(DateUtil.getFormatTime(crystalDto.getLineStartTime()));
            }

            ProductionPaintingLine paintingLine = productionPaintingLineService.findByCrystalNo(crystalDto.getCrystalNo());

            if (null != paintingLine) {
                //一检等径长度，从单晶生产产量报表里取
                longCrystalExcelDto.setYiJianDengJinglength(paintingLine.getSubmitLength());
                //一检合格有效长度
                longCrystalExcelDto.setYiJianHeGeYouXiaolength(paintingLine.getValidLength());

                if (null != paintingLine.getValidLength()) {
                    //折重系数
                    DictionaryItem weightReductionCoefficientDictionaryItem = dictionaryItemService.findByValueAndThemeId(crystalDto.getSpecs(), 94);
                    if (null != weightReductionCoefficientDictionaryItem && !weightReductionCoefficientDictionaryItem.getValue().isEmpty()) {
                        BigDecimal weightReductionCoefficient = new BigDecimal(weightReductionCoefficientDictionaryItem.getValue());
                        //成晶重量
                        longCrystalExcelDto.setChengJingWeight(paintingLine.getValidLength().divide(weightReductionCoefficient).setScale(3, BigDecimal.ROUND_HALF_UP));
                    }
                }
            }

            //投料总量, 完结尾晶棒显示，其他类型晶棒不显示此字段
            if (!crystalDto.getClosureIdentification().isEmpty() && crystalDto.getClosureIdentification().equals("W") && !crystalDto.getLotNo().isEmpty()) {
                //灌料
                BigDecimal totaGuanLiaoWeightByLotNo = againTaskDetailService.getTotaGuanLiaoWeightByLotNo(crystalDto.getLotNo());
                //投料
                BigDecimal peiLiaoTotalWeightByLotNo = loadingTaskService.getPeiLiaoTotalWeightByLotNo(crystalDto.getLotNo());
                //投料总量,完结尾晶棒显示，其他类型晶棒不显示此字段
                if (null != totaGuanLiaoWeightByLotNo && null != peiLiaoTotalWeightByLotNo) {
                    longCrystalExcelDto.setTouLiaoTotalWeight(totaGuanLiaoWeightByLotNo.add(peiLiaoTotalWeightByLotNo));
                } else if (null != totaGuanLiaoWeightByLotNo && null == peiLiaoTotalWeightByLotNo) {
                    longCrystalExcelDto.setTouLiaoTotalWeight(totaGuanLiaoWeightByLotNo);
                } else if (null == totaGuanLiaoWeightByLotNo && null != peiLiaoTotalWeightByLotNo) {
                    longCrystalExcelDto.setTouLiaoTotalWeight(peiLiaoTotalWeightByLotNo);
                }

                //长晶棒总重量,
                BigDecimal longCrystalTotalWeight = BigDecimal.ZERO;
                List<LongCrystal> longCrystals = this.findByLotNo(crystalDto.getLotNo());
                if (!longCrystals.isEmpty()) {
                    for (LongCrystal longCrystal : longCrystals) {
                        //正常收尾
                        if (!longCrystal.getWindUp().isEmpty() && longCrystal.getWindUp().equals("Y")) {
                            //毛重>=等径重量用毛重，反之用等径重量
                            if (null != longCrystal.getWeight() && null != longCrystal.getLastWeight() && longCrystal.getWeight().compareTo(longCrystal.getLastWeight()) >= 0) {
                                longCrystalTotalWeight.add(longCrystal.getWeight());
                            } else if (null != longCrystal.getWeight() && null != longCrystal.getLastWeight() && longCrystal.getWeight().compareTo(longCrystal.getLastWeight()) < 0) {
                                longCrystalTotalWeight.add(longCrystal.getLastWeight());
                                //正常收尾， 有一个为空的场景,取不空的
                            } else if (null != longCrystal.getWeight() && null == longCrystal.getLastWeight()) {
                                longCrystalTotalWeight.add(longCrystal.getWeight());
                            } else if (null == longCrystal.getWeight() && null != longCrystal.getLastWeight()) {
                                longCrystalTotalWeight.add(longCrystal.getLastWeight());
                            }
                        } else if (!longCrystal.getWindUp().isEmpty() && !longCrystal.getWindUp().equals("Y")) {//不是正常收尾的统计等径重量
                            longCrystalTotalWeight.add(longCrystal.getWeight());
                        }
                    }
                    longCrystalExcelDto.setLongCrystalTotalWeight(longCrystalTotalWeight);
                }

                //提渣盖
                BigDecimal tiZhaGaiByLotNo = recycledMaterialManageService.findTiZhaGaiByLotNo(crystalDto.getLotNo());
                longCrystalExcelDto.setTiZhaGai(tiZhaGaiByLotNo);
                //提肩料
                BigDecimal tiJianLiaoByLotNo = recycledMaterialManageService.findTiJianLiaoByLotNo(crystalDto.getLotNo());
                longCrystalExcelDto.setTiJianLiao(tiJianLiaoByLotNo);
                //埚底料
                BigDecimal guoDiLiaoByLotNo = recycledMaterialManageService.findGuoDiLiaoByLotNo(crystalDto.getLotNo());
                longCrystalExcelDto.setGuoDiLiao(guoDiLiaoByLotNo);
                //墩埚料
                BigDecimal dunGuoLiaoByLotNo = recycledMaterialManageService.findDunGuoLiaoByLotNo(crystalDto.getLotNo());
                longCrystalExcelDto.setDunGuoLiao(dunGuoLiaoByLotNo);
                //炉次损耗
                if (null == totaGuanLiaoWeightByLotNo) {
                    totaGuanLiaoWeightByLotNo = BigDecimal.ZERO;
                }
                if (null == peiLiaoTotalWeightByLotNo) {
                    peiLiaoTotalWeightByLotNo = BigDecimal.ZERO;
                }
                if (null == longCrystalTotalWeight) {
                    longCrystalTotalWeight = BigDecimal.ZERO;
                }
                if (null == tiZhaGaiByLotNo) {
                    tiZhaGaiByLotNo = BigDecimal.ZERO;
                }
                if (null == tiJianLiaoByLotNo) {
                    tiJianLiaoByLotNo = BigDecimal.ZERO;
                }
                if (null == guoDiLiaoByLotNo) {
                    guoDiLiaoByLotNo = BigDecimal.ZERO;
                }
                if (null == dunGuoLiaoByLotNo) {
                    dunGuoLiaoByLotNo = BigDecimal.ZERO;
                }
                longCrystalExcelDto.setHeatLoss(totaGuanLiaoWeightByLotNo.add(peiLiaoTotalWeightByLotNo).subtract(longCrystalTotalWeight).subtract(tiZhaGaiByLotNo).subtract(tiJianLiaoByLotNo).subtract(guoDiLiaoByLotNo).subtract(dunGuoLiaoByLotNo));
            }

            longCrystalExcelDtos.add(longCrystalExcelDto);
        }
        return longCrystalExcelDtos;
    }

    @Override
    public List<LongCrystal> findByLotNo(String lotNo) {

        return dao.findByLotNo(lotNo);
    }

    @Override
    public List<LongCrystal> findByEquipmentCode(String equipmentCode) {

        return dao.findByEquipmentCode(equipmentCode);
    }

    @Override
    public List<String> findByLotNoAndClosureIdentification(List<String> lotNoList, String closureIdentification) {

        return dao.findByLotNoAndClosureIdentification(lotNoList, closureIdentification);
    }

    @Override
    public LongCrystal findByCrystalNo(String crystalNo) {
        return dao.findByCrystalNo(crystalNo);
    }

    @Override
    public List<LongCrystal> findLongCrystal() {
        return dao.findLongCrystal();
    }

    @Override
    public List<LongCrystal> findByCrystalNoAndNotId(String crystalNo, Long id) {
        return dao.findByCrystalNoAndNotId(crystalNo, id);
    }

    @Override
    public List<LongCrystal> findAllByCrystalNo(List<String> crystalNos) {
        return dao.findAllByCrystalNo(crystalNos);
    }

    @Override
    public LongCrystal findByCrystalNo2(String crystalNo) {
        return dao.findByCrystalNo2(crystalNo);
    }

    @Override
    public List<LongCrystal> findByAgvTaskCode(String taskCode) {
        return dao.findByAgvTaskCode(taskCode);
    }

    @Override
    public List<LongCrystal> findByConfirmCrystals(String lotNo) {
//        List<LongCrystal> longCrystalsV1 = dao.findTop3ByEquipmentCodeAndCrystalStatusNotOrderByIdDesc(equipmentCode, EnumValuesFactory.CrystalStatus.待确认.getKey());
//        List<LongCrystal> longCrystals = dao.findByEquipmentCodeAndCrystalStatusOrderById(equipmentCode, EnumValuesFactory.CrystalStatus.待确认.getKey());

        List<LongCrystal> longCrystalsV1 = dao.findByLotNoCodeByIdDesc(lotNo);
        List<LongCrystal> resultLongCrystals = new LinkedList<>(longCrystalsV1);
//        resultLongCrystals.addAll(longCrystals);
        resultLongCrystals.sort(Comparator.comparing(LongCrystal::getId));
        return resultLongCrystals;
    }

    @Override
    public LongCrystal findTopByLotId(Long id) {
        return dao.findTopByLotIdOrderByIdDesc(id);
    }

    @Override
    public List<LongCrystal> findByIds(List<Integer> ids) {
        return dao.findByIds(ids);
    }

    @Override
    public List<String> findTop3LotNo() {
        return dao.findTop3LotNo();
    }


    @Override
    public List<String> findTop3LotNoByEquipmentCode(String equipmentCode) {
        return dao.findTop3LotNoByEquipmentCode(equipmentCode);
    }

    @Override
    public LongCrystal findByLotIdAndAgainNumAndCrystalNumAndCrystalStatusNotAndIdNot(Long lotId, Integer againNum, Integer crystalNum, int crystalStatus, Long id) {
        List<LongCrystal> longCrystals = dao.findByLotIdAndAgainNumAndCrystalNumAndCrystalStatusNotAndIdNot(lotId, againNum, crystalNum, crystalStatus, id);
        if (longCrystals.size() == 0) {
            return null;
        }
        return longCrystals.get(0);
    }

    @Override
    public Result updateCrystalNo(LongCrystalInfoDto dto) {
        LongCrystal entity = get(dto.getId());
        if (entity == null) {
            return ResultGenerator.fail("原信息不存在");
        }
        // 单晶状态为待确认，不允许修改编号
        if (entity.getCrystalStatus() == 9) {
            return ResultGenerator.fail("单晶状态为待确认，不允许修改编号");
        }
        if (entity.getCrystalStatus() == 5) {
            return ResultGenerator.fail("单晶状态为已划线，不允许修改编号");
        }

//        if (entity.getRodPulled() == 1) {
//            return ResultGenerator.fail("单晶状态为已拉取，不允许修改编号");
//        }
        List<LongCrystal> longCrystals = dao.findByLotIdAndAgainNumAndCrystalNumAndCrystalStatusNotAndIdNot(entity.getLotId(), dto.getAgainNum(), dto.getCrystalNum(), EnumValuesFactory.CrystalStatus.待确认.getKey(), entity.getId());
        if (longCrystals.size() > 0) {
            throw new BusinessException("该【" + entity.getLotNo() + "】已存在复投次数【" + dto.getAgainNum() + "】" + "颗次【" + dto.getCrystalNum() + "】的单晶");
        }

        String crystalNoOld = entity.getCrystalNo();
        String crystalNo = entity.getCrystalNo();
        Result<CurrentWipStorageStatusDto> result = wipStorageService.selectWipStorageResult(crystalNo);
        CurrentWipStorageStatusDto currentWipStorageStatusDto = result.getData();
        if (!EnumValuesFactory.WipStorageCode.送验.getKey().equals(currentWipStorageStatusDto.getWipStorageCode())
                && !EnumValuesFactory.WipStorageCode.划线.getKey().equals(currentWipStorageStatusDto.getWipStorageCode())) {
            return ResultGenerator.fail("当前单晶在" + EnumValuesFactory.WipStorageCode.getText(currentWipStorageStatusDto.getWipStorageCode())
                    + "，不能修改单晶编号");
        }

        entity.setWindUp(dto.getWindUp());
        entity.setAgainNum(dto.getAgainNum());
        entity.setCrystalNum(dto.getCrystalNum());


        crystalNo = eapService.generateCrystalNo(crystalNo, dto);

        // 检查新晶棒编号是否存在
        List<LongCrystal> checkExists = longCrystalService.findByCrystalNoAndNotId(crystalNo, entity.getId());
        if (!CollectionUtils.isEmpty(checkExists)) {
            throw new BusinessException("新晶棒编号【" + crystalNo + "】已存在，请检查是否存在异常数据！");
        }

        //修改工单信息
        PlanProcessingOrder
                planProcessingOrder = planProcessingOrderService.findByGoodsIdAndOrderType(entity.getId(),
                EnumValuesFactory.PlanProcessingOrderOrderType.单晶.getKey());
        planProcessingOrder.setCode(crystalNo);
        planProcessingOrder.setAgainNum(dto.getAgainNum());
        planProcessingOrder.setCrystalNum(dto.getCrystalNum());
        planProcessingOrder.setCodeChain(planProcessingOrder.getCodeChain().replace(crystalNoOld, crystalNo));
        planProcessingOrderService.saveOrUpdate(planProcessingOrder);
        processLogService.createProcessLog(planProcessingOrder.getId(), planProcessingOrder.getCode(), null, null, null, null, "修改单晶编号：" + crystalNoOld + "->" + crystalNo);

        //修改在制品工单号
        List<WipStorage> wipStorages = wipStorageService.findByProcessingOrderId(planProcessingOrder.getId());
        String finalCrystalNo = crystalNo;
        wipStorages.forEach(wipStorage -> wipStorage.setProcessingOrderCode(finalCrystalNo));
        wipStorageDao.saveAll(wipStorages);

        //修改长棒信息
        entity.setCrystalNo(crystalNo);
        entity.setWindUp(dto.getWindUp());
        entity.setAgainNum(dto.getAgainNum());
        entity.setGmtUpdate(new Date());
        saveOrUpdate(entity);
        if ((EnumValuesFactory.WipStorageCode.送验.getKey().equals(currentWipStorageStatusDto.getWipStorageCode()) &&
                currentWipStorageStatusDto.getWipStorageStatus() == EnumValuesFactory.WipStorageStatus.已进站.getKey())
                || EnumValuesFactory.WipStorageCode.划线.getKey().equals(currentWipStorageStatusDto.getWipStorageCode())) {
            // 修改送验记录
            InspectionRecord inspectionRecord = inspectionRecordService.findByLongCrystalId(entity.getId());
            inspectionRecord.setCrystalNo(crystalNo);
            inspectionRecord.setCrystalNum(dto.getCrystalNum());
            inspectionRecord.setAgainNum(dto.getAgainNum());
            inspectionRecord.setWindUp(dto.getWindUp());
            inspectionRecordService.saveOrUpdate(inspectionRecord);
            //修改托盘记录表
            productionBindingTrayService.updateByCrystalNo(crystalNoOld, crystalNo);
            //修改托盘记录表
            productionBindingTrayLogService.updateByCrystalNo(crystalNoOld, crystalNo);
        }
        return ResultGenerator.success();
    }

    @Override
    public Result updateCrystalStatus(LongCrystalDto dto) {
        LongCrystal entity = get(dto.getId());
        if (entity == null) {
            return ResultGenerator.fail("原信息不存在");
        }
        // 单晶状态为待确认，不允许修改编号
        if (entity.getCrystalStatus() == 9) {
            return ResultGenerator.fail("单晶状态为待确认，不允许修改单晶状态");
        }

        List<LongCrystal> longCrystals = dao.findByLotIdAndAgainNumAndCrystalNumAndCrystalStatusNotAndIdNot(entity.getLotId(), dto.getAgainNum(), dto.getCrystalNum(), EnumValuesFactory.CrystalStatus.待确认.getKey(), entity.getId());
        if (longCrystals.size() > 0) {
            throw new BusinessException("该【" + entity.getLotNo() + "】已存在复投次数【" + dto.getAgainNum() + "】" + "颗次【" + dto.getCrystalNum() + "】的单晶");
        }
        String crystalNo = entity.getCrystalNo();
        Result<CurrentWipStorageStatusDto> result = wipStorageService.selectWipStorageResult(crystalNo);
        CurrentWipStorageStatusDto currentWipStorageStatusDto = result.getData();
        if (!EnumValuesFactory.WipStorageCode.送验.getKey().equals(currentWipStorageStatusDto.getWipStorageCode())
                && !EnumValuesFactory.WipStorageCode.划线.getKey().equals(currentWipStorageStatusDto.getWipStorageCode())) {
            return ResultGenerator.fail("当前单晶在" + EnumValuesFactory.WipStorageCode.getText(currentWipStorageStatusDto.getWipStorageCode())
                    + "，不能修改单晶状态");
        }
        //修改单晶状态
        entity.setCrystalStatus(dto.getCrystalStatus());
        saveOrUpdate(entity);
        return ResultGenerator.success();
    }

    @Override
    public List<LongCrystal> findByLotIdAndCrystalStatusNot(Long lotId, Integer crystalStatus) {
        return dao.findByLotIdAndCrystalStatusNot(lotId, crystalStatus);
    }

    @Override
    public Result<Integer> updateYbWorkOrder(String crystalNo, String ybWorkOrder) {
        return ResultGenerator.success(dao.updateYbWorkOrder(crystalNo, ybWorkOrder));
    }

    /**
     * 补全长晶棒产出的订单号
     *
     * @param lotNo     炉次号
     * @param crystalNo 单晶编号
     * @param startTime 划线开始时间
     */
    @Override
    @ServiceLogs(description = "画线前更新长晶棒状态为已划线")
    public void completionLongCrystalOrder(String lotNo, String crystalNo, Date startTime, BigDecimal maxDiam, BigDecimal minDiam, Boolean flag) {
        LongCrystal longCrystal = findByCrystalNo(crystalNo);
    /*    // 工单排程
//        ProductionSchedule productionSchedule = productionScheduleService.findByLotNo(lotNo);
        ProductionSchedule productionSchedule = productionScheduleService.findByLotNoC(lotNo);

        //设备加工能力信息校验
        Boolean aBoolean = false;
        ProductionOrder productionOrder;
        if(null != productionSchedule){
            productionOrder = productionSchedule.getProductionOrder();
            aBoolean = checkProperties(productionSchedule, productionOrder, longCrystal, startTime, true);
        }

        if (aBoolean) {
            ProductionOrder oldProductionOrder = productionSchedule.getProductionOrder();
            // ProductionOrder currentProductionOrder = productionOrderService.changeOrder(oldProductionOrder, startTime, lotNo);
            ProductionOrder currentProductionOrder = null;
            fillInData(oldProductionOrder, currentProductionOrder, longCrystal, flag);
        } else {
            List<ProductionSchedule> allByLotNo = null;
            String fromMark = lotNo.substring(SectionIndexRangeEnum.炉次号第一位.getBeginIndex(), SectionIndexRangeEnum.炉次号第一位.getEndIndex());
            if (fromMark.matches("[A-Z]+")) {
                allByLotNo = productionScheduleService.findAllByLotNo(lotNo.substring(SectionIndexRangeEnum.设备号.getBeginIndex(), SectionIndexRangeEnum.设备号.getEndIndex()));
            } else {
                allByLotNo = productionScheduleService.findAllByLotNo(lotNo.substring(2, 6));
            }
            if(!CollectionUtils.isEmpty(allByLotNo)){
                for (ProductionSchedule schedule : allByLotNo) {
                    //设备加工能力信息校验
                    ProductionOrder productionOrder1 = schedule.getProductionOrder();
                    Boolean aBoolean1 = checkProperties(schedule, productionOrder1, longCrystal, startTime, true);
                    if (aBoolean1) {
                        ProductionOrder oldProductionOrder = schedule.getProductionOrder();
                        // ProductionOrder currentProductionOrder = productionOrderService.changeOrder(oldProductionOrder, startTime, lotNo);
                        ProductionOrder currentProductionOrder = null;
                        fillInData(oldProductionOrder, currentProductionOrder, longCrystal, flag);
                        break;
                    } else {
                        //直接在单晶计划工单中查询符合要求的订单
                        MachineCapacityInfo machineCapacityInfo = machineCapacityInfoService.getMachineCapacityInfo(longCrystal.getConductiveType(), longCrystal.getProductType(), longCrystal.getSpecs(), longCrystal.getDopant());
                        List<ProductionOrder> productionOrders = productionOrderService.findByMachineCapacityIdAndStatusAndProductionStatusAndGmtCreateTime(machineCapacityInfo.getId(), "REL", true, startTime);
                        if(null != productionOrders && productionOrders.size() > 0){
                            longCrystal.setOrderId(productionOrders.get(0).getId());
                            if(flag){
                                longCrystal.setAdvanceOrder(productionOrders.get(0).getAufnr());
                            } else {
                                longCrystal.setOrderNo(productionOrders.get(0).getAufnr());
                            }
                            longCrystal.setOrderType(productionOrders.get(0).getAuart());
                            longCrystal.setSideLengthRange(productionOrders.get(0).getSideLengthRange());
                        }
                    }
                }
            }
        }*/
        if (longCrystal != null && !flag) {
//            if(null == longCrystal.getLineStartTime()){
            longCrystal.setLineStartTime(startTime);
//            }
            if (!flag) {
                longCrystal.setCrystalStatus(EnumValuesFactory.CrystalStatus.已划线.getKey());
            }
            longCrystal.setMinDiam(minDiam);
            longCrystal.setMaxDiam(maxDiam);
            saveOrUpdate(longCrystal);
        }
    }

    public Boolean checkProperties(ProductionSchedule productionSchedule, ProductionOrder productionOrder, LongCrystal longCrystal, Date startTime, Boolean stuckTime) {
        if (null == productionSchedule) {
            return false;
        }
        //长晶棒信息
        String specs = longCrystal.getSpecs();
        String dopant = longCrystal.getDopant();
        String productType = longCrystal.getProductType();

        Integer machineCapacityId = productionOrder.getMachineCapacityId();
        // 加工能力
        MachineCapacityInfo machineCapacityInfo = machineCapacityInfoService.get(machineCapacityId);
        if (null == machineCapacityInfo) {
            return false;
        }
        String dopant1 = machineCapacityInfo.getDopant();
        String productType1 = machineCapacityInfo.getProductType();
        String specs1 = machineCapacityInfo.getSpecification();

        // 计划结束时间
        Date gltrp = productionOrder.getGltrp();
        // 计划开始时间
        Date gstrp = productionOrder.getGstrp();

        Boolean flag = false;
        if (gstrp.getTime() <= startTime.getTime() && gltrp.getTime() >= startTime.getTime()) {
            flag = true;
        }

        if (!stuckTime) {
            flag = true;
        }

        //判断查到的工单是否符合设备加工能力和时间
        if (!StringUtils.equals(specs, specs1) || !StringUtils.equals(dopant, dopant1) || !StringUtils.equals(productType, productType1) || !flag) {
            return false;
        }
        return true;
    }

    public void fillInData(ProductionOrder oldProductionOrder, ProductionOrder currentProductionOrder, LongCrystal longCrystal, Boolean flag) {
        longCrystal.setSideLengthRange(oldProductionOrder.getSideLengthRange());
        if (currentProductionOrder == null) {
            longCrystal.setLastOrderId(oldProductionOrder.getId());
            longCrystal.setLastOrderNo(oldProductionOrder.getAufnr());
            longCrystal.setLastOrderType(oldProductionOrder.getAuart());

            longCrystal.setOrderId(oldProductionOrder.getId());
            if (flag) {
                longCrystal.setAdvanceOrder(oldProductionOrder.getAufnr());
            } else {
                longCrystal.setOrderNo(oldProductionOrder.getAufnr());
            }
            longCrystal.setOrderType(oldProductionOrder.getAuart());
        } else if (oldProductionOrder == currentProductionOrder) {

            longCrystal.setOrderId(oldProductionOrder.getId());
            if (flag) {
                longCrystal.setAdvanceOrder(oldProductionOrder.getAufnr());
            } else {
                longCrystal.setOrderNo(oldProductionOrder.getAufnr());
            }
            longCrystal.setOrderType(oldProductionOrder.getAuart());
        } else {

            longCrystal.setLastOrderId(oldProductionOrder.getId());
            if (flag) {
                longCrystal.setAdvanceOrder(oldProductionOrder.getAufnr());
            } else {
                longCrystal.setOrderNo(oldProductionOrder.getAufnr());
            }
            longCrystal.setLastOrderType(oldProductionOrder.getAuart());

            longCrystal.setOrderId(currentProductionOrder.getId());
            if (flag) {
                longCrystal.setAdvanceOrder(oldProductionOrder.getAufnr());
            } else {
                longCrystal.setOrderNo(oldProductionOrder.getAufnr());
            }
            longCrystal.setOrderType(currentProductionOrder.getAuart());
            longCrystal.setSideLengthRange(currentProductionOrder.getSideLengthRange());
        }
    }

    @Override
    public LongCrystal findBLotNoAndClosureIdentification(String crystalNo, String closureIdentification) {
        return dao.findBLotNoAndClosureIdentification(crystalNo, closureIdentification);
    }

    @Override
    public LongCrystal findTopByLotIdAndCrystalStatus(Long lotId, Integer crystalStatus) {
        return dao.findTopByLotIdAndCrystalStatus(lotId, crystalStatus);
    }

    @Override
    public void saveOrUpdate(LongCrystal longCrystal) {
        super.saveOrUpdate(longCrystal);
        try {
            inspectDataBaseChangeAsync.longCrystalDataBaseChange(longCrystal);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Result updateLastLongCrstalWeight(LongCrystalVO longCrystalVO) {
        String equipmentCode = longCrystalVO.getDeviceCode();
        Map<String, String> startCollectionData = longCrystalVO.getStartCollectionData();
        BigDecimal length = new BigDecimal(startCollectionData.get("1274Max")).setScale(2, BigDecimal.ROUND_HALF_UP);
        BigDecimal weight = new BigDecimal(startCollectionData.get("等径结束的重量"));
        BigDecimal lastWeight = new BigDecimal(startCollectionData.get("3287"));
        try {
            BigDecimal length1 = length.add(new BigDecimal(-3));
            BigDecimal length2 = length.add(new BigDecimal(13));
            dao.updateLastLongCrstalWeight(equipmentCode, length1, length2, lastWeight);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success();
    }

    @Override
    public Result updateWeightAndHeight(LongCrystalInfoDto dto) {
        LongCrystal entity = get(dto.getId());
        if (entity == null) {
            return ResultGenerator.fail("原信息不存在");
        }

        //修改单晶状态
        entity.setWeight(dto.getWeight());
        entity.setLength(dto.getLength());
        saveOrUpdate(entity);
        return ResultGenerator.success();
    }

    @Override
    public List<LongCrystal> findByGmtCreate(String startTime, String endTime) {
        return dao.findByGmtCreate(startTime, endTime);
    }

    @Override
    public List<String> findByGmtCreate1(String startTime, String endTime, String area, String s) {
        return dao.findByGmtCreate1(startTime, endTime, area, s);
    }

    @Override
    public List<LongCrystal> findByGmtCreate2(List<String> lotNoList, String area, String s) {
        return dao.findByGmtCreate2(lotNoList, area, s);
    }

    @Override
    public BigDecimal findByGmtCreateAndAreaAndarea(String startTime, String endTime, String area) {
        return dao.findByGmtCreateAndAreaAndarea(startTime, endTime, area);
    }

    @Override
    public BigDecimal findByGmtCreateAndAreaAndarea1(String startTime, String endTime, String area) {
        return dao.findByGmtCreateAndAreaAndarea1(startTime, endTime, area);
    }

    @Override
    public List<Map<String, Object>> pullOutPutData() {
        return dao.pullOutPutData();
    }

    @Override
    public List<Map<String, Object>> pullOutPutDataCut() {
        return dao.pullOutPutDataCut();
    }

    @Override
    public void updatePulledState(List<Long> idList) {
        dao.updatePulledState(idList);
    }

    @Override
    public void updateSquarePulledState(List<Long> idList) {
        dao.updateSquarePulledState(idList);
    }

    @Override
    public LongCrystal getLastId(String equipmentCode, Long id) {
        return dao.getLastId(equipmentCode, id);
    }

    @Override
    public List<LongCrystal> findByLotNoAndAgainNum(String lotNo, Integer againNum) {
        return dao.findByLotNoAndAgainNum(lotNo, againNum);
    }

    @Override
    public LongCrystal findDeviceNoAndCreateTime(String deviceNo, Date createTime, Integer crystalStatus) {
        return dao.findDeviceNoAndCreateTime(deviceNo, createTime, crystalStatus);
    }

    @Override
    public BigDecimal findSumWeightByOrderNo(String orderNo) {
        return dao.findSumWeightByOrderNo(orderNo);
    }

    @Override
    public LongCrystal findLastByEquipmentCode(String equipmentCode) {
        AgainTask task = againTaskService.findCompletedTopByEquipmentCode(equipmentCode);
        if (ObjectUtils.isEmpty(task)) return null;
        return dao.findLastByLotNoAndAgainNum(task.getLotNo(), task.getAgainNum());
    }

    @Override
    public LongCrystal findLastRightByLotNoAndAgainNum(String lotNo, Integer againNum, Long id) {
        return dao.findLastRightByLotNoAndAgainNum(lotNo, againNum, id);
    }

    @Override
    public List<LongCrystal> findUnconfirmedByLotNo(String lotNo) {
        return dao.findUnconfirmedByLotNo(lotNo);
    }


    @Override
    public List<LongCrystalWorkHourDto> getCrystalWorkHour(List<String> orderList) {

        List<LongCrystalWorkHourDto> longCrystalWorkHourDtos = new ArrayList<>();

        List<LongCrystal> byOrderNo = dao.findByOrderNo(orderList);
        List<String> collect = byOrderNo.stream().map(longCrystal -> longCrystal.getLotNo()).collect(Collectors.toList());
        List<LongCrystal> byLotNos = this.findByLotNos(collect);
        Map<String, List<LongCrystal>> collect1 = byLotNos.stream().collect(Collectors.groupingBy(LongCrystal::getLotNo));

        if(null != byOrderNo && byOrderNo.size() > 0){
            for (LongCrystal longCrystal : byOrderNo) {
                LongCrystalWorkHourDto longCrystalWorkHourDto = new LongCrystalWorkHourDto();
                List<LongCrystal> longCrystalList = collect1.get(longCrystal.getLotNo());

                //首棒
                Long startTime = 0L;
                if(longCrystal.getAgainNum() == 1 && longCrystal.getCrystalNum() == 1){
                    ProcessWorkingHours hours;
                    hours = processWorkingHoursService.findByLotNoAndStep(longCrystal.getLotNo(), "抽真空");
                    if(null == hours){
                        hours = processWorkingHoursService.findByLotNoAndStep(longCrystal.getLotNo(), "熔料工时");
                    }
                    if(null == hours){
                        longCrystalWorkHourDto.setCrystalNo(longCrystal.getCrystalNo());
                        longCrystalWorkHourDto.setOrderNo(longCrystal.getOrderNo());
                        longCrystalWorkHourDtos.add(longCrystalWorkHourDto);
                        continue;
                    }
                    startTime = hours.getStartTime().getTime();
                } else {
                    //中间棒或尾棒
                    for (LongCrystal crystal : longCrystalList) {
                        if(crystal.getAgainNum().equals(longCrystal.getAgainNum()) && crystal.getCrystalNum() == longCrystal.getCrystalNum() - 1){
                            startTime = crystal.getGmtCreate().getTime();
                            if(startTime > 0){
                                break;
                            }
                        }
                    }

                    for (LongCrystal crystal : longCrystalList) {
                        if(crystal.getAgainNum().equals(longCrystal.getAgainNum() - 1)){
                            startTime = crystal.getGmtCreate().getTime();
                            if(startTime > 0){
                                break;
                            }
                        }
                    }
                }
                longCrystalWorkHourDto.setCrystalNo(longCrystal.getCrystalNo());
                longCrystalWorkHourDto.setOrderNo(longCrystal.getOrderNo());
                longCrystalWorkHourDto.setWorkHour(new BigDecimal((longCrystal.getGmtCreate().getTime()-startTime)).divide(new BigDecimal(3600000),3, RoundingMode.HALF_UP).setScale(3, BigDecimal.ROUND_HALF_UP));
                longCrystalWorkHourDtos.add(longCrystalWorkHourDto);
            }
        }
        return longCrystalWorkHourDtos;
    }

    public List<LongCrystal> findByLotNos(List<String> lotNos) {

        return dao.findByLotNos(lotNos);
    }

    @Override
    public List<LongCrystal> findByTakeCrystalAgvTaskCode(String takeCrystalAgvTaskCode) {
        return dao.findByTakeCrystalAgvTaskCode(takeCrystalAgvTaskCode);
    }

}
