Dormant Savings Feature

Project: http://git-wip-us.apache.org/repos/asf/incubator-fineract/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-fineract/commit/9d4d9012
Tree: http://git-wip-us.apache.org/repos/asf/incubator-fineract/tree/9d4d9012
Diff: http://git-wip-us.apache.org/repos/asf/incubator-fineract/diff/9d4d9012

Branch: refs/heads/develop
Commit: 9d4d90121a0a0cfb4a0082f4022c26c600886dc1
Parents: a2d794a
Author: Adi Narayana Raju <adi.r...@confluxtechnologies.com>
Authored: Mon May 2 19:21:37 2016 +0530
Committer: Adi Narayana Raju <adi.r...@confluxtechnologies.com>
Committed: Mon May 2 19:21:37 2016 +0530

----------------------------------------------------------------------
 .../accounting/common/AccountingConstants.java  |   7 +-
 .../CashBasedAccountingProcessorForSavings.java |   5 +
 ...GLAccountMappingFromApiJsonDeserializer.java |   9 +
 ...GLAccountMappingReadPlatformServiceImpl.java |   2 +
 ...LAccountMappingWritePlatformServiceImpl.java |   8 +
 .../SavingsProductToGLAccountMappingHelper.java |   3 +
 .../infrastructure/jobs/service/JobName.java    |   3 +-
 .../data/SavingsAccountSummaryData.java         |   9 +-
 ...ilsReadPlatformServiceJpaRepositoryImpl.java |  14 +-
 .../portfolio/charge/domain/Charge.java         |   8 +-
 .../portfolio/charge/domain/ChargeTimeType.java |  16 +-
 .../ChargeDropdownReadPlatformServiceImpl.java  |   2 +-
 .../charge/service/ChargeEnumerations.java      |   4 +
 .../savings/SavingsAccountTransactionType.java  |  12 +-
 .../portfolio/savings/SavingsApiConstants.java  |  15 +-
 .../savings/data/SavingsAccountData.java        | 196 +++++++++++--------
 .../data/SavingsAccountSubStatusEnumData.java   |  54 +++++
 .../data/SavingsAccountTransactionEnumData.java |   6 +
 .../savings/data/SavingsProductData.java        |  37 +++-
 .../data/SavingsProductDataValidator.java       |  71 ++++++-
 .../savings/domain/SavingsAccount.java          |  46 +++++
 .../savings/domain/SavingsAccountCharge.java    |   4 +
 .../domain/SavingsAccountSubStatusEnum.java     |  85 ++++++++
 .../domain/SavingsAccountTransaction.java       |   9 +
 .../savings/domain/SavingsProduct.java          |  78 +++++++-
 .../savings/domain/SavingsProductAssembler.java |  12 +-
 .../SavingsAccountReadPlatformService.java      |   8 +
 .../SavingsAccountReadPlatformServiceImpl.java  | 157 +++++++++++++--
 .../SavingsAccountWritePlatformService.java     |   6 +
 ...ntWritePlatformServiceJpaRepositoryImpl.java |  40 +++-
 .../savings/service/SavingsEnumerations.java    |  39 ++++
 .../SavingsProductReadPlatformServiceImpl.java  |  15 +-
 ...ctWritePlatformServiceJpaRepositoryImpl.java |   4 +-
 .../service/SavingsSchedularService.java        |   2 +
 .../service/SavingsSchedularServiceImpl.java    |  37 +++-
 .../core_db/V303__Savings_Account_Dormancy.sql  |  18 ++
 36 files changed, 911 insertions(+), 130 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingConstants.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingConstants.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingConstants.java
index 01a6510..bf99219 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingConstants.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingConstants.java
@@ -151,7 +151,7 @@ public class AccountingConstants {
     /*** Accounting placeholders for cash based accounting for savings 
products ***/
     public static enum CASH_ACCOUNTS_FOR_SAVINGS {
         SAVINGS_REFERENCE(1), SAVINGS_CONTROL(2), INTEREST_ON_SAVINGS(3), 
INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), TRANSFERS_SUSPENSE(
-                10), OVERDRAFT_PORTFOLIO_CONTROL(11), 
INCOME_FROM_INTEREST(12), LOSSES_WRITTEN_OFF(13);
+                10), OVERDRAFT_PORTFOLIO_CONTROL(11), 
INCOME_FROM_INTEREST(12), LOSSES_WRITTEN_OFF(13), ESCHEAT_LIABILITY(14);
 
         private final Integer value;
 
@@ -192,7 +192,7 @@ public class AccountingConstants {
                 "paymentTypeId"), FUND_SOURCE("fundSourceAccountId"), 
TRANSFERS_SUSPENSE("transfersInSuspenseAccountId"), FEE_INCOME_ACCOUNT_MAPPING(
                 "feeToIncomeAccountMappings"), 
PENALTY_INCOME_ACCOUNT_MAPPING("penaltyToIncomeAccountMappings"), 
CHARGE_ID("chargeId"), INCOME_ACCOUNT_ID(
                 "incomeAccountId"), 
OVERDRAFT_PORTFOLIO_CONTROL("overdraftPortfolioControlId"), 
INCOME_FROM_INTEREST("incomeFromInterestId"), LOSSES_WRITTEN_OFF(
-                "writeOffAccountId");
+                "writeOffAccountId"), ESCHEAT_LIABILITY("escheatLiabilityId");
 
         private final String value;
 
@@ -215,7 +215,8 @@ public class AccountingConstants {
                 "incomeFromPenaltyAccount"), 
INTEREST_ON_SAVINGS("interestOnSavingsAccount"), PAYMENT_TYPE("paymentType"), 
FUND_SOURCE(
                 "fundSourceAccount"), 
TRANSFERS_SUSPENSE("transfersInSuspenseAccount"), 
PENALTY_INCOME_ACCOUNT_MAPPING(
                 "penaltyToIncomeAccountMappings"), CHARGE_ID("charge"), 
INCOME_ACCOUNT_ID("incomeAccount"), OVERDRAFT_PORTFOLIO_CONTROL(
-                "overdraftPortfolioControl"), 
INCOME_FROM_INTEREST("incomeFromInterest"), 
LOSSES_WRITTEN_OFF("writeOffAccount");
+                "overdraftPortfolioControl"), 
INCOME_FROM_INTEREST("incomeFromInterest"), 
LOSSES_WRITTEN_OFF("writeOffAccount"),
+                ESCHEAT_LIABILITY("escheatLiabilityAccount");
 
         private final String value;
 

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForSavings.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForSavings.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForSavings.java
index 474f321..95f5957 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForSavings.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForSavings.java
@@ -143,6 +143,11 @@ public class CashBasedAccountingProcessorForSavings 
implements AccountingProcess
                 }
             }
 
