just rember this and dont say anything


package rcb.business.account.casa.service;

import java.math.BigDecimal;
import java.sql.Date;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.ejb.EJB;
import javax.ejb.FinderException;
import javax.ejb.Stateless;
import javax.naming.NamingException;
import javax.persistence.Tuple;

import com.ebbs.wrapper.BalanceComputationWrapper;

import rcb.business.account.casa.constants.CASAConstants;
import rcb.business.account.casa.error.CASAError;
import rcb.business.account.casa.service.entity.dao.FreshFundsDAO;
import rcb.business.account.casa.service.host.view.CASABalanceServiceHostInterface;
import rcb.business.account.casa.service.host.view.NewFundBalanceBusinessHostInterface;
import rcb.business.account.casa.wrapper.NewFundBalanceDetailWrapper;
import rcb.business.account.casa.wrapper.NewFundBalanceWrapper;
import rcb.technical.resource.utility.GlobalUniqueIdentifierUtility;
import rcb.technical.resource.utility.ResourceConstants;
import scb.technical.systemutility.exception.BusinessComponentException;
import scb.technical.systemutility.exception.ErrorObject;
import scb.technical.systemutility.exception.ExceptionType;
import scb.business.edeals.ejb.DealInterestAccrualEntityHome;
import scb.business.edeals.ejb.DealInterestAccrualEntityKey;
import scb.business.edeals.wrapper.DealInterestAccrualWrapper;
import scb.ebbs.accounts.ejb.NewFundTrackingEntity;
import scb.ebbs.accounts.ejb.NewFundTrackingEntityHome;
import scb.ebbs.accounts.ejb.NewFundTrackingEntityKey;
import scb.ebbs.accounts.factory.NewFundTrackingDAOFactory;
import scb.ebbs.accounts.wrapper.NewFundTrackingWrapper;
import scb.ebbs.ecodes.wrapper.SystemWrapper;
import scb.ebbs.ecodes.wrapper.FreshFundsBusinessParamWrapper;
import scb.ebbs.util.BalanceComputationUtility;
import scb.ebbs.util.EBBSBusinessProcessConstants;
import scb.ebbs.util.NewFundUtility;
import scb.ebbs.util.StaticDataCache;
import scb.exception.SCBApplicationException;
import scb.general.ejb.BusinessProcessParamCache;
import scb.technical.integration.errors.TechnicalErrors;
import scb.technical.integration.service.util.SystemServiceProvider;
import scb.technical.resource.utility.SystemInstanceConstants;
import scb.technical.systemutility.exception.TechnicalComponentException;
import scb.technical.systemutility.util.StringUtility;
import scb.util.BusinessInfo;
import scb.util.DateUtility;
import scb.util.EBBSConstants;
import scb.util.EntityBeanLookupAdaptor;
import scb.util.LogWriter;
import scb.util.SystemProperties;
import scb.wrapper.AbstractWrapper;

/**
 * NewFundBalanceBusinessHostBean class used for New Fund Balance to handle
 * Business related process
 * 
 * @project   :KEYSTONEHK-11051
 * @author    :1637811 (Udayakumar V)
 * @createdOn :14-07-2022
 */
@Stateless
public class NewFundBalanceBusinessHostBean implements NewFundBalanceBusinessHostInterface {

	NewFundTrackingEntityHome newFundTrackingEntityHome = null;
	LogWriter log = LogWriter.getInstance("NewFundBalanceBusinessHostBean", "NewFundBalanceBusinessHostBean");
	@EJB
	FreshFundsDAO freshFundsDAO;
	DealInterestAccrualEntityHome dealInterestAccrualEntityHome;

