Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Specification com SUM e Group By

Eu preciso montar uma consulta Criteria que me retorne o TOTAL das despesas com situação igual a ABERTO, agrupadas por CARTÕES CORPORATIVOS.

Gostaria de saber se consigo fazer esse tipo de consulta utilizando Specifications com Spring Data ?

3 respostas

A select seria algo semelhante ao que esta abaixo:

SELECT
    SUM(D.VALOR),  
    F.NOME
FROM DESPESA D

INNER JOIN FUNCIONARIO F 
ON F.ID = D.ID_FUNCIONARIO

WHERE D.SITUACAO = 'A'

GROUP BY F.NOME

Como montar isso com Spring Data utilizando JpaRepository e JpaSpecificationExecutor ???

Converti a ideia em uma JPQL e obtive o resultado esperado, mas vou continuar com problemas para aplicar os filtros

DTO

@Data
public class DespesaDto {
    String idtel;
    String nome;
    String bandeira;
    String cartao;
    Date dataIinicio;
    Date dataFim;
    BigDecimal valorTotal;
}

Consulta do Repository

    @Query(value = 
             " select "
             + "  new br.com.nuvemapi.integrador.dtos.DespesaDto("
             + "      d.idtelUsuario,"
             + "      f.nome,"
             + "      d.movimento.funcionarioCartao.bandeira,"
             + "      d.movimento.funcionarioCartao.cartao,"             
             + "      min(d.data), "
             + "      max(d.data), "
             + "      sum(d.valor) "
             +"   )"
             + " from DespesaEntity d "  
             + " join FuncionarioPortalEntity f on f.idtel = d.idtelUsuario"
             + " where d.situacaoDespesa.idSituacao = 2"
             + " group by "
             + "   d.idtelUsuario,"
             + "   f.nome,"
             + "   d.movimento.funcionarioCartao.bandeira,"
             + "   d.movimento.funcionarioCartao.cartao")    
    List<DespesaDto> totalDespesasPorUsuario();

Alguém tem alguma solução de como deixar isso dinâmico ???

Preciso filtrar por Período (dataInicial, DataFinal) e por Funcionário (idtel) inicialmente, e ambos os campos são de preenchimento opcional.

solução!

Oi Thiano, tudo bem?

Sim, é possível criar essa consulta usando specifications usando Spring data.

A query que você está montando ficaria algo assim:

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Despesa> query = builder.createQuery(Despesa.class);
Root<Despesa> despesaRoot = query.from(Despesa.class);
List<Predicate> predicateList = new ArrayList<>();
Join<Despesa, Funcionario> join = despesaRoot.join("funcionario", JoinType.INNER);
predicateList.add(builder.and(builder.equal(join.get())), builder.sum(despesaRoot.get("valor")));
query.groupBy(join.get("nome"));
query.where( predicateList.toArray( new Predicate[predicateList.size()] ) );
query.select(despesaRoot);
TypedQuery<Despesa> createQuery = em.createQuery(query);

return (List<Despesa>) createQuery.getResultList();

Espero ter ajudado,

Abraço!