/*********************************************************************
*  All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JKUejbDaihyouKaNoAcqUtil
*	ソースファイル名	：JKUejbDaihyouKaNoAcqUtil.java
*	作成者				：富士通　
*	作成日				：2011年08月31日
*＜機能概要＞
*	同時代表工事案件番号取得部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/08/31   FJ)高橋	新規作成
*	v5.00.00	2013/09/09   FJ)高橋	OM-2013-0001898
*	v10.00.00	2014/07/15   FJ)阪口	【ANK-1918-00-00】US管理対応
*********************************************************************/

package eo.ejb.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;

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.fw.AgentDispatchContext;

import eo.common.constant.JKUStrConst;
import eo.common.util.JKUCommonUtil;
import eo.ejb.cbm.entity.KU0011ETMsg;
import eo.ejb.cbm.entity.KU0081ETMsg;
import eo.ejb.cbm.entity.KU0101ETMsg;
import eo.ejb.common.db.JKUejbKU0011SecProc;
import eo.ejb.common.db.JKUejbKU0081SecProc;
import eo.ejb.common.db.JKUejbKU0101SecProc;
import eo.ejb.common.rule.JKUejbRule0050001;
import eo.ejb.common.rule.JKUejbRule0050002;

/**
 *  <dd>クラス名：同時代表工事案件番号取得
 *  <dd>クラス説明：同時代表工事案件番号取得部品です。
 *  <dd>備考：
 * @version  1.00 2011/08/31
 * @author 富士通
 *
 */
public class JKUejbDaihyouKojiakNoAcqUtil
{
	
	/**
	 * 同時代表工事案件番号取得<br>
	 * 取得に必要な項目は、工事案件番号に紐づく工事案件データから取得します。
	 * @param kojiakNo            工事案件番号
	 * @param svcKeiKaisenUcwkCd  サービス契約回線内訳番号
	 * @return 同時代表工事案件番号、見つからなかった場合null
	 * @throws CAANException
	 */
	public static String getSimRepKojiakNo(String kojiakNo, String svcKeiKaisenUcwkCd) throws CAANException
	{
		// ルール0050002 
		JKUejbRule0050002 rule0050002 = new JKUejbRule0050002();
		
		// 引数のチェックを実行する
		if (null == kojiakNo || null == svcKeiKaisenUcwkCd)
		{
			return null;
		}
		
		// 工事案件番号に紐づく工事案件データを取得する
		CAANMsg ku0011Msg = getTrgKojiak(kojiakNo);
		if (null == ku0011Msg)
		{
			return null;
		}
		
		// 工事案件種別グループコードを取得する
		String kojiakSbtGrp = rule0050002.chkSokanRule0050002(ku0011Msg.getString(KU0011ETMsg.KOJIAK_SBT_CD));
		if (null == kojiakSbtGrp)
		{
			return null;
		}
		
		// 工事契約サービスコードを取得する
		String kojiKeiSvcCd = getKojiKeiSvcCd(kojiakNo, ku0011Msg.getString(KU0011ETMsg.PRC_GRP_CD), ku0011Msg.getString(KU0011ETMsg.MANSION_BUKKEN_CD));
		if (null == kojiKeiSvcCd)
		{
			return null;
		}
		
		// 比較対象の候補を取得する
		TreeMap<String, CAANMsg> kohoMap = getKohoMap(svcKeiKaisenUcwkCd, ku0011Msg.getString(KU0011ETMsg.PRC_GRP_CD));
		if (null == kohoMap)
		{
			return null;
		}
		
		// 条件に合う工事案件番号を返して終了する
		return getDojiKojiAkNo(kohoMap, kojiKeiSvcCd, kojiakSbtGrp);
	}
	
