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

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.sw.mes.base.factory.init.entity.CrystalMaterialRelation;
import com.sw.mes.base.factory.init.entity.FactoryModel;
import com.sw.mes.base.factory.init.service.CrystalMaterialRelationService;
import com.sw.mes.base.factory.init.service.FactoryModelService;
import com.sw.mes.base.factory.inspect.service.DefaultCrystalAttrService;
import com.sw.mes.base.factory.material.entity.MaterialModel;
import com.sw.mes.base.factory.material.service.MaterialModelService;
import com.sw.mes.base.factory.utils.PageUtils;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.core.entity.CrystalLossRecord;
import com.sw.mes.base.workinprocess.entity.PlanProcessingOrder;
import com.sw.mes.base.workinprocess.entity.WipStorage;
import com.sw.mes.base.workinprocess.service.CrystalLossRecordService;
import com.sw.mes.base.workinprocess.service.PlanProcessingOrderService;
import com.sw.mes.base.workinprocess.service.WipStorageService;
import com.sw.mes.core.api.system.FbFeignClients;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.constant.Constants;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.dto.CooperateDataInfoDto;
import com.sw.mes.core.entity.FbCheckOutData;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.enums.SectionIndexRangeEnum;
import com.sw.mes.core.enums.SeedMassageEnum;
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.DateUtil;
import com.sw.mes.core.utils.NumberUtil;
import com.sw.mes.core.utils.RequestPage;
import com.sw.mes.core.utils.StringUtils;
import com.sw.mes.dingTalk.service.DingTalkService;
import com.sw.mes.enumvalue.EnumValuesServer;
import com.sw.mes.inspect.entity.YbInspectData;
import com.sw.mes.inspect.service.YbInspectDataService;
import com.sw.mes.yb.pad.dao.*;
import com.sw.mes.yb.pad.dto.RecutDto;
import com.sw.mes.yb.pad.dto.RecutInfoFbDetailInfo;
import com.sw.mes.yb.pad.entity.*;
import com.sw.mes.yb.pad.service.*;
import com.sw.mes.yb.production.entity.LongCrystal;
import com.sw.mes.yb.production.service.LongCrystalService;
import com.sw.mes.yb.turnstore.dao.ProductionBindingTrayDao;
import com.sw.mes.yb.turnstore.entity.ProductionBindingTray;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.hibernate.Session;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
@Slf4j
public class FbReCutServiceImpl extends BaseServiceImpl<ReCut> implements FbReCutService {

    FbReCutDAO fbReCutDAO;

    @Autowired
    private SectionNoDetailDao sectionNoDetailDao;
    @Autowired
    private ProductionRecutServiceImpl productionRecutServiceImpl;
    @Autowired
    private PlanProcessingOrderService planProcessingOrderService;

    @Autowired
    public void setDao(FbReCutDAO fbReCutDAO) {
        this.fbReCutDAO = fbReCutDAO;
        super.setBaseDao(fbReCutDAO);
    }

    @Autowired
    private ModelMapper modelMapper;

    @Autowired
    private ProductionPaintingLineDetailDao productionPaintingLineDetailDao;

    @Autowired
    private ZhxxOperateCheckOutDataDao zhxxOperateCheckOutDataDao;

    @Autowired
    private ProductionBindingTrayDao productionBindingTrayDao;

    @Autowired
    private RecutDetailDao recutDetailDao;

    @Autowired
    private RecutDetailService recutDetailService;

    @Autowired
    private WipStorageService wipStorageService;

    @Autowired
    private DefaultCrystalAttrService defaultCrystalAttrService;
    @Autowired
    private DictionaryItemService dictionaryItemService;

    @Autowired
    private YbInspectDataService ybInspectDataService;

    @PersistenceContext
    private EntityManager entityManager;

    @Autowired
    private SectionNoDetailService sectionNoDetailService;

    @Autowired
    private PieceDetailDao pieceDetailDao;


    @Autowired
    private FbFeignClients fbFeignClients;
    @Autowired
    private DingTalkService dingTalkService;

    @Autowired
    private CrystalLossRecordService crystalLossRecordService;

    @Autowired
    private CrystalMaterialRelationService crystalMaterialRelationService;
    @Autowired
    private MaterialModelService materialModelService;
    @Autowired
    private LongCrystalService longCrystalService;

    @Autowired
    private ProductionPaintingLineService productionPaintingLineService;


    @Autowired
    private FactoryModelService factoryModelService;



    @Override
    public List<ReCut> findByExample(Specification<ReCut> specification, RequestPage page) {
        org.springframework.data.domain.Page<ReCut> springDataPage = fbReCutDAO.findAll(specification, PageUtils.createPageable(page));
        page.setTotal(springDataPage.getTotalElements());
        return springDataPage.getContent();
    }

    /**
     * 通过托盘绑定信息 找到对应晶段
     *
     * @param trayNo
     * @return
     */
    @Override
    public Result<Map<String, Object>> findByTrayNo(String trayNo) {
        // 通过托盘绑定信息 找到对应晶段
        List<ProductionBindingTray> byTrayNo = this.productionBindingTrayDao.findByTrayNo(trayNo);
        if (byTrayNo.size() != 1) {
            return ResultGenerator.fail("此载具找不到唯一方棒信息");
        }
        ProductionBindingTray productionBindingTray = byTrayNo.get(0);
        // 晶段编号,用于记录返切画线生成编号
        String segmentNo = productionBindingTray.getCrystalNo();
        Map<String, Object> map = new HashMap<>();
        map.put("segmentNo", segmentNo);
        map.put("length", getSecitonNoInfo(segmentNo).getData());
        return ResultGenerator.success(map);
    }

    @Override
    public Result<BigDecimal> getSecitonNoInfo(String sectionNoFb) {
        // 检验数据提交判断是否在方棒检验已进站状态
        wipStorageService.selectWipStorage(sectionNoFb, EnumValuesFactory.WipStorageCode.方棒检验.getKey(), true);
        RecutDetail recutDetail = recutDetailService.findBySectionNoFb(sectionNoFb);
        if (!sectionNoFb.startsWith("B") && recutDetail == null) {
            return ResultGenerator.fail("该方棒:" + sectionNoFb + "无追溯信息");
        }
        List<FbCheckOutData> listBySectionNoFbs = this.zhxxOperateCheckOutDataDao.findByFbSectionNo(sectionNoFb);
        if (listBySectionNoFbs.size() == 0) {
            return ResultGenerator.fail("该方棒:" + sectionNoFb + "无检验信息");
        }
        if (listBySectionNoFbs.get(0).getSticksCount() > 1) {
            return ResultGenerator.fail("该方棒:" + sectionNoFb + "为拼棒，无法反切");
        }

        return ResultGenerator.success(listBySectionNoFbs.get(0).getLength());
    }

