http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanReschedulingWithinCenterTest.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanReschedulingWithinCenterTest.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanReschedulingWithinCenterTest.java index a825bcb..4126f75 100644 --- a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanReschedulingWithinCenterTest.java +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanReschedulingWithinCenterTest.java @@ -111,7 +111,8 @@ public class LoanReschedulingWithinCenterTest { LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_NONE, LoanProductTestBuilder.RECALCULATION_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS, LoanProductTestBuilder.RECALCULATION_FREQUENCY_TYPE_DAILY, "0", recalculationRestFrequencyDate, - LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE, null, isMultiTrancheLoan); + LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE, null, isMultiTrancheLoan, + null, null); // APPLY FOR TRANCHE LOAN WITH INTEREST RECALCULATION final Integer loanId = applyForLoanApplicationForInterestRecalculation(clientId, groupId, calendarId, loanProductID, disbursalDate, @@ -222,7 +223,8 @@ public class LoanReschedulingWithinCenterTest { LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_NONE, LoanProductTestBuilder.RECALCULATION_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS, LoanProductTestBuilder.RECALCULATION_FREQUENCY_TYPE_DAILY, "0", recalculationRestFrequencyDate, - LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE, null, isMultiTrancheLoan); + LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE, null, isMultiTrancheLoan, + null, null); // CREATE TRANCHES List<HashMap> createTranches = new ArrayList<>(); @@ -279,14 +281,18 @@ public class LoanReschedulingWithinCenterTest { final String interestRecalculationCompoundingMethod, final String rescheduleStrategyMethod, final String recalculationRestFrequencyType, final String recalculationRestFrequencyInterval, final String recalculationRestFrequencyDate, final String preCloseInterestCalculationStrategy, final Account[] accounts, - final boolean isMultiTrancheLoan) { + final boolean isMultiTrancheLoan, final Integer recalculationRestFrequencyOnDayType, final Integer recalculationRestFrequencyDayOfWeekType) { final String recalculationCompoundingFrequencyType = null; final String recalculationCompoundingFrequencyInterval = null; final String recalculationCompoundingFrequencyDate = null; + final Integer recalculationCompoundingFrequencyOnDayType = null; + final Integer recalculationCompoundingFrequencyDayOfWeekType = null; return createLoanProductWithInterestRecalculation(repaymentStrategy, interestRecalculationCompoundingMethod, rescheduleStrategyMethod, recalculationRestFrequencyType, recalculationRestFrequencyInterval, recalculationRestFrequencyDate, recalculationCompoundingFrequencyType, recalculationCompoundingFrequencyInterval, - recalculationCompoundingFrequencyDate, preCloseInterestCalculationStrategy, accounts, null, false, isMultiTrancheLoan); + recalculationCompoundingFrequencyDate, preCloseInterestCalculationStrategy, accounts, null, false, isMultiTrancheLoan, + recalculationCompoundingFrequencyOnDayType, recalculationCompoundingFrequencyDayOfWeekType, recalculationRestFrequencyOnDayType, + recalculationRestFrequencyDayOfWeekType); } private Integer createLoanProductWithInterestRecalculation(final String repaymentStrategy, @@ -295,7 +301,10 @@ public class LoanReschedulingWithinCenterTest { final String recalculationRestFrequencyDate, final String recalculationCompoundingFrequencyType, final String recalculationCompoundingFrequencyInterval, final String recalculationCompoundingFrequencyDate, final String preCloseInterestCalculationStrategy, final Account[] accounts, final String chargeId, - boolean isArrearsBasedOnOriginalSchedule, final boolean isMultiTrancheLoan) { + boolean isArrearsBasedOnOriginalSchedule, final boolean isMultiTrancheLoan, + final Integer recalculationCompoundingFrequencyOnDayType, + final Integer recalculationCompoundingFrequencyDayOfWeekType, final Integer recalculationRestFrequencyOnDayType, + final Integer recalculationRestFrequencyDayOfWeekType) { System.out.println("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------"); LoanProductTestBuilder builder = new LoanProductTestBuilder() .withPrincipal("10000.00") @@ -311,9 +320,10 @@ public class LoanReschedulingWithinCenterTest { .withInterestRecalculationDetails(interestRecalculationCompoundingMethod, rescheduleStrategyMethod, preCloseInterestCalculationStrategy) .withInterestRecalculationRestFrequencyDetails(recalculationRestFrequencyType, recalculationRestFrequencyInterval, - recalculationRestFrequencyDate) + recalculationRestFrequencyOnDayType, recalculationRestFrequencyDayOfWeekType) .withInterestRecalculationCompoundingFrequencyDetails(recalculationCompoundingFrequencyType, - recalculationCompoundingFrequencyInterval, recalculationCompoundingFrequencyDate); + recalculationCompoundingFrequencyInterval, recalculationCompoundingFrequencyOnDayType, + recalculationCompoundingFrequencyDayOfWeekType); if (accounts != null) { builder = builder.withAccountingRulePeriodicAccrual(accounts); } @@ -356,7 +366,6 @@ public class LoanReschedulingWithinCenterTest { .withInterestCalculationPeriodTypeAsDays() // .withExpectedDisbursementDate(disbursementDate) // .withSubmittedOnDate(disbursementDate) // - .withRestFrequencyDate(restStartDate)// .withwithRepaymentStrategy(repaymentStrategy) // .withCharges(charges)// .build(clientID.toString(), groupId.toString(), loanProductID.toString(), null); @@ -389,4 +398,5 @@ public class LoanReschedulingWithinCenterTest { date.add(type, addvalue); return new ArrayList<>(Arrays.asList(date.get(Calendar.YEAR), date.get(Calendar.MONTH) + 1, date.get(Calendar.DAY_OF_MONTH))); } + } \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java index cfa9c39..50d9cc9 100644 --- a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java @@ -61,8 +61,6 @@ public class LoanApplicationTestBuilder { private List<HashMap> disbursementData = null; @SuppressWarnings("rawtypes") private List<HashMap> charges = new ArrayList<>(); - private String recalculationRestFrequencyDate = null; - private String recalculationCompoundingFrequencyDate = null; private String repaymentsStartingFromDate = null; private String calendarId; @@ -135,12 +133,6 @@ public class LoanApplicationTestBuilder { map.put("maxOutstandingLoanBalance", maxOutstandingLoanBalance); } - if (recalculationRestFrequencyDate != null) { - map.put("recalculationRestFrequencyDate", recalculationRestFrequencyDate); - } - if (recalculationCompoundingFrequencyDate != null) { - map.put("recalculationCompoundingFrequencyDate", recalculationCompoundingFrequencyDate); - } System.out.println("Loan Application request : " + map); return new Gson().toJson(map); @@ -281,15 +273,7 @@ public class LoanApplicationTestBuilder { return this; } - public LoanApplicationTestBuilder withRestFrequencyDate(final String recalculationRestFrequencyDate) { - this.recalculationRestFrequencyDate = recalculationRestFrequencyDate; - return this; - } - public LoanApplicationTestBuilder withCompoundingFrequencyDate(final String recalculationCompoundingFrequencyDate) { - this.recalculationCompoundingFrequencyDate = recalculationCompoundingFrequencyDate; - return this; - } public LoanApplicationTestBuilder withFirstRepaymentDate(final String firstRepaymentDate) { this.repaymentsStartingFromDate = firstRepaymentDate; http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java index 3b4c767..5f90468 100644 --- a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java @@ -104,10 +104,8 @@ public class LoanProductTestBuilder { private String rescheduleStrategyMethod = "1"; private String recalculationRestFrequencyType = "1"; private String recalculationRestFrequencyInterval = "0"; - private String recalculationRestFrequencyDate = null; private String recalculationCompoundingFrequencyType = null; private String recalculationCompoundingFrequencyInterval = null; - private String recalculationCompoundingFrequencyDate = null; private String minimumDaysBetweenDisbursalAndFirstRepayment = null; private Boolean holdGuaranteeFunds = null; private String mandatoryGuarantee = null; @@ -122,6 +120,10 @@ public class LoanProductTestBuilder { private Boolean allowVariableInstallments = Boolean.FALSE; private Integer minimumGap; private Integer maximumGap; + private Integer recalculationCompoundingFrequencyOnDayType = null; + private Integer recalculationRestFrequencyOnDayType = null; + private Integer recalculationCompoundingFrequencyDayOfWeekType = null; + private Integer recalculationRestFrequencyDayOfWeekType = null; public String build(final String chargeId) { final HashMap<String, Object> map = new HashMap<>(); @@ -177,16 +179,18 @@ public class LoanProductTestBuilder { map.put("rescheduleStrategyMethod", this.rescheduleStrategyMethod); map.put("recalculationRestFrequencyType", recalculationRestFrequencyType); map.put("recalculationRestFrequencyInterval", recalculationRestFrequencyInterval); - map.put("recalculationRestFrequencyDate", recalculationRestFrequencyDate); if (!RECALCULATION_COMPOUNDING_METHOD_NONE.equals(this.interestRecalculationCompoundingMethod)) { map.put("recalculationCompoundingFrequencyType", recalculationCompoundingFrequencyType); map.put("recalculationCompoundingFrequencyInterval", recalculationCompoundingFrequencyInterval); - map.put("recalculationCompoundingFrequencyDate", recalculationCompoundingFrequencyDate); } map.put("preClosureInterestCalculationStrategy", preCloseInterestCalculationStrategy); if (isArrearsBasedOnOriginalSchedule != null) { map.put("isArrearsBasedOnOriginalSchedule", isArrearsBasedOnOriginalSchedule); } + map.put("recalculationCompoundingFrequencyOnDayType", this.recalculationCompoundingFrequencyOnDayType); + map.put("recalculationCompoundingFrequencyDayOfWeekType", this.recalculationCompoundingFrequencyDayOfWeekType); + map.put("recalculationRestFrequencyOnDayType", this.recalculationRestFrequencyOnDayType); + map.put("recalculationRestFrequencyDayOfWeekType", this.recalculationRestFrequencyDayOfWeekType); } if (holdGuaranteeFunds != null) { map.put("holdGuaranteeFunds", this.holdGuaranteeFunds); @@ -437,20 +441,24 @@ public class LoanProductTestBuilder { } public LoanProductTestBuilder withInterestRecalculationRestFrequencyDetails(final String recalculationRestFrequencyType, - final String recalculationRestFrequencyInterval, final String recalculationRestFrequencyDate) { + final String recalculationRestFrequencyInterval, final Integer recalculationRestFrequencyOnDayType, + final Integer recalculationRestFrequencyDayOfWeekType) { this.isInterestRecalculationEnabled = true; this.recalculationRestFrequencyType = recalculationRestFrequencyType; this.recalculationRestFrequencyInterval = recalculationRestFrequencyInterval; - this.recalculationRestFrequencyDate = recalculationRestFrequencyDate; + this.recalculationRestFrequencyOnDayType = recalculationRestFrequencyOnDayType; + this.recalculationRestFrequencyDayOfWeekType = recalculationRestFrequencyDayOfWeekType; return this; } public LoanProductTestBuilder withInterestRecalculationCompoundingFrequencyDetails(final String recalculationCompoundingFrequencyType, - final String recalculationCompoundingFrequencyInterval, final String recalculationCompoundingFrequencyDate) { + final String recalculationCompoundingFrequencyInterval, final Integer recalculationCompoundingFrequencyOnDayType, + final Integer recalculationCompoundingFrequencyDayOfWeekType) { this.isInterestRecalculationEnabled = true; this.recalculationCompoundingFrequencyType = recalculationCompoundingFrequencyType; this.recalculationCompoundingFrequencyInterval = recalculationCompoundingFrequencyInterval; - this.recalculationCompoundingFrequencyDate = recalculationCompoundingFrequencyDate; + this.recalculationCompoundingFrequencyOnDayType = recalculationCompoundingFrequencyOnDayType; + this.recalculationCompoundingFrequencyDayOfWeekType = recalculationCompoundingFrequencyDayOfWeekType; return this; } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntry.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntry.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntry.java index 3e499d1..447cb13 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntry.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntry.java @@ -173,6 +173,9 @@ public class JournalEntry extends AbstractAuditableCustom<AppUser, Long> { return this.amount; } + public void setAmount(BigDecimal amount) { + this.amount = amount; + } public void setReversalJournalEntry(final JournalEntry reversalJournalEntry) { this.reversalJournalEntry = reversalJournalEntry; } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepository.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepository.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepository.java index ab61a70..120b03e 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepository.java @@ -18,6 +18,7 @@ */ package org.apache.fineract.accounting.journalentry.domain; +import java.util.Date; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; @@ -39,8 +40,13 @@ public interface JournalEntryRepository extends JpaRepository<JournalEntry, Long @Query("from JournalEntry journalEntry where journalEntry.entityId= :entityId and journalEntry.entityType = :entityType") List<JournalEntry> findProvisioningJournalEntriesByEntityId(@Param("entityId") Long entityId, @Param("entityType") Integer entityType) ; - + @Query("from JournalEntry journalEntry where journalEntry.transactionId= :transactionId and journalEntry.reversed is false and journalEntry.entityType = :entityType") - List<JournalEntry> findJournalEntries(@Param("transactionId") String transactionId, @Param("entityType") Integer entityType) ; - + List<JournalEntry> findJournalEntries(@Param("transactionId") String transactionId, @Param("entityType") Integer entityType); + + @Query("from JournalEntry journalEntry where glAccount.id= :accountId and transactionId= :transactionId and transactionDate= :transactionDate" + + " and type= :journalEntryType and entityType=1 and entityId= :loanId and loanTransaction.id= :loanTransactionId") + JournalEntry findLOANJournalEntryWith(@Param("accountId") Long accountId, @Param("transactionId") String transactionId, + @Param("transactionDate") Date transactionDate, @Param("journalEntryType") Integer journalEntryType, + @Param("loanId") Long loanId, @Param("loanTransactionId") Long loanTransactionId); } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java index 3d64581..c7a0c23 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java @@ -781,6 +781,12 @@ public class AccountingProcessorHelper { final Long loanProductId, final Long paymentTypeId, final Long loanId, final String transactionId, final Date transactionDate, final BigDecimal amount, final Boolean isReversal) { final GLAccount account = getLinkedGLAccountForLoanProduct(loanProductId, accountMappingTypeId, paymentTypeId); + createCreditJournalEntryOrReversalForLoan(office, currencyCode, loanId, transactionId, transactionDate, amount, isReversal, account); + } + + public void createCreditJournalEntryOrReversalForLoan(final Office office, final String currencyCode, final Long loanId, + final String transactionId, final Date transactionDate, final BigDecimal amount, final Boolean isReversal, + final GLAccount account) { if (isReversal) { createDebitJournalEntryForLoan(office, currencyCode, account, loanId, transactionId, transactionDate, amount); } else { @@ -1070,7 +1076,7 @@ public class AccountingProcessorHelper { this.glJournalEntryRepository.save(journalEntry); } - private GLAccount getLinkedGLAccountForLoanProduct(final Long loanProductId, final int accountMappingTypeId, final Long paymentTypeId) { + public GLAccount getLinkedGLAccountForLoanProduct(final Long loanProductId, final int accountMappingTypeId, final Long paymentTypeId) { GLAccount glAccount = null; if (isOrganizationAccount(accountMappingTypeId)) { FinancialActivityAccount financialActivityAccount = this.financialActivityAccountRepository http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java index 8287b72..7408ac9 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java @@ -21,12 +21,16 @@ package org.apache.fineract.accounting.journalentry.service; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import org.apache.fineract.accounting.closure.domain.GLClosure; import org.apache.fineract.accounting.common.AccountingConstants.ACCRUAL_ACCOUNTS_FOR_LOAN; import org.apache.fineract.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN; import org.apache.fineract.accounting.common.AccountingConstants.FINANCIAL_ACTIVITY; +import org.apache.fineract.accounting.glaccount.domain.GLAccount; import org.apache.fineract.accounting.journalentry.data.ChargePaymentDTO; import org.apache.fineract.accounting.journalentry.data.LoanDTO; import org.apache.fineract.accounting.journalentry.data.LoanTransactionDTO; @@ -88,7 +92,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess .getTransactionType().isWaiveCharges())) { createJournalEntriesForRepaymentsAndWriteOffs(loanDTO, loanTransactionDTO, office, true, false); } - + /** Logic for Refunds of Active Loans **/ else if (loanTransactionDTO.getTransactionType().isRefundForActiveLoans()) { createJournalEntriesForRefundForActiveLoan(loanDTO, loanTransactionDTO, office); @@ -193,18 +197,27 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess BigDecimal totalDebitAmount = new BigDecimal(0); + Map<GLAccount, BigDecimal> accountMap = new HashMap<>(); + // handle principal payment or writeOff (and reversals) if (principalAmount != null && !(principalAmount.compareTo(BigDecimal.ZERO) == 0)) { totalDebitAmount = totalDebitAmount.add(principalAmount); - this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, ACCRUAL_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO, - loanProductId, paymentTypeId, loanId, transactionId, transactionDate, principalAmount, isReversal); + GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, + ACCRUAL_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.getValue(), paymentTypeId); + accountMap.put(account, principalAmount); } // handle interest payment of writeOff (and reversals) if (interestAmount != null && !(interestAmount.compareTo(BigDecimal.ZERO) == 0)) { totalDebitAmount = totalDebitAmount.add(interestAmount); - this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_RECEIVABLE, - loanProductId, paymentTypeId, loanId, transactionId, transactionDate, interestAmount, isReversal); + GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, + ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_RECEIVABLE.getValue(), paymentTypeId); + if (accountMap.containsKey(account)) { + BigDecimal amount = accountMap.get(account).add(interestAmount); + accountMap.put(account, amount); + } else { + accountMap.put(account, interestAmount); + } } // handle fees payment of writeOff (and reversals) @@ -212,12 +225,23 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess totalDebitAmount = totalDebitAmount.add(feesAmount); if (isIncomeFromFee) { - this.helper.createCreditJournalEntryOrReversalForLoanCharges(office, currencyCode, - ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.getValue(), loanProductId, loanId, transactionId, transactionDate, - feesAmount, isReversal, loanTransactionDTO.getFeePayments()); + GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, + ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.getValue(), paymentTypeId); + if (accountMap.containsKey(account)) { + BigDecimal amount = accountMap.get(account).add(feesAmount); + accountMap.put(account, amount); + } else { + accountMap.put(account, feesAmount); + } } else { - this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, ACCRUAL_ACCOUNTS_FOR_LOAN.FEES_RECEIVABLE, - loanProductId, paymentTypeId, loanId, transactionId, transactionDate, feesAmount, isReversal); + GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, + ACCRUAL_ACCOUNTS_FOR_LOAN.FEES_RECEIVABLE.getValue(), paymentTypeId); + if (accountMap.containsKey(account)) { + BigDecimal amount = accountMap.get(account).add(feesAmount); + accountMap.put(account, amount); + } else { + accountMap.put(account, feesAmount); + } } } @@ -225,19 +249,41 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess if (penaltiesAmount != null && !(penaltiesAmount.compareTo(BigDecimal.ZERO) == 0)) { totalDebitAmount = totalDebitAmount.add(penaltiesAmount); if (isIncomeFromFee) { - this.helper.createCreditJournalEntryOrReversalForLoanCharges(office, currencyCode, - ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue(), loanProductId, loanId, transactionId, transactionDate, - penaltiesAmount, isReversal, loanTransactionDTO.getPenaltyPayments()); + GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, + ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue(), paymentTypeId); + if (accountMap.containsKey(account)) { + BigDecimal amount = accountMap.get(account).add(penaltiesAmount); + accountMap.put(account, amount); + } else { + accountMap.put(account, penaltiesAmount); + } } else { - this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, ACCRUAL_ACCOUNTS_FOR_LOAN.PENALTIES_RECEIVABLE, - loanProductId, paymentTypeId, loanId, transactionId, transactionDate, penaltiesAmount, isReversal); + GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, + ACCRUAL_ACCOUNTS_FOR_LOAN.PENALTIES_RECEIVABLE.getValue(), paymentTypeId); + if (accountMap.containsKey(account)) { + BigDecimal amount = accountMap.get(account).add(penaltiesAmount); + accountMap.put(account, amount); + } else { + accountMap.put(account, penaltiesAmount); + } } } - + if (overPaymentAmount != null && !(overPaymentAmount.compareTo(BigDecimal.ZERO) == 0)) { totalDebitAmount = totalDebitAmount.add(overPaymentAmount); - this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, ACCRUAL_ACCOUNTS_FOR_LOAN.OVERPAYMENT, loanProductId, - paymentTypeId, loanId, transactionId, transactionDate, overPaymentAmount, isReversal); + GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, + ACCRUAL_ACCOUNTS_FOR_LOAN.OVERPAYMENT.getValue(), paymentTypeId); + if (accountMap.containsKey(account)) { + BigDecimal amount = accountMap.get(account).add(overPaymentAmount); + accountMap.put(account, amount); + } else { + accountMap.put(account, overPaymentAmount); + } + } + + for (Entry<GLAccount, BigDecimal> entry : accountMap.entrySet()) { + this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, loanId, transactionId, transactionDate, + entry.getValue(), isReversal, entry.getKey()); } /** @@ -367,6 +413,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess paymentTypeId, loanId, transactionId, transactionDate, refundAmount, isReversal); } } + private void createJournalEntriesForRefundForActiveLoan(LoanDTO loanDTO, LoanTransactionDTO loanTransactionDTO, Office office) { // TODO Auto-generated method stub // loan properties @@ -401,12 +448,13 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess if (feesAmount != null && !(feesAmount.compareTo(BigDecimal.ZERO) == 0)) { totalDebitAmount = totalDebitAmount.add(feesAmount); - + List<ChargePaymentDTO> chargePaymentDTOs = new ArrayList<>(); - - for(ChargePaymentDTO chargePaymentDTO : loanTransactionDTO.getFeePayments()) { - chargePaymentDTOs.add(new ChargePaymentDTO(chargePaymentDTO.getChargeId(), chargePaymentDTO.getLoanChargeId(), - chargePaymentDTO.getAmount().floatValue() < 0 ? chargePaymentDTO.getAmount().multiply(new BigDecimal(-1)):chargePaymentDTO.getAmount() )); + + for (ChargePaymentDTO chargePaymentDTO : loanTransactionDTO.getFeePayments()) { + chargePaymentDTOs.add(new ChargePaymentDTO(chargePaymentDTO.getChargeId(), chargePaymentDTO.getLoanChargeId(), + chargePaymentDTO.getAmount().floatValue() < 0 ? chargePaymentDTO.getAmount().multiply(new BigDecimal(-1)) + : chargePaymentDTO.getAmount())); } this.helper.createCreditJournalEntryOrReversalForLoanCharges(office, currencyCode, CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.getValue(), loanProductId, loanId, transactionId, transactionDate, feesAmount, @@ -416,12 +464,13 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess if (penaltiesAmount != null && !(penaltiesAmount.compareTo(BigDecimal.ZERO) == 0)) { totalDebitAmount = totalDebitAmount.add(penaltiesAmount); List<ChargePaymentDTO> chargePaymentDTOs = new ArrayList<>(); - - for(ChargePaymentDTO chargePaymentDTO : loanTransactionDTO.getPenaltyPayments()) { - chargePaymentDTOs.add(new ChargePaymentDTO(chargePaymentDTO.getChargeId(), chargePaymentDTO.getLoanChargeId(), - chargePaymentDTO.getAmount().floatValue() < 0 ? chargePaymentDTO.getAmount().multiply(new BigDecimal(-1)):chargePaymentDTO.getAmount() )); + + for (ChargePaymentDTO chargePaymentDTO : loanTransactionDTO.getPenaltyPayments()) { + chargePaymentDTOs.add(new ChargePaymentDTO(chargePaymentDTO.getChargeId(), chargePaymentDTO.getLoanChargeId(), + chargePaymentDTO.getAmount().floatValue() < 0 ? chargePaymentDTO.getAmount().multiply(new BigDecimal(-1)) + : chargePaymentDTO.getAmount())); } - + this.helper.createCreditJournalEntryOrReversalForLoanCharges(office, currencyCode, CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue(), loanProductId, loanId, transactionId, transactionDate, penaltiesAmount, !isReversal, chargePaymentDTOs); @@ -434,8 +483,8 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess } /*** create a single debit entry (or reversal) for the entire amount **/ - this.helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue(), loanProductId, - paymentTypeId, loanId, transactionId, transactionDate, totalDebitAmount, !isReversal); - + this.helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue(), + loanProductId, paymentTypeId, loanId, transactionId, transactionDate, totalDebitAmount, !isReversal); + } } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java index cec29fb..0580a4c 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java @@ -39,8 +39,9 @@ public enum JobName { RECALCULATE_INTEREST_FOR_LOAN("Recalculate Interest For Loans"), // GENERATE_RD_SCEHDULE("Generate Mandatory Savings Schedule"), // GENERATE_LOANLOSS_PROVISIONING("Generate Loan Loss Provisioning"), // - POST_DIVIDENTS_FOR_SHARES("Post Dividends For Shares"), - UPDATE_SAVINGS_DORMANT_ACCOUNTS("Update Savings Dormant Accounts"); + POST_DIVIDENTS_FOR_SHARES("Post Dividends For Shares"), // + UPDATE_SAVINGS_DORMANT_ACCOUNTS("Update Savings Dormant Accounts"), // + ADD_PERIODIC_ACCRUAL_ENTRIES_FOR_LOANS_WITH_INCOME_POSTED_AS_TRANSACTIONS("Add Accrual Transactions For Loans With Income Posted As Transactions"); private final String name; http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/CalendarConstants.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/CalendarConstants.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/CalendarConstants.java index a15a71b..b96eee5 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/CalendarConstants.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/CalendarConstants.java @@ -31,7 +31,8 @@ public class CalendarConstants { "typeId"), REPEATING("repeating"), REMIND_BY_ID("remindById"), FIRST_REMINDER("firstReminder"), SECOND_REMINDER( "secondReminder"), LOCALE("locale"), DATE_FORMAT("dateFormat"), FREQUENCY("frequency"), INTERVAL("interval"), REPEATS_ON_DAY( "repeatsOnDay"), RESCHEDULE_BASED_ON_MEETING_DATES("reschedulebasedOnMeetingDates"), PRESENT_MEETING_DATE( - "presentMeetingDate"), NEW_MEETING_DATE("newMeetingDate"),MEETING_TIME("meetingtime"),Time_Format("timeFormat"), ; + "presentMeetingDate"), NEW_MEETING_DATE("newMeetingDate"),MEETING_TIME("meetingtime"),Time_Format("timeFormat"), REPEATS_ON_NTH_DAY_OF_MONTH("repeatsOnNthDayOfMonth"), + REPEATS_ON_LAST_WEEKDAY_OF_MONTH("repeatsOnLastWeekdayOfMonth"), REPEATS_ON_DAY_OF_MONTH("repeatsOnDayOfMonth"); private final String value; http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/api/CalendarsApiResource.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/api/CalendarsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/api/CalendarsApiResource.java index f2ac608..418c902 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/api/CalendarsApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/api/CalendarsApiResource.java @@ -230,8 +230,9 @@ public class CalendarsApiResource { final List<EnumOptionData> remindByOptions = this.dropdownReadPlatformService.retrieveCalendarRemindByOptions(); final List<EnumOptionData> frequencyOptions = this.dropdownReadPlatformService.retrieveCalendarFrequencyTypeOptions(); final List<EnumOptionData> repeatsOnDayOptions = this.dropdownReadPlatformService.retrieveCalendarWeekDaysTypeOptions(); + final List<EnumOptionData> frequencyNthDayTypeOptions = this.dropdownReadPlatformService.retrieveCalendarFrequencyNthDayTypeOptions(); return CalendarData.withTemplateOptions(calendarData, entityTypeOptions, calendarTypeOptions, remindByOptions, frequencyOptions, - repeatsOnDayOptions); + repeatsOnDayOptions, frequencyNthDayTypeOptions); } private CommandWrapper getResourceDetails(final CalendarEntityType type, final Long entityId) { http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/data/CalendarData.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/data/CalendarData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/data/CalendarData.java index de89923..2c6513a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/data/CalendarData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/data/CalendarData.java @@ -28,6 +28,7 @@ import org.apache.fineract.portfolio.calendar.domain.CalendarType; import org.apache.fineract.portfolio.calendar.domain.CalendarWeekDaysType; import org.apache.fineract.portfolio.calendar.service.CalendarEnumerations; import org.apache.fineract.portfolio.calendar.service.CalendarUtils; +import org.apache.fineract.portfolio.common.domain.NthDayType; import org.joda.time.LocalDate; import org.joda.time.LocalTime; @@ -53,6 +54,7 @@ public class CalendarData { private final EnumOptionData frequency; private final Integer interval; private final EnumOptionData repeatsOnDay; + private final EnumOptionData repeatsOnNthDayOfMonth; private final EnumOptionData remindBy; private final Integer firstReminder; private final Integer secondReminder; @@ -67,20 +69,24 @@ public class CalendarData { private final String createdByUsername; private final Long lastUpdatedByUserId; private final String lastUpdatedByUsername; + private final Integer repeatsOnDayOfMonth; + // template related final List<EnumOptionData> entityTypeOptions; final List<EnumOptionData> calendarTypeOptions; final List<EnumOptionData> remindByOptions; final List<EnumOptionData> frequencyOptions; final List<EnumOptionData> repeatsOnDayOptions; + final List<EnumOptionData> frequencyNthDayTypeOptions; public static CalendarData instance(final Long id, final Long calendarInstanceId, final Long entityId, final EnumOptionData entityType, final String title, final String description, final String location, final LocalDate startDate, final LocalDate endDate, final Integer duration, final EnumOptionData type, final boolean repeating, final String recurrence, - final EnumOptionData frequency, final Integer interval, final EnumOptionData repeatsOnDay, final EnumOptionData remindBy, - final Integer firstReminder, final Integer secondReminder, final String humanReadable, final LocalDate createdDate, - final LocalDate lastUpdatedDate, final Long createdByUserId, final String createdByUsername, final Long lastUpdatedByUserId, - final String lastUpdatedByUsername, final LocalTime meetingTime) { + final EnumOptionData frequency, final Integer interval, final EnumOptionData repeatsOnDay, + final EnumOptionData repeatsOnNthDayOfMonth, final EnumOptionData remindBy, final Integer firstReminder, + final Integer secondReminder, final String humanReadable, final LocalDate createdDate, final LocalDate lastUpdatedDate, + final Long createdByUserId, final String createdByUsername, final Long lastUpdatedByUserId, final String lastUpdatedByUsername, + final LocalTime meetingTime, final Integer repeatsOnDayOfMonth) { final Collection<LocalDate> recurringDates = null; final Collection<LocalDate> nextTenRecurringDates = null; @@ -91,12 +97,14 @@ public class CalendarData { final List<EnumOptionData> remindByOptions = null; final List<EnumOptionData> frequencyOptions = null; final List<EnumOptionData> repeatsOnDayOptions = null; + final List<EnumOptionData> frequencyNthDayTypeOptions = null; return new CalendarData(id, calendarInstanceId, entityId, entityType, title, description, location, startDate, endDate, duration, - type, repeating, recurrence, frequency, interval, repeatsOnDay, remindBy, firstReminder, secondReminder, recurringDates, - nextTenRecurringDates, humanReadable, recentEligibleMeetingDate, createdDate, lastUpdatedDate, createdByUserId, - createdByUsername, lastUpdatedByUserId, lastUpdatedByUsername, entityTypeOptions, calendarTypeOptions, remindByOptions, - frequencyOptions, repeatsOnDayOptions, meetingTime); + type, repeating, recurrence, frequency, interval, repeatsOnDay, repeatsOnNthDayOfMonth, remindBy, firstReminder, + secondReminder, recurringDates, nextTenRecurringDates, humanReadable, recentEligibleMeetingDate, createdDate, + lastUpdatedDate, createdByUserId, createdByUsername, lastUpdatedByUserId, lastUpdatedByUsername, repeatsOnDayOfMonth, + entityTypeOptions, calendarTypeOptions, remindByOptions, frequencyOptions, repeatsOnDayOptions, meetingTime, + frequencyNthDayTypeOptions); } public static CalendarData withRecurringDates(final CalendarData calendarData, final Collection<LocalDate> recurringDates, @@ -104,24 +112,24 @@ public class CalendarData { return new CalendarData(calendarData.id, calendarData.calendarInstanceId, calendarData.entityId, calendarData.entityType, calendarData.title, calendarData.description, calendarData.location, calendarData.startDate, calendarData.endDate, calendarData.duration, calendarData.type, calendarData.repeating, calendarData.recurrence, calendarData.frequency, - calendarData.interval, calendarData.repeatsOnDay, calendarData.remindBy, calendarData.firstReminder, + calendarData.interval, calendarData.repeatsOnDay, calendarData.repeatsOnNthDayOfMonth, calendarData.remindBy, calendarData.firstReminder, calendarData.secondReminder, recurringDates, nextTenRecurringDates, calendarData.humanReadable, recentEligibleMeetingDate, calendarData.createdDate, calendarData.lastUpdatedDate, calendarData.createdByUserId, calendarData.createdByUsername, - calendarData.lastUpdatedByUserId, calendarData.lastUpdatedByUsername, calendarData.entityTypeOptions, + calendarData.lastUpdatedByUserId, calendarData.lastUpdatedByUsername, calendarData.repeatsOnDayOfMonth, calendarData.entityTypeOptions, calendarData.calendarTypeOptions, calendarData.remindByOptions, calendarData.frequencyOptions, - calendarData.repeatsOnDayOptions,calendarData.meetingTime); + calendarData.repeatsOnDayOptions, calendarData.meetingTime, calendarData.frequencyNthDayTypeOptions); } public static CalendarData withRecentEligibleMeetingDate(final CalendarData calendarData, final LocalDate recentEligibleMeetingDate) { return new CalendarData(calendarData.id, calendarData.calendarInstanceId, calendarData.entityId, calendarData.entityType, calendarData.title, calendarData.description, calendarData.location, calendarData.startDate, calendarData.endDate, calendarData.duration, calendarData.type, calendarData.repeating, calendarData.recurrence, calendarData.frequency, - calendarData.interval, calendarData.repeatsOnDay, calendarData.remindBy, calendarData.firstReminder, + calendarData.interval, calendarData.repeatsOnDay, calendarData.repeatsOnNthDayOfMonth, calendarData.remindBy, calendarData.firstReminder, calendarData.secondReminder, calendarData.recurringDates, calendarData.nextTenRecurringDates, calendarData.humanReadable, recentEligibleMeetingDate, calendarData.createdDate, calendarData.lastUpdatedDate, calendarData.createdByUserId, calendarData.createdByUsername, calendarData.lastUpdatedByUserId, calendarData.lastUpdatedByUsername, - calendarData.entityTypeOptions, calendarData.calendarTypeOptions, calendarData.remindByOptions, - calendarData.frequencyOptions, calendarData.repeatsOnDayOptions,calendarData.meetingTime); + calendarData.repeatsOnDayOfMonth, calendarData.entityTypeOptions, calendarData.calendarTypeOptions, calendarData.remindByOptions, + calendarData.frequencyOptions, calendarData.repeatsOnDayOptions,calendarData.meetingTime, calendarData.frequencyNthDayTypeOptions); } public static CalendarData sensibleDefaultsForNewCalendarCreation() { @@ -141,6 +149,7 @@ public class CalendarData { final EnumOptionData frequency = CalendarEnumerations.calendarFrequencyType(CalendarFrequencyType.DAILY); final Integer interval = new Integer(1); final EnumOptionData repeatsOnDay = CalendarEnumerations.calendarWeekDaysType(CalendarWeekDaysType.MO); + final EnumOptionData repeatsOnNthDayOfMonth = CalendarEnumerations.calendarFrequencyNthDayType(NthDayType.ONE); final EnumOptionData remindBy = CalendarEnumerations.calendarRemindBy(CalendarRemindBy.EMAIL); final Integer firstReminder = new Integer(0); final Integer secondReminder = new Integer(0); @@ -154,6 +163,7 @@ public class CalendarData { final List<EnumOptionData> remindByOptions = null; final List<EnumOptionData> frequencyOptions = null; final List<EnumOptionData> repeatsOnDayOptions = null; + final List<EnumOptionData> frequencyNthDayTypeOptions = null; final LocalDate createdDate = null; final LocalDate lastUpdatedDate = null; @@ -162,39 +172,44 @@ public class CalendarData { final Long lastUpdatedByUserId = null; final String lastUpdatedByUsername = null; final LocalTime meetingTime = null; + final Integer repeatsOnDayOfMonth = null; return new CalendarData(id, calendarInstanceId, entityId, entityType, title, description, location, startDate, endDate, duration, - type, repeating, recurrence, frequency, interval, repeatsOnDay, remindBy, firstReminder, secondReminder, recurringDates, - nextTenRecurringDates, humanReadable, recentEligibleMeetingDate, createdDate, lastUpdatedDate, createdByUserId, - createdByUsername, lastUpdatedByUserId, lastUpdatedByUsername, entityTypeOptions, calendarTypeOptions, remindByOptions, - frequencyOptions, repeatsOnDayOptions, meetingTime); + type, repeating, recurrence, frequency, interval, repeatsOnDay, repeatsOnNthDayOfMonth, remindBy, firstReminder, + secondReminder, recurringDates, nextTenRecurringDates, humanReadable, recentEligibleMeetingDate, createdDate, + lastUpdatedDate, createdByUserId, createdByUsername, lastUpdatedByUserId, lastUpdatedByUsername, repeatsOnDayOfMonth, + entityTypeOptions, calendarTypeOptions, remindByOptions, frequencyOptions, repeatsOnDayOptions, meetingTime, + frequencyNthDayTypeOptions); } public static CalendarData withTemplateOptions(final CalendarData calendarData, final List<EnumOptionData> entityTypeOptions, final List<EnumOptionData> calendarTypeOptions, final List<EnumOptionData> remindByOptions, - final List<EnumOptionData> repeatsOptions, final List<EnumOptionData> repeatsOnDayOptions) { + final List<EnumOptionData> repeatsOptions, final List<EnumOptionData> repeatsOnDayOptions, + final List<EnumOptionData> frequencyNthDayTypeOptions) { return new CalendarData(calendarData.id, calendarData.calendarInstanceId, calendarData.entityId, calendarData.entityType, calendarData.title, calendarData.description, calendarData.location, calendarData.startDate, calendarData.endDate, calendarData.duration, calendarData.type, calendarData.repeating, calendarData.recurrence, calendarData.frequency, - calendarData.interval, calendarData.repeatsOnDay, calendarData.remindBy, calendarData.firstReminder, - calendarData.secondReminder, calendarData.recurringDates, calendarData.nextTenRecurringDates, calendarData.humanReadable, - calendarData.recentEligibleMeetingDate, calendarData.createdDate, calendarData.lastUpdatedDate, + calendarData.interval, calendarData.repeatsOnDay, calendarData.repeatsOnNthDayOfMonth, calendarData.remindBy, + calendarData.firstReminder, calendarData.secondReminder, calendarData.recurringDates, calendarData.nextTenRecurringDates, + calendarData.humanReadable, calendarData.recentEligibleMeetingDate, calendarData.createdDate, calendarData.lastUpdatedDate, calendarData.createdByUserId, calendarData.createdByUsername, calendarData.lastUpdatedByUserId, - calendarData.lastUpdatedByUsername, entityTypeOptions, calendarTypeOptions, remindByOptions, repeatsOptions, - repeatsOnDayOptions,calendarData.meetingTime); + calendarData.lastUpdatedByUsername, calendarData.repeatsOnDayOfMonth, entityTypeOptions, calendarTypeOptions, + remindByOptions, repeatsOptions, repeatsOnDayOptions, calendarData.meetingTime, frequencyNthDayTypeOptions); } private CalendarData(final Long id, final Long calendarInstanceId, final Long entityId, final EnumOptionData entityType, final String title, final String description, final String location, final LocalDate startDate, final LocalDate endDate, final Integer duration, final EnumOptionData type, final boolean repeating, final String recurrence, - final EnumOptionData frequency, final Integer interval, final EnumOptionData repeatsOnDay, final EnumOptionData remindBy, - final Integer firstReminder, final Integer secondReminder, final Collection<LocalDate> recurringDates, - final Collection<LocalDate> nextTenRecurringDates, final String humanReadable, final LocalDate recentEligibleMeetingDate, - final LocalDate createdDate, final LocalDate lastUpdatedDate, final Long createdByUserId, final String createdByUsername, - final Long lastUpdatedByUserId, final String lastUpdatedByUsername, final List<EnumOptionData> entityTypeOptions, + final EnumOptionData frequency, final Integer interval, final EnumOptionData repeatsOnDay, + final EnumOptionData repeatsOnNthDayOfMonth, final EnumOptionData remindBy, final Integer firstReminder, + final Integer secondReminder, final Collection<LocalDate> recurringDates, final Collection<LocalDate> nextTenRecurringDates, + final String humanReadable, final LocalDate recentEligibleMeetingDate, final LocalDate createdDate, + final LocalDate lastUpdatedDate, final Long createdByUserId, final String createdByUsername, final Long lastUpdatedByUserId, + final String lastUpdatedByUsername, final Integer repeatsOnDayOfMonth, final List<EnumOptionData> entityTypeOptions, final List<EnumOptionData> calendarTypeOptions, final List<EnumOptionData> remindByOptions, - final List<EnumOptionData> repeatsOptions, final List<EnumOptionData> repeatsOnDayOptions,final LocalTime meetingTime) { + final List<EnumOptionData> repeatsOptions, final List<EnumOptionData> repeatsOnDayOptions,final LocalTime meetingTime, + final List<EnumOptionData> frequencyNthDayTypeOptions) { this.id = id; this.calendarInstanceId = calendarInstanceId; this.entityId = entityId; @@ -211,6 +226,7 @@ public class CalendarData { this.frequency = frequency; this.interval = interval; this.repeatsOnDay = repeatsOnDay; + this.repeatsOnNthDayOfMonth = repeatsOnNthDayOfMonth; this.remindBy = remindBy; this.firstReminder = firstReminder; this.secondReminder = secondReminder; @@ -224,12 +240,14 @@ public class CalendarData { this.createdByUsername = createdByUsername; this.lastUpdatedByUserId = lastUpdatedByUserId; this.lastUpdatedByUsername = lastUpdatedByUsername; + this.repeatsOnDayOfMonth = repeatsOnDayOfMonth; this.entityTypeOptions = entityTypeOptions; this.calendarTypeOptions = calendarTypeOptions; this.remindByOptions = remindByOptions; this.frequencyOptions = repeatsOptions; this.repeatsOnDayOptions = repeatsOnDayOptions; this.meetingTime = meetingTime; + this.frequencyNthDayTypeOptions = frequencyNthDayTypeOptions; } public Long getId() { @@ -350,4 +368,10 @@ public class CalendarData { public EnumOptionData frequencyType(){ return this.frequency; } + public EnumOptionData getRepeatsOnDay() { + return this.repeatsOnDay; + } + public EnumOptionData getRepeatsOnNthDayOfMonth() { + return this.repeatsOnNthDayOfMonth; + } } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/Calendar.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/Calendar.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/Calendar.java index f44dfdd..f2fa718 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/Calendar.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/Calendar.java @@ -48,6 +48,7 @@ import org.apache.fineract.portfolio.calendar.CalendarConstants.CALENDAR_SUPPORT import org.apache.fineract.portfolio.calendar.exception.CalendarDateException; import org.apache.fineract.portfolio.calendar.exception.CalendarParameterUpdateNotSupportedException; import org.apache.fineract.portfolio.calendar.service.CalendarUtils; +import org.apache.fineract.portfolio.common.domain.NthDayType; import org.apache.fineract.useradministration.domain.AppUser; import org.apache.poi.openxml4j.util.Nullable; import org.joda.time.LocalDate; @@ -152,8 +153,9 @@ public class Calendar extends AbstractAuditableCustom<AppUser, Long> { } public static Calendar createRepeatingCalendar(final String title, final LocalDate startDate, final Integer typeId, - final CalendarFrequencyType frequencyType, final Integer interval, final Integer repeatsOnDay) { - final String recurrence = constructRecurrence(frequencyType, interval, repeatsOnDay); + final CalendarFrequencyType frequencyType, final Integer interval, final Integer repeatsOnDay, + final Integer repeatsOnNthDayOfMonth) { + final String recurrence = constructRecurrence(frequencyType, interval, repeatsOnDay, repeatsOnNthDayOfMonth); return createRepeatingCalendar(title, startDate, typeId, recurrence); } @@ -245,7 +247,7 @@ public class Calendar extends AbstractAuditableCustom<AppUser, Long> { // TODO cover other recurrence also - this.recurrence = constructRecurrence(calendarFrequencyType, interval, repeatsOnDay); + this.recurrence = constructRecurrence(calendarFrequencyType, interval, repeatsOnDay, null); } @@ -422,7 +424,7 @@ public class Calendar extends AbstractAuditableCustom<AppUser, Long> { @SuppressWarnings("null") public Map<String, Object> updateRepeatingCalendar(final LocalDate calendarStartDate, final CalendarFrequencyType frequencyType, - final Integer interval, final Integer repeatsOnDay) { + final Integer interval, final Integer repeatsOnDay, final Integer repeatsOnNthDay) { final Map<String, Object> actualChanges = new LinkedHashMap<>(9); if (calendarStartDate != null & this.startDate != null) { @@ -432,7 +434,7 @@ public class Calendar extends AbstractAuditableCustom<AppUser, Long> { } } - final String newRecurrence = Calendar.constructRecurrence(frequencyType, interval, repeatsOnDay); + final String newRecurrence = Calendar.constructRecurrence(frequencyType, interval, repeatsOnDay, repeatsOnNthDay); if (!StringUtils.isBlank(this.recurrence) && !newRecurrence.equalsIgnoreCase(this.recurrence)) { actualChanges.put("recurrence", newRecurrence); this.recurrence = newRecurrence; @@ -568,13 +570,27 @@ public class Calendar extends AbstractAuditableCustom<AppUser, Long> { if (frequencyType.isWeekly()) { repeatsOnDay = command.integerValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.REPEATS_ON_DAY.getValue()); } + Integer repeatsOnNthDayOfMonth = null; + if (frequencyType.isMonthly()) { + repeatsOnNthDayOfMonth = command.integerValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.REPEATS_ON_NTH_DAY_OF_MONTH + .getValue()); + final NthDayType nthDay = NthDayType.fromInt(repeatsOnNthDayOfMonth); + repeatsOnDay = command.integerValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.REPEATS_ON_LAST_WEEKDAY_OF_MONTH + .getValue()); + if (nthDay.isOnDay()) { + repeatsOnNthDayOfMonth = command.integerValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.REPEATS_ON_DAY_OF_MONTH + .getValue()); + repeatsOnDay = null; + } + } - return constructRecurrence(frequencyType, interval, repeatsOnDay); + return constructRecurrence(frequencyType, interval, repeatsOnDay, repeatsOnNthDayOfMonth); } return ""; } - private static String constructRecurrence(final CalendarFrequencyType frequencyType, final Integer interval, final Integer repeatsOnDay) { + private static String constructRecurrence(final CalendarFrequencyType frequencyType, final Integer interval, + final Integer repeatsOnDay, final Integer repeatsOnNthDayOfMonth) { final StringBuilder recurrenceBuilder = new StringBuilder(200); recurrenceBuilder.append("FREQ="); @@ -584,10 +600,31 @@ public class Calendar extends AbstractAuditableCustom<AppUser, Long> { recurrenceBuilder.append(interval); } if (frequencyType.isWeekly()) { - final CalendarWeekDaysType weekDays = CalendarWeekDaysType.fromInt(repeatsOnDay); - if (!weekDays.isInvalid()) { - recurrenceBuilder.append(";BYDAY="); - recurrenceBuilder.append(weekDays.toString().toUpperCase()); + if (repeatsOnDay != null) { + final CalendarWeekDaysType weekDays = CalendarWeekDaysType.fromInt(repeatsOnDay); + if (!weekDays.isInvalid()) { + recurrenceBuilder.append(";BYDAY="); + recurrenceBuilder.append(weekDays.toString().toUpperCase()); + } + } + } + if (frequencyType.isMonthly()) { + if (repeatsOnNthDayOfMonth != null && (repeatsOnDay == null || repeatsOnDay == CalendarWeekDaysType.INVALID.getValue())) { + if (repeatsOnNthDayOfMonth >= -1 && repeatsOnNthDayOfMonth <= 28) { + recurrenceBuilder.append(";BYMONTHDAY="); + recurrenceBuilder.append(repeatsOnNthDayOfMonth); + } + } else if (repeatsOnNthDayOfMonth != null && repeatsOnDay != null && repeatsOnDay != CalendarWeekDaysType.INVALID.getValue()) { + final NthDayType nthDay = NthDayType.fromInt(repeatsOnNthDayOfMonth); + if (!nthDay.isInvalid()) { + recurrenceBuilder.append(";BYSETPOS="); + recurrenceBuilder.append(nthDay.getValue()); + } + final CalendarWeekDaysType weekday = CalendarWeekDaysType.fromInt(repeatsOnDay); + if (!weekday.isInvalid()) { + recurrenceBuilder.append(";BYDAY="); + recurrenceBuilder.append(weekday.toString().toUpperCase()); + } } } return recurrenceBuilder.toString(); @@ -611,18 +648,22 @@ public class Calendar extends AbstractAuditableCustom<AppUser, Long> { final CalendarFrequencyType frequencyType = CalendarUtils.getFrequency(this.recurrence); final Integer interval = new Integer(CalendarUtils.getInterval(this.recurrence)); - final String newRecurrence = Calendar.constructRecurrence(frequencyType, interval, startDate.getDayOfWeek()); + final String newRecurrence = Calendar.constructRecurrence(frequencyType, interval, startDate.getDayOfWeek(), null); this.recurrence = newRecurrence; this.startDate = startDate.toDate(); this.endDate = endDate.toDate(); } - - public Set<CalendarHistory> getCalendarHistory(){ - return this.calendarHistory; + + public Set<CalendarHistory> getCalendarHistory() { + return this.calendarHistory; } - - public void updateCalendarHistory(final Set<CalendarHistory> calendarHistory){ - this.calendarHistory = calendarHistory; + + public void updateCalendarHistory(final Set<CalendarHistory> calendarHistory) { + this.calendarHistory = calendarHistory; + } + + public void setRecurrence(String recurrence) { + this.recurrence = recurrence; } } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarInstance.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarInstance.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarInstance.java index 6c40b04..6ae6c60 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarInstance.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarInstance.java @@ -31,7 +31,7 @@ import org.springframework.data.jpa.domain.AbstractPersistable; @Table(name = "m_calendar_instance") public class CalendarInstance extends AbstractPersistable<Long> { - @ManyToOne(cascade = CascadeType.ALL) + @ManyToOne(cascade = CascadeType.PERSIST) @JoinColumn(name = "calendar_id", nullable = false) private Calendar calendar; http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/serialization/CalendarCommandFromApiJsonDeserializer.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/serialization/CalendarCommandFromApiJsonDeserializer.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/serialization/CalendarCommandFromApiJsonDeserializer.java index c956afa..fcdd2e2 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/serialization/CalendarCommandFromApiJsonDeserializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/serialization/CalendarCommandFromApiJsonDeserializer.java @@ -37,6 +37,7 @@ import org.apache.fineract.portfolio.calendar.domain.CalendarEntityType; import org.apache.fineract.portfolio.calendar.domain.CalendarFrequencyType; import org.apache.fineract.portfolio.calendar.domain.CalendarRemindBy; import org.apache.fineract.portfolio.calendar.domain.CalendarWeekDaysType; +import org.apache.fineract.portfolio.calendar.service.CalendarUtils; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.springframework.beans.factory.annotation.Autowired; @@ -173,6 +174,10 @@ public class CalendarCommandFromApiJsonDeserializer extends AbstractFromApiJsonD CALENDAR_SUPPORTED_PARAMETERS.REPEATS_ON_DAY.getValue(), element); baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.REPEATS_ON_DAY.getValue()).value(repeatsOnDay) .notBlank().inMinMaxRange(CalendarWeekDaysType.getMinValue(), CalendarWeekDaysType.getMaxValue()); + } else if (CalendarFrequencyType.fromInt(frequency).isMonthly()) { + CalendarUtils.validateNthDayOfMonthFrequency(baseDataValidator, + CALENDAR_SUPPORTED_PARAMETERS.REPEATS_ON_NTH_DAY_OF_MONTH.getValue(), + CALENDAR_SUPPORTED_PARAMETERS.REPEATS_ON_LAST_WEEKDAY_OF_MONTH.getValue(), element, this.fromApiJsonHelper); } } } @@ -305,11 +310,17 @@ public class CalendarCommandFromApiJsonDeserializer extends AbstractFromApiJsonD .integerGreaterThanZero(); } + if (CalendarFrequencyType.fromInt(frequency).isWeekly()) { if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.REPEATS_ON_DAY.getValue(), element)) { final Integer repeatsOnDay = this.fromApiJsonHelper.extractIntegerSansLocaleNamed( CALENDAR_SUPPORTED_PARAMETERS.REPEATS_ON_DAY.getValue(), element); baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.REPEATS_ON_DAY.getValue()).value(repeatsOnDay) .notBlank().inMinMaxRange(CalendarWeekDaysType.getMinValue(), CalendarWeekDaysType.getMaxValue()); + } + } else if (CalendarFrequencyType.fromInt(frequency).isMonthly()) { + CalendarUtils.validateNthDayOfMonthFrequency(baseDataValidator, + CALENDAR_SUPPORTED_PARAMETERS.REPEATS_ON_NTH_DAY_OF_MONTH.getValue(), + CALENDAR_SUPPORTED_PARAMETERS.REPEATS_ON_LAST_WEEKDAY_OF_MONTH.getValue(), element, this.fromApiJsonHelper); } } } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarDropdownReadPlatformService.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarDropdownReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarDropdownReadPlatformService.java index 1c95c77..c670643 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarDropdownReadPlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarDropdownReadPlatformService.java @@ -33,5 +33,6 @@ public interface CalendarDropdownReadPlatformService { List<EnumOptionData> retrieveCalendarFrequencyTypeOptions(); List<EnumOptionData> retrieveCalendarWeekDaysTypeOptions(); + List<EnumOptionData> retrieveCalendarFrequencyNthDayTypeOptions(); } \ 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/calendar/service/CalendarDropdownReadPlatformServiceImpl.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarDropdownReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarDropdownReadPlatformServiceImpl.java index 713a38c..7881180 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarDropdownReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarDropdownReadPlatformServiceImpl.java @@ -55,4 +55,8 @@ public class CalendarDropdownReadPlatformServiceImpl implements CalendarDropdown public List<EnumOptionData> retrieveCalendarWeekDaysTypeOptions() { return CalendarEnumerations.calendarWeekDaysType(CalendarWeekDaysType.values()); } + @Override + public List<EnumOptionData> retrieveCalendarFrequencyNthDayTypeOptions() { + return CalendarEnumerations.calendarFrequencyNthDayType(); + } } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarEnumerations.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarEnumerations.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarEnumerations.java index e96dba6..15c74ec 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarEnumerations.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarEnumerations.java @@ -19,6 +19,7 @@ package org.apache.fineract.portfolio.calendar.service; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.apache.fineract.infrastructure.core.data.EnumOptionData; @@ -27,6 +28,7 @@ import org.apache.fineract.portfolio.calendar.domain.CalendarFrequencyType; import org.apache.fineract.portfolio.calendar.domain.CalendarRemindBy; import org.apache.fineract.portfolio.calendar.domain.CalendarType; import org.apache.fineract.portfolio.calendar.domain.CalendarWeekDaysType; +import org.apache.fineract.portfolio.common.domain.NthDayType; public class CalendarEnumerations { @@ -86,8 +88,11 @@ public class CalendarEnumerations { } public static EnumOptionData calendarFrequencyType(final CalendarFrequencyType calendarFrequencyType) { - final EnumOptionData optionData = new EnumOptionData(calendarFrequencyType.getValue().longValue(), calendarFrequencyType.getCode(), + EnumOptionData optionData = null; + if (!calendarFrequencyType.isInvalid()) { + optionData = new EnumOptionData(calendarFrequencyType.getValue().longValue(), calendarFrequencyType.getCode(), calendarFrequencyType.toString()); + } return optionData; } @@ -106,8 +111,11 @@ public class CalendarEnumerations { } public static EnumOptionData calendarWeekDaysType(final CalendarWeekDaysType calendarWeekDaysType) { - final EnumOptionData optionData = new EnumOptionData(calendarWeekDaysType.getValue().longValue(), calendarWeekDaysType.getCode(), + EnumOptionData optionData = null; + if (!calendarWeekDaysType.isInvalid()) { + optionData = new EnumOptionData(calendarWeekDaysType.getValue().longValue(), calendarWeekDaysType.getCode(), calendarWeekDaysType.toString()); + } return optionData; } @@ -120,4 +128,19 @@ public class CalendarEnumerations { } return optionDatas; } + public static EnumOptionData calendarFrequencyNthDayType(final int id) { + return calendarFrequencyNthDayType(NthDayType.fromInt(id)); + } + public static EnumOptionData calendarFrequencyNthDayType(final NthDayType calendarFrequencyNthDayType) { + final EnumOptionData optionData = new EnumOptionData(calendarFrequencyNthDayType.getValue().longValue(), calendarFrequencyNthDayType.getCode(), + calendarFrequencyNthDayType.toString()); + return optionData; + } + public static List<EnumOptionData> calendarFrequencyNthDayType() { + final List<EnumOptionData> optionDatas = Arrays.asList(calendarFrequencyNthDayType(NthDayType.ONE), + calendarFrequencyNthDayType(NthDayType.TWO), calendarFrequencyNthDayType(NthDayType.THREE), + calendarFrequencyNthDayType(NthDayType.FOUR), calendarFrequencyNthDayType(NthDayType.LAST), + calendarFrequencyNthDayType(NthDayType.ONDAY)); + return optionDatas; + } } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java index 3b5c37c..c9e7068 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java @@ -89,6 +89,7 @@ public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformServ final EnumOptionData frequency = CalendarEnumerations.calendarFrequencyType(CalendarUtils.getFrequency(recurrence)); final Integer interval = new Integer(CalendarUtils.getInterval(recurrence)); final EnumOptionData repeatsOnDay = CalendarEnumerations.calendarWeekDaysType(CalendarUtils.getRepeatsOnDay(recurrence)); + final EnumOptionData repeatsOnNthDayOfMonth = CalendarEnumerations.calendarFrequencyNthDayType(CalendarUtils.getRepeatsOnNthDayOfMonth(recurrence)); final Integer remindById = rs.getInt("remindById"); EnumOptionData remindBy = null; if (remindById != null && remindById != 0) { @@ -100,7 +101,7 @@ public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformServ if (startDate != null && recurrence != null) { humanReadable = CalendarUtils.getRRuleReadable(startDate, recurrence); } - + Integer monthOnDay = CalendarUtils.getMonthOnDay(recurrence); final LocalDate createdDate = JdbcSupport.getLocalDate(rs, "createdDate"); final LocalDate lastUpdatedDate = JdbcSupport.getLocalDate(rs, "updatedDate"); final Long createdByUserId = rs.getLong("creatingUserId"); @@ -110,9 +111,9 @@ public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformServ final LocalTime meetingTime = JdbcSupport.getLocalTime(rs,"meetingTime"); return CalendarData.instance(id, calendarInstanceId, entityId, entityType, title, description, location, startDate, endDate, - duration, type, repeating, recurrence, frequency, interval, repeatsOnDay, remindBy, firstReminder, secondReminder, + duration, type, repeating, recurrence, frequency, interval, repeatsOnDay, repeatsOnNthDayOfMonth, remindBy, firstReminder, secondReminder, humanReadable, createdDate, lastUpdatedDate, createdByUserId, createdByUserName, lastUpdatedByUserId, - lastUpdatedByUserName,meetingTime); + lastUpdatedByUserName,meetingTime, monthOnDay); } } @@ -479,6 +480,8 @@ public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformServ final EnumOptionData frequency = CalendarEnumerations.calendarFrequencyType(CalendarUtils.getFrequency(recurrence)); final Integer interval = new Integer(CalendarUtils.getInterval(recurrence)); final EnumOptionData repeatsOnDay = CalendarEnumerations.calendarWeekDaysType(CalendarUtils.getRepeatsOnDay(recurrence)); + final EnumOptionData repeatsOnNthDayOfMonth = CalendarEnumerations.calendarFrequencyNthDayType(CalendarUtils + .getRepeatsOnNthDayOfMonth(recurrence)); final Integer remindById = rs.getInt("remindById"); EnumOptionData remindBy = null; if (remindById != null && remindById != 0) { @@ -498,11 +501,12 @@ public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformServ final Long lastUpdatedByUserId = null; final String lastUpdatedByUserName = null; final LocalTime meetingTime = null; + Integer monthOnDay = CalendarUtils.getMonthOnDay(recurrence); return CalendarData.instance(id, calendarInstanceId, entityId, entityType, title, description, location, startDate, endDate, - duration, type, repeating, recurrence, frequency, interval, repeatsOnDay, remindBy, firstReminder, secondReminder, - humanReadable, createdDate, lastUpdatedDate, createdByUserId, createdByUserName, lastUpdatedByUserId, - lastUpdatedByUserName, meetingTime); + duration, type, repeating, recurrence, frequency, interval, repeatsOnDay, repeatsOnNthDayOfMonth, remindBy, + firstReminder, secondReminder, humanReadable, createdDate, lastUpdatedDate, createdByUserId, createdByUserName, + lastUpdatedByUserId, lastUpdatedByUserName, meetingTime, monthOnDay); } }