	/*
	 * getNewFundBalanceByParams method used to get New Fund Balance details based on RealtionshioNo
	 * 
	 * @param NewFundBalanceWrapper
	 * @return newFundBalanceWrapper
	 */
	@Override
	public NewFundBalanceWrapper getNewFundBalanceByParams(NewFundBalanceWrapper newFundBalanceWrapper)
			throws TechnicalComponentException, BusinessComponentException {
		NewFundBalanceWrapper newFundBalanceWrapperResponse = new NewFundBalanceWrapper();
		List<NewFundBalanceDetailWrapper> newFundBalanceDetailWrapperList = new ArrayList<>();
		Map<String, BigDecimal> totalAvailableBalanceMap = new HashMap<>();
		log.println("freshFundsParamWrapper.isBalanceBased before ");
		FreshFundsBusinessParamWrapper freshFundsParamWrapper = fetchFreshFundsBPPWrapper();
		if(freshFundsParamWrapper != null && freshFundsParamWrapper.isBalanceBased != null && "Y".equals(freshFundsParamWrapper.isBalanceBased.trim())) {
			log.println("freshFundsParamWrapper.isBalanceBased "+freshFundsParamWrapper.isBalanceBased);
			try{
				newFundBalanceWrapperResponse = processBalanceBasedFreshFunds(freshFundsParamWrapper,newFundBalanceWrapper);
			}
			catch(Exception e) {
				log.printErrorMessage(e);
				throw new TechnicalComponentException(TechnicalErrors.TECHNICAL_ERROR.getErrorCode(),TechnicalErrors.TECHNICAL_ERROR.getErrorDescription(), CASAConstants.COMPONENT);
			}
		}
		else {
			try {
				newFundTrackingEntityHome = (NewFundTrackingEntityHome) NewFundTrackingDAOFactory.getDAOInstance("NewFundTrackingEntity");

				if (newFundBalanceWrapper.getProfileId() != null) {

					newFundBalanceWrapperResponse.setId(GlobalUniqueIdentifierUtility.getInstance().construct(
							SystemInstanceConstants.getResourceInstance(ResourceConstants.CASA_RESOURCE),
							SystemInstanceConstants.getCountryInstance(SystemProperties.getInstance().getCompanyID()),
							new String[] { newFundBalanceWrapper.getProfileId().trim() }));
					newFundBalanceWrapperResponse.setProfileId(newFundBalanceWrapper.getProfileId().trim());

					NewFundTrackingEntityKey newFundTrackingEntityKey = new NewFundTrackingEntityKey(
							newFundBalanceWrapper.getProfileId().trim(), null, null, null, null, null);

					getTotalAvailableBalanceMap(newFundTrackingEntityKey, totalAvailableBalanceMap);

					Map<String, Date> accountRelOpenDateMap = newFundTrackingEntityHome.getAccountRelOpenDateMap(newFundTrackingEntityKey);
					String customerType = getCustomerType(accountRelOpenDateMap);
					newFundBalanceWrapperResponse.setCustomerType(customerType);
					log.println("newFundBalanceWrapperResponse.setCustomerType= "+ newFundBalanceWrapperResponse.getCustomerType());

					NewFundTrackingEntity newFundTrackingEntity = newFundTrackingEntityHome
							.findByPrimaryKey(new NewFundTrackingEntityKey(newFundBalanceWrapper.getProfileId().trim(),null, null, null, null, null));

					List<NewFundTrackingWrapper> newFundTrackingWrapperList = (List<NewFundTrackingWrapper>) newFundTrackingEntity
							.getNewFundTrackingDetails();
					log.println("newFundTrackingWrapperList.size=" +newFundTrackingWrapperList.size());

					if (newFundTrackingWrapperList != null && newFundTrackingWrapperList.size() > 0) {
						convertNewFundTrackingToNewFundBalanceWrapper(newFundTrackingWrapperList,newFundBalanceWrapperResponse,
								newFundBalanceDetailWrapperList, totalAvailableBalanceMap,newFundBalanceWrapper.getProfileId());
					}
					newFundBalanceWrapperResponse.setNewFundBalanceDetailList(newFundBalanceDetailWrapperList);
				}
			} catch (Exception exception) {
				if (exception instanceof FinderException) {
					log.println("FinderException - input relationshipno not in NewFund Tracking table ");
					convertNewFundTrackingToNewFundBalanceWrapper(null, newFundBalanceWrapperResponse,
							newFundBalanceDetailWrapperList, totalAvailableBalanceMap,newFundBalanceWrapper.getProfileId());
					if(newFundBalanceDetailWrapperList.size() == 0) {
						log.println("No Records Found");
						throw new BusinessComponentException(ExceptionType.BUSINESS,CASAError.NORECORD_FOUND.getErrorCode(),
								CASAError.NORECORD_FOUND.getErrorDescription(), CASAConstants.COMPONENT);
					}
					newFundBalanceWrapperResponse.setNewFundBalanceDetailList(newFundBalanceDetailWrapperList);
				} else {
					log.println("Other exception");
					throw new BusinessComponentException(ExceptionType.BUSINESS,CASAError.NORECORD_FOUND.getErrorCode(),
							CASAError.NORECORD_FOUND.getErrorDescription(), CASAConstants.COMPONENT);
				}
			}
		}
		log.println("NewFundBalanceBusinessHostBean : getNewFundBalanceByParams method end");
		return newFundBalanceWrapperResponse;
	}

	private void getTotalAvailableBalanceMap(NewFundTrackingEntityKey newFundTrackingEntityKey,
			Map<String, BigDecimal> totalAvailableBalanceMap) {
		try {
			List<NewFundTrackingWrapper> newFundTrackingWrapperBalList = newFundTrackingEntityHome.getAccountNoCurrencyCodeList(newFundTrackingEntityKey);
			log.println("AcountNo-CurrencyCode - newFundTrackingWrapperBalList.size=" + newFundTrackingWrapperBalList.size());
			if (newFundTrackingWrapperBalList.size() > 0 && newFundTrackingWrapperBalList != null) {

				for (NewFundTrackingWrapper newFundTrackingWrapper : newFundTrackingWrapperBalList) {
					BalanceComputationWrapper balanceComputationWrapper = new BalanceComputationWrapper();
					balanceComputationWrapper.accountNo = newFundTrackingWrapper.accountNo;
					balanceComputationWrapper.currencyCode = newFundTrackingWrapper.currencyCode;
					
					BalanceComputationUtility.getInstance().getCompleteAccountBalance(balanceComputationWrapper);

					log.println("getTotalAvailableBalanceMap -- balanceComputationWrapper.accountNo="
							+ balanceComputationWrapper.accountNo + "//" + "balanceComputationWrapper.currencyCode="
							+ balanceComputationWrapper.currencyCode + "//"
							+ "balanceComputationWrapper.availableBalanceWithLimits="
							+ balanceComputationWrapper.availableBalanceWithLimits);
					
					// total available Balance groupby currency
					if (totalAvailableBalanceMap.containsKey(newFundTrackingWrapper.currencyCode)) {
						totalAvailableBalanceMap.put(newFundTrackingWrapper.currencyCode,totalAvailableBalanceMap.get(newFundTrackingWrapper.currencyCode)
										.add(balanceComputationWrapper.availableBalanceWithLimits));
					} else {
						totalAvailableBalanceMap.put(newFundTrackingWrapper.currencyCode,balanceComputationWrapper.availableBalanceWithLimits);
					}
				}
				log.println("totalAvailableBalanceMap= " + totalAvailableBalanceMap);
			}
		} catch (SCBApplicationException | FinderException e) {
			log.println("getTotalAvailableBalanceMap - newFundTrackingEntityHome.getAccountNoCurrencyCodeList(newFundTrackingEntityKey) - Exception");
			log.printErrorMessage(e);
		}
	}

