B4A=true Group=Default Group ModulesStructureVersion=1 Type=Class Version=12.8 @EndOfDesignText@ Sub Class_Globals Dim ruta As String Dim almacen As String Dim cliente As String Dim db As SQL Private EventName As String 'ignore Private CallBack As Object 'ignore End Sub 'Initializes the object. You can add parameters to this method if needed. Public Sub Initialize (vCallback As Object, vEventName As String, db0 As SQL) As Object EventName = vEventName CallBack = vCallback db = db0 Log("PROMOS INIT") db.ExecNonQuery("CREATE TABLE IF NOT EXISTS PROMOCIONES_INFO (P_ID TEXT, P_ESTATUS TEXT, P_MAXXCLIENTE NUMERIC, P_MAXRECURRENTE NUMERIC, P_MAXPROMOS NUMERIC, HISTORICO TEXT, P_TIPOS TEXT, P_PRODSFIJOS TEXT, P_PRODSFIJOS_CANT NUMERIC, P_PRODSFIJOS_PIEZAS TEXT, P_PRODSFIJOS_PRECIOS TEXT, P_PRODSVARIABLES TEXT, P_PRODSVARIABLES_CANT NUMERIC, P_PRODSVARIABLES_PRECIOS TEXT, P_PRODSVARIABLES_REQUERIDOS NUMERIC)") db.ExecNonQuery("DELETE FROM PROMOCIONES_INFO") Return Me End Sub Sub procesaPromocion(idPromo As String, cliente0 As String) As Map 'ignore Private thisLog As Boolean = False 'Si es verdadero, muestra los logs de este sub. cliente = cliente0 Private inicioContador As String = DateTime.Now Private maxPromos As Int = 0 If thisLog Then LogColor($"********* Iniciamos revision de Promo ${idPromo} *********"$, Colors.red) ' LogColor("**************************** " & traeInfoFromPromo("P_PRODSFIJOS", idPromo), Colors.blue) ' Private d As List = traeListFromPromo("P_PRODSFIJOS", idPromo) ' Log(d.Get(0)) 'Obtenemos el mapa con toda la info de la promoción. ' Private pm As Map = traePromo(idPromo, cliente) traePromo(idPromo, cliente0) ' If thisLog Then LogColor(pm, Colors.Blue) ' If thisLog Then LogColor("|" & pm.Get("maxPromos") & "|", Colors.Blue) ' Log("|"&revisaMaxPromosProdsFijosPorInventario(pm)&"|") If revisaMaxPromosProdsFijosPorInventario(idPromo) < 1 Then db.ExecNonQuery($"update PROMOCIONES_INFO set P_ESTATUS = 'ko' where P_ID = '${idPromo}'"$) Log($"resultado = ${traeInfoFromPromo("P_ESTATUS", idPromo)}"$) If traeInfoFromPromo("P_ESTATUS", idPromo) = "ok" Then 'Si encontramos la promoción, entonces ... 'Buscamos el máximo de promociones permitidas. maxPromos = traeMaxPromos(idPromo) ' If thisLog Then LogColor($"Promociones permitidas=${mp}"$, Colors.Blue) ' If thisLog Then Log("Promos vendidas: " & traePromosVendidas(idPromo, cliente)) If maxPromos < 1 Then If thisLog Then LogColor("Ya se vendieron las promos PERMITIDAS para el cliente", Colors.red) Return CreateMap("status":"ko") ' , "mp":pm End If 'Restamos del inventario (mapa) las piezas necesarias para los productos fijos. Private inventarioSinFijos As Map = restaFijosPromo(idPromo, CreateMap()) If thisLog Then LogColor("inventariosfijos="&inventarioSinFijos, Colors.Magenta) ' If inventarioSinFijos.Get("resultado") = "ok" Then ' 'Revisamos que los productos variables requeridos sean menos que el inventario total (mapa). ' Private pv As Boolean = alcanzanLosVariablesParaPromo(pm, inventarioSinFijos) ' If thisLog Then Log("Alcanzan los variables? --> " & pv) ' If pv Then Return CreateMap("status":"ok", "mp":pm) Else Return CreateMap("status":"ko", "mp":pm) ' Else ' If thisLog Then LogColor("NO HAY INVENTARIO SUFICIENTE " & idPromo, Colors.red) ' Return CreateMap("status":"ko", "mp":pm) ' End If Else Return CreateMap("status":"ko") ' , "mp":pm End If ' Si tenemos suficiente inventario para los variables mostramos la promocion, si no ... ' break 'NO HAY INVENTARIO SUFICIENTE PARA LA PROMOCION. LogColor("TIEMPO DE PROCESO ESTA PROMO: " & ((DateTime.Now-inicioContador)/1000), Colors.Red) End Sub 'Regresa un mapa con la información de la promo. 'Regresa: {id, maxXcliente, maxRecurrente, maxPromos, historico, ' productos={idProducto={idProducto, preciosimptos, precio, almacen, tipo, piezas, usuario, fecha, regalo, clasif}} 'Mapa con los productos de la promo y los datos de cada uno. ' tipos={idProducto=tipo} 'Mapa con id y tipo del producto, 0 si es fijo y 1 si es variable. ' prodsFijos={idProducto,idProducto} 'Lista con los ids de los productos fijos. ' prodsVariables={idProducto,idProducto} 'Lista con los ids de los productos variables. ' resultado="OK" 'Ok si existe la promocion. ' prodsVariablesRequeridos=5} 'Cantidad de productos variables requeridos para la promoción. Sub traePromo(promo As String, cliente0 As String) As Map Private thisLog As Boolean = True If thisLog Then LogColor("############# traePromoC: "&promo, Colors.red) Private inicioContador As String = DateTime.Now Private c As Cursor = Starter.skmt.ExecQuery("Select * from promos_comp where cat_pa_id = '"& promo&"'") 'Obtenemos las el maximo de promocioones a otorgar. Private siHistorico As String = 0 ' Private promoMap As Map Private prodsFijos, prodsFijosPrecios, prodsFijosPiezas, prodsVariables, prodsVariablesPrecios As List ' promoMap.Initialize prodsFijos.Initialize prodsFijosPrecios.Initialize prodsFijosPiezas.Initialize prodsVariables.Initialize prodsVariablesPrecios.Initialize c.Position = 0 ' promoMap = CreateMap("id":promo, "maxXcliente":0, "maxRecurrente":0, "maxPromos":0) 'Ponemos el DEFAULT en CERO. Private yaExistePromo As Cursor = db.ExecQuery($"SELECT P_ID from PROMOCIONES_INFO where P_ID = '${promo}'"$) If yaExistePromo.RowCount > 0 Then db.ExecNonQuery($"update PROMOCIONES_INFO set P_MAXXCLIENTE = 0, P_MAXRECURRENTE = 0, P_MAXPROMOS = 0 where P_ID = '${promo}'"$) Else db.ExecNonQuery($"insert into PROMOCIONES_INFO (P_ID, P_MAXXCLIENTE, P_MAXRECURRENTE, P_MAXPROMOS) values ('${promo}', 0, 0, 0)"$) End If If c.RowCount > 0 Then ' promoMap = CreateMap("id":promo, "maxXcliente":c.GetString("CAT_PA_MAXPROMCLIE"), "maxRecurrente":c.GetString("CAT_PA_MAXPROMREC"), "maxPromos":c.GetString("CAT_PA_MAXPROM")) db.ExecNonQuery($"update PROMOCIONES_INFO set P_MAXXCLIENTE = ${c.GetInt("CAT_PA_MAXPROMREC")}, P_MAXRECURRENTE = ${c.GetInt("CAT_PA_MAXPROMREC")}, P_MAXPROMOS = ${c.GetInt("CAT_PA_MAXPROM")} where P_ID = '${promo}'"$) ' Log($"update PROMOCIONES_INFO set P_MAXXCLIENTE = ${c.GetInt("CAT_PA_MAXPROMREC")}, P_MAXRECURRENTE = ${c.GetInt("CAT_PA_MAXPROMREC")}, P_MAXPROMOS = ${c.GetInt("CAT_PA_MAXPROM")} where P_ID = '${promo}'"$) End If '######### PROMOCIONES SEGMENTADAS ########## ' Si la promo esta en la lista, SOLO los clientes que la tengan la pueden ver. Private ps As Cursor = Starter.skmt.ExecQuery($"select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${cliente0}' "$) ' Log($"select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${cliente0}' "$) Log($"PROMOS SEGMENTADAS DISPONIBLES: ${ps.RowCount}"$) If ps.RowCount > 0 Then ps.Position = 0 db.ExecNonQuery($"update PROMOCIONES_INFO set P_MAXXCLIENTE = 0, P_MAXRECURRENTE = 0, P_MAXPROMOS = 0 where P_ID = '${promo}'"$) 'Si es segmentada la ponemos en cero, porque SOLO le debe de aparecer a ciertos clientes. ' promoMap = CreateMap("id":promo, "maxXcliente":0, "maxRecurrente":0, "maxPromos":0) 'Si es segmentada la ponemos en cero, porque SOLO le debe de aparecer a ciertos clientes. LogColor($">>> PROMO "${promo}" SEGMENTADA PARA EL CLIENTE ${ps.GetString("HCCP_CLIENTE")}"$, Colors.Magenta) ' Select hccp_cliente As valido from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${traecliente}' Private ps2 As Cursor = Starter.skmt.ExecQuery($"Select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${cliente0}' and HCCP_CANT > HCCP_CANT_VENDIDA"$) ' Log($"Select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${traeCliente}' and HCCP_CANT > HCCP_CANT_VENDIDA"$) Log($"registros:${ps2.RowCount}"$) If ps2.RowCount > 0 Then ps2.Position = 0 ' Log($"registros:${ps2.RowCount}, cliente: ${ps2.GetString("HCCP_CLIENTE")} cant:${ps2.GetString("HCCP_CANT")}, Vendidas: ${ps2.GetString("HCCP_CANT_VENDIDA")}"$) db.ExecNonQuery($"update PROMOCIONES_INFO set P_MAXXCLIENTE = ${(ps2.getint("HCCP_CANT")-ps2.GetInt("HCCP_CANT_VENDIDA"))}, P_MAXRECURRENTE = ${ps2.GetString("HCCP_CANT")}, P_MAXPROMOS = ${ps2.GetString("HCCP_CANT")} where P_ID = '${promo}'"$) 'Si es segmentada SOLO le aparece a ciertos clientes. ' Log($"update PROMOCIONES_INFO set P_MAXXCLIENTE = ${(ps2.GetString("HCCP_CANT")-ps2.GetString("HCCP_CANT_VENDIDA"))}, P_MAXRECURRENTE = ${ps2.GetString("HCCP_CANT")}, P_MAXPROMOS = ${ps2.GetString("HCCP_CANT")} where P_ID = '${promo}'"$) ' promoMap = CreateMap("id":promo, "maxXcliente":(ps2.GetString("HCCP_CANT")-ps2.GetString("HCCP_CANT_VENDIDA")), "maxRecurrente":ps2.GetString("HCCP_CANT"), "maxPromos":ps2.GetString("HCCP_CANT")) 'Si es segmentada SOLO le aparece a ciertos clientes. End If End If ' Log(promoMap) ' Log($"P_MAXXCLIENTE = ${(ps2.GetString("HCCP_CANT")-ps2.GetString("HCCP_CANT_VENDIDA"))}, P_MAXRECURRENTE = ${ps2.GetString("HCCP_CANT")}, P_MAXPROMOS = ${ps2.GetString("HCCP_CANT")}'"$) ' ########## TERMINA PROMOS SEGMENTADAS ########## c = Starter.skmt.ExecQuery("Select count(*) as hist from HIST_PROMOS where HP_CLIENTE = '"& cliente0 & "' and HP_CODIGO_PROMOCION = '" & promo & "'") 'Revisamos si hay historico de la promoción. c.Position = 0 If c.GetString("hist") > 0 Then siHistorico = 1 db.ExecNonQuery($"update PROMOCIONES_INFO set HISTORICO = ${siHistorico} where P_ID = '${promo}'"$) ' promoMap.Put("historico", siHistorico) c = Starter.skmt.ExecQuery("Select * from CAT_DETALLES_PAQ where CAT_DP_ID = '"& promo & "'") 'Obtenemos los detalles de la promoción. c.Position = 0 If c.RowCount > 0 Then Private prods, tipos As Map prods.Initialize tipos.Initialize For i = 0 To c.RowCount -1 c.Position=i prods.Put(c.GetString("CAT_DP_IDPROD"), CreateMap("idProducto":c.GetString("CAT_DP_IDPROD"), "precioSimptos":c.GetString("CAT_DP_PRECIO_SIMPTOS"), "precio":c.GetString("CAT_DP_PRECIO"), "tipo":c.GetString("CAT_DP_TIPO"), "piezas":c.GetString("CAT_DP_PZAS"), "regalo":c.GetString("CAT_DP_REGALO"), "clasif":c.GetString("CAT_DP_CLASIF"))) tipos.Put(c.GetString("CAT_DP_IDPROD"), c.GetString("CAT_DP_TIPO")) If c.GetString("CAT_DP_TIPO") = "0" Then prodsFijos.Add(c.GetString("CAT_DP_IDPROD")) prodsFijosPrecios.Add(c.GetString("CAT_DP_PRECIO")) prodsFijosPiezas.Add(c.GetString("CAT_DP_PZAS")) End If If c.GetString("CAT_DP_TIPO") = "1" Then prodsVariables.Add(c.GetString("CAT_DP_IDPROD")) prodsVariablesPrecios.Add(c.GetString("CAT_DP_PRECIO")) End If ' If thisLog Then Log($"id:${c.GetString("CAT_DP_IDPROD")}, tipo:${c.GetString("CAT_DP_TIPO")}"$) Next db.ExecNonQuery($"update PROMOCIONES_INFO set P_TIPOS = '${tipos}', P_PRODSFIJOS = '${prodsFijos}', P_PRODSFIJOS_CANT = ${prodsFijos.Size}, P_PRODSFIJOS_PRECIOS = '${prodsFijosPrecios}', P_PRODSFIJOS_PIEZAS = '${prodsFijosPiezas}', P_PRODSVARIABLES = '${prodsVariables}', P_PRODSVARIABLES_CANT = ${prodsVariables.Size}, P_PRODSVARIABLES_PRECIOS = '${prodsVariablesPrecios}', P_ESTATUS = 'ok' where P_ID = '${promo}'"$) ' promoMap.Put("productos", prods) 'Mapa con los productos de la promocion (id, precio, almacen, tipo, piezas, etc.) ' promoMap.Put("tipos", tipos) 'Mapa con los productos de la promoción y su tipo (fijo o variable). ' promoMap.Put("prodsFijos", prodsFijos) 'Lista de los productos fijos de la promoción. ' promoMap.Put("prodsFijosCant", prodsFijos.Size) ' promoMap.Put("prodsFijosPrecios", prodsFijosPrecios) ' promoMap.Put("prodsFijosPiezas", prodsFijosPiezas) ' promoMap.Put("prodsVariables", prodsVariables) 'Lista de los productos variables de la promoción. ' promoMap.Put("prodsVariablesCant", prodsVariables.Size) ' promoMap.Put("prodsVariablesPrecios", prodsVariablesPrecios) ' promoMap.Put("resultado", "ok") Else ' promoMap.Put("resultado", "No hay datos de la promoción.") db.ExecNonQuery($"update PROMOCIONES_INFO set P_ESTATUS = 'No hay datos de la promoción.' where P_ID = '${promo}'"$) End If c = Starter.skmt.ExecQuery("Select CAT_GP_STS, CAT_GP_NOMBRE from CAT_GUNAPROD2 where CAT_GP_ID = '"& promo & "'") 'Obtenemos las piezas requeridas de productos variables para la promoción. c.Position = 0 Private pvr As String = 0 If c.RowCount > 0 Then c.Position = 0 pvr = c.GetString("CAT_GP_STS") ' promoMap.Put("prodsVariablesRequeridos", pvr) 'Cantidad de productos variables requeridos para la promoción. ' promoMap.put("descripcion", c.GetString("CAT_GP_NOMBRE")) db.ExecNonQuery($"update PROMOCIONES_INFO set P_PRODSVARIABLES_REQUERIDOS = ${pvr} where P_ID = '${promo}'"$) 'Cantidad de productos variables requeridos para la promoción. End If c.Close ' If thisLog Then Log($"Inv variables: ${cuantosVariablesDisponiblesDB(promo)}"$) ' If thisLog Then Log($"Inv dispo: ${traemosInventarioDisponibleParaPromo(promo)}"$) ' If thisLog Then LogColor($"Promo ${promo}: ${promoMap}"$, Colors.Blue) If thisLog Then LogColor("TIEMPO para traePromo -=" & promo & "=- : " & ((DateTime.Now-inicioContador)/1000), Colors.Red) ' Return promoMap End Sub 'Regresa cuantas promos alcanzan con los productos FIJOS que hay en inventario. Sub revisaMaxPromosProdsFijosPorInventario(id As String) As Int ' Private pm As Map = CreateMap() '' XXXXXXXX Private thisLog As Boolean = True Private invFijoXpromo As Map Private t As List Private c As ResultSet = db.ExecQuery($"select P_PRODSFIJOS, P_PRODSFIJOS_PIEZAS from PROMOCIONES_INFO where P_ID = '${id}'"$) t.Initialize t.Add(traeMaxPromos(id)) ' Agregamos a la lista las promos maximas permitidas (recurrente, cliente y promo). invFijoXpromo.Initialize ' If thisLog Then LogColor($"pm=${pm}"$, Colors.Blue) Private invDispParaPromo As Map = traemosInventarioDisponibleParaPromo(id) If thisLog Then Log(">>>>> " & $"invDispParaPromo=${invDispParaPromo}"$) Private prodsFijosPiezas As List = traeListFromPromo("P_PRODSFIJOS_PIEZAS", id) Private idProdsFijos As List = traeListFromPromo("P_PRODSFIJOS", id) Log($"${idProdsFijos},${prodsFijosPiezas}"$) For p = 0 To idProdsFijos.Size -1 'Generamos una lista con las promos disponibles por producto (dividimos el inventario total entre las piezas requeridas). Private thisInvDisp As Int = 0 Log($"|${invDispParaPromo.Get("3800025096")}|"$) Private tmpId As String = idProdsFijos.Get(p) Log($"### ThisP = |${idProdsFijos.Get(p)}| -> |${invDispParaPromo.Get(tmpId)}| -> |${invDispParaPromo.Get(idProdsFijos.Get(p).As(String))}|"$) If invDispParaPromo.Get(idProdsFijos.Get(p).As(String)) <> Null Then thisInvDisp = invDispParaPromo.Get(idProdsFijos.Get(p).As(String)) Log($"thisInvDisp = ${thisInvDisp}"$) End If If thisLog Then Log($"id=${idProdsFijos.Get(p)}, inv=${thisInvDisp}, pzas=${prodsFijosPiezas.Get(p)}"$) If thisLog Then Log($"${(thisInvDisp / prodsFijosPiezas.Get(p))}"$) Private x() As String = Regex.Split("\.", $"${(thisInvDisp / prodsFijosPiezas.Get(p))}"$) 'Separamos el resultado de la division por el punto decimal. If thisLog Then Log(x(0)) t.Add(x(0).As(Int)) 'Solo guardamos la parte del entero de la division. Next t.Sort(True) 'Ordenamos la lista para que en el lugar 0 este el resultao mas pequeño. If thisLog Then LogColor($"prodsFijos=${idProdsFijos}"$, Colors.Blue) If thisLog Then LogColor($"prodsFijosPiezasReq=${prodsFijosPiezas}"$, Colors.Blue) If thisLog Then LogColor($"invFijoXpromo=${invFijoXpromo}"$, Colors.Blue) If thisLog Then LogColor("Max promos de prodsFijos POR inventario = " & t.Get(0), Colors.red) ' LogColor(">>>>>> " & t.Get(0), Colors.red) Return t.Get(0) 'Regresamos el resultado mas pequeño. End Sub 'Regresa cuantas promos alcanzan con los productos VARIABLES que hay en inventario. 'La cantidad de promos disponibles se calcula DESPUES de descontar los productos fijos, y si las 'promos por productos fijos llega al maximo, aunque se puedan mas de producos variables, solo se 'regresa el maximo por productos fijos. Ej. si las promos por variables es 10, pero el maximo por 'fijos es 5, entonces regresamos 5. Sub revisaMaxPromosProdsVariablesPorInventario(pm As Map) As Int 'ignore Private thisLog As Boolean = True If thisLog Then Log("======================================================") If thisLog Then Log("======================================================") Private invFijoXpromo As Map invFijoXpromo.Initialize Private totalProdsVariablesDisponibles As Int = 0 If thisLog Then LogColor($"pm=${pm}"$, Colors.Blue) Private invDispParaPromo As Map = traemosInventarioDisponibleParaPromo(pm.Get("id")) If thisLog Then Log($"invDispParaPromo=${invDispParaPromo}"$) Private maxPromos As String = traeMaxPromos(pm) Private maxPromosXFijos As Int = revisaMaxPromosProdsFijosPorInventario(pm) Private idProdsVariables As List = pm.Get("prodsVariables") Private prodsVariablesRequeridos As Int = pm.Get("prodsVariablesRequeridos") Private prodsFijosPiezas As List = pm.Get("prodsFijosPiezas") Private idProdsFijos As List = pm.Get("prodsFijos") For p = 0 To idProdsFijos.Size -1 'Generamos mapa con los productos fijos y piezas requeridas por promo. invFijoXpromo.Put(idProdsFijos.Get(p), prodsFijosPiezas.Get(p)) Private idEsteProd As String = idProdsFijos.Get(p) Private invEsteProd As Int = invDispParaPromo.Get(idEsteProd) Private pzasReqEsteProd As Int = prodsFijosPiezas.Get(p) If thisLog Then Log($"id=${idEsteProd}, inv=${invEsteProd}, pzas=${pzasReqEsteProd}"$) ' invDispParaPromo.Put( idEsteProd, (invEsteProd - (1)) ) Next If thisLog Then LogColor($"MaxPromos=${maxPromos}, promosXFijos=${maxPromosXFijos}"$, Colors.Blue) If thisLog Then LogColor($"prodsFijos=${idProdsFijos}"$, Colors.Blue) If thisLog Then LogColor($"prodsFijosPiezasReq=${prodsFijosPiezas}"$, Colors.Blue) If thisLog Then LogColor($"prodsVariables=${idProdsVariables}${CRLF}Variables Req=${prodsVariablesRequeridos} "$, Colors.Blue) If thisLog Then LogColor($"invFijoXpromo=${invFijoXpromo}"$, Colors.Blue) If thisLog Then Log($"Prods variables disponibles = ${totalProdsVariablesDisponibles}"$) Private maxPromosXVariables As Int = 0 For x = 1 To maxPromosXFijos If thisLog Then Log("=====================================================") If thisLog Then Log("=====================================================") For i = 0 To idProdsFijos.Size - 1 If thisLog Then Log($"FIJO - ${idProdsFijos.Get(i)}, ${invDispParaPromo.Get(idProdsFijos.Get(i))} - ${prodsFijosPiezas.Get(i).As(Int)*(i+1)}"$) invDispParaPromo.Put(idProdsFijos.Get(i), invDispParaPromo.Get(idProdsFijos.Get(i)).As(Int) - prodsFijosPiezas.Get(i).As(Int)*(i+1)) 'Restamos las piezas de los productos fijos del inventario disponible. Next If thisLog Then LogColor("Inv disponible despues de restar fijos = " & invDispParaPromo, Colors.Blue) totalProdsVariablesDisponibles = 0 For i = 0 To idProdsVariables.Size - 1 'Obtenemos total de productos variables disponibes. If invDispParaPromo.ContainsKey(idProdsVariables.Get(i)) Then totalProdsVariablesDisponibles = totalProdsVariablesDisponibles + invDispParaPromo.Get(idProdsVariables.Get(i)) End If Next 'Revisamos variables. If thisLog Then Log($"Var disponibles - var requeridos : ${totalProdsVariablesDisponibles} - ${prodsVariablesRequeridos*x}"$) totalProdsVariablesDisponibles = totalProdsVariablesDisponibles - (prodsVariablesRequeridos*x) If thisLog Then Log("prodsVariables disponibles despues de promo = " & totalProdsVariablesDisponibles) If totalProdsVariablesDisponibles < 0 Then Exit 'Ya no hay inventario disponible. maxPromosXVariables = x Next 'Restamos fijos. ' LogColor("Max promos de prodsVariables POR inventario = " & maxPromosXVariables, Colors.red) Return maxPromosXVariables End Sub 'Regresa un mapa con el inventario disponible por producto para la promoción (desde la base de datos). Sub traemosInventarioDisponibleParaPromo(promo As String) As Map 'ignore Private c As Cursor c = Starter.skmt.ExecQuery2("SELECT CAT_GP_ID, CAT_GP_ALMACEN FROM CAT_GUNAPROD2 WHERE CAT_GP_ID IN (select CAT_DP_IDPROD FROM CAT_DETALLES_PAQ WHERE CAT_DP_ID = ?)", Array As String(promo)) ' Private prodInv As Map ' prodInv.Initialize Private prods As Map prods.Initialize If c.RowCount > 0 Then For i=0 To c.RowCount -1 c.Position=i prods.Put(c.GetString("CAT_GP_ID"), c.GetString("CAT_GP_ALMACEN")) ' Log($"prod:${c.GetString("CAT_GP_ID")}, inventario:${c.GetString("CAT_GP_ALMACEN")}"$) Next ' prodInv.Put("inventarios", prods) End If Return prods End Sub 'Resta los productos fijos del inventario de la promoción (mapa) y regresa un mapa con el nuevo inventario. 'Hay que darle como parametro un mapa (traePromo(promo)) con toda la informacion de la promocion. 'Regresa en el mapa la llave "resultado" que nos da "ok" o "No hay suficiente producto para la promocion". Sub restaFijosPromo(idPromo As String, promoMap As Map) As Map 'ignore Private thisLog As Boolean = True 'Si es verdadero, muestra los logs de este sub. Private inventariosDisponiblesParaEstaPromo As Map = traemosInventarioDisponibleParaPromo(idPromo) 'Obtenemos un mapa con el inventario disponible para cada producto de la promocion desde la base de datos. If thisLog Then LogColor(inventariosDisponiblesParaEstaPromo, Colors.red) If thisLog Then LogColor("Inventario inicial antes de FIJOS: "&inventariosDisponiblesParaEstaPromo, Colors.Gray) 'Inventario inicial. Private i As Int Private prodsmap As Map = promoMap.Get("productos") 'Obtenemos un mapa con todos los productos de la promoción. Private prodsFijos As List = traeListFromPromo("P_PRODSFIJOS", idPromo) 'Obtenemos un a lista con los productos fijos de la promoción. If thisLog Then LogColor("ProdsFijos -> " & prodsFijos, Colors.red) inventariosDisponiblesParaEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.") 'Valor por default Log($"Prods fijos requeridos ${prodsFijos.Size}"$) If prodsFijos.Size = 0 Then inventariosDisponiblesParaEstaPromo.Put("resultado", "ok") 'Si no lleva prods fijos la promo, entonces ponemos FIJOS OK. For p = 0 To prodsFijos.Size - 1 Private t As String = prodsFijos.Get(p) 'Obtenemos el Id de este producto desde la lista de productos fijos. Private p2 As Map = prodsmap.Get(t) 'Obtenemos un mapa con los datos de este producto (id, precio, almacen, tipo, piezas, etc.) If thisLog Then Log($"T: ${t}, prod ${p2.Get("idProducto")}, piezas: ${p2.Get("piezas")}"$) 'Producto y piezas requeridas If thisLog Then Log("inventariosDisponiblesParaEstaPromo="&inventariosDisponiblesParaEstaPromo) If inventariosDisponiblesParaEstaPromo.ContainsKey(t) Then 'Si el mapa del inventario contiene el id del producto entonces ... i = inventariosDisponiblesParaEstaPromo.get(t) 'Obtenemos del mapa el inventario de este producto. Private nuevoInv As Int = NumberFormat2((i - promoMap.Get("prodsFijosPiezas").As(List).get(p)), 1, 0,0,False) If thisLog Then Log($"Nuevo inventario de ${t}: ${i}-${promoMap.Get("prodsFijosPiezas").As(List).get(p)} = ${nuevoInv}"$) 'El nuevo inventario. inventariosDisponiblesParaEstaPromo.Put(t, $"${nuevoInv}"$) 'Restamos del inventario las piezas requeridas para la promoción y guardamos el nuevo inventario en el mapa. inventariosDisponiblesParaEstaPromo.Put("resultado", "ok") Else 'Si en el mapa no esta el id del producto, entonces no tenemos inventario. inventariosDisponiblesParaEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.") If thisLog Then LogColor("Sin suficiente inventario fijo: " & t, Colors.Blue) Exit End If If i - p2.Get("piezas") < 0 Then inventariosDisponiblesParaEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.") 'Si el inventario de este producto sale negativo, quiere decir que no tenemos suficiente inventario para la promoción. Exit End If Next If thisLog Then LogColor("Inventario final despues de FIJOS: "&inventariosDisponiblesParaEstaPromo, Colors.blue) 'Inventario final. Return inventariosDisponiblesParaEstaPromo End Sub 'Revisa si tenemos los productos variables requeridos para la promoción (mapa). 'Hay que darle como parametro un mapa (traePromo(promo)) con toda la informacion de la promocion. Sub alcanzanLosVariablesParaPromo(promoMap As Map, inventarioSinFijos As Map) As Boolean 'ignore Private thisLog As Boolean = False 'Si es verdadero, muestra los logs de este sub. If thisLog Then LogColor("Inventario inicial: "&inventarioSinFijos, Colors.Gray) 'Inventario inicial. Private totalProdsVariables As Int = 0 ' Private prodsmap As Map = promoMap.Get("productos") 'Obtenemos un mapa con todos los productos de la promoción. Private prodsVariables As List = promoMap.get("prodsVariables") 'Obtenemos un a lista con los productos variables de la promoción. For p = 0 To prodsVariables.Size - 1 Private t As String = prodsVariables.Get(p) 'Obtenemos el Id de este producto desde la lista de productos fijos. If inventarioSinFijos.ContainsKey(t) Then 'Si existe el producto en la lista del inventario, entonces ... Private p2 As Int = inventarioSinFijos.Get(t) 'Obtenemos el inventario disponible este producto. If thisLog Then Log($"prod ${t}, hay: ${p2}"$) 'Producto y piezas requeridas totalProdsVariables = totalProdsVariables + p2 End If Next If thisLog Then Log("Total prods variables=" & totalProdsVariables & ", requeridos=" & promoMap.Get("prodsVariablesRequeridos")) Private res As Boolean = False If totalProdsVariables >= promoMap.Get("prodsVariablesRequeridos") Then res = True 'Si el total de inventario de productos variables (totalProdsVariables) es mayor o igual a los productos requeridos entonces regresamos TRUE Return res End Sub 'Regresa el numero máximo de promociones permitidas, tomando en cuenta recurrentes, clientes y maxPromos. Sub traeMaxPromos(idPromo As String) As Int Private thisLog As Boolean = True 'Si es verdadero, muestra los logs de este sub. Private maxPromos As List Private mp0, mp As String = "0" maxPromos.Initialize Private hccp As Cursor = db.ExecQuery($"select HCCP_CANT from HIST_CLIENTE_CANT_PROMOS where HCCP_CLIENTE = '${cliente}' and HCCP_PROMO = '${idPromo}'"$) If thisLog Then LogColor("==== HISTORICO:"&traeInfoFromPromo("HISTORICO", idPromo), Colors.Red) ' If thisLog Then Log(pm) If traeInfoFromPromo("HISTORICO", idPromo) = "1" Then maxPromos.Add(traeInfoFromPromo("P_MAXRECURRENTE", idPromo).As(Int)) 'Si hay historico, agregamos maxRecurrente If traeInfoFromPromo("P_MAXPROMOS", idPromo) <> "null" Then maxPromos.Add(traeInfoFromPromo("P_MAXPROMOS", idPromo).As(Int)) 'Agregamos maxPromos If traeInfoFromPromo("P_MAXXCLIENTE", idPromo) <> "null" Then maxPromos.Add(traeInfoFromPromo("P_MAXXCLIENTE", idPromo).As(Int)) 'Agregamos maxXcliente If hccp.RowCount > 0 Then 'Agregamos promos HCCP hccp.Position = 0 maxPromos.Add(hccp.GetInt("HCCP_CANT")) End If ' Log($"|${traeInfoFromPromo("HISTORICO", idPromo)}|${traeInfoFromPromo("P_MAXPROMOS", idPromo)}|${traeInfoFromPromo("P_MAXXCLIENTE", idPromo)}|"$) ' Log(maxPromos) maxPromos.Sort(True) If thisLog Then Log($">>>>> Max promos : ${maxPromos}"$) mp = 0 If maxPromos.Size > 0 Then mp0 = maxPromos.Get(0) ' Log(mp0) mp = mp0 - traePromosVendidas(idPromo) If thisLog Then Log($"Max Promos (${mp0}) - promos vendidas (${(traePromosVendidas(idPromo)).As(Int)}) = ${mp}"$) End If Return mp 'Regresamos el numero mas pequeño de las opciones. End Sub 'Regresa la cantidad de promos que se le han vendido al cliente. Sub traePromosVendidas(idPromo As String) As Int Private c As Cursor Private pv As Int = 0 c=db.ExecQuery($"select sum(PE_CANT) as cuantas from PEDIDO where PE_PROID = '${idPromo}' and PE_CLIENTE = '${cliente}'"$) If c.RowCount > 0 Then c.Position = 0 If c.GetString("cuantas") <> Null Then pv = c.GetString("cuantas") End If Return pv End Sub Sub traeInfoFromPromo(col As String, idPromo As String) As String Private res As String = "" Private c As ResultSet = db.ExecQuery($"select ${col} from PROMOCIONES_INFO where P_ID = '${idPromo}'"$) ' Log($"select ${col} from PROMOCIONES_INFO where P_ID = '${idPromo}'"$) Do While c.NextRow res = c.GetString(col) Loop Return res End Sub 'Regresa una lista de la BD, en la BD se guarda como string y esta funcion la convierte en lista nuevamente. Sub traeListFromPromo(col As String, promo As String) As List Private res As List Private s As String Private c As ResultSet = db.ExecQuery($"select ${col} from PROMOCIONES_INFO where P_ID = '${promo}'"$) Do While c.NextRow s = c.GetString(col) Loop If s.StartsWith("[") And s.EndsWith("]") Then Private j As JSONParser j.Initialize(s) res.Initialize2(j.NextArray) Else res.Initialize End If Return res End Sub