/**
   * Change the order of a KPI definition comparing to the other KPIs with the same object type.
   *
   * @param kpiDefinitionId the KPI definition id
   * @param isDecrement if true then we decrement the order, else we increment it
   */
  public Result changeOrder(Long kpiDefinitionId, Boolean isDecrement) {

    KpiDefinition kpiDefinition = KpiDefinition.getById(kpiDefinitionId);

    KpiDefinition kpiDefinitionToReverse = null;
    if (isDecrement) {
      kpiDefinitionToReverse =
          KpiDefinition.getPrevious(kpiDefinition.objectType, kpiDefinition.order);
    } else {
      kpiDefinitionToReverse = KpiDefinition.getNext(kpiDefinition.objectType, kpiDefinition.order);
    }

    if (kpiDefinitionToReverse != null) {

      Integer newOrder = kpiDefinitionToReverse.order;

      kpiDefinitionToReverse.order = kpiDefinition.order;
      kpiDefinitionToReverse.save();

      kpiDefinition.order = newOrder;
      kpiDefinition.save();
    }

    return redirect(controllers.admin.routes.KpiManagerController.index());
  }
  /**
   * Delete a custom KPI.
   *
   * @param kpiDefinitionId the KPI definition id
   */
  public Result delete(Long kpiDefinitionId) {

    // get the KPI
    KpiDefinition kpiDefinition = KpiDefinition.getById(kpiDefinitionId);
    Kpi kpi = new Kpi(kpiDefinition, getKpiService());

    if (!kpiDefinition.isStandard) {

      // cancel the scheduler
      kpi.cancel();

      // delete the values and data
      deleteKpiValueDefinition(kpiDefinition.mainKpiValueDefinition);
      deleteKpiValueDefinition(kpiDefinition.additional1KpiValueDefinition);
      deleteKpiValueDefinition(kpiDefinition.additional2KpiValueDefinition);

      // delete the colors
      if (kpiDefinition.kpiColorRules != null) {
        for (KpiColorRule kpiColorRule : kpiDefinition.kpiColorRules) {
          kpiColorRule.doDelete();
        }
      }

      kpiDefinition.deleted = true;
      kpiDefinition.save();

      Utilities.sendSuccessFlashMessage(Msg.get("admin.kpi.delete.successful"));

    } else {
      Utilities.sendSuccessFlashMessage(Msg.get("admin.kpi.delete.error"));
    }

    return redirect(controllers.admin.routes.KpiManagerController.index());
  }
  /** Process the form to create a new custom and external KPI. */
  public Result processCreate() {

    // bind the form
    Form<CustomExternalKpiFormData> boundForm = customExternalKpiFormTemplate.bindFromRequest();

    // get the object type
    String objectType = boundForm.data().get("objectType");

    if (boundForm.hasErrors()) {
      return ok(views.html.admin.kpi.create.render(objectType, boundForm));
    }

    CustomExternalKpiFormData customExternalKpiFormData = boundForm.get();

    KpiDefinition kpiDefinition = customExternalKpiFormData.constructKpiDefinition();

    kpiDefinition.mainKpiValueDefinition.save();
    kpiDefinition.additional1KpiValueDefinition.save();
    kpiDefinition.additional2KpiValueDefinition.save();
    kpiDefinition.save();

    customExternalKpiFormData.mainName.persist(getI18nMessagesPlugin());
    customExternalKpiFormData.additional1Name.persist(getI18nMessagesPlugin());
    customExternalKpiFormData.additional2Name.persist(getI18nMessagesPlugin());

    reloadKpiDefinition(kpiDefinition.uid);

    Utilities.sendSuccessFlashMessage(Msg.get("admin.kpi.create.successful"));

    return redirect(controllers.admin.routes.KpiManagerController.view(kpiDefinition.id));
  }
  /**
   * Delete the scheduler of a KPI definition.
   *
   * @param kpiDefinitionId the KPI definition id
   */
  public Result deleteScheduler(Long kpiDefinitionId) {

    KpiDefinition kpiDefinition = KpiDefinition.getById(kpiDefinitionId);

    kpiDefinition.schedulerFrequency = null;
    kpiDefinition.schedulerRealTime = null;
    kpiDefinition.schedulerStartTime = null;
    kpiDefinition.save();

    reloadKpiDefinition(kpiDefinition.uid);

    Utilities.sendSuccessFlashMessage(Msg.get("admin.kpi.scheduler.delete"));

    return redirect(controllers.admin.routes.KpiManagerController.view(kpiDefinitionId));
  }