/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JEKK0371C040ETDA
*	ソースファイル名：JEKK0371C040ETDA.java
*	作成者			：富士通
*	日付			：2011年10月06日
*＜機能概要＞
*	オプションサービス契約<電話>開始時の副次処理を行う部品
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/10/06	富士通		新規作成
*	v10.00.00	2014/09/16	FJ）宇野	OM-2014-0002890対応
*
**********************************************************************/

package eo.ejb.common.db;

import java.text.ParseException;
import java.util.HashMap;
import java.util.List;

import com.fujitsu.futurity.common.JCMConstants;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANRuntimeException;
import com.fujitsu.futurity.model.ejb.common.StatusCodes;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;

import eo.ejb.cbm.entity.KK0351ETMsg;
import eo.ejb.cbm.entity.KK0371ETMsg;
import eo.ejb.cbm.entity.KK1681ETMsg;
import eo.ejb.cbs.cbsmsg.EKK0371C040CBSMsg;
import eo.ejb.cbs.mainproc.JKKejbIdoRsvUtil;
import eo.ejb.common.JKKModelCommon;
import eo.ejb.common.JKKModelConst;

/**
 * <p>
 * オプションサービス契約<電話>開始の副次処理を行う部品クラスです。
 * </p>
 * @author 富士通
 */
public class JEKK0371C040ETDA
{

	/** サービスコード 電話サービス */
	private static final String SVCCD_TEL = "02";
	
	/** 予約適用コード 予約確定 */
	private static final String APLYCD_DECIDED = "2";
	
	/** 無効フラグ 有効 */
	private static final String MKFLG_VALID = "0";
	
	/** 関連チェックエラーフラグ&エラー返却項目(オプションサービス契約 開始日確定チェック) */
	private static final String[] KRCK_OP_START_DECIDED_ERR = {"EE", EKK0371C040CBSMsg.OP_SVC_KEI_NO_ERR};

	/** 相関ルールチェックエラーフラグ&エラー返却項目(異動対象スキーマ判定相関ルール) */
	private static final String[] CORR_IDOJDG = {"EA", EKK0371C040CBSMsg.IDO_DIV_ERR};
	
