package com.cim.idm.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cim.idm.exception.GlobalException;
import com.cim.idm.framework.IDMFrameServiceProxy;
import com.cim.idm.framework.data.EventInfo;
import com.cim.idm.model.MaterialPacking;
import com.cim.idm.model.po.MaterialReceiveRequest;
import com.cim.idm.utils.AjaxResult;
import com.cim.idm.utils.CommonUtils;
import com.cim.idm.utils.EventInfoUtil;
import com.cim.idm.wmsextend.generic.errorHandler.CustomException;
import com.cim.idm.wmspackage.name.NameServiceProxy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.cim.idm.service.Impl.ReturnStockIntoServiceImpl;
import com.cim.idm.service.Impl.ProductIntoServiceImpl;

/**
 * 退料入库控制器
 * @author ZXYGY17
 *
 */
@RestController
@RequestMapping("/ProduceReturn")
@EnableAutoConfiguration
public class ProduceReturnController {

	@Autowired
	private ReturnStockIntoServiceImpl ReturnStockIntoServiceImpl;

	@Autowired
	private ProductIntoServiceImpl ProductIntoServiceImpl;

	CommonUtils untils=new CommonUtils();
	/**
	 * 获取单据信息
	 * @param in
	 * @return
	 */
	@RequestMapping(value = "/getBarCode", method = RequestMethod.POST)
	public AjaxResult getBarCode(@RequestBody JSONObject in ){

		MaterialPacking materialPacking = JSON.toJavaObject(in, MaterialPacking.class);
		String materialPackingName = materialPacking.getMaterialPackingName();
		String erpLocation = materialPacking.getErpLocation();
		String erpFactory = materialPacking.getErpFactory();
		String locationName = materialPacking.getLocationName();
		String materialSpecName = materialPacking.getMaterialSpecName();
		//判断条码是否存在且状态是在库
		String sql = "SELECT M.STOCKSTATE,M.RECEIVEACTNO FROM MATERIALPACKING M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME";

		Map<String, Object> bindMap = new HashMap<String, Object>();
		bindMap.put("MATERIALPACKINGNAME",materialPackingName); 
		bindMap.put("ERPLOCATION",erpLocation); 
		bindMap.put("ERPFACTORY",erpFactory); 
		bindMap.put("LOCATIONNAME",locationName); 
		List<Map<String,Object>> list = IDMFrameServiceProxy.getSqlTemplate().queryForList(sql, bindMap);
		if(list.size() > 1) {
			throw new GlobalException("条码不止一个,请联系IT处理！");
		}
		if (list.size() == 1) {
			for (Map<String, Object> map : list) {
				if (!"StockOut".equals(map.get("STOCKSTATE").toString())) {
					throw new GlobalException("条码已存在且不为出库状态,请联系IT处理！");
				}
			}
		}




		String sql2 = "SELECT\r\n" + 
				"	BMS.LOTNAME MATERIALPACKINGNAME,\r\n" + 
				"	BMS.PRODUCTSPECNAME MATERIALSPECNAME,\r\n" + 
				"	BMS.PHASE ,\r\n" + 
				"	BMS.PACKINGGRADE ,\r\n" +
				"	BMS.QTY MATERIALQUANTITY ,\r\n" +
				"	BMS.REQUESTNAME RECEIVEREQUESTNAME ,\r\n" +
				"	SS.SPECNAME ,\r\n" + 
				"	m.DESC_CN ,\r\n" +
				"	0 AS HAVEQUANTITY ,\r\n" +
				"  :ERPFACTORY ERPFACTORY, :ERPLOCATION ERPLOCATION, :LOCATIONNAME LOCATIONNAME,\r\n" + 
				"	REGEXP_SUBSTR(BMS.LOTNAME , '[^|]+', 1, 5) AS CHARGE\r\n" + 
				"FROM\r\n" + 
				"	BS_MES_SHIPPED BMS LEFT JOIN MATERIALSPEC m ON m.MATERIALSPECNAME = BMS.PRODUCTSPECNAME \r\n" + 
				"	LEFT JOIN SDK_SPEC SS ON SS.SDK_ID = BMS.SDK_ID \r\n" + 
				"WHERE\r\n" + 
				"	BMS.LOTNAME = :MATERIALPACKINGNAME\r\n" + 
				"	AND (BMS.RECEIVE_FLAG IS NULL\r\n" + 
				"		OR BMS.RECEIVE_FLAG <> 'Y')";

		List<Map<String,Object>> list2 = IDMFrameServiceProxy.getSqlTemplate().queryForList(sql2, bindMap);
		if(list2.size() != 1) {
			throw new GlobalException("未打印退库标签,请联系IT处理！");
		}

		// 良品与不良品与仓校验
		String packingGrade = list2.get(0).get("PACKINGGRADE") == null ? "" : list2.get(0).get("PACKINGGRADE").toString();

		Boolean judgeMtaerialStateWithERPLocation = untils.JudgeMtaerialStateWithERPLocation(erpLocation, packingGrade);
		if (!judgeMtaerialStateWithERPLocation) {
			throw new GlobalException("仓库类型和物料品质等级不一致");
		}
		if ("OK".equals(packingGrade) && ("101".equals(erpFactory) || "102".equals(erpFactory))) {
			//恒温恒湿管控
			if(!(untils.JudgeMentERPLocationAndMaterialSpec(erpLocation,materialSpecName)))
			{
				throw new GlobalException("物料为:"+materialSpecName+" 仓库为:"+erpLocation+" ,不符合恒温恒湿管理");
			}
		}

		//判断入库组织与接收组织是否一致
//		String ftySql = "SELECT DISTINCT M.SHIPREQUESTNAME,mt.ERPRECEIVEFACTORY,M.REQUESTQUANTITY,M.ASSIGNEDQUANTITY,M.MATERIALSPECNAME,M.PHASE,M.SDK_ID \n" +
//				"FROM MATERIALSHIPREQUEST mt\n" +
//				"LEFT JOIN MATERIALSHIPREQUESTDETAIL M ON M.SHIPREQUESTNAME = mt.SHIPREQUESTNAME \n" +
//				"WHERE (M.RETURNNO = :SOURCEORDER OR M.SHIPREQUESTNAME = :SOURCEORDER)\n" +
//				"AND M.MATERIALSPECNAME = :PRODUCTSPECNAME";

		String receiveRequestName = list2.get(0).get("RECEIVEREQUESTNAME") == null ? "" : list2.get(0).get("RECEIVEREQUESTNAME").toString();
		String materialspecName = list2.get(0).get("MATERIALSPECNAME") == null ? "" : list2.get(0).get("MATERIALSPECNAME").toString();

		String ftySql;
		if(receiveRequestName.contains("DC")) {
			ftySql ="SELECT DISTINCT M.SHIPREQUESTNAME,mt.ERPRECEIVEFACTORY,M.REQUESTQUANTITY,M.ASSIGNEDQUANTITY,M.MATERIALSPECNAME,M.PHASE,M.SDK_ID \n" +
					"FROM MATERIALSHIPREQUEST mt\n" +
					"LEFT JOIN MATERIALSHIPREQUESTDETAIL M ON M.SOURCENO = mt.SHIPREQUESTNAME \n" +
					"WHERE (M.RETURNNO = :SOURCEORDER OR M.SHIPREQUESTNAME = :SOURCEORDER)";
		}else {
			ftySql = "SELECT DISTINCT M.SHIPREQUESTNAME,mt.ERPRECEIVEFACTORY,M.REQUESTQUANTITY,M.ASSIGNEDQUANTITY,M.MATERIALSPECNAME,M.PHASE,M.SDK_ID \n" +
					"FROM MATERIALSHIPREQUEST mt\n" +
					"LEFT JOIN MATERIALSHIPREQUESTDETAIL M ON M.SHIPREQUESTNAME = mt.SHIPREQUESTNAME \n" +
					"WHERE (M.RETURNNO = :SOURCEORDER OR M.SHIPREQUESTNAME = :SOURCEORDER)\n" +
					"AND M.MATERIALSPECNAME = :PRODCUTSPECNAME";
		}

		Map<String, Object> ftyMap = new HashMap<String, Object>();
		ftyMap.put("SOURCEORDER",receiveRequestName);
		ftyMap.put("PRODCUTSPECNAME",materialspecName);
		List<Map<String,Object>> list3 = IDMFrameServiceProxy.getSqlTemplate().queryForList(ftySql, ftyMap);
		String erpreceiveFactory = list3.get(0).get("ERPRECEIVEFACTORY") == null ? "" :list3.get(0).get("ERPRECEIVEFACTORY").toString();
		if(!erpreceiveFactory.equals(erpFactory)) {
			throw new GlobalException("仓库对应组织与单据接收组织不一致!");
		}
		list2.get(0).put("REQUESTQUANTITY",list3.get(0).get("REQUESTQUANTITY").toString());
		list2.get(0).put("ASSIGNEDQUANTITY",list3.get(0).get("ASSIGNEDQUANTITY").toString());
//		List<Map<String, Object>> listAll = new ArrayList<Map<String,Object> >(list2);
//		listAll.addAll(list3);
//		Map<String, Object> MapAll = new HashMap<String, Object>();
//		MapAll.put("list2",list2);
//		MapAll.put("list3",list3);
		// 求和所有的单据数量
//		String totalSql = "SELECT SUM(be.QTY) TOTALQTY  FROM BS_MES_SHIPPED  be WHERE REQUESTNAME = :SOURCEORDER"; // AND PRODCUTSPECNAME=:PRODCUTSPECNAME
//		List<Map<String,Object>> list4 = IDMFrameServiceProxy.getSqlTemplate().queryForList(totalSql, ftyMap);
//		String totalQty = list4.get(0).get("TOTALQTY").toString();
//		if(!list2.isEmpty()) {
//			list2.get(0).put("TOTALQTY",totalQty);
//		}

		String bySql;
//		String bySql = "SELECT b.PRODCUTSPECNAME MATERIALSPECNAME,0 HAVEQUANTITY,b.REQUESTNAME RECEIVEREQUESTNAME , b.PHASE,b.TRUEGG,SUM(b.QTY) TOTALQTY  FROM BS_MES_SHIPPED  b WHERE REQUESTNAME = :SOURCEORDER GROUP BY b.PRODCUTSPECNAME,b.REQUESTNAME,b.PHASE,b.TRUEGG";
		if(receiveRequestName.contains("DC")) {
			bySql = "SELECT b.MATERIALSPECNAME,0 HAVEQUANTITY,b.SHIPREQUESTNAME RECEIVEREQUESTNAME , b.PHASE,SUM(b.REQUESTQUANTITY) TOTALQTY  FROM MATERIALSHIPREQUESTDETAIL  b WHERE SHIPREQUESTNAME = :SOURCEORDER GROUP BY b.MATERIALSPECNAME,b.SHIPREQUESTNAME,b.PHASE\n";
		}else {
			bySql = "SELECT b.MATERIALSPECNAME,0 HAVEQUANTITY,b.SHIPREQUESTNAME RECEIVEREQUESTNAME , b.PHASE,SUM(b.REQUESTQUANTITY) TOTALQTY  FROM MATERIALSHIPREQUESTDETAIL  b WHERE RETURNNO = :SOURCEORDER GROUP BY b.MATERIALSPECNAME,b.SHIPREQUESTNAME,b.PHASE\n";
		}

		List<Map<String,Object>> list4 = IDMFrameServiceProxy.getSqlTemplate().queryForList(bySql, ftyMap);
		if(!receiveRequestName.contains("DC")) {
//			list2.get(0).get("RECEIVEREQUESTNAME") = list3.get(0).get("RECEIVEREQUESTNAME").toString();
			list2.get(0).put("RECEIVEREQUESTNAME",list4.get(0).get("RECEIVEREQUESTNAME").toString());
		}
		Map<String, Object> MapAll = new HashMap<String, Object>();
		MapAll.put("list2",list2);
		MapAll.put("list4",list4);
		return AjaxResult.me().setResultObj(MapAll);
//		return AjaxResult.me().setResultObj(list2);
	}




