Subversion Repositories Integrator Subversion

Rev

Rev 607 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

package br.com.ec.repository.jpa;

import java.util.List;

import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;

import org.springframework.stereotype.Repository;

import br.com.ec.core.exception.NegocioException;
import br.com.ec.core.util.VerificadorUtil;
import br.com.ec.domain.dto.CompraProdutoDTO;
import br.com.ec.domain.dto.ProdutoDTO;
import br.com.ec.domain.model.Produto;
import br.com.ec.domain.util.CodigoBarraEAN;
import br.com.ec.repository.ProdutoRepository;
import br.com.ec.repository.SistemaAbstractRepository;

@Repository
public class ProdutoRepositoryJpaImpl extends SistemaAbstractRepository<Produto> implements ProdutoRepository {

        @Override
        protected String getColunaOrdenadora() {
                return "modelo.descricao, estilo, cor, descricao";
        }
       
        @Override
        protected boolean adicionarDistinct() {
                return false;
        }
       
        @Override
        public Produto consultarProdutoPorCodigo(String codigoProduto) {
                StringBuilder sql = new StringBuilder();
                sql.append("SELECT e FROM Produto e ");
                sql.append("WHERE e.codigo = :codigo");
                try {
                        return getEntityManager().createQuery(sql.toString(), Produto.class).setParameter("codigo", codigoProduto).getSingleResult();
                } catch(NoResultException ex) {
                        throw new NegocioException("NÃO EXISTE PRODUTO COM ESTE CÓDIGO");
                } catch(Exception ex) {
                        ex.printStackTrace();
                        return null;
                }
        }
       
        @Override
        public ProdutoDTO consultarProdutoDTOPorCodigoOuEAN(String codigoOuEAN) {
                StringBuilder jpql = new StringBuilder();
                jpql.append("SELECT new br.com.ec.domain.dto.ProdutoDTO(");
                jpql.append(ProdutoDTO.CONSULTA_DTO_SIMPLES_COM_MODELO_E_SUBTIPO);
                jpql.append(") FROM Produto e ");
                jpql.append("WHERE 1=1 AND ");
                if (CodigoBarraEAN.validarCodigoBarras(codigoOuEAN)) {
                        jpql.append("e.codigoEAN = :codigoOuEAN");
                } else {
                        codigoOuEAN = ProdutoDTO.retornarCodigoProdutoPadrao(codigoOuEAN);
                        jpql.append("e.codigo = :codigoOuEAN");
                }
                try {
                        TypedQuery<ProdutoDTO> query = (TypedQuery<ProdutoDTO>) getEntityManager()
                                        .createQuery(jpql.toString(), ProdutoDTO.class)
                                        .setParameter("codigoOuEAN", codigoOuEAN);
                        return query.getSingleResult();
                } catch(NoResultException ex) {
                        throw new NegocioException("NÃO EXISTE PRODUTO COM ESTE CÓDIGO");
                } catch(Exception ex) {
                        ex.printStackTrace();
                        return null;
                }
        }
       
        @Override
        public List<CompraProdutoDTO> consultarComprasDoProduto(Long sequencialProduto) {
                StringBuilder jpql = new StringBuilder();
                jpql.append("SELECT new br.com.ec.domain.dto.CompraProdutoDTO(");
                jpql.append(CompraProdutoDTO.CONSULTA_DTO_COMPLETA);
                jpql.append(") FROM CompraProduto e ");
                jpql.append("WHERE 1=1 AND ");
                jpql.append("e.produto.sequencial = :sequencialProduto ");
                try {
                        jpql.append("ORDER BY e.compra.dataCompra DESC");
                        return getEntityManager().createQuery(jpql.toString(), CompraProdutoDTO.class)
                                        .setParameter("sequencialProduto", sequencialProduto)
                                        .getResultList();
                } catch(Exception ex) {
                        ex.printStackTrace();
                        return null;
                }
        }
       
        @Override
        public List<ProdutoDTO> consultarProdutosDoFornecedor(Long sequencialFornecedor) {
                StringBuilder jpql = new StringBuilder();
                jpql.append("SELECT new br.com.ec.domain.dto.ProdutoDTO(");
                jpql.append(ProdutoDTO.CONSULTA_DTO_SIMPLES_COM_MODELO);
                jpql.append(") FROM Produto e ");
                jpql.append("LEFT JOIN ");
                jpql.append("WHERE 1=1 ");
                jpql.append("AND e.produto.sequencial = :sequencialProduto ");
                jpql.append("AND EXISTS(SELECT fp FROM FornecedorProduto fp WHERE fp.fornecedor.sequencial = :sequencialFornecedor AND fp.produto.sequencial = e.sequencial) ");
                try {
                        jpql.append("ORDER BY e.descricao DESC");
                        return getEntityManager().createQuery(jpql.toString(), ProdutoDTO.class)
                                        .setParameter("sequencialFornecedor", sequencialFornecedor)
                                        .getResultList();
                } catch(Exception ex) {
                        ex.printStackTrace();
                        return null;
                }
        }
       
