package com.cim.idm.service.Impl;

import com.alibaba.fastjson.JSONArray;
import com.cim.idm.dao.MaterialReversalDao;
import com.cim.idm.exception.GlobalException;
import com.cim.idm.framework.IDMFrameServiceProxy;
import com.cim.idm.framework.data.EventInfo;
import com.cim.idm.service.IMaterialUndoService;
import com.cim.idm.service.impl.ToSAPServiceImpl;
import com.cim.idm.utils.AjaxResult;
import com.cim.idm.utils.EventInfoUtil;
import com.cim.idm.wmspackage.materialpacking.MaterialPackingServiceProxy;
import com.cim.idm.wmspackage.materialpacking.management.data.MaterialPacking;
import com.cim.idm.wmspackage.materialpacking.management.data.MaterialPackingKey;
import com.cim.idm.wmspackage.materialpacking.management.info.RemoveInfo;
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.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("MaterialUndo")
public class MaterialUndoServiceImpl implements IMaterialUndoService {

	@Autowired
	private ToSAPServiceImpl toSAPService;

	@Autowired
	private MaterialReversalDao materialReversalDao;
	/**
	 * 入库冲销
	 * @param undoId
	 * @param user
	 */
	@Transactional
	public void rkUndo (String undoId, String user) throws Exception {

		String billCode = toSAPService.cancelShipInter(undoId, user);
		if (billCode == null) {
			throw new GlobalException("报送ERP失败,请联系IT处理！");
		}

		EventInfo makeEventInfo = new EventInfoUtil().makeEventInfo("MakeUndo", user, "MakeUndo");
		String  condition="WHERE UNDOID =? ";
		String[] bindSet={undoId};
		//根据物料凭证找到所有的待冲销数据，更新库存状态为创建
		List<MaterialPacking> list = MaterialPackingServiceProxy.getMaterialPackingService().select(condition, bindSet);
		Map<String, Object> hashMap = new HashMap<String, Object> ();
		hashMap.put("stockState", "Created");
		SetEventInfo setEventInfo = new SetEventInfo();
		setEventInfo.setUserColumns(hashMap);
		for (MaterialPacking materialPacking : list) {
			MaterialPackingKey key = materialPacking.getKey();
			MaterialPackingServiceProxy.getMaterialPackingService().setEvent(key, makeEventInfo, setEventInfo);
		}

//		String sql = "UPDATE BS_MATERIALPACKINGUNDOINFO b SET b.FLAG = 'Y' WHERE b.UNDOID = :UNDOID";
//		Map<String, Object> hashMap2 = new HashMap<String, Object> ();
//		hashMap2.put("UNDOID", undoId);
//		IDMFrameServiceProxy.getSqlTemplate().update(sql, hashMap2);
		// 更新凭证冲销状态
		MaterialReversalDao.updateReversalUnDoId(undoId);
	}
	
