private String login() throws PluggableTaskException {

    String json =
        "{"
            + "  \"user_auth\": {"
            + "    \"user_name\": \""
            + getParameter(PARAM_USER_NAME.getName())
            + "\", "
            + "    \"password\": \""
            + getParameter(PARAM_PASSWORD.getName())
            + "\", "
            + "    \"encryption\": \"PLAIN\" "
            + "  }, "
            + "  \"application_name\": \"JBilling\","
            + "  \"name_value_list\": null "
            + "}";

    Map<String, Object> result = makeCall(json, "login");

    if (result.get("id") == null) {
      String message = "No session id. Error calling SugarCRM: " + result.get("description");
      LOG.error(message);
      throw new PluggableTaskException(message);
    }

    return result.get("id").toString();
  }
  public void update(CurrencyDTO dto, Integer entityId) {
    if (currency != null) {
      currency.setSymbol(dto.getSymbol());
      currency.setCode(dto.getCode());
      currency.setCountryCode(dto.getCountryCode());

      // set system rate
      if (dto.getSysRate() != null) {
        final CurrencyExchangeDTO systemExchangeRate =
            findExchange(SYSTEM_RATE_ENTITY_ID, currency.getId(), new Date());
        systemExchangeRate.setRate(dto.getSysRate());
      }

      // add active currencies to the company map
      CompanyDTO company = new CompanyDAS().find(entityId);
      if (dto.getInUse()) {
        company.getCurrencies().add(currency);
      } else {
        company.getCurrencies().remove(currency);
      }

      invalidateCache();
      ;

    } else {
      LOG.error("Cannot update, CurrencyDTO not found or not set!");
    }
  }
  public Integer create(CurrencyDTO dto, Integer entityId) {
    if (dto != null) {
      /*
         Simplify currency creation; Set exchange rates from transient CurrencyDTO#getRate() and
         CurrencyDTO#getSysRate() if no currency exchanges have been mapped.
      */
      if (dto.getCurrencyExchanges().isEmpty()) {
        // set system rate
        CurrencyExchangeDTO sysRate = new CurrencyExchangeDTO();
        sysRate.setEntityId(SYSTEM_RATE_ENTITY_ID);
        sysRate.setRate(dto.getSysRate() != null ? dto.getSysRate() : BigDecimal.ONE);
        sysRate.setValidSince(
            com.sapienter.jbilling.common.Util.truncateDate(CommonConstants.EPOCH_DATE));
        sysRate.setCurrency(dto);

        dto.getCurrencyExchanges().add(sysRate);
      }

      this.currency = currencyDas.save(dto);

      // add active currencies to the company map
      if (dto.getInUse()) {
        CompanyDTO company = new CompanyDAS().find(entityId);
        company.getCurrencies().add(this.currency);
      }

      invalidateCache();

      return this.currency.getId();
    }

    LOG.error("Cannot save a null CurrencyDTO!");
    return null;
  }
 /**
  * Removes all customer prices for the plan's current set of plan items. This will remove prices
  * for subscribed customers AND orphaned prices where the customers order has been deleted in a
  * non-standard way (DB delete, non API usage).
  */
 public void purgeCustomerPrices() {
   if (plan != null) {
     LOG.debug("Removing ALL remaining customer prices for plan %s", plan.getId());
     new CustomerPriceBL().removeAllPrices(plan.getPlanItems());
   } else {
     LOG.error("Cannot purge customer prices, PlanDTO not found or not set!");
   }
 }
 private String getParameter(String name) throws PluggableTaskException {
   String value = parameters.get(name);
   if (value == null || value.equals("")) {
     String message = "Parameter '" + name + "' required";
     LOG.error(message);
     throw new PluggableTaskException(message);
   }
   return value;
 }
  public void delete() {
    if (plan != null) {
      purgeCustomerPrices();
      planDas.delete(plan);

      // trigger internal event
      EventManager.process(new PlanDeletedEvent(plan));
    } else {
      LOG.error("Cannot delete, PlanDTO not found or not set!");
    }
  }
  public boolean delete() {
    if (currency != null && currency.isDeletable()) {
      currency.getEntities_1().clear();
      currencyDas.delete(currency);
      invalidateCache();
      return true;
    } else {
      LOG.error("Cannot delete, CurrencyDTO not found or not deletable!");
    }

    return false;
  }
  /**
   * Here we will have the initial credentials for a user be created
   *
   * @param user
   */
  @Override
  public void createPassword(UserDTO user) {
    ResetPasswordCodeDAS resetCodeDAS = new ResetPasswordCodeDAS();

    ResetPasswordCodeDTO resetCode = new ResetPasswordCodeDTO();
    resetCode.setUser(user);
    resetCode.setDateCreated(new Date());
    resetCode.setToken(RandomStringUtils.random(32, true, true));
    resetCodeDAS.save(resetCode);

    try {
      new UserBL()
          .sendCredentials(
              user.getCompany().getId(), user.getId(), 1, generateLink(resetCode.getToken()));
    } catch (SessionInternalError e) {
      LOG.error(e.getMessage(), e);
      throw new SessionInternalError("Exception while sending notification : " + e.getMessage());
    } catch (NotificationNotFoundException e) {
      LOG.error(e.getMessage(), e);
      throw new SessionInternalError("createCredentials.notification.not.found");
    }
  }
  /**
   * Refreshes the customer plan item price mappings for all customers that have subscribed to this
   * plan. This method will remove all existing prices for the plan and insert the current list of
   * plan items into the customer price map.
   */
  public void refreshCustomerPrices() {
    if (plan != null) {
      LOG.debug("Refreshing customer prices for subscribers to plan %s", plan.getId());

      for (CustomerDTO customer : getCustomersByPlan(plan.getId())) {
        CustomerPriceBL bl = new CustomerPriceBL(customer);
        bl.removePrices(plan.getId());
        bl.addPrices(plan.getPlanItems());
      }
    } else {
      LOG.error("Cannot update customer prices, PlanDTO not found or not set!");
    }
  }
  public Integer create(PlanDTO plan) {
    if (plan != null) {
      validateAttributes(plan);

      this.plan = planDas.save(plan);

      // trigger internal event
      EventManager.process(new NewPlanEvent(plan));

      return this.plan.getId();
    }

    LOG.error("Cannot save a null PlanDTO!");
    return null;
  }
  /**
   * This method sends an email to the given user with the link to reset his password
   *
   * @param user the user
   */
  @Override
  public void resetPassword(UserDTO user) {
    ResetPasswordCodeDAS resetCodeDAS = new ResetPasswordCodeDAS();
    // find previous passwordCode

    ResetPasswordCodeDTO resetCode = resetCodeDAS.findByUser(user);
    if (resetCode == null) {
      resetCode = new ResetPasswordCodeDTO();
      resetCode.setUser(user);
      resetCode.setDateCreated(new Date());
      resetCode.setToken(RandomStringUtils.random(32, true, true));
      resetCodeDAS.save(resetCode);
      resetCodeDAS.flush();
    } else {
      DateTime dateResetCode = new DateTime(resetCode.getDateCreated());
      DateTime today = DateTime.now();
      Duration duration = new Duration(dateResetCode, today);
      Long minutesDifference = duration.getStandardMinutes();
      Long expirationMinutes =
          PreferenceBL.getPreferenceValueAsIntegerOrZero(
                      user.getEntity().getId(),
                      CommonConstants.PREFERENCE_FORGOT_PASSWORD_EXPIRATION)
                  .longValue()
              * 60;
      if (minutesDifference > expirationMinutes) {
        resetCodeDAS.delete(resetCode);
        resetCodeDAS.flush();
        resetCode = new ResetPasswordCodeDTO();
        resetCode.setUser(user);
        resetCode.setDateCreated(new Date());
        resetCode.setToken(RandomStringUtils.random(32, true, true));
        resetCodeDAS.save(resetCode);
      }
    }

    try {
      new UserBL()
          .sendLostPassword(
              user.getCompany().getId(), user.getId(), 1, generateLink(resetCode.getToken()));

    } catch (SessionInternalError e) {
      LOG.error("Exception while sending notification : " + e.getMessage());
      throw new SessionInternalError("forgotPassword.notification.not.found");
    } catch (NotificationNotFoundException e) {
      e.printStackTrace();
    }
  }
  public void addPrice(PlanItemDTO planItem) {
    if (plan != null) {
      PriceModelBL.validateAttributes(planItem.getModels().values());

      plan.addPlanItem(planItem);

      LOG.debug("Saving updates to plan %s", plan.getId());
      this.plan = planDas.save(plan);

      refreshCustomerPrices();

      // trigger internal event
      EventManager.process(new PlanUpdatedEvent(plan));

    } else {
      LOG.error("Cannot add price, PlanDTO not found or not set!");
    }
  }
  private void updatePlan(PlanDTO plan, String action, String sessionId)
      throws PluggableTaskException {
    ItemDTO item = plan.getItem();
    int itemId = item.getId();
    String itemDescription = item.getDescription(item.getEntity().getLanguageId());

    String xml =
        "<updateplans>"
            + "  <plan action='"
            + action
            + "'>"
            + "    <code>"
            + itemId
            + "</code>"
            + "    <description>"
            + itemDescription
            + "</description>"
            + "  </plan>"
            + "</updateplans>";

    String json =
        "{" + "  \"session\": \"" + sessionId + "\", " + "  \"xmldata\": \"" + xml + "\" " + "}";

    Map<String, Object> result = makeCall(json, "updatePlan");

    String error = null;
    if (result.get("status") != null) {
      if (!result.get("status").toString().equals("OK")) {
        error = result.get("error").toString();
      }
    } else {
      error = result.get("description").toString();
    }

    if (error != null) {
      error = "Error calling SugarCRM: " + error;
      LOG.error(error);
      throw new PluggableTaskException(error);
    }
  }
  public void update(PlanDTO dto) {
    if (plan != null) {

      // un-subscribe existing customers before updating
      List<CustomerDTO> subscribers = getCustomersByPlan(plan.getId());
      for (CustomerDTO customer : subscribers) {
        unsubscribe(customer.getBaseUser().getUserId());
      }

      // clean all remaining prices just-in-case there's an orphaned record
      if (plan.getPlanItems().size() > 0) {
        purgeCustomerPrices();
      }

      // do update
      validateAttributes(dto);

      plan.setDescription(dto.getDescription());
      plan.setItem(dto.getItem());
      plan.setPeriod(dto.getPeriod());

      plan.getPlanItems().clear();
      plan.getPlanItems().addAll(dto.getPlanItems());

      LOG.debug("Saving updates to plan %s", plan.getId());
      this.plan = planDas.save(plan);

      // re-subscribe customers after plan has been saved
      for (CustomerDTO customer : subscribers) {
        subscribe(customer.getBaseUser().getUserId());
      }

      // trigger internal event
      EventManager.process(new PlanUpdatedEvent(plan));

    } else {
      LOG.error("Cannot update, PlanDTO not found or not set!");
    }
  }