Java tutorial
/* * 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.clientportfolio.loan.ui; import java.io.Serializable; import java.math.BigDecimal; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; import javax.validation.constraints.NotNull; import org.apache.commons.lang.StringUtils; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.mifos.clientportfolio.newloan.applicationservice.LoanDisbursementDateValidationServiceFacade; import org.mifos.clientportfolio.newloan.applicationservice.VariableInstallmentWithFeeValidationResult; import org.mifos.clientportfolio.newloan.applicationservice.VariableInstallmentsFeeValidationServiceFacade; import org.mifos.dto.domain.FeeDto; import org.mifos.dto.domain.PenaltyDto; import org.mifos.platform.validation.MifosBeanValidator; import org.mifos.platform.validations.ErrorEntry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.binding.message.Message; import org.springframework.binding.message.MessageBuilder; import org.springframework.binding.message.MessageContext; import org.springframework.binding.message.MessageCriteria; import org.springframework.binding.validation.ValidationContext; import org.springframework.validation.Errors; import org.springframework.validation.FieldError; @SuppressWarnings("PMD") @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = { "SE_NO_SERIALVERSIONID", "EI_EXPOSE_REP", "EI_EXPOSE_REP2", "DLS_DEAD_LOCAL_STORE" }, justification = "should disable at filter level and also for pmd - not important for us") public class LoanAccountFormBean implements Serializable { @Autowired private transient MifosBeanValidator validator; @Autowired private transient LoanDisbursementDateValidationServiceFacade loanDisbursementDateValidationServiceFacade; @Autowired private transient VariableInstallmentsFeeValidationServiceFacade variableInstallmentsFeeValidationServiceFacade; private transient DateValidator dateValidator; private boolean redoLoanAccount = false; // only used for validating business rule on disbursement private Integer customerId; @NotNull private Integer productId; // custom validation private Number amount; private Number minAllowedAmount; private Number maxAllowedAmount; private Number interestRate; private Number minAllowedInterestRate; private Number maxAllowedInterestRate; private Number numberOfInstallments; private Number minNumberOfInstallments; private Number maxNumberOfInstallments; private Number disbursementDateDD; private Number disbursementDateMM; private Number disbursementDateYY; private Short disbursalPaymentTypeId; private Number graceDuration = Integer.valueOf(0); private Number maxGraceDuration = Integer.valueOf(0); private boolean sourceOfFundsMandatory; private Integer fundId; private boolean purposeOfLoanMandatory; private Integer loanPurposeId; private boolean collateralTypeAndNotesHidden; private Integer collateralTypeId; private String collateralNotes; private boolean externalIdHidden; private boolean externalIdMandatory; private String externalId; // only when LSIM is turned on. private boolean repaymentScheduleIndependentOfCustomerMeeting = false; private Integer repaymentRecursEvery; private Integer repaymentDayOfWeek; private Integer repaymentDayOfMonth; private Integer repaymentWeekOfMonth; private boolean monthly; private boolean monthlyDayOfMonthOptionSelected; private boolean monthlyWeekOfMonthOptionSelected; private String montlyOption = "weekOfMonth"; private boolean weekly; // variable installments only for validation purposes private boolean variableInstallmentsAllowed; private Integer minGapInDays; private Integer maxGapInDays; private BigDecimal minInstallmentAmount; // GLIM specific private boolean glimApplicable; private Boolean[] clientSelectForGroup = new Boolean[1]; private String[] clientGlobalId = new String[1]; private Number[] clientAmount = new Number[1]; private Integer[] clientLoanPurposeId = new Integer[] { 0 }; // fees private List<FeeDto> defaultFees; private List<FeeDto> additionalFees; private Boolean[] defaultFeeSelected; private Number[] defaultFeeAmountOrRate; private Number[] defaultFeeId; private Number[] selectedFeeId; private Number[] selectedFeeAmount; // penalties private List<PenaltyDto> defaultPenalties; private Boolean[] defaultPenaltySelected; private Number[] defaultPenaltyAmountOrRate; private Number[] defaultPenaltyId; // validation of interest field private int digitsBeforeDecimalForInterest; private int digitsAfterDecimalForInterest; private int digitsBeforeDecimalForMonetaryAmounts; private int digitsAfterDecimalForMonetaryAmounts; private Locale locale; public Locale getLocale() { return locale; } public void validateEditAccountDetailsStep(ValidationContext context) { validateEnterAccountDetailsStep(context); } @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = { "SIC_INNER_SHOULD_BE_STATIC_ANON" }, justification = "") public void validateEnterAccountDetailsStep(ValidationContext context) { MessageContext messageContext = context.getMessageContext(); Errors errors = validator.checkConstraints(this); // handle data binding errors that may of occurred if (messageContext.hasErrorMessages()) { Message[] errorMessages = messageContext.getMessagesByCriteria(new MessageCriteria() { @Override public boolean test(@SuppressWarnings("unused") Message message) { return true; } }); messageContext.clearMessages(); for (Message message : errorMessages) { handleDataMappingError(errors, message); } } if (this.glimApplicable) { int index = 0; int selectedCount = 0; for (Boolean clientSelected : this.clientSelectForGroup) { if (clientSelected != null && clientSelected.booleanValue()) { Number clientAmount = this.clientAmount[index]; if (clientAmount == null || exceedsMinOrMax(clientAmount, Integer.valueOf(1), this.maxAllowedAmount)) { String defaultErrorMessage = "Please specify valid Amount."; rejectGlimClientAmountField(index + 1, errors, defaultErrorMessage); } if (clientAmount != null) { BigDecimal amountAsDecimal = new BigDecimal(clientAmount.toString()).stripTrailingZeros(); int places = amountAsDecimal.scale(); if (places > this.digitsAfterDecimalForMonetaryAmounts) { String defaultErrorMessage = "The number of digits after the decimal separator exceeds the allowed number."; rejectInterestRateFieldValue(errors, defaultErrorMessage, "loanAccountFormBean.client.amount.digitsAfterDecimal.invalid", new Object[] { index + 1, this.digitsAfterDecimalForMonetaryAmounts }); } int digitsBefore = amountAsDecimal.toBigInteger().toString().length(); if (digitsBefore > this.digitsBeforeDecimalForMonetaryAmounts) { String defaultErrorMessage = "The number of digits before the decimal separator exceeds the allowed number."; rejectInterestRateFieldValue(errors, defaultErrorMessage, "loanAccountFormBean.client.amount.digitsBeforeDecimal.invalid", new Object[] { index + 1, this.digitsBeforeDecimalForMonetaryAmounts }); } } // check error message of loan purpose for each client when its mandatory.. Integer clientLoanPurposeId = this.clientLoanPurposeId[index]; if (this.purposeOfLoanMandatory && isInvalidSelection(clientLoanPurposeId)) { errors.rejectValue("clientLoanPurposeId", "loanAccountFormBean.glim.purposeOfLoan.invalid", new Object[] { index + 1 }, "Please specify loan purpose."); this.clientLoanPurposeId[index] = 0; } else { // needed so attempt in freemarker(ftl) to display loan purpose doesnt fall over. if (clientLoanPurposeId == null) { this.clientLoanPurposeId[index] = 0; } } selectedCount++; } else { Number clientAmount = this.clientAmount[index]; Integer clientLoanPurposeId = this.clientLoanPurposeId[index]; if (clientAmount != null || clientLoanPurposeId != null) { String defaultErrorMessage = "You have entered details for a member you have not selected. Select the checkbox in front of the member's name in order to include him or her in the loan."; rejectUnselectedGlimClientAmountField(index + 1, errors, defaultErrorMessage); } } index++; } if (selectedCount < 2) { String defaultErrorMessage = "Not enough clients for group loan."; rejectGroupLoanWithTooFewClients(errors, defaultErrorMessage); } } if (this.amount == null || exceedsMinOrMax(this.amount, this.minAllowedAmount, this.maxAllowedAmount)) { String defaultErrorMessage = "Please specify valid Amount."; if (glimApplicable) { defaultErrorMessage = "The sum of the amounts specified for each member is outside the allowable total amount for this loan product."; rejectGlimTotalAmountField(errors, defaultErrorMessage); } else { rejectAmountField(errors, defaultErrorMessage); } } if (this.amount != null) { BigDecimal amountAsDecimal = new BigDecimal(this.amount.toString()).stripTrailingZeros(); int places = amountAsDecimal.scale(); if (places > this.digitsAfterDecimalForMonetaryAmounts) { String defaultErrorMessage = "The number of digits after the decimal separator exceeds the allowed number."; rejectInterestRateFieldValue(errors, defaultErrorMessage, "loanAccountFormBean.amount.digitsAfterDecimal.invalid", new Object[] { this.digitsAfterDecimalForMonetaryAmounts }); } int digitsBefore = amountAsDecimal.toBigInteger().toString().length(); if (digitsBefore > this.digitsBeforeDecimalForMonetaryAmounts) { String defaultErrorMessage = "The number of digits before the decimal separator exceeds the allowed number."; rejectInterestRateFieldValue(errors, defaultErrorMessage, "loanAccountFormBean.amount.digitsBeforeDecimal.invalid", new Object[] { this.digitsBeforeDecimalForMonetaryAmounts }); } } if (this.interestRate == null || exceedsMinOrMax(this.interestRate, this.minAllowedInterestRate, this.maxAllowedInterestRate)) { String defaultErrorMessage = "Please specify valid Interest rate."; rejectInterestRateField(errors, defaultErrorMessage); } if (this.interestRate != null) { BigDecimal interestRateAsDecimal = new BigDecimal(this.interestRate.toString()).stripTrailingZeros(); int places = interestRateAsDecimal.scale(); if (places > this.digitsAfterDecimalForInterest) { String defaultErrorMessage = "The number of digits after the decimal separator exceeds the allowed number."; rejectInterestRateFieldValue(errors, defaultErrorMessage, "loanAccountFormBean.digitsAfterDecimalForInterest.invalid", new Object[] { this.digitsAfterDecimalForInterest }); } int digitsBefore = interestRateAsDecimal.toBigInteger().toString().length(); if (digitsBefore > this.digitsBeforeDecimalForInterest) { String defaultErrorMessage = "The number of digits before the decimal separator exceeds the allowed number."; rejectInterestRateFieldValue(errors, defaultErrorMessage, "loanAccountFormBean.digitsBeforeDecimalForInterest.invalid", new Object[] { this.digitsBeforeDecimalForInterest }); } } if (this.numberOfInstallments == null || exceedsMinOrMax(this.numberOfInstallments, this.minNumberOfInstallments, this.maxNumberOfInstallments)) { String defaultErrorMessage = "Please specify valid number of installments."; rejectNumberOfInstallmentsField(errors, defaultErrorMessage); } if (this.graceDuration == null || this.graceDuration.intValue() < 0) { if (!errors.hasFieldErrors("graceDuration")) { String defaultErrorMessage = "Please specify valid Grace period for repayments. Grace period should be a value less than " + numberOfInstallments.intValue() + "."; rejectGraceDurationField(errors, defaultErrorMessage); } } else { if (this.graceDuration.intValue() > this.maxGraceDuration.intValue()) { String defaultErrorMessage = "The Grace period cannot be greater than in loan product definition."; errors.rejectValue("graceDuration", "loanAccountFormBean.gracePeriodDuration.invalid", defaultErrorMessage); } if (this.numberOfInstallments != null && (this.graceDuration.intValue() >= this.numberOfInstallments.intValue())) { String defaultErrorMessage = "Grace period for repayments must be less than number of loan installments."; errors.rejectValue("graceDuration", "loanAccountFormBean.gracePeriodDurationInRelationToInstallments.invalid", defaultErrorMessage); } } if (dateValidator == null) { dateValidator = new DateValidator(); } if (!dateValidator.formsValidDate(this.disbursementDateDD, this.disbursementDateMM, this.disbursementDateYY)) { String defaultErrorMessage = "Please specify valid disbursal date."; rejectDisbursementDateField(errors, defaultErrorMessage, "disbursementDateDD", "loanAccountFormBean.DisbursalDate.invalid", ""); } else { LocalDate validDate = new DateTime().withDate(disbursementDateYY.intValue(), disbursementDateMM.intValue(), disbursementDateDD.intValue()).toLocalDate(); org.mifos.platform.validations.Errors disbursementDateErrors = new org.mifos.platform.validations.Errors(); if (this.redoLoanAccount) { disbursementDateErrors = loanDisbursementDateValidationServiceFacade .validateLoanWithBackdatedPaymentsDisbursementDate(validDate, customerId, productId); } else { disbursementDateErrors = loanDisbursementDateValidationServiceFacade .validateLoanDisbursementDate(validDate, customerId, productId); } for (ErrorEntry entry : disbursementDateErrors.getErrorEntries()) { String defaultErrorMessage = "The disbursal date is invalid."; rejectDisbursementDateField(errors, defaultErrorMessage, "disbursementDateDD", entry.getErrorCode(), entry.getArgs().get(0)); } } if (this.sourceOfFundsMandatory && isInvalidSelection(this.fundId)) { errors.rejectValue("fundId", "loanAccountFormBean.SourceOfFunds.invalid", "Please specify source of funds."); } if (this.externalIdMandatory && StringUtils.isBlank(this.externalId)) { errors.rejectValue("externalId", "loanAccountFormBean.externalid.invalid", "Please specify required external id."); } if (!this.glimApplicable && this.purposeOfLoanMandatory && isInvalidSelection(this.loanPurposeId)) { errors.rejectValue("loanPurposeId", "loanAccountFormBean.PurposeOfLoan.invalid", "Please specify loan purpose."); } validateAdministrativeAndAdditionalFees(errors); if (this.repaymentScheduleIndependentOfCustomerMeeting) { if (isInvalidRecurringFrequency(this.repaymentRecursEvery)) { errors.rejectValue("repaymentRecursEvery", "loanAccountFormBean.repaymentDay.recursEvery.invalid", "Please specify a valid recurring frequency for repayment day."); } if (this.weekly) { if (isInvalidDayOfWeekSelection()) { errors.rejectValue("repaymentDayOfWeek", "loanAccountFormBean.repaymentDay.weekly.dayOfWeek.invalid", "Please select a day of the week for repayment day."); } } else if (this.monthly) { if (this.monthlyDayOfMonthOptionSelected) { if (isInvalidDayOfMonthEntered()) { errors.rejectValue("repaymentDayOfMonth", "loanAccountFormBean.repaymentDay.monthly.dayOfMonth.invalid", "Please select a day of the month for repayment day."); } } else if (this.monthlyWeekOfMonthOptionSelected) { if (isInvalidWeekOfMonthSelection()) { errors.rejectValue("repaymentWeekOfMonth", "loanAccountFormBean.repaymentDay.monthly.weekOfMonth.invalid", "Please select a week of the month for repayment day."); } if (isInvalidDayOfWeekSelection()) { errors.rejectValue("repaymentDayOfWeek", "loanAccountFormBean.repaymentDay.monthly.dayOfWeek.invalid", "Please select a day of the week for repayment day."); } } } if (this.variableInstallmentsAllowed) { if (this.selectedFeeId != null) { for (Number feeId : this.selectedFeeId) { if (feeId != null) { VariableInstallmentWithFeeValidationResult result = variableInstallmentsFeeValidationServiceFacade .validateFeeCanBeAppliedToVariableInstallmentLoan(feeId.longValue()); if (!result.isFeeCanBeAppliedToVariableInstallmentLoan()) { errors.rejectValue("selectedFeeId", "loanAccountFormBean.additionalfees.variableinstallments.invalid", new String[] { result.getFeeName() }, "This type of fee cannot be applied to loan with variable installments."); } } } } int defaultFeeIndex = 0; if (this.defaultFeeId != null) { for (Number feeId : this.defaultFeeId) { if (feeId != null) { Boolean feeSelectedForRemoval = this.defaultFeeSelected[defaultFeeIndex]; if (feeSelectedForRemoval == null || !feeSelectedForRemoval) { VariableInstallmentWithFeeValidationResult result = variableInstallmentsFeeValidationServiceFacade .validateFeeCanBeAppliedToVariableInstallmentLoan(feeId.longValue()); if (!result.isFeeCanBeAppliedToVariableInstallmentLoan()) { errors.rejectValue("selectedFeeId", "loanAccountFormBean.defaultfees.variableinstallments.invalid", new String[] { result.getFeeName() }, "This type of fee cannot be applied to loan with variable installments."); } } } defaultFeeIndex++; } } } } if (errors.hasErrors()) { for (FieldError fieldError : errors.getFieldErrors()) { MessageBuilder builder = new MessageBuilder().error().source(fieldError.getField()) .codes(fieldError.getCodes()).defaultText(fieldError.getDefaultMessage()) .args(fieldError.getArguments()); messageContext.addMessage(builder.build()); } } } private void validateAdministrativeAndAdditionalFees(Errors errors) { Set<Integer> feeSet = new HashSet<Integer>(); if (this.selectedFeeId != null) { boolean noDuplicateExists = true; for (Number feeId : this.selectedFeeId) { if (feeId != null) { noDuplicateExists = feeSet.add(feeId.intValue()); if (!noDuplicateExists) { errors.rejectValue("selectedFeeId", "loanAccountFormBean.additionalfees.invalid", "Multiple instances of the same fee are not allowed."); break; } } } } int defaultFeeIndex = 0; if (this.defaultFeeId != null) { for (Number feeId : this.defaultFeeId) { if (feeId != null) { Boolean feeSelectedForRemoval = this.defaultFeeSelected[defaultFeeIndex]; if (feeSelectedForRemoval == null || !feeSelectedForRemoval) { Number amountOrRate = this.defaultFeeAmountOrRate[defaultFeeIndex]; if (amountOrRate == null) { errors.rejectValue("defaultFeeId", "loanAccountFormBean.defaultfees.amountOrRate.invalid", "Please specify fee amount for administrative fee " + Integer.valueOf(defaultFeeIndex + 1).toString()); } else { FeeDto selectedFee = findDefaultFee(feeId.intValue()); if (selectedFee.isRateBasedFee()) { // maybe check based on 'interest rate' decimals? } else { BigDecimal feeAmountAsDecimal = new BigDecimal(amountOrRate.toString()) .stripTrailingZeros(); int places = feeAmountAsDecimal.scale(); if (places > this.digitsAfterDecimalForMonetaryAmounts) { errors.rejectValue("selectedFeeId", "loanAccountFormBean.defaultfees.amountOrRate.digits.after.decimal.invalid", new Object[] { Integer.valueOf(defaultFeeIndex + 1), this.digitsAfterDecimalForMonetaryAmounts }, "Please specify fee amount for additional fee " + Integer.valueOf(defaultFeeIndex + 1).toString()); } int digitsBefore = feeAmountAsDecimal.toBigInteger().toString().length(); if (digitsBefore > this.digitsBeforeDecimalForMonetaryAmounts) { errors.rejectValue("selectedFeeId", "loanAccountFormBean.defaultfees.amountOrRate.digits.before.decimal.invalid", new Object[] { Integer.valueOf(defaultFeeIndex + 1), this.digitsAfterDecimalForMonetaryAmounts }, "Please specify fee amount for additional fee " + Integer.valueOf(defaultFeeIndex + 1).toString()); } } } } } defaultFeeIndex++; } } int additionalFeeIndex = 0; if (this.selectedFeeId != null) { for (Number feeId : this.selectedFeeId) { if (feeId != null) { Number amountOrRate = this.selectedFeeAmount[additionalFeeIndex]; if (amountOrRate == null) { errors.rejectValue("selectedFeeId", "loanAccountFormBean.additionalfees.amountOrRate.invalid", "Please specify fee amount for additional fee " + Integer.valueOf(additionalFeeIndex + 1).toString()); } else { int digitsAllowedBefore, digitsAllowedAfter; if (findAdditionalFee(feeId.intValue()).isRateBasedFee()) { digitsAllowedBefore = this.digitsBeforeDecimalForInterest; digitsAllowedAfter = this.digitsAfterDecimalForInterest; } else { digitsAllowedBefore = this.digitsBeforeDecimalForMonetaryAmounts; digitsAllowedAfter = this.digitsAfterDecimalForMonetaryAmounts; } BigDecimal feeAmountAsDecimal = new BigDecimal(amountOrRate.toString()) .stripTrailingZeros(); int places = feeAmountAsDecimal.scale(); if (places > digitsAllowedAfter) { errors.rejectValue("selectedFeeId", "loanAccountFormBean.additionalfees.amountOrRate.digits.after.decimal.invalid", new Object[] { Integer.valueOf(additionalFeeIndex + 1), digitsAllowedAfter }, "Please specify fee amount for additional fee " + Integer.valueOf(additionalFeeIndex + 1).toString()); } int digitsBefore = feeAmountAsDecimal.toBigInteger().toString().length(); if (digitsBefore > digitsAllowedBefore) { errors.rejectValue("selectedFeeId", "loanAccountFormBean.additionalfees.amountOrRate.digits.before.decimal.invalid", new Object[] { Integer.valueOf(additionalFeeIndex + 1), digitsAllowedBefore }, "Please specify fee amount for additional fee " + Integer.valueOf(additionalFeeIndex + 1).toString()); } } } additionalFeeIndex++; } } } private FeeDto findDefaultFee(Integer feeId) { FeeDto found = null; for (FeeDto fee : this.defaultFees) { if (fee.getId().equals(feeId.toString())) { found = fee; } } return found; } private FeeDto findAdditionalFee(Integer feeId) { FeeDto found = null; for (FeeDto fee : this.additionalFees) { if (fee.getId().equals(feeId.toString())) { found = fee; } } return found; } private boolean isInvalidDayOfMonthEntered() { return this.repaymentDayOfMonth == null || this.repaymentDayOfMonth < 1 || this.repaymentDayOfMonth > 31; } private boolean isInvalidWeekOfMonthSelection() { return this.repaymentWeekOfMonth == null; } private boolean isInvalidDayOfWeekSelection() { return this.repaymentDayOfWeek == null; } private boolean isInvalidRecurringFrequency(Integer recursEvery) { return (recursEvery == null || recursEvery < 1); } private void rejectGlimTotalAmountField(Errors errors, String defaultErrorMessage) { errors.rejectValue("disbursementDateDD", "loanAccountFormBean.glim.totalAmount.invalid", new Object[] { this.minAllowedAmount, this.maxAllowedAmount }, defaultErrorMessage); } private void rejectGroupLoanWithTooFewClients(Errors errors, String defaultErrorMessage) { errors.rejectValue("disbursementDateDD", "loanAccountFormBean.glim.notEnoughClients", defaultErrorMessage); } private void rejectUnselectedGlimClientAmountField(int clientIndex, Errors errors, String defaultErrorMessage) { errors.rejectValue("clientAmount", "loanAccountFormBean.glim.client.notselected", new Object[] { clientIndex }, defaultErrorMessage); } private void rejectGlimClientAmountField(int clientIndex, Errors errors, String defaultErrorMessage) { errors.rejectValue("clientAmount", "loanAccountFormBean.glim.clientAmount.invalid", new Object[] { clientIndex, this.minAllowedAmount, this.maxAllowedAmount }, defaultErrorMessage); } private void rejectDisbursementDateField(Errors errors, String defaultErrorMessage, String field, String errorCode, String args) { errors.rejectValue(field, errorCode, new Object[] { args }, defaultErrorMessage); } private void rejectNumberOfInstallmentsField(Errors errors, String defaultErrorMessage) { errors.rejectValue("numberOfInstallments", "loanAccountFormBean.NumberOfInstallments.invalid", new Object[] { this.minNumberOfInstallments, this.maxNumberOfInstallments }, defaultErrorMessage); } private void rejectGraceDurationField(Errors errors, String defaultErrorMessage) { String field = "Grace period"; Integer numberOfInstallments = this.numberOfInstallments.intValue(); errors.rejectValue("graceDuration", "loanAccountFormBean.gracePeriodDuration.emptyOrIncorrect.invalid", new Object[] { field, numberOfInstallments }, defaultErrorMessage); } private void rejectAmountField(Errors errors, String defaultErrorMessage) { errors.rejectValue("amount", "loanAccountFormBean.Amount.invalid", new Object[] { this.minAllowedAmount, this.maxAllowedAmount }, defaultErrorMessage); } private void rejectInterestRateField(Errors errors, String defaultErrorMessage) { errors.rejectValue("interestRate", "loanAccountFormBean.InterestRate.invalid", new Object[] { this.minAllowedInterestRate, this.maxAllowedInterestRate }, defaultErrorMessage); } private void rejectInterestRateFieldValue(Errors errors, String defaultErrorMessage, String errorCode, Object[] args) { errors.rejectValue("interestRate", errorCode, args, defaultErrorMessage); } private void handleDataMappingError(Errors errors, Message message) { if ("amount".equals(message.getSource())) { rejectAmountField(errors, message.getText()); } if ("interestRate".equals(message.getSource())) { rejectInterestRateField(errors, message.getText()); } if ("numberOfInstallments".equals(message.getSource())) { rejectNumberOfInstallmentsField(errors, message.getText()); } if ("graceDuration".equals(message.getSource())) { rejectGraceDurationField(errors, message.getText()); } if ("disbursementDateDD".equals(message.getSource())) { rejectDisbursementDateField(errors, message.getText(), message.getSource().toString(), "loanAccountFormBean.DisbursalDate.dd.invalid", ""); } if ("disbursementDateMM".equals(message.getSource())) { rejectDisbursementDateField(errors, message.getText(), message.getSource().toString(), "loanAccountFormBean.DisbursalDate.mm.invalid", ""); } if ("disbursementDateYY".equals(message.getSource())) { rejectDisbursementDateField(errors, message.getText(), message.getSource().toString(), "loanAccountFormBean.DisbursalDate.yyyy.invalid", ""); } if (message.getSource().toString().startsWith("selectedFeeAmount")) { rejectAdditionalOrDefaultFeeField(errors, message.getText(), "loanAccountFormBean.additionalfee.invalid"); } String messageSource = message.getSource().toString(); if (messageSource.startsWith("defaultFeeAmountOrRate")) { int first = messageSource.indexOf("["); int last = messageSource.indexOf("]"); Integer feeIndex = Integer.valueOf(messageSource.substring(first + 1, last)); Boolean feeSelectedForRemoval = this.defaultFeeSelected[feeIndex]; if (feeSelectedForRemoval == null || !feeSelectedForRemoval) { rejectAdditionalOrDefaultFeeField(errors, message.getText(), "loanAccountFormBean.additionalfee.invalid"); } } } private void rejectAdditionalOrDefaultFeeField(Errors errors, String defaultErrorMessage, String errorCode) { errors.rejectValue("selectedFeeAmount[0]", errorCode, defaultErrorMessage); } private boolean isInvalidSelection(Integer selectionId) { return selectionId == null; } private boolean exceedsMinOrMax(Number defaultValue, Number minValue, Number maxValue) { return defaultValue.doubleValue() > maxValue.doubleValue() || defaultValue.doubleValue() < minValue.doubleValue(); } public Number[] getSelectedFeeId() { return selectedFeeId; } public void setSelectedFeeId(Number[] selectedFeeId) { this.selectedFeeId = selectedFeeId; } public Number[] getSelectedFeeAmount() { return selectedFeeAmount; } public void setSelectedFeeAmount(Number[] selectedFeeAmount) { this.selectedFeeAmount = selectedFeeAmount; } public String getExternalId() { return externalId; } public void setExternalId(String externalId) { this.externalId = externalId; } public String getCollateralNotes() { return collateralNotes; } public void setCollateralNotes(String collateralNotes) { this.collateralNotes = collateralNotes; } public Integer getLoanPurposeId() { return loanPurposeId; } public void setLoanPurposeId(Integer loanPurposeId) { this.loanPurposeId = loanPurposeId; } public Integer getCollateralTypeId() { return collateralTypeId; } public void setCollateralTypeId(Integer collateralTypeId) { this.collateralTypeId = collateralTypeId; } public Integer getFundId() { return fundId; } public void setFundId(Integer fundId) { this.fundId = fundId; } public Number getGraceDuration() { return graceDuration; } public void setGraceDuration(Number graceDuration) { this.graceDuration = graceDuration; } public Integer getProductId() { return productId; } public void setProductId(Integer productId) { this.productId = productId; } public Number getAmount() { return amount; } public void setAmount(Number amount) { this.amount = amount; } public Number getInterestRate() { return interestRate; } public void setInterestRate(Number interestRate) { this.interestRate = interestRate; } public Number getNumberOfInstallments() { return numberOfInstallments; } public void setNumberOfInstallments(Number numberOfInstallments) { this.numberOfInstallments = numberOfInstallments; } public Number getDisbursementDateDD() { return disbursementDateDD; } public void setDisbursementDateDD(Number disbursalDateDay) { this.disbursementDateDD = disbursalDateDay; } public Number getDisbursementDateMM() { return disbursementDateMM; } public void setDisbursementDateMM(Number disbursalDateMonth) { this.disbursementDateMM = disbursalDateMonth; } public Number getDisbursementDateYY() { return disbursementDateYY; } public void setDisbursementDateYY(Number disbursalDateYear) { this.disbursementDateYY = disbursalDateYear; } public Short getDisbursalPaymentTypeId() { return disbursalPaymentTypeId; } public void setDisbursalPaymentTypeId(Short disbursalPaymentTypeId) { this.disbursalPaymentTypeId = disbursalPaymentTypeId; } public Number getMinAllowedAmount() { return minAllowedAmount; } public void setMinAllowedAmount(Number minAllowedAmount) { this.minAllowedAmount = minAllowedAmount; } public Number getMaxAllowedAmount() { return maxAllowedAmount; } public void setMaxAllowedAmount(Number maxAllowedAmount) { this.maxAllowedAmount = maxAllowedAmount; } public Number getMinAllowedInterestRate() { return minAllowedInterestRate; } public void setMinAllowedInterestRate(Number minAllowedInterestRate) { this.minAllowedInterestRate = minAllowedInterestRate; } public Number getMaxAllowedInterestRate() { return maxAllowedInterestRate; } public void setMaxAllowedInterestRate(Number maxAllowedInterestRate) { this.maxAllowedInterestRate = maxAllowedInterestRate; } public Number getMinNumberOfInstallments() { return minNumberOfInstallments; } public void setMinNumberOfInstallments(Number minNumberOfInstallments) { this.minNumberOfInstallments = minNumberOfInstallments; } public Number getMaxNumberOfInstallments() { return maxNumberOfInstallments; } public void setMaxNumberOfInstallments(Number maxNumberOfInstallments) { this.maxNumberOfInstallments = maxNumberOfInstallments; } public boolean isSourceOfFundsMandatory() { return sourceOfFundsMandatory; } public void setSourceOfFundsMandatory(boolean sourceOfFundsMandatory) { this.sourceOfFundsMandatory = sourceOfFundsMandatory; } public boolean isPurposeOfLoanMandatory() { return purposeOfLoanMandatory; } public void setPurposeOfLoanMandatory(boolean purposeOfLoanMandatory) { this.purposeOfLoanMandatory = purposeOfLoanMandatory; } public Integer getCustomerId() { return customerId; } public void setCustomerId(Integer customerId) { this.customerId = customerId; } public void setValidator(MifosBeanValidator validator) { this.validator = validator; } public void setDateValidator(DateValidator dateValidator) { this.dateValidator = dateValidator; } public void setLoanDisbursementDateValidationServiceFacade( LoanDisbursementDateValidationServiceFacade loanDisbursementDateValidationServiceFacade) { this.loanDisbursementDateValidationServiceFacade = loanDisbursementDateValidationServiceFacade; } public boolean isRepaymentScheduleIndependentOfCustomerMeeting() { return repaymentScheduleIndependentOfCustomerMeeting; } public void setRepaymentScheduleIndependentOfCustomerMeeting( boolean repaymentScheduleIndependentOfCustomerMeeting) { this.repaymentScheduleIndependentOfCustomerMeeting = repaymentScheduleIndependentOfCustomerMeeting; } public Integer getRepaymentRecursEvery() { return repaymentRecursEvery; } public void setRepaymentRecursEvery(Integer repaymentRecursEvery) { this.repaymentRecursEvery = repaymentRecursEvery; } public Integer getRepaymentDayOfWeek() { return repaymentDayOfWeek; } public void setRepaymentDayOfWeek(Integer repaymentDayOfWeek) { this.repaymentDayOfWeek = repaymentDayOfWeek; } public boolean isVariableInstallmentsAllowed() { return variableInstallmentsAllowed; } public void setVariableInstallmentsAllowed(boolean variableInstallmentsAllowed) { this.variableInstallmentsAllowed = variableInstallmentsAllowed; } public Integer getMinGapInDays() { return minGapInDays; } public void setMinGapInDays(Integer minGapInDays) { this.minGapInDays = minGapInDays; } public Integer getMaxGapInDays() { return maxGapInDays; } public void setMaxGapInDays(Integer maxGapInDays) { this.maxGapInDays = maxGapInDays; } public BigDecimal getMinInstallmentAmount() { return minInstallmentAmount; } public void setMinInstallmentAmount(BigDecimal minInstallmentAmount) { this.minInstallmentAmount = minInstallmentAmount; } public Integer[] getClientLoanPurposeId() { return this.clientLoanPurposeId; } public void setClientLoanPurposeId(Integer[] clientLoanPurposeId) { this.clientLoanPurposeId = clientLoanPurposeId; } public Number[] getClientAmount() { return clientAmount; } public void setClientAmount(Number[] clientAmount) { this.clientAmount = clientAmount; } public boolean isGlimApplicable() { return glimApplicable; } public void setGlimApplicable(boolean glimApplicable) { this.glimApplicable = glimApplicable; } public Boolean[] getClientSelectForGroup() { return clientSelectForGroup; } public void setClientSelectForGroup(Boolean[] clientSelectForGroup) { this.clientSelectForGroup = clientSelectForGroup; } public boolean isClientSelected(Integer index) { Boolean result = this.clientSelectForGroup[index]; boolean clientSelected = false; if (result != null) { clientSelected = result.booleanValue(); } return clientSelected; } public String[] getClientGlobalId() { return clientGlobalId; } public void setClientGlobalId(String[] clientGlobalId) { this.clientGlobalId = clientGlobalId; } public Integer getRepaymentDayOfMonth() { return repaymentDayOfMonth; } public void setRepaymentDayOfMonth(Integer repaymentDayOfMonth) { this.repaymentDayOfMonth = repaymentDayOfMonth; } public Integer getRepaymentWeekOfMonth() { return repaymentWeekOfMonth; } public void setRepaymentWeekOfMonth(Integer repaymentWeekOfMonth) { this.repaymentWeekOfMonth = repaymentWeekOfMonth; } public boolean isMonthly() { return monthly; } public void setMonthly(boolean monthly) { this.monthly = monthly; } public boolean isMonthlyDayOfMonthOptionSelected() { return monthlyDayOfMonthOptionSelected; } public void setMonthlyDayOfMonthOptionSelected(boolean monthlyDayOfMonthOptionSelected) { this.monthlyDayOfMonthOptionSelected = monthlyDayOfMonthOptionSelected; } public boolean isMonthlyWeekOfMonthOptionSelected() { return monthlyWeekOfMonthOptionSelected; } public void setMonthlyWeekOfMonthOptionSelected(boolean monthlyWeekOfMonthOptionSelected) { this.monthlyWeekOfMonthOptionSelected = monthlyWeekOfMonthOptionSelected; } public boolean isWeekly() { return weekly; } public void setWeekly(boolean weekly) { this.weekly = weekly; } public String getMontlyOption() { return montlyOption; } public void setMontlyOption(String montlyOption) { this.montlyOption = montlyOption; if (this.montlyOption.equalsIgnoreCase("weekOfMonth")) { this.monthlyDayOfMonthOptionSelected = false; this.monthlyWeekOfMonthOptionSelected = true; } else if (this.montlyOption.equalsIgnoreCase("dayOfMonth")) { this.monthlyDayOfMonthOptionSelected = true; this.monthlyWeekOfMonthOptionSelected = true; } } public void setDayOfMonthDetails(Integer dayOfMonth, Integer recursEvery) { this.weekly = false; this.monthly = true; this.monthlyDayOfMonthOptionSelected = true; this.monthlyWeekOfMonthOptionSelected = false; this.repaymentDayOfMonth = dayOfMonth; this.repaymentWeekOfMonth = null; this.repaymentDayOfWeek = null; this.repaymentRecursEvery = recursEvery; this.montlyOption = "dayOfMonth"; } public void setWeekOfMonthDetails(Integer weekOfMonth, Integer dayOfWeek, Integer recursEvery) { this.weekly = false; this.monthly = true; this.monthlyDayOfMonthOptionSelected = false; this.monthlyWeekOfMonthOptionSelected = true; this.repaymentDayOfMonth = null; this.repaymentWeekOfMonth = weekOfMonth; this.repaymentDayOfWeek = dayOfWeek; this.repaymentRecursEvery = recursEvery; this.montlyOption = "weekOfMonth"; } public void setWeeklyDetails(Integer dayOfWeek, Integer recursEvery) { this.weekly = true; this.monthly = false; this.monthlyDayOfMonthOptionSelected = false; this.monthlyWeekOfMonthOptionSelected = false; this.repaymentDayOfMonth = null; this.repaymentWeekOfMonth = null; this.repaymentDayOfWeek = dayOfWeek; this.repaymentRecursEvery = recursEvery; } public Boolean[] getDefaultFeeSelected() { return defaultFeeSelected; } public void setDefaultFeeSelected(Boolean[] defaultFeeSelected) { this.defaultFeeSelected = defaultFeeSelected; } public Boolean[] getDefaultPenaltySelected() { return defaultPenaltySelected; } public void setDefaultPenaltySelected(Boolean[] defaultPenaltySelected) { this.defaultPenaltySelected = defaultPenaltySelected; } public Number[] getDefaultFeeAmountOrRate() { return defaultFeeAmountOrRate; } public void setDefaultFeeAmountOrRate(Number[] defaultFeeAmountOrRate) { this.defaultFeeAmountOrRate = defaultFeeAmountOrRate; } public List<PenaltyDto> getDefaultPenalties() { return defaultPenalties; } public void setDefaultPenalties(List<PenaltyDto> defaultPenalties) { this.defaultPenalties = defaultPenalties; } public Number[] getDefaultPenaltyAmountOrRate() { return defaultPenaltyAmountOrRate; } public void setDefaultPenaltyAmountOrRate(Number[] defaultPenaltyAmountOrRate) { this.defaultPenaltyAmountOrRate = defaultPenaltyAmountOrRate; } public Number[] getDefaultFeeId() { return defaultFeeId; } public void setDefaultFeeId(Number[] defaultFeeId) { this.defaultFeeId = defaultFeeId; } public Number[] getDefaultPenaltyId() { return defaultPenaltyId; } public void setDefaultPenaltyId(Number[] defaultPenaltyId) { this.defaultPenaltyId = defaultPenaltyId; } public Number getMaxGraceDuration() { return maxGraceDuration; } public void setMaxGraceDuration(Number maxGraceDuration) { this.maxGraceDuration = maxGraceDuration; } public int getDigitsAfterDecimalForInterest() { return digitsAfterDecimalForInterest; } public void setDigitsAfterDecimalForInterest(int digitsAfterDecimalForInterest) { this.digitsAfterDecimalForInterest = digitsAfterDecimalForInterest; } public int getDigitsBeforeDecimalForInterest() { return digitsBeforeDecimalForInterest; } public void setDigitsBeforeDecimalForInterest(int digitsBeforeDecimalForInterest) { this.digitsBeforeDecimalForInterest = digitsBeforeDecimalForInterest; } public int getDigitsAfterDecimalForMonetaryAmounts() { return digitsAfterDecimalForMonetaryAmounts; } public void setDigitsAfterDecimalForMonetaryAmounts(int digitsAfterDecimalForMonetaryAmounts) { this.digitsAfterDecimalForMonetaryAmounts = digitsAfterDecimalForMonetaryAmounts; } public int getDigitsBeforeDecimalForMonetaryAmounts() { return digitsBeforeDecimalForMonetaryAmounts; } public void setDigitsBeforeDecimalForMonetaryAmounts(int digitsBeforeDecimalForMonetaryAmounts) { this.digitsBeforeDecimalForMonetaryAmounts = digitsBeforeDecimalForMonetaryAmounts; } public String getNumberFormatForMonetaryAmounts() { StringBuilder numberFormat = new StringBuilder("0."); for (int i = 0; i < this.digitsAfterDecimalForMonetaryAmounts; i++) { numberFormat.append("#"); } if (this.digitsAfterDecimalForMonetaryAmounts == 0) { numberFormat = new StringBuilder("0"); } return numberFormat.toString(); } public boolean isRedoLoanAccount() { return redoLoanAccount; } public void setRedoLoanAccount(boolean redoLoanAccount) { this.redoLoanAccount = redoLoanAccount; } public boolean isCollateralTypeAndNotesHidden() { return collateralTypeAndNotesHidden; } public void setCollateralTypeAndNotesHidden(boolean collateralTypeAndNotesHidden) { this.collateralTypeAndNotesHidden = collateralTypeAndNotesHidden; } public boolean isExternalIdHidden() { return externalIdHidden; } public void setExternalIdHidden(boolean externalIdHidden) { this.externalIdHidden = externalIdHidden; } public boolean isExternalIdMandatory() { return externalIdMandatory; } public void setExternalIdMandatory(boolean externalIdMandatory) { this.externalIdMandatory = externalIdMandatory; } public List<FeeDto> getDefaultFees() { return defaultFees; } public void setDefaultFees(List<FeeDto> defaultFees) { this.defaultFees = defaultFees; } public List<FeeDto> getAdditionalFees() { return additionalFees; } public void setAdditionalFees(List<FeeDto> additionalFees) { this.additionalFees = additionalFees; } public void setLocale(Locale default1) { this.locale = default1; } }