- VERSION 5.09.10

- Se escondio el boton de NoVenta en cliente hata tener ubicacion.
- Se habilitó los clientes nuevos POR RUTA, en la tabla "CLIENTES_NUEVOS_X_RUTA", y si ya llegaron a limite, se "deshabilita" el boton en principal.
- Se corrige que para Trade Spending, estaba todavia la ruta y almacen en duro.
This commit is contained in:
2025-09-17 18:51:37 -06:00
parent d54ebd7994
commit ae8ac63b1d
9 changed files with 369 additions and 76 deletions

View File

@@ -120,6 +120,7 @@ Sub Class_Globals
' Type TResultado(Tag As String, Success As Boolean, resultado As DBResult, ErrorMessage As String) ' Type TResultado(Tag As String, Success As Boolean, resultado As DBResult, ErrorMessage As String)
Private Label4 As Label Private Label4 As Label
Private clicked As Int = 0 Private clicked As Int = 0
Dim linker As C_deviceLinker
End Sub End Sub
Public Sub Initialize Public Sub Initialize
@@ -395,9 +396,10 @@ End Sub
Sub B4XPage_Appear Sub B4XPage_Appear
Log(">>>>>> APPEAR - INICIAMOS MAIN PAGE <<<<<<<<<") Log(">>>>>> APPEAR - INICIAMOS MAIN PAGE <<<<<<<<<")
linker.Initialize(Me, "Linker", True)
clicked = 0 clicked = 0
If Not(MES1.IsInitialized) Then MES1.Initialize(Me, "MES1") If Not(MES1.IsInitialized) Then MES1.Initialize(Me, "MES1")
Log(DateTime.GetDayOfWeek(DateTime.Now)) ' Log(DateTime.GetDayOfWeek(DateTime.Now))
kh.RD_Init kh.RD_Init
kh.SetButtonTintList(cb_geocerca, Colors.LightGray, Colors.RGB(43, 154, 211)) kh.SetButtonTintList(cb_geocerca, Colors.LightGray, Colors.RGB(43, 154, 211))
kh.SetButtonTintList(cb_cartaPorte, Colors.LightGray, Colors.RGB(43, 154, 211)) kh.SetButtonTintList(cb_cartaPorte, Colors.LightGray, Colors.RGB(43, 154, 211))
@@ -465,7 +467,7 @@ Sub B4XPage_Appear
cmd.Name = "select_fecha" cmd.Name = "select_fecha"
' cmd.Parameters = Array As Object(Null) ' cmd.Parameters = Array As Object(Null)
reqManager.ExecuteQuery(cmd , 0, "fecha") reqManager.ExecuteQuery(cmd , 0, "fecha")
Log("############### APPEAR PAGE ####################") Log("############### PAGE_APPEAR ####################")
Log(MES1.IsInitialized) Log(MES1.IsInitialized)
If MES1.IsInitialized Then If MES1.IsInitialized Then
LogColor("Permisos de almacenamiento: " & MES1.HasPermission, Colors.Magenta) LogColor("Permisos de almacenamiento: " & MES1.HasPermission, Colors.Magenta)
@@ -1033,15 +1035,18 @@ End Sub
Private Sub ImageView1_LongClick Private Sub ImageView1_LongClick
' Log("###### TRAEMOS FECHA #######") ' Log("###### TRAEMOS FECHA #######")
' GetFecha ' GetFecha
Log("traeConexion") ' Log("traeConexion")
Private reqManagerX As DBRequestManager ' Private reqManagerX As DBRequestManager
reqManagerX.Initialize(Me, "http://keymon.net:9010/DB2") ' reqManagerX.Initialize(Me, "http://keymon.net:9010/DB2")
Private cmdX As DBCommand ' Private cmdX As DBCommand
cmdX.Initialize ' cmdX.Initialize
cmdX.Name = "traeConexion" ' cmdX.Name = "traeConexion"
cmdX.Parameters = Array As Object() ' cmdX.Parameters = Array As Object()
reqManagerX.ExecuteQuery(cmdX, 0, "traeConexion") ' reqManagerX.ExecuteQuery(cmdX, 0, "traeConexion")
If Subs.traeAlmacen <> "" Then
linker.VerifyAndLinkDevice(Subs.traeAlmacen, Subs.traeRuta)
End If
End Sub End Sub
Sub ponUsuario Sub ponUsuario
@@ -1060,3 +1065,33 @@ Private Sub Label4_Click
ponUsuario ponUsuario
End If End If
End Sub End Sub
Sub Linker_Response(Status As String) ' << AÑADE ESTE SUB [New Query]
If Starter.Logger Then LogColor($"Respuesta de DeviceLinker para la verificación del dispositivo: ${Status}"$, Colors.Magenta) '
Select Status
Case "UUID_ERROR"
ToastMessageShow("Error interno al obtener el identificador único del dispositivo.", True)
Case "HTTP_ERROR"
LogColor("Error HTTP al verificar el dispositivo: " & linker.lastJobDoneError, Colors.Red)
ToastMessageShow("Error de conexión al servidor durante la verificación del dispositivo.", True)
Case "SERVER_LOGIC_ERROR"
ToastMessageShow("El servidor no proporcionó un estado de verificación válido. Contacte a soporte.", True)
Case "OK"
If Starter.Logger Then Log("Dispositivo ligado y verificado exitosamente.")
ToastMessageShow("Dispositivo verificado y ligado correctamente.", False)
' Aquí puedes añadir lógica adicional si la verificación es exitosa, por ejemplo, habilitar ciertos botones o continuar con el flujo normal.
Case "NO_REGISTRADO"
If Starter.Logger Then Log("Dispositivo NO registrado.")
ToastMessageShow("Dispositivo NO registrado.", False)
Case "REGISTRO_NUEVO"
If Starter.Logger Then Log("¡¡Registro nuevo!!")
ToastMessageShow("¡¡Registro nuevo!!", False)
Case "ALREADY_REGISTERED"
If Starter.Logger Then Log("¡¡El dispositivo ya esta registrado con otra ruta!!")
ToastMessageShow("¡¡El dispositivo ya esta registrado con otra ruta!!", True)
Case Else ' Otros estados que tu servidor pueda devolver (ej. "UNAUTHORIZED", "PENDING_APPROVAL")
If Starter.Logger Then Log($"Estado de verificación del dispositivo: ${Status}"$)
ToastMessageShow($"Verificación del dispositivo: ${Status}"$, True)
' Puedes decidir si bloquear la funcionalidad o mostrar un mensaje específico según el estado.
End Select
End Sub