	/**
	 * <p>
	 * オプションサービス契約<電話>開始のDBアクセスを行います。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 */
	public void execDBAccess(CAANMsg inCBSMsg, AgentDispatchContext inContext)
	{
		// オプションサービス契約ETDA生成
		JKKejbKK0351ETDA opEtda = new JKKejbKK0351ETDA();
		
		String opSvcKeiNo = inCBSMsg.getString(EKK0371C040CBSMsg.OP_SVC_KEI_NO);
		String skjYkgt = inCBSMsg.getString(EKK0371C040CBSMsg.SKJ_YKGT);
		
		// 開始日設定(オプションサービス)相関ルール
		String staYmd = opEtda.execSokanOfStaYmd(inCBSMsg, inContext, opSvcKeiNo, SVCCD_TEL, skjYkgt);

		if (null == staYmd)
		{
			// 開始日を取得しなかった場合、関連チェックエラー
			setErrInfo(inCBSMsg, StatusCodes.RELATION_ERR, KRCK_OP_START_DECIDED_ERR);
			return;
		}
		
		// 異動対象スキーマ判定相関ルール
		List<HashMap<String, Object>> ruleList = opEtda.execSokanOfIdoJdg(inCBSMsg, inContext, staYmd);

		if (ruleList == null)
		{
			// 異動対象スキーマ判定相関ルールの結果が0件の場合は相関ルールチェックエラー
			setErrInfo(inCBSMsg, StatusCodes.TEMPLATE_CORRELATION_ERR, CORR_IDOJDG);
			return;
		}
		
		// 相関ルールチェック結果を格納
		new JKKejbIdoRsvUtil().setOnlyIdoRsvFlg(inCBSMsg, inContext, ruleList);

		String targetSchema = opEtda.judgeSchema(inCBSMsg, inContext, ruleList);
		
		if (JKKejbKK0351ETDA.SCHEMAID_OPSVCKEI.equals(targetSchema))
		{
			// オプションサービス契約に振舞う場合
			CAANMsg kk0351Msg = new CAANMsg(KK0351ETMsg.class.getName());
			kk0351Msg.set(KK0351ETMsg.OP_SVC_KEI_NO, opSvcKeiNo);
			kk0351Msg.set(KK0351ETMsg.IDO_DIV, inCBSMsg.getString(EKK0371C040CBSMsg.IDO_DIV));
			
			// OM-2014-0002890 ADD START
			// オプションサービス契約の初回履歴レコードを取得
			JKKejbKK0351DBABase kk0351DbaBase = new JKKejbKK0351DBABase();
			CAANMsg kk0351FirstMsg = kk0351DbaBase.getKK0351RirekiFirst(inCBSMsg.getString(EKK0371C040CBSMsg.OP_SVC_KEI_NO));
			
			// 入力値の異動区分が光電話・番ポ情報変更且つ、初回履歴レコードの異動区分がオプション設定且つ、開始日が月初の場合
			String chrgStaYmd = "";
			String first_idoDiv = kk0351FirstMsg.getString(KK0351ETMsg.IDO_DIV);
			if(JKKModelConst.IDO_DIV_HIKARI_DENPO_CHG.equals(inCBSMsg.getString(EKK0371C040CBSMsg.IDO_DIV)) && 
					JKKModelConst.IDO_DIV_OP_SET.equals(first_idoDiv) && 
					"01".equals(staYmd.substring(6, 8)))
			{
				// 開始日の翌月月初を設定する
				try
				{
					chrgStaYmd = JKKModelCommon.addMonth(staYmd, 1);
				}
				catch (ParseException ce)
				{
					throw new CAANRuntimeException(ce);
				}
				
			}
			else
			{
			// OM-2014-0002890 ADD END

				// OM-2014-0002890 MOD START
				// 課金開始日設定(オプション)相関ルール
//				String chrgStaYmd = opEtda.execSokanOfChrgStaYmd(inCBSMsg, inContext, opSvcKeiNo, skjYkgt, staYmd);
				chrgStaYmd = opEtda.execSokanOfChrgStaYmd(inCBSMsg, inContext, opSvcKeiNo, skjYkgt, staYmd);
				// OM-2014-0002890 MOD END
				
				if (null == chrgStaYmd)
				{
					// 課金開始日を取得しなかった場合、関連チェックエラー
					setErrInfo(inCBSMsg, StatusCodes.RELATION_ERR, KRCK_OP_START_DECIDED_ERR);
					return;
				}
			}

			// オプションサービス契約登録
			CAANMsg dbInfoOp = opEtda.execDBAccessOpKei(inCBSMsg, inContext, kk0351Msg, staYmd, chrgStaYmd);

			// オプションサービス契約<電話>登録
			CAANMsg dbInfoSub = execDBAccessOpSub(inCBSMsg, inContext);
			
			// 出力項目の設定
			setOutputOfOp(inCBSMsg, inContext, dbInfoOp);
			setOutputOfOpSub(inCBSMsg, inContext, dbInfoSub);
		}
		else
		{
			// 上記のスキーマ以外(異動予約)に振舞う場合
			CAANMsg kk1681Msg = new CAANMsg(KK1681ETMsg.class.getName());
			kk1681Msg.set(KK1681ETMsg.OP_SVC_KEI_NO, opSvcKeiNo);
			kk1681Msg.set(KK1681ETMsg.IDO_DIV, inCBSMsg.getString(EKK0371C040CBSMsg.IDO_DIV));
			
			// 異動予約登録
			CAANMsg dbInfoIdoRsv = opEtda.execDBAccessIdoRsv(inCBSMsg, inContext, kk1681Msg, staYmd, null, ruleList.get(0));

			// 出力項目の設定
			setOutputOfIdoRsv(inCBSMsg, inContext, dbInfoIdoRsv);
		}
	}

