/*********************************************************************
*  All Rights reserved,Copyright (c) K-Opticom						 *
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JBSbatACEMKeiFailJdg
*	ソースファイル名	：JBSbatACEMKeiFailJdg.java
*	作成者				：富士通　
*	作成日				：2011年05月24日
*＜機能概要＞
*　ＥＭ契約解除料金回収不能判定部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/05/24   富士通		新規作成
*********************************************************************/
package eo.business.service;

import java.util.ArrayList;
import java.util.HashMap;

import eo.business.common.JBSbatBusinessService;
import eo.business.util.file.JBSbatACIFM002;
import eo.business.util.table.JBSbatCH_T_SAIKEN;
import eo.business.util.table.JBSbatCH_T_TOKUSOKU;
import eo.business.util.table.JBSbatZM_M_WORK_PARAM_KNRI;
import eo.common.constant.JPCBatchMessageConstant;
import eo.framework.application.JBSbatBusinessException;
import eo.framework.db.JBSbatSQLAccess;
import eo.framework.item.JBSbatCommonDBInterface;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.item.JBSbatServiceInterfaceMap;
import eo.framework.util.JBSbatCheckUtil;

/**
* (クラスの機能概要) <p>
*<BR>
* @author 富士通
*/
public class JBSbatACEMKeiFailJdg extends JBSbatBusinessService
{
	/**▼▼▼▼▼▼ツールから生成した宣言です 開始▼▼▼▼▼▼*/
	/** テーブル(業務パラメータ管理)*/
	private static final String D_TBL_NAME_ZM_M_WORK_PARAM_KNRI = "ZM_M_WORK_PARAM_KNRI";

	/** テーブル(債権)*/
	private static final String D_TBL_NAME_CH_T_SAIKEN = "CH_T_SAIKEN";

	/** SQL定義キー(AC_SELECT_001)*/
	private static final String ZM_M_WORK_PARAM_KNRI_AC_SELECT_001 = "AC_SELECT_001";

	/** SQL定義キー(AC_SELECT_001)*/
	private static final String CH_T_SAIKEN_AC_SELECT_001 = "AC_SELECT_001";

	/** テーブルアクセスクラス(業務パラメータ管理)*/
	private JBSbatSQLAccess db_ZM_M_WORK_PARAM_KNRI = null;

	/** テーブルアクセスクラス(債権)*/
	private JBSbatSQLAccess db_CH_T_SAIKEN = null;
	/**▲▲▲▲▲▲ツールから生成した宣言です 終了▲▲▲▲▲▲*/

	/** 債権ステータス（収納済み） */
	private static final String SAIKEN_STAT_SHUNOZM = "050";

	/** 出力なし */
	private static final int KAISYU_FLAG_NO_OUTPUT = 0;

	/** 回収不能 */
	private static final int KAISYU_FLAG_FAIL = 1;

	/** 回収可能 */
	private static final int KAISYU_FLAG_PSB = 2;

	/** 単項目チェック項目マップ */
	private HashMap<String, String> singleChkKmkMap = null;

	/** パラメータ：督促ステータス */
	private ArrayList<String> paramTokusokuStat = null;