View File

@@ -405,6 +405,7 @@ End Sub
Sub B4XPage_Appear Sub B4XPage_Appear
indicePregunta = 0 indicePregunta = 0
b_noVenta.Enabled = False b_noVenta.Enabled = False
Log("NoVenta False")
' Log(kh.traeTotalCliente) ' Log(kh.traeTotalCliente)
If kh.traeTotalCliente = 0 Then b_noVenta.Enabled = True If kh.traeTotalCliente = 0 Then b_noVenta.Enabled = True
clienteId = kh.traeCliente clienteId = kh.traeCliente
@@ -414,6 +415,7 @@ Sub B4XPage_Appear
' Log($"TOTAL VENTA: ${kh.traeTotalCliente}"$) ' Log($"TOTAL VENTA: ${kh.traeTotalCliente}"$)
B_VENTA.Visible = False B_VENTA.Visible = False
b_noVenta.Visible = False b_noVenta.Visible = False
Log("NoVenta False")
If clienteId.StartsWith("N") Then b_noVenta.Visible = False If clienteId.StartsWith("N") Then b_noVenta.Visible = False
l_doe.Text = "HAY PEDIDO DOE" l_doe.Text = "HAY PEDIDO DOE"
' Log(Starter.rp.Check("android.permission.BLUETOOTH_CONNECT")) ' Log(Starter.rp.Check("android.permission.BLUETOOTH_CONNECT"))
@@ -545,9 +547,13 @@ Sub B4XPage_Appear
End If End If
If kh.traeTotalCliente < 0.01 And kh.traeTotalClienteDOE < 0.01 Then If kh.traeTotalCliente < 0.01 And kh.traeTotalClienteDOE < 0.01 Then
If Not(clienteId.StartsWith("N")) And la_cuenta.Text <> "0" Then b_noVenta.Visible = True 'Ni cliente nuevo, ni abordo. If Not(clienteId.StartsWith("N")) And la_cuenta.Text <> "0" Then
' b_noVenta.Visible = True 'Ni cliente nuevo, ni abordo. ... Si apagan el GPS, y este esta habilitado, les da tiempo de meter NoVenta aun estando fuera de la geocerca.
' Log("NoVenta True")
End If
Else Else
b_noVenta.Visible = False b_noVenta.Visible = False
Log("NoVenta False")
If la_cuenta.text = 0 Then If la_cuenta.text = 0 Then
CREDITO_DISPONIBLE = 10000000 CREDITO_DISPONIBLE = 10000000
CREDITO = 0 CREDITO = 0
@@ -681,7 +687,10 @@ Sub B4XPage_Appear
c = Starter.skmt.ExecQuery("select count(*) as conNoVenta FROM NOVENTA WHERE NV_CLIENTE IN (Select CUENTA from cuentaa)") c = Starter.skmt.ExecQuery("select count(*) as conNoVenta FROM NOVENTA WHERE NV_CLIENTE IN (Select CUENTA from cuentaa)")
c.Position = 0 c.Position = 0
If c.GetString("conNoVenta") = 1 Then b_noVenta.Visible = False 'Si ya tiene NoVenta, ocultamos el boton. If c.GetString("conNoVenta") = 1 Then
b_noVenta.Visible = False 'Si ya tiene NoVenta, ocultamos el boton.
Log("NoVenta False")
End If
c.Close c.Close
Else Else
RutaBoleta=Starter.rutaV RutaBoleta=Starter.rutaV
@@ -899,10 +908,14 @@ Sub GPS_LocationChanged (Location1 As Location)
' If gps_boton_doe = "1" And clienteConPromo = "0" And revisaExistenciasDOE Then b_whats.Visible = True ' If gps_boton_doe = "1" And clienteConPromo = "0" And revisaExistenciasDOE Then b_whats.Visible = True
If Not(clienteDeudor) Then B_VENTA.Visible = True 'Si el cliente no tiene adeudo, habilitamos el boton de venta If Not(clienteDeudor) Then B_VENTA.Visible = True 'Si el cliente no tiene adeudo, habilitamos el boton de venta
If Not(clienteId.StartsWith("N")) And la_cuenta.Text <> "0" Then b_noVenta.Visible = True 'Ni cliente nuevo, ni abordo. If Not(clienteId.StartsWith("N")) And la_cuenta.Text <> "0" Then
b_noVenta.Visible = True 'Ni cliente nuevo, ni abordo.
Log("NoVenta False")
End If
If Not(p_rechazoDOE.Visible) Then pedido_doe_muestra If Not(p_rechazoDOE.Visible) Then pedido_doe_muestra
Else Else
b_noVenta.Visible = False b_noVenta.Visible = False
Log("NoVenta False")
B_VENTA.Visible = False B_VENTA.Visible = False
b_whats.Visible = False b_whats.Visible = False
End If End If

