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

import com.alibaba.fastjson.JSON;
import com.sw.mes.base.factory.inspect.dto.SupportRuleDto;
import com.sw.mes.base.factory.inspect.entity.BarSupportRule;
import com.sw.mes.base.factory.inspect.service.BarSupportRuleService;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.service.DictionaryItemService;
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.annotation.ServiceLogs;
import com.sw.mes.core.api.system.FbFeignClients;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.dto.TrayPostDto;
import com.sw.mes.core.dto.TurnstoreTrayDto;
import com.sw.mes.core.entity.TurnstoreTrayItem;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultCode;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.core.utils.BeanUtil;
import com.sw.mes.core.utils.DateUtil;
import com.sw.mes.core.utils.ThreadManager;
import com.sw.mes.inspect.entity.YbInspectData;
import com.sw.mes.inspect.service.YbInspectDataService;
import com.sw.mes.sap.SapServer;
import com.sw.mes.third.service.SapGrService;
import com.sw.mes.yb.plan.service.ProductionOrderService;
import com.sw.mes.yb.turnstore.dao.TurnstoreDao;
import com.sw.mes.yb.turnstore.dao.TurnstoreTrayDao;
import com.sw.mes.yb.turnstore.dto.WmsToYbReceiveDto;
import com.sw.mes.yb.turnstore.dto.YbToWmsReceiptDataDto;
import com.sw.mes.yb.turnstore.dto.YbToWmsReceiptDto;
import com.sw.mes.yb.turnstore.entity.TurnstoreTray;
import com.sw.mes.yb.turnstore.service.TurnstoreTrayItemService;
import com.sw.mes.yb.turnstore.service.TurnstoreTrayService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@Slf4j
@Service
@Transactional
public class TurnstoreTrayServiceImpl extends BaseServiceImpl<TurnstoreTray> implements TurnstoreTrayService {
    @Autowired
    ModelMapper modelMapper;

    TurnstoreTrayDao dao;

    @Autowired
    TurnstoreDao turnstoreDao;

    @Autowired
    private DictionaryItemService dictionaryItemService;

    @Autowired
    @Lazy
    private TurnstoreTrayItemService turnstoreTrayItemService;

    @Autowired
    private YbInspectDataService inspectService;

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private WipStorageService wipStorageService;

    @Resource
    private FbFeignClients fbFeignClients;

    @Autowired
    private BarSupportRuleService barSupportRuleService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private PlanProcessingOrderService planProcessingOrderService;

    @Value("${wms.url}")
    private String wmsUrl;

    @Autowired
    private ProductionOrderService productionOrderService;

    @Autowired
    private YbInspectDataService inspectDataBaseService;

    @Autowired
    private SapServer sapService;


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

    @Autowired
    private SapGrService sapGrService;

    @Autowired
    @Lazy
    private TurnstoreTrayService turnstoreTrayService;

    @Override
    public String createTray(BarSupportRule ruleDto, TurnstoreTray turnstoreTray, List<TurnstoreTrayItem> items, String trayNo1, String trayNo2) {
        //生成托号
        createTrayNo(ruleDto, turnstoreTray);
        Date date = new Date();
        turnstoreTray.setTime(date);
        turnstoreTray.setOperationTime(date);
        TurnstoreTray tray = dao.save(turnstoreTray);
        //保存明细字段
        saveItemList(tray, items);
        //合拖更新历史数据
        if (null != trayNo1 && null != trayNo2 && !trayNo1.isEmpty() && !trayNo2.isEmpty()) {
            //更新组托1
            updateOldTray(date, trayNo1, turnstoreTray.getUpdateUser());
            //更新组托2
            updateOldTray(date, trayNo2, turnstoreTray.getUpdateUser());
        }
        return turnstoreTray.getTrayNo();
    }

    private void updateOldTray(Date date, String trayNo, String updateUser) {
        //更新组托主表
        TurnstoreTray byTrayNo = findByTrayNo(trayNo);
        byTrayNo.setState(8);
        byTrayNo.setOperationTime(date);
        byTrayNo.setUpdateUser(updateUser);
        saveOrUpdate(byTrayNo);
        //更新组托列表
        List<TurnstoreTrayItem> itemsByTrayNo = turnstoreTrayItemService.getItemsByTrayNo(trayNo);
        for (TurnstoreTrayItem trayItem : itemsByTrayNo) {
            trayItem.setState(8);
            trayItem.setOperationTime(date);
            turnstoreTrayItemService.saveOrUpdate(trayItem);
        }
    }

