package com.prolog.cs.biz.inbound.service.impl.processor.handler;

import com.prolog.common.util.DateUtils;
import com.prolog.cs.basic.warehouse.model.BaseWmsWarehouseLocator;
import com.prolog.cs.biz.control.model.vo.LocatorQueryVO;
import com.prolog.cs.biz.inbound.constant.BizConstant;
import com.prolog.cs.biz.inbound.dao.rcv.RcvLinesProfilesMapper;
import com.prolog.cs.biz.inbound.dto.rcv.RcvLinesDTO;
import com.prolog.cs.biz.inbound.dto.task.TaskInstockDetailDTO;
import com.prolog.cs.biz.inbound.model.rcv.RcvLinesProfiles;
import com.prolog.cs.biz.inbound.remote.ControlRemoteCaller;
import com.prolog.cs.biz.inbound.remote.StrategyClient;
import com.prolog.cs.biz.inbound.service.impl.processor.Helper.TaskHelper;
import com.prolog.cs.biz.inbound.service.impl.processor.enums.ConclusionEnum;
import com.prolog.cs.biz.inbound.service.impl.processor.enums.RcvTypeStrategyEnum;
import com.prolog.cs.biz.inbound.service.impl.processor.enums.RqcStrategyEnum;
import com.prolog.cs.biz.inbound.service.impl.processor.enums.SubjectStrategyEnum;
import com.prolog.cs.biz.inbound.service.impl.strategy.WhAreaCategoryContext;
import com.prolog.cs.biz.inbound.service.rcv.RcvInstockLinesService;
import com.prolog.cs.biz.inbound.service.task.TaskInstockDetailService;
import com.prolog.cs.biz.inbound.service.task.TaskQcDetailService;
import com.prolog.cs.biz.inbound.service.task.TaskQcRecheckDetailService;
import com.prolog.cs.biz.inbound.service.task.TaskRejectedDetailService;
import com.prolog.cs.biz.inbound.utils.ObjectUtils;
import com.prolog.cs.biz.inbound.utils.UserUtils;
import com.prolog.framework.authority.core.dto.UserDTO;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.BizException;
import com.prolog.framework.core.exception.ParameterException;
import com.prolog.framework.utils.JsonUtils;
import com.prolog.framework.utils.StringUtils;
import com.prolog.upcloud.base.inventory.dto.InstockItemInfo;
import com.prolog.upcloud.base.strategy.domain.core.Strategy;
import com.prolog.upcloud.base.strategy.dto.StrategyDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

@Service
@Slf4j
public class RcvTaskHandler implements TaskHandler {

	@Resource
	private TaskInstockDetailService taskInstockDetailService;

	@Resource
	private RcvInstockLinesService rcvInstockLinesService;

	@Resource
	private TaskQcDetailService taskQcDetailService;

	@Resource
	private TaskQcRecheckDetailService taskQcRecheckDetailService;

	@Resource
	private TaskRejectedDetailService taskRejectedDetailService;

	@Resource
	private TaskHelper taskHelper;

	@Resource
	private ControlRemoteCaller controlRemoteCaller;

	@Resource
	private RcvLinesProfilesMapper rcvLinesProfilesMapper;

	@Resource
	private UserUtils userUtils;

	@Resource
	private StrategyClient strategyClient;

	@Override
	public Object excute(SubjectStrategyEnum subjectStrategy, RcvTypeStrategyEnum rcvType, RqcStrategyEnum rqcStrategy,
			Map<String, Object> dataMap, ConclusionEnum conclusionEnum, boolean isAuto) {
		// 做具体逻辑
		String strategy = subjectStrategy.getStrategy();
		switch (strategy) {
		case "rcv_in_01":
			return filterSubject(rcvType, rqcStrategy, dataMap, conclusionEnum, isAuto);
		default:
			return null;
		}
	}

	@Override
	public Object rfExcute(SubjectStrategyEnum subjectStrategy, RcvTypeStrategyEnum rcvType,
			RqcStrategyEnum rqcStrategy, Map<String, Object> dataMap, ConclusionEnum conclusionEnum, boolean isAuto) {
		// 做具体逻辑
		String strategy = subjectStrategy.getStrategy();
		switch (strategy) {
		case "rcv_in_01":
			return rfFilterSubject(rcvType, rqcStrategy, dataMap, conclusionEnum, isAuto);
		default:
			return null;
		}
	}

