/*********************************************************************
*   All Right reserved,Copyright (c) K-Opticom 
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JECH0051D011TPMA
*   ソースファイル名：JECH0051D011TPMA.java
*   作成者          ：富士通
*   日付            ：2011年11月17日
*＜機能概要＞
*   随時請求登録顧客独自処理部品
*＜修正履歴＞
*   バージョン  修正日      修正者      修正内容
*   v1.00.00    2011/11/17  富士通      新規作成
*   v4.00.00    2012/12/19  FJ          【ST4-2012-0000141】性能改善
*   v5.00.00    2013/07/05  FJ)小野     【IT2-2013-0000589】随時入金登録時、未収額に充当額と同じ値が更新されている障害を修正。未収額は0で登録する。
*	v8.00.00	2013/12/25  FJ)小野     【ANK-1584-00-00】MVNO（本体）対応
*	v8.00.01    2014/02/20  FJ)江森     【OM-2014-0000814】整理番号内同一料金コース別サービス契約番号の表示順不正対応
*	v8.00.02    2014/02/24	FJ)小野     【ANK-1589-00-00】消費税に伴う料金施策により、ソート順変更。
*	v8.00.03	2014/03/12	FJ) 林		【TG1-2014-0000004】消費税に伴う料金施策（増税対応）
*	v8.00.04	2014/04/25	FJ) 林      【OM-2014-0001671】会社別合計内訳マイナス金額チェック削除対応
*	v9.00.00	2014/05/29	FJ)江森     【IT1-2014-0000164】製造番号を取得する基準日を修正。
*	v9.00.01	2014/06/02	FJ)江森     【OM-2013-0005201】随時請求で一時金を登録するように修正。
*	v9.00.02	2014/08/15  FJ)桑島     【OM-2014-0002355】ID番号コンボのソート順を修正。登録データの料金グループコードの修正。
*	v10.00.00	2014/08/29  FJ)江森     【OM-2014-0001880,IT2-2014-000167】支払証明書の消費税不正対応。
*	v11.00.00	2014/11/21	FJ)古田    【OM-2014-0003587】ニッテレ債権委託対応
*	v36.00.00	2018/02/03	FJ)清原     【ANK-3296-00-00】標準工事費分割請求
**********************************************************************/

package eo.ejb.cbs.mainproc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.fujitsu.futurity.model.base.CAANConnectionMgr;
import com.fujitsu.futurity.model.base.CAANException;
import com.fujitsu.futurity.model.base.CAANJDBCUtil;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANRuntimeException;
import com.fujitsu.futurity.model.ejb.common.JSYejbConnection;
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.JCRSortComparator;
import eo.common.util.JCRUtilCommon;
import eo.common.util.JPCEditString;
import eo.ejb.cbm.entity.CH0401ETMsg;
import eo.ejb.cbm.entity.CH0501ETMsg;
import eo.ejb.cbs.cbsmsg.ECH0051D011CBSMsg;
import eo.ejb.cbs.cbsmsg.ECH0101D011CBSMsg;
import eo.ejb.common.JCCModelCommon;
import eo.ejb.common.JCHModelCommon;
import eo.ejb.common.JCHModelConst;
import eo.ejb.common.JPCModelCommon;
import eo.ejb.common.db.JCHejbAC0171SecProc;
import eo.ejb.common.db.JCHejbCH0011SecProc;
import eo.ejb.common.db.JCHejbCH0021SecProc;
import eo.ejb.common.db.JCHejbCH0101SecProc;
import eo.ejb.common.db.JCHejbCH0761SecProc;
import eo.ejb.common.entity.JCHejbCH0101KRCK;

/**
 * <p>
 * 随時請求登録顧客独自処理部品
 * </p>
 * @author 富士通
 */
public class JECH0051D011TPMA implements TemplateMainHandler
{

	/**
	 * コンストラクタです。
	 */
	public JECH0051D011TPMA()
	{
		super();
	}
	
	/** 料金調整登録用一覧内部データ（料金グループコード） */
	private static final String PRC_GRP_CD = "prc_grp_cd";
	
	/** 料金調整登録用一覧内部データ（料金コースコード） */
	private static final String PCRS_CD = "pcrs_cd";
	
	/** 料金調整登録用一覧内部データ（料金サービスコード） */
	private static final String PRC_SVC_CD = "prc_svc_cd";
	
	/** 料金調整登録用一覧内部データ（料金項目コード） */
	private static final String PRC_KMK_CD = "prc_kmk_cd";
	
	/** 随時請求登録用一覧内部データ（金額） */
	private static final String AMNT = "amnt";

	/** 消費税計算対象料金項目コード */
	public static final String TAX_CAL_PRC_KMK_CD = "tax_cal_prc_kmk_cd";
	
	/** 一時金登録用タイムスタンプ */
	private static final String ICJKN_DTM = "icjkn_dtm";
	
	/** 一時金登録用訂正区分 */
	private static final String TEISEI_KBN = "teisei_kbn";
	
	/** 一時金登録用訂正区分（調整） */
	private static final String ADJ = "adj";
	
	/** 一時金登録用訂正区分（変更） */
	private static final String CHG = "chg";
	