View File

@@ -51,6 +51,7 @@ 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 B4XPage_Appear Sub B4XPage_Appear
b_guardar.Visible = False
b_guardar.Enabled = False b_guardar.Enabled = False
permitirCtesNuevos = True permitirCtesNuevos = True
b_guardar.Text = "Sin Ubicación ..." b_guardar.Text = "Sin Ubicación ..."
@@ -61,22 +62,24 @@ Sub B4XPage_Appear
c.Position = 0 c.Position = 0
maxClientesNuevos = c.GetString("CAT_VA_VALOR") maxClientesNuevos = c.GetString("CAT_VA_VALOR")
End If End If
' Log("MaxClientesNuevos: " & maxClientesNuevos) Log("MaxClientesNuevos: " & maxClientesNuevos)
'Para el almacen 12 (GDL) no hay limite de clientes nuevos. 'Para el almacen 12 (GDL) no hay limite de clientes nuevos.
If kh.traeAlmacen = 12 Then maxClientesNuevos = 0 ' If kh.traeAlmacen = 12 Then maxClientesNuevos = 0
If maxClientesNuevos <> 0 Then If maxClientesNuevos <> 0 Then
Private d As Cursor = Starter.skmt.ExecQuery($"select count(CAT_CL_CODIGO) as ctesNuevos from kmt_info where CAT_CL_CODIGO like 'N%'"$) Private d As Cursor = Starter.skmt.ExecQuery($"select count(CAT_CL_CODIGO) as ctesNuevos from kmt_info where CAT_CL_CODIGO like 'N%'"$)
If d.RowCount > 0 Then If d.RowCount > 0 Then
d.Position = 0 d.Position = 0
' Log($"Clientes nuevos actuales: ${d.GetString("ctesNuevos")}"$) Log($"Clientes nuevos actuales: ${d.GetString("ctesNuevos")}"$)
If d.GetString("ctesNuevos") >= maxClientesNuevos Then If d.GetString("ctesNuevos") >= maxClientesNuevos Then
b_guardar.Enabled = False b_guardar.Enabled = False
permitirCtesNuevos = False permitirCtesNuevos = False
ToastMessageShow("¡Ha alcanzado el LIMITE de usuarios nuevos por día!", True) ToastMessageShow("¡Ha alcanzado el LIMITE de usuarios nuevos por día!", True)
End If End If
End If End If
Else
b_guardar.Visible = True
End If End If
End Sub End Sub
@@ -87,6 +90,7 @@ Sub GPS_LocationChanged (Location1 As Location)
b_guardar.Enabled = False b_guardar.Enabled = False
Else Else
b_guardar.Enabled = True b_guardar.Enabled = True
b_guardar.Visible = True
End If End If
b_guardar.Text = "Guardar" b_guardar.Text = "Guardar"
End Sub End Sub
@@ -128,7 +132,7 @@ Sub b_guardar_Click
Starter.skmt.ExecNonQuery2("INSERT INTO CUENTAA VALUES (?)", Array As Object(no_cliente)) Starter.skmt.ExecNonQuery2("INSERT INTO CUENTAA VALUES (?)", Array As Object(no_cliente))
Subs.iniciaActividad("cliente") Subs.iniciaActividad("cliente")
Else Else
ToastMessageShow("No hay clientes para visitar el día de hoy.", true) ToastMessageShow("No hay clientes para visitar el día de hoy.", True)
End If End If
End If End If
End Sub End Sub

View File

