/*********************************************************************
 *  All Rights reserved,Copyright (c) K-Opticom
 **********************************************************************
 *＜プログラム内容＞
 *	システム名			：eo顧客基幹システム
 *	モジュール名		：JBSBatCHMineoTkskRlsTgCht
 *	ソースファイル名	：JBSBatCHMineoTkskRlsTgCht.java
 *	作成者				：富士通　
 *	作成日				：2017年02月01日
 *＜機能概要＞
 *　mineo支払方法未登録一括登録データ抽出部品です。
 *＜修正履歴＞
 *	バージョン	修正日		修正者		修正内容
 *  v33.00.00   2017/08/15   FJ)澤田    【ANK-3171-00-00】有効な支払登録なしmineo契約の利用停止・強制解約実施
 *	v41.00.00	2019/02/04	FJ)中野		【ANK-3396-00-00】利用停止スケジュールの変更対応
 *********************************************************************/
package eo.business.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import eo.business.common.JACBatCommon;
import eo.business.common.JACbatDebugLogUtil;
import eo.business.common.JBSbatBusinessService;
import eo.business.common.JCCBatCommon;
import eo.business.common.JKKBatConst;
import eo.business.util.file.JBSbatCHIFE516;
import eo.business.util.file.JBSbatCHIFM274;
import eo.business.util.table.JBSbatCC_T_DLYD_TRN_REQ;
import eo.business.util.table.JBSbatCH_M_PRC_SCHDL_TEIGI;
import eo.business.util.table.JBSbatKK_T_CRECARD;
import eo.business.util.table.JBSbatKK_T_KOZA;
import eo.business.util.table.JBSbatKK_T_SEIKY_KEI;
import eo.business.util.table.JBSbatKK_T_SVC_KEI;
import eo.common.constant.JACStrConst;
import eo.common.constant.JCNStrConst;
import eo.common.util.JKKStringUtil;
import eo.common.util.JZMCommonUtil;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatServiceInterfaceMap;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.item.JBSbatCommonDBInterface;
import eo.framework.db.JBSbatSQLAccess;
import eo.framework.file.JBSbatDefFileUtil;
import eo.framework.file.JBSbatInputFileUtil;
import eo.framework.file.JBSbatOutputFileUtil;
import eo.framework.util.JBSbatAplConst;
import eo.framework.util.JBSbatBusinessFileUtil;
import eo.framework.util.JBSbatDateUtil;

/**
 * (クラスの機能概要) <p>
 *<BR>
 * @author 富士通
 */
public class JBSbatCHmineoPayWayAddChs extends JBSbatBusinessService
{
	/**▼▼▼▼▼▼ツールから生成した宣言です 開始▼▼▼▼▼▼*/
	/** 料金スケジュール管理*/
	private static final String D_TBL_NAME_CH_M_PRC_SCHDL_TEIGI = "CH_M_PRC_SCHDL_TEIGI";
	
	/** ディレイド処理依頼*/
	private static final String D_TBL_NAME_CC_T_DLYD_TRN_REQ = "CC_T_DLYD_TRN_REQ";

	/** テーブル(サービス契約)*/
	private static final String D_TBL_NAME_KK_T_SVC_KEI = "KK_T_SVC_KEI";

	/** SQL定義キー(CH_SELECT_001)*/
	private static final String CC_T_DLYD_TRN_REQ_CH_SELECT_001 = "CH_SELECT_001";

	/** SQL定義キー(CH_SELECT_002)*/
	private static final String KK_T_SVC_KEI_AC_SELECT_040 = "AC_SELECT_040";

	/** SQL定義キー(AC_SELECT_040)*/
	private static final String CH_M_PRC_SCHDL_TEIGI_CH_SELECT_002 = "CH_SELECT_002";
	
	/** テーブルアクセスクラス(ディレイド処理依頼)*/
	private JBSbatSQLAccess db_CC_T_DLYD_TRN_REQ = null;

	/** テーブルアクセスクラス(サービス契約)*/
	private JBSbatSQLAccess db_KK_T_SVC_KEI = null;
	
	/** テーブルアクセスクラス(ディレイド処理依頼)*/
	private JBSbatSQLAccess db_CH_M_PRC_SCHDL_TEIGI = null;
	/**▲▲▲▲▲▲ツールから生成した宣言です 終了▲▲▲▲▲▲*/

