/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JFUCalcPlanPrcExcludeTax
*   ソースファイル名：JFUCalcPlanPrcExcludeTax.java
*   作成者          ：富士通
*   日付            ：2013年12月26日
*＜機能概要＞
*   プラン金額税抜計算部品です。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v8.00       2012/12/26   FJ)岡井     【ANK-1589-00-00】消費増税に伴う料金施策
*   v40.01      2019/02/14   FJ)張本     【ANK-3412-08-00】高速割料金と料金シュミレーションの改善
*   v45.00      2019/07/31   FJ)西川     【ANK-3636-00-00】消費増税対応（8%⇒10%）の小数誤差修正
*
**********************************************************************/
package eo.web.webview.common;

import static com.fujitsu.futurity.web.x31.X31SWebLog.DEBUG_LOG;

import java.math.BigDecimal;
import java.util.Map;

import com.fujitsu.futurity.web.x00.JCCBusinessException;
import com.fujitsu.futurity.web.x31.X31BWebBusinessLogic;

import eo.common.constant.JFUStrConst;
import eo.common.util.JPCDateUtil;

/**
 * プラン金額税抜計算結果出力部品です。
 * <br>
 * @author 富士通
 */
public class JFUCalcPlanPrcExcludeTax
{

	/** 定義取得パス：消費税関係 */
	private static final String PATH_TAX = "DISPSETTING/COMMONSETTING/DISPTEXT[@groupid='TAX']";
	/** 税率 */
	private static final String TAX_RATE = "tax_rate";

