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

import com.sw.mes.base.factory.inspect.entity.ReturnRecord;
import com.sw.mes.base.factory.inspect.service.ReturnRecordService;
import com.sw.mes.base.factory.material.dao.MaterialModelDao;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.base.workinprocess.dto.PlanProcessingOrderWipStorageDto;
import com.sw.mes.base.workinprocess.entity.PlanProcessingOrder;
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.context.BaseContextHandler;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultCode;
import com.sw.mes.core.utils.SapUtil;
import com.sw.mes.core.utils.SectionNoUtil;
import com.sw.mes.enumvalue.EnumValuesServer;
import com.sw.mes.inspect.service.YbInspectDataService;
import com.sw.mes.yb.turnstore.dao.*;
import com.sw.mes.yb.turnstore.entity.Turnstore;
import com.sw.mes.yb.turnstore.entity.TurnstoreIn;
import com.sw.mes.yb.turnstore.entity.TurnstoreInItem;
import com.sw.mes.yb.turnstore.service.TurnstoreInItemService;
import com.sw.mes.yb.turnstore.service.TurnstoreInService;
import com.sw.mes.yb.turnstore.service.TurnstoreTrayItemService;
import com.sw.mes.yb.turnstore.statics.EnumValues;
import com.sw.mes.yb.turnstore.statics.Utlis;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@Service
@Transactional
public class TurnstoreInServiceImpl extends BaseServiceImpl<TurnstoreIn> implements TurnstoreInService {
    TurnstoreInDao dao;
    @Autowired
    TurnstoreInItemDao itemDao;

    @Autowired
    TurnstoreDao turnstoreDao;

    @Autowired
    ModelMapper modelMapper;

    @Autowired
    private WipStorageService wipStorageService;

/*    @Autowired
    SapSectionMaterialNumberDao sapSectionMaterialNumberDao;*/

    //@Autowired
    //SapProductionScheduleDao sapProductionScheduleDao;

    @Autowired
    private MaterialModelDao materialModelDao;
//
//    @Autowired
//    private SapProductionOrderDao sapProductionOrderDao;
//
//
//    @Autowired
//    private SapProductionOrderService sapProductionOrderService;

    @Autowired
    private TurnstoreInItemService turnstoreInItemService;

    @Autowired
    private YbInspectDataService inspectDataBaseService;

    @Autowired
    private TurnstoreOutItemDao turnstoreOutItemDao;

    @Autowired
    private TurnstoreOutDao turnstoreOutDao;


    @Autowired
    private FbFeignClients fbFeignClients;

    @Autowired
    private TurnstoreTrayItemService turnstoreTrayItemService;

    @Autowired
    private ReturnRecordService returnRecordService;

    @Autowired
    private DictionaryItemService dictionaryItemService;

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


    private Logger logger = LoggerFactory.getLogger(this.getClass());

    //检查list是否有重复 判断是否在周转库 判断是否填写过申请单且为待入库
    public void checkSectionNosInUpdate(TurnstoreIn turnstoreIn, List<TurnstoreInItem> items, Integer turnstoreId) {
        for (TurnstoreInItem turnstoreInItem : items) {
            if (StringUtils.isBlank(turnstoreInItem.getSectionNo())) {
                throw new RuntimeException("错误，晶段编号不能为空");
            }
        }
        //判断是否在周转库
        //判断是否在周转库
        //所有单晶
        List<String> sectionItems = new ArrayList<>();
        //非复检单晶
        List<String> sectionItemsFirst = new ArrayList<>();
        for (TurnstoreInItem turnstoreInItem : items) {
            sectionItems.add(turnstoreInItem.getSectionNo());
            if (turnstoreInItem.getReCheckType() == null || turnstoreInItem.getReCheckType().equals("") || !turnstoreInItem.getReCheckType().equals("复检单晶")) {
                sectionItemsFirst.add(turnstoreInItem.getSectionNo());
            }
        }
        //List<String> sectionItems=items.stream().map(TurnstoreInItem::getSectionNo).collect(Collectors.toList());
        //判断是否传入的list是否有重复晶段编号
        if (sectionItems.size() != new HashSet<String>(sectionItems).size()) {
            throw new RuntimeException("晶段编号不能重复");
        }
        List<Turnstore> checkList = turnstoreDao.getStoreInfoBySectionNos(sectionItems);
        if (checkList != null && checkList.size() > 0) {
            List<String> inInfo = checkList.stream().map(Turnstore::getSectionNo).collect(Collectors.toList());
            throw new RuntimeException(String.join(",", inInfo) + "等单晶已在周转库");
        }
        //查看是否填写过入库单，状态为待入库
        List<TurnstoreInItem> checkList1 = itemDao.getItemsBySectionNosUpdate(sectionItems, turnstoreId);
        if (checkList1 != null && checkList1.size() > 0) {
            List<String> inInfo1 = checkList1.stream().map(TurnstoreInItem::getSectionNo).collect(Collectors.toList());
            throw new RuntimeException(String.join(",", inInfo1) + "等单晶已是待入库状态");
        }
        //非复检单晶 查看有无入库记录
        if (turnstoreIn.getType().equals(EnumValues.InType.圆棒入库.getValue())) {
            if (sectionItemsFirst.size() > 0) {
                List<TurnstoreInItem> checkList2 = itemDao.getItemsBySectionNosUpdateNoState(sectionItemsFirst, turnstoreId);
                if (checkList2 != null && checkList2.size() > 0) {
                    List<String> inInfo2 = checkList2.stream().map(TurnstoreInItem::getSectionNo).collect(Collectors.toList());
                    throw new RuntimeException(String.join(",", inInfo2) + "等单晶为一次检验，重复入库");
                }
            }
        }
    }

