/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKejbRule0079001
*	ソースファイル名：JKKejbRule0079001.java
*	作成者			：富士通
*	日付			：2011年08月01日
*＜機能概要＞
*	工事費判定相関ルール部品
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/08/01	FJ)			新規作成
*	v5.00.00	2013/05/27	FJ）寺園	IT2-2013-0000451
*	v8.00.00	2014/02/09	FJ）大山	ANK-1589-00-00
*	v40.00.00	2019/01/22	FJ）阪口	【ANK-3412-00-00】５ギガ・１０ギガコース導入対応
*	v45.00.00	2019/05/22	FJ）黒田	【ANK-3636-00-00】消費増税対応（8%⇒10%）
*	v61.00.00	2023/05/31	FJ）張本	【ANK-4315-00-00】【eo定期】eoホームゲートウェイ導入対応
*
**********************************************************************/

package eo.ejb.common.rule;

import java.util.ArrayList;
import java.util.HashMap;

import com.fujitsu.futurity.model.base.CAANException;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANRuntimeException;

import eo.ejb.cbm.entity.KK0011ETMsg;
import eo.ejb.cbm.entity.KK0021ETMsg;
import eo.ejb.cbm.entity.KK0021LE;
import eo.ejb.cbm.entity.KK0081ETMsg;
import eo.ejb.cbm.entity.KK0081LE;
import eo.ejb.cbm.entity.KK1021ETMsg;
import eo.ejb.common.JKKModelCommon;
import eo.ejb.common.db.JKKejbKK0021DBABase;
import eo.ejb.common.db.JKKejbZM0321DBAccess;
import eo.ejb.common.edit.JKKejbKK1021NumberParts;

/**
 * <p>
 * 工事費判定相関ルール部品クラスです。
 * </p>
 * @author 富士通
 */
public class JKKejbRule0079001 extends JKKejbRuleBase
{

	/** ルールID */
	private static final String RULE_ID = "RULE0079001";

	/** 異動区分 */
	private static final String IDO_DIV = "IDO_DIV";

	/** 申込料金グループコード */
	private static final String MSKM_PRC_GRP_CD = "MSKM_PRC_GRP_CD";

	/** バンドル有無 */
	private static final String BUNDLE_UM = "BUNDLE_UM";

	/** 撤去希望設備 */
	private static final String TK_KIBO_EQUIP = "TK_KIBO_EQUIP";

	/** 判定結果 */
	public static final String JUDGE_RSLT = "JUDGE_RSLT";

	/** 一時支払料金番号 */
	public static final String TMP_PAY_PRC_NO = "TMP_PAY_PRC_NO";

	/** 発生単位 */
	public static final String HASSEI_TANI = "HASSEI_TANI";

	/** 一時金設定コード */
	public static final String ICJKN_SETTE_CD = "ICJKN_SETTE_CD";

	/** 住居形態 */
	private static final String JK_FORM = "JK_FORM";

	/** 税率区分 */
	private static final String STAX_DIV = "STAX_DIV";

// ANK-3412-00-00 ADD START
	/** 申込料金コースコード */
	private static final String MSKM_PCRS_CD = "MSKM_PCRS_CD";
// ANK-3412-00-00 ADD END
// ANK-3415-00-00 ADD START
	/** 工事案件種別コード */
	private static final String KOJIAK_SBT_CD = "KOJIAK_SBT_CD";
// ANK-3415-00-00 ADD END

	/** 判定結果(徴収対象) */
	private static final String JDG_RSLT_CLCT_TRGT = "1";

	/** 一時金設定コード(半額) */
	private static final String ICJKN_SET_CD_AMNT_HF = "03";

	/** 一時金設定コード(バンドルあり減額) */
	private static final String ICJKN_SET_CD_BNDL_GNGK = "05";

	/** バンドル有無(無) */
	private static final String BUNDLE_UM_OFF = "0";

	/** バンドル有無(有) */
	private static final String BUNDLE_UM_ON = "1";