	/**
	 * <p>
	 * 随時請求登録顧客独自処理部品 <br>
	 * 随時請求登録時に請求先単位合計明細、会社単位合計明細、サービスID単位合計明細を作成する。
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @throws CAANException
	 */
	public static void invoke(CAANMsg inCBSMsg, AgentDispatchContext inContext) throws CAANException
	{
		/** 基準日（料金スケジュール定義の利用終了日）取得処理 */
		String[] useYmdArray = JCHModelCommon.getUseYmd(inCBSMsg, "2", inCBSMsg.getString("seiky_ym"));
		inCBSMsg.setPrivate(JCHModelConst.STANDARD_DAY, useYmdArray[1]);
		
		JCHejbCH0101SecProc ch0101ScPrc = new JCHejbCH0101SecProc();
		
		//v36.00.00 ANK-3296-00-00 Add Start
		/** InputListマージ処理 */
		CAANMsg[] caECH0101CBSMsg3List = inCBSMsg.getCAANMsgList(ECH0051D011CBSMsg.ECH0051D011CBSMSG3LIST);
		if (caECH0101CBSMsg3List!= null)
		{
			ch0101ScPrc.margeInputList2(inCBSMsg,  ECH0051D011CBSMsg.ECH0051D011CBSMSG1LIST,  ECH0051D011CBSMsg.ECH0051D011CBSMSG3LIST);
		}
		//v36.00.00 ANK-3296-00-00 Add End
		
		/** 料金集計 初期処理 */
		HashMap<String, Object> initMsp = ch0101ScPrc.init(inCBSMsg, inContext, ECH0051D011CBSMsg.ECH0051D011CBSMSG1LIST);
		
		/** 料金集計 主処理 */
		ArrayList<CAANMsg> alPrcShukResltList = ch0101ScPrc.main(inCBSMsg, inContext, initMsp);
		
		/** 随時請求登録時のチェック処理 */
		if(!isCheck(inCBSMsg, inContext, alPrcShukResltList))
		{
			return;
		}
		
		// 機能コード判定
		if ("1".equals(inCBSMsg.getObject(ECH0051D011CBSMsg.FUNC_CODE).toString()))
		{
			/** 登録処理を行う。 */
			execute(inCBSMsg, inContext, alPrcShukResltList);
		}
		else
		{
			/** 随時請求登録明細（表示用）料金項目出力名称を設定 */
			ArrayList<CAANMsg> alECH0051D011CBSMsg2List = makePrcKmkMn(inCBSMsg, inContext, alPrcShukResltList, initMsp);
			
			/** ソート処理を行う */ //TODO ソート条件足りてる？
			alECH0051D011CBSMsg2List = sort(alECH0051D011CBSMsg2List);
			
			/** 請求明細の編集を行う */
			ArrayList<CAANMsg> retOutList = editSeikyuMeisai(inCBSMsg, inContext, alECH0051D011CBSMsg2List);
			
			//v36.00.00 ANK-3296-00-00 Mod Start
//			// 随時請求登録明細（表示用）を設定する。
//			inCBSMsg.set(ECH0051D011CBSMsg.ECH0051D011CBSMSG2LIST, (CAANMsg[])retOutList.toArray(new CAANMsg[0]));
			/** 返却リスト作成処理（ECH0101D011CBSMsg4List） */
			CAANMsg[] outMsg = (CAANMsg[])retOutList.toArray(new CAANMsg[0]);
			if (caECH0101CBSMsg3List!= null)
			{
				/** OutputList分離処理 */
				ch0101ScPrc.divideOutputList2(inCBSMsg, outMsg, ECH0051D011CBSMsg.ECH0051D011CBSMSG3LIST, ECH0051D011CBSMsg.ECH0051D011CBSMSG2LIST,  ECH0051D011CBSMsg.ECH0051D011CBSMSG4LIST);
			}
			//v36.00.00 ANK-3296-00-00 Mod End
		}
	}
	
