@SuppressWarnings("unchecked")
  public static Predicate[] deviceListPredicates(
      CriteriaBuilder cb,
      Root<Device> from,
      Optional<String> name,
      Optional<String> namePattern,
      Optional<String> status,
      Optional<Long> networkId,
      Optional<String> networkName,
      Optional<Long> deviceClassId,
      Optional<String> deviceClassName,
      Optional<String> deviceClassVersion,
      Optional<HivePrincipal> principal) {
    final List<Predicate> predicates = new LinkedList<>();

    name.ifPresent(n -> predicates.add(cb.equal(from.<String>get("name"), n)));
    namePattern.ifPresent(np -> predicates.add(cb.like(from.<String>get("name"), np)));
    status.ifPresent(s -> predicates.add(cb.equal(from.<String>get("status"), s)));

    final Join<Device, Network> networkJoin = (Join) from.fetch("network", JoinType.LEFT);
    networkId.ifPresent(nId -> predicates.add(cb.equal(networkJoin.<Long>get("id"), nId)));
    networkName.ifPresent(
        nName -> predicates.add(cb.equal(networkJoin.<String>get("name"), nName)));

    final Join<Device, DeviceClass> dcJoin = (Join) from.fetch("deviceClass", JoinType.LEFT);
    deviceClassId.ifPresent(dcId -> predicates.add(cb.equal(dcJoin.<Long>get("id"), dcId)));
    deviceClassName.ifPresent(
        dcName -> predicates.add(cb.equal(dcJoin.<String>get("name"), dcName)));
    deviceClassVersion.ifPresent(
        dcVersion -> predicates.add(cb.equal(dcJoin.<String>get("version"), dcVersion)));

    predicates.addAll(deviceSpecificPrincipalPredicates(cb, from, principal));

    return predicates.toArray(new Predicate[predicates.size()]);
  }
  @Override
  public List<Report593ByTimeDTO> getBatteriesByTimeFor593(
      String fromDate, String toDate, List<Integer> clinicIds) {

    HashMap<String, Report593ByTimeDTO> cache = new HashMap<>();
    Report593ByTimeDTO dto = null;

    Query q =
        entityManager.createNativeQuery(
            "SELECT date_format(date_completed, '%m/%d/%Y'), date_format(date_completed, '%W'), "
                + " count(*)"
                + " FROM veteran_assessment "
                + " WHERE assessment_status_id <> 7 AND date_completed >= :fromDate AND date_completed <= :toDate "
                + "AND clinic_id IN (:clinicIds) AND date_completed IS NOT NULL "
                + "AND  extract(HOUR FROM date_completed) >= :fr AND extract(HOUR FROM date_completed) <= :to "
                + "GROUP BY date_format( date_completed, '%Y%m%d' ) "
                + "ORDER BY date_format( date_completed, '%Y%m%d' ) ");
    setParametersFor593(q, fromDate, toDate, clinicIds);

    List result = getData(q, 6, 7);
    if (result != null && result.size() > 0) {
      for (Object aRow : result) {
        Object[] objs = (Object[]) aRow;
        dto = new Report593ByTimeDTO();
        dto.setDate((String) objs[0]);
        dto.setDayOfWeek((String) objs[1]);
        dto.setSixToEight(Integer.toString(((Number) objs[2]).intValue()));
        cache.put(dto.getDate(), dto);
      }
    }

    setParametersFor593(q, fromDate, toDate, clinicIds);

    result = getData(q, 8, 9);
    if (result != null && result.size() > 0) {
      for (Object aRow : result) {
        Object[] objs = (Object[]) aRow;
        dto = cache.get((String) objs[0]);
        if (dto == null) {
          dto = new Report593ByTimeDTO();
        }
        dto.setDate((String) objs[0]);
        dto.setDayOfWeek((String) objs[1]);
        dto.setEightToTen(Integer.toString(((Number) objs[2]).intValue()));
        cache.put(dto.getDate(), dto);
      }
    }

    result = getData(q, 10, 11);
    if (result != null && result.size() > 0) {
      for (Object aRow : result) {
        Object[] objs = (Object[]) aRow;
        dto = cache.get((String) objs[0]);
        if (dto == null) {
          dto = new Report593ByTimeDTO();
        }
        dto.setDate((String) objs[0]);
        dto.setDayOfWeek((String) objs[1]);
        dto.setTenToTwelve(Integer.toString(((Number) objs[2]).intValue()));
        cache.put(dto.getDate(), dto);
      }
    }
    result = getData(q, 12, 13);
    if (result != null && result.size() > 0) {
      for (Object aRow : result) {
        Object[] objs = (Object[]) aRow;
        dto = cache.get((String) objs[0]);
        if (dto == null) {
          dto = new Report593ByTimeDTO();
        }
        dto.setDate((String) objs[0]);
        dto.setDayOfWeek((String) objs[1]);
        dto.setTwelveToTwo(Integer.toString(((Number) objs[2]).intValue()));
        cache.put(dto.getDate(), dto);
      }
    }
    result = getData(q, 14, 15);
    if (result != null && result.size() > 0) {
      for (Object aRow : result) {
        Object[] objs = (Object[]) aRow;
        dto = cache.get((String) objs[0]);
        if (dto == null) {
          dto = new Report593ByTimeDTO();
        }
        dto.setDate((String) objs[0]);
        dto.setDayOfWeek((String) objs[1]);
        dto.setTwoToFour(Integer.toString(((Number) objs[2]).intValue()));
        cache.put(dto.getDate(), dto);
      }
    }

    result = getData(q, 16, 17);
    if (result != null && result.size() > 0) {
      for (Object aRow : result) {
        Object[] objs = (Object[]) aRow;
        dto = cache.get((String) objs[0]);
        if (dto == null) {
          dto = new Report593ByTimeDTO();
        }
        dto.setDate((String) objs[0]);
        dto.setDayOfWeek((String) objs[1]);
        dto.setFourToSix(Integer.toString(((Number) objs[2]).intValue()));
        cache.put(dto.getDate(), dto);
      }
    }

    List<Report593ByTimeDTO> resultList = new ArrayList<>();
    if (!cache.isEmpty()) {
      resultList.addAll(cache.values());

      for (Report593ByTimeDTO d : resultList) {
        if (d.getEightToTen() == null) {
          d.setEightToTen("0");
        }
        if (d.getFourToSix() == null) {
          d.setFourToSix("0");
        }
        if (d.getSixToEight() == null) {
          d.setSixToEight("0");
        }
        if (d.getTenToTwelve() == null) {
          d.setTenToTwelve("0");
        }
        if (d.getTwelveToTwo() == null) {
          d.setTwelveToTwo("0");
        }
        if (d.getTwoToFour() == null) {
          d.setTwoToFour("0");
        }

        d.setTotal(
            Integer.toString(
                Integer.parseInt(d.getEightToTen())
                    + Integer.parseInt(d.getFourToSix())
                    + Integer.parseInt(d.getSixToEight())
                    + Integer.parseInt(d.getTenToTwelve())
                    + Integer.parseInt(d.getTwelveToTwo())
                    + Integer.parseInt(d.getTwoToFour())));
      }

      Collections.sort(
          resultList,
          new Comparator<Report593ByTimeDTO>() {
            @Override
            public int compare(Report593ByTimeDTO o1, Report593ByTimeDTO o2) {
              SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
              try {
                return sdf.parse(o1.getDate()).compareTo(sdf.parse(o2.getDate()));
              } catch (Exception e) {
                return 0;
              }
            }
          });
    }

    return resultList;
  }