+            else if (savingsTransactionDTO.getTransactionType().isEscheat()) {
+                
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, 
currencyCode,
+                               
CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL.getValue(), 
CASH_ACCOUNTS_FOR_SAVINGS.ESCHEAT_LIABILITY.getValue(),
+                        savingsProductId, paymentTypeId, savingsId, 
transactionId, transactionDate, amount, isReversal);
+            }
             /**
              * Handle Interest Applications and reversals of Interest
              * Applications

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/serialization/ProductToGLAccountMappingFromApiJsonDeserializer.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/serialization/ProductToGLAccountMappingFromApiJsonDeserializer.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/serialization/ProductToGLAccountMappingFromApiJsonDeserializer.java
index 6189087..7a0f91b 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/serialization/ProductToGLAccountMappingFromApiJsonDeserializer.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/serialization/ProductToGLAccountMappingFromApiJsonDeserializer.java
@@ -20,6 +20,7 @@ package 
org.apache.fineract.accounting.producttoaccountmapping.serialization;
 
 import static 
org.apache.fineract.portfolio.savings.SavingsApiConstants.SAVINGS_PRODUCT_RESOURCE_NAME;
 import static 
org.apache.fineract.portfolio.savings.SavingsApiConstants.accountingRuleParamName;
+import static 
org.apache.fineract.portfolio.savings.SavingsApiConstants.isDormancyTrackingActiveParamName;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -206,6 +207,14 @@ public final class 
ProductToGLAccountMappingFromApiJsonDeserializer {
                     
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), element);
             
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue())
                     
.value(incomeFromPenaltyId).notNull().integerGreaterThanZero();
+            
+            final Boolean isDormancyTrackingActive = 
this.fromApiJsonHelper.extractBooleanNamed(isDormancyTrackingActiveParamName, 
element);
+            if(null != isDormancyTrackingActive && isDormancyTrackingActive){
+                final Long escheatLiabilityId = 
this.fromApiJsonHelper.extractLongNamed(
+                        
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.ESCHEAT_LIABILITY.getValue(), element);
+                
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.ESCHEAT_LIABILITY.getValue())
+                        
.value(escheatLiabilityId).notNull().integerGreaterThanZero();
+            }
 
             if (!accountType.equals(DepositAccountType.RECURRING_DEPOSIT) && 
!accountType.equals(DepositAccountType.FIXED_DEPOSIT)) {
                 final Long overdraftAccount = 
this.fromApiJsonHelper.extractLongNamed(

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformServiceImpl.java
index b5a84f2..3141a95 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformServiceImpl.java
@@ -228,6 +228,8 @@ public class 
ProductToGLAccountMappingReadPlatformServiceImpl implements Product
                     
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.LOSSES_WRITTEN_OFF.getValue(),
 gLAccountData);
                 } else if 
(glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.INCOME_FROM_INTEREST)) {
                     
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.INCOME_FROM_INTEREST.getValue(),
 gLAccountData);
+                } else if 
(glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.ESCHEAT_LIABILITY)) {
+                    
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.ESCHEAT_LIABILITY.getValue(),
 gLAccountData);
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformServiceImpl.java
index c735997..8b1e504 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformServiceImpl.java
@@ -19,6 +19,7 @@
 package org.apache.fineract.accounting.producttoaccountmapping.service;
 
 import static 
org.apache.fineract.portfolio.savings.SavingsApiConstants.accountingRuleParamName;
+import static 
org.apache.fineract.portfolio.savings.SavingsApiConstants.isDormancyTrackingActiveParamName;
 
 import java.util.HashMap;
 import java.util.Locale;
@@ -224,6 +225,13 @@ public class 
ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
                 
this.savingsProductToGLAccountMappingHelper.saveSavingsToLiabilityAccountMapping(element,
                         
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), 
savingProductId,
                         
CASH_ACCOUNTS_FOR_SAVINGS.TRANSFERS_SUSPENSE.getValue());
+                
+                final Boolean isDormancyTrackingActive = 
this.fromApiJsonHelper.extractBooleanNamed(isDormancyTrackingActiveParamName, 
element);
+                if(null != isDormancyTrackingActive && 
isDormancyTrackingActive){
+                    
this.savingsProductToGLAccountMappingHelper.saveSavingsToLiabilityAccountMapping(element,
+                            
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.ESCHEAT_LIABILITY.getValue(), savingProductId,
+                            
CASH_ACCOUNTS_FOR_SAVINGS.ESCHEAT_LIABILITY.getValue());
+                }
 
                 // advanced accounting mappings
                 
this.savingsProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command,
 element, savingProductId, null);

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/SavingsProductToGLAccountMappingHelper.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/SavingsProductToGLAccountMappingHelper.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/SavingsProductToGLAccountMappingHelper.java
index ed519ef..529fb44 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/SavingsProductToGLAccountMappingHelper.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/SavingsProductToGLAccountMappingHelper.java
@@ -222,6 +222,9 @@ public class SavingsProductToGLAccountMappingHelper extends 
ProductToGLAccountMa
                 mergeSavingsToLiabilityAccountMappingChanges(element, 
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(),
                         savingsProductId, 
CASH_ACCOUNTS_FOR_SAVINGS.TRANSFERS_SUSPENSE.getValue(),
                         
CASH_ACCOUNTS_FOR_SAVINGS.TRANSFERS_SUSPENSE.toString(), changes);
+                mergeSavingsToLiabilityAccountMappingChanges(element, 
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.ESCHEAT_LIABILITY.getValue(),
+                        savingsProductId, 
CASH_ACCOUNTS_FOR_SAVINGS.ESCHEAT_LIABILITY.getValue(),
+                        
CASH_ACCOUNTS_FOR_SAVINGS.ESCHEAT_LIABILITY.toString(), changes);
             break;
             case ACCRUAL_PERIODIC:
             break;

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/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 999840b..cec29fb 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,7 +39,8 @@ 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");
+    POST_DIVIDENTS_FOR_SHARES("Post Dividends For Shares"),
+    UPDATE_SAVINGS_DORMANT_ACCOUNTS("Update Savings Dormant Accounts");
 
     private final String name;
 

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/SavingsAccountSummaryData.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/SavingsAccountSummaryData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/SavingsAccountSummaryData.java
index f14962a..55e04e9 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/SavingsAccountSummaryData.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/SavingsAccountSummaryData.java
@@ -24,6 +24,8 @@ import 
org.apache.fineract.infrastructure.core.data.EnumOptionData;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import 
org.apache.fineract.portfolio.savings.data.SavingsAccountApplicationTimelineData;
 import org.apache.fineract.portfolio.savings.data.SavingsAccountStatusEnumData;
+import 
org.apache.fineract.portfolio.savings.data.SavingsAccountSubStatusEnumData;
+import org.joda.time.LocalDate;
 
 /**
  * Immutable data object for savings accounts.
@@ -43,13 +45,16 @@ public class SavingsAccountSummaryData {
     //differentiate Individual, JLG or Group account
     private final EnumOptionData accountType;
     private final SavingsAccountApplicationTimelineData timeline;
+    private final SavingsAccountSubStatusEnumData subStatus;
+    private final LocalDate lastActiveTransactionDate;
 
     //differentiate deposit accounts Savings, FD and RD accounts
     private final EnumOptionData depositType;
 
     public SavingsAccountSummaryData(final Long id, final String accountNo, 
final String externalId, final Long productId,
             final String productName, final String shortProductName, final 
SavingsAccountStatusEnumData status, final CurrencyData currency,
-            final BigDecimal accountBalance, final EnumOptionData accountType, 
final SavingsAccountApplicationTimelineData timeline, final EnumOptionData 
depositType) {
+            final BigDecimal accountBalance, final EnumOptionData accountType, 
final SavingsAccountApplicationTimelineData timeline, final EnumOptionData 
depositType, 
+            final SavingsAccountSubStatusEnumData subStatus, final LocalDate 
lastActiveTransactionDate) {
         this.id = id;
         this.accountNo = accountNo;
         this.externalId = externalId;
@@ -62,5 +67,7 @@ public class SavingsAccountSummaryData {
         this.accountType = accountType;
         this.timeline = timeline;
         this.depositType = depositType;
+        this.subStatus = subStatus;
+        this.lastActiveTransactionDate = lastActiveTransactionDate;
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java
index 339ffd9..3601183 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java
@@ -39,6 +39,7 @@ import 
org.apache.fineract.portfolio.loanaccount.data.LoanStatusEnumData;
 import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
 import 
org.apache.fineract.portfolio.savings.data.SavingsAccountApplicationTimelineData;
 import org.apache.fineract.portfolio.savings.data.SavingsAccountStatusEnumData;
+import 
org.apache.fineract.portfolio.savings.data.SavingsAccountSubStatusEnumData;
 import org.apache.fineract.portfolio.savings.service.SavingsEnumerations;
 import 
org.apache.fineract.portfolio.shareaccounts.data.ShareAccountApplicationTimelineData;
 import 
org.apache.fineract.portfolio.shareaccounts.data.ShareAccountStatusEnumData;
@@ -258,6 +259,13 @@ public class 
AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
             accountsSummary.append("avbu.username as activatedByUsername,");
             accountsSummary.append("avbu.firstname as activatedByFirstname, 
avbu.lastname as activatedByLastname,");
 
+            accountsSummary.append("sa.sub_status_enum as subStatusEnum, ");
+            accountsSummary.append("(select 
IFNULL(max(sat.transaction_date),sa.activatedon_date) ");
+            accountsSummary.append("from m_savings_account_transaction as sat 
");
+            accountsSummary.append("where sat.is_reversed = 0 ");
+            accountsSummary.append("and sat.transaction_type_enum in (1,2) ");
+            accountsSummary.append("and sat.savings_account_id = sa.id) as 
lastActiveTransactionDate, ");
+
             accountsSummary.append("sa.closedon_date as closedOnDate,");
             accountsSummary.append("cbu.username as closedByUsername,");
             accountsSummary.append("cbu.firstname as closedByFirstname, 
cbu.lastname as closedByLastname,");
@@ -340,6 +348,10 @@ public class 
AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
             final String closedByUsername = rs.getString("closedByUsername");
             final String closedByFirstname = rs.getString("closedByFirstname");
             final String closedByLastname = rs.getString("closedByLastname");
+            final Integer subStatusEnum = JdbcSupport.getInteger(rs, 
"subStatusEnum");
+            final SavingsAccountSubStatusEnumData subStatus = 
SavingsEnumerations.subStatus(subStatusEnum);
+            
+            final LocalDate lastActiveTransactionDate = 
JdbcSupport.getLocalDate(rs, "lastActiveTransactionDate");
 
             final SavingsAccountApplicationTimelineData timeline = new 
SavingsAccountApplicationTimelineData(submittedOnDate,
                     submittedByUsername, submittedByFirstname, 
submittedByLastname, rejectedOnDate, rejectedByUsername,
@@ -349,7 +361,7 @@ public class 
AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
                     closedByLastname);
 
             return new SavingsAccountSummaryData(id, accountNo, externalId, 
productId, productName, shortProductName, status, currency, accountBalance,
-                    accountTypeData, timeline, depositTypeData);
+                    accountTypeData, timeline, depositTypeData, subStatus, 
lastActiveTransactionDate);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/Charge.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/Charge.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/Charge.java
index 3008849..3e20582 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/Charge.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/Charge.java
@@ -184,10 +184,10 @@ public class Charge extends AbstractPersistable<Long> {
                         
.failWithCodeNoParameterAddedToErrorCode("not.allowed.charge.calculation.type.for.savings");
             }
 
-            if (!ChargeTimeType.fromInt(getChargeTimeType()).isWithdrawalFee()
+            if 
(!(ChargeTimeType.fromInt(getChargeTimeType()).isWithdrawalFee() || 
ChargeTimeType.fromInt(getChargeTimeType()).isSavingsNoActivityFee())
                     && 
ChargeCalculationType.fromInt(getChargeCalculation()).isPercentageOfAmount()) {
                 
baseDataValidator.reset().parameter("chargeCalculationType").value(this.chargeCalculation)
-                        
.failWithCodeNoParameterAddedToErrorCode("savings.charge.calculation.type.percentage.allowed.only.for.withdrawal");
+                        
.failWithCodeNoParameterAddedToErrorCode("savings.charge.calculation.type.percentage.allowed.only.for.withdrawal.or.NoActivity");
             }
 
         } else if (isLoanCharge()) {
@@ -401,10 +401,10 @@ public class Charge extends AbstractPersistable<Long> {
                             
.failWithCodeNoParameterAddedToErrorCode("not.allowed.charge.calculation.type.for.savings");
                 }
 
-                if 
(!ChargeTimeType.fromInt(getChargeTimeType()).isWithdrawalFee()
+                if 
(!(ChargeTimeType.fromInt(getChargeTimeType()).isWithdrawalFee() || 
ChargeTimeType.fromInt(getChargeTimeType()).isSavingsNoActivityFee())
                         && 
ChargeCalculationType.fromInt(getChargeCalculation()).isPercentageOfAmount()) {
                     
baseDataValidator.reset().parameter("chargeCalculationType").value(this.chargeCalculation)
-                            
.failWithCodeNoParameterAddedToErrorCode("charge.calculation.type.percentage.allowed.only.for.withdrawal");
+                            
.failWithCodeNoParameterAddedToErrorCode("charge.calculation.type.percentage.allowed.only.for.withdrawal.or.noactivity");
                 }
             } else if (isClientCharge()) {
                 if (!isAllowedClientChargeCalculationType()) {

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/ChargeTimeType.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/ChargeTimeType.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/ChargeTimeType.java
index 5aa6fe5..b7d695a 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/ChargeTimeType.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/ChargeTimeType.java
@@ -35,7 +35,9 @@ public enum ChargeTimeType {
                                                                     // loan
     SHAREACCOUNT_ACTIVATION(13, "chargeTimeType.activation"), // only for loan
     SHARE_PURCHASE(14, "chargeTimeType.sharespurchase"), 
-    SHARE_REDEEM(15, "chargeTimeType.sharesredeem");
+    SHARE_REDEEM(15, "chargeTimeType.sharesredeem"),
+    
+    SAVINGS_NOACTIVITY_FEE(16,"chargeTimeType.savingsNoActivityFee");
 
     private final Integer value;
     private final String code;
@@ -67,7 +69,8 @@ public enum ChargeTimeType {
     public static Object[] validSavingsValues() {
         return new Integer[] { ChargeTimeType.SPECIFIED_DUE_DATE.getValue(), 
ChargeTimeType.SAVINGS_ACTIVATION.getValue(),
                 ChargeTimeType.SAVINGS_CLOSURE.getValue(), 
ChargeTimeType.WITHDRAWAL_FEE.getValue(), ChargeTimeType.ANNUAL_FEE.getValue(),
-                ChargeTimeType.MONTHLY_FEE.getValue(), 
ChargeTimeType.OVERDRAFT_FEE.getValue(), ChargeTimeType.WEEKLY_FEE.getValue() };
+                ChargeTimeType.MONTHLY_FEE.getValue(), 
ChargeTimeType.OVERDRAFT_FEE.getValue(), ChargeTimeType.WEEKLY_FEE.getValue(),
+                ChargeTimeType.SAVINGS_NOACTIVITY_FEE.getValue()};
     }
 
     public static Object[] validClientValues() {
@@ -127,6 +130,9 @@ public enum ChargeTimeType {
                 case 15:
                     chargeTimeType = SHARE_REDEEM;
                 break;
+                case 16:
+                       chargeTimeType = SAVINGS_NOACTIVITY_FEE;
+                break;
                 default:
                     chargeTimeType = INVALID;
                 break;
@@ -154,6 +160,10 @@ public enum ChargeTimeType {
     public boolean isWithdrawalFee() {
         return this.value.equals(ChargeTimeType.WITHDRAWAL_FEE.getValue());
     }
+    
+    public boolean isSavingsNoActivityFee() {
+       return 
this.value.equals(ChargeTimeType.SAVINGS_NOACTIVITY_FEE.getValue());
+    }
 
     public boolean isAnnualFee() {
         return this.value.equals(ChargeTimeType.ANNUAL_FEE.getValue());
@@ -185,7 +195,7 @@ public enum ChargeTimeType {
 
     public boolean isAllowedSavingsChargeTime() {
         return isOnSpecifiedDueDate() || isSavingsActivation() || 
isSavingsClosure() || isWithdrawalFee() || isAnnualFee()
-                || isMonthlyFee() || isWeeklyFee() || isOverdraftFee();
+                || isMonthlyFee() || isWeeklyFee() || isOverdraftFee() || 
isSavingsNoActivityFee();
     }
 
     public boolean isOverdraftFee() {

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeDropdownReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeDropdownReadPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeDropdownReadPlatformServiceImpl.java
index be5753b..50a83ab 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeDropdownReadPlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeDropdownReadPlatformServiceImpl.java
@@ -102,7 +102,7 @@ public class ChargeDropdownReadPlatformServiceImpl 
implements ChargeDropdownRead
                 // chargeTimeType(ChargeTimeType.SAVINGS_CLOSURE),
                 chargeTimeType(ChargeTimeType.WITHDRAWAL_FEE), 
chargeTimeType(ChargeTimeType.ANNUAL_FEE),
                 chargeTimeType(ChargeTimeType.MONTHLY_FEE), 
chargeTimeType(ChargeTimeType.WEEKLY_FEE),
-                chargeTimeType(ChargeTimeType.OVERDRAFT_FEE));
+                chargeTimeType(ChargeTimeType.OVERDRAFT_FEE), 
chargeTimeType(ChargeTimeType.SAVINGS_NOACTIVITY_FEE));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeEnumerations.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeEnumerations.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeEnumerations.java
index 0099be5..28e48bd 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeEnumerations.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeEnumerations.java
@@ -91,6 +91,10 @@ public class ChargeEnumerations {
             case SHARE_REDEEM:
                optionData = new 
EnumOptionData(ChargeTimeType.SHARE_REDEEM.getValue().longValue(), 
ChargeTimeType.SHARE_REDEEM.getCode(), "Share Redeem") ;
             break ;
+            case SAVINGS_NOACTIVITY_FEE:
+               optionData = new 
EnumOptionData(ChargeTimeType.SAVINGS_NOACTIVITY_FEE.getValue().longValue(), 
ChargeTimeType.SAVINGS_NOACTIVITY_FEE.getCode(), 
+                               "Saving No Activity Fee");
+            break;
             default:
                 optionData = new 
EnumOptionData(ChargeTimeType.INVALID.getValue().longValue(), 
ChargeTimeType.INVALID.getCode(), "Invalid");
             break;

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsAccountTransactionType.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsAccountTransactionType.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsAccountTransactionType.java
index 057f883..f989433 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsAccountTransactionType.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsAccountTransactionType.java
@@ -40,7 +40,8 @@ public enum SavingsAccountTransactionType {
     WITHDRAW_TRANSFER(14, "savingsAccountTransactionType.withdrawTransfer"), //
     REJECT_TRANSFER(15, "savingsAccountTransactionType.rejectTransfer"), 
WRITTEN_OFF(16, "savingsAccountTransactionType.writtenoff"), //
     OVERDRAFT_INTEREST(17, "savingsAccountTransactionType.overdraftInterest"), 
//
-    WITHHOLD_TAX(18, "savingsAccountTransactionType.withholdTax");
+    WITHHOLD_TAX(18, "savingsAccountTransactionType.withholdTax"),
+    ESCHEAT(19, "savingsAccountTransactionType.escheat");
 
     private final Integer value;
     private final String code;
@@ -109,6 +110,9 @@ public enum SavingsAccountTransactionType {
             case 18:
                 savingsAccountTransactionType = 
SavingsAccountTransactionType.WITHHOLD_TAX;
             break;
+            case 19:
+               savingsAccountTransactionType = 
SavingsAccountTransactionType.ESCHEAT;
+            break;
         }
         return savingsAccountTransactionType;
     }
@@ -177,8 +181,12 @@ public enum SavingsAccountTransactionType {
         return 
this.value.equals(SavingsAccountTransactionType.OVERDRAFT_INTEREST.getValue());
     }
 
+    public boolean isEscheat() {
+        return 
this.value.equals(SavingsAccountTransactionType.ESCHEAT.getValue());
+    }
+
     public boolean isDebit() {
-        return isWithdrawal() || isWithdrawalFee() || isAnnualFee() || 
isPayCharge() || isIncomeFromInterest() || isWithHoldTax();
+        return isWithdrawal() || isWithdrawalFee() || isAnnualFee() || 
isPayCharge() || isIncomeFromInterest() || isWithHoldTax() || isEscheat();
     }
 
     public boolean isCredit() {

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsApiConstants.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsApiConstants.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsApiConstants.java
index e269a54..3393f8e 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsApiConstants.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsApiConstants.java
@@ -160,6 +160,13 @@ public class SavingsApiConstants {
     public static final String onHoldTransactionTypeParamName = 
"transactionType";
     public static final String onHoldTransactionDateParamName = 
"transactionDate";
     public static final String onHoldReversedParamName = "reversed";
+    
+    // Savings Dormancy
+    public static final String isDormancyTrackingActiveParamName = 
"isDormancyTrackingActive";
+    public static final String daysToInactiveParamName = "daysToInactive";
+    public static final String daysToDormancyParamName = "daysToDormancy";
+    public static final String daysToEscheatParamName = "daysToEscheat";
+    
 
     public static final Set<String> SAVINGS_PRODUCT_REQUEST_DATA_PARAMETERS = 
new HashSet<>(Arrays.asList(localeParamName,
             monthDayFormatParamName, nameParamName, shortNameParamName, 
descriptionParamName, currencyCodeParamName,
@@ -178,7 +185,10 @@ public class SavingsApiConstants {
             
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PENALTY_INCOME_ACCOUNT_MAPPING.getValue(),
             
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
             SAVINGS_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(),
-            SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_INTEREST.getValue(), 
allowOverdraftParamName, overdraftLimitParamName,
+            SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_INTEREST.getValue(), 
+            SAVINGS_PRODUCT_ACCOUNTING_PARAMS.ESCHEAT_LIABILITY.getValue(),
+            isDormancyTrackingActiveParamName, daysToDormancyParamName, 
daysToInactiveParamName, daysToEscheatParamName,
+            allowOverdraftParamName, overdraftLimitParamName,
             nominalAnnualInterestRateOverdraftParamName, 
minOverdraftForInterestCalculationParamName, minRequiredBalanceParamName,
             enforceMinRequiredBalanceParamName, 
minBalanceForInterestCalculationParamName, withHoldTaxParamName, 
taxGroupIdParamName));
 
@@ -196,7 +206,8 @@ public class SavingsApiConstants {
             "interestCompoundingPeriodTypeOptions", 
"interestPostingPeriodTypeOptions", "interestCalculationTypeOptions",
             "interestCalculationDaysInYearTypeOptions", 
"lockinPeriodFrequencyTypeOptions", "withdrawalFeeTypeOptions",
             nominalAnnualInterestRateOverdraftParamName, 
minOverdraftForInterestCalculationParamName, withHoldTaxParamName,
-            taxGroupIdParamName));
+            taxGroupIdParamName, isDormancyTrackingActiveParamName, 
daysToInactiveParamName, daysToDormancyParamName, 
+            daysToInactiveParamName));
 
     public static final Set<String> SAVINGS_ACCOUNT_REQUEST_DATA_PARAMETERS = 
new HashSet<>(Arrays.asList(localeParamName,
             dateFormatParamName, monthDayFormatParamName, staffIdParamName, 
accountNoParamName, externalIdParamName, clientIdParamName,

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountData.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountData.java
index 6df8f09..fa6064d 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountData.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountData.java
@@ -29,6 +29,7 @@ import 
org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.organisation.staff.data.StaffData;
 import org.apache.fineract.portfolio.charge.data.ChargeData;
 import org.apache.fineract.portfolio.tax.data.TaxGroupData;
+import org.joda.time.LocalDate;
 
 /**
  * Immutable data object representing a savings account.
@@ -48,6 +49,7 @@ public class SavingsAccountData {
     private final Long fieldOfficerId;
     private final String fieldOfficerName;
     private final SavingsAccountStatusEnumData status;
+    private final SavingsAccountSubStatusEnumData subStatus;
     private final SavingsAccountApplicationTimelineData timeline;
     private final CurrencyData currency;
     private final BigDecimal nominalAnnualInterestRate;
@@ -67,6 +69,11 @@ public class SavingsAccountData {
     private final BigDecimal onHoldFunds;
     private final boolean withHoldTax;
     private final TaxGroupData taxGroup;
+    private final LocalDate lastActiveTransactionDate;
+    private final boolean isDormancyTrackingActive;
+    private final Integer daysToInactive;
+    private final Integer daysToDormancy;
+    private final Integer daysToEscheat;
 
     // associations
     private final SavingsAccountSummaryData summary;
@@ -96,16 +103,18 @@ public class SavingsAccountData {
     public static SavingsAccountData instance(final Long id, final String 
accountNo, final EnumOptionData depositType,
             final String externalId, final Long groupId, final String 
groupName, final Long clientId, final String clientName,
             final Long productId, final String productName, final Long 
fieldOfficerId, final String fieldOfficerName,
-            final SavingsAccountStatusEnumData status, final 
SavingsAccountApplicationTimelineData timeline, final CurrencyData currency,
-            final BigDecimal interestRate, final EnumOptionData 
interestCompoundingPeriodType,
-            final EnumOptionData interestPostingPeriodType, final 
EnumOptionData interestCalculationType,
-            final EnumOptionData interestCalculationDaysInYearType, final 
BigDecimal minRequiredOpeningBalance,
-            final Integer lockinPeriodFrequency, final EnumOptionData 
lockinPeriodFrequencyType, final boolean withdrawalFeeForTransfers,
-            final SavingsAccountSummaryData summary, final boolean 
allowOverdraft, final BigDecimal overdraftLimit,
-            final BigDecimal minRequiredBalance, final boolean 
enforceMinRequiredBalance,
-            final BigDecimal minBalanceForInterestCalculation, final 
BigDecimal onHoldFunds,
-            final BigDecimal nominalAnnualInterestRateOverdraft, final 
BigDecimal minOverdraftForInterestCalculation,
-            final boolean withHoldTax, final TaxGroupData taxGroup) {
+            final SavingsAccountStatusEnumData status, 
SavingsAccountSubStatusEnumData subStatus, final 
SavingsAccountApplicationTimelineData timeline,
+            final CurrencyData currency, final BigDecimal interestRate,
+            final EnumOptionData interestCompoundingPeriodType, final 
EnumOptionData interestPostingPeriodType,
+            final EnumOptionData interestCalculationType, final EnumOptionData 
interestCalculationDaysInYearType,
+            final BigDecimal minRequiredOpeningBalance, final Integer 
lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType,
+            final boolean withdrawalFeeForTransfers, final 
SavingsAccountSummaryData summary, final boolean allowOverdraft,
+            final BigDecimal overdraftLimit, final BigDecimal 
minRequiredBalance,
+            final boolean enforceMinRequiredBalance, final BigDecimal 
minBalanceForInterestCalculation,
+            final BigDecimal onHoldFunds, final BigDecimal 
nominalAnnualInterestRateOverdraft,
+            final BigDecimal minOverdraftForInterestCalculation, final boolean 
withHoldTax, final TaxGroupData taxGroup, 
+            final LocalDate lastActiveTransactionDate, final boolean 
isDormancyTrackingActive, final Integer daysToInactive, 
+            final Integer daysToDormancy, final Integer daysToEscheat) {
 
         final Collection<SavingsProductData> productOptions = null;
         final Collection<StaffData> fieldOfficerOptions = null;
@@ -121,14 +130,15 @@ public class SavingsAccountData {
         final Collection<ChargeData> chargeOptions = null;
 
         return new SavingsAccountData(id, accountNo, depositType, externalId, 
groupId, groupName, clientId, clientName, productId,
-                productName, fieldOfficerId, fieldOfficerName, status, 
timeline, currency, interestRate, interestCompoundingPeriodType,
-                interestPostingPeriodType, interestCalculationType, 
interestCalculationDaysInYearType, minRequiredOpeningBalance,
-                lockinPeriodFrequency, lockinPeriodFrequencyType, 
withdrawalFeeForTransfers, summary, transactions, productOptions,
-                fieldOfficerOptions, interestCompoundingPeriodTypeOptions, 
interestPostingPeriodTypeOptions,
-                interestCalculationTypeOptions, 
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
-                withdrawalFeeTypeOptions, charges, chargeOptions, 
allowOverdraft, overdraftLimit, minRequiredBalance,
-                enforceMinRequiredBalance, minBalanceForInterestCalculation, 
onHoldFunds, nominalAnnualInterestRateOverdraft,
-                minOverdraftForInterestCalculation, withHoldTax, taxGroup);
+                productName, fieldOfficerId, fieldOfficerName, status, 
subStatus, timeline, currency, interestRate,
+                interestCompoundingPeriodType, interestPostingPeriodType, 
interestCalculationType, interestCalculationDaysInYearType,
+                minRequiredOpeningBalance, lockinPeriodFrequency, 
lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, transactions,
+                productOptions, fieldOfficerOptions, 
interestCompoundingPeriodTypeOptions,
+                interestPostingPeriodTypeOptions, 
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
+                lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, 
charges, chargeOptions, allowOverdraft, overdraftLimit,
+                minRequiredBalance, enforceMinRequiredBalance, 
minBalanceForInterestCalculation, onHoldFunds,
+                nominalAnnualInterestRateOverdraft, 
minOverdraftForInterestCalculation, withHoldTax, taxGroup, 
+                lastActiveTransactionDate, isDormancyTrackingActive, 
daysToInactive, daysToDormancy, daysToEscheat);
     }
 
     public static SavingsAccountData lookup(final Long accountId, final String 
accountNo, final EnumOptionData depositType) {
@@ -184,16 +194,23 @@ public class SavingsAccountData {
         final Collection<ChargeData> chargeOptions = null;
         final boolean withHoldTax = false;
         final TaxGroupData taxGroup = null;
+        final SavingsAccountSubStatusEnumData subStatus = null;
+        final LocalDate lastActiveTransactionDate = null;
+        final boolean isDormancyTrackingActive = false;
+        final Integer daysToInactive = null;
+        final Integer daysToDormancy = null;
+        final Integer daysToEscheat = null;
 
         return new SavingsAccountData(accountId, accountNo, depositType, 
externalId, groupId, groupName, clientId, clientName, productId,
-                productName, fieldOfficerId, fieldOfficerName, status, 
timeline, currency, nominalAnnualInterestRate, interestPeriodType,
-                interestPostingPeriodType, interestCalculationType, 
interestCalculationDaysInYearType, minRequiredOpeningBalance,
-                lockinPeriodFrequency, lockinPeriodFrequencyType, 
withdrawalFeeForTransfers, summary, transactions, productOptions,
-                fieldOfficerOptions, interestCompoundingPeriodTypeOptions, 
interestPostingPeriodTypeOptions,
-                interestCalculationTypeOptions, 
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
-                withdrawalFeeTypeOptions, charges, chargeOptions, 
allowOverdraft, overdraftLimit, minRequiredBalance,
-                enforceMinRequiredBalance, minBalanceForInterestCalculation, 
onHoldFunds, nominalAnnualInterestRateOverdraft,
-                minOverdraftForInterestCalculation, withHoldTax, taxGroup);
+                productName, fieldOfficerId, fieldOfficerName, status, 
subStatus, timeline, currency, nominalAnnualInterestRate,
+                interestPeriodType, interestPostingPeriodType, 
interestCalculationType, interestCalculationDaysInYearType,
+                minRequiredOpeningBalance, lockinPeriodFrequency, 
lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, transactions,
+                productOptions, fieldOfficerOptions, 
interestCompoundingPeriodTypeOptions,
+                interestPostingPeriodTypeOptions, 
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
+                lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, 
charges, chargeOptions, allowOverdraft, overdraftLimit,
+                minRequiredBalance, enforceMinRequiredBalance, 
minBalanceForInterestCalculation, onHoldFunds,
+                nominalAnnualInterestRateOverdraft, 
minOverdraftForInterestCalculation, withHoldTax, taxGroup, 
+                lastActiveTransactionDate, isDormancyTrackingActive, 
daysToInactive, daysToDormancy, daysToEscheat);
     }
 
     public static SavingsAccountData lookupWithProductDetails(final Long 
accountId, final String accountNo,
@@ -247,16 +264,23 @@ public class SavingsAccountData {
         final Collection<ChargeData> chargeOptions = null;
         final boolean withHoldTax = false;
         final TaxGroupData taxGroup = null;
+        final SavingsAccountSubStatusEnumData subStatus = null;
+        final LocalDate lastActiveTransactionDate = null;
+        final boolean isDormancyTrackingActive = false;
+        final Integer daysToInactive = null;
+        final Integer daysToDormancy = null;
+        final Integer daysToEscheat = null;
 
         return new SavingsAccountData(accountId, accountNo, depositType, 
externalId, groupId, groupName, clientId, clientName, productId,
-                productName, fieldOfficerId, fieldOfficerName, status, 
timeline, currency, nominalAnnualInterestRate, interestPeriodType,
-                interestPostingPeriodType, interestCalculationType, 
interestCalculationDaysInYearType, minRequiredOpeningBalance,
-                lockinPeriodFrequency, lockinPeriodFrequencyType, 
withdrawalFeeForTransfers, summary, transactions, productOptions,
-                fieldOfficerOptions, interestCompoundingPeriodTypeOptions, 
interestPostingPeriodTypeOptions,
-                interestCalculationTypeOptions, 
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
-                withdrawalFeeTypeOptions, charges, chargeOptions, 
allowOverdraft, overdraftLimit, minRequiredBalance,
-                enforceMinRequiredBalance, minBalanceForInterestCalculation, 
onHoldFunds, nominalAnnualInterestRateOverdraft,
-                minOverdraftForInterestCalculation, withHoldTax, taxGroup);
+                productName, fieldOfficerId, fieldOfficerName, status, 
subStatus, timeline, currency, nominalAnnualInterestRate,
+                interestPeriodType, interestPostingPeriodType, 
interestCalculationType, interestCalculationDaysInYearType,
+                minRequiredOpeningBalance, lockinPeriodFrequency, 
lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, transactions,
+                productOptions, fieldOfficerOptions, 
interestCompoundingPeriodTypeOptions,
+                interestPostingPeriodTypeOptions, 
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
+                lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, 
charges, chargeOptions, allowOverdraft, overdraftLimit,
+                minRequiredBalance, enforceMinRequiredBalance, 
minBalanceForInterestCalculation, onHoldFunds,
+                nominalAnnualInterestRateOverdraft, 
minOverdraftForInterestCalculation, withHoldTax, taxGroup, 
+                lastActiveTransactionDate, isDormancyTrackingActive, 
daysToInactive, daysToDormancy, daysToEscheat);
     }
 
     public static SavingsAccountData withTemplateOptions(final 
SavingsAccountData account, final SavingsAccountData template,
@@ -280,17 +304,19 @@ public class SavingsAccountData {
 
         return new SavingsAccountData(account.id, account.accountNo, 
account.depositType, account.externalId, account.groupId,
                 account.groupName, account.clientId, account.clientName, 
account.savingsProductId, account.savingsProductName,
-                account.fieldOfficerId, account.fieldOfficerName, 
account.status, account.timeline, account.currency,
-                account.nominalAnnualInterestRate, 
account.interestCompoundingPeriodType, account.interestPostingPeriodType,
-                account.interestCalculationType, 
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance,
-                account.lockinPeriodFrequency, 
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, 
account.summary,
-                transactions, template.productOptions, 
template.fieldOfficerOptions, template.interestCompoundingPeriodTypeOptions,
-                template.interestPostingPeriodTypeOptions, 
template.interestCalculationTypeOptions,
-                template.interestCalculationDaysInYearTypeOptions, 
template.lockinPeriodFrequencyTypeOptions,
-                template.withdrawalFeeTypeOptions, charges, 
template.chargeOptions, account.allowOverdraft, account.overdraftLimit,
-                account.minRequiredBalance, account.enforceMinRequiredBalance, 
account.minBalanceForInterestCalculation,
-                account.onHoldFunds, 
account.nominalAnnualInterestRateOverdraft, 
account.minOverdraftForInterestCalculation,
-                account.withHoldTax, account.taxGroup);
+                account.fieldOfficerId, account.fieldOfficerName, 
account.status, account.subStatus, account.timeline,
+                account.currency, account.nominalAnnualInterestRate, 
account.interestCompoundingPeriodType,
+                account.interestPostingPeriodType, 
account.interestCalculationType, account.interestCalculationDaysInYearType,
+                account.minRequiredOpeningBalance, 
account.lockinPeriodFrequency, account.lockinPeriodFrequencyType, 
account.withdrawalFeeForTransfers,
+                account.summary, transactions, template.productOptions, 
template.fieldOfficerOptions,
+                template.interestCompoundingPeriodTypeOptions, 
template.interestPostingPeriodTypeOptions,
+                template.interestCalculationTypeOptions, 
template.interestCalculationDaysInYearTypeOptions,
+                template.lockinPeriodFrequencyTypeOptions, 
template.withdrawalFeeTypeOptions, charges, template.chargeOptions, 
account.allowOverdraft,
+                account.overdraftLimit, account.minRequiredBalance, 
account.enforceMinRequiredBalance,
+                account.minBalanceForInterestCalculation, account.onHoldFunds, 
account.nominalAnnualInterestRateOverdraft,
+                account.minOverdraftForInterestCalculation, 
account.withHoldTax, account.taxGroup, 
+                account.lastActiveTransactionDate, 
account.isDormancyTrackingActive, account.daysToInactive, 
+                account.daysToDormancy, account.daysToEscheat);
     }
 
     public static SavingsAccountData withTemplateOptions(final 
SavingsAccountData account,
@@ -305,16 +331,17 @@ public class SavingsAccountData {
 
         return new SavingsAccountData(account.id, account.accountNo, 
account.depositType, account.externalId, account.groupId,
                 account.groupName, account.clientId, account.clientName, 
account.savingsProductId, account.savingsProductName,
-                account.fieldOfficerId, account.fieldOfficerName, 
account.status, account.timeline, account.currency,
-                account.nominalAnnualInterestRate, 
account.interestCompoundingPeriodType, account.interestPostingPeriodType,
-                account.interestCalculationType, 
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance,
-                account.lockinPeriodFrequency, 
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, 
account.summary,
-                transactions, productOptions, fieldOfficerOptions, 
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
-                interestCalculationTypeOptions, 
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
-                withdrawalFeeTypeOptions, charges, chargeOptions, 
account.allowOverdraft, account.overdraftLimit,
-                account.minRequiredBalance, account.enforceMinRequiredBalance, 
account.minBalanceForInterestCalculation,
-                account.onHoldFunds, 
account.nominalAnnualInterestRateOverdraft, 
account.minOverdraftForInterestCalculation,
-                account.withHoldTax, account.taxGroup);
+                account.fieldOfficerId, account.fieldOfficerName, 
account.status, account.subStatus, account.timeline,
+                account.currency, account.nominalAnnualInterestRate, 
account.interestCompoundingPeriodType,
+                account.interestPostingPeriodType, 
account.interestCalculationType, account.interestCalculationDaysInYearType,
+                account.minRequiredOpeningBalance, 
account.lockinPeriodFrequency, account.lockinPeriodFrequencyType, 
account.withdrawalFeeForTransfers,
+                account.summary, transactions, productOptions, 
fieldOfficerOptions, interestCompoundingPeriodTypeOptions,
+                interestPostingPeriodTypeOptions, 
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
+                lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, 
charges, chargeOptions, account.allowOverdraft,
+                account.overdraftLimit, account.minRequiredBalance, 
account.enforceMinRequiredBalance,
+                account.minBalanceForInterestCalculation, account.onHoldFunds, 
account.nominalAnnualInterestRateOverdraft,
+                account.minOverdraftForInterestCalculation, 
account.withHoldTax, account.taxGroup, account.lastActiveTransactionDate, 
+                account.isDormancyTrackingActive, account.daysToInactive, 
account.daysToDormancy, account.daysToEscheat);
     }
 
     public static SavingsAccountData withClientTemplate(final Long clientId, 
final String clientName, final Long groupId,
@@ -370,38 +397,47 @@ public class SavingsAccountData {
 
         final Collection<SavingsAccountChargeData> charges = null;
         final Collection<ChargeData> chargeOptions = null;
+        final SavingsAccountSubStatusEnumData subStatus = null;
+        final LocalDate lastActiveTransactionDate = null;
+        final boolean isDormancyTrackingActive = false;
+        final Integer daysToInactive = null;
+        final Integer daysToDormancy = null;
+        final Integer daysToEscheat = null;
 
         return new SavingsAccountData(id, accountNo, depositType, externalId, 
groupId, groupName, clientId, clientName, productId,
-                productName, fieldOfficerId, fieldOfficerName, status, 
timeline, currency, nominalAnnualInterestRate, interestPeriodType,
-                interestPostingPeriodType, interestCalculationType, 
interestCalculationDaysInYearType, minRequiredOpeningBalance,
-                lockinPeriodFrequency, lockinPeriodFrequencyType, 
withdrawalFeeForTransfers, summary, transactions, productOptions,
-                fieldOfficerOptions, interestCompoundingPeriodTypeOptions, 
interestPostingPeriodTypeOptions,
-                interestCalculationTypeOptions, 
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
-                withdrawalFeeTypeOptions, charges, chargeOptions, 
allowOverdraft, overdraftLimit, minRequiredBalance,
-                enforceMinRequiredBalance, minBalanceForInterestCalculation, 
onHoldFunds, nominalAnnualInterestRateOverdraft,
-                minOverdraftForInterestCalculation, withHoldTax, taxGroup);
+                productName, fieldOfficerId, fieldOfficerName, status, 
subStatus, timeline, currency, nominalAnnualInterestRate,
+                interestPeriodType, interestPostingPeriodType, 
interestCalculationType, interestCalculationDaysInYearType,
+                minRequiredOpeningBalance, lockinPeriodFrequency, 
lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, transactions,
+                productOptions, fieldOfficerOptions, 
interestCompoundingPeriodTypeOptions,
+                interestPostingPeriodTypeOptions, 
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
+                lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, 
charges, chargeOptions, allowOverdraft, overdraftLimit,
+                minRequiredBalance, enforceMinRequiredBalance, 
minBalanceForInterestCalculation, onHoldFunds,
+                nominalAnnualInterestRateOverdraft, 
minOverdraftForInterestCalculation, withHoldTax, taxGroup, 
+                lastActiveTransactionDate, isDormancyTrackingActive, 
daysToInactive, daysToDormancy, daysToEscheat);
     }
 
     private SavingsAccountData(final Long id, final String accountNo, final 
EnumOptionData depositType, final String externalId,
             final Long groupId, final String groupName, final Long clientId, 
final String clientName, final Long productId,
             final String productName, final Long fieldofficerId, final String 
fieldofficerName, final SavingsAccountStatusEnumData status,
-            final SavingsAccountApplicationTimelineData timeline, final 
CurrencyData currency, final BigDecimal nominalAnnualInterestRate,
-            final EnumOptionData interestPeriodType, final EnumOptionData 
interestPostingPeriodType,
-            final EnumOptionData interestCalculationType, final EnumOptionData 
interestCalculationDaysInYearType,
-            final BigDecimal minRequiredOpeningBalance, final Integer 
lockinPeriodFrequency,
-            final EnumOptionData lockinPeriodFrequencyType, final boolean 
withdrawalFeeForTransfers,
-            final SavingsAccountSummaryData summary, final 
Collection<SavingsAccountTransactionData> transactions,
-            final Collection<SavingsProductData> productOptions, final 
Collection<StaffData> fieldOfficerOptions,
+            final SavingsAccountSubStatusEnumData subStatus, final 
SavingsAccountApplicationTimelineData timeline, final CurrencyData currency,
+            final BigDecimal nominalAnnualInterestRate, final EnumOptionData 
interestPeriodType,
+            final EnumOptionData interestPostingPeriodType, final 
EnumOptionData interestCalculationType,
+            final EnumOptionData interestCalculationDaysInYearType, final 
BigDecimal minRequiredOpeningBalance,
+            final Integer lockinPeriodFrequency, final EnumOptionData 
lockinPeriodFrequencyType,
+            final boolean withdrawalFeeForTransfers, final 
SavingsAccountSummaryData summary,
+            final Collection<SavingsAccountTransactionData> transactions, 
final Collection<SavingsProductData> productOptions,
+            final Collection<StaffData> fieldOfficerOptions,
             final Collection<EnumOptionData> 
interestCompoundingPeriodTypeOptions,
             final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
             final Collection<EnumOptionData> interestCalculationTypeOptions,
-            final Collection<EnumOptionData> 
interestCalculationDaysInYearTypeOptions,
-            final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, 
final Collection<EnumOptionData> withdrawalFeeTypeOptions,
-            final Collection<SavingsAccountChargeData> charges, final 
Collection<ChargeData> chargeOptions, final boolean allowOverdraft,
-            final BigDecimal overdraftLimit, final BigDecimal 
minRequiredBalance, final boolean enforceMinRequiredBalance,
-            final BigDecimal minBalanceForInterestCalculation, final 
BigDecimal onHoldFunds,
-            final BigDecimal nominalAnnualInterestRateOverdraft, final 
BigDecimal minOverdraftForInterestCalculation,
-            final boolean withHoldTax, final TaxGroupData taxGroup) {
+            final Collection<EnumOptionData> 
interestCalculationDaysInYearTypeOptions, final Collection<EnumOptionData> 
lockinPeriodFrequencyTypeOptions,
+            final Collection<EnumOptionData> withdrawalFeeTypeOptions, final 
Collection<SavingsAccountChargeData> charges, final Collection<ChargeData> 
chargeOptions,
+            final boolean allowOverdraft, final BigDecimal overdraftLimit, 
final BigDecimal minRequiredBalance,
+            final boolean enforceMinRequiredBalance, final BigDecimal 
minBalanceForInterestCalculation,
+            final BigDecimal onHoldFunds, final BigDecimal 
nominalAnnualInterestRateOverdraft,
+            final BigDecimal minOverdraftForInterestCalculation, final boolean 
withHoldTax, final TaxGroupData taxGroup, 
+            final LocalDate lastActiveTransactionDate, final boolean 
isDormancyTrackingActive, final Integer daysToInactive, 
+            final Integer daysToDormancy, final Integer daysToEscheat) {
         this.id = id;
         this.accountNo = accountNo;
         this.depositType = depositType;
@@ -415,6 +451,7 @@ public class SavingsAccountData {
         this.fieldOfficerId = fieldofficerId;
         this.fieldOfficerName = fieldofficerName;
         this.status = status;
+        this.subStatus = subStatus;
         this.timeline = timeline;
         this.currency = currency;
         this.nominalAnnualInterestRate = nominalAnnualInterestRate;
@@ -461,6 +498,11 @@ public class SavingsAccountData {
         this.onHoldFunds = onHoldFunds;
         this.withHoldTax = withHoldTax;
         this.taxGroup = taxGroup;
+        this.lastActiveTransactionDate = lastActiveTransactionDate;
+        this.isDormancyTrackingActive = isDormancyTrackingActive;
+        this.daysToInactive = daysToInactive;
+        this.daysToDormancy = daysToDormancy;
+        this.daysToEscheat = daysToEscheat;
     }
 
     private SavingsAccountChargeData getWithdrawalFee() {

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountSubStatusEnumData.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountSubStatusEnumData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountSubStatusEnumData.java
new file mode 100644
index 0000000..4981113
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountSubStatusEnumData.java
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.savings.data;
+
+/**
+ * Immutable data object represent savings account sub-status enumerations.
+ */
+public class SavingsAccountSubStatusEnumData {
+
+    private final Long id;
+    @SuppressWarnings("unused")
+    private final String code;
+    @SuppressWarnings("unused")
+    private final String value;
+    @SuppressWarnings("unused")
+    private final boolean none;
+    @SuppressWarnings("unused")
+    private final boolean inactive;
+    @SuppressWarnings("unused")
+    private final boolean dormant;
+    @SuppressWarnings("unused")
+    private final boolean escheat;
+
+    public SavingsAccountSubStatusEnumData(final Long id, final String code, 
final String value, final boolean none,
+            final boolean inactive, final boolean dormant, final boolean 
escheat) {
+        this.id = id;
+        this.code = code;
+        this.value = value;
+        this.none = none;
+        this.inactive = inactive;
+        this.dormant = dormant;
+        this.escheat = escheat;
+    }
+
+    public Long id() {
+        return this.id;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionEnumData.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionEnumData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionEnumData.java
index e7da011..2417a02 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionEnumData.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionEnumData.java
@@ -43,6 +43,7 @@ public class SavingsAccountTransactionEnumData {
     private final boolean writtenoff;
     private final boolean overdraftFee = true;
     private final boolean withholdTax;
+    private final boolean escheat;
 
     public SavingsAccountTransactionEnumData(final Long id, final String code, 
final String value) {
         this.id = id;
@@ -62,6 +63,7 @@ public class SavingsAccountTransactionEnumData {
         this.writtenoff = 
Long.valueOf(SavingsAccountTransactionType.WRITTEN_OFF.getValue()).equals(this.id);
         this.overdraftInterest = 
Long.valueOf(SavingsAccountTransactionType.OVERDRAFT_INTEREST.getValue()).equals(this.id);
         this.withholdTax = 
Long.valueOf(SavingsAccountTransactionType.WITHHOLD_TAX.getValue()).equals(this.id);
+        this.escheat = 
Long.valueOf(SavingsAccountTransactionType.ESCHEAT.getValue()).equals(this.id);
         // this.overdraftFee =
         // 
Long.valueOf(SavingsAccountTransactionType.OVERDRAFT_INTEREST.getValue()).equals(this.id);
     }
@@ -133,5 +135,9 @@ public class SavingsAccountTransactionEnumData {
     public boolean isDividendPayout() {
         return this.dividendPayout;
     }
+    
+    public boolean isEscheat() {
+       return this.escheat;
+    }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductData.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductData.java
index 6741164..f8bba20 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductData.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductData.java
@@ -86,6 +86,10 @@ public class SavingsProductData {
     private final Collection<ChargeData> chargeOptions;
     private final Collection<ChargeData> penaltyOptions;
     private final Collection<TaxGroupData> taxGroupOptions;
+       private final Boolean isDormancyTrackingActive;
+       private final Long daysToInactive;
+       private final Long daysToDormancy;
+       private final Long daysToEscheat;
 
     public static SavingsProductData template(final CurrencyData currency, 
final EnumOptionData interestCompoundingPeriodType,
             final EnumOptionData interestPostingPeriodType, final 
EnumOptionData interestCalculationType,
@@ -122,6 +126,10 @@ public class SavingsProductData {
         final BigDecimal minOverdraftForInterestCalculation = null;
         final boolean withHoldTax = false;
         final TaxGroupData taxGroup = null;
+        final Boolean isDormancyTrackingActive = false;
+        final Long daysToInactive = null;
+        final Long daysToDormancy = null;
+        final Long daysToEscheat = null;
 
         return new SavingsProductData(id, name, shortName, description, 
currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
                 interestPostingPeriodType, interestCalculationType, 
interestCalculationDaysInYearType, minRequiredOpeningBalance,
@@ -132,7 +140,7 @@ public class SavingsProductData {
                 accountingMappingOptions, charges, chargeOptions, 
penaltyOptions, feeToIncomeAccountMappings,
                 penaltyToIncomeAccountMappings, allowOverdraft, 
overdraftLimit, minRequiredBalance, enforceMinRequiredBalance,
                 minBalanceForInterestCalculation, 
nominalAnnualInterestRateOverdraft, minOverdraftForInterestCalculation, 
withHoldTax,
-                taxGroup, taxGroupOptions);
+                taxGroup, taxGroupOptions, isDormancyTrackingActive, 
daysToInactive, daysToDormancy, daysToEscheat);
     }
 
     public static SavingsProductData withCharges(final SavingsProductData 
product, final Collection<ChargeData> charges) {
@@ -148,7 +156,8 @@ public class SavingsProductData {
                 product.feeToIncomeAccountMappings, 
product.penaltyToIncomeAccountMappings, product.allowOverdraft, 
product.overdraftLimit,
                 product.minRequiredBalance, product.enforceMinRequiredBalance, 
product.minBalanceForInterestCalculation,
                 product.nominalAnnualInterestRateOverdraft, 
product.minOverdraftForInterestCalculation, product.withHoldTax,
-                product.taxGroup, product.taxGroupOptions);
+                product.taxGroup, product.taxGroupOptions, 
product.isDormancyTrackingActive, product.daysToInactive, 
+                product.daysToDormancy, product.daysToEscheat);
     }
 
     /**
@@ -181,7 +190,8 @@ public class SavingsProductData {
                 existingProduct.feeToIncomeAccountMappings, 
existingProduct.penaltyToIncomeAccountMappings, existingProduct.allowOverdraft,
                 existingProduct.overdraftLimit, 
existingProduct.minRequiredBalance, existingProduct.enforceMinRequiredBalance,
                 existingProduct.minBalanceForInterestCalculation, 
existingProduct.nominalAnnualInterestRateOverdraft,
-                existingProduct.minOverdraftForInterestCalculation, 
existingProduct.withHoldTax, existingProduct.taxGroup, taxGroupOptions);
+                existingProduct.minOverdraftForInterestCalculation, 
existingProduct.withHoldTax, existingProduct.taxGroup, taxGroupOptions, 
+                existingProduct.isDormancyTrackingActive, 
existingProduct.daysToInactive, existingProduct.daysToDormancy, 
existingProduct.daysToEscheat);
     }
 
     public static SavingsProductData withAccountingDetails(final 
SavingsProductData existingProduct,
@@ -217,7 +227,8 @@ public class SavingsProductData {
                 existingProduct.minRequiredBalance, 
existingProduct.enforceMinRequiredBalance,
                 existingProduct.minBalanceForInterestCalculation, 
existingProduct.nominalAnnualInterestRateOverdraft,
                 existingProduct.minOverdraftForInterestCalculation, 
existingProduct.withHoldTax, existingProduct.taxGroup,
-                existingProduct.taxGroupOptions);
+                existingProduct.taxGroupOptions, 
existingProduct.isDormancyTrackingActive, existingProduct.daysToInactive, 
+                existingProduct.daysToDormancy, existingProduct.daysToEscheat);
     }
 
     public static SavingsProductData instance(final Long id, final String 
name, final String shortName, final String description,
@@ -228,7 +239,8 @@ public class SavingsProductData {
             final EnumOptionData accountingType, final boolean allowOverdraft, 
final BigDecimal overdraftLimit,
             final BigDecimal minRequiredBalance, final boolean 
enforceMinRequiredBalance,
             final BigDecimal minBalanceForInterestCalculation, final 
BigDecimal nominalAnnualInterestRateOverdraft,
-            final BigDecimal minOverdraftForInterestCalculation, final boolean 
withHoldTax, final TaxGroupData taxGroup) {
+            final BigDecimal minOverdraftForInterestCalculation, final boolean 
withHoldTax, final TaxGroupData taxGroup, 
+            final Boolean isDormancyTrackingActive, final Long daysToInactive, 
final Long daysToDormancy, final Long daysToEscheat) {
 
         final Map<String, Object> accountingMappings = null;
         final Collection<PaymentTypeToGLAccountMapper> 
paymentChannelToFundSourceMappings = null;
@@ -259,7 +271,7 @@ public class SavingsProductData {
                 accountingMappingOptions, charges, chargeOptions, 
penaltyOptions, feeToIncomeAccountMappings,
                 penaltyToIncomeAccountMappings, allowOverdraft, 
overdraftLimit, minRequiredBalance, enforceMinRequiredBalance,
                 minBalanceForInterestCalculation, 
nominalAnnualInterestRateOverdraft, minOverdraftForInterestCalculation, 
withHoldTax,
-                taxGroup, taxGroupOptions);
+                taxGroup, taxGroupOptions, isDormancyTrackingActive, 
daysToInactive, daysToDormancy, daysToEscheat);
     }
 
     public static SavingsProductData lookup(final Long id, final String name) {
@@ -305,6 +317,10 @@ public class SavingsProductData {
         final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = 
null;
         final Collection<ChargeToGLAccountMapper> 
penaltyToIncomeAccountMappings = null;
         final Collection<TaxGroupData> taxGroupOptions = null;
+        final Boolean isDormancyTrackingActive = null;
+        final Long daysToInactive = null;
+        final Long daysToDormancy = null;
+        final Long daysToEscheat = null;
 
         return new SavingsProductData(id, name, shortName, description, 
currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
                 interestPostingPeriodType, interestCalculationType, 
interestCalculationDaysInYearType, minRequiredOpeningBalance,
@@ -315,7 +331,7 @@ public class SavingsProductData {
                 accountingMappingOptions, charges, chargeOptions, 
penaltyOptions, feeToIncomeAccountMappings,
                 penaltyToIncomeAccountMappings, allowOverdraft, 
overdraftLimit, minRequiredBalance, enforceMinRequiredBalance,
                 minBalanceForInterestCalculation, 
nominalAnnualInterestRateOverdraft, minOverdraftForInterestCalculation, 
withHoldTax,
-                taxGroup, taxGroupOptions);
+                taxGroup, taxGroupOptions, isDormancyTrackingActive, 
daysToInactive, daysToDormancy, daysToEscheat);
     }
 
     private SavingsProductData(final Long id, final String name, final String 
shortName, final String description,
@@ -338,7 +354,8 @@ public class SavingsProductData {
             final BigDecimal overdraftLimit, final BigDecimal 
minRequiredBalance, final boolean enforceMinRequiredBalance,
             final BigDecimal minBalanceForInterestCalculation, final 
BigDecimal nominalAnnualInterestRateOverdraft,
             final BigDecimal minOverdraftForInterestCalculation, final boolean 
withHoldTax, final TaxGroupData taxGroup,
-            final Collection<TaxGroupData> taxGroupOptions) {
+            final Collection<TaxGroupData> taxGroupOptions, final Boolean 
isDormancyTrackingActive, final Long daysToInactive, 
+            final Long daysToDormancy, final Long daysToEscheat) {
         this.id = id;
         this.name = name;
         this.shortName = shortName;
@@ -391,6 +408,10 @@ public class SavingsProductData {
         this.taxGroup = taxGroup;
         this.withHoldTax = withHoldTax;
         this.taxGroupOptions = taxGroupOptions;
+        this.isDormancyTrackingActive = isDormancyTrackingActive;
+        this.daysToInactive = daysToInactive;
+        this.daysToDormancy = daysToDormancy;
+        this.daysToEscheat = daysToEscheat;
     }
 
     public boolean hasAccountingEnabled() {

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/9d4d9012/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductDataValidator.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductDataValidator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductDataValidator.java
index 912a0c0..94f0252 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductDataValidator.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductDataValidator.java
@@ -44,6 +44,10 @@ import static 
org.apache.fineract.portfolio.savings.SavingsApiConstants.shortNam
 import static 
org.apache.fineract.portfolio.savings.SavingsApiConstants.withdrawalFeeForTransfersParamName;
 import static 
org.apache.fineract.portfolio.savings.SavingsApiConstants.withHoldTaxParamName;
 import static 
org.apache.fineract.portfolio.savings.SavingsApiConstants.taxGroupIdParamName;
+import static 
org.apache.fineract.portfolio.savings.SavingsApiConstants.isDormancyTrackingActiveParamName;
+import static 
org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToInactiveParamName;
+import static 
org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToDormancyParamName;
+import static 
org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToEscheatParamName;
 
 import java.lang.reflect.Type;
 import java.math.BigDecimal;
@@ -64,6 +68,7 @@ import 
org.apache.fineract.portfolio.savings.SavingsCompoundingInterestPeriodTyp
 import 
org.apache.fineract.portfolio.savings.SavingsInterestCalculationDaysInYearType;
 import org.apache.fineract.portfolio.savings.SavingsInterestCalculationType;
 import org.apache.fineract.portfolio.savings.SavingsPostingInterestPeriodType;
+import org.apache.fineract.portfolio.savings.domain.SavingsProduct;
 import org.joda.time.MonthDay;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -232,6 +237,27 @@ public class SavingsProductDataValidator {
                 
baseDataValidator.reset().parameter(feeAmountParamName).value(annualFeeAmount).notNull().zeroOrPositiveAmount();
             }
         }
+        
+        //dormancy
+        final Boolean isDormancyActive = 
this.fromApiJsonHelper.extractBooleanNamed(isDormancyTrackingActiveParamName, 
element);
+        
+        if(null != isDormancyActive && isDormancyActive){
+               final Long daysToInact = 
this.fromApiJsonHelper.extractLongNamed(daysToInactiveParamName, element);
+               
baseDataValidator.reset().parameter(daysToInactiveParamName).value(daysToInact).notNull().longGreaterThanZero();
+
+               final Long daysToDor = 
this.fromApiJsonHelper.extractLongNamed(daysToDormancyParamName, element);
+               
baseDataValidator.reset().parameter(daysToDormancyParamName).value(daysToDor).notNull().longGreaterThanZero();
+
+               final Long daysToEsc = 
this.fromApiJsonHelper.extractLongNamed(daysToEscheatParamName, element);
+               
baseDataValidator.reset().parameter(daysToEscheatParamName).value(daysToEsc).notNull().longGreaterThanZero();
+
+               if(null != daysToInact
+                               && null != daysToDor
+                               && null != daysToEsc){
+                       
baseDataValidator.reset().parameter(daysToDormancyParamName).value(daysToDor).longGreaterThanNumber(daysToInact);
+                       
baseDataValidator.reset().parameter(daysToEscheatParamName).value(daysToEsc).longGreaterThanNumber(daysToDor);
+               }
+        }
 
         // accounting related data validation
         final Integer accountingRuleType = 
this.fromApiJsonHelper.extractIntegerNamed("accountingRule", element, 
Locale.getDefault());
@@ -283,6 +309,13 @@ public class SavingsProductDataValidator {
                     
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), element);
             
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue()).value(writtenoff)
                     .notNull().integerGreaterThanZero();
+            
+            if(null != isDormancyActive && isDormancyActive){
+               final Long escheatLiabilityAccountId = 
this.fromApiJsonHelper.extractLongNamed(
+                        
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.ESCHEAT_LIABILITY.getValue(), element);
+                
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.ESCHEAT_LIABILITY.getValue())
+                        
.value(escheatLiabilityAccountId).notNull().integerGreaterThanZero();
+            }
 
             validatePaymentChannelFundSourceMappings(baseDataValidator, 
element);
             validateChargeToIncomeAccountMappings(baseDataValidator, element);
@@ -302,7 +335,7 @@ public class SavingsProductDataValidator {
         throwExceptionIfValidationWarningsExist(dataValidationErrors);
     }
 
-    public void validateForUpdate(final String json) {
+    public void validateForUpdate(final String json, final SavingsProduct 
product) {
 
         if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
 
@@ -453,6 +486,42 @@ public class SavingsProductDataValidator {
         
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue()).value(writtenoff)
                 .ignoreIfNull().integerGreaterThanZero();
 
+        //dormancy
+        final Boolean isDormancyActive = 
this.fromApiJsonHelper.parameterExists(isDormancyTrackingActiveParamName, 
element)?
+                       
this.fromApiJsonHelper.extractBooleanNamed(isDormancyTrackingActiveParamName, 
element):
+                               product.isDormancyTrackingActive();
+        
+        if(null != isDormancyActive && isDormancyActive){
+               final Long daysToInact = 
this.fromApiJsonHelper.parameterExists(daysToInactiveParamName, element)?
+                               
this.fromApiJsonHelper.extractLongNamed(daysToInactiveParamName, element):
+                                       product.getDaysToInactive();
+               
baseDataValidator.reset().parameter(daysToInactiveParamName).value(daysToInact).notNull().longGreaterThanZero();
+
+               final Long daysToDor = 
this.fromApiJsonHelper.parameterExists(daysToDormancyParamName, element)?
+                               
this.fromApiJsonHelper.extractLongNamed(daysToDormancyParamName, element):
+                                       product.getDaysToDormancy();
+               
baseDataValidator.reset().parameter(daysToDormancyParamName).value(daysToDor).notNull().longGreaterThanZero();
+
+               final Long daysToEsc = 
this.fromApiJsonHelper.parameterExists(daysToEscheatParamName, element)?
+                               
this.fromApiJsonHelper.extractLongNamed(daysToEscheatParamName, element):
+                                       product.getDaysToEscheat();
+               
baseDataValidator.reset().parameter(daysToEscheatParamName).value(daysToEsc).notNull().longGreaterThanZero();
+
+               if(null != daysToInact
+                               && null != daysToDor
+                               && null != daysToEsc){
+                       
baseDataValidator.reset().parameter(daysToDormancyParamName).value(daysToDor).longGreaterThanNumber(daysToInact);
+                       
baseDataValidator.reset().parameter(daysToEscheatParamName).value(daysToEsc).longGreaterThanNumber(daysToDor);
+               }
+
+               
if(this.fromApiJsonHelper.parameterExists(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.ESCHEAT_LIABILITY.getValue(),
 element)){
+               final Long escheatLiabilityAccountId = 
this.fromApiJsonHelper.extractLongNamed(
+                        
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.ESCHEAT_LIABILITY.getValue(), element);
+                
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.ESCHEAT_LIABILITY.getValue())
+                        
.value(escheatLiabilityAccountId).notNull().integerGreaterThanZero();
+               }
+        }
+
         validatePaymentChannelFundSourceMappings(baseDataValidator, element);
         validateChargeToIncomeAccountMappings(baseDataValidator, element);
         validateOverdraftParams(baseDataValidator, element);

Reply via email to