/*******************************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
********************************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JEKU0011C020TPMA
*	ソースファイル名：JEKU0011C020TPMA.java
*	作成者			：富士通
*	日付			：2011年12月22日
*＜機能概要＞
*	工事案件名寄せ変更の独自処理を呼び出す部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	ｖ1.00.00
*	ｖ10.00.00	2014/07/31	FJ)川島		【ANK-1918-00-00】ＵＳ管理Ｓ向けｅｏ顧客ＳのＩ／Ｆ改修
********************************************************************************/
package eo.ejb.cbs.mainproc;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.fujitsu.futurity.model.base.CAANException;
import com.fujitsu.futurity.model.base.CAANFinderException;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.ejb.common.StatusCodes;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;
import com.fujitsu.futurity.model.ejb.common.fw.TemplateMainHandler;

import eo.common.constant.JKUStrConst;
import eo.common.constant.JPCModelConstant;
import eo.ejb.cbm.entity.KU0011ETMsg;
import eo.ejb.cbm.entity.KU0081ETMsg;
import eo.ejb.cbm.entity.KU0101ETMsg;
import eo.ejb.cbs.cbsmsg.EKU0011C020CBSMsg;
import eo.ejb.common.JKUModelCommon;
import eo.ejb.common.JPCModelCommon;
import eo.ejb.common.db.JKUejbKU0011SecProc;
import eo.ejb.common.db.JKUejbKU0081SecProc;
import eo.ejb.common.db.JKUejbKU0101SecProc;

/**
 * <p>
 * 工事案件名寄せ変更の独自処理を呼び出す部品です。
 * </p>
 * @author 富士通
 */
public class JEKU0011C020TPMA implements TemplateMainHandler
{
	
	/**
	 * コンストラクタです
	 */
	public JEKU0011C020TPMA()
	{
		super();
	}
	
	/**
	 * 主処理
	 * @param inCBSMsg	CBSメッセージ
	 * @param inContext	ディスパッチコンテキスト
	 * @throws CAANException
	 */
	public void invoke(CAANMsg inCBSMsg, AgentDispatchContext inContext) throws CAANException
	{
		
		
		// 変更対象SYSIDリスト(寄る側)
		HashMap<String, List<CAANMsg[]>> sysidInfo = getBfData(inCBSMsg, inContext);
		
		
		// 対象が空の場合エラーが発生している
		if(null == sysidInfo)
		{
			return;
		}
		
		
		// 機能コード１以外の場合はチェックのみのため処理を終了する
		if (!JPCModelConstant.FUNC_CD_1.equals(inCBSMsg.getString(EKU0011C020CBSMsg.FUNC_CODE)))
		{
			return;
		}
		
		
		// SYSID(変更後のSYSID)
		String sysid = inCBSMsg.getString(EKU0011C020CBSMsg.SYSID);
		
		// 更新処理実行
		updateAll(inCBSMsg, sysid, sysidInfo);
		
		
		// ---アウトプット項目の設定
		
		// 更新年月日時分秒
		inCBSMsg.set(EKU0011C020CBSMsg.UPD_DTM, inCBSMsg.getString(EKU0011C020CBSMsg.OPERATEDATETIME));
		// 更新オペレータアカウント
		inCBSMsg.set(EKU0011C020CBSMsg.UPD_OPEACNT, inCBSMsg.getString(EKU0011C020CBSMsg.OPERATORID));
		
		
	}
	
	
	