	private Object filterSubject(RcvTypeStrategyEnum rcvType, RqcStrategyEnum rqcStrategy, Map<String, Object> dataMap,
			ConclusionEnum conclusionEnum, boolean isAuto) {
		// 主体1 的逻辑
		String typeStrategy = rcvType.getTypeStrategy();
		switch (typeStrategy) {
		case "rcv_in_type01":
			// 可以配合policy包使用
			return filterRcvType(rqcStrategy, dataMap, conclusionEnum, isAuto);
		default:
			return null;
		}
	}

	private Object rfFilterSubject(RcvTypeStrategyEnum rcvType, RqcStrategyEnum rqcStrategy,
			Map<String, Object> dataMap, ConclusionEnum conclusionEnum, boolean isAuto) {
		// 主体1 的逻辑
		String typeStrategy = rcvType.getTypeStrategy();
		switch (typeStrategy) {
		case "rcv_in_type01":
			// 可以配合policy包使用
			return rfFilterRcvType(rqcStrategy, dataMap, conclusionEnum, isAuto);
		default:
			return null;
		}
	}

	private Object filterRcvType(RqcStrategyEnum rqcStrategy, Map<String, Object> dataMap,
			ConclusionEnum conclusionEnum, boolean isAuto) {
		// 普通采购入库 逻辑
		String typeStrategy = rqcStrategy.getTypeStrategy();
		switch (typeStrategy) {
		case "rqc_00":
			return filterRqcStrategy1(dataMap, conclusionEnum, isAuto);
		case "rqc_12":
			return filterRqcStrategy4(dataMap, conclusionEnum, isAuto);
		default:
			return null;
		}
	}

	private Object rfFilterRcvType(RqcStrategyEnum rqcStrategy, Map<String, Object> dataMap,
			ConclusionEnum conclusionEnum, boolean isAuto) {
		// 普通采购入库 逻辑
		String typeStrategy = rqcStrategy.getTypeStrategy();
		switch (typeStrategy) {
		case "rqc_00":
			return filterRqcStrategy1(dataMap, conclusionEnum, isAuto);
		case "rqc_12":
			return rFfilterRqcStrategy4(dataMap, conclusionEnum, isAuto);
		default:
			return null;
		}
	}

	@SuppressWarnings("unchecked")
	private Object filterRqcStrategy4(Map<String, Object> dataMap, ConclusionEnum conclusionEnum, boolean isAuto) {
		// 质检策略4 需要走质检
		String conclusionval = conclusionEnum.getConclusionval();
		String conclusionval1 = ConclusionEnum.qualified.getConclusionval();
		String conclusionval2 = ConclusionEnum.noQualified.getConclusionval();
		String conclusionval3 = ConclusionEnum.pending.getConclusionval();
		String conclusionval4 = ConclusionEnum.refuse.getConclusionval();
		String mtlOwnerId = (String) dataMap.get("mtlOwnerId");
		String warehouseId = (String) dataMap.get("warehouseId");
		List<RcvLinesDTO> list = (List<RcvLinesDTO>) dataMap.get("data");
		Object excuteTask = null;
		List<String> rcvTypeList = new ArrayList<String>();
		rcvTypeList.add(BizConstant.PURCHASE_IN);
		rcvTypeList.add(BizConstant.SALE_RETURN_IN);
		rcvTypeList.add(BizConstant.ALLOT_IN);
		rcvTypeList.add(BizConstant.FACTORY_MAINTENANCE_IN);
		rcvTypeList.add(BizConstant.CUSTORM_MAINTENANCE_IN);
		List<String> pararmTypeList = list.stream().map(RcvLinesDTO::getRcvType).distinct()
				.collect(Collectors.toList());
		// 合格/不合格/质检 都需走质检
		if (conclusionval1.equals(conclusionval)) {
			// 合格不合格由上架任务池自身处理
			// 合格
//			excuteTask = taskInstockDetailService.excuteTask(list, mtlOwnerId, warehouseId);
			excuteTask = taskQcDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
			if (rcvTypeList.containsAll(pararmTypeList)) {
				taskQcDetailService.updateTaskToFinshed(list);
			}
		} else if (conclusionval2.equals(conclusionval)) {
			// 不合格
//			excuteTask = taskInstockDetailService.excuteTask(list, mtlOwnerId, warehouseId);
			excuteTask = taskQcDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
		} else if (conclusionval3.equals(conclusionval)) {
			// 待处理(需要根据业务参数判断是否直接到复检并且进入代管子流程0否1是)
			String regValue = taskHelper.getInboundPendRerqcHostin(warehouseId, mtlOwnerId);

			if (regValue.equals("1")) {
				// 收货->复检(先做代管入)
				excuteTask = taskQcRecheckDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
			} else {
				// 走正常收货->验收逻辑
				excuteTask = taskQcDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
			}
		} else if (conclusionval4.equals(conclusionval)) {
			// 拒绝
			excuteTask = taskRejectedDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
		} else {
			excuteTask = taskQcDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
		}

		/* 添加生成验收任务时--生成上架任务的操作，适用于维修入库\调拨入库\消退入库 ---- on 2022-07-25 by 陈浩---开始 */
		// 不是这几种类型的数据不予处理 此处有问题
		/*if (rcvTypeList.containsAll(pararmTypeList)) {
			// 生成上架任务
			excuteTask = taskInstockDetailService.excuteTask(list, mtlOwnerId, warehouseId);
			this.upLocDetailToUpTask(list);
		}*/
		/* 添加生成验收任务时--生成上架任务的操作，适用于维修入库\调拨入库\消退入库 ---- on 2022-07-25 by 陈浩---结束 */
		return excuteTask;
	}