    private void saveItemList(TurnstoreTray turnstoreTray, List<TurnstoreTrayItem> items) {
        for (int i = 0; i < items.size(); i++) {
            if (9 == turnstoreTray.getState()) {
                items.get(i).setState(turnstoreTray.getState());
            }
            //序号
            if (null == items.get(i).getOrderNum()) {
                items.get(i).setOrderNum(i + 1);
            }
            //空操作人赋值
            if (null == items.get(i).getUser()) {
                if (null != turnstoreTray.getUpdateUser()) {
                    items.get(i).setUser(turnstoreTray.getUpdateUser());
                } else {
                    items.get(i).setUser(turnstoreTray.getUser());
                }
            }
            items.get(i).setHasGone(turnstoreTray.getHasGone());
            items.get(i).setTrayId(turnstoreTray.getId());
            items.get(i).setTrayNo(turnstoreTray.getTrayNo());
            items.get(i).setOperationTime(turnstoreTray.getOperationTime());

            //锁定为组托状态
            PlanProcessingOrder planProcessingOrder = planProcessingOrderService.findByCode(items.get(i).getSectionNo());
            if (null != planProcessingOrder) {
                if ("退料".equals(turnstoreTray.getHasGone())) {
                    planProcessingOrder.setStatus(EnumValuesFactory.PlanProcessingOrderStatus.已作废.getKey());
                } else {
                    planProcessingOrder.setStatus(EnumValuesFactory.PlanProcessingOrderStatus.组托.getKey());
                }
                planProcessingOrderService.saveOrUpdate(planProcessingOrder);
            }
            turnstoreTrayItemService.saveOrUpdate(items.get(i));
        }
    }

