/**
 * 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 static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.LinkedHashMap;
import java.util.Map;

import my.com.kfh.enterprise.services.GenericBVDataServicesImpl;
import my.com.kfh.enterprise.services.GenericESBServicesImpl;
import my.com.kfh.enterprise.services.IBEnterpriseServices;
import my.com.kfh.enterprise.services.IBEnterpriseServicesWorkspace;
import my.com.kfh.enterprise.services.IBUtils;
import my.com.kfh.enterprise.services.IBUtilsOnlineAcc;
import my.com.kfh.enterprise.services.common.CommonConstants;
import my.com.kfh.enterprise.services.ib101_access.AccessConstants;
import my.com.kfh.enterprise.services.ib101_access.IBAccessDBUtils;
import my.com.kfh.enterprise.services.ib105_billpayment.constant.BillPaymentContants;
import my.com.kfh.enterprise.services.ib112_si.IBGenericSIServices;
import my.com.kfh.enterprise.services.ib112_si.SIConstants;
import my.com.kfh.enterprise.services.ib112_si.SIDBUtils;
import my.com.kfh.enterprise.services.ib112_si.SI_PAYMENT_MODE;
import my.com.kfh.enterprise.services.ib116_online_acc.constant.OnlineAccConstants;
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.esb.response.ESBAccountEnquiryTC100Bean;
import my.com.kfh.esb.response.ESBBillPaymentBean;
import my.com.kfh.esb.response.ESBTransferGLtoCASABean;
import my.com.kfh.esb.response.ESBTransferToGLBean;
import my.com.kfh.hibernate.utils.HibernateOnlineAccUtils;
import my.com.kfh.integration.OnlineAccPromoBean;
import my.com.kfh.sms.services.SMSServices;
import my.com.kfh.web.utils.BVI_DateTime;
import my.com.kfh.web.utils.DataValidator;
import my.com.kfh.web.utils.DateTimeUtils;
import my.com.kfh.web.utils.FormatterUtils;
import my.com.kfh.web.utils.GSTUtils;
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.ResourcesUtils;
import my.com.kfh.web.utils.constant.ESBConstants;
import my.com.kfh.web.utils.constant.LogTables;
import my.com.kfh.web.utils.constant.ServiceInfo;

import com.broadvision.data.client.Content;
import com.broadvision.data.client.DataManager;
import com.broadvision.data.common.TableData;

/**
 * <pre>
 * PROGRAMMER: Ang Wei Cheng
 * CHANGE-NO:
 * TASK-NO:
 * DATE CREATED: Apr 7, 2010
 * TAG AS:
 * REASON(S):
 * MODIFICATION:
 * </pre>
 */

/**
 * <Class description>
 */
public class IBPaymentSIResultsServices
{
	private static Class c_oClass = IBPaymentSIResultsServices.class;