	/**
	 * 成品入库冲销
	 * @param undoId
	 * @param user
	 */
	@Transactional
	public void cprkUndo (String undoId, String user) throws Exception {
		String billCode = toSAPService.cancelShipInter(undoId, user);
		if (billCode == null) {
			throw new GlobalException("报送ERP失败,请联系IT处理！");
		}
		EventInfo makeEventInfo = new EventInfoUtil ().makeEventInfo("MakeUndo", user, "MakeUndo");
		String  condition="SELECT MATERIALPACKINGNAME FROM MATERIALPACKING WHERE UNDOID = :UNDOID ";
//		String[] bindSet={undoId};
		Map<String, Object> hashMap = new HashMap<String, Object> ();
		hashMap.put("UNDOID", undoId);
		//根据物料凭证找到所有的待冲销数据，更新库存状态为创建
		List<Map<String, Object>> MPlIST = IDMFrameServiceProxy.getSqlTemplate().queryForList(condition, hashMap);
		SetEventInfo setEventInfo = new SetEventInfo();
		setEventInfo.setUserColumns(hashMap);
		RemoveInfo removeInfo = new RemoveInfo();
		for (Map<String, Object> MP : MPlIST) {
			//根据当前的数据跟新完工报告且删除入库表的数据
			String sql = "SELECT M.RECEIVEREQUESTNAME,M.RECEIVEREQUESTDETAILNAME,M.QTY FROM MATERIALPACKINGSUB M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME\r\n" + 
					"UNION \r\n" + 
					"SELECT M.RECEIVEREQUESTNAME,M.RECEIVEREQUESTDETAILNAME,M.QTY FROM MATERIALPACKINGSUBHISTORY M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME";
			String MATERIALPACKINGNAME = MP.get("MATERIALPACKINGNAME").toString();
			hashMap.put("MATERIALPACKINGNAME", MATERIALPACKINGNAME);
			List<Map<String, Object>> queryForList = IDMFrameServiceProxy.getSqlTemplate().queryForList(sql, hashMap);
			for (int i = 0; i < queryForList.size(); i++) {
				String dh = queryForList.get(i).get("RECEIVEREQUESTNAME").toString();
				hashMap.put("RECEIVEREQUESTNAME", dh);
				String hh = queryForList.get(i).get("RECEIVEREQUESTDETAILNAME").toString();
				hashMap.put("RECEIVEREQUESTDETAILNAME", hh);
//				String sl = queryForList.get(i).get("QTY").toString();
				String updateSql = "UPDATE MATERIALRECEIVEREQUESTDETAIL T  \r\n" + 
						"SET T.RECEIVEDQUANTITY = T.RECEIVEDQUANTITY - (  \r\n" + 
						"    SELECT NVL(SUM(M.QTY),0)  \r\n" + 
						"    FROM MATERIALPACKINGSUB M  \r\n" + 
						"    WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME  \r\n" + 
						"      AND M.RECEIVEREQUESTNAME = T.RECEIVEREQUESTNAME  \r\n" + 
						"      AND M.RECEIVEREQUESTDETAILNAME = T.RECEIVEREQUESTDETAILNAME  \r\n" + 
						")  \r\n" + 
						"WHERE T.RECEIVEREQUESTNAME = :RECEIVEREQUESTNAME  \r\n" + 
						"  AND T.RECEIVEREQUESTDETAILNAME = :RECEIVEREQUESTDETAILNAME";
				IDMFrameServiceProxy.getSqlTemplate().update(updateSql, hashMap);
				
				
				String updateSql2 = "UPDATE MATERIALRECEIVEREQUESTDETAIL T  \r\n" + 
						"SET T.RECEIVEDQUANTITY = T.RECEIVEDQUANTITY - (  \r\n" + 
						"    SELECT NVL(SUM(M.QTY),0)  \r\n" + 
						"    FROM MATERIALPACKINGSUBHISTORY M  \r\n" + 
						"    WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME  \r\n" + 
						"      AND M.RECEIVEREQUESTNAME = T.RECEIVEREQUESTNAME  \r\n" + 
						"      AND M.RECEIVEREQUESTDETAILNAME = T.RECEIVEREQUESTDETAILNAME  \r\n" + 
						")  \r\n" + 
						"WHERE T.RECEIVEREQUESTNAME = :RECEIVEREQUESTNAME  \r\n" + 
						"  AND T.RECEIVEREQUESTDETAILNAME = :RECEIVEREQUESTDETAILNAME";
				IDMFrameServiceProxy.getSqlTemplate().update(updateSql2, hashMap);
				
				String deleteSql = " DELETE FROM MATERIALPACKINGSUB T WHERE T.RECEIVEREQUESTNAME = :RECEIVEREQUESTNAME AND "
						+ "T.RECEIVEREQUESTDETAILNAME = :RECEIVEREQUESTDETAILNAME AND T.MATERIALPACKINGNAME = :MATERIALPACKINGNAME";
				IDMFrameServiceProxy.getSqlTemplate().update(deleteSql, hashMap);
				
				String MESsQL = " UPDATE BS_MES_SHIPPED T SET T.RECEIVE_FLAG = 'N' WHERE T.LOTNAME = :MATERIALPACKINGNAME ";
				IDMFrameServiceProxy.getSqlTemplate().update(MESsQL, hashMap);
			}
			MaterialPackingServiceProxy.getMaterialPackingService().remove(new MaterialPackingKey("SDK", MATERIALPACKINGNAME), makeEventInfo, removeInfo);
		}
		
//		String sql = "UPDATE IF_ERPUNDO T SET T.FLAG = 'Y' WHERE  T.UNDOID = :UNDOID ";
//		Map<String, Object> hashMap2 = new HashMap<String, Object> ();
//		hashMap2.put("UNDOID", undoId);
//		IDMFrameServiceProxy.getSqlTemplate().update(sql, hashMap2);
		// 更新凭证冲销状态
		MaterialReversalDao.updateReversalUnDoId(undoId);
	}


