/*********************************************************************
*  All Rights reserved,Copyright (c) K-Opticom  					 *
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JBSbatACTrgtJrSvcKeiMake
*	ソースファイル名	：JBSbatACTrgtJrSvcKeiMake.java
*	作成者				：富士通　
*	作成日				：2011年07月19日
*＜機能概要＞
*　課金対象従量サービス契約情報作成部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/07/19   富士通		新規作成
*	v3.00		2012/06/21   FJ)永田	【ANK-0024-04-00】
*	v3.01		2012/07/23   FJ)今井	【TG1-2012-0000002_BAT】
*	v3.02		2012/09/07   FJ)冨井	【ST2-2012-0001651】
**	v3.03		2012/10/08   FJ)岡田	【ST3-2012-0000331】整理番号NULL対応
*	v4.00		2013/02/06   FJ)早崎	【ST3-2013-0000347】課金開始日不正対応
*	v4.01		2013/03/08   FJ)広野	【ST4-2013-0000095】シーケンス採番方法変更。java内でカウントアップし、加算数をファイル出力する。
*	v4.02		2013/03/13   FJ)浜口	【TG1-2013-0000070】通信料未取込対応
*	v4.03		2013/04/05   FJ)小柴	【IKK-2013-0000783】文字化け対策のため、エンコード形式の変更
*	v4.04		2013/04/14   FJ)早崎	【TG1-2013-0000153】TG1-2013-0000070対応戻し対応
*	v4.05		2013/05/20   FJ)小野	【TG1-2013-0000323】従量サービス契約IF過去履歴除外対応
*	v5.00		2013/06/25   FJ)早崎	【TG1-2013-0000644】(関連対応)eo光電話契約履歴の除外判定改修
*	v5.01		2013/07/12   FJ)岡田	【TG1-2013-0000662】マスタ参照基準日水平展開対応
*	v5.02		2013/07/12   FJ)後藤	【TG1-2013-0000662】eo-netフォン・TELvision請求タイミング考慮
*	v5.03		2013/07/28   FJ)狭間	【TG1-2013-0000718】料金サービス識別コードがセットされない不具合を修正
*	v8.00		2014/03/17   FJ)後藤	【OM-2014-0001052】過去解約済でも最新データを残す仕様に修正
*	v10.00		2014/09/01   FJ)鈴木	【OM-2014-0002772】FTTHの場合、請求契約番号＋サービス契約番号をキーとして判定するように修正
*	v25.00.00	2016/07/04   FJ)中山	【OM-2016-0001645】シーケンスの桁あふれ対応
*********************************************************************/
package eo.business.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import eo.business.common.JACBatCommon;
import eo.business.common.JACbatDebugLogUtil;
import eo.business.common.JACbatRknBusinessUtil;
import eo.business.common.JACbatSchdlUtil;
import eo.business.common.JBSbatBusinessService;
import eo.business.common.JCCBatCommon;
import eo.business.util.file.JBSbatACIFI001;
import eo.business.util.file.JBSbatACIFI013;
import eo.business.util.file.JBSbatACIFM062;
import eo.business.util.table.JBSbatAC_M_PRC_SVC_KANRI;
import eo.common.constant.JACStrConst;
import eo.common.util.JPCUtilCommon;
import eo.framework.db.JBSbatSQLAccess;
import eo.framework.file.JBSbatDefFileUtil;
import eo.framework.file.JBSbatOutputFileUtil;
import eo.framework.item.JBSbatCommonDBInterface;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.item.JBSbatServiceInterfaceMap;
import eo.framework.util.JBSbatAplConst;
import eo.framework.util.JBSbatBusinessFileUtil;

/**
* (クラスの機能概要) <p>
*<BR>
* @author 富士通
*/
public class JBSbatACTrgtJrSvcKeiMake extends JBSbatBusinessService
{
	/**▼▼▼▼▼▼ツールから生成した宣言です 開始▼▼▼▼▼▼*/

	/** テーブル(料金サービス管理)*/
	private static final String D_TBL_NAME_AC_M_PRC_SVC_KANRI = "AC_M_PRC_SVC_KANRI";

	/** SQL定義キー(AC_SELECT_001)*/
	private static final String AC_M_PRC_SVC_KANRI_AC_SELECT_001 = "AC_SELECT_001";

	/** テーブルアクセスクラス(料金サービス管理)*/
	private JBSbatSQLAccess db_AC_M_PRC_SVC_KANRI = null;
	/**▲▲▲▲▲▲ツールから生成した宣言です 終了▲▲▲▲▲▲*/

	 /**▼▼▼▼▼▼クラス変数追加 開始▼▼▼▼▼▼*/
	
	/** 料金グループコード桁数 */
	private static final int PRC_GRP_CD_LEN 			= 2;

	/** 料金コースコード桁数 */
	private static final int PCRS_CD_LEN 			= 3;

	/** 料金サービスコード桁数 */
	private static final int PRC_SVC_CD_LEN 			= 12;

	/** 請求契約番号（請求先番号）桁数 */
	private static final int SEIKY_KEI_NO_LEN 		= 10;

	/** 整理番号桁数 */
	private static final int SEIRI_NO_LEN 			= 14;

	/** サービス番号桁数 */
	private static final int SVC_NO_LEN 				= 20;

	/** サービス契約内訳番号桁数 */
	private static final int SVC_KEI_UCWK_NO_LEN 	= 12;

	/** 従属サービス番号桁数 */
	private static final int OP_SVC_KEI_NO_LEN 		= 12;

	/** 割引サービス契約番号桁数 */
	private static final int WRIB_SVC_KEI_NO_LEN 	= 12;

	/** サービス開始日桁数 */
	private static final int SVC_STAYMD_LEN 			= 8;

	/** 初回課金開始日桁数 */
	private static final int FIRST_CHRG_STAYMD_LEN 	= 8;

	/** 課金開始日桁数 */
	private static final int CHRG_STAYMD_LEN 		= 8;

	/** 課金終了日桁数 */
	private static final int CHRG_ENDYMD_LEN 		= 8;

	/** サービス解約日桁数 */
	private static final int SVC_DSL_YMD_LEN 		= 8;

	/** サービス回復日桁数 */
	private static final int SVC_KAIHK_DAY_LEN 		= 8;

	/** サービスキャンセル日桁数 */
	private static final int SVC_CANCEL_DAY_LEN 		= 8;
	
	/**
	 * 料金サービス管理保持用マップ<BR>
	 * 出力ファイル、料金サービス識別コード用。
	 **/
	private HashMap<String, String> db_SvcKnrMap			= new HashMap<String, String>();

	/** 請求年月 */
	private String wk_SkyuYM 	= null;

	/** 群月初日 */
	private String wk_GunStr 	= null;

	/** 群締め日 */
	private String wk_GunEnd 	= null;
	
	/** 前月月末日 */
	private String wk_PrvMonEndDay 	= null;

	/** 請求年月の歴日付 */
	private int	wk_CalDay 	= -1;
	
	// twk_が付く変数は、同一キー単位での情報とする。
	// キーブレイクしたら、初期化すること。
	/**
	 * 当月イベント発生フラグ （true：当月イベントあり、false ：当月イベントなし（初期値））
	 */
	private boolean 	twk_flgIsEvntRslt 	= false;

