/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：物流管理システム
*   ソースファイル名：JDKCommon32CC.java
*   作成者          ：富士通
*   日付            ：2011年10月20日
*＜機能概要＞
*   強制機器出荷登録CCクラスです。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v1.00.00    2011/10/20   FJ          新規作成
*
**********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.fujitsu.futurity.bp.custom.mapping.DKSV0076_DKSV0076OP_EDKA0010003BSMapper;
import com.fujitsu.futurity.bp.custom.mapping.DKSV0108_DKSV0108OP_EDK0011D020BSMapper;
import com.fujitsu.futurity.bp.custom.mapping.DKSV0108_DKSV0108OP_EKK0081A010BSMapper;
import com.fujitsu.futurity.bp.x21.bpm.ServiceComponentRequestInvoker;
import com.fujitsu.futurity.bp.x21.bpm.db.SessionHandle;
import com.fujitsu.futurity.bp.x21.bpm.exception.RequestParameterException;
import com.fujitsu.futurity.bp.x21.bpm.parameter.IRequestParameterReadWrite;
import com.fujitsu.futurity.bp.x21.cc.AbstractCommonComponent;
import com.fujitsu.futurity.bp.x21.cc.exception.SCCallException;
import com.fujitsu.futurity.bp.x21.sc.exception.SCException;
import com.fujitsu.futurity.model.ejb.common.JSYejbLog;
import com.fujitsu.futurity.model.ejb.common.StatusCodes;

import eo.common.constant.JDKStrConst;
import eo.common.constant.JPCModelConstant;
import eo.ejb.cbs.cbsmsg.EDK0011C080CBSMsg;
import eo.ejb.cbs.cbsmsg.EDKA0010003CBSMsg1List;


/**
 * 強制機器出荷登録CCクラスです。
 * @author 富士通
 */
public class JDKCommon32CC extends AbstractCommonComponent
{
	/** CC名 */
	private static final String DKSV010801CC = "DKSV010801CC";
	private static final String DKSV010802CC = "DKSV010802CC";
	/** SC名 */
	private static final String DKSV010803SC = "DKSV010803SC";

	/** マッパー */
	private static final DKSV0108_DKSV0108OP_EKK0081A010BSMapper CONTRACT_MAPPER = new DKSV0108_DKSV0108OP_EKK0081A010BSMapper();
	/** マッパー */
	private static final DKSV0108_DKSV0108OP_EDK0011D020BSMapper APPROVE_MAPPER = new DKSV0108_DKSV0108OP_EDK0011D020BSMapper();
	
	/** サービス契約ステータス */
	private static final Set<String> CONTRACTED_STATUS = new HashSet<String>();
	static
	{
		CONTRACTED_STATUS.add("910");	// 解約済
		CONTRACTED_STATUS.add("920");	// キャンセル済
	}
	
	/**
	 * 強制機器出荷登録処理を行います。
	 * @param handle セッションハンドル
	 * @param param パラメータ
	 * @param fixedText 定型文字
	 * @return パラメータ
	 * @throws Throwable 
	 */
	@SuppressWarnings("unchecked")
	public IRequestParameterReadWrite createKsiKkshka(SessionHandle handle, IRequestParameterReadWrite param, String fixedText) throws Throwable
	{
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();
		
		HashMap<String, Object> contractsParamMap = new HashMap<String, Object>();
		contractsParamMap = CONTRACT_MAPPER.editInMsg(param);
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "サービス契約一意照会処理の実行");
		Map contractResult = scCall.run(contractsParamMap, handle);
		CONTRACT_MAPPER.editResultRP(contractResult, param);
		if (JDKBPCommon.hasError(param))
		{
			throw new SCCallException("サービス契約一意照会処理失敗", "0", 
										Integer.parseInt(param.getControlMapData("returnCode").toString()));
		}
		
		if (!checkSvcKeiStat(param))
		{
			JDKBPCommon.addError(param, "dohubt_kktk_svc_kei_no_err", "EG", "EDK0011D020", StatusCodes.RELATION_ERR, 0);
			throw new SCCallException("戻り値不正", "0", StatusCodes.RELATION_ERR);
		}
		
		
		if (!isEnoughStock(handle, param))
		{
			JDKBPCommon.addError(param, "dohubt_kktk_svc_kei_no_err", "EH", "EDK0011D020", StatusCodes.RELATION_ERR, 0);
			throw new SCCallException("在庫不足", "0", StatusCodes.RELATION_ERR);
		}
		
