Respuestas de foro creadas

Viendo 15 entradas - de la 196 a la 210 (de un total de 232)
  • Autor
    Entradas
  • en respuesta a: Guia para desarrollo de ventana de consulta #34267
    Javier AderJavier Ader
    Participante

    Ok, ahora que lo decís, la idea esta buena en general y podría ser de utilidad para todos (en particular los campos Marca, Submfalia y familia; agregar tus otros campos propios y su correspondientes filtrado debe ser más de lo mismo); y se podría agregar como una ventana de info de productos avanzada (o incluso reemplazar la de info actual).
    Miro un poco esa clase y veo si te puedo dar una mano; de paso rememoro un poco mis conocimientos acerca swing que hace rato que no hago una GUI usando estas librerías.

    Saludos
    Javier

    en respuesta a: Guia para desarrollo de ventana de consulta #34266
    Javier AderJavier Ader
    Participante

    Buenas. No se si hay un guía (la armamos si queres), pero no entiendo bien porque necesitas hacer esto; la ventana infoProduct ni no me equivoco YA es accesible independientemente de si estás en una ventana o no; Ver -> Información de Articulo (o usado el shortcut Ctrl + I). Esta ventana, si no estoy loco, es además solo lectura.
    Ahora, si lo que queres es necesariamente asociarlo a una entrada del menú, me imagino que podes ver cual es el código que dispara el shortcut y crear un proceso (un formularío no lo veo necesario) que replica lo mismo; ese proceso puede tener asociada la entrada del menú. Casi seguro que el código que dispara este acceso esta en APanel o AWindow.
    Ahora, si infoProduct no es exactamente lo que necesitas (tal vez requieras ver más datos o algo por el estilo), supongo que el camino es tomar como base infoProduct y hacerle modificaciones (y después a este nuevo info product, o asociarlo a un menú via un proceso o a una de las entradas en Ver). A esto apuntas?

    en respuesta a: Problema con instalación de Componente #34246
    Javier AderJavier Ader
    Participante

    Buenísimo, ahí anduvo… me iba a volver loco. Me habia puesto de debugear con eclipse y como la consola la tengo configurada con un buffer pequeño no había alcanzado a ver el error en la creación del juguete y menos a darme cuenta que la transacción se abortaba y por eso todo lo demás iba a fallar (supongo que el despues de hacer el doPreinstall habria que chequear que la transaccion esta abierta o que este metodo lo haga, si no se sabe en que parte falla). Me daba la sensación que el problema estaba en obtener las nuevas ids desde las secuencias.
    Lo de los permisos de acceso ya me había dado cuenta ya que los cambios en AD_Window_Access no se loguean mientras se está en “modo desarrollo” (iba pispiando la tabla AD_Changelog para ver que se insertaba y que no); lo cual veo correcto (los usuarios cambian de instalación en instalación).

    Ahora lo que vi es que aunque puso en AD_Changelog las modificaciones que hice a los juguetes (2 creaciones y un delete), estas no fueron a parar ni al install.xml ni al postinstall.xml (y por lo tanto luego de la instalación no tengo juguetes). Esto debe venir porque no “registre” la tabla M_Juguetes dentro de los esquemas de tablas mientras estaba en modo desarrollo (los exportadores alcance a ver que filtran por los esquemas data y metadata); supongo que si lo hubiese hecho despues de detener el desarrollo también habría exportado las modificaciones a las filas a M_Juguetes (aunque no a los esquemas de tablas en si mismos), e.d hubiese exportado los juguetes en particular pero no los cambios a los esquemas. Despues lo investigo un poco más porque igual el tema de los esquemas de tabla no lo termino de comprender del todo.

    Unas últimas notas, para no crear un nuevo thread:

    – no termino de entender para que sirve el AD_Plugin; al parecer en el proceso de instalación se crea un solo plugin por componente a lo sumo (el plugin queda asociado a la versión del componente siendo instalada, pero solo a una).

    – el proceso de desarrollo ralentaba muchísimo las modificaciones de metadatos; supongo que era por las multiples modificaciones en AD_Changelog (por ej, cuando se importan masivamente las columas de una tabla). Ok, mi maquina esta bastante vieja, pero igual creo que la diferencia era bastante notable.

    – por qué usaron la tabla AD_Changelog? Estaba desde antes y supongo que estaba pensada para mantener otra tipo de funcionalidad. También tiene una estructura redundante (se nota cuando se hace un insert; no tanto con una modificación simple o elimianción ya que ahi va una sola fila por operación ), e.d no esta normalizada (pienso que debe ser 2 tablas en vez de una, con una relación 1 a muchos; la segunda manteniendo los cambios a nivel de columna de una tabla). Otra limitación que le veo es que el oldvalue y el newvalue parecen tener longitud máxima de 2000 caracteres ; supongo que de ahí viene la limitación para registrar los cambios de datos binarios (a nivel de código vi algunas cosas que intentaban implementar pasando previamente a base64 los datos binarios; pero casi cualquier dato binario va a superar 2000 caracteres, más en base64).

    – las notas anteriores no tienen mucha importancia ya que las mejoras andan y seguramente van a traer muchas otras de la mano. Los felicito nuevamente.

    en respuesta a: Porque m_product_costing no tiene montos?? #34241
    Javier AderJavier Ader
    Participante

    Si, yo había tenido ese problema. Al final no lo había investigado más, pero ahora que lo decís me puse a mirar un poco. Al parecer la tabla M_Product_Costing tiene asociada la ventana de Artículos, pero esta ventana no tiene asociada ninguna pestaña relacionada con esta tabla. Mirando un poco más M_Product_Costing tiene otra columna de enlace a tabla principal; en este caso a C_AcctSchema ; esta última tiene asociada la ventana Esquema Contable, pero de nuevo está ventana no tiene una pestaña a la tabla M_Product_Costing… Esto es, ninguna de las dos ventanas te va a permitir setear estos valores.
    A nivel de sql M_Product_Costing es “medio extraña” ; ya que tiene una clave primaria doble con los dos Ids y que ademas son referencias a M_Product y a C_AcctSchema (e.d, es una relación muchos a muchos entre el producto y un esquema contable). También es raro que a nivel de libertya tiene solo 3 columnas acualizables, isActive, currentCostPrice (este creo que es el que importa) y FutureCostPrice. Los demás precios que aparecen, readonly desde esta tabla y creo que están seteados automáticamente a partir de la creación de listas de precios.

    Ok, como se podría tener acceso a esta tabla? Supongo que podrías agregando un pestaña contable (para que no la vean todos) en Artículos asociada con esta tabla (nivel de pestaña 1; secuencia le pondría alguna justo después de la pestaña Accounting, pero esto va en gusto).
    En cualquier caso vas a tener que ir producto por producto sentándole este “precio de costo”. Esto me hace pensar que tal vez exista un proceso o alguna otra ventana que permita hacer esto de una manera un poco más práctica (después busco alguna consulta sql que permita me ver cuales son todas las ventanas cuyas pestañas están relacionadas con esta tabla); por ej, un proceso que automticamente copie los campos calculados a partir de las listas de precios en los currentCostPrice.

    Ahora, contablemente creo esto se usa para dar una valoración interna de tus propios bienes y el valor usado acá no necesariamente tiene que ser el precio de costo usado realmente en la compra del producto (Mercadería y Materias Primas es de Activo, aunque esto no se si dice mucho), pero en contabilidad tengo un baches bastantes grandes.

    PD : si miras la salida en consola del servidor de aplicaciones vas a ver que muchas el procesador contable va a buscar filas a M_Product_Costing y al no encontrarlas muestra un mensaje de warning relacionado (creo que también lo muestra si el precio encontrado es cero).

    en respuesta a: factura electronica #34213
    Javier AderJavier Ader
    Participante

    según el changelog http://www.libertya.org/Changelog-Libertya-release-10.03.html la funcionalidad de Facturación Electrónica se agrego en esta versión; la anterior no lo tenía.

    en respuesta a: Posible Bug y solución en Importador de Extracto #34195
    Javier AderJavier Ader
    Participante

    lo del and y or sigo creyendo que esta mal jaja. Fijate que en realidad tiene poco sentido chequear porque sea distinto de ‘Y’ o que sea NULL ya que en la primer sentencia sql se setea explícitamente a ‘N’ (el tema es que esta sentencia no creo que funcione por el tema del SysDate).
    Mirando la importación de productos (ImportProduct) se ve que en vez de usar Sysdate se usa current_timestamp lo cual si es una función de postgres. También fijate que lo de setear al principio I_ErrorMsg a NULL sigue siendo un error; lo podes verificar agreando una linea en la ventana de importacion que sepas que va a fallar por que la ecuación que decis no se cumple; en el campo Error De Importación te debería aparecer Err=Invalid Amount , lo cual estoy seguro que no te está apareciendo. Mi conclusión es que la segunda linea que sigue a “// Set Client, Org, IsActive, Created/Updated” hay que cambiarla por

    Code:
    sql.append( ” IsActive = COALESCE (IsActive, ‘Y’),” +
    “Created = COALESCE (Created, current_timestamp),” +
    ” CreatedBy = COALESCE (CreatedBy, 0),” +
    ” Updated = COALESCE (Updated, current_timestamp),” +
    ” UpdatedBy = COALESCE (UpdatedBy, 0),” +
    ” I_ErrorMsg = ”,” + ” I_IsImported = ‘N’ ” +
    “WHERE I_IsImported<>‘Y’ OR I_IsImported IS NULL” );

    el current_timestamp para que no haya error a nivel sintáctico y el I_ErrorMsg seteado a la string vacía para que los mensajes se puedan guardar (el tema de fondo que no dije antes que si vos concatenas NULL a cualquier string el resultado es NULL y eso es lo que estan haciendo los update que setean los errores; es por eso nunca muestra los errores en los campos de Error de Importacion).

    Ahora, después de esto, y asumiendo que esta consulta se ejecuta correctamente, no es posible que haya una fila en la tabla que tenga I_IsImported con NULL (la sentencia anterior la deberia haber puesto a ‘N’); por lo tanto esta condición se pueden borrar en todas las sentencias sql que siguen (por ej en “//set Banck Account” la string ” OR i.I_IsImported IS NULL” simplemente se puede borrar). De esta manera solucionas también el tema de los ORs y los ANDs (simplemente porque desaparecen los ORs!).
    Fijate también que el código debe ser más reciente (por ej el que el chequea la ecuación en cuestion) , NO usa la condición “OR i.I_IsImported IS NULL”, la condición “AND I_IsImported<>‘Y'” alcanza.

    Ahora, como decís, el importador aún funcione! Pero me da la sensación que va a funcionar correctamente cuando los datos en las tablas temporales sean correctos y por ej, va a fallar en poner los errores en la tabla I_ErrorMsg [no lo veo como un error grave, pero si por ej, hay un error como el que te ocurria a vos, es medio difícil de rastrear]. Mejorarlo un poco no cuesta nada.

    Saludos

    PD : a los que manejan el foro… puede ser que hayan dejado de andar los BBCode de Bold? por ej Bold , lo veo explicitamente con los tags “b” en vez de en negrita.

    PD2 : ah ahí haciendo un preview me di cuenta…. los tags b y supongo que casi todos los demás no funcionan dentro de las bbcode Code (algo que me parece de utilidad para remarcar partes especificas del código o cambios realizados). Pasemos a PhpBB ;) !

    en respuesta a: Posible Bug y solución en Importador de Extracto #34194
    Javier AderJavier Ader
    Participante

    mmm, por las cosas que mostre antes y por el hecho de que el formato de importacion para extractos bancarios no existe (al menos yo no lo encontré), me da la sensación de que esta funcionalidad no está implementada y la ventana de importación de extractos quedo de “antes”. Por lo anterior y tambien porque en la linea linea 139 aparece lo siguiente
    Created = COALESCE (Created, SysDate)
    Sysdate es una función de Oracle, no de postgres… e.d el código es viejo y no debería estar habilitado. Ese update tiene que fallar por un error de sintaxis a nivel de sql (lo raro es que debugueando la aplicacion no tiraba ningún error; simplemente el DB.executeUpdate retornaba 0… raro).
    Ahora ejecutando el siguiente update a desde pgadmin

    Code:
    UPDATE I_BankStatement SET AD_Client_ID = COALESCE (AD_Client_ID,1000010), AD_Org_ID = COALESCE (AD_Org_ID,1000047), IsActive = COALESCE (IsActive, ‘Y’), Created = COALESCE (Created, SysDate), CreatedBy = COALESCE (CreatedBy, 0), Updated = COALESCE (Updated, SysDate), UpdatedBy = COALESCE (UpdatedBy, 0), I_ErrorMsg = NULL, I_IsImported = ‘N’ WHERE I_IsImported<>‘Y’ OR I_IsImported IS NULL

    si tira un error de sintáxis debido al SysDate….

    Mi conclusión es que la ventana Importación de extractos debería también estar deshabilitada, ya que todas las demás cosas de las que dependen no están funcionales.

    en respuesta a: Posible Bug y solución en Importador de Extracto #34193
    Javier AderJavier Ader
    Participante

    Bueno, exactamente no se por donde viene, pero a simple vista esa clase parece tener muchos bugs a nivel de sql; en particular por el tema de precedencia de operadores AND y OR; por ej, en muchos lugares se ve algo como

    SELECT o UPDTE….

    WHERE algunas codiciones separas por AND
    AND
    i.I_IsImported<>‘Y’ OR i.I_IsImported is NULL
    AND AD_Client_ID= xxxx

    [code]
    en donde el ultimo and es agregado por una expresión append( clientCheck ) , y la idea es solo tocar los registros de importacion o de la tabla en las que se impotan los registros que pertenezcan a al mismo cliente (para que importanciones de distintas companias no se mezcle).
    Bueno, en todas esas sentecias hay un error ya que la condicion
    i.I_IsImported<>‘Y’ OE i.I_IsImported is NULL debe ir entre parensis [ esto es exactamente decir que para multiplicar 2 por 3 + 1 uno tiene que escribri 2 * (3 + 1); si uno escibre sin parentesis, e.d 2 * 3 + 1, se evalua como (2 * 3) + 1).
    Por ej el codigo anterior tiene la misma evaluacion que
    [code]

    SELECT o UPDTE….

    WHERE
    (algunas codiciones separas por AND
    AND
    i.I_IsImported<>‘Y’)
    OR
    (i.I_IsImported is NULL
    AND AD_Client_ID= xxxx )

    [code]
    Lo cual obivmente no es la intención de la sentencia.
    No se si este error es el que te está generando problemas, depues miro un poco más. Si queres podes probar cambiando todas los
    i.I_IsImported<>‘Y’ OR i.I_IsImported is NULL
    por
    (i.I_IsImported<>‘Y’ OR i.I_IsImported is NULL)
    En cualuqier caso, eso de setear con ‘E’ algo que es boolena (e.d, puede tomar solo Y o N), me parece muy raro (si lo que se quiere es setear un error, se deberia usar la columan de mensaje de error en la tabla temporal).

    PD : Tambien es probable que haya un error cuando se setea el error de mensaje en expresiones como I_ErrorMsg=I_ErrorMsg||’ERR=Invalid Org
    ya eso concatena los errores solo I_ErrorMsg no es null (y es justamente seteado a NULL al principio de prepareImportatation, en la linea 139).
    Esto se soluciona en vez de seteandolo a null, seteandolo a ”,
    e.d en la linea 139 cambias [b]I_ErrorMsg = NULL[/b] por [b]I_ErrorMsg = ”[/b].
    Los errores seteados ahí son los que vana aparecer en Mensajes de Error al Importar dentro de Importar Extracto bancario (es probable que tengas que abrir y cerrar la ventana, me parece que no hace un refresh automático de todas las lineas…creo…)[code]

    SELECT o UPDTE….

    WHERE algunas codiciones separas por AND
    AND
    i.I_IsImported<>‘Y’ OR i.I_IsImported is NULL
    AND AD_Client_ID= xxxx

    en donde el ultimo and es agregado por una expresión append( clientCheck ) , y la idea es solo tocar los registros de importacion o de la tabla en las que se impotan los registros que pertenezcan a al mismo cliente (para que importanciones de distintas companias no se mezcle).
    Bueno, en todas esas sentecias hay un error ya que la condicion
    i.I_IsImported<>‘Y’ OE i.I_IsImported is NULL debe ir entre parensis [ esto es exactamente decir que para multiplicar 2 por 3 + 1 uno tiene que escribri 2 * (3 + 1); si uno escibre sin parentesis, e.d 2 * 3 + 1, se evalua como (2 * 3) + 1).
    Por ej el codigo anterior tiene la misma evaluacion que
    [code]

    SELECT o UPDTE….

    WHERE
    (algunas codiciones separas por AND
    AND
    i.I_IsImported<>‘Y’)
    OR
    (i.I_IsImported is NULL
    AND AD_Client_ID= xxxx )

    [code]
    Lo cual obivmente no es la intención de la sentencia.
    No se si este error es el que te está generando problemas, depues miro un poco más. Si queres podes probar cambiando todas los
    i.I_IsImported<>‘Y’ OR i.I_IsImported is NULL
    por
    (i.I_IsImported<>‘Y’ OR i.I_IsImported is NULL)
    En cualuqier caso, eso de setear con ‘E’ algo que es boolena (e.d, puede tomar solo Y o N), me parece muy raro (si lo que se quiere es setear un error, se deberia usar la columan de mensaje de error en la tabla temporal).

    PD : Tambien es probable que haya un error cuando se setea el error de mensaje en expresiones como I_ErrorMsg=I_ErrorMsg||’ERR=Invalid Org
    ya eso concatena los errores solo I_ErrorMsg no es null (y es justamente seteado a NULL al principio de prepareImportatation, en la linea 139).
    Esto se soluciona en vez de seteandolo a null, seteandolo a ”,
    e.d en la linea 139 cambias [b]I_ErrorMsg = NULL[/b] por [b]I_ErrorMsg = ”[/b].
    Los errores seteados ahí son los que vana aparecer en Mensajes de Error al Importar dentro de Importar Extracto bancario (es probable que tengas que abrir y cerrar la ventana, me parece que no hace un refresh automático de todas las lineas…creo…)[code]
    en donde el ultimo and es agregado por una expresión append( clientCheck ) , y la idea es solo tocar los registros de importacion o de la tabla en las que se impotan los registros que pertenezcan a al mismo cliente (para que importanciones de distintas companias no se mezcle).
    Bueno, en todas esas sentecias hay un error ya que la condicion
    i.I_IsImported<>‘Y’ OE i.I_IsImported is NULL debe ir entre parensis [ esto es exactamente decir que para multiplicar 2 por 3 + 1 uno tiene que escribri 2 * (3 + 1); si uno escibre sin parentesis, e.d 2 * 3 + 1, se evalua como (2 * 3) + 1).
    Por ej el codigo anterior tiene la misma evaluacion que

    SELECT o UPDTE….

    WHERE
    (algunas codiciones separas por AND
    AND
    i.I_IsImported<>‘Y’)
    OR
    (i.I_IsImported is NULL
    AND AD_Client_ID= xxxx )

    [code]
    Lo cual obivmente no es la intención de la sentencia.
    No se si este error es el que te está generando problemas, depues miro un poco más. Si queres podes probar cambiando todas los
    i.I_IsImported<>‘Y’ OR i.I_IsImported is NULL
    por
    (i.I_IsImported<>‘Y’ OR i.I_IsImported is NULL)
    En cualuqier caso, eso de setear con ‘E’ algo que es boolena (e.d, puede tomar solo Y o N), me parece muy raro (si lo que se quiere es setear un error, se deberia usar la columan de mensaje de error en la tabla temporal).

    PD : Tambien es probable que haya un error cuando se setea el error de mensaje en expresiones como I_ErrorMsg=I_ErrorMsg||’ERR=Invalid Org
    ya eso concatena los errores solo I_ErrorMsg no es null (y es justamente seteado a NULL al principio de prepareImportatation, en la linea 139).
    Esto se soluciona en vez de seteandolo a null, seteandolo a ”,
    e.d en la linea 139 cambias [b]I_ErrorMsg = NULL[/b] por [b]I_ErrorMsg = ”[/b].
    Los errores seteados ahí son los que vana aparecer en Mensajes de Error al Importar dentro de Importar Extracto bancario (es probable que tengas que abrir y cerrar la ventana, me parece que no hace un refresh automático de todas las lineas…creo…)[code]

    SELECT o UPDTE….

    WHERE
    (algunas codiciones separas por AND
    AND
    i.I_IsImported<>‘Y’)
    OR
    (i.I_IsImported is NULL
    AND AD_Client_ID= xxxx )

    Lo cual obivmente no es la intención de la sentencia.
    No se si este error es el que te está generando problemas, depues miro un poco más. Si queres podes probar cambiando todas los
    i.I_IsImported<>‘Y’ OR i.I_IsImported is NULL
    por
    (i.I_IsImported<>‘Y’ OR i.I_IsImported is NULL)
    En cualuqier caso, eso de setear con ‘E’ algo que es boolena (e.d, puede tomar solo Y o N), me parece muy raro (si lo que se quiere es setear un error, se deberia usar la columan de mensaje de error en la tabla temporal).

    PD : Tambien es probable que haya un error cuando se setea el error de mensaje en expresiones como I_ErrorMsg=I_ErrorMsg||’ERR=Invalid Org
    ya eso concatena los errores solo I_ErrorMsg no es null (y es justamente seteado a NULL al principio de prepareImportatation, en la linea 139).
    Esto se soluciona en vez de seteandolo a null, seteandolo a ”,
    e.d en la linea 139 cambias [b]I_ErrorMsg = NULL[/b] por [b]I_ErrorMsg = ”[/b].
    Los errores seteados ahí son los que vana aparecer en Mensajes de Error al Importar dentro de Importar Extracto bancario (es probable que tengas que abrir y cerrar la ventana, me parece que no hace un refresh automático de todas las lineas…creo…)[code]
    Lo cual obivmente no es la intención de la sentencia.
    No se si este error es el que te está generando problemas, depues miro un poco más. Si queres podes probar cambiando todas los
    i.I_IsImported<>‘Y’ OR i.I_IsImported is NULL
    por
    (i.I_IsImported<>‘Y’ OR i.I_IsImported is NULL)
    En cualuqier caso, eso de setear con ‘E’ algo que es boolena (e.d, puede tomar solo Y o N), me parece muy raro (si lo que se quiere es setear un error, se deberia usar la columan de mensaje de error en la tabla temporal).

    PD : Tambien es probable que haya un error cuando se setea el error de mensaje en expresiones como I_ErrorMsg=I_ErrorMsg||’ERR=Invalid Org
    ya eso concatena los errores solo I_ErrorMsg no es null (y es justamente seteado a NULL al principio de prepareImportatation, en la linea 139).
    Esto se soluciona en vez de seteandolo a null, seteandolo a ”,
    e.d en la linea 139 cambias I_ErrorMsg = NULL por I_ErrorMsg = ”.
    Los errores seteados ahí son los que vana aparecer en Mensajes de Error al Importar dentro de Importar Extracto bancario (es probable que tengas que abrir y cerrar la ventana, me parece que no hace un refresh automático de todas las lineas…creo…)

    en respuesta a: Duda en la clase PO al instanciar un nuevo objeto #34178
    Javier AderJavier Ader
    Participante

    mschimpf, despues de ejecutar el save sobre un objeto po creado con Id 0, el nuevo id se obtiene como en cualquier otro objeto: o.getXXXX_ID() (despues del save, este metodo no te retorna 0, si no el nuevo id generado automaticamente).
    Ahora, a nivel de base de datos los valores de las claves primarias sí se pueden modificar en ciertos casos (por lo general si las claves primarias no son autonumericas; como es el la mayoría por no decir todas, las tablas de libertya).
    El siguiente update anda (asumiendo que hay un juguete con Id 100001; despues del update queda con Id 10)

    Code:
    update libertya.m_juguetes set m_juguetes_id = 10 where m_juguetes_id =1000001

    Lo que yo te propongo es (pero que no lo veo correcto en el sentido de diseño) es

    Code:
    MProductQuery mpq = new MProductQuery(this.getCtx(), this.getM_Product_ID(), this.get_TrxName());

    …. seteas lo que sea neceario….
    //lo salvas
    mpg.save();
    // y ahora podes hacer dos cosas
    //1)
    mpq.setM_Product_Query_ID(this.getM_Product_ID());
    mpg.save();

    //o 2)
    DB.executeUpdate(“Update m_ProductQuery set m_productQuery_id = “+
    this.getM_Product_ID() +
    ” where m_productQuery_id ” = mpg.getM_Product_Query_ID() );
    //este ejecuta el update de la clave primaria “a mano”
    //y ahora “lo relees”
    mpg = new MProductQuery(this.getCtx(), this.getM_Product_ID(), this.get_TrxName());

    En cualquier caso, esto es bastante mala práctica (internamente el servidor setea indices sobres la claves primarias…. cuando se cambian los valores de las claves, se tienen que modificar el indice lo cual puede ser muyyyyyy costoso).

    Lo que yo te digo igual es que debes estar intentando un diseño medio raro… por el código que pusiste estas intentando usar el id de un producto para setear el id (la clave primaria) de una fila en la tabla MProductQuery. Para lo único que puede tener sentido esto es para tener una relación 1 a 1 entre entre queries y productos (e.d un producto puede tener asociado a lo máximo una query ); si no es tu intención, entonces no se para que queres setear especificamente el id en la tabla query; si es tu intención, entonces deben haber mejores diseños.

    en respuesta a: Duda en la clase PO al instanciar un nuevo objeto #34177
    Javier AderJavier Ader
    Participante

    Muy clara no la tengo, pero al llamar al contructo con id 0, el objeto se considera como “nuevo” (PO.m_createNew = true); y al ejecutar el PO.save(), necesariamente va a parar a PO.saveNew(); el cual en las primeras lineas se ve

    Code:
    // Set ID for single key – Multi-Key values need explicitly be set previously
    if (m_IDs.length == 1 && p_info.hasKeyColumn()
    && !m_KeyColumns[0].equals(“AD_Language”))
    {
    int no = DB.getNextID(getAD_Client_ID(), p_info.getTableName(), m_trxName);
    if (no <= 0) { log.severe("No NextID (" + no + ")"); return saveFinish (true, false); } m_IDs[0] = new Integer(no); set_ValueNoCheck(m_KeyColumns[0], m_IDs[0]); }

    lo cual termina llamando a set_valueNoCheck con el id calculado automaticamente por DB.getNextId; vos al llamar a mpq.setM_Product_Query_ID haces lo mismo pero ANTES del save (e.d, vos cambias el id de 0 a tu numero; pero despues el saveNew lo pisa).
    Para mi, tal vez evitando que se llege al saveNew… una de las formas que veo es (aunque tal vez no muy elegante y no se si no va a tirar algún tipo de error), creas un objeto nuevo (id = 0), lo salvas (eso va a parar a saveNew); lo volves a traer con el id generado automaticamente, se lo cambias con setM_Product_Query_ID al id que vos realmente queres y volves a ejecutar un save(). La teoria es que el ultimo save() no va a llamar a saveNew() , si no a saveUpdate() y tal vez (auqneu tenga bastantes dudas) el codigo de saveUpdate es lo suficientemente general como para permitir updates sobres columnas claves (me da la sensación que si, mirándolo un poco por arriba).

    Otra forma que veo es hacer el utlimo update a “mano” (DB.executeUpdate casi seguro que anda), ejecutando algo como
    “Update m_ProductQuery set m_productQuery_id =
    where m_productQuery_id =
    Viejo valor seria el que te dio atuomaticamente el saveNew().
    Ok, despues de esto obvimetne tenes que releer el objeto con usadno el constructor con el nuevo id.
    OTRA… que no se si va a andar, es NO definir m_productquery_id como Id en la base de datos (tal vez si sea necesario asociarlo al elemento MProductId y como “columana padre”). De esa manera, el saveNew, aun cuando es llamado, no entra dentro del if que genera el id automaticamente (m_IDs.length =0 ).

    Más allá de todo esto… estas usando como clave primaria la clave primaria de otra tabla? Es medio raro y problemático; supongo que podes hacer otro diseño que te sirva y no te complique las cosas; pero no se bien cual es la idea (me da la sensación que es una relación 1 a 1-0 entre productos y queries)

    en respuesta a: isSOTrx es la abreviación de qué? #34170
    Javier AderJavier Ader
    Participante

    mmmm bueno, no, es al revés de lo que dije… debe ser is “Sales Order Transaction”; e.d transacción de ventas (aunque de nuevo el nombre es medio raro… no necesariamente hay una “venta”); o “saliente” o “generalmente realizada desde nosotros hacia nuestros clientes”.

    El tema es que ahora veo estas lineas en MInOut.beforeSave (en realidad eran las que me hicieron repensar por enésima vez la semántica detrás de isSOTrx…):

    Code:
    //Validar número de doccumento para remitos de salida
    if (!isSOTrx() && existsDocNumber(false)) {
    log.saveError(“ShipmentNumberAlredyExists”, “”);
    return false;
    }

    Que supongo que lo que esta queriendo chequear es que no se repitan los numeros de nuestros remitos (los generados por nuestros proveedores pueden potencialmente tener el mismo número).
    OK, pero ahora este código en MInOut.completeIt

    Code:
    // if (!this.get_Value(“DeliveryRule”).toString().equalsIgnoreCase(“F”) && isSOTrx()) {
    if (!getDeliveryRule().equalsIgnoreCase(DELIVERYRULE_Force) && isSOTrx()) {
    //Si la regla de albaranado es distinta de F y ademas es un albarán de salida

    Que supongo que lo que hace es no permitir remitos de salidas con regla de entrega no forzada cuando no hay stock….
    Bueno, en el primero usan !isSOTrx() y en el segundo isSOTrx() para determinar si es de salida! O los comentarios están mal o uno de los secciones tienen un error (me da la sensación es que el primero; no debería estar negado isSOTrx() )… o me marié y el error lo tengo yo :(

    en respuesta a: Seteo de la tarifa en confección de facturas #34132
    Javier AderJavier Ader
    Participante

    Y si… justo después de postear me di cuenta que te estabas refiriendo a la versión internacional y no la localización (e.d usar el lenguaje “Español (Argentina)”. Bueno, por lo menos sirvió para saber que la arquitectura de plugins va a manejar este tipo de diferencias (entre otras ventajas que debe traer).

    en respuesta a: Seteo de la tarifa en confección de facturas #34144
    Javier AderJavier Ader
    Participante

    fcristina escribió:

    Quote:
    Aprovecho para mencionar que dicho fix funcionará únicamente para la localización AR (ya que utiliza exclusivamente la clase CalloutInvoiceExt). De tener que corregirlo en una version Internacional, habría que modificar la superclase CalloutInvoice.

    Perdón por el offtopic; pero porque la localización afecta al llamado un callout? No es algo independiente? Si no me equivoco se define a nivel de columna de tabla en diccionario, y eso es igual para todas las localizaciones, no?

    en respuesta a: PO.save y beforeSave en libertya 9.10 #34142
    Javier AderJavier Ader
    Participante

    Así era nomás: M_Juguetes_ID estaba en el diccionario en minúsculas (y eso que lo advirtieron bastantes veces jajaja…). Lo que me confundió fue más que nada el segundo error, ya que el constructor ERA llamado y por lo tanto encontrado via reflexión (tanto en un update como en un insert), y obviamente MJuguetes.java era encontrado lo más bien. También, aún cuando se muestra este error (en la consola, no en la aplicación), los cambios realmente se persisten; supongo que antes estos casos se recurre a otro mecanismo de persistencia que “bypasa” a PO y sus descendientes.
    En M_Table.getPO (528) se encuentra:

    Code:
    try {

    Constructor constructor = clazz.getDeclaredConstructor(new Class[] { Properties.class, ResultSet.class, String.class });
    PO po = (PO) constructor.newInstance(new Object[] { getCtx(), rs, trxName });

    return po;

    } catch (Exception e) {

    log.log(Level.SEVERE, “(rs) – Table=” + tableName + “,Class=” + clazz, e);
    errorLogged = true;
    log.saveError(“Error”, “Table=” + tableName + “,Class=” + clazz);
    }

    y pienso que lo que falla ahí no es el GetDeclaredConstructor, si no que la invocación (constructor.newInstance) en la linea siguiente dispara una excepción, porque el constructor en PO (invocado desde el constructor de MJuguetes) no encuentra la clave primaria y dispara una excepción…
    La clave entonces creo que esta en (que dicho sea de paso, aparece en la traza, pero no entiendo porque en el “medio” de la misma)

    Code:
    caused by: java.lang.IllegalStateException: No PK nor FK – M_Juguetes
    at org.openXpertya.model.PO.setKeyInfo(PO.java:1391)
    at org.openXpertya.model.PO.load(PO.java:1284)
    at org.openXpertya.model.PO.(PO.java:176)

    PO.setKeyInfo (1381-1391)

    Code:
    // Search for Parents
    ArrayList columnNames = new ArrayList();
    for (int i = 0; i < p_info.getColumnCount(); i++) { if (p_info.isColumnParent(i)) columnNames.add(p_info.getColumnName(i)); } // Set FKs int size = columnNames.size(); if (size == 0) throw new IllegalStateException("No PK nor FK - " + p_info.getTableName());

    el size == 0 era true al parecer porque p_info.isColumnParent daba false para todas las columnas. Supongo que para p_info una columna es “parent” si es un ID o un clave foranea (segun el diccionario de datos). La info de la columnas creo que es precomputada en POInfo.loadInfo… pero este metodo simplemetne hace un select de de inner joins sobre AD_Table, AD_Column y un par de tablas mas… y isParent para la columna termina siendo lo que diga AD_Column.IsParent en la base de datos… asi que para seguir rastreando porque no me marca algo como “parent” cuando no se respeta al convención de nombres hay que ir a mirar por otros lados (en particular el codigo que modifica el diccionario de datos)… pero bueno ya el rastreo se hace muyyyyyyy largo; obviamente en algún lugar se tiene que hacer respetar la convención…
    En cualquier caso la conclusión que hago es: respetar la convención de nombres (al menos para las columnas ID, supongo también que para cualquier otra no?)… y que el constructor de una clase de persistencia de objetos sea llamado no significa mucho; hay que verificar que retorne correctamente y no con una excepción (que era lo que me pasaba a mi…)

    PD : también, el segundo error que me mostraba claramente esta “mal”… el constructor se encuentra, el tema es que su invocación tira una excepción (el código debe tener un try catch similar que pueda fallar por las dos razones, pero en el catch al mostrar la causa del error solo se contempla que lo que falle sea la reflexión y no la invocación)

    en respuesta a: Grave Error de Seguridad #34114
    Javier AderJavier Ader
    Participante

    y si… yo cuando hice el curso había planteado algo similar a “hay alguna posibilidad de obligar al usuario a NO poder guardar la contraseña”; algo similar a lo que pasa con el tilde de “mostrar pestañas contables”.
    Ahora, mas allá de esto, a mi nunca me cerro que los settings se guarden de manera local, pero bueno, todo tiene sus pros y sus contras y se el tema se va un poco….
    También, si uno va a estar tan preocupado por la seguridad de los usuarios, tal vez tenga más sentido ir un nivel mas arriba y directamente crear distintas cuentas de usuario a nivel de SO. Igual, a mi gustaría la opción de no permitirlo; no estaría de más.

Viendo 15 entradas - de la 196 a la 210 (de un total de 232)