/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：FUW10901SFLogic
*	ソースファイル名：FUW10901SFLogic.java
*	作成者			：富士通
*	日付			：2013年02月08日
*＜機能概要＞
*	登録証照会のビューロジッククラスです。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v5.00		2013/02/08	FJ)西村 	新規作成
*	v7.00		2014/02/19	FJ)畑中 	【ANK-1914-00-00】LaLaCall通話明細について
*	v8.00		2014/03/15	FJ)谷本 	【ANK-1585-01-00】【案件内部仕様変更】L2-MVNO対応(LC複数契約対応)
*	v8.00		2014/04/14	FJ)谷本 	【ANK-2108-00-00】【ＮＯ．１４７５】【LCstep2】通話明細旧URLのパラメータ無し対応
*	v48.00.00	2020/02/26	FJ)吉田 	【OM-2020-000204】通話明細の通話時間が24時間周期で時間表示が0に戻る
*	v54.00.00	2021/08/31	FJ)西川 	【ANK-4132-00-00】高リスク情報表示Web画面の2段階認証チェック機能追加
*
**********************************************************************/
package eo.web.webview.FUW10901SF;

import static com.fujitsu.futurity.web.x31.X31SWebLog.DEBUG_LOG;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import com.fujitsu.futurity.web.x00.JCCBusinessException;
import com.fujitsu.futurity.web.x00.JCCWebServiceException;
import com.fujitsu.futurity.web.x31.X31CWebConst;
import com.fujitsu.futurity.web.x31.X31SDataBeanAccess;
import com.fujitsu.futurity.web.x31.X31SDataBeanAccessArray;
import com.fujitsu.futurity.web.x31.X31SWebLog;
import com.fujitsu.futurity.web.x33.X33CUtil;
import com.fujitsu.futurity.web.x33.X33WSessionController;

import eo.common.constant.JACStrConst;
import eo.common.constant.JFUStrConst;
import eo.common.constant.JPCModelConstant;
import eo.common.util.JCCFrameworkException;
import eo.common.util.JCCcomEncryptionUtil;
import eo.common.util.JPCUtilCommon;
import eo.web.webview.JCCWebBusinessLogic;
import eo.web.webview.CommonInfoCF.CommonInfoCFConst;
import eo.web.webview.common.JCCWebCommon;
import eo.web.webview.common.JFUScreenConst;
import eo.web.webview.common.JFUWebCommon;
import eo.web.webview.mapping.FUSV0265_FUSV0265OPDBMapper;
import eo.web.webview.mapping.FUSV0267_FUSV0267OPDBMapper;

/**
 * LaLaCall通話明細照会のビューロジッククラスです。
 * <p>
 * <BR>
 * @author 富士通
 */
@SuppressWarnings({"serial", "unchecked"})
public class FUW10901SFLogic extends JCCWebBusinessLogic
{
	/** サービスID (初期表示)*/
	private static final String USECASE_ID_FUSV0265 = "FUSV0265";
	/** サービスID (表示ボタン押下時)*/
	private static final String USECASE_ID_FUSV0267 = "FUSV0267";

	/** DataBean操作種別：項目値設定 */
	private static final String SET = X31CWebConst.DATABEAN_SET_VALUE;
	/** DataBean操作種別：項目値取得 */
	private static final String GET = X31CWebConst.DATABEAN_GET_VALUE;
	/** DataBean操作種別：項目値取得 */
	private static final String ADD = X31CWebConst.DATABEAN_ADD_VALUE;

	/** SCタイトル.FUSV26701SC */
	private static final String FUSV026701SC = "FUSV026701SC";
	/** SCタイトル.FUSV26702SC */
	private static final String FUSV026702SC = "FUSV026702SC";
	/** コンテンツ契約内訳一覧照会 */
	private static final String EAC06321B010CBSMSG1LIST = "EAC0621B010CBSMsg1List";
	/** コンテンツ通話明細合計一覧照会 */
	private static final String EAC0621B020CBSMSG1LIST = "EAC0621B020CBSMsg1List";

	/** フロント用画面表示定義ファイル：対象年月の期間 */
	private static final String TRGT_YM_KIKAN = "trgt_ym_kikan";

	/** 年月日書式：yyyyMMdd */
	private static final String FMT_YMD = "yyyyMMdd";
	/** 年月書式：yyyyMM */
	private static final String FMT_YM = "yyyyMM";
	/** 年月日編集書式：yyyyMM */
	private static final String DISP_EDIT_YM = "yyyy'年'MM'月通話分'";
	/** 時分秒書式：HHmmssS */
	private static final String FMT_HMS = "HHmmssS";
	/** 時分秒編集書式：HH:mm:ss.S */
	private static final String EDIT_HMS = "HH:mm:ss.S";
	/** 時分秒初期値 */
	private static final String DEF_HMS = "00:00:00.0";

	/** 文字列：ピリオド */
	private static final String PERIOD = ".";
	/** 文字列：2 */
	private static final int PLUS_TWO = 2;
	/** 文字列：-1 */
	private static final int MINUS_ONE = -1;
	/** 文字列：時分秒変換用 */
	private static final int HMS_CHANGE = 60;
	/** 文字列：日("01") */
	private static final String FIRST_DAY = "01";

	/** ユーザーエージェント */
	private static final String USER_AGENT = "USER-AGENT";
	/** 割り込み画面ID付加文字列 */
	private static final String WARIKOMI_GAMEN_ID_FUKA_STR = "0PJP";
	/** プロパティファイル取得文字列 */
	private static final String PATH_SMART_PHONE = "DISPSETTING/SETTING[@screenId='#']/DISPTEXT[@groupid='SMART_PHONE']";
	/** プロパティファイル取得文字列 */
	private static final String PATH_NOT_SMART_PHONE = "DISPSETTING/SETTING[@screenId='#']/DISPTEXT[@groupid='NOT_SMART_PHONE']";
	/** 属性名 */
	private static final String QUERY_ATTR_NAME = "id";