	/** 入力レコード退避リスト */
	private ArrayList<JBSbatServiceInterfaceMap>	twk_tmpList				= new ArrayList<JBSbatServiceInterfaceMap>();
	
	/** 最終出力マップ */
	private HashMap<String, JBSbatServiceInterfaceMap> finalOutMap = new HashMap<String, JBSbatServiceInterfaceMap>();;

	/** 退避キー(課金開始日最新チェック用) */
	private String tmpBreakKey2 = "";

	/**▲▲▲▲▲▲クラス変数追加 終了▲▲▲▲▲▲*/

	/** 出力ファイル定義 */
	private static final String PRM_OTD 	= "OTD";

	/** 対象キーワークシーケンス更新用ファイル */
	private JBSbatBusinessFileUtil trgtKeyWkSeqFile = null;

	/** フリー項目(カンマsplit済み) */
	private String[] freeItems = null;

	/*▼ シーケンス採番用定義変数 ▼*/
	/** シーケンス名（対象キーワーク番号） */
	private static final String SEQ_NAME_SEQ_CHRG_JSVKEI_CKS_NO = "SEQ_CHRG_JSVKEI_CKS_NO";

	/** シーケンス接頭辞（対象キーワーク番号） */
	private static final String SEQ_PREFIX_SEQ_NAME_SEQ_CHRG_JSVKEI_CKS_NO = "";

	/** シーケンス桁数（対象キーワーク番号） */
	private static final int SEQ_LEN_SEQ_CHRG_JSVKEI_CKS_NO = 20;

//OM-2016-0001645 MOD START
//	/** 対象キーワーク番号（処理前（シーケンスから取得）） */
//	private int seqChrgJsvkeiCksNoBef = 0;
//	
//	/** 対象キーワーク番号（シーケンスから取得） */
//	private int seqChrgJsvkeiCksNo = 0;
	/** 対象キーワーク番号（処理前（シーケンスから取得）） */
	private long seqChrgJsvkeiCksNoBef = 0;
	
	/** 対象キーワーク番号（シーケンスから取得） */
	private long seqChrgJsvkeiCksNo = 0;
//OM-2016-0001645 MOD END

	 /** フリー項目(0)：ファイル項目定義ファイル(ACIFM106) */
	private final int FREEITEM_ACIFM106 = 0;

	/** フリー項目(1)：対象キーワーク更新数ファイル */
	private final int FREEITEM_SEQFILE_TRGT_KEY_WK = 1;
	
	
	/**
	 * 初期処理
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した初期化のソースです 開始▼▼▼▼▼▼*/
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);

		// DBアクセスクラスを生成します
		db_AC_M_PRC_SVC_KANRI = new JBSbatSQLAccess(commonItem, D_TBL_NAME_AC_M_PRC_SVC_KANRI);
		/**▲▲▲▲▲▲ツールから生成した初期化のソースです 終了▲▲▲▲▲▲*/

		// FREEITEMの取得
		freeItems = super.freeItem.split(JACStrConst.SEMI_COLON);
		
		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.wk_SkyuYM = schdUtil.getBillDate(super.opeDate, JACStrConst.EVENT_CD_USE_ENDYMD);
		
		// 群月初日、群締め日　←　JACbatSchdlUtil.getUseStrEnd(請求年月, イベントコード("01"（利用開始日））, イベントコード（"02"（利用終了日））)
		String[] rtn = schdUtil.getUseStrEnd(this.wk_SkyuYM, JACStrConst.EVENT_CD_USE_STAYMD, JACStrConst.EVENT_CD_USE_ENDYMD);
		
		// クローズ
		schdUtil.close();
				
		this.wk_GunStr = rtn[0];
		this.wk_GunEnd = rtn[1];
		
		// バッチ運用日前月月末日
		this.wk_PrvMonEndDay = JCCBatCommon.addDay(wk_GunStr, -1);

		// 請求月の暦日数を取得する（引数：群終了日、群開始日）
		this.wk_CalDay = JPCUtilCommon.subtractDay(wk_GunEnd, wk_GunStr) + 1;
		
		// サービス管理マスタ検索処理 
		this.setSvcKnrMap();

		// シーケンスからサービス契約蓄積番号を取得
//OM-2016-0001645 MOD START
//		this.seqChrgJsvkeiCksNoBef = Integer.parseInt(JCCBatCommon.getFormatedNextSeq(super.commonItem, SEQ_NAME_SEQ_CHRG_JSVKEI_CKS_NO, SEQ_PREFIX_SEQ_NAME_SEQ_CHRG_JSVKEI_CKS_NO, SEQ_LEN_SEQ_CHRG_JSVKEI_CKS_NO));
		this.seqChrgJsvkeiCksNoBef = Long.parseLong(JCCBatCommon.getFormatedNextSeq(super.commonItem, SEQ_NAME_SEQ_CHRG_JSVKEI_CKS_NO, SEQ_PREFIX_SEQ_NAME_SEQ_CHRG_JSVKEI_CKS_NO, SEQ_LEN_SEQ_CHRG_JSVKEI_CKS_NO));
