/*********************************************************************
*  All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JBSbatACOtelKoIfSndTgSksi
*	ソースファイル名	：JBSbatACOtelKoIfSndTgSksi.java
*	作成者				：富士通　
*	作成日				：2012年08月20日
*＜機能概要＞
*　法人分オプション電話通話明細集計、ＩＯ請求明細情報作成部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2012/08/20   富士通		新規作成
*	v3.00		2012/09/05   FJ)岡田	【ST1-2012-0000509】小数部切り捨て
*	v4.00		2013/03/26   FJ)小柴	【内部管理番号-0000613】ファイル出力オブジェクト生成時のエンコード設定ずれ防止対応
*	v4.01		2013/04/05   FJ)小柴	【IKK-2013-0000783】文字化け対策のため、エンコード形式の変更
*	v4.02		2013/05/31   FJ)黒木	【TG1-2013-0000552】ＩＯ請求明細情報トレーラレコード出力不正対応
*	v5.00		2013/07/11   FJ)狭間	【IT1-2013-0001363】（水平展開）lineToObjectの第三引数適正化
*********************************************************************/
package eo.business.service;

import java.math.BigDecimal;

import eo.business.common.JACbatRknBusinessUtil;
import eo.business.common.JBSbatBusinessService;
import eo.business.common.JCCBatCommon;
import eo.business.util.file.JBSbatACIFM090;
import eo.business.util.file.JBSbatACIFM091;
import eo.business.util.file.JBSbatACIFM092;
import eo.business.util.file.JBSbatACIFM156;
import eo.common.constant.JACStrConst;
import eo.common.util.JPCUtilCommon;
import eo.framework.file.JBSbatDefFileUtil;
import eo.framework.file.JBSbatInputFileUtil;
import eo.framework.file.JBSbatOutputFileUtil;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.item.JBSbatServiceInterfaceMap;
import eo.framework.util.JBSbatAplConst;

/**
* (クラスの機能概要) <p>
*<BR>
* @author 富士通
*/
public class JBSbatACOtelKoIfSndTgSksi extends JBSbatBusinessService
{
	/**▼▼▼▼▼▼ツールから生成した宣言です 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成した宣言です 終了▲▲▲▲▲▲*/

	/** 入力ファイルパラメータ */
	private static final String PARAM_IND = "IND";
	
	/** 出力ファイル定義 */
	private static final String PARAM_OTD = "OTD";
	
	/** レコード種別：ヘッダ */
	private static final String REC_SBT_HEADER = "0";

	/** レコード種別：データ */
	private static final String REC_SBT_DATA = "1";

	/** レコード種別：トレーラ */
	private static final String REC_SBT_TRAILER = "9";

	/** 前回分入力情報 */
	private JBSbatServiceInterfaceMap znkiInMap = null;
	
	/** 出力用レコード */
	private JBSbatServiceInterfaceMap outRecord = null;
	
	/** フリー項目格納用 */
	private String[] freeItemArray = null;
	
	/** システム年月日時分秒 */
	private String sysDateTime = null;
	
	/** 出力レコード件数 */
	private int outRecCnt = 0;
	
	/** 桁数＿金額 */
	private final int LENGTH_SIKY_DTL_CNT = 8;
	
