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


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

import cn.hutool.core.collection.CollectionUtil;
import com.sw.mes.base.global.GlobalSwitch;
import com.sw.mes.base.global.GlobalSwitchNamespace;
import com.sw.mes.core.annotation.Jinko;
import com.sw.mes.core.api.system.StoreFeignClients;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.dto.store.LockInventoryDto;
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.mmcs.service.MMcsInterfaceService;
import com.sw.mes.mqtt.service.NotificationService;
import com.sw.mes.production.entity.FormulaScheme;
import com.sw.mes.production.entity.ProductionAgainTaskRecipe;
import com.sw.mes.production.service.FormulaSchemeService;
import com.sw.mes.production.service.ProductionAgainTaskRecipeService;
import com.sw.mes.yb.ipc.service.impl.MaterialOperationClickServiceImpl;
import com.sw.mes.yb.mcs.service.YbMesToMcsService;
import com.sw.mes.yb.production.dto.*;
import com.sw.mes.yb.production.dto.AgainTask.AgainTaskDto;
import com.sw.mes.yb.production.dto.InputFurnaceBurden.InputFurnaceBurdenExportParam;
import com.sw.mes.yb.production.dto.LoadingTask.FeedingInformationDto;
import com.sw.mes.yb.production.dto.LoadingTask.FillingTaskVo;
import com.sw.mes.yb.production.dto.LoadingTask.IngredientInfoDto;
import com.sw.mes.yb.production.dto.LoadingTask.LoadingTaskDto;
import com.sw.mes.yb.production.entity.*;
import com.sw.mes.yb.production.service.*;
import org.modelmapper.ModelMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.utils.StringUtils;
import com.sw.mes.enumvalue.EnumValuesAgv;
import com.sw.mes.yb.agv.dto.AgvCallDto;
import com.sw.mes.yb.agv.service.AgvDispatchService;
import com.sw.mes.yb.production.dao.AgainTaskDetailDao;
import com.sw.mes.yb.production.dto.AgainTaskDetail.AgainTaskDetailDto;
import com.sw.mes.yb.production.dto.AgainTaskDetail.AgainTaskDetailUpdate;
import com.sw.mes.yb.production.dto.AgainTaskDetail.AgainTaskInstoreDto;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@Service
@Transactional
public class AgainTaskDetailServiceImpl extends BaseServiceImpl<AgainTaskDetail> implements AgainTaskDetailService {
	@Autowired
	ModelMapper modelMapper;

	AgainTaskDetailDao dao;

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

	@Autowired
	AgainTaskDetailService againTaskDetailService;

	@Autowired
	private InputFurnaceDetailService inputFurnaceDetailService;
	@Autowired
	private InputFurnaceBurdenService inputFurnaceBurdenService;

	@Autowired
	private AgvDispatchService agvDispatchService;
	@Autowired
	private NotificationService notificationService;
	@Autowired
	StoreFeignClients storeFeignClients;
	@Autowired
	private AgainTaskService againTaskService;

	@Autowired
	@Lazy
	private MMcsInterfaceService mMcsInterfaceService;

	@Autowired
	private FillingTaskRecipeService fillingTaskRecipeService;
	@Autowired
	private ProductionCircleRecipeDetailService productionCircleRecipeDetailService;
	@Autowired
	private ProductionAgainTaskRecipeService productionAgainTaskRecipeService;

	@Autowired
	private ProductionMaterialReturnRecordService productionMaterialReturnRecordService;

	@Autowired
	private FormulaSchemeService formulaSchemeService;

	@Autowired
	private YbMesToMcsService mesToMcsService;


	@Override
	public void instoreOperation(AgainTaskInstoreDto againTaskInstoreDto) {
		AgainTaskDetail detail = get(againTaskInstoreDto.getId());
		detail.setInstoreOperatorTime(new Date());
		detail.setInstorePosCode(againTaskInstoreDto.getInstorePosCode());
		detail.setInstoreRemark(againTaskInstoreDto.getInstoreRemark());
		detail.setInstoreUserName(againTaskInstoreDto.getInstoreUserName());

		if (detail.getRawStatus().equals(AgainTaskDetailDto.rawStatus_4) || detail.getRawStatus().equals(AgainTaskDetailDto.rawStatus_3)) {
			detail.setRawStatus(AgainTaskDetailDto.rawStatus_7);
		} else {
			throw new RuntimeException("当前任务不在可操作时间段内");
		}


		try {
			AgvCallDto agvCall = new AgvCallDto();
			agvCall.setKeyword(EnumValuesAgv.AGVKeyword.复投满料.getValue());//关键字 根据配置中的信息固定写入  : 圆棒送验
			//agvCall.setStartPoint(dto.getEquipmentCode()); //起始位置编号  - 当前传入机台号
			agvCall.setStartCode(againTaskInstoreDto.getInstorePosCode());
			agvCall.setTargetPoint(againTaskInstoreDto.getEquipmentCode());
			//其他信息可根据配置信息自动填充
			String taskCode = agvDispatchService.callAgv(agvCall);
		} catch (Exception e) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			throw new RuntimeException(e.getMessage());
		}

