Actualizar los precios de la lista de materiales

En este ejemplo, veremos cómo volver a calcular los precios de los artículos a partir de su lista de materiales. En la práctica, al cambiar el precio de un producto podremos ver en qué lista de materiales se encuentra y desde allí volveremos a calcular los precios de los productos padre.

Grupo ScriptEvento
FichaPost Guardado

Entonces, veamos cómo usar una función recursiva, es decir, una función que se autodenomina para poder calcular todos los niveles de la lista de materiales (billmaterials_dn) de cada producto pasado.

El script se vinculará al Post Guardado del producto.

function calculate(gfather)
        - extract the bill of materials and recover the
        prices and the costs
 
        tfather = database.getsql("SELECT * FROM
        billmaterials_dn WHERE gguidp='" .. gfather .."'")
        nrowsp = tfather.countrows()
        rowsp = tfather.getrows()
        finalprice = 0
        finalcost = 0
 
        for i = 1,nrowsp do
               finalprice = finalprice + rowsp[i].getvalue("total_price")
               finalcost  = finalcost + rowsp[i].getvalue("total_cost")
        end


        database.setsql("UPDATE items SET update=1,cost=" .. utility.formatnum(finalcost,2) ..",price=" .. utility.formatnum(finalprice,2) ..  " WHERE gguid='" .. gfather .. "'")
        database.setsql("UPDATE items SET tid=" .. tostring(utility.tid()) .. " WHERE gguid='" .. gfather .. "'")
 
        database.addsyncbox("items",gfather)
 
        - check if this is not a child of someone else, if you then start at calculate the other fathers
 
        tfathers = database.getsql("SELECT * FROM billmaterials_dn WHERE gguid_code_dn='" .. gfather .. "'")


        nrowsfathers = tfathers.countrows()
        rowsfathers = tfathers.getrows()
        - Update the prices and costs if the object is used as a son on other lists


        sprice = utility.formatnum(finalprice,2)
        scost = utility.formatnum(finalcost,2)


        gguidfathers = {}
 
        for i = 1,nrowsfathers do
               database.setsql("UPDATE billmaterials_dn SET cost=" .. scost  .. ",price=" .. sprice ..  " WHERE gguid='" .. rowsfathers[i].getvalue("gguid") .. "'")
 
               database.setsql("UPDATE billmaterials_dn SET total_cost=cost * qty_dn,total_price=price * qty_dn WHERE .. rowsfathers[i].getvalue("gguid") .. "'")
 
               database.setsql("UPDATE billmaterials_dn SET tid=" ..
               tostring(utility.tid()) .. " WHERE gguid='" .. rowsfathers[i].getvalue("gguid") .. "'")
 
               database.addsyncbox("billmaterials_dn", rowsfathers[i].getvalue("gguid"))
 
               -- extract the fathers' gguids
               table.insert(gguidfathers,"gguidp"))
        end
 
        -- I proceed to recursively process the items
        for i,gp in pairs(gguidfathers) do
               calculate(gp)
        end


end

Primero escribimos la función recursiva que considera que el gguid del producto se actualiza como un parámetro de entrada. De esta forma se recupera la tabla de la lista de materiales, se recalcula y actualiza su precio (price). Durante la actualización recuperamos los gguids de los productos que los llevan de vuelta a sus listas de materiales y, como puede ver, llamamos a la misma función, creando así la recursión.

En la práctica, el sistema actualiza el producto desde el nivel cada vez más bajo (siempre dado por el producto que modificamos al principio) y luego vuelve a calcular al revés a todos sus padres.

price = dataview.getvalue("price")
cost = dataview.getvalue("cost")
gguid = dataview.getvalue("gguid")
sprice = utility.formatnum(price,2)
scost = utility.formatnum(cost,2)
- extrapol where the article is used and
update the price and the cost
 
tlist = database.getsql("SELECT * FROM billmaterials_dn WHERE gguid_code_dn='" .. gguid .."'")
nrows = tlist.countrows()
rows = tlist.getrows()
gguidfathers = {}
for i = 1,nrows do
 
       database.setsql("UPDATE billmaterials_dn SET cost=" .. scost .. ",price=" .. sprice ..  " WHERE gguid='" .. rows[i].getvalue("gguid") .. "'")
 
       database.setsql("UPDATE billmaterials_dn SET total_cost=cost * qty_dn,total_price=price * qty_dn WHERE ..  rows[i].getvalue("gguid") .. 
        "'")
 
       database.setsql("UPDATE billmaterials_dn SET tid=" .. tostring(utility.tid()) .. " WHERE gguid='" .. rows[i].getvalue("gguid") .. "'")


        database.addsyncbox("billmaterials_dn", rows[i].getvalue("gguid"))
 
       -- extract the fathers' gguids
       table.insert(gguidfathers,rows[i].getvalue("gguidp"))
end
 
-- I proceed to recursively process the itemsfor i,gp in pairs(gguidfathers) do
       calcolate(gp)
end
 
program.refreshsection("items")

En esta parte del script, la que realmente lanzó el programa, recuperamos la información del producto y actualizamos los precios (prices) y los costos (costs) en los que este último aparece en las listas de materiales (billmaterials_dn). De esta manera, será posible recuperar los gguids de los padres que luego pasarán a la función Calcula. A partir de ahí, para cada padre, la función subirá por la cadena de productos asegurando que la modificación realizada por el producto inicial se implemente por todas las listas de materiale y, por lo tanto, por los precios y costos de los aproductos que lo recuerdan directamente o indirectamente.