	/**
	 * 同時代表工事案件番号取得<br>
	 * 工事案件番号による検索を行わなわず、同時代表工事案件番号を取得します。
	 * @param kojiakSbtCd	工事案件種別コード
	 * @param prcGrpCd		料金グループコード
	 * @param mansBukkenCd	マンション物件コード
	 * @param mansTsnStbCd	マンション通信設備コード
	 * @param ipHaraidashiCd	IP払出コード
	 * @param svcKeiKaisenUcwkCd	サービス契約回線内訳コード
	 * @return	同時代表工事案件番号、見つからなかった場合null
	 * @throws CAANException
	 */
	public static String getSimRepKojiakNoNotFindByPk(String kojiakSbtCd, String prcGrpCd, String mansBukkenCd,
			String mansTsnStbCd, String ipHaraidashiCd, String svcKeiKaisenUcwkCd) throws CAANException
	{
		// ルール0050002 
		JKUejbRule0050002 rule0050002 = new JKUejbRule0050002();
		
		// 引数のチェックを実行する
		if (null == kojiakSbtCd || "".equals(kojiakSbtCd))
		{
			return null;
		}
		if (null == prcGrpCd)
		{
			return null;
		}
		if (null == svcKeiKaisenUcwkCd)
		{
			return null;
		}
		
		// 工事案件種別グループコードを取得する
		String kojiakSbtGrp = rule0050002.chkSokanRule0050002(kojiakSbtCd);
		if (null == kojiakSbtGrp)
		{
			return null;
		}
		
		// 工事契約サービスコードを取得する
		String kojiKeiSvcCd = getKojiKeiSvcCdNotFindPk(prcGrpCd, mansBukkenCd, mansTsnStbCd, ipHaraidashiCd);
		if (null == kojiKeiSvcCd)
		{
			return null;
		}
		
		// 比較対象の候補を取得する
		TreeMap<String, CAANMsg> kohoMap = getKohoMap(svcKeiKaisenUcwkCd, prcGrpCd);
		if (null == kohoMap)
		{
			return null;
		}
		
		// 条件に合う工事案件番号を返して終了する
		return getDojiKojiAkNo(kohoMap, kojiKeiSvcCd, kojiakSbtGrp);
	}
	
	/**
	 * 工事案件レコード１件取得
	 * @param kojiakNo
	 * @return 工事案件データ
	 * @throws CAANException
	 */
	private static CAANMsg getTrgKojiak(String kojiakNo) throws CAANException
	{
		JKUejbKU0011SecProc ku0011SecProc = new JKUejbKU0011SecProc();
		
		// 工事案件番号をキーに工事案件を取得する
		CAANMsg ku0011Msg = new CAANMsg(KU0011ETMsg.class.getName());
		
		// 工事案件番号
		ku0011Msg.set(KU0011ETMsg.KOJIAK_NO, kojiakNo);
		
		return ku0011SecProc.findByPrimaryKey(ku0011Msg, true);
	}
	
	/**
	 * 同時工事判定の候補となる工事案件データを取得する
	 * @param svcKeiKaisenUcwkNo	サービス契約内訳番号
	 * @param prcGrpCd	料金グループコード
	 * @return	候補となるTreeMap
	 * @throws CAANException
	 */
	private static TreeMap<String, CAANMsg> getKohoMap(String svcKeiKaisenUcwkNo, String prcGrpCd) throws CAANException
	{
		// 検索を実行する
//		CAANMsg[] ku0011MsgArray = JKUModelCommon.getKU0011DoitsuKoji(svcKeiKaisenUcwkNo, prcGrpCd);
		
		CAANMsg ku0081Msg = new CAANMsg(KU0081ETMsg.class.getName());
		
		// サービス契約回線内訳番号
		ku0081Msg.set(KU0081ETMsg.SVC_KEI_KAISEN_UCWK_NO, svcKeiKaisenUcwkNo);
		// 無効フラグ
		ku0081Msg.set(KU0081ETMsg.MK_FLG, JKUStrConst.MK_FLG_YUKO);
		
		CAANMsg[] ku0081MsgArray = new JKUejbKU0081SecProc().findByCondition(ku0081Msg);
		if (null == ku0081MsgArray || ku0081MsgArray.length == 0)
		{
			return null;
		}
		// 工事案件番号のリストを作成する
		List<String> kojiakNoList = new ArrayList<String>();
		for (int i = 0; i < ku0081MsgArray.length; ++i)
		{
			String kojiakNo = ku0081MsgArray[i].getString(KU0081ETMsg.KOJIAK_NO);
			
			// 重複せず、nullでもない工事案件番号である場合
			if (null != kojiakNo 
					&&  -1 == kojiakNoList.indexOf(kojiakNo))
			{
				// リストに工事案件番号を追加する
				kojiakNoList.add(kojiakNo);
			}
		}
		
		List<CAANMsg> retList = new ArrayList<CAANMsg>();
		JKUejbKU0011SecProc ku0011SecProc = new JKUejbKU0011SecProc();
		
		for (int i = 0; i < kojiakNoList.size(); ++i)
		{
			// 工事案件データを取得する
			CAANMsg ku0011Msg = new CAANMsg(KU0011ETMsg.class.getName());
			// 工事案件番号
			ku0011Msg.set(KU0011ETMsg.KOJIAK_NO, kojiakNoList.get(i));
			
			ku0011Msg = ku0011SecProc.findByPrimaryKey(ku0011Msg, true);
			
			if (null != ku0011Msg
					&& JKUStrConst.CD00474_UK_ZM.equals(
							JKUModelCommon.getYkKojiakStat(ku0011Msg.getString(KU0011ETMsg.KOJIAK_STAT), ku0011Msg.getString(KU0011ETMsg.MANS_KOJIAK_STAT_CD))))
			{
				retList.add(ku0011Msg);
			}
		}
		
		if (null == retList || retList.size() == 0)
		{
			return null;
		}
		
		// 検索結果をTreeMapに変換する
		return kojiRcOldSort(retList.toArray(new CAANMsg[retList.size()]));
	}
	
