package com.cim.idm.service.Impl;

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.mwmsextend.generic.util.CommonValidation;
import com.cim.idm.mwmsextend.materialpacking.service.MaterialPackingServiceImpl;
import com.cim.idm.service.impl.ToSAPServiceImpl;
import com.cim.idm.utils.CommonUtils;
import com.cim.idm.utils.EventInfoUtil;
import com.cim.idm.wmspackage.materialpacking.MaterialPackingServiceProxy;
import com.cim.idm.wmspackage.materialpacking.management.data.MaterialPackingKey;
import com.cim.idm.wmspackage.materialpacking.management.info.SetEventInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Service("SaleOut")
public class SaleOutServiceImpl {
	private EventInfo makeEventInfo;

	@Autowired
	private ToSAPServiceImpl toSAPService;

	CommonValidation comm = new CommonValidation ();
	private CommonUtils untils=new CommonUtils();
	private MaterialPackingServiceImpl mp = new MaterialPackingServiceImpl();
	@Transactional
	public boolean BindSalePreToSale(String saleOrder,String materialSpecName,String sdk_id,String user,
			String phase,String salePreOrder) throws GlobalException {
		EventInfoUtil eventInfoUtil = new EventInfoUtil();
		makeEventInfo = eventInfoUtil.makeEventInfo("BindSalePreToSale", user, "BindSalePreToSale");
		//查询出所有满足备货条件的预备货批次明细
		String pcSql = "SELECT\r\n" + 
				"	m.MATERIALPACKINGNAME,\r\n" + 
				"	m.SDK_ID ,\r\n" + 
				"	m.PHASE ,\r\n" + 
				"	m.CHARGE,\r\n" + 
				"	m.MATERIALQUANTITY,\r\n" + 
				"	m.MATERIALQUANTITY2\r\n" + 
				"FROM\r\n" + 
				"	MATERIALPACKING m\r\n" + 
				"LEFT JOIN MATERIALSHIPREQUEST m2 ON\r\n" + 
				"	m.SHIPREQUESTNAME = m2.SHIPREQUESTNAME\r\n" + 
				"WHERE\r\n" + 
				"	m2.SHIPREQUESTNAME = :SALEPREORDER";
		Map<String, Object> hashMap2 = new HashMap<String,Object> ();
		hashMap2.put("SALEPREORDER", salePreOrder);
		List<Map<String, Object>> queryForList = IDMFrameServiceProxy.getSqlTemplate().queryForList(pcSql, hashMap2);
		for (Map<String, Object> map : queryForList) {
			String materialQuatity2 = map.get("MATERIALQUANTITY2").toString();
			String materialPackingName = map.get("MATERIALPACKINGNAME").toString();
			MaterialPackingKey materialPackingKey = new MaterialPackingKey("SDK",materialPackingName);
			BigDecimal pcQty = new BigDecimal(materialQuatity2);
			String saleSql = "SELECT\r\n" + 
					"	m.SHIPREQUESTNAME ,\r\n" + 
					"	m.SHIPREQUESTDETAILNAME ,\r\n" + 
					"	m.REQUESTQUANTITY ,\r\n" + 
					"	m.ASSIGNEDQUANTITY ,\r\n" + 
					"	(m.REQUESTQUANTITY - m.ASSIGNEDQUANTITY) MINUSQTY\r\n" + 
					"FROM\r\n" + 
					"	MATERIALSHIPREQUESTDETAIL m\r\n" + 
					"WHERE\r\n" + 
					"	m.SHIPREQUESTNAME = :SALEORDER\r\n" + 
					"	AND m.MATERIALSPECNAME = :MATERIALSPECNAME\r\n" + 
					"	AND (:SDK_ID IS NULL OR m.SDK_ID = :SDK_ID )\r\n" + 
					"	AND (:PHASE IS NULL OR m.PHASE = :PHASE ) \r\n" + 
					"	AND m.REQUESTQUANTITY - m.ASSIGNEDQUANTITY > 0 ORDER BY m.SHIPREQUESTDETAILNAME ASC";
			hashMap2.put("SALEORDER", saleOrder);
			hashMap2.put("MATERIALSPECNAME", materialSpecName);
			hashMap2.put("SDK_ID", sdk_id);
			hashMap2.put("PHASE", phase);
			List<Map<String, Object>> queryForList2 = IDMFrameServiceProxy.getSqlTemplate().queryForList(saleSql, hashMap2);
			for (Map<String, Object> map2 : queryForList2) {
				String shipRequestName = map2.get("SHIPREQUESTNAME").toString();
				String shipRequestDetailName = map2.get("SHIPREQUESTDETAILNAME").toString();
				String minusQty = map2.get("MINUSQTY").toString();
				BigDecimal fdhQty = new BigDecimal(minusQty);
				String updateSql = "UPDATE MATERIALSHIPREQUESTDETAIL SET ASSIGNEDQUANTITY = ASSIGNEDQUANTITY + :QTY "
						+ "WHERE SHIPREQUESTNAME = :SHIPREQUESTNAME AND SHIPREQUESTDETAILNAME  = :SHIPREQUESTDETAILNAME";
				String insertSql = "INSERT INTO MATERIALPACKINGSUB (MATERIALPACKINGNAME, RECEIVEREQUESTNAME,RECEIVEREQUESTDETAILNAME,QTY)\r\n" + 
						"VALUES (:MATERIALPACKINGNAME, :RECEIVEREQUESTNAME,:RECEIVEREQUESTDETAILNAME,:QTY)";
				//比较批次数量和单号数量是否一致，不一致分情况判断
				if (pcQty.compareTo(fdhQty) == 0) {//数量一致
					//更新订单数量
					Map<String, Object> ddUpdate = new HashMap<String,Object> ();
					ddUpdate.put("QTY", pcQty);
					ddUpdate.put("SHIPREQUESTNAME", shipRequestName);
					ddUpdate.put("SHIPREQUESTDETAILNAME", shipRequestDetailName);
					IDMFrameServiceProxy.getSqlTemplate().update(updateSql, ddUpdate);
					//绑定批次信息到新订单
					SetEventInfo setEventInfo = new SetEventInfo();
					Map<String, Object> pcUpdate = new HashMap<String,Object> ();
					pcUpdate.put("shipRequestName", shipRequestName);
					setEventInfo.setUserColumns(pcUpdate);
					MaterialPackingServiceProxy.getMaterialPackingService().setEvent(materialPackingKey, makeEventInfo, setEventInfo);
					//插入过账条码表
					Map<String, Object> tm = new HashMap<String,Object> ();
					tm.put("MATERIALPACKINGNAME", materialPackingName);
					tm.put("RECEIVEREQUESTNAME", shipRequestName);
					tm.put("RECEIVEREQUESTDETAILNAME", shipRequestDetailName);
					tm.put("QTY", pcQty);
					IDMFrameServiceProxy.getSqlTemplate().update(insertSql, tm);
					pcQty = pcQty.subtract(fdhQty);
					fdhQty = fdhQty.subtract(fdhQty);
				} else if (pcQty.compareTo(fdhQty) > 0) {//批次数量大
					Map<String, Object> ddUpdate = new HashMap<String,Object> ();
					ddUpdate.put("QTY", fdhQty);
					ddUpdate.put("SHIPREQUESTNAME", shipRequestName);
					ddUpdate.put("SHIPREQUESTDETAILNAME", shipRequestDetailName);
					IDMFrameServiceProxy.getSqlTemplate().update(updateSql, ddUpdate);
					//绑定批次信息到新订单
					SetEventInfo setEventInfo = new SetEventInfo();
					Map<String, Object> pcUpdate = new HashMap<String,Object> ();
					pcUpdate.put("shipRequestName", shipRequestName);
					setEventInfo.setUserColumns(pcUpdate);
					MaterialPackingServiceProxy.getMaterialPackingService().setEvent(materialPackingKey, makeEventInfo, setEventInfo);
					//插入过账条码表
					Map<String, Object> tm = new HashMap<String,Object> ();
					tm.put("MATERIALPACKINGNAME", materialPackingName);
					tm.put("RECEIVEREQUESTNAME", shipRequestName);
					tm.put("RECEIVEREQUESTDETAILNAME", shipRequestDetailName);
					tm.put("QTY", fdhQty);
					IDMFrameServiceProxy.getSqlTemplate().update(insertSql, tm);
					pcQty = pcQty.subtract(fdhQty);
					fdhQty = fdhQty.subtract(fdhQty);
				} else {//批次数量小
					Map<String, Object> ddUpdate = new HashMap<String,Object> ();
					ddUpdate.put("QTY", pcQty);
					ddUpdate.put("SHIPREQUESTNAME", shipRequestName);
					ddUpdate.put("SHIPREQUESTDETAILNAME", shipRequestDetailName);
					IDMFrameServiceProxy.getSqlTemplate().update(updateSql, ddUpdate);
					//绑定批次信息到新订单
					SetEventInfo setEventInfo = new SetEventInfo();
					Map<String, Object> pcUpdate = new HashMap<String,Object> ();
					pcUpdate.put("shipRequestName", shipRequestName);
					setEventInfo.setUserColumns(pcUpdate);
					MaterialPackingServiceProxy.getMaterialPackingService().setEvent(materialPackingKey, makeEventInfo, setEventInfo);
					//插入过账条码表
					Map<String, Object> tm = new HashMap<String,Object> ();
					tm.put("MATERIALPACKINGNAME", materialPackingName);
					tm.put("RECEIVEREQUESTNAME", shipRequestName);
					tm.put("RECEIVEREQUESTDETAILNAME", shipRequestDetailName);
					tm.put("QTY", pcQty);
					IDMFrameServiceProxy.getSqlTemplate().update(insertSql, tm);
					pcQty = pcQty.subtract(pcQty);
					fdhQty = fdhQty.subtract(pcQty);
					break;
				}
				
			}
		}
		return true;
	}
	
	
	@Transactional
	public boolean Commit4CToERP(String shipRequestName,List< MaterialPacking> boxList,String user,
			String commitDate,String opcode) throws Exception {
		EventInfoUtil eventInfoUtil = new EventInfoUtil();
		makeEventInfo = eventInfoUtil.makeEventInfo("Commit4CToERP", user, "Commit4CToERP");
		//判断单据类型是否是销售发货单
		String sql = "SELECT m.SHIPREQUESTTYPE FROM MATERIALSHIPREQUEST m WHERE SHIPREQUESTNAME = :SHIPREQUESTNAME";
		Map<String, Object> hashMap = new HashMap<String,Object> ();
		hashMap.put("SHIPREQUESTNAME", shipRequestName);
		List<Map<String,Object>> queryForList = IDMFrameServiceProxy.getSqlTemplate().queryForList(sql, hashMap);
		if (queryForList == null || queryForList.size() < 1) {
			throw new GlobalException("单据不存在");
		} else {
			String string = queryForList.get(0).get("SHIPREQUESTTYPE").toString();
			if (!"4C".equals(string)) {
				throw new GlobalException("单据类型不为发货单");
			}
		}
		List<String> arrayList = new ArrayList<String> ();
		for ( MaterialPacking m : boxList) {
			arrayList.add(m.getMaterialPackingName());
		}
		StringBuffer cklx = new StringBuffer();
		cklx.append("SELECT DISTINCT m.ERPLOCATION FROM MATERIALPACKING m WHERE m.MATERIALPACKINGNAME IN ");
		String str = "";
		str += "(";
		for (String materialPacking : arrayList) {
			str += "'" + materialPacking + "',";
		}
		str += "'')";
		List<Map<String, Object>> queryForList2 = IDMFrameServiceProxy.getSqlTemplate().queryForList(cklx.toString() + str, hashMap);
		for (int i = 0; i < queryForList2.size(); i++) {
			String erpLocation = queryForList2.get(i).get("ERPLOCATION").toString();
			String billCode = toSAPService.SaleStockOut(shipRequestName, "SDK", user,arrayList,erpLocation,commitDate,opcode);
			if (billCode == null || "".equals(billCode)) return false;
			String getMessageID = comm.GetMessageID("SDK");
			//根据单据获取要出库的Box集合
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
			String format = simpleDateFormat.format(new Date());
			untils.SaveUnDoInfo(arrayList, billCode, makeEventInfo,erpLocation,commitDate,"4C",user,shipRequestName);
		}
		
		String updateCommit = "UPDATE MATERIALSHIPREQUEST T SET T.SHIPREQUESTSTATE = 'Completed' WHERE T.SHIPREQUESTNAME = :SHIPREQUESTNAME";
		Map<String, Object> hashMap2 = new HashMap<String,Object> ();
		hashMap2.put("SHIPREQUESTNAME", shipRequestName);
		IDMFrameServiceProxy.getSqlTemplate().update(updateCommit, hashMap2);
		return true;
	}
	
	


}
