/**
 * Copyright (c) 2009 Penril Datability (SEA) Sdn Bhd All rights reserved.
 *
 * This software is copyrighted. Under the copyright laws, this software
 * may not be copied, in whole or in part, without prior written consent
 * of Penril Datability (SEA) Sdn Bhd or its assignees. This software is
 * provided under the terms of a license between Penril Datability (SEA)
 * Sdn Bhd and the recipient, and its use is subject to the terms of that
 * license.
 */

package my.com.kfh.enterprise.services.ib105_billpayment;

import java.util.List;
import java.util.Map;

import my.com.kfh.enterprise.services.IBUtils;
import my.com.kfh.enterprise.services.common.CommonConstants;
import my.com.kfh.enterprise.services.ib105_billpayment.constant.BillPaymentContants;
import my.com.kfh.enterprise.services.ib112_si.IBGenericSIServices;
import my.com.kfh.error.exception.IBBusinessException;
import my.com.kfh.error.exception.IBGenericException;
import my.com.kfh.error.exception.IBServiceException;
import my.com.kfh.error.handler.CommonErrorCode;
import my.com.kfh.error.handler.IBErrorHandler;
import my.com.kfh.hibernate.tables.IBGSTContent;
import my.com.kfh.hibernate.utils.HibernateUtils;
import my.com.kfh.sms.services.SMSServices;
import my.com.kfh.web.utils.DataValidator;
import my.com.kfh.web.utils.FormatterUtils;
import my.com.kfh.web.utils.GSTUtils;
import my.com.kfh.web.utils.IBDynaBean;
import my.com.kfh.web.utils.IBLoadProperty;
import my.com.kfh.web.utils.IBLogger;
import my.com.kfh.web.utils.IBSessionObjects;
import my.com.kfh.web.utils.IBTimer;
import my.com.kfh.web.utils.constant.ServiceInfo;

/**
 * <pre>
 * PROGRAMMER: Jelson Low
 * CHANGE-NO:
 * TASK-NO:
 * DATE CREATED: Dec 21, 2008
 * TAG AS:
 * REASON(S):
 * MODIFICATION:
 * </pre>
 */

/**
 * This class handles the back end process of IBPaymentConfirm.
 */
public class IBPaymentConfirmServices extends IBGenericPaymentServices
{
	private static Class c_oClass = IBPaymentConfirmServices.class;

	/**
	 * Class constructor specifying session object.
	 *
	 * @param m_oIBSessionObjects Session object contains all information stored in HTTP session
	 */
	public IBPaymentConfirmServices (IBSessionObjects m_oIBSessionObjects)
	{
		super (m_oIBSessionObjects);
		// TODO Auto-generated constructor stub
	}

