Neste guia serão abordadas as funcionalidades relacionadas a Pesquisa Combinatória, voltadas aos desenvolvedores do Bematech ERP, dando a visão a quem irá implementar melhorias no sistema utilizando o objeto de responsável pela escolha do melhor registro em cadastros e/ou configurações utilizando o conceito de pesquisa combinatória.
O objetivo deste guia é orientar como utilizar as APIs disponibilizadas para manipular uma Pesquisa Combinatória onde iremos explanar desde o conceito da pesquisa combinatória e quais os pré-requisitos para utilizar esta funcionalidade no sistema.
Considerando-se a complexidade de um ERP, não serão descritos nesse guia termos introdutórios do sistema.
Para a perfeita compreensão do uso do objetos responsável pela Pesquisa Combinatória se faz necessário entender sua abrangência e estar familiarizado com a linguagem do sistema Bematech ERP. Devemos iniciar tendo uma visão de como desenvolver no sistema Bematech ERP, portanto realize a leitura do Guia de estudo da Plataforma Bematech ERP, além disso é necessário que o leitor tenha o conhecimento de uso e dos conceitos do Bematech ERP e principalmente sobre a estrutura da classe de Configuração e classe de Dados do ERP.
De forma macro, a pesquisa combinatória pode ser utilizada para a pesquisa de registros, em uma classe de dados, de acordo com os filtros informados pelo usuário e considerando as configurações feitas em uma classe de configuração.
O objeto responsável pela pesquisa é o PesquisaCombinatoria. O PesquisaCombinatoria tem como principal API o método consultar. Lembrando que precisa ser informado para a pesquisa em qual universo será realizada a pesquisa dos registros, ou seja, precisa ser informada a tabela referente a classe de dados que se deseja que a pesquisa seja realizada. Também é obrigatório informar a classe de configuração, que determina a ordem de prioridade dos filtros, dentre outras configurações.
Ao consumir o objeto PesquisaCombinatoria através do uso do método consultar são pesquisados todas as possíveis combinações de valores dos filtros, incluindo classes mãe, caso o filtro seja de classe, até que um registro seja localizado ou seja atingido o máximo de combinações possíveis. Ao ler a palavra pesquisa, entenda-se como cada tentativa de se achar um valor válido na classe de dados e não ao ato de se invocar o método consultar().
Para uma melhor visão de como utilizar o PesquisaCombinatoria abaixo serão listados os principais casos de uso e a explicação de quais as APIs devem ser utilizadas.
Ao realizar a instância do PesquisaCombinatoria deve-se passar qual a classe de configuração que desejamos instanciar. Essa classe de configuração contém a configuração dos filtros, indicando sua ordem na pesquisa e se ele é de classe, registro, data, hora ou usuario/grupo. O PesquisaCombinatoria pode receber uma classe de configuração com os filtros ou um objeto literal com a configuração dos filtros.
var pesquisa = new PesquisaCombinatoria( <informar a chave da classe de configuração da Pesquisa> );
Exemplo de idbc realizando a instância do PesquisaCombinatoria utilizando a classe de configuração do cadastro de Sugestão de Classe. Assim como Sugestão de Classe podem ser utilizadas qualquer classe de configuração de filtros para pesquisa combinatória.
__includeOnce(-1898141835); // /products/INTEQengine/configuration/iDBCsql library.ijs
__includeOnce(-1897036688); // /products/INTEQerp infrastructure/library/pesquisa/PesquisaCombinatoria.ijs
var classeConfiguracao = -1894443734 /* Sugestão de Classe */;
var pesquisa = new PesquisaCombinatoria(classeConfiguracao);
Para realizar uma consulta devemos iniciar instanciando o objeto PesquisaCombinatoria passando a classe de configuração que iremos utilizar.
__includeOnce(-1898141835); // /products/INTEQengine/configuration/iDBCsql library.ijs
__includeOnce(-1897036688); // /products/INTEQerp infrastructure/library/pesquisa/PesquisaCombinatoria.ijs
var classeConfiguracao = -1894443734 /* Sugestão de Classe */;
var pesquisa = new PesquisaCombinatoria(classeConfiguracao);
Os cadastros que utilizam pesquisa combinatória normalmente são criados em classes de cache, dessa forma podemos passar para a propriedade dados do objeto PesquisaCombinatoria uma visão do cache local da classe de dados criada ou um dataset com os registros que se deseja que a consulta seja efetuada.
var classeDados = -1896647597 /* Sugestão de Classe de Pedido ou Provisão */;
var dados = classes.getCachedDataSet(classeDados);
pesquisa.dados = dados;
Para efetuar a consulta precisamos preencher os filtros da pesquisa combinatória de acordo com as informações passadas pelo usuário.
Exemplo de idbc preenchendo os filtros da pesquisa combinatória de acordo com as informações passadas pelo usuário.
pesquisa.filtro.pessoa = 3478816 /* Paula Souza */;
pesquisa.filtro.comportfis = -1899999164 /* Não Contribuinte */;
pesquisa.filtro.locescritu = 408425 /* Unum LocEscritu */;
pesquisa.filtro.classepedido = -1899998925 /* C p Consumo */;
pesquisa.filtro.recurso = 42354 /* ANTENA TV */;
pesquisa.filtro.nucleo =36925844 /* Almox Análise */;
pesquisa.filtro.tiposaida = -1894743958 /* Normal */;
Veja que o filtro "classerecurso" não foi preenchido, isso porque o filtro "recurso" tem filtro associado de classe e dessa forma não é necessário informar o filtro de classe, informado apenas o filtro de registro.
consultando um único registro válido de maior prioridade
Para realizar uma consulta devemos iniciar instanciando o objeto PesquisaCombinatoria passando a classe de configuração que iremos utilizar.
__includeOnce(-1898141835); // /products/INTEQengine/configuration/iDBCsql library.ijs
__includeOnce(-1897036688); // /products/INTEQerp infrastructure/library/pesquisa/PesquisaCombinatoria.ijs
var classeConfiguracao = -1894443734 /* Sugestão de Classe */;
var pesquisa = new PesquisaCombinatoria(classeConfiguracao);
Em seguida devemos passar para a propriedade dados uma visão do cache local da classe de dados criada.
var classeDados = -1896647597 /* Sugestão de Classe de Pedido ou Provisão */;
var dados = classes.getCachedDataSet(classeDados);
pesquisa.dados = dados;
Em seguida devemos preencher os filtros da pesquisa combinatória de acordo com as informações passadas pelo usuário.
pesquisa.filtro.pessoa = 3478816 /* Paula Souza */;
pesquisa.filtro.comportfis = -1899999164 /* Não Contribuinte */;
pesquisa.filtro.locescritu = 408425 /* Unum LocEscritu */;
pesquisa.filtro.classepedido = -1899998925 /* C p Consumo */;
pesquisa.filtro.recurso = 42354 /* ANTENA TV */;
pesquisa.filtro.nucleo =36925844 /* Almox Análise */;
pesquisa.filtro.tiposaida = -1894743958 /* Normal */;
Em seguida devemos utilizar o método consultar que tem o retorno de acordo com os parâmetros recebidos.
O primeiro parâmetro é um booleano indicando se retorna todas as chaves dos registros válidos independente da ordem de prioridade.
O segundo parâmetro é um booleano indicando se o retorna deve ser um dataset, caso seja informado false o retorno é um objeto literal contendo as propriedades "chave" e "prioridade".
O terceiro parâmetro é um booleano indicando se retorna todas as chaves dos registros válidos, apenas da prioridade máxima.
Portanto para que a consulta traga como resultado um único registro válido de maior prioridade deve ser passado false para o primeiro e terceiro parâmetro.
var resultado = pesquisa.consultar(false, true, false);
Exemplo completo no idbc. Há necessidade de trocar as chaves informadas por uma chave da base onde está sendo executado.
__includeOnce(-1898141835); // /products/INTEQengine/configuration/iDBCsql library.ijs
__includeOnce(-1897036688); // /products/INTEQerp infrastructure/library/pesquisa/PesquisaCombinatoria.ijs
var classeConfiguracao = -1894443734 /* Sugestão de Classe */;
var classeDados = -1896647597 /* Sugestão de Classe de Pedido ou Provisão */;
var dados = classes.getCachedDataSet(classeDados);
var pesquisa = new PesquisaCombinatoria(classeConfiguracao);
pesquisa.dados = dados;
pesquisa.filtro.pessoa = 3478816 /* Paula Souza */;
pesquisa.filtro.comportfis = -1899999164 /* Não Contribuinte */;
pesquisa.filtro.locescritu = 408425 /* Unum LocEscritu */;
pesquisa.filtro.classepedido = -1899998925 /* C p Consumo */;
pesquisa.filtro.recurso = 42354 /* ANTENA TV */;
pesquisa.filtro.nucleo =36925844 /* Almox Análise */;
pesquisa.filtro.tiposaida = -1894743958 /* Normal */;
var resultado = pesquisa.consultar(false, true, false);
consultando todos os registros válidos de maior prioridade
Para realizar uma consulta devemos iniciar instanciando o objeto PesquisaCombinatoria passando a classe de configuração que iremos utilizar.
__includeOnce(-1898141835); // /products/INTEQengine/configuration/iDBCsql library.ijs
__includeOnce(-1897036688); // /products/INTEQerp infrastructure/library/pesquisa/PesquisaCombinatoria.ijs
var classeConfiguracao = -1894443734 /* Sugestão de Classe */;
var pesquisa = new PesquisaCombinatoria(classeConfiguracao);
Em seguida devemos passar para a propriedade dados uma visão do cache local da classe de dados criada.
var classeDados = -1896647597 /* Sugestão de Classe de Pedido ou Provisão */;
var dados = classes.getCachedDataSet(classeDados);
pesquisa.dados = dados;
Em seguida devemos preencher os filtros da pesquisa combinatória de acordo com as informações passadas pelo usuário.
pesquisa.filtro.pessoa = 3478816 /* Paula Souza */;
pesquisa.filtro.comportfis = -1899999164 /* Não Contribuinte */;
pesquisa.filtro.locescritu = 408425 /* Unum LocEscritu */;
pesquisa.filtro.classepedido = -1899998925 /* C p Consumo */;
pesquisa.filtro.recurso = 42354 /* ANTENA TV */;
pesquisa.filtro.nucleo =36925844 /* Almox Análise */;
pesquisa.filtro.tiposaida = -1894743958 /* Normal */;
Em seguida devemos utilizar o método consultar que tem o retorno de acordo com os parâmetros recebidos.
O primeiro parâmetro é um booleano indicando se retorna todas as chaves dos registros válidos independente da ordem de prioridade.
O segundo parâmetro é um booleano indicando se o retorna deve ser um dataset, caso seja informado false o retorno é um objeto literal contendo as propriedades "chave" e "prioridade".
O terceiro parâmetro é um booleano indicando se retorna todas as chaves dos registros válidos, apenas da prioridade máxima.
Portanto para que a consulta traga como resultado todos os registros válidos de maior prioridade deve ser passado true para o primeiro e terceiro parâmetro.
var resultado = pesquisa.consultar(true, true, true);
Exemplo completo no idbc. Há necessidade de trocar as chaves informadas por uma chave da base onde está sendo executado.
__includeOnce(-1898141835); // /products/INTEQengine/configuration/iDBCsql library.ijs
__includeOnce(-1897036688); // /products/INTEQerp infrastructure/library/pesquisa/PesquisaCombinatoria.ijs
var classeConfiguracao = -1894443734 /* Sugestão de Classe */;
var classeDados = -1896647597 /* Sugestão de Classe de Pedido ou Provisão */;
var dados = classes.getCachedDataSet(classeDados);
var pesquisa = new PesquisaCombinatoria(classeConfiguracao);
pesquisa.dados = dados;
pesquisa.filtro.pessoa = 3478816 /* Paula Souza */;
pesquisa.filtro.comportfis = -1899999164 /* Não Contribuinte */;
pesquisa.filtro.locescritu = 408425 /* Unum LocEscritu */;
pesquisa.filtro.classepedido = -1899998925 /* C p Consumo */;
pesquisa.filtro.recurso = 42354 /* ANTENA TV */;
pesquisa.filtro.nucleo =36925844 /* Almox Análise */;
pesquisa.filtro.tiposaida = -1894743958 /* Normal */;
var resultado = pesquisa.consultar(true, true, true);
consultando todos os registros válidos
Para realizar uma consulta devemos iniciar instanciando o objeto PesquisaCombinatoria passando a classe de configuração que iremos utilizar.
__includeOnce(-1898141835); // /products/INTEQengine/configuration/iDBCsql library.ijs
__includeOnce(-1897036688); // /products/INTEQerp infrastructure/library/pesquisa/PesquisaCombinatoria.ijs
var classeConfiguracao = -1894443734 /* Sugestão de Classe */;
var pesquisa = new PesquisaCombinatoria(classeConfiguracao);
Em seguida devemos passar para a propriedade dados uma visão do cache local da classe de dados criada.
var classeDados = -1896647597 /* Sugestão de Classe de Pedido ou Provisão */;
var dados = Classes.getCachedDataSet(classeDados);
pesquisa.dados = dados;
Em seguida devemos preencher os filtros da pesquisa combinatória de acordo com as informações passadas pelo usuário.
pesquisa.filtro.pessoa = 3478816 /* Paula Souza */;
pesquisa.filtro.comportfis = -1899999164 /* Não Contribuinte */;
pesquisa.filtro.locescritu = 408425 /* Unum LocEscritu */;
pesquisa.filtro.classepedido = -1899998925 /* C p Consumo */;
pesquisa.filtro.recurso = 42354 /* ANTENA TV */;
pesquisa.filtro.nucleo =36925844 /* Almox Análise */;
pesquisa.filtro.tiposaida = -1894743958 /* Normal */;
Em seguida devemos utilizar o método consultar que tem o retorno de acordo com os parâmetros recebidos.
O primeiro parâmetro é um booleano indicando se retorna todas as chaves dos registros válidos independente da ordem de prioridade.
O segundo parâmetro é um booleano indicando se o retorna deve ser um dataset, caso seja informado false o retorno é um objeto literal contendo as propriedades "chave" e "prioridade".
O terceiro parâmetro é um booleano indicando se retorna todas as chaves dos registros válidos, apenas da prioridade máxima.
Portanto para que a consulta traga como resultado todos os registros válidos, independente da prioridade, deve ser passado true para o primeiro parâmetro e false para o terceiro parâmetro.
var resultado = pesquisa.consultar(true, true, false);
Exemplo completo no idbc. Há necessidade de trocar as chaves informadas por uma chave da base onde está sendo executado.
__includeOnce(-1898141835); // /products/INTEQengine/configuration/iDBCsql library.ijs
__includeOnce(-1897036688); // /products/INTEQerp infrastructure/library/pesquisa/PesquisaCombinatoria.ijs
var classeConfiguracao = -1894443734 /* Sugestão de Classe */;
var classeDados = -1896647597 /* Sugestão de Classe de Pedido ou Provisão */;
var dados = classes.getCachedDataSet(classeDados);
var pesquisa = new PesquisaCombinatoria(classeConfiguracao);
pesquisa.dados = dados;
pesquisa.filtro.pessoa = 3478816 /* Paula Souza */;
pesquisa.filtro.comportfis = -1899999164 /* Não Contribuinte */;
pesquisa.filtro.locescritu = 408425 /* Unum LocEscritu */;
pesquisa.filtro.classepedido = -1899998925 /* C p Consumo */;
pesquisa.filtro.recurso = 42354 /* ANTENA TV */;
pesquisa.filtro.nucleo =36925844 /* Almox Análise */;
pesquisa.filtro.tiposaida = -1894743958 /* Normal */;
var resultado = pesquisa.consultar(true, true, false);
A prioridade de um filtro sobre o outro na pesquisa é determinada nas configurações, através da propriedade ordem. Filtros que tendem a ser mais estáticos ou que possuam menos variações de informação (exemplo Local de Escrituração) deve ter ordem maior e com isto permanecerão com seu valor por mais tempo na consulta. Informações como recurso, devem estar com ordem menor, para serem processados primeiro e rapidamente sairem do filtro da pesquisa. Dificilmente haverá uma regra (registro na classe de dados) cadastrado específico para um recurso, portanto, ele saindo da combinação de dados de forma antecipada evitará processamento desnecessário.
Como exemplo podemos ver a definição de filtros da Sugestão de Classe, definida no script -1894443577, onde o filtro para a classe do pedido tem maior prioridade que o filtro do recurso.
var prioridade = 1000;
var filtro = this.filtro( "classepedido" );
filtro.prioridade = --prioridade;
filtro.tipo = TipoFiltro.CLASSE;
filtro.classeLimite = -2008879000 /* Pedidos ou Provisões */;
var filtro = this.filtro( "recurso");
filtro.prioridade = --prioridade;
filtro.filtroAssociado = "classerecurso";
Filtros de registro, na qual a classe de configuração possua um outro filtro associado, são testados para definir se o registro é válido com o valor informado nele, caso não seja localizado o valor é apagado e a pesquisa passa a ser feita sobre a classe do valor informado. Essa associação de filtros é muito utilizada quando queremos que a pesquisa avaliar o registro ou a classe, e a configuração do filtro é definida conforme abaixo.
var filtro = this.filtro( "recurso" )
filtro.prioridade = --prioridade
filtro.filtroAssociado = "classerecurso"
var filtro = this.filtro( "classerecurso" )
filtro.prioridade = --prioridade
filtro.tipo = TipoFiltro.CLASSE
filtro.classeLimite = -2007800000 /* Recursos */
Nesses casos onde o filtro de registro foi definido com um filtro associado de classe é necessário que na classe de dados seja implementada uma validação para impedir que o usuário final cadastre uma regra com o campo de registro e de classe preenchidos ao mesmo tempo.
Para cada campo criado na classe de configuração deverá existir um campo na classe de dados a ser usada pela pesquisa combinatória. Os campos que possuem filtros associados do tipo TipoFiltro.CLASSE no x-class de configuração da pesquisa não devem permitir que sejam preenchidos ao mesmo tempo na tabela de dados que a pesquisa irá utilizar o registro do tipo registro e o registo do tipo classe.
Vejamos um exemplo prático onde o x-class de configuração possui o filtro "recurso" que é associado ao filtro de classe "classerecurso".
var filtro = this.filtro( "recurso" )
filtro.prioridade = --prioridade
filtro.filtroAssociado = "classerecurso"
var filtro = this.filtro( "classerecurso" )
filtro.prioridade = --prioridade
filtro.classeLimite = -2007800000 /* Recursos * /
filtro.tipo = TipoFiltro.CLASSE
Ao montar os filtros para realizar a busca utlizando a pesquisa é necessário que somente o filtro recurso seja preenchido.
this._pesquisaTarefa.filtro[ "recurso" ] = 42354 /* ANTENA TV */;
É necessário também que seja validado no x-class de cadastro para que os dois não sejam preenchidos ao mesmo tempo.