/**
   * Difference from getInternalCSV: Joins with CHARGE_BOX and OCPP_TAG tables, selects
   * CHARGE_BOX_PK and OCPP_TAG_PK additionally
   */
  @SuppressWarnings("unchecked")
  private SelectQuery<
          Record10<
              Integer,
              String,
              Integer,
              String,
              DateTime,
              String,
              DateTime,
              String,
              Integer,
              Integer>>
      getInternal(TransactionQueryForm form) {

    SelectQuery selectQuery = ctx.selectQuery();
    selectQuery.addFrom(TRANSACTION);
    selectQuery.addJoin(CONNECTOR, TRANSACTION.CONNECTOR_PK.eq(CONNECTOR.CONNECTOR_PK));
    selectQuery.addJoin(CHARGE_BOX, CHARGE_BOX.CHARGE_BOX_ID.eq(CONNECTOR.CHARGE_BOX_ID));
    selectQuery.addJoin(OCPP_TAG, OCPP_TAG.ID_TAG.eq(TRANSACTION.ID_TAG));
    selectQuery.addSelect(
        TRANSACTION.TRANSACTION_PK,
        CONNECTOR.CHARGE_BOX_ID,
        CONNECTOR.CONNECTOR_ID,
        TRANSACTION.ID_TAG,
        TRANSACTION.START_TIMESTAMP,
        TRANSACTION.START_VALUE,
        TRANSACTION.STOP_TIMESTAMP,
        TRANSACTION.STOP_VALUE,
        CHARGE_BOX.CHARGE_BOX_PK,
        OCPP_TAG.OCPP_TAG_PK);

    return addConditions(selectQuery, form);
  }
  @Override
  public List<Account> getAccessibleProjects(
      Set<Identity> identities, boolean isAdmin, Long usingAccount) {
    List<Account> projects = new ArrayList<>();
    if (identities == null) {
      return projects;
    }
    if (isAdmin) {
      projects.addAll(
          create()
              .selectFrom(ACCOUNT)
              .where(ACCOUNT.KIND.eq(ProjectConstants.TYPE).and(ACCOUNT.REMOVED.isNull()))
              .orderBy(ACCOUNT.ID.asc())
              .fetch());
      return projects;
    }

    if (usingAccount != null) {
      Account project = getAccountById(usingAccount);
      if (project != null && project.getKind().equalsIgnoreCase(ProjectConstants.TYPE)) {
        projects.add(project);
        return projects;
      }
    }
    // DSL.falseCondition is created so that we can dynamically build a or
    // Condition without caring what the external Ids are and still make one
    // Database call.
    Condition allMembers = DSL.falseCondition();
    for (Identity id : identities) {
      allMembers =
          allMembers.or(
              PROJECT_MEMBER
                  .EXTERNAL_ID
                  .eq(id.getExternalId())
                  .and(PROJECT_MEMBER.EXTERNAL_ID_TYPE.eq(id.getExternalIdType()))
                  .and(PROJECT_MEMBER.REMOVED.isNull())
                  .and(PROJECT_MEMBER.STATE.eq(CommonStatesConstants.ACTIVE)));
    }
    SelectQuery<Record> query = create().selectQuery();
    query.addFrom(ACCOUNT);
    query.addJoin(PROJECT_MEMBER, PROJECT_MEMBER.PROJECT_ID.equal(ACCOUNT.ID));
    query.addConditions(allMembers);
    query.setDistinct(true);
    projects.addAll(query.fetchInto(ACCOUNT));
    Map<Long, Account> returnProjects = new HashMap<>();
    for (Account project : projects) {
      returnProjects.put(project.getId(), project);
    }
    projects = new ArrayList<>();
    projects.addAll(returnProjects.values());
    return projects;
  }
  @SuppressWarnings("unchecked")
  private Result<Record5<Integer, String, String, String, DateTime>> getOverviewInternal(
      ChargePointQueryForm form) {
    SelectQuery selectQuery = ctx.selectQuery();
    selectQuery.addFrom(CHARGE_BOX);
    selectQuery.addSelect(
        CHARGE_BOX.CHARGE_BOX_PK,
        CHARGE_BOX.CHARGE_BOX_ID,
        CHARGE_BOX.DESCRIPTION,
        CHARGE_BOX.OCPP_PROTOCOL,
        CHARGE_BOX.LAST_HEARTBEAT_TIMESTAMP);

    if (form.isSetOcppVersion()) {

      // http://dev.mysql.com/doc/refman/5.7/en/pattern-matching.html
      selectQuery.addConditions(
          CHARGE_BOX.OCPP_PROTOCOL.like(form.getOcppVersion().getValue() + "_"));
    }

    if (form.isSetDescription()) {
      selectQuery.addConditions(includes(CHARGE_BOX.DESCRIPTION, form.getDescription()));
    }

    switch (form.getHeartbeatPeriod()) {
      case ALL:
        break;

      case TODAY:
        selectQuery.addConditions(
            date(CHARGE_BOX.LAST_HEARTBEAT_TIMESTAMP).eq(date(DateTime.now())));
        break;

      case YESTERDAY:
        selectQuery.addConditions(
            date(CHARGE_BOX.LAST_HEARTBEAT_TIMESTAMP).eq(date(DateTime.now().minusDays(1))));
        break;

      case EARLIER:
        selectQuery.addConditions(
            date(CHARGE_BOX.LAST_HEARTBEAT_TIMESTAMP).lessThan(date(DateTime.now().minusDays(1))));
        break;

      default:
        throw new SteveException("Unknown enum type");
    }

    // Default order
    selectQuery.addOrderBy(CHARGE_BOX.CHARGE_BOX_PK.asc());

    return selectQuery.fetch();
  }
 public List<? extends ProjectMember> getProjectMembersByIdentity(
     long projectId, Set<Identity> identities) {
   Condition allMembers = DSL.falseCondition();
   for (Identity identity : identities) {
     allMembers =
         allMembers.or(
             PROJECT_MEMBER
                 .EXTERNAL_ID
                 .eq(identity.getExternalId())
                 .and(PROJECT_MEMBER.EXTERNAL_ID_TYPE.eq(identity.getExternalIdType()))
                 .and(PROJECT_MEMBER.REMOVED.isNull())
                 .and(PROJECT_MEMBER.STATE.eq(CommonStatesConstants.ACTIVE))
                 .and(PROJECT_MEMBER.PROJECT_ID.eq(projectId)));
   }
   SelectQuery<Record> query = create().selectQuery();
   query.addFrom(PROJECT_MEMBER);
   query.addConditions(allMembers);
   query.setDistinct(true);
   return query.fetchInto(PROJECT_MEMBER);
 }