- Este debate está vacío.
-
AutorEntradas
-
18 noviembre, 2012 a las 3:59 pm #32215Javier AderParticipante
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 FROMWHERE = ‘id registro’
— En el segundo y tercer caso
— SELECT IsSOTrx FROMWHERE — 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 TableNameRefFROM
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_IDORDER 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).
-
AutorEntradas
- Debes estar registrado para responder a este debate.