/*********************************************************************
 *  All Rights reserved,Copyright (c) K-Opticom
 **********************************************************************
 *＜プログラム内容＞
 *	システム名			：eo顧客基幹システム
 *	モジュール名		：JBSbatCHKsdAddMishuSknInfoSksi
 *	ソースファイル名	：JBSbatCHKsdAddMishuSknInfoSksi.java
 *	作成者				：富士通　
 *	作成日				：2014年07月15日
 *＜機能概要＞
 *　貸倒登録未収債権情報作成部品です。
 *＜修正履歴＞
 *	バージョン	修正日		修正者		修正内容
 *	v10.00.00	2014/07/15   富士通		新規作成
 *	v55.00.00	2021/10/01	FJ)森脇		【ANK-4121-00-00】貸倒対象者一覧のマイナス金額出力対応
 *********************************************************************/
package eo.business.service;

import java.math.BigDecimal;

import eo.business.common.JACbatDebugLogUtil;
import eo.business.common.JACbatRknBusinessUtil;
import eo.business.common.JBSbatBusinessService;
import eo.business.common.JBSbatMatchServiceInterface;
import eo.business.common.JCHbatSeikyKaknoBusinessUtil;
import eo.business.util.file.JBSbatCHIFM233;
import eo.business.util.file.JBSbatCHIFM234;
import eo.business.util.file.JBSbatCHIFM235;
import eo.common.constant.JACStrConst;
import eo.common.constant.JPCBatchMessageConstant;
import eo.common.util.JACTaxCalcShikibetuCodeUtil;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.item.JBSbatServiceInterfaceMap;

/**
 * (クラスの機能概要)
 * <p>
 *<BR>
 * 
 * @author 富士通
 */
public class JBSbatCHKsdAddMishuSknInfoSksi extends JBSbatBusinessService implements JBSbatMatchServiceInterface
{
	/** ▼▼▼▼▼▼ツールから生成した宣言です 開始▼▼▼▼▼▼ */
	/** キーマッチ処理フラグ */
	private boolean matchProcFlg;

	/** マスタファイル処理フラグ */
	private boolean mastProcFlg;

	/** トランファイル処理フラグ */
	private boolean tranProcFlg;
	/** ▲▲▲▲▲▲ツールから生成した宣言です 終了▲▲▲▲▲▲ */

	/** 充当額残 **/
	private BigDecimal jutoAmntZan = BigDecimal.ZERO;

	/** 充当額残初期化フラグ **/
	private boolean jutoAmntZanInitFlg = false;

	/** 税計算識別コード管理クラス */
	private JACTaxCalcShikibetuCodeUtil jACTaxCalcShikibetuCodeUtil = null;

	/** 料金業務共通クラスインスタンス */
	private JACbatRknBusinessUtil rknBusinessUtil = null;

	/** 請求収納業務共通クラスインス */
	private JCHbatSeikyKaknoBusinessUtil skBusinessUtil = null;

