package com.cim.idm.service.Impl;

import com.cim.idm.exception.GlobalException;
import com.cim.idm.framework.IDMFrameServiceProxy;
import com.cim.idm.model.OutStockDto;
import com.cim.idm.service.IMaterialShipService;
import org.springframework.stereotype.Service;

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


@Service("MaterialShip")
public class MaterialShipServiceImpl implements IMaterialShipService {

	/**
	 * 出库方法实现
	 */
	@Override
	public Map<String, Object> outStock(OutStockDto outStockDto)  throws Throwable  {
		// 参数非空校验
		String site = outStockDto.getSite();
		String barCode = outStockDto.getBarCode();
		String billNo = outStockDto.getBillNo();
		String detailRowNo = outStockDto.getDetailRowNo();
		String userId = outStockDto.getUserId();
		String storageName = outStockDto.getStorageName();
		
		if(Objects.isNull(site)) {
			throw new GlobalException("site不能为空！");
		}
		if(Objects.isNull(barCode)) {
			throw new GlobalException("barCode不能为空！");
		}
		if(Objects.isNull(billNo)) {
			throw new GlobalException("billNo不能为空！");
		}
		if(Objects.isNull(detailRowNo)) {
			throw new GlobalException("detailRowNo不能为空！");
		}
		if(Objects.isNull(userId)) {
			throw new GlobalException("userId不能为空！");
		}
		Map<String, Object> map = new HashMap<String, Object>();
		// 将前端传入的参数和存储过程中的参数对应起来
		map.put("V_SITE",site);
		map.put("V_BILLNO",billNo);
		map.put("V_DETAILROWNO",detailRowNo);
		map.put("V_BARCODE",barCode);
		map.put("V_USERID",userId);
		map.put("V_KW","");
		map.put("V_RESULT","");
		String procedureName = "CALL SHIP_OUTSTOCK(:V_SITE, :V_BILLNO, :V_DETAILROWNO, :V_BARCODE, :V_KW, :V_USERID,  :V_RESULT)";
		try {
			// 调用存储过程返回参数
			Map<String, Object> queryResult = IDMFrameServiceProxy.getSqlTemplate().queryForMap(procedureName,map);
			
			if(Objects.nonNull(queryResult)) {
				return queryResult;
			}
			throw new GlobalException("未查询到对应参数");
			
		}catch(Throwable e) {
			throw e;
		}
	
	}
	
	/**
	 * 取消出库方法
	 */
	@Override
	public Map<String, Object> cancle(OutStockDto outStockDto) throws Throwable {
		// 参数非空校验
		String site = outStockDto.getSite();
		String barCode = outStockDto.getBarCode();
		String billNo = outStockDto.getBillNo();
		String detailRowNo = outStockDto.getDetailRowNo();
		String userId = outStockDto.getUserId();
		String storageName = outStockDto.getStorageName();

		if(Objects.isNull(site)) {
			throw new GlobalException("site不能为空！");
		}
		if(Objects.isNull(barCode)) {
			throw new GlobalException("barCode不能为空！");
		}
		if(Objects.isNull(billNo)) {
			throw new GlobalException("billNo不能为空！");
		}
		
		if(Objects.isNull(userId)) {
			throw new GlobalException("userId不能为空！");
		}
		Map<String, Object> map = new HashMap<String, Object>();
		// 将前端传入的参数和存储过程中的参数对应起来
		map.put("V_SITE",site);
		map.put("V_BILLNO",billNo);
		map.put("V_BARCODE",barCode);
		map.put("V_USERID",userId);
		//map.put("V_KW",storageName);
		map.put("V_RESULT","");
		String procedureName = "CALL SHIP_OUTSTOCK_CANCEL(:V_SITE, :V_BILLNO, :V_BARCODE, :V_USERID, :V_RESULT)";
		try {
			// 调用存储过程返回参数
			Map<String, Object> queryResult = IDMFrameServiceProxy.getSqlTemplate().executeProcedure(procedureName,map);
			if(Objects.nonNull(queryResult)) {
				return queryResult;
			}
			throw new GlobalException("未查询到对应参数");
			
		}catch(Throwable e) {
			throw e;
		}
	
	}

