package com.cim.idm.service.Impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cim.idm.framework.IDMFrameServiceProxy;
import com.cim.idm.framework.data.EventInfo;
import com.cim.idm.framework.util.time.TimeStampUtil;
import com.cim.idm.model.MoveTransformDetailDto;
import com.cim.idm.service.impl.ToSAPServiceImpl;
import com.cim.idm.utils.EventInfoUtil;
import com.cim.idm.wmsextend.generic.errorHandler.CustomException;
import com.cim.idm.wmspackage.materialpacking.MaterialPackingServiceProxy;
import com.cim.idm.wmspackage.materialpacking.management.data.MaterialPacking;
import com.cim.idm.wmspackage.materialpacking.management.info.CreateInfo;
import com.cim.idm.wmspackage.materialpacking.management.info.SetEventInfo;
import com.cim.idm.wmspackage.storage.StorageServiceProxy;
import com.cim.idm.wmspackage.storage.management.data.StorageSpec;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
public class MoveTransformServiceImpl {
	private EventInfo makeEventInfo;


	@Autowired
	private ToSAPServiceImpl toSAPServiceImpl;

	@Transactional
	public boolean MoveTransformOut(List<MoveTransformDetailDto> from, List<MoveTransformDetailDto> to, String user, String commitDate) throws Exception {
		String condition="";
		//根据批次找到条码信息进行出库
		for (MoveTransformDetailDto moveTransformDetailDto : from) {
			String charge = moveTransformDetailDto.getCHARGE();
			String materialPackingName = moveTransformDetailDto.getMATERIALPACKINGNAME();
			String materialSpecName = moveTransformDetailDto.getMATERIALSPECNAME();
			String materialquantity = moveTransformDetailDto.getMATERIALQUANTITY();//数量
			String sql = "SELECT 1 FROM MATERIALPACKING WHERE CHARGE=:CHARGE AND MATERIALSPECNAME= :MATERIALSPECNAME";
			Map<String, Object> hashMap2 = new HashMap<String,Object> ();
			hashMap2.put("CHARGE", charge);
			hashMap2.put("MATERIALSPECNAME", materialSpecName);
			List<Map<String, Object>> queryForList = IDMFrameServiceProxy.getSqlTemplate().queryForList(sql, hashMap2);
			List<MaterialPacking> MaterialPackingList = null;
			if (queryForList != null && queryForList.size() > 0) {
				String[] bindSet={charge,materialSpecName};
				condition="WHERE CHARGE=? AND MATERIALSPECNAME=? ";
				MaterialPackingList = MaterialPackingServiceProxy.getMaterialPackingService().select(condition, bindSet);
			} else {
				throw new RuntimeException("转换前条码信息不存在!"); 
				
			}
			//解析条码,根据远条码信息更新目标条码数量和库存状态
			SetEventInfo setEventInfo = new SetEventInfo();
			EventInfoUtil eventInfoUtil = new EventInfoUtil();
			makeEventInfo = eventInfoUtil.makeEventInfo("MoveTransform", user, "MoveTransform", "", "");
			for (MaterialPacking materialPacking : MaterialPackingList) {
				//更新批次，数量，库位状态
				Map<String, Object> hashMap = new HashMap<String,Object> ();
				//校验数量是否满足
				Double materialQuantity2 = materialPacking.getMaterialQuantity();//源标签数量
				Double parseFloat = Double.parseDouble(materialquantity);//单据数量
				if (parseFloat > materialQuantity2) {
					throw new RuntimeException("源标签数量" + materialQuantity2 + "; 不足!"); 
				} else if (parseFloat - materialQuantity2 == 0) {
					hashMap.put("stockState", "StockOut");
				} else {
					hashMap.put("materialQuantity", materialQuantity2 - parseFloat );
				}
				setEventInfo.setUserColumns(hashMap);
				MaterialPackingServiceProxy.getMaterialPackingService().setEvent(materialPacking.getKey(), makeEventInfo, setEventInfo);
			}
		}

		for (MoveTransformDetailDto moveTransformDetailDto : to) {
			String charge = moveTransformDetailDto.getCHARGE() == null ? "" : moveTransformDetailDto.getCHARGE();
			String materialPackingName = moveTransformDetailDto.getMATERIALPACKINGNAME() == null ? "" : moveTransformDetailDto.getMATERIALPACKINGNAME();
			String materialSpecName = moveTransformDetailDto.getMATERIALSPECNAME() == null ? "" : moveTransformDetailDto.getMATERIALSPECNAME();
			String erpfactory = moveTransformDetailDto.getERPFACTORY() == null ? "" : moveTransformDetailDto.getERPFACTORY();
			String erplocation = moveTransformDetailDto.getERPLOCATION() == null ? "" : moveTransformDetailDto.getERPLOCATION();
			String locationname = moveTransformDetailDto.getLOCATIONNAME() ==null ? "" : moveTransformDetailDto.getLOCATIONNAME();
			String sdk_ID = moveTransformDetailDto.getSDK_ID() == null ? "" : moveTransformDetailDto.getSDK_ID();
			String phase = moveTransformDetailDto.getPHASE() == null ? "" : moveTransformDetailDto.getPHASE();
			String materialquantity = moveTransformDetailDto.getMATERIALQUANTITY() == null ? "" : moveTransformDetailDto.getMATERIALQUANTITY();
			String makedate = moveTransformDetailDto.getMAKEDATE();
			String expirdate = moveTransformDetailDto.getEXPIRDATE();
			String receiverequestdetailname = moveTransformDetailDto.getRECEIVEREQUESTDETAILNAME();
			String receiverequestname = moveTransformDetailDto.getRECEIVEREQUESTNAME();
			String materialunit = moveTransformDetailDto.getMATERIALUNIT();
			if (makedate == null || expirdate == null) {
				throw new RuntimeException("目标信息保质期或制造日期为空"); 
			}
			String bqMakeDate = makedate == null ? "" : makedate.replace("-", "").substring(0, 8);
			String sdkSpec = "SELECT SPECNAME FROM SDK_SPEC SS WHERE SS.SDK_ID = :SDK_ID";
			Map<String, Object> hashMap3 = new HashMap<String,Object> ();
			hashMap3.put("SDK_ID", sdk_ID);
			List<Map<String, Object>> queryForList2 = IDMFrameServiceProxy.getSqlTemplate().queryForList(sdkSpec, hashMap3);
			String sepcName = "";
			if (queryForList2 !=  null && queryForList2.size() > 0) {
				sepcName = queryForList2.get(0).get("SPECNAME").toString();
			}
			String newBoxId = materialSpecName + "|1|" + phase + "|" + sepcName + "|" + charge + "|" 
					+ bqMakeDate + "|" + materialunit + "|" + materialquantity;
			String sql = "SELECT 1 FROM MATERIALPACKING WHERE MATERIALPACKINGNAME = :MATERIALPACKINGNAME";
			Map<String, Object> hashMap2 = new HashMap<String,Object> ();
			hashMap2.put("MATERIALPACKINGNAME", newBoxId);
			List<Map<String, Object>> queryForList = IDMFrameServiceProxy.getSqlTemplate().queryForList(sql, hashMap2);
			List<MaterialPacking> MaterialPackingList = null;
			if (queryForList != null && queryForList.size() > 0) {
				String[] bindSet={newBoxId};
				condition="WHERE MATERIALPACKINGNAME=?   ";
				MaterialPackingList = MaterialPackingServiceProxy.getMaterialPackingService().select(condition, bindSet);
			}
			//解析条码,根据远条码信息更新目标条码数量和库存状态
			SetEventInfo setEventInfo = new SetEventInfo();
			EventInfoUtil eventInfoUtil = new EventInfoUtil();
			makeEventInfo = eventInfoUtil.makeEventInfo("MoveTransform", user, "MoveTransform" );
			//找到原来标签的相关信息
//			String receiveTime = "";
//			String makeDate = "";
//			String expireDate = "";
			String holdState = "N";
			String oqaResult = "OK";
			String oqaResultState = "END";
			String packingGrade = "OK";
			String trueGg = "";
//			String erpFactory = "";
//			String erpLocation = "";
//			String locationName = "";
			String shelfName = "";
			String areaName = "";
			String durableName = "";;
			String CAREER_ASSISTANCE = "";
	        String SALESPERSON = "";
	        String CUSTOMNO = "";
	        String DEVIATION = "";
	        String DIAMETER = "";
	        String WIDTH = "";
	        String WEIGHT = "";
	        String PRODUCTLINE = "";
	        String UNIT = "";
	        String MJPC = "";
	        String BUSINESS_UNIT = "";
	        String REMARK = "";
	        String EXPIRINGDATE = "";
			String ypcSql = "SELECT M.RECEIVETIME,ITB.MAKEDATE,ITB.EXPIRDATE,M.HOLDSTATE,M.OQARESULTSTATE ,M.REMARK, \r\n" + 
					"							M.OQARESULT ,M.PACKINGGRADE ,M.TRUEGG ,M.ERPFACTORY ,M.ERPLOCATION ,M.LOCATIONNAME ,\r\n" + 
					"							M.SHELFNAME ,M.AREANAME ,M.DURABLENAME ,M.CAREER_ASSISTANCE ,M.SALESPERSON ,M.CUSTOMNO,\r\n" + 
					"					      M.DEVIATION ,M.DIAMETER ,M.WIDTH ,M.WEIGHT ,M.PRODUCTLINE,UNIT ,MJPC,BUSINESS_UNIT ,M.SPECIALSTATE ,M.CUSTOMNO    \r\n" +
					"							FROM IC_TRANSFORM_B ITB LEFT JOIN  MATERIALPACKING M \r\n" + 
					"							ON ITB.MATERIALSPECNAME = M.MATERIALSPECNAME AND ITB.CHARGE = M.CHARGE \r\n" + 
					"							WHERE   ITB.CHARGE  = :OLDCHARGE  AND ITB.TYPE = '2' ";
			//根据当前标签信息查询源标签信息，比当前行号小1的即为源标签信息
			String searchSql = "SELECT CHARGE FROM IC_TRANSFORM_B T WHERE " +
					"TO_NUMBER(T.RECEIVEREQUESTDETAILNAME) < " +
					"(SELECT TO_NUMBER(RECEIVEREQUESTDETAILNAME) FROM IC_TRANSFORM_B WHERE RECEIVEREQUESTNAME = :RECEIVEREQUESTNAME AND CHARGE  = :CHARGE" +
					" AND TYPE = '3'  FETCH FIRST 1 ROW ONLY) AND RECEIVEREQUESTNAME = :RECEIVEREQUESTNAME ORDER BY RECEIVEREQUESTDETAILNAME DESC";
			//制造日期需要从转换后的单据取
			String makeDateSql = "SELECT MAKEDATE,EXPIRDATE FROM IC_TRANSFORM_B WHERE RECEIVEREQUESTNAME = :RECEIVEREQUESTNAME AND CHARGE  = :CHARGE" +
					" AND TYPE = '3'  FETCH FIRST 1 ROW ONLY";
			Map<String, Object> stringObjectHashMap = new HashMap<>();
			stringObjectHashMap.put("RECEIVEREQUESTNAME", receiverequestname);
			stringObjectHashMap.put("CHARGE", charge);
			String oldCharge = charge;
			List<Map<String, Object>> queryForList1 = IDMFrameServiceProxy.getSqlTemplate().queryForList(searchSql, stringObjectHashMap);
			if (queryForList1 != null && queryForList1.size() > 0) {
				Map<String, Object> map = queryForList1.get(0);
				oldCharge = map.get("CHARGE").toString();
			}
			Map<String, Object> hashMap4 = new HashMap<String,Object> ();
			hashMap4.put("MATERIALSPECNAME", materialSpecName);
			hashMap4.put("OLDCHARGE", oldCharge);
			hashMap4.put("RECEIVEREQUESTNAME", receiverequestname);
			hashMap4.put("CHARGE", charge);
			List<Map<String, Object>> queryForList3 = IDMFrameServiceProxy.getSqlTemplate().queryForList(ypcSql, hashMap4);
			List<Map<String, Object>> maps = IDMFrameServiceProxy.getSqlTemplate().queryForList(makeDateSql, hashMap4);
			if (queryForList3 != null && queryForList3.size() > 0) {
				Map<String, Object> map = queryForList3.get(0);
				 holdState = map.get("HOLDSTATE") == null ? "N" : map.get("HOLDSTATE").toString();
//				 oqaResult = map.get("OQARESULT") == null ? "OK" : map.get("OQARESULT").toString();
				oqaResult = map.get("OQARESULT") == null ? "" : map.get("OQARESULT").toString();
//				 oqaResultState = map.get("OQARESULTSTATE") == null ? "END" : map.get("OQARESULTSTATE").toString();
//				 packingGrade = map.get("PACKINGGRADE") == null ? "OK" : map.get("PACKINGGRADE").toString();
				oqaResultState = map.get("OQARESULTSTATE") == null ? "" : map.get("OQARESULTSTATE").toString();
				packingGrade = map.get("PACKINGGRADE") == null ? "" : map.get("PACKINGGRADE").toString();
				 trueGg = map.get("TRUEGG") == null ? "" : map.get("TRUEGG").toString();
//				 erpFactory = map.get("ERPFACTORY") == null ? "" : map.get("ERPFACTORY").toString();
//				 erpLocation = map.get("ERPLOCATION") == null ? "" : map.get("ERPLOCATION").toString();
//				 locationName = map.get("LOCATIONNAME") == null ? "" : map.get("LOCATIONNAME").toString();
				 shelfName = map.get("SHELFNAME") == null ? "" : map.get("SHELFNAME").toString();
				 areaName = map.get("AREANAME") == null ? "" : map.get("AREANAME").toString();
				 durableName = map.get("DURABLENAME") == null ? "" : map.get("DURABLENAME").toString();
				 CAREER_ASSISTANCE = map.get("CAREER_ASSISTANCE") == null ? "" : map.get("CAREER_ASSISTANCE").toString();
		         SALESPERSON = map.get("SALESPERSON") == null ? "" : map.get("SALESPERSON").toString();
		         CUSTOMNO = map.get("CUSTOMNO") == null ? "" : map.get("CUSTOMNO").toString();
		         DEVIATION = map.get("DEVIATION") == null ? "" : map.get("DEVIATION").toString();
		         DIAMETER = map.get("DIAMETER") == null ? "" : map.get("DIAMETER").toString();
		         WIDTH = map.get("WIDTH") == null ? "" : map.get("WIDTH").toString();
		         WEIGHT = map.get("WEIGHT") == null ? "" : map.get("WEIGHT").toString();
		         PRODUCTLINE = map.get("PRODUCTLINE") == null ? "" : map.get("PRODUCTLINE").toString();
		         UNIT = map.get("UNIT") == null ? "" : map.get("UNIT").toString();
		         MJPC = map.get("MJPC") == null ? "" : map.get("MJPC").toString();
		         BUSINESS_UNIT = map.get("BUSINESS_UNIT") == null ? "" : map.get("BUSINESS_UNIT").toString();
		         REMARK = map.get("REMARK") == null ? "" : map.get("REMARK").toString();
			}
			
			if (MaterialPackingList != null && MaterialPackingList.size() > 0) {
				for (MaterialPacking materialPacking : MaterialPackingList) {
					String stockState = materialPacking.getStockState();
					if (!"StockOut".equals(stockState)) throw new RuntimeException("批次已存在且为在库状态！");
					//根据货位找到ERP库位和组织
					condition="WHERE ERPFACTORY = ? AND ERPLOCATION = ? AND STORAGENAME=? ";
					String[] indSet={erpfactory,erplocation,locationname};
					List<StorageSpec> select = StorageServiceProxy.getStorageSpecService().select(condition, indSet);
					if (select == null || select.size() != 1) {
						throw new CustomException(erpfactory + ":" + erplocation + ":" + locationname + "对应关系不正确！");
					}
					//更新批次，数量，库位状态
					Map<String, Object> hashMap = new HashMap<String,Object> ();
					hashMap.put("erpLocation", erplocation);
					hashMap.put("erpFactory", erpfactory);
					hashMap.put("locationName", locationname);
					hashMap.put("SDK_ID", sdk_ID);
					hashMap.put("PHASE", phase);
					hashMap.put("stockState", "Stocked");
					setEventInfo.setUserColumns(hashMap);
					MaterialPackingServiceProxy.getMaterialPackingService().setEvent(materialPacking.getKey(), makeEventInfo, setEventInfo);
				}
			} else if (MaterialPackingList != null && MaterialPackingList.size() > 1) {
				throw new RuntimeException("批次不唯一！");
			} else {
				CreateInfo createInfo = new CreateInfo();
				createInfo.setSiteName("SDK");
				createInfo.setMaterialPackingName(newBoxId);// 新生成的box id
				createInfo.setMaterialPackingType("Box");
				createInfo.setContentMaterialType("");

				Map<String, Object> bindMap = new HashMap<String, Object>();
				bindMap.put("MaterialSpecName", materialSpecName);
				bindMap.put("PackingGrade", packingGrade);
				bindMap.put("oqaResult", oqaResult);
				bindMap.put("oqaResultState", oqaResultState);
				bindMap.put("SubPackingQuantity",materialquantity);
				bindMap.put("MaterialCreateQuantity",materialquantity);
				bindMap.put("MaterialQuantity", materialquantity);// 数量
				bindMap.put("PackingState", "Released");
				bindMap.put("OldPackingState", "Released");
				bindMap.put("stockState", "Stocked");
				bindMap.put("OldStockState", "Created");
				bindMap.put("HoldState", holdState);
				bindMap.put("LocationName", locationname);
				bindMap.put("charge",charge);
				bindMap.put("MaterialProcessGroupName","");
				bindMap.put("LastEventTimeKey",TimeStampUtil.getCurrentEventTimeKey());
				
				
				if (queryForList3 != null && queryForList3.size() > 0) {
					bindMap.put("MakeDate", queryForList3.get(0).get("MAKEDATE"));
					bindMap.put("expiringDate", queryForList3.get(0).get("EXPIRDATE"));
					bindMap.put("ReceiveTime", queryForList3.get(0).get("RECEIVETIME"));
					bindMap.put("unit", queryForList3.get(0).get("UNIT"));
					bindMap.put("specialState", queryForList3.get(0).get("SPECIALSTATE"));
					bindMap.put("CUSTOMNO", queryForList3.get(0).get("CUSTOMNO"));
				} else {
					bindMap.put("unit", materialunit);
					bindMap.put("MakeDate", makedate);
					bindMap.put("expiringDate", expirdate);
					bindMap.put("ReceiveTime", makeEventInfo.getEventTime());
				}

				if(maps != null && maps.size() > 0) {
					bindMap.put("MakeDate", maps.get(0).get("MAKEDATE"));
					bindMap.put("expiringDate", maps.get(0).get("EXPIRDATE"));
				}
				
				bindMap.put("ReceiveUser", makeEventInfo.getEventUser());
				bindMap.put("ErpLocation", erplocation);
				bindMap.put("ErpFactory", erpfactory);
				bindMap.put("locationName", locationname);
				bindMap.put("StockInType", "Normal");
				bindMap.put("SDK_ID", sdk_ID);
				bindMap.put("PHASE", phase);
				bindMap.put("ReceiveRequestName", receiverequestname);
				bindMap.put("ReceiveRequestDetailName",receiverequestdetailname);
				
			
				
				bindMap.put("CAREER_ASSISTANCE", CAREER_ASSISTANCE);//业助信息
				bindMap.put("BUSINESS_UNIT", BUSINESS_UNIT);//业务
				bindMap.put("SALESPERSON", SALESPERSON);//事业部
				bindMap.put("MJPC", MJPC);//母卷批次
				bindMap.put("truegg", trueGg);
				bindMap.put("durableName", durableName);
				bindMap.put("areaName", areaName);
				bindMap.put("PRODUCTLINE", PRODUCTLINE);
				bindMap.put("WIDTH", WIDTH);
				bindMap.put("DEVIATION", DEVIATION);
				bindMap.put("WEIGHT", WEIGHT);
				bindMap.put("DIAMETER", DIAMETER);
				bindMap.put("shelfName", shelfName);
				bindMap.put("remark",REMARK);
				createInfo.setUserColumns(bindMap);
				MaterialPackingServiceProxy.getMaterialPackingService().create(makeEventInfo, createInfo);
			}
		}
		String xtzh = xtzh(from, to, user,commitDate);
		return true;
	}


