org.mifos.framework.struts.action.BaseAction.java Source code

Java tutorial

Introduction

Here is the source code for org.mifos.framework.struts.action.BaseAction.java

Source

/*
 * Copyright (c) 2005-2011 Grameen Foundation USA
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * See also http://www.apache.org/licenses/LICENSE-2.0.html for an
 * explanation of the license and how it is applied.
 */

package org.mifos.framework.struts.action;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.struts.Globals;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.actions.DispatchAction;
import org.hibernate.HibernateException;
import org.mifos.accounts.acceptedpaymenttype.persistence.LegacyAcceptedPaymentTypeDao;
import org.mifos.accounts.fees.persistence.FeeDao;
import org.mifos.accounts.fund.persistence.FundDao;
import org.mifos.accounts.fund.servicefacade.FundServiceFacade;
import org.mifos.accounts.loan.persistance.LoanDao;
import org.mifos.accounts.penalties.persistence.PenaltyDao;
import org.mifos.accounts.persistence.LegacyAccountDao;
import org.mifos.accounts.productdefinition.persistence.LoanProductDao;
import org.mifos.accounts.productdefinition.persistence.SavingsProductDao;
import org.mifos.accounts.savings.persistence.SavingsDao;
import org.mifos.accounts.servicefacade.AccountServiceFacade;
import org.mifos.application.admin.servicefacade.CheckListServiceFacade;
import org.mifos.application.admin.servicefacade.FeeServiceFacade;
import org.mifos.application.admin.servicefacade.HolidayServiceFacade;
import org.mifos.application.admin.servicefacade.InvalidDateException;
import org.mifos.application.admin.servicefacade.MonthClosingServiceFacade;
import org.mifos.application.admin.servicefacade.OfficeServiceFacade;
import org.mifos.application.admin.servicefacade.PersonnelServiceFacade;
import org.mifos.application.admin.system.ShutdownManager;
import org.mifos.application.importexport.servicefacade.ImportTransactionsServiceFacade;
import org.mifos.application.master.business.MifosCurrency;
import org.mifos.application.master.persistence.LegacyMasterDao;
import org.mifos.application.servicefacade.ApplicationContextProvider;
import org.mifos.application.servicefacade.CenterServiceFacade;
import org.mifos.application.servicefacade.ClientServiceFacade;
import org.mifos.application.servicefacade.CustomerServiceFacade;
import org.mifos.application.servicefacade.GroupServiceFacade;
import org.mifos.application.servicefacade.LoanAccountServiceFacade;
import org.mifos.application.servicefacade.LoanServiceFacade;
import org.mifos.application.servicefacade.MeetingServiceFacade;
import org.mifos.application.servicefacade.NewLoginServiceFacade;
import org.mifos.application.servicefacade.SavingsServiceFacade;
import org.mifos.application.util.helpers.ActionForwards;
import org.mifos.application.util.helpers.EntityType;
import org.mifos.config.AccountingRules;
import org.mifos.config.persistence.ApplicationConfigurationDao;
import org.mifos.customers.office.persistence.OfficeDao;
import org.mifos.customers.persistence.CustomerDao;
import org.mifos.customers.personnel.persistence.LegacyPersonnelDao;
import org.mifos.customers.personnel.persistence.PersonnelDao;
import org.mifos.framework.business.AbstractBusinessObject;
import org.mifos.framework.business.LogUtils;
import org.mifos.framework.business.service.BusinessService;
import org.mifos.framework.business.util.helpers.MethodNameConstants;
import org.mifos.framework.components.audit.business.service.AuditBusinessService;
import org.mifos.framework.components.audit.util.helpers.AuditConstants;
import org.mifos.framework.components.audit.util.helpers.AuditInterceptor;
import org.mifos.framework.components.batchjobs.MifosBatchJob;
import org.mifos.framework.components.fieldConfiguration.persistence.LegacyFieldConfigurationDao;
import org.mifos.framework.exceptions.ApplicationException;
import org.mifos.framework.exceptions.PageExpiredException;
import org.mifos.framework.exceptions.ServiceException;
import org.mifos.framework.exceptions.SystemException;
import org.mifos.framework.exceptions.ValueObjectConversionException;
import org.mifos.framework.hibernate.helper.StaticHibernateUtil;
import org.mifos.framework.util.DateTimeService;
import org.mifos.framework.util.LocalizationConverter;
import org.mifos.framework.util.helpers.CloseSession;
import org.mifos.framework.util.helpers.Constants;
import org.mifos.framework.util.helpers.ConversionUtil;
import org.mifos.framework.util.helpers.DateUtils;
import org.mifos.framework.util.helpers.Flow;
import org.mifos.framework.util.helpers.FlowManager;
import org.mifos.framework.util.helpers.Money;
import org.mifos.framework.util.helpers.ServletUtils;
import org.mifos.framework.util.helpers.SessionUtils;
import org.mifos.framework.util.helpers.TransactionDemarcate;
import org.mifos.reports.admindocuments.persistence.LegacyAdminDocAccStateMixDao;
import org.mifos.reports.admindocuments.persistence.LegacyAdminDocumentDao;
import org.mifos.security.AuthenticationAuthorizationServiceFacade;
import org.mifos.security.login.util.helpers.LoginConstants;
import org.mifos.security.rolesandpermission.persistence.LegacyRolesPermissionsDao;
import org.mifos.security.util.UserContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class BaseAction extends DispatchAction {

    private static final Logger logger = LoggerFactory.getLogger(BaseAction.class);

    protected BusinessService getService() throws ServiceException {
        return null;
    }

    protected PersonnelDao personnelDao;
    protected OfficeDao officeDao;
    protected CustomerDao customerDao;
    protected SavingsDao savingsDao;
    protected LoanDao loanDao;
    protected LoanProductDao loanProductDao;
    protected SavingsProductDao savingsProductDao;
    protected FeeDao feeDao;
    protected PenaltyDao penaltyDao;
    protected FundDao fundDao;
    protected ApplicationConfigurationDao applicationConfigurationDao;

    protected NewLoginServiceFacade loginServiceFacade;
    protected PersonnelServiceFacade personnelServiceFacade;
    protected CustomerServiceFacade customerServiceFacade;
    protected CenterServiceFacade centerServiceFacade;
    protected GroupServiceFacade groupServiceFacade;
    protected ClientServiceFacade clientServiceFacade;
    protected AccountServiceFacade accountServiceFacade;
    protected MeetingServiceFacade meetingServiceFacade;
    protected LoanAccountServiceFacade loanAccountServiceFacade;
    protected MonthClosingServiceFacade monthClosingServiceFacade;
    protected SavingsServiceFacade savingsServiceFacade;
    protected HolidayServiceFacade holidayServiceFacade;
    protected OfficeServiceFacade officeServiceFacade;
    protected FeeServiceFacade feeServiceFacade;
    protected FundServiceFacade fundServiceFacade;
    protected AuthenticationAuthorizationServiceFacade authenticationAuthorizationServiceFacade;
    protected ImportTransactionsServiceFacade importTransactionsServiceFacade;
    protected CheckListServiceFacade checkListServiceFacade;

    protected LegacyMasterDao legacyMasterDao;
    protected LegacyAdminDocumentDao legacyAdminDocumentDao;
    protected LegacyFieldConfigurationDao legacyFieldConfigurationDao;
    protected LegacyAdminDocAccStateMixDao legacyAdminDocAccStateMixDao;
    protected LegacyRolesPermissionsDao legacyRolesPermissionsDao;
    protected LegacyAccountDao legacyAccountDao;
    protected LegacyAcceptedPaymentTypeDao legacyAcceptedPaymentTypeDao;
    protected LegacyPersonnelDao legacyPersonnelDao;

    // non domain app
    protected LoanServiceFacade loanServiceFacade;

    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {

        configureDaoBeans();
        configureServiceFacadeBeans();
        configureLegacyDaoBeans();

        if (MifosBatchJob.isBatchJobRunningThatRequiresExclusiveAccess()) {
            return logout(mapping, request);
        }
        ShutdownManager shutdownManager = (ShutdownManager) ServletUtils.getGlobal(request,
                ShutdownManager.class.getName());
        if (shutdownManager.isShutdownDone()) {
            return shutdown(mapping, request);
        }
        if (shutdownManager.isInShutdownCountdownNotificationThreshold()) {
            request.setAttribute("shutdownIsImminent", true);
        }
        TransactionDemarcate annotation = getTransaction(form, request);
        preExecute(form, request, annotation);
        ActionForward forward = super.execute(mapping, form, request, response);
        // TODO: passing 'true' to postExecute guarantees that the session will
        // be closed still working through resolving issues related to enforcing
        // this postExecute(request, annotation, true);
        postExecute(request, annotation, isCloseSessionAnnotationPresent(form, request));
        return forward;
    }

    private <T extends Object> T getBean(Class<T> clazz) {
        return ApplicationContextProvider.getBean(clazz);
    }

    private void configureLegacyDaoBeans() {
        this.legacyMasterDao = getBean(LegacyMasterDao.class);
        this.legacyAdminDocumentDao = getBean(LegacyAdminDocumentDao.class);
        this.legacyFieldConfigurationDao = getBean(LegacyFieldConfigurationDao.class);
        this.legacyAdminDocAccStateMixDao = getBean(LegacyAdminDocAccStateMixDao.class);
        this.legacyRolesPermissionsDao = getBean(LegacyRolesPermissionsDao.class);
        this.legacyAccountDao = getBean(LegacyAccountDao.class);
        this.legacyAcceptedPaymentTypeDao = getBean(LegacyAcceptedPaymentTypeDao.class);
        this.legacyPersonnelDao = getBean(LegacyPersonnelDao.class);
    }

    private void configureServiceFacadeBeans() {
        this.loginServiceFacade = getBean(NewLoginServiceFacade.class);
        this.personnelServiceFacade = getBean(PersonnelServiceFacade.class);
        this.customerServiceFacade = getBean(CustomerServiceFacade.class);
        this.centerServiceFacade = getBean(CenterServiceFacade.class);
        this.groupServiceFacade = getBean(GroupServiceFacade.class);
        this.clientServiceFacade = getBean(ClientServiceFacade.class);
        this.accountServiceFacade = getBean(AccountServiceFacade.class);
        this.meetingServiceFacade = getBean(MeetingServiceFacade.class);
        this.loanServiceFacade = getBean(LoanServiceFacade.class);
        this.loanAccountServiceFacade = getBean(LoanAccountServiceFacade.class);
        this.monthClosingServiceFacade = getBean(MonthClosingServiceFacade.class);
        this.holidayServiceFacade = getBean(HolidayServiceFacade.class);
        this.officeServiceFacade = getBean(OfficeServiceFacade.class);
        this.feeServiceFacade = getBean(FeeServiceFacade.class);
        this.fundServiceFacade = getBean(FundServiceFacade.class);
        this.savingsServiceFacade = getBean(SavingsServiceFacade.class);
        this.authenticationAuthorizationServiceFacade = getBean(AuthenticationAuthorizationServiceFacade.class);
        this.importTransactionsServiceFacade = getBean(ImportTransactionsServiceFacade.class);
        this.checkListServiceFacade = getBean(CheckListServiceFacade.class);
    }

    private void configureDaoBeans() {
        this.personnelDao = getBean(PersonnelDao.class);
        this.officeDao = getBean(OfficeDao.class);
        this.customerDao = getBean(CustomerDao.class);
        this.savingsDao = getBean(SavingsDao.class);
        this.loanDao = getBean(LoanDao.class);
        this.loanProductDao = getBean(LoanProductDao.class);
        this.savingsProductDao = getBean(SavingsProductDao.class);
        this.feeDao = getBean(FeeDao.class);
        this.penaltyDao = getBean(PenaltyDao.class);
        this.fundDao = getBean(FundDao.class);
        this.applicationConfigurationDao = getBean(ApplicationConfigurationDao.class);
    }

    protected void preExecute(ActionForm actionForm, HttpServletRequest request, TransactionDemarcate annotation)
            throws SystemException, ApplicationException {
        if (null != request.getParameter(Constants.CURRENTFLOWKEY)) {
            request.setAttribute(Constants.CURRENTFLOWKEY, request.getParameter(Constants.CURRENTFLOWKEY));
        }

        preHandleTransaction(request, annotation);
        UserContext userContext = (UserContext) request.getSession().getAttribute(Constants.USER_CONTEXT_KEY);
        Locale locale = getLocale(userContext);
        if (!skipActionFormToBusinessObjectConversion(request.getParameter("method"))) {
            try {
                AbstractBusinessObject businessObject = getBusinessObjectFromSession(request);
                ConversionUtil.populateBusinessObject(actionForm, businessObject, locale);
            } catch (ValueObjectConversionException e) {
                logger.debug("Value object conversion exception while validating BusinessObject: "
                        + new LogUtils().getStackTrace(e));
            }
        }
    }

    @SuppressWarnings("unchecked")
    protected TransactionDemarcate getTransaction(@SuppressWarnings("unused") ActionForm actionForm,
            HttpServletRequest request) {
        TransactionDemarcate annotation = null;
        try {
            String methodName = request.getParameter(MethodNameConstants.METHOD);
            Method methodToExecute = this.clazz.getMethod(methodName, new Class[] { ActionMapping.class,
                    ActionForm.class, HttpServletRequest.class, HttpServletResponse.class });
            annotation = methodToExecute.getAnnotation(TransactionDemarcate.class);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
        return annotation;
    }

    @SuppressWarnings("unchecked")
    protected boolean isCloseSessionAnnotationPresent(@SuppressWarnings("unused") ActionForm actionForm,
            HttpServletRequest request) {
        boolean isAnnotationPresent = false;
        try {
            String methodName = request.getParameter(MethodNameConstants.METHOD);
            Method methodToExecute = this.clazz.getMethod(methodName, new Class[] { ActionMapping.class,
                    ActionForm.class, HttpServletRequest.class, HttpServletResponse.class });
            isAnnotationPresent = methodToExecute.isAnnotationPresent(CloseSession.class);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
        return isAnnotationPresent;
    }

    protected void preHandleTransaction(HttpServletRequest request, TransactionDemarcate annotation)
            throws PageExpiredException {
        if (null != annotation && annotation.saveToken()) {
            createToken(request);
        } else if ((null != annotation && annotation.validateAndResetToken())
                || (null != annotation && annotation.joinToken())) {
            joinToken(request);
        } else if (null != annotation && annotation.conditionToken()) {
            String flowKey = (String) request.getAttribute(Constants.CURRENTFLOWKEY);
            if (flowKey == null) {
                createToken(request);
            } else {
                joinToken(request);
            }

        }
    }

    private void createToken(HttpServletRequest request) {
        String flowKey = String.valueOf(new DateTimeService().getCurrentDateTime().getMillis());
        FlowManager flowManager = (FlowManager) request.getSession().getAttribute(Constants.FLOWMANAGER);
        if (flowManager == null) {
            flowManager = new FlowManager();
            request.getSession(false).setAttribute(Constants.FLOWMANAGER, flowManager);
        }
        flowManager.addFLow(flowKey, new Flow(), this.clazz.getName());
        request.setAttribute(Constants.CURRENTFLOWKEY, flowKey);

    }

    private void joinToken(HttpServletRequest request) throws PageExpiredException {
        String flowKey = request.getParameter(Constants.CURRENTFLOWKEY);
        if (null == flowKey) {
            flowKey = (String) request.getAttribute(Constants.CURRENTFLOWKEY);
        }
        FlowManager flowManager = (FlowManager) request.getSession().getAttribute(Constants.FLOWMANAGER);
        if (flowKey == null || !flowManager.isFlowValid(flowKey)) {
            throw new PageExpiredException("no flow for key " + flowKey);
        }

    }

    protected void postHandleTransaction(HttpServletRequest request, TransactionDemarcate annotation)
            throws SystemException {
        if (null != annotation && annotation.validateAndResetToken()) {
            FlowManager flowManager = (FlowManager) request.getSession().getAttribute(Constants.FLOWMANAGER);
            flowManager.removeFlow((String) request.getAttribute(Constants.CURRENTFLOWKEY));
            request.setAttribute(Constants.CURRENTFLOWKEY, null);
        }
    }

    protected void postExecute(HttpServletRequest request, TransactionDemarcate annotation, boolean closeSession)
            throws ApplicationException, SystemException {
        // do cleanup here
        if (startSession()) {
            try {
                StaticHibernateUtil.commitTransaction();
                postHandleTransaction(request, annotation);
            } catch (HibernateException he) {
                he.printStackTrace();
                StaticHibernateUtil.rollbackTransaction();
                throw new ApplicationException(he);
            }
        } else {
            postHandleTransaction(request, annotation);
        }

        if (closeSession) {
            // StaticHibernateUtil.flushAndCloseSession();
            StaticHibernateUtil.closeSession();
        }
    }

    protected boolean isNewBizRequired(HttpServletRequest request) throws ServiceException {
        if (sessionHasBusinessKey(request)) {
            return serviceReturnsBusinessObject() && isTypeOfBusinessKeyDifferentToThatFromService(request);
        }
        return true;
    }

    private boolean serviceReturnsBusinessObject() throws ServiceException {
        return getService().getBusinessObject(null) != null;
    }

    private boolean isTypeOfBusinessKeyDifferentToThatFromService(HttpServletRequest request)
            throws ServiceException {
        return !getClassNameOfBusinessKeyAttribute(request)
                .equalsIgnoreCase(getClassNameOfBusinessObjectFromService());
    }

    private boolean sessionHasBusinessKey(HttpServletRequest request) {
        return request.getSession().getAttribute(Constants.BUSINESS_KEY) != null;
    }

    private String getClassNameOfBusinessObjectFromService() throws ServiceException {
        return getService().getBusinessObject(null).getClass().getName();
    }

    private String getClassNameOfBusinessKeyAttribute(HttpServletRequest request) {
        return request.getSession().getAttribute(Constants.BUSINESS_KEY).getClass().getName();
    }

    private AbstractBusinessObject getBusinessObjectFromSession(HttpServletRequest request)
            throws ServiceException {
        AbstractBusinessObject object = null;
        if (isNewBizRequired(request)) {
            UserContext userContext = (UserContext) request.getSession().getAttribute("UserContext");
            object = getService().getBusinessObject(userContext);
            request.getSession().setAttribute(Constants.BUSINESS_KEY, object);
        } else {
            object = (AbstractBusinessObject) request.getSession().getAttribute(Constants.BUSINESS_KEY);
        }
        return object;
    }

    protected Locale getLocale(UserContext userContext) {
        Locale locale = null;
        if (userContext != null) {
            locale = userContext.getCurrentLocale();
        }

        return locale;
    }

    protected boolean startSession() {
        return true;
    }

    /**
     * This should return true if we don't want to the automatic conversion of
     * forms to business objects (for example, if the data from the form ends up in several business objects)
     */
    protected boolean skipActionFormToBusinessObjectConversion(@SuppressWarnings("unused") String method) {
        return true;
    }

    protected UserContext getUserContext(HttpServletRequest request) {
        return (UserContext) SessionUtils.getAttribute(Constants.USER_CONTEXT_KEY, request.getSession());
    }

    protected Short getShortValue(String str) {
        return StringUtils.isNotBlank(str) ? Short.valueOf(str) : null;
    }

    protected Integer getIntegerValue(String str) {
        return StringUtils.isNotBlank(str) ? Integer.valueOf(str) : null;
    }

    protected Double getDoubleValue(String str) {
        return StringUtils.isNotBlank(str) ? new LocalizationConverter().getDoubleValueForCurrentLocale(str) : null;
    }

    protected String getStringValue(Integer value) {
        return value != null ? String.valueOf(value) : null;
    }

    protected String getStringValue(Short value) {
        return value != null ? String.valueOf(value) : null;
    }

    protected String getStringValue(Money value) {
        return value != null ? String.valueOf(value) : null;
    }

    protected String getStringValue(boolean value) {
        if (value) {
            return "1";
        }
        return "0";
    }

    protected String getDoubleStringForMoney(Double dNumber) {
        return dNumber != null ? new LocalizationConverter().getDoubleStringForMoney(dNumber) : null;
    }

    protected String getDoubleStringForInterest(Double dNumber) {
        return dNumber != null ? new LocalizationConverter().getDoubleStringForInterest(dNumber) : null;
    }

    protected Date getDateFromString(String strDate, Locale locale) throws InvalidDateException {
        Date date = null;
        if (StringUtils.isNotBlank(strDate)) {
            date = new Date(DateUtils.getLocaleDate(locale, strDate).getTime());
        }
        return date;
    }

    protected void setInitialObjectForAuditLogging(Object object) {
        StaticHibernateUtil.getSessionTL();
        ((AuditInterceptor) StaticHibernateUtil.getInterceptor()).createInitialValueMap(object);
    }

    private ActionForward logout(ActionMapping mapping, HttpServletRequest request) {
        request.getSession(false).invalidate();
        ActionErrors error = new ActionErrors();
        error.add(LoginConstants.BATCH_JOB_RUNNING,
                new ActionMessage(messages.getMessage(LoginConstants.BATCH_JOB_RUNNING,
                        "You have been logged out of the system because batch jobs are running.")));
        request.setAttribute(Globals.ERROR_KEY, error);
        return mapping.findForward(ActionForwards.load_main_page.toString());
    }

    private ActionForward shutdown(ActionMapping mapping, HttpServletRequest request) {
        request.getSession(false).invalidate();
        ActionErrors error = new ActionErrors();
        error.add(LoginConstants.SHUTDOWN, new ActionMessage(messages.getMessage(LoginConstants.SHUTDOWN,
                "You have been logged out of the system because Mifos is shutting down.")));
        request.setAttribute(Globals.ERROR_KEY, error);
        return mapping.findForward(ActionForwards.load_main_page.toString());
    }

    @TransactionDemarcate(joinToken = true)
    public ActionForward loadChangeLog(ActionMapping mapping, @SuppressWarnings("unused") ActionForm form,
            HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) throws Exception {

        Short entityType = EntityType
                .getEntityValue(request.getParameter(AuditConstants.ENTITY_TYPE).toUpperCase());
        Integer entityId = Integer.valueOf(request.getParameter(AuditConstants.ENTITY_ID));

        // FIXME - keithw - when replacing BaseActions loadChangeLog functionality for given entity when doing spring/ftl
        // see CenterServiceFacade.retrieveChangeLogs for example.
        AuditBusinessService auditBusinessService = new AuditBusinessService();
        request.getSession().setAttribute(AuditConstants.AUDITLOGRECORDS,
                auditBusinessService.getAuditLogRecords(entityType, entityId));

        return mapping.findForward(
                AuditConstants.VIEW + request.getParameter(AuditConstants.ENTITY_TYPE) + AuditConstants.CHANGE_LOG);
    }

    @TransactionDemarcate(saveToken = true)
    public ActionForward cancelChangeLog(ActionMapping mapping, @SuppressWarnings("unused") ActionForm form,
            HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
        return mapping.findForward(AuditConstants.CANCEL + request.getParameter(AuditConstants.ENTITY_TYPE)
                + AuditConstants.CHANGE_LOG);
    }

    protected void checkVersionMismatch(Integer oldVersionNum, Integer newVersionNum) throws ApplicationException {
        if (!oldVersionNum.equals(newVersionNum)) {
            throw new ApplicationException(Constants.ERROR_VERSION_MISMATCH);
        }
    }

    protected MifosCurrency getCurrency(Short currencyId) {
        MifosCurrency currency;
        if (currencyId == null) {
            // Currency is passed from Form only for Loan (Amount) Fees in multi-currency settings
            currency = Money.getDefaultCurrency();
        } else {
            currency = AccountingRules.getCurrencyByCurrencyId(currencyId);
        }
        return currency;
    }

    public void setLoanServiceFacade(LoanServiceFacade loanServiceFacade) {
        this.loanServiceFacade = loanServiceFacade;
    }

    public void setLoanAccountServiceFacade(LoanAccountServiceFacade loanAccountServiceFacade) {
        this.loanAccountServiceFacade = loanAccountServiceFacade;
    }
}