	@SuppressWarnings("unchecked")
	private Object rFfilterRqcStrategy4(Map<String, Object> dataMap, ConclusionEnum conclusionEnum, boolean isAuto) {
		// 质检策略4 需要走质检
		String conclusionval = conclusionEnum.getConclusionval();
		String conclusionval1 = ConclusionEnum.qualified.getConclusionval();
		String conclusionval2 = ConclusionEnum.noQualified.getConclusionval();
		String conclusionval3 = ConclusionEnum.pending.getConclusionval();
		String conclusionval4 = ConclusionEnum.refuse.getConclusionval();
		String mtlOwnerId = (String) dataMap.get("mtlOwnerId");
		String warehouseId = (String) dataMap.get("warehouseId");
		List<RcvLinesDTO> list = (List<RcvLinesDTO>) dataMap.get("data");
		Object excuteTask = null;
		List<String> rcvTypeList = new ArrayList<String>();
		rcvTypeList.add(BizConstant.PURCHASE_IN);
		rcvTypeList.add(BizConstant.SALE_RETURN_IN);
		rcvTypeList.add(BizConstant.ALLOT_IN);
		rcvTypeList.add(BizConstant.FACTORY_MAINTENANCE_IN);
		rcvTypeList.add(BizConstant.CUSTORM_MAINTENANCE_IN);
		List<String> pararmTypeList = list.stream().map(RcvLinesDTO::getRcvType).distinct()
				.collect(Collectors.toList());
		// 合格/不合格/质检 都需走质检
		if (conclusionval1.equals(conclusionval)) {
			// 合格不合格由上架任务池自身处理
			// 合格
//			excuteTask = taskInstockDetailService.excuteTask(list, mtlOwnerId, warehouseId);
			excuteTask = taskQcDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
		} else if (conclusionval2.equals(conclusionval)) {
			// 不合格
//			excuteTask = taskInstockDetailService.excuteTask(list, mtlOwnerId, warehouseId);
			excuteTask = taskQcDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
		} else if (conclusionval3.equals(conclusionval)) {
			// 待处理(需要根据业务参数判断是否直接到复检并且进入代管子流程0否1是)
			String regValue = taskHelper.getInboundPendRerqcHostin(warehouseId, mtlOwnerId);

			if (regValue.equals("1")) {
				// 收货->复检(先做代管入)
				excuteTask = taskQcRecheckDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
			} else {
				// 走正常收货->验收逻辑
				excuteTask = taskQcDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
			}
		} else if (conclusionval4.equals(conclusionval)) {
			// 拒绝
			excuteTask = taskRejectedDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
		} else {
			excuteTask = taskQcDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
		}

		// 生成上架任务
		excuteTask = taskInstockDetailService.excuteTask(list, mtlOwnerId, warehouseId);



		taskQcDetailService.updateTaskToFinshed(list);
		this.upLocDetailToUpTask(list);
		/* 添加生成验收任务时--生成上架任务的操作，适用于维修入库\调拨入库\消退入库 ---- on 2022-07-25 by 陈浩---结束 */
		return excuteTask;
	}