    //检查list是否有重复 判断是否在周转库
    public void checkSectionNosConfirmIn(List<TurnstoreInItem> items) {
        for (TurnstoreInItem turnstoreInItem : items) {
            if (StringUtils.isBlank(turnstoreInItem.getSectionNo())) {
                throw new RuntimeException("错误，晶段编号不能为空");
            }
        }
        //判断是否在周转库
        List<String> sectionItems = items.stream().map(TurnstoreInItem::getSectionNo).collect(Collectors.toList());
        //判断是否传入的list是否有重复晶段编号
        if (sectionItems.size() != new HashSet<String>(sectionItems).size()) {
            throw new RuntimeException("晶段编号不能重复");
        }
        List<Turnstore> checkList = turnstoreDao.getStoreInfoBySectionNos(sectionItems);
        if (checkList != null && checkList.size() > 0) {
            List<String> inInfo = checkList.stream().map(Turnstore::getSectionNo).collect(Collectors.toList());
            throw new RuntimeException(String.join(",", inInfo) + "等单晶已在周转库");
        }
    }

//    public void getMaterialNumber(List<TurnstoreInItem> items) {
//        List<String> sectionItems = items.stream().map(TurnstoreInItem::getSectionNo).collect(Collectors.toList());
//        //炉次号列表
//        List<String> lotNos = new ArrayList<>();
//        //设备编号列表
//        List<String> deviceNos = new ArrayList<>();
//        for (String sectionNo : sectionItems) {
//            String lotNo = null;
//            String deviceNo = null;
//            if (sectionNo.length() >= 18) {
//                //炉次号
//                //lotNo = sectionNo.substring(7,16);
//                lotNo = SectionNoUtil.getLotNoFromSectionNo(sectionNo);
//                //deviceNo = sectionNo.substring(11,14);
//                deviceNo = SectionNoUtil.getDeviceNoFromSectionNo(sectionNo);
//            }
//            if (StringUtils.isNotBlank(lotNo)) {
//                lotNos.add(lotNo);
//            }
//            if (StringUtils.isNotBlank(deviceNo)) {
//                deviceNos.add(deviceNo);
//            }
//        }
//        //查询原来的物料号与单晶编号匹配的信息
////        List<SapSectionMaterialNumber> orgSapSectionMaterialNumberList = sapSectionMaterialNumberDao.getListBySectionList(sectionItems);
//        //根据设备编号列表查询SAP订单信息
//        String sapDate = SapUtil.getDateNowForSap(540);
//        //List<SapProductionSchedule> sapProductionSchedules = sapProductionScheduleDao.getByDeviceNoListAndDate(deviceNos,sapDate);
//        //List<SapProductionSchedule> sapProductionSchedules = null;
////        List<SapSectionMaterialNumber> newSapSectionMaterialNumberList = new ArrayList<>();
//        //获取综计退料列表
//        List<TurnstoreInItem> wmsBackItems = itemDao.getWmsBackBySectionNoAndType(sectionItems);
//        for (TurnstoreInItem turnstoreInItem : items) {
//            //是否综计退料的复检单晶
//            Integer type = EnumValues.SapSectionType.正常单晶.getValue();
//            //根据炉次号 查询订单客户
//
//            String customerIn = null;
//            //炉次号
//            String lotNo = null;
//            //设备编号
//            String deviceNo = null;
//            //排程信息
//            //SapProductionSchedule sapProductionSchedule = null;
//            if (turnstoreInItem.getSectionNo().length() >= 17) {
//                //炉次号
//                //lotNo = turnstoreInItem.getSectionNo().substring(7,16);
//                lotNo = SectionNoUtil.getLotNoFromSectionNo(turnstoreInItem.getSectionNo());
//                //deviceNo = turnstoreInItem.getSectionNo().substring(11,14);
//                deviceNo = SectionNoUtil.getDeviceNoFromSectionNo(turnstoreInItem.getSectionNo());
//            }
//            //导电型号 从产品类型截取
//            String conductiveType = turnstoreInItem.getProductTypeSecond().substring(0, 1);
//            //第三位编号 掺杂剂
//            String sectionNoThirdPosition = turnstoreInItem.getSectionNo().substring(2, 3);
//            if (sectionNoThirdPosition.equals("S") || sectionNoThirdPosition.equals("s")) {
//                sectionNoThirdPosition = "G";
//            }
//            String productLevelSecond = turnstoreInItem.getProductLevelSecond();
//            if (null != productLevelSecond && productLevelSecond.contains("━")) {
//                productLevelSecond = productLevelSecond.replaceAll("━", "-");
//            }
//            //单晶直径 从产品类型截取
//            BigDecimal diameter = new BigDecimal(turnstoreInItem.getProductTypeSecond().substring(2));
//          /*  String materialNumber = sapSectionMaterialNumberDao.getMaterialNumber(conductiveType, sectionNoThirdPosition, diameter, productLevelSecond, turnstoreInItem.getInstoreLength(), 1, customerIn);
//            SapSectionMaterialNumber sapSectionMaterialNumber = orgSapSectionMaterialNumberList.stream().filter(o -> o.getSectionNo().equalsIgnoreCase(turnstoreInItem.getSectionNo())).findAny().orElse(null);
//            //没有评过物料
//            if (sapSectionMaterialNumber == null) {
//                sapSectionMaterialNumber = new SapSectionMaterialNumber();
//                sapSectionMaterialNumber.setId(null);
//                sapSectionMaterialNumber.setSectionNo(turnstoreInItem.getSectionNo());
//                sapSectionMaterialNumber.setOrgMaterialNumber(materialNumber);
//                sapSectionMaterialNumber.setNewMaterialNumber(materialNumber);
//                sapSectionMaterialNumber.setCreateDate(new Date());
//                sapSectionMaterialNumber.setUpdateDate(new Date());
//            }
//            //评过物料 更新旧物料编号、新物料编号
//            else {
//                sapSectionMaterialNumber.setOrgMaterialNumber(sapSectionMaterialNumber.getNewMaterialNumber());
//                sapSectionMaterialNumber.setNewMaterialNumber(materialNumber);
//                sapSectionMaterialNumber.setUpdateDate(new Date());
//            }
//            sapSectionMaterialNumber.setWeight(turnstoreInItem.getInstoreWeight());
//            sapSectionMaterialNumber.setOrgWeight(turnstoreInItem.getInstoreWeight());*/
//            if ("复检单晶".equals(turnstoreInItem.getReCheckType())) {
//                type = EnumValues.SapSectionType.复检单晶.getValue();
//            }
//            if (wmsBackItems != null && wmsBackItems.size() > 0) {
//                for (TurnstoreInItem checkEntity : wmsBackItems) {
//                    if (checkEntity.getSectionNo().equals(turnstoreInItem.getSectionNo())) {
//                        type = EnumValues.SapSectionType.记产单晶.getValue();
//                        break;
//                    }
//                }
//                if ("复检单晶".equals(turnstoreInItem.getReCheckType())) {
//                    type = EnumValues.SapSectionType.记产复检单晶.getValue();
//                }
//            }
//
//        }
////        sapSectionMaterialNumberDao.saveAll(newSapSectionMaterialNumberList);
//    }