@@ -548,8 +548,13 @@ Sub B4XPage_Appear
NUEVO.Enabled = True NUEVO.Enabled = True
B_PROXIMA.Enabled = True B_PROXIMA.Enabled = True
End If End If
' LogColor("REVISAMOS GUID", Colors.red) kh.traeMaxClientesNuevos
' Subs.generaGUID_EnExterno Private n As Cursor = Starter.skmt.ExecQuery("select count(*) as cuantos from kmt_info where cat_cl_codigo like 'N%'")
n.Position = 0
Log(n.GetString("cuantos"))
If n.GetString("cuantos") >= kh.traeMaxClientesNuevos Then NUEVO.Enabled = False
LogColor(">>>>>>>> REVISAMOS GUID <<<<<<<<<", Colors.red)
Subs.generaGUID_EnExterno
End Sub End Sub
Sub trabajar_Click Sub trabajar_Click
@@ -842,6 +847,34 @@ Sub cargar_Click
Log(r.ErrorMessage) Log(r.ErrorMessage)
End If End If
'Autorizacion para crear clientes nuevos
cmd.Initialize
cmd.Name = "autorizacionClientesNuevos"
cmd.Parameters = Array As Object(ALMACEN, e_ruta.text)
reqManagerW.ExecuteQuery(Starter.DBReqServer, cmd, Me, "autorizacionClientesNuevos")
Wait For autorizacionClientesNuevos_Completed (r0 As TResultado)
Log("tag: " & r0.tag & " Success: " & r0.Success)
If r0.Success Then
Subs.logJobDoneResultados(r0.resultado)
Private result As DBResult = r0.resultado
cargar.Enabled = True
' Log("TIEMPO kmt_datos : " & ((DateTime.Now-inicioContador)/1000))
' S_CC.TEXT = "CARGANDO"
Starter.skmt.BeginTransaction
For Each records() As Object In result.Rows
Dim CNR_AUTORIZADO As String = records(result.Columns.Get("CNR_AUTORIZADO"))
Dim CNR_CUANTOS_CN As String = records(result.Columns.Get("CNR_CUANTOS_CN"))
Next
Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("CN_AUTORIZADO"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("CN_AUTORIZADO", CNR_AUTORIZADO))
Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("CN_CUANTOS"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("CN_CUANTOS", CNR_CUANTOS_CN))
Starter.skmt.TransactionSuccessful 'Si no se pone TransactionSuccessful no se escribe NADA!!
Starter.skmt.EndTransaction
Else
Log(r0.ErrorMessage)
End If
cmd.Initialize cmd.Initialize
cmd.Name = "select_cat_clientes_guna_KELL2" cmd.Name = "select_cat_clientes_guna_KELL2"
cmd.Parameters = Array As Object(e_ruta.text, ALMACEN) cmd.Parameters = Array As Object(e_ruta.text, ALMACEN)
@@ -892,7 +925,7 @@ Sub cargar_Click
Starter.skmt.ExecNonQuery2("INSERT INTO kmt_info(CAT_CL_CODIGO,CAT_CL_RUTA,CAT_CL_NOMBRE,CAT_CL_ATIENDE1,CAT_CL_ATIENTE2,CAT_CL_TELEFONO,CAT_CL_EMAIL,CAT_CL_CALLE,CAT_CL_NOEXT,CAT_CL_NOINT,CAT_CL_CALLE1,CAT_CL_CALLE2,CAT_CL_COLONIA,CAT_CL_MUNI,CAT_CL_EDO,CAT_CL_CP,CAT_CL_LONG,CAT_CL_LAT,CAT_CL_BFACTURA,CAT_CL_BCREDITO,CAT_CL_MTOCOMPRA,CAT_CL_NUM_SERIEFISICO,CAT_CL_DIAS_VISITA, gestion, IMPRESION) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,0,0,0,?,0,0) ",Array As Object ("0",e_ruta.TEXT, "VENTA ABORDO","null","null","null","null","null","null","null","null","null","null","null","0","null","null","null","10000000","null")) Starter.skmt.ExecNonQuery2("INSERT INTO kmt_info(CAT_CL_CODIGO,CAT_CL_RUTA,CAT_CL_NOMBRE,CAT_CL_ATIENDE1,CAT_CL_ATIENTE2,CAT_CL_TELEFONO,CAT_CL_EMAIL,CAT_CL_CALLE,CAT_CL_NOEXT,CAT_CL_NOINT,CAT_CL_CALLE1,CAT_CL_CALLE2,CAT_CL_COLONIA,CAT_CL_MUNI,CAT_CL_EDO,CAT_CL_CP,CAT_CL_LONG,CAT_CL_LAT,CAT_CL_BFACTURA,CAT_CL_BCREDITO,CAT_CL_MTOCOMPRA,CAT_CL_NUM_SERIEFISICO,CAT_CL_DIAS_VISITA, gestion, IMPRESION) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,0,0,0,?,0,0) ",Array As Object ("0",e_ruta.TEXT, "VENTA ABORDO","null","null","null","null","null","null","null","null","null","null","null","0","null","null","null","10000000","null"))
Starter.skmt.TransactionSuccessful 'Si no se pone TransactionSuccessful no se escribe NADA!! Starter.skmt.TransactionSuccessful 'Si no se pone TransactionSuccessful no se escribe NADA!!
Starter.skmt.EndTransaction Starter.skmt.EndTransaction
LogColor("##################################################################3", Colors.red) ' LogColor("##################################################################3", Colors.red)
Listo1 = 1 Listo1 = 1
S_CC.Text = "LISTO" S_CC.Text = "LISTO"
' ToastMessageShow("Catalogo Clientes Actualizados." , True) ' ToastMessageShow("Catalogo Clientes Actualizados." , True)
@@ -2086,7 +2119,7 @@ Sub JobDone(Job As HttpJob)
Starter.skmt.ExecNonQuery2("INSERT INTO HIST_TREND_SPENDING_SEMANAL (HIST_TSS_RUTA, HIST_TSS_IDALMACEN, HIST_TSS_TIPO, HIST_TSS_SEMANA1, HIST_TSS_SEMANA1_ACUM, HIST_TSS_SEMANA2, HIST_TSS_SEMANA2_ACUM, HIST_TSS_SEMANA3, HIST_TSS_SEMANA3_ACUM, HIST_TSS_SEMANA4, HIST_TSS_SEMANA4_ACUM, HIST_TSS_SEMANA5, HIST_TSS_SEMANA5_ACUM, HIST_TSS_SEMANA6, HIST_TSS_SEMANA6_ACUM, HIST_TSS_GRUPO) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", Array As Object (HIST_TSS_RUTA, HIST_TSS_IDALMACEN, HIST_TSS_TIPO, HIST_TSS_SEMANA1, HIST_TSS_SEMANA1_ACUM, HIST_TSS_SEMANA2, HIST_TSS_SEMANA2_ACUM, HIST_TSS_SEMANA3, HIST_TSS_SEMANA3_ACUM, HIST_TSS_SEMANA4, HIST_TSS_SEMANA4_ACUM, HIST_TSS_SEMANA5, HIST_TSS_SEMANA5_ACUM, HIST_TSS_SEMANA6, HIST_TSS_SEMANA6_ACUM, HIST_TSS_GRUPO)) Starter.skmt.ExecNonQuery2("INSERT INTO HIST_TREND_SPENDING_SEMANAL (HIST_TSS_RUTA, HIST_TSS_IDALMACEN, HIST_TSS_TIPO, HIST_TSS_SEMANA1, HIST_TSS_SEMANA1_ACUM, HIST_TSS_SEMANA2, HIST_TSS_SEMANA2_ACUM, HIST_TSS_SEMANA3, HIST_TSS_SEMANA3_ACUM, HIST_TSS_SEMANA4, HIST_TSS_SEMANA4_ACUM, HIST_TSS_SEMANA5, HIST_TSS_SEMANA5_ACUM, HIST_TSS_SEMANA6, HIST_TSS_SEMANA6_ACUM, HIST_TSS_GRUPO) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", Array As Object (HIST_TSS_RUTA, HIST_TSS_IDALMACEN, HIST_TSS_TIPO, HIST_TSS_SEMANA1, HIST_TSS_SEMANA1_ACUM, HIST_TSS_SEMANA2, HIST_TSS_SEMANA2_ACUM, HIST_TSS_SEMANA3, HIST_TSS_SEMANA3_ACUM, HIST_TSS_SEMANA4, HIST_TSS_SEMANA4_ACUM, HIST_TSS_SEMANA5, HIST_TSS_SEMANA5_ACUM, HIST_TSS_SEMANA6, HIST_TSS_SEMANA6_ACUM, HIST_TSS_GRUPO))
Next Next
LogColor("GUARDAMOS INFO DE TRADE SPENDING", Colors.Blue) LogColor("GUARDAMOS INFO DE TRADE SPENDING", Colors.Blue)
Subs.logJobDoneResultados(RESULT) ' Subs.logJobDoneResultados(RESULT)
ts.Initialize(Me, "ts", Starter.skmt) ts.Initialize(Me, "ts", Starter.skmt)
End If End If
End If End If