//OM-2016-0001645 MOD END
		
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][initial][シーケンス番号（対象キーワーク）" + this.seqChrgJsvkeiCksNoBef + "]");
		
		this.seqChrgJsvkeiCksNo = this.seqChrgJsvkeiCksNoBef;

		// サービス契約蓄積シーケンス更新用ファイル
		this.trgtKeyWkSeqFile = createFile(freeItems[FREEITEM_SEQFILE_TRGT_KEY_WK], freeItems[FREEITEM_ACIFM106]);
		
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, 
				"バッチ運用日：" + super.opeDate +
				"　群開始日："   + this.wk_GunStr +
				"　群終了日："   + this.wk_GunEnd +
				"　歴日付："     + this.wk_CalDay +
				"　バッチ運用日前月月末日：" + this.wk_PrvMonEndDay);

		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);
			
			// 最終出力判定
			finalOut(outputInItem);
			
			// 処理終了
			return outputInItem;
		}
		
		// 主処理の先頭にて
		// サービスコードをフル桁にする
		inMap.setString(JBSbatACIFI013.TRGT_PRC_SVC_CD,
						JACbatRknBusinessUtil.fullPrcSvcCd(inMap.getString(JBSbatACIFI013.TRGT_PRC_SVC_CD)));

		String inKey 		= null;		// 入力．キー
		String tmpKey 		= null;		// 退避．キー

		// ブレイクキー（入力）の設定
		inKey = getKeyInfo(inMap);

		// 最終出力判定用ブレイクキー2（請求契約番号＋サービス契約内訳番号）
		String inBreakKey2 = inMap.getString(JBSbatACIFI013.SEIKY_KEI_NO).concat(inMap.getString(JBSbatACIFI013.SVC_KEI_UCWK_NO));

		// ■1件目（初回）はここで終了
		
		//   退避．キー ＝ null の場合
		if (!outputInItem.isKeyList())
		{
			// ダミーレコードの設定
			// ※最終レコード後の主処理呼び出しのため
			outputInItem.addOutMapList(new JBSbatServiceInterfaceMap());

			// キー情報設定
			outputInItem.clearKeyList(); 		// キー情報のクリア
			outputInItem.addKeyList(inKey); 	// ブレイクキー（入力）

			tmpBreakKey2 = inBreakKey2;

			// 対象判定処理
			this.checkRec(inMap);

			return outputInItem;
		}

		// ■2件目以降（退避キーが存在する場合）
		// 退避．キーの取得
		tmpKey = (String)outputInItem.getKeyList().get(0);

		// 出力情報設定
		// 入力．キー ＝　退避．キー
		if (inKey.equals(tmpKey))
		{
			// 対象判定処理
			this.checkRec(inMap);
		}
		// 入力．キー ≠　退避．キー
		else
		{
			this.keyBreak(outputInItem);
			
			// 最終出力判定
			if(!tmpBreakKey2.equals(inBreakKey2))
			{
				// 出力
				finalOut(outputInItem);
				
				// 退避クリア
				finalOutMap = new HashMap<String, JBSbatServiceInterfaceMap>();
				tmpBreakKey2 = inBreakKey2;
				
			}
			// 退避クリア
			this.twk_flgIsEvntRslt = false;
			this.twk_tmpList       = new ArrayList<JBSbatServiceInterfaceMap>();

			// キー情報設定
			outputInItem.clearKeyList(); 		// キー情報のクリア
			outputInItem.addKeyList(inKey); 	// ブレイクキー（入力）

			// 対象判定処理
			this.checkRec(inMap);
		}

		assert outputInItem != null ? JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][execute][outputInItem=" + outputInItem.getOutMapList().toString() + "]") : true;
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][execute]");
		return outputInItem;
	/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼*/
		// DBアクセスクラスをクローズします
		db_AC_M_PRC_SVC_KANRI.close();

		// サービス契約シーケンス更新用ファイル出力
		this.outSeqNo();

		// サービス契約蓄積シーケンス更新用ファイルクローズ
		JCCBatCommon.closeBusinessFileUtil(this.trgtKeyWkSeqFile);
		/**▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲*/
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][terminal]");
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][terminal]");
	/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}

	/**▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼*/

	/**
	 * SQLKEY(AC_SELECT_001)でDBアクセスを行います。<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.引数でバイント変数を設定します。<br>
	 *
	 * 2.DBアクセスを実行します。<br>
	 * 
	 * 3.メソッドの呼び出し方です。<br>
	 *		引数:
	 *		param:順にバイント変数の値をparam配列に入れます。バイント変数は以下に説明します。
	 *		 	システムコード
	 *		 	バッチ運用日
	 * </pre>
	 * <p>
	 * @param param バイント変数の値配列。
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void executeAC_M_PRC_SVC_KANRI_AC_SELECT_001(Object[] param) throws Exception
	{
		// バイント変数のリストを生成します
		JBSbatCommonDBInterface paramList = new JBSbatCommonDBInterface();
		paramList.setValue(param[0].toString());
		paramList.setValue(param[1].toString());

		// DBアクセスを実行します
		db_AC_M_PRC_SVC_KANRI.selectBySqlDefine(paramList, AC_M_PRC_SVC_KANRI_AC_SELECT_001);
	}
	/**▲▲▲▲▲▲ツールから生成したメソッドです 終了▲▲▲▲▲▲*/

	/**▼▼▼▼▼▼メソッド追加 開始▼▼▼▼▼▼*/	
	
	/**
	 * サービス管理マスタ検索処理 <br>
	 * 検索結果は、HashMap（this.db_SvcKnrMap）へ設定する。 <br>
	 * 　　キー：料金コースコード　＋ 料金サービスコード <br>
	 * 　　値　：料金サービス識別コード<br>
	 * <br>
	 * 出力ファイルの編集にて使用する。
	 * 
	 * @throws Exception
	 */
	private void setSvcKnrMap() throws Exception
	{
		// ＤＢアクセス用のパラメータ定義
		JBSbatCommonDBInterface dbList = new JBSbatCommonDBInterface();

		dbList.setValue(super.systemCode);		// システムコード
		dbList.setValue(this.wk_GunEnd); 		// 適用開始年月日,適用終了年月日

		// SELECT文発行 サービス管理マスタ情報
		executeAC_M_PRC_SVC_KANRI_AC_SELECT_001(dbList.getList().toArray());

		// 料金項目コードの設定
		JBSbatCommonDBInterface dbMap = db_AC_M_PRC_SVC_KANRI.selectNext();

		// 取得情報が存在する間繰り返す
		while (dbMap != null)
		{
			StringBuffer keyBuf = new StringBuffer();

			keyBuf.append(dbMap.getString(JBSbatAC_M_PRC_SVC_KANRI.PCRS_CD)); 		// 料金コースコード
			keyBuf.append(dbMap.getString(JBSbatAC_M_PRC_SVC_KANRI.PRC_SVC_CD));	// 料金サービスコード

			// キー :料金コースコード＋料金サービスコード
			// 値　 :料金サービス識別コード
			db_SvcKnrMap.put(keyBuf.toString(), dbMap.getString(JBSbatAC_M_PRC_SVC_KANRI.PRC_SVC_SKBT_CD));

			// 次レコード取得
			dbMap = db_AC_M_PRC_SVC_KANRI.selectNext();
		}

	}

	/**
	 * キー情報取得処理<BR>
	 * キー情報：料金グループコード　＋　料金コースコード　＋　料金サービスコード
	 *           ＋　請求契約番号（請求先番号）　＋　整理番号　＋　サービス番号
	 *           ＋　従属サービス番号　＋　割引サービス契約番号
	 *           ＋　サービス開始日　＋　初回課金開始日　＋　課金開始日　＋　課金終了日
	 *           ＋　サービス解約日　＋　サービス回復日　＋　サービスキャンセル日
	 * @param  inMap 入力情報
	 * @return String キー情報
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private String getKeyInfo(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		StringBuffer keyBuf = new StringBuffer();
		
		// 料金グループコード
		keyBuf.append(JACbatRknBusinessUtil.fillHalfSpace(inMap.getString(JBSbatACIFI013.PRC_GRP_CD), 			PRC_GRP_CD_LEN, 		true));
		
		// 料金コースコード
		keyBuf.append(JACbatRknBusinessUtil.fillHalfSpace(inMap.getString(JBSbatACIFI013.PCRS_CD), 				PCRS_CD_LEN, 			true));
		
		// 料金サービスコード
		keyBuf.append(JACbatRknBusinessUtil.fillHalfSpace(inMap.getString(JBSbatACIFI013.TRGT_PRC_SVC_CD), 		PRC_SVC_CD_LEN, 		true));
		
		// 請求契約番号（請求先番号）
		keyBuf.append(JACbatRknBusinessUtil.fillHalfSpace(inMap.getString(JBSbatACIFI013.SEIKY_KEI_NO), 		SEIKY_KEI_NO_LEN, 		true));
		
		// 整理番号
		keyBuf.append(JACbatRknBusinessUtil.fillHalfSpace(inMap.getString(JBSbatACIFI013.SEIRI_NO), 			SEIRI_NO_LEN, 			true));
		
		// サービス番号
		keyBuf.append(JACbatRknBusinessUtil.fillHalfSpace(inMap.getString(JBSbatACIFI013.SVC_NO), 				SVC_NO_LEN, 			true));
		
		// サービス契約内訳番号
		keyBuf.append(JACbatRknBusinessUtil.fillHalfSpace(inMap.getString(JBSbatACIFI013.SVC_KEI_UCWK_NO), 		SVC_KEI_UCWK_NO_LEN, 	true));
		
		// 従属サービス番号
		keyBuf.append(JACbatRknBusinessUtil.fillHalfSpace(inMap.getString(JBSbatACIFI013.OP_SVC_KEI_NO), 		OP_SVC_KEI_NO_LEN, 		true));
		
		// 割引サービス契約番号
		keyBuf.append(JACbatRknBusinessUtil.fillHalfSpace(inMap.getString(JBSbatACIFI013.WRIB_SVC_KEI_NO), 		WRIB_SVC_KEI_NO_LEN, 	true));
		
		// サービス開始日
		keyBuf.append(JACbatRknBusinessUtil.fillHalfSpace(inMap.getString(JBSbatACIFI013.SVC_STAYMD), 			SVC_STAYMD_LEN, 		true));
		
		// 初回課金開始日
		keyBuf.append(JACbatRknBusinessUtil.fillHalfSpace(inMap.getString(JBSbatACIFI013.FIRST_CHRG_STAYMD), 	FIRST_CHRG_STAYMD_LEN, 	true));
		
		// 課金開始日
		keyBuf.append(JACbatRknBusinessUtil.fillHalfSpace(inMap.getString(JBSbatACIFI013.CHRG_STAYMD), 			CHRG_STAYMD_LEN, 		true));
		
		// 課金終了日
		keyBuf.append(JACbatRknBusinessUtil.fillHalfSpace(inMap.getString(JBSbatACIFI013.CHRG_ENDYMD), 			CHRG_ENDYMD_LEN, 		true));
		
		// サービス解約日
		keyBuf.append(JACbatRknBusinessUtil.fillHalfSpace(inMap.getString(JBSbatACIFI013.SVC_DSL_YMD), 			SVC_DSL_YMD_LEN, 		true));
		
		// サービス回復日
		keyBuf.append(JACbatRknBusinessUtil.fillHalfSpace(inMap.getString(JBSbatACIFI013.SVC_KAIHK_DAY), 		SVC_KAIHK_DAY_LEN, 		true));
		
		// サービスキャンセル日
		keyBuf.append(JACbatRknBusinessUtil.fillHalfSpace(inMap.getString(JBSbatACIFI013.SVC_CANCEL_DAY), 		SVC_CANCEL_DAY_LEN, 	true));
		
		return keyBuf.toString();
	}

	/**
	 * キーブレイク時の処理
	 * 1）退避リストに設定した情報から以下の情報を求める。
	 *    ・利用開始日
	 *    ・利用終了日
	 *    ・利用日数
	 *    ・利用不可日数
	 * 2）計算した結果を出力レコードへ設定する
	 * @param outputInItem 出力共通電文クラス
	 * @throws Exception
	 */
	public void keyBreak(JBSbatOutputItem outputInItem) throws Exception
	{
		// 退避なし
		if(this.twk_tmpList.size() == 0)
		{
			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);
			
			// １）利用不可期間を1レコードとして出力するため
			// 　　利用不可開始日が設定されているレコードはfukaListへ退避し、for文の後でマージして出力する
			if(!tmpMap.getString(JBSbatACIFI013.SVC_USE_FAIL_STAYMD).equals(JACStrConst.KARA_MOJI))
			{
				fukaList.add(tmpMap);
			}
			// ２）休止レコードが複数あった場合、直近のみ出力するため分けて退避する
			else if(!tmpMap.getString(JBSbatACIFI013.SVC_PAUSE_DAY).equals(JACStrConst.KARA_MOJI))
			{
				kyushiList.add(tmpMap);
			}
			// ３）その他は1レコードずつ出力する
			else
			{
				sonotaList = new ArrayList<JBSbatServiceInterfaceMap>();
				sonotaList.add(tmpMap);
				this.outPutRec(sonotaList, outputInItem, false);
			}
		}
		
		// １-２）利用不可マージ用のリストが存在するとき、利用不可日数の計算をして出力
		if(!fukaList.isEmpty())
		{
			this.outPutRec(fukaList, outputInItem, true);
		}
		
		// ２-２）休止オミット用リストが存在するとき、最後のリストのみを出力する
		if(!kyushiList.isEmpty())
		{
			ArrayList<JBSbatServiceInterfaceMap> kyushiOmtList = new ArrayList<JBSbatServiceInterfaceMap>();
			kyushiOmtList.add(kyushiList.get(kyushiList.size() - 1));
			this.outPutRec(kyushiOmtList, outputInItem, false);
		}

	}

	/**
	 * 課金対象サービス契約情報レコードを出力する
	 * @param  tmpList 退避リスト
	 * @param  outputInItem 出力オブジェクト
	 * @param  flg 利用不可日数の計算実施フラグ
	 * 
	 * 
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void outPutRec(ArrayList<JBSbatServiceInterfaceMap> tmpList, JBSbatOutputItem outputInItem, boolean flg) throws Exception
	{
		String useStaYmd 			= null; // 利用開始日
		String useEndYmd 			= null; // 利用終了日
		String tmpFistChrgStaYmd 	= null; // 課金開始日
		String tmpLastChrgEndYmd 	= null; // 課金終了日
		
		int notUseStr 		= 0; // 未利用期間（開始）
		int nouUseEnd 		= 0; // 未利用期間（終了）
		int riyoDateCount 	= 0; // 利用日数
		int lastInd 		= 0; // 退避リスト最終件インデックス
		
		boolean riyoDateCntFlg = true; // 利用日数計算フラグ
		
		// サービスを利用していない期間の算出
		// 退避リスト[1件目]．課金開始日
		tmpFistChrgStaYmd 	= tmpList.get(0).getString(JBSbatACIFI013.CHRG_STAYMD);
		
		// 退避リスト[最終件]．課金終了日
		lastInd = tmpList.size() - 1;
		tmpLastChrgEndYmd 	= tmpList.get(lastInd).getString(JBSbatACIFI013.CHRG_ENDYMD);
		
		// 課金開始日が設定されていない場合
		if(tmpFistChrgStaYmd.equals(JACStrConst.KARA_MOJI))
		{
			riyoDateCount = 0;
			useStaYmd = JACStrConst.KARA_MOJI;
			useEndYmd = JACStrConst.KARA_MOJI;
		}
		else 
		{
			// 課金終了日が設定されていて
			// 課金開始＞課金終了（初月解約）の場合
			if(!tmpLastChrgEndYmd.equals(JACStrConst.KARA_MOJI) && tmpFistChrgStaYmd.compareTo(tmpLastChrgEndYmd) > 0)
			{
				riyoDateCntFlg = false;
			}
			
			// 前月　または　群月初日　で課金終了している場合
			else if(tmpLastChrgEndYmd.compareTo(this.wk_GunStr) < 0)
			{
				riyoDateCntFlg = false;
			}
			
			// 翌月以降課金開始となるサービスである場合
			else if(tmpFistChrgStaYmd.compareTo(this.wk_GunEnd) > 0)
			{
				riyoDateCntFlg = false;
				flg = false;
			}
			
			
			//////////////////////////////////
			// A.群月初日　から(当月)課金開始日
			//////////////////////////////////
			// 前月　または　群月初日　で課金開始している場合
			// 退避リスト[1件目]．課金開始日  < 群月初日
			if(tmpFistChrgStaYmd.compareTo(this.wk_GunStr) < 0)
			{
				// 前月以前で課金終了している場合
				if(tmpLastChrgEndYmd.compareTo(this.wk_GunStr) < 0)
				{
					// ◆利用開始日　←　課金開始日
					useStaYmd = tmpFistChrgStaYmd;
				}
				else
				{
					// ◆利用開始日　←　群月初日
					useStaYmd = this.wk_GunStr;
				}
				
				// 0日間
				notUseStr = 0;
			}
			// 群月初日より後に課金開始している場合	
			// 群月初日　≦　退避リスト[1件目]．課金開始日	
			else
			{
				// ◆利用開始日　←　課金開始日
				useStaYmd = tmpFistChrgStaYmd;

				// 退避リスト[1件目]．課金開始日　-　群月初日
				notUseStr = JPCUtilCommon.subtractDay(tmpFistChrgStaYmd, this.wk_GunStr);
			}

			//////////////////////////////////
			// B.課金終了日 から 群締め日
			//////////////////////////////////
			// 群締め日まで課金対象の場合
			// 　退避リスト[最終件]．課金終了日　＝　未設定　 または
			// 　退避リスト[最終件]．課金終了日　＞　群月末日
			if(tmpLastChrgEndYmd.isEmpty() 
				|| tmpLastChrgEndYmd.compareTo(this.wk_GunEnd) > 0)
			{
				// 退避リスト[最終件]．課金開始日　＞　群月末日
				if(tmpFistChrgStaYmd.compareTo(this.wk_GunEnd) > 0)
				{
					// ◆利用終了　←　課金終了日
					useEndYmd = tmpLastChrgEndYmd;
				}
				else
				{
					// ◆利用終了　←　群締め日
					useEndYmd = this.wk_GunEnd;
				}
				// 0日間
				nouUseEnd = 0;
			}
			// 翌郡月初日以前に課金終了した場合	
			// 　退避リスト[最終件]．課金終了日　≦　群月末日
			else
			{
				// ◆利用終了　←　課金終了日
				useEndYmd = tmpLastChrgEndYmd;

				// 群締め日　-　退避リスト[最終件]．課金終了日
				nouUseEnd = JPCUtilCommon.subtractDay(this.wk_GunEnd, useEndYmd);
			}
			
			// ◆利用期間
			if(riyoDateCntFlg)
			{
				// 　利用日数　←　歴日数 - サービスを利用していない期間（未利用期間（開始）＋（終了））
				riyoDateCount = this.wk_CalDay - (notUseStr + nouUseEnd);
			}
			else
			{
				riyoDateCount = 0;
			}
		}
	
		// ◆利用不可日数
		int riyoFuka = 0;
		
		//   利用不可期間の算出
		if(flg)
		{
			riyoFuka = this.getnotUseDays(tmpList);
		}

		// マップより（退避リストの最終件目取得）
		JBSbatServiceInterfaceMap tmpList1 = tmpList.get(lastInd);

		// 料金サービス条件検索用キー
		StringBuffer mapKeyBuf = new StringBuffer();
		mapKeyBuf.append(tmpList1.getString(JBSbatACIFI013.PCRS_CD)); 			// 料金コースコード
		mapKeyBuf.append(tmpList1.getString(JBSbatACIFI013.TRGT_PRC_SVC_CD)); 	// 料金サービスコード
		
		String prcSvcSkbtCd = null; // 料金サービス識別コード
		
		// 該当データありの場合
		if (db_SvcKnrMap.containsKey(mapKeyBuf.toString()))
		{
			prcSvcSkbtCd = db_SvcKnrMap.get(mapKeyBuf.toString());
		}
		// 該当データなし
		else 
		{
			prcSvcSkbtCd = JACStrConst.KARA_MOJI;	// 空文字
		}
		
		// 出力レコード情報設定
		JBSbatServiceInterfaceMap outRecMap = new JBSbatServiceInterfaceMap();

		// 出力情報設定
		// 整理番号が未設定である場合にはフル桁スペース埋めに変換する
		outRecMap.setString(JBSbatACIFM062.SEIRI_NO,					convertNull(tmpList1.getString(JBSbatACIFI013.SEIRI_NO), SEIRI_NO_LEN)); 		// 整理番号
		outRecMap.setString(JBSbatACIFM062.SVC_SKBT_CD,					prcSvcSkbtCd); 																	// 料金サービス識別コード
		outRecMap.setString(JBSbatACIFM062.PRC_GRP_CD,					convertNull(tmpList1.getString(JBSbatACIFI013.PRC_GRP_CD), PRC_GRP_CD_LEN));	// 料金グループコード
		outRecMap.setString(JBSbatACIFM062.PCRS_CD,						convertNull(tmpList1.getString(JBSbatACIFI013.PCRS_CD), PCRS_CD_LEN)); 		 	// 料金コースコード
		outRecMap.setString(JBSbatACIFM062.PRC_SVC_CD,					tmpList1.getString(JBSbatACIFI013.TRGT_PRC_SVC_CD)); 			// 料金サービスコード
		outRecMap.setString(JBSbatACIFM062.SVC_NO,						tmpList1.getString(JBSbatACIFI013.SVC_NO)); 					// サービス番号
		outRecMap.setString(JBSbatACIFM062.SVC_KEI_UCWK_NO,				tmpList1.getString(JBSbatACIFI013.SVC_KEI_UCWK_NO)); 			// サービス契約内訳番号
		outRecMap.setString(JBSbatACIFM062.OP_SVC_KEI_NO,				tmpList1.getString(JBSbatACIFI013.OP_SVC_KEI_NO)); 				// オプションサービス契約番号
		outRecMap.setString(JBSbatACIFM062.SEIKY_KEI_NO,				tmpList1.getString(JBSbatACIFI013.SEIKY_KEI_NO)); 				// 請求先番号
		outRecMap.setString(JBSbatACIFM062.SEIKY_YM,					this.wk_SkyuYM); 												// 請求年月
		outRecMap.setString(JBSbatACIFM062.WRIB_SVC_KEI_NO,				tmpList1.getString(JBSbatACIFI013.WRIB_SVC_KEI_NO)); 			// 割引サービス契約番号
		outRecMap.setString(JBSbatACIFM062.TELNO,						tmpList1.getString(JBSbatACIFI013.TELNO).trim()); 				// 電話番号
		outRecMap.setString(JBSbatACIFM062.JIGYOSHA_KEI_ID,				tmpList1.getString(JBSbatACIFI013.JIGYOSHA_KEI_ID).trim()); 	// 事業者用契約ID
		outRecMap.setString(JBSbatACIFM062.SVC_STAYMD,					tmpList1.getString(JBSbatACIFI013.SVC_STAYMD)); 				// サービス開始日
		outRecMap.setString(JBSbatACIFM062.SVC_DSL_YMD,					tmpList1.getString(JBSbatACIFI013.SVC_DSL_YMD)); 				// サービス解約日
		outRecMap.setString(JBSbatACIFM062.SVC_DLRE,					tmpList1.getString(JBSbatACIFI013.SVC_DLRE)); 					// サービス解約理由
		outRecMap.setString(JBSbatACIFM062.SVC_KAIHK_DAY,				tmpList1.getString(JBSbatACIFI013.SVC_KAIHK_DAY)); 				// サービス回復日
		outRecMap.setString(JBSbatACIFM062.SVC_CANCEL_DAY,				tmpList1.getString(JBSbatACIFI013.SVC_CANCEL_DAY)); 			// サービスキャンセル日
		outRecMap.setString(JBSbatACIFM062.SVC_PAUSE_DAY,				tmpList1.getString(JBSbatACIFI013.SVC_PAUSE_DAY)); 				// サービス休止日
		outRecMap.setString(JBSbatACIFM062.SVC_PAUSE_RLS_YMD,			tmpList1.getString(JBSbatACIFI013.SVC_PAUSE_RLS_YMD)); 			// サービス休止解除日
		outRecMap.setString(JBSbatACIFM062.USE_STAYMD,					useStaYmd); 													// 利用開始日
		outRecMap.setString(JBSbatACIFM062.USE_ENDYMD,					useEndYmd); 													// 利用終了日
		outRecMap.setString(JBSbatACIFM062.VA_SHUKKA_YMD,				tmpList1.getString(JBSbatACIFI013.VA_SHUKKA_YMD)); 				// ＶＡ出荷日
		outRecMap.setBigDecimal(JBSbatACIFM062.USE_DAY_CNT,				riyoDateCount); 												// 利用日数
		outRecMap.setBigDecimal(JBSbatACIFM062.USE_FAIL_DAY_CNT,		riyoFuka); 														// 利用不可日数
		outRecMap.setString(JBSbatACIFM062.CHRG_STAYMD,					tmpList1.getString(JBSbatACIFI013.CHRG_STAYMD)); 				// 課金開始日
		outRecMap.setString(JBSbatACIFM062.FIRST_CHRG_STAYMD,			tmpList1.getString(JBSbatACIFI013.FIRST_CHRG_STAYMD)); 			// 初回課金開始日
		outRecMap.setString(JBSbatACIFM062.CHRG_ENDYMD,					tmpList1.getString(JBSbatACIFI013.CHRG_ENDYMD)); 				// 課金終了日
		outRecMap.setBigDecimal(JBSbatACIFM062.SVC_KEIZOKU_MON_CNT,		tmpList1.getBigDecimal(JBSbatACIFI013.SVC_KEIZOKU_MON_CNT));	// サービス継続月数
		outRecMap.setBigDecimal(JBSbatACIFM062.SVC_KEIZOKU_DAY_CNT,		tmpList1.getBigDecimal(JBSbatACIFI013.SVC_KEIZOKU_DAY_CNT));	// サービス継続日数
		outRecMap.setBigDecimal(JBSbatACIFM062.CHRG_KEIZOKU_MON_CNT,	tmpList1.getBigDecimal(JBSbatACIFI013.CHRG_KEIZOKU_MON_CNT)); 	// 課金継続月数
		outRecMap.setBigDecimal(JBSbatACIFM062.CHRG_KEIZOKU_DAY_CNT,	tmpList1.getBigDecimal(JBSbatACIFI013.CHRG_KEIZOKU_DAY_CNT)); 	// 課金継続日数
		outRecMap.setBigDecimal(JBSbatACIFM062.KEI_CNT,					tmpList1.getBigDecimal(JBSbatACIFI013.KEI_CNT)); 				// 契約数
		outRecMap.setBigDecimal(JBSbatACIFM062.MON_CHU_MAX_KEI_CNT,		tmpList1.getBigDecimal(JBSbatACIFI013.MON_CHU_MAX_KEI_CNT)); 	// 月中最大契約数
		outRecMap.setString(JBSbatACIFM062.AIT_DIV,						JACStrConst.AITAI_NO_1); 										// 相対区分
		outRecMap.setString(JBSbatACIFM062.SIME_DAY,					tmpList1.getString(JBSbatACIFI013.SIME_DAY)); 					// 締め日

		finalOutJudge(outRecMap, outputInItem);
	}

	/**
	 * 項目の設定／未設定を判定し、未設定である場合にはフル桁スペースを返却します。
	 * @param strValue 対象項目
	 * @param iLength 未設定の場合に返却するスペースの桁数
	 * @return 引数の項目またはフル桁スペース
	 */
	private String convertNull(String strValue, int iLength)
	{
		if (JACStrConst.KARA_MOJI.equals(strValue))
		{
			// 項目が未設定であった場合、フル桁スペースを返却する
			return JACbatRknBusinessUtil.fillHalfSpace(strValue, iLength, true);
		}
		else
		{
			// 上記以外は単純転送
			return strValue;
		}
	}
	
	/**
	 * 対象判定処理
	 * イベント日が当月かを判定し、対象の場合退避リストへ設定する。
	 * @param inMap 
	 * @throws Exception
	 */
	public void checkRec(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		String chrgStaYmd = inMap.getString(JBSbatACIFI013.CHRG_STAYMD); 	// 課金開始日
		String chrgEndYmd = inMap.getString(JBSbatACIFI013.CHRG_ENDYMD); 	// 課金終了日

		// 過去分の履歴が退避されている場合
		if(!this.twk_flgIsEvntRslt && !this.twk_tmpList.isEmpty())
		{
			// 過去分は直近のみ保持できていればよいので、削除する
			this.twk_tmpList.clear();
		}
		
		// 課金開始日が設定されていない場合
		if(chrgStaYmd.equals(JACStrConst.KARA_MOJI))
		{
			// 退避リストへ追加
			this.twk_tmpList.add(inMap);
			
			// 処理対象
			return;
		}
		
		// 当月のイベントレコードか、過去の履歴レコードかの判定を行う.
		// ◆判定方法
		// 　以下の項目のうちいずれかが、当月内のイベントだった場合
		// 　群月初日 ≦ ※ ≦ 群終了日
																						// 課金開始日
																						// 課金終了日
		String svcPauseDay 		= inMap.getString(JBSbatACIFI013.SVC_PAUSE_DAY); 		// サービス休止日
		String svcPauseRlsDay 	= inMap.getString(JBSbatACIFI013.SVC_PAUSE_RLS_YMD); 	// サービス休止解除日
		String svcUseFailStaymd = inMap.getString(JBSbatACIFI013.SVC_USE_FAIL_STAYMD);	// サービス利用不可開始日
		String svcUseFailEndymd = inMap.getString(JBSbatACIFI013.SVC_USE_FAIL_ENDYMD); 	// サービス利用不可終了日
		if (isTargetDate(chrgStaYmd) 
				|| isTargetDate(chrgEndYmd)
				|| isTargetDate(svcPauseDay)
				|| isTargetDate(svcPauseRlsDay)
				|| isTargetDate(svcUseFailStaymd)
				|| isTargetDate(svcUseFailEndymd))
		{
			this.twk_flgIsEvntRslt = true;
		}

		// 退避リストへ追加
		this.twk_tmpList.add(inMap);

		// 処理対象
		return;
	}

	/**
	 * 当月のイベントがあるかどうかを判断する
	 * @param  inDate 対象日
	 * @return boolean true:イベントあり/false:イベントなし
	 * 
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private boolean isTargetDate(String inDate)
	{
		// イベントなし（未設定）
		if(JACStrConst.KARA_MOJI.equals(inDate))
		{
			return false;
		}
		
		// 当月のイベントあり（群月初日　から　群締め日の間の場合）
		else if(this.wk_GunStr.compareTo(inDate) <= 0 && inDate.compareTo(this.wk_GunEnd) <= 0)
		{
			return true;
		}
		
		// 当月以外のイベントあり
		else
		{
			return false;
		}
	}

	/**
	 * 開始、終了日の調整をする
	 * 以下の場合、開始、終了日の調整をする。
	 * １．開始日　＜　群開始日　の場合
	 *   　群開始日とする。
	 * ２．未設定　または　群締め日＜終了日
	 *   　群締め日とする。
	 *   
	 * @param  tmpList 退避リスト
	 * @return int 利用不可期間
	 * 
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private int getnotUseDays(ArrayList<JBSbatServiceInterfaceMap> tmpList) throws Exception
	{
		// 利用不可リスト
		ArrayList<String[]> svcUseFailList = new ArrayList<String[]>();

		String useFailStaYmd  	= null; 	// サービス利用不可開始日
		String useFailEndYmd  	= null; 	// サービス利用不可終了日  利用期間含まない
		String chrgEndYmd 		= null; 	// 課金終了日
		for(int i = 0; i < tmpList.size(); i++)
		{
			JBSbatServiceInterfaceMap tmpMap = tmpList.get(i);

			// サービス利用不可開始日を求める
			useFailStaYmd  = tmpMap.getString(JBSbatACIFI001.SVC_USE_FAIL_STAYMD);
			
			// サービス利用不可終了日を求める
			useFailEndYmd  = tmpMap.getString(JBSbatACIFI001.SVC_USE_FAIL_ENDYMD);
			
			// サービス利用不可終了日　≧　群月初日の場合
			if(useFailEndYmd.compareTo(this.wk_GunStr) >= 0)
			{
				
				// サービス利用不可開始日　＜　群月初日の場合
				if(useFailStaYmd.compareTo(this.wk_GunStr) < 0)
				{
					
					// 群月初日
					useFailStaYmd = this.wk_GunStr;
				}
				
				// 課金終了日を設定する
				chrgEndYmd = tmpMap.getString(JBSbatACIFI001.CHRG_ENDYMD); 
				
				// 課金終了日に設定あり、かつ　課金終了日　＜　サービス利用不可終了日の場合
				if(!JACbatRknBusinessUtil.isNull(chrgEndYmd) && chrgEndYmd.compareTo(useFailEndYmd) < 0)
				{
					useFailEndYmd = chrgEndYmd;
				}
				this.setList(svcUseFailList, useFailStaYmd, useFailEndYmd, false);
			}

		}

		// 利用不可期間の計算
		return this.keisan(svcUseFailList);
	}

	/**
	 * 利用不可期間の計算処理を行う
	 * @param  inList 利用不可リスト
	 * @return rtn 利用不可期間
	 * 
	 */
	private int keisan(ArrayList<String[]> inList)
	{
		// 利用不可期間
		int rtn = 0;

		// 利用不可期間のリストが存在する場合計算する
		if (!inList.isEmpty())
		{
			// リスト分繰り返し
			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);

			}
		}

		return rtn;
	}

	/**
	 * 利用不可期間リスト設定処理を行います。
	 * 
	 * @param inList リスト
	 * @param str 開始日
	 * @param end 終了日
	 * @param endFlg 利用不可期間に含むフラグ（true：含む、false：含まない（マイナス１日した日を設定する））
	 */
	private void setList(ArrayList<String[]> inList, String str, String end, boolean endFlg)
	{
		// 開始日が空のデータ　または　開始日が未来のデータ（締め日＜開始日）
		if(str.equals(JACStrConst.KARA_MOJI) || this.wk_GunEnd.compareTo(str) < 0)
		{
			
			// 処理対象外とし、リストに設定しない
			return;
		}
		
		// 終了日が利用不可期間に含まない場合 かつ
		// 群開始日から群開始日-1の場合　※群終了日の場合は処理対象外となるので、設定しない。
		if(!endFlg && !JACStrConst.KARA_MOJI.equals(end))
		{
			
			// 終了日-1
			end = JPCUtilCommon.addDay(end, -1);
		}
		
		// 終了日が当月以降　または　未設定の場合（群締め日　＜　終了日）
		if(this.wk_GunEnd.compareTo(end) < 0 || JACStrConst.KARA_MOJI.equals(end))
		{
			
			// 締め日とする
			end = this.wk_GunEnd;
		}
		
		String[] listData = null; 			// リスト内要素

		// 最後が同じ場合、同じ日付が存在するか確認する
		if(!inList.isEmpty())
		{
			listData = inList.get(inList.size() - 1);
		
			// リスト[最後]．開始日　＝　入力．開始日の場合
			if(listData[0].equals(str))
			{
				
				// 要素を更新し、処理終了
				listData[1] = end;
				return;
			}
		}
		
		String[] addData  = new String[2]; 	// 追加要素

		// 同じ開始日がない場合最後に追加する
		addData[0] = str;
		addData[1] = end;
		inList.add(addData);
	}
	/**▲▲▲▲▲▲メソッド追加 終了▲▲▲▲▲▲*/
	
	/**
	 * 更新用シーケンス番号をファイル出力します
	 * 
	 * @throws Exception
	 */
	private void outSeqNo() throws Exception
	{
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][outSeqNo]");
		
		// シーケンスを100進める
		this.seqChrgJsvkeiCksNo = getNextSeq(this.seqChrgJsvkeiCksNo, 100);
		
		// 処理前との差分を算出
