/*********************************************************************
*  All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JBSbatACPnltCalcKeikSochChoWri
*	ソースファイル名	：JBSbatACPnltCalcKeikSochChoWri.java
*	作成者				：富士通　
*	作成日				：2022年04月27日
*＜機能概要＞
*　違約金計算（経過措置）長割部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v59.00.00	2022/04/27  FJ）麻生	【ANK-4248-00-00】消費者保護ガイドライン改正対応（新規作成）
*	v67.00.00	2023/08/09  FJ）北村	【ANK-4426-00-00】長割解約精算金の計算ロジック改善
*********************************************************************/
package eo.business.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import eo.business.common.JACbatDebugLogUtil;
import eo.business.common.JACbatParamUtil;
import eo.business.common.JBSbatBusinessService;
import eo.business.util.file.JBSbatACIFM357;
import eo.business.util.table.JBSbatAC_M_PNLTY;
import eo.common.constant.JACStrConst;
import eo.common.util.JCHStringUtil;
import eo.common.util.JKKStringUtil;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatServiceInterfaceMap;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.util.JBSbatDateUtil;
import eo.framework.util.JBSbatStringUtil;

/**
* (クラスの機能概要) <p>
*<BR>
* @author 富士通
*/
public class JBSbatACPnltCalcKeikSochChoWri extends JBSbatBusinessService
{
	/**▼▼▼▼▼▼ツールから生成した宣言です 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成した宣言です 終了▲▲▲▲▲▲*/

	/** 経過措置違約金情報項目数*/
	private static final int KEIK_SOCH_PNLTY_INF_CNT = 7;

	/** 長割適用日算出月数*/
	private static final String CHO_WRI_MON_CNT = "CHO_WRT_MON_CNT";

	/** データタイプ数値*/
	private static final String DATA_TYPE_NUM = "1";

	/** （消費者保護ガイドライン）旧制度満了日*/
	private String kyuseidoEndymd = null;

	/** 経過措置違約金情報リスト*/
	private List<JBSbatServiceInterfaceMap> keikSochPnltyInfList = null;

	/**
	 * 初期処理
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した初期化のソースです 開始▼▼▼▼▼▼*/
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);

		/**▲▲▲▲▲▲ツールから生成した初期化のソースです 終了▲▲▲▲▲▲*/

		// 旧制度満了日取得
		kyuseidoEndymd = getKyuseidoEndymd();

		// 経過措置違約金情報読込
		keikSochPnltyInfList = getKeikSochPnltyInfList();

	/**▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 主処理
	 * @param inMap　入力電文
	 * @return JBSbatOutputItem　出力情報
	 * @throws Exception
	 */
	public JBSbatOutputItem execute(JBSbatServiceInterfaceMap inMap) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの主処理を記述してください。▼▼▼▼▼▼*/

		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][execute]");

		// 違約金を取得
		BigDecimal pnltyPrc = inMap.getBigDecimal(JBSbatACIFM357.PRC);
		
// ANK-4426-00-00 ADD START
		// 初回課金開始日を取得
		String judgeYmd = JKKStringUtil.nullToBlank(inMap.getString(JBSbatACIFM357.FIRST_CHRG_STAYMD));
		if (!(kyuseidoEndymd.compareTo(judgeYmd) < 0))
		{
// ANK-4426-00-00 ADD END 
			// 経過措置違約金情報を取得
			JBSbatServiceInterfaceMap keikSochPnltyInf = getKeikSochPnltyInf(inMap);

			// 経過措置対象判定
			if (isKeikSochTarget(inMap, keikSochPnltyInf))
			{
				// 違約金を経過措置の金額に置換
				pnltyPrc = keikSochPnltyInf.getBigDecimal(JBSbatAC_M_PNLTY.PNLTY_TANKA);
			}
// ANK-4426-00-00 ADD START
		}