	/**
	 *<pre>
	 * To set the payee details.
	 * If amount display is null , set the amount currency as 'RM'.
	 * If the amount is more or less the specified values, create a business exception.
	 * If the minPayment value from service is true, then amount should not be less than minPayment or business exception will be created.
	 * If the maxPayment value from service is true, then amount should not be more than maxPayment or business exception will be created.
	 * Set all required data into beans.
	 *</pre>
	 *
	 * @throws IBGenericException Exception thrown for generic purposes
	 */
	public void executeServices () throws IBGenericException
	{
		String m_sMethodName = "executeServices";
		IBTimer m_oTimer = IBLogger.logBSFNMethodEnteringMessage (c_oClass, m_sMethodName);

		String m_sAmountDisplay = null;
		String m_sAmount = null;
		String m_sRef1Value = null;
		String m_sRef1Display = null;
		String m_sRef2Value = null;
		String m_sRef2Display = null;
		String m_sPaymentType = null;
		String m_sBillAcctNo = null;
		String m_sPayeeCode = null;
		Boolean isCheckDigit = null;
		String m_sCheckDigitIndicator = null;

		List m_oRef1List = null;
		List m_oRef2List = null;

		IBDynaBean m_oBillPaymentViewBean = null;
		IBDynaBean m_oPayeeDetailsBean = null;
		IBDynaBean m_oAccountBean = null;
		IBDynaBean m_oRef1Element = null;
		IBDynaBean m_oRef2Element = null;
		IBDynaBean m_oServiceInfoBean = null;
		boolean isDIGI = false; //Penril Digi

		try
		{
			m_oBillPaymentViewBean = (IBDynaBean) getIBDynaBean ().get (BillPaymentContants.BILL_PAYMENT_VIEW_BEAN);
			m_sPaymentType = (String) m_oBillPaymentViewBean.get (BillPaymentContants.VBEAN_PAYMENT_TYPE);

			m_oPayeeDetailsBean = (IBDynaBean) m_oBillPaymentViewBean.get (BillPaymentContants.PAYEE_DETAILS_VIEW_BEAN);

			m_sAmount = (String) getIBDynaBean ().get (BillPaymentContants.FBEAN_AMOUNT);
			m_sAmountDisplay = (String) m_oBillPaymentViewBean.get (BillPaymentContants.VBEAN_AMOUNT_DISPLAY);
			m_sBillAcctNo = (String) getIBDynaBean().get(BillPaymentContants.FBEAN_BILL_ACCOUNT_NO);
			m_sPayeeCode = (String) m_oPayeeDetailsBean.get(BillPaymentContants.VBEAN_PAYEE_CODE);
			m_sCheckDigitIndicator = (String) m_oPayeeDetailsBean.get(BillPaymentContants.VBEAN_CHECK_DIGIT_INDI);
			
			if (DataValidator.isEmptyString (m_sAmountDisplay))
			{
				m_sAmountDisplay = FormatterUtils.formatMoneyDisplay (m_sAmount, null, true);
			}

			
			if (Double.parseDouble (m_sAmount) <= 0 || Double.parseDouble (m_sAmount) > 999999.99)
			{
				throw IBErrorHandler.createBusinessException (IBBusinessException.BILL_PAYMENT, "error.invalid.amount");
			}

			if ((Boolean) m_oPayeeDetailsBean.get (BillPaymentContants.VBPAYEE_MIN_PAYMENT))
			{
				String min = FormatterUtils.formatMoneyDisplay((String) m_oPayeeDetailsBean.get (BillPaymentContants.VBPAYEE_MIN_PAYMENT_AMOUNT),"",false);
				if (Double.parseDouble (m_sAmount) < Double.parseDouble
						((String) m_oPayeeDetailsBean.get (BillPaymentContants.VBPAYEE_MIN_PAYMENT_AMOUNT)))
				{
					throw IBErrorHandler.createBusinessException (IBBusinessException.BILL_PAYMENT, "error.invalid.min.amount",
							new String[] {min});
				}
			}

			if ((Boolean) m_oPayeeDetailsBean.get (BillPaymentContants.VBPAYEE_MAX_PAYMENT))
			{
				String max = FormatterUtils.formatMoneyDisplay((String) m_oPayeeDetailsBean.get (BillPaymentContants.VBPAYEE_MAX_PAYMENT_AMOUNT),"",false);
				if (Double.parseDouble (m_sAmount) > Double.parseDouble
						((String) m_oPayeeDetailsBean.get (BillPaymentContants.VBPAYEE_MAX_PAYMENT_AMOUNT)))
				{

					throw IBErrorHandler.createBusinessException (IBBusinessException.BILL_PAYMENT, "error.invalid.max.amount",
							new String[] {max});
				}
			}
			//Penril Digi
			String SHORTNAME = "";
			String contactNo = (String)getIBDynaBean ().get(BillPaymentContants.FBEAN_BILL_REF1_NO);
			
			SHORTNAME = (String)m_oPayeeDetailsBean.get(BillPaymentContants.VBPAYEE_SHORT_NAME);
			if(SHORTNAME.equalsIgnoreCase("DIGIKL"))
			{
				isDIGI=true;
				m_sCheckDigitIndicator = "No";
			}
			//end penril
			if(CommonConstants.isTrue (m_sCheckDigitIndicator))
			{
				if(!DataValidator.isEmptyString(m_sBillAcctNo))
				{
					try
					{
						isCheckDigit = BillPaymentDBUtils.BillerCheckDigit(this, m_sBillAcctNo, m_sPayeeCode);
						if(!isCheckDigit)
						{
							throw IBErrorHandler.createBusinessException (IBBusinessException.BILL_PAYMENT, "invalid.bill.no");
						}
					}
					catch (Exception e)
					{
						throw IBErrorHandler.createBusinessException (IBBusinessException.BILL_PAYMENT, "invalid.bill.no");
					}
					
				}
			}

			if (BillPaymentContants.REF1_SELECTION.equalsIgnoreCase(
					(String)m_oPayeeDetailsBean.get (BillPaymentContants.VBPAYEE_BILL_REF1_TYPE))){

				m_oRef1List = (List)m_oBillPaymentViewBean.get(BillPaymentContants.VBEAN_REF1_LIST);

				for(int i=0; i<m_oRef1List.size();i++){
					m_oRef1Element = (IBDynaBean)m_oRef1List.get(i);
					m_sRef1Value = (String)m_oRef1Element.get(BillPaymentContants.VB_REF_REF_VALUE);
					if(m_sRef1Value.equalsIgnoreCase((String)getIBDynaBean ().get(BillPaymentContants.FBEAN_BILL_REF1_NO))){
						m_sRef1Display = (String)m_oRef1Element.get(BillPaymentContants.VB_REF_DISPLAY);
					}
				}
			}

			if (BillPaymentContants.REF2_SELECTION.equalsIgnoreCase(
					(String)m_oPayeeDetailsBean.get (BillPaymentContants.VBPAYEE_BILL_REF2_TYPE))){

				m_oRef2List = (List)m_oBillPaymentViewBean.get(BillPaymentContants.VBEAN_REF2_LIST);

				for(int i=0; i<m_oRef2List.size();i++){
					m_oRef2Element = (IBDynaBean)m_oRef2List.get(i);
					m_sRef2Value = (String)m_oRef2Element.get(BillPaymentContants.VB_REF_REF_VALUE);
					if(m_sRef2Value.equalsIgnoreCase((String)getIBDynaBean ().get(BillPaymentContants.FBEAN_BILL_REF2_NO))){
						m_sRef2Display = (String)m_oRef2Element.get(BillPaymentContants.VB_REF_DISPLAY);
					}
				}
			}

//			 If contactNo is null or empty
			if(DataValidator.isEmptyString((String)getIBDynaBean ().get (BillPaymentContants.FBEAN_CONTACT_NO))){
				m_oBillPaymentViewBean.set (BillPaymentContants.VBEAN_CONTACT_NO, IBLoadProperty.getValue("dummyBillPaymentContactNo"));
			}
			else
			{
				m_oBillPaymentViewBean.set (BillPaymentContants.VBEAN_CONTACT_NO,
						(String)getIBDynaBean ().get (BillPaymentContants.FBEAN_CONTACT_NO));
			}

			m_oServiceInfoBean = (IBDynaBean)m_oBillPaymentViewBean.get (ServiceInfo.SERVICE_INFO_BEAN);
			
			//Pixakarft Bank Negara Changes 30th Mar 2013 start
			if (((Boolean) m_oServiceInfoBean.get (ServiceInfo.BEAN_ATT_TAC_REQUIRED)).booleanValue ())
			{
				IBDynaBean m_oSMSViewBean = (IBDynaBean) getIBSessionObjects().getHttpSessionAttrObject(CommonConstants.SMS_VIEW_BEAN);
				m_oSMSViewBean.set(CommonConstants.AMOUNT, m_sAmountDisplay);
				if(!DataValidator.isEmptyString(SHORTNAME)){
					m_oSMSViewBean.set(CommonConstants.BENE_NAME, SHORTNAME.length()>14?SHORTNAME.substring(0, 14):SHORTNAME);
				}
				getIBSessionObjects().setHttpSessionAttrObject(CommonConstants.SMS_VIEW_BEAN, m_oSMSViewBean);
			}
			//Pixakarft Bank Negara Changes 30th Mar 2013 start
			
			if (m_oServiceInfoBean != null &&
					((Boolean)m_oServiceInfoBean.get (ServiceInfo.BEAN_ATT_FUTURE_TRANSACTION_FLAG)).booleanValue ())
			{
				IBGenericSIServices m_oGenericSIServices = new IBGenericSIServices (getIBSessionObjects ());
				m_oGenericSIServices.setIBDynaBean (getIBDynaBean ());
				m_oGenericSIServices.confirmSIInput (m_oBillPaymentViewBean);
			}
			
			//Penril Digi
			if(isDIGI)
			{
				int length =0;
				boolean isNumeric = false;
				String checkPrefix ="";
				String checkBillAccNo = "";
				
				isNumeric = isNumeric(m_sBillAcctNo);
				length = m_sBillAcctNo.length();
				checkBillAccNo = m_sBillAcctNo.substring(0, 1);
				checkPrefix = contactNo.substring(0, 1);
				
				if(isNumeric)
				{
					//valid
					for (int j = 0; j < m_sBillAcctNo.length(); j++)
					{
						int code = m_sBillAcctNo.charAt(j);

						if (!(code >= 48 && code <= 57))
						{
							//error
							throw IBErrorHandler.createBusinessException(IBBusinessException.BILL_PAYMENT, BillPaymentContants.ERR_DIGI_BILL_ACC_NO);
						}
						
					}
				}
				else
				{
					throw IBErrorHandler.createBusinessException(IBBusinessException.BILL_PAYMENT, BillPaymentContants.ERR_DIGI_BILL_ACC_NO);
				}
				if(contactNo.length() < 11)
				{
					throw IBErrorHandler.createBusinessException(IBBusinessException.BILL_PAYMENT, BillPaymentContants.ERR_DIGI_MOBILE_NO);
				}
				
				if(!checkPrefix.equalsIgnoreCase("6"))
				{
					throw IBErrorHandler.createBusinessException(IBBusinessException.BILL_PAYMENT, BillPaymentContants.ERR_DIGI_PREFIX);
				}
				else
				{
					//valid
				}
				if(length != 13)
				{
					throw IBErrorHandler.createBusinessException(IBBusinessException.BILL_PAYMENT, BillPaymentContants.ERR_DIGI_BILL_ACC_LENGTH);
				}
				else
				{
					//valid
				}
				if(checkBillAccNo.equalsIgnoreCase("1"))
				{
					//valid
				}
				if(checkBillAccNo.equalsIgnoreCase("2"))
				{
					//valid
				}
				else if (!checkBillAccNo.equalsIgnoreCase("1") && !checkBillAccNo.equalsIgnoreCase("2"))
				{
						System.out.println(m_sBillAcctNo.substring(0, 1));
						throw IBErrorHandler.createBusinessException(IBBusinessException.BILL_PAYMENT, BillPaymentContants.ERR_DIGI_BILL_ACC_NO);
				}
			}
			//end Penril Digi
			
			//GST
			String m_sChargesAmount = null;
			String m_sGSTCharges = null;
			String m_sChargesIndicator = (String) m_oPayeeDetailsBean.get(BillPaymentContants.VBEAN_ISCHARGES);
			String gstChargesIndicator = (String) m_oPayeeDetailsBean.get(BillPaymentContants.VBPAYEE_NOTE3_REQUIRED);
			String gstChargesWithoutRounding = 	"";
			
			if(CommonConstants.isTrue (m_sChargesIndicator)){
				m_sChargesAmount = (String) m_oPayeeDetailsBean.get(BillPaymentContants.VBEAN_CHARGES_AMOUNT);
				m_sChargesAmount = DataValidator.isEmptyString(m_sChargesAmount)?"0.00":m_sChargesAmount;
			
				if(!DataValidator.isEmptyString(gstChargesIndicator)){
					if(gstChargesIndicator.equalsIgnoreCase(BillPaymentContants.GST_CHANNEL_ALL) || gstChargesIndicator.equalsIgnoreCase(BillPaymentContants.GST_CHANNEL_CIB)){
						IBGSTContent gstContent = HibernateUtils.getGstContentByChargesCode(IBLoadProperty.getValue(GSTUtils.BILL_CHARGES_CODE));
						if(gstContent!=null){
							String gstChargesRate = IBUtils.getGSTRate(this, IBLoadProperty.getValue(GSTUtils.BILL_CHARGES_CODE));
							m_sGSTCharges = GSTUtils.gstAmount2Dec(m_sChargesAmount, gstChargesRate);
							gstChargesWithoutRounding = GSTUtils.gstCalcCharges(m_sChargesAmount, gstChargesRate);
						}
					} 
				}
			}
			
			m_oBillPaymentViewBean.set (BillPaymentContants.VBEAN_CHARGES, m_sChargesAmount);
			m_oBillPaymentViewBean.set (BillPaymentContants.VBEAN_CHARGES_DISPLAY, DataValidator.isEmptyString(m_sChargesAmount)?"-":!(Double.valueOf(m_sChargesAmount)>0)?"-":FormatterUtils.formatMoneyDisplay (m_sChargesAmount, null, true));
			m_oBillPaymentViewBean.set (BillPaymentContants.VBEAN_GST_CHARGES, m_sGSTCharges);
			m_oBillPaymentViewBean.set (BillPaymentContants.VBEAN_GST_CHARGES_DISPLAY, DataValidator.isEmptyString(m_sGSTCharges)? "-":("0.00".equals(m_sGSTCharges) ||"0.0".equals(m_sGSTCharges)||"0".equals(m_sGSTCharges)?"-":FormatterUtils.formatMoneyDisplay (m_sGSTCharges, null, true)));
			m_oBillPaymentViewBean.set (BillPaymentContants.VBEAN_CHARGES_INDI, m_sChargesIndicator);
			m_oBillPaymentViewBean.set(BillPaymentContants.GST_CHARGES_WITHOUT_ROUNDING, gstChargesWithoutRounding);

			Map m_oFromAccountsMap = (Map)m_oBillPaymentViewBean.get (BillPaymentContants.VBEAN_ACCOUNT_MAP);
			m_oAccountBean = (IBDynaBean) m_oFromAccountsMap.get ((String) getIBDynaBean ().get
					(BillPaymentContants.FBEAN_ACCOUNT_INDEX_NO));
			m_oBillPaymentViewBean.set (BillPaymentContants.VBEAN_ACCOUNT_NO, m_oAccountBean.get (CommonConstants.ACCOUNT_NO));
			m_oBillPaymentViewBean.set (BillPaymentContants.VBEAN_ACCOUNT_DISPLAY,
					m_oAccountBean.get (CommonConstants.ACCOUNT_NICKNAME)+"-"+m_oAccountBean.get (CommonConstants.ACCOUNT_NO));
			m_oBillPaymentViewBean.set (BillPaymentContants.VBEAN_AMOUNT_DISPLAY, m_sAmountDisplay);
			m_oBillPaymentViewBean.set (BillPaymentContants.VBEAN_REF1_DISPLAY, m_sRef1Display);
			m_oBillPaymentViewBean.set (BillPaymentContants.VBEAN_REF2_DISPLAY, m_sRef2Display);
			
			//SMS Notification START
			m_oBillPaymentViewBean = SMSServices.setupConfirmViewBean(this, m_sAmount, getIBDynaBean(), m_oBillPaymentViewBean, m_oServiceInfoBean);
			// SMS Notification END

			getIBDynaBean ().set (BillPaymentContants.BILL_PAYMENT_VIEW_BEAN, m_oBillPaymentViewBean);

		}
		catch (Exception e)
		{
			if (e instanceof IBGenericException)
			{
				throw (IBGenericException) e;
			}

			throw IBErrorHandler.createServiceException(
					IBServiceException.GENERAL_SERVICE_ERROR, true,
					new String[] {CommonErrorCode.GENERIC_CODE, "", "", "", IBErrorHandler.generateErrorMessage(e)}, c_oClass);
		}
		IBLogger.logBSFNMethodLeavingMessage (c_oClass, m_sMethodName, m_oTimer);
	}
	public static boolean isNumeric(String s) {
	    try { 
	        double d = Double.parseDouble(s);
	    } catch(NumberFormatException e) { 
	        return false; 
	    }
	    // only got here if we didn't return false
	    return true;
	}

}