	/**
	 * <p>
	 * オプションサービス契約<電話>のDBアクセスを行います。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @return オプションサービス契約<電話>の登録内容
	 */
	private CAANMsg execDBAccessOpSub(CAANMsg inCBSMsg, AgentDispatchContext inContext)
	{
		// 引継元となるオプションサービス契約<電話>を取得
		String opSvcKeiNo = inCBSMsg.getString(EKK0371C040CBSMsg.OP_SVC_KEI_NO);
		CAANMsg kk0371Cur = getCurOpKeiSub(inCBSMsg, inContext, opSvcKeiNo);
		
		// 登録内容設定
		kk0371Cur.set(KK0371ETMsg.OP_SVC_KEI_NO, inCBSMsg.getString(EKK0371C040CBSMsg.OP_SVC_KEI_NO));
		kk0371Cur.set(KK0371ETMsg.GENE_ADD_DTM, JKKModelCommon.getTransferGeneAddDtm(inCBSMsg, inContext));
		kk0371Cur.set(KK0371ETMsg.N_050_OP_TELNO, inCBSMsg.getString(EKK0371C040CBSMsg.N_050_OP_TELNO));
		kk0371Cur.set(KK0371ETMsg.RSV_APLY_CD, APLYCD_DECIDED);
		kk0371Cur.set(KK0371ETMsg.ADD_DTM, inCBSMsg.getString(JCMConstants.OPERATE_DATETIME_KEY));
		kk0371Cur.set(KK0371ETMsg.ADD_OPEACNT, inCBSMsg.getString(JCMConstants.OPERATOR_ID_KEY));
		kk0371Cur.set(KK0371ETMsg.UPD_DTM, inCBSMsg.getString(JCMConstants.OPERATE_DATETIME_KEY));
		kk0371Cur.set(KK0371ETMsg.UPD_OPEACNT, inCBSMsg.getString(JCMConstants.OPERATOR_ID_KEY));
		kk0371Cur.setNull(KK0371ETMsg.DEL_DTM);
		kk0371Cur.setNull(KK0371ETMsg.DEL_OPEACNT);
		kk0371Cur.set(KK0371ETMsg.MK_FLG, MKFLG_VALID);
		
		createKK0371(inCBSMsg, inContext, kk0371Cur);
		
		return kk0371Cur;
	}

	/**
	 * <p>
	 * オプションサービス契約<電話>のカレントレコードを取得します。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @return オプションサービス契約<電話>のカレントレコード
	 */
	private CAANMsg getCurOpKeiSub(CAANMsg inCBSMsg, AgentDispatchContext inContext, String opSvcKeiNo)
	{
		CAANMsg kk0371Cond = new CAANMsg(KK0371ETMsg.class.getName());
		kk0371Cond.set(KK0371ETMsg.OP_SVC_KEI_NO, opSvcKeiNo);
		
		return new JKKejbKK0371DBABase().findByCurrent(kk0371Cond);
	}
	
	/**
	 * <p>
	 * エラー返却項目にエラーフラグを設定します。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param status エラー時のステータス
	 * @param errInfo[] エラー情報が設定された配列 [0]:エラーフラグ [1]:エラー返却項目
	 */
	private void setErrInfo(CAANMsg inCBSMsg, int status, String[] errInfo)
	{
		inCBSMsg.set(JCMConstants.STATUS_INT_KEY, status);
		inCBSMsg.set(errInfo[1], errInfo[0]);
		return;	
	}
	
	/**
	 * <p>
	 * オプションサービス契約<電話>の登録を行います。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param kk0371Msg　オプションサービス契約<電話>のETメッセージ
	 */
	private void createKK0371(CAANMsg inCBSMsg, AgentDispatchContext inContext, CAANMsg kk0371Msg)
	{
		JKKejbDBAUtil dbaU = new JKKejbDBAUtil(inCBSMsg);
		dbaU.create(kk0371Msg);
	}

