/*********************************************************************
*  All Rights reserved,Copyright (c) Fujitsu ,2018					 *
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JBSbatACMVNOKaikInfoEdit
*	ソースファイル名	：JBSbatACMVNOKaikInfoEdit.java
*	作成者				：富士通　
*	作成日				：2023年08月09日
*＜機能概要＞
*　MVNO会計売掛金情報編集部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v67.00.00	2023/08/09   FJ)吉田あ		新規作成
*	v67.00.01	2023/08/09   FJ)吉田賢		【IT2-2023-0000001】料金月の設定／料金サービスコードのパディング
*	v67.00.02	2023/10/18   FJ)吉村		【#83196】しわ取り後の消費税額が普段の月より著しく少ない
*********************************************************************/
package eo.business.service;


import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import eo.business.common.JACbatRknBusinessUtil;
import eo.business.common.JACbatSchdlUtil;
import eo.business.common.JBSbatBusinessService;
import eo.business.util.file.JBSbatACIFM358;
import eo.common.constant.JACStrConst;
import eo.common.constant.JPCBatchMessageConstant;
import eo.common.util.JCHStringUtil;
import eo.common.util.JPCUtilCommon;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatServiceInterfaceMap;
import eo.framework.item.JBSbatOutputItem;

/**
* (クラスの機能概要) <p>
*<BR>
* @author 富士通
*/
public class JBSbatACMVNOKaikInfoEdit extends JBSbatBusinessService
{
	/**▼▼▼▼▼▼ツールから生成した宣言です 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成した宣言です 終了▲▲▲▲▲▲*/

	private static String seikyYm = null;
	
	/** 請求番号_999999999999 */
	private static final String SEIKYU_NO_999999999999  = "999999999999";
	
	// #83196 ADD START
	/** 税率区分コード 8% */
	public static final String TAX_RT_CD_8 = "1";
	
	/** 税率区分コード 10% */
	public static final String TAX_RT_CD_10 = "2";
	
	/** 税計算識別コード（消費税(内税)8%） */
	public static final String TAX_CALC_SKBT_CD_UTZEI_8 = "03";
	
	/** 税計算識別コード（消費税(内税)10%） */
	public static final String TAX_CALC_SKBT_CD_UTZEI_10 = "05";
	
	/** 会計内訳種別コード_会計用売掛金_10 */
	private static final String KAIK_UCWK_SBT_CD_10  = "10";
	
	/** 会計内訳種別詳細コード_会計用売掛金_1040 */
	private static final String KAIK_UCWK_SBT_DTL_CD_1040  = "1040";
	
	/** 会計内訳コード_うち消費税(8%) */
	private static final String KAIK_UCWK_CD_UTZEI_8  = "200000000000";
	
	/** 会計内訳コード_うち消費税(10%) */
	private static final String KAIK_UCWK_CD_UTZEI_10  = "400000000000";
	
	/** 料金項目コード_うち消費税(8%) */
	private static final String PRC_KMK_CD__UTZEI_8  = "10900910201";
	
	/** 料金項目コード_うち消費税(10%) */
	private static final String PRC_KMK_CD_UTZEI_10  = "20900910201";
	
	/** 業務共通クラスインスタンス */
	private JACbatRknBusinessUtil	rknBusinessUtil			= null;
	
	/** 入力レコード（退避）*/
	private JBSbatServiceInterfaceMap tmpMap = null;
	
	/** 消費税 合計金額 */
	private BigDecimal sumAmnt = BigDecimal.ZERO;
	/** 消費税 最終合計金額 */
	private BigDecimal lastSumAmnt = BigDecimal.ZERO;
	
	/** 消費税計算前リスト*/
	private List<JBSbatServiceInterfaceMap> bfCalcList = new ArrayList<JBSbatServiceInterfaceMap>();
	/** 消費税計算後リスト*/
	private List<JBSbatServiceInterfaceMap> afCalcList = new ArrayList<JBSbatServiceInterfaceMap>();
	/** 消費税マップ*/
	private JBSbatServiceInterfaceMap staxMap = null;
	// #83196 ADD END
	