    /**
     * 保存方棒反切后的晶段信息
     *
     * @param recutDto
     * @return
     */
    @Override
    public Result saveSegmentNo(RecutDto recutDto) {
        // 检验数据提交判断是否在方棒检验已进站状态
        wipStorageService.selectWipStorage(recutDto.getSegmentNo(), EnumValuesFactory.WipStorageCode.方棒检验.getKey(), true);
        recutDto.setProcessCode(EnumValuesFactory.WipStorageCode.方棒检验.getValue());
        ReCut reCut = fromDto(recutDto);
        reCut.setEndTime(new Date());
        List<ReCut> byCrystalSectionNo = this.fbReCutDAO.findByCrystalSectionNoAndStatus(recutDto.getSegmentNo(), 0);
        if (byCrystalSectionNo.size() > 0) {
            return ResultGenerator.fail("该单晶存在未截断的返切记录!请勿重复操作");
        }
        reCut.setRecutType(recutDto.getCutType());
        RecutDetail recutDetail = recutDetailService.findBySectionNoFb(recutDto.getSegmentNo());
        if (recutDetail == null) {
            return ResultGenerator.fail("该方棒:" + recutDto.getSegmentNo() + "无追溯信息");
        }
        List<FbCheckOutData> listBySectionNoFbs = this.zhxxOperateCheckOutDataDao.findByFbSectionNo(recutDto.getSegmentNo());
        if (listBySectionNoFbs.size() == 0) {
            return ResultGenerator.fail("该方棒:" + recutDto.getSegmentNo() + "无检验信息");
        }
        if (listBySectionNoFbs.get(0).getSticksCount() > 1) {
            return ResultGenerator.fail("该方棒:" + recutDto.getSegmentNo() + "为拼棒，无法反切");
        }
       /* List<DictionaryItem> paintCrystalUsedLength = dictionaryItemService.findByThemeValueAndEnable("paintCrystalUsedLength", true);
        Map<String, String> collect = paintCrystalUsedLength.stream().collect(Collectors.toMap(DictionaryItem::getName, DictionaryItem::getValue));
        if(!collect.containsKey(EnumValuesServer.SQUARE)){
            throw new BusinessException("请前往数据字典配置规格为【" + listBySectionNoFbs.get(0).getSpecification() + "】的划线晶段可用长度控制");
        }
        Integer length = Integer.valueOf(collect.get(EnumValuesServer.SQUARE));*/
        BigDecimal segmentLength = new BigDecimal("0");
        for (RecutInfoFbDetailInfo datum : recutDto.getDetail()) {
            if (datum.getType() == EnumValuesServer.LineType.晶段.getKey()) {
               /* if(datum.getLength().compareTo(new BigDecimal(length)) < 0){
                    throw new BusinessException(datum.getSegmentNo() + "：晶段长度小于有效长度");
                }*/
                segmentLength = segmentLength.add(datum.getLength());
            }
        }
        //反切长度
        reCut.setRecutLength(reCut.getSegmentNoLength().subtract(segmentLength));
        //方棒规格
        reCut.setSpecs(listBySectionNoFbs.get(0).getSpecification());
        fbReCutDAO.save(reCut);
        List<ProductionPaintingLineDetail> detailList = new ArrayList<>();
        // 晶段追溯信息集合
        List<RecutDetail> recutDetails = new ArrayList<>();
        //List<DictionaryItem> dictionaryItems = dictionaryItemService.findByThemeValueAndItemName(Constants.WEIGHT_RATIO, listBySectionNoFbs.get(0).getSpecification().substring(0, 3), true);
        List<DictionaryItem> dictionaryItems = dictionaryItemService.findByThemeValueAndItemName(Constants.WEIGHT_RATIO, listBySectionNoFbs.get(0).getSpecification(), true);
        if (dictionaryItems.size() == 0) {
            //throw new BusinessException("请配置【" + listBySectionNoFbs.get(0).getSpecification().substring(0, 3) + "】规格的理论重量系数");
            throw new BusinessException("请配置【" + listBySectionNoFbs.get(0).getSpecification() + "】规格的理论重量系数");
        }
        BigDecimal weightLossCoefficient = NumberUtil.Object2BigDecimal(dictionaryItems.get(0).getValue());
        if (weightLossCoefficient == null || weightLossCoefficient.compareTo(new BigDecimal("1")) < 1) {
            throw new BusinessException("【" + dictionaryItems.get(0).getValue() + "】理论重量系数格式不正确，只能为大于0的数字类型");
        }
        //回收料段数
        Integer count = 0;
        SectionNoDetail sectionNoDetail = sectionNoDetailService.findBySectionNo(recutDetail.getSectionNo());
        List<PieceDetail> pieceDetails = new ArrayList<>();
        // List<DefaultCrystalAttr> defaultCrystalAttrList = defaultCrystalAttrService.findByDopantLikeAndSpecificationsLikeOrderByIdDesc(listBySectionNoFbs.get(0).getDopant(), listBySectionNoFbs.get(0).getSpecification().substring(0, 3));
        // 不合格反切
        for (int i = 0; i < recutDto.getDetail().size(); i++) {
            RecutInfoFbDetailInfo datum = recutDto.getDetail().get(i);
            if (datum.getType() == EnumValuesServer.LineType.晶段.getKey()
                    && datum.getLength().compareTo(new BigDecimal(60)) < 0) {
                throw new BusinessException("晶段长度不能小于60");
            }
            ProductionPaintingLineDetail detail1 = new ProductionPaintingLineDetail();
            detail1.setCreateTime(new Date());
            detail1.setOperateReversecutDrawId(reCut.getId());
            detail1.setCrystalId(recutDetail.getCrystalId());
            detail1.setNo(datum.getSegmentNo());
            detail1.setLength(datum.getLength());
            detail1.setRemark(datum.getRemark());
            detail1.setSequence(datum.getIndex());
            detail1.setParentId(0);
            detail1.setIsCut(0);
            detail1.setType(datum.getType());
            // 方棒
            detail1.setCrystalType(1);
            detail1.setWeight(datum.getLength().divide(weightLossCoefficient, 2, RoundingMode.CEILING));
            if (null == detail1.getCrystalId()) {
                detail1.setCrystalId(0L);
            }
            detailList.add(detail1);
            if (detail1.getType() == EnumValuesServer.LineType.晶段.getKey()) {
                RecutDetail recutDetailNew = new RecutDetail();
                recutDetailNew.setSectionNoFb(datum.getSegmentNo());
                recutDetailNew.setYbId(recutDetail.getYbId());
                recutDetailNew.setSectionNo(recutDetail.getSectionNo());
                recutDetailNew.setMaterial(null);
                recutDetailNew.setIsCut(0);
                recutDetailNew.setParentId(recutDetail.getId());
                recutDetailNew.setCreateUser(BaseContextHandler.getUsername());
                recutDetailNew.setCrystalId(recutDetail.getCrystalId());
                recutDetailNew.setCreateDate(new Date());
                if (i - 1 >= 0 && EnumValuesServer.LineType.样片.getKey() == recutDto.getDetail().get(i - 1).getType()) {
                    recutDetailNew.setPieceNoHead(recutDto.getDetail().get(i - 1).getSegmentNo());
                }
                if (i + 1 < recutDto.getDetail().size() && EnumValuesServer.LineType.样片.getKey() == recutDto.getDetail().get(i + 1).getType()) {
                    recutDetailNew.setPieceNoEnd(recutDto.getDetail().get(i + 1).getSegmentNo());
                }
                recutDetails.add(recutDetailNew);
            }
            if (datum.getType() == EnumValuesServer.LineType.回收料.getKey()) {
                count++;
            }
            if (datum.getType() == EnumValuesServer.LineType.样片.getKey()) {
                PieceDetail pieceDetail = new PieceDetail();
                pieceDetail.setPieceNo(datum.getSegmentNo());
                pieceDetail.setType(1);
                pieceDetail.setConductiveType(sectionNoDetail.getConductiveType());
                pieceDetail.setDopant(sectionNoDetail.getDopant());
                pieceDetail.setSpecs(sectionNoDetail.getSpecs());
                pieceDetail.setCrystalId(sectionNoDetail.getCrystalId());
                pieceDetail.setCrystalNo(sectionNoDetail.getCrystalNo());
                pieceDetail.setLotNo(sectionNoDetail.getLotNo());
                pieceDetail.setEquipmentCode(sectionNoDetail.getEquipmentCode());
                pieceDetail.setProductType(sectionNoDetail.getProductType());
                pieceDetail.setProductCode(sectionNoDetail.getProductCode());
                pieceDetail.setProductGrade(sectionNoDetail.getProductGrade());
                pieceDetail.setSegmentId(sectionNoDetail.getId());
                pieceDetail.setCreateDate(new Date());
                pieceDetail.setIsQualified(0);
                pieceDetail.setSegmentNum(sectionNoDetail.getSegmentNum());
                pieceDetail.setBackCut(EnumValuesFactory.ConfirmIdentification.YES.getValue());
                pieceDetails.add(pieceDetail);
            }
        }
        if (!pieceDetails.isEmpty()) {
            pieceDetailDao.saveAll(pieceDetails);
        }
        if (recutDetails.size() > 0) {
            recutDetailService.saveAll(recutDetails);
        }
        //如果是分段反切，则将其切断类型变为已切断，不合格反切不会产生新编号不改变其状态
//        if (recutDto.getCutType() == 2) {
        recutDetail.setIsCut(1);
        recutDetail.setCreateUser(BaseContextHandler.getUsername());
        recutDetailService.saveOrUpdate(recutDetail);
//        }
        productionPaintingLineDetailDao.saveAll(detailList);
        // 出库到截断工序
        Result result = wipStorageService.outStation(recutDto.getSegmentNo(), "B", null);
        if (count == recutDto.getDetail().size()) {
            PlanProcessingOrder planProcessingOrder = planProcessingOrderService.findByCode(recutDto.getSegmentNo());
            if (planProcessingOrder != null) {
                planProcessingOrder.setStatus(EnumValuesFactory.PlanProcessingOrderStatus.已作废.getKey());
                planProcessingOrderService.saveOrUpdate(planProcessingOrder);
            }
        }
        //返切将方棒返切标识标记为返切
        fbFeignClients.updateBackCutByFbSectionNo(recutDto.getSegmentNo(),1);

        //推送晶彩
        this.handleRobotSeedMessage(reCut,sectionNoDetail,listBySectionNoFbs.get(0));

        if (ResultCode.SUCCESS.getCode() == result.getCode()) {
            return ResultGenerator.success();
        }
        return ResultGenerator.fail("方棒反切后的晶段信息: " + result.getMessage());
    }