193
B4A/C_deviceLinker.bas Normal file
View File

@@ -0,0 +1,193 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=12.8
@EndOfDesignText@
'-----------------------------------------------------------------------------------
' Modulo de Clase: DeviceLinker.bas
' Propósito: Gestionar el GUID del dispositivo y verificar/ligar el dispositivo
' a un almacén y ruta en el servidor de forma segura.
'-----------------------------------------------------------------------------------
Sub Class_Globals
' Configuración del servidor y comandos
Private Const GUID_KEY_ALIAS As String = "DeviceGUID" ' << ALIAS PARA EL GUID EN EL KEYSTORE
' Objetos y variables internas
Private kvs As KeyValueStore ' << ALMACENAMIENTO SEGURO PARA EL GUID
Private CallBack As Object ' << OBJETO DE CALLBACK PARA ENVIAR RESPUESTAS
Private EventName As String ' << NOMBRE DEL EVENTO DE RESPUESTA
Public reqManager As DBRequestManager ' << GESTOR DE PETICIONES AL SERVIDOR jRDC
Private logger As Boolean ' << PARA CONTROLAR LOS LOGS DE ESTA CLASE
Dim lastJobDoneError As String = ""
Dim almacen As String = ""
Dim ruta As String = ""
Dim deviceId As String = ""
' Se requieren las siguientes librerías:
' - KeyValueStore2
' - DBRequestManager
' - XUI
End Sub
' Inicializa la clase DeviceLinker.
' PageObject: El módulo (ej. C_Principal) que inicializa esta clase y manejará sus respuestas (normalmente "Me").
' NameOfEvent: El prefijo para el evento de respuesta (ej. "DeviceLinker_Response").
' AppLogger: Booleano para activar/desactivar los logs internos de esta clase, siguiendo el Starter.Logger de la app.
Public Sub Initialize (PageObject As Object, NameOfEvent As String, AppLogger As Boolean)
CallBack = PageObject
EventName = NameOfEvent
logger = AppLogger ' Asignamos el estado del logger de la aplicación.
' Inicializamos el KeyValueStore para almacenamiento seguro del GUID
kvs.Initialize(File.DirInternal, "DeviceKeyStore.b4xkey")
If logger Then Log("B4XKeyStore 'DeviceKeyStore' inicializado.")
' Inicializamos el DBRequestManager para las comunicaciones con el servidor.
' 'Me' indica que el evento JobDone de esta clase se encargará de las respuestas de reqManager.
' reqManager.Initialize(Me, Starter.DBReqServer)
reqManager.Initialize(Me, "http://keymon.net:9010/DB2") 'Servidor de pruebas
If logger Then Log("DBRequestManager para DeviceLinker inicializado.")
If logger Then Log("DeviceLinker inicializado y listo para operar.")
End Sub
' Verifica y liga el dispositivo con un almacén y una ruta en el servidor.
' Almacen: El identificador del almacén.
' Ruta: El identificador de la ruta.
Public Sub VerifyAndLinkDevice(Almacen_ As String, Ruta_ As String)
Dim DeviceId_ As String = GetDeviceGUID ' Obtenemos o generamos el GUID del dispositivo.
almacen = Almacen_
ruta = Ruta_
deviceId = DeviceId_
If DeviceId_ = "" Then
If logger Then LogColor("Error: GUID del dispositivo no pudo ser obtenido o generado.", Colors.Red)
' Enviar una respuesta de error al callback si no se pudo obtener el GUID.
If SubExists(CallBack, EventName & "_Response") Then ' [New Query]
CallSub2(CallBack, EventName & "_Response", "GUID_ERROR")
End If
Return
End If
If logger Then Log($"Enviando solicitud de verificación para DeviceId: ${DeviceId_}, Almacen: ${Almacen_}, Ruta: ${Ruta_}"$)
Dim cmd As DBCommand ' Creamos un comando para enviar al servidor.
cmd.Initialize
cmd.Name = "verify_device"
' Pasamos el almacén, la ruta y el GUID del dispositivo como parámetros.
cmd.Parameters = Array As Object(Almacen_, Ruta_) ', DeviceId_
' Ejecutamos el comando en el servidor. 'Me' indica que DBRequestManager_JobDone en esta clase manejará la respuesta.
reqManager.ExecuteQuery(cmd, 0, "verify_device")
End Sub
' Obtiene el GUID único del dispositivo desde B4XKeyStore.
' Si no existe, lo genera y lo guarda utilizando Subs.GUID.
Private Sub GetDeviceGUID As String
If kvs.ContainsKey(GUID_KEY_ALIAS) = False Then
' Corrección: Usamos la función GUID ya existente en el módulo Subs [1].
Dim NewGUID As String = generaGUID
kvs.Put(GUID_KEY_ALIAS, NewGUID) ' Lo guardamos de forma segura en el KeyStore.
If logger Then LogColor($"Nuevo GUID generado y guardado: ${NewGUID}"$, Colors.Blue)
Return NewGUID
Else
Dim ExistingGUID As String = kvs.Get(GUID_KEY_ALIAS) ' Recuperamos el GUID existente.
If logger Then LogColor($"GUID existente cargado: ${ExistingGUID}"$, Colors.Blue)
Return ExistingGUID
End If
End Sub
' Callback para manejar las respuestas del DBRequestManager de esta clase.
Public Sub JobDone(Job As HttpJob) ' El nombre del sub debe ser 'JobDone' o el que se haya especificado en reqManager.Initialize(Me, ApiUrl)
If logger Then Log("INICA JOBDONE DEVICELINKER - " & Job.Tag)
If reqManager.reqsList.IsInitialized Then 'Si tenemos lista de requests, la procesamos.
If reqManager.reqsList.IndexOf(Job.tag) <> -1 Then
reqManager.reqsList.RemoveAt(reqManager.reqsList.IndexOf(Job.tag))
LogColor($">>>>>> Recibimos y quitamos ${Job.tag.As(String).ToUpperCase}"$, Colors.Blue)
End If
LogColor(">>>>>> " & reqManager.reqsList.Size & " - " & reqManager.reqsList, Colors.Blue)
End If
If Job.Success = False Then
lastJobDoneError = Job.ErrorMessage
LogColor("############################################", Colors.red)
LogColor("###### JobError: " & Job.Tag & CRLF & Job.ErrorMessage, Colors.red)
LogColor("############################################", Colors.red)
' Enviar una respuesta de error HTTP al callback.
If SubExists(CallBack, EventName & "_Response") Then
CallSub2(CallBack, EventName & "_Response", "HTTP_ERROR")
End If
Else 'If Job Success then ...
lastJobDoneError = ""
If Job.JobName = "DBRequest" Then ' Asegurarse de que sea una respuesta de DBRequestManager.
' Primero verificamos Job.Success para saber si la comunicación HTTP fue exitosa [New Query]
If Job.Success Then
Dim result As DBResult = reqManager.HandleJob(Job) ' Procesamos el HttpJob para obtener el DBResult.
If logger Then LogColor($"Petición exitosa al servidor. Registros devueltos: ${result.Rows.Size}"$, Colors.Green)
If result.Tag = "hist_cliente_promos" Then 'query tag
Starter.skmt.BeginTransaction
For Each records() As Object In result.Rows
Dim HCCP_CLIENTE As String = records(result.Columns.Get("HCCP_CLIENTE"))
Starter.skmt.ExecNonQuery2("INSERT INTO HIST_CLIENTE_CANT_PROMOS(HCCP_CLIENTE, HCCP_PROMO, HCCP_CANT, HCCP_CANT_VENDIDA) VALUES (?,?,?,?)", Array As Object (HCCP_CLIENTE))
Next
Starter.skmt.TransactionSuccessful
Starter.skmt.EndTransaction
' ToastMessageShow(" Historico Clientes Promociones Actualizado." , True)
End If
If result.Tag = "verify_device" Then 'query tag
' Aquí es donde la lógica de la aplicación interpreta el éxito/falla de la operación en el servidor.
' No usamos result.Success porque DBResult no tiene esa propiedad.
' En su lugar, comprobamos si se devolvieron filas y el campo 'status' dentro de los datos.
If result.Rows.Size > 0 Then
Subs.logJobDoneResultados(result)
For Each records() As Object In result.Rows
Dim Status As String = records(result.Columns.Get("ESTATUS"))
Dim GUID As String = records(result.Columns.Get("GUID"))
If deviceId <> GUID Then Status = "ALREADY_REGISTERED" ' Ya existe OTRO registro.
' Invocamos el callback en el módulo principal con el estado.
If SubExists(CallBack, EventName & "_Response") Then
CallSub2(CallBack, EventName & "_Response", Status)
End If
Next
Else
If logger Then LogColor($"El servidor respondió con éxito, pero no encontró registros.${CRLF}Quiere decir que la ruta NO esta registrada en el servidor."$, Colors.Red)
Dim cmd As DBCommand ' Creamos un comando para enviar al servidor.
cmd.Initialize
cmd.Name = "registarMovil"
' Pasamos el almacén, la ruta y el GUID del dispositivo como parámetros.
cmd.Parameters = Array As Object(almacen, ruta, deviceId)
reqManager.ExecuteCommand(cmd, "registramosGUID")
If SubExists(CallBack, EventName & "_Response") Then
CallSub2(CallBack, EventName & "_Response", "NO_REGISTRADO")
End If
End If
End If
If result.Tag = "registramosGUID" Then
Subs.logJobDoneResultados(result)
If SubExists(CallBack, EventName & "_Response") Then
CallSub2(CallBack, EventName & "_Response", "REGISTRO_NUEVO")
End If
End If
End If
End If
Job.Release ' Muy importante liberar el HttpJob para evitar fugas de memoria.
End If
End Sub
'Genera un GUID (globally unique identifier)
Sub generaGUID As String
Dim sb As StringBuilder
sb.Initialize
For Each stp As Int In Array(8, 4, 4, 4, 12)
If sb.Length > 0 Then sb.Append("-")
For n = 1 To stp
Dim c As Int = Rnd(0, 16)
If c < 10 Then c = c + 48 Else c = c + 55
sb.Append(Chr(c))
Next
Next
Return sb.ToString
End Sub

