You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ad...@apache.org on 2023/09/18 13:20:02 UTC

[fineract] branch develop updated: FINERACT-1931: Savings Account with overdraft - cannot deposit after negative balance

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

adamsaghy 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 1f107b4e8 FINERACT-1931: Savings Account with overdraft - cannot deposit after negative balance
1f107b4e8 is described below

commit 1f107b4e817631e609a15fcf70cde1e202c7a961
Author: jmarta <ma...@dpc.hu>
AuthorDate: Tue Sep 5 19:30:49 2023 +0200

    FINERACT-1931: Savings Account with overdraft - cannot deposit after negative balance
---
 .../data/SavingsAccountTransactionData.java        | 554 ++++++++-------------
 .../data/SavingsAccountTransactionEnumData.java    |  58 ++-
 .../service/SavingsSchedularInterestPoster.java    |   2 +-
 .../ClientSavingsIntegrationTest.java              |  49 ++
 4 files changed, 282 insertions(+), 381 deletions(-)

diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java
index d99dcd95f..0ff25943d 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java
@@ -30,7 +30,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import lombok.Getter;
-import org.apache.fineract.infrastructure.codes.data.CodeValueData;
 import org.apache.fineract.infrastructure.core.domain.LocalDateInterval;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
@@ -68,7 +67,7 @@ public final class SavingsAccountTransactionData implements Serializable {
     private BigDecimal runningBalance;
     private boolean reversed;
     private final AccountTransferData transfer;
-    private LocalDate submittedOnDate;
+    private final LocalDate submittedOnDate;
     private final boolean interestedPostedAsOn;
     private final String submittedByUsername;
     private final String note;
@@ -78,10 +77,10 @@ public final class SavingsAccountTransactionData implements Serializable {
     private final Boolean lienTransaction;
     private final Long releaseTransactionId;
     private final String reasonForBlock;
-    private Set<SavingsAccountChargesPaidByData> chargesPaidByData = new HashSet<>();
+    private final Set<SavingsAccountChargesPaidByData> chargesPaidByData = new HashSet<>();
 
     // templates
-    final Collection<PaymentTypeData> paymentTypeOptions;
+    private final Collection<PaymentTypeData> paymentTypeOptions;
 
     // import fields
     private transient Integer rowIndex;
@@ -96,45 +95,217 @@ public final class SavingsAccountTransactionData implements Serializable {
     private String routingCode;
     private String receiptNumber;
     private String bankNumber;
+
     private BigDecimal cumulativeBalance;
     private LocalDate balanceEndDate;
-    private transient List<TaxDetailsData> taxDetails = new ArrayList<>();
+    private final transient List<TaxDetailsData> taxDetails = new ArrayList<>();
     private Integer balanceNumberOfDays;
     private BigDecimal overdraftAmount;
     private transient Long modifiedId;
     private transient String refNo;
 
+    private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType,
+            final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate transactionDate,
+            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, boolean isManualTransaction, final Boolean lienTransaction,
+            final Long releaseTransactionId, final String reasonForBlock) {
+        this.id = id;
+        this.transactionType = transactionType;
+        TransactionEntryType entryType = null;
+        if (transactionType != null) {
+            entryType = transactionType.getEntryType();
+            entryType = entryType != null && Boolean.TRUE.equals(isReversal) ? entryType.getReversal() : entryType;
+        }
+        this.entryType = entryType;
+
+        // duplicated fields
+        this.accountId = savingsId;
+        this.accountNo = savingsAccountNo;
+        this.date = transactionDate;
+        this.amount = amount;
+
+        this.paymentDetailData = paymentDetailData;
+        this.currency = currency;
+        this.outstandingChargeAmount = outstandingChargeAmount;
+        this.runningBalance = runningBalance;
+        this.reversed = reversed;
+        this.transfer = transfer;
+        this.paymentTypeOptions = paymentTypeOptions;
+        this.submittedOnDate = submittedOnDate;
+
+        this.interestedPostedAsOn = interestedPostedAsOn;
+        this.submittedByUsername = submittedByUsername;
+        this.note = note;
+        this.isManualTransaction = isManualTransaction;
+        this.isReversal = isReversal;
+        this.originalTransactionId = originalTransactionId;
+        this.lienTransaction = lienTransaction;
+        this.releaseTransactionId = releaseTransactionId;
+        this.reasonForBlock = reasonForBlock;
+    }
+
+    private static SavingsAccountTransactionData createData(final Long id, final SavingsAccountTransactionEnumData transactionType,
+            final PaymentDetailData paymentDetailData, final Long accountId, final String accountNo, 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 lienTransaction) {
+        return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, accountId, accountNo, date, currency, amount,
+                outstandingChargeAmount, runningBalance, reversed, transfer, paymentTypeOptions, submittedOnDate, interestedPostedAsOn,
+                submittedByUsername, note, null, null, false, lienTransaction, null, null);
+    }
+
+    public static SavingsAccountTransactionData create(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 LocalDate submittedOnDate, final boolean interestedPostedAsOn,
+            final String submittedByUsername, final String note, final Boolean isReversal, final Long originalTransactionId,
+            final Boolean lienTransaction, final Long releaseTransactionId, final String reasonForBlock) {
+        return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency,
+                amount, outstandingChargeAmount, runningBalance, reversed, transfer, null, submittedOnDate, interestedPostedAsOn,
+                submittedByUsername, note, isReversal, originalTransactionId, false, lienTransaction, releaseTransactionId, reasonForBlock);
+    }
+
+    public static SavingsAccountTransactionData create(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 boolean interestedPostedAsOn,
+            final String submittedByUsername, final String note, final LocalDate submittedOnDate) {
+        return createData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency, amount,
+                outstandingChargeAmount, runningBalance, reversed, transfer, null, submittedOnDate, interestedPostedAsOn,
+                submittedByUsername, note, false);
+    }
+
+    public static SavingsAccountTransactionData create(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 LocalDate submittedOnDate, final boolean interestedPostedAsOn, final BigDecimal cumulativeBalance,
+            final LocalDate balanceEndDate) {
+        SavingsAccountTransactionData data = createData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency,
+                amount, outstandingChargeAmount, runningBalance, reversed, null, null, submittedOnDate, interestedPostedAsOn, null, null,
+                false);
+        data.transactionDate = date;
+        data.cumulativeBalance = cumulativeBalance;
+        data.balanceEndDate = balanceEndDate;
+        return data;
+    }
+
+    public static SavingsAccountTransactionData create(final Long id) {
+        return createData(id, null, null, null, null, null, null, null, null, null, false, null, null, null, false, null, null, false);
+    }
+
+    public static SavingsAccountTransactionData withWithDrawalTransactionDetails(
+            final SavingsAccountTransactionData savingsAccountTransactionData) {
+        final LocalDate currentDate = DateUtils.getBusinessLocalDate();
+        final SavingsAccountTransactionEnumData transactionType = SavingsEnumerations
+                .transactionType(SavingsAccountTransactionType.WITHDRAWAL.getValue());
+        return createData(savingsAccountTransactionData.getId(), transactionType, savingsAccountTransactionData.getPaymentDetailData(),
+                savingsAccountTransactionData.getAccountId(), savingsAccountTransactionData.getAccountNo(), currentDate,
+                savingsAccountTransactionData.getCurrency(), savingsAccountTransactionData.getAmount(),
+                savingsAccountTransactionData.getOutstandingChargeAmount(), savingsAccountTransactionData.getRunningBalance(),
+                savingsAccountTransactionData.isReversed(), savingsAccountTransactionData.getTransfer(),
+                savingsAccountTransactionData.getPaymentTypeOptions(), savingsAccountTransactionData.getSubmittedOnDate(),
+                savingsAccountTransactionData.isInterestedPostedAsOn(), savingsAccountTransactionData.getSubmittedByUsername(),
+                savingsAccountTransactionData.getNote(), savingsAccountTransactionData.getLienTransaction());
+    }
+
+    public static SavingsAccountTransactionData template(final Long savingsId, final String savingsAccountNo,
+            final LocalDate defaultLocalDate, final CurrencyData currency) {
+        return createData(null, null, null, savingsId, savingsAccountNo, defaultLocalDate, currency, null, null, null, false, null, null,
+                defaultLocalDate, false, null, null, false);
+    }
+
+    public static SavingsAccountTransactionData templateOnTop(final SavingsAccountTransactionData savingsAccountTransactionData,
+            final Collection<PaymentTypeData> paymentTypeOptions) {
+        return createData(savingsAccountTransactionData.getId(), savingsAccountTransactionData.getTransactionType(),
+                savingsAccountTransactionData.getPaymentDetailData(), savingsAccountTransactionData.getAccountId(),
+                savingsAccountTransactionData.getAccountNo(), savingsAccountTransactionData.getDate(),
+                savingsAccountTransactionData.getCurrency(), savingsAccountTransactionData.getAmount(),
+                savingsAccountTransactionData.getOutstandingChargeAmount(), savingsAccountTransactionData.getRunningBalance(),
+                savingsAccountTransactionData.isReversed(), savingsAccountTransactionData.getTransfer(), paymentTypeOptions,
+                savingsAccountTransactionData.getSubmittedOnDate(), savingsAccountTransactionData.isInterestedPostedAsOn(),
+                savingsAccountTransactionData.getSubmittedByUsername(), savingsAccountTransactionData.getNote(),
+                savingsAccountTransactionData.getLienTransaction());
+    }
+
+    private static SavingsAccountTransactionData createImport(final SavingsAccountTransactionEnumData transactionType,
+            final PaymentDetailData paymentDetailData, final Long savingsAccountId, final String accountNumber,
+            final LocalDate transactionDate, final BigDecimal transactionAmount, final boolean reversed, final LocalDate submittedOnDate,
+            boolean isManualTransaction, final Boolean lienTransaction) {
+        SavingsAccountTransactionData data = new SavingsAccountTransactionData(null, transactionType, paymentDetailData, savingsAccountId,
+                accountNumber, transactionDate, null, transactionAmount, null, null, reversed, null, null, submittedOnDate, false, null,
+                null, null, null, isManualTransaction, lienTransaction, null, null);
+        // duplicated import fields
+        data.savingsAccountId = savingsAccountId;
+        data.accountNumber = accountNumber;
+        data.transactionDate = transactionDate;
+        data.transactionAmount = transactionAmount;
+        return data;
+    }
+
+    public static SavingsAccountTransactionData copyTransaction(SavingsAccountTransactionData accountTransaction) {
+        return createImport(accountTransaction.getTransactionType(), accountTransaction.getPaymentDetailData(),
+                accountTransaction.getSavingsAccountId(), null, accountTransaction.getTransactionDate(), accountTransaction.getAmount(),
+                accountTransaction.isReversed(), accountTransaction.getSubmittedOnDate(), accountTransaction.isManualTransaction(),
+                accountTransaction.getLienTransaction());
+    }
+
     public static SavingsAccountTransactionData importInstance(BigDecimal transactionAmount, LocalDate transactionDate, Long paymentTypeId,
             String accountNumber, String checkNumber, String routingCode, String receiptNumber, String bankNumber, Long savingsAccountId,
             SavingsAccountTransactionEnumData transactionType, Integer rowIndex, String locale, String dateFormat) {
-        return new SavingsAccountTransactionData(transactionAmount, transactionDate, paymentTypeId, accountNumber, checkNumber, routingCode,
-                receiptNumber, bankNumber, savingsAccountId, transactionType, rowIndex, locale, dateFormat, false);
+        SavingsAccountTransactionData data = createImport(transactionType, null, savingsAccountId, accountNumber, transactionDate,
+                transactionAmount, false, transactionDate, false, false);
+        data.rowIndex = rowIndex;
+        data.paymentTypeId = paymentTypeId;
+        data.checkNumber = checkNumber;
+        data.routingCode = routingCode;
+        data.receiptNumber = receiptNumber;
+        data.bankNumber = bankNumber;
+        data.locale = locale;
+        data.dateFormat = dateFormat;
+        return data;
+    }
+
+    private static SavingsAccountTransactionData createImport(SavingsAccountTransactionEnumData transactionType, Long savingsAccountId,
+            LocalDate transactionDate, BigDecimal transactionAmount, final LocalDate submittedOnDate, boolean isManualTransaction) {
+        // import transaction
+        return createImport(transactionType, null, savingsAccountId, null, transactionDate, transactionAmount, false, submittedOnDate,
+                isManualTransaction, false);
     }
 
     public static SavingsAccountTransactionData interestPosting(final SavingsAccountData savingsAccount, final LocalDate date,
             final Money amount, final boolean isManualTransaction) {
-        final boolean isReversed = false;
-        final Boolean lienTransaction = false;
         final LocalDate submittedOnDate = DateUtils.getBusinessLocalDate();
         final SavingsAccountTransactionType savingsAccountTransactionType = SavingsAccountTransactionType.INTEREST_POSTING;
-        SavingsAccountTransactionEnumData savingsAccountTransactionEnumData = new SavingsAccountTransactionEnumData(
+        SavingsAccountTransactionEnumData transactionType = new SavingsAccountTransactionEnumData(
                 savingsAccountTransactionType.getValue().longValue(), savingsAccountTransactionType.getCode(),
                 savingsAccountTransactionType.getValue().toString());
-        return new SavingsAccountTransactionData(amount.getAmount(), date, savingsAccount.getId(), savingsAccountTransactionEnumData,
-                isReversed, null, isManualTransaction, lienTransaction, submittedOnDate);
+        return createImport(transactionType, savingsAccount.getId(), date, amount.getAmount(), submittedOnDate, isManualTransaction);
     }
 
     public static SavingsAccountTransactionData overdraftInterest(final SavingsAccountData savingsAccount, final LocalDate date,
             final Money amount, final boolean isManualTransaction) {
-        final boolean isReversed = false;
-        final Boolean lienTransaction = false;
         final LocalDate submittedOnDate = DateUtils.getBusinessLocalDate();
         final SavingsAccountTransactionType savingsAccountTransactionType = SavingsAccountTransactionType.OVERDRAFT_INTEREST;
-        SavingsAccountTransactionEnumData savingsAccountTransactionEnumData = new SavingsAccountTransactionEnumData(
+        SavingsAccountTransactionEnumData transactionType = new SavingsAccountTransactionEnumData(
                 savingsAccountTransactionType.getValue().longValue(), savingsAccountTransactionType.getCode(),
                 savingsAccountTransactionType.getValue().toString());
-        return new SavingsAccountTransactionData(amount.getAmount(), date, savingsAccount.getId(), savingsAccountTransactionEnumData,
-                isReversed, null, isManualTransaction, lienTransaction, submittedOnDate);
+        return createImport(transactionType, savingsAccount.getId(), date, amount.getAmount(), submittedOnDate, isManualTransaction);
+    }
+
+    public static SavingsAccountTransactionData withHoldTax(final SavingsAccountData savingsAccount, final LocalDate date,
+            final Money amount, final Map<TaxComponentData, BigDecimal> taxDetails) {
+        final LocalDate submittedOnDate = DateUtils.getBusinessLocalDate();
+        SavingsAccountTransactionType savingsAccountTransactionType = SavingsAccountTransactionType.WITHHOLD_TAX;
+        SavingsAccountTransactionEnumData transactionType = new SavingsAccountTransactionEnumData(
+                savingsAccountTransactionType.getValue().longValue(), savingsAccountTransactionType.getCode(),
+                savingsAccountTransactionType.getValue().toString());
+        SavingsAccountTransactionData accountTransaction = createImport(transactionType, savingsAccount.getId(), date, amount.getAmount(),
+                submittedOnDate, false);
+        accountTransaction.addTaxDetails(taxDetails);
+        return accountTransaction;
     }
 
     public boolean isInterestPostingAndNotReversed() {
@@ -150,15 +321,15 @@ public final class SavingsAccountTransactionData implements Serializable {
     }
 
     public boolean isCredit() {
-        return transactionType.getTransactionTypeEnum().isCredit() && isNotReversed() && !isReversalTransaction();
+        return transactionType.isCredit() && isNotReversed() && !isReversalTransaction();
     }
 
     public boolean isDebit() {
-        return transactionType.getTransactionTypeEnum().isDebit() && isNotReversed() && !isReversalTransaction();
+        return transactionType.isDebit() && isNotReversed() && !isReversalTransaction();
     }
 
     public boolean isWithdrawalFeeAndNotReversed() {
-        return this.transactionType.isFeeDeduction() && isNotReversed();
+        return transactionType.isFeeDeduction() && isNotReversed();
     }
 
     public boolean isPayCharge() {
@@ -298,55 +469,6 @@ public final class SavingsAccountTransactionData implements Serializable {
         return this.transactionType.isDeposit();
     }
 
-    public static SavingsAccountTransactionData copyTransaction(SavingsAccountTransactionData accountTransaction) {
-        return new SavingsAccountTransactionData(accountTransaction.getSavingsAccountId(), null, accountTransaction.getPaymentDetailData(),
-                accountTransaction.getTransactionType(), accountTransaction.getTransactionDate(), accountTransaction.getSubmittedOnDate(),
-                accountTransaction.getAmount(), accountTransaction.isReversed(), null, accountTransaction.isManualTransaction(),
-                accountTransaction.lienTransaction);
-    }
-
-    private SavingsAccountTransactionData(final Long savingsId, final Long officeId, final PaymentDetailData paymentDetailData,
-            final SavingsAccountTransactionEnumData savingsAccountTransactionType, final LocalDate transactionDate,
-            final LocalDate submittedOnDate, final BigDecimal amount, final boolean isReversed, final Long userId,
-            final boolean isManualTransaction, final Boolean lienTransaction) {
-        this.savingsAccountId = savingsId;
-        this.paymentDetailData = paymentDetailData;
-        this.transactionType = savingsAccountTransactionType;
-        this.entryType = transactionType == null ? null : transactionType.getTransactionTypeEnum().getEntryType();
-        this.transactionDate = transactionDate;
-        this.submittedOnDate = submittedOnDate;
-        this.amount = amount;
-        this.isManualTransaction = isManualTransaction;
-        this.lienTransaction = lienTransaction;
-        this.id = null;
-        this.accountId = null;
-        this.accountNo = null;
-        this.date = null;
-        this.currency = null;
-        this.outstandingChargeAmount = null;
-        this.runningBalance = null;
-        this.reversed = isReversed;
-        this.transfer = null;
-        this.interestedPostedAsOn = false;
-        this.rowIndex = null;
-        this.dateFormat = null;
-        this.locale = null;
-        this.transactionAmount = null;
-        this.paymentTypeId = null;
-        this.accountNumber = null;
-        this.checkNumber = null;
-        this.routingCode = null;
-        this.receiptNumber = null;
-        this.bankNumber = null;
-        this.paymentTypeOptions = null;
-        this.submittedByUsername = null;
-        this.note = null;
-        this.isReversal = null;
-        this.originalTransactionId = null;
-        this.releaseTransactionId = null;
-        this.reasonForBlock = null;
-    }
-
     public boolean isChargeTransaction() {
         return this.transactionType.isChargeTransaction();
     }
@@ -432,27 +554,11 @@ public final class SavingsAccountTransactionData implements Serializable {
         return Money.of(currency, this.amount);
     }
 
-    public static SavingsAccountTransactionData withHoldTax(final SavingsAccountData savingsAccount, final LocalDate date,
-            final Money amount, final Map<TaxComponentData, BigDecimal> taxDetails) {
-        final boolean isReversed = false;
-        final boolean isManualTransaction = false;
-        final Boolean lienTransaction = false;
-        final LocalDate submittedOnDate = DateUtils.getBusinessLocalDate();
-        SavingsAccountTransactionType savingsAccountTransactionType = SavingsAccountTransactionType.WITHHOLD_TAX;
-        SavingsAccountTransactionEnumData transactionType = new SavingsAccountTransactionEnumData(
-                savingsAccountTransactionType.getValue().longValue(), savingsAccountTransactionType.getCode(),
-                savingsAccountTransactionType.getValue().toString());
-        SavingsAccountTransactionData accountTransaction = new SavingsAccountTransactionData(amount.getAmount(), date,
-                savingsAccount.getId(), transactionType, isReversed, null, isManualTransaction, lienTransaction, submittedOnDate);
-        updateTaxDetails(taxDetails, accountTransaction);
-        return accountTransaction;
-    }
-
-    public static void updateTaxDetails(final Map<TaxComponentData, BigDecimal> taxDetails,
-            final SavingsAccountTransactionData accountTransaction) {
+    public void addTaxDetails(final Map<TaxComponentData, BigDecimal> taxDetails) {
         if (taxDetails != null) {
+            List<TaxDetailsData> thisTaxDetails = getTaxDetails();
             for (Map.Entry<TaxComponentData, BigDecimal> mapEntry : taxDetails.entrySet()) {
-                accountTransaction.getTaxDetails().add(new TaxDetailsData(mapEntry.getKey(), mapEntry.getValue()));
+                thisTaxDetails.add(new TaxDetailsData(mapEntry.getKey(), mapEntry.getValue()));
             }
         }
     }
@@ -510,89 +616,6 @@ public final class SavingsAccountTransactionData implements Serializable {
         return thisTransactionData;
     }
 
-    private SavingsAccountTransactionData(BigDecimal transactionAmount, LocalDate transactionDate, Long savingsAccountId,
-            SavingsAccountTransactionEnumData transactionType, boolean isReversed, String locale, boolean isManualTransaction,
-            final Boolean lienTransaction, final LocalDate submittedOnDate) {
-        this.id = null;
-        this.transactionType = transactionType;
-        this.entryType = transactionType == null ? null : transactionType.getTransactionTypeEnum().getEntryType();
-        this.accountId = null;
-        this.accountNo = null;
-        this.date = transactionDate;
-        this.currency = null;
-        this.paymentDetailData = null;
-        this.amount = transactionAmount;
-        this.outstandingChargeAmount = null;
-        this.runningBalance = null;
-        this.reversed = isReversed;
-        this.transfer = null;
-        this.submittedOnDate = submittedOnDate;
-        this.interestedPostedAsOn = false;
-        this.rowIndex = null;
-        this.savingsAccountId = savingsAccountId;
-        this.dateFormat = null;
-        this.locale = locale;
-        this.transactionDate = transactionDate;
-        this.transactionAmount = transactionAmount;
-        this.paymentTypeId = null;
-        this.accountNumber = null;
-        this.checkNumber = null;
-        this.routingCode = null;
-        this.receiptNumber = null;
-        this.bankNumber = null;
-        this.paymentTypeOptions = null;
-        this.submittedByUsername = null;
-        this.note = null;
-        this.isManualTransaction = isManualTransaction;
-        this.isReversal = null;
-        this.originalTransactionId = null;
-        this.lienTransaction = lienTransaction;
-        this.releaseTransactionId = null;
-        this.reasonForBlock = null;
-    }
-
-    private SavingsAccountTransactionData(BigDecimal transactionAmount, LocalDate transactionDate, Long paymentTypeId, String accountNumber,
-            String checkNumber, String routingCode, String receiptNumber, String bankNumber, Long savingsAccountId,
-            SavingsAccountTransactionEnumData transactionType, Integer rowIndex, String locale, String dateFormat,
-            final Boolean lienTransaction) {
-        this.id = null;
-        this.transactionType = transactionType;
-        this.entryType = transactionType == null ? null : transactionType.getTransactionTypeEnum().getEntryType();
-        this.accountId = null;
-        this.accountNo = null;
-        this.date = null;
-        this.currency = null;
-        this.paymentDetailData = null;
-        this.amount = null;
-        this.outstandingChargeAmount = null;
-        this.runningBalance = null;
-        this.reversed = false;
-        this.transfer = null;
-        this.submittedOnDate = null;
-        this.interestedPostedAsOn = false;
-        this.rowIndex = rowIndex;
-        this.savingsAccountId = savingsAccountId;
-        this.dateFormat = dateFormat;
-        this.locale = locale;
-        this.transactionDate = transactionDate;
-        this.transactionAmount = transactionAmount;
-        this.paymentTypeId = paymentTypeId;
-        this.accountNumber = accountNumber;
-        this.checkNumber = checkNumber;
-        this.routingCode = routingCode;
-        this.receiptNumber = receiptNumber;
-        this.bankNumber = bankNumber;
-        this.paymentTypeOptions = null;
-        this.submittedByUsername = null;
-        this.note = null;
-        this.isManualTransaction = false;
-        this.isReversal = null;
-        this.originalTransactionId = null;
-        this.lienTransaction = lienTransaction;
-        this.releaseTransactionId = null;
-        this.reasonForBlock = null;
-    }
-
     public boolean isWithdrawal() {
         return this.transactionType.isWithdrawal();
     }
@@ -614,195 +637,6 @@ public final class SavingsAccountTransactionData implements Serializable {
         return balanceInterval.containsPortionOf(periodInterval);
     }
 
-    public static SavingsAccountTransactionData create(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 LocalDate submittedOnDate, final boolean interestedPostedAsOn, final BigDecimal cumulativeBalance,
-            final LocalDate balanceEndDate) {
-        final Collection<PaymentTypeData> paymentTypeOptions = null;
-        return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency,
-                amount, outstandingChargeAmount, runningBalance, reversed, submittedOnDate, paymentTypeOptions, interestedPostedAsOn,
-                cumulativeBalance, balanceEndDate, false);
-    }
-
-    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 LocalDate submittedOnDate, final Collection<PaymentTypeData> paymentTypeOptions,
-            final boolean interestedPostedAsOn, final BigDecimal cumulativeBalance, final LocalDate balanceEndDate,
-            final Boolean lienTransaction) {
-
-        this(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency, amount, outstandingChargeAmount,
-                runningBalance, reversed, paymentTypeOptions, submittedOnDate, interestedPostedAsOn, cumulativeBalance, balanceEndDate,
-                lienTransaction);
-    }
-
-    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 Collection<PaymentTypeData> paymentTypeOptions, final LocalDate submittedOnDate,
-            final boolean interestedPostedAsOn, final BigDecimal cumulativeBalance, final LocalDate balanceEndDate,
-            final Boolean lienTransaction) {
-        this.id = id;
-        this.transactionDate = date;
-        this.transactionType = transactionType;
-        this.entryType = transactionType == null ? null : transactionType.getTransactionTypeEnum().getEntryType();
-        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.paymentTypeOptions = paymentTypeOptions;
-        this.submittedOnDate = submittedOnDate;
-        this.interestedPostedAsOn = interestedPostedAsOn;
-        this.cumulativeBalance = cumulativeBalance;
-        this.transfer = null;
-        this.submittedByUsername = null;
-        this.note = null;
-        this.balanceEndDate = balanceEndDate;
-        this.isManualTransaction = false;
-        this.isReversal = null;
-        this.originalTransactionId = null;
-        this.lienTransaction = lienTransaction;
-        this.releaseTransactionId = null;
-        this.reasonForBlock = null;
-    }
-
-    public static SavingsAccountTransactionData create(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 boolean interestedPostedAsOn,
-            final String submittedByUsername, final String note, final LocalDate submittedOnDate) {
-        final Collection<PaymentTypeData> paymentTypeOptions = null;
-        return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency,
-                amount, outstandingChargeAmount, runningBalance, reversed, transfer, paymentTypeOptions, interestedPostedAsOn,
-                submittedByUsername, note, false, submittedOnDate);
-    }
-
-    public static SavingsAccountTransactionData create(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 LocalDate submittedOnDate, final boolean interestedPostedAsOn,
-            final String submittedByUsername, final String note, final Boolean isReversal, final Long originalTransactionId,
-            final Boolean lienTransaction, 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, lienTransaction, releaseTransactionId,
-                reasonForBlock);
-    }
-
-    public static SavingsAccountTransactionData create(final Long id) {
-        final Collection<PaymentTypeData> paymentTypeOptions = null;
-        return new SavingsAccountTransactionData(id, null, null, null, null, null, null, null, null, null, false, null, paymentTypeOptions,
-                null, false, null, null, null, null, false, null, null);
-    }
-
-    public static SavingsAccountTransactionData template(final Long savingsId, final String savingsAccountNo,
-            final LocalDate defaultLocalDate, final CurrencyData currency) {
-        final Long id = null;
-        final SavingsAccountTransactionEnumData transactionType = null;
-        final BigDecimal amount = null;
-        final BigDecimal outstandingChargeAmount = null;
-        final BigDecimal runningBalance = null;
-        final boolean reversed = false;
-        final PaymentDetailData paymentDetailData = null;
-        final Collection<CodeValueData> paymentTypeOptions = null;
-        final boolean interestedPostedAsOn = false;
-        final String submittedByUsername = null;
-        final String note = null;
-        final Boolean lienTransaction = false;
-        return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, defaultLocalDate,
-                currency, amount, outstandingChargeAmount, runningBalance, reversed, null, null, interestedPostedAsOn, submittedByUsername,
-                note, lienTransaction, defaultLocalDate);
-    }
-
-    public static SavingsAccountTransactionData templateOnTop(final SavingsAccountTransactionData savingsAccountTransactionData,
-            final Collection<PaymentTypeData> paymentTypeOptions) {
-        return new SavingsAccountTransactionData(savingsAccountTransactionData.getId(), savingsAccountTransactionData.getTransactionType(),
-                savingsAccountTransactionData.getPaymentDetailData(), savingsAccountTransactionData.getAccountId(),
-                savingsAccountTransactionData.getAccountNo(), savingsAccountTransactionData.getDate(),
-                savingsAccountTransactionData.getCurrency(), savingsAccountTransactionData.getAmount(),
-                savingsAccountTransactionData.getOutstandingChargeAmount(), savingsAccountTransactionData.getRunningBalance(),
-                savingsAccountTransactionData.isReversed(), savingsAccountTransactionData.getTransfer(), paymentTypeOptions,
-                savingsAccountTransactionData.isInterestedPostedAsOn(), savingsAccountTransactionData.getSubmittedByUsername(),
-                savingsAccountTransactionData.getNote(), savingsAccountTransactionData.getLienTransaction(),
-                savingsAccountTransactionData.getSubmittedOnDate());
-    }
-
-    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 boolean interestedPostedAsOn, final String submittedByUsername, final String note, final Boolean lienTransaction,
-            final LocalDate submittedOnDate) {
-
-        this(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency, amount, outstandingChargeAmount,
-                runningBalance, reversed, transfer, paymentTypeOptions, submittedOnDate, interestedPostedAsOn, submittedByUsername, note,
-                null, null, lienTransaction, null, 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, final Boolean lienTransaction, final Long releaseTransactionId,
-            final String reasonForBlock) {
-        this.id = id;
-        this.transactionType = transactionType;
-        TransactionEntryType entryType = null;
-        if (transactionType != null) {
-            entryType = transactionType.getTransactionTypeEnum().getEntryType();
-            entryType = Boolean.TRUE.equals(isReversal) ? entryType.getReversal() : entryType;
-        }
-        this.entryType = entryType;
-        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;
-        this.submittedOnDate = submittedOnDate;
-
-        this.interestedPostedAsOn = interestedPostedAsOn;
-        this.submittedByUsername = submittedByUsername;
-        this.note = note;
-        this.isManualTransaction = false;
-        this.isReversal = isReversal;
-        this.originalTransactionId = originalTransactionId;
-        this.lienTransaction = lienTransaction;
-        this.releaseTransactionId = releaseTransactionId;
-        this.reasonForBlock = reasonForBlock;
-    }
-
-    public static SavingsAccountTransactionData withWithDrawalTransactionDetails(
-            final SavingsAccountTransactionData savingsAccountTransactionData) {
-
-        final LocalDate currentDate = DateUtils.getBusinessLocalDate();
-        final SavingsAccountTransactionEnumData transactionType = SavingsEnumerations
-                .transactionType(SavingsAccountTransactionType.WITHDRAWAL.getValue());
-
-        return new SavingsAccountTransactionData(savingsAccountTransactionData.getId(), transactionType,
-                savingsAccountTransactionData.getPaymentDetailData(), savingsAccountTransactionData.getAccountId(),
-                savingsAccountTransactionData.getAccountNo(), currentDate, savingsAccountTransactionData.getCurrency(),
-                savingsAccountTransactionData.getAmount(), savingsAccountTransactionData.getOutstandingChargeAmount(),
-                savingsAccountTransactionData.getRunningBalance(), savingsAccountTransactionData.isReversed(),
-                savingsAccountTransactionData.getTransfer(), savingsAccountTransactionData.getPaymentTypeOptions(),
-                savingsAccountTransactionData.isInterestedPostedAsOn(), savingsAccountTransactionData.getSubmittedByUsername(),
-                savingsAccountTransactionData.getNote(), savingsAccountTransactionData.getLienTransaction(),
-                savingsAccountTransactionData.getSubmittedOnDate());
-    }
-
     public void setId(final Long id) {
         this.id = id;
         this.modifiedId = id;
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionEnumData.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionEnumData.java
index c9814a960..60401d5b2 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionEnumData.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionEnumData.java
@@ -20,6 +20,7 @@ package org.apache.fineract.portfolio.savings.data;
 
 import java.io.Serializable;
 import lombok.Getter;
+import org.apache.fineract.portfolio.TransactionEntryType;
 import org.apache.fineract.portfolio.savings.SavingsAccountTransactionType;
 
 /**
@@ -43,7 +44,7 @@ public class SavingsAccountTransactionEnumData implements Serializable {
     private final boolean rejectTransfer;
     private final boolean overdraftInterest;
     private final boolean writtenoff;
-    private final boolean overdraftFee = true;
+    private final boolean overdraftFee;
     private final boolean withholdTax;
     private final boolean escheat;
     private final boolean amountHold;
@@ -53,23 +54,25 @@ public class SavingsAccountTransactionEnumData implements Serializable {
         this.id = id;
         this.code = code;
         this.value = value;
-        this.deposit = Long.valueOf(SavingsAccountTransactionType.DEPOSIT.getValue()).equals(this.id);
-        this.dividendPayout = Long.valueOf(SavingsAccountTransactionType.DIVIDEND_PAYOUT.getValue()).equals(this.id);
-        this.withdrawal = Long.valueOf(SavingsAccountTransactionType.WITHDRAWAL.getValue()).equals(this.id);
-        this.interestPosting = Long.valueOf(SavingsAccountTransactionType.INTEREST_POSTING.getValue()).equals(this.id);
-        this.feeDeduction = Long.valueOf(SavingsAccountTransactionType.ANNUAL_FEE.getValue()).equals(this.id)
-                || Long.valueOf(SavingsAccountTransactionType.WITHDRAWAL_FEE.getValue()).equals(this.id)
-                || Long.valueOf(SavingsAccountTransactionType.PAY_CHARGE.getValue()).equals(this.id);
-        this.initiateTransfer = Long.valueOf(SavingsAccountTransactionType.INITIATE_TRANSFER.getValue()).equals(this.id);
-        this.approveTransfer = Long.valueOf(SavingsAccountTransactionType.APPROVE_TRANSFER.getValue()).equals(this.id);
-        this.withdrawTransfer = Long.valueOf(SavingsAccountTransactionType.WITHDRAW_TRANSFER.getValue()).equals(this.id);
-        this.rejectTransfer = Long.valueOf(SavingsAccountTransactionType.REJECT_TRANSFER.getValue()).equals(this.id);
-        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.amountHold = Long.valueOf(SavingsAccountTransactionType.AMOUNT_HOLD.getValue()).equals(this.id);
-        this.amountRelease = Long.valueOf(SavingsAccountTransactionType.AMOUNT_RELEASE.getValue()).equals(this.id);
+        SavingsAccountTransactionType transactionType = id == null ? null : SavingsAccountTransactionType.fromInt(id.intValue());
+        this.deposit = transactionType == SavingsAccountTransactionType.DEPOSIT;
+        this.dividendPayout = transactionType == SavingsAccountTransactionType.DIVIDEND_PAYOUT;
+        this.withdrawal = transactionType == SavingsAccountTransactionType.WITHDRAWAL;
+        this.interestPosting = transactionType == SavingsAccountTransactionType.INTEREST_POSTING;
+        this.feeDeduction = transactionType == SavingsAccountTransactionType.ANNUAL_FEE
+                || transactionType == SavingsAccountTransactionType.WITHDRAWAL_FEE
+                || transactionType == SavingsAccountTransactionType.PAY_CHARGE;
+        this.initiateTransfer = transactionType == SavingsAccountTransactionType.INITIATE_TRANSFER;
+        this.approveTransfer = transactionType == SavingsAccountTransactionType.APPROVE_TRANSFER;
+        this.withdrawTransfer = transactionType == SavingsAccountTransactionType.WITHDRAW_TRANSFER;
+        this.rejectTransfer = transactionType == SavingsAccountTransactionType.REJECT_TRANSFER;
+        this.writtenoff = transactionType == SavingsAccountTransactionType.WRITTEN_OFF;
+        this.overdraftFee = false;
+        this.overdraftInterest = transactionType == SavingsAccountTransactionType.OVERDRAFT_INTEREST;
+        this.withholdTax = transactionType == SavingsAccountTransactionType.WITHHOLD_TAX;
+        this.escheat = transactionType == SavingsAccountTransactionType.ESCHEAT;
+        this.amountHold = transactionType == SavingsAccountTransactionType.AMOUNT_HOLD;
+        this.amountRelease = transactionType == SavingsAccountTransactionType.AMOUNT_RELEASE;
     }
 
     public boolean isIncomeFromInterest() {
@@ -85,7 +88,7 @@ public class SavingsAccountTransactionEnumData implements Serializable {
     }
 
     public boolean isChargeTransaction() {
-        return isPayCharge() || isWithdrawalFee() || isAnnualFee();
+        return feeDeduction;
     }
 
     public boolean isAnnualFee() {
@@ -100,7 +103,22 @@ public class SavingsAccountTransactionEnumData implements Serializable {
         return Long.valueOf(SavingsAccountTransactionType.WITHDRAWAL_FEE.getValue()).equals(this.id);
     }
 
+    public boolean isCredit() {
+        SavingsAccountTransactionType transactionType = getTransactionTypeEnum();
+        return transactionType != null && transactionType.isCredit();
+    }
+
+    public boolean isDebit() {
+        SavingsAccountTransactionType transactionType = getTransactionTypeEnum();
+        return transactionType != null && transactionType.isDebit();
+    }
+
+    public TransactionEntryType getEntryType() {
+        SavingsAccountTransactionType transactionType = getTransactionTypeEnum();
+        return transactionType == null ? null : transactionType.getEntryType();
+    }
+
     public SavingsAccountTransactionType getTransactionTypeEnum() {
-        return SavingsAccountTransactionType.fromInt(id.intValue());
+        return id == null ? null : SavingsAccountTransactionType.fromInt(id.intValue());
     }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java
index 3ba3de47e..ccf0d5f34 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java
@@ -204,7 +204,7 @@ public class SavingsSchedularInterestPoster {
                             savingsAccountTransactionData.isReversed(), savingsAccountTransactionData.getTransactionType().getId(),
                             savingsAccountTransactionData.getTransactionDate(), savingsAccountTransactionData.getAmount(), balanceEndDate,
                             savingsAccountTransactionData.getBalanceNumberOfDays(), savingsAccountTransactionData.getRunningBalance(),
-                            savingsAccountTransactionData.getCumulativeBalance(), currentDate, Integer.valueOf(1),
+                            savingsAccountTransactionData.getCumulativeBalance(), currentDate, 1,
                             savingsAccountTransactionData.isManualTransaction(), savingsAccountTransactionData.getRefNo(),
                             savingsAccountTransactionData.isReversalTransaction(), savingsAccountTransactionData.getOverdraftAmount(),
                             DateUtils.getBusinessLocalDate() });
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 55a6dcf9b..8923bcefe 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
@@ -3162,7 +3162,56 @@ public class ClientSavingsIntegrationTest {
 
         assertEquals("error.msg.savingsaccount.transaction.insufficient.account.balance",
                 error.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
+    }
+
+    @Test
+    public void testSavingsAccountDepositAfterNegativeHoldAmount() {
+        this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
+
+        final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
+        ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
+
+        final Integer savingsProductID = createSavingsProduct(this.requestSpec, this.responseSpec, "0", null, false, true, false);
+        Assertions.assertNotNull(savingsProductID);
+
+        final Integer savingsId = this.savingsAccountHelper.applyForSavingsApplication(clientID, savingsProductID, ACCOUNT_TYPE_INDIVIDUAL);
+        this.savingsAccountHelper.approveSavings(savingsId);
+        HashMap savingsStatusHashMap = this.savingsAccountHelper.activateSavings(savingsId);
+        SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
 
+        float balance = 0F;
+        float transactionAmount = 100F;
+        Integer depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsId,
+                String.valueOf(transactionAmount), SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
+        Assertions.assertNotNull(depositTransactionId);
+        balance = balance + transactionAmount;
+        HashMap summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
+        assertEquals(balance, summary.get("availableBalance"), "Verifying Balance after deposit");
+        Integer withdrawalTransactionId = (Integer) this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId,
+                String.valueOf(transactionAmount), SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
+        Assertions.assertNotNull(withdrawalTransactionId);
+        balance = balance - transactionAmount;
+        summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
+        assertEquals(balance, summary.get("availableBalance"), "Verifying Balance after withdrawal");
+
+        float holdAmount = 50F;
+        Integer holdTransactionId = (Integer) this.savingsAccountHelper.holdAmountInSavingsAccount(savingsId, String.valueOf(holdAmount),
+                false, SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
+        Assertions.assertNotNull(holdTransactionId);
+        balance = balance - holdAmount;
+        summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
+        assertEquals(balance, summary.get("availableBalance"), "Verifying Balance after hold amount");
+        this.savingsAccountHelper.releaseAmount(savingsId, holdTransactionId);
+        balance = balance + holdAmount;
+        summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
+        assertEquals(balance, summary.get("availableBalance"), "Verifying Balance after release amount");
+
+        depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsId, String.valueOf(transactionAmount),
+                SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
+        Assertions.assertNotNull(depositTransactionId);
+        balance = balance + transactionAmount;
+        summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
+        assertEquals(balance, summary.get("availableBalance"), "Verifying Balance after hold-release-deposit");
     }
 
     private Integer createSavingsAccountDailyPostingOverdraft(final Integer clientID, final String startDate) {