    @Override
    public void createIn(TurnstoreIn turnstoreIn, List<TurnstoreInItem> items) {
//        checkSectionNosIn(turnstoreIn, items);
        //查询上次单号顺序
        Date now = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String nowDateStr = dateFormat.format(now);
        Integer lastSort = dao.getMaxSortByDate(nowDateStr);
        turnstoreIn.setTime(now);
        turnstoreIn.setDate(now);
        turnstoreIn.setState(EnumValues.InState.待入库.getValue());
      /*  if (turnstoreIn.getType().equals(EnumValues.InType.综计退料.getValue())) {
            turnstoreIn.setState(EnumValues.InState.已入库.getValue());
        } else {
            turnstoreIn.setState(EnumValues.InState.待入库.getValue());
        }*/

        turnstoreIn.setSort(lastSort + 1);
        turnstoreIn.setCount(items.size());
        //生成单号
        String orderNo = Utlis.getOrderNoByType(turnstoreIn.getType(), lastSort + 1);
        if (StringUtils.isBlank(orderNo)) {
            throw new RuntimeException("退库单号生成失败");
        }
        turnstoreIn.setOrderNo(orderNo);
        //添加退库次数默认值
        turnstoreIn.setCancelNum(0);
        dao.save(turnstoreIn);
        for (TurnstoreInItem turnstoreInItem : items) {
            turnstoreInItem.setId(null);
            //主表ID
            turnstoreInItem.setInId(turnstoreIn.getId());
            turnstoreInItem.setType(turnstoreIn.getType());
            turnstoreInItem.setState(turnstoreIn.getState());
            turnstoreInItem.setOrderNo(orderNo);
            turnstoreInItem.setUser(turnstoreIn.getUser());
            turnstoreInItem.setTime(now);
            turnstoreInItem.setPurpose(turnstoreIn.getPurpose());
            turnstoreInItem.setReturnStation(turnstoreIn.getReturnStation());
            turnstoreInItem.setLocationName(EnumValues.InType.方棒退料.getValue());
            turnstoreInItem.setBatchNo(turnstoreIn.getBatchNo());
            TurnstoreInItem tii = itemDao.getItems2SectionNoAndType(turnstoreInItem.getSectionNo(), turnstoreInItem.getType());
            if (Objects.nonNull(tii)) {
                turnstoreInItem.setTimes(tii.getTimes() + 1);
            }
            //将在制品状态更新为已出站
//            handleOutStation(turnstoreIn.getPurpose(),turnstoreInItem.getSectionNo(),"B",false);
            handleOutStation(turnstoreIn.getPurpose(), turnstoreInItem.getSectionNo(), false, turnstoreIn.getReturnStation());
        }
        itemDao.saveAll(items);

    }