    /**
     * 生成托号
     *
     * @param ruleDto       组托规则
     * @param turnstoreTray 组托信息
     */
    @Override
    public String createTrayNo(BarSupportRule ruleDto, TurnstoreTray turnstoreTray) {
        StringBuilder trayNo = new StringBuilder();
        String order3Num = null;
        String order5Num = null;
        String num3Value;
        String num5Value;
        String key5 = "YBOrderNum5";
        String key3 = "YBOrderNum3";
        //日期获取
        long time = new DateUtil().getChangeShiftsTime().getTime();
        Calendar cal = Calendar.getInstance();
        if (System.currentTimeMillis() < time) {
            cal.add(Calendar.DATE, -1);
        } else {
            cal.add(Calendar.DATE, 0);
        }
        String date = new SimpleDateFormat("yyMMdd").format(cal.getTime());
        if ("综计WMS".equals(turnstoreTray.getHasGone())) {
            if (null == ruleDto) {
                ruleDto = barSupportRuleService.findRuleByGroupName(turnstoreTray.getRuleName());
            }
            //规则匹配托号
            String spacer = ",";
            String workShop = "六期圆棒";
            //第一位:厂别:Y
            DictionaryItem shopValue;
            shopValue = dictionaryItemService.findByThemeValueAndNameAndEnable("workShop", workShop, true);
            if (null != shopValue) {
                trayNo.append(shopValue.getValue());
            } else {
                trayNo.append("Y");
            }
            //第二位:整拼类型
            DictionaryItem pinValue;
            if (null == ruleDto.getSticksCount() || "".equals(ruleDto.getSticksCount()) || ruleDto.getSticksCount().contains(spacer)) {
                String pin = "混拼";
                pinValue = dictionaryItemService.findByThemeValueAndNameAndEnable("spell", pin, true);
            } else {
                String type = ruleDto.getSticksCount() + "拼";
                pinValue = dictionaryItemService.findByThemeValueAndNameAndEnable("spell", type, true);
            }
            if (null != pinValue) {
                trayNo.append(pinValue.getValue());
            } else {
                trayNo.append("Z");
            }
            //第三位:棒长
            String lengthType = "不区分棒长";
            String dtoLength = ruleDto.getLength();
            DictionaryItem lengthValue;
            if (lengthType.equals(dtoLength)) {
                lengthValue = dictionaryItemService.findByThemeValueAndNameAndEnable("rodLength", lengthType, true);
            } else if (dtoLength.contains(spacer)) {
                lengthValue = dictionaryItemService.findByThemeValueAndNameAndEnable("rodLength", "800-900", true);
            } else {
                lengthValue = dictionaryItemService.findByThemeValueAndNameAndEnable("rodLength", dtoLength, true);
            }
            if (null != lengthValue) {
                trayNo.append(lengthValue.getValue());
            } else {
                trayNo.append("0");
            }
            //第四位:规格型号
            String spec = "转规格";
            String specs = ruleDto.getConductiveType() + "型" + ruleDto.getSpecs();
            DictionaryItem specValue;
            if (specs.contains("转")) {
                specValue = dictionaryItemService.findByThemeValueAndNameAndEnable("specMod", spec, true);
            } else {
                specValue = dictionaryItemService.findByThemeValueAndNameAndEnable("specMod", specs, true);
            }
            if (null != specValue) {
                trayNo.append(specValue.getValue());
            } else {
                trayNo.append("Z");
            }
            //第五位:产品等级
            String grade = "混类别";
            String productGrade = ruleDto.getProductGrade();
            DictionaryItem gradeValue;
            if (productGrade.contains(spacer)) {
                gradeValue = dictionaryItemService.findByThemeValueAndNameAndEnable("productRat", grade, true);
            } else {
                gradeValue = dictionaryItemService.findByThemeValueAndNameAndEnable("productRat", productGrade, true);
            }
            if (null != gradeValue) {
                trayNo.append(gradeValue.getValue());
            } else {
                trayNo.append("Z");
            }
            //第六-十一位:日期
            trayNo.append(date);
            //第十二-十四位:顺序号
            //Integer num = dao.findOrderNumByWMS();
            if (redisTemplate.hasKey(key3)) {
                //先获取redis中的顺序号
                num3Value = (String) redisTemplate.opsForValue().get(key3);
                order3Num = String.valueOf(Integer.parseInt(num3Value) + 1);
                if (order3Num.length() == 1) {
                    order3Num = "00" + order3Num;
                } else if (order3Num.length() == 2) {
                    order3Num = "0" + order3Num;
                }
            } else {
                order3Num = "001";
            }
            trayNo.append(order3Num);
            //第十五位:实验等级
            DictionaryItem experValue;
            if (null == ruleDto.getExperGrade() || ruleDto.getExperGrade().contains(spacer)) {
                experValue = dictionaryItemService.findByThemeValueAndNameAndEnable("tempSign", grade, true);
            } else {
                experValue = dictionaryItemService.findByThemeValueAndNameAndEnable("tempSign", ruleDto.getExperGrade(), true);
            }
            if (null != experValue) {
                trayNo.append(experValue.getValue());
            } else {
                trayNo.append("Z");
            }
        } else {
            trayNo.append("Y").append(date);
            //其他去向的托号按照流水号生成（年月日+五位流水）
            //Integer num = dao.findOrderNumByTime();
            if (redisTemplate.hasKey(key5)) {
                //先获取redis中的顺序号
                num5Value = (String) redisTemplate.opsForValue().get(key5);
                order5Num = String.valueOf(Integer.parseInt(num5Value) + 1);
                //查询最大托号+1.对比缓存+1,选取最大值
                TurnstoreTray tray = dao.queryDbNum();
                String maxOrderNum = tray.getTrayNo().substring(7);
                int max5Num = Integer.parseInt(maxOrderNum) + 1;
                if (max5Num > Integer.parseInt(order5Num)) {
                    order5Num = String.valueOf(max5Num);
                }
            } else {
                order5Num = "1";
            }
            trayNo.append(order5Num);
        }
        turnstoreTray.setTrayNo(trayNo.toString());
        if (null != order3Num) {
            turnstoreTray.setOrderNum(Integer.parseInt(order3Num));
        } else {
            turnstoreTray.setOrderNum(Integer.parseInt(order5Num));
        }
        //更新缓存
        //每天08:59:59秒重置
        long timeLong;
        if (System.currentTimeMillis() < time) {
            //小于当天08:59:59,计算至当天08:59:59
            timeLong = time - System.currentTimeMillis();
        } else {
            //大于当天08:59:59,计算至第二天08:59:59点
            timeLong = new DateUtil().getCurrentDayEndTime().getTime() + 32400000 - System.currentTimeMillis();
        }
        if (timeLong > 1000) {
            if (null != order3Num) {
                redisTemplate.opsForValue().set(key3, order3Num, timeLong / 1000, TimeUnit.SECONDS);
            } else {
                redisTemplate.opsForValue().set(key5, order5Num, timeLong / 1000, TimeUnit.SECONDS);
            }
        }
        //判断拖号是否重复
        if (null != dao.checkTrayNo(trayNo.toString())) {
            throw new RuntimeException("错误，生成的拖号【" + trayNo + "】已存在");
        }
        return trayNo.toString();
    }

