Files
Mariana-Reparto-V5/B4A/C_deviceLinker.bas
jalarakmt 1919f61049 Se agrega codigo unico de imei
Se agrego el brinco para replicar con el KMTM
se agrego que mande la fecha
2026-03-18 11:21:09 -06:00

310 lines
15 KiB
QBasic

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.
'-----------------------------------------------------------------------------------
' Ejemplo de uso:
' ==== En config.properties ====
' sql.verify_device=Select nvl(CAT_RU_IDTELEFONO, 0) As CAT_RU_IDTELEFONO from kelloggs.CAT_RUTAS where cat_ru_idalmacen = ? And cat_ru_ruta = ?
' sql.registarMovil=update kelloggs.CAT_RUTAS set CAT_RU_IDTELEFONO = ? where cat_ru_idalmacen = ? And cat_ru_ruta = ?
' ==== En Class_Globals ====
' Dim linker As C_deviceLinker '<<<< Class_Globals
' ==== En B4XPage_Created ====
' linker.Initialize(Me, "Linker", True) '<<<<<< B4XPage_Created
' ==== En donde se quiera llamar ====
' linker.VerifyDevice(Subs.traeAlmacen, Subs.traeRuta)
' 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 "OK"
' Log("########################################################")
' ToastMessageShow("Dispositivo verificado y vinculado 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 "REGISTRO_COMPLETO"
' Log("########################################################")
' ToastMessageShow("¡Registro completo!", False)
' Case "SIN_REGISTRO"
' Log("########################################################")
' ToastMessageShow("¡Dispositivo sin registro!", False)
' linker.linkDevice(Subs.traeAlmacen, e_ruta.text) '<<<<<<<<< Si no esta registrado lo registramos.
' Case "REGISTRANDO"
' ToastMessageShow("¡Registro en proceso!", True)
' Case "YA_REGISTRADO"
' Log("########################################################")
' ToastMessageShow("¡¡El dispositivo ya esta registrado con otra ruta!!", True)
' Case Else ' Otros estados que tu servidor pueda devolver (ej. "UNAUTHORIZED", "PENDING_APPROVAL")
' Log("########################################################")
' 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
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
Dim dlDB As SQL
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.")
dlDB.Initialize(File.DirInternal, "deviceLink.db", True)
dlDB.ExecNonQuery("CREATE TABLE IF NOT EXISTS Registro (GUID_KEY_ALIAS TEXT)") ' Creamos la tabla si no existe
' 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
' reqManager.Initialize(Me, "http://keymon.net:1781") 'Servidor productivo
reqManager.Initialize(Me, Starter.DBReqServer) 'Servidor productivo
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 verifyDevice(Almacen_ As String, Ruta_ As String)
Private verificar As Boolean = True ' La verificacion se realiza por default
Private tv As Cursor = Starter.skmt.ExecQuery("select * from cat_variables where CAT_VA_DESCRIPCION = 'VERIFY_DEVICE'")
If tv.RowCount > 0 Then
tv.Position = 0
If tv.GetString("CAT_VA_VALOR") = 0 Then verificar = False
End If
If verificar Then ' Si VERIFY_DEVICE no está en CERO ... verificamos.
Dim DeviceId_ As String = GetDeviceGUID ' Obtenemos o generamos el GUID del dispositivo.
LogColor(DeviceId_, Colors.red)
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") ' Dispara el evento Linker_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_MARDS"
' Pasamos el almacén, la ruta y el GUID del dispositivo como parámetros.
cmd.Parameters = Array As Object(Almacen_, Ruta_) ', DeviceId_
Log($"Enviamos almacen: ${Almacen_} y ruta: ${Ruta_}"$)
' Ejecutamos el comando en el servidor. 'Me' indica que DBRequestManager_JobDone en esta clase manejará la respuesta.
reqManager.ExecuteQuery(cmd, 0, "verify_device")
Else ' Si está en CERO (Verificacion deshabilitada), regresamos "OK".
CallSub2(CallBack, EventName & "_Response", "OK")
End If
End Sub
Sub linkDevice(Almacen_ As String, Ruta_ As String)
Dim deviceId As String = GetDeviceGUID ' Obtenemos o generamos el GUID del dispositivo.
Log("########################################################")
Log("REGISTRANDO")
Dim cmd As DBCommand ' Creamos un comando para enviar al servidor.
cmd.Initialize
cmd.Name = "registarMovil_MARDS"
' Pasamos el almacén, la ruta y el GUID del dispositivo como parámetros.
cmd.Parameters = Array As Object(deviceId, Almacen_, Ruta_)
reqManager.ExecuteCommand(cmd, "registramosGUID")
If SubExists(CallBack, EventName & "_Response") Then
CallSub2(CallBack, EventName & "_Response", "REGISTRANDO") ' Dispara el evento Linker_Response("REGISTRANDO")
End If
End Sub
'244500
' 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
If deviceLinked = False Then
' Corrección: Usamos la función GUID ya existente en el módulo Subs [1].
Dim NewGUID As String = generaGUID
dlDB.ExecNonQuery($"insert into registro ('GUID_KEY_ALIAS') values ('${NewGUID}')"$) ' Guardamos nuevo registro
If logger Then LogColor($"Nuevo GUID generado y guardado: ${NewGUID}"$, Colors.Blue)
Return NewGUID
Else
Dim ExistingGUID As String
Private e As Cursor = dlDB.ExecQuery("select GUID_KEY_ALIAS from registro")
e.Position = 0
ExistingGUID = e.GetString("GUID_KEY_ALIAS")
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") ' Dispara el evento Linker_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.
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 CAT_RU_IDTELEFONO As String = records(result.Columns.Get("CAT_RU_IDTELEFONO_REPARTO"))
deviceId = GetDeviceGUID
Log($"|${deviceId}|${CAT_RU_IDTELEFONO}|"$)
' If deviceId <> CAT_RU_IDTELEFONO Then Status = "YA_REGISTRADO" ' Ya existe OTRO registro.
If CAT_RU_IDTELEFONO = 0 Or CAT_RU_IDTELEFONO.Length < 5 Then
Status = "SIN_REGISTRO"
Log("########################################################")
Log("REGISTRANDO")
' 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(deviceId, almacen, ruta)
' reqManager.ExecuteCommand(cmd, "registramosGUID")
If SubExists(CallBack, EventName & "_Response") Then
CallSub2(CallBack, EventName & "_Response", "SIN_REGISTRO")
End If
else if CAT_RU_IDTELEFONO = deviceId Then
Status = "OK"
Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("LIGADO"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("LIGADO", 1))
Log("OK")
LogColor("######### GUARDAMOS ###########", Colors.red)
Else
Status = "YA_REGISTRADO"
Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("LIGADO"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("LIGADO", 0))
Log("YA_REGISTRADO")
LogColor("######### GUARDAMOS ###########", Colors.red)
End If
' Invocamos el callback en el módulo principal con el estado.
Next
Else
Status = "NO_EXISTE_RUTA"
End If
If SubExists(CallBack, EventName & "_Response") Then
CallSub2(CallBack, EventName & "_Response", Status) ' Dispara el evento Linker_Response("OK") o Linker_Response("YA_REGISTRADO")
End If
End If
If result.Tag = "registramosGUID" Then
Log("########################################################")
Log("REGISTRO_COMPLETO")
LogColor("######### GUARDAMOS ###########", Colors.red)
Subs.logJobDoneResultados(result)
Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("LIGADO"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("LIGADO", 1))
If SubExists(CallBack, EventName & "_Response") Then
CallSub2(CallBack, EventName & "_Response", "REGISTRO_COMPLETO") ' Dispara el evento Linker_Response("REGISTRO_COMPLETO")
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
'Regresa true si existe registro
Sub deviceLinked As Boolean
Private e As Cursor = dlDB.ExecQuery("select * from registro")
If e.RowCount > 0 Then
Return True
Else
Return False
End If
End Sub