@Transactional
  @Override
  public CommandProcessingResult rejectApplication(
      final Long savingsId, final JsonCommand command) {

    final AppUser currentUser = this.context.authenticatedUser();

    this.savingsAccountApplicationTransitionApiJsonValidator.validateRejection(command.json());

    final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsId);
    checkClientOrGroupActive(savingsAccount);

    final Map<String, Object> changes =
        savingsAccount.rejectApplication(currentUser, command, DateUtils.getLocalDateOfTenant());
    if (!changes.isEmpty()) {
      this.savingAccountRepository.save(savingsAccount);

      final String noteText = command.stringValueOfParameterNamed("note");
      if (StringUtils.isNotBlank(noteText)) {
        final Note note = Note.savingNote(savingsAccount, noteText);
        changes.put("note", noteText);
        this.noteRepository.save(note);
      }
    }

    return new CommandProcessingResultBuilder() //
        .withCommandId(command.commandId()) //
        .withEntityId(savingsId) //
        .withOfficeId(savingsAccount.officeId()) //
        .withClientId(savingsAccount.clientId()) //
        .withGroupId(savingsAccount.groupId()) //
        .withSavingsId(savingsId) //
        .with(changes) //
        .build();
  }
  @GET
  @Path("{taxMapId}")
  @Consumes({MediaType.APPLICATION_JSON})
  @Produces({MediaType.APPLICATION_JSON})
  public String retrievedSingleTaxMap(
      @PathParam("taxMapId") final Long taxMapId, @Context final UriInfo uriInfo) {

    context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
    TaxMapData taxMapData = taxMapReadPlatformService.retrievedSingleTaxMapData(taxMapId);
    final ApiRequestJsonSerializationSettings settings =
        apiRequestParameterHelper.process(uriInfo.getQueryParameters());
    if (settings.isTemplate()) {
      final List<ChargeCodeData> chargeCodeData =
          this.taxMapReadPlatformService.retrivedChargeCodeTemplateData();
      final Collection<MCodeData> taxTypeData =
          this.mCodeReadPlatformService.getCodeValue(CodeNameConstants.CODE_TYPE);
      final List<PriceRegionData> priceRegionData =
          this.regionalPriceReadplatformService.getPriceRegionsDetails();
      taxMapData.setChargeCodesForTax(chargeCodeData);
      taxMapData.setTaxTypeData(taxTypeData);
      taxMapData.setPriceRegionData(priceRegionData);
      taxMapData.setDate(DateUtils.getLocalDateOfTenantForClient());
    }
    return this.apiJsonSerializer.serialize(settings, taxMapData, RESPONSE_TAXMAPPING_PARAMETERS);
  }
  @Transactional
  @Override
  public CommandProcessingResult createEventOrder(JsonCommand command) {

    try {

      this.context.authenticatedUser();
      Long clientId = command.longValueOfParameterNamed("clientId");

      // Check Client Custome Validation
      this.eventValidationReadPlatformService.checkForCustomValidations(
          clientId, EventActionConstants.EVENT_EVENT_ORDER, command.json(), getUserId());
      EventOrder eventOrder = assembleEventOrderDetails(command, clientId);
      Configuration walletConfiguration =
          this.configurationRepository.findOneByName(
              ConfigurationConstants.CONFIG_PROPERTY_WALLET_ENABLE);
      boolean isBalanceAvailable =
          this.checkClientBalance(
              eventOrder.getBookedPrice(), clientId, walletConfiguration.isEnabled());
      if (!isBalanceAvailable) {
        throw new InsufficientAmountException("bookevent");
      }
      this.eventOrderRepository.save(eventOrder);

      List<OneTimeSaleData> oneTimeSaleDatas =
          eventOrderReadplatformServie.retrieveEventOrderData(eventOrder.getClientId());
      for (OneTimeSaleData oneTimeSaleData : oneTimeSaleDatas) {
        CommandProcessingResult commandProcessingResult =
            this.invoiceOneTimeSale.invoiceOneTimeSale(
                eventOrder.getClientId(), oneTimeSaleData, walletConfiguration.isEnabled());
        this.updateOneTimeSale(oneTimeSaleData);
        if (walletConfiguration.isEnabled()) {
          JournalVoucher journalVoucher =
              new JournalVoucher(
                  commandProcessingResult.resourceId(),
                  DateUtils.getDateOfTenant(),
                  "Event Sale",
                  null,
                  eventOrder.getBookedPrice(),
                  eventOrder.getClientId());
          this.journalvoucherRepository.save(journalVoucher);
        }
      }

      // Add New Action
      List<ActionDetaislData> actionDetaislDatas =
          this.actionDetailsReadPlatformService.retrieveActionDetails(
              EventActionConstants.EVENT_EVENT_ORDER);
      if (!actionDetaislDatas.isEmpty()) {
        this.actiondetailsWritePlatformService.AddNewActions(
            actionDetaislDatas, clientId, eventOrder.getId().toString(), null);
      }
      return new CommandProcessingResult(
          eventOrder.getEventOrderdetials().get(0).getMovieLink(), eventOrder.getClientId());

    } catch (DataIntegrityViolationException dve) {
      handleCodeDataIntegrityIssues(command, dve);
      return new CommandProcessingResult(Long.valueOf(-1));
    }
  }
  public void updateSummary(
      final MonetaryCurrency currency,
      final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments,
      final LoanSummaryWrapper summaryWrapper) {

    this.totalPrincipalOverdue =
        summaryWrapper
            .calculateTotalPrincipalOverdueOn(
                repaymentScheduleInstallments, currency, DateUtils.getLocalDateOfTenant())
            .getAmount();
    this.totalInterestOverdue =
        summaryWrapper
            .calculateTotalInterestOverdueOn(
                repaymentScheduleInstallments, currency, DateUtils.getLocalDateOfTenant())
            .getAmount();
    this.totalFeeChargesOverdue =
        summaryWrapper
            .calculateTotalFeeChargesOverdueOn(
                repaymentScheduleInstallments, currency, DateUtils.getLocalDateOfTenant())
            .getAmount();
    this.totalPenaltyChargesOverdue =
        summaryWrapper
            .calculateTotalPenaltyChargesOverdueOn(
                repaymentScheduleInstallments, currency, DateUtils.getLocalDateOfTenant())
            .getAmount();

    final Money totalOverdue =
        Money.of(currency, this.totalPrincipalOverdue)
            .plus(this.totalInterestOverdue)
            .plus(this.totalFeeChargesOverdue)
            .plus(this.totalPenaltyChargesOverdue);
    this.totalOverdue = totalOverdue.getAmount();

    final LocalDate overdueSinceLocalDate =
        summaryWrapper.determineOverdueSinceDateFrom(
            repaymentScheduleInstallments, currency, DateUtils.getLocalDateOfTenant());
    if (overdueSinceLocalDate != null) {
      this.overdueSinceDate = overdueSinceLocalDate.toDate();
    } else {
      this.overdueSinceDate = null;
    }
  }
 @GET
 @Path("template")
 @Consumes({MediaType.APPLICATION_JSON})
 @Produces({MediaType.APPLICATION_JSON})
 public String retriveOwnedHardwareTemplate(@Context final UriInfo uriInfo) {
   this.context.authenticatedUser().validateHasReadPermission(resourceType);
   List<ItemData> itemCodes = ownedHardwareReadPlatformService.retriveTemplate();
   ItemData itemCode = new ItemData(itemCodes);
   itemCode.setDate(DateUtils.getLocalDateOfTenantForClient());
   final ApiRequestJsonSerializationSettings settings =
       apiRequestParameterHelper.process(uriInfo.getQueryParameters());
   return this.apiJsonSerializerForItemCode.serialize(
       settings, itemCode, SUPPORTED_RESPONSE_PARAMETERS_ITEMCODE);
 }
 @GET
 @Path("own/{id}")
 @Consumes({MediaType.APPLICATION_JSON})
 @Produces({MediaType.APPLICATION_JSON})
 public String retriveOwnedHardwareSingleData(
     @PathParam("id") final Long id, @Context final UriInfo uriInfo) {
   this.context.authenticatedUser().validateHasReadPermission(resourceType);
   List<ItemData> itemCodes = ownedHardwareReadPlatformService.retriveTemplate();
   List<OwnedHardwareData> ownedHardwareDatas =
       ownedHardwareReadPlatformService.retriveSingleOwnedHardwareData(id);
   OwnedHardwareData ss = new OwnedHardwareData(itemCodes, ownedHardwareDatas);
   ss.setDate(DateUtils.getLocalDateOfTenantForClient());
   final ApiRequestJsonSerializationSettings settings =
       apiRequestParameterHelper.process(uriInfo.getQueryParameters());
   return this.apiJsonSerializer.serialize(settings, ss, SUPPORTED_RESPONSE_PARAMETERS);
 }
  @Transactional
  @Override
  public CommandProcessingResult createGLClosure(final JsonCommand command) {
    try {
      final GLClosureCommand closureCommand =
          this.fromApiJsonDeserializer.commandFromApiJson(command.json());
      closureCommand.validateForCreate();

      // check office is valid
      final Long officeId =
          command.longValueOfParameterNamed(GLClosureJsonInputParams.OFFICE_ID.getValue());
      final Office office = this.officeRepository.findOne(officeId);
      if (office == null) {
        throw new OfficeNotFoundException(officeId);
      }

      // TODO: Get Tenant specific date
      // ensure closure date is not in the future
      final Date todaysDate = DateUtils.getDateOfTenant();
      final Date closureDate =
          command.DateValueOfParameterNamed(GLClosureJsonInputParams.CLOSING_DATE.getValue());
      if (closureDate.after(todaysDate)) {
        throw new GLClosureInvalidException(GL_CLOSURE_INVALID_REASON.FUTURE_DATE, closureDate);
      }
      // shouldn't be before an existing accounting closure
      final GLClosure latestGLClosure =
          this.glClosureRepository.getLatestGLClosureByBranch(officeId);
      if (latestGLClosure != null) {
        if (latestGLClosure.getClosingDate().after(closureDate)) {
          throw new GLClosureInvalidException(
              GL_CLOSURE_INVALID_REASON.ACCOUNTING_CLOSED, latestGLClosure.getClosingDate());
        }
      }
      final GLClosure glClosure = GLClosure.fromJson(office, command);

      this.glClosureRepository.saveAndFlush(glClosure);

      return new CommandProcessingResultBuilder()
          .withCommandId(command.commandId())
          .withOfficeId(officeId)
          .withEntityId(glClosure.getId())
          .build();
    } catch (final DataIntegrityViolationException dve) {
      handleGLClosureIntegrityIssues(command, dve);
      return CommandProcessingResult.empty();
    }
  }
  @GET
  @Path("template")
  @Consumes({MediaType.APPLICATION_JSON})
  @Produces({MediaType.APPLICATION_JSON})
  public String retriveTaxMapTemplate(
      @QueryParam("chargeCode") final String chargeCode, @Context final UriInfo uriInfo) {

    context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
    final Collection<MCodeData> taxTypeData =
        this.mCodeReadPlatformService.getCodeValue(CodeNameConstants.CODE_TYPE);
    final List<PriceRegionData> priceRegionData =
        this.regionalPriceReadplatformService.getPriceRegionsDetails();
    final TaxMapData taxMapData =
        new TaxMapData(
            taxTypeData, priceRegionData, chargeCode, DateUtils.getLocalDateOfTenantForClient());
    final ApiRequestJsonSerializationSettings settings =
        apiRequestParameterHelper.process(uriInfo.getQueryParameters());
    return this.apiJsonSerializer.serialize(settings, taxMapData, RESPONSE_TAXMAPPING_PARAMETERS);
  }
  @Override
  public CommandProcessingResult calculateInterest(
      final Long savingsId, final JsonCommand command) {
    this.context.authenticatedUser();

    final SavingsAccount account =
        this.savingAccountRepository.findOneWithNotFoundDetection(savingsId);

    final LocalDate today = DateUtils.getLocalDateOfTenant();
    account.calculateInterest(today);
    this.savingAccountRepository.save(account);

    return new CommandProcessingResultBuilder() //
        .withEntityId(savingsId) //
        .withOfficeId(account.officeId()) //
        .withClientId(account.clientId()) //
        .withGroupId(account.groupId()) //
        .withSavingsId(savingsId) //
        .build();
  }
  @POST
  @Path("/documents")
  @Consumes({MediaType.MULTIPART_FORM_DATA})
  @Produces({MediaType.APPLICATION_JSON})
  public Response createUploadFile(
      @HeaderParam("Content-Length") final Long fileSize,
      @FormDataParam("file") final InputStream inputStream,
      @FormDataParam("file") final FormDataContentDisposition fileDetails,
      @FormDataParam("file") final FormDataBodyPart bodyPart,
      @FormDataParam("status") final String name,
      @FormDataParam("description") final String description) {

    FileUtils.validateFileSizeWithinPermissibleRange(
        fileSize, name, ApiConstants.MAX_FILE_UPLOAD_SIZE_IN_MB);
    inputStreamObject = inputStream;
    DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy");
    final Date date = DateUtils.getDateOfTenant();
    final DateTimeFormatter dtf = DateTimeFormat.forPattern("dd MMMM yyyy");
    final LocalDate localdate = dtf.parseLocalDate(dateFormat.format(date));
    final String fileUploadLocation = FileUtils.generateXlsFileDirectory();
    final String fileName = fileDetails.getFileName();
    if (!new File(fileUploadLocation).isDirectory()) {
      new File(fileUploadLocation).mkdirs();
    }
    final DataUploadCommand uploadStatusCommand =
        new DataUploadCommand(
            name,
            null,
            localdate,
            "",
            null,
            null,
            null,
            description,
            fileName,
            inputStream,
            fileUploadLocation);
    CommandProcessingResult id = this.dataUploadWritePlatformService.addItem(uploadStatusCommand);
    return Response.ok().entity(id.toString()).build();
    // return null;
  }
  @Transactional
  @Override
  public CommandProcessingResult postInterest(final Long savingsId, final JsonCommand command) {
    this.context.authenticatedUser();
    final List<Long> existingTransactionIds = new ArrayList<Long>();
    final List<Long> existingReversedTransactionIds = new ArrayList<Long>();

    final SavingsAccount account =
        this.savingAccountRepository.findOneWithNotFoundDetection(savingsId);

    final LocalDate today = DateUtils.getLocalDateOfTenant();
    account.postInterest(today, existingTransactionIds, existingReversedTransactionIds);
    this.savingAccountRepository.save(account);

    postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);

    return new CommandProcessingResultBuilder() //
        .withEntityId(savingsId) //
        .withOfficeId(account.officeId()) //
        .withClientId(account.clientId()) //
        .withGroupId(account.groupId()) //
        .withSavingsId(savingsId) //
        .build();
  }
