@Override
    public SavingsDueData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum)
        throws SQLException {
      final Long savingsId = rs.getLong("savingsId");
      final String accountId = rs.getString("accountId");
      final Integer accountStatusId = JdbcSupport.getInteger(rs, "accountStatusId");
      final String productName = rs.getString("productShortName");
      final Long productId = rs.getLong("productId");
      final BigDecimal dueAmount = rs.getBigDecimal("dueAmount");

      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");
      // currency
      final CurrencyData currency =
          new CurrencyData(
              currencyCode,
              currencyName,
              currencyDigits,
              inMultiplesOf,
              currencyDisplaySymbol,
              currencyNameCode);

      return SavingsDueData.instance(
          savingsId, accountId, accountStatusId, productName, productId, currency, dueAmount);
    }
    @Override
    public JLGGroupData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum)
        throws SQLException {

      final String groupName = rs.getString("groupName");
      final Long groupId = JdbcSupport.getLong(rs, "groupId");
      final Long staffId = JdbcSupport.getLong(rs, "staffId");
      final String staffName = rs.getString("staffName");
      final Long levelId = JdbcSupport.getLong(rs, "levelId");
      final String levelName = rs.getString("levelName");
      return JLGGroupData.instance(groupId, groupName, staffId, staffName, levelId, levelName);
    }
    @Override
    public Map<String, Object> mapRow(
        final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {

      final Long id = rs.getLong("id");
      final Long glAccountId = rs.getLong("glAccountId");
      final Long productId = rs.getLong("productId");
      final Long paymentTypeId = JdbcSupport.getLong(rs, "paymentTypeId");
      final Long chargeId = rs.getLong("chargeId");
      final Integer productType = rs.getInt("productType");
      final String paymentTypeValue = rs.getString("codeValue");
      final Integer financialAccountType = rs.getInt("financialAccountType");
      final String glAccountName = rs.getString("name");
      final String glCode = rs.getString("code");
      final String chargeName = rs.getString("chargeName");
      final Boolean penalty = rs.getBoolean("penalty");

      final Map<String, Object> loanProductToGLAccountMap = new LinkedHashMap<>(5);
      loanProductToGLAccountMap.put("id", id);
      loanProductToGLAccountMap.put("glAccountId", glAccountId);
      loanProductToGLAccountMap.put("productId", productId);
      loanProductToGLAccountMap.put("productType", productType);
      loanProductToGLAccountMap.put("financialAccountType", financialAccountType);
      loanProductToGLAccountMap.put("paymentTypeId", paymentTypeId);
      loanProductToGLAccountMap.put("paymentTypeValue", paymentTypeValue);
      loanProductToGLAccountMap.put("chargeId", chargeId);
      loanProductToGLAccountMap.put("chargeName", chargeName);
      loanProductToGLAccountMap.put("penalty", penalty);
      loanProductToGLAccountMap.put("glAccountName", glAccountName);
      loanProductToGLAccountMap.put("glCode", glCode);
      return loanProductToGLAccountMap;
    }
 @Override
 public GroupGeneralData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum)
     throws SQLException {
   final Long id = JdbcSupport.getLong(rs, "id");
   final String displayName = rs.getString("displayName");
   return GroupGeneralData.lookup(id, displayName);
 }
    @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 SavingsAccountAnnualFeeData mapRow(
        final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {

      final Long id = rs.getLong("id");
      final Long accountId = rs.getLong("accountId");
      final String accountNo = rs.getString("accountNo");
      final LocalDate annualFeeNextDueDate = JdbcSupport.getLocalDate(rs, "dueDate");

      return SavingsAccountAnnualFeeData.instance(id, accountId, accountNo, annualFeeNextDueDate);
    }
    @Override
    public JLGClientData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum)
        throws SQLException {

      final String clientName = rs.getString("clientName");
      final Long clientId = JdbcSupport.getLong(rs, "clientId");
      // final Integer attendanceTypeId = rs.getInt("attendanceTypeId");
      // final EnumOptionData attendanceType =
      // AttendanceEnumerations.attendanceType(attendanceTypeId);
      final EnumOptionData attendanceType = null;

      return JLGClientData.instance(clientId, clientName, attendanceType);
    }
    public JLGClientData mapRowData(ResultSet rs, int rowNum) throws SQLException {

      List<SavingsDueData> savings = new ArrayList<>();

      JLGClientData client = this.mapRow(rs, rowNum);
      final Long previousClientId = client.getClientId();

      // first savings row of new client record
      SavingsDueData saving = savingsDueDataMapper.mapRow(rs, rowNum);
      savings.add(saving);

      while (rs.next()) {
        final Long clientId = JdbcSupport.getLong(rs, "clientId");
        if (previousClientId != null && clientId.compareTo(previousClientId) != 0) {
          // client id changes then return for next client data
          return JLGClientData.withSavings(client, savings);
        }
        saving = savingsDueDataMapper.mapRow(rs, rowNum);
        savings.add(saving);
      }
      return JLGClientData.withSavings(client, savings);
    }
    public JLGGroupData mapRowData(ResultSet rs, int rowNum) throws SQLException {
      final List<JLGClientData> clients = new ArrayList<>();
      final JLGGroupData group = this.mapRow(rs, rowNum);
      final Long previousGroupId = group.getGroupId();

      // first client row of new group
      JLGClientData client = clientSavingsDataMapper.mapRowData(rs, rowNum);
      clients.add(client);

      // if its not after last row loop
      while (!rs.isAfterLast()) {
        final Long groupId = JdbcSupport.getLong(rs, "groupId");
        if (previousGroupId != null && groupId.compareTo(previousGroupId) != 0) {
          // return for next group details
          return JLGGroupData.withClients(group, clients);
        }
        client = clientSavingsDataMapper.mapRowData(rs, rowNum);
        clients.add(client);
      }

      return JLGGroupData.withClients(group, clients);
    }
    @Override
    public AccountTransferData mapRow(
        final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {

      final Long id = rs.getLong("id");
      final boolean reversed = rs.getBoolean("isReversed");

      final LocalDate transferDate = JdbcSupport.getLocalDate(rs, "transferDate");
      final BigDecimal transferAmount =
          JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "transferAmount");
      final String transferDescription = rs.getString("transferDescription");

      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 Long fromOfficeId = JdbcSupport.getLong(rs, "fromOfficeId");
      final String fromOfficeName = rs.getString("fromOfficeName");
      final OfficeData fromOffice = OfficeData.dropdown(fromOfficeId, fromOfficeName, null);

      final Long toOfficeId = JdbcSupport.getLong(rs, "toOfficeId");
      final String toOfficeName = rs.getString("toOfficeName");
      final OfficeData toOffice = OfficeData.dropdown(toOfficeId, toOfficeName, null);

      final Long fromClientId = JdbcSupport.getLong(rs, "fromClientId");
      final String fromClientName = rs.getString("fromClientName");
      final ClientData fromClient =
          ClientData.lookup(fromClientId, fromClientName, fromOfficeId, fromOfficeName);

      final Long toClientId = JdbcSupport.getLong(rs, "toClientId");
      final String toClientName = rs.getString("toClientName");
      final ClientData toClient =
          ClientData.lookup(toClientId, toClientName, toOfficeId, toOfficeName);

      final Long fromSavingsAccountId = JdbcSupport.getLong(rs, "fromSavingsAccountId");
      final String fromSavingsAccountNo = rs.getString("fromSavingsAccountNo");
      final Long fromLoanAccountId = JdbcSupport.getLong(rs, "fromLoanAccountId");
      final String fromLoanAccountNo = rs.getString("fromLoanAccountNo");
      PortfolioAccountData fromAccount = null;
      EnumOptionData fromAccountType = null;
      if (fromSavingsAccountId != null) {
        fromAccount = PortfolioAccountData.lookup(fromSavingsAccountId, fromSavingsAccountNo);
        fromAccountType = AccountTransferEnumerations.accountType(PortfolioAccountType.SAVINGS);
      } else if (fromLoanAccountId != null) {
        fromAccount = PortfolioAccountData.lookup(fromLoanAccountId, fromLoanAccountNo);
        fromAccountType = AccountTransferEnumerations.accountType(PortfolioAccountType.LOAN);
      }

      PortfolioAccountData toAccount = null;
      EnumOptionData toAccountType = null;
      final Long toSavingsAccountId = JdbcSupport.getLong(rs, "toSavingsAccountId");
      final String toSavingsAccountNo = rs.getString("toSavingsAccountNo");
      final Long toLoanAccountId = JdbcSupport.getLong(rs, "toLoanAccountId");
      final String toLoanAccountNo = rs.getString("toLoanAccountNo");

      if (toSavingsAccountId != null) {
        toAccount = PortfolioAccountData.lookup(toSavingsAccountId, toSavingsAccountNo);
        toAccountType = AccountTransferEnumerations.accountType(PortfolioAccountType.SAVINGS);
      } else if (toLoanAccountId != null) {
        toAccount = PortfolioAccountData.lookup(toLoanAccountId, toLoanAccountNo);
        toAccountType = AccountTransferEnumerations.accountType(PortfolioAccountType.LOAN);
      }

      return AccountTransferData.instance(
          id,
          reversed,
          transferDate,
          currency,
          transferAmount,
          transferDescription,
          fromOffice,
          toOffice,
          fromClient,
          toClient,
          fromAccountType,
          fromAccount,
          toAccountType,
          toAccount);
    }
    @Override
    public RecurringDepositProductData mapRow(
        final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {

      final DepositProductData depositProductData = super.mapRow(rs);

      final boolean interestFreePeriodApplicable = rs.getBoolean("interestFreePeriodApplicable");
      final Integer interestFreeFromPeriod = JdbcSupport.getInteger(rs, "interestFreeFromPeriod");
      final Integer interestFreeToPeriod = JdbcSupport.getInteger(rs, "interestFreeToPeriod");
      final Integer periodFrequencyTypeId =
          JdbcSupport.getInteger(rs, "interestFreePeriodFrequencyId");
      final EnumOptionData interestFreePeriodFrequencyType =
          (periodFrequencyTypeId == null)
              ? null
              : InterestRateChartEnumerations.periodType(periodFrequencyTypeId);
      final boolean preClosurePenalApplicable = rs.getBoolean("preClosurePenalApplicable");
      final BigDecimal preClosurePenalInterest =
          JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "preClosurePenalInterest");
      final Integer preClosurePenalInterestOnTypeId =
          JdbcSupport.getInteger(rs, "preClosurePenalInterestOnId");
      final EnumOptionData preClosurePenalInterestOnType =
          (preClosurePenalInterestOnTypeId == null)
              ? null
              : SavingsEnumerations.preClosurePenaltyInterestOnType(
                  preClosurePenalInterestOnTypeId);
      final Integer recurringDepositTypeId = JdbcSupport.getInteger(rs, "recurringDepositTypeId");
      final EnumOptionData recurringDepositType =
          (recurringDepositTypeId == null)
              ? null
              : SavingsEnumerations.recurringDepositType(recurringDepositTypeId);
      final Integer recurringDepositFrequency =
          JdbcSupport.getInteger(rs, "recurringDepositFrequency");
      final Integer recurringDepositFrequencyTypeId =
          JdbcSupport.getInteger(rs, "recurringDepositFrequencyTypeId");
      final BigDecimal minDepositAmount =
          JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "minDepositAmount");
      final BigDecimal depositAmount =
          JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "depositAmount");
      final BigDecimal maxDepositAmount =
          JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "maxDepositAmount");
      final EnumOptionData recurringDepositFrequencyType =
          (recurringDepositFrequencyTypeId == null)
              ? null
              : SavingsEnumerations.recurringDepositFrequencyType(recurringDepositFrequencyTypeId);

      final Integer minDepositTerm = JdbcSupport.getInteger(rs, "minDepositTerm");
      final Integer maxDepositTerm = JdbcSupport.getInteger(rs, "maxDepositTerm");
      final Integer minDepositTermTypeId = JdbcSupport.getInteger(rs, "minDepositTermTypeId");
      final EnumOptionData minDepositTermType =
          (minDepositTermTypeId == null)
              ? null
              : SavingsEnumerations.depositTermFrequencyType(minDepositTermTypeId);
      final Integer maxDepositTermTypeId = JdbcSupport.getInteger(rs, "maxDepositTermTypeId");
      final EnumOptionData maxDepositTermType =
          (maxDepositTermTypeId == null)
              ? null
              : SavingsEnumerations.depositTermFrequencyType(maxDepositTermTypeId);
      final Integer inMultiplesOfDepositTerm =
          JdbcSupport.getInteger(rs, "inMultiplesOfDepositTerm");
      final Integer inMultiplesOfDepositTermTypeId =
          JdbcSupport.getInteger(rs, "inMultiplesOfDepositTermTypeId");
      final EnumOptionData inMultiplesOfDepositTermType =
          (inMultiplesOfDepositTermTypeId == null)
              ? null
              : SavingsEnumerations.depositTermFrequencyType(inMultiplesOfDepositTermTypeId);

      return RecurringDepositProductData.instance(
          depositProductData,
          interestFreePeriodApplicable,
          interestFreeFromPeriod,
          interestFreeToPeriod,
          interestFreePeriodFrequencyType,
          preClosurePenalApplicable,
          preClosurePenalInterest,
          preClosurePenalInterestOnType,
          minDepositTerm,
          maxDepositTerm,
          minDepositTermType,
          maxDepositTermType,
          inMultiplesOfDepositTerm,
          inMultiplesOfDepositTermType,
          recurringDepositType,
          recurringDepositFrequency,
          recurringDepositFrequencyType,
          minDepositAmount,
          depositAmount,
          maxDepositAmount);
    }
    public DepositProductData mapRow(final ResultSet rs) throws SQLException {

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

      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 nominalAnnualInterestRate = rs.getBigDecimal("nominalAnnualInterestRate");

      final Integer compoundingInterestPeriodTypeValue =
          JdbcSupport.getInteger(rs, "compoundingInterestPeriodType");
      final EnumOptionData compoundingInterestPeriodType =
          SavingsEnumerations.compoundingInterestPeriodType(compoundingInterestPeriodTypeValue);

      final Integer interestPostingPeriodTypeValue =
          JdbcSupport.getInteger(rs, "interestPostingPeriodType");
      final EnumOptionData interestPostingPeriodType =
          SavingsEnumerations.interestPostingPeriodType(interestPostingPeriodTypeValue);

      final Integer interestCalculationTypeValue =
          JdbcSupport.getInteger(rs, "interestCalculationType");
      final EnumOptionData interestCalculationType =
          SavingsEnumerations.interestCalculationType(interestCalculationTypeValue);

      EnumOptionData interestCalculationDaysInYearType = null;
      final Integer interestCalculationDaysInYearTypeValue =
          JdbcSupport.getInteger(rs, "interestCalculationDaysInYearType");
      if (interestCalculationDaysInYearTypeValue != null) {
        interestCalculationDaysInYearType =
            SavingsEnumerations.interestCalculationDaysInYearType(
                interestCalculationDaysInYearTypeValue);
      }

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

      final Integer lockinPeriodFrequency = JdbcSupport.getInteger(rs, "lockinPeriodFrequency");
      EnumOptionData lockinPeriodFrequencyType = null;
      final Integer lockinPeriodFrequencyTypeValue =
          JdbcSupport.getInteger(rs, "lockinPeriodFrequencyType");
      if (lockinPeriodFrequencyTypeValue != null) {
        lockinPeriodFrequencyType =
            SavingsEnumerations.lockinPeriodFrequencyType(lockinPeriodFrequencyTypeValue);
      }

      return DepositProductData.instance(
          id,
          name,
          shortName,
          description,
          currency,
          nominalAnnualInterestRate,
          compoundingInterestPeriodType,
          interestPostingPeriodType,
          interestCalculationType,
          interestCalculationDaysInYearType,
          lockinPeriodFrequency,
          lockinPeriodFrequencyType,
          accountingRuleType);
    }
    @Override
    @SuppressWarnings("unused")
    public LoanRescheduleRequestData mapRow(final ResultSet rs, final int rowNum)
        throws SQLException {
      final Long id = rs.getLong("id");
      final Long loanId = rs.getLong("loanId");
      final Integer statusEnumId = JdbcSupport.getInteger(rs, "statusEnum");
      final LoanRescheduleRequestStatusEnumData statusEnum =
          LoanRescheduleRequestEnumerations.status(statusEnumId);
      final String clientName = rs.getString("clientName");
      final String loanAccountNumber = rs.getString("loanAccountNumber");
      final Long clientId = rs.getLong("clientId");
      final Integer rescheduleFromInstallment =
          JdbcSupport.getInteger(rs, "rescheduleFromInstallment");
      final Integer graceOnPrincipal = JdbcSupport.getInteger(rs, "graceOnPrincipal");
      final Integer graceOnInterest = JdbcSupport.getInteger(rs, "graceOnInterest");
      final LocalDate rescheduleFromDate = JdbcSupport.getLocalDate(rs, "rescheduleFromDate");
      final LocalDate adjustedDueDate = JdbcSupport.getLocalDate(rs, "adjustedDueDate");
      final Integer extraTerms = JdbcSupport.getInteger(rs, "extraTerms");
      final BigDecimal interestRate = rs.getBigDecimal("interestRate");
      final Long rescheduleReasonCvId = JdbcSupport.getLong(rs, "rescheduleReasonCvId");
      final String rescheduleReasonCvValue = rs.getString("rescheduleReasonCvValue");
      final CodeValueData rescheduleReasonCodeValue =
          CodeValueData.instance(rescheduleReasonCvId, rescheduleReasonCvValue);
      final String rescheduleReasonComment = rs.getString("rescheduleReasonComment");
      final Boolean recalculateInterest = rs.getBoolean("recalculateInterest");

      final LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, "submittedOnDate");
      final String submittedByUsername = rs.getString("submittedByUsername");
      final String submittedByFirstname = rs.getString("submittedByFirstname");
      final String submittedByLastname = rs.getString("submittedByLastname");

      final LocalDate approvedOnDate = JdbcSupport.getLocalDate(rs, "approvedOnDate");
      final String approvedByUsername = rs.getString("approvedByUsername");
      final String approvedByFirstname = rs.getString("approvedByFirstname");
      final String approvedByLastname = rs.getString("approvedByLastname");

      final LocalDate rejectedOnDate = JdbcSupport.getLocalDate(rs, "rejectedOnDate");
      final String rejectedByUsername = rs.getString("rejectedByUsername");
      final String rejectedByFirstname = rs.getString("rejectedByFirstname");
      final String rejectedByLastname = rs.getString("rejectedByLastname");

      final LoanRescheduleRequestTimelineData timeline =
          new LoanRescheduleRequestTimelineData(
              submittedOnDate,
              submittedByUsername,
              submittedByFirstname,
              submittedByLastname,
              approvedOnDate,
              approvedByUsername,
              approvedByFirstname,
              approvedByLastname,
              rejectedOnDate,
              rejectedByUsername,
              rejectedByFirstname,
              rejectedByLastname);

      return LoanRescheduleRequestData.instance(
          id,
          loanId,
          statusEnum,
          rescheduleFromInstallment,
          graceOnPrincipal,
          graceOnInterest,
          rescheduleFromDate,
          adjustedDueDate,
          extraTerms,
          interestRate,
          rescheduleReasonCodeValue,
          rescheduleReasonComment,
          timeline,
          clientName,
          loanAccountNumber,
          clientId,
          recalculateInterest);
    }
    @Override
    public SavingsAccountChargeData mapRow(
        final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {

      final Long id = rs.getLong("id");
      final Long chargeId = rs.getLong("chargeId");
      final Long accountId = rs.getLong("accountId");
      final String name = rs.getString("name");
      final BigDecimal amount = rs.getBigDecimal("amountDue");
      final BigDecimal amountPaid = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountPaid");
      final BigDecimal amountWaived =
          JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountWaived");
      final BigDecimal amountWrittenOff =
          JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountWrittenOff");
      final BigDecimal amountOutstanding = rs.getBigDecimal("amountOutstanding");

      final BigDecimal percentageOf =
          JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "percentageOf");
      final BigDecimal amountPercentageAppliedTo =
          JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountPercentageAppliedTo");

      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 currencyDecimalPlaces = JdbcSupport.getInteger(rs, "currencyDecimalPlaces");
      final Integer inMultiplesOf = JdbcSupport.getInteger(rs, "inMultiplesOf");

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

      final int chargeTime = rs.getInt("chargeTime");
      final EnumOptionData chargeTimeType = ChargeEnumerations.chargeTimeType(chargeTime);

      final LocalDate dueAsOfDate = JdbcSupport.getLocalDate(rs, "dueAsOfDate");
      final Integer feeInterval = JdbcSupport.getInteger(rs, "feeInterval");
      MonthDay feeOnMonthDay = null;
      final Integer feeOnMonth = JdbcSupport.getInteger(rs, "feeOnMonth");
      final Integer feeOnDay = JdbcSupport.getInteger(rs, "feeOnDay");
      if (feeOnDay != null) {
        feeOnMonthDay = new MonthDay(feeOnMonth, feeOnDay);
      }

      final int chargeCalculation = rs.getInt("chargeCalculation");
      final EnumOptionData chargeCalculationType =
          ChargeEnumerations.chargeCalculationType(chargeCalculation);
      final boolean penalty = rs.getBoolean("penalty");

      final Collection<ChargeData> chargeOptions = null;

      return SavingsAccountChargeData.instance(
          id,
          chargeId,
          accountId,
          name,
          currency,
          amount,
          amountPaid,
          amountWaived,
          amountWrittenOff,
          amountOutstanding,
          chargeTimeType,
          dueAsOfDate,
          chargeCalculationType,
          percentageOf,
          amountPercentageAppliedTo,
          chargeOptions,
          penalty,
          feeOnMonthDay,
          feeInterval);
    }
    @Override
    public JLGCollectionSheetFlatData mapRow(
        final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {

      final String groupName = rs.getString("groupName");
      final Long groupId = JdbcSupport.getLong(rs, "groupId");
      final Long staffId = JdbcSupport.getLong(rs, "staffId");
      final String staffName = rs.getString("staffName");
      final Long levelId = JdbcSupport.getLong(rs, "levelId");
      final String levelName = rs.getString("levelName");
      final String clientName = rs.getString("clientName");
      final Long clientId = JdbcSupport.getLong(rs, "clientId");
      final Long loanId = JdbcSupport.getLong(rs, "loanId");
      final String accountId = rs.getString("accountId");
      final Integer accountStatusId = JdbcSupport.getInteger(rs, "accountStatusId");
      final String productShortName = rs.getString("productShortName");
      final Long productId = JdbcSupport.getLong(rs, "productId");

      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");
      CurrencyData currencyData = null;
      if (currencyCode != null) {
        currencyData =
            new CurrencyData(
                currencyCode,
                currencyName,
                currencyDigits,
                inMultiplesOf,
                currencyDisplaySymbol,
                currencyNameCode);
      }

      final BigDecimal disbursementAmount = rs.getBigDecimal("disbursementAmount");
      final BigDecimal principalDue = rs.getBigDecimal("principalDue");
      final BigDecimal principalPaid = rs.getBigDecimal("principalPaid");
      final BigDecimal interestDue = rs.getBigDecimal("interestDue");
      final BigDecimal interestPaid = rs.getBigDecimal("interestPaid");
      final BigDecimal chargesDue = rs.getBigDecimal("chargesDue");

      final Integer attendanceTypeId = rs.getInt("attendanceTypeId");
      final EnumOptionData attendanceType = AttendanceEnumerations.attendanceType(attendanceTypeId);

      return new JLGCollectionSheetFlatData(
          groupName,
          groupId,
          staffId,
          staffName,
          levelId,
          levelName,
          clientName,
          clientId,
          loanId,
          accountId,
          accountStatusId,
          productShortName,
          productId,
          currencyData,
          disbursementAmount,
          principalDue,
          principalPaid,
          interestDue,
          interestPaid,
          chargesDue,
          attendanceType);
    }
    @Override
    public SavingsProductData mapRow(
        final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {

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

      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 nominalAnnualInterestRate = rs.getBigDecimal("nominalAnnualInterestRate");

      final Integer compoundingInterestPeriodTypeValue =
          JdbcSupport.getInteger(rs, "compoundingInterestPeriodType");
      final EnumOptionData compoundingInterestPeriodType =
          SavingsEnumerations.compoundingInterestPeriodType(compoundingInterestPeriodTypeValue);

      final Integer interestPostingPeriodTypeValue =
          JdbcSupport.getInteger(rs, "interestPostingPeriodType");
      final EnumOptionData interestPostingPeriodType =
          SavingsEnumerations.interestPostingPeriodType(interestPostingPeriodTypeValue);

      final Integer interestCalculationTypeValue =
          JdbcSupport.getInteger(rs, "interestCalculationType");
      final EnumOptionData interestCalculationType =
          SavingsEnumerations.interestCalculationType(interestCalculationTypeValue);

      EnumOptionData interestCalculationDaysInYearType = null;
      final Integer interestCalculationDaysInYearTypeValue =
          JdbcSupport.getInteger(rs, "interestCalculationDaysInYearType");
      if (interestCalculationDaysInYearTypeValue != null) {
        interestCalculationDaysInYearType =
            SavingsEnumerations.interestCalculationDaysInYearType(
                interestCalculationDaysInYearTypeValue);
      }

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

      final BigDecimal minRequiredOpeningBalance = rs.getBigDecimal("minRequiredOpeningBalance");

      final Integer lockinPeriodFrequency = JdbcSupport.getInteger(rs, "lockinPeriodFrequency");
      EnumOptionData lockinPeriodFrequencyType = null;
      final Integer lockinPeriodFrequencyTypeValue =
          JdbcSupport.getInteger(rs, "lockinPeriodFrequencyType");
      if (lockinPeriodFrequencyTypeValue != null) {
        lockinPeriodFrequencyType =
            SavingsEnumerations.lockinPeriodFrequencyType(lockinPeriodFrequencyTypeValue);
      }

      final boolean withdrawalFeeForTransfers = rs.getBoolean("withdrawalFeeForTransfers");
      final boolean allowOverdraft = rs.getBoolean("allowOverdraft");
      final BigDecimal overdraftLimit = rs.getBigDecimal("overdraftLimit");
      return SavingsProductData.instance(
          id,
          name,
          shortName,
          description,
          currency,
          nominalAnnualInterestRate,
          compoundingInterestPeriodType,
          interestPostingPeriodType,
          interestCalculationType,
          interestCalculationDaysInYearType,
          minRequiredOpeningBalance,
          lockinPeriodFrequency,
          lockinPeriodFrequencyType,
          withdrawalFeeForTransfers,
          accountingRuleType,
          allowOverdraft,
          overdraftLimit);
    }
    @Override
    public SavingsAccountSummaryData mapRow(
        final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {

      final Long id = JdbcSupport.getLong(rs, "id");
      final String accountNo = rs.getString("accountNo");
      final String externalId = rs.getString("externalId");
      final Long productId = JdbcSupport.getLong(rs, "productId");
      final String productName = rs.getString("productName");
      final Integer statusId = JdbcSupport.getInteger(rs, "statusEnum");
      final BigDecimal accountBalance =
          JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "accountBalance");
      final SavingsAccountStatusEnumData status = SavingsEnumerations.status(statusId);
      final Integer accountType = JdbcSupport.getInteger(rs, "accountType");
      final EnumOptionData accountTypeData = AccountEnumerations.loanType(accountType);

      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 LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, "submittedOnDate");
      final String submittedByUsername = rs.getString("submittedByUsername");
      final String submittedByFirstname = rs.getString("submittedByFirstname");
      final String submittedByLastname = rs.getString("submittedByLastname");

      final LocalDate rejectedOnDate = JdbcSupport.getLocalDate(rs, "rejectedOnDate");
      final String rejectedByUsername = rs.getString("rejectedByUsername");
      final String rejectedByFirstname = rs.getString("rejectedByFirstname");
      final String rejectedByLastname = rs.getString("rejectedByLastname");

      final LocalDate withdrawnOnDate = JdbcSupport.getLocalDate(rs, "withdrawnOnDate");
      final String withdrawnByUsername = rs.getString("withdrawnByUsername");
      final String withdrawnByFirstname = rs.getString("withdrawnByFirstname");
      final String withdrawnByLastname = rs.getString("withdrawnByLastname");

      final LocalDate approvedOnDate = JdbcSupport.getLocalDate(rs, "approvedOnDate");
      final String approvedByUsername = rs.getString("approvedByUsername");
      final String approvedByFirstname = rs.getString("approvedByFirstname");
      final String approvedByLastname = rs.getString("approvedByLastname");

      final LocalDate activatedOnDate = JdbcSupport.getLocalDate(rs, "activatedOnDate");
      final String activatedByUsername = rs.getString("activatedByUsername");
      final String activatedByFirstname = rs.getString("activatedByFirstname");
      final String activatedByLastname = rs.getString("activatedByLastname");

      final LocalDate closedOnDate = JdbcSupport.getLocalDate(rs, "closedOnDate");
      final String closedByUsername = rs.getString("closedByUsername");
      final String closedByFirstname = rs.getString("closedByFirstname");
      final String closedByLastname = rs.getString("closedByLastname");

      final SavingsAccountApplicationTimelineData timeline =
          new SavingsAccountApplicationTimelineData(
              submittedOnDate,
              submittedByUsername,
              submittedByFirstname,
              submittedByLastname,
              rejectedOnDate,
              rejectedByUsername,
              rejectedByFirstname,
              rejectedByLastname,
              withdrawnOnDate,
              withdrawnByUsername,
              withdrawnByFirstname,
              withdrawnByLastname,
              approvedOnDate,
              approvedByUsername,
              approvedByFirstname,
              approvedByLastname,
              activatedOnDate,
              activatedByUsername,
              activatedByFirstname,
              activatedByLastname,
              closedOnDate,
              closedByUsername,
              closedByFirstname,
              closedByLastname);

      return new SavingsAccountSummaryData(
          id,
          accountNo,
          externalId,
          productId,
          productName,
          status,
          currency,
          accountBalance,
          accountTypeData,
          timeline);
    }
    @Override
    public LoanAccountSummaryData mapRow(
        final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {

      final Long id = JdbcSupport.getLong(rs, "id");
      final String accountNo = rs.getString("accountNo");
      final String externalId = rs.getString("externalId");
      final Long productId = JdbcSupport.getLong(rs, "productId");
      final String loanProductName = rs.getString("productName");
      final Integer loanStatusId = JdbcSupport.getInteger(rs, "statusId");
      final LoanStatusEnumData loanStatus = LoanEnumerations.status(loanStatusId);
      final Integer loanTypeId = JdbcSupport.getInteger(rs, "loanType");
      final EnumOptionData loanType = AccountEnumerations.loanType(loanTypeId);
      final Integer loanCycle = JdbcSupport.getInteger(rs, "loanCycle");

      final LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, "submittedOnDate");
      final String submittedByUsername = rs.getString("submittedByUsername");
      final String submittedByFirstname = rs.getString("submittedByFirstname");
      final String submittedByLastname = rs.getString("submittedByLastname");

      final LocalDate rejectedOnDate = JdbcSupport.getLocalDate(rs, "rejectedOnDate");
      final String rejectedByUsername = rs.getString("rejectedByUsername");
      final String rejectedByFirstname = rs.getString("rejectedByFirstname");
      final String rejectedByLastname = rs.getString("rejectedByLastname");

      final LocalDate withdrawnOnDate = JdbcSupport.getLocalDate(rs, "withdrawnOnDate");
      final String withdrawnByUsername = rs.getString("withdrawnByUsername");
      final String withdrawnByFirstname = rs.getString("withdrawnByFirstname");
      final String withdrawnByLastname = rs.getString("withdrawnByLastname");

      final LocalDate approvedOnDate = JdbcSupport.getLocalDate(rs, "approvedOnDate");
      final String approvedByUsername = rs.getString("approvedByUsername");
      final String approvedByFirstname = rs.getString("approvedByFirstname");
      final String approvedByLastname = rs.getString("approvedByLastname");

      final LocalDate expectedDisbursementDate =
          JdbcSupport.getLocalDate(rs, "expectedDisbursementDate");
      final LocalDate actualDisbursementDate =
          JdbcSupport.getLocalDate(rs, "actualDisbursementDate");
      final String disbursedByUsername = rs.getString("disbursedByUsername");
      final String disbursedByFirstname = rs.getString("disbursedByFirstname");
      final String disbursedByLastname = rs.getString("disbursedByLastname");

      final LocalDate closedOnDate = JdbcSupport.getLocalDate(rs, "closedOnDate");
      final String closedByUsername = rs.getString("closedByUsername");
      final String closedByFirstname = rs.getString("closedByFirstname");
      final String closedByLastname = rs.getString("closedByLastname");

      final LocalDate writtenOffOnDate = JdbcSupport.getLocalDate(rs, "writtenOffOnDate");

      final LocalDate expectedMaturityDate = JdbcSupport.getLocalDate(rs, "expectedMaturityDate");

      final LocalDate overdueSinceDate = JdbcSupport.getLocalDate(rs, "overdueSinceDate");
      Boolean inArrears = true;
      if (overdueSinceDate == null) {
        inArrears = false;
      }

      final LoanApplicationTimelineData timeline =
          new LoanApplicationTimelineData(
              submittedOnDate,
              submittedByUsername,
              submittedByFirstname,
              submittedByLastname,
              rejectedOnDate,
              rejectedByUsername,
              rejectedByFirstname,
              rejectedByLastname,
              withdrawnOnDate,
              withdrawnByUsername,
              withdrawnByFirstname,
              withdrawnByLastname,
              approvedOnDate,
              approvedByUsername,
              approvedByFirstname,
              approvedByLastname,
              expectedDisbursementDate,
              actualDisbursementDate,
              disbursedByUsername,
              disbursedByFirstname,
              disbursedByLastname,
              closedOnDate,
              closedByUsername,
              closedByFirstname,
              closedByLastname,
              expectedMaturityDate,
              writtenOffOnDate,
              closedByUsername,
              closedByFirstname,
              closedByLastname);

      return new LoanAccountSummaryData(
          id,
          accountNo,
          externalId,
          productId,
          loanProductName,
          loanStatus,
          loanType,
          loanCycle,
          timeline,
          inArrears);
    }
    @Override
    public AutoPostingData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum)
        throws SQLException {

      final Long id = rs.getLong("id");
      final String name = rs.getString("name");
      final String description = rs.getString("description");
      final Long officeId = JdbcSupport.getLong(rs, "officeId");
      final String officeName = rs.getString("officeName");
      final int productTypeEnum = rs.getInt("productTypeEnum");
      final Long productId = JdbcSupport.getLong(rs, "productId");
      final Long chargeId = JdbcSupport.getLong(rs, "chargeId");
      final Long accountingRuleId = JdbcSupport.getLong(rs, "accountingRuleId");
      final Long eventId = JdbcSupport.getLong(rs, "eventId");
      final Long eventAttributeId = JdbcSupport.getLong(rs, "eventAttributeId");
      final Long debitAccountId = JdbcSupport.getLong(rs, "debitAccountId");
      final Long creditAccountId = JdbcSupport.getLong(rs, "creditAccountId");
      final String savingProductName = rs.getString("savingProductName");
      final String loanProductName = rs.getString("loanProductName");
      final String chargeName = rs.getString("chargeName");
      final String eventName = rs.getString("eventName");
      final String eventAttributeName = rs.getString("eventAttributeName");
      final boolean chargeIsPenalty = rs.getBoolean("isPenalty");

      OfficeData officeData = null;
      if (officeId != null) {
        officeData = OfficeData.dropdown(officeId, officeName, null);
      }

      SavingsProductData savingsProductData = null;
      LoanProductData loanProductData = null;

      PortfolioProductType portfolioProductType = PortfolioProductType.fromInt(productTypeEnum);
      EnumOptionData productType =
          AccountingEnumerations.portfolioProductType(portfolioProductType);
      if (portfolioProductType.isLoanProduct() && productId != null) {
        savingsProductData = SavingsProductData.lookup(productId, savingProductName);
      } else if (portfolioProductType.isSavingProduct() && productId != null) {
        loanProductData = LoanProductData.lookup(productId, loanProductName);
      }

      ChargeData chargeData = null;
      if (chargeId != null) {
        chargeData = ChargeData.lookup(chargeId, chargeName, chargeIsPenalty);
      }

      CodeData event = CodeData.instance(eventId, eventName, true);

      CodeValueData eventAttribute = null;
      if (eventAttributeId != null) {
        eventAttribute = CodeValueData.instance(eventAttributeId, eventAttributeName);
      }

      AccountingRuleData accountingRuleData =
          new AccountingRuleData(accountingRuleId, debitAccountId, creditAccountId);

      return new AutoPostingData(
          id,
          name,
          description,
          officeData,
          productType,
          loanProductData,
          savingsProductData,
          chargeData,
          event,
          eventAttribute,
          accountingRuleData);
    }
    @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);
    }