	/**
	 * 変更対象SYSIDデータ取得処理
	 * @param inCBSMsg
	 * @param inContext
	 * @return resultMap 変更対象格納map
	 * @throws CAANException
	 */
	private HashMap<String, List<CAANMsg[]>> getBfData(CAANMsg inCBSMsg, AgentDispatchContext inContext) throws CAANException
	{
		// 返却用マップ
		HashMap<String, List<CAANMsg[]>> resultMap = new HashMap<String, List<CAANMsg[]>>();
		// 変更対象SYSID
		String sysid_bf = inCBSMsg.getString(EKU0011C020CBSMsg.SYSID_BF);
		// チェック対象工事案件番号
		List<String> checkKojiakNo = new ArrayList<String>();
		// 変更対象サービス契約＿工事案件情報取得
		CAANMsg[] svcInfoBf = getBfSvcKojiInfo(sysid_bf);
		// 変更対象工事案件番号
		List<String> list = new ArrayList<String>();
		
		if(null == svcInfoBf || svcInfoBf.length == 0)
		{
			// 対象が存在しない場合整合性エラー
			
			// SYSID整合性エラーを登録
			inCBSMsg.set(EKU0011C020CBSMsg.SYSID_BF_ERR, "EA");
			// ステータス
			inCBSMsg.set(EKU0011C020CBSMsg.STATUS, StatusCodes.RELATION_ERR);
			return null;
		}
		
		// 工事案件番号存在確認・リスト取得
		for (CAANMsg msg : svcInfoBf)
		{
			
			
			// 工事案件のETメッセージを作成
			CAANMsg msgKU0011 = new CAANMsg(KU0011ETMsg.class.getName());
			
			// 更新対象のレコード取得
			msgKU0011 = getKU0011FindByPrimaryKeyE(msg.getString(KU0081ETMsg.KOJIAK_NO));
			
			// 存在チェック
			if(null == msgKU0011)
			{
				// 対象が存在しない場合整合性エラー
				
				// SYSID整合性エラーを登録
				inCBSMsg.set(EKU0011C020CBSMsg.SYSID_BF_ERR, "EB");
				// ステータス
				inCBSMsg.set(EKU0011C020CBSMsg.STATUS, StatusCodes.RELATION_ERR);
				return null;
			}
			else
			{
				// 取得した工事案件番号について重複を取り除く
				if (!checkKojiakNo.contains(msg.getString(KU0081ETMsg.KOJIAK_NO)))
				{
					// リストになければ追加する
					checkKojiakNo.add(msg.getString(KU0081ETMsg.KOJIAK_NO));
				}
				
			}
			
			
		}
		
		// 工事案件副次処理部品
		JKUejbKU0011SecProc ku0011SecProc = new JKUejbKU0011SecProc();
		// 
		CAANMsg ku0011Msg = null;
		// 仕掛工事案件番号
		List<String> shikakariKojiakNo = new ArrayList<String>();
		
		for(String cKojiakNo: checkKojiakNo)
		{
			ku0011Msg = new CAANMsg(KU0011ETMsg.class.getName());
			
			// 工事案件番号
			ku0011Msg.set(KU0011ETMsg.KOJIAK_NO, cKojiakNo);
			
			// PK検索を実行
			ku0011Msg = ku0011SecProc.findByPrimaryKey(ku0011Msg, true);
			
			// 仕掛中、最新、チェック
			if (JKUModelCommon.isSkkrOrSaishinKojiak(ku0011Msg))
			{
				// 工事案件番号格納
				shikakariKojiakNo.add(ku0011Msg.getString(KU0011ETMsg.KOJIAK_NO));
			}
			
		}
		
		if(shikakariKojiakNo != null)
		{
			for(String kojiakNo: shikakariKojiakNo)
			{
				list.add(kojiakNo);
			}
		}
		
		if(list.size() == 0)
		{
			// SYSID整合性エラーを登録
			inCBSMsg.set(EKU0011C020CBSMsg.SYSID_BF_ERR, "EA");
			// ステータス
			inCBSMsg.set(EKU0011C020CBSMsg.STATUS, StatusCodes.RELATION_ERR);
			return null;
		}
		
		// 排他チェック
		
		
		List<CAANMsg> ku0011MsgList = getChangeDataMapKU0011(list);
		
		if(isLockedKojiak(ku0011MsgList, inContext))
		{
			// 工事案件排他ロックエラーを登録
			inCBSMsg.set(EKU0011C020CBSMsg.SYSID_BF_ERR, "EB");
			// ステータス
			inCBSMsg.set(EKU0011C020CBSMsg.STATUS, StatusCodes.RELATION_ERR);
			return null;
		}
		
		
		// 工事案件情報取得
		List<CAANMsg[]> kojiInfo = getKojiakInfo(list);
		
		
		if(null == kojiInfo || kojiInfo.size() == 0)
		{
			// 対象が存在しない場合整合性エラー
			
			// SYSID整合性エラーを登録
			inCBSMsg.set(EKU0011C020CBSMsg.SYSID_BF_ERR, "EB");
			// ステータス
			inCBSMsg.set(EKU0011C020CBSMsg.STATUS, StatusCodes.RELATION_ERR);
			return null;
		}
		
		
		// サービス契約＿工事案件情報取得
		List<CAANMsg[]> svcInfo = getSvcKojiInfo(list);
		
		
		// 先行設計情報取得
		List<CAANMsg[]> senkouInfo = getSenkoInfo(list);
		
		// 先行設計のみ対象が無くともエラーとしない
		
		// 結果をマップに設定する
		
		// 工事案件
		resultMap.put(JKUStrConst.SCHEMA_KU0011, kojiInfo);
		// サービス契約＿工事案件
		resultMap.put(JKUStrConst.SCHEMA_KU0081, svcInfo);
		// 先行設計
		resultMap.put(JKUStrConst.SCHEMA_KU0101, senkouInfo);
		
		
		return resultMap;
	}
	
	
	/**
	 * サービス契約＿工事案件変更対象取得
	 * @param sysid
	 * @return arrMsgKU0081 サービス契約＿工事案件情報
	 * @throws CAANException
	 */
	private CAANMsg[] getBfSvcKojiInfo(String sysid) throws CAANException
	{
		
		// サービス契約 ロジカルエンティティクラス
		JKUejbKU0081SecProc ku0081SecProc = new JKUejbKU0081SecProc();
		
		// サービス契約のETメッセージを作成
		CAANMsg msgKU0081 = new CAANMsg(KU0081ETMsg.class.getName());
		
		// SYSID
		msgKU0081.set(KU0081ETMsg.SYSID, sysid);
		// 無効フラグ
		msgKU0081.set(KU0081ETMsg.MK_FLG, JKUStrConst.MK_FLG_YUKO);
		
		CAANMsg[] arrMsgKU0081 = ku0081SecProc.findByCondition(msgKU0081);
		
		return arrMsgKU0081;
	}
	
	
	/**
	 * 工事案件情報取得
	 * @param list
	 * @return resultList 工事案件検索結果
	 * @throws CAANException
	 */
	private List<CAANMsg[]> getKojiakInfo(List<String> list) throws CAANException
	{
		
		// 工事案件 ロジカルエンティティクラス
		JKUejbKU0011SecProc ku0011SecProc = new JKUejbKU0011SecProc();
		
		// 工事案件のETメッセージを作成
		CAANMsg msgKU0011 = new CAANMsg(KU0011ETMsg.class.getName());
		
		// 結果リスト
		List<CAANMsg[]> resultList = new ArrayList<CAANMsg[]>();
		
		for(String kojiakNo: list)
		{
			// 工事案件番号
			msgKU0011.set(KU0011ETMsg.KOJIAK_NO, kojiakNo);
			// 無効フラグ
			msgKU0011.set(KU0011ETMsg.MK_FLG, JKUStrConst.MK_FLG_YUKO);
			
			// 更新対象のレコード取得
			CAANMsg[] arrMsgKU0011 = ku0011SecProc.findByCondition(msgKU0011);
			
			resultList.add(arrMsgKU0011);
		}
		
		return resultList;
	}
	
	
	/**
	 * サービス契約＿工事案件情報取得
	 * @param list
	 * @return resultList サービス契約＿工事案件検索結果
	 * @throws CAANException
	 */
	private List<CAANMsg[]> getSvcKojiInfo(List<String> list) throws CAANException
	{
		
		// サービス契約 ロジカルエンティティクラス
		JKUejbKU0081SecProc ku0081SecProc = new JKUejbKU0081SecProc();
		
		// サービス契約のETメッセージを作成
		CAANMsg msgKU0081 = new CAANMsg(KU0081ETMsg.class.getName());
		
		// 結果リスト
		List<CAANMsg[]> resultList = new ArrayList<CAANMsg[]>();
		
		
		for(String kojiakNo: list)
		{
			
			// 工事案件番号
			msgKU0081.set(KU0081ETMsg.KOJIAK_NO, kojiakNo);
			// 無効フラグ
			msgKU0081.set(KU0081ETMsg.MK_FLG, JKUStrConst.MK_FLG_YUKO);
			
			CAANMsg[] arrMsgKU0081 = ku0081SecProc.findByCondition(msgKU0081);
			
			
			resultList.add(arrMsgKU0081);
			
		}
		
		
		
		
		return resultList;
	}
	
	
	/**
	 * 先行設計情報取得
	 * @param list
	 * @return resultList 先行設計検索結果
	 * @throws CAANException
	 */
	private List<CAANMsg[]> getSenkoInfo(List<String> list) throws CAANException
	{
		
		// 先行設計 ロジカルエンティティクラス
		JKUejbKU0101SecProc ku0101SecProc = new JKUejbKU0101SecProc();
		
		// 先行設計のETメッセージを作成
		CAANMsg msgKU0101 = new CAANMsg(KU0101ETMsg.class.getName());
		
		// 結果リスト
		List<CAANMsg[]> resultList = new ArrayList<CAANMsg[]>();
		
		
		for(String kojiakNo: list)
		{
			
			// 工事案件番号
			msgKU0101.set(KU0101ETMsg.KOJIAK_NO, kojiakNo);
			// 先行設計ステータス
			msgKU0101.set(KU0101ETMsg.SNKSKI_STAT, JKUStrConst.SNKSKI_STAT_UK_ZM);
			// 無効フラグ
			msgKU0101.set(KU0101ETMsg.MK_FLG, JKUStrConst.MK_FLG_YUKO);
			
			// 更新対象のレコード取得
			CAANMsg[] arrMsgKU0101 = ku0101SecProc.findByCondition(msgKU0101);
			
			resultList.add(arrMsgKU0101);
			
		}
		
		
		
		return resultList;
	}
	
	
	