	/** コンテンツ通話明細課税非課税コード */
	private static final String CONT_TW_DTL_KAZEI_HIKAZEI_CD = "cont_tw_dtl_kazei_hikazei_cd";
	/** コンテンツ通話明細合計(通話数) */
	private static final String CONT_TW_DTL_GOKEI = "cont_tw_dtl_gokei";
	/** コンテンツ通話明細通話料金合計 */
	private static final String CONT_TW_DTL_PCALL_PRC_GOKEI = "cont_tw_dtl_pcall_prc_gokei";
	/** 通話年月 */
	private static final String TUWA_YM = "TUWA_YM";
	/** 通話開始年月日 */
	private static final String PCALL_STAYMD = "pcall_staymd";
	/** 通話開始時分秒 */
	private static final String PCALL_STA_HMS = "pcall_sta_hms";
	/** 通話秒数 */
	private static final String PCALL_SEC_CNT = "pcall_sec_cnt";
	/** 着信電話番号 */
	private static final String INCOMING_TELNO = "incoming_telno";
	/** 通話料金 */
	private static final String PCALL_PRC = "pcall_prc";
	/** 通話種別コード */
	private static final String TUWA_SBT_ALI = "tuwa_sbt_ali";
	/** 課税非課税コード */
	private static final String KAZEI_HIKAZEI_CD = "kazei_hikazei_cd";
	/** 画面ID取得用Key */
	private static final String GAMEN_ID_KEY = "GAMEN_ID_KEY";
	/** 暗号化キーの値を取得するキー */
	private static final String ENCRYPTION_KEY = "CK";
	/** 暗号化キーの値を取得するキー */
	private static final String TELNO_KEY = "TENO";
	/** LaLaCall連携(リクエストフィルタリング)用設定　共通暗号化キーの値を取得するキー */
	private static final String LALACALL_COMMON_ENCRYPTION_KEY = "LALACALL_ENCRYPTION_KEY";
	/** 画面ID 050アプリ通話明細(電話番号連携) */
	private static final String GAMEN_ID_LALACALL_NUMBER = "050_call_details_by_number";
	/** アクセスエラーのメッセージID */
	private static final String ACCESS_ERR_MSGID = "0009";

	/**
	 * 初期処理
	 * <br/>
	 *
	 * @return 処理結果
	 * @throws Exception
	 */
	public boolean init() throws Exception
	{
		DEBUG_LOG.info("----- FUW10901 Start init -----");

		// 2段階認証チェック
		if (!JFUWebCommon.isSetAuthTwoStep(this))
		{
			// 2段階認証を促すCMP側共通エラー画面にリダイレクト
			return true;
		}

		// 共有フォームBeanのデータBeanアクセスクラスを取得
		X31SDataBeanAccess commonInfoBean = super.getCommonInfoBean();
		// サービスフォームBeanのデータBeanアクセスクラスを取得
		X31SDataBeanAccess bean = super.getServiceFormBean();
		// 電話番号
		String decTelNo = null;

		// ●共有フォームBeanより現顧客契約情報を取得
		Map<String, Object> commonInfoMap = getCommoninfoBeanInfo(commonInfoBean);

		// ssoInfoBeanを取得
		X31SDataBeanAccess ssoInfoBean = (X31SDataBeanAccess)commonInfoMap.get(CommonInfoCFConst.SSO_INFO);
		// 配列にssoInfoBeanを格納
		X31SDataBeanAccess[] beanArray = { ssoInfoBean };

		// ユースケースID格納用マップを生成。
		HashMap<String, String> paramMap = new HashMap<String, String>(16);
		paramMap.put(X31CWebConst.TELEGRAM_INFO_USECASE_ID, USECASE_ID_FUSV0265);

		FUSV0265_FUSV0265OPDBMapper mapper = new FUSV0265_FUSV0265OPDBMapper();
		HashMap<String, Object> dataMap = new HashMap<String, Object>();

		// 画面ID取得
		X33WSessionController session_controller = X33CUtil.getSession(this.getSessionId());
		HttpServletRequest request = session_controller.getServletRequest();
		String gamenId = getGamenId(request);

		// 050アプリ通話明細(電話番号連携)の場合
		if (GAMEN_ID_LALACALL_NUMBER.equals(gamenId))
		{
			// 暗号キーが存在する
			// 暗号化キー自信が暗号化されているので、共通暗号化キーで復号する。
			try
			{
				// 電話番号復元
				String encTelNo = request.getParameter(TELNO_KEY);
				
				// 値が設定されている場合のみ複合化を行う。
				if (!JFUWebCommon.isNull(encTelNo))
				{
					// リクエストより暗号キーの取得
					String encryptionKeyValue = request.getParameter(ENCRYPTION_KEY);

					// 暗号キー取得
					// LaLaCall連携(リクエストフィルタリング)用設定暗号キーをAPLConstから取得
					String comKey = JCCWebCommon.getApplicationConst(LALACALL_COMMON_ENCRYPTION_KEY);

					// 暗号キー(CK)が設定されていない場合
					if (JFUWebCommon.isNull(encryptionKeyValue))
					{
						// "0009"（アクセスエラー）
						throw new JCCBusinessException(ACCESS_ERR_MSGID);
					}
		
					// 暗号化キーの復号化（共通暗号化キー）
					String decodedEncryptionKey = JCCcomEncryptionUtil.decryptKey(comKey, encryptionKeyValue);

					// 電話番号の複合化（暗号化キー）
					decTelNo = JCCcomEncryptionUtil.decryptKey(decodedEncryptionKey, encTelNo);
				}

			}
			catch (Exception e)
			{
				// 復号化できない場合
				// "0009"（アクセスエラー）
				JCCBusinessException be = new JCCBusinessException(ACCESS_ERR_MSGID);
				be.initCause(e);
				throw be;
			}
		}

		// ●上りマッピング(詳細取得)
		// 共有フォームBeanより、前画面引継情報.通話年月を取得
		String tuwaYm = getTuwaYm();
		// 運用日付を取得
		String opeDate = JCCWebCommon.getOpeDate(this, null);
		// 開始年月日(月初)
		String firstday = JFUStrConst.EMPTY;
		// 開始年月日(末日)
		String lastday = JFUStrConst.EMPTY;
		// フロント用画面表示定義ファイルから対象年月の期間を取得
		int tgYmKikan = Integer.parseInt(JFUWebCommon.getDispText(JFUScreenConst.SCREEN_ID_FUW10901, TRGT_YM_KIKAN));

		// ●コンボボックス：通話年月の初期選択値設定
		if (null != tuwaYm && !JFUStrConst.EMPTY.equals(tuwaYm))
		{
			// 前画面引継情報.通話年月がある場合
			String editFirstday = JPCUtilCommon.addMonth(tuwaYm + FIRST_DAY, MINUS_ONE);
			firstday = JFUWebCommon.getBeginOfNextMonthDate(editFirstday);
			lastday = JFUWebCommon.getEndOfMonthDate(tuwaYm);
		}
		else
		{
			// 前画面引継情報.通話年月がない場合
			String editFirstday = JPCUtilCommon.addMonth(opeDate, MINUS_ONE);
			firstday = JFUWebCommon.getBeginOfNextMonthDate(editFirstday);
			lastday = JFUWebCommon.getEndOfMonthDate(opeDate);
		}

		// ●上りマッピング
		// 050アプリ電話番号一覧照会
		mapper.setFUSV026501SC(beanArray, dataMap, JPCModelConstant.FUNC_CD_1);

		// ●検索結果格納用マップを生成。
		HashMap<String, Object> outputMap = new HashMap<String, Object>();

		// ●サービス呼出処理１
		try
		{
			invokeService(paramMap, dataMap, outputMap);
		}
		catch (JCCWebServiceException se)
		{
			throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0002);
		}

