/*********************************************************************
*  All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JBSbatKKIdTrkShoPriJhFileSksi
*	ソースファイル名	：JBSbatKKIdTrkShoPriJhFileSksi.java
*	作成者				：富士通　
*	作成日				：2016年03月16日
*＜機能概要＞
*　ID登録証印刷情報ファイル作成部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v25.00.00	2016/03/16   FJ)松本	新規作成【ANK-2729-00-00_ＩＤ登録証のトムソン非同梱対応】
*	v61.00.00	2022/12/08   FJ)宇野	ANK-4315-00-00_【eo定期】 eoホームゲートウェイ導入対応
*	v73.00.00	2024/11/08   FJ)辻中	ANK-4427-00-00 NTT卸対応
*********************************************************************/
package eo.business.service;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import eo.business.common.JBSbatBusinessService;
import eo.business.common.JKKBatConst;
import eo.business.util.table.JBSbatKK_M_PCRS;
import eo.business.util.table.JBSbatKU_T_KOJIAK;
import eo.business.util.table.JBSbatKU_T_SVKEI_KOJIAK;
import eo.common.constant.JPCBatchMessageConstant;
import eo.common.util.JPCDateUtil;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.item.JBSbatCommonDBInterface;
import eo.framework.application.JBSbatBusinessError;
import eo.framework.application.JBSbatBusinessException;
import eo.framework.db.JBSbatSQLAccess;
import eo.framework.file.JBSbatInputFileUtil;
import eo.framework.file.JBSbatOutputFileUtil;

/**
* (クラスの機能概要) <p>
*<BR>
* @author 富士通
*/
public class JBSbatKKIdTrkShoPriJhFileSksi extends JBSbatBusinessService
{
	/**▼▼▼▼▼▼ツールから生成した宣言です 開始▼▼▼▼▼▼*/
	/** テーブル(サービス契約＿工事案件)*/
	private static final String D_TBL_NAME_KU_T_SVKEI_KOJIAK = "KU_T_SVKEI_KOJIAK";
	
	// ANK-4427-00-00 ADD START
	/** テーブル(料金コース)*/
	private static final String D_TBL_NAME_KK_M_PCRS = "KK_M_PCRS";
	// ANK-4427-00-00 ADD END
	
	/** SQL定義キー(KK_SELECT_018)*/
	private static final String KU_T_SVKEI_KOJIAK_KK_SELECT_018 = "KK_SELECT_018";
	
	// ANK-4427-00-00 ADD START
	/** SQL定義キー(KK_SELECT_013)*/
	private static final String KK_M_PCRS_KK_SELECT_013 = "KK_SELECT_013";
	// ANK-4427-00-00 ADD END

	/** テーブルアクセスクラス(サービス契約＿工事案件)*/
	private JBSbatSQLAccess db_KU_T_SVKEI_KOJIAK = null;
	
	// ANK-4427-00-00 ADD START
	/** テーブルアクセスクラス(料金コース)*/
	private JBSbatSQLAccess db_KK_M_PCRS = null;
	// ANK-4427-00-00 ADD END
	/**▲▲▲▲▲▲ツールから生成した宣言です 終了▲▲▲▲▲▲*/

	/** 入力ファイルパス格納（ID登録証データ）*/
	private String inputFilePath;
	
	/** 出力ファイルパス格納（KKIFE325_ID登録証印刷情報ファイル）*/
	private String outputFilePath;
	
	/** 入力ファイル1行分配列の添え字（レコード種別）*/
	private static final int INDEX_RCD_SBT = 0;
	
	/** 入力ファイル1行分配列の添え字（サービス契約番号）*/
	private static final int INDEX_SVC_KEI_NO = 10;
	
	// ANK-4427-00-00 ADD START
	/** 入力ファイル1行分配列の添え字（料金コースコード）*/
	private static final int INDEX_PCRS_CD = 4;
	// ANK-4427-00-00 ADD END
	