    public void handleWipState(List<String> nos, String state) {
        dao.updateWipStateBySnIn(nos, state);
    }

    @Override
    public void updateIn(TurnstoreIn turnstoreIn, List<TurnstoreInItem> items) {
        checkSectionNosInUpdate(turnstoreIn, items, turnstoreIn.getId());
        turnstoreIn.setTime(new Date());
        turnstoreIn.setCount(items.size());
        //编辑状态重置为待入库
        turnstoreIn.setState(EnumValues.InState.待入库.getValue());
        dao.save(turnstoreIn);

        // 圆棒入库
        List<String> nos = new ArrayList<>();
        List<String> orgNos = new ArrayList<>();
        if (EnumValues.InType.圆棒入库.getValue().equals(turnstoreIn.getType())) {
            orgNos = itemDao.getSectionNoByInId(turnstoreIn.getId());
            nos = items.stream().map(TurnstoreInItem::getSectionNo).collect(Collectors.toList());
        }

        //删除明细
        itemDao.deleteByInId(turnstoreIn.getId());
        //set冗余字段
        for (TurnstoreInItem turnstoreInItem : items) {
            turnstoreInItem.setId(null);
            //主表ID
            turnstoreInItem.setInId(turnstoreIn.getId());
            turnstoreInItem.setType(turnstoreIn.getType());
            turnstoreInItem.setState(turnstoreIn.getState());
            turnstoreInItem.setOrderNo(turnstoreIn.getOrderNo());
            turnstoreInItem.setUser(turnstoreIn.getUser());
            turnstoreInItem.setTime(new Date());
            turnstoreInItem.setLocationName(EnumValues.InType.方棒退料.getValue());
            turnstoreInItem.setBatchNo(turnstoreIn.getBatchNo());
            turnstoreInItem.setPurpose(turnstoreIn.getPurpose());
            turnstoreInItem.setReturnStation(turnstoreIn.getReturnStation());
            //将在制品状态更新为已出站
//            handleOutStation(turnstoreIn.getPurpose(),turnstoreInItem.getSectionNo(),"B",false);
            //将在制品状态更新为已出站
            handleOutStation(turnstoreIn.getPurpose(), turnstoreInItem.getSectionNo(), false, turnstoreIn.getReturnStation());
        }

        itemDao.saveAll(items);
    /*    //生成料号
        getMaterialNumber(items); */
    }