	/**
	 * 初期処理
	 * 
	 * @param JBSbatCommonItem commonItem バッチ共通パラメータ電文
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
		/** ▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼ */
		/** ▼▼▼▼▼▼ツールから生成した初期化のソースです 開始▼▼▼▼▼▼ */
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][initial]");
		/** ▲▲▲▲▲▲ツールから生成した初期化のソースです 終了▲▲▲▲▲▲ */

		// 税計算識別コード管理クラスのインスタンス生成
		this.jACTaxCalcShikibetuCodeUtil = new JACTaxCalcShikibetuCodeUtil(JACStrConst.CALLER_BATCH, commonItem.getConnection());

		// 料金業務共通クラスインスタンス生成
		this.rknBusinessUtil = new JACbatRknBusinessUtil(commonItem);

		// 請求収納業務共通クラスインスタンス生成
		this.skBusinessUtil = new JCHbatSeikyKaknoBusinessUtil(commonItem);

		// 充当額残初期化フラグに true を設定
		jutoAmntZanInitFlg = true;

		/** ▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲ */
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][initial][opeDate=" + super.opeDate + "]");
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][initial][freeItem=" + super.freeItem + "]");
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][initial]");
	}

	/**
	 * 主処理
	 * 
	 * @param mastMap 入力電文
	 * @param tranMap 入力電文
	 * @param outputInItem 入力情報
	 * @return JBSbatOutputItem 出力情報
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	public JBSbatOutputItem execute(JBSbatServiceInterfaceMap mastMap, JBSbatServiceInterfaceMap tranMap, JBSbatOutputItem outputInItem) throws Exception
	{
		/** ▼▼▼▼▼▼業務サービスの主処理を記述してください。▼▼▼▼▼▼ */
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][execute]");
		assert mastMap != null ? JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][execute][mastMap=" + mastMap.getMap().toString() + "]") : true;
		assert tranMap != null ? JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][execute][tranMap=" + tranMap.getMap().toString() + "]") : true;

		if (mastMap != null && tranMap == null)
		{
			assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][execute][入力Ｍのみ存在する]");
			// 入力Ｍのみ存在する場合

			this.setMastProcFlg(true);

			// 充当額残を初期化
			resetJutoAmntZan(mastMap);

			if (jutoAmntZan.compareTo(BigDecimal.ZERO) > 0)
			{
				// 充当額残が 0 より大きい場合

				// ワーニング
				super.logPrint.printBusinessErrorLog(JPCBatchMessageConstant.ECHB1500KW,
						new String[] { "マスタ情報（" + getMastLogInfo(mastMap) + "）に対してトラン情報が存在しない、またはトラン情報の金額が小さいです。" });
			}

			// 充当額残初期化フラグに true を設定
			jutoAmntZanInitFlg = true;

		}
		else if (mastMap == null && tranMap != null)
		{
			assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][execute][入力Ｔのみ存在する]");
			// 入力Ｔのみ存在する場合

			this.setTranProcFlg(true);
			// 出力情報生成
			makeOutPutMap(tranMap, outputInItem);
		}
		else
		{
			// 入力Ｍ、入力Ｔともに存在する

			// 充当額残を初期化
			resetJutoAmntZan(mastMap);

			// キー情報取得
			String mastSeiKeiNo = mastMap.getString(JBSbatCHIFM234.SEIKY_KEI_NO); // 貸倒登録対象充当額.請求契約番号
			String mastSknNo = mastMap.getString(JBSbatCHIFM234.SAIKEN_NO); // 貸倒登録対象充当額.債権番号
			String tranSeiKeiNo = tranMap.getString(JBSbatCHIFM233.SEIKY_KEI_NO); // 貸倒登録対象債権額.請求契約番号
			String tranSknNo = tranMap.getString(JBSbatCHIFM233.SAIKEN_NO); // 貸倒登録対象債権額.債権番号

			// マッチングキー（マスタ）を作成
			StringBuffer mastKey = new StringBuffer();
			mastKey.append(mastSeiKeiNo);
			mastKey.append(mastSknNo);

			// マッチングキー（トラン）を作成
			StringBuffer tranKey = new StringBuffer();
			tranKey.append(tranSeiKeiNo);
			tranKey.append(tranSknNo);

			if (mastKey.toString().compareTo(tranKey.toString()) == 0)
			{
				assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][execute][入力Ｍ、入力Ｔともに存在する][入力Ｍ＝入力Ｔ]");
				// 入力Ｍ = 入力Ｔ
				this.setMatchProcFlg(true);

				// 債権額取得
				BigDecimal sknAmnt = tranMap.getBigDecimal(JBSbatCHIFM233.SAIKEN_AMNT);

				if (sknAmnt.compareTo(jutoAmntZan) > 0)
				{
					// 債権額が充当額残より大きい場合

					// 出力情報生成
					makeOutPutMap(tranMap, outputInItem);
					// 充当額残に 0 を設定
					jutoAmntZan = BigDecimal.ZERO;
				}
				else if (sknAmnt.compareTo(BigDecimal.ZERO) > 0)
				{
					// 債権額が 0 より大きい場合
					
					// 充当額残に 充当額残 - 債権額 を設定
					jutoAmntZan = jutoAmntZan.subtract(sknAmnt);
				}

			}
			else if (mastKey.toString().compareTo(tranKey.toString()) < 0)
			{
				assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][execute][入力Ｍ、入力Ｔともに存在する][入力Ｍ＜入力Ｔ]");
				// 入力Ｍ < 入力Ｔ
				this.setMastProcFlg(true);

				if (jutoAmntZan.compareTo(BigDecimal.ZERO) > 0)
				{
					// 充当額残が 0 より大きい場合

					// ワーニング
					super.logPrint.printBusinessErrorLog(JPCBatchMessageConstant.ECHB1500KW, 
							new String[] { "マスタ情報（" + getMastLogInfo(mastMap) + "）に対してトラン情報が存在しない、またはトラン情報の金額が小さいです。" });
				}

				// 充当額残初期化フラグに true を設定
				jutoAmntZanInitFlg = true;
			}
			else
			{
				assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[L][execute][入力Ｍ、入力Ｔともに存在する][入力Ｍ＞入力Ｔ]");
				// 入力Ｍ > 入力Ｔ
				this.setTranProcFlg(true);
				// 出力情報生成
				makeOutPutMap(tranMap, outputInItem);
			}
		}
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][execute]");
		return outputInItem;
		/** ▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲ */
	}

	/**
	 * 業務サービス終了処理
	 * 
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	public void terminal() throws Exception
	{
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][terminal]");
		/** ▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼ */
		/** ▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼ */
		/** ▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲ */

		// 請求収納業務共通クラスインスclose
		this.skBusinessUtil.close();

		/** ▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲ */
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][terminal]");
	}

	/** ▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼ */
	/**
	 * @return mastProcFlg を戻します。
	 */
	public boolean isMastProcFlg()
	{
		return mastProcFlg;
	}

	/**
	 * @return matchProcFlg を戻します。
	 */
	public boolean isMatchProcFlg()
	{
		return matchProcFlg;
	}

	/**
	 * @return tranProcFlg を戻します。
	 */
	public boolean isTranProcFlg()
	{
		return tranProcFlg;
	}

	/**
	 * @param mast_ProcFlg 設定する mastProcFlg。
	 */
	public void setMastProcFlg(boolean mast_ProcFlg)
	{
		this.mastProcFlg = mast_ProcFlg;
	}

	/**
	 * @param match_ProcFlg 設定する matchProcFlg。
	 */
	public void setMatchProcFlg(boolean match_ProcFlg)
	{
		this.matchProcFlg = match_ProcFlg;
	}

	/**
	 * @param tran_ProcFlg 設定する tranProcFlg。
	 */
	public void setTranProcFlg(boolean tran_ProcFlg)
	{
		this.tranProcFlg = tran_ProcFlg;
	}

	/** ▲▲▲▲▲▲ツールから生成したメソッドです 終了▲▲▲▲▲▲ */

	/**
	 * 出力データ編集
	 * 
	 * @param tranMap 入力電文
	 * @param outputInItem 入力情報
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private void makeOutPutMap(JBSbatServiceInterfaceMap tranMap, JBSbatOutputItem outputInItem) throws Exception
	{
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][makeOutPutMap]");
		
		if (tranMap.getBigDecimal(JBSbatCHIFM233.SAIKEN_AMNT).compareTo(BigDecimal.ZERO) <= 0)
		{
			// 債権額が 0 以下の場合は出力対象外
			return;
		}

		JBSbatServiceInterfaceMap outputMap = new JBSbatServiceInterfaceMap();

		// 請求契約番号
		outputMap.setString(JBSbatCHIFM235.SEIKY_KEI_NO, tranMap.getString(JBSbatCHIFM233.SEIKY_KEI_NO));
		// 債権番号
		outputMap.setString(JBSbatCHIFM235.SAIKEN_NO, tranMap.getString(JBSbatCHIFM233.SAIKEN_NO));
		// 処理順
		outputMap.setInt(JBSbatCHIFM235.TRN_JUN, tranMap.getInt(JBSbatCHIFM233.TRN_JUN));
		// 未収額変換後料金グループコード
		outputMap.setString(JBSbatCHIFM235.MISHU_AMNT_CHG_PRC_GRP_CD, tranMap.getString(JBSbatCHIFM233.MISHU_AMNT_CHG_PRC_GRP_CD));
		// 未収額変換後料金コースコード
		outputMap.setString(JBSbatCHIFM235.MISHU_AMNT_CHG_PCRS_CD, tranMap.getString(JBSbatCHIFM233.MISHU_AMNT_CHG_PCRS_CD));
		// 未収額変換後料金サービスコード
		outputMap.setString(JBSbatCHIFM235.MISHU_AMNT_CHG_PRC_SVC_CD, tranMap.getString(JBSbatCHIFM233.MISHU_AMNT_CHG_PRC_SVC_CD));
		// 未収額変換後料金項目コード
		outputMap.setString(JBSbatCHIFM235.MISHU_AMNT_CHG_PRC_KMK_CD, tranMap.getString(JBSbatCHIFM233.MISHU_AMNT_CHG_PRC_KMK_CD));
		// 債権年月
		outputMap.setString(JBSbatCHIFM235.SAIKEN_YM, tranMap.getString(JBSbatCHIFM233.SAIKEN_YM));
		// 請求種別コード
		outputMap.setString(JBSbatCHIFM235.SEIKY_SBT_CD, tranMap.getString(JBSbatCHIFM233.SEIKY_SBT_CD));
		// 課税免税区分
		outputMap.setString(JBSbatCHIFM235.KAZEI_HIKAZEI_DIV, tranMap.getString(JBSbatCHIFM233.KAZEI_HIKAZEI_DIV));
		// 消費税区分
		outputMap.setString(JBSbatCHIFM235.TAX_DIV, tranMap.getString(JBSbatCHIFM233.TAX_DIV));
		// 請求元会社コード
		outputMap.setString(JBSbatCHIFM235.SIKY_MT_COMP_CD, tranMap.getString(JBSbatCHIFM233.SIKY_MT_COMP_CD));
		// 未収額
		if (isMatchProcFlg())
		{
			// 入力Ｍ = 入力Ｔ の場合
			outputMap.setBigDecimal(JBSbatCHIFM235.MISHU_AMNT, tranMap.getBigDecimal(JBSbatCHIFM233.SAIKEN_AMNT).subtract(jutoAmntZan));
		}
		else
		{
			// 入力Ｍ = 入力Ｔ でない場合
			outputMap.setBigDecimal(JBSbatCHIFM235.MISHU_AMNT, tranMap.getBigDecimal(JBSbatCHIFM233.SAIKEN_AMNT));
		}
		// 消費税額、消費税率
		String[] stax = getStax(tranMap.getString(JBSbatCHIFM233.TAX_DIV), tranMap.getString(JBSbatCHIFM233.MISHU_AMNT_CHG_PRC_KMK_CD), tranMap.getString(JBSbatCHIFM233.SAIKEN_YM), outputMap.getBigDecimal(JBSbatCHIFM235.MISHU_AMNT));
		outputMap.setString(JBSbatCHIFM235.STAX_AMNT, stax[0]);
		outputMap.setString(JBSbatCHIFM235.STAX_RT, stax[1]);

		// 出力フラグを設定
		outputMap.setOutFlg(true);

		// 出力共通電文に設定
		outputInItem.addOutMapList(outputMap);

		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][makeOutPutMap]");
	}

	/**
	 * 消費税額、消費税率取得
	 * 
	 * @param taxDiv 消費税区分
	 * @param prcKmkCd 料金項目コード
	 * @param saikenYm 債権年月
	 * @param mishuAmnt 未収額
	 * @return String[0]：消費税額、[1]：消費税率(小数点以下2桁)
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private String[] getStax(String taxDiv, String prcKmkCd, String saikenYm, BigDecimal mishuAmnt) throws Exception
	{
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][getStax]");

		if (JACStrConst.SPACE_1.equals(taxDiv))
		{
			// 消費税区分が半角スペースの場合
			//return new String[] { JACStrConst.KARA_MOJI, JACStrConst.KARA_MOJI };
			return new String[] { "0", JACStrConst.KARA_MOJI };
		}

		// 税率コード
		String taxRateCd = prcKmkCd.substring(0, 1);
		// 税計算区分
		String taxSkbtCd = this.jACTaxCalcShikibetuCodeUtil.getTaxSkbtCd(taxRateCd, JACStrConst.UZEI_SZEI_SKBT_UCHI, super.opeDate);
		// 基準日
		String stdardYmd = skBusinessUtil.getEventYmd(saikenYm, JACStrConst.EVENT_CD_USE_ENDYMD);

		// 消費税相当額計算
// ANK-4121-00-00 MOD START
//		BigDecimal[] tax = this.rknBusinessUtil.calcTaxCharge(taxSkbtCd, mishuAmnt, stdardYmd);
		BigDecimal[] tax = this.rknBusinessUtil.calcTaxCharge(taxSkbtCd, mishuAmnt, stdardYmd, false);
// ANK-4121-00-00 MOD END

		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][getStax]");
		return new String[] { tax[0].toString(), tax[1].setScale(2).toString() };
	}

	/**
	 * 充当額残初期化
	 * 
	 * @param mastMap 入力電文
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private void resetJutoAmntZan(JBSbatServiceInterfaceMap mastMap) throws Exception
	{
		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[S][resetJutoAmntZan]");

		if (jutoAmntZanInitFlg)
		{
			// 充当額残初期化フラグが true の場合

			// 充当額残を初期化
			jutoAmntZan = mastMap.getBigDecimal(JBSbatCHIFM234.JUTO_AMNT);
			// 充当額残初期化フラグに false を設定
			jutoAmntZanInitFlg = false;
		}

		assert JACbatDebugLogUtil.printDebugLog(super.logPrint, "[E][resetJutoAmntZan]");
	}

	/**
	 * ログ出力用のマスタ側マッチングキー情報を作成して返却します。
	 * 
	 * @param mastMap 入力電文
	 * @return ログ出力用マッチングキー情報
	 * @throws Exception 業務サービス内で発生した例外全般
	 */
	private String getMastLogInfo(JBSbatServiceInterfaceMap mastMap) throws Exception
	{
		// キー情報（請求契約番号＋債権番号）作成 
		StringBuffer mastKey = new StringBuffer();
		mastKey.append(JBSbatCHIFM234.SEIKY_KEI_NO);
		mastKey.append(":");
		mastKey.append(mastMap.getString(JBSbatCHIFM234.SEIKY_KEI_NO));
		mastKey.append(", ");
		mastKey.append(JBSbatCHIFM234.SAIKEN_NO);
		mastKey.append(":");
		mastKey.append(mastMap.getString(JBSbatCHIFM234.SAIKEN_NO));

		return mastKey.toString();
	}

}
