mirror of
https://github.com/KeymonSoft/Kelloggs_v4.git
synced 2026-04-18 02:29:13 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 048deef8c1 | |||
| b0b10b22a6 | |||
| 44d97b4845 | |||
| f5fe4c4a52 | |||
| 60aa115e24 | |||
| eaa185bb6d | |||
| 10a2c84997 | |||
| af1f4b9ead |
@@ -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=..\..\
|
||||
'###########################################################################################################
|
||||
@@ -124,6 +127,7 @@ Sub Class_Globals
|
||||
Private Label4 As Label
|
||||
Private clicked As Int = 0
|
||||
Dim linker As C_deviceLinker
|
||||
Dim aud As C_Auditoria
|
||||
End Sub
|
||||
|
||||
Public Sub Initialize
|
||||
@@ -195,6 +199,7 @@ Private Sub B4XPage_Created (Root1 As B4XView)
|
||||
kh.agregaColumna(Starter.skmt, "PEDIDO", "PE_ARCH", "TEXT")
|
||||
kh.agregaColumna(Starter.skmt, "PEDIDO_CLIENTE", "PC_ARCH", "TEXT")
|
||||
kh.agregaColumna(Starter.skmt, "PEDIDO3", "PE_ARCH", "TEXT")
|
||||
aud.Initialize(Starter.skmt)
|
||||
Root = Root1
|
||||
' Root.LoadLayout("MainPage")
|
||||
Root.LoadLayout("login")
|
||||
@@ -412,6 +417,7 @@ End Sub
|
||||
|
||||
Sub B4XPage_Appear
|
||||
Log(">>>>>> APPEAR - INICIAMOS MAIN PAGE <<<<<<<<<")
|
||||
aud.guarda($"Entrada a Login"$)
|
||||
linker.Initialize(Me, "Linker", True)
|
||||
clicked = 0
|
||||
If Not(MES1.IsInitialized) Then MES1.Initialize(Me, "MES1")
|
||||
@@ -542,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
|
||||
@@ -743,6 +749,8 @@ Private Sub i_engranes_LongClick
|
||||
Dim reqManagerW As DBRequestManagerW
|
||||
reqManagerW.Initialize
|
||||
cmd.Initialize
|
||||
|
||||
Dim a As Int = "abc"
|
||||
|
||||
cmd.Name = "select_usuario_guna_KELL"
|
||||
cmd.Parameters = Array As Object(user.Text, pass.Text)
|
||||
@@ -968,8 +976,6 @@ Private Sub cb_cartaPorte_CheckedChange(Checked As Boolean)
|
||||
Starter.skmt.ExecNonQuery($"insert into CAT_VARIABLES (CAT_VA_DESCRIPCION, CAT_VA_VALOR) values ('CARTAPORTE', '${Checked}')"$)
|
||||
End Sub
|
||||
|
||||
|
||||
|
||||
private Sub l_geocerca_Click
|
||||
If cb_geocerca.Enabled = False Then ToastMessageShow("Ingrese la contraseña para modificar", True)
|
||||
End Sub
|
||||
|
||||
84
B4A/C_Auditoria.bas
Normal file
84
B4A/C_Auditoria.bas
Normal file
@@ -0,0 +1,84 @@
|
||||
B4A=true
|
||||
Group=Default Group
|
||||
ModulesStructureVersion=1
|
||||
Type=Class
|
||||
Version=12.8
|
||||
@EndOfDesignText@
|
||||
Sub Class_Globals
|
||||
Dim audb As SQL
|
||||
Dim ruta As String = File.DirInternal
|
||||
End Sub
|
||||
|
||||
'You can add more parameters here.
|
||||
Public Sub Initialize(db As SQL) As Object
|
||||
If Not(audb.IsInitialized) Then audb.Initialize(ruta,"kmt.db", True)
|
||||
audb = db
|
||||
audb.ExecNonQuery("CREATE TABLE IF NOT EXISTS auditoria(almacen text, ruta text, usuario text, cliente text, evento text, fecha text, lat text, lon text)")
|
||||
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.
|
||||
|
||||
Sub guarda(evento As String)
|
||||
DateTime.DateFormat = "yyyy-MM-dd HH:mm:ss"
|
||||
audb.ExecNonQuery2("insert into auditoria (almacen, ruta, usuario, cliente, evento, fecha, lat, lon) values (?, ?, ?, ?, ?, ?, ?, ?)", Array As String(traeAlmacen, traeRuta, traeUsuarioDeBD, traeCliente, evento, DateTime.Date(DateTime.Now)))
|
||||
End Sub
|
||||
|
||||
'Regresa el almacen actual de la base de datos.
|
||||
Sub traeAlmacen As String 'ignore
|
||||
Private c As Cursor
|
||||
Private a As String = ""
|
||||
c = audb.ExecQuery("select ID_ALMACEN from CAT_ALMACEN")
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
a = C.GetString("ID_ALMACEN")
|
||||
End If
|
||||
c.Close
|
||||
Return a
|
||||
End Sub
|
||||
|
||||
'Regresa la ruta actual de la base de datos.
|
||||
Sub traeRuta As String 'ignore
|
||||
Private c As Cursor
|
||||
Private r As String
|
||||
c = audb.ExecQuery("select CAT_CL_RUTA from kmt_info limit 1")
|
||||
r = "0"
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
r = c.GetString("CAT_CL_RUTA")
|
||||
End If
|
||||
c.Close
|
||||
Return r
|
||||
End Sub
|
||||
|
||||
'Regresa el usuario de la tabla USUARIOA
|
||||
Sub traeUsuarioDeBD As String 'ignore
|
||||
Private c As Cursor
|
||||
Private u As String = "SinUsuario"
|
||||
c = audb.ExecQuery("select USUARIO from usuarioa")
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
u = c.GetString("USUARIO")
|
||||
End If
|
||||
c.Close
|
||||
Return u
|
||||
End Sub
|
||||
|
||||
'Trae el cliente de CUENTAA
|
||||
Sub traeCliente As String 'ignore
|
||||
Private c As Cursor
|
||||
Private cl As String = ""
|
||||
c = audb.ExecQuery("Select CUENTA from cuentaa")
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
cl = c.GetString("CUENTA")
|
||||
End If
|
||||
c.Close
|
||||
Return cl
|
||||
End Sub
|
||||
@@ -409,6 +409,7 @@ End Sub
|
||||
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
|
||||
|
||||
Sub B4XPage_Appear
|
||||
B4XPages.MainPage.aud.guarda($"Entrada a Cliente"$)
|
||||
indicePregunta = 0
|
||||
b_noVenta.Enabled = False
|
||||
Log("NoVenta False")
|
||||
@@ -795,8 +796,8 @@ Sub B4XPage_Appear
|
||||
Log(">>>> GUARDAMOS PROMOXMONTO PRODS")
|
||||
Subs.guardaProductoSinGestion(mPromoXMonto.Get("id"), dp.GetString("CAT_DP_PRECIO"), dp.GetString("CAT_DP_PZAS"), Subs.traeProdNombre(dp.GetString("CAT_DP_IDPROD")), dp.GetString("CAT_DP_IDPROD"), Subs.traeCliente, Subs.traeFecha, Subs.traeUsuarioDeBD, Subs.traeRuta, 0, Starter.tipov)
|
||||
' Traemos el monto de las bonificacionos a guardar. -- Trade Spending
|
||||
Log("Monto Bonificacion -->> " & B4XPages.MainPage.promos.ts.traeMontoBonificacion(dp.GetString("CAT_DP_IDPROD"), dp.GetString("CAT_DP_PRECIO"), mPromoXMonto.Get("id")))
|
||||
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (B4XPages.MainPage.promos.ts.traeMontoBonificacion(dp.GetString("CAT_DP_IDPROD"), dp.GetString("CAT_DP_PRECIO"), mPromoXMonto.Get("id")) * dp.GetString("CAT_DP_PZAS"))
|
||||
Log("Monto Bonificacion -->> " & B4XPages.MainPage.promos.ts.traeMontoBonificacion(dp.GetString("CAT_DP_IDPROD"), dp.GetString("CAT_DP_PRECIO"), mPromoXMonto.Get("id"),"LOG_APPEAR1"))
|
||||
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (B4XPages.MainPage.promos.ts.traeMontoBonificacion(dp.GetString("CAT_DP_IDPROD"), dp.GetString("CAT_DP_PRECIO"), mPromoXMonto.Get("id"), "APPEAR2") * dp.GetString("CAT_DP_PZAS"))
|
||||
End If
|
||||
Next
|
||||
B4XPages.MainPage.promos.ts.modTrendSpending("RESTA", "BONIFICACIONES", elMontoTSDeLaVenta)
|
||||
@@ -1020,6 +1021,7 @@ Sub DATOS_Click
|
||||
End Sub
|
||||
|
||||
Sub Guardar_Click
|
||||
B4XPages.MainPage.aud.guarda($"Guarda Venta Cliente"$)
|
||||
DateTime.DateFormat = "MM/dd/yyyy"
|
||||
sDate=DateTime.Date(DateTime.Now)
|
||||
sTime=DateTime.Time(DateTime.Now)
|
||||
@@ -1082,7 +1084,7 @@ Sub Guardar_Click
|
||||
b_inicioFinVenta.Text = "TERMINAR VENTA"
|
||||
Log("RESPALDO")
|
||||
kh.RD_respaldoBatch
|
||||
|
||||
|
||||
' Subir_Pedido_Con_Integridad(clie_id)
|
||||
|
||||
mandaPendientes
|
||||
@@ -1218,7 +1220,7 @@ Sub B_IMP_Click
|
||||
a_VENTA_F = 0
|
||||
End If
|
||||
C4.Close
|
||||
|
||||
|
||||
C4=Starter.skmt.ExecQuery2("select count(*) as CUANTOS from pedido where substr(pe_pronombre,1,6) = ? AND PE_PROID = ? ", Array As String("CAMBIO", s.GetString("CAT_GP_ID")))
|
||||
C4.Position=0
|
||||
If C4.GetString("CUANTOS") > 0 Then
|
||||
@@ -3290,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.
|
||||
@@ -3585,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)
|
||||
|
||||
@@ -3594,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")
|
||||
@@ -3793,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
|
||||
@@ -3835,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)
|
||||
@@ -4478,8 +4481,8 @@ Private Sub b_notificacion_Click
|
||||
Log("-" & tag & "-")
|
||||
Private tag1() As String = Regex.Split("\|", tag)
|
||||
Log(tag1.Length & "-" & tag1(0) & "-" & tag1(1))
|
||||
Private CODIGO As String = tag1(0)
|
||||
Private ID As String = tag1(1)
|
||||
Private CODIGO As String = tag1(1)
|
||||
Private ID As String = tag1(0)
|
||||
p_transparenciaNoti.Visible = False
|
||||
DateTime.DateFormat = "yyyy-MM-dd HH:mm:ss"
|
||||
Starter.skmt.ExecNonQuery($"insert into HIST_NOTIFICACIONES (HN_CODIGO, HN_ID, HN_FECHA) values ('${CODIGO}', '${ID}', '${DateTime.Date(DateTime.Now)}')"$)
|
||||
@@ -4494,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)
|
||||
@@ -4562,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
|
||||
|
||||
@@ -50,6 +50,7 @@ End Sub
|
||||
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
|
||||
|
||||
Sub B4XPage_Appear
|
||||
B4XPages.MainPage.aud.guarda("Entrada a Historico")
|
||||
L_CANT.Text =""
|
||||
L_TOTAL.Text=""
|
||||
c=Starter.skmt.ExecQuery("select count(*) as EXISTE from HIST_VENTAS WHERE HVD_CLIENTE IN (Select CUENTA from cuentaa)")
|
||||
|
||||
@@ -54,6 +54,7 @@ End Sub
|
||||
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
|
||||
|
||||
Sub B4XPage_Appear
|
||||
B4XPages.MainPage.aud.guarda("Entrada a Mapas")
|
||||
GPS.Initialize("GPS")
|
||||
Log(1)
|
||||
rp.CheckAndRequest(rp.PERMISSION_ACCESS_FINE_LOCATION)
|
||||
|
||||
@@ -46,6 +46,7 @@ End Sub
|
||||
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
|
||||
|
||||
Sub B4XPage_Appear
|
||||
B4XPages.MainPage.aud.guarda("Entrada a No Venta")
|
||||
e_comm.Text=""
|
||||
lat_gps = 0
|
||||
lon_gps = 0
|
||||
@@ -86,6 +87,7 @@ Sub GUARDA_Click
|
||||
Else
|
||||
motivo = "NO ESTA EL ENCARGADO"
|
||||
End If
|
||||
B4XPages.MainPage.aud.guarda($"Guarda No Venta: ${motivo}"$)
|
||||
usuario = Subs.traeUsuarioDeBD
|
||||
If B4XPages.MainPage.cliente.IsInitialized Then
|
||||
B4XPages.MainPage.cliente.motivoNoVenta = motivo
|
||||
|
||||
@@ -99,6 +99,7 @@ End Sub
|
||||
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
|
||||
|
||||
Sub B4XPage_Appear
|
||||
B4XPages.MainPage.aud.guarda("Entrada a Nota")
|
||||
If kh.clienteConDOE And l_tipoPedido.IsInitialized Then
|
||||
l_tipoPedido.Visible = True
|
||||
Else
|
||||
@@ -265,6 +266,7 @@ Sub borra_Click
|
||||
If folio = "0" Or 1 = 1 Then 'Si el folio es 0 o el cliente actual es "abordo", los deja borrar. - Mod por CHV 220512 'Para que el abordo borre siempre agregar -> " Or Subs.clienteActual = "0""
|
||||
result = Msgbox2($"¿Seguro que desea borrar el pedido${textoExtra}?"$,"Cancelar pedido", "Si", "", "No", LoadBitmap(File.DirAssets,"alert2.png")) 'ignore
|
||||
If result = DialogResponse.POSITIVE Then
|
||||
B4XPages.MainPage.aud.guarda($"Borrar Nota Ok"$)
|
||||
' c = Starter.skmt.ExecQuery("select PE_PROID, PE_CANT, PE_TIPO, PE_CEDIS FROM PEDIDO where pe_cliente in (Select CUENTA from cuentaa) ")
|
||||
' If c.RowCount>0 Then
|
||||
' For i=0 To c.RowCount -1
|
||||
|
||||
@@ -51,6 +51,7 @@ End Sub
|
||||
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
|
||||
|
||||
Sub B4XPage_Appear
|
||||
B4XPages.MainPage.aud.guarda("Entrada a NuevoCliente")
|
||||
b_guardar.Visible = False
|
||||
b_guardar.Enabled = False
|
||||
permitirCtesNuevos = True
|
||||
|
||||
@@ -309,6 +309,10 @@ Private Sub B4XPage_Created (Root1 As B4XView)
|
||||
kh.centraPanel(Panel2, Root.Width)
|
||||
kh.centraPanel(Panel1, Root.Width)
|
||||
kh.centraPanel(p_botonesResumen, Root.Width)
|
||||
p_transparente.Top = 0 : p_transparente.left = 0
|
||||
p_transparente.Height = Root.Height : p_transparente.Width = Root.Width
|
||||
' PNL_ACCESO.Top = 0 : PNL_ACCESO.left = 0
|
||||
' PNL_ACCESO.Height = Root.Height : PNL_ACCESO.Width = Root.Width
|
||||
' kh.centraPanel(Panel7, Root.Width)
|
||||
' kh.centraPanel(PNL_ACCESO, Root.Width)
|
||||
|
||||
@@ -324,6 +328,7 @@ End Sub
|
||||
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
|
||||
|
||||
Sub B4XPage_Appear
|
||||
B4XPages.MainPage.aud.guarda("Entrada a Principal")
|
||||
' Log(Subs.traeDiaSemana)
|
||||
linker.Initialize(Me, "Linker", True)
|
||||
Starter.errorConnDBReq = False
|
||||
@@ -564,7 +569,7 @@ Sub B4XPage_Appear
|
||||
NUEVO.Enabled = True
|
||||
B_PROXIMA.Enabled = True
|
||||
End If
|
||||
|
||||
|
||||
'############# Deshabilitamos botones para validacion de ruta y vinculo #########
|
||||
c = Starter.skmt.ExecQuery("select count(*) as cuantos from CAT_VARIABLES WHERE CAT_VA_DESCRIPCION = 'LIGADO' and CAT_VA_VALOR = 1")
|
||||
c.Position = 0
|
||||
@@ -638,6 +643,7 @@ Sub Subir_Click
|
||||
Next
|
||||
End If
|
||||
Sleep(1000)
|
||||
Starter.revisandoNotifiaciones = False
|
||||
|
||||
CARGA = "SUBIR"
|
||||
' P1.Visible = True
|
||||
@@ -1444,7 +1450,6 @@ Sub JobDone(Job As HttpJob)
|
||||
'CAT_GP_INICIATIVA = 5
|
||||
' skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD(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_DEV) 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_DEV))
|
||||
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD(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_INICIATIVA,CAT_GP_DEV,CAT_GP_CODPROMO,CAT_GP_TIPOPROD2,CAT_GP_PROMOCION) 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, CAT_GP_INICIATIVA,CAT_GP_DEV, CAT_GP_TIPOPROD2,CAT_GP_PROMOCION))
|
||||
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_INVENTARIO(CI_IDPROD,CI_INVENTARIO) VALUES (?,?)", Array As Object (CAT_GP_ID,CAT_GP_ALMACEN))
|
||||
Next
|
||||
Starter.skmt.TransactionSuccessful
|
||||
Starter.skmt.EndTransaction
|
||||
@@ -1498,6 +1503,7 @@ Sub JobDone(Job As HttpJob)
|
||||
' skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD(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_DEV) 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_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_INICIATIVA,CAT_GP_DEV,CAT_GP_CODPROMO,CAT_GP_TIPOPROD2) 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, CAT_GP_INICIATIVA,CAT_GP_DEV,CAT_GP_CODPROMO,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_INVENTARIO(CI_IDPROD,CI_INVENTARIO) VALUES (?,?)", Array As Object (CAT_GP_ID,CAT_GP_ALMACEN))
|
||||
Next
|
||||
Starter.skmt.TransactionSuccessful
|
||||
Starter.skmt.EndTransaction
|
||||
@@ -1544,7 +1550,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
|
||||
@@ -1589,7 +1595,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
|
||||
@@ -2284,9 +2290,9 @@ Sub JobDone(Job As HttpJob)
|
||||
LogColor(reqManager.reqsList, Colors.blue)
|
||||
LogColor(reqManager.reqsList.Size, Colors.blue)
|
||||
If CARGA = "SUBIR" Then actualizaProgressBar
|
||||
|
||||
|
||||
'Si ya se procesaron TODAS las peticiones, entonces realizamos validaciones.
|
||||
If reqManager.reqsList.Size = 0 Then
|
||||
If reqManager.reqsList.Size = 0 And Not(Starter.revisandoNotifiaciones) Then
|
||||
If CARGA = "SUBIR" Then revisaHistNotificaciones
|
||||
End If
|
||||
End If
|
||||
@@ -2309,14 +2315,15 @@ Sub JobDone(Job As HttpJob)
|
||||
End Sub
|
||||
|
||||
'Envia el historial de notificaciones despues de haberlas borrado para que no se dupliquen.
|
||||
Sub enviaHistNotificaciones
|
||||
Private hn As Cursor = Starter.skmt.ExecQuery($"select * from hist_notificaciones"$)
|
||||
Sub enviaHistNotificaciones(id As String, codigo As String)
|
||||
Private hn As Cursor = Starter.skmt.ExecQuery($"select * from hist_notificaciones where HN_CODIGO = '${codigo}' and HN_ID = '${id}'"$)
|
||||
If hn.RowCount > 0 Then
|
||||
For i = 0 To hn.RowCount - 1
|
||||
hn.Position = i
|
||||
cmd.Initialize
|
||||
cmd.Name = "insertHistNotificaciones"
|
||||
cmd.Parameters = Array As Object( hn.GetString("HN_CODIGO"), hn.GetString("HN_ID"), hn.GetString("HN_FECHA"))
|
||||
cmd.Parameters = Array As Object(hn.GetString("HN_ID"), hn.GetString("HN_CODIGO"), hn.GetString("HN_FECHA"))
|
||||
Log($"Enviamos notificacion: id: ${hn.GetString("HN_ID")}, codigo: ${hn.GetString("HN_CODIGO")}, fecha: ${hn.GetString("HN_FECHA")}"$)
|
||||
reqManager.ExecuteCommand(cmd , "insertHistNotificaciones")
|
||||
Next
|
||||
hn.Close
|
||||
@@ -2326,7 +2333,9 @@ End Sub
|
||||
' Revisa que en web haya el numero correcto de notificaciones en el historial
|
||||
Sub revisaHistNotificaciones
|
||||
LogColor("####################### REVISA NOTIS ########", Colors.red)
|
||||
Private cn As Cursor = Starter.skmt.ExecQuery("select count(HN_CODIGO) as cuantos, HN_CODIGO, HN_ID from HIST_NOTIFICACIONES")
|
||||
Starter.revisandoNotifiaciones = True
|
||||
' Private cn As Cursor = Starter.skmt.ExecQuery("select count(HN_CODIGO) as cuantos, HN_CODIGO, HN_ID from HIST_NOTIFICACIONES")
|
||||
Private cn As Cursor = Starter.skmt.ExecQuery($"SELECT HN_ID, HN_CODIGO, HN_FECHA, COUNT(*) As cuantos FROM HIST_NOTIFICACIONES GROUP BY HN_ID"$)
|
||||
If cn.RowCount > 0 Then
|
||||
cn.Position = 0
|
||||
Private CuantasN As Int = cn.GetInt("cuantos")
|
||||
@@ -2339,14 +2348,15 @@ Sub revisaHistNotificaciones
|
||||
Subs.logJobDoneResultados(r.resultado)
|
||||
For Each records() As Object In r.resultado.Rows
|
||||
Dim CuantasN As Int = records(r.resultado.Columns.Get("CUANTOS"))
|
||||
LogColor($"####################### id: ${cn.GetString("HN_ID")}, codigo: ${cn.GetString("HN_CODIGO")}, Cuantas: ${CuantasN} ########"$, Colors.red)
|
||||
If cn.GetInt("cuantos") > CuantasN Then
|
||||
enviaHistNotificaciones
|
||||
enviaHistNotificaciones(cn.GetString("HN_ID"), cn.GetString("HN_CODIGO"))
|
||||
Log($"enviaHistNotificaciones(${cn.GetString("HN_ID")}, ${cn.GetString("HN_CODIGO")})"$)
|
||||
End If
|
||||
Next
|
||||
Else
|
||||
Log(r.ErrorMessage)
|
||||
End If
|
||||
|
||||
End If
|
||||
End Sub
|
||||
|
||||
@@ -2521,6 +2531,7 @@ Private Sub connecta_LongClick
|
||||
'' End If
|
||||
' Log("MANDAMOS BITACORA")
|
||||
If e_ruta.Text = "KMTKLL1" Then Subs.deshabilitaValidaciones
|
||||
' B4XPages.MainPage.recordatorio.agregaPanelRecordatorio(Root)
|
||||
End Sub
|
||||
|
||||
Sub BUSCA_Click
|
||||
@@ -2572,6 +2583,8 @@ Sub e_ruta_EnterPressed
|
||||
Starter.skmt.ExecNonQuery("delete from TREND_SPENDING")
|
||||
Starter.skmt.ExecNonQuery("delete from HIST_TREND_SPENDING_SEMANAL")
|
||||
Starter.skmt.ExecNonQuery("delete from VERSIONES")
|
||||
Starter.skmt.ExecNonQuery("delete from auditoria")
|
||||
Starter.skmt.ExecNonQuery("delete from HIST_NOTIFICACIONES")
|
||||
|
||||
Starter.skmt.ExecNonQuery2("INSERT INTO HIST_ENVIOS VALUES (?,0,?)", Array As Object(sTime, "PEDIDO"))
|
||||
Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("NUMERO_PEDIDO"))
|
||||
@@ -2824,6 +2837,7 @@ Sub B_OK_RES_Click
|
||||
End Sub
|
||||
|
||||
Sub Resumen_Click
|
||||
B4XPages.MainPage.aud.guarda("Entrada a resumenDia")
|
||||
Log("###############")
|
||||
L_ABORDO.Text = "0"
|
||||
P_RESUMEN.Visible = True
|
||||
@@ -3440,8 +3454,8 @@ Sub SUBIR_INFO_PEDIDO
|
||||
PB2.Progress = PB2.Progress + 1
|
||||
contador_env = contador_env + 1
|
||||
Next
|
||||
c.Close
|
||||
End If
|
||||
c.Close
|
||||
d.Position=0
|
||||
cuantos_noventa = D.GetString("CUANTOS_NOVENTA")
|
||||
PB2.Progress = 100
|
||||
@@ -3513,7 +3527,393 @@ 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. Valida contra el servidor si el pedido es modificable (no liquidado/arqueado).
|
||||
' 4. Empaqueta todo en una lista de comandos (Batch) para enviarlo al servidor en una sola transacción.
|
||||
Sub enviaPedidoBatch(filtro As String)
|
||||
' Preparamos una variable para filtrar la consulta a la base de datos local.
|
||||
' 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"
|
||||
If filtro <> "Todos" Then
|
||||
condicion = "WHERE PC_ENVIADO = 0 OR PC_CLIENTE IN (SELECT PE_CLIENTE FROM PEDIDO WHERE PE_ENVIADO = 0)" ' Si se actualizo un producto, hay que volver a enviar todo el pedido.
|
||||
End If
|
||||
|
||||
' 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 local 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 locales 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")
|
||||
|
||||
' 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)
|
||||
|
||||
' Revisamos si nuestro cursor 'cx' (los encabezados de pedido) trajo algún resultado.
|
||||
If cx.RowCount > 0 Then ' Si hay pedido entonces comenzamos el proceso de envío.
|
||||
' Iniciamos un bucle (For) para recorrer cada uno de los encabezados de pedido encontrados localmente.
|
||||
For j = 0 To cx.RowCount - 1
|
||||
|
||||
' =========================================================================================
|
||||
' BLOQUE DE VALIDACIÓN REMOTA: Revisar si el pedido ya está liquidado o el arqueo cerrado
|
||||
' =========================================================================================
|
||||
' sql.revisaArqueoYLiquidacion_Kelloggs = select NVL(HVD_ESTATUS, 'NO') as liquidado, HVD_DTECIERRE, (select hist_ca_fecha from KELLOGGS.hist_cierre_arqueo where hist_ca_idalmacen = (?) and hist_ca_ruta = (?) and trunc(sysdate) = trunc(hist_ca_fecha)) as arqueo from KELLOGGS.HIST_VENTAS_DETALLE where HVD_ALMACEN = (?) and HVD_RUTA = (?) and trunc(sysdate) = trunc(HVD_FECHA) and HVD_TIPOVENTA = 'VENTA' and rownum <= 1
|
||||
|
||||
' 1. Preparamos el comando para consultar el estatus directamente en la base de datos del servidor.
|
||||
cmd.Initialize
|
||||
cmd.Name = "revisaArqueoYLiquidacion_Kelloggs"
|
||||
Private ruta_ As String = Subs.traeRuta
|
||||
cmd.Parameters = Array As Object(ALMACEN, ruta_, ALMACEN, ruta_)
|
||||
|
||||
' 2. Disparamos la consulta al servidor de forma asíncrona usando reqManagerW.
|
||||
reqManagerW.ExecuteQuery(Starter.DBReqServer, cmd, Me, "revisaPedidoLiquidado")
|
||||
|
||||
' 3. Pausamos la ejecución de este bloque local hasta que el servidor nos responda.
|
||||
Wait For revisaPedidoLiquidado_Completed (rpd As TResultado)
|
||||
|
||||
' 4. Evaluamos la respuesta del servidor.
|
||||
If rpd.Success Then
|
||||
Log("SUCCESS - revisaPedidoLiquidado")
|
||||
|
||||
' Inicializamos variables asumiendo que el pedido NO está liquidado y NO hay arqueo.
|
||||
Dim liquidado As String = "NO"
|
||||
Dim arqueo As String = "null"
|
||||
|
||||
' Leemos los registros devueltos por el servidor para actualizar nuestras variables.
|
||||
For Each records() As Object In rpd.resultado.Rows
|
||||
liquidado = records(rpd.resultado.Columns.Get("LIQUIDADO"))
|
||||
arqueo = records(rpd.resultado.Columns.Get("ARQUEO"))
|
||||
Next
|
||||
|
||||
Subs.logJobDoneResultados(rpd.resultado)
|
||||
|
||||
' 5. Regla de negocio: Si el estatus es "NO" liquidado y el arqueo es "null" (abierto),
|
||||
' entonces es seguro proceder a modificar/enviar la información.
|
||||
If liquidado = "NO" And arqueo = "null" Then
|
||||
Log("==== BORRAMOS Y ENVIAMOS PEDIDO ===")
|
||||
|
||||
' =========================================================================================
|
||||
' INICIA PREPARACIÓN DEL BATCH (EMPAQUETADO DE DELETES E INSERTS)
|
||||
' =========================================================================================
|
||||
' 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})"$)
|
||||
|
||||
Log("===== AGREGAMOS HEADER DE PEDIDO =====")
|
||||
' Movemos el cursor 'cx' a la posición 'j' actual del bucle de encabezados.
|
||||
cx.Position = j
|
||||
|
||||
' ===== EJECUTAR DELETES PRIMERO =====
|
||||
' Preparamos la eliminación de los registros viejos en el servidor para evitar duplicados.
|
||||
Log("===== LIMPIANDO PEDIDOS PREVIOS EN SERVER =====")
|
||||
|
||||
' Borrar Pedido (Detalle) en el servidor
|
||||
Dim cmdDelPed As DBCommand
|
||||
cmdDelPed.Initialize
|
||||
cmdDelPed.Name = "borraPedido_Kelloggs"
|
||||
cmdDelPed.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
|
||||
BatchCommands.Add(cmdDelPed)
|
||||
|
||||
' Borrar Pedido Cliente (Header) en el servidor
|
||||
Dim cmdDelHeader As DBCommand
|
||||
cmdDelHeader.Initialize
|
||||
cmdDelHeader.Name = "borraPedidoCliente_Kelloggs"
|
||||
cmdDelHeader.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
|
||||
BatchCommands.Add(cmdDelHeader)
|
||||
|
||||
' Borrar Hist_Ventas (Header) en el servidor
|
||||
Dim cmdDelHV As DBCommand
|
||||
cmdDelHV.Initialize
|
||||
cmdDelHV.Name = "borraHV_Kelloggs"
|
||||
cmdDelHV.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
|
||||
BatchCommands.Add(cmdDelHV)
|
||||
|
||||
' Borrar Hist_Ventas_Detalle (Detalle) en el servidor
|
||||
Dim cmdDelHVD As DBCommand
|
||||
cmdDelHVD.Initialize
|
||||
cmdDelHVD.Name = "borraHVD_Kelloggs"
|
||||
cmdDelHVD.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
|
||||
BatchCommands.Add(cmdDelHVD)
|
||||
|
||||
' ===== GENERACIÓN DE ID ÚNICO (ARCH) =====
|
||||
' Generamos un identificador único (Arch) concatenando el almacén, la ruta, el cliente y la fecha/hora actual.
|
||||
' Esto sirve para agrupar y amarrar lógicamente en el servidor el encabezado con sus respectivos detalles.
|
||||
Dim Arch As String = Subs.traeAlmacen & "_" & Subs.traeRuta & "_" & cx.GetString("PC_CLIENTE") & "_" & DateTime.Now
|
||||
|
||||
' Actualizamos las tablas locales asignándoles este nuevo ID 'Arch'.
|
||||
Starter.skmt.ExecNonQuery2($"UPDATE PEDIDO SET PE_ARCH = ? WHERE PE_CLIENTE = ?"$, Array As Object(Arch, cx.GetString("PC_CLIENTE")))
|
||||
Starter.skmt.ExecNonQuery2($"UPDATE PEDIDO_CLIENTE SET PC_ARCH = ? WHERE PC_CLIENTE = ?"$, Array As Object(Arch, cx.GetString("PC_CLIENTE")))
|
||||
|
||||
' ===== INSERCIÓN DEL NUEVO ENCABEZADO =====
|
||||
' Preparamos el comando de inserción del encabezado para mandar al servidor.
|
||||
Dim cmdHeader As DBCommand
|
||||
cmdHeader.Initialize
|
||||
' Asignamos el nombre del procedimiento almacenado o query de inserción.
|
||||
cmdHeader.Name = "insert_pedidos_KELL_arch"
|
||||
' Pasamos los parámetros leyendo los datos del cursor local 'cx' y le añadimos 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 de inserción a nuestra lista del lote (Batch).
|
||||
BatchCommands.Add(cmdHeader)
|
||||
|
||||
' ===== INSERCIÓN DE LOS DETALLES (PRODUCTOS) =====
|
||||
' Hacemos una consulta local para buscar los productos individuales de este pedido en específico.
|
||||
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 where pe_cliente = '${cx.GetString("PC_CLIENTE")}' "$)
|
||||
|
||||
' Si la consulta arrojó productos para este cliente...
|
||||
If cPed.RowCount > 0 Then
|
||||
' Iniciamos un bucle interno para recorrer cada uno de esos productos.
|
||||
For i = 0 To cPed.RowCount - 1
|
||||
Log("==== AGREGAMOS PRODS DE PEDIDO ====")
|
||||
' Movemos el cursor de detalles a la posición actual 'i'.
|
||||
cPed.Position = i
|
||||
|
||||
' Preparamos el comando de inserción para este producto en el servidor.
|
||||
Dim cmdDetail As DBCommand
|
||||
cmdDetail.Initialize
|
||||
|
||||
' Verificamos si el vendedor tiene un perfil especial.
|
||||
If PERFIL = "V-ESPECIAL" Then
|
||||
Log("===== V-ESPECIAL =====")
|
||||
' Utilizamos el query específico para ventas especiales y pasamos sus parámetros.
|
||||
cmdDetail.Name = "insert_pedido_esp_KELL"
|
||||
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"),NUMERO_PEDIDO)
|
||||
Else
|
||||
' Si es un vendedor normal, usamos el query estándar y lo vinculamos usando la variable 'Arch'.
|
||||
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 de inserción de este producto al lote (Batch).
|
||||
BatchCommands.Add(cmdDetail)
|
||||
Next
|
||||
End If
|
||||
' Cerramos el cursor de detalles locales para liberar memoria.
|
||||
cPed.Close
|
||||
|
||||
' ===== ENVÍO DEL LOTE AL SERVIDOR =====
|
||||
' Mandamos a ejecutar toda la lista de instrucciones (Deletes + Inserts) al servidor en una sola petición HTTP.
|
||||
' Le ponemos una etiqueta (Tag) con el ID del cliente para poder identificar la respuesta en el evento JobDone.
|
||||
reqManager.ExecuteBatch(BatchCommands, "pedido_completo_" & cx.GetString("PC_CLIENTE"))
|
||||
Log("==== ENVIAMOS PEDIDO COMPLETO ====")
|
||||
|
||||
Else
|
||||
' Si la validación falló (el pedido ESTÁ liquidado o el arqueo ESTÁ cerrado),
|
||||
' bloqueamos la operación y le mostramos advertencias al usuario en pantalla.
|
||||
ToastMessageShow("Pedido liquidado o cerrado", True)
|
||||
MsgboxAsync("¡El pedido esta liquidado o el arqueo cerrado, la información NO fue enviada a web!", "AVISO")
|
||||
End If
|
||||
Else
|
||||
' Si la consulta de validación (revisaArqueoYLiquidacion) falló por problemas de red o servidor,
|
||||
' registramos el error en el log local. No procedemos con el envío por seguridad.
|
||||
Log("===== ERROR =====")
|
||||
Log(rpd.ErrorMessage)
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
|
||||
' Cerramos los cursores principales abiertos al inicio de la función para evitar memory leaks.
|
||||
c.Close
|
||||
cx.Close
|
||||
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 enviaPedidoBatch1(filtro As String)
|
||||
' 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"
|
||||
If filtro <> "Todos" Then
|
||||
condicion = "WHERE PC_ENVIADO = 0 OR PC_CLIENTE IN (SELECT PE_CLIENTE FROM PEDIDO WHERE PE_ENVIADO = 0)" ' Si se actualizo un producto, hay que volver a enviar todo el pedido.
|
||||
End If
|
||||
|
||||
' 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
|
||||
|
||||
' sql.revisaArqueoYLiquidacion_Kelloggs = select NVL(HVD_ESTATUS, 'NO') as liquidado, HVD_DTECIERRE, (select hist_ca_fecha from KELLOGGS.hist_cierre_arqueo where hist_ca_idalmacen = (?) and hist_ca_ruta = (?) and trunc(sysdate) = trunc(hist_ca_fecha)) as arqueo from KELLOGGS.HIST_VENTAS_DETALLE where HVD_ALMACEN = (?) and HVD_RUTA = (?) and trunc(sysdate) = trunc(HVD_FECHA) and HVD_TIPOVENTA = 'VENTA' and rownum <= 1
|
||||
cmd.Initialize
|
||||
cmd.Name = "revisaArqueoYLiquidacion_Kelloggs"
|
||||
Private ruta_ As String = Subs.traeRuta
|
||||
cmd.Parameters = Array As Object(ALMACEN, ruta_, ALMACEN, ruta_)
|
||||
reqManagerW.ExecuteQuery(Starter.DBReqServer, cmd, Me, "revisaPedidoLiquidado")
|
||||
Wait For revisaPedidoLiquidado_Completed (rpd As TResultado)
|
||||
If rpd.Success Then
|
||||
Log("SUCCESS - revisaPedidoLiquidado")
|
||||
Dim liquidado As String = "NO"
|
||||
Dim arqueo As String = "null"
|
||||
For Each records() As Object In rpd.resultado.Rows
|
||||
liquidado = records(rpd.resultado.Columns.Get("LIQUIDADO"))
|
||||
arqueo = records(rpd.resultado.Columns.Get("ARQUEO"))
|
||||
Next
|
||||
Subs.logJobDoneResultados(rpd.resultado)
|
||||
If liquidado = "NO" And arqueo = "null" Then
|
||||
Log("==== BORRAMOS Y ENVIAMOS PEDIDO ===")
|
||||
|
||||
' 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})"$)
|
||||
|
||||
Log("===== AGREGAMOS HEADER DE PEDIDO =====")
|
||||
' Movemos el cursor 'cx' a la posición 'j' actual del bucle.
|
||||
cx.Position = j
|
||||
|
||||
' ===== 1. EJECUTAR DELETES PRIMERO =====
|
||||
Log("===== LIMPIANDO PEDIDOS PREVIOS EN SERVER =====")
|
||||
|
||||
' Borrar Pedido (Detalle)
|
||||
Dim cmdDelPed As DBCommand
|
||||
cmdDelPed.Initialize
|
||||
cmdDelPed.Name = "borraPedido_Kelloggs"
|
||||
cmdDelPed.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
|
||||
BatchCommands.Add(cmdDelPed)
|
||||
|
||||
' Borrar Pedido Cliente (Header)
|
||||
Dim cmdDelHeader As DBCommand
|
||||
cmdDelHeader.Initialize
|
||||
cmdDelHeader.Name = "borraPedidoCliente_Kelloggs"
|
||||
cmdDelHeader.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
|
||||
BatchCommands.Add(cmdDelHeader)
|
||||
|
||||
' Borrar Hist_Ventas (Header)
|
||||
Dim cmdDelHV As DBCommand
|
||||
cmdDelHV.Initialize
|
||||
cmdDelHV.Name = "borraHV_Kelloggs"
|
||||
cmdDelHV.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
|
||||
BatchCommands.Add(cmdDelHV)
|
||||
|
||||
' Borrar Hist_Ventas_Detalle (Detalle)
|
||||
Dim cmdDelHVD As DBCommand
|
||||
cmdDelHVD.Initialize
|
||||
cmdDelHVD.Name = "borraHVD_Kelloggs"
|
||||
cmdDelHVD.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
|
||||
BatchCommands.Add(cmdDelHVD)
|
||||
|
||||
' 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
|
||||
|
||||
Starter.skmt.ExecNonQuery2($"UPDATE PEDIDO SET PE_ARCH = ? WHERE PE_CLIENTE = ?"$, Array As Object(Arch, cx.GetString("PC_CLIENTE")))
|
||||
Starter.skmt.ExecNonQuery2($"UPDATE PEDIDO_CLIENTE SET PC_ARCH = ? WHERE PC_CLIENTE = ?"$, Array As Object(Arch, cx.GetString("PC_CLIENTE")))
|
||||
|
||||
' 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 where 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("==== AGREGAMOS PRODS DE PEDIDO ====")
|
||||
' 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.
|
||||
cmdDetail.Name = "insert_pedido_esp_KELL"
|
||||
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"),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
|
||||
cPed.Close
|
||||
' 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"))
|
||||
Log("==== ENVIAMOS PEDIDO COMPLETO ====")
|
||||
Else
|
||||
ToastMessageShow("Pedido liquidado o cerrado", True)
|
||||
MsgboxAsync("¡El pedido esta liquidado o el arqueo cerrado, la información NO fue enviada a web!", "AVISO")
|
||||
End If
|
||||
Else
|
||||
Log("===== ERROR =====")
|
||||
Log(rpd.ErrorMessage)
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
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
|
||||
@@ -3536,7 +3936,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 =====")
|
||||
@@ -4071,6 +4471,7 @@ Sub IsConnectedToInternet As Boolean 'ignore
|
||||
End Sub
|
||||
|
||||
Private Sub b_motivoNoVisita_Click
|
||||
B4XPages.MainPage.aud.guarda("Entrada a motivoNoVisita")
|
||||
r_1.Checked = True
|
||||
r_razonNoVisita = "FALLA MECANICA"
|
||||
If Not(kh.motivoNoVisitaActivo) Then
|
||||
@@ -4096,6 +4497,7 @@ Private Sub b_noVisita_Click
|
||||
Msgbox2Async("Si se envia la información, ya NO se va a poder continuar con la ruta, los clientes por visitar se van a bloquear.", "AVISO", "Continuar", "Cancelar", "", LoadBitmap(File.DirAssets,"alert2.png"), False)
|
||||
Wait For Msgbox_Result (result As Int)
|
||||
If result = DialogResponse.POSITIVE Then
|
||||
B4XPages.MainPage.aud.guarda($"Se envió MotivoNoVisita: "${r_razonNoVisita}""$)
|
||||
ToastMessageShow("CONTINUAR", False)
|
||||
Starter.skmt.ExecNonQuery($"delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'NOVISITA_ACTIVA'"$)
|
||||
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("NOVISITA_ACTIVA", 1))
|
||||
|
||||
@@ -166,6 +166,7 @@ End Sub
|
||||
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
|
||||
|
||||
Sub B4XPage_Appear
|
||||
B4XPages.MainPage.aud.guarda("Entrada a Productos")
|
||||
If Starter.Logger Then Log("Entro: " & entro)
|
||||
' Log($"LIMITE ABORDO: ${limiteAbordo}"$)
|
||||
' clv_prods_ll.Initialize(Me, "clv_prods_ll")
|
||||
@@ -351,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
|
||||
@@ -142,6 +142,7 @@ Private Sub B4XPage_Created (Root1 As B4XView)
|
||||
End Sub
|
||||
|
||||
Sub B4XPage_Appear
|
||||
B4XPages.MainPage.aud.guarda("Entrada a Promos")
|
||||
B4XPages.MainPage.productos.entro = 3
|
||||
' LogColor(B4XPages.MainPage.productos.prodsMap, Colors.blue)
|
||||
prodsIds.Initialize
|
||||
@@ -156,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)
|
||||
@@ -167,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)
|
||||
@@ -562,7 +564,7 @@ Private Sub b_terminar1_Click
|
||||
|
||||
' ' Asumimos que el índice 0 es el encabezado de la promoción (estaPromo) y no tiene bonificación de producto.
|
||||
If t > 0 Then
|
||||
Private bonificacion_monto As String = ts.traeMontoBonificacion(idProdFijo, prodsPrecio, estaPromo)
|
||||
Private bonificacion_monto As String = ts.traeMontoBonificacion(idProdFijo, prodsPrecio, estaPromo, "b_terminar1_Click")
|
||||
Log(bonificacion_monto)
|
||||
Log("elMontoTSDeLaVenta=" & elMontoTSDeLaVenta)
|
||||
Log($"${elMontoTSDeLaVenta} + (${bonificacion_monto} * ${cantProdFijo})"$)
|
||||
@@ -576,8 +578,8 @@ Private Sub b_terminar1_Click
|
||||
Private pn As String = Subs.traeProdNombre(prodsIds2.Get(t))
|
||||
Subs.guardaProductoSinGestion(estaPromo, prodsPrecios2.Get(t), prodsCants2.Get(t), pn, prodsIds2.Get(t), Subs.traeCliente, Subs.traeFecha, Subs.traeUsuarioDeBD, Subs.traeRuta, 0, Starter.tipov)
|
||||
' Traemos el monto de las bonificacionos a guardar. -- Trade Spending
|
||||
Log("Monto Bonificacion -->> " & ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo))
|
||||
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo) * prodsCants2.Get(t))
|
||||
Log("Monto Bonificacion -->> " & ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo, "LOG_b_terminar1_Click2"))
|
||||
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo, "b_terminar1_Click3") * prodsCants2.Get(t))
|
||||
Log("Acumulado: " & elMontoTSDeLaVenta)
|
||||
Next
|
||||
ts.modTrendSpending("RESTA", "BONIFICACIONES", elMontoTSDeLaVenta)
|
||||
@@ -604,7 +606,7 @@ Private Sub b_continuar_Click
|
||||
|
||||
' ' Asumimos que el índice 0 es el encabezado de la promoción (estaPromo) y no tiene bonificación de producto.
|
||||
If t > 0 Then
|
||||
Private bonificacion_monto As String = ts.traeMontoBonificacion(idProdFijo, prodsPrecio, estaPromo)
|
||||
Private bonificacion_monto As String = ts.traeMontoBonificacion(idProdFijo, prodsPrecio, estaPromo, "b_continuar_Click")
|
||||
Log(bonificacion_monto)
|
||||
Log("elMontoTSDeLaVenta=" & elMontoTSDeLaVenta)
|
||||
Log($"${elMontoTSDeLaVenta} + (${bonificacion_monto} * ${cantProdFijo})"$)
|
||||
@@ -618,8 +620,8 @@ Private Sub b_continuar_Click
|
||||
Private pn As String = Subs.traeProdNombre(prodsIds2.Get(t))
|
||||
Subs.guardaProductoSinGestion(estaPromo, prodsPrecios2.Get(t), prodsCants2.Get(t), pn, prodsIds2.Get(t), Subs.traeCliente, Subs.traeFecha, Subs.traeUsuarioDeBD, Subs.traeRuta, 0, Starter.tipov)
|
||||
' Traemos el monto de las bonificacionos a guardar. -- Trade Spending
|
||||
Log("Monto Bonificacion -->> " & ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo))
|
||||
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo) * prodsCants2.Get(t))
|
||||
Log("Monto Bonificacion -->> " & ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo, "LOG_b_continuar_Click2"))
|
||||
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo, "b_continuar_Click3") * prodsCants2.Get(t))
|
||||
Log("Acumulado: " & elMontoTSDeLaVenta)
|
||||
Next
|
||||
ts.modTrendSpending("RESTA", "BONIFICACIONES", elMontoTSDeLaVenta)
|
||||
|
||||
@@ -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.
|
||||
@@ -48,6 +48,7 @@ End Sub
|
||||
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
|
||||
|
||||
Sub B4XPage_Appear
|
||||
B4XPages.MainPage.aud.guarda("Entrada a TicketsDia")
|
||||
nombre_boton = "NOVENTA"
|
||||
c=Starter.skmt.ExecQuery("select PC_CLIENTE,PC_MONTO,PC_NOART,(select CAT_CL_NOMBRE from kmt_info where cat_cl_codigo = pc_cliente ) as NOMBRE FROM PEDIDO_CLIENTE ORDER BY PC_FECHA asc")
|
||||
ListView1.Clear
|
||||
@@ -90,9 +91,10 @@ Sub Activity_KeyPress (key As Int) As Boolean
|
||||
End Sub
|
||||
|
||||
Sub ListView1_ItemLongClick (Position As Int, Value As Object)
|
||||
Log(value)
|
||||
Log(Value)
|
||||
Starter.skmt.ExecNonQuery("delete from CUENTAA")
|
||||
Starter.skmt.ExecNonQuery2("INSERT INTO CUENTAA VALUES (?)", Array As Object(Value))
|
||||
B4XPages.MainPage.aud.guarda($"Clic largo TicketsDia: ${Value}"$)
|
||||
Subs.iniciaActividad("Cliente")
|
||||
End Sub
|
||||
|
||||
|
||||
462
B4A/C_TrendSpending.bas
Normal file
462
B4A/C_TrendSpending.bas
Normal file
@@ -0,0 +1,462 @@
|
||||
B4A=true
|
||||
Group=Default Group
|
||||
ModulesStructureVersion=1
|
||||
Type=Class
|
||||
Version=12.8
|
||||
@EndOfDesignText@
|
||||
' Clase para las funciones de Trend Spending.
|
||||
' Trend spending son 3 presupuestos que tiene Kelloggs, que son bonificaciones, descuentos y RMIs, estos se calculan semanalmente
|
||||
' y se descargan de la tabla HIST_TRADE_SPENDING_SEMANAL, de ahi obtenemos el presupuesto de la semana y el acumulado hasta ayer
|
||||
' en la noche, a cada presupuesto le vamos sumando cada que agregamos a pedido un DESCUENTO (Precios diferentes al original que
|
||||
' NO están en PROMOS), una BONIFICACION (precios con descuento que estan en promociones) o un RMI (de estos sumamos al presupuesto
|
||||
' el precio del RMI seleccionado), de acuerdo al presupuesto disponible de cada tipo, se limitan los productos, es decir que si
|
||||
' el presupuesto de bonificaciones ya se agoto, ya no aparecen promociones, o si el de descuentos se agoto, ya no se pueden agregar
|
||||
' mas productos con descuento.
|
||||
|
||||
' 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
|
||||
Dim tsMaximas As Int = 0
|
||||
Private tsdb As SQL
|
||||
Dim TS_RMI() As String
|
||||
Dim TS_DESCUENTOS() As String
|
||||
Dim TS_BONIFICACIONES() As String
|
||||
End Sub
|
||||
|
||||
'Initializes the object. You can add parameters to this method if needed.
|
||||
Public Sub Initialize (vCallback As Object, vEventName As String, db As SQL) As Object
|
||||
EventName = vEventName
|
||||
CallBack = vCallback
|
||||
tsdb = db
|
||||
Private mx As Map = traeInfoTrendSpending
|
||||
LogColor(mx, Colors.red)
|
||||
TS_RMI = Regex.Split(",", mx.Get("RMI"))
|
||||
TS_DESCUENTOS = Regex.Split(",", mx.Get("DESCUENTOS"))
|
||||
TS_BONIFICACIONES = Regex.Split(",", mx.Get("BONIFICACIONES"))
|
||||
LogColor(">>>>>>>>>>>>> TRENDSPENDING: " & mx, Colors.red)
|
||||
LogColor("RMI: " & TS_RMI(0) & "|" & TS_RMI(1), Colors.red)
|
||||
LogColor("DESCUENTOS: " & TS_DESCUENTOS(0) & "|" & TS_DESCUENTOS(1), Colors.red)
|
||||
LogColor("BONIFICACIONES: " & TS_BONIFICACIONES(0) & "|" & TS_BONIFICACIONES(1), Colors.red)
|
||||
Return Me
|
||||
End Sub
|
||||
|
||||
'Regresa la tabla de productos (cat_gunaprod o cat_gunaprod2) dependiendo del tipo de venta.
|
||||
Sub traeTablaProds(tipoventa As String) As String
|
||||
Private tablaProds As String = "cat_gunaprod2"
|
||||
If tipoventa = "ABORDO" Or tipoventa = "PREVENTA" Then tablaProds = "cat_gunaprod"
|
||||
' LogColor($"Tipo= ${tipoventa}, tabla=${tablaProds}"$, Colors.RGB(200,136,0))
|
||||
Return tablaProds
|
||||
End Sub
|
||||
|
||||
'Regresa el descuento de condiciones comerciales por SKU.
|
||||
Sub traeDescXSku(clienteId As String, prodId As String) As String 'ignore
|
||||
Private desc As String = "0"
|
||||
Private c As Cursor = tsdb.ExecQuery($"Select * from CAT_DESCUENTOS_SKU where CAT_DS_CLIENTE = '${clienteId}' and CAT_DS_PRODID = '${prodId}'"$)
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
desc = c.GetString("CAT_DS_PORCENTAJE")
|
||||
End If
|
||||
Return desc
|
||||
End Sub
|
||||
|
||||
' Regresa un mapa con el tipo, monto permitido semanal y el acumulado hasta el día anterior:
|
||||
' ej:
|
||||
' - RMI=1500,0
|
||||
' - DESCUENTOS=1500,0
|
||||
' - BONIFICACIONES=1500,480
|
||||
Sub traeInfoTrendSpending As Map
|
||||
Private semana As Int = 0
|
||||
Private HIST_TSS_SEMANA As String = 0
|
||||
Private HIST_TSS_SEMANA_ACUM As String = 0
|
||||
Private m As Map = CreateMap("RMI": 10000000 & "," & 0, "DESCUENTOS": 10000000 & "," & 0, "BONIFICACIONES": 10000000 & "," & 0) ' El 100,000 es el default del presupuesto, por si NO HAY datos de trend spending.
|
||||
' m.Initialize
|
||||
Private c As Cursor = tsdb.ExecQuery($"select cat_va_valor from cat_variables where cat_va_descripcion = 'SEM_CAL_LABORAL'"$)
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
semana = c.GetInt("CAT_VA_VALOR")
|
||||
End If
|
||||
If semana > 0 Then
|
||||
c = tsdb.ExecQuery($"select HIST_TSS_TIPO, HIST_TSS_SEMANA${semana}, ifnull(HIST_TSS_SEMANA${semana}_ACUM,0) as HIST_TSS_SEMANA${semana}_ACUM from HIST_TREND_SPENDING_SEMANAL"$)
|
||||
Log($"select HIST_TSS_TIPO, HIST_TSS_SEMANA${semana}, ifnull(HIST_TSS_SEMANA${semana}_ACUM,0) as HIST_TSS_SEMANA${semana}_ACUM from HIST_TREND_SPENDING_SEMANAL"$)
|
||||
If c.RowCount > 0 Then
|
||||
For i = 0 To c.RowCount - 1
|
||||
c.Position = i
|
||||
HIST_TSS_SEMANA = c.GetString($"HIST_TSS_SEMANA${semana}"$)
|
||||
If Not(IsNumber(HIST_TSS_SEMANA)) Then HIST_TSS_SEMANA = 0
|
||||
Private xx As String = c.GetString($"HIST_TSS_SEMANA${semana}_ACUM"$)
|
||||
If xx = "null" Then xx = 0
|
||||
HIST_TSS_SEMANA_ACUM = xx
|
||||
If c.GetString("HIST_TSS_TIPO") = "RMI" Then
|
||||
m.Put("RMI", HIST_TSS_SEMANA & "," & HIST_TSS_SEMANA_ACUM)
|
||||
else if c.GetString("HIST_TSS_TIPO") = "DESCUENTOS" Then
|
||||
m.Put("DESCUENTOS", HIST_TSS_SEMANA & "," & HIST_TSS_SEMANA_ACUM)
|
||||
else if c.GetString("HIST_TSS_TIPO") = "BONIFICACIONES" Then
|
||||
m.Put("BONIFICACIONES", HIST_TSS_SEMANA & "," & HIST_TSS_SEMANA_ACUM)
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
End If
|
||||
Return m
|
||||
End Sub
|
||||
|
||||
' Modifica el acumulado del Trend Speding, le "suma" o "resta" al presupuesto especificado (RMI, BONIFICACIONES o DESCUENTOS)
|
||||
Sub modTrendSpending(accion As String, tipo As String, monto As String)
|
||||
LogColor($"#### ACCION: ${accion}, Tipo: ${tipo}, Monto: ${monto}"$, Colors.Blue)
|
||||
Private HIST_TSS_SEMANA As String
|
||||
Private HIST_TSS_SEMANA_ACUM As String
|
||||
Private acumulado As String = "0"
|
||||
If Starter.semana = 0 Then
|
||||
Private c As Cursor = tsdb.ExecQuery($"select cat_va_valor from cat_variables where cat_va_descripcion = 'SEM_CAL_LABORAL'"$)
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
Starter.semana = c.GetInt("CAT_VA_VALOR")
|
||||
End If
|
||||
End If
|
||||
HIST_TSS_SEMANA = $"HIST_TSS_SEMANA${Starter.semana}"$
|
||||
HIST_TSS_SEMANA_ACUM = $"HIST_TSS_SEMANA${Starter.semana}_ACUM"$
|
||||
Private d As Cursor = tsdb.ExecQuery($"select ifnull(acumulado, 0) as ACUMULADO from TREND_SPENDING where tipo = '${tipo.ToUpperCase}'"$)
|
||||
If d.RowCount > 0 Then
|
||||
d.Position = 0
|
||||
acumulado = d.GetString("ACUMULADO")
|
||||
End If
|
||||
Log("acumulado:" & acumulado & " | monto: " & monto)
|
||||
Private c As Cursor = tsdb.ExecQuery($"select HIST_TSS_TIPO, ifnull(${HIST_TSS_SEMANA},0) as disponible, ifnull(${HIST_TSS_SEMANA_ACUM},0) as acumulado from HIST_TREND_SPENDING_SEMANAL where HIST_TSS_TIPO = '${tipo.ToUpperCase}'"$)
|
||||
' Log(($"select HIST_TSS_TIPO, ${HIST_TSS_SEMANA} as disponible, ${HIST_TSS_SEMANA_ACUM} as acumulado from HIST_TREND_SPENDING_SEMANAL where HIST_TSS_TIPO = '${tipo.ToUpperCase}'"$))
|
||||
Log("---- " & c.RowCount)
|
||||
If accion.ToUpperCase = "RESTA" Then
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
If tipo.ToUpperCase = "DESCUENTOS" Or tipo.ToUpperCase = "RMI" Or tipo.ToUpperCase = "BONIFICACIONES" Then
|
||||
Private nuevaBonificacion As String = NumberFormat2((acumulado + monto), 1, 2, 2, False)
|
||||
LogColor($"Nuevo acumulado ${tipo} = ${nuevaBonificacion}"$, Colors.Magenta)
|
||||
tsdb.ExecNonQuery($"delete from TREND_SPENDING where tipo = '${tipo.ToUpperCase}' "$)
|
||||
tsdb.ExecNonQuery($"insert into TREND_SPENDING (tipo, acumulado) values ('${tipo.ToUpperCase}', '${nuevaBonificacion}')"$)
|
||||
Log($"Insertamos en TRADE_SPENDING: ${nuevaBonificacion}"$)
|
||||
' else if tipo.ToUpperCase = "RMI" Then
|
||||
End If
|
||||
End If
|
||||
else if accion.ToUpperCase = "SUMA" Then
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
If tipo.ToUpperCase = "DESCUENTOS" Or tipo.ToUpperCase = "RMI" Or tipo.ToUpperCase = "BONIFICACIONES" Then
|
||||
Private nuevaBonificacion As String = NumberFormat2((acumulado - monto), 1, 2, 2, False)
|
||||
LogColor($"Nueva bonificacion = ${nuevaBonificacion}"$, Colors.Magenta)
|
||||
tsdb.ExecNonQuery($"delete from TREND_SPENDING where tipo = '${tipo.ToUpperCase}' "$)
|
||||
tsdb.ExecNonQuery($"insert into TREND_SPENDING (tipo, acumulado) values ('${tipo.ToUpperCase}', '${nuevaBonificacion}')"$)
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Sub traeAcumuladoHoyTS(tipo As String) As String
|
||||
' Private HIST_TSS_SEMANA As String
|
||||
' Private HIST_TSS_SEMANA_ACUM As String
|
||||
Private acumulado As String = "0"
|
||||
If Starter.semana = 0 Then
|
||||
Private c As Cursor = tsdb.ExecQuery($"select cat_va_valor from cat_variables where cat_va_descripcion = 'SEM_CAL_LABORAL'"$)
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
Starter.semana = c.GetInt("CAT_VA_VALOR")
|
||||
End If
|
||||
End If
|
||||
' HIST_TSS_SEMANA = $"HIST_TSS_SEMANA${Starter.semana}"$
|
||||
' HIST_TSS_SEMANA_ACUM = $"HIST_TSS_SEMANA${Starter.semana}_ACUM"$
|
||||
Private d As Cursor = tsdb.ExecQuery($"select acumulado from TREND_SPENDING where tipo = '${tipo.ToUpperCase}'"$)
|
||||
If d.RowCount > 0 Then
|
||||
d.Position = 0
|
||||
acumulado = d.GetString("ACUMULADO")
|
||||
End If
|
||||
' LogColor($"Acumulado hoy de ${tipo}: "$ & acumulado, Colors.Blue)
|
||||
Return NumberFormat2(acumulado, 1, 2, 2, False)
|
||||
End Sub
|
||||
|
||||
'Trae el cliente de CUENTAA
|
||||
Sub traeCliente As String 'ignore
|
||||
Private c As Cursor
|
||||
Private cl As String
|
||||
c = Starter.skmt.ExecQuery("Select CUENTA from cuentaa")
|
||||
c.Position = 0
|
||||
cl = c.GetString("CUENTA")
|
||||
c.Close
|
||||
Return cl
|
||||
End Sub
|
||||
|
||||
Sub traePrecio(id As String) As String
|
||||
Private precio As String = "0"
|
||||
Private c As Cursor = tsdb.ExecQuery($"select cat_gp_precio from ${traeTablaProds(Starter.tipov)} where cat_gp_id = '${id}'"$)
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
precio = c.GetString("CAT_GP_PRECIO")
|
||||
End If
|
||||
Return precio
|
||||
End Sub
|
||||
|
||||
Sub trendSpending(accion As String, tipo As String, clienteId As String, id As String, laCant As String, inv As Int) As String
|
||||
Private logger As Boolean = True
|
||||
LogColor("-------- > TRADE SPENDING < ---------", Colors.red)
|
||||
' Log("DescxSku: " & traeDescXSku(clienteId, id))
|
||||
Dim TS_RMI() As String
|
||||
Dim TS_DESCUENTOS() As String
|
||||
Dim TS_BONIFICACIONES() As String
|
||||
Private mx As Map = traeInfoTrendSpending
|
||||
TS_RMI = Regex.Split(",", mx.Get("RMI"))
|
||||
TS_DESCUENTOS = Regex.Split(",", mx.Get("DESCUENTOS"))
|
||||
TS_BONIFICACIONES = Regex.Split(",", mx.Get("BONIFICACIONES"))
|
||||
If tipo.ToUpperCase = "RMI" Then
|
||||
Private lasMaximas As Int = 0
|
||||
Log($"Acumulado de RMIs: ${traeAcumuladoHoyTS("rmi")}"$)
|
||||
Private elMonto As String = NumberFormat2(traePrecioRMI(id), 1, 2, 2, False)
|
||||
If logger Then Log($"elMonto: ${elMonto}"$)
|
||||
' If logger Then Log($"TS_RMI(0): ${TS_RMI(0)}"$)
|
||||
' If logger Then Log($"TS_RMI(1): ${TS_RMI(1)}"$)
|
||||
If logger Then Log($"LaCant: ${laCant}"$)
|
||||
Private tsRestantes As String = (TS_RMI(0) - TS_RMI(1) - traeAcumuladoHoyTS("rmi"))
|
||||
Log($"tsRestantes: ${tsRestantes}"$)
|
||||
If accion.ToUpperCase = "PRODMAS" Then 'Regresa lasMaximas y elMonto separadas por un "|"
|
||||
If elMonto > 0 Then
|
||||
lasMaximas = ((laCant * elMonto) + tsRestantes) / elMonto
|
||||
If logger Then Log("lasMaximas: " & lasMaximas)
|
||||
If logger Then Log("traeAcumuladoHoyTS: " & traeAcumuladoHoyTS("rmi"))
|
||||
End If
|
||||
' If laCant + 1 = lasMaximas Then
|
||||
' ToastMessageShow("El presupuesto de RMI no permite agregar mas productos!!", False)
|
||||
' End If
|
||||
If logger Then Log("EL RMI: " & elMonto)
|
||||
If logger Then Log($"lacant=${laCant} < lasMaximas=${lasMaximas} = ${laCant<lasMaximas}"$)
|
||||
If laCant < lasMaximas Then
|
||||
modTrendSpending("resta", "rmi", elMonto) ' Restamos al presupuesto de hoy (agregamos al acumulado).
|
||||
Log($"modTrendSpending("resta", "rmi", ${elMonto})"$)
|
||||
End If
|
||||
If logger Then LogColor("RMI RESTANTES: " & (TS_RMI(0) - TS_RMI(1) - traeAcumuladoHoyTS("rmi")), Colors.red)
|
||||
Return lasMaximas & "|" & elMonto
|
||||
else if accion.ToUpperCase = "PRODMENOS" Then
|
||||
If logger Then Log("LaCANT= " & laCant & ", elMonto= " & elMonto)
|
||||
If laCant >= 0 Then
|
||||
modTrendSpending("suma", "rmi", elMonto) ' Agregamos al presupuesto de hoy (restamos del acumulado).
|
||||
Log($"modTrendSpending("suma", "rmi", ${elMonto})"$)
|
||||
End If
|
||||
Return lasMaximas & "|" & elMonto
|
||||
End If
|
||||
else If tipo.ToUpperCase = "DESCUENTOS" Then
|
||||
Dim lasMaximas As Int = 0
|
||||
Dim elMonto As String = 0
|
||||
Private elMonto As String = NumberFormat2(traePrecio(id)*(traeDescXSku(clienteId, id)/100), 1, 2, 2, False)
|
||||
Private tsRestantes As String = (TS_DESCUENTOS(0) - TS_DESCUENTOS(1) - traeAcumuladoHoyTS("descuentos"))
|
||||
If logger Then Log("EL MONTO: " & elMonto)
|
||||
If logger Then LogColor("Monto del presupuesto disponible: " & tsRestantes, Colors.blue)
|
||||
If accion.ToUpperCase = "PRODMAS" Then 'Regresa lasMaximas y elMonto separadas por un "|"
|
||||
' If logger Then Log("PMAS")
|
||||
If elMonto > 0 Then
|
||||
lasMaximas = ((laCant * elMonto) + tsRestantes) / elMonto
|
||||
If logger Then Log("lasMaximas: " & lasMaximas)
|
||||
' If logger Then Log("lasMaximas2: " & traeMaximas("descuentos", clienteId, id, laCant, ""))
|
||||
If logger Then Log("Acumulado hoy: " & traeAcumuladoHoyTS("descuentos"))
|
||||
End If
|
||||
If laCant = lasMaximas Then
|
||||
ToastMessageShow("El presupuesto de DESCUENTOS no permite agregar mas productos!!", False)
|
||||
End If
|
||||
If logger Then Log("EL MONTO: " & elMonto)
|
||||
If inv > 0 And laCant < lasMaximas Then
|
||||
modTrendSpending("resta", "descuentos", elMonto) ' Restamos al presupuesto de hoy (agregamos al acumulado).
|
||||
End If
|
||||
If logger Then Log(">>>> MONTO RESTANTE PRESUPUESTO: " & (TS_DESCUENTOS(0) - TS_DESCUENTOS(1) - traeAcumuladoHoyTS("descuentos")))
|
||||
Return lasMaximas & "|" & elMonto
|
||||
else if accion.ToUpperCase = "PRODMENOS" Then 'Regresa descuentosMaximas y elMonto separadas por un "|"
|
||||
If logger Then Log("LaCANT= " & laCant & ", elMonto= " & elMonto)
|
||||
If laCant >= 0 Then
|
||||
modTrendSpending("suma", "descuentos", elMonto) ' Agregamos al presupuesto de hoy (restamos del acumulado).
|
||||
End If
|
||||
Return lasMaximas & "|" & elMonto
|
||||
else if accion.ToUpperCase = "TEXTCHANGED" Then
|
||||
If logger Then Log("TC")
|
||||
else if accion.ToUpperCase = "FOCUSCHANGED" Then 'Regresa descuentos maximas, SOLO correr esta parte si HASFOCUS es VERDADERO.
|
||||
If logger Then Log("FC")
|
||||
Private elMonto As String = traePrecio(id)*(traeDescXSku(clienteId, id)/100)
|
||||
If elMonto > 0 Then 'And HasFocus
|
||||
If logger Then Log("LA BONIFICACION: " & elMonto)
|
||||
Private tsRestantes As String = (TS_DESCUENTOS(0) - TS_DESCUENTOS(1) - traeAcumuladoHoyTS("descuentos"))
|
||||
If logger Then Log("Monto del PRESUPUESTO disponible: " & tsRestantes)
|
||||
lasMaximas = ((laCant * elMonto) + tsRestantes) / elMonto
|
||||
If logger Then Log("tsMaximas: " & lasMaximas)
|
||||
End If
|
||||
Return lasMaximas
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
|
||||
' Trae el precio del RMI desde CAT_RMI.
|
||||
Sub traePrecioRMI(id As String) As String
|
||||
Private precio As String = "0"
|
||||
Private c As Cursor = tsdb.ExecQuery($"select cat_monto from cat_rmi where cat_id = '${id}'"$)
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
precio = c.GetString("CAT_MONTO")
|
||||
End If
|
||||
Return precio
|
||||
End Sub
|
||||
|
||||
' Traemos el monto (descuento total) del producto actual.
|
||||
' Utiliza el descuento de condiciones comerciales por SKU (tabla CAT_DESCUENTOS).
|
||||
Sub traeMonto(clienteId As String, id As String) As String
|
||||
Private tsMonto As String
|
||||
tsMonto = NumberFormat2(traePrecio(id)*(traeDescXSku(clienteId, id)/100), 1, 2, 2, False)
|
||||
Return tsMonto
|
||||
End Sub
|
||||
|
||||
' Trae la cantidad máxima de rmis, bonificaciones o descuentos por presupuesto.
|
||||
Sub traeMaximas(tipo As String, clienteId As String, id As String, laCant As String, promoId As String) As Int
|
||||
Private tsMaximas As Int = 10000000
|
||||
Private tsRestantes As String = 0
|
||||
Private tsMonto As String '= traeMonto(clienteId, id)
|
||||
' If tsMonto > 0 Then
|
||||
If tipo.ToUpperCase = "DESCUENTOS" Then
|
||||
tsMonto = NumberFormat2(traePrecio(id)*(traeDescXSku(clienteId, id)/100), 1, 2, 2, False)
|
||||
tsRestantes = (TS_DESCUENTOS(0) - TS_DESCUENTOS(1) - traeAcumuladoHoyTS("descuentos")) ' Traemos monto restante de Trend Spending para descuentos.
|
||||
else If tipo.ToUpperCase = "RMI" Then
|
||||
tsMonto = NumberFormat2(traePrecioRMI(id), 1, 2, 2, False)
|
||||
tsRestantes = (TS_RMI(0) - TS_RMI(1) - traeAcumuladoHoyTS("rmi")) ' Traemos monto restante de Trend Spending para rmis.
|
||||
' else If tipo.ToUpperCase = "BONIFICACIONES" Then
|
||||
' tsMonto = NumberFormat2(traeMontoBonificacion(id, promoId), 1, 2, 2, False)
|
||||
' tsRestantes = (TS_BONIFICACIONES(0) - TS_BONIFICACIONES(1) - traeAcumuladoHoyTS("bonificaciones")) ' Traemos monto restante de Trend Spending para bonificaciones.
|
||||
End If
|
||||
' Log($"${TS_BONIFICACIONES(0)} - ${TS_BONIFICACIONES(1)} - ${traeAcumuladoHoyTS("bonificaciones")}"$)
|
||||
' Log($"((${laCant} * ${tsMonto}) + ${tsRestantes}) / ${tsMonto}"$)
|
||||
Log($"tsMonto: ${tsMonto}"$)
|
||||
Log($"tsRestantes: ${tsRestantes}"$)
|
||||
tsMaximas = ((laCant * tsMonto) + tsRestantes) / tsMonto
|
||||
' End If
|
||||
Return tsMaximas
|
||||
End Sub
|
||||
|
||||
' Trae la cantidad máxima de productos con bonificacion por presupuesto.
|
||||
' Si el presupuesto es 10 y la bonificacion del producto es 2, el máximo es 5 productos.
|
||||
Sub traeBonificacionesMaximas(tipo As String, clienteId As String, id As String, laCant As String, elPrecioVenta As String, promoId As String) As Int
|
||||
Private thisLog As Boolean = True
|
||||
Private tsMaximas As Int = 100000000
|
||||
Private tsRestantes As String = 0
|
||||
Private tsMonto As String
|
||||
|
||||
Private mx As Map = traeInfoTrendSpending
|
||||
TS_RMI = Regex.Split(",", mx.Get("RMI"))
|
||||
TS_DESCUENTOS = Regex.Split(",", mx.Get("DESCUENTOS"))
|
||||
TS_BONIFICACIONES = Regex.Split(",", mx.Get("BONIFICACIONES"))
|
||||
|
||||
If thisLog Then LogColor($" ============ INICIA BONIFICACIONES MAXIMAS (${id}) ========"$, Colors.RGB(0,197,110))
|
||||
If thisLog Then LogColor($" Presupuesto: ${TS_BONIFICACIONES(0)} - Acumulado ayer: ${TS_BONIFICACIONES(1)} - Hoy: ${traeAcumuladoHoyTS("bonificaciones")}"$, Colors.Magenta)
|
||||
If tipo.ToUpperCase = "BONIFICACIONES" Then
|
||||
tsMonto = NumberFormat2(traeMontoBonificacion(id, elPrecioVenta, promoId, "traeBonificacionesMaximas"), 1, 2, 2, False)
|
||||
tsRestantes = (TS_BONIFICACIONES(0) - TS_BONIFICACIONES(1) - traeAcumuladoHoyTS("bonificaciones")) ' Traemos monto restante de Trend Spending para bonificaciones.
|
||||
Log($" PresupuestoBonifs: ${TS_BONIFICACIONES(0)}, AcumuladoBonifs: ${TS_BONIFICACIONES(1)}, traeAcumuladoHoyTS('bonificaciones'): ${traeAcumuladoHoyTS("bonificaciones")}"$)
|
||||
' Log($" ${TS_BONIFICACIONES(0)} - ${TS_BONIFICACIONES(1)} - ${traeAcumuladoHoyTS("bonificaciones")}"$)
|
||||
End If
|
||||
If thisLog Then Log($" Monto de bonificacion: ${tsMonto}"$)
|
||||
If thisLog Then Log($" Presupuesto disponible: ${tsRestantes}"$)
|
||||
' If thisLog Then Log($"Cantidad: ${laCant}"$)
|
||||
If thisLog Then Log($" Floor(tsRestantes / (tsMonto * laCant)) <==> Floor(${tsRestantes} / (${tsMonto} * ${laCant})) = ${Floor(tsRestantes / (tsMonto * laCant))}"$)
|
||||
' If thisLog Then Log($"Floor(${tsRestantes} / (${tsMonto} * ${laCant}))= ${Floor(tsRestantes / (tsMonto * laCant))}"$)
|
||||
If tsMonto > 0 Then
|
||||
tsMaximas = Floor(tsRestantes / (tsMonto * laCant))
|
||||
End If
|
||||
If thisLog Then LogColor(" ************************************************", Colors.red)
|
||||
If thisLog Then LogColor(" ***** BONIFICACIONES MAXIMAS: " & tsMaximas & " *****", Colors.red)
|
||||
If thisLog Then LogColor(" ************************************************", Colors.red)
|
||||
If thisLog Then LogColor(" ============ TERMINA BONIFICACIONNES MAXIMAS ========", Colors.RGB(0,197,110))
|
||||
Return tsMaximas
|
||||
End Sub
|
||||
|
||||
' Trae el monto de la bonificacion, que es el precio original MENOS el precio de venta con descuento.
|
||||
' - Si CAT_DP_PRECIOB es 1, la bonificacion es: Precio original - precio de venta.
|
||||
' - Si CAT_DP_PRECIOB es 0, la bonificacion es: .
|
||||
Sub traeMontoBonificacion(id As String, precio As String, promoId As String, parent As String) As String
|
||||
Private thisLog As Boolean = True
|
||||
If thisLog Then LogColor($" ============ INICIA MONTO BONIFICACION (${id}) ========"$, Colors.RGB(151,0,171))
|
||||
If thisLog Then LogColor($" ###### ${id}, ${precio}, ${promoId}, ${parent}"$, Colors.Magenta)
|
||||
Private tsMonto As String = 0
|
||||
Private re As Cursor = Starter.skmt.ExecQuery($"select cat_gp_id from cat_gunaprod2 where (cat_gp_tipo like 'REGALO%' or cat_gp_tipo like 'EXHIBIDOR%') and cat_gp_id = '${id}'"$) ' Revisamos si el producto es regalo o exhibidor.
|
||||
If re.RowCount = 0 Then' No es regalo ni exhibidor.
|
||||
Private c As Cursor = tsdb.ExecQuery($"SELECT CAT_DP_ID, CAT_DP_IDPROD, CAT_DP_PRECIO, CAT_DP_TIPO, CAT_GP_PRECIO, CAT_DP_PRECIOB FROM CAT_DETALLES_PAQ join ${traeTablaProds(Starter.tipov)} on CAT_GP_ID = CAT_DP_IDPROD where CAT_GP_ID = '${id}' and CAT_DP_PRECIO = '${precio}' and CAT_DP_ID = '${promoId}'"$)
|
||||
' Log($"SELECT CAT_DP_ID, CAT_DP_IDPROD, CAT_DP_PRECIO, CAT_DP_TIPO, CAT_GP_PRECIO, CAT_DP_PRECIOB FROM CAT_DETALLES_PAQ join ${traeTablaProds(Starter.tipov)} on CAT_GP_ID = CAT_DP_IDPROD where CAT_GP_ID = '${id}' and CAT_DP_PRECIO = '${precio}' and CAT_DP_ID = '${promoId}'"$)
|
||||
If thisLog Then Log($" Rowcount DP y CGP2: ${c.RowCount}"$)
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
LogColor($"Precio original:${c.GetString("CAT_GP_PRECIO")} - Precio Venta:${c.GetString("CAT_DP_PRECIO")}"$, Colors.Blue)
|
||||
If c.GetInt("CAT_DP_PRECIOB") = 1 Or (c.GetInt("CAT_DP_PRECIOB") = 0 And c.GetString("CAT_GP_PRECIO") = c.GetString("CAT_DP_PRECIO")) Then
|
||||
tsMonto = c.GetString("CAT_GP_PRECIO") - c.GetString("CAT_DP_PRECIO") ' Precio original - precio de venta.
|
||||
Else
|
||||
tsMonto = c.GetString("CAT_GP_PRECIO") ' Precio original.
|
||||
End If
|
||||
' Log("PRECIOB: " & c.GetInt("CAT_DP_PRECIOB"))
|
||||
If thisLog Then Log($" Precio normal: ${c.GetString("CAT_GP_PRECIO")}, Precio desc: ${c.GetString("CAT_DP_PRECIO")}, Monto bonificacion: ${tsMonto}"$)
|
||||
End If
|
||||
' Log("ROWCOUNT: " & c.RowCount)
|
||||
End If
|
||||
If thisLog Then LogColor($" ============ TERMINA MONTO BONIFICACION ========"$, Colors.RGB(151,0,171))
|
||||
Return tsMonto
|
||||
End Sub
|
||||
|
||||
' Recibe una lista con los ids de los productos variables, revisa cada id para traer los maximos por presupuesto para ese producto
|
||||
' y pone ese maximo en una lista, luego ordena esa lista para obtener el mas chico y regresa ese como maximo.
|
||||
' esta funcion se va a aplicar en la funcion maxpromos como un limite mas para que no muestre las promociones.
|
||||
' NOTA: hay que ver como y cuando dejar de mostrar promociones cuando quede poco presupuesto para bonificaciones.
|
||||
' NOTA: Talvez se pueda hacer que cuando se entre a PROMOS, si ya no hay presupuesto suficiente, mande un toast o msgbox diciendo que ya
|
||||
' se agoto el presupuesto.
|
||||
' Aunque si hay suficiente para mostrar algunas promos ... pues que si las muestre.
|
||||
Sub maxPromosPorProdsVariables(idProdsVariables As List, promo As String)As Int
|
||||
Private logger As Boolean = True
|
||||
Private Maxs As Int = 10000000
|
||||
Private elPrecio As String = 0
|
||||
Private prodsVariablesXPresupuestoBonificaciones As List
|
||||
Private prodsVariablesRequeridos As Int = traeProdsVariablesRequeridos(promo)
|
||||
prodsVariablesXPresupuestoBonificaciones.Initialize
|
||||
' LogColor("===========> Prods Variables: " & idProdsVariables.Size & " <==========", Colors.red)
|
||||
For i = 0 To idProdsVariables.Size - 1 'Obtenemos total de productos variables disponibes.
|
||||
If logger Then LogColor($"=>> prodVariable ${i} : ${idProdsVariables.Get(i)}, ${Subs.traeProdNombre(idProdsVariables.Get(i))} <<=="$, Colors.blue)
|
||||
' Log($"Este invDisponible: ${invDispParaPromo.Get(idProdsVariables.Get(i))}"$)
|
||||
' If logger Then Log(">> Monto Bonificacion: " & traeMontoBonificacion(idProdsVariables.Get(i), 1, promo))
|
||||
Private ep As Cursor = Starter.skmt.ExecQuery($"select cat_dp_precio from cat_detalles_paq where cat_dp_id = '${promo}' and cat_dp_idprod = '${idProdsVariables.Get(i)}'"$)
|
||||
If ep.RowCount > 0 Then
|
||||
ep.Position = 0
|
||||
Log("=========>>>> " & ep.GetString("CAT_DP_PRECIO"))
|
||||
elPrecio = ep.GetString("CAT_DP_PRECIO")
|
||||
End If
|
||||
Private maxProds As Int = traeBonificacionesMaximas("bonificaciones", traeCliente, idProdsVariables.Get(i), prodsVariablesRequeridos, elPrecio, promo)
|
||||
prodsVariablesXPresupuestoBonificaciones.Add(maxProds)
|
||||
Next
|
||||
prodsVariablesXPresupuestoBonificaciones.Sort(True)
|
||||
If prodsVariablesXPresupuestoBonificaciones.Size > 0 Then
|
||||
Maxs = prodsVariablesXPresupuestoBonificaciones.Get(0)
|
||||
End If
|
||||
If logger Then LogColor("=====>> Max prods variables x monto de bonificaciones: " & Maxs, Colors.blue)
|
||||
Return Maxs
|
||||
End Sub
|
||||
|
||||
' Regresa los productos variables requeridos de la promocion dada.
|
||||
Sub traeProdsVariablesRequeridos(promo As String) As Int
|
||||
Private pvr As Int = 0
|
||||
Private c As Cursor = Starter.skmt.ExecQuery("Select CAT_GP_STS, CAT_GP_NOMBRE from CAT_GUNAPROD2 where CAT_GP_ID = '"& promo & "'") 'Obtenemos las piezas requeridas de productos variables para la promoción.
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
If c.RowCount > 0 Then
|
||||
c.Position = 0
|
||||
pvr = c.GetString("CAT_GP_STS")
|
||||
End If
|
||||
End If
|
||||
c.Close
|
||||
Return pvr
|
||||
End Sub
|
||||
|
||||
|
||||
'########################################################################################
|
||||
' Los productos fijos NO estan restando del presupuesto de BONIFICACIONES
|
||||
'########################################################################################
|
||||
|
||||
'Poner en una funcion (maxPromosPorProdsFijos) el codigo para traer las promos maximas por productos fijos, igual que la de productos
|
||||
' variables, y ponerla igual en "traeMaxPromos" en lugar de en "revisaMaxPromosProdsFijosPorInventario".
|
||||
|
||||
' Falta el codigo para el funcionamiento diferente de las bonificaciones:
|
||||
' Si CAT_DP_PRECIOB es 1 --> (Precio de original (cat_precio) - precio de venta) y se suma al acumulado de BONIFICACIONES
|
||||
' Si CAT_DP_PRECIOB es 0 --> precio orginal se suma al acumulado de BONIFICACIONES
|
||||
'Hay que traer desde web la columna "CAT_DP_PRECIOB" y gardarla en algun lado en movil!!
|
||||
@@ -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
|
||||
@@ -4,167 +4,153 @@ ModulesStructureVersion=1
|
||||
Type=Class
|
||||
Version=12.8
|
||||
@EndOfDesignText@
|
||||
'Class module: jRDC1Wrapper
|
||||
'Version 1.3 - Thread-Safe with ExecuteCommand support
|
||||
'#######################################################################################
|
||||
' Módulo de Clase: jRDC1Wrapper
|
||||
' Versión: 1.9.2 - Thread-Safe, Async Support, B4A Memory Safe, State Persistent & Dynamic Link Support
|
||||
' Autor: Cheve (José Alberto)
|
||||
'
|
||||
' DESCRIPCIÓN:
|
||||
' Este módulo actúa como un "Wrapper" (envoltorio) especializado para DBRequestManager
|
||||
' en entornos jRDC1. Su objetivo principal es modernizar el flujo de trabajo de
|
||||
' versiones antiguas de B4X, permitiendo el uso de la sintaxis "Wait For" en lugar
|
||||
' de depender exclusivamente del evento JobDone global.
|
||||
'
|
||||
' Ejemplo de uso:
|
||||
|
||||
' Dim reqManagerW As DBRequestManagerW
|
||||
' reqManagerW.Initialize
|
||||
' cmd.Initialize
|
||||
' cmd.Name = "selectAlgoDeAlgunLado"
|
||||
' cmd.Parameters = Array As Object(user.Text, pass.Text)
|
||||
' reqManagerW.ExecuteQuery(Starter.DBReqServer, cmd, Me, "loSeleccionado")
|
||||
' Wait For loSeleccionado_Completed (res1 As TResultado)
|
||||
' Log("tag: " & res1.tag & " Success: " & res1.Success)
|
||||
' If res1.Success Then
|
||||
' Subs.logJobDoneResultados(res1.resultado)
|
||||
' Else
|
||||
' Log(res1.ErrorMessage)
|
||||
' End If
|
||||
'#######################################################################################
|
||||
|
||||
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
|
||||
|
||||
' Instancia centralizada.
|
||||
Private reqManager As DBRequestManager
|
||||
|
||||
' Rastreo del EndPoint activo para evitar reinicializaciones redundantes
|
||||
Private currentActiveLink As String = ""
|
||||
End Sub
|
||||
|
||||
'Initializes the object.
|
||||
Public Sub Initialize
|
||||
'C <<< Inicializamos el mapa y el contador
|
||||
activeJobs.Initialize
|
||||
If activeJobs.IsInitialized = False Then
|
||||
activeJobs.Initialize
|
||||
End If
|
||||
jobCounter = 0
|
||||
currentActiveLink = ""
|
||||
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 = "reqManagerWJob_" & jobCounter
|
||||
currentJobTag = Event
|
||||
Dim currentJobTag As String = $"reqManagerWJob_${DateTime.Now}_${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
|
||||
' Actualización dinámica de EndPoint solo si el Link cambió
|
||||
If reqManager.IsInitialized = False Or currentActiveLink <> rdcLink Then
|
||||
reqManager.Initialize(Me, rdcLink)
|
||||
currentActiveLink = rdcLink
|
||||
End If
|
||||
|
||||
Dim jobInfo As TJobInfo
|
||||
jobInfo.Initialize
|
||||
jobInfo.Target = Target
|
||||
jobInfo.EventName = Event
|
||||
jobInfo.IsQuery = True ' Mark as query job
|
||||
jobInfo.IsQuery = True
|
||||
|
||||
'<<< 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)
|
||||
reqManager.ExecuteQuery(Command, 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 = "reqManagerWJob_" & jobCounter
|
||||
currentJobTag = Event
|
||||
Dim currentJobTag As String = $"reqManagerWJob_${DateTime.Now}_${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
|
||||
' Actualización dinámica de EndPoint solo si el Link cambió
|
||||
If reqManager.IsInitialized = False Or currentActiveLink <> rdcLink Then
|
||||
reqManager.Initialize(Me, rdcLink)
|
||||
currentActiveLink = rdcLink
|
||||
End If
|
||||
|
||||
Dim jobInfo As TJobInfo
|
||||
jobInfo.Initialize
|
||||
jobInfo.Target = Target
|
||||
jobInfo.EventName = Event
|
||||
jobInfo.IsQuery = False ' Mark as command job
|
||||
jobInfo.IsQuery = False
|
||||
|
||||
'<<< 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)
|
||||
reqManager.ExecuteCommand(Command, currentJobTag)
|
||||
End Sub
|
||||
|
||||
'This sub will be called by the DBRequestManager when the job is done
|
||||
Public Sub JobDone(job As HttpJob)
|
||||
Log("===== JDDBRW =====")
|
||||
LogColor("JobDone: '" & reqManager.HandleJob(job).tag & "' - Registros: " & reqManager.HandleJob(job).Rows.Size, Colors.Green) 'Mod por CHV - 211110
|
||||
'<<< 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)
|
||||
If logger Then Log("===== JDDBRW =====")
|
||||
Dim currentJobTag As String = ""
|
||||
|
||||
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)
|
||||
If job <> Null And job.Tag <> Null And job.Tag Is String Then
|
||||
currentJobTag = job.Tag
|
||||
End If
|
||||
|
||||
If activeJobs.ContainsKey(currentJobTag) Then
|
||||
|
||||
Dim jobInfo As TJobInfo = activeJobs.Get(currentJobTag)
|
||||
Dim res As TResultado
|
||||
res.Initialize
|
||||
res.Tag = jobInfo.EventName
|
||||
|
||||
If job.Success Then
|
||||
Dim dbResult As DBResult = reqManager.HandleJob(job)
|
||||
If logger Then LogColor("JobDone: '" & dbResult.tag & "' - Registros: " & dbResult.Rows.Size, Colors.Green)
|
||||
res.Success = True
|
||||
res.resultado = dbResult
|
||||
res.ErrorMessage = ""
|
||||
Else
|
||||
res.Success = False
|
||||
res.resultado = Null
|
||||
res.ErrorMessage = job.ErrorMessage
|
||||
End If
|
||||
|
||||
activeJobs.Remove(currentJobTag)
|
||||
|
||||
If logger Then LogColor($"EVENTO: ${jobInfo.EventName}_Completed"$, Colors.Magenta)
|
||||
CallSubDelayed2(jobInfo.Target, jobInfo.EventName & "_Completed", res)
|
||||
|
||||
Else
|
||||
If logger Then Log($"JobDone: Job descartado (Tag desconocido o nulo): ${currentJobTag}"$)
|
||||
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)
|
||||
If logger Then LogColor("Error Crítico en jRDC1Wrapper.JobDone: " & LastException, Colors.Red)
|
||||
|
||||
If currentJobTag <> "" And activeJobs.ContainsKey(currentJobTag) Then
|
||||
Dim jobInfo As TJobInfo = activeJobs.Get(currentJobTag)
|
||||
Dim resErr As TResultado
|
||||
resErr.Initialize
|
||||
resErr.Tag = jobInfo.EventName
|
||||
resErr.Success = False
|
||||
resErr.ErrorMessage = "Error interno procesando la respuesta DB: " & LastException.Message
|
||||
|
||||
activeJobs.Remove(currentJobTag)
|
||||
CallSubDelayed2(jobInfo.Target, jobInfo.EventName & "_Completed", resErr)
|
||||
End If
|
||||
End Try
|
||||
|
||||
If job <> Null Then job.Release
|
||||
End Sub
|
||||
Binary file not shown.
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.
File diff suppressed because one or more lines are too long
@@ -26,6 +26,7 @@ ModuleBookmarks30=
|
||||
ModuleBookmarks31=
|
||||
ModuleBookmarks32=
|
||||
ModuleBookmarks33=
|
||||
ModuleBookmarks34=
|
||||
ModuleBookmarks4=
|
||||
ModuleBookmarks5=
|
||||
ModuleBookmarks6=
|
||||
@@ -60,6 +61,7 @@ ModuleBreakpoints30=
|
||||
ModuleBreakpoints31=
|
||||
ModuleBreakpoints32=
|
||||
ModuleBreakpoints33=
|
||||
ModuleBreakpoints34=
|
||||
ModuleBreakpoints4=
|
||||
ModuleBreakpoints5=
|
||||
ModuleBreakpoints6=
|
||||
@@ -67,39 +69,40 @@ ModuleBreakpoints7=
|
||||
ModuleBreakpoints8=
|
||||
ModuleBreakpoints9=
|
||||
ModuleClosedNodes0=
|
||||
ModuleClosedNodes1=2,3,6,10,11,12,13,14,15,16,18,19,20,21,22,23,24,25,26,27,28,29,31,33,34,35,37,38,39,40,41,42,43,45,46,47
|
||||
ModuleClosedNodes1=
|
||||
ModuleClosedNodes10=
|
||||
ModuleClosedNodes11=
|
||||
ModuleClosedNodes12=
|
||||
ModuleClosedNodes13=8,9,11,12
|
||||
ModuleClosedNodes14=1,2
|
||||
ModuleClosedNodes13=42,43
|
||||
ModuleClosedNodes14=
|
||||
ModuleClosedNodes15=
|
||||
ModuleClosedNodes16=3,8,17
|
||||
ModuleClosedNodes16=2,7,8,9
|
||||
ModuleClosedNodes17=
|
||||
ModuleClosedNodes18=
|
||||
ModuleClosedNodes19=7,8,9,10,11,12,13,14
|
||||
ModuleClosedNodes19=
|
||||
ModuleClosedNodes2=
|
||||
ModuleClosedNodes20=3,4
|
||||
ModuleClosedNodes20=
|
||||
ModuleClosedNodes21=
|
||||
ModuleClosedNodes22=
|
||||
ModuleClosedNodes23=
|
||||
ModuleClosedNodes24=
|
||||
ModuleClosedNodes25=
|
||||
ModuleClosedNodes26=24,26,31,32,33,35
|
||||
ModuleClosedNodes26=
|
||||
ModuleClosedNodes27=
|
||||
ModuleClosedNodes28=4
|
||||
ModuleClosedNodes28=
|
||||
ModuleClosedNodes29=
|
||||
ModuleClosedNodes3=
|
||||
ModuleClosedNodes30=
|
||||
ModuleClosedNodes30=3
|
||||
ModuleClosedNodes31=
|
||||
ModuleClosedNodes32=116
|
||||
ModuleClosedNodes32=
|
||||
ModuleClosedNodes33=
|
||||
ModuleClosedNodes4=
|
||||
ModuleClosedNodes34=
|
||||
ModuleClosedNodes4=1,3
|
||||
ModuleClosedNodes5=
|
||||
ModuleClosedNodes6=
|
||||
ModuleClosedNodes7=
|
||||
ModuleClosedNodes8=
|
||||
ModuleClosedNodes9=
|
||||
NavigationStack=C_Principal,cargar_Click,1031,0,Subs,modTrendSpending,2210,3,C_TrendSpending,modTrendSpending,112,2,C_Productos,B4XPage_Appear,236,0,C_TrendSpending,traeDescXSku,59,0,C_TrendSpending,traeInfoTrendSpending,73,2,C_Principal,JobDone,2240,0,Main,Activity_Create,43,0,B4XMainPage,Class_Globals,119,0,B4XMainPage,Initialize,129,0
|
||||
NavigationStack=Subs,parseHTTPError,2013,0,C_Principal,revisaHistNotificaciones,2355,6,C_Principal,enviaHistNotificaciones,2325,6,C_NuevoCliente,Class_Globals,2,0,B4XMainPage,i_engranes_LongClick,745,0,DBRequestManagerW,ExecuteQuery,50,0,DBRequestManagerW,Initialize,42,0,DBRequestManagerW,JobDone,135,6,DBRequestManagerW,Class_Globals,20,0,DBRequestManagerW,ExecuteCommand,105,0
|
||||
SelectedBuild=0
|
||||
VisibleModules=31,1,12,3,32,13,14,20,19,33
|
||||
VisibleModules=32,1,13,4,33,16,34,14,15,24,22
|
||||
|
||||
@@ -115,6 +115,7 @@ Sub Activity_Create(FirstTime As Boolean)
|
||||
End Sub
|
||||
|
||||
Sub Activity_Resume
|
||||
B4XPages.MainPage.aud.guarda("Entrada a MapaRutas")
|
||||
If GPS.GPSEnabled = False Then
|
||||
ToastMessageShow("Debe Activar el GPS del Equipo.", True)
|
||||
StartActivity(GPS.LocationSettingsIntent)
|
||||
@@ -232,6 +233,7 @@ Sub OnInfoWindowClickListener1_click(Marker1 As Marker)
|
||||
Starter.skmt.ExecNonQuery("delete from CUENTAA")
|
||||
Starter.skmt.ExecNonQuery2("INSERT INTO CUENTAA VALUES (?) ", Array As Object(Marker1.Title))
|
||||
Activity.Finish
|
||||
B4XPages.MainPage.aud.guarda($"Clic Tooltip Mapas Ruta: ${Marker1.Title}"$)
|
||||
Subs.iniciaActividad("Cliente")
|
||||
End Sub
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -58,6 +58,7 @@ Sub Process_Globals
|
||||
Dim GUID As String = ""
|
||||
Dim passSupervisor As String = "135###" ' Valor predeterminado DIFERENTE a ""
|
||||
Dim semana As Int = 0
|
||||
dim revisandoNotifiaciones as Boolean = false
|
||||
End Sub
|
||||
|
||||
Sub Service_Create
|
||||
@@ -72,6 +73,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"
|
||||
@@ -85,9 +87,9 @@ Sub Service_Create
|
||||
reqManager.Initialize(Me, DBReqServer) 'Inicializamos reqManager.
|
||||
If Logger Then Log($"Starter reqManager server: ${DBReqServer}"$)
|
||||
'Para los Logs
|
||||
#if RELEASE
|
||||
' #if RELEASE
|
||||
logcat.LogCatStart(Array As String("-v","raw","*:F","B4A:v"), "logcat")
|
||||
#end if
|
||||
' #end if
|
||||
logs.Initialize
|
||||
sesion.Initialize
|
||||
End Sub
|
||||
@@ -123,7 +125,7 @@ Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
|
||||
logs.Append(StackTrace)
|
||||
Subs.revisaBD
|
||||
LogColor(logs, Colors.blue)
|
||||
errorLog.ExecNonQuery($"INSERT INTO errores(fecha, error) VALUES ('${Subs.fechaKMT(DateTime.now)}', '${logs}')"$)
|
||||
skmt.ExecNonQuery($"INSERT INTO errores(fecha, error) VALUES ('${Subs.fechaKMT(DateTime.now)}', '${logs}')"$)
|
||||
LogColor("insertamos Error", Colors.red)
|
||||
StartActivity(errorManager)
|
||||
Return True
|
||||
|
||||
67
B4A/Subs.bas
67
B4A/Subs.bas
@@ -975,7 +975,7 @@ Sub actualizaProducto(cedis As String, costoU As String, cant As String, nombre
|
||||
Private antCant As Int = 0
|
||||
If IsNumber(c.GetInt("PE_CANT")) Then antCant=c.GetInt("PE_CANT")
|
||||
Private difCant As Int = cant - antCant
|
||||
Starter.skmt.ExecNonQuery($"update pedido set pe_cant = ${cant}, pe_costou = ${costoU}, pe_costo_tot = ${NumberFormat2((cant*c.GetString("PE_COSTOU")), 1, 2, 2, False)}, pe_tipo = '${tipoVenta}' where pe_cedis = '${cedis}' and pe_proid = '${prodId}' and pe_cliente = '${clienteId}' "$)
|
||||
Starter.skmt.ExecNonQuery($"update pedido set pe_cant = ${cant}, pe_costou = ${costoU}, pe_costo_tot = ${NumberFormat2((cant*c.GetString("PE_COSTOU")), 1, 2, 2, False)}, pe_tipo = '${tipoVenta}', pe_enviado = 0 where pe_cedis = '${cedis}' and pe_proid = '${prodId}' and pe_cliente = '${clienteId}' "$)
|
||||
If cedis <> "DUR" Then Starter.skmt.ExecNonQuery($"update ${traeTablaProds(tipoVenta)} set cat_gp_almacen = cat_gp_almacen - (${difCant}) where cat_gp_id = '${prodId}' "$)
|
||||
If cant = 0 Then
|
||||
LogColor($"BORRAMOS PRODUCTO - ${prodId}"$, Colors.Red)
|
||||
@@ -1219,7 +1219,7 @@ Sub traeMaxPromos(pm As Map) As Int
|
||||
' If thisLog Then LogColor("==== Historico: "&pm.Get("historico"), Colors.Red)
|
||||
' Log("### PRODS VARIABLES: " & pm.Get("prodsVariables"))
|
||||
Private maxPromosXDescPV As String = B4XPages.MainPage.promos.ts.maxPromosPorProdsVariables(pm.Get("prodsVariables"), pm.Get("id"))
|
||||
' Log("########### " & maxPromosXDescPV)
|
||||
Logcolor("########### maxPromosXDescPV " & maxPromosXDescPV, Colors.Yellow)
|
||||
' If thisLog Then Log(pm)
|
||||
maxPromos.Add(maxPromosXDescPV.As(Int))
|
||||
If pm.Get("historico") = "1" Then maxPromos.Add(pm.Get("maxRecurrente")) 'Si hay historico, agregamos maxRecurrente
|
||||
@@ -1385,7 +1385,7 @@ Sub revisaMaxPromosProdsFijosPorInventario(pm As Map) As Int
|
||||
t.Add(x(0).As(Int)) 'Solo guardamos la parte del entero de la division. (promos por inventario)
|
||||
' If thisLog Then LogColor($" ### T: ${t}"$, Colors.Green) 'promos por inventario
|
||||
If thisLog Then LogColor($" >>>>> PROMOS X PRODS FIJOS (${idProdsFijos.Get(p)}): ${x(0)} <<<<<"$, Colors.red)
|
||||
Log($" >>>>> Monto Bonificacion FIJOS (${idProdsFijos.Get(p)}): "$ & B4XPages.MainPage.promos.ts.traeMontoBonificacion(idProdsFijos.Get(p), idProdsFijosPrecios.Get(p), pm.Get("id")))
|
||||
Log($" >>>>> Monto Bonificacion FIJOS (${idProdsFijos.Get(p)}): "$ & B4XPages.MainPage.promos.ts.traeMontoBonificacion(idProdsFijos.Get(p), idProdsFijosPrecios.Get(p), pm.Get("id"),"LOG_revisaMaxPromosProdsFijosPorInventario"))
|
||||
If thisLog Then LogColor(" >> MAX PRODS FIJOS X BONIFICACIONES: " & B4XPages.MainPage.promos.ts.traeBonificacionesMaximas("bonificaciones", clienteActual, idProdsFijos.Get(p), prodsFijosPiezas.Get(p), idProdsFijosPrecios.Get(p), pm.Get("id")), Colors.blue)
|
||||
t.Add(B4XPages.MainPage.promos.ts.traeBonificacionesMaximas("bonificaciones", clienteActual, idProdsFijos.Get(p), prodsFijosPiezas.Get(p), idProdsFijosPrecios.Get(p), pm.Get("id"))) 'Agregamos las promos disponibles por Trade Spending
|
||||
If thisLog Then LogColor($" ### PROMOS X INV: ${t}"$, Colors.Green) 'promos por inventario
|
||||
@@ -1594,7 +1594,7 @@ Sub borraPedidoClienteActual As String
|
||||
Log("precioConDesc: " & precioConDesc)
|
||||
Log(">>>>>>>>>>>>> " & (precioConDesc * thisC.GetString("PE_CANT")))
|
||||
If Not(IsNumber(thisC.GetString("PE_CEDIS"))) Then ' Si es promo, entonces es bonificacion.
|
||||
Private desc As String = B4XPages.MainPage.promos.ts.traeMontoBonificacion(thisC.GetString("PE_PROID"), thisC.GetString("PE_COSTOU"), thisC.GetString("PE_CEDIS"))
|
||||
Private desc As String = B4XPages.MainPage.promos.ts.traeMontoBonificacion(thisC.GetString("PE_PROID"), thisC.GetString("PE_COSTOU"), thisC.GetString("PE_CEDIS"),"borraPedidoClienteActual")
|
||||
desc = desc * thisC.GetString("PE_CANT")
|
||||
Log("Regresamos bonificaciones " & thisC.GetString("PE_PROID") & "=" & desc)
|
||||
modTrendSpending("suma", "bonificaciones", desc)
|
||||
@@ -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
|
||||
@@ -2498,32 +2498,51 @@ Public Sub RecalcularInventario
|
||||
' 3. FILTRA (Ignora) los RMIs usando PE_CEDIS <> 'DUR' y el nombre '%CAMBIO%'.
|
||||
' 4. Actualiza CAT_GUNAPROD2 masivamente.
|
||||
|
||||
' Dim sql As String = _
|
||||
' "UPDATE CAT_GUNAPROD2 " & _
|
||||
' "SET CAT_GP_ALMACEN = ( " & _
|
||||
' " SELECT (IFNULL(T5.CAT_GP_ALMACEN, 0) - IFNULL(Ventas.CantidadVendida, 0)) " & _
|
||||
' " FROM CAT_GUNAPROD5 T5 " & _
|
||||
' " LEFT JOIN ( " & _
|
||||
' " SELECT PE_PROID, SUM(PE_CANT) AS CantidadVendida " & _
|
||||
' " FROM PEDIDO " & _
|
||||
' " WHERE PE_CLIENTE <> '0' " & _
|
||||
' " AND PE_CEDIS <> 'DUR' " & _
|
||||
' " AND PE_PRONOMBRE NOT LIKE '%CAMBIO%' " & _
|
||||
' " GROUP BY PE_PROID " & _
|
||||
' " ) Ventas ON T5.CAT_GP_ID = Ventas.PE_PROID " & _
|
||||
' " WHERE T5.CAT_GP_ID = CAT_GUNAPROD2.CAT_GP_ID " & _
|
||||
' ") " & _
|
||||
' "WHERE EXISTS ( " & _ '<-- ESTA ES LA CLAVE QUE EVITA LOS NULLS
|
||||
' " SELECT 1 FROM CAT_GUNAPROD5 T5 " & _
|
||||
' " WHERE T5.CAT_GP_ID = CAT_GUNAPROD2.CAT_GP_ID " & _
|
||||
' ")"
|
||||
|
||||
Dim sql As String = _
|
||||
"UPDATE CAT_GUNAPROD2 " & _
|
||||
"SET CAT_GP_ALMACEN = ( " & _
|
||||
" SELECT (IFNULL(T5.CAT_GP_ALMACEN, 0) - IFNULL(Ventas.CantidadVendida, 0)) " & _
|
||||
" FROM CAT_GUNAPROD5 T5 " & _
|
||||
" LEFT JOIN ( " & _
|
||||
" SELECT PE_PROID, SUM(PE_CANT) AS CantidadVendida " & _
|
||||
" FROM PEDIDO " & _
|
||||
" WHERE PE_CLIENTE <> '0' " & _
|
||||
" AND PE_CEDIS <> 'DUR' " & _
|
||||
" AND PE_PRONOMBRE NOT LIKE '%CAMBIO%' " & _
|
||||
" GROUP BY PE_PROID " & _
|
||||
" ) Ventas ON T5.CAT_GP_ID = Ventas.PE_PROID " & _
|
||||
" WHERE T5.CAT_GP_ID = CAT_GUNAPROD2.CAT_GP_ID " & _
|
||||
") " & _
|
||||
"WHERE EXISTS ( " & _ '<-- ESTA ES LA CLAVE QUE EVITA LOS NULLS
|
||||
" SELECT 1 FROM CAT_GUNAPROD5 T5 " & _
|
||||
" WHERE T5.CAT_GP_ID = CAT_GUNAPROD2.CAT_GP_ID " & _
|
||||
")"
|
||||
"UPDATE CAT_GUNAPROD2 " & _
|
||||
"SET CAT_GP_ALMACEN = ( " & _
|
||||
" SELECT (IFNULL(INV.CI_INVENTARIO, 0) - IFNULL(Ventas.CantidadVendida, 0)) " & _
|
||||
" FROM CAT_INVENTARIO INV " & _
|
||||
" LEFT JOIN ( " & _
|
||||
" SELECT PE_PROID, SUM(PE_CANT) AS CantidadVendida " & _
|
||||
" FROM PEDIDO " & _
|
||||
" WHERE PE_CLIENTE <> '0' " & _
|
||||
" AND PE_CEDIS <> 'DUR' " & _
|
||||
" AND PE_PRONOMBRE NOT LIKE '%CAMBIO%' " & _
|
||||
" GROUP BY PE_PROID " & _
|
||||
" ) Ventas ON INV.CI_IDPROD = Ventas.PE_PROID " & _
|
||||
" WHERE INV.CI_IDPROD = CAT_GUNAPROD2.CAT_GP_ID " & _
|
||||
") " & _
|
||||
"WHERE EXISTS ( " & _
|
||||
" SELECT 1 FROM CAT_INVENTARIO INV " & _
|
||||
" WHERE INV.CI_IDPROD = CAT_GUNAPROD2.CAT_GP_ID " & _
|
||||
")"
|
||||
|
||||
' Ejecutamos el cálculo masivo
|
||||
Starter.skmt.ExecNonQuery(sql)
|
||||
|
||||
Starter.skmt.TransactionSuccessful
|
||||
If Starter.Logger Then Log("Inventario Sincronizado (Excluyendo RMIs)")
|
||||
|
||||
Catch
|
||||
Log("Error al recalcular inventario: " & LastException)
|
||||
End Try
|
||||
|
||||
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,28 +1,127 @@
|
||||
# SCRIPT: _juntaBas.ps1 - Versión Saneada y Optimizada para LLM
|
||||
$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.
|
||||
|
||||
# Eliminar el archivo anterior si existe (IMPORTANTE)
|
||||
Remove-Item -Path $OutputFile -ErrorAction SilentlyContinue
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
$Dir = Get-Location
|
||||
$LT = [char]60; $GT = [char]62; $SL = [char]47
|
||||
$NL = [Environment]::NewLine
|
||||
|
||||
Write-Host "Iniciando fusion para LLM..."
|
||||
Write-Output '--- GENERANDO MASTER IA DEFINITIVO (FIX ESTRUCTURAL) ---'
|
||||
|
||||
# Itera sobre los archivos .bas, .b4a, .b4j
|
||||
Get-ChildItem -Path ".\*" -Include @("*.bas", "*.b4a", "*.b4j") | ForEach-Object {
|
||||
$currentFile = $_.Name
|
||||
Write-Host "Procesando: $currentFile"
|
||||
# 1. PARSEO DEL PROYECTO .B4A
|
||||
$b4a = Get-ChildItem -Path ".\*" -Include "*.b4a" -Recurse | Select-Object -First 1
|
||||
$Name = 'App'; $Ver = '0.0'; $ModulosValidos = @(); $Librerias = @()
|
||||
|
||||
# --- ENCABEZADO ESTRUCTURADO Y COMENTADO EN B4X (Agregado al archivo) ---
|
||||
Add-Content -Path $OutputFile -Value "`n'======================================================================================"
|
||||
Add-Content -Path $OutputFile -Value $"// ARCHIVO_INICIO: ${currentFile}"
|
||||
Add-Content -Path $OutputFile -Value "'======================================================================================`n"
|
||||
|
||||
# Vuelca el contenido del archivo
|
||||
Get-Content -Encoding UTF8 -Path $_.FullName -Raw | Add-Content -Path $OutputFile
|
||||
|
||||
# --- DELIMITADOR DE FIN DE ARCHIVO (Agregado al archivo) ---
|
||||
Add-Content -Path $OutputFile -Value "`n'======================================================================================"
|
||||
Add-Content -Path $OutputFile -Value $"// ARCHIVO_FIN: ${currentFile}"
|
||||
Add-Content -Path $OutputFile -Value "'======================================================================================`n"
|
||||
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() }
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "`nProceso terminado. Se ha creado el archivo: $OutputFile"
|
||||
$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