diff --git a/mifosng-db/patches-post-multi-tenant/patch-0007-add-loan-transaction-strategy-table-and-relationships.sql b/mifosng-db/patches-post-multi-tenant/patch-0007-add-loan-transaction-strategy-table-and-relationships.sql index e2a385c3a..8e4639955 100644 --- a/mifosng-db/patches-post-multi-tenant/patch-0007-add-loan-transaction-strategy-table-and-relationships.sql +++ b/mifosng-db/patches-post-multi-tenant/patch-0007-add-loan-transaction-strategy-table-and-relationships.sql @@ -18,6 +18,11 @@ ADD COLUMN `loan_transaction_strategy_id` bigint(20) DEFAULT NULL, ADD KEY `FK_ltp_strategy` (`loan_transaction_strategy_id`), ADD CONSTRAINT `FK_ltp_strategy` FOREIGN KEY (`loan_transaction_strategy_id`) REFERENCES `ref_loan_transaction_processing_strategy` (`id`); +ALTER TABLE `portfolio_loan` +ADD COLUMN `loan_transaction_strategy_id` bigint(20) DEFAULT NULL, +ADD KEY `FK_loan_ltp_strategy` (`loan_transaction_strategy_id`), +ADD CONSTRAINT `FK_loan_ltp_strategy` FOREIGN KEY (`loan_transaction_strategy_id`) REFERENCES `ref_loan_transaction_processing_strategy` (`id`); + -- update ref table with out-of-the-box strategies INSERT INTO `ref_loan_transaction_processing_strategy` diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/SubmitLoanApplicationCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/SubmitLoanApplicationCommand.java index ad4d01a8b..c7fdd044d 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/SubmitLoanApplicationCommand.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/SubmitLoanApplicationCommand.java @@ -15,6 +15,7 @@ public class SubmitLoanApplicationCommand { private final String externalId; private final Long fundId; + private final Long transactionProcessingStrategyId; private final BigDecimal principal; private final BigDecimal inArrearsTolerance; @@ -39,7 +40,8 @@ public class SubmitLoanApplicationCommand { private LoanSchedule loanSchedule; public SubmitLoanApplicationCommand( - final Long clientId, final Long productId, final String externalId, final Long fundId, + final Long clientId, final Long productId, final String externalId, + final Long fundId, final Long transactionProcessingStrategyId, final LocalDate submittedOnDate, final String submittedOnNote, final LocalDate expectedDisbursementDate, final LocalDate repaymentsStartingFromDate, @@ -55,6 +57,7 @@ public class SubmitLoanApplicationCommand { this.productId = productId; this.externalId = externalId; this.fundId = fundId; + this.transactionProcessingStrategyId = transactionProcessingStrategyId; this.submittedOnDate = submittedOnDate; this.submittedOnNote = submittedOnNote; @@ -104,6 +107,10 @@ public class SubmitLoanApplicationCommand { public Long getFundId() { return fundId; } + + public Long getTransactionProcessingStrategyId() { + return transactionProcessingStrategyId; + } public BigDecimal getPrincipal() { return principal; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java index d75f1bbc8..c4fa0d125 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java @@ -872,7 +872,7 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService { Map requestMap = gsonConverter.fromJson(json, typeOfMap); Set supportedParams = new HashSet( - Arrays.asList("clientId", "productId", "externalId", "fundId", + Arrays.asList("clientId", "productId", "externalId", "fundId", "transactionProcessingStrategyId", "principal", "inArrearsTolerance", "interestRatePerPeriod", "repaymentEvery", "numberOfRepayments", "repaymentFrequencyType", "interestRateFrequencyType", "amortizationType", "interestType", "interestCalculationPeriodType", "expectedDisbursementDate", "repaymentsStartingFromDate", "interestChargedFromDate", "submittedOnDate", "submittedOnNote", @@ -886,6 +886,7 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService { Long clientId = extractLongParameter("clientId", requestMap, modifiedParameters); Long productId = extractLongParameter("productId", requestMap, modifiedParameters); Long fundId = extractLongParameter("fundId", requestMap, modifiedParameters); + Long transactionProcessingStrategyId = extractLongParameter("transactionProcessingStrategyId", requestMap, modifiedParameters); String externalId = extractStringParameter("externalId", requestMap, modifiedParameters); BigDecimal principal = extractBigDecimalParameter("principal", requestMap, modifiedParameters); @@ -908,7 +909,8 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService { String submittedOnNote = extractStringParameter("submittedOnNote", requestMap, modifiedParameters); - return new SubmitLoanApplicationCommand(clientId, productId, externalId, fundId, submittedOnDate, submittedOnNote, + return new SubmitLoanApplicationCommand(clientId, productId, externalId, fundId, transactionProcessingStrategyId, + submittedOnDate, submittedOnNote, expectedDisbursementDate, repaymentsStartingFromDate, interestChargedFromDate, principal, interestRatePerPeriod, interestRateFrequencyTypeValue, interestTypeValue, interestCalculationPeriodTypeValue, repaymentEvery, repaymentFrequencyType, numberOfRepayments, amortizationTypeValue, inArrearsToleranceValue); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/Loan.java index e8365287e..8a7fa34e4 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/Loan.java @@ -50,6 +50,10 @@ public class Loan extends AbstractAuditableCustom { @ManyToOne @JoinColumn(name = "fund_id", nullable = true) private Fund fund; + + @ManyToOne + @JoinColumn(name = "loan_transaction_strategy_id", nullable = true) + private LoanTransactionProcessingStrategy transactionProcessingStrategy; @Column(name = "external_id") private String externalId; @@ -136,11 +140,10 @@ public class Loan extends AbstractAuditableCustom { @Transient private final LoanRepaymentScheduleTransactionProcessorFactory transactionProcessor = new LoanRepaymentScheduleTransactionProcessorFactory(); - public static Loan createNew(final Fund fund, + public static Loan createNew(final Fund fund, final LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanProduct loanProduct, final Client client, final LoanProductRelatedDetail loanRepaymentScheduleDetail) { - return new Loan(client, fund, loanProduct, loanRepaymentScheduleDetail, - null); + return new Loan(client, fund, transactionProcessingStrategy, loanProduct, loanRepaymentScheduleDetail, null); } public Loan() { @@ -149,15 +152,12 @@ public class Loan extends AbstractAuditableCustom { this.loanRepaymentScheduleDetail = null; } - public Loan(final Client client, Fund fund, final LoanProduct loanProduct, + public Loan(final Client client, Fund fund, LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanProduct loanProduct, final LoanProductRelatedDetail loanRepaymentScheduleDetail, final LoanStatus loanStatus) { this.client = client; - if (fund != null) { - this.fund = fund; - } else { - this.fund = loanProduct.getFund(); - } + this.fund = fund; + this.transactionProcessingStrategy = transactionProcessingStrategy; this.loanProduct = loanProduct; this.loanRepaymentScheduleDetail = loanRepaymentScheduleDetail; this.loanStatus = loanStatus; @@ -445,7 +445,7 @@ public class Loan extends AbstractAuditableCustom { Collections.sort(repaymentsOrWaivers, transactionComparator); - final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessor.determineProcessor(); + final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessor.determineProcessor(this.transactionProcessingStrategy); if (isTransactionChronologicallyLatest && !adjusted) { loanRepaymentScheduleTransactionProcessor.handleTransaction(loanTransaction, getCurrency(), this.repaymentScheduleInstallments); } else { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanRepaymentScheduleTransactionProcessorFactory.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanRepaymentScheduleTransactionProcessorFactory.java index 753ed01ea..8c13e3fa6 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanRepaymentScheduleTransactionProcessorFactory.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanRepaymentScheduleTransactionProcessorFactory.java @@ -1,21 +1,32 @@ package org.mifosng.platform.loan.domain; -import org.mifosng.platform.infrastructure.MifosPlatformTenant; -import org.mifosng.platform.infrastructure.ThreadLocalContextUtil; /** * */ public class LoanRepaymentScheduleTransactionProcessorFactory { - public LoanRepaymentScheduleTransactionProcessor determineProcessor() { + public LoanRepaymentScheduleTransactionProcessor determineProcessor(final LoanTransactionProcessingStrategy transactionProcessingStrategy) { LoanRepaymentScheduleTransactionProcessor processor = new HeavensFamilyLoanRepaymentScheduleTransactionProcessor(); - // FIXME - Just temp way of deciding what 'repayment strategy' to use for now. - MifosPlatformTenant tenant = ThreadLocalContextUtil.getTenant(); - if ("mifostenant-creocore".equalsIgnoreCase(tenant.getSchemaName())) { - processor = new CreocoreLoanRepaymentScheduleTransactionProcessor(); + if (transactionProcessingStrategy != null) { + + if (transactionProcessingStrategy.isStandardMifosStrategy()) { + processor = new HeavensFamilyLoanRepaymentScheduleTransactionProcessor(); + } + + if (transactionProcessingStrategy.isHeavensfamilyStrategy()) { + processor = new HeavensFamilyLoanRepaymentScheduleTransactionProcessor(); + } + + if (transactionProcessingStrategy.isCreocoreStrategy()) { + processor = new CreocoreLoanRepaymentScheduleTransactionProcessor(); + } + + if (transactionProcessingStrategy.isIndianRBIStrategy()) { + processor = new AdhikarLoanRepaymentScheduleTransactionProcessor(); + } } return processor; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanTransactionProcessingStrategy.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanTransactionProcessingStrategy.java index 94e913926..5e19769f8 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanTransactionProcessingStrategy.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanTransactionProcessingStrategy.java @@ -25,11 +25,23 @@ public class LoanTransactionProcessingStrategy extends AbstractAuditableCustom