org.mifos.accounts.struts.action.ApplyAdjustment.java Source code

Java tutorial

Introduction

Here is the source code for org.mifos.accounts.struts.action.ApplyAdjustment.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.accounts.struts.action;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

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

import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.mifos.accounts.business.AccountBO;
import org.mifos.accounts.business.AccountPaymentEntity;
import org.mifos.accounts.business.AdjustablePaymentDto;
import org.mifos.accounts.business.service.AccountBusinessService;
import org.mifos.accounts.loan.business.LoanBO;
import org.mifos.accounts.productdefinition.util.helpers.InterestType;
import org.mifos.accounts.struts.actionforms.AccountApplyPaymentActionForm;
import org.mifos.accounts.struts.actionforms.ApplyAdjustmentActionForm;
import org.mifos.application.master.util.helpers.MasterConstants;
import org.mifos.application.servicefacade.ApplicationContextProvider;
import org.mifos.application.servicefacade.GroupLoanAccountServiceFacade;
import org.mifos.application.servicefacade.ListItem;
import org.mifos.core.MifosRuntimeException;
import org.mifos.dto.domain.AdjustedPaymentDto;
import org.mifos.dto.domain.GroupIndividualLoanDto;
import org.mifos.dto.screen.AccountPaymentDto;
import org.mifos.dto.screen.GroupLoanMemberAdjustmentDto;
import org.mifos.framework.business.service.BusinessService;
import org.mifos.framework.exceptions.ApplicationException;
import org.mifos.framework.exceptions.ServiceException;
import org.mifos.framework.struts.action.BaseAction;
import org.mifos.framework.util.helpers.CloseSession;
import org.mifos.framework.util.helpers.Constants;
import org.mifos.framework.util.helpers.Money;
import org.mifos.framework.util.helpers.SessionUtils;
import org.mifos.framework.util.helpers.TransactionDemarcate;
import org.mifos.security.util.UserContext;

/**
 * This is the action class for applying adjustment. This action is to be merged
 * with AccountAction once an AccountAction for M2 is done.
 */
public class ApplyAdjustment extends BaseAction {

    private GroupLoanAccountServiceFacade groupLoanService;

    public ApplyAdjustment() {
        this.groupLoanService = ApplicationContextProvider.getBean(GroupLoanAccountServiceFacade.class);
    }

    @Override
    protected BusinessService getService() throws ServiceException {
        return new AccountBusinessService();
    }

    @TransactionDemarcate(joinToken = true)
    public ActionForward editAdjustment(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
        ApplyAdjustmentActionForm appAdjustActionForm = (ApplyAdjustmentActionForm) form;
        boolean isRevert = Boolean.parseBoolean(request.getParameter(Constants.ADJUSTMENT_IS_REVERT));
        appAdjustActionForm.setAdjustcheckbox(isRevert);

        request.setAttribute("method", "loadAdjustment");
        return mapping.findForward("loadadjustment_success");
    }