	/**
	 * 出库冲销
	 * @param undoId
	 * @param user
	 */
	@Transactional
	public void ckUndo (String undoId, String user) throws Exception {

		String billCode = toSAPService.cancelShipInter(undoId, user);
		if (billCode == null) {
			throw new GlobalException("报送ERP失败,请联系IT处理！");
		}

		EventInfo makeEventInfo = new EventInfoUtil ().makeEventInfo("MakeUndo", user, "MakeUndo");
		String  condition="WHERE UNDOID =? ";
		String[] bindSet={undoId};
		//根据物料凭证找到所有的待冲销数据，更新库存状态为创建
		List<MaterialPacking> list = MaterialPackingServiceProxy.getMaterialPackingService().select(condition, bindSet);
		Map<String, Object> hashMap = new HashMap<String, Object> ();
		hashMap.put("stockState", "Stocked");
		hashMap.put("shipRequestName", "");
		SetEventInfo setEventInfo = new SetEventInfo();
		for (MaterialPacking materialPacking : list) {
			MaterialPackingKey key = materialPacking.getKey();
			//获取实际发货数量
			Double materialQuantity = materialPacking.getMaterialQuantity();
			Double materialQuantity2 = materialPacking.getMaterialQuantity2();
			String shipRequestName = materialPacking.getShipRequestName();
			//判断批次现在的库存状态，如果是已出库说明Box已被该单据完全出库，从出库明细表获取信息更新数量，如果状态还是在库更新数量为原有基础上增加
			String pcSql = "MERGE INTO MATERIALPACKING T USING (SELECT MATERIALPACKINGNAME,SUM(QTY) QTY FROM \n" +
					"(SELECT DISTINCT M.MATERIALPACKINGNAME,M.QTY FROM MATERIALPACKINGSUB M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME AND M.RECEIVEREQUESTNAME = :SHIPREQUESTNAME\n" +
					"UNION \n" +
					"SELECT  DISTINCT M.MATERIALPACKINGNAME,M.QTY FROM MATERIALPACKINGSUBHISTORY M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME AND M.RECEIVEREQUESTNAME = :SHIPREQUESTNAME)\n" +
					"GROUP BY MATERIALPACKINGNAME) M ON (T.MATERIALPACKINGNAME = M.MATERIALPACKINGNAME )\n" +
					"WHEN MATCHED THEN UPDATE SET T.MATERIALQUANTITY = T.MATERIALQUANTITY + M.QTY";
			if ("Stocked".equals(materialPacking.getStockState())) {
				pcSql = "MERGE INTO MATERIALPACKING T USING (SELECT MATERIALPACKINGNAME,SUM(QTY) QTY FROM \n" +
						"(SELECT DISTINCT M.MATERIALPACKINGNAME,M.QTY FROM MATERIALPACKINGSUB M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME AND M.RECEIVEREQUESTNAME = :SHIPREQUESTNAME\n" +
						"UNION \n" +
						"SELECT  DISTINCT M.MATERIALPACKINGNAME,M.QTY FROM MATERIALPACKINGSUBHISTORY M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME AND M.RECEIVEREQUESTNAME = :SHIPREQUESTNAME)\n" +
						"GROUP BY MATERIALPACKINGNAME) M ON (T.MATERIALPACKINGNAME = M.MATERIALPACKINGNAME )\n" +
						"WHEN MATCHED THEN UPDATE SET T.MATERIALQUANTITY = T.MATERIALQUANTITY + M.QTY,T.MATERIALQUANTITY2 = 0 ";
			} else if ("StockOut".equals(materialPacking.getStockState())) {
				pcSql = "MERGE INTO MATERIALPACKING T USING (SELECT MATERIALPACKINGNAME,SUM(QTY) QTY FROM \n" +
						"(SELECT DISTINCT M.MATERIALPACKINGNAME,M.QTY FROM MATERIALPACKINGSUB M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME AND M.RECEIVEREQUESTNAME = :SHIPREQUESTNAME\n" +
						"UNION \n" +
						"SELECT  DISTINCT M.MATERIALPACKINGNAME,M.QTY FROM MATERIALPACKINGSUBHISTORY M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME AND M.RECEIVEREQUESTNAME = :SHIPREQUESTNAME)\n" +
						"GROUP BY MATERIALPACKINGNAME) M ON (T.MATERIALPACKINGNAME = M.MATERIALPACKINGNAME )\n" +
						"WHEN MATCHED THEN UPDATE SET T.MATERIALQUANTITY =  M.QTY,T.MATERIALQUANTITY2 = 0 ";
			}
//			BigDecimal fmaterialQuantity = new BigDecimal(materialQuantity);
//			BigDecimal fmaterialQuantity2 = new BigDecimal(materialQuantity2);
//			if (fmaterialQuantity.compareTo(fmaterialQuantity2) == 0) {
//				fmaterialQuantity = BigDecimal.ZERO;
//			}
//			hashMap.put("materialQuantity", fmaterialQuantity);
//			hashMap.put("materialQuantity2", 0);
			setEventInfo.setUserColumns(hashMap);
			MaterialPackingServiceProxy.getMaterialPackingService().setEvent(key, makeEventInfo, setEventInfo);
			
			String cxSql = "MERGE INTO MATERIALSHIPREQUESTDETAIL T USING (SELECT RECEIVEREQUESTNAME,RECEIVEREQUESTDETAILNAME,SUM(QTY) QTY FROM \r\n" + 
					"(SELECT DISTINCT M.RECEIVEREQUESTNAME,M.RECEIVEREQUESTDETAILNAME,M.QTY FROM MATERIALPACKINGSUB M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME\r\n" +
					"UNION \r\n" + 
					"SELECT DISTINCT M.RECEIVEREQUESTNAME,M.RECEIVEREQUESTDETAILNAME,M.QTY FROM MATERIALPACKINGSUBHISTORY M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME)\r\n" +
					"GROUP BY RECEIVEREQUESTNAME,RECEIVEREQUESTDETAILNAME) M ON (T.SHIPREQUESTNAME = M.RECEIVEREQUESTNAME AND T.SHIPREQUESTDETAILNAME = M.RECEIVEREQUESTDETAILNAME)\r\n" + 
					"WHEN MATCHED THEN UPDATE SET T.ASSIGNEDQUANTITY = T.ASSIGNEDQUANTITY - M.QTY,T.SALEOUTQUANTITY = T.SALEOUTQUANTITY - M.QTY";


			//根据当前的出库数量更新saleQty
//			String sql = "SELECT M.RECEIVEREQUESTNAME,M.RECEIVEREQUESTDETAILNAME,M.QTY FROM MATERIALPACKINGSUB M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME\r\n" + 
//					"UNION \r\n" + 
//					"SELECT M.RECEIVEREQUESTNAME,M.RECEIVEREQUESTDETAILNAME,M.QTY FROM MATERIALPACKINGSUBHISTORY M WHERE M.MATERIALPACKINGNAME = :MATERIALPACKINGNAME";
			String MATERIALPACKINGNAME = materialPacking.getMaterialPackingName().toString();
			hashMap.put("MATERIALPACKINGNAME", MATERIALPACKINGNAME);
			hashMap.put("SHIPREQUESTNAME", shipRequestName);
			IDMFrameServiceProxy.getSqlTemplate().update(pcSql, hashMap);
			IDMFrameServiceProxy.getSqlTemplate().update(cxSql, hashMap);
		}

		// 更新凭证冲销状态
		MaterialReversalDao.updateReversalUnDoId(undoId);
	}

