This commit is contained in:
2023-09-24 00:22:53 -06:00
parent 2b7cd5c3b5
commit ac27d8ea79
3 changed files with 827 additions and 1 deletions

608
B4A/C_Subs.bas Normal file
View File

@@ -0,0 +1,608 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=12.2
@EndOfDesignText@
Sub Class_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
' Public GZip As GZipStrings 'Usa la libreria CompressStrings
' Private su As StringUtils 'Usa la libreria StringUtils
Dim reqManager As DBRequestManager
Private EventName As String 'ignore
Private CallBack As Object 'ignore
Dim phn As Phone
Dim devModel As String
Dim db, kmt, errorLog As SQL 'Requiere la libreria "SQL" 'ignore
Dim ssid As String 'ignore
Dim reqsList As List
Dim reqError As Boolean = False
Private subsLogs As Boolean = False
End Sub
'You can add more parameters here.
Public Sub Initialize (vCallback As Object, vEventName As String) As Object
reqsList.Initialize
EventName = vEventName
CallBack = vCallback
db = dbInit
reqManager = reqManagerInit
Return Me
End Sub
'Inicializa la BD con "kmt.db" en File.DirInternal, si el archivo no existe, lo copia desde File.DirAssets.
'Dispara el evento "dbOk" cuando termina.
Sub dbInit As SQL
If File.Exists(File.DirInternal, "kmt.db") = False Then File.Copy(File.DirAssets, "kmt.db", File.DirInternal, "kmt.db")
db.Initialize(File.DirInternal,"kmt.db", True)
dbOk(True)
' Log(db.IsInitialized)
Return db
End Sub
Sub dbOk(Success As Boolean)
If SubExists(CallBack, EventName & "_dbOk") Then
CallSub2(CallBack, EventName & "_dbOk", Success)
End If
End Sub
'Inicializamos el DBReqServer.
Sub reqManagerInit As DBRequestManager
Private rm As DBRequestManager
rm.Initialize(Me, traeDBReqServerDeBD(db))
Log($"Inicializamos reqManager con ${traeDBReqServerDeBD(db)}"$)
Return rm
End Sub
'Reinicializamos el DBReqServer de C_Subs.
Sub reqManagerReInit
Log("reqManager ReInit")
reqManager = reqManagerInit
End Sub
Sub envioTest
reqsList.Initialize ' Ponemos la lista de DBRequests en cero.
Private cmd As DBCommand
cmd.Initialize
cmd.Name = "select_fecha"
For i = 0 To 50
' Sleep(200)
reqManager.ExecuteQuery(cmd, 0, $"select_fecha_${i}"$)
reqsList.Add($"select_fecha_${i}"$)
Next
End Sub
'Dispara el evento "_envioOk" del caller.
Sub envioOk(Success As Boolean)
' Log($"_ENVIOOK_"$)
If SubExists(CallBack, EventName & "_envioOk") Then
CallSub2(CallBack, EventName & "_envioOk", Success)
End If
End Sub
Sub JobDone(Job As HttpJob)
LogColor("C_SUBS JOBDONE - " & Job.Success, Colors.Red)
If Job.Success = False Then
Log($"Error en el request ${Job.Tag}"$)
LogColor("** " & Job.Tag & " Error: " & Job.ErrorMessage, Colors.Red)
If reqsList.IndexOf(Job.Tag) > -1 Then reqsList.RemoveAt(reqsList.IndexOf(Job.Tag))
reqError = True
Else
If Job.JobName = "DBRequest" Then
Dim resultado As DBResult = reqManager.HandleJob(Job)
If reqsList.IndexOf(resultado.Tag) > -1 Then reqsList.RemoveAt(reqsList.IndexOf(resultado.Tag))
If resultado.Tag = "select_fecha" Then
For Each records() As Object In resultado.Rows
For Each k As String In resultado.Columns.Keys
Log(resultado.Tag & ": " & k & ": " & records(resultado.Columns.Get(k)))
Next
Next
End If
End If
End If
Log(reqsList.Size)
If reqsList.Size = 0 Then 'Ya no hay DBReqs pendientes.
Log(reqError)
If Not(reqError) Then
envioOk(True)
Else
envioOk(False)
End If
reqError = False
Log("-= FIN =-")
End If
Job.Release
End Sub
'Pone el valor de phn.Model en la variable global "devModel"
Sub getPhnId As String 'ignore
'Requiere la libreria "Phone"
devModel = phn.Model
If devModel.Length <= 3 Then 'Si phn.Model esta en blanco ...
Dim t As String = phn.GetSettings("android_id") 'Intentamos con "android_id"
devModel = t
End If
If devModel.Length >= 3 Then 'Si tenemos valor para phn.Model
File.WriteString(File.DirInternal, "phnId.txt", devModel) 'Sobreescribimos archivo phnId.txt with deviceId
' Log("Tenemos phnId: "&devModel&" "&File.DirInternal&"/phn.txt sobreescrito")
Else If devModel.Length < 3 Then ' Si no tenemos valor, lo leemos de phnId.txt
Dim s As String = File.ReadString(File.DirInternal, "phnId.txt")
devModel = s
' Log("Leemos id de "&File.DirInternal&"/phnId.txt")
' Log(devModel)
End If
Return devModel
End Sub
'Convierte una fecha al formato yyMMddHHmmss
Sub fechaKMT(fecha As String) As String 'ignore
' Log(fecha)
Dim OrigFormat As String = DateTime.DateFormat 'save orig date format
DateTime.DateFormat="yyMMddHHmmss"
Dim nuevaFecha As String=DateTime.Date(fecha)
DateTime.DateFormat=OrigFormat 'return to orig date format
' Log(nuevaFecha)
Return nuevaFecha
End Sub
'Escribimos las coordenadas y fecha a un archivo de texto
Sub guardaInfoEnArchivo(coords As String) 'ignore
' Cambiamos el formato de la hora
Dim OrigFormat As String=DateTime.DateFormat 'save orig date format
DateTime.DateFormat="MMM-dd HH:mm:ss"
Dim lastUpdate As String=DateTime.Date(DateTime.Now)
DateTime.DateFormat=OrigFormat 'return to orig date format
Dim ubic As String = coords&","&lastUpdate
Dim out As OutputStream = File.OpenOutput(File.DirRootExternal, "gps.txt", True)
Dim s As String = ubic & CRLF
Dim t() As Byte = s.GetBytes("UTF-8")
out.WriteBytes(t, 0, t.Length)
out.Close
End Sub
'Escribimos las coordenadas (latitud, longitud, fecha) y fecha a una BD
Sub guardaInfoEnBD(coords As String) 'ignore
Log("Guardamos ubicacion en BD - "&coords)
Try
Dim latlon() As String = Regex.Split("\|", coords)
If latlon.Length < 2 Then latlon = Regex.Split(",", coords) 'Si son menos de 2, entonces estan separadas por comas y no por "|"
If subsLogs Then Log("LatLon="&latlon)
kmt.ExecNonQuery2("INSERT INTO RUTA_GPS(FECHA, LAT, LON) VALUES (?,?,?)", Array As Object (latlon(2),latlon(0),latlon(1)))
Catch
LogColor(LastException, Colors.red)
End Try
End Sub
'Limpiamos la tabla RUTA_GPS de la BD
Sub deleteGPS_DB 'ignore
kmt.ExecNonQuery("delete from RUTA_GPS")
kmt.ExecNonQuery("vacuum;")
ToastMessageShow("Borramos BD Coords GPS", False)
End Sub
'Limpiamos la tabla errorLog de la BD
Sub deleteErrorLog_DB 'ignore
errorLog.ExecNonQuery("delete from errores")
errorLog.ExecNonQuery("vacuum;")
ToastMessageShow("BD Errores Borrada", False)
End Sub
'Mandamos "coords" en un mensaje a "Sprvsr"
'Sub mandamosLoc(coords As String) 'ignore
'' Log("Iniciamos mandamosLoc "&coords)
'' Log("locRequest="&Tracker.locRequest)
' guardaInfoEnBD(coords)'Escribimos coordenadas y fecha a una bd
' Dim t As String
' If Tracker.locRequest="Activa" Then
' If PushService.au = 1 Then
' t = "au" ' es una actualizacion
' Else
' t = "u" ' es una peticion
' End If
' Dim params As Map = CreateMap("topic":"Sprvsr", "coords":coords, "t":t, "b":PushService.battery, "mt":Main.montoActual)
' CallSub2(PushService, "mandaMensaje",params)
' Tracker.locRequest="Enviada"
' CallSubDelayed(Tracker,"CreateLocationRequest")
' End If
'End Sub
'Regresa la fecha y hora de hoy a las 00:00 en el formato "yyMMddHHMMSS"
Sub fechaInicioHoy As String 'ignore
Dim OrigFormat As String = DateTime.DateFormat 'save orig date format
DateTime.DateFormat="yyMMdd"
Private h As String = DateTime.Date(DateTime.Now)&"000000"
DateTime.DateFormat=OrigFormat 'return to orig date format
Log("Hoy="&h)
Return h
End Sub
'Guardamos "texto" a la bitacora
Sub log2DB(texto As String) 'ignore
LogColor(fechaKMT(DateTime.Now)&" - log2BD: '"&texto&"'", Colors.LightGray)
kmt.ExecNonQuery2("INSERT INTO bitacora(fecha, texto) VALUES (?,?)", Array As Object (fechaKMT(DateTime.now), texto))
End Sub
'Regresa verdadero si ya pasaron XX minutos de la fecha dada
Sub masDeXXMins(hora As Int, mins As Int) As Boolean 'ignore
If (hora + mins * DateTime.TicksPerMinute) < DateTime.Now Then
Return True
Else
Return False
End If
End Sub
'Regresa verdadero si ya pasaron XX minutos de la fechaKMT dada
Sub masDeXXMinsKMT(hora As String, mins As Int) As Boolean 'ignore
Try
' LogColor($"Hora=${fechaKMT(fechaKMT2Ticks(hora) + mins * DateTime.TicksPerMinute)}, Mins=${mins}, Actual=${fechaKMT(DateTime.Now)}"$,Colors.red)
If fechaKMT2Ticks(hora) + mins * DateTime.TicksPerMinute < DateTime.Now Then
' Log("+++ +++ "&fechaKMT(fechaKMT2Ticks(hora) + mins * DateTime.TicksPerMinute) & " < " & fechaKMT(DateTime.Now))
Return True
Else
' Log("+++ +++ "&fechaKMT(fechaKMT2Ticks(hora) + mins * DateTime.TicksPerMinute) & " > " & fechaKMT(DateTime.Now))
Return False
End If
Catch
Log(LastException)
End Try
End Sub
'Limpiamos la tabla "bitacora" de la BD
Sub borraLogDB 'ignore
LogColor("Borramos BD de log", Colors.Magenta)
kmt.ExecNonQuery("delete from bitacora")
kmt.ExecNonQuery("vacuum;")
End Sub
'Monitoreamos los servicios para ver si estan activos (No pausados), y si no, los reniciamos
'Sub Monitor 'ignore
' Private monitorStatus As Boolean = True
' LogColor("Corriendo Subs.Monitor", Colors.RGB(161,150,0))
' If IsPaused(Tracker) Then
' log2DB("Reiniciando 'Tracker Pausado' desde Subs.Monitor")
' StartService(Tracker)
' monitorStatus = False
' Else
' CallSubDelayed(Tracker, "revisaFLP")
' End If
' If IsPaused(PushService) Then
' log2DB("Reiniciando 'PushService Pausado' desde Subs.Monitor")
' StartService(PushService)
' monitorStatus = False
' Else
' revisaPushService
' End If
' If monitorStatus Then LogColor(" +++ +++ Servicios Activos", Colors.Green)
'End Sub
'Convierte una fecha en formato YYMMDDHHMMSS a Ticks
Sub fechaKMT2Ticks(fKMT As String) As Long 'ignore
Try
If fKMT.Length = 12 Then
Private parteFecha As String = fKMT.SubString2(0,6)
Private parteHora As String = fKMT.SubString(6)
Private OrigFormat As String = DateTime.DateFormat 'save original date format
DateTime.DateFormat="yymmdd"
DateTime.TimeFormat="HHmmss"
Private ticks As Long = DateTime.DateTimeParse(parteFecha,parteHora)
DateTime.DateFormat=OrigFormat 'return to original date format
Return ticks
Else
Log("Formato de fecha incorrecto, debe de ser 'YYMMDDHHMMSS', no '"&fKMT&"' largo="&fKMT.Length)
Return 0
End If
Catch
Log(LastException)
LogColor($"Fecha dada: ${fKMT}, Parte Fecha: ${parteFecha}, Parte Hora: ${parteHora}"$, Colors.Red)
Return 0
End Try
End Sub
Sub InstallAPK(dir As String, apk As String) 'ignore
If File.Exists(dir, apk) Then
Dim i As Intent
i.Initialize(i.ACTION_VIEW, "file://" & File.Combine(dir, apk))
i.SetType("application/vnd.android.package-archive")
StartActivity(i)
End If
End Sub
'Copia la base de datos del almacenamiento interno al externo en el directorio kmts.
Sub copiaDB(result As Boolean) 'ignore
ToastMessageShow("copiaDB", False)
If result Then
Dim p As String
If File.ExternalWritable Then
p = File.DirRootExternal
' Log("Externo")
Else
p = File.DirInternal
' Log("Interno")
End If
Dim theDir As String
Try
File.MakeDir(File.DirRootExternal,"kmts")
theDir = "/kmts"
Catch
theDir = ""
End Try
Try
File.Copy(File.DirInternal,"kmt.db",File.DirRootExternal&theDir,"cedex_kmt.db")
File.Copy(File.DirInternal,"errorLog.db",File.DirRootExternal&theDir,"cedex_errorLog.db")
ToastMessageShow("BD copiada!", False)
Catch
ToastMessageShow("No se pudo hacer la copia: "&LastException, True)
End Try
Log("rootExternal="&p)
Log("File.DirInternal="&File.DirInternal)
Log("File.DirRootExternal="&File.DirRootExternal)
Else
ToastMessageShow("Sin permisos", False)
End If
End Sub
'Hace visible y trae al frente el panel con los parametros "Top" y "Left" dados.
Sub panelVisible(panel As Panel, top As Int, left As Int) 'ignore
panel.BringToFront
panel.Visible = True
panel.Top = top
panel.Left = left
End Sub
'Centra una etiqueta dentro de un elemento superior.
Sub centraEtiqueta(elemento As Label, anchoElementoSuperior As Int) 'ignore
elemento.Left = Round(anchoElementoSuperior/2)-(elemento.Width/2)
End Sub
'Centra un panel horizontalmente dentro de un elemento superior.
Sub centraPanel(elemento As Panel, anchoElementoSuperior As Int) 'ignore
elemento.Left = Round(anchoElementoSuperior/2)-(elemento.Width/2)
End Sub
'Centra un panel verticalmente dentro de un elemento superior.
Sub centraPanelV(elemento As Panel, altoElementoSuperior As Int) 'ignore
elemento.Top = Round(altoElementoSuperior/2)-(elemento.Height/2)
End Sub
'Centra una barra de progreso dentro de un elemento superior.
Sub centraProgressBar(elemento As ProgressBar, anchoElementoSuperior As Int) 'ignore
elemento.Left = Round(anchoElementoSuperior/2)-(elemento.Width/2)
End Sub
'Regresa el usuario de la tabla USUARIOA si es que existe, si no existe, regresa "SinUsuario".
Sub buscaDBUsuario As String 'ignore
Private c As Cursor
Private usuario As String = "SinUsuario"
c=kmt.ExecQuery("select USUARIO from usuarioa")
c.Position=0
If c.RowCount > 0 Then usuario = c.GetString("USUARIO")
Return usuario
End Sub
'Regresa la fecha en el formato "MM/dd/yyyy"
Sub traeFecha As String 'ignore
DateTime.DateFormat = "MM/dd/yyyy"
Private sDate As String = DateTime.Date(DateTime.Now)
Private sTime As String = DateTime.Time(DateTime.Now)
Return sDate & sTime
End Sub
'Guarda el nombre y version de la app en CAT_VARIABLES.
Sub guardaAppInfo(skmt As SQL) 'ignore
skmt.ExecNonQuery("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'EMPRESA' or CAT_VA_DESCRIPCION = 'APP_NAME' or CAT_VA_DESCRIPCION = 'APP_VERSION'")
skmt.ExecNonQuery($"insert into CAT_VARIABLES (CAT_VA_DESCRIPCION, CAT_VA_VALOR) values ('APP_NAME', '${Application.LabelName}')"$)
skmt.ExecNonQuery($"insert into CAT_VARIABLES (CAT_VA_DESCRIPCION, CAT_VA_VALOR) values ('APP_VERSION', '${Application.VersionName}')"$)
End Sub
'Muestra en el Log los campos y valores que regresan en el JobDone.
Sub logJobDoneResultados(resultado As DBResult) 'ignore
For Each records() As Object In resultado.Rows
LogColor($"====== ${resultado.Tag} - REGISTROS = ${resultado.Rows.Size}"$, Colors.RGB(215,37,0))
For Each k As String In resultado.Columns.Keys
LogColor(k & " = " & records(resultado.Columns.Get(k)), Colors.RGB(215,37,0))
Next
Next
End Sub
'Regresa la base de datos especificada ya inicializada.
Sub inicializaBD(ruta As String, BDName As String) As SQL 'ignore
Dim skmt As SQL
If File.Exists(ruta, BDName) = False Then
File.Copy(File.DirAssets, BDName, ruta, BDName)
LogColor($"Copiamos ${BDName} de ${File.DirAssets} a ${ruta}"$,Colors.Green)
End If
skmt.Initialize(ruta, BDName, True)
Return skmt
End Sub
'Agrega una columna a la tabla especificada.
'Hay que indicar el "tipo" de la columna (TEXT, INTEGER, ETC)
'Ej. agregaColumna("TABLA", "COLUMNA", "TIPO")
Sub agregaColumna(tabla As String, columna As String, tipo As String) 'ignore
Try 'Intentamos usar "pragma_table_info" para revisar si existe la columna en la tabla
Private c As Cursor = db.ExecQuery($"SELECT COUNT(*) AS fCol FROM pragma_table_info('${tabla}') WHERE name='${columna}'"$)
c.Position = 0
If c.GetString("fCol") = 0 Then 'Si no esta la columna la agregamos
db.ExecNonQuery($"ALTER TABLE ${tabla} ADD COLUMN ${columna} ${tipo}"$)
Log($"Columna "${columna} ${tipo}", agregada a "${tabla}"."$)
End If
Catch 'Si no funciona "pragma_table_info" lo hacemos con try/catch
Try
db.ExecNonQuery($"ALTER TABLE ${tabla} ADD COLUMN ${columna} ${tipo}"$)
Log($"Columna "${columna} ${tipo}", agregada a "${tabla}".."$)
Catch
Log(LastException)
End Try
End Try
End Sub
'Regresa el DBReqServer desde CAT_VARIABLES o "N/A" si no existe.
Sub traeDBReqServerDeBD(dbx As SQL) As String 'ignore
Dim srvr As String = "N/A"
Dim rs As ResultSet = dbx.ExecQuery("select CAT_VA_VALOR from cat_variables where CAT_VA_DESCRIPCION = 'SERVER'")
If rs.RowCount > 0 Then
rs.NextRow
srvr = rs.GetString("CAT_VA_VALOR")
End If
Return srvr
End Sub
'Regresa el valor de intervalo desde CAT_VARIABLES o "30" si no existe.
Sub traeIntervaloDeBD As String 'ignore
Dim intrvl As String = "30"
Dim rs As ResultSet = db.ExecQuery("select valor from cat_variables where nombre = 'intervalo'")
If rs.RowCount > 0 Then
rs.NextRow
intrvl = rs.GetString("valor")
End If
Return intrvl
End Sub
'Regresa el valor timeout desde CAT_VARIABLES o "9000" si no existe.
Sub traeTimeoutDeBD As String 'ignore
Dim tmout As String = "9000"
Dim rs As ResultSet = db.ExecQuery("select valor from cat_variables where nombre = 'timeout'")
If rs.RowCount > 0 Then
rs.NextRow
tmout = rs.GetString("valor")
End If
Return tmout
End Sub
'Crea una notificación con el "body" dado y regresa el objeto.
Sub CreateNotification (Body As String) As Notification 'ignore
Dim notification As Notification
notification.Initialize2(notification.IMPORTANCE_LOW)
notification.Icon = "icon"
notification.SetInfo("Tester", Body, Main)
Return notification
End Sub
'Genera una notificacion con importancia alta
Sub notiHigh(title As String, body As String, id As String, activity As Object) 'ignore
activity = Main
Private notif As Notification
notif.Initialize2(notif.IMPORTANCE_HIGH)
notif.Icon = "icon"
notif.Vibrate = False
notif.Sound = False
notif.AutoCancel = True
' If logger Then Log("notiHigh: "&title)
notif.SetInfo(title, body, activity)
' Log("notiHigh SetInfo")
notif.Notify(id)
End Sub
'Regresa el objeto de una notificacion con importancia baja
Sub notiLowReturn(title As String, Body As String, id As Int) As Notification 'ignore
Private notification As Notification
notification.Initialize2(notification.IMPORTANCE_LOW)
' Log("notiLowReturn: "&title)
notification.Icon = "icon"
notification.Sound = False
notification.Vibrate = False
notification.SetInfo(title, Body, Main)
notification.Notify(id)
' Log("notiLowReturn SetInfo")
Return notification
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 = db.ExecQuery("select ID_ALMACEN from CAT_ALMACEN")
c.Position = 0
a = C.GetString("ID_ALMACEN")
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 = db.ExecQuery("select CAT_CL_RUTA from kmt_info where CAT_CL_CODIGO In (Select cuenta from cuentaa)")
r = "0"
If c.RowCount > 0 Then
c.Position=0
r = c.GetString("CAT_CL_RUTA")
End If
c.Close
Return r
End Sub
'Mandamos los pedidos pendientes (pc_envio_ok <> 1).
Sub mandaPendientes 'ignore
Private logger As Boolean = False
'PEDIDO_CLIENTE (Pendientes)
Private c As Cursor = db.ExecQuery("SELECT PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT, PC_COSTO_SIN, PC_RUTA, PC_ALMACEN, PC_FACTURA FROM PEDIDO_CLIENTE where pc_envio_ok <> 1")
If logger Then Log($"Pedido_Cliente PENDIENTE: ${c.RowCount}"$)
Private almacen As String = traeAlmacen
Private ruta As String = traeRuta
If c.RowCount>0 Then
For i = 0 To c.RowCount - 1
c.Position = i
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "DELETE_PEDIDO_MARDS_PC"
cmd.Parameters = Array As Object(almacen, ruta, c.GetString("PC_CLIENTE") )
reqManager.ExecuteCommand(cmd , "DEL_PC")
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "insert_pedidos_MARDS"
If logger Then Log($"${c.GetString("PC_CLIENTE")}, ${almacen}"$)
cmd.Parameters = Array As Object(C.GetString("PC_CLIENTE"), C.GetString("PC_FECHA"), C.GetString("PC_USER"), C.GetString("PC_NOART"), C.GetString("PC_MONTO"), C.GetString("PC_LON"), C.GetString("PC_LAT"), almacen, ruta, C.GetString("PC_COSTO_SIN"), C.GetString("PC_FACTURA"))
reqManager.ExecuteCommand(cmd , $"ins_pedidosPendientes_head_${c.GetString("PC_CLIENTE")}"$)
Next
End If
'PEDIDO (Pendientes)
c=Starter.skmt.ExecQuery("SELECT PC_ENVIO_OK, 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 FROM pedido_cliente left join PEDIDO where pc_cliente = pe_cliente and pc_envio_ok <> 1")
If logger Then Log($"Pedido PENDIENTE: ${c.RowCount}"$)
If c.RowCount>0 Then
For i = 0 To c.RowCount - 1
c.Position = i
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "DELETE_PEDIDO_MARDS_PE"
cmd.Parameters = Array As Object(almacen, ruta,c.GetString("PE_CLIENTE") )
reqManager.ExecuteCommand(cmd , "DEL_PE")
cmd.Initialize
cmd.Name = "insert_pedido_MARDS"
cmd.Parameters = Array As Object(c.GetString("PE_CEDIS"), almacen, c.GetString("PE_COSTO_TOT"), c.GetString("PE_COSTOU"), c.GetString("PE_CANT"), c.GetString("PE_PRONOMBRE"), c.GetString("PE_PROID"), c.GetString("PE_CLIENTE"), c.GetString("PE_FECHA"), c.GetString("PE_USUARIO"), c.GetString("PE_RUTA"), C.GetString("PE_COSTO_SIN"), c.GetString("PE_DESC"), c.GetString("PE_FOLIO"))
reqManager.ExecuteCommand(cmd , $"ins_pedidosPendientes_prods_${c.GetString("PE_CLIENTE")}"$)
Next
End If
'ABONOS
Dim ab As Cursor = db.ExecQuery($"SELECT * from ABONOS where a_enviado is null"$)
If logger Then Log(ab.RowCount)
If ab.RowCount > 0 Then
For i = 0 To ab.RowCount - 1
ab.Position = i
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "insert_abono_MARDS"
cmd.Parameters = Array As Object( ab.GetString("a_usuario"), ab.GetString("a_ruta"), ab.GetString("a_cliente"), ab.GetString("a_abono"), ab.GetString("a_fecha") )
reqManager.ExecuteCommand(cmd , $"ins_abonosPendientes_${ab.GetString("a_cliente")}"$)
If logger Then Log($"ins_abonosPendientes_${ab.GetString("a_cliente")}"$)
Next
End If
ab.Close
End Sub
'Revisa si la aplicación tiene permiso para acceder a las notificaciones.
Sub CheckNotificationAccess As Boolean 'ignore
Dim ph As Phone
Dim nstr, pstr As String
Dim r As Reflector
pstr = r.GetStaticField("anywheresoftware.b4a.BA", "packageName")
nstr = ph.GetSettings("enabled_notification_listeners")
Return nstr.Contains(pstr)
End Sub