View File

@@ -130,7 +130,7 @@ Public Sub JobDone(job As HttpJob)
job.Release job.Release
'<<< Usamos la información recuperada del mapa para llamar al Sub correcto '<<< Usamos la información recuperada del mapa para llamar al Sub correcto
if logger then LogColor($"EVENTO: ${jobInfo.EventName}_Completed"$, Colors.Magenta) If logger Then LogColor($"EVENTO: ${jobInfo.EventName}_Completed"$, Colors.Magenta)
CallSubDelayed2(jobInfo.Target, jobInfo.EventName & "_Completed", resultado) CallSubDelayed2(jobInfo.Target, jobInfo.EventName & "_Completed", resultado)
Else Else
' Handle command result ' Handle command result
@@ -161,7 +161,7 @@ Public Sub JobDone(job As HttpJob)
'C <<< Se remueve el job del mapa en caso de ÉXITO 'C <<< Se remueve el job del mapa en caso de ÉXITO
activeJobs.Remove(currentJobTag) activeJobs.Remove(currentJobTag)
Catch Catch
if logger then LogColor("Error en jRDC1Wrapper.JobDone: " & LastException, Colors.Red) If logger Then LogColor("Error en jRDC1Wrapper.JobDone: " & LastException, Colors.Red)
'<<< MUY IMPORTANTE: Remover el job del mapa para no tener fugas de memoria '<<< MUY IMPORTANTE: Remover el job del mapa para no tener fugas de memoria
activeJobs.Remove(currentJobTag) activeJobs.Remove(currentJobTag)
End Try End Try

