@Override
  public Map<String, Object> fetchAccountMappingDetailsForLoanProduct(
      final Long loanProductId, final Integer accountingType) {

    final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);

    final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
    final String sql =
        "select "
            + rm.schema()
            + " and product_id = ? and payment_type is null and mapping.charge_id is null";

    final List<Map<String, Object>> listOfProductToGLAccountMaps =
        this.jdbcTemplate.query(
            sql, rm, new Object[] {PortfolioProductType.LOAN.getValue(), loanProductId});

    if (AccountingRuleType.CASH_BASED.getValue().equals(accountingType)) {

      for (final Map<String, Object> productToGLAccountMap : listOfProductToGLAccountMaps) {

        final Integer financialAccountType =
            (Integer) productToGLAccountMap.get("financialAccountType");
        final CASH_ACCOUNTS_FOR_LOAN glAccountForLoan =
            CASH_ACCOUNTS_FOR_LOAN.fromInt(financialAccountType);

        final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
        final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
        final String glCode = (String) productToGLAccountMap.get("glCode");
        final GLAccountData gLAccountData = new GLAccountData(glAccountId, glAccountName, glCode);

        if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.FUND_SOURCE.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.INCOME_FROM_FEES.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.INCOME_FROM_PENALTIES.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.INTEREST_ON_LOANS.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.LOAN_PORTFOLIO.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.TRANSFERS_SUSPENSE)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.TRANSFERS_SUSPENSE.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.LOSSES_WRITTEN_OFF.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.OVERPAYMENT)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.OVERPAYMENT.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_RECOVERY)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.INCOME_FROM_RECOVERY.getValue(), gLAccountData);
        }
      }
    } else if (AccountingRuleType.ACCRUAL_UPFRONT.getValue().equals(accountingType)
        || AccountingRuleType.ACCRUAL_PERIODIC.getValue().equals(accountingType)) {

      for (final Map<String, Object> productToGLAccountMap : listOfProductToGLAccountMaps) {
        final Integer financialAccountType =
            (Integer) productToGLAccountMap.get("financialAccountType");
        final ACCRUAL_ACCOUNTS_FOR_LOAN glAccountForLoan =
            ACCRUAL_ACCOUNTS_FOR_LOAN.fromInt(financialAccountType);

        final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
        final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
        final String glCode = (String) productToGLAccountMap.get("glCode");
        final GLAccountData gLAccountData = new GLAccountData(glAccountId, glAccountName, glCode);

        if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.FUND_SOURCE)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.FUND_SOURCE.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.INCOME_FROM_FEES.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.INCOME_FROM_PENALTIES.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.INTEREST_ON_LOANS.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.LOAN_PORTFOLIO.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.OVERPAYMENT)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.OVERPAYMENT.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.TRANSFERS_SUSPENSE)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.TRANSFERS_SUSPENSE.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.LOSSES_WRITTEN_OFF.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_RECEIVABLE)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.INTEREST_RECEIVABLE.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.FEES_RECEIVABLE)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.FEES_RECEIVABLE.getValue(), gLAccountData);
        } else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.PENALTIES_RECEIVABLE)) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.PENALTIES_RECEIVABLE.getValue(), gLAccountData);
        } else if ((glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_RECOVERY))) {
          accountMappingDetails.put(
              LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.INCOME_FROM_RECOVERY.getValue(), gLAccountData);
        }
      }
    }

    return accountMappingDetails;
  }
 private boolean isCashBasedAccounting(final Integer accountingRuleType) {
   return AccountingRuleType.CASH_BASED.getValue().equals(accountingRuleType);
 }
  @Override
  public Map<String, Object> fetchAccountMappingDetailsForSavingsProduct(
      final Long savingsProductId, final Integer accountingType) {
    final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);

    final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
    final String sql =
        "select "
            + rm.schema()
            + " and product_id = ? and payment_type is null and mapping.charge_id is null ";

    final List<Map<String, Object>> listOfProductToGLAccountMaps =
        this.jdbcTemplate.query(
            sql, rm, new Object[] {PortfolioProductType.SAVING.getValue(), savingsProductId});

    if (AccountingRuleType.CASH_BASED.getValue().equals(accountingType)) {

      for (final Map<String, Object> productToGLAccountMap : listOfProductToGLAccountMaps) {

        final Integer financialAccountType =
            (Integer) productToGLAccountMap.get("financialAccountType");
        final CASH_ACCOUNTS_FOR_SAVINGS glAccountForSavings =
            CASH_ACCOUNTS_FOR_SAVINGS.fromInt(financialAccountType);

        final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
        final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
        final String glCode = (String) productToGLAccountMap.get("glCode");
        final GLAccountData gLAccountData = new GLAccountData(glAccountId, glAccountName, glCode);

        if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_REFERENCE)) {
          accountMappingDetails.put(
              SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.SAVINGS_REFERENCE.getValue(), gLAccountData);
        } else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL)) {
          accountMappingDetails.put(
              SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.SAVINGS_CONTROL.getValue(), gLAccountData);
        } else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.INCOME_FROM_FEES)) {
          accountMappingDetails.put(
              SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.INCOME_FROM_FEES.getValue(), gLAccountData);
        } else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.INCOME_FROM_PENALTIES)) {
          accountMappingDetails.put(
              SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.INCOME_FROM_PENALTIES.getValue(),
              gLAccountData);
        } else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.TRANSFERS_SUSPENSE)) {
          accountMappingDetails.put(
              SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.TRANSFERS_SUSPENSE.getValue(), gLAccountData);
        } else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.INTEREST_ON_SAVINGS)) {
          accountMappingDetails.put(
              SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.INTEREST_ON_SAVINGS.getValue(), gLAccountData);
        } else if (glAccountForSavings.equals(
            CASH_ACCOUNTS_FOR_SAVINGS.OVERDRAFT_PORTFOLIO_CONTROL)) {
          accountMappingDetails.put(
              SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
              gLAccountData);
        } else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.LOSSES_WRITTEN_OFF)) {
          accountMappingDetails.put(
              SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.LOSSES_WRITTEN_OFF.getValue(), gLAccountData);
        } else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.INCOME_FROM_INTEREST)) {
          accountMappingDetails.put(
              SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.INCOME_FROM_INTEREST.getValue(),
              gLAccountData);
        }
      }
    }
    return accountMappingDetails;
  }