View File

@@ -82,6 +82,6 @@ ModuleClosedNodes6=
ModuleClosedNodes7=
ModuleClosedNodes8=1
ModuleClosedNodes9=
NavigationStack=C_Subs,mandaPendientes,592,0,B4XMainPage,B4XPage_Appear,244,1,NotificationService,Service_Destroy,72,0,NotificationService,NotiMon_NotificationPosted,83,0,B4XMainPage,i_engrane_Click,659,0,C_RespaldoDiario,Class_Globals,0,0,C_RespaldoDiario,Initialize,23,6,B4XMainPage,ocultaProgreso,653,0,B4XMainPage,lv_server_ItemClick,684,0,B4XMainPage,Entrar_LongClick,676,0,B4XMainPage,i_engrane_LongClick,672,0
NavigationStack=B4XMainPage,B4XPage_Appear,244,1,NotificationService,Service_Destroy,72,0,NotificationService,NotiMon_NotificationPosted,83,0,B4XMainPage,i_engrane_Click,659,0,C_RespaldoDiario,Class_Globals,0,0,C_RespaldoDiario,Initialize,23,6,B4XMainPage,ocultaProgreso,653,0,B4XMainPage,Entrar_LongClick,676,0,B4XMainPage,i_engrane_LongClick,672,0,B4XMainPage,lv_server_ItemClick,681,0
SelectedBuild=0
VisibleModules=2,25,23,12,15,13,4,26,14,8,22,9,16,27

