MIFOSX-53 added post and template methods. WIP.
This commit is contained in:
+52
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
-2
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+38
-4
@@ -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()) {
|
||||||
|
|||||||
+50
-3
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+33
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-1
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user