    private void handleRobotSeedMessage(ReCut reCut,SectionNoDetail sectionNoDetail,FbCheckOutData fbCheckOutData){
        if (null == reCut){
            return;
        }
        StringBuffer content = new StringBuffer();
        content.append(". [MES推送]晶棒损耗:").append("\n");
        content.append(". ").append(reCut.getSegmentNo()).append("\n");
        content.append(".时间：").append(DateUtil.formatDate1(reCut.getEndTime())).append("\n");
        content.append(".切方损耗").append("\n");
        content.append(".损耗工序：").append("方棒返切").append("\n");
        content.append(".损耗原因：").append(reCut.getReason()).append("\n");
        content.append(".损耗长度：").append(reCut.getRecutLength()).append("\n");
        if (null != reCut.getSegmentNoLength() && null != reCut.getRecutLength()){
            content.append(".剩余长度：").append(reCut.getSegmentNoLength().subtract(reCut.getRecutLength())).append("\n");
        }
        content.append(".录入人：").append(reCut.getOperateUser()).append("\n");
        content.append(".备注：").append(StringUtils.isNotBlank(reCut.getRemark()) ? reCut.getRemark() : "").append("\n");
        ArrayList<String> sceneList = new ArrayList<>();
        ArrayList<String> groupNameList = new ArrayList<>();
        sceneList.add("prod");
        String groupName = "切方长度损耗实时推送群";
        groupNameList.add(groupName);
        String source = "晶棒损耗";
        dingTalkService.robotSeedMessage(String.valueOf(content), groupNameList, source, sceneList, SeedMassageEnum.GROUP);

        //处理损耗记录
        CrystalLossRecord crystalLossRecord = new CrystalLossRecord();
        crystalLossRecord.setSectionNo(reCut.getSegmentNo());
        crystalLossRecord.setLossLength(reCut.getRecutLength());
        crystalLossRecord.setRodLength(reCut.getSegmentNoLength());
        if (null != sectionNoDetail){
            crystalLossRecord.setCrystalNo(sectionNoDetail.getCrystalNo());
            BigDecimal weightLossCoefficient = null;
            if (null != reCut.getSegmentNoLength() && null != reCut.getRecutLength()){
                crystalLossRecord.setRemainLength(reCut.getSegmentNoLength().subtract(reCut.getRecutLength()));
            }
            if (StringUtils.isNotBlank(sectionNoDetail.getSpecs())){
                List<DictionaryItem> dictionaryItems = dictionaryItemService.findByThemeValueAndItemName(Constants.THEORETICAL_WEIGHT_COEFFICIENTFB, sectionNoDetail.getSpecs(), true);
                if (!org.springframework.util.CollectionUtils.isEmpty(dictionaryItems)) {
                    weightLossCoefficient = NumberUtil.Object2BigDecimal(dictionaryItems.get(0).getValue());
                    if (null != weightLossCoefficient && weightLossCoefficient.compareTo(BigDecimal.ONE) > 0) {
                        if (null != reCut.getRecutLength()) {
                            crystalLossRecord.setLossWeight(reCut.getRecutLength().divide(weightLossCoefficient, 3, RoundingMode.HALF_UP));
                        }
                        if (null != crystalLossRecord.getRemainLength()){
                            crystalLossRecord.setRemainWeight(crystalLossRecord.getRemainLength().divide(weightLossCoefficient, 3, RoundingMode.HALF_UP));
                        }
                    }
                }
            }
            if (null != fbCheckOutData){
                CrystalMaterialRelation crystalMaterialRelationKf = crystalMaterialRelationService.findBySectionNo(fbCheckOutData.getYbSectionNo());
                if (null != crystalMaterialRelationKf){
                    if (null != crystalMaterialRelationKf.getMaterialModelId()){
                        MaterialModel materialModel = materialModelService.get(crystalMaterialRelationKf.getMaterialModelId());
                        if (null != materialModel){
                            crystalLossRecord.setMaterialName(materialModel.getName());
                        }
                    }
                    crystalLossRecord.setSquareMachine(crystalMaterialRelationKf.getDeviceNo());
                    crystalLossRecord.setMaterialCode(crystalMaterialRelationKf.getMaterialCode());
                    crystalLossRecord.setOrderNo(crystalMaterialRelationKf.getOrderNo());
                }
            }
            CrystalMaterialRelation crystalMaterialRelationJd = crystalMaterialRelationService.findBySectionNo(sectionNoDetail.getCrystalNo());
            if (null != crystalMaterialRelationJd){
                crystalLossRecord.setCutMachine(crystalMaterialRelationJd.getDeviceNo());
            }

            LongCrystal longCrystal = longCrystalService.findByCrystalNo(sectionNoDetail.getCrystalNo());
            if (null != longCrystal){
                crystalLossRecord.setArea(longCrystal.getSeries());

                FactoryModel factoryModel = factoryModelService.findByCode(longCrystal.getArea());
                if (null != factoryModel){
                    crystalLossRecord.setWorkshop(factoryModel.getName());
                }
                crystalLossRecord.setSimpleName(longCrystal.getSimpleName());
            }
            //处理圆棒划线数据
            if (StringUtils.isNotBlank(sectionNoDetail.getCrystalNo())){
                ProductionPaintingLine productionPaintingLine = productionPaintingLineService.findByCrystalNo(sectionNoDetail.getCrystalNo());
                if (null != productionPaintingLine){
                    crystalLossRecord.setRodTime(productionPaintingLine.getEndTime());
                    crystalLossRecord.setRodInspector(productionPaintingLine.getUserName());
                }
            }
          /*  crystalLossRecord.setRodTime(sectionNoDetail.getCreateDate());
            crystalLossRecord.setRodInspector(sectionNoDetail.getCreateUser());*/
        }

        crystalLossRecord.setLossProcessName("方棒返切");
        crystalLossRecord.setMajorCategories(EnumValuesFactory.CrystalLossType.CUTTING_LOSS.getValue());

        crystalLossRecord.setLossType(reCut.getReason());
        crystalLossRecord.setCreateName(reCut.getOperateUser());

        if (null != reCut.getEndTime()){
            crystalLossRecord.setCreateTime(reCut.getEndTime());
        }else {
            crystalLossRecord.setCreateTime(new Date());
        }
        crystalLossRecord.setOperateRemark(reCut.getRemark());
        crystalLossRecordService.saveOrUpdate(crystalLossRecord);
    }

    @Override
    public ReCut findReCutInfoBySectionNo(String sectionNo) {
        List<ReCut> reCutList = fbReCutDAO.findByCrystalSectionNo(sectionNo);
        if (reCutList.size() > 0) {
            return reCutList.get(0);
        }
        return null;
    }

