Merge pull request #406 from mifoscontributer/MIFOSX-212-B
Add Loan cycle counter for client
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
ALTER TABLE m_product_loan
|
||||
ADD COLUMN `include_in_borrower_cycle` TINYINT(1) NOT NULL DEFAULT '0';
|
||||
|
||||
CREATE TABLE `m_client_loan_counter` (
|
||||
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
`client_id` BIGINT(20) NOT NULL,
|
||||
`loan_product_id` BIGINT(20) NOT NULL,
|
||||
`loan_id` BIGINT(20) NOT NULL,
|
||||
`running_count` SMALLINT(4) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `FK_m_client_id_loan_counter` (`client_id`),
|
||||
INDEX `FK_m_loan_product_loan_counter` (`loan_product_id`),
|
||||
INDEX `FK_m_client_loan_counter` (`loan_id`),
|
||||
CONSTRAINT `FK_m_client_id_loan_counter` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`),
|
||||
CONSTRAINT `FK_m_loan_product_loan_counter` FOREIGN KEY (`loan_product_id`) REFERENCES `m_product_loan` (`id`),
|
||||
CONSTRAINT `FK_m_client_loan_counter` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`)
|
||||
)
|
||||
COLLATE='utf8_general_ci'
|
||||
ENGINE=InnoDB;
|
||||
+6
-1
@@ -30,6 +30,8 @@ public class ClientAccountSummaryData {
|
||||
@SuppressWarnings("unused")
|
||||
private final EnumOptionData loanType;
|
||||
private final SavingsAccountStatusEnumData savingAccountStatus;
|
||||
@SuppressWarnings("unused")
|
||||
private final Integer loanCycle;
|
||||
|
||||
public ClientAccountSummaryData(final Long id, final String externalId, final Long productId, final String loanProductName,
|
||||
final Integer loanStatusId) {
|
||||
@@ -42,10 +44,11 @@ public class ClientAccountSummaryData {
|
||||
this.status = null;
|
||||
this.loanType = null;
|
||||
this.savingAccountStatus = null;
|
||||
this.loanCycle = null;
|
||||
}
|
||||
|
||||
public ClientAccountSummaryData(final Long id, final String accountNo, final String externalId, final Long productId,
|
||||
final String loanProductName, final LoanStatusEnumData loanStatus, final EnumOptionData loanType) {
|
||||
final String loanProductName, final LoanStatusEnumData loanStatus, final EnumOptionData loanType, final Integer loanCycle) {
|
||||
this.id = id;
|
||||
this.accountNo = accountNo;
|
||||
this.externalId = externalId;
|
||||
@@ -55,6 +58,7 @@ public class ClientAccountSummaryData {
|
||||
this.status = loanStatus;
|
||||
this.loanType = loanType;
|
||||
this.savingAccountStatus = null;
|
||||
this.loanCycle = loanCycle;
|
||||
}
|
||||
|
||||
public ClientAccountSummaryData(final Long id, final String accountNo, final String externalId, final Long productId,
|
||||
@@ -68,6 +72,7 @@ public class ClientAccountSummaryData {
|
||||
this.status = null;
|
||||
this.loanType = null;
|
||||
this.savingAccountStatus = savingAccountStatus;
|
||||
this.loanCycle = null;
|
||||
}
|
||||
|
||||
public Integer accountStatusId() {
|
||||
|
||||
+6
-3
@@ -520,8 +520,10 @@ 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("from m_loan l ")
|
||||
.append("LEFT JOIN m_product_loan AS lp ON lp.id = l.product_id ");
|
||||
.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 ");
|
||||
|
||||
return accountsSummary.toString();
|
||||
}
|
||||
@@ -538,8 +540,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
final LoanStatusEnumData loanStatus = LoanEnumerations.status(loanStatusId);
|
||||
final Integer loanTypeId = JdbcSupport.getInteger(rs, "loanType");
|
||||
final EnumOptionData loanType = LoanEnumerations.loanType(loanTypeId);
|
||||
final Integer loanCycle = JdbcSupport.getInteger(rs, "loanCycle");
|
||||
|
||||
return new ClientAccountSummaryData(id, accountNo, externalId, productId, loanProductName, loanStatus, loanType);
|
||||
return new ClientAccountSummaryData(id, accountNo, externalId, productId, loanProductName, loanStatus, loanType, loanCycle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
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
@@ -0,0 +1,15 @@
|
||||
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);
|
||||
|
||||
}
|
||||
+4
@@ -6,6 +6,7 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.domain;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
@@ -23,4 +24,7 @@ public interface LoanRepository extends JpaRepository<Loan, Long>,
|
||||
|
||||
@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);
|
||||
}
|
||||
+54
-1
@@ -39,6 +39,7 @@ 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;
|
||||
@@ -49,6 +50,8 @@ 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;
|
||||
@@ -64,6 +67,7 @@ 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;
|
||||
@@ -94,6 +98,7 @@ 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,
|
||||
@@ -105,7 +110,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 PaymentDetailWritePlatformService paymentDetailWritePlatformService, final LoanCycleRepository loanCycleRepository) {
|
||||
this.context = context;
|
||||
this.loanEventApiJsonValidator = loanEventApiJsonValidator;
|
||||
this.loanAssembler = loanAssembler;
|
||||
@@ -122,6 +127,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.loanScheduleFactory = loanScheduleFactory;
|
||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
||||
this.paymentDetailWritePlatformService = paymentDetailWritePlatformService;
|
||||
this.loanCycleRepository = loanCycleRepository;
|
||||
}
|
||||
|
||||
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
||||
@@ -161,6 +167,31 @@ 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());
|
||||
|
||||
// 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);
|
||||
|
||||
@@ -273,6 +304,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
context.authenticatedUser();
|
||||
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
removeLoanCycle(loan);
|
||||
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
||||
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
||||
final Map<String, Object> changes = loan.undoDisbursal(existingTransactionIds, existingReversedTransactionIds);
|
||||
@@ -574,6 +606,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
changes.put("dateFormat", command.dateFormat());
|
||||
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
removeLoanCycle(loan);
|
||||
|
||||
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
||||
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
||||
@@ -674,6 +707,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.loanEventApiJsonValidator.validateTransactionWithNoAmount(command.json());
|
||||
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
removeLoanCycle(loan);
|
||||
|
||||
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
||||
changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate"));
|
||||
@@ -1006,4 +1040,23 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
if (loanCycleToRemove != null) {
|
||||
this.loanCycleRepository.save(loanCycles);
|
||||
this.loanCycleRepository.delete(loanCycleToRemove);
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-9
@@ -60,15 +60,15 @@ import org.springframework.stereotype.Component;
|
||||
public class LoanProductsApiResource {
|
||||
|
||||
private final Set<String> LOAN_PRODUCT_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "name", "description", "fundId",
|
||||
"fundName", "currency", "principal", "minPrincipal", "maxPrincipal", "numberOfRepayments", "minNumberOfRepayments",
|
||||
"maxNumberOfRepayments", "repaymentEvery", "repaymentFrequencyType", "graceOnPrincipalPayment", "graceOnInterestPayment",
|
||||
"graceOnInterestCharged", "interestRatePerPeriod", "minInterestRatePerPeriod", "maxInterestRatePerPeriod",
|
||||
"interestRateFrequencyType", "annualInterestRate", "amortizationType", "interestType", "interestCalculationPeriodType",
|
||||
"inArrearsTolerance", "transactionProcessingStrategyId", "transactionProcessingStrategyName", "charges", "accountingRule",
|
||||
"accountingMappings", "paymentChannelToFundSourceMappings", "fundOptions", "paymentTypeOptions", "currencyOptions",
|
||||
"repaymentFrequencyTypeOptions", "interestRateFrequencyTypeOptions", "amortizationTypeOptions", "interestTypeOptions",
|
||||
"interestCalculationPeriodTypeOptions", "transactionProcessingStrategyOptions", "chargeOptions", "accountingOptions",
|
||||
"accountingRuleOptions", "accountingMappingOptions"));
|
||||
"fundName", "includeInBorrowerCycle", "currency", "principal", "minPrincipal", "maxPrincipal", "numberOfRepayments",
|
||||
"minNumberOfRepayments", "maxNumberOfRepayments", "repaymentEvery", "repaymentFrequencyType", "graceOnPrincipalPayment",
|
||||
"graceOnInterestPayment", "graceOnInterestCharged", "interestRatePerPeriod", "minInterestRatePerPeriod",
|
||||
"maxInterestRatePerPeriod", "interestRateFrequencyType", "annualInterestRate", "amortizationType", "interestType",
|
||||
"interestCalculationPeriodType", "inArrearsTolerance", "transactionProcessingStrategyId", "transactionProcessingStrategyName",
|
||||
"charges", "accountingRule", "accountingMappings", "paymentChannelToFundSourceMappings", "fundOptions", "paymentTypeOptions",
|
||||
"currencyOptions", "repaymentFrequencyTypeOptions", "interestRateFrequencyTypeOptions", "amortizationTypeOptions",
|
||||
"interestTypeOptions", "interestCalculationPeriodTypeOptions", "transactionProcessingStrategyOptions", "chargeOptions",
|
||||
"accountingOptions", "accountingRuleOptions", "accountingMappingOptions"));
|
||||
|
||||
private final String resourceNameForPermissions = "LOANPRODUCT";
|
||||
|
||||
|
||||
+10
-4
@@ -37,6 +37,7 @@ public class LoanProductData {
|
||||
private final String description;
|
||||
private final Long fundId;
|
||||
private final String fundName;
|
||||
private final boolean includeInBorrowerCycle;
|
||||
|
||||
// terms
|
||||
private final CurrencyData currency;
|
||||
@@ -127,13 +128,14 @@ public class LoanProductData {
|
||||
final Integer graceOnInterestCharged = null;
|
||||
final Collection<ChargeData> charges = null;
|
||||
final EnumOptionData accountingType = null;
|
||||
final boolean includeInBorrowerCycle = false;
|
||||
|
||||
return new LoanProductData(id, name, description, currency, principal, minPrincipal, maxPrincipal, tolerance, numberOfRepayments,
|
||||
minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod, minInterestRatePerPeriod,
|
||||
maxInterestRatePerPeriod, annualInterestRate, repaymentFrequencyType, interestRateFrequencyType, amortizationType,
|
||||
interestType, interestCalculationPeriodType, fundId, fundName, transactionProcessingStrategyId,
|
||||
transactionProcessingStrategyName, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, charges,
|
||||
accountingType);
|
||||
accountingType, includeInBorrowerCycle);
|
||||
}
|
||||
|
||||
public static LoanProductData lookupWithCurrency(final Long id, final String name, final CurrencyData currency) {
|
||||
@@ -165,13 +167,14 @@ public class LoanProductData {
|
||||
|
||||
final Collection<ChargeData> charges = null;
|
||||
final EnumOptionData accountingType = null;
|
||||
final boolean includeInBorrowerCycle = false;
|
||||
|
||||
return new LoanProductData(id, name, description, currency, principal, minPrincipal, maxPrincipal, tolerance, numberOfRepayments,
|
||||
minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod, minInterestRatePerPeriod,
|
||||
maxInterestRatePerPeriod, annualInterestRate, repaymentFrequencyType, interestRateFrequencyType, amortizationType,
|
||||
interestType, interestCalculationPeriodType, fundId, fundName, transactionProcessingStrategyId,
|
||||
transactionProcessingStrategyName, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, charges,
|
||||
accountingType);
|
||||
accountingType, includeInBorrowerCycle);
|
||||
}
|
||||
|
||||
public static LoanProductData sensibleDefaultsForNewLoanProductCreation() {
|
||||
@@ -209,13 +212,14 @@ public class LoanProductData {
|
||||
|
||||
final Collection<ChargeData> charges = null;
|
||||
final EnumOptionData accountingType = AccountingEnumerations.accountingRuleType(AccountingRuleType.NONE);
|
||||
final boolean includeInBorrowerCycle = false;
|
||||
|
||||
return new LoanProductData(id, name, description, currency, principal, minPrincipal, maxPrincipal, tolerance, numberOfRepayments,
|
||||
minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod, minInterestRatePerPeriod,
|
||||
maxInterestRatePerPeriod, annualInterestRate, repaymentFrequencyType, interestRateFrequencyType, amortizationType,
|
||||
interestType, interestCalculationPeriodType, fundId, fundName, transactionProcessingStrategyId,
|
||||
transactionProcessingStrategyName, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, charges,
|
||||
accountingType);
|
||||
accountingType, includeInBorrowerCycle);
|
||||
}
|
||||
|
||||
public static LoanProductData withAccountingDetails(final LoanProductData productData, final Map<String, Object> accountingMappings,
|
||||
@@ -238,7 +242,7 @@ public class LoanProductData {
|
||||
final EnumOptionData interestCalculationPeriodType, final Long fundId, final String fundName,
|
||||
final Long transactionProcessingStrategyId, final String transactionProcessingStrategyName,
|
||||
final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged,
|
||||
final Collection<ChargeData> charges, final EnumOptionData accountingType) {
|
||||
final Collection<ChargeData> charges, final EnumOptionData accountingType, final boolean includeInBorrowerCycle) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
@@ -269,6 +273,7 @@ public class LoanProductData {
|
||||
this.transactionProcessingStrategyName = transactionProcessingStrategyName;
|
||||
this.charges = charges;
|
||||
this.accountingRule = accountingType;
|
||||
this.includeInBorrowerCycle = includeInBorrowerCycle;
|
||||
|
||||
this.chargeOptions = null;
|
||||
this.penaltyOptions = null;
|
||||
@@ -349,6 +354,7 @@ public class LoanProductData {
|
||||
this.graceOnPrincipalPayment = productData.graceOnPrincipalPayment;
|
||||
this.graceOnInterestPayment = productData.graceOnInterestPayment;
|
||||
this.graceOnInterestCharged = productData.graceOnInterestCharged;
|
||||
this.includeInBorrowerCycle = productData.includeInBorrowerCycle;
|
||||
|
||||
this.amortizationTypeOptions = amortizationTypeOptions;
|
||||
this.interestTypeOptions = interestTypeOptions;
|
||||
|
||||
+14
-2
@@ -72,6 +72,9 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
|
||||
@Column(name = "accounting_type", nullable = false)
|
||||
private Integer accountingRule;
|
||||
|
||||
@Column(name = "include_in_borrower_cycle")
|
||||
private boolean includeInBorrowerCycle;
|
||||
|
||||
public static LoanProduct assembleFromJson(final Fund fund, final LoanTransactionProcessingStrategy loanTransactionProcessingStrategy,
|
||||
final List<Charge> productCharges, final JsonCommand command, final AprCalculator aprCalculator) {
|
||||
@@ -111,12 +114,13 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
final Integer graceOnInterestCharged = command.integerValueOfParameterNamed("graceOnInterestCharged");
|
||||
|
||||
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(command.integerValueOfParameterNamed("accountingRule"));
|
||||
final boolean includeInBorrowerCycle = command.booleanPrimitiveValueOfParameterNamed("includeInBorrowerCycle");
|
||||
|
||||
return new LoanProduct(fund, loanTransactionProcessingStrategy, name, description, currency, principal, minPrincipal, maxPrincipal,
|
||||
interestRatePerPeriod, minInterestRatePerPeriod, maxInterestRatePerPeriod, interestFrequencyType, annualInterestRate,
|
||||
interestMethod, interestCalculationPeriodMethod, repaymentEvery, repaymentFrequencyType, numberOfRepayments,
|
||||
minNumberOfRepayments, maxNumberOfRepayments, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged,
|
||||
amortizationMethod, inArrearsTolerance, productCharges, accountingRuleType);
|
||||
amortizationMethod, inArrearsTolerance, productCharges, accountingRuleType, includeInBorrowerCycle);
|
||||
}
|
||||
|
||||
protected LoanProduct() {
|
||||
@@ -135,7 +139,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
final Integer defaultMinNumberOfInstallments, final Integer defaultMaxNumberOfInstallments,
|
||||
final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged,
|
||||
final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance, final List<Charge> charges,
|
||||
final AccountingRuleType accountingRuleType) {
|
||||
final AccountingRuleType accountingRuleType, final boolean includeInBorrowerCycle) {
|
||||
this.fund = fund;
|
||||
this.transactionProcessingStrategy = transactionProcessingStrategy;
|
||||
this.name = name.trim();
|
||||
@@ -163,6 +167,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
if (accountingRuleType != null) {
|
||||
this.accountingRule = accountingRuleType.getValue();
|
||||
}
|
||||
this.includeInBorrowerCycle = includeInBorrowerCycle;
|
||||
}
|
||||
|
||||
public MonetaryCurrency getCurrency() {
|
||||
@@ -257,6 +262,13 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
actualChanges.put(chargesParamName, command.jsonFragment(chargesParamName));
|
||||
}
|
||||
}
|
||||
|
||||
final String includeInBorrowerCycleParamName = "includeInBorrowerCycle";
|
||||
if (command.isChangeInBooleanParameterNamed(includeInBorrowerCycleParamName, this.includeInBorrowerCycle)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(includeInBorrowerCycleParamName);
|
||||
actualChanges.put(includeInBorrowerCycleParamName, newValue);
|
||||
this.includeInBorrowerCycle = newValue;
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
+4
-1
@@ -43,7 +43,7 @@ public final class LoanProductDataValidator {
|
||||
"minNumberOfRepayments", "maxNumberOfRepayments", "repaymentFrequencyType", "interestRatePerPeriod",
|
||||
"minInterestRatePerPeriod", "maxInterestRatePerPeriod", "interestRateFrequencyType", "amortizationType", "interestType",
|
||||
"interestCalculationPeriodType", "inArrearsTolerance", "transactionProcessingStrategyId", "graceOnPrincipalPayment",
|
||||
"graceOnInterestPayment", "graceOnInterestCharged", "charges", "accountingRule",
|
||||
"graceOnInterestPayment", "graceOnInterestCharged", "charges", "accountingRule","includeInBorrowerCycle",
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(),
|
||||
@@ -81,6 +81,9 @@ public final class LoanProductDataValidator {
|
||||
final Long fundId = fromApiJsonHelper.extractLongNamed("fundId", element);
|
||||
baseDataValidator.reset().parameter("fundId").value(fundId).ignoreIfNull().integerGreaterThanZero();
|
||||
}
|
||||
|
||||
final Boolean includeInBorrowerCycle = fromApiJsonHelper.extractBooleanNamed("includeInBorrowerCycle", element);
|
||||
baseDataValidator.reset().parameter("includeInBorrowerCycle").value(includeInBorrowerCycle).notNull();
|
||||
|
||||
// terms
|
||||
final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element);
|
||||
|
||||
+4
-2
@@ -103,7 +103,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
+ "lp.repay_every as repaidEvery, lp.repayment_period_frequency_enum as repaymentPeriodFrequency, lp.number_of_repayments as numberOfRepayments, lp.min_number_of_repayments as minNumberOfRepayments, lp.max_number_of_repayments as maxNumberOfRepayments, "
|
||||
+ "lp.grace_on_principal_periods as graceOnPrincipalPayment, lp.grace_on_interest_periods as graceOnInterestPayment, lp.grace_interest_free_periods as graceOnInterestCharged,"
|
||||
+ "lp.amortization_method_enum as amortizationMethod, lp.arrearstolerance_amount as tolerance, "
|
||||
+ "lp.accounting_type as accountingType, "
|
||||
+ "lp.accounting_type as accountingType, lp.include_in_borrower_cycle as includeInBorrowerCycle, "
|
||||
+ "curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol "
|
||||
+ " from m_product_loan lp "
|
||||
+ " left join m_fund f on f.id = lp.fund_id"
|
||||
@@ -168,13 +168,15 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
final int interestCalculationPeriodTypeId = JdbcSupport.getInteger(rs, "interestCalculationInPeriodMethod");
|
||||
final EnumOptionData interestCalculationPeriodType = LoanEnumerations
|
||||
.interestCalculationPeriodType(interestCalculationPeriodTypeId);
|
||||
|
||||
final boolean includeInBorrowerCycle = rs.getBoolean("includeInBorrowerCycle");
|
||||
|
||||
return new LoanProductData(id, name, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
minInterestRatePerPeriod, maxInterestRatePerPeriod, annualInterestRate, repaymentFrequencyType,
|
||||
interestRateFrequencyType, amortizationType, interestType, interestCalculationPeriodType, fundId, fundName,
|
||||
transactionStrategyId, transactionStrategyName, graceOnPrincipalPayment, graceOnInterestPayment,
|
||||
graceOnInterestCharged, this.charges, accountingRuleType);
|
||||
graceOnInterestCharged, this.charges, accountingRuleType, includeInBorrowerCycle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user