private Query getQueryTotalesPorFuente(
      Session session, Long idPais, Integer anio, boolean excluirSACM) {

    StringBuffer buffer = new StringBuffer();
    buffer
        .append("SELECT new " + MontoPorDerecho.class.getName() + "(")
        .append(
            "dc.idFuente, dc.nombreFuente, dc.nombreDerechoExterno, dc.trimestre, SUM(dc.montoPercibido)) ")
        .append("FROM DatosCancion dc ");

    if (excluirSACM) {
      buffer.append("WHERE dc.companyId != :companyId ");

    } else {
      buffer.append("WHERE dc.companyId = :companyId ");
    }

    buffer
        .append(DaoUtils.getWhereClause(null, anio, idPais, null))
        .append("GROUP BY dc.idFuente, dc.nombreDerechoExterno, dc.trimestre ")
        .append("ORDER BY dc.idFuente, dc.nombreDerechoExterno");

    Query query = session.createQuery(buffer.toString());
    query.setParameter("companyId", Configuracion.SACM_COMPANY_ID);

    DaoUtils.setearParametros(query, idPais, anio, null, null);

    return query;
  }
  @SuppressWarnings("unchecked")
  @Transactional(value = "transactionManager")
  private List<MontoTotal> getMontosTotalesPorPais(
      Integer anio, Integer trimestre, Pais pais, boolean excluirSACM) {

    Session session = sessionFactory.getCurrentSession();

    StringBuffer buffer = new StringBuffer();
    buffer
        .append("SELECT new " + MontoTotal.class.getName() + "(")
        .append(anio)
        .append(", ")
        .append(trimestre)
        .append(", dc.idPais, dc.nombrePais, SUM(dc.montoPercibido)) ")
        .append("FROM DatosCancion dc ");

    if (excluirSACM) {
      buffer.append("WHERE dc.companyId != :companyId ");

    } else {
      buffer.append("WHERE dc.companyId = :companyId ");
    }

    buffer
        .append(
            DaoUtils.getWhereClause(trimestre, anio, (pais != null) ? pais.getId() : null, null))
        .append("GROUP BY dc.idPais");

    Query query = session.createQuery(buffer.toString());
    query.setParameter("companyId", Configuracion.SACM_COMPANY_ID);

    DaoUtils.setearParametros(query, (pais != null) ? pais.getId() : null, anio, trimestre, null);

    List<MontoTotal> montos = query.list();

    if (pais == null) {

      List<Pais> todosLosPaises = getPaises();
      for (Pais otroPais : todosLosPaises) {

        MontoTotal nuevoMonto = new MontoTotal(anio, trimestre, otroPais, 0.0);
        if (!montos.contains(nuevoMonto)) {
          montos.add(nuevoMonto);
        }
      }
    }

    Collections.sort(montos, new MontoTotal.ComparadorPorPais());

    return montos;
  }
  @Transactional(value = "transactionManager")
  @Cacheable("cancionesCount")
  public long getCantidadCanciones(
      Long idPais, Integer anio, Integer trimestre, Long idAutor, String filtro) {

    Session session = sessionFactory.getCurrentSession();

    StringBuffer buffer = new StringBuffer();
    buffer
        .append("select count(DISTINCT dc.idCancion) FROM DatosCancion dc ")
        .append("WHERE (dc.companyId = :companyId OR dc.companyId is null) ");

    buffer.append(DaoUtils.getWhereClause(trimestre, anio, idPais, filtro, idAutor));

    Query query = session.createQuery(buffer.toString());
    query.setParameter("companyId", Configuracion.SACM_COMPANY_ID);

    DaoUtils.setearParametros(query, idPais, anio, trimestre, filtro, idAutor);

    Long resultado = (Long) query.uniqueResult();

    return resultado != null ? resultado.longValue() : 0;
  }
  @SuppressWarnings("unchecked")
  @Transactional(value = "transactionManager")
  @Cacheable("canciones")
  public List<RankingCancion> getCanciones(
      Long idPais,
      Integer anio,
      Integer trimestre,
      Long idAutor,
      int inicio,
      int cantidadResultados,
      String filtro) {

    Session session = sessionFactory.getCurrentSession();

    StringBuffer buffer = new StringBuffer();
    buffer
        .append("SELECT new " + RankingCancion.class.getName() + "( ")
        .append("dc.idCancion, dc.nombreCancion, dc.idAutor, dc.nombreAutor, ")
        .append("SUM(dc.cantidadUnidades), SUM(dc.montoPercibido)) ")
        .append("FROM DatosCancion dc ")
        .append("WHERE (dc.companyId = :companyId OR dc.companyId is null) ");

    buffer.append(DaoUtils.getWhereClause(trimestre, anio, idPais, filtro, idAutor));

    buffer.append("GROUP BY dc.idCancion, dc.idAutor ").append("ORDER BY dc.nombreCancion asc");

    Query query = session.createQuery(buffer.toString());
    query.setParameter("companyId", Configuracion.SACM_COMPANY_ID);

    DaoUtils.setearParametros(query, idPais, anio, trimestre, filtro, idAutor);

    query.setFirstResult(inicio);
    query.setMaxResults(cantidadResultados);

    return query.list();
  }