	public String xtzh (List<MoveTransformDetailDto> from, List<MoveTransformDetailDto> to,String user,String commitDate) {
		JSONObject mainObject = new JSONObject(true);
		JSONArray outArray = new JSONArray();
		JSONArray inArray = new JSONArray();
		for (MoveTransformDetailDto moveTransformDetailDto : from) {
			JSONObject outmains = new JSONObject(true); 
			outmains.put("storecode", moveTransformDetailDto.getERPLOCATION());
			outmains.put("dbilldate", commitDate);
			outmains.put("ctrantypeOut", "4I-06");
			outmains.put("manager", user);
			JSONArray outItemArray = new JSONArray();								
			//                "cspecialbid": "1001A110000000XNRYE8", //形态转换明细主键
			//                "dbizdate": "2024-05-07 00:00:00", //出库日期
			//                //"location":"109000008",//货位
			//                "num": "4" //实发（收）数量
			JSONObject item = new JSONObject(true);
			item.put("cspecialbid", moveTransformDetailDto.getDETAILID());
			item.put("dbizdate", commitDate);
			item.put("wmsid", UUID.randomUUID());
			item.put("num", moveTransformDetailDto.getMATERIALQUANTITY());
			item.put("location", moveTransformDetailDto.getLOCATIONNAME());
			outItemArray.add(item);

			outmains.put("OutItems", outItemArray);
			outArray.add(outmains);
		}

		for (MoveTransformDetailDto moveTransformDetailDto : to) {
			JSONObject inmains = new JSONObject(true); 
			//	            "manager": "101867", //库管员
			//	            "dbilldate": "2024-05-07 00:00:00", //单据日期
			//	            "ctrantypeIn": "4A-06", //其他入单据类型
			//	            "storecode": "10102065", //明细仓库
			inmains.put("storecode", moveTransformDetailDto.getERPLOCATION());
			inmains.put("dbilldate",commitDate);
			inmains.put("ctrantypeIn", "4A-06");
			inmains.put("manager", user);
			JSONArray inItemArray = new JSONArray();								
			//                "cspecialbid": "1001A110000000XNRYE9", //形态转换明细主键
			//                "dbizdate": "2024-05-07 00:00:00", //入库日期
			//                "location": "206500001", //货位
			//                "num": "4" //实发（收）数量
			JSONObject item = new JSONObject(true);
			item.put("cspecialbid", moveTransformDetailDto.getDETAILID());
			item.put("dbizdate", commitDate);
			item.put("wmsid", UUID.randomUUID());
			item.put("num", moveTransformDetailDto.getMATERIALQUANTITY());
			item.put("location", moveTransformDetailDto.getLOCATIONNAME());
			inItemArray.add(item);

			inmains.put("InItems", inItemArray);
			inArray.add(inmains);
		}
		mainObject.put("user_code", user);  //名称
		mainObject.put("cspecialhid", from.get(0).getERPID());//主表ID
		mainObject.put("Out", outArray);
		mainObject.put("In", inArray);
		String rcode = "";
//		String rcode = "";
		return rcode;
	}
}


