/*********************************************************************
*   All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JECH0191C020TPMA
*   ソースファイル名：JECH0191C020TPMA.java
*   作成者          ：富士通
*   日付            ：2011年08月12日
*＜機能概要＞
*   金庫移動登録顧客独自処理部品
*＜修正履歴＞
*   バージョン  修正日      修正者      修正内容
*   v1.00.00    2011/08/12  富士通      新規作成
*   v5.00.00    2013/07/29  FJ) 河井   【IT1-2013-0001477】 移動先金庫番号の更新処理追加
*	v5.00.01	2013/10/09	FJ) 小野   【OM-2013-0003338】金庫移動先が貸倒後入金の場合の債権内訳、督促、督促異動の更新処理を修正。
*	v5.00.02	2013/10/14	FJ) 小野   【OM-2013-0001717】金庫取消時の入金ステータス変更処理を修正。
*	v5.00.03	2013/10/25	FJ) 小野   【OM-2013-0002944】当月の債権に紐づく督促は、督促金額更新の計算対象外とする。
*	v6.00.00	2013/11/24	FJ) 小野   【OM-2013-0003532】入金取消時の入金更新処理の変更に伴い、横並びで金庫取消の入金更新処理を変更。
*	v6.00.01	2014/01/08	FJ) 小野   【OM-2014-0000039】金庫取消時の入金変更処理を修正(入金が更新されない不具合を修正)。
*	v8.00.00	2014/03/18	FJ) 小野   【IT2-2014-0000166】移動元、移動先金庫ステータスが同じ場合で、請求先が変わる場合、移動可否チェックをOKとする。
*	v9.00.00	2014/03/18	FJ) 江森   【OM-2013-0005201】債権内訳の貸倒後入金を更新する際の検索キーに債権番号を追加
*
**********************************************************************/

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.HashMap;
import java.util.List;

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.JSYejbLog;
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.EntityMainHandler;
import com.fujitsu.futurity.model.ejb.common.fw.TemplateMainHandler;

import eo.common.constant.JACStrConst;
import eo.common.util.JCRUtilCommon;
import eo.ejb.cbm.cbmmsg.CH0021CBMMsg;
import eo.ejb.cbm.cbmmsg.CH0191CBMMsg;
import eo.ejb.cbm.entity.CH0021ETMsg;
import eo.ejb.cbm.entity.CH0191ETMsg;
import eo.ejb.cbm.entity.CH0201ETMsg;
import eo.ejb.cbm.entity.CH0231ETMsg;
import eo.ejb.cbm.entity.CH0341ETMsg;
import eo.ejb.cbm.entity.CH0341LE;
import eo.ejb.cbm.entity.CH0361ETMsg;
import eo.ejb.cbm.entity.CH0381ETMsg;
import eo.ejb.cbm.entity.CH0401ETMsg;
import eo.ejb.cbm.entity.CH0501ETMsg;
import eo.ejb.cbm.entity.CK0061ETMsg;
import eo.ejb.cbm.entity.CK0061LE;
import eo.ejb.cbs.cbsmsg.ECH0191C020CBSMsg;
import eo.ejb.cbs.cbsmsg.ECH0191D020CBSMsg;
import eo.ejb.cbs.cbsmsg.ECH0191D020CBSMsg1List;
import eo.ejb.cbs.cbsmsg.ECH0191D020CBSMsg2List;
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.JCHejbCH0021SecProc;
import eo.ejb.common.db.JCHejbCH0191SecProc;
import eo.ejb.common.db.JCHejbCH0201SecProc;
import eo.ejb.common.db.JCHejbCH0231SecProc;
import eo.ejb.common.db.JCHejbCH0361SecProc;
import eo.ejb.common.db.JCHejbCH0381SecProc;
import eo.ejb.common.edit.JCHejbCH0191NumberParts;
import eo.ejb.common.edit.JCHejbCH0201NumberParts;

/**
 * <p>
 * 金庫移動登録時に副次処理を呼び出す部品
 * および、金庫変更登録時に副次処理を呼び出す部品
 * </p>
 * @author 富士通
 */
public class JECH0191C020TPMA implements TemplateMainHandler, EntityMainHandler{

	/** キー：債権番号 */
	private static final String KEY_SAIKEN_NO = "saiken_no";
	/** キー：料金グループコード */
	private static final String KEY_PRC_GRP_CD = "prc_grp_cd";
	/** キー：料金コースコード */
	private static final String KEY_PCRS_CD = "pcrs_cd";
	/** キー：料金サービスコード */
	private static final String KEY_PRC_SVC_CD = "prc_svc_cd";
	/** キー：料金項目コード */
	private static final String KEY_PRC_KMK_CD = "prc_kmk_cd";
	/** キー：金額 */
	private static final String KEY_AMNT = "amnt";
	/** キー：債権確定年月 */
	private static final String KEY_SAIKEN_FIX_YM = "saiken_fix_ym";
	/** キー：オペレータ_ID */
	private static final String KEY_OPERATORID = "operatorID";
	/** 会計内訳コード(スペース12桁) */
	private static final String KAIK_UCWK_CD = "            ";
	/** ダミー値(入金番号／金庫番号) */
	private static final String DUMMY_NO = "000000000000";

	/**
	 * コンストラクタです。
	 */
	public JECH0191C020TPMA()
	{
		super();
	}

	/**
	 * <p>
	 * 入金登録時の債権内訳の更新を行います。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 */
	public static void invoke(CAANMsg inCBSMsg, AgentDispatchContext inContext) throws CAANException
	{
		// パラメタの取得
		String inKnkNo = inCBSMsg.getString(ECH0191D020CBSMsg.KNK_NO);
		String inIdoMtSeiKeiNo = inCBSMsg.getString(ECH0191D020CBSMsg.IDO_MT_SEIKY_KEI_NO);
		String inKnkUpDTM = inCBSMsg.getString(ECH0191D020CBSMsg.KNK_UPD_DTM);
		CAANMsg[] inMsgList = inCBSMsg.getCAANMsgList(ECH0191D020CBSMsg.ECH0191D020CBSMSG1LIST);
		
		// (1) 移動元金庫番号をもとに移動元金庫更新副次処理を呼び出す。
		JCHejbCH0191SecProc ch0191SecProc = new JCHejbCH0191SecProc();
		
		// 移動元金庫番号チェック
		String sErrFlg = isKnkNoCheck(inCBSMsg, inContext, inKnkNo, inKnkUpDTM);
		if(!sErrFlg.equals("")){
			inCBSMsg.set(ECH0191D020CBSMsg.KNK_NO_ERR, sErrFlg);
			inCBSMsg.set(ECH0191D020CBSMsg.STATUS, StatusCodes.RELATION_ERR);
			return;
		}
		
		// 移動元請求番号存在チェック
		if(!"".equals(inIdoMtSeiKeiNo) && inIdoMtSeiKeiNo != null)
		{
			if(!isIdoMtSeiKeiNo(inCBSMsg, inContext, inIdoMtSeiKeiNo)){
				inCBSMsg.set(ECH0191D020CBSMsg.IDO_MT_SEIKY_KEI_NO_ERR, "EC");
				inCBSMsg.set(ECH0191D020CBSMsg.STATUS, StatusCodes.RELATION_ERR);
				return;
			}
		}
		
		// 金庫ステータス移動チェック
		if(!isKnkStateMoveCheck(inCBSMsg, inContext)){
			inCBSMsg.set(ECH0191D020CBSMsg.ECH0191D020CBSMSG1LIST_ERR, "EE");
			inCBSMsg.set(ECH0191D020CBSMsg.STATUS, StatusCodes.RELATION_ERR);
			return;
		}

		// 処理済金（貸倒後入金）の料金項目コードを取得する。
		CAANMsg[] sPrcKmkCdArray = JCHModelCommon.getPrcKmkCsChge(inCBSMsg, inContext, false, JACStrConst.WKPRA_CH_WKS_SRZ_KASHID_AT);
		String ksdrPrcKmkCd = "";
		if (sPrcKmkCdArray.length > 0)
		{
			ksdrPrcKmkCd = sPrcKmkCdArray[0].getString(CH0401ETMsg.PRC_KMK_CD);
		}
		else
		{
			return;
		}

		// 貸倒後入金チェック
		HashMap<String, List<HashMap<String, String>>> mishuMap = new HashMap<String, List<HashMap<String, String>>>();
		if(isKsdrNyukinCheck(inCBSMsg, inContext, mishuMap, ksdrPrcKmkCd))
		{
			return;
		}

		// 機能コード判定
		if(!"1".equals(inCBSMsg.getString(ECH0191D020CBSMsg.FUNC_CODE))){
			return;
		}
		
		// 金庫移動の場合、移動先金庫番号を採番する
		String inKnkNoAf = "";
		if(inMsgList.length == 1)
		{
			inKnkNoAf = JCHejbCH0191NumberParts.getKnkNoOnce(inCBSMsg, inContext);
		}

		// ----------------------------------------------------
		// 移動元金庫を更新する。
		// ----------------------------------------------------
		ch0191SecProc.updateAmnt(inCBSMsg, inContext, inKnkNo, inKnkNoAf);

		// ----------------------------------------------------
		// 移動先が貸倒後入金の場合、債権内訳を更新する(未収額、貸倒後入金額)。
		// また、督促の更新、督促異動の登録、不良顧客情報の取得を行う。
		// ----------------------------------------------------
		ksdrNyukin(inCBSMsg, inContext, inMsgList, mishuMap, ksdrPrcKmkCd);

	}