	private Object filterRqcStrategy1(Map<String, Object> dataMap, ConclusionEnum conclusionEnum, boolean isAuto) {
		// 质检策略1 不进行质检
		// 具体质检不质检由物料本身结论决定
		String conclusionval = conclusionEnum.getConclusionval();
		String conclusionval1 = ConclusionEnum.qualified.getConclusionval();
		String conclusionval2 = ConclusionEnum.noQualified.getConclusionval();
		String conclusionval3 = ConclusionEnum.pending.getConclusionval();
		String conclusionval4 = ConclusionEnum.refuse.getConclusionval();
		String mtlOwnerId = (String) dataMap.get("mtlOwnerId");
		String warehouseId = (String) dataMap.get("warehouseId");
		List<RcvLinesDTO> list = (List<RcvLinesDTO>) dataMap.get("data");
		Object excuteTask = null;
		// 合格/不合格/待处理 都走上架
		if (conclusionval1.equals(conclusionval)) {
			// 合格不合格由上架任务池自身处理
			excuteTask = taskInstockDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
		} else if (conclusionval2.equals(conclusionval))
			// 不合格
			excuteTask = taskInstockDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
		else if (conclusionval3.equals(conclusionval))
			// 待处理
			excuteTask = taskInstockDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
		else if (conclusionval4.equals(conclusionval))
			// 拒绝
			excuteTask = taskRejectedDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
		else
			excuteTask = taskInstockDetailService.excuteTask(list, mtlOwnerId, warehouseId, isAuto);
		return excuteTask;
	}

	/*
	 * 添加有质检策略生成验收任务单时，需要根据有无库别、根据策略获取库别和获取货位的方法，在去生成上架任务-----on 2022-07-26 by
	 * 陈浩---开始
	 */
	/**
	 * 修改上架任务的货物和库别信息
	 */
	public void upLocDetailToUpTask(List<RcvLinesDTO> rcvLinesDTOList) {
		// 若收货有选库别，则直接调用商品货位限定，分配货位，生成上架任务
		List<RcvLinesDTO> list1 = rcvLinesDTOList.stream()
				.filter(i -> org.apache.commons.lang.StringUtils.isNotBlank(i.getWarehouseAreaCategory()))
				.collect(Collectors.toList());
		// 若收货没有选库别，则先调取上架策略分配库别，再调用商品货位限定，分配货位，生成上架任务
		List<RcvLinesDTO> list2 = rcvLinesDTOList.stream()
				.filter(i -> org.apache.commons.lang.StringUtils.isBlank(i.getWarehouseAreaCategory()))
				.collect(Collectors.toList());
		UserDTO userDTO = userUtils.getUserDTO();
		this.getLocCode(list1, userDTO);
		this.getWarehouseCode(list2, userDTO);
	}

	public void getLocCode(List<RcvLinesDTO> list1, UserDTO userDTO) {
		if (list1 == null || list1.size() < 1) {
			return;
		}

		List<String> rcvLineSet = list1.stream().map(p -> p.getRcvLineId()).distinct().collect(Collectors.toList());
		List<RcvLinesProfiles> linePro = rcvLinesProfilesMapper.findByIds(RcvLinesProfiles.class,
				rcvLineSet.toArray(new String[rcvLineSet.size()]), null);
		List<TaskInstockDetailDTO> askInstockDetailList = taskInstockDetailService
				.geTaskInstockDetailsByRcvLineId(rcvLineSet);
		askInstockDetailList.stream().forEach(i -> {
			RcvLinesDTO dto = list1.stream().filter(m -> m.getRcvLineId().equals(i.getRcvLineId())).findFirst()
					.orElse(null);
			if (dto != null) {
				i.setBatchExpiredDate(dto.getBatchExpiredDate());
				i.setBatchProductionDate(dto.getBatchProductionDate());
				i.setCategoryId(dto.getCategoryId());
				i.setCategoryName(dto.getCategoryName());
			}
		});
		List<LocatorQueryVO> queryVOList = new ArrayList<LocatorQueryVO>();
		// 调用策略获取库别 TODO
		// Step1: 远程找寻策略
		String enterpriseId = userDTO.getEnterpriseId();
		askInstockDetailList.stream().forEach(i -> {
			LocatorQueryVO vo = new LocatorQueryVO();
			vo.setEnterpriseId(enterpriseId);
			String warehouseId = i.getWarehouseId();
			String mtlOwnerId = i.getMtlOwnerId();
			// Step2: 组装查询货位的条件
			InstockItemInfo info = new InstockItemInfo();
			info.setWarehouseId(warehouseId);
			info.setCargoOwnerId(mtlOwnerId);
			buildGetLocatorCondition(info, i, warehouseId, mtlOwnerId, linePro);
			vo.setItemInfo(info);
			queryVOList.add(vo);
		});
		try {
			this.excuteGetLocator(queryVOList, askInstockDetailList, userDTO, new Date());
		} catch (Exception e) {
			e.printStackTrace();
			log.info("找寻推荐货位失败,原因->{}", e);
		}
	}

