http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index 772ea77..ac732b5 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -550,7 +550,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { + " l.principal_amount_proposed as proposedPrincipal, l.principal_amount as principal, l.approved_principal as approvedPrincipal, l.arrearstolerance_amount as inArrearsTolerance, l.number_of_repayments as numberOfRepayments, l.repay_every as repaymentEvery," + " l.grace_on_principal_periods as graceOnPrincipalPayment, l.recurring_moratorium_principal_periods as recurringMoratoriumOnPrincipalPeriods, l.grace_on_interest_periods as graceOnInterestPayment, l.grace_interest_free_periods as graceOnInterestCharged,l.grace_on_arrears_ageing as graceOnArrearsAgeing," + " l.nominal_interest_rate_per_period as interestRatePerPeriod, l.annual_nominal_interest_rate as annualInterestRate, " - + " l.repayment_period_frequency_enum as repaymentFrequencyType, l.repayment_frequency_nth_day_enum as repaymentFrequencyNthDayType, l.repayment_frequency_day_of_week_enum as repaymentFrequencyDayOfWeekType, l.interest_period_frequency_enum as interestRateFrequencyType, " + + " l.repayment_period_frequency_enum as repaymentFrequencyType, l.interest_period_frequency_enum as interestRateFrequencyType, " + " l.term_frequency as termFrequency, l.term_period_frequency_enum as termPeriodFrequencyType, " + " l.amortization_method_enum as amortizationType, l.interest_method_enum as interestType, l.interest_calculated_in_period_enum as interestCalculationPeriodType," + " l.allow_partial_period_interest_calcualtion as allowPartialPeriodInterestCalcualtion," @@ -600,9 +600,15 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { + " l.interest_recalculation_enabled as isInterestRecalculationEnabled, " + " lir.id as lirId, lir.loan_id as loanId, lir.compound_type_enum as compoundType, lir.reschedule_strategy_enum as rescheduleStrategy, " + " lir.rest_frequency_type_enum as restFrequencyEnum, lir.rest_frequency_interval as restFrequencyInterval, " - + " lir.rest_freqency_date as restFrequencyDate, " + + " lir.rest_frequency_nth_day_enum as restFrequencyNthDayEnum, " + + " lir.rest_frequency_weekday_enum as restFrequencyWeekDayEnum, " + + " lir.rest_frequency_on_day as restFrequencyOnDay, " + " lir.compounding_frequency_type_enum as compoundingFrequencyEnum, lir.compounding_frequency_interval as compoundingInterval, " - + " lir.compounding_freqency_date as compoundingFrequencyDate, " + + " lir.compounding_frequency_nth_day_enum as compoundingFrequencyNthDayEnum, " + + " lir.compounding_frequency_weekday_enum as compoundingFrequencyWeekDayEnum, " + + " lir.compounding_frequency_on_day as compoundingFrequencyOnDay, " + + " lir.is_compounding_to_be_posted_as_transaction as isCompoundingToBePostedAsTransaction, " + + " lir.allow_compounding_on_eod as allowCompoundingOnEod, " + " l.is_floating_interest_rate as isFloatingInterestRate, " + " l.interest_rate_differential as interestRateDifferential, " + " l.create_standing_instruction_at_disbursement as createStandingInstructionAtDisbursement, " @@ -752,14 +758,6 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final int repaymentFrequencyTypeInt = JdbcSupport.getInteger(rs, "repaymentFrequencyType"); final EnumOptionData repaymentFrequencyType = LoanEnumerations.repaymentFrequencyType(repaymentFrequencyTypeInt); - final Integer repaymentFrequencyNthDayTypeInt = JdbcSupport.getInteger(rs, "repaymentFrequencyNthDayType"); - final EnumOptionData repaymentFrequencyNthDayType = LoanEnumerations - .repaymentFrequencyNthDayType(repaymentFrequencyNthDayTypeInt); - - final Integer repaymentFrequencyDayOfWeekTypeInt = JdbcSupport.getInteger(rs, "repaymentFrequencyDayOfWeekType"); - final EnumOptionData repaymentFrequencyDayOfWeekType = LoanEnumerations - .repaymentFrequencyDayOfWeekType(repaymentFrequencyDayOfWeekTypeInt); - final int interestRateFrequencyTypeInt = JdbcSupport.getInteger(rs, "interestRateFrequencyType"); final EnumOptionData interestRateFrequencyType = LoanEnumerations.interestRateFrequencyType(interestRateFrequencyTypeInt); @@ -877,7 +875,18 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final int restFrequencyEnumValue = JdbcSupport.getInteger(rs, "restFrequencyEnum"); final EnumOptionData restFrequencyType = LoanEnumerations.interestRecalculationFrequencyType(restFrequencyEnumValue); final int restFrequencyInterval = JdbcSupport.getInteger(rs, "restFrequencyInterval"); - final LocalDate restFrequencyDate = JdbcSupport.getLocalDate(rs, "restFrequencyDate"); + final Integer restFrequencyNthDayEnumValue = JdbcSupport.getInteger(rs, "restFrequencyNthDayEnum"); + EnumOptionData restFrequencyNthDayEnum = null; + if (restFrequencyNthDayEnumValue != null) { + restFrequencyNthDayEnum = LoanEnumerations.interestRecalculationCompoundingNthDayType(restFrequencyNthDayEnumValue); + } + final Integer restFrequencyWeekDayEnumValue = JdbcSupport.getInteger(rs, "restFrequencyWeekDayEnum"); + EnumOptionData restFrequencyWeekDayEnum = null; + if (restFrequencyWeekDayEnumValue != null) { + restFrequencyWeekDayEnum = LoanEnumerations + .interestRecalculationCompoundingDayOfWeekType(restFrequencyWeekDayEnumValue); + } + final Integer restFrequencyOnDay = JdbcSupport.getInteger(rs, "restFrequencyOnDay"); final CalendarData compoundingCalendarData = null; final Integer compoundingFrequencyEnumValue = JdbcSupport.getInteger(rs, "compoundingFrequencyEnum"); EnumOptionData compoundingFrequencyType = null; @@ -885,25 +894,41 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { compoundingFrequencyType = LoanEnumerations.interestRecalculationFrequencyType(compoundingFrequencyEnumValue); } final Integer compoundingInterval = JdbcSupport.getInteger(rs, "compoundingInterval"); - final LocalDate compoundingFrequencyDate = JdbcSupport.getLocalDate(rs, "compoundingFrequencyDate"); + final Integer compoundingFrequencyNthDayEnumValue = JdbcSupport.getInteger(rs, "compoundingFrequencyNthDayEnum"); + EnumOptionData compoundingFrequencyNthDayEnum = null; + if (compoundingFrequencyNthDayEnumValue != null) { + compoundingFrequencyNthDayEnum = LoanEnumerations + .interestRecalculationCompoundingNthDayType(compoundingFrequencyNthDayEnumValue); + } + final Integer compoundingFrequencyWeekDayEnumValue = JdbcSupport.getInteger(rs, "compoundingFrequencyWeekDayEnum"); + EnumOptionData compoundingFrequencyWeekDayEnum = null; + if (compoundingFrequencyWeekDayEnumValue != null) { + compoundingFrequencyWeekDayEnum = LoanEnumerations + .interestRecalculationCompoundingDayOfWeekType(compoundingFrequencyWeekDayEnumValue); + } + final Integer compoundingFrequencyOnDay = JdbcSupport.getInteger(rs, "compoundingFrequencyOnDay"); + final Boolean isCompoundingToBePostedAsTransaction = rs.getBoolean("isCompoundingToBePostedAsTransaction"); + final Boolean allowCompoundingOnEod = rs.getBoolean("allowCompoundingOnEod"); interestRecalculationData = new LoanInterestRecalculationData(lprId, productId, interestRecalculationCompoundingType, - rescheduleStrategyType, calendarData, restFrequencyType, restFrequencyInterval, restFrequencyDate, - compoundingCalendarData, compoundingFrequencyType, compoundingInterval, compoundingFrequencyDate); + rescheduleStrategyType, calendarData, restFrequencyType, restFrequencyInterval, restFrequencyNthDayEnum, + restFrequencyWeekDayEnum, restFrequencyOnDay, compoundingCalendarData, compoundingFrequencyType, + compoundingInterval, compoundingFrequencyNthDayEnum, compoundingFrequencyWeekDayEnum, compoundingFrequencyOnDay, + isCompoundingToBePostedAsTransaction, allowCompoundingOnEod); } return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, groupData, loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, currencyData, proposedPrincipal, principal, approvedPrincipal, totalOverpaid, inArrearsTolerance, termFrequency, - termPeriodFrequencyType, numberOfRepayments, repaymentEvery, repaymentFrequencyType, repaymentFrequencyNthDayType, - repaymentFrequencyDayOfWeekType, transactionStrategyId, transactionStrategyName, amortizationType, - interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, interestType, isFloatingInterestRate, - interestRateDifferential, interestCalculationPeriodType, allowPartialPeriodInterestCalcualtion, - expectedFirstRepaymentOnDate, graceOnPrincipalPayment, recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, - interestChargedFromDate, timeline, loanSummary, feeChargesDueAtDisbursementCharged, syncDisbursementWithMeeting, - loanCounter, loanProductCounter, multiDisburseLoan, canDefineInstallmentAmount, fixedEmiAmount, outstandingLoanBalance, - inArrears, graceOnArrearsAgeing, isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, + termPeriodFrequencyType, numberOfRepayments, repaymentEvery, repaymentFrequencyType, null, null, transactionStrategyId, + transactionStrategyName, amortizationType, interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, + interestType, isFloatingInterestRate, interestRateDifferential, interestCalculationPeriodType, + allowPartialPeriodInterestCalcualtion, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, + recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, + timeline, loanSummary, feeChargesDueAtDisbursementCharged, syncDisbursementWithMeeting, loanCounter, + loanProductCounter, multiDisburseLoan, canDefineInstallmentAmount, fixedEmiAmount, outstandingLoanBalance, inArrears, + graceOnArrearsAgeing, isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, createStandingInstructionAtDisbursement, isvariableInstallmentsAllowed, minimumGap, maximumGap); } @@ -1569,10 +1594,11 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { sqlBuilder .append("select ") .append(mapper.schema()) - .append(" where ((ls.fee_charges_amount <> if(ls.accrual_fee_charges_derived is null,0, ls.accrual_fee_charges_derived))") + .append(" where (recaldet.is_compounding_to_be_posted_as_transaction is null or recaldet.is_compounding_to_be_posted_as_transaction = 0) ") + .append(" and (((ls.fee_charges_amount <> if(ls.accrual_fee_charges_derived is null,0, ls.accrual_fee_charges_derived))") .append(" or ( ls.penalty_charges_amount <> if(ls.accrual_penalty_charges_derived is null,0,ls.accrual_penalty_charges_derived))") .append(" or ( ls.interest_amount <> if(ls.accrual_interest_derived is null,0,ls.accrual_interest_derived)))") - .append(" and loan.loan_status_id=:active and mpl.accounting_type=:type and loan.is_npa=0 and ls.duedate <= CURDATE() "); + .append(" and loan.loan_status_id=:active and mpl.accounting_type=:type and loan.is_npa=0 and ls.duedate <= CURDATE()) "); if(organisationStartDate != null){ sqlBuilder.append(" and ls.duedate > :organisationstartdate "); } @@ -1594,11 +1620,12 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { sqlBuilder .append("select ") .append(mapper.schema()) - .append(" where ((ls.fee_charges_amount <> if(ls.accrual_fee_charges_derived is null,0, ls.accrual_fee_charges_derived))") + .append(" where (recaldet.is_compounding_to_be_posted_as_transaction is null or recaldet.is_compounding_to_be_posted_as_transaction = 0) ") + .append(" and (((ls.fee_charges_amount <> if(ls.accrual_fee_charges_derived is null,0, ls.accrual_fee_charges_derived))") .append(" or (ls.penalty_charges_amount <> if(ls.accrual_penalty_charges_derived is null,0,ls.accrual_penalty_charges_derived))") .append(" or (ls.interest_amount <> if(ls.accrual_interest_derived is null,0,ls.accrual_interest_derived)))") .append(" and loan.loan_status_id=:active and mpl.accounting_type=:type and (loan.closedon_date <= :tilldate or loan.closedon_date is null)") - .append(" and loan.is_npa=0 and (ls.duedate <= :tilldate or (ls.duedate > :tilldate and ls.fromdate < :tilldate)) "); + .append(" and loan.is_npa=0 and (ls.duedate <= :tilldate or (ls.duedate > :tilldate and ls.fromdate < :tilldate))) "); if(organisationStartDate != null){ sqlBuilder.append(" and ls.duedate > :organisationstartdate "); } @@ -1632,7 +1659,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { .append(" from m_loan_repayment_schedule ls ").append(" left join m_loan loan on loan.id=ls.loan_id ") .append(" left join m_product_loan mpl on mpl.id = loan.product_id") .append(" left join m_client mc on mc.id = loan.client_id ").append(" left join m_group mg on mg.id = loan.group_id") - .append(" left join m_currency curr on curr.code = loan.currency_code"); + .append(" left join m_currency curr on curr.code = loan.currency_code") + .append(" left join m_loan_recalculation_details as recaldet on loan.id = recaldet.loan_id "); return sqlBuilder.toString(); } @@ -1693,7 +1721,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { .append(" from m_loan_repayment_schedule ls ").append(" left join m_loan loan on loan.id=ls.loan_id ") .append(" left join m_product_loan mpl on mpl.id = loan.product_id") .append(" left join m_client mc on mc.id = loan.client_id ").append(" left join m_group mg on mg.id = loan.group_id") - .append(" left join m_currency curr on curr.code = loan.currency_code"); + .append(" left join m_currency curr on curr.code = loan.currency_code") + .append(" left join m_loan_recalculation_details as recaldet on loan.id = recaldet.loan_id "); return sqlBuilder.toString(); } @@ -2034,4 +2063,24 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { } } + @Override + public Collection<Long> retrieveLoanIdsWithPendingIncomePostingTransactions() { + StringBuilder sqlBuilder = new StringBuilder() + .append(" select distinct loan.id ") + .append(" from m_loan as loan ") + .append(" inner join m_loan_recalculation_details as recdet on (recdet.loan_id = loan.id and recdet.is_compounding_to_be_posted_as_transaction is not null and recdet.is_compounding_to_be_posted_as_transaction = 1) ") + .append(" inner join m_loan_repayment_schedule as repsch on repsch.loan_id = loan.id ") + .append(" inner join m_loan_interest_recalculation_additional_details as adddet on adddet.loan_repayment_schedule_id = repsch.id ") + .append(" left join m_loan_transaction as trans on (trans.is_reversed <> 1 and trans.transaction_type_enum = 19 and trans.loan_id = loan.id and trans.transaction_date = adddet.effective_date) ") + .append(" where loan.loan_status_id = 300 ") + .append(" and adddet.effective_date is not null ") + .append(" and trans.transaction_date is null ") + .append(" and adddet.effective_date < ? "); + try { + String currentdate = formatter.print(DateUtils.getLocalDateOfTenant()); + return this.jdbcTemplate.queryForList(sqlBuilder.toString(), Long.class, new Object[] { currentdate }); + } catch (final EmptyResultDataAccessException e) { + return null; + } + } }
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index b6c7ba1..1699182 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -90,14 +90,14 @@ import org.apache.fineract.portfolio.charge.domain.ChargeRepositoryWrapper; import org.apache.fineract.portfolio.charge.exception.ChargeCannotBeUpdatedException; import org.apache.fineract.portfolio.charge.exception.LoanChargeCannotBeAddedException; import org.apache.fineract.portfolio.charge.exception.LoanChargeCannotBeDeletedException; -import org.apache.fineract.portfolio.charge.exception.LoanChargeCannotBePayedException; -import org.apache.fineract.portfolio.charge.exception.LoanChargeCannotBeUpdatedException; -import org.apache.fineract.portfolio.charge.exception.LoanChargeCannotBeWaivedException; -import org.apache.fineract.portfolio.charge.exception.LoanChargeNotFoundException; import org.apache.fineract.portfolio.charge.exception.LoanChargeCannotBeDeletedException.LOAN_CHARGE_CANNOT_BE_DELETED_REASON; +import org.apache.fineract.portfolio.charge.exception.LoanChargeCannotBePayedException; import org.apache.fineract.portfolio.charge.exception.LoanChargeCannotBePayedException.LOAN_CHARGE_CANNOT_BE_PAYED_REASON; +import org.apache.fineract.portfolio.charge.exception.LoanChargeCannotBeUpdatedException; import org.apache.fineract.portfolio.charge.exception.LoanChargeCannotBeUpdatedException.LOAN_CHARGE_CANNOT_BE_UPDATED_REASON; +import org.apache.fineract.portfolio.charge.exception.LoanChargeCannotBeWaivedException; import org.apache.fineract.portfolio.charge.exception.LoanChargeCannotBeWaivedException.LOAN_CHARGE_CANNOT_BE_WAIVED_REASON; +import org.apache.fineract.portfolio.charge.exception.LoanChargeNotFoundException; import org.apache.fineract.portfolio.client.domain.Client; import org.apache.fineract.portfolio.client.exception.ClientNotActiveException; import org.apache.fineract.portfolio.collectionsheet.command.CollectionSheetBulkDisbursalCommand; @@ -126,6 +126,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeRepository; import org.apache.fineract.portfolio.loanaccount.domain.LoanDisbursementDetails; import org.apache.fineract.portfolio.loanaccount.domain.LoanEvent; import org.apache.fineract.portfolio.loanaccount.domain.LoanInstallmentCharge; +import org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalcualtionAdditionalDetails; import org.apache.fineract.portfolio.loanaccount.domain.LoanLifecycleStateMachine; import org.apache.fineract.portfolio.loanaccount.domain.LoanOverdueInstallmentCharge; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment; @@ -304,7 +305,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final Loan loan = this.loanAssembler.assembleFrom(loanId); checkClientOrGroupActive(loan); - + final LocalDate nextPossibleRepaymentDate = loan.getNextPossibleRepaymentDateForRescheduling(); final Date rescheduledRepaymentDate = command.DateValueOfParameterNamed("adjustRepaymentDate"); @@ -336,8 +337,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final Map<String, Object> changes = new LinkedHashMap<>(); final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes); - - final Boolean isPaymnetypeApplicableforDisbursementCharge=configurationDomainService.isPaymnetypeApplicableforDisbursementCharge(); + + final Boolean isPaymnetypeApplicableforDisbursementCharge = configurationDomainService + .isPaymnetypeApplicableforDisbursementCharge(); updateLoanCounters(loan, actualDisbursementDate); Money amountBeforeAdjust = loan.getPrincpal(); @@ -366,10 +368,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.loanScheduleHistoryWritePlatformService.createAndSaveLoanScheduleArchive(loan.fetchRepaymentScheduleInstallments(), loan, null); } - if(isPaymnetypeApplicableforDisbursementCharge){ - changedTransactionDetail = loan.disburse(currentUser, command, changes, scheduleGeneratorDTO,paymentDetail); - }else{ - changedTransactionDetail = loan.disburse(currentUser, command, changes, scheduleGeneratorDTO,null); + if (isPaymnetypeApplicableforDisbursementCharge) { + changedTransactionDetail = loan.disburse(currentUser, command, changes, scheduleGeneratorDTO, paymentDetail); + } else { + changedTransactionDetail = loan.disburse(currentUser, command, changes, scheduleGeneratorDTO, null); } } if (!changes.isEmpty()) { @@ -549,7 +551,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final SingleDisbursalCommand[] disbursalCommand = bulkDisbursalCommand.getDisburseTransactions(); final Map<String, Object> changes = new LinkedHashMap<>(); if (disbursalCommand == null) { return changes; } - + final LocalDate nextPossibleRepaymentDate = null; final Date rescheduledRepaymentDate = null; @@ -597,15 +599,16 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } LocalDate recalculateFrom = null; final ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom); - regenerateScheduleOnDisbursement(command, loan, recalculateSchedule, scheduleGeneratorDTO, nextPossibleRepaymentDate, rescheduledRepaymentDate); + regenerateScheduleOnDisbursement(command, loan, recalculateSchedule, scheduleGeneratorDTO, nextPossibleRepaymentDate, + rescheduledRepaymentDate); if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { this.loanScheduleHistoryWritePlatformService.createAndSaveLoanScheduleArchive( loan.fetchRepaymentScheduleInstallments(), loan, null); } - if(configurationDomainService.isPaymnetypeApplicableforDisbursementCharge()){ - changedTransactionDetail = loan.disburse(currentUser, command, changes, scheduleGeneratorDTO,paymentDetail); - }else{ - changedTransactionDetail = loan.disburse(currentUser, command, changes, scheduleGeneratorDTO,null); + if (configurationDomainService.isPaymnetypeApplicableforDisbursementCharge()) { + changedTransactionDetail = loan.disburse(currentUser, command, changes, scheduleGeneratorDTO, paymentDetail); + } else { + changedTransactionDetail = loan.disburse(currentUser, command, changes, scheduleGeneratorDTO, null); } } if (!changes.isEmpty()) { @@ -1990,8 +1993,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf // loop through each loan to reschedule the repayment dates for (final Loan loan : loans) { if (loan != null) { - - if(loan.getExpectedFirstRepaymentOnDate() != null && loan.getExpectedFirstRepaymentOnDate().equals(presentMeetingDate)){ + if (loan.getExpectedFirstRepaymentOnDate() != null && loan.getExpectedFirstRepaymentOnDate().equals(presentMeetingDate)) { final String defaultUserMessage = "Meeting calendar date update is not supported since its a first repayment date"; throw new CalendarParameterUpdateNotSupportedException("meeting.for.first.repayment.date", defaultUserMessage, loan.getExpectedFirstRepaymentOnDate(), presentMeetingDate); @@ -2337,9 +2339,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf BigDecimal interest = BigDecimal.ZERO; BigDecimal feeCharges = BigDecimal.ZERO; BigDecimal penaltyCharges = BigDecimal.ONE; + final List<LoanInterestRecalcualtionAdditionalDetails> compoundingDetails = null; LoanRepaymentScheduleInstallment newEntry = new LoanRepaymentScheduleInstallment(loan, installments.size() + 1, lastInstallment.getDueDate(), lastChargeDate, principal, interest, feeCharges, penaltyCharges, - recalculatedInterestComponent); + recalculatedInterestComponent, compoundingDetails); installments.add(newEntry); } } @@ -2548,8 +2551,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf if (command.entityId() != null) { - changedTransactionDetail = loan.updateDisbursementDateAndAmountForTranche(loanDisbursementDetails, command, - changes, scheduleGeneratorDTO, currentUser); + changedTransactionDetail = loan.updateDisbursementDateAndAmountForTranche(loanDisbursementDetails, command, changes, + scheduleGeneratorDTO, currentUser); } else { // BigDecimal setAmount = loan.getApprovedPrincipal(); Collection<LoanDisbursementDetails> loanDisburseDetails = loan.getDisbursementDetails(); @@ -2735,8 +2738,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf AppUser currentUser = getAppUserIfPresent(); final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate"); BigDecimal emiAmount = command.bigDecimalValueOfParameterNamed(LoanApiConstants.emiAmountParameterName); - loan.regenerateScheduleOnDisbursement(scheduleGeneratorDTO, recalculateSchedule, actualDisbursementDate, emiAmount, currentUser, - nextPossibleRepaymentDate, rescheduledRepaymentDate); + loan.regenerateScheduleOnDisbursement(scheduleGeneratorDTO, recalculateSchedule, actualDisbursementDate, emiAmount, currentUser, + nextPossibleRepaymentDate, rescheduledRepaymentDate); } private List<LoanRepaymentScheduleInstallment> retrieveRepaymentScheduleFromModel(LoanScheduleModel model) { @@ -2747,7 +2750,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf scheduledLoanInstallment.periodNumber(), scheduledLoanInstallment.periodFromDate(), scheduledLoanInstallment.periodDueDate(), scheduledLoanInstallment.principalDue(), scheduledLoanInstallment.interestDue(), scheduledLoanInstallment.feeChargesDue(), - scheduledLoanInstallment.penaltyChargesDue(), scheduledLoanInstallment.isRecalculatedInterestComponent()); + scheduledLoanInstallment.penaltyChargesDue(), scheduledLoanInstallment.isRecalculatedInterestComponent(), + scheduledLoanInstallment.getLoanCompoundingDetails()); installments.add(installment); } } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/LoanProductConstants.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/LoanProductConstants.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/LoanProductConstants.java index f476e46..f704925 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/LoanProductConstants.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/LoanProductConstants.java @@ -86,12 +86,17 @@ public interface LoanProductConstants { public static final String rescheduleStrategyMethodParameterName = "rescheduleStrategyMethod"; public static final String recalculationRestFrequencyTypeParameterName = "recalculationRestFrequencyType"; public static final String recalculationRestFrequencyIntervalParameterName = "recalculationRestFrequencyInterval"; - public static final String recalculationRestFrequencyDateParamName = "recalculationRestFrequencyDate"; + public static final String recalculationRestFrequencyWeekdayParamName = "recalculationRestFrequencyDayOfWeekType"; + public static final String recalculationRestFrequencyNthDayParamName = "recalculationRestFrequencyNthDayType"; + public static final String recalculationRestFrequencyOnDayParamName = "recalculationRestFrequencyOnDayType"; public static final String isArrearsBasedOnOriginalScheduleParamName = "isArrearsBasedOnOriginalSchedule"; public static final String preClosureInterestCalculationStrategyParamName = "preClosureInterestCalculationStrategy"; public static final String recalculationCompoundingFrequencyTypeParameterName = "recalculationCompoundingFrequencyType"; public static final String recalculationCompoundingFrequencyIntervalParameterName = "recalculationCompoundingFrequencyInterval"; - public static final String recalculationCompoundingFrequencyDateParamName = "recalculationCompoundingFrequencyDate"; + public static final String recalculationCompoundingFrequencyWeekdayParamName = "recalculationCompoundingFrequencyDayOfWeekType"; + public static final String recalculationCompoundingFrequencyNthDayParamName = "recalculationCompoundingFrequencyNthDayType"; + public static final String recalculationCompoundingFrequencyOnDayParamName = "recalculationCompoundingFrequencyOnDayType"; + public static final String isCompoundingToBePostedAsTransactionParamName = "isCompoundingToBePostedAsTransaction"; // Guarantee related public static final String holdGuaranteeFundsParamName = "holdGuaranteeFunds"; @@ -115,6 +120,7 @@ public interface LoanProductConstants { public static final String inArrearsToleranceParamName = "inArrearsTolerance"; public static final String repaymentEveryParamName = "repaymentEvery"; public static final String graceOnPrincipalAndInterestPaymentParamName = "graceOnPrincipalAndInterestPayment"; + public static final String allowCompoundingOnEodParamName = "allowCompoundingOnEod"; //Variable Installments Settings public static final String allowVariableInstallmentsParamName = "allowVariableInstallments" ; http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResource.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResource.java index a7d1816..a269d54 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResource.java @@ -298,6 +298,10 @@ public class LoanProductsApiResource { final List<EnumOptionData> rescheduleStrategyTypeOptions = dropdownReadPlatformService.retrieveRescheduleStrategyTypeOptions(); final List<EnumOptionData> interestRecalculationFrequencyTypeOptions = dropdownReadPlatformService .retrieveInterestRecalculationFrequencyTypeOptions(); + final List<EnumOptionData> interestRecalculationNthDayTypeOptions = dropdownReadPlatformService + .retrieveInterestRecalculationNthDayTypeOptions(); + final List<EnumOptionData> interestRecalculationDayOfWeekTypeOptions = dropdownReadPlatformService + .retrieveInterestRecalculationDayOfWeekTypeOptions(); final List<EnumOptionData> preCloseInterestCalculationStrategyOptions = dropdownReadPlatformService .retrivePreCloseInterestCalculationStrategyOptions(); final List<FloatingRateData> floatingRateOptions = this.floatingRateReadPlatformService.retrieveLookupActive(); @@ -307,7 +311,8 @@ public class LoanProductsApiResource { interestRateFrequencyTypeOptions, fundOptions, transactionProcessingStrategyOptions, accountOptions, accountingRuleTypeOptions, loanCycleValueConditionTypeOptions, daysInMonthTypeOptions, daysInYearTypeOptions, interestRecalculationCompoundingTypeOptions, rescheduleStrategyTypeOptions, interestRecalculationFrequencyTypeOptions, - preCloseInterestCalculationStrategyOptions, floatingRateOptions); + preCloseInterestCalculationStrategyOptions, floatingRateOptions, interestRecalculationNthDayTypeOptions, + interestRecalculationDayOfWeekTypeOptions); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/data/LoanProductData.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/data/LoanProductData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/data/LoanProductData.java index 48f730a..2418945 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/data/LoanProductData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/data/LoanProductData.java @@ -159,6 +159,10 @@ public class LoanProductData { @SuppressWarnings("unused") private final List<EnumOptionData> interestRecalculationCompoundingTypeOptions; @SuppressWarnings("unused") + private final List<EnumOptionData> interestRecalculationNthDayTypeOptions; + @SuppressWarnings("unused") + private final List<EnumOptionData> interestRecalculationDayOfWeekTypeOptions; + @SuppressWarnings("unused") private final List<EnumOptionData> rescheduleStrategyTypeOptions; @SuppressWarnings("unused") private final List<EnumOptionData> preClosureInterestCalculationStrategyOptions; @@ -585,6 +589,8 @@ public class LoanProductData { this.interestRecalculationCompoundingTypeOptions = null; this.rescheduleStrategyTypeOptions = null; this.interestRecalculationFrequencyTypeOptions = null; + this.interestRecalculationNthDayTypeOptions = null; + this.interestRecalculationDayOfWeekTypeOptions = null; this.canDefineInstallmentAmount = canDefineInstallmentAmount; this.installmentAmountInMultiplesOf = installmentAmountInMultiplesOf; @@ -602,7 +608,9 @@ public class LoanProductData { final List<EnumOptionData> valueConditionTypeOptions, final List<EnumOptionData> daysInMonthTypeOptions, final List<EnumOptionData> daysInYearTypeOptions, final List<EnumOptionData> interestRecalculationCompoundingTypeOptions, final List<EnumOptionData> rescheduleStrategyTypeOptions, final List<EnumOptionData> interestRecalculationFrequencyTypeOptions, - final List<EnumOptionData> preCloseInterestCalculationStrategyOptions, final List<FloatingRateData> floatingRateOptions) { + final List<EnumOptionData> preCloseInterestCalculationStrategyOptions, final List<FloatingRateData> floatingRateOptions, + final List<EnumOptionData> interestRecalculationNthDayTypeOptions, + final List<EnumOptionData> interestRecalculationDayOfWeekTypeOptions) { this.id = productData.id; this.name = productData.name; this.shortName = productData.shortName; @@ -686,6 +694,8 @@ public class LoanProductData { this.amortizationTypeOptions = amortizationTypeOptions; this.interestTypeOptions = interestTypeOptions; this.interestCalculationPeriodTypeOptions = interestCalculationPeriodTypeOptions; + this.interestRecalculationNthDayTypeOptions = interestRecalculationNthDayTypeOptions; + this.interestRecalculationDayOfWeekTypeOptions = interestRecalculationDayOfWeekTypeOptions; this.repaymentFrequencyTypeOptions = repaymentFrequencyTypeOptions; this.interestRateFrequencyTypeOptions = interestRateFrequencyTypeOptions; @@ -946,8 +956,11 @@ public class LoanProductData { final CalendarData compoundingCalendarData = null; return new LoanInterestRecalculationData(id, loanId, getInterestRecalculationCompoundingType(), getRescheduleStrategyType(), calendarData, getRecalculationRestFrequencyType(), getRecalculationRestFrequencyInterval(), - getRecalculationRestFrequencyDate(), compoundingCalendarData, getRecalculationCompoundingFrequencyType(), - getRecalculationCompoundingFrequencyInterval(), getRecalculationCompoundingFrequencyDate()); + getInterestRecalculationRestNthDayType(), getInterestRecalculationRestWeekDayType(), + getInterestRecalculationRestOnDayType(), compoundingCalendarData, getRecalculationCompoundingFrequencyType(), + getRecalculationCompoundingFrequencyInterval(), getInterestRecalculationCompoundingNthDayType(), + getInterestRecalculationCompoundingWeekDayType(), getInterestRecalculationCompoundingOnDayType(), + isCompoundingToBePostedAsTransaction(), allowCompoundingOnEod()); } private EnumOptionData getRescheduleStrategyType() { @@ -960,8 +973,16 @@ public class LoanProductData { return null; } - private LocalDate getRecalculationRestFrequencyDate() { - if (isInterestRecalculationEnabled()) { return this.interestRecalculationData.getRecalculationRestFrequencyDate(); } + private EnumOptionData getInterestRecalculationCompoundingNthDayType() { + if (isInterestRecalculationEnabled()) { return this.interestRecalculationData.getRecalculationCompoundingFrequencyNthDay(); } + return null; + } + private EnumOptionData getInterestRecalculationCompoundingWeekDayType() { + if (isInterestRecalculationEnabled()) { return this.interestRecalculationData.getRecalculationCompoundingFrequencyWeekday(); } + return null; + } + private Integer getInterestRecalculationCompoundingOnDayType() { + if (isInterestRecalculationEnabled()) { return this.interestRecalculationData.getRecalculationCompoundingFrequencyOnDay(); } return null; } @@ -975,8 +996,18 @@ public class LoanProductData { return null; } - private LocalDate getRecalculationCompoundingFrequencyDate() { - if (isInterestRecalculationEnabled()) { return this.interestRecalculationData.getRecalculationCompoundingFrequencyDate(); } + private EnumOptionData getInterestRecalculationRestNthDayType() { + if (isInterestRecalculationEnabled()) { return this.interestRecalculationData.getRecalculationRestFrequencyNthDay(); } + return null; + } + + private EnumOptionData getInterestRecalculationRestWeekDayType() { + if (isInterestRecalculationEnabled()) { return this.interestRecalculationData.getRecalculationRestFrequencyWeekday(); } + return null; + } + + private Integer getInterestRecalculationRestOnDayType() { + if (isInterestRecalculationEnabled()) { return this.interestRecalculationData.getRecalculationRestFrequencyOnDay(); } return null; } @@ -989,6 +1020,14 @@ public class LoanProductData { if (isInterestRecalculationEnabled()) { return this.interestRecalculationData.getRecalculationCompoundingFrequencyInterval(); } return null; } + public Boolean isCompoundingToBePostedAsTransaction() { + if (isInterestRecalculationEnabled()) { return this.interestRecalculationData.isCompoundingToBePostedAsTransaction(); } + return null; + } + public Boolean allowCompoundingOnEod() { + if (isInterestRecalculationEnabled()) { return this.interestRecalculationData.allowCompoundingOnEod(); } + return null; + } public boolean canDefineInstallmentAmount() { return this.canDefineInstallmentAmount; http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/data/LoanProductInterestRecalculationData.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/data/LoanProductInterestRecalculationData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/data/LoanProductInterestRecalculationData.java index 42b3683..12dc470 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/data/LoanProductInterestRecalculationData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/data/LoanProductInterestRecalculationData.java @@ -26,7 +26,6 @@ import org.apache.fineract.infrastructure.core.data.EnumOptionData; import org.apache.fineract.portfolio.loanproduct.domain.InterestRecalculationCompoundingMethod; import org.apache.fineract.portfolio.loanproduct.domain.LoanPreClosureInterestCalculationStrategy; import org.apache.fineract.portfolio.loanproduct.domain.LoanRescheduleStrategyMethod; -import org.joda.time.LocalDate; public class LoanProductInterestRecalculationData { @@ -38,33 +37,48 @@ public class LoanProductInterestRecalculationData { private final EnumOptionData rescheduleStrategyType; private final EnumOptionData recalculationRestFrequencyType; private final Integer recalculationRestFrequencyInterval; - private final LocalDate recalculationRestFrequencyDate; + private final EnumOptionData recalculationRestFrequencyNthDay; + private final EnumOptionData recalculationRestFrequencyWeekday; + private final Integer recalculationRestFrequencyOnDay; private final EnumOptionData recalculationCompoundingFrequencyType; private final Integer recalculationCompoundingFrequencyInterval; - private final LocalDate recalculationCompoundingFrequencyDate; + private final EnumOptionData recalculationCompoundingFrequencyNthDay; + private final EnumOptionData recalculationCompoundingFrequencyWeekday; + private final Integer recalculationCompoundingFrequencyOnDay; @SuppressWarnings("unused") private final boolean isArrearsBasedOnOriginalSchedule; + private final boolean isCompoundingToBePostedAsTransaction; @SuppressWarnings("unused") private final EnumOptionData preClosureInterestCalculationStrategy; + private final boolean allowCompoundingOnEod; public LoanProductInterestRecalculationData(final Long id, final Long productId, final EnumOptionData interestRecalculationCompoundingType, final EnumOptionData rescheduleStrategyType, final EnumOptionData recalculationRestFrequencyType, final Integer recalculationRestFrequencyInterval, - final LocalDate recalculationRestFrequencyDate, final EnumOptionData recalculationCompoundingFrequencyType, - final Integer recalculationCompoundingFrequencyInterval, final LocalDate recalculationCompoundingFrequencyDate, - final boolean isArrearsBasedOnOriginalSchedule, final EnumOptionData preCloseInterestCalculationStrategy) { + final EnumOptionData recalculationRestFrequencyNthDay, final EnumOptionData recalculationRestFrequencyWeekday, + final Integer recalculationRestFrequencyOnDay, final EnumOptionData recalculationCompoundingFrequencyType, + final Integer recalculationCompoundingFrequencyInterval, final EnumOptionData recalculationCompoundingFrequencyNthDay, + final EnumOptionData recalculationCompoundingFrequencyWeekday, final Integer recalculationCompoundingFrequencyOnDay, + final boolean isArrearsBasedOnOriginalSchedule, boolean isCompoundingToBePostedAsTransaction, + final EnumOptionData preCloseInterestCalculationStrategy, final boolean allowCompoundingOnEod) { this.id = id; this.productId = productId; this.interestRecalculationCompoundingType = interestRecalculationCompoundingType; this.rescheduleStrategyType = rescheduleStrategyType; this.recalculationRestFrequencyType = recalculationRestFrequencyType; this.recalculationRestFrequencyInterval = recalculationRestFrequencyInterval; - this.recalculationRestFrequencyDate = recalculationRestFrequencyDate; + this.recalculationRestFrequencyNthDay = recalculationRestFrequencyNthDay; + this.recalculationRestFrequencyOnDay = recalculationRestFrequencyOnDay; + this.recalculationRestFrequencyWeekday = recalculationRestFrequencyWeekday; this.recalculationCompoundingFrequencyType = recalculationCompoundingFrequencyType; this.recalculationCompoundingFrequencyInterval = recalculationCompoundingFrequencyInterval; - this.recalculationCompoundingFrequencyDate = recalculationCompoundingFrequencyDate; + this.recalculationCompoundingFrequencyNthDay = recalculationCompoundingFrequencyNthDay; + this.recalculationCompoundingFrequencyOnDay = recalculationCompoundingFrequencyOnDay; + this.recalculationCompoundingFrequencyWeekday = recalculationCompoundingFrequencyWeekday; this.isArrearsBasedOnOriginalSchedule = isArrearsBasedOnOriginalSchedule; this.preClosureInterestCalculationStrategy = preCloseInterestCalculationStrategy; + this.isCompoundingToBePostedAsTransaction = isCompoundingToBePostedAsTransaction; + this.allowCompoundingOnEod = allowCompoundingOnEod; } public static LoanProductInterestRecalculationData sensibleDefaultsForNewLoanProductCreation() { @@ -74,16 +88,24 @@ public class LoanProductInterestRecalculationData { final EnumOptionData rescheduleStrategyType = rescheduleStrategyType(LoanRescheduleStrategyMethod.REDUCE_EMI_AMOUNT); final EnumOptionData recalculationRestFrequencyType = null; final Integer recalculationRestFrequencyInterval = null; - final LocalDate recalculationRestFrequencyDate = null; + final EnumOptionData recalculationRestFrequencyNthDay = null; + final EnumOptionData recalculationRestFrequencyWeekday = null; + final Integer recalculationRestFrequencyOnDay = null; final EnumOptionData recalculationCompoundingFrequencyType = null; final Integer recalculationCompoundingFrequencyInterval = null; - final LocalDate recalculationCompoundingFrequencyDate = null; + final EnumOptionData recalculationCompoundingFrequencyNthDay = null; + final EnumOptionData recalculationCompoundingFrequencyWeekday = null; + final Integer recalculationCompoundingFrequencyOnDay = null; final boolean isArrearsBasedOnOriginalSchedule = false; + final boolean isCompoundingToBePostedAsTransaction = false; final EnumOptionData preCloseInterestCalculationStrategy = preCloseInterestCalculationStrategy(LoanPreClosureInterestCalculationStrategy.TILL_PRE_CLOSURE_DATE); + final boolean allowCompoundingOnEod = false; return new LoanProductInterestRecalculationData(id, productId, interestRecalculationCompoundingType, rescheduleStrategyType, - recalculationRestFrequencyType, recalculationRestFrequencyInterval, recalculationRestFrequencyDate, - recalculationCompoundingFrequencyType, recalculationCompoundingFrequencyInterval, recalculationCompoundingFrequencyDate, - isArrearsBasedOnOriginalSchedule, preCloseInterestCalculationStrategy); + recalculationRestFrequencyType, recalculationRestFrequencyInterval, recalculationRestFrequencyNthDay, + recalculationRestFrequencyWeekday, recalculationRestFrequencyOnDay, recalculationCompoundingFrequencyType, + recalculationCompoundingFrequencyInterval, recalculationCompoundingFrequencyNthDay, + recalculationCompoundingFrequencyWeekday, recalculationCompoundingFrequencyOnDay, isArrearsBasedOnOriginalSchedule, + isCompoundingToBePostedAsTransaction, preCloseInterestCalculationStrategy, allowCompoundingOnEod); } public EnumOptionData getInterestRecalculationCompoundingType() { @@ -92,10 +114,7 @@ public class LoanProductInterestRecalculationData { public EnumOptionData getRescheduleStrategyType() { return this.rescheduleStrategyType; - } - public LocalDate getRecalculationRestFrequencyDate() { - return this.recalculationRestFrequencyDate; } public EnumOptionData getRecalculationRestFrequencyType() { @@ -114,8 +133,29 @@ public class LoanProductInterestRecalculationData { return this.recalculationCompoundingFrequencyInterval; } - public LocalDate getRecalculationCompoundingFrequencyDate() { - return this.recalculationCompoundingFrequencyDate; + public EnumOptionData getRecalculationRestFrequencyNthDay() { + return this.recalculationRestFrequencyNthDay; + } + public EnumOptionData getRecalculationRestFrequencyWeekday() { + return this.recalculationRestFrequencyWeekday; + } + public Integer getRecalculationRestFrequencyOnDay() { + return this.recalculationRestFrequencyOnDay; + } + public EnumOptionData getRecalculationCompoundingFrequencyNthDay() { + return this.recalculationCompoundingFrequencyNthDay; } + public EnumOptionData getRecalculationCompoundingFrequencyWeekday() { + return this.recalculationCompoundingFrequencyWeekday; + } + public Integer getRecalculationCompoundingFrequencyOnDay() { + return this.recalculationCompoundingFrequencyOnDay; + } + public boolean isCompoundingToBePostedAsTransaction() { + return this.isCompoundingToBePostedAsTransaction; + } + public boolean allowCompoundingOnEod() { + return this.allowCompoundingOnEod; + } } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductInterestRecalculationDetails.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductInterestRecalculationDetails.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductInterestRecalculationDetails.java index 4456054..1b5a34f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductInterestRecalculationDetails.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductInterestRecalculationDetails.java @@ -18,7 +18,6 @@ */ package org.apache.fineract.portfolio.loanproduct.domain; -import java.util.Date; import java.util.Map; import javax.persistence.Column; @@ -26,12 +25,9 @@ import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.portfolio.loanproduct.LoanProductConstants; -import org.joda.time.LocalDate; import org.springframework.data.jpa.domain.AbstractPersistable; /** @@ -66,9 +62,14 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable @Column(name = "rest_frequency_interval", nullable = false) private Integer restInterval; - @Temporal(TemporalType.DATE) - @Column(name = "rest_freqency_date") - private Date restFrequencyDate; + @Column(name = "rest_frequency_nth_day_enum", nullable = true) + private Integer restFrequencyNthDay; + + @Column(name = "rest_frequency_weekday_enum", nullable = true) + private Integer restFrequencyWeekday; + + @Column(name = "rest_frequency_on_day", nullable = true) + private Integer restFrequencyOnDay; @Column(name = "compounding_frequency_type_enum", nullable = true) private Integer compoundingFrequencyType; @@ -76,9 +77,14 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable @Column(name = "compounding_frequency_interval", nullable = true) private Integer compoundingInterval; - @Temporal(TemporalType.DATE) - @Column(name = "compounding_freqency_date") - private Date compoundingFrequencyDate; + @Column(name = "compounding_frequency_nth_day_enum", nullable = true) + private Integer compoundingFrequencyNthDay; + + @Column(name = "compounding_frequency_weekday_enum", nullable = true) + private Integer compoundingFrequencyWeekday; + + @Column(name = "compounding_frequency_on_day", nullable = true) + private Integer compoundingFrequencyOnDay; @Column(name = "arrears_based_on_original_schedule") private boolean isArrearsBasedOnOriginalSchedule; @@ -86,6 +92,12 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable @Column(name = "pre_close_interest_calculation_strategy") private Integer preClosureInterestCalculationStrategy; + @Column(name = "is_compounding_to_be_posted_as_transaction") + private Boolean isCompoundingToBePostedAsTransaction; + + @Column(name = "allow_compounding_on_eod") + private Boolean allowCompoundingOnEod; + protected LoanProductInterestRecalculationDetails() { // } @@ -100,19 +112,16 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable final Integer recurrenceFrequency = command .integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyTypeParameterName); - final LocalDate recurrenceOnLocalDate = command - .localDateValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyDateParamName); + final Integer recurrenceOnNthDay = command + .integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyNthDayParamName); + final Integer recurrenceOnDay = command.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyOnDayParamName); + final Integer recurrenceOnWeekday = command + .integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyWeekdayParamName); Integer recurrenceInterval = command .integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyIntervalParameterName); final boolean isArrearsBasedOnOriginalSchedule = command .booleanPrimitiveValueOfParameterNamed(LoanProductConstants.isArrearsBasedOnOriginalScheduleParamName); RecalculationFrequencyType frequencyType = RecalculationFrequencyType.fromInt(recurrenceFrequency); - Date recurrenceOnDate = null; - if (recurrenceOnLocalDate != null) { - if (!frequencyType.isSameAsRepayment()) { - recurrenceOnDate = recurrenceOnLocalDate.toDate(); - } - } if (frequencyType.isSameAsRepayment()) { recurrenceInterval = 0; } @@ -121,7 +130,10 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable .fromInt(interestRecalculationCompoundingMethod); Integer compoundingRecurrenceFrequency = null; Integer compoundingInterval = null; - Date recurrenceOnCompoundingDate = null; + Integer compoundingRecurrenceOnNthDay = null; + Integer compoundingRecurrenceOnDay = null; + Integer compoundingRecurrenceOnWeekday = null; + boolean allowCompoundingOnEod = false; if (compoundingMethod.isCompoundingEnabled()) { compoundingRecurrenceFrequency = command .integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyTypeParameterName); @@ -131,14 +143,14 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable if (compoundingFrequencyType.isSameAsRepayment()) { recurrenceInterval = 0; } - final LocalDate compoundingRecurrenceOnLocalDate = command - .localDateValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyDateParamName); - - if (compoundingRecurrenceOnLocalDate != null) { - if (!compoundingFrequencyType.isSameAsRepayment()) { - recurrenceOnCompoundingDate = compoundingRecurrenceOnLocalDate.toDate(); - } - } + compoundingRecurrenceOnNthDay = command + .integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyNthDayParamName); + compoundingRecurrenceOnDay = command + .integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName); + compoundingRecurrenceOnWeekday = command + .integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyWeekdayParamName); + if (!compoundingFrequencyType.isDaily()) + allowCompoundingOnEod = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.allowCompoundingOnEodParamName); } Integer preCloseInterestCalculationStrategy = command @@ -147,25 +159,39 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable preCloseInterestCalculationStrategy = LoanPreClosureInterestCalculationStrategy.TILL_PRE_CLOSURE_DATE.getValue(); } + final boolean isCompoundingToBePostedAsTransaction = command + .booleanPrimitiveValueOfParameterNamed(LoanProductConstants.isCompoundingToBePostedAsTransactionParamName); + return new LoanProductInterestRecalculationDetails(interestRecalculationCompoundingMethod, loanRescheduleStrategyMethod, - recurrenceFrequency, recurrenceInterval, recurrenceOnDate, compoundingRecurrenceFrequency, compoundingInterval, - recurrenceOnCompoundingDate, isArrearsBasedOnOriginalSchedule, preCloseInterestCalculationStrategy); + recurrenceFrequency, recurrenceInterval, recurrenceOnNthDay, recurrenceOnDay, recurrenceOnWeekday, + compoundingRecurrenceFrequency, compoundingInterval, compoundingRecurrenceOnNthDay, compoundingRecurrenceOnDay, + compoundingRecurrenceOnWeekday, isArrearsBasedOnOriginalSchedule, preCloseInterestCalculationStrategy, + isCompoundingToBePostedAsTransaction, allowCompoundingOnEod); } private LoanProductInterestRecalculationDetails(final Integer interestRecalculationCompoundingMethod, final Integer rescheduleStrategyMethod, final Integer restFrequencyType, final Integer restInterval, - final Date restFrequencyDate, Integer compoundingFrequencyType, Integer compoundingInterval, Date compoundingFrequencyDate, - final boolean isArrearsBasedOnOriginalSchedule, final Integer preCloseInterestCalculationStrategy) { + final Integer restFrequencyNthDay, final Integer restFrequencyOnDay, final Integer restFrequencyWeekday, + Integer compoundingFrequencyType, Integer compoundingInterval, final Integer compoundingFrequencyNthDay, + final Integer compoundingFrequencyOnDay, final Integer compoundingFrequencyWeekday, + final boolean isArrearsBasedOnOriginalSchedule, final Integer preCloseInterestCalculationStrategy, + final boolean isCompoundingToBePostedAsTransaction, final boolean allowCompoundingOnEod) { this.interestRecalculationCompoundingMethod = interestRecalculationCompoundingMethod; this.rescheduleStrategyMethod = rescheduleStrategyMethod; this.restFrequencyType = restFrequencyType; this.restInterval = restInterval; - this.restFrequencyDate = restFrequencyDate; - this.compoundingFrequencyDate = compoundingFrequencyDate; + this.restFrequencyNthDay = restFrequencyNthDay; + this.restFrequencyOnDay = restFrequencyOnDay; + this.restFrequencyWeekday = restFrequencyWeekday; this.compoundingFrequencyType = compoundingFrequencyType; this.compoundingInterval = compoundingInterval; + this.compoundingFrequencyNthDay = compoundingFrequencyNthDay; + this.compoundingFrequencyOnDay = compoundingFrequencyOnDay; + this.compoundingFrequencyWeekday = compoundingFrequencyWeekday; this.isArrearsBasedOnOriginalSchedule = isArrearsBasedOnOriginalSchedule; this.preClosureInterestCalculationStrategy = preCloseInterestCalculationStrategy; + this.isCompoundingToBePostedAsTransaction = isCompoundingToBePostedAsTransaction; + this.allowCompoundingOnEod = allowCompoundingOnEod; } public void updateProduct(final LoanProduct loanProduct) { @@ -209,7 +235,9 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable RecalculationFrequencyType frequencyType = RecalculationFrequencyType.fromInt(this.restFrequencyType); if (frequencyType.isSameAsRepayment()) { this.restInterval = 0; - this.restFrequencyDate = null; + this.restFrequencyNthDay = null; + this.restFrequencyWeekday = null; + this.restFrequencyOnDay = null; } else { if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationRestFrequencyIntervalParameterName, this.restInterval)) { @@ -220,16 +248,46 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable this.restInterval = newValue; } - if (command.isChangeInLocalDateParameterNamed(LoanProductConstants.recalculationRestFrequencyDateParamName, - getRestFrequencyLocalDate())) { - final LocalDate newValue = command - .localDateValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyDateParamName); - Date recurrenceOnDate = null; - if (newValue != null) { - recurrenceOnDate = newValue.toDate(); - } - actualChanges.put(LoanProductConstants.recalculationRestFrequencyDateParamName, newValue); - this.restFrequencyDate = recurrenceOnDate; + if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationRestFrequencyNthDayParamName, + getRestFrequencyNthDay())) { + Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyNthDayParamName); + actualChanges.put(LoanProductConstants.recalculationRestFrequencyNthDayParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.restFrequencyNthDay = newValue; + this.restFrequencyOnDay = null; + } + if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationRestFrequencyWeekdayParamName, + getRestFrequencyWeekday())) { + Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyWeekdayParamName); + actualChanges.put(LoanProductConstants.recalculationRestFrequencyWeekdayParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.restFrequencyWeekday = newValue; + this.restFrequencyOnDay = null; + } + if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationRestFrequencyOnDayParamName, + getRestFrequencyOnDay())) { + Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyOnDayParamName); + actualChanges.put(LoanProductConstants.recalculationRestFrequencyOnDayParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.restFrequencyOnDay = newValue; + this.restFrequencyNthDay = null; + this.restFrequencyWeekday = null; + } + + if (frequencyType.isWeekly()) { + this.restFrequencyNthDay = null; + this.restFrequencyOnDay = null; + } else if (frequencyType.isMonthly()) { + if(command.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyOnDayParamName) != null) { + this.restFrequencyNthDay = null; + this.restFrequencyWeekday = null; + } else { + this.restFrequencyOnDay = null; + } + } else if (frequencyType.isDaily()) { + this.restFrequencyNthDay = null; + this.restFrequencyWeekday = null; + this.restFrequencyOnDay = null; } } @@ -247,7 +305,9 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable RecalculationFrequencyType compoundingfrequencyType = RecalculationFrequencyType.fromInt(this.compoundingFrequencyType); if (compoundingfrequencyType.isSameAsRepayment()) { this.compoundingInterval = null; - this.compoundingFrequencyDate = null; + this.compoundingFrequencyNthDay = null; + this.compoundingFrequencyWeekday = null; + this.compoundingFrequencyOnDay = null; } else { if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyIntervalParameterName, this.compoundingInterval)) { @@ -257,22 +317,66 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable this.compoundingInterval = newValue; } - if (command.isChangeInLocalDateParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyDateParamName, - getCompoundingFrequencyLocalDate())) { - final LocalDate newValue = command - .localDateValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyDateParamName); - Date recurrenceOnDate = null; - if (newValue != null) { - recurrenceOnDate = newValue.toDate(); - } - actualChanges.put(LoanProductConstants.recalculationCompoundingFrequencyDateParamName, newValue); - this.compoundingFrequencyDate = recurrenceOnDate; + if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyNthDayParamName, + getCompoundingFrequencyNthDay())) { + Integer newValue = command + .integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyNthDayParamName); + actualChanges.put(LoanProductConstants.recalculationCompoundingFrequencyNthDayParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.compoundingFrequencyNthDay = newValue; + this.compoundingFrequencyOnDay = null; + } + if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyWeekdayParamName, + getCompoundingFrequencyWeekday())) { + Integer newValue = command + .integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyWeekdayParamName); + actualChanges.put(LoanProductConstants.recalculationCompoundingFrequencyWeekdayParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.compoundingFrequencyWeekday = newValue; + this.compoundingFrequencyOnDay = null; + } + if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName, + getCompoundingFrequencyOnDay())) { + Integer newValue = command + .integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName); + actualChanges.put(LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.compoundingFrequencyOnDay = newValue; + this.compoundingFrequencyNthDay = null; + this.compoundingFrequencyWeekday = null; + } + + if (compoundingfrequencyType.isWeekly()) { + this.compoundingFrequencyNthDay = null; + this.compoundingFrequencyOnDay = null; + } else if (compoundingfrequencyType.isMonthly()) { + if(command.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName) != null) { + this.compoundingFrequencyNthDay = null; + this.compoundingFrequencyWeekday = null; + } else { + this.compoundingFrequencyOnDay = null; + } + } else if (compoundingfrequencyType.isDaily()) { + this.compoundingFrequencyNthDay = null; + this.compoundingFrequencyWeekday = null; + this.compoundingFrequencyOnDay = null; } } + if (!compoundingfrequencyType.isDaily()) { + if (command.isChangeInBooleanParameterNamed(LoanProductConstants.allowCompoundingOnEodParamName, allowCompoundingOnEod())) { + boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.allowCompoundingOnEodParamName); + actualChanges.put(LoanProductConstants.allowCompoundingOnEodParamName, newValue); + this.allowCompoundingOnEod = newValue; + } + } else { + this.allowCompoundingOnEod = false; + } } else { this.compoundingFrequencyType = null; this.compoundingInterval = null; - this.compoundingFrequencyDate = null; + this.compoundingFrequencyNthDay = null; + this.compoundingFrequencyWeekday = null; + this.compoundingFrequencyOnDay = null; } if (command.isChangeInBooleanParameterNamed(LoanProductConstants.isArrearsBasedOnOriginalScheduleParamName, @@ -292,15 +396,15 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable actualChanges.put(LoanProductConstants.preClosureInterestCalculationStrategyParamName, newValue); this.preClosureInterestCalculationStrategy = newValue; } - - } - - public LocalDate getRestFrequencyLocalDate() { - LocalDate recurrenceOnLocalDate = null; - if (this.restFrequencyDate != null) { - recurrenceOnLocalDate = new LocalDate(this.restFrequencyDate); + + if (command.isChangeInBooleanParameterNamed(LoanProductConstants.isCompoundingToBePostedAsTransactionParamName, + this.isCompoundingToBePostedAsTransaction)) { + final boolean newValue = command + .booleanPrimitiveValueOfParameterNamed(LoanProductConstants.isCompoundingToBePostedAsTransactionParamName); + actualChanges.put(LoanProductConstants.isCompoundingToBePostedAsTransactionParamName, newValue); + this.isCompoundingToBePostedAsTransaction = newValue; } - return recurrenceOnLocalDate; + } public RecalculationFrequencyType getRestFrequencyType() { @@ -311,14 +415,6 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable return this.restInterval; } - public LocalDate getCompoundingFrequencyLocalDate() { - LocalDate recurrenceOnLocalDate = null; - if (this.compoundingFrequencyDate != null) { - recurrenceOnLocalDate = new LocalDate(this.compoundingFrequencyDate); - } - return recurrenceOnLocalDate; - } - public RecalculationFrequencyType getCompoundingFrequencyType() { return RecalculationFrequencyType.fromInt(this.compoundingFrequencyType); } @@ -334,4 +430,36 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable public LoanPreClosureInterestCalculationStrategy preCloseInterestCalculationStrategy() { return LoanPreClosureInterestCalculationStrategy.fromInt(this.preClosureInterestCalculationStrategy); } + + public Integer getRestFrequencyNthDay() { + return this.restFrequencyNthDay; + } + + public Integer getRestFrequencyWeekday() { + return this.restFrequencyWeekday; + } + + public Integer getRestFrequencyOnDay() { + return this.restFrequencyOnDay; + } + + public Integer getCompoundingFrequencyNthDay() { + return this.compoundingFrequencyNthDay; + } + + public Integer getCompoundingFrequencyWeekday() { + return this.compoundingFrequencyWeekday; + } + + public Integer getCompoundingFrequencyOnDay() { + return this.compoundingFrequencyOnDay; + } + + public Boolean getIsCompoundingToBePostedAsTransaction() { + return this.isCompoundingToBePostedAsTransaction; + } + + public Boolean allowCompoundingOnEod() { + return this.allowCompoundingOnEod; + } } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductRelatedDetail.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductRelatedDetail.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductRelatedDetail.java index 1d7aaf6..b7dbc8a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductRelatedDetail.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductRelatedDetail.java @@ -346,8 +346,9 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche actualChanges.put(repaymentFrequencyTypeParamName, newValue); actualChanges.put("locale", localeAsInput); this.repaymentPeriodFrequencyType = PeriodFrequencyType.fromInt(newValue); - + } if (this.repaymentPeriodFrequencyType == PeriodFrequencyType.MONTHS) { + Integer newValue = null; final String repaymentFrequencyNthDayTypeParamName = "repaymentFrequencyNthDayType"; newValue = command.integerValueOfParameterNamed(repaymentFrequencyNthDayTypeParamName); actualChanges.put(repaymentFrequencyNthDayTypeParamName, newValue); @@ -357,7 +358,6 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche actualChanges.put(repaymentFrequencyDayOfWeekTypeParamName, newValue); actualChanges.put("locale", localeAsInput); - } } final String numberOfRepaymentsParamName = "numberOfRepayments";