    @TransactionDemarcate(joinToken = true)
    public ActionForward loadAdjustment(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
        ApplyAdjustmentActionForm appAdjustActionForm = (ApplyAdjustmentActionForm) form;
        AccountBO accnt = getBizService().findBySystemId(appAdjustActionForm.getGlobalAccountNum());
        SessionUtils.setAttribute(Constants.BUSINESS_KEY, accnt, request);
        request.setAttribute("method", "loadAdjustment");

        UserContext userContext = getUserContext(request);
        SessionUtils.setCollectionAttribute(MasterConstants.PAYMENT_TYPE,
                this.accountServiceFacade.constructPaymentTypeListForLoanRepayment(userContext.getLocaleId()),
                request);

        AccountPaymentEntity payment = null;
        if (request.getParameter(Constants.ADJ_TYPE_KEY) != null
                && request.getParameter(Constants.ADJ_TYPE_KEY).equals(Constants.ADJ_SPECIFIC)) {
            Integer paymentId = appAdjustActionForm.getPaymentId();
            payment = accnt.findPaymentById(paymentId);

            AccountPaymentEntity previous = null;
            AccountPaymentEntity next = null;
            boolean getPrevious = false;
            for (AccountPaymentEntity p : accnt.getAccountPayments()) {
                if (!p.getAmount().equals(Money.zero())) {
                    if (getPrevious) {
                        previous = p;
                        break;
                    } else if (p.getPaymentId().equals(payment.getPaymentId())) {
                        getPrevious = true;
                    } else {
                        next = p;
                    }
                }
            }

            Date previousPaymentDate = (previous == null) ? null : previous.getPaymentDate();
            Date nextPaymentDate = (next == null) ? null : next.getPaymentDate();

            appAdjustActionForm.setPreviousPaymentDate(previousPaymentDate);
            appAdjustActionForm.setNextPaymentDate(nextPaymentDate);

            SessionUtils.setAttribute(Constants.ADJUSTED_AMOUNT, payment.getAmount().getAmount(), request);

            Short transferPaymentTypeId = legacyAcceptedPaymentTypeDao.getSavingsTransferId();
            if (payment.getPaymentType().getId().equals(transferPaymentTypeId)) {
                List<ListItem<Short>> paymentTypeList = this.accountServiceFacade
                        .constructPaymentTypeListForLoanRepayment(userContext.getLocaleId());
                for (Iterator<ListItem<Short>> it = paymentTypeList.iterator(); it.hasNext();) {
                    ListItem<Short> listItem = it.next();
                    if (!listItem.getId().equals(transferPaymentTypeId)) {
                        it.remove();
                    }
                }
                SessionUtils.setCollectionAttribute(MasterConstants.PAYMENT_TYPE, paymentTypeList, request);
            } else {
                SessionUtils.setCollectionAttribute(MasterConstants.PAYMENT_TYPE, this.accountServiceFacade
                        .constructPaymentTypeListForLoanRepayment(userContext.getLocaleId()), request);
            }
        } else {
            SessionUtils.setCollectionAttribute(MasterConstants.PAYMENT_TYPE,
                    this.accountServiceFacade.constructPaymentTypeListForLoanRepayment(userContext.getLocaleId()),
                    request);
            payment = accnt.getLastPmntToBeAdjusted();
            appAdjustActionForm.setPaymentId(null);
            SessionUtils.setAttribute(Constants.ADJUSTED_AMOUNT, accnt.getLastPmntAmntToBeAdjusted(), request);
        }

        if (accnt.isParentGroupLoanAccount()) {
            SessionUtils.setAttribute(Constants.TYPE_OF_GROUP_LOAN, "parentAcc", request);
        } else if (accnt.isGroupLoanAccountMember()) {
            appAdjustActionForm.setGroupLoanMember(Boolean.TRUE);
        }

        populateForm(appAdjustActionForm, payment);
        return mapping.findForward("loadadjustment_success");
    }

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