	/**
	 * 转库
	 * @param undoId
	 * @param user
	 */
	@Transactional
	public void zkUndo (String undoId, String user) throws Exception {

		String billCode = toSAPService.cancelShipInter(undoId, user);
		if (billCode == null) {
			throw new GlobalException("报送ERP失败,请联系IT处理！");
		}

		EventInfo makeEventInfo = new EventInfoUtil().makeEventInfo("MakeUndo", user, "MakeUndo");
		String  condition="WHERE UNDOID =? ";
		String[] bindSet={undoId};
		//根据物料凭证找到所有的待冲销数据，更新库存状态为创建
		List<MaterialPacking> list = MaterialPackingServiceProxy.getMaterialPackingService().select(condition, bindSet);

		for (MaterialPacking materialPacking : list) {
			Map<String, Object> hashMap = new HashMap<String, Object> ();
			hashMap.put("erpLocation", materialPacking.getPreErpLocation());
			hashMap.put("locationName", materialPacking.getPreLocationName());
			hashMap.put("preErpLocation", materialPacking.getErpLocation());
			hashMap.put("preLocationName", materialPacking.getLocationName());
			SetEventInfo setEventInfo = new SetEventInfo();
			setEventInfo.setUserColumns(hashMap);
			MaterialPackingKey key = materialPacking.getKey();
			MaterialPackingServiceProxy.getMaterialPackingService().setEvent(key, makeEventInfo, setEventInfo);
		}

		// 更新凭证冲销状态
		MaterialReversalDao.updateReversalUnDoId(undoId);
	}

}