File diff suppressed because one or more lines are too long

View File

@@ -25,6 +25,7 @@ ModuleBookmarks3=
ModuleBookmarks30= ModuleBookmarks30=
ModuleBookmarks31= ModuleBookmarks31=
ModuleBookmarks32= ModuleBookmarks32=
ModuleBookmarks33=
ModuleBookmarks4= ModuleBookmarks4=
ModuleBookmarks5= ModuleBookmarks5=
ModuleBookmarks6= ModuleBookmarks6=
@@ -58,6 +59,7 @@ ModuleBreakpoints3=
ModuleBreakpoints30= ModuleBreakpoints30=
ModuleBreakpoints31= ModuleBreakpoints31=
ModuleBreakpoints32= ModuleBreakpoints32=
ModuleBreakpoints33=
ModuleBreakpoints4= ModuleBreakpoints4=
ModuleBreakpoints5= ModuleBreakpoints5=
ModuleBreakpoints6= ModuleBreakpoints6=
@@ -65,38 +67,39 @@ ModuleBreakpoints7=
ModuleBreakpoints8= ModuleBreakpoints8=
ModuleBreakpoints9= ModuleBreakpoints9=
ModuleClosedNodes0= ModuleClosedNodes0=
ModuleClosedNodes1=4,6 ModuleClosedNodes1=6,8,46,47
ModuleClosedNodes10= ModuleClosedNodes10=
ModuleClosedNodes11=3,5,6 ModuleClosedNodes11=
ModuleClosedNodes12=3,7,8,9,10,11,12 ModuleClosedNodes12=3,5,6
ModuleClosedNodes13=6,7,8,9,12,13 ModuleClosedNodes13=7,8,9,10,11,12
ModuleClosedNodes14= ModuleClosedNodes14=6,7,8,9,12,13
ModuleClosedNodes15=3,7,8,15,17 ModuleClosedNodes15=
ModuleClosedNodes16= ModuleClosedNodes16=3,7,8,15,17
ModuleClosedNodes17= ModuleClosedNodes17=
ModuleClosedNodes18= ModuleClosedNodes18=
ModuleClosedNodes19= ModuleClosedNodes19=7,8,9,10,11,12,13,14
ModuleClosedNodes2= ModuleClosedNodes2=
ModuleClosedNodes20= ModuleClosedNodes20=
ModuleClosedNodes21= ModuleClosedNodes21=
ModuleClosedNodes22= ModuleClosedNodes22=
ModuleClosedNodes23= ModuleClosedNodes23=
ModuleClosedNodes24= ModuleClosedNodes24=
ModuleClosedNodes25=24,25,26,27,31,32,33,35 ModuleClosedNodes25=
ModuleClosedNodes26= ModuleClosedNodes26=24,26,27,31,32,33,35
ModuleClosedNodes27=4 ModuleClosedNodes27=
ModuleClosedNodes28= ModuleClosedNodes28=4
ModuleClosedNodes29= ModuleClosedNodes29=
ModuleClosedNodes3=1,3,5,6 ModuleClosedNodes3=1,3,5,6
ModuleClosedNodes30= ModuleClosedNodes30=
ModuleClosedNodes31=114,116 ModuleClosedNodes31=
ModuleClosedNodes32= ModuleClosedNodes32=114,116
ModuleClosedNodes33=
ModuleClosedNodes4= ModuleClosedNodes4=
ModuleClosedNodes5= ModuleClosedNodes5=
ModuleClosedNodes6= ModuleClosedNodes6=
ModuleClosedNodes7= ModuleClosedNodes7=
ModuleClosedNodes8= ModuleClosedNodes8=
ModuleClosedNodes9= ModuleClosedNodes9=
NavigationStack=B4XMainPage,ImageView1_LongClick,1031,6,C_Principal,Class_Globals,12,0,Diseñador Visual,productos.bal,-100,1,C_Productos,Busca_TextChanged,1467,4,Subs,traeTablaProds,1683,0,Subs,generaGUID_EnExterno,1966,0,Subs,parseHTTPError,1978,0,C_TrendSpending,Initialize,29,0,C_Principal,JobDone,2081,6,C_Principal,cargar_Click,939,0,B4XMainPage,JobDone,570,0 NavigationStack=C_Cliente,GPS_LocationChanged,906,0,C_Cliente,B4XPage_Appear,552,6,Diseñador Visual,cliente.bal,-100,6,Diseñador Visual,principal.bal,-100,2,C_Principal,cargar_Click,837,0,C_Principal,B4XPage_Appear,539,6,kms_helperSubs,traeRuta,748,0,C_deviceLinker,Initialize,43,0,C_deviceLinker,VerifyAndLinkDevice,64,0,B4XMainPage,ImageView1_LongClick,1041,0
SelectedBuild=0 SelectedBuild=0
VisibleModules=1,30,11,15,3,31,12,13,7,28 VisibleModules=31,1,12,5,16,26,3,32,13,14,8,33,10,28