    @Override
    public Result<RecutDto> getSectionNoFbRecutInfo(RecutDto recutDto) {
        Result<BigDecimal> result = getSecitonNoInfo(recutDto.getSegmentNo());
        if (result.getCode() != ResultCode.SUCCESS.getCode()) {
            throw new BusinessException(result.getMessage());
        }
        if (recutDto.getSegmentNoLength().compareTo(result.getData()) != 0) {
            throw new BusinessException("晶段长度不一致");
        }
        getSegmentNo(recutDto);
//        getSegmentNo2(recutDto);
        /*List<FbCheckOutData> byFbSectionNo = zhxxOperateCheckOutDataDao.findByFbSectionNo(recutDto.getSegmentNo());
        List<DictionaryItem> paintCrystalUsedLength = dictionaryItemService.findByThemeValueAndEnable("paintCrystalUsedLength", true);
        Map<String, String> collect = paintCrystalUsedLength.stream().collect(Collectors.toMap(DictionaryItem::getName, DictionaryItem::getValue));
        if(!collect.containsKey(EnumValuesServer.SQUARE)){
            throw new BusinessException("请前往数据字典配置规格为【方棒】的划线晶段可用长度控制");
        }
        Integer length = Integer.valueOf(collect.get(EnumValuesServer.SQUARE));
        getNewSegmentNo(recutDto, length);*/
        return ResultGenerator.success(recutDto);
    }

    @Override
    public void deleteReCut(Long id) {
        ReCut reCut = get(id);
        if (reCut.getStatus()) {
            throw new BusinessException("该划线信息已切断，无法删除");
        }
        List<SectionNoDetail> sectionNoDetails = sectionNoDetailDao.findBySectionNo(reCut.getSegmentNo());
        if (sectionNoDetails.isEmpty()) {
            throw new BusinessException("晶段数据不存在");
        }
        // 检验数据提交判断是否在截断待进站状态
        wipStorageService.selectWipStorage(reCut.getSegmentNo(), EnumValuesFactory.WipStorageCode.方棒截断.getKey(), false);
        // 删除晶棒信息
        List<String> segmentNos = this.productionPaintingLineDetailDao.findByFbOperateRecutDrawId(id);
        List<RecutDetail> bySectionNos = this.recutDetailDao.findBySectionNoFb(segmentNos);
        if (bySectionNos != null && bySectionNos.size() > 0) {
            recutDetailDao.deleteInBatch(bySectionNos);
        }
        List<RecutDetail> bySectionNosParat = this.recutDetailDao.findBySectionNoFb(reCut.getSegmentNo());
        if (!bySectionNosParat.isEmpty()) {
            bySectionNosParat.get(0).setIsCut(0);
            recutDetailDao.save(bySectionNosParat.get(0));
        }

        // 删除样片
        List<PieceDetail> pieceNo = this.pieceDetailDao.findByPieceNo(segmentNos);
        if (pieceNo != null && !pieceNo.isEmpty()) {
            this.pieceDetailDao.deleteInBatch(pieceNo);
        }

        //删除方棒反切划线信息
        productionPaintingLineDetailDao.deleteFbByOperateRecutDrawId(id);
        //删除方棒反切划线
        delete(id);
        // 出库到截断工序
        wipStorageService.exitStation(reCut.getSegmentNo());
        List<String> segmentNoIndexs = new ArrayList<>();
        List<ProductionPaintingLineDetail> productionPaintingLineDetails = productionPaintingLineDetailDao.findByOperateRecutDrawIdFb(reCut.getId());
        productionRecutServiceImpl.resetRetCutSegmentNum(sectionNoDetails, segmentNoIndexs, productionPaintingLineDetails);

    }

    @Override
    public ReCut findBySectionNoAndStatus(String sectionNo, int status) {
        List<ReCut> reCutList = fbReCutDAO.findByCrystalSectionNoAndStatus(sectionNo, status);
        if (!reCutList.isEmpty()) {
            return reCutList.get(0);
        }
        return null;
    }


    /**
     * 生成晶段编号(方棒反切)
     * 20230322
     * wujiaxin
     *
     * @param recutDto
     */
    public void getNewSegmentNo(RecutDto recutDto, Integer length) {
        // 原有晶段编号
        String segmentNo = StringUtils.upperCase(recutDto.getSegmentNo().trim());

        List<RecutDetail> recutDetails = recutDetailService.getAllDataBySectionNoFb(segmentNo);
        if (CollectionUtils.isEmpty(recutDetails) || recutDetails.size() == 0) {
            if (segmentNo.startsWith("B")) {
                RecutDetail recutDetail = new RecutDetail();
                recutDetail.setSectionNo(segmentNo);
                recutDetail.setSectionNoFb(segmentNo);
                recutDetail.setParentId(0L);
                recutDetail.setCreateDate(new Date());
                recutDetail.setCreateUser(BaseContextHandler.getUsername());
                recutDetail.setRetCutSegmentNum(0);
                recutDetail.setIsCut(0);
                YbInspectData ybInspectData = ybInspectDataService.getSectionNo(segmentNo);
                if (null != ybInspectData) {
                    recutDetail.setCrystalId(ybInspectData.getId());
                }
                recutDetailService.saveOrUpdate(recutDetail);
                recutDetails = recutDetailService.getAllDataBySectionNoFb(segmentNo);
            } else {
                throw new BusinessException(segmentNo + "晶段编号不存在");
            }
        }

        // 反切明细
        List<RecutInfoFbDetailInfo> detail = recutDto.getDetail();
        if (detail.size() < 1) {
            throw new BusinessException(segmentNo + "切断明细内，至少包含一段晶段");
        }
        //回收料段数
        int materialIndex = 1;
        //晶段段数
        int segmentIndex = 1;
        //头片段数
        int headPieceCount = 0;
        //尾片段数
        int tailPieceCount = 0;
        //最后一段的序号
        int lsatSegmentIndexNo = 1;

        RecutDetail recutDetail = recutDetails.get(0);

        // 获取detail.size()个没有用到的segmentCount
        LinkedList<String> segmentIndexs = getSegmentNoIndex(recutDetail, detail.size());
        for (int i = 0; i < detail.size(); i++) {
            if (EnumValuesServer.LineType.晶段.getKey() == detail.get(i).getType()) {
                // 去除晶段编号最后一位 拼接新的尾号
                if (detail.get(i).getLength().compareTo(new BigDecimal(length)) < 0) {
                    throw new RuntimeException("晶段长度小于有效长度" + length);
                }
                segmentNo = segmentNo.substring(0, segmentNo.length() - 1) + segmentIndexs.get(segmentIndex - 1);
                detail.get(i).getSegmentIndex().setMaterialNum(0);
                detail.get(i).getSegmentIndex().setTailPieceNum(0);
                detail.get(i).getSegmentIndex().setHeadPieceNum(0);
                detail.get(i).setSegmentNo(segmentNo);
                //头样片最大序号赋值
                detail.get(i).getSegmentIndex().setHeadPieceNum(headPieceCount);
                headPieceCount = 0;
                if (segmentIndex != 0) {
                    //尾样片最大序号赋值
                    detail.get(lsatSegmentIndexNo).getSegmentIndex().setTailPieceNum(tailPieceCount);
                }
                tailPieceCount = 0;
                //晶段段数++
                segmentIndex++;
                lsatSegmentIndexNo = i;
            } else if (EnumValuesServer.LineType.样片.getKey() == detail.get(i).getType()) {
                if (segmentIndex == 1) {
                    detail.get(i).setSegmentNo(segmentNo.substring(0, segmentNo.length() - 1) + segmentIndexs.get(segmentIndex - 1) + "TP");
                    headPieceCount++;
                } else {
                    detail.get(i).setSegmentNo(segmentNo + "WP");
                    tailPieceCount++;
                    detail.get(segmentIndex - 1).getSegmentIndex().setTailPieceNum(tailPieceCount);
                }
            } else if (EnumValuesServer.LineType.回收料.getKey() == detail.get(i).getType()) {
                detail.get(i).setSegmentNo(recutDetail.getSectionNoFb() + "X" + materialIndex);
                materialIndex++;
            } else {
                throw new BusinessException("【" + detail.get(i).getType() + "】该类型未处理");
            }
        }
    }