	/**
	 * 生成入库单号
	 * @param in
	 * @return
	 */
	@RequestMapping(value = "/createActNo", method = RequestMethod.POST)
	public AjaxResult createActNo(@RequestBody JSONObject in ) {
		// 获取系统当前时间
		java.util.Calendar c = java.util.Calendar.getInstance();
		java.text.SimpleDateFormat f = new java.text.SimpleDateFormat(
				"yyyyMMdd");

		List<String> args = new ArrayList<String>();
		String actType1 = "F";
		String siteName = "SH";
		args.add(siteName);
		args.add(actType1);
		args.add(f.format(c.getTime()));

		String ReceiveRequestActNo;

		ReceiveRequestActNo = NameServiceProxy.getNameRuleDefService()
				.generateName("ReceiveActNo", args, 1).get(0);
		List<Map<String, Object>> arrayList = new ArrayList<Map<String,Object>> ();
		arrayList.add(new HashMap<String,Object> () {
			{
				this.put("ReceiveActNo", ReceiveRequestActNo);
			}
		});
		return AjaxResult.me().setResultObj(arrayList);
	}


	/**
	 * 创建成品入库包装信息
	 * @param in
	 * @return
	 */
	@RequestMapping(value = "/createBoxInfo", method = RequestMethod.POST)
	public AjaxResult createBoxInfo(@RequestBody JSONObject in ) {
		MaterialPacking materialPacking = JSON.toJavaObject(in, MaterialPacking.class);
		String materialPackingName = materialPacking.getMaterialPackingName();
		String receiveActNo = materialPacking.getReceiveActNo();
		String user = materialPacking.getUser();
		String locationName = materialPacking.getLocationName();
		String erpFactory = materialPacking.getErpFactory();
		String erpLocation = materialPacking.getErpLocation();
		String materialspecname=materialPacking.getMaterialSpecName();
		//恒温恒湿管控
		if ("1010".equals(erpFactory) || "1020".equals(erpFactory)) {
			if (!(untils.JudgeMentERPLocationAndMaterialSpec(erpLocation, materialspecname))) {
				throw new GlobalException("物料为:" + materialspecname + " 仓库为:" + erpLocation + " ,不符合恒温恒湿管理");
			}
		}
		String sql2 = "SELECT\r\n" + 
				"	BMS.LOTNAME ,\r\n" + 
				"	BMS.PRODUCTSPECNAME ,\r\n" + 
				"	BMS.PHASE ,\r\n" + 
				"	SS.SPECNAME ,\r\n" + 
				"	m.DESC_CN ,\r\n" + 
				"	BMS.QTY ,\r\n" + 
				"	BMS.SHIPTIME ,\r\n" + 
				"	SS.SDK_ID ,BMS .REQUESTNAME ,\r\n" + 
				"	REGEXP_SUBSTR(BMS.LOTNAME , '[^|]+', 1, 5) AS CHARGE\r\n" + 
				"FROM\r\n" + 
				"	BS_MES_SHIPPED BMS LEFT JOIN MATERIALSPEC m ON m.MATERIALSPECNAME = BMS.PRODUCTSPECNAME \r\n" + 
				"	LEFT JOIN SDK_SPEC SS ON SS.SDK_ID = BMS.SDK_ID \r\n" + 
				"WHERE\r\n" + 
				"	BMS.LOTNAME = :LOTNAME\r\n" + 
				"	AND (BMS.RECEIVE_FLAG IS NULL\r\n" + 
				"		OR BMS.RECEIVE_FLAG <> 'Y')";
		Map<String, Object> bindMap = new HashMap<String, Object>();
		bindMap.put("LOTNAME",materialPackingName); 
		List<Map<String,Object>> list2 = IDMFrameServiceProxy.getSqlTemplate().queryForList(sql2, bindMap);
		if(list2.size() < 1) {
			throw new GlobalException("未打印退库标签,请联系IT处理！");
		}
		//根据退库信息获取退料单
		String sql3 = "SELECT\r\n" + 
				"	M.SHIPREQUESTNAME,\r\n" + 
				"	M.SHIPREQUESTDETAILNAME\r\n" + 
				"FROM\r\n" + 
				"	MATERIALSHIPREQUESTDETAIL M\r\n" + 
				"WHERE\r\n" + 
				"	(M.RETURNNO = :SHIPREQUESTNAME OR M.SHIPREQUESTNAME = :SHIPREQUESTNAME )\r\n" + 
				"	AND M.MATERIALSPECNAME = :MATERIALSPECNAME ";

		bindMap.put("SHIPREQUESTNAME",list2.get(0).get("REQUESTNAME"));
		bindMap.put("MATERIALSPECNAME",list2.get(0).get("PRODUCTSPECNAME"));
		List<Map<String, Object>> queryForList = IDMFrameServiceProxy.getSqlTemplate().queryForList(sql3, bindMap);
		if (queryForList == null || queryForList.size() < 1) {
			throw new GlobalException("未打印退库标签,请联系IT处理！");
		}
		EventInfo makeEventInfo = new EventInfoUtil().makeEventInfo("createBoxInfoReturn", user, "createBoxInfoReturn", "", "");
		try {
			ReturnStockIntoServiceImpl.CreateMaterialReceiveRequestAct
			(makeEventInfo, "SDK", queryForList.get(0).get("SHIPREQUESTNAME").toString(), 
					queryForList.get(0).get("SHIPREQUESTDETAILNAME").toString(), list2.get(0).get("SHIPTIME").toString(), 
					receiveActNo, "ProduceReturn", list2.get(0).get("QTY").toString(), list2.get(0).get("PRODUCTSPECNAME").toString());
		} catch (CustomException | ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new GlobalException(e.toString());
		}

		ReturnStockIntoServiceImpl.SHIPMesShippInfo(makeEventInfo, "SDK", materialPackingName, "", user, 
				materialPackingName, receiveActNo, erpLocation, erpFactory, locationName,queryForList.get(0).get("SHIPREQUESTNAME").toString(), queryForList.get(0).get("SHIPREQUESTDETAILNAME").toString());

		return AjaxResult.me().setResultObj(null);
	}


