Merge pull request #423 from mifoscontributer/MIFOSX-212-JLG
Add Loan counter for Group and JLG Loan
This commit is contained in:
+99
-2
@@ -191,6 +191,22 @@
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<td></td>
|
||||
<td>clients/{clientId}?command=assignStaff</td>
|
||||
<td><a href="#clients_assignStaff">Assign Staff</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>clients/{clientId}?command=unassignStaff</td>
|
||||
<td><a href="#clients_unassignStaff">Unassign Staff</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<td></td>
|
||||
<td>clients/{clientId}/loans</td>
|
||||
@@ -1818,6 +1834,12 @@ function executeAjaxRequest(url, verbType, jsonData, basicAuthKey, successFuncti
|
||||
business that doesnt suit the firstname,middlename,lastname
|
||||
structure.</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>staffId</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=fielddesc>The staffId of the staff member dealing with the client office. The staff member is not specifically the loan officer.</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1906,7 +1928,7 @@ GET https://DomainName/api/v1/clients/template
|
||||
<td><div class="mifosXHeading2">Optional Fields</div></td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>groupId, externalId, accountNo</td>
|
||||
<td>groupId, externalId, accountNo, staffId</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
@@ -2013,6 +2035,59 @@ Request Body:
|
||||
{
|
||||
"clientId":15,
|
||||
"resourceId":15
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="clients_assignStaff" name="clients_assignStaff" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Assign a Staff</h4>
|
||||
<p>Allows you to assign <i>Staff</i> for existed Client.</p>
|
||||
<p>The selected Staff member should be belongs to the client's office.</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">POST https://Domain Name/api/v1/clients/{clientId}?command=assignStaff</code>
|
||||
<code class="method-request">POST clients/1?command=assignStaff
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"staffId": "1"
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"officeId": 1,
|
||||
"clientId": 1,
|
||||
"resourceId": 1,
|
||||
"changes": {"staffId":1}
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="clients_unassignStaff" name="clients_unassignStaff" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Unassign a Staff</h4>
|
||||
<p>Allows you to unassign the <i>Staff</i>.</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">POST https://Domain Name/api/v1/clients/{clientId}?command=unassignStaff</code>
|
||||
<code class="method-request">POST clients/1?command=unassignStaff
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"staffId":"1"
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"officeId": 1,
|
||||
"clientId": 1,
|
||||
"resourceId": 1,
|
||||
"changes": {"staffId":1}
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -7084,6 +7159,12 @@ Request Body:
|
||||
<tr>
|
||||
<td class=fielddesc>For associating a loan product with a given fund by default.</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>includeInBorrowerCycle</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=fielddesc>It is a flag, Used to denote whether the loans should include in loan cycle counter or not.</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>currencyCode</td>
|
||||
</tr>
|
||||
@@ -7786,7 +7867,7 @@ GET https://DomainName/api/v1/loanproducts/{productId}
|
||||
<td><div class="mifosXHeading2">Optional Fields</div></td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>inArrearsTolerance, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, charges, paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings</td>
|
||||
<td>inArrearsTolerance, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, charges, paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, includeInBorrowerCycle</td>
|
||||
</tr>
|
||||
|
||||
<tr class="matrixHeadingBG">
|
||||
@@ -15834,6 +15915,22 @@ GET https://DomainName/api/v1/search?query=000000111
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<td></td>
|
||||
<td>clients/{clientId}?command=assignStaff</td>
|
||||
<td><a href="#clients_assignStaff">Assign Staff</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>clients/{clientId}?command=unassignStaff</td>
|
||||
<td><a href="#clients_unassignStaff">Unassign Staff</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<td></td>
|
||||
<td>clients/{clientId}/loans</td>
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
ALTER TABLE `m_client_loan_counter`
|
||||
ADD COLUMN `group_id` BIGINT(20) NOT NULL AFTER `client_id`,
|
||||
ADD CONSTRAINT `FK_m_group_loan_counter` FOREIGN KEY (`group_id`) REFERENCES `m_group` (`id`);
|
||||
|
||||
RENAME TABLE `m_client_loan_counter` TO `m_loan_counter`;
|
||||
|
||||
ALTER TABLE `m_loan_counter`
|
||||
CHANGE COLUMN `client_id` `client_id` BIGINT(20) NULL DEFAULT NULL AFTER `id`,
|
||||
CHANGE COLUMN `group_id` `group_id` BIGINT(20) NULL DEFAULT NULL AFTER `client_id`;
|
||||
|
||||
ALTER TABLE `m_loan`
|
||||
ADD COLUMN `loan_counter` SMALLINT NULL DEFAULT NULL AFTER `sync_disbursement_with_meeting`,
|
||||
ADD COLUMN `loan_product_counter` SMALLINT NULL DEFAULT NULL AFTER `loan_counter`;
|
||||
|
||||
DROP TABLE `m_loan_counter`;
|
||||
+2
-3
@@ -521,9 +521,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
StringBuilder accountsSummary = new StringBuilder("l.id as id, l.account_no as accountNo, l.external_id as externalId,");
|
||||
accountsSummary.append("l.product_id as productId, lp.name as productName,")
|
||||
.append("l.loan_status_id as statusId, l.loan_type_enum as loanType, ")
|
||||
.append("lc.running_count as loanCycle ").append(" from m_loan l ")
|
||||
.append("LEFT JOIN m_product_loan AS lp ON lp.id = l.product_id ")
|
||||
.append("LEFT JOIN m_client_loan_counter lc on l.id = lc.loan_id ");
|
||||
.append("l.loan_product_counter as loanCycle ").append(" from m_loan l ")
|
||||
.append("LEFT JOIN m_product_loan AS lp ON lp.id = l.product_id");
|
||||
|
||||
return accountsSummary.toString();
|
||||
}
|
||||
|
||||
+2
-1
@@ -96,7 +96,8 @@ public class LoansApiResource {
|
||||
"summary", "repaymentSchedule", "transactions", "charges", "collateral", "guarantors", "meeting", "productOptions",
|
||||
"amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions", "repaymentFrequencyTypeOptions",
|
||||
"termFrequencyTypeOptions", "interestRateFrequencyTypeOptions", "fundOptions", "repaymentStrategyOptions", "chargeOptions",
|
||||
"loanOfficerOptions", "loanPurposeOptions", "loanCollateralOptions", "chargeTemplate", "calendarOptions", "syncDisbursementWithMeeting"));
|
||||
"loanOfficerOptions", "loanPurposeOptions", "loanCollateralOptions", "chargeTemplate", "calendarOptions", "syncDisbursementWithMeeting",
|
||||
"loanCounter", "loanProductCounter"));
|
||||
|
||||
private final String resourceNameForPermissions = "LOAN";
|
||||
|
||||
|
||||
+32
-12
@@ -122,6 +122,10 @@ public class LoanAccountData {
|
||||
@Transient
|
||||
private final BigDecimal feeChargesAtDisbursementCharged;
|
||||
private final BigDecimal totalOverpaid;
|
||||
|
||||
//loanCycle
|
||||
private final Integer loanCounter;
|
||||
private final Integer loanProductCounter;
|
||||
|
||||
/**
|
||||
* Used to produce a {@link LoanAccountData} with only collateral options
|
||||
@@ -192,6 +196,8 @@ public class LoanAccountData {
|
||||
final Collection<CodeValueData> loanPurposeOptions = null;
|
||||
final Collection<CalendarData> calendarOptions = null;
|
||||
final Boolean syncDisbursementWithMeeting = null;
|
||||
final Integer loancounter = null;
|
||||
final Integer loanProductCounter = null;
|
||||
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId,
|
||||
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
||||
@@ -203,7 +209,7 @@ public class LoanAccountData {
|
||||
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, transactionProcessingStrategyOptions,
|
||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
||||
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
||||
syncDisbursementWithMeeting);
|
||||
syncDisbursementWithMeeting, loancounter, loanProductCounter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,6 +281,8 @@ public class LoanAccountData {
|
||||
final Collection<CodeValueData> loanCollateralOptions = null;
|
||||
final Collection<CalendarData> calendarOptions = null;
|
||||
final Boolean syncDisbursementWithMeeting = null;
|
||||
final Integer loancounter = null;
|
||||
final Integer loanProductCounter = null;
|
||||
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId,
|
||||
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
||||
@@ -285,7 +293,8 @@ public class LoanAccountData {
|
||||
feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData,
|
||||
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
|
||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
||||
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions, syncDisbursementWithMeeting);
|
||||
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
||||
syncDisbursementWithMeeting, loancounter, loanProductCounter);
|
||||
}
|
||||
|
||||
public static LoanAccountData populateClientDefaults(final LoanAccountData acc, final LoanAccountData clientAcc) {
|
||||
@@ -302,7 +311,8 @@ public class LoanAccountData {
|
||||
acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions,
|
||||
acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
|
||||
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
|
||||
acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions, acc.syncDisbursementWithMeeting);
|
||||
acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions, acc.syncDisbursementWithMeeting,
|
||||
acc.loanCounter, acc.loanProductCounter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -375,6 +385,8 @@ public class LoanAccountData {
|
||||
final Collection<CodeValueData> loanCollateralOptions = null;
|
||||
final Collection<CalendarData> calendarOptions = null;
|
||||
final Boolean syncDisbursementWithMeeting = null;
|
||||
final Integer loancounter = null;
|
||||
final Integer loanProductCounter = null;
|
||||
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId,
|
||||
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
||||
@@ -386,7 +398,7 @@ public class LoanAccountData {
|
||||
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
|
||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
||||
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
||||
syncDisbursementWithMeeting);
|
||||
syncDisbursementWithMeeting, loancounter, loanProductCounter);
|
||||
}
|
||||
|
||||
public static LoanAccountData populateGroupDefaults(final LoanAccountData acc, final LoanAccountData groupAcc) {
|
||||
@@ -404,7 +416,7 @@ public class LoanAccountData {
|
||||
acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
|
||||
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
|
||||
acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions,
|
||||
acc.syncDisbursementWithMeeting);
|
||||
acc.syncDisbursementWithMeeting, acc.loanCounter, acc.loanProductCounter);
|
||||
}
|
||||
|
||||
public static LoanAccountData loanProductWithTemplateDefaults(final LoanProductData product,
|
||||
@@ -469,6 +481,9 @@ public class LoanAccountData {
|
||||
for (ChargeData charge : product.charges()) {
|
||||
charges.add(charge.toLoanChargeData());
|
||||
}
|
||||
|
||||
final Integer loancounter = null;
|
||||
final Integer loanProductCounter = null;
|
||||
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType,
|
||||
product.getId(), product.getName(), product.getDescription(), product.getFundId(), product.getFundName(), loanPurposeId,
|
||||
@@ -482,7 +497,7 @@ public class LoanAccountData {
|
||||
repaymentSchedule, transactions, charges, collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions,
|
||||
repaymentFrequencyTypeOptions, repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions,
|
||||
interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions,
|
||||
loanPurposeOptions, loanCollateralOptions, calendarOptions, syncDisbursementWithMeeting);
|
||||
loanPurposeOptions, loanCollateralOptions, calendarOptions, syncDisbursementWithMeeting, loancounter, loanProductCounter);
|
||||
}
|
||||
|
||||
public static LoanAccountData populateLoanProductDefaults(final LoanAccountData acc, final LoanProductData product) {
|
||||
@@ -528,7 +543,8 @@ public class LoanAccountData {
|
||||
acc.summary, acc.feeChargesAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors,
|
||||
calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
|
||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
||||
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions, acc.syncDisbursementWithMeeting);
|
||||
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
||||
acc.syncDisbursementWithMeeting, acc.loanCounter, acc.loanProductCounter);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -547,7 +563,8 @@ public class LoanAccountData {
|
||||
final EnumOptionData interestCalculationPeriodType, final LocalDate expectedFirstRepaymentOnDate,
|
||||
final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged,
|
||||
final LocalDate interestChargedFromDate, final LoanApplicationTimelineData timeline, final LoanSummaryData loanSummary,
|
||||
final BigDecimal feeChargesDueAtDisbursementCharged, final Boolean syncDisbursementWithMeeting) {
|
||||
final BigDecimal feeChargesDueAtDisbursementCharged, final Boolean syncDisbursementWithMeeting,
|
||||
final Integer loancounter, final Integer loanProductCounter) {
|
||||
|
||||
final LoanScheduleData repaymentSchedule = null;
|
||||
final Collection<LoanTransactionData> transactions = null;
|
||||
@@ -581,7 +598,7 @@ public class LoanAccountData {
|
||||
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
|
||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
||||
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
||||
syncDisbursementWithMeeting);
|
||||
syncDisbursementWithMeeting, loancounter, loanProductCounter);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -611,7 +628,7 @@ public class LoanAccountData {
|
||||
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, transactionProcessingStrategyOptions,
|
||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
||||
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
||||
acc.syncDisbursementWithMeeting);
|
||||
acc.syncDisbursementWithMeeting, acc.loanCounter, acc.loanProductCounter);
|
||||
}
|
||||
|
||||
public static LoanAccountData associationsAndTemplate(final LoanAccountData acc, final Collection<LoanProductData> productOptions,
|
||||
@@ -637,7 +654,7 @@ public class LoanAccountData {
|
||||
acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
|
||||
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
|
||||
acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions,
|
||||
acc.syncDisbursementWithMeeting);
|
||||
acc.syncDisbursementWithMeeting, acc.loanCounter, acc.loanProductCounter);
|
||||
}
|
||||
|
||||
private LoanAccountData(
|
||||
@@ -684,7 +701,7 @@ public class LoanAccountData {
|
||||
final Collection<FundData> fundOptions, final Collection<ChargeData> chargeOptions, final ChargeData chargeTemplate,
|
||||
final Collection<StaffData> loanOfficerOptions, final Collection<CodeValueData> loanPurposeOptions,
|
||||
final Collection<CodeValueData> loanCollateralOptions, final Collection<CalendarData> calendarOptions,
|
||||
final Boolean syncDisbursementWithMeeting) {
|
||||
final Boolean syncDisbursementWithMeeting, final Integer loanCounter, final Integer loanProductCounter) {
|
||||
this.id = id;
|
||||
this.accountNo = accountNo;
|
||||
this.status = status;
|
||||
@@ -789,6 +806,9 @@ public class LoanAccountData {
|
||||
} else {
|
||||
this.calendarOptions = calendarOptions;
|
||||
}
|
||||
|
||||
this.loanCounter = loanCounter;
|
||||
this.loanProductCounter = loanProductCounter;
|
||||
}
|
||||
|
||||
public RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData() {
|
||||
|
||||
+30
-1
@@ -100,7 +100,6 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
@JoinColumn(name = "group_id", nullable = true)
|
||||
private Group group;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "loan_type_enum", nullable = false)
|
||||
private Integer loanType;
|
||||
|
||||
@@ -230,6 +229,12 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "total_overpaid_derived", scale = 6, precision = 19)
|
||||
private BigDecimal totalOverpaid;
|
||||
|
||||
@Column(name = "loan_counter")
|
||||
private Integer loanCounter;
|
||||
|
||||
@Column(name = "loan_product_counter")
|
||||
private Integer loanProductCounter;
|
||||
|
||||
@LazyCollection(LazyCollectionOption.FALSE)
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true)
|
||||
@@ -2349,4 +2354,28 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
}
|
||||
}
|
||||
|
||||
public Group group() {
|
||||
return this.group;
|
||||
}
|
||||
|
||||
public Integer getCurrentLoanCounter() {
|
||||
return this.loanCounter;
|
||||
}
|
||||
|
||||
public Integer getLoanProductLoanCounter() {
|
||||
return this.loanProductCounter;
|
||||
}
|
||||
|
||||
public void updateClientLoanCounter(Integer newLoanCounter) {
|
||||
this.loanCounter = newLoanCounter;
|
||||
}
|
||||
|
||||
public void updateLoanProductLoanCounter(Integer newLoanProductLoanCounter) {
|
||||
this.loanProductCounter = newLoanProductLoanCounter;
|
||||
}
|
||||
|
||||
public boolean isGroupLoan() {
|
||||
return LoanType.fromInt(this.loanType).isGroupLoan();
|
||||
}
|
||||
|
||||
}
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.domain;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_client_loan_counter")
|
||||
public class LoanCycle extends AbstractPersistable<Long> {
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "client_id", nullable = false)
|
||||
private Client client;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "loan_product_id", nullable = false)
|
||||
private LoanProduct loanProduct;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "loan_id", nullable = false)
|
||||
private Loan loan;
|
||||
|
||||
@Column(name = "running_count", nullable = false)
|
||||
private Integer runningCount;
|
||||
|
||||
public LoanCycle() {
|
||||
|
||||
}
|
||||
|
||||
private LoanCycle(final Client client, final LoanProduct loanProduct, final Loan loan, final Integer runningCounter) {
|
||||
this.client = client;
|
||||
this.loanProduct = loanProduct;
|
||||
this.loan = loan;
|
||||
this.runningCount = runningCounter;
|
||||
}
|
||||
|
||||
public static LoanCycle create(final Client client, final LoanProduct loanProduct, final Loan loan, final Integer runningCounter) {
|
||||
return new LoanCycle(client, loanProduct, loan, runningCounter);
|
||||
}
|
||||
|
||||
public Integer getRunningCounter() {
|
||||
return this.runningCount;
|
||||
}
|
||||
|
||||
public Loan loan() {
|
||||
return this.loan;
|
||||
}
|
||||
|
||||
public LoanCycle updateLoanCycleCounter(final Integer runningCount) {
|
||||
this.runningCount = runningCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.domain;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
public interface LoanCycleRepository extends JpaRepository<LoanCycle, Long>, JpaSpecificationExecutor<LoanCycle> {
|
||||
|
||||
@Query("from LoanCycle lc where lc.client.id=:clientId and lc.loanProduct.id=:loanProductId order by lc.runningCount")
|
||||
List<LoanCycle> findByClientIdAndLoanProductId(@Param("clientId") Long clientId, @Param("loanProductId") Long loanProductId);
|
||||
|
||||
}
|
||||
+74
-12
@@ -14,17 +14,79 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
public interface LoanRepository extends JpaRepository<Loan, Long>,
|
||||
JpaSpecificationExecutor<Loan> {
|
||||
@Query("from Loan loan where loan.client.id = :clientId and loan.group.id = :groupId")
|
||||
List<Loan> findByClientIdAndGroupId(@Param("clientId") Long clientId, @Param("groupId") Long groupId);
|
||||
|
||||
@Query("from Loan loan where loan.client.id = :clientId")
|
||||
List<Loan> findLoanByClientId(@Param("clientId") Long clientId);
|
||||
public interface LoanRepository extends JpaRepository<Loan, Long>, JpaSpecificationExecutor<Loan> {
|
||||
|
||||
@Query("from Loan loan where loan.id IN :ids and loan.loanStatus IN :loanStatuses and loan.loanType IN :loanTypes")
|
||||
List<Loan> findByIdsAndLoanStatusAndLoanType(@Param("ids") Collection<Long> ids, @Param("loanStatuses") Collection<Integer> loanStatuses, @Param("loanTypes") Collection<Integer> loanTypes);
|
||||
|
||||
@Query("select loan.id from Loan loan where loan.actualDisbursementDate > :disbursalDate order by loan.actualDisbursementDate")
|
||||
List<Long> getLoansDisbursedAfter(@Param("disbursalDate") Date disbursalDate);
|
||||
public static final String FIND_GROUP_LOANS_DISBURSED_AFTER = "from Loan l where l.actualDisbursementDate > :disbursementDate and "
|
||||
+ "l.group.id = :groupId and l.loanType = :loanType order by l.actualDisbursementDate";
|
||||
|
||||
public static final String FIND_CLIENT_OR_JLG_LOANS_DISBURSED_AFTER = "from Loan l where l.actualDisbursementDate > :disbursementDate and "
|
||||
+ "l.client.id = :clientId order by l.actualDisbursementDate";
|
||||
|
||||
public static final String FIND_MAX_GROUP_LOAN_COUNTER_QUERY = "Select MAX(l.loanCounter) from Loan l where l.group.id = :groupId "
|
||||
+ "and l.loanType = :loanType";
|
||||
|
||||
public static final String FIND_MAX_GROUP_LOAN_PRODUCT_COUNTER_QUERY = "Select MAX(l.loanProductCounter) from Loan l where "
|
||||
+ "l.group.id = :groupId and l.loanType = :loanType and l.loanProduct.id = :productId";
|
||||
|
||||
public static final String FIND_MAX_CLIENT_OR_JLG_LOAN_COUNTER_QUERY = "Select MAX(l.loanCounter) from Loan l where "
|
||||
+ "l.client.id = :clientId";
|
||||
|
||||
public static final String FIND_MAX_CLIENT_OR_JLG_LOAN_PRODUCT_COUNTER_QUERY = "Select MAX(l.loanProductCounter) from Loan l where "
|
||||
+ "l.client.id = :clientId and l.loanProduct.id = :productId";
|
||||
|
||||
public static final String FIND_GROUP_LOANS_TO_UPDATE = "from Loan l where l.loanCounter > :loanCounter and "
|
||||
+ "l.group.id = :groupId and l.loanType = :groupLoanType order by l.loanCounter";
|
||||
|
||||
public static final String FIND_CLIENT_OR_JLG_LOANS_TO_UPDATE = "from Loan l where l.loanCounter > :loanCounter and "
|
||||
+ "l.client.id = :clientId order by l.loanCounter";
|
||||
|
||||
public static final String FIND_GROUP_LOANS_TO_UPDATE_LOANPRODUCT_COUNTER = "from Loan l where l.loanProductCounter > :loanProductCounter"
|
||||
+ " and l.group.id = :groupId and l.loanType = :groupLoanType and l.loanCounter is NULL order by l.loanProductCounter";
|
||||
|
||||
public static final String FIND_CLIENT_LOANS_TO_UPDATE_LOANPRODUCT_COUNTER = "from Loan l where l.loanProductCounter > :loanProductCounter"
|
||||
+ " and l.client.id = :clientId and l.loanCounter is NULL order by l.loanProductCounter";
|
||||
|
||||
@Query("from Loan loan where loan.client.id = :clientId and loan.group.id = :groupId")
|
||||
List<Loan> findByClientIdAndGroupId(@Param("clientId") Long clientId, @Param("groupId") Long groupId);
|
||||
|
||||
@Query("from Loan loan where loan.client.id = :clientId")
|
||||
List<Loan> findLoanByClientId(@Param("clientId") Long clientId);
|
||||
|
||||
@Query("from Loan loan where loan.id IN :ids and loan.loanStatus IN :loanStatuses and loan.loanType IN :loanTypes")
|
||||
List<Loan> findByIdsAndLoanStatusAndLoanType(@Param("ids") Collection<Long> ids,
|
||||
@Param("loanStatuses") Collection<Integer> loanStatuses, @Param("loanTypes") Collection<Integer> loanTypes);
|
||||
|
||||
@Query(FIND_GROUP_LOANS_DISBURSED_AFTER)
|
||||
List<Loan> getGroupLoansDisbursedAfter(@Param("disbursementDate") Date disbursementDate, @Param("groupId") Long groupId,
|
||||
@Param("loanType") Integer loanType);
|
||||
|
||||
@Query(FIND_CLIENT_OR_JLG_LOANS_DISBURSED_AFTER)
|
||||
List<Loan> getClientOrJLGLoansDisbursedAfter(@Param("disbursementDate") Date disbursementDate, @Param("clientId") Long clientId);
|
||||
|
||||
@Query(FIND_MAX_GROUP_LOAN_COUNTER_QUERY)
|
||||
Integer getMaxGroupLoanCounter(@Param("groupId") Long groupId, @Param("loanType") Integer loanType);
|
||||
|
||||
@Query(FIND_MAX_GROUP_LOAN_PRODUCT_COUNTER_QUERY)
|
||||
Integer getMaxGroupLoanProductCounter(@Param("productId") Long productId, @Param("groupId") Long groupId,
|
||||
@Param("loanType") Integer loanType);
|
||||
|
||||
@Query(FIND_MAX_CLIENT_OR_JLG_LOAN_COUNTER_QUERY)
|
||||
Integer getMaxClientOrJLGLoanCounter(@Param("clientId") Long clientId);
|
||||
|
||||
@Query(FIND_MAX_CLIENT_OR_JLG_LOAN_PRODUCT_COUNTER_QUERY)
|
||||
Integer getMaxClientOrJLGLoanProductCounter(@Param("productId") Long productId, @Param("clientId") Long clientId);
|
||||
|
||||
@Query(FIND_GROUP_LOANS_TO_UPDATE)
|
||||
List<Loan> getGroupLoansToUpdateLoanCounter(@Param("loanCounter") Integer loanCounter, @Param("groupId") Long groupId,
|
||||
@Param("groupLoanType") Integer groupLoanType);
|
||||
|
||||
@Query(FIND_CLIENT_OR_JLG_LOANS_TO_UPDATE)
|
||||
List<Loan> getClientOrJLGLoansToUpdateLoanCounter(@Param("loanCounter") Integer loanCounter, @Param("clientId") Long clientId);
|
||||
|
||||
@Query(FIND_GROUP_LOANS_TO_UPDATE_LOANPRODUCT_COUNTER)
|
||||
List<Loan> getGroupLoansToUpdateLoanProductCounter(@Param("loanProductCounter") Integer loanProductCounter, @Param("groupId") Long groupId,
|
||||
@Param("groupLoanType") Integer groupLoanType);
|
||||
|
||||
@Query(FIND_CLIENT_LOANS_TO_UPDATE_LOANPRODUCT_COUNTER)
|
||||
List<Loan> getClientLoansToUpdateLoanProductCounter(@Param("loanProductCounter") Integer loanProductCounter, @Param("clientId") Long clientId);
|
||||
}
|
||||
+6
-2
@@ -443,7 +443,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
+ " la.penalty_charges_overdue_derived as penaltyChargesOverdue,"
|
||||
+ " la.total_overdue_derived as totalOverdue,"
|
||||
+ " la.overdue_since_date_derived as overdueSinceDate,"
|
||||
+ " l.sync_disbursement_with_meeting as syncDisbursementWithMeeting"
|
||||
+ " l.sync_disbursement_with_meeting as syncDisbursementWithMeeting,"
|
||||
+ " l.loan_counter as loanCounter, l.loan_product_counter as loanProductCounter"
|
||||
+ " from m_loan l" //
|
||||
+ " join m_product_loan lp on lp.id = l.product_id" //
|
||||
+ " join m_currency rc on rc.`code` = l.currency_code" //
|
||||
@@ -648,6 +649,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
groupData = GroupGeneralData.instance(groupId, groupName, groupExternalId, groupStatus, activationDate, groupOfficeId,
|
||||
null, groupParentId, null, groupStaffId, null, groupHierarchy);
|
||||
}
|
||||
|
||||
final Integer loanCounter = JdbcSupport.getInteger(rs, "loanCounter");
|
||||
final Integer loanProductCounter = JdbcSupport.getInteger(rs, "loanProductCounter");
|
||||
|
||||
return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, groupData,
|
||||
loanType, loanProductId, loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName,
|
||||
@@ -656,7 +660,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
amortizationType, interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, interestType,
|
||||
interestCalculationPeriodType, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, graceOnInterestPayment,
|
||||
graceOnInterestCharged, interestChargedFromDate, timeline, loanSummary, feeChargesDueAtDisbursementCharged,
|
||||
syncDisbursementWithMeeting);
|
||||
syncDisbursementWithMeeting, loanCounter, loanProductCounter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+142
-44
@@ -39,7 +39,6 @@ import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeUpdatedExc
|
||||
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeWaivedException;
|
||||
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeWaivedException.LOAN_CHARGE_CANNOT_BE_WAIVED_REASON;
|
||||
import org.mifosplatform.portfolio.charge.exception.LoanChargeNotFoundException;
|
||||
import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkDisbursalCommand;
|
||||
import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkRepaymentCommand;
|
||||
import org.mifosplatform.portfolio.collectionsheet.command.SingleDisbursalCommand;
|
||||
@@ -50,8 +49,6 @@ import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateM
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanChargeRepository;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanCycle;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanCycleRepository;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
|
||||
@@ -67,7 +64,6 @@ import org.mifosplatform.portfolio.loanaccount.exception.LoanTransactionNotFound
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
|
||||
import org.mifosplatform.portfolio.loanaccount.serialization.LoanEventApiJsonValidator;
|
||||
import org.mifosplatform.portfolio.loanaccount.serialization.LoanUpdateCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRelatedDetail;
|
||||
import org.mifosplatform.portfolio.loanproduct.exception.InvalidCurrencyException;
|
||||
import org.mifosplatform.portfolio.note.domain.Note;
|
||||
@@ -98,7 +94,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
private final LoanScheduleGeneratorFactory loanScheduleFactory;
|
||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
||||
private final PaymentDetailWritePlatformService paymentDetailWritePlatformService;
|
||||
private final LoanCycleRepository loanCycleRepository;
|
||||
|
||||
@Autowired
|
||||
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||
@@ -110,7 +105,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
final JournalEntryWritePlatformService journalEntryWritePlatformService, final LoanSummaryWrapper loanSummaryWrapper,
|
||||
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
||||
final LoanScheduleGeneratorFactory loanScheduleFactory, final CalendarInstanceRepository calendarInstanceRepository,
|
||||
final PaymentDetailWritePlatformService paymentDetailWritePlatformService, final LoanCycleRepository loanCycleRepository) {
|
||||
final PaymentDetailWritePlatformService paymentDetailWritePlatformService) {
|
||||
this.context = context;
|
||||
this.loanEventApiJsonValidator = loanEventApiJsonValidator;
|
||||
this.loanAssembler = loanAssembler;
|
||||
@@ -127,7 +122,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.loanScheduleFactory = loanScheduleFactory;
|
||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
||||
this.paymentDetailWritePlatformService = paymentDetailWritePlatformService;
|
||||
this.loanCycleRepository = loanCycleRepository;
|
||||
}
|
||||
|
||||
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
||||
@@ -167,31 +161,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate");
|
||||
final LocalDate firstRepaymentMeetingDate = getFirstRepaymentMeetingDate(actualDisbursementDate, loan, calendarInstance);
|
||||
|
||||
// create loan cycle
|
||||
final LoanProduct product = loan.loanProduct();
|
||||
final Client client = loan.client();
|
||||
// get the loan Ids which have disbursement date greater than
|
||||
// 'actualDisbursementDate'.
|
||||
final List<Long> loansToUpdateLoanCycle = this.loanRepository.getLoansDisbursedAfter(actualDisbursementDate.toDate());
|
||||
updateLoanCounters(loan, actualDisbursementDate);
|
||||
|
||||
// get all available loan cycles.
|
||||
final List<LoanCycle> loanCycles = this.loanCycleRepository.findByClientIdAndLoanProductId(client.getId(), product.getId());
|
||||
|
||||
Integer loanCounter = loanCycles.size() + 1;
|
||||
for (final long loanCycleLoanId : loansToUpdateLoanCycle) {
|
||||
for (final LoanCycle loanCycle : loanCycles) {
|
||||
if (loanCycle.loan().getId() == loanCycleLoanId) {
|
||||
int runningCounter = loanCycle.getRunningCounter();
|
||||
if (loanCounter > runningCounter) {
|
||||
loanCounter = runningCounter;
|
||||
}
|
||||
loanCycle.updateLoanCycleCounter(++runningCounter);
|
||||
}
|
||||
}
|
||||
}
|
||||
final LoanCycle loanCycle = LoanCycle.create(client, product, loan, loanCounter);
|
||||
this.loanCycleRepository.save(loanCycle);
|
||||
|
||||
loan.disburse(this.loanScheduleFactory, currentUser, command, applicationCurrency, existingTransactionIds,
|
||||
existingReversedTransactionIds, changes, paymentDetail, firstRepaymentMeetingDate);
|
||||
|
||||
@@ -1042,21 +1013,148 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
}
|
||||
|
||||
private void removeLoanCycle(final Loan loan) {
|
||||
final Client client = loan.client();
|
||||
final LoanProduct product = loan.loanProduct();
|
||||
final List<LoanCycle> loanCycles = this.loanCycleRepository.findByClientIdAndLoanProductId(client.getId(), product.getId());
|
||||
LoanCycle loanCycleToRemove = null;
|
||||
for (LoanCycle loanCycle : loanCycles) {
|
||||
if (loanCycle.loan().getId().equals(loan.getId())) {
|
||||
loanCycleToRemove = loanCycle;
|
||||
} else if (loanCycleToRemove != null) {
|
||||
loanCycle = loanCycle.updateLoanCycleCounter(loanCycle.getRunningCounter() - 1);
|
||||
final List<Loan> loansToUpdate;
|
||||
if (loan.isGroupLoan()) {
|
||||
if (loan.loanProduct().isIncludeInBorrowerCycle()) {
|
||||
loansToUpdate = this.loanRepository.getGroupLoansToUpdateLoanCounter(loan.getCurrentLoanCounter(), loan.getGroupId(),
|
||||
LoanType.GROUP.getValue());
|
||||
} else {
|
||||
loansToUpdate = this.loanRepository.getGroupLoansToUpdateLoanProductCounter(loan.getLoanProductLoanCounter(),
|
||||
loan.getGroupId(), LoanType.GROUP.getValue());
|
||||
}
|
||||
|
||||
} else {
|
||||
if (loan.loanProduct().isIncludeInBorrowerCycle()) {
|
||||
loansToUpdate = this.loanRepository
|
||||
.getClientOrJLGLoansToUpdateLoanCounter(loan.getCurrentLoanCounter(), loan.getClientId());
|
||||
} else {
|
||||
loansToUpdate = this.loanRepository.getClientLoansToUpdateLoanProductCounter(loan.getLoanProductLoanCounter(),
|
||||
loan.getClientId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (loanCycleToRemove != null) {
|
||||
this.loanCycleRepository.save(loanCycles);
|
||||
this.loanCycleRepository.delete(loanCycleToRemove);
|
||||
if (loansToUpdate != null) {
|
||||
updateLoanCycleCounter(loansToUpdate, loan);
|
||||
}
|
||||
loan.updateClientLoanCounter(null);
|
||||
loan.updateLoanProductLoanCounter(null);
|
||||
|
||||
}
|
||||
|
||||
private void updateLoanCounters(final Loan loan, final LocalDate actualDisbursementDate) {
|
||||
|
||||
if (loan.isGroupLoan()) {
|
||||
final List<Loan> loansToUpdateForLoanCounter = this.loanRepository.getGroupLoansDisbursedAfter(actualDisbursementDate.toDate(),
|
||||
loan.getGroupId(), LoanType.GROUP.getValue());
|
||||
final Integer newLoanCounter = getNewGroupLoanCounter(loan);
|
||||
final Integer newLoanProductCounter = getNewGroupLoanProductCounter(loan);
|
||||
updateLoanCounter(loan, loansToUpdateForLoanCounter, newLoanCounter, newLoanProductCounter);
|
||||
} else {
|
||||
final List<Loan> loansToUpdateForLoanCounter = this.loanRepository.getClientOrJLGLoansDisbursedAfter(
|
||||
actualDisbursementDate.toDate(), loan.getClientId());
|
||||
final Integer newLoanCounter = getNewClientOrJLGLoanCounter(loan);
|
||||
final Integer newLoanProductCounter = getNewClientOrJLGLoanProductCounter(loan);
|
||||
updateLoanCounter(loan, loansToUpdateForLoanCounter, newLoanCounter, newLoanProductCounter);
|
||||
}
|
||||
}
|
||||
|
||||
private Integer getNewGroupLoanCounter(final Loan loan) {
|
||||
|
||||
Integer maxClientLoanCounter = this.loanRepository.getMaxGroupLoanCounter(loan.getGroupId(), LoanType.GROUP.getValue());
|
||||
if (maxClientLoanCounter == null) {
|
||||
maxClientLoanCounter = 1;
|
||||
} else {
|
||||
maxClientLoanCounter = maxClientLoanCounter + 1;
|
||||
}
|
||||
return maxClientLoanCounter;
|
||||
}
|
||||
|
||||
private Integer getNewGroupLoanProductCounter(final Loan loan) {
|
||||
|
||||
Integer maxLoanProductLoanCounter = this.loanRepository.getMaxGroupLoanProductCounter(loan.loanProduct().getId(),
|
||||
loan.getGroupId(), LoanType.GROUP.getValue());
|
||||
if (maxLoanProductLoanCounter == null) {
|
||||
maxLoanProductLoanCounter = 1;
|
||||
} else {
|
||||
maxLoanProductLoanCounter = maxLoanProductLoanCounter + 1;
|
||||
}
|
||||
return maxLoanProductLoanCounter;
|
||||
}
|
||||
|
||||
private void updateLoanCounter(final Loan loan, final List<Loan> loansToUpdateForLoanCounter, Integer newLoanCounter,
|
||||
Integer newLoanProductCounter) {
|
||||
|
||||
final boolean includeInBorrowerCycle = loan.loanProduct().isIncludeInBorrowerCycle();
|
||||
for (final Loan loanToUpdate : loansToUpdateForLoanCounter) {
|
||||
//Update client loan counter if loan product includeInBorrowerCycle is true
|
||||
if (includeInBorrowerCycle) {
|
||||
Integer currentLoanCounter = loanToUpdate.getCurrentLoanCounter();
|
||||
if (newLoanCounter > currentLoanCounter) {
|
||||
newLoanCounter = currentLoanCounter;
|
||||
}
|
||||
loanToUpdate.updateClientLoanCounter(++currentLoanCounter);
|
||||
}
|
||||
|
||||
if (loanToUpdate.loanProduct().getId().equals(loan.loanProduct().getId())) {
|
||||
Integer loanProductLoanCounter = loanToUpdate.getLoanProductLoanCounter();
|
||||
if (newLoanProductCounter > loanProductLoanCounter) {
|
||||
newLoanProductCounter = loanProductLoanCounter;
|
||||
}
|
||||
loanToUpdate.updateLoanProductLoanCounter(++loanProductLoanCounter);
|
||||
}
|
||||
}
|
||||
|
||||
if (includeInBorrowerCycle) {
|
||||
loan.updateClientLoanCounter(newLoanCounter);
|
||||
} else {
|
||||
loan.updateClientLoanCounter(null);
|
||||
}
|
||||
loan.updateLoanProductLoanCounter(newLoanProductCounter);
|
||||
this.loanRepository.save(loansToUpdateForLoanCounter);
|
||||
}
|
||||
|
||||
private Integer getNewClientOrJLGLoanCounter(final Loan loan) {
|
||||
|
||||
Integer maxClientLoanCounter = this.loanRepository.getMaxClientOrJLGLoanCounter(loan.getClientId());
|
||||
if (maxClientLoanCounter == null) {
|
||||
maxClientLoanCounter = 1;
|
||||
} else {
|
||||
maxClientLoanCounter = maxClientLoanCounter + 1;
|
||||
}
|
||||
return maxClientLoanCounter;
|
||||
}
|
||||
|
||||
private Integer getNewClientOrJLGLoanProductCounter(final Loan loan) {
|
||||
|
||||
Integer maxLoanProductLoanCounter = this.loanRepository.getMaxClientOrJLGLoanProductCounter(loan.loanProduct().getId(),
|
||||
loan.getClientId());
|
||||
if (maxLoanProductLoanCounter == null) {
|
||||
maxLoanProductLoanCounter = 1;
|
||||
} else {
|
||||
maxLoanProductLoanCounter = maxLoanProductLoanCounter + 1;
|
||||
}
|
||||
return maxLoanProductLoanCounter;
|
||||
}
|
||||
|
||||
private void updateLoanCycleCounter(final List<Loan> loansToUpdate, final Loan loan) {
|
||||
|
||||
final Integer currentLoancounter = loan.getCurrentLoanCounter();
|
||||
final Integer currentLoanProductCounter = loan.getLoanProductLoanCounter();
|
||||
|
||||
for (final Loan loanToUpdate : loansToUpdate) {
|
||||
if (loan.loanProduct().isIncludeInBorrowerCycle()) {
|
||||
Integer runningLoancounter = loanToUpdate.getCurrentLoanCounter();
|
||||
if (runningLoancounter > currentLoancounter) {
|
||||
loanToUpdate.updateClientLoanCounter(--runningLoancounter);
|
||||
}
|
||||
}
|
||||
if (loan.loanProduct().getId().equals(loanToUpdate.loanProduct().getId())) {
|
||||
Integer runningLoanProductCounter = loanToUpdate.getLoanProductLoanCounter();
|
||||
if (runningLoanProductCounter > currentLoanProductCounter) {
|
||||
loanToUpdate.updateLoanProductLoanCounter(--runningLoanProductCounter);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.loanRepository.save(loansToUpdate);
|
||||
}
|
||||
}
|
||||
+4
@@ -329,4 +329,8 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
null, null, null, null) : this.loanProductMinMaxConstraints;
|
||||
return loanProductMinMaxConstraints;
|
||||
}
|
||||
|
||||
public boolean isIncludeInBorrowerCycle() {
|
||||
return this.includeInBorrowerCycle;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user