• Este debate está vacío.
Viendo 1 entrada (de un total de 1)
  • Autor
    Entradas
  • #32215
    Javier Ader
    Participante

    Buenas y saludos a todos.

    Tal vez ya se reporto pero bueno: bajo ciertas circunstancias especificas se entra en un ciclo infinito al hacer zoom sobre un lookup.

    En particular pasa cuando se hace zooms sobre lineas de Pedidos que pertenecen a un Pedido que no es de venta (IsSOTrx = ‘N’) pero desde una ventana que es de Venta (AD_Window.IsSOTrx = ‘Y’). También pasaría a la inversa.
    Básicamente esto ocurre porque la lógica actual no puede inferir si una linea de Pedido es de ventas o no (C_OrderLine NO tiene una columna llamada IsSOTrx; la tiene C_Order), por lo tanto defaultea al valor IsSOTrx de la ventana desde donde se esta haciendo el zoom. Esto lleva a abrir la ventana Pedidos de Clientes (en vez de la correcta, Pedidos de Proveedores), intentar buscar el pedido que contiene la linea en la primer pestaña (acá no se encuentra obviamente tal pedido), pasar a la pestaña de Linea de Pedido, y buscar ahí el registro (en este punto tal registro necesariamente tampoco se encuentra, ya que se esta en la ventana incorrecta y ahí se produce el bucle infinito).
    El error inicial parte de que se infiere incorrectamente cual ventana abrir, el segundo, es que el cuando se busca el registro se hace asumiendo que se va a encontrar y como tal cosa no ocurre nunca, la búsqueda no termina y la aplicación se bloquea.

    En particular, lo segundo se da en el ultimo while de APanel.irATablaRegistro:

    Code:
    // buscar el registro
    if( id_hijo != 0 ) {
    while(( m_curTab.getRowCount() > m_curTab.getCurrentRow()) && ( m_curTab.getKeyID( m_curTab.getCurrentRow()) != id_hijo )) {
    m_curGC.getTable().removeEditor();
    m_curTab.navigateRelative( +1 );
    }

    m_curTab.getRowCount() retorna 0; m_curTab.getCurrentRow() retorna -1, y la segunda condición m_curTab.getKeyID( m_curTab.getCurrentRow()) != id_hijo obviametne nunca se cumple.

    Una forma de solucionar esto es, antes de entrar al bucle prechequear que la tabla tenga al menos una fila con el id buscado. Con esto se evitaría el ciclo infinito, pero aún así se abriría la ventana incorrecta.

    Para solucionar lo primero, tal vez se podria mejorar la logica si un registro es IsSOTrx o no, y asi por ej para C_ORderLine, en vez de mirar directamente en el tabla, se buscaria la tabla “padre” ; C_Order. En este caso el sql seria algo así como

    Code:
    SELECT IsSOTrx FROM C_Order WHERE C_Order_ID IN
    (SELECT C_Order_ID FROM C_OrderLine WHERE C_OrderLine_ID = )

    Esto es una linea de pedidos es de “venta” si el pedido al que pertenece lo es.

    Esto se podría tratar como casos especiales para unas cuantas tablas mas: C_InvoiceBatchLine,C_InvoiceLine,C_InvoicePaySchedule,C_InvoiceTax,C_OrderLine,C_OrderTax,C_InvoiceLIne, C_TaxOrder, M_InOutLine (y par mas pero que en realidad son vistas, no tablas; aún así, igual se aplica)
    Todas estas tablas por si mismo no contienen la columna IsSOTrx, pero si “forman parte” (se asocian mediante una columna IsParent = Y) de otra tabla que si contienen esta columna.

    De manera general, que tablas tienen IsSOTrx directa o indirectamente (via un padre) se puede determinar mediante esta sql (bastante compleja, y no se si es tan necesario….) :

    Code:
    — Con esta query se puede encontrar las tablas en donde chequear
    — si determinado registro es IsSOTrx, con uno o dos niveles de
    — “anidación” (la anidación se hace mediante columnas “padres”, esto es mediante
    — AD_Column.IsParent, y AD_Column.AD_Reference_Value_ID).
    — Por ej, para C_Invoice se debe verificar directamente
    — en C_Invoice, pero para C_OrderLine se debe verificar en C_Order (NO en
    — C_OrderLine ya que esta tabla no tiene la columna IsSoTrx).
    — Si se encuentra el nombre de la tabla en una fila con nombre de columna
    — “IsSoTrx” se debe usar directametne
    — Si no, TableNameRef no es null se debe usar esa
    — Si no, se debe usar Columnname eliminado previamente el sufijo “_ID”
    — En el primer caso (directo) la sentencia sql deberia ser
    — SELECT IsSOTrx FROM WHERE = ‘id registro’
    — En el segundo y tercer caso
    — SELECT IsSOTrx FROM WHERE — IN (SELECT FROM WHERE = ‘id registro’

    –set search_path to libertya
    SELECT
    t.AD_Table_ID , t.Tablename, c.AD_Column_id, c.ColumnName, c.IsParent,
    c.AD_Reference_ID, c.AD_Reference_Value_ID,
    t.po_window_id,
    rt.AD_Table_ID as AD_TableRef_ID,
    (SELECT TableName FROM AD_Table WHERE AD_Table_ID = rt.AD_Table_ID) AS TableNameRef

    FROM
    AD_Table t
    LEFT JOIN AD_Column c ON (t.AD_Table_ID = c.AD_Table_ID)
    LEFT JOIN AD_Reference r ON (c.AD_Reference_Value_ID = r.AD_Reference_ID AND r.ValidationType = ‘T’)
    LEFT JOIN AD_Ref_Table rt ON (r.AD_Reference_ID = rt.AD_Reference_ID)
    WHERE
    –t.tableName ILIKE ‘C_ORderLine’ AND
    (
    (c.ColumnName ILIKE ‘IsSOTrx’
    –AND t.po_window_ID IS NOT NULL
    )
    OR

    (c.IsParent = ‘Y’
    AND
    (c.AD_Reference_ID = 19
    OR
    ( c.AD_Reference_ID = 30
    AND c.AD_Reference_Value_ID IS NULL)
    )
    AND
    char_length(c.ColumnName) > 3
    AND
    EXISTS
    (
    SELECT * FROM AD_Table tt
    WHERE
    tt.TableName ILIKE substring(c.ColumnName FROM 1 FOR (char_length(c.ColumnName)-3))
    AND tt.AD_Table_ID IN
    (SELECT AD_Table_ID FROM AD_Column
    WHERE ColumnName ILIKE ‘IsSOTrx’

    )
    )
    )
    OR
    (
    c.IsParent = ‘Y’
    AND
    (c.AD_Reference_ID = 18
    OR
    ( c.AD_Reference_ID = 30
    AND c.AD_Reference_Value_ID IS NOT NULL)
    )
    AND
    rt.AD_Table_ID IN
    (SELECT AD_Table_ID FROM AD_Column
    WHERE ColumnName ILIKE ‘IsSOTrx’)
    )

    )
    –ORDER BY c.AD_Reference_ID

    ORDER BY c.IsParent, t.tableName

    Si no, lo más simple creo: dejar la cosas tal como están (eso si, evitando el bucle infinito) pero detectar si en la ventana que se infirió se encontró o no el registro; si no se encontró, entonces intentar con la otra ventana (esto es, si por ej, se se infirió que el registro hay que mostrarlo en Pedidos de Cliente, pero no se encontró, entonces probar en Pedidos de Proveedor).

    Saludos

    PD: recalco nuevamente que para que esto pase se tienen que dar condiciones bastantes complejas: en particular solo ocurre con zooms sobre tablas que tengan asociadas tanto ventanas de “venta” como “de compra” (aunque el bucle infinito se puede dar con o sin doble “ventana”), no tengan directamente la columna IsSOTrx (asi por ej, nunca va ocurrir haciendo un zoom sobre Pedidos; solo sobre Lineas de Pedidos) y que el zoom se este haciendo desde una ventana que no sea del “mismo tipo” que el registro (ej, la ventana es IsSOTrx = ‘Y’, pero la linea de pedido pertenece a un pedido que es IsSOTrx = ‘N’). En particular a mi me ocurrió sobre una ventana de un componente que estamos desarrollando desde el perfil Administración (el cual tiene acceso tanto a Pedidos de clientes como Pedidos a Proveedores).

Viendo 1 entrada (de un total de 1)
  • Debes estar registrado para responder a este debate.