	/** レコード種別 基本 */
	private static final String RCD_SBT_BASE = "91";
	/** レコード種別 オプション */
	private static final String RCD_SBT_OPTION = "92";
	/** レコード種別 トレーラ */
	private static final String RCD_SBT_TRAILER = "93";
	/** 改行コード */
	private static final String CRLF  = "CR+LF";
	/** 文字コード */
	private static final String MS932  = "MS932";
	/** 工事案件種別（新設） */
	private static final String KOJIAK_SBT_SIN = "001";
	/** 工事案件種別（住変新設） */
	private static final String KOJIAK_SBT_JYUHENSIN = "003";
	/** 工事案件種別（プラン変更(収容替)） */
	private static final String KOJIAK_SBT_SYUYO = "009";
	/** 工事案件種別（eoテレビ変更） */
	private static final String KOJIAK_SBT_EO_TV_CHG = "013";
	// ANK-4315-00-00 ADD STR
	/** 工事案件種別（ONU交換工事） */
	private static final String KOJIAK_SBT_ONU_CHG_KOJI = "015";
	// ANK-4315-00-00 ADD END
	/** 基本工事フラグ（有） */
	private static final String KIHON_KOJI_FLG_ARI = "1";
	/** 入力ファイルオブジェクト */
	private JBSbatInputFileUtil inPutFile = null;
	/** 外部インターフェースファイルオブジェクト */
	private JBSbatOutputFileUtil outPutFile = null;
	/** 起動条件識別コード */
	private String mRunType = null;
	/** 起動条件識別コード値 夜間 */
	private static final String RUN_TYPE_NIGHT = "1";
	// ANK-4427-00-00 ADD START
	/** NTT卸区分設定料金コースコードリスト */
	private static List<String> nttOrsPcrsCdList = null;
	// ANK-4427-00-00 ADD END