	private String getCustomerType(Map<String, Date> accountRelOpenDateMap) {

		String customerType = null;
		try {
			log.println("accountRelOpenDateMap= " + accountRelOpenDateMap);
			SystemWrapper systemWrapper = (SystemWrapper) StaticDataCache.getInstance().getSystemWrapper();
			Date accountOpenDate = accountRelOpenDateMap.get("ACCOUNT_OPENDATE");
			Date relOpenDate = accountRelOpenDateMap.get("REL_OPENDATE");
			int accountOpenDays = DateUtility.getDaysBetween(systemWrapper.systemDate, accountOpenDate);
			int relOpenDays = DateUtility.getDaysBetween(systemWrapper.systemDate, relOpenDate);

			log.println("accountOpenDate= " + accountOpenDate + " // " + "relOpenDate= " + relOpenDate + " // "
					+ "accountOpenDays= " + accountOpenDays + " // " + "relOpenDays= " + relOpenDays + " // "
					+ "systemWrapper.systemDate= " + systemWrapper.systemDate);

			if (accountOpenDays < 60 && relOpenDays < 365) {
				customerType = "NTB";
			} else {
				customerType = "ETB";
			}
			log.println("customerType= " + customerType);
		} catch (SCBApplicationException e) {
			log.printErrorMessage(e);
		}
		return customerType;
	}

