/*********************************************************************
*  All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JBSbatACTelnoGuideUseChrgInfoTrkmDataChk
*	ソースファイル名	：JBSbatACTelnoGuideUseChrgInfoTrkmDataChk.java
*	作成者				：富士通　
*  日付                ：2024年05月17日
*＜機能概要＞
*　電話番号案内利用課金情報取込データチェック部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*  v71.00.00   2024/05/17  FJ)吉田賢	【ANK-4497-00-00】電話番号案内の課金情報連携変更対応
*  v71.00.00   2024/07/02  FJ)上島      【IT1-2024-0000017】電話番号案内の課金情報連携変更対応
*********************************************************************/
package eo.business.service;

import eo.business.common.JACbatDebugLogUtil;
import eo.business.common.JBSbatBusinessService;
import eo.business.common.JKKBatCommon;
import eo.business.util.file.JBSbatACIFM367;
import eo.business.util.file.JBSbatACIFM368;
import eo.common.constant.JACStrConst;
import eo.common.constant.JKKStrConst;
import eo.common.util.JCHStringUtil;
import eo.common.util.JPCUtilCommon;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.item.JBSbatServiceInterfaceMap;

/**
* 電話番号案内利用課金情報取込フォーマットチェック <p>
*<BR>
* @author 富士通
*/
public class JBSbatACTelnoGuideUseChrgInfoTrkmDataChk extends JBSbatBusinessService
{
	
	// ==============================
	// =====エラーメッセージ情報=====
	// ==============================
	/** エラーメッセージ(電話番号の存在チェック) */
	private final String ERRMSG_TELNO_EXISTS_CHK = "電話番号がマスタに存在しません";
	/** エラーメッセージ(課金対象データの利用タイミングの整合性チェック) */
	private final String ERRMSG_USE_TIMING_CHK = "発側終了日が未来日です";
	/** エラーメッセージ(通話タイミングの重複チェック) */
	private final String ERRMSG_CALL_TIMING_CHK = "発側開始日から発側終了日の時刻が、他のレコードの利用期間と重複しています";
	/** エラーメッセージ(サービス契約番号の存在チェック) */
	// 2024/07/02 IT1-2024-0000017 上島 MOD START
//	private final String ERRMSG_SVC_KEI_EXISTS_CHK = "サービス契約番号が契約に存在しません";
	private final String ERRMSG_SVC_KEI_EXISTS_CHK = "対象の電話番号のサービスが課金できない状態です";
	// 2024/07/02 IT1-2024-0000017 上島 MOD END
	/** エラーメッセージ(サービス契約期間チェック) */
	private final String ERRMSG_SVC_KEI_PERIOD_CHK = "サービス契約期間外の利用です";
	
	// ======================
	// =====共通変数情報=====
	// ======================
	/** 退避：処理電話番号 */
	private String procTelno = JACStrConst.KARA_MOJI;
	/** 退避：発側通話終了年月日時分秒 */
	private String procHashinEndDtm = JACStrConst.KARA_MOJI;
	/** ヘッダ出力済フラグ */
	private boolean exexcOutputHeader = false;
	
