From fc2d90db7b57d4cb444310969f99be4ec34d7fac Mon Sep 17 00:00:00 2001 From: Madhukar Date: Thu, 26 Jun 2014 06:18:31 +0530 Subject: [PATCH] MIFOSX-1358,MIFOSX-1357 --- api-docs/apiLive.htm | 613 +++++++++++++++++- .../holiday/service/HolidayUtil.java | 14 +- .../workingdays/service/WorkingDaysUtil.java | 4 + .../portfolio/loanaccount/domain/Loan.java | 1 + .../domain/DefaultScheduledDateGenerator.java | 15 +- 5 files changed, 639 insertions(+), 8 deletions(-) diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm index f03c3b2ef..8c30e26c5 100644 --- a/api-docs/apiLive.htm +++ b/api-docs/apiLive.htm @@ -730,20 +730,60 @@ - recurringdepositaccounts/{accountId}?command=calculateInterest - Calculate interest on a recurring deposit account + recurringdepositaccounts/{accountId}?command=postInterest + Post interest on a recurring deposit account + + + + + + Recurring Deposit Transactions + recurringdepositaccounts/{accountId}/transactions?command=deposit + Make a deposit - recurringdepositaccounts/{accountId}?command=postInterest - Post interest on a recurring deposit account + recurringdepositaccounts/{accountId}/transactions?command=withdrawal + Make a withdrawal + + + recurringdepositaccounts/{accountId}/transactions/{transactionId}?command=undo + Undo transaction + + + + + + + recurringdepositaccounts/{accountId}/transactions/{transactionId}?command=modify + Adjust transaction + + + + + + + recurringdepositaccounts/{accountId}/transactions/template + + Retrieve Deposit account transaction template + + + + + + recurringdepositaccounts/{accountId}/transactions/{transactionId} + + Retrieve Deposit account transaction + + + @@ -21910,6 +21950,291 @@ No Request Body: "officeId": 1, "clientId": 1, "resourceId": 1 +} + + + +   +
+
+

Recurring Deposit Account Transactions:

+

Transactions possible on a recurring deposit account.

+ + + + + + + + +
Field Descriptions
transactionDate
The date of the transaction.
transactionAmount
The amount of the transaction.
+
+
+ +   +
+
+

Retrieve Recurring Deposit Account Transaction Template:

+

This is a convenience resource. It can be useful when building maintenance user interface screens for client applications. The template data returned consists of any or all of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Requests:

+
recurringdepositaccounts/1/transactions/template?command=deposit
+
+
recurringdepositaccounts/1/transactions/template?command=withdrawal
+
+
+ GET https://Domain Name/api/v1/recurringdepositaccounts/{accountId}/transactions/template?command=deposit + + +{ + "id": 1, + "transactionType": { + "id": 1, + "code": "savingsAccountTransactionType.deposit", + "value": "Deposit", + "deposit": true, + "withdrawal": false, + "interestPosting": false, + "feeDeduction": false, + "initiateTransfer": false, + "approveTransfer": false, + "withdrawTransfer": false, + "rejectTransfer": false, + "overdraftInterest": false, + "writtenoff": false, + "overdraftFee": true + }, + "accountId": 1, + "accountNo": "000000001", + "date": [ + 2014, + 6, + 25 + ], + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 4, + "inMultiplesOf": 100, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100000.000000, + "reversed": false, + "paymentTypeOptions": [] +} + +
+
+ +  +
+
+

Retrieve Recurring Deposit Account Transaction:

+

Example Requests:

+
recurringdepositaccounts/1/transactions/1
+
+
+
+ GET https://Domain Name/api/v1/recurringdepositaccounts/{accountId}/transactions/{transactionId} + + +{ + "id": 1, + "transactionType": { + "id": 2, + "code": "savingsAccountTransactionType.withdrawal", + "value": "Withdrawal", + "deposit": false, + "withdrawal": true, + "interestPosting": false, + "feeDeduction": false + }, + "accountId": 1, + "accountNo": "000000001", + "date": [ + 2013, + 8, + 7 + ], + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 0, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "paymentDetailData": { + "id": 62, + "paymentType": { + "id": 11, + "name": "cash" + }, + "accountNumber": "", + "checkNumber": "", + "routingCode": "", + "receiptNumber": "", + "bankNumber": "" + }, + "amount": 5000, + "runningBalance": 0, + "reversed": true +} + +
+
+ +   +
+
+

Deposit Transaction

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountsId}/transactions?command=deposit + POST recurringdepositaccounts/1/transactions?command=deposit +Content-Type: application/json +No Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "transactionDate": "27 May 2013", + "transactionAmount": "500", + "paymentTypeId": "14", + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" +} + + +{ + "officeId": 1, + "clientId": 2, + "savingsId": 1, + "resourceId": 47, + "changes": { + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" + } +} + +
+
+ +   +
+
+