	/** eo光ネット系料金グループ */
	private static final String[] EO_NET_GRP = {"02", "03", "04"};

	/** 税率区分（５％) */
	private static final String STAX_DIV_5 = "0";

	/** 税率区分（８％) */
	private static final String STAX_DIV_8 = "1";

// ANK-3636-00-00 ADD START
	/** 税率区分（１０％) */
	private static final String STAX_DIV_10 = "2";
// ANK-3636-00-00 ADD END

	/** 業務パラメータＩＤ（KK_TPPN_STAX_APLYYMD） */
	private static final String KK_TPPN_STAX_APLYYMD = "KK_TPPN_STAX_APLYYMD";

// ANK-3636-00-00 ADD START
	/** 業務パラメータＩＤ（KK_TPPN_STAX_APYMD08） */
	private static final String KK_TPPN_STAX_APYMD08 = "KK_TPPN_STAX_APYMD08";
// ANK-3636-00-00 ADD END

	/** 処理対象のCBSMsg */
	private CAANMsg inCBSMsg = null;

	/** 異動区分 */
	private String ido_div = null;

	/** 申込料金グループコード */
	private String mskm_prc_grp_cd = null;

	/** バンドル有無 */
	private String bundle_um = null;

	/** 撤去希望設備 */
	private String tk_kibo_equip = null;

	/** 申込明細番号 */
	private String mskm_dtl_no = null;

	/** サービス契約番号 */
	private String svc_kei_no = null;

	/** 住居形態 */
	private String jk_form = null;

	/** 税率区分 */
	private String stax_div = null;

// ANK-3412-00-00 ADD START
	/** 申込料金コースコード */
	private String mskm_pcrs_cd = null;
// ANK-3412-00-00 ADD END

// ANK-4315-00-00 ADD START
	/** 工事案件種別コード */
	private String kojiak_sbt_cd = null;
// ANK-4315-00-00 ADD END


	/**
	 * <p>
	 * JKKejbRule0079001クラスのコンストラクタです。
	 * </p>
	 * @param inMsg 処理対象のCBSMsg
	 */
	public JKKejbRule0079001(CAANMsg inMsg)
	{
		super();
		this.inCBSMsg = inMsg;
	}

	/**
	 * <p>
	 * 処理対象のCBSMsgを取得します。
	 * </p>
	 * @return 処理対象のCBSMsg
	 */
	protected CAANMsg getCBSMsg()
	{
		return this.inCBSMsg;
	}

	/**
	 * <p>
	 * ルールIDを取得します。
	 * </p>
	 * @return ルールID
	 */
	protected String getRuleId()
	{
		return RULE_ID;
	}

	/**
	 * <p>
	 * ルールエンジンを複数条件モードで実行するか設定します。
	 * </p>
	 * @return 複数条件モードで実行する場合はtrue
	 */
	protected boolean isMultiMode()
	{
		return true;
	}

	/**
	 * <p>
	 * 異動区分を取得します。
	 * </p>
	 * @return 異動区分
	 */
	private String getIdo_div()
	{
		return this.ido_div;
	}

	/**
	 * <p>
	 * 申込料金グループコードを取得します。
	 * </p>
	 * @return 申込料金グループコード
	 */
	private String getMskm_prc_grp_cd()
	{
		return this.mskm_prc_grp_cd;
	}

	/**
	 * <p>
	 * バンドル有無を取得します。
	 * </p>
	 * @return バンドル有無
	 */
	private String getBundle_um()
	{
		return this.bundle_um;
	}

	/**
	 * <p>
	 * 撤去希望設備を取得します。
	 * </p>
	 * @return 撤去希望設備
	 */
	private String getTk_kibo_equip()
	{
		return this.tk_kibo_equip;
	}

	/**
	 * <p>
	 * 申込明細番号を取得します。
	 * </p>
	 * @return 申込明細番号
	 */
	private String getMskm_dtl_no()
	{
		return this.mskm_dtl_no;
	}

