You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ar...@apache.org on 2022/04/04 13:50:59 UTC

[fineract] branch develop updated: FINERACT-130:AccountHold

This is an automated email from the ASF dual-hosted git repository.

arnold pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 9329b9918 FINERACT-130:AccountHold
9329b9918 is described below

commit 9329b99185e1c2a8befb6c8e8af4b11b8f11941c
Author: rrpawar96 <rr...@gmail.com>
AuthorDate: Wed Mar 30 15:20:58 2022 +0530

    FINERACT-130:AccountHold
---
 .../portfolio/savings/SavingsApiConstants.java     |   1 +
 .../savings/api/SavingsAccountsApiResource.java    |   4 +-
 .../portfolio/savings/data/SavingsAccountData.java | 129 +++++++++++----------
 .../data/SavingsAccountTransactionData.java        |  59 +++++++++-
 .../SavingsAccountTransactionDataValidator.java    |  41 ++++---
 .../portfolio/savings/domain/SavingsAccount.java   |  19 ++-
 .../savings/domain/SavingsAccountSummary.java      |   4 +
 .../savings/domain/SavingsAccountTransaction.java  |   7 ++
 ...BlockCreditsToSavingsAccountCommandHandler.java |   2 +-
 ...lockDebitsFromSavingsAccountCommandHandler.java |   2 +-
 .../handler/BlockSavingsAccountCommandHandler.java |   2 +-
 .../SavingsAccountReadPlatformServiceImpl.java     |  39 ++++---
 .../SavingsAccountWritePlatformService.java        |   6 +-
 ...countWritePlatformServiceJpaRepositoryImpl.java |  70 +++++++++--
 .../db/changelog/tenant/changelog-tenant.xml       |   1 +
 .../parts/0009_hold_reason_savings_account.xml     |  53 +++++++++
 .../ClientSavingsIntegrationTest.java              |   2 +-
 .../common/savings/SavingsAccountHelper.java       |  20 +++-
 18 files changed, 345 insertions(+), 116 deletions(-)

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 08086dcf4..4dd397368 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
@@ -80,6 +80,7 @@ public class SavingsApiConstants {
     public static final String externalIdParamName = "externalId";
     public static final String statusParamName = "status";
     public static final String subStatusParamName = "subStatus";
+    public static final String reasonForBlockParamName = "reasonForBlock";
     public static final String clientIdParamName = "clientId";
     public static final String isRetailAccountParamName = "isRetailAccount";
     public static final String autogenerateTransactionIdParamName = "autogenerateTransactionId";
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsAccountsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsAccountsApiResource.java
index b749896a9..9ecd0ceb9 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsAccountsApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsAccountsApiResource.java
@@ -479,10 +479,10 @@ public class SavingsAccountsApiResource {
             final CommandWrapper commandRequest = builder.unblockCreditsToSavingsAccount(accountId).build();
             result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
         } else if (is(commandParam, SavingsApiConstants.COMMAND_BLOCK_ACCOUNT)) {
-            final CommandWrapper commandRequest = builder.withNoJsonBody().blockSavingsAccount(accountId).build();
+            final CommandWrapper commandRequest = builder.blockSavingsAccount(accountId).build();
             result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
         } else if (is(commandParam, SavingsApiConstants.COMMAND_UNBLOCK_ACCOUNT)) {
-            final CommandWrapper commandRequest = builder.withNoJsonBody().unblockSavingsAccount(accountId).build();
+            final CommandWrapper commandRequest = builder.unblockSavingsAccount(accountId).build();
             result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
         }
 
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 e1722e9a4..e42cfc978 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
@@ -64,6 +64,7 @@ public final class SavingsAccountData implements Serializable {
     private final String fieldOfficerName;
     private final SavingsAccountStatusEnumData status;
     private final SavingsAccountSubStatusEnumData subStatus;
+    private final String reasonForBlock;
     private final SavingsAccountApplicationTimelineData timeline;
     private final CurrencyData currency;
     private final BigDecimal nominalAnnualInterestRate;
@@ -174,6 +175,7 @@ public final class SavingsAccountData implements Serializable {
         this.fieldOfficerName = null;
         this.status = null;
         this.subStatus = null;
+        this.reasonForBlock = null;
         this.timeline = null;
         this.currency = null;
         this.nominalAnnualInterestRate = nominalAnnualInterestRate;
@@ -528,6 +530,7 @@ public final class SavingsAccountData implements Serializable {
         this.fieldOfficerName = null;
         this.status = null;
         this.subStatus = null;
+        this.reasonForBlock = null;
         this.timeline = null;
         this.currency = null;
         this.nominalAnnualInterestRate = nominalAnnualInterestRate;
@@ -584,7 +587,7 @@ public final class SavingsAccountData implements Serializable {
     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, SavingsAccountSubStatusEnumData subStatus,
+            final SavingsAccountStatusEnumData status, SavingsAccountSubStatusEnumData subStatus, final String reasonForBlock,
             final SavingsAccountApplicationTimelineData timeline, final CurrencyData currency, final BigDecimal interestRate,
             final EnumOptionData interestCompoundingPeriodType, final EnumOptionData interestPostingPeriodType,
             final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
@@ -611,7 +614,7 @@ public final class SavingsAccountData implements Serializable {
         final Collection<ChargeData> chargeOptions = null;
 
         return new SavingsAccountData(id, accountNo, depositType, externalId, groupId, groupName, clientId, clientName, productId,
-                productName, fieldOfficerId, fieldOfficerName, status, subStatus, timeline, currency, interestRate,
+                productName, fieldOfficerId, fieldOfficerName, status, subStatus, reasonForBlock, timeline, currency, interestRate,
                 interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
                 minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary,
                 transactions, productOptions, fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
@@ -676,6 +679,7 @@ public final class SavingsAccountData implements Serializable {
         final boolean withHoldTax = false;
         final TaxGroupData taxGroup = null;
         final SavingsAccountSubStatusEnumData subStatus = null;
+        final String reasonForBlock = null;
         final LocalDate lastActiveTransactionDate = null;
         final boolean isDormancyTrackingActive = false;
         final Integer daysToInactive = null;
@@ -684,15 +688,15 @@ public final class SavingsAccountData implements Serializable {
         final BigDecimal savingsAmountOnHold = null;
 
         return new SavingsAccountData(accountId, accountNo, depositType, externalId, groupId, groupName, clientId, clientName, productId,
-                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, savingsAmountOnHold);
+                productName, fieldOfficerId, fieldOfficerName, status, subStatus, reasonForBlock, 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, savingsAmountOnHold);
     }
 
     public static SavingsAccountData lookupWithProductDetails(final Long accountId, final String accountNo,
@@ -747,6 +751,7 @@ public final class SavingsAccountData implements Serializable {
         final boolean withHoldTax = false;
         final TaxGroupData taxGroup = null;
         final SavingsAccountSubStatusEnumData subStatus = null;
+        final String reasonForBlock = null;
         final LocalDate lastActiveTransactionDate = null;
         final boolean isDormancyTrackingActive = false;
         final Integer daysToInactive = null;
@@ -755,15 +760,15 @@ public final class SavingsAccountData implements Serializable {
         final BigDecimal savingsAmountOnHold = null;
 
         return new SavingsAccountData(accountId, accountNo, depositType, externalId, groupId, groupName, clientId, clientName, productId,
-                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, savingsAmountOnHold);
+                productName, fieldOfficerId, fieldOfficerName, status, subStatus, reasonForBlock, 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, savingsAmountOnHold);
     }
 
     public static SavingsAccountData withTemplateOptions(final SavingsAccountData account, final SavingsAccountData template,
@@ -787,18 +792,19 @@ public final class SavingsAccountData implements Serializable {
 
         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.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, account.savingsAmountOnHold);
+                account.fieldOfficerId, account.fieldOfficerName, account.status, account.subStatus, account.reasonForBlock,
+                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,
+                account.savingsAmountOnHold);
     }
 
     public static SavingsAccountData withTemplateOptions(final SavingsAccountData account,
@@ -813,17 +819,18 @@ public final class SavingsAccountData implements Serializable {
 
         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.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, account.savingsAmountOnHold);
+                account.fieldOfficerId, account.fieldOfficerName, account.status, account.subStatus, account.reasonForBlock,
+                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, account.savingsAmountOnHold);
     }
 
     public static SavingsAccountData withClientTemplate(final Long clientId, final String clientName, final Long groupId,
@@ -880,6 +887,7 @@ public final class SavingsAccountData implements Serializable {
         final Collection<SavingsAccountChargeData> charges = null;
         final Collection<ChargeData> chargeOptions = null;
         final SavingsAccountSubStatusEnumData subStatus = null;
+        final String reasonForBlock = null;
         final LocalDate lastActiveTransactionDate = null;
         final boolean isDormancyTrackingActive = false;
         final Integer daysToInactive = null;
@@ -888,28 +896,28 @@ public final class SavingsAccountData implements Serializable {
         final BigDecimal savingsAmountOnHold = null;
 
         return new SavingsAccountData(id, accountNo, depositType, externalId, groupId, groupName, clientId, clientName, productId,
-                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, savingsAmountOnHold);
+                productName, fieldOfficerId, fieldOfficerName, status, subStatus, reasonForBlock, 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, savingsAmountOnHold);
     }
 
     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 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 SavingsAccountSubStatusEnumData subStatus, final String reasonForBlock,
+            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,
@@ -935,6 +943,7 @@ public final class SavingsAccountData implements Serializable {
         this.fieldOfficerName = fieldOfficerName;
         this.status = status;
         this.subStatus = subStatus;
+        this.reasonForBlock = reasonForBlock;
         this.timeline = timeline;
         this.currency = currency;
         this.nominalAnnualInterestRate = nominalAnnualInterestRate;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java
index acf5fd928..3338635a8 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java
@@ -73,6 +73,8 @@ public final class SavingsAccountTransactionData implements Serializable {
     private final boolean isManualTransaction;
     private final Boolean isReversal;
     private final Long originalTransactionId;
+    private final Long releaseTransactionId;
+    private final String reasonForBlock;
     private Set<SavingsAccountChargesPaidByData> chargesPaidByData = new HashSet<>();
 
     // templates
@@ -347,6 +349,8 @@ public final class SavingsAccountTransactionData implements Serializable {
         this.note = null;
         this.isReversal = null;
         this.originalTransactionId = null;
+        this.releaseTransactionId = null;
+        this.reasonForBlock = null;
     }
 
     public boolean isChargeTransaction() {
@@ -544,7 +548,8 @@ public final class SavingsAccountTransactionData implements Serializable {
         this.isManualTransaction = isManualTransaction;
         this.isReversal = null;
         this.originalTransactionId = null;
-
+        this.releaseTransactionId = null;
+        this.reasonForBlock = null;
     }
 
     private SavingsAccountTransactionData(BigDecimal transactionAmount, LocalDate transactionDate, Long paymentTypeId, String accountNumber,
@@ -582,6 +587,8 @@ public final class SavingsAccountTransactionData implements Serializable {
         this.isManualTransaction = false;
         this.isReversal = null;
         this.originalTransactionId = null;
+        this.releaseTransactionId = null;
+        this.reasonForBlock = null;
     }
 
     private SavingsAccountTransactionData(Integer id, BigDecimal transactionAmount, LocalDate transactionDate, Long paymentTypeId,
@@ -621,6 +628,8 @@ public final class SavingsAccountTransactionData implements Serializable {
         this.isManualTransaction = false;
         this.isReversal = null;
         this.originalTransactionId = null;
+        this.releaseTransactionId = null;
+        this.reasonForBlock = null;
     }
 
     public Integer getRowIndex() {
@@ -753,6 +762,8 @@ public final class SavingsAccountTransactionData implements Serializable {
         this.isManualTransaction = false;
         this.isReversal = null;
         this.originalTransactionId = null;
+        this.releaseTransactionId = null;
+        this.reasonForBlock = null;
     }
 
     public static SavingsAccountTransactionData create(final Long id, final SavingsAccountTransactionEnumData transactionType,
@@ -770,11 +781,12 @@ public final class SavingsAccountTransactionData implements Serializable {
             final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
             final CurrencyData currency, final BigDecimal amount, final BigDecimal outstandingChargeAmount, final BigDecimal runningBalance,
             final boolean reversed, final AccountTransferData transfer, final LocalDate submittedOnDate, final boolean interestedPostedAsOn,
-            final String submittedByUsername, final String note, final Boolean isReversal, final Long originalTransactionId) {
+            final String submittedByUsername, final String note, final Boolean isReversal, final Long originalTransactionId,
+            final Long releaseTransactionId, final String reasonForBlock) {
         final Collection<PaymentTypeData> paymentTypeOptions = null;
         return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency,
                 amount, outstandingChargeAmount, runningBalance, reversed, transfer, paymentTypeOptions, submittedOnDate,
-                interestedPostedAsOn, submittedByUsername, note, isReversal, originalTransactionId);
+                interestedPostedAsOn, submittedByUsername, note, isReversal, originalTransactionId, releaseTransactionId, reasonForBlock);
     }
 
     public static SavingsAccountTransactionData create(final Long id) {
@@ -827,7 +839,7 @@ public final class SavingsAccountTransactionData implements Serializable {
             final CurrencyData currency, final BigDecimal amount, final BigDecimal outstandingChargeAmount, final BigDecimal runningBalance,
             final boolean reversed, final AccountTransferData transfer, final Collection<PaymentTypeData> paymentTypeOptions,
             final LocalDate submittedOnDate, final boolean interestedPostedAsOn, final String submittedByUsername, final String note,
-            final Boolean isReversal, final Long originalTransactionId) {
+            final Boolean isReversal, final Long originalTransactionId, final Long releaseTransactionId, final String reasonForBlock) {
         this.id = id;
         this.transactionType = transactionType;
         this.paymentDetailData = paymentDetailData;
@@ -853,6 +865,8 @@ public final class SavingsAccountTransactionData implements Serializable {
         this.isManualTransaction = false;
         this.isReversal = isReversal;
         this.originalTransactionId = originalTransactionId;
+        this.releaseTransactionId = releaseTransactionId;
+        this.reasonForBlock = reasonForBlock;
     }
 
     private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType,
@@ -886,6 +900,43 @@ public final class SavingsAccountTransactionData implements Serializable {
         this.isManualTransaction = false;
         this.isReversal = null;
         this.originalTransactionId = null;
+        this.releaseTransactionId = null;
+        this.reasonForBlock = null;
+    }
+
+    private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType,
+            final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
+            final CurrencyData currency, final BigDecimal amount, final BigDecimal outstandingChargeAmount, final BigDecimal runningBalance,
+            final boolean reversed, final AccountTransferData transfer, final Collection<PaymentTypeData> paymentTypeOptions,
+            final LocalDate submittedOnDate, final boolean interestedPostedAsOn, final String submittedByUsername, final String note,
+            final Boolean isReversal, final Long originalTransactionId) {
+        this.id = id;
+        this.transactionType = transactionType;
+        this.paymentDetailData = paymentDetailData;
+        this.accountId = savingsId;
+        this.accountNo = savingsAccountNo;
+        this.date = date;
+        this.currency = currency;
+        this.amount = amount;
+        this.outstandingChargeAmount = outstandingChargeAmount;
+        this.runningBalance = runningBalance;
+        this.reversed = reversed;
+        this.transfer = transfer;
+        this.paymentTypeOptions = paymentTypeOptions;
+        if (submittedOnDate != null) {
+            this.submittedOnDate = Date.from(submittedOnDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
+        } else {
+            this.submittedOnDate = null;
+        }
+
+        this.interestedPostedAsOn = interestedPostedAsOn;
+        this.submittedByUsername = submittedByUsername;
+        this.note = note;
+        this.isManualTransaction = false;
+        this.isReversal = isReversal;
+        this.originalTransactionId = originalTransactionId;
+        this.releaseTransactionId = null;
+        this.reasonForBlock = null;
     }
 
     public static SavingsAccountTransactionData withWithDrawalTransactionDetails(
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionDataValidator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionDataValidator.java
index f3acadedf..86235bc9a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionDataValidator.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionDataValidator.java
@@ -57,6 +57,8 @@ import org.apache.fineract.organisation.monetary.domain.Money;
 import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
 import org.apache.fineract.portfolio.savings.SavingsApiConstants;
 import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
+import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler;
+import org.apache.fineract.portfolio.savings.domain.SavingsAccountSubStatusEnum;
 import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
 import org.apache.fineract.portfolio.savings.exception.TransactionBeforePivotDateNotAllowed;
 import org.apache.fineract.useradministration.domain.AppUser;
@@ -69,14 +71,17 @@ public class SavingsAccountTransactionDataValidator {
     private final FromJsonHelper fromApiJsonHelper;
     private static final Set<String> SAVINGS_ACCOUNT_HOLD_AMOUNT_REQUEST_DATA_PARAMETERS = new HashSet<>(
             Arrays.asList(transactionDateParamName, SavingsApiConstants.dateFormatParamName, SavingsApiConstants.localeParamName,
-                    transactionAmountParamName, lienParamName));
+                    transactionAmountParamName, lienParamName, SavingsApiConstants.reasonForBlockParamName));
+
     private final ConfigurationDomainService configurationDomainService;
+    private final SavingsAccountAssembler savingAccountAssembler;
 
     @Autowired
     public SavingsAccountTransactionDataValidator(final FromJsonHelper fromApiJsonHelper,
-            final ConfigurationDomainService configurationDomainService) {
+            final ConfigurationDomainService configurationDomainService, final SavingsAccountAssembler savingAccountAssembler) {
         this.fromApiJsonHelper = fromApiJsonHelper;
         this.configurationDomainService = configurationDomainService;
+        this.savingAccountAssembler = savingAccountAssembler;
     }
 
     public void validateTransactionWithPivotDate(final LocalDate transactionDate, final SavingsAccount savingsAccount) {
@@ -179,6 +184,13 @@ public class SavingsAccountTransactionDataValidator {
                     account.getId());
         }
 
+        if (account.getSubStatus().equals(SavingsAccountSubStatusEnum.BLOCK.getValue())
+                || account.getSubStatus().equals(SavingsAccountSubStatusEnum.BLOCK_CREDIT.getValue())
+                || account.getSubStatus().equals(SavingsAccountSubStatusEnum.BLOCK_DEBIT.getValue())) {
+            baseDataValidator.reset().parameter(SavingsApiConstants.subStatusParamName)
+                    .failWithCodeNoParameterAddedToErrorCode("account.is.in.blocked.state");
+        }
+
         validatePaymentTypeDetails(baseDataValidator, element);
 
         throwExceptionIfValidationWarningsExist(dataValidationErrors);
@@ -225,6 +237,10 @@ public class SavingsAccountTransactionDataValidator {
         baseDataValidator.reset().parameter(transactionAmountParamName).value(amount).notNull().positiveAmount();
         final LocalDate transactionDate = this.fromApiJsonHelper.extractLocalDateNamed(transactionDateParamName, element);
 
+        final String reasonForBlock = this.fromApiJsonHelper.extractStringNamed(SavingsApiConstants.reasonForBlockParamName, element);
+        baseDataValidator.reset().parameter(SavingsApiConstants.reasonForBlockParamName).value(reasonForBlock).notBlank()
+                .notExceedingLengthOf(100);
+
         baseDataValidator.reset().parameter(transactionDateParamName).value(transactionDate).notNull();
         boolean isActive = account.isActive();
 
@@ -232,21 +248,18 @@ public class SavingsAccountTransactionDataValidator {
             baseDataValidator.reset().parameter(SavingsApiConstants.statusParamName)
                     .failWithCodeNoParameterAddedToErrorCode(SavingsApiConstants.ERROR_MSG_SAVINGS_ACCOUNT_NOT_ACTIVE);
         }
-        account.holdAmount(amount);
-
-        if (account.getEnforceMinRequiredBalance()) {
-            if (account.getWithdrawableBalance().compareTo(BigDecimal.ZERO) < 0) {
-                baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("insufficient balance", account.getId());
-            }
-        }
 
         Boolean lien = false;
-
         if (this.fromApiJsonHelper.parameterExists(lienParamName, element)) {
             lien = this.fromApiJsonHelper.extractBooleanNamed(lienParamName, element);
-            if (!lien) {
-                if (account.getWithdrawableBalanceWithoutMinimumBalance().compareTo(BigDecimal.ZERO) < 0) {
-                    baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("insufficient balance", account.getId());
+        }
+
+        if (account.getEnforceMinRequiredBalance()) {
+            if (account.getWithdrawableBalance().compareTo(BigDecimal.ZERO) < 0) {
+                if (!lien) {
+                    if (account.getWithdrawableBalanceWithoutMinimumBalance().compareTo(account.getMinRequiredBalance()) < 0) {
+                        baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("insufficient balance", account.getId());
+                    }
                 }
             }
         }
@@ -271,6 +284,7 @@ public class SavingsAccountTransactionDataValidator {
 
         SavingsAccountTransaction transaction = SavingsAccountTransaction.holdAmount(account, account.office(), paymentDetails,
                 transactionDate, Money.of(account.getCurrency(), amount), createdDate, createdUser);
+
         return transaction;
     }
 
@@ -298,6 +312,7 @@ public class SavingsAccountTransactionDataValidator {
         throwExceptionIfValidationWarningsExist(dataValidationErrors);
         Date createdDate = new Date();
         LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
+
         SavingsAccountTransaction transaction = SavingsAccountTransaction.releaseAmount(holdTransaction, transactionDate, createdDate,
                 createdUser);
         return transaction;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java
index 3bf5809f7..8b56a5875 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java
@@ -220,6 +220,9 @@ public class SavingsAccount extends AbstractPersistableCustom {
     @JoinColumn(name = "closedon_userid", nullable = true)
     protected AppUser closedBy;
 
+    @Column(name = "reason_for_block", nullable = true)
+    protected String reasonForBlock;
+
     @Embedded
     protected MonetaryCurrency currency;
 
@@ -1442,8 +1445,16 @@ public class SavingsAccount extends AbstractPersistableCustom {
         }
 
         if (this.getSavingsHoldAmount().compareTo(BigDecimal.ZERO) > 0) {
-            if (runningBalance.minus(this.getSavingsHoldAmount()).isLessThanZero()) {
-                throw new InsufficientAccountBalanceException("transactionAmount", getAccountBalance(), withdrawalFee, transactionAmount);
+            if (this.enforceMinRequiredBalance) {
+                if (runningBalance.minus(minRequiredBalance.plus(this.getSavingsHoldAmount())).isLessThanZero()) {
+                    throw new InsufficientAccountBalanceException("transactionAmount", getAccountBalance(), withdrawalFee,
+                            transactionAmount);
+                }
+            } else {
+                if (runningBalance.minus(this.getSavingsHoldAmount()).isLessThanZero()) {
+                    throw new InsufficientAccountBalanceException("transactionAmount", getAccountBalance(), withdrawalFee,
+                            transactionAmount);
+                }
             }
         }
     }
@@ -3500,6 +3511,10 @@ public class SavingsAccount extends AbstractPersistableCustom {
         this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, transactions);
     }
 
+    public void updateReason(final String reasonForBlock) {
+        this.reasonForBlock = reasonForBlock;
+    }
+
     public Map<String, Object> block() {
 
         final Map<String, Object> actualChanges = new LinkedHashMap<>();
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountSummary.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountSummary.java
index 92c358e43..8eb54625c 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountSummary.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountSummary.java
@@ -262,6 +262,10 @@ public final class SavingsAccountSummary {
         return this.accountBalance;
     }
 
+    public void setAccountBalance(BigDecimal accountBalance) {
+        this.accountBalance = accountBalance;
+    }
+
     public BigDecimal getTotalInterestPosted() {
         return this.totalInterestPosted;
     }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java
index 014ca9967..6b2c9c119 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java
@@ -127,6 +127,9 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
     @Column(name = "release_id_of_hold_amount", length = 20)
     private Long releaseIdOfHoldAmountTransaction;
 
+    @Column(name = "reason_for_block", nullable = true)
+    private String reasonForBlock;
+
     @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
     @JoinColumn(name = "savings_account_transaction_id", referencedColumnName = "id")
     private List<Note> notes = new ArrayList<>();
@@ -843,6 +846,10 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
         this.releaseIdOfHoldAmountTransaction = releaseId;
     }
 
+    public void updateReason(String reasonForBlock) {
+        this.reasonForBlock = reasonForBlock;
+    }
+
     public Long getReleaseIdOfHoldAmountTransaction() {
         return this.releaseIdOfHoldAmountTransaction;
     }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/BlockCreditsToSavingsAccountCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/BlockCreditsToSavingsAccountCommandHandler.java
index 2c483f605..7f623b460 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/BlockCreditsToSavingsAccountCommandHandler.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/BlockCreditsToSavingsAccountCommandHandler.java
@@ -41,7 +41,7 @@ public class BlockCreditsToSavingsAccountCommandHandler implements NewCommandSou
     @Transactional
     @Override
     public CommandProcessingResult processCommand(JsonCommand command) {
-        return this.writePlatformService.blockCredits(command.getSavingsId());
+        return this.writePlatformService.blockCredits(command.getSavingsId(), command);
     }
 
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/BlockDebitsFromSavingsAccountCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/BlockDebitsFromSavingsAccountCommandHandler.java
index 15bbf5044..53cb80f70 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/BlockDebitsFromSavingsAccountCommandHandler.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/BlockDebitsFromSavingsAccountCommandHandler.java
@@ -41,7 +41,7 @@ public class BlockDebitsFromSavingsAccountCommandHandler implements NewCommandSo
     @Transactional
     @Override
     public CommandProcessingResult processCommand(JsonCommand command) {
-        return this.writePlatformService.blockDebits(command.getSavingsId());
+        return this.writePlatformService.blockDebits(command.getSavingsId(), command);
     }
 
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/BlockSavingsAccountCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/BlockSavingsAccountCommandHandler.java
index 6001c668d..d2dec0012 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/BlockSavingsAccountCommandHandler.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/BlockSavingsAccountCommandHandler.java
@@ -41,7 +41,7 @@ public class BlockSavingsAccountCommandHandler implements NewCommandSourceHandle
     @Transactional
     @Override
     public CommandProcessingResult processCommand(JsonCommand command) {
-        return this.writePlatformService.blockAccount(command.getSavingsId());
+        return this.writePlatformService.blockAccount(command.getSavingsId(), command);
     }
 
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java
index 71e67943b..0888ea820 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java
@@ -576,7 +576,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
                     final BigDecimal minRequiredBalance = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "minRequiredBalance");
                     final boolean enforceMinRequiredBalance = rs.getBoolean("enforceMinRequiredBalance");
                     savingsAccountData = SavingsAccountData.instance(id, accountNo, depositType, externalId, null, null, null, null,
-                            productId, null, null, null, status, subStatus, timeline, currency, nominalAnnualInterestRate,
+                            productId, null, null, null, status, subStatus, null, timeline, currency, nominalAnnualInterestRate,
                             interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType,
                             interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
                             withdrawalFeeForTransfers, summary, allowOverdraft, overdraftLimit, minRequiredBalance,
@@ -746,6 +746,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
             sqlBuilder.append("s.id fieldOfficerId, s.display_name as fieldOfficerName, ");
             sqlBuilder.append("sa.status_enum as statusEnum, ");
             sqlBuilder.append("sa.sub_status_enum as subStatusEnum, ");
+            sqlBuilder.append("sa.reason_for_block as reasonForBlock, ");
             sqlBuilder.append("sa.submittedon_date as submittedOnDate,");
             sqlBuilder.append("sbu.username as submittedByUsername,");
             sqlBuilder.append("sbu.firstname as submittedByFirstname, sbu.lastname as submittedByLastname,");
@@ -874,6 +875,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
 
             final Integer subStatusEnum = JdbcSupport.getInteger(rs, "subStatusEnum");
             final SavingsAccountSubStatusEnumData subStatus = SavingsEnumerations.subStatus(subStatusEnum);
+            final String reasonForBlock = rs.getString("reasonForBlock");
 
             final LocalDate lastActiveTransactionDate = JdbcSupport.getLocalDate(rs, "lastActiveTransactionDate");
             final boolean isDormancyTrackingActive = rs.getBoolean("isDormancyTrackingActive");
@@ -1022,7 +1024,6 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
 
             BigDecimal availableBalance = accountBalance;
             if (availableBalance != null && onHoldFunds != null) {
-
                 availableBalance = availableBalance.subtract(onHoldFunds);
             }
 
@@ -1052,12 +1053,13 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
             }
 
             return SavingsAccountData.instance(id, accountNo, depositType, externalId, groupId, groupName, clientId, clientName, productId,
-                    productName, fieldOfficerId, fieldOfficerName, status, subStatus, timeline, currency, nominalAnnualInterestRate,
-                    interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
-                    minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary,
-                    allowOverdraft, overdraftLimit, minRequiredBalance, enforceMinRequiredBalance, minBalanceForInterestCalculation,
-                    onHoldFunds, nominalAnnualInterestRateOverdraft, minOverdraftForInterestCalculation, withHoldTax, taxGroupData,
-                    lastActiveTransactionDate, isDormancyTrackingActive, daysToInactive, daysToDormancy, daysToEscheat, onHoldAmount);
+                    productName, fieldOfficerId, fieldOfficerName, status, subStatus, reasonForBlock, timeline, currency,
+                    nominalAnnualInterestRate, interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType,
+                    interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
+                    withdrawalFeeForTransfers, summary, allowOverdraft, overdraftLimit, minRequiredBalance, enforceMinRequiredBalance,
+                    minBalanceForInterestCalculation, onHoldFunds, nominalAnnualInterestRateOverdraft, minOverdraftForInterestCalculation,
+                    withHoldTax, taxGroupData, lastActiveTransactionDate, isDormancyTrackingActive, daysToInactive, daysToDormancy,
+                    daysToEscheat, onHoldAmount);
         }
     }
 
@@ -1312,6 +1314,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
             final StringBuilder sqlBuilder = new StringBuilder(400);
             sqlBuilder.append("tr.id as transactionId, tr.transaction_type_enum as transactionType, ");
             sqlBuilder.append("tr.transaction_date as transactionDate, tr.amount as transactionAmount,");
+            sqlBuilder.append(" tr.release_id_of_hold_amount as releaseTransactionId,");
+            sqlBuilder.append(" tr.reason_for_block as reasonForBlock,");
             sqlBuilder.append("tr.created_date as submittedOnDate,");
             sqlBuilder.append(" au.username as submittedByUsername, ");
             sqlBuilder.append(" nt.note as transactionNote, ");
@@ -1357,6 +1361,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
             final LocalDate date = JdbcSupport.getLocalDate(rs, "transactionDate");
             final LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, "submittedOnDate");
             final BigDecimal amount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "transactionAmount");
+            final Long releaseTransactionId = rs.getLong("releaseTransactionId");
+            final String reasonForBlock = rs.getString("reasonForBlock");
             final BigDecimal outstandingChargeAmount = null;
             final BigDecimal runningBalance = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "runningBalance");
             final boolean reversed = rs.getBoolean("reversed");
@@ -1416,7 +1422,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
             final String note = rs.getString("transactionNote");
             return SavingsAccountTransactionData.create(id, transactionType, paymentDetailData, savingsId, accountNo, date, currency,
                     amount, outstandingChargeAmount, runningBalance, reversed, transfer, submittedOnDate, postInterestAsOn,
-                    submittedByUsername, note, isReversal, originalTransactionId);
+                    submittedByUsername, note, isReversal, originalTransactionId, releaseTransactionId, reasonForBlock);
         }
     }
 
@@ -1619,6 +1625,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
             final BigDecimal savingsAmountOnHold = null;
 
             final SavingsAccountSubStatusEnumData subStatus = null;
+            final String reasonForBlock = null;
             final LocalDate lastActiveTransactionDate = null;
             final boolean isDormancyTrackingActive = false;
             final Integer daysToInactive = null;
@@ -1628,13 +1635,13 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
             final SavingsAccountApplicationTimelineData timeline = SavingsAccountApplicationTimelineData.templateDefault();
             final EnumOptionData depositType = null;
             return SavingsAccountData.instance(null, null, depositType, null, groupId, groupName, clientId, clientName, productId,
-                    productName, fieldOfficerId, fieldOfficerName, status, subStatus, timeline, currency, nominalAnnualIterestRate,
-                    interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
-                    minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary,
-                    allowOverdraft, overdraftLimit, minRequiredBalance, enforceMinRequiredBalance, minBalanceForInterestCalculation,
-                    onHoldFunds, nominalAnnualInterestRateOverdraft, minOverdraftForInterestCalculation, withHoldTax, taxGroupData,
-                    lastActiveTransactionDate, isDormancyTrackingActive, daysToInactive, daysToDormancy, daysToEscheat,
-                    savingsAmountOnHold);
+                    productName, fieldOfficerId, fieldOfficerName, status, subStatus, reasonForBlock, timeline, currency,
+                    nominalAnnualIterestRate, interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType,
+                    interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
+                    withdrawalFeeForTransfers, summary, allowOverdraft, overdraftLimit, minRequiredBalance, enforceMinRequiredBalance,
+                    minBalanceForInterestCalculation, onHoldFunds, nominalAnnualInterestRateOverdraft, minOverdraftForInterestCalculation,
+                    withHoldTax, taxGroupData, lastActiveTransactionDate, isDormancyTrackingActive, daysToInactive, daysToDormancy,
+                    daysToEscheat, savingsAmountOnHold);
         }
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformService.java
index 2036b53d1..dab91c282 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformService.java
@@ -96,17 +96,17 @@ public interface SavingsAccountWritePlatformService {
     SavingsAccountData postInterest(SavingsAccountData account, boolean postInterestAs, LocalDate transactionDate,
             boolean backdatedTxnsAllowedTill);
 
-    CommandProcessingResult blockAccount(Long savingsId);
+    CommandProcessingResult blockAccount(Long savingsId, JsonCommand command);
 
     CommandProcessingResult unblockAccount(Long savingsId);
 
     CommandProcessingResult holdAmount(Long savingsId, JsonCommand command);
 
-    CommandProcessingResult blockCredits(Long savingsId);
+    CommandProcessingResult blockCredits(Long savingsId, JsonCommand command);
 
     CommandProcessingResult unblockCredits(Long savingsId);
 
-    CommandProcessingResult blockDebits(Long savingsId);
+    CommandProcessingResult blockDebits(Long savingsId, JsonCommand command);
 
     CommandProcessingResult unblockDebits(Long savingsId);
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java
index 9d920fc2d..68acfaf16 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java
@@ -23,6 +23,7 @@ import static org.apache.fineract.portfolio.savings.SavingsApiConstants.SAVINGS_
 import static org.apache.fineract.portfolio.savings.SavingsApiConstants.amountParamName;
 import static org.apache.fineract.portfolio.savings.SavingsApiConstants.chargeIdParamName;
 import static org.apache.fineract.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName;
+import static org.apache.fineract.portfolio.savings.SavingsApiConstants.transactionAmountParamName;
 import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withHoldTaxParamName;
 import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withdrawBalanceParamName;
 
@@ -53,6 +54,7 @@ import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuild
 import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
 import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
 import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
 import org.apache.fineract.infrastructure.core.exception.PlatformServiceUnavailableException;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
@@ -1762,7 +1764,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
     }
 
     @Override
-    public CommandProcessingResult blockAccount(final Long savingsId) {
+    public CommandProcessingResult blockAccount(final Long savingsId, final JsonCommand command) {
 
         this.context.authenticatedUser();
 
@@ -1770,6 +1772,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
         checkClientOrGroupActive(account);
 
         final Map<String, Object> changes = account.block();
+
+        final String reasonForBlock = command.stringValueOfParameterNamed(SavingsApiConstants.reasonForBlockParamName);
+        validateReasonForHold(reasonForBlock);
+        account.updateReason(reasonForBlock);
+
         if (!changes.isEmpty()) {
 
             this.savingAccountRepositoryWrapper.save(account);
@@ -1786,6 +1793,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
         checkClientOrGroupActive(account);
 
         final Map<String, Object> changes = account.unblock();
+
+        account.updateReason(null);
+
         if (!changes.isEmpty()) {
 
             this.savingAccountRepositoryWrapper.save(account);
@@ -1804,12 +1814,29 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
 
         checkClientOrGroupActive(account);
 
-        SavingsAccountTransaction transacton = this.savingsAccountTransactionDataValidator.validateHoldAndAssembleForm(command.json(),
+        final BigDecimal amount = command.bigDecimalValueOfParameterNamed(transactionAmountParamName);
+
+        Money runningBalance = Money.of(account.getCurrency(), account.getAccountBalance());
+        if (account.getSavingsHoldAmount() != null) {
+            runningBalance = runningBalance.minus(account.getSavingsHoldAmount()).minus(amount);
+        } else {
+            runningBalance = runningBalance.minus(amount);
+        }
+
+        account.holdAmount(amount);
+
+        SavingsAccountTransaction transaction = this.savingsAccountTransactionDataValidator.validateHoldAndAssembleForm(command.json(),
                 account, submittedBy, backdatedTxnsAllowedTill);
 
-        this.savingsAccountTransactionDataValidator.validateTransactionWithPivotDate(transacton.getTransactionLocalDate(), account);
+        transaction.updateRunningBalance(runningBalance);
+
+        final String reasonForBlock = command.stringValueOfParameterNamed(SavingsApiConstants.reasonForBlockParamName);
+        transaction.updateReason(reasonForBlock);
 
-        this.savingsAccountTransactionRepository.saveAndFlush(transacton);
+        account.getAccountBalance();
+        this.savingsAccountTransactionDataValidator.validateTransactionWithPivotDate(transaction.getTransactionLocalDate(), account);
+
+        this.savingsAccountTransactionRepository.saveAndFlush(transaction);
 
         if (backdatedTxnsAllowedTill) {
             // Check again whether transactions are modified
@@ -1818,7 +1845,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
 
         this.savingAccountRepositoryWrapper.saveAndFlush(account);
 
-        return new CommandProcessingResultBuilder().withEntityId(transacton.getId()).withOfficeId(account.officeId())
+        return new CommandProcessingResultBuilder().withEntityId(transaction.getId()).withOfficeId(account.officeId())
                 .withClientId(account.clientId()).withGroupId(account.groupId()).withSavingsId(savingsId).build();
     }
 
@@ -1830,6 +1857,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
         SavingsAccountTransaction holdTransaction = this.savingsAccountTransactionRepository
                 .findOneByIdAndSavingsAccountId(savingsTransactionId, savingsId);
 
+        holdTransaction.updateReason(null);
+
         final SavingsAccountTransaction transaction = this.savingsAccountTransactionDataValidator
                 .validateReleaseAmountAndAssembleForm(holdTransaction, submittedBy);
 
@@ -1837,6 +1866,15 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
         final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId, backdatedTxnsAllowedTill);
         checkClientOrGroupActive(account);
 
+        Money runningBalance = Money.of(account.getCurrency(), account.getAccountBalance());
+
+        Money savingsOnHold = Money.of(account.getCurrency(), account.getSavingsHoldAmount());
+
+        runningBalance = runningBalance.minus(savingsOnHold);
+
+        runningBalance = runningBalance.plus(transaction.getAmount());
+        transaction.updateRunningBalance(runningBalance);
+
         this.savingsAccountTransactionDataValidator.validateTransactionWithPivotDate(transaction.getTransactionLocalDate(), account);
         account.releaseOnHoldAmount(transaction.getAmount());
 
@@ -1855,12 +1893,16 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
 
     @Transactional
     @Override
-    public CommandProcessingResult blockCredits(final Long savingsId) {
+    public CommandProcessingResult blockCredits(final Long savingsId, final JsonCommand command) {
         this.context.authenticatedUser();
 
         final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId, false);
         checkClientOrGroupActive(account);
 
+        final String reasonForBlock = command.stringValueOfParameterNamed(SavingsApiConstants.reasonForBlockParamName);
+        validateReasonForHold(reasonForBlock);
+        account.updateReason(reasonForBlock);
+
         final Map<String, Object> changes = account.blockCredits(account.getSubStatus());
         if (!changes.isEmpty()) {
 
@@ -1877,7 +1919,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
 
         final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId, false);
         checkClientOrGroupActive(account);
-
+        account.updateReason(null);
         final Map<String, Object> changes = account.unblockCredits();
         if (!changes.isEmpty()) {
 
@@ -1889,12 +1931,16 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
 
     @Transactional
     @Override
-    public CommandProcessingResult blockDebits(final Long savingsId) {
+    public CommandProcessingResult blockDebits(final Long savingsId, final JsonCommand command) {
         this.context.authenticatedUser();
 
         final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId, false);
         checkClientOrGroupActive(account);
 
+        final String reasonForBlock = command.stringValueOfParameterNamed(SavingsApiConstants.reasonForBlockParamName);
+        validateReasonForHold(reasonForBlock);
+        account.updateReason(reasonForBlock);
+
         final Map<String, Object> changes = account.blockDebits(account.getSubStatus());
         if (!changes.isEmpty()) {
 
@@ -1912,6 +1958,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
         final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId, false);
         checkClientOrGroupActive(account);
 
+        account.updateReason(null);
+
         final Map<String, Object> changes = account.unblockDebits();
         if (!changes.isEmpty()) {
 
@@ -1934,4 +1982,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
         }
 
     }
+
+    private void validateReasonForHold(String reasonForBlock) {
+        if (StringUtils.isBlank(reasonForBlock)) {
+            throw new PlatformDataIntegrityException("Reason For Block is Mandatory", "error.msg.reason.for.block.mandatory");
+        }
+    }
 }
diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
index 8412d3ac3..bc73503ce 100644
--- a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
+++ b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
@@ -28,4 +28,5 @@
     <include file="parts/0006_product_loan_disallow_expected_disbursements.xml" relativeToChangelogFile="true"/>
     <include file="parts/0007_product_loan_higher_than_applied_loan_amount_management.xml" relativeToChangelogFile="true"/>
     <include file="parts/0008_loan_charge_add_external_id.xml" relativeToChangelogFile="true"/>
+    <include file="parts/0009_hold_reason_savings_account.xml" relativeToChangelogFile="true"/>
 </databaseChangeLog>
diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0009_hold_reason_savings_account.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0009_hold_reason_savings_account.xml
new file mode 100644
index 000000000..d9e2d6755
--- /dev/null
+++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0009_hold_reason_savings_account.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
+    <changeSet author="fineract" id="1">
+        <addColumn tableName="m_savings_account">
+            <column name="reason_for_block" type="VARCHAR(256)"/>
+        </addColumn>
+    </changeSet>
+    <changeSet author="fineract" id="2">
+        <addColumn tableName="m_savings_account_transaction">
+            <column name="reason_for_block" type="VARCHAR(256)"/>
+        </addColumn>
+    </changeSet>
+    <changeSet author="fineract" id="3">
+        <insert tableName="m_code">
+            <column name="code_name" value="SavingsAccountBlockReasons"/>
+            <column name="is_system_defined" valueBoolean="true"/>
+        </insert>
+        <insert tableName="m_code">
+            <column name="code_name" value="DebitTransactionFreezeReasons"/>
+            <column name="is_system_defined" valueBoolean="true"/>
+        </insert>
+        <insert tableName="m_code">
+            <column name="code_name" value="CreditTransactionFreezeReasons"/>
+            <column name="is_system_defined" valueBoolean="true"/>
+        </insert>
+        <insert tableName="m_code">
+            <column name="code_name" value="SavingsTransactionFreezeReasons"/>
+            <column name="is_system_defined" valueBoolean="true"/>
+        </insert>
+    </changeSet>
+</databaseChangeLog>
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientSavingsIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientSavingsIntegrationTest.java
index 88465822d..ef2fa2fbb 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientSavingsIntegrationTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientSavingsIntegrationTest.java
@@ -2193,7 +2193,7 @@ public class ClientSavingsIntegrationTest {
 
         final String minBalanceForInterestCalculation = null;
         final String minRequiredBalance = null;
-        final String enforceMinRequiredBalance = "false";
+        final String enforceMinRequiredBalance = "true";
         final boolean allowOverdraft = false;
         final Integer savingsProductID = createSavingsProduct(this.requestSpec, this.responseSpec, MINIMUM_OPENING_BALANCE,
                 minBalanceForInterestCalculation, minRequiredBalance, enforceMinRequiredBalance, allowOverdraft);
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsAccountHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsAccountHelper.java
index 733cf33b7..e0335b1bb 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsAccountHelper.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsAccountHelper.java
@@ -338,8 +338,8 @@ public class SavingsAccountHelper {
     public HashMap blockSavings(final Integer savingsID) {
         LOG.info("---------------------------------- BLOCKING SAVINGS ACCOUNT ----------------------------------");
         Boolean isBlock = true;
-        return performSavingApplicationActions(createSavingsOperationURL(BLOCK_SAVINGS_COMMAND, savingsID), getActivatedSavingsAsJSON(),
-                isBlock);
+        return performSavingApplicationActions(createSavingsOperationURL(BLOCK_SAVINGS_COMMAND, savingsID),
+                getActivatedSavingsAsForHoldJSON(), isBlock);
     }
 
     public HashMap unblockSavings(final Integer savingsID) {
@@ -353,7 +353,7 @@ public class SavingsAccountHelper {
         LOG.info("---------------------------------- BLOCKING DEBIT TRANSACTIONS ----------------------------------");
         Boolean isBlock = true;
         return performSavingApplicationActions(createSavingsOperationURL(BLOCK_DEBITS_SAVINGS_COMMAND, savingsID),
-                getActivatedSavingsAsJSON(), isBlock);
+                getActivatedSavingsAsForHoldJSON(), isBlock);
     }
 
     public HashMap unblockDebit(final Integer savingsID) {
@@ -367,7 +367,7 @@ public class SavingsAccountHelper {
         LOG.info("---------------------------------- BLOCKING CREDIT TRANSACTIONS ----------------------------------");
         Boolean isBlock = true;
         return performSavingApplicationActions(createSavingsOperationURL(BLOCK_CREDITS_SAVINGS_COMMAND, savingsID),
-                getActivatedSavingsAsJSON(), isBlock);
+                getActivatedSavingsAsForHoldJSON(), isBlock);
     }
 
     public HashMap unblockCredit(final Integer savingsID) {
@@ -437,6 +437,17 @@ public class SavingsAccountHelper {
         return savingsAccountActivateJson;
     }
 
+    private String getActivatedSavingsAsForHoldJSON() {
+        final HashMap<String, String> map = new HashMap<>();
+        map.put("locale", CommonConstants.LOCALE);
+        map.put("dateFormat", CommonConstants.DATE_FORMAT);
+        map.put("activatedOnDate", TRANSACTION_DATE);
+        map.put("reasonForBlock", "unUsualActivity");
+        String savingsAccountActivateJson = new Gson().toJson(map);
+        LOG.info(savingsAccountActivateJson);
+        return savingsAccountActivateJson;
+    }
+
     private String getSavingsTransactionJSON(final String amount, final String transactionDate) {
         final HashMap<String, String> map = new HashMap<>();
         map.put("locale", CommonConstants.LOCALE);
@@ -455,6 +466,7 @@ public class SavingsAccountHelper {
         map.put("transactionDate", transactionDate);
         map.put("transactionAmount", amount);
         map.put("lien", lien);
+        map.put("reasonForBlock", "unUsualActivity");
         String savingsAccountWithdrawalJson = new Gson().toJson(map);
         LOG.info(savingsAccountWithdrawalJson);
         return savingsAccountWithdrawalJson;