/* * 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.actionforms; import java.util.ArrayList; import java.util.HashMap; import java.util.Locale; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.apache.struts.Globals; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessage; import org.mifos.accounts.business.AccountBO; import org.mifos.accounts.business.service.AccountBusinessService; import org.mifos.accounts.util.helpers.AccountConstants; import org.mifos.application.master.business.MifosCurrency; import org.mifos.application.util.helpers.Methods; import org.mifos.config.AccountingRules; import org.mifos.core.MifosRuntimeException; import org.mifos.framework.business.util.helpers.MethodNameConstants; import org.mifos.framework.exceptions.ServiceException; import org.mifos.framework.struts.actionforms.BaseActionForm; import org.mifos.framework.util.helpers.DoubleConversionResult; import org.mifos.framework.util.helpers.FilePaths; public class ApplyChargeActionForm extends BaseActionForm { private String accountId; // chargeType is constructed in the jsp page applyCharges.jsp as "<isPenaltyType>:<feeId>:<isRateType>" // where <feeId> is the id of the fee that has been selected and // <isRateType> is "1" if the fee is a rate type (% of some amount) or "0" if it is // a simple amount (money value) private String chargeType; private String chargeAmount; private String charge; private String selectedChargeFormula; private Map<Integer,String> individualValues = new HashMap<Integer, String>(); public Map<Integer, String> getIndividualValues() { return individualValues; } public void setIndividualValues(Map<Integer, String> individualValues) { this.individualValues = individualValues; } public void setUpdateIndividualValues(String accountId, String value) { individualValues.put(Integer.valueOf(accountId), value); } public String getIndividualValues(Integer accountId) { return individualValues.get(accountId); } public String getAccountId() { return accountId; } public void setAccountId(String accountId) { this.accountId = accountId; } public String getChargeAmount() { return chargeAmount; } public void setChargeAmount(String chargeAmount) { this.chargeAmount = chargeAmount; } public String getChargeType() { return chargeType; } public void setChargeType(String chargeType) { this.chargeType = chargeType; } public String getCharge() { return charge; } public void setCharge(String charge) { this.charge = charge; } public String getSelectedChargeFormula() { return selectedChargeFormula; } public void setSelectedChargeFormula(String selectedChargeFormula) { this.selectedChargeFormula = selectedChargeFormula; } /* * Extract the <isRateType> boolean value from the chargeType (see note above about chargeType) */ public boolean isRateType() { String[] values = getChargeType().split(":"); return values[2].equals("1"); } /* * Extract the <isPenaltyType> boolean value from the chargeType (see note above about chargeType) */ public boolean isPenaltyType() { String[] values = getChargeType().split(":"); return values[0].equals("1"); } /* * Extract the <feeId> value from the chargeType (see note above about chargeType) */ public String getFeeId() { String[] values = getChargeType().split(":"); return values[1]; } @Override public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { Locale locale = getUserContext(request).getPreferredLocale(); ActionErrors errors = new ActionErrors(); String methodCalled = request.getParameter(MethodNameConstants.METHOD); boolean groupLoanWithMembers = AccountingRules.isGroupLoanWithMembers(); AccountBusinessService service = new AccountBusinessService(); AccountBO accountBO = null; if(groupLoanWithMembers){ try { accountBO = service.getAccount(Integer.valueOf(getAccountId())); } catch (ServiceException e) { throw new MifosRuntimeException(e); } } if (groupLoanWithMembers && accountBO.isParentGroupLoanAccount()) { if (methodCalled != null && methodCalled.equals("divide")) { if (StringUtils.isNotBlank(selectedChargeFormula)) { validateRate(errors, request); } validateAmount(errors, locale); } if (methodCalled != null && methodCalled.equals("update")) { validateHashMap(errors); } if (!errors.isEmpty()) { request.setAttribute(Globals.ERROR_KEY, errors); if (methodCalled.equals("divide")) { request.setAttribute("methodCalled", "update"); } else if (methodCalled.equals("update")) { request.setAttribute("methodCalled", "create"); } else { request.setAttribute("methodCalled", methodCalled); } } } else { if (null != methodCalled) { if ((Methods.update.toString()).equals(methodCalled)) { if (StringUtils.isNotBlank(selectedChargeFormula)) { validateRate(errors, request); } validateAmount(errors, locale); } } if (!errors.isEmpty()) { request.setAttribute(Globals.ERROR_KEY, errors); request.setAttribute("methodCalled", methodCalled); } } return errors; } private void validateHashMap(ActionErrors errors) { ArrayList<String> mapValue = new ArrayList<String>(individualValues.values()); double total = 0.0; for (int i=0; i<individualValues.size(); i++){ DoubleConversionResult conversionResult = validateAmount(mapValue.get(i), getChargeCurrency() , AccountConstants.ACCOUNT_AMOUNT, errors, ""); if (conversionResult.getErrors().size() > 0 || conversionResult.getDoubleValue() < 0.0) { addError(errors, AccountConstants.ACCOUNT_AMOUNT, AccountConstants.ERRORS_MUST_BE_GREATER_OR_EQUAL_ZERO, getLocalizedMessage(AccountConstants.ACCOUNT_AMOUNT)); } else { total += conversionResult.getDoubleValue(); } } if (!isRateType() && total != getDoubleValue(charge)) { addError(errors, AccountConstants.ACCOUNT_AMOUNT, AccountConstants.ERRORS_MUST_SUM_TO_VALID_AMOUNT, getLocalizedMessage(AccountConstants.ACCOUNT_AMOUNT), charge); } } protected void validateRate(ActionErrors errors, HttpServletRequest request) { Double chargeAmountDoubleValue; try { chargeAmountDoubleValue = getDoubleValue(chargeAmount); } catch (NumberFormatException e) { return; } if (chargeAmountDoubleValue != null) { //FIXME Do not use hard coded values for properties local.properties if (chargeAmountDoubleValue > Double.valueOf("999")) { errors.add(AccountConstants.RATE, new ActionMessage(AccountConstants.RATE_ERROR)); request.setAttribute("selectedChargeFormula", selectedChargeFormula); } } } protected void validateAmount(ActionErrors errors, Locale locale) { if(StringUtils.isBlank(getChargeType())){ addError(errors, FilePaths.ACCOUNTS_UI_RESOURCE_PROPERTYFILE, "errors.mandatoryselect", getLocalizedMessage("account.chargetype")); return; } DoubleConversionResult conversionResult = null; String chargeAmount = getCharge(); if (StringUtils.isBlank(chargeAmount)) { Double amount = 0.0; for(Map.Entry<Integer, String> entry : individualValues.entrySet()) { amount += Double.valueOf(entry.getValue()); } chargeAmount = amount.toString(); } if (!StringUtils.isBlank(chargeAmount)) { if (isRateType()) { conversionResult = validateInterest(getCharge(), AccountConstants.ACCOUNT_AMOUNT, errors); } else { conversionResult = validateAmount(getCharge(), getChargeCurrency(), AccountConstants.ACCOUNT_AMOUNT, errors,""); } } else { addError(errors, AccountConstants.ACCOUNT_AMOUNT, "errors.mandatory", "amount"); } if (conversionResult != null && conversionResult.getErrors().size() == 0 && !(conversionResult.getDoubleValue() > 0.0)) { addError(errors, AccountConstants.ACCOUNT_AMOUNT, AccountConstants.ERRORS_MUST_BE_GREATER_THAN_ZERO, getLocalizedMessage(AccountConstants.ACCOUNT_AMOUNT)); } } private MifosCurrency getChargeCurrency() { try { AccountBusinessService service = new AccountBusinessService(); AccountBO accountBO = service.getAccount(Integer.valueOf(getAccountId())); return accountBO.getCurrency(); } catch(Exception ex) { return null; } } public void clear() { setAccountId(null); setChargeType(null); setChargeAmount(null); } }