	/**
	 * 取得した同一サービスの工事レコードを申込受付年月日時分秒の古い日付順でソートする
	 * @param douituSvc
	 * @return 申込受付年月日時分秒をキーとしたツリーマップ
	 */
	private static TreeMap<String, CAANMsg> kojiRcOldSort(CAANMsg[] douituSvc)
	{
		// ソートした同一サービス契約内訳番号工事案件レコード
		TreeMap<String, CAANMsg> sortDouituSvc = new TreeMap<String, CAANMsg>();
		
		if (null == douituSvc)
		{
			return null;
		}
		
		// 繰り返し
		for (CAANMsg doujituSvcCd: douituSvc)
		{
			// 工事受付契機異動年月日時分秒をキーにして昇順ソートに用いる
			sortDouituSvc.put(doujituSvcCd.getString(KU0011ETMsg.KOJI_UK_OPTNTY_IDO_DTM), doujituSvcCd);
		}
		
		return sortDouituSvc;
	}
	
	/**
	 * 候補の中から、最初に同時工事と判定された工事案件番号を取得する
	 * @param kohoMap	候補となる工事案件データマップ
	 * @param kojiKeiSvcCd	工事契約サービスコード
	 * @param kojiakSbtGrp	工事案件種別グループ
	 * @return 同時代表工事案件番号、見つからなかった場合null
	 */
	private static String getDojiKojiAkNo(TreeMap<String, CAANMsg> kohoMap, String kojiKeiSvcCd, String kojiakSbtGrp)
	{
		
		// ルール0050001
		JKUejbRule0050001 rule0050001 = new JKUejbRule0050001();
		// ルール0050002 
		JKUejbRule0050002 rule0050002 = new JKUejbRule0050002();
		
		// ソートしたキーを取得
		Set<String> keySet = kohoMap.keySet();
		// キーからIterator作成
		Iterator<String> keyIte = keySet.iterator();
		
		// レコード件数分繰り返し
		while(keyIte.hasNext())
		{
			String mapKey = keyIte.next();
			
			// 受付済みのみ
			if (JKUStrConst.CD00474_UK_ZM.equals(
					JKUModelCommon.getYkKojiakStat(
							kohoMap.get(mapKey).getString(KU0011ETMsg.KOJIAK_STAT), kohoMap.get(mapKey).getString(KU0011ETMsg.MANS_KOJIAK_STAT_CD))))
			{
				// 工事案件種別グループコードを取得する
				String kojiakSbtGrpKoho = rule0050002.chkSokanRule0050002(kohoMap.get(mapKey).getString(KU0011ETMsg.KOJIAK_SBT_CD));
				if (null == kojiakSbtGrpKoho)
				{
					continue;
				}
				
				// 工事契約サービスコードを取得する
				String kojiKeiSvcCdKoho = getKojiKeiSvcCd(kohoMap.get(mapKey).getString(KU0011ETMsg.KOJIAK_NO),
							kohoMap.get(mapKey).getString(KU0011ETMsg.PRC_GRP_CD), kohoMap.get(mapKey).getString(KU0011ETMsg.MANSION_BUKKEN_CD));
				if (null == kojiKeiSvcCdKoho)
				{
					continue;
				}
				
				// 同時工事判定実行
				if(true == rule0050001.chkSokanRule0050001(kojiakSbtGrp, kojiakSbtGrpKoho, kojiKeiSvcCd, kojiKeiSvcCdKoho))
				{
					return kohoMap.get(mapKey).getString(KU0011ETMsg.KOJIAK_NO);
				}
				
			}
			
		}
		return null;
	}
	
