package com.shkj.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shkj.common.constant.RedisConstant;
import com.shkj.common.core.domain.Result;
import com.shkj.common.enums.HttpStatus;
import com.shkj.common.utils.DateUtils;
import com.shkj.common.utils.SecurityUtils;
import com.shkj.common.utils.StringUtils;
import com.shkj.plc.sdk.device.PLCReadAndWrite;
import com.shkj.plc.sdk.device.PLCUtil;
import com.shkj.plc.sdk.device.PlcOperate;
import com.shkj.system.service.ISysParameterService;
import com.shkj.wms.bo.*;
import com.shkj.wms.constants.ParameterConstants;
import com.shkj.wms.controller.third.BarcodeThirdController;
import com.shkj.wms.domain.*;
import com.shkj.wms.enums.TaskStatusEnum;
import com.shkj.wms.enums.TaskTypeEnum;
import com.shkj.wms.mapper.*;
import com.shkj.wms.plc.PlcInit;
import com.shkj.wms.service.*;
import com.shkj.wms.third.rcs.RCSUtil;
import com.shkj.wms.third.rcs.dto.RcsCreateTaskDto;
import com.shkj.wms.third.rcs.dto.RcsIdList;
import com.shkj.wms.third.rcs.enums.RCSTaskTypeEnum;
import com.shkj.wms.utils.JsonUtil;
import com.shkj.wms.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 任务管理Service业务层处理
 *
 * @author zjx
 * @date 2023-04-07
 */
@Slf4j
@Service
public class PutInOutStorageServiceImpl extends ServiceImpl<BasePointDeviceMapper,BasePointDevice > implements IPutInOutStorageService
{
    @Resource
    private BusinDataTaskMapper businDataTaskMapper;

    @Resource
    PlcInit plcInit;

    @Resource
    RedisTemplate redisTemplate;

    @Resource
    IBaseBarcodesInService iBaseBarcodesInService;

    @Resource
    private IBusinEnptyContainerServiceImpl iBusinEnptyContainerServiceImpl;

    @Resource
    IBusinDataTaskGoodsService iBusinDataTaskGoodsService;

    @Autowired
    private ISysParameterService sysParameterService;


    @Resource
    private  IBusinDataTaskService iBusinDataTaskService;

    @Resource
    IBaseDeriveService iBaseDeriveService;

    @Resource
    private  ISysStockService iSysStockService;

    @Resource
    private  IBusinBillheadService iBusinBillheadService;

    @Resource
    IBusinBillbodyService iBusinBillbodyService;

    @Autowired
    BaseLocationServiceImpl baseLocationService;

    @Autowired
    IBaseBarcodesOutService iBaseBarcodesOutService;

    @Autowired
    ISysStockDetailService iSysStockDetailService;

    @Autowired
    ISysParameterService iSysParameterService;
    @Resource
    IWcsPlcPropertyService iWcsPlcPropertyService;
    @Autowired
    private IBaseLocationService iBaseLocationService;
    @Resource
    IWcsPlcConnectService iWcsPlcConnectService;
    @Resource
    private BusinBillheadMapper businBillheadMapper;
    @Resource
    BasePointDeviceMapper basePointDeviceMapper;
    @Resource
    BarcodeThirdController barcodeThirdController;
    @Resource
    BaseLocationPlcMapper baseLocationPlcMapper;
    @Resource
    RCSUtil rcsUtil;
    @Resource
    BaseLocationMapper baseLocationMapper;

