From 99d50b248a1206f0cec5ff17a69b81db7de2851f Mon Sep 17 00:00:00 2001 From: Michal Dudzinski Date: Wed, 5 Sep 2012 15:39:12 +0200 Subject: [PATCH] MIFOSX-53 added post and template methods. WIP. --- .../api/commands/LoanChargeCommand.java | 52 ++++++++++++ .../SubmitLoanApplicationCommand.java | 13 ++- .../ApiDataConversionServiceImpl.java | 42 +++++++++- .../platform/charge/domain/Charge.java | 8 ++ .../mifosng/platform/loan/domain/Loan.java | 17 +++- .../platform/loan/domain/LoanCharge.java | 80 +++++++++++++++++++ .../platform/loan/domain/LoanProduct.java | 6 +- .../platform/loan/service/LoanAssembler.java | 53 +++++++++++- .../service/LoanChargeCommandValidator.java | 33 ++++++++ .../service/LoanReadPlatformServiceImpl.java | 8 ++ ...SubmitLoanApplicationCommandValidator.java | 14 +++- 11 files changed, 314 insertions(+), 12 deletions(-) create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/api/commands/LoanChargeCommand.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanCharge.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanChargeCommandValidator.java diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/LoanChargeCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/LoanChargeCommand.java new file mode 100644 index 000000000..e62ce3bf6 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/LoanChargeCommand.java @@ -0,0 +1,52 @@ +package org.mifosng.platform.api.commands; + +import java.math.BigDecimal; +import java.util.Set; + +public class LoanChargeCommand { + + private final Long id; + private final BigDecimal amount; + + private final Integer chargeTimeType; + private final Integer chargeCalculationType; + + private final Set modifiedParameters; + + public LoanChargeCommand(final Set modifiedParameters, final Long id, final BigDecimal amount, + final Integer chargeTimeType, final Integer chargeCalculationType) { + this.modifiedParameters = modifiedParameters; + this.id = id; + this.amount = amount; + this.chargeTimeType = chargeTimeType; + this.chargeCalculationType = chargeCalculationType; + } + + public Long getId() { + return id; + } + + public BigDecimal getAmount() { + return amount; + } + + public Integer getChargeTimeType() { + return chargeTimeType; + } + + public Integer getChargeCalculationType() { + return chargeCalculationType; + } + + public boolean isAmountChanged(){ + return this.modifiedParameters.contains("amount"); + } + + public boolean isChargeTimeTypeChanged(){ + return this.modifiedParameters.contains("chargeTimeType"); + } + + public boolean isChargeCalculationTypeChanged(){ + return this.modifiedParameters.contains("chargeCalculationType"); + } +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/SubmitLoanApplicationCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/SubmitLoanApplicationCommand.java index 30e1ee5f0..511103bb9 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/SubmitLoanApplicationCommand.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/SubmitLoanApplicationCommand.java @@ -38,7 +38,9 @@ public class SubmitLoanApplicationCommand { private final LocalDate interestChargedFromDate; private final LocalDate submittedOnDate; private final String submittedOnNote; - + + private final LoanChargeCommand[] charges; + private LoanSchedule loanSchedule; public SubmitLoanApplicationCommand( @@ -55,7 +57,7 @@ public class SubmitLoanApplicationCommand { final Integer interestCalculationPeriodMethod, final Integer repaymentEvery, final Integer repaymentFrequency, final Integer numberOfRepayments, Integer amortizationMethod, final Integer loanTermFrequency, final Integer loanTermFrequencyType, - final BigDecimal toleranceAmount) { + final BigDecimal toleranceAmount, final LoanChargeCommand[] charges) { this.clientId = clientId; this.productId = productId; this.externalId = externalId; @@ -81,6 +83,8 @@ public class SubmitLoanApplicationCommand { this.repaymentFrequencyType = repaymentFrequency; this.numberOfRepayments = numberOfRepayments; this.amortizationType = amortizationMethod; + + this.charges = charges; } public CalculateLoanScheduleCommand toCalculateLoanScheduleCommand() { @@ -185,4 +189,9 @@ public class SubmitLoanApplicationCommand { public String getSubmittedOnNote() { return submittedOnNote; } + + public LoanChargeCommand[] getCharges() { + return charges; + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java index 1c12ed589..3a4181d70 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java @@ -27,6 +27,7 @@ import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; import org.mifosng.platform.api.commands.DepositStateTransitionCommand; import org.mifosng.platform.api.commands.FundCommand; import org.mifosng.platform.api.commands.GroupCommand; +import org.mifosng.platform.api.commands.LoanChargeCommand; import org.mifosng.platform.api.commands.LoanProductCommand; import org.mifosng.platform.api.commands.LoanStateTransitionCommand; import org.mifosng.platform.api.commands.LoanTransactionCommand; @@ -479,14 +480,49 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService { LocalDate submittedOnDate = extractLocalDateParameter("submittedOnDate", requestMap, modifiedParameters); String submittedOnNote = extractStringParameter("submittedOnNote", requestMap, modifiedParameters); - + + JsonParser parser = new JsonParser(); + + LoanChargeCommand[] charges = null; + JsonElement element = parser.parse(json); + if (element.isJsonObject()) { + JsonObject object = element.getAsJsonObject(); + if (object.has("charges")) { + modifiedParameters.add("charges"); + JsonArray array = object.get("charges").getAsJsonArray(); + charges = new LoanChargeCommand[array.size()]; + for (int i=0; i chargeModifiedParameters = new HashSet(); + Long id = loanCharge.get("id").getAsLong(); + BigDecimal amount = null; + Integer chargeTimeType = null; + Integer chargeCalculationType = null; + + if (loanCharge.has("amount")){ + chargeModifiedParameters.add("amount"); + amount = loanCharge.get("amount").getAsBigDecimal(); + } + if (loanCharge.has("chargeTimeType")){ + chargeModifiedParameters.add("chargeTimeType"); + chargeTimeType = loanCharge.get("chargeTimeType").getAsInt(); + } + if (loanCharge.has("chargeCalculationType")){ + chargeModifiedParameters.add("chargeCalculationType"); + chargeCalculationType = loanCharge.get("chargeCalculationType").getAsInt(); + } + charges[i] = new LoanChargeCommand(chargeModifiedParameters, id, amount, chargeTimeType, chargeCalculationType); + } + } + } + return new SubmitLoanApplicationCommand(clientId, productId, externalId, fundId, transactionProcessingStrategyId, submittedOnDate, submittedOnNote, expectedDisbursementDate, repaymentsStartingFromDate, interestChargedFromDate, principal, interestRatePerPeriod, interestRateFrequencyTypeValue, interestTypeValue, interestCalculationPeriodTypeValue, repaymentEvery, repaymentFrequencyType, numberOfRepayments, amortizationTypeValue, loanTermFrequency, loanTermFrequencyType, - inArrearsToleranceValue); + inArrearsToleranceValue, charges); } @Override @@ -1101,6 +1137,4 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService { return new DepositStateTransitionApprovalCommand(resourceIdentifier, productId, eventDate, tenureInMonths, depositAmount, interestCompoundedEveryPeriodType,interestCompoundedEvery); } - - } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/Charge.java b/mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/Charge.java index df55024c5..7af2cd554 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/Charge.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/Charge.java @@ -73,6 +73,14 @@ public class Charge extends AbstractAuditableCustom { return currencyCode; } + public Integer getChargeTime() { + return chargeTime; + } + + public Integer getChargeCalculation() { + return chargeCalculation; + } + public boolean isActive() { return active; } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/Loan.java index db64a4005..430035483 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/Loan.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -128,6 +129,11 @@ public class Loan extends AbstractAuditableCustom { @Column(name = "maturedon_date") private Date maturedOnDate; + @SuppressWarnings("unused") + @LazyCollection(LazyCollectionOption.FALSE) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true) + private Set charges; + // see // http://stackoverflow.com/questions/4334970/hibernate-cannot-simultaneously-fetch-multiple-bags @LazyCollection(LazyCollectionOption.FALSE) @@ -160,6 +166,7 @@ public class Loan extends AbstractAuditableCustom { this.client = null; this.loanProduct = null; this.loanRepaymentScheduleDetail = null; + this.charges = charges; } public Loan(final Client client, Fund fund, LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanProduct loanProduct, @@ -924,7 +931,15 @@ public class Loan extends AbstractAuditableCustom { return possibleMaturityDate; } - public void addRepaymentScheduleInstallment( + public Set getCharges() { + return charges; + } + + public void setCharges(Set charges) { + this.charges = charges; + } + + public void addRepaymentScheduleInstallment( final LoanRepaymentScheduleInstallment installment) { installment.updateLoan(this); this.repaymentScheduleInstallments.add(installment); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanCharge.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanCharge.java new file mode 100644 index 000000000..a72340f8b --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanCharge.java @@ -0,0 +1,80 @@ +package org.mifosng.platform.loan.domain; + +import org.mifosng.platform.api.commands.LoanChargeCommand; +import org.mifosng.platform.charge.domain.Charge; + +import javax.persistence.*; +import java.io.Serializable; +import java.math.BigDecimal; + +@Entity @IdClass(LoanCharge.LoanChargePK.class) +@Table(name = "m_loan_charge") +public class LoanCharge { + + @Id + private Loan loan; + + @Id + private Charge charge; + + @Column(name = "amount", scale = 6, precision = 19, nullable = false) + private BigDecimal amount; + + @SuppressWarnings("unused") + @Column(name = "charge_time_enum", nullable = false) + private Integer chargeTime; + + @SuppressWarnings("unused") + @Column(name = "charge_calculation_enum") + private Integer chargeCalculation; + + public LoanCharge() { + } + + public LoanCharge(Loan loan, Charge charge, LoanChargeCommand command) { + this.loan = loan; + this.charge = charge; + + if (command.isAmountChanged()){ + this.amount = command.getAmount(); + } else { + this.amount = charge.getAmount(); + } + + if (command.isChargeTimeTypeChanged()){ + this.chargeTime = command.getChargeTimeType(); + } else { + this.chargeTime = charge.getChargeTime(); + } + + if (command.isChargeCalculationTypeChanged()){ + this.chargeCalculation = command.getChargeCalculationType(); + } else { + this.chargeCalculation = charge.getChargeCalculation(); + } + } + + public LoanCharge(Loan loan, Charge charge) { + this(loan, charge, charge.getAmount(), charge.getChargeTime(), charge.getChargeCalculation()); + } + + public LoanCharge(Loan loan, Charge charge, BigDecimal amount, Integer chargeTime, Integer chargeCalculation) { + this.loan = loan; + this.charge = charge; + this.amount = amount; + this.chargeTime = chargeTime; + this.chargeCalculation = chargeCalculation; + } + + public static class LoanChargePK implements Serializable{ + @Id + @ManyToOne(optional = false) + @JoinColumn(name = "loan_id", referencedColumnName = "id", nullable=false) + private Loan loan; + + @Id + @ManyToOne(optional = false) + @JoinColumn(name = "charge_id", referencedColumnName = "id", nullable=false) + private Charge charge; + } +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanProduct.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanProduct.java index 4abd1dcf7..602520803 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanProduct.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanProduct.java @@ -153,7 +153,11 @@ public class LoanProduct extends AbstractAuditableCustom { return transactionProcessingStrategy; } - public void update(final LoanProductCommand command, final Fund fund, final LoanTransactionProcessingStrategy strategy, + public Set getCharges() { + return charges; + } + + public void update(final LoanProductCommand command, final Fund fund, final LoanTransactionProcessingStrategy strategy, final Set charges) { if (command.isNameChanged()) { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanAssembler.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanAssembler.java index b4ae1e2d4..1a9ce34a8 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanAssembler.java @@ -2,17 +2,25 @@ package org.mifosng.platform.loan.service; import java.math.BigDecimal; import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import org.mifosng.platform.api.commands.LoanChargeCommand; import org.mifosng.platform.api.commands.SubmitLoanApplicationCommand; import org.mifosng.platform.api.data.LoanSchedule; import org.mifosng.platform.api.data.MoneyData; import org.mifosng.platform.api.data.ScheduledLoanInstallment; +import org.mifosng.platform.charge.domain.Charge; +import org.mifosng.platform.charge.domain.ChargeRepository; import org.mifosng.platform.client.domain.Client; import org.mifosng.platform.client.domain.ClientRepository; import org.mifosng.platform.currency.domain.MonetaryCurrency; +import org.mifosng.platform.exceptions.ChargeIsNotActiveException; +import org.mifosng.platform.exceptions.ChargeNotFoundException; import org.mifosng.platform.exceptions.ClientNotFoundException; import org.mifosng.platform.exceptions.FundNotFoundException; +import org.mifosng.platform.exceptions.InvalidCurrencyException; import org.mifosng.platform.exceptions.LoanProductNotFoundException; import org.mifosng.platform.exceptions.LoanTransactionProcessingStrategyNotFoundException; import org.mifosng.platform.fund.domain.Fund; @@ -22,6 +30,7 @@ import org.mifosng.platform.loan.domain.DefaultLoanLifecycleStateMachine; import org.mifosng.platform.loan.domain.InterestCalculationPeriodMethod; import org.mifosng.platform.loan.domain.InterestMethod; import org.mifosng.platform.loan.domain.Loan; +import org.mifosng.platform.loan.domain.LoanCharge; import org.mifosng.platform.loan.domain.LoanLifecycleStateMachine; import org.mifosng.platform.loan.domain.LoanProduct; import org.mifosng.platform.loan.domain.LoanProductRelatedDetail; @@ -34,6 +43,7 @@ import org.mifosng.platform.loan.domain.PeriodFrequencyType; import org.mifosng.platform.loanschedule.domain.AprCalculator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.ObjectUtils; @Service public class LoanAssembler { @@ -42,6 +52,7 @@ public class LoanAssembler { private final ClientRepository clientRepository; private final AprCalculator aprCalculator = new AprCalculator(); private final FundRepository fundRepository; + private final ChargeRepository chargeRepository; private final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository; @Autowired @@ -49,10 +60,12 @@ public class LoanAssembler { final LoanProductRepository loanProductRepository, final ClientRepository clientRepository, final FundRepository fundRepository, + final ChargeRepository chargeRepository, final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository) { this.loanProductRepository = loanProductRepository; this.clientRepository = clientRepository; this.fundRepository = fundRepository; + this.chargeRepository = chargeRepository; this.loanTransactionProcessingStrategyRepository = loanTransactionProcessingStrategyRepository; } @@ -96,10 +109,13 @@ public class LoanAssembler { // associating fund with loan product at creation is optional for now. Fund fund = findFundByIdIfProvided(command.getFundId()); LoanTransactionProcessingStrategy loanTransactionProcessingStrategy = findStrategyByIdIfProvided(command.getTransactionProcessingStrategyId()); - + Loan loan = Loan.createNew(fund, loanTransactionProcessingStrategy, loanProduct, client, loanRepaymentScheduleDetail); loan.setExternalId(command.getExternalId()); - + + final Set charges = this.assembleSetOfCharges(command, loan, loanProduct, currency.getCode()); + loan.setCharges(charges); + for (ScheduledLoanInstallment scheduledLoanInstallment : loanRepaymentSchedule) { MoneyData readPrincipalDue = scheduledLoanInstallment.getPrincipalDue(); @@ -111,7 +127,7 @@ public class LoanAssembler { readInterestDue.getAmount()); loan.addRepaymentScheduleInstallment(installment); } - + loan.submitApplication(loanTermFrequency, loanTermFrequencyType, command.getSubmittedOnDate(), command.getExpectedDisbursementDate(), command.getRepaymentsStartingFromDate(), command.getInterestChargedFromDate(), @@ -146,4 +162,35 @@ public class LoanAssembler { } return strategy; } + + private Set assembleSetOfCharges(final SubmitLoanApplicationCommand command, final Loan loan, + final LoanProduct product, final String currencyCode) { + + Set charges = new HashSet(); + LoanChargeCommand[] loanChargesArray = command.getCharges(); + + if (!ObjectUtils.isEmpty(loanChargesArray)) { + for (LoanChargeCommand loanChargeCommand : loanChargesArray) { + Long id = loanChargeCommand.getId(); + Charge charge = this.chargeRepository.findOne(id); + if (charge == null || charge.isDeleted()) { + throw new ChargeNotFoundException(id); + } + if (!charge.isActive()){ + throw new ChargeIsNotActiveException(id); + } + if (!currencyCode.equals(charge.getCurrencyCode())){ + String errorMessage = "Charge and Loan must have the same currency."; + throw new InvalidCurrencyException("charge", "attach.to.loan", errorMessage); + } + charges.add(new LoanCharge(loan, charge, loanChargeCommand)); + } + } else { + for (Charge productCharge : product.getCharges()){ + charges.add(new LoanCharge(loan, productCharge)); + } + } + + return charges; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanChargeCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanChargeCommandValidator.java new file mode 100644 index 000000000..b88d9e471 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanChargeCommandValidator.java @@ -0,0 +1,33 @@ +package org.mifosng.platform.loan.service; + + +import org.mifosng.platform.DataValidatorBuilder; +import org.mifosng.platform.api.commands.LoanChargeCommand; +import org.mifosng.platform.api.data.ApiParameterError; +import org.mifosng.platform.exceptions.PlatformApiDataValidationException; + +import java.util.ArrayList; +import java.util.List; + +public class LoanChargeCommandValidator { + + private final LoanChargeCommand command; + + public LoanChargeCommandValidator(LoanChargeCommand command) { + this.command = command; + } + + public void validate(){ + List dataValidationErrors = new ArrayList(); + + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("charge"); + + baseDataValidator.reset().parameter("amount").value(command.getAmount()).ignoreIfNull().positiveAmount(); + baseDataValidator.reset().parameter("chargeTimeType").value(command.getChargeTimeType()).ignoreIfNull().inMinMaxRange(1, 1); + baseDataValidator.reset().parameter("chargeCalculationType").value(command.getChargeCalculationType()).ignoreIfNull().inMinMaxRange(1, 4); + + if (!dataValidationErrors.isEmpty()) { + throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); + } + } +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanReadPlatformServiceImpl.java index 7570d3b4d..3816e46c6 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanReadPlatformServiceImpl.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.Collection; import org.joda.time.LocalDate; +import org.mifosng.platform.api.data.ChargeData; import org.mifosng.platform.api.data.ClientData; import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.EnumOptionData; @@ -20,6 +21,7 @@ import org.mifosng.platform.api.data.LoanTransactionData; import org.mifosng.platform.api.data.LoanRepaymentTransactionData; import org.mifosng.platform.api.data.MoneyData; import org.mifosng.platform.api.data.NewLoanData; +import org.mifosng.platform.charge.service.ChargeReadPlatformService; import org.mifosng.platform.client.service.ClientReadPlatformService; import org.mifosng.platform.currency.domain.ApplicationCurrency; import org.mifosng.platform.currency.domain.ApplicationCurrencyRepository; @@ -54,6 +56,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { private final LoanProductReadPlatformService loanProductReadPlatformService; private final ClientReadPlatformService clientReadPlatformService; private final LoanTransactionRepository loanTransactionRepository; + private final ChargeReadPlatformService chargeReadPlatformService; @Autowired public LoanReadPlatformServiceImpl( @@ -63,6 +66,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final ApplicationCurrencyRepository applicationCurrencyRepository, final LoanProductReadPlatformService loanProductReadPlatformService, final ClientReadPlatformService clientReadPlatformService, + final ChargeReadPlatformService chargeReadPlatformService, final TenantAwareRoutingDataSource dataSource) { this.context = context; this.loanRepository = loanRepository; @@ -70,6 +74,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { this.applicationCurrencyRepository = applicationCurrencyRepository; this.loanProductReadPlatformService = loanProductReadPlatformService; this.clientReadPlatformService = clientReadPlatformService; + this.chargeReadPlatformService = chargeReadPlatformService; this.jdbcTemplate = new JdbcTemplate(dataSource); } @@ -274,6 +279,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { if (loanProductLookup.getId().equals(productId)) { match = this.loanProductReadPlatformService .retrieveLoanProduct(loanProductLookup.getId()); + Collection chargeOptions = this.chargeReadPlatformService.retrieveLoanApplicableCharges(); + chargeOptions.removeAll(match.getCharges()); + match.setChargeOptions(chargeOptions); break; } } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/SubmitLoanApplicationCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/SubmitLoanApplicationCommandValidator.java index 61e065e52..6cb6f22ef 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/SubmitLoanApplicationCommandValidator.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/SubmitLoanApplicationCommandValidator.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; import org.mifosng.platform.api.commands.CalculateLoanScheduleCommand; +import org.mifosng.platform.api.commands.LoanChargeCommand; import org.mifosng.platform.api.commands.SubmitLoanApplicationCommand; import org.mifosng.platform.api.data.ApiParameterError; import org.mifosng.platform.exceptions.PlatformApiDataValidationException; @@ -46,7 +47,18 @@ public class SubmitLoanApplicationCommandValidator { } catch (PlatformApiDataValidationException e) { dataValidationErrors.addAll(e.getErrors()); } - + + if (this.command.getCharges() != null){ + for (LoanChargeCommand loanChargeCommand : this.command.getCharges()){ + try { + LoanChargeCommandValidator validator = new LoanChargeCommandValidator(loanChargeCommand); + validator.validate(); + } catch (PlatformApiDataValidationException e) { + dataValidationErrors.addAll(e.getErrors()); + } + } + } + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); }