//OM-2016-0001645 MOD START
//		int updSeikyNoCnt = this.seqChrgJsvkeiCksNo - this.seqChrgJsvkeiCksNoBef;
		long updSeikyNoCnt = this.seqChrgJsvkeiCksNo - this.seqChrgJsvkeiCksNoBef;
//OM-2016-0001645 MOD END
		
		// 請求シーケンス更新用ファイル出力
		ArrayList<Object> updSeikyNoList = new ArrayList<Object>();
		updSeikyNoList.add(updSeikyNoCnt);
		JCCBatCommon.printBusinessFileUtil(this.trgtKeyWkSeqFile, updSeikyNoList);
		
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][outSeqNo]");
	}

//OM-2016-0001645 MOD START
//	/**
//	 * シーケンスを引数分加算します。
//	 * 
//	 * @param seqNo 加算対象シーケンス番号
//	 * @param num 加算数
//	 * @return int 加算済シーケンス番号
//	 * @throws Exception
//	 */
//	private int getNextSeq(int seqNo, int num) throws Exception
//	{
//		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][getNextSeq]");
//		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][getNextSeq][" + seqNo + " ＋ " + num + " ＝ " + seqNo + num + "]");
//		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][getNextSeq]");
//		
//		//引数分加算する
//		return seqNo + num;
//	}
	
	/**
	 * シーケンスを引数分加算します。
	 * 
	 * @param seqNo 加算対象シーケンス番号
	 * @param num 加算数
	 * @return 加算済シーケンス番号
	 * @throws Exception
	 */
	private long getNextSeq(long seqNo, long num) throws Exception
	{
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][getNextSeq]");
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][getNextSeq][" + seqNo + " ＋ " + num + " ＝ " + seqNo + num + "]");
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][getNextSeq]");
		
		//引数分加算する
		return seqNo + num;
	}