    @Resource
    BaseInventoryRatioService baseInventoryRatioService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Long>  saveBusinBillTaskData(MachineHandAddBo bo) {
        log.info("MachineHandAddBo："+JsonUtil.toJSONString(bo));
        String firstBarcode = bo.getFirstBarcode();
        String secondBarcode = bo.getSecondBarcode();
        String thirdBarcode = bo.getThirdBarcode();
        Long containerId = bo.getContainerId();
        Long plcIP = bo.getPlcIP();
//        Long containerId = (Long) redisTemplate.opsForValue().get(RedisConstant.redisContainer + bo.getContainerId());
        if (!firstBarcode.equals("EMPTY") || !firstBarcode.equals("EMPTY") || !firstBarcode.equals("EMPTY")) {
            BaseBarcodesIn barcodes_f =null;
            BaseBarcodesIn barcodes_s =null;
            BaseBarcodesIn barcodes_t =null;

            // 获取 plcconnect 数据
            WcsPlcConnect wcsPlcConnectStk = iWcsPlcConnectService.getById(plcIP);
            // 获取 PlcProperty 数据
            List<WcsPlcProperty> propertyList = iWcsPlcPropertyService.getWcsPlcPropertyByPlcId(wcsPlcConnectStk.getId());

            String oneAddress = null;
            String oneValueType = null;
            int oneTemp = 0;

            // 获取 机械手拿到保险杠数量
            for (WcsPlcProperty wcsPlcProperty : propertyList) {
                if (wcsPlcProperty.getPointType().equals("11")) {
                    oneAddress = wcsPlcProperty.getAddress();
                    oneValueType = wcsPlcProperty.getValueType();
                    //任务ID
                }
            }
            PlcOperate automation = plcInit.getPlcOperateByIp(wcsPlcConnectStk.getPlcIp());

            PLCUtil plcUtil = new PLCUtil();
            oneTemp = Integer.valueOf(plcUtil.readPlc(oneAddress,oneValueType,automation,0));

            List<BaseBarcodesIn> barcodesIns = new ArrayList<>();
            if (!firstBarcode.equals("ERROR")&&firstBarcode!=null&&!firstBarcode.isEmpty()) {
                barcodes_f = iBaseBarcodesInService.getBaseBarcodesByQrCode(firstBarcode);
                if (ObjectUtils.isNotEmpty(barcodes_f)){
                    barcodes_f.setInStatus("1");
                }
            }

            if (secondBarcode !=null &&!secondBarcode.equals("ERROR")&&!secondBarcode.isEmpty()) {
                barcodes_s = iBaseBarcodesInService.getBaseBarcodesByQrCode(secondBarcode);
                if (ObjectUtils.isNotEmpty(barcodes_s)){
                    barcodes_s.setInStatus("1");
                }
            }

            if ( thirdBarcode !=null &&!thirdBarcode.equals("ERROR")&&!thirdBarcode.isEmpty()) {
                barcodes_t = iBaseBarcodesInService.getBaseBarcodesByQrCode(thirdBarcode);
                if (ObjectUtils.isNotEmpty(barcodes_t)){
                    barcodes_t.setInStatus("1");
                }
            }

            //如果入库计划未有该条码信息则直接下达去平库任务
            if (ObjectUtils.isEmpty(barcodes_f) && ObjectUtils.isEmpty(barcodes_s) &&ObjectUtils.isEmpty(barcodes_t)){
                // 创建任务
                BusinDataTask task = new BusinDataTask();
                task.setTaskCode("T_" + DateUtils.dateTimeNow());
                task.setTaskPath("KW17");
                task.setTaskStatus(TaskStatusEnum.wait_put.getValue());
                //入库计划未有该条码信息设置任务类型为18
                task.setTaskType("2");
                task.setBatch(DateUtils.dateTimeNow("yyyy-MM-dd"));
                task.setIsDown(String.valueOf(RCSTaskTypeEnum.TO_B_AND_PUT1.getValue()));
                task.setContainerId(containerId);
                task.setPlcId(30L);
                task.setCreateTime(new Date());
                task.setUpdateTime(new Date());
                iBusinDataTaskService.insertBusinTask(task);
                Long taskId = task.getId();
                return Result.ok().data(taskId);
            }

            int count_f = 0;
            int count_s = 0;
            int count_t = 0;
            //需维修逻辑
            String isRepair_f ="0";
            String isRepair_s ="0";
            String isRepair_t ="0";
            //冲孔数据
            String isPunching_f="0";
            String isPunching_s="0";
            String isPunching_t="0";
            //冲孔结果数据
            String punchingResult_f="0";
            String punchingResult_s="0";
            String punchingResult_t="0";
            //前后杠数据
            String location_f="0";
            String location_s="0";
            String location_t="0";
            //是否分体数据
            String split_f="0";
            String split_s="0";
            String split_t="0";

            if(StringUtils.isNotEmpty(firstBarcode) && !firstBarcode.equals("ERROR")){
                count_f++;
            }
            if(StringUtils.isNotEmpty(secondBarcode) && !secondBarcode.equals("ERROR")){
                count_s++;
            }
            if(StringUtils.isNotEmpty(thirdBarcode) && !thirdBarcode.equals("ERROR")){
                count_t++;
            }

            if(barcodes_f !=null){
                isRepair_f = barcodes_f.getIsRepair();
                isPunching_f = barcodes_f.getIsPunching();
                location_f = barcodes_f.getLocation();
                split_f = barcodes_f.getIsSplit();
                punchingResult_f = barcodes_f.getPunchingResult();
                barcodesIns.add(barcodes_f);
            }

            if(barcodes_s !=null){
                isRepair_s = barcodes_s.getIsRepair();
                isPunching_s = barcodes_s.getIsPunching();
                location_s = barcodes_s.getLocation();
                split_s = barcodes_s.getIsSplit();
                punchingResult_s = barcodes_s.getPunchingResult();
                barcodesIns.add(barcodes_s);
            }

            if(barcodes_t !=null){
                isRepair_t = barcodes_t.getIsRepair();
                isPunching_t = barcodes_t.getIsPunching();
                location_t = barcodes_t.getLocation();
                split_t = barcodes_t.getIsSplit();
                punchingResult_t = barcodes_t.getPunchingResult();
                barcodesIns.add(barcodes_t);
            }

            // 获取当前保险杠是什么车型
            String model = barcodesIns.get(0).getVehicheModel();
            // 获取入库比例数据进行验证应该入立库还是平库
            List<BaseInventoryRatio> baseInventoryRatioList = baseInventoryRatioService.getInfoByvehicheModel(model);

            //获取下料点点位
            String taskCode = "T_" + DateUtils.dateTimeNow();
            String transId = com.shkj.common.utils.uuid.UUID.randomUUID().toString();
            BusinTaskAddBo businTaskAddBo =new BusinTaskAddBo();
            businTaskAddBo.setTaskCode(taskCode);
            businTaskAddBo.setPlcId(plcIP);
            businTaskAddBo.setTaskStatus(TaskStatusEnum.wait_put.getValue());
            businTaskAddBo.setCreateTime(DateUtils.getNowDate());
            businTaskAddBo.setBatch(DateUtils.getDate());
            businTaskAddBo.setTransId(transId);
            businTaskAddBo.setContainerId(containerId);
            businTaskAddBo.setTaskPath(bo.getPointNo());
            //正常业务，生成入库单及入库任务
            businTaskAddBo.setTaskType(bo.getTaskType());

            //扫码异常 生成任务单，统一调度内容呼叫AGV
            if("ERROR".equals(firstBarcode) || "ERROR".equals(secondBarcode) || "ERROR".equals(thirdBarcode)){
                businTaskAddBo.setTaskType(TaskTypeEnum.scancode_err.getValue());
                Map<String,String> map = checkWarehouseType(baseInventoryRatioList,TaskTypeEnum.scancode_err.getValue());
                if(ObjectUtils.isNotEmpty(map)){
                    businTaskAddBo.setWarehouseType(map.get("warehouseType"));
                }
            }else  if ("1".equals(isRepair_f) || "1".equals(isRepair_s) || "1".equals(isRepair_t)) {
                businTaskAddBo.setTaskType(TaskTypeEnum.upkeep_err.getValue());
                Map<String,String> map = checkWarehouseType(baseInventoryRatioList,TaskTypeEnum.upkeep_err.getValue());
                if(ObjectUtils.isNotEmpty(map)){
                    businTaskAddBo.setWarehouseType(map.get("warehouseType"));
                }
            }else if(("1".equals(isPunching_f)&& "0".equals(punchingResult_f))
                    || ("1".equals(isPunching_s)&& "0".equals(punchingResult_s))
                    || ("1".equals(isPunching_t)&& "0".equals(punchingResult_t))){
                businTaskAddBo.setTaskType(TaskTypeEnum.putin_punching.getValue());
                Map<String,String> map = checkWarehouseType(baseInventoryRatioList,TaskTypeEnum.putin_punching.getValue());
                if(ObjectUtils.isNotEmpty(map)){
                    businTaskAddBo.setWarehouseType(map.get("warehouseType"));
                    businTaskAddBo.setIsReturn(map.get("isReturn"));
                    if(map.get("isReturn").equals("1")){
                        businTaskAddBo.setTaskType(bo.getTaskType());
                    }
                }
            }
            else {
                //判断只有一个杠的情况
                if(oneTemp == 1) {
                    // 只有一个杠判断前杠不分体，后杠不分体则进存货区 反之则进待补货区
                    if ((count_f == 1 && (("0".equals(location_f) && "1".equals(split_f)) || ("1".equals(location_f) && "1".equals(split_f))))
                            || (count_s == 1 && (("0".equals(location_s) && "1".equals(split_s)) || ("1".equals(location_s) && "1".equals(split_s))))
                            || (count_t == 1 && (("0".equals(location_t) && "1".equals(split_t)) || ("1".equals(location_t) && "1".equals(split_t))))){
                        //正常业务，生成入库单及入库任务
                        businTaskAddBo.setTaskType(bo.getTaskType());
                    }else if (count_f < 1 && count_s < 1 && count_t < 1){
                        businTaskAddBo.setTaskType(TaskTypeEnum.scancode_err.getValue());
                        log.info("出现只抓了一个杠，而且没有条码的情况；进入异常");
                    }else{
                        //暂时注释，不进入待补货区 正常入库
                        //businTaskAddBo.setTaskType(TaskTypeEnum.replenished_in.getValue());
                        businTaskAddBo.setTaskType(bo.getTaskType());
                    }
                }else if(oneTemp == 2) {
                    if((count_f == 1 && count_s == 1) || (count_f == 1 && count_t == 1) || (count_s == 1 && count_t == 1)){
                        businTaskAddBo.setTaskType(bo.getTaskType());
                        //暂时注释，不进入待补货区 正常入库
//                        businTaskAddBo.setTaskType(TaskTypeEnum.replenished_in.getValue());
                    }else{
                        businTaskAddBo.setTaskType(TaskTypeEnum.scancode_err.getValue());
                        log.info("出现只抓了两个杠，而且没有条码的情况；进入异常");
                    }
                }else if(oneTemp == 3){
                    if(count_f == 1 && count_s == 1 && count_t == 1){
                        businTaskAddBo.setTaskType(bo.getTaskType());
                    }else{
                        businTaskAddBo.setTaskType(TaskTypeEnum.scancode_err.getValue());
                        log.info("出现只抓了三个杠，而且没有条码的情况；进入异常");
                    }
                }
                Map<String,String> map = checkWarehouseType(baseInventoryRatioList,TaskTypeEnum.normal_in.getValue());
                if(ObjectUtils.isNotEmpty(map)){
                    businTaskAddBo.setWarehouseType(map.get("warehouseType"));
                }
            }
            //新增任务
            BusinDataTask businDataTask = BeanUtil.toBean(businTaskAddBo, BusinDataTask.class);
            iBusinDataTaskService.insertBusinDataTask(businDataTask);
            Long taskId=businDataTask.getId();
            //新增任务物料明细
            List<BusinDataTaskGoods> goods = new ArrayList<>();
            if (firstBarcode != "" && !firstBarcode.isEmpty()){
                BusinDataTaskGoods firstGoods = new BusinDataTaskGoods();
                firstGoods.setQrCode(firstBarcode);
                firstGoods.setBranchId(SecurityUtils.getCurrentBranchId());
                firstGoods.setTaskCode(taskId);
                firstGoods.setCreateTime(DateUtils.getNowDate());
                if (!"ERROR".equals(firstBarcode) && ObjectUtils.isNotEmpty(barcodes_f)){
                    firstGoods.setGoodsNo(barcodes_f.getGoodsNo());
                    firstGoods.setIsPunching(barcodes_f.getIsPunching());
                    firstGoods.setIsRepair(barcodes_f.getIsRepair());
                }
                goods.add(firstGoods);
            }

            if (secondBarcode != null && !secondBarcode.isEmpty()){
                BusinDataTaskGoods secondGoods = new BusinDataTaskGoods();
                secondGoods.setQrCode(secondBarcode);
                secondGoods.setBranchId(SecurityUtils.getCurrentBranchId());
                secondGoods.setTaskCode(taskId);
                secondGoods.setCreateTime(DateUtils.getNowDate());
                if (!"ERROR".equals(secondBarcode) && ObjectUtils.isNotEmpty(barcodes_s)){
                    secondGoods.setGoodsNo(barcodes_s.getGoodsNo());
                    secondGoods.setIsPunching(barcodes_s.getIsPunching());
                    secondGoods.setIsRepair(barcodes_s.getIsRepair());
                }
                goods.add(secondGoods);
            }

            if (thirdBarcode != null && !thirdBarcode.isEmpty()){
                BusinDataTaskGoods thirdGoods = new BusinDataTaskGoods();
                thirdGoods.setQrCode(thirdBarcode);
                thirdGoods.setBranchId(SecurityUtils.getCurrentBranchId());
                thirdGoods.setTaskCode(taskId);
                thirdGoods.setCreateTime(DateUtils.getNowDate());
                if (!"ERROR".equals(thirdBarcode) && ObjectUtils.isNotEmpty(barcodes_t)) {
                    thirdGoods.setGoodsNo(barcodes_t.getGoodsNo());
                    thirdGoods.setIsPunching(barcodes_t.getIsPunching());
                    thirdGoods.setIsRepair(barcodes_t.getIsRepair());
                }
                goods.add(thirdGoods);
            }
            //新增物料明细
            boolean b = iBusinDataTaskGoodsService.saveOrUpdateBatch(goods);
            //更新条码表的入库状态
            return iBaseBarcodesInService.saveOrUpdateBatch(barcodesIns)?Result.ok().data(taskId):Result.err();
        }
        else {
            //入库接驳口是否需要空治具
            BusinDataTaskVo dataTaskVo = null;

            boolean stuat=false;
            String toPpoint = null;
            String agvType = null;
            Long plcid=null;
            String tunnelId=null;
            Long stkPlcId =0L;
            Long dspPlcId =0L;
            BaseLocationVo locationVo=null;
            //防止进入保养后在进入入库
            boolean stuats=true;

            //治具是否需要保养
            BasePointDeviceVo pointDeviceVo = iBusinEnptyContainerServiceImpl.checkContailnerUpkeep(containerId);

            if (pointDeviceVo != null){
                toPpoint = pointDeviceVo.getPointNo();
                agvType= String.valueOf(RCSTaskTypeEnum.A_TO_B_HAND_PUT.getValue());
                stuats=false;
            }
            if (stuats){
                //是否有呼叫空治具的任务
                dataTaskVo = iBusinEnptyContainerServiceImpl.checkTaskData();
            }

            if (dataTaskVo !=null){
                agvType= String.valueOf(RCSTaskTypeEnum.A_TO_B_NO_PUT.getValue());
                toPpoint = dataTaskVo.getTaskPath();
                stuat=true;
            }else if (stuats){
                Map map = iBusinEnptyContainerServiceImpl.checkWareForEmptycon();
                if(ObjectUtils.isEmpty(map)){
                    return Result.err().msg("暂无空治具存放区域");
                }
                pointDeviceVo = BeanUtil.toBean(map.get("basePointDeviceVo"),BasePointDeviceVo.class);
                locationVo = BeanUtil.toBean(map.get("locationVo"),BaseLocationVo.class);
                agvType= String.valueOf(RCSTaskTypeEnum.A_TO_B_HAND_PUT.getValue());
                toPpoint = pointDeviceVo.getPointNo();
                dspPlcId=Long.valueOf(sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.LK_plc_id));

                //获取巷道对应的堆垛机信息
                BasePointDeviceQueryBo pointQueryBo = new BasePointDeviceQueryBo();
                pointQueryBo.setDevType("1");
                pointQueryBo.setTunnel(pointDeviceVo.getTunnel());
                BaseDevicePlcVo baseDevicePlcVo = baseLocationPlcMapper.selectBaseDevicePlc(pointQueryBo);
                stkPlcId = baseDevicePlcVo.getPlcId();
                tunnelId = baseDevicePlcVo.getTunnel();

            }

            //创建任务
            BusinDataTask businDataTask = new BusinDataTask();
            businDataTask.setTaskPath(toPpoint);
            String taskstatus=TaskStatusEnum.wait_put.getValue();
            businDataTask.setTaskStatus(taskstatus);
            String Type=TaskTypeEnum.empty_in.getValue();
            businDataTask.setTaskType(Type);
            businDataTask.setIsDown(agvType);
            businDataTask.setContainerId(containerId);
            if (plcid!=null&&plcid!=0){
                businDataTask.setPlcId(plcid);
            }
            businDataTask.setDpsNoOne(dspPlcId);
            businDataTask.setDpsNoTwo(stkPlcId);
            businDataTask.setTunnel(tunnelId);
            businDataTask.setBatch(DateUtils.getDate());
            if (stuat){
                businDataTask.setRemark(String.valueOf(dataTaskVo.getId()));
            }

            if (locationVo!=null){
                businDataTask.setToColumn(locationVo.getLocationColumn());
                businDataTask.setToLayer(locationVo.getLayer());
                businDataTask.setToRow(locationVo.getLocationRow());
                businDataTask.setLocationId(locationVo.getId());

            }

            int  agvTaskType = Integer.valueOf(agvType);
            RcsCreateTaskDto dto = new RcsCreateTaskDto();
            Map<String,String> snPointMap = new HashMap<>();
            List<RcsIdList> idList = new ArrayList<>();

            dto.setMapId(1);
            dto.setTaskType(agvTaskType);

            RcsIdList startId = new RcsIdList();
            RcsIdList endId = new RcsIdList();
            RcsIdList endId1 = new RcsIdList();

            String tepairGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.putout_point);
            BasePointDeviceQueryBo pointQueryBoup = new BasePointDeviceQueryBo();
            pointQueryBoup.setGroupNo(tepairGroup);
            BasePointDeviceVo pointDevice = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBoup);

            startId.setId(bo.getPointNo());
            idList.add(startId);
            endId.setId(pointDevice.getHandshakePoint());
            idList.add(endId);
            endId1.setId(toPpoint);
            idList.add(endId1);

            snPointMap.put("1",bo.getPointNo());
            snPointMap.put("2",pointDevice.getHandshakePoint());
            snPointMap.put("3",toPpoint);

            dto.setTargets(idList);

            businDataTask.setPoints(JsonUtil.toJSONString(snPointMap));
            businDataTask.setWarehouseType("1");

            //创建任务
            iBusinDataTaskService.insertBusinTask(businDataTask);
            Long taskId = businDataTask.getId();
            dto.setTaskId(taskId.toString());
            //呼叫AGV
            Result<Boolean> booleanResult =  rcsUtil.rcsCreateTask(dto);

            if (booleanResult.getCode()== HttpStatus.SUCCESS.getCode()){

                //根据plcId获取plc信息
                WcsPlcConnect wcsplc = BeanUtil.toBean(redisTemplate.opsForValue().get(RedisConstant.redisPlcConnect + 30L),WcsPlcConnect.class);
                List<WcsPlcProperty> propertyList = iWcsPlcPropertyService.getWcsPlcPropertyByPlcId(30L);
                String writeTaskId = "";
                String valueType = "";
                for (WcsPlcProperty wcsPlcProperty : propertyList) {
                    //AGV取走完成
                    if (wcsPlcProperty.getPointType().equals("6")) {
                        writeTaskId = wcsPlcProperty.getAddress();
                        valueType = wcsPlcProperty.getValueType();
                    }
                }
                PlcOperate plcOperate =plcInit.getPlcOperateByIp(wcsplc.getPlcIp());
                PLCReadAndWrite plcReadAndWrite = new PLCReadAndWrite();

                Map<String, Long> writeMap = new HashMap<>(1);
                writeMap.put(valueType, taskId);
                Map<String, Object> allMap = new HashMap<>(1);
                allMap.put(writeTaskId, writeMap);
                plcReadAndWrite.execWrite(plcOperate, JsonUtil.toJSONString(allMap));

                businDataTask.setTaskStatus(TaskStatusEnum.wait_callback.getValue());
                iBusinDataTaskService.updateById(businDataTask);
                //更新货位状态为已分配
                if (locationVo!=null){
                    BaseLocation baseLocation = BeanUtil.toBean(locationVo,BaseLocation.class);
                    baseLocation.setLocationStatus("4");
                    baseLocationMapper.updateById(baseLocation);
                }
                //有呼叫空治具的任务时添加任务后更改原任务状态
                if (stuat) {
                    BusinDataTask byId = iBusinDataTaskService.getById(dataTaskVo.getId());
                    byId.setTaskStatus("3");
                    byId.setRemark("已取消，已被任务ID为："+taskId+" 替代！");
                    iBusinDataTaskService.updateById(byId);
                    businDataTask.setRemark(String.valueOf(dataTaskVo.getId()));
                }
            }
            else{
                businDataTask.setExceptionMsg(booleanResult.getMsg());
                iBusinDataTaskService.updateById(businDataTask);

            }
            return Result.ok().data(taskId);
        }
    }


    public Map<String,String> checkWarehouseType(List<BaseInventoryRatio> baseInventoryRatioList,String taskType){
        Map<String,String> map = new HashMap<>();
        for (BaseInventoryRatio item: baseInventoryRatioList) {
            String vehicheModel = item.getVehicheModel();
            String bumperShape = item.getBumperShape();
            Integer punching = item.getPunching();
            Integer proportion = item.getProportion();
            // 扫码异常 异常杠
            if(taskType.equals(TaskTypeEnum.scancode_err.getValue())){
                if("err".equals(bumperShape)){
                    map.put("warehouseType","2");
                    return map;
                }
            }
            // 维修异常 异常杠
            if(taskType.equals(TaskTypeEnum.upkeep_err.getValue())){
                if("err".equals(bumperShape)){
                    if(proportion.equals(100)){
                        map.put("warehouseType","2");
                        return map;
                    }
                }
            }
            // 冲孔    正常杠
            String putinPunching = TaskTypeEnum.putin_punching.getValue();
            if(taskType.equals(putinPunching)){
                if("yes".equals(bumperShape)){
                    if(proportion.equals(100)){
                        map.put("isReturn","2");
                        map.put("warehouseType","2");
                        return map;
                    }else if(proportion.equals(0)){
                        map.put("isReturn","2");
                        map.put("warehouseType","1");
                        return map;
                    }
                    else{
                        // 平库比例
                        Integer proportionPing = proportion/10;
                        // 立库比例
                        Integer proportionLi = (100-proportion)/10;
                        if(proportionPing.equals(1)){
                            proportionPing = 1;
                            proportionLi = 9;
                        }
                        if(proportionPing.equals(2)){
                            proportionPing = 1;
                            proportionLi = 4;
                        }
                        if(proportionPing.equals(3)){
                            proportionPing = 1;
                            proportionLi = 2;
                        }
                        if(proportionPing.equals(4)){
                            proportionPing = 2;
                            proportionLi = 3;
                        }
                        if(proportionPing.equals(5)){
                            proportionPing = 1;
                            proportionLi = 1;
                        }
                        if(proportionPing.equals(6)){
                            proportionPing = 3;
                            proportionLi = 2;
                        }
                        if(proportionPing.equals(7)){
                            proportionPing = 2;
                            proportionLi = 1;
                        }
                        if(proportionPing.equals(8)){
                            proportionPing = 4;
                            proportionLi = 1;
                        }
                        if(proportionPing.equals(9)){
                            proportionPing = 9;
                            proportionLi = 1;
                        }

                        // 初始化立库、平库入库数量
                        if(ObjectUtils.isEmpty(redisTemplate.opsForValue().get(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_li))){
                            redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_li,0);
                        }
                        if(ObjectUtils.isEmpty(redisTemplate.opsForValue().get(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_ping))){
                            redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_ping,0);
                        }

                        if(punching.equals(0)){
                            map.put("isReturn","1");
                        }else if(punching.equals(1)){
                            map.put("isReturn","2");
                        }

                        // 验证 入立库还是平库 并累计入库数量
                        // 获取立库平库入库数量
                        Integer storehouseLi = Integer.parseInt(redisTemplate.opsForValue().get(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_li).toString());
                        Integer storehousePing = Integer.parseInt(redisTemplate.opsForValue().get(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_ping).toString());

                        if(storehouseLi.equals(0) && storehousePing.equals(0)){
                            redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_li,storehouseLi+1);
                            map.put("warehouseType","1");
                            return map;
                        }

                        if(storehousePing.equals(0)){
                            if(storehouseLi.equals(proportionLi)){
                                redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_li,0);
                                redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_ping,storehousePing+1);
                                map.put("warehouseType","2");
                            }else{
                                redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_li,storehouseLi+1);
                                map.put("warehouseType","1");
                            }
                            return map;
                        }

                        if(storehouseLi.equals(0)){
                            if(storehousePing.equals(proportionPing)){
                                redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_ping,0);
                                redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_li,storehouseLi+1);
                                map.put("warehouseType","1");
                            }else{
                                redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_ping,storehousePing+1);
                                map.put("warehouseType","2");
                            }
                            return map;
                        }
                    }
                }
            }
            // 不冲孔  正常杠
            String normalIn = TaskTypeEnum.normal_in.getValue();
            if(taskType.equals(normalIn)){
                if("no".equals(bumperShape)){
                    if(proportion.equals(100)){
                        map.put("warehouseType","2");
                        return map;
                    }else if(proportion.equals(0)){
                        map.put("isReturn","1");
                        map.put("warehouseType","1");
                        return map;
                    }else{
                        // 平库比例
                        Integer proportionPing = proportion/10;
                        // 立库比例
                        Integer proportionLi = (100-proportion)/10;
                        if(proportionPing.equals(1)){
                            proportionPing = 1;
                            proportionLi = 9;
                        }
                        if(proportionPing.equals(2)){
                            proportionPing = 1;
                            proportionLi = 4;
                        }
                        if(proportionPing.equals(3)){
                            proportionPing = 1;
                            proportionLi = 2;
                        }
                        if(proportionPing.equals(4)){
                            proportionPing = 2;
                            proportionLi = 3;
                        }
                        if(proportionPing.equals(5)){
                            proportionPing = 1;
                            proportionLi = 1;
                        }
                        if(proportionPing.equals(6)){
                            proportionPing = 3;
                            proportionLi = 2;
                        }
                        if(proportionPing.equals(7)){
                            proportionPing = 2;
                            proportionLi = 1;
                        }
                        if(proportionPing.equals(8)){
                            proportionPing = 4;
                            proportionLi = 1;
                        }
                        if(proportionPing.equals(9)){
                            proportionPing = 9;
                            proportionLi = 1;
                        }

                        // 初始化立库、平库入库数量
                        if(ObjectUtils.isEmpty(redisTemplate.opsForValue().get(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_li))){
                            redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_li,0);
                        }
                        if(ObjectUtils.isEmpty(redisTemplate.opsForValue().get(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_ping))){
                            redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_ping,0);
                        }
                        // 验证 入立库还是平库 并累计入库数量
                        // 获取立库平库入库数量
                        Integer storehouseLi = Integer.parseInt(redisTemplate.opsForValue().get(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_li).toString());
                        Integer storehousePing = Integer.parseInt(redisTemplate.opsForValue().get(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_ping).toString());

                        if(storehouseLi.equals(0) && storehousePing.equals(0)){
                            redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_li,storehouseLi+1);
                            map.put("warehouseType","1");
                            return map;
                        }

                        if(storehousePing.equals(0)){
                            if(storehouseLi.equals(proportionLi)){
                                redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_li,0);
                                redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_ping,storehousePing+1);
                                map.put("warehouseType","2");
                            }else{
                                redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_li,storehouseLi+1);
                                map.put("warehouseType","1");
                            }
                            return map;
                        }

                        if(storehouseLi.equals(0)){
                            if(storehousePing.equals(proportionPing)){
                                redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_ping,0);
                                redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_li,storehouseLi+1);
                                map.put("warehouseType","1");
                            }else{
                                redisTemplate.opsForValue().set(vehicheModel+"_"+putinPunching+"_"+RedisConstant.storehouse_ping,storehousePing+1);
                                map.put("warehouseType","2");
                            }
                            return map;
                        }
                    }
                }
            }
        }
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Long>  saveBusinBillTaskData(MachineHandAddBo bo,String type) {
        String firstBarcode = bo.getFirstBarcode();
        String secondBarcode = bo.getSecondBarcode();
        String thirdBarcode = bo.getThirdBarcode();
//        Long containerId = (Long) redisTemplate.opsForValue().get(RedisConstant.redisContainer + bo.getContainerId());
        Long containerId = bo.getContainerId();
        Long plcIP = bo.getPlcIP();
        BaseBarcodesIn barcodes_f =null;
        BaseBarcodesIn barcodes_s =null;
        BaseBarcodesIn barcodes_t =null;
        int count = 0;
        int count_f = 0;
        int count_s = 0;
        int count_t = 0;

        if(StringUtils.isNotEmpty(firstBarcode) && !firstBarcode.equals("ERROR")){
            count_f++;
            count++;
        }else if(StringUtils.isNotEmpty(secondBarcode) && !firstBarcode.equals("ERROR")){
            count_s++;
            count++;
        }else if(StringUtils.isNotEmpty(thirdBarcode) && !firstBarcode.equals("ERROR")){
            count_t++;
            count++;
        }

        List<BaseBarcodesIn> barcodesIns = new ArrayList<>();
        if (!firstBarcode.equals("ERROR")&&firstBarcode!=null&&!firstBarcode.isEmpty()) {
            barcodes_f = iBaseBarcodesInService.getBaseBarcodesByQrCode(firstBarcode);
            barcodes_f.setInStatus("1");
        }

        if (secondBarcode !=null && !secondBarcode.equals("ERROR")&&!secondBarcode.isEmpty()) {
            barcodes_s = iBaseBarcodesInService.getBaseBarcodesByQrCode(secondBarcode);
            barcodes_s.setInStatus("1");
        }

        if ( thirdBarcode !=null && !thirdBarcode.equals("ERROR")&&!thirdBarcode.isEmpty()) {
            barcodes_t = iBaseBarcodesInService.getBaseBarcodesByQrCode(thirdBarcode);
            barcodes_t.setInStatus("1");
        }

        //需维修逻辑
        String isRepair_f ="0";
        String isRepair_s ="0";
        String isRepair_t ="0";
        //冲孔数据
        String isPunching_f="0";
        String isPunching_s="0";
        String isPunching_t="0";

        //冲孔结果数据
        String punchingResult_f="0";
        String punchingResult_s="0";
        String punchingResult_t="0";

        //前后杠数据
        String location_f="0";
        String location_s="0";
        String location_t="0";

        //是否分体数据
        String split_f="0";
        String split_s="0";
        String split_t="0";

        if(barcodes_f !=null){
            isRepair_f = barcodes_f.getIsRepair();
            isPunching_f = barcodes_f.getIsPunching();
            punchingResult_f = barcodes_f.getPunchingResult();
            location_f = barcodes_f.getLocation();
            split_f = barcodes_f.getIsSplit();
            barcodesIns.add(barcodes_f);
        }

        if(barcodes_s !=null){
            isRepair_s = barcodes_s.getIsRepair();
            isPunching_s = barcodes_s.getIsPunching();
            punchingResult_s = barcodes_s.getPunchingResult();
            location_s = barcodes_s.getLocation();
            split_s = barcodes_s.getIsSplit();
            barcodesIns.add(barcodes_s);
        }

        if(barcodes_t !=null){
            isRepair_t = barcodes_t.getIsRepair();
            isPunching_t = barcodes_t.getIsPunching();
            punchingResult_t = barcodes_t.getPunchingResult();
            location_t = barcodes_t.getLocation();
            split_t = barcodes_t.getIsSplit();
            barcodesIns.add(barcodes_t);
        }
        //获取下料点点位
        String taskCode = "T_" + DateUtils.dateTimeNow();
        String transId = com.shkj.common.utils.uuid.UUID.randomUUID().toString();
        BusinTaskAddBo businTaskAddBo =new BusinTaskAddBo();
        businTaskAddBo.setTaskCode(taskCode);
        businTaskAddBo.setPlcId(plcIP);
        businTaskAddBo.setTaskStatus(TaskStatusEnum.wait_put.getValue());
        businTaskAddBo.setCreateTime(DateUtils.getNowDate());
        businTaskAddBo.setBatch(DateUtils.getDate());
        businTaskAddBo.setTransId(transId);
        businTaskAddBo.setContainerId(containerId);
        businTaskAddBo.setTaskPath(bo.getPointNo());

        //扫码异常 生成任务单，统一调度内容呼叫AGV
        if("ERROR".equals(firstBarcode) || "ERROR".equals(secondBarcode) || "ERROR".equals(thirdBarcode)||"0".equals(String.valueOf(containerId))){
            businTaskAddBo.setTaskType(TaskTypeEnum.scancode_err.getValue());
        }else  if ("1".equals(isRepair_f) || "1".equals(isRepair_s) || "1".equals(isRepair_t)) {
            businTaskAddBo.setTaskType(TaskTypeEnum.upkeep_err.getValue());
        }else if(("1".equals(isPunching_f)&& "0".equals(punchingResult_f))
                 || ("1".equals(isPunching_s)&& "0".equals(punchingResult_s))
                || ("1".equals(isPunching_t)&& "0".equals(punchingResult_t))){
            businTaskAddBo.setTaskType(TaskTypeEnum.putin_punching.getValue());
        }else {
            //判断只有一个杠的情况
            if(count == 1) {
                // 只有一个杠判断前杠不分体，后杠不分体则进存货区 反之则进待补货区
                if ((count_f == 1 && (("0".equals(location_f) && "1".equals(split_f)) || ("1".equals(location_f) && "1".equals(split_f))))
                        || (count_s == 1 && (("0".equals(location_s) && "1".equals(split_s)) || ("1".equals(location_s) && "1".equals(split_s))))
                        || (count_t == 1 && (("0".equals(location_t) && "1".equals(split_t)) || ("1".equals(location_t) && "1".equals(split_t))))){
                    //正常业务，生成入库单及入库任务
                    businTaskAddBo.setTaskType(bo.getTaskType());
                }else{
                    //暂时注释，不进入待补货区 正常入库
                    //businTaskAddBo.setTaskType(TaskTypeEnum.replenished_in.getValue());
                    businTaskAddBo.setTaskType(bo.getTaskType());
                }
            }else if(count == 2) {
                //暂时注释，不进入待补货区 正常入库
                //businTaskAddBo.setTaskType(TaskTypeEnum.replenished_in.getValue());
                businTaskAddBo.setTaskType(bo.getTaskType());
            }else if(count == 3){
                businTaskAddBo.setTaskType(bo.getTaskType());
            }



            //正常业务，生成入库单及入库任务
//            businTaskAddBo.setTaskType(bo.getTaskType());
        }
        //新增任务
        BusinDataTask businDataTask = BeanUtil.toBean(businTaskAddBo, BusinDataTask.class);
        iBusinDataTaskService.insertBusinDataTask(businDataTask);
        Long taskId=businDataTask.getId();
        //新增任务物料明细
        List<BusinDataTaskGoods> goods = new ArrayList<>();
        if (firstBarcode != "" && !firstBarcode.isEmpty()){
            BusinDataTaskGoods firstGoods = new BusinDataTaskGoods();
            firstGoods.setQrCode(firstBarcode);
            firstGoods.setBranchId(SecurityUtils.getCurrentBranchId());
            firstGoods.setTaskCode(taskId);
            firstGoods.setCreateTime(DateUtils.getNowDate());
            if (!"ERROR".equals(firstBarcode)){
                firstGoods.setGoodsNo(barcodes_f.getGoodsNo());
                firstGoods.setIsPunching(barcodes_f.getIsPunching());
                firstGoods.setIsRepair(barcodes_f.getIsRepair());
            }
            goods.add(firstGoods);
        }

        if (secondBarcode != null && !secondBarcode.isEmpty()){
            BusinDataTaskGoods secondGoods = new BusinDataTaskGoods();
            secondGoods.setQrCode(secondBarcode);
            secondGoods.setBranchId(SecurityUtils.getCurrentBranchId());
            secondGoods.setTaskCode(taskId);
            secondGoods.setCreateTime(DateUtils.getNowDate());
            if (!"ERROR".equals(secondBarcode)){
                secondGoods.setGoodsNo(barcodes_s.getGoodsNo());
                secondGoods.setIsPunching(barcodes_s.getIsPunching());
                secondGoods.setIsRepair(barcodes_s.getIsRepair());
            }
            goods.add(secondGoods);
        }

        if (thirdBarcode != null && !thirdBarcode.isEmpty()){
            BusinDataTaskGoods thirdGoods = new BusinDataTaskGoods();
            thirdGoods.setQrCode(thirdBarcode);
            thirdGoods.setBranchId(SecurityUtils.getCurrentBranchId());
            thirdGoods.setTaskCode(taskId);
            thirdGoods.setCreateTime(DateUtils.getNowDate());
            if (!"ERROR".equals(thirdBarcode)) {
                thirdGoods.setGoodsNo(barcodes_t.getGoodsNo());
                thirdGoods.setIsPunching(barcodes_t.getIsPunching());
                thirdGoods.setIsRepair(barcodes_t.getIsRepair());
            }
            goods.add(thirdGoods);
        }
        //新增物料明细
        boolean b = iBusinDataTaskGoodsService.saveOrUpdateBatch(goods);
        //更新条码表的入库状态
        boolean aiFan = iBaseBarcodesInService.saveOrUpdateBatch(barcodesIns);
        if(aiFan){

            List<String> a = goods.stream().map(e -> e.getQrCode()).collect(Collectors.toList());
            String[] c = a.toArray(new String[a.size()]);
            Map<String,Object> m = new HashMap<>();
            m.put("qrCodes",c);
            new Thread(() -> {
                try {
                    Result result = barcodeThirdController.rcsSyncNum(m);
                    if(!result.getResult()){
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        barcodeThirdController.rcsSyncNum(m);
                    }
                } catch (Exception s) {
                    barcodeThirdController.rcsSyncNum(m);
                }
            }).start();
        }

        return aiFan ? Result.ok().data(taskId):Result.err();


    }

    @Override
    public Result<Boolean> productDeposit(Long taskId) {
        BusinBillHeadBodyQueryBo bodyQueryBo =new BusinBillHeadBodyQueryBo();
        bodyQueryBo.setTaskId(taskId);

        BusinDataTask businDataTask = iBusinDataTaskService.getById(taskId);
        //获取要入库的物料信息
        List<BusinBillHeadbodyInVo> bodyInOutDatas = iBusinBillheadService.getBillHeadBodyInOutData(bodyQueryBo);
        if(businDataTask.getTaskType().equals(TaskTypeEnum.emptyCon.getValue()) || businDataTask.getTaskType().equals(TaskTypeEnum.empty_in.getValue())){
            //改货位状态
            //获取货位
//            BaseLocation baseLocation = iBaseLocationService.getOne(new LambdaQueryWrapper<BaseLocation>()
//                    .eq(BaseLocation::getLocationColumn, businDataTask.getToColumn())
//                    .eq(BaseLocation::getLayer, businDataTask.getToLayer())
//                    .eq(BaseLocation::getLocationRow, businDataTask.getToRow())
//                    .eq(BaseLocation::getLocationStatus,"4"));
            BaseLocation baseLocation = iBaseLocationService.getById(businDataTask.getLocationId());
            baseLocation.setLocationStatus("2");
            //添加库存
            //TODO 空治具出库是没有处理库存流程 考虑入库时是否添加库存
            SysStockDetail sysStockDetail = new SysStockDetail();
            sysStockDetail.setQty(new BigDecimal("1"));
            sysStockDetail.setAreaId(baseLocation.getAreaId());
            sysStockDetail.setLocationId(baseLocation.getId());
            sysStockDetail.setStorageId(9L);
            sysStockDetail.setTunnel(baseLocation.getTunnel());
            sysStockDetail.setContainerCode(businDataTask.getContainerId());
            sysStockDetail.setBatch(businDataTask.getBatch());
            sysStockDetail.setInTime(DateUtils.getNowDate());
            sysStockDetail.setCreateTime(DateUtils.getNowDate());
            //更改任务状态
            businDataTask.setTaskStatus("2");
            iBaseLocationService.updateById(baseLocation);
            iSysStockDetailService.save(sysStockDetail);
            return businDataTaskMapper.updateById(businDataTask)>0?Result.ok():Result.err();
        }
        if (businDataTask.getTaskType().equals(TaskTypeEnum.scancode_err.getValue())){
            BaseLocation baseLocation = iBaseLocationService.getOne(new LambdaQueryWrapper<BaseLocation>()
                    .eq(BaseLocation::getLocationColumn, businDataTask.getToColumn())
                    .eq(BaseLocation::getLayer, businDataTask.getToLayer())
                    .eq(BaseLocation::getLocationRow, businDataTask.getToRow()));
            baseLocation.setLocationStatus("2");
            SysStockDetail sysStockDetail = new SysStockDetail();
            sysStockDetail.setQty(new BigDecimal("1"));
            sysStockDetail.setAreaId(baseLocation.getAreaId());
            sysStockDetail.setLocationId(baseLocation.getId());
            sysStockDetail.setStorageId(9L);
            sysStockDetail.setGoodsNo("ERROR");
            sysStockDetail.setQrCode("ERROR");
            sysStockDetail.setTunnel(baseLocation.getTunnel());
            sysStockDetail.setContainerCode(businDataTask.getContainerId());
            sysStockDetail.setBatch(businDataTask.getBatch());
            sysStockDetail.setInTime(DateUtils.getNowDate());
            sysStockDetail.setCreateTime(DateUtils.getNowDate());
            iBaseLocationService.updateById(baseLocation);
            iSysStockDetailService.save(sysStockDetail);
            return businDataTaskMapper.updateById(businDataTask)>0?Result.ok():Result.err();
        }
        if(ObjectUtils.isEmpty(bodyInOutDatas)){
            return Result.err().msg("没有要处理的库存信息");
        }
        Long locationCode=0L;
        String batch="";
        Long containerCode=0L;
        Long storageCode=0L;
        int isPunching=0;
        int isRepair=0;
        List<BaseBarcodesIn> barcodesIns = new ArrayList<>();
        List goods = new ArrayList();
        for (BusinBillHeadbodyInVo bodyInOutData : bodyInOutDatas) {
            locationCode = bodyInOutData.getLocationCode();
            storageCode = bodyInOutData.getStorageCode();
            batch = bodyInOutData.getBatch();
            isRepair += Integer.valueOf(bodyInOutData.getIsRepair());
            isPunching += Integer.valueOf(bodyInOutData.getIsPunching());
            containerCode = bodyInOutData.getContainerCode();
            Map goodsMap =new HashMap();
            goodsMap.put("goodsNo",bodyInOutData.getGoodsNo());
            goodsMap.put("qrCode",bodyInOutData.getQrCode());
            goods.add(goodsMap);

            // TODO 测试注释  要打开
            //更改入库条码状态
            BaseBarcodesIn baseBarcodesIn = iBaseBarcodesInService.getOne(new LambdaQueryWrapper<BaseBarcodesIn>()
                    .eq(BaseBarcodesIn::getQrCode, bodyInOutData.getQrCode()).last("limit 1"));

            baseBarcodesIn.setInStatus("4");
            baseBarcodesIn.setInDate(DateUtils.getDate());
            barcodesIns.add(baseBarcodesIn);

        }
        //更新条码状态为已入库,状态为4
         iBaseBarcodesInService.saveOrUpdateBatch(barcodesIns);

         iSysStockService.productDeposit(locationCode,containerCode,batch,String.valueOf(isPunching),goods,storageCode);

        //将任务状态改为已完成
        businDataTask.setTaskStatus(TaskStatusEnum.finished.getValue());
        iBusinDataTaskService.updateById(businDataTask);
        //回填入库状态，已完成入库
        return businBillheadMapper.updateInfoBytaskCode(taskId) > 0 ? Result.ok():Result.err();
    }

    @Override
    public Result<String> exeTaskPutinStorage(BusinTaskExeBo bo) {
        //生成出入库单
        int lindId = 0;
        String transCode = DateUtils.dateTime();

        List<BusinBillbody> bodyList = new ArrayList<>();
        BusinBillHeadAddBo billhead = null;
        List<BusinDataTaskGoodsVo> businDataTaskGoodsVos = bo.getBusinDataTaskGoodsVo();
        for (BusinDataTaskGoodsVo dataTaskGoodsVo : businDataTaskGoodsVos) {
            //查询物料是否已经入库
            BusinBillHeadBodyQueryBo queryBo = new BusinBillHeadBodyQueryBo();
            queryBo.setQrCode(dataTaskGoodsVo.getQrCode());
            BusinBillHeadVo businBillHeadVo = iBusinBillheadService.queryBillHeadAndBody(queryBo);
            if (businBillHeadVo != null) {
                // return Result.err().msg("此 " + firstBarcode + "条码已入库");
                //写日志进行监控
            }

            Long tqty = Long.valueOf(businDataTaskGoodsVos.size());

            //生成入库信息
            billhead = new BusinBillHeadAddBo();
            billhead.setTransId(transCode);
            //1入库 2出库 3退回
            billhead.setTransNo(bo.getTransNo());
            //1入库 -1 出库
            billhead.setTransQual(bo.getTransQual());
            billhead.setTqty(tqty);
            billhead.setContainerCode(bo.getContainerId());
            billhead.setTaskCode(bo.getTaskCode());
            billhead.setBatch(DateUtils.getDate());
            billhead.setBranchId(SecurityUtils.getCurrentBranchId());
            billhead.setAuditFlg("0");
            billhead.setContainerCode(bo.getContainerId());

            BusinBillhead businBillhead = BeanUtil.toBean(billhead, BusinBillhead.class);

            iBusinBillheadService.insertBusinBillhead(businBillhead);
            Long transId = businBillhead.getId();
            //可以没有货位
            BaseLocationVo locationVo=new BaseLocationVo();
            if (bo.getBaseLocationVo()!=null){
                locationVo= bo.getBaseLocationVo();
            }

            lindId += 1;
            BusinBillbody body = new BusinBillbody();
            body.setLineId(lindId);
            body.setGoodsNo(dataTaskGoodsVo.getGoodsNo());
            body.setQty(1);
            body.setTransId(transId);
            body.setTaskCode(bo.getTaskCode());
            body.setIsPunching(dataTaskGoodsVo.getIsPunching());
            body.setIsRepair(dataTaskGoodsVo.getIsRepair());
            if (bo.getBaseLocationVo()!=null) {
            body.setBranchCode(locationVo.getBranchId());
            body.setLocationCode(locationVo.getId());
            body.setStorageCode(locationVo.getStorageId());
            body.setAreaCode(locationVo.getAreaId());
            }
            body.setQrCode(dataTaskGoodsVo.getQrCode());
            bodyList.add(body);
        }
        return iBusinBillbodyService.saveBatch(bodyList)? Result.ok(): Result.err();
    }

    @Override
    public Result saveBillTaskIn(BillTaskAddbo billTaskAddbo,String type) {
        //获取紧急出库下料点位
        String startPoint = billTaskAddbo.getStartPoint();
        if (startPoint==null){
            String tepairGroup ="";
            tepairGroup = iSysParameterService.selectConfigByKey(SecurityUtils.getCurrentBranchId(), ParameterConstants.ParameterSystem.blanking_point);
            BasePointDeviceQueryBo pointQueryBo = new BasePointDeviceQueryBo();
            pointQueryBo.setGroupNo(tepairGroup);

            BasePointDeviceVo pointDevice = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBo);
            startPoint=pointDevice.getPointNo();
        }

        MachineHandAddBo mhaddbo = new MachineHandAddBo();
        mhaddbo.setTaskType("7");
        if (StringUtils.isNotEmpty(billTaskAddbo.getTaskType())){
            mhaddbo.setTaskType(billTaskAddbo.getTaskType());
        }

        mhaddbo.setPointNo(startPoint);
        mhaddbo.setContainerId(billTaskAddbo.getContainerCode());
        List<BasinBarcodeInAddBo> barcodesList = billTaskAddbo.getBarcodesList();
        int i =0;
        for (BasinBarcodeInAddBo barcode : barcodesList) {
            i++;
            if (i ==1){
                mhaddbo.setFirstBarcode(barcode.getQrCode());
            }else if (i == 2){
                mhaddbo.setSecondBarcode(barcode.getQrCode());
            }
            else if (i == 3){
                mhaddbo.setThirdBarcode(barcode.getQrCode());
            }
        }
        Result<Long> r= null;
        if (StringUtils.isNotEmpty(type) && ("RG").equals(type)) {
            r = this.saveBusinBillTaskData(mhaddbo,"RG");
        }else{
            r = this.saveBusinBillTaskData(mhaddbo);
        }
        Long taskId  = r.getData();
        return Result.ok().data(taskId);
    }

    @Override
    public Result<Boolean> queryderiveId(BillTaskAddbo billTaskAddbo) {
        BasinBarcodeInAddBo basinBarcodeInAddBoONE=billTaskAddbo.getBarcodesList().get(0);
        BasinBarcodeInAddBo basinBarcodeInAddBoTWE=billTaskAddbo.getBarcodesList().get(1);

        BaseDeriveQueryBo deriveQueryBoONE=new BaseDeriveQueryBo();
        BaseDeriveQueryBo deriveQueryBoTWE = new BaseDeriveQueryBo();
        deriveQueryBoONE.setVehicheModel(basinBarcodeInAddBoONE.getVehicheModel());
        deriveQueryBoONE.setColor(basinBarcodeInAddBoONE.getColor());

        deriveQueryBoTWE.setVehicheModel(basinBarcodeInAddBoTWE.getVehicheModel());
        deriveQueryBoTWE.setColor(basinBarcodeInAddBoTWE.getColor());

        BaseDerive deriveONE=iBaseDeriveService.getBaseDeriveBybarcodes(deriveQueryBoONE);
        BaseDerive deriveTWE=iBaseDeriveService.getBaseDeriveBybarcodes(deriveQueryBoTWE);
        Boolean bool=true;
        if (deriveONE.getId().equals(deriveTWE.getId())){
            bool=false;
        }
        if (!bool){
            return Result.err();
        }

        return Result.ok();
    }

    @Override
    public Result getnumberderive(BillTaskAddbo billTaskAddbo) {
        BasinBarcodeInAddBo basinBarcodeInAddBo = billTaskAddbo.getBarcodesList().get(0);
        BaseDeriveQueryBo deriveQueryBo = new BaseDeriveQueryBo();
        deriveQueryBo.setVehicheModel(basinBarcodeInAddBo.getVehicheModel());
        deriveQueryBo.setColor(basinBarcodeInAddBo.getColor());
        BaseDerive baseDeriveBybarcodes = iBaseDeriveService.getBaseDeriveBybarcodes(deriveQueryBo);
        String number="3";
        if (baseDeriveBybarcodes!=null) {
            if ("0".equals(baseDeriveBybarcodes.getRearSplit())) {
                number = "1";
            }
        }else {
            number="0";
        }
        Map map=new HashMap();
        map.put("number",number);

        return Result.ok().data(map);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> reduceInventory(Long taskId) {
        BusinBillHeadBodyQueryBo bodyQueryBo =new BusinBillHeadBodyQueryBo();
        bodyQueryBo.setTaskId(taskId);
        //获取要出库的物料信息
        List<BusinBillHeadbodyInVo> bodyInOutDatas = iBusinBillheadService.getBillHeadBodyInOutData(bodyQueryBo);
        if(bodyInOutDatas == null){
            return Result.err().msg("没有要处理的出库库存信息");
        }
        //处理出库物料的库存信息
        for (BusinBillHeadbodyInVo bodyInOutData : bodyInOutDatas) {
            SysStockReduceBo sysStockReduceBo = new SysStockReduceBo();
            sysStockReduceBo.setBranchId(SecurityUtils.getCurrentBranchId());
            sysStockReduceBo.setAreaId(bodyInOutData.getAreaCode());
            sysStockReduceBo.setStorageId(bodyInOutData.getStorageCode());
            sysStockReduceBo.setLocationId(bodyInOutData.getLocationCode());
            sysStockReduceBo.setGoodsNo(bodyInOutData.getGoodsNo());
            iSysStockService.reduceInventory(sysStockReduceBo);
        }

        //回填出库状态，已完成出库
        LambdaQueryWrapper<BusinBillhead> lqw = Wrappers.lambdaQuery();
        lqw.eq(StrUtil.isNotBlank(taskId.toString()),BusinBillhead::getTaskCode,taskId);
        BusinBillhead one = iBusinBillheadService.getOne(lqw);
        one.setAuditFlg("1");
        return iBusinBillheadService.updateById(one)?Result.ok():Result.err();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> reduceInventory(Long taskId,List<String> goods) {
        BusinBillHeadBodyQueryBo bodyQueryBo =new BusinBillHeadBodyQueryBo();
        bodyQueryBo.setTaskId(taskId);
        bodyQueryBo.setGoods(goods);
        //获取要出库的物料信息
        List<BusinBillHeadbodyInVo> bodyInOutDatas = iBusinBillheadService.getBillHeadBodyInOutData(bodyQueryBo);
        if(bodyInOutDatas == null){
            return Result.err().msg("没有要处理的出库库存信息");
        }

        for (BusinBillHeadbodyInVo bodyInOutData : bodyInOutDatas) {
            SysStockReduceBo sysStockReduceBo = new SysStockReduceBo();
            sysStockReduceBo.setBranchId(SecurityUtils.getCurrentBranchId());
            sysStockReduceBo.setAreaId(bodyInOutData.getAreaCode());
            sysStockReduceBo.setStorageId(bodyInOutData.getStorageCode());
            sysStockReduceBo.setLocationId(bodyInOutData.getLocationCode());
            sysStockReduceBo.setGoodsNo(bodyInOutData.getGoodsNo());
            iSysStockService.reduceInventory(sysStockReduceBo);
        }

        //回填出库状态，已完成出库
        LambdaQueryWrapper<BusinBillhead> lqw = Wrappers.lambdaQuery();
        lqw.eq(StrUtil.isNotBlank(taskId.toString()),BusinBillhead::getTaskCode,taskId);
        BusinBillhead one = iBusinBillheadService.getOne(lqw);
        one.setAuditFlg("1");
        return iBusinBillheadService.updateById(one)?Result.ok():Result.err();
    }


}
