A new rates module was added to define new rates that can be used to set min and max nominal interest rate, when a new loan account is created they can be used to determine which rates may be applicable for the loan account.
This commit is contained in:
committed by
Michael Vorburger ⛑️
parent
f484f884a0
commit
a7d4c83e92
+17
@@ -3147,4 +3147,21 @@ public class CommandWrapperBuilder {
|
|||||||
this.href = "/self/pocket?command="+PocketApiConstants.delinkAccountsFromPocketCommandParam;
|
this.href = "/self/pocket?command="+PocketApiConstants.delinkAccountsFromPocketCommandParam;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommandWrapperBuilder createRate() {
|
||||||
|
this.actionName = "CREATE";
|
||||||
|
this.entityName = "RATE";
|
||||||
|
this.entityId = null;
|
||||||
|
this.href = "/rates/template";
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandWrapperBuilder updateRate(final Long rateId) {
|
||||||
|
this.actionName = "UPDATE";
|
||||||
|
this.entityName = "RATE";
|
||||||
|
this.entityId = rateId;
|
||||||
|
this.href = "/rates/" + rateId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -92,4 +92,6 @@ public interface ConfigurationDomainService {
|
|||||||
Integer retrieveOTPCharacterLength();
|
Integer retrieveOTPCharacterLength();
|
||||||
|
|
||||||
Integer retrieveOTPLiveTime();
|
Integer retrieveOTPLiveTime();
|
||||||
|
|
||||||
|
boolean isSubRatesEnabled();
|
||||||
}
|
}
|
||||||
+11
@@ -332,4 +332,15 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
|
|||||||
}
|
}
|
||||||
return configurations.get(key);
|
return configurations.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSubRatesEnabled() {
|
||||||
|
GlobalConfigurationPropertyData configuration = getGlobalConfigurationPropertyData("sub-rates");
|
||||||
|
if (configuration==null){
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
return configuration.isEnabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -54,6 +54,7 @@ import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSer
|
|||||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionData;
|
import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionData;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.service.LoanChargePaidByReadPlatformService;
|
||||||
import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService;
|
import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService;
|
||||||
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
||||||
import org.apache.fineract.portfolio.paymenttype.service.PaymentTypeReadPlatformService;
|
import org.apache.fineract.portfolio.paymenttype.service.PaymentTypeReadPlatformService;
|
||||||
@@ -82,19 +83,21 @@ public class LoanTransactionsApiResource {
|
|||||||
private final DefaultToApiJsonSerializer<LoanTransactionData> toApiJsonSerializer;
|
private final DefaultToApiJsonSerializer<LoanTransactionData> toApiJsonSerializer;
|
||||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||||
private final PaymentTypeReadPlatformService paymentTypeReadPlatformService;
|
private final PaymentTypeReadPlatformService paymentTypeReadPlatformService;
|
||||||
|
private final LoanChargePaidByReadPlatformService loanChargePaidByReadPlatformService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanTransactionsApiResource(final PlatformSecurityContext context, final LoanReadPlatformService loanReadPlatformService,
|
public LoanTransactionsApiResource(final PlatformSecurityContext context, final LoanReadPlatformService loanReadPlatformService,
|
||||||
final ApiRequestParameterHelper apiRequestParameterHelper,
|
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||||
final DefaultToApiJsonSerializer<LoanTransactionData> toApiJsonSerializer,
|
final DefaultToApiJsonSerializer<LoanTransactionData> toApiJsonSerializer,
|
||||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
||||||
PaymentTypeReadPlatformService paymentTypeReadPlatformService) {
|
PaymentTypeReadPlatformService paymentTypeReadPlatformService, LoanChargePaidByReadPlatformService loanChargePaidByReadPlatformService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.loanReadPlatformService = loanReadPlatformService;
|
this.loanReadPlatformService = loanReadPlatformService;
|
||||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||||
this.paymentTypeReadPlatformService = paymentTypeReadPlatformService;
|
this.paymentTypeReadPlatformService = paymentTypeReadPlatformService;
|
||||||
|
this.loanChargePaidByReadPlatformService = loanChargePaidByReadPlatformService;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean is(final String commandParam, final String commandValue) {
|
private boolean is(final String commandParam, final String commandValue) {
|
||||||
@@ -170,6 +173,7 @@ public class LoanTransactionsApiResource {
|
|||||||
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
|
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
|
||||||
|
|
||||||
LoanTransactionData transactionData = this.loanReadPlatformService.retrieveLoanTransaction(loanId, transactionId);
|
LoanTransactionData transactionData = this.loanReadPlatformService.retrieveLoanTransaction(loanId, transactionId);
|
||||||
|
transactionData.setLoanChargePaidByList(this.loanChargePaidByReadPlatformService.getLoanChargesPaidByTransactionId(transactionId));
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
if (settings.isTemplate()) {
|
if (settings.isTemplate()) {
|
||||||
final Collection<PaymentTypeData> paymentTypeOptions = this.paymentTypeReadPlatformService.retrieveAllPaymentTypes();
|
final Collection<PaymentTypeData> paymentTypeOptions = this.paymentTypeReadPlatformService.retrieveAllPaymentTypes();
|
||||||
|
|||||||
+39
-24
@@ -64,6 +64,7 @@ import org.apache.fineract.infrastructure.bulkimport.service.BulkImportWorkbookP
|
|||||||
import org.apache.fineract.infrastructure.bulkimport.service.BulkImportWorkbookService;
|
import org.apache.fineract.infrastructure.bulkimport.service.BulkImportWorkbookService;
|
||||||
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
||||||
import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformService;
|
import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformService;
|
||||||
|
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||||
import org.apache.fineract.infrastructure.core.api.ApiParameterHelper;
|
import org.apache.fineract.infrastructure.core.api.ApiParameterHelper;
|
||||||
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
|
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
|
||||||
import org.apache.fineract.infrastructure.core.api.JsonQuery;
|
import org.apache.fineract.infrastructure.core.api.JsonQuery;
|
||||||
@@ -131,6 +132,8 @@ import org.apache.fineract.portfolio.loanproduct.service.LoanProductReadPlatform
|
|||||||
import org.apache.fineract.portfolio.note.data.NoteData;
|
import org.apache.fineract.portfolio.note.data.NoteData;
|
||||||
import org.apache.fineract.portfolio.note.domain.NoteType;
|
import org.apache.fineract.portfolio.note.domain.NoteType;
|
||||||
import org.apache.fineract.portfolio.note.service.NoteReadPlatformServiceImpl;
|
import org.apache.fineract.portfolio.note.service.NoteReadPlatformServiceImpl;
|
||||||
|
import org.apache.fineract.portfolio.rate.data.RateData;
|
||||||
|
import org.apache.fineract.portfolio.rate.service.RateReadService;
|
||||||
import org.apache.fineract.portfolio.savings.DepositAccountType;
|
import org.apache.fineract.portfolio.savings.DepositAccountType;
|
||||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountStatusType;
|
import org.apache.fineract.portfolio.savings.domain.SavingsAccountStatusType;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -259,7 +262,7 @@ public class LoansApiResource {
|
|||||||
"syncDisbursementWithMeeting", "loanCounter", "loanProductCounter", "notes", "accountLinkingOptions", "linkedAccount",
|
"syncDisbursementWithMeeting", "loanCounter", "loanProductCounter", "notes", "accountLinkingOptions", "linkedAccount",
|
||||||
"interestRateDifferential", "isFloatingInterestRate", "interestRatesPeriods", LoanApiConstants.canUseForTopup,
|
"interestRateDifferential", "isFloatingInterestRate", "interestRatesPeriods", LoanApiConstants.canUseForTopup,
|
||||||
LoanApiConstants.isTopup, LoanApiConstants.loanIdToClose, LoanApiConstants.topupAmount, LoanApiConstants.clientActiveLoanOptions,
|
LoanApiConstants.isTopup, LoanApiConstants.loanIdToClose, LoanApiConstants.topupAmount, LoanApiConstants.clientActiveLoanOptions,
|
||||||
LoanApiConstants.datatables));
|
LoanApiConstants.datatables, LoanProductConstants.ratesParamName));
|
||||||
|
|
||||||
private final Set<String> LOAN_APPROVAL_DATA_PARAMETERS = new HashSet<>(Arrays.asList("approvalDate", "approvalAmount"));
|
private final Set<String> LOAN_APPROVAL_DATA_PARAMETERS = new HashSet<>(Arrays.asList("approvalDate", "approvalAmount"));
|
||||||
private final String resourceNameForPermissions = "LOAN";
|
private final String resourceNameForPermissions = "LOAN";
|
||||||
@@ -291,30 +294,32 @@ public class LoansApiResource {
|
|||||||
private final EntityDatatableChecksReadService entityDatatableChecksReadService;
|
private final EntityDatatableChecksReadService entityDatatableChecksReadService;
|
||||||
private final BulkImportWorkbookService bulkImportWorkbookService;
|
private final BulkImportWorkbookService bulkImportWorkbookService;
|
||||||
private final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService;
|
private final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService;
|
||||||
|
private final RateReadService rateReadService;
|
||||||
|
private final ConfigurationDomainService configurationDomainService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoansApiResource(final PlatformSecurityContext context, final LoanReadPlatformService loanReadPlatformService,
|
public LoansApiResource(final PlatformSecurityContext context, final LoanReadPlatformService loanReadPlatformService,
|
||||||
final LoanProductReadPlatformService loanProductReadPlatformService,
|
final LoanProductReadPlatformService loanProductReadPlatformService,
|
||||||
final LoanDropdownReadPlatformService dropdownReadPlatformService, final FundReadPlatformService fundReadPlatformService,
|
final LoanDropdownReadPlatformService dropdownReadPlatformService, final FundReadPlatformService fundReadPlatformService,
|
||||||
final ChargeReadPlatformService chargeReadPlatformService, final LoanChargeReadPlatformService loanChargeReadPlatformService,
|
final ChargeReadPlatformService chargeReadPlatformService, final LoanChargeReadPlatformService loanChargeReadPlatformService,
|
||||||
final CollateralReadPlatformService loanCollateralReadPlatformService,
|
final CollateralReadPlatformService loanCollateralReadPlatformService,
|
||||||
final LoanScheduleCalculationPlatformService calculationPlatformService,
|
final LoanScheduleCalculationPlatformService calculationPlatformService,
|
||||||
final GuarantorReadPlatformService guarantorReadPlatformService,
|
final GuarantorReadPlatformService guarantorReadPlatformService,
|
||||||
final CodeValueReadPlatformService codeValueReadPlatformService, final GroupReadPlatformService groupReadPlatformService,
|
final CodeValueReadPlatformService codeValueReadPlatformService, final GroupReadPlatformService groupReadPlatformService,
|
||||||
final DefaultToApiJsonSerializer<LoanAccountData> toApiJsonSerializer,
|
final DefaultToApiJsonSerializer<LoanAccountData> toApiJsonSerializer,
|
||||||
final DefaultToApiJsonSerializer<LoanApprovalData> loanApprovalDataToApiJsonSerializer,
|
final DefaultToApiJsonSerializer<LoanApprovalData> loanApprovalDataToApiJsonSerializer,
|
||||||
final DefaultToApiJsonSerializer<LoanScheduleData> loanScheduleToApiJsonSerializer,
|
final DefaultToApiJsonSerializer<LoanScheduleData> loanScheduleToApiJsonSerializer,
|
||||||
final ApiRequestParameterHelper apiRequestParameterHelper, final FromJsonHelper fromJsonHelper,
|
final ApiRequestParameterHelper apiRequestParameterHelper, final FromJsonHelper fromJsonHelper,
|
||||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
||||||
final CalendarReadPlatformService calendarReadPlatformService, final NoteReadPlatformServiceImpl noteReadPlatformService,
|
final CalendarReadPlatformService calendarReadPlatformService, final NoteReadPlatformServiceImpl noteReadPlatformService,
|
||||||
final PortfolioAccountReadPlatformService portfolioAccountReadPlatformServiceImpl,
|
final PortfolioAccountReadPlatformService portfolioAccountReadPlatformServiceImpl,
|
||||||
final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService,
|
final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService,
|
||||||
final LoanScheduleHistoryReadPlatformService loanScheduleHistoryReadPlatformService,
|
final LoanScheduleHistoryReadPlatformService loanScheduleHistoryReadPlatformService,
|
||||||
final AccountDetailsReadPlatformService accountDetailsReadPlatformService,
|
final AccountDetailsReadPlatformService accountDetailsReadPlatformService,
|
||||||
final EntityDatatableChecksReadService entityDatatableChecksReadService,
|
final EntityDatatableChecksReadService entityDatatableChecksReadService,
|
||||||
final BulkImportWorkbookService bulkImportWorkbookService,
|
final BulkImportWorkbookService bulkImportWorkbookService,
|
||||||
final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService) {
|
final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService, final RateReadService rateReadService,
|
||||||
|
final ConfigurationDomainService configurationDomainService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.loanReadPlatformService = loanReadPlatformService;
|
this.loanReadPlatformService = loanReadPlatformService;
|
||||||
this.loanProductReadPlatformService = loanProductReadPlatformService;
|
this.loanProductReadPlatformService = loanProductReadPlatformService;
|
||||||
@@ -340,8 +345,10 @@ public class LoansApiResource {
|
|||||||
this.loanScheduleHistoryReadPlatformService = loanScheduleHistoryReadPlatformService;
|
this.loanScheduleHistoryReadPlatformService = loanScheduleHistoryReadPlatformService;
|
||||||
this.accountDetailsReadPlatformService = accountDetailsReadPlatformService;
|
this.accountDetailsReadPlatformService = accountDetailsReadPlatformService;
|
||||||
this.entityDatatableChecksReadService = entityDatatableChecksReadService;
|
this.entityDatatableChecksReadService = entityDatatableChecksReadService;
|
||||||
|
this.rateReadService = rateReadService;
|
||||||
this.bulkImportWorkbookService=bulkImportWorkbookService;
|
this.bulkImportWorkbookService=bulkImportWorkbookService;
|
||||||
this.bulkImportWorkbookPopulatorService=bulkImportWorkbookPopulatorService;
|
this.bulkImportWorkbookPopulatorService=bulkImportWorkbookPopulatorService;
|
||||||
|
this.configurationDomainService = configurationDomainService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -397,6 +404,7 @@ public class LoansApiResource {
|
|||||||
LoanAccountData newLoanAccount = null;
|
LoanAccountData newLoanAccount = null;
|
||||||
Long officeId = null;
|
Long officeId = null;
|
||||||
Collection<PortfolioAccountData> accountLinkingOptions = null;
|
Collection<PortfolioAccountData> accountLinkingOptions = null;
|
||||||
|
boolean isRatesEnabled = this.configurationDomainService.isSubRatesEnabled();
|
||||||
|
|
||||||
if (productId != null) {
|
if (productId != null) {
|
||||||
newLoanAccount = this.loanReadPlatformService.retrieveLoanProductDetailsTemplate(productId, clientId, groupId);
|
newLoanAccount = this.loanReadPlatformService.retrieveLoanProductDetailsTemplate(productId, clientId, groupId);
|
||||||
@@ -474,7 +482,7 @@ public class LoansApiResource {
|
|||||||
// add product options, allowed loan officers and calendar options
|
// add product options, allowed loan officers and calendar options
|
||||||
// (calendar options will be null in individual loan)
|
// (calendar options will be null in individual loan)
|
||||||
newLoanAccount = LoanAccountData.associationsAndTemplate(newLoanAccount, productOptions, allowedLoanOfficers, calendarOptions,
|
newLoanAccount = LoanAccountData.associationsAndTemplate(newLoanAccount, productOptions, allowedLoanOfficers, calendarOptions,
|
||||||
accountLinkingOptions);
|
accountLinkingOptions, isRatesEnabled);
|
||||||
}
|
}
|
||||||
final List<DatatableData> datatableTemplates = this.entityDatatableChecksReadService
|
final List<DatatableData> datatableTemplates = this.entityDatatableChecksReadService
|
||||||
.retrieveTemplates(StatusEnum.CREATE.getCode().longValue(), EntityTables.LOAN.getName(), productId);
|
.retrieveTemplates(StatusEnum.CREATE.getCode().longValue(), EntityTables.LOAN.getName(), productId);
|
||||||
@@ -736,13 +744,20 @@ public class LoansApiResource {
|
|||||||
|
|
||||||
paidInAdvanceTemplate = this.loanReadPlatformService.retrieveTotalPaidInAdvance(loanId);
|
paidInAdvanceTemplate = this.loanReadPlatformService.retrieveTotalPaidInAdvance(loanId);
|
||||||
|
|
||||||
|
//Get rates from Loan
|
||||||
|
boolean isRatesEnabled = this.configurationDomainService.isSubRatesEnabled();
|
||||||
|
List<RateData> rates = null;
|
||||||
|
if (isRatesEnabled){
|
||||||
|
rates = this.rateReadService.retrieveLoanRates(loanId);
|
||||||
|
}
|
||||||
|
|
||||||
final LoanAccountData loanAccount = LoanAccountData.associationsAndTemplate(loanBasicDetails, repaymentSchedule, loanRepayments,
|
final LoanAccountData loanAccount = LoanAccountData.associationsAndTemplate(loanBasicDetails, repaymentSchedule, loanRepayments,
|
||||||
charges, collateral, guarantors, meeting, productOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions,
|
charges, collateral, guarantors, meeting, productOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions,
|
||||||
repaymentFrequencyNthDayTypeOptions, repaymentFrequencyDayOfWeekTypeOptions, repaymentStrategyOptions,
|
repaymentFrequencyNthDayTypeOptions, repaymentFrequencyDayOfWeekTypeOptions, repaymentStrategyOptions,
|
||||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
||||||
fundOptions, chargeOptions, chargeTemplate, allowedLoanOfficers, loanPurposeOptions, loanCollateralOptions,
|
fundOptions, chargeOptions, chargeTemplate, allowedLoanOfficers, loanPurposeOptions, loanCollateralOptions,
|
||||||
calendarOptions, notes, accountLinkingOptions, linkedAccount, disbursementData, emiAmountVariations,
|
calendarOptions, notes, accountLinkingOptions, linkedAccount, disbursementData, emiAmountVariations,
|
||||||
overdueCharges, paidInAdvanceTemplate, interestRatesPeriods, clientActiveLoanOptions);
|
overdueCharges, paidInAdvanceTemplate, interestRatesPeriods, clientActiveLoanOptions, rates, isRatesEnabled);
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters(),
|
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters(),
|
||||||
mandatoryResponseParameters);
|
mandatoryResponseParameters);
|
||||||
|
|||||||
+53
-18
@@ -50,6 +50,7 @@ import org.apache.fineract.portfolio.loanproduct.data.TransactionProcessingStrat
|
|||||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
|
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
|
||||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductValueConditionType;
|
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductValueConditionType;
|
||||||
import org.apache.fineract.portfolio.note.data.NoteData;
|
import org.apache.fineract.portfolio.note.data.NoteData;
|
||||||
|
import org.apache.fineract.portfolio.rate.data.RateData;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
@@ -219,6 +220,10 @@ public class LoanAccountData {
|
|||||||
private List<DatatableData> datatables = null;
|
private List<DatatableData> datatables = null;
|
||||||
private final Boolean isEqualAmortization;
|
private final Boolean isEqualAmortization;
|
||||||
|
|
||||||
|
//Rate
|
||||||
|
private final List<RateData> rates;
|
||||||
|
private final Boolean isRatesEnabled;
|
||||||
|
|
||||||
//import fields
|
//import fields
|
||||||
private String dateFormat;
|
private String dateFormat;
|
||||||
private String locale;
|
private String locale;
|
||||||
@@ -311,6 +316,7 @@ public class LoanAccountData {
|
|||||||
this.groupId=groupId;
|
this.groupId=groupId;
|
||||||
this.expectedDisbursementDate=expectedDisbursementDate;
|
this.expectedDisbursementDate=expectedDisbursementDate;
|
||||||
this.charges = charges;
|
this.charges = charges;
|
||||||
|
this.rates=null;
|
||||||
this.id = null;
|
this.id = null;
|
||||||
this.accountNo = null;
|
this.accountNo = null;
|
||||||
|
|
||||||
@@ -418,6 +424,7 @@ public class LoanAccountData {
|
|||||||
this.minimumGap = null;
|
this.minimumGap = null;
|
||||||
this.maximumGap = null;
|
this.maximumGap = null;
|
||||||
this.isEqualAmortization = null;
|
this.isEqualAmortization = null;
|
||||||
|
this.isRatesEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -580,6 +587,9 @@ public class LoanAccountData {
|
|||||||
final String closureLoanAccountNo = null;
|
final String closureLoanAccountNo = null;
|
||||||
final BigDecimal topupAmount = null;
|
final BigDecimal topupAmount = null;
|
||||||
final boolean isEqualAmortization = false;
|
final boolean isEqualAmortization = false;
|
||||||
|
final List<RateData> rates = null;
|
||||||
|
final Boolean isRatesEnabled = false;
|
||||||
|
|
||||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
|
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
|
||||||
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName,
|
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName,
|
||||||
loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, currencyData, proposedPrincipal, principal, principal,
|
loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, currencyData, proposedPrincipal, principal, principal,
|
||||||
@@ -598,7 +608,7 @@ public class LoanAccountData {
|
|||||||
maxOutstandingLoanBalance, emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges,
|
maxOutstandingLoanBalance, emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges,
|
||||||
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
||||||
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
||||||
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization);
|
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization, rates, isRatesEnabled);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -720,6 +730,9 @@ public class LoanAccountData {
|
|||||||
final String closureLoanAccountNo = null;
|
final String closureLoanAccountNo = null;
|
||||||
final BigDecimal topupAmount = null;
|
final BigDecimal topupAmount = null;
|
||||||
final boolean isEqualAmortization = false;
|
final boolean isEqualAmortization = false;
|
||||||
|
final List<RateData> rates = null;
|
||||||
|
final Boolean isRatesEnabled = false;
|
||||||
|
|
||||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
|
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
|
||||||
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName,
|
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName,
|
||||||
loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, currencyData, proposedPrincipal, principal, principal,
|
loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, currencyData, proposedPrincipal, principal, principal,
|
||||||
@@ -738,7 +751,8 @@ public class LoanAccountData {
|
|||||||
maxOutstandingLoanBalance, emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges,
|
maxOutstandingLoanBalance, emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges,
|
||||||
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
||||||
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
||||||
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization);
|
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization,
|
||||||
|
rates, isRatesEnabled);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -768,7 +782,8 @@ public class LoanAccountData {
|
|||||||
acc.isInterestRecalculationEnabled, acc.interestRecalculationData, acc.originalSchedule,
|
acc.isInterestRecalculationEnabled, acc.interestRecalculationData, acc.originalSchedule,
|
||||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods,
|
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods,
|
||||||
acc.isVariableInstallmentsAllowed, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup,
|
acc.isVariableInstallmentsAllowed, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup,
|
||||||
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization);
|
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization,
|
||||||
|
acc.rates, acc.isRatesEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -891,6 +906,9 @@ public class LoanAccountData {
|
|||||||
final String closureLoanAccountNo = null;
|
final String closureLoanAccountNo = null;
|
||||||
final BigDecimal topupAmount = null;
|
final BigDecimal topupAmount = null;
|
||||||
final boolean isEqualAmortization = false;
|
final boolean isEqualAmortization = false;
|
||||||
|
final List<RateData> rates = null;
|
||||||
|
final Boolean isRatesEnabled = false;
|
||||||
|
|
||||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
|
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
|
||||||
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName,
|
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName,
|
||||||
loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, currencyData, proposedPrincipal, principal, principal,
|
loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, currencyData, proposedPrincipal, principal, principal,
|
||||||
@@ -909,7 +927,8 @@ public class LoanAccountData {
|
|||||||
maxOutstandingBalance, emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges,
|
maxOutstandingBalance, emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges,
|
||||||
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
||||||
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
||||||
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization);
|
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization,
|
||||||
|
rates, isRatesEnabled);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -939,7 +958,8 @@ public class LoanAccountData {
|
|||||||
acc.isInterestRecalculationEnabled, acc.interestRecalculationData, acc.originalSchedule,
|
acc.isInterestRecalculationEnabled, acc.interestRecalculationData, acc.originalSchedule,
|
||||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods,
|
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods,
|
||||||
acc.isVariableInstallmentsAllowed, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup,
|
acc.isVariableInstallmentsAllowed, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup,
|
||||||
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization);
|
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization,
|
||||||
|
acc.rates, acc.isRatesEnabled);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1069,6 +1089,9 @@ public class LoanAccountData {
|
|||||||
final Long closureLoanId = null;
|
final Long closureLoanId = null;
|
||||||
final String closureLoanAccountNo = null;
|
final String closureLoanAccountNo = null;
|
||||||
final BigDecimal topupAmount = null;
|
final BigDecimal topupAmount = null;
|
||||||
|
final List<RateData> rates = null;
|
||||||
|
final Boolean isRatesEnabled = false;
|
||||||
|
|
||||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
|
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
|
||||||
loanType, product.getId(), product.getName(), product.getDescription(), product.isLinkedToFloatingInterestRates(),
|
loanType, product.getId(), product.getName(), product.getDescription(), product.isLinkedToFloatingInterestRates(),
|
||||||
product.getFundId(), product.getFundName(), loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
product.getFundId(), product.getFundName(), loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
||||||
@@ -1093,7 +1116,7 @@ public class LoanAccountData {
|
|||||||
originalSchedule, createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods,
|
originalSchedule, createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods,
|
||||||
product.isVariableInstallmentsAllowed(), product.getMinimumGapBetweenInstallments(),
|
product.isVariableInstallmentsAllowed(), product.getMinimumGapBetweenInstallments(),
|
||||||
product.getMaximumGapBetweenInstallments(), subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId,
|
product.getMaximumGapBetweenInstallments(), subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId,
|
||||||
closureLoanAccountNo, topupAmount, product.isEqualAmortization());
|
closureLoanAccountNo, topupAmount, product.isEqualAmortization(),rates, isRatesEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData populateLoanProductDefaults(final LoanAccountData acc, final LoanProductData product) {
|
public static LoanAccountData populateLoanProductDefaults(final LoanAccountData acc, final LoanProductData product) {
|
||||||
@@ -1153,7 +1176,8 @@ public class LoanAccountData {
|
|||||||
product.toLoanInterestRecalculationData(), acc.originalSchedule, acc.createStandingInstructionAtDisbursement,
|
product.toLoanInterestRecalculationData(), acc.originalSchedule, acc.createStandingInstructionAtDisbursement,
|
||||||
paidInAdvance, acc.interestRatesPeriods, product.isVariableInstallmentsAllowed(),
|
paidInAdvance, acc.interestRatesPeriods, product.isVariableInstallmentsAllowed(),
|
||||||
product.getMinimumGapBetweenInstallments(), product.getMaximumGapBetweenInstallments(), acc.subStatus, acc.canUseForTopup,
|
product.getMinimumGapBetweenInstallments(), product.getMaximumGapBetweenInstallments(), acc.subStatus, acc.canUseForTopup,
|
||||||
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, product.isEqualAmortization());
|
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, product.isEqualAmortization(), acc.rates,
|
||||||
|
acc.isRatesEnabled);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1222,6 +1246,8 @@ public class LoanAccountData {
|
|||||||
final PaidInAdvanceData paidInAdvance = null;
|
final PaidInAdvanceData paidInAdvance = null;
|
||||||
final Collection<InterestRatePeriodData> interestRatesPeriods = null;
|
final Collection<InterestRatePeriodData> interestRatesPeriods = null;
|
||||||
final Collection<LoanAccountSummaryData> clientActiveLoanOptions = null;
|
final Collection<LoanAccountSummaryData> clientActiveLoanOptions = null;
|
||||||
|
final List<RateData> rates = null;
|
||||||
|
final Boolean isRatesEnabled = false;
|
||||||
|
|
||||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
|
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
|
||||||
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName,
|
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName,
|
||||||
@@ -1241,7 +1267,8 @@ public class LoanAccountData {
|
|||||||
outstandingLoanBalance, emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges,
|
outstandingLoanBalance, emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges,
|
||||||
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
||||||
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
||||||
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization);
|
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization,
|
||||||
|
rates, isRatesEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1265,7 +1292,7 @@ public class LoanAccountData {
|
|||||||
final PortfolioAccountData linkedAccount, final Collection<DisbursementData> disbursementDetails,
|
final PortfolioAccountData linkedAccount, final Collection<DisbursementData> disbursementDetails,
|
||||||
final Collection<LoanTermVariationsData> emiAmountVariations, final Collection<ChargeData> overdueCharges,
|
final Collection<LoanTermVariationsData> emiAmountVariations, final Collection<ChargeData> overdueCharges,
|
||||||
final PaidInAdvanceData paidInAdvance, Collection<InterestRatePeriodData> interestRatesPeriods,
|
final PaidInAdvanceData paidInAdvance, Collection<InterestRatePeriodData> interestRatesPeriods,
|
||||||
final Collection<LoanAccountSummaryData> clientActiveLoanOptions) {
|
final Collection<LoanAccountSummaryData> clientActiveLoanOptions,final List<RateData> rates, final Boolean isRatesEnabled) {
|
||||||
LoanProductConfigurableAttributes loanProductConfigurableAttributes = null;
|
LoanProductConfigurableAttributes loanProductConfigurableAttributes = null;
|
||||||
if (acc.product != null) {
|
if (acc.product != null) {
|
||||||
loanProductConfigurableAttributes = acc.product.getloanProductConfigurableAttributes();
|
loanProductConfigurableAttributes = acc.product.getloanProductConfigurableAttributes();
|
||||||
@@ -1294,12 +1321,12 @@ public class LoanAccountData {
|
|||||||
acc.isInterestRecalculationEnabled, acc.interestRecalculationData, acc.originalSchedule,
|
acc.isInterestRecalculationEnabled, acc.interestRecalculationData, acc.originalSchedule,
|
||||||
acc.createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
acc.createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
||||||
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, clientActiveLoanOptions, acc.isTopup,
|
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, clientActiveLoanOptions, acc.isTopup,
|
||||||
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization);
|
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, rates, isRatesEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData associationsAndTemplate(final LoanAccountData acc, final Collection<LoanProductData> productOptions,
|
public static LoanAccountData associationsAndTemplate(final LoanAccountData acc, final Collection<LoanProductData> productOptions,
|
||||||
final Collection<StaffData> allowedLoanOfficers, final Collection<CalendarData> calendarOptions,
|
final Collection<StaffData> allowedLoanOfficers, final Collection<CalendarData> calendarOptions,
|
||||||
final Collection<PortfolioAccountData> accountLinkingOptions) {
|
final Collection<PortfolioAccountData> accountLinkingOptions, final Boolean isRatesEnabled) {
|
||||||
return associationsAndTemplate(acc, acc.repaymentSchedule, acc.transactions, acc.charges, acc.collateral, acc.guarantors,
|
return associationsAndTemplate(acc, acc.repaymentSchedule, acc.transactions, acc.charges, acc.collateral, acc.guarantors,
|
||||||
acc.meeting, productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions,
|
acc.meeting, productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions,
|
||||||
acc.repaymentFrequencyNthDayTypeOptions, acc.repaymentFrequencyDaysOfWeekTypeOptions,
|
acc.repaymentFrequencyNthDayTypeOptions, acc.repaymentFrequencyDaysOfWeekTypeOptions,
|
||||||
@@ -1307,7 +1334,7 @@ public class LoanAccountData {
|
|||||||
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
|
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
|
||||||
allowedLoanOfficers, acc.loanPurposeOptions, acc.loanCollateralOptions, calendarOptions, acc.notes, accountLinkingOptions,
|
allowedLoanOfficers, acc.loanPurposeOptions, acc.loanCollateralOptions, calendarOptions, acc.notes, accountLinkingOptions,
|
||||||
acc.linkedAccount, acc.disbursementDetails, acc.emiAmountVariations, acc.overdueCharges, acc.paidInAdvance,
|
acc.linkedAccount, acc.disbursementDetails, acc.emiAmountVariations, acc.overdueCharges, acc.paidInAdvance,
|
||||||
acc.interestRatesPeriods, acc.clientActiveLoanOptions);
|
acc.interestRatesPeriods, acc.clientActiveLoanOptions,acc.rates, isRatesEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData associateGroup(final LoanAccountData acc, final GroupGeneralData group) {
|
public static LoanAccountData associateGroup(final LoanAccountData acc, final GroupGeneralData group) {
|
||||||
@@ -1336,7 +1363,8 @@ public class LoanAccountData {
|
|||||||
acc.isInterestRecalculationEnabled, acc.interestRecalculationData, acc.originalSchedule,
|
acc.isInterestRecalculationEnabled, acc.interestRecalculationData, acc.originalSchedule,
|
||||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods,
|
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods,
|
||||||
acc.isVariableInstallmentsAllowed, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup,
|
acc.isVariableInstallmentsAllowed, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup,
|
||||||
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization);
|
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates,
|
||||||
|
acc.isRatesEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData associateMemberVariations(final LoanAccountData acc, final Map<Long, Integer> memberLoanCycle) {
|
public static LoanAccountData associateMemberVariations(final LoanAccountData acc, final Map<Long, Integer> memberLoanCycle) {
|
||||||
@@ -1401,7 +1429,8 @@ public class LoanAccountData {
|
|||||||
acc.isInterestRecalculationEnabled, acc.interestRecalculationData, acc.originalSchedule,
|
acc.isInterestRecalculationEnabled, acc.interestRecalculationData, acc.originalSchedule,
|
||||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods,
|
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods,
|
||||||
acc.isVariableInstallmentsAllowed, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup,
|
acc.isVariableInstallmentsAllowed, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup,
|
||||||
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization);
|
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates,
|
||||||
|
acc.isRatesEnabled);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1435,7 +1464,8 @@ public class LoanAccountData {
|
|||||||
acc.isInterestRecalculationEnabled, interestRecalculationData, acc.originalSchedule,
|
acc.isInterestRecalculationEnabled, interestRecalculationData, acc.originalSchedule,
|
||||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods,
|
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods,
|
||||||
acc.isVariableInstallmentsAllowed, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup,
|
acc.isVariableInstallmentsAllowed, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup,
|
||||||
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization);
|
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates,
|
||||||
|
acc.isRatesEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData withLoanCalendarData(final LoanAccountData acc, final CalendarData calendarData) {
|
public static LoanAccountData withLoanCalendarData(final LoanAccountData acc, final CalendarData calendarData) {
|
||||||
@@ -1463,7 +1493,8 @@ public class LoanAccountData {
|
|||||||
acc.isNPA, acc.daysInMonthType, acc.daysInYearType, acc.isInterestRecalculationEnabled, acc.interestRecalculationData,
|
acc.isNPA, acc.daysInMonthType, acc.daysInYearType, acc.isInterestRecalculationEnabled, acc.interestRecalculationData,
|
||||||
acc.originalSchedule, acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods,
|
acc.originalSchedule, acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods,
|
||||||
acc.isVariableInstallmentsAllowed, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup,
|
acc.isVariableInstallmentsAllowed, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup,
|
||||||
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization);
|
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization,
|
||||||
|
acc.rates, acc.isRatesEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData withOriginalSchedule(final LoanAccountData acc, final LoanScheduleData originalSchedule) {
|
public static LoanAccountData withOriginalSchedule(final LoanAccountData acc, final LoanScheduleData originalSchedule) {
|
||||||
@@ -1492,7 +1523,8 @@ public class LoanAccountData {
|
|||||||
acc.isInterestRecalculationEnabled, acc.interestRecalculationData, originalSchedule,
|
acc.isInterestRecalculationEnabled, acc.interestRecalculationData, originalSchedule,
|
||||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods,
|
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods,
|
||||||
acc.isVariableInstallmentsAllowed, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup,
|
acc.isVariableInstallmentsAllowed, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup,
|
||||||
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization);
|
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization,
|
||||||
|
acc.rates, acc.isRatesEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanAccountData(final Long id, //
|
private LoanAccountData(final Long id, //
|
||||||
@@ -1542,7 +1574,8 @@ public class LoanAccountData {
|
|||||||
final Collection<InterestRatePeriodData> interestRatesPeriods, final Boolean isVariableInstallmentsAllowed,
|
final Collection<InterestRatePeriodData> interestRatesPeriods, final Boolean isVariableInstallmentsAllowed,
|
||||||
final Integer minimumGap, final Integer maximumGap, final EnumOptionData subStatus, final Boolean canUseForTopup,
|
final Integer minimumGap, final Integer maximumGap, final EnumOptionData subStatus, final Boolean canUseForTopup,
|
||||||
final Collection<LoanAccountSummaryData> clientActiveLoanOptions, final boolean isTopup,
|
final Collection<LoanAccountSummaryData> clientActiveLoanOptions, final boolean isTopup,
|
||||||
final Long closureLoanId, final String closureLoanAccountNo, final BigDecimal topupAmount, final boolean isEqualAmortization) {
|
final Long closureLoanId, final String closureLoanAccountNo, final BigDecimal topupAmount, final boolean isEqualAmortization,
|
||||||
|
final List<RateData> rates, final Boolean isRatesEnabled) {
|
||||||
|
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.accountNo = accountNo;
|
this.accountNo = accountNo;
|
||||||
@@ -1622,6 +1655,7 @@ public class LoanAccountData {
|
|||||||
this.amortizationTypeOptions = amortizationTypeOptions;
|
this.amortizationTypeOptions = amortizationTypeOptions;
|
||||||
this.interestTypeOptions = interestTypeOptions;
|
this.interestTypeOptions = interestTypeOptions;
|
||||||
this.interestCalculationPeriodTypeOptions = interestCalculationPeriodTypeOptions;
|
this.interestCalculationPeriodTypeOptions = interestCalculationPeriodTypeOptions;
|
||||||
|
this.isRatesEnabled = isRatesEnabled;
|
||||||
|
|
||||||
if (CollectionUtils.isEmpty(transactionProcessingStrategyOptions)) {
|
if (CollectionUtils.isEmpty(transactionProcessingStrategyOptions)) {
|
||||||
this.transactionProcessingStrategyOptions = null;
|
this.transactionProcessingStrategyOptions = null;
|
||||||
@@ -1725,6 +1759,7 @@ public class LoanAccountData {
|
|||||||
this.closureLoanAccountNo = closureLoanAccountNo;
|
this.closureLoanAccountNo = closureLoanAccountNo;
|
||||||
this.topupAmount = topupAmount;
|
this.topupAmount = topupAmount;
|
||||||
this.isEqualAmortization = isEqualAmortization;
|
this.isEqualAmortization = isEqualAmortization;
|
||||||
|
this.rates = rates;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
@@ -27,6 +27,17 @@ public class LoanChargePaidByData {
|
|||||||
private final Integer installmentNumber;
|
private final Integer installmentNumber;
|
||||||
private final Long chargeId;
|
private final Long chargeId;
|
||||||
private final Long transactionId;
|
private final Long transactionId;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public LoanChargePaidByData(final Long id, final BigDecimal amount, final Integer installmentNumber, final Long chargeId,
|
||||||
|
final Long transactionId, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.amount = amount;
|
||||||
|
this.installmentNumber = installmentNumber;
|
||||||
|
this.chargeId = chargeId;
|
||||||
|
this.transactionId = transactionId;
|
||||||
|
this.name=name;
|
||||||
|
}
|
||||||
|
|
||||||
public LoanChargePaidByData(final Long id, final BigDecimal amount, final Integer installmentNumber, final Long chargeId,
|
public LoanChargePaidByData(final Long id, final BigDecimal amount, final Integer installmentNumber, final Long chargeId,
|
||||||
final Long transactionId) {
|
final Long transactionId) {
|
||||||
@@ -35,6 +46,7 @@ public class LoanChargePaidByData {
|
|||||||
this.installmentNumber = installmentNumber;
|
this.installmentNumber = installmentNumber;
|
||||||
this.chargeId = chargeId;
|
this.chargeId = chargeId;
|
||||||
this.transactionId = transactionId;
|
this.transactionId = transactionId;
|
||||||
|
this.name=null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
@@ -57,4 +69,7 @@ public class LoanChargePaidByData {
|
|||||||
return this.transactionId;
|
return this.transactionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -59,6 +59,8 @@ public class LoanTransactionData {
|
|||||||
private final boolean manuallyReversed;
|
private final boolean manuallyReversed;
|
||||||
private final LocalDate possibleNextRepaymentDate;
|
private final LocalDate possibleNextRepaymentDate;
|
||||||
|
|
||||||
|
private Collection<LoanChargePaidByData> loanChargePaidByList;
|
||||||
|
|
||||||
// templates
|
// templates
|
||||||
final Collection<PaymentTypeData> paymentTypeOptions;
|
final Collection<PaymentTypeData> paymentTypeOptions;
|
||||||
|
|
||||||
@@ -339,4 +341,12 @@ public class LoanTransactionData {
|
|||||||
public void setWriteOffReasonOptions(Collection<CodeValueData> writeOffReasonOptions){
|
public void setWriteOffReasonOptions(Collection<CodeValueData> writeOffReasonOptions){
|
||||||
this.writeOffReasonOptions =writeOffReasonOptions;
|
this.writeOffReasonOptions =writeOffReasonOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collection<LoanChargePaidByData> getLoanChargePaidByList() {
|
||||||
|
return loanChargePaidByList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLoanChargePaidByList(Collection<LoanChargePaidByData> loanChargePaidByList) {
|
||||||
|
this.loanChargePaidByList = loanChargePaidByList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+31
-7
@@ -133,6 +133,7 @@ import org.apache.fineract.portfolio.loanproduct.domain.LoanTransactionProcessin
|
|||||||
import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType;
|
import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType;
|
||||||
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
|
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
|
||||||
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
|
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
|
||||||
|
import org.apache.fineract.portfolio.rate.domain.Rate;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
import org.joda.time.Days;
|
import org.joda.time.Days;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
@@ -388,20 +389,24 @@ public class Loan extends AbstractPersistableCustom<Long> {
|
|||||||
@OneToOne(cascade = CascadeType.ALL, mappedBy = "loan", optional = true, orphanRemoval = true, fetch=FetchType.EAGER)
|
@OneToOne(cascade = CascadeType.ALL, mappedBy = "loan", optional = true, orphanRemoval = true, fetch=FetchType.EAGER)
|
||||||
private LoanTopupDetails loanTopupDetails;
|
private LoanTopupDetails loanTopupDetails;
|
||||||
|
|
||||||
|
@OneToMany(fetch = FetchType.LAZY)
|
||||||
|
@JoinTable(name = "m_loan_rate", joinColumns = @JoinColumn(name = "loan_id"), inverseJoinColumns = @JoinColumn(name = "rate_id"))
|
||||||
|
private List<Rate> rates;
|
||||||
|
|
||||||
public static Loan newIndividualLoanApplication(final String accountNo, final Client client, final Integer loanType,
|
public static Loan newIndividualLoanApplication(final String accountNo, final Client client, final Integer loanType,
|
||||||
final LoanProduct loanProduct, final Fund fund, final Staff officer, final CodeValue loanPurpose,
|
final LoanProduct loanProduct, final Fund fund, final Staff officer, final CodeValue loanPurpose,
|
||||||
final LoanTransactionProcessingStrategy transactionProcessingStrategy,
|
final LoanTransactionProcessingStrategy transactionProcessingStrategy,
|
||||||
final LoanProductRelatedDetail loanRepaymentScheduleDetail, final Set<LoanCharge> loanCharges,
|
final LoanProductRelatedDetail loanRepaymentScheduleDetail, final Set<LoanCharge> loanCharges,
|
||||||
final Set<LoanCollateral> collateral, final BigDecimal fixedEmiAmount, final List<LoanDisbursementDetails> disbursementDetails,
|
final Set<LoanCollateral> collateral, final BigDecimal fixedEmiAmount, final List<LoanDisbursementDetails> disbursementDetails,
|
||||||
final BigDecimal maxOutstandingLoanBalance, final Boolean createStandingInstructionAtDisbursement,
|
final BigDecimal maxOutstandingLoanBalance, final Boolean createStandingInstructionAtDisbursement,
|
||||||
final Boolean isFloatingInterestRate, final BigDecimal interestRateDifferential) {
|
final Boolean isFloatingInterestRate, final BigDecimal interestRateDifferential, final List<Rate> rates) {
|
||||||
final LoanStatus status = null;
|
final LoanStatus status = null;
|
||||||
final Group group = null;
|
final Group group = null;
|
||||||
final Boolean syncDisbursementWithMeeting = null;
|
final Boolean syncDisbursementWithMeeting = null;
|
||||||
return new Loan(accountNo, client, group, loanType, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
|
return new Loan(accountNo, client, group, loanType, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
|
||||||
loanRepaymentScheduleDetail, status, loanCharges, collateral, syncDisbursementWithMeeting, fixedEmiAmount,
|
loanRepaymentScheduleDetail, status, loanCharges, collateral, syncDisbursementWithMeeting, fixedEmiAmount,
|
||||||
disbursementDetails, maxOutstandingLoanBalance, createStandingInstructionAtDisbursement, isFloatingInterestRate,
|
disbursementDetails, maxOutstandingLoanBalance, createStandingInstructionAtDisbursement, isFloatingInterestRate,
|
||||||
interestRateDifferential);
|
interestRateDifferential, rates);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Loan newGroupLoanApplication(final String accountNo, final Group group, final Integer loanType,
|
public static Loan newGroupLoanApplication(final String accountNo, final Group group, final Integer loanType,
|
||||||
@@ -411,13 +416,13 @@ public class Loan extends AbstractPersistableCustom<Long> {
|
|||||||
final Set<LoanCollateral> collateral, final Boolean syncDisbursementWithMeeting, final BigDecimal fixedEmiAmount,
|
final Set<LoanCollateral> collateral, final Boolean syncDisbursementWithMeeting, final BigDecimal fixedEmiAmount,
|
||||||
final List<LoanDisbursementDetails> disbursementDetails, final BigDecimal maxOutstandingLoanBalance,
|
final List<LoanDisbursementDetails> disbursementDetails, final BigDecimal maxOutstandingLoanBalance,
|
||||||
final Boolean createStandingInstructionAtDisbursement, final Boolean isFloatingInterestRate,
|
final Boolean createStandingInstructionAtDisbursement, final Boolean isFloatingInterestRate,
|
||||||
final BigDecimal interestRateDifferential) {
|
final BigDecimal interestRateDifferential, final List<Rate> rates) {
|
||||||
final LoanStatus status = null;
|
final LoanStatus status = null;
|
||||||
final Client client = null;
|
final Client client = null;
|
||||||
return new Loan(accountNo, client, group, loanType, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
|
return new Loan(accountNo, client, group, loanType, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
|
||||||
loanRepaymentScheduleDetail, status, loanCharges, collateral, syncDisbursementWithMeeting, fixedEmiAmount,
|
loanRepaymentScheduleDetail, status, loanCharges, collateral, syncDisbursementWithMeeting, fixedEmiAmount,
|
||||||
disbursementDetails, maxOutstandingLoanBalance, createStandingInstructionAtDisbursement, isFloatingInterestRate,
|
disbursementDetails, maxOutstandingLoanBalance, createStandingInstructionAtDisbursement, isFloatingInterestRate,
|
||||||
interestRateDifferential);
|
interestRateDifferential, rates);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Loan newIndividualLoanApplicationFromGroup(final String accountNo, final Client client, final Group group,
|
public static Loan newIndividualLoanApplicationFromGroup(final String accountNo, final Client client, final Group group,
|
||||||
@@ -427,12 +432,12 @@ public class Loan extends AbstractPersistableCustom<Long> {
|
|||||||
final Set<LoanCollateral> collateral, final Boolean syncDisbursementWithMeeting, final BigDecimal fixedEmiAmount,
|
final Set<LoanCollateral> collateral, final Boolean syncDisbursementWithMeeting, final BigDecimal fixedEmiAmount,
|
||||||
final List<LoanDisbursementDetails> disbursementDetails, final BigDecimal maxOutstandingLoanBalance,
|
final List<LoanDisbursementDetails> disbursementDetails, final BigDecimal maxOutstandingLoanBalance,
|
||||||
final Boolean createStandingInstructionAtDisbursement, final Boolean isFloatingInterestRate,
|
final Boolean createStandingInstructionAtDisbursement, final Boolean isFloatingInterestRate,
|
||||||
final BigDecimal interestRateDifferential) {
|
final BigDecimal interestRateDifferential, final List<Rate> rates) {
|
||||||
final LoanStatus status = null;
|
final LoanStatus status = null;
|
||||||
return new Loan(accountNo, client, group, loanType, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
|
return new Loan(accountNo, client, group, loanType, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
|
||||||
loanRepaymentScheduleDetail, status, loanCharges, collateral, syncDisbursementWithMeeting, fixedEmiAmount,
|
loanRepaymentScheduleDetail, status, loanCharges, collateral, syncDisbursementWithMeeting, fixedEmiAmount,
|
||||||
disbursementDetails, maxOutstandingLoanBalance, createStandingInstructionAtDisbursement, isFloatingInterestRate,
|
disbursementDetails, maxOutstandingLoanBalance, createStandingInstructionAtDisbursement, isFloatingInterestRate,
|
||||||
interestRateDifferential);
|
interestRateDifferential,rates);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Loan() {
|
protected Loan() {
|
||||||
@@ -445,7 +450,7 @@ public class Loan extends AbstractPersistableCustom<Long> {
|
|||||||
final Set<LoanCharge> loanCharges, final Set<LoanCollateral> collateral, final Boolean syncDisbursementWithMeeting,
|
final Set<LoanCharge> loanCharges, final Set<LoanCollateral> collateral, final Boolean syncDisbursementWithMeeting,
|
||||||
final BigDecimal fixedEmiAmount, final List<LoanDisbursementDetails> disbursementDetails,
|
final BigDecimal fixedEmiAmount, final List<LoanDisbursementDetails> disbursementDetails,
|
||||||
final BigDecimal maxOutstandingLoanBalance, final Boolean createStandingInstructionAtDisbursement,
|
final BigDecimal maxOutstandingLoanBalance, final Boolean createStandingInstructionAtDisbursement,
|
||||||
final Boolean isFloatingInterestRate, final BigDecimal interestRateDifferential) {
|
final Boolean isFloatingInterestRate, final BigDecimal interestRateDifferential, final List<Rate> rates) {
|
||||||
|
|
||||||
this.loanRepaymentScheduleDetail = loanRepaymentScheduleDetail;
|
this.loanRepaymentScheduleDetail = loanRepaymentScheduleDetail;
|
||||||
this.loanRepaymentScheduleDetail.validateRepaymentPeriodWithGraceSettings();
|
this.loanRepaymentScheduleDetail.validateRepaymentPeriodWithGraceSettings();
|
||||||
@@ -503,6 +508,9 @@ public class Loan extends AbstractPersistableCustom<Long> {
|
|||||||
|
|
||||||
this.proposedPrincipal = this.loanRepaymentScheduleDetail.getPrincipal().getAmount();
|
this.proposedPrincipal = this.loanRepaymentScheduleDetail.getPrincipal().getAmount();
|
||||||
|
|
||||||
|
//rates added here
|
||||||
|
this.rates = rates;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanSummary updateSummaryWithTotalFeeChargesDueAtDisbursement(final BigDecimal feeChargesDueAtDisbursement) {
|
private LoanSummary updateSummaryWithTotalFeeChargesDueAtDisbursement(final BigDecimal feeChargesDueAtDisbursement) {
|
||||||
@@ -1166,6 +1174,14 @@ public class Loan extends AbstractPersistableCustom<Long> {
|
|||||||
this.collateral.addAll(associateWithThisLoan(loanCollateral));
|
this.collateral.addAll(associateWithThisLoan(loanCollateral));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateLoanRates(final List<Rate> loanRates) {
|
||||||
|
if (this.rates == null) {
|
||||||
|
this.rates = new ArrayList<>();
|
||||||
|
}
|
||||||
|
this.rates.clear();
|
||||||
|
this.rates.addAll(loanRates);
|
||||||
|
}
|
||||||
|
|
||||||
public void updateLoanSchedule(final LoanScheduleModel modifiedLoanSchedule, AppUser currentUser) {
|
public void updateLoanSchedule(final LoanScheduleModel modifiedLoanSchedule, AppUser currentUser) {
|
||||||
this.repaymentScheduleInstallments.clear();
|
this.repaymentScheduleInstallments.clear();
|
||||||
for (final LoanScheduleModelPeriod scheduledLoanInstallment : modifiedLoanSchedule.getPeriods()) {
|
for (final LoanScheduleModelPeriod scheduledLoanInstallment : modifiedLoanSchedule.getPeriods()) {
|
||||||
@@ -6533,4 +6549,12 @@ public class Loan extends AbstractPersistableCustom<Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isIndividualLoan(){return AccountType.fromInt(this.loanType).isIndividualAccount();}
|
public boolean isIndividualLoan(){return AccountType.fromInt(this.loanType).isIndividualAccount();}
|
||||||
|
|
||||||
|
public void setRates(List<Rate> rates) {
|
||||||
|
this.rates = rates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Rate> getRates() {
|
||||||
|
return rates;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -67,7 +67,8 @@ public final class CalculateLoanScheduleQueryFromApiJsonHelper {
|
|||||||
LoanProductConstants.graceOnArrearsAgeingParameterName, LoanApiConstants.createStandingInstructionAtDisbursementParameterName,
|
LoanProductConstants.graceOnArrearsAgeingParameterName, LoanApiConstants.createStandingInstructionAtDisbursementParameterName,
|
||||||
LoanApiConstants.isFloatingInterestRateParameterName, LoanApiConstants.interestRateDifferentialParameterName,
|
LoanApiConstants.isFloatingInterestRateParameterName, LoanApiConstants.interestRateDifferentialParameterName,
|
||||||
LoanApiConstants.repaymentFrequencyNthDayTypeParameterName, LoanApiConstants.repaymentFrequencyDayOfWeekTypeParameterName,
|
LoanApiConstants.repaymentFrequencyNthDayTypeParameterName, LoanApiConstants.repaymentFrequencyDayOfWeekTypeParameterName,
|
||||||
LoanApiConstants.isTopup, LoanApiConstants.loanIdToClose, LoanApiConstants.datatables, LoanApiConstants.isEqualAmortizationParam));
|
LoanApiConstants.isTopup, LoanApiConstants.loanIdToClose, LoanApiConstants.datatables, LoanApiConstants.isEqualAmortizationParam,
|
||||||
|
LoanProductConstants.ratesParamName));
|
||||||
|
|
||||||
private final FromJsonHelper fromApiJsonHelper;
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -91,7 +91,7 @@ public final class LoanApplicationCommandFromApiJsonHelper {
|
|||||||
LoanApiConstants.linkAccountIdParameterName, LoanApiConstants.disbursementDataParameterName,
|
LoanApiConstants.linkAccountIdParameterName, LoanApiConstants.disbursementDataParameterName,
|
||||||
LoanApiConstants.emiAmountParameterName, LoanApiConstants.maxOutstandingBalanceParameterName,
|
LoanApiConstants.emiAmountParameterName, LoanApiConstants.maxOutstandingBalanceParameterName,
|
||||||
LoanProductConstants.graceOnArrearsAgeingParameterName, LoanApiConstants.createStandingInstructionAtDisbursementParameterName,
|
LoanProductConstants.graceOnArrearsAgeingParameterName, LoanApiConstants.createStandingInstructionAtDisbursementParameterName,
|
||||||
LoanApiConstants.isTopup, LoanApiConstants.loanIdToClose, LoanApiConstants.datatables, LoanApiConstants.isEqualAmortizationParam));
|
LoanApiConstants.isTopup, LoanApiConstants.loanIdToClose, LoanApiConstants.datatables, LoanApiConstants.isEqualAmortizationParam, LoanProductConstants.ratesParamName));
|
||||||
|
|
||||||
private final FromJsonHelper fromApiJsonHelper;
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
private final CalculateLoanScheduleQueryFromApiJsonHelper apiJsonHelper;
|
private final CalculateLoanScheduleQueryFromApiJsonHelper apiJsonHelper;
|
||||||
|
|||||||
+11
-2
@@ -126,6 +126,7 @@ import org.apache.fineract.portfolio.loanproduct.serialization.LoanProductDataVa
|
|||||||
import org.apache.fineract.portfolio.loanproduct.service.LoanProductReadPlatformService;
|
import org.apache.fineract.portfolio.loanproduct.service.LoanProductReadPlatformService;
|
||||||
import org.apache.fineract.portfolio.note.domain.Note;
|
import org.apache.fineract.portfolio.note.domain.Note;
|
||||||
import org.apache.fineract.portfolio.note.domain.NoteRepository;
|
import org.apache.fineract.portfolio.note.domain.NoteRepository;
|
||||||
|
import org.apache.fineract.portfolio.rate.service.RateAssembler;
|
||||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
|
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
|
||||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler;
|
import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
@@ -178,6 +179,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
private final FineractEntityToEntityMappingRepository repository;
|
private final FineractEntityToEntityMappingRepository repository;
|
||||||
private final FineractEntityRelationRepository fineractEntityRelationRepository;
|
private final FineractEntityRelationRepository fineractEntityRelationRepository;
|
||||||
private final LoanProductReadPlatformService loanProductReadPlatformService;
|
private final LoanProductReadPlatformService loanProductReadPlatformService;
|
||||||
|
private final RateAssembler rateAssembler;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper,
|
public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper,
|
||||||
@@ -200,7 +202,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
final LoanScheduleAssembler loanScheduleAssembler, final LoanUtilService loanUtilService,
|
final LoanScheduleAssembler loanScheduleAssembler, final LoanUtilService loanUtilService,
|
||||||
final CalendarReadPlatformService calendarReadPlatformService, final GlobalConfigurationRepositoryWrapper globalConfigurationRepository,
|
final CalendarReadPlatformService calendarReadPlatformService, final GlobalConfigurationRepositoryWrapper globalConfigurationRepository,
|
||||||
final FineractEntityToEntityMappingRepository repository, final FineractEntityRelationRepository fineractEntityRelationRepository,
|
final FineractEntityToEntityMappingRepository repository, final FineractEntityRelationRepository fineractEntityRelationRepository,
|
||||||
final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService, final LoanProductReadPlatformService loanProductReadPlatformService) {
|
final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService, final LoanProductReadPlatformService loanProductReadPlatformService,
|
||||||
|
final RateAssembler rateAssembler) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.fromJsonHelper = fromJsonHelper;
|
this.fromJsonHelper = fromJsonHelper;
|
||||||
this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator;
|
this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator;
|
||||||
@@ -236,7 +239,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
this.fineractEntityRelationRepository = fineractEntityRelationRepository;
|
this.fineractEntityRelationRepository = fineractEntityRelationRepository;
|
||||||
this.loanProductReadPlatformService = loanProductReadPlatformService;
|
this.loanProductReadPlatformService = loanProductReadPlatformService;
|
||||||
|
this.rateAssembler = rateAssembler;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
||||||
@@ -858,6 +861,12 @@ public void checkForProductMixRestrictions(final Loan loan) {
|
|||||||
existingLoanApplication.recalculateAllCharges();
|
existingLoanApplication.recalculateAllCharges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Changes to modify loan rates.
|
||||||
|
if (command.hasParameter(LoanProductConstants.ratesParamName)) {
|
||||||
|
existingLoanApplication.updateLoanRates(rateAssembler.fromParsedJson(command.parsedJson()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
this.fromApiJsonDeserializer.validateLoanTermAndRepaidEveryValues(existingLoanApplication.getTermFrequency(),
|
this.fromApiJsonDeserializer.validateLoanTermAndRepaidEveryValues(existingLoanApplication.getTermFrequency(),
|
||||||
existingLoanApplication.getTermPeriodFrequencyType(), productRelatedDetail.getNumberOfRepayments(),
|
existingLoanApplication.getTermPeriodFrequencyType(), productRelatedDetail.getNumberOfRepayments(),
|
||||||
productRelatedDetail.getRepayEvery(), productRelatedDetail.getRepaymentPeriodFrequencyType().getValue(),
|
productRelatedDetail.getRepayEvery(), productRelatedDetail.getRepaymentPeriodFrequencyType().getValue(),
|
||||||
|
|||||||
+14
-4
@@ -25,6 +25,8 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
import org.apache.fineract.infrastructure.codes.domain.CodeValue;
|
import org.apache.fineract.infrastructure.codes.domain.CodeValue;
|
||||||
import org.apache.fineract.infrastructure.codes.domain.CodeValueRepositoryWrapper;
|
import org.apache.fineract.infrastructure.codes.domain.CodeValueRepositoryWrapper;
|
||||||
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||||
@@ -71,6 +73,7 @@ import org.apache.fineract.portfolio.loanaccount.exception.MultiDisbursementData
|
|||||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanApplicationTerms;
|
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanApplicationTerms;
|
||||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
|
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
|
||||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleAssembler;
|
import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleAssembler;
|
||||||
|
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
|
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
|
||||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
|
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
|
||||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
|
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
|
||||||
@@ -78,6 +81,8 @@ import org.apache.fineract.portfolio.loanproduct.domain.LoanTransactionProcessin
|
|||||||
import org.apache.fineract.portfolio.loanproduct.exception.InvalidCurrencyException;
|
import org.apache.fineract.portfolio.loanproduct.exception.InvalidCurrencyException;
|
||||||
import org.apache.fineract.portfolio.loanproduct.exception.LinkedAccountRequiredException;
|
import org.apache.fineract.portfolio.loanproduct.exception.LinkedAccountRequiredException;
|
||||||
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductNotFoundException;
|
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductNotFoundException;
|
||||||
|
import org.apache.fineract.portfolio.rate.domain.Rate;
|
||||||
|
import org.apache.fineract.portfolio.rate.service.RateAssembler;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -104,6 +109,7 @@ public class LoanAssembler {
|
|||||||
private final ConfigurationDomainService configurationDomainService;
|
private final ConfigurationDomainService configurationDomainService;
|
||||||
private final WorkingDaysRepositoryWrapper workingDaysRepository;
|
private final WorkingDaysRepositoryWrapper workingDaysRepository;
|
||||||
private final LoanUtilService loanUtilService;
|
private final LoanUtilService loanUtilService;
|
||||||
|
private final RateAssembler rateAssembler;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanAssembler(final FromJsonHelper fromApiJsonHelper, final LoanRepositoryWrapper loanRepository,
|
public LoanAssembler(final FromJsonHelper fromApiJsonHelper, final LoanRepositoryWrapper loanRepository,
|
||||||
@@ -115,7 +121,7 @@ public class LoanAssembler {
|
|||||||
final CollateralAssembler loanCollateralAssembler, final LoanSummaryWrapper loanSummaryWrapper,
|
final CollateralAssembler loanCollateralAssembler, final LoanSummaryWrapper loanSummaryWrapper,
|
||||||
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
||||||
final HolidayRepository holidayRepository, final ConfigurationDomainService configurationDomainService,
|
final HolidayRepository holidayRepository, final ConfigurationDomainService configurationDomainService,
|
||||||
final WorkingDaysRepositoryWrapper workingDaysRepository, final LoanUtilService loanUtilService) {
|
final WorkingDaysRepositoryWrapper workingDaysRepository, final LoanUtilService loanUtilService, RateAssembler rateAssembler) {
|
||||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||||
this.loanRepository = loanRepository;
|
this.loanRepository = loanRepository;
|
||||||
this.loanProductRepository = loanProductRepository;
|
this.loanProductRepository = loanProductRepository;
|
||||||
@@ -134,6 +140,7 @@ public class LoanAssembler {
|
|||||||
this.configurationDomainService = configurationDomainService;
|
this.configurationDomainService = configurationDomainService;
|
||||||
this.workingDaysRepository = workingDaysRepository;
|
this.workingDaysRepository = workingDaysRepository;
|
||||||
this.loanUtilService = loanUtilService;
|
this.loanUtilService = loanUtilService;
|
||||||
|
this.rateAssembler = rateAssembler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Loan assembleFrom(final Long accountId) {
|
public Loan assembleFrom(final Long accountId) {
|
||||||
@@ -222,6 +229,9 @@ public class LoanAssembler {
|
|||||||
Client client = null;
|
Client client = null;
|
||||||
Group group = null;
|
Group group = null;
|
||||||
|
|
||||||
|
//Here we add Rates to LoanApplication
|
||||||
|
final List<Rate> rates = this.rateAssembler.fromParsedJson(element);
|
||||||
|
|
||||||
final LoanProductRelatedDetail loanProductRelatedDetail = this.loanScheduleAssembler.assembleLoanProductRelatedDetail(element);
|
final LoanProductRelatedDetail loanProductRelatedDetail = this.loanScheduleAssembler.assembleLoanProductRelatedDetail(element);
|
||||||
|
|
||||||
final BigDecimal interestRateDifferential = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(LoanApiConstants.interestRateDifferentialParameterName, element);
|
final BigDecimal interestRateDifferential = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(LoanApiConstants.interestRateDifferentialParameterName, element);
|
||||||
@@ -250,21 +260,21 @@ public class LoanAssembler {
|
|||||||
loanApplication = Loan.newIndividualLoanApplicationFromGroup(accountNo, client, group, loanType.getId().intValue(),
|
loanApplication = Loan.newIndividualLoanApplicationFromGroup(accountNo, client, group, loanType.getId().intValue(),
|
||||||
loanProduct, fund, loanOfficer, loanPurpose, loanTransactionProcessingStrategy, loanProductRelatedDetail, loanCharges,
|
loanProduct, fund, loanOfficer, loanPurpose, loanTransactionProcessingStrategy, loanProductRelatedDetail, loanCharges,
|
||||||
collateral, syncDisbursementWithMeeting, fixedEmiAmount, disbursementDetails, maxOutstandingLoanBalance,
|
collateral, syncDisbursementWithMeeting, fixedEmiAmount, disbursementDetails, maxOutstandingLoanBalance,
|
||||||
createStandingInstructionAtDisbursement, isFloatingInterestRate, interestRateDifferential);
|
createStandingInstructionAtDisbursement, isFloatingInterestRate, interestRateDifferential, rates);
|
||||||
|
|
||||||
} else if (group != null) {
|
} else if (group != null) {
|
||||||
|
|
||||||
loanApplication = Loan.newGroupLoanApplication(accountNo, group, loanType.getId().intValue(), loanProduct, fund, loanOfficer,
|
loanApplication = Loan.newGroupLoanApplication(accountNo, group, loanType.getId().intValue(), loanProduct, fund, loanOfficer,
|
||||||
loanPurpose, loanTransactionProcessingStrategy, loanProductRelatedDetail, loanCharges, collateral,
|
loanPurpose, loanTransactionProcessingStrategy, loanProductRelatedDetail, loanCharges, collateral,
|
||||||
syncDisbursementWithMeeting, fixedEmiAmount, disbursementDetails, maxOutstandingLoanBalance,
|
syncDisbursementWithMeeting, fixedEmiAmount, disbursementDetails, maxOutstandingLoanBalance,
|
||||||
createStandingInstructionAtDisbursement,isFloatingInterestRate, interestRateDifferential);
|
createStandingInstructionAtDisbursement,isFloatingInterestRate, interestRateDifferential, rates);
|
||||||
|
|
||||||
} else if (client != null) {
|
} else if (client != null) {
|
||||||
|
|
||||||
loanApplication = Loan.newIndividualLoanApplication(accountNo, client, loanType.getId().intValue(), loanProduct, fund,
|
loanApplication = Loan.newIndividualLoanApplication(accountNo, client, loanType.getId().intValue(), loanProduct, fund,
|
||||||
loanOfficer, loanPurpose, loanTransactionProcessingStrategy, loanProductRelatedDetail, loanCharges, collateral,
|
loanOfficer, loanPurpose, loanTransactionProcessingStrategy, loanProductRelatedDetail, loanCharges, collateral,
|
||||||
fixedEmiAmount, disbursementDetails, maxOutstandingLoanBalance, createStandingInstructionAtDisbursement,
|
fixedEmiAmount, disbursementDetails, maxOutstandingLoanBalance, createStandingInstructionAtDisbursement,
|
||||||
isFloatingInterestRate, interestRateDifferential);
|
isFloatingInterestRate, interestRateDifferential, rates);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.portfolio.loanaccount.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.data.LoanChargePaidByData;
|
||||||
|
|
||||||
|
public interface LoanChargePaidByReadPlatformService {
|
||||||
|
|
||||||
|
List<LoanChargePaidByData> getLoanChargesPaidByTransactionId(Long id);
|
||||||
|
}
|
||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.fineract.portfolio.loanaccount.service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
|
||||||
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.data.LoanChargePaidByData;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class LoanChargePaidByReadPlatformServiceImpl implements
|
||||||
|
LoanChargePaidByReadPlatformService {
|
||||||
|
|
||||||
|
private final JdbcTemplate jdbcTemplate;
|
||||||
|
private final PlatformSecurityContext context;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public LoanChargePaidByReadPlatformServiceImpl(final PlatformSecurityContext context,
|
||||||
|
final RoutingDataSource dataSource) {
|
||||||
|
this.context = context;
|
||||||
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<LoanChargePaidByData> getLoanChargesPaidByTransactionId(Long transactionId) {
|
||||||
|
this.context.authenticatedUser();
|
||||||
|
final LoanChargePaidByMapper rm = new LoanChargePaidByMapper();
|
||||||
|
final String sql = "select " + rm.loanChargePaidBySchema() + " where lcpd.loan_transaction_id = ?";
|
||||||
|
return this.jdbcTemplate.query(sql, rm, new Object[]{transactionId});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class LoanChargePaidByMapper implements RowMapper<LoanChargePaidByData> {
|
||||||
|
|
||||||
|
public String loanChargePaidBySchema() {
|
||||||
|
return "lcpd.id as id, lcpd.amount as amount, lcpd.installment_number as installmentNumber," +
|
||||||
|
" lcpd.loan_charge_id as chargeId, lcpd.loan_transaction_id as transactionId, " +
|
||||||
|
" c.name as chargeName"
|
||||||
|
+ " from m_loan_charge_paid_by lcpd"
|
||||||
|
+ " join m_loan_charge lc on lc.id=lcpd.loan_charge_Id"
|
||||||
|
+ " join m_charge c on c.id=lc.charge_id";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LoanChargePaidByData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum)
|
||||||
|
throws SQLException {
|
||||||
|
final Long id = rs.getLong("id");
|
||||||
|
final BigDecimal amount = rs.getBigDecimal("amount");
|
||||||
|
final Integer installmentNumber = rs.getInt("installmentNumber");
|
||||||
|
final Long chargeId = rs.getLong("chargeId");
|
||||||
|
final Long transactionId = rs.getLong("transactionId");
|
||||||
|
final String chargeName = rs.getString("chargeName");
|
||||||
|
return new LoanChargePaidByData(id, amount, installmentNumber, chargeId, transactionId, chargeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+1
@@ -134,5 +134,6 @@ public interface LoanProductConstants {
|
|||||||
|
|
||||||
public static final String isEqualAmortizationParam = "isEqualAmortization";
|
public static final String isEqualAmortizationParam = "isEqualAmortization";
|
||||||
|
|
||||||
|
public static final String ratesParamName = "rates";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-4
@@ -52,6 +52,7 @@ import org.apache.fineract.accounting.producttoaccountmapping.service.ProductToG
|
|||||||
import org.apache.fineract.commands.domain.CommandWrapper;
|
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||||
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
||||||
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
|
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||||
|
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||||
import org.apache.fineract.infrastructure.core.api.ApiParameterHelper;
|
import org.apache.fineract.infrastructure.core.api.ApiParameterHelper;
|
||||||
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
|
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
|
||||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
@@ -77,6 +78,8 @@ import org.apache.fineract.portfolio.loanproduct.service.LoanDropdownReadPlatfor
|
|||||||
import org.apache.fineract.portfolio.loanproduct.service.LoanProductReadPlatformService;
|
import org.apache.fineract.portfolio.loanproduct.service.LoanProductReadPlatformService;
|
||||||
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
||||||
import org.apache.fineract.portfolio.paymenttype.service.PaymentTypeReadPlatformService;
|
import org.apache.fineract.portfolio.paymenttype.service.PaymentTypeReadPlatformService;
|
||||||
|
import org.apache.fineract.portfolio.rate.data.RateData;
|
||||||
|
import org.apache.fineract.portfolio.rate.service.RateReadService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -102,7 +105,8 @@ public class LoanProductsApiResource {
|
|||||||
"interestCalculationPeriodTypeOptions", "transactionProcessingStrategyOptions", "chargeOptions", "accountingOptions",
|
"interestCalculationPeriodTypeOptions", "transactionProcessingStrategyOptions", "chargeOptions", "accountingOptions",
|
||||||
"accountingRuleOptions", "accountingMappingOptions", "floatingRateOptions", "isLinkedToFloatingInterestRates",
|
"accountingRuleOptions", "accountingMappingOptions", "floatingRateOptions", "isLinkedToFloatingInterestRates",
|
||||||
"floatingRatesId", "interestRateDifferential", "minDifferentialLendingRate", "defaultDifferentialLendingRate",
|
"floatingRatesId", "interestRateDifferential", "minDifferentialLendingRate", "defaultDifferentialLendingRate",
|
||||||
"maxDifferentialLendingRate", "isFloatingInterestRateCalculationAllowed", LoanProductConstants.canUseForTopup, LoanProductConstants.isEqualAmortizationParam));
|
"maxDifferentialLendingRate", "isFloatingInterestRateCalculationAllowed", LoanProductConstants.canUseForTopup, LoanProductConstants.isEqualAmortizationParam,
|
||||||
|
LoanProductConstants.ratesParamName));
|
||||||
|
|
||||||
private final Set<String> PRODUCT_MIX_DATA_PARAMETERS = new HashSet<>(Arrays.asList("productId", "productName", "restrictedProducts",
|
private final Set<String> PRODUCT_MIX_DATA_PARAMETERS = new HashSet<>(Arrays.asList("productId", "productName", "restrictedProducts",
|
||||||
"allowedProducts", "productOptions"));
|
"allowedProducts", "productOptions"));
|
||||||
@@ -125,6 +129,9 @@ public class LoanProductsApiResource {
|
|||||||
private final DropdownReadPlatformService commonDropdownReadPlatformService;
|
private final DropdownReadPlatformService commonDropdownReadPlatformService;
|
||||||
private final PaymentTypeReadPlatformService paymentTypeReadPlatformService;
|
private final PaymentTypeReadPlatformService paymentTypeReadPlatformService;
|
||||||
private final FloatingRatesReadPlatformService floatingRateReadPlatformService;
|
private final FloatingRatesReadPlatformService floatingRateReadPlatformService;
|
||||||
|
private final RateReadService rateReadService;
|
||||||
|
private final ConfigurationDomainService configurationDomainService;
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanProductsApiResource(final PlatformSecurityContext context, final LoanProductReadPlatformService readPlatformService,
|
public LoanProductsApiResource(final PlatformSecurityContext context, final LoanProductReadPlatformService readPlatformService,
|
||||||
@@ -139,7 +146,8 @@ public class LoanProductsApiResource {
|
|||||||
final ProductMixReadPlatformService productMixReadPlatformService,
|
final ProductMixReadPlatformService productMixReadPlatformService,
|
||||||
final DropdownReadPlatformService commonDropdownReadPlatformService,
|
final DropdownReadPlatformService commonDropdownReadPlatformService,
|
||||||
PaymentTypeReadPlatformService paymentTypeReadPlatformService,
|
PaymentTypeReadPlatformService paymentTypeReadPlatformService,
|
||||||
final FloatingRatesReadPlatformService floatingRateReadPlatformService) {
|
final FloatingRatesReadPlatformService floatingRateReadPlatformService, final RateReadService rateReadService,
|
||||||
|
final ConfigurationDomainService configurationDomainService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.loanProductReadPlatformService = readPlatformService;
|
this.loanProductReadPlatformService = readPlatformService;
|
||||||
this.chargeReadPlatformService = chargeReadPlatformService;
|
this.chargeReadPlatformService = chargeReadPlatformService;
|
||||||
@@ -156,6 +164,8 @@ public class LoanProductsApiResource {
|
|||||||
this.commonDropdownReadPlatformService = commonDropdownReadPlatformService;
|
this.commonDropdownReadPlatformService = commonDropdownReadPlatformService;
|
||||||
this.paymentTypeReadPlatformService = paymentTypeReadPlatformService;
|
this.paymentTypeReadPlatformService = paymentTypeReadPlatformService;
|
||||||
this.floatingRateReadPlatformService = floatingRateReadPlatformService;
|
this.floatingRateReadPlatformService = floatingRateReadPlatformService;
|
||||||
|
this.rateReadService = rateReadService;
|
||||||
|
this.configurationDomainService = configurationDomainService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@@ -288,6 +298,12 @@ public class LoanProductsApiResource {
|
|||||||
penaltyOptions = null;
|
penaltyOptions = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isRatesEnabled = this.configurationDomainService.isSubRatesEnabled();
|
||||||
|
Collection<RateData> rateOptions = this.rateReadService.retrieveLoanApplicableRates();
|
||||||
|
if(rateOptions.isEmpty()){
|
||||||
|
rateOptions = null;
|
||||||
|
}
|
||||||
|
|
||||||
final Collection<CurrencyData> currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies();
|
final Collection<CurrencyData> currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies();
|
||||||
final List<EnumOptionData> amortizationTypeOptions = this.dropdownReadPlatformService.retrieveLoanAmortizationTypeOptions();
|
final List<EnumOptionData> amortizationTypeOptions = this.dropdownReadPlatformService.retrieveLoanAmortizationTypeOptions();
|
||||||
final List<EnumOptionData> interestTypeOptions = this.dropdownReadPlatformService.retrieveLoanInterestTypeOptions();
|
final List<EnumOptionData> interestTypeOptions = this.dropdownReadPlatformService.retrieveLoanInterestTypeOptions();
|
||||||
@@ -331,11 +347,11 @@ public class LoanProductsApiResource {
|
|||||||
|
|
||||||
return new LoanProductData(productData, chargeOptions, penaltyOptions, paymentTypeOptions, currencyOptions,
|
return new LoanProductData(productData, chargeOptions, penaltyOptions, paymentTypeOptions, currencyOptions,
|
||||||
amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, repaymentFrequencyTypeOptions,
|
amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, repaymentFrequencyTypeOptions,
|
||||||
interestRateFrequencyTypeOptions, fundOptions, transactionProcessingStrategyOptions, accountOptions,
|
interestRateFrequencyTypeOptions, fundOptions, transactionProcessingStrategyOptions, rateOptions, accountOptions,
|
||||||
accountingRuleTypeOptions, loanCycleValueConditionTypeOptions, daysInMonthTypeOptions, daysInYearTypeOptions,
|
accountingRuleTypeOptions, loanCycleValueConditionTypeOptions, daysInMonthTypeOptions, daysInYearTypeOptions,
|
||||||
interestRecalculationCompoundingTypeOptions, rescheduleStrategyTypeOptions, interestRecalculationFrequencyTypeOptions,
|
interestRecalculationCompoundingTypeOptions, rescheduleStrategyTypeOptions, interestRecalculationFrequencyTypeOptions,
|
||||||
preCloseInterestCalculationStrategyOptions, floatingRateOptions, interestRecalculationNthDayTypeOptions,
|
preCloseInterestCalculationStrategyOptions, floatingRateOptions, interestRecalculationNthDayTypeOptions,
|
||||||
interestRecalculationDayOfWeekTypeOptions);
|
interestRecalculationDayOfWeekTypeOptions, isRatesEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+34
-9
@@ -47,6 +47,7 @@ import org.apache.fineract.portfolio.loanproduct.domain.InterestMethod;
|
|||||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
|
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
|
||||||
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
|
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
|
||||||
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
||||||
|
import org.apache.fineract.portfolio.rate.data.RateData;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
@@ -133,6 +134,10 @@ public class LoanProductData implements Serializable {
|
|||||||
private Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings;
|
private Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings;
|
||||||
private Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings;
|
private Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings;
|
||||||
|
|
||||||
|
// rates
|
||||||
|
private final boolean isRatesEnabled;
|
||||||
|
private final Collection<RateData> rates;
|
||||||
|
|
||||||
// template related
|
// template related
|
||||||
private final Collection<FundData> fundOptions;
|
private final Collection<FundData> fundOptions;
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@@ -146,6 +151,7 @@ public class LoanProductData implements Serializable {
|
|||||||
private final List<EnumOptionData> interestCalculationPeriodTypeOptions;
|
private final List<EnumOptionData> interestCalculationPeriodTypeOptions;
|
||||||
private final Collection<TransactionProcessingStrategyData> transactionProcessingStrategyOptions;
|
private final Collection<TransactionProcessingStrategyData> transactionProcessingStrategyOptions;
|
||||||
private final Collection<ChargeData> chargeOptions;
|
private final Collection<ChargeData> chargeOptions;
|
||||||
|
private final Collection<RateData> rateOptions;
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private final Collection<ChargeData> penaltyOptions;
|
private final Collection<ChargeData> penaltyOptions;
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@@ -261,6 +267,9 @@ public class LoanProductData implements Serializable {
|
|||||||
final boolean syncExpectedWithDisbursementDate = false;
|
final boolean syncExpectedWithDisbursementDate = false;
|
||||||
final boolean canUseForTopup = false;
|
final boolean canUseForTopup = false;
|
||||||
final boolean isEqualAmortization = false;
|
final boolean isEqualAmortization = false;
|
||||||
|
final Collection<RateData> rateOptions = null;
|
||||||
|
final Collection<RateData> rates = null;
|
||||||
|
final boolean isRatesEnabled= false;
|
||||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||||
minInterestRatePerPeriod, maxInterestRatePerPeriod, annualInterestRate, repaymentFrequencyType, interestRateFrequencyType,
|
minInterestRatePerPeriod, maxInterestRatePerPeriod, annualInterestRate, repaymentFrequencyType, interestRateFrequencyType,
|
||||||
@@ -275,7 +284,7 @@ public class LoanProductData implements Serializable {
|
|||||||
loanProductConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRateId, floatingRateName,
|
loanProductConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRateId, floatingRateName,
|
||||||
interestRateDifferential, minDifferentialLendingRate, defaultDifferentialLendingRate, maxDifferentialLendingRate,
|
interestRateDifferential, minDifferentialLendingRate, defaultDifferentialLendingRate, maxDifferentialLendingRate,
|
||||||
isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGap, maximumGap,
|
isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGap, maximumGap,
|
||||||
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization);
|
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, rateOptions, rates, isRatesEnabled);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,6 +362,9 @@ public class LoanProductData implements Serializable {
|
|||||||
final boolean syncExpectedWithDisbursementDate = false;
|
final boolean syncExpectedWithDisbursementDate = false;
|
||||||
final boolean canUseForTopup = false;
|
final boolean canUseForTopup = false;
|
||||||
final boolean isEqualAmortization = false;
|
final boolean isEqualAmortization = false;
|
||||||
|
final Collection<RateData> rateOptions = null;
|
||||||
|
final Collection<RateData> rates = null;
|
||||||
|
final boolean isRatesEnabled = false;
|
||||||
|
|
||||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||||
@@ -368,7 +380,7 @@ public class LoanProductData implements Serializable {
|
|||||||
loanProductConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRateId, floatingRateName,
|
loanProductConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRateId, floatingRateName,
|
||||||
interestRateDifferential, minDifferentialLendingRate, defaultDifferentialLendingRate, maxDifferentialLendingRate,
|
interestRateDifferential, minDifferentialLendingRate, defaultDifferentialLendingRate, maxDifferentialLendingRate,
|
||||||
isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGap, maximumGap,
|
isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGap, maximumGap,
|
||||||
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization);
|
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, rateOptions, rates, isRatesEnabled);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,6 +465,9 @@ public class LoanProductData implements Serializable {
|
|||||||
final boolean syncExpectedWithDisbursementDate = false;
|
final boolean syncExpectedWithDisbursementDate = false;
|
||||||
final boolean canUseForTopup = false;
|
final boolean canUseForTopup = false;
|
||||||
final boolean isEqualAmortization = false;
|
final boolean isEqualAmortization = false;
|
||||||
|
final Collection<RateData> rateOptions = null;
|
||||||
|
final Collection<RateData> rates = null;
|
||||||
|
final boolean isRatesEnabled = false;
|
||||||
|
|
||||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||||
@@ -468,7 +483,7 @@ public class LoanProductData implements Serializable {
|
|||||||
installmentAmountInMultiplesOf, loanProductConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRateId,
|
installmentAmountInMultiplesOf, loanProductConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRateId,
|
||||||
floatingRateName, interestRateDifferential, minDifferentialLendingRate, defaultDifferentialLendingRate,
|
floatingRateName, interestRateDifferential, minDifferentialLendingRate, defaultDifferentialLendingRate,
|
||||||
maxDifferentialLendingRate, isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGap, maximumGap,
|
maxDifferentialLendingRate, isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGap, maximumGap,
|
||||||
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization);
|
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, rateOptions, rates, isRatesEnabled);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,6 +562,9 @@ public class LoanProductData implements Serializable {
|
|||||||
final boolean syncExpectedWithDisbursementDate = false;
|
final boolean syncExpectedWithDisbursementDate = false;
|
||||||
final boolean canUseForTopup = false;
|
final boolean canUseForTopup = false;
|
||||||
final boolean isEqualAmortization = false;
|
final boolean isEqualAmortization = false;
|
||||||
|
final Collection<RateData> rateOptions = null;
|
||||||
|
final Collection<RateData> rates = null;
|
||||||
|
final boolean isRatesEnabled = false;
|
||||||
|
|
||||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||||
@@ -562,7 +580,7 @@ public class LoanProductData implements Serializable {
|
|||||||
installmentAmountInMultiplesOf, loanProductConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRateId,
|
installmentAmountInMultiplesOf, loanProductConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRateId,
|
||||||
floatingRateName, interestRateDifferential, minDifferentialLendingRate, defaultDifferentialLendingRate,
|
floatingRateName, interestRateDifferential, minDifferentialLendingRate, defaultDifferentialLendingRate,
|
||||||
maxDifferentialLendingRate, isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGap, maximumGap,
|
maxDifferentialLendingRate, isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGap, maximumGap,
|
||||||
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization);
|
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, rateOptions, rates, isRatesEnabled);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -601,7 +619,8 @@ public class LoanProductData implements Serializable {
|
|||||||
BigDecimal minDifferentialLendingRate, BigDecimal defaultDifferentialLendingRate, BigDecimal maxDifferentialLendingRate,
|
BigDecimal minDifferentialLendingRate, BigDecimal defaultDifferentialLendingRate, BigDecimal maxDifferentialLendingRate,
|
||||||
boolean isFloatingInterestRateCalculationAllowed, final boolean isVariableInstallmentsAllowed,
|
boolean isFloatingInterestRateCalculationAllowed, final boolean isVariableInstallmentsAllowed,
|
||||||
final Integer minimumGapBetweenInstallments, final Integer maximumGapBetweenInstallments,
|
final Integer minimumGapBetweenInstallments, final Integer maximumGapBetweenInstallments,
|
||||||
final boolean syncExpectedWithDisbursementDate, final boolean canUseForTopup, final boolean isEqualAmortization) {
|
final boolean syncExpectedWithDisbursementDate, final boolean canUseForTopup, final boolean isEqualAmortization, Collection<RateData> rateOptions, Collection<RateData> rates,
|
||||||
|
final boolean isRatesEnabled) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.shortName = shortName;
|
this.shortName = shortName;
|
||||||
@@ -653,6 +672,9 @@ public class LoanProductData implements Serializable {
|
|||||||
this.status = status;
|
this.status = status;
|
||||||
this.externalId = externalId;
|
this.externalId = externalId;
|
||||||
this.minimumDaysBetweenDisbursalAndFirstRepayment = minimumDaysBetweenDisbursalAndFirstRepayment;
|
this.minimumDaysBetweenDisbursalAndFirstRepayment = minimumDaysBetweenDisbursalAndFirstRepayment;
|
||||||
|
this.rateOptions = rateOptions;
|
||||||
|
this.rates = rates;
|
||||||
|
this.isRatesEnabled = isRatesEnabled;
|
||||||
|
|
||||||
this.chargeOptions = null;
|
this.chargeOptions = null;
|
||||||
this.penaltyOptions = null;
|
this.penaltyOptions = null;
|
||||||
@@ -715,7 +737,7 @@ public class LoanProductData implements Serializable {
|
|||||||
final List<EnumOptionData> interestTypeOptions, final List<EnumOptionData> interestCalculationPeriodTypeOptions,
|
final List<EnumOptionData> interestTypeOptions, final List<EnumOptionData> interestCalculationPeriodTypeOptions,
|
||||||
final List<EnumOptionData> repaymentFrequencyTypeOptions, final List<EnumOptionData> interestRateFrequencyTypeOptions,
|
final List<EnumOptionData> repaymentFrequencyTypeOptions, final List<EnumOptionData> interestRateFrequencyTypeOptions,
|
||||||
final Collection<FundData> fundOptions, final Collection<TransactionProcessingStrategyData> transactionStrategyOptions,
|
final Collection<FundData> fundOptions, final Collection<TransactionProcessingStrategyData> transactionStrategyOptions,
|
||||||
final Map<String, List<GLAccountData>> accountingMappingOptions, final List<EnumOptionData> accountingRuleOptions,
|
final Collection<RateData> rateOptions, final Map<String, List<GLAccountData>> accountingMappingOptions, final List<EnumOptionData> accountingRuleOptions,
|
||||||
final List<EnumOptionData> valueConditionTypeOptions, final List<EnumOptionData> daysInMonthTypeOptions,
|
final List<EnumOptionData> valueConditionTypeOptions, final List<EnumOptionData> daysInMonthTypeOptions,
|
||||||
final List<EnumOptionData> daysInYearTypeOptions, final List<EnumOptionData> interestRecalculationCompoundingTypeOptions,
|
final List<EnumOptionData> daysInYearTypeOptions, final List<EnumOptionData> interestRecalculationCompoundingTypeOptions,
|
||||||
final List<EnumOptionData> rescheduleStrategyTypeOptions, final List<EnumOptionData> interestRecalculationFrequencyTypeOptions,
|
final List<EnumOptionData> rescheduleStrategyTypeOptions, final List<EnumOptionData> interestRecalculationFrequencyTypeOptions,
|
||||||
@@ -780,6 +802,7 @@ public class LoanProductData implements Serializable {
|
|||||||
this.currency = productData.currency;
|
this.currency = productData.currency;
|
||||||
this.fundOptions = fundOptions;
|
this.fundOptions = fundOptions;
|
||||||
this.transactionProcessingStrategyOptions = transactionStrategyOptions;
|
this.transactionProcessingStrategyOptions = transactionStrategyOptions;
|
||||||
|
this.rateOptions = rateOptions;
|
||||||
this.floatingRateOptions = floatingRateOptions;
|
this.floatingRateOptions = floatingRateOptions;
|
||||||
if (this.transactionProcessingStrategyOptions != null && this.transactionProcessingStrategyOptions.size() == 1) {
|
if (this.transactionProcessingStrategyOptions != null && this.transactionProcessingStrategyOptions.size() == 1) {
|
||||||
final List<TransactionProcessingStrategyData> listOfOptions = new ArrayList<>(this.transactionProcessingStrategyOptions);
|
final List<TransactionProcessingStrategyData> listOfOptions = new ArrayList<>(this.transactionProcessingStrategyOptions);
|
||||||
@@ -843,6 +866,8 @@ public class LoanProductData implements Serializable {
|
|||||||
this.syncExpectedWithDisbursementDate = productData.syncExpectedWithDisbursementDate;
|
this.syncExpectedWithDisbursementDate = productData.syncExpectedWithDisbursementDate;
|
||||||
this.canUseForTopup = productData.canUseForTopup;
|
this.canUseForTopup = productData.canUseForTopup;
|
||||||
this.isEqualAmortization = productData.isEqualAmortization;
|
this.isEqualAmortization = productData.isEqualAmortization;
|
||||||
|
this.rates = productData.rates;
|
||||||
|
this.isRatesEnabled = isRatesEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<ChargeData> nullIfEmpty(final Collection<ChargeData> charges) {
|
private Collection<ChargeData> nullIfEmpty(final Collection<ChargeData> charges) {
|
||||||
@@ -1198,9 +1223,9 @@ public class LoanProductData implements Serializable {
|
|||||||
return syncExpectedWithDisbursementDate;
|
return syncExpectedWithDisbursementDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canUseForTopup() {
|
public boolean canUseForTopup() {
|
||||||
return this.canUseForTopup;
|
return this.canUseForTopup;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BigDecimal getInterestRateDifferential() {
|
public BigDecimal getInterestRateDifferential() {
|
||||||
return this.interestRateDifferential;
|
return this.interestRateDifferential;
|
||||||
|
|||||||
+48
-3
@@ -61,6 +61,7 @@ import org.apache.fineract.portfolio.floatingrates.domain.FloatingRate;
|
|||||||
import org.apache.fineract.portfolio.fund.domain.Fund;
|
import org.apache.fineract.portfolio.fund.domain.Fund;
|
||||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
||||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||||
|
import org.apache.fineract.portfolio.rate.domain.Rate;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,6 +100,10 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
|||||||
@JoinTable(name = "m_product_loan_charge", joinColumns = @JoinColumn(name = "product_loan_id"), inverseJoinColumns = @JoinColumn(name = "charge_id"))
|
@JoinTable(name = "m_product_loan_charge", joinColumns = @JoinColumn(name = "product_loan_id"), inverseJoinColumns = @JoinColumn(name = "charge_id"))
|
||||||
private List<Charge> charges;
|
private List<Charge> charges;
|
||||||
|
|
||||||
|
@ManyToMany(fetch = FetchType.LAZY)
|
||||||
|
@JoinTable(name = "m_product_loan_rate", joinColumns = @JoinColumn(name = "product_loan_id"), inverseJoinColumns = @JoinColumn(name = "rate_id"))
|
||||||
|
private List<Rate> rates;
|
||||||
|
|
||||||
@Embedded
|
@Embedded
|
||||||
private LoanProductRelatedDetail loanProductRelatedDetail;
|
private LoanProductRelatedDetail loanProductRelatedDetail;
|
||||||
|
|
||||||
@@ -184,7 +189,8 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
|||||||
private boolean isEqualAmortization = false;
|
private boolean isEqualAmortization = false;
|
||||||
|
|
||||||
public static LoanProduct assembleFromJson(final Fund fund, final LoanTransactionProcessingStrategy loanTransactionProcessingStrategy,
|
public static LoanProduct assembleFromJson(final Fund fund, final LoanTransactionProcessingStrategy loanTransactionProcessingStrategy,
|
||||||
final List<Charge> productCharges, final JsonCommand command, final AprCalculator aprCalculator, FloatingRate floatingRate) {
|
final List<Charge> productCharges, final JsonCommand command, final AprCalculator aprCalculator, FloatingRate floatingRate,
|
||||||
|
final List<Rate> productRates) {
|
||||||
|
|
||||||
final String name = command.stringValueOfParameterNamed("name");
|
final String name = command.stringValueOfParameterNamed("name");
|
||||||
final String shortName = command.stringValueOfParameterNamed(LoanProductConstants.shortName);
|
final String shortName = command.stringValueOfParameterNamed(LoanProductConstants.shortName);
|
||||||
@@ -350,7 +356,7 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
|||||||
installmentAmountInMultiplesOf, loanConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRate,
|
installmentAmountInMultiplesOf, loanConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRate,
|
||||||
interestRateDifferential, minDifferentialLendingRate, maxDifferentialLendingRate, defaultDifferentialLendingRate,
|
interestRateDifferential, minDifferentialLendingRate, maxDifferentialLendingRate, defaultDifferentialLendingRate,
|
||||||
isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGapBetweenInstallments,
|
isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGapBetweenInstallments,
|
||||||
maximumGapBetweenInstallments, syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization);
|
maximumGapBetweenInstallments, syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, productRates);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -580,7 +586,7 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
|||||||
BigDecimal minDifferentialLendingRate, BigDecimal maxDifferentialLendingRate, BigDecimal defaultDifferentialLendingRate,
|
BigDecimal minDifferentialLendingRate, BigDecimal maxDifferentialLendingRate, BigDecimal defaultDifferentialLendingRate,
|
||||||
Boolean isFloatingInterestRateCalculationAllowed, final Boolean isVariableInstallmentsAllowed,
|
Boolean isFloatingInterestRateCalculationAllowed, final Boolean isVariableInstallmentsAllowed,
|
||||||
final Integer minimumGapBetweenInstallments, final Integer maximumGapBetweenInstallments,
|
final Integer minimumGapBetweenInstallments, final Integer maximumGapBetweenInstallments,
|
||||||
final boolean syncExpectedWithDisbursementDate, final boolean canUseForTopup, final boolean isEqualAmortization) {
|
final boolean syncExpectedWithDisbursementDate, final boolean canUseForTopup, final boolean isEqualAmortization, final List<Rate> rates) {
|
||||||
this.fund = fund;
|
this.fund = fund;
|
||||||
this.transactionProcessingStrategy = transactionProcessingStrategy;
|
this.transactionProcessingStrategy = transactionProcessingStrategy;
|
||||||
this.name = name.trim();
|
this.name = name.trim();
|
||||||
@@ -658,6 +664,10 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
|||||||
syncExpectedWithDisbursementDate;
|
syncExpectedWithDisbursementDate;
|
||||||
this.canUseForTopup = canUseForTopup;
|
this.canUseForTopup = canUseForTopup;
|
||||||
this.isEqualAmortization = isEqualAmortization;
|
this.isEqualAmortization = isEqualAmortization;
|
||||||
|
|
||||||
|
if(rates != null){
|
||||||
|
this.rates = rates;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MonetaryCurrency getCurrency() {
|
public MonetaryCurrency getCurrency() {
|
||||||
@@ -699,6 +709,25 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
|||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean updateRates(final List<Rate> newProductRates) {
|
||||||
|
if (newProductRates == null) { return false; }
|
||||||
|
|
||||||
|
boolean updated = false;
|
||||||
|
if (this.rates != null) {
|
||||||
|
final Set<Rate> currentSetOfCharges = new HashSet<>(this.rates);
|
||||||
|
final Set<Rate> newSetOfCharges = new HashSet<>(newProductRates);
|
||||||
|
|
||||||
|
if (!currentSetOfCharges.equals(newSetOfCharges)) {
|
||||||
|
updated = true;
|
||||||
|
this.rates = newProductRates;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
updated = true;
|
||||||
|
this.rates = newProductRates;
|
||||||
|
}
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
public Integer getAccountingType() {
|
public Integer getAccountingType() {
|
||||||
return this.accountingRule;
|
return this.accountingRule;
|
||||||
}
|
}
|
||||||
@@ -1043,6 +1072,13 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
|||||||
this.canUseForTopup = newValue;
|
this.canUseForTopup = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (command.hasParameter(LoanProductConstants.ratesParamName)) {
|
||||||
|
final JsonArray jsonArray = command.arrayOfParameterNamed(LoanProductConstants.ratesParamName);
|
||||||
|
if (jsonArray != null) {
|
||||||
|
actualChanges.put(LoanProductConstants.ratesParamName, command.jsonFragment(LoanProductConstants.ratesParamName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return actualChanges;
|
return actualChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1379,4 +1415,13 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
|||||||
this.isEqualAmortization = isEqualAmortization;
|
this.isEqualAmortization = isEqualAmortization;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<Rate> getRates() {
|
||||||
|
return rates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRates(List<Rate> rates) {
|
||||||
|
this.rates = rates;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -163,4 +163,12 @@ public class LoanProductMinMaxConstraints {
|
|||||||
this.maxNominalInterestRatePerPeriod = null;
|
this.maxNominalInterestRatePerPeriod = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setMinNominalInterestRatePerPeriod(BigDecimal minNominalInterestRatePerPeriod) {
|
||||||
|
this.minNominalInterestRatePerPeriod = minNominalInterestRatePerPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxNominalInterestRatePerPeriod(BigDecimal maxNominalInterestRatePerPeriod) {
|
||||||
|
this.maxNominalInterestRatePerPeriod = maxNominalInterestRatePerPeriod;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+3
@@ -666,4 +666,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
|||||||
this.isEqualAmortization = isEqualAmortization;
|
this.isEqualAmortization = isEqualAmortization;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setNominalInterestRatePerPeriod(BigDecimal nominalInterestRatePerPeriod) {
|
||||||
|
this.nominalInterestRatePerPeriod = nominalInterestRatePerPeriod;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -106,7 +106,8 @@ public final class LoanProductDataValidator {
|
|||||||
LoanProductConstants.recalculationRestFrequencyWeekdayParamName,
|
LoanProductConstants.recalculationRestFrequencyWeekdayParamName,
|
||||||
LoanProductConstants.recalculationRestFrequencyNthDayParamName, LoanProductConstants.recalculationRestFrequencyOnDayParamName,
|
LoanProductConstants.recalculationRestFrequencyNthDayParamName, LoanProductConstants.recalculationRestFrequencyOnDayParamName,
|
||||||
LoanProductConstants.isCompoundingToBePostedAsTransactionParamName, LoanProductConstants.allowCompoundingOnEodParamName,
|
LoanProductConstants.isCompoundingToBePostedAsTransactionParamName, LoanProductConstants.allowCompoundingOnEodParamName,
|
||||||
LoanProductConstants.canUseForTopup, LoanProductConstants.isEqualAmortizationParam));
|
LoanProductConstants.canUseForTopup, LoanProductConstants.isEqualAmortizationParam,
|
||||||
|
LoanProductConstants.ratesParamName));
|
||||||
|
|
||||||
private static final String[] supportedloanConfigurableAttributes = {LoanProductConstants.amortizationTypeParamName,
|
private static final String[] supportedloanConfigurableAttributes = {LoanProductConstants.amortizationTypeParamName,
|
||||||
LoanProductConstants.interestTypeParamName, LoanProductConstants.transactionProcessingStrategyIdParamName,
|
LoanProductConstants.interestTypeParamName, LoanProductConstants.transactionProcessingStrategyIdParamName,
|
||||||
|
|||||||
+16
-6
@@ -42,6 +42,8 @@ import org.apache.fineract.portfolio.loanproduct.data.LoanProductInterestRecalcu
|
|||||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
|
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
|
||||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductParamType;
|
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductParamType;
|
||||||
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductNotFoundException;
|
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductNotFoundException;
|
||||||
|
import org.apache.fineract.portfolio.rate.data.RateData;
|
||||||
|
import org.apache.fineract.portfolio.rate.service.RateReadService;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.dao.EmptyResultDataAccessException;
|
import org.springframework.dao.EmptyResultDataAccessException;
|
||||||
@@ -55,16 +57,18 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
private final ChargeReadPlatformService chargeReadPlatformService;
|
private final ChargeReadPlatformService chargeReadPlatformService;
|
||||||
|
private final RateReadService rateReadService;
|
||||||
private final FineractEntityAccessUtil fineractEntityAccessUtil;
|
private final FineractEntityAccessUtil fineractEntityAccessUtil;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanProductReadPlatformServiceImpl(final PlatformSecurityContext context,
|
public LoanProductReadPlatformServiceImpl(final PlatformSecurityContext context,
|
||||||
final ChargeReadPlatformService chargeReadPlatformService, final RoutingDataSource dataSource,
|
final ChargeReadPlatformService chargeReadPlatformService, final RoutingDataSource dataSource,
|
||||||
final FineractEntityAccessUtil fineractEntityAccessUtil) {
|
final FineractEntityAccessUtil fineractEntityAccessUtil, final RateReadService rateReadService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.chargeReadPlatformService = chargeReadPlatformService;
|
this.chargeReadPlatformService = chargeReadPlatformService;
|
||||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
this.fineractEntityAccessUtil = fineractEntityAccessUtil;
|
this.fineractEntityAccessUtil = fineractEntityAccessUtil;
|
||||||
|
this.rateReadService=rateReadService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -72,8 +76,9 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final Collection<ChargeData> charges = this.chargeReadPlatformService.retrieveLoanProductCharges(loanProductId);
|
final Collection<ChargeData> charges = this.chargeReadPlatformService.retrieveLoanProductCharges(loanProductId);
|
||||||
|
final Collection<RateData> rates = this.rateReadService.retrieveProductLoanRates(loanProductId);
|
||||||
final Collection<LoanProductBorrowerCycleVariationData> borrowerCycleVariationDatas = retrieveLoanProductBorrowerCycleVariations(loanProductId);
|
final Collection<LoanProductBorrowerCycleVariationData> borrowerCycleVariationDatas = retrieveLoanProductBorrowerCycleVariations(loanProductId);
|
||||||
final LoanProductMapper rm = new LoanProductMapper(charges, borrowerCycleVariationDatas);
|
final LoanProductMapper rm = new LoanProductMapper(charges, borrowerCycleVariationDatas, rates);
|
||||||
final String sql = "select " + rm.loanProductSchema() + " where lp.id = ?";
|
final String sql = "select " + rm.loanProductSchema() + " where lp.id = ?";
|
||||||
|
|
||||||
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { loanProductId });
|
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { loanProductId });
|
||||||
@@ -95,7 +100,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
|
|
||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
|
|
||||||
final LoanProductMapper rm = new LoanProductMapper(null, null);
|
final LoanProductMapper rm = new LoanProductMapper(null, null, null);
|
||||||
|
|
||||||
String sql = "select " + rm.loanProductSchema();
|
String sql = "select " + rm.loanProductSchema();
|
||||||
|
|
||||||
@@ -172,10 +177,13 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
|
|
||||||
private final Collection<LoanProductBorrowerCycleVariationData> borrowerCycleVariationDatas;
|
private final Collection<LoanProductBorrowerCycleVariationData> borrowerCycleVariationDatas;
|
||||||
|
|
||||||
|
private final Collection<RateData> rates;
|
||||||
|
|
||||||
public LoanProductMapper(final Collection<ChargeData> charges,
|
public LoanProductMapper(final Collection<ChargeData> charges,
|
||||||
final Collection<LoanProductBorrowerCycleVariationData> borrowerCycleVariationDatas) {
|
final Collection<LoanProductBorrowerCycleVariationData> borrowerCycleVariationDatas, final Collection<RateData> rates) {
|
||||||
this.charges = charges;
|
this.charges = charges;
|
||||||
this.borrowerCycleVariationDatas = borrowerCycleVariationDatas;
|
this.borrowerCycleVariationDatas = borrowerCycleVariationDatas;
|
||||||
|
this.rates = rates;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String loanProductSchema() {
|
public String loanProductSchema() {
|
||||||
@@ -448,6 +456,8 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
final boolean syncExpectedWithDisbursementDate = rs.getBoolean("syncExpectedWithDisbursementDate");
|
final boolean syncExpectedWithDisbursementDate = rs.getBoolean("syncExpectedWithDisbursementDate");
|
||||||
|
|
||||||
final boolean canUseForTopup = rs.getBoolean("canUseForTopup");
|
final boolean canUseForTopup = rs.getBoolean("canUseForTopup");
|
||||||
|
final Collection<RateData> rateOptions= null;
|
||||||
|
final boolean isRatesEnabled = false;
|
||||||
|
|
||||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||||
@@ -464,7 +474,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
installmentAmountInMultiplesOf, allowAttributeOverrides, isLinkedToFloatingInterestRates, floatingRateId,
|
installmentAmountInMultiplesOf, allowAttributeOverrides, isLinkedToFloatingInterestRates, floatingRateId,
|
||||||
floatingRateName, interestRateDifferential, minDifferentialLendingRate, defaultDifferentialLendingRate,
|
floatingRateName, interestRateDifferential, minDifferentialLendingRate, defaultDifferentialLendingRate,
|
||||||
maxDifferentialLendingRate, isFloatingInterestRateCalculationAllowed, isVariableIntallmentsAllowed, minimumGap,
|
maxDifferentialLendingRate, isFloatingInterestRateCalculationAllowed, isVariableIntallmentsAllowed, minimumGap,
|
||||||
maximumGap, syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization);
|
maximumGap, syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, rateOptions, this.rates, isRatesEnabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -534,7 +544,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
public Collection<LoanProductData> retrieveAllLoanProductsForCurrency(String currencyCode) {
|
public Collection<LoanProductData> retrieveAllLoanProductsForCurrency(String currencyCode) {
|
||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
|
|
||||||
final LoanProductMapper rm = new LoanProductMapper(null, null);
|
final LoanProductMapper rm = new LoanProductMapper(null, null, null);
|
||||||
|
|
||||||
String sql = "select " + rm.loanProductSchema() + " where lp.currency_code= ? ";
|
String sql = "select " + rm.loanProductSchema() + " where lp.currency_code= ? ";
|
||||||
|
|
||||||
|
|||||||
+38
-2
@@ -49,6 +49,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
|
|||||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionProcessingStrategyRepository;
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionProcessingStrategyRepository;
|
||||||
import org.apache.fineract.portfolio.loanaccount.exception.LoanTransactionProcessingStrategyNotFoundException;
|
import org.apache.fineract.portfolio.loanaccount.exception.LoanTransactionProcessingStrategyNotFoundException;
|
||||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
||||||
|
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
|
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
|
||||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
|
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
|
||||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanTransactionProcessingStrategy;
|
import org.apache.fineract.portfolio.loanproduct.domain.LoanTransactionProcessingStrategy;
|
||||||
@@ -57,6 +58,8 @@ import org.apache.fineract.portfolio.loanproduct.exception.LoanProductCannotBeMo
|
|||||||
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductDateException;
|
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductDateException;
|
||||||
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductNotFoundException;
|
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductNotFoundException;
|
||||||
import org.apache.fineract.portfolio.loanproduct.serialization.LoanProductDataValidator;
|
import org.apache.fineract.portfolio.loanproduct.serialization.LoanProductDataValidator;
|
||||||
|
import org.apache.fineract.portfolio.rate.domain.Rate;
|
||||||
|
import org.apache.fineract.portfolio.rate.domain.RateRepositoryWrapper;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -76,6 +79,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
|||||||
private final FundRepository fundRepository;
|
private final FundRepository fundRepository;
|
||||||
private final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository;
|
private final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository;
|
||||||
private final ChargeRepositoryWrapper chargeRepository;
|
private final ChargeRepositoryWrapper chargeRepository;
|
||||||
|
private final RateRepositoryWrapper rateRepository;
|
||||||
private final ProductToGLAccountMappingWritePlatformService accountMappingWritePlatformService;
|
private final ProductToGLAccountMappingWritePlatformService accountMappingWritePlatformService;
|
||||||
private final FineractEntityAccessUtil fineractEntityAccessUtil;
|
private final FineractEntityAccessUtil fineractEntityAccessUtil;
|
||||||
private final FloatingRateRepositoryWrapper floatingRateRepository;
|
private final FloatingRateRepositoryWrapper floatingRateRepository;
|
||||||
@@ -87,7 +91,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
|||||||
final LoanProductDataValidator fromApiJsonDeserializer, final LoanProductRepository loanProductRepository,
|
final LoanProductDataValidator fromApiJsonDeserializer, final LoanProductRepository loanProductRepository,
|
||||||
final AprCalculator aprCalculator, final FundRepository fundRepository,
|
final AprCalculator aprCalculator, final FundRepository fundRepository,
|
||||||
final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository,
|
final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository,
|
||||||
final ChargeRepositoryWrapper chargeRepository,
|
final ChargeRepositoryWrapper chargeRepository, final RateRepositoryWrapper rateRepository,
|
||||||
final ProductToGLAccountMappingWritePlatformService accountMappingWritePlatformService,
|
final ProductToGLAccountMappingWritePlatformService accountMappingWritePlatformService,
|
||||||
final FineractEntityAccessUtil fineractEntityAccessUtil,
|
final FineractEntityAccessUtil fineractEntityAccessUtil,
|
||||||
final FloatingRateRepositoryWrapper floatingRateRepository,
|
final FloatingRateRepositoryWrapper floatingRateRepository,
|
||||||
@@ -100,6 +104,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
|||||||
this.fundRepository = fundRepository;
|
this.fundRepository = fundRepository;
|
||||||
this.loanTransactionProcessingStrategyRepository = loanTransactionProcessingStrategyRepository;
|
this.loanTransactionProcessingStrategyRepository = loanTransactionProcessingStrategyRepository;
|
||||||
this.chargeRepository = chargeRepository;
|
this.chargeRepository = chargeRepository;
|
||||||
|
this.rateRepository = rateRepository;
|
||||||
this.accountMappingWritePlatformService = accountMappingWritePlatformService;
|
this.accountMappingWritePlatformService = accountMappingWritePlatformService;
|
||||||
this.fineractEntityAccessUtil = fineractEntityAccessUtil;
|
this.fineractEntityAccessUtil = fineractEntityAccessUtil;
|
||||||
this.floatingRateRepository = floatingRateRepository;
|
this.floatingRateRepository = floatingRateRepository;
|
||||||
@@ -125,6 +130,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
|||||||
|
|
||||||
final String currencyCode = command.stringValueOfParameterNamed("currencyCode");
|
final String currencyCode = command.stringValueOfParameterNamed("currencyCode");
|
||||||
final List<Charge> charges = assembleListOfProductCharges(command, currencyCode);
|
final List<Charge> charges = assembleListOfProductCharges(command, currencyCode);
|
||||||
|
final List<Rate> rates = assembleListOfProductRates(command);
|
||||||
|
|
||||||
FloatingRate floatingRate = null;
|
FloatingRate floatingRate = null;
|
||||||
if(command.parameterExists("floatingRatesId")){
|
if(command.parameterExists("floatingRatesId")){
|
||||||
@@ -132,7 +138,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
|||||||
.findOneWithNotFoundDetection(command.longValueOfParameterNamed("floatingRatesId"));
|
.findOneWithNotFoundDetection(command.longValueOfParameterNamed("floatingRatesId"));
|
||||||
}
|
}
|
||||||
final LoanProduct loanproduct = LoanProduct.assembleFromJson(fund, loanTransactionProcessingStrategy, charges, command,
|
final LoanProduct loanproduct = LoanProduct.assembleFromJson(fund, loanTransactionProcessingStrategy, charges, command,
|
||||||
this.aprCalculator, floatingRate);
|
this.aprCalculator, floatingRate, rates);
|
||||||
loanproduct.updateLoanProductInRelatedClasses();
|
loanproduct.updateLoanProductInRelatedClasses();
|
||||||
|
|
||||||
this.loanProductRepository.save(loanproduct);
|
this.loanProductRepository.save(loanproduct);
|
||||||
@@ -237,6 +243,14 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
|||||||
.updateLoanProductToGLAccountMapping(product.getId(), command, accountingTypeChanged, product.getAccountingType());
|
.updateLoanProductToGLAccountMapping(product.getId(), command, accountingTypeChanged, product.getAccountingType());
|
||||||
changes.putAll(accountingMappingChanges);
|
changes.putAll(accountingMappingChanges);
|
||||||
|
|
||||||
|
if (changes.containsKey(LoanProductConstants.ratesParamName)) {
|
||||||
|
final List<Rate> productRates = assembleListOfProductRates(command);
|
||||||
|
final boolean updated = product.updateRates(productRates);
|
||||||
|
if (!updated) {
|
||||||
|
changes.remove(LoanProductConstants.ratesParamName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!changes.isEmpty()) {
|
if (!changes.isEmpty()) {
|
||||||
this.loanProductRepository.saveAndFlush(product);
|
this.loanProductRepository.saveAndFlush(product);
|
||||||
}
|
}
|
||||||
@@ -299,6 +313,28 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
|||||||
return charges;
|
return charges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Rate> assembleListOfProductRates(final JsonCommand command) {
|
||||||
|
|
||||||
|
final List<Rate> rates = new ArrayList<>();
|
||||||
|
|
||||||
|
if (command.parameterExists("rates")) {
|
||||||
|
final JsonArray ratesArray = command.arrayOfParameterNamed("rates");
|
||||||
|
if (ratesArray != null) {
|
||||||
|
List<Long> idList = new ArrayList<>();
|
||||||
|
for (int i = 0; i < ratesArray.size(); i++) {
|
||||||
|
|
||||||
|
final JsonObject jsonObject = ratesArray.get(i).getAsJsonObject();
|
||||||
|
if (jsonObject.has("id")) {
|
||||||
|
idList.add(jsonObject.get("id").getAsLong());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rates.addAll(this.rateRepository.findMultipleWithNotFoundDetection(idList));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rates;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Guaranteed to throw an exception no matter what the data integrity issue
|
* Guaranteed to throw an exception no matter what the data integrity issue
|
||||||
* is.
|
* is.
|
||||||
|
|||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.portfolio.rate.api;
|
||||||
|
|
||||||
|
public class RateApiConstants {
|
||||||
|
|
||||||
|
public static final String approveUserIdParamName = "approveUserId";
|
||||||
|
public static final String rate = "rate";
|
||||||
|
public static final String rateName = "name";
|
||||||
|
public static final String ratePercentage = "percentage";
|
||||||
|
public static final String rateProductApply = "productApply";
|
||||||
|
|
||||||
|
}
|
||||||
+137
@@ -0,0 +1,137 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.fineract.portfolio.rate.api;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||||
|
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
||||||
|
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||||
|
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||||
|
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||||
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.apache.fineract.portfolio.rate.data.RateData;
|
||||||
|
import org.apache.fineract.portfolio.rate.service.RateReadService;
|
||||||
|
import org.apache.fineract.portfolio.rate.service.RateWriteService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.ws.rs.*;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bowpi GT Created by Jose on 19/07/2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Path("/rates")
|
||||||
|
@Component
|
||||||
|
@Scope("singleton")
|
||||||
|
public class RateApiResource {
|
||||||
|
|
||||||
|
private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(
|
||||||
|
Arrays.asList("id", "name", "percentage", "productApply", "active"));
|
||||||
|
private final String resourceNameForPermissions = "RATE";
|
||||||
|
private final PlatformSecurityContext context;
|
||||||
|
private final RateReadService readPlatformService;
|
||||||
|
private final DefaultToApiJsonSerializer<RateData> toApiJsonSerializer;
|
||||||
|
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||||
|
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public RateApiResource(final PlatformSecurityContext context,
|
||||||
|
final RateReadService rateReadService,
|
||||||
|
final DefaultToApiJsonSerializer<RateData> toApiJsonSerializer,
|
||||||
|
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||||
|
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
|
||||||
|
this.context = context;
|
||||||
|
this.readPlatformService = rateReadService;
|
||||||
|
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||||
|
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||||
|
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{rateId}")
|
||||||
|
@Consumes({MediaType.APPLICATION_JSON})
|
||||||
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
|
public String retrieveRate(@PathParam("rateId") Long rateId, @Context final UriInfo uriInfo) {
|
||||||
|
|
||||||
|
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
|
||||||
|
|
||||||
|
final RateData rate = this.readPlatformService.retrieveOne(rateId);
|
||||||
|
|
||||||
|
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper
|
||||||
|
.process(uriInfo.getQueryParameters());
|
||||||
|
|
||||||
|
return this.toApiJsonSerializer.serialize(settings, rate, this.RESPONSE_DATA_PARAMETERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Consumes({MediaType.APPLICATION_JSON})
|
||||||
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
|
public String createRate(final String apiRequestBodyAsJson) {
|
||||||
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().createRate()
|
||||||
|
.withJson(apiRequestBodyAsJson).build();
|
||||||
|
|
||||||
|
final CommandProcessingResult result = this.commandsSourceWritePlatformService
|
||||||
|
.logCommandSource(commandRequest);
|
||||||
|
|
||||||
|
return this.toApiJsonSerializer.serialize(result);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Consumes({MediaType.APPLICATION_JSON})
|
||||||
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
|
public String getAllRates(@Context final UriInfo uriInfo) {
|
||||||
|
|
||||||
|
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
|
||||||
|
|
||||||
|
Collection<RateData> rates = this.readPlatformService.retrieveAllRates();
|
||||||
|
|
||||||
|
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper
|
||||||
|
.process(uriInfo.getQueryParameters());
|
||||||
|
|
||||||
|
return this.toApiJsonSerializer.serialize(settings, rates, this.RESPONSE_DATA_PARAMETERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("{rateId}")
|
||||||
|
@Consumes({MediaType.APPLICATION_JSON})
|
||||||
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
|
public String updateRate(@PathParam("rateId") Long rateId, final String apiRequestBodyAsJson) {
|
||||||
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateRate(rateId)
|
||||||
|
.withJson(apiRequestBodyAsJson).build();
|
||||||
|
|
||||||
|
final CommandProcessingResult result = this.commandsSourceWritePlatformService
|
||||||
|
.logCommandSource(commandRequest);
|
||||||
|
|
||||||
|
return this.toApiJsonSerializer.serialize(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.fineract.portfolio.rate.data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bowpi GT Created by Jose on 19/07/2017.
|
||||||
|
*/
|
||||||
|
public class RateData implements Serializable {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private BigDecimal percentage;
|
||||||
|
|
||||||
|
private String productApply;
|
||||||
|
|
||||||
|
private boolean active;
|
||||||
|
|
||||||
|
public static RateData instance(final Long id, final String name, final BigDecimal percentage,
|
||||||
|
final String productApply, final boolean active) {
|
||||||
|
return new RateData(id, name, percentage, productApply, active);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RateData(final Long id, final String name, final BigDecimal percentage,
|
||||||
|
final String productApply, final boolean active) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.percentage = percentage;
|
||||||
|
this.productApply = productApply;
|
||||||
|
this.active = active;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,201 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.fineract.portfolio.rate.domain;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bowpi GT Created by Jose on 19/07/2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "m_rate", uniqueConstraints = {
|
||||||
|
@UniqueConstraint(columnNames = {"name"}, name = "name")})
|
||||||
|
public class Rate extends AbstractAuditableCustom<AppUser, Long> {
|
||||||
|
|
||||||
|
@Column(name = "name", length = 250, unique = true)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(name = "percentage", scale = 10, precision = 2, nullable = false)
|
||||||
|
private BigDecimal percentage;
|
||||||
|
|
||||||
|
@Column(name = "product_apply", length = 100)
|
||||||
|
private String productApply;
|
||||||
|
|
||||||
|
@Column(name = "active", nullable = false)
|
||||||
|
private boolean active;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "approve_user", nullable = true)
|
||||||
|
private AppUser approveUser;
|
||||||
|
|
||||||
|
|
||||||
|
public Rate() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Rate(String name, BigDecimal percentage, String productApply, boolean active,
|
||||||
|
AppUser approveUser) {
|
||||||
|
this.name = name;
|
||||||
|
this.percentage = percentage;
|
||||||
|
this.productApply = productApply;
|
||||||
|
this.active = active;
|
||||||
|
this.approveUser = approveUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rate(String name, BigDecimal percentage, String productApply, boolean active) {
|
||||||
|
this.name = name;
|
||||||
|
this.percentage = percentage;
|
||||||
|
this.productApply = productApply;
|
||||||
|
this.active = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getPercentage() {
|
||||||
|
return percentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPercentage(BigDecimal percentage) {
|
||||||
|
this.percentage = percentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActive() {
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActive(boolean active) {
|
||||||
|
this.active = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AppUser getApproveUser() {
|
||||||
|
return approveUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApproveUser(AppUser approveUser) {
|
||||||
|
this.approveUser = approveUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProductApply() {
|
||||||
|
return productApply;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProductApply(String productApply) {
|
||||||
|
this.productApply = productApply;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Rate{" +
|
||||||
|
"name='" + name + '\'' +
|
||||||
|
", percentage=" + percentage +
|
||||||
|
", productApply='" + productApply + '\'' +
|
||||||
|
", active=" + active +
|
||||||
|
", approveUser=" + approveUser +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Rate from(String name, BigDecimal percentage, String productApply, Boolean active) {
|
||||||
|
return new Rate(name, percentage, productApply, active);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Rate fromJson(final JsonCommand command, AppUser user) {
|
||||||
|
|
||||||
|
final String name = command.stringValueOfParameterNamed("name");
|
||||||
|
|
||||||
|
final BigDecimal percentage = command.bigDecimalValueOfParameterNamed("percentage");
|
||||||
|
|
||||||
|
final String productApply = command.stringValueOfParameterNamed("productApply");
|
||||||
|
|
||||||
|
final boolean active = command.booleanPrimitiveValueOfParameterNamed("active");
|
||||||
|
|
||||||
|
return new Rate(name, percentage, productApply, active, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> update(final JsonCommand command) {
|
||||||
|
|
||||||
|
final Map<String, Object> actualChanges = new LinkedHashMap<>(7);
|
||||||
|
|
||||||
|
final String nameParamName = "name";
|
||||||
|
if (command.isChangeInStringParameterNamed(nameParamName, this.name)) {
|
||||||
|
final String newValue = command.stringValueOfParameterNamed(nameParamName);
|
||||||
|
actualChanges.put(nameParamName, newValue);
|
||||||
|
this.name = StringUtils.defaultIfEmpty(newValue, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String percentageParamName = "percentage";
|
||||||
|
if (command.isChangeInBigDecimalParameterNamed(percentageParamName, this.percentage)) {
|
||||||
|
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(percentageParamName);
|
||||||
|
actualChanges.put(percentageParamName, newValue);
|
||||||
|
this.percentage = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String productApplyParamName = "productApply";
|
||||||
|
if (command.isChangeInStringParameterNamed(productApplyParamName, this.productApply)) {
|
||||||
|
final String newValue = command.stringValueOfParameterNamed(productApplyParamName);
|
||||||
|
actualChanges.put(productApplyParamName, newValue);
|
||||||
|
this.productApply = StringUtils.defaultIfEmpty(newValue, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String activeParamName = "active";
|
||||||
|
if (command.isChangeInBooleanParameterNamed(activeParamName, this.active)) {
|
||||||
|
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(activeParamName);
|
||||||
|
actualChanges.put(activeParamName, newValue);
|
||||||
|
this.active = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String approveUserParamName = "approveUserId";
|
||||||
|
if (command.isChangeInLongParameterNamed(approveUserParamName, getApproveUserId())) {
|
||||||
|
final Long newValue = command.longValueOfParameterNamed(approveUserParamName);
|
||||||
|
actualChanges.put(approveUserParamName, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return actualChanges;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long getApproveUserId() {
|
||||||
|
Long approveUserId = null;
|
||||||
|
if (this.approveUser != null) {
|
||||||
|
approveUserId = this.approveUser.getId();
|
||||||
|
}
|
||||||
|
return approveUserId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assembleFrom(String name, BigDecimal percentage, String productApply, boolean active){
|
||||||
|
this.name = name;
|
||||||
|
this.percentage = percentage;
|
||||||
|
this.productApply = productApply;
|
||||||
|
this.active = active;
|
||||||
|
}
|
||||||
|
}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.portfolio.rate.domain;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bowpi GT
|
||||||
|
* Rate repository to save on m_rate table (custom change for Credi Chapin)
|
||||||
|
* Created by Jose on 19/07/2017.
|
||||||
|
*/
|
||||||
|
public interface RateRepository extends JpaRepository<Rate, Long>, JpaSpecificationExecutor<Rate> {
|
||||||
|
|
||||||
|
Rate findByName(String name);
|
||||||
|
List<Rate> findAllByActiveAndProductApply(boolean active, String productApply);
|
||||||
|
|
||||||
|
}
|
||||||
+70
@@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.portfolio.rate.domain;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.apache.fineract.portfolio.rate.exception.RateNotFoundException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class RateRepositoryWrapper {
|
||||||
|
|
||||||
|
private final RateRepository repository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public RateRepositoryWrapper(final RateRepository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rate findOneWithNotFoundDetection(final Long rateId) {
|
||||||
|
|
||||||
|
final Rate rate = this.repository.findOne(rateId);
|
||||||
|
if (rate == null) {
|
||||||
|
throw new RateNotFoundException(rateId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Rate> findMultipleWithNotFoundDetection(final List<Long> rateIds) {
|
||||||
|
List<Rate> rates = new ArrayList<>();
|
||||||
|
if (rateIds != null && !rateIds.isEmpty()) {
|
||||||
|
final List<Rate> foundRates = this.repository.findAll(rateIds);
|
||||||
|
for (Long rateId : rateIds) {
|
||||||
|
Boolean found = false;
|
||||||
|
for (Rate foundRate : foundRates) {
|
||||||
|
if (Objects.equals(foundRate.getId(),
|
||||||
|
rateId)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
throw new RateNotFoundException(rateId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rates.addAll(foundRates);
|
||||||
|
}
|
||||||
|
return rates;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.portfolio.rate.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bowpi GT
|
||||||
|
* Created by Jose on 24/07/2017.
|
||||||
|
*/
|
||||||
|
public class RateAlreadyExistException extends Exception{
|
||||||
|
|
||||||
|
public RateAlreadyExistException(String s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.fineract.portfolio.rate.exception;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||||
|
|
||||||
|
public class RateNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||||
|
|
||||||
|
|
||||||
|
public RateNotFoundException(final Long id) {
|
||||||
|
super("error.msg.rate.id.invalid", "Rate with identifier " + id + " does not exist", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateNotFoundException(final String name) {
|
||||||
|
super("error.msg.rate.id.invalid", "Rate with name " + name + " does not exist", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.portfolio.rate.handler;
|
||||||
|
|
||||||
|
import org.apache.fineract.commands.annotation.CommandType;
|
||||||
|
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||||
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
import org.apache.fineract.portfolio.rate.service.RateWriteService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bowpi GT
|
||||||
|
* Created by Jose on 19/07/2017.
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@CommandType(entity = "RATE", action = "CREATE")
|
||||||
|
public class CreateRateCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
|
private final RateWriteService writePlatformService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public CreateRateCommandHandler(final RateWriteService writePlatformService) {
|
||||||
|
this.writePlatformService = writePlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||||
|
return this.writePlatformService.createRate(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.portfolio.rate.handler;
|
||||||
|
|
||||||
|
import org.apache.fineract.commands.annotation.CommandType;
|
||||||
|
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||||
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
import org.apache.fineract.portfolio.rate.service.RateWriteService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bowpi GT
|
||||||
|
* Created by Jose on 19/07/2017.
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@CommandType(entity = "RATE", action = "UPDATE")
|
||||||
|
public class UpdateRateCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
|
private final RateWriteService writePlatformService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public UpdateRateCommandHandler(final RateWriteService writePlatformService) {
|
||||||
|
this.writePlatformService = writePlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||||
|
|
||||||
|
return this.writePlatformService.updateRate(command.entityId(), command);
|
||||||
|
}
|
||||||
|
}
|
||||||
+129
@@ -0,0 +1,129 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.portfolio.rate.serialization;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||||
|
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
|
||||||
|
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
|
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||||
|
import org.apache.fineract.portfolio.rate.api.RateApiConstants;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class RateDefinitionCommandFromApiJsonDeserializer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameters supported for this command.
|
||||||
|
*/
|
||||||
|
private final Set<String> supportedParameters = new HashSet<>(
|
||||||
|
Arrays.asList("id", "name", "percentage", "productApply", "active", "approveUser", "locale"));
|
||||||
|
|
||||||
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public RateDefinitionCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
|
||||||
|
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validateForCreate(final String json) {
|
||||||
|
if (StringUtils.isBlank(json)) {
|
||||||
|
throw new InvalidJsonException();
|
||||||
|
}
|
||||||
|
|
||||||
|
final Type typeOfMap = new TypeToken<Map<String, Object>>() {
|
||||||
|
}.getType();
|
||||||
|
|
||||||
|
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters);
|
||||||
|
|
||||||
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||||
|
|
||||||
|
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||||
|
.resource(RateApiConstants.rateName);
|
||||||
|
|
||||||
|
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||||
|
|
||||||
|
final String name = this.fromApiJsonHelper.extractStringNamed(RateApiConstants.rateName, element);
|
||||||
|
baseDataValidator.reset().parameter(RateApiConstants.rateName).value(name).notBlank().notExceedingLengthOf(250);
|
||||||
|
|
||||||
|
final BigDecimal percentage = this.fromApiJsonHelper
|
||||||
|
.extractBigDecimalWithLocaleNamed(RateApiConstants.ratePercentage, element);
|
||||||
|
baseDataValidator.reset().parameter(RateApiConstants.ratePercentage).value(percentage).notBlank();
|
||||||
|
|
||||||
|
final String productApply = this.fromApiJsonHelper.extractStringNamed(RateApiConstants.rateProductApply, element);
|
||||||
|
baseDataValidator.reset().parameter(RateApiConstants.rateProductApply).value(productApply).notBlank()
|
||||||
|
.notExceedingLengthOf(100);
|
||||||
|
|
||||||
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validateForUpdate(final String json) {
|
||||||
|
if (StringUtils.isBlank(json)) {
|
||||||
|
throw new InvalidJsonException();
|
||||||
|
}
|
||||||
|
|
||||||
|
final Type typeOfMap = new TypeToken<Map<String, Object>>() {
|
||||||
|
}.getType();
|
||||||
|
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters);
|
||||||
|
|
||||||
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||||
|
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||||
|
.resource(RateApiConstants.rate);
|
||||||
|
|
||||||
|
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||||
|
|
||||||
|
if (this.fromApiJsonHelper.parameterExists(RateApiConstants.rateName, element)) {
|
||||||
|
final String name = this.fromApiJsonHelper.extractStringNamed(RateApiConstants.rateName, element);
|
||||||
|
baseDataValidator.reset().parameter(RateApiConstants.rateName).value(name).notBlank().notExceedingLengthOf(250);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.fromApiJsonHelper.parameterExists(RateApiConstants.ratePercentage, element)) {
|
||||||
|
final BigDecimal percentage = this.fromApiJsonHelper
|
||||||
|
.extractBigDecimalWithLocaleNamed(RateApiConstants.ratePercentage, element);
|
||||||
|
baseDataValidator.reset().parameter(RateApiConstants.ratePercentage).value(percentage).notBlank();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.fromApiJsonHelper.parameterExists(RateApiConstants.rateProductApply, element)) {
|
||||||
|
final String productApply = this.fromApiJsonHelper.extractStringNamed(RateApiConstants.rateProductApply, element);
|
||||||
|
baseDataValidator.reset().parameter(RateApiConstants.rateProductApply).value(productApply).notBlank();
|
||||||
|
}
|
||||||
|
|
||||||
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void throwExceptionIfValidationWarningsExist(
|
||||||
|
final List<ApiParameterError> dataValidationErrors) {
|
||||||
|
if (!dataValidationErrors.isEmpty()) {
|
||||||
|
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+80
@@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.portfolio.rate.service;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||||
|
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||||
|
import org.apache.fineract.portfolio.rate.domain.Rate;
|
||||||
|
import org.apache.fineract.portfolio.rate.domain.RateRepositoryWrapper;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class RateAssembler {
|
||||||
|
|
||||||
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
|
private final RateRepositoryWrapper rateRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public RateAssembler(final FromJsonHelper fromApiJsonHelper,
|
||||||
|
final RateRepositoryWrapper rateRepository) {
|
||||||
|
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||||
|
this.rateRepository = rateRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Rate> fromParsedJson(final JsonElement element) {
|
||||||
|
|
||||||
|
final List<Rate> rateItems = new ArrayList<>();
|
||||||
|
|
||||||
|
if (element.isJsonObject()) {
|
||||||
|
final JsonObject topLevelJsonElement = element.getAsJsonObject();
|
||||||
|
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement);
|
||||||
|
|
||||||
|
if (topLevelJsonElement.has(LoanProductConstants.ratesParamName) && topLevelJsonElement
|
||||||
|
.get(LoanProductConstants.ratesParamName)
|
||||||
|
.isJsonArray()) {
|
||||||
|
final JsonArray array = topLevelJsonElement.get(LoanProductConstants.ratesParamName)
|
||||||
|
.getAsJsonArray();
|
||||||
|
List<Long> idList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < array.size(); i++) {
|
||||||
|
|
||||||
|
final JsonObject rateElement = array.get(i).getAsJsonObject();
|
||||||
|
|
||||||
|
final Long id = this.fromApiJsonHelper.extractLongNamed("id", rateElement);
|
||||||
|
|
||||||
|
if (id != null) {
|
||||||
|
final Long rateId = this.fromApiJsonHelper.extractLongNamed("id", rateElement);
|
||||||
|
idList.add(rateId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rateItems.addAll(rateRepository.findMultipleWithNotFoundDetection(idList));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rateItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.portfolio.rate.service;
|
||||||
|
|
||||||
|
import org.apache.fineract.portfolio.rate.data.RateData;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bowpi GT
|
||||||
|
* Created by Jose on 19/07/2017.
|
||||||
|
*/
|
||||||
|
public interface RateReadService {
|
||||||
|
|
||||||
|
Collection<RateData> retrieveAllRates();
|
||||||
|
|
||||||
|
Collection<RateData> retrieveLoanApplicableRates();
|
||||||
|
|
||||||
|
RateData retrieveOne(Long rateId);
|
||||||
|
|
||||||
|
RateData retrieveByName(String name);
|
||||||
|
|
||||||
|
List<RateData> retrieveProductLoanRates(Long loanId);
|
||||||
|
|
||||||
|
List<RateData> retrieveLoanRates(Long loanId);
|
||||||
|
|
||||||
|
}
|
||||||
+150
@@ -0,0 +1,150 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.fineract.portfolio.rate.service;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
|
||||||
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.apache.fineract.portfolio.rate.exception.RateNotFoundException;
|
||||||
|
import org.apache.fineract.portfolio.rate.domain.Rate;
|
||||||
|
import org.apache.fineract.portfolio.rate.data.RateData;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.dao.EmptyResultDataAccessException;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bowpi GT Created by Jose on 19/07/2017.
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class RateReadServiceImpl implements RateReadService {
|
||||||
|
|
||||||
|
private final JdbcTemplate jdbcTemplate;
|
||||||
|
private final PlatformSecurityContext context;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public RateReadServiceImpl(PlatformSecurityContext context, final RoutingDataSource dataSource) {
|
||||||
|
this.context = context;
|
||||||
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<RateData> retrieveAllRates() {
|
||||||
|
this.context.authenticatedUser();
|
||||||
|
final RateMapper rm = new RateMapper();
|
||||||
|
final String sql = "select " + rm.rateSchema();
|
||||||
|
return this.jdbcTemplate.query(sql, rm, new Object[]{});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RateData retrieveOne(Long rateId) {
|
||||||
|
try {
|
||||||
|
this.context.authenticatedUser();
|
||||||
|
final RateMapper rm = new RateMapper();
|
||||||
|
final String sql = "select " + rm.rateSchema() + " where r.id = ?";
|
||||||
|
final RateData selectedRate = this.jdbcTemplate.queryForObject(sql, rm, new Object[]{rateId});
|
||||||
|
return selectedRate;
|
||||||
|
|
||||||
|
} catch (final EmptyResultDataAccessException e) {
|
||||||
|
throw new RateNotFoundException(rateId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RateData retrieveByName(String name) {
|
||||||
|
try {
|
||||||
|
this.context.authenticatedUser();
|
||||||
|
final RateMapper rm = new RateMapper();
|
||||||
|
final String sql = "select " + rm.rateSchema() + " where r.name = ?";
|
||||||
|
final RateData selectedRate = this.jdbcTemplate.queryForObject(sql, rm, new Object[]{name});
|
||||||
|
return selectedRate;
|
||||||
|
|
||||||
|
} catch (final EmptyResultDataAccessException e) {
|
||||||
|
throw new RateNotFoundException(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<RateData> retrieveLoanApplicableRates() {
|
||||||
|
this.context.authenticatedUser();
|
||||||
|
final RateMapper rm = new RateMapper();
|
||||||
|
final String sql = "select " + rm.rateSchema() + " where r.active = ? and product_apply=?";
|
||||||
|
return this.jdbcTemplate.query(sql, rm, new Object[]{true, "m_loan"});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RateData> retrieveLoanRates(Long loanId) {
|
||||||
|
final RateMapper rm = new RateMapper();
|
||||||
|
final String sql = "select " + rm.loanRateSchema() + " where lr.loan_id = ?";
|
||||||
|
return this.jdbcTemplate.query(sql, rm, new Object[]{loanId});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RateData> retrieveProductLoanRates(Long loanId) {
|
||||||
|
final RateMapper rm = new RateMapper();
|
||||||
|
final String sql = "select " + rm.productLoanRateSchema() + " where lr.product_loan_id = ?";
|
||||||
|
return this.jdbcTemplate.query(sql, rm, new Object[]{loanId});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class RateMapper implements RowMapper<RateData> {
|
||||||
|
|
||||||
|
|
||||||
|
public String rateSchema() {
|
||||||
|
return " r.id as id, r.name as name, r.percentage as percentage, " +
|
||||||
|
"r.product_apply as productApply, r.active as active from m_rate r ";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String loanRateSchema() {
|
||||||
|
return rateSchema() + " join m_loan_rate lr on lr.rate_id = r.id";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String productLoanRateSchema() {
|
||||||
|
return rateSchema() + " join m_product_loan_rate lr on lr.rate_id = r.id";
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RateData mapRow(ResultSet resultSet, int i) throws SQLException {
|
||||||
|
final Long id = resultSet.getLong("id");
|
||||||
|
final String name = resultSet.getString("name");
|
||||||
|
final BigDecimal percentage = resultSet.getBigDecimal("percentage");
|
||||||
|
final String productApply = resultSet.getString("productApply");
|
||||||
|
final boolean active = resultSet.getBoolean("active");
|
||||||
|
return RateData.instance(id, name, percentage, productApply, active);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateData mapRow(Rate rateResponse, int i) {
|
||||||
|
final Long id = rateResponse.getId();
|
||||||
|
final String name = rateResponse.getName();
|
||||||
|
final BigDecimal percentage = rateResponse.getPercentage();
|
||||||
|
final String productApply = rateResponse.getProductApply();
|
||||||
|
final boolean active = rateResponse.isActive();
|
||||||
|
return RateData.instance(id, name, percentage, productApply, active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.portfolio.rate.service;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bowpi GT
|
||||||
|
* Created by Jose on 19/07/2017.
|
||||||
|
*/
|
||||||
|
public interface RateWriteService {
|
||||||
|
|
||||||
|
CommandProcessingResult createRate(final JsonCommand command);
|
||||||
|
|
||||||
|
CommandProcessingResult updateRate(Long rateId, JsonCommand command);
|
||||||
|
|
||||||
|
}
|
||||||
+157
@@ -0,0 +1,157 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.portfolio.rate.service;
|
||||||
|
|
||||||
|
import static org.apache.fineract.portfolio.rate.api.RateApiConstants.approveUserIdParamName;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.persistence.PersistenceException;
|
||||||
|
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||||
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||||
|
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||||
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.apache.fineract.portfolio.rate.domain.Rate;
|
||||||
|
import org.apache.fineract.portfolio.rate.domain.RateRepository;
|
||||||
|
import org.apache.fineract.portfolio.rate.exception.RateNotFoundException;
|
||||||
|
import org.apache.fineract.portfolio.rate.serialization.RateDefinitionCommandFromApiJsonDeserializer;
|
||||||
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
|
import org.apache.fineract.useradministration.domain.AppUserRepository;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bowpi GT Created by Jose on 19/07/2017.
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class RateWriteServiceImpl implements RateWriteService {
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory
|
||||||
|
.getLogger(RateWriteServiceImpl.class);
|
||||||
|
private final RateRepository rateRepository;
|
||||||
|
private final AppUserRepository appUserRepository;
|
||||||
|
private final PlatformSecurityContext context;
|
||||||
|
private final RateDefinitionCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public RateWriteServiceImpl(RateRepository rateRepository, AppUserRepository appUserRepository,
|
||||||
|
final RateDefinitionCommandFromApiJsonDeserializer fromApiJsonDeserializer,
|
||||||
|
PlatformSecurityContext context) {
|
||||||
|
this.rateRepository = rateRepository;
|
||||||
|
this.appUserRepository = appUserRepository;
|
||||||
|
this.context = context;
|
||||||
|
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult createRate(JsonCommand command) {
|
||||||
|
try {
|
||||||
|
this.context.authenticatedUser();
|
||||||
|
this.fromApiJsonDeserializer.validateForCreate(command.json());
|
||||||
|
|
||||||
|
final Long approveUserId = command.longValueOfParameterNamed(approveUserIdParamName);
|
||||||
|
AppUser approveUser = null;
|
||||||
|
if (approveUserId != null) {
|
||||||
|
approveUser = this.appUserRepository.findOne(approveUserId);
|
||||||
|
}
|
||||||
|
final Rate rate = Rate.fromJson(command, approveUser);
|
||||||
|
|
||||||
|
this.rateRepository.save(rate);
|
||||||
|
|
||||||
|
return new CommandProcessingResultBuilder().withCommandId(command.commandId())
|
||||||
|
.withEntityId(rate.getId()).build();
|
||||||
|
|
||||||
|
} catch (final DataIntegrityViolationException dve) {
|
||||||
|
handleRateDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
|
||||||
|
return CommandProcessingResult.empty();
|
||||||
|
} catch (final PersistenceException dve) {
|
||||||
|
Throwable throwable = ExceptionUtils.getRootCause(dve.getCause());
|
||||||
|
handleRateDataIntegrityIssues(command, throwable, dve);
|
||||||
|
return CommandProcessingResult.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult updateRate(final Long rateId, final JsonCommand command) {
|
||||||
|
try {
|
||||||
|
this.context.authenticatedUser();
|
||||||
|
|
||||||
|
final Rate rateToUpdate = this.rateRepository.findOne(rateId);
|
||||||
|
if (rateToUpdate == null) {
|
||||||
|
throw new RateNotFoundException(rateId);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<String, Object> changes = rateToUpdate.update(command);
|
||||||
|
|
||||||
|
this.fromApiJsonDeserializer.validateForUpdate(command.json());
|
||||||
|
|
||||||
|
if (changes.containsKey(approveUserIdParamName)) {
|
||||||
|
final Long newValue = (Long) changes.get(approveUserIdParamName);
|
||||||
|
AppUser newApproveUser = null;
|
||||||
|
if (newValue != null) {
|
||||||
|
newApproveUser = this.appUserRepository.findOne(newValue);
|
||||||
|
}
|
||||||
|
rateToUpdate.setApproveUser(newApproveUser);
|
||||||
|
}
|
||||||
|
if (!changes.isEmpty()) {
|
||||||
|
this.rateRepository.saveAndFlush(rateToUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CommandProcessingResultBuilder() //
|
||||||
|
.withCommandId(command.commandId()) //
|
||||||
|
.withEntityId(rateId) //
|
||||||
|
.with(changes) //
|
||||||
|
.build();
|
||||||
|
|
||||||
|
} catch (final DataIntegrityViolationException dve) {
|
||||||
|
handleRateDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
|
||||||
|
return new CommandProcessingResult(Long.valueOf(-1));
|
||||||
|
} catch (final PersistenceException dve) {
|
||||||
|
Throwable throwable = ExceptionUtils.getRootCause(dve.getCause());
|
||||||
|
handleRateDataIntegrityIssues(command, throwable, dve);
|
||||||
|
return CommandProcessingResult.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Guaranteed to throw an exception no matter what the data integrity issue
|
||||||
|
* is.
|
||||||
|
*/
|
||||||
|
private void handleRateDataIntegrityIssues(final JsonCommand command, final Throwable realCause,
|
||||||
|
final Exception dve) {
|
||||||
|
if (realCause.getMessage().contains("rate_name_org")) {
|
||||||
|
final String name = command.stringValueOfParameterNamed("name");
|
||||||
|
throw new PlatformDataIntegrityException("error.msg.fund.duplicate.externalId",
|
||||||
|
"A rate with name '" + name
|
||||||
|
+ "' already exists", "name", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.error(dve.getMessage(), dve);
|
||||||
|
throw new PlatformDataIntegrityException("error.msg.fund.unknown.data.integrity.issue",
|
||||||
|
"Unknown data integrity issue with resource: " + realCause.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
--
|
||||||
|
-- Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
-- or more contributor license agreements. See the NOTICE file
|
||||||
|
-- distributed with this work for additional information
|
||||||
|
-- regarding copyright ownership. The ASF licenses this file
|
||||||
|
-- to you under the Apache License, Version 2.0 (the
|
||||||
|
-- "License"); you may not use this file except in compliance
|
||||||
|
-- with the License. You may obtain a copy of the License at
|
||||||
|
--
|
||||||
|
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
--
|
||||||
|
-- Unless required by applicable law or agreed to in writing,
|
||||||
|
-- software distributed under the License is distributed on an
|
||||||
|
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
-- KIND, either express or implied. See the License for the
|
||||||
|
-- specific language governing permissions and limitations
|
||||||
|
-- under the License.
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `m_rate` (
|
||||||
|
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` varchar(250) NOT NULL,
|
||||||
|
`percentage` decimal(10,2) NOT NULL,
|
||||||
|
`active` tinyint(1) DEFAULT '0',
|
||||||
|
`product_apply` varchar(100) NOT NULL,
|
||||||
|
`created_date` datetime NULL DEFAULT NULL,
|
||||||
|
`createdby_id` bigint(20) NOT NULL,
|
||||||
|
`lastmodifiedby_id` bigint(20) NOT NULL,
|
||||||
|
`lastmodified_date` datetime NULL DEFAULT NULL,
|
||||||
|
`approve_user` bigint(20) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `FK_M_RATE_CREATE_USER` (`createdby_id`),
|
||||||
|
KEY `FK_M_RATE_APPROVE_USER` (`approve_user`),
|
||||||
|
CONSTRAINT `FK_M_RATE_APPROVE_USER` FOREIGN KEY (`approve_user`) REFERENCES `m_appuser` (`id`),
|
||||||
|
CONSTRAINT `FK_M_RATE_CREATE_USER` FOREIGN KEY (`createdby_id`) REFERENCES `m_appuser` (`id`)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `m_loan_rate` (
|
||||||
|
`loan_id` bigint(20) NOT NULL,
|
||||||
|
`rate_id` bigint(20) NOT NULL,
|
||||||
|
PRIMARY KEY (`loan_id`,`rate_id`),
|
||||||
|
KEY `FK_M_LOAN_RATE_RATE` (`rate_id`),
|
||||||
|
CONSTRAINT `FK_M_LOAN_RATE_LOAN` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`),
|
||||||
|
CONSTRAINT `FK_M_LOAN_RATE_RATE` FOREIGN KEY (`rate_id`) REFERENCES `m_rate` (`id`)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `m_product_loan_rate` (
|
||||||
|
`product_loan_id` bigint(20) NOT NULL,
|
||||||
|
`rate_id` bigint(20) NOT NULL,
|
||||||
|
PRIMARY KEY (`product_loan_id`,`rate_id`),
|
||||||
|
KEY `FK_M_PRODUCT_LOAN_RATE_RATE` (`rate_id`),
|
||||||
|
CONSTRAINT `FK_M_PRODUCT_LOAN_RATE_LOAN` FOREIGN KEY (`product_loan_id`) REFERENCES `m_product_loan` (`id`),
|
||||||
|
CONSTRAINT `FK_M_PRODUCT_LOAN_RATE_RATE` FOREIGN KEY (`rate_id`) REFERENCES `m_rate` (`id`)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO `m_permission`
|
||||||
|
(`grouping`,`code`,`entity_name`,`action_name`,`can_maker_checker`) VALUES
|
||||||
|
('organisation', 'CREATE_RATE', 'RATE', 'CREATE', '1'),
|
||||||
|
('organisation', 'UPDATE_RATE', 'RATE', 'UPDATE', '1');
|
||||||
|
|
||||||
|
INSERT INTO `c_configuration`
|
||||||
|
(`name`, `value`, `enabled`, `is_trap_door`, `description`) VALUES
|
||||||
|
('vat-tax', 12, 0, 0, 'VAT tax'),
|
||||||
|
('sub-rates', 12, 0, 0, 'Enable Rates Module');;
|
||||||
Reference in New Issue
Block a user