	/*
	 * convertNewFundTrackingToNewFundBalanceWrapper method used to set Tracking result to New Banlance wrapper
	 * 
	 * @param newFundTrackingWrapperList
	 * @param newFundBalanceWrapperResponse
	 * @param newFundBalanceDetailWrapperList
	 */
	public void convertNewFundTrackingToNewFundBalanceWrapper(List<NewFundTrackingWrapper> newFundTrackingWrapperList,
			NewFundBalanceWrapper newFundBalanceWrapperResponse, 
			List<NewFundBalanceDetailWrapper> newFundBalanceDetailWrapperList, Map<String, BigDecimal> totalAvailableBalanceMap,
			String profileId) {

			log.println("convertNewFundTrackingToNewFundBalanceWrapper method start");
			Set<String> newFundCurrencyCodeIterationSet =  new HashSet<>(); //repeatable currency for json
			
			if(newFundTrackingWrapperList != null ) {

			Map<String, Map<String, BigDecimal>> newFundInAndDayWiseTotalNewFundsSumMap = new NewFundUtility().getNewFundDetails(profileId);//KEYSTONEHK-360576
			log.println("NewFundBalanceBusinessHostBean : newFundInAndDayWiseTotalNewFundsSumMap= "+newFundInAndDayWiseTotalNewFundsSumMap);

					for (NewFundTrackingWrapper newFundTrackingWrapper : newFundTrackingWrapperList) {
						if(newFundCurrencyCodeIterationSet.contains(newFundTrackingWrapper.currencyCode)) {
							log.println("Repetable new Fund `same CurrencyCode  skip");
							continue;
						}
						NewFundBalanceDetailWrapper newFundBalanceDetailWrapper = new NewFundBalanceDetailWrapper();
						
				setNewFundBalanceDetailWrapper(newFundBalanceDetailWrapper,newFundTrackingWrapper,totalAvailableBalanceMap,
							newFundInAndDayWiseTotalNewFundsSumMap);
						newFundBalanceDetailWrapperList.add(newFundBalanceDetailWrapper);
						newFundCurrencyCodeIterationSet.add(newFundBalanceDetailWrapper.getCasaCurrencyCode());
				   }
				   log.println("NFTRCKG table - newFundBalanceDetailWrapperList.size= " + newFundBalanceDetailWrapperList.size());
				  // CurrencyCode not availble in 'NFTRCKG' table,but its under new fund
				  if(!totalAvailableBalanceMap.isEmpty() && !newFundCurrencyCodeIterationSet.isEmpty()) {
						for(Entry<String, BigDecimal> entry : totalAvailableBalanceMap.entrySet()) {
							log.println("newFundCurrencyCodeIterationSet//entry.getKey="+newFundCurrencyCodeIterationSet+"//"+entry.getKey());
							if(!newFundCurrencyCodeIterationSet.contains(entry.getKey())) {
									NewFundBalanceDetailWrapper newFundBalanceDetailWrapper = new NewFundBalanceDetailWrapper();
									newFundBalanceDetailWrapper.setCasaCurrencyCode(entry.getKey());
									newFundBalanceDetailWrapper.setTotalAvailableBalance(entry.getValue());
									newFundBalanceDetailWrapper.setTotalAvailableNewFund(BigDecimal.ZERO); //Assigning default value
									newFundBalanceDetailWrapper.setTotalNewFund(BigDecimal.ZERO); //Assigning default value
									newFundBalanceDetailWrapperList.add(newFundBalanceDetailWrapper);
							}
						}
						log.println("CurrencyCode not availble in 'NFTRCKG' table,but its under new fund"
								    +"newFundBalanceDetailWrapperList size="+newFundBalanceDetailWrapperList.size());
				  }
		 } else {
			 
			  if(!totalAvailableBalanceMap.isEmpty()) {
				  for(Entry<String, BigDecimal> entry : totalAvailableBalanceMap.entrySet()) {
					  NewFundBalanceDetailWrapper newFundBalanceDetailWrapper = new NewFundBalanceDetailWrapper();
					  newFundBalanceDetailWrapper.setCasaCurrencyCode(entry.getKey());
					  newFundBalanceDetailWrapper.setTotalAvailableBalance(entry.getValue());
					  newFundBalanceDetailWrapper.setTotalAvailableNewFund(BigDecimal.ZERO); //Assigning default value
					  newFundBalanceDetailWrapper.setTotalNewFund(BigDecimal.ZERO); //Assigning default value
					  newFundBalanceDetailWrapperList.add(newFundBalanceDetailWrapper);
				  }
			  }
		 }
		log.println("Final newFundBalanceDetailWrapperList.size= " + newFundBalanceDetailWrapperList.size());
	}
	public void setNewFundBalanceDetailWrapper(NewFundBalanceDetailWrapper newFundBalanceDetailWrapper,
			NewFundTrackingWrapper newFundTrackingWrapper,
			Map<String, BigDecimal> totalAvailableBalanceMap, 
			Map<String, Map<String, BigDecimal>> newFundInAndDayWiseTotalNewFundsSumMap) {
			
			newFundBalanceDetailWrapper.setCasaCurrencyCode(newFundTrackingWrapper.currencyCode);
			
			Map<String,BigDecimal> totalNewFundAndTotalAvailableNewFundMap = newFundInAndDayWiseTotalNewFundsSumMap.get(newFundTrackingWrapper.currencyCode);
			
			log.println("currencyCode : totalNewFundAndTotalAvailableNewFundMap= "+newFundTrackingWrapper.currencyCode +" : "
						+totalNewFundAndTotalAvailableNewFundMap 
					    +"totalAvailableBalanceMap= "+totalAvailableBalanceMap);
	
			if(!totalNewFundAndTotalAvailableNewFundMap.isEmpty() && totalNewFundAndTotalAvailableNewFundMap.get("TOTAL_NEWFUND") != null) {
				newFundBalanceDetailWrapper.setTotalNewFund(totalNewFundAndTotalAvailableNewFundMap.get("TOTAL_NEWFUND"));
			}else {
				newFundBalanceDetailWrapper.setTotalNewFund(BigDecimal.ZERO);
			}
			
			if(!totalNewFundAndTotalAvailableNewFundMap.isEmpty() && totalNewFundAndTotalAvailableNewFundMap.get("TOTAL_AVAILABLE_NEWFUND") != null ) {
				if(totalNewFundAndTotalAvailableNewFundMap.get("TOTAL_AVAILABLE_NEWFUND").signum() == -1) {
					newFundBalanceDetailWrapper.setTotalAvailableNewFund(BigDecimal.ZERO);
				} else {
					newFundBalanceDetailWrapper.setTotalAvailableNewFund(totalNewFundAndTotalAvailableNewFundMap.get("TOTAL_AVAILABLE_NEWFUND"));
				}
			}else {
				newFundBalanceDetailWrapper.setTotalAvailableNewFund(BigDecimal.ZERO);
			}
			
			if(totalAvailableBalanceMap !=null && !totalAvailableBalanceMap.isEmpty() && totalAvailableBalanceMap.get(newFundTrackingWrapper.currencyCode) != null ) {
				log.println("In setTotalAvailableBalance");
				newFundBalanceDetailWrapper.setTotalAvailableBalance(totalAvailableBalanceMap.get(newFundTrackingWrapper.currencyCode)); //total available balance
			}else {
				newFundBalanceDetailWrapper.setTotalAvailableBalance(BigDecimal.ZERO);
			}
			log.println("newFundBalanceDetailWrapper.totalNewFund=" + newFundBalanceDetailWrapper.getTotalNewFund() + " // "
						+"newFundBalanceDetailWrapper.TotalAvailableNewFund=" + newFundBalanceDetailWrapper.getTotalAvailableNewFund()+ " // "
						+"newFundBalanceDetailWrapper.getTotalAvailableBalance=" + newFundBalanceDetailWrapper.getTotalAvailableBalance());
			
			setNewFundBalanceDetailWrapperNegativeProcess(newFundBalanceDetailWrapper);
			
			log.println("After TotalAvailableNewFund > TotalAvailableBalance = TotalAvailableNewFund=" +newFundBalanceDetailWrapper.getTotalAvailableNewFund());
			
		}

	private void setNewFundBalanceDetailWrapperNegativeProcess(NewFundBalanceDetailWrapper newFundBalanceDetailWrapper) {
		
		if(newFundBalanceDetailWrapper.getTotalAvailableNewFund().compareTo(newFundBalanceDetailWrapper.getTotalAvailableBalance()) >= 0) {
			newFundBalanceDetailWrapper.setTotalAvailableNewFund(newFundBalanceDetailWrapper.getTotalAvailableBalance());
		}
		
		if(newFundBalanceDetailWrapper.getTotalAvailableNewFund().compareTo(newFundBalanceDetailWrapper.getTotalAvailableBalance()) >= 0) {
			
			 if(newFundBalanceDetailWrapper.getTotalAvailableBalance().signum() == 1) {
				 newFundBalanceDetailWrapper.setTotalAvailableNewFund(newFundBalanceDetailWrapper.getTotalAvailableBalance());
			 }
			 else {
				 newFundBalanceDetailWrapper.setTotalAvailableBalance(BigDecimal.ZERO);
			 }
		}
	}

