waive and payment of installment charge corrections
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
CREATE TABLE `m_loan_installment_charge` (
|
||||||
|
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||||
|
`loan_charge_id` BIGINT(20) NOT NULL,
|
||||||
|
`loan_schedule_id` BIGINT(20) NOT NULL,
|
||||||
|
`due_date` DATE NULL DEFAULT NULL,
|
||||||
|
`amount` DECIMAL(19,6) NOT NULL,
|
||||||
|
`amount_paid_derived` DECIMAL(19,6) NULL DEFAULT NULL,
|
||||||
|
`amount_waived_derived` DECIMAL(19,6) NULL DEFAULT NULL,
|
||||||
|
`amount_writtenoff_derived` DECIMAL(19,6) NULL DEFAULT NULL,
|
||||||
|
`amount_outstanding_derived` DECIMAL(19,6) NOT NULL DEFAULT '0.000000',
|
||||||
|
`is_paid_derived` TINYINT(1) NOT NULL DEFAULT '0',
|
||||||
|
`waived` TINYINT(1) NOT NULL DEFAULT '0',
|
||||||
|
`amount_through_charge_payment` DECIMAL(19,6) NULL DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
CONSTRAINT `FK_loan_charge_id_charge_schedule` FOREIGN KEY (`loan_charge_id`) REFERENCES `m_loan_charge` (`id`),
|
||||||
|
CONSTRAINT `FK_loan_schedule_id_charge_schedule` FOREIGN KEY (`loan_schedule_id`) REFERENCES `m_loan_repayment_schedule` (`id`)
|
||||||
|
)
|
||||||
|
COLLATE='utf8_general_ci'
|
||||||
|
ENGINE=InnoDB;
|
||||||
+3
-18
@@ -21,45 +21,32 @@ import org.mifosplatform.portfolio.charge.domain.ChargeTimeType;
|
|||||||
public class LoanChargeData {
|
public class LoanChargeData {
|
||||||
|
|
||||||
private final Long id;
|
private final Long id;
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final Long chargeId;
|
private final Long chargeId;
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final String name;
|
private final String name;
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final EnumOptionData chargeTimeType;
|
private final EnumOptionData chargeTimeType;
|
||||||
|
|
||||||
private final LocalDate dueDate;
|
private final LocalDate dueDate;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final EnumOptionData chargeCalculationType;
|
private final EnumOptionData chargeCalculationType;
|
||||||
|
|
||||||
private final BigDecimal percentage;
|
private final BigDecimal percentage;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final BigDecimal amountPercentageAppliedTo;
|
private final BigDecimal amountPercentageAppliedTo;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final CurrencyData currency;
|
private final CurrencyData currency;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final BigDecimal amount;
|
private final BigDecimal amount;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final BigDecimal amountPaid;
|
private final BigDecimal amountPaid;
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final BigDecimal amountWaived;
|
private final BigDecimal amountWaived;
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final BigDecimal amountWrittenOff;
|
private final BigDecimal amountWrittenOff;
|
||||||
|
|
||||||
private final BigDecimal amountOutstanding;
|
private final BigDecimal amountOutstanding;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final BigDecimal amountOrPercentage;
|
private final BigDecimal amountOrPercentage;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final Collection<ChargeData> chargeOptions;
|
private final Collection<ChargeData> chargeOptions;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final boolean penalty;
|
private final boolean penalty;
|
||||||
|
|
||||||
private final EnumOptionData chargePaymentMode;
|
private final EnumOptionData chargePaymentMode;
|
||||||
@@ -68,17 +55,15 @@ public class LoanChargeData {
|
|||||||
|
|
||||||
private final boolean waived;
|
private final boolean waived;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final boolean chargePayable;
|
private final boolean chargePayable;
|
||||||
|
|
||||||
private final Long loanId;
|
private final Long loanId;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final BigDecimal minCap;
|
private final BigDecimal minCap;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final BigDecimal maxCap;
|
private final BigDecimal maxCap;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private final Collection<LoanInstallmentChargeData> installmentChargeData;
|
private final Collection<LoanInstallmentChargeData> installmentChargeData;
|
||||||
|
|
||||||
public static LoanChargeData template(final Collection<ChargeData> chargeOptions) {
|
public static LoanChargeData template(final Collection<ChargeData> chargeOptions) {
|
||||||
@@ -181,7 +166,7 @@ public class LoanChargeData {
|
|||||||
this.installmentChargeData = installmentChargeData;
|
this.installmentChargeData = installmentChargeData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoanChargeData(final Long id, final LocalDate dueAsOfDate, final BigDecimal amountOutstanding, final Long loanId, Collection<LoanInstallmentChargeData> installmentChargeData) {
|
public LoanChargeData(final Long id, final LocalDate dueAsOfDate, final BigDecimal amountOutstanding, EnumOptionData chargeTimeType, final Long loanId, Collection<LoanInstallmentChargeData> installmentChargeData) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.chargeId = null;
|
this.chargeId = null;
|
||||||
this.name = null;
|
this.name = null;
|
||||||
@@ -191,7 +176,7 @@ public class LoanChargeData {
|
|||||||
this.amountWaived = null;
|
this.amountWaived = null;
|
||||||
this.amountWrittenOff = null;
|
this.amountWrittenOff = null;
|
||||||
this.amountOutstanding = amountOutstanding;
|
this.amountOutstanding = amountOutstanding;
|
||||||
this.chargeTimeType = null;
|
this.chargeTimeType = chargeTimeType;
|
||||||
this.dueDate = dueAsOfDate;
|
this.dueDate = dueAsOfDate;
|
||||||
this.chargeCalculationType = null;
|
this.chargeCalculationType = null;
|
||||||
this.percentage = null;
|
this.percentage = null;
|
||||||
|
|||||||
+17
-6
@@ -885,8 +885,9 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateLoanSchedule(final LoanScheduleModel modifiedLoanSchedule) {
|
public void updateLoanSchedule(final LoanScheduleModel modifiedLoanSchedule) {
|
||||||
|
clearInstallmentLoanCharge();
|
||||||
this.repaymentScheduleInstallments.clear();
|
this.repaymentScheduleInstallments.clear();
|
||||||
|
|
||||||
for (final LoanScheduleModelPeriod scheduledLoanInstallment : modifiedLoanSchedule.getPeriods()) {
|
for (final LoanScheduleModelPeriod scheduledLoanInstallment : modifiedLoanSchedule.getPeriods()) {
|
||||||
|
|
||||||
if (scheduledLoanInstallment.isRepaymentPeriod()) {
|
if (scheduledLoanInstallment.isRepaymentPeriod()) {
|
||||||
@@ -901,6 +902,15 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
updateLoanScheduleDependentDerivedFields();
|
updateLoanScheduleDependentDerivedFields();
|
||||||
updateLoanSummaryDerivedFields();
|
updateLoanSummaryDerivedFields();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearInstallmentLoanCharge(){
|
||||||
|
for(LoanCharge loanCharge:this.charges){
|
||||||
|
if(loanCharge.isInstalmentFee()){
|
||||||
|
loanCharge.clearLoanInstallmentCharges();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateLoanScheduleDependentDerivedFields() {
|
private void updateLoanScheduleDependentDerivedFields() {
|
||||||
@@ -2979,20 +2989,21 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
return this.charges;
|
return this.charges;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<LoanInstallmentCharge> createInstallmentLoanCharges(final LoanCharge loanCharge){
|
public Set<LoanInstallmentCharge> generateInstallmentLoanCharges(final LoanCharge loanCharge){
|
||||||
Set<LoanInstallmentCharge> loanChargePerInstallments = new HashSet<LoanInstallmentCharge>();
|
Set<LoanInstallmentCharge> loanChargePerInstallments = new HashSet<LoanInstallmentCharge>();
|
||||||
if(loanCharge.isInstalmentFee()){
|
if(loanCharge.isInstalmentFee()){
|
||||||
for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) {
|
for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) {
|
||||||
BigDecimal amount = BigDecimal.ZERO;;
|
BigDecimal amount = BigDecimal.ZERO;
|
||||||
if(loanCharge.getChargeCalculation().isFlat()){
|
if(loanCharge.getChargeCalculation().isFlat()){
|
||||||
amount = loanCharge.amount();
|
amount = loanCharge.amount().divide(BigDecimal.valueOf(repaymentScheduleDetail().getNumberOfRepayments()));
|
||||||
}else{
|
}else{
|
||||||
amount = calculateInstallmentChargeAmount(loanCharge.getChargeCalculation(), loanCharge.getPercentage(), installment).getAmount();
|
amount = calculateInstallmentChargeAmount(loanCharge.getChargeCalculation(), loanCharge.getPercentage(), installment).getAmount();
|
||||||
}
|
}
|
||||||
LoanInstallmentCharge loanChargePerInstallment = new LoanInstallmentCharge(amount, loanCharge, installment);
|
LoanInstallmentCharge loanInstallmentCharge = new LoanInstallmentCharge(amount, loanCharge, installment);
|
||||||
loanChargePerInstallments.add(loanChargePerInstallment);
|
loanChargePerInstallments.add(loanInstallmentCharge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return loanChargePerInstallments;
|
return loanChargePerInstallments;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+50
-22
@@ -8,6 +8,7 @@ package org.mifosplatform.portfolio.loanaccount.domain;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.MathContext;
|
import java.math.MathContext;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@@ -107,7 +108,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
@LazyCollection(LazyCollectionOption.FALSE)
|
@LazyCollection(LazyCollectionOption.FALSE)
|
||||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loancharge", orphanRemoval = true)
|
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loancharge", orphanRemoval = true)
|
||||||
private Set<LoanInstallmentCharge> loanChargePerInstallments = new HashSet<LoanInstallmentCharge>();
|
private Set<LoanInstallmentCharge> loanInstallmentCharge = new HashSet<LoanInstallmentCharge>();
|
||||||
|
|
||||||
public static LoanCharge createNewFromJson(final Loan loan, final Charge chargeDefinition, final JsonCommand command) {
|
public static LoanCharge createNewFromJson(final Loan loan, final Charge chargeDefinition, final JsonCommand command) {
|
||||||
|
|
||||||
@@ -248,14 +249,14 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
this.amountOrPercentage = chargeAmount;
|
this.amountOrPercentage = chargeAmount;
|
||||||
if(this.loan!=null && this.isInstalmentFee()){
|
if(this.loan!=null && this.isInstalmentFee()){
|
||||||
Set<LoanInstallmentCharge> chargePerInstallments = this.loan.createInstallmentLoanCharges(this);
|
Set<LoanInstallmentCharge> chargePerInstallments = this.loan.generateInstallmentLoanCharges(this);
|
||||||
if(this.loanChargePerInstallments.isEmpty()){
|
if(this.loanInstallmentCharge.isEmpty()){
|
||||||
this.loanChargePerInstallments.addAll(chargePerInstallments);
|
this.loanInstallmentCharge.addAll(chargePerInstallments);
|
||||||
}else{
|
}else{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
LoanInstallmentCharge[] loanChargePerInstallments = new LoanInstallmentCharge[chargePerInstallments.size()];
|
LoanInstallmentCharge[] loanChargePerInstallments = new LoanInstallmentCharge[chargePerInstallments.size()];
|
||||||
LoanInstallmentCharge[] loanChargePerInstallmentArray = chargePerInstallments.toArray(loanChargePerInstallments);
|
LoanInstallmentCharge[] loanChargePerInstallmentArray = chargePerInstallments.toArray(loanChargePerInstallments);
|
||||||
for(LoanInstallmentCharge chargePerInstallment:this.loanChargePerInstallments){
|
for(LoanInstallmentCharge chargePerInstallment:this.loanInstallmentCharge){
|
||||||
chargePerInstallment.copyFrom(loanChargePerInstallmentArray[index++]);
|
chargePerInstallment.copyFrom(loanChargePerInstallmentArray[index++]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,12 +276,18 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
|||||||
this.amountOutstanding = calculateAmountOutstanding(currency);
|
this.amountOutstanding = calculateAmountOutstanding(currency);
|
||||||
this.paid = false;
|
this.paid = false;
|
||||||
this.waived = false;
|
this.waived = false;
|
||||||
|
for(LoanInstallmentCharge installmentCharge:loanInstallmentCharge){
|
||||||
|
installmentCharge.resetPaidAmount(currency);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetPaidAmount(final MonetaryCurrency currency) {
|
public void resetPaidAmount(final MonetaryCurrency currency) {
|
||||||
this.amountPaid = BigDecimal.ZERO;
|
this.amountPaid = BigDecimal.ZERO;
|
||||||
this.amountOutstanding = calculateAmountOutstanding(currency);
|
this.amountOutstanding = calculateAmountOutstanding(currency);
|
||||||
this.paid = false;
|
this.paid = false;
|
||||||
|
for(LoanInstallmentCharge installmentCharge:loanInstallmentCharge){
|
||||||
|
installmentCharge.resetPaidAmount(currency);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money waive(final MonetaryCurrency currency, Integer loanInstallmentNumber) {
|
public Money waive(final MonetaryCurrency currency, Integer loanInstallmentNumber) {
|
||||||
@@ -347,14 +354,14 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
this.amountOrPercentage = amount;
|
this.amountOrPercentage = amount;
|
||||||
if(this.loan !=null && this.isInstalmentFee()){
|
if(this.loan !=null && this.isInstalmentFee()){
|
||||||
Set<LoanInstallmentCharge> chargePerInstallments = this.loan.createInstallmentLoanCharges(this);
|
Set<LoanInstallmentCharge> chargePerInstallments = this.loan.generateInstallmentLoanCharges(this);
|
||||||
if(this.loanChargePerInstallments.isEmpty()){
|
if(this.loanInstallmentCharge.isEmpty()){
|
||||||
this.loanChargePerInstallments.addAll(chargePerInstallments);
|
this.loanInstallmentCharge.addAll(chargePerInstallments);
|
||||||
}else{
|
}else{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
LoanInstallmentCharge[] loanChargePerInstallments = new LoanInstallmentCharge[chargePerInstallments.size()];
|
LoanInstallmentCharge[] loanChargePerInstallments = new LoanInstallmentCharge[chargePerInstallments.size()];
|
||||||
LoanInstallmentCharge[] loanChargePerInstallmentArray = chargePerInstallments.toArray(loanChargePerInstallments);
|
LoanInstallmentCharge[] loanChargePerInstallmentArray = chargePerInstallments.toArray(loanChargePerInstallments);
|
||||||
for(LoanInstallmentCharge chargePerInstallment:this.loanChargePerInstallments){
|
for(LoanInstallmentCharge chargePerInstallment:this.loanInstallmentCharge){
|
||||||
chargePerInstallment.copyFrom(loanChargePerInstallmentArray[index++]);
|
chargePerInstallment.copyFrom(loanChargePerInstallmentArray[index++]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -410,14 +417,14 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
this.amountOrPercentage = newValue;
|
this.amountOrPercentage = newValue;
|
||||||
if(this.isInstalmentFee()){
|
if(this.isInstalmentFee()){
|
||||||
Set<LoanInstallmentCharge> chargePerInstallments = this.loan.createInstallmentLoanCharges(this);
|
Set<LoanInstallmentCharge> chargePerInstallments = this.loan.generateInstallmentLoanCharges(this);
|
||||||
if(this.loanChargePerInstallments.isEmpty()){
|
if(this.loanInstallmentCharge.isEmpty()){
|
||||||
this.loanChargePerInstallments.addAll(chargePerInstallments);
|
this.loanInstallmentCharge.addAll(chargePerInstallments);
|
||||||
}else{
|
}else{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
LoanInstallmentCharge[] loanChargePerInstallments = new LoanInstallmentCharge[chargePerInstallments.size()];
|
LoanInstallmentCharge[] loanChargePerInstallments = new LoanInstallmentCharge[chargePerInstallments.size()];
|
||||||
LoanInstallmentCharge[] loanChargePerInstallmentArray = chargePerInstallments.toArray(loanChargePerInstallments);
|
LoanInstallmentCharge[] loanChargePerInstallmentArray = chargePerInstallments.toArray(loanChargePerInstallments);
|
||||||
for(LoanInstallmentCharge chargePerInstallment:this.loanChargePerInstallments){
|
for(LoanInstallmentCharge chargePerInstallment:this.loanInstallmentCharge){
|
||||||
chargePerInstallment.copyFrom(loanChargePerInstallmentArray[index++]);
|
chargePerInstallment.copyFrom(loanChargePerInstallmentArray[index++]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -603,17 +610,18 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param feeAmount TODO
|
||||||
* @param processAmount
|
* @param processAmount
|
||||||
* Amount used to pay off this charge
|
* Amount used to pay off this charge
|
||||||
* @return Actual amount paid on this charge
|
* @return Actual amount paid on this charge
|
||||||
*/
|
*/
|
||||||
public Money updatePaidAmountBy(final Money incrementBy,final Integer installmentNumber) {
|
public Money updatePaidAmountBy(final Money incrementBy,final Integer installmentNumber, Money feeAmount) {
|
||||||
Money processAmount = Money.zero(incrementBy.getCurrency());
|
Money processAmount = Money.zero(incrementBy.getCurrency());
|
||||||
if(this.isInstalmentFee()){
|
if(this.isInstalmentFee()){
|
||||||
if(installmentNumber == null){
|
if(installmentNumber == null){
|
||||||
processAmount = getUnpaidInstallmentLoanCharge().updatePaidAmountBy(incrementBy);
|
processAmount = getUnpaidInstallmentLoanCharge().updatePaidAmountBy(incrementBy, feeAmount);
|
||||||
}else{
|
}else{
|
||||||
processAmount = getInstallmentLoanCharge(installmentNumber).updatePaidAmountBy(incrementBy);
|
processAmount = getInstallmentLoanCharge(installmentNumber).updatePaidAmountBy(incrementBy, feeAmount);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
processAmount = incrementBy;
|
processAmount = incrementBy;
|
||||||
@@ -631,9 +639,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
|||||||
amountPaidOnThisCharge = processAmount;
|
amountPaidOnThisCharge = processAmount;
|
||||||
amountPaidToDate = amountPaidToDate.plus(processAmount);
|
amountPaidToDate = amountPaidToDate.plus(processAmount);
|
||||||
this.amountPaid = amountPaidToDate.getAmount();
|
this.amountPaid = amountPaidToDate.getAmount();
|
||||||
|
this.amountOutstanding = calculateAmountOutstanding(incrementBy.getCurrency());
|
||||||
final Money amountExpected = Money.of(processAmount.getCurrency(), this.amount);
|
|
||||||
this.amountOutstanding = amountExpected.minus(amountPaidToDate).getAmount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.paid = determineIfFullyPaid();
|
this.paid = determineIfFullyPaid();
|
||||||
@@ -695,7 +701,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
public LoanInstallmentCharge getUnpaidInstallmentLoanCharge() {
|
public LoanInstallmentCharge getUnpaidInstallmentLoanCharge() {
|
||||||
LoanInstallmentCharge unpaidChargePerInstallment = null;
|
LoanInstallmentCharge unpaidChargePerInstallment = null;
|
||||||
for (LoanInstallmentCharge loanChargePerInstallment : this.loanChargePerInstallments) {
|
for (LoanInstallmentCharge loanChargePerInstallment : this.loanInstallmentCharge) {
|
||||||
if (loanChargePerInstallment.isPending()
|
if (loanChargePerInstallment.isPending()
|
||||||
&& (unpaidChargePerInstallment == null || unpaidChargePerInstallment.getRepaymentInstallment().getDueDate()
|
&& (unpaidChargePerInstallment == null || unpaidChargePerInstallment.getRepaymentInstallment().getDueDate()
|
||||||
.isAfter(loanChargePerInstallment.getRepaymentInstallment().getDueDate()))) {
|
.isAfter(loanChargePerInstallment.getRepaymentInstallment().getDueDate()))) {
|
||||||
@@ -706,7 +712,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public LoanInstallmentCharge getInstallmentLoanCharge(LocalDate periodDueDate) {
|
public LoanInstallmentCharge getInstallmentLoanCharge(LocalDate periodDueDate) {
|
||||||
for (LoanInstallmentCharge loanChargePerInstallment : this.loanChargePerInstallments) {
|
for (LoanInstallmentCharge loanChargePerInstallment : this.loanInstallmentCharge) {
|
||||||
if (periodDueDate.isEqual(loanChargePerInstallment.getRepaymentInstallment().getDueDate())) {
|
if (periodDueDate.isEqual(loanChargePerInstallment.getRepaymentInstallment().getDueDate())) {
|
||||||
return loanChargePerInstallment;
|
return loanChargePerInstallment;
|
||||||
}
|
}
|
||||||
@@ -715,11 +721,33 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public LoanInstallmentCharge getInstallmentLoanCharge(Integer installmentNumber) {
|
public LoanInstallmentCharge getInstallmentLoanCharge(Integer installmentNumber) {
|
||||||
for (LoanInstallmentCharge loanChargePerInstallment : this.loanChargePerInstallments) {
|
for (LoanInstallmentCharge loanChargePerInstallment : this.loanInstallmentCharge) {
|
||||||
if (installmentNumber.equals(loanChargePerInstallment.getRepaymentInstallment().getInstallmentNumber().intValue()) ){
|
if (installmentNumber.equals(loanChargePerInstallment.getRepaymentInstallment().getInstallmentNumber().intValue()) ){
|
||||||
return loanChargePerInstallment;
|
return loanChargePerInstallment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearLoanInstallmentCharges(){
|
||||||
|
this.loanInstallmentCharge.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLoanInstallmentCharges(Collection<LoanInstallmentCharge> installmentCharges){
|
||||||
|
this.loanInstallmentCharge.addAll(installmentCharges);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNoLoanInstallmentCharges(){
|
||||||
|
return this.loanInstallmentCharge.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoanRepaymentScheduleInstallment fetchRepaymentInstallment(Money trasferedAmount){
|
||||||
|
for (LoanInstallmentCharge loanChargePerInstallment : this.loanInstallmentCharge) {
|
||||||
|
if (loanChargePerInstallment.isPending() &&
|
||||||
|
trasferedAmount.getAmount().equals(loanChargePerInstallment.getAmountThroughChargePayment(trasferedAmount.getCurrency()).getAmount()) ){
|
||||||
|
return loanChargePerInstallment.getRepaymentInstallment();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+40
-6
@@ -44,6 +44,9 @@ public class LoanInstallmentCharge extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
@Column(name = "amount_outstanding_derived", scale = 6, precision = 19, nullable = false)
|
@Column(name = "amount_outstanding_derived", scale = 6, precision = 19, nullable = false)
|
||||||
private BigDecimal amountOutstanding;
|
private BigDecimal amountOutstanding;
|
||||||
|
|
||||||
|
@Column(name = "amount_through_charge_payment", scale = 6, precision = 19, nullable = true)
|
||||||
|
private BigDecimal amountThroughChargePayment;
|
||||||
|
|
||||||
@Column(name = "is_paid_derived", nullable = false)
|
@Column(name = "is_paid_derived", nullable = false)
|
||||||
private boolean paid = false;
|
private boolean paid = false;
|
||||||
@@ -122,12 +125,24 @@ public class LoanInstallmentCharge extends AbstractPersistable<Long> {
|
|||||||
public BigDecimal getAmount() {
|
public BigDecimal getAmount() {
|
||||||
return this.amount;
|
return this.amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Money getAmount(final MonetaryCurrency currency) {
|
||||||
|
return Money.of(currency, this.amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Money getAmountPaid(final MonetaryCurrency currency) {
|
||||||
|
return Money.of(currency, this.amountPaid);
|
||||||
|
}
|
||||||
|
|
||||||
public BigDecimal getAmountOutstanding() {
|
public BigDecimal getAmountOutstanding() {
|
||||||
return this.amountOutstanding;
|
return this.amountOutstanding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BigDecimal calculateAmountOutstanding(final MonetaryCurrency currency) {
|
||||||
|
return getAmount(currency).minus(getAmountWaived(currency)).minus(getAmountPaid(currency)).getAmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isPaid() {
|
public boolean isPaid() {
|
||||||
return this.paid;
|
return this.paid;
|
||||||
}
|
}
|
||||||
@@ -145,7 +160,7 @@ public class LoanInstallmentCharge extends AbstractPersistable<Long> {
|
|||||||
return this.installment;
|
return this.installment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money updatePaidAmountBy(final Money incrementBy) {
|
public Money updatePaidAmountBy(final Money incrementBy, Money feeAmount) {
|
||||||
|
|
||||||
Money amountPaidToDate = Money.of(incrementBy.getCurrency(), this.amountPaid);
|
Money amountPaidToDate = Money.of(incrementBy.getCurrency(), this.amountPaid);
|
||||||
final Money amountOutstanding = Money.of(incrementBy.getCurrency(), this.amountOutstanding);
|
final Money amountOutstanding = Money.of(incrementBy.getCurrency(), this.amountOutstanding);
|
||||||
@@ -160,11 +175,9 @@ public class LoanInstallmentCharge extends AbstractPersistable<Long> {
|
|||||||
amountPaidOnThisCharge = incrementBy;
|
amountPaidOnThisCharge = incrementBy;
|
||||||
amountPaidToDate = amountPaidToDate.plus(incrementBy);
|
amountPaidToDate = amountPaidToDate.plus(incrementBy);
|
||||||
this.amountPaid = amountPaidToDate.getAmount();
|
this.amountPaid = amountPaidToDate.getAmount();
|
||||||
|
this.amountOutstanding = calculateAmountOutstanding(incrementBy.getCurrency());
|
||||||
final Money amountExpected = Money.of(incrementBy.getCurrency(), this.amount);
|
|
||||||
this.amountOutstanding = amountExpected.minus(amountPaidToDate).getAmount();
|
|
||||||
}
|
}
|
||||||
|
this.amountThroughChargePayment = feeAmount.getAmount();
|
||||||
this.paid = determineIfFullyPaid();
|
this.paid = determineIfFullyPaid();
|
||||||
|
|
||||||
return amountPaidOnThisCharge;
|
return amountPaidOnThisCharge;
|
||||||
@@ -174,4 +187,25 @@ public class LoanInstallmentCharge extends AbstractPersistable<Long> {
|
|||||||
public Money getAmountWrittenOff(final MonetaryCurrency currency) {
|
public Money getAmountWrittenOff(final MonetaryCurrency currency) {
|
||||||
return Money.of(currency, this.amountWrittenOff);
|
return Money.of(currency, this.amountWrittenOff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void resetPaidAmount(final MonetaryCurrency currency) {
|
||||||
|
this.amountPaid = BigDecimal.ZERO;
|
||||||
|
this.amountOutstanding = calculateAmountOutstanding(currency);
|
||||||
|
this.paid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetToOriginal(final MonetaryCurrency currency) {
|
||||||
|
this.amountPaid = BigDecimal.ZERO;
|
||||||
|
this.amountWaived = BigDecimal.ZERO;
|
||||||
|
this.amountWrittenOff = BigDecimal.ZERO;
|
||||||
|
this.amountOutstanding = calculateAmountOutstanding(currency);
|
||||||
|
this.paid = false;
|
||||||
|
this.waived = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Money getAmountThroughChargePayment(final MonetaryCurrency currency) {
|
||||||
|
return Money.of(currency, this.amountThroughChargePayment);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
-5
@@ -13,6 +13,7 @@ import java.util.Set;
|
|||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
@@ -105,11 +106,6 @@ public final class LoanRepaymentScheduleInstallment extends AbstractAuditableCus
|
|||||||
@Column(name = "obligations_met_on_date")
|
@Column(name = "obligations_met_on_date")
|
||||||
private Date obligationsMetOnDate;
|
private Date obligationsMetOnDate;
|
||||||
|
|
||||||
@LazyCollection(LazyCollectionOption.FALSE)
|
|
||||||
@OneToMany(cascade = CascadeType.ALL)
|
|
||||||
private Set<LoanInstallmentCharge> loanChargePerInstallments = new HashSet<LoanInstallmentCharge>();
|
|
||||||
|
|
||||||
|
|
||||||
protected LoanRepaymentScheduleInstallment() {
|
protected LoanRepaymentScheduleInstallment() {
|
||||||
this.installmentNumber = null;
|
this.installmentNumber = null;
|
||||||
this.fromDate = null;
|
this.fromDate = null;
|
||||||
|
|||||||
+19
-3
@@ -69,12 +69,24 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
final List<LoanTransaction> transactionstoBeProcessed = new ArrayList<LoanTransaction>();
|
final List<LoanTransaction> transactionstoBeProcessed = new ArrayList<LoanTransaction>();
|
||||||
for (final LoanTransaction loanTransaction : transactionsPostDisbursement) {
|
for (final LoanTransaction loanTransaction : transactionsPostDisbursement) {
|
||||||
if (loanTransaction.isChargePayment()) {
|
if (loanTransaction.isChargePayment()) {
|
||||||
|
final List<LoanRepaymentScheduleInstallment> chargePaymentInstallments = new ArrayList<LoanRepaymentScheduleInstallment>();
|
||||||
final Set<LoanChargePaidBy> chargePaidBies = loanTransaction.getLoanChargesPaid();
|
final Set<LoanChargePaidBy> chargePaidBies = loanTransaction.getLoanChargesPaid();
|
||||||
final Set<LoanCharge> transferCharges = new HashSet<LoanCharge>();
|
final Set<LoanCharge> transferCharges = new HashSet<LoanCharge>();
|
||||||
for (final LoanChargePaidBy chargePaidBy : chargePaidBies) {
|
for (final LoanChargePaidBy chargePaidBy : chargePaidBies) {
|
||||||
transferCharges.add(chargePaidBy.getLoanCharge());
|
LoanCharge loanCharge = chargePaidBy.getLoanCharge();
|
||||||
|
transferCharges.add(loanCharge);
|
||||||
|
if(loanCharge.isInstalmentFee()){
|
||||||
|
LoanRepaymentScheduleInstallment installment = null;
|
||||||
|
if(loanCharge.isFeeCharge()){
|
||||||
|
installment = loanCharge.fetchRepaymentInstallment(loanTransaction.getFeeChargesPortion(currency));
|
||||||
|
}else{
|
||||||
|
installment = loanCharge.fetchRepaymentInstallment(loanTransaction.getPenaltyChargesPortion(currency));
|
||||||
|
}
|
||||||
|
if(installment !=null){
|
||||||
|
chargePaymentInstallments.add(installment);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
final List<LoanRepaymentScheduleInstallment> chargePaymentInstallments = new ArrayList<LoanRepaymentScheduleInstallment>();
|
|
||||||
LocalDate startDate = disbursementDate;
|
LocalDate startDate = disbursementDate;
|
||||||
for (final LoanRepaymentScheduleInstallment installment : installments) {
|
for (final LoanRepaymentScheduleInstallment installment : installments) {
|
||||||
for (final LoanCharge loanCharge : transferCharges) {
|
for (final LoanCharge loanCharge : transferCharges) {
|
||||||
@@ -221,7 +233,11 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
Money amountRemaining = feeCharges;
|
Money amountRemaining = feeCharges;
|
||||||
while(amountRemaining.isGreaterThanZero()) {
|
while(amountRemaining.isGreaterThanZero()) {
|
||||||
final LoanCharge unpaidCharge = findEarliestUnpaidChargeFromUnOrderedSet(charges);
|
final LoanCharge unpaidCharge = findEarliestUnpaidChargeFromUnOrderedSet(charges);
|
||||||
final Money amountPaidTowardsCharge = unpaidCharge.updatePaidAmountBy(amountRemaining,installmentNumber);
|
Money feeAmount = feeCharges.zero();
|
||||||
|
if(loanTransaction.isChargePayment()){
|
||||||
|
feeAmount = feeCharges;
|
||||||
|
}
|
||||||
|
final Money amountPaidTowardsCharge = unpaidCharge.updatePaidAmountBy(amountRemaining,installmentNumber, feeAmount);
|
||||||
if (!amountPaidTowardsCharge.isZero()) {
|
if (!amountPaidTowardsCharge.isZero()) {
|
||||||
if (!loanTransaction.isChargePayment()) {
|
if (!loanTransaction.isChargePayment()) {
|
||||||
final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(loanTransaction, unpaidCharge,
|
final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(loanTransaction, unpaidCharge,
|
||||||
|
|||||||
+17
-2
@@ -5,8 +5,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.portfolio.loanaccount.service;
|
package org.mifosplatform.portfolio.loanaccount.service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -47,6 +49,8 @@ import org.mifosplatform.portfolio.group.exception.GroupNotActiveException;
|
|||||||
import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
|
import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanChargeRepository;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanInstallmentCharge;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
|
||||||
@@ -109,6 +113,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
private final CalendarInstanceRepository calendarInstanceRepository;
|
||||||
private final SavingsAccountAssembler savingsAccountAssembler;
|
private final SavingsAccountAssembler savingsAccountAssembler;
|
||||||
private final AccountAssociationsRepository accountAssociationsRepository;
|
private final AccountAssociationsRepository accountAssociationsRepository;
|
||||||
|
private final LoanChargeRepository loanChargeRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper,
|
public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper,
|
||||||
@@ -122,7 +127,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
final LoanSummaryWrapper loanSummaryWrapper, final GroupRepositoryWrapper groupRepository,
|
final LoanSummaryWrapper loanSummaryWrapper, final GroupRepositoryWrapper groupRepository,
|
||||||
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
||||||
final CalendarRepository calendarRepository, final CalendarInstanceRepository calendarInstanceRepository,
|
final CalendarRepository calendarRepository, final CalendarInstanceRepository calendarInstanceRepository,
|
||||||
final SavingsAccountAssembler savingsAccountAssembler, final AccountAssociationsRepository accountAssociationsRepository) {
|
final SavingsAccountAssembler savingsAccountAssembler, final AccountAssociationsRepository accountAssociationsRepository,
|
||||||
|
final LoanChargeRepository loanChargeRepository) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.fromJsonHelper = fromJsonHelper;
|
this.fromJsonHelper = fromJsonHelper;
|
||||||
this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator;
|
this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator;
|
||||||
@@ -145,6 +151,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
this.calendarInstanceRepository = calendarInstanceRepository;
|
||||||
this.savingsAccountAssembler = savingsAccountAssembler;
|
this.savingsAccountAssembler = savingsAccountAssembler;
|
||||||
this.accountAssociationsRepository = accountAssociationsRepository;
|
this.accountAssociationsRepository = accountAssociationsRepository;
|
||||||
|
this.loanChargeRepository = loanChargeRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
||||||
@@ -333,7 +340,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
|
|
||||||
if (changes.containsKey("recalculateLoanSchedule")) {
|
if (changes.containsKey("recalculateLoanSchedule")) {
|
||||||
changes.remove("recalculateLoanSchedule");
|
changes.remove("recalculateLoanSchedule");
|
||||||
|
|
||||||
final JsonElement parsedQuery = this.fromJsonHelper.parse(command.json());
|
final JsonElement parsedQuery = this.fromJsonHelper.parse(command.json());
|
||||||
final JsonQuery query = JsonQuery.from(command.json(), parsedQuery, this.fromJsonHelper);
|
final JsonQuery query = JsonQuery.from(command.json(), parsedQuery, this.fromJsonHelper);
|
||||||
|
|
||||||
@@ -354,6 +361,14 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
final Note note = Note.loanNote(existingLoanApplication, submittedOnNote);
|
final Note note = Note.loanNote(existingLoanApplication, submittedOnNote);
|
||||||
this.noteRepository.save(note);
|
this.noteRepository.save(note);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (final LoanCharge loanCharge : existingLoanApplication.charges()) {
|
||||||
|
if(loanCharge.isInstalmentFee() && loanCharge.hasNoLoanInstallmentCharges()){
|
||||||
|
Set<LoanInstallmentCharge> chargePerInstallments = existingLoanApplication.generateInstallmentLoanCharges(loanCharge);
|
||||||
|
loanCharge.addLoanInstallmentCharges(chargePerInstallments);
|
||||||
|
this.loanChargeRepository.save(loanCharge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final Long calendarId = command.longValueOfParameterNamed("calendarId");
|
final Long calendarId = command.longValueOfParameterNamed("calendarId");
|
||||||
Calendar calendar = null;
|
Calendar calendar = null;
|
||||||
|
|||||||
+10
-4
@@ -169,7 +169,10 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
|
|||||||
|
|
||||||
public String schema() {
|
public String schema() {
|
||||||
return "lc.id as id, lc.due_for_collection_as_of_date as dueAsOfDate, "
|
return "lc.id as id, lc.due_for_collection_as_of_date as dueAsOfDate, "
|
||||||
+ "lc.amount_outstanding_derived as amountOutstanding, " + "loan.id as loanId " + "from m_loan_charge lc "
|
+ "lc.amount_outstanding_derived as amountOutstanding, "
|
||||||
|
+ "lc.charge_time_enum as chargeTime, "
|
||||||
|
+ "loan.id as loanId "
|
||||||
|
+ "from m_loan_charge lc "
|
||||||
+ "join m_loan loan on loan.id = lc.loan_id ";
|
+ "join m_loan loan on loan.id = lc.loan_id ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +183,10 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
|
|||||||
final LocalDate dueAsOfDate = JdbcSupport.getLocalDate(rs, "dueAsOfDate");
|
final LocalDate dueAsOfDate = JdbcSupport.getLocalDate(rs, "dueAsOfDate");
|
||||||
final Long loanId = rs.getLong("loanId");
|
final Long loanId = rs.getLong("loanId");
|
||||||
final BigDecimal amountOutstanding = rs.getBigDecimal("amountOutstanding");
|
final BigDecimal amountOutstanding = rs.getBigDecimal("amountOutstanding");
|
||||||
return new LoanChargeData(id, dueAsOfDate, amountOutstanding, loanId, null);
|
final int chargeTime = rs.getInt("chargeTime");
|
||||||
|
final EnumOptionData chargeTimeType = ChargeEnumerations.chargeTimeType(chargeTime);
|
||||||
|
|
||||||
|
return new LoanChargeData(id, dueAsOfDate, amountOutstanding, chargeTimeType, loanId, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +196,7 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
|
|||||||
String sql = "select " + rm.schema()
|
String sql = "select " + rm.schema()
|
||||||
+ "where lic.loan_charge_id= ? ";
|
+ "where lic.loan_charge_id= ? ";
|
||||||
if(onlyPaymentPendingCharges){
|
if(onlyPaymentPendingCharges){
|
||||||
sql = sql +"and lc.waived =0 and lc.is_paid_derived=0";
|
sql = sql +"and lic.waived =0 and lic.is_paid_derived=0";
|
||||||
}
|
}
|
||||||
return this.jdbcTemplate.query(sql, rm, new Object[] { loanChargeId });
|
return this.jdbcTemplate.query(sql, rm, new Object[] { loanChargeId });
|
||||||
}
|
}
|
||||||
@@ -200,7 +206,7 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
|
|||||||
public String schema() {
|
public String schema() {
|
||||||
return " lsi.installment as installmentNumber, lsi.duedate as dueAsOfDate, "
|
return " lsi.installment as installmentNumber, lsi.duedate as dueAsOfDate, "
|
||||||
+ "lic.amount_outstanding_derived as amountOutstanding,"
|
+ "lic.amount_outstanding_derived as amountOutstanding,"
|
||||||
+ "lic.amount as amount"
|
+ "lic.amount as amount, "
|
||||||
+ "lic.is_paid_derived as paid, "
|
+ "lic.is_paid_derived as paid, "
|
||||||
+ "lic.waived as waied "
|
+ "lic.waived as waied "
|
||||||
+ "from m_loan_installment_charge lic "
|
+ "from m_loan_installment_charge lic "
|
||||||
|
|||||||
+33
-7
@@ -266,6 +266,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
for (final LoanCharge loanCharge : loanCharges) {
|
for (final LoanCharge loanCharge : loanCharges) {
|
||||||
if (loanCharge.isDueAtDisbursement() && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()) {
|
if (loanCharge.isDueAtDisbursement() && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()) {
|
||||||
disBuLoanCharges.put(loanCharge.getId(), loanCharge.amount());
|
disBuLoanCharges.put(loanCharge.getId(), loanCharge.amount());
|
||||||
|
}else if(loanCharge.isInstalmentFee() && loanCharge.hasNoLoanInstallmentCharges()){
|
||||||
|
Set<LoanInstallmentCharge> chargePerInstallments = loan.generateInstallmentLoanCharges(loanCharge);
|
||||||
|
loanCharge.addLoanInstallmentCharges(chargePerInstallments);
|
||||||
|
this.loanChargeRepository.save(loanCharge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final Locale locale = command.extractLocale();
|
final Locale locale = command.extractLocale();
|
||||||
@@ -384,6 +388,26 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
|
|
||||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||||
}
|
}
|
||||||
|
final Set<LoanCharge> loanCharges = loan.charges();
|
||||||
|
final Map<Long, BigDecimal> disBuLoanCharges = new HashMap<Long, BigDecimal>();
|
||||||
|
for (final LoanCharge loanCharge : loanCharges) {
|
||||||
|
if (loanCharge.isDueAtDisbursement() && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()) {
|
||||||
|
disBuLoanCharges.put(loanCharge.getId(), loanCharge.amount());
|
||||||
|
}else if(loanCharge.isInstalmentFee() && loanCharge.hasNoLoanInstallmentCharges()){
|
||||||
|
Set<LoanInstallmentCharge> chargePerInstallments = loan.generateInstallmentLoanCharges(loanCharge);
|
||||||
|
loanCharge.addLoanInstallmentCharges(chargePerInstallments);
|
||||||
|
this.loanChargeRepository.save(loanCharge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final Locale locale = command.extractLocale();
|
||||||
|
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||||
|
for (final Map.Entry<Long, BigDecimal> entrySet : disBuLoanCharges.entrySet()) {
|
||||||
|
final PortfolioAccountData savingAccountData = this.accountAssociationsReadPlatformService.retriveLoanAssociation(loan.getId());
|
||||||
|
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(actualDisbursementDate, entrySet.getValue(),
|
||||||
|
PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN, savingAccountData.accountId(), loan.getId(), "Loan Charge Payment",
|
||||||
|
locale, fmt, null, null, LoanTransactionType.REPAYMENT_AT_DISBURSEMENT.getValue(), entrySet.getKey(), null);
|
||||||
|
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
@@ -933,12 +957,14 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
Integer loanInstallmentNumber = null;
|
Integer loanInstallmentNumber = null;
|
||||||
if (loanCharge.isInstalmentFee()){
|
if (loanCharge.isInstalmentFee()){
|
||||||
LoanInstallmentCharge chargePerInstallment = null;
|
LoanInstallmentCharge chargePerInstallment = null;
|
||||||
final LocalDate dueDate = command.localDateValueOfParameterNamed("dueDate");
|
if(!StringUtils.isBlank(command.json())){
|
||||||
final Integer installmentNumber = command.integerValueOfParameterNamed("installmentNumber");
|
final LocalDate dueDate = command.localDateValueOfParameterNamed("dueDate");
|
||||||
if(dueDate !=null){
|
final Integer installmentNumber = command.integerValueOfParameterNamed("installmentNumber");
|
||||||
chargePerInstallment = loanCharge.getInstallmentLoanCharge(dueDate);
|
if(dueDate !=null){
|
||||||
}else if(installmentNumber!=null){
|
chargePerInstallment = loanCharge.getInstallmentLoanCharge(dueDate);
|
||||||
chargePerInstallment = loanCharge.getInstallmentLoanCharge(installmentNumber);
|
}else if(installmentNumber!=null){
|
||||||
|
chargePerInstallment = loanCharge.getInstallmentLoanCharge(installmentNumber);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(chargePerInstallment == null){
|
if(chargePerInstallment == null){
|
||||||
chargePerInstallment = loanCharge.getUnpaidInstallmentLoanCharge();
|
chargePerInstallment = loanCharge.getUnpaidInstallmentLoanCharge();
|
||||||
@@ -1090,7 +1116,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
Collection<LoanInstallmentChargeData> chargePerInstallments = this.LoanChargeReadPlatformService.retrieveInstallmentLoanCharges(chargeData.getId(), true);
|
Collection<LoanInstallmentChargeData> chargePerInstallments = this.LoanChargeReadPlatformService.retrieveInstallmentLoanCharges(chargeData.getId(), true);
|
||||||
PortfolioAccountData portfolioAccountData = null;
|
PortfolioAccountData portfolioAccountData = null;
|
||||||
for(LoanInstallmentChargeData installmentChargeData : chargePerInstallments){
|
for(LoanInstallmentChargeData installmentChargeData : chargePerInstallments){
|
||||||
if(installmentChargeData.getDueDate().isAfter(new LocalDate())){
|
if(!installmentChargeData.getDueDate().isAfter(new LocalDate())){
|
||||||
if(portfolioAccountData == null){
|
if(portfolioAccountData == null){
|
||||||
portfolioAccountData = this.accountAssociationsReadPlatformService
|
portfolioAccountData = this.accountAssociationsReadPlatformService
|
||||||
.retriveLoanAssociation(chargeData.getLoanId());
|
.retriveLoanAssociation(chargeData.getLoanId());
|
||||||
|
|||||||
Reference in New Issue
Block a user