    @Autowired
    private PlanProcessingOrderService planProcessingOrderService;

    /**
     * 退料处理方法
     *
     * @param purpose       退料目标站点
     * @param sectionNo     晶段编号
     * @param isCancle      true：取消退料申请单，false：创建退料申请单
     * @param returnStation 退料站点
     */
    private void handleOutStation(String purpose, String sectionNo, Boolean isCancle, String returnStation) {
        //将在制品状态更新为已出站
        if (StringUtils.equals(purpose, EnumValues.ReturnPurposeType.ROUND_ROD_INSPECTION.getValue())) {
            if (StringUtils.equals(returnStation, "开方站")) {
                if (!isCancle) { // 开方站执行退料
                    PlanProcessingOrderWipStorageDto planProcessingOrderWipStorageDto = wipStorageService.selectWipStorage(sectionNo, EnumValuesFactory.WipStorageCode.开方.getKey(), null);
                    materialReturn(sectionNo, planProcessingOrderWipStorageDto);

                } else { // 开方站取消退料
                    cancelMaterialReturn(sectionNo);
                }
            } else if (StringUtils.equals(returnStation, "粘圆棒站")) {
                if (!isCancle) {
                    PlanProcessingOrderWipStorageDto planProcessingOrderWipStorageDto = wipStorageService.selectWipStorage(sectionNo, EnumValuesFactory.WipStorageCode.粘圆棒.getKey(), null);
                    materialReturn(sectionNo, planProcessingOrderWipStorageDto);
                } else {
                    cancelMaterialReturn(sectionNo);
                }
            } else {
                throw new BusinessException(returnStation + "不能退至" + EnumValues.ReturnPurposeType.ROUND_ROD_INSPECTION.getKey());
            }
        } else if (StringUtils.equals(purpose, EnumValues.ReturnPurposeType.SQUARE_ROD_INSPECTION.getValue())) {
            if (StringUtils.equals(returnStation, "粘方棒站")) {
                if (!isCancle) {
                    PlanProcessingOrderWipStorageDto planProcessingOrderWipStorageDto = wipStorageService.selectWipStorage(sectionNo, EnumValuesFactory.WipStorageCode.粘方棒.getKey(), null);
                    materialReturn(sectionNo, planProcessingOrderWipStorageDto);
                } else {
                    cancelMaterialReturn(sectionNo);
                }
            } else {
                throw new BusinessException(returnStation + "不能退至" + EnumValues.ReturnPurposeType.SQUARE_ROD_INSPECTION.getKey());
            }
        } else {
            throw new BusinessException("目标站点异常");
        }
    }

    /**
     * 工单取消退料状态
     *
     * @param sectionNo
     */
    private void cancelMaterialReturn(String sectionNo) {
        List<PlanProcessingOrder> planProcessingOrders = planProcessingOrderService.findByCodeOrderByIdDesc(sectionNo);
        if (planProcessingOrders.isEmpty()) {
            throw new BusinessException(sectionNo + "工单号不存在");
        }
        PlanProcessingOrder planProcessingOrder = planProcessingOrders.get(0);
        if (planProcessingOrder.getStatus() != EnumValuesFactory.PlanProcessingOrderStatus.组托.getKey()) {
            throw new BusinessException(sectionNo + "不是" + EnumValuesFactory.PlanProcessingOrderStatus.组托.getValue() + "状态");
        }
        planProcessingOrder.setStatus(EnumValuesFactory.PlanProcessingOrderStatus.加工中.getKey());
        planProcessingOrderService.createPlanProcessingOrder(planProcessingOrder, null, null);
    }

    /**
     * 工单设为退料
     *
     * @param sectionNo
     * @param planProcessingOrderWipStorageDto
     */
    private void materialReturn(String sectionNo, PlanProcessingOrderWipStorageDto planProcessingOrderWipStorageDto) {
        PlanProcessingOrder planProcessingOrder = planProcessingOrderWipStorageDto.getPlanProcessingOrder();
        if (planProcessingOrder.getStatus() == EnumValuesFactory.PlanProcessingOrderStatus.组托.getKey()) {
            throw new BusinessException(sectionNo + "已是" + EnumValuesFactory.PlanProcessingOrderStatus.组托.getValue() + "状态");
        }
        planProcessingOrder.setStatus(EnumValuesFactory.PlanProcessingOrderStatus.组托.getKey());
        planProcessingOrderService.createPlanProcessingOrder(planProcessingOrder, null, null);
    }


