/**
 * Copyright (c) 2010 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.ib104_fundtransfer.interbank;

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.GenericESBServicesImpl;
import my.com.kfh.enterprise.services.GenericIBGServicesImpl;
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.ib104_fundtransfer.others.IBStdDailyLimitBaseServices;
import my.com.kfh.enterprise.services.ib104_fundtransfer.thirdparty.IBFundTransferDBUtils;
import my.com.kfh.enterprise.services.ib104_fundtransfer.thirdparty.ThirdPartyTransferTags;
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.enterprise.services.integration.ESBAccountBalanceServices;
import my.com.kfh.enterprise.services.integration.ESBPhoenixWSServices;
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.request.ESBRequestAccountBalanceBean;
import my.com.kfh.esb.request.ESBRequestPhoenixWSBean;
import my.com.kfh.esb.response.ESBAccCreateDateBean;
import my.com.kfh.esb.response.ESBAccountBalanceBean;
import my.com.kfh.esb.response.ESBAccountEnquiryTC100Bean;
import my.com.kfh.esb.response.ESBAccountInfoDetailBean;
import my.com.kfh.esb.response.ESBCompanyProfileBean;
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.SMSConstants;
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.IBLogWriter;
import my.com.kfh.web.utils.IBLogger;
import my.com.kfh.web.utils.IBOfacBlackList;
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.BeneficiaryIDType;
import my.com.kfh.web.utils.constant.CurrencyCode;
import my.com.kfh.web.utils.constant.ESBConstants;
import my.com.kfh.web.utils.constant.IBGConstants;
import my.com.kfh.web.utils.constant.LogTables;
import my.com.kfh.web.utils.constant.ServiceInfo;
import net.penril.bean.IBGEntryRespBean;

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 5, 2010
 * TAG AS:
 * REASON(S):
 * MODIFICATION:
 * </pre>
 */

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

	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_sSIChargesRevertRefNo = null;
		boolean m_boSIChargeRevertStatus = false;
		double m_dAvailableBal = 0.0;
		double m_dTransferAmount = 0.0;
		double m_dTotalAmount = 0.0;
		double m_dSICharges = 0.0;
		String m_sServiceCharges = "0";
		double m_dServiceCharges = 0.0;
		String gstCharges = "0";
		double dGstServiceCharges = 0.0;
		String m_sSIChargeResponseCode = null;
		boolean m_boIsFundSufficient = true;
		String m_sHostRefNo=null;

		String m_sTransStatus = ResourcesUtils.getUnsuccessful ();
		String m_sTransStatusDisplay = ResourcesUtils.getUnsuccessful ();
		String m_sTransStatusMsg="";
		String m_sActualStatus="";
		boolean m_boIsResultSuccessful = false;

		String m_sIbgTransID = "";
		String m_sChargesRefNo = "";
		String m_sChargesRevRefNo = "";
		boolean m_boChargesStatus = false;
		boolean m_boChargeRevStatus = false;
		String m_sFromAccountCreateDate = "";
		String gstChargesRefNo = "";
		String gstChargesRevRefNo = "";

		Float m_fUserLimit = null;
		Content m_oSIServiceInfoContent = null;
		String m_sSIServiceMaxLimit = null;
		boolean m_boSIIndicator = true;
		boolean m_boIsScheduler = true;
		
		long m_sUserId = 0;
		Float specialDailyLimit= null;
		Float userDailyLimit= null;
		String residencyType = "";
		
		String m_sBeneIdNewIC = "";
    	String m_sBeneIdOldIC = "";
    	String m_sBeneIdBusReg = "";
    	String m_sBeneIdOtherId = "";
    	
    	String SIGSTCharges = "0";

		//#-- added by pixa 20121017 start
		OnlineAccPromoBean onlineAccTrnxPromoBean=null;	
		OnlineAccPromoBean onlineAccSIPromoBean=null;
		//#-- added by pixa 20121017 end  
		
		String m_sFromIsoCurrency = CurrencyCode.MALAYSIA_RINGGIT; //defaulted to MYR
		String m_sNewBalance = "";
        try
        {
			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 ());

			IBEnterpriseServices p_oEnterpriseServices = new IBEnterpriseServicesWorkspace(m_oSessionObj);
			GenericESBServicesImpl m_oEsbServices = new GenericESBServicesImpl (m_oSessionObj); //move to top by pixa 20121017
			//get user id from trnx
			table = InterbankDBUtils.getTransactionByTrnxId(p_oEnterpriseServices, currentTrnxId);
			String userId = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.USER_ID.toString ());
			
			m_sUserId = Long.parseLong(userId);
			userDailyLimit = IBUtils.getUserDailyLimit(p_oEnterpriseServices, m_sUserId);
			residencyType = IBUtils.getResidencyType(p_oEnterpriseServices, m_sUserId);
        	specialDailyLimit = IBUtils.getSpecialDailyLimit(p_oEnterpriseServices, m_sUserId);
        	specialDailyLimit = IBStdDailyLimitBaseServices. getSystemDailyLimit(p_oEnterpriseServices, null, null, residencyType , specialDailyLimit);
        	
        	
			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_INTER_TRANSFER.FROM_ACCOUNT_NO.toString ());
			String m_sToAccount = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.BENEFICIARY_ACCOUNT_NO.toString ());
			String m_sAmount = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.AMOUNT.toString ());
			String fromCurrency = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.FROM_CURRENCY.toString ());
			String toCurrency = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.TO_CURRENCY.toString ());
			m_sServiceCharges = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.CHARGES.toString ());
			gstCharges = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.GST_CHARGES.toString ());

			//get user rim no
			String rimNo = IBAccessDBUtils.getRimNoByUserId(p_oEnterpriseServices, userId);

			when(m_oSessionObj.getHttpSessionAttrObject (AccessConstants.RIM_NO)).thenReturn(rimNo);

            BVI_DateTime m_oCurrentBVIDateTime = new BVI_DateTime();
            String m_sDateDis = DateTimeUtils.formatDayMonthYear (m_oCurrentBVIDateTime);
            String m_sTimeDis = m_oCurrentBVIDateTime.getTime ();
            String m_sEffectiveDate = m_oCurrentBVIDateTime.getSimpleDate ();
            String m_sAmountDis = FormatterUtils.formatMoneyDisplay(m_sAmount, null, true);
            String m_sBeneBankDis = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.BENEFICIARY_BANK_NAME.toString ());
            String m_sBeneAccountNo = m_sToAccount;
            String m_sBeneHolderName = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.BENEFICIARY_NAME.toString ());
            String m_sBeneID = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.BENEFICIARY_ID.toString ());
            String m_sUserTransactionRefNo = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.PAYMENT_REFERENCE.toString ());
            String m_sTransactionDesc = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.PAYMENT_DETAILS.toString ());
            boolean m_boEnableVerification = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.VERIFY_INDICATOR.toString ()).equals("0")?true:false;
            String m_sBankRouteNo = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.BANK_ROUTE_ID.toString ());
            String m_sBeneIdType = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.BENEFICIARY_ID_TYPE.toString ());
            String m_sEmail = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.BENE_EMAIL.toString ());
            String m_sBeneIdTypeDisplay = BeneficiaryIDType.getDescription (m_sBeneIdType);

            String m_sTransId = IBUtils.getTransactionId (new DataManager ());
            String m_sFormattedTransId = FormatterUtils.formatTransID (m_sTransId);
            String senderName = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.SENDER_NAME.toString ());
            String beneName = table.getStringValue(0, LogTables.IB_INTER_TRANSFER.BENEFICIARY_NAME.toString ());
            
            //set it to pay now, since when SI run, it is suppose to run immediately

            /*
             * check blacklisted beneficiary name
             */
            if (IBFundTransferDBUtils.isNameBlacklisted (null, m_sBeneHolderName))
			{
            	m_boIsResultSuccessful = Boolean.FALSE;
            	m_sActualStatus = IBOfacBlackList.BLACK_LISTED;

                m_sTransStatus = ResourcesUtils.getUnsuccessful ();
                m_sTransStatusDisplay = ResourcesUtils.getUnsuccessful ();
                m_sTransStatusMsg = ResourcesUtils.getBusinessExceptionErrorMessage (IBBusinessException.INTERBANK_TRANSFER, InterbankConstants.ERR_BLACKLISTED_BENE_NAME);
			}
            else
            {

            	m_oSIServiceInfoContent = IBGenericSIServices.getServiceInfoContent (m_sSIServiceCode);
                m_sSIServiceMaxLimit = (String) m_oSIServiceInfoContent.getStringValue (ServiceInfo.TABLE_ATT_MAX_LIMIT);

            	/*
    			 * check daily limit based on Interbank transfer (combine open and registered interbank - SIFUNOER+SIFUNFER against SIINTERLIM)
    			 */
        		Map m_oSIBankLimitReturnMap = IBGenericInterbankServices.checkInterbankTransferDailyLimit (p_oEnterpriseServices,
	            		null, null, m_sAmount, m_sEffectiveDate, m_boSIIndicator, m_boIsScheduler , residencyType);
    			/*
                 * check daily limit based on service code (open interbank, registered interbank separately - SIFUNFER, SIFUNOER)
                 */
                m_fUserLimit = IBFundTransferDBUtils.getUserTransferLimit (m_oSessionObj, m_sSIServiceCode, m_boIsScheduler);

                Map m_oSIUserLimitReturnMap = IBGenericInterbankServices.checkInterbankTransferDailyLimitByServiceCode (p_oEnterpriseServices,
	            		m_sAmount, m_sSIServiceMaxLimit, m_fUserLimit, m_sSIServiceCode, m_sEffectiveDate, m_boSIIndicator, m_boIsScheduler,
	            		residencyType ,m_oSIBankLimitReturnMap);

                /*
                 * check daily limit
                 */
                
                Map m_oStdBankingLimitReturnMap = IBStdDailyLimitBaseServices.checkBankDailyLimit(p_oEnterpriseServices, null, 
                		null , m_sAmount , specialDailyLimit, m_sEffectiveDate, m_boSIIndicator, m_boIsScheduler , residencyType);
                
                Map m_oStdUserLimitReturnMap = IBStdDailyLimitBaseServices.checkUserDailyLimit(p_oEnterpriseServices, null, 
                		null, m_sAmount , userDailyLimit, m_sEffectiveDate, m_boSIIndicator, m_boIsScheduler);
                
                if (!((Boolean) m_oSIUserLimitReturnMap.get (InterbankConstants.STATUS)).booleanValue ())
                {
                	m_boIsResultSuccessful = Boolean.FALSE;

                    m_sTransStatus = ResourcesUtils.getUnsuccessful ();
                    m_sTransStatusDisplay = ResourcesUtils.getUnsuccessful ();
                    m_sTransStatusMsg = ResourcesUtils.getBusinessExceptionErrorMessage (IBBusinessException.SI, SIConstants.ERR_USER_MAX_LIMIT,
							new String [] { FormatterUtils.formatMoneyDisplay ( (String)m_oSIUserLimitReturnMap.get (SIConstants.MAX_LIMIT),
									null, true) });
                }
                else if (!((Boolean) m_oSIBankLimitReturnMap.get (InterbankConstants.STATUS)).booleanValue ())
    			{
    				m_boIsResultSuccessful = Boolean.FALSE;

                    m_sTransStatus = ResourcesUtils.getUnsuccessful ();
                    m_sTransStatusDisplay = ResourcesUtils.getUnsuccessful ();
                    m_sTransStatusMsg = ResourcesUtils.getBusinessExceptionErrorMessage (IBBusinessException.SI, SIConstants.ERR_BANK_MAX_LIMIT,
							new String [] { FormatterUtils.formatMoneyDisplay ( (String)m_oSIBankLimitReturnMap.get (SIConstants.MAX_LIMIT),
									null, true) });
    			}
                else if (!((Boolean) m_oStdUserLimitReturnMap.get (ThirdPartyTransferTags.STATUS)).booleanValue ())
                {
                	m_boIsResultSuccessful = Boolean.FALSE;
                	m_sTransStatus = ResourcesUtils.getUnsuccessful ();
                	m_sTransStatusDisplay = ResourcesUtils.getUnsuccessful ();
                	m_sTransStatusMsg = ResourcesUtils.getApplicationResourceMessage (ThirdPartyTransferTags.ERR_SI_USER_STD_LIMIT,
 	                		new String [] { FormatterUtils.formatMoneyDisplay (String.valueOf(specialDailyLimit) ,
 	                				CurrencyCode.MALAYSIA_RINGGIT, true) });
                	
//                	m_sTransStatusMsg = ResourcesUtils.getApplicationResourceMessage (ThirdPartyTransferTags.ERR_USER_STD_LIMIT,
//                    		new String [] { FormatterUtils.formatMoneyDisplay ((String) m_oStdUserLimitReturnMap.get (ThirdPartyTransferTags.MAX_LIMIT),
//                    				CurrencyCode.MALAYSIA_RINGGIT, true) });
                }
                else if ((!((Boolean) m_oStdBankingLimitReturnMap.get (ThirdPartyTransferTags.STATUS)).booleanValue ()))
                {
    				m_boIsResultSuccessful = Boolean.FALSE;
    				m_sTransStatus = ResourcesUtils.getUnsuccessful ();
    				m_sTransStatusDisplay = ResourcesUtils.getUnsuccessful ();
    				m_sTransStatusMsg = ResourcesUtils.getApplicationResourceMessage (ThirdPartyTransferTags.ERR_SI_BANK_STD_LIMIT,
                    		new String [] { FormatterUtils.formatMoneyDisplay ((String) m_oStdBankingLimitReturnMap.get (ThirdPartyTransferTags.MAX_LIMIT),
                    				CurrencyCode.MALAYSIA_RINGGIT, true) });	
                }
                else
                {

	            	String m_sRimNo = (String)  m_oSessionObj.getHttpSessionAttrObject (AccessConstants.RIM_NO);

	            	//GenericESBServicesImpl m_oEsbServices = new GenericESBServicesImpl (m_oSessionObj); //move to top by pixa 20121017

	    			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_INTER);
		    			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);
		            	}
		            	System.out.println("SI Charges: " + m_sSICharges);
		            	//#-- added by pixa 20121017 end --
		            	
		    			if (m_dSICharges > 0)
		    			{
		    				if (m_dAvailableBal > m_dSICharges)
		    				{
		    					String m_sChargeGLAccount = IBGenericSIServices.getSICollectionAccountNo (m_sFromAccount);

		    					ESBTransferToGLBean m_oESBTransferToGLBean = m_oEsbServices.chargesTransfer (m_sFromAccount,
		    							m_sChargeGLAccount, m_sSICharges, ESBConstants.SI_CHARGES, null, senderName, beneName, m_sUserTransactionRefNo, m_sTransactionDesc );

		    					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 = m_oEsbServices.chargesTransfer (m_sFromAccount,
		    								ResourcesUtils.getGLAccountResource ("gl.account.gst"), SIGSTCharges, ESBConstants.SI_GST_CHARGES, null, senderName, beneName, m_sUserTransactionRefNo, m_sTransactionDesc);
		    						
		    						String m_sSIGSTChargeResponseCode = m_oGSTESBTransferToGLBean.getResponseCode ();
			    					if (ESBConstants.IB_SUCCESS_RC.equalsIgnoreCase (m_sSIGSTChargeResponseCode)){
			    						m_boSIGSTChargeStatus = true;
			    						m_sSIGSTChargesRefNo = m_oGSTESBTransferToGLBean.getReferenceNo ();
			    					}else{
			    						m_boIsFundSufficient = false;
			    						m_boIsResultSuccessful = false;
			    						m_sTransStatus = ResourcesUtils.getUnsuccessful ();
			    						m_sTransStatusMsg = m_oGSTESBTransferToGLBean.getErrorMessage ();
			    						
			    						ESBTransferGLtoCASABean m_oESBTransferGLtoCASABean = m_oEsbServices.transferGLtoCASA(m_sChargeGLAccount, m_sFromAccount, m_sSICharges, ESBConstants.SI_CHARGES_REVERT, null, beneName, m_sTransactionDesc);
			    						
			    						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_sTransStatus = ResourcesUtils.getUnsuccessful ();
		    						m_sTransStatusDisplay = ResourcesUtils.getUnsuccessful ();
		    						m_sTransStatusMsg = m_oESBTransferToGLBean.getErrorMessage ();
		    					}
		    				}
		    				else
		    				{
		    					m_boIsFundSufficient = false;
		    					m_boIsResultSuccessful = false;
		    					m_sTransStatus = ResourcesUtils.getUnsuccessful ();
		    					m_sTransStatusDisplay = ResourcesUtils.getUnsuccessful ();
		    					m_sTransStatusMsg = ResourcesUtils.getApplicationResourceMessage (SIConstants.RESOURCES_INSUFFICIENT_FUND);
		    				}
		    			}
					}

	    			if (m_boIsFundSufficient)
	    			{
		    			m_dTransferAmount = Double.parseDouble (m_sAmount);
		    			if (!DataValidator.isEmptyString (m_sServiceCharges))
		    			{
		    				m_dServiceCharges = Double.parseDouble (m_sServiceCharges);
		    			}
		    			if (!DataValidator.isEmptyString (gstCharges))
		    			{
		    				dGstServiceCharges = Double.parseDouble (gstCharges);
		    			}
		    			m_dTotalAmount = m_dTransferAmount + m_dSICharges + Double.parseDouble(SIGSTCharges) + m_dServiceCharges + dGstServiceCharges;

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

	    			if (m_boIsFundSufficient)
	    			{
		            	/*
		            	 * get Segment Code
		            	 * R = 0, N = 1
		            	 */
		            	ESBCompanyProfileBean m_oESBCompanyProfileBean = m_oEsbServices.getProfileByAccRim (null, m_sRimNo);
		            	String m_sResidency = m_oESBCompanyProfileBean.getResidency ();

		            	String m_sElementCode = IBGConstants.ELEMENT_CODE_RESIDENCY;
		            	if (!DataValidator.isEmptyString (m_sResidency) && m_sResidency.equalsIgnoreCase (InterbankConstants.NON_RESIDENCY_TYPE))
		            	{
		            		m_sElementCode = IBGConstants.ELEMENT_CODE_NON_RESIDENCY;
		            	}

		            	/*
		            	 * get Element Code
		            	 * enable = 5, disable = 1
		            	 */
		            	String m_sSegmentCode = IBGConstants.SEGMENT_CODE_NON_VERIFICATION_BANK;
		            	if (m_boEnableVerification)
		            	{
		            		m_sSegmentCode = IBGConstants.SEGMENT_CODE_VERIFICATION_BANK;
		            	}

		            	m_sBeneIdNewIC=table.getStringValue(0, LogTables.IB_INTER_TRANSFER.NEW_IC_NO.toString ());
		            	m_sBeneIdOldIC=table.getStringValue(0, LogTables.IB_INTER_TRANSFER.OLD_IC_NO.toString ());
		            	m_sBeneIdBusReg=table.getStringValue(0, LogTables.IB_INTER_TRANSFER.BUSINESS_REG_NO.toString ());
		            	m_sBeneIdOtherId=table.getStringValue(0, LogTables.IB_INTER_TRANSFER.OTHER_ID_NO.toString ());

		            	/*
		            	 * set the Bene ID Type to the correct field
		            	 */
		            	if (BeneficiaryIDType.isNewIC (m_sBeneIdType))
		            	{
		            		m_sBeneIdNewIC = m_sBeneID;
		            	}
		            	else if (BeneficiaryIDType.isOldIC (m_sBeneIdType))
		            	{
		            		m_sBeneIdOldIC = m_sBeneID;
		            	}
		            	else if (BeneficiaryIDType.isBusinessRegistrationNo (m_sBeneIdType))
		            	{
		            		m_sBeneIdBusReg = m_sBeneID;
		            	}
		            	else if (BeneficiaryIDType.isOtherID (m_sBeneIdType))
		            	{
		            		m_sBeneIdOtherId = m_sBeneID;
		            	}
		            	String m_sLastName = IBAccessDBUtils.getLastNameByUserId(p_oEnterpriseServices, userId);

		            	ESBAccountInfoDetailBean m_oESBAcctInfoDetails = null;
	    				m_oESBAcctInfoDetails = m_oEsbServices.getAccountInfoDetail(m_sFromAccount);
	    				String m_sBranchCode = m_oESBAcctInfoDetails.getBranchCode();
	    				m_sBranchCode = FormatterUtils.padderLeft (m_sBranchCode,"0", 3);
	    				String transferGstCharges = "N";
	    				if(!DataValidator.isEmptyString(gstCharges)){
	    					if(!(gstCharges.equals("0") || gstCharges.equals("0.00"))){
	    						transferGstCharges = "Y";
	    					}
	    				}
	    				
		            	IBGEntryRespBean m_oIBGEntryRespBean = new GenericIBGServicesImpl (m_oSessionObj).insertIBGEntry (
		            			m_sFromAccount,
		            			m_sLastName,
		            			m_sBeneAccountNo,
		            			m_sBeneHolderName,
		            			m_sServiceCharges,
		            			m_sAmount,
		            			m_sEffectiveDate,
		            			IBGConstants.CHANNEL_ID_INTERNET_BANKING,
		            			IBGConstants.SUB_CHANNEL_ID_IB,
		            			m_sSegmentCode,
		            			m_sElementCode,
		            			m_sBeneID,
		            			m_sTransId,
		            			m_sBankRouteNo,
		            			SI_PAYMENT_MODE.PAY_NOW.getCode (),
		            			m_sTransactionDesc,
		            			m_sUserTransactionRefNo,
		            			m_sRimNo,
		            			m_sBranchCode, //IBUtils.getBranchCodeByAccNo (m_sFromAccount),
		            			m_sBeneIdNewIC,
		            			m_sBeneIdOldIC,
		            			m_sBeneIdBusReg,
		            			m_sBeneIdOtherId,
		            			null, null, null, siPaymentModeCode,
		            			gstCharges);

		            	m_sIbgTransID = m_oIBGEntryRespBean.getOid ();

		            	if (IBGConstants.IBG_RC_SUCCESS.equals (m_oIBGEntryRespBean.getRespCode ())
		            			|| IBGConstants.IBG_FUTURE_RC_SUCCESS.equals (m_oIBGEntryRespBean.getRespCode ()))
		            	{
		            		m_boIsResultSuccessful = true;
		            		m_sTransStatus = ResourcesUtils.getAccepted ();
		            		m_sTransStatusDisplay = ResourcesUtils.getApplicationResourceMessage ("general.status.accepted.for.processing");
		            		m_sHostRefNo = m_oIBGEntryRespBean.getFundReferenceNo ();
		            		m_sChargesRefNo = m_oIBGEntryRespBean.getChargeReferenceNo ();
		            		gstChargesRefNo = m_oIBGEntryRespBean.getGstChargeReferenceNo();
		            		m_boChargesStatus = true;
		            		
		            		// TC: 132 - Account Balance
        					ESBRequestAccountBalanceBean m_oBeanReq = new ESBRequestAccountBalanceBean ();
        					ESBAccountBalanceServices m_oESBAccountBalanceServices = new ESBAccountBalanceServices ();
        					ESBAccountBalanceBean m_oBeanResp = null;
        					// From Account Balance
        					m_oBeanReq.setAccountNo (m_sFromAccount);
        					m_oBeanReq.setRimNo (m_sRimNo);
        					m_oBeanResp = m_oESBAccountBalanceServices.retrieve (m_oBeanReq);
        					m_sNewBalance = FormatterUtils.formatMoneyDisplay (
        							DataValidator.isEmptyString (m_oBeanResp.getAvailableBalance ()) ? "0"
        									: m_oBeanResp.getAvailableBalance ().trim (),
        									m_sFromIsoCurrency, true);

		            		// Account Creation Date
		            		ESBPhoenixWSServices m_oESBPhoenixWSServices = new ESBPhoenixWSServices();
		            		ESBRequestPhoenixWSBean m_oRequest = new ESBRequestPhoenixWSBean();
		            		// From Account Creation Date
		            		m_oRequest.setAcctNo (m_sFromAccount);
		            		ESBAccCreateDateBean m_oAccCreateDateBean = m_oESBPhoenixWSServices.getAccCreateDate (m_oRequest);
		            		m_sFromAccountCreateDate = m_oAccCreateDateBean.getDtAccOpen();
		            	}
		            	else
		            	{
		            		m_boIsResultSuccessful = false;
		            		m_sTransStatus = ResourcesUtils.getUnsuccessful ();
		            		m_sTransStatusDisplay = ResourcesUtils.getUnsuccessful();
		            		m_sTransStatusMsg = m_oIBGEntryRespBean.getRespMsg ();
		            		m_sChargesRevRefNo = m_oIBGEntryRespBean.getChargeReferenceNo ();
		            		m_boChargeRevStatus = true;
		            	}
	    			}
	            }
            }

            if (m_boIsResultSuccessful)
            {
            	String m_sServiceName=trnxTypeDisplay;

                /*
            	 * email transfer notification to recipient
            	 */
        		if (!DataValidator.isEmptyString (m_sEmail))
                {
    				String m_sSubject = ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.email.subject");
                	String m_sCustomerName = IBAccessDBUtils.getLastNameByUserId (p_oEnterpriseServices, userId);

                	StringBuffer m_sbEmailMsg = new StringBuffer ();
                	m_sbEmailMsg.append (ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.email.greetCustomer", new String [] {m_sSubject, m_sBeneHolderName} ));
                	m_sbEmailMsg.append (ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.email.note1",
                			new String [] {m_sCustomerName,
                				DateTimeUtils.formatDayMonthYear (m_oCurrentBVIDateTime).concat (" ").concat (m_oCurrentBVIDateTime.getTime()) } ));

                	IBLogWriter m_oTableCreater = new IBLogWriter();
                	m_sbEmailMsg.append (m_oTableCreater.RowCreater ("S", ResourcesUtils.getApplicationResourceMessage ("general.amount"), m_sAmountDis, null, null)).append("\n");
                    m_sbEmailMsg.append (m_oTableCreater.RowCreater ("C", ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.bene.bank"), m_sBeneBankDis, null, null)).append("\n");
                	m_sbEmailMsg.append (m_oTableCreater.RowCreater ("C", ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.recipient.ref"),
                			DataValidator.isEmptyString (m_sUserTransactionRefNo) ? "-" : m_sUserTransactionRefNo, null, null)).append("\n");
                	m_sbEmailMsg.append (m_oTableCreater.RowCreater ("E", ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.payment.desc"),
                			DataValidator.isEmptyString (m_sTransactionDesc) ? "-" : m_sTransactionDesc, null, null)).append("\n");

                	m_sbEmailMsg.append (ResourcesUtils.getApplicationResourceMessage ("ib104.thirdparty.email.note2"));
                	m_sbEmailMsg.append (ResourcesUtils.getApplicationResourceMessage ("ib104.thirdparty.email.disclaimer"));

                	IBUtils.sendEmail (p_oEnterpriseServices, null, m_sEmail, m_sSubject, m_sbEmailMsg.toString (), m_sTransStatusDisplay, null);
                }

                /*
                 * receipt
                 */
            	Map<String,String> m_oReceiptMap = new LinkedHashMap<String, String>();
            	m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("receipt.transaction.type"), m_sServiceName);
                m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("ib104.sender.name"), senderName);
                m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.bene.holder.name"), m_sBeneHolderName);
                m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("general.status"), m_sTransStatusDisplay);
                m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("general.amount"), m_sAmountDis);
                if (!DataValidator.isEmptyString (m_sUserTransactionRefNo ))
				{
					m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.recipient.ref"), m_sUserTransactionRefNo);
				}
                m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.bene.bank"), m_sBeneBankDis);
                m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.bene.acct.no"), m_sBeneAccountNo);
    			if (!DataValidator.isEmptyString (m_sBeneIdNewIC))
				{
                	m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.new.ic"), m_sBeneIdNewIC);
				}
                if (!DataValidator.isEmptyString (m_sBeneIdOldIC))
				{
                	m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.old.ic"), m_sBeneIdOldIC);
				}
                if (!DataValidator.isEmptyString (m_sBeneIdBusReg))
				{
                	m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.business.reg"), m_sBeneIdBusReg);
				}
                if (!DataValidator.isEmptyString (m_sBeneIdOtherId))
				{
                	m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.other.id"), m_sBeneIdOtherId);
				}
                if (!DataValidator.isEmptyString (m_sUserTransactionRefNo))
				{
					m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.payment.desc"), m_sUserTransactionRefNo);
				}
                if (!DataValidator.isEmptyString (m_sEmail))
 				{
                 	m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("general.email"), m_sEmail);
 				}

                m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("general.amount"), m_sAmountDis);
                if(!DataValidator.isEmptyString(m_sServiceCharges) && Double.valueOf(m_sServiceCharges)>0)
                	m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("general.charges"), FormatterUtils.formatMoneyDisplay(m_sServiceCharges, null, true));
                if(!DataValidator.isEmptyString(gstCharges) && !("0.00".equals(gstCharges)|| "0.0".equals(gstCharges)|| "0".equals(gstCharges)))
                {
                	m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("general.gst.charges"), FormatterUtils.formatMoneyDisplay(gstCharges, null, true));
                }
                
                m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.bene.bank"), m_sBeneBankDis);
                m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("ib104.interbank.bene.acct.no"), m_sBeneAccountNo);

                m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("general.reference.number"), m_sFormattedTransId);
                if(!DataValidator.isEmptyString (m_sHostRefNo))
				{
                	m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("general.reference"), m_sHostRefNo);
				}
                m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("general.transaction.date"), m_sDateDis);
                m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("general.transaction.time"), m_sTimeDis);

                //Add KFH GST Account No
                if(!DataValidator.isEmptyString(gstCharges) && !("0.00".equals(gstCharges)|| "0.0".equals(gstCharges)|| "0".equals(gstCharges)))
                	m_oReceiptMap.put (ResourcesUtils.getApplicationResourceMessage ("general.gst.id.no"), IBLoadProperty.getValue("gst.id.no") );
				
                /*
                 * log into IB_RECEIPT_DETAIL
                 */
                IBUtils.loopIntoReceiptDetails (p_oEnterpriseServices, m_oReceiptMap, m_oCurrentBVIDateTime.getSimpleDate (), m_sTransId);
                
                //#-- added by pixa 20121017 start
                if (onlineAccSIPromoBean !=null){
        	    	HibernateOnlineAccUtils.saveIBOnlineAccPromoTrnx(onlineAccSIPromoBean);
        	    }
            	onlineAccTrnxPromoBean = IBUtilsOnlineAcc.getChargesIfIsOnlineAccount(m_oEsbServices,m_sFromAccount, OnlineAccConstants.IBG);
            	if(onlineAccTrnxPromoBean !=null){
            		HibernateOnlineAccUtils.saveIBOnlineAccPromoTrnx(onlineAccTrnxPromoBean);
            	}
                //#-- added by pixa 20121017 end
            }
			//log into si history
			IBLogger.logSIHistory(p_oEnterpriseServices, rimNo, siId, m_sTransId, m_oCurrentBVIDateTime.getJavaDate (),
					SIConstants.TRANSCODE_INTER_TRANSFER,
					m_sFromAccount, m_sToAccount, fromCurrency, toCurrency,
					m_sAmount,
					"0", // ForeignAmount
					m_sServiceCharges,
					m_sSICharges, // SICharges
					m_sTransStatus,
					m_sTransStatusMsg,
					m_sHostRefNo,
					"", // PhxRevRefNo
					false, // PhxRevStatus
					"", // EpayRefNo
					m_sChargesRefNo, // PhxChargeRefNo
					m_boChargesStatus, // PhxChargeStatus
					m_sChargesRevRefNo, // PhxChargeRevRefNo
					m_boChargeRevStatus, // PhxCharRevStatus
					m_sSIChargesRefNo, // SIChargeRefNo
					m_boSIChargeStatus,
					m_sSIChargesRevertRefNo, // SIChargeRevRefNo
					m_boSIChargeRevertStatus, // SIChargeRevStatus
					m_sSIServiceCode,
					m_boIsResultSuccessful,
					m_sSIGSTCharges, // SI GST Charges
					gstCharges, // Service GST Charges
					"", // SIGSTChargesRevertRefNo
					false); // SIGSTChargeRevertStatus
			
			//SMS Notification START
			SMSServices.sendCustomerSMSForSI (
					p_oEnterpriseServices, 
					userId, 
					m_sSIServiceCode, 
					SIConstants.TRANSCODE_INTER_TRANSFER, 
					m_sTransStatus, 
					m_sTransId, 
					m_sFromAccount, 
					m_sAmount, 
					m_oCurrentBVIDateTime,
					m_sNewBalance,
					m_sBeneHolderName.length()>18?m_sBeneHolderName.substring(0, 18):m_sBeneHolderName);
			//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);
    }
}