	/**
	 * 初期処理
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した初期化のソースです 開始▼▼▼▼▼▼*/
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);
		/**▲▲▲▲▲▲ツールから生成した初期化のソースです 終了▲▲▲▲▲▲*/

		// フリー項目文字列を分解
		freeItemArray = commonItem.getFreeItem().split(JACStrConst.FREE_DIV);
		
		// システム年月日時分秒を取得
		sysDateTime = JCCBatCommon.getSysDateTime();
		
	/**▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 主処理
	 * @return JBSbatOutputItem　出力情報
	 * @throws Exception
	 */
	public JBSbatOutputItem execute() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの主処理を記述してください。▼▼▼▼▼▼*/
		JBSbatOutputItem outputItem = new JBSbatOutputItem();
		
		// IO請求明細情報送信(ヘッダ)ファイルの生成
		createHeaderFile();
		
		// 法人分オプション電話通話明細情報ファイルオブジェクト生成
		// ファイル読み込み
		JBSbatInputFileUtil fileObj = new JBSbatInputFileUtil(freeItemArray[2]);
		fileObj.setEncode(JACStrConst.ENCODE_SJIS);
		fileObj.createReader();
		
		// レコード数分繰り返す
		String sLine = null;
		while((sLine = fileObj.readLine()) != null)
		{
			// ヘッダレコード取得
			JBSbatServiceInterfaceMap inMap = this.getRecMap(fileObj, sLine, freeItemArray[3]);
			
			// 課金可否の判定
			if ( ! JACStrConst.KAKIN_KA.equals(inMap.getString(JBSbatACIFM156.KKN_KH_KBN)))
			{
				// 課金可不可区分≠“1”（課金可）のデータを対象外とする
				continue;
			}
			
			// 集計キーの作成
			String key1 = makeKeyStr(inMap);
			// 集計キーの作成（前回分）
			String key2 = makeKeyStr(znkiInMap);
			
			// 集計キーの判定
			if (key1.equals(key2))
			{
				// 金額の集計処理
				calcDataRecordAmnt(inMap);
			}
			else
			{
				// 出力レコードの存在判定
				if (outRecord != null)
				{
					// 出力レコードが存在する場合、出力ファイルに追加
					outRecord.setOutFlg(true);
					// 出力用レコードの小数点以下切り捨てを行う
					amtRoundDown();
					outputItem.addOutMapList(outRecord);
					outRecCnt++;
				}
				// 出力レコードの作成
				createDataRecord(inMap);
			}
			// 入力情報を前回分として保持
			znkiInMap = inMap;
		}
		// 出力レコードの存在判定
		if (outRecord != null)
		{
			// 出力レコードが存在する場合、出力ファイルに追加
			outRecord.setOutFlg(true);
			// 出力用レコードの小数点以下切り捨てを行う
			amtRoundDown();
			outputItem.addOutMapList(outRecord);
			outRecCnt++;
		}
		
		createTrailerFile(outputItem);
		
		// 出力情報を返却
		return outputItem;
	/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼*/
		/**▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲*/
	/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}

	/**▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成したメソッドです 終了▲▲▲▲▲▲*/
	
	/**
	 * IO請求明細情報送信(ヘッダ)ファイルの作成
	 * @throws Exception
	 */
	private void createHeaderFile() throws Exception
	{
		// IO請求明細情報送信(ヘッダ)ファイル名を取得
		JBSbatOutputFileUtil dataFile = new JBSbatOutputFileUtil(freeItemArray[0]);
		dataFile.setJobID(commonItem.getJobid());

		// IO請求明細情報送信(ヘッダ)ファイル定義情報を取得
		String dataFileDefName = JBSbatAplConst.getAplConstValue(PARAM_OTD) + freeItemArray[1];
		JBSbatDefFileUtil dataFileDef = new JBSbatDefFileUtil(dataFileDefName, dataFile);

		// IO請求明細情報送信(ヘッダ)ファイル出力
		dataFile.createWriter();
		dataFile.print(setHeaderFileMap(), dataFileDef);

		// ファイルクローズ
		dataFile.close();
	}
	
	/**
	 * IO請求明細情報送信(ヘッダ)ファイルの出力項目を設定する
	 * @return	JBSbatServiceInterfaceMap	出力電文
	 * @throws Exception
	 */
	private JBSbatServiceInterfaceMap setHeaderFileMap() throws Exception
	{
		JBSbatServiceInterfaceMap outMap = new JBSbatServiceInterfaceMap();

		// レコード種別
		outMap.set(JBSbatACIFM090.REC_SBT, REC_SBT_HEADER);

		// ファイル作成年月日時分秒
		outMap.set(JBSbatACIFM090.FILE_SKSI_DTM, sysDateTime);

		outMap.setOutFlg(true);

		return outMap;
	}
	
	/**
	 * データレコードの作成
	 * 
	 * @param inMap 入力情報
	 * @throws Exception
	 */
	private void createDataRecord(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		outRecord = new JBSbatServiceInterfaceMap();
		outRecord.setString(JBSbatACIFM091.REC_SBT, REC_SBT_DATA);
		outRecord.setString(JBSbatACIFM091.KEI_UK_NO, inMap.getString(JBSbatACIFM156.KEI_UKTK_NO));
		outRecord.setString(JBSbatACIFM091.SVC_KEI_NO, inMap.getString(JBSbatACIFM156.SVC_KEI_NO));
		outRecord.setString(JBSbatACIFM091.USE_YM, inMap.getString(JBSbatACIFM156.USE_YM));
		outRecord.setString(JBSbatACIFM091.PRC_CD, inMap.getString(JBSbatACIFM156.PRC_CD));
		outRecord.setString(JBSbatACIFM091.SIKY_DTL_AMNT, inMap.getString(JBSbatACIFM156.PCALL_PRC));
		outRecord.setString(JBSbatACIFM091.RENKEI_DTM, sysDateTime);
	}
	
	/**
	 * データレコードの金額を集計
	 * 
	 * @param inMap 入力情報
	 * @throws Exception 
	 */
	private void calcDataRecordAmnt(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		BigDecimal amnt1 = new BigDecimal(outRecord.getString(JBSbatACIFM091.SIKY_DTL_AMNT));
		BigDecimal amnt2 = new BigDecimal(inMap.getString(JBSbatACIFM156.PCALL_PRC));
		outRecord.setString(JBSbatACIFM091.SIKY_DTL_AMNT, amnt1.add(amnt2).toString());
	}
	
	/**
	 * 請求明細金額の小数点以下切り捨てを行います。
	 * 
	 * @throws Exception
	 */
	private void amtRoundDown() throws Exception
	{
		// 請求明細金額を参照
		BigDecimal dtlAmnt = new BigDecimal(outRecord.getString(JBSbatACIFM091.SIKY_DTL_AMNT));
		// 小数点以下の切り捨てを行う
		BigDecimal downAmnt = JACbatRknBusinessUtil.round(JACStrConst.ROUND_DOWN, dtlAmnt, 0);
		// 請求明細金額を再設定する
		outRecord.setString(JBSbatACIFM091.SIKY_DTL_AMNT, downAmnt);
	}
	
	/**
	 * トレーラーファイルの作成
	 * 
	 * @param outputItem 出力情報
	 * @throws Exception 
	 */
	private void createTrailerFile(JBSbatOutputItem outputItem) throws Exception
	{
		JBSbatServiceInterfaceMap outMap = new JBSbatServiceInterfaceMap();
		outMap.setString(JBSbatACIFM092.REC_SBT, REC_SBT_TRAILER);
		outMap.setString(JBSbatACIFM092.SIKY_DTL_CNT, JPCUtilCommon.fillZero(String.valueOf(outRecCnt), LENGTH_SIKY_DTL_CNT, false));
		outMap.setOutFlg(true);
		outputItem.addOutMapList_2(outMap);
	}
	
	/**
	 * 集計用キーの作成（契約受付番号、サービス契約番号、利用年月、料金コード）
	 * 
	 * @param map 入力情報
	 * @return 集計用キー
	 * @throws Exception 
	 */
	private String makeKeyStr(JBSbatServiceInterfaceMap map) throws Exception
	{
		if (map == null)
		{
			return "";
		}
		return makeStr(
						map.getString(JBSbatACIFM156.KEI_UKTK_NO), 
						map.getString(JBSbatACIFM156.SVC_KEI_NO), 
						map.getString(JBSbatACIFM156.USE_YM), 
						map.getString(JBSbatACIFM156.PRC_CD));
	}
	
	/**
	 * 文字を連結します
	 * @param string　文字
	 * @return strBuf　連結した文字列
	 */
	private String makeStr(String ...string)
	{
		StringBuffer strBuf = new StringBuffer();
		for(String str:string){
			if (str != null)
			{
				strBuf.append(str);
			}
		}
		return strBuf.toString();
	}

	/**
	 * ファイルからレコードを取得
	 * 
	 * @param inFileObj 入力ファイルオブジェクト
	 * @param sLine 行文字列
	 * @param fileDef ファイル定義名
	 * @return JBSbatServiceInterfaceMap レコードマップ
	 * @throws Exception スローされる例外
	 */
	private JBSbatServiceInterfaceMap getRecMap(JBSbatInputFileUtil inFileObj, String sLine, String fileDef) throws Exception
	{
		// エンコード形式を退避・復元する（出力定義ファイルオブジェクト生成時に上書きが発生しているため）
		String enc = inFileObj.getEncode();
		// encodeの形式がSHIFT-JISの場合、MS932に変換
		if (JACStrConst.ENCODE_SJIS.toUpperCase().equals(enc.toUpperCase()))
		{
			enc = JACStrConst.ENCODE_MS932;
		}
		
		JBSbatDefFileUtil defUtil = new JBSbatDefFileUtil(JBSbatAplConst.getAplConstValue(PARAM_IND) + fileDef, inFileObj);
		inFileObj.setEncode(enc);
		
		return defUtil.lineToObject(sLine, inFileObj, 0);
	}
}