		HashMap<String, Object> approveParamMap = APPROVE_MAPPER.editInMsg(param);
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "配送受付処理の実行");
		Map approveResult = scCall.run(approveParamMap, handle);
		
		param = APPROVE_MAPPER.editResultRP(approveResult, param);
		if (JDKBPCommon.hasError(param))
		{
			throw new SCCallException("配送受付処理失敗", "0", StatusCodes.RELATION_ERR);
		}
		
		
		if (JPCModelConstant.FUNC_CD_2.equals(((Map)param.getData(DKSV010802CC)).get(EDK0011C080CBSMsg.FUNC_CODE)))
		{
			return param;
		}
		
		Map inputs01CC = (Map)param.getData(DKSV010801CC);
		Map inputs02CC = (Map)param.getData(DKSV010802CC);
		Map inputs03SC = (Map)param.getData(DKSV010803SC);
		List<HashMap> haisotbpnList = (ArrayList<HashMap>)inputs01CC.get("EKK0081A010CBSMsg1List");
		List<HashMap> haisoList = (ArrayList<HashMap>)inputs02CC.get("EDK0011D020CBSMsg1List");
		
		List<Map> buppins = new ArrayList<Map>();
		// 機器出荷情報更新を使用し、宅内のデータを更新する
		for (int i = 0; i < haisotbpnList.size(); i++)
		{
			Map buppin = new HashMap(haisotbpnList.get(i));
			
			buppin.put("idomoto_kriplace_skcd", "1");
			buppin.put(EDKA0010003CBSMsg1List.KNRI_PLC_CD, inputs03SC.get("kiki_hkat_shitei_soko_cd"));
			buppin.put(EDKA0010003CBSMsg1List.KNRI_PLC_SLF_CD, inputs03SC.get("kiki_hkat_shitei_skdn_cd"));
			
			buppin.put("taknkiki_model_cd", haisoList.get(i).get("taknkiki_model_cd"));
			
			buppin.put(EDKA0010003CBSMsg1List.JZAIKO_NUM, "0");
			buppin.put(EDKA0010003CBSMsg1List.HAISO_UK_JUCHU_NUM, "1");
			buppin.put(EDKA0010003CBSMsg1List.TJITU_HAISO_SHKA_NUM, "0");
			
			buppins.add(buppin);
		}
		doUpdateStocks(buppins, handle, param);
		
		return param;
	}
	
	
	@SuppressWarnings("unchecked")
	private boolean isEnoughStock(SessionHandle handle, IRequestParameterReadWrite param) throws SCException, Exception {
		JDKStockMap stocks = new JDKStockMap();

		Map dataMap = (Map)param.getData("DKSV010802CC");
		List<Map> dataList = (List)dataMap.get("EDK0011D020CBSMsg1List");
		for (Map data : dataList) {
			String warehouse = (String)dataMap.get("haiso_moto_soko_cd");
			String shelf = (String)data.get("haiso_moto_skdn_cd");
			String modelNo = (String)data.get("taknkiki_model_cd");
			// 移動元管理場所識別コードは"1"（倉庫）固定
			String [] keies = {warehouse, shelf, modelNo, JDKStrConst.KANRI_PLACE_SKB_SOKO};
			
			Integer moves = 1;
			
			if (!stocks.hasKey(keies)) {
				// 宅内機器物流在庫一意照会(EKKA0020005)を実行し、在庫情報を得る
				// 移動元管理場所識別コードは"1"（倉庫）固定
				stocks.setValue(JDKBPCommon.getStockAmount(warehouse, shelf, modelNo, JDKStrConst.KANRI_PLACE_SKB_SOKO, handle, param), keies);
			}
			stocks.decrease(moves, keies);
			
			if (stocks.isNegative(keies))
			{
				return false;
			}
		}
		
		return true;
	}
	
	/**
	 * サービス契約ステータスを判定する
	 * @param param パラメータ
	 * @return ステータス一覧
	 * @throws RequestParameterException 例外発生時
	 */
	@SuppressWarnings("unchecked")
	private boolean checkSvcKeiStat(IRequestParameterReadWrite param) throws RequestParameterException  
	{
		HashMap inMap = (HashMap)param.getData(DKSV010801CC);
		
		List<Map> list = (List)inMap.get("EKK0081A010CBSMsg1List");
		
		for (Map data : list) {
			if (CONTRACTED_STATUS.contains(data.get("svc_kei_stat")))
			{
				return false;
			}
		}
		
		return true;
	}

	@SuppressWarnings("unchecked")
	private void doUpdateStocks(List<Map> inputDatas, SessionHandle handle, IRequestParameterReadWrite param)
	throws Throwable
	{
		Map workMap = (Map)param.getMappingWorkArea();
		HashMap dataMap = new HashMap();
		workMap.put("work", dataMap);
		
		Map work =  (Map)param.getMappingWorkArea().get("work");
		work.put("buppin_list", inputDatas);
		
		DKSV0076_DKSV0076OP_EDKA0010003BSMapper mapper = new DKSV0076_DKSV0076OP_EDKA0010003BSMapper();
		HashMap inMap = mapper.editInMsg(param);
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "機器出荷情報更新処理の実行");
		Map result = new ServiceComponentRequestInvoker().run(inMap, handle);
		mapper.editResultRP(result, param);
		
		if (JDKBPCommon.hasError(param))
		{
			throw new SCCallException("機器出荷情報更新処理失敗", "0", 
				Integer.parseInt(param.getControlMapData("returnCode").toString()));
		}
		
		JDKBPCommon.throwScExceptionIfHasError("機器出荷情報更新処理リターンコード不正", param);
	}
}
