MIFOSX-53 added post and template methods. WIP.

This commit is contained in:
Michal Dudzinski
2012-09-05 15:46:06 +02:00
parent ca3d666578
commit 99d50b248a
11 changed files with 314 additions and 12 deletions
@@ -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<String> modifiedParameters;
public LoanChargeCommand(final Set<String> 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");
}
}
@@ -38,7 +38,9 @@ public class SubmitLoanApplicationCommand {
private final LocalDate interestChargedFromDate; private final LocalDate interestChargedFromDate;
private final LocalDate submittedOnDate; private final LocalDate submittedOnDate;
private final String submittedOnNote; private final String submittedOnNote;
private final LoanChargeCommand[] charges;
private LoanSchedule loanSchedule; private LoanSchedule loanSchedule;
public SubmitLoanApplicationCommand( public SubmitLoanApplicationCommand(
@@ -55,7 +57,7 @@ public class SubmitLoanApplicationCommand {
final Integer interestCalculationPeriodMethod, final Integer interestCalculationPeriodMethod,
final Integer repaymentEvery, final Integer repaymentFrequency, final Integer numberOfRepayments, Integer amortizationMethod, final Integer repaymentEvery, final Integer repaymentFrequency, final Integer numberOfRepayments, Integer amortizationMethod,
final Integer loanTermFrequency, final Integer loanTermFrequencyType, final Integer loanTermFrequency, final Integer loanTermFrequencyType,
final BigDecimal toleranceAmount) { final BigDecimal toleranceAmount, final LoanChargeCommand[] charges) {
this.clientId = clientId; this.clientId = clientId;
this.productId = productId; this.productId = productId;
this.externalId = externalId; this.externalId = externalId;
@@ -81,6 +83,8 @@ public class SubmitLoanApplicationCommand {
this.repaymentFrequencyType = repaymentFrequency; this.repaymentFrequencyType = repaymentFrequency;
this.numberOfRepayments = numberOfRepayments; this.numberOfRepayments = numberOfRepayments;
this.amortizationType = amortizationMethod; this.amortizationType = amortizationMethod;
this.charges = charges;
} }
public CalculateLoanScheduleCommand toCalculateLoanScheduleCommand() { public CalculateLoanScheduleCommand toCalculateLoanScheduleCommand() {
@@ -185,4 +189,9 @@ public class SubmitLoanApplicationCommand {
public String getSubmittedOnNote() { public String getSubmittedOnNote() {
return submittedOnNote; return submittedOnNote;
} }
public LoanChargeCommand[] getCharges() {
return charges;
}
} }
@@ -27,6 +27,7 @@ import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand;
import org.mifosng.platform.api.commands.DepositStateTransitionCommand; import org.mifosng.platform.api.commands.DepositStateTransitionCommand;
import org.mifosng.platform.api.commands.FundCommand; import org.mifosng.platform.api.commands.FundCommand;
import org.mifosng.platform.api.commands.GroupCommand; 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.LoanProductCommand;
import org.mifosng.platform.api.commands.LoanStateTransitionCommand; import org.mifosng.platform.api.commands.LoanStateTransitionCommand;
import org.mifosng.platform.api.commands.LoanTransactionCommand; import org.mifosng.platform.api.commands.LoanTransactionCommand;
@@ -479,14 +480,49 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
LocalDate submittedOnDate = extractLocalDateParameter("submittedOnDate", requestMap, modifiedParameters); LocalDate submittedOnDate = extractLocalDateParameter("submittedOnDate", requestMap, modifiedParameters);
String submittedOnNote = extractStringParameter("submittedOnNote", 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<array.size(); i++) {
JsonObject loanCharge = array.get(i).getAsJsonObject();
Set<String> chargeModifiedParameters = new HashSet<String>();
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, return new SubmitLoanApplicationCommand(clientId, productId, externalId, fundId, transactionProcessingStrategyId,
submittedOnDate, submittedOnNote, submittedOnDate, submittedOnNote,
expectedDisbursementDate, repaymentsStartingFromDate, interestChargedFromDate, expectedDisbursementDate, repaymentsStartingFromDate, interestChargedFromDate,
principal, interestRatePerPeriod, interestRateFrequencyTypeValue, interestTypeValue, interestCalculationPeriodTypeValue, principal, interestRatePerPeriod, interestRateFrequencyTypeValue, interestTypeValue, interestCalculationPeriodTypeValue,
repaymentEvery, repaymentFrequencyType, numberOfRepayments, amortizationTypeValue, repaymentEvery, repaymentFrequencyType, numberOfRepayments, amortizationTypeValue,
loanTermFrequency, loanTermFrequencyType, loanTermFrequency, loanTermFrequencyType,
inArrearsToleranceValue); inArrearsToleranceValue, charges);
} }
@Override @Override
@@ -1101,6 +1137,4 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
return new DepositStateTransitionApprovalCommand(resourceIdentifier, productId, eventDate, tenureInMonths, depositAmount, interestCompoundedEveryPeriodType,interestCompoundedEvery); return new DepositStateTransitionApprovalCommand(resourceIdentifier, productId, eventDate, tenureInMonths, depositAmount, interestCompoundedEveryPeriodType,interestCompoundedEvery);
} }
} }
@@ -73,6 +73,14 @@ public class Charge extends AbstractAuditableCustom<AppUser, Long> {
return currencyCode; return currencyCode;
} }
public Integer getChargeTime() {
return chargeTime;
}
public Integer getChargeCalculation() {
return chargeCalculation;
}
public boolean isActive() { public boolean isActive() {
return active; return active;
} }
@@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType; import javax.persistence.CascadeType;
import javax.persistence.Column; import javax.persistence.Column;
@@ -128,6 +129,11 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "maturedon_date") @Column(name = "maturedon_date")
private Date maturedOnDate; private Date maturedOnDate;
@SuppressWarnings("unused")
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true)
private Set<LoanCharge> charges;
// see // see
// http://stackoverflow.com/questions/4334970/hibernate-cannot-simultaneously-fetch-multiple-bags // http://stackoverflow.com/questions/4334970/hibernate-cannot-simultaneously-fetch-multiple-bags
@LazyCollection(LazyCollectionOption.FALSE) @LazyCollection(LazyCollectionOption.FALSE)
@@ -160,6 +166,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
this.client = null; this.client = null;
this.loanProduct = null; this.loanProduct = null;
this.loanRepaymentScheduleDetail = null; this.loanRepaymentScheduleDetail = null;
this.charges = charges;
} }
public Loan(final Client client, Fund fund, LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanProduct loanProduct, public Loan(final Client client, Fund fund, LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanProduct loanProduct,
@@ -924,7 +931,15 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
return possibleMaturityDate; return possibleMaturityDate;
} }
public void addRepaymentScheduleInstallment( public Set<LoanCharge> getCharges() {
return charges;
}
public void setCharges(Set<LoanCharge> charges) {
this.charges = charges;
}
public void addRepaymentScheduleInstallment(
final LoanRepaymentScheduleInstallment installment) { final LoanRepaymentScheduleInstallment installment) {
installment.updateLoan(this); installment.updateLoan(this);
this.repaymentScheduleInstallments.add(installment); this.repaymentScheduleInstallments.add(installment);
@@ -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;
}
}
@@ -153,7 +153,11 @@ public class LoanProduct extends AbstractAuditableCustom<AppUser, Long> {
return transactionProcessingStrategy; return transactionProcessingStrategy;
} }
public void update(final LoanProductCommand command, final Fund fund, final LoanTransactionProcessingStrategy strategy, public Set<Charge> getCharges() {
return charges;
}
public void update(final LoanProductCommand command, final Fund fund, final LoanTransactionProcessingStrategy strategy,
final Set<Charge> charges) { final Set<Charge> charges) {
if (command.isNameChanged()) { if (command.isNameChanged()) {
@@ -2,17 +2,25 @@ package org.mifosng.platform.loan.service;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet;
import java.util.List; 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.commands.SubmitLoanApplicationCommand;
import org.mifosng.platform.api.data.LoanSchedule; import org.mifosng.platform.api.data.LoanSchedule;
import org.mifosng.platform.api.data.MoneyData; import org.mifosng.platform.api.data.MoneyData;
import org.mifosng.platform.api.data.ScheduledLoanInstallment; 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.Client;
import org.mifosng.platform.client.domain.ClientRepository; import org.mifosng.platform.client.domain.ClientRepository;
import org.mifosng.platform.currency.domain.MonetaryCurrency; 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.ClientNotFoundException;
import org.mifosng.platform.exceptions.FundNotFoundException; import org.mifosng.platform.exceptions.FundNotFoundException;
import org.mifosng.platform.exceptions.InvalidCurrencyException;
import org.mifosng.platform.exceptions.LoanProductNotFoundException; import org.mifosng.platform.exceptions.LoanProductNotFoundException;
import org.mifosng.platform.exceptions.LoanTransactionProcessingStrategyNotFoundException; import org.mifosng.platform.exceptions.LoanTransactionProcessingStrategyNotFoundException;
import org.mifosng.platform.fund.domain.Fund; 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.InterestCalculationPeriodMethod;
import org.mifosng.platform.loan.domain.InterestMethod; import org.mifosng.platform.loan.domain.InterestMethod;
import org.mifosng.platform.loan.domain.Loan; 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.LoanLifecycleStateMachine;
import org.mifosng.platform.loan.domain.LoanProduct; import org.mifosng.platform.loan.domain.LoanProduct;
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail; 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.mifosng.platform.loanschedule.domain.AprCalculator;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
@Service @Service
public class LoanAssembler { public class LoanAssembler {
@@ -42,6 +52,7 @@ public class LoanAssembler {
private final ClientRepository clientRepository; private final ClientRepository clientRepository;
private final AprCalculator aprCalculator = new AprCalculator(); private final AprCalculator aprCalculator = new AprCalculator();
private final FundRepository fundRepository; private final FundRepository fundRepository;
private final ChargeRepository chargeRepository;
private final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository; private final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository;
@Autowired @Autowired
@@ -49,10 +60,12 @@ public class LoanAssembler {
final LoanProductRepository loanProductRepository, final LoanProductRepository loanProductRepository,
final ClientRepository clientRepository, final ClientRepository clientRepository,
final FundRepository fundRepository, final FundRepository fundRepository,
final ChargeRepository chargeRepository,
final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository) { final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository) {
this.loanProductRepository = loanProductRepository; this.loanProductRepository = loanProductRepository;
this.clientRepository = clientRepository; this.clientRepository = clientRepository;
this.fundRepository = fundRepository; this.fundRepository = fundRepository;
this.chargeRepository = chargeRepository;
this.loanTransactionProcessingStrategyRepository = loanTransactionProcessingStrategyRepository; this.loanTransactionProcessingStrategyRepository = loanTransactionProcessingStrategyRepository;
} }
@@ -96,10 +109,13 @@ public class LoanAssembler {
// associating fund with loan product at creation is optional for now. // associating fund with loan product at creation is optional for now.
Fund fund = findFundByIdIfProvided(command.getFundId()); Fund fund = findFundByIdIfProvided(command.getFundId());
LoanTransactionProcessingStrategy loanTransactionProcessingStrategy = findStrategyByIdIfProvided(command.getTransactionProcessingStrategyId()); LoanTransactionProcessingStrategy loanTransactionProcessingStrategy = findStrategyByIdIfProvided(command.getTransactionProcessingStrategyId());
Loan loan = Loan.createNew(fund, loanTransactionProcessingStrategy, loanProduct, client, loanRepaymentScheduleDetail); Loan loan = Loan.createNew(fund, loanTransactionProcessingStrategy, loanProduct, client, loanRepaymentScheduleDetail);
loan.setExternalId(command.getExternalId()); loan.setExternalId(command.getExternalId());
final Set<LoanCharge> charges = this.assembleSetOfCharges(command, loan, loanProduct, currency.getCode());
loan.setCharges(charges);
for (ScheduledLoanInstallment scheduledLoanInstallment : loanRepaymentSchedule) { for (ScheduledLoanInstallment scheduledLoanInstallment : loanRepaymentSchedule) {
MoneyData readPrincipalDue = scheduledLoanInstallment.getPrincipalDue(); MoneyData readPrincipalDue = scheduledLoanInstallment.getPrincipalDue();
@@ -111,7 +127,7 @@ public class LoanAssembler {
readInterestDue.getAmount()); readInterestDue.getAmount());
loan.addRepaymentScheduleInstallment(installment); loan.addRepaymentScheduleInstallment(installment);
} }
loan.submitApplication(loanTermFrequency, loanTermFrequencyType, loan.submitApplication(loanTermFrequency, loanTermFrequencyType,
command.getSubmittedOnDate(), command.getExpectedDisbursementDate(), command.getSubmittedOnDate(), command.getExpectedDisbursementDate(),
command.getRepaymentsStartingFromDate(), command.getInterestChargedFromDate(), command.getRepaymentsStartingFromDate(), command.getInterestChargedFromDate(),
@@ -146,4 +162,35 @@ public class LoanAssembler {
} }
return strategy; return strategy;
} }
private Set<LoanCharge> assembleSetOfCharges(final SubmitLoanApplicationCommand command, final Loan loan,
final LoanProduct product, final String currencyCode) {
Set<LoanCharge> charges = new HashSet<LoanCharge>();
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;
}
} }
@@ -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<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
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);
}
}
}
@@ -7,6 +7,7 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import org.joda.time.LocalDate; 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.ClientData;
import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.CurrencyData;
import org.mifosng.platform.api.data.EnumOptionData; 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.LoanRepaymentTransactionData;
import org.mifosng.platform.api.data.MoneyData; import org.mifosng.platform.api.data.MoneyData;
import org.mifosng.platform.api.data.NewLoanData; 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.client.service.ClientReadPlatformService;
import org.mifosng.platform.currency.domain.ApplicationCurrency; import org.mifosng.platform.currency.domain.ApplicationCurrency;
import org.mifosng.platform.currency.domain.ApplicationCurrencyRepository; import org.mifosng.platform.currency.domain.ApplicationCurrencyRepository;
@@ -54,6 +56,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
private final LoanProductReadPlatformService loanProductReadPlatformService; private final LoanProductReadPlatformService loanProductReadPlatformService;
private final ClientReadPlatformService clientReadPlatformService; private final ClientReadPlatformService clientReadPlatformService;
private final LoanTransactionRepository loanTransactionRepository; private final LoanTransactionRepository loanTransactionRepository;
private final ChargeReadPlatformService chargeReadPlatformService;
@Autowired @Autowired
public LoanReadPlatformServiceImpl( public LoanReadPlatformServiceImpl(
@@ -63,6 +66,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
final ApplicationCurrencyRepository applicationCurrencyRepository, final ApplicationCurrencyRepository applicationCurrencyRepository,
final LoanProductReadPlatformService loanProductReadPlatformService, final LoanProductReadPlatformService loanProductReadPlatformService,
final ClientReadPlatformService clientReadPlatformService, final ClientReadPlatformService clientReadPlatformService,
final ChargeReadPlatformService chargeReadPlatformService,
final TenantAwareRoutingDataSource dataSource) { final TenantAwareRoutingDataSource dataSource) {
this.context = context; this.context = context;
this.loanRepository = loanRepository; this.loanRepository = loanRepository;
@@ -70,6 +74,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
this.applicationCurrencyRepository = applicationCurrencyRepository; this.applicationCurrencyRepository = applicationCurrencyRepository;
this.loanProductReadPlatformService = loanProductReadPlatformService; this.loanProductReadPlatformService = loanProductReadPlatformService;
this.clientReadPlatformService = clientReadPlatformService; this.clientReadPlatformService = clientReadPlatformService;
this.chargeReadPlatformService = chargeReadPlatformService;
this.jdbcTemplate = new JdbcTemplate(dataSource); this.jdbcTemplate = new JdbcTemplate(dataSource);
} }
@@ -274,6 +279,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
if (loanProductLookup.getId().equals(productId)) { if (loanProductLookup.getId().equals(productId)) {
match = this.loanProductReadPlatformService match = this.loanProductReadPlatformService
.retrieveLoanProduct(loanProductLookup.getId()); .retrieveLoanProduct(loanProductLookup.getId());
Collection<ChargeData> chargeOptions = this.chargeReadPlatformService.retrieveLoanApplicableCharges();
chargeOptions.removeAll(match.getCharges());
match.setChargeOptions(chargeOptions);
break; break;
} }
} }
@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.mifosng.platform.api.commands.CalculateLoanScheduleCommand; 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.commands.SubmitLoanApplicationCommand;
import org.mifosng.platform.api.data.ApiParameterError; import org.mifosng.platform.api.data.ApiParameterError;
import org.mifosng.platform.exceptions.PlatformApiDataValidationException; import org.mifosng.platform.exceptions.PlatformApiDataValidationException;
@@ -46,7 +47,18 @@ public class SubmitLoanApplicationCommandValidator {
} catch (PlatformApiDataValidationException e) { } catch (PlatformApiDataValidationException e) {
dataValidationErrors.addAll(e.getErrors()); 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()) { if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
} }