	/**
	 * <p>
	 * 移動元金庫チェック。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @param inKnkNo 金庫番号
	 * @param inKnkUpDTM 金庫更新年月日時分秒
	 */
	private static String isKnkNoCheck(CAANMsg inCBSMsg, AgentDispatchContext inContext, String inKnkNo, String inKnkUpDTM)
	{
		// 返却エラーフラグ
		String retErrFlg = "";

		// ダミー値の場合はチェック対象外とする
		if (DUMMY_NO.equals(inKnkNo))
		{
			return retErrFlg;
		}

		// 移動元金庫が存在するか確認する。
		if(!isKnkNoExistence(inCBSMsg, inContext, inKnkNo)){
			retErrFlg = "ED";
			return retErrFlg;
		}
		
		// 移動元金庫の排他チェックを行う。
		if(!isKnkSucceededExclusiveLock(inCBSMsg, inContext, inKnkNo, inKnkUpDTM)){
			retErrFlg = "EB";
			return retErrFlg;
		}

		return retErrFlg;
	}
	
	/**
	 * <p>
	 * 移動元請求契約番号存在チェック
	 * </p>
	 * 移動元請求契約番号の存在チェックを行う。
	 * <br>
	 * @param inMsg 処理対象のメッセージ
	 * @param inContext エージェントディスパッチコンテキスト
	 * @param inSeiKeiNo 移動元請求契約番号
	 * @return チェックOK：false、チェックNG：true
	 */
	private static boolean isIdoMtSeiKeiNo(CAANMsg inCBSMsg, AgentDispatchContext inContext, String inSeiKeiNo){
		
		// 戻り値
		boolean bRtn = false;
		// コネクション
		Connection con1 = null;
		// プリペアステートメント
		PreparedStatement pstmt = null;
		// リザルトセット
		ResultSet rsltQuery = null;
		
		int i = 1;
		/******************** 
		 * SQL文の作成
		 ********************/
		try{
			
			//コネクション取得
			con1 = JSYejbConnection.getConnection(CH0191ETMsg.getTableName());
			
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT ")
					.append("     COUNT(*) CNT")
					.append(" FROM ")
					.append("     KK_T_SEIKY_KEI KK0491 ")
					.append(" WHERE ")
					.append("     KK0491.SEIKY_KEI_NO = ?")
					.append(" AND KK0491.RSV_APLY_YMD || KK0491.GENE_ADD_DTM = ")
					.append("          ( SELECT  ")
					.append("                MAX(KK0491_GENE.RSV_APLY_YMD || KK0491_GENE.GENE_ADD_DTM) AS KK0491_MAX")
					.append("            FROM ")
					.append("                KK_T_SEIKY_KEI KK0491_GENE ")
					.append("            WHERE ")
					.append("                KK0491_GENE.SEIKY_KEI_NO = KK0491.SEIKY_KEI_NO ")
					.append("            AND KK0491_GENE.RSV_APLY_YMD <= ? ")
					.append("            AND KK0491_GENE.RSV_APLY_CD = '2' ")
					.append("            AND KK0491_GENE.MK_FLG = '0' ) ");
			
			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());
			
			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, JECH0191C020TPMA.class, sql_Buff);
			
			// パラメータの設定(移動元請求契約番号を指定)
			CAANJDBCUtil.setParam(pstmt, i++, inSeiKeiNo);
			// パラメータの設定(運用日を指定)
			CAANJDBCUtil.setParam(pstmt, i++, JPCModelCommon.getOpeDate(inCBSMsg, inContext, null));
			
			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();
			