	/**
	 * 工事契約サービスコードを取得する
	 * @param kojiakNo	工事案件番号
	 * @param prcGrpCd	料金グループコード
	 * @param mansBukkenCd	マンション物件コード
	 * @return	工事契約サービスコード
	 */
	private static String getKojiKeiSvcCd(String kojiakNo, String prcGrpCd, String mansBukkenCd)
	{
		HashMap<String, String> kokyakuMapFromKoji = new HashMap<String, String>();
		
		// 料金グループコードを設定
		kokyakuMapFromKoji.put(JKUStrConst.RNKI_SYS_PRC_GRP_CD, prcGrpCd);
		// マンション物件コードを設定
		kokyakuMapFromKoji.put(JKUStrConst.RNKI_SYS_MANS_BUKKEN_CD, mansBukkenCd);
		// 連携システムを設定
		kokyakuMapFromKoji.put(JKUStrConst.RNKI_SYS_SYSTEM, JKUStrConst.RNKI_SYSTEM_OPMS);
		
		// 料金グループコードからサービス契約コード取得
		return JKUModelCommon.getKjKeiSvcCd(kojiakNo, kokyakuMapFromKoji);
	}
	
	/**
	 * 工事契約サービスコードを取得する
	 * @param prcGrpCd	料金グループコード
	 * @param mansBukkenCd	マンション物件コード
	 * @param mansTsnStbCd	マンション通信設備コード
	 * @param ipHaraidashiCd	IP払出コード
	 * @return	工事契約サービスコード
	 */
	private static String getKojiKeiSvcCdNotFindPk(String prcGrpCd, String mansBukkenCd, String mansTsnStbCd, String ipHaraidashiCd)
	{
		HashMap<String, String> kokyakuMapFromkoji = new HashMap<String, String>();
		
		// 料金グループコード
		kokyakuMapFromkoji.put(JKUStrConst.RNKI_SYS_PRC_GRP_CD, prcGrpCd);
		// マンション物件コード
		kokyakuMapFromkoji.put(JKUStrConst.RNKI_SYS_MANS_BUKKEN_CD, mansBukkenCd);
		// マンション通信設備コード
		kokyakuMapFromkoji.put(JKUStrConst.RNKI_SYS_MANS_TSN_STB_CD, mansTsnStbCd);
		// IP払出コード
		kokyakuMapFromkoji.put(JKUStrConst.RNKI_SYS_IP_HARAIDASHI, ipHaraidashiCd);
		// 連携システム
		kokyakuMapFromkoji.put(JKUStrConst.RNKI_SYS_SYSTEM, JKUStrConst.RNKI_SYSTEM_OPMS);
		
		return JKUCommonUtil.getKjKeiSvcCd(kokyakuMapFromkoji);
	}
	
	/**
	 * 同時代表工事更新工事案件
	 * @param kojiakNo	工事案件番号
	 * @param dojiDaihyoKojiakNo	同時代表工事案件番号
	 * @param operateDatetime 更新年月日時分秒
	 * @param operatorId 更新オペレータアカウント
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param ukFlg 受付フラグ true:受付系(同時代表工事案件番号を引数の工事案件番号で更新) false:解約系(同時代表工事案件番号を空白で更新)
	 * @return boolean
	 * @throws CAANException
	 */
	public static boolean updateDojiDaihyoKojiak(String kojiakNo, String dojiDaihyoKojiakNo, 
			String operateDatetime, String operatorId, AgentDispatchContext inContext, boolean ukFlg) throws CAANException
	{
		// 同時代表工事案件番号がNULL
		if(null == dojiDaihyoKojiakNo)
		{
			// 更新処理なし
			return true;
		}
		
		// 工事案件 副次処理
		JKUejbKU0011SecProc sp0011 = new JKUejbKU0011SecProc();
		// 工事案件のETメッセージを作成
		CAANMsg msgKU0011 = new CAANMsg(KU0011ETMsg.class.getName());
		// 工事案件番号
		msgKU0011.set(KU0011ETMsg.KOJIAK_NO, dojiDaihyoKojiakNo);
		// 無効フラグ
		msgKU0011.set(KU0011ETMsg.MK_FLG, JKUStrConst.MK_FLG_YUKO);
		// 対象のレコード取得
		msgKU0011 = sp0011.findByPrimaryKey(msgKU0011, true);
		// 排他処理
		if (false == JPCModelCommon.succeededExclusiveLock(msgKU0011, inContext, JKUStrConst.SCHEMA_KU0011))
		{
			// 排他処理失敗
			return false;
		}
		
		// 以下更新項目設定
		if(ukFlg)
		{
			// 同時代表工事案件番号
			msgKU0011.set(KU0011ETMsg.DOJI_DAIHYO_KOJIAK_NO, kojiakNo);
			
			// TV契約照査待ち有無
			// 同項目が有の場合のみ更新
			if (JKUStrConst.UM_YK.equals(msgKU0011.getString(KU0011ETMsg.TV_KEI_SHOSA_STAY_UM)))
			{
				msgKU0011.set(KU0011ETMsg.TV_KEI_SHOSA_STAY_UM, JKUStrConst.UM_NON);
			}
		}
		else
		{
			// 同時代表工事案件番号
			msgKU0011.set(KU0011ETMsg.DOJI_DAIHYO_KOJIAK_NO, "");
		}
		
		// 更新年月日時分秒
		msgKU0011.set(KU0011ETMsg.UPD_DTM, operateDatetime);
		// 更新オペレータアカウント
		msgKU0011.set(KU0011ETMsg.UPD_OPEACNT, operatorId);

		try
		{
			sp0011.update(msgKU0011);
		}
		catch (CAANFinderException cfe)
		{
			throw cfe;
		}
		
		return true;
		
	}
	
