Histórico da Página
...
A consulta rápida é responsável por apresentar para o usuário dados de indicadores definidos pelas áreas de negócio para cada um dos ERPs TOTVS. A obtenção destas informações é feita através de serviços REST implementados por cada um dos segmentos. O O widget de consulta rápida será semelhante ao da figura abaixo:
Cadastrando as consultas
O cadastro de consulta rápida deve ser realizada através do formulário FRM0015 - Indicadores. Neste cadastro é necessário preencher com as informações da consulta.
...
Nota |
---|
Até o momento, não será possível efetuar a chamada do LOG de segurança padrão do LOGIX nas funções da consulta rápida. Estas consultas não são cadastradas no menu e não são dadas permissões no ERP, apenas via Fluig Identity. Por este motivo se as funções possuírem chamadas do LOG de segurança, a execução da consulta será interrompida. |
.br
Função de START
No 4GL o nome desta função deve ter o sufixo _indicator_start, não poderá possuir parâmetros e deverá retornar para o Fluig uma variável RECORD com as informações de montagem do widget de consulta rápida, como:
...
Função GET-DATA
Esta função é de definição opcional e deve ser criada quando houver necessidade de tratar filtros customizados do widget de consulta rápida. Ela será executada quando estiver presente no fonte 4GL e o parâmetro "customfilter" for informado na chamada REST proveniente do widget de consulta rápida.
No 4GL o nome da função deve conter o sufixo _indicator_get_data e não receberá parâmetros. Estes serão passados para a função através de uma área de memória compartilhada, acessível através da função _ADVPL_QSGetParameter(<nome"nome_do_parametro>)parametro"), onde "nome_do_parâmetro" é o identificador do campo dentro da área de memória compartilhada que contem o valor desejado.
O corpo da função SEARCH deve ser transferido para a função GET-DATA, sendo que a primeira deve ser mantida no 4GL, por questões de compatibilidade, e deve ser reescrita para apenas chamar a função GET-DATA passando os parâmetros através da área de memória compartilhada.
...
Os dados devem ser transferidos para a função usando uma estrutura variável do tipo RECORD, que deve ser definida exatamente como segue:
DEFINE lr_params RECORD
l_searchcol CHAR(50),
l_searchval CHAR(300),
l_selection CHAR(01),
l_sortcol CHAR(50),
l_sortorder CHAR(04),
l_rows CHAR(10),
l_page CHAR(10),
l_customfilter CHAR(500)
END RECORD
A estrutura variável RECORD deve ser preenchida com os valores correspondentes antes de ser passada como parâmetro para a função _ADVPL_QSSetParameters(). Lembre-se de inicializar o RECORD antes de atribuir valores ao mesmo.
INITIALIZE lr_params.* TO NULL # Inicialização do recordRECORD
LET lr_params.l_searchcol = l_filter_column
LET lr_params.l_searchval = l_filter_value
LET lr_params.l_selection = l_selection
LET lr_params.l_sortcol = l_sort_col
LET lr_params.l_sortorder = l_sort_order
LET lr_params.l_rows = l_rows
LET lr_params.l_page = l_page
LET lr_params.l_customfilter = ""
CALL _ADVPL_QSSetParameters( lr_params ) # Passando o record para a área de memória compartilhada
...
Bloco de código | ||
---|---|---|
| ||
#---------------------------------------------------------------------------------------------------------------#
FUNCTION log1i_indicator_search(l_filter_column,l_filter_value,l_selection,l_sort_col,l_sort_order,l_rows,l_page)
#---------------------------------------------------------------------------------------------------------------#
DEFINE l_filter_column CHAR(50), #Coluna de filtro (opcional)
l_filter_value CHAR(300), #Valor do filtro da coluna acima (opcional)
l_selection CHAR(01), #Valor selecionado na lista de filtros (opcional)
l_sort_col CHAR(50), #Coluna de ordenação (opcional)
l_sort_order CHAR(04), #Tipo de ordenação ASC ou DESC (opcional)
l_rows SMALLINT, #Máximo de registros por página
l_page SMALLINT #Página atual de pesquisa
DEFINE lr_params RECORD
l_searchcol CHAR(50),
l_searchval CHAR(300),
l_selection CHAR(01),
l_sortcol CHAR(50),
l_sortorder CHAR(04),
l_rows CHAR(10),
l_page CHAR(10),
l_customfilter CHAR(500)
END RECORD
INITIALIZE lr_params.* TO NULL
# O record recebe os parâmetros da função search
LET lr_params.l_searchcol = l_filter_column
LET lr_params.l_searchval = l_filter_value
LET lr_params.l_selection = l_selection
LET lr_params.l_sortcol = l_sort_col
LET lr_params.l_sortorder = l_sort_order
LET lr_params.l_rows = l_rows
LET lr_params.l_page = l_page
LET lr_params.l_customfilter = "" # Customfilter sempre será branco quando a função search for chamada.
CALL _ADVPL_QSSetParameters(lr_params) # Grava os parâmetros na área compartilhada
RETURN LOG1i_indicator_get_data() # O retorno da função search é o mesmo da get_data
END FUNCTION |
...
Os dados atribuidos à área de memória compartilhada são recuperados através da função _ADVPL_QSGetParameter(<nome"nome_do_parametro>)parametro").O "nome_do_parametro" deve ser exatamente igual ao campo da variável RECORD que se deseja recuperar.
. No exemplo abaixo, vemos o trecho da função GET-DATA onde é feita a recuperação dos parâmetros.
Exemplo
...
Bloco de código | ||
---|---|---|
| ||
#---------------------------------------------------------------------------------------------------------------# FUNCTION log1i_indicator_get_data() #---------------------------------------------------------------------------------------------------------------# DEFINE l_filter_column CHAR(50), #Coluna de filtro (opcional) l_filter_value CHAR(300), #Valor do filtro da coluna acima (opcional) l_selection CHAR(01), #Valor selecionado na lista de filtros (opcional) l_sort_col CHAR(50), #Coluna de ordenação (opcional) l_sort_order CHAR(04), #Tipo de ordenação ASC ou DESC (opcional) l_rows SMALLINT, #Máximo de registros por página l_page SMALLINT, #Página atual de pesquisa l_customfilter CHAR(500) DEFINE l_sql_stmt CHAR(500), l_sql_count CHAR(500), l_where_clause CHAR(250) DEFINE l_ind SMALLINT, l_position INTEGER DEFINE lr_search RECORD data ARRAY[60] OF RECORD #Lista com os resultados da consulta cod_usuario LIKE usuarios.cod_usuario, nom_funcionario LIKE usuarios.nom_funcionario, ind_admlog LIKE usuarios.ind_admlog END RECORD, count SMALLINT, total INTEGER, #Total de registros encontrados na consulta (sem a paginação) cpage INTEGER, #Página de registros atual pages SMALLINT #Total de páginas resultantes da consulta END RECORD IF LOG_initApp("PADRAO") > 0 THEN RETURN END IF #Recebe#Recupera os valores dos parametros LET l_filter_column = _ADVPL_QSGetParameter("l_searchcol") LET l_filter_value = _ADVPL_QSGetParameter("l_searchval") LET l_selection = _ADVPL_QSGetParameter("l_selection") LET l_sort_col = _ADVPL_QSGetParameter("l_sortcol") LET l_sort_order = _ADVPL_QSGetParameter("l_sortorder") LET l_rows = _ADVPL_QSGetParameter("l_rows") LET l_page = _ADVPL_QSGetParameter("l_page") LET l_customfilter = _ADVPL_QSGetParameter("l_customfilter") CALL conout( "Executando LOG1i_indicator_get_data..." ) CALL conout( "Coluna de filtro...: " || l_filter_column ) CALL conout( "Valor de filtro....: " || l_filter_value ) CALL conout( "Selecao............: " || l_selection ) CALL conout( "Coluna de Ordenacao: " || l_sort_col ) CALL conout( "Ordenacao:.........: " || l_sort_order ) CALL conout( "LInhas.............: " || l_rows ) CALL conout( "Pagina.............: " || l_page ) CALL conout( "Filtro customizado.: " || l_customfilter ) # A partir daqui, segue o restante da função get_data |
...
... |
Aplicando o filtro customizado
O valor informado no parâmetro customfilter deve estar de acordo com a sintaxe SQL usada no 4GL. Ou seja, sua aplicação na pesquisa não requer tratamento especifico. Caso o conteúdo do parâmetro customfilter não esteja correto, não será necessário qualquer tratamento de exceção adicional.
Exemplo
Trecho do corpo da função GET-DATA mostrando como utilizar o valor recebido no parâmetro customfilter.
Bloco de código |
---|
# ...trecho inicial da função get_data
#Adiciona o filtro conforme selecionado
IF l_selection IS NOT NULL AND l_selection <> "*" THEN
LET l_where_clause = l_where_clause CLIPPED," AND u.ind_admlog = '",l_selection CLIPPED,"'"
END IF
# Adiciona o filtro customizado INformado na consulta rapida
IF l_customfilter IS NOT NULL THEN
LET l_where_clause = l_where_clause CLIPPED," AND ",l_customfilter CLIPPED
end IF
#Monta o SQL da consulta rápida
LET l_sql_stmt = "SELECT DISTINCT",
" u.cod_usuario,",
" u.nom_funcionario,",
" u.ind_admlog",
" FROM usuarios u",
" LEFT OUTER JOIN log_usu_grupos l",
" ON l.usuario = u.cod_usuario",
" LEFT OUTER JOIN log_grupos g",
" ON g.grupo = l.grupo",
" WHERE ",l_where_clause
# Continuação do codigo da função get_data... |
Função AUTO-COMPLETE
No 4GL o nome desta função deve ter o sufixo _indicator_autocomplete, deve ter como parâmetro:
...
- os dados da consulta; e
- o total de registros encontrados no banco de dados.
Exemplo
Bloco de código | ||||
---|---|---|---|---|
| ||||
#-------------------------------------------------------------------# FUNCTION logi1_indicator_autocomplete(l_filter_column,l_filter_value) #-------------------------------------------------------------------# DEFINE l_filter_column CHAR(50), #Coluna de filtro (opcional) l_filter_value CHAR(300) #Valor do filtro da coluna acima (opcional) DEFINE l_sql_stmt CHAR(500), l_sql_count CHAR(500), l_where_clause CHAR(250) DEFINE l_ind SMALLINT, l_position INTEGER DEFINE lr_autocomplete RECORD data ARRAY[500] OF CHAR(200), count SMALLINT END RECORD INITIALIZE lr_autocomplete.* TO NULL #Verifica a coluna e o filtro informado por parâmetro IF l_filter_column IS NOT NULL AND l_filter_value IS NOT NULL THEN LET l_where_clause = "UPPER(g."||l_filter_column CLIPPED||") LIKE '%"||UPSHIFT(l_filter_value) CLIPPED||"%'" ELSE LET l_where_clause = "1=1" END IF #Monta o SQL do auto-completar LET l_sql_stmt = "SELECT g.",l_filter_column CLIPPED, " FROM log_grupos g", " WHERE ",l_where_clause CLIPPED, " ORDER BY 1" WHENEVER ERROR CONTINUE PREPARE var_indicator_autocomplete FROM l_sql_stmt WHENEVER ERROR STOP IF sqlca.sqlcode <> 0 THEN CALL QS_consoleDebugMessage(l_sql_stmt) CALL log0030_processa_err_sql("PREPARE SQL","var_indicator_autocomplete",1) RETURN NULL END IF WHENEVER ERROR CONTINUE DECLARE cq_indicator_autocomplete CURSOR FOR var_indicator_autocomplete WHENEVER ERROR STOP IF sqlca.sqlcode <> 0 THEN CALL log0030_processa_err_sql("DECLARE CURSOR","cq_indicator_autocomplete",1) FREE var_indicator_autocomplete RETURN NULL END IF WHENEVER ERROR CONTINUE LET l_ind = 1 FOREACH cq_indicator_autocomplete INTO lr_autocomplete.data[l_ind] IF sqlca.sqlcode <> 0 THEN CALL log0030_processa_err_sql("FOREACH CURSOR","cq_indicator_autocomplete",1) EXIT FOREACH END IF LET l_ind = l_ind + 1 IF l_ind > 500 THEN EXIT FOREACH END IF END FOREACH FREE cq_indicator_autocomplete WHENEVER ERROR STOP LET lr_autocomplete.count = l_ind - 1 RETURN lr_autocomplete END FUNCTION |
...
Para que isso possa ser realizado é necessário alterar os programas que são informados como ações na função de START. Deve-se incluir nestes programas uma verificação para obter os parâmetros de execução utilizando a função APPLICATION_getNumArgs e já efetuar a operação de consulta.
Exemplo
Bloco de código | ||||
---|---|---|---|---|
| ||||
#-----------------# FUNCTION log02720() #-----------------# DEFINE l_usuario LIKE log_usu_grupos.usuario IF LOG_initApp("PADRAO") > 0 THEN RETURN END IF LET m_form_reference = _ADVPL_create_component(NULL,"LFORMMETADATA",m_container_reference) CALL _ADVPL_set_property(m_form_reference,"FORM","log02720",mr_log_usu_grupos,ma_log_usu_grupos) #Verifica se há um argumento de execução para o programa IF APPLICATION_getNumArgs() > 0 THEN IF APPLICATION_getArg("action") = "INDICATOR" AND UPSHIFT(APPLICATION_getArg("indicator")) = "LOGI1" THEN LET l_usuario = DOWNSHIFT(APPLICATION_getArg("cod_usuario")) END IF END IF IF l_usuario IS NOT NULL THEN CALL _ADVPL_get_property(m_form_reference,"EXECUTE_OPERATION","FIND","a.usuario='"||l_usuario CLIPPED||"'") ELSE CALL _ADVPL_set_property(m_form_reference,"ACTIVATE",TRUE) END IF END FUNCTION |
...