	/**
	 * 初期処理
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した初期化のソースです 開始▼▼▼▼▼▼*/
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);

		JACbatSchdlUtil schdlUtil = new JACbatSchdlUtil(commonItem);
		seikyYm = schdlUtil.getBillDate(super.opeDate, JACStrConst.EVENT_CD_KAIK_SHORI_YMD);
		// 料金スケジュール定義アクセス部品クローズ
		schdlUtil.close();

		// #83196 ADD START
		this.rknBusinessUtil = new JACbatRknBusinessUtil(commonItem); 	// 料金業務共通クラス
		// #83196 ADD END

		
		/**▲▲▲▲▲▲ツールから生成した初期化のソースです 終了▲▲▲▲▲▲*/
	/**▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 主処理
	 * @param inMap　入力電文
	 * @return JBSbatOutputItem　出力情報
	 * @throws Exception
	 */
	public JBSbatOutputItem execute(JBSbatServiceInterfaceMap inMap) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの主処理を記述してください。▼▼▼▼▼▼*/

		JBSbatOutputItem outputBean = new JBSbatOutputItem();

		// 請求契約番号
		String seikyKeiNo = inMap.getString(JBSbatACIFM358.SEIKY_KEI_NO);
		// 支払方法
		String payway = inMap.getString(JBSbatACIFM358.PAY_WAY);
		// サービス契約番号
		String svcKeiNo = inMap.getString(JBSbatACIFM358.SVC_KEI_NO);
		
		// 請求契約番号が空の場合はWAを発報
		if(JCHStringUtil.isNullBlank(seikyKeiNo))
		{
			super.logPrint.printBusinessErrorLog(JPCBatchMessageConstant.EACB0840KW, new String[] {"サービス契約番号：" + svcKeiNo, "請求契約番号"});
			return outputBean;
		}
		// 支払方法が空の場合はWAを発報
		if(JCHStringUtil.isNullBlank(payway))
		{
			super.logPrint.printBusinessErrorLog(JPCBatchMessageConstant.EACB0840KW, new String[] {"サービス契約番号：" + svcKeiNo, "支払方法"});
			return outputBean;
		}
		
		// ファイル出力処理
		JBSbatServiceInterfaceMap outmap = new JBSbatServiceInterfaceMap();
		outmap = outPutFile(inMap);
		outmap.setOutFlg(true);
		outputBean.addOutMapList(outmap);
		
		// #83196 ADD START
		// 会計用売掛金のうち消費税額の算出
		JBSbatServiceInterfaceMap outstaxmap = new JBSbatServiceInterfaceMap();
		outstaxmap = mvnoStaxSum(outmap);
		if (null != outstaxmap){
			outstaxmap.setOutFlg(true);
			outputBean.addOutMapList(outstaxmap);
		}
		// #83196 ADD END

		return outputBean;
	/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * ファイル出力項目を設定します
	 * @param seikinMapyKeiNo 入力電文
	 * @return JBSbatServiceInterfaceMap 出力情報
	 */
	private JBSbatServiceInterfaceMap outPutFile(JBSbatServiceInterfaceMap inMap) throws Exception {
		JBSbatServiceInterfaceMap outmap = new JBSbatServiceInterfaceMap();
		
		outmap.setString(JBSbatACIFM358.KAIK_UCWK_SBT_CD, inMap.getString(JBSbatACIFM358.KAIK_UCWK_SBT_CD));
		outmap.setString(JBSbatACIFM358.KAIK_UCWK_SBT_DTL_CD, inMap.getString(JBSbatACIFM358.KAIK_UCWK_SBT_DTL_CD));
		outmap.setString(JBSbatACIFM358.SEIKY_KEI_NO, inMap.getString(JBSbatACIFM358.SEIKY_KEI_NO));
		outmap.setString(JBSbatACIFM358.KAIK_YM, seikyYm);
		outmap.setString(JBSbatACIFM358.KAIK_UCWK_CD, inMap.getString(JBSbatACIFM358.KAIK_UCWK_CD));
		outmap.setString(JBSbatACIFM358.PRC_GRP_CD, inMap.getString(JBSbatACIFM358.PRC_GRP_CD));
		outmap.setString(JBSbatACIFM358.PCRS_CD, inMap.getString(JBSbatACIFM358.PCRS_CD));
		// IT2-2023-0000001 MOD START
//		outmap.setString(JBSbatACIFM358.PRC_SVC_CD, inMap.getString(JBSbatACIFM358.PRC_SVC_CD));
		if(JCHStringUtil.isNullBlank(inMap.getString(JBSbatACIFM358.PRC_SVC_CD)))
		{
			outmap.setString(JBSbatACIFM358.PRC_SVC_CD, JACStrConst.PRC_SVC_CD_SP);

		}
		else {
			outmap.setString(JBSbatACIFM358.PRC_SVC_CD, JPCUtilCommon.fillHalfSpace(inMap.getString(JBSbatACIFM358.PRC_SVC_CD), 12, true));

		}
		// IT2-2023-0000001 MOD END
		outmap.setString(JBSbatACIFM358.PRC_KMK_CD, inMap.getString(JBSbatACIFM358.PRC_KMK_CD));
		outmap.setString(JBSbatACIFM358.CVSTORE_PAY_RSV_YMD, inMap.getString(JBSbatACIFM358.CVSTORE_PAY_RSV_YMD));
		outmap.setString(JBSbatACIFM358.CNT, inMap.getString(JBSbatACIFM358.CNT));
		outmap.setString(JBSbatACIFM358.AMNT, inMap.getString(JBSbatACIFM358.AMNT));
		outmap.setString(JBSbatACIFM358.SEIKY_NO, SEIKYU_NO_999999999999);
		// IT2-2023-0000001 MOD START
//		outmap.setString(JBSbatACIFM358.PRC_MON, inMap.getString(JBSbatACIFM358.PRC_MON));
		outmap.setString(JBSbatACIFM358.PRC_MON, seikyYm);
		// IT2-2023-0000001 MOD END
		outmap.setString(JBSbatACIFM358.SVC_KEI_NO, inMap.getString(JBSbatACIFM358.SVC_KEI_NO));
		outmap.setString(JBSbatACIFM358.PAY_WAY, inMap.getString(JBSbatACIFM358.PAY_WAY));
		outmap.setString(JBSbatACIFM358.CRECARD_COMP_CD, inMap.getString(JBSbatACIFM358.CRECARD_COMP_CD));
		outmap.setString(JBSbatACIFM358.CONT_SVC_CD, inMap.getString(JBSbatACIFM358.CONT_SVC_CD));
		outmap.setString(JBSbatACIFM358.COMP_SKBT_CD, inMap.getString(JBSbatACIFM358.COMP_SKBT_CD));

		outmap.setOutFlg(true);

		return outmap;
	}
	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼*/
		/**▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲*/
	/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}

	/**▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成したメソッドです 終了▲▲▲▲▲▲*/
	
	// #83196 ADD START 
	/**
	 * MVNO売掛金情報（うち消費税）を算出し、出力する
	 * @param inMap inputファイルマップ
	 * @return outMap    出力Map
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private JBSbatServiceInterfaceMap mvnoStaxSum(JBSbatServiceInterfaceMap outmap) throws Exception 
	{
		// 1件目（最終行ではなく、退避リストが空のとき）
		if (!this.commonItem.isEndRecordFlg() && null == tmpMap) {
			tmpMap = outmap;
			return null;
		}
		// 1件のみの処理の場合（最終行であり、退避リストが空のとき）
		else if (this.commonItem.isEndRecordFlg() && null == tmpMap) {
			// 消費税を算出し、ファイルに出力する
			BigDecimal amnt = new BigDecimal(outmap.getString(JBSbatACIFM358.AMNT));
			JBSbatServiceInterfaceMap afCalcMap = calcMvnoStax(outmap, amnt);
			lastSumAmnt = new BigDecimal(afCalcMap.getString(JBSbatACIFM358.AMNT));
			staxMap = fileOutMvnoStax(outmap, lastSumAmnt);
			return staxMap;
		}
		
		// 請求契約番号をキー設定
		// キー（退避）メイン生成
		String tmpSeikyKeiNo = tmpMap.getString(JBSbatACIFM358.SEIKY_KEI_NO);
		// キー（入力）メイン生成
		String inSeikyKeiNo = outmap.getString(JBSbatACIFM358.SEIKY_KEI_NO);
		
		//前レコードを計算前リストに入れる
		bfCalcList.add(tmpMap);
		// キーが一致
		if (!this.commonItem.isEndRecordFlg() && inSeikyKeiNo.equals(tmpSeikyKeiNo)) {
			// 入力リストを退避リストに格納する
			tmpMap = outmap;
			// 次レコードの処理へ
		}
		// 不一致の場合、請求契約番号単位で消費税を計算する処理を実行
		else
		{
			if (this.commonItem.isEndRecordFlg()) {
				// 最終レコードであり、請求契約番号が一致する場合は現レコードをリストに入れる
				if (inSeikyKeiNo.equals(tmpSeikyKeiNo)) {
					bfCalcList.add(outmap);
				}
				// 一致しない場合は該当レコードのみの消費税を算出する
				else {
					BigDecimal amnt = new BigDecimal(outmap.getString(JBSbatACIFM358.AMNT));
					JBSbatServiceInterfaceMap afCalcMap = calcMvnoStax(outmap, amnt);
					afCalcList.add(afCalcMap);
				}
			}
			
			// 請求契約番号1個分の処理実行
			for(int i = 0; i < bfCalcList.size(); i++){
				// 金額
				BigDecimal amnt = null;
				amnt = new BigDecimal(bfCalcList.get(i).getString(JBSbatACIFM358.AMNT));
				// 金額を足す
				sumAmnt = sumAmnt.add(amnt);
				}
			
			// 合計金額の消費税を算出する
			JBSbatServiceInterfaceMap afCalcMap = calcMvnoStax(outmap, sumAmnt);
			
			// 入力リストを退避リストに格納する
			tmpMap = outmap;
			// 計算情報をクリアする
			bfCalcList = new ArrayList<JBSbatServiceInterfaceMap>();
			sumAmnt = BigDecimal.ZERO;
			
			// 最終レコードの場合、計算後マップの消費税を合算し、消費税マップにMVNO売掛金情報をセットする
			afCalcList.add(afCalcMap);
			if (this.commonItem.isEndRecordFlg()) {
				// 消費税を合算する
				for(int i = 0; i < afCalcList.size(); i++){
					// 合計金額
					BigDecimal sumAmnt = null;
					sumAmnt = new BigDecimal(afCalcList.get(i).getString(JBSbatACIFM358.AMNT));
					// 金額を足す
					lastSumAmnt = lastSumAmnt.add(sumAmnt);
				}
				// MVNO売掛金情報（うち消費税）のファイル出力処理
				staxMap = fileOutMvnoStax(outmap, lastSumAmnt);
			}
		}
		
		return staxMap;
		
	}
	/**
	 * 消費税を算出する
	 * @param inMap inputファイルマップ
	 * @return outMap    出力Map
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private JBSbatServiceInterfaceMap calcMvnoStax(JBSbatServiceInterfaceMap outmap, BigDecimal sumAmnt) throws Exception 
	{
		// 計算情報を設定するMap
		JBSbatServiceInterfaceMap afCalcMap = new JBSbatServiceInterfaceMap();
		
		// 料金項目コード（工事費割賦情報）上１桁
		String taxRateCd = outmap.getString(JBSbatACIFM358.PRC_KMK_CD).substring(0, 1);
		// 税計算識別コード
		String taxCalcSkbtCd = "";

		if (TAX_RT_CD_8.equals(taxRateCd))
		{
			// 税計算識別コード（消費税(内税)8%）を設定
			taxCalcSkbtCd = TAX_CALC_SKBT_CD_UTZEI_8;
		}
		else if (TAX_RT_CD_10.equals(taxRateCd)) {
			// 税計算識別コード（消費税(内税)10%）を設定
			taxCalcSkbtCd = TAX_CALC_SKBT_CD_UTZEI_10;
		}

		// 消費税を計算する
		BigDecimal[] tax = this.rknBusinessUtil.calcTaxCharge(taxCalcSkbtCd, sumAmnt, super.opeDate);

		// 消費税情報を計算後マップに格納する
		String stax = tax[0].toString();
		afCalcMap.setString(JBSbatACIFM358.AMNT, stax);

		return afCalcMap;
	}
	/**
	 * MVNO売掛金情報（うち消費税）を出力する
	 * @param inMap inputファイルマップ
	 * @return outMap    出力Map
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private JBSbatServiceInterfaceMap fileOutMvnoStax(JBSbatServiceInterfaceMap outmap, BigDecimal lastSumAmnt) throws Exception 
	{
		// 出力情報を設定するMap
		JBSbatServiceInterfaceMap outstaxmap = new JBSbatServiceInterfaceMap();
		
		// 料金項目コード（工事費割賦情報）上１桁
		String taxRateCd = outmap.getString(JBSbatACIFM358.PRC_KMK_CD).substring(0, 1);
		// 料金項目コード
		String prcKmkCd = "";
		// 会計内訳コード
		String kaikUcwkCd = "";
		if (TAX_RT_CD_8.equals(taxRateCd))
		{
			// 料金項目コード(8%)を設定
			prcKmkCd = PRC_KMK_CD__UTZEI_8;
			// 会計内訳コード
			kaikUcwkCd = KAIK_UCWK_CD_UTZEI_8;
		}
		else if (TAX_RT_CD_10.equals(taxRateCd)) {
			// 料金項目コード(10%)を設定
			prcKmkCd = PRC_KMK_CD_UTZEI_10;
			// 会計内訳コード
			kaikUcwkCd = KAIK_UCWK_CD_UTZEI_10;
		}

		outstaxmap.setString(JBSbatACIFM358.KAIK_UCWK_SBT_CD, KAIK_UCWK_SBT_CD_10);
		outstaxmap.setString(JBSbatACIFM358.KAIK_UCWK_SBT_DTL_CD, KAIK_UCWK_SBT_DTL_CD_1040);
		outstaxmap.setString(JBSbatACIFM358.SEIKY_KEI_NO, outmap.getString(JBSbatACIFM358.SEIKY_KEI_NO));
		outstaxmap.setString(JBSbatACIFM358.KAIK_YM, seikyYm);
		outstaxmap.setString(JBSbatACIFM358.KAIK_UCWK_CD, kaikUcwkCd);
		outstaxmap.setString(JBSbatACIFM358.PRC_GRP_CD, outmap.getString(JBSbatACIFM358.PRC_GRP_CD));
		outstaxmap.setString(JBSbatACIFM358.PCRS_CD, JACStrConst.PCRS_CD_SP);
		outstaxmap.setString(JBSbatACIFM358.PRC_SVC_CD, JACStrConst.PRC_SVC_CD_SP);
		outstaxmap.setString(JBSbatACIFM358.PRC_KMK_CD, prcKmkCd);
		outstaxmap.setString(JBSbatACIFM358.CVSTORE_PAY_RSV_YMD, "");
		outstaxmap.setString(JBSbatACIFM358.CNT, "1");
		outstaxmap.setString(JBSbatACIFM358.AMNT, lastSumAmnt);
		outstaxmap.setString(JBSbatACIFM358.SEIKY_NO, SEIKYU_NO_999999999999);
		outstaxmap.setString(JBSbatACIFM358.PRC_MON, seikyYm);
		outstaxmap.setString(JBSbatACIFM358.SVC_KEI_NO, JACStrConst.SVC_KEI_NO_SP);
		outstaxmap.setString(JBSbatACIFM358.PAY_WAY, outmap.getString(JBSbatACIFM358.PAY_WAY));
		outstaxmap.setString(JBSbatACIFM358.CRECARD_COMP_CD, "");
		outstaxmap.setString(JBSbatACIFM358.CONT_SVC_CD, "");
		outstaxmap.setString(JBSbatACIFM358.COMP_SKBT_CD, "");

		outstaxmap.setOutFlg(true);

		return outstaxmap;
	}
	// #83196 ADD END
}