	/**
	 * <p>
	 * サービス契約番号を取得します。
	 * </p>
	 * @return サービス契約番号
	 */
	private String getSvc_kei_no()
	{
		return this.svc_kei_no;
	}

	/**
	 * <p>
	 * 住居形態を取得します。
	 * </p>
	 * @return 住居形態
	 */
	private String getJk_form()
	{
		return this.jk_form;
	}

	/**
	 * <p>
	 * 税率区分を取得します。
	 * </p>
	 * @return 住居形態
	 */
	public String getStax_div()
	{
		return stax_div;
	}

// ANK-3412-00-00 ADD START
	/**
	 * <p>
	 * 申込料金コースコードを取得します。
	 * </p>
	 * @return 申込料金コースコード
	 */
	public String getMskm_pcrs_cd()
	{
		return mskm_pcrs_cd;
	}
// ANK-3412-00-00 ADD END

// ANK-4315-00-00 ADD START
	/**
	 * <p>
	 * 工事案件種別コードを取得します。
	 * </p>
	 * @return 工事案件種別コード
	 */
	public String getKojiak_sbt_cd()
	{
		return kojiak_sbt_cd;
	}
// ANK-4315-00-00 ADD END

	/**
	 * <p>
	 * 異動区分を設定します。
	 * </p>
	 * @param p_ido_div 異動区分
	 */
	public void setIdo_div(String p_ido_div)
	{
		this.ido_div = p_ido_div;
	}

	/**
	 * <p>
	 * 申込料金グループコードを設定します。
	 * </p>
	 * @param p_mskm_prc_grp_cd 申込料金グループコード
	 */
	public void setMskm_prc_grp_cd(String p_mskm_prc_grp_cd)
	{
		this.mskm_prc_grp_cd = p_mskm_prc_grp_cd;
	}

	/**
	 * <p>
	 * バンドル有無を設定します。
	 * </p>
	 * @param p_bundle_um バンドル有無
	 */
	public void setBundle_um(String p_bundle_um)
	{
		this.bundle_um = p_bundle_um;
	}

	/**
	 * <p>
	 * 撤去希望設備を設定します。
	 * </p>
	 * @param p_tk_kibo_equip 撤去希望設備
	 */
	public void setTk_kibo_equip(String p_tk_kibo_equip)
	{
		this.tk_kibo_equip = p_tk_kibo_equip;
	}

	/**
	 * <p>
	 * 申込明細番号を設定します。
	 * </p>
	 * @param p_mskm_dtl_no 申込明細番号
	 */
	public void setMskm_dtl_no(String p_mskm_dtl_no)
	{
		this.mskm_dtl_no = p_mskm_dtl_no;
	}

	/**
	 * <p>
	 * サービス契約番号を設定します。
	 * </p>
	 * @param p_svc_kei_no サービス契約番号
	 */
	public void setSvc_kei_no(String p_svc_kei_no)
	{
		this.svc_kei_no = p_svc_kei_no;
	}

	/**
	 * <p>
	 * 住居形態を設定します。
	 * </p>
	 * @param p_jk_form 住居形態
	 */
	public void setJk_form(String p_jk_form)
	{
		this.jk_form = p_jk_form;
	}

	/**
	 * <p>
	 * 税率区分を設定します。
	 * </p>
	 * @param p_jk_form 住居形態
	 */
	public void setStax_div(String stax_div)
	{
		this.stax_div = stax_div;
	}

// ANK-3412-00-00 ADD START
	/**
	 * <p>
	 * 申込料金コースコードを設定します。
	 * </p>
	 * @param mskm_pcrs_cd 申込料金コースコード
	 */
	public void setMskm_pcrs_cd(String mskm_pcrs_cd)
	{
		this.mskm_pcrs_cd = mskm_pcrs_cd;
	}
// ANK-3412-00-00 ADD END

// ANK-4315-00-00 ADD START
	/**
	 * <p>
	 * 工事案件種別コードを設定します。
	 * </p>
	 * @param p_kojiak_sbt_cd 工事案件種別コード
	 */
	public void setKojiak_sbt_cd(String p_kojiak_sbt_cd)
	{
		this.kojiak_sbt_cd = p_kojiak_sbt_cd;
	}
// ANK-4315-00-00 ADD END