	@SuppressWarnings("unchecked")
	public static void executeTransaction (String siId) throws IBGenericException
	{
		String m_sMethodName = "executeTransaction";
		IBTimer m_oTimer = IBLogger.logBSFNMethodEnteringMessage (c_oClass, m_sMethodName, String.class.getName ());

		String m_sSICharges = "0";
		String m_sSIChargesRefNo = null;
		boolean m_boSIChargeStatus = false;
		String m_sSIGSTCharges = "0";
		String m_sSIGSTChargesRefNo = null;
		boolean m_boSIGSTChargeStatus = false;
		String m_sSIGSTChargesRevertRefNo = null;
		boolean m_boSIGSTChargeRevertStatus = false;
		double m_dAvailableBal = 0.0;
		double m_dTransferAmount = 0.0;
		double m_dTotalAmount = 0.0;
		double m_dSICharges = 0.0;
		String m_sSIChargeResponseCode = null;
		boolean m_boIsFundSufficient = true;
		String m_sRevertReference = null;
		boolean m_boRevertStatus = false;
		
		String p_sProdSubCode = "";
		String m_sBalance = "";
		String m_sPhoenixRc = null;
		String m_sEPayRc 	= null;
		String m_sRevertRc 	= null;
		String m_sMerchantAccNo = null;
		String m_sMerchantId = null;
		String m_sOperatorId = null;
		String m_sTerminalId = null;
		String m_sMercRespCode = null;
		String m_sMercRespMsg = null;
		String m_sTransTraceId = null;

		String m_sTransStatusMsg="";
		String m_sStatus = ResourcesUtils.getUnsuccessful ();
		String m_sReason="";

		String m_sEPayReference = null;
		String m_sPhoenixReference="";
		boolean m_boIsResultSuccessful=false;
		Map<String, String> m_oReceiptMap = new LinkedHashMap<String, String> ();
		ESBBillPaymentBean m_oESBPay = new ESBBillPaymentBean();
		BVI_DateTime m_oDate = null;

		String m_sEsbDescription = null;

		String m_sChargeGLAccount = "";
		String m_sSIChargesRevertRefNo = null;
		boolean m_boSIChargeRevertStatus = false;
		
		//Other Payees
		String m_sChargesIndicator = null;
		String m_sChargesAmount = null;
		String m_sChargesAcctCode = null;
		String m_sTrnxPaymentMode = null;
		String m_sMerchantAcctCode = null;
		String SIGSTCharges = "0";
		String gstCharges = "0";
		double dCharges = 0;
		double dGstCharges = 0;

		//#-- added by pixa 20121017 start
		OnlineAccPromoBean onlineAccSIPromoBean=null;	
		OnlineAccPromoBean onlineAccTrnxPromoBean=null;	
		//#-- added by pixa 20121017 end 
		try
		{
			m_oDate = new BVI_DateTime ();
			String m_sDate = DateTimeUtils.formatDayMonthYear (m_oDate);
			String m_sTime = m_oDate.getTime ();
			String gstGLAccountCode		= IBLoadProperty.getValue("gst.gl.account.code");


			//mock up
			IBSessionObjects m_oSessionObj = mock(IBSessionObjects.class);
			when(m_oSessionObj.getDataManager()).thenReturn(new DataManager());
			when(m_oSessionObj.getRemoteIPAddress ()).thenReturn("127.0.0.1");

			TableData table = SIDBUtils.getSICurrentTransId(new IBEnterpriseServicesWorkspace(m_oSessionObj), siId);
			String currentTrnxId  = table.getStringValue(0, LogTables.IB_SI.CURRENT_TRNX_ID.toString ());
			String siPaymentModeCode = table.getStringValue(0, LogTables.IB_SI.PAYMENT_MODE.toString ());
			String trnxTypeDisplay = table.getStringValue(0, LogTables.IB_SI.TRNX_TYPE.toString ());
			String m_sSIServiceCode = table.getStringValue (0, LogTables.IB_SI.SERVICE_CODE.toString ());

			m_sEsbDescription = ESBConstants.BILL_PAYMENT;
			m_sEsbDescription = IBGenericSIServices.getESBDescription (m_sEsbDescription, siPaymentModeCode);
			String m_sEsbDescriptionCharges = m_sEsbDescription+" "+CommonConstants.CHARGES_LABEL;
			String m_sEsbDescriptionRevertCharges = m_sEsbDescription+ " "+CommonConstants.CHARGES_LABEL+CommonConstants.REVERT_LABEL;

			IBEnterpriseServices p_oEnterpriseServices = new IBEnterpriseServicesWorkspace(m_oSessionObj);

			//get user id from trnx
			table = BillPaymentDBUtils.getTransactionByTrnxId(p_oEnterpriseServices, currentTrnxId);
			String userId = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.USER_ID.toString ());

			com.broadvision.visitor.client.Visitor visitor = mock(com.broadvision.visitor.client.Visitor.class);
			when(visitor.getId()).thenReturn(Long.parseLong(userId));
			when(m_oSessionObj.getVisitor()).thenReturn(visitor);

			//get various data from transaction
			String m_sFromAccount = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.FROM_ACC_NO.toString ());
			String m_sToAccount = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.BILL_ACC_NO.toString ());
			String m_sAmount = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.AMOUNT.toString ());
			String fromCurrency = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.FROM_CURRENCY.toString ());
			String toCurrency = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.TO_CURRENCY.toString ());
			String m_sCharges = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.CHARGES_AMOUNT.toString ());
			gstCharges = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.GST_CHARGES.toString ());
			String merchant = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.MERCHANT.toString ());
			String m_sBillAccountNo = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.BILL_ACC_NO.toString ());
			String m_sAccountNo = m_sFromAccount;
			String m_sProductCode = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.PRODUCT_CODE.toString ());
			String p_sInfo2 = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.INFO2.toString ());
			String p_sInfo3 = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.INFO3.toString ());
			String desc = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.OTHER1.toString ());
			String payeeName = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.PAYEE_NAME.toString ());
			String details = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.BILL_ACC_NO.toString ());
			
			//charges convertion
			if(!DataValidator.isEmptyString(m_sCharges))
				dCharges = Double.parseDouble(m_sCharges);
			
			if(!DataValidator.isEmptyString(gstCharges))
				dGstCharges = Double.parseDouble(gstCharges);
				
			//get user rim no
			String rimNo = IBAccessDBUtils.getRimNoByUserId(p_oEnterpriseServices, userId);
			when(m_oSessionObj.getHttpSessionAttrObject (AccessConstants.RIM_NO)).thenReturn(rimNo);

			//no store payment type? just find in trnxtype display, search for open or favourite, no prepaid in si
			String m_sTrnxID 	= IBUtils.getTransactionId (new DataManager ());
			String m_sTrnxType = trnxTypeDisplay;
			
			//Penril Digi
			String payeCode = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.PAYEE_CODE.toString ());
			String m_sBillAcctNo = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.BILL_ACC_NO.toString ());
			String contactNo = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.INFO2.toString ());
			
			if(payeCode.equalsIgnoreCase("DIGIKL"))
			{
				boolean isBillAcctNoValid = false;
				boolean isContactNoValid = false;
				String checkPrefix ="";
				String checkBillAccNo = "";
				int length =0;
				
				checkBillAccNo = m_sBillAcctNo.substring(0, 1);
				checkPrefix = contactNo.substring(0, 1);
				length = m_sBillAccountNo.length();
				
				if(isNumeric(m_sBillAcctNo))
				{
					//if(checkBillAccNo == "1" || checkBillAccNo == "2")
					if (!checkBillAccNo.equalsIgnoreCase("1") && !checkBillAccNo.equalsIgnoreCase("2")) 
					{
						//error
						isBillAcctNoValid = false;
					}
					else
					{
						//valid
						if(length != 13)
						{
							isBillAcctNoValid = false;
						}
						else
						{
							//error
							isBillAcctNoValid = true;
						}
					}
					
				}
				else
				{
					//error
					isBillAcctNoValid = false;
				}
				
				if(isNumeric(contactNo))
				{
					if(contactNo.length() >= 11)
					{
						if(checkPrefix.equalsIgnoreCase("6"))
						{
							isContactNoValid = true;
						}
						else
						{
							isContactNoValid = false;
						}
					}
					else
					{
						isContactNoValid = false;
					}
					
				}
				else
				{
					isContactNoValid = false;
				}
				if((isBillAcctNoValid == true) && (isContactNoValid == true))
				{
					m_sStatus 	= ResourcesUtils.getSuccessful ();
				}
				else if ((isBillAcctNoValid == true) && (isContactNoValid == false))
				{
					isContactNoValid = false;
					m_boIsFundSufficient = false;
					m_boIsResultSuccessful = false;
					m_sStatus = ResourcesUtils.getUnsuccessful ();
					m_sReason = "Invalid Mobile No";
				}
				else if ((isBillAcctNoValid == false) && (isContactNoValid == true))
				{
					isContactNoValid = false;
					m_boIsFundSufficient = false;
					m_boIsResultSuccessful = false;
					m_sStatus = ResourcesUtils.getUnsuccessful ();
					m_sReason = "Invalid Bill Account No";
				}
				else if ((isBillAcctNoValid == false) && (isContactNoValid == false))
				{
					isContactNoValid = false;
					m_boIsFundSufficient = false;
					m_boIsResultSuccessful = false;
					m_sStatus = ResourcesUtils.getUnsuccessful ();
					m_sReason = "Invalid Bill Account No & Mobile No";
				}
				
			}
			//end Penril Digi
			
			Content m_oPayeeContent = new GenericBVDataServicesImpl (m_oSessionObj).getContentListByKey (
					table.getStringValue(0, LogTables.IB_BILL_PAYMENT.PAYEE_CODE.toString ()),
					BillPaymentContants.TBL_IB_PAYEE_LIST, IBSessionObjects.SERVICE_NAME_VALUE);

			boolean m_bOnline 	= isTrue (m_oPayeeContent.getStringValue (BillPaymentContants.COL_ONLINE_PAYMENT));

			//check daily limit
			Map m_oSILimitMap = IBGenericSIServices.verifySIDailyLimitByBank (p_oEnterpriseServices, null, null,
					m_sSIServiceCode, m_sAmount, m_oDate.getSimpleDate (), true);

			//Pixakraft Bank Negara changes 25th Mar 2013
			boolean exceedGlobalLimit = IBGenericPaymentServices.exceedGlobalDailyLimit(p_oEnterpriseServices, m_sAmount, m_sSIServiceCode);
			
			if (!((Boolean) m_oSILimitMap.get (SIConstants.TRANS_STATUS)).booleanValue ())
	        {
				m_boIsResultSuccessful = false;
				m_sStatus = ResourcesUtils.getUnsuccessful ();
				m_sReason = ResourcesUtils.getBusinessExceptionErrorMessage (IBBusinessException.SI,
	            		SIConstants.ERR_BANK_MAX_LIMIT,
	            		new String [] { FormatterUtils.formatMoneyDisplay ( (String)m_oSILimitMap.get (SIConstants.MAX_LIMIT),
	            				fromCurrency, true) });
	        }
			//Pixakraft Bank Negara changes 25th Mar 2013
			else if(exceedGlobalLimit){
				m_boIsResultSuccessful = false;
				m_sStatus = ResourcesUtils.getUnsuccessful ();
				String globalDailyLimit = IBPaymentUtils.getGlobalLimit(BillPaymentContants.GLOBAL_BILLPAYMENT_DAILY_LIMIT);
				m_sReason = ResourcesUtils.getBusinessExceptionErrorMessage (IBBusinessException.SI, SIConstants.ERR_BANK_GLOBAL_LIMIT,
	            		new String [] { FormatterUtils.formatMoneyDisplay ( globalDailyLimit, fromCurrency, true) });
			}
			else
			{
				String p_sContactNo="";
				//only M1 need contact No, M2 no need
				if (BillPaymentContants.isMobilityOne(merchant))
				{
					//no hard code contact no for M2
					if (BillPaymentContants.isMobilityTwo(desc))
					{
						p_sProdSubCode = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.SUB_PRODUCT_CODE.toString ());
						p_sInfo2 = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.INFO2.toString ());
						p_sInfo3 = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.INFO3.toString ());

					}
					else
					{
						p_sProdSubCode = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.SUB_PRODUCT_CODE.toString ());
						p_sContactNo =  table.getStringValue(0, LogTables.IB_BILL_PAYMENT.CONTACT_NO.toString ());
						p_sInfo2 = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.INFO2.toString ());
						p_sInfo3 = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.INFO3.toString ());

					}
				}
				if(!DataValidator.isEmptyString(m_sBillAccountNo)){
    				details = m_sBillAccountNo;
    			} else{
    				details = "-";
    			}
    			if(!DataValidator.isEmptyString(p_sInfo2)){
    					details = details + "," + p_sInfo2;
    			}
    			
				GenericESBServicesImpl m_oEsbServices = new GenericESBServicesImpl (m_oSessionObj);

				ESBAccountEnquiryTC100Bean m_oTCEnquiryBean = m_oEsbServices.getAccountDetailsTC100 (m_sFromAccount);
				if (!DataValidator.isEmptyString (m_oTCEnquiryBean.getAvailable_Bal ()))
				{
					m_dAvailableBal = Double.parseDouble (m_oTCEnquiryBean.getAvailable_Bal ());
				}

    			if (SI_PAYMENT_MODE.RECURRING_PAYMENT.getCode ().equals (siPaymentModeCode))
				{
    				m_dSICharges = IBGenericSIServices.getSICharges (ServiceInfo.SI_FEE_BILL_PAYMENT);
	    			m_sSICharges = String.valueOf (m_dSICharges);

					//#-- added by pixa 20121017 start --remember to include import at top
	    			onlineAccSIPromoBean = IBUtilsOnlineAcc.getChargesIfIsOnlineAccount(m_oEsbServices,m_sFromAccount, OnlineAccConstants.SI);
	            	if(onlineAccSIPromoBean !=null){
	            		m_sSICharges = onlineAccSIPromoBean.getPromotionCharges();
	            		m_dSICharges = Double.valueOf(m_sSICharges);
	            	}
	            	//#-- added by pixa 20121017 end --
	            	
					if (m_dSICharges > 0)
					{
						if (m_dAvailableBal > m_dSICharges)
						{
							m_sChargeGLAccount = IBGenericSIServices.getSICollectionAccountNo (m_sFromAccount);

							ESBTransferToGLBean m_oESBTransferToGLBean = m_oEsbServices.chargesTransfer (m_sFromAccount,
									m_sChargeGLAccount, m_sSICharges, ESBConstants.SI_CHARGES, null, "", payeeName, "", details);

							m_sSIChargeResponseCode = m_oESBTransferToGLBean.getResponseCode ();
							if (ESBConstants.IB_SUCCESS_RC.equalsIgnoreCase (m_sSIChargeResponseCode))
							{
								m_boSIChargeStatus = true;
								m_sSIChargesRefNo = m_oESBTransferToGLBean.getReferenceNo ();
								
								String SIGSTChargesRate = IBUtils.getGSTRate(new IBEnterpriseServicesWorkspace(m_oSessionObj), IBLoadProperty.getValue(GSTUtils.SI_CHARGES_CODE));
	    						SIGSTCharges = GSTUtils.gstAmount2Dec(m_sSICharges, SIGSTChargesRate);
	    						
	    						ESBTransferToGLBean m_oGSTESBTransferToGLBean = new ESBTransferToGLBean();
	    						boolean isGstCharges = false;
	    						if(DataValidator.isEmptyString(SIGSTCharges) || SIGSTCharges.equals("0.00") || SIGSTCharges.equals("0.0") || SIGSTCharges.equals("0"))
	    						{
	    							m_oGSTESBTransferToGLBean.setResponseCode(ESBConstants.IB_SUCCESS_RC);
	    							isGstCharges = false;
	    						}
	    						else
	    						{
	    							m_oGSTESBTransferToGLBean = m_oEsbServices.chargesTransfer (m_sFromAccount,
	    								ResourcesUtils.getGLAccountResource ("gl.account.gst"), SIGSTCharges, ESBConstants.SI_GST_CHARGES, null, "", payeeName, "", details);
	    						
	    							isGstCharges = true;
	    						}
	    						
	    						String m_sSIGSTChargeResponseCode = m_oGSTESBTransferToGLBean.getResponseCode ();
		    					if (ESBConstants.IB_SUCCESS_RC.equalsIgnoreCase (m_sSIGSTChargeResponseCode)){
		    						if(isGstCharges)
		    						{
		    						m_boSIGSTChargeStatus = true;
		    						m_sSIGSTChargesRefNo = m_oGSTESBTransferToGLBean.getReferenceNo ();
		    						}
		    						else
		    						{
		    							m_boSIGSTChargeStatus = false;
		    						}
		    					}else{
		    						m_boIsFundSufficient = false;
									m_boIsResultSuccessful = false;
									m_sStatus = ResourcesUtils.getUnsuccessful ();
									m_sReason = m_oGSTESBTransferToGLBean.getErrorMessage ();
		    						
		    						ESBTransferGLtoCASABean m_oESBTransferGLtoCASABean = m_oEsbServices.transferGLtoCASA(m_sChargeGLAccount, m_sFromAccount, m_sSICharges, ESBConstants.SI_CHARGES_REVERT, null, payeeName, details);
		    						
		    						String m_sSIGSTRevertChargeResponseCode = m_oESBTransferGLtoCASABean.getResponseCode ();
		    						if (ESBConstants.IB_SUCCESS_RC.equalsIgnoreCase (m_sSIGSTRevertChargeResponseCode)){
		    							m_boSIChargeRevertStatus = true;
		    							m_sSIChargesRevertRefNo = m_oESBTransferGLtoCASABean.getReferenceNo();
		    						}
		    					}
							}
							else
							{
								m_boIsFundSufficient = false;
								m_boIsResultSuccessful = false;
								m_sStatus = ResourcesUtils.getUnsuccessful ();
								m_sReason = m_oESBTransferToGLBean.getErrorMessage ();
							}
						}
						else
						{
							m_boIsFundSufficient = false;
							m_boIsResultSuccessful = false;
							m_sStatus = ResourcesUtils.getUnsuccessful ();
							m_sReason = ResourcesUtils.getApplicationResourceMessage (SIConstants.RESOURCES_INSUFFICIENT_FUND);
						}
					}
				}
    			if (m_boIsFundSufficient)
    			{
					m_dTransferAmount = Double.parseDouble (m_sAmount);
					m_dTotalAmount = m_dTransferAmount + m_dSICharges + dCharges + dGstCharges + Double.parseDouble(m_sSIGSTCharges);

					if(m_dAvailableBal < m_dTotalAmount)
					{
						m_boIsFundSufficient = false;
						m_boIsResultSuccessful = false;
						m_sStatus = ResourcesUtils.getUnsuccessful ();
						m_sTransStatusMsg = ResourcesUtils.getApplicationResourceMessage (SIConstants.RESOURCES_INSUFFICIENT_FUND);
						m_sReason = m_sTransStatusMsg;
					}
    			}

    			if (m_boIsFundSufficient)
				{
					if(BillPaymentContants.isEPay(merchant))
					{
						m_oESBPay =	m_oEsbServices.ePayPayment (m_sTrnxID, m_sAccountNo, m_sAmount, m_sEsbDescription, null,
								m_sProductCode, m_sBillAccountNo, m_bOnline, m_oDate.getJavaDate (), "", payeeName, details);
					}
					else if (BillPaymentContants.isMobilityOne(merchant))
					{
						if(BillPaymentContants.isMobilityTwo(desc))
						{
							m_oESBPay =	m_oEsbServices.m1Payment (m_sTrnxID, m_sAccountNo, m_sAmount, m_sEsbDescription, null,
		                                                            //BVMC bill account no field, ref1 field, ref2 field
									m_sProductCode, p_sProdSubCode, m_sBillAccountNo, p_sInfo2, p_sInfo3, "", "", "", payeeName, details);
						}
						else
						{
							m_oESBPay =	m_oEsbServices.m1Payment (m_sTrnxID, m_sAccountNo, m_sAmount, m_sEsbDescription, null,
									m_sProductCode, p_sProdSubCode, p_sContactNo, m_sBillAccountNo, p_sInfo2, p_sInfo3, "", "", payeeName, details);
							
						}
					}
					else
					{
						m_sChargesIndicator = (String) m_oPayeeContent.getStringValue (BillPaymentContants.COL_ISCHARGES);
						m_sChargesAmount = (String) m_oPayeeContent.getStringValue (BillPaymentContants.COL_CHARGES_AMOUNT);
						m_sChargesAcctCode = (String) m_oPayeeContent.getStringValue (BillPaymentContants.COL_CHARGES_ACCT);
						m_sTrnxPaymentMode = (String) m_oPayeeContent.getStringValue (BillPaymentContants.COL_PAYMENT_MODE);
						m_sMerchantAcctCode = (String) m_oPayeeContent.getStringValue (BillPaymentContants.COL_MERCHANT_COLLECTION_ACCT_NO);
						
						
						//changes indicator = "YES" - apply charges | "NO" - No charges
						if(CommonConstants.isTrue (m_sChargesIndicator)&&!DataValidator.isEmptyString(m_sChargesAmount) && Double.valueOf(m_sChargesAmount)>0)
						{
							
							//#-- added by pixa 20121017 start --remember to include import at top
							onlineAccTrnxPromoBean = IBUtilsOnlineAcc.getChargesIfIsOnlineAccount(m_oEsbServices,m_sAccountNo, OnlineAccConstants.BILL);
			            	if(onlineAccTrnxPromoBean !=null){
			            		m_sChargesAmount = onlineAccTrnxPromoBean.getPromotionCharges();
			            	}
			            	//#-- added by pixa 20121017 end --
			            	
			            	//charges
							m_oESBPay = m_oEsbServices.CommonBillerPayment(p_oEnterpriseServices, m_sAccountNo, m_sChargesAmount, m_sChargesAcctCode, m_sTrnxPaymentMode, m_sEsbDescriptionCharges, null, "", payeeName, details);
							if(ESBConstants.IB_SUCCESS_RC.equals(m_oESBPay.getResponseCode()))
							{
								String m_sPaymentDescGSTCharges = m_sEsbDescription+" GST Charges";
								String m_sPaymentDescRevertGSTCharges = m_sEsbDescription+" Revert GST Charges";
								ESBBillPaymentBean m_oESBGSTPay = new ESBBillPaymentBean();
								
								String gstChargesRate = IBUtils.getGSTRate(new IBEnterpriseServicesWorkspace(m_oSessionObj), IBLoadProperty.getValue(GSTUtils.BILL_CHARGES_CODE));
								gstCharges = GSTUtils.gstAmount2Dec(m_sChargesAmount, gstChargesRate);
								
								if(!DataValidator.isEmptyString(gstCharges) && !(gstCharges.equals("0.00")||gstCharges.equals("0.0")||gstCharges.equals("0")))
								{
									//GST charges
									m_oESBGSTPay = m_oEsbServices.CommonBillerPayment(p_oEnterpriseServices, m_sAccountNo, gstCharges, gstGLAccountCode, m_sTrnxPaymentMode, m_sPaymentDescGSTCharges, null, "", payeeName, details);
								
									if((!DataValidator.isEmptyString(gstCharges) && ESBConstants.IB_SUCCESS_RC.equals(m_oESBGSTPay.getResponseCode()))
											|| DataValidator.isEmptyString(gstCharges))
									{
										//transfer
										m_oESBPay = m_oEsbServices.CommonBillerPayment(p_oEnterpriseServices, m_sAccountNo, m_sAmount, m_sMerchantAcctCode, m_sTrnxPaymentMode, m_sEsbDescription, null, "", payeeName, details);
	
										if(!ESBConstants.IB_SUCCESS_RC.equals(m_oESBPay.getResponseCode()))
										{
											//Revert charges if fund transfer is fail.
											m_oESBPay = m_oEsbServices.RevertBillerCharges(p_oEnterpriseServices, m_sChargesAcctCode, m_sChargesAmount, m_sAccountNo, m_sEsbDescriptionCharges, null, "", payeeName, details);
											
											//Revert gst charges if fund transfer is fail.
											m_oESBGSTPay = m_oEsbServices.RevertBillerCharges(p_oEnterpriseServices, gstGLAccountCode, gstCharges, m_sAccountNo, m_sPaymentDescRevertGSTCharges, null, "", payeeName, details);
										}
									}
									else{
										//Revert charges if fund transfer is fail.
										if(!DataValidator.isEmptyString(gstCharges))
											m_oESBPay = m_oEsbServices.RevertBillerCharges(p_oEnterpriseServices, m_sChargesAcctCode, m_sChargesAmount, m_sAccountNo, m_sEsbDescriptionCharges, null, "", payeeName, details);
									}
								}
								else
								{
									//transfer
									m_oESBPay = m_oEsbServices.CommonBillerPayment(p_oEnterpriseServices, m_sAccountNo, m_sAmount, m_sMerchantAcctCode, m_sTrnxPaymentMode, m_sEsbDescription, null, "", payeeName, details);

									if(!ESBConstants.IB_SUCCESS_RC.equals(m_oESBPay.getResponseCode()))
									{
										//Revert charges if fund transfer is fail.
										m_oESBPay = m_oEsbServices.RevertBillerCharges(p_oEnterpriseServices, m_sChargesAcctCode, m_sChargesAmount, m_sAccountNo, m_sEsbDescriptionRevertCharges, null, "", payeeName, details);
									}
								}
								
							}
						}
						else
						{
							m_oESBPay = m_oEsbServices.CommonBillerPayment(p_oEnterpriseServices, m_sAccountNo, m_sAmount, m_sMerchantAcctCode, m_sTrnxPaymentMode, m_sEsbDescription, null, "", payeeName, details);
						}
					}

					m_sBalance 	= m_oESBPay.getFromAccountBalance ();

					m_sPhoenixReference = m_oESBPay.getTransferReferenceNo ();
					m_sEPayReference 	= m_oESBPay.getTransRef();
					m_sRevertReference	= m_oESBPay.getRevertReferenceNo();
					if (ESBConstants.IB_SUCCESS_RC.equals (m_oESBPay.getRevertResponseCode ()))
					{
						m_boRevertStatus = true;
					}

					m_sPhoenixRc 	= m_oESBPay.getTransferResponseCode();
					m_sEPayRc 		= m_oESBPay.getMerchantResponseCode();
					m_sRevertRc 	= m_oESBPay.getRevertResponseCode();

					m_sMerchantAccNo = m_oESBPay.getMerchantAccNo();
					m_sMerchantId = m_oESBPay.getMerchantId();
					m_sOperatorId = m_oESBPay.getOperatorId();
					m_sTerminalId = m_oESBPay.getTerminalId();
					m_sMercRespCode = m_oESBPay.getMercRespCode ();
					m_sMercRespMsg = m_oESBPay.getMercRespMsg ();
					m_sTransTraceId = m_oESBPay.getTransTraceId();

					// Phoenix Transaction
					if(ESBConstants.IB_SUCCESS_RC.equals(m_sPhoenixRc))
					{
						// EPay Transaction
						if(ESBConstants.IB_SUCCESS_RC.equals(m_sEPayRc))
						{
							m_boIsResultSuccessful = true;
							m_sStatus 	= ResourcesUtils.getSuccessful ();
						}
						else
						{
							//Epay error
							m_sTransStatusMsg = m_oESBPay.getMerchantErrorMessage();
							m_sReason = m_sTransStatusMsg;

							// Revert Transaction
							if(!ESBConstants.IB_SUCCESS_RC.equals(m_sRevertRc))
							{
								// In case error occurs while Reverting
								m_sTransStatusMsg = m_oESBPay.getRevertErrorMessage();
								m_sReason = m_sTransStatusMsg;
							}
							else
							{
								if (m_boSIChargeStatus)
								{
									ESBTransferGLtoCASABean m_oESBTransferGLtoCASABean = m_oEsbServices.transferGLtoCASA (m_sChargeGLAccount,
											m_sAccountNo, m_sSICharges, ESBConstants.SI_CHARGES_REVERT, null, payeeName, details);
									m_sSIChargesRevertRefNo = m_oESBTransferGLtoCASABean.getReferenceNo ();
									if (ESBConstants.IB_SUCCESS_RC.equals (m_oESBTransferGLtoCASABean.getResponseCode ()))
									{
										m_boSIChargeRevertStatus = true;
									}
								}
								
								if (m_boSIGSTChargeStatus)
								{
									ESBTransferGLtoCASABean m_oESBTransferGLtoCASABean = m_oEsbServices.transferGLtoCASA (ResourcesUtils.getGLAccountResource ("gl.account.gst"),
											m_sAccountNo, m_sSIGSTCharges, ESBConstants.SI_GST_CHARGES_REVERT, null, payeeName, details);
									m_sSIGSTChargesRevertRefNo = m_oESBTransferGLtoCASABean.getReferenceNo ();
									if (ESBConstants.IB_SUCCESS_RC.equals (m_oESBTransferGLtoCASABean.getResponseCode ()))
									{
										m_boSIGSTChargeRevertStatus = true;
									}
								}
							}
							m_boIsResultSuccessful = false;
							m_sStatus = ResourcesUtils.getUnsuccessful ();
						}

						//is this for iCubes prupose
						if(!DataValidator.isEmptyString(m_oESBPay.getMerchantAccNo()))
						{
							if(!BillPaymentContants.isEPay(m_oPayeeContent)
									&& !BillPaymentContants.isMobilityOneNTwo(m_oPayeeContent))
							{
								m_boIsResultSuccessful = true;
								m_sStatus 	= ResourcesUtils.getSuccessful ();
							}
						}
					}
					else
					{
						m_sTransStatusMsg = m_oESBPay.getTransferErrorMessage();
						m_sReason = m_sTransStatusMsg;
						m_boIsResultSuccessful = false;
						m_sStatus = ResourcesUtils.getUnsuccessful ();
					}
				}
			}

			//Start Create Receipt
			if(m_boIsResultSuccessful)
			{
				m_oReceiptMap.put(ResourcesUtils.getApplicationResourceMessage ("receipt.transaction.type"), m_sTrnxType);
				m_oReceiptMap.put(ResourcesUtils.getApplicationResourceMessage ("ib105.bill.payment.from.account"), m_sFromAccount);
				m_oReceiptMap.put(ResourcesUtils.getApplicationResourceMessage ("ib105.bill.payment.amount"), FormatterUtils.formatMoneyDisplay (m_sAmount, null, true));
				if(CommonConstants.isTrue (m_sChargesIndicator)&&!DataValidator.isEmptyString(m_sChargesAmount) && Double.valueOf(m_sChargesAmount)>0)
					m_oReceiptMap.put(ResourcesUtils.getApplicationResourceMessage ("general.charges"), DataValidator.isEmptyString(m_sChargesAmount)?"-":FormatterUtils.formatMoneyDisplay (m_sChargesAmount, null, true));
				
				String gstChargesdis = DataValidator.isEmptyString(gstCharges)? "-":("0.00".equals(gstCharges) ||"0.0".equals(gstCharges)||"0".equals(gstCharges)?"-":FormatterUtils.formatMoneyDisplay (gstCharges, null, true));
				if(!"-".equalsIgnoreCase(gstChargesdis)){
					m_oReceiptMap.put(ResourcesUtils.getApplicationResourceMessage ("general.gst.charges"), gstChargesdis);
				}
				m_oReceiptMap.put(ResourcesUtils.getApplicationResourceMessage ("ib105.bill.payment.payee"), table.getStringValue(0, LogTables.IB_BILL_PAYMENT.PAYEE_NAME.toString ()));

				if( isFavouritePayment(trnxTypeDisplay) && !DataValidator.isEmptyString(m_sToAccount))
				{
					m_oReceiptMap.put(ResourcesUtils.getApplicationResourceMessage ("ib105.bill.payment.bill.account.holder"), m_sToAccount);
				}

				if(isTrue (m_oPayeeContent.getStringValue (BillPaymentContants.COL_BILL_ACCT_REQ))
						&& !DataValidator.isEmptyString(m_sToAccount))
				{
					String m_sBillAccDisplay = null;

					if(isTrue (m_oPayeeContent.getStringValue (BillPaymentContants.COL_ACCT_DISP_NAME_REQ)))
					{
						m_sBillAccDisplay = table.getStringValue(0, LogTables.IB_BILL_PAYMENT.BILL_ACC_NAME.toString ());
					}
					else
					{
						m_sBillAccDisplay = ResourcesUtils.getApplicationResourceMessage ("ib105.bill.payment.bill.account.no");
					}
					m_oReceiptMap.put(m_sBillAccDisplay, table.getStringValue(0, LogTables.IB_BILL_PAYMENT.BILL_ACC_NO.toString ()));
				}

				//only M1 using the hard scoded contact no
				if(BillPaymentContants.isMobilityOne(merchant)
						&& !DataValidator.isEmptyString(table.getStringValue(0, LogTables.IB_BILL_PAYMENT.CONTACT_NO.toString ())))
				{
					m_oReceiptMap.put(ResourcesUtils.getApplicationResourceMessage ("ib105.bill.payment.contact.no"), table.getStringValue(0, "CONTACT_NO"));
				}

				if(isTrue(m_oPayeeContent.getStringValue (BillPaymentContants.COL_BILL_REF1_REQ))
						&& isTrue(m_oPayeeContent.getStringValue (BillPaymentContants.COL_BILL_REF1_MANDATORY)))
				{
					String m_sBillRef1Display = null;

					if(isTrue (m_oPayeeContent.getStringValue (BillPaymentContants.COL_BILL_REF1_DISP_NAME_REQ))
							&& !DataValidator.isEmptyString(m_oPayeeContent.getStringValue (BillPaymentContants.COL_BILL_REF1_DISP_NAME)))
					{
						m_sBillRef1Display = m_oPayeeContent.getStringValue (BillPaymentContants.COL_BILL_REF1_DISP_NAME);
					}
					else
					{
						m_sBillRef1Display = ResourcesUtils.getApplicationResourceMessage ("ib105.bill.payment.bil.reference.1");
					}
					m_oReceiptMap.put(m_sBillRef1Display, table.getStringValue(0, LogTables.IB_BILL_PAYMENT.INFO2.toString ()));
				}

				if(isTrue (m_oPayeeContent.getStringValue (BillPaymentContants.COL_BILL_REF2_REQ))
						&& isTrue (m_oPayeeContent.getStringValue (BillPaymentContants.COL_BILL_REF2_MANDATORY)))
				{
					String m_sBillRef2Display = null;

					if(isTrue (m_oPayeeContent.getStringValue (BillPaymentContants.COL_BILL_REF2_DISP_NAME_REQ))
							&& !DataValidator.isEmptyString(m_oPayeeContent.getStringValue (BillPaymentContants.COL_BILL_REF2_DISP_NAME)))
					{
						m_sBillRef2Display = m_oPayeeContent.getStringValue (BillPaymentContants.COL_BILL_REF2_DISP_NAME);
					}
					else
					{
						m_sBillRef2Display = ResourcesUtils.getApplicationResourceMessage ("ib105.bill.payment.bil.reference.2");
					}
					m_oReceiptMap.put(m_sBillRef2Display, table.getStringValue(0, LogTables.IB_BILL_PAYMENT.INFO3.toString ()));
				}

				m_oReceiptMap.put(ResourcesUtils.getApplicationResourceMessage ("general.status"), m_sStatus);

//				if(!DataValidator.isEmptyString(m_sBalance))
//				{
//					m_oReceiptMap.put(ResourcesUtils.getApplicationResourceMessage ("general.new.balance"), m_sBalance);
//				}

				if(!DataValidator.isEmptyString(m_sPhoenixReference))
				{
					m_oReceiptMap.put(ResourcesUtils.getApplicationResourceMessage ("general.reference"),m_sPhoenixReference);
				}

				m_oReceiptMap.put(ResourcesUtils.getApplicationResourceMessage ("general.reference.number"), FormatterUtils.formatTransID (m_sTrnxID));
				m_oReceiptMap.put(ResourcesUtils.getApplicationResourceMessage ("general.transaction.date"), m_sDate);
				m_oReceiptMap.put(ResourcesUtils.getApplicationResourceMessage ("general.transaction.time"), m_sTime);

				//Add KFH GST Account No
				if(!"-".equalsIgnoreCase(gstChargesdis))
					m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("general.gst.id.no"), IBLoadProperty.getValue("gst.id.no"));
				
				IBUtils.loopIntoReceiptDetails (p_oEnterpriseServices, m_oReceiptMap, m_oDate.getSimpleDate (), m_sTrnxID);
				
				//#-- added by pixa 20121017 start
                if (onlineAccSIPromoBean !=null){
        	    	HibernateOnlineAccUtils.saveIBOnlineAccPromoTrnx(onlineAccSIPromoBean);
        	    }
                if (onlineAccTrnxPromoBean !=null){
        	    	HibernateOnlineAccUtils.saveIBOnlineAccPromoTrnx(onlineAccTrnxPromoBean);
        	    }
                //#-- added by pixa 20121017 end
			}
			// End Create Receipt

			//log into si history

			if(DataValidator.isEmptyString(m_sToAccount))
			{
				m_sToAccount = "";
			}

			IBLogger.logSIHistory(p_oEnterpriseServices, rimNo, siId, m_sTrnxID, m_oDate.getJavaDate (),
					SIConstants.TRANSCODE_BILL_PAYMENT,
					m_sFromAccount, m_sToAccount, fromCurrency, toCurrency,
					m_sAmount,
					"0", // ForeignAmount
					m_sChargesAmount,
					m_sSICharges, // SICharges
					m_sStatus,
					m_sReason,
					m_sPhoenixReference,
					m_sRevertReference, // PhxRevRefNo
					m_boRevertStatus, // PhxRevStatus
					m_sEPayReference, // EpayRefNo
					"", // PhxChargeRefNo
					true, // PhxChargeStatus
					"", // PhxChargeRevRefNo
					false, // PhxCharRevStatus
					m_sSIChargesRefNo, // SIChargeRefNo
					m_boSIChargeStatus,
					m_sSIChargesRevertRefNo,
					m_boSIChargeRevertStatus,
					m_sSIServiceCode,
					m_boIsResultSuccessful,
					m_sProductCode,
					p_sProdSubCode,
					merchant,
					m_sMerchantAccNo,
					m_sMerchantId,
					m_sOperatorId,
					m_sTerminalId,
					"", //p_sRespPin
					"", //p_sRespPinExp
					m_sMercRespCode, //p_sRespCode
					m_sMercRespMsg, //p_sRespMsg
					m_sTransTraceId, //p_sTrnxTraceID					
					m_sSIGSTCharges, // SI GST Charges
					"",
					m_sSIGSTChargesRevertRefNo, // SIGSTChargesRevertRefNo
					m_boSIGSTChargeRevertStatus); // SIGSTChargeRevertStatus
			
			//SMS Notification START
			String payeeShortName =  (String) m_oPayeeContent.getStringValue (BillPaymentContants.COL_SHORT_NAME);
			SMSServices.sendCustomerSMSForSI (
					p_oEnterpriseServices, 
					userId, 
					m_sSIServiceCode, 
					SIConstants.TRANSCODE_BILL_PAYMENT, 
					m_sStatus, 
					m_sTrnxID, 
					m_sFromAccount, 
					m_sAmount, 
					m_oDate,
					FormatterUtils.formatMoneyDisplay (m_sBalance, "", true),
					payeeShortName.length()>14?payeeShortName.substring(0, 14):payeeShortName);
			//SMS Notification END
		}
		catch (Exception e)
		{
			e.printStackTrace();
			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);
	}

	private static boolean isFavouritePayment (String p_sPaymentType)
	{
		if (p_sPaymentType.contains(BillPaymentContants.PAYMENT_TYPE_FAVOURITE))
		{
			return true;
		}
		return false;
	}

	/**
	 * <pre>
	 * If string given is '0' or 'Yes'
	 * return true else false
	 * </pre>
	 *
	 * @param p_sPaymentType String containing type of payment such as 'OPEN'.etc
	 * @return false
	 */
	private static boolean isTrue (String p_sString)
	{
		if (!DataValidator.isEmptyString (p_sString) &&
				(CommonConstants.BV_INT_YES.equals (p_sString) || CommonConstants.BV_STRING_YES.equals (p_sString)))
		{
			return true;
		}

		return false;
	}
	public static boolean isNumeric(String s) 
	{
		Boolean result = false;
	    try 
	    { 
	    	for (int j = 0; j < s.length(); j++)
			{
				int code = s.charAt(j);

				if (!(code >= 48 && code <= 57))
				{
					//error
					return false;
				}
				else
				{
					result = true;
				}
			}
		
	    } catch(NumberFormatException e) 
	    { 
	    	result = false; 
	    }
	    // only got here if we didn't return false
	    return result;
	}
}
