@Override
  public LoanProductData retrieveNewLoanProductDetails() {

    LoanProductData productData = new LoanProductData();

    productData.setAmortizationType(
        LoanEnumerations.amortizationType(AmortizationMethod.EQUAL_INSTALLMENTS));
    productData.setInterestType(LoanEnumerations.interestType(InterestMethod.DECLINING_BALANCE));
    productData.setRepaymentFrequencyType(
        LoanEnumerations.repaymentFrequencyType(PeriodFrequencyType.MONTHS));
    productData.setInterestRateFrequencyType(
        LoanEnumerations.interestRateFrequencyType(PeriodFrequencyType.MONTHS));
    productData.setInterestCalculationPeriodType(
        LoanEnumerations.interestCalculationPeriodType(
            InterestCalculationPeriodMethod.SAME_AS_REPAYMENT_PERIOD));

    populateProductDataWithDropdownOptions(productData);

    if (productData.getCurrencyOptions().size() >= 1) {
      CurrencyData currency = productData.getCurrencyOptions().get(0);
      MoneyData zero = MoneyData.zero(currency);
      productData.setPrincipal(zero);
      productData.setInArrearsTolerance(zero);
    }

    return productData;
  }
    @Override
    public LoanProductBorrowerCycleVariationData mapRow(
        final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
      final Long id = rs.getLong("id");
      final Integer cycleNumber = JdbcSupport.getInteger(rs, "cycleNumber");
      final Integer conditionType = JdbcSupport.getInteger(rs, "conditionType");
      final EnumOptionData conditionTypeData =
          LoanEnumerations.loanCycleValueConditionType(conditionType);
      final Integer paramType = JdbcSupport.getInteger(rs, "paramType");
      final EnumOptionData paramTypeData = LoanEnumerations.loanCycleParamType(paramType);
      final BigDecimal defaultValue = rs.getBigDecimal("defaultValue");
      final BigDecimal maxValue = rs.getBigDecimal("maxVal");
      final BigDecimal minValue = rs.getBigDecimal("minVal");

      final LoanProductBorrowerCycleVariationData borrowerCycleVariationData =
          new LoanProductBorrowerCycleVariationData(
              id, cycleNumber, paramTypeData, conditionTypeData, defaultValue, minValue, maxValue);
      return borrowerCycleVariationData;
    }
    @Override
    public LoanProductData mapRow(final ResultSet rs, final int rowNum) throws SQLException {

      Long id = rs.getLong("id");
      String name = rs.getString("name");
      String description = rs.getString("description");

      String currencyCode = rs.getString("currencyCode");
      Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");

      CurrencyData currencyData = findCurrencyByCode(currencyCode, allowedCurrencies);
      if (currencyData != null) {
        currencyData.setDecimalPlaces(currencyDigits);
      }

      BigDecimal principal = rs.getBigDecimal("principal");
      BigDecimal tolerance = rs.getBigDecimal("tolerance");

      MoneyData principalMoney = MoneyData.of(currencyData, principal);
      MoneyData toleranceMoney = MoneyData.of(currencyData, tolerance);

      Integer numberOfRepayments = JdbcSupport.getInteger(rs, "numberOfRepayments");
      Integer repaymentEvery = JdbcSupport.getInteger(rs, "repaidEvery");
      BigDecimal interestRatePerPeriod = rs.getBigDecimal("interestRatePerPeriod");
      BigDecimal annualInterestRate = rs.getBigDecimal("annualInterestRate");

      int repaymentFrequencyTypeId = JdbcSupport.getInteger(rs, "repaymentPeriodFrequency");
      EnumOptionData repaymentFrequencyType =
          LoanEnumerations.repaymentFrequencyType(repaymentFrequencyTypeId);

      int amortizationTypeId = JdbcSupport.getInteger(rs, "amortizationMethod");
      EnumOptionData amortizationType = LoanEnumerations.amortizationType(amortizationTypeId);

      int interestRateFrequencyTypeId = JdbcSupport.getInteger(rs, "interestRatePerPeriodFreq");
      EnumOptionData interestRateFrequencyType =
          LoanEnumerations.interestRateFrequencyType(interestRateFrequencyTypeId);

      int interestTypeId = JdbcSupport.getInteger(rs, "interestMethod");
      EnumOptionData interestType = LoanEnumerations.interestType(interestTypeId);

      int interestCalculationPeriodTypeId =
          JdbcSupport.getInteger(rs, "interestCalculationInPeriodMethod");
      EnumOptionData interestCalculationPeriodType =
          LoanEnumerations.interestCalculationPeriodType(interestCalculationPeriodTypeId);

      DateTime createdOn = JdbcSupport.getDateTime(rs, "createdon");
      DateTime lastModifedOn = JdbcSupport.getDateTime(rs, "modifiedon");

      return new LoanProductData(
          createdOn,
          lastModifedOn,
          id,
          name,
          description,
          principalMoney,
          toleranceMoney,
          numberOfRepayments,
          repaymentEvery,
          interestRatePerPeriod,
          annualInterestRate,
          repaymentFrequencyType,
          interestRateFrequencyType,
          amortizationType,
          interestType,
          interestCalculationPeriodType);
    }
    @Override
    public LoanProductData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum)
        throws SQLException {

      final Long id = JdbcSupport.getLong(rs, "id");
      final String name = rs.getString("name");
      final String shortName = rs.getString("shortName");
      final String description = rs.getString("description");
      final Long fundId = JdbcSupport.getLong(rs, "fundId");
      final String fundName = rs.getString("fundName");
      final Long transactionStrategyId = JdbcSupport.getLong(rs, "transactionStrategyId");
      final String transactionStrategyName = rs.getString("transactionStrategyName");

      final String currencyCode = rs.getString("currencyCode");
      final String currencyName = rs.getString("currencyName");
      final String currencyNameCode = rs.getString("currencyNameCode");
      final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
      final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
      final Integer inMultiplesOf = JdbcSupport.getInteger(rs, "inMultiplesOf");

      final CurrencyData currency =
          new CurrencyData(
              currencyCode,
              currencyName,
              currencyDigits,
              inMultiplesOf,
              currencyDisplaySymbol,
              currencyNameCode);

      final BigDecimal principal = rs.getBigDecimal("principal");
      final BigDecimal minPrincipal = rs.getBigDecimal("minPrincipal");
      final BigDecimal maxPrincipal = rs.getBigDecimal("maxPrincipal");
      final BigDecimal tolerance = rs.getBigDecimal("tolerance");

      final Integer numberOfRepayments = JdbcSupport.getInteger(rs, "numberOfRepayments");
      final Integer minNumberOfRepayments = JdbcSupport.getInteger(rs, "minNumberOfRepayments");
      final Integer maxNumberOfRepayments = JdbcSupport.getInteger(rs, "maxNumberOfRepayments");
      final Integer repaymentEvery = JdbcSupport.getInteger(rs, "repaidEvery");

      final Integer graceOnPrincipalPayment =
          JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnPrincipalPayment");
      final Integer graceOnInterestPayment =
          JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnInterestPayment");
      final Integer graceOnInterestCharged =
          JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnInterestCharged");
      final Integer graceOnArrearsAgeing =
          JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnArrearsAgeing");
      final Integer overdueDaysForNPA =
          JdbcSupport.getIntegerDefaultToNullIfZero(rs, "overdueDaysForNPA");
      final Integer minimumDaysBetweenDisbursalAndFirstRepayment =
          JdbcSupport.getInteger(rs, "minimumDaysBetweenDisbursalAndFirstRepayment");

      final Integer accountingRuleId = JdbcSupport.getInteger(rs, "accountingType");
      final EnumOptionData accountingRuleType =
          AccountingEnumerations.accountingRuleType(accountingRuleId);

      final BigDecimal interestRatePerPeriod = rs.getBigDecimal("interestRatePerPeriod");
      final BigDecimal minInterestRatePerPeriod = rs.getBigDecimal("minInterestRatePerPeriod");
      final BigDecimal maxInterestRatePerPeriod = rs.getBigDecimal("maxInterestRatePerPeriod");
      final BigDecimal annualInterestRate = rs.getBigDecimal("annualInterestRate");

      final int repaymentFrequencyTypeId = JdbcSupport.getInteger(rs, "repaymentPeriodFrequency");
      final EnumOptionData repaymentFrequencyType =
          LoanEnumerations.repaymentFrequencyType(repaymentFrequencyTypeId);

      final int amortizationTypeId = JdbcSupport.getInteger(rs, "amortizationMethod");
      final EnumOptionData amortizationType = LoanEnumerations.amortizationType(amortizationTypeId);

      final int interestRateFrequencyTypeId =
          JdbcSupport.getInteger(rs, "interestRatePerPeriodFreq");
      final EnumOptionData interestRateFrequencyType =
          LoanEnumerations.interestRateFrequencyType(interestRateFrequencyTypeId);

      final int interestTypeId = JdbcSupport.getInteger(rs, "interestMethod");
      final EnumOptionData interestType = LoanEnumerations.interestType(interestTypeId);

      final int interestCalculationPeriodTypeId =
          JdbcSupport.getInteger(rs, "interestCalculationInPeriodMethod");
      final EnumOptionData interestCalculationPeriodType =
          LoanEnumerations.interestCalculationPeriodType(interestCalculationPeriodTypeId);

      final boolean includeInBorrowerCycle = rs.getBoolean("includeInBorrowerCycle");
      final boolean useBorrowerCycle = rs.getBoolean("useBorrowerCycle");
      final LocalDate startDate = JdbcSupport.getLocalDate(rs, "startDate");
      final LocalDate closeDate = JdbcSupport.getLocalDate(rs, "closeDate");
      String status = "";
      if (closeDate != null && closeDate.isBefore(DateUtils.getLocalDateOfTenant())) {
        status = "loanProduct.inActive";
      } else {
        status = "loanProduct.active";
      }
      final String externalId = rs.getString("externalId");
      final Collection<LoanProductBorrowerCycleVariationData> principalVariationsForBorrowerCycle =
          new ArrayList<>();
      final Collection<LoanProductBorrowerCycleVariationData>
          interestRateVariationsForBorrowerCycle = new ArrayList<>();
      final Collection<LoanProductBorrowerCycleVariationData>
          numberOfRepaymentVariationsForBorrowerCycle = new ArrayList<>();
      if (this.borrowerCycleVariationDatas != null) {
        for (final LoanProductBorrowerCycleVariationData borrowerCycleVariationData :
            this.borrowerCycleVariationDatas) {
          final LoanProductParamType loanProductParamType =
              borrowerCycleVariationData.getParamType();
          if (loanProductParamType.isParamTypePrincipal()) {
            principalVariationsForBorrowerCycle.add(borrowerCycleVariationData);
          } else if (loanProductParamType.isParamTypeInterestTate()) {
            interestRateVariationsForBorrowerCycle.add(borrowerCycleVariationData);
          } else if (loanProductParamType.isParamTypeRepayment()) {
            numberOfRepaymentVariationsForBorrowerCycle.add(borrowerCycleVariationData);
          }
        }
      }

      final Boolean multiDisburseLoan = rs.getBoolean("multiDisburseLoan");
      final Integer maxTrancheCount = rs.getInt("maxTrancheCount");
      final BigDecimal outstandingLoanBalance = rs.getBigDecimal("outstandingLoanBalance");

      final int daysInMonth = JdbcSupport.getInteger(rs, "daysInMonth");
      final EnumOptionData daysInMonthType = CommonEnumerations.daysInMonthType(daysInMonth);
      final int daysInYear = JdbcSupport.getInteger(rs, "daysInYear");
      final EnumOptionData daysInYearType = CommonEnumerations.daysInYearType(daysInYear);
      final boolean isInterestRecalculationEnabled =
          rs.getBoolean("isInterestRecalculationEnabled");

      LoanProductInterestRecalculationData interestRecalculationData = null;
      if (isInterestRecalculationEnabled) {

        final Long lprId = JdbcSupport.getLong(rs, "lprId");
        final Long productId = JdbcSupport.getLong(rs, "productId");
        final int compoundTypeEnumValue = JdbcSupport.getInteger(rs, "compoundType");
        final EnumOptionData interestRecalculationCompoundingType =
            LoanEnumerations.interestRecalculationCompoundingType(compoundTypeEnumValue);
        final int rescheduleStrategyEnumValue = JdbcSupport.getInteger(rs, "rescheduleStrategy");
        final EnumOptionData rescheduleStrategyType =
            LoanEnumerations.rescheduleStrategyType(rescheduleStrategyEnumValue);
        final int restFrequencyEnumValue = JdbcSupport.getInteger(rs, "restFrequencyEnum");
        final EnumOptionData restFrequencyType =
            LoanEnumerations.interestRecalculationFrequencyType(restFrequencyEnumValue);
        final int restFrequencyInterval = JdbcSupport.getInteger(rs, "restFrequencyInterval");
        final LocalDate restFrequencyDate = JdbcSupport.getLocalDate(rs, "restFrequencyDate");

        interestRecalculationData =
            new LoanProductInterestRecalculationData(
                lprId,
                productId,
                interestRecalculationCompoundingType,
                rescheduleStrategyType,
                restFrequencyType,
                restFrequencyInterval,
                restFrequencyDate);
      }

      final boolean holdGuaranteeFunds = rs.getBoolean("holdGuaranteeFunds");
      LoanProductGuaranteeData loanProductGuaranteeData = null;
      if (holdGuaranteeFunds) {
        final Long lpgId = JdbcSupport.getLong(rs, "lpgId");
        final BigDecimal mandatoryGuarantee = rs.getBigDecimal("mandatoryGuarantee");
        final BigDecimal minimumGuaranteeFromOwnFunds =
            rs.getBigDecimal("minimumGuaranteeFromOwnFunds");
        final BigDecimal minimumGuaranteeFromGuarantor =
            rs.getBigDecimal("minimumGuaranteeFromGuarantor");
        loanProductGuaranteeData =
            LoanProductGuaranteeData.instance(
                lpgId,
                id,
                mandatoryGuarantee,
                minimumGuaranteeFromOwnFunds,
                minimumGuaranteeFromGuarantor);
      }

      return new LoanProductData(
          id,
          name,
          shortName,
          description,
          currency,
          principal,
          minPrincipal,
          maxPrincipal,
          tolerance,
          numberOfRepayments,
          minNumberOfRepayments,
          maxNumberOfRepayments,
          repaymentEvery,
          interestRatePerPeriod,
          minInterestRatePerPeriod,
          maxInterestRatePerPeriod,
          annualInterestRate,
          repaymentFrequencyType,
          interestRateFrequencyType,
          amortizationType,
          interestType,
          interestCalculationPeriodType,
          fundId,
          fundName,
          transactionStrategyId,
          transactionStrategyName,
          graceOnPrincipalPayment,
          graceOnInterestPayment,
          graceOnInterestCharged,
          this.charges,
          accountingRuleType,
          includeInBorrowerCycle,
          useBorrowerCycle,
          startDate,
          closeDate,
          status,
          externalId,
          principalVariationsForBorrowerCycle,
          interestRateVariationsForBorrowerCycle,
          numberOfRepaymentVariationsForBorrowerCycle,
          multiDisburseLoan,
          maxTrancheCount,
          outstandingLoanBalance,
          graceOnArrearsAgeing,
          overdueDaysForNPA,
          daysInMonthType,
          daysInYearType,
          isInterestRecalculationEnabled,
          interestRecalculationData,
          minimumDaysBetweenDisbursalAndFirstRepayment,
          holdGuaranteeFunds,
          loanProductGuaranteeData);
    }