Withdrawal Transaction

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountsId}/transactions?command=withdrawal + POST recurringdepositaccounts/1/transactions?command=withdrawal +Content-Type: application/json +No Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "transactionDate": "27 May 2013", + "transactionAmount": "500", + "paymentTypeId": "14", + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" +} + + +{ + "officeId": 1, + "clientId": 2, + "savingsId": 1, + "resourceId": 48, + "changes": { + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" + } +} + +
+
+ +   +
+
+

Adjust Transaction

+

This command modifies the given transaction.

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountsId}/transactions/{transactionId}?command=modify + POST recurringdepositaccounts/1/transactions/1?command=modify +Content-Type: application/json +No Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "transactionDate": "27 May 2013", + "transactionAmount": "500", + "paymentTypeId": "14", + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" +} + + +{ + "officeId": 1, + "clientId": 2, + "savingsId": 1, + "resourceId": 48, + "changes": { + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" + } +} + +
+
+ +   +
+
+

Undo transaction

+

This command reverses the given transaction.

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountsId}/transactions/{transactionId}?command=undo + POST recurringdepositaccounts/1/transactions/1?command=undo +Content-Type: application/json +No Request Body: +{ +} + + +{ + "officeId": 1, + "clientId": 2, + "savingsId": 1, + "resourceId": 1 }
@@ -24241,6 +24566,14 @@ No Request Body: An array of columns in the new Data Table. + + Optional - multiRow + + + Allows to create multiple entries in the Data Table. Optional, defaults to false. + If this property is not provided Data Table will allow only one entry. + + @@ -31472,6 +31805,278 @@ No Request Body: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Fixed Deposit ProductfixeddepositproductsCreate a Fixed Deposit productList Fixed Deposit products
fixeddepositproducts/{productId}Retrieve a Fixed Deposit productUpdate a Fixed Deposit productDelete a Fixed Deposit product
Fixed Deposit AccountsfixeddepositaccountsSubmit new fixed deposit applicationList fixed deposit application/accounts
fixeddepositaccounts/{accountId}Retrieve a fixed deposit application/accountModify a fixed deposit applicationDelete a fixed deposit application
fixeddepositaccounts/{accountId}?command=approveApprove a fixed deposit application
fixeddepositaccounts/{accountId}?command=undoApprovalUndo fixed deposit application approval
fixeddepositaccounts/{accountId}?command=rejectReject a fixed deposit application
fixeddepositaccounts/{accountId}?command=withdrawWithdraw fixed deposit application
fixeddepositaccounts/{accountId}?command=activateActivate a fixed deposit account
fixeddepositaccounts/{accountId}?command=closeClose a fixed deposit account
fixeddepositaccounts/{accountId}?command=prematureClosePremature Close a fixed deposit account
fixeddepositaccounts/{accountId}?command=calculatePrematureAmountCalculate Premature amount on a fixed deposit account
fixeddepositaccounts/{accountId}?command=calculateInterestCalculate interest on a fixed deposit account
fixeddepositaccounts/{accountId}?command=postInterestPost interest on a fixed deposit account
Recurring Deposit ProductrecurringdepositproductsCreate a Recurring Deposit productList Recurring Deposit products
recurringdepositproducts/{productId}Retrieve a Recurring Deposit productUpdate a Recurring Deposit productDelete a Recurring Deposit product
Recurring Deposit AccountsrecurringdepositaccountsSubmit new recurring deposit applicationList recurring deposit application/accounts
recurringdepositaccounts/{accountId}Retrieve a recurring deposit application/accountModify a recurring deposit applicationDelete a recurring deposit application
recurringdepositaccounts/{accountId}?command=approveApprove a recurring deposit application
recurringdepositaccounts/{accountId}?command=undoApprovalUndo recurring deposit application approval
recurringdepositaccounts/{accountId}?command=rejectReject a recurring deposit application
recurringdepositaccounts/{accountId}?command=withdrawWithdraw recurring deposit application
recurringdepositaccounts/{accountId}?command=activateActivate a recurring deposit account
recurringdepositaccounts/{accountId}?command=closeClose a recurring deposit account
recurringdepositaccounts/{accountId}?command=prematureClosePremature Close a recurring deposit account
recurringdepositaccounts/{accountId}?command=calculatePrematureAmountCalculate Premature amount on a recurring deposit account
recurringdepositaccounts/{accountId}?command=calculateInterestCalculate interest on a recurring deposit account
recurringdepositaccounts/{accountId}?command=postInterestPost interest on a recurring deposit account
Recurring Deposit Transactionsrecurringdepositaccounts/{accountId}/transactions?command=depositMake a deposit
recurringdepositaccounts/{accountId}/transactions?command=withdrawalMake a withdrawal
recurringdepositaccounts/{accountId}/transactions/{transactionId}?command=undoUndo transaction
recurringdepositaccounts/{accountId}/transactions/{transactionId}?command=modifyAdjust transaction
recurringdepositaccounts/{accountId}/transactions/templateRetrieve Deposit account transaction template
recurringdepositaccounts/{accountId}/transactions/{transactionId}Retrieve Deposit account transaction
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/service/HolidayUtil.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/service/HolidayUtil.java index d597d267a..ee6040177 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/service/HolidayUtil.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/service/HolidayUtil.java @@ -7,7 +7,19 @@ import org.mifosplatform.organisation.holiday.domain.Holiday; public class HolidayUtil { - public static LocalDate getRepaymentRescheduleDateToIfHoliday(final LocalDate repaymentDate, final List holidays) { + public static LocalDate getRepaymentRescheduleDateToIfHoliday(LocalDate repaymentDate, final List holidays) { + + for (final Holiday holiday : holidays) { + if (repaymentDate.equals(holiday.getFromDateLocalDate()) || repaymentDate.equals(holiday.getToDateLocalDate()) + || (repaymentDate.isAfter(holiday.getFromDateLocalDate()) && repaymentDate.isBefore(holiday.getToDateLocalDate()))) { + repaymentDate = getRepaymentRescheduleDateIfHoliday(repaymentDate, holidays); + } + } + return repaymentDate; + } + + private static LocalDate getRepaymentRescheduleDateIfHoliday(final LocalDate repaymentDate, final List holidays) { + for (final Holiday holiday : holidays) { if (repaymentDate.equals(holiday.getFromDateLocalDate()) || repaymentDate.equals(holiday.getToDateLocalDate()) || (repaymentDate.isAfter(holiday.getFromDateLocalDate()) && repaymentDate.isBefore(holiday.getToDateLocalDate()))) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/workingdays/service/WorkingDaysUtil.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/workingdays/service/WorkingDaysUtil.java index e802e8d65..147f42513 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/workingdays/service/WorkingDaysUtil.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/workingdays/service/WorkingDaysUtil.java @@ -40,4 +40,8 @@ public class WorkingDaysUtil { public static boolean isWorkingDay(final WorkingDays workingDays, final LocalDate date) { return CalendarUtils.isValidRedurringDate(workingDays.getRecurrence(), date, date); } + + public static boolean isNonWorkingDay(final WorkingDays workingDays, final LocalDate date) { + return !isWorkingDay(workingDays, date); + } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java index 52b53168e..80ed0d8c1 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java @@ -2112,6 +2112,7 @@ public class Loan extends AbstractPersistable { existingReversedTransactionIds.addAll(findExistingReversedTransactionIds()); reverseExistingTransactions(); + updateLoanSummaryDerivedFields(); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGenerator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGenerator.java index 1f9016a86..8f047f829 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGenerator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGenerator.java @@ -53,10 +53,19 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator { @Override public LocalDate adjustRepaymentDate(final LocalDate dueRepaymentPeriodDate, final LoanApplicationTerms loanApplicationTerms, final boolean isHolidayEnabled, final List holidays, final WorkingDays workingDays) { + LocalDate adjustedDate = dueRepaymentPeriodDate; - final LocalDate nextDueRepaymentPeriodDate = getRepaymentPeriodDate(loanApplicationTerms.getRepaymentPeriodFrequencyType(), - loanApplicationTerms.getRepaymentEvery(), adjustedDate); - adjustedDate = WorkingDaysUtil.getOffSetDateIfNonWorkingDay(adjustedDate, nextDueRepaymentPeriodDate, workingDays); + /** + * Fix for https://mifosforge.jira.com/browse/MIFOSX-1357 + */ + // recursively check for the next working day. + while (WorkingDaysUtil.isNonWorkingDay(workingDays, adjustedDate)) { + + final LocalDate nextDueRepaymentPeriodDate = getRepaymentPeriodDate(loanApplicationTerms.getRepaymentPeriodFrequencyType(), + loanApplicationTerms.getRepaymentEvery(), adjustedDate); + adjustedDate = WorkingDaysUtil.getOffSetDateIfNonWorkingDay(adjustedDate, nextDueRepaymentPeriodDate, workingDays); + } + if (isHolidayEnabled) { adjustedDate = HolidayUtil.getRepaymentRescheduleDateToIfHoliday(adjustedDate, holidays); }