// ANK-4426-00-00 ADD END 

		// 出力共通電文オブジェクト生成
		JBSbatOutputItem outItem = new JBSbatOutputItem();

		// 出力用マップを設定
		JBSbatServiceInterfaceMap outMap = makeOutMap(inMap, pnltyPrc);

		outItem.addOutMapList(outMap);

		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][execute]");

		return outItem;

	/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼*/
		/**▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲*/
	/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}

	/**▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成したメソッドです 終了▲▲▲▲▲▲*/

	/**
	 * 旧制度満了日の取得処理
	 * 
	 * @return String 旧制度満了日
	 * @throws Exception 業務パラメータ管理取得時の例外
	 */
	private String getKyuseidoEndymd() throws Exception
	{
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][getKyuseidoEndymd]");

		// 旧制度満了日
		String ymd;

		// パラメータ取得部品
		JACbatParamUtil paramUtil = new JACbatParamUtil(commonItem);

		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][getKyuseidoEndymd][業務パラメータ管理．検索条件：" + JACStrConst.WKPRA_CSMPRT_OLDMRD + "]");

		try
		{
			// 業務パラメータ取得（消費者保護ガイドライン＿旧制度満了日）
			ymd = paramUtil.getGyoumuParameter2(JACStrConst.WKPRA_CSMPRT_OLDMRD);
		}
		finally
		{
			paramUtil.close();
		}

		if (ymd == null)
		{
			ymd = "";
		}

		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][getKeikSochPnltyInfList][旧制度満了日:" + ymd + "]");

		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][getKyuseidoEndymd]");

		return ymd;
	}

	/**
	 * 経過措置違約金情報リストの取得処理
	 * 
	 * @return List<JBSbatCommonDBInterface> 経過措置違約金情報リスト
	 * @throws Exception 業務パラメータ管理取得時の例外
	 */
	private List<JBSbatServiceInterfaceMap> getKeikSochPnltyInfList() throws Exception
	{
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][getKeikSochPnltyInfList]");

		// 経過措置違約金情報リスト
		List<JBSbatServiceInterfaceMap> list = new ArrayList<JBSbatServiceInterfaceMap>();

		// パラメータ取得部品
		JACbatParamUtil paramUtil = new JACbatParamUtil(commonItem);

		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][getKeikSochPnltyInfList][業務パラメータ管理．検索条件：" + JACStrConst.WKPRA_KIK_SOCHI_PLT_ + "%, " + super.opeDate + "]");

		Map<String, String> workPamamMap = null;
		try
		{
			// 業務パラメータ取得（経過措置違約金情報）
			workPamamMap = paramUtil.getGyoumuParameterMap2(JACStrConst.WKPRA_KIK_SOCHI_PLT_, super.opeDate);
		}
		finally
		{
			paramUtil.close();
		}

		if (workPamamMap != null && workPamamMap.size() > 0)
		{
			assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][getKeikSochPnltyInfList][検索結果有]");

			for (Map.Entry<String, String> entry : workPamamMap.entrySet())
			{
				String workParamSetteValue = entry.getValue();
				if (!JCHStringUtil.isNullBlank(workParamSetteValue))
				{
					// 経過措置違約金情報リスト設定
					String[] params = workParamSetteValue.split(JACStrConst.COMMA);
					if (params.length == KEIK_SOCH_PNLTY_INF_CNT)
					{
						BigDecimal pnltyTanka;
						int choWriMonCnt;
						try
						{
							pnltyTanka = new BigDecimal(params[5]);
							choWriMonCnt = Integer.parseInt(params[6]);
						}
						catch (NumberFormatException e)
						{
							// 違約金単価、長割適用日算出月数が数値変換できないレコードはスキップ
							continue;
						}
						JBSbatServiceInterfaceMap keikSochPnltyInfMap = new JBSbatServiceInterfaceMap();
						keikSochPnltyInfMap.setString(JBSbatAC_M_PNLTY.TRGT_PCRS_CD, params[0]);
						keikSochPnltyInfMap.setString(JBSbatAC_M_PNLTY.TRGT_PRC_SVC_CD, params[1]);
						keikSochPnltyInfMap.setString(JBSbatAC_M_PNLTY.SVC_DSL_RSN_SKBT_CD, params[2]);
						keikSochPnltyInfMap.setString(JBSbatAC_M_PNLTY.LOWL_VALUE, params[3]);
						keikSochPnltyInfMap.setString(JBSbatAC_M_PNLTY.UPPL_VALUE, params[4]);
						keikSochPnltyInfMap.setBigDecimal(JBSbatAC_M_PNLTY.PNLTY_TANKA, pnltyTanka);
						keikSochPnltyInfMap.setInt(CHO_WRI_MON_CNT, choWriMonCnt);
						list.add(keikSochPnltyInfMap);
					}
				}
			}
		}

		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][getKeikSochPnltyInfList]");

		return list;
	}

	/**
	 * 経過措置違約金情報の取得処理
	 * 
	 * @param inMap 利用料金情報ファイル（違約金情報）
	 * @return JBSbatServiceInterfaceMap 経過措置違約金情報
	 * @throws Exception JBSbatServiceInterfaceMapの入出力時の例外
	 */
	private JBSbatServiceInterfaceMap getKeikSochPnltyInf(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][getKeikSochPnltyInf]");

		JBSbatServiceInterfaceMap inf = null;

		if (inMap != null && keikSochPnltyInfList != null)
		{
			assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint,
					"[L][getKeikSochPnltyInf][料金コースコード：" + inMap.getString(JBSbatACIFM357.PCRS_CD)
					+ ", 料金サービスコード：" + inMap.getString(JBSbatACIFM357.PRC_SVC_CD)
					+ ", サービス解約理由：" + inMap.getString(JBSbatACIFM357.SVC_DLRE)
					+ ", 継続期間：" + inMap.getString(JBSbatACIFM357.KEIZK_PRD)
					+ "]");

			//
			// 下記条件で経過措置違約金情報を検索
			// 
			// 経過措置違約金情報リスト．料金コースコード           ＝ 利用料金情報ファイル（違約金情報）．料金コースコード
			// 経過措置違約金情報リスト．料金サービスコード         ＝ 利用料金情報ファイル（違約金情報）．料金サービスコード
			// 経過措置違約金情報リスト．サービス解約理由識別コード ＝ 利用料金情報ファイル（違約金情報）．サービス解約理由
			// 経過措置違約金情報リスト．下限値                     ≦ 利用料金情報ファイル（違約金情報）．継続期間
			// 経過措置違約金情報リスト．上限値                     ≧ 利用料金情報ファイル（違約金情報）．継続期間
			//
			for (JBSbatServiceInterfaceMap keikSochPnltyInfMap: keikSochPnltyInfList)
			{
				if (JCHStringUtil.isNullBlank(keikSochPnltyInfMap.getString(JBSbatAC_M_PNLTY.TRGT_PCRS_CD))
						|| JCHStringUtil.isNullBlank(keikSochPnltyInfMap.getString(JBSbatAC_M_PNLTY.TRGT_PRC_SVC_CD))
						|| JCHStringUtil.isNullBlank(keikSochPnltyInfMap.getString(JBSbatAC_M_PNLTY.SVC_DSL_RSN_SKBT_CD))
						|| JCHStringUtil.isNullBlank(keikSochPnltyInfMap.getString(JBSbatAC_M_PNLTY.LOWL_VALUE))
						|| JCHStringUtil.isNullBlank(keikSochPnltyInfMap.getString(JBSbatAC_M_PNLTY.UPPL_VALUE))
						|| JCHStringUtil.isNullBlank(inMap.getString(JBSbatACIFM357.PCRS_CD))
						|| JCHStringUtil.isNullBlank(inMap.getString(JBSbatACIFM357.PRC_SVC_CD))
						|| JCHStringUtil.isNullBlank(inMap.getString(JBSbatACIFM357.SVC_DLRE))
						|| JCHStringUtil.isNullBlank(inMap.getString(JBSbatACIFM357.KEIZK_PRD)))
				{
					continue;
				}
				if (keikSochPnltyInfMap.getString(JBSbatAC_M_PNLTY.TRGT_PCRS_CD).equals(inMap.getString(JBSbatACIFM357.PCRS_CD))
						&& keikSochPnltyInfMap.getString(JBSbatAC_M_PNLTY.TRGT_PRC_SVC_CD).equals(inMap.getString(JBSbatACIFM357.PRC_SVC_CD))
						&& keikSochPnltyInfMap.getString(JBSbatAC_M_PNLTY.SVC_DSL_RSN_SKBT_CD).equals(inMap.getString(JBSbatACIFM357.SVC_DLRE))
						&& JBSbatStringUtil.rangeCheck(keikSochPnltyInfMap.getString(JBSbatAC_M_PNLTY.UPPL_VALUE),
								keikSochPnltyInfMap.getString(JBSbatAC_M_PNLTY.LOWL_VALUE), inMap.getString(JBSbatACIFM357.KEIZK_PRD), DATA_TYPE_NUM))
				{
					inf = new JBSbatServiceInterfaceMap();
					for (Object key : keikSochPnltyInfMap.getMap().keySet())
					{
						inf.set((String)key, keikSochPnltyInfMap.get((String)key));
					}

					assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][getKeikSochPnltyInf][経過措置違約金情報取得]");

					break;
				}
			}
		}

		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][getKeikSochPnltyInf]");

		return inf;
	}

	/**
	 * 経過措置対象の判定処理
	 * 
	 * @param inMap 利用料金情報ファイル（違約金情報）
	 * @param keikSochPnltyInf 経過措置違約金情報
	 * @return boolean 判定結果
	 * @throws Exception JBSbatServiceInterfaceMapの入出力時の例外
	 */
	private boolean isKeikSochTarget(JBSbatServiceInterfaceMap inMap, JBSbatServiceInterfaceMap keikSochPnltyInf) throws Exception
	{
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][isKeikSochTarget]");

		if (inMap != null && keikSochPnltyInf != null)
		{
			if (!JCHStringUtil.isNullBlank(inMap.getString(JBSbatACIFM357.SVC_STAYMD))
					&& keikSochPnltyInf.get(CHO_WRI_MON_CNT) != null)
			{
				assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][isKeikSochTarget][サービス開始日：" + inMap.getString(JBSbatACIFM357.SVC_STAYMD)
						+ ",長割適用開始月数：" + String.valueOf(keikSochPnltyInf.getInt(CHO_WRI_MON_CNT)) + "]");

				//
				// 下記条件で経過措置対象かを判定
				// 
				// 利用料金情報ファイル（違約金情報）．サービス開始日 ＋ 経過措置違約金情報．長割適用開始月数 ≦ 旧制度満了日
				//
				int choWriMonCnt = keikSochPnltyInf.getInt(CHO_WRI_MON_CNT);
				String judgeYmd = JBSbatDateUtil.adjustMonth(inMap.getString(JBSbatACIFM357.SVC_STAYMD), choWriMonCnt);
				if (judgeYmd.compareTo(kyuseidoEndymd) <= 0)
				{
					assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][isKeikSochTarget][経過措置対象:true"
							+ " ,請求先番号:" + inMap.getString(JBSbatACIFM357.SEIKY_KEI_NO)
							+ " ,請求年月:" + inMap.getString(JBSbatACIFM357.SEIKY_YM)
							+ " ,整理番号:" + inMap.getString(JBSbatACIFM357.SEIRI_NO)
							+ " ,割引サービス契約番号:" + inMap.getString(JBSbatACIFM357.WRIB_SVC_KEI_NO)
							+ " ,割引サービス対象契約番号:" + inMap.getString(JBSbatACIFM357.WRISVC_TRGT_KEI_NO)
							+ " ,オプションサービス契約番号:" + inMap.getString(JBSbatACIFM357.OP_SVKEI_NO)
							+ " ,料金サービス識別コード:" + inMap.getString(JBSbatACIFM357.SVC_SKBT_CD)
							+ " ,料金グループコード:" + inMap.getString(JBSbatACIFM357.PRC_GRP_CD)
							+ " ,料金コースコード:" + inMap.getString(JBSbatACIFM357.PCRS_CD)
							+ " ,料金サービスコード:" + inMap.getString(JBSbatACIFM357.PRC_SVC_CD)
							+ " ,料金項目コード:" + inMap.getString(JBSbatACIFM357.PRC_KMK_CD)
							+ " ,徴収パターンコード:" + inMap.getString(JBSbatACIFM357.COLLECT_PATTERN_CD)
							+ " ,料金:" + String.valueOf(inMap.getBigDecimal(JBSbatACIFM357.PRC))
							+ " ,置換後料金:" + String.valueOf(keikSochPnltyInf.getBigDecimal(JBSbatAC_M_PNLTY.PNLTY_TANKA))+ "]");

					return true;
				}
			}
		}

		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][isKeikSochTarget]");

		return false;
	}

	/**
	 * 出力情報作成処理
	 * 
	 * @param inMap 利用料金情報ファイル（違約金情報）(CHIFM357001)
	 * @param pnltyPrc 違約金
	 * @return JBSbatServiceInterfaceMap 利用料金情報ファイル（違約金情報）(ACIFI016006)
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private JBSbatServiceInterfaceMap makeOutMap(JBSbatServiceInterfaceMap inMap, BigDecimal pnltyPrc) throws Exception
	{
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][makeOutMap]");

		JBSbatServiceInterfaceMap outMap = new JBSbatServiceInterfaceMap();

		for (Object key : inMap.getMap().keySet())
		{
			// 継続期間と料金以外の項目をコピー
			if (!JBSbatACIFM357.KEIZK_PRD.equals(key) && !JBSbatACIFM357.PRC.equals(key))
			{
				outMap.set((String)key, inMap.get((String)key));
			}
		}

		// 料金（違約金）を設定
		outMap.setBigDecimal(JBSbatACIFM357.PRC, pnltyPrc);

		// レコード出力判定フラグの設定
		outMap.setOutFlg(true);

		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][makeOutMap]");

		return outMap;
	}
}