Example #12
0
 private boolean isDateInTheFuture(final LocalDate localDate) {
   return localDate.isAfter(DateUtils.getLocalDateOfTenant());
 }
  @Transactional
  @Override
  public CommandProcessingResult modifyApplication(
      final Long savingsId, final JsonCommand command) {
    try {
      this.savingsAccountDataValidator.validateForUpdate(command.json());

      final Map<String, Object> changes = new LinkedHashMap<String, Object>(20);

      final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
      checkClientOrGroupActive(account);
      account.modifyApplication(command, changes);
      account.validateNewApplicationState(DateUtils.getLocalDateOfTenant());
      account.validateAccountValuesWithProduct();

      if (!changes.isEmpty()) {

        if (changes.containsKey(SavingsApiConstants.clientIdParamName)) {
          final Long clientId =
              command.longValueOfParameterNamed(SavingsApiConstants.clientIdParamName);
          if (clientId != null) {
            final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
            if (client.isNotActive()) {
              throw new ClientNotActiveException(clientId);
            }
            account.update(client);
          } else {
            final Client client = null;
            account.update(client);
          }
        }

        if (changes.containsKey(SavingsApiConstants.groupIdParamName)) {
          final Long groupId =
              command.longValueOfParameterNamed(SavingsApiConstants.groupIdParamName);
          if (groupId != null) {
            final Group group = this.groupRepository.findOne(groupId);
            if (group == null) {
              throw new GroupNotFoundException(groupId);
            }
            if (group.isNotActive()) {
              if (group.isCenter()) {
                throw new CenterNotActiveException(groupId);
              }
              throw new GroupNotActiveException(groupId);
            }
            account.update(group);
          } else {
            final Group group = null;
            account.update(group);
          }
        }

        if (changes.containsKey(SavingsApiConstants.productIdParamName)) {
          final Long productId =
              command.longValueOfParameterNamed(SavingsApiConstants.productIdParamName);
          final SavingsProduct product = this.savingsProductRepository.findOne(productId);
          if (product == null) {
            throw new SavingsProductNotFoundException(productId);
          }

          account.update(product);
        }

        if (changes.containsKey(SavingsApiConstants.fieldOfficerIdParamName)) {
          final Long fieldOfficerId =
              command.longValueOfParameterNamed(SavingsApiConstants.fieldOfficerIdParamName);
          Staff fieldOfficer = null;
          if (fieldOfficerId != null) {
            fieldOfficer = this.staffRepository.findOneWithNotFoundDetection(fieldOfficerId);
          } else {
            changes.put(SavingsApiConstants.fieldOfficerIdParamName, "");
          }
          account.update(fieldOfficer);
        }

        if (changes.containsKey("charges")) {
          final Set<SavingsAccountCharge> charges =
              this.savingsAccountChargeAssembler.fromParsedJson(
                  command.parsedJson(), account.getCurrency().getCode());
          final boolean updated = account.update(charges);
          if (!updated) {
            changes.remove("charges");
          }
        }

        this.savingAccountRepository.saveAndFlush(account);
      }

      return new CommandProcessingResultBuilder() //
          .withCommandId(command.commandId()) //
          .withEntityId(savingsId) //
          .withOfficeId(account.officeId()) //
          .withClientId(account.clientId()) //
          .withGroupId(account.groupId()) //
          .withSavingsId(savingsId) //
          .with(changes) //
          .build();
    } catch (final DataAccessException dve) {
      handleDataIntegrityIssues(command, dve);
      return new CommandProcessingResult(Long.valueOf(-1));
    }
  }
  @Override
  public AccountTransferData retrieveTemplate(
      final Long fromOfficeId,
      final Long fromClientId,
      final Long fromAccountId,
      final Integer fromAccountType,
      final Long toOfficeId,
      final Long toClientId,
      final Long toAccountId,
      final Integer toAccountType) {

    final EnumOptionData loanAccountType =
        AccountTransferEnumerations.accountType(PortfolioAccountType.LOAN);
    final EnumOptionData savingsAccountType =
        AccountTransferEnumerations.accountType(PortfolioAccountType.SAVINGS);

    Integer mostRelevantFromAccountType = fromAccountType;
    final Collection<EnumOptionData> fromAccountTypeOptions =
        Arrays.asList(savingsAccountType, loanAccountType);
    final Collection<EnumOptionData> toAccountTypeOptions;
    if (mostRelevantFromAccountType == 1) {
      // overpaid loan amt transfer to savings account
      toAccountTypeOptions = Arrays.asList(savingsAccountType);
    } else {
      toAccountTypeOptions = Arrays.asList(loanAccountType, savingsAccountType);
    }
    final Integer mostRelevantToAccountType = toAccountType;

    final EnumOptionData fromAccountTypeData =
        AccountTransferEnumerations.accountType(mostRelevantFromAccountType);
    final EnumOptionData toAccountTypeData =
        AccountTransferEnumerations.accountType(mostRelevantToAccountType);

    // from settings
    OfficeData fromOffice = null;
    ClientData fromClient = null;
    PortfolioAccountData fromAccount = null;

    OfficeData toOffice = null;
    ClientData toClient = null;
    PortfolioAccountData toAccount = null;

    // template
    Collection<PortfolioAccountData> fromAccountOptions = null;
    Collection<PortfolioAccountData> toAccountOptions = null;

    Long mostRelevantFromOfficeId = fromOfficeId;
    Long mostRelevantFromClientId = fromClientId;

    Long mostRelevantToOfficeId = toOfficeId;
    Long mostRelevantToClientId = toClientId;

    if (fromAccountId != null) {
      Integer accountType;
      if (mostRelevantFromAccountType == 1) {
        accountType = PortfolioAccountType.LOAN.getValue();
      } else {
        accountType = PortfolioAccountType.SAVINGS.getValue();
      }
      fromAccount =
          this.portfolioAccountReadPlatformService.retrieveOne(fromAccountId, accountType);

      // override provided fromClient with client of account
      mostRelevantFromClientId = fromAccount.clientId();
    }

    if (mostRelevantFromClientId != null) {
      fromClient = this.clientReadPlatformService.retrieveOne(mostRelevantFromClientId);
      mostRelevantFromOfficeId = fromClient.officeId();
      long[] loanStatus = null;
      if (mostRelevantFromAccountType == 1) {
        loanStatus = new long[] {300, 700};
      }
      fromAccountOptions =
          this.portfolioAccountReadPlatformService.retrieveAllForLookup(
              mostRelevantFromAccountType, mostRelevantFromClientId, loanStatus);
    }

    Collection<OfficeData> fromOfficeOptions = null;
    Collection<ClientData> fromClientOptions = null;
    if (mostRelevantFromOfficeId != null) {
      fromOffice = this.officeReadPlatformService.retrieveOffice(mostRelevantFromOfficeId);
      fromOfficeOptions = this.officeReadPlatformService.retrieveAllOfficesForDropdown();
      fromClientOptions =
          this.clientReadPlatformService.retrieveAllForLookupByOfficeId(mostRelevantFromOfficeId);
    }

    // defaults
    final LocalDate transferDate = DateUtils.getLocalDateOfTenant();
    Collection<OfficeData> toOfficeOptions = fromOfficeOptions;
    Collection<ClientData> toClientOptions = null;

    if (toAccountId != null && fromAccount != null) {
      toAccount =
          this.portfolioAccountReadPlatformService.retrieveOne(
              toAccountId, mostRelevantToAccountType, fromAccount.currencyCode());
      mostRelevantToClientId = toAccount.clientId();
    }

    if (mostRelevantToClientId != null) {
      toClient = this.clientReadPlatformService.retrieveOne(mostRelevantToClientId);
      mostRelevantToOfficeId = toClient.officeId();

      toClientOptions =
          this.clientReadPlatformService.retrieveAllForLookupByOfficeId(mostRelevantToOfficeId);

      toAccountOptions =
          retrieveToAccounts(fromAccount, mostRelevantToAccountType, mostRelevantToClientId);
    }

    if (mostRelevantToOfficeId != null) {
      toOffice = this.officeReadPlatformService.retrieveOffice(mostRelevantToOfficeId);
      toOfficeOptions = this.officeReadPlatformService.retrieveAllOfficesForDropdown();

      toClientOptions =
          this.clientReadPlatformService.retrieveAllForLookupByOfficeId(mostRelevantToOfficeId);
      if (toClientOptions != null && toClientOptions.size() == 1) {
        toClient = new ArrayList<ClientData>(toClientOptions).get(0);

        toAccountOptions =
            retrieveToAccounts(fromAccount, mostRelevantToAccountType, mostRelevantToClientId);
      }
    }

    return AccountTransferData.template(
        fromOffice,
        fromClient,
        fromAccountTypeData,
        fromAccount,
        transferDate,
        toOffice,
        toClient,
        toAccountTypeData,
        toAccount,
        fromOfficeOptions,
        fromClientOptions,
        fromAccountTypeOptions,
        fromAccountOptions,
        toOfficeOptions,
        toClientOptions,
        toAccountTypeOptions,
        toAccountOptions);
  }
  @Override
  public CommandProcessingResult convertToClient(final Long entityId) {

    final AppUser currentUser = context.authenticatedUser();
    final ClientProspect clientProspect = retrieveCodeBy(entityId);

    Long clientId = null;

    final JSONObject newClientJsonObject = new JSONObject();

    try {
      SimpleDateFormat formatter = new SimpleDateFormat("dd MMMM yyyy");
      String activationDate = formatter.format(DateUtils.getDateOfTenant());

      final Long officeId = currentUser.getOffice().getId();
      newClientJsonObject.put("dateFormat", "dd MMMM yyyy");
      newClientJsonObject.put("locale", "en");
      newClientJsonObject.put("officeId", officeId);
      newClientJsonObject.put("firstname", clientProspect.getFirstName());
      newClientJsonObject.put("middlename", clientProspect.getMiddleName());
      newClientJsonObject.put("lastname", clientProspect.getLastName());
      newClientJsonObject.put("fullname", "");
      newClientJsonObject.put("externalId", "");
      newClientJsonObject.put("clientCategory", "20");
      // newClientJsonObject.put("active","300");
      newClientJsonObject.put("activationDate", activationDate);
      newClientJsonObject.put("active", "true");
      newClientJsonObject.put("email", clientProspect.getEmail());
      newClientJsonObject.put("phone", clientProspect.getMobileNumber());
      newClientJsonObject.put("flag", false);
      /*
       * newClientJsonObject.put("login","");
       * newClientJsonObject.put("password","");
       */

      newClientJsonObject.put("addressNo", clientProspect.getAddress());
      newClientJsonObject.put("street", clientProspect.getStreetArea());
      newClientJsonObject.put("city", clientProspect.getCityDistrict());
      newClientJsonObject.put("zipCode", clientProspect.getZipCode());
      newClientJsonObject.put("state", clientProspect.getState());
      newClientJsonObject.put("country", clientProspect.getCountry());
      newClientJsonObject.put("flag", "false");

      final CommandWrapper commandNewClient =
          new CommandWrapperBuilder()
              .createClient()
              .withJson(newClientJsonObject.toString().toString())
              .build(); //

      final CommandProcessingResult clientResult =
          this.commandsSourceWritePlatformService.logCommandSource(commandNewClient);
      /*
       * final CommandWrapper commandRequest = new
       * CommandWrapperBuilder().
       * createAddress(clientResult.getClientId()).
       * withJson(newClientAddressObject.toString().toString()).build();
       * final CommandProcessingResult addressResult =
       * this.commandsSourceWritePlatformService
       * .logCommandSource(commandRequest);
       */

      clientProspect.setStatusRemark(clientResult.getClientId().toString());
      clientId = clientResult.getClientId();

    } catch (JSONException e) {
      e.printStackTrace();
    }

    clientProspect.setStatus("Closed");
    // clientProspect.setIsDeleted('Y');

    // clientProspect.setStatusRemark(command.stringValueOfParameterNamed("statusRemark"));

    this.clientProspectJpaRepository.saveAndFlush(clientProspect);

    return new CommandProcessingResultBuilder().withEntityId(clientId).build();
  }
  /**
   * This method is using for Handling Paypal IPN Requests.
   *
   * <p>i) We have to Verify the Paypal IPN Request by Re-Sending the Received Parameters to Paypal
   * IPN Server.
   *
   * <p>ii) Paypal IPN Server Checks Whether IPN Server Sending Request Parameters and Received
   * Parameters(Which are Sending by OBS on (i)).
   *
   * <p>iii) If Both Request Parameters are Match, Then Only Paypal Server Send "VERIFIED" as
   * Response
   *
   * <p>iv) If Both are mis-match, Then Send "INVALID" as Response.
   */
  @POST
  @Path("ipnhandler")
  @Consumes({MediaType.APPLICATION_FORM_URLENCODED})
  @Produces({MediaType.TEXT_HTML})
  public void paypalRecurringPayment(final @Context HttpServletRequest request) {

    RecurringBillingHistory recurringBillingHistory = new RecurringBillingHistory();

    try {
      String verifiyMessage =
          this.paymentGatewayRecurringWritePlatformService.paypalRecurringVerification(request);
      String txnType =
          request.getParameter(RecurringPaymentTransactionTypeConstants.RECURRING_TXNTYPE);

      System.out.println("Transaction Type :" + txnType + " , Result:" + verifiyMessage);

      String requestParameters =
          this.paymentGatewayRecurringWritePlatformService.getRequestParameters(request);

      recurringBillingHistory.setTransactionData(requestParameters);
      recurringBillingHistory.setTransactionDate(DateUtils.getDateOfTenant());
      recurringBillingHistory.setSource(RecurringPaymentTransactionTypeConstants.PAYPAL);
      recurringBillingHistory.setTransactionStatus(verifiyMessage);
      recurringBillingHistory.setTransactionCategory(txnType);

      if (request.getParameterMap().containsKey("txn_id")) {
        recurringBillingHistory.setTransactionId(request.getParameter("txn_id"));
      }

      if (RecurringPaymentTransactionTypeConstants.RECURRING_VERIFIED.equals(verifiyMessage)) {

        switch (txnType) {
          case RecurringPaymentTransactionTypeConstants.SUBSCR_SIGNUP:
          case RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_PROFILE_CREATED:
            this.paymentGatewayRecurringWritePlatformService.recurringSubscriberSignUp(
                request, recurringBillingHistory);

            break;

          case RecurringPaymentTransactionTypeConstants.SUBSCR_PAYMENT:
          case RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT:
            PaypalRecurringBilling paypalRecurringBilling =
                this.paymentGatewayRecurringWritePlatformService.recurringSubscriberSignUp(
                    request, recurringBillingHistory);

            if (null != paypalRecurringBilling) {

              String jsonObject =
                  this.paymentGatewayRecurringWritePlatformService.createJsonForOnlineMethod(
                      request);

              String data = OnlinePaymentMethod(jsonObject);

              JSONObject resultJsonObject = new JSONObject(data);

              String result = resultJsonObject.getString("Result");
              String description = resultJsonObject.getString("Description");

              if (result.equalsIgnoreCase(RecurringPaymentTransactionTypeConstants.SUCCESS)) {

                this.paymentGatewayRecurringWritePlatformService.recurringEventUpdate(
                    request, recurringBillingHistory);

              } else {
                recurringBillingHistory.setClientId(paypalRecurringBilling.getClientId());
                recurringBillingHistory.setObsStatus(
                    RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
                recurringBillingHistory.setObsDescription(
                    "Payment Failed in OBS, Reason: " + description);
                this.recurringBillingHistoryRepository.save(recurringBillingHistory);
              }
            }

            break;

          case RecurringPaymentTransactionTypeConstants.SUBSCR_EOT:
          case RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_EXPIRED:
          case RecurringPaymentTransactionTypeConstants.SUBSCR_CANCELLED:
            String profileId =
                request.getParameter(RecurringPaymentTransactionTypeConstants.SUBSCRID);
            PaypalRecurringBilling billing =
                this.paymentGatewayRecurringWritePlatformService.getRecurringBillingObject(
                    profileId);

            if (null == billing || null == billing.getOrderId()) {

              recurringBillingHistory.setClientId(0L);
              recurringBillingHistory.setObsStatus(
                  RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
              recurringBillingHistory.setObsDescription(
                  "OrderId Not Found with this SubscriberId:" + profileId);

            } else {

              String status =
                  this.paymentGatewayRecurringWritePlatformService.getOrderStatus(
                      billing.getOrderId());

              this.paymentGatewayRecurringWritePlatformService.updateRecurringBillingTable(
                  profileId);

              if (null != status && status.equalsIgnoreCase(StatusTypeEnum.ACTIVE.toString())) {
                final CommandWrapper commandRequest =
                    new CommandWrapperBuilder().terminateOrder(billing.getOrderId()).build();
                CommandProcessingResult result =
                    this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
                recurringBillingHistory.setClientId(billing.getClientId());

                if (null == result || result.resourceId() <= 0) {
                  recurringBillingHistory.setObsStatus(
                      RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
                  recurringBillingHistory.setObsDescription("order Terminate Action Failed...");
                } else {
                  recurringBillingHistory.setObsStatus(
                      RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_SUCCESS);
                  recurringBillingHistory.setObsDescription("Order Termination Completed...");
                }
              }
            }

            this.recurringBillingHistoryRepository.save(recurringBillingHistory);

            break;

          case RecurringPaymentTransactionTypeConstants.SUBSCR_FAILED:
          case RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILED:
          case RecurringPaymentTransactionTypeConstants.SUBSCR_MODIFY:
          case RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_SKIPPED:
            recurringBillingHistory.setClientId(0L);
            recurringBillingHistory.setObsStatus(
                RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_UNKNOWN);
            recurringBillingHistory.setObsDescription("UnDeveloped Request types");
            this.recurringBillingHistoryRepository.save(recurringBillingHistory);
            break;

          case RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_SUSPENDED:
          case RecurringPaymentTransactionTypeConstants
              .RECURRING_PAYMENT_SUSPENDED_DUE_TO_MAX_FAILED_PAYMENT:
            String profileId1 =
                request.getParameter(RecurringPaymentTransactionTypeConstants.SUBSCRID);
            this.paymentGatewayRecurringWritePlatformService.disConnectOrder(
                profileId1, recurringBillingHistory);

            break;
          default:
            break;
        }

      } else {
        recurringBillingHistory.setClientId(0L);
        recurringBillingHistory.setObsStatus(
            RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
        recurringBillingHistory.setObsDescription("Paypal Verification Failed...");
        this.recurringBillingHistoryRepository.save(recurringBillingHistory);
      }

    } catch (JSONException e) {
      recurringBillingHistory.setClientId(0L);
      recurringBillingHistory.setObsStatus(
          RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
      recurringBillingHistory.setObsDescription("JSONException throwing.." + stackTraceToString(e));
      this.recurringBillingHistoryRepository.save(recurringBillingHistory);
    } catch (UnsupportedEncodingException e) {
      recurringBillingHistory.setClientId(0L);
      recurringBillingHistory.setObsStatus(
          RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
      recurringBillingHistory.setObsDescription(
          "UnsupportedEncodingException throwing.." + stackTraceToString(e));
      this.recurringBillingHistoryRepository.save(recurringBillingHistory);
    } catch (IllegalStateException e) {
      recurringBillingHistory.setClientId(0L);
      recurringBillingHistory.setObsStatus(
          RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
      recurringBillingHistory.setObsDescription(
          "IllegalStateException throwing.." + stackTraceToString(e));
      this.recurringBillingHistoryRepository.save(recurringBillingHistory);
    } catch (ClientProtocolException e) {
      recurringBillingHistory.setClientId(0L);
      recurringBillingHistory.setObsStatus(
          RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
      recurringBillingHistory.setObsDescription(
          "ClientProtocolException throwing.." + stackTraceToString(e));
      this.recurringBillingHistoryRepository.save(recurringBillingHistory);
    } catch (IOException e) {
      recurringBillingHistory.setClientId(0L);
      recurringBillingHistory.setObsStatus(
          RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
      recurringBillingHistory.setObsDescription("IOException throwing.." + stackTraceToString(e));
      this.recurringBillingHistoryRepository.save(recurringBillingHistory);
    }
  }
  // @SuppressWarnings("unused")
  @Override
  public CommandProcessingResult selfRegistrationProcess(JsonCommand command) {

    try {

      context.authenticatedUser();
      Configuration deviceStatusConfiguration =
          configurationRepository.findOneByName(
              ConfigurationConstants.CONFIR_PROPERTY_REGISTRATION_DEVICE);

      commandFromApiJsonDeserializer.validateForCreate(
          command.json(), deviceStatusConfiguration.isEnabled());
      Long id = new Long(1);
      CommandProcessingResult resultClient = null;
      CommandProcessingResult resultSale = null;
      CommandProcessingResult resultOrder = null;
      String device = null;
      String dateFormat = "dd MMMM yyyy";
      String activationDate = new SimpleDateFormat(dateFormat).format(DateUtils.getDateOfTenant());

      String fullname = command.stringValueOfParameterNamed("fullname");
      String firstName = command.stringValueOfParameterNamed("firstname");
      String city = command.stringValueOfParameterNamed("city");
      String address = command.stringValueOfParameterNamed("address");
      Long phone = command.longValueOfParameterNamed("phone");
      Long homePhoneNumber = command.longValueOfParameterNamed("homePhoneNumber");
      String email = command.stringValueOfParameterNamed("email");
      String nationalId = command.stringValueOfParameterNamed("nationalId");
      String deviceId = command.stringValueOfParameterNamed("device");
      String deviceAgreementType = command.stringValueOfParameterNamed("deviceAgreementType");
      String password = command.stringValueOfParameterNamed("password");
      String isMailCheck = command.stringValueOfParameterNamed("isMailCheck");
      String passport = command.stringValueOfParameterNamed("passport");
      SelfCareTemporary temporary = null;

      if (isMailCheck == null || isMailCheck.isEmpty()) {
        temporary = selfCareTemporaryRepository.findOneByEmailId(email);

        if (temporary == null) {
          throw new SelfCareTemporaryEmailIdNotFoundException(email);

        } else if (temporary.getStatus().equalsIgnoreCase("ACTIVE")) {
          throw new ClientAlreadyCreatedException();

        } else if (temporary.getStatus().equalsIgnoreCase("INACTIVE")) {
          throw new SelfCareNotVerifiedException(email);
        }
      }

      //	if (temporary.getStatus().equalsIgnoreCase("PENDING")){

      String zipCode = command.stringValueOfParameterNamed("zipCode");
      // client creation
      AddressData addressData = this.addressReadPlatformService.retrieveAdressBy(city);
      CodeValue codeValue = this.codeValueRepository.findOneByCodeValue("Normal");
      JSONObject clientcreation = new JSONObject();
      clientcreation.put("officeId", new Long(1));
      clientcreation.put("clientCategory", codeValue.getId());
      clientcreation.put("firstname", firstName);
      clientcreation.put("lastname", fullname);
      clientcreation.put("phone", phone);
      clientcreation.put("homePhoneNumber", homePhoneNumber);
      clientcreation.put("entryType", "IND"); // new Long(1));
      clientcreation.put("addressNo", address);
      clientcreation.put("city", addressData.getCity());
      clientcreation.put("state", addressData.getState());
      clientcreation.put("country", addressData.getCountry());
      clientcreation.put("email", email);
      clientcreation.put("locale", "en");
      clientcreation.put("active", true);
      clientcreation.put("dateFormat", dateFormat);
      clientcreation.put("activationDate", activationDate);
      clientcreation.put("flag", false);
      clientcreation.put("zipCode", zipCode);
      clientcreation.put("device", deviceId);
      clientcreation.put("password", password);

      if (nationalId != null && !nationalId.equalsIgnoreCase("")) {
        clientcreation.put("externalId", nationalId);
      }

      final JsonElement element = fromJsonHelper.parse(clientcreation.toString());
      JsonCommand clientCommand =
          new JsonCommand(
              null,
              clientcreation.toString(),
              element,
              fromJsonHelper,
              null,
              null,
              null,
              null,
              null,
              null,
              null,
              null,
              null,
              null,
              null,
              null);
      resultClient = this.clientWritePlatformService.createClient(clientCommand);

      if (resultClient == null) {
        throw new PlatformDataIntegrityException(
            "error.msg.client.creation.failed", "Client Creation Failed", "Client Creation Failed");
      }

      if (passport != null && !passport.equalsIgnoreCase("")) {
        CodeValue passportcodeValue = this.codeValueRepository.findOneByCodeValue("Passport");
        JSONObject clientIdentifierJson = new JSONObject();
        clientIdentifierJson.put("documentTypeId", passportcodeValue.getId());
        clientIdentifierJson.put("documentKey", passport);
        final JsonElement idenfierJsonEement =
            fromJsonHelper.parse(clientIdentifierJson.toString());
        JsonCommand idenfierJsonCommand =
            new JsonCommand(
                null,
                clientIdentifierJson.toString(),
                idenfierJsonEement,
                fromJsonHelper,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null);
        this.clientIdentifierWritePlatformService.addClientIdentifier(
            resultClient.getClientId(), idenfierJsonCommand);
      }

      if (temporary != null) {
        temporary.setStatus("ACTIVE");
        this.selfCareTemporaryRepository.saveAndFlush(temporary);
      }

      // book device
      if (deviceStatusConfiguration != null) {

        if (deviceStatusConfiguration.isEnabled()) {

          JSONObject bookDevice = new JSONObject();
          /*deviceStatusConfiguration = configurationRepository
          .findOneByName(ConfigurationConstants.CONFIG_PROPERTY_DEVICE_AGREMENT_TYPE);*/

          /*if (deviceStatusConfiguration != null&& deviceStatusConfiguration.isEnabled()
          && deviceStatusConfiguration.getValue().equalsIgnoreCase(ConfigurationConstants.CONFIR_PROPERTY_SALE)) {*/
          if (deviceAgreementType.equalsIgnoreCase(ConfigurationConstants.CONFIR_PROPERTY_SALE)) {

            device = command.stringValueOfParameterNamed("device");
            ItemDetails detail = itemDetailsRepository.getInventoryItemDetailBySerialNum(device);

            if (detail == null) {
              throw new SerialNumberNotFoundException(device);
            }

            ItemMaster itemMaster = this.itemRepository.findOne(detail.getItemMasterId());

            if (itemMaster == null) {
              throw new ItemNotFoundException(deviceId);
            }

            if (detail != null && detail.getStatus().equalsIgnoreCase("Used")) {
              throw new SerialNumberAlreadyExistException(device);
            }

            JSONObject serialNumberObject = new JSONObject();
            serialNumberObject.put("serialNumber", device);
            serialNumberObject.put("clientId", resultClient.getClientId());
            serialNumberObject.put("status", "allocated");
            serialNumberObject.put("itemMasterId", detail.getItemMasterId());
            serialNumberObject.put("isNewHw", "Y");
            JSONArray serialNumber = new JSONArray();
            serialNumber.put(0, serialNumberObject);

            bookDevice.put("chargeCode", itemMaster.getChargeCode());
            bookDevice.put("unitPrice", itemMaster.getUnitPrice());
            bookDevice.put("itemId", itemMaster.getId());
            bookDevice.put("discountId", id);
            bookDevice.put("officeId", detail.getOfficeId());
            bookDevice.put("totalPrice", itemMaster.getUnitPrice());

            bookDevice.put("quantity", id);
            bookDevice.put("locale", "en");
            bookDevice.put("dateFormat", dateFormat);
            bookDevice.put("saleType", "NEWSALE");
            bookDevice.put("saleDate", activationDate);
            bookDevice.put("serialNumber", serialNumber);

            final JsonElement deviceElement = fromJsonHelper.parse(bookDevice.toString());
            JsonCommand comm =
                new JsonCommand(
                    null,
                    bookDevice.toString(),
                    deviceElement,
                    fromJsonHelper,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null);

            resultSale =
                this.oneTimeSaleWritePlatformService.createOneTimeSale(
                    comm, resultClient.getClientId());

            if (resultSale == null) {
              throw new PlatformDataIntegrityException(
                  "error.msg.client.device.assign.failed",
                  "Device Assign Failed for ClientId :" + resultClient.getClientId(),
                  "Device Assign Failed");
            }

          } else if (deviceAgreementType.equalsIgnoreCase(
              ConfigurationConstants.CONFIR_PROPERTY_OWN)) {

            List<ItemMaster> itemMaster = this.itemRepository.findAll();
            bookDevice.put("locale", "en");
            bookDevice.put("dateFormat", dateFormat);
            bookDevice.put("allocationDate", activationDate);
            bookDevice.put("provisioningSerialNumber", deviceId);
            bookDevice.put("itemType", itemMaster.get(0).getId());
            bookDevice.put("serialNumber", deviceId);
            bookDevice.put("status", "ACTIVE");
            CommandWrapper commandWrapper =
                new CommandWrapperBuilder()
                    .createOwnedHardware(resultClient.getClientId())
                    .withJson(bookDevice.toString())
                    .build();
            final CommandProcessingResult result =
                portfolioCommandSourceWritePlatformService.logCommandSource(commandWrapper);

            if (result == null) {
              throw new PlatformDataIntegrityException(
                  "error.msg.client.device.assign.failed",
                  "Device Assign Failed for ClientId :" + resultClient.getClientId(),
                  "Device Assign Failed");
            }
          } else {

          }
        }
      }

      // book order
      Configuration selfregistrationconfiguration =
          configurationRepository.findOneByName(
              ConfigurationConstants.CONFIR_PROPERTY_SELF_REGISTRATION);

      if (selfregistrationconfiguration != null && selfregistrationconfiguration.isEnabled()) {

        if (selfregistrationconfiguration.getValue() != null) {

          JSONObject ordeJson = new JSONObject(selfregistrationconfiguration.getValue());
          ordeJson.put("locale", "en");
          ordeJson.put("isNewplan", true);
          ordeJson.put("dateFormat", dateFormat);
          ordeJson.put("start_date", activationDate);

          CommandWrapper commandRequest =
              new CommandWrapperBuilder()
                  .createOrder(resultClient.getClientId())
                  .withJson(ordeJson.toString())
                  .build();
          resultOrder =
              this.portfolioCommandSourceWritePlatformService.logCommandSource(commandRequest);

          if (resultOrder == null) {
            throw new PlatformDataIntegrityException(
                "error.msg.client.order.creation",
                "Book Order Failed for ClientId:" + resultClient.getClientId(),
                "Book Order Failed");
          }

        } else {

          String paytermCode = command.stringValueOfParameterNamed("paytermCode");
          Long contractPeriod = command.longValueOfParameterNamed("contractPeriod");
          Long planCode = command.longValueOfParameterNamed("planCode");

          JSONObject ordeJson = new JSONObject();

          ordeJson.put("planCode", planCode);
          ordeJson.put("contractPeriod", contractPeriod);
          ordeJson.put("paytermCode", paytermCode);
          ordeJson.put("billAlign", false);
          ordeJson.put("locale", "en");
          ordeJson.put("isNewplan", true);
          ordeJson.put("dateFormat", dateFormat);
          ordeJson.put("start_date", activationDate);

          CommandWrapper commandRequest =
              new CommandWrapperBuilder()
                  .createOrder(resultClient.getClientId())
                  .withJson(ordeJson.toString())
                  .build();
          resultOrder =
              this.portfolioCommandSourceWritePlatformService.logCommandSource(commandRequest);

          if (resultOrder == null) {
            throw new PlatformDataIntegrityException(
                "error.msg.client.order.creation",
                "Book Order Failed for ClientId:" + resultClient.getClientId(),
                "Book Order Failed");
          }
        }
      }

      return resultClient;

      /*}  else {
      	return new CommandProcessingResult(Long.valueOf(-1));
      }*/

    } catch (DataIntegrityViolationException dve) {
      handleDataIntegrityIssues(command, dve);
      return new CommandProcessingResult(Long.valueOf(-1));
    } catch (JSONException e) {
      return new CommandProcessingResult(Long.valueOf(-1));
    }
  }
    @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);
    }