    @Override
    public List<TurnstoreTrayItem> groupItemList(YbInspectData inspectData) {
        List<TurnstoreTrayItem> trayItemList = new ArrayList<>();
        //如果是拼棒则带出所有晶段信息
        String split = ",";
        if (null != inspectData.getSectionCompose() && inspectData.getSectionCompose().contains(split)) {
            String[] sections = inspectData.getSectionCompose().split(split);
            if (sections.length > 0) {
                for (String sectionNo : sections) {
                    YbInspectData inspectDataBase = inspectService.findBySectionNo(sectionNo);
                    if (null != inspectDataBase) {
                        packageItemList(trayItemList, inspectData);
                    }
                }
            }
        } else {
            //组装当前晶段信息
            packageItemList(trayItemList, inspectData);
        }
        return trayItemList;
    }

    @Override
    public Result valudate(YbInspectData inspectData) {
        if (null == inspectData.getMaterialCode()) {
            return ResultGenerator.fail("料号不能为空");
        }
//        else if (null == inspectData.getActualWeight()) {
//            return ResultGenerator.fail("实际称重不能为空");
//        }
//        else if (null == inspectData.getWareHouseLength()) {
//            return ResultGenerator.fail("入库长度不能为空");
//        }
        else if (null == inspectData.getActualLength()) {
            return ResultGenerator.fail("硅棒总长不能为空");
        } else if (null == inspectData.getTheoryWeight()) {
            return ResultGenerator.fail("理论重量不能为空");
        } else if (null == inspectData.getOrderNo()) {
            return ResultGenerator.fail("订单号不能为空");
        } else if (null == inspectData.getProductLevel()) {
            return ResultGenerator.fail("客户类别不能为空");
        }
        return ResultGenerator.success();
    }