	/**
	 * <p>
	 * 取得した料金情報を表示順でソートします。
	 * </p>
	 * @param alECH0051D011CBSMsg2List 料金情報
	 * @return 表示順でソートされた料金情報のリスト
	 */
	private static ArrayList<CAANMsg> sort(ArrayList<CAANMsg> alECH0051D011CBSMsg2List)
	{
		// ソート順設定
//		for (CAANMsg outMsg: alECH0051D011CBSMsg2List)
//		{
//			// 整理番号
//			String seiriNo = outMsg.getString(ECH0051D011CBSMsg2List.SEIRI_NO_OUT);
//			// 表示順
//			String dispJun = outMsg.getString(ECH0051D011CBSMsg2List.DSP_JUN);
//			// 表示順（先頭1文字）デフォルト
//			String dispJunTop = "2";
//			
//			if (JACStrConst.SEIRI_NO_SP.equals(seiriNo))
//			{
//				// 表示順（先頭1文字）
//				dispJunTop = JPCEditString.fillZero(dispJun, 9, false).substring(0, 1);
//			}
//			// ソート順
//			StringBuffer sortJun = new StringBuffer();
//			sortJun.append(dispJunTop).append(seiriNo).append(dispJun);
//
//			outMsg.setPrivate("sort_jun", sortJun.toString());
//		}
//		
//		Collections.sort(alECH0051D011CBSMsg2List, new Comparator<CAANMsg>()
//		{
//
//			/**
//			 * <p>
//			 * ２つのオブジェクトの大小比較を行う。 <br>
//			 * </p>
//			 * @param obj1 比較対象１
//			 * @param obj2 比較対象２
//			 * @return int値
//			 */
//			public int compare(CAANMsg obj1, CAANMsg obj2)
//			{
//				return obj1.getString("sort_jun").compareTo(obj2.getString("sort_jun"));
//			}
//		});
		
		for (CAANMsg outMsg: alECH0051D011CBSMsg2List)
		{
			String seiriNo = outMsg.getString("seiri_no_out");           // 整理番号
			String dispJun = outMsg.getString("dsp_jun");                // 表示順
			String prcGrpCd = outMsg.getString("prc_grp_cd_out");        // 料金グループコード
			String svcKeiNo = outMsg.getString("svc_kei_no_out");        // サービス契約番号
			String roomNo = outMsg.getString("kaisen_place_adrrm_out");  // 部屋番号
			String svcDtlSkbtNo = outMsg.getString("svc_dtl_skbt_no_out"); // サービス詳細識別番号
			String seikyUcwkNo = outMsg.getString("seiky_ucwk_no_out");		// 請求内訳番号
			String prcKmkCd = outMsg.getString("prc_kmk_cd_out");		// 料金項目コード

			if (!JCRUtilCommon.isNull(svcKeiNo))
			{
//				String savedRoomNo = (String)roomNoMap.get(svcKeiNo);
//				roomNo = savedRoomNo;
			}

			if (dispJun == null)
			{
				dispJun = "0";
			}

			if (roomNo == null)
			{
				roomNo = "0";
			}

			if (svcDtlSkbtNo == null || JACStrConst.SVC_DTL_SKBT_NO_SP.equals(svcDtlSkbtNo))
			{
				svcDtlSkbtNo = "00000000000";
			}

			// 表示順（料金項目種類）
			String dispJunPrcKind = "2";
			if (JACStrConst.SEIRI_NO_SP.equals(seiriNo))
			{
				dispJunPrcKind = JPCEditString.fillZero(dispJun, 9, false).substring(0, 1);
				
				if ("3".equals(dispJunPrcKind))
				{
					dispJunPrcKind = "2";
				}
			}

			// マンション区分
			String mansionKbn = "0";
			if (!JACStrConst.SEIRI_NO_SP.equals(seiriNo) && seiriNo.trim().length() == 10)
			{
				mansionKbn = "1";
			}

			// 整理番号
			if ("4".equals(JPCEditString.fillZero(dispJun, 9, false).substring(0, 1)))
			{
				seiriNo = JACStrConst.SEIRI_NO_SP;
			}
			
			// 表示順（料金コース）
			String dispJunPcrs = JPCEditString.fillZero(dispJun, 9, false).substring(0, 5);

			// 部屋番号
			if ("99".equals(prcGrpCd) && "9999999999".equals(svcKeiNo))
			{
				roomNo = "zzzzz";
			}
			else if (roomNo == null)
			{
				roomNo = "     ";
			}
			else
			{
				roomNo = JPCEditString.fillZero(roomNo, 5, false);
			}

			// サービス契約番号（表示順（料金項目種類）が"2"の時のみ、条件に加える）
			if (!"2".equals(dispJunPrcKind))
			{
				svcKeiNo = "          ";
			}

			// 料金項目種類
			String prcKmkCdKind = prcKmkCd.substring(0, 1);

			outMsg.setPrivate("sort_Jun_1", dispJunPrcKind);
			outMsg.setPrivate("sort_Jun_3", mansionKbn);
			outMsg.setPrivate("sort_Jun_4", seiriNo);
			outMsg.setPrivate("sort_Jun_5", dispJunPcrs);
			outMsg.setPrivate("sort_Jun_6", roomNo);
			outMsg.setPrivate("sort_Jun_7", svcKeiNo);
			outMsg.setPrivate("sort_Jun_8", svcDtlSkbtNo);
			outMsg.setPrivate("sort_Jun_9", prcKmkCdKind);
			outMsg.setPrivate("sort_Jun_10", seikyUcwkNo);
		}
		
		if (!alECH0051D011CBSMsg2List.isEmpty())
		{
			String[] sortTargetList = new String[] {
					"sort_Jun_1",
					"gsan_seiky_ym",
					"sort_Jun_3",
					"sort_Jun_4",
					"sort_Jun_5",
					"sort_Jun_6",
					"sort_Jun_7",
					"sort_Jun_8",
					"dsp_jun",
					"sort_Jun_9",
					"sort_Jun_10"};

			int [] sortTypeList = new int[] {
					JCRSortComparator.SORT_TYPE_ASC,
					JCRSortComparator.SORT_TYPE_DESC,
					JCRSortComparator.SORT_TYPE_ASC,
					JCRSortComparator.SORT_TYPE_ASC,
					JCRSortComparator.SORT_TYPE_ASC,
					JCRSortComparator.SORT_TYPE_ASC,
					JCRSortComparator.SORT_TYPE_ASC,
					JCRSortComparator.SORT_TYPE_ASC,
					JCRSortComparator.SORT_TYPE_ASC,
					JCRSortComparator.SORT_TYPE_DESC,
					JCRSortComparator.SORT_TYPE_ASC};

			int [] sortItemTypeList = new int[] {
					JCRSortComparator.SORT_ITEM_TYPE_CHAR,
					JCRSortComparator.SORT_ITEM_TYPE_CHAR,
					JCRSortComparator.SORT_ITEM_TYPE_CHAR,
					JCRSortComparator.SORT_ITEM_TYPE_CHAR,
					JCRSortComparator.SORT_ITEM_TYPE_CHAR,
					JCRSortComparator.SORT_ITEM_TYPE_CHAR,
					JCRSortComparator.SORT_ITEM_TYPE_CHAR,
					JCRSortComparator.SORT_ITEM_TYPE_CHAR,
					JCRSortComparator.SORT_ITEM_TYPE_CHAR,
					JCRSortComparator.SORT_ITEM_TYPE_CHAR,
					JCRSortComparator.SORT_ITEM_TYPE_CHAR};

			Collections.sort(alECH0051D011CBSMsg2List, new JCRSortComparator(sortTargetList, sortTypeList, sortItemTypeList));
		}
		
		return alECH0051D011CBSMsg2List;
	}
	
	