	/**
	 * 初期処理
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した初期化のソースです 開始▼▼▼▼▼▼*/
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);

		// DBアクセスクラスを生成します
		db_KU_T_SVKEI_KOJIAK = new JBSbatSQLAccess(commonItem, D_TBL_NAME_KU_T_SVKEI_KOJIAK);
		// ANK-4427-00-00 ADD START
		db_KK_M_PCRS = new JBSbatSQLAccess(commonItem, D_TBL_NAME_KK_M_PCRS);
		// ANK-4427-00-00 ADD END
		/**▲▲▲▲▲▲ツールから生成した初期化のソースです 終了▲▲▲▲▲▲*/
		
		// フリー項目取得
		String[] mfreeItem = super.freeItem.split(";");
		// 入力ファイルパス格納（ID登録証データ）
		this.inputFilePath = mfreeItem[0];
		// 出力ファイルパス格納（ID登録証印刷情報ファイル）
		this.outputFilePath = mfreeItem[1];
		
		// KKIFE325オブジェクト生成
		this.outPutFile = new JBSbatOutputFileUtil(this.outputFilePath);
		this.outPutFile.setEncode(JKKBatConst.SJIS);
		this.outPutFile.setLine(CRLF);
		this.outPutFile.createWriter();
		
		// 起動条件識別コード格納
		this.mRunType = mfreeItem[2];
		
		// ANK-4427-00-00 ADD START
		//NTT卸の料金コースコードを取得する
		setNttOrsPcrsCdList();
		// ANK-4427-00-00 ADD END
	/**▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 主処理
	 * @param inMap　入力電文
	 * @return JBSbatOutputItem　出力情報
	 * @throws Exception
	 */
	public JBSbatOutputItem execute() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの主処理を記述してください。▼▼▼▼▼▼*/
		File file = new File(this.inputFilePath);
		// 入力ファイルが存在する場合
		if(file.exists())
		{
			// 入力ファイルをオープン
			inPutFile = new JBSbatInputFileUtil(this.inputFilePath);
			inPutFile.setEncode(JKKBatConst.SJIS);
			inPutFile.setLine(CRLF);
			// Readerオブジェクトを生成する。
			inPutFile.createReader();
			
			// 入力ファイルのレコード件数
			int inFileRecordCnt = 0;
	
			// ANK-4427-00-00 ADD START
			boolean optionInfoOutputFlg = true;
			// ANK-4427-00-00 ADD END
			
			while (inPutFile.ready()) 
			{
				// 行数をカウントアップ
				inFileRecordCnt++;
				// ファイルから１レコード取得
				String line = inPutFile.readLine();
				
				String splitLine[] = line.split("\",\"");
				splitLine[0] = splitLine[0].substring(1);
				splitLine[splitLine.length-1] = splitLine[splitLine.length-1].substring(0, splitLine[splitLine.length-1].length()-1);
				
				// レコード種別（[0]番目の項目値）を取得
				String recSbt = splitLine[INDEX_RCD_SBT];
				// レコード種別が「91：基本」
				if(RCD_SBT_BASE.equals(recSbt))
				{
					// ANK-4427-00-00 ADD START
					String pcrsCd = splitLine[INDEX_PCRS_CD];
					//NTT卸の料金コースかチェックする
					if (nttOrsPcrsCdList.contains(pcrsCd)) {
						//NTT卸の料金コースの場合は出力対象外とする。カウントもしない
						inFileRecordCnt--;
						optionInfoOutputFlg = false;
						continue;
					} else {
						optionInfoOutputFlg = true;
					}
					// ANK-4427-00-00 ADD END
					
					// サービス契約番号（[10]番目の項目値）を取得
					String svcKeiNo = splitLine[INDEX_SVC_KEI_NO];
					
					// 対象の工事案件番号を取得
					String trgtKojiakNo = this.getTrgtKojiakNo(svcKeiNo);
					
					// 配列の要素を追加するために一旦リストに変換
					List<String> list = Arrays.asList(splitLine);
					ArrayList<String> lineArray =  new ArrayList<String>(list);
					// 要素の2番目に追加
					lineArray.add(1, trgtKojiakNo);
					
					// リストの要素を1行分のカンマ区切り文字列に結合（各要素にダブルクォートも付与）
					String lineString = getRecordString(lineArray);
					this.outPutFile.write(lineString);
				}
				else if(RCD_SBT_OPTION.equals(recSbt))
				{
					// ANK-4427-00-00 ADD START
					if (!optionInfoOutputFlg) {
						//Falseは基本情報がNTT卸であるため、そのオプション情報も出力しない。
						inFileRecordCnt--;
						continue;
					}
					// ANK-4427-00-00 ADD END
					
					this.outPutFile.write(line);
				}
				else if(RCD_SBT_TRAILER.equals(recSbt))
				{
					// 何もしない
				}
			}
			// 最後にトレーラ部の出力
			// 入力ファイルが０件の場合、トレーラ部1行のみ出力するため、トレーラ部自身の件数としてプラス1しておく
			if(inFileRecordCnt == 0)
			{
				inFileRecordCnt++;
			}
			String trailLine[] = new String[3];
			trailLine[0] = RCD_SBT_TRAILER;
			trailLine[1] = String.valueOf(inFileRecordCnt);
			// 夜間起動の場合はODATEを利用しているため、運用日はマイナス1日を設定
			if(RUN_TYPE_NIGHT.equals(this.mRunType))
			{
				trailLine[2] = JPCDateUtil.addDay(super.opeDate, -1);
			}
			else
			{
				trailLine[2] = super.opeDate;
			}
			List<String> list = Arrays.asList(trailLine);
			ArrayList<String> trailArray =  new ArrayList<String>(list);
			// リストの要素を1行分のカンマ区切り文字列に結合（各要素にダブルクォートも付与）
			String trailString = getRecordString(trailArray);
			this.outPutFile.write(trailString);
			
		}
		else
		{
			//入力ファイルが存在しないため、マイナーアラームを通知する。
			throw new JBSbatBusinessError(JPCBatchMessageConstant.EKKB1100CW);
		}

		return null;
	/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼*/
		// DBアクセスクラスをクローズします
		db_KU_T_SVKEI_KOJIAK.close();
		// ANK-4427-00-00 ADD START
		db_KK_M_PCRS.close();
		// ANK-4427-00-00 ADD END
		// ファイルをクローズします
		if(null != inPutFile)
		{
			this.inPutFile.close();
		}
		if(null != outPutFile)
		{
			this.outPutFile.close();
		}
		/**▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲*/
	/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}

	/**▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼*/
	/**
	 * SQLKEY(KK_SELECT_018)でDBアクセスを行います。<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.引数でバイント変数を設定します。<br>
	 *
	 * 2.DBアクセスを実行します。<br>
	 * 
	 * 3.メソッドの呼び出し方です。<br>
	 *		引数:
	 *		param:順にバイント変数の値をparam配列に入れます。バイント変数は以下に説明します。
	 *		 	サービス契約番号
	 * </pre>
	 * <p>
	 * @param param バイント変数の値配列。
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void executeKU_T_SVKEI_KOJIAK_KK_SELECT_018(String svcKeiNo) throws Exception
	{
		// バイント変数のリストを生成します
		JBSbatCommonDBInterface paramList = new JBSbatCommonDBInterface();
		paramList.setValue(svcKeiNo);

		// DBアクセスを実行します
		db_KU_T_SVKEI_KOJIAK.selectBySqlDefine(paramList, KU_T_SVKEI_KOJIAK_KK_SELECT_018);
	}
	// ANK-4427-00-00 ADD START
	/**
	 * SQLKEY(KK_SELECT_013)でDBアクセスを行います。<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.引数でバイント変数を設定します。<br>
	 *
	 * 2.DBアクセスを実行します。<br>
	 * 
	 * 3.メソッドの呼び出し方です。<br>
	 *		引数:
	 *		param:順にバイント変数の値をparam配列に入れます。バイント変数は以下に説明します。
	 *		 	運用日付
	 * </pre>
	 * <p>
	 * @param param バイント変数の値配列。
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void executeKK_M_PCRS_KK_SELECT_013(String batOpeDate) throws Exception
	{
		// バイント変数のリストを生成します
		JBSbatCommonDBInterface paramList = new JBSbatCommonDBInterface();
		paramList.setValue(batOpeDate);

		// DBアクセスを実行します
		db_KK_M_PCRS.selectBySqlDefine(paramList, KK_M_PCRS_KK_SELECT_013);
	}
	// ANK-4427-00-00 ADD END
	/**▲▲▲▲▲▲ツールから生成したメソッドです 終了▲▲▲▲▲▲*/
	
	
	/**
	 * パラメータで指定されたサービス契約番号に紐付く<br>
	 * 工事中もしくは基本工事の工事案件番号を取得します。<br>
	 * <p>
	 * @param svcKeiNo サービス契約番号
	 * @return tgtKojiak　対象の工事案件番号
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private String getTrgtKojiakNo(String svcKeiNo) throws Exception
	{
		// 戻り値（デフォルト値：空文字）
		String tgtKojiak = JKKBatConst.SPACE;
		
		// 現在工事中である新設もしくは住変新設もしくは収容換えの工事案件の工事案件番号
		String kojicyuKojiakNo = null;
		
		// 基本工事案件の工事案件番号
		String kihonkojiKojiakNo = null;
		
		// サービス契約番号に紐付く工事案件を取得
		executeKU_T_SVKEI_KOJIAK_KK_SELECT_018(svcKeiNo);
		
		// サービス契約番号に紐付く工事案件レコードを取得
		JBSbatCommonDBInterface kojiInfoRec = db_KU_T_SVKEI_KOJIAK.selectNext();
		while(null != kojiInfoRec)
		{
			// 工事案件ステータス
			String kojiakStat = kojiInfoRec.getString(JBSbatKU_T_KOJIAK.KOJIAK_STAT);
			// マンション工事案件状態ステータス
			String mansKojiakStat = kojiInfoRec.getString(JBSbatKU_T_KOJIAK.MANS_KOJIAK_STAT_CD);
			// 工事案件種別コード
			String kojiakSbt = kojiInfoRec.getString(JBSbatKU_T_KOJIAK.KOJIAK_SBT_CD);
			// 基本工事フラグ
			String kihonKojiFlg = kojiInfoRec.getString(JBSbatKU_T_KOJIAK.RCNT_KIHON_KOJI_FLG);
			// サービス契約_工事案件適用開始年月日
			String kojiTekiStaYmd = kojiInfoRec.getString(JBSbatKU_T_SVKEI_KOJIAK.SVKEI_KOJIAK_TSTAYMD);
			// サービス契約_工事案件適用終了年月日
			String kojiTekiEndYmd = kojiInfoRec.getString(JBSbatKU_T_SVKEI_KOJIAK.SVKEI_KOJIAK_TENDYMD);
			// ANK-4315-00-00 MOD STR
//			// （新設：001） or （住変新設：003） or （プラン変更(収容替)：009） or  (eoテレビ変更：013)
//			if(KOJIAK_SBT_SIN.equals(kojiakSbt)||KOJIAK_SBT_JYUHENSIN.equals(kojiakSbt)
//					||KOJIAK_SBT_SYUYO.equals(kojiakSbt) || KOJIAK_SBT_EO_TV_CHG.equals(kojiakSbt))
			// （新設：001） or （住変新設：003） or （プラン変更(収容替)：009） or  (eoテレビ変更：013) or  (ONU交換工事：015)
			if(KOJIAK_SBT_SIN.equals(kojiakSbt)||KOJIAK_SBT_JYUHENSIN.equals(kojiakSbt)
					||KOJIAK_SBT_SYUYO.equals(kojiakSbt) || KOJIAK_SBT_EO_TV_CHG.equals(kojiakSbt) || KOJIAK_SBT_ONU_CHG_KOJI.equals(kojiakSbt))
			// ANK-4315-00-00 MOD END
			{
				// 工事案件ステータスまたはマンション工事案件状態コードが
				// （依頼済：140）or（宅内調査完了済：160）or （工事会社決定済：160）
				// 　or（宅内機器予定登録済：170）or（仮鍵開発行依頼済：180）or（現場作業完了済：190）の場合、工事中とみなす
				if(JKKBatConst.KOJIAK_STAT_REQZM.equals(kojiakStat) 
						|| JKKBatConst.KOJIAK_STAT_TAKCHOFIN.equals(kojiakStat)
						|| JKKBatConst.KOJIAK_STAT_KOCOMPFIX.equals(kojiakStat)
						|| JKKBatConst.KOJIAK_STAT_TKKKADDZM.equals(kojiakStat)
						|| JKKBatConst.KOJIAK_STAT_KEYREQZM.equals(kojiakStat)
						|| JKKBatConst.KOJIAK_STAT_GEMBAWORKFIN.equals(kojiakStat)
						|| JKKBatConst.KOJIAK_STAT_REQZM.equals(mansKojiakStat)
						|| JKKBatConst.KOJIAK_STAT_KOCOMPFIX.equals(mansKojiakStat)
						)
				{
					// サービス契約_工事案件適用開始年月日が運用日以下　かつ　サービス契約_工事案件適用終了年月日が運用日より大きい
					if((super.opeDate.compareTo(kojiTekiStaYmd) >= 0) 
							&& super.opeDate.compareTo(kojiTekiEndYmd) < 0)
					{
						kojicyuKojiakNo = kojiInfoRec.getString(JBSbatKU_T_KOJIAK.KOJIAK_NO);
						break;
					}
				}
			}
			if(null == kojicyuKojiakNo )
			{
				if(KIHON_KOJI_FLG_ARI.equals(kihonKojiFlg))
				{
					kihonkojiKojiakNo = kojiInfoRec.getString(JBSbatKU_T_KOJIAK.KOJIAK_NO);
				}
			}
			// 次の工事案件レコードを取得し、処理を繰り返す
			kojiInfoRec = db_KU_T_SVKEI_KOJIAK.selectNext();
		}
		// 工事中の工事案件を優先して返す
		if(null != kojicyuKojiakNo)
		{
			tgtKojiak = kojicyuKojiakNo;
		}
		// 工事中の工事案件が無ければ基本工事フラグが立っている工事案件を返す
		else if(null != kihonkojiKojiakNo)
		{
			tgtKojiak = kihonkojiKojiakNo;
		}
		else
		{
			// 何もしない
		}
		
		return tgtKojiak;
	}
	
	// ANK-4427-00-00 ADD START
	/**
	 * NTT卸区分がNullでないく<br>
	 * 料金コースコードをリストにセットします。<br>
	 * <p>
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void setNttOrsPcrsCdList() throws Exception
	{
		
		nttOrsPcrsCdList = new ArrayList<String>();
		
		String batOpeDate = this.commonItem.getOpeDate();
		
		// 料金コースコードを取得
		executeKK_M_PCRS_KK_SELECT_013(batOpeDate);
		
		// 料金コースレコードを取得
		JBSbatCommonDBInterface pcrsInfoRec = db_KK_M_PCRS.selectNext();
		while(null != pcrsInfoRec)
		{
			// 料金コースコード
			String pcrsCd = pcrsInfoRec.getString(JBSbatKK_M_PCRS.PCRS_CD);
			// NTT卸区分
			String nttOrsDiv = pcrsInfoRec.getString(JBSbatKK_M_PCRS.NTTORS_DIV);

			if(nttOrsDiv != null && !("".equals(nttOrsDiv))) {
				nttOrsPcrsCdList.add(pcrsCd);
			}
			// 次の工事案件レコードを取得し、処理を繰り返す
			pcrsInfoRec = db_KK_M_PCRS.selectNext();
		}
	}	
	// ANK-4427-00-00 ADD END
	
	/**
	 * パラメータで指定されたリストを<br>
	 * カンマ区切り文字列に変換して返します<br>
	 * <p>
	 * @param lineArray リスト
	 * @return カンマ区切り文字列（各要素にダブルクォートも付与される）
	 */
	private String getRecordString(ArrayList<String> lineArray)
	{
		StringBuilder recString = new StringBuilder();
		for(String lineToken : lineArray)
		{
			if(!JKKBatConst.SPACE.equals(recString.toString()))
			{
				recString.append(JKKBatConst.S_SEP_CAM);
			}

			recString.append(JKKBatConst.S_DBL_QUOT);
			recString.append(lineToken);
			recString.append(JKKBatConst.S_DBL_QUOT);
		}
		return recString.toString();
	}
}