	/**
	 * プラン金額税抜計算処理です。
	 *
	 * <br>
	 * @param bl X31BWebBusinessLogic
	 * @param inPlanPrc プラン金額
	 * @return 計算結果
	 * @throws Exception 例外
	 */
	public static String calcPlanPrcExcludeTax(X31BWebBusinessLogic bl, String inPlanPrc) throws Exception
	{
		// 結果格納
		String planPrcTax = inPlanPrc;

		try
		{
			// 値チェック
			if(JFUWebCommon.isNull(inPlanPrc))
			{
				// システムエラー
				DEBUG_LOG.info("※料金プラン金額未設定エラー");
				throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0002);
			}

			// 税率取得
			String taxRate = getTaxRate(bl);

			// 金額取得
			String planPrc = getPlanPrc(inPlanPrc);

			// 税率計算結果
			planPrcTax = calcPlanPrc(taxRate, planPrc);

		}
		catch (Exception e)
		{
			DEBUG_LOG.info("※税抜き計算中にエラー");
			DEBUG_LOG.info("エラー内容：" + e.toString());
			throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0002);
		}

		return planPrcTax;
	}

	/**
	 * プラン金額税抜計算処理です。
	 *
	 * <br>
	 * @param bl X31BWebBusinessLogic
	 * @param inPlanPrc プラン金額
	 * @return 計算結果
	 * @throws Exception 例外
	 */
	public static String calcPlanPrcExcludeTaxCut(X31BWebBusinessLogic bl, String inPlanPrc) throws Exception
	{
		// 結果格納
		String planPrcTax = inPlanPrc;

		try
		{
			// 値チェック
			if(JFUWebCommon.isNull(inPlanPrc))
			{
				// システムエラー
				DEBUG_LOG.info("※料金プラン金額未設定エラー");
				throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0002);
			}

			// 税率取得
			String taxRate = getTaxRate(bl);

			// 金額取得
			String planPrc = getPlanPrc(inPlanPrc);

			// 税率計算結果
			planPrcTax = calcPlanPrcCut(taxRate, planPrc);

		}
		catch (Exception e)
		{
			DEBUG_LOG.info("※税抜き計算中にエラー");
			DEBUG_LOG.info("エラー内容：" + e.toString());
			throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0002);
		}

		return planPrcTax;
	}

	/**
	 * 税率を取得します。
	 *
	 * <br>
	 * @param bl X31BWebBusinessLogic
	 * @return 税率
	 * @throws Exception 例外
	 */
	@SuppressWarnings("unchecked")
	private static String getTaxRate(X31BWebBusinessLogic bl) throws Exception
	{
		// 返却税率格納用
		String taxRate = JFUStrConst.EMPTY;

		// 消費税関係の情報を取得
		Map taxMap = JFUWebCommon.getDispItemsAsMap(PATH_TAX, JFUStrConst.QUERY_ATTR_NAME);

		// 税率情報取得
		String taxRateInfo = (String)taxMap.get(TAX_RATE);

		// オンライン運用日取得
		String opeDate = JCCWebCommon.getOpeDate(bl, null);

		// 設定されている有効な税率を取得
		if(taxRateInfo.contains(JFUStrConst.HALF_COLON))
		{
			// 半角コロンが含んでいる場合、複数設定値があるのでループして有効な設定値を取得
			String[] taxRateArray = taxRateInfo.split(JFUStrConst.HALF_COLON);

			for (int i = 0; i < taxRateArray.length; i++)
			{
				String val = taxRateArray[i];
				if(JFUWebCommon.isNull(val))
				{
					// 不正値の場合
					continue;
				}

				String[] childInfo = val.split(JFUStrConst.COMMA);
				if(JFUWebCommon.isNull(childInfo) || childInfo.length != 3)
				{
					// 不正値の場合
					continue;
				}

				// 税率
				String rate = childInfo[0];
				// 開始日
				String start = childInfo[1];
				// 終了日
				String end = childInfo[2];

				// 有効期限チェック
				if(JPCDateUtil.subtractDay(opeDate, start) >= 0 && JPCDateUtil.subtractDay(end, opeDate) >= 0)
				{
					// 有効期限内の税率を取得
					taxRate = rate;
					break;
				}
			}
		}
		else
		{
			// 半角コロンが含んでいない場合、設定値が1つだけなのでその設定値を取得
			String[] childInfo = taxRateInfo.split(JFUStrConst.COMMA);

			if(JFUWebCommon.isNull(childInfo) || childInfo.length != 3)
			{
				// 不正値の場合、システムエラー
				DEBUG_LOG.info("※税率設定値不正エラー");
				throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0002);
			}

			// 税率
			String rate = childInfo[0];
			// 開始日
			String start = childInfo[1];
			// 終了日
			String end = childInfo[2];

			// 有効期限チェック
			if(JPCDateUtil.subtractDay(start, opeDate) >= 0 && JPCDateUtil.subtractDay(opeDate, end) >= 0)
			{
				// 有効期限内の税率を取得
				taxRate = rate;
			}
		}

		if(JFUWebCommon.isNull(taxRate))
		{
			DEBUG_LOG.info("※税率設定値不正エラー");
			throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0002);
		}

		return taxRate;
	}

	/**
	 * 金額を取得します。
	 *
	 * <br>
	 * @param inPlanPrc プラン金額文字列
	 * @return プラン金額
	 */
	private static String getPlanPrc(String inPlanPrc)
	{
		String prc = JFUStrConst.EMPTY;

		if(inPlanPrc.contains(JFUStrConst.YEN))
		{
			// 円がある場合、円で区切る
			prc = inPlanPrc.split(JFUStrConst.YEN)[0].trim();
		}
		else
		{
			// 円がない場合、そのまま使用
			prc = inPlanPrc;
		}

		return prc;
	}

	/**
	 * 税抜計算(小数点切り上げ)処理です。
	 *
	 * <br>
	 * @param inTaxRate 税率
	 * @param inPlanPrc プラン金額
	 * @return 計算結果
	 */
	private static String calcPlanPrc(String inTaxRate, String inPlanPrc)
	{
		// 切り上げ結果を返却
		return calcPlanPrc(inTaxRate, inPlanPrc, BigDecimal.ROUND_UP);
	}

	/**
	 * 税抜計算(小数点切り捨て)処理です。
	 *
	 * <br>
	 * @param inTaxRate 税率
	 * @param inPlanPrc プラン金額
	 * @return 計算結果
	 */
	private static String calcPlanPrcCut(String inTaxRate, String inPlanPrc)
	{
		// 切り捨て結果を返却
		return calcPlanPrc(inTaxRate, inPlanPrc, BigDecimal.ROUND_DOWN);
	}

	/**
	 * 税抜計算処理です。
	 *
	 * <br>
	 * @param inTaxRate 税率
	 * @param inPlanPrc プラン金額
	 * @param roundType 小数点切り捨て／切り上げなどを指定
	 * @return 計算結果
	 */
	private static String calcPlanPrc(String inTaxRate, String inPlanPrc,int roundType)
	{

		// 税込金額
		BigDecimal planPrcBig = new BigDecimal(inPlanPrc);
		// 税率
		BigDecimal taxRateBig = new BigDecimal(inTaxRate);

		BigDecimal res = planPrcBig.divide(taxRateBig, 0, roundType);

		// 切り上げ結果を返却
		return String.valueOf(res);
	}
}
