FINERACT-1968: Advanced payment allocation strategy for Loan

This commit is contained in:
Adam Saghy
2023-08-30 13:47:30 +02:00
parent 349103015f
commit e2e10d2008
11 changed files with 341 additions and 40 deletions
@@ -237,6 +237,9 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
@Column(name = "loan_transaction_strategy_name")
private String transactionProcessingStrategyName;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch = FetchType.LAZY)
private List<LoanPaymentAllocationRule> paymentAllocationRules = new ArrayList<>();
@Embedded
private LoanProductRelatedDetail loanRepaymentScheduleDetail;
@@ -7187,4 +7190,20 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
public LoanInterestRecalculationDetails getLoanInterestRecalculationDetails() {
return loanInterestRecalculationDetails;
}
public List<LoanPaymentAllocationRule> getPaymentAllocationRules() {
return paymentAllocationRules;
}
public void setPaymentAllocationRules(List<LoanPaymentAllocationRule> loanPaymentAllocationRules) {
this.paymentAllocationRules = loanPaymentAllocationRules;
}
public String getTransactionProcessingStrategyCode() {
return transactionProcessingStrategyCode;
}
public String getTransactionProcessingStrategyName() {
return transactionProcessingStrategyName;
}
}
@@ -19,11 +19,10 @@
package org.apache.fineract.portfolio.loanaccount.domain;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Convert;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
@@ -35,6 +34,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
import org.apache.fineract.portfolio.loanproduct.domain.AllocationTypeListConverter;
import org.apache.fineract.portfolio.loanproduct.domain.FutureInstallmentAllocationRule;
import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationTransactionType;
import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
@@ -42,13 +42,13 @@ import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
@Getter
@Setter
@Entity
@Table(name = "m_loan_payment_allocation", uniqueConstraints = {
@Table(name = "m_loan_payment_allocation_rule", uniqueConstraints = {
@UniqueConstraint(columnNames = { "loan_id", "transaction_type" }, name = "uq_m_loan_payment_allocation_rule") })
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class LoanPaymentAllocationRule extends AbstractAuditableWithUTCDateTimeCustom {
@ManyToOne(fetch = FetchType.LAZY)
@ManyToOne
@JoinColumn(name = "loan_id", nullable = false)
private Loan loan;
@@ -56,7 +56,7 @@ public class LoanPaymentAllocationRule extends AbstractAuditableWithUTCDateTimeC
@Enumerated(EnumType.STRING)
private PaymentAllocationTransactionType transactionType;
@ElementCollection(fetch = FetchType.EAGER)
@Convert(converter = AllocationTypeListConverter.class)
@Column(name = "allocation_types", nullable = false)
private List<PaymentAllocationType> allocationTypes;
@@ -91,7 +91,7 @@ public class LoanProduct extends AbstractPersistableCustom {
private String transactionProcessingStrategyName;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loanProduct", orphanRemoval = true, fetch = FetchType.EAGER)
private List<LoanProductPaymentAllocationRule> loanProductPaymentAllocationRules = new ArrayList<>();
private List<LoanProductPaymentAllocationRule> paymentAllocationRules = new ArrayList<>();
@Column(name = "name", nullable = false, unique = true)
private String name;
@@ -600,7 +600,7 @@ public class LoanProduct extends AbstractPersistableCustom {
}
public LoanProduct(final Fund fund, final String transactionProcessingStrategyCode,
final List<LoanProductPaymentAllocationRule> loanProductPaymentAllocationRules, final String name, final String shortName,
final List<LoanProductPaymentAllocationRule> paymentAllocationRules, final String name, final String shortName,
final String description, final MonetaryCurrency currency, final BigDecimal defaultPrincipal,
final BigDecimal defaultMinPrincipal, final BigDecimal defaultMaxPrincipal,
final BigDecimal defaultNominalInterestRatePerPeriod, final BigDecimal defaultMinNominalInterestRatePerPeriod,
@@ -635,9 +635,9 @@ public class LoanProduct extends AbstractPersistableCustom {
this.fund = fund;
this.transactionProcessingStrategyCode = transactionProcessingStrategyCode;
this.loanProductPaymentAllocationRules = loanProductPaymentAllocationRules;
if (this.loanProductPaymentAllocationRules != null) {
for (LoanProductPaymentAllocationRule loanProductPaymentAllocationRule : this.loanProductPaymentAllocationRules) {
this.paymentAllocationRules = paymentAllocationRules;
if (this.paymentAllocationRules != null) {
for (LoanProductPaymentAllocationRule loanProductPaymentAllocationRule : this.paymentAllocationRules) {
loanProductPaymentAllocationRule.setLoanProduct(this);
}
}
@@ -731,7 +731,7 @@ public class LoanProduct extends AbstractPersistableCustom {
}
public void validateLoanProductPreSave() {
if (this.loanProductPaymentAllocationRules != null && loanProductPaymentAllocationRules.size() > 0
if (this.paymentAllocationRules != null && paymentAllocationRules.size() > 0
&& !transactionProcessingStrategyCode.equals("advanced-payment-allocation-strategy")) {
throw new LoanProductGeneralRuleException(
"payment_allocation.must.not.be.provided.when.allocation.strategy.is.not.advanced-payment-strategy",
@@ -867,8 +867,8 @@ public class LoanProduct extends AbstractPersistableCustom {
return this.charges;
}
public List<LoanProductPaymentAllocationRule> getLoanProductPaymentAllocationRules() {
return this.loanProductPaymentAllocationRules;
public List<LoanProductPaymentAllocationRule> getPaymentAllocationRules() {
return this.paymentAllocationRules;
}
public void update(final LoanProductConfigurableAttributes loanConfigurableAttributes) {
@@ -23,7 +23,6 @@ import jakarta.persistence.Convert;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
@@ -45,7 +44,7 @@ import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDa
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class LoanProductPaymentAllocationRule extends AbstractAuditableWithUTCDateTimeCustom {
@ManyToOne(fetch = FetchType.LAZY)
@ManyToOne
@JoinColumn(name = "loan_product_id", nullable = false)
private LoanProduct loanProduct;