		saveOrUpdate(detail);
	}

	@Override
	public BigDecimal getTotaGuanLiaoWeightByLotNo(String lotNo) {
		return dao.getTotaGuanLiaoWeightByLotNo(lotNo);
	}


	@Override
	public void updateInfo(AgainTaskDetailUpdate dto, List<InputFurnaceDetailDto> inputFurnaceDetailDtos) {
		AgainTaskDetail task = get(dto.getId());
		task.setEquipmentCode(dto.getEquipmentCode());
		task.setLotNo(dto.getLotNo());
		saveOrUpdate(task);

		List<InputFurnaceBurden> inputFurnaceBurdens = inputFurnaceBurdenService.findByAgainTaskDetailId(task.getId());
		for (InputFurnaceBurden inputFurnaceBurden : inputFurnaceBurdens) {
			inputFurnaceBurden.setEquipmentCode(dto.getEquipmentCode());
			inputFurnaceBurden.setLotNo(dto.getLotNo());
			inputFurnaceBurdenService.saveOrUpdate(inputFurnaceBurden);
		}


		for (InputFurnaceDetailDto inputFurnaceDetailDto : inputFurnaceDetailDtos) {
			InputFurnaceDetail detail = fromDto(inputFurnaceDetailDto);
			inputFurnaceDetailService.saveOrUpdate(detail);
		}
	}

	public InputFurnaceDetail fromDto(InputFurnaceDetailDto dto) {
		return modelMapper.map(dto, InputFurnaceDetail.class);
	}


	@Override
	public List<AgainTaskDetail> findByLotNoAndPailNum(String lotNo, String pailNum) {
		return dao.findByLotNoAndPailNum(lotNo, pailNum);
	}


	@Override
	public List<AgainTaskDetail> findByLotNoAndPailNumAndAgainNum(String lotNo, String pailNum, Integer againNum) {
		return dao.findByLotNoAndPailNumAndAgainNum(lotNo, pailNum, againNum);
	}


	@Override
	public Page<AgainTaskDetail> findByPdaPage(AgainTaskDetailDto againTaskDetailDto, Pageable page) {
		List<String> seriesList = null;
		//格式化系列
		if (!StringUtils.isBlank(againTaskDetailDto.getSeries())) {
			String[] seriesArr = againTaskDetailDto.getSeries().split(",");
			seriesList = Arrays.asList(seriesArr);
		}

		if (seriesList == null) {
			return dao.findByPdaPage(againTaskDetailDto.getEquipmentCode(), page);
		} else {
			return dao.findByPdaPage(againTaskDetailDto.getEquipmentCode(), seriesList, page);
		}


	}


	@Override
	public AgainTaskDetail getLastSuccessTask(String equipmentCode, String lotNo) {
		return dao.getLastSuccessTask(equipmentCode, lotNo);
	}

	@Override
	public List<AgainTaskDetail> findByAgainTaskId(Long againTaskId) {
		return dao.findByAgainTaskId(againTaskId);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void backTask(Long id, String cause, Integer bucket) {

		AgainTaskDetail task = this.get(id);
		// 确认投料卡控
		if (GlobalSwitch.enable(GlobalSwitchNamespace.NAMESPACE_YB_CHECK, "checkBackMaterialByConfirm", true)) {
			if (task.getConfirm() == 1) throw new RuntimeException("IPC中已确认投料，无法退料");
		}

		// 复投任务
		AgainTask againTask = againTaskService.get(task.getAgainTaskId());

		InputFurnaceBurden burden = inputFurnaceBurdenService.findTopByAgainTaskDetailId(id);
		if (task.getRawStatus().equals(AgainTaskDetailDto.rawStatus_3) || task.getRawStatus().equals(AgainTaskDetailDto.rawStatus_4) || task.getRawStatus().equals(AgainTaskDetailDto.rawStatus_7)) {
			List<InputFurnaceDetail> detailList = null;
			boolean backAll = false;
			if (bucket == 1) {
				if (burden.getLeftBack() == 1) throw new RuntimeException("左桶已退料，不能重复退料");
				if (burden.getRightBack() == 1) {
					backAll = true;
				}
				detailList = inputFurnaceDetailService.findByAgainTaskDetailIdAndBucket(id, burden.getLeftCode());

				burden.setAgainRealWeight(burden.getAgainRealWeight().subtract(burden.getLeftWeight()));
				burden.setPailNum(burden.getPailNum() - 1);
				task.setAgainRealWeight(task.getAgainRealWeight().subtract(burden.getLeftWeight()));
				task.setAlreadyPailNum(task.getAlreadyPailNum() - 1);
				againTask.setAlreadyPailNum(againTask.getAlreadyPailNum() - 1);

				burden.setLeftBack(1);
				burden.setLeftWeight(new BigDecimal(0));
			} else if (bucket == 2) {
				if (burden.getRightBack() == 1) throw new RuntimeException("右桶已退料，不能重复退料");
				if (burden.getLeftBack() == 1) {
					backAll = true;
				}
				detailList = inputFurnaceDetailService.findByAgainTaskDetailIdAndBucket(id, burden.getRightCode());

				burden.setAgainRealWeight(burden.getAgainRealWeight().subtract(burden.getRightWeight()));
				burden.setPailNum(burden.getPailNum() - 1);
				task.setAgainRealWeight(task.getAgainRealWeight().subtract(burden.getRightWeight()));
				task.setAlreadyPailNum(task.getAlreadyPailNum() - 1);
				againTask.setAlreadyPailNum(againTask.getAlreadyPailNum() - 1);

				burden.setRightBack(1);
				burden.setRightWeight(new BigDecimal(0));
			}
			if (bucket == 3 || backAll) {
				task.setRawStatus(LoadingTaskDto.rawStatus_5);
				task.setOperationCause(cause);
				task.setUserName(BaseContextHandler.getUsername());
				task.setOperationTime(new Date());
				this.saveOrUpdate(task);

				// 修改复投任务状态为退料: 所有灌料任务都为退料时，复投任务修改为退料
				List<AgainTaskDetail> taskDetailList = againTaskDetailService.findByAgainTaskId(task.getAgainTaskId());
				boolean isBackAll = true;
				for (AgainTaskDetail taskDetail : taskDetailList) {
					if (taskDetail.getRawStatus() != AgainTaskDto.rawStatus_5) {
						isBackAll = false;
						break;
					}
				}
				if (isBackAll) {
					againTask.setRawStatus(AgainTaskDto.rawStatus_5);
					againTask.setOperationCause(cause);
				}

				// 查询退料明细
				if (bucket == 3) {
					detailList = inputFurnaceDetailService.findByAgainTaskDetailId(id);
					if (StringUtils.isEmpty(burden.getLeftCode()) || StringUtils.isEmpty(burden.getRightCode())){
						task.setAlreadyPailNum(task.getAlreadyPailNum() - 1);
						againTask.setAlreadyPailNum(againTask.getAlreadyPailNum() - 1);
					}else {
						task.setAlreadyPailNum(task.getAlreadyPailNum() - 2);
						againTask.setAlreadyPailNum(againTask.getAlreadyPailNum() - 2);
					}
				}
				burden.setAgainRealWeight(new BigDecimal(0));
				burden.setPailNum(0);
				task.setAgainRealWeight(new BigDecimal(0));

				burden.setLeftBack(1);
				burden.setLeftWeight(new BigDecimal(0));
				burden.setRightBack(1);
				burden.setRightWeight(new BigDecimal(0));
			}

			inputFurnaceBurdenService.saveOrUpdate(burden);
			againTaskDetailService.saveOrUpdate(task);
			againTaskService.saveOrUpdate(againTask);

			// 解锁库存明细
			List<LockInventoryDto> unLockInventoryList = new ArrayList<>();

			// 保存退料记录
			List<ProductionMaterialReturnRecord> backList = new ArrayList<>();
			for (InputFurnaceDetail detail : detailList) {
				ProductionMaterialReturnRecord back = new ProductionMaterialReturnRecord();
				back.setTaskId(id);
				back.setTaskRecordId(detail.getId());
				back.setEquipmentNo(task.getEquipmentCode());
				back.setLotNo(task.getLotNo());
				back.setAgainNum(task.getAgainNum());
				back.setProductCode(detail.getMaterialCode());
				back.setMaterialCode(detail.getMaterialCode());
				back.setMaterialName(detail.getMaterialName());
				back.setBatchNo(detail.getBatchNo());
				back.setWeight(detail.getWeight());
				back.setMaterialTypeName(detail.getMaterialTypeName());
				back.setSupplierName(detail.getSupplierName());
				back.setInstallTime(task.getStartTime());
				back.setPailNum(task.getPailNum());
				back.setInstallUser(burden.getUserName());
				back.setSapOrderNo(burden.getSapNo());
				back.setSapProductCode(task.getProductCode());
				back.setCarrierNo(burden.getVehicleCode());
				back.setBucketNo(detail.getBucketNo());
				back.setClassNo(burden.getClassNo());
				back.setTeamGroup(burden.getTeamGroup());
				back.setCreateUser(BaseContextHandler.getUsername());
				back.setCreateTime(new Date());
				back.setReason(cause);

				backList.add(back);

				// 组织解锁库存数据
				LockInventoryDto inventory = new LockInventoryDto();
				inventory.setMaterialModelCode(detail.getMaterialCode());
				inventory.setBatchNo(detail.getBatchNo());
				inventory.setUniqueCode(detail.getUniqueCode() == null ? "" : detail.getUniqueCode());
				inventory.setWarehouseId(detail.getStoreLocationId().longValue());
				inventory.setQuantity(detail.getWeight());

				unLockInventoryList.add(inventory);
			}

			productionMaterialReturnRecordService.saveAll(backList);

			// 解锁库存
			Result result = storeFeignClients.unLockInventory(unLockInventoryList);
			if (result.getCode() != ResultCode.SUCCESS.getCode()) {
				throw new RuntimeException("线边仓解锁库存失败：" + result.getMessage());
			}

			//发送MQTT通知id
			MaterialOperationClickServiceImpl.sendAgainTaskDetailMessage(task, notificationService);

			// 删除投料记录
			for (InputFurnaceDetail detail : detailList) {
				inputFurnaceDetailService.delete(detail.getId());
			}

		} else {
			throw new RuntimeException("非取消状态无法重复叫料");
		}
	}

	@Override
	public void repeatOpenTask(Long id) {
		AgainTaskDetail task = this.get(id);
		if (task.getRawStatus().equals(AgainTaskDetailDto.rawStatus_2) || task.getRawStatus().equals(AgainTaskDetailDto.rawStatus_5)) {

			//验证是否已重新叫料
			boolean isDoubleTask = doubleTaskValidate(task);
			if (isDoubleTask) {
				throw new RuntimeException("相同炉次同一桶已存在叫料任务");
			}

			AgainTaskDetail newTask = new AgainTaskDetail(task, AgainTaskDetailDto.rawStatus_0);
			this.saveOrUpdate(newTask);

			//复投任务
			AgainTask againTask = againTaskService.get(task.getAgainTaskId());
			if (againTask.getRawStatus().equals(AgainTaskDto.rawStatus_2)){
				throw new RuntimeException("所属复投任务已取消，该灌料任务无法重新叫料");
			}

			//完成任务 - 复投任务
			if (againTask.getRawStatus().equals(AgainTaskDto.rawStatus_4)
					|| againTask.getRawStatus().equals(AgainTaskDto.rawStatus_3)
					|| againTask.getRawStatus().equals(AgainTaskDto.rawStatus_5)) {
				againTask.setRawStatus(AgainTaskDto.rawStatus_1);
			}
			againTaskService.saveOrUpdate(againTask);

			// 修改下次灌料任务的前次任务ID
			List<AgainTaskDetail> nextTaskDetailList = this.findByCarrierSort(task.getAgainTaskId(), task.getAgainNum(), (task.getCarrierSort() + 1));
			if (!CollectionUtils.isEmpty(nextTaskDetailList)){
				for (AgainTaskDetail nextTaskDetail : nextTaskDetailList) {
					nextTaskDetail.setPreDetailId(newTask.getId());
				}
				this.saveAll(nextTaskDetailList);
			}

			//下发生产任务接口
			//mMcsInterfaceService.issueMoInterface(againTask);

			//发送MQTT通知
			MaterialOperationClickServiceImpl.sendAgainTaskDetailMessage(newTask, notificationService);
		} else {
			throw new RuntimeException("非取消状态无法重复叫料");
		}
	}

	@Override
	public void cancelTask(Long id, String operationCause) {
		AgainTaskDetail entity = this.get(id);
		if (entity.getRawStatus().equals(AgainTaskDetailDto.rawStatus_0)) {
			entity.setRawStatus(AgainTaskDetailDto.rawStatus_2);
			entity.setOperationCause(operationCause);
			entity.setOperationTime(new Date());
			entity.setUserName(BaseContextHandler.getUsername());

			this.saveOrUpdate(entity);

			//复投任务
			AgainTask againTask = againTaskService.get(entity.getAgainTaskId());
			// 现场取消灌料时 赋值(新增字段)
			againTask.setCancelStatus("现场取消灌料");

			// 如果没有正常执行的灌料任务，则复投任务也取消
			List<AgainTaskDetail> againTaskDetails = findNormalTaskByAgainTaskId(againTask.getId());
			if(againTask.getRawStatus().equals(AgainTaskDto.rawStatus_1)) {
				if(CollectionUtil.isEmpty(againTaskDetails)){
					againTask.setRawStatus(AgainTaskDto.rawStatus_2);
				}
			}else {
				throw new RuntimeException("当前复投任务未处在可执行状态");
			}

			againTaskService.saveOrUpdate(againTask);
			if (GlobalSwitch.enable(GlobalSwitchNamespace.NAMESPACE_AUTOMATION, "CanningMaterial", false)) {
				//下发取消生产任务接口 装罐料下发
				mesToMcsService.cancelMoDistributionInterface(againTask);
			}

			//发送MQTT通知
			MaterialOperationClickServiceImpl.sendAgainTaskDetailMessage(entity, notificationService);
		} else {
			throw new RuntimeException("非新建状态不能取消此任务");
		}
	}

	@Override
	public List<Map<String, Object>> findInputTask(InputFurnaceBurdenExportParam param) {
		return dao.findInputTask(param.getSearch_GTE_startTime(), param.getSearch_LTE_startTime(),
				param.getSearch_EQ_rawStatus(), param.getSearch_LIKE_userName(),
				param.getSearch_EQ_lotNo(), param.getSearch_LIKE_equipmentCode());
	}

	@Override
	public RecipeDto findFillingRecipe(Long againTaskDetailId) {
		//分桶的配方方案先去查是否有保存的，没有的话组装配方
		//总方案先根据detailId找到复投任务，找到总重量按照配方获取总的分配重量再减去已经保存的
		RecipeDto recipeDto = new RecipeDto();
		List<FillingTaskRecipe> fillingTaskRecipes = fillingTaskRecipeService.findByAgainTaskDetailId(againTaskDetailId);
		List<FillingTaskVo> fillingTaskVos;
		if (fillingTaskRecipes == null || fillingTaskRecipes.size() <= 0) {
			// 获取原始配方里的
			fillingTaskVos = findByTaskRecipe(againTaskDetailId);
		} else {
			//获取已经保存的数据
			fillingTaskVos = findByFillingTaskRecipe(fillingTaskRecipes);
		}
		recipeDto.setFillingTaskVos(fillingTaskVos);
		// 获取复投任务的总配方
		AgainTaskRecipeDto AgainTaskRecipeDto = findByAgainTask(againTaskDetailId);
		recipeDto.setAgainTaskVo(AgainTaskRecipeDto);
		return recipeDto;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveFillingRecipeV1(RecipeSaveDto dtoes) {
		List<FillingTaskRecipeDto> dtos = dtoes.getFillingTaskRecipeDtos();
		if (dtos == null || dtos.size() <= 0) {
			throw new BusinessException("无数据");
		}
		Long againTaskDetailId = dtos.get(0).getAgainTaskDetailId();
		if (null == againTaskDetailId) {
			throw new BusinessException("无灌料任务id");
		}

		AgainTaskDetail againTaskDetail = this.get(againTaskDetailId);
		Long againTaskId = againTaskDetail.getAgainTaskId();
		// 根据是否有id保存复投方案
		List<ProductionAgainTaskRecipeDto> productionAgainTaskRecipeDtos = dtoes.getProductionAgainTaskRecipeDtos();
		if (productionAgainTaskRecipeDtos == null || productionAgainTaskRecipeDtos.size() <= 0) {
			throw new BusinessException("无复投配方方案！");
		} else {
			//第一次保存
			if (productionAgainTaskRecipeDtos.get(0).getId() == null) {
				List<ProductionAgainTaskRecipe> productionAgainTaskRecipeOlds = productionAgainTaskRecipeService.findByAgainTaskId(againTaskId);
				if (productionAgainTaskRecipeOlds != null && productionAgainTaskRecipeOlds.size() > 0) {
					throw new BusinessException("其他账号已保存，请刷新页面!");
				}
				//重新获取最新的剩余重量
				//resetSweight(productionAgainTaskRecipeDtos,againTaskId);
				for (ProductionAgainTaskRecipeDto dto : productionAgainTaskRecipeDtos) {
					dto.setCreateBy(BaseContextHandler.getUsername());
					dto.setCreateTime(new Date());
					dto.setAgainTaskId(againTaskId);
					ProductionAgainTaskRecipe productionAgainTaskRecipe = toLazyDto1(dto);
					productionAgainTaskRecipe.setSuppliesTypes(String.join(",", dto.getSuppliesTypeList()));
					productionAgainTaskRecipeService.saveOrUpdate(productionAgainTaskRecipe);
					//校验每一种物料有没有超出总量
					int sWeight = dto.getWeight();
					for (FillingTaskRecipeDto dto1 : dtos) {
						if (dto.getRecipeKind().equals(dto1.getRecipeKind())) {
							sWeight = sWeight - dto1.getWeight().intValue();
						}
					}
					if (sWeight < 0) {
						throw new BusinessException(dto.getSuppliesType() + "剩余重量不能为负数");
					}
				}
			}
			//只更新物料分类
			else {
				resetSweight(productionAgainTaskRecipeDtos, againTaskId);
				for (ProductionAgainTaskRecipeDto dto : productionAgainTaskRecipeDtos) {
					//校验校验每一种物料有没有超出总量
					//查看此前该灌料是否已保存过，保存过则把每个物料加上去再去减
					List<FillingTaskRecipe> fillingTaskRecipes = fillingTaskRecipeService.findByAgainTaskDetailId(againTaskDetailId);
					Integer weight = dto.getWeight1();
					if (fillingTaskRecipes != null && fillingTaskRecipes.size() > 0) {
						for (FillingTaskRecipe fto : fillingTaskRecipes) {
							if (dto.getRecipeKind().equals(fto.getRecipeKind())) {
								weight = weight + fto.getWeight().intValue();
							}
						}
					}
					for (FillingTaskRecipeDto fto : dtos) {
						if (dto.getRecipeKind().equals(fto.getRecipeKind())) {
							weight = weight - fto.getWeight().intValue();
						}
					}
					if (weight < 0) {
						throw new BusinessException(dto.getSuppliesType() + "剩余重量不能为负数!");
					}
					ProductionAgainTaskRecipe productionAgainTaskRecipeOld = productionAgainTaskRecipeService.get(dto.getId());
					productionAgainTaskRecipeOld.setSuppliesType(dto.getSuppliesType());
					productionAgainTaskRecipeService.saveOrUpdate(productionAgainTaskRecipeOld);
				}
			}
		}
		//删掉原来的，新增新的
		fillingTaskRecipeService.deleteByAgainTaskDetailId(againTaskDetailId);
		List<FillingTaskRecipe> fillingTaskRecipes = new ArrayList<>();
		for (FillingTaskRecipeDto dto : dtos) {
			dto.setId(null);
			FillingTaskRecipe entity = fromDto(dto);
			entity.setCreateBy(BaseContextHandler.getUsername());
			entity.setCreateTime(new Date());
			fillingTaskRecipes.add(entity);
		}
		fillingTaskRecipeService.saveAll(fillingTaskRecipes);
	}

	private void resetSweight(List<ProductionAgainTaskRecipeDto> productionAgainTaskRecipeDtos, Long againTaskId) {
		List<Long> againTaskDetailIds = this.findNotReturnByAgainTaskId(againTaskId);
		List<FillingTaskRecipe> fillingTaskRecipes = fillingTaskRecipeService.findByIds(againTaskDetailIds);
		for (ProductionAgainTaskRecipeDto temp : productionAgainTaskRecipeDtos) {
			BigDecimal sWeight = new BigDecimal(Integer.parseInt(temp.getWeight().toString()));
			if (fillingTaskRecipes != null && fillingTaskRecipes.size() > 0) {
				for (FillingTaskRecipe entity : fillingTaskRecipes) {
					if (entity.getSuppliesType().equals("合金") || entity.getRecipeKind() == null) {
						continue;
					}
					if (entity.getRecipeKind().equals(temp.getRecipeKind())) {
						sWeight = sWeight.subtract(entity.getWeight());
					}
				}
			}
			temp.setWeight1(sWeight.intValue());
		}
	}

	@Override
	public List<AgainTaskDetail> findByLotNoAndAgainNumAndStatus(String lotNo, Integer againNum) {
		return dao.findByLotNoAndAgainNumAndStatus(lotNo, againNum);
	}

	@Override
	public List<AgainTaskDetail> findByLotNoAndAgainNum(String lotNo, Integer againNum) {
		return dao.findByLotNoAndAgainNum(lotNo, againNum);
	}

	@Override
	public List<AgainTaskDetail> findBySapNo(String sapNo) {
		return dao.findBySapNo(sapNo);
	}

	@Override
	public List<AgainTaskDetail> findByAgainTaskIdList(List<Long> idList) {
		return dao.findByAgainTaskIdList(idList);
	}

	@Override
	public AgainTaskDetail findTopByEquipmentCodeOrderByIdDesc(String equipmentCode) {
		return dao.findTopByEquipmentCodeOrderByIdDesc(equipmentCode);
	}

	@Jinko(value = "灌料部分退料", author = "wxl")
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void materialReturn(PartReturnMaterialDto dto) {
		String reason = dto.getReason();
		List<ProductionMaterialReturnRecordDto> list = dto.getList();
		List<ProductionMaterialReturnRecord> productionMaterialReturnRecords = new ArrayList<>();
		BigDecimal allWeight = BigDecimal.ZERO;

		//1扣减配料记录2记录退料信息3生成线边仓记录4扣减总数
		if (CollectionUtil.isNotEmpty(list)) {
			for (ProductionMaterialReturnRecordDto recordDto : list) {
				//保存记录
				ProductionMaterialReturnRecord record = toLazy(recordDto);
				record.setReason(reason);
				record.setCreateTime(new Date());
				record.setCreateUser(BaseContextHandler.getUsername());
				productionMaterialReturnRecords.add(record);
				//扣减灌料料表
				InputFurnaceDetail detail = inputFurnaceDetailService.get(recordDto.getTaskRecordId());
				BigDecimal weight = detail.getWeight();
				BigDecimal weight1 = recordDto.getWeight();
				allWeight = allWeight.add(weight1);
				if (weight.compareTo(weight1) < 0) {
					throw new BusinessException("退料重量大于配料重量！");
				}
				weight = weight.subtract(weight1);
				detail.setWeight(weight);

				// 用于记录消耗
				InputFurnaceDetail consumeDetail = new InputFurnaceDetail();
				BeanUtils.copyProperties(detail, consumeDetail);

				if (weight.compareTo(BigDecimal.ZERO) == 0) {
					inputFurnaceDetailService.delete(detail.getId());
				} else {
					inputFurnaceDetailService.saveOrUpdate(detail);
					consumeDetail.setWeight(weight1);
				}
			}
		} else {
			throw new BusinessException("无数据！");
		}
		List<InputFurnaceBurden> inputFurnaceBurdens = inputFurnaceBurdenService.findByAgainTaskDetailId(list.get(0).getTaskId());
		AgainTaskDetail againTaskDetail = this.get(list.get(0).getTaskId());
		BigDecimal realWeight = againTaskDetail.getAgainRealWeight();
		realWeight = realWeight.subtract(allWeight);
		againTaskDetail.setAgainRealWeight(realWeight);
		if (realWeight.compareTo(BigDecimal.ZERO) == 0) {
			if (againTaskDetail.getRawStatus().equals(AgainTaskDetailDto.rawStatus_3) || againTaskDetail.getRawStatus().equals(AgainTaskDetailDto.rawStatus_4) || againTaskDetail.getRawStatus().equals(AgainTaskDetailDto.rawStatus_7)) {
				againTaskDetail.setRawStatus(LoadingTaskDto.rawStatus_5);
				againTaskDetail.setOperationCause(reason);
				againTaskDetail.setUserName(BaseContextHandler.getUsername());
				againTaskDetail.setOperationTime(new Date());
				//如果该复投任务的灌料任务全是退料则改成取消
				AgainTask againTask = againTaskService.get(againTaskDetail.getAgainTaskId());
				List<AgainTaskDetail> againTaskDetails = findNormalTaskByAgainTaskId(againTask.getId());
				if (CollectionUtil.isEmpty(againTaskDetails)) {
					againTask.setRawStatus(LoadingTaskDto.rawStatus_2);
					againTaskService.saveOrUpdate(againTask);
				}
			}
		}
		this.saveOrUpdate(againTaskDetail);
		if (CollectionUtil.isNotEmpty(inputFurnaceBurdens)) {
			InputFurnaceBurden burden = inputFurnaceBurdens.get(0);
			BigDecimal realWeight1 = burden.getAgainRealWeight();
			realWeight1 = realWeight1.subtract(allWeight);
			burden.setAgainRealWeight(realWeight1);
			inputFurnaceBurdenService.saveOrUpdate(burden);
		}

		//生成退料记录
		productionMaterialReturnRecordService.saveAll(productionMaterialReturnRecords);
	}

	@Jinko(value = "灌料部分退料", author = "wxl")
	@Override
	public List<ProductionMaterialReturnRecordDto> findMaterialList(Long id) {
		List<ProductionMaterialReturnRecordDto> list = new ArrayList<>();
		AgainTaskDetail againTaskDetail = this.get(id);
		String equipmentNo = againTaskDetail.getEquipmentCode();
		String lotNo = againTaskDetail.getLotNo();
		String sapNo = againTaskDetail.getSapNo();
		Integer againNum = againTaskDetail.getAgainNum();
		List<InputFurnaceDetail> inputFurnaceDetails = inputFurnaceDetailService.findByAgainTaskDetailId(id);
		List<InputFurnaceBurden> inputFurnaceBurdens = inputFurnaceBurdenService.findByAgainTaskDetailId(id);
		String userName = null;
		String carrierNo = null;
		String classNo = null;
		String teamGroup = null;
		String painNum = againTaskDetail.getPailNum();
		if (CollectionUtil.isNotEmpty(inputFurnaceBurdens)) {
			userName = inputFurnaceBurdens.get(0).getUserName();
			carrierNo = inputFurnaceBurdens.get(0).getVehicleCode();
			classNo = inputFurnaceBurdens.get(0).getClassNo();
			teamGroup = inputFurnaceBurdens.get(0).getTeamGroup();

		}
		if (CollectionUtil.isNotEmpty(inputFurnaceDetails)) {
			for (InputFurnaceDetail detail : inputFurnaceDetails) {
				ProductionMaterialReturnRecordDto dto = new ProductionMaterialReturnRecordDto();
				dto.setTaskId(id);
				dto.setTaskRecordId(detail.getId());
				dto.setEquipmentNo(equipmentNo);
				dto.setLotNo(lotNo);
				dto.setAgainNum(againNum);
				dto.setProductCode(detail.getProductCode());
				dto.setMaterialCode(detail.getMaterialCode());
				dto.setMaterialName(detail.getMaterialName());
				dto.setBatchNo(detail.getBatchNo());
				dto.setWeight(detail.getWeight());
				dto.setMaterialTypeName(detail.getMaterialTypeName());
				dto.setSupplierName(detail.getSupplierName());
				dto.setInstallTime(againTaskDetail.getEndTime());
				dto.setInstallUser(userName);
				dto.setSapOrderNo(sapNo);
				dto.setCarrierNo(carrierNo);
				dto.setBucketNo(detail.getBucketNo());
				dto.setPailNum(painNum);
				dto.setClassNo(classNo);
				dto.setTeamGroup(teamGroup);
				list.add(dto);
			}
		}
		return list;
	}

	@Override
	public AgainTaskDetail findUnconfirmedTask(String lotNo) {
		return dao.findUnconfirmedTask(lotNo);
	}

	private ProductionAgainTaskRecipe toLazyDto1(ProductionAgainTaskRecipeDto dto) {
		return modelMapper.map(dto, ProductionAgainTaskRecipe.class);
	}

	private ProductionMaterialReturnRecord toLazy(ProductionMaterialReturnRecordDto recordDto) {
		return modelMapper.map(recordDto, ProductionMaterialReturnRecord.class);
	}

	private List<AgainTaskDetail> findNormalTaskByAgainTaskId(Long id) {
		return dao.findNormalTaskByAgainTaskId(id);
	}

	private AgainTaskRecipeDto findByAgainTask(Long againTaskDetailId) {
		AgainTaskRecipeDto againTaskRecipeDto = new AgainTaskRecipeDto();
		AgainTaskDetail taskDetail = this.get(againTaskDetailId);
		Long againTaskId = taskDetail.getAgainTaskId();
		AgainTask againTask = againTaskService.get(againTaskId);
		BigDecimal weightBucket1 = againTask.getAgainWeigth();
		if (weightBucket1 == null) {
			throw new BusinessException("无复投总重量!");
		}
		Integer weightBucket = weightBucket1.intValue();
		BigDecimal syWeight = weightBucket1;
		againTaskRecipeDto.setWeight(weightBucket);
		List<ProductionBucketRecipeRecordDto> productionBucketRecipeRecordDtos = new ArrayList<>();
		//先去表里查该复投任务有没有方案/没有的话去查配料方案保存返回
		List<ProductionAgainTaskRecipe> productionAgainTaskRecipes = productionAgainTaskRecipeService.findByAgainTaskId(againTaskId);
		if (productionAgainTaskRecipes == null || productionAgainTaskRecipes.size() <= 0) {
			Long recipeId = taskDetail.getRecipeId();
			Integer againNum = taskDetail.getAgainNum();
			List<ProductionCircleRecipeDetail> productionCircleRecipeDetails;
			//是不是完结复投
			if (taskDetail.getIsDone() == 1) {
				productionCircleRecipeDetails = productionCircleRecipeDetailService.getProductionRecipeDetailsByParam(recipeId, "0");
			} else {
				productionCircleRecipeDetails = productionCircleRecipeDetailService.getProductionRecipeDetailsByParam(recipeId, "%" + againNum.toString() + "%");
			}
			Map<String, List<ProductionCircleRecipeDetail>> map1 = productionCircleRecipeDetails.stream().collect(Collectors.groupingBy(ProductionCircleRecipeDetail::getRecipeKind));
			Set set = map1.keySet();
			Iterator iterator = set.iterator();
			while (iterator.hasNext()) {
				String key = iterator.next().toString();
				List<ProductionCircleRecipeDetail> entitys = map1.get(key);
				List<ProductionCircleRecipeDetailDto> dtos = entitys.stream().map(temp -> modelMapper.map(temp, ProductionCircleRecipeDetailDto.class)).collect(Collectors.toList());
				if (dtos != null && dtos.size() > 0) {
					if (dtos.get(0).getWeightRatio() != 0) {
						ProductionCircleRecipeDetailDto temp = dtos.get(0);
						ProductionBucketRecipeRecordDto dto = new ProductionBucketRecipeRecordDto();
						Integer weightRatio = temp.getWeightRatio();
						Map<String, Integer> map = calculateWeight(weightRatio, weightBucket);
						dto.setWeight(map.get("weight"));
						dto.setWeight1(map.get("weight"));
						dto.setBucketForty(map.get("bucketForty"));
						dto.setBucketTen(map.get("bucketTen"));
						//dto.setId(temp.getId());
						dto.setRecipeKind(temp.getRecipeKind());
						dto.setSuppliesName(temp.getSuppliesName());
						dto.setSuppliesType(temp.getSuppliesType());
						dto.setSuppliesCode(temp.getSuppliesCode());
						dto.setSuppliesResistanceMax(temp.getSuppliesResistanceMax());
						dto.setSuppliesResistanceMin(temp.getSuppliesResistanceMin());
						dto.setSuppliesDopant(temp.getSuppliesDopant());
						List<String> suppliesTypes = dtos.stream().map(t -> t.getSuppliesType()).collect(Collectors.toList());
						dto.setSuppliesTypeList(suppliesTypes);
						productionBucketRecipeRecordDtos.add(dto);
					}
				}
			}
		}
		//有方案的话查出来减掉未退料的
		else {
			List<Long> againTaskDetailIds = this.findNotReturnByAgainTaskId(againTaskId);
			List<FillingTaskRecipe> fillingTaskRecipes = fillingTaskRecipeService.findByIds(againTaskDetailIds);
			for (ProductionAgainTaskRecipe temp : productionAgainTaskRecipes) {
				ProductionBucketRecipeRecordDto dto = new ProductionBucketRecipeRecordDto();
				String suppliesTypes = temp.getSuppliesTypes();
				List<String> suppliesTypeList = new ArrayList<>();
				if (suppliesTypes != null) {
					suppliesTypeList = Arrays.asList(suppliesTypes.split(","));
				}
				dto.setSuppliesTypeList(suppliesTypeList);
				dto.setId(temp.getId().intValue());
				dto.setRecipeKind(temp.getRecipeKind());
				dto.setSuppliesName(temp.getSuppliesName());
				dto.setSuppliesType(temp.getSuppliesType());
				BigDecimal sWeight = temp.getWeight();
				dto.setWeight(temp.getWeight().intValue());
				if (fillingTaskRecipes != null && fillingTaskRecipes.size() > 0) {
					for (FillingTaskRecipe entity : fillingTaskRecipes) {
						if (entity.getSuppliesType().equals("合金") || entity.getRecipeKind() == null) {
							continue;
						}
						if (entity.getRecipeKind().equals(temp.getRecipeKind())) {
							sWeight = sWeight.subtract(entity.getWeight());
						}
					}
				}
				dto.setWeight1(sWeight.intValue());
				Map<String, Integer> map = calculateWeight1(sWeight);
				dto.setBucketForty(map.get("bucketForty"));
				dto.setBucketTen(map.get("bucketTen"));
				productionBucketRecipeRecordDtos.add(dto);
			}
			if (fillingTaskRecipes != null && fillingTaskRecipes.size() > 0) {
				for (FillingTaskRecipe entity : fillingTaskRecipes) {
					if (entity.getSuppliesType().equals("合金") || entity.getRecipeKind() == null) {
						continue;
					}
					syWeight = syWeight.subtract(entity.getWeight());
				}
			}
		}
		againTaskRecipeDto.setSWeight(syWeight.intValue());
		againTaskRecipeDto.setProductionBucketRecipeRecordDtos(productionBucketRecipeRecordDtos);
		return againTaskRecipeDto;
	}

	private Map<String, Integer> calculateWeight1(BigDecimal value) {
		Map<String, Integer> map = new HashMap<>();
		BigDecimal[] result1 = value.divideAndRemainder(new BigDecimal("40"));
		Integer bucketForty = result1[0].intValue();
		BigDecimal remainder = result1[1];
		BigDecimal[] result2 = remainder.divideAndRemainder(new BigDecimal("10"));
		Integer bucketTen = result2[0].intValue();
		map.put("bucketForty", bucketForty);
		map.put("bucketTen", bucketTen);
		return map;
	}

	private List<Long> findNotReturnByAgainTaskId(Long againTaskId) {
		return dao.findNotReturnByAgainTaskId(againTaskId);
	}

	private List<FillingTaskVo> findByFillingTaskRecipe(List<FillingTaskRecipe> fillingTaskRecipes) {
		List<FillingTaskRecipeDto> fillingTaskRecipeDtos = new ArrayList<>();
		for (FillingTaskRecipe entity : fillingTaskRecipes) {
			FillingTaskRecipeDto dto = toLazyDto(entity);
			fillingTaskRecipeDtos.add(dto);
		}
		List<FillingTaskVo> fillingTaskVos = new ArrayList<>();
		List<FillingTaskRecipeDto> fillingTaskRecipeDtos1 = new ArrayList<>();
		//合金
		FillingTaskVo fillingTaskVo1 = new FillingTaskVo();
		fillingTaskVo1.setAlloyName("合金");
		for (FillingTaskRecipeDto entity : fillingTaskRecipeDtos) {
			if (entity.getSuppliesType().contains("合金")) {
				fillingTaskVo1.setAlloyName(entity.getSuppliesType());
				fillingTaskVo1.setAlloyWeight(entity.getWeight());
			} else {
				fillingTaskRecipeDtos1.add(entity);
			}
		}
		fillingTaskVos.add(fillingTaskVo1);
		Map<Integer, List<FillingTaskRecipeDto>> stringListMap = fillingTaskRecipeDtos1.stream().collect(Collectors.groupingBy(entity -> entity.getBucketNum()));
		Set set = stringListMap.keySet();
		Iterator iterator = set.iterator();
		while (iterator.hasNext()) {
			Integer key = Integer.valueOf(iterator.next().toString());
			List<FillingTaskRecipeDto> fillingTaskRecipeDtoList = stringListMap.get(key);
			FillingTaskVo fillingTaskVo = new FillingTaskVo();
			fillingTaskVo.setWeight(fillingTaskRecipeDtoList.get(0).getGross());
			fillingTaskVo.setProductionBucketRecipeRecordDtos(fillingTaskRecipeDtoList);
			fillingTaskVos.add(fillingTaskVo);
		}
		return fillingTaskVos;
	}

	private List<FillingTaskVo> findByTaskRecipe(Long againTaskDetailId) {
		List<FillingTaskVo> fillingTaskVos = new ArrayList<>();
		AgainTaskDetail taskDetail = this.get(againTaskDetailId);
		Long recipeId = taskDetail.getRecipeId();
		Integer againNum = taskDetail.getAgainNum();
		List<ProductionCircleRecipeDetail> productionCircleRecipeDetails;
		//是不是完结复投
		if (taskDetail.getIsDone() == 1) {
			productionCircleRecipeDetails = productionCircleRecipeDetailService.getProductionCircleRecipeDetailsByParamAccurate(recipeId, "0");
		} else {
			productionCircleRecipeDetails = productionCircleRecipeDetailService.getProductionCircleRecipeDetailsByParam(recipeId, "%" + againNum.toString() + "%");
		}
		if (null == productionCircleRecipeDetails || productionCircleRecipeDetails.size() <= 0) {
			throw new BusinessException("该产品未绑定产品配方");
		}
		Map<String, List<ProductionCircleRecipeDetail>> map1 = productionCircleRecipeDetails.stream().collect(Collectors.groupingBy(ProductionCircleRecipeDetail::getRecipeKind));
		String weight = taskDetail.getTaskWeigths();
		String painNum = taskDetail.getPailNum();
		String[] weights = weight.split(",");
		String[] painNums = painNum.split(",");
		for (int i = 0; i < weights.length; i++) {
			Integer weightBucket = Integer.valueOf(weights[i]);
			Integer bucketNum = Integer.valueOf(painNums[i]);
			Set set = map1.keySet();
			Iterator iterator = set.iterator();
			FillingTaskVo fillingTaskVo = new FillingTaskVo();
			List<FillingTaskRecipeDto> fillingTaskRecipeDtoList = new ArrayList<>();
			fillingTaskVo.setWeight(weightBucket);
			while (iterator.hasNext()) {
				String key = iterator.next().toString();
				List<ProductionCircleRecipeDetail> entitys = map1.get(key);
				List<ProductionCircleRecipeDetailDto> dtos = entitys.stream().map(temp -> modelMapper.map(temp, ProductionCircleRecipeDetailDto.class)).collect(Collectors.toList());
				if (dtos != null && dtos.size() > 0) {
					ProductionCircleRecipeDetailDto dto1 = dtos.get(0);
					if (dto1.getWeightRatio() == 0) {
						continue;
					}
					FillingTaskRecipeDto fillingTaskRecipeDto = new FillingTaskRecipeDto();
					fillingTaskRecipeDto.setWeight(BigDecimal.ZERO);
					fillingTaskRecipeDto.setBucketForty(0);
					fillingTaskRecipeDto.setBucketTen(0);
					fillingTaskRecipeDto.setRecipeKind(dto1.getRecipeKind());
					fillingTaskRecipeDto.setSuppliesName(dto1.getSuppliesName());
					fillingTaskRecipeDto.setSuppliesType(dto1.getSuppliesType());
					fillingTaskRecipeDto.setBucketNum(bucketNum);
					fillingTaskRecipeDto.setSuppliesCode(dto1.getSuppliesCode());
					fillingTaskRecipeDto.setSuppliesResistanceMax(dto1.getSuppliesResistanceMax());
					fillingTaskRecipeDto.setSuppliesResistanceMin(dto1.getSuppliesResistanceMin());
					fillingTaskRecipeDto.setSuppliesDopant(dto1.getSuppliesDopant());
					fillingTaskRecipeDtoList.add(fillingTaskRecipeDto);
				}
			}
			fillingTaskVo.setProductionBucketRecipeRecordDtos(fillingTaskRecipeDtoList);
			fillingTaskVos.add(fillingTaskVo);
		}
		//如果之前保存过复投任务配方，显示更改后的物料种类
		List<ProductionAgainTaskRecipe> productionAgainTaskRecipes = productionAgainTaskRecipeService.findByAgainTaskId(taskDetail.getAgainTaskId());
		if (productionAgainTaskRecipes != null && productionAgainTaskRecipes.size() > 0) {
			for (ProductionAgainTaskRecipe po : productionAgainTaskRecipes) {
				if (fillingTaskVos != null && fillingTaskVos.size() > 0) {
					for (FillingTaskVo vo : fillingTaskVos) {
						List<FillingTaskRecipeDto> productionBucketRecipeRecordDtos = vo.getProductionBucketRecipeRecordDtos();
						if (productionBucketRecipeRecordDtos != null && productionBucketRecipeRecordDtos.size() > 0) {
							for (FillingTaskRecipeDto dto : productionBucketRecipeRecordDtos) {
								if (dto.getRecipeKind() != null && dto.getRecipeKind().equals(po.getRecipeKind())) {
									dto.setSuppliesType(po.getSuppliesType());
								}
							}
						}
					}
				}
			}
		}
		return fillingTaskVos;
	}

	public FillingTaskRecipeDto toLazyDto(FillingTaskRecipe entity) {
		return modelMapper.map(entity, FillingTaskRecipeDto.class);
	}

	private Map<String, Integer> calculateWeight(Integer weightRatio, Integer weightBucket) {
		Map<String, Integer> map = new HashMap<>();
		//总重
		BigDecimal weightBucket1 = new BigDecimal(Integer.parseInt(weightBucket.toString()));
		//比例
		BigDecimal ratio = new BigDecimal(Integer.parseInt(weightRatio.toString()));
		BigDecimal tempRatio = ratio.divide(new BigDecimal("1000"));
		//算出配料重量(五舍六入)
		BigDecimal weight = weightBucket1.multiply(tempRatio).setScale(0, BigDecimal.ROUND_HALF_DOWN).multiply(new BigDecimal("10"));
		//取余
		BigDecimal[] result1 = weight.divideAndRemainder(new BigDecimal("40"));
		Integer bucketForty = Integer.parseInt(result1[0].toString());
		BigDecimal remainder = result1[1];
		BigDecimal[] result2 = remainder.divideAndRemainder(new BigDecimal("10"));
		Integer bucketTen = Integer.parseInt(result2[0].toString());
		map.put("weight", Integer.parseInt(weight.toString()));
		map.put("bucketForty", bucketForty);
		map.put("bucketTen", bucketTen);
		return map;
	}

	public FillingTaskRecipe fromDto(FillingTaskRecipeDto dto) {
		return modelMapper.map(dto, FillingTaskRecipe.class);
	}


	/**
	 * 多次叫料验证
	 **/
	private boolean doubleTaskValidate(AgainTaskDetail task) {
		boolean isDoubleTask = false;
		List<AgainTaskDetail> allLotNoTask = this.findByLotNoAndPailNumAndAgainNum(task.getLotNo(), task.getPailNum(), task.getAgainNum());
		for (AgainTaskDetail againDetaiTask : allLotNoTask) {
			if (!againDetaiTask.getRawStatus().equals(AgainTaskDetailDto.rawStatus_2) && !againDetaiTask.getRawStatus().equals(AgainTaskDetailDto.rawStatus_5)) {
				isDoubleTask = true;
				break;
			}
		}
		return isDoubleTask;
	}

	@Override
	public AgainTaskDetail findSuccessByLotNo(String lotNo) {
		return dao.findSuccessByLotNo(lotNo);
	}

	@Override
	public IngredientInfoDto findIngredientInfoById(Long id) {
		AgainTaskDetail againTaskDetailDb = againTaskDetailService.get(id);
		Assert.notNull(againTaskDetailDb, "灌料任务不存在");
//            灌料记录
		List<InputFurnaceBurden> inputFurnaceBurdenList = inputFurnaceBurdenService.findByAgainTaskDetailId(againTaskDetailDb.getId());
		Assert.isTrue(!CollectionUtils.isEmpty(inputFurnaceBurdenList), "灌料记录不存在");
		InputFurnaceBurden inputFurnaceBurdenDb = inputFurnaceBurdenList.stream()
				.max(Comparator.comparing(InputFurnaceBurden::getId)).
				orElse(null);
		Assert.notNull(inputFurnaceBurdenDb, "灌料记录不存在");
		return buildAgainTaskTaskIngredientInfoDto(againTaskDetailDb, inputFurnaceBurdenDb);
	}

	@Override
	public List<Map<String, Object>> findTaskAndDetails(InputFurnaceBurdenExportParam param) {
		return dao.findTaskAndDetails(
				param.getSearch_GTE_startTime(),
				param.getSearch_LTE_startTime(),
				param.getSearch_LIKE_equipmentCode(),
				param.getSearch_EQ_lotNo()
		);
	}

	@Override
	public BigDecimal findAgainSumWeightBySapNoAndInRawStatus(String orderNo) {
		return dao.findAgainSumWeightBySapNoAndInRawStatus(orderNo);
	}

	@Override
	public BigDecimal findTotalSumWeightBySapNoAndInRawStatus(String orderNo) {
		return dao.findTotalSumWeightBySapNoAndInRawStatus(orderNo);
	}

	@Override
	public AgainTaskDetail findByAgainTaskIdAndFillEndAndAgainNum(Long againTaskId,Integer againNum) {
		return dao.findByAgainTaskIdAndFillEndAndAgainNum(againTaskId,1,againNum);
	}

	@Override
	public List<AgainTaskDetail> findByAgainTaskAndPreDetailId(Long againTaskId, Long preDetailId) {
		return dao.findByAgainTaskAndPreDetailId(againTaskId, preDetailId);
	}

	@Override
	public List<AgainTaskDetail> findByCarrierSort(Long againTaskId, Integer againNum, Integer carrierSort) {
		return dao.findByCarrierSort(againTaskId, againNum, carrierSort);
	}

	@Override
	public String checkTaskOrder(Long id) {
		AgainTaskDetail againTaskDetail = againTaskDetailService.get(id);
		if (GlobalSwitch.enable(GlobalSwitchNamespace.NAMESPACE_YB_CHECK, "checkInputMaterialOrder", false)
			&& !ObjectUtils.isEmpty(againTaskDetail)
			&& againTaskDetail.getCarrierSort() >= 2){

			AgainTaskDetail preTaskDetail = againTaskDetailService.get(againTaskDetail.getPreDetailId());
			if(!ObjectUtils.isEmpty(preTaskDetail)
				&& !preTaskDetail.getRawStatus().equals(AgainTaskDetailDto.rawStatus_3)
				&& !preTaskDetail.getRawStatus().equals(AgainTaskDetailDto.rawStatus_4)) {

				return "请先完成前次【"+preTaskDetail.getPailNum()+"】桶的灌料任务";
			}
		}
		return null;
	}


	/**
	 * 构建灌料任务信息
	 */
	private IngredientInfoDto buildAgainTaskTaskIngredientInfoDto(AgainTaskDetail againTaskDetailDb, InputFurnaceBurden inputFurnaceBurdenDb) {
		ArrayList<FeedingInformationDto> informationDtoArrayList = new ArrayList<>();
		FormulaScheme formulaScheme = null;
		IngredientInfoDto ingredientInfoDto = new IngredientInfoDto();
		ingredientInfoDto.setIngredientUser(inputFurnaceBurdenDb.getUserName());
		ingredientInfoDto.setIngredientDate(inputFurnaceBurdenDb.getStartTime());
		ingredientInfoDto.setMissionType(inputFurnaceBurdenDb.getAgainNum() + "次复投");
		ingredientInfoDto.setArea(inputFurnaceBurdenDb.getArea());
		ingredientInfoDto.setEquipmentCode(inputFurnaceBurdenDb.getEquipmentCode());
		if (Objects.nonNull(againTaskDetailDb.getRecipeId())) {
			formulaScheme = formulaSchemeService.get(againTaskDetailDb.getRecipeId());
		}
		if (Objects.nonNull(formulaScheme) && Objects.nonNull(formulaScheme.getId())) {
			ingredientInfoDto.setProcessPlan(formulaScheme.getName());
		}
		List<InputFurnaceDetail> inputFurnaceDetailList = inputFurnaceDetailService.findByAgainTaskDetailId(againTaskDetailDb.getId());
		if (!CollectionUtils.isEmpty(inputFurnaceDetailList)) {
			Map<String, List<InputFurnaceDetail>> listMap = inputFurnaceDetailList.stream()
					.collect(Collectors.groupingBy(InputFurnaceDetail::getBucketNo));
			BigDecimal totalWeight = inputFurnaceDetailList.stream()
					.map(InputFurnaceDetail::getWeight)
					.reduce(BigDecimal.ZERO, BigDecimal::add);
			for (InputFurnaceDetail inputFurnaceDetail : inputFurnaceDetailList) {
				List<InputFurnaceDetail> inputFurnaceDetailList1 = listMap.get(inputFurnaceDetail.getBucketNo());
				Integer barrelCount = 0;
				if (!CollectionUtils.isEmpty(inputFurnaceDetailList1)) {
					barrelCount++;
					for (InputFurnaceDetail furnaceDetail : inputFurnaceDetailList1) {
						FeedingInformationDto feedingInformationDto = new FeedingInformationDto();
						feedingInformationDto.setBarrelCount(barrelCount);
						feedingInformationDto.setBarrelNumber(furnaceDetail.getBucketNo());
						feedingInformationDto.setMaterialCode(furnaceDetail.getMaterialCode());
						feedingInformationDto.setMaterialName(furnaceDetail.getMaterialName());
						feedingInformationDto.setSupplier(furnaceDetail.getFactoryBrand());
						feedingInformationDto.setBatchNumber(furnaceDetail.getBatchNo());
						feedingInformationDto.setWeight(furnaceDetail.getWeight());
						feedingInformationDto.setTotalWeight(totalWeight);
						informationDtoArrayList.add(feedingInformationDto);
					}
				}
			}
			ingredientInfoDto.setFeedingInformationDtoList(informationDtoArrayList);
		}
		return ingredientInfoDto;
	}
}
