@Transactional
  @Override
  public SavingsAccountTransaction handleRDDeposit(
      final RecurringDepositAccount account,
      final DateTimeFormatter fmt,
      final LocalDate transactionDate,
      final BigDecimal transactionAmount,
      final PaymentDetail paymentDetail,
      final boolean isRegularTransaction) {

    final boolean isSavingsInterestPostingAtCurrentPeriodEnd =
        this.configurationDomainService.isSavingsInterestPostingAtCurrentPeriodEnd();
    final Integer financialYearBeginningMonth =
        this.configurationDomainService.retrieveFinancialYearBeginningMonth();

    boolean isAccountTransfer = false;
    final boolean isPreMatureClosure = false;
    final MathContext mc = MathContext.DECIMAL64;
    final SavingsAccountTransaction deposit =
        this.savingsAccountDomainService.handleDeposit(
            account,
            fmt,
            transactionDate,
            transactionAmount,
            paymentDetail,
            isAccountTransfer,
            isRegularTransaction);

    account.handleScheduleInstallments(deposit);
    account.updateMaturityDateAndAmount(
        mc,
        isPreMatureClosure,
        isSavingsInterestPostingAtCurrentPeriodEnd,
        financialYearBeginningMonth);
    account.updateOverduePayments(DateUtils.getLocalDateOfTenant());
    return deposit;
  }
  @Transactional
  @Override
  public Long handleRDAccountPreMatureClosure(
      final RecurringDepositAccount account,
      final PaymentDetail paymentDetail,
      final AppUser user,
      final JsonCommand command,
      final LocalDate tenantsTodayDate,
      final Map<String, Object> changes) {

    final boolean isSavingsInterestPostingAtCurrentPeriodEnd =
        this.configurationDomainService.isSavingsInterestPostingAtCurrentPeriodEnd();
    final Integer financialYearBeginningMonth =
        this.configurationDomainService.retrieveFinancialYearBeginningMonth();

    boolean isAccountTransfer = false;
    final boolean isPreMatureClosure = true;
    boolean isRegularTransaction = false;
    final Set<Long> existingTransactionIds = new HashSet<>();
    final Set<Long> existingReversedTransactionIds = new HashSet<>();
    updateExistingTransactionsDetails(
        account, existingTransactionIds, existingReversedTransactionIds);

    final LocalDate closedDate =
        command.localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName);
    final Locale locale = command.extractLocale();
    final DateTimeFormatter fmt =
        DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
    Long savingsTransactionId = null;
    // post interest
    account.postPreMaturityInterest(
        closedDate,
        isPreMatureClosure,
        isSavingsInterestPostingAtCurrentPeriodEnd,
        financialYearBeginningMonth);

    final Integer closureTypeValue =
        command.integerValueOfParameterNamed(DepositsApiConstants.onAccountClosureIdParamName);
    DepositAccountOnClosureType closureType = DepositAccountOnClosureType.fromInt(closureTypeValue);

    if (closureType.isTransferToSavings()) {
      final boolean isExceptionForBalanceCheck = false;
      final Long toSavingsId = command.longValueOfParameterNamed(toSavingsAccountIdParamName);
      final String transferDescription =
          command.stringValueOfParameterNamed(transferDescriptionParamName);
      final SavingsAccount toSavingsAccount =
          this.depositAccountAssembler.assembleFrom(
              toSavingsId, DepositAccountType.SAVINGS_DEPOSIT);
      final AccountTransferDTO accountTransferDTO =
          new AccountTransferDTO(
              closedDate,
              account.getAccountBalance(),
              PortfolioAccountType.SAVINGS,
              PortfolioAccountType.SAVINGS,
              null,
              null,
              transferDescription,
              locale,
              fmt,
              null,
              null,
              null,
              null,
              null,
              AccountTransferType.ACCOUNT_TRANSFER.getValue(),
              null,
              null,
              null,
              null,
              toSavingsAccount,
              account,
              isRegularTransaction,
              isExceptionForBalanceCheck);
      this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
    } else {
      final SavingsAccountTransaction withdrawal =
          this.handleWithdrawal(
              account,
              fmt,
              closedDate,
              account.getAccountBalance(),
              paymentDetail,
              false,
              isRegularTransaction);
      savingsTransactionId = withdrawal.getId();
    }

    /** * Update account transactionIds for post journal entries. */
    updateExistingTransactionsDetails(
        account, existingTransactionIds, existingReversedTransactionIds);
    account.prematureClosure(user, command, tenantsTodayDate, changes);
    this.savingsAccountRepository.save(account);
    postJournalEntries(
        account, existingTransactionIds, existingReversedTransactionIds, isAccountTransfer);
    return savingsTransactionId;
  }
  @Transactional
  @Override
  public Long handleRDAccountClosure(
      final RecurringDepositAccount account,
      final PaymentDetail paymentDetail,
      final AppUser user,
      final JsonCommand command,
      final LocalDate tenantsTodayDate,
      final Map<String, Object> changes) {

    final boolean isSavingsInterestPostingAtCurrentPeriodEnd =
        this.configurationDomainService.isSavingsInterestPostingAtCurrentPeriodEnd();
    final Integer financialYearBeginningMonth =
        this.configurationDomainService.retrieveFinancialYearBeginningMonth();

    boolean isRegularTransaction = false;
    boolean isAccountTransfer = false;
    final boolean isPreMatureClosure = false;
    final Set<Long> existingTransactionIds = new HashSet<>();
    final Set<Long> existingReversedTransactionIds = new HashSet<>();
    updateExistingTransactionsDetails(
        account, existingTransactionIds, existingReversedTransactionIds);

    final MathContext mc = MathContext.DECIMAL64;
    final Locale locale = command.extractLocale();
    final DateTimeFormatter fmt =
        DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
    final LocalDate closedDate =
        command.localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName);
    Long savingsTransactionId = null;
    account.postMaturityInterest(
        isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, closedDate);
    final BigDecimal transactionAmount = account.getAccountBalance();
    final Integer onAccountClosureId =
        command.integerValueOfParameterNamed(onAccountClosureIdParamName);
    final DepositAccountOnClosureType onClosureType =
        DepositAccountOnClosureType.fromInt(onAccountClosureId);
    if (onClosureType.isReinvest()) {
      RecurringDepositAccount reinvestedDeposit = account.reInvest(transactionAmount);
      depositAccountAssembler.assignSavingAccountHelpers(reinvestedDeposit);
      reinvestedDeposit.updateMaturityDateAndAmount(
          mc,
          isPreMatureClosure,
          isSavingsInterestPostingAtCurrentPeriodEnd,
          financialYearBeginningMonth);
      reinvestedDeposit.processAccountUponActivation(fmt, user);
      reinvestedDeposit.updateMaturityDateAndAmount(
          mc,
          isPreMatureClosure,
          isSavingsInterestPostingAtCurrentPeriodEnd,
          financialYearBeginningMonth);
      this.savingsAccountRepository.save(reinvestedDeposit);

      Money amountForDeposit = reinvestedDeposit.activateWithBalance();
      if (amountForDeposit.isGreaterThanZero()) {
        handleRDDeposit(
            reinvestedDeposit,
            fmt,
            reinvestedDeposit.getActivationLocalDate(),
            amountForDeposit.getAmount(),
            paymentDetail,
            isRegularTransaction);
      }
      reinvestedDeposit.updateMaturityDateAndAmount(
          mc,
          isPreMatureClosure,
          isSavingsInterestPostingAtCurrentPeriodEnd,
          financialYearBeginningMonth);
      this.savingsAccountRepository.save(reinvestedDeposit);
      autoGenerateAccountNumber(reinvestedDeposit);

      final SavingsAccountTransaction withdrawal =
          this.handleWithdrawal(
              account,
              fmt,
              closedDate,
              account.getAccountBalance(),
              paymentDetail,
              false,
              isRegularTransaction);
      savingsTransactionId = withdrawal.getId();

    } else if (onClosureType.isTransferToSavings()) {
      final Long toSavingsId = command.longValueOfParameterNamed(toSavingsAccountIdParamName);
      final String transferDescription =
          command.stringValueOfParameterNamed(transferDescriptionParamName);
      final SavingsAccount toSavingsAccount =
          this.depositAccountAssembler.assembleFrom(
              toSavingsId, DepositAccountType.SAVINGS_DEPOSIT);
      final boolean isExceptionForBalanceCheck = false;
      final AccountTransferDTO accountTransferDTO =
          new AccountTransferDTO(
              closedDate,
              transactionAmount,
              PortfolioAccountType.SAVINGS,
              PortfolioAccountType.SAVINGS,
              null,
              null,
              transferDescription,
              locale,
              fmt,
              null,
              null,
              null,
              null,
              null,
              AccountTransferType.ACCOUNT_TRANSFER.getValue(),
              null,
              null,
              null,
              null,
              toSavingsAccount,
              account,
              isRegularTransaction,
              isExceptionForBalanceCheck);
      this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
    } else {
      final SavingsAccountTransaction withdrawal =
          this.handleWithdrawal(
              account,
              fmt,
              closedDate,
              account.getAccountBalance(),
              paymentDetail,
              false,
              isRegularTransaction);
      savingsTransactionId = withdrawal.getId();
    }

    /** * Update account transactionIds for post journal entries. */
    updateExistingTransactionsDetails(
        account, existingTransactionIds, existingReversedTransactionIds);
    account.close(user, command, tenantsTodayDate, changes);

    this.savingsAccountRepository.save(account);

    postJournalEntries(
        account, existingTransactionIds, existingReversedTransactionIds, isAccountTransfer);

    return savingsTransactionId;
  }