	public void getWarehouseCode(List<RcvLinesDTO> list2, UserDTO userDTO) {
		if (list2 == null || list2.size() < 1) {
			return;
		}
		List<String> rcvLineSet = list2.stream().map(p -> p.getRcvLineId()).distinct().collect(Collectors.toList());
		List<TaskInstockDetailDTO> askInstockDetailList = taskInstockDetailService
				.geTaskInstockDetailsByRcvLineId(rcvLineSet);

		askInstockDetailList.stream().forEach(i -> {
			RcvLinesDTO dto = list2.stream().filter(m -> m.getRcvLineId().equals(i.getRcvLineId())).findFirst()
					.orElse(null);
			if (dto != null) {
				i.setBatchExpiredDate(dto.getBatchExpiredDate());
				i.setBatchProductionDate(dto.getBatchProductionDate());
				i.setCategoryId(dto.getCategoryId());
				i.setCategoryName(dto.getCategoryName());
			}
		});

		List<LocatorQueryVO> queryVOList = this.getWhCategory(askInstockDetailList, userDTO);
		try {
			this.excuteGetLocator(queryVOList, askInstockDetailList, userDTO, new Date());
		} catch (Exception e) {
			e.printStackTrace();
			log.info("找寻推荐货位失败,原因->{}", e);
		}
	}

	private void buildGetLocatorCondition(InstockItemInfo info, TaskInstockDetailDTO taskInstockDetail,
			String warehouseId, String mtlOwnerId, List<RcvLinesProfiles> linePro) {
		Map<String, String> collect = null;
		if (!ObjectUtils.isNull(linePro)) {
			collect = linePro.stream().collect(Collectors.toMap(RcvLinesProfiles::getRcvLineId,
					RcvLinesProfiles::getStoreTemperature, (key1, key2) -> key2));
		}
		String itemId = taskInstockDetail.getItemId();
		String rcvLineId = taskInstockDetail.getRcvLineId();
		String rcvHeaderId = taskInstockDetail.getRcvHeaderId();
		BigDecimal pieceQty = taskInstockDetail.getPieceQty();
		String bldgCode = taskInstockDetail.getBldgCode();
		BigDecimal conversionRate = taskInstockDetail.getConversionRate();
		String vendorBatchNum = taskInstockDetail.getVendorBatchNum();
		String manufacturerLotNum = taskInstockDetail.getManufacturerLotNum();
		String goodsCaseCode = taskInstockDetail.getGoodsCaseCode();
		String containerCode = taskInstockDetail.getContainerCode();
		String categoryId = taskInstockDetail.getCategoryId();
		Date batchExpiredDate = taskInstockDetail.getBatchExpiredDate();
		Date batchProductionDate = taskInstockDetail.getBatchProductionDate();
		if (ObjectUtils.isNull(batchExpiredDate) || ObjectUtils.isNull(batchProductionDate))
			throw new ParameterException("请检查自己的批次生产日期和批次有效期!");
		String productionPlace = taskInstockDetail.getProductionPlace();
		String orgId = taskInstockDetail.getOrgId();
		String vendorId = taskInstockDetail.getVendorId();
		String erpBatchNum2 = taskInstockDetail.getErpBatchNum();
		BigDecimal piecePriceTe = taskInstockDetail.getPiecePriceTe();
		BigDecimal piecePriceTi = taskInstockDetail.getPiecePriceTi();
		BigDecimal taxRate = taskInstockDetail.getTaxRate();
		String enterpriseId = taskInstockDetail.getEnterpriseId();

		String whAreaCategoryCode2 = taskInstockDetail.getWhAreaCategoryCode();

		info.setRcvId(rcvHeaderId);
		info.setRcvLineId(rcvLineId);
		info.setWarehouseCategoryCode(whAreaCategoryCode2);
		info.setEnterpriseId(enterpriseId);
		info.setBatchExpiredDate(batchExpiredDate);
		info.setBatchProductionDate(batchProductionDate);
		info.setCargoOwnerId(mtlOwnerId);
		info.setErpBatchNum(erpBatchNum2); // 预留
		info.setItemId(itemId);
		info.setManufacturerLotNum(manufacturerLotNum);
		info.setOrgnId(orgId); // 预留
		info.setProductionPlace(productionPlace);
		info.setShelfLifeDays(Math.abs(DateUtils.subtract(batchExpiredDate, batchProductionDate, ChronoUnit.DAYS)));
		info.setPieceCostTe(piecePriceTe);
		info.setPieceCostTi(piecePriceTi);
		info.setTaxRate(taxRate);
		info.setVendorBatchNum(vendorBatchNum);
		info.setVendorId(vendorId);
		info.setWarehouseId(warehouseId);
		info.setGoodsCaseCode(goodsCaseCode);
		info.setItemPieceQty(pieceQty);
		info.setBldgCode(bldgCode);

		String storeTempture = null;
		if (!ObjectUtils.isNull(collect)) {
			storeTempture = collect.get(rcvLineId);
			if (StringUtils.isBlank(storeTempture)) {
				storeTempture = "常温";
			}
			if (!StringUtils.isBlank(storeTempture) && !storeTempture.contains("常温") && !storeTempture.contains("阴凉")
					&& !storeTempture.contains("冷藏") && !storeTempture.contains("冷冻")) {
				storeTempture = "常温";
			}
		}
		info.setStoreTemperature(storeTempture);

		info.setConversionRate(conversionRate);
		info.setContainerCode(containerCode);
		info.setItemCategoryCode(categoryId);

		info.setBillId(taskInstockDetail.getAsnHeaderId());
		info.setAsnId(taskInstockDetail.getAsnHeaderId());
		info.setLineBillId(taskInstockDetail.getAsnLineId());

		String asnHeaderId = taskInstockDetail.getAsnHeaderId();
		String taskInboundId = taskInstockDetail.getTaskInboundId();
		String batchId = taskInstockDetail.getBatchId();

		String inventoryStatus = taskInstockDetail.getInventoryStatus();
		// 库存状态
		info.setStockStatus(inventoryStatus);

		// 需要加入二级库存状态
		String secondStatus = taskInstockDetail.getSecondStatus();
		if (!StringUtils.isBlank(secondStatus)) {
			info.setStockStatus(secondStatus);
		}

		info.setAsnId(asnHeaderId);
		info.setRcvLineId(rcvLineId);
		info.setRcvId(rcvHeaderId);
		info.setTaskId(taskInboundId);
		info.setBatchId(batchId);

	}

