/*********************************************************************
*  All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JBSbatACZeroSeikyDelete
*	ソースファイル名	：JBSbatACZeroSeikyDelete.java
*	作成者				：富士通　
*	作成日				：2013年04月23日
*＜機能概要＞
*　０円請求削除部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2013/04/23   富士通		新規作成
*	v5.00.00	2013/06/17   FJ) 小柴	【TG1-2013-0000637】前受金充当額のデータが常に0円明細リストに出力されている問題を修正
*															前受金充当額のデータが両方の出力ファイルに出力されている問題を修正
*	v10.00.00	2014/09/01   FJ) 沖田	【OM-2014-0002693】マイナス請求を除外しないよう修正
*********************************************************************/
package eo.business.service;

import java.math.BigDecimal;
import java.util.ArrayList;

import eo.business.common.JACbatDebugLogUtil;
import eo.business.common.JACbatParamUtil;
import eo.business.common.JBSbatBusinessService;
import eo.business.util.file.JBSbatCHIFI005;
import eo.common.constant.JACStrConst;
import eo.common.util.JPCUtilCommon;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.item.JBSbatServiceInterfaceMap;

/**
* (クラスの機能概要) <p>
*<BR>
* @author 富士通
*/
public class JBSbatACZeroSeikyDelete extends JBSbatBusinessService
{
	/**▼▼▼▼▼▼ツールから生成した宣言です 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成した宣言です 終了▲▲▲▲▲▲*/
	
	/** 請求額合計料金項目コード */
	private String skgkPrcKmkCd = null;
	
	/** 前受金充当額料金項目コード */
	private String meukPrcKmkCd = null;
	
	/** 退避．LIST（請求内訳情報） */
	private ArrayList<JBSbatServiceInterfaceMap> outDataUtwk = new ArrayList<JBSbatServiceInterfaceMap>();
	
	/** 退避．LIST（請求削除明細情報） */
	private ArrayList<Integer> outDataDel = new ArrayList<Integer>();
	
	/** 請求額合計０円判定フラグ */
	private boolean skgkZeroJudgeFlg = false;
	
	/** 課金明細有無判定フラグ */
	private boolean chgMeisUmuFlg = false;
	
	/** 料金項目コード下2桁 */
	private static final String PRC01 = "01";
	
	/** 行番号カウント */
	private int rowNum = 0;
	