    @Override
    public void deleteIn(Integer id) {
        TurnstoreIn entity = get(id);
        if (entity == null) {
            throw new RuntimeException("此入库申请单不存在");
        }
        if (entity.getState().equals(EnumValues.InState.已入库.getValue())) {
            throw new RuntimeException("已入库申请单不能删除");
        }

        // 圆棒入库
        if (EnumValues.InType.圆棒入库.getValue().equals(entity.getType())) {
            List<String> nos = itemDao.getSectionNoByInId(entity.getId());
            if (nos != null && !nos.isEmpty()) {
                handleWipState(nos, "WIP_Y");
            }
        }

        itemDao.deleteByInId(id);
        dao.delete(entity);
    }

    @Override
    public void returnTurnstore(Integer id, String confirmUser, String reason, String remark) {
        TurnstoreIn entity = dao.getOne(id);
        if (entity == null) {
            throw new RuntimeException("此方棒退库申请单不存在");
        }

        if (entity.getState().equals(EnumValues.InState.已入库.getValue())) {
            throw new RuntimeException("圆棒已接收不能删除");
        }
//        Optional.ofNullable(itemDao.getSectionNoByInId(id)).orElse(new ArrayList<>()).forEach((sectionNo) -> handleOutStation(entity.getPurpose(),sectionNo,"A",true));
        //将在制品状态回退到进站
        Optional.ofNullable(itemDao.getSectionNoByInId(id)).orElse(new ArrayList<>()).forEach((sectionNo) -> handleOutStation(entity.getPurpose(), sectionNo, true, entity.getReturnStation()));
        itemDao.updateById(EnumValues.InState.退回.getValue(), id, confirmUser);
        entity.setState(EnumValues.InState.退回.getValue());
        entity.setReason(reason);
        if (StringUtils.isNotBlank(remark)){
            entity.setRemark(remark);
        }
        entity.setConfirmUser(confirmUser);
        dao.save(entity);
    }

    @Override
    public void backIn(Integer id, String userName) {
        TurnstoreIn entity = dao.getOne(id);
        if (entity == null) {
            throw new RuntimeException("此入库申请单不存在");
        }
        if (entity.getState().equals(EnumValues.InState.已入库.getValue())) {
            throw new RuntimeException("已入库申请单不能退回");
        }
        entity.setState(EnumValues.InState.退回.getValue());
        entity.setConfirmUser(userName);
        dao.save(entity);
    }

    @Override
    public void confirmIn(Integer id, String userName) {
        TurnstoreIn entity = dao.getOne(id);
        if (entity == null) {
            throw new RuntimeException("此入库申请单不存在");
        }
        if (!entity.getState().equals(EnumValues.InState.待入库.getValue())) {
            throw new RuntimeException("只有待入库的申请单可以确认");
        }
        List<TurnstoreInItem> inItems = itemDao.getItemsByInId(id);
        if (inItems == null || inItems.isEmpty()) {
            throw new RuntimeException("此入库申请单明细错误");
        }
//      //判断是否在周转库
        checkSectionNosConfirmIn(inItems);
        //List<TurnstoreInItem> inItems = itemDao.getItemsByInId(id);
        if (inItems.isEmpty()) {
            throw new RuntimeException("此入库申请单明细错误");
        }

        List<Turnstore> inList = fromDto(inItems);

        for (Turnstore turnstore : inList) {
            turnstore.setId(null);
            turnstore.setInstoreOrderNo(entity.getOrderNo());
            turnstore.setInstoreType(entity.getType());
            turnstore.setInstoreTime(new Date());
            turnstore.setInstoreOperateUser(userName);
            turnstore.setRemark(entity.getRemark());
            turnstore.setOutState(EnumValues.OutState.未组拖.getValue());
        }

        turnstoreDao.saveAll(inList);


        //更新申请的状态
        entity.setState(EnumValues.InState.已入库.getValue());
        entity.setTime(new Date());
        entity.setConfirmUser(userName);
        dao.save(entity);

        List<String> sectionItems = inItems.stream().map(TurnstoreInItem::getSectionNo).collect(Collectors.toList());
        List<Map<String, Object>> inspectInfoMap = turnstoreOutDao.getInfoBySectionNos(sectionItems);
        //更新明细的状态
        for (TurnstoreInItem turnstoreInItem : inItems) {
            turnstoreInItem.setState(EnumValues.InState.已入库.getValue());
            turnstoreInItem.setConfirmUser(userName);

            for (Map<String, Object> map : inspectInfoMap) {
                if (map.get("sectionNo") != null && StringUtils.isNotBlank(map.get("sectionNo").toString())) {
                    String sectionNo = map.get("sectionNo").toString();
                    if (turnstoreInItem.getSectionNo().trim().equalsIgnoreCase(sectionNo)) {
                        turnstoreInItem.setRemark(map.get("remark") == null ? null : map.get("remark").toString());
                        turnstoreInItem.setFineDiameter(map.get("fineDiameter") == null ? null : new BigDecimal(map.get("fineDiameter").toString()));
                        break;
                    }
                }
            }
        }
        itemDao.saveAll(inItems);
    }

