/*********************************************************************
*   All Right reserved,Copyright (c) Fujitsu, 2011
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム構築
*   モジュール名    ：JECH0051D012TPMA
*   ソースファイル名：JECH0051D012TPMA.java
*   作成者          ：富士通
*   日付            ：2011年09月12日
*＜機能概要＞
*   再請求登録顧客独自処理部品
*＜修正履歴＞
*   バージョン  修正日      修正者      修正内容
*   v1.00.00    2011/09/12  富士通      新規作成
*   v5.00.00    2013/11/01  FJ)小野     【OM-2013-0003539】請求書再発行時の動作不具合につき、請求内訳の存在チェックを追加。
*	v8.00.00    2014/02/19  FJ)小野     【ANK-1589-00-00】 消費税に伴う料金施策（増税対応）。
*  v52.00.00    2020/10/15  FJ)三原     【ANK-3838-00-00】窓口払い手数料の顧客負担方式導入
*  v57.00.00	2022/02/25  FJ)西窪	    【ANK-4206-00-00】請求書再発行時の発行回数改善対応
**********************************************************************/

package eo.ejb.cbs.mainproc;

import java.util.HashMap;

import com.fujitsu.futurity.common.JCCWebAddTrnId;
import com.fujitsu.futurity.common.JCMConstants;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANRuntimeException;
import com.fujitsu.futurity.model.base.CAANSQLFacility;
import com.fujitsu.futurity.model.ejb.common.StatusCodes;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;
import com.fujitsu.futurity.model.ejb.common.fw.TemplateMainHandler;

import eo.common.constant.JACStrConst;
import eo.common.util.JCHCommonFormatUtil;
import eo.common.util.JPCDateChecker;
import eo.ejb.cbm.entity.CH0051ETMsg;
import eo.ejb.cbs.cbsmsg.ECH0051D012CBSMsg;
import eo.ejb.cbs.cbsmsg.ECH0051D012CBSMsg1List;
import eo.ejb.common.JCCModelCommon;
import eo.ejb.common.JCHModelCommon;
import eo.ejb.common.db.JCHejbCH0051SecProc;
import eo.ejb.common.db.JCHejbCH0101SecProc;
import eo.ejb.common.entity.JCHejbCH0051KRCK;
import eo.ejb.common.entity.JCHejbCH0101KRCK;
import eo.ejb.common.entity.JCHejbKRCKCommon;

/**
 * <p>
 * 再請求登録顧客独自処理部品
 * </p>
 * @author 富士通
 */
public class JECH0051D012TPMA extends CAANSQLFacility implements TemplateMainHandler{
	
	/** 機能コード1 */
	private static final String FUNC_CD_1 = "1";
	
	/** エラーフラグ(EA) */
	private static final String EA_ERR_FLAG = "EA";
	/** エラーフラグ(EB) */
	private static final String EB_ERR_FLAG = "EB";
	/** エラーフラグ(EC) */
	private static final String EC_ERR_FLAG = "EC";
	
	/** 支払期限年月日指定可能月数(業務パラメータID) */
	private static final String CH_PAY_PSB_MONTH = "CH_PAY_PSB_MONTH";
	/** 取扱期限年月日指定可能日数(業務パラメータID) */
	private static final String CH_TRAT_PSB_DAYS = "CH_TRAT_PSB_DAYS";

	/** 発行種別(請求書の再印刷) */
	private static final String PRINT_DIV_REPRINT = "2";
	
	// ANK-4206-00-00 ADD START
	/**
	 * 請求書再発行画面の画面ID
	 */
	public static final String SCREEN_ID_CHW00106 = "CHW00106";
	/**
	 * 請求書再発行確認画面の画面ID
	 */
	public static final String SCREEN_ID_CHW00107 = "CHW00107";
	// ANK-4206-00-00 ADD END
	
	/**
	 * コンストラクタです。
	 */
	public JECH0051D012TPMA()
	{
		super();
	}
	