	/**
	 * 出库前校验
	 */
	@Override
	public String outStockCheck(OutStockDto outStockDto) throws GlobalException {
		
		/**
		 * 
			0.如果无记录，则提示，此物料不在出库列表中;
			0.1 如果DFQTY<0,则提示，此物料已出库完成，无发出库
			1。STOCKSTATE，如果不是Stocked，则提示不在仓库
			2.如果ISRELEASE=0，则提示未释放,单号：LASTEVENTBILLNO
			3.如果DJCK不为空，继续判断TMCK与DJCK不一致，则提示，此条码的仓库不属于调出仓
			4.如果ALLOWOVERPICK=Y,且MATERIALQUANTITY大于DFQTY，则提示此不允许超发;
		 */
		String shipRequestName = outStockDto.getBillNo(); // 单号
		String materialPackingName = outStockDto.getBarCode(); // 条码编号
		String detailRowNo = outStockDto.getDetailRowNo();
		if(Objects.isNull(shipRequestName)) {
			throw new GlobalException("shipRequestName不能为空！");
			}
		if(Objects.isNull(materialPackingName)) {
			throw new GlobalException("materialPackingName不能为空！");
		}
		// 获取物料前校验
		String sql = "SELECT m.SHIPREQUESTNAME,m1.SHIPREQUESTDETAILNAME,m2.STOCKSTATE,m1.ERPLOCATION DJCK,"
				+ " m2.ERPLOCATION TMCK, "
				+ "m2.ISRELEASE,m2.LASTEVENTBILLNO , "
				+ " m2.MATERIALQUANTITY, NVL(m3.ALLOWOVERPICK,'N') ALLOWOVERPICK,m1.REQUESTQUANTITY - NVL(m1.ASSIGNEDQUANTITY,0) DFQTY  " + 
				"FROM MATERIALSHIPREQUEST m   " + 
				"JOIN MATERIALSHIPREQUESTDETAIL m1 ON m.SITENAME=m1.SITENAME  AND m.SHIPREQUESTNAME =m1.SHIPREQUESTNAME " + 
				"JOIN MATERIALPACKING m2 ON m1.SITENAME=m2.SITENAME AND m1.MATERIALSPECNAME=m2.MATERIALSPECNAME " + 
				"JOIN MATERIALSPEC m3 ON m3.SITENAME =m1.SITENAME  AND m3.MATERIALSPECNAME =m1.MATERIALSPECNAME  " + 
				"WHERE m.SHIPREQUESTNAME =:SHIPREQUESTNAME AND  m2.MATERIALPACKINGNAME=:MATERIALPACKINGNAME";
		
		Map<String, Object> bindMap = new HashMap<String, Object>();
		bindMap.put("SHIPREQUESTNAME",shipRequestName); 
		bindMap.put("MATERIALPACKINGNAME",materialPackingName); 
		// 如果无记录，则提示，此物料不在出库列表中;
		List<Map<String,Object>> list = IDMFrameServiceProxy.getSqlTemplate().queryForList(sql, bindMap);
		
		if(Objects.isNull(list) || list.isEmpty()) {
			throw new GlobalException("此物料不在出库列表中！");
			}
		
		Map map = list.get(0);
		// 0.1 如果DFQTY<0,则提示，此物料已出库完成，无发出库
		float dfqty = Float.parseFloat(map.get("DFQTY").toString());
		if(dfqty <= 0) {
			throw new GlobalException("此物料已出库完成，无发出库！");
		}
		
		// 1.STOCKSTATE，如果不是Stocked，则提示不在仓库
		String stockState = map.get("STOCKSTATE").toString();
		if(!stockState.equals("Stocked")) {
			throw new GlobalException("该物料不在仓库！");
		}
		
		// 2.如果ISRELEASE=0，则提示未释放
		Integer isRelease = Integer.parseInt(map.get("ISRELEASE").toString());
		if(isRelease == 0) {		
			String lastEventBillNo = map.get("LASTEVENTBILLNO").toString();
			throw new GlobalException("该条码未释放！单号：" + lastEventBillNo);
		}
		String RowNo = map.get("SHIPREQUESTDETAILNAME").toString();
		if (detailRowNo == null || !detailRowNo.equals(RowNo)) {
			throw new GlobalException("所选行号与物料不一致！");
		}
		
		//3.如果DJCK不为空，继续判断TMCK与DJCK不一致，则提示，此条码的仓库不属于调出仓
		/*
		 * String dbck = map.get("DBCK").toString(); String tmck =
		 * map.get("TMCK").toString(); if(Objects.nonNull(dbck)) {
		 * if(!dbck.equals(tmck)) { throw new GlobalException("此条码的仓库不属于调出仓！"); } }
		 */
		
		// 4.如果ALLOWOVERPICK=Y,且MATERIALQUANTITY大于DFQTY，则提示此不允许超发;
		String allowOverPick = map.get("ALLOWOVERPICK").toString();
		Float materialQuantity = Float.parseFloat(map.get("MATERIALQUANTITY").toString());
		if(allowOverPick.equals("Y") && materialQuantity > dfqty ) {
			throw new GlobalException("此物料不允许超发！");
			
		}
		String shipRequestDetailName = map.get("SHIPREQUESTDETAILNAME").toString();
		
		return shipRequestDetailName;
		 
	}


}
