• Este debate está vacío.
Viendo 3 entradas - de la 1 a la 3 (de un total de 3)
  • Autor
    Entradas
  • #31606
    Javier Ader
    Participante

    Bueno, que son esas tablas? Y porque estan tan mal implementado el codigo que las accede jajaja
    Ok, el tema es que ya encontre un bug en MMPCMRP que es “relativamente” bastante obvio y supongo que todo el codigo relacionado a esto no es tan bien mantenido (miren por ej MMPCMRP.C_OrderLine…. eso duplica entradas para una misma C_OrderLine; la razon es que el select se ejecuta fuera de cualquier transaccion,y por lo tanto no puede ver entradas creadas dentro de una transaccion en curso; en particular , la transaccion que creo o modifico la C_OrderLine)
    A primera vista me da la sensación que esta relacionado con “la historia” de por ej los articulos; bien, mirando las otras tablas tambien me da la sensacion que esta relacionado con la historia de muchas otras cosas en general; por ej de peridod (mpc_order supongo, que es para esto), pero lo raro es que TODAS las tablas MPC_xxxx , salvo MPC_MRP estan vacias…
    Todo este viene porque el codigo relacionado a esto, es uno de los cuellos de botella que encuentra el codigo del TPV (admeas que el codigo de MOrderLine de manera bastante “dudosa” intenta crear una entrada en MMP_MRP tanto en beforeSave como en el afterSave… esto por una y cada una de los guardados de un MOrderLine, y cuando se factura desde el TPV esto es llamado muuuuuchas veces por cada linea)

    PD : antes de postear mire si tenia que ver con la “historia de productos “( el dialogo que aparece en InfoProduct) y no…. Pregunto, que pasa si deshabilito a nivel de código todo lo relacionado a “MPC_xxxx”? Se rompe algo? Me da la sensación que no mucho porque casi todas las tablas están vacías…

    #35266
    Federico Cristina
    Superadministrador

    Buenas,

    Casualmente hace un par de días atrás estuve trabajando sobre la performance del TPV y me encontré con dichas invocaciones desde MOrderLine.

    Por lo que pude averiguar MPC_MRP parece que refiere a Manufacturing Planning and Control & Material Requirements Planning. Sin embargo, dudo mucho en la correcta funcionalidad de dichos features, y además habría que ver desde dónde se utiliza la información que va recavando.

    Por lo pronto, comentando las invocaciones desde el beforeSave() y el afterSave() de MOrderLine, junto con alguna que otra modificación adicional que realicé se logra reducir a la mitad el tiempo de procesamiento y emitisión de un ticket TPV (obviamente que esto es más notorio si la cantidad de líneas en una venta es mayor).

    Sobre tu pregunta respecto de si se rompe algo, ya comenté las invocaciones mencionadas, así que ya veremos ;)

    Saludos,
    Federico

    #35267
    Javier Ader
    Participante

    Y si… ademas de por el bug que te comente, una misma linea de pedido es ingresada mas de una vez; en realidad una vez por cada beforeSave y afterSave() de MorderLine…. (la razón: el select count(*) se hace sobre transaccion “null”; pero la creacion de las entradas en la tabla se hace sobre la transacción que esta usando la linea….).
    Ahora, seguro que comentado estas invocaciones (yo ya lo hice y no vi nada raro) se mejora la performace el tpv…. cada linea del pedido es salada cerca de 10 veces; estas 10 veces generan 4 accesos a estas tablas (dos en el before, 2 en el after)… Es decir; 40 accesos adicionales por linea de pedido que no tienen mucho sentido.

    Fijate también en MOrder.afterSave (creo…); que llama a un método “afterSaveSync” la primer parte de este método tiene que ver con esta tabla; también la comente… Después de eso te tira un error, porque el código que sigue actualiza codigo que realmente “deberia” estar sincronizado entre el pedido y sus lineas… el tema es que el afterSync es llamado con “DocStatus”; una columna que no existe en las lineas; por lo tanto tambien comente la invocacion afterSaveSync( “DocStatus” ). (las demas invocaciones “parecen” estar bien…)

    Ok, ahi con esto la ganancia es minima (un sql update por cada save en una Morder) pero bueno… es lo correcto.

    Un tema relacionado: si estas con la optimización del TPV (algo en lo que tambien estoy…) mira por los afterSave de MorderLine (iba a hacer un thread sobre esto, pero bueno, lo pongo aca…). Ahi se actualiza los C_OrderTax del pedido y el total (en 10.09 se hace de una manera un poco distinta a 10.03, pero termina sineod lo mismo). Ese codigo no solo ralenta mucho el TPV si no que es ….. incorrecto.
    Por que? y bueno, uno modifica una linea, no se deberia tocar NADA de la cabecera, principalmente porque la cabecera puede estar completa (si uno recalcula los impuestos, va a estar modificando un pedido que NO deberia modificarse, ya que esta completo y posiblemente contabilizado; y el resulta puede ser distinto, si por ej, algun producto cambio de cat. iva ). Es decir, se viola el “pricipio” de que los documentos completos no se modifican. Se puede dar esto? Y si….. se da todo el tiempo; el punto mas evidente es cuando se completa un remito o una factura asociada a un pedido (sus lineas son modificadas, pero solo ciertas partes como la cantidad entregada y facturada; eso esta bien; el tema es que el after save no mira para nada esto….
    De donde viene este actualizacion de un header por parte de una linea? Y… no se, pero debe venir de que sirve a la gui, ya que te mantiene actualizados los totales cuando uno modifica o agrega una linea….
    Que solucion veo? Que esto solo se lleve a cabo cuando el pedido que contitne a la linea este en estado drafted… En realidad es una situación tan común modificar un documento cuando NO esta en drafted (externamente via el codigo de otro documento, por ej, de un remito, sobre las lineas de un pedido), que pienso que habria que poner un metodo directametne en PO, que sirva para todos estos casos; algo como

    Code:
    public boolean isHeaderDrafted(String TableHeader, int IdHeader)
    {
    if (idHeader <= 0) false; //igual , se supune que es llamado desde el afterSave //o del beforeSave pero cuanod no "isNew"; asi que no deberia darse ya que se deberia haber setedo en la linea String sqlST = "SELECT DocStatus FROM " + TableHeader + " WHERE " + TableHeader+"_ID = " + getId(); PreparedStatement pstmt = DB.preparedStatement(sqlST,getTrx_Name()); String ST = null; //try.... y toda la bola ResultSet rs = pstmt.executeQuery(); if (rs.next()) ST = rs.getString(1); else //se loguea algun error, return "DR".equals(ST); }

    (fijate que el el preparedStatement corre sobre la transacción que esta usado el objeto actual… si no, se rompe todo; va a pasar los mismo que el select que te dije antes…)
    Entonces, el codigo del afterSave, no puede hacerse mas eficiente:

    Code:
    afterSave…. sobre el final
    ….
    if (isHeaderDrafted(“C_Order”,getC_Order_ID())
    {

    //SOLO ahora actualizo los totales y los impuestos…
    //si esto es necesario claro; SI NO, no se toca nada del
    //header, ya que no esta en estado Drafted

    }

    Lo ultimo, como te dije, no solo es por eficiencia, si no también por correctitud, y pienso que se debería aplicar a MInvoceLine y MInOutLine (bueno , en realidad , a casi cualquier cosa que se una “linea” de un documento; incluso tal vez a otras cosa relacionadas, como COrderTax, o CInvoiceTax).

    Incluso mas… en el beforeSave o afterSave se podria llegar a dispara un error si se descubre que se esta modificando algo que no deberia poder ser modificado sobre un pedido/remito/factura no drafted. Por ej, desde la linea del pedido se deberia chequear que cosas como la cantidad o el producto NO estan siendo modificadas en un pedido NO drafted (en el caso del pedido creo que hay solo 2 o 3 columnas que deberias ser permitidas modicadas desde codigo: la cantidades ordernadas, entregadas y facturadas; todo lo demas, SOLO si el pedido esta en DR). También por ej, en el before o afterSave de registro nuevos se debería poder evitar la inserción sobre no documento no DR (algo similar en before o after delete).

    La ganancia que tenes ahi de efincia es de 2 o 3 accesos por cada modificación de linea de pedido luego de que este esta en estado completo (hay que contar que el chequeo te come 1 acceso, asi que la ganancia no es tan grande).

    Finalmente, esto no afecta la correctitud (en realidad, el código que afecta a la cabecera puede ser elminado completamente; salvo que desde la gui no se va a tener los resultados calculados hasta que hasta que uno lo complete), ya que el prepareIt de Morder, recalcula todo de nuevo, asi que las COrderTax y los totales van a estar ok.

Viendo 3 entradas - de la 1 a la 3 (de un total de 3)
  • Debes estar registrado para responder a este debate.