	/**
	 * <p>
	 * 工事費判定相関ルールの参照を行います。
	 * </p>
	 * @return ルールエンジンの実行結果リスト
	 */
	public ArrayList<HashMap<String, Object>> referRuleEngine()
	{
		// ルールエンジンで使用する値を設定
		set(IDO_DIV, getIdo_div());
		set(MSKM_PRC_GRP_CD, getMskm_prc_grp_cd());
		set(BUNDLE_UM, getBundle_um());
		set(TK_KIBO_EQUIP, getTk_kibo_equip());
		set(JK_FORM, getJk_form());
		set(STAX_DIV, getStax_divZM0321());
// ANK-3412-00-00 ADD START
		set(MSKM_PCRS_CD, getMskm_pcrs_cd());
// ANK-3412-00-00 ADD END
// ANK-4315-00-00 ADD START
		set(KOJIAK_SBT_CD, getKojiak_sbt_cd());
// ANK-4315-00-00 ADD END

		// ルールエンジンの実行
		super.execRuleEngine();

		if (!hasNext())
		{
			// 実行結果が存在しない場合
			return null;
		}

		// 実行結果を返却
		return super.getResultList();
	}

	/**
	 * <p>
	 * 工事費判定相関ルールを実行します。
	 * </p>
	 */
	public void invoke()
	{
		// ルールエンジンで使用する値を設定
		set(IDO_DIV, getIdo_div());
		set(MSKM_PRC_GRP_CD, getMskm_prc_grp_cd());
		set(BUNDLE_UM, getBundle_um());
		set(TK_KIBO_EQUIP, getTk_kibo_equip());
		set(JK_FORM, getJk_form());
		set(STAX_DIV, getStax_divZM0321());

		// ルールエンジンの実行
		super.execRuleEngine();

		// 実行結果のデータ件数分処理を実行
		while (hasNext())
		{
			HashMap<String, Object> retMap = getResultMap();

			// 実行結果が「0：徴収対象外」の場合は一時金設定を登録しない
			if (!JDG_RSLT_CLCT_TRGT.equals(retMap.get(JUDGE_RSLT)))
			{
				continue;
			}

			// 一時金設定の登録
			createKK1021(retMap);
		}
	}

