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


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

import cn.hutool.core.collection.CollectionUtil;
import com.sw.mes.base.factory.material.entity.MaterialModel;
import com.sw.mes.base.factory.material.service.MaterialModelService;
import com.sw.mes.base.factory.product.service.NewProductModelService;
import com.sw.mes.base.global.GlobalSwitch;
import com.sw.mes.base.global.GlobalSwitchNamespace;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.core.api.system.StoreFeignClients;
import com.sw.mes.core.dto.WarehouseModelDto;
import com.sw.mes.core.dto.store.*;
import com.sw.mes.core.enums.SeedMassageEnum;
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.dingTalk.service.DingTalkService;
import com.sw.mes.production.entity.FormulaMaterialClass;
import com.sw.mes.production.service.FormulaMaterialClassService;
import com.sw.mes.redis.server.RedisUtils;
import com.sw.mes.sap.entity.ReportSapGoodsmvt;
import com.sw.mes.sap.service.ReportSapGoodsmvtService;
import com.sw.mes.utils.StringUtils;
import com.sw.mes.yb.production.entity.*;
import com.sw.mes.yb.production.service.*;
import lombok.extern.slf4j.Slf4j;
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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.mmcs.service.MMcsInterfaceService;
import com.sw.mes.yb.production.dao.InputFurnaceBurdenDao;
import com.sw.mes.yb.production.dto.InputFurnaceDetailDto;
import com.sw.mes.yb.production.dto.AgainTask.AgainTaskDto;
import com.sw.mes.yb.production.dto.AgainTaskDetail.AgainTaskDetailDto;
import com.sw.mes.yb.production.dto.InputFurnaceBurden.InputFurnaceBurdenDto;
import org.springframework.util.ObjectUtils;


/**
* @Author
* @Description：
* @Date: Create in
* @Modified By:
*/
@Slf4j
@Service
@Transactional
public class InputFurnaceBurdenServiceImpl extends BaseServiceImpl<InputFurnaceBurden> implements InputFurnaceBurdenService {

	private final static String BurdenKey = "six_burden_task_";

	@Autowired
	ModelMapper modelMapper;

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

	@Autowired
	private AgainTaskDetailService againTaskDetailService;
	@Autowired
	private AgainTaskService againTaskService;
	@Autowired
	private InputFurnaceDetailService inputFurnaceDetailService;

	@Autowired
	@Lazy
	private MMcsInterfaceService mMcsInterfaceService;

	@Autowired
	private RedisUtils redisUtils;
	@Autowired
	private ProductionCircleRecipeDetailService productionCircleRecipeDetailService;
	@Autowired
	private StoreFeignClients storeFeignClients;

	@Autowired
	private DictionaryItemService dictionaryItemService;

	@Autowired
	private MaterialModelService materialModelService;

	@Autowired
	private ReportSapGoodsmvtService reportSapGoodsmvtService;

	@Autowired
	private DingTalkService dingTalkService;

	@Autowired
	private ProductionFurnaceMaterialSplitService splitService;

	@Autowired
	private FormulaMaterialClassService formulaMaterialClassService;

	@Autowired
	private NewProductModelService newProductModelService;


	@Override
	public InputFurnaceBurdenDto getStartInfo(Long againTaskDetailId) {
		try {
			InputFurnaceBurdenDto data = (InputFurnaceBurdenDto) redisUtils.get(BurdenKey+""+againTaskDetailId);
			return data;
		}catch (Exception e) {
			return null;
		}
	}


