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>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</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">
|
<tr class="alt">
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>clients/{clientId}/loans</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
|
business that doesnt suit the firstname,middlename,lastname
|
||||||
structure.</td>
|
structure.</td>
|
||||||
</tr>
|
</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>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1906,7 +1928,7 @@ GET https://DomainName/api/v1/clients/template
|
|||||||
<td><div class="mifosXHeading2">Optional Fields</div></td>
|
<td><div class="mifosXHeading2">Optional Fields</div></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class=alt>
|
<tr class=alt>
|
||||||
<td>groupId, externalId, accountNo</td>
|
<td>groupId, externalId, accountNo, staffId</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@@ -2017,6 +2039,59 @@ Request Body:
|
|||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
|
</div>
|
||||||
<a id="clients_retrieve" name="clients_retrieve" class="old-syle-anchor"> </a>
|
<a id="clients_retrieve" name="clients_retrieve" class="old-syle-anchor"> </a>
|
||||||
<div class="method-section">
|
<div class="method-section">
|
||||||
<div class="method-description">
|
<div class="method-description">
|
||||||
@@ -7084,6 +7159,12 @@ Request Body:
|
|||||||
<tr>
|
<tr>
|
||||||
<td class=fielddesc>For associating a loan product with a given fund by default.</td>
|
<td class=fielddesc>For associating a loan product with a given fund by default.</td>
|
||||||
</tr>
|
</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>
|
<tr class=alt>
|
||||||
<td>currencyCode</td>
|
<td>currencyCode</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -7786,7 +7867,7 @@ GET https://DomainName/api/v1/loanproducts/{productId}
|
|||||||
<td><div class="mifosXHeading2">Optional Fields</div></td>
|
<td><div class="mifosXHeading2">Optional Fields</div></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class=alt>
|
<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>
|
||||||
|
|
||||||
<tr class="matrixHeadingBG">
|
<tr class="matrixHeadingBG">
|
||||||
@@ -15834,6 +15915,22 @@ GET https://DomainName/api/v1/search?query=000000111
|
|||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</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">
|
<tr class="alt">
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>clients/{clientId}/loans</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,");
|
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,")
|
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("l.loan_status_id as statusId, l.loan_type_enum as loanType, ")
|
||||||
.append("lc.running_count as loanCycle ").append(" from m_loan l ")
|
.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 ")
|
.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 ");
|
|
||||||
|
|
||||||
return accountsSummary.toString();
|
return accountsSummary.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -96,7 +96,8 @@ public class LoansApiResource {
|
|||||||
"summary", "repaymentSchedule", "transactions", "charges", "collateral", "guarantors", "meeting", "productOptions",
|
"summary", "repaymentSchedule", "transactions", "charges", "collateral", "guarantors", "meeting", "productOptions",
|
||||||
"amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions", "repaymentFrequencyTypeOptions",
|
"amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions", "repaymentFrequencyTypeOptions",
|
||||||
"termFrequencyTypeOptions", "interestRateFrequencyTypeOptions", "fundOptions", "repaymentStrategyOptions", "chargeOptions",
|
"termFrequencyTypeOptions", "interestRateFrequencyTypeOptions", "fundOptions", "repaymentStrategyOptions", "chargeOptions",
|
||||||
"loanOfficerOptions", "loanPurposeOptions", "loanCollateralOptions", "chargeTemplate", "calendarOptions", "syncDisbursementWithMeeting"));
|
"loanOfficerOptions", "loanPurposeOptions", "loanCollateralOptions", "chargeTemplate", "calendarOptions", "syncDisbursementWithMeeting",
|
||||||
|
"loanCounter", "loanProductCounter"));
|
||||||
|
|
||||||
private final String resourceNameForPermissions = "LOAN";
|
private final String resourceNameForPermissions = "LOAN";
|
||||||
|
|
||||||
|
|||||||
+32
-12
@@ -123,6 +123,10 @@ public class LoanAccountData {
|
|||||||
private final BigDecimal feeChargesAtDisbursementCharged;
|
private final BigDecimal feeChargesAtDisbursementCharged;
|
||||||
private final BigDecimal totalOverpaid;
|
private final BigDecimal totalOverpaid;
|
||||||
|
|
||||||
|
//loanCycle
|
||||||
|
private final Integer loanCounter;
|
||||||
|
private final Integer loanProductCounter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to produce a {@link LoanAccountData} with only collateral options
|
* Used to produce a {@link LoanAccountData} with only collateral options
|
||||||
* for now.
|
* for now.
|
||||||
@@ -192,6 +196,8 @@ public class LoanAccountData {
|
|||||||
final Collection<CodeValueData> loanPurposeOptions = null;
|
final Collection<CodeValueData> loanPurposeOptions = null;
|
||||||
final Collection<CalendarData> calendarOptions = null;
|
final Collection<CalendarData> calendarOptions = null;
|
||||||
final Boolean syncDisbursementWithMeeting = 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,
|
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId,
|
||||||
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
||||||
@@ -203,7 +209,7 @@ public class LoanAccountData {
|
|||||||
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, transactionProcessingStrategyOptions,
|
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, transactionProcessingStrategyOptions,
|
||||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
||||||
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
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<CodeValueData> loanCollateralOptions = null;
|
||||||
final Collection<CalendarData> calendarOptions = null;
|
final Collection<CalendarData> calendarOptions = null;
|
||||||
final Boolean syncDisbursementWithMeeting = 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,
|
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId,
|
||||||
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
||||||
@@ -285,7 +293,8 @@ public class LoanAccountData {
|
|||||||
feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData,
|
feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData,
|
||||||
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
|
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
|
||||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
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) {
|
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.meeting, acc.productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions,
|
||||||
acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
|
acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
|
||||||
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
|
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<CodeValueData> loanCollateralOptions = null;
|
||||||
final Collection<CalendarData> calendarOptions = null;
|
final Collection<CalendarData> calendarOptions = null;
|
||||||
final Boolean syncDisbursementWithMeeting = 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,
|
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId,
|
||||||
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
||||||
@@ -386,7 +398,7 @@ public class LoanAccountData {
|
|||||||
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
|
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
|
||||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
||||||
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
||||||
syncDisbursementWithMeeting);
|
syncDisbursementWithMeeting, loancounter, loanProductCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData populateGroupDefaults(final LoanAccountData acc, final LoanAccountData groupAcc) {
|
public static LoanAccountData populateGroupDefaults(final LoanAccountData acc, final LoanAccountData groupAcc) {
|
||||||
@@ -404,7 +416,7 @@ public class LoanAccountData {
|
|||||||
acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
|
acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
|
||||||
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
|
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
|
||||||
acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions,
|
acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions,
|
||||||
acc.syncDisbursementWithMeeting);
|
acc.syncDisbursementWithMeeting, acc.loanCounter, acc.loanProductCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData loanProductWithTemplateDefaults(final LoanProductData product,
|
public static LoanAccountData loanProductWithTemplateDefaults(final LoanProductData product,
|
||||||
@@ -470,6 +482,9 @@ public class LoanAccountData {
|
|||||||
charges.add(charge.toLoanChargeData());
|
charges.add(charge.toLoanChargeData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final Integer loancounter = null;
|
||||||
|
final Integer loanProductCounter = null;
|
||||||
|
|
||||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType,
|
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType,
|
||||||
product.getId(), product.getName(), product.getDescription(), product.getFundId(), product.getFundName(), loanPurposeId,
|
product.getId(), product.getName(), product.getDescription(), product.getFundId(), product.getFundName(), loanPurposeId,
|
||||||
loanPurposeName, loanOfficerId, loanOfficerName, product.getCurrency(), product.getPrincipal(), totalOverpaid,
|
loanPurposeName, loanOfficerId, loanOfficerName, product.getCurrency(), product.getPrincipal(), totalOverpaid,
|
||||||
@@ -482,7 +497,7 @@ public class LoanAccountData {
|
|||||||
repaymentSchedule, transactions, charges, collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions,
|
repaymentSchedule, transactions, charges, collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions,
|
||||||
repaymentFrequencyTypeOptions, repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions,
|
repaymentFrequencyTypeOptions, repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions,
|
||||||
interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions,
|
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) {
|
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,
|
acc.summary, acc.feeChargesAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors,
|
||||||
calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
|
calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
|
||||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
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 EnumOptionData interestCalculationPeriodType, final LocalDate expectedFirstRepaymentOnDate,
|
||||||
final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged,
|
final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged,
|
||||||
final LocalDate interestChargedFromDate, final LoanApplicationTimelineData timeline, final LoanSummaryData loanSummary,
|
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 LoanScheduleData repaymentSchedule = null;
|
||||||
final Collection<LoanTransactionData> transactions = null;
|
final Collection<LoanTransactionData> transactions = null;
|
||||||
@@ -581,7 +598,7 @@ public class LoanAccountData {
|
|||||||
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
|
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
|
||||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
||||||
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
||||||
syncDisbursementWithMeeting);
|
syncDisbursementWithMeeting, loancounter, loanProductCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -611,7 +628,7 @@ public class LoanAccountData {
|
|||||||
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, transactionProcessingStrategyOptions,
|
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, transactionProcessingStrategyOptions,
|
||||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
||||||
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
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,
|
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.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
|
||||||
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
|
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
|
||||||
acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions,
|
acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions,
|
||||||
acc.syncDisbursementWithMeeting);
|
acc.syncDisbursementWithMeeting, acc.loanCounter, acc.loanProductCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanAccountData(
|
private LoanAccountData(
|
||||||
@@ -684,7 +701,7 @@ public class LoanAccountData {
|
|||||||
final Collection<FundData> fundOptions, final Collection<ChargeData> chargeOptions, final ChargeData chargeTemplate,
|
final Collection<FundData> fundOptions, final Collection<ChargeData> chargeOptions, final ChargeData chargeTemplate,
|
||||||
final Collection<StaffData> loanOfficerOptions, final Collection<CodeValueData> loanPurposeOptions,
|
final Collection<StaffData> loanOfficerOptions, final Collection<CodeValueData> loanPurposeOptions,
|
||||||
final Collection<CodeValueData> loanCollateralOptions, final Collection<CalendarData> calendarOptions,
|
final Collection<CodeValueData> loanCollateralOptions, final Collection<CalendarData> calendarOptions,
|
||||||
final Boolean syncDisbursementWithMeeting) {
|
final Boolean syncDisbursementWithMeeting, final Integer loanCounter, final Integer loanProductCounter) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.accountNo = accountNo;
|
this.accountNo = accountNo;
|
||||||
this.status = status;
|
this.status = status;
|
||||||
@@ -789,6 +806,9 @@ public class LoanAccountData {
|
|||||||
} else {
|
} else {
|
||||||
this.calendarOptions = calendarOptions;
|
this.calendarOptions = calendarOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.loanCounter = loanCounter;
|
||||||
|
this.loanProductCounter = loanProductCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData() {
|
public RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData() {
|
||||||
|
|||||||
+30
-1
@@ -100,7 +100,6 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
@JoinColumn(name = "group_id", nullable = true)
|
@JoinColumn(name = "group_id", nullable = true)
|
||||||
private Group group;
|
private Group group;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
@Column(name = "loan_type_enum", nullable = false)
|
@Column(name = "loan_type_enum", nullable = false)
|
||||||
private Integer loanType;
|
private Integer loanType;
|
||||||
|
|
||||||
@@ -231,6 +230,12 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
@Column(name = "total_overpaid_derived", scale = 6, precision = 19)
|
@Column(name = "total_overpaid_derived", scale = 6, precision = 19)
|
||||||
private BigDecimal totalOverpaid;
|
private BigDecimal totalOverpaid;
|
||||||
|
|
||||||
|
@Column(name = "loan_counter")
|
||||||
|
private Integer loanCounter;
|
||||||
|
|
||||||
|
@Column(name = "loan_product_counter")
|
||||||
|
private Integer loanProductCounter;
|
||||||
|
|
||||||
@LazyCollection(LazyCollectionOption.FALSE)
|
@LazyCollection(LazyCollectionOption.FALSE)
|
||||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true)
|
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true)
|
||||||
private Set<LoanCharge> charges = new HashSet<LoanCharge>();
|
private Set<LoanCharge> charges = new HashSet<LoanCharge>();
|
||||||
@@ -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);
|
|
||||||
|
|
||||||
}
|
|
||||||
+72
-10
@@ -14,17 +14,79 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
|
|
||||||
public interface LoanRepository extends JpaRepository<Loan, Long>,
|
public interface LoanRepository extends JpaRepository<Loan, Long>, JpaSpecificationExecutor<Loan> {
|
||||||
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")
|
public static final String FIND_GROUP_LOANS_DISBURSED_AFTER = "from Loan l where l.actualDisbursementDate > :disbursementDate and "
|
||||||
List<Loan> findLoanByClientId(@Param("clientId") Long clientId);
|
+ "l.group.id = :groupId and l.loanType = :loanType order by l.actualDisbursementDate";
|
||||||
|
|
||||||
@Query("from Loan loan where loan.id IN :ids and loan.loanStatus IN :loanStatuses and loan.loanType IN :loanTypes")
|
public static final String FIND_CLIENT_OR_JLG_LOANS_DISBURSED_AFTER = "from Loan l where l.actualDisbursementDate > :disbursementDate and "
|
||||||
List<Loan> findByIdsAndLoanStatusAndLoanType(@Param("ids") Collection<Long> ids, @Param("loanStatuses") Collection<Integer> loanStatuses, @Param("loanTypes") Collection<Integer> loanTypes);
|
+ "l.client.id = :clientId order by l.actualDisbursementDate";
|
||||||
|
|
||||||
@Query("select loan.id from Loan loan where loan.actualDisbursementDate > :disbursalDate order by loan.actualDisbursementDate")
|
public static final String FIND_MAX_GROUP_LOAN_COUNTER_QUERY = "Select MAX(l.loanCounter) from Loan l where l.group.id = :groupId "
|
||||||
List<Long> getLoansDisbursedAfter(@Param("disbursalDate") Date disbursalDate);
|
+ "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.penalty_charges_overdue_derived as penaltyChargesOverdue,"
|
||||||
+ " la.total_overdue_derived as totalOverdue,"
|
+ " la.total_overdue_derived as totalOverdue,"
|
||||||
+ " la.overdue_since_date_derived as overdueSinceDate,"
|
+ " 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" //
|
+ " from m_loan l" //
|
||||||
+ " join m_product_loan lp on lp.id = l.product_id" //
|
+ " join m_product_loan lp on lp.id = l.product_id" //
|
||||||
+ " join m_currency rc on rc.`code` = l.currency_code" //
|
+ " join m_currency rc on rc.`code` = l.currency_code" //
|
||||||
@@ -649,6 +650,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
null, groupParentId, null, groupStaffId, null, groupHierarchy);
|
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,
|
return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, groupData,
|
||||||
loanType, loanProductId, loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName,
|
loanType, loanProductId, loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName,
|
||||||
loanOfficerId, loanOfficerName, currencyData, principal, totalOverpaid, inArrearsTolerance, termFrequency,
|
loanOfficerId, loanOfficerName, currencyData, principal, totalOverpaid, inArrearsTolerance, termFrequency,
|
||||||
@@ -656,7 +660,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
amortizationType, interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, interestType,
|
amortizationType, interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, interestType,
|
||||||
interestCalculationPeriodType, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, graceOnInterestPayment,
|
interestCalculationPeriodType, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, graceOnInterestPayment,
|
||||||
graceOnInterestCharged, interestChargedFromDate, timeline, loanSummary, feeChargesDueAtDisbursementCharged,
|
graceOnInterestCharged, interestChargedFromDate, timeline, loanSummary, feeChargesDueAtDisbursementCharged,
|
||||||
syncDisbursementWithMeeting);
|
syncDisbursementWithMeeting, loanCounter, loanProductCounter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+141
-43
@@ -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;
|
||||||
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeWaivedException.LOAN_CHARGE_CANNOT_BE_WAIVED_REASON;
|
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeWaivedException.LOAN_CHARGE_CANNOT_BE_WAIVED_REASON;
|
||||||
import org.mifosplatform.portfolio.charge.exception.LoanChargeNotFoundException;
|
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.CollectionSheetBulkDisbursalCommand;
|
||||||
import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkRepaymentCommand;
|
import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkRepaymentCommand;
|
||||||
import org.mifosplatform.portfolio.collectionsheet.command.SingleDisbursalCommand;
|
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.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.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.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;
|
||||||
@@ -67,7 +64,6 @@ import org.mifosplatform.portfolio.loanaccount.exception.LoanTransactionNotFound
|
|||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
|
||||||
import org.mifosplatform.portfolio.loanaccount.serialization.LoanEventApiJsonValidator;
|
import org.mifosplatform.portfolio.loanaccount.serialization.LoanEventApiJsonValidator;
|
||||||
import org.mifosplatform.portfolio.loanaccount.serialization.LoanUpdateCommandFromApiJsonDeserializer;
|
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.domain.LoanProductRelatedDetail;
|
||||||
import org.mifosplatform.portfolio.loanproduct.exception.InvalidCurrencyException;
|
import org.mifosplatform.portfolio.loanproduct.exception.InvalidCurrencyException;
|
||||||
import org.mifosplatform.portfolio.note.domain.Note;
|
import org.mifosplatform.portfolio.note.domain.Note;
|
||||||
@@ -98,7 +94,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
private final LoanScheduleGeneratorFactory loanScheduleFactory;
|
private final LoanScheduleGeneratorFactory loanScheduleFactory;
|
||||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
private final CalendarInstanceRepository calendarInstanceRepository;
|
||||||
private final PaymentDetailWritePlatformService paymentDetailWritePlatformService;
|
private final PaymentDetailWritePlatformService paymentDetailWritePlatformService;
|
||||||
private final LoanCycleRepository loanCycleRepository;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||||
@@ -110,7 +105,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final JournalEntryWritePlatformService journalEntryWritePlatformService, final LoanSummaryWrapper loanSummaryWrapper,
|
final JournalEntryWritePlatformService journalEntryWritePlatformService, final LoanSummaryWrapper loanSummaryWrapper,
|
||||||
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
||||||
final LoanScheduleGeneratorFactory loanScheduleFactory, final CalendarInstanceRepository calendarInstanceRepository,
|
final LoanScheduleGeneratorFactory loanScheduleFactory, final CalendarInstanceRepository calendarInstanceRepository,
|
||||||
final PaymentDetailWritePlatformService paymentDetailWritePlatformService, final LoanCycleRepository loanCycleRepository) {
|
final PaymentDetailWritePlatformService paymentDetailWritePlatformService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.loanEventApiJsonValidator = loanEventApiJsonValidator;
|
this.loanEventApiJsonValidator = loanEventApiJsonValidator;
|
||||||
this.loanAssembler = loanAssembler;
|
this.loanAssembler = loanAssembler;
|
||||||
@@ -127,7 +122,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
this.loanScheduleFactory = loanScheduleFactory;
|
this.loanScheduleFactory = loanScheduleFactory;
|
||||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
this.calendarInstanceRepository = calendarInstanceRepository;
|
||||||
this.paymentDetailWritePlatformService = paymentDetailWritePlatformService;
|
this.paymentDetailWritePlatformService = paymentDetailWritePlatformService;
|
||||||
this.loanCycleRepository = loanCycleRepository;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
||||||
@@ -167,30 +161,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate");
|
final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate");
|
||||||
final LocalDate firstRepaymentMeetingDate = getFirstRepaymentMeetingDate(actualDisbursementDate, loan, calendarInstance);
|
final LocalDate firstRepaymentMeetingDate = getFirstRepaymentMeetingDate(actualDisbursementDate, loan, calendarInstance);
|
||||||
|
|
||||||
// create loan cycle
|
updateLoanCounters(loan, actualDisbursementDate);
|
||||||
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());
|
|
||||||
|
|
||||||
// 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,
|
loan.disburse(this.loanScheduleFactory, currentUser, command, applicationCurrency, existingTransactionIds,
|
||||||
existingReversedTransactionIds, changes, paymentDetail, firstRepaymentMeetingDate);
|
existingReversedTransactionIds, changes, paymentDetail, firstRepaymentMeetingDate);
|
||||||
@@ -1042,21 +1013,148 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void removeLoanCycle(final Loan loan) {
|
private void removeLoanCycle(final Loan loan) {
|
||||||
final Client client = loan.client();
|
final List<Loan> loansToUpdate;
|
||||||
final LoanProduct product = loan.loanProduct();
|
if (loan.isGroupLoan()) {
|
||||||
final List<LoanCycle> loanCycles = this.loanCycleRepository.findByClientIdAndLoanProductId(client.getId(), product.getId());
|
if (loan.loanProduct().isIncludeInBorrowerCycle()) {
|
||||||
LoanCycle loanCycleToRemove = null;
|
loansToUpdate = this.loanRepository.getGroupLoansToUpdateLoanCounter(loan.getCurrentLoanCounter(), loan.getGroupId(),
|
||||||
for (LoanCycle loanCycle : loanCycles) {
|
LoanType.GROUP.getValue());
|
||||||
if (loanCycle.loan().getId().equals(loan.getId())) {
|
} else {
|
||||||
loanCycleToRemove = loanCycle;
|
loansToUpdate = this.loanRepository.getGroupLoansToUpdateLoanProductCounter(loan.getLoanProductLoanCounter(),
|
||||||
} else if (loanCycleToRemove != null) {
|
loan.getGroupId(), LoanType.GROUP.getValue());
|
||||||
loanCycle = loanCycle.updateLoanCycleCounter(loanCycle.getRunningCounter() - 1);
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (loan.loanProduct().isIncludeInBorrowerCycle()) {
|
||||||
|
loansToUpdate = this.loanRepository
|
||||||
|
.getClientOrJLGLoansToUpdateLoanCounter(loan.getCurrentLoanCounter(), loan.getClientId());
|
||||||
|
} else {
|
||||||
|
loansToUpdate = this.loanRepository.getClientLoansToUpdateLoanProductCounter(loan.getLoanProductLoanCounter(),
|
||||||
|
loan.getClientId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
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 (loanCycleToRemove != null) {
|
if (includeInBorrowerCycle) {
|
||||||
this.loanCycleRepository.save(loanCycles);
|
loan.updateClientLoanCounter(newLoanCounter);
|
||||||
this.loanCycleRepository.delete(loanCycleToRemove);
|
} 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;
|
null, null, null, null) : this.loanProductMinMaxConstraints;
|
||||||
return loanProductMinMaxConstraints;
|
return loanProductMinMaxConstraints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isIncludeInBorrowerCycle() {
|
||||||
|
return this.includeInBorrowerCycle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user