	/**
	 * 名寄せ処理  各スキーマの更新を行う。
	 * @param inCBSMsg
	 * @param sysid
	 * @param sysidInfo
	 * @throws CAANException
	 */
	private void updateAll(CAANMsg inCBSMsg, String sysid, HashMap<String, List<CAANMsg[]>> sysidInfo) throws CAANException
	{
		
		// 工事案件更新
		updateKojiak(inCBSMsg, sysid, sysidInfo.get(JKUStrConst.SCHEMA_KU0011));
		
		// サービス契約＿工事案件更新
		updateSvkeiKoji(inCBSMsg, sysid, sysidInfo.get(JKUStrConst.SCHEMA_KU0081));
		
		// 先行設計更新
		updateSenkou(inCBSMsg, sysid, sysidInfo.get(JKUStrConst.SCHEMA_KU0101));
		
	}
	
	
	/**
	 * 工事案件の更新を行う。
	 * @param inCBSMsg
	 * @param sysid
	 * @param changeDataMsgList
	 * @throws CAANException
	 */
	private void updateKojiak(CAANMsg inCBSMsg, String sysid, List<CAANMsg[]> changeDataMsgList) throws CAANException
	{
		
		// 工事案件を更新する
		JKUejbKU0011SecProc ku0011SecProc = new JKUejbKU0011SecProc();
		String ykKojiakStat = null;
		
		try
		{
			
			
			for(CAANMsg[] changeDataRec : changeDataMsgList)
			{
				
				for(CAANMsg changeDataMsg : changeDataRec)
				{
					
					// SYSID更新
					changeDataMsg.set(KU0011ETMsg.SYSID, sysid);
					
					// 有効な工事案件ステータスを取得する
					ykKojiakStat = JKUModelCommon.getYkKojiakStat(changeDataMsg.getString(KU0011ETMsg.KOJIAK_STAT),
							changeDataMsg.getString(KU0011ETMsg.MANS_KOJIAK_STAT_CD));
					
					// OPMS変更連携要否('要'　有効な工事案件ステータスが｢受付済み｣以外の場合のみ)
					if(!JKUStrConst.CD00474_UK_ZM.equals(ykKojiakStat))
					{
						changeDataMsg.set(KU0011ETMsg.OPMS_CHGE_RNKI_YH, JKUStrConst.KH_PSG);
					}
					
					// Genesis変更連携要否('要')
					changeDataMsg.set(KU0011ETMsg.GENESIS_CHGE_RNKI_YH, JKUModelCommon.getChgRnkiYh(changeDataMsg, JKUStrConst.RNKI_SYSTEM_GENESIS));
					// 更新年月日時分秒
					changeDataMsg.set(KU0011ETMsg.UPD_DTM, inCBSMsg.getString(EKU0011C020CBSMsg.OPERATEDATETIME));
					// 更新オペレータアカウント
					changeDataMsg.set(KU0011ETMsg.UPD_OPEACNT, inCBSMsg.getString(EKU0011C020CBSMsg.OPERATORID));
					
					// 更新実行
					ku0011SecProc.update(changeDataMsg);
					
				}
				
				
			}
			
		}
		catch (CAANFinderException cfe)
		{
			inCBSMsg.set(EKU0011C020CBSMsg.STATUS, StatusCodes.UPDATE_DB_ERR);
			throw cfe;
		}
		
		
	}
	
	
	/**
	 * サービス契約＿工事案件の更新を行う。
	 * @param inCBSMsg
	 * @param sysid
	 * @param changeDataMsgList
	 * @throws CAANException
	 */
	private void updateSvkeiKoji(CAANMsg inCBSMsg, String sysid, List<CAANMsg[]> changeDataMsgList) throws CAANException
	{
		
		// サービス契約_工事案件を更新する
		JKUejbKU0081SecProc ku0081SecProc = new JKUejbKU0081SecProc();
		
		
		try
		{
			
			for(CAANMsg[] changeDataRec : changeDataMsgList)
			{
				
				for(CAANMsg changeDataMsg : changeDataRec)
				{
					
					//  SYSID更新
					changeDataMsg.set(KU0081ETMsg.SYSID, sysid);
					// 更新年月日時分秒
					changeDataMsg.set(KU0081ETMsg.UPD_DTM, inCBSMsg.getString(EKU0011C020CBSMsg.OPERATEDATETIME));
					// 更新オペレータアカウント
					changeDataMsg.set(KU0081ETMsg.UPD_OPEACNT, inCBSMsg.getString(EKU0011C020CBSMsg.OPERATORID));
					
					// 更新実行
					ku0081SecProc.update(changeDataMsg);
					
				}
				
				
			}
			
			
		}
		catch (CAANFinderException cfe)
		{
			inCBSMsg.set(EKU0011C020CBSMsg.STATUS, StatusCodes.UPDATE_DB_ERR);
			throw cfe;
		}
		
		
		
	}
	
	
	/**
	 * 先行設計の更新を行う。
	 * @param inCBSMsg
	 * @param sysid
	 * @param changeDataMsgList
	 * @throws CAANException
	 */
	private void updateSenkou(CAANMsg inCBSMsg, String sysid, List<CAANMsg[]> changeDataMsgList) throws CAANException
	{
		
		// 先行設計を更新する
		JKUejbKU0101SecProc ku0101SecProc = new JKUejbKU0101SecProc();
		
		
		if(null == changeDataMsgList || changeDataMsgList.size() == 0)
		{
			// 先行設計が空の場合
			return;
		}
		
		try
		{
			
			for(CAANMsg[] changeDataRec : changeDataMsgList)
			{
				
				for(CAANMsg changeDataMsg : changeDataRec)
				{
					
					//  SYSID更新
					changeDataMsg.set(KU0101ETMsg.SYSID, sysid);
					// 更新年月日時分秒
					changeDataMsg.set(KU0101ETMsg.UPD_DTM, inCBSMsg.getString(EKU0011C020CBSMsg.OPERATEDATETIME));
					// 更新オペレータアカウント
					changeDataMsg.set(KU0101ETMsg.UPD_OPEACNT, inCBSMsg.getString(EKU0011C020CBSMsg.OPERATORID));
					
					// 更新実行
					ku0101SecProc.update(changeDataMsg);
					
				}
				
			}
			
		}
		catch (CAANFinderException cfe)
		{
			inCBSMsg.set(EKU0011C020CBSMsg.STATUS, StatusCodes.UPDATE_DB_ERR);
			throw cfe;
		}
		
		
	}
	