	@Override
	public void startInputFurnace(InputFurnaceBurdenDto inputFurnaceBurdenDto) {
		//桶任务 - 灌料任务
		AgainTaskDetail againTaskDetail = againTaskDetailService.get(inputFurnaceBurdenDto.getAgainTaskDetailId());
//		AgainTask againTask = againTaskService.get(againTaskDetail.getAgainTaskId());
		if(againTaskDetail.getRawStatus().equals(AgainTaskDetailDto.rawStatus_0)) {
			againTaskDetail.setRawStatus(AgainTaskDetailDto.rawStatus_1);
		}else {
			throw new RuntimeException("当前任务未处在可执行状态");
		}

		List<InputFurnaceDetailDto> detailDto = inputFurnaceBurdenDto.getDetails();
		List<String> bucketBatchNos = new ArrayList<>();
		for (InputFurnaceDetailDto inputFurnaceDetailDto : detailDto) {
			String bucketBatchNo = inputFurnaceDetailDto.getBucketNo() +"-"+ inputFurnaceDetailDto.getBatchNo();
			BigDecimal weightD = inputFurnaceDetailDto.getWeight();
			if(weightD == null || weightD.compareTo(BigDecimal.ZERO) <= 0 ){
				throw new RuntimeException("重量不允许为0或者负数");
			}
			if(bucketBatchNos.contains(bucketBatchNo)){
				throw new RuntimeException("物料有重复，请检查！");
			}
			bucketBatchNos.add(bucketBatchNo);
		}

		//校验物料类型是否在方案内
//		List<InputFurnaceDetailDto> detailDtos = inputFurnaceBurdenDto.getDetails();
//		List<String> materialTypeNames = detailDtos.stream().map(temp->temp.getMaterialTypeName()).distinct().collect(Collectors.toList());
//		if(null == materialTypeNames||materialTypeNames.isEmpty()){
//			throw new RuntimeException("未查询到物料");
//		}
//		Long recipeId = againTaskDetail.getRecipeId();
//		Integer againNum = againTaskDetail.getAgainNum();
//		List <String> recipeMaterialTypeNames;
//		//是不是完结复投
//		if(againTaskDetail.getIsDone() == 1){
//			recipeMaterialTypeNames = productionCircleRecipeDetailService.getRecipeMaterialTypeNamesByParamAccurate(recipeId,"0");
//		}else {
//			recipeMaterialTypeNames = productionCircleRecipeDetailService.getRecipeMaterialTypeNamesByParam(recipeId, "%" + againNum.toString() + "%");
//		}
//		if(null == materialTypeNames||materialTypeNames.isEmpty()){
//			throw new RuntimeException("未查询到物料");
//		}
//		if(!recipeMaterialTypeNames.containsAll(materialTypeNames)){
//			throw new RuntimeException("投放的物料类型不在物料方案内，请检查");
//		}

		//校验箱数总量是否等于总重量
//		Integer bucketFortyCount = detailDtos.stream().mapToInt(temp->Optional.ofNullable(temp.getBucketForty()).orElse(0)).sum();
//		Integer bucketTenCount = detailDtos.stream().mapToInt(temp->Optional.ofNullable(temp.getBucketTen()).orElse(0)).sum();
//		Integer sum = bucketFortyCount*40 + bucketTenCount*10;
//		if(new BigDecimal(sum).compareTo(inputFurnaceBurdenDto.getWeigth()) != 0){
//			throw new RuntimeException("投放的总量与需要投放的总量不相等，请检查");
//		}
		againTaskDetail.setStartTime(new Date());

		againTaskDetailService.saveOrUpdate(againTaskDetail);

		//复投任务

//		Integer pailNum = againTask.getPailNum();
//		pailNum = pailNum==null?0:pailNum;
//		againTask.setPailNum((int)(pailNum+againTaskDetail.getNum()));//当前桶数
//
//		againTaskService.saveOrUpdate(againTask);

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

		//开始灌料缓存参数
		redisUtils.set(BurdenKey+""+inputFurnaceBurdenDto.getAgainTaskDetailId(), inputFurnaceBurdenDto);
	}


	@Override
	public void cancelInputFurnace(Long againTaskDetailId) {
		//桶任务 - 灌料任务
		AgainTaskDetail againTaskDetail = againTaskDetailService.get(againTaskDetailId);
		if(againTaskDetail.getRawStatus().equals(AgainTaskDetailDto.rawStatus_1)) {
			againTaskDetail.setRawStatus(AgainTaskDetailDto.rawStatus_0);
		}else {
			throw new RuntimeException("当前任务未处在生产状态");
		}


		againTaskDetailService.saveOrUpdate(againTaskDetail);

		//复投任务
		AgainTask againTask = againTaskService.get(againTaskDetail.getAgainTaskId());
		Integer pailNum = againTask.getPailNum();
		pailNum = pailNum==null?0:pailNum;
		againTask.setPailNum((int)(againTaskDetail.getNum()-pailNum));//当前桶数
		againTaskService.saveOrUpdate(againTask);

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

		//删除redis中填写数据信息
		redisUtils.remove(BurdenKey+""+againTaskDetailId);
	}