	private List<LocatorQueryVO> getWhCategory(List<TaskInstockDetailDTO> detailsList, UserDTO userDTO) {
		if (ObjectUtils.isNull(userDTO))
			userDTO = userUtils.getUserDTO();
		List<LocatorQueryVO> queryVOList = new ArrayList<>();

		// 调用策略获取库别 TODO
		// Step1: 远程找寻策略
		String enterpriseId = userDTO.getEnterpriseId();
		TaskInstockDetailDTO taskInstockDetail2 = detailsList.get(0);
		String warehouseId = taskInstockDetail2.getWarehouseId();
		String mtlOwnerId = taskInstockDetail2.getMtlOwnerId();

		log.info("-------调用策略服务");
		RestMessage<StrategyDTO> strategyResult = strategyClient.getStrategyDTO(enterpriseId, "InStock", mtlOwnerId,
				warehouseId);
		if (strategyResult == null || !strategyResult.isSuccess() || strategyResult.getData() == null)
			throw new BizException("未找到有效推荐库别的策略,请联系相关人员检查自己的策略!");
		StrategyDTO strategyDTO = strategyResult.getData();
		Strategy strategy = null;
		try {
			log.info("创建上架寻库别策略中-------+" + strategyDTO.toString());
			strategy = strategyDTO.createStrategy();
		} catch (Exception e) {
			// 打印日志
			log.error("策略创建失败,原因->", e);
			throw new BizException("未找到有效推荐库别的策略,请联系管理员设置!");
		}
		log.info("-------调用策略服务成功!");

		Set<String> rcvLineSet = detailsList.stream().map(p -> p.getRcvLineId()).collect(Collectors.toSet());
		List<RcvLinesProfiles> linePro = rcvLinesProfilesMapper.findByIds(RcvLinesProfiles.class,
				rcvLineSet.toArray(new String[rcvLineSet.size()]), null);

		for (TaskInstockDetailDTO taskInstockDetail : detailsList) {

			String taskInboundId = taskInstockDetail.getTaskInboundId();
			String whAreaCategoryCode = taskInstockDetail.getWhAreaCategoryCode();
			if (StringUtils.isBlank(whAreaCategoryCode)) {
				String rcvType2 = taskInstockDetail.getRcvType();
				String hostLocatorId = taskInstockDetail.getHostLocatorId();
				if (!StringUtils.isBlank(rcvType2) && BizConstant.WAIT_CHECK_IN.equals(rcvType2)
						&& !StringUtils.isBlank(hostLocatorId)) {
					taskInstockDetail.setWhAreaCategoryCode(BizConstant.DGK);
					whAreaCategoryCode = BizConstant.DGK;
				}
				// 组装匹配因子
				WhAreaCategoryContext context = new WhAreaCategoryContext();
				WhAreaCategoryContext.RcvLineData rcvLineData = context.new RcvLineData();

				// 单据类型
				String rcvType = taskInstockDetail.getRcvType();
				if (StringUtils.isBlank(mtlOwnerId))
					rcvType = "1";

				rcvLineData.setBillType(rcvType);

				// 整散参数
				String itemIsPieceOrCase = taskInstockDetail.getItemIsPieceOrCase();
				if (StringUtils.isBlank(itemIsPieceOrCase))
					itemIsPieceOrCase = "1"; // 默认整散分开
				if (itemIsPieceOrCase.equals("1"))
					rcvLineData.setIsPieceOrCase(false);
				else
					rcvLineData.setIsPieceOrCase(true);

				// 是否整散
				BigDecimal pieceQty = taskInstockDetail.getPieceQty();
				BigDecimal conversionRate = taskInstockDetail.getConversionRate();
				BigDecimal oddCaseQty = pieceQty.divide(conversionRate, 0, RoundingMode.DOWN);
				BigDecimal oddPieceQty = pieceQty.subtract(oddCaseQty.multiply(conversionRate));
				// 判断数据的整散
				if (null != oddPieceQty && oddPieceQty.compareTo(BigDecimal.ZERO) == 0) {
					// 为整数
					rcvLineData.setIsCase("0");
					// 整散数量
					rcvLineData.setQty(oddCaseQty.doubleValue());
				}

				if (null != oddCaseQty && oddCaseQty.compareTo(BigDecimal.ZERO) == 0 && null != oddPieceQty
						&& oddPieceQty.compareTo(BigDecimal.ZERO) == 1) {
					// 零散散
					rcvLineData.setIsCase("1");
//					rcvLineData.setQty(oddPieceQty.doubleValue());
				}

				if (null != oddCaseQty && oddCaseQty.compareTo(BigDecimal.ZERO) == 1 && null != oddPieceQty
						&& oddPieceQty.compareTo(BigDecimal.ZERO) == 1) {
					// 整散
					rcvLineData.setIsCase("2");
//					rcvLineData.setQty(pieceQty.doubleValue());
				}

				// 库存结论属性
				// 0不合格1合格
				String result = taskInstockDetail.getResult();
				String storageStatus = "0"; // 默认合格
				if (result.equals("0")) {
					storageStatus = "0";
				} else {
					storageStatus = "1";
				}
				rcvLineData.setStorageStatus(storageStatus);

				context.setRcvLineData(rcvLineData);
				try {
					log.info("-------开始执行策略中...............!,策略条件数据->" + JsonUtils.toString(context));
					strategy.execute(context); // 捕捉异常
				} catch (Exception e) {
					log.error("策略执行失败,原因->", e);
					e.printStackTrace();
				}
				boolean completed = context.completed();
				if (completed) {
					// 找到匹配的策略
					log.info("-------获取合适策略");
					List<String> targetAreaCategoryCodes = context.getTargetAreaCategoryCodes();
					String join = String.join(",", targetAreaCategoryCodes);
					log.info(String.format("上架任务[%s],推荐库别[%s]", taskInboundId, join));
					taskInstockDetail.setWhAreaCategoryCode(join);
				}

			}
			log.info("-------找到合适的策略成功!");
			String whAreaCategoryCode2 = taskInstockDetail.getWhAreaCategoryCode();
			String rcvType = taskInstockDetail.getRcvType();
			taskInstockDetail.setWhAreaCategoryCode(whAreaCategoryCode2);
			if (StringUtils.isBlank(whAreaCategoryCode2)) {
				// 看是否使用默认库别
				log.info("-------没有合适的库别!");
				throw new BizException("没有合适的库别,请选择库别,或联系管理员检查并设置上架策略!");
			}

			// 设备库的处理
			String[] split = whAreaCategoryCode2.split(",");
			String whAreaCategoryCode33 = split[0];
			if (!StringUtils.isBlank(whAreaCategoryCode33) && whAreaCategoryCode33.equals(BizConstant.SBK)) {
				continue;
			}

			LocatorQueryVO vo = new LocatorQueryVO();
			String refId = taskInstockDetail.getTaskInboundId();
			vo.setRefId(refId);
			String enterpriseId2 = taskInstockDetail.getEnterpriseId();
			if (StringUtils.isBlank(enterpriseId2))
				vo.setEnterpriseId(enterpriseId);
			else
				vo.setEnterpriseId(enterpriseId2);

			// Step2: 组装查询货位的条件
			InstockItemInfo info = new InstockItemInfo();
			buildGetLocatorCondition(info, taskInstockDetail, warehouseId, mtlOwnerId, linePro);
			vo.setItemInfo(info);
			queryVOList.add(vo);

		}
		return queryVOList;
	}