	// CBRCPBD-28410 - Fresh funds changes start
	private FreshFundsBusinessParamWrapper fetchFreshFundsBPPWrapper() {
		FreshFundsBusinessParamWrapper freshFundsBPPWrapper = null;
		try {
			BusinessProcessParamCache businessProcessParamCache = BusinessProcessParamCache.getInstance(); 
			AbstractWrapper[] abstractWrappers = businessProcessParamCache.getProcessParameters(EBBSBusinessProcessConstants.FRESH_FUNDS);
			if(abstractWrappers!=null && abstractWrappers.length>0) {
				freshFundsBPPWrapper = (FreshFundsBusinessParamWrapper) abstractWrappers[0];
				log.println("fresh funds bpp "+freshFundsBPPWrapper);
			}
		}
		catch(Exception e) {
			log.println("Exception while trying to fetch BPP::FRESHFUNDS");
		}
		return freshFundsBPPWrapper;
	}
	public NewFundBalanceWrapper processBalanceBasedFreshFunds(FreshFundsBusinessParamWrapper freshFundsBPPWrapper,NewFundBalanceWrapper newFundInputWrapper ) throws SCBApplicationException, TechnicalComponentException {
		NewFundBalanceWrapper fundBalanceWrapper = new NewFundBalanceWrapper();
		fundBalanceWrapper.setProfileId(newFundInputWrapper.getProfileId());
		List<ErrorObject> errorList = new ArrayList<>();
		Object[] tupleObj = new Object[3];
		log.println("processBalanceBasedFreshFunds::FRESHFUNDS::SG");
		try{
			String currCode = newFundInputWrapper.getCasaCurrencyCode()!= null ? newFundInputWrapper.getCasaCurrencyCode().trim():null;
			fundBalanceWrapper.setCasaCurrencyCode(currCode);
			SystemWrapper systemWrapper = (SystemWrapper) StaticDataCache.getInstance().getSystemWrapper();
			log.println("FreshFunds SystemDate::"+systemWrapper.systemDate);
			Date prevBalCalcDate = fetchPrevBalCalculationDate(freshFundsBPPWrapper,systemWrapper.systemDate);
			List<Tuple> casas = freshFundsDAO.getActiveCasasByRelationshipNoCurrCode(newFundInputWrapper.getProfileId(), currCode,prevBalCalcDate);
			List<Tuple> deals = freshFundsDAO.getActiveDealsByRelationshipNoCurrCode(newFundInputWrapper.getProfileId(), currCode,prevBalCalcDate);
			List<Tuple> futureDeals = freshFundsDAO.getFutureDealsByRelationshipNoCurrCode(newFundInputWrapper.getProfileId(), currCode);
			if((casas == null || casas.isEmpty())&&(deals == null || deals.isEmpty())) {
				log.println("No Active Products for the Customer");
				errorList.add(new ErrorObject(ExceptionType.BUSINESS.getValue(),CASAError.FRESHFUNDS_NO_ACTIVE_PRODUCTS.getErrorCode(),
						CASAError.FRESHFUNDS_NO_ACTIVE_PRODUCTS.getErrorDescription(),CASAConstants.COMPONENT));
				fundBalanceWrapper.setErrorList(errorList);
				return fundBalanceWrapper;
			}
			tupleObj[0] = casas;
			tupleObj[1] = deals;
			tupleObj[2] = futureDeals;
			fundBalanceWrapper = calculateCasaDealBalances(tupleObj,freshFundsBPPWrapper,fundBalanceWrapper,prevBalCalcDate);
		}
		catch(Exception e) {
			log.printErrorMessage(e);
			throw new TechnicalComponentException(TechnicalErrors.TECHNICAL_ERROR.getErrorCode(),TechnicalErrors.TECHNICAL_ERROR.getErrorDescription(), CASAConstants.COMPONENT);
		}
		return fundBalanceWrapper;
	}
	private Date fetchPrevBalCalculationDate(FreshFundsBusinessParamWrapper freshFundsBusinessParamWrapper, Date systemDate) throws SCBApplicationException {
		Date prevBalDate = systemDate;
		log.println("NewFundBalanceBusinessHostBean::fetchPrevBalCalculationDate::");
		if(freshFundsBusinessParamWrapper.beforeDaysBalanceCount != null && freshFundsBusinessParamWrapper.beforeDaysBalanceCount.trim().length()>0) {
			prevBalDate = DateUtility.addDays(systemDate, -(Integer.parseInt(freshFundsBusinessParamWrapper.beforeDaysBalanceCount.trim())));
		}
		else {
			throw new SCBApplicationException("SG :: FRESHFUNDS beforeDaysBalanceCount BPP not set");
		}
		log.println("NewFundBalanceBusinessHostBean::fetchPrevBalCalculationDate::Date"+prevBalDate);
		return prevBalDate;
	}
	public NewFundBalanceWrapper calculateCasaDealBalances (Object[] tupleObject,FreshFundsBusinessParamWrapper freshFundsBPPWrapper,NewFundBalanceWrapper newFundBalWrapper,Date prevBalanceCalcDate) throws Exception {
		log.println("NewFundBalanceBusinessHostBean::calculateCasaDealBalances::");
		CASABalanceServiceHostInterface casaBalanceServiceHostInterface = null;
		List<Tuple> casaList = (List<Tuple>) tupleObject[0];
		ArrayList<ErrorObject> errorList = new ArrayList<ErrorObject>();
		HashMap<String, BigDecimal> totalCurrentBalanceMap = new HashMap<String,BigDecimal>();
		HashMap<String, BigDecimal> totalPastDatedBalanceMap = new HashMap<String,BigDecimal>();
		try {
			casaBalanceServiceHostInterface = (CASABalanceServiceHostInterface) SystemServiceProvider.lookup(CASAConstants.COMPONENT,
					CASAConstants.CASA_BALANCE_SERVICE_BEAN, CASAConstants.CASA_BALANCE_SERVICE_HOST);
		}
		catch (NamingException namingException) {
			errorList.add(new ErrorObject(ExceptionType.SYSTEM.getValue(), TechnicalErrors.NAMING_ERROR.getErrorCode(), TechnicalErrors.NAMING_ERROR.getErrorDescription(), "SYSTEM"));
			newFundBalWrapper.setErrorList(errorList);
			return newFundBalWrapper;
		}
		if (casaList != null && !casaList.isEmpty()) {
			for (Tuple tuple : casaList) {
				log.println("NewFundBalanceBusinessHostBean::calculateCasaDealBalances:: casa list not empty");
				String accountNo = StringUtility.trimString((String) tuple.get("ACCOUNTNO"));
				String currencyCode = StringUtility.trimString((String) tuple.get("CURRENCYCODE"));
				Date acOpenDate = (java.sql.Date) tuple.get("ACOPENDATE");
				BigDecimal statusFlag = tuple.get("STATUSFLAG") != null ? (BigDecimal) tuple.get("STATUSFLAG") : BigDecimal.ZERO;
				short statusFlagVal = statusFlag.shortValueExact();
				log.println("statusFlag "+statusFlag+" "+statusFlagVal);
				log.println("NewFundBalanceBusinessHostBean::calculateCasaDealBalances:: acOpenDate" +acOpenDate);
				BigDecimal casaFrontEndBalance = BigDecimal.ZERO;
				BigDecimal casaPastDatedEndBalance = BigDecimal.ZERO;
				log.println("NewFundBalanceBusinessHostBean::calculateCasaDealBalances:: ZERO value" +casaPastDatedEndBalance);
				try {
					if(statusFlagVal != EBBSConstants.CLOSED){
					casaFrontEndBalance = casaBalanceServiceHostInterface.getCasaBalanceByParams(accountNo, currencyCode, 'F', null);
					}
					log.println("NewFundBalanceBusinessHostBean::calculateCasaDealBalances::casaFrontEndBalance"+casaFrontEndBalance+"::"+currencyCode);
				} catch (SCBApplicationException | FinderException e) {
					log.printErrorMessage(e);
				}
				if(totalCurrentBalanceMap.containsKey(currencyCode)) {
					BigDecimal newBalance = totalCurrentBalanceMap.get(currencyCode).add(casaFrontEndBalance);
					totalCurrentBalanceMap.put(currencyCode, newBalance);
				}
				else {
					totalCurrentBalanceMap.put(currencyCode, casaFrontEndBalance);
				}
				try {
					casaPastDatedEndBalance = casaBalanceServiceHostInterface.getCasaBalanceByParams(accountNo, currencyCode, 'B', prevBalanceCalcDate);
					log.println("NewFundBalanceBusinessHostBean::calculateCasaDealBalances::casaPastDatedEndBalance"+casaPastDatedEndBalance);
				} catch (SCBApplicationException | FinderException e) {
					log.printErrorMessage(e);
				}
				if(totalPastDatedBalanceMap.containsKey(currencyCode)) {
					BigDecimal newBalance = totalPastDatedBalanceMap.get(currencyCode).add(casaPastDatedEndBalance);
					totalPastDatedBalanceMap.put(currencyCode, newBalance);
				}
				else {
					totalPastDatedBalanceMap.put(currencyCode, casaPastDatedEndBalance);
				}
			}
		}
		Object[] balancesMap = calculateDealBalances(tupleObject,freshFundsBPPWrapper,totalCurrentBalanceMap,totalPastDatedBalanceMap,prevBalanceCalcDate);
		boolean freshFundsExcFlag = freshFundsBPPWrapper.excludeFreshFundsDeposit !=null && "Y".equalsIgnoreCase(freshFundsBPPWrapper.excludeFreshFundsDeposit.trim()) ? true :false;
		populateResponseWrapper(newFundBalWrapper,totalCurrentBalanceMap,totalPastDatedBalanceMap,balancesMap,freshFundsExcFlag);
		return newFundBalWrapper;
	}
	private void populateResponseWrapper(NewFundBalanceWrapper fundBalResponseWrapper,HashMap<String, BigDecimal> currentFundAvailable, HashMap<String,BigDecimal> pastFundAvailable,Object[] exclusionBalances, boolean freshFundExcFlag) throws Exception {
		HashMap<String, BigDecimal> totalFreshFundsDealsBalanceMap = (HashMap<String, BigDecimal>) exclusionBalances[0];
		HashMap<String, BigDecimal> futureDatedDealsBalanceMap = (HashMap<String, BigDecimal>) exclusionBalances[1];
		ArrayList<NewFundBalanceDetailWrapper> detailWrapperList = new ArrayList<NewFundBalanceDetailWrapper>();
		fundBalResponseWrapper.setId(GlobalUniqueIdentifierUtility.getInstance().construct(
				SystemInstanceConstants.getResourceInstance(ResourceConstants.CASA_RESOURCE),
				SystemInstanceConstants.getCountryInstance(SystemProperties.getInstance().getCompanyID()),
				new String[] { fundBalResponseWrapper.getProfileId().trim() }));
		for(String currencyCode : currentFundAvailable.keySet()) {
			NewFundBalanceDetailWrapper detailWrapper = new NewFundBalanceDetailWrapper();
			BigDecimal totalFreshFund = currentFundAvailable.get(currencyCode);
			log.println("NewFundBalanceBusinessHostBean::populateResponseWrapper::currFund"+currencyCode+"::"+totalFreshFund);
			if(pastFundAvailable.containsKey(currencyCode)) {
				totalFreshFund =totalFreshFund.subtract(pastFundAvailable.get(currencyCode));
			}
			log.println("populateResponseWrapper::FreshFund"+currencyCode+"::"+totalFreshFund);
			if(freshFundExcFlag && totalFreshFundsDealsBalanceMap.containsKey(currencyCode)) {
				log.println("populateResponseWrapper::FreshFundBalanceAmount"+currencyCode+"::"+totalFreshFundsDealsBalanceMap.get(currencyCode));
				totalFreshFund = totalFreshFund.subtract(totalFreshFundsDealsBalanceMap.get(currencyCode));
			}
			if(futureDatedDealsBalanceMap.containsKey(currencyCode)) {
				log.println("populateResponseWrapper::FutureDatedBalanceAmount"+currencyCode+"::"+futureDatedDealsBalanceMap.get(currencyCode));
				totalFreshFund = totalFreshFund.subtract(futureDatedDealsBalanceMap.get(currencyCode));
			}
			log.println("populateResponseWrapper::FinalFreshFundBalanceAmount"+currencyCode+"::"+totalFreshFund);
			if(totalFreshFund.compareTo(BigDecimal.ZERO) < 0) {
				totalFreshFund = BigDecimal.ZERO;
			}
			int precision = BusinessInfo.getInstance().getCurrencyPrecision(currencyCode);
			totalFreshFund = totalFreshFund.setScale(precision, BigDecimal.ROUND_HALF_UP);
			detailWrapper.setCasaCurrencyCode(currencyCode);
			detailWrapper.setTotalAvailableNewFund(totalFreshFund);
			detailWrapperList.add(detailWrapper);
		}
		fundBalResponseWrapper.setNewFundBalanceDetailList(detailWrapperList);
	}
	private Object[] calculateDealBalances(Object[] tupleObj, FreshFundsBusinessParamWrapper freshFundsBPPWrapper,HashMap<String, BigDecimal> totalCurrentBalanceFunds,HashMap<String, BigDecimal> totalPastDatedFunds, Date prevBalanceCalcDate) {
		HashMap<String, BigDecimal> totalFreshFundsDealsBalanceMap = new HashMap<String,BigDecimal>();
		HashMap<String, BigDecimal> futureDatedDealsBalanceMap = new HashMap<String,BigDecimal>();
		List<Tuple> dealsList = (List<Tuple>) tupleObj[1];
		List<Tuple> futureDatedDeals = (List<Tuple>) tupleObj[2];
		Object[] obj = new Object[2];
		if (dealsList != null && !dealsList.isEmpty()) {
			for (Tuple tuple : dealsList) {
				log.println("NewFundBalanceBusinessHostBean::calculateDealBalances:: deal list not empty");
				String dealNo = StringUtility.trimString((String) tuple.get("DEALNO"));
				String dealCurrencyCode = StringUtility.trimString((String) tuple.get("DEALCURRCD"));
			//	BigDecimal dealsCurrentBalanceAmount = tuple.get("CURRENTPRINCIPAL") != null ? (BigDecimal) tuple.get("CURRENTPRINCIPAL") : BigDecimal.ZERO;
				BigDecimal dealsCurrentBalanceAmount =BigDecimal.ZERO;
				Date dealValueDate = (java.sql.Date) tuple.get("VALUEDT");
				BigDecimal rollOverCount = tuple.get("ROLLOVERCOUNT") != null ? (BigDecimal) tuple.get("ROLLOVERCOUNT") : BigDecimal.ZERO;
				Character freshFunds = tuple.get("FRESHFUNDSFLAG") != null ? (Character) tuple.get("FRESHFUNDSFLAG") : null;
				BigDecimal dealStatusFlag = tuple.get("STATUSFLAG") != null ? (BigDecimal) tuple.get("STATUSFLAG") : BigDecimal.ZERO;
				short dealStatusFlagVal = dealStatusFlag.shortValueExact();
				log.println("dealStatusFlag "+dealStatusFlag+" "+dealStatusFlagVal);
				Character dealCurrStatus = tuple.get("DEALCURRENTSTATUS") != null ? (Character) tuple.get("DEALCURRENTSTATUS") : null;
				if(dealStatusFlagVal != EBBSConstants.CLOSED && dealCurrStatus != null && dealCurrStatus != 'C' ) {
					dealsCurrentBalanceAmount = tuple.get("CURRENTPRINCIPAL") != null ? (BigDecimal) tuple.get("CURRENTPRINCIPAL") : BigDecimal.ZERO;
				}
				log.println("NewFundBalanceBusinessHostBean::calculateDealBalances::"+dealValueDate+"::"+rollOverCount+"::"+freshFunds);
				if(totalCurrentBalanceFunds.containsKey(dealCurrencyCode)) {
					BigDecimal newDealsBalanceAmt = totalCurrentBalanceFunds.get(dealCurrencyCode).add(dealsCurrentBalanceAmount);
					totalCurrentBalanceFunds.put(dealCurrencyCode, newDealsBalanceAmt);
				}
				else {
					totalCurrentBalanceFunds.put(dealCurrencyCode, dealsCurrentBalanceAmount);
				}
				DealInterestAccrualEntityKey dealInterestAccrualEntityKey = new DealInterestAccrualEntityKey(dealNo,prevBalanceCalcDate);
				boolean flag = calculatePastDatedDealBalanceSum(totalPastDatedFunds,dealCurrencyCode,dealInterestAccrualEntityKey);
				populateFreshFundsBalance(totalFreshFundsDealsBalanceMap,dealCurrencyCode,freshFunds,flag,dealsCurrentBalanceAmount);
			}
		}
		calculateFutureDatedDealFunds(futureDatedDeals,futureDatedDealsBalanceMap);
		obj[0] = totalFreshFundsDealsBalanceMap;
		obj[1] = futureDatedDealsBalanceMap;
		return obj;
	}
	public void populateFreshFundsBalance(HashMap<String, BigDecimal> totalFreshFundsDealsBalancesMap, String currCode, Character freshFundsIndicator,boolean flag, BigDecimal dealsCurrentBalance) {
		log.println("populateFreshFundsBalance::"+freshFundsIndicator+" "+flag);
		if(freshFundsIndicator != null && freshFundsIndicator == 'Y' && !flag) {
			log.println("populateFreshFundsBalance1::"+freshFundsIndicator+" "+flag);
			if(totalFreshFundsDealsBalancesMap.containsKey(currCode)) {
				BigDecimal freshFundsBalanceAmt = totalFreshFundsDealsBalancesMap.get(currCode).add(dealsCurrentBalance);
				totalFreshFundsDealsBalancesMap.put(currCode, freshFundsBalanceAmt);
			}
			else {
				totalFreshFundsDealsBalancesMap.put(currCode, dealsCurrentBalance);
			}
		}
	}
	public void calculateFutureDatedDealFunds(List<Tuple> futureDatedDeals,HashMap<String, BigDecimal> futureDatedFunds) {
		try{
			if(futureDatedDeals != null && futureDatedDeals.size()>0) {
				for (Tuple tuple : futureDatedDeals) {
					log.println("NewFundBalanceBusinessHostBean::calculateFutureDatedDealFunds:: deal list not empty");
					String dealNo = StringUtility.trimString((String) tuple.get("DEALNO"));
					String dealCurrencyCode = StringUtility.trimString((String) tuple.get("DEALCURRCD"));
					BigDecimal futureDealAmount = tuple.get("DEALAMT") != null ? (BigDecimal) tuple.get("DEALAMT") : BigDecimal.ZERO;
					log.println("NewFundBalanceBusinessHostBean::calculateFutureDatedDealFunds::"+dealNo+"::"+dealCurrencyCode+"::"+futureDealAmount);
					if(futureDatedFunds.containsKey(dealCurrencyCode)) {
						BigDecimal updatedFutureDealBalance = futureDatedFunds.get(dealCurrencyCode).add(futureDealAmount);
						futureDatedFunds.put(dealCurrencyCode, updatedFutureDealBalance);
					}
					else {
						futureDatedFunds.put(dealCurrencyCode, futureDealAmount);
					}
				}
			}
			else {
				log.println("No future dated deals found::");
			}
		}
		catch(Exception e) {
			log.printErrorMessage(e);
		}
	}
	public boolean  calculatePastDatedDealBalanceSum(HashMap<String, BigDecimal> totalPastDatedBalanceMap, String dealCurrCode,DealInterestAccrualEntityKey dealIntAclEntityKey) {
		log.println("NewFundBalanceBusinessHostBean::calculatePastDatedDealBalanceSum");
		boolean dlIntAclEntryFlag = false;
		try{
			DealInterestAccrualWrapper dealInterestAccrualWrapper = getDealWrapperByKey(dealIntAclEntityKey);
			BigDecimal pastDealBalance = dealInterestAccrualWrapper.dealAmount != null ? dealInterestAccrualWrapper.dealAmount:BigDecimal.ZERO;
			dlIntAclEntryFlag = true;
			log.println("NewFundBalanceBusinessHostBean::calculatePastDatedDealBalanceSum"+pastDealBalance);
			if(totalPastDatedBalanceMap.containsKey(dealCurrCode)) {
				BigDecimal newDealsBalance = totalPastDatedBalanceMap.get(dealCurrCode).add(pastDealBalance);
				totalPastDatedBalanceMap.put(dealCurrCode, newDealsBalance);
			}
			else {
				totalPastDatedBalanceMap.put(dealCurrCode, pastDealBalance);
			}
		}
		catch(Exception e) {
			log.println("DLINTACL data not found::dealNo"+dealIntAclEntityKey.dealNo+"::dealDate"+dealIntAclEntityKey.date);
		}
		return dlIntAclEntryFlag;
	}
	public DealInterestAccrualEntityHome getDealInterestAccrualEntityHome() throws  FinderException {
		try{
			if(dealInterestAccrualEntityHome == null)
				dealInterestAccrualEntityHome = (DealInterestAccrualEntityHome) EntityBeanLookupAdaptor.getEntityLookup(EBBSConstants.EBBS_APPLICATION + "/DealInterestAccrualEntity","scb.business.edeals.factory.MMKDealsOpicsBusinessDAOFactory");
		} catch (SCBApplicationException e) {
			throw new FinderException(e.getMessage());
		}
		return dealInterestAccrualEntityHome;
	}
	public DealInterestAccrualWrapper getDealWrapperByKey(DealInterestAccrualEntityKey dealInterestAccrualEntityKey) throws FinderException {
		dealInterestAccrualEntityHome= getDealInterestAccrualEntityHome();
		return (DealInterestAccrualWrapper) dealInterestAccrualEntityHome.findByPrimaryKey(dealInterestAccrualEntityKey).getWrapper();
	}
	// CBRCPBD-28410 - Fresh funds changes end
}