	@RequestMapping(value = "/ReturnStockIn", method = RequestMethod.POST)
	public AjaxResult fgStockIn(@RequestBody JSONObject in ) throws Exception {
		MaterialPacking materialPacking = JSON.toJavaObject(in, MaterialPacking.class);
		String receiveActNo = materialPacking.getReceiveActNo();
		String user = materialPacking.getUser();
		String commitDate = materialPacking.getCommitDate();
		String opCode = materialPacking.getOpCode();
		String fgStockIn = ReturnStockIntoServiceImpl.ReturnStockIn(receiveActNo, user,commitDate,opCode);
		if (fgStockIn.isEmpty()) {
			throw new GlobalException("报送ERP失败,请联系IT处理！");
		}
		return AjaxResult.me().setResultObj(null);
	}

	//重写退料入库方法，退料时再创建Box，同组织/跨组织均可。zd.2024.9.2
	@RequestMapping(value = "/ReturnStockInNew", method = RequestMethod.POST)
	@Transactional
	public AjaxResult returnStockInNew(@RequestBody JSONObject in ) throws Exception {
		MaterialReceiveRequest sl = JSON.toJavaObject(in, MaterialReceiveRequest.class);
		String commitDate = sl.getCommitDate();
		String opCode = sl.getOpCode();
		List<com.cim.idm.wmspackage.materialpacking.management.data.MaterialPacking> boxList = sl.getBoxList();
		String user = sl.getUser();
		ReturnStockIntoServiceImpl.returnStockInNew(boxList, commitDate, opCode, user);

		return AjaxResult.me().setSuccess(true).setResultObj(null);
	}

	
	/**
	 * 根据抬头文本获取已绑定Box信息
	 * @param in
	 * @return
	 */
	@RequestMapping(value = "/getActBindBox", method = RequestMethod.POST)
	public AjaxResult getActBindBox(@RequestBody JSONObject in ) {
		MaterialPacking materialPacking = JSON.toJavaObject(in, MaterialPacking.class);
		String receiveActNo = materialPacking.getReceiveActNo();
		String sql = "SELECT * FROM MATERIALPACKING m LEFT JOIN  MATERIALRECEIVEACT m2 ON m.RECEIVEACTNO = m2.RECEIVEACTNO \r\n" + 
				"WHERE m.RECEIVEACTNO = :RECEIVEACTNO AND m2.RECEIVEACTSTATE = 'Created'";
		Map<String, Object> hashMap = new HashMap<String,Object> ();
		hashMap.put("RECEIVEACTNO", receiveActNo);
		List<Map<String, Object>> queryForList = IDMFrameServiceProxy.getSqlTemplate().queryForList(sql, hashMap);
		return AjaxResult.me().setResultObj(queryForList);
	}

}