			// 戻り値の判定
			if (rsltQuery.next()){
				if(rsltQuery.getLong("CNT")>0){
					bRtn = true;
				}
			}
			
		}catch (SQLException e)	{
			inCBSMsg.set(CH0191CBMMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw new CAANRuntimeException(e);
		}finally{
			// 資源の解放
			try{
				if (rsltQuery != null){
					rsltQuery.close();
				}
				if (pstmt != null){
					pstmt.close();
				}
				if (con1 != null){
					CAANConnectionMgr.getInstance().close(con1);
				}
			}catch(SQLException e){
				inCBSMsg.set(CH0191CBMMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}
		
		return bRtn;
	}
	
	/**
	 * <p>
	 * 移動元金庫番号排他チェック
	 * </p>
	 * 移動元金庫番号の排他チェックを行う。
	 * <br>
	 * @param inMsg 処理対象のメッセージ
	 * @param inContext エージェントディスパッチコンテキスト
	 * @param inItemName 金庫番号の項目名
	 * @return チェックOK：false、チェックNG：true
	 */
	private static boolean isKnkNoExistence(CAANMsg inMsg, AgentDispatchContext inContext, String inKnkNo){
		// 戻り値
		boolean bRtn = false;
		// コネクション
		Connection con1 = null;
		// プリペアステートメント
		PreparedStatement pstmt = null;
		// リザルトセット
		ResultSet rsltQuery = null;
		// パラメータインデックス
		int i = 1;
		/******************** 
		 * SQL文の作成
		 ********************/
		try{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(CH0191ETMsg.getTableName());
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT ")
					.append("  COUNT(*) CNT")
					.append(" FROM ")
					.append("  CH_T_KNK CH0191 ")
					.append(" WHERE ")
					.append("  KNK_NO = ?")
					.append(" AND MK_FLG = '0'");
			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());
			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, JECH0191C020TPMA.class, sql_Buff);
			// パラメータの設定(金庫番号を指定)
			CAANJDBCUtil.setParam(pstmt, i++, inKnkNo);
			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();
			// 戻り値の判定
			if (rsltQuery.next()){
				if(rsltQuery.getLong("CNT")>0){
					bRtn = true;
				}
			}
		}catch (SQLException e)	{
			inMsg.set(CH0191CBMMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw new CAANRuntimeException(e);
		}finally{
			// 資源の解放
			try{
				if (rsltQuery != null){
					rsltQuery.close();
				}
				if (pstmt != null){
					pstmt.close();
				}
				if (con1 != null){
					CAANConnectionMgr.getInstance().close(con1);
				}
			}catch(SQLException e){
				inMsg.set(CH0191CBMMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}
		return bRtn;
	}
	
	/**
	 * <p>
	 * 移動元金庫番号排他チェック
	 * </p>
	 * 移動元金庫番号の排他チェックを行う。
	 * <br>
	 * @param inMsg 処理対象のメッセージ
	 * @param inContext エージェントディスパッチコンテキスト
	 * @param inItemName 移動元金庫更新年月日時分秒の項目名
	 * @return チェックOK：false、チェックNG：true
	 */
	private static boolean isKnkSucceededExclusiveLock(CAANMsg inMsg, AgentDispatchContext inContext, String inKnkNo, String inKnkUpDTM){
		// 戻り値
		boolean bRtn = false;
		// コネクション
		Connection con1 = null;
		// プリペアステートメント
		PreparedStatement pstmt = null;
		// リザルトセット
		ResultSet rsltQuery = null;
		// パラメータインデックス
		int i = 1;
		// 更新年月日時分秒
		String sUpDate = null;
		/******************** 
		 * SQL文の作成
		 ********************/
		try{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(CH0191ETMsg.getTableName());
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT ")
					.append("  CH0191.UPD_DTM ")
					.append(" FROM ")
					.append("  CH_T_KNK CH0191 ")
					.append(" WHERE ")
					.append("  CH0191.KNK_NO = ?")
					.append(" AND CH0191.GENE_ADD_DTM = ")
					.append("          (SELECT MAX(CH0191_GENE.GENE_ADD_DTM) AS CH0191_MAX ")
					.append("             FROM CH_T_KNK CH0191_GENE ")
					.append("            WHERE CH0191_GENE.KNK_NO = CH0191.KNK_NO ")
					.append("              AND CH0191_GENE.MK_FLG = '0') ")
					.append(" AND CH0191.MK_FLG = '0' ");
			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());
			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, JECH0191C020TPMA.class, sql_Buff);
			// パラメータの設定(金庫番号を指定)
			CAANJDBCUtil.setParam(pstmt, i++, inKnkNo);
			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();
			// 戻り値の判定
			if (rsltQuery.next()){
				sUpDate = rsltQuery.getString("UPD_DTM");
			}
		}catch (SQLException e)	{
			inMsg.set(CH0191CBMMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw new CAANRuntimeException(e);
		}finally{
			// 資源の解放
			try{
				if (rsltQuery != null){
					rsltQuery.close();
				}
				if (pstmt != null){
					pstmt.close();
				}
				if (con1 != null){
					CAANConnectionMgr.getInstance().close(con1);
				}
			}catch(SQLException e){
				inMsg.set(CH0191CBMMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}
		
		if(inKnkUpDTM.equals(sUpDate)){
			bRtn = true;
		}
		return bRtn;
	}

	/**
	 * <p>
	 * 金庫ステータス移動チェック
	 * </p>
	 * 移動先金庫料金項目コードへの遷移が可能かチェックする。
	 * <br>
	 * @param inMsg 処理対象のメッセージ
	 * @param inContext エージェントディスパッチコンテキスト
	 * @param KnkNo 金庫番号
	 * @param sKnkPrcKmkCd 金庫料金項目コード
	 * @param sSeikeiNo 移動先請求契約番号の項目名
	 * @param sKnkPrcKmkCdaf 移動先金庫料金項目コードの項目名
	 * @param inKnkMoveMeisai 金庫移動登録明細
	 * @return チェックOK：false、チェックNG：true
	 */
	public static boolean isKnkStateMoveCheck(CAANMsg inCBSMsg, AgentDispatchContext inContext){
		
		// 戻り値
		boolean bRtn = false;
		
		// 運用日付
		String sOpeDate = (String) JPCModelCommon.getOpeDate(inCBSMsg, inContext, null);
		
		// 金庫移動登録明細の取得
		CAANMsg[] inKnkMoveMeisaiList = inCBSMsg.getCAANMsgList(ECH0191D020CBSMsg.ECH0191D020CBSMSG1LIST);
		
		// 移動元金庫料金項目コードの取得
		String inKnkPrcKmkCd = inCBSMsg.getString(ECH0191D020CBSMsg.KNK_PRC_KMK_CD);
		
		// 移動元請求契約番号
		String inSeikyKeiNo = inCBSMsg.getString(ECH0191D020CBSMsg.IDO_MT_SEIKY_KEI_NO);
		
		for(CAANMsg cKnkMoveMeisai : inKnkMoveMeisaiList)
		{
			// 移動先請求契約番号の取得
			String sIdoSkSeikeiNo = cKnkMoveMeisai.getString(ECH0191D020CBSMsg1List.SEIKY_KEI_NO);
			
			// 移動先金庫料金項目コードの取得
			String sKnkPrcKmkCdaf = cKnkMoveMeisai.getString(ECH0191D020CBSMsg1List.KNK_PRC_KMK_CD_AF);
			
			//------------------------------------------
			// 金庫ステータス移動管理.金庫移動可否の取得
			//------------------------------------------
			
			// コネクション
			Connection con1 = null;
			
			// プリペアステートメント
			PreparedStatement pstmt = null;
			
			// リザルトセット
			ResultSet rsltQuery = null;
			
			// パラメータインデックス
			int i = 1;
			
			// 金庫移動可否
			String sKnkIddSkbtCd = null;
			
			/******************** 
			 * SQL文の作成
			 ********************/
			try
			{
				//コネクション取得
				con1 = JSYejbConnection.getConnection(CH0191ETMsg.getTableName());
				StringBuffer sql_Buff = new StringBuffer();
				sql_Buff.append(" SELECT ")
						.append("      CH0671.KNK_IDO_SKBT_CD ")
						.append(" FROM ")
						.append("    CH_M_KNK_STAT_MV_JKN CH0671")
						.append(" WHERE ")
						.append("      CH0671.IDOMOTO_KNK_PRC_KMK_CD = ?")
						.append("  AND CH0671.IDOSAKI_KNK_PRC_KMK_CD = ?")
						.append("  AND CH0671.KNK_STAT_MV_JKN_TSTAYMD <= ? ")
						.append("  AND CH0671.KNK_STAT_MV_JKN_TENDYMD >= ? ")
						.append("  AND CH0671.RSV_APLY_YMD || CH0671.GENE_ADD_DTM = ")
						.append("           ( SELECT ")
						.append("                 MAX(CH0671_GENE.RSV_APLY_YMD || CH0671_GENE.GENE_ADD_DTM) AS CH0671_MAX ")
						.append("             FROM  ")
						.append("                 CH_M_KNK_STAT_MV_JKN CH0671_GENE ")
						.append("             WHERE ")
						.append("                 CH0671_GENE.IDOMOTO_KNK_PRC_KMK_CD = CH0671.IDOMOTO_KNK_PRC_KMK_CD ")
						.append("             AND CH0671_GENE.IDOSAKI_KNK_PRC_KMK_CD = CH0671.IDOSAKI_KNK_PRC_KMK_CD ")
						.append("             AND CH0671_GENE.RSV_APLY_YMD <= ? ")
						.append("             AND CH0671_GENE.MK_FLG = '0' ) ");
				
				//prepareStatementにSQL文をセット
				pstmt = con1.prepareStatement(sql_Buff.toString());
				
				//ログ出力(SQL文の出力)
				JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, JECH0191C020TPMA.class, sql_Buff);
				
				// パラメータの設定(金庫料金項目コードを指定)
				CAANJDBCUtil.setParam(pstmt, i++, inKnkPrcKmkCd);
				
				// パラメータの設定(移動先金庫料金項目コードを指定)
				CAANJDBCUtil.setParam(pstmt, i++, sKnkPrcKmkCdaf);
				
				// パラメータの設定(運用日付を指定)
				CAANJDBCUtil.setParam(pstmt, i++, JPCModelCommon.getOpeDate(inCBSMsg, inContext, null));
				CAANJDBCUtil.setParam(pstmt, i++, JPCModelCommon.getOpeDate(inCBSMsg, inContext, null));
				CAANJDBCUtil.setParam(pstmt, i++, JPCModelCommon.getOpeDate(inCBSMsg, inContext, null));
				
				// ResultSetの取得
				rsltQuery = pstmt.executeQuery();
				
				// 戻り値の判定
				if (rsltQuery.next())
				{
					sKnkIddSkbtCd = rsltQuery.getString("KNK_IDO_SKBT_CD");
				}
			}
			catch (SQLException e)
			{
				inCBSMsg.set(CH0191CBMMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
			finally
			{
				// 資源の解放
				try
				{
					if (rsltQuery != null)
					{
						rsltQuery.close();
					}
					if (pstmt != null)
					{
						pstmt.close();
					}
					if (con1 != null)
					{
						CAANConnectionMgr.getInstance().close(con1);
					}
				}
				catch(SQLException e)
				{
					inCBSMsg.set(CH0191ETMsg.STATUS, StatusCodes.FIND_DB_ERR);
					throw new CAANRuntimeException(e);
				}
			}
			
			// 金庫移動識別コードの判定
			if(JACStrConst.KINKO_IDO_SKBT_CD_FAIL.equals(sKnkIddSkbtCd))
			{
				// 金庫移動識別コードが"0":移動不可の場合、falseを返却
				return bRtn;
			}
			else if(JACStrConst.KINKO_IDO_SKBT_CD_PSB.equals(sKnkIddSkbtCd))
			{
				// 金庫移動識別コードが"1":移動可の場合、次明細のチェックを行う
				continue;
			}
			else if(JACStrConst.KINKO_IDO_SKBT_CD_PSB_SEIKY_NO.equals(sKnkIddSkbtCd))
			{
				// 金庫移動識別コードが"2":条件付移動可(請求契約番号同一)の場合、請求契約番号のチェックを行う。
				if(!inSeikyKeiNo.equals(sIdoSkSeikeiNo))
				{
					// 移動元と移動先の請求契約番号が同一でない場合、falseを返却
					return bRtn;
				}
			}
			else if(JACStrConst.KINKO_IDO_SKBT_CD_PSB_KNK_BNKT.equals(sKnkIddSkbtCd))
			{
				// 金庫移動識別コードが"3":条件付移動可(金庫分割)の場合、金庫分割のチェックを行う
				// ただし移動元請求先と移動先請求先が異なる場合は、移動可能とする。

				// 今回の移動で複数に金庫を移動する場合（金庫分割）チェックOK
				if(inKnkMoveMeisaiList.length <= 1)
				{
					// 移動元請求先が未設定の場合は、チェックOK
					if (!JCRUtilCommon.isNull(inSeikyKeiNo))
					{
						if (inSeikyKeiNo.equals(sIdoSkSeikeiNo))
						{
							// 移動元請求先と移動先請求先が同じ場合は、エラーとする。
							return bRtn;
						}
					}
				}
			}
			else if(JACStrConst.KINKO_IDO_SKBT_CD_PSB_IDO_YMD.equals(sKnkIddSkbtCd))
			{
				// 金庫移動識別コードが"4":条件付移動可(金庫移動月同月)の場合、金庫移動年月日のチェックを行う。
				
				// 金庫移動年月日を取得する。
				String sKnkIdoYMD = getKnkIdoYMD(inCBSMsg, inContext);
				
				// 金庫移動年月日が取得できなかった場合、falseを返却
				if(sKnkIdoYMD == null){
					return bRtn;
				}
				
				// 金庫移動年月日と同月か判定する。
				if(!sOpeDate.substring(0, 6).equals(sKnkIdoYMD.substring(0, 6)))
				{
					// 同月でない場合、falseを返却
					return bRtn;
				}
			}
			else if(JACStrConst.KINKO_IDO_SKBT_CD_PSB_NYUKIN.equals(sKnkIddSkbtCd))
			{
				// 金庫移動識別コードが"5":移動可（入金登録画面からの金庫充当用）の場合、次明細のチェックを行う
				continue;
			}
		}
		// 前明細のチェックがOKの場合、trueを返却
		bRtn = true;
		return bRtn;
	}

	/**
	 * <p>
	 * 貸倒後入金チェック
	 * </p>
	 * 移動先金庫料金項目コードへの遷移が可能かチェックする。
	 * <br>
	 * @param inMsg 処理対象のメッセージ
	 * @param inContext エージェントディスパッチコンテキスト
	 * @param mishuMap 未収情報マップ
	 * @param ksdrPrcKmkCd 金庫料金項目コード(貸倒後入金)
	 * @return チェックOK：false、チェックNG：true
	 */
	public static boolean isKsdrNyukinCheck(CAANMsg inCBSMsg, AgentDispatchContext inContext,
			HashMap<String, List<HashMap<String, String>>> mishuMap, String ksdrPrcKmkCd)
	{
		// 戻り値
		boolean bRtn = false;

		// 金庫移動登録明細の取得
		CAANMsg[] inKnkMoveMeisaiList = inCBSMsg.getCAANMsgList(ECH0191D020CBSMsg.ECH0191D020CBSMSG1LIST);
		for (CAANMsg cKnkMoveMeisai : inKnkMoveMeisaiList)
		{
			// 移動先金庫料金項目コードの取得
			String idoSakiKnkPrcKmkCd = cKnkMoveMeisai.getString(ECH0191D020CBSMsg1List.KNK_PRC_KMK_CD_AF);

			// 移動先金庫料金項目コードが「処理済金（貸倒後入金）」の場合、チェックを実行
			if (ksdrPrcKmkCd.equals(idoSakiKnkPrcKmkCd))
			{
				// 移動先請求契約番号の取得
				String idoSakiSeikyKeiNo = cKnkMoveMeisai.getString(ECH0191D020CBSMsg1List.SEIKY_KEI_NO);
	
				// 債権内訳の未収額レコードをリストで取得（年月の昇順、請求種別コードの昇順、債権番号の昇順、消込定義順にソート済）
				List<HashMap<String, String>> mishuList =
					getSaikenUcwk(inCBSMsg, inContext, idoSakiSeikyKeiNo, JACStrConst.SAIKEN_STAT_KASHID_ADD, JACStrConst.MISYU_NTK, JCHModelConst.SORT_TYPE_NORMAL_ASC);
	
				// 債権ステータスが"080"でない場合エラー
				if (mishuList.isEmpty())
				{
					inCBSMsg.set(ECH0191D020CBSMsg.ECH0191D020CBSMSG1LIST_ERR, "EF");
					inCBSMsg.set(ECH0191D020CBSMsg.STATUS, StatusCodes.RELATION_ERR);
					return true;
				}
	
				long amnt = 0L;
				for (HashMap<String, String> mishuObj : mishuList)
				{
					String mishuAmnt = mishuObj.get(KEY_AMNT);
					amnt += Long.parseLong(mishuAmnt);
				}

				// 未収金額が存在しないまたは、ゼロである場合エラー
				if (amnt <= 0)
				{
					inCBSMsg.set(ECH0191D020CBSMsg.ECH0191D020CBSMSG1LIST_ERR, "EG");
					inCBSMsg.set(ECH0191D020CBSMsg.STATUS, StatusCodes.RELATION_ERR);
					return true;
				}

				// チェックOKの場合、マップを追加する。[key:移動先請求契約番号、value:未収金額リスト]
				mishuMap.put(idoSakiSeikyKeiNo, mishuList);
			}
		}

		return bRtn;
	}

	/**
	 * <p>
	 * 金庫移動年月日を取得する。
	 * </p>
	 * @param inCBSMsg  処理対象のメッセージキャリア
	 * @param inContext ディスパッチコンテキスト
	 * @return retKnkIdoYMD 取得した金庫移動年月日
	 */
	private static String getKnkIdoYMD(CAANMsg inCBSMsg, AgentDispatchContext inContext){
		
		String retKnkIdoYMD = null;
		
		// 移動元金庫番号の取得
		String sKnkNo = inCBSMsg.getString(ECH0191D020CBSMsg.KNK_NO);
		
		// コネクション
		Connection con1 = null;
		
		// プリペアステートメント
		PreparedStatement pstmt = null;
		
		// リザルトセット
		ResultSet rsltQuery = null;

		// パラメータインデックス
		int i = 1;
		
		/******************** 
		 * SQL文の作成
		 ********************/
		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(CH0191ETMsg.getTableName());
			
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT ")
					.append("     CH0191.KNK_IDO_YMD ")
					.append(" FROM ")
					.append("     CH_T_KNK CH0191 ")
					.append(" WHERE ")
					.append("     CH0191.KNK_NO = ? ")
					.append(" AND CH0191.GENE_ADD_DTM = ")
					.append("          ( SELECT ")
					.append("                MAX(CH0191_GENE.GENE_ADD_DTM) AS CH0191_MAX ")
					.append("            FROM ")
					.append("                CH_T_KNK CH0191_GENE ")
					.append("            WHERE ")
					.append("                CH0191_GENE.KNK_NO = CH0191.KNK_NO ")
					.append("            AND CH0191_GENE.MK_FLG = '0') ");
			
			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());
			
			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, JECH0191C020TPMA.class, sql_Buff);
			
			// パラメータの設定(請求契約番号を指定)
			CAANJDBCUtil.setParam(pstmt, i++, sKnkNo);
			
			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();
			
			// 戻り値の判定
			if (rsltQuery.next())
			{
				retKnkIdoYMD = rsltQuery.getString("KNK_IDO_YMD");
			}
		}
		catch (SQLException e)
		{
			inCBSMsg.set(CH0191CBMMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw new CAANRuntimeException(e);
		}
		finally
		{
			// 資源の解放
			try
			{
				if (rsltQuery != null)
				{
					rsltQuery.close();
				}
				if (pstmt != null)
				{
					pstmt.close();
				}
				if (con1 != null)
				{
					CAANConnectionMgr.getInstance().close(con1);
				}
			}
			catch(SQLException e)
			{
				inCBSMsg.set(CH0191ETMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}
		return retKnkIdoYMD;
	}

	/**
	 * <p>
	 * 貸倒登録済の債権内訳を取得する。
	 * 消込順序定義を結合し、処理順のリストを返す。
	 * </p>
	 * @param inCBSMsg  処理対象のメッセージキャリア
	 * @param inContext ディスパッチコンテキスト
	 * @param seikyKeiNo 請求契約番号
	 * @param status 債権ステータスコード
	 * @param workKinoSkbtCd 業務機能識別コード
	 * @param sortType ソートタイプ
	 * @return 債権内訳リスト
	 */
	private static List<HashMap<String, String>> getSaikenUcwk(CAANMsg inCBSMsg, AgentDispatchContext inContext,
			String seikyKeiNo, String status, String workKinoSkbtCd, String sortType)
	{
		// コネクション
		Connection con1 = null;

		// プリペアステートメント
		PreparedStatement pstmt = null;

		// リザルトセット
		ResultSet rsltQuery = null;

		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(CH0021ETMsg.getTableName());

			// SQL文の作成
			StringBuffer sql_Buff = JCHModelCommon.getKsdrSaikenUcwkSql(sortType);

			// prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());

			// ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, JECH0191C020TPMA.class, sql_Buff);

			// パラメータインデックス
			int i = 1;
			// パラメータの設定(運用日を指定)
			CAANJDBCUtil.setParam(pstmt, i++, JCCModelCommon.getOnlineOpeDate(inCBSMsg, null));
			// パラメータの設定(請求契約番号)
			CAANJDBCUtil.setParam(pstmt, i++, seikyKeiNo);
			// パラメータの設定(債権ステータス)
			CAANJDBCUtil.setParam(pstmt, i++, status);
			// パラメータの設定(SYS_CDを指定)
			CAANJDBCUtil.setParam(pstmt, i++, JACStrConst.SYS_CD_CH);
			// パラメータの設定(業務機能識別コードを指定)
			CAANJDBCUtil.setParam(pstmt, i++, workKinoSkbtCd);
			// パラメータの設定(抽出変換コード 1)
			CAANJDBCUtil.setParam(pstmt, i++, JACStrConst.CHSHT_CHG_CD_1);
			// パラメータの設定(運用日を指定)
			CAANJDBCUtil.setParam(pstmt, i++, JCCModelCommon.getOnlineOpeDate(inCBSMsg, null));

			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();

			List<HashMap<String, String>> retList = new ArrayList<HashMap<String, String>>();
			while (rsltQuery.next()) {

				// 債権番号を取得する
				String saikenNo = rsltQuery.getString(CH0021ETMsg.SAIKEN_NO);
				// 料金グループコードを取得する
				String prcGrpCd = rsltQuery.getString(CH0021ETMsg.PRC_GRP_CD);
				// 料金コースコードを取得する
				String pcrsCd = rsltQuery.getString(CH0021ETMsg.PCRS_CD);
				// 料金サービスコードを取得する
				String prcSvcCd = rsltQuery.getString(CH0021ETMsg.PRC_SVC_CD);
				// 料金項目コードを取得する
				String prcKmkCd = rsltQuery.getString(CH0021ETMsg.PRC_KMK_CD);
				// 金額を取得する
				String amnt = rsltQuery.getString(CH0021ETMsg.AMNT);
				// 債権確定年月を取得する
				String saikenFixYm = rsltQuery.getString(CH0021ETMsg.SAIKEN_FIX_YM);

				HashMap<String, String> retMap = new HashMap<String, String>();
				retMap.put(KEY_SAIKEN_NO, saikenNo);
				retMap.put(KEY_PRC_GRP_CD, prcGrpCd);
				retMap.put(KEY_PCRS_CD, pcrsCd);
				retMap.put(KEY_PRC_SVC_CD, prcSvcCd);
				retMap.put(KEY_PRC_KMK_CD, prcKmkCd);
				retMap.put(KEY_AMNT, amnt);
				retMap.put(KEY_SAIKEN_FIX_YM, saikenFixYm);
				retList.add(retMap);
			}

			return retList;
		}
		catch (SQLException e)
		{
			inCBSMsg.set(CH0021CBMMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw new CAANRuntimeException(e);
		}
		finally
		{
			// 資源の解放
			try
			{
				if (rsltQuery != null)
				{
					rsltQuery.close();
				}
				if (pstmt != null)
				{
					pstmt.close();
				}
				if (con1 != null)
				{
					CAANConnectionMgr.getInstance().close(con1);
				}
			}
			catch(SQLException e)
			{
				inCBSMsg.set(CH0021ETMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}
	}

	/**
	 * <p>
	 * 貸倒登録済の債権内訳を取得する。
	 * </p>
	 * @param inCBSMsg  処理対象のメッセージキャリア
	 * @param inContext ディスパッチコンテキスト
	 * @param seikyKeiNo 請求契約番号
	 * @param status 債権ステータスコード
	 * @param workKinoSkbtCd 業務機能識別コード
	 * @return 債権内訳リスト
	 */
	private static List<HashMap<String, String>> getSaikenUcwk2(CAANMsg inCBSMsg, AgentDispatchContext inContext,
			String seikyKeiNo, String status, String workKinoSkbtCd)
	{
		// コネクション
		Connection con1 = null;

		// プリペアステートメント
		PreparedStatement pstmt = null;

		// リザルトセット
		ResultSet rsltQuery = null;

		try
		{
			//コネクション取得
			con1 = JSYejbConnection.getConnection(CH0021ETMsg.getTableName());

			// SQL文の作成
			StringBuffer sql_Buff = JCHModelCommon.getKsdrSaikenUcwkSql2();

			// prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());

			// ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, JECH0191C020TPMA.class, sql_Buff);

			// パラメータインデックス
			int i = 1;
			// パラメータの設定(請求契約番号)
			CAANJDBCUtil.setParam(pstmt, i++, seikyKeiNo);
			// パラメータの設定(債権ステータス)
			CAANJDBCUtil.setParam(pstmt, i++, status);
			// パラメータの設定(SYS_CDを指定)
			CAANJDBCUtil.setParam(pstmt, i++, JACStrConst.SYS_CD_CH);
			// パラメータの設定(業務機能識別コード)
			CAANJDBCUtil.setParam(pstmt, i++, workKinoSkbtCd);
			// パラメータの設定(抽出変換コード 1)
			CAANJDBCUtil.setParam(pstmt, i++, JACStrConst.CHSHT_CHG_CD_1);
			// パラメータの設定(運用日を指定)
			CAANJDBCUtil.setParam(pstmt, i++, JCCModelCommon.getOnlineOpeDate(inCBSMsg, null));

			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();

			List<HashMap<String, String>> retList = new ArrayList<HashMap<String, String>>();
			while (rsltQuery.next()) {

				// 債権番号を取得する
				String saikenNo = rsltQuery.getString(CH0021ETMsg.SAIKEN_NO);
				// 料金グループコードを取得する
				String prcGrpCd = rsltQuery.getString(CH0021ETMsg.PRC_GRP_CD);
				// 料金コースコードを取得する
				String pcrsCd = rsltQuery.getString(CH0021ETMsg.PCRS_CD);
				// 料金サービスコードを取得する
				String prcSvcCd = rsltQuery.getString(CH0021ETMsg.PRC_SVC_CD);
				// 料金項目コードを取得する
				String prcKmkCd = rsltQuery.getString(CH0021ETMsg.PRC_KMK_CD);
				// 金額を取得する
				String amnt = rsltQuery.getString(CH0021ETMsg.AMNT);
				// 債権確定年月を取得する
				String saikenFixYm = rsltQuery.getString(CH0021ETMsg.SAIKEN_FIX_YM);

				HashMap<String, String> retMap = new HashMap<String, String>();
				retMap.put(KEY_SAIKEN_NO, saikenNo);
				retMap.put(KEY_PRC_GRP_CD, prcGrpCd);
				retMap.put(KEY_PCRS_CD, pcrsCd);
				retMap.put(KEY_PRC_SVC_CD, prcSvcCd);
				retMap.put(KEY_PRC_KMK_CD, prcKmkCd);
				retMap.put(KEY_AMNT, amnt);
				retMap.put(KEY_SAIKEN_FIX_YM, saikenFixYm);
				retList.add(retMap);
			}

			return retList;
		}
		catch (SQLException e)
		{
			inCBSMsg.set(CH0021CBMMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw new CAANRuntimeException(e);
		}
		finally
		{
			// 資源の解放
			try
			{
				if (rsltQuery != null)
				{
					rsltQuery.close();
				}
				if (pstmt != null)
				{
					pstmt.close();
				}
				if (con1 != null)
				{
					CAANConnectionMgr.getInstance().close(con1);
				}
			}
			catch(SQLException e)
			{
				inCBSMsg.set(CH0021ETMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}
	}

	/**
	 * <p>
	 * 債権内訳リスト分割処理。
	 * 第1引数で受け取った債権内訳リストを、請求先単位のレコードと料金グループ計単位のレコードに分割します。
	 * 第2引数、第3引数のそれぞれのリストは空のリストを受け取り、このメソッドで中身を更新する。
	 * </p>
	 * @param saikenUcwkList 債権内訳リスト
	 * @param list1 請求先単位レコード保持リスト
	 * @param list2 料金グループ系単位レコード保持リスト
	 */
	private static void divideSaikenUcwkList(List<HashMap<String, String>> saikenUcwkList,
			List<HashMap<String, String>> list1, List<HashMap<String, String>> list2)
	{
		for (HashMap<String, String> saikenUw : saikenUcwkList)
		{
			String pcGrpCd = saikenUw.get(KEY_PRC_GRP_CD);

			if (JACStrConst.PRC_GRP_CD_SP.equals(pcGrpCd))
			{
				list1.add(saikenUw);
			}
			else
			{
				list2.add(saikenUw);
			}
		}
	}

	/**
	 * <p>
	 * 貸倒登録済の債権内訳を取得する。
	 * 引数の債権内訳リストを元に、以下のキーと値を保持したマップを作成し、リターンする。
	 * キー：債権確定年月 + 料金グループコード + 料金コースコード + 料金サービスコード + 料金項目コード
	 * 値：債権内訳情報
	 * </p>
	 * @param saikenUcwkList 債権内訳リスト
	 * @return 債権内訳情報を保持したマップ
	 */
	private static HashMap<String, HashMap<String, String>> getSaikenUcwkMap(List<HashMap<String, String>> saikenUcwkList)
	{
		// 返却用マップ
		HashMap<String, HashMap<String, String>> retMap = new HashMap<String, HashMap<String, String>>();
		for (HashMap<String, String> saikenUw : saikenUcwkList)
		{
			// 債権確定年月を取得する
			String saikenFixYm = (String)saikenUw.get(KEY_SAIKEN_FIX_YM);
			// 料金グループコードを取得する
			String prcGrpCd = (String)saikenUw.get(KEY_PRC_GRP_CD);
			// 料金コースコードを取得する
			String pcrsCd = (String)saikenUw.get(KEY_PCRS_CD);
			// 料金サービスコードを取得する
			String prcSvcCd = (String)saikenUw.get(KEY_PRC_SVC_CD);
			// 料金項目コードを取得する
			String prcKmkCd = (String)saikenUw.get(KEY_PRC_KMK_CD);
			// 債権番号を取得する
			String saikenNo = (String)saikenUw.get(KEY_SAIKEN_NO);

			StringBuilder key = new StringBuilder();
			key.append(saikenFixYm)
				.append(prcGrpCd)
				.append(pcrsCd)
				.append(prcSvcCd)
				.append(prcKmkCd)
				.append(saikenNo);

			retMap.put(key.toString(), saikenUw);
		}

		return retMap;
	}

	/**
	 * <p>
	 * 債権内訳更新処理。
	 * 移動先金庫料金項目コードが「処理済金（貸倒後入金）」の場合、
	 * 債権内訳の未収額、貸倒後入金のレコードを更新する。
	 * </p>
	 * @param inCBSMsg  処理対象のメッセージキャリア
	 * @param inContext ディスパッチコンテキスト
	 * @param saikenUcwkList 処理対象となる債権内訳（未収額）の情報を保持するリスト
	 * @param ksdrMap 処理対象となる債権内訳（貸倒後入金額）の情報を保持するマップ
	 * @param cnvMap 未収額→貸倒後入金額変換用のマップ
	 * @param inSeikyKeiNo 移動先請求契約番号
	 * @param inKnkAmnt 移動先金庫金額
	 * @param idoSakiKnkNo 移動先金庫番号
	 * @param kaikIdoFlg 会計異動登録フラグ（trueの時、会計異動の登録を行う）
	 * @return 債権内訳リスト
	 */
	private static long execUpdateSaikenUcwk(CAANMsg inCBSMsg, AgentDispatchContext inContext, List<HashMap<String, String>> saikenUcwkList,
			HashMap<String, HashMap<String, String>>ksdrMap, HashMap<String, String> cnvMap, String inSeikyKeiNo, long inKnkAmnt, String idoSakiKnkNo, boolean kaikIdoFlg)
	{
		// ----------------------------------------------------
		// 変数定義
		// ----------------------------------------------------
		// ワーク金額（初期値：移動先金庫金額）
		long workAmnt = inKnkAmnt;

		// ワーク消込金額
		long workKskmAmnt = 0L;

		// 運用日付
		String opeDate = (String) JPCModelCommon.getOnlineOpeDate(inCBSMsg, null);

		// 請求年月取得
		CAANMsg[] seikyYmArray = JCHModelCommon.getPrcSchdlContain(inCBSMsg, inContext, JACStrConst.EVENT_CD_SIKY_TRN_DAY);
		if (seikyYmArray.length < 0)
		{
			return 0L;
		}
		String seikyYm = seikyYmArray[0].getString(CH0501ETMsg.SEIKY_YM);

		// 入金番号
		String nyukinNo = inCBSMsg.getString(ECH0191D020CBSMsg.NYUKIN_NO);

		// ----------------------------------------------------
		// 督促債権関連を取得。
		// ----------------------------------------------------
		HashMap<String, String> tokuskSknKnrnMap = new HashMap<String, String>();
		if (kaikIdoFlg)
		{
			// 請求契約番号をキーに督促を取得
			CAANMsg[] tokusokuArray = JCHModelCommon.getTokusokuBySeikykeiNo(inCBSMsg, inContext, inSeikyKeiNo);
			if (tokusokuArray.length > 0)
			{
				// キー項目を設定
				CAANMsg inETMsg = new CAANMsg(CH0341ETMsg.class.getName());
				inETMsg.set(CH0341ETMsg.TOKUSOKU_NO, tokusokuArray[0].getString(CH0231ETMsg.TOKUSOKU_NO));
				inETMsg.set(CH0341ETMsg.MK_FLG, "0");
	
				CH0341LE leCH0341 = new CH0341LE();
				CAANMsg[] retCH0341Array;
				try {
					retCH0341Array = leCH0341.findByCondition(inETMsg);
					if (null != retCH0341Array && retCH0341Array.length > 0)
					{
						for (int i = 0; i < retCH0341Array.length; i++)
						{
							tokuskSknKnrnMap.put(retCH0341Array[i].getString(CH0341ETMsg.SAIKEN_NO), null);
						}
					}
				} catch (CAANException ce) {
					throw new CAANRuntimeException(ce);
				}
			}
		}

		// 債権内訳リスト分処理
		for (HashMap<String, String> saikenUw : saikenUcwkList)
		{
			// 債権番号を取得する
			String saikenNo = (String)saikenUw.get(KEY_SAIKEN_NO);
			// 料金グループコードを取得する
			String prcGrpCd = (String)saikenUw.get(KEY_PRC_GRP_CD);
			// 料金コースコードを取得する
			String pcrsCd = (String)saikenUw.get(KEY_PCRS_CD);
			// 料金サービスコードを取得する
			String prcSvcCd = (String)saikenUw.get(KEY_PRC_SVC_CD);
			// 料金項目コードを取得する
			String prcKmkCd = (String)saikenUw.get(KEY_PRC_KMK_CD);
			// 金額を取得する
			String amnt = (String)saikenUw.get(KEY_AMNT);
			long dbAmnt = Long.valueOf(amnt);
			// 債権確定年月を取得する
			String saikenFixYm = (String)saikenUw.get(KEY_SAIKEN_FIX_YM);

			// 未収額が0円の場合は処理対象外として次レコードへ進む
			if (dbAmnt == 0L)
			{
				continue;
			}

			// ----------------------------------------------------
			// 更新金額の計算
			// ----------------------------------------------------
			// 未収額
			long mishuAmnt = 0L;
			// 貸倒後入金額
			long ksdrNyukinAmnt = 0L;

			if (workAmnt >= dbAmnt)
			{
				mishuAmnt = 0L;
				ksdrNyukinAmnt = dbAmnt;
			}
			else
			{
				mishuAmnt = dbAmnt - workAmnt;
				ksdrNyukinAmnt = workAmnt;
			}

			// ----------------------------------------------------
			// 債権内訳の未収額を更新
			// ----------------------------------------------------
			// 債権内訳登録副次部品
			CAANMsg inETMsgSaikenUcwk = new CAANMsg(CH0021ETMsg.class.getName());

			// キー項目を設定
			inETMsgSaikenUcwk.set(CH0021ETMsg.SAIKEN_NO, saikenNo);
			inETMsgSaikenUcwk.set(CH0021ETMsg.SAIKEN_FIX_YM, saikenFixYm);
			inETMsgSaikenUcwk.set(CH0021ETMsg.PRC_GRP_CD, prcGrpCd);
			inETMsgSaikenUcwk.set(CH0021ETMsg.PCRS_CD, pcrsCd);
			inETMsgSaikenUcwk.set(CH0021ETMsg.PRC_SVC_CD, prcSvcCd);
			inETMsgSaikenUcwk.set(CH0021ETMsg.PRC_KMK_CD, prcKmkCd);

			// 更新項目を設定
			inETMsgSaikenUcwk.set(CH0021ETMsg.AMNT, String.valueOf(mishuAmnt));
			inETMsgSaikenUcwk.set(CH0021ETMsg.UPD_OPEACNT, inCBSMsg.getString(KEY_OPERATORID));

			// 債権内訳副次部品を呼び出し、債権内訳を更新
			JCHejbCH0021SecProc ch0021SecProc = new JCHejbCH0021SecProc();
			ch0021SecProc.executeUpdate(inETMsgSaikenUcwk);

			// 未収額の料金グループコード、料金コースコード、料金サービスコード、料金項目コードをキーに
			// 変換マップを検索し、未収額のコードに対応する貸倒後入金額のコードを取得する。
			StringBuilder key = new StringBuilder();
			key.append(prcGrpCd).append(pcrsCd).append(prcSvcCd).append(prcKmkCd);

			// ----------------------------------------------------
			// 債権内訳の貸倒後入金額を更新
			// ----------------------------------------------------
			if (cnvMap.containsKey(key.toString()))
			{
				// 変換マップに存在した場合、取得した値を分解して
				// 貸倒後入金額の料金グループコード、料金コースコード、料金サービスコード、料金項目コードを取得する。
				String ksdrPrcKmk = cnvMap.get(key.toString());
				String ksdrPrgGrpCd = ksdrPrcKmk.substring(0, 2);
				String ksdrPcrsCd = ksdrPrcKmk.substring(2, 5);
				String ksdrPrgSvcCd = ksdrPrcKmk.substring(5, 17);
				String ksdrPrgKmkCd = ksdrPrcKmk.substring(17);

				// 料金グループ計のレコードのみ処理対象
				if (!JACStrConst.PRC_GRP_CD_SP.equals(ksdrPrgGrpCd))
				{
					// 債権内訳（貸倒後入金額）のサーチキーに債権確定年月と債権番号を追加
					String searchKey = saikenFixYm.concat(ksdrPrcKmk).concat(saikenNo);

					// キー項目を設定
					CAANMsg inETMsgSaikenUcwk2 = new CAANMsg(CH0021ETMsg.class.getName());
					inETMsgSaikenUcwk2.set(CH0021ETMsg.SAIKEN_NO, saikenNo);
					inETMsgSaikenUcwk2.set(CH0021ETMsg.SAIKEN_FIX_YM, saikenFixYm);
					inETMsgSaikenUcwk2.set(CH0021ETMsg.PRC_GRP_CD, ksdrPrgGrpCd);
					inETMsgSaikenUcwk2.set(CH0021ETMsg.PCRS_CD, ksdrPcrsCd);
					inETMsgSaikenUcwk2.set(CH0021ETMsg.PRC_SVC_CD, ksdrPrgSvcCd);
					inETMsgSaikenUcwk2.set(CH0021ETMsg.PRC_KMK_CD, ksdrPrgKmkCd);

					// 更新項目を設定
					inETMsgSaikenUcwk2.set(CH0021ETMsg.UPD_OPEACNT, inCBSMsg.getString(KEY_OPERATORID));

					if (ksdrMap.containsKey(searchKey))
					{
						// 貸倒後入金額が存在する場合、
						HashMap<String, String> ksdrNyukin = ksdrMap.get(searchKey);

						// 金額を取得し、加算して更新
						long tmpAmnt = Long.valueOf(ksdrNyukin.get(KEY_AMNT));

						// 更新項目を設定
						inETMsgSaikenUcwk2.set(CH0021ETMsg.AMNT, String.valueOf(tmpAmnt + ksdrNyukinAmnt));
						// 債権内訳副次部品を呼び出し、債権内訳を更新
						ch0021SecProc.executeUpdate(inETMsgSaikenUcwk2);
					}
					else
					{
						// 貸倒後入金額が存在しない場合、
						// 更新項目を設定
						inETMsgSaikenUcwk2.set(CH0021ETMsg.AMNT, String.valueOf(ksdrNyukinAmnt));
						inETMsgSaikenUcwk2.set(CH0021ETMsg.ADD_OPEACNT, inCBSMsg.getString(KEY_OPERATORID));
						// 債権内訳副次部品を呼び出し、債権内訳を追加
						ch0021SecProc.executeInsert(inETMsgSaikenUcwk2);
					}

					// ----------------------------------------------------
					// 会計異動を登録
					// ----------------------------------------------------
					// TODO
					// 会計異動テーブルの以下の項目については2013/10時点で未使用であるため暫定の値を設定するものとする。
					// 料金）前田氏確認済
					// 会計異動コード
					// 請求年月
					// 会計年月
					// 会計内訳コード
					if (kaikIdoFlg)
					{
						// 会計異動副次部品
						CAANMsg inETMsgKaikIdo = new CAANMsg(CH0381ETMsg.class.getName());

						// 会計異動年月日
						inETMsgKaikIdo.set(CH0381ETMsg.KAIK_IDO_YMD, opeDate);
						// 請求契約番号
						inETMsgKaikIdo.set(CH0381ETMsg.SEIKY_KEI_NO, inSeikyKeiNo);
						// 会計異動コード
						inETMsgKaikIdo.set(CH0381ETMsg.KAIK_IDO_CD, JACStrConst.KAIK_IDO_CD_KASHID);
						// 料金グループコード
						inETMsgKaikIdo.set(CH0381ETMsg.PRC_GRP_CD, ksdrPrgGrpCd);
						// 料金コースコード
						inETMsgKaikIdo.set(CH0381ETMsg.PCRS_CD, ksdrPcrsCd);
						// 料金サービスコード
						inETMsgKaikIdo.set(CH0381ETMsg.PRC_SVC_CD, ksdrPrgSvcCd);
						// 料金項目コード
						inETMsgKaikIdo.set(CH0381ETMsg.PRC_KMK_CD, ksdrPrgKmkCd);
						// 異動前金額
						inETMsgKaikIdo.set(CH0381ETMsg.IDO_BF_AMNT, "0");
						// 異動後金額
						inETMsgKaikIdo.set(CH0381ETMsg.IDO_AF_AMNT, String.valueOf(ksdrNyukinAmnt));
						// 異動金額
						inETMsgKaikIdo.set(CH0381ETMsg.IDO_AMNT, String.valueOf(ksdrNyukinAmnt));
						// 請求年月
						inETMsgKaikIdo.set(CH0381ETMsg.SEIKY_YM, saikenFixYm);
						// 会計年月
						inETMsgKaikIdo.set(CH0381ETMsg.KAIK_YM, seikyYm);
						// 債権番号
						inETMsgKaikIdo.set(CH0381ETMsg.SAIKEN_NO, saikenNo);
						// 入金番号
						inETMsgKaikIdo.set(CH0381ETMsg.NYUKIN_NO, nyukinNo);
						// 会計内訳コード
						inETMsgKaikIdo.set(CH0381ETMsg.KAIK_UCWK_CD, KAIK_UCWK_CD);

						// 会計異動副次部品を呼び出し、会計異動を登録
						JCHejbCH0381SecProc ch00381SecProc = new JCHejbCH0381SecProc();
						ch00381SecProc.insertKaikIdo(inCBSMsg, inContext, inETMsgKaikIdo);
					}
				}
				else
				{
					// ----------------------------------------------------
					// 充当を登録
					// ----------------------------------------------------
					// キー項目を設定
					CAANMsg inETMsgJuto = new CAANMsg(CH0201ETMsg.class.getName());
					inETMsgJuto.set(CH0201ETMsg.JUTO_NO, JCHejbCH0201NumberParts.getJutoNo(inCBSMsg, inContext));

					// 更新項目を設定
					inETMsgJuto.set(CH0201ETMsg.JUTO_YMD, opeDate);
					inETMsgJuto.set(CH0201ETMsg.JUTO_SBT_CD, JACStrConst.JUTO_SBT_AZKIN_JUTO);
					inETMsgJuto.set(CH0201ETMsg.JUTO_AMNT, String.valueOf(ksdrNyukinAmnt));
					inETMsgJuto.set(CH0201ETMsg.NYUKIN_NO, nyukinNo);
					inETMsgJuto.set(CH0201ETMsg.KNK_NO, idoSakiKnkNo);
					inETMsgJuto.set(CH0201ETMsg.SAIKEN_NO, saikenNo);
					inETMsgJuto.set(CH0201ETMsg.OPERATORID, inCBSMsg.getString(KEY_OPERATORID));

					// 充当副次部品を呼び出し、充当を登録
					JCHejbCH0201SecProc ch0201SecProc = new JCHejbCH0201SecProc();
					ch0201SecProc.insertJuto(inCBSMsg, inContext, inETMsgJuto);
				}

			}

			// ワーク金額を計算
			workAmnt = workAmnt - dbAmnt;

			if (tokuskSknKnrnMap.containsKey(saikenNo))
			{
				// 消込処理済金額を加算
				workKskmAmnt += ksdrNyukinAmnt;
			}

			// 消込対象金額がなくなった場合は終了
			if (workAmnt <= 0)
			{
				break;
			}
		}

		return workKskmAmnt;
	}

	/**
	 * <p>
	 * 督促更新処理。
	 * 督促の更新、督促異動の登録、不良顧客情報の取得を行う。
	 * </p>
	 * @param inCBSMsg  処理対象のメッセージキャリア
	 * @param inContext ディスパッチコンテキスト
	 * @param seikyKeiMap 請求契約番号をキーに保持するマップ
	 * @param inSeikyKeiNo 請求契約番号
	 * @param inTokusokuAmnt 督促金額
	 * @param huryoCustDelList 不良顧客削除リスト
	 * @return 債権内訳リスト
	 */
	private static void execUpdateTokusoku(CAANMsg inCBSMsg, AgentDispatchContext inContext,
			HashMap<String, String> seikyKeiMap, String inSeikyKeiNo, long inTokusokuAmnt, List<CAANMsg> huryoCustDelList)
	{
		// 請求契約番号をキーに督促を取得
		CAANMsg[] tokusokuArray = JCHModelCommon.getTokusokuBySeikykeiNo(inCBSMsg, inContext, inSeikyKeiNo);

		if (tokusokuArray.length > 0)
		{
			// ----------------------------------------------------
			// 督促を更新。
			// ----------------------------------------------------
			// キー項目を設定
			CAANMsg inETMsg = new CAANMsg(CH0231ETMsg.class.getName());
			inETMsg.set(CH0231ETMsg.TOKUSOKU_NO, tokusokuArray[0].getString(CH0231ETMsg.TOKUSOKU_NO));

			// 更新項目を設定
			String dbAmnt = tokusokuArray[0].getString(CH0231ETMsg.TOKUSOKU_AMNT);
			long updateAmnt = Long.valueOf(dbAmnt) - inTokusokuAmnt;
			inETMsg.set(CH0231ETMsg.TOKUSOKU_AMNT, String.valueOf(updateAmnt));
			inETMsg.set(CH0231ETMsg.TOKUSOKU_IDO_EVENT_CD, JACStrConst.TKSKIDO_EVCD_KNK_IDO);
			inETMsg.set(CH0231ETMsg.UPD_OPEACNT, inCBSMsg.getString(KEY_OPERATORID));

			// 督促副次部品を呼び出し、督促を更新
			JCHejbCH0231SecProc ch0231SecProc = new JCHejbCH0231SecProc();
			ch0231SecProc.updateAmnt(inCBSMsg, inContext, inETMsg);

			// ----------------------------------------------------
			// 督促異動を登録。
			// ----------------------------------------------------
			// 督促番号
			inETMsg.set(CH0361ETMsg.TOKUSOKU_NO, tokusokuArray[0].getString(CH0231ETMsg.TOKUSOKU_NO));
			// 督促異動イベントコード
			inETMsg.set(CH0361ETMsg.TOKUSOKU_IDO_EVENT_CD, tokusokuArray[0].getString(CH0231ETMsg.TOKUSOKU_IDO_EVENT_CD));
			// 督促異動年月日
			inETMsg.set(CH0361ETMsg.TOKUSOKU_IDO_YMD, tokusokuArray[0].getString(CH0231ETMsg.TOKUSOKU_IDO_YMD));
			// 督促ステータス
			inETMsg.set(CH0361ETMsg.TOKUSOKU_STAT, tokusokuArray[0].getString(CH0231ETMsg.TOKUSOKU_STAT));
			// 督促金額 = 変更前の督促金額
			inETMsg.set(CH0361ETMsg.TOKUSOKU_AMNT, dbAmnt);
			// 支払約束受付年月日
			inETMsg.set(CH0361ETMsg.PAY_YAKUSOKU_UK_YMD, tokusokuArray[0].getString(CH0231ETMsg.PAY_YAKUSOKU_UK_YMD));
			// 変更支払約束年月日
			inETMsg.set(CH0361ETMsg.PAY_YAKUSOKU_YMD, tokusokuArray[0].getString(CH0231ETMsg.PAY_YAKUSOKU_YMD));
			// 変更支払約束履行判定年月日
			inETMsg.set(CH0361ETMsg.PAY_YAKUSOKU_RIKO_JDG_YMD, tokusokuArray[0].getString(CH0231ETMsg.PAY_YAKUSOKU_RIKO_JDG_YMD));
			inETMsg.set(CH0361ETMsg.ADD_OPEACNT, inCBSMsg.getString(KEY_OPERATORID));
			inETMsg.set(CH0361ETMsg.UPD_OPEACNT, inCBSMsg.getString(KEY_OPERATORID));

			// 督促異動副次部品を呼び出し、督促異動を登録
			JCHejbCH0361SecProc ch0361SecProc = new JCHejbCH0361SecProc();
			ch0361SecProc.insertTokusokuIdo(inCBSMsg, inContext, inETMsg);

			// ----------------------------------------------------
			// 不良顧客情報を取得し、CBSメッセージへ登録（後続のサービスIFで使用する）
			// ----------------------------------------------------
			if (updateAmnt == 0)
			{
				try {

					// マップにキーとして入っている請求契約番号は重複して処理しない
					if (!seikyKeiMap.containsKey(inSeikyKeiNo))
					{
						CAANMsg msgCK0061 = new CAANMsg(CK0061ETMsg.class.getName());

						// 検索条件設定
						msgCK0061.set(CK0061ETMsg.SEIKY_KEI_NO, inSeikyKeiNo);
						msgCK0061.set(CK0061ETMsg.MK_FLG, JACStrConst.MK_FLG_YK);

						// 請求契約番号をキーに不良顧客を取得
						CK0061LE le = new CK0061LE();
						CAANMsg[] retCK0061 = le.findByCondition(msgCK0061);

						if (retCK0061.length > 0)
						{
							String schemaName =  "eo.ejb.cbs.cbsmsg.ECH0191D020CBSMsg2List";
							for (int i = 0; i < retCK0061.length; i++)
							{
								CAANMsg ck0061Obj = retCK0061[i];
								CAANMsg rsltMsg = new CAANMsg(schemaName);
								rsltMsg.set(ECH0191D020CBSMsg2List.HURYO_CUST_NO ,ck0061Obj.getString(CK0061ETMsg.HURYO_CUST_NO));
								rsltMsg.set(ECH0191D020CBSMsg2List.HURYO_CUST_SEIKY_KEI_NO ,ck0061Obj.getString(CK0061ETMsg.SEIKY_KEI_NO));
								rsltMsg.set(ECH0191D020CBSMsg2List.HURYO_CUST_SYSID ,ck0061Obj.getString(CK0061ETMsg.SYSID));
								rsltMsg.set(ECH0191D020CBSMsg2List.HURYO_CUST_ADD_CD ,ck0061Obj.getString(CK0061ETMsg.HURYO_CUST_ADD_CD));
								rsltMsg.set(ECH0191D020CBSMsg2List.HURYO_UPD_DTM , ck0061Obj.getString(CK0061ETMsg.UPD_DTM));
								huryoCustDelList.add(rsltMsg);
							}
						}
					}
				}
				catch (CAANException e)
				{
					throw new CAANRuntimeException();
				}

			}
		}
	}

	/**
	 * <p>
	 * 債権内訳更新処理。
	 * 移動先金庫料金項目コードが「処理済金（貸倒後入金）」の場合、
	 * 債権内訳の未収額、貸倒後入金のレコードを更新する。
	 * また、督促の更新、督促異動の登録、不良顧客情報の取得を行う。
	 * </p>
	 * @param inCBSMsg  処理対象のメッセージキャリア
	 * @param inContext ディスパッチコンテキスト
	 * @param inMsgList 移動先金庫情報
	 * @param mishuMap 移動先金庫情報
	 * @param ksdrPrcKmkCd 金庫料金項目コード(貸倒後入金)
	 */
	private static void ksdrNyukin(CAANMsg inCBSMsg, AgentDispatchContext inContext, CAANMsg[] inMsgList,
			HashMap<String, List<HashMap<String, String>>> mishuMap, String ksdrPrcKmkCd)
	{
		// 未収額→貸倒後入金額変換用のマップを取得
		HashMap<String, String> cnvMap = JCHModelCommon.getCnvCdMap(inCBSMsg, inContext, JACStrConst.MS_KSD_NK, true);

		// 処理済金（貸倒後入金）の料金項目コードを取得する。
		long retAmnt = 0L;

		// 請求契約番号をキーに保持するマップ
		HashMap<String, String> seikyKeiMap= new HashMap<String, String>();

		// 不良顧客削除リスト
		List<CAANMsg> huryoCustDelList = new ArrayList<CAANMsg>();

		// 金庫移動登録画面の移動先金庫情報単位に処理を実行する
		for (CAANMsg inMsg : inMsgList)
		{
			// 移動先金庫料金項目コードを取得する。
			String inIdosakiKnkPrcKmkCd = inMsg.getString(ECH0191D020CBSMsg1List.KNK_PRC_KMK_CD_AF);
			// 移動先請求契約番号
			String inSeikyKeiNo = inMsg.getString(ECH0191D020CBSMsg1List.SEIKY_KEI_NO);
			// 移動先金庫金額
			long inKnkAmnt = Long.valueOf(inMsg.getString(ECH0191D020CBSMsg1List.KNK_AMNT_AF));

			String idoSakiKnkNo = JCHejbCH0191NumberParts.getKnkNoForKnkIdo(inCBSMsg, inContext, inMsg);
			inMsg.set(ECH0191D020CBSMsg1List.KNK_NO_AF, idoSakiKnkNo);

			// 移動先金庫料金項目コードが「処理済金（貸倒後入金）」の場合、登録振舞
			if (ksdrPrcKmkCd.equals(inIdosakiKnkPrcKmkCd))
			{
				// 債権内訳の未収額レコードをリストで取得（年月の昇順、消込定義順にソート済）
				List<HashMap<String, String>> mishuList = mishuMap.get(inSeikyKeiNo);

				// 債権内訳の貸倒後入金額レコードをマップで取得
				List<HashMap<String, String>> ksdrList = getSaikenUcwk2(inCBSMsg, inContext, inSeikyKeiNo, JACStrConst.SAIKEN_STAT_KASHID_ADD, JACStrConst.KSD_AF_NK);
				HashMap<String, HashMap<String, String>> ksdrMap = getSaikenUcwkMap(ksdrList);

				// 請求先単位レコード格納用リスト
				List<HashMap<String, String>> seikyKeiNoList = new ArrayList<HashMap<String, String>>();

				// 料金グループ計レコード格納用リスト
				List<HashMap<String, String>> prcGrpKeiList = new ArrayList<HashMap<String, String>>();

				// 債権内訳の未収額レコードリストを請求先単位と、料金グループ計に分割する。
				divideSaikenUcwkList(mishuList, seikyKeiNoList, prcGrpKeiList);

				// 請求先単位レコード分を処理
				execUpdateSaikenUcwk(inCBSMsg, inContext, seikyKeiNoList, ksdrMap, cnvMap, inSeikyKeiNo, inKnkAmnt, idoSakiKnkNo, false);

				// 料金グループ計レコード分を処理
				retAmnt = execUpdateSaikenUcwk(inCBSMsg, inContext, prcGrpKeiList, ksdrMap, cnvMap, inSeikyKeiNo, inKnkAmnt, idoSakiKnkNo, true);

				// 債権内訳の更新があった時、督促の更新
				if (retAmnt != 0)
				{
					execUpdateTokusoku(inCBSMsg, inContext, seikyKeiMap, inSeikyKeiNo, retAmnt, huryoCustDelList);
					// 処理済みの請求契約番号をマップに貯める
					seikyKeiMap.put(inSeikyKeiNo, null);
				}
			}
		}

		// 不良顧客削除リストをCBSメッセージにセット
		inCBSMsg.set(ECH0191D020CBSMsg.ECH0191D020CBSMSG2LIST, (CAANMsg[])huryoCustDelList.toArray(new CAANMsg[0]));
	}

	/**
	 * <p>
	 * 金庫取消変更顧客独自処理
	 * </p>
	 * @param inCBSMsg  処理対象のメッセージキャリア
	 * @param inContext ディスパッチコンテキスト
	 */
	public static void invoke2(CAANMsg inCBSMsg, AgentDispatchContext inContext)
	{
		JCHejbCH0191SecProc jch0191 = new JCHejbCH0191SecProc();

		// ----------------------------------------------------
		// 金庫（自分）を更新し、履歴データにする
		// ----------------------------------------------------
		// 金庫取消変更更新副次処理部品を呼び出す
		jch0191.KnkCacelUpDate(inCBSMsg, inContext, 
				inCBSMsg.getString(ECH0191C020CBSMsg.IDOMOTO_KNK_NO), inCBSMsg.getString(ECH0191C020CBSMsg.KNK_NO_O));

		// ----------------------------------------------------
		// 金庫が取消された場合、この金庫の入金番号に紐づいている金庫をすべてチェックし
		// 入金番号に紐づいている金庫がすべて取消になっている場合、入金ステータスを取消に変更する。
		// ----------------------------------------------------
		jch0191.updateNyukinByKnkCl(inCBSMsg, inContext);
	}

}