	@Override
	public void back(InputFurnaceBurdenDto inputFurnaceBurdenDto) {
		//开始灌料缓存参数
		redisUtils.set(BurdenKey+""+inputFurnaceBurdenDto.getAgainTaskDetailId(), inputFurnaceBurdenDto);
	}



	@Override
	@Transactional(rollbackFor = Exception.class)
	public void endInputFurnace(InputFurnaceBurdenDto inputFurnaceBurdenDto,Integer rawStatus,String operationName) {
		//桶任务 - 灌料任务
		AgainTaskDetail againTaskDetail = againTaskDetailService.get(inputFurnaceBurdenDto.getAgainTaskDetailId());
		if(inputFurnaceBurdenDto.getUserName() == null){
			inputFurnaceBurdenDto.setUserName(operationName);
		}
		if(againTaskDetail.getRawStatus().equals(AgainTaskDetailDto.rawStatus_1)||againTaskDetail.getRawStatus().equals(AgainTaskDetailDto.rawStatus_0)) {
			againTaskDetail.setRawStatus(rawStatus);
		}else {
			throw new RuntimeException("当前任务未处在可执行状态");
		}

		// 按照桶顺序灌料
		String checkTaskOrder = againTaskDetailService.checkTaskOrder(againTaskDetail.getId());
		if(StringUtils.isNotBlank(checkTaskOrder)) {
			throw new RuntimeException(checkTaskOrder);
		}

		// 物料分类及重量卡控
		if (GlobalSwitch.enable(GlobalSwitchNamespace.NAMESPACE_YB_CHECK, "checkMaterialClassAndWeight", false)){
			List<InputFurnaceDetailDto> detailDtoList = inputFurnaceBurdenDto.getDetails();
			for (InputFurnaceDetailDto detailDto : detailDtoList) {
				if (ObjectUtils.isEmpty(detailDto.getBucketIndex())){
					throw new RuntimeException("桶序号不能为空");
				}
			}
			// 根据桶序号分类
			Map<Integer, List<InputFurnaceDetailDto>> bucketIndexListMap = detailDtoList.stream().collect(Collectors.groupingBy(InputFurnaceDetailDto::getBucketIndex));
			// 分桶校验
			for (Integer bucketIndex : bucketIndexListMap.keySet()) {
				List<ProductionFurnaceMaterialSplit> splitList = splitService.findByBucketIndex(againTaskDetail.getAgainTaskId(), againTaskDetail.getAgainNum(), bucketIndex);
				if (CollectionUtil.isEmpty(splitList)){
					throw new RuntimeException("未查询到关联的桶分解数据");
				}
				// 分桶数据分类重量
				Map<String, BigDecimal> classNameWeightMap = splitList.stream().collect(Collectors.toMap(ProductionFurnaceMaterialSplit::getMaterialClassName, ProductionFurnaceMaterialSplit::getMaterialWeight));
				// 投料数据分类重量
				Map<String, BigDecimal> inputClassNameWeightMap = new HashMap<>();
				List<InputFurnaceDetailDto> bucketDtoList = bucketIndexListMap.get(bucketIndex);
				for (InputFurnaceDetailDto detailDto : bucketDtoList) {
					// 物料对应的分类集合
					List<FormulaMaterialClass> materialClassList = formulaMaterialClassService.findFormulaMaterialClassByMaterialCode(detailDto.getMaterialCode());
					if (CollectionUtil.isEmpty(materialClassList)){
						throw new RuntimeException("物料【"+detailDto.getMaterialCode()+"】未查询到关联的物料分类");
					}
					Set<String> materialClassNameSet = materialClassList.stream().map(FormulaMaterialClass::getName).collect(Collectors.toSet());

					// 判断分类是否存在，存在则设置重量
					boolean containSign = false;
					for (String materialClassName : materialClassNameSet) {
						if (ObjectUtils.isEmpty(classNameWeightMap.get(materialClassName))) continue;
						inputClassNameWeightMap.put(materialClassName, detailDto.getWeight());
						containSign = true;
					}

					if (!containSign){
						throw new RuntimeException("物料【"+detailDto.getMaterialCode()+"】所属分类【"+StringUtils.join(materialClassNameSet, ",")+"】不在桶数序号【"+detailDto.getBucketIndex()+"】的物料搭配中");
					}
				}

				// 检查重量
				for (String cns : classNameWeightMap.keySet()) {
					BigDecimal inputWeight = inputClassNameWeightMap.get(cns);
					if (ObjectUtils.isEmpty(inputWeight)){
						throw new RuntimeException("物料搭配：桶序号【"+bucketIndex+"】物料分类【"+cns+"】没有实际投料");
					}
					if (classNameWeightMap.get(cns).compareTo(inputWeight) != 0){
						throw new RuntimeException("物料搭配：桶序号【"+bucketIndex+"】物料分类【"+cns+"】的搭配重量与实际投料重量不一致");
					}
				}
			}
		}

		// 更新灌料任务
		againTaskDetail.setCarrierNo(inputFurnaceBurdenDto.getVehicleCode());
		againTaskDetail.setAlreadyPailNum(inputFurnaceBurdenDto.getPailNum());
		againTaskDetail.setStartTime(inputFurnaceBurdenDto.getStartTime());
		againTaskDetail.setEndTime(inputFurnaceBurdenDto.getEndTime());
		againTaskDetail.setUserName(inputFurnaceBurdenDto.getUserName());
		againTaskDetail.setAgainRealWeight(inputFurnaceBurdenDto.getAgainRealWeight());
		if (againTaskDetail.getAgainRealWeight().compareTo(againTaskDetail.getAgainWeigth()) > 0){
			throw new RuntimeException("实际灌料重量不能大于当前复投重量！");
		}
		// 实际投料与复投重量一致
		if (GlobalSwitch.enable(GlobalSwitchNamespace.NAMESPACE_YB_CHECK, "checkInputAllWeightMaterial", false)
			&& againTaskDetail.getAgainRealWeight().compareTo(againTaskDetail.getAgainWeigth()) != 0) {
			throw new RuntimeException("实际灌料重量必须等于当前任务复投重量！");
		}
		againTaskDetailService.saveOrUpdate(againTaskDetail);

		//复投任务
		AgainTask againTask = againTaskService.get(againTaskDetail.getAgainTaskId());
		//已灌料桶数
		int alreadyPailNum = againTask.getAlreadyPailNum()==null?0:againTask.getAlreadyPailNum();
		alreadyPailNum += inputFurnaceBurdenDto.getPailNum();

		againTask.setAlreadyPailNum(alreadyPailNum);
		//完成任务 - 复投任务
		if(againTask.getAgainPailNum()==null || againTask.getAlreadyPailNum() >= againTask.getAgainPailNum()) {
			if(againTask.getRawStatus().equals(AgainTaskDto.rawStatus_1)) {
				againTask.setRawStatus(AgainTaskDto.rawStatus_4);
				robotSeedMessage(againTask.getEquipmentCode(),againTask.getAgainNum());
			}else {
				throw new RuntimeException("当前复投任务未处在可执行状态");
			}
		}
		Integer pailNum = againTask.getPailNum();
		pailNum = pailNum==null?0:pailNum;
		againTask.setPailNum(pailNum+againTaskDetail.getNum());//当前桶数
		againTask.setAlloyBrand(inputFurnaceBurdenDto.getAlloyBrand());
		againTask.setAlloyType(inputFurnaceBurdenDto.getAlloyType());
		againTask.setAlloyWeight(inputFurnaceBurdenDto.getAlloyWeight());
		againTask.setRemark(inputFurnaceBurdenDto.getRemark());
		againTask.setTrialType(inputFurnaceBurdenDto.getTrialType());
		againTaskService.saveOrUpdate(againTask);

		//完善灌料开始数据
		InputFurnaceBurden inputFurnaceBurden = fromDto(inputFurnaceBurdenDto);
		initStartInputFurnaceBurdenData(againTaskDetail, inputFurnaceBurden);
		saveOrUpdate(inputFurnaceBurden);

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

		// 保存投料明细
		List<InputFurnaceDetailDto> detailDto = inputFurnaceBurdenDto.getDetails();
		List<String> bucketBatchNos = new ArrayList<>();
		for (InputFurnaceDetailDto inputFurnaceDetailDto : detailDto) {
			if(inputFurnaceDetailDto.getWeight() == null
					|| inputFurnaceDetailDto.getWeight().compareTo(BigDecimal.ZERO) <= 0 ){
				throw new RuntimeException("重量不允许为0或者负数");
			}

			// 单桶内物料不能重复
			String bucketBatchNo = inputFurnaceDetailDto.getBucketNo() +"-"+ inputFurnaceDetailDto.getBatchNo();
			if(bucketBatchNos.contains(bucketBatchNo)){
				throw new RuntimeException("物料有重复，请检查！");
			}
			if(inputFurnaceDetailDto.getMaterialName().contains("合金")){
				//如果无合金牌号和类型，提示必填
				if(StringUtils.isAnyBlank(inputFurnaceBurdenDto.getAlloyBrand(),inputFurnaceBurdenDto.getAlloyType())){
					throw new RuntimeException("无合金牌号或者类型");
				}
				inputFurnaceDetailDto.setAlloyBrand(inputFurnaceBurdenDto.getAlloyBrand());
				inputFurnaceDetailDto.setAlloyType(inputFurnaceBurdenDto.getAlloyType());
			}

			InputFurnaceDetail detail = fromDto(inputFurnaceDetailDto);
			detail.setInputFurnaceId(inputFurnaceBurden.getId());
			detail.setAgainTaskDetailId(againTaskDetail.getId());
			// 补充物料信息
			Result<WarehouseInventoryBo> result = storeFeignClients.getByBatchNoAndWarehouseCode(detail.getBatchNo(), detail.getStoreLocationName());
			WarehouseInventoryBo warehouse = result.getData();
			if (!ObjectUtils.isEmpty(warehouse)) {
				detail.setMaterialLevel(warehouse.getMaterialLevel());
				detail.setSuppliesGrain(warehouse.getSuppliesGrain());
				detail.setResistanceGear(warehouse.getMaterialGear());
			}

			inputFurnaceDetailService.saveOrUpdate(detail);

			// 物料唯一码
			bucketBatchNos.add(bucketBatchNo);

			// 组织锁定库存数据
			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());
			lockInventoryList.add(inventory);
		}

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

