mirror of
https://github.com/KeymonSoft/Kelloggs_v4.git
synced 2026-04-17 18:26:11 +00:00
- 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.
193 lines
8.8 KiB
QBasic
193 lines
8.8 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.
|
|
'-----------------------------------------------------------------------------------
|
|
|
|
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 |