    @Override
    public Long getMaxBatchNo() {
        return dao.getMaxBatchNo();
    }

    @Override
    public List<TurnstoreIn> getItemsByBatchNo(Long batchNo) {
        return dao.getItemsByBatchNo(batchNo);
    }

    /**
     * 退料接收
     *
     * @param turnstoreIn
     * @param turnstoreInItems
     */
    @Override
    public void confirmOut(TurnstoreIn turnstoreIn, List<TurnstoreInItem> turnstoreInItems) {
        if (null == turnstoreIn || CollectionUtils.isEmpty(turnstoreInItems)) {
            return;
        }
        String withdrawingType=null;
        if(turnstoreInItems.size()>0){
            withdrawingType=turnstoreInItems.get(0).getWithdrawingType();
        }
        String wipStatusCode = null;
        if (!turnstoreInItems.isEmpty()) {
            //关联开方站退库到圆棒检验站
            if ("开方站".equals(turnstoreInItems.get(0).getReturnStation())) {
                wipStatusCode = EnumValuesFactory.WipStorageCode.开方.getKey();
            } else if ("粘圆棒站".equals(turnstoreInItems.get(0).getReturnStation())) {
                wipStatusCode = EnumValuesFactory.WipStorageCode.粘圆棒.getKey();
            }else if ("粘方棒站".equals(turnstoreInItems.get(0).getReturnStation())) {
                wipStatusCode = EnumValuesFactory.WipStorageCode.粘方棒.getKey();
            } else {
                throw new BusinessException(turnstoreInItems.get(0).getReturnStation() + "该退料站点不支持，退料接收");
            }
        }

        //方棒退库到圆棒标识
        Boolean purposeIsRodFlag = StringUtils.equals(turnstoreIn.getPurpose(), EnumValues.ReturnPurposeType.ROUND_ROD_INSPECTION.getValue());
        List<ReturnRecord> returnRecordList = new ArrayList<>();
        List<String> sectionNoList = new ArrayList<>();
        String finalWipStatusCode = wipStatusCode;
        Optional.of(turnstoreInItems).orElse(new ArrayList<>()).forEach((turnstoreInItem) -> {
            turnstoreInItem.setLocationName(EnumValues.InType.方棒退料接收.getValue());
            turnstoreInItem.setState(EnumValues.InState.已入库.getValue());
//            if (StringUtils.isNotBlank(turnstoreInItem.getSectionNo()) && StringUtils.equals("退库复检", turnstoreInItem.getWithdrawingType())) {
            //需求修改调整
            //查询数据字典中接收类型的扩展字段
            DictionaryItem dictionaryItem = null;
            if (StringUtils.isNotBlank(turnstoreInItem.getSectionNo()) && StringUtils.isNotBlank(turnstoreInItem.getWithdrawingType()) && turnstoreInItem.getWithdrawingType().contains("复检")) {
                sectionNoList.add(turnstoreInItem.getSectionNo());
                dictionaryItem = dictionaryItemService.findByThemeValueAndValue("withdrawing_type", turnstoreInItem.getWithdrawingType());
            }


            Integer isDirectIn = EnumValuesFactory.WipStorageStatus.待进站.getKey();
            if (null != dictionaryItem && StringUtils.equals(dictionaryItem.getExtendValue(),"1")){
                isDirectIn = EnumValuesFactory.WipStorageStatus.已进站.getKey();
            }

            //查询在制品状态
            wipStorageService.selectWipStorage(turnstoreInItem.getSectionNo(), finalWipStatusCode, null, EnumValuesFactory.PlanProcessingOrderStatus.组托.getKey());
            //将工单状态恢复正常
            cancelMaterialReturn(turnstoreInItem.getSectionNo());
            //执行出站操作
            Result result = wipStorageService.outStation(turnstoreInItem.getSectionNo(), "B", isDirectIn, false);
            if (result.getCode() != ResultCode.SUCCESS.getCode()) {
                //手动回滚事务
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new RuntimeException(result.getMessage());
            }

            turnstoreInItemService.saveOrUpdate(turnstoreInItem);
            if (purposeIsRodFlag){
                ReturnRecord returnRecord = ReturnRecord.builder().sectionNo(turnstoreInItem.getSectionNo())
                        .orderNo(turnstoreInItem.getOrderNo()).withdrawingType(turnstoreInItem.getWithdrawingType()).state(1)
                        .userName(turnstoreInItem.getUser()).operationTime(turnstoreInItem.getTime())
                        .confirmTime(turnstoreInItem.getTime()).confirmUser(BaseContextHandler.getUsername())
                        .productLevel(turnstoreInItem.getProductLevelSecond()).experGrade(turnstoreInItem.getProductLevelExperiment())
//                        .specs(turnstoreInItem.getProductTypeSecond()).inputLength(turnstoreInItem.getInstoreLength())
                        .inputLength(turnstoreInItem.getInstoreLength())
//                        .sectionType(turnstoreInItem.getSectionType())
                        .instoreWeight(turnstoreInItem.getInstoreWeight()).actualLength(turnstoreInItem.getActualLength())
                        .weight(turnstoreInItem.getActualWeight()).fineCutLength(turnstoreInItem.getFineCutLength())
                        .collapseLine(turnstoreInItem.getCollapseLine()).reCheckType("复检")
                        .purpose(turnstoreInItem.getPurpose()).returnStation(turnstoreInItem.getReturnStation())
                        .isRecheck(1).remark(turnstoreIn.getRemark()).build();
                returnRecordList.add(returnRecord);
            }

        });
        turnstoreIn.setState(EnumValues.InState.已入库.getValue());
        dao.save(turnstoreIn);
        //方棒退料接收，接收时，若类型为：退库复检，则需要把这些晶段编号在检验数据库里的订单类型（ order_Type）赋值为：ZH04
        if (CollectionUtils.isNotEmpty(sectionNoList)) {
            if (purposeIsRodFlag) {
                if("退库反切复检".equals(withdrawingType)){
                    inspectDataBaseService.updateOrderTypeBySectionNoList(sectionNoList, EnumValuesServer.ProductionOrderType.返工.getKey(), "复检");
                }else{
                    inspectDataBaseService.updateOrderTypeBySectionNoListNoType(sectionNoList, EnumValuesServer.ProductionOrderType.返工.getKey(), "复检");

                }
               //批量保存圆棒退库数据
                returnRecordService.saveAll(returnRecordList);
                //更新托号中状态
                //turnstoreTrayItemService.updateTrayItemState(sectionNoList);
            } else if (StringUtils.equals(turnstoreIn.getPurpose(), EnumValues.ReturnPurposeType.SQUARE_ROD_INSPECTION.getValue())) {
                fbFeignClients.updateOrderTypeByFbSectionNoList(sectionNoList);
            }

        }
    }