	/**
	 * 初期処理
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼*/
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);
		
		// DBアクセスクラスを生成します
		
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][initial]");
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][initial][opeDate=" + super.opeDate + "]");
		
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][initial]");
	/**▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 主処理
	 * @param inMap　入力電文
	 * @return JBSbatOutputItem　出力情報
	 * @throws Exception
	 */
	public JBSbatOutputItem execute(JBSbatServiceInterfaceMap inMap, JBSbatOutputItem outputItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの主処理を記述してください。▼▼▼▼▼▼*/
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][execute]");
		assert inMap != null ? JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][execute][inMap=" + inMap.getMap().toString() + "]"): true;
		
		if(!exexcOutputHeader)
		{
			// エラーファイルにヘッダ情報を出力する
			setOutputMapErrorHeader(inMap, outputItem);
			exexcOutputHeader = true;
		}
		
		// 電話番号の存在チェック
		if(checkExistsTelNo(inMap))
		{
			setOutputMapError(inMap, outputItem, ERRMSG_TELNO_EXISTS_CHK);
			setOutputMapSucsess(inMap, outputItem);
		}
		// 発信者電話番号の法人チェック
		else if(checkTelNoHojin(inMap))
		{
			setOutputMapSucsess(inMap, outputItem);
		}
		// 課金対象データの利用タイミングの整合性チェック
		else if(checkUseTiming(inMap))
		{
			setOutputMapError(inMap, outputItem, ERRMSG_USE_TIMING_CHK);
			// エラーフラグをtrueに設定
			// 2024/07/02 IT1-2024-0000017 上島 DEL START
//			commonItem.setErrFlg(true);
			// 2024/07/02 IT1-2024-0000017 上島 DEL END
		}
		// 通話タイミングの重複チェック
		else if(checkCalTiming(inMap))
		{
			setOutputMapError(inMap, outputItem, ERRMSG_CALL_TIMING_CHK);
			// エラーフラグをtrueに設定
			// 2024/07/02 IT1-2024-0000017 上島 DEL START
//			commonItem.setErrFlg(true);
			// 2024/07/02 IT1-2024-0000017 上島 DEL END
		}
		// サービス契約番号の存在チェック
		else if(checkExistsSvcKeiNo(inMap))
		{
			setOutputMapError(inMap, outputItem, ERRMSG_SVC_KEI_EXISTS_CHK);
			// エラーフラグをtrueに設定
			// 2024/07/02 IT1-2024-0000017 上島 DEL START
//			commonItem.setErrFlg(true);
			// 2024/07/02 IT1-2024-0000017 上島 DEL END
		}
		// サービス契約期間チェック
		else if(checkSvcKeiPeriod(inMap))
		{
			setOutputMapError(inMap, outputItem, ERRMSG_SVC_KEI_PERIOD_CHK);
			// エラーフラグをtrueに設定
			// 2024/07/02 IT1-2024-0000017 上島 DEL START
//			commonItem.setErrFlg(true);
			// 2024/07/02 IT1-2024-0000017 上島 DEL END
		}
		else
		{
			// エラーがない場合は正常終了
			setOutputMapSucsess(inMap, outputItem);
		}
		
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][execute]");
		return outputItem;
	/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}
	
	/**
	 * 電話番号の存在チェックを行います
	 * 
	 * @param inMap
	 * @return
	 * @throws Exception
	 */
	private boolean checkExistsTelNo(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		// 電話番号(DB取得)
		String telno = inMap.getString(JBSbatACIFM368.TELNO);
		
		boolean result = false;
		
		result = JCHStringUtil.isNullBlank(telno);
		
		return result;
	}

	/**
	 * 発信者電話番号の法人チェックを行います
	 * 個人法人番号帯コードがない場合は法人として扱います
	 * 
	 * @param inMap
	 * @return true:法人 false:法人以外
	 * @throws Exception 
	 */
	private boolean checkTelNoHojin(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		// 個人法人電話番号帯コード
		String kojinHojinTlnTaiCd = inMap.getString(JBSbatACIFM368.KOJIN_HOJIN_TLN_TAI_CD);
		
		boolean result = false;
		
		result = !JKKStrConst.CD00410_KOJIN.equals(kojinHojinTlnTaiCd);
		
		return result;
	}

	/**
	 * 課金対象データの利用タイミングの整合性チェックを行います
	 * 
	 * @param inMap
	 * @return
	 */
	private boolean checkUseTiming(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		// 発側終了日
		String hashinEndYmd = inMap.getString(JBSbatACIFM368.HASHIN_END_YMD);
		
		boolean result = false;
		
		if( super.opeDate.compareTo(hashinEndYmd) < 0)
		{
			result = true;
		}
		
		return result;
	}

	/**
	 * 通話タイミングの重複チェックを行います
	 * 
	 * @param inMap
	 * @return
	 */
	private boolean checkCalTiming(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		// 電話番号(取込データ)
		String telno = inMap.getString(JBSbatACIFM368.HASINSHA_TELNO).substring(1);
		// 発側開始日
		String hashinStaYmd = inMap.getString(JBSbatACIFM368.HASHIN_STA_YMD);
		// 発側開始時刻
		String hashinStaTime = inMap.getString(JBSbatACIFM368.HASHIN_STA_TIME);
		// 発側終了日
		String hashinEndYmd = inMap.getString(JBSbatACIFM368.HASHIN_END_YMD);
		// 発側終了時刻
		String hashinEndTime = inMap.getString(JBSbatACIFM368.HASHIN_END_TIME);
		
		boolean result = false;
		
		// 発側開始年月日時分秒
		String hashinStaDtm = hashinStaYmd + hashinStaTime;
		// 2024/07/02 IT1-2024-0000017 上島 DEL START
//		// 発側開始年月日時分秒
//		String hashinEndDtm = hashinEndYmd + hashinEndTime;
		// 2024/07/02 IT1-2024-0000017 上島 DEL END
		
		
		// 処理中の電話番号が、退避した電話番号と異なればチェックしない
		// （電話番号単位の先頭レコードのため、チェックしない）
		if(procTelno.equals(telno))
		{
			// 同じ電話番号の時は、通話タイミングの整合性をチェックする。
			if(hashinStaDtm.compareTo(procHashinEndDtm) <= 0)
			{
				result = true;
			}
		}
		
		// 電話番号退避
		procTelno = telno;
		procHashinEndDtm = hashinEndYmd + hashinEndTime;
		
		return result;
	}

	/**
	 * サービス契約番号の存在チェックを行います
	 * 
	 * @param inMap
	 * @return
	 */
	private boolean checkExistsSvcKeiNo(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		// サービス契約番号
		String svcKeiNo = inMap.getString(JBSbatACIFM368.SVC_KEI_NO);
		
		boolean result = false;
		
		result = JCHStringUtil.isNullBlank(svcKeiNo);
		
		return result;
	}

	/**
	 * サービス契約期間チェックを行います
	 * 
	 * @param inMap
	 * @return
	 */
	private boolean checkSvcKeiPeriod(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		// 2024/07/02 IT1-2024-0000017 上島 MOD START
		// 発側開始日
		//String hashinStaYmd = inMap.getString(JBSbatACIFM368.HASHIN_STA_YMD);
		// 発側終了日
		String hashinEndYmd = inMap.getString(JBSbatACIFM368.HASHIN_END_YMD);
		// 2024/07/02 IT1-2024-0000017 上島 MOD END
		// サービス開始日
		String svcStaYmd    = inMap.getString(JBSbatACIFM368.SVC_STA_YMD);
		// サービス終了日
		String svcEndYmd    = inMap.getString(JBSbatACIFM368.SVC_END_YMD);
		
		boolean result = false;
		
		// サービス開始日／終了日が空ならエラー
		if(JCHStringUtil.isNullBlank(svcStaYmd) || JCHStringUtil.isNullBlank(svcEndYmd))
		{
			return true;
		}
		
		// 2024/07/02 IT1-2024-0000017 上島 MOD START
//		// サービス開始日　＞　発側開始日　または　サービス終了日　＜　発側開始日
//		if(JPCUtilCommon.isFutureDate(svcStaYmd, hashinStaYmd, "0") || JPCUtilCommon.isPastDate(svcEndYmd, hashinStaYmd, "0"))
		// サービス開始日　＞　発側終了日　または　サービス終了日　＜　発側終了日
		if(JPCUtilCommon.isFutureDate(svcStaYmd, hashinEndYmd, "0") || JPCUtilCommon.isPastDate(svcEndYmd, hashinEndYmd, "0"))
		// 2024/07/02 IT1-2024-0000017 上島 MOD END
		
		{
			return true;
		}
		
		return result;
	}

	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][terminal]");
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][terminal]");
	/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}
	
	/**
	 * チェックで正常と判断したデータをファイルに出力します。
	 * 
	 * @param inMap 入力電文
	 * @param outputItem 出力電文
	 * @param value レコード
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private void setOutputMapSucsess(JBSbatServiceInterfaceMap inMap, JBSbatOutputItem outputItem) throws Exception
	{
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][setOutputMapSucsess]");
		
		JBSbatServiceInterfaceMap outMap = new JBSbatServiceInterfaceMap();
		
		// システム年月日時分秒を取得
		String sys_date = JKKBatCommon.getSysDateTimeStamp();
		
		outMap.setString(JBSbatACIFM368.RECODE_KBN				, inMap.getString(JBSbatACIFM368.RECODE_KBN));					// レコード区分
		outMap.setString(JBSbatACIFM368.JIGYOSHA_CD				, inMap.getString(JBSbatACIFM368.JIGYOSHA_CD));					// 事業者コード
		outMap.setString(JBSbatACIFM368.DATA_MAKE_YMD			, inMap.getString(JBSbatACIFM368.DATA_MAKE_YMD));				// データ作成日
		outMap.setString(JBSbatACIFM368.DATA_MAKE_TIME			, inMap.getString(JBSbatACIFM368.DATA_MAKE_TIME));				// データ作成時刻
		outMap.setString(JBSbatACIFM368.RECODE_NO				, inMap.getString(JBSbatACIFM368.RECODE_NO));					// レコード番号
		outMap.setString(JBSbatACIFM368.HASINSHA_TELNO			, inMap.getString(JBSbatACIFM368.HASINSHA_TELNO));				// 発信者電話番号
		outMap.setString(JBSbatACIFM368.INCOMING_TELNO			, inMap.getString(JBSbatACIFM368.INCOMING_TELNO));				// 着信電話番号
		outMap.setString(JBSbatACIFM368.HASHIN_AREA_CD			, inMap.getString(JBSbatACIFM368.HASHIN_AREA_CD));				// 発側エリアコード
		outMap.setString(JBSbatACIFM368.INCOMING_AREA_CD		, inMap.getString(JBSbatACIFM368.INCOMING_AREA_CD));			// 着側エリアコード
		outMap.setString(JBSbatACIFM368.CHRG_CNT				, inMap.getString(JBSbatACIFM368.CHRG_CNT));					// 課金回数
		outMap.setString(JBSbatACIFM368.HASHIN_STA_YMD			, inMap.getString(JBSbatACIFM368.HASHIN_STA_YMD));				// 発側開始日
		outMap.setString(JBSbatACIFM368.HASHIN_STA_TIME			, inMap.getString(JBSbatACIFM368.HASHIN_STA_TIME));				// 発側開始時刻
		outMap.setString(JBSbatACIFM368.HASHIN_END_YMD			, inMap.getString(JBSbatACIFM368.HASHIN_END_YMD));				// 発側終了日
		outMap.setString(JBSbatACIFM368.HASHIN_END_TIME			, inMap.getString(JBSbatACIFM368.HASHIN_END_TIME));				// 発側終了時刻
		outMap.setString(JBSbatACIFM368.INCOMING_STA_YMD		, inMap.getString(JBSbatACIFM368.INCOMING_STA_YMD));			// 着側開始日
		outMap.setString(JBSbatACIFM368.INCOMING_STA_TIME		, inMap.getString(JBSbatACIFM368.INCOMING_STA_TIME));			// 着側開始時刻
		outMap.setString(JBSbatACIFM368.INCOMING_END_YMD		, inMap.getString(JBSbatACIFM368.INCOMING_END_YMD));			// 着側終了日
		outMap.setString(JBSbatACIFM368.INCOMING_END_TIME		, inMap.getString(JBSbatACIFM368.INCOMING_END_TIME));			// 着側終了時刻
		outMap.setString(JBSbatACIFM368.TELNO					, inMap.getString(JBSbatACIFM368.TELNO));						// 電話番号
		outMap.setString(JBSbatACIFM368.SVC_KEI_NO				, inMap.getString(JBSbatACIFM368.SVC_KEI_NO));					// サービス契約
		outMap.setString(JBSbatACIFM368.KOJIN_HOJIN_TLN_TAI_CD	, inMap.getString(JBSbatACIFM368.KOJIN_HOJIN_TLN_TAI_CD));		// 個人法人電話番号帯コード
		outMap.setString(JBSbatACIFM368.SVC_STA_YMD				, inMap.getString(JBSbatACIFM368.SVC_STA_YMD));					// サービス開始日
		outMap.setString(JBSbatACIFM368.SVC_END_YMD				, inMap.getString(JBSbatACIFM368.SVC_END_YMD));					// サービス終了日
		
		// 出力フラグ ← true
		outMap.setOutFlg(true);
		
		outputItem.addOutMapList(outMap);
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][setOutputMapSucsess]");
	}
	
	/**
	 * チェックで異常と判断したデータをファイルに出力します。
	 * 
	 * @param errCd エラーコード
	 * @param errMsg エラー内容
	 * @param outputItem 出力電文
	 * @param seiky_kei_no 請求契約番号
	 * @param receipt_ymd 収納年月日
	 * @param nyukin_amnt 入金額
	 * @param sknksitkcm_cd 債権回収委託会社コード
	 * @param kiji 記事
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private void setOutputMapError(JBSbatServiceInterfaceMap inMap, JBSbatOutputItem outputItem, String errMessage) throws Exception
	{
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][setOutputMapError]");
		JBSbatServiceInterfaceMap errMap = new JBSbatServiceInterfaceMap();
		
		errMap.setString(JBSbatACIFM367.SVC_KEI_NO			, inMap.getString(JBSbatACIFM368.SVC_KEI_NO));						// サービス契約番号
		errMap.setString(JBSbatACIFM367.RECODE_NO			, inMap.getString(JBSbatACIFM368.RECODE_NO));						// レコード番号
		errMap.setString(JBSbatACIFM367.HASINSHA_TELNO		, inMap.getString(JBSbatACIFM368.HASINSHA_TELNO));					// 発信者電話番号
		errMap.setString(JBSbatACIFM367.CHRG_CNT			, inMap.getString(JBSbatACIFM368.CHRG_CNT));						// 課金回数
		errMap.setString(JBSbatACIFM367.HASHIN_STA_YMD		, inMap.getString(JBSbatACIFM368.HASHIN_STA_YMD));					// 発側開始日
		errMap.setString(JBSbatACIFM367.ERR_NAIYO			, errMessage);														// エラー内容
		
		// 出力フラグ ← true
		errMap.setOutFlg(true);
		
		outputItem.addOutMapList_2(errMap);
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][setOutputMapError]");
	}
	
	/**
	 * エラーファイルのヘッダ情報をファイルに出力します。
	 * 
	 * @param errCd エラーコード
	 * @param errMsg エラー内容
	 * @param outputItem 出力電文
	 * @param seiky_kei_no 請求契約番号
	 * @param receipt_ymd 収納年月日
	 * @param nyukin_amnt 入金額
	 * @param sknksitkcm_cd 債権回収委託会社コード
	 * @param kiji 記事
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private void setOutputMapErrorHeader(JBSbatServiceInterfaceMap inMap, JBSbatOutputItem outputItem) throws Exception
	{
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][setOutputMapError]");
		JBSbatServiceInterfaceMap errMap = new JBSbatServiceInterfaceMap();
		
		errMap.setString(JBSbatACIFM367.SVC_KEI_NO			, "サービス契約番号");		// サービス契約番号
		errMap.setString(JBSbatACIFM367.RECODE_NO			, "レコード番号");			// レコード番号
		errMap.setString(JBSbatACIFM367.HASINSHA_TELNO		, "発信者電話番号");		// 発信者電話番号
		errMap.setString(JBSbatACIFM367.CHRG_CNT			, "課金回数");				// 課金回数
		errMap.setString(JBSbatACIFM367.HASHIN_STA_YMD		, "発側開始日");			// 発側開始日
		errMap.setString(JBSbatACIFM367.ERR_NAIYO			, "エラー内容");			// エラー内容
		
		// 出力フラグ ← true
		errMap.setOutFlg(true);
		
		outputItem.addOutMapList_2(errMap);
		
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][setOutputMapError]");
	}

}