		// ●下りマッピング
		// 050アプリ電話番号一覧照会
		// コンボボックス.通話年月の編集
		setTuwaYm(bean, commonInfoBean, tuwaYm, tgYmKikan);
		boolean errFlg = mapper.getFUSV026501SC(bean, outputMap, gamenId, decTelNo);

		if (!errFlg)
		{
			X31SWebLog.DEBUG_LOG.debug("関連チェック【契約状態エラー】");
			throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0102);
		}
		// コンボボックス.選択利用電話番号の設定
		int telno = Integer.parseInt(bean.sendMessageString(FUW10901SFConst.CHOICE_TELNO, GET));

		X31SDataBeanAccessArray useTelnoListDataType = bean.getDataBeanArray(FUW10901SFConst.USE_TELNO_LIST);
		X31SDataBeanAccess telnoDataType = useTelnoListDataType.getDataBean(0);
		String choiceTelno = telnoDataType.sendMessageString(FUW10901SFConst.VALUE_03, GET, telno);

		// 選択利用電話番号の050アプリ設定状態を取得
		X31SDataBeanAccessArray aplStatListDataType = bean.getDataBeanArray(FUW10901SFConst.APL_STAT_CODE_LIST);
		X31SDataBeanAccess aplStatDataType = aplStatListDataType.getDataBean(0);
		String aplStat = aplStatDataType.sendMessageString(FUW10901SFConst.VALUE_04, GET, telno);

		// 050アプリ設定状態が「2(設定済み)」でない場合は初期設定フラグに1を設定
		if (JFUStrConst.SETTEI_ZUMI_050_2.equals(aplStat))
		{
			bean.sendMessageString(FUW10901SFConst.SYOKISETTEI_FLG, SET, JFUStrConst.S_ZERO);

			// ユースケースID格納用マップを生成。
			HashMap<String, String> paramMapDtl = new HashMap<String, String>(16);
			paramMapDtl.put(X31CWebConst.TELEGRAM_INFO_USECASE_ID, USECASE_ID_FUSV0267);

			FUSV0267_FUSV0267OPDBMapper mapperDtl = new FUSV0267_FUSV0267OPDBMapper();
			HashMap<String, Object> dataMapDtl = new HashMap<String, Object>();
			HashMap<String, Object> outputMapDtl = new HashMap<String, Object>();

			// 上りマッピング
			// コンテンツ通話明細合計一覧照会
			mapperDtl.setFUSV026701SC(beanArray, dataMapDtl, JPCModelConstant.FUNC_CD_3, firstday, lastday, choiceTelno);
			// コンテンツ通話明細一覧照会
			mapperDtl.setFUSV026702SC(beanArray, dataMapDtl, JPCModelConstant.FUNC_CD_4, firstday, lastday, choiceTelno);

			// サービス呼出処理
			try
			{
				invokeService(paramMapDtl, dataMapDtl, outputMapDtl);
			}
			catch (JCCWebServiceException se)
			{
				throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0002);
			}

			// ●下りマッピング
			// コンテンツ通話明細合計一覧照会
			setContDtlGokei(bean, outputMapDtl, FUSV026701SC);
			// コンテンツ通話明細一覧照会
			setContDtl(bean, outputMapDtl, FUSV026702SC);

			// 表示メイン処理
			dispMain(bean, outputMapDtl, FUSV026701SC);
		}
		else
		{
			bean.sendMessageString(FUW10901SFConst.SYOKISETTEI_FLG, SET, JFUStrConst.S_ONE);
		}

		// ●スマートフォン判定
		boolean smartPhonFlg = chekcSmartPhonFlg();

		// 画面IDと画面名格納用
		String nextScreenId = null;
		String nextScreenName = null;

		// スマートフォンの場合
		if (smartPhonFlg)
		{
			nextScreenId = JFUScreenConst.SCREEN_ID_FUW10903;
			nextScreenName = JFUScreenConst.SCREEN_NAME_FUW10903;
			// スマートフォンフラグ
			bean.sendMessageString(FUW10901SFConst.SMARTPHONE_FLG, SET, JFUStrConst.S_ONE);

			// 割り込み設定
			super.setTransferPageId(JFUScreenConst.SCREEN_ID_FUW10903 + WARIKOMI_GAMEN_ID_FUKA_STR);

		}
		// スマートフォンでない場合
		else
		{
			nextScreenId = JFUScreenConst.SCREEN_ID_FUW10902;
			nextScreenName = JFUScreenConst.SCREEN_NAME_FUW10902;

			// スマートフォンフラグ
			bean.sendMessageString(FUW10901SFConst.SMARTPHONE_FLG, SET, JFUStrConst.S_ZERO);

			// 割り込み設定
			super.setTransferPageId(JFUScreenConst.SCREEN_ID_FUW10902 + WARIKOMI_GAMEN_ID_FUKA_STR);
		}
		// 遷移先画面IDを設定
		commonInfoBean.sendMessageString(CommonInfoCFConst.NEXT_SCREEN_ID, SET, nextScreenId);
		// 遷移先画面名を設定
		commonInfoBean.sendMessageString(CommonInfoCFConst.NEXT_SCREEN_NAME, SET, nextScreenName);

		DEBUG_LOG.info("----- FUW10901 End init -----");

		return true;
	}

	/**
	 * 表示するボタン押下処理
	 * <br/>
	 * 表示するボタン押下時の処理を行います。
	 *
	 * @return true
	 * @throws Exception
	 */
	public boolean disp() throws Exception
	{
		// ユースケースID格納用マップを生成。
		HashMap<String, String> paramMap = new HashMap<String, String>(16);
		paramMap.put(X31CWebConst.TELEGRAM_INFO_USECASE_ID, USECASE_ID_FUSV0267);

		// サービスフォームBeanのデータBeanアクセスクラスを取得
		X31SDataBeanAccess bean = super.getServiceFormBean();

		// 各Beanを配列に格納
		// データBean, SSO
		X31SDataBeanAccess commonInfoBean = super.getCommonInfoBean();
		Map<String, Object> commonInfoMap = getCommoninfoBeanInfo(commonInfoBean);
		X31SDataBeanAccess ssoInfoBean = (X31SDataBeanAccess)commonInfoMap.get(CommonInfoCFConst.SSO_INFO);
		X31SDataBeanAccess[] beanArray = { ssoInfoBean };

		// 画面で選択した電話番号を取得
		int telno = Integer.parseInt(bean.sendMessageString(FUW10901SFConst.CHOICE_TELNO, GET));
		X31SDataBeanAccessArray useTelnoListDataType = bean.getDataBeanArray(FUW10901SFConst.USE_TELNO_LIST);
		X31SDataBeanAccess telnoDataType = useTelnoListDataType.getDataBean(0);
		String choiceTelno = telnoDataType.sendMessageString(FUW10901SFConst.VALUE_03, GET, telno);

		// 選択利用電話番号の050アプリ設定状態のを取得
		X31SDataBeanAccessArray aplStatListDataType = bean.getDataBeanArray(FUW10901SFConst.APL_STAT_CODE_LIST);
		X31SDataBeanAccess aplStatDataType = aplStatListDataType.getDataBean(0);
		String aplStat = aplStatDataType.sendMessageString(FUW10901SFConst.VALUE_04, GET, telno);

		// 050アプリ設定状態が「2(設定済み)」でない場合は初期設定フラグに1を設定
		if (JFUStrConst.SETTEI_ZUMI_050_2.equals(aplStat))
		{
			bean.sendMessageString(FUW10901SFConst.SYOKISETTEI_FLG, SET, JFUStrConst.S_ZERO);

			// 画面で選択した通話年月を取得
			int tuwaYM = Integer.parseInt(bean.sendMessageString(FUW10901SFConst.CHOICE_TUWA_YM, GET));
			X31SDataBeanAccessArray useTuwaYMListDataType = bean.getDataBeanArray(FUW10901SFConst.USE_TUWA_YM_LIST);
			X31SDataBeanAccess tuwaYMDataType = useTuwaYMListDataType.getDataBean(0);
			String choiceYM = tuwaYMDataType.sendMessageString(FUW10901SFConst.VALUE_02, GET, tuwaYM);

			String editFirstday = JPCUtilCommon.addMonth(choiceYM, MINUS_ONE);
			String firstday = JFUWebCommon.getBeginOfNextMonthDate(editFirstday);
			String lastday = JFUWebCommon.getEndOfMonthDate(choiceYM);

			FUSV0267_FUSV0267OPDBMapper mapper = new FUSV0267_FUSV0267OPDBMapper();
			HashMap<String, Object> dataMap = new HashMap<String, Object>();

			// 上りマッピング
			// コンテンツ通話明細合計一覧照会
			mapper.setFUSV026701SC(beanArray, dataMap, JPCModelConstant.FUNC_CD_3, firstday, lastday, choiceTelno);
			// コンテンツ通話明細一覧照会
			mapper.setFUSV026702SC(beanArray, dataMap, JPCModelConstant.FUNC_CD_4, firstday, lastday, choiceTelno);

			// 検索結果格納用マップを生成
			HashMap<String, Object> dtlOutputMap = new HashMap<String, Object>();

			// サービス呼出処理
			try
			{
				invokeService(paramMap, dataMap, dtlOutputMap);
			}
			catch (JCCWebServiceException se)
			{
				throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0002);
			}

			// 下りマッピング
			// コンテンツ通話明細合計一覧照会
			setContDtlGokei(bean, dtlOutputMap, FUSV026701SC);
			// コンテンツ通話明細一覧照会
			setContDtl(bean, dtlOutputMap, FUSV026702SC);

			// 表示メイン処理
			dispMain(bean, dtlOutputMap, FUSV026701SC);
		}
		else
		{
			bean.sendMessageString(FUW10901SFConst.SYOKISETTEI_FLG, SET, JFUStrConst.S_ONE);
		}

		return true;
	}

	/**
	 * 表示メイン処理
	 * <br/>
	 * @param serviceFormBean サービスフォームBean
	 * @param dtlOutputMap 検索結果格納用マップ
	 * @param sif 検索結果SC名
	 * @throws Exception
	 */
	private void dispMain(X31SDataBeanAccess serviceFormBean, HashMap<String, Object> dtlOutputMap, String sif) throws Exception
	{
		// サービス処理結果.通話明細合計一覧照会
		HashMap parentMap = (HashMap)dtlOutputMap.get(sif);
		ArrayList childList = null;

		// 通話明細合計の編集
		// 通話数合計
		int pcallCntGk = JFUStrConst.I_ZERO;
		// 課税分料金合計
		BigDecimal kazeibunPrcGk = new BigDecimal(JFUStrConst.S_ZERO);
		// 免税分料金合計
		BigDecimal menzeibunPrcGk = new BigDecimal(JFUStrConst.S_ZERO);
		// 通話料金合計
		BigDecimal pcallPrcGk = new BigDecimal(JFUStrConst.S_ZERO);

		if (null != parentMap && 0 < parentMap.size())
		{
			// サービス処理結果.コンテンツ通話明細合計一覧照会
			childList = (ArrayList)parentMap.get(EAC0621B020CBSMSG1LIST);
		}

		if (null != parentMap && null != childList && parentMap.containsKey(EAC0621B020CBSMSG1LIST))
		{

			for (int i = 0; i < childList.size(); i++)
			{
				if (null != childList && 0 < childList.size())
				{

					// 050電話通話合計一意照会情報
					HashMap<String, String> childMap = (HashMap<String, String>)childList.get(i);

					// コンテンツ通話明細課税非課税コード
					String kazeiHikazeiCd = childMap.get(CONT_TW_DTL_KAZEI_HIKAZEI_CD);

					if (JACStrConst.KAZEI_HIKAZEI_CD_KAZEI.equals(kazeiHikazeiCd))
					{
						// 課税分料金合計
						kazeibunPrcGk = kazeibunPrcGk.add(new BigDecimal(childMap.get(CONT_TW_DTL_PCALL_PRC_GOKEI)));
						// 通話料金合計
						pcallPrcGk = pcallPrcGk.add(new BigDecimal(childMap.get(CONT_TW_DTL_PCALL_PRC_GOKEI)));
						// 課税分コンテンツ通話明細合計(通話数)
						pcallCntGk += Integer.parseInt(childMap.get(CONT_TW_DTL_GOKEI));
					}
					else
					{
						// 免税分料金合計
						menzeibunPrcGk = menzeibunPrcGk.add(new BigDecimal(childMap.get(CONT_TW_DTL_PCALL_PRC_GOKEI)));
						// 通話料金合計
						pcallPrcGk = pcallPrcGk.add(new BigDecimal(childMap.get(CONT_TW_DTL_PCALL_PRC_GOKEI)));
						// 免税分コンテンツ通話明細合計(通話数)
						pcallCntGk += Integer.parseInt(childMap.get(CONT_TW_DTL_GOKEI));
					}
				}
			}
		}

		// サービスフォームBean.コンテンツ通話明細合計(通話数)
		serviceFormBean.sendMessageString(FUW10901SFConst.CONT_TW_DTL_GOKEI, SET, String.valueOf(pcallCntGk));
		// サービスフォームBean.課税分合計額（税込）
		serviceFormBean.sendMessageString(FUW10901SFConst.KAZEIBUN_PRC_GOKEI, SET, kazeibunPrcGk.toString());
		// サービスフォームBean.免税分合計金額
		serviceFormBean.sendMessageString(FUW10901SFConst.MENZEIBUN_PRC_GOKEI, SET, menzeibunPrcGk.toString());
		// サービスフォームBean.合計金額
		serviceFormBean.sendMessageString(FUW10901SFConst.CONT_TW_DTL_PCALL_PRC_GOKEI, SET, pcallPrcGk.toString());
		// 通話明細編集
		// サービスフォームBean.通話明細
		X31SDataBeanAccessArray tuwaDtlList = serviceFormBean.getDataBeanArray(FUW10901SFConst.TUWA_DTL_LIST);

		// 通話明細の編集
		for (int i = 0; i < tuwaDtlList.getCount(); i++)
		{
			// 通話明細Bean
			X31SDataBeanAccess tuwaldtlBean = tuwaDtlList.getDataBean(i);
			// サービスフォームBean.通話明細.通話開始日時(時分秒)
			String pcallStaHms = tuwaldtlBean.sendMessageString(FUW10901SFConst.PCALL_STA_HMS_01, GET);
			// サービスフォームBean.通話明細.通話時間（時分秒）
			String pcallTimeHms = tuwaldtlBean.sendMessageString(FUW10901SFConst.TUWA_HMS_01, GET);

			// HH:mm:ss.S形式に編集
			pcallStaHms = toFormatDate(pcallStaHms, FMT_HMS, EDIT_HMS);
			if (pcallTimeHms == null || JFUStrConst.EMPTY.equals(pcallTimeHms))
			{
				pcallTimeHms = DEF_HMS;
			}
			else
			{
				pcallTimeHms = editPcallTimeHms(pcallTimeHms);
			}
			// サービスフォームBeanに設定
			tuwaldtlBean.sendMessageString(FUW10901SFConst.PCALL_STA_HMS_01, SET, pcallStaHms);
			tuwaldtlBean.sendMessageString(FUW10901SFConst.TUWA_HMS_01, SET, pcallTimeHms);
		}
	}

	/**
	 * 共有フォームBean情報取得
	 * <br/>
	 * 共有フォームBeanの情報を取得します。
	 *
	 * @param commoninfoBean 共有フォームBean
	 * @return resultMap
	 */
	private Map<String, Object> getCommoninfoBeanInfo(X31SDataBeanAccess commoninfoBean)
	{
		// 結果格納マップ
		Map<String, Object> resultMap = new HashMap<String, Object>();

		// ★WEB変更情報
		X31SDataBeanAccess webChgInfoBean = getX31SDataBeanAccess(commoninfoBean, CommonInfoCFConst.WEB_CHG_INFO);

		// ★SSO情報(WEB変更情報の子階層)
		X31SDataBeanAccessArray ssoInfoArray = webChgInfoBean.getDataBeanArray(CommonInfoCFConst.SSO_INFO);
		X31SDataBeanAccess ssoInfoBean = ssoInfoArray.getDataBean(0);

		// ★現顧客情報
		X31SDataBeanAccessArray genCustKeiInfoArray = webChgInfoBean.getDataBeanArray(CommonInfoCFConst.GEN_CUST_KEI_INFO);
		X31SDataBeanAccess genCustKeiInfoBean = genCustKeiInfoArray.getDataBean(0);

		// 各Bean情報を設定
		resultMap.put(CommonInfoCFConst.WEB_CHG_INFO, webChgInfoBean);
		resultMap.put(CommonInfoCFConst.SSO_INFO, ssoInfoBean);
		resultMap.put(CommonInfoCFConst.GEN_CUST_KEI_INFO, genCustKeiInfoBean);

		return resultMap;
	}

	/**
	 * データBeanリストから0番目のデータBeanを取得します。 <BR>
	 * 
	 * @param bean サービスフォームBean
	 * @param componentID
	 * @return subBean
	 */
	private X31SDataBeanAccess getX31SDataBeanAccess(X31SDataBeanAccess bean, String componentID)
	{
		X31SDataBeanAccessArray subBeanArray = bean.getDataBeanArray(componentID);
		X31SDataBeanAccess subBean = subBeanArray.getDataBean(0);
		if (null == subBean)
		{
			subBeanArray.addDataBean();
			subBean = subBeanArray.getDataBean(0);
		}
		return subBean;
	}

	/**
	 * 検索キー情報の設定(コンボボックス：通話年月の編集)。 <BR>
	 * 
	 * @param bean サービスフォームBean
	 * @param commonInfoBean 共有フォームBean
	 * @param tuwaYm 通話年月
	 * @param tgYmKikan 対象期間
	 * @throws Exception 
	 */
	private void setTuwaYm(X31SDataBeanAccess bean, X31SDataBeanAccess commonInfoBean, String tuwaYm, int tgYmKikan) throws Exception
	{
		// 運用日付を取得
		String opeDate = JCCWebCommon.getOpeDate(this, null);

		X31SDataBeanAccessArray useTuwaYMListArray = bean.getDataBeanArray(FUW10901SFConst.USE_TUWA_YM_LIST);
		useTuwaYMListArray.clearArray();

		X31SDataBeanAccess useTuwaYMListDataType = useTuwaYMListArray.addDataBean();

		// 運用日付から対象期間を設定する
		for (int i = 0; i < tgYmKikan; i++)
		{
			String ym = null;

			if (i == JFUStrConst.I_ZERO)
			{
				// リストの0番目にマイナスしないで運用日付をリストに追加
				useTuwaYMListDataType.sendMessageString(FUW10901SFConst.VALUE_02, ADD, opeDate);
				useTuwaYMListDataType.sendMessageString(FUW10901SFConst.DSP_VALUE_02, ADD, toFormatDate(opeDate, FMT_YMD, DISP_EDIT_YM));
				ym = toFormatDate(opeDate, FMT_YMD, FMT_YM);
			}
			else
			{
				// 運用日付の月からカウンタ分をマイナス
				String useTuwaYm = JPCUtilCommon.addMonth(opeDate, -i);
				useTuwaYMListDataType.sendMessageString(FUW10901SFConst.VALUE_02, ADD, useTuwaYm);
				useTuwaYMListDataType.sendMessageString(FUW10901SFConst.DSP_VALUE_02, ADD, toFormatDate(useTuwaYm, FMT_YMD, DISP_EDIT_YM));
				ym = toFormatDate(useTuwaYm, FMT_YMD, FMT_YM);
			}

			// コンボボックス：通話年月の初期選択値設定
			if (null != tuwaYm && !JFUStrConst.EMPTY.equals(tuwaYm) && tuwaYm.equals(ym))
			{
				// 前画面引継情報.通話年月がある場合、プルダウンの初期値へ設定
				bean.sendMessageString(FUW10901SFConst.CHOICE_TUWA_YM, SET, String.valueOf(i));

			}
		}

		// コンボボックス：通話年月の初期選択値設定
		if (null == tuwaYm || JFUStrConst.EMPTY.equals(tuwaYm))
		{
			// 前画面引継情報.通話年月がない場合
			bean.sendMessageString(FUW10901SFConst.CHOICE_TUWA_YM, SET, JFUStrConst.S_ZERO);
		}
	}

	/**
	 * SIF下りマッピング情報取得(コンテンツ通話明細合計一覧照会)
	 * <br/>
	 * SIF（）下りマッピングnの情報を取得します。
	 * @param bean サービスフォームBean
	 * @param dtlOutputMap 検索結果格納用マップ
	 * @param sif 検索結果SC名
	 */
	private void setContDtlGokei(X31SDataBeanAccess bean, HashMap<String, Object> dtlOutputMap, String sif)
	{
		HashMap<String, Object> parentMap = null;
		if (dtlOutputMap.containsKey(sif))
		{
			parentMap = (HashMap)dtlOutputMap.get(sif);
		}

		ArrayList childList = null;
		if(null != parentMap ){
			childList = (ArrayList)parentMap.get(EAC0621B020CBSMSG1LIST);
		}

		if (null != parentMap && null != childList && parentMap.containsKey(EAC0621B020CBSMSG1LIST))
		{
			for (int i = 0; i < childList.size(); i++)
			{
				HashMap childMap = (HashMap)childList.get(i);

				// コンテンツ通話明細合計 ← コンテンツ通話明細一覧照会マップ.コンテンツ通話明細一覧照会.通話料
				if (null != childMap)
				{
					bean.sendMessageString(FUW10901SFConst.CONT_TW_DTL_GOKEI, ADD, (String)childMap.get(CONT_TW_DTL_GOKEI));
				}
				else
				{
					bean.sendMessageString(FUW10901SFConst.CONT_TW_DTL_GOKEI, ADD, JFUStrConst.EMPTY);
				}

				// コンテンツ通話明細通話料金合計 ← コンテンツ通話明細一覧照会マップ.コンテンツ通話明細一覧照会.コンテンツ通話明細通話料金合計
				if (null != childMap)
				{
					bean.sendMessageString(FUW10901SFConst.CONT_TW_DTL_PCALL_PRC_GOKEI, ADD, (String)childMap.get(CONT_TW_DTL_PCALL_PRC_GOKEI));
				}
				else
				{
					bean.sendMessageString(FUW10901SFConst.CONT_TW_DTL_PCALL_PRC_GOKEI, ADD, JFUStrConst.EMPTY);
				}
			}
		}
	}

	/**
	 * SIF下りマッピング情報取得(コンテンツ通話明細一覧照会)
	 * <br/>
	 * SIF（）下りマッピングnの情報を取得します。
	 *
	 * @param bean サービスフォームBean
	 * @param dtlOutputMap 共有フォームBean
	 * @param sif 
	 * @return bean
	 */
	private X31SDataBeanAccess setContDtl(X31SDataBeanAccess bean, HashMap<String, Object> dtlOutputMap, String sif)
	{
		HashMap<String, Object> parentMap = null;

		if (dtlOutputMap.containsKey(sif))
		{
			parentMap = (HashMap)dtlOutputMap.get(sif);
		}

		ArrayList childList = null;

		X31SDataBeanAccessArray listFUSV026503SC_tuwa_dtl_list_EAC06321B010CBSMsg1List = bean.getDataBeanArray(FUW10901SFConst.TUWA_DTL_LIST);
		listFUSV026503SC_tuwa_dtl_list_EAC06321B010CBSMsg1List.clearArray();

		if (null != parentMap && parentMap.containsKey(EAC06321B010CBSMSG1LIST))
		{

			childList = (ArrayList)parentMap.get(EAC06321B010CBSMSG1LIST);

			for (int i = 0; i < childList.size(); i++)
			{
				X31SDataBeanAccess subbean = null;

				if (listFUSV026503SC_tuwa_dtl_list_EAC06321B010CBSMsg1List.getCount() - 1 >= i)
				{
					subbean = listFUSV026503SC_tuwa_dtl_list_EAC06321B010CBSMsg1List.getDataBean(i);
				}
				else
				{
					subbean = listFUSV026503SC_tuwa_dtl_list_EAC06321B010CBSMsg1List.addDataBean();
				}

				HashMap childMap = (HashMap)childList.get(i);
				if (subbean == null)
				{
					continue;
				}

				// 通話明細リスト.通話開始日時(月/日) ← コンテンツ通話明細一覧照会マップ.コンテンツ通話明細一覧照会.通話開始年月日
				if (childMap != null)
				{
					subbean.sendMessageString(FUW10901SFConst.PCALL_STAYMD_01, SET, (String)childMap.get(PCALL_STAYMD));
				}
				else
				{
					subbean.sendMessageString(FUW10901SFConst.PCALL_STAYMD_01, SET, JFUStrConst.EMPTY);
				}

				// 通話明細リスト.通話開始日時(時分秒) ← コンテンツ通話明細一覧照会マップ.コンテンツ通話明細一覧照会.通話開始時分秒
				if (null != childMap)
				{
					subbean.sendMessageString(FUW10901SFConst.PCALL_STA_HMS_01, SET, (String)childMap.get(PCALL_STA_HMS));
				}
				else
				{
					subbean.sendMessageString(FUW10901SFConst.PCALL_STA_HMS_01, SET, JFUStrConst.EMPTY);
				}

				// 通話明細リスト.通話時間(時分秒) ← コンテンツ通話明細一覧照会マップ.コンテンツ通話明細一覧照会.通話開始時分秒
				if (null != childMap)
				{
					subbean.sendMessageString(FUW10901SFConst.TUWA_HMS_01, SET, (String)childMap.get(PCALL_SEC_CNT));
				}
				else
				{
					subbean.sendMessageString(FUW10901SFConst.TUWA_HMS_01, SET, JFUStrConst.EMPTY);
				}

				// 通話明細リスト.電話番号 ← コンテンツ通話明細一覧照会マップ.コンテンツ通話明細一覧照会.着信電話番号
				if (null != childMap)
				{
					subbean.sendMessageString(FUW10901SFConst.TUWA_TELNO_01, SET, (String)childMap.get(INCOMING_TELNO));
				}
				else
				{
					subbean.sendMessageString(FUW10901SFConst.TUWA_TELNO_01, SET, JFUStrConst.EMPTY);
				}

				// 通話明細リスト.通話料 ← コンテンツ通話明細一覧照会マップ.コンテンツ通話明細一覧照会.通話料金
				if (null != childMap)
				{
					subbean.sendMessageString(FUW10901SFConst.TUWA_PRC_01, SET, (String)childMap.get(PCALL_PRC));
				}
				else
				{
					subbean.sendMessageString(FUW10901SFConst.TUWA_PRC_01, SET, JFUStrConst.EMPTY);
				}

				// 通話明細リスト.種別 ← コンテンツ通話明細一覧照会マップ.コンテンツ通話明細一覧照会.通話種別コード
				if (null != childMap)
				{
					subbean.sendMessageString(FUW10901SFConst.TUWA_SBT_01, SET, (String)childMap.get(TUWA_SBT_ALI));
				}
				else
				{
					subbean.sendMessageString(FUW10901SFConst.TUWA_SBT_01, SET, JFUStrConst.EMPTY);
				}

				// 通話明細リスト.通話料(免税表示) ← コンテンツ通話明細一覧照会マップ.コンテンツ通話明細一覧照会.課税非課税コード 
				if (childMap != null)
				{
					subbean.sendMessageString(FUW10901SFConst.TUWA_PRC_MENZEI_HYOJI_01, SET, (String)childMap.get(KAZEI_HIKAZEI_CD));
				}
				else
				{
					subbean.sendMessageString(FUW10901SFConst.TUWA_PRC_MENZEI_HYOJI_01, SET, JFUStrConst.EMPTY);
				}

				// 通話明細識別フラグの設定
				subbean.sendMessageString(FUW10901SFConst.TUWA_DTL_SKBT_FLG_01, SET, getFlg(i));

				// 通話明細合計フラグの設定
				if (i == 0)
				{
					bean.sendMessageString(FUW10901SFConst.TUWA_DTL_GK_FLG, SET, JFUStrConst.S_ONE);
				}
			}
		}
		else
		{
			bean.sendMessageString(FUW10901SFConst.TUWA_DTL_GK_FLG, SET, JFUStrConst.S_ZERO);
		}
		return bean;
	}

	/**
	 * 日付オブジェクトを指定された形式の文字列に編集します。
	 * <br>
	 * @param arg0 編集する日付オブジェクト
	 * @param arg1 java.util.Date型の日付書式
	 * @param arg2 編集する文字列の日付書式
	 * @return 指定された形式に編集された文字列
	 */
	private String toFormatDate(String arg0, String arg1, String arg2)
	{
		try
		{
			SimpleDateFormat instance = new SimpleDateFormat(arg1);

			return new SimpleDateFormat(arg2).format(instance.parse(arg0));

		}
		catch (ParseException pe)
		{
			return arg0;
		}
	}

	/**
	 * 通話時間(秒)を編集します。
	 * <br>
	 * @param strPcallTimeHms 通話時間(秒)
	 * @return pcallTimeHms 通話時間(HH:mm:ss.S形式)
	 */
	private String editPcallTimeHms(String strPcallTimeHms)
	{
		BigDecimal bdTimeHms = new BigDecimal(strPcallTimeHms);
		// 通話時間(秒)から整数部のみ取得
		int hms = bdTimeHms.intValue();
		// 小数点の位置を取得
		int point = strPcallTimeHms.indexOf(PERIOD);
		// 通話時間(秒)の少数部
		String smallNumber = JFUStrConst.EMPTY;
		if (point == MINUS_ONE)
		{
			// 小数部がない場合
			smallNumber = JFUStrConst.S_ZERO;
		}
		else
		{
			// 小数部がある場合、小数部を取得
			smallNumber = strPcallTimeHms.substring(point + 1, strPcallTimeHms.length());
		}
		// 通話時間(秒)から時分秒に変換する
		int minutes = hms / HMS_CHANGE;
		int second = hms % HMS_CHANGE;
		int hour = minutes / HMS_CHANGE;
		minutes = minutes % HMS_CHANGE;
		String hh = String.valueOf(hour);
		String mm = String.valueOf(minutes);
		String ss = String.valueOf(second);
		hh = JPCUtilCommon.fillZero(hh, PLUS_TWO, false);
		mm = JPCUtilCommon.fillZero(mm, PLUS_TWO, false);
		ss = JPCUtilCommon.fillZero(ss, PLUS_TWO, false);

		// OM-2020-0000204 MOD START
//		// 通話時間(時分秒)
//		String pcallTimeHms = hh + mm + ss + smallNumber;
//		// 通話時間(時分秒)の編集 ※HH:mm:ss.S形式
//		pcallTimeHms = toFormatDate(pcallTimeHms, FMT_HMS, EDIT_HMS);
		String pcallTimeHms = hh + ":" + mm + ":" + ss + "." + smallNumber;
		// OM-2020-0000204 MOD END

		return pcallTimeHms;
	}

	/**
	 * request情報から通話年月の取得
	 * 
	 * <br>
	 * @return 通話年月
	 */
	private String getTuwaYm()
	{

		Map<String, Object> reqMap = getRequestParams();

		return (String)reqMap.get(TUWA_YM);
	}

	/**
	 * 通話明細識別フラグの情報を取得します。
	 *  0：無(偶数行)
	 *  1：有(奇数行)
	 * <br>
	 * @param i
	 * @return tuwaDtlSkbtFlg 通話明細識別フラグ
	 */
	private String getFlg(int i)
	{
		String tuwaDtlSkbtFlg = null;
		if (i % PLUS_TWO == JFUStrConst.I_ZERO)
		{
			// 奇数行の場合、"1"を設定。
			tuwaDtlSkbtFlg = JFUStrConst.CD00002_1;
		}
		else
		{
			// 偶数行の場合、"0"を設定。
			tuwaDtlSkbtFlg = JFUStrConst.CD00002_0;

		}
		return tuwaDtlSkbtFlg;
	}

	/**
	 * ユーザーエージェントにスマートフォンの文字列が含まれているかチェックする
	 * 含まれている場合：true
	 * 含まれていない場合：false
	 * <br>
	 * @return smartPhonFlg スマートフォンフラグ
	 * @throws Exception
	 */
	private boolean chekcSmartPhonFlg() throws Exception
	{

		X33WSessionController session_controller = X33CUtil.getSession(this.getSessionId());
		HttpServletRequest request = session_controller.getServletRequest();
		String userAgent = request.getHeader(USER_AGENT);

		// ●スマートフォンプロパティ取得処理
		Map<String, String> smartPhoneMap = JFUWebCommon.getDispItemsAsMap(PATH_SMART_PHONE, QUERY_ATTR_NAME);
		Collection<String> smartPhoneCollection = smartPhoneMap.values();

		// スマートフォンフラグ
		boolean smartPhonFlg = false;

		Iterator<String> itr = smartPhoneCollection.iterator();

		while (itr.hasNext())
		{
			String smartPhoneStr = itr.next();
			Pattern ptn = Pattern.compile(smartPhoneStr);
			Matcher mc = ptn.matcher(userAgent);

			// UAにスマートフォン文字列が含まれている場合
			if (mc.find())
			{
				// ●スマートフォン以外プロパティ取得処理(SC-01C)
				Map<String, String> notSmartPhoneMap = JFUWebCommon.getDispItemsAsMap(PATH_NOT_SMART_PHONE, QUERY_ATTR_NAME);
				Collection<String> notSmartPhoneCollection = notSmartPhoneMap.values();

				Iterator<String> notItr = notSmartPhoneCollection.iterator();

				while (notItr.hasNext())
				{
					String notSmartPhoneStr = notItr.next();
					Pattern notPtn = Pattern.compile(notSmartPhoneStr);
					Matcher notMc = notPtn.matcher(userAgent);

					// スマートフォン以外の値がマッチした場合、PC版とみなす
					if (notMc.find())
					{
						smartPhonFlg = false;
						break;
					}
					else
					{
						smartPhonFlg = true;
					}
				}
				break;
			}
			// UAにスマートフォン文字列が含まれていない場合
			else
			{
				smartPhonFlg = false;
			}
		}

		return smartPhonFlg;
	}

	/**
	 * 画面IDの取得
	 * <br>
	 * アプリケーションプロパティファイルに設定されている取得用キーを使用して、画面IDを取得する
	 * @param req HttpServletRequestオブジェクト
	 * @return 画面ID
	 */
	private String getGamenId(HttpServletRequest req)
	{
		// 画面ID取得キーの取得
		// ユーザーサポート又はマイポータルからのURLパラメータに含まれる画面IDを取得するためのキー
		String gamenIdKey = JCCWebCommon.getApplicationConst(GAMEN_ID_KEY);
		if (null == gamenIdKey || "".equals(gamenIdKey))
		{
			throw new JCCFrameworkException("画面ID取得用キーGAMEN_ID_KEYがアプリケーションプロパティから取得できません。");
		}
		// 画面IDの抽出
		String gamenId = req.getParameter(gamenIdKey);
		// 画面IDを元に、連携IDを取得
		return gamenId;
	}
}