//OM-2016-0001645 MOD END

	/**
	 * ファイル出力
	 * 
	 * @param  filePath  ファイルパス
	 * @param  fileDef   ファイル定義
	 * @return fileUtil  ファイルインスタンス
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private JBSbatBusinessFileUtil createFile(String filePath, String fileDef) throws Exception 
	{
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][createFile]");
		JBSbatOutputFileUtil trailerFile 	= new JBSbatOutputFileUtil(filePath);
		String tempFileDefName 				= JBSbatAplConst.getAplConstValue(PRM_OTD) + fileDef;
		JBSbatDefFileUtil trailerFileDef 	= new JBSbatDefFileUtil(tempFileDefName, trailerFile);
		
		// ファイルの生成
		JBSbatBusinessFileUtil fileUtil = JCCBatCommon.createBusinessFileUtil(filePath
																			, JACStrConst.ENCODE_MS932
																			, JACBatCommon.chgKaigyo(JACStrConst.LINE_CRLF)
																			, trailerFileDef.getDelimiter());
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][createFile]");
		return fileUtil;
	}
	
	/**
	 * 最終出力判定
	 * 
	 * @param  outMap 出力情報  
 	 * @param  outputInItem 出力オブジェクト
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void finalOutJudge(JBSbatServiceInterfaceMap outMap, JBSbatOutputItem outputInItem)throws Exception 
	{
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][finalOutJudge]");
		StringBuffer tmpMapKey = new StringBuffer();
		
		tmpMapKey.append(outMap.getString(JBSbatACIFM062.SEIKY_KEI_NO));
		tmpMapKey.append(outMap.getString(JBSbatACIFM062.SVC_KEI_UCWK_NO));
		
//		// 電話番号≠nullの かつ オプションサービス契約番号＝null場合（eo光電話）
//		if (!outMap.getString(JBSbatACIFM062.TELNO).equals(JACStrConst.KARA_MOJI)
//			&& outMap.getString(JBSbatACIFM062.OP_SVC_KEI_NO).equals(JACStrConst.KARA_MOJI))
//		{
//			
//			// サービス解約日
//			String svcDslYmd = outMap.getString(JBSbatACIFM062.SVC_DSL_YMD);
//			
//			// サービス解約日 ＞ 前月月末日 または 未解約のレコードを出力する
//			if(JACStrConst.KARA_MOJI.equals(svcDslYmd) || this.wk_PrvMonEndDay.compareTo(svcDslYmd) < 0 )
//			{
//				
//				// 出力情報設定
//				finalOutSet(outMap, outputInItem);
//			}
//			
//			assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][finalOutJudge]");
//			return;
//		}
//		
//		// 電話番号≠nullの かつ オプションサービス契約番号≠null場合（eo-netフォン、TELvision）
//		else if (!outMap.getString(JBSbatACIFM062.TELNO).equals(JACStrConst.KARA_MOJI) 
//				&& !outMap.getString(JBSbatACIFM062.OP_SVC_KEI_NO).equals(JACStrConst.KARA_MOJI))
//		{
// 
		// 電話番号≠nullの場合（eo-netフォン、TELvision、eo光電話）
		if (!outMap.getString(JBSbatACIFM062.TELNO).equals(JACStrConst.KARA_MOJI))
		{
// 
			tmpMapKey.append(outMap.getString(JBSbatACIFM062.OP_SVC_KEI_NO));
			tmpMapKey.append(outMap.getString(JBSbatACIFM062.TELNO));
		}
		
		// 事業者用契約ID≠nullの場合（eoモバイル）課金開始日が最新のレコード以外は出力しない
		else if (!outMap.getString(JBSbatACIFM062.JIGYOSHA_KEI_ID).equals(JACStrConst.KARA_MOJI))
		{
			tmpMapKey.append(outMap.getString(JBSbatACIFM062.OP_SVC_KEI_NO));
			tmpMapKey.append(outMap.getString(JBSbatACIFM062.JIGYOSHA_KEI_ID));
		}

// 2014.09.01 OM-2014-0002772 add start
		else {
			// その他の場合（FTTH）
			// 請求契約番号＋サービス契約番号 をキーとして判定する。
			tmpMapKey = new StringBuffer();
			tmpMapKey.append(outMap.getString(JBSbatACIFM062.SEIKY_KEI_NO));
			tmpMapKey.append(outMap.getString(JBSbatACIFM062.SVC_NO));
		}
// 2014.09.01 OM-2014-0002772 add end
		
		// その他の場合（FTTH）課金開始日が最新のレコード以外は出力しない
		// 課金開始日が退避．課金開始日より大きい（課金開始日が空の場合、最大とみなす）場合
		// 退避情報を塗り替える
		String mapKey = tmpMapKey.toString();
		JBSbatServiceInterfaceMap bkMap = finalOutMap.get(mapKey);
		
		if(bkMap == null)
		{
			finalOutMap.put(mapKey, outMap);
		}
		else
		{
			String chrgStaymd = outMap.getString(JBSbatACIFM062.CHRG_STAYMD);
			String bkChrgStaymd = bkMap.getString(JBSbatACIFM062.CHRG_STAYMD);
		
			if(!bkChrgStaymd.equals(JACStrConst.KARA_MOJI) && (chrgStaymd.equals(JACStrConst.KARA_MOJI) || bkChrgStaymd.compareTo(chrgStaymd) < 0))
			{
				finalOutMap.put(mapKey, outMap);
			}
		}
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][finalOutJudge]");
	}
	
	/**
	 * 最終出力
	 *  
	 * @param  outputInItem 出力オブジェクト
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void finalOut(JBSbatOutputItem outputInItem)throws Exception 
	{
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][finalOut]");
		
		Iterator<JBSbatServiceInterfaceMap> allColList = finalOutMap.values().iterator();

		// 退避件数分出力
		while(allColList.hasNext())
		{
			JBSbatServiceInterfaceMap outMap = allColList.next();
			
			// 出力情報設定
			finalOutSet(outMap, outputInItem);
		}
		assert 	JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][finalOut]");
	}
	
	/**
	 * 最終出力情報設定処理
	 *  
	 * @param  outMap 出力情報 
	 * @param  outputInItem 出力オブジェクト
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void finalOutSet(JBSbatServiceInterfaceMap outMap, JBSbatOutputItem outputInItem)throws Exception
	{
		this.seqChrgJsvkeiCksNo = getNextSeq(this.seqChrgJsvkeiCksNo, 1);
		outMap.setString(JBSbatACIFM062.CHRG_JSVKEI_CKS_NO, JPCUtilCommon.fillZero(String.valueOf(this.seqChrgJsvkeiCksNo),
															SEQ_LEN_SEQ_CHRG_JSVKEI_CKS_NO, false)); 		// 課金対象従量サービス契約蓄積番号

		outMap.setOutFlg(true);
		outputInItem.addOutMapList(outMap);
	}
}