	/**
	 * <p>
	 * 随時請求登録時の関連制約チェックを行う。 <br>
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param inDtMsgList 随時請求登録明細（表示用）
	 * @return boolean [true:エラーなし,false:エラーあり]
	 */
	private static boolean isCheck(CAANMsg inCBSMsg, AgentDispatchContext inContext, ArrayList<CAANMsg> inDtMsgList)
	{
		
		//OM-2014-0002355 MOD START
		CAANMsg[] inDtCBSMsg1List = inDtMsgList.toArray(new CAANMsg[inDtMsgList.size()]);
		
		// サービス契約番号の存在チェック
//		if (!JCHejbCH0101KRCK.isZuijiSeiCheck000(inCBSMsg, inContext, inDtMsgList))
//		{
		if (!JCHejbCH0101KRCK.isPrcAdjCheck004(inCBSMsg, inContext, inDtCBSMsg1List))
		{
		//OM-2014-0002355 MOD END	
			
			// サービス契約番号が1件でも存在しない場合、随時請求登録明細のエラー項目に"EA"を設定する。
			inCBSMsg.set(ECH0051D011CBSMsg.ECH0051D011CBSMSG1LIST_ERR, "EA");
			inCBSMsg.set(ECH0051D011CBSMsg.STATUS, StatusCodes.RELATION_ERR);
			return false;
		}

		// 処理対象リストから請求先合計を取得
		String seikyGokei = JCHejbCH0101KRCK.getSeikyGokei(inCBSMsg, inContext, inDtMsgList, JACStrConst.KEY_PRC_SHUK_AMNT);

		// 請求先合計内訳マイナス金額チェック
		if (!JCHejbCH0101KRCK.isZuijiSeiCheck001(inCBSMsg, inContext, seikyGokei))
		{
			// 請求先合計が0以下である場合、随時請求登録明細のエラー項目に"EB"を設定する。
			inCBSMsg.set(ECH0051D011CBSMsg.ECH0051D011CBSMSG1LIST_ERR, "EB");
			inCBSMsg.set(ECH0051D011CBSMsg.STATUS, StatusCodes.RELATION_ERR);
			return false;
		}

		// 請求額合計、入金額、預り金チェック
		// 入金額、預り金額を取得。
		String sNyukinAmnt = inCBSMsg.getString(ECH0051D011CBSMsg.NYUKIN_AMNT);
		String sAzukariAmnt = inCBSMsg.getString(ECH0051D011CBSMsg.AZUKARI_AMNT);

		// 入金額、預り金いづれか設定されている場合
		if (!(sNyukinAmnt == null && sAzukariAmnt == null))
		{
			// 預り金設定判定
			if (sAzukariAmnt == null)
			{
				if (sNyukinAmnt != null)
				{
					// 預り金が設定されていない場合、請求額合計と入金額のチェックを行う。
					if (!JCHejbCH0101KRCK.isZuijiSeiCheck003(inCBSMsg, inContext, seikyGokei, sNyukinAmnt))
					{
						// エラーの場合、随時請求登録明細のエラー項目に"ED"を設定する。
						inCBSMsg.set(ECH0051D011CBSMsg.ECH0051D011CBSMSG1LIST_ERR, "ED");
						inCBSMsg.set(ECH0051D011CBSMsg.STATUS, StatusCodes.RELATION_ERR);
						return false;
					}
				}
			}
			else
			{
				if (sNyukinAmnt != null)
				{
					// 預り金が設定されている場合、入金額、請求額のチェックを行う。
					if (!JCHejbCH0101KRCK.isZuijiSeiCheck003(inCBSMsg, inContext, seikyGokei, sNyukinAmnt))
					{
						// エラーの場合、随時請求登録明細のエラー項目に"EE"を設定する。
						inCBSMsg.set(ECH0051D011CBSMsg.ECH0051D011CBSMSG1LIST_ERR, "EE");
						inCBSMsg.set(ECH0051D011CBSMsg.STATUS, StatusCodes.RELATION_ERR);
						return false;
					}
					
					// 入金額と預り金のチェックを行う。
					if (!JCHejbCH0101KRCK.isZuijiSeiCheck004(sNyukinAmnt, sAzukariAmnt))
					{
						// エラーの場合、随時請求登録明細のエラー項目に"EF"を設定する。
						inCBSMsg.set(ECH0051D011CBSMsg.ECH0051D011CBSMSG1LIST_ERR, "EF");
						inCBSMsg.set(ECH0051D011CBSMsg.STATUS, StatusCodes.RELATION_ERR);
						return false;
					}
				}
			}
		}

		// 機器製造番号チェック
		if (!JCHejbCH0101KRCK.isZuijiSeiCheck005(inCBSMsg, inContext, inCBSMsg.getString(JCHModelConst.STANDARD_DAY)))
		{
			// エラーの場合、随時請求登録明細のエラー項目に"EG"を設定する。
			inCBSMsg.set(ECH0051D011CBSMsg.ECH0051D011CBSMSG1LIST_ERR, "EG");
			inCBSMsg.set(ECH0051D011CBSMsg.STATUS, StatusCodes.RELATION_ERR);
			return false;
		}

		return true;
	}
	