	/**
	 * <p>
	 * オプションサービス契約の登録内容でCBSメッセージに出力項目を設定します。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param kk0351Msg　オプションサービス契約のETメッセージ
	 */
	private void setOutputOfOp(CAANMsg inCBSMsg, AgentDispatchContext inContext, CAANMsg kk0351Msg)
	{
		inCBSMsg.set(EKK0371C040CBSMsg.KK0351_GENE_ADD_DTM, kk0351Msg.getString(KK0351ETMsg.GENE_ADD_DTM));
		inCBSMsg.set(EKK0371C040CBSMsg.OP_SVC_KEI_STAT, kk0351Msg.getString(KK0351ETMsg.OP_SVC_KEI_STAT));
		inCBSMsg.set(EKK0371C040CBSMsg.RSV_APLY_YMD, kk0351Msg.getString(KK0351ETMsg.RSV_APLY_YMD));
		inCBSMsg.set(EKK0371C040CBSMsg.RSV_APLY_CD, kk0351Msg.getString(KK0351ETMsg.RSV_APLY_CD));
		inCBSMsg.set(EKK0371C040CBSMsg.PLAN_STAYMD, kk0351Msg.getString(KK0351ETMsg.PLAN_STAYMD));
		inCBSMsg.set(EKK0371C040CBSMsg.PLAN_ENDYMD, kk0351Msg.getString(KK0351ETMsg.PLAN_ENDYMD));
		inCBSMsg.set(EKK0371C040CBSMsg.PLAN_CHRG_STAYMD, kk0351Msg.getString(KK0351ETMsg.PLAN_CHRG_STAYMD));
		inCBSMsg.set(EKK0371C040CBSMsg.PLAN_CHRG_ENDYMD, kk0351Msg.getString(KK0351ETMsg.PLAN_CHRG_ENDYMD));
		inCBSMsg.set(EKK0371C040CBSMsg.SVC_STAYMD, kk0351Msg.getString(KK0351ETMsg.SVC_STAYMD));
		inCBSMsg.set(EKK0371C040CBSMsg.SVC_CHRG_STAYMD, kk0351Msg.getString(KK0351ETMsg.SVC_CHRG_STAYMD));
		inCBSMsg.set(EKK0371C040CBSMsg.SVC_ENDYMD, kk0351Msg.getString(KK0351ETMsg.SVC_ENDYMD));
		inCBSMsg.set(EKK0371C040CBSMsg.SVC_CHRG_ENDYMD, kk0351Msg.getString(KK0351ETMsg.SVC_CHRG_ENDYMD));
		inCBSMsg.set(EKK0371C040CBSMsg.ADD_DTM, kk0351Msg.getString(KK0351ETMsg.ADD_DTM));
		inCBSMsg.set(EKK0371C040CBSMsg.ADD_OPEACNT, kk0351Msg.getString(KK0351ETMsg.ADD_OPEACNT));
		inCBSMsg.set(EKK0371C040CBSMsg.UPD_DTM, kk0351Msg.getString(KK0351ETMsg.UPD_DTM));
		inCBSMsg.set(EKK0371C040CBSMsg.UPD_OPEACNT, kk0351Msg.getString(KK0351ETMsg.UPD_OPEACNT));
		inCBSMsg.set(EKK0371C040CBSMsg.MK_FLG, kk0351Msg.getString(KK0351ETMsg.MK_FLG));
	}

	/**
	 * <p>
	 * オプションサービス契約<電話>の登録内容でCBSメッセージに出力項目を設定します。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param kk0371Msg　オプションサービス契約<電話>のETメッセージ
	 */
	private void setOutputOfOpSub(CAANMsg inCBSMsg, AgentDispatchContext inContext, CAANMsg kk0371Msg)
	{
		inCBSMsg.set(EKK0371C040CBSMsg.KK0371_GENE_ADD_DTM, kk0371Msg.getString(KK0371ETMsg.GENE_ADD_DTM));
	}

	/**
	 * <p>
	 * 異動予約の登録内容でCBSメッセージに出力項目を設定します。
	 * </p>
	 * @param inCBSMsg　CBSメッセージ
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param kk1681Msg 異動予約のETメッセージ
	 */
	private void setOutputOfIdoRsv(CAANMsg inCBSMsg, AgentDispatchContext inContext, CAANMsg kk1681Msg)
	{
		inCBSMsg.set(EKK0371C040CBSMsg.ADD_DTM, kk1681Msg.getString(KK1681ETMsg.ADD_DTM));
		inCBSMsg.set(EKK0371C040CBSMsg.ADD_OPEACNT, kk1681Msg.getString(KK1681ETMsg.ADD_OPEACNT));
		inCBSMsg.set(EKK0371C040CBSMsg.UPD_DTM, kk1681Msg.getString(KK1681ETMsg.UPD_DTM));
		inCBSMsg.set(EKK0371C040CBSMsg.UPD_OPEACNT, kk1681Msg.getString(KK1681ETMsg.UPD_OPEACNT));
		inCBSMsg.set(EKK0371C040CBSMsg.MK_FLG, kk1681Msg.getString(KK1681ETMsg.MK_FLG));
	}

}