    @Override
    public Result<String> updateState(TurnstoreTray entity, TrayPostDto trayPostDto) {
        try {
//            ThreadManager.getThreadPollProxy().execute(() -> {
            TurnstoreTray turnstoreTray = fromDto(trayPostDto.getTrayDto());
            Date date = turnstoreTray.getConfirmTime();
            turnstoreTray.setId(entity.getId());
            turnstoreTray.setUser(entity.getUser());
            BeanUtils.copyProperties(turnstoreTray, entity, BeanUtil.getIgnoreProperties(turnstoreTray, null, null));
            //更新详情
            List<TurnstoreTrayItem> trayItemList = trayPostDto.getTrayItems();
            List<TurnstoreTrayItem> sendGrtrayItems = new ArrayList<>();
            for (TurnstoreTrayItem trayItem : trayItemList) {
                TurnstoreTrayItem bySectionNo = turnstoreTrayItemService.findByTrayNoAndSectionNo(turnstoreTray.getTrayNo(), trayItem.getSectionNo());
                if (null != bySectionNo) {
                    bySectionNo.setConfirmTime(date);
                    bySectionNo.setConfirmUser(turnstoreTray.getConfirmUser());
                    bySectionNo.setState(trayItem.getState());
                    turnstoreTrayItemService.saveOrUpdate(bySectionNo);
                    // 确认接收
                    if (bySectionNo.getState() == 1) {
                        sendGrtrayItems.add(bySectionNo);
                    }
                }
            }
            dao.save(entity);
            sapService.sendGr(sendGrtrayItems);
//            });
            return ResultGenerator.success();
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
    }

    private void packageItemList(List<TurnstoreTrayItem> trayItemList, YbInspectData inspectData) {
        TurnstoreTrayItem turnstoreTrayItem = new TurnstoreTrayItem();
        BeanUtils.copyProperties(inspectData, turnstoreTrayItem, BeanUtil.getIgnoreProperties(inspectData, null, null));
        //异常
//        turnstoreTrayItem.setErrorMsg(inspectData.getAnomaly());
        //物料编号
        turnstoreTrayItem.setItemNo(inspectData.getMaterialCode());
        //客户类型
        turnstoreTrayItem.setCustomerType(inspectData.getProductLevel());
        String sectionNo = turnstoreTrayItem.getSectionNo();
        //单晶组合
        if (null == inspectData.getSectionCompose()) {
            turnstoreTrayItem.setSectionCompose(sectionNo + ";");
        } else {
            //替换
            String sectionCompose = inspectData.getSectionCompose().replaceAll(",", ";");
            turnstoreTrayItem.setSectionCompose(sectionCompose + ";");
        }
        //工厂
        String factory = sectionNo.substring(0, 1);
        DictionaryItem factoryCate = dictionaryItemService.findByThemeValueAndValueAndEnable("FactoryCate", factory, true);
        if (null != factoryCate) {
            factory = factoryCate.getName();
        }
        turnstoreTrayItem.setFactory(factory);
        //库存地点
        turnstoreTrayItem.setStockPlace("Q001");
        trayItemList.add(turnstoreTrayItem);
    }

    @Override
    public void updateTray(TurnstoreTray turnstoreTray, List<TurnstoreTrayItem> items) {
        turnstoreTray.setOperationTime(new Date());
        saveOrUpdate(turnstoreTray);
        //SET明细字段
        saveItemList(turnstoreTray, items);
    }

    @Override
    public void reGetSapOrderNo(List<String> sectionNos) {

    }

    @Override
    public void reGetSapOrderNoNotRechcek(List<String> sectionNos) {

    }

    @Override
    public void toWms(Integer id) {

    }

    @Override
    public String validateRules(SupportRuleDto ruleDto, YbInspectData inspectData) {
        String hun = "混类别";
        //判断规格是否符合
        if (null != ruleDto.getSpecs() && !"".equals(ruleDto.getSpecs())) {
            if (null == inspectData.getProductTypeSecond() || !ruleDto.getSpecs().contains(inspectData.getProductTypeSecond())) {
                return "规格不符合规则";
            }
        }
        //判断导电型号是否符合
        if (null != ruleDto.getConductiveType() && !"".equals(ruleDto.getConductiveType())) {
            if (null == inspectData.getConductiveType() || !ruleDto.getConductiveType().contains(inspectData.getConductiveType())) {
                return "导电型号不符合规则";
            }
        }
        //判断产品等级是否符合
        if (null != ruleDto.getProductGrade() && !"".equals(ruleDto.getProductGrade()) && !hun.equals(ruleDto.getProductGrade())) {
            if (null == inspectData.getProductLevel() || !ruleDto.getProductGrade().contains(inspectData.getProductLevel())) {
                return "产品等级不符合规则";
            }
        }
        //判断实验等级是否符合
        if (null != ruleDto.getExperGrade() && !"".equals(ruleDto.getExperGrade())) {
            if (null == inspectData.getProductLevelExperiment() || !ruleDto.getExperGrade().contains(inspectData.getProductLevelExperiment())) {
                return "实验等级不符合规则";
            }
        }
        //判断拼数是否符合
        if (null != ruleDto.getSticksCount() && !"".equals(ruleDto.getSticksCount())) {
            if (null == inspectData.getSticksCount() || !ruleDto.getSticksCount().contains(inspectData.getSticksCount().toString())) {
                return "拼数不符合规则";
            }
        }
        //判断长度范围是否符合
        if (null != ruleDto.getLength() && !"".equals(ruleDto.getLength()) && !"非标".equals(ruleDto.getLength())) {
            String length = ruleDto.getLength();
            String lengthType = "不区分棒长";
            if (!lengthType.equals(length) && null != inspectData.getActualLength()) {
                boolean flag = false;
                String[] lengths = length.split(",");
                for (String s : lengths) {
                    String[] split = s.split("-");
                    if (split.length != 2) {
                        return "长度范围规则不正确:" + length;
                    }
                    double minLength = Double.parseDouble(split[0]);
                    double maxLength = Double.parseDouble(split[1]);
                    double actualLength;
                    if (null != inspectData.getSpellBarLength()) {
                        actualLength = inspectData.getSpellBarLength().doubleValue();
                    } else {
                        actualLength = inspectData.getActualLength().doubleValue();
                    }
                    if (minLength <= actualLength && actualLength <= maxLength) {
                        flag = true;
                    }
                }
                if (!flag) {
                    return "长度范围不符合规则，只能为：" + ruleDto.getLength();
                }
            }
        }
        return "符合";
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateItem(TurnstoreTray turnstoreTray, List<TurnstoreTrayItem> turnstoreTrayItemList, Boolean autoReceive) {
        //查询详情列表
        for (TurnstoreTrayItem trayItem : turnstoreTrayItemList) {
            trayItem.setIsToWms(turnstoreTray.getIsToWms());
            trayItem.setToWmsTime(turnstoreTray.getToWmsTime());
            trayItem.setState(turnstoreTray.getState());
            trayItem.setOperationTime(turnstoreTray.getOperationTime());
            String hasGone = turnstoreTray.getHasGone();
            //同步更新站点信息
            if ("方棒加工".equals(hasGone)) {
                if (!autoReceive) {
                    //自动发料到开方的单独过站，不走次方法
                    wipStorageService.outStation(trayItem.getSectionNo(), "B", null);
                }
            } else if ("粘圆棒".equals(hasGone)) {
                wipStorageService.outStation(trayItem.getSectionNo(), "A", null);
            } else if ("综计WMS".equals(hasGone)) {
                wipStorageService.outStation(trayItem.getSectionNo(), "C", null);
            }
            if (autoReceive) {
                trayItem.setTrayId(turnstoreTray.getId());
            }
            turnstoreTrayItemService.saveOrUpdate(trayItem);
        }
    }

    @Override
    public TurnstoreTray findByTrayNo(String trayNo) {
        List<TurnstoreTray> turnstoreTrayList = dao.findByTrayNo(trayNo);
        if (null != turnstoreTrayList && !turnstoreTrayList.isEmpty()) {
            return turnstoreTrayList.get(0);
        }
        return null;
    }

    @ServiceLogs(description = "圆棒发起入库")
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result initiateReceipt(TurnstoreTrayDto turnstoreTrayDto, List<TurnstoreTrayItem> turnstoreTrayItemList, Boolean autoReceive) {
        Date date = new Date();
        turnstoreTrayDto.setOperationTime(date);
        TurnstoreTray turnstoreTray = fromDto(turnstoreTrayDto);
        //WMS传递对象
        YbToWmsReceiptDto ybToWmsReceiptDto = new YbToWmsReceiptDto();
        List<YbToWmsReceiptDataDto> ybToWmsReceiptDataDtos = new ArrayList<>();
        //查询是否处于当前站点
        for (TurnstoreTrayItem trayItem : turnstoreTrayItemList) {
            //重新匹配订单
            if (!"退料".equals(turnstoreTray.getHasGone())) {
                if (autoReceive) {
                    wipStorageService.selectWipStorage(trayItem.getSectionNo(), EnumValuesFactory.WipStorageCode.圆棒检验.getKey(), true);
                } else {
                    wipStorageService.selectWipStorage(trayItem.getSectionNo(), EnumValuesFactory.WipStorageCode.圆棒检验.getKey(), true, EnumValuesFactory.PlanProcessingOrderStatus.组托.getKey());
                }
                String orderNo = productionOrderService.matchOrder(trayItem.getSectionNo(), trayItem.getPlanMaterialCode(),
                        trayItem.getPlanOrderType(), trayItem.getOrderType(), trayItem.getPlanOrderNo(), trayItem.getCheckoutName());
                trayItem.setOrderNo(orderNo);
                inspectDataBaseService.updateOrderNoBySectionNo(trayItem.getSectionNo(), orderNo);
            }
            //组装传递对象
            if ("综计WMS".equals(turnstoreTray.getHasGone())) {
                if (null == trayItem.getOrderNo()) {
                    return ResultGenerator.fail(trayItem.getSectionNo() + "该晶段未匹配到订单号,请联系管理员处理");
                }
                //组装传递对象
                YbToWmsReceiptDataDto ybToWmsReceiptDataDto = assembleData(trayItem);
                ybToWmsReceiptDataDtos.add(ybToWmsReceiptDataDto);
            }
        }
        try {
            //根据去向调用不同接口
            if ("综计WMS".equals(turnstoreTray.getHasGone())) {
                //发送至WMS
                turnstoreTray.setIsToWms(1);
                turnstoreTray.setToWmsTime(new Date());
                turnstoreTray.setState(0);
                //调用接口
                String jsonString = JSON.toJSONString(ybToWmsReceiptDataDtos);
                ybToWmsReceiptDto.setZDATA(jsonString);
                String content = JSON.toJSONString(ybToWmsReceiptDto);
                String url = wmsUrl + "api/YC6MES/otherinteraction";
                String send = send(content, url);
                if (null != send && send.contains("\"ztype\":\"E\"")) {
                    return ResultGenerator.fail(send);
                }
            } else if ("方棒加工".equals(turnstoreTray.getHasGone()) || "粘圆棒".equals(turnstoreTray.getHasGone())) {
                TrayPostDto trayPostDto = new TrayPostDto();
                if (autoReceive) {
                    trayPostDto.setAutoReceive(true);
                    turnstoreTray.setConfirmTime(date);
                    turnstoreTray.setState(1);
                    turnstoreTray.setTime(new Date());
                    turnstoreTray.setConfirmUser("自动确认");
                    turnstoreTrayItemList.forEach(turnstoreTrayItem -> {
                        turnstoreTrayItem.setConfirmTime(date);
                        turnstoreTrayItem.setConfirmUser("自动确认");
                        turnstoreTrayItem.setHasGone("方棒加工");
                        turnstoreTrayItem.setTrayNo(turnstoreTray.getTrayNo());
                        turnstoreTrayItem.setState(1);
                        turnstoreTrayItem.setTime(new Date());
                    });
                } else {
                    turnstoreTray.setState(0);
                }
                trayPostDto.setTrayDto(turnstoreTrayDto);
                trayPostDto.setTrayItems(turnstoreTrayItemList);
                //发送至方棒
                Result<String> receive = fbFeignClients.receive(trayPostDto);
                if (receive.getCode() != ResultCode.SUCCESS.getCode()) {
                    return ResultGenerator.fail(receive.getMessage());
                }
                if (autoReceive) {
                    //确认接收上报gr
                    sapService.sendGr(turnstoreTrayItemList);
                }
            } else {
                //退料/修改状态并更新退料记录
                for (TurnstoreTrayItem trayItem : turnstoreTrayItemList) {
                    TurnstoreTrayItem turnstoreTrayItem = turnstoreTrayItemService.findBySectionNoAndState(trayItem.getSectionNo(), 1);
                    if (null != turnstoreTrayItem && "退料".equals(turnstoreTrayItem.getHasGone())) {
                        return ResultGenerator.fail("该晶段已发起退料，不能重复退料,所在托号为: " + turnstoreTrayItem.getTrayNo());
                    }
                    //修改订单状态
                    PlanProcessingOrder planProcessingOrder = planProcessingOrderService.findByCode(trayItem.getSectionNo());
                    if (null == planProcessingOrder) {
                        throw new BusinessException(trayItem.getSectionNo() + "工单号不存在");
                    }
                    planProcessingOrder.setStatus(EnumValuesFactory.PlanProcessingOrderStatus.已作废.getKey());
                    planProcessingOrderService.saveOrUpdate(planProcessingOrder);
                }
                //修改状态
                turnstoreTray.setState(1);
            }
//            if (!autoReceive) {
            saveOrUpdate(turnstoreTray);
            //更新详情数据
            updateItem(turnstoreTray, turnstoreTrayItemList, autoReceive);
//            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success();
    }

    //数据转换
    private YbToWmsReceiptDataDto assembleData(TurnstoreTrayItem trayItem) {
        YbToWmsReceiptDataDto ybToWmsData = new YbToWmsReceiptDataDto();
        ybToWmsData.setBoxCode(trayItem.getTrayNo());
        ybToWmsData.setNumber(trayItem.getOrderNum());
        ybToWmsData.setCrystalNo(trayItem.getSectionNo());
        //美科项目未用此方法
        ybToWmsData.setSerialNumber(trayItem.getSectionNo().substring(11, 14));
        ybToWmsData.setCrystalGroup(trayItem.getSectionCompose());
        ybToWmsData.setModel(trayItem.getConductiveType());
        ybToWmsData.setNorms(trayItem.getProductTypeSecond());
        ybToWmsData.setStorageLength(trayItem.getWareHouseLength());
        ybToWmsData.setTheoreticalWeight(trayItem.getTheoryWeight());
        ybToWmsData.setCrystalLength(trayItem.getActualLength());
        ybToWmsData.setActualWeight(trayItem.getActualWeight());
        ybToWmsData.setFineLengthReduction(trayItem.getFineCutLength());
        ybToWmsData.setAvalancheLine(trayItem.getCollapseLine());
        ybToWmsData.setFactory("1031");
        ybToWmsData.setLgort(trayItem.getStockPlace());
        ybToWmsData.setRemark(trayItem.getRemark());
        ybToWmsData.setCustomerType(trayItem.getCustomerType());
        ybToWmsData.setOrderNum(trayItem.getOrderNo());
        ybToWmsData.setBrokenEdgeSkin(trayItem.getEdgeBark());
        ybToWmsData.setOblique(trayItem.getIsBevel());
        ybToWmsData.setFineTotalLength(trayItem.getFineDiameter());
        ybToWmsData.setTorsion(trayItem.getDistortion());
        ybToWmsData.setRodLifeClass(trayItem.getLifeGrading());
        ybToWmsData.setProductNo(trayItem.getItemNo());
        ybToWmsData.setExceptions(trayItem.getErrorMsg());
        return ybToWmsData;
    }


    @Override
    public void updateTurnstoreTrayStateById(WmsToYbReceiveDto wmsToYbReceiveDto, TurnstoreTray turnstoreTray) {
        try {
            //更新主表
            saveOrUpdate(turnstoreTray);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateTrayItemState(WmsToYbReceiveDto wmsToYbReceiveDto, TurnstoreTray turnstoreTray, List<TurnstoreTrayItem> trayItemList) {
        //更新明细表
        ThreadManager.getThreadPollProxy().execute(() -> {
            try {
                updateTrayItemList(turnstoreTray, trayItemList);
            } catch (Exception e) {
                e.printStackTrace();
                //回滚表头信息
                turnstoreTray.setState(0);
                //todo 数据库字段只有50
                turnstoreTray.setRemark("失败原因：" + e.getMessage().substring(0, 40));
                saveOrUpdate(turnstoreTray);
            }
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Deprecated
    public void updateTrayState(WmsToYbReceiveDto receiveDto, TurnstoreTray turnstoreTray, List<TurnstoreTrayItem> trayItemList) {
        try {
            //更新信息
            turnstoreTray.setConfirmUser(receiveDto.getRejectionUser());
            turnstoreTray.setConfirmTime(receiveDto.getRejectionDate());
            //根据状态进行操作
            if (1 == receiveDto.getType()) {
                //确认接收
                turnstoreTray.setState(1);
            } else if (2 == receiveDto.getType()) {
                //拒收
                turnstoreTray.setState(3);
                turnstoreTray.setRemark(receiveDto.getRejectionReason());
            } else {
                //冲销==取消
                turnstoreTray.setState(4);
                if (null != receiveDto.getRejectionReason()) {
                    turnstoreTray.setRemark(receiveDto.getRejectionReason());
                } else {
                    turnstoreTray.setRemark("冲销");
                }
            }
            //更新列表
            updateTrayItemList(turnstoreTray, trayItemList);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void updateTrayItemList(TurnstoreTray turnstoreTray, List<TurnstoreTrayItem> trayItemList) {
        List<TurnstoreTrayItem> trayItemGrs = new ArrayList<>();
        for (TurnstoreTrayItem trayItem : trayItemList) {
            //解锁组托状态
            PlanProcessingOrder planProcessingOrder = planProcessingOrderService.findByCode(trayItem.getSectionNo());
            if (null == planProcessingOrder) {
                throw new BusinessException(trayItem.getSectionNo() + "工单号不存在");
            }
            if (1 == turnstoreTray.getState()) {
                //成功--执行进站操作
                wipStorageService.inStation(trayItem.getSectionNo(), null, false);
                //更新状态
                planProcessingOrder.setStatus(EnumValuesFactory.PlanProcessingOrderStatus.入库完成.getKey());
                planProcessingOrderService.saveOrUpdate(planProcessingOrder);
                trayItemGrs.add(trayItem);
            } else {
                //更新状态
                planProcessingOrder.setStatus(EnumValuesFactory.PlanProcessingOrderStatus.加工中.getKey());
                planProcessingOrderService.saveOrUpdate(planProcessingOrder);
                //拒收/冲销---执行退站操作
                wipStorageService.exitStation(trayItem.getSectionNo());
            }
            //将信息更新至明细
            trayItem.setState(turnstoreTray.getState());
            trayItem.setConfirmTime(turnstoreTray.getConfirmTime());
            trayItem.setConfirmUser(turnstoreTray.getConfirmUser());
            if (null != turnstoreTray.getRemark()) {
                trayItem.setReason(turnstoreTray.getRemark());
                trayItem.setRemark(turnstoreTray.getRemark());
            }
            turnstoreTrayItemService.saveOrUpdate(trayItem);
        }
        if (1 == turnstoreTray.getState()) {
            //确认接收上报gr
            sapService.sendGr(trayItemGrs);
        }
    }

    public TurnstoreTray fromDto(TurnstoreTrayDto dto) {
        modelMapper.getConfiguration().setFullTypeMatchingRequired(true);
        modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
        return modelMapper.map(dto, TurnstoreTray.class);
    }

    private String send(String data, String url) {
        HttpHeaders headers = new HttpHeaders();
        MediaType mediaType = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(mediaType);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        HttpEntity<String> httpEntity = new HttpEntity<>(data, headers);
        //使用exchange请求接口
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
        return exchange.getBody();
    }

}