View File

@@ -1035,15 +1035,25 @@ Sub traeUsarIntentBDWA As Boolean 'ignore
End Sub End Sub
'Regresa los clientes nuevos maximos. 'Regresa los clientes nuevos maximos.
'Si no está especificado, el default es 2. 'Si no está especificado o no esta autorizado para crear clientes nuevos, el default es 0.
Sub traeMaxClientesNuevos As Int 'ignore Sub traeMaxClientesNuevos As Int 'ignore
Private CN As Int = 5 Private CN_AUT As Int = 0
Private x As Cursor = Starter.skmt.ExecQuery($"select CAT_VA_VALOR from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'MAXCTESNUEVOS'"$) Private CN_MAX As Int = 0
Private x As Cursor = Starter.skmt.ExecQuery($"select ifnull(CAT_VA_VALOR, 0) as CAT_VA_VALOR from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'CN_AUTORIZADO'"$)
If x.RowCount > 0 Then If x.RowCount > 0 Then
x.Position = 0 x.Position = 0
CN = x.GetString("CAT_VA_VALOR") CN_AUT = x.GetInt("CAT_VA_VALOR")
End If End If
Return CN If CN_AUT = 1 Then
Private x As Cursor = Starter.skmt.ExecQuery($"select ifnull(CAT_VA_VALOR, 0) as CAT_VA_VALOR from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'CN_CUANTOS'"$)
If x.RowCount > 0 Then
x.Position = 0
CN_MAX = x.GetString("CAT_VA_VALOR")
End If
End If
x.Close
Log($"Clientes Nuevos, Autorizado ${CN_AUT}, Cuantos: ${CN_MAX}"$)
Return CN_MAX
End Sub End Sub
'Regresa verdadero o falso dependiendo si el cliente lleva pedido DOE. 'Regresa verdadero o falso dependiendo si el cliente lleva pedido DOE.