	/**
	 * <p>
	 * 再請求登録独自処理を行います。
	 * </p>
	 * 
	 * @param inCBSMsg  処理対象のメッセージキャリア
	 * @param inContext ディスパッチコンテキスト
	 */
	public static void invoke(CAANMsg inCBSMsg, AgentDispatchContext inContext)
	{
		// 請求契約番号が指定されていたら、請求契約番号の存在チェックを行う
		if (!inCBSMsg.isNull(ECH0051D012CBSMsg.SEIKY_KEI_NO))
		{
			// 請求契約番号存在チェック
			if(!JCHejbCH0051KRCK.isExistCurrentSeikyKei(inCBSMsg, inContext, inCBSMsg.getString(ECH0051D012CBSMsg.SEIKY_KEI_NO)))
			{
				// 請求契約番号が存在しない場合、請求契約番号にEAの関連制約エラーフラグを設定する
				inCBSMsg.set(ECH0051D012CBSMsg.STATUS, StatusCodes.RELATION_ERR);
				inCBSMsg.set(ECH0051D012CBSMsg.SEIKY_KEI_NO_ERR, EA_ERR_FLAG);
				return;
			}
		}

		// 請求番号存在チェック
		CAANMsg[] msgCH0051List = inCBSMsg.getCAANMsgList(ECH0051D012CBSMsg.ECH0051D012CBSMSG1LIST);
		
		for (int i = 0; msgCH0051List.length > i; i++)
		{
			if (!JCHejbCH0051KRCK.isExistSeikyNo(inCBSMsg, inContext, 
					msgCH0051List[i].getObject(ECH0051D012CBSMsg1List.SEIKY_YM), msgCH0051List[i].getObject(ECH0051D012CBSMsg1List.SEIKY_NO)))
			{
				// 請求番号が存在しない場合、再請求登録明細にEAの関連制約エラーフラグを設定する
				inCBSMsg.set(ECH0051D012CBSMsg.STATUS, StatusCodes.RELATION_ERR);
				inCBSMsg.set(ECH0051D012CBSMsg.ECH0051D012CBSMSG2LIST_ERR, EA_ERR_FLAG);
				return;
			}
		}

		// 請求内訳存在チェック
		if (!JCHejbCH0101KRCK.isExistSeikyUcwk(inCBSMsg, inContext))
		{
			// 請求内訳が存在しない場合、再請求明細にEAの関連制約エラーフラグを設定する
			inCBSMsg.set(ECH0051D012CBSMsg.STATUS, StatusCodes.RELATION_ERR);
			inCBSMsg.set(ECH0051D012CBSMsg.ECH0051D012CBSMSG1LIST_ERR, EA_ERR_FLAG);
			return;
		}

		// 印刷様式が設定されていた場合、印刷可能かチェックを行う
		if (!inCBSMsg.isNull(ECH0051D012CBSMsg.PRINT))
		{
			// 印刷様式に対する支払方法チェック
			if(!JCHejbCH0051SecProc.isPayWayPossiblePrint(inCBSMsg))
			{
				// 印刷できない場合、印刷様式にEAの関連制約エラーフラグを設定する
				inCBSMsg.set(ECH0051D012CBSMsg.STATUS, StatusCodes.RELATION_ERR);
				inCBSMsg.set(ECH0051D012CBSMsg.PRINT_ERR, EA_ERR_FLAG);
				return;
			}
		}
		
		// 印刷様式が設定されていて、印刷様式が口振領収書のみの場合、口座振替収納実績チェックを行う
		if (!inCBSMsg.isNull(ECH0051D012CBSMsg.PRINT) &&
				JACStrConst.PRINT_YSK_CD_RCPT.equals(inCBSMsg.getString(ECH0051D012CBSMsg.PRINT)))
		{
			// 口振収納実績チェック
			if (!JCHejbCH0051SecProc.isExistSyunoJisseki(inCBSMsg, inContext))
			{
				// リストの項目に一つでも収納実績がない場合、印刷様式にEBの関連制約エラーフラグを設定する
				inCBSMsg.set(ECH0051D012CBSMsg.STATUS, StatusCodes.RELATION_ERR);
				inCBSMsg.set(ECH0051D012CBSMsg.PRINT_ERR, EB_ERR_FLAG);
				return;
			}
		}
		
		// 支払期限年月日、取扱期限年月日についてチェックを実施する
		if (!isLimitDateCheck(inCBSMsg, inContext))
		{
			// チェックでfalseが返却されたらエラー、フラグは内部で設定済み
			return;
		}
		
		// ANK-4206-00-00 ADD START
		
		CAANMsg[] inMsgList = inCBSMsg.getCAANMsgList(ECH0051D012CBSMsg.ECH0051D012CBSMSG1LIST);
		// 請求年月
		String seikyYm = inMsgList[0].getString(ECH0051D012CBSMsg1List.SEIKY_YM);
		// 請求契約番号
		String seikyKeiNo = inCBSMsg.getString(ECH0051D012CBSMsg.SEIKY_KEI_NO);
		// 群番号
		String gunNo = null;
		// 発行シーケンス
		int sksHakkoSeq = 0;
		
		// 共通メッセージからサービス呼び出し元の区分を取得する
		HashMap<String, Object> commonMsg = JCCWebAddTrnId.get(JCMConstants.ADD_TRN_ID_MESSAGE_COMMON_MAP);
		// 呼び出し元画面ID
		String gamenId = (String)commonMsg.get(JCMConstants.INVOKE_GAMEN_ID_KEY);
		// 請求書画面再発行画面からの場合、群番号取得処理を実行
		if(null != gamenId && ((gamenId.startsWith(SCREEN_ID_CHW00106)) || (gamenId.startsWith(SCREEN_ID_CHW00107))))
		{
			
			// 群番号
			gunNo = JCHCommonFormatUtil.getGunNo(seikyKeiNo, seikyYm, JCCModelCommon.getOpeDate(inCBSMsg, null));
			// 発行シーケンス
			sksHakkoSeq = JCHCommonFormatUtil.getSksHakkoSeq(seikyKeiNo, seikyYm, JCCModelCommon.getOpeDate(inCBSMsg, null), "1");
			
			
			// 発番可能な群番号が存在しない場合、エラー
			if(null == gunNo)
			{
				inCBSMsg.set(ECH0051D012CBSMsg.STATUS, StatusCodes.RELATION_ERR);
				inCBSMsg.set(ECH0051D012CBSMsg.SEIKY_KEI_NO_ERR, EB_ERR_FLAG);
				return;
			}
			
		}
		else
		{
			// 発行シーケンス
			sksHakkoSeq = JCHCommonFormatUtil.getSksHakkoSeq(seikyKeiNo, seikyYm, JCCModelCommon.getOpeDate(inCBSMsg, null), "");
		}
		// ANK-4206-00-00 ADD END

		
		// 機能コード1で、印刷様式が口振領収のみ以外、または発行種別が再印刷以外の場合、請求、請求内訳に登録を行う
		if (FUNC_CD_1.equals(inCBSMsg.getString(ECH0051D012CBSMsg.FUNC_CODE))
				&& !JACStrConst.PRINT_YSK_CD_RCPT.equals(inCBSMsg.getString(ECH0051D012CBSMsg.PRINT))
				&& !PRINT_DIV_REPRINT.equals(inCBSMsg.getString(ECH0051D012CBSMsg.PRINT_DIV)))
		{
			// 請求へ登録
			JCHejbCH0051SecProc ch0051sp = new JCHejbCH0051SecProc();
			// ANK-4206-00-00 MOD START
			// ch0051sp.createReSeiky(inCBSMsg, inContext);
			ch0051sp.createReSeiky(inCBSMsg, inContext, gunNo, sksHakkoSeq);
			// ANK-4206-00-00 MOD END
			// 請求内訳へ登録
			JCHejbCH0101SecProc ch0101sp = new JCHejbCH0101SecProc();
			ch0101sp.createReSeikyUcwk(inCBSMsg, inContext);
		}
	}
	