	/** 口座ステータス（審査済み）*/
	private static final String KOZA_STATE_SNSZM = "100";

	/** 処理区分 1:利用停止予告 */
	private static final String SYORI_KBN_1 = "1";
	
	/** 処理区分 2:強制解約予告 */
	private static final String SYORI_KBN_2 = "2";
	
	/** 処理区分 3:強制解約 */
	private static final String SYORI_KBN_3 = "3";
	
	/** 出力ファイル定義 */
	private static final String PRM_OTD = "OTD";
	
	/** 結果出力ファイル */
	private JBSbatBusinessFileUtil chifmOutFile = null;

	/** ディレイド処理依頼ステータス 処理済 */
	private static final String DLYD_TRN_REQ_STAT_FIN = "002";

	

	/**
	 * 初期処理
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
		/**▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した初期化のソースです 開始▼▼▼▼▼▼*/
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);

		// DBアクセスクラスを生成します
		db_CC_T_DLYD_TRN_REQ = new JBSbatSQLAccess(commonItem, D_TBL_NAME_CC_T_DLYD_TRN_REQ);
		db_KK_T_SVC_KEI = new JBSbatSQLAccess(commonItem, D_TBL_NAME_KK_T_SVC_KEI);
		db_CH_M_PRC_SCHDL_TEIGI = new JBSbatSQLAccess(commonItem, D_TBL_NAME_CH_M_PRC_SCHDL_TEIGI);
		/**▲▲▲▲▲▲ツールから生成した初期化のソースです 終了▲▲▲▲▲▲*/
		/**▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 主処理
	 * @return JBSbatOutputItem　出力情報
	 * @throws Exception
	 */
	public JBSbatOutputItem execute() throws Exception
	{
		/**▼▼▼▼▼▼業務サービスの主処理を記述してください。▼▼▼▼▼▼*/
		JBSbatDateUtil jbsBatDateUtil = new JBSbatDateUtil();
		// ファイル名などの出力ファイル情報をフリー項目から取得
		String[] outWork = freeItem.split(JKKBatConst.S_PARAM_DELIM);
		
		// mineo支払方法未登録ファイルの出力先パスを取得（スラッシュ付）
		String outFilePath = outWork[0];
		
		// mineo支払方法未登録ファイルの定義を取得
		String outFileDif = outWork[1];
		
		// 処理区分 1:利用停止予告 2:強制解約予告 3:強制解約
		String outSyoriKbn = outWork[2];
		
		// 処理JOBID 
		String outJobId = outWork[3];
		
		// ファイルの生成
		this.chifmOutFile = createFile(outFilePath, outFileDif);
		
		String eventYmd = "";
		// 処理区分 1:利用停止予告
		if (SYORI_KBN_1.equals(outSyoriKbn)) 
		{
			//料金スケジュール定義から請求処理日を取得する。
			executeCH_M_PRC_SCHDL_TEIGI_CH_SELECT_002(new Object[]{getDay(commonItem.getOpeDate(), -2).substring(0, 6), JACStrConst.EVENT_CD_SIKY_TRN_DAY});

			JBSbatCommonDBInterface result = db_CH_M_PRC_SCHDL_TEIGI.selectNext();
			if (result == null)
			{
				return null;
			}
			//請求処理日をセット
			eventYmd = result.getString(JBSbatCH_M_PRC_SCHDL_TEIGI.EVENT_YMD);
			//請求処理日の翌々日をセットする。
			eventYmd = jbsBatDateUtil.adjustDate(eventYmd, 2);
		
		}
		// 処理区分 2:強制解約予告	
		else if (SYORI_KBN_2.equals(outSyoriKbn))
		{
			//昨月の日付19日に固定
			eventYmd = getDay(commonItem.getOpeDate(), -1) + "19";
			//日付19日の翌日をセットする。
			eventYmd = jbsBatDateUtil.adjustDate(eventYmd, 1);
		}
		// 3:強制解約
		else 
		{
			//昨月の月末日を取得
			String endOfMonthDay = jbsBatDateUtil.getEndOfMonth(getDay(commonItem.getOpeDate(), -1));
			
			eventYmd = getDay(commonItem.getOpeDate(), -1) + endOfMonthDay;
			//月末日の翌日をセットする。
			eventYmd = jbsBatDateUtil.adjustDate(eventYmd, 1);
		}
				
		//ディレイド処理依頼から電子ファイルを取得する。
		executeCC_T_DLYD_TRN_REQ_CH_SELECT_001(new Object[]{outJobId, eventYmd, commonItem.getOpeDate()});
		
		JBSbatCommonDBInterface result = db_CC_T_DLYD_TRN_REQ.selectNext();
		//データがない場合、処理終了
		if (result == null)
		{
			return null;
		}
		// ディレイド処理依頼ステータス
		String dlydTrmReqStat = JZMCommonUtil.nullToBlank((String)result.getString(JBSbatCC_T_DLYD_TRN_REQ.DLYD_TRN_REQ_STAT));
		// ディレイド処理結果コード
		String dlydTrnRsltCd = JZMCommonUtil.nullToBlank((String)result.getString(JBSbatCC_T_DLYD_TRN_REQ.DLYD_TRN_RSLT_CD));
		
		//ディレイド処理依頼.ディレイド処理依頼ステータスが"002"（処理済）　かつ　ディレイド処理依頼.ディレイド処理結果コードが"1"（完了）以外の場合
		if (!(DLYD_TRN_REQ_STAT_FIN.equals(dlydTrmReqStat) && JACStrConst.DLYD_TRN_RSLT_CD_FIN.equals(dlydTrnRsltCd)))
		{
			return null;
		}
		
		// 入力ファイルの定義取得
		String inDefFileName = JBSbatAplConst.getAplConstValue("IND") + "CHIFM281.def";
		// 入力電子ファイル管理番号
		String fileKanriNo = (String)result.getString(JBSbatCC_T_DLYD_TRN_REQ.INPUT_EFILE_KANRI_NO);

		// 電子ファイル管理よりコース変更依頼ファイルの復元
		String inFilePath = JCCBatCommon.searchDenshiFile(commonItem, fileKanriNo);
		// ReadFileOpen
		JBSbatInputFileUtil inFileUtil = new JBSbatInputFileUtil(inFilePath);
		JBSbatDefFileUtil inFileDef = new JBSbatDefFileUtil(inDefFileName, inFileUtil);

		// Readerオブジェクトを生成する。
		inFileUtil.createReader();

		// 入力ファイルのレコード件数
		int inFileRecordCnt = 0;

		while (inFileUtil.ready())
		{
			// ファイルから１レコード取得
			String line = inFileUtil.readLine();

			// レコード件数カウント
			inFileRecordCnt++;

			// １レコードの情報をマップに格納
			JBSbatServiceInterfaceMap recordMap = inFileDef.lineToObject(line, inFileUtil, inFileRecordCnt);

			String inputSvcKeiNo =  (String)recordMap.get(JBSbatKK_T_SVC_KEI.SVC_KEI_NO);
			
			//サービス契約からマイネオ情報を取得する。
			executeKK_T_SVC_KEI_AC_SELECT_040(new Object[]{inputSvcKeiNo, commonItem.getOpeDate(),
					commonItem.getOpeDate(), commonItem.getOpeDate(), commonItem.getOpeDate()});

			//
			JBSbatCommonDBInterface resultMineoInfo = db_KK_T_SVC_KEI.selectNext();
			//対象のレコードが存在しない場合
			if (resultMineoInfo == null)
			{
				//次の処理へ
				continue;
			}
			
			// サービス契約ステータス
			String svcKeiStat = JZMCommonUtil.nullToBlank((String)resultMineoInfo.getString(JBSbatKK_T_SVC_KEI.SVC_KEI_STAT));
			// 請求方法コード
			String seikyWayCd = JZMCommonUtil.nullToBlank((String)resultMineoInfo.getString(JBSbatKK_T_SEIKY_KEI.SEIKY_WAY_CD));
			// 口座ステータス
			String kozaStat = JZMCommonUtil.nullToBlank((String)resultMineoInfo.getString(JBSbatKK_T_KOZA.KOZA_STAT));
			// クレジットカード無効年月
			String crecaMkYm = JZMCommonUtil.nullToBlank((String)resultMineoInfo.getString(JBSbatKK_T_CRECARD.CRECA_MK_YM));			
			
			// 処理区分 1:利用停止予告 2:強制解約予告	
			if (SYORI_KBN_1.equals(outSyoriKbn) || SYORI_KBN_2.equals(outSyoriKbn)) 
			{
				//サービス契約ステータスが照査・締結・サービス提供中以外の場合
				if (!(svcKeiStat.equals(JACStrConst.SVC_KEI_STAT_SYOSA) || 
						svcKeiStat.equals(JACStrConst.SVC_KEI_STAT_TIKT) || 
							svcKeiStat.equals(JACStrConst.SVC_KEI_STAT_SVCTK))) 
				{
					//次の処理へ
					continue;
				}
			}
			// 3:強制解約
			else 
			{
				//サービス契約ステータスが利用停止中以外の場合
				if (!(svcKeiStat.equals(JACStrConst.SVC_KEI_STAT_STP)))
				{
					//次の処理へ
					continue;
				}
			}
			
			//支払方法の状態チェック
			
			//請求方法が窓口払いの場合
			if (JACStrConst.SEIKY_MADOGUCHI.equals(seikyWayCd)) 
			{
				//ファイル出力を行う
				outRecCHIFM(resultMineoInfo, outSyoriKbn);
			}
			//請求方法が預金口座振替・郵便自動振替の場合
			else if (JACStrConst.SEIKY_KHRI.equals(seikyWayCd) || JACStrConst.SEIKY_YUFUIRI.equals(seikyWayCd))
			{
				//口座ステータスが100:審査済以外の場合
				if (!KOZA_STATE_SNSZM.equals(kozaStat)) 
				{
					//ファイル出力を行う
					outRecCHIFM(resultMineoInfo, outSyoriKbn);
				}
			}
			//請求方法がクレジットの場合
			else if (JACStrConst.SEIKY_CREDIT.equals(seikyWayCd))
			{
				//クレジットカード無効年月日が設定されている場合
				if(!JKKStringUtil.isNullBlank(crecaMkYm))
				{
					//ファイル出力を行う
					outRecCHIFM(resultMineoInfo, outSyoriKbn);
				}
			}
		}

		return null;
		/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}
	
	/**
	 * ファイル生成
	 * 
	 * @param  filePath  ファイルパス＋ファイル名
	 * @param  fileDef   ファイル定義
	 * @return fileUtil  ファイルインスタンス
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private JBSbatBusinessFileUtil createFile(String filePath, String fileDef) throws Exception 
	{
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][createFile]");

		JBSbatOutputFileUtil dataFile 		= new JBSbatOutputFileUtil(filePath);
		String tempFileDefPath 				= JBSbatAplConst.getAplConstValue(PRM_OTD) + fileDef;
		JBSbatDefFileUtil trailerFileDef 	= new JBSbatDefFileUtil(tempFileDefPath, dataFile);
		
		// ファイルの生成
		JBSbatBusinessFileUtil fileUtil = JCCBatCommon.createBusinessFileUtil(filePath
																			, dataFile.getEncode()
																			, JACBatCommon.chgKaigyo(dataFile.getLine())
																			, trailerFileDef.getDelimiter());	
		
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][createFile]");
		return fileUtil;
	}

	/**
	 * mineo支払方法未登録ファイル の出力を行います。
	 * 
	 * @param inMap
	 * @param outSyoriKbn
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private void outRecCHIFM(JBSbatCommonDBInterface inMap, String outSyoriKbn) throws Exception
	{		
		ArrayList<Object> dataList = new ArrayList<Object>();
		
		//CHIFM274
		if (SYORI_KBN_1.equals(outSyoriKbn) || SYORI_KBN_2.equals(outSyoriKbn)) 
		{
			//督促番号
			dataList.add("");
			//サービス契約番号
			dataList.add(inMap.getString(JBSbatCHIFM274.SVC_KEI_NO));
			//mineo督促理由コード
			dataList.add("02");
			//請求契約番号
			dataList.add(inMap.getString(JBSbatCHIFM274.SEIKY_KEI_NO));
			// ANK-3396-00-00 ADD START
			//早期利用停止フラグ 0:対象外
			dataList.add("0");
			// ANK-3396-00-00 ADD END
		}
		//CHIFE516
		else
		{
			//サービス契約番号
			dataList.add(inMap.getString(JBSbatCHIFE516.SVC_KEI_NO));
			//強制解約理由区分
			dataList.add("01");
			// ANK-3396-00-00 ADD START
			//早期利用停止フラグ 0:対象外
			dataList.add("0");
			// ANK-3396-00-00 ADD END
		}
		
		JCCBatCommon.printBusinessFileUtil(this.chifmOutFile, dataList);
	}

	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
		/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼*/
		// ファイルクローズ
		JCCBatCommon.closeBusinessFileUtil(this.chifmOutFile);
		// DBアクセスクラスをクローズします
		db_CC_T_DLYD_TRN_REQ.close();
		db_KK_T_SVC_KEI.close();
		db_CH_M_PRC_SCHDL_TEIGI.close();
		/**▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲*/
		/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}
	
	/**▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼*/
	
	/**
	 * SQLKEY(CH_SELECT_002)でDBアクセスを行います。<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.引数でバイント変数を設定します。<br>
	 *
	 * 2.DBアクセスを実行します。<br>
	 * 
	 * 3.メソッドの呼び出し方です。<br>
	 *		引数:
	 *		param:順にバイント変数の値をparam配列に入れます。バイント変数は以下に説明します。
	 *		 	SEIKY_WAY_NO_KOZA 
	 * </pre>
	 * <p>
	 * @param param バイント変数の値配列。
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void executeCH_M_PRC_SCHDL_TEIGI_CH_SELECT_002(Object[] param) throws Exception
	{
		// バイント変数のリストを生成します
		JBSbatCommonDBInterface paramList = new JBSbatCommonDBInterface();
		paramList.setValue(param[0].toString());
		paramList.setValue(param[1].toString());

		// DBアクセスを実行します
		db_CH_M_PRC_SCHDL_TEIGI.selectBySqlDefine(paramList, CH_M_PRC_SCHDL_TEIGI_CH_SELECT_002);
	}

	/**▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼*/
	
	/**
	 * SQLKEY(CH_SELECT_001)でDBアクセスを行います。<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.引数でバイント変数を設定します。<br>
	 *
	 * 2.DBアクセスを実行します。<br>
	 * 
	 * 3.メソッドの呼び出し方です。<br>
	 *		引数:
	 *		param:順にバイント変数の値をparam配列に入れます。バイント変数は以下に説明します。
	 *		 	SEIKY_WAY_NO_KOZA 
	 * </pre>
	 * <p>
	 * @param param バイント変数の値配列。
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void executeCC_T_DLYD_TRN_REQ_CH_SELECT_001(Object[] param) throws Exception
	{
		// バイント変数のリストを生成します
		JBSbatCommonDBInterface paramList = new JBSbatCommonDBInterface();
		paramList.setValue(param[0].toString());
		paramList.setValue(param[1].toString() + JCNStrConst.ZEROPAD_TIMESTAMP);
		paramList.setValue(param[2].toString() + JCNStrConst.CN_235959_TIMESTAMP);

		// DBアクセスを実行します
		db_CC_T_DLYD_TRN_REQ.selectBySqlDefine(paramList, CC_T_DLYD_TRN_REQ_CH_SELECT_001);
	}

	/**
	 * SQLKEY(CH_SELECT_008)でDBアクセスを行います。<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.引数でバイント変数を設定します。<br>
	 *
	 * 2.DBアクセスを実行します。<br>
	 * 
	 * 3.メソッドの呼び出し方です。<br>
	 *		引数:
	 *		param:順にバイント変数の値をparam配列に入れます。バイント変数は以下に説明します。
	 *		 	SEIKY_WAY_NO_CRECARD
	 * </pre>
	 * <p>
	 * @param param バイント変数の値配列。
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void executeKK_T_SVC_KEI_AC_SELECT_040(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());
		paramList.setValue(param[4].toString());

		// DBアクセスを実行します
		db_KK_T_SVC_KEI.selectBySqlDefine(paramList, KK_T_SVC_KEI_AC_SELECT_040);
	}
	
	/**
	 * 請求月の加減値を返す
	 * @param unyoYmd 運用日付YMD
	 * @param num 加減値
	 * @return String 加減された請求月
	 */
	private String getDay(String unyoYmd, int num)
	{
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, Integer.parseInt(unyoYmd.substring(0, 4)));
		cal.set(Calendar.MONTH, Integer.parseInt(unyoYmd.substring(4, 6)) - 1);
		cal.set(Calendar.DAY_OF_MONTH, 1);

		// 前々月
		cal.add(Calendar.MONTH, num);

		Date date = cal.getTime();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");

		return sdf.format(date);
	}
	/**▲▲▲▲▲▲ツールから生成したメソッドです 終了▲▲▲▲▲▲*/
}
