<div id="main-content" class="wiki-content group"> <script type='text/javascript'> //<![CDATA[ AJS.toInit(function() { if (Cloak) { Cloak.closeHTML = "<span class=\'cloakDefaultClose\'/>"; Cloak.openHTML = "<span class=\'cloakDefaultOpen\'/>"; Cloak.toggleZone = true; Cloak.memoryDuration = 0; Cloak.memoryPrefix = "contentId:108661156"; Cloak.memoryPath = "/"; } });// ]]> </script> <script type='text/javascript'> //<![CDATA[ AJS.toInit(function() { if (jQuery.composition && jQuery.composition.deck) { jQuery.composition.deck.memoryDuration = 0; } });// ]]> </script> <h1 id="id-5.Widgetdeconsultarápida-Objetivo"> <span style="color: rgb(0, 51, 102);">Objetivo</span> </h1> <p> La consulta rápida es responsable de presentar al usuario los datos de indicadores definidos por las áreas de negocio para cada uno de los ERPs TOTVS. La obtención de estas informaciones es realizada a través de servicios REST implementados por cada uno de los segmentos. <span style="font-size: 10.0pt; line-height: 13.0pt;">El <em>widget</em> de consulta rápida será semejante al de la figura a continuación: </span> </p> <p> <span style="font-size: 10.0pt; line-height: 13.0pt;"><img class="confluence-embedded-image image-center" width="600" src="http://tdn.totvs.com/download/attachments/108661156/QVWidget.jpg?version=1&modificationDate=1408537173000&api=v2" data-image-src="http://tdn.totvs.com/download/attachments/108661156/QVWidget.jpg?version=1&modificationDate=1408537173000&api=v2"></span> </p> <h1 id="id-5.Widgetdeconsultarápida-Cadastrandoasconsultas"> <span style="color: rgb(0, 51, 102);">Registro de consultas</span> </h1> <p> El registro de consulta rápida debe realizarse a través del formulario <strong>FRM0015 - Indicadores</strong>. En este registro es necesario llenar con la información de la consulta. </p> <div class="aui-message warning shadowed information-macro"> <span class="aui-icon icon-warning">Icon</span> <div class="message-content"> <p style="text-align: center;">Para que sea posible la visualización de la consulta rápida en el Fluig, la misma debe estar liberada, es decir, el desarrollo de la misma debe ser finalizada a través de la herramienta GOLD.</p> </div> </div> <p> </p> <p> </p> <blockquote> <p>El nombre de la consulta debe seguir el estándar compuesto por el código del sistema Logix, la letra "i" y la secuencia de identificación del indicador.</p> </blockquote> <p> <img class="confluence-embedded-image image-center" src="http://tdn.totvs.com/download/attachments/108661156/indicador.jpg?version=1&modificationDate=1404247516000&api=v2" data-image-src="http://tdn.totvs.com/download/attachments/108661156/indicador.jpg?version=1&modificationDate=1404247516000&api=v2"> </p> <h2 id="id-5.Widgetdeconsultarápida-Desenvolvimento"> <span style="color: rgb(0, 51, 102);">Desarrollo</span> </h2> <p> <span style="color: rgb(0, 0, 0);">Después de la creación, debe desarrollarse la fuente 4GL con las funciones estándares para la ejecución de la consulta rápida en Fluig. </span><span style="color: rgb(0, 0, 0); font-size: 10.0pt; line-height: 13.0pt;">Actualmente tres funciones son necesarias para cada indicador, siendo:</span> </p> <ol> <li><span style="color: rgb(0, 0, 0); font-size: 10.0pt; line-height: 13.0pt;"><strong>START:</strong> función responsable por retornar datos iniciales de la consulta rápida;</span></li> <li><span style="color: rgb(0, 0, 0); font-size: 10.0pt; line-height: 13.0pt;"><strong>SEARCH:</strong> función responsable para retornar los datos de la consulta; y</span></li> <li><span style="color: rgb(0, 0, 0); font-size: 10.0pt; line-height: 13.0pt;"><strong>AUTO_COMPLETE:</strong> función responsable por retornar las informaciones del autocompletar del <em>widget</em> en Fluig.</span><span style="color: rgb(0, 0, 0); font-size: 10.0pt; line-height: 13.0pt;"><br /></span><br /> <span style="color: rgb(0, 0, 0); font-size: 10.0pt; line-height: 13.0pt;"><br /></span></li> </ol> <div class="aui-message warning shadowed information-macro"> <span class="aui-icon icon-warning">Icon</span> <div class="message-content"> <p style="text-align: center;">Hasta ahora, no será posible efectuar la llamada del LOG de seguridad estándar del LOGIX en las funciones de la consulta rápida. Estas consultas no se registran en el menú y no se dan permisos en el ERP, apenas vía Fluig Identity. Por este motivo si las funciones poseen llamadas del LOG de seguridad, la ejecución de la consulta será interrumpida.</p> </div> </div> <p> <span style="color: rgb(0, 0, 0); font-size: 10.0pt; line-height: 13.0pt;"><br /></span> </p> <h2 id="id-5.Widgetdeconsultarápida-FunçãodeSTART"> <span style="color: rgb(0, 51, 102);">Función de START</span> </h2> <p> <span style="color: rgb(0, 0, 0);">En el 4GL el nombre de esta función debe tener el sufijo <strong>_indicator_start, </strong>no podrá poseer parámetros y deberá retornar para el Fluig una variable RECORD con las informaciones de montaje del <em>widget</em> de consulta rápida, como: </span> </p> <ul> <li><span style="color: rgb(0, 0, 0);">los filtros que se podrán realizar;</span></li> <li><span style="color: rgb(0, 0, 0);">las columnas que compondrán la grilla con los datos de la consulta;</span></li> <li><span style="color: rgb(0, 0, 0);">la lista de filtros predefinidos que se podrán utilizar; y</span></li> <li><span style="color: rgb(0, 0, 0);">la lista con el nombre de los programas que se podrán ejecutar a partir de la consulta.</span></li> </ul> <h5 id="id-5.Widgetdeconsultarápida-Exemplo"> <span style="color: rgb(0, 51, 102);">Exemplo</span> </h5> <div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> <pre class="theme: Eclipse; brush: plain; gutter: false" style="font-size: 12px;">#------------------------------# FUNCTION logi1_indicator_start() #------------------------------# DEFINE lr_start RECORD filters ARRAY[2] OF RECORD table_name LIKE frm_column.table_name, column_name LIKE frm_column.column_name END RECORD, columns ARRAY[3] OF RECORD table_name LIKE frm_column.table_name, column_name LIKE frm_column.column_name, can_order SMALLINT END RECORD, selection ARRAY[3] OF RECORD code CHAR(03), label CHAR(50) END RECORD, actions ARRAY[2] OF RECORD code CHAR(08), label CHAR(50) END RECORD END RECORD #Define las columnas de filtro de la consulta rápida LET lr_start.filters[1].table_name = 'log_grupos' LET lr_start.filters[1].column_name = 'grupo' LET lr_start.filters[2].table_name = 'log_grupos' LET lr_start.filters[2].column_name = 'des_grupo' #Define las columnas de la consulta rápida LET lr_start.columns[1].table_name = 'usuarios' LET lr_start.columns[1].column_name = 'cod_usuario' LET lr_start.columns[1].can_order = TRUE LET lr_start.columns[2].table_name = 'usuarios' LET lr_start.columns[2].column_name = 'nom_funcionario' LET lr_start.columns[2].can_order = TRUE LET lr_start.columns[3].table_name = 'usuarios' LET lr_start.columns[3].column_name = 'ind_admlog' LET lr_start.columns[3].can_order = FALSE #Define cuáles valores estarán en la selección de filtros LET lr_start.selection[1].code = '*' LET lr_start.selection[1].label = 'Todos los usuarios' LET lr_start.selection[2].code = 'S' LET lr_start.selection[2].label = 'Solamente administradores' LET lr_start.selection[3].code = 'N' LET lr_start.selection[3].label = 'Solamente usuarios comunes' #Define cuáles programas podrán ser llamados por la consulta LET lr_start.actions[1].code = 'log02700' LET lr_start.actions[1].label = 'Usuarios' LET lr_start.actions[2].code = 'log02720' LET lr_start.actions[2].label = 'Grupos del usuario' RETURN lr_start END FUNCTION</pre> </div> </div> <p> <span style="color: rgb(0, 0, 0); font-size: 10.0pt; line-height: 13.0pt;">La ejecución de la función anterior permitirá la iniciación del </span><em style="color: rgb(0, 0, 0); font-size: 10.0pt; line-height: 13.0pt;">widget</em><span style="color: rgb(0, 0, 0); font-size: 10.0pt; line-height: 13.0pt;"> de consulta rápida y lo creará semejante a la pantalla a continuación:</span> </p> <p> <span style="color: rgb(0, 0, 0);"><img class="confluence-embedded-image image-center" width="600" src="http://tdn.totvs.com/download/attachments/108661156/QVWIDGET2.jpg?version=1&modificationDate=1408538629000&api=v2" data-image-src="http://tdn.totvs.com/download/attachments/108661156/QVWIDGET2.jpg?version=1&modificationDate=1408538629000&api=v2"></span> </p> <h2 id="id-5.Widgetdeconsultarápida-FunçãodeSEARCH"> <span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 51, 102);">Función de SEARCH</span></span> </h2> <p> En el 4GL el nombre de esta función debe tener el sufijo <strong>_indicator_search</strong>, debe tener como parámetros: </p> <ol> <li>nombre de la columna de filtro seleccionada por el usuario;</li> <li>valor del filtro informado por el usuario;</li> <li>valor del filtro predefinido seleccionado;</li> <li>nombre de la columna de ordenación;</li> <li>tipo de ordenación;</li> <li>cantidad de líneas por página; y</li> <li>número de la página de consulta actual.</li> </ol> <p>Todos estos parámetros deben ser considerados al ejecutar la consulta en el banco de datos y el retorno debe ser una variable RECORD con:</p> <ol> <li>los datos de la consulta;</li> <li>cantidad total de registros encontrados en el banco de datos;</li> <li>cantidad total de registros que se retornarán al Fluig;</li> <li>número total de páginas conforme a la consulta efectuada; y</li> <li>número de la página actual de consulta.</li> </ol> <h5 id="id-5.Widgetdeconsultarápida-Exemplo.1"> <span style="color: rgb(0, 51, 102);">Ejemplo</span> </h5> <div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> <pre class="theme: Eclipse; brush: plain; gutter: false" style="font-size: 12px;">#---------------------------------------------------------------------------------------------------------------# FUNCTION logi1_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 del filtro de la columna anterior (opcional) l_selection CHAR(01), #Valor seleccionado en la lista de filtros (opcional) l_sort_col CHAR(50), #Columna de ordenación (opcional) l_sort_order CHAR(04), #Tipo de ordenación ASC o DESC (opcional) l_rows SMALLINT, #Máximo de registros por página l_page SMALLINT #Página actual de investigación 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 con los resultados de la consulta cod_usuario LIKE usuarios.cod_usuario, nom_funcionario LIKE usuarios.nom_funcionario, ind_admlog LIKE usuarios.ind_admlog END RECORD, count SMALLINT, #Total de registros que se retornarán total INTEGER, #Total de registros encontrados en la consulta (sin la paginación) cpage INTEGER, #Página de registros actual pages SMALLINT #Total de páginas resultantes de la consulta END RECORD INITIALIZE lr_search.* TO NULL #Verifica la columna y el 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 #Adiciona el filtro conforme seleccionado 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 #Monta el SQL de la 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 #Monta el SQL de COUNT (es necesario ser sin ORDER BY) LET l_sql_count = "SELECT COUNT(*) FROM ("||l_sql_stmt CLIPPED||") t" #Atribuye el ORDER BY para el SQL de la consulta rápida IF l_sort_col IS NOT NULL AND l_sort_order IS NOT NULL THEN LET l_sql_stmt = l_sql_stmt CLIPPED||" ORDER BY "||l_sort_col CLIPPED||" "||l_sort_order ELSE LET l_sql_stmt = l_sql_stmt CLIPPED||" ORDER BY 1" END IF WHENEVER ERROR CONTINUE PREPARE var_indicator_count FROM l_sql_count WHENEVER ERROR STOP IF sqlca.sqlcode <> 0 THEN CALL QS_consoleDebugMessage(l_sql_count) CALL log0030_processa_err_sql("PREPARE SQL","var_indicator_count",1) RETURN NULL END IF WHENEVER ERROR CONTINUE EXECUTE var_indicator_count INTO lr_search.total WHENEVER ERROR STOP IF sqlca.sqlcode <> 0 THEN CALL log0030_processa_err_sql("EXECUTE SQL","var_indicator_count",1) FREE var_indicator_count RETURN NULL END IF #Cuenta la cantidad de página que resultó la consulta LET lr_search.pages = LOG_round(lr_search.total/l_rows,0) #Verifica si la página informada excedió el total de páginas IF lr_search.pages > 0 THEN IF l_page > lr_search.pages THEN LET lr_search.cpage = lr_search.pages ELSE LET lr_search.cpage = l_page END IF ELSE LET lr_search.pages = 1 LET lr_search.cpage = l_page END IF WHENEVER ERROR CONTINUE FREE var_indicator_count PREPARE var_indicator_search 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_search",1) RETURN NULL END IF WHENEVER ERROR CONTINUE DECLARE cq_indicator_search CURSOR FOR var_indicator_search WHENEVER ERROR STOP IF sqlca.sqlcode <> 0 THEN CALL log0030_processa_err_sql("DECLARE CURSOR","cq_indicator_search",1) FREE var_indicator_search RETURN NULL END IF WHENEVER ERROR CONTINUE OPEN cq_indicator_search WHENEVER ERROR STOP IF sqlca.sqlcode <> 0 THEN CALL log0030_processa_err_sql("OPEN CURSOR","cq_indicator_search",1) FREE var_indicator_search RETURN NULL END IF #Calcula la posición del registro actual como la página y la cantidad de #líneas por página LET l_ind = 1 LET l_position = ((l_rows * l_page) - l_rows) + 1 WHILE TRUE WHENEVER ERROR CONTINUE FETCH ABSOLUTE l_position cq_indicator_search INTO lr_search.data[l_ind].* WHENEVER ERROR STOP IF sqlca.sqlcode <> 0 THEN IF sqlca.sqlcode <> NOTFOUND THEN CALL log0030_processa_err_sql("FETCH CURSOR","cq_indicator_search",1) END IF EXIT WHILE END IF LET l_ind = l_ind + 1 LET l_position = l_position + 1 #No puede exceder el límite de registros por página IF l_ind > l_rows THEN EXIT WHILE END IF END WHILE WHENEVER ERROR CONTINUE CLOSE cq_indicator_search FREE cq_indicator_search WHENEVER ERROR STOP LET lr_search.count = l_ind - 1 RETURN lr_search END FUNCTION</pre> </div> </div> <h2 id="id-5.Widgetdeconsultarápida-FunçãoAUTO-COMPLETE"> <span style="color: rgb(0, 51, 102);">Función AUTO-COMPLETE</span> </h2> <p> <span style="color: rgb(0, 0, 0);">En el 4GL el nombre de esta función debe tener el sufijo <strong>_indicator_autocomplete</strong>, debe tener como parámetro: </span> </p> <ol> <li><span style="color: rgb(0, 0, 0);">nombre de la columna seleccionado para filtro; y</span></li> <li><span style="color: rgb(0, 0, 0);">y el valor del filtro informado por el usuario.</span></li> </ol> <p> <span style="color: rgb(0, 0, 0);">La devolución debe ser una variable RECORD con:</span> </p> <ol> <li><span style="color: rgb(0, 0, 0);">los datos de la consulta; y</span></li> <li><span style="color: rgb(0, 0, 0);">el total de registros encontrados en el banco de datos.</span></li> </ol> <h5 id="id-5.Widgetdeconsultarápida-Exemplo.2"> <span style="color: rgb(0, 51, 102);">Ejemplo</span> </h5> <div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> <pre class="theme: Confluence; brush: plain; gutter: true" style="font-size: 12px;">#-------------------------------------------------------------------# FUNCTION logi1_indicator_autocomplete(l_filter_column,l_filter_value) #-------------------------------------------------------------------# DEFINE l_filter_column CHAR(50), #Columna de filtro (opcional) l_filter_value CHAR(300) #Valor del filtro de la columna anterior (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 fecha ARRAY[500] OF CHAR(200), count SMALLINT END RECORD INITIALIZE lr_autocomplete.* TO NULL #Verifica la columna y el 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 el SQL del autocompletar 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</pre> </div> </div> <p> <span style="color: rgb(0, 51, 102);"><span style="color: rgb(0, 0, 0);">Esta función es ejecutada cuando el usuario informa algún filtro en la consulta, como se muestra en el ejemplo a seguir:</span></span> </p> <p> <span style="color: rgb(0, 51, 102);"><img class="confluence-embedded-image image-center" width="600" src="http://tdn.totvs.com/download/attachments/108661156/QVWidget3.jpg?version=1&modificationDate=1408539017000&api=v2" data-image-src="http://tdn.totvs.com/download/attachments/108661156/QVWidget3.jpg?version=1&modificationDate=1408539017000&api=v2"></span> </p> <h2 id="id-5.Widgetdeconsultarápida-Posicionamentoautomáticonoregistroselecionado"> <span style="color: rgb(0, 51, 102);">Posicionamiento automático en el registro seleccionado</span> </h2> <p> Cuando el usuario, en el <em>widget</em> de consulta rápida, seleccione un registro en la grilla y haga clic en una de las acciones seleccionadas es necesario que la ejecución del programa Logix seleccionado ya exhiba el registro seleccionado ya consultado. </p> <p> Para que eso pueda ser realizado es necesario alterar los programas que son informados como acciones en la función de <strong>START</strong>. En estos programas se debe incluir una verificación para obtener los parámetros de ejecución utilizando la función <strong>APPLICATION_getNumArgs</strong> y ya efectuar la operación de consulta. </p> <h5 id="id-5.Widgetdeconsultarápida-Exemplo.3"> <span style="color: rgb(0, 51, 102);">Ejemplo</span> </h5> <div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> <pre class="theme: Confluence; brush: plain; gutter: true" style="font-size: 12px;">#-----------------# 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 si hay un argumento de ejecución para el 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</pre> </div> </div> <p> <span style="color: rgb(0, 0, 0);">Cuando se ejecuta a través del widget de consulta rápida del Fluig, la función <strong>APPLICATION_getNumArgs </strong>siempre devolverá como mínimo tres parámetros, siendo: </span> </p> <ol> <li><span style="color: rgb(0, 0, 0);"><strong>ACTION: </strong>la palabra "INDICATOR" para identificar que se trata de la acción de un indicador;</span></li> <li><span style="color: rgb(0, 0, 0);"><strong>INDICATOR: </strong>el código del indicador registrado en el <strong>FRM0015</strong>.</span></li> </ol> <p> <span style="color: rgb(0, 0, 0);">A partir del segundo parámetro, se envían las columnas con los valores seleccionados por el usuario.</span> </p> </div> |