218
B4A/NotificationService.bas Normal file
View File

@@ -0,0 +1,218 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Service
Version=11
@EndOfDesignText@
#Region Service Attributes
#StartAtBoot: False
#End Region
'******************************************************************************
'Se necesita la libreria ReplyAuto.
'No olvidar agregar esta linea al editor de manifiesto:
'AddApplicationText(
'<Service android:name="b4a.jsaplication.com.br.ReplyAuto"
' android:label="Mariana" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
' <intent-filter><action android:name="android.service.notification.NotificationListenerService" /></intent-filter>
' </Service>)
'En B4XPage_Appear de MainPage agregar estas lineas:
'
'If Not(CheckNotificationAccess) Then
' Msgbox2Async($"Se necesita acceso a las notificaciones, haga clic en "Aceptar" y en la siguiente pantalla permita el acceso a la aplicación "${Application.LabelName}"."$, "Permisos necesarios", "Aceptar", "Cancelar", "", Null, True)
' Wait For Msgbox_Result (resultado As Int)
' If resultado = DialogResponse.POSITIVE Then
' Dim In As Intent
' In.Initialize("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS", "")
' StartActivity(In)
' End If
'End If
'
'Y al final de Mainpage agregar esta funcion:
'
''Revisa si la aplicación tiene permiso para acceder a las notificaciones.
'Sub CheckNotificationAccess As Boolean 'ignore
' Dim ph As Phone
' Dim nstr, pstr As String
' Dim r As Reflector
' pstr = r.GetStaticField("anywheresoftware.b4a.BA", "packageName")
' nstr = ph.GetSettings("enabled_notification_listeners")
' Return nstr.Contains(pstr)
'End Sub
'******************************************************************************
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
Dim rp As ReplyAuto
' Dim activo As Boolean = True
' Dim ultimaNoti As String
Dim logger As Boolean = False
End Sub
Sub Service_Create
rp.Initialize("NotiMon")
#if not(DEBUG)
logger = False
#end if
' If logger Then Log("**************** Iniciamos Monitor Keymon ***********************")
End Sub
Sub Service_Start (StartingIntent As Intent)
' Log("NotificationService Start")
If rp.HandleIntent(StartingIntent) Then Return
' DateTime.DateFormat = "mm"
' ultimaNoti = DateTime.Date(DateTime.now)
' If logger Then LogColor($"Ultima notificación en el minuto ${ultimaNoti}"$, Colors.green)
End Sub
Sub Service_Destroy
End Sub
Sub NotiMon_NotificationPosted (SBN As StatusBarNotification)
Private logger As Boolean = True
If SBN.PackageName = "com.whatsapp" Then
If logger Then LogColor(SBN.PackageName, Colors.Red)
If logger Then LogColor("isGroupWA2: "&isGroupWA(SBN),Colors.Magenta)
If logger Then LogColor("isPersonWA: "&isPersonWA(SBN),Colors.Magenta)
If logger Then Log($"getGroupName: |${getGroupName(SBN.Title)}|"$)
Private cmd() As String = Regex.Split(" ", SBN.Message)
If SBN.Message.StartsWith("#NS") And cmd.Length = 2 Then 'Si el mensaje contiene "#NS" y tiene un segundo parametro ...
If esMensajeWAValido(SBN) Then
' Log(cmd(1))
rp.ClearNotification(SBN)
Starter.reinicializaReqManager(cmd(1))
rp.reply(SBN.Notification, SBN.PackageName, $"Servidor cambiado a ${cmd(1)} "$)
Sleep(1000)
' rp.ClearNotification(SBN)
rp.ClearAll
End If
End If
End If
End Sub
'Regresa verdadero si el mensaje de whatsapp es un mensaje valido.
Sub esMensajeWAValido(SBN As StatusBarNotification)
Private valido As Boolean = False
Private ww() As String = Regex.Split("\|", SBN.Key)
If ww(3) <> Null And ww(3) <> "null" Then valido = True
Return valido
End Sub
'Returns TRUE if the sender is a GROUP.
'Searches the provided sbn.title for the string ": " to know if the sender is a group.
Sub isGroupWA2(sbnTitle As String) As Boolean 'ignore
Private x As Boolean = Regex.ismatch(".*(: ).*", sbnTitle)
Return x
End Sub
'Returns TRUE if the sender is a GROUP.
'Searches the provided notification object for the string "@g.us" and if found returns TRUE.
Sub isGroupWA(sbn As StatusBarNotification) As Boolean
Private a As Boolean = False
If sbn.As(String).IndexOf("@g.us") > -1 Then a = True 'ignore
Return a
End Sub
'Returns TRUE if the sender is a PERSON.
'Searches the provided notification object for the string "@s.whatsapp.net" and if found returns TRUE.
Sub isPersonWA(sbn As StatusBarNotification) As Boolean 'ignore
Private a As Boolean = False
If sbn.As(String).IndexOf("@s.whatsapp.net") > -1 Then a = True 'ignore
Return a
End Sub
'Returns TRUE if the sender is a PERSON.
'Searches the provided notification object for the string "channel=individual" and if found returns TRUE.
Sub isPersonWA2(sbn As StatusBarNotification) As Boolean 'ignore
Private a As Boolean = False
If sbn.As(String).IndexOf("channel=individual") > -1 Then a = True 'ignore
Return a
End Sub
'Returns the sender's number.
'Searches the provided notification object and gets the numbers between "shortcut=" and "@s.whatsapp.net".
Sub getNumberWA(sbn As StatusBarNotification) As String
Private a As Int = sbn.As(String).IndexOf("@s.whatsapp.net") 'ignore
If a > -1 Then
Private x As String = sbn.As(String) 'ignore
Private y As Int = x.IndexOf("shortcut=")
If (y+9) > 0 And a > (y+9) Then x = x.SubString2(y+9, a) Else x = "Not a person"
Else 'It is probably is a group.
x = "Not a person"
End If
Return x
End Sub
'Returns the name of the group from the given text.
'If it is not a group, then returns the notification's title.
Sub getGroupName(sbnTitle As String) As String 'ignore
Private a As Int = sbnTitle.IndexOf(": ")
Private x As String = sbnTitle
If a > -1 Then
Private b As String = sbnTitle.SubString2(0, a)
x = Regex.Replace(" \(.+\)", b, "")
End If
Return x
End Sub
'Returns the name of the group from the given notification object.
'Searches the provided notification for the string "hiddenConversationTitle" and if found, gets the name.
'If it is not a group,then it returns the notification's title.
Sub getGroupName2(sbn As StatusBarNotification) As String 'ignore
Private inicio As Int = sbn.Extras.As(String).IndexOf("hiddenConversationTitle=") 'ignore
If inicio > -1 And sbn.Extras.As(String).IndexOf("hiddenConversationTitle=null") = -1 Then 'ignore
Private x As String = sbn.Extras.As(String) 'ignore
Private fin As Int = x.IndexOf(", android.reduced.images=")
x = x.SubString2(inicio+24, fin)
x = Regex.Replace(" \(.+\)", x, "") 'Replace anything between () with "", this en the case that we have something like "MyGroupName (5 messages)"
Else 'Is not from a group.
Private x As String = sbn.Title
End If
Return x
End Sub
'Returns the person's name (or the number) when the message comes from a group.
'Searches the provided sbn.title for the string ": " in the title and returns the string after that,
'if it does not find ": " then returns the complete string.
Sub getPersonFromGroup(sbnTitle As String) As String 'ignore
Private a As Int = sbnTitle.IndexOf(": ")
If a = -1 Then a = -2 'Is not from a group.
Private b As String = sbnTitle.SubString(a+2)
Return b
End Sub
'Returns the NUMBER of the sender and if NOT a person, then returns the name of the group.
Sub getNumberOrGroupWA(sbn As StatusBarNotification) As String 'ignore
Private numRemitente As String = getNumberWA(sbn)
If numRemitente = "Not a person" Then numRemitente = getGroupName(sbn.Title)
Return numRemitente
End Sub
'Regresa el "shortcut" del remitente.
'Si es de un grupo, es algo como "120363023512345678@g.us"
'Si es de una persona, entonces "5215512345678@s.whatsapp.net"
Sub getShortcut(sbn As StatusBarNotification) As String 'ignore
Private ap As Int = sbn.As(String).IndexOf("@s.whatsapp.net") 'ignore
Private ag As Int = sbn.As(String).IndexOf("@g.us") 'ignore
Private x As String = sbn.As(String) 'ignore
Private y As Int = x.IndexOf("shortcut=")
If ap > -1 Then
Private x As String = sbn.As(String) 'ignore
Private y As Int = x.IndexOf("shortcut=")
x = x.SubString2(y+9, ap+15)
Else if ag > -1 Then 'It is probably is a group.
Private x As String = sbn.As(String) 'ignore
Private y As Int = x.IndexOf("shortcut=")
x = x.SubString2(y+9, ag+5)
End If
Return x
End Sub