		//删除redis中填写数据信息
		redisUtils.remove(BurdenKey+""+inputFurnaceBurdenDto.getAgainTaskDetailId());
	}

	/**
	 * 发送消息到精彩群
	 */
	private void robotSeedMessage(String equipmentCode, Integer againNum) {
		try {
			ArrayList<String> sceneList = new ArrayList<>();
			ArrayList<String> groupNameList = new ArrayList<>();
			sceneList.add("prod");
			groupNameList.add("母合金报料群");
			String content=equipmentCode + "炉台,系统以过账，需要领母合金"+"复投次数:"+againNum;
			String source="ipc确认投料";
			dingTalkService.robotSeedMessage(content, groupNameList, source, sceneList, SeedMassageEnum.GROUP);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	private void checkFromMark(AgainTaskDetail againTaskDetail, InputFurnaceBurdenDto inputFurnaceBurdenDto) {
		String productType = againTaskDetail.getProductType();
		Date startDate ;
		DictionaryItem item = dictionaryItemService.findByThemeValueAndNameAndEnable("traceabilityTime","startTime",true);
		if(item == null){
			throw new RuntimeException("溯源卡控时间未维护！");
		} else{
			String startTime = item.getValue();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			try {
				startDate = sdf.parse(startTime);
			} catch (ParseException e) {
				throw new RuntimeException("溯源卡控时间格式不正确！");
			}
		}
		List<String> fromMarks = new ArrayList<>();
		if(productType.length() > 1 && startDate != null && startDate.compareTo(new Date()) < 0) {
			String productCategory = productType.substring(0, 1);
			if (productCategory != null) {
				fromMarks = dictionaryItemService.findValuesByThemeValueAndItemName("fillMarkMap", productCategory);
				if (CollectionUtil.isEmpty(fromMarks)) {
					throw new RuntimeException(productCategory+"的溯源卡控标识对应关系未维护！");
				}
			}
			List<InputFurnaceDetailDto> details = inputFurnaceBurdenDto.getDetails();
			for (InputFurnaceDetailDto dto : details) {
				String batchNo = dto.getBatchNo();
				String fromMark = batchNo.substring(0,1);
				if(!fromMarks.contains(fromMark)){
					throw new RuntimeException("批次号"+batchNo+"溯源卡控不通过！工单溯源标识为"+productCategory);
				}

			}
		}

	}

	@Override
	public List<InputFurnaceBurden> findByAgainTaskDetailId(Long ainTaskDetailId) {
		return dao.findByAgainTaskDetailId(ainTaskDetailId);
	}



	private void initStartInputFurnaceBurdenData(AgainTaskDetail againTaskDetail, InputFurnaceBurden inputFurnaceBurden) {
        inputFurnaceBurden.setId(null);
        inputFurnaceBurden.setAgainNum(againTaskDetail.getAgainNum());
        inputFurnaceBurden.setEquipmentCode(againTaskDetail.getEquipmentCode());
        inputFurnaceBurden.setLotNo(againTaskDetail.getLotNo());
        inputFurnaceBurden.setSeries(againTaskDetail.getSeries());
        inputFurnaceBurden.setArea(againTaskDetail.getArea());
        inputFurnaceBurden.setRawType(againTaskDetail.getRawType());
        if (inputFurnaceBurden.getPailNum() == null) {
            inputFurnaceBurden.setPailNum(againTaskDetail.getNum());
        }
        inputFurnaceBurden.setWeigth(againTaskDetail.getAgainWeigth());
        inputFurnaceBurden.setEndTime(new Date());
        inputFurnaceBurden.setFurnaceType(againTaskDetail.getFurnaceType());
        inputFurnaceBurden.setSapNo(againTaskDetail.getSapNo());
        inputFurnaceBurden.setProductCode(againTaskDetail.getProductCode());
        inputFurnaceBurden.setProductGrade(againTaskDetail.getProductGrade());
        inputFurnaceBurden.setSpecs(againTaskDetail.getSpecs());
        inputFurnaceBurden.setDopant(againTaskDetail.getDopant());
        inputFurnaceBurden.setProductType(againTaskDetail.getProductType());
        inputFurnaceBurden.setAgainTaskDetailId(againTaskDetail.getId());
        //下次复投是否完结【0：不是; 1 是;】
        inputFurnaceBurden.setIsNextEnd(againTaskDetail.getIsNextEnd());
    }


	public InputFurnaceBurden fromDto(InputFurnaceBurdenDto dto) {
		return modelMapper.map(dto, InputFurnaceBurden.class);
	}


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

	@Override
	public List<InputFurnaceBurden> findByStartTime(String startTime, String endTime, String series) {
		return dao.findByStartTime(startTime, endTime, series);
	}

	@Override
	public List<InputFurnaceBurden> findUnconfirmedTask(String lotNo) {
		return dao.findUnconfirmedTask(lotNo);
	}

	@Override
	public Result confirmMaterials(Long id) {
		InputFurnaceBurden burden = dao.getOne(id);
		if (burden.getConfirm() == 1){
			return ResultGenerator.fail("已完成确认投料，请勿重复操作");
		}
		Date date = new Date();
		burden.setConfirm(1);
		burden.setConfirmTime(date);
		dao.save(burden);
		AgainTaskDetail taskDetail = againTaskDetailService.get(burden.getAgainTaskDetailId());
		taskDetail.setConfirm(1);
		taskDetail.setConfirmTime(date);
		againTaskDetailService.saveOrUpdate(taskDetail);

		// 查询投料明细
		List<InputFurnaceDetail> detailList = inputFurnaceDetailService.findByInputFurnaceId(id);

		// 线边仓出库
		WarehouseOutputBillBo outputBillBo = new WarehouseOutputBillBo();
		outputBillBo.setType("生产领用");
		outputBillBo.setAutoAudit(true);
		outputBillBo.setDestination("车间");
		outputBillBo.setCreateUserId(1);
		outputBillBo.setCreateUserName(burden.getUserName());

		// 线边仓回滚
		StoreDataBo rollBackBo = new StoreDataBo();
		rollBackBo.setReturnType(0);
		rollBackBo.setType("装灌料回滚入库");
		rollBackBo.setCreateUserId(1);
		rollBackBo.setCreateUserName(burden.getUserName());

		List<WarehouseOutputBillDetailBo> boList = new ArrayList<>();
		List<StoreDataDetailsBo> rollBackList = new ArrayList<>();
		for (InputFurnaceDetail detail : detailList) {
			MaterialModel model = materialModelService.findByCode(detail.getMaterialCode());
			WarehouseOutputBillDetailBo bo = new WarehouseOutputBillDetailBo();
			bo.setMaterialModelId(model.getId().longValue());
			bo.setMaterialModelCode(model.getCode());
			bo.setMaterialModelName(model.getName());
			bo.setBatchNo(detail.getBatchNo());
			bo.setUniqueCode(detail.getUniqueCode());
			bo.setMaterialTypeName(model.getMaterialType().getName());
			bo.setSupplier(model.getSupplier());
			bo.setSpecification(model.getSpecification());
			bo.setMaterialTh(model.getNumberOfDrawings());
			bo.setRequireCount(detail.getWeight());
			bo.setUnitName(detail.getUnit());
			bo.setWarehouseId(detail.getStoreLocationId().longValue());
			bo.setWarehouseName(detail.getStoreLocationName());
			bo.setCreateUserId(1);
			bo.setCreateUserName(burden.getUserName());
			bo.setLockInventory(true);

			boList.add(bo);

			StoreDataDetailsBo rbBo = new StoreDataDetailsBo();
			BeanUtils.copyProperties(bo, rbBo);
			rbBo.setCount(detail.getWeight());
			rollBackList.add(rbBo);
		}
		outputBillBo.setOutputBillDetails(boList);
		rollBackBo.setDetailsBos(rollBackList);

		Result<String> result = storeFeignClients.outputApply(outputBillBo);
		if (result.getCode() != ResultCode.SUCCESS.getCode()){
			throw new RuntimeException("线边仓出库失败：" + result.getMessage());
		}

		try{
			// SAP报消耗
			for (InputFurnaceDetail detail : detailList) {
				ReportSapGoodsmvt reportSap = new ReportSapGoodsmvt();
				reportSap.setBwart("261");		// 移动类型
				reportSap.setKostl(null);		// 成本中心
				reportSap.setProcName("拉晶");	// 工序
				reportSap.setAufnr(taskDetail.getSapNo());		// SAP生产订单
				reportSap.setMatnr(detail.getMaterialCode());	// 物料编码
				reportSap.setCharg(StringUtils.isEmpty(detail.getCrystalNo())? detail.getBatchNo(): detail.getCrystalNo());		// 批次号
				reportSap.setMenge(detail.getWeight().toString());	// 数量
				reportSap.setMeins(detail.getUnit());		// 单位
				reportSap.setDeviceNo(taskDetail.getEquipmentCode());	// 设备号
				reportSap.setOther1(taskDetail.getAgainNum().toString());		// 加次
				reportSap.setRemark("1-" + detail.getId());		// 对账使用
				Result<WarehouseModelDto> result1 = storeFeignClients.getById(detail.getStoreLocationId().longValue());
				if (result1.getCode() == ResultCode.SUCCESS.getCode()){
					WarehouseModelDto dto = result1.getData();
					if (dto != null){
						reportSap.setLgort(dto.getCode());	// 库存地点
					}
				}

				reportSapGoodsmvtService.saveOrUpdate(reportSap);
			}
		}catch (Exception e){
			log.error("灌料确认投料：", e);
			storeFeignClients.rollBackStore(rollBackBo);
			throw new RuntimeException("保存SAP记录异常");
		}

		return ResultGenerator.success();
	}

	@Override
	public List<InputFurnaceBurden> findTask(String lotNo, Integer againNum, Integer confirm) {
		return dao.findTask(lotNo, againNum, confirm);
	}

	@Override
	public InputFurnaceBurden findTopByAgainTaskDetailId(Long ainTaskDetailId) {
		return dao.findTopByAgainTaskDetailIdOrderByIdDesc(ainTaskDetailId);
	}

}