	/**
	 * <p>
	 * 支払期限年月日、取扱期限年月日に関するチェックを行う。
	 * </p>
	 * 
	 * @param inMsg     処理対象のメッセージキャリア
	 * @param inContext ディスパッチコンテキスト
	 * 
	 * @return true:エラーがない
	 *          false:エラーがある
	 */
	private static boolean isLimitDateCheck(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		// 支払期限日が設定されていた場合、支払期限年月日過去日チェックを行う
		if (!inMsg.isNull(ECH0051D012CBSMsg.PAY_KIGEN_YMD))
		{
			// 支払期限年月日過去日チェック
			if(JCHejbKRCKCommon.isPastYmd2(inMsg, inContext, 
					inMsg.getObject(ECH0051D012CBSMsg.PAY_KIGEN_YMD), null, null, null))
			{
				// 支払期限年月日が運用日より過去の場合、支払期限年月日にEAの関連制約エラーフラグを設定する
				inMsg.set(ECH0051D012CBSMsg.STATUS, StatusCodes.RELATION_ERR);
				inMsg.set(ECH0051D012CBSMsg.PAY_KIGEN_YMD_ERR, EA_ERR_FLAG);
				return false;
			}
		}
		
		// 取扱期限年月日が設定されているかチェックを行う
		if (!inMsg.isNull(ECH0051D012CBSMsg.TORI_KIGEN_YMD))
		{
			// 取扱期限年月日過去日チェック
			if(JCHejbKRCKCommon.isPastYmd2(inMsg, inContext, 
					inMsg.getObject(ECH0051D012CBSMsg.TORI_KIGEN_YMD), null, null, null))
			{
				// 取扱期限年月日
				inMsg.set(ECH0051D012CBSMsg.STATUS, StatusCodes.RELATION_ERR);
				inMsg.set(ECH0051D012CBSMsg.TORI_KIGEN_YMD_ERR, EA_ERR_FLAG);
				return false;
			}
		}
		
		// 取扱期限年月日、支払期限年月日が設定されていた場合、チェックを実施する
		if (!inMsg.isNull(ECH0051D012CBSMsg.TORI_KIGEN_YMD)
				&& !inMsg.isNull(ECH0051D012CBSMsg.PAY_KIGEN_YMD))
		{
			// 取扱期限年月日が支払期限年月日より過去でないかチェック
			if (JPCDateChecker.isPastDate(inMsg.getString(ECH0051D012CBSMsg.TORI_KIGEN_YMD), 
					inMsg.getString(ECH0051D012CBSMsg.PAY_KIGEN_YMD), "0"))
			{
				// 取扱期限日が支払期限日より過去の場合、エラー
				inMsg.set(ECH0051D012CBSMsg.STATUS, StatusCodes.RELATION_ERR);
				inMsg.set(ECH0051D012CBSMsg.PAY_KIGEN_YMD_ERR, EB_ERR_FLAG);
				return false;
			}
		}
		
		// 支払期限年月日が指定されていた場合にチェックを行う
		if (!inMsg.isNull(ECH0051D012CBSMsg.PAY_KIGEN_YMD))
		{
			// 支払期限年月日指定可能月数(デフォルト:12)
			int monthCnt = 12;
			
			// 業パラから支払期限年月日指定可能月数を取得する
			String strMonthCnt = JCHModelCommon.getWorkParam(CH_PAY_PSB_MONTH);
			
			if (strMonthCnt != null)
			{
				try
				{
					monthCnt = Integer.parseInt(strMonthCnt);
				}
				catch (NumberFormatException nfe)
				{
					throw new CAANRuntimeException(nfe);
				}
			}
			
			// 指定可能期間内かチェックを行う
			if(JCHejbKRCKCommon.isFutureYmd(inMsg, inContext, 
					inMsg.getObject(ECH0051D012CBSMsg.PAY_KIGEN_YMD), null, monthCnt, null))
			{
				// エラー情報設定
				inMsg.set(ECH0051D012CBSMsg.STATUS, StatusCodes.RELATION_ERR);
				inMsg.set(ECH0051D012CBSMsg.PAY_KIGEN_YMD_ERR, EC_ERR_FLAG);
				return false;
			}
		}

		// ANK-3838-00-00 DEL START
//		// 取扱期限年月日が設定されている場合のみチェックを行う
//		if (!inMsg.isNull(ECH0051D012CBSMsg.TORI_KIGEN_YMD))
//		{
//			// 取扱期限日に２０９９年１２月３１日以降が設定された場合、取扱期限を無期限扱いとするためチェックを行わない。
//			if (JACStrConst.MAX_DATE.compareTo(inMsg.getString(ECH0051D012CBSMsg.TORI_KIGEN_YMD)) <= 0)
//			{
//				return true;
//			}
//		}
		// ANK-3838-00-00 DEL END

		// ANK-3838-00-00 DEL START
		//// 督促ステータスの値によりチェック処理を切替
		//if (JACStrConst.TOKUSOKU_STAT_USE_STOP.compareTo(inMsg.getString(ECH0051D012CBSMsg.TOKUSOKU_STAT)) > 0)
		//{
		//	// 督促ステータスが利用停止済(20)未満の場合
		// ANK-3838-00-00 DEL END
			if (!isTkskStatLessThanUseStopCheck(inMsg, inContext))
			{
				// falseが返却されたエラーが見つかっているのでfalseを返却
				return false;
			}
		// ANK-3838-00-00 DEL START
		//}
		// ANK-3838-00-00 DEL END
		return true;
	}
	