        /*
        @Override
        public List<Produto> consultarProdutoPorParametros(ParametrosConsultaProdutoDTO parametrosConsultaProduto) {
                StringBuilder sql = new StringBuilder();
                sql.append("SELECT DISTINCT e FROM Produto e ");
                sql.append("WHERE 1=1 ");
                try {
                        setarStringParametrosConsulta(sql, parametrosConsultaProduto);
                        sql.append("ORDER BY e.descricao");
                        TypedQuery<Produto> query = (TypedQuery<Produto>) getEntityManager().createQuery(sql.toString(), Produto.class);
                        setarQueryParametrosConsulta(query, parametrosConsultaProduto);
                        return query.getResultList();
                } catch(Exception ex) {
                        ex.printStackTrace();
                        return null;
                }
        }
       
        @Override
        public List<Produto> consultarCompativeis(Produto produto) {
                StringBuilder sql = new StringBuilder();
                sql.append("SELECT DISTINCT e FROM Produto e ");
                sql.append("WHERE e.sequencial = :sequencialProduto ");
                sql.append("OR e IN (SELECT pr.produtoRelacionado FROM ProdutoRelacionado pr WHERE pr.produto.sequencial = :sequencialProduto) ");
                sql.append("OR e IN (SELECT prr.produto FROM ProdutoRelacionado prr WHERE prr.produtoRelacionado.sequencial = :sequencialProduto) ");
                try {
                        sql.append("ORDER BY e.descricao");
                        TypedQuery<Produto> query = (TypedQuery<Produto>) getEntityManager().createQuery(sql.toString(), Produto.class);
                        query.setParameter("sequencialProduto", produto.getSequencial());
                        return query.getResultList();
                } catch(Exception ex) {
                        ex.printStackTrace();
                        return null;
                }
        }
       
        @Override
        public Produto detalharProduto(Produto produto) {
                StringBuilder jpql = new StringBuilder();
                jpql.append("SELECT p FROM Produto p ");
                jpql.append("LEFT JOIN FETCH p.pedidosCompra c ");
                jpql.append("LEFT JOIN FETCH p.fornecedores f ");
                jpql.append("LEFT JOIN FETCH p.relacionados r ");
                jpql.append("LEFT JOIN FETCH p.relacionadosReverse v ");
                jpql.append("WHERE p = :produto");
                return getEntityManager().createQuery(jpql.toString(), Produto.class).setParameter("produto", produto).getSingleResult();
        }
       
        @Override
        protected void setarStringParametrosConsultar(StringBuilder sql, Produto produto) {
                if (VerificadorUtil.naoEstaNulo(produto)) {
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getCodigo())) {
                                sql.append("AND e.codigo = :codigo ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getCodigoRapido())) {
                                sql.append("AND e.codigoRapido = :codigoRapido ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getCodigoEAN())) {
                                sql.append("AND e.codigoEAN = :codigoEAN ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getDescricao())) {
                                sql.append("AND ");
                                sql.append(sqlConsultarSemAcento("e.descricao"));
                                sql.append(" like upper(:descricao) ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getTipo())) {
                                sql.append("AND e.tipo = :tipoProduto ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getEstilo())) {
                                sql.append("AND e.estilo = :estilo ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getCor())) {
                                sql.append("AND e.cor = :cor ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getGenero())) {
                                sql.append("AND e.genero = :tipoGenero ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getIndicadorOnline())) {
                                if (produto.getIndicadorOnline()) {
                                        sql.append("AND e.dataOnline IS NOT NULL ");
                                } else {
                                        sql.append("AND e.dataOnline IS NULL ");
                                }
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getIndicadorOnlineMercadoLivre())) {
                                if (produto.getIndicadorOnlineMercadoLivre()) {
                                        sql.append("AND e.dataOnlineMercadoLivre IS NOT NULL ");
                                } else {
                                        sql.append("AND e.dataOnlineMercadoLivre IS NULL ");
                                }
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getAtivo())) {
                                sql.append("AND e.indicadorAtivo = :indicadorAtivo ");
                        }
                        if (VerificadorUtil.naoEstaNulo(produto.getSequencialDoModelo())) {
                                sql.append("AND e.modelo.sequencial = :sequencialModelo ");
                        }
                        if (VerificadorUtil.naoEstaNulo(produto.getMarcaDoModelo())) {
                                sql.append("AND e.modelo.marca.sequencial = :sequencialMarcaDoModelo ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getSujeitoST())) {
                                sql.append("AND e.sujeitoST = :sujeitoST ");
                        }
                }
        }
       
        @Override
        protected void setarQueryParametrosConsultar(Query query, Produto produto) {
                if (VerificadorUtil.naoEstaNulo(produto)) {
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getCodigo())) {
                                query.setParameter("codigo", produto.getCodigoProdutoPadrao());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getCodigoRapido())) {
                                query.setParameter("codigoRapido", produto.getCodigoRapido());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getCodigoEAN())) {
                                query.setParameter("codigoEAN", produto.getCodigoEAN());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getDescricao())) {
                                query.setParameter("descricao", "%" + removerAcentuacao(produto.getDescricao()) + "%");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getTipo())) {
                                query.setParameter("tipoProduto", produto.getTipo());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getEstilo())) {
                                query.setParameter("estilo", produto.getEstilo());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getCor())) {
                                query.setParameter("cor", produto.getCor());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getGenero())) {
                                query.setParameter("tipoGenero", produto.getGenero());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getAtivo())) {
                                query.setParameter("indicadorAtivo", produto.getAtivo());
                        }
                        if (VerificadorUtil.naoEstaNulo(produto.getSequencialDoModelo())) {
                                query.setParameter("sequencialModelo", produto.getSequencialDoModelo());
                        }
                        if (VerificadorUtil.naoEstaNulo(produto.getMarcaDoModelo())) {
                                query.setParameter("sequencialMarcaDoModelo", produto.getMarcaDoModelo().getSequencial());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getSujeitoST())) {
                                query.setParameter("sujeitoST", produto.getSujeitoST());
                        }
                }
        }
       
        @Override
        protected void setarStringParametrosConsulta(StringBuilder sql, ParametrosConsulta<Produto> parametros) {
                if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getFiltro())) {
                        sql.append("AND (e.codigo = :filtro OR e.codigo = :filtroECCEAN OR e.codigoEAN = :filtroCEAN) ");
                }
                if (VerificadorUtil.naoEstaNulo(parametros.getEntidade())) {
                        verificarRestricoes(sql, parametros);
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getCodigo())) {
                                sql.append("AND e.codigo = :codigo ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getCodigoRapido())) {
                                sql.append("AND e.codigoRapido = :codigoRapido ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getCodigoEAN())) {
                                if (CodigoBarraEAN.validarCodigoBarras(parametros.getEntidade().getCodigoEAN())) {
                                        sql.append("AND (e.codigoEAN = :codigoEAN OR e.codigo = :codigoBarras) ");
                                } else {
                                        sql.append("AND e.codigoEAN = :codigoEAN ");
                                }
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getDescricao())) {
                                sql.append("AND ");
                                sql.append(sqlConsultarSemAcento("e.descricao"));
                                sql.append(" like upper(:descricao) ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getTipo())) {
                                sql.append("AND e.tipo = :tipoProduto ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getEstilo())) {
                                sql.append("AND e.estilo = :estilo ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getCor())) {
                                sql.append("AND e.cor = :cor ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getGenero())) {
                                sql.append("AND e.genero = :tipoGenero ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getIndicadorComissionado())) {
                                sql.append("AND e.indicadorComissionado = :indicadorComissionado ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(((ParametrosConsultaProdutoDTO)parametros).getConsultarAtivo())) {
                                sql.append("AND e.ativo = :ativo ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(((ParametrosConsultaProdutoDTO)parametros).getConsultarOnline())) {
                                if (((ParametrosConsultaProdutoDTO)parametros).getConsultarOnline().equals(1)) {
                                        sql.append("AND e.dataOnline IS NOT NULL ");
                                } else if (((ParametrosConsultaProdutoDTO)parametros).getConsultarOnline().equals(2)) {
                                        sql.append("AND e.dataOnline IS NULL ");
                                }
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(((ParametrosConsultaProdutoDTO)parametros).getConsultarOnlineMercadoLivre())) {
                                if (((ParametrosConsultaProdutoDTO)parametros).getConsultarOnlineMercadoLivre().equals(1)) {
                                        sql.append("AND e.dataOnlineMercadoLivre IS NOT NULL ");
                                } else if (((ParametrosConsultaProdutoDTO)parametros).getConsultarOnlineMercadoLivre().equals(2)) {
                                        sql.append("AND e.dataOnlineMercadoLivre IS NULL ");
                                }
                        }
                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametros).getModelo())) {
                                sql.append("AND e.modelo.sequencial = :sequencialModelo ");
                        }
                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametros).getMarca())) {
                                sql.append("AND e.modelo.marca.sequencial = :sequencialMarcaDoModelo ");
                        }
                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametros).getFornecedor())) {
                                sql.append("AND EXISTS(SELECT fp FROM FornecedorProduto fp WHERE fp.fornecedor.sequencial = :sequencialFornecedor AND fp.produto.sequencial = e.sequencial) ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(((ParametrosConsultaProdutoDTO)parametros).getIndicadorModeloFavorito())) {
                                sql.append("AND e.modelo.indicadorFavorito = :indicadorFavorito ");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(((ParametrosConsultaProdutoDTO)parametros).getSujeitoST())) {
                                sql.append("AND e.sujeitoST = :sujeitoST ");
                        }
                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametros).getTributacao())) {
                                sql.append("AND e.tributacao = :tributacao ");
                        }
                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametros).getLojaSelecionadaParaContagem())) {
                                sql.append("AND e.modelo is not null ");
                                sql.append("AND EXISTS(SELECT pl FROM ProdutoLoja pl WHERE ");
                                if (VerificadorUtil.naoEstaNuloOuVazio(((ParametrosConsultaProdutoDTO)parametros).getLocalizacaoLojaSelecionada())) {
                                        sql.append("pl.localizacao like upper(:localizacao) AND ");
                                }
                                if (!((ParametrosConsultaProdutoDTO)parametros).getContagemObrigatoria()) {
                                        verificarSeNaoHaTransferenciasDoProduto(sql);
                                        // PRODUTOS SEM PREPARACAO DE CONTAGEM
                                        // OU (
                                                // PRODUTOS PREPARADOS POR OUTROS
                                                // AND (
                                                        // COM INDICAÇÃO DE CONTAGEM SOLICITADA
                                                        // OU
                                                        // COM PREPARAÇÃO POSTERIOR AO DA CONTAGEM
                                                        // OU
                                                        // COM CONTAGENS FINALIZADAS POR MAIS DE 60 DIAS
                                                // )
                                        // )
                                        sql.append("AND (");
                                                sql.append("pl.usuarioUltimaContagemPreparacao.sequencial IS NULL ");
                                                sql.append("OR (");
                                                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametros).getUsuarioParaContagem())) {
                                                                sql.append("pl.usuarioUltimaContagemPreparacao != :usuarioParaContagem ");
                                                        } else {
                                                                sql.append("pl.usuarioUltimaContagemPreparacao != null ");
                                                        }
                                                        sql.append(") ");
                                                        // CONTAR PRODUTOS COM DATA DE CONTAGEM ACIMA DE 60 DIAS
//                                                      sql.append("OR ");
//                                                      sql.append("(date_part('day', now() - pl.dataContagem) >= ").append(ConstantesSEC.StatusContagem.CONTAGEM_VERMELHO_60_DIAS).append(") ");
                                                sql.append(") ");
//                                      sql.append("AND (pl.dataContagem IS NULL OR pl.dataContagemPreparacao > pl.dataContagem) ");
                                        sql.append("AND (pl.produto.modelo.marca.dataContagemSolicitada > pl.dataContagem) ");
                                        sql.append("AND (");
                                                sql.append("(pl.quantidadeEstoque != 0 AND ");
                                                sql.append("(pl.indicadorContagemSolicitada IS TRUE OR pl.produto.modelo.marca.indicadorContagemSolicitada IS TRUE) ");
                                        sql.append(") ");
                                        if (ConstantesSEC.FORMATO_CONTAGEM.equals(ConstantesSEC.ContagemFormato.FORMATO_CONTAGEM_POR_PERIODO_1)) {
                                                sql.append("AND (date_part('day', now() - pl.dataContagem) >= ").append(ConstantesSEC.StatusContagem.CONTAGEM_VERMELHO_60_DIAS);
                                                sql.append(" OR pl.dataContagem IS NULL)) ");
                                        } else if (ConstantesSEC.FORMATO_CONTAGEM.equals(ConstantesSEC.ContagemFormato.FORMATO_CONTAGEM_POR_MARCA_2)) {}
                                        sql.append("AND (");
                                }
                                sql.append("pl.produto.sequencial = e.sequencial AND pl.loja.sequencial = ");
                                sql.append(((ParametrosConsultaProdutoDTO)parametros).getLojaSelecionadaParaContagem().getSequencial());
                                sql.append("))) ");
                        }
                        /*
                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametros).getLojaSelecionadaParaContagem())) {
                                sql.append("AND e.modelo is not null ");
                                sql.append("AND EXISTS(SELECT pl FROM ProdutoLoja pl WHERE ");
                                if (VerificadorUtil.naoEstaNuloOuVazio(((ParametrosConsultaProdutoDTO)parametros).getLocalizacaoLojaSelecionada())) {
                                        sql.append("pl.localizacao like upper(:localizacao) AND ");
                                }
                                if (!((ParametrosConsultaProdutoDTO)parametros).getContagemObrigatoria()) {
                                        verificarSeNaoHaTransferenciasDoProduto(sql);

                                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametros).getUsuarioParaContagem())) {
                                                sql.append("AND (");
                                                sql.append("(pl.usuarioUltimaContagemPreparacao != :usuarioParaContagem ");
                                                sql.append("AND pl.indicadorContagemSolicitada IS TRUE) ");
                                                sql.append("OR (pl.usuarioUltimaContagemPreparacao != :usuarioParaContagem ");
                                                sql.append("AND (pl.dataContagem IS NULL ");
                                                sql.append("OR pl.dataContagem < pl.dataContagemPreparacao)) ");
                                                sql.append("OR pl.usuarioUltimaContagemPreparacao.sequencial IS NULL ");
                                                sql.append(") ");
                                        }
                                       
                                        sql.append("AND (pl.indicadorContagemSolicitada IS TRUE ");
                                        sql.append("OR (pl.quantidadeEstoque != 0 AND ");
                                        if (ConstantesSEC.FORMATO_CONTAGEM.equals(ConstantesSEC.ContagemFormato.FORMATO_CONTAGEM_POR_PERIODO_1)) {
                                                sql.append("(date_part('day', now() - pl.dataContagem) >= ").append(ConstantesSEC.StatusContagem.CONTAGEM_VERMELHO_60_DIAS);
                                                sql.append(" OR pl.dataContagem IS NULL)) ");
                                        } else if (ConstantesSEC.FORMATO_CONTAGEM.equals(ConstantesSEC.ContagemFormato.FORMATO_CONTAGEM_POR_MARCA_2)) {
                                                sql.append("pl.produto.modelo.marca.indicadorContagemSolicitada IS TRUE AND ");
                                        }
                                        sql.append("(pl.dataContagem IS NULL OR pl.dataContagemPreparacao IS NULL OR pl.dataContagem < pl.dataContagemPreparacao)) ");
                                        sql.append(") AND (");
                                }
                                sql.append("pl.produto.sequencial = e.sequencial AND pl.loja.sequencial = ");
                                sql.append(((ParametrosConsultaProdutoDTO)parametros).getLojaSelecionadaParaContagem().getSequencial());
                                sql.append("))) ");
                        }
                        */

/*     
                }
        }
       
        private void verificarSeNaoHaTransferenciasDoProduto(StringBuilder sql) {
                sql.append("NOT EXISTS(SELECT (tp) FROM TransferenciaProduto tp ");
                sql.append("WHERE tp.produto.sequencial = pl.produto.sequencial ");
                sql.append("AND tp.transferencia.dataFinalizacao IS NULL ");
                sql.append("AND (tp.transferencia.lojaEntrada.sequencial = pl.loja.sequencial ");
                sql.append("OR tp.transferencia.lojaSaida.sequencial = pl.loja.sequencial)) ");
        }
       
        @Override
        protected void setarQueryParametrosConsulta(Query query, ParametrosConsulta<Produto> parametros) {
                if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getFiltro())) {
                        query.setParameter("filtro", String.format("%06d", new Long(parametros.getFiltro().trim())));
                        if (CodigoBarraEAN.validarCodigoBarras(parametros.getFiltro())) {
                                String codigoRetornado = CodigoBarraEAN.retornarCodigoDoCodigoBarras(parametros.getFiltro());
                                query.setParameter("filtroECCEAN", String.format("%06d", new Long(codigoRetornado.trim())));
                        } else {
                                query.setParameter("filtroECCEAN", String.format("%06d", new Long(parametros.getFiltro().trim())));    
                        }
                        query.setParameter("filtroCEAN", parametros.getFiltro().trim());
                }
                if (VerificadorUtil.naoEstaNulo(parametros.getEntidade())) {
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getCodigo())) {
                                query.setParameter("codigo", parametros.getEntidade().getCodigoProdutoPadrao());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getCodigoRapido())) {
                                query.setParameter("codigoRapido", parametros.getEntidade().getCodigoRapido());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getCodigoEAN())) {
                                if (CodigoBarraEAN.validarCodigoBarras(parametros.getEntidade().getCodigoEAN())) {
                                        query.setParameter("codigoBarras", CodigoBarraEAN.retornarCodigoDoCodigoBarras(parametros.getEntidade().getCodigoEAN()));
                                }
                                query.setParameter("codigoEAN", parametros.getEntidade().getCodigoEAN());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getDescricao())) {
                                query.setParameter("descricao", "%" + removerAcentuacao(parametros.getEntidade().getDescricao()) + "%");
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getTipo())) {
                                query.setParameter("tipoProduto", parametros.getEntidade().getTipo());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getEstilo())) {
                                query.setParameter("estilo", parametros.getEntidade().getEstilo());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getCor())) {
                                query.setParameter("cor", parametros.getEntidade().getCor());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getGenero())) {
                                query.setParameter("tipoGenero", parametros.getEntidade().getGenero());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(parametros.getEntidade().getIndicadorComissionado())) {
                                query.setParameter("indicadorComissionado", parametros.getEntidade().getIndicadorComissionado());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(((ParametrosConsultaProdutoDTO)parametros).getConsultarAtivo())) {
                                query.setParameter("ativo", ((ParametrosConsultaProdutoDTO)parametros).getConsultarAtivo() == 1 );
                        }
                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametros).getModelo())) {
                                query.setParameter("sequencialModelo", ((ParametrosConsultaProdutoDTO)parametros).getModelo().getSequencial());
                        }
                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametros).getMarca())) {
                                query.setParameter("sequencialMarcaDoModelo", ((ParametrosConsultaProdutoDTO)parametros).getMarca().getSequencial());
                        }
                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametros).getFornecedor())) {
                                query.setParameter("sequencialFornecedor", ((ParametrosConsultaProdutoDTO)parametros).getFornecedor().getSequencial());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(((ParametrosConsultaProdutoDTO)parametros).getIndicadorModeloFavorito())) {
                                query.setParameter("indicadorFavorito", ((ParametrosConsultaProdutoDTO)parametros).getIndicadorModeloFavorito());
                        }
                        if (VerificadorUtil.naoEstaNuloOuVazio(((ParametrosConsultaProdutoDTO)parametros).getSujeitoST())) {
                                query.setParameter("sujeitoST", ((ParametrosConsultaProdutoDTO)parametros).getSujeitoST());
                        }
                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametros).getTributacao())) {
                                query.setParameter("tributacao", ((ParametrosConsultaProdutoDTO)parametros).getTributacao());
                        }
                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametros).getLojaSelecionadaParaContagem())) {
                                if (VerificadorUtil.naoEstaNuloOuVazio(((ParametrosConsultaProdutoDTO)parametros).getLocalizacaoLojaSelecionada())) {
                                        query.setParameter("localizacao", "%" + ((ParametrosConsultaProdutoDTO)parametros).getLocalizacaoLojaSelecionada() + "%");
                                }
                        }
                        if (((ParametrosConsultaProdutoDTO)parametros).getIndicadorProdutosSemVendas()) {
                                query.setParameter("dataInicialSemVendas", DataUtils.getDataComHorarioMinimo(((ParametrosConsultaProdutoDTO)parametros).getDataInicialSemVendas()));
                                query.setParameter("dataFinalSemVendas", DataUtils.getDataComHorarioMaximo(((ParametrosConsultaProdutoDTO)parametros).getDataFinalSemVendas()));
                        }
                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametros).getUsuarioParaContagem())) {
                                query.setParameter("usuarioParaContagem", ((ParametrosConsultaProdutoDTO)parametros).getUsuarioParaContagem());
                        }
                }
        }
       
        private void verificarRestricoes(StringBuilder sql, ParametrosConsulta<Produto> parametrosConsulta) {
                clonarProdutoParaAlteracaoParaConsulta(parametrosConsulta);
                prepararVerificacoesRestricoes(parametrosConsulta);
               
                if (((ParametrosConsultaProdutoDTO)parametrosConsulta).getTipoRelatorioProduto().equals(TipoRelatorio.GERAL.getValor())) {
                        sql.append("AND e.modelo.ativo is true ");
                }
               
                if (((ParametrosConsultaProdutoDTO)parametrosConsulta).getTipoRelatorioProduto().equals(TipoRelatorio.PRODUTOS_COM_ESTOQUE.getValor())) {
                        adicionarSqlProdutoComEstoque(sql, parametrosConsulta);
                }
               
                if (((ParametrosConsultaProdutoDTO)parametrosConsulta).getTipoRelatorioProduto().equals(TipoRelatorio.PELICULAS_SEM_ESTOQUE.getValor())) {
                        sql.append("AND e.modelo.ativo is true ");
                        ((ParametrosConsultaProdutoDTO)parametrosConsulta).getProduto().setTipo(TipoProduto.PELICULA.getValor());
                        setarParametrosSemEstoquePorPonto(sql, parametrosConsulta);
                }

                if (((ParametrosConsultaProdutoDTO)parametrosConsulta).getTipoRelatorioProduto().equals(TipoRelatorio.PRODUTOS_SEM_ESTOQUE.getValor())) {
                        sql.append("AND e.modelo.ativo is true ");
                        setarParametrosSemEstoquePorPonto(sql, parametrosConsulta);
                }
               
                if (((ParametrosConsultaProdutoDTO)parametrosConsulta).getTipoRelatorioProduto().equals(TipoRelatorio.RETIRAR_SITE.getValor())) {
                        // RETIRAR DO SITE: SEM ESTOQUE NA MATRIZ, JATIÚCA OU MACEIÓ, EXCETO TPU SOFT
                        ((ParametrosConsultaProdutoDTO)parametrosConsulta).setLojaSelecionada(ConstantesSEC.SEQUENCIAL_MATRIZ_ESTOQUE_9);
                        setarParametrosSemEstoquePorPonto(sql, parametrosConsulta);
                        sql.append("AND e.descricao NOT LIKE '%TPU SOFT%' ");
                        sql.append("AND (NOT EXISTS(SELECT p FROM ProdutoLoja p WHERE p.quantidadeEstoque > 0 ");
                        sql.append("AND p.produto.sequencial = e.sequencial ");
                        sql.append("AND p.loja.sequencial IN (");
                        sql.append(ConstantesSEC.SEQUENCIAL_MATRIZ_ESTOQUE_9);
                        sql.append(", ");
                        sql.append(ConstantesSEC.SEQUENCIAL_QUIOSQUE_BIG_JATIUCA_6);
                        sql.append(", ");
                        sql.append(ConstantesSEC.SEQUENCIAL_LOJA_MACEIO_8);
                        sql.append("))) ");
//                      sql.append(((ParametrosConsultaProdutoDTO)parametrosConsulta).getLojaSelecionada());
//                      sql.append(") AND (SELECT SUM(p.quantidadeEstoque) AS estoque FROM ProdutoLoja p WHERE p.produto.sequencial = e.sequencial) < 2) ");
                        ((ParametrosConsultaProdutoDTO)parametrosConsulta).setConsultarOnline(1);;
                        ((ParametrosConsultaProdutoDTO)parametrosConsulta).setConsultarAtivo(null);
                }
               
                if (((ParametrosConsultaProdutoDTO)parametrosConsulta).getTipoRelatorioProduto().equals(TipoRelatorio.ESTOQUE_INVALIDO.getValor())) {
                        sql.append("AND EXISTS(SELECT p FROM ProdutoLoja p WHERE p.quantidadeEstoque < 0 ");
                        sql.append("AND p.produto.sequencial = e.sequencial");
                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametrosConsulta).getLojaSelecionada())) {
                                sql.append(" AND p.loja.sequencial = ");
                                sql.append(((ParametrosConsultaProdutoDTO)parametrosConsulta).getLojaSelecionada());
                        }
                        sql.append(") ");
                }
               
                if (((ParametrosConsultaProdutoDTO)parametrosConsulta).getTipoRelatorioProduto().equals(TipoRelatorio.ESTOQUE_NAO_FAVORITO.getValor())) {
                        sql.append("AND EXISTS(SELECT p FROM ProdutoLoja p WHERE p.quantidadeEstoque > 0 ");
                        sql.append("AND p.produto.modelo.indicadorFavorito IS FALSE ");
                        sql.append("AND p.produto.sequencial = e.sequencial ");
                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametrosConsulta).getLojaSelecionada())) {
                                sql.append("AND p.loja.sequencial = ");
                                sql.append(((ParametrosConsultaProdutoDTO)parametrosConsulta).getLojaSelecionada());
                        }
                        sql.append(") ");
                }
               
                if (((ParametrosConsultaProdutoDTO)parametrosConsulta).getTipoRelatorioProduto().equals(TipoRelatorio.CONTAGENS_PENDENTES.getValor())) {
                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametrosConsulta).getLojaSelecionada())) {
                                ((ParametrosConsultaProdutoDTO)parametrosConsulta).setLojaSelecionadaParaContagem(new Loja(((ParametrosConsultaProdutoDTO)parametrosConsulta).getLojaSelecionada()));
                        }
                        ((ParametrosConsultaProdutoDTO)parametrosConsulta).setConsultarAtivo(1);
                }
               
                if (((ParametrosConsultaProdutoDTO)parametrosConsulta).getTipoRelatorioProduto().equals(TipoRelatorio.PROMOCOES.getValor())) {
                        sql.append("AND e.valorVarejoPromocional is not null ");
                        sql.append("AND e.valorVarejoPromocional > 0 ");
                }
               
                if (((ParametrosConsultaProdutoDTO)parametrosConsulta).getIndicadorProdutosSemVendas()) {
                        sql.append("AND NOT EXISTS(SELECT l FROM Lancamento l WHERE l.produto.sequencial = e.sequencial ");
                        sql.append("AND l.venda.dataVenda >= :dataInicialSemVendas AND l.venda.dataVenda <= :dataFinalSemVendas ");
                        if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametrosConsulta).getLojaSelecionada())) {
                                sql.append(" AND l.venda.loja.sequencial = ");
                                sql.append(((ParametrosConsultaProdutoDTO)parametrosConsulta).getLojaSelecionada());
                        }
                        sql.append(") ");
                }
        }

        private void adicionarSqlProdutoComEstoque(StringBuilder sql, ParametrosConsulta<Produto> parametrosConsulta) {
                sql.append("AND EXISTS(SELECT p FROM ProdutoLoja p WHERE p.quantidadeEstoque > 0 ");
                sql.append("AND p.produto.sequencial = e.sequencial");
                if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametrosConsulta).getLojaSelecionada())) {
                        sql.append(" AND p.loja.sequencial = ");
                        sql.append(((ParametrosConsultaProdutoDTO)parametrosConsulta).getLojaSelecionada());
                }
                sql.append(") ");
        }

        private void clonarProdutoParaAlteracaoParaConsulta(ParametrosConsulta<Produto> parametrosConsulta) {
                try {
                        ((ParametrosConsultaProdutoDTO)parametrosConsulta).setProduto(((ParametrosConsultaProdutoDTO)parametrosConsulta).getProduto().clone());
                } catch (CloneNotSupportedException e) {
                        e.printStackTrace();
                }
        }

        private void prepararVerificacoesRestricoes(ParametrosConsulta<Produto> parametrosConsulta) {
                ((ParametrosConsultaProdutoDTO)parametrosConsulta).getProduto().setIndicadorOnline(null);
                ((ParametrosConsultaProdutoDTO)parametrosConsulta).getProduto().setIndicadorOnlineMercadoLivre(null);
                ((ParametrosConsultaProdutoDTO)parametrosConsulta).getProduto().setDataOnline(null);
        }

        private void setarParametrosSemEstoquePorPonto(StringBuilder sql, ParametrosConsulta<Produto> parametrosConsulta) {
                sql.append("AND NOT EXISTS(SELECT p FROM ProdutoLoja p WHERE p.quantidadeEstoque > 0 ");
                sql.append("AND p.produto.sequencial = e.sequencial");
                if (VerificadorUtil.naoEstaNulo(((ParametrosConsultaProdutoDTO)parametrosConsulta).getLojaSelecionada())) {
                        sql.append(" AND p.loja.sequencial = ");
                        sql.append(((ParametrosConsultaProdutoDTO)parametrosConsulta).getLojaSelecionada());
                }
                sql.append(") ");
        }

        @Override
        public Produto consultarProdutoPorCodigoEAN(String codigoEAN) {
                StringBuilder sql = new StringBuilder();
                sql.append("SELECT e FROM Produto e ");
                sql.append("WHERE e.codigoEAN = :codigoEAN");
                if (CodigoBarraEAN.validarCodigoBarras(codigoEAN)) {
                        sql.append(" OR e.codigo = :codigoBarras");
                }
                try {
                        Query query = getEntityManager().createQuery(sql.toString(), Produto.class).setParameter("codigoEAN", codigoEAN);
                        if (CodigoBarraEAN.validarCodigoBarras(codigoEAN)) {
                                query.setParameter("codigoBarras", CodigoBarraEAN.retornarCodigoDoCodigoBarras(codigoEAN));
                        }
                        return (Produto) query.getSingleResult();
                } catch(Exception ex) {
                        ex.printStackTrace();
                        return null;
                }
        }

        @Override
        public Produto consultarProdutoPorCodigoRapido(String codigoRapido) {
                StringBuilder sql = new StringBuilder();
                sql.append("SELECT e FROM Produto e ");
                sql.append("WHERE e.codigoRapido = :codigoRapido");
                try {
                        return getEntityManager().createQuery(sql.toString(), Produto.class).setParameter("codigoRapido", codigoRapido).getSingleResult();
                } catch(Exception ex) {
                        ex.printStackTrace();
                        return null;
                }
        }
       
        @Override
        public Long consultarUltimoCodigo() {
                StringBuilder sql = new StringBuilder();
                sql.append("SELECT MAX(CAST(coalesce(p.cod_produto, '0') AS integer)) ");
                sql.append("FROM sc_sec.sec_produto p ");
                sql.append("WHERE p.cod_produto not like '000000'");
                try {
                        return new Long(getEntityManager().createNativeQuery(sql.toString()).getSingleResult().toString());
                } catch(Exception ex) {
                        ex.printStackTrace();
                        return null;
                }
        }
       
        @Override
        public Integer quantidadeTotalEstoque(Loja loja) {
                StringBuilder sql = new StringBuilder();
                sql.append("SELECT SUM(e.quantidadeEstoque) FROM ProdutoLoja e WHERE e.produto.codigo != '000000'");
                if (VerificadorUtil.naoEstaNulo(loja)) {
                        sql.append(" AND e.loja.sequencial = :sequencialLoja");
                }
                try {
                        Long quantidadeTotal = new Long(0);
                        TypedQuery<Long> query =  getEntityManager().createQuery(sql.toString(), Long.class);
                        if (VerificadorUtil.naoEstaNulo(loja)) {
                                query.setParameter("sequencialLoja", loja.getSequencial());
                        }
                        quantidadeTotal = query.getSingleResult();
                        if (VerificadorUtil.naoEstaNulo(quantidadeTotal)) {
                                return quantidadeTotal.intValue();
                        }
                        return 0;
                } catch(Exception ex) {
                        ex.printStackTrace();
                        return 0;
                }
        }
       
       
       
        @Override
        public Integer quantidadeEstoque(ParametrosConsultaProdutoDTO parametrosConsulta) {
                StringBuilder sql = new StringBuilder("SELECT SUM(pl.quantidadeEstoque) FROM ProdutoLoja pl WHERE pl.produto.codigo != '000000'");
                try {
                        setarStringParametrosConsulta(sql, parametrosConsulta);
                        String sqlAlterado = sql.toString().replace(" e.", " pl.produto.").replace("(e.", "(pl.produto.");
                        TypedQuery<Long> query = getEntityManager().createQuery(sqlAlterado, Long.class);
                        setarQueryParametrosConsulta(query, parametrosConsulta);
                        Long quantidade = query.getSingleResult();
                        if (VerificadorUtil.naoEstaNulo(quantidade)) {
                                return quantidade.intValue();
                        }
                        return 0;
                } catch(Exception ex) {
                        ex.printStackTrace();
                        return 0;
                }
        }
       
        @Override
        public Integer quantidadeEstoque(ParametrosConsultaProdutoDTO parametrosConsulta, Long sequencialLoja) {
                StringBuilder sql = new StringBuilder("SELECT SUM(pl.quantidadeEstoque) FROM ProdutoLoja pl WHERE pl.produto.codigo != '000000'");
                try {
                        setarStringParametrosConsulta(sql, parametrosConsulta);
                        sql.append("AND pl.loja.sequencial = :sequencialLoja ");
                        String sqlAlterado = sql.toString().replace(" e.", " pl.produto.").replace("(e.", "(pl.produto.");
                        TypedQuery<Long> query = getEntityManager().createQuery(sqlAlterado, Long.class);
                        setarQueryParametrosConsulta(query, parametrosConsulta);
                        query.setParameter("sequencialLoja", sequencialLoja);
                        Long quantidade = query.getSingleResult();
                        if (VerificadorUtil.naoEstaNulo(quantidade)) {
                                return quantidade.intValue();
                        }
                        return 0;
                } catch(Exception ex) {
                        ex.printStackTrace();
                        return 0;
                }
        }
*/
     
