mirror of
https://github.com/KeymonSoft/Kelloggs_v4.git
synced 2026-04-17 18:26:11 +00:00
VERSION 6.02.03
This commit is contained in:
@@ -12,6 +12,9 @@ Version=9.85
|
||||
'###################### PULL #############################################################
|
||||
'Ctrl + click ide://run?file=%WINDIR%\System32\cmd.exe&Args=/c&Args=git&Args=pull
|
||||
'###########################################################################################################
|
||||
'###################### PULL FORZADO #############################################################
|
||||
'Ctrl + click Respaldar y Pull: ide://run?file=%WINDIR%\System32\cmd.exe&Args=/c&Args=start&Args=powershell.exe&Args=-ExecutionPolicy&Args=Bypass&Args=-File&Args=..\..\_sync_project.ps1
|
||||
'###########################################################################################################
|
||||
'###################### PUSH #############################################################
|
||||
'Ctrl + click ide://run?file=%WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe&Args=github&Args=..\..\
|
||||
'###########################################################################################################
|
||||
@@ -545,7 +548,7 @@ Sub JobDone(Job As HttpJob)
|
||||
LogColor("Error: " & Job.tag & " : " & Subs.parseHTTPError(Job.ErrorMessage), Colors.red)
|
||||
ToastMessageShow("Error: " & Job.ErrorMessage, True)
|
||||
Else
|
||||
' If logger Then LogColor("JobDone: '" & reqManager.HandleJob(Job).tag & "' - Registros: " & reqManager.HandleJob(Job).Rows.Size, Colors.Green) 'Mod por CHV - 211110
|
||||
If logger Then LogColor("JobDone: '" & reqManager.HandleJob(Job).tag & "' - Registros: " & reqManager.HandleJob(Job).Rows.Size, Colors.Green) 'Mod por CHV - 211110
|
||||
If Job.JobName = "DBRequest" Then
|
||||
Dim result As DBResult = reqManager.HandleJob(Job)
|
||||
If result.Tag = "version" Then 'query tag
|
||||
|
||||
@@ -5,8 +5,6 @@ Type=Class
|
||||
Version=12.8
|
||||
@EndOfDesignText@
|
||||
Sub Class_Globals
|
||||
Private Root As B4XView 'ignore
|
||||
Private xui As XUI 'ignore
|
||||
Dim audb As SQL
|
||||
Dim ruta As String = File.DirInternal
|
||||
End Sub
|
||||
@@ -21,7 +19,7 @@ End Sub
|
||||
|
||||
'This event will be called once, before the page becomes visible.
|
||||
Private Sub B4XPage_Created (Root1 As B4XView)
|
||||
Root = Root1
|
||||
' Root = Root1
|
||||
'load the layout to Root
|
||||
End Sub
|
||||
|
||||
@@ -35,10 +33,12 @@ End Sub
|
||||
'Regresa el almacen actual de la base de datos.
|
||||
Sub traeAlmacen As String 'ignore
|
||||
Private c As Cursor
|
||||
Private a As String
|
||||
Private a As String = ""
|
||||
c = audb.ExecQuery("select ID_ALMACEN from CAT_ALMACEN")
|
||||
c.Position = 0
|
||||
a = C.GetString("ID_ALMACEN")
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
a = C.GetString("ID_ALMACEN")
|
||||
End If
|
||||
c.Close
|
||||
Return a
|
||||
End Sub
|
||||
@@ -50,7 +50,7 @@ Sub traeRuta As String 'ignore
|
||||
c = audb.ExecQuery("select CAT_CL_RUTA from kmt_info limit 1")
|
||||
r = "0"
|
||||
If c.RowCount > 0 Then
|
||||
c.Position=0
|
||||
c.Position = 0
|
||||
r = c.GetString("CAT_CL_RUTA")
|
||||
End If
|
||||
c.Close
|
||||
@@ -62,8 +62,10 @@ Sub traeUsuarioDeBD As String 'ignore
|
||||
Private c As Cursor
|
||||
Private u As String = "SinUsuario"
|
||||
c = audb.ExecQuery("select USUARIO from usuarioa")
|
||||
c.Position=0
|
||||
If c.RowCount > 0 Then u = c.GetString("USUARIO")
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
u = c.GetString("USUARIO")
|
||||
End If
|
||||
c.Close
|
||||
Return u
|
||||
End Sub
|
||||
@@ -71,10 +73,12 @@ End Sub
|
||||
'Trae el cliente de CUENTAA
|
||||
Sub traeCliente As String 'ignore
|
||||
Private c As Cursor
|
||||
Private cl As String
|
||||
Private cl As String = ""
|
||||
c = audb.ExecQuery("Select CUENTA from cuentaa")
|
||||
c.Position = 0
|
||||
cl = c.GetString("CUENTA")
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
cl = c.GetString("CUENTA")
|
||||
End If
|
||||
c.Close
|
||||
Return cl
|
||||
End Sub
|
||||
@@ -1084,7 +1084,7 @@ Sub Guardar_Click
|
||||
b_inicioFinVenta.Text = "TERMINAR VENTA"
|
||||
Log("RESPALDO")
|
||||
kh.RD_respaldoBatch
|
||||
|
||||
|
||||
' Subir_Pedido_Con_Integridad(clie_id)
|
||||
|
||||
mandaPendientes
|
||||
@@ -3292,7 +3292,7 @@ Sub B_IMP_INVBAK_Click
|
||||
Printer1.WriteString("RESUMEN DIA" & CRLF)
|
||||
Printer1.WriteString(sDate & " " & sTime & CRLF)
|
||||
Printer1.WriteString("Vendedor:" & usuario & CRLF)
|
||||
Printer1.WriteString("-------INVENTARIO A BORDO----------" & CRLF)
|
||||
Printer1.WriteString("-------INVENTARIO ABORDO----------" & CRLF)
|
||||
Printer1.WriteString("---II---CD---IIT---VT---RMI---IF---" & CRLF)
|
||||
|
||||
' aqui es donde esta el pedo de julieta de los descuentos quitar el precio2 pero meter un if para saber si es ruta especial o es normal o que show.
|
||||
@@ -3587,7 +3587,7 @@ Sub B_IMP_INV_Click
|
||||
Printer1.WriteString("RESUMEN DIA" & CRLF)
|
||||
Printer1.WriteString(sDate & " " & sTime & CRLF)
|
||||
Printer1.WriteString("Vendedor:" & usuario & CRLF)
|
||||
Printer1.WriteString("-------INVENTARIO A BORDO----------" & CRLF)
|
||||
Printer1.WriteString("-------INVENTARIO ABORDO----------" & CRLF)
|
||||
''' se cambia este Printer1.WriteString("---II---CD---IIT---VT---RMI---IF---" & CRLF) ------- sin RMI
|
||||
Printer1.WriteString("---II---CD---IIT---VT---------IF---" & CRLF)
|
||||
|
||||
@@ -3596,11 +3596,11 @@ Sub B_IMP_INV_Click
|
||||
Log($"Reglones: ${s.RowCount}"$)
|
||||
If s.RowCount > 0 Then
|
||||
For i = 0 To S.RowCount - 1
|
||||
Log(i)
|
||||
' Log(i)
|
||||
Try
|
||||
s.Position = i
|
||||
Printer1.WriteString(s.GetString("CAT_GP_NOMBRE") & CRLF)
|
||||
Log("p"&i)
|
||||
' Log("p"&i)
|
||||
Catch
|
||||
Log(LastException)
|
||||
If logger Then Log("Saliendo con Try/Catch")
|
||||
@@ -3795,14 +3795,14 @@ Sub B_IMP_INV_Click
|
||||
Printer1.WriteString(CRLF)
|
||||
End Try
|
||||
End If
|
||||
|
||||
|
||||
' TOTALES DE LOS ARCHIVOS
|
||||
|
||||
|
||||
s.Close
|
||||
S = Starter.skmt.ExecQuery2("select SUM(CAT_GP_ALMACEN) AS CAT_GP_ALMACEN from cat_gunaprod2 WHERE CAT_GP_CLASIF <> ? ", Array As String("PROMOS"))
|
||||
S.Position = 0
|
||||
a_final =s.GetString("CAT_GP_ALMACEN")
|
||||
|
||||
|
||||
S1.Close
|
||||
S1 = Starter.skmt.ExecQuery("select SUM(CAT_GP_ALMACEN) AS CAT_GP_ALMACEN from cat_gunaprod5 ")
|
||||
S1.Position = 0
|
||||
@@ -3837,6 +3837,7 @@ Sub B_IMP_INV_Click
|
||||
Printer1.WriteString(Printer1.BOLD & "----RESUMEN TOTAL---- " & CRLF)
|
||||
'' se cambia por lo del rmi Printer1.WriteString("---" & a_inicial & "..." & ABORDO & "..." & a_total & "..." & a_venta & "..." & a_final & "..." & RMI & CRLF)
|
||||
Printer1.WriteString("---" & a_inicial & "..." & ABORDO & "..." & a_total & "..." & a_venta & "..." & a_final & "..." & CRLF)
|
||||
Log("---" & a_inicial & "..." & ABORDO & "..." & a_total & "..." & a_venta & "..." & a_final & "..." & CRLF)
|
||||
Printer1.WriteString(Printer1.BOLD & "TOTAL VENTA " & Subs.sumaPedido(Subs.traeCliente) & CRLF)
|
||||
Printer1.WriteString("------------------------------" & CRLF)
|
||||
Printer1.WriteString("Nombre y Firma" & CRLF)
|
||||
@@ -4496,7 +4497,7 @@ End Sub
|
||||
' Llama a esto desde tu botón Subir_Click
|
||||
' Devuelve un ResumableSub que puedes esperar con Wait For
|
||||
Sub Subir_Pedido_Con_Integridad(cliente As String) As ResumableSub
|
||||
|
||||
|
||||
Log("--- Iniciando Envío Seguro para Cliente: " & cliente & " ---")
|
||||
|
||||
' 1. Generar ARCH (Identificador Único del Paquete)
|
||||
@@ -4564,13 +4565,11 @@ Sub Subir_Pedido_Con_Integridad(cliente As String) As ResumableSub
|
||||
Dim cmd As DBCommand
|
||||
cmd.Initialize
|
||||
cmd.Name = "insert_pedido_KELL_arch"
|
||||
|
||||
cmd.Parameters = Array As Object(cPed.GetString("PE_CEDIS"), Subs.traeAlmacen, cPed.GetString("PE_COSTO_TOT"), cPed.GetString("PE_COSTOU"), cPed.GetString("PE_CANT"), cPed.GetString("PE_PRONOMBRE"), cPed.GetString("PE_PROID"), cPed.GetString("PE_CLIENTE"), cPed.GetString("PE_FECHA"), cPed.GetString("PE_USUARIO"), cPed.GetString("PE_RUTA"), cPed.GetString("PE_COSTO_SIN"), cPed.GetString("PE_DESC"), cPed.GetString("PE_FOLIO"), cPed.GetString("PE_TIPO"), cPed.GetString("PE_ARCH"))
|
||||
|
||||
reqManagerW.ExecuteCommand(Starter.DBReqServer, cmd, Me, "detalle_envio")
|
||||
|
||||
|
||||
Wait For detalle_envio_Completed (ResultDet As TResultado)
|
||||
|
||||
|
||||
If ResultDet.Success = False Then
|
||||
Log("Error enviando producto " & cPed.GetString("PE_PRONOMBRE"))
|
||||
envioCorrecto = False
|
||||
|
||||
@@ -1549,7 +1549,7 @@ Sub JobDone(Job As HttpJob)
|
||||
Dim CAT_GP_TIPOPROD As Int = records(RESULT.Columns.Get("CAT_GP_TIPOPROD"))
|
||||
' Dim CAT_GP_DEV As String = records(RESULT.Columns.Get("CAT_GP_DEV"))
|
||||
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD2(CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG,CAT_GP_ALMACEN,CAT_GP_TIPOPROD,CAT_GP_DEV,CAT_GP_CODPROMO) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,0)", Array As Object (CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG, CAT_GP_ALMACEN,CAT_GP_TIPOPROD,"0"))
|
||||
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD5(CAT_GP_ID,CAT_GP_ALMACEN) VALUES (?,?)", Array As Object (CAT_GP_ID,CAT_GP_ALMACEN))
|
||||
' Starter.skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD5(CAT_GP_ID,CAT_GP_ALMACEN) VALUES (?,?)", Array As Object (CAT_GP_ID,CAT_GP_ALMACEN))
|
||||
' skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD2(CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG,CAT_GP_ALMACEN,CAT_GP_TIPOPROD,CAT_GP_DEV,CAT_GP_CODPROMO) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,0)", Array As Object (CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG, CAT_GP_ALMACEN,CAT_GP_TIPOPROD,"0"))
|
||||
Next
|
||||
Starter.skmt.TransactionSuccessful
|
||||
@@ -1594,7 +1594,7 @@ Sub JobDone(Job As HttpJob)
|
||||
Dim CAT_GP_ALMACEN As Int = records(RESULT.Columns.Get("CAT_GP_ALMACEN"))
|
||||
Dim CAT_GP_TIPOPROD As Int = records(RESULT.Columns.Get("CAT_GP_TIPOPROD"))
|
||||
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD2(CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG,CAT_GP_ALMACEN,CAT_GP_TIPOPROD) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", Array As Object (CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG, CAT_GP_ALMACEN,CAT_GP_TIPOPROD))
|
||||
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD5(CAT_GP_ID,CAT_GP_ALMACEN) VALUES (?,?)", Array As Object (CAT_GP_ID,CAT_GP_ALMACEN))
|
||||
' Starter.skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD5(CAT_GP_ID,CAT_GP_ALMACEN) VALUES (?,?)", Array As Object (CAT_GP_ID,CAT_GP_ALMACEN))
|
||||
' skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD2(CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG,CAT_GP_ALMACEN,CAT_GP_TIPOPROD) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", Array As Object (CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG, CAT_GP_ALMACEN,CAT_GP_TIPOPROD))
|
||||
Next
|
||||
Starter.skmt.TransactionSuccessful
|
||||
@@ -3521,7 +3521,122 @@ Sub SUBIR_INFO_PEDIDO
|
||||
DateTime.TimeFormat = "HH:mm:ss"
|
||||
End Sub
|
||||
|
||||
' 1. Recopila encabezados y detalles de pedidos locales (todos o solo los pendientes).
|
||||
' 2. Genera un ID único (Arch) para vincular exactamente cada venta con sus productos.
|
||||
' 3. Empaqueta todo en una lista de comandos (Batch) para enviarlo al servidor en una sola transacción.
|
||||
Sub enviaPedidoBatch(filtro As String)
|
||||
' Creamos una lista llamada BatchCommands. Aquí vamos a guardar todas las instrucciones
|
||||
' de base de datos que queremos mandar al servidor de un solo golpe (en lote o "batch").
|
||||
Dim BatchCommands As List
|
||||
BatchCommands.Initialize
|
||||
Log($"enviaPedidoBatch(${filtro})"$)
|
||||
|
||||
' Preparamos una variable para filtrar la consulta a la base de datos.
|
||||
' Si el filtro no dice "Todos", armamos la condición para traer solo los pedidos que no se han enviado (PC_ENVIADO = 0).
|
||||
Private condicion As String = ""
|
||||
If filtro <> "Todos" Then condicion = "where PC_ENVIADO = 0"
|
||||
|
||||
' Ejecutamos una consulta (Query) a la base de datos local de SQLite (skmt).
|
||||
' Buscamos los ENCABEZADOS de los pedidos en la tabla PEDIDO_CLIENTE usando la condición que armamos arriba.
|
||||
' El resultado se guarda en un Cursor llamado 'cx', que es como una tabla en memoria por la que podemos navegar.
|
||||
Private cx As Cursor = Starter.skmt.ExecQuery($"SELECT PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT, PC_COSTO_SIN, PC_RUTA, PC_ALMACEN, PC_ENVIADO FROM PEDIDO_CLIENTE ${condicion}"$)
|
||||
Log($"SELECT PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT, PC_COSTO_SIN, PC_RUTA, PC_ALMACEN, PC_ENVIADO FROM PEDIDO_CLIENTE ${condicion}"$)
|
||||
Log("pedido_cliente: " & cx.RowCount)
|
||||
|
||||
' Reiniciamos la variable de condición para usarla ahora en el DETALLE de los pedidos.
|
||||
Private condicion As String = ""
|
||||
If filtro <> "Todos" Then condicion = "where PE_ENVIADO = 0"
|
||||
|
||||
' Verificamos si en la tabla de envíos históricos (HIST_ENVIOS) hay registros del tipo "ABORDO" (Ventas en ruta directa).
|
||||
c = Starter.skmt.ExecQuery2("SELECT COUNT(*) as CANTIDAD FROM HIST_ENVIOS WHERE HE_TIPO = ?",Array As String("ABORDO") )
|
||||
c.Position = 0
|
||||
|
||||
' Si encontramos que sí hay ventas a bordo...
|
||||
If c.GetString("CANTIDAD") > 0 Then
|
||||
Log($"pe_cedis_0"$)
|
||||
' Actualizamos la tabla PEDIDO para que los artículos del cliente "0" (que suele ser el inventario a bordo)
|
||||
' y que no tengan un número de folio, se marquen con el almacén/cedis "RECARGA".
|
||||
Starter.skmt.ExecNonQuery2("update PEDIDO set PE_CEDIS = ? where PE_CLIENTE =? AND PE_FOLIO IS NULL ", Array As Object("RECARGA", "0"))
|
||||
End If
|
||||
|
||||
' Hacemos una actualización rápida a los registros de PEDIDO que no tengan folio (folio 0 o 1).
|
||||
' Les asignamos temporalmente el 'rowid' (el número de fila interno de SQLite) como folio para identificarlos.
|
||||
Starter.skmt.ExecNonQuery("UPDATE PEDIDO SET PE_FOLIO = rowid where PE_FOLIO = 0 or PE_FOLIO = 1")
|
||||
|
||||
' Revisamos si nuestro cursor 'cx' (los encabezados de pedido) trajo algún resultado.
|
||||
If cx.RowCount > 0 Then ' Si hay pedido entonces lo enviamos.
|
||||
|
||||
' Iniciamos un bucle (For) para recorrer cada uno de los encabezados de pedido encontrados.
|
||||
For j = 0 To cx.RowCount - 1
|
||||
Log("===== ENVIAMOS PRODUCTOS DE PEDIDO =====")
|
||||
' Movemos el cursor 'cx' a la posición 'j' actual del bucle.
|
||||
cx.Position = j
|
||||
|
||||
' Generamos un identificador único (Arch) concatenando el almacén, la ruta, el cliente y la fecha/hora actual.
|
||||
' Esto sirve para agrupar en el servidor el encabezado con sus respectivos detalles.
|
||||
Dim Arch As String = Subs.traeAlmacen & "_" & Subs.traeRuta & "_" & cx.GetString("PC_CLIENTE") & "_" & DateTime.Now
|
||||
|
||||
' Preparamos un comando de base de datos (DBCommand) para mandar al servidor.
|
||||
Dim cmdHeader As DBCommand
|
||||
cmdHeader.Initialize
|
||||
' Asignamos el nombre del procedimiento almacenado o query que está en el servidor (jRDC2).
|
||||
cmdHeader.Name = "insert_pedidos_KELL_arch"
|
||||
' Pasamos los parámetros leyendo los datos del cursor 'cx' (encabezado) y le pasamos el ID único 'Arch'.
|
||||
cmdHeader.Parameters = Array As Object(cx.GetString("PC_CLIENTE"),cx.GetString("PC_FECHA"),cx.GetString("PC_USER"),cx.GetString("PC_NOART"),cx.GetString("PC_MONTO"),cx.GetString("PC_LON"),cx.GetString("PC_LAT"),ALMACEN,l_ruta.text,cx.GetString("PC_COSTO_SIN"), Arch)
|
||||
|
||||
' Añadimos este comando a nuestra lista del lote (Batch).
|
||||
BatchCommands.Add(cmdHeader)
|
||||
|
||||
' Ahora hacemos una consulta para buscar el DETALLE de este pedido (los productos individuales).
|
||||
' Filtramos por la condición (si se envió o no) y lo amarramos al cliente actual del bucle (PC_CLIENTE).
|
||||
Private cPed As Cursor = Starter.skmt.ExecQuery($"SELECT PE_CEDIS, PE_COSTO_TOT, PE_COSTOU, PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_FECHA, PE_USUARIO, PE_COSTO_SIN, PE_RUTA, PE_DESC, PE_FOLIO, PE_TIPO, PE_ARCH FROM PEDIDO ${condicion} ${(IIf(condicion = "","where", "and"))} pe_cliente = '${cx.GetString("PC_CLIENTE")}' "$)
|
||||
|
||||
' Si hay detalles para este encabezado...
|
||||
If cPed.RowCount > 0 Then
|
||||
|
||||
' Iniciamos un bucle interno para recorrer cada producto de este pedido.
|
||||
For i = 0 To cPed.RowCount - 1
|
||||
Log("==== ENVIAMOS PRODS ====")
|
||||
' Movemos el cursor de detalles a la posición actual.
|
||||
cPed.Position = i
|
||||
|
||||
' Preparamos el comando para enviar este producto al servidor.
|
||||
Dim cmdDetail As DBCommand
|
||||
cmdDetail.Initialize
|
||||
|
||||
' Si el perfil del vendedor es especial ("V-ESPECIAL")...
|
||||
If PERFIL = "V-ESPECIAL" Then
|
||||
Log("===== V-ESPECIAL =====")
|
||||
' Nota: Aquí el código original tiene un detalle, usa la variable global 'cmd' en lugar de 'cmdDetail'
|
||||
' que acaba de inicializar, pero la copiamos tal cual. Utiliza un query distinto para ventas especiales.
|
||||
cmd.Name = "insert_pedido_esp_KELL"
|
||||
cmd.Parameters = Array As Object(cPed.GetString("PE_CEDIS"),ALMACEN,cPed.GetString("PE_COSTO_TOT"),cPed.GetString("PE_COSTOU"),cPed.GetString("PE_CANT"),cPed.GetString("PE_PRONOMBRE"),cPed.GetString("PE_PROID"),cPed.GetString("PE_CLIENTE"),cPed.GetString("PE_FECHA"),cPed.GetString("PE_USUARIO"),cPed.GetString("PE_RUTA"),cPed.GetString("PE_COSTO_SIN"),cPed.GetString("PE_DESC"),cPed.GetString("PE_FOLIO"),cPed.GetString("PE_TIPO"),NUMERO_PEDIDO)
|
||||
Else
|
||||
' Si es un vendedor normal, usa el comando estándar para insertar el detalle
|
||||
' y le pasa la misma variable 'Arch' para que en el servidor sepa de qué encabezado es.
|
||||
cmdDetail.Name = "insert_pedido_KELL_arch"
|
||||
cmdDetail.Parameters = Array As Object (cPed.GetString("PE_CEDIS"),ALMACEN,cPed.GetString("PE_COSTO_TOT"),cPed.GetString("PE_COSTOU"),cPed.GetString("PE_CANT"),cPed.GetString("PE_PRONOMBRE"),cPed.GetString("PE_PROID"),cPed.GetString("PE_CLIENTE"),cPed.GetString("PE_FECHA"),cPed.GetString("PE_USUARIO"),cPed.GetString("PE_RUTA"), cPed.GetString("PE_COSTO_SIN"),cPed.GetString("PE_DESC"),cPed.GetString("PE_FOLIO"), cPed.GetString("PE_TIPO"), Arch)
|
||||
End If
|
||||
|
||||
' Añadimos la instrucción del producto al lote de envío.
|
||||
BatchCommands.Add(cmdDetail)
|
||||
Next
|
||||
End If
|
||||
Next
|
||||
|
||||
' Al terminar de empaquetar, enviamos toda la lista de instrucciones (BatchCommands) al servidor de un solo golpe.
|
||||
' Se le asigna un nombre de etiqueta (Tag) para saber qué responderá el JobDone ("pedido_completo_" + id de cliente).
|
||||
' (Ojo visual para el programador: Esta línea está dentro del 'If' general, pero también después de armar los batches en el bucle 'For'. Al procesar el último item del bucle cx, tomará el ID del último cliente para el Tag).
|
||||
reqManager.ExecuteBatch(BatchCommands, "pedido_completo_" & cx.GetString("PC_CLIENTE"))
|
||||
End If
|
||||
|
||||
' Por buena práctica y para evitar fugas de memoria (memory leaks),
|
||||
' cerramos siempre los cursores que abrimos hacia la base de datos local.
|
||||
c.Close
|
||||
cx.Close
|
||||
End Sub
|
||||
|
||||
Sub enviaPedidoBatch0(filtro As String)
|
||||
' Crear una lista para almacenar TODAS las operaciones de UN pedido
|
||||
Dim BatchCommands As List
|
||||
BatchCommands.Initialize
|
||||
@@ -3544,7 +3659,7 @@ Sub enviaPedidoBatch(filtro As String)
|
||||
Starter.skmt.ExecNonQuery2("update PEDIDO set PE_CEDIS = ? where PE_CLIENTE =? AND PE_FOLIO IS NULL ", Array As Object("RECARGA", "0"))
|
||||
End If
|
||||
Starter.skmt.ExecNonQuery("UPDATE PEDIDO SET PE_FOLIO = rowid where PE_FOLIO = 0 or PE_FOLIO = 1")
|
||||
|
||||
|
||||
If cx.RowCount > 0 Then ' Si hay pedido entonces lo enviamos.
|
||||
For j = 0 To cx.RowCount - 1
|
||||
Log("===== ENVIAMOS PRODUCTOS DE PEDIDO =====")
|
||||
|
||||
@@ -352,22 +352,58 @@ Sub lv_catalogos_ItemClick (Position As Int, Value As Object)
|
||||
|
||||
' Log($"Resultados : ${c2.RowCount}, ${Value}, ${marca}, ${tipo}"$)
|
||||
If c2.RowCount > 0 Then
|
||||
LogColor("=== INICIO DIAGNÓSTICO DE PROMOS ===", Colors.Magenta)
|
||||
LogColor($"Cliente: ${clienteId} | Total Candidatas en BD: ${c2.RowCount}"$, Colors.Magenta)
|
||||
|
||||
Dim MotorNuevo As C_Promociones
|
||||
MotorNuevo.Initialize(Starter.skmt, ts)
|
||||
|
||||
For i=0 To c2.RowCount -1
|
||||
c2.Position=i
|
||||
Private tm As Map = Subs.procesaPromocion(c2.GetString("CAT_GP_ID"), clienteId)
|
||||
' promosC.procesaPromocion(c2.GetString("CAT_GP_ID"), clienteId)
|
||||
If tm.Get("status") = "ok" Then 'Solo muestrala si hay producto.
|
||||
|
||||
' Log(c2.GetString("CAT_GP_ID"))
|
||||
' Log(c2.GetString("CAT_PA_TIPO_PROMONTO"))
|
||||
' Log(c2.GetString("CAT_PA_PORCENTAJE_PAQUETE"))
|
||||
If c2.GetString("CAT_PA_TIPO_PROMONTO") = "0" Then ' Si NO es promo por monto entonces la mostamos.
|
||||
Dim idPromo As String = c2.GetString("CAT_GP_ID")
|
||||
Log($"[${i}] Revisando ID: ${idPromo} (${c2.GetString("CAT_GP_NOMBRE")})"$)
|
||||
|
||||
' --- 1. DIAGNÓSTICO MAPAS (VIEJO) ---
|
||||
Dim tm As Map = Subs.procesaPromocion(idPromo, clienteId)
|
||||
Dim statusViejo As String = tm.Get("status")
|
||||
Dim maxViejo As Int = Subs.revisaMaxPromosProdsFijosPorInventario(tm.Get("mp"))
|
||||
|
||||
If statusViejo <> "ok" Then
|
||||
LogColor($" >> MAPA rechaza: Status='${statusViejo}'"$, Colors.Red)
|
||||
Else
|
||||
LogColor($" >> MAPA acepta: MaxFijos=${maxViejo}"$, Colors.Green)
|
||||
End If
|
||||
|
||||
' --- 2. DIAGNÓSTICO TYPES (NUEVO) ---
|
||||
Try
|
||||
Dim tPromo As TPromoLegacy = MotorNuevo.TraePromo(idPromo, clienteId)
|
||||
Dim maxNuevo As Int = MotorNuevo.RevisaMaxPromosProdsFijos(tPromo)
|
||||
|
||||
Log($" >> TYPE Info Interna: Res='${tPromo.Resultado}', Msg='${tPromo.MensajeError}'"$)
|
||||
Log($" >> TYPE Listas: Fijos=${tPromo.ProdsFijos.Size}, Vars=${tPromo.ProdsVariables.Size}"$)
|
||||
|
||||
If tPromo.Resultado = "ok" And maxNuevo > 0 Then
|
||||
LogColor($" >> TYPE acepta: MaxFijos=${maxNuevo}"$, Colors.Green)
|
||||
Else
|
||||
LogColor($" >> TYPE rechaza: Resultado='${tPromo.Resultado}' | MaxCalculado=${maxNuevo}"$, Colors.Red)
|
||||
End If
|
||||
|
||||
Catch
|
||||
LogColor(" >> CRASH en Nuevo: " & LastException.Message, Colors.Red)
|
||||
End Try
|
||||
|
||||
Log("-") ' Separador
|
||||
|
||||
' --- 3. CODIGO VISUAL ORIGINAL ---
|
||||
If tm.Get("status") = "ok" Then
|
||||
If c2.GetString("CAT_PA_TIPO_PROMONTO") = "0" Then
|
||||
lv_promos.AddTwoLines(c2.GetString("CAT_GP_NOMBRE"),"# " & c2.GetString("CAT_GP_ALMACEN") & " $ " & c2.GetString("CAT_GP_PRECIO") & " F:" & tm.Get("mp").As(Map).Get("prodsFijosCant") & " V:" & tm.Get("mp").As(Map).Get("prodsVariablesCant"))
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
LogColor("=== FIN DIAGNÓSTICO ===", Colors.Magenta)
|
||||
Else
|
||||
ToastMessageShow("No hay promociones disponibles.", False)
|
||||
ToastMessageShow("No hay promociones en la consulta inicial.", False)
|
||||
End If
|
||||
c2.Close
|
||||
entro = "4"
|
||||
|
||||
1331
B4A/C_Productos2.bas
1331
B4A/C_Productos2.bas
File diff suppressed because it is too large
Load Diff
379
B4A/C_Promociones.bas
Normal file
379
B4A/C_Promociones.bas
Normal file
@@ -0,0 +1,379 @@
|
||||
B4A=true
|
||||
Group=Default Group
|
||||
ModulesStructureVersion=1
|
||||
Type=Class
|
||||
Version=12.8
|
||||
@EndOfDesignText@
|
||||
'Class module: C_Promociones
|
||||
Sub Class_Globals
|
||||
Private sql As SQL
|
||||
' Referencia a tu clase de Trade Spending (ajusta el tipo si se llama diferente)
|
||||
Private ts As Object ' Lo dejo como Object para que no te marque error si no has copiado esa clase aun
|
||||
|
||||
' Variable local para el cliente actual (para no depender de Subs.traeCliente)
|
||||
Private mClienteActual As String
|
||||
|
||||
End Sub
|
||||
|
||||
' Inicializa la clase.
|
||||
' db: La conexión SQL (Starter.skmt)
|
||||
' tradeSpending: La instancia de tu clase de TradeSpending (B4XPages.MainPage.promos.ts)
|
||||
Public Sub Initialize(db As SQL, tradeSpendingInstance As Object)
|
||||
sql = db
|
||||
ts = tradeSpendingInstance
|
||||
End Sub
|
||||
|
||||
' =============================================================================
|
||||
' CONTROLADOR PRINCIPAL: ORQUESTADOR DE VALIDACIONES
|
||||
' =============================================================================
|
||||
Public Sub procesaPromocion(idPromo As String, cliente As String) As Map
|
||||
Private thisLog As Boolean = True 'Si es verdadero, muestra los logs de este sub.
|
||||
Private inicioContador As String = DateTime.Now
|
||||
Private mp As Int = 0
|
||||
|
||||
If thisLog Then LogColor($"****************************************************************"$, Colors.RGB(142,0,255))
|
||||
If thisLog Then LogColor($"********* Iniciamos revision de Promo ${idPromo} *********"$, Colors.RGB(142,0,255))
|
||||
If thisLog Then LogColor($"****************************************************************"$, Colors.RGB(142,0,255))
|
||||
|
||||
Try
|
||||
Private pm As TPromoLegacy = TraePromo(idPromo, cliente)
|
||||
If thisLog Then LogColor(pm, Colors.Blue)
|
||||
|
||||
Private maxPromosXprodsFijos As Int = RevisaMaxPromosProdsFijos(pm)
|
||||
If maxPromosXprodsFijos < 1 Then pm.Resultado = "0"
|
||||
|
||||
If thisLog Then LogColor($"***********************************************************************"$, Colors.Blue)
|
||||
LogColor($"*** PROMOS DISPONIBLES X PRODS FIJOS (${idPromo}) = ${maxPromosXprodsFijos} ***"$, Colors.Blue)
|
||||
If thisLog Then LogColor($"***********************************************************************"$, Colors.Blue)
|
||||
|
||||
If pm.Resultado = "ok" Then 'Si encontramos la promoción, entonces ...
|
||||
mp = TraeMaxPromos(pm)
|
||||
If mp < 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
|
||||
|
||||
Private inventarioSinFijos As Map = restaFijosPromo(pm)
|
||||
If thisLog Then LogColor("inventariosfijos="&inventarioSinFijos, Colors.Magenta)
|
||||
|
||||
If inventarioSinFijos.Get("resultado") = "ok" Then
|
||||
Private pv As Boolean = alcanzanLosVariablesParaPromo(pm, inventarioSinFijos)
|
||||
|
||||
If thisLog Then LogColor($"****************************************************"$, Colors.Blue)
|
||||
If thisLog Then LogColor($"***** ¿ALCANZAN LOS VARIABLES? ==> ${IIf(pv, "SI", "NO")} *****"$, Colors.Blue)
|
||||
If thisLog Then LogColor($"****************************************************"$, Colors.Blue)
|
||||
|
||||
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
|
||||
|
||||
LogColor("TIEMPO DE PROCESO ESTA PROMO: " & ((DateTime.Now-inicioContador)/1000), Colors.Red)
|
||||
|
||||
Catch
|
||||
Log($"Promo ${idPromo} mal configurada"$)
|
||||
ToastMessageShow($"Promo ${idPromo} mal configurada"$, True)
|
||||
Log(LastException)
|
||||
Return CreateMap("status":"ko", "mp":Null)
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
' =============================================================================
|
||||
' RUTINA PRINCIPAL: ARMA LA ESTRUCTURA (Clon de Subs.traePromo)
|
||||
' =============================================================================
|
||||
Public Sub TraePromo(promo As String, cliente As String) As TPromoLegacy
|
||||
mClienteActual = cliente ' Guardamos el cliente para uso interno
|
||||
|
||||
Dim t As TPromoLegacy
|
||||
t.Initialize
|
||||
|
||||
' Inicialización de Listas y Mapas (CRÍTICO para evitar Nulls)
|
||||
t.ProdsFijos.Initialize
|
||||
t.ProdsFijosPiezas.Initialize
|
||||
t.ProdsFijosPrecios.Initialize
|
||||
t.ProdsVariables.Initialize
|
||||
t.ProdsVariablesPrecios.Initialize
|
||||
t.Productos.Initialize
|
||||
t.Tipos.Initialize
|
||||
|
||||
t.Id = promo
|
||||
t.MaxXCliente = 0
|
||||
t.MaxRecurrente = 0
|
||||
t.MaxPromos = 0
|
||||
|
||||
' --- 1. LECTURA GENERAL ---
|
||||
Dim c As Cursor = sql.ExecQuery("Select * from promos_comp where cat_pa_id = '"& promo&"'")
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
t.MaxXCliente = c.GetString("CAT_PA_MAXPROMCLIE")
|
||||
t.MaxRecurrente = c.GetString("CAT_PA_MAXPROMREC")
|
||||
t.MaxPromos = c.GetString("CAT_PA_MAXPROM")
|
||||
End If
|
||||
c.Close
|
||||
|
||||
' --- 2. SEGMENTACIÓN ---
|
||||
Dim ps As Cursor = sql.ExecQuery($"select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}'"$)
|
||||
If ps.RowCount > 0 Then
|
||||
' Es segmentada -> Bloqueamos por defecto
|
||||
t.MaxXCliente = "0"
|
||||
t.MaxRecurrente = "0"
|
||||
t.MaxPromos = "0"
|
||||
|
||||
Dim ps2 As Cursor = sql.ExecQuery($"Select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${cliente}' and HCCP_CANT > HCCP_CANT_VENDIDA"$)
|
||||
If ps2.RowCount > 0 Then
|
||||
ps2.Position = 0
|
||||
t.MaxXCliente = (ps2.GetInt("HCCP_CANT") - ps2.GetInt("HCCP_CANT_VENDIDA"))
|
||||
t.MaxRecurrente = ps2.GetString("HCCP_CANT")
|
||||
t.MaxPromos = ps2.GetString("HCCP_CANT")
|
||||
End If
|
||||
ps2.Close
|
||||
End If
|
||||
ps.Close
|
||||
|
||||
' --- 3. HISTÓRICO ---
|
||||
Dim siHistorico As String = "0"
|
||||
c = sql.ExecQuery("Select count(*) as hist from HIST_PROMOS where HP_CLIENTE = '"& cliente & "' and HP_CODIGO_PROMOCION = '" & promo & "'")
|
||||
c.Position = 0
|
||||
If c.GetInt("hist") > 0 Then siHistorico = "1"
|
||||
t.Historico = siHistorico
|
||||
c.Close
|
||||
|
||||
' --- 4. DETALLES Y PRODUCTOS ---
|
||||
c = sql.ExecQuery("Select * from CAT_DETALLES_PAQ where CAT_DP_ID = '"& promo & "'")
|
||||
If c.RowCount > 0 Then
|
||||
t.Resultado = "ok"
|
||||
For i = 0 To c.RowCount -1
|
||||
c.Position = i
|
||||
Dim idProd As String = c.GetString("CAT_DP_IDPROD")
|
||||
|
||||
' Llenamos el mapa de productos (igual que el original para compatibilidad)
|
||||
t.Productos.Put(idProd, CreateMap("idProducto":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")))
|
||||
t.Tipos.Put(idProd, c.GetString("CAT_DP_TIPO"))
|
||||
|
||||
If c.GetString("CAT_DP_TIPO") = "0" Then
|
||||
t.ProdsFijos.Add(idProd)
|
||||
t.ProdsFijosPrecios.Add(c.GetString("CAT_DP_PRECIO"))
|
||||
t.ProdsFijosPiezas.Add(c.GetString("CAT_DP_PZAS"))
|
||||
End If
|
||||
If c.GetString("CAT_DP_TIPO") = "1" Then
|
||||
t.ProdsVariables.Add(idProd)
|
||||
t.ProdsVariablesPrecios.Add(c.GetString("CAT_DP_PRECIO"))
|
||||
End If
|
||||
Next
|
||||
Else
|
||||
t.Resultado = "No hay datos de la promoción."
|
||||
t.MensajeError = "Sin detalles"
|
||||
End If
|
||||
c.Close
|
||||
|
||||
' --- 5. VARIABLES REQUERIDAS ---
|
||||
c = sql.ExecQuery("Select CAT_GP_STS, CAT_GP_NOMBRE from CAT_GUNAPROD2 where CAT_GP_ID = '"& promo & "'")
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
t.ProdsVariablesRequeridos = c.GetInt("CAT_GP_STS")
|
||||
t.Descripcion = c.GetString("CAT_GP_NOMBRE")
|
||||
Else
|
||||
t.ProdsVariablesRequeridos = 0
|
||||
End If
|
||||
c.Close
|
||||
|
||||
Return t
|
||||
End Sub
|
||||
|
||||
' =============================================================================
|
||||
' LÓGICA DE CÁLCULO 1: FIJOS (Clon de Subs.revisaMaxPromosProdsFijosPorInventario)
|
||||
' =============================================================================
|
||||
Public Sub RevisaMaxPromosProdsFijos(pm As TPromoLegacy) As Int
|
||||
Dim tLista As List
|
||||
tLista.Initialize
|
||||
|
||||
' 1. Agregamos el máximo configurado
|
||||
tLista.Add(TraeMaxPromos(pm))
|
||||
|
||||
' 2. Obtenemos inventario real
|
||||
Dim invDispParaPromo As Map = TraemosInventarioDisponibleParaPromo(pm.Id)
|
||||
|
||||
Dim prodsFijosPiezas As List = pm.ProdsFijosPiezas
|
||||
Dim idProdsFijos As List = pm.ProdsFijos
|
||||
Dim idProdsFijosPrecios As List = pm.ProdsFijosPrecios
|
||||
|
||||
' 3. Iteramos sobre los fijos
|
||||
For p = 0 To idProdsFijos.Size -1
|
||||
Dim thisInvDisp As Int = 0
|
||||
If invDispParaPromo.Get(idProdsFijos.Get(p)) <> Null Then
|
||||
thisInvDisp = invDispParaPromo.Get(idProdsFijos.Get(p))
|
||||
End If
|
||||
|
||||
Dim pzasReq As Int = prodsFijosPiezas.Get(p)
|
||||
|
||||
If pzasReq > 0 Then
|
||||
Dim division As Double = thisInvDisp / pzasReq
|
||||
Dim x() As String = Regex.Split("\.", $"${division}"$)
|
||||
tLista.Add(x(0).As(Int))
|
||||
|
||||
' --- AQUI ESTA TU CAMBIO (DIRECTO Y SIN DOLOR) ---
|
||||
' Nota: Cambié pm.Get("id") por pm.Id porque ahora es un Type
|
||||
|
||||
Dim maxTS As Int = B4XPages.MainPage.promos.ts.traeBonificacionesMaximas("bonificaciones", mClienteActual, idProdsFijos.Get(p), pzasReq, idProdsFijosPrecios.Get(p), pm.Id)
|
||||
|
||||
tLista.Add(maxTS)
|
||||
' -------------------------------------------------
|
||||
|
||||
Else
|
||||
Log($"Promo ${pm.Id} mal configurada (0 piezas requeridas en producto fijo)"$)
|
||||
ToastMessageShow($"Promo ${pm.Id} mal configurada"$, True)
|
||||
tLista.Add(0)
|
||||
End If
|
||||
Next
|
||||
|
||||
tLista.Sort(True)
|
||||
Return tLista.Get(0)
|
||||
End Sub
|
||||
|
||||
' =============================================================================
|
||||
' LÓGICA DE CÁLCULO 2: MÁXIMOS (Clon de Subs.traeMaxPromos)
|
||||
' =============================================================================
|
||||
Public Sub TraeMaxPromos(pm As TPromoLegacy) As Int
|
||||
Dim maxPromos As List
|
||||
maxPromos.Initialize
|
||||
|
||||
' A. Histórico del Cliente (HCCP)
|
||||
Dim hccp As Cursor = sql.ExecQuery($"select HCCP_CANT from HIST_CLIENTE_CANT_PROMOS where HCCP_CLIENTE = '${mClienteActual}' and HCCP_PROMO = '${pm.Id}'"$)
|
||||
If hccp.RowCount > 0 Then
|
||||
hccp.Position = 0
|
||||
maxPromos.Add(hccp.GetInt("HCCP_CANT"))
|
||||
End If
|
||||
hccp.Close
|
||||
|
||||
' B. Trade Spending Variables
|
||||
If ts <> Null Then
|
||||
Dim maxPromosXDescPV As String = B4XPages.MainPage.promos.ts.maxPromosPorProdsVariables(pm.ProdsVariables, pm.Id)
|
||||
maxPromos.Add(maxPromosXDescPV.As(Int))
|
||||
End If
|
||||
|
||||
' C. Límites Generales
|
||||
If pm.Historico = "1" And pm.MaxRecurrente <> "null" Then maxPromos.Add(pm.MaxRecurrente.As(Int))
|
||||
If pm.MaxPromos <> "null" Then maxPromos.Add(pm.MaxPromos.As(Int))
|
||||
If pm.MaxXCliente <> "null" Then maxPromos.Add(pm.MaxXCliente.As(Int))
|
||||
|
||||
maxPromos.Sort(True)
|
||||
|
||||
Dim mp As Int = 0
|
||||
If maxPromos.Size > 0 Then
|
||||
Dim mp0 As Int = maxPromos.Get(0)
|
||||
' Restamos lo ya vendido
|
||||
mp = mp0 - TraePromosVendidas(pm.Id, mClienteActual)
|
||||
End If
|
||||
|
||||
Return mp
|
||||
End Sub
|
||||
|
||||
' =============================================================================
|
||||
' LÓGICA DE CÁLCULO 3: RESTA INVENTARIO FIJO (Clon de Subs.restaFijosPromo)
|
||||
' =============================================================================
|
||||
Public Sub restaFijosPromo(pm As TPromoLegacy) As Map
|
||||
Private thisLog As Boolean = False 'Si es verdadero, muestra los logs de este sub.
|
||||
Private inventariosDisponiblesParaEstaPromo As Map = TraemosInventarioDisponibleParaPromo(pm.Id) '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 = pm.productos 'Obtenemos un mapa con todos los productos de la promoción.
|
||||
Private prodsFijos As List = pm.ProdsFijos 'Obtenemos una 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
|
||||
|
||||
If thisLog Then 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 - pm.ProdsFijosPiezas.Get(p)), 1, 0,0,False)
|
||||
If thisLog Then Log($"Nuevo inventario de ${t}: ${i}-${pm.ProdsFijosPiezas.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
|
||||
|
||||
' =============================================================================
|
||||
' LÓGICA DE CÁLCULO 4: VARIABLES (Clon de Subs.alcanzanLosVariablesParaPromo)
|
||||
' =============================================================================
|
||||
Public Sub alcanzanLosVariablesParaPromo(pm As TPromoLegacy, inventarioSinFijos As Map) As Boolean
|
||||
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 prodsVariables As List = pm.ProdsVariables 'Obtenemos la 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=" & pm.ProdsVariablesRequeridos)
|
||||
|
||||
Private res As Boolean = False
|
||||
If totalProdsVariables >= pm.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
|
||||
|
||||
' =============================================================================
|
||||
' HELPERS PRIVADOS (Para hacer la clase portable sin depender de Subs.bas)
|
||||
' =============================================================================
|
||||
|
||||
Private Sub TraePromosVendidas(promo As String, cliente As String) As Int
|
||||
Dim c As Cursor
|
||||
Dim pv As Int = 0
|
||||
c = sql.ExecQuery($"select sum(PE_CANT) as cuantas from PEDIDO where PE_PROID = '${promo}' and PE_CLIENTE = '${cliente}'"$)
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
If c.GetString("cuantas") <> Null Then pv = c.GetInt("cuantas")
|
||||
End If
|
||||
c.Close
|
||||
Return pv
|
||||
End Sub
|
||||
|
||||
Private Sub TraemosInventarioDisponibleParaPromo(promo As String) As Map
|
||||
Dim c As Cursor
|
||||
c = sql.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))
|
||||
Dim 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"))
|
||||
Next
|
||||
End If
|
||||
c.Close
|
||||
Return prods
|
||||
End Sub
|
||||
@@ -157,8 +157,8 @@ Sub B4XPage_Appear
|
||||
Log($"laPromo=${laPromo}, el cliente=${elCliente}"$)
|
||||
If laPromo <> "" Then muestraPromo(laPromo, elCliente)
|
||||
End Sub
|
||||
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
|
||||
|
||||
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
|
||||
Sub muestraPromo(promo As String, cliente As String)
|
||||
LogColor($"****************************************************************"$, Colors.red)
|
||||
LogColor($"************ muestraPromo: ${promo} *************"$, Colors.red)
|
||||
@@ -168,6 +168,7 @@ Sub muestraPromo(promo As String, cliente As String)
|
||||
estaPromo = promo
|
||||
esteCliente = cliente
|
||||
Private mp As Map = Subs.traePromo(promo, cliente)
|
||||
|
||||
If thisLog Then LogColor(mp, Colors.blue)
|
||||
Private prodsPromo As Map = mp.Get("productos") 'Los productos de la promoción.
|
||||
' Private invDispPromo As Map = Subs.traemosInventarioDisponibleParaPromo(promo)
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
B4A=true
|
||||
Group=Default Group
|
||||
ModulesStructureVersion=1
|
||||
Type=Class
|
||||
Version=11.5
|
||||
@EndOfDesignText@
|
||||
Sub Class_Globals
|
||||
Private Root As B4XView 'ignore
|
||||
Private xui As XUI 'ignore
|
||||
End Sub
|
||||
|
||||
'You can add more parameters here.
|
||||
Public Sub Initialize As Object
|
||||
Return Me
|
||||
End Sub
|
||||
|
||||
'This event will be called once, before the page becomes visible.
|
||||
Private Sub B4XPage_Created (Root1 As B4XView)
|
||||
Root = Root1
|
||||
'load the layout to Root
|
||||
|
||||
End Sub
|
||||
|
||||
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
|
||||
@@ -16,8 +16,6 @@ Version=12.8
|
||||
' Descuento es TODO lo que tenga un precio diferente al precio de lista y NO esta en promo.
|
||||
' Bonificacion es lo que tiene precio diferente al orginal y esta en promo y NO es regalo o exhibidor.
|
||||
|
||||
|
||||
|
||||
Sub Class_Globals
|
||||
Private EventName As String 'ignore
|
||||
Private CallBack As Object 'ignore
|
||||
|
||||
@@ -1,360 +0,0 @@
|
||||
B4A=true
|
||||
Group=Default Group
|
||||
ModulesStructureVersion=1
|
||||
Type=Class
|
||||
Version=6.8
|
||||
@EndOfDesignText@
|
||||
''Class module
|
||||
Sub Class_Globals
|
||||
Private mTarget As Object
|
||||
Type DBResult (Tag As Object, Columns As Map, Rows As List)
|
||||
Type DBCommand (Name As String, Parameters() As Object)
|
||||
Private link As String
|
||||
Private bc As ByteConverter
|
||||
Private T_NULL = 0, T_STRING = 1, T_SHORT = 2, T_INT = 3, T_LONG = 4, T_FLOAT = 5 _
|
||||
,T_DOUBLE = 6, T_BOOLEAN = 7, T_BLOB = 8 As Byte
|
||||
Private VERSION As Float = 0.9
|
||||
Private tempArray(1) As Object
|
||||
Dim jobTagAnterior As String = "" 'Mod por CHV - 211109
|
||||
Dim reqsList, timesList As List
|
||||
Dim inicioRequest As Long 'ignore
|
||||
Dim inicioJobDone As Long 'ignore
|
||||
Dim inicioRequestMap, inicioJobDoneMap As Map
|
||||
End Sub
|
||||
|
||||
'Target - The module that handles JobDone (usually Me).
|
||||
'ConnectorLink - URL of the Java server.
|
||||
Public Sub Initialize (Target As Object, ConnectorLink As String)
|
||||
mTarget = Target
|
||||
link = ConnectorLink
|
||||
End Sub
|
||||
|
||||
'Sends a query request.
|
||||
'Command - Query name and parameters.
|
||||
'Limit - Maximum rows to return or 0 for no limit.
|
||||
'Tag - An object that will be returned in the result.
|
||||
Public Sub ExecuteQuery(Command As DBCommand, Limit As Int, Tag As Object)
|
||||
Dim j As HttpJob
|
||||
Dim ms As OutputStream
|
||||
Dim out2 As OutputStream = StartJob(j, ms, Tag)
|
||||
' If reqsList.IsInitialized Then reqsList.Add(Tag)
|
||||
' If timesList.IsInitialized Then timesList.Add(DateTime.now)
|
||||
|
||||
WriteObject(Command.Name, out2)
|
||||
WriteInt(Limit, out2)
|
||||
WriteList(Command.Parameters, out2)
|
||||
out2.Close
|
||||
j.PostBytes(link & "?method=query", ms.ToBytesArray)
|
||||
End Sub
|
||||
|
||||
'Sends a query request.
|
||||
'Command - Query name and parameters.
|
||||
'Limit - Maximum rows to return or 0 for no limit.
|
||||
'Tag - An object that will be returned in the result.
|
||||
'Timeout - The http request timeout in ms, or 0 if default (30 secs)
|
||||
Public Sub ExecuteQuery3(Command As DBCommand, Limit As Int, Tag As Object, Timeout As Int) 'Mod por CHV, agregué el parametro Timeout - 211229
|
||||
Dim j As HttpJob
|
||||
Dim ms As OutputStream
|
||||
Dim out2 As OutputStream = StartJob(j,ms, Tag)
|
||||
WriteObject(Command.Name, out2)
|
||||
WriteInt(Limit, out2)
|
||||
WriteList(Command.Parameters, out2)
|
||||
out2.Close
|
||||
j.PostBytes(link & "?method=query", ms.ToBytesArray)
|
||||
If Timeout <> 0 Then j.GetRequest.Timeout = Timeout
|
||||
End Sub
|
||||
|
||||
'Executes a batch of (non-select) commands.
|
||||
'ListOfCommands - List of the commands that will be executes.
|
||||
'Tag - An object that will be returned in the result.
|
||||
Public Sub ExecuteBatch(ListOfCommands As List, Tag As Object)
|
||||
Dim j As HttpJob
|
||||
Dim ms As OutputStream
|
||||
Dim out2 As OutputStream = StartJob(j, ms, Tag)
|
||||
WriteInt(ListOfCommands.Size, out2)
|
||||
For Each Command As DBCommand In ListOfCommands
|
||||
WriteObject(Command.Name, out2)
|
||||
WriteList(Command.Parameters, out2)
|
||||
Next
|
||||
out2.Close
|
||||
j.PostBytes(link & "?method=batch", ms.ToBytesArray)
|
||||
End Sub
|
||||
|
||||
'Similar to ExecuteBatch. Sends a single command.
|
||||
Public Sub ExecuteCommand(Command As DBCommand, Tag As Object)
|
||||
' If reqsList.IsInitialized Then reqsList.Add(Tag)
|
||||
' If timesList.IsInitialized Then timesList.Add(DateTime.now)
|
||||
ExecuteBatch(Array As DBCommand(Command), Tag)
|
||||
End Sub
|
||||
|
||||
Private Sub StartJob(j As HttpJob, MemoryStream As OutputStream, Tag As Object) As OutputStream
|
||||
' inicioRequest = DateTime.now
|
||||
If reqsList.IsInitialized Then reqsList.Add(Tag)
|
||||
If timesList.IsInitialized Then timesList.Add(DateTime.now)
|
||||
j.Initialize("DBRequest", mTarget)
|
||||
j.Tag = Tag
|
||||
MemoryStream.InitializeToBytesArray(0)
|
||||
Dim compress As CompressedStreams
|
||||
Dim out As OutputStream = compress.WrapOutputStream(MemoryStream, "gzip")
|
||||
WriteObject(VERSION, out)
|
||||
Return out
|
||||
End Sub
|
||||
|
||||
Private Sub WriteList(Parameters As List, out As OutputStream)
|
||||
Dim data() As Byte
|
||||
If Parameters = Null Or Parameters.IsInitialized = False Then
|
||||
Dim Parameters As List
|
||||
Parameters.Initialize
|
||||
End If
|
||||
data = bc.IntsToBytes(Array As Int(Parameters.Size))
|
||||
out.WriteBytes(data, 0, data.Length)
|
||||
For Each o As Object In Parameters
|
||||
WriteObject(o, out)
|
||||
Next
|
||||
End Sub
|
||||
|
||||
Private Sub WriteObject(o As Object, out As OutputStream)
|
||||
Dim data() As Byte
|
||||
tempArray(0) = o
|
||||
If tempArray(0) = Null Then
|
||||
out.WriteBytes(Array As Byte(T_NULL), 0, 1)
|
||||
Else If tempArray(0) Is Short Then
|
||||
out.WriteBytes(Array As Byte(T_SHORT), 0, 1)
|
||||
data = bc.ShortsToBytes(Array As Short(o))
|
||||
Else If tempArray(0) Is Int Then
|
||||
out.WriteBytes(Array As Byte(T_INT), 0, 1)
|
||||
data = bc.IntsToBytes(Array As Int(o))
|
||||
Else If tempArray(0) Is Float Then
|
||||
out.WriteBytes(Array As Byte(T_FLOAT), 0, 1)
|
||||
data = bc.FloatsToBytes(Array As Float(o))
|
||||
Else If tempArray(0) Is Double Then
|
||||
out.WriteBytes(Array As Byte(T_DOUBLE), 0, 1)
|
||||
data = bc.DoublesToBytes(Array As Double(o))
|
||||
Else If tempArray(0) Is Long Then
|
||||
out.WriteBytes(Array As Byte(T_LONG), 0, 1)
|
||||
data = bc.LongsToBytes(Array As Long(o))
|
||||
Else If tempArray(0) Is Boolean Then
|
||||
out.WriteBytes(Array As Byte(T_BOOLEAN), 0, 1)
|
||||
Dim b As Boolean = 0
|
||||
Dim data(1) As Byte
|
||||
If b Then data(0) = 1 Else data(0) = 0
|
||||
Else If GetType(tempArray(0)) = "[B" Then
|
||||
data = o
|
||||
out.WriteBytes(Array As Byte(T_BLOB), 0, 1)
|
||||
WriteInt(data.Length, out)
|
||||
Else 'If o Is String Then (treat all other values as string)
|
||||
out.WriteBytes(Array As Byte(T_STRING), 0, 1)
|
||||
data = bc.StringToBytes(o, "UTF8")
|
||||
WriteInt(data.Length, out)
|
||||
End If
|
||||
If data.Length > 0 Then out.WriteBytes(data, 0, data.Length)
|
||||
End Sub
|
||||
|
||||
Private Sub ReadObject(In As InputStream) As Object
|
||||
Dim data(1) As Byte
|
||||
In.ReadBytes(data, 0, 1)
|
||||
Select data(0)
|
||||
Case T_NULL
|
||||
Return Null
|
||||
Case T_SHORT
|
||||
Dim data(2) As Byte
|
||||
Return bc.ShortsFromBytes(ReadBytesFully(In, data, data.Length))(0)
|
||||
Case T_INT
|
||||
Dim data(4) As Byte
|
||||
Return bc.IntsFromBytes(ReadBytesFully(In, data, data.Length))(0)
|
||||
Case T_LONG
|
||||
Dim data(8) As Byte
|
||||
Return bc.LongsFromBytes(ReadBytesFully(In, data, data.Length))(0)
|
||||
Case T_FLOAT
|
||||
Dim data(4) As Byte
|
||||
Return bc.FloatsFromBytes(ReadBytesFully(In, data, data.Length))(0)
|
||||
Case T_DOUBLE
|
||||
Dim data(8) As Byte
|
||||
Return bc.DoublesFromBytes(ReadBytesFully(In, data, data.Length))(0)
|
||||
Case T_BOOLEAN
|
||||
Dim b As Byte = ReadByte(In)
|
||||
Return b = 1
|
||||
Case T_BLOB
|
||||
Dim len As Int = ReadInt(In)
|
||||
Dim data(len) As Byte
|
||||
Return ReadBytesFully(In, data, data.Length)
|
||||
Case Else
|
||||
Dim len As Int = ReadInt(In)
|
||||
Dim data(len) As Byte
|
||||
ReadBytesFully(In, data, data.Length)
|
||||
Return BytesToString(data, 0, data.Length, "UTF8")
|
||||
End Select
|
||||
End Sub
|
||||
|
||||
Private Sub ReadBytesFully(In As InputStream, Data() As Byte, Len As Int) As Byte()
|
||||
Dim count = 0, read As Int
|
||||
Do While count < Len And read > -1
|
||||
read = In.ReadBytes(Data, count, Len - count)
|
||||
count = count + read
|
||||
Loop
|
||||
Return Data
|
||||
End Sub
|
||||
|
||||
Private Sub WriteInt(i As Int, out As OutputStream)
|
||||
Dim data() As Byte
|
||||
data = bc.IntsToBytes(Array As Int(i))
|
||||
out.WriteBytes(data, 0, data.Length)
|
||||
End Sub
|
||||
|
||||
Private Sub ReadInt(In As InputStream) As Int
|
||||
Dim data(4) As Byte
|
||||
Return bc.IntsFromBytes(ReadBytesFully(In, data, data.Length))(0)
|
||||
End Sub
|
||||
|
||||
Private Sub ReadByte(In As InputStream) As Byte
|
||||
Dim data(1) As Byte
|
||||
In.ReadBytes(data, 0, 1)
|
||||
Return data(0)
|
||||
End Sub
|
||||
|
||||
'Handles the Job result and returns a DBResult.
|
||||
Public Sub HandleJob(Job As HttpJob) As DBResult
|
||||
If jobTagAnterior <> Job.Tag Then
|
||||
' inicioJobDone = DateTime.Now 'ignore
|
||||
If inicioJobDoneMap.IsInitialized Then inicioJobDoneMap.Put(Job.Tag, DateTime.Now)
|
||||
' tiempos.Put(Job.taskId, CreateMap("inicioJobDone":inicioJobDone))
|
||||
' Log(tiempos)
|
||||
' Log("############# " & Job.taskId)
|
||||
End If
|
||||
Dim In As InputStream = Job.GetInputStream
|
||||
Dim cs As CompressedStreams
|
||||
In = cs.WrapInputStream(In, "gzip")
|
||||
Dim serverVersion As Float = ReadObject(In) 'ignore
|
||||
Dim method As String = ReadObject(In)
|
||||
Dim table As DBResult
|
||||
table.Initialize
|
||||
table.Columns.Initialize
|
||||
table.rows.Initialize
|
||||
table.Tag = Job.Tag
|
||||
If method = "query" Then
|
||||
Dim numberOfColumns As Int = ReadInt(In)
|
||||
For i = 0 To numberOfColumns - 1
|
||||
table.Columns.Put(ReadObject(In), i)
|
||||
Next
|
||||
Do While ReadByte(In) = 1
|
||||
Dim rowObjects(numberOfColumns) As Object
|
||||
table.rows.Add(rowObjects)
|
||||
For col = 0 To numberOfColumns - 1
|
||||
Dim o As Object = ReadObject(In)
|
||||
rowObjects(col) = o
|
||||
Next
|
||||
Loop
|
||||
Else If method = "batch" Then
|
||||
table.Columns.Put("AffectedRows", 0)
|
||||
Dim rows As Int = ReadInt(In)
|
||||
For i = 0 To rows - 1
|
||||
table.rows.Add(Array As Object(ReadInt(In)))
|
||||
Next
|
||||
End If
|
||||
In.Close
|
||||
' Log("HandleJob: " & (DateTime.Now - start))'Comentado por CHV - 211112
|
||||
If jobTagAnterior <> table.Tag Then
|
||||
LogColor("HandleJob: '"&table.Tag&"'" & " - Registros: " & table.Rows.Size, Colors.RGB(115, 0, 140)) 'Mod por CHV - 211109
|
||||
End If
|
||||
jobTagAnterior = table.Tag 'Mod por CHV - 211109
|
||||
Return table
|
||||
End Sub
|
||||
|
||||
'Reads a file and returns the file as a bytes array.
|
||||
Public Sub FileToBytes(Dir As String, FileName As String) As Byte()
|
||||
Dim out As OutputStream
|
||||
out.InitializeToBytesArray(0)
|
||||
Dim In As InputStream = File.OpenInput(Dir, FileName)
|
||||
File.Copy2(In, out)
|
||||
out.Close
|
||||
Return out.ToBytesArray
|
||||
End Sub
|
||||
|
||||
'Converts an image to a bytes array (for BLOB fields).
|
||||
Public Sub ImageToBytes(Image As Bitmap) As Byte()
|
||||
Dim out As OutputStream
|
||||
out.InitializeToBytesArray(0)
|
||||
Image.WriteToStream(out, 100, "JPEG")
|
||||
out.Close
|
||||
Return out.ToBytesArray
|
||||
End Sub
|
||||
|
||||
'Converts a bytes array to an image (for BLOB fields).
|
||||
Public Sub BytesToImage(bytes() As Byte) As Bitmap
|
||||
Dim In As InputStream
|
||||
In.InitializeFromBytesArray(bytes, 0, bytes.Length)
|
||||
Dim bmp As Bitmap
|
||||
bmp.Initialize2(In)
|
||||
Return bmp
|
||||
End Sub
|
||||
|
||||
'Prints the table to the logs.
|
||||
Public Sub PrintTable(Table As DBResult)
|
||||
Log("Tag: " & Table.Tag & ", Columns: " & Table.Columns.Size & ", Rows: " & Table.Rows.Size)
|
||||
Dim sb As StringBuilder
|
||||
sb.Initialize
|
||||
For Each col In Table.Columns.Keys
|
||||
sb.Append(col).Append(TAB)
|
||||
Next
|
||||
Log(sb.ToString)
|
||||
For Each row() As Object In Table.Rows
|
||||
Dim sb As StringBuilder
|
||||
sb.Initialize
|
||||
For Each record As Object In row
|
||||
sb.Append(record).Append(TAB)
|
||||
Next
|
||||
Log(sb.ToString)
|
||||
Next
|
||||
End Sub
|
||||
|
||||
Sub requestTimes(tag As String) As Map 'ignore
|
||||
Private times As Map
|
||||
times.Initialize
|
||||
' Log("###### " & tag)
|
||||
' Log(reqsList.IsInitialized)
|
||||
If reqsList.IsInitialized Then
|
||||
' Log(reqsList)
|
||||
' Private pos As Int = reqsList.IndexOf(tag)
|
||||
If inicioRequestMap.ContainsKey(tag) Then
|
||||
inicioRequest = inicioRequestMap.Get(tag)
|
||||
' Log(">>>>>>> From inicioRequestMap")
|
||||
End If
|
||||
If inicioJobDoneMap.ContainsKey(tag) Then
|
||||
inicioJobDone = inicioJobDoneMap.Get(tag)
|
||||
' Log(">>>>>>> From inicioJobDoneMap")
|
||||
End If
|
||||
End If
|
||||
' Log($"${inicioJobDone} - ${inicioRequest}"$)
|
||||
Private requestTime As String = NumberFormat2(((inicioJobDone - inicioRequest) / 1000),1,5,0,False)
|
||||
Private JobDoneTime As String = NumberFormat2(((DateTime.Now - inicioJobDone) / 1000),1,5,0,False)
|
||||
times.Put("requestTime", requestTime)
|
||||
times.Put("jobDoneTime", JobDoneTime)
|
||||
times.Put("totalTime", NumberFormat2((JobDoneTime + requestTime),1,5,0,False))
|
||||
Return times
|
||||
End Sub
|
||||
|
||||
'Initializes request tracking
|
||||
Sub trackInit 'ignore
|
||||
Log(">>>>>>>>> TRACKINIT ")
|
||||
reqsList.Initialize
|
||||
timesList.Initialize
|
||||
inicioRequestMap.Initialize
|
||||
inicioJobDoneMap.Initialize
|
||||
End Sub
|
||||
|
||||
Sub trackNext(job As HttpJob)
|
||||
If reqsList.IsInitialized Then 'Si tenemos lista de requests, la procesamos.
|
||||
Private quitamos As String = ""
|
||||
If reqsList.IndexOf(job.tag) <> -1 Then
|
||||
Private pos As Int = reqsList.IndexOf(job.tag)
|
||||
If pos <> -1 Then
|
||||
inicioRequestMap.Put(job.Tag, timesList.Get(pos))
|
||||
reqsList.RemoveAt(pos)
|
||||
timesList.RemoveAt(pos)
|
||||
End If
|
||||
quitamos = $"Quitamos ${job.tag} - "$
|
||||
End If
|
||||
LogColor(">>>>>> Requests: " & reqsList.Size & " - " & quitamos & reqsList, Colors.Blue)
|
||||
LogColor(">>>>>> inicioRequestMap:" & inicioRequestMap.Size & " - " & inicioRequestMap, Colors.Magenta)
|
||||
End If
|
||||
End Sub
|
||||
@@ -1,201 +0,0 @@
|
||||
B4A=true
|
||||
Group=Default Group
|
||||
ModulesStructureVersion=1
|
||||
Type=Class
|
||||
Version=6.8
|
||||
@EndOfDesignText@
|
||||
'Requires support for resumable subs
|
||||
'Class module
|
||||
|
||||
Sub Class_Globals
|
||||
Private mTarget As Object
|
||||
Private link As String
|
||||
Private VERSION As Float = 2
|
||||
Dim reqsList, timesList As List
|
||||
Dim inicioRequest As Long 'ignore
|
||||
Dim inicioJobDone As Long 'ignore
|
||||
Dim inicioRequestMap, inicioJobDoneMap As Map
|
||||
End Sub
|
||||
|
||||
'Target - The module that handles JobDone (usually Me).
|
||||
'ConnectorLink - URL of the Java server.
|
||||
Public Sub Initialize (Target As Object, ConnectorLink As String)
|
||||
mTarget = Target
|
||||
link = ConnectorLink
|
||||
End Sub
|
||||
|
||||
'Sends a query request.
|
||||
'Command - Query name and parameters.
|
||||
'Limit - Maximum rows to return or 0 for no limit.
|
||||
'Tag - An object that will be returned in the result.
|
||||
Public Sub ExecuteQuery(Command As DBCommand, Limit As Int, Tag As Object) As HttpJob
|
||||
Dim ser As B4XSerializator
|
||||
Dim data() As Byte = ser.ConvertObjectToBytes(CreateMap("command": Command, "limit": Limit, "version": VERSION))
|
||||
Return SendJob(CreateJob, data, Tag, "query2")
|
||||
End Sub
|
||||
|
||||
Private Sub SendJob(j As HttpJob, Data() As Byte, Tag As Object, Method As String) As HttpJob
|
||||
j.Tag = Tag
|
||||
j.PostBytes(link & "?method=" & Method , Data)
|
||||
Return j
|
||||
End Sub
|
||||
|
||||
Private Sub CreateJob As HttpJob
|
||||
Dim j As HttpJob
|
||||
j.Initialize("DBRequest", mTarget)
|
||||
Return j
|
||||
End Sub
|
||||
|
||||
'Executes a batch of (non-select) commands.
|
||||
'ListOfCommands - List of the commands that will be executes.
|
||||
'Tag - An object that will be returned in the result.
|
||||
Public Sub ExecuteBatch(ListOfCommands As List, Tag As Object) As HttpJob
|
||||
Dim j As HttpJob = CreateJob
|
||||
ExecuteBatchImpl(j, ListOfCommands, Tag)
|
||||
Return j
|
||||
End Sub
|
||||
|
||||
Private Sub ExecuteBatchImpl(Job As HttpJob, ListOfCommands As List, Tag As Object)
|
||||
Dim ser As B4XSerializator
|
||||
ser.ConvertObjectToBytesAsync(CreateMap("commands": ListOfCommands, "version": VERSION), "ser")
|
||||
Wait For (ser) ser_ObjectToBytes (Success As Boolean, Bytes() As Byte)
|
||||
If Success = False Then
|
||||
Log("Error building command: " & LastException)
|
||||
Return
|
||||
End If
|
||||
Dim ser As B4XSerializator = Sender
|
||||
SendJob(Job, Bytes, Tag, "batch2")
|
||||
End Sub
|
||||
|
||||
|
||||
'Similar to ExecuteBatch. Sends a single command.
|
||||
Public Sub ExecuteCommand(Command As DBCommand, Tag As Object) As HttpJob
|
||||
Return ExecuteBatch(Array As DBCommand(Command), Tag)
|
||||
End Sub
|
||||
|
||||
'Handles the Job result and returns a DBResult.
|
||||
'It is recommended to use HandleJobAsync instead.
|
||||
Public Sub HandleJob(Job As HttpJob) As DBResult
|
||||
Dim ser As B4XSerializator
|
||||
Dim data() As Byte = Bit.InputStreamToBytes(Job.GetInputStream)
|
||||
Dim res As DBResult = ser.ConvertBytesToObject(data)
|
||||
res.Tag = Job.Tag
|
||||
Return res
|
||||
End Sub
|
||||
'Handles the Job result and raises the Result event when the data is ready.
|
||||
|
||||
Public Sub HandleJobAsync(Job As HttpJob, EventName As String)
|
||||
Dim ser As B4XSerializator
|
||||
Dim data() As Byte = Bit.InputStreamToBytes(Job.GetInputStream)
|
||||
ser.ConvertBytesToObjectAsync(data, "ser")
|
||||
Wait For (ser) ser_BytesToObject (Success As Boolean, NewObject As Object)
|
||||
If Success = False Then
|
||||
Log("Error reading response: " & LastException)
|
||||
Return
|
||||
End If
|
||||
Dim res As DBResult = NewObject
|
||||
res.Tag = Job.Tag
|
||||
CallSubDelayed2(mTarget, EventName & "_result", res)
|
||||
End Sub
|
||||
|
||||
|
||||
|
||||
|
||||
'Reads a file and returns the file as a bytes array.
|
||||
Public Sub FileToBytes(Dir As String, FileName As String) As Byte()
|
||||
Dim out As OutputStream
|
||||
out.InitializeToBytesArray(0)
|
||||
Dim In As InputStream = File.OpenInput(Dir, FileName)
|
||||
File.Copy2(In, out)
|
||||
out.Close
|
||||
Return out.ToBytesArray
|
||||
End Sub
|
||||
#if Not(B4J)
|
||||
'Converts an image to a bytes array (for BLOB fields).
|
||||
Public Sub ImageToBytes(Image As Bitmap) As Byte()
|
||||
Dim out As OutputStream
|
||||
out.InitializeToBytesArray(0)
|
||||
Image.WriteToStream(out, 100, "JPEG")
|
||||
out.Close
|
||||
Return out.ToBytesArray
|
||||
End Sub
|
||||
'Converts a bytes array to an image (for BLOB fields).
|
||||
Public Sub BytesToImage(bytes() As Byte) As Bitmap
|
||||
Dim In As InputStream
|
||||
In.InitializeFromBytesArray(bytes, 0, bytes.Length)
|
||||
Dim bmp As Bitmap
|
||||
bmp.Initialize2(In)
|
||||
Return bmp
|
||||
End Sub
|
||||
#End If
|
||||
|
||||
'Prints the table to the logs.
|
||||
Public Sub PrintTable(Table As DBResult)
|
||||
Log("Tag: " & Table.Tag & ", Columns: " & Table.Columns.Size & ", Rows: " & Table.Rows.Size)
|
||||
Dim sb As StringBuilder
|
||||
sb.Initialize
|
||||
For Each col In Table.Columns.Keys
|
||||
sb.Append(col).Append(TAB)
|
||||
Next
|
||||
Log(sb.ToString)
|
||||
For Each row() As Object In Table.Rows
|
||||
Dim sb As StringBuilder
|
||||
sb.Initialize
|
||||
For Each record As Object In row
|
||||
sb.Append(record).Append(TAB)
|
||||
Next
|
||||
Log(sb.ToString)
|
||||
Next
|
||||
End Sub
|
||||
|
||||
Sub requestTimes(tag As String) As Map 'ignore
|
||||
Private times As Map
|
||||
times.Initialize
|
||||
' Log("###### " & tag)
|
||||
' Log(reqsList.IsInitialized)
|
||||
If reqsList.IsInitialized Then
|
||||
' Log(reqsList)
|
||||
' Private pos As Int = reqsList.IndexOf(tag)
|
||||
If inicioRequestMap.ContainsKey(tag) Then
|
||||
inicioRequest = inicioRequestMap.Get(tag)
|
||||
' Log(">>>>>>> From inicioRequestMap")
|
||||
End If
|
||||
If inicioJobDoneMap.ContainsKey(tag) Then
|
||||
inicioJobDone = inicioJobDoneMap.Get(tag)
|
||||
' Log(">>>>>>> From inicioJobDoneMap")
|
||||
End If
|
||||
End If
|
||||
' Log($"${inicioJobDone} - ${inicioRequest}"$)
|
||||
Private requestTime As String = NumberFormat2(((inicioJobDone - inicioRequest) / 1000),1,5,0,False)
|
||||
Private JobDoneTime As String = NumberFormat2(((DateTime.Now - inicioJobDone) / 1000),1,5,0,False)
|
||||
times.Put("requestTime", requestTime)
|
||||
times.Put("jobDoneTime", JobDoneTime)
|
||||
times.Put("totalTime", NumberFormat2((JobDoneTime + requestTime),1,5,0,False))
|
||||
Return times
|
||||
End Sub
|
||||
|
||||
'Initializes request tracking
|
||||
Sub trackInit 'ignore
|
||||
Log(">>>>>>>>> TRACKINIT ")
|
||||
reqsList.Initialize
|
||||
timesList.Initialize
|
||||
inicioRequestMap.Initialize
|
||||
inicioJobDoneMap.Initialize
|
||||
End Sub
|
||||
|
||||
Sub trackNext(job As HttpJob)
|
||||
If reqsList.IsInitialized Then 'Si tenemos lista de requests, la procesamos.
|
||||
Private quitamos As String = ""
|
||||
If reqsList.IndexOf(job.tag) <> -1 Then
|
||||
Private pos As Int = reqsList.IndexOf(job.tag)
|
||||
If pos <> -1 Then
|
||||
inicioRequestMap.Put(job.Tag, timesList.Get(pos))
|
||||
reqsList.RemoveAt(pos)
|
||||
timesList.RemoveAt(pos)
|
||||
End If
|
||||
quitamos = $"Quitamos ${job.tag} - "$
|
||||
End If
|
||||
LogColor(">>>>>> Requests: " & reqsList.Size & " - " & quitamos & reqsList, Colors.Blue)
|
||||
LogColor(">>>>>> inicioRequestMap:" & inicioRequestMap.Size & " - " & inicioRequestMap, Colors.Magenta)
|
||||
End If
|
||||
End Sub
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
B4A/Files/qr.bal
BIN
B4A/Files/qr.bal
Binary file not shown.
Binary file not shown.
@@ -331,7 +331,7 @@ File395=productos2.bal
|
||||
File396=profina.jpg
|
||||
File397=profina.png
|
||||
File398=promociones.bal
|
||||
File399=qr.bal
|
||||
File399=qr.bal__
|
||||
File4=alerta_amarilla.png
|
||||
File40=info_gral.resp
|
||||
File400=QR_Kelloggs.png
|
||||
@@ -882,24 +882,24 @@ Module11=C_NuevoCliente
|
||||
Module12=C_Pedidos
|
||||
Module13=C_Principal
|
||||
Module14=C_Productos
|
||||
Module15=C_Promos
|
||||
Module16=C_TicketsDia
|
||||
Module17=|relative|..\C_TrendSpending
|
||||
Module18=C_updateAvailable
|
||||
Module19=CameraExClass
|
||||
Module2=|relative|..\C_Auditoria
|
||||
Module20=DBRequestManager
|
||||
Module21=DBRequestManagerW
|
||||
Module22=DownloadService
|
||||
Module23=errorManager
|
||||
Module24=EscPosPrinter
|
||||
Module25=FileHandler
|
||||
Module26=foto
|
||||
Module27=kms_helperSubs
|
||||
Module28=ManageExternalStorage
|
||||
Module29=MAPA_RUTAS
|
||||
Module15=C_Promociones
|
||||
Module16=C_Promos
|
||||
Module17=C_TicketsDia
|
||||
Module18=C_TrendSpending
|
||||
Module19=C_updateAvailable
|
||||
Module2=C_Auditoria
|
||||
Module20=CameraExClass
|
||||
Module21=DBRequestManager
|
||||
Module22=DBRequestManagerW
|
||||
Module23=DownloadService
|
||||
Module24=errorManager
|
||||
Module25=EscPosPrinter
|
||||
Module26=FileHandler
|
||||
Module27=foto
|
||||
Module28=kms_helperSubs
|
||||
Module29=ManageExternalStorage
|
||||
Module3=C_CheckList
|
||||
Module30=Promociones
|
||||
Module30=MAPA_RUTAS
|
||||
Module31=SD_Spinner
|
||||
Module32=Starter
|
||||
Module33=Subs
|
||||
@@ -918,7 +918,7 @@ Version=12.8
|
||||
#Region Project Attributes
|
||||
#ApplicationLabel: Kelloggs Venta
|
||||
#VersionCode: 3000
|
||||
#VersionName: 6.01.31
|
||||
#VersionName: 6.02.03
|
||||
#SupportedOrientations: portrait
|
||||
#CanInstallToExternalStorage: False
|
||||
#BridgeLogger:true
|
||||
@@ -947,7 +947,24 @@ Sub Process_Globals
|
||||
End Sub
|
||||
|
||||
Sub Globals
|
||||
|
||||
' Esta estructura es IDÉNTICA al Mapa que usas en Subs.traePromo
|
||||
Type TPromoLegacy ( Id As String, _
|
||||
MaxXCliente As String, _
|
||||
MaxRecurrente As String, _
|
||||
MaxPromos As String, _
|
||||
historico As String, _
|
||||
productos As Map, _
|
||||
Tipos As Map, _
|
||||
ProdsFijos As List, _
|
||||
ProdsVariables As List, _
|
||||
ProdsFijosPiezas As List, _
|
||||
ProdsFijosPrecios As List, _
|
||||
ProdsVariablesPrecios As List, _
|
||||
ProdsVariablesRequeridos As Int, _
|
||||
Descripcion As String, _
|
||||
Resultado As String, _
|
||||
MensajeError As String _
|
||||
)
|
||||
End Sub
|
||||
|
||||
Sub Activity_Create(FirstTime As Boolean)
|
||||
|
||||
@@ -73,10 +73,10 @@ ModuleClosedNodes1=
|
||||
ModuleClosedNodes10=
|
||||
ModuleClosedNodes11=
|
||||
ModuleClosedNodes12=
|
||||
ModuleClosedNodes13=
|
||||
ModuleClosedNodes13=42
|
||||
ModuleClosedNodes14=
|
||||
ModuleClosedNodes15=
|
||||
ModuleClosedNodes16=
|
||||
ModuleClosedNodes16=1,2,7,8,9
|
||||
ModuleClosedNodes17=
|
||||
ModuleClosedNodes18=
|
||||
ModuleClosedNodes19=
|
||||
@@ -90,19 +90,19 @@ ModuleClosedNodes25=
|
||||
ModuleClosedNodes26=
|
||||
ModuleClosedNodes27=
|
||||
ModuleClosedNodes28=
|
||||
ModuleClosedNodes29=3
|
||||
ModuleClosedNodes29=
|
||||
ModuleClosedNodes3=
|
||||
ModuleClosedNodes30=
|
||||
ModuleClosedNodes30=3
|
||||
ModuleClosedNodes31=
|
||||
ModuleClosedNodes32=
|
||||
ModuleClosedNodes33=
|
||||
ModuleClosedNodes34=
|
||||
ModuleClosedNodes4=
|
||||
ModuleClosedNodes4=1,128
|
||||
ModuleClosedNodes5=
|
||||
ModuleClosedNodes6=
|
||||
ModuleClosedNodes7=
|
||||
ModuleClosedNodes8=
|
||||
ModuleClosedNodes9=
|
||||
NavigationStack=B4XMainPage,B4XPage_Created,392,0,B4XMainPage,Initialize,123,0,C_Principal,B4XPage_Appear,333,0,C_Principal,connecta_LongClick,2504,0,C_Principal,connecta3,2503,0,C_Principal,connecta2,2488,0,C_Principal,b_motivoNoVisita_Click,4075,0,Diseñador Visual,principal.bal,-100,6,C_Principal,B4XPage_Created,311,0,C_Principal,JobDone,1498,0,C_Principal,cargar_Click,797,0
|
||||
NavigationStack=C_Cliente,JobDone,4283,0,C_Principal,enviaPedidoBatch0,3517,0,C_Principal,SUBIR_INFO_PEDIDO,3519,0,C_Principal,enviaPedidoBatch,3619,0,C_Cliente,Guardar_Click,1084,0,C_Cliente,mandaPendientes,1099,0,C_TrendSpending,traeInfoTrendSpending,75,0,C_Principal,JobDone,2243,0,Diseñador Visual,principal.bal,-100,1,C_Principal,cargar_Click,1030,0,C_Principal,B4XPage_Appear,555,0
|
||||
SelectedBuild=0
|
||||
VisibleModules=32,1,13,4,33,15,34,14,29
|
||||
VisibleModules=32,1,13,4,33,16,34,14,15,18
|
||||
|
||||
@@ -1,592 +0,0 @@
|
||||
B4A=true
|
||||
Group=Default Group
|
||||
ModulesStructureVersion=1
|
||||
Type=Class
|
||||
Version=12.8
|
||||
@EndOfDesignText@
|
||||
'##############################################################################################
|
||||
' CODIGO DE PRUEBA, NO HABILITADO, NO TERMINADO
|
||||
' PRETENDE UTILIZAR MENOS MAPAS Y MAS QUERIES PARA EL CALCULO DE LAS PROMOCIONES
|
||||
'##############################################################################################
|
||||
|
||||
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
|
||||
Dim tablaProds As String
|
||||
Dim muestraLogs As Boolean
|
||||
Dim releaseMode As Boolean
|
||||
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")
|
||||
#if RELEASE
|
||||
releaseMode = True
|
||||
#Else if DEBUG
|
||||
releaseMode = False
|
||||
#end if
|
||||
Return Me
|
||||
End Sub
|
||||
|
||||
Sub procesaPromocion(idPromo As String, cliente0 As String, tipoVenta As String) As Map 'ignore
|
||||
'######################################################
|
||||
muestraLogs = True ' Si es verdadero, se muestran los logs de la clase.
|
||||
'######################################################
|
||||
If releaseMode Then muestraLogs = False
|
||||
cliente = cliente0
|
||||
' Private inicioContador As String = DateTime.Now
|
||||
Private maxPromos As Int = 0
|
||||
Private maxPromosXFijos As Int = 0
|
||||
tablaProds = "cat_gunaprod2"
|
||||
If tipoVenta = "ABORDO" Or tipoVenta = "PREVENTA" Then tablaProds = "cat_gunaprod"
|
||||
If muestraLogs Then LogColor($"**********************************************************************"$, Colors.Green)
|
||||
If muestraLogs Then LogColor($"********* INICIAMOS REVISION DE PROMO ${idPromo} *********"$, Colors.Green)
|
||||
If muestraLogs Then LogColor($"**********************************************************************"$, Colors.Green)
|
||||
' LogColor("**************************** " & traeInfoDePromo("P_PRODSFIJOS", idPromo), Colors.blue)
|
||||
traePromo(idPromo, cliente0) ' Generamos la tabla con la información d la promoción.
|
||||
maxPromosXFijos = revisaMaxPromosProdsFijosPorInventario(idPromo)
|
||||
If maxPromosXFijos < 1 Then
|
||||
db.ExecNonQuery($"update PROMOCIONES_INFO set P_ESTATUS = 'ko' where P_ID = '${idPromo}'"$)
|
||||
End If
|
||||
Private logColor1 As String
|
||||
If traeInfoDePromo("P_ESTATUS", idPromo) = "ok" Then logColor1 = Colors.RGB(0,143,0) Else logColor1 = Colors.Red
|
||||
If muestraLogs And traeInfoDePromo("P_ESTATUS", idPromo) = "ok" Then LogColor($"### MAX PROMOS X FIJOS = ${maxPromosXFijos}"$, logColor1)
|
||||
If traeInfoDePromo("P_ESTATUS", idPromo) = "ok" Then 'Si encontramos la promoción, entonces ...
|
||||
maxPromos = traeMaxPromos(idPromo) ' Buscamos el máximo de promociones permitidas.
|
||||
If muestraLogs Then LogColor($"Promociones permitidas=${maxPromos}"$, Colors.Blue)
|
||||
' If muestraLogs Then Log("Promos vendidas: " & traePromosVendidas(idPromo))
|
||||
If maxPromos < 1 Then
|
||||
If muestraLogs 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 = restaFijosDePromo(idPromo)
|
||||
If muestraLogs Then LogColor("inventarioSinFijos="&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(idPromo, inventarioSinFijos)
|
||||
If pv Then logColor1 = Colors.RGB(0,143,0) Else logColor1 = Colors.Red
|
||||
If muestraLogs And pv Then
|
||||
LogColor("### ALCANZAN LOS VARIABLES? --> " & pv, logColor1)
|
||||
End If
|
||||
' LogColor("TIEMPO DE PROCESO ESTA PROMO: " & ((DateTime.Now-inicioContador)/1000), Colors.Red)
|
||||
If pv Then
|
||||
Return CreateMap("status":"ok", "prodsFijosCant":traeInfoDePromo("P_PRODSFIJOS_CANT", idPromo), "prodsVariablesCant":traeInfoDePromo("P_PRODSVARIABLES_CANT", idPromo))
|
||||
Else
|
||||
If muestraLogs Then LogColor("NO HAY INVENTARIO SUFICIENTE " & idPromo, Colors.red)
|
||||
Return CreateMap("status":"ko")
|
||||
End If
|
||||
Else
|
||||
If muestraLogs Then LogColor("NO HAY INVENTARIO SUFICIENTE " & idPromo, Colors.red)
|
||||
' LogColor("TIEMPO DE PROCESO ESTA PROMO: " & ((DateTime.Now-inicioContador)/1000), Colors.Red)
|
||||
Return CreateMap("status":"ko")
|
||||
End If
|
||||
Else
|
||||
If muestraLogs Then LogColor("NO HAY INVENTARIO SUFICIENTE " & idPromo, Colors.red)
|
||||
' LogColor("TIEMPO DE PROCESO ESTA PROMO: " & ((DateTime.Now-inicioContador)/1000), Colors.Red)
|
||||
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.
|
||||
End Sub
|
||||
|
||||
'Genera una tabla (PROMOCIONES_INFO) con la información de la promo.
|
||||
'Columnas: P_ID, P_MAXXCLIENTE, P_MAXRECURRENTE, P_MAXPROMOS, HISTORICO,
|
||||
' P_TIPOS={idProducto=tipo} 'Mapa con id y tipo del producto, 0 si es fijo y 1 si es variable.
|
||||
' P_PRODSFIJOS=[idProducto,idProducto] 'Lista con los ids de los productos fijos.
|
||||
' P_PRODSVARIABLES=[idProducto,idProducto] 'Lista con los ids de los productos variables.
|
||||
' P_ESTATUS="OK" 'Ok si existe la promocion.
|
||||
' P_PRODSVARIABLES_REQUERIDOS=5 'Cantidad de productos variables requeridos para la promoción.
|
||||
Sub traePromo(promo As String, cliente0 As String) As Map
|
||||
'######################################################
|
||||
muestraLogs = True ' Si es verdadero, se muestran los logs de la clase.
|
||||
'######################################################
|
||||
If releaseMode Then muestraLogs = False
|
||||
If muestraLogs Then LogColor("> TraePromo: " & promo, Colors.blue)
|
||||
' 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, prodsFijosReq, prodsVariables, prodsVariablesPrecios As List
|
||||
promoMap.Initialize
|
||||
prodsFijos.Initialize
|
||||
prodsFijosPrecios.Initialize
|
||||
prodsFijosReq.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_MAXPROMCLIE")}, 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}' "$)
|
||||
If muestraLogs Then 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.
|
||||
If muestraLogs Then 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"$)
|
||||
If muestraLogs Then 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"))
|
||||
prodsFijosReq.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 muestraLogs 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 = '${prodsFijosReq}', 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("prodsFijosReq", prodsFijosReq)
|
||||
' 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 ${tablaProds} 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 muestraLogs Then Log($"Inv variables: ${cuantosVariablesDisponiblesDB(promo)}"$)
|
||||
' If muestraLogs Then Log($"Inv dispo: ${traemosInvDispParaPromo(promo)}"$)
|
||||
' If muestraLogs Then LogColor($"Promo ${promo}: ${promoMap}"$, Colors.Blue)
|
||||
' If muestraLogs Then LogColor("TIEMPO para traePromo -=" & promo & "=- : " & ((DateTime.Now-inicioContador)/1000), Colors.Blue)
|
||||
Return promoMap
|
||||
End Sub
|
||||
|
||||
' Regresa cuantas promos alcanzan con los productos FIJOS que hay en inventario.
|
||||
Sub revisaMaxPromosProdsFijosPorInventario(idPromo As String) As Int
|
||||
If muestraLogs Then LogColor("> revisaMaxPromosProdsFijosPorInventario: " & idPromo, Colors.blue)
|
||||
Private maxPromosPermitidas As List
|
||||
Private promosDispEsteProd, InvDispEsteProd, pzasReqEsteProd As Int
|
||||
Private esteColor As Double
|
||||
Private esteMensaje As String
|
||||
maxPromosPermitidas.Initialize
|
||||
maxPromosPermitidas.Add(traeMaxPromos(idPromo)) ' Agregamos a la lista las promos maximas permitidas (por cliente, recurrentes y maxpromos).
|
||||
' 👇🏼 Traemos los productos fijos y piezas requeridas de la promoción. 👇🏼
|
||||
Private c As ResultSet = db.ExecQuery($"select CAT_DP_IDPROD, sum(CAT_DP_PZAS) as totalPzas from CAT_DETALLES_PAQ where CAT_DP_ID = '${idPromo}' and CAT_DP_TIPO = '0' group by CAT_DP_IDPROD"$)
|
||||
Do While c.NextRow
|
||||
InvDispEsteProd = traeInventario(c.GetString("CAT_DP_IDPROD"))
|
||||
pzasReqEsteProd = c.GetString("totalPzas")
|
||||
esteColor = Colors.green
|
||||
esteMensaje = "INVENTARIO OK"
|
||||
If pzasReqEsteProd > InvDispEsteProd Then
|
||||
esteColor = Colors.red
|
||||
esteMensaje = "INVENTARIO INSUFICIENTE"
|
||||
End If
|
||||
If muestraLogs Then LogColor($"PROD FIJO=${c.GetString("CAT_DP_IDPROD")}, INV=${InvDispEsteProd}, REQ=${pzasReqEsteProd} --> ${esteMensaje}"$, esteColor)
|
||||
promosDispEsteProd = (InvDispEsteProd/pzasReqEsteProd).As(Int) 'Agregamos el as(int) para que solo nos regrese la parte entera de la division.
|
||||
maxPromosPermitidas.Add(promosDispEsteProd) ' Agregamos a la lista las promociones permitidas por inventario de este producto.
|
||||
Loop
|
||||
maxPromosPermitidas.Sort(True) ' Ordenamos la lista para que el primer elemento sea el MAS pequeño.
|
||||
If muestraLogs Then LogColor("Max promos de prodsFijos POR inventario = " & maxPromosPermitidas.Get(0), Colors.Magenta)
|
||||
Return maxPromosPermitidas.Get(0) 'Regresamos el MENOR numero de promociones permitidas.
|
||||
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 llegan 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(idPromo As String) As Int 'ignore
|
||||
If muestraLogs Then LogColor("> revisaMaxPromosProdsVariablesPorInventario: " & idPromo, Colors.blue)
|
||||
Private invFijoXpromo As Map
|
||||
invFijoXpromo.Initialize
|
||||
Private totalProdsVariablesDisponibles As Int = 0
|
||||
' If muestraLogs Then LogColor($"pm=${pm}"$, Colors.Blue)
|
||||
Private invDispParaPromo As Map = traemosInvDispParaPromo(idPromo)
|
||||
' If muestraLogs Then
|
||||
Log($"invDispParaPromo=${invDispParaPromo}"$)
|
||||
Private maxPromos As String = traeMaxPromos(idPromo)
|
||||
Private maxPromosXFijos As Int = revisaMaxPromosProdsFijosPorInventario(idPromo)
|
||||
Private idProdsVariables As List = traeListaDePromo("P_PRODSVARIABLES", idPromo)
|
||||
Private prodsVariablesRequeridos As Int = traeInfoDePromo("P_PRODSVARIABLES_REQUERIDOS", idPromo)
|
||||
Private prodsFijosReq As List = traeListaDePromo("P_PRODSFIJOS_PIEZAS", idPromo)
|
||||
Private idProdsFijos As List = traeListaDePromo("P_PRODSFIJOS", idPromo)
|
||||
For p = 0 To idProdsFijos.Size -1 'Generamos mapa con los productos fijos y piezas requeridas por promo.
|
||||
invFijoXpromo.Put(idProdsFijos.Get(p), prodsFijosReq.Get(p))
|
||||
Log(idProdsFijos)
|
||||
Private idEsteProd As String = idProdsFijos.Get(p)
|
||||
Log(idEsteProd)
|
||||
Private invEsteProd As Int = invDispParaPromo.Get(idEsteProd)
|
||||
Private pzasReqEsteProd As Int = prodsFijosReq.Get(p)
|
||||
If muestraLogs Then Log($"id=${idEsteProd}, inv=${invEsteProd}, pzas=${pzasReqEsteProd}"$)
|
||||
' invDispParaPromo.Put( idEsteProd, (invEsteProd - (1)) )
|
||||
Next
|
||||
If muestraLogs Then LogColor($"MaxPromos=${maxPromos}, promosXFijos=${maxPromosXFijos}"$, Colors.Blue)
|
||||
If muestraLogs Then LogColor($"prodsFijos=${idProdsFijos}"$, Colors.Blue)
|
||||
If muestraLogs Then LogColor($"prodsFijosReq=${prodsFijosReq}"$, Colors.Blue)
|
||||
If muestraLogs Then LogColor($"prodsVariables=${idProdsVariables}${CRLF}Variables Req=${prodsVariablesRequeridos} "$, Colors.Blue)
|
||||
If muestraLogs Then LogColor($"invFijoXpromo=${invFijoXpromo}"$, Colors.Blue)
|
||||
If muestraLogs Then Log($"Prods variables disponibles = ${totalProdsVariablesDisponibles}"$)
|
||||
Private maxPromosXVariables As Int = 0
|
||||
If Not(releaseMode) Then muestraLogs = True
|
||||
For x = 1 To maxPromosXFijos
|
||||
If muestraLogs Then Log("=====================================================")
|
||||
For i = 0 To idProdsFijos.Size - 1
|
||||
' Log(prodsFijosReq.Get(i))
|
||||
Private prodsFijosRequeridos As Int = prodsFijosReq.Get(i)
|
||||
Private esteProdFijo As String = idProdsFijos.Get(i)
|
||||
' Log(invDispParaPromo)
|
||||
If muestraLogs Then Log($"FIJO - ${idProdsFijos.Get(i)}, ${invDispParaPromo.Get(esteProdFijo)} - ${prodsFijosRequeridos*(i+1)}"$)
|
||||
invDispParaPromo.Put(esteProdFijo, invDispParaPromo.Get(esteProdFijo) - prodsFijosRequeridos*(i+1)) 'Restamos las piezas de los productos fijos del inventario disponible.
|
||||
Next
|
||||
If muestraLogs 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.
|
||||
Private thisProdVariable As String = idProdsVariables.Get(i)
|
||||
If invDispParaPromo.ContainsKey(thisProdVariable) Then
|
||||
totalProdsVariablesDisponibles = totalProdsVariablesDisponibles + invDispParaPromo.Get(thisProdVariable)
|
||||
End If
|
||||
Next
|
||||
'Revisamos variables.
|
||||
If muestraLogs Then Log($"Var disponibles - var requeridos : ${totalProdsVariablesDisponibles} - ${prodsVariablesRequeridos*x}"$)
|
||||
totalProdsVariablesDisponibles = totalProdsVariablesDisponibles - (prodsVariablesRequeridos*x)
|
||||
If muestraLogs 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 traemosInvDispParaPromo(idPromo As String) As Map 'ignore
|
||||
If muestraLogs Then LogColor("> traemosInvDispParaPromo: " & idPromo, Colors.blue)
|
||||
Private c As Cursor
|
||||
c = Starter.skmt.ExecQuery2($"SELECT CAT_GP_ID, CAT_GP_ALMACEN FROM ${tablaProds} WHERE CAT_GP_ID IN (select CAT_DP_IDPROD FROM CAT_DETALLES_PAQ WHERE CAT_DP_ID = ?)"$, Array As String(idPromo))
|
||||
' 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 y regresa un mapa con el nuevo inventario.
|
||||
'Hay que darle como parametro el Id de la promocion.
|
||||
'Regresa en el mapa la llave "resultado" que nos da "ok" o "No hay suficiente producto para la promocion".
|
||||
Sub restaFijosDePromo(idPromo As String) As Map 'ignore
|
||||
If muestraLogs Then LogColor("> restaFijosDePromo: " & idPromo, Colors.blue)
|
||||
Private invDispEstaPromo As Map = traemosInvDispParaPromo(idPromo) 'Obtenemos un mapa con el inventario disponible para cada producto de la promocion desde la base de datos.
|
||||
If muestraLogs Then LogColor("Inventario inicial antes de FIJOS: "&invDispEstaPromo, Colors.Magenta) 'Inventario inicial.
|
||||
Private InvDispEsteProd, pzasReqEsteProd As Int
|
||||
Private esteProd As String
|
||||
invDispEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.") 'Valor por DEFAULT.
|
||||
Private nuevoInv As Int
|
||||
' 👇🏼 Traemos los productos fijos y piezas requeridas de la promoción. 👇🏼
|
||||
Private c As ResultSet = db.ExecQuery($"select CAT_DP_IDPROD, sum(CAT_DP_PZAS) as totalPzas from CAT_DETALLES_PAQ where CAT_DP_ID = '${idPromo}' and CAT_DP_TIPO = '0' group by CAT_DP_IDPROD"$)
|
||||
Do While c.NextRow
|
||||
esteProd = c.GetString("CAT_DP_IDPROD")
|
||||
pzasReqEsteProd = c.GetString("totalPzas")
|
||||
If muestraLogs Then Log($"esteProd ${esteProd}, piezasReq: ${pzasReqEsteProd}"$) 'Producto y piezas requeridas
|
||||
If muestraLogs Then Log("invDispEstaPromo="&invDispEstaPromo)
|
||||
If invDispEstaPromo.ContainsKey(esteProd) Then 'Si el mapa del inventario contiene el id del producto entonces ...
|
||||
InvDispEsteProd = invDispEstaPromo.get(esteProd) 'Obtenemos del mapa el inventario de este producto.
|
||||
nuevoInv = NumberFormat2((InvDispEsteProd - pzasReqEsteProd), 1, 0,0,False)
|
||||
If muestraLogs Then Log($"Nuevo inventario de ${esteProd}: ${InvDispEsteProd}-${pzasReqEsteProd} = ${nuevoInv}"$) 'El nuevo inventario.
|
||||
invDispEstaPromo.Put(esteProd.Trim, nuevoInv) 'Restamos del inventario las piezas requeridas para la promoción y guardamos el nuevo inventario en el mapa.
|
||||
invDispEstaPromo.Put("resultado", "ok")
|
||||
Else 'Si en el mapa no esta el id del producto, entonces no tenemos inventario.
|
||||
invDispEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.")
|
||||
If muestraLogs Then LogColor("Sin suficiente inventario fijo: " & esteProd, Colors.Blue)
|
||||
Exit
|
||||
End If
|
||||
If nuevoInv < 0 Then
|
||||
invDispEstaPromo.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
|
||||
Loop
|
||||
If muestraLogs Then LogColor("Inventario final despues de FIJOS: "&invDispEstaPromo, Colors.blue) 'Inventario final.
|
||||
Return invDispEstaPromo
|
||||
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(idPromo As String, inventarioSinFijos As Map) As Boolean 'ignore
|
||||
If muestraLogs Then LogColor("> alcanzanLosVariablesParaPromo: " & idPromo, Colors.blue)
|
||||
If muestraLogs 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 = traeListaDePromo("P_PRODSVARIABLES", idPromo) ' 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 muestraLogs Then Log($"prod ${t}, hay: ${p2}"$) 'Producto y piezas requeridas
|
||||
totalProdsVariables = totalProdsVariables + p2
|
||||
End If
|
||||
Next
|
||||
Private prodsVariablesRequeridos As Int = traeInfoDePromo("P_PRODSVARIABLES_REQUERIDOS", idPromo)
|
||||
If muestraLogs Then Log("Total prods variables=" & totalProdsVariables & ", requeridos=" & prodsVariablesRequeridos)
|
||||
Private res As Boolean = False
|
||||
If totalProdsVariables >= 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
|
||||
If muestraLogs Then LogColor("> traeMaxPromos: " & idPromo, Colors.blue)
|
||||
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 muestraLogs Then LogColor("Historico: "&traeInfoDePromo("HISTORICO", idPromo), Colors.Blue)
|
||||
' If muestraLogs Then Log(pm)
|
||||
If traeInfoDePromo("HISTORICO", idPromo) = "1" Then maxPromos.Add(traeInfoDePromo("P_MAXRECURRENTE", idPromo).As(Int)) 'Si hay historico, agregamos maxRecurrente
|
||||
If traeInfoDePromo("P_MAXPROMOS", idPromo) <> "null" Then maxPromos.Add(traeInfoDePromo("P_MAXPROMOS", idPromo).As(Int)) 'Agregamos maxPromos
|
||||
If traeInfoDePromo("P_MAXXCLIENTE", idPromo) <> "null" Then maxPromos.Add(traeInfoDePromo("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($"|${traeInfoDePromo("HISTORICO", idPromo)}|${traeInfoDePromo("P_MAXPROMOS", idPromo)}|${traeInfoDePromo("P_MAXXCLIENTE", idPromo)}|"$)
|
||||
' Log(maxPromos)
|
||||
maxPromos.Sort(True)
|
||||
' If muestraLogs Then Log($"Max promos : ${maxPromos}"$)
|
||||
mp = 0
|
||||
If maxPromos.Size > 0 Then
|
||||
mp0 = maxPromos.Get(0)
|
||||
' Log(mp0)
|
||||
Private promosVendidas As Int = traePromosVendidas(idPromo)
|
||||
mp = mp0 - promosVendidas
|
||||
If muestraLogs Then Log($"Max Promos (${mp0}) - Promos Vendidas (${(promosVendidas)}) = Promos Disponibles (${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
|
||||
If muestraLogs Then LogColor("> traePromosVendidas: " & idPromo, Colors.blue)
|
||||
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
|
||||
|
||||
'Trae el valor de la columna especificada de la promo dada.
|
||||
Sub traeInfoDePromo(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 traeListaDePromo(col As String, promo As String) As List
|
||||
' Log($"${col}, ${promo}"$)
|
||||
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)
|
||||
res.Initialize
|
||||
s = s.Replace("[", "")
|
||||
s = s.Replace("]", "")
|
||||
Private s2() As String = Regex.Split(",", s)
|
||||
For i = 0 To s2.Length - 1
|
||||
res.Add(s2(i).as(String).trim)
|
||||
Next
|
||||
Else
|
||||
res.Initialize
|
||||
End If
|
||||
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 traeMapaDePromo(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
|
||||
|
||||
'Regresa el inventario de un producto dado o CERO si no lo encuentra.
|
||||
Sub traeInventario(id As String) As Int
|
||||
Private inv As Int = 0
|
||||
Private c As ResultSet = db.ExecQuery($"select CAT_GP_ALMACEN from ${tablaProds} where CAT_GP_ID = ${id}"$)
|
||||
Do While c.NextRow
|
||||
inv = c.GetInt("CAT_GP_ALMACEN")
|
||||
Loop
|
||||
Return inv
|
||||
End Sub
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
'Regresa cuantas promos alcanzan con los productos FIJOS que hay en inventario.
|
||||
Sub revisaMaxPromosProdsFijosPorInventarioXXX(id As String) As Int
|
||||
If muestraLogs Then LogColor("> revisaMaxPromosProdsFijosPorInventario: " & id, Colors.blue)
|
||||
' Private invFijoXpromo As Map
|
||||
Private t As List
|
||||
t.Initialize
|
||||
t.Add(traeMaxPromos(id)) ' Agregamos a la lista las promos maximas permitidas (recurrente, cliente y promo).
|
||||
' invFijoXpromo.Initialize
|
||||
' If muestraLogs Then LogColor($"pm=${pm}"$, Colors.Blue)
|
||||
Private prodsFijosReq As List = traeListaDePromo("P_PRODSFIJOS_PIEZAS", id)
|
||||
Private idProdsFijos As List = traeListaDePromo("P_PRODSFIJOS", id)
|
||||
If muestraLogs Then Log($"ProdsFijos: ${idProdsFijos}, PiezasReq: ${prodsFijosReq}"$)
|
||||
Private invDispParaPromo As Map = traemosInvDispParaPromo(id)
|
||||
If muestraLogs Then Log(">>> " & $"invDispParaPromo=${invDispParaPromo}"$)
|
||||
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
|
||||
If invDispParaPromo.Get(idProdsFijos.Get(p).As(String)) <> Null Then
|
||||
thisInvDisp = invDispParaPromo.Get(idProdsFijos.Get(p).As(String))
|
||||
End If
|
||||
Private esteColor As Double = Colors.green
|
||||
Private esteMensaje As String = "INVENTARIO OK"
|
||||
If prodsFijosReq.Get(p) > thisInvDisp Then
|
||||
esteColor = Colors.red
|
||||
esteMensaje = "INVENTARIO INSUFICIENTE"
|
||||
End If
|
||||
If muestraLogs Then LogColor($"PROD=${idProdsFijos.Get(p)}, INV=${thisInvDisp}, REQ=${prodsFijosReq.Get(p)} - ${esteMensaje}"$, esteColor)
|
||||
' If muestraLogs Then Log($"${(thisInvDisp / prodsFijosReq.Get(p))}"$)
|
||||
Private x() As String = Regex.Split("\.", $"${(thisInvDisp / prodsFijosReq.Get(p))}"$) 'Separamos el resultado de la division por el punto decimal.
|
||||
' If muestraLogs Then Log($"PROD: ${idProdsFijos.Get(p)}, INV: ${x(0)}, REQ: ${prodsFijosReq.Get(p)}"$)
|
||||
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 resultado mas pequeño.
|
||||
' If muestraLogs Then LogColor($"prodsFijos=${idProdsFijos}"$, Colors.Blue)
|
||||
' If muestraLogs Then LogColor($"prodsFijosReq=${prodsFijosReq}"$, Colors.Blue)
|
||||
' If muestraLogs Then LogColor($"promosProdsFijosDisp=${t}"$, Colors.Blue)
|
||||
' If muestraLogs Then LogColor($"invFijoXpromo=${invFijoXpromo}"$, Colors.Blue)
|
||||
If muestraLogs Then LogColor("Max promos de prodsFijos POR inventario = " & t.Get(0), Colors.Magenta)
|
||||
Return t.Get(0) 'Regresamos el resultado mas pequeño.
|
||||
End Sub
|
||||
|
||||
'Resta los productos fijos del inventario de la promoción y regresa un mapa con el nuevo inventario.
|
||||
'Hay que darle como parametro el Id de la promocion.
|
||||
'Regresa en el mapa la llave "resultado" que nos da "ok" o "No hay suficiente producto para la promocion".
|
||||
Sub restaFijosDePromoXXX(idPromo As String) As Map 'ignore
|
||||
If muestraLogs Then LogColor("> restaFijosDePromo: " & idPromo, Colors.blue)
|
||||
Private invDispEstaPromo As Map = traemosInvDispParaPromo(idPromo) 'Obtenemos un mapa con el inventario disponible para cada producto de la promocion desde la base de datos.
|
||||
If muestraLogs Then LogColor("Inventario inicial antes de FIJOS: "&invDispEstaPromo, Colors.Magenta) 'Inventario inicial.
|
||||
Private inv As Int
|
||||
Private prodsFijos As List = traeListaDePromo("P_PRODSFIJOS", idPromo) 'Obtenemos una lista con los productos fijos de la promoción.
|
||||
Private prodsFijosReq As List = traeListaDePromo("P_PRODSFIJOS_PIEZAS", idPromo) 'Obtenemos un a lista con los productos fijos de la promoción.
|
||||
If muestraLogs Then LogColor("ProdsFijos -> " & prodsFijos, Colors.red)
|
||||
invDispEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.") 'Valor por DEFAULT.
|
||||
If muestraLogs Then Log($"Prods fijos requeridos ${prodsFijos.Size}"$)
|
||||
If prodsFijos.Size = 0 Then invDispEstaPromo.Put("resultado", "ok") 'Si no lleva prods fijos la promo, entonces ponemos FIJOS OK.
|
||||
Private nuevoInv As Int
|
||||
For p = 0 To prodsFijos.Size - 1
|
||||
Private esteProd As String = prodsFijos.Get(p) 'Obtenemos el Id de este producto desde la lista de productos fijos.
|
||||
If muestraLogs Then Log($"esteProd ${esteProd}, piezasReq: ${prodsFijosReq.Get(p)}"$) 'Producto y piezas requeridas
|
||||
If muestraLogs Then Log("invDispEstaPromo="&invDispEstaPromo)
|
||||
If invDispEstaPromo.ContainsKey(esteProd) Then 'Si el mapa del inventario contiene el id del producto entonces ...
|
||||
inv = invDispEstaPromo.get(esteProd) 'Obtenemos del mapa el inventario de este producto.
|
||||
nuevoInv = NumberFormat2((inv - prodsFijosReq.get(p)), 1, 0,0,False)
|
||||
If muestraLogs Then Log($"Nuevo inventario de ${esteProd}: ${inv}-${prodsFijosReq.get(p)} = ${nuevoInv}"$) 'El nuevo inventario.
|
||||
invDispEstaPromo.Put(esteProd, $"${nuevoInv}"$) 'Restamos del inventario las piezas requeridas para la promoción y guardamos el nuevo inventario en el mapa.
|
||||
invDispEstaPromo.Put("resultado", "ok")
|
||||
Else 'Si en el mapa no esta el id del producto, entonces no tenemos inventario.
|
||||
invDispEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.")
|
||||
If muestraLogs Then LogColor("Sin suficiente inventario fijo: " & esteProd, Colors.Blue)
|
||||
Exit
|
||||
End If
|
||||
If nuevoInv < 0 Then
|
||||
invDispEstaPromo.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 muestraLogs Then LogColor("Inventario final despues de FIJOS: "&invDispEstaPromo, Colors.blue) 'Inventario final.
|
||||
Return invDispEstaPromo
|
||||
End Sub
|
||||
@@ -72,6 +72,7 @@ Sub Service_Create
|
||||
GPS.Initialize("GPS")
|
||||
ubicacionActual.Initialize
|
||||
Subs.revisaBD
|
||||
' promociones.Initialize
|
||||
pe.Initialize("pe") 'Para obtener la bateria
|
||||
' skmt = s.dbInit 'Inicializamos BD.
|
||||
DBReqServer = "http://keymon.net:1781"
|
||||
|
||||
@@ -2065,7 +2065,7 @@ Sub revisaHora As Boolean
|
||||
Private hr As Int = h.GetString("CAT_VA_VALOR")
|
||||
DateTime.DateFormat = "HH"
|
||||
Private ahora As String = DateTime.Date(DateTime.Now)
|
||||
' Log($"${hr} >= ${(ahora - 2)} and ${hr} <= ${(ahora + 2)}"$)
|
||||
Log($"${hr} >= ${(ahora - 2)} and ${hr} <= ${(ahora + 2)}"$)
|
||||
If hr >= ahora - 2 And hr <= ahora + 2 Then
|
||||
horaCorrecta = True
|
||||
End If
|
||||
|
||||
167
B4A/_git_tag.ps1
167
B4A/_git_tag.ps1
@@ -1,110 +1,127 @@
|
||||
# --- SCRIPT DE AUTODESCUBRIMIENTO CON GUI MEJORADA ---
|
||||
# --- SCRIPT DE COMMIT Y TAG (MODO IDE B4A) ---
|
||||
|
||||
# Cargar librería visual
|
||||
# 0. CONFIGURACIÓN
|
||||
$HacerPush = $true # Cambia a $true para que suba los cambios a GitHub
|
||||
|
||||
# Cargar librería visual para el MessageBox (por si se necesita en el Push)
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
|
||||
# 1. AUTODESCUBRIMIENTO
|
||||
$projectPath = $PSScriptRoot
|
||||
Write-Host "Ruta: $projectPath"
|
||||
Write-Host "Ruta del proyecto: $projectPath"
|
||||
|
||||
$b4aFileItem = Get-ChildItem -Path $projectPath -Filter "*.b4a" | Select-Object -First 1
|
||||
|
||||
if (-Not $b4aFileItem) {
|
||||
[System.Windows.Forms.MessageBox]::Show("No hay archivo .b4a en esta carpeta.", "Error", "OK", "Error")
|
||||
Write-Host "ERROR: No hay archivo .b4a en esta carpeta."
|
||||
return
|
||||
}
|
||||
|
||||
$b4aFile = $b4aFileItem.FullName
|
||||
$projectName = $b4aFileItem.BaseName
|
||||
Write-Host "Proyecto: $projectName"
|
||||
Write-Host "Proyecto detectado: $projectName"
|
||||
|
||||
# 2. LIMPIEZA
|
||||
# $objectsPath = Join-Path $projectPath "Objects"
|
||||
# if (Test-Path $objectsPath) {
|
||||
# Write-Host "Limpiando Objects..."
|
||||
# Remove-Item -Path "$objectsPath\*" -Recurse -Force -ErrorAction SilentlyContinue
|
||||
# }
|
||||
|
||||
# 3. LEER VERSIÓN
|
||||
$versionLine = Get-Content $b4aFile | Select-String "#VersionName:"
|
||||
if (-Not $versionLine) { Write-Error "Falta #VersionName"; return }
|
||||
# 2. LEER VERSIÓN
|
||||
$versionLine = Get-Content $b4aFileItem.FullName | Select-String "#VersionName:"
|
||||
if (-Not $versionLine) {
|
||||
Write-Host "ERROR: Falta #VersionName en el archivo .b4a"
|
||||
return
|
||||
}
|
||||
$version = ($versionLine -split ":")[1].Trim()
|
||||
$tagName = "v$version"
|
||||
# Reemplaza cualquier espacio en blanco por un guion bajo solo para el tag
|
||||
$tagName = "$version".Replace(" ", "_")
|
||||
|
||||
Set-Location $projectPath
|
||||
|
||||
# 4. COMMIT
|
||||
$oldCommit = git rev-parse HEAD
|
||||
# 3. COMMIT CON TORTOISEGIT
|
||||
$oldCommit = git rev-parse HEAD 2>$null
|
||||
|
||||
Write-Host "----------------------------------------"
|
||||
Write-Host "Versión: $version"
|
||||
Write-Host "Abriendo TortoiseGit..."
|
||||
Write-Host "Version a etiquetar: $version"
|
||||
Write-Host "Abriendo ventana de TortoiseGit..."
|
||||
|
||||
# Argumentos limpios
|
||||
$pathArg = '/path:"{0}"' -f $projectPath
|
||||
$msgArg = '/logmsg:"VERSION {0}"' -f $version
|
||||
$cmdArg = "/command:commit"
|
||||
|
||||
$process = Start-Process "TortoiseGitProc.exe" -ArgumentList $cmdArg, $pathArg, $msgArg -Wait -PassThru
|
||||
Start-Process "TortoiseGitProc.exe" -ArgumentList $cmdArg, $pathArg, $msgArg
|
||||
|
||||
$newCommit = git rev-parse HEAD
|
||||
Write-Host "Esperando a que termines el commit en TortoiseGit..."
|
||||
# El freno de mano: espera a que cierres la ventana
|
||||
while (Get-Process "TortoiseGitProc" -ErrorAction SilentlyContinue) {
|
||||
Start-Sleep -Seconds 1
|
||||
}
|
||||
|
||||
# 5. VALIDACIÓN
|
||||
$newCommit = git rev-parse HEAD 2>$null
|
||||
|
||||
# 4. VALIDACIÓN
|
||||
if ($oldCommit -eq $newCommit) {
|
||||
Write-Warning "Commit cancelado."
|
||||
git tag -d $tagName 2>$null # Borra tag local previo si existe para actualizarlo al nuevo commit
|
||||
Write-Host "WARNING: Commit cancelado o sin cambios detectados."
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host ">> Commit detectado."
|
||||
Write-Host "Commit registrado exitosamente: $newCommit"
|
||||
|
||||
# 6. GESTIÓN DE TAGS (VISUAL TOPMOST)
|
||||
Write-Host "git ls-remote --tags origin $tagName"
|
||||
$remoteTagInfo = git ls-remote --tags origin $tagName
|
||||
# 5. GESTIÓN DE TAGS
|
||||
$tagGenerado = $false
|
||||
|
||||
if ($remoteTagInfo) {
|
||||
# --- TRUCO PARA QUE LA VENTANA SALGA AL FRENTE ---
|
||||
# Creamos un formulario invisible que esté "Siempre Visible" (TopMost)
|
||||
Write-Host "Recibimos remoteTagInfo"
|
||||
$topForm = New-Object System.Windows.Forms.Form
|
||||
$topForm.TopMost = $true
|
||||
$topForm.Opacity = 0 # Invisible
|
||||
$topForm.ShowInTaskbar = $false
|
||||
$topForm.StartPosition = "CenterScreen"
|
||||
$topForm.Show()
|
||||
$topForm.Activate()
|
||||
|
||||
[System.Console]::Beep(1000, 200)
|
||||
[System.Console]::Beep(1000, 200)
|
||||
|
||||
$msgBody = "El tag '$tagName' YA EXISTE en GitHub.`n`nDeseas SOBRESCRIBIRLO?`n`nSi = Borrar anterior y actualizar (Force Push).`nNo = Subir solo codigo (mantener tag viejo)."
|
||||
$msgTitle = "⚠️ Conflicto de Versiones - $projectName"
|
||||
|
||||
# El mensaje ahora es "hijo" del formulario invisible, heredando su propiedad TopMost
|
||||
Write-Host "Preguntamos que hacer con el tag"
|
||||
$respuesta = [System.Windows.Forms.MessageBox]::Show($topForm, $msgBody, $msgTitle, "YesNo", "Warning")
|
||||
|
||||
$topForm.Dispose() # Limpiamos el formulario invisible
|
||||
|
||||
if ($respuesta -eq "Yes") {
|
||||
Write-Host "Sobrescribiendo..."
|
||||
git tag -d $tagName 2>$null
|
||||
git tag -a $tagName -m "Release version $version (Updated)"
|
||||
|
||||
git push origin
|
||||
git push origin $tagName --force
|
||||
Write-Host ">> Tag actualizado (Force Push)."
|
||||
} else {
|
||||
Write-Host "Conservando tag anterior..."
|
||||
git push origin
|
||||
Write-Host ">> Código subido."
|
||||
}
|
||||
} else {
|
||||
# Tag Nuevo
|
||||
git tag -a $tagName -m "Release version $version"
|
||||
git push origin --follow-tags
|
||||
Write-Host ">> Versión publicada."
|
||||
# Revisamos si el tag ya existe localmente y lo borramos para recrearlo con el nuevo commit
|
||||
if (git tag -l $tagName) {
|
||||
git tag -d $tagName 2>$null | Out-Null
|
||||
}
|
||||
|
||||
Write-Host "----------------------------------------"
|
||||
# Creamos el tag nuevo apuntando al commit que acabamos de hacer
|
||||
git tag -a $tagName -m "Release version $version"
|
||||
if ($?) { $tagGenerado = $true }
|
||||
|
||||
# 6. LÓGICA DE PUSH
|
||||
if ($HacerPush) {
|
||||
Write-Host "Conectando con GitHub..."
|
||||
$remoteTagInfo = git ls-remote --tags origin $tagName
|
||||
|
||||
if ($remoteTagInfo) {
|
||||
# Conflicto: Ya existe en remoto
|
||||
$topForm = New-Object System.Windows.Forms.Form
|
||||
$topForm.TopMost = $true
|
||||
$topForm.Opacity = 0
|
||||
$topForm.ShowInTaskbar = $false
|
||||
$topForm.StartPosition = "CenterScreen"
|
||||
$topForm.Show()
|
||||
$topForm.Activate()
|
||||
|
||||
[System.Console]::Beep(1000, 200)
|
||||
|
||||
$msgBody = "El tag '$tagName' YA EXISTE en GitHub.`n`nDeseas SOBRESCRIBIRLO?`n`nSi = Borrar anterior y actualizar (Force Push).`nNo = Subir solo codigo (mantener tag viejo)."
|
||||
$msgTitle = "Conflicto de Versiones - $projectName"
|
||||
|
||||
$respuesta = [System.Windows.Forms.MessageBox]::Show($topForm, $msgBody, $msgTitle, "YesNo", "Warning")
|
||||
$topForm.Dispose()
|
||||
|
||||
if ($respuesta -eq "Yes") {
|
||||
Write-Host "Sobrescribiendo tag en GitHub (Force Push)..."
|
||||
git push origin
|
||||
git push origin $tagName --force
|
||||
} else {
|
||||
Write-Host "Conservando tag anterior en GitHub..."
|
||||
git push origin
|
||||
}
|
||||
} else {
|
||||
# Tag Nuevo
|
||||
Write-Host "Subiendo codigo y tag nuevo a GitHub..."
|
||||
git push origin --follow-tags
|
||||
}
|
||||
} else {
|
||||
Write-Host "Push OMITIDO (Switch de control apagado)."
|
||||
}
|
||||
|
||||
# 7. REPORTE FINAL PARA EL IDE
|
||||
$EstadoPush = if($HacerPush) { "SI" } else { "NO (Modo de prueba local)" }
|
||||
$EstadoTag = if($tagGenerado) { "SI ($tagName)" } else { "NO (Error al generar)" }
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "========================================"
|
||||
Write-Host " REPORTE DE VERSION "
|
||||
Write-Host "========================================"
|
||||
Write-Host " PROYECTO : $projectName"
|
||||
Write-Host " TAG CREADO : $EstadoTag"
|
||||
Write-Host " PUSH GITHUB: $EstadoPush"
|
||||
Write-Host "========================================"
|
||||
@@ -1,29 +0,0 @@
|
||||
@echo off
|
||||
setlocal EnableDelayedExpansion
|
||||
|
||||
:: Nombre del archivo de salida
|
||||
set "OutputFile=TODOS_LOS_BAS.txt"
|
||||
|
||||
:: Si existe una versión anterior, la elimina para no anexar datos duplicados
|
||||
if exist "!OutputFile!" del "!OutputFile!"
|
||||
|
||||
echo Iniciando proceso de fusion...
|
||||
|
||||
:: Itera sobre todos los archivos .bas en el directorio actual
|
||||
for %%F in (*.bas *.b4a *.b4j) do (
|
||||
echo Procesando: %%F
|
||||
|
||||
:: Agrega un salto de linea y el encabezado al archivo de salida
|
||||
echo. >> "!OutputFile!"
|
||||
echo ====================================== >> "!OutputFile!"
|
||||
echo ARCHIVO: %%F >> "!OutputFile!"
|
||||
echo ====================================== >> "!OutputFile!"
|
||||
echo. >> "!OutputFile!"
|
||||
|
||||
:: Vuelca el contenido del archivo actual al archivo de salida
|
||||
type "%%F" >> "!OutputFile!"
|
||||
)
|
||||
|
||||
echo.
|
||||
echo Proceso terminado. Se ha creado el archivo: !OutputFile!
|
||||
pause
|
||||
@@ -1,81 +1,127 @@
|
||||
# SCRIPT: _juntaBas.ps1 - Versión SYSTEM PROMPT CONDICIONAL + Ultimate (Corregido)
|
||||
$OutputFile="_CODIGO_COMPLETO_PARA_LLM.txt"
|
||||
# SCRIPT: _juntaBas_Master_FinalIA.ps1
|
||||
# FIX: Corregida sintaxis de comillas y concatenación de tags XML.
|
||||
# OBJETIVO: Fuente de verdad para IA con navegación ultra estructurada.
|
||||
|
||||
Remove-Item -Path $OutputFile -ErrorAction SilentlyContinue
|
||||
Write-Host "Generando Código Maestro con Protocolo Condicional..."
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
$Dir = Get-Location
|
||||
$LT = [char]60; $GT = [char]62; $SL = [char]47
|
||||
$NL = [Environment]::NewLine
|
||||
|
||||
$files = Get-ChildItem -Path ".\*" -Include @("*.bas", "*.b4a", "*.j")
|
||||
Write-Output '--- GENERANDO MASTER IA DEFINITIVO (FIX ESTRUCTURAL) ---'
|
||||
|
||||
# --- 0. INYECCIÓN DE INSTRUCCIONES DE SISTEMA (CONDICIONALES) ---
|
||||
# Se han reemplazado paréntesis conflictivos y comillas internas para evitar errores de PowerShell
|
||||
Add-Content -Path $OutputFile -Value "''' ======================================================================================" -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "''' INSTRUCCIONES CRÍTICAS PARA EL ASISTENTE (PROTOCOLO B4A)" -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "''' 1. CONTEXTO: Este archivo contiene el código fuente ACTUAL del proyecto." -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "''' 2. ANTI-ALUCINACION: Antes de sugerir propiedades, VERIFICA si existen" -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "''' en las secciones [Variables Globales] o [Estructuras Types] del Manifiesto abajo." -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "''' 3. DOCUMENTACION EXTERNA (CONDICIONAL):" -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "''' - SI el usuario adjunta archivos de referencia (ej. _B4X_Library... o _B4A_Library...)," -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "''' PRIORIZA esos métodos sobre tu conocimiento general." -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "''' - SI NO se adjuntan referencias, apóyate en el código existente en Subs.bas." -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "''' 4. SCOPE: Respeta la visibilidad (Public/Private)." -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "''' ======================================================================================`n" -Encoding UTF8
|
||||
# 1. PARSEO DEL PROYECTO .B4A
|
||||
$b4a = Get-ChildItem -Path ".\*" -Include "*.b4a" -Recurse | Select-Object -First 1
|
||||
$Name = 'App'; $Ver = '0.0'; $ModulosValidos = @(); $Librerias = @()
|
||||
|
||||
# --- 1. GENERACIÓN DEL MANIFIESTO (TABLA DE CONTENIDO) ---
|
||||
Add-Content -Path $OutputFile -Value "'======================================================================================" -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "' MANIFIESTO DEL PROYECTO - Generado el $(Get-Date -Format 'yyyy-MM-dd HH:mm')" -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "' Total de archivos: $($files.Count)" -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "'======================================================================================" -Encoding UTF8
|
||||
|
||||
foreach ($file in $files) {
|
||||
$content = Get-Content $file.FullName
|
||||
$ext = $file.Extension.ToLower()
|
||||
$lines = $content.Count
|
||||
|
||||
# Extraer (Subs, Globales, Types, Libs)
|
||||
$subs = $content | Where-Object { $_ -match "^\s*Sub\s+" } | ForEach-Object { $_.Trim() -replace "'.*$", "" }
|
||||
$globals = $content | Where-Object { $_ -match "^\s*(Private|Public|Dim)\s+\w+\s+As" } | ForEach-Object { $_.Trim() -replace "'.*$", "" }
|
||||
$types = $content | Where-Object { $_ -match "^\s*Type\s+\w+" } | ForEach-Object { $_.Trim() }
|
||||
|
||||
$libs = @()
|
||||
if ($ext -eq ".b4a") {
|
||||
$libs = $content | Where-Object { $_ -match "^Library\d+=" } | ForEach-Object { $_ -replace "^Library\d+=", "" }
|
||||
if ($b4a) {
|
||||
$lines = [System.IO.File]::ReadAllLines($b4a.FullName)
|
||||
foreach ($L in $lines) {
|
||||
if ($L -match '#ApplicationLabel:\s*(.*)') { $Name = $Matches[1].Trim() }
|
||||
if ($L -match '#VersionName:\s*(.*)') { $Ver = $Matches[1].Trim() }
|
||||
if ($L -match '^Module\d+=(.*)') {
|
||||
$m = [System.IO.Path]::GetFileName($Matches[1].Trim())
|
||||
if (-not $m.EndsWith(".bas") -and $m -ne "Main") { $m += ".bas" }
|
||||
$ModulosValidos += $m
|
||||
}
|
||||
if ($L -match '^Library\d+=(.*)') { $Librerias += $Matches[1].Trim() }
|
||||
}
|
||||
|
||||
# Escribir Manifiesto
|
||||
Add-Content -Path $OutputFile -Value "' [ ] Archivo: $($file.Name) ($lines líneas)" -Encoding UTF8
|
||||
|
||||
if ($libs) {
|
||||
Add-Content -Path $OutputFile -Value "' --- Librerías Activas ---" -Encoding UTF8
|
||||
foreach ($l in $libs) { Add-Content -Path $OutputFile -Value "' [LIB] $l" -Encoding UTF8 }
|
||||
}
|
||||
if ($types) {
|
||||
Add-Content -Path $OutputFile -Value "' --- Estructuras (Types) ---" -Encoding UTF8
|
||||
foreach ($t in $types) { Add-Content -Path $OutputFile -Value "' {TYPE} $t" -Encoding UTF8 }
|
||||
}
|
||||
if ($globals) {
|
||||
Add-Content -Path $OutputFile -Value "' --- Variables Globales ---" -Encoding UTF8
|
||||
foreach ($g in $globals) { Add-Content -Path $OutputFile -Value "' . $g" -Encoding UTF8 }
|
||||
}
|
||||
if ($subs) {
|
||||
Add-Content -Path $OutputFile -Value "' --- Subrutinas ---" -Encoding UTF8
|
||||
foreach ($s in $subs) { Add-Content -Path $OutputFile -Value "' > $s" -Encoding UTF8 }
|
||||
}
|
||||
Add-Content -Path $OutputFile -Value "' ------------------------------------------------------------------------------------" -Encoding UTF8
|
||||
}
|
||||
Add-Content -Path $OutputFile -Value "' FINAL DEL MANIFIESTO`n" -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "'======================================================================================`n" -Encoding UTF8
|
||||
|
||||
# --- 2. VUELCO DE CONTENIDO ---
|
||||
$files | ForEach-Object {
|
||||
$currentFile = $_.Name
|
||||
Write-Host "Procesando: $currentFile"
|
||||
Add-Content -Path $OutputFile -Value "'======================================================================================" -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "// ARCHIVO_INICIO: ${currentFile}" -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "'======================================================================================`n" -Encoding UTF8
|
||||
Get-Content -Encoding UTF8 -Path $_.FullName -Raw | Add-Content -Path $OutputFile -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "`n'======================================================================================" -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "// ARCHIVO_FIN: ${currentFile}" -Encoding UTF8
|
||||
Add-Content -Path $OutputFile -Value "'======================================================================================`n" -Encoding UTF8
|
||||
}
|
||||
|
||||
Write-Host "¡Listo! Archivo $OutputFile con Instrucciones Condicionales generado (Sin Errores)."
|
||||
$OutName = "_" + $Name + "_" + $Ver + "_IA.md"
|
||||
$OutFile = Join-Path $Dir $OutName
|
||||
|
||||
# 2. HEADER CON TUS INSTRUCCIONES CRÍTICAS
|
||||
$CurrentDate = Get-Date -Format 'yyyy-MM-dd HH:mm'
|
||||
$Header = @"
|
||||
# PROYECTO: $Name
|
||||
- Version: $Ver
|
||||
- Fecha: $CurrentDate
|
||||
- Librerias Activas: $($Librerias -join ", ")
|
||||
|
||||
## INSTRUCCIONES CRITICAS (B4A / BASIC4ANDROID)
|
||||
0. **Integridad del Contexto:** Antes de procesar peticiones, cuenta si el numero de modulos listados en el indice coincide con los detallados en el cuerpo.
|
||||
1. **Source of Truth (Codigo):** Este archivo contiene el codigo fuente ACTUAL del proyecto.
|
||||
2. **Source of Truth (Librerias):** Basa tus sugerencias en la lista de 'Librerias Activas'.
|
||||
3. **Anti-Alucinacion:** Antes de sugerir, VERIFICA la 'Interfaz Pública' o el código fuente del módulo.
|
||||
4. **Existencia Estricta:** Si una variable/Sub no está en el texto, NO EXISTE.
|
||||
5. **Formato:** Usa bloques 'vb'.
|
||||
6. **Navegacion Estructural:** Usa los tags <module>, <interface> y <method> para localizar codigo.
|
||||
7. **Inferencia de Datos:** Deduce la BD solo de los strings SQL presentes.
|
||||
"@
|
||||
|
||||
Set-Content -Path $OutFile -Value $Header -Encoding UTF8
|
||||
|
||||
# 3. LISTAR ARCHIVOS
|
||||
$files = Get-ChildItem -Path $Dir -Include *.bas,*.b4a -Recurse | Where-Object {
|
||||
$_.FullName -notmatch 'Objects' -and ($_.Extension -eq '.b4a' -or $ModulosValidos -contains $_.Name)
|
||||
}
|
||||
|
||||
# 4. INDICE DE MODULOS
|
||||
Add-Content $OutFile ($NL + "## INDICE DE MODULOS" + $NL) -Encoding UTF8
|
||||
foreach ($f in $files) {
|
||||
$Ref = $f.Name.Replace('.', '').Replace(' ', '-').ToLower()
|
||||
Add-Content $OutFile ("- [" + $f.Name + "](#modulo-" + $Ref + ")") -Encoding UTF8
|
||||
}
|
||||
|
||||
# 5. CODIGO FUENTE ESTRUCTURADO
|
||||
Add-Content $OutFile ($NL + '## CODIGO FUENTE DETALLADO' + $NL) -Encoding UTF8
|
||||
|
||||
foreach ($f in $files) {
|
||||
Write-Host " -> $($f.Name)... " -NoNewline
|
||||
$txt = [System.IO.File]::ReadAllLines($f.FullName)
|
||||
|
||||
# Pre-escaneo para <interface>
|
||||
$Methods = @()
|
||||
foreach ($line in $txt) {
|
||||
if ($line.Trim() -match '^(?:Public\s+|Private\s+)?Sub\s+([\w\d_]+)') {
|
||||
$Methods += $Matches[1]
|
||||
}
|
||||
}
|
||||
|
||||
$Ref = $f.Name.Replace('.', '').Replace(' ', '-').ToLower()
|
||||
Add-Content $OutFile "$NL<module name='$($f.Name)' id='modulo-$Ref'>" -Encoding UTF8
|
||||
|
||||
Add-Content $OutFile " <interface>" -Encoding UTF8
|
||||
foreach($m in $Methods) {
|
||||
Add-Content $OutFile " <method_ref name='$m' />" -Encoding UTF8
|
||||
}
|
||||
Add-Content $OutFile " </interface>$NL" -Encoding UTF8
|
||||
|
||||
Add-Content $OutFile "```vb" -Encoding UTF8
|
||||
|
||||
$skip = ($f.Extension -eq '.b4a')
|
||||
|
||||
foreach ($l in $txt) {
|
||||
$trim = $l.Trim()
|
||||
|
||||
if ($skip) {
|
||||
if ($trim.StartsWith("#") -and -not $trim.StartsWith("#Region")) { Add-Content $OutFile $l -Encoding UTF8 }
|
||||
if ($l.Contains("@EndOfDesignText@")) { $skip = $false }
|
||||
continue
|
||||
}
|
||||
|
||||
# Inicio de Método
|
||||
if ($trim -match '^(?:Public\s+|Private\s+)?Sub\s+([\w\d_]+)') {
|
||||
Add-Content $OutFile "<method name='$($Matches[1])'>" -Encoding UTF8
|
||||
}
|
||||
|
||||
# Limpieza de comentarios y escritura de línea
|
||||
if ($trim.StartsWith("'")) {
|
||||
if (-not ($trim.StartsWith("'#") -or ($trim -match 'TODO:') -or ($trim -match 'FIX:'))) { continue }
|
||||
}
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($trim)) {
|
||||
Add-Content $OutFile $l -Encoding UTF8
|
||||
}
|
||||
|
||||
# Fin de Método
|
||||
if ($trim -eq "End Sub") {
|
||||
Add-Content $OutFile "</method>" -Encoding UTF8
|
||||
}
|
||||
}
|
||||
|
||||
Add-Content $OutFile "```$NL</module>" -Encoding UTF8
|
||||
Write-Host "OK" -ForegroundColor Green
|
||||
}
|
||||
|
||||
Write-Output ("--- FINALIZADO: " + $OutName + " ---")
|
||||
@@ -1,166 +0,0 @@
|
||||
B4A=true
|
||||
Group=Default Group
|
||||
ModulesStructureVersion=1
|
||||
Type=Class
|
||||
Version=12.8
|
||||
@EndOfDesignText@
|
||||
'Class module: jRDC1Wrapper
|
||||
'Version 1.3 - Thread-Safe with ExecuteCommand support
|
||||
|
||||
Public Sub Class_Globals
|
||||
' Public properties to be accessed after the wait for completes
|
||||
Type TResultado(Tag As String, Success As Boolean, resultado As DBResult, ErrorMessage As String)
|
||||
' Type TCommandResult(Tag As String, Success As Boolean, RowsAffected As Int, ErrorMessage As String)
|
||||
|
||||
'C <<< Definimos un tipo para almacenar la información de cada job
|
||||
Type TJobInfo (Target As Object, EventName As String, IsQuery As Boolean)
|
||||
|
||||
'C <<< Un mapa para mantener un registro de los jobs activos
|
||||
Private activeJobs As Map
|
||||
|
||||
'C <<< Un contador para generar tags únicos para cada job
|
||||
Private jobCounter As Int
|
||||
|
||||
Public reqManager As DBRequestManager
|
||||
Public cmd As DBCommand
|
||||
Public resultado As TResultado
|
||||
' Public commandResult As TCommandResult
|
||||
Private logger As Boolean = False
|
||||
End Sub
|
||||
|
||||
'Initializes the object.
|
||||
Public Sub Initialize
|
||||
'C <<< Inicializamos el mapa y el contador
|
||||
activeJobs.Initialize
|
||||
jobCounter = 0
|
||||
End Sub
|
||||
|
||||
'Executes the query using the old jRDC1 mechanism.
|
||||
'Parameters:
|
||||
' - rdcLink: The link for the reqManager initialization.
|
||||
' - Command: The DBCommand to execute.
|
||||
' - Target: The module (like 'Me') where the completed event should be raised.
|
||||
' - Event: The name of the event to raise when the query completes (e.g., "WrapperEvent").
|
||||
Public Sub ExecuteQuery(rdcLink As String, Command As DBCommand, Target As Object, Event As String)
|
||||
'<<< Incrementamos el contador para obtener un ID único
|
||||
jobCounter = jobCounter + 1
|
||||
Dim currentJobTag As String = "jRDCWrapJob_" & jobCounter
|
||||
|
||||
If logger Then Log($"ExecuteQuery (Tag: ${currentJobTag}): Command=${Command.Name}, Event=${Event}"$)
|
||||
|
||||
'<<< Creamos una instancia de TJobInfo para guardar el target y el evento
|
||||
Dim jobInfo As TJobInfo
|
||||
jobInfo.Initialize
|
||||
jobInfo.Target = Target
|
||||
jobInfo.EventName = Event
|
||||
jobInfo.IsQuery = True ' Mark as query job
|
||||
|
||||
'<<< Guardamos la información del job en el mapa, usando el tag único como llave
|
||||
activeJobs.Put(currentJobTag, jobInfo)
|
||||
|
||||
reqManager.Initialize(Me, rdcLink)
|
||||
cmd = Command
|
||||
|
||||
'<<< Ejecutamos la consulta pasando nuestro TAG ÚNICO
|
||||
reqManager.ExecuteQuery(cmd, 0, currentJobTag)
|
||||
End Sub
|
||||
|
||||
'Executes a command (INSERT, UPDATE, DELETE) using the old jRDC1 mechanism.
|
||||
'Parameters:
|
||||
' - rdcLink: The link for the reqManager initialization.
|
||||
' - Command: The DBCommand to execute.
|
||||
' - Target: The module (like 'Me') where the completed event should be raised.
|
||||
' - Event: The name of the event to raise when the command completes (e.g., "WrapperEvent").
|
||||
Public Sub ExecuteCommand(rdcLink As String, Command As DBCommand, Target As Object, Event As String)
|
||||
'<<< Incrementamos el contador para obtener un ID único
|
||||
jobCounter = jobCounter + 1
|
||||
Dim currentJobTag As String = "jRDCWrapJob_" & jobCounter
|
||||
|
||||
if logger then Log($"ExecuteCommand (Tag: ${currentJobTag}): Command=${Command.Name}, Event=${Event}"$)
|
||||
|
||||
'<<< Creamos una instancia de TJobInfo para guardar el target y el evento
|
||||
Dim jobInfo As TJobInfo
|
||||
jobInfo.Initialize
|
||||
jobInfo.Target = Target
|
||||
jobInfo.EventName = Event
|
||||
jobInfo.IsQuery = False ' Mark as command job
|
||||
|
||||
'<<< Guardamos la información del job en el mapa, usando el tag único como llave
|
||||
activeJobs.Put(currentJobTag, jobInfo)
|
||||
|
||||
reqManager.Initialize(Me, rdcLink)
|
||||
cmd = Command
|
||||
|
||||
'<<< Ejecutamos el comando pasando nuestro TAG ÚNICO
|
||||
reqManager.ExecuteCommand(cmd, currentJobTag)
|
||||
End Sub
|
||||
|
||||
'This sub will be called by the DBRequestManager when the job is done
|
||||
Public Sub JobDone(job As HttpJob)
|
||||
'<<< Obtenemos el Tag único que asignamos al job
|
||||
Dim currentJobTag As String = job.Tag
|
||||
|
||||
'C <<< Verificamos si este job fue iniciado por nuestro wrapper
|
||||
If activeJobs.ContainsKey(currentJobTag) = False Then
|
||||
If logger Then Log($"JobDone: Se recibió un job con un tag desconocido: ${currentJobTag}"$)
|
||||
job.Release
|
||||
Return
|
||||
End If
|
||||
|
||||
'<<< Recuperamos la información específica de este job desde el mapa
|
||||
Dim jobInfo As TJobInfo = activeJobs.Get(currentJobTag)
|
||||
Try
|
||||
If jobInfo.IsQuery Then
|
||||
' Handle query result
|
||||
resultado.Initialize
|
||||
resultado.Tag = jobInfo.EventName ' Usamos el nombre del evento original como Tag del resultado
|
||||
|
||||
If job.Success Then
|
||||
Dim dbResult As DBResult = reqManager.HandleJob(job)
|
||||
resultado.Success = True
|
||||
resultado.Resultado = dbResult
|
||||
resultado.ErrorMessage = ""
|
||||
Else
|
||||
resultado.Success = False
|
||||
resultado.Resultado = Null
|
||||
resultado.ErrorMessage = job.ErrorMessage
|
||||
End If
|
||||
job.Release
|
||||
|
||||
'<<< Usamos la información recuperada del mapa para llamar al Sub correcto
|
||||
if logger then LogColor($"EVENTO: ${jobInfo.EventName}_Completed"$, Colors.Magenta)
|
||||
CallSubDelayed2(jobInfo.Target, jobInfo.EventName & "_Completed", resultado)
|
||||
Else
|
||||
' Handle command result
|
||||
resultado.Initialize
|
||||
resultado.Tag = jobInfo.EventName
|
||||
|
||||
If job.Success Then
|
||||
Dim dbResult As DBResult = reqManager.HandleJob(job)
|
||||
' Dim rowsAffected As Int = reqManager.HandleCommandResult(job)
|
||||
' For Each records() As Object In dbResult.Rows
|
||||
' Dim rowsAffected As Int = records(dbResult.Columns.Get("AffectedRows"))
|
||||
' Next
|
||||
resultado.Success = True
|
||||
resultado.resultado = dbResult
|
||||
resultado.ErrorMessage = ""
|
||||
Else
|
||||
resultado.Success = False
|
||||
resultado.resultado = Null
|
||||
resultado.ErrorMessage = job.ErrorMessage
|
||||
End If
|
||||
job.Release
|
||||
|
||||
'<<< Usamos la información recuperada del mapa para llamar al Sub correcto
|
||||
If logger Then LogColor($"EVENTO: ${jobInfo.EventName}_Completed"$, Colors.Magenta)
|
||||
CallSubDelayed2(jobInfo.Target, jobInfo.EventName & "_Completed", resultado)
|
||||
End If
|
||||
|
||||
'C <<< Se remueve el job del mapa en caso de ÉXITO
|
||||
activeJobs.Remove(currentJobTag)
|
||||
Catch
|
||||
if logger then LogColor("Error en jRDC1Wrapper.JobDone: " & LastException, Colors.Red)
|
||||
'<<< MUY IMPORTANTE: Remover el job del mapa para no tener fugas de memoria
|
||||
activeJobs.Remove(currentJobTag)
|
||||
End Try
|
||||
End Sub
|
||||
Reference in New Issue
Block a user