	/**
	 * 同時代表工事更新先行設計
	 * @param kojiakNo	工事案件番号
	 * @param dojiDaihyoKojiakNo	同時代表工事案件番号
	 * @param operateDatetime 更新年月日時分秒
	 * @param operatorId 更新オペレータアカウント
	 * @param ukFlg 受付フラグ true:受付系(同時代表工事案件番号を引数の工事案件番号で更新) false:解約系(同時代表工事案件番号を空白で更新)
	 * @return boolean
	 * @throws CAANException
	 */
	public static boolean updateDojiDaihyoSenkoDsgn(String kojiakNo, String dojiDaihyoKojiakNo, 
			String operateDatetime, String operatorId, boolean ukFlg) throws CAANException
	{
		// 同時代表工事案件番号がNULL
		if(null == dojiDaihyoKojiakNo)
		{
			// 更新処理なし
			return false;
		}
		
		// 工事案件 副次処理
		JKUejbKU0101SecProc sp0101 = new JKUejbKU0101SecProc();
		// 工事案件のETメッセージを作成
		CAANMsg inMsgKU0101 = new CAANMsg(KU0101ETMsg.class.getName());
		CAANMsg[] outMsgKU0101 = null;
		// 工事案件番号
		inMsgKU0101.set(KU0101ETMsg.KOJIAK_NO, dojiDaihyoKojiakNo);
		// 無効フラグ
		inMsgKU0101.set(KU0101ETMsg.MK_FLG, JKUStrConst.MK_FLG_YUKO);
		// 対象のレコード取得
		outMsgKU0101 = sp0101.findByCondition(inMsgKU0101);
		
		// ステータスが依頼前のもののみをリスト化する
		
		List<CAANMsg> befIraiMsgKu0101 = new ArrayList<CAANMsg>();
		String snkskiStat = null;
		
		if (null != outMsgKU0101)
		{
			for (int i = 0; i < outMsgKU0101.length; ++i)
			{
				snkskiStat = outMsgKU0101[i].getString(KU0101ETMsg.SNKSKI_STAT);
				if (JKUStrConst.SNKSKI_STAT_TOROKU_ZM.equals(snkskiStat)
						|| JKUStrConst.SNKSKI_STAT_UK_ZM.equals(snkskiStat))
				{
					befIraiMsgKu0101.add(outMsgKU0101[i]);
				}
			}
		}
		
		if(befIraiMsgKu0101.size() == 0)
		{
			return false;
		}
		try
		{
			for(CAANMsg msgKU0101 : befIraiMsgKu0101)
			{
				// 以下更新項目設定
				
				if(ukFlg)
				{
					// 同時代表工事案件番号
					msgKU0101.set(KU0101ETMsg.DOJI_DAIHYO_KOJIAK_NO, kojiakNo);
					
					// 先行設計ステータス
					msgKU0101.set(KU0101ETMsg.SNKSKI_STAT, JKUStrConst.SNKSKI_STAT_UK_ZM);
				}
				else
				{
					// 同時代表工事案件番号
					msgKU0101.set(KU0101ETMsg.DOJI_DAIHYO_KOJIAK_NO, "");
				}
				
				// 更新年月日時分秒
				msgKU0101.set(KU0101ETMsg.UPD_DTM, operateDatetime);
				// 更新オペレータアカウント
				msgKU0101.set(KU0101ETMsg.UPD_OPEACNT, operatorId);
				
				sp0101.update(msgKU0101);
			}
		}
		catch (CAANFinderException cfe)
		{
			throw cfe;
		}
		
		return true;
		
	}
}