	/**
	 * 初期処理
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した初期化のソースです 開始▼▼▼▼▼▼*/
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);

		// DBアクセスクラスを生成します
		db_ZM_M_WORK_PARAM_KNRI = new JBSbatSQLAccess(commonItem, D_TBL_NAME_ZM_M_WORK_PARAM_KNRI);
		db_CH_T_SAIKEN = new JBSbatSQLAccess(commonItem, D_TBL_NAME_CH_T_SAIKEN);
		/**▲▲▲▲▲▲ツールから生成した初期化のソースです 終了▲▲▲▲▲▲*/

		// 業務パラメータから回収不能対象の督促ステータスを取得
		getTokusokuStat();

		// 単項目チェック用Map生成
		singleChkKmkMap = new HashMap<String, String>();
		singleChkKmkMap.put("TXT-ACIFM002-INF1.SEIKY_SK_NO", "ＥＭ利用料金情報.請求先番号");
		singleChkKmkMap.put("TXT-ACIFM002-INF1.SEIKY_YM", "ＥＭ利用料金情報.請求年月");
		/**▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 主処理
	 * @param inMap　入力電文
	 * @return JBSbatOutputItem　出力情報
	 * @throws Exception
	 */
	public JBSbatOutputItem execute(JBSbatServiceInterfaceMap inMap) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの主処理を記述してください。▼▼▼▼▼▼*/
		// 単項目チェック
		if (!isSingleCheckACIFM002_INF1(inMap.getMap(), singleChkKmkMap))
		{
			return null;		// TODO:単項目チェックエラーの場合の処理を確認
		}

		// 請求先番号
		String seikyNo = inMap.getString(JBSbatACIFM002.SEIKY_SK_NO);

		// 請求年月
		String seikyYm = inMap.getString(JBSbatACIFM002.SEIKY_YM);

		// 出力共通電文オブジェクト生成
		JBSbatOutputItem outputBean = new JBSbatOutputItem();

		// 回収不能状況の判定
		switch (jdgKaishuFail(seikyNo, seikyYm))
		{
		case KAISYU_FLAG_NO_OUTPUT:		// 出力なし
			return null;

		case KAISYU_FLAG_FAIL:			// 回収不能
			outputBean.addOutMapList(setFileMap(inMap));
			break;

		case KAISYU_FLAG_PSB:			// 回収可能（累積分へ出力）
			outputBean.addOutMapList_2(setFileMap(inMap));
			break;

		default:
			break;

		}
		return null;
	/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼*/
		// DBアクセスクラスをクローズします
		db_ZM_M_WORK_PARAM_KNRI.close();
		db_CH_T_SAIKEN.close();
		/**▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲*/
	/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}

	/**▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼*/

	/**
	 *入力情報（ＥＭ利用料金情報）の単項目チェックを行います。<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.単項目チェックを行います。<br>
	 * 
	 * 2.メソッドの呼び出し方です。<br>
	 *		引数:
	 *		rsMap:(項目、値)を(key、value)として、データをrsMapに入れます
	 *		itemvalueMap:埋め込み文字の値をitemvalueMapに入れます。キーの値は、以下に説明します。
	 *			 TXT-ACIFM002-INF1.SEIKY_SK_NO			ＥＭ利用料金情報.請求先番号
	 *			 TXT-ACIFM002-INF1.SEIKY_SK_NO			ＥＭ利用料金情報.請求先番号
	 *			 TXT-ACIFM002-INF1.SEIKY_SK_NO			ＥＭ利用料金情報.請求先番号
	 *			 TXT-ACIFM002-INF1.SEIKY_YM			ＥＭ利用料金情報.請求年月
	 *			 TXT-ACIFM002-INF1.SEIKY_YM			ＥＭ利用料金情報.請求年月
	 *			 TXT-ACIFM002-INF1.SEIKY_YM			ＥＭ利用料金情報.請求年月
	 * </pre>
	 * <p>
	 * @param rsMap 入力データ（TXT又はDB）を格納されたHashMap。
	 * @param itemvalueMap エラーメッセージに関する項目値を格納されたHashMap。
	 * @return  boolean trueである場合、エラーがありません。falseである場合、エラーを発生しました。
	 */
	private boolean isSingleCheckACIFM002_INF1(HashMap rsMap, HashMap itemvalueMap)
	{
		// 単項目チェックを行います
		String strValue = null;

		// 請求先番号項目チェック
		strValue = (String)rsMap.get("SEIKY_SK_NO");
		// 必須チェック
		if(strValue == null || "".equals(strValue))
		{
			commonItem.getLogPrint().printBusinessErrorLog("EACB0450CE", new String[]{
															(String)itemvalueMap.get("TXT-ACIFM002-INF1.SEIKY_SK_NO")});
			return false;
		}
		// 桁数チェック
		if(!JBSbatCheckUtil.invoke(strValue, new String[]{"ketasuu2", "0", "12"}))
		{
			commonItem.getLogPrint().printBusinessErrorLog("EACB0470CE", new String[]{
															(String)itemvalueMap.get("TXT-ACIFM002-INF1.SEIKY_SK_NO")});
			return false;
		}
		// 属性チェック
		if(!JBSbatCheckUtil.invoke(strValue, new String[]{"hannkakuesuuji1"}))
		{
			commonItem.getLogPrint().printBusinessErrorLog("EACB0460CE", new String[]{
															(String)itemvalueMap.get("TXT-ACIFM002-INF1.SEIKY_SK_NO")});
			return false;
		}

		// 請求年月項目チェック
		strValue = (String)rsMap.get("SEIKY_YM");
		// 必須チェック
		if(strValue == null || "".equals(strValue))
		{
			commonItem.getLogPrint().printBusinessErrorLog("EACB0450CE", new String[]{
															(String)itemvalueMap.get("TXT-ACIFM002-INF1.SEIKY_YM")});
			return false;
		}
		// 桁数チェック
		if(!JBSbatCheckUtil.invoke(strValue, new String[]{"ketasuu2", "0", "6"}))
		{
			commonItem.getLogPrint().printBusinessErrorLog("EACB0470CE", new String[]{
															(String)itemvalueMap.get("TXT-ACIFM002-INF1.SEIKY_YM")});
			return false;
		}
		// 属性チェック
		if(!JBSbatCheckUtil.invoke(strValue, new String[]{"year_month1"}))
		{
			commonItem.getLogPrint().printBusinessErrorLog("EACB0460CE", new String[]{
															(String)itemvalueMap.get("TXT-ACIFM002-INF1.SEIKY_YM")});
			return false;
		}

		return true;
	}

	/**
	 * SQLKEY(AC_SELECT_001)でDBアクセスを行います。<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.引数でバイント変数を設定します。<br>
	 *
	 * 2.DBアクセスを実行します。<br>
	 * 
	 * 3.メソッドの呼び出し方です。<br>
	 *		引数:
	 *		param:順にバイント変数の値をparam配列に入れます。バイント変数は以下に説明します。
	 *		 	業務パラメータID
	 *		 	業務パラメータ適用開始年月日
	 *		 	業務パラメータ適用終了年月日
	 * </pre>
	 * <p>
	 * @param param バイント変数の値配列。
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void executeZM_M_WORK_PARAM_KNRI_AC_SELECT_001(Object[] param) throws Exception
	{
		// バイント変数のリストを生成します
		JBSbatCommonDBInterface paramList = new JBSbatCommonDBInterface();
		paramList.setValue(param[0].toString());
		paramList.setValue(param[1].toString());
		paramList.setValue(param[2].toString());

		// DBアクセスを実行します
		db_ZM_M_WORK_PARAM_KNRI.selectBySqlDefine(paramList, ZM_M_WORK_PARAM_KNRI_AC_SELECT_001);
	}

	/**
	 * SQLKEY(AC_SELECT_001)でDBアクセスを行います。<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.引数でバイント変数を設定します。<br>
	 *
	 * 2.DBアクセスを実行します。<br>
	 * 
	 * 3.メソッドの呼び出し方です。<br>
	 *		引数:
	 *		param:順にバイント変数の値をparam配列に入れます。バイント変数は以下に説明します。
	 *		 	債権．請求契約番号
	 *		 	債権．債権確定年月
	 *		 	督促.督促管理開始年月日
	 *		 	督促.督促管理終了年月日
	 * </pre>
	 * <p>
	 * @param param バイント変数の値配列。
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void executeCH_T_SAIKEN_AC_SELECT_001(Object[] param) throws Exception
	{
		// バイント変数のリストを生成します
		JBSbatCommonDBInterface paramList = new JBSbatCommonDBInterface();
		paramList.setValue(param[0].toString());
		paramList.setValue(param[1].toString());
		paramList.setValue(param[2].toString());
		paramList.setValue(param[3].toString());

		// DBアクセスを実行します
		db_CH_T_SAIKEN.selectBySqlDefine(paramList, CH_T_SAIKEN_AC_SELECT_001);
	}
	/**▲▲▲▲▲▲ツールから生成したメソッドです 終了▲▲▲▲▲▲*/

	/**
	 * 業務パラメータから回収不能対象の督促ステータスを取得
	 * @throws Exception
	 */
	private void getTokusokuStat() throws Exception
	{
		paramTokusokuStat = new ArrayList<String>();

		executeZM_M_WORK_PARAM_KNRI_AC_SELECT_001(new Object[] {"WORKPARAM", super.opeDate, super.opeDate});	// TODO:業務パラメータIDを確定すること
		JBSbatCommonDBInterface record = db_ZM_M_WORK_PARAM_KNRI.selectNext();
		if (record == null)
		{
			// 業務パラメータ管理テーブルから取得できない場合はエラーとする
			throw new JBSbatBusinessException(JPCBatchMessageConstant.EACB0440CE,
					new String[] { JBSbatZM_M_WORK_PARAM_KNRI.TABLE_NAME });
		}

		// 設定値の取得
		String workSetteValue = record.getString(JBSbatZM_M_WORK_PARAM_KNRI.WORK_PARAM_SETTE_VALUE);

		// 設定値を「;」で分割し、ArrayListへ格納する
		String[] tokusokuStatAry = workSetteValue.split(";");
		for (String tokusokuStat : tokusokuStatAry)
		{
			paramTokusokuStat.add(tokusokuStat);
		}
	}

	/**
	 * 
	 * @param seikyNo
	 * @param seikyYm
	 * @return	boolean	:0=出力しない、1=回収不能、2=回収可能
	 * @throws Exception
	 */
	private int jdgKaishuFail(String seikyNo, String seikyYm) throws Exception
	{
		executeCH_T_SAIKEN_AC_SELECT_001(new Object[] {seikyNo, seikyYm, super.opeDate, super.opeDate});
		JBSbatCommonDBInterface record = db_CH_T_SAIKEN.selectNext();
		if (record == null)
		{
			// TODO:回収状況の取得に失敗した場合の処理を確認すること
			return KAISYU_FLAG_FAIL;
		}

		// 債権ステータス
		String saikenStat = record.getString(JBSbatCH_T_SAIKEN.SAIKEN_STAT);

		// 収納済みの場合は出力しない
		if (SAIKEN_STAT_SHUNOZM.equals(saikenStat))
		{
			return KAISYU_FLAG_NO_OUTPUT;
		}

		// 督促ステータス
		String tokusokuStat = record.getString(JBSbatCH_T_TOKUSOKU.TOKUSOKU_STAT);

		// 回収不能対象の督促ステータスの場合は回収不能
		if (paramTokusokuStat.contains(tokusokuStat))
		{
			return KAISYU_FLAG_FAIL;
		}

		// 回収可能
		return KAISYU_FLAG_PSB;
	}
	
	/**
	 * EM利用料金情報(契約解除料金)回収不能分・累積分の出力項目を設定する
	 * @param inMap　入力電文
	 * @return JBSbatServiceInterfaceMap	出力電文
	 * @throws Exception
	 */
	private JBSbatServiceInterfaceMap setFileMap(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		JBSbatServiceInterfaceMap retMap = new JBSbatServiceInterfaceMap();

		// 請求先番号
		retMap.set(JBSbatACIFM002.SEIKY_SK_NO, inMap.get(JBSbatACIFM002.SEIKY_SK_NO));

		// 請求年月
		retMap.set(JBSbatACIFM002.SEIKY_YM, inMap.get(JBSbatACIFM002.SEIKY_YM));

		// 統合請求先番号
		retMap.set(JBSbatACIFM002.TOGO_SEIKY_CK_NO, inMap.get(JBSbatACIFM002.TOGO_SEIKY_CK_NO));

		// 割引グループ番号
		retMap.set(JBSbatACIFM002.WRIB_GRP_NO, inMap.get(JBSbatACIFM002.WRIB_GRP_NO));

		// 割引サービス契約番号
		retMap.set(JBSbatACIFM002.WRIBSVK_NO, inMap.get(JBSbatACIFM002.WRIBSVK_NO));

		// 割引サービス対象契約番号
		retMap.set(JBSbatACIFM002.WRISVC_TG_KEI_NO, inMap.get(JBSbatACIFM002.WRISVC_TG_KEI_NO));

		// サービス番号
		retMap.set(JBSbatACIFM002.SVC_NO, inMap.get(JBSbatACIFM002.SVC_NO));

		// サービス識別
		retMap.set(JBSbatACIFM002.SVC_SKBT, inMap.get(JBSbatACIFM002.SVC_SKBT));

		// 料金コースコード
		retMap.set(JBSbatACIFM002.PCRS_CD, inMap.get(JBSbatACIFM002.PCRS_CD));

		// 料金サービスコード
		retMap.set(JBSbatACIFM002.PRC_SVC_CD, inMap.get(JBSbatACIFM002.PRC_SVC_CD));

		// 料金項目コード
		retMap.set(JBSbatACIFM002.PRC_KMK_CD, inMap.get(JBSbatACIFM002.PRC_KMK_CD));

		// 徴収パターンコード
		retMap.set(JBSbatACIFM002.COLLECT_PTN_CD, inMap.get(JBSbatACIFM002.COLLECT_PTN_CD));

		// 料金
		retMap.set(JBSbatACIFM002.PRC, inMap.get(JBSbatACIFM002.PRC));

		// 利用開始日
		retMap.set(JBSbatACIFM002.USE_STAYMD, inMap.get(JBSbatACIFM002.USE_STAYMD));

		// 利用終了日
		retMap.set(JBSbatACIFM002.USE_END_DAY, inMap.get(JBSbatACIFM002.USE_END_DAY));

		// サービス開始日
		retMap.set(JBSbatACIFM002.SVC_STAYMD, inMap.get(JBSbatACIFM002.SVC_STAYMD));

		// 初回課金開始日
		retMap.set(JBSbatACIFM002.FIRST_CHRG_STAYMD, inMap.get(JBSbatACIFM002.FIRST_CHRG_STAYMD));

		// サービス解約日
		retMap.set(JBSbatACIFM002.SVC_DSL_DAY, inMap.get(JBSbatACIFM002.SVC_DSL_DAY));

		// サービス解約理由
		retMap.set(JBSbatACIFM002.SVC_DLRE, inMap.get(JBSbatACIFM002.SVC_DLRE));

		// サービス回復日
		retMap.set(JBSbatACIFM002.SVC_KAIHK_DAY, inMap.get(JBSbatACIFM002.SVC_KAIHK_DAY));

		// 利用日数
		retMap.set(JBSbatACIFM002.USE_DAY_CNT, inMap.get(JBSbatACIFM002.USE_DAY_CNT));

		// 利用不可日数
		retMap.set(JBSbatACIFM002.USE_FAIL_DAY_CNT, inMap.get(JBSbatACIFM002.USE_FAIL_DAY_CNT));

		// 相対区分
		retMap.set(JBSbatACIFM002.AITAI_DIV, inMap.get(JBSbatACIFM002.AITAI_DIV));

		// 締め日
		retMap.set(JBSbatACIFM002.SHIME_DAY, inMap.get(JBSbatACIFM002.SHIME_DAY));

		retMap.setOutFlg(true);

		return retMap;
	}
}