        /*
        @Override
        public Integer quantidadeContagens(Long sequencialLoja) {
                StringBuilder sql = new StringBuilder("SELECT COUNT(pl) FROM ProdutoLoja pl WHERE pl.loja.sequencial = :sequencialLoja");
                try {
                        sql.append(" AND (");
                        sql.append("SELECT COUNT(*) FROM TransferenciaProduto tp ");
                        sql.append("WHERE tp.produto = pl.produto AND tp.transferencia.dataFinalizacao is null ");
                        sql.append("AND (tp.transferencia.lojaSaida.sequencial = :sequencialLoja OR tp.transferencia.lojaEntrada.sequencial = :sequencialLoja)");
                        sql.append(")=0 ");
                        sql.append(" AND (");
                        sql.append("(pl.indicadorContagemSolicitada IS TRUE)");
                        sql.append(" OR ");
                        sql.append("(pl.quantidadeEstoque != 0");
                        sql.append(" AND (date_part('day', now() - pl.dataContagem) >= ").append(ConstantesSEC.StatusContagem.CONTAGEM_VERMELHO_60_DIAS);
                        sql.append(" OR pl.dataContagem is null)))");
                       
                        TypedQuery<Long> query = getEntityManager().createQuery(sql.toString(), Long.class);
                        query.setParameter("sequencialLoja", sequencialLoja);
                        Long quantidade = query.getSingleResult();
                        if (VerificadorUtil.naoEstaNulo(quantidade)) {
                                return quantidade.intValue();
                        }
                        return 0;
                } catch(Exception ex) {
                        ex.printStackTrace();
                }
                return 0;
        }
        */

/*             
       
        @Override
        public Date dataUltimaVenda(Produto produto) {
                StringBuilder sql = new StringBuilder();
                sql.append("SELECT MAX(e.dataVenda) FROM Venda e ");
                sql.append("LEFT JOIN e.listaLancamentos l ");
                sql.append("WHERE l.ativo IS TRUE ");
                sql.append("AND l.produto.sequencial = :sequencialProduto ");
                try {
                        TypedQuery<Date> query = getEntityManager().createQuery(sql.toString(), Date.class);
                        query.setParameter("sequencialProduto", produto.getSequencial());
                        return query.getSingleResult();
                } catch(Exception ex) {
                        ex.printStackTrace();
                }
                return null;
        }
       
        @Override
        public Integer quantidadeProdutosAdicionadosSite(Date dataInicial, Date dataFinal) {
                StringBuilder sql = new StringBuilder();
                sql.append("SELECT COUNT(p) FROM Produto p ");
                sql.append("WHERE p.dataOnline >= :dataInicial AND p.dataOnline <= :dataFinal ");
                try {
                        TypedQuery<Long> query = getEntityManager().createQuery(sql.toString(), Long.class);
                        query.setParameter("dataInicial", DataUtils.getDataComHorarioMinimo(dataInicial));
                        query.setParameter("dataFinal", DataUtils.getDataComHorarioMaximo(dataFinal));
                        return query.getSingleResult().intValue();
                } catch(Exception ex) {
                        ex.printStackTrace();
                }
                return null;
        }
       
        @Override
        public Integer quantidadeProdutosOnline() {
                StringBuilder sql = new StringBuilder();
                sql.append("SELECT COUNT(p) FROM Produto p ");
                sql.append("WHERE p.dataOnline IS NOT NULL ");
                try {
                        return getEntityManager().createQuery(sql.toString(), Long.class).getSingleResult().intValue();
                } catch(Exception ex) {
                        ex.printStackTrace();
                }
                return null;
        }
       
        @Override
        public Integer quantidadeProdutosFavoritosOffline(Loja loja) {
                StringBuilder sql = new StringBuilder();
                sql.append("SELECT COUNT(e) FROM Produto e ");
                sql.append("WHERE e.dataOnline IS NULL AND e.modelo.indicadorFavorito IS TRUE ");
                sql.append("AND EXISTS(SELECT p FROM ProdutoLoja p WHERE p.quantidadeEstoque > 0 ");
                sql.append("AND p.produto.sequencial = e.sequencial ");
                if (VerificadorUtil.naoEstaNulo(loja)) {
                        sql.append("AND p.loja.sequencial = :sequencialLoja");
                }
                sql.append(") ");
                try {
                        TypedQuery<Long> query = getEntityManager().createQuery(sql.toString(), Long.class);
                        if (VerificadorUtil.naoEstaNulo(loja)) {
                                query.setParameter("sequencialLoja", loja.getSequencial());
                        }
                        return query.getSingleResult().intValue();
                } catch(Exception ex) {
                        ex.printStackTrace();
                }
                return null;
        }
       
        @Override
        public List<ProdutoHistoricoDTO> consultarHistoricoDeEntradas(Produto produto, Loja loja, Date dataInicial, Date dataFinal) {
                List<ProdutoHistoricoDTO> historico = new ArrayList<ProdutoHistoricoDTO>();
                historico.addAll(consultarHistoricoProduto(produto, dataInicial, dataFinal, TipoLancamentoHistorico.COMPRAS.getValor(), loja));
                historico.addAll(consultarHistoricoProduto(produto, dataInicial, dataFinal, TipoLancamentoHistorico.CONTAGENS_ENTRADA.getValor(), loja));
                return historico;
        }
       
        @Override
        public List<ProdutoHistoricoDTO> consultarHistoricoDeSaidas(Produto produto, Loja loja, Date dataInicial, Date dataFinal) {
                List<ProdutoHistoricoDTO> historico = new ArrayList<ProdutoHistoricoDTO>();
                historico.addAll(consultarHistoricoProduto(produto, dataInicial, dataFinal, TipoLancamentoHistorico.VENDAS.getValor(), loja));
                historico.addAll(consultarHistoricoProduto(produto, dataInicial, dataFinal, TipoLancamentoHistorico.AVARIAS.getValor(), loja));
                historico.addAll(consultarHistoricoProduto(produto, dataInicial, dataFinal, TipoLancamentoHistorico.TROCAS.getValor(), loja));
                historico.addAll(consultarHistoricoProduto(produto, dataInicial, dataFinal, TipoLancamentoHistorico.CONTAGENS_SAIDA.getValor(), loja));
                return historico;
        }
       
        @Override
        public List<ProdutoHistoricoDTO> consultarHistorico(Produto produto, Date dataInicial, Date dataFinal) {
                List<ProdutoHistoricoDTO> historico = new ArrayList<ProdutoHistoricoDTO>();
                historico.addAll(consultarHistoricoProduto(produto, dataInicial, dataFinal, TipoLancamentoHistorico.COMPRAS.getValor(), null));
                historico.addAll(consultarHistoricoProduto(produto, dataInicial, dataFinal, TipoLancamentoHistorico.VENDAS.getValor(), null));
                historico.addAll(consultarHistoricoProduto(produto, dataInicial, dataFinal, TipoLancamentoHistorico.AVARIAS.getValor(), null));
                historico.addAll(consultarHistoricoProduto(produto, dataInicial, dataFinal, TipoLancamentoHistorico.TROCAS.getValor(), null));
                historico.addAll(consultarHistoricoProduto(produto, dataInicial, dataFinal, TipoLancamentoHistorico.DEVOLUCOES.getValor(), null));
                historico.addAll(consultarHistoricoProduto(produto, dataInicial, dataFinal, TipoLancamentoHistorico.CONTAGENS_ENTRADA.getValor(), null));
                historico.addAll(consultarHistoricoProduto(produto, dataInicial, dataFinal, TipoLancamentoHistorico.CONTAGENS_SAIDA.getValor(), null));
                return historico;
        }
       
        private List<ProdutoHistoricoDTO> consultarHistoricoProduto(Produto produto, Date dataInicial, Date dataFinal, String tipoLancamento, Loja loja) {
                StringBuilder sql = new StringBuilder();
                sql.append("SELECT ");
                sql.append("new br.com.ec.domain.dto.ProdutoHistoricoDTO(e.produto, ");
                sql.append("'" + (DataUtils.obterCalendario(dataInicial).get(Calendar.MONTH)+1) + "', ");
                sql.append("'" + DataUtils.obterCalendario(dataInicial).get(Calendar.YEAR) + "', ");
               
                if (tipoLancamento.equals(TipoLancamentoHistorico.VENDAS.getValor())) {
                        sql.append("SUM(e.valorVenda), COUNT(e.produto), ");
                        sql.append("'" + tipoLancamento + "') ");
                        sql.append("FROM Lancamento e ");
                        sql.append("WHERE e.venda.dataVenda >= :dataInicial AND e.venda.dataVenda <= :dataFinal ");
                        if (VerificadorUtil.naoEstaNulo(loja)) {
                                sql.append("AND e.venda.loja <= :loja ");
                        }
                }
               
                if (tipoLancamento.equals(TipoLancamentoHistorico.COMPRAS.getValor())) {
                        sql.append("MAX(e.valorCompra), SUM(e.quantidade), ");
                        sql.append("'" + tipoLancamento + "') ");
                        sql.append("FROM CompraProduto e ");
                        sql.append("WHERE e.compra.dataCompra >= :dataInicial AND e.compra.dataCompra <= :dataFinal ");
                        if (VerificadorUtil.naoEstaNulo(loja)) {
                                sql.append("AND e.compra.loja <= :loja ");
                        }
                }
               
                if (tipoLancamento.equals(TipoLancamentoHistorico.AVARIAS.getValor())) {
                        sql.append(sqlAuditoria(tipoLancamento, TipoEstoqueAuditoria.AVARIA.getValor(), loja));
                }
               
                if (tipoLancamento.equals(TipoLancamentoHistorico.TROCAS.getValor())) {
                        sql.append(sqlAuditoria(tipoLancamento, TipoEstoqueAuditoria.TROCA.getValor(), loja));
                }
               
                if (tipoLancamento.equals(TipoLancamentoHistorico.DEVOLUCOES.getValor())) {
                        sql.append(sqlAuditoria(tipoLancamento, TipoEstoqueAuditoria.DEVOLUCAO.getValor(), loja));
                }
               
                if (tipoLancamento.equals(TipoLancamentoHistorico.CONTAGENS_ENTRADA.getValor())) {
                        sql.append(sqlAuditoria(tipoLancamento, TipoEstoqueAuditoria.CONTAGEM.getValor(), loja));
                        sql.append("AND e.quantidadeEstoqueAnterior < e.quantidadeEstoqueNovo ");
                }
               
                if (tipoLancamento.equals(TipoLancamentoHistorico.CONTAGENS_SAIDA.getValor())) {
                        sql.append(sqlAuditoria(tipoLancamento, TipoEstoqueAuditoria.CONTAGEM.getValor(), loja));
                        sql.append("AND e.quantidadeEstoqueAnterior > e.quantidadeEstoqueNovo ");
                }
               
                if (VerificadorUtil.naoEstaNulo(produto)) {
                        if (VerificadorUtil.naoEstaNuloOuVazio(produto.getSequencial())) {
                                sql.append("AND e.produto.sequencial = :sequencialProduto ");
                        }
                }
                sql.append("GROUP BY e.produto ");
                try {
                        TypedQuery<ProdutoHistoricoDTO> query = getEntityManager().createQuery(sql.toString(), ProdutoHistoricoDTO.class);
                        if (VerificadorUtil.naoEstaNulo(loja)) {
                                query.setParameter("dataInicial", dataInicial);
                                query.setParameter("dataFinal", dataFinal);
                        } else {
                                query.setParameter("dataInicial", DataUtils.getDataComHorarioMinimo(dataInicial));
                                query.setParameter("dataFinal", DataUtils.getDataComHorarioMaximo(dataFinal));
                        }
                        if (VerificadorUtil.naoEstaNulo(produto)) {
                                if (VerificadorUtil.naoEstaNuloOuVazio(produto.getSequencial())) {
                                        query.setParameter("sequencialProduto", produto.getSequencial());
                                }
                                if (VerificadorUtil.naoEstaNulo(loja)) {
                                        query.setParameter("loja", loja);
                                }
                        }
                        return query.getResultList();
                } catch(Exception ex) {
                        ex.printStackTrace();
                        return null;
                }
        }

        private String sqlAuditoria(String tipoLancamento, String tipoEstoqueAuditoria, Loja loja) {
                StringBuilder sql = new StringBuilder();
                sql.append("0.0, COUNT(e.produto), ");
                sql.append("'" + tipoLancamento + "') ");
                sql.append("FROM EstoqueAuditoria e ");
                sql.append("WHERE e.dataAtualizacao >= :dataInicial AND e.dataAtualizacao <= :dataFinal ");
                sql.append("AND e.tipoEstoqueAuditoria like '" + tipoEstoqueAuditoria + "' ");
                if (VerificadorUtil.naoEstaNulo(loja)) {
                        sql.append("AND e.loja = :loja ");
                }
                return sql.toString();
        }
       
        @Override
        public List<ProdutoHistoricoDetalhesDTO> detalharHistorico(ProdutoHistoricoDTO produtoHistorico, Date dataInicial, Date dataFinal) {
                StringBuilder sql = new StringBuilder();
                sql.append("SELECT ");
                sql.append("new br.com.ec.domain.dto.ProdutoHistoricoDetalhesDTO(");
               
                if (produtoHistorico.getTipoLancamento().equals(TipoLancamentoHistorico.VENDAS.getValor())) {
                        sql.append("e.venda.sequencial, (SELECT v.nome FROM Vendedor v WHERE v.sequencial = e.venda.vendedor.sequencial), ");
                        sql.append("e.venda.loja, e.venda.dataVenda, e.valorVenda, ");
                        sql.append("'" + produtoHistorico.getTipoLancamento() + "', e.observacao) ");
                        sql.append("FROM Lancamento e ");
                        sql.append("WHERE e.venda.dataVenda >= :dataInicial AND e.venda.dataVenda <= :dataFinal ");
                        if (VerificadorUtil.naoEstaNulo(produtoHistorico.getProduto())) {
                                if (VerificadorUtil.naoEstaNuloOuVazio(produtoHistorico.getProduto().getSequencial())) {
                                        sql.append("AND e.produto.sequencial = :sequencialProduto ");
                                }
                        }
                        sql.append("ORDER BY e.venda.dataVenda DESC");
                }
               
                if (produtoHistorico.getTipoLancamento().equals(TipoLancamentoHistorico.COMPRAS.getValor())) {
                        sql.append("e.compra.sequencial, e.compra.dataCompra, e.valorCompra, e.quantidade, ");
                        sql.append("(SELECT f FROM Fornecedor f WHERE f = e.compra.fornecedor), ");
                        sql.append("'" + produtoHistorico.getTipoLancamento() + "', e.compra.observacao) ");
                        sql.append("FROM CompraProduto e ");
                        sql.append("WHERE e.compra.dataCompra >= :dataInicial AND e.compra.dataCompra <= :dataFinal ");
                        if (VerificadorUtil.naoEstaNulo(produtoHistorico.getProduto())) {
                                if (VerificadorUtil.naoEstaNuloOuVazio(produtoHistorico.getProduto().getSequencial())) {
                                        sql.append("AND e.produto.sequencial = :sequencialProduto ");
                                }
                        }
                        sql.append("ORDER BY e.compra.dataCompra DESC");
                }
               
                if (produtoHistorico.getTipoLancamento().equals(TipoLancamentoHistorico.AVARIAS.getValor())) {
                        sql.append(sqlAuditoriaDetalhe(produtoHistorico, TipoEstoqueAuditoria.AVARIA.getValor()));
                        sql.append("ORDER BY e.dataAtualizacao DESC");
                }
               
                if (produtoHistorico.getTipoLancamento().equals(TipoLancamentoHistorico.TROCAS.getValor())) {
                        sql.append(sqlAuditoriaDetalhe(produtoHistorico, TipoEstoqueAuditoria.TROCA.getValor()));
                        sql.append("ORDER BY e.dataAtualizacao DESC");
                }
               
                if (produtoHistorico.getTipoLancamento().equals(TipoLancamentoHistorico.DEVOLUCOES.getValor())) {
                        sql.append(sqlAuditoriaDetalhe(produtoHistorico, TipoEstoqueAuditoria.DEVOLUCAO.getValor()));
                        sql.append("ORDER BY e.dataAtualizacao DESC");
                }
               
                if (produtoHistorico.getTipoLancamento().equals(TipoLancamentoHistorico.CONTAGENS_ENTRADA.getValor())) {
                        sql.append(sqlAuditoriaDetalhe(produtoHistorico, TipoEstoqueAuditoria.CONTAGEM.getValor()));
                        sql.append("AND e.quantidadeEstoqueAnterior < e.quantidadeEstoqueNovo ");
                        sql.append("ORDER BY e.dataAtualizacao DESC");
                }
               
                if (produtoHistorico.getTipoLancamento().equals(TipoLancamentoHistorico.CONTAGENS_SAIDA.getValor())) {
                        sql.append(sqlAuditoriaDetalhe(produtoHistorico, TipoEstoqueAuditoria.CONTAGEM.getValor()));
                        sql.append("AND e.quantidadeEstoqueAnterior > e.quantidadeEstoqueNovo ");
                        sql.append("ORDER BY e.dataAtualizacao DESC");
                }
               
                try {
                        TypedQuery<ProdutoHistoricoDetalhesDTO> query = getEntityManager().createQuery(sql.toString(), ProdutoHistoricoDetalhesDTO.class)
                                        .setParameter("dataInicial", DataUtils.getDataComHorarioMinimo(dataInicial))
                                        .setParameter("dataFinal", DataUtils.getDataComHorarioMaximo(dataFinal));
                        if (VerificadorUtil.naoEstaNulo(produtoHistorico.getProduto())) {
                                if (VerificadorUtil.naoEstaNuloOuVazio(produtoHistorico.getProduto().getSequencial())) {
                                        query.setParameter("sequencialProduto", produtoHistorico.getProduto().getSequencial());
                                }
                        }
                        return query.getResultList();
                } catch(Exception ex) {
                        ex.printStackTrace();
                        return null;
                }
        }
       
        private String sqlAuditoriaDetalhe(ProdutoHistoricoDTO produtoHistorico, String tipoEstoqueAuditoria) {
                StringBuilder sql = new StringBuilder();
                sql.append("e.sequencial, (SELECT u.nome FROM Usuario u WHERE u.sequencial = e.usuario.sequencial), e.loja, e.dataAtualizacao, 0.0, ");
                sql.append("'" + produtoHistorico.getTipoLancamento() + "'");
                if (tipoEstoqueAuditoria.equals(TipoEstoqueAuditoria.CONTAGEM.getValor())) {
                        sql.append(", e.quantidadeEstoqueNovo - e.quantidadeEstoqueAnterior");
                }
                sql.append(", e.observacao) ");
                sql.append("FROM EstoqueAuditoria e ");
                sql.append("WHERE e.dataAtualizacao >= :dataInicial AND e.dataAtualizacao <= :dataFinal ");
                sql.append("AND e.tipoEstoqueAuditoria like '" + tipoEstoqueAuditoria + "' ");
                if (VerificadorUtil.naoEstaNulo(produtoHistorico.getProduto())) {
                        if (VerificadorUtil.naoEstaNuloOuVazio(produtoHistorico.getProduto().getSequencial())) {
                                sql.append("AND e.produto.sequencial = :sequencialProduto ");
                        }
                }
                return sql.toString();
        }
        */

       
}