	/**
	 * 督促ステータスが利用停止済(20)未満の場合のチェック処理を行う。
	 * 
	 * @param inMsg     処理対象のメッセージキャリア
	 * @param inContext ディスパッチコンテキスト
	 * 
	 * @return true：エラーがない
	 *          false：エラーがある
	 */
	private static boolean isTkskStatLessThanUseStopCheck(CAANMsg inMsg, AgentDispatchContext inContext)
	{
		// 取扱期限年月日日付範囲チェック
		if (!inMsg.isNull(ECH0051D012CBSMsg.TORI_KIGEN_YMD))
		{
			// 取扱期限年月日指定可能日数(デフォルト:60)
			int dayCnt = 60;
			
			// 業パラから取扱期限年月日指定可能日数を取得する
			String strDayCnt = JCHModelCommon.getWorkParam(CH_TRAT_PSB_DAYS);
			
			if (strDayCnt != null)
			{
				try
				{
					dayCnt = Integer.parseInt(strDayCnt);
				}
				catch (NumberFormatException nfe)
				{
					throw new CAANRuntimeException(nfe);
				}
			}
			
			// 指定可能期間内かチェックを行う
			if(JCHejbKRCKCommon.isFutureYmd(inMsg, inContext, 
					inMsg.getObject(ECH0051D012CBSMsg.TORI_KIGEN_YMD), null, null, dayCnt))
			{
				// エラー情報設定
				inMsg.set(ECH0051D012CBSMsg.STATUS, StatusCodes.RELATION_ERR);
				inMsg.set(ECH0051D012CBSMsg.TORI_KIGEN_YMD_ERR, EB_ERR_FLAG);
				return false;
			}
		}
		return true;
	}
	
}
