/*********************************************************************
*  All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JBSBatACTrgtSvcKeiMakeJgskn
*	ソースファイル名	：JBSBatACTrgtSvcKeiMakeJgskn.java
*	作成者				：富士通　
*	作成日				：2012年04月02日
*＜機能概要＞
*　課金対象サービス契約情報作成（EM）部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2012/04/02   富士通		新規作成
*	v4.00.00	2012/11/14   FJ)早崎	【ANK-0141-00-00】対応
*	v4.01.00	2013/02/06   FJ)早崎	【ST3-2013-0000347】課金開始日不正対応
*	v5.00.00	2013/07/09   FJ)岡田	【LT-2013-0000352】対応
*	v5.01.00	2013/09/26   FJ)黒木/江森	【OM-2013-0002478 】EM精算結果出力不正対応
*	v6.00.00	2013/12/06   FJ)黒木	【OM-2013-0002478 】EM精算結果出力不正対応
*	v6.01.00	2013/12/20   FJ)黒木	【OM-2013-0005343 】EM精算結果出力不正対応
*********************************************************************/
package eo.business.service;

import java.util.ArrayList;

import eo.business.common.JACbatDebugLogUtil;
import eo.business.common.JACbatRknBusinessUtil;
import eo.business.common.JACbatSchdlUtil;
import eo.business.common.JBSbatBusinessService;
import eo.business.util.file.JBSbatACIFM170;
import eo.common.constant.JACStrConst;
import eo.common.util.JPCUtilCommon;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatServiceInterfaceMap;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.util.JBSbatDateUtil;

/**
* (クラスの機能概要) <p>
*<BR>
* @author 富士通
*/
public class JBSbatACTrgtSvcKeiMakeJgskn extends JBSbatBusinessService
{
	/**▼▼▼▼▼▼ツールから生成した宣言です 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成した宣言です 終了▲▲▲▲▲▲*/

	/** 退避.請求年月 */
	private String seikyYM = null;

	/** 群月初日 */
	private String gunStr = null;

	/** 群締め日 */
	private String gunEnd = null;

	/** 請求月の暦日数 */
	private int calDay = -1;

	/** 入力レコード退避リスト */
	private ArrayList<JBSbatServiceInterfaceMap> twk_tmpList = null;

	/** 当月イベント発生フラグ true：当月イベントあり false ：当月イベントなし（初期値）） */
	private boolean twk_flgIsEvntRslt = false;