	/**
	 * 工事案件ＰＫ検索
	 * @param kojiakNo 工事案件番号
	 * @return 工事案件レコード
	 * @throws CAANException
	 */
	private CAANMsg getKU0011FindByPrimaryKeyE(String kojiakNo) throws CAANException
	{
		// 工事案件 副次処理
		JKUejbKU0011SecProc sp0011 = new JKUejbKU0011SecProc();
		
		// 工事案件のETメッセージを作成
		CAANMsg msgKU0011 = new CAANMsg(KU0011ETMsg.class.getName());
		
		// 工事案件番号
		msgKU0011.set(KU0011ETMsg.KOJIAK_NO, kojiakNo);
		
		// 無効フラグ
		msgKU0011.set(KU0011ETMsg.MK_FLG, JKUStrConst.MK_FLG_YUKO);
		
		// 対象のレコード取得
		return  sp0011.findByPrimaryKey(msgKU0011, true);
	}
	
	
	/**
	 * 変更対象取得＿工事案件
	 * @param list 工事案件番号
	 * @return List<CAANMsg>
	 * @throws CAANException 
	 */
	private List<CAANMsg> getChangeDataMapKU0011(List<String> list) throws CAANException
	{
		List<CAANMsg> returnList = new ArrayList<CAANMsg>();
		
		// 引数の工事案件番号の件数分、工事案件を取得する。
		for (String kojiakNo : list)
		{
			// 工事案件ＰＫ検索
			CAANMsg msgKU0011 = getKU0011FindByPrimaryKeyE(kojiakNo);
			
			if(msgKU0011 != null)
			{
				returnList.add(msgKU0011);
			}
		}
		
		return returnList;
		
	}
	
	
	
	/**
	 * ロックされた工事案件かどうかを判断
	 * @param caanMsgList
	 * @param inContext
	 * @return boolean
	 */
	private boolean isLockedKojiak(List<CAANMsg> caanMsgList, AgentDispatchContext inContext)
	{
		CAANMsg[] ku0011MsgArray = (CAANMsg[])caanMsgList.toArray(new CAANMsg[caanMsgList.size()]);
		CAANMsg ku0011Msg = null;
		for (int i = 0; i < ku0011MsgArray.length; ++i)
		{
			ku0011Msg = ku0011MsgArray[i];
			
			if (!JPCModelCommon.succeededExclusiveLock(ku0011Msg, inContext, JKUStrConst.SCHEMA_KU0011))
			{
				return true;
			}
		}
		
		return false;
	}
	
	
	
}