	/**
	 * <p>
	 * 一時金設定の登録を行います。
	 * </p>
	 * @param retMap ルールエンジン実行結果のMap
	 */
	private void createKK1021(HashMap<String, Object> retMap)
	{
		// 一時金設定登録メッセージの作成
		CAANMsg inETMsg = new CAANMsg(KK1021ETMsg.class.getName());
		// 一時金設定番号 <= 採番部品戻り値
		inETMsg.set(KK1021ETMsg.ICJKN_SETTE_NO, new JKKejbKK1021NumberParts().getIcjknSetteNo());
		// 一時支払料金番号 <= ルール実行結果Map.一時支払料金番号
		inETMsg.set(KK1021ETMsg.TMP_PAY_PRC_NO, (String)retMap.get(TMP_PAY_PRC_NO));

		// 一時金設定コード
		String icjknSetteCd = (String)retMap.get(ICJKN_SETTE_CD);

		if (ICJKN_SET_CD_BNDL_GNGK.equals(icjknSetteCd))
		{
			// 一時金設定コードが"05"(バンドルあり減額)の場合
			// 一時金設定コード <= "03"(半額)
			inETMsg.set(KK1021ETMsg.ICJKN_SETTE_CD, ICJKN_SET_CD_AMNT_HF);
		}
		else
		{
			// 一時金設定コード <= ルール実行結果Map.一時金設定コード
			inETMsg.set(KK1021ETMsg.ICJKN_SETTE_CD, icjknSetteCd);
		}

		// 一時金指定率 <= NULL値
		inETMsg.setNull(KK1021ETMsg.ICJKN_SHITEI_RT);
		// 一時支払料金額 <= NULL値
		inETMsg.setNull(KK1021ETMsg.ICJKN_SHITEI_AMNT);
		// サービス契約番号 <= 入力値.サービス契約番号
		inETMsg.set(KK1021ETMsg.SVC_KEI_NO, getSvc_kei_no());
		// サービス契約内訳番号 <= NULL値
		inETMsg.setNull(KK1021ETMsg.SVC_KEI_UCWK_NO);
		// 機器提供サービス契約番号 <= NULL値
		inETMsg.setNull(KK1021ETMsg.KKTK_SVC_KEI_NO);
		// オプションサービス契約番号 <= NULL値
		inETMsg.setNull(KK1021ETMsg.OP_SVC_KEI_NO);
		// サブオプションサービス契約番号 <= NULL値
		inETMsg.setNull(KK1021ETMsg.SBOP_SVC_KEI_NO);
		// 割引サービス契約番号 <= NULL値
		inETMsg.setNull(KK1021ETMsg.WRIB_SVC_KEI_NO);
		// 請求オプションサービス契約番号 <= NULL値
		inETMsg.setNull(KK1021ETMsg.SEIOPSVC_KEI_NO);
		// 申込明細番号 <= 入力値.申込明細番号
		inETMsg.set(KK1021ETMsg.MSKM_DTL_NO, getMskm_dtl_no());
		// 一時金発生年月日 <= 運用日付
		inETMsg.set(KK1021ETMsg.ICJKN_HASSEI_YMD, JKKModelCommon.getOpeDate(inCBSMsg));

		// 登録処理の実行
		super.create(inETMsg);
	}

	/**
	 * <p>
	 * バンドル有無を取得します。
	 * </p>
	 * @param p_mskm_dtl_no 申込明細番号
	 * @return ネットが同時に申し込まれている場合は"0"(無)、それ以外の場合は"1"(有)
	 */
	public String getBundleUm(String p_mskm_dtl_no)
	{
		// 申込明細番号が設定されていない場合
		if (p_mskm_dtl_no == null)
		{
			return BUNDLE_UM_OFF;
		}

		// 申込明細から申込番号を取得
		CAANMsg kk0021 = findByCurrentKK0021(p_mskm_dtl_no);

		// 申込番号に紐付く申込明細番号を取得
		CAANMsg[] kk0021List = findByConditionKK0021(kk0021.getString(KK0021ETMsg.MSKM_NO));

		// 処理済み判定用のMap
		HashMap<String, String> syrzmMap = new HashMap<String, String>();

		// 取得した申込明細番号毎にサービス契約を検索
		for (CAANMsg kk0021Data : kk0021List)
		{
			String mskmDtlNo = kk0021Data.getString(KK0021ETMsg.MSKM_DTL_NO);

			if (p_mskm_dtl_no.equals(mskmDtlNo))
			{
				// 入力と同じ申込明細番号は処理対象外
				continue;
			}

			if (syrzmMap.containsKey(mskmDtlNo))
			{
				// 処理済みの申込明細番号は処理対象外
				continue;
			}

			// サービス契約の検索
			CAANMsg[] kk0081List = findByConditionKK0081(mskmDtlNo);

			for (CAANMsg kk0081Data : kk0081List)
			{
				if (isEoNetTypeGroup(kk0081Data.getString(KK0081ETMsg.PRC_GRP_CD)))
				{
					// eo光ネット系料金グループの場合は同時申込あり
					return BUNDLE_UM_ON;
				}
			}

			// 処理済み判定用のMapに格納
			syrzmMap.put(mskmDtlNo, mskmDtlNo);
		}

		return BUNDLE_UM_OFF;
	}