        return mapping.findForward("loadgroupadjustment_success");
    }

    @TransactionDemarcate(joinToken = true)
    public ActionForward listPossibleAdjustments(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
        ApplyAdjustmentActionForm appAdjustActionForm = (ApplyAdjustmentActionForm) form;
        this.resetActionFormFields(appAdjustActionForm);
        AccountBO accnt = getBizService().findBySystemId(appAdjustActionForm.getGlobalAccountNum());

        boolean decliningRecalculation = false;
        if (accnt instanceof LoanBO) {
            LoanBO loan = (LoanBO) accnt;
            if (loan.getInterestType().getId().equals(InterestType.DECLINING_PB.getValue())) {
                decliningRecalculation = true;
            }
        }

        List<AccountPaymentEntity> payments = accnt.getAccountPayments();
        ArrayList<AdjustablePaymentDto> adjustablePayments = new ArrayList<AdjustablePaymentDto>();

        int i = 1;
        for (AccountPaymentEntity payment : payments) {
            //ommit disbursal payment
            if (!payment.getAmount().equals(Money.zero()) && i != payments.size()) {
                AdjustablePaymentDto adjustablePaymentDto = new AdjustablePaymentDto(payment.getPaymentId(),
                        payment.getAmount(), payment.getPaymentType().getName(), payment.getPaymentDate(),
                        payment.getReceiptDate(), payment.getReceiptNumber());

                adjustablePayments.add(adjustablePaymentDto);
                if (decliningRecalculation) {
                    break; //only last payment
                }
            }
            i++;
        }

        SessionUtils.setAttribute(Constants.BUSINESS_KEY, accnt, request);
        SessionUtils.setAttribute(Constants.POSSIBLE_ADJUSTMENTS, adjustablePayments, request);
        request.setAttribute("method", "loadAdjustment");

        return mapping.findForward("loadadjustments_success");
    }

    /*
     * This method do the same thing as loadAdjustment, but added to allow
     * handling permission : can adjust payment when account is closed
     * obligation met
     */

    @TransactionDemarcate(joinToken = true)
    public ActionForward loadAdjustmentWhenObligationMet(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
        ApplyAdjustmentActionForm appAdjustActionForm = (ApplyAdjustmentActionForm) form;
        AccountBO accnt = getBizService().findBySystemId(appAdjustActionForm.getGlobalAccountNum());

        SessionUtils.setAttribute(Constants.BUSINESS_KEY, accnt, request);
        request.setAttribute("method", "loadAdjustmentWhenObligationMet");

        AccountPaymentEntity payment = null;
        if (request.getParameter(Constants.ADJ_TYPE_KEY) != null
                && request.getParameter(Constants.ADJ_TYPE_KEY).equals(Constants.ADJ_SPECIFIC)) {
            Integer paymentId = appAdjustActionForm.getPaymentId();
            payment = accnt.findPaymentById(paymentId);
            SessionUtils.setAttribute(Constants.ADJUSTED_AMOUNT, payment.getAmount().getAmount(), request);
        } else {
            payment = accnt.getLastPmntToBeAdjusted();
            appAdjustActionForm.setPaymentId(null);
            SessionUtils.setAttribute(Constants.ADJUSTED_AMOUNT, accnt.getLastPmntAmntToBeAdjusted(), request);
        }

        appAdjustActionForm.setAdjustData(false);
        populateForm(appAdjustActionForm, payment);
        return mapping.findForward("loadadjustment_success");
    }

    @TransactionDemarcate(joinToken = true)
    public ActionForward previewAdjustment(ActionMapping mapping, @SuppressWarnings("unused") ActionForm form,
            HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
        ApplyAdjustmentActionForm appAdjustActionForm = (ApplyAdjustmentActionForm) form;
        appAdjustActionForm.setAdjustData(!appAdjustActionForm.getAdjustcheckbox());

        if (appAdjustActionForm.isAdjustData()) {
            @SuppressWarnings("unchecked")
            List<ListItem<Short>> paymentTypes = (List<ListItem<Short>>) SessionUtils
                    .getAttribute(MasterConstants.PAYMENT_TYPE, request);

            Short elementType = Short.valueOf(appAdjustActionForm.getPaymentType());
            for (ListItem<Short> item : paymentTypes) {
                if (item.getId().equals(elementType)) {
                    SessionUtils.setAttribute(Constants.ADJUSTMENT_PAYMENT_TYPE, item.getDisplayValue(), request);
                }
            }
        }

        if (appAdjustActionForm.getNewAmounts() != null && !appAdjustActionForm.getNewAmounts().isEmpty()) {
            BigDecimal newAmount = BigDecimal.ZERO;
            for (String memberNewAmountString : appAdjustActionForm.getNewAmounts().values()) {
                BigDecimal memberNewAmount = BigDecimal.ZERO;
                if (!StringUtils.isBlank(memberNewAmountString)) {
                    memberNewAmount = new BigDecimal(memberNewAmountString);
                }
                newAmount = newAmount.add(memberNewAmount);
            }
            appAdjustActionForm.setAmount(newAmount.toString());
        }

        request.setAttribute("method", "previewAdjustment");
        return mapping.findForward("previewadj_success");
    }

    @TransactionDemarcate(joinToken = true)
    public ActionForward divide(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
        ApplyAdjustmentActionForm applyAdjustmentActionForm = (ApplyAdjustmentActionForm) form;
        Integer parentAccountId = getBizService().findBySystemId(applyAdjustmentActionForm.getGlobalAccountNum())
                .getAccountId();
        Integer parentPaymentId = applyAdjustmentActionForm.getPaymentId();
        BigDecimal newAmount = new BigDecimal(applyAdjustmentActionForm.getAmount());

        if (applyAdjustmentActionForm.getAdjustcheckbox()) {
            newAmount = BigDecimal.ZERO;
        }

        List<GroupLoanMemberAdjustmentDto> memberAdjustmentDtoList = this.groupLoanService
                .retrieveMemberAdjustmentDtos(parentAccountId, parentPaymentId, newAmount);

        applyAdjustmentActionForm.setMemberAdjustmentDtoList(memberAdjustmentDtoList);

        return mapping.findForward("divideadjustment_success");
    }

    @TransactionDemarcate(validateAndResetToken = true)
    @CloseSession
    public ActionForward applyAdjustment(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
        request.setAttribute("method", "applyAdjustment");
        ApplyAdjustmentActionForm appAdjustActionForm = (ApplyAdjustmentActionForm) form;
        Integer paymentId = appAdjustActionForm.getPaymentId();

        checkVersionMismatchForAccountBO(request, appAdjustActionForm);
        UserContext userContext = (UserContext) SessionUtils.getAttribute(Constants.USER_CONTEXT_KEY,
                request.getSession());
        try {
            if (paymentId == null) {
                accountServiceFacade.applyAdjustment(appAdjustActionForm.getGlobalAccountNum(),
                        appAdjustActionForm.getAdjustmentNote(), userContext.getId());
            } else {
                AdjustedPaymentDto adjustedPaymentDto = appAdjustActionForm.getPaymentData();
                if (appAdjustActionForm.isGroupLoanMember()) {
                    accountServiceFacade.applyMemberAccountHistoricalAdjustment(
                            appAdjustActionForm.getGlobalAccountNum(), paymentId,
                            appAdjustActionForm.getAdjustmentNote(), userContext.getId(), adjustedPaymentDto);
                } else {
                    accountServiceFacade.applyHistoricalAdjustment(appAdjustActionForm.getGlobalAccountNum(),
                            paymentId, appAdjustActionForm.getAdjustmentNote(), userContext.getId(),
                            adjustedPaymentDto);
                }
            }
        } catch (MifosRuntimeException e) {
            request.setAttribute("method", "previewAdjustment");
            throw (Exception) e.getCause();
        }
        resetActionFormFields(appAdjustActionForm);
        return mapping.findForward("applyadj_success");
    }

    private void checkVersionMismatchForAccountBO(HttpServletRequest request,
            ApplyAdjustmentActionForm appAdjustActionForm) throws ApplicationException {
        AccountBO accountBOInSession = (AccountBO) SessionUtils.getAttribute(Constants.BUSINESS_KEY, request);
        AccountBO accountBO = getBizService().findBySystemId(appAdjustActionForm.getGlobalAccountNum());
        checkVersionMismatch(accountBOInSession.getVersionNo(), accountBO.getVersionNo());
    }

    @TransactionDemarcate(validateAndResetToken = true)
    public ActionForward cancelAdjustment(ActionMapping mapping, ActionForm form,
            @SuppressWarnings("unused") HttpServletRequest request,
            @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
        ApplyAdjustmentActionForm appAdjustActionForm = (ApplyAdjustmentActionForm) form;
        resetActionFormFields(appAdjustActionForm);
        return mapping.findForward("canceladj_success");
    }

    /**
     * This method resets action form fields after successfully applying payment
     * or on cancel.
     */
    private void resetActionFormFields(ApplyAdjustmentActionForm appAdjustActionForm) {
        appAdjustActionForm.setAdjustmentNote(null);
        appAdjustActionForm.setPaymentId(null);
        appAdjustActionForm.setGroupLoanMember(Boolean.FALSE);
    }

    @Override
    protected boolean isNewBizRequired(HttpServletRequest request) throws ServiceException {
        if (request.getAttribute(Constants.BUSINESS_KEY) != null) {
            return false;
        }
        return true;
    }

    private AccountBusinessService getBizService() {
        return new AccountBusinessService();
    }

    private void populateForm(ApplyAdjustmentActionForm form, AccountPaymentEntity payment) {
        if (payment != null) {
            form.setPaymentType(String.valueOf(payment.getPaymentType().getId()));
            form.setAmount(payment.getAmount().toString());
            form.setTrxnDate(payment.getPaymentDate());
            form.setAccountId(payment.getAccount().getAccountId());
        }
        if (form.getMemberAdjustmentDtoList() != null) {
            form.getMemberAdjustmentDtoList().clear();
        }
        form.getNewAmounts().clear();
    }
}