	private void excuteGetLocator(List<LocatorQueryVO> queryVOList, List<TaskInstockDetailDTO> detailsList,
			UserDTO userDTO, Date now) {
		// Step3: 远程获取推荐库位
		RestMessage<Map<String, BaseWmsWarehouseLocator>> recommendLocatoror = null;
		try {
			log.info("-------开始调用远程寻货位操作!--入参数:" + JsonUtils.toString(queryVOList));
			recommendLocatoror = controlRemoteCaller.getRecommendLocatoror(queryVOList);
		} catch (Exception e) {
			e.printStackTrace();
			throw new BizException(String.format("远程调用库位推荐失败!错误原因->%s", e.getMessage()));
		}
		Map<String, BaseWmsWarehouseLocator> data = null;
		if (!ObjectUtils.isNull(recommendLocatoror) && recommendLocatoror.isSuccess()) {
			data = recommendLocatoror.getData();
			if (ObjectUtils.isNull(data))
				throw new BizException(String.format("推荐数据为空!请重试!"));
			// 看是否有数据
			int row = 0;
			for (Entry<String, BaseWmsWarehouseLocator> entry : data.entrySet()) {
				row++;
				BaseWmsWarehouseLocator value = entry.getValue();
				String key = entry.getKey();
				if (ObjectUtils.isNull(value)) {
					log.info(String.format("第[%d]行数据,来源任务id(上架任务)[%s]的推荐货位为空!", row, key));
				}
			}
			log.info("-------寻货位成功!");
			// 需要更新的上架任务
			for (TaskInstockDetailDTO taskInstockDetail : detailsList) {
				String taskInboundId = taskInstockDetail.getTaskInboundId();
				BaseWmsWarehouseLocator baseWmsWarehouseLocator = data.get(taskInboundId);
				String whLocatorId = taskInstockDetail.getWhLocatorId();
				if (ObjectUtils.isNull(baseWmsWarehouseLocator) || !StringUtils.isEmpty(whLocatorId))
					continue;
				String warehouseLocatorId = baseWmsWarehouseLocator.getWarehouseLocatorId();
				String warehouseLocatorCode = baseWmsWarehouseLocator.getWarehouseLocatorCode();
				String warehouseLocatorName = baseWmsWarehouseLocator.getWarehouseLocatorName();
				taskInstockDetail.setWhLocatorId(warehouseLocatorId);
				taskInstockDetail.setWhLocatorCode(warehouseLocatorCode);
				taskInstockDetail.setWhLocatorName(warehouseLocatorName);
				taskInstockDetail.setWhAreaCode(baseWmsWarehouseLocator.getWarehouseAreaCode());
				taskInstockDetail.setLocatorFloorNum(baseWmsWarehouseLocator.getFloorNum());
				String whAreaCategoryCode = taskInstockDetail.getWhAreaCategoryCode();
				if (StringUtils.isBlank(whAreaCategoryCode)) {
					taskInstockDetail.setWhAreaCategoryCode(baseWmsWarehouseLocator.getWarehouseAreaCategoryCode());
				}
				taskInstockDetail.setAttribute2(baseWmsWarehouseLocator.getPickMode()); // 加入拣货方式
			}
		} else {
			log.info("-------远程找寻货位失败!");
			Map<String, BaseWmsWarehouseLocator> data2 = recommendLocatoror.getData();
			String string = "";
			if (data2 != null) {
				string = recommendLocatoror.getMessage() + data2.toString();
			} else {
				string = recommendLocatoror.getMessage();
			}
			throw new BizException(String.format("远程调用库位推荐失败!错误原因->%s", string));
		}

	}
	/*
	 * 添加有质检策略生成验收任务单时，需要根据有无库别、根据策略获取库别和获取货位的方法，在去生成上架任务-----on 2022-07-26 by
	 * 陈浩---结束
	 */

}