	/**
	 * 初期処理
	 * @param  JBSbatCommonItem commonItem バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した初期化のソースです 開始▼▼▼▼▼▼*/
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);
		/**▲▲▲▲▲▲ツールから生成した初期化のソースです 終了▲▲▲▲▲▲*/
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][initial]");
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][initial][opeDate=" + super.opeDate + "]");
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][initial][freeItem=" + super.freeItem + "]");

		// 料金スケジュール定義アクセス部品生成
		JACbatSchdlUtil schdUtil = new JACbatSchdlUtil(commonItem);

		// 請求年月取得（バッチ運用日の前月）
		this.seikyYM = JBSbatDateUtil.adjustMonth(super.opeDate, -1).substring(0, 6);		// 請求年月

		// 群月初日、群締め日　←　JACbatSchdlUtil.getUseStrEnd(請求年月, イベントコード("01"（利用開始日））,
		// イベントコード（"02"（利用終了日））)
		String[] rtn = schdUtil.getUseStrEnd(this.seikyYM, JACStrConst.EVENT_CD_USE_STAYMD, JACStrConst.EVENT_CD_USE_ENDYMD);

		// クローズ
		schdUtil.close();

		this.gunStr = rtn[0];
		this.gunEnd = rtn[1];

		// 請求月の暦日数を取得する（引数：群終了日、群開始日）
		this.calDay = JPCUtilCommon.subtractDay(this.gunEnd, this.gunStr) + 1;

		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "バッチ運用日：" + super.opeDate + "　群開始日：" + this.gunStr + "　群終了日："
						+ this.gunEnd + "　歴日付：" + this.calDay);

		// 入力レコード退避リスト初期化
		this.twk_tmpList = new ArrayList<JBSbatServiceInterfaceMap>();

		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][initial]");
	/**▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 主処理
	 * @param inMap 入力電文
	 * @param outputInItem 入力情報
	 * @return JBSbatOutputItem 出力情報
	 * @throws Exception
	 */
	public JBSbatOutputItem execute(JBSbatServiceInterfaceMap inMap, JBSbatOutputItem outputInItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの主処理を記述してください。▼▼▼▼▼▼*/
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][execute]");
		assert inMap != null ? JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][execute][inMap=" + inMap.getMap().toString() + "]") : true;

		// ■最終レコード後はここで終了
		if (inMap == null)
		{
			// 出力
			// キーブレイク時の処理
			this.keyBreak(outputInItem);

			// 処理終了
			return outputInItem;
		}

		// 主処理の先頭にて
		// サービスコードをフル桁にする
		inMap.setString(JBSbatACIFM170.PRC_SVC_CD, JACbatRknBusinessUtil.fullPrcSvcCd(inMap.getString(JBSbatACIFM170.PRC_SVC_CD)));

		String inKey = null; // 入力．キー
		String tmpKey = null; // 退避．キー

		// ブレイクキー（入力）の設定
		inKey = getKeyInfo(inMap);

		// ■1件目（初回）はここで終了
		// 退避．キー ＝ null の場合
		if (!outputInItem.isKeyList())
		{
			// ダミーレコードの設定
			// ※最終レコード後の主処理呼び出しのため
			outputInItem.addOutMapList(new JBSbatServiceInterfaceMap());

			// キー情報設定
			outputInItem.clearKeyList(); // キー情報のクリア
			outputInItem.addKeyList(inKey); // ブレイクキー（入力）

			// 退避リストへ追加
			this.twk_tmpList.add(inMap);

			return outputInItem;
		}

		// ■2件目以降（退避キーが存在する場合）
		// 退避．キーの取得
		tmpKey = (String)outputInItem.getKeyList().get(0);

		// 出力情報設定
		if (inKey.equals(tmpKey))
		{
			// 入力．キー ＝　退避．キー

			// 退避リストへ追加
			this.twk_tmpList.add(inMap);
			
		}
		else
		{
			// 入力．キー ≠　退避．キー
			this.keyBreak(outputInItem);

			// 退避クリア
			this.twk_flgIsEvntRslt = false;
			this.twk_tmpList = new ArrayList<JBSbatServiceInterfaceMap>();

			// キー情報設定
			outputInItem.clearKeyList(); // キー情報のクリア
			outputInItem.addKeyList(inKey); // ブレイクキー（入力）
			
			// 退避リストへ追加
			this.twk_tmpList.add(inMap);
			
		}

		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][execute]");
		return outputInItem;
	/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼*/
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][terminal]");
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][terminal]");
		/**▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲*/
	/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}

	/**▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成したメソッドです 終了▲▲▲▲▲▲*/

	/**
	 * キーブレイク時の処理
	 * 1）退避リストに設定した情報から以下の情報を求める。
	 *    ・利用開始日
	 *    ・利用終了日
	 *    ・利用日数
	 *    ・利用不可日数
	 * 2）計算した結果を出力レコードへ設定する
	 * @param outputInItem 出力共通電文クラス
	 * @throws Exception
	 */
	public void keyBreak(JBSbatOutputItem outputInItem) throws Exception
	{
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][keyBreak]");

		// 退避なし
		if (this.twk_tmpList.size() == 0)
		{
			assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][keyBreak]");
			return;
		}

		ArrayList<JBSbatServiceInterfaceMap> fukaList = new ArrayList<JBSbatServiceInterfaceMap>(); // 利用不可マージ用リスト
		ArrayList<JBSbatServiceInterfaceMap> kyushiList = new ArrayList<JBSbatServiceInterfaceMap>(); // 休止オミット用リスト
		ArrayList<JBSbatServiceInterfaceMap> sonotaList = new ArrayList<JBSbatServiceInterfaceMap>(); // その他出力用リスト

		// 以下３つ分けて処理を行う。
		// １）利用不可あり
		// ２）利用不可なし、休止あり
		// ３）その他
		for (int i = 0; i < this.twk_tmpList.size(); i++)
		{
			JBSbatServiceInterfaceMap tmpMap = this.twk_tmpList.get(i);

			if (!JACStrConst.KARA_MOJI.equals(tmpMap.getString(JBSbatACIFM170.SVC_USE_FAIL_STAYMD)))
			{
				// １）利用不可期間を1レコードとして出力するため
				// 　　利用不可開始日が設定されているレコードはfukaListへ退避し、for文の後でマージして出力する
				fukaList.add(tmpMap);
			}
			else if (!JACStrConst.KARA_MOJI.equals(tmpMap.getString(JBSbatACIFM170.SVC_PAUSE_DAY)))
			{
				// ２）休止レコードが複数あった場合、直近のみ出力するため分けて退避する
				kyushiList.add(tmpMap);
			}
			else
			{
				// ３）その他は1レコードずつ出力する
				sonotaList = new ArrayList<JBSbatServiceInterfaceMap>();
				sonotaList.add(tmpMap);
				this.outPutRec(sonotaList, outputInItem, false);
			}
		}

		// １-２）利用不可マージ用のリストが存在するとき、利用不可日数の計算をして出力
		if (fukaList.size() != 0)
		{
			this.outPutRec(fukaList, outputInItem, true);
		}

		// ２-２）休止オミット用リストが存在するとき、最後のリストのみを出力する
		if (kyushiList.size() != 0)
		{
			ArrayList<JBSbatServiceInterfaceMap> kyushiOmtList = new ArrayList<JBSbatServiceInterfaceMap>();
			kyushiOmtList.add(kyushiList.get(kyushiList.size() - 1));
			this.outPutRec(kyushiOmtList, outputInItem, false);
		}

		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][keyBreak]");
	}

	/**
	 * 出力処理
	 * @param  tmpList 
	 * @param  outputInItem 
	 * @param  flg 
	 * @throws Exception
	 */
	private void outPutRec(ArrayList<JBSbatServiceInterfaceMap> tmpList, JBSbatOutputItem outputInItem, boolean flg) throws Exception
	{
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][outPutRec]");

		String useStaYmd 			= null; // 利用開始日
		String useEndYmd 			= null; // 利用終了日
		String tmpFistChrgStaYmd 	= null; // 課金開始日
		String tmpLastChrgEndYmd 	= null; // 課金終了日
		String gunNextYmd 			= null; // 群月翌月初日

		int notUseStr 		= 0; // 未利用期間（開始）
		int nouUseEnd 		= 0; // 未利用期間（終了）
		int riyoDateCount 	= 0; // 利用日数
		int lastInd 		= 0; // 退避リスト最終件インデックス

		boolean riyoDateCntFlg = true; // 利用日数計算フラグ

		boolean riyoJudgeFlg = true; // 利用判定フラグ

		boolean gunStrJudgeFlg = false; // 月初終了判定フラグ

		// 群月翌月初日取得
		gunNextYmd = JPCUtilCommon.addMonth(this.gunStr, 1);

		// サービスを利用していない期間の算出
		// 退避リスト[1件目]．課金開始日
		tmpFistChrgStaYmd 	= tmpList.get(0).getString(JBSbatACIFM170.CHRG_STAYMD);

		// 退避リスト[最終件]．課金終了日
		lastInd = tmpList.size() - 1;
		tmpLastChrgEndYmd 	= tmpList.get(lastInd).getString(JBSbatACIFM170.CHRG_ENDYMD);

		if(JACStrConst.KARA_MOJI.equals(tmpFistChrgStaYmd))
		{
			// 課金開始日が設定されていない場合
			riyoDateCount = 0;
			useStaYmd = JACStrConst.KARA_MOJI;
			useEndYmd = JACStrConst.KARA_MOJI;
		}
		else 
		{
			// 課金終了日が設定されていて、課金開始＞課金終了−１日（初月解約）の場合
			if (!JACStrConst.KARA_MOJI.equals(tmpLastChrgEndYmd) && tmpFistChrgStaYmd.compareTo(JPCUtilCommon.addDay(tmpLastChrgEndYmd, -1)) > 0)
			{
				riyoDateCntFlg = false;
			}
			// 課金終了日＜群月初日の場合
			else if(tmpLastChrgEndYmd.compareTo(this.gunStr) < 0)
			{
				// 群月初日より前に課金終了している場合
				riyoJudgeFlg = false;
			}
			else if(tmpLastChrgEndYmd.compareTo(this.gunStr) == 0)
			{
				// 群月初日　で課金終了している場合
				gunStrJudgeFlg = true;
			}

			// 群月初日から課金開始	
			if(tmpFistChrgStaYmd.compareTo(this.gunStr) < 0)
			{
				// 課金終了日≧群月初日の場合
				if(tmpLastChrgEndYmd.compareTo(this.gunStr) >= 0)
				{
					// ◆利用開始日　←　群月初日
					useStaYmd = this.gunStr;
				}
				else
				{
					// 前月以前で課金終了している場合
					riyoJudgeFlg = false;
				}

				// 0日間
				notUseStr = 0;
			}
			// 群月初日より後に課金開始
			else
			{
				// ◆利用開始日　←　課金開始日
				useStaYmd = tmpFistChrgStaYmd;

				// 退避リスト[1件目]．課金開始日　-　群月初日
				notUseStr = JPCUtilCommon.subtractDay(tmpFistChrgStaYmd, this.gunStr);
			}

			//////////////////////////////////
			// B.課金終了日 から 群締め日
			//////////////////////////////////
			if (tmpLastChrgEndYmd.length() == 0 || tmpLastChrgEndYmd.compareTo(gunNextYmd) >= 0)
			{
				// 群締め日まで課金対象の場合
				// 　退避リスト[最終件]．課金終了日　＝　未設定　 または
				// 　退避リスト[最終件]．課金終了日　≧　翌群月初日

				// ◆利用終了　←　群締め日
				useEndYmd = this.gunEnd;

				// 0日間
				nouUseEnd = 0;
			}
			else
			{
				// 翌郡月初日より前に課金終了した場合	
				// 　退避リスト[最終件]．課金終了日　＜　翌群月初日

				// ◆利用終了　←　課金終了日
				useEndYmd = tmpLastChrgEndYmd;

				// 群締め日　-　退避リスト[最終件]．課金終了日
				nouUseEnd = JPCUtilCommon.subtractDay(this.gunEnd, useEndYmd);
			}

			// ◆利用期間
			if (riyoDateCntFlg)
			{
				// 　利用日数　←　歴日数 - サービスを利用していない期間（未利用期間（開始）＋（終了））
				riyoDateCount = this.calDay - (notUseStr + nouUseEnd);
			}
			else
			{
				riyoDateCount = 1;
				useStaYmd = tmpFistChrgStaYmd;
				useEndYmd = tmpLastChrgEndYmd;
			}

			// 課金開始日＞群締め日及び課金終了日＞群締め日の場合
			if(tmpFistChrgStaYmd.compareTo(this.gunEnd) > 0 && tmpLastChrgEndYmd.compareTo(this.gunEnd) > 0)
			{
				riyoJudgeFlg = false;
			}
		}

		//   利用期間外の場合
		if (!riyoJudgeFlg)
		{
			riyoDateCount = 0;
			useStaYmd = JACStrConst.KARA_MOJI;
			useEndYmd = JACStrConst.KARA_MOJI;
		}
		//   月初終了の場合
		else if(gunStrJudgeFlg)
		{
			riyoDateCount = 1;
			useStaYmd = this.gunStr;
			useEndYmd = this.gunStr;
		}

		// ◆利用不可日数
		int riyoFuka = 0;

		//   利用不可期間の算出
		if (flg)
		{
			riyoFuka = this.getNotUseDays(tmpList);
		}

		// マップより（退避リストの最終件目取得）
		JBSbatServiceInterfaceMap tmpList1 = tmpList.get(lastInd);

		// 料金サービス条件検索用キー
		StringBuffer mapKeyBuf = new StringBuffer();
		mapKeyBuf.append(tmpList1.getString(JBSbatACIFM170.PCRS_CD)); 			// 料金コースコード
		mapKeyBuf.append(tmpList1.getString(JBSbatACIFM170.PRC_SVC_CD)); 	// 料金サービスコード

		// 出力レコード情報設定
		JBSbatServiceInterfaceMap outRecMap = new JBSbatServiceInterfaceMap();

		// 出力情報設定
		outRecMap.setString(JBSbatACIFM170.PCRS_CD,						tmpList1.getString(JBSbatACIFM170.PCRS_CD)); 					// 01.料金コースコード
		outRecMap.setString(JBSbatACIFM170.PRC_SVC_CD,					tmpList1.getString(JBSbatACIFM170.PRC_SVC_CD)); 				// 02.料金サービスコード
		outRecMap.setString(JBSbatACIFM170.TAKNKIKI_MODEL_CD,			tmpList1.getString(JBSbatACIFM170.TAKNKIKI_MODEL_CD)); 			// 03.宅内機器型式コード
		outRecMap.setString(JBSbatACIFM170.SVC_NO,						tmpList1.getString(JBSbatACIFM170.SVC_NO)); 					// 04.サービス番号
		outRecMap.setString(JBSbatACIFM170.JYUZOKU_SVC_NO,				tmpList1.getString(JBSbatACIFM170.JYUZOKU_SVC_NO));				// 05.従属サービス番号
		outRecMap.setString(JBSbatACIFM170.SEIKY_KEI_NO,				tmpList1.getString(JBSbatACIFM170.SEIKY_KEI_NO)); 				// 06.請求先番号
		outRecMap.setString(JBSbatACIFM170.SEIKY_YM,					this.seikyYM); 													// 07.請求年月
		outRecMap.setString(JBSbatACIFM170.WRIB_SVC_KEI_NO,				tmpList1.getString(JBSbatACIFM170.WRIB_SVC_KEI_NO)); 			// 08.割引サービス契約番号
		outRecMap.setString(JBSbatACIFM170.WRISVC_TRGT_KEI_NO,			tmpList1.getString(JBSbatACIFM170.WRISVC_TRGT_KEI_NO)); 		// 09.割引サービス対象契約番号
		outRecMap.setString(JBSbatACIFM170.SVC_STAYMD,					tmpList1.getString(JBSbatACIFM170.SVC_STAYMD)); 				// 10.サービス開始日
		outRecMap.setString(JBSbatACIFM170.SVC_DSL_YMD,					tmpList1.getString(JBSbatACIFM170.SVC_DSL_YMD)); 				// 11.サービス解約日
		outRecMap.setString(JBSbatACIFM170.SVC_DLRE,					tmpList1.getString(JBSbatACIFM170.SVC_DLRE)); 					// 12.サービス解約理由
		outRecMap.setString(JBSbatACIFM170.SVC_KAIHK_DAY,				tmpList1.getString(JBSbatACIFM170.SVC_KAIHK_DAY)); 				// 13.サービス回復日
		outRecMap.setString(JBSbatACIFM170.SVC_CANCEL_DAY,				tmpList1.getString(JBSbatACIFM170.SVC_CANCEL_DAY)); 			// 14.サービスキャンセル日
		outRecMap.setString(JBSbatACIFM170.SVC_PAUSE_DAY,				tmpList1.get(JBSbatACIFM170.SVC_PAUSE_DAY)); 					// 15.サービス休止日
		outRecMap.setString(JBSbatACIFM170.SVC_PAUSE_RLS_YMD,			tmpList1.get(JBSbatACIFM170.SVC_PAUSE_RLS_YMD)); 				// 16.サービス休止解除日
		outRecMap.setString(JBSbatACIFM170.SVC_USE_FAIL_STAYMD,			tmpList1.get(JBSbatACIFM170.SVC_USE_FAIL_STAYMD));				// 17.サービス利用不可開始日
		outRecMap.setString(JBSbatACIFM170.SVC_USE_FAIL_ENDYMD,			tmpList1.get(JBSbatACIFM170.SVC_USE_FAIL_ENDYMD));				// 18.サービス利用不可終了日
		outRecMap.setString(JBSbatACIFM170.USE_STAYMD,					useStaYmd); 													// 19.利用開始日
		outRecMap.setString(JBSbatACIFM170.USE_ENDYMD,					useEndYmd); 													// 20.利用終了日
		outRecMap.setBigDecimal(JBSbatACIFM170.USE_DAY_CNT,				riyoDateCount); 												// 21.利用日数
		outRecMap.setBigDecimal(JBSbatACIFM170.USE_FAIL_DAY_CNT,		riyoFuka); 														// 22.利用不可日数
		outRecMap.setString(JBSbatACIFM170.CHRG_STAYMD,					tmpList1.getString(JBSbatACIFM170.CHRG_STAYMD)); 				// 23.課金開始日
		outRecMap.setString(JBSbatACIFM170.FIRST_CHRG_STAYMD,			tmpList1.getString(JBSbatACIFM170.FIRST_CHRG_STAYMD)); 			// 24.初回課金開始日
		outRecMap.setString(JBSbatACIFM170.CHRG_ENDYMD,					tmpList1.getString(JBSbatACIFM170.CHRG_ENDYMD)); 				// 25.課金終了日
		outRecMap.setBigDecimal(JBSbatACIFM170.SVC_KEIZOKU_MON_CNT,		tmpList1.getBigDecimal(JBSbatACIFM170.SVC_KEIZOKU_MON_CNT));	// 26.サービス継続月数
		outRecMap.setBigDecimal(JBSbatACIFM170.SVC_KEIZOKU_DAY_CNT,		tmpList1.getBigDecimal(JBSbatACIFM170.SVC_KEIZOKU_DAY_CNT));	// 27.サービス継続日数
		outRecMap.setBigDecimal(JBSbatACIFM170.CHRG_KEIZOKU_MON_CNT,	tmpList1.getBigDecimal(JBSbatACIFM170.CHRG_KEIZOKU_MON_CNT)); 	// 28.課金継続月数
		outRecMap.setBigDecimal(JBSbatACIFM170.CHRG_KEIZOKU_DAY_CNT,	tmpList1.getBigDecimal(JBSbatACIFM170.CHRG_KEIZOKU_DAY_CNT)); 	// 29.課金継続日数
		outRecMap.setBigDecimal(JBSbatACIFM170.KEI_CNT,					tmpList1.getBigDecimal(JBSbatACIFM170.KEI_CNT)); 				// 30.契約数
		outRecMap.setBigDecimal(JBSbatACIFM170.MON_CHU_MAX_KEI_CNT,		tmpList1.getBigDecimal(JBSbatACIFM170.MON_CHU_MAX_KEI_CNT)); 	// 31.月中最大契約数
		outRecMap.setString(JBSbatACIFM170.AIT_DIV,						tmpList1.getString(JBSbatACIFM170.AIT_DIV)); 					// 32.相対区分
		outRecMap.setString(JBSbatACIFM170.SIME_DAY,					tmpList1.getString(JBSbatACIFM170.SIME_DAY)); 					// 33.締め日
		outRecMap.setString(JBSbatACIFM170.MANSION_ID,					tmpList1.getString(JBSbatACIFM170.MANSION_ID)); 				// 34.マンションＩＤ
		outRecMap.setString(JBSbatACIFM170.TK_HOSHIKI_KEI_NO,			tmpList1.getString(JBSbatACIFM170.TK_HOSHIKI_KEI_NO)); 			// 35.提供方式契約番号
		outRecMap.setString(JBSbatACIFM170.KANYU_KEI_PAY_HOSHIKI_CD,	tmpList1.getString(JBSbatACIFM170.KANYU_KEI_PAY_HOSHIKI_CD)); 	// 36.加入契約支払方式コード

		outRecMap.setOutFlg(true);

		outputInItem.addOutMapList(outRecMap);
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][outPutRec]");
	}

	/**
	 * 開始、終了日の調整処理
	 * 以下の場合、開始、終了日の調整をする
	 * １．開始日　＜　群開始日　の場合
	 *   　群開始日とする。
	 * ２．未設定　または　群締め日＜終了日
	 *   　群締め日とする。
	 * @param  tmpList
	 * @return int 利用不可期間
	 * @throws Exception
	 */
	private int getNotUseDays(ArrayList<JBSbatServiceInterfaceMap> tmpList) throws Exception
	{
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][getnotUseDays]");

		// 利用不可リスト
		ArrayList<String[]> svcUseFailList = new ArrayList<String[]>();

		for (int i = 0; i < tmpList.size(); i++)
		{
			JBSbatServiceInterfaceMap tmpMap = tmpList.get(i);

			// サービス利用不可開始日を求める
			String useFailStaYmd = tmpMap.getString(JBSbatACIFM170.SVC_USE_FAIL_STAYMD); // サービス利用不可開始日

			// サービス利用不可開始日　＜　群月初日の場合
			if (useFailStaYmd.compareTo(this.gunStr) < 0)
			{
				// 群月初日
				useFailStaYmd = this.gunStr;
			}

			// サービス利用不可終了日を求める
			String useFailEndYmd = tmpMap.getString(JBSbatACIFM170.SVC_USE_FAIL_ENDYMD); // サービス利用不可終了日
																							// 利用期間含まない
			String chrgEndYmd = tmpMap.getString(JBSbatACIFM170.CHRG_ENDYMD); // 課金終了日

			// 課金終了日に設定あり、かつ　課金終了日　＜　サービス利用不可終了日の場合
			if (!JACbatRknBusinessUtil.isNull(chrgEndYmd) && JPCUtilCommon.addDay(chrgEndYmd, -1).compareTo(useFailEndYmd) < 0)
			{
				useFailEndYmd = chrgEndYmd;
			}

			this.setList(svcUseFailList, useFailStaYmd, useFailEndYmd);
		}

		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][getnotUseDays]");

		// 利用不可期間の計算
		return this.keisan(svcUseFailList);
	}

	/**
	 * 利用不可期間リスト設定処理を行います。
	 * @param inList リスト
	 * @param str 開始日
	 * @param end 終了日
	 */
	private void setList(ArrayList<String[]> inList, String str, String end)
	{
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][setList]");

		// 開始日が空のデータ　または　開始日が未来のデータ（締め日＜開始日）
		if (JACStrConst.KARA_MOJI.equals(str) || this.gunEnd.compareTo(str) < 0)
		{
			assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][setList]");

			// 処理対象外とし、リストに設定しない
			return;
		}

		// 終了日が当月以降　または　未設定の場合（群締め日　＜　終了日）
		if (this.gunEnd.compareTo(end) < 0 || JACStrConst.KARA_MOJI.equals(end))
		{
			// 締め日とする
			end = this.gunEnd;
		}

		String[] listData = null; // リスト内要素

		// 最後が同じ場合、同じ日付が存在するか確認する
		if (inList.size() != 0)
		{
			listData = inList.get(inList.size() - 1);

			// リスト[最後]．開始日　＝　入力．開始日の場合
			if (listData[0].equals(str))
			{
				// 要素を更新し、処理終了
				listData[1] = end;
				assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][setList]");
				return;
			}
		}

		String[] addData = new String[2]; // 追加要素

		// 同じ開始日がない場合
		// 最後に追加する
		addData[0] = str;
		addData[1] = end;
		inList.add(addData);
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][setList]");
	}

	/**
	 * 利用不可期間の計算処理
	 * @param  inList 
	 * @return 利用不可期間
	 */
	private int keisan(ArrayList<String[]> inList)
	{
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][keisan]");

		// 利用不可期間
		int rtn = 0;

		// 利用不可期間のリストが存在する場合計算する
		if (inList.size() != 0)
		{
			// リスト分繰り返し
			for (int i = 0; i < inList.size(); i++)
			{
				String[] data = inList.get(i);

				String str = data[0];
				String end = data[1];

				// 2件目以降、
				// 前回と重複している場合、開始日を重複後からとする。
				if (i >= 1)
				{
					String[] bfDate = inList.get(i - 1);
					String bfEnd = bfDate[1];

					// 前回．終了日 >= 今回．開始日
					if (bfEnd.compareTo(str) >= 0)
					{
						// 今回開始日　←　前回終了日 + 1
						str = JPCUtilCommon.addDay(bfEnd, 1);
					}
				}

				// 終了日 - 開始日を足していく。
				rtn = rtn + JPCUtilCommon.subtractDay(end, str) + 1;

				assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "keisan: keisan=" + rtn + " 開始：str=" + str + "終了：end=" + end);
			}
		}
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][keisan]");
		return rtn;
	}

	/**
	 * キー情報取得処理<BR>
	 * キー情報：料金コースコード　＋　料金サービスコード　＋　請求契約番号（請求先番号）　＋　サービス番号
	 * @param inMap 入力情報
	 * @return String キー情報
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	
	private String getKeyInfo(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][getKeyInfo]");
		StringBuffer keyBuf = new StringBuffer();
		keyBuf.append(inMap.getString(JBSbatACIFM170.PCRS_CD)); 		// 料金コースコード
		keyBuf.append(inMap.getString(JBSbatACIFM170.PRC_SVC_CD)); 		// 料金サービスコード
		keyBuf.append(inMap.getString(JBSbatACIFM170.SEIKY_KEI_NO)); 	// 請求契約番号（請求先番号）
		keyBuf.append(inMap.getString(JBSbatACIFM170.SVC_NO)); 			// サービス番号
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][getKeyInfo]");
		return keyBuf.toString();
	}

}