	/**
	 * <p>
	 * eo光ネット系料金グループか判定します。
	 * </p>
	 * @param p_prc_grp_cd 料金グループコード
	 * @return eo光ネット系料金グループの場合はtrue
	 */
	private boolean isEoNetTypeGroup(String p_prc_grp_cd)
	{
		for (String value : EO_NET_GRP)
		{
			if (value.equals(p_prc_grp_cd))
			{
				return true;
			}
		}

		return false;
	}

	/**
	 * <p>
	 * 申込明細のカレントレコード検索を行います。
	 * </p>
	 * @param p_mskm_dtl_no 申込明細番号
	 * @return 申込明細のカレントレコード
	 */
	private CAANMsg findByCurrentKK0021(String p_mskm_dtl_no)
	{
		CAANMsg kk0021_01 = new CAANMsg(KK0021ETMsg.class.getName());
		kk0021_01.set(KK0021ETMsg.MSKM_DTL_NO, p_mskm_dtl_no);
		return new JKKejbKK0021DBABase().findByCurrent(kk0021_01);
	}

	/**
	 * <p>
	 * 申込番号に紐付く申込明細の一覧検索を行います。
	 * </p>
	 * @param p_mskm_no 申込番号
	 * @return 申込番号に紐付く申込明細一覧
	 */
	private CAANMsg[] findByConditionKK0021(String p_mskm_no)
	{
		CAANMsg msg = new CAANMsg(KK0021ETMsg.class.getName());
		msg.set(KK0011ETMsg.MSKM_NO, p_mskm_no);
		msg.set(KK0011ETMsg.MK_FLG, "0");

		try
		{
			return new KK0021LE().findByCondition(msg);
		}
		catch (CAANException ce)
		{
			throw new CAANRuntimeException(ce);
		}
	}

	/**
	 * <p>
	 * 申込明細番号に紐付くサービス契約の一覧検索を行います。
	 * </p>
	 * @param p_mskm_dtl_no 申込明細番号
	 * @return 申込番号に紐付くサービス契約一覧
	 */
	private CAANMsg[] findByConditionKK0081(String p_mskm_dtl_no)
	{
		CAANMsg msg = new CAANMsg(KK0081ETMsg.class.getName());
		msg.set(KK0081ETMsg.MSKM_DTL_NO, p_mskm_dtl_no);
		msg.set(KK0081ETMsg.MK_FLG, "0");

		try
		{
			return new KK0081LE().findByCondition(msg);
		}
		catch (CAANException ce)
		{
			throw new CAANRuntimeException(ce);
		}
	}

	/**
	 * 税率区分の取得を行う。
	 */
	private String getStax_divZM0321() {
		JKKejbZM0321DBAccess zm0321Access = new JKKejbZM0321DBAccess();
		
		// 一時支払料金番号（５％）適用年月日
		String strStaxDate = zm0321Access.getParam(KK_TPPN_STAX_APLYYMD);
// ANK-3636-00-00 ADD START
		// 一時支払料金番号（８％）適用年月日
		String strStaxDate_8 = zm0321Access.getParam(KK_TPPN_STAX_APYMD08);
// ANK-3636-00-00 ADD END
		String opeDate = JKKModelCommon.getOpeDate(getCBSMsg());
		
		// 基準日（８％）（税率区分）が運用日より過去（運用日含まず）の場合１０％を返却
// ANK-3636-00-00 MOD START
//		if(JKKModelCommon.isPastDate(strStaxDate, opeDate, "0")) {
		if(JKKModelCommon.isPastDate(strStaxDate_8, opeDate, "0"))
		{
			setStax_div(STAX_DIV_10);
		}
		// 基準日（５％）（税率区分）が運用日より過去（運用日含まず）の場合８％を返却
		else if(JKKModelCommon.isPastDate(strStaxDate, opeDate, "0"))
		{
// ANK-3636-00-00 MOD END
			setStax_div(STAX_DIV_8);
		}
		else
		{
			setStax_div(STAX_DIV_5);
		}
		
		return getStax_div();
	}
}