	/**
	 * 初期処理
	 * @param 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 + "]");
		
		// 業務パラメータの取得
		// パラメータ取得クラス生成
		JACbatParamUtil paramUtil = new JACbatParamUtil(commonItem);
		
		// 業務パラメータ情報を取得する
		this.skgkPrcKmkCd = paramUtil.getGyoumuParameter(JACStrConst.WKPARA_AC_WKS_SKGK_PRC);		// 請求額合計料金項目コード
		this.meukPrcKmkCd = paramUtil.getGyoumuParameter(JACStrConst.WKPARA_AC_WKS_MEUK_PRC);		// 前受金充当額料金項目コード
		
		// パラメータ取得クラスクローズ
		paramUtil.close();
		
		// 請求額合計０円判定フラグをクリアする
		skgkZeroJudgeFlg = false;
		
		// 課金明細有無判定フラグをクリアする
		chgMeisUmuFlg = false;
		
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][initial][請求額合計料金項目コード:" + skgkPrcKmkCd + "]");
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][initial][前受金充当額料金項目コード:" + meukPrcKmkCd + "]");
	/**▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 主処理
	 * @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(!outputInItem.isOutMapList())
		{
			// ダミーを設定
			outputInItem.addOutMapList(new JBSbatServiceInterfaceMap());
		}
		
		// レコード終了時
		if(inMap == null)
		{
			outPut(outputInItem);
			return outputInItem;
		}
		
		String inKey = null; 							// ブレイクキー（入力）
		String outKey = null; 							// ブレイクキー（出力）
		
		// ブレイクキー（入力）を設定する
		inKey = getShukKey(inMap);

		// ブレイクキー（出力）を設定する
		outKey = setOutKey(outputInItem);

		// キーブレイク時（請求契約単位（入力）≠ 請求契約単位（出力））
		if (!inKey.equals(outKey))
		{
			// ブレイク時の出力
			outPut(outputInItem);
			
			// キーリストをクリアする
			outputInItem.clearKeyList();
			
			 // ブレイクキー（入力）を追加する
			outputInItem.addKeyList(inKey);
		}
		
		// 料金項目コードを設定する
		String prcKmkCd = inMap.getString(JBSbatCHIFI005.PRC_KMK_CD);
		
		// 前受金充当額の料金項目コードの場合
		if (meukPrcKmkCd.equals(prcKmkCd))
		{
			assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "前受金充当額判定処理");
			
			// 金額をチェックし、0円の場合は削除対象とする
			BigDecimal amnt = inMap.getBigDecimal(JBSbatCHIFI005.AMNT);
			
			if (amnt.intValue() == 0)
			{
				// 削除リストに行番号を追加する
				outDataDel.add(new Integer(rowNum));
			}
		}
		
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "0円削除判定処理");
		
		// 請求内訳情報（入力）を出力リストに追加する
		inMap.setOutFlg(true);
		outDataUtwk.add(inMap);
		
		// 請求額合計０円判定
		seikyGkZeroJudge(inMap);
		
		// 課金明細有無判定
		kakinMeisaiUmuJudge(inMap);
		
		// 行番号カウントを増やす
		rowNum++;
		
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][execute]");
		
		return outputInItem;

		/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼*/
		/**▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲*/
	/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}
	
	/**▼▼▼▼▼▼メソッド追加 開始▼▼▼▼▼▼*/
	
	/**
	 * 集計単位を取得します。
	 * 
	 * @param outputInItem 入力情報
	 * @return String 集計単位
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private String setOutKey(JBSbatOutputItem outputInItem) throws Exception
	{
		String rtnKey = null;
		
		// 集計単位が既に設定されている場合
		if (outputInItem.isKeyList())
		{
			rtnKey = (String)outputInItem.getKeyList().get(0);
		}
		// 設定されていない場合（初回処理）
		else
		{
			// null値を設定する
			rtnKey = null;
		}
		
		return rtnKey;
	}
	
	/**
	 * ブレイクキーを取得します
	 * 
	 * @param inMap 入力電文
	 * @return String ブレイクキー
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private String getShukKey(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		String rtnKey = null;
		
		// 入力レコードが存在する場合
		if (inMap != null)
		{
			StringBuffer keyBuf = new StringBuffer();
			
			keyBuf.append(inMap.getString(JBSbatCHIFI005.SEIKY_KEI_NO)); 			// 請求契約番号
			
			// ブレイクキー生成
			rtnKey = keyBuf.toString();
		}
		// 入力ファイルの最終ブレイクレコードの場合
		else
		{
			// 空を設定する
			rtnKey = "";
		}
		return rtnKey;
	}
	
	/**
	 * 出力処理
	 * 
	 * @param outputInItem 入力情報
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private void outPut(JBSbatOutputItem outputInItem) throws Exception
	{
		
		// 出力パターン判定にそって出力
		if (skgkZeroJudgeFlg == false && chgMeisUmuFlg == false)//請求額合計０円かつ課金明細無の場合
		{
			outPtn2(outputInItem);
		}
		else
		{
			outPtn1(outputInItem);
		}
		
		// 請求内訳情報退避リストをクリアする
		outDataUtwk.clear();
		
		// 請求削除明細情報退避リストをクリアする
		outDataDel.clear();
		
		// 請求額合計０円判定フラグをクリアする
		skgkZeroJudgeFlg = false;
		
		// 課金明細有無判定フラグをクリアする
		chgMeisUmuFlg = false;
		
		// 件数カウントをクリアする
		rowNum = 0;
	}
	
	/**
	 * 出力パターン１
	 * 
	 * @param outputInItem 入力情報
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private void outPtn1(JBSbatOutputItem outputInItem) throws Exception
	{
		
		// 請求内訳情報、請求内訳削除情報の出力
		for (int i = 0; i < outDataUtwk.size(); i++)
		{
			// 請求削除明細情報退避リストに含まれる場合
			if (outDataDel.contains(new Integer(i)))
			{
				// 削除リストへ出力を行う
				outputInItem.addOutMapList_2(outDataUtwk.get(i));
			}
			// 含まれない場合
			else
			{
				// 請求内訳明細（0円明細削除）へ出力を行う
				outputInItem.addOutMapList(outDataUtwk.get(i));
			}
		}
		
		
	}
	
	/**
	 * 出力パターン２
	 * 
	 * @param outputInItem 入力情報
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private void outPtn2(JBSbatOutputItem outputInItem) throws Exception
	{
		
		// 出力レコード（請求削除明細情報）が存在する場合
		for (int i = 0; i < outDataUtwk.size(); i++)
		{
			outputInItem.addOutMapList_2(outDataUtwk.get(i));
		}
		
	}
	
	/**
	 * 請求額合計０円判定
	 * 
	 * @param inMap 入力情報
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private void seikyGkZeroJudge(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		
		// 料金項目コードを設定する
		String prcKmkCd = inMap.getString(JBSbatCHIFI005.PRC_KMK_CD);
		
		// 料金を設定
		BigDecimal amnt = inMap.getBigDecimal(JBSbatCHIFI005.AMNT);
		
		// OM-2014-0002693 MOD START
//		// 請求額合計の料金項目コードかつ請求額合計が０円より多いか判定
//		if (skgkPrcKmkCd.equals(prcKmkCd) && amnt.intValue() > 0)
		// 請求額合計の料金項目コードかつ請求額合計が０円以外か判定
		if (skgkPrcKmkCd.equals(prcKmkCd) && amnt.intValue() != 0)
		// OM-2014-0002693 MOD END
		{
			skgkZeroJudgeFlg = true;
		}
		
	}
	
	/**
	 * 課金明細有無判定
	 * 
	 * @param inMap 入力情報
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private void kakinMeisaiUmuJudge(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		// 料金を設定
		BigDecimal amnt = inMap.getBigDecimal(JBSbatCHIFI005.AMNT);
		
		// 料金サービスコードの空白除去
		String prcSvcCd = JPCUtilCommon.Rtrim(inMap.getString(JBSbatCHIFI005.PRC_SVC_CD));	//料金サービスコード
		
		// 料金項目コード下２桁設定
		String prckmkCd = inMap.getString(JBSbatCHIFI005.PRC_KMK_CD);	 					//料金項目コード
		String prckmkCdLow2 = JACStrConst.KARA_MOJI;
		
		if(prckmkCd != null && !JACStrConst.KARA_MOJI.equals(prckmkCd) && prckmkCd.length() > 1)
		{
			prckmkCdLow2 = prckmkCd.substring(prckmkCd.length() - 2, prckmkCd.length());
		}

		// OM-2014-0002693 MOD START
//		// 料金サービスコードが空以外かつ料金項目コード下２桁が０１：料金かつ料金が０円より多い
//		if (prcSvcCd != null && !JACStrConst.KARA_MOJI.equals(prcSvcCd) && PRC01.equals(prckmkCdLow2) && amnt.intValue() > 0)
		// 料金サービスコードが空以外かつ料金項目コード下２桁が０１：料金かつ料金が０円以外
		if (prcSvcCd != null && !JACStrConst.KARA_MOJI.equals(prcSvcCd) && PRC01.equals(prckmkCdLow2) && amnt.intValue() != 0)
		// OM-2014-0002693 MOD END
		{
			chgMeisUmuFlg = true;
		}
		
	}
	
	/**▲▲▲▲▲▲メソッド追加 終了▲▲▲▲▲▲*/

	/**▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成したメソッドです 終了▲▲▲▲▲▲*/
}