	/**
	 * <p>
	 * 料金項目出力名称を検索し随時請求登録明細（表示用）を作成する。 <br>
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param inDtMsgList 料金計算結果内部データ
	 * @param initMsp 初期処理マスタデータ
	 * @return 随時請求登録明細（表示用）
	 */
	private static ArrayList<CAANMsg> makePrcKmkMn(CAANMsg inCBSMsg, AgentDispatchContext inContext,
			ArrayList<CAANMsg> inDtMsgList, HashMap<String, Object> initMsp)
	{
		
		// 随時請求登録明細（表示用）の生成
		ArrayList<CAANMsg> ayECH0051D011CBSMsg2List = new ArrayList<CAANMsg>();
		
		JCHejbCH0101SecProc ch0101ScPrc = new JCHejbCH0101SecProc();
		
		// 表示用料金項目
		String workParamSetteValue = JCHModelCommon.getWorkParam(JACStrConst.WKPARA_CH_CH_WKS_PRC_ADJ_DSP);

		// コネクション
		Connection con1 = null;

		// プリペアステートメント
		PreparedStatement pstmt1 = null;

		// リザルトセット
		ResultSet rsltQuery = null;

		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(CH0401ETMsg.getTableName());

			// SQL文の作成
			String sql = JCHModelCommon.getExistsPrcKmkCdSql().toString();

			//prepareStatementにSQL文をセット
			pstmt1 = con1.prepareStatement(sql);

			// 運用日付
			String opeDate = (String)JPCModelCommon.getOpeDate(inCBSMsg, inContext, null);

			// 料金項目コード取得（債権額）
			String sSaikenPrcKmkCd = ch0101ScPrc.getPrcKmkCd(inCBSMsg, inContext, JACStrConst.WKPRA_CH_WKS_SAIKEN_AMNT);
			// 料金項目コード取得（債権うち消費税額）
			HashMap<String, String> staxPrcKmkCdMap  = ch0101ScPrc.getPrcKmkCdMap(inCBSMsg, inContext, JACStrConst.WKPRA_CH_WKS_SAIKEN_U_STAX);

			String saikenAmnt = "0";
			String staxAmnt = "0";

			// 料金計算結果内部データ分、料金項目出力名称を取得する。
			for(CAANMsg inDtMsg : inDtMsgList)
			{
				// 債権額の設定
				if (sSaikenPrcKmkCd.equals(inDtMsg.getString(PRC_KMK_CD)))
				{
					saikenAmnt = inDtMsg.getString(AMNT);
				}
				// 債権うち消費税額の設定
				if (staxPrcKmkCdMap.size() > 0 && staxPrcKmkCdMap.containsKey(inDtMsg.getString(PRC_KMK_CD)))
				{
					staxAmnt = JCHCommonFormatUtil.calcAdd(staxAmnt, inDtMsg.getString(AMNT), true);
					staxPrcKmkCdMap.remove(inDtMsg.getString(PRC_KMK_CD));
				}
				
				// 表示用料金項目に存在しない場合、処理迂回
				if (!JCHModelCommon.isExistsPrcKmkCd(inCBSMsg, inContext, con1, pstmt1, rsltQuery, inDtMsg, opeDate, workParamSetteValue))
				{
					continue;
				}

				// システムコードを設定
				inCBSMsg.setPrivate("sys_cd", JACStrConst.SYS_CD_CH);

				// 料金項目出力名称を取得する。
				CAANMsg msgCH0391 = ch0101ScPrc.getPrcKmkNmForZuiji(inCBSMsg, inContext, inDtMsg, initMsp);

				ayECH0051D011CBSMsg2List.add(msgCH0391);
			}

			inCBSMsg.set(ECH0051D011CBSMsg.SEIKY_AMNT, saikenAmnt);
			inCBSMsg.set(ECH0051D011CBSMsg.STAX_AMNT, staxAmnt);

			return ayECH0051D011CBSMsg2List;
		}
		catch (SQLException e)
		{
			inCBSMsg.set(CH0401ETMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw new CAANRuntimeException(e);
		}
		finally 
		{
			// 資源の解放
			try
			{
				if(rsltQuery != null)
				{
					rsltQuery.close();
				}
				if(pstmt1 != null)
				{
					pstmt1.close();
				}
				if(con1 != null)
				{
					CAANConnectionMgr.getInstance().close(con1);
				}
			}
			catch(SQLException e)
			{
				inCBSMsg.set(ECH0051D011CBSMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}
	}

	/**
	 * <p>
	 * 請求内訳の編集を行う。<br>
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param alECH0051D011CBSMsg2List 料金計算結果内部データ
	 * @return 編集後請求内訳データ
	 * @throws CAANException
	 */
	private static ArrayList<CAANMsg> editSeikyuMeisai(CAANMsg inCBSMsg, AgentDispatchContext inContext,
			ArrayList<CAANMsg> alECH0051D011CBSMsg2List) throws CAANException
	{
		JCHejbCH0101SecProc ch0101ScPrc = new JCHejbCH0101SecProc();
		
		ArrayList<CAANMsg> outAyList = ch0101ScPrc.eitSeikyuMeisai(inCBSMsg, inContext, alECH0051D011CBSMsg2List);
		
		return outAyList;
	}
	
	/**
	 * <p>
	 * 随時請求登録時に請求内訳、債権内訳の登録を行う。<br>
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param inDtMsgList 料金計算結果内部データ
	 */
	private static void execute(CAANMsg inCBSMsg, AgentDispatchContext inContext, ArrayList<CAANMsg> inDtMsgList)
	{

		// 請求内訳副次部品
		JCHejbCH0101SecProc ch0101ScPrc = new JCHejbCH0101SecProc();
		// 債権内訳副次部品
		JCHejbCH0021SecProc ch0021ScPrc = new JCHejbCH0021SecProc();
		// 割賦債権内訳副次部品
		JCHejbCH0761SecProc ch0761ScPrc = new JCHejbCH0761SecProc();
		
		// 請求内訳登録判定用
		String hmSeikUchi = JCHModelCommon.getWorkParam(JACStrConst.WKPARA_CH_WKS_SIKYAD_SIKYUW);
		// 債権内訳登録判定用
		String hmSaikUchi = JCHModelCommon.getWorkParam(JACStrConst.WKPARA_CH_WKS_SIKYAD_SKNUW);
		// 割賦債権内訳登録判定用
		String hmKapSaikUchi = JCHModelCommon.getWorkParam(JACStrConst.WKPRA_CH_WKS_KAP_SKNUW);

		// コネクション
		Connection con1 = null;

		// プリペアステートメント
		PreparedStatement pstmt1 = null;

		// リザルトセット
		ResultSet rsltQuery = null;

		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(CH0401ETMsg.getTableName());

			// SQL文の作成
			String sql = JCHModelCommon.getExistsPrcKmkCdSql().toString();

			//prepareStatementにSQL文をセット
			pstmt1 = con1.prepareStatement(sql);

			// 運用日付
			String opeDate = (String)JPCModelCommon.getOnlineOpeDate(inCBSMsg, null);

			// 未収金額の料金項目コード情報を保持するマップ
			Map<String, String> mishuMap = new HashMap<String, String>();
			
// OM-2014-0001880 ADD START
			// 未収金額の料金項目コード情報を保持するマップ
			Map<String, String> staxMap = new HashMap<String, String>();
// OM-2014-0001880 ADD END

			// 随時入金登録の場合(入金額が設定されている場合)
			if (!inCBSMsg.isNull(ECH0051D011CBSMsg.NYUKIN_AMNT))
			{
				// 料金項目抽出変換マスタを検索し、随時入金未収額に定義されている
				// 料金グループコード、料金コースコード、料金サービスコード、料金項目コードをキーとするマップを作成する(キーのみ使用しvalueは未使用)
				CAANMsg[] mishuList = JCHModelCommon.getPrcKmkCsChge(inCBSMsg, inContext, true, JACStrConst.WKPARA_CH_WKS_ZUIJI_MISYU);

				for (CAANMsg mishuObj: mishuList)
				{
					StringBuilder mishuKey = new StringBuilder();
					mishuKey.append(mishuObj.getString(JACStrConst.KEY_SAIKEN_UCWK_PRC_GRP_CD))
					   .append(mishuObj.getString(JACStrConst.KEY_SAIKEN_UCWK_PCRS_CD))
					   .append(mishuObj.getString(JACStrConst.KEY_SAIKEN_UCWK_PRC_SVC_CD))
					   .append(mishuObj.getString(JACStrConst.KEY_SAIKEN_UCWK_PRC_KMK_CD));
					mishuMap.put(mishuKey.toString(), null);
				}
// OM-2014-0001880 ADD START
				// 料金項目抽出変換マスタを検索し、債権うち消費税額に定義されている
				// 料金グループコード、料金コースコード、料金サービスコード、料金項目コードをキーとするマップを作成する(キーのみ使用しvalueは未使用)
				CAANMsg[] staxList = JCHModelCommon.getPrcKmkCsChge(inCBSMsg, inContext, true, JACStrConst.WKPRA_CH_WKS_SAIKEN_U_STAX);

				for (CAANMsg staxObj: staxList)
				{
					StringBuilder staxKey = new StringBuilder();
					staxKey.append(staxObj.getString(JACStrConst.KEY_SAIKEN_UCWK_PRC_GRP_CD))
					   .append(staxObj.getString(JACStrConst.KEY_SAIKEN_UCWK_PCRS_CD))
					   .append(staxObj.getString(JACStrConst.KEY_SAIKEN_UCWK_PRC_SVC_CD))
					   .append(staxObj.getString(JACStrConst.KEY_SAIKEN_UCWK_PRC_KMK_CD));
					staxMap.put(staxKey.toString(), null);
				}
// OM-2014-0001880 ADD END
			}

			// 請求年月（入力）
			String seikyYm = inCBSMsg.getString("seiky_ym");

			// 随時請求登録の場合(入金額が設定されていない場合)
			if (inCBSMsg.isNull(ECH0051D011CBSMsg.NYUKIN_AMNT))
			{
				// 料金スケジュール定義を取得(会計処理日)
				CAANMsg[] prcScdl = JCHModelCommon.getPrcSchdlContain(inCBSMsg, inContext, JACStrConst.EVENT_CD_KAIK_SHORI_YMD);

				// 次回会計処理日に該当する請求年月
				String nextKaikeiYm = "";
				// 次回会計処理日
				String nextKaikeiYmd = "";

				// 1件のみ取得できる
				if (prcScdl.length > 0)
				{
					nextKaikeiYm = prcScdl[0].getString(CH0501ETMsg.SEIKY_YM);
					nextKaikeiYmd = prcScdl[0].getString(CH0501ETMsg.EVENT_YMD);
				}

				// 指定された請求年月 < 次回会計処理日に該当する請求年月
				if (seikyYm.compareTo(nextKaikeiYm) < 0)
				{
					// 一時金の副次問い合わせ
					JCHejbAC0171SecProc AC0171 = new JCHejbAC0171SecProc();

					// 一時金の登録を行う
					inCBSMsg.setPrivate(ICJKN_DTM, JPCModelCommon.getOpeDateTimeStamp(inCBSMsg, inContext, null));
					
					// 料金スケジュール定義を取得(請求処理日)
					CAANMsg[] prcScdl2 = JCHModelCommon.getPrcSchdlContain(inCBSMsg, inContext, JACStrConst.EVENT_CD_SEIKY_SHORI_YMD);
					
					// 次回請求処理日
					String nextseikyYmd = "";
					
					// 1件のみ取得できる
					if (prcScdl.length > 0)
					{
						nextseikyYmd = prcScdl2[0].getString(CH0501ETMsg.EVENT_YMD);
					}
					
					// 次回請求処理日 < 次回会計処理日 の場合
					if (nextseikyYmd.compareTo(nextKaikeiYmd) < 0)
					{
						// 料金調整として一時金へ登録する
						inCBSMsg.setPrivate(TEISEI_KBN, ADJ);
					}
					else
					{
						// 料金変更として一時金へ登録する
						inCBSMsg.setPrivate(TEISEI_KBN, CHG);
					}
					
					// 登録明細を取得する。
					CAANMsg[] caanMsgList = inCBSMsg.getCAANMsgList(ECH0051D011CBSMsg.ECH0051D011CBSMSG1LIST);
					for(CAANMsg caIcjknExecute : caanMsgList)
					{
						AC0171.PrcAdjIcjknIns(inCBSMsg, inContext, caIcjknExecute);
					}
				}
			}

			// 料金スケジュール定義から利用開始年月日、利用終了年月日を取得する。
			String useYmdArray[] = JCHModelCommon.getUseYmd(inCBSMsg, "3", seikyYm);
			
// OM-2014-0001880 ADD START
			// 債権うち消費税額
			int saikenUcStax = 0;
// OM-2014-0001880 ADD END
			
			// 料金計算結果内部データ分処理を繰り返す。
			for (CAANMsg inDMsg : inDtMsgList)
			{
				// 請求内訳登録判定用に存在する場合、請求内訳を登録する。
				if (JCHModelCommon.isExistsPrcKmkCd(inCBSMsg, inContext, con1, pstmt1, rsltQuery, inDMsg, opeDate, hmSeikUchi))
				{
					// 請求内訳登録処理
					ch0101ScPrc.insSeikyUcwk(inCBSMsg, inContext, inDMsg, useYmdArray);
				}

				// 債権内訳登録判定用に存在する場合、債権内訳を登録する。
				if (JCHModelCommon.isExistsPrcKmkCd(inCBSMsg, inContext, con1, pstmt1, rsltQuery, inDMsg, opeDate, hmSaikUchi))
				{
					// 随時入金登録の場合(入金額が設定されている場合)
					if (!inCBSMsg.isNull(ECH0051D011CBSMsg.NYUKIN_AMNT))
					{
						// 料金計算結果内部データの料金グループコード、料金コースコード、料金サービスコード、料金項目コードをキーとする
						StringBuilder key = new StringBuilder();
						key.append(inDMsg.getString(PRC_GRP_CD))
						   .append(inDMsg.getString(PCRS_CD))
						   .append(inDMsg.getString(PRC_SVC_CD))
						   .append(inDMsg.getString(PRC_KMK_CD));

						// 随時入金未収額に定義されている場合、金額をゼロにする
						if (mishuMap.containsKey(key.toString()))
						{
							inDMsg.setPrivate(AMNT, "0");
						}

// OM-2014-0001880 ADD START
						// 債権うち消費税額に定義されている場合、債権うち消費税額に加算する
						if (staxMap.containsKey(key.toString()))
						{
							saikenUcStax += Integer.valueOf(inDMsg.getString(AMNT));
						}
// OM-2014-0001880 ADD END
					}
					
// OM-2014-0001880 ADD START
					// 債権うち消費税額を設定
					inCBSMsg.set(ECH0051D011CBSMsg.STAX_AMNT, String.valueOf(saikenUcStax));
// OM-2014-0001880 ADD START

					// 債権内訳登録処理
					ch0021ScPrc.insSaikenUcwk(inCBSMsg, inContext, inDMsg);
				}

				// 割賦債権内訳登録判定用に存在する場合、割賦債権内訳を登録する。
				if (JCHModelCommon.isExistsPrcKmkCd(inCBSMsg, inContext, con1, pstmt1, rsltQuery, inDMsg, opeDate, hmKapSaikUchi))
				{
					// 割賦契約番号取得
					String kapKeiNo = JCHModelCommon.getkapkeiNo(inCBSMsg, inContext, inDMsg.getString(JACStrConst.KEY_PRC_SHUK_SVC_DTL_SKBT_NO), opeDate);
					if (!JCRUtilCommon.isNull(kapKeiNo))
					{
						// 割賦契約番号をセット
						inDMsg.setPrivate(JCHModelConst.KEY_KAP_KEI_NO, kapKeiNo);

						// 割賦債権内訳登録処理
						ch0761ScPrc.executePrcAdjInsert(inCBSMsg, inContext, inDMsg);
					}
				}
			}

			
/* ++++++++++ v11.00.00 追加開始 ++++++++++ */
			// 債権取扱コードを取得します。
			String saikenTakCd = ch0101ScPrc.getSaikenToriatukaiCd(inCBSMsg, inContext);
			
			// 債権取扱コードの反映
			// 債権の副次問い合わせ
			JCHejbCH0011SecProc CH0011 = new JCHejbCH0011SecProc();
			
			// 債権の更新を行う(債権取扱コード)
			CH0011.executePrcAdjSaikenSaikenTakCd(inCBSMsg, inContext, saikenTakCd);
			
/* ++++++++++ v11.00.00 追加完了 ++++++++++ */
			
			// 入金額が設定されている場合、債権内訳に充当額合計を登録
			if (!inCBSMsg.isNull(ECH0051D011CBSMsg.NYUKIN_AMNT))
			{
				insSaikenUcwk(inCBSMsg, inContext);
			}
		}
		catch (SQLException e)
		{
			inCBSMsg.set(CH0401ETMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw new CAANRuntimeException(e);
		}
		finally 
		{
			// 資源の解放
			try
			{
				if(rsltQuery != null)
				{
					rsltQuery.close();
				}
				if(pstmt1 != null)
				{
					pstmt1.close();
				}
				if(con1 != null)
				{
					CAANConnectionMgr.getInstance().close(con1);
				}
			}
			catch(SQLException e)
			{
				inCBSMsg.set(ECH0051D011CBSMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}

	}

	/**
	 * <p>
	 * 債権内訳に充当額合計の登録を行う。<br>
	 * </p>
	 * @param inCBSMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 */
	private static void insSaikenUcwk(CAANMsg inCBSMsg, AgentDispatchContext inContext)
	{
		// コネクション
		Connection con = null;

		// プリペアステートメント
		PreparedStatement pstmt = null;

		// リザルトセット
		ResultSet rsltQuery = null;

		CAANMsg inDMsg = null;
		
		try
		{
			//コネクション取得
			con = JSYejbConnection.getConnection(CH0401ETMsg.getTableName());
			
			String sql = JCHModelCommon.getPrcKmkCsChgeSql(false).toString();
			
			//prepareStatementにSQL文をセット
			pstmt = con.prepareStatement(sql);
			
			int i = 1;
			// パラメータの設定
			CAANJDBCUtil.setParam(pstmt, i++, JACStrConst.SYS_CD_CH);
			CAANJDBCUtil.setParam(pstmt, i++, JACStrConst.CHSHT_CHG_CD_1);
			CAANJDBCUtil.setParam(pstmt, i++, JCCModelCommon.getOpeDate(inCBSMsg, inContext, null));
			CAANJDBCUtil.setParam(pstmt, i++, JACStrConst.WKPRA_CH_WKS_JUTO_GOKEI);
			CAANJDBCUtil.setParam(pstmt, i++, JCCModelCommon.getOpeDate(inCBSMsg, inContext, null));
			
			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();
			
			// 戻り値の判定
			if (rsltQuery.next())
			{
				inDMsg = new CAANMsg();
				inDMsg.setPrivate(PRC_GRP_CD, rsltQuery.getString(CH0401ETMsg.PRC_GRP_CD));
				inDMsg.setPrivate(PCRS_CD, rsltQuery.getString(CH0401ETMsg.PCRS_CD));
				inDMsg.setPrivate(PRC_SVC_CD, rsltQuery.getString(CH0401ETMsg.PRC_SVC_CD));
				inDMsg.setPrivate(PRC_KMK_CD, rsltQuery.getString(CH0401ETMsg.PRC_KMK_CD));
			}
			
			// 料金項目抽出変換マスタが取得できたら、債権内訳に登録
			if (inDMsg != null)
			{
				JCHejbCH0021SecProc ch0021ScPrc = new JCHejbCH0021SecProc();
				
				// 入金額
				inDMsg.setPrivate(AMNT, inCBSMsg.getString(ECH0051D011CBSMsg.NYUKIN_AMNT));
				
				// 債権内訳登録処理
				ch0021ScPrc.insSaikenUcwk(inCBSMsg, inContext, inDMsg);
			}
		}
		catch (SQLException e)
		{
			inCBSMsg.set(CH0401ETMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw new CAANRuntimeException(e);
		}
		finally 
		{
			// 資源の解放
			try
			{
				if(rsltQuery != null)
				{
					rsltQuery.close();
				}
				if(pstmt != null)
				{
					pstmt.close();
				}
				if(con != null)
				{
					CAANConnectionMgr.getInstance().close(con);
				}
			}
			catch(SQLException e)
			{
				inCBSMsg.set(ECH0051D011CBSMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}
	}

}