    private LinkedList<String> getSegmentNoIndex(RecutDetail recutDetail, int count) {
        LinkedList<String> segmentNoIndexs = new LinkedList<>();
        if (count > 0) {
            //实际要反切的单晶编号
            String sectionNoFb = recutDetail.getSectionNoFb();
            List<RecutDetail> recutDetailInitials = recutDetailDao.findByCrystalIdAndParentId(recutDetail.getCrystalId(), 0L);
            List<RecutDetail> collect = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(recutDetailInitials)) {

                String fromMark = sectionNoFb.substring(SectionIndexRangeEnum.基地追溯产品类型.getBeginIndex(), SectionIndexRangeEnum.基地追溯产品类型.getEndIndex());
                if (fromMark.matches("[A-Z]+")) {
                    collect = recutDetailInitials.stream().filter(recutDetail1 -> recutDetail1.getSectionNoFb().substring(SectionIndexRangeEnum.毛棒到截断位数.getBeginIndex(), SectionIndexRangeEnum.毛棒到截断位数.getEndIndex())
                            .equals(recutDetail.getSectionNo().substring(SectionIndexRangeEnum.毛棒到截断位数.getBeginIndex(), SectionIndexRangeEnum.毛棒到截断位数.getEndIndex()))).collect(Collectors.toList());
                } else {
                    collect = recutDetailInitials.stream().filter(recutDetail1 -> recutDetail1.getSectionNoFb().substring(0, 13).equals(recutDetail.getSectionNo().substring(0, 13))).collect(Collectors.toList());
                }
            }
            String indexs = com.sw.mes.utils.StringUtils.leftPad(Integer.toBinaryString(NumberUtil.Object2Integer(collect.get(0).getRetCutSegmentNum(), 0)), 26, "0");
            StringBuilder indexsIndexs = new StringBuilder(com.sw.mes.utils.StringUtils.leftPad(Integer.toBinaryString(NumberUtil.Object2Integer(collect.get(0).getRetCutSegmentNum(), 0)), 26, "0"));

            //String sectionNoFb = collect.get(0).getSectionNoFb();
            String endEnglishArr = sectionNoFb.substring(sectionNoFb.length() - 1).toUpperCase();

            if (!endEnglishArr.equals("Y")) {
                //圆棒反切过来的A_Z,从该字母重新计算尾部字母
                int indexNum = Arrays.binarySearch(Constants.englishArr, endEnglishArr);
                indexs = StrUtil.replace(indexs, 1, indexNum, '1');
                indexsIndexs = new StringBuilder(indexs);
            }
            for (int i = 0; i < indexs.length(); i++) {
                if (i != 24 && segmentNoIndexs.size() < count && "0".equals(indexs.charAt(i) + "")) {
                    indexsIndexs.replace(i, i + 1, "1");
                    //判断反切记录是否存在该单晶编码;存在则追加1,不存在则生成编号结尾
                    String endStr = Constants.englishArr[i + 1];
                    String newSectionNoFb = sectionNoFb.substring(0, sectionNoFb.length() - 1) + endStr;
                    List<RecutDetail> bySectionNoFb = recutDetailDao.findBySectionNoFb(newSectionNoFb);
                    List<SectionNoDetail> bySectionNo = sectionNoDetailDao.findBySectionNo(newSectionNoFb);
                    if ((CollectionUtils.isNotEmpty(bySectionNoFb) && bySectionNoFb.size() > 0) || (CollectionUtils.isNotEmpty(bySectionNo) && bySectionNo.size() > 0)) {
                        indexsIndexs.replace(i, i + 1, "1");
                    } else {
                        segmentNoIndexs.add(Constants.englishArr[i + 1]);
                    }
                    // segmentNoIndexs.add(Constants.englishArr[i + 1]);
                }
            }
            //手动的接管下事务,然后set完把那条修改记录给擦除掉
            Session session = entityManager.unwrap(org.hibernate.Session.class);
            collect.get(0).setRetCutSegmentNum(Integer.parseInt(indexsIndexs.toString(), 2));
            session.evict(collect.get(0));
            // recutDetailService.saveOrUpdate(collect.get(0));
            return segmentNoIndexs;
        }
        return segmentNoIndexs;
    }

    /**
     * 生成晶段编号
     * 20220830
     * 新命名规则
     * zyy
     *
     * @param recutDto
     */
    public void getSegmentNo2(RecutDto recutDto) {
        // 原有晶段编号
        String segmentNo = recutDto.getSegmentNo().trim();
        // 反切规则集合
        List<RecutInfoFbDetailInfo> detail = recutDto.getDetail();
        int segmentIndex = 1;
        int materialIndex = 1;

        //=========================================================20220907zyy处理回收料编号序号
        String tSegmentNo;
        if (!(segmentNo.substring(segmentNo.length() - 1)).equals("Y")) {  //编号为“ABC```”结尾的
            tSegmentNo = segmentNo;
        } else {
            tSegmentNo = segmentNo.substring(0, segmentNo.length() - 1);
        }
        List<ProductionPaintingLineDetail> paintingLineDetailByLikeSegmentNo = productionPaintingLineDetailDao.findByLikeSegmentNoHs(tSegmentNo);
        if (segmentNo.substring(segmentNo.length() - 2).equals("WY")) {
            materialIndex = 1;
        } else if (null != paintingLineDetailByLikeSegmentNo && paintingLineDetailByLikeSegmentNo.size() > 0) {
            materialIndex = Integer.parseInt(paintingLineDetailByLikeSegmentNo.get(0).getNo().substring(paintingLineDetailByLikeSegmentNo.get(0).getNo().length() - 1)) + 1;
        }
        //=========================================================

        //是否为不合格反切
        int segmentCount = 0;
        for (RecutInfoFbDetailInfo recutInfoFbDetailInfo : recutDto.getDetail()) {
            if (recutInfoFbDetailInfo.getType() == EnumValuesServer.LineType.晶段.getKey()) {
                segmentCount++;
            }
        }

        //type:分段类型(1:晶段 2样片 3回收料)（已弃用20220831）
        //type:分段类型(0:晶段 2回收料)20220831
        List<Integer> detailTypes = detail.stream().map(t -> t.getType()).collect(Collectors.toList());
        boolean flag = true;
        for (Integer detailType : detailTypes) {
            if (detailType == 2) {
                flag = false;
            }
        }

        //===================================================处理晶棒编号后缀
        char suffix = 'A';
        char suffix2 = segmentNo.charAt(segmentNo.length() - 1);
        //String tSegmentNo = segmentNo.substring(0, segmentNo.length() - 1);
        List<ProductionPaintingLineDetail> paintingLineDetailByLikeSegmentNo1 = productionPaintingLineDetailDao.findByLikeSegmentNoFb(segmentNo.substring(0, segmentNo.length() - 1));//方棒晶棒集合
        if (null != paintingLineDetailByLikeSegmentNo1 && paintingLineDetailByLikeSegmentNo1.size() > 0) {
            String lastSectionNo = paintingLineDetailByLikeSegmentNo1.get(0).getNo();
            suffix2 = (char) (lastSectionNo.charAt(lastSectionNo.length() - 1) + 1);
        } else {
            suffix2 = (char) (suffix2 + 1);
        }
        //==================================================================

        if (segmentCount > 1) {              //晶棒数量
            recutDto.setCutType(2);//2分段反切
            for (RecutInfoFbDetailInfo recutInfoFbDetailInfo : detail) {
                if (recutInfoFbDetailInfo.getType() == EnumValuesServer.LineType.晶段.getKey()) {
                    if (recutInfoFbDetailInfo.getLength().compareTo(new BigDecimal(60)) < 0) {
                        throw new BusinessException("晶段长度不能小于60");
                    }
                }
                if (detailTypes.contains(2)) {   //“回收料”+“晶段”  类型

                    if (2 == (recutInfoFbDetailInfo.getType())) { //回收料命名
                        recutInfoFbDetailInfo.setSegmentNo(segmentNo + "X" + materialIndex);
                        materialIndex++;
                    } else if (0 == (recutInfoFbDetailInfo.getType())) {//晶段命名
                        if ((segmentNo.substring(segmentNo.length() - 1)).equals("Y")) {//晶段结尾是Y，多个晶段
                            recutInfoFbDetailInfo.setSegmentNo(segmentNo.substring(0, segmentNo.length() - 1) + suffix);
                            suffix++;
                        } else if (!(segmentNo.substring(segmentNo.length() - 1)).equals("Y")) {//晶段结尾不是Y，多个晶段
                            recutInfoFbDetailInfo.setSegmentNo(segmentNo.substring(0, segmentNo.length() - 1) + suffix2);
                            suffix2++;
                        }
                    }
                }           //“晶段”+“晶段”  类型，不包含回收料和样片
                else if (!detailTypes.contains(2)) {
                    if ((segmentNo.substring(segmentNo.length() - 1)).equals("Y")) {//晶棒编号结尾是Y
                        recutInfoFbDetailInfo.setSegmentNo(segmentNo.substring(0, segmentNo.length() - 1) + suffix);
                        suffix++;
                    } else if (!(segmentNo.substring(segmentNo.length() - 1)).equals("Y")) {//晶棒编号结尾 不是Y
                        recutInfoFbDetailInfo.setSegmentNo(segmentNo.substring(0, segmentNo.length() - 1) + suffix2);
                        suffix2++;
                    }
                }
            }
        } else {         //不合格反切

            recutDto.setCutType(1);
            for (RecutInfoFbDetailInfo recutInfoFbDetailInfo : detail) {
                if (recutInfoFbDetailInfo.getType() == EnumValuesServer.LineType.晶段.getKey()) {
                    if (recutInfoFbDetailInfo.getLength().compareTo(new BigDecimal(60)) < 0) {
                        throw new BusinessException("晶段长度不能小于60");
                    }
                    if ((segmentNo.substring(segmentNo.length() - 1)).equals("Y")) {
                        recutInfoFbDetailInfo.setSegmentNo(segmentNo.substring(0, segmentNo.length() - 1) + suffix);
                    } else if (!(segmentNo.substring(segmentNo.length() - 1)).equals("Y")) {
                        recutInfoFbDetailInfo.setSegmentNo(segmentNo.substring(0, segmentNo.length() - 1) + suffix2);
                    }
                    segmentIndex++;
                } else if (recutInfoFbDetailInfo.getType() == EnumValuesServer.LineType.回收料.getKey()) {
                    recutInfoFbDetailInfo.setSegmentNo(segmentNo + "X" + materialIndex);
                    materialIndex++;
                }
            }
        }
    }


    /**
     * 生成晶段编号
     *
     * @param recutDto
     */
    public void getSegmentNo(RecutDto recutDto) {
        // 原有晶段编号
        String segmentNo = recutDto.getSegmentNo().trim();
        // 反切规则集合
        List<RecutInfoFbDetailInfo> detail = recutDto.getDetail();
        int segmentIndex = 1;
        int materialIndex = 1;
        //是否为不合格反切
        int segmentCount = 0;
        Date date = new Date();
        for (RecutInfoFbDetailInfo recutInfoFbDetailInfo : recutDto.getDetail()) {
            if (recutInfoFbDetailInfo.getType() == EnumValuesServer.LineType.晶段.getKey()) {
                segmentCount++;
            }
        }
        if (segmentCount > 1) {
            recutDto.setCutType(2);
            for (RecutInfoFbDetailInfo recutInfoFbDetailInfo : detail) {
                if (recutInfoFbDetailInfo.getType() == EnumValuesServer.LineType.晶段.getKey()) {
                   /* if (recutInfoFbDetailInfo.getLength().compareTo(new BigDecimal(60)) < 0) {
                        throw new BusinessException("晶段长度不能小于60");
                    }*/
//                    recutInfoFbDetailInfo.setSegmentNo(segmentNo + "F" + segmentIndex);
                    recutInfoFbDetailInfo.setSegmentNo(segmentNo + segmentIndex);
                    segmentIndex++;
                } else if (recutInfoFbDetailInfo.getType() == EnumValuesServer.LineType.回收料.getKey()) {
                    //recutInfoFbDetailInfo.setSegmentNo(segmentNo + "FX" + materialIndex);
                    recutInfoFbDetailInfo.setSegmentNo(segmentNo + String.format("%02d", materialIndex));
                    materialIndex++;
                }
            }
        } else {
            recutDto.setCutType(1);
            for (RecutInfoFbDetailInfo recutInfoFbDetailInfo : detail) {
                if (recutInfoFbDetailInfo.getType() == EnumValuesServer.LineType.晶段.getKey()) {
                    recutInfoFbDetailInfo.setSegmentNo(segmentNo + "1");
                    segmentIndex++;
                } else if (recutInfoFbDetailInfo.getType() == EnumValuesServer.LineType.回收料.getKey()) {
                    recutInfoFbDetailInfo.setSegmentNo(segmentNo + String.format("%02d", materialIndex));
                    materialIndex++;
                } else if (recutInfoFbDetailInfo.getType() == EnumValuesServer.LineType.样片.getKey()) {
                    if (segmentIndex == 1) {
                        recutInfoFbDetailInfo.setSegmentNo(productionRecutService.handleSampleNo(date, segmentNo, 1, false));
                    } else {
                        recutInfoFbDetailInfo.setSegmentNo(productionRecutService.handleSampleNo(date, segmentNo, 1, true));
                    }
                }
            }
        }
    }

    @Autowired
    private ProductionRecutService productionRecutService;

    @Override
    public Result<ReCut> getReCutBySectionNo(String sectionNo) {
        return ResultGenerator.success(this.findReCutInfoBySectionNo(sectionNo));
    }

    @Override
    public Result getCooperateInfo(CooperateDataInfoDto cooperateDataInfoDto) {

        String crystalNo = cooperateDataInfoDto.getCrystalNo();
        BigDecimal target1 = cooperateDataInfoDto.getTarget1();
        BigDecimal target2 = cooperateDataInfoDto.getTarget2();
        BigDecimal sum = target1.add(target2);

        RecutDto recutDto = new RecutDto();
        recutDto.setSegmentNo(crystalNo);
        // 反切类型  todo  反切类型 : 1不合格反切 ,2分段反切
        recutDto.setCutType(2);
        recutDto.setSegmentNoLength(sum);
        recutDto.setCutNum("2");
        recutDto.setStartTime(new Date());
        recutDto.setSpecs(cooperateDataInfoDto.getSpecs());
        recutDto.setProductLevel(cooperateDataInfoDto.getProductGrade());

        List<RecutInfoFbDetailInfo> detail = new ArrayList<>();
        RecutInfoFbDetailInfo recutInfoFbDetailInfo1 = new RecutInfoFbDetailInfo();
        recutInfoFbDetailInfo1.setIndex(0);
        recutInfoFbDetailInfo1.setLength(target1);
        recutInfoFbDetailInfo1.setType(0);
        RecutInfoFbDetailInfo recutInfoFbDetailInfo2 = new RecutInfoFbDetailInfo();
        recutInfoFbDetailInfo2.setIndex(1);
        recutInfoFbDetailInfo2.setLength(target2);
        recutInfoFbDetailInfo2.setType(0);

        detail.add(recutInfoFbDetailInfo1);
        detail.add(recutInfoFbDetailInfo2);
        recutDto.setDetail(detail);
        // 生成编号
        log.info("配棒信息生成方棒编号前: " + JSONObject.toJSONString(recutDto));
        Result<RecutDto> result = getSectionNoFbRecutInfo(recutDto);
        if (ResultCode.SUCCESS.getCode() == result.getCode()) {
            RecutDto data = result.getData();
            log.info("配棒信息生成方棒编号后" + JSONObject.toJSONString(data));
            // 创建画线信息
            Result result1 = saveSegmentNo(data);
            if (ResultCode.SUCCESS.getCode() == result1.getCode()) {
                return ResultGenerator.success(data);
            } else {
                return ResultGenerator.fail("创建画线信息失败：" + result1);
            }
        } else {
            return ResultGenerator.fail("生成编号失败：" + result);
        }

    }

    @Override
    public Result<BigDecimal> findLengthBySecitonNo(String sectionNo) {

        WipStorage wipStorage = wipStorageService.findByProcessingOrderCode(sectionNo, Arrays.asList(EnumValuesFactory.WipStorageStatus.已出站.getKey(), EnumValuesFactory.WipStorageStatus.待进站.getKey()));
        if (null != wipStorage && StringUtils.equals("方棒反切", wipStorage.getProcessName())) {

            BigDecimal actualLength = BigDecimal.ZERO;
            List<ReCut> byCrystalSectionNo = this.fbReCutDAO.findByCrystalSectionNoAndStatus(sectionNo, 0);
            if (byCrystalSectionNo.size() > 0) {
                return ResultGenerator.fail("该单晶存在未截断的返切记录!请勿重复操作");
            }
            String code = sectionNo;
            YbInspectData bySectionNo = ybInspectDataService.findBySectionNo(sectionNo);
            if (null == bySectionNo) {
                List<ProductionPaintingLineDetail> bySegmentNo = productionPaintingLineDetailDao.findBySegmentNo(sectionNo);
                if (CollectionUtils.isNotEmpty(bySegmentNo)) {
                    ProductionPaintingLineDetail productionPaintingLineDetail = bySegmentNo.get(0);
                    actualLength = productionPaintingLineDetail.getLength();
                    Long operateReversecutDrawId = productionPaintingLineDetail.getOperateReversecutDrawId();
                    if (null != operateReversecutDrawId) {
                        ReCut reCut = this.get(operateReversecutDrawId);
                        if (null != reCut) {
                            code = reCut.getSegmentNo();
                        }
                    }
                } else {
                    return ResultGenerator.fail("该单晶:" + sectionNo + "无圆棒检验信息");
                }
            } else {
                actualLength = bySectionNo.getActualLength();
            }
            if (null == actualLength) {
                return ResultGenerator.fail("该单晶:" + sectionNo + "圆棒检验长度为零！");
            }
            RecutDetail recutDetail = recutDetailService.findBySectionNoFb(code);
            if (null == recutDetail) {
                return ResultGenerator.fail("该方棒:" + sectionNo + "无追溯信息!");
            }
            return ResultGenerator.success(actualLength);

        }
        return this.getSecitonNoInfo(sectionNo);
    }

    @Override
    public Result<RecutDto> getSectionNoFbRecutInfoNew(RecutDto recutDto) {
        String sectionNo = recutDto.getSegmentNo();
        if (StringUtils.isBlank(sectionNo)) {
            return ResultGenerator.fail("该晶段编号不存在!");
        }
        WipStorage wipStorage = wipStorageService.findByProcessingOrderCode(sectionNo, Arrays.asList(EnumValuesFactory.WipStorageStatus.已出站.getKey(), EnumValuesFactory.WipStorageStatus.待进站.getKey()));
        if (null != wipStorage && StringUtils.equals("方棒反切", wipStorage.getProcessName())) {

            List<ReCut> byCrystalSectionNo = this.fbReCutDAO.findByCrystalSectionNoAndStatus(sectionNo, 0);
            if (byCrystalSectionNo.size() > 0) {
                return ResultGenerator.fail("该单晶存在未截断的返切记录!");
            }
            BigDecimal actualLength = BigDecimal.ZERO;
            String code = sectionNo;
            YbInspectData bySectionNo = ybInspectDataService.findBySectionNo(sectionNo);
            if (null == bySectionNo) {
                List<ProductionPaintingLineDetail> bySegmentNo = productionPaintingLineDetailDao.findBySegmentNo(sectionNo);
                if (CollectionUtils.isNotEmpty(bySegmentNo)) {
                    ProductionPaintingLineDetail productionPaintingLineDetail = bySegmentNo.get(0);
                    actualLength = productionPaintingLineDetail.getLength();
                    Long operateReversecutDrawId = productionPaintingLineDetail.getOperateReversecutDrawId();
                    if (null != operateReversecutDrawId) {
                        ReCut reCut = this.get(operateReversecutDrawId);
                        if (null != reCut) {
                            code = reCut.getSegmentNo();
                        }
                    }
                } else {
                    return ResultGenerator.fail("该单晶:" + sectionNo + "不存在圆棒检验信息!");
                }

            } else {
                actualLength = bySectionNo.getActualLength();
            }
            if (null == actualLength) {
                return ResultGenerator.fail("该单晶:" + sectionNo + "圆棒检验长度为零!");
            }
            if (recutDto.getSegmentNoLength().compareTo(actualLength) != 0) {
                return ResultGenerator.fail("晶段长度不一致!");
            }
            RecutDetail recutDetail = recutDetailService.findBySectionNoFb(code);
            if (null == recutDetail) {
                return ResultGenerator.fail("该方棒:" + recutDto.getSegmentNo() + "无追溯信息!");
            }

            List<RecutInfoFbDetailInfo> detail = recutDto.getDetail();
            if (CollectionUtils.isEmpty(detail)) {
                return ResultGenerator.fail("该单晶:" + sectionNo + "划线明细为空!");
            }
            Date date = new Date();
            recutDto.setCutType(1);
            Integer segmentIndex = 1;
            Integer materialIndex = 0;
            for (RecutInfoFbDetailInfo recutInfoFbDetailInfo : detail) {
                if (recutInfoFbDetailInfo.getType() == EnumValuesServer.LineType.晶段.getKey()) {
                    recutInfoFbDetailInfo.setSegmentNo(sectionNo + segmentIndex);
                    segmentIndex++;
                } else if (recutInfoFbDetailInfo.getType() == EnumValuesServer.LineType.回收料.getKey()) {
                    materialIndex++;
                    recutInfoFbDetailInfo.setSegmentNo(sectionNo + String.format("%02d", materialIndex));
                } else if (recutInfoFbDetailInfo.getType() == EnumValuesServer.LineType.样片.getKey()) {
                    if (segmentIndex == 1) {
                        recutInfoFbDetailInfo.setSegmentNo(productionRecutService.handleSampleNo(date, sectionNo, 1, false));
                    } else {
                        recutInfoFbDetailInfo.setSegmentNo(productionRecutService.handleSampleNo(date, sectionNo, 1, true));
                    }
                }
            }
            if (segmentIndex != 1) {
                recutDto.setCutType(2);
            }
            return ResultGenerator.success(recutDto);
        }
        return this.getSectionNoFbRecutInfo(recutDto);
    }

    @Override
    public Result saveSegmentNoNew(RecutDto recutDto) {
        String sectionNo = recutDto.getSegmentNo();
        if (StringUtils.isBlank(sectionNo)) {
            return ResultGenerator.fail("方棒返切晶段编号不存在!");
        }
        BigDecimal actualLength = BigDecimal.ZERO;
        String specs = "";
        //WipStorage wipStorage = wipStorageService.findByProcessingOrderCode(sectionNo, Arrays.asList(EnumValuesFactory.WipStorageStatus.已出站.getKey()));
        WipStorage wipStorage = null;
        //添加判断，站点在检验需要评级
        List<WipStorage> wipStorageList = wipStorageService.findByProcessingByOrderCode(sectionNo);
        if (CollectionUtils.isEmpty(wipStorageList)) {
            wipStorage = wipStorageList.get(0);
        }
        if (null != wipStorage && (StringUtils.equals(EnumValuesFactory.WipStorageCode.开方.getValue(), wipStorage.getProcessName()) ||
                StringUtils.equals(EnumValuesFactory.WipStorageCode.磨倒.getValue(), wipStorage.getProcessName()))) {

            recutDto.setProcessCode(wipStorage.getProcessName());
            Date date = new Date();
            BigDecimal segmentLength = BigDecimal.ZERO;
            String username = BaseContextHandler.getUsername();
            ReCut reCut = fromDto(recutDto);
            reCut.setEndTime(date);
            List<ReCut> byCrystalSectionNo = this.fbReCutDAO.findByCrystalSectionNoAndStatus(recutDto.getSegmentNo(), 0);
            if (byCrystalSectionNo.size() > 0) {
                return ResultGenerator.fail("该单晶存在未截断的返切记录!");
            }
            RecutDetail recutDetail = recutDetailService.findBySectionNoFb(recutDto.getSegmentNo());
            if (recutDetail == null) {
                return ResultGenerator.fail("该方棒:" + recutDto.getSegmentNo() + "无追溯信息!");
            }
            reCut.setRecutType(recutDto.getCutType());
            YbInspectData bySectionNo = ybInspectDataService.findBySectionNo(sectionNo);
            if (null == bySectionNo || null == bySectionNo.getActualLength()) {
                List<ProductionPaintingLineDetail> bySegmentNo = productionPaintingLineDetailDao.findBySegmentNo(sectionNo);
                if (CollectionUtils.isNotEmpty(bySegmentNo)) {
                    ProductionPaintingLineDetail productionPaintingLineDetail = bySegmentNo.get(0);
                    actualLength = productionPaintingLineDetail.getLength();
                    Long operateReversecutDrawId = productionPaintingLineDetail.getOperateReversecutDrawId();
                    if (null != operateReversecutDrawId) {
                        ReCut reCutNew = this.get(operateReversecutDrawId);
                        if (null != reCutNew) {
                            specs = reCutNew.getSpecs();
                        }
                    }
                } else {
                    return ResultGenerator.fail("该单晶:" + sectionNo + "不存在圆棒检验信息!");
                }
            } else {
                actualLength = bySectionNo.getActualLength();
                specs = bySectionNo.getProductTypeSecond();
            }
            if (recutDto.getSegmentNoLength().compareTo(actualLength) != 0) {
                return ResultGenerator.fail("晶段长度不一致!");
            }
            List<RecutInfoFbDetailInfo> detail = recutDto.getDetail();

            for (RecutInfoFbDetailInfo datum : detail) {
                if (datum.getType() == EnumValuesServer.LineType.晶段.getKey()) {
                    segmentLength = segmentLength.add(datum.getLength());
                }
            }
            //方棒规格
            reCut.setSpecs(specs);
            //反切长度
            reCut.setRecutLength(reCut.getSegmentNoLength().subtract(segmentLength));

            fbReCutDAO.save(reCut);
            List<ProductionPaintingLineDetail> detailList = new ArrayList<>();
            // 晶段追溯信息集合
            List<RecutDetail> recutDetails = new ArrayList<>();
            List<DictionaryItem> dictionaryItems = dictionaryItemService.findByThemeValueAndItemName(Constants.WEIGHT_RATIO, specs, true);
            if (CollectionUtils.isEmpty(dictionaryItems)) {
                return ResultGenerator.fail("请配置【" + specs + "】规格的理论重量系数");
            }
            BigDecimal weightLossCoefficient = NumberUtil.Object2BigDecimal(dictionaryItems.get(0).getValue());
            if (null == weightLossCoefficient || weightLossCoefficient.compareTo(new BigDecimal("1")) < 1) {
                return ResultGenerator.fail("【" + dictionaryItems.get(0).getValue() + "】理论重量系数格式不正确，只能为大于0的数字类型");
            }
            SectionNoDetail sectionNoDetail = sectionNoDetailService.findBySectionNo(recutDetail.getSectionNo());
            //回收料段数
            Integer count = 0;
            List<PieceDetail> pieceDetails = new ArrayList<>();
            // 不合格反切
            for (int i = 0; i < detail.size(); i++) {
                RecutInfoFbDetailInfo datum = detail.get(i);
                ProductionPaintingLineDetail detail1 = modelMapper.map(datum, ProductionPaintingLineDetail.class);
                detail1.setCreateTime(date);
                detail1.setCrystalType(1);
                detail1.setOperateReversecutDrawId(reCut.getId());
                detail1.setCrystalId(recutDetail.getCrystalId());
                detail1.setNo(datum.getSegmentNo());
                detail1.setSequence(datum.getIndex());
                detail1.setParentId(0);
                detail1.setIsCut(0);
                detail1.setReason(datum.getReason());
                detail1.setWeight(datum.getLength().divide(weightLossCoefficient, 2, RoundingMode.CEILING));
                if (null == detail1.getCrystalId()) {
                    detail1.setCrystalId(0L);
                }
                detailList.add(detail1);
                if (detail1.getType() == EnumValuesServer.LineType.晶段.getKey()) {
                    RecutDetail recutDetailNew = new RecutDetail();
                    recutDetailNew.setMaterial(null);
                    recutDetailNew.setSectionNoFb(datum.getSegmentNo());
                    recutDetailNew.setSectionNo(recutDetail.getSectionNo());
                    recutDetailNew.setYbId(recutDetail.getYbId());
                    recutDetailNew.setIsCut(0);
                    recutDetailNew.setParentId(recutDetail.getId());
                    recutDetailNew.setCreateUser(username);
                    recutDetailNew.setCrystalId(recutDetail.getCrystalId());
                    recutDetailNew.setCreateDate(date);
                    if (i - 1 >= 0 && EnumValuesServer.LineType.样片.getKey() == detail.get(i - 1).getType()) {
                        recutDetailNew.setPieceNoHead(detail.get(i - 1).getSegmentNo());
                    }
                    if (i + 1 < detail.size() && EnumValuesServer.LineType.样片.getKey() == detail.get(i + 1).getType()) {
                        recutDetailNew.setPieceNoEnd(detail.get(i + 1).getSegmentNo());
                    }
                    recutDetails.add(recutDetailNew);
                }
                if (datum.getType() == EnumValuesServer.LineType.回收料.getKey()) {
                    count++;
                }
                if (datum.getType() == EnumValuesServer.LineType.样片.getKey()) {
                    PieceDetail pieceDetail = new PieceDetail();
                    pieceDetail.setPieceNo(datum.getSegmentNo());
                    pieceDetail.setType(1);
                    pieceDetail.setConductiveType(sectionNoDetail.getConductiveType());
                    pieceDetail.setDopant(sectionNoDetail.getDopant());
                    pieceDetail.setSpecs(sectionNoDetail.getSpecs());
                    pieceDetail.setCrystalId(sectionNoDetail.getCrystalId());
                    pieceDetail.setCrystalNo(sectionNoDetail.getCrystalNo());
                    pieceDetail.setLotNo(sectionNoDetail.getLotNo());
                    pieceDetail.setEquipmentCode(sectionNoDetail.getEquipmentCode());
                    pieceDetail.setProductType(sectionNoDetail.getProductType());
                    pieceDetail.setProductCode(sectionNoDetail.getProductCode());
                    pieceDetail.setProductGrade(sectionNoDetail.getProductGrade());
                    pieceDetail.setSegmentId(sectionNoDetail.getId());
                    pieceDetail.setCreateDate(new Date());
                    pieceDetail.setIsQualified(0);
                    pieceDetail.setSegmentNum(sectionNoDetail.getSegmentNum());
                    pieceDetail.setBackCut(EnumValuesFactory.ConfirmIdentification.YES.getValue());
                    pieceDetails.add(pieceDetail);
                }
            }
            if (!recutDetails.isEmpty()) {
                recutDetailService.saveAll(recutDetails);
            }
            if (!pieceDetails.isEmpty()) {
                pieceDetailDao.saveAll(pieceDetails);
            }
            recutDetail.setIsCut(1);
            recutDetail.setCreateUser(username);
            recutDetailService.saveOrUpdate(recutDetail);
            if (!detailList.isEmpty()) {
                productionPaintingLineDetailDao.saveAll(detailList);
            }

          /*  //先退站
            wipStorageService.exitStation(sectionNo);
            // 出库到方棒返切工序
            wipStorageService.outStation(sectionNo, "B", null);*/
            return ResultGenerator.success();

          /*  //先进方棒返切工序
            wipStorageService.inStation(sectionNo,wipStorage.getEquipmentCode(),false);

            // 出库到磨削工序
            Result result = wipStorageService.outStation(sectionNo, "A", null);
*//*
            if(count == detail.size()){
                PlanProcessingOrder planProcessingOrder = planProcessingOrderService.findByCode(sectionNo);
                if (planProcessingOrder != null) {
                    planProcessingOrder.setStatus(EnumValuesFactory.PlanProcessingOrderStatus.已作废.getKey());
                    planProcessingOrderService.saveOrUpdate(planProcessingOrder);
                }
            }*//*
            if (ResultCode.SUCCESS.getCode() == result.getCode()) {
                return ResultGenerator.success();
            }
            return ResultGenerator.fail("方棒反切后的晶段信息: " + result.getMessage());*/
        }
        return this.saveSegmentNo(recutDto);
    }

    public ReCut fromDto(RecutDto dto) {
        return modelMapper.map(dto, ReCut.class);
    }
}