    @Override
    public void cancelTurnstore(Integer id, String confirmUser) {
        TurnstoreIn entity = get(id);
        if (entity == null) {
            throw new RuntimeException("方棒退库申请单不存在!");
        }

        if (entity.getState().equals(EnumValues.InState.已入库.getValue())) {
            throw new RuntimeException("已接收不能取消");
        }
        //查询详细单晶
        Optional.ofNullable(itemDao.getSectionNoByInId(id)).orElse(new ArrayList<>()).forEach((sectionNo) -> handleOutStation(entity.getPurpose(), sectionNo, true, entity.getReturnStation()));
        itemDao.updateStateAndUserById(EnumValues.InState.取消.getValue(), id, confirmUser);
        entity.setState(EnumValues.InState.取消.getValue());
        entity.setUser(confirmUser);
        entity.setCancelNum(null != entity.getCancelNum() ? entity.getCancelNum() + 1 : 1);
        entity.setCancelCrystalNum(entity.getCount());
        dao.save(entity);
    }

    public List<Turnstore> fromDto(List<TurnstoreInItem> dto) {
        //ModelMapper modelMapper = new ModelMapper();
        modelMapper.getConfiguration().setFullTypeMatchingRequired(true);
        modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
        List<Turnstore> listEntity = dto.stream().map(turnstore -> modelMapper.map(turnstore, Turnstore.class)).collect(Collectors.toList());
        return listEntity;
    }
}
