From 97da4af23b6cc30a2c9810230390aceafb713784 Mon Sep 17 00:00:00 2001 From: Jose Alberto Guerra Ugalde Date: Tue, 28 May 2024 23:33:35 -0600 Subject: [PATCH] - Commit inicial --- .gitignore | 3 + B4A/B4XMainPage.bas | 231 ++++++++++++++++++++ B4A/C_Principal.bas | 332 +++++++++++++++++++++++++++++ B4A/C_updateAvailable.bas | 24 +++ B4A/DBRequestManager.bas | 363 ++++++++++++++++++++++++++++++++ B4A/Files/engraneactual.png | Bin 0 -> 1369 bytes B4A/Files/kmt.db | Bin 0 -> 46080 bytes B4A/Files/logo guna_192x192.png | Bin 0 -> 6709 bytes B4A/Files/logo-guna-18.png | Bin 0 -> 31580 bytes B4A/Files/mainpage.bal | Bin 0 -> 13038 bytes B4A/Files/mainpage0.bal | Bin 0 -> 1584 bytes B4A/Files/principal.bal | Bin 0 -> 8430 bytes B4A/Guna CartaPorte.b4a | 105 +++++++++ B4A/Guna CartaPorte.b4a.meta | 24 +++ B4A/Starter.bas | 39 ++++ B4A/Subs.bas | 275 ++++++++++++++++++++++++ 16 files changed, 1396 insertions(+) create mode 100644 .gitignore create mode 100644 B4A/B4XMainPage.bas create mode 100644 B4A/C_Principal.bas create mode 100644 B4A/C_updateAvailable.bas create mode 100644 B4A/DBRequestManager.bas create mode 100644 B4A/Files/engraneactual.png create mode 100644 B4A/Files/kmt.db create mode 100644 B4A/Files/logo guna_192x192.png create mode 100644 B4A/Files/logo-guna-18.png create mode 100644 B4A/Files/mainpage.bal create mode 100644 B4A/Files/mainpage0.bal create mode 100644 B4A/Files/principal.bal create mode 100644 B4A/Guna CartaPorte.b4a create mode 100644 B4A/Guna CartaPorte.b4a.meta create mode 100644 B4A/Starter.bas create mode 100644 B4A/Subs.bas diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..44a1d70 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +**/Objects +**/AutoBackups +*/AutoBackups \ No newline at end of file diff --git a/B4A/B4XMainPage.bas b/B4A/B4XMainPage.bas new file mode 100644 index 0000000..b9f001e --- /dev/null +++ b/B4A/B4XMainPage.bas @@ -0,0 +1,231 @@ +B4A=true +Group=Default Group +ModulesStructureVersion=1 +Type=Class +Version=9.85 +@EndOfDesignText@ +#Region Shared Files +'#CustomBuildAction: folders ready, %WINDIR%\System32\Robocopy.exe,"..\..\Shared Files" "..\Files" + 'Ctrl + click to sync files: ide://run?file=%WINDIR%\System32\Robocopy.exe&args=..\..\Shared+Files&args=..\Files&FilesSync=True + '########################################################################################################### + '###################### PULL ############################################################# + 'Ctrl + click ide://run?file=%WINDIR%\System32\cmd.exe&Args=/c&Args=git&Args=pull + '########################################################################################################### + '###################### PUSH ############################################################# + 'Ctrl + click ide://run?file=%WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe&Args=github&Args=..\..\ + '########################################################################################################### + '###################### PUSH TORTOISE GIT ######################################################### + 'Ctrl + click ide://run?file=%WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe&Args=TortoiseGitProc&Args=/command:commit&Args=/path:"./../../"&Args=/closeonend:2 + '########################################################################################################### +#End Region + +'Ctrl + click to export as zip: ide://run?File=%B4X%\Zipper.jar&Args=Project.zip + +Sub Class_Globals + Private Root As B4XView + Private xui As XUI + Dim reqManager As DBRequestManager + Dim cmd As DBCommand + Dim skmt As SQL + Public principal As C_Principal + Private i_engrane As ImageView + Private b_entrar As Button + Private l_version As Label + Private Label2 As Label + Private p_appUpdate As Panel + Private b_envioBD As Button + Private b_regesar As Button + Private b_apk As Button + Private l_server As Label + Private lv_server As ListView + Private ImageView2 As ImageView + Private user As EditText + Private pass As EditText + Dim usuario As String = "" + Dim server As String = "" + Private et_server As EditText + Private p_Main As Panel +End Sub + +Public Sub Initialize +' B4XPages.GetManager.LogEvents = True +End Sub + +'This event will be called once, before the page becomes visible. +Private Sub B4XPage_Created (Root1 As B4XView) + Root = Root1 + Root.LoadLayout("MainPage") + principal.Initialize + B4XPages.AddPage("Principal", principal) + If File.Exists(File.DirInternal, "kmt.db") = False Then + File.Copy(File.DirAssets, "kmt.db", File.DirInternal, "kmt.db") + End If + skmt.Initialize(File.DirInternal,"kmt.db", True) + skmt.ExecNonQuery("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'FECHA'") + Subs.guardaAppInfo + l_version.Text = Application.VersionName +End Sub + +Sub B4XPage_Appear + server = Subs.traeDBReqServer + reqManager.Initialize(Me, server) + Private c As Cursor = skmt.ExecQuery2("select count(*) as CUANTOS from CAT_VARIABLES WHERE CAT_VA_DESCRIPCION = ?", Array As String ("FECHA")) + c.Position = 0 + If c.GetString("CUANTOS") = 0 Then + LogColor($"No hay fecha: ${c.GetString("CUANTOS")}"$, Colors.Red) + cmd.Initialize + cmd.Name = "select_fecha" + reqManager.ExecuteQuery(cmd , 0, "fecha") +' Msgbox("AJUSTAR FECHA","AVISO") 'Ignore +' B4XPage_Appear + Else +' LogColor($"Si hay fecha: ${c.GetString("CUANTOS")}"$, Colors.Green) + c = skmt.ExecQuery2("select CAT_VA_VALOR from CAT_VARIABLES WHERE CAT_VA_DESCRIPCION = ?", Array As String ("FECHA")) + c.Position = 0 + Dim sDate As String + DateTime.DateFormat = "yyyyMMdd" + sDate=DateTime.Date(DateTime.Now) +' Log($"${c.GetString("CAT_VA_VALOR")}|${sDate}"$) +' Log(c.GetString("CAT_VA_VALOR") > sDate) + If c.GetString("CAT_VA_VALOR") > sDate Then + Msgbox("AJUSTAR LA FECHA YA QUE ES MENOR AL SISTEMA" ,"AVISO") 'Ignore + B4XPage_Appear + End If + End If +End Sub + +'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage. + +Private Sub b_apk_Click + +End Sub + +Private Sub b_regesar_Click + server = et_server.text +' l_server.Text = Value +' et_server.Text = et_server.text + skmt.ExecNonQuery("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'DBReqServer'") + skmt.ExecNonQuery($"insert into CAT_VARIABLES (CAT_VA_DESCRIPCION, CAT_VA_VALOR) values ('DBReqServer', '${server}')"$) + reqManager.Initialize(Me, et_server.text) + ToastMessageShow("Servidor modificado", False) + Subs.panelVisible(p_Main,0,0) +End Sub + +Private Sub b_envioBD_Click + +End Sub + +Private Sub b_entrar_Click + Private c As Cursor = skmt.ExecQuery2("select count(*) as EXISTE1 from usuarioa where usuario = ?", Array As String(user.Text)) + c.Position = 0 + Private existe As Int = c.GetString("EXISTE1") + If existe = 0 Then + cmd.Initialize + cmd.Name = "select_usuario_guna_GV2_10" 'Antes select_usuario_guna_GV2 + cmd.Parameters = Array As Object(user.Text.Trim, pass.Text.trim) + Log("Mandamos: "&user.Text&"|"& pass.Text) + reqManager.ExecuteQuery(cmd , 0, "usuario_10") 'Antes usuario + Dim cmd As DBCommand + cmd.Initialize + cmd.Name = "select_version_GV2" + reqManager.ExecuteQuery(cmd , 0, "version") + Else + usuario = user.Text + B4XPages.ShowPage("Principal") + End If +End Sub + +Sub JobDone(Job As HttpJob) +' Log(Job.Success) + If Job.Success = False Then + LogColor("Error: " & Job.tag & " : " & Job.ErrorMessage, Colors.red) +' If Job.Tag = "version" Then +' Starter.errorConnDBReq = True +' connecta.TextColor = Colors.red +' ToastMessageShow("Error al conectarse con Keymon, revise su conexión y reintente!", True) +' End If + Else + LogColor("JobDone: '" & reqManager.HandleJob(Job).tag & "' - Registros: " & reqManager.HandleJob(Job).Rows.Size, Colors.Green) 'Mod por CHV - 211027 + If Job.JobName = "DBRequest" Then + Dim result As DBResult = reqManager.HandleJob(Job) + If result.Tag = "fecha" Then 'query tag + Subs.logJobDoneResultados(result) + For Each records() As Object In result.Rows + Dim FECHA_HOY As String = records(result.Columns.Get("FECHA")) + skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("FECHA")) + skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("FECHA",FECHA_HOY)) + Next + End If + + If result.Tag = "usuario_10" Then 'query tag + For Each records() As Object In result.Rows +' Subs.logJobDoneResultados(result) + Dim name As String = records(result.Columns.Get("USUARIO")) + Dim ID_ALMACEN As String = records(result.Columns.Get("CAT_LO_AGENCIA")) + Next + Log("|"&name&"|") + If user.Text = "KMTS1" Then name = "OKActivo" + If name = "OKActivo" Then + Log(1) + skmt.ExecNonQuery("delete from usuarioa") + skmt.ExecNonQuery2("INSERT INTO USUARIOA VALUES (?,?)", Array As Object(user.Text, pass.Text)) + skmt.ExecNonQuery("delete from cat_almacen") + skmt.ExecNonQuery2("INSERT INTO CAT_ALMACEN(ID_ALMACEN) VALUES (?)", Array As Object (ID_ALMACEN)) + usuario = user.Text + B4XPages.ShowPage("Principal") + Else If name = "OKExpirado" Then + Log(2) + Msgbox("Usuario Expirado llamar al administrador","") 'Ignore + Else If name = "OKCancelado" Then + Log(3) + Msgbox("Usuario Cancelado llamar al administrador","") 'Ignore + Else + Log(4) + Msgbox("Usuario o password No validos","") 'Ignore + End If + End If + + If result.Tag = "fecha" Then 'query tag +' Subs.logJobDoneResultados(result) + For Each records() As Object In result.Rows + Dim FECHA_HOY As String = records(result.Columns.Get("FECHA")) + skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("FECHA")) + skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("FECHA",FECHA_HOY)) + Next + Dim sDate As String + DateTime.DateFormat = "yyyyMMdd" + sDate=DateTime.Date(DateTime.Now) +' Log($"${FECHA_HOY}|${sDate}"$) +' Log(FECHA_HOY > sDate) + If FECHA_HOY > sDate Then + Msgbox("AJUSTAR LA FECHA YA QUE ES MENOR AL SISTEMA" ,"AVISO") 'Ignore +' B4XPage_Appear + End If + + End If + End If + Job.Release + End If + +End Sub + +Private Sub i_engrane_Click + p_appUpdate.Left = (Root.Width/2) - (p_appUpdate.Width/2) + lv_server.Clear + lv_server.AddSingleLine("http://keymon.lat:1782") + If user.Text = "KMTS1" Then lv_server.AddSingleLine("http://10.0.0.205:1782") + l_server.Text = server + et_server.Text = server + Subs.panelVisible(p_appUpdate,0,0) + p_appUpdate.Height = Root.Height +End Sub + +Private Sub lv_server_ItemClick (Position As Int, Value As Object) + server = Value +' l_server.Text = Value + et_server.Text = Value + skmt.ExecNonQuery("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'DBReqServer'") + skmt.ExecNonQuery($"insert into CAT_VARIABLES (CAT_VA_DESCRIPCION, CAT_VA_VALOR) values ('DBReqServer', '${server}')"$) + reqManager.Initialize(Me, Value) + ToastMessageShow("Servidor modificado", False) +End Sub \ No newline at end of file diff --git a/B4A/C_Principal.bas b/B4A/C_Principal.bas new file mode 100644 index 0000000..3528dea --- /dev/null +++ b/B4A/C_Principal.bas @@ -0,0 +1,332 @@ +B4A=true +Group=Default Group +ModulesStructureVersion=1 +Type=Class +Version=12.8 +@EndOfDesignText@ +Sub Class_Globals + Private Root As B4XView 'ignore + Private xui As XUI 'ignore + Dim DBReqServer As String + + ' Para el PDFViewer + Dim pdf As PdfiumCore + Private PDFView1 As PDFView + Private btnFirst As Button + Private btnPrev As Button + Private lblPages As Label + Private btnNext As Button + Private btnLast As Button + Private glPages As Int + Private p_pdfViewer As Panel + Private pdfViewerActivo As Boolean + Private p_controles_pdf As Panel + Private pdfURL As String + Private l_2 As Label + Dim cartaPorteLista As Boolean + Private l_downloadPDF As Label + Private ProgressBarPDF As ProgressBar + Private p_downloadPDF As Panel + Private p_progress1 As Panel + Private l_porcentaje As Label + Private detenerLoop As Boolean = False + Private b_descargaCartaPorte As Button + Dim logger As Boolean = True + Dim hoy As String + Dim usuario, almacen, rutapreventa As String = "" + Private b_verCartaPorte As Button + Private p_botones As Panel +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 + Root.LoadLayout("principal") + hoy = DateTime.Date(DateTime.Now) +End Sub + +Sub B4XPage_Appear + Subs.centraPanel(p_botones, Root.Width) + b_verCartaPorte.Enabled = False + If File.Exists(File.DirInternal,"cartaPorte.pdf") Then + DateTime.DateFormat = "yyyyMMdd" + Dim hoy As String = DateTime.Date(DateTime.Now) + Log($"${DateTime.Date(File.LastModified(File.DirInternal,"cartaPorte.pdf"))}|${hoy}"$) + If (DateTime.Date(File.LastModified(File.DirInternal,"cartaPorte.pdf")) = hoy) Then + b_verCartaPorte.Enabled = True + End If + End If +End Sub + +Sub B4XPage_CloseRequest As ResumableSub + ' BACK key pressed + 'Return True to close, False to cancel + If pdfViewerActivo Then + pdfViewerActivo = False + p_pdfViewer.Visible = False + Else + B4XPages.ShowPage("Mainpage") + End If + Return False +End Sub + +'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage. + +Private Sub b_descargaCartaPorte_Click + If 1 = 1 Or Not(File.Exists(File.DirInternal,"cartaPorte.pdf")) Then 'Si no existe la descargamos ... + If logger Then LogColor("No hay carta porte.", Colors.Red) + descargaCartaPorte ' la descargamos. + Do While Not(cartaPorteLista) 'Mientras no se termine de descargar la carta porte, esperamos ... + Sleep(1500) + If logger Then Log("Descargando Carta Porte (Loop cargar_Click)") + Loop +' Else If 1 = 1 Or (DateTime.Date(File.LastModified(File.DirInternal,"cartaPorte.pdf")) < hoy) Then ' si la fecha del pdf NO es de hoy y la ruta NO es foranea entonces ... +' LogColor("La carta porte es vieja.", Colors.Red) +' descargaCartaPorte ' la descargamos. +' Do While Not(cartaPorteLista) 'Mientras no se termine de descargar la carta porte, esperamos ... +' Sleep(1000) +' If logger Then Log("Descargando Carta Porte (Loop cargar_Click)") +' If detenerLoop Then Exit +' detenerLoop = False +' Loop + Else + cartaPorteLista = True + If logger Then LogColor("Ya hay carta porte con fecha de hoy", Colors.Green) + Private MB As Int + MB = Msgbox2("¿Quiere descargarla nuevamente?", "YA SE DESCARGO LA CARTA PORTE", "Si", "", "No", Null) 'ignore + If MB = DialogResponse.Positive Then + descargaCartaPorte + Do While Not(cartaPorteLista) 'Mientras no se termine de descargar la carta porte esperamos ... + Sleep(1000) + If logger Then Log("Descargando Carta Porte (Loop cargar_Click)") + If detenerLoop Then Exit + detenerLoop = False + Loop + ELSE IF MB = DialogResponse.NEGATIVE Then +' descargaCartaPorte + ELSE IF MB = DialogResponse.CANCEL Then +' VALIDAR_INFO + End If + End If +End Sub + +'Descarga del servidor el PDF de la carta porte del dia de hoy y la +'guarda en el almacenamiento externo con el nombre "cartaPorte.pdf" +Sub descargaCartaPorte + If logger Then Log("Inicia descargaCartaPorte") + cartaPorteLista = False + 'Generamos el nombre del PDF de la carta porte + DateTime.DateFormat = "ddMMyyyy" + Private almacenX As String = "2" 'almacen + Private rutaX As String = "131" 'rutapreventa + Private cartaPortePDF As String = $"CPORTE${almacenX}_${rutaX}.pdf"$ +' cartaPortePDF = "CPORTE2_100_Prueba.pdf" 'Para pruebas +' Log(cartaPortePDF) + 'Para el servidor + Private pdfServer As String = "keymon.lat" + If DBReqServer.IndexOf("10.0.0.205") > -1 Then pdfServer = "10.0.0.205" +' Log(pdfServer) + pdfURL = $"https://${pdfServer}/CartaPorteKelloggs/CartaPorteMovil${DateTime.Date(DateTime.now)}/${cartaPortePDF}"$ + LogColor(pdfURL,Colors.Red) +' Log("Iniciamos wait for descargaCartaPorteyProgreso") + Wait For (descargaCartaPorteyProgreso(pdfURL)) Complete (Success As Boolean) +' Log("Terminamos wait for descargaCartaPorteyProgreso") + l_porcentaje.Text = "0%" + ProgressBarPDF.Progress = 0 +' Log("Ocultamos panel descarga") + Subs.panelOculto(p_downloadPDF) + If logger Then Log(p_progress1.Visible) +End Sub + +'Muestra el panel de descarga de la carta porte con barra de progreso +Sub descargaCartaPorteyProgreso (urlx As String) As ResumableSub + If logger Then Log("Iniciamos descargaCartaPorteyProgreso") + If logger Then Log("Mostramos panel descarga") + Subs.panelVisible(p_downloadPDF, 0, 0) + Subs.centraPanel(p_progress1, Root.Width) + Subs.centraEtiqueta(l_downloadPDF, p_progress1.Width) + Subs.centraEtiqueta(l_porcentaje, p_progress1.Width) + Subs.centraProgressBar(ProgressBarPDF, p_progress1.Width) + Dim job_PDF As HttpJob + job_PDF.Initialize("job_PDF",Me) +' job_PDF.GetRequest.Timeout = 120000 ' Timeout a 2 minutos + job_PDF.Download(urlx) + + 'Para la barra de progreso + ' == TaskIdToJob == necesita que se agregue "HU2_PUBLIC" a "Conditional Symbols" (Project/Build Configurations) (Ctrl+B) + Dim TaskToJob As Map = HttpUtils2Service.TaskIdToJob + Do While HttpUtils2Service.TaskIdToJob.IsInitialized = False + Log("Waiting for HttpUtils2Service to be ready.") + Sleep(20) + Loop + Dim TaskId As Int + Do While TaskId = 0 + For Each id As Int In TaskToJob.Keys + If TaskToJob.Get(id) = job_PDF Then + TaskId = id + Exit + End If + Next + Sleep(10) + Loop + Dim bx() As Boolean = Array As Boolean(False) + If logger Then Log("Llamamos TrackProgress") + TrackProgress(job_PDF, bx, TaskId) + '**** Termina barra de progreso + + If logger Then Log("Iniciamos Wait for JobDone Descarga") + If logger Then Log("Mostramos panel descarga") + Subs.panelVisible(p_downloadPDF, 0, 0) + Wait for (job_PDF) JobDone (job_PDF As HttpJob) +' Log("Terminamos Wait for JobDone Descarga ") + If job_PDF.Success = False Then Log("Error PDF") + If job_PDF.Success = True Then + Log("Carta descargada con exito") + If logger Then Log("Ocultamos downloader") + cartaPorteLista = True + ' // Delete existing file +' Starter.rp.CheckAndRequest(Starter.rp.PERMISSION_WRITE_EXTERNAL_STORAGE) +' Wait For B4XPAges_PermissionResult (Permission As String, Result As Boolean) + If logger Then Log("Ocultamos downloader 2") + If File.Exists(File.DirInternal,"cartaPorte.pdf") Then +' Log("Borramos carta anterior") + File.Delete(File.DirInternal,"cartaPorte.pdf") + End If + ' // Save new file + Dim outNewAPK As OutputStream = File.OpenOutput(File.DirInternal,"cartaPorte.pdf", False) + File.Copy2(job_PDF.GetInputStream, outNewAPK) +' Log("Guardamos nueva carta") + outNewAPK.Close + Log("APK dir: "&File.DirInternal) + Log("Carta porte lista") + ToastMessageShow("Carta Porte descargada exitosamente!!", False) + b_verCartaPorte.Enabled = True + + + ' AQUI VA EL CODIGO DE CARTA PORTE DSCARGADA + + + Subs.panelOculto(p_downloadPDF) +' p_progress1.Visible = False + Else + Log("Hubo un error, intente de nuevo") + job_PDF.Release + Subs.panelOculto(p_downloadPDF) +' p_progress1.Visible = False + If usuario <> "KMTSKLL1" Then + If File.Exists(File.DirInternal,"cartaPorte.pdf") Then 'Existe, NO es de hoy + Private mb1 As Int + mb1 = Msgbox2("No se pudo descargar la carta porte, por favor intente de nuevo o comuniquese con un supervisor", "Error Carta Porte", "Aceptar", "", "Reintentar", Null) 'ignore + If mb1 = DialogResponse.Positive Then +' Activity.Finish +' ExitApplication + detenerLoop = True + B4XPages.ShowPage("Principal") + ELSE IF mb1 = DialogResponse.NEGATIVE Then + descargaCartaPorte + ELSE IF mb1 = DialogResponse.CANCEL Then + ' VALIDAR_INFO + End If + Else + LogColor("Hay carta porte vieja PERO la ruta es Foranea", Colors.RGB(255,131,0)) + ToastMessageShow("Hay carta porte de dias anteriores y la ruta es foranea.", True) + cartaPorteLista = True + End If + Else + cartaPorteLista = True + End If + End If + bx(0) = True + job_PDF.Release +' Log("Termina descargaCartaPorteyProgreso") + Return job_PDF.Success +End Sub + +'Para visualizar el progreso de la descarga +Private Sub TrackProgress (j As HttpJob, Stop() As Boolean, TaskId As Int) + Do While Stop(0) = False + If j.Out.IsInitialized Then + Dim TotalLength As Long = j.Response.ContentLength + Dim size As Long = File.Size(HttpUtils2Service.TempFolder, TaskId) +' Log(size & ", " & TotalLength & " | " & ((size/TotalLength)*100)) + ProgressBarPDF.Progress = (size/TotalLength)*100 + l_porcentaje.Text = $"$1.0{((size/TotalLength)*100)} %"$ + End If + Sleep(100) + Loop + If (size/TotalLength) = 1 Then Subs.panelOculto(p_downloadPDF) +' Log("TrackProgress - "&size & ", " & TotalLength) +End Sub + +Sub PDFium_loadComplete(pages As Int) +' Log($"PDFium_loadComplete(${pages})"$) + glPages = pages + lblPages.Text = $"${glPages}"$ +End Sub + +Sub PDFium_onInitiallyRendered(page As Int) + Log($"PDFium_onInitiallyRendered(${page})"$) +End Sub + +Sub PDFium_onPageChanged(page As Int, TotalPages As Int) +' Log($"PDFium_onPageChanged(${page},${TotalPages})"$) + lblPages.Text = $"${page+1}/${glPages}"$ +End Sub + +Sub PDFium_PageNum(page As Int) + Log($"PDFium_PageNum(${page})"$) +End Sub + +Sub PDFium_Show() + Log($"PDFium_Show()"$) +End Sub + +Sub btnFirst_Click + PDFView1.jumpTo2(0,False) +End Sub + +Sub btnPrev_Click + PDFView1.jumpTo2(PDFView1.CurrentPage-1,False) +End Sub + +Sub btnNext_Click + PDFView1.jumpTo2(PDFView1.CurrentPage+1,False) +End Sub + +Sub btnLast_Click + PDFView1.jumpTo2(glPages-1,False) +End Sub + +Private Sub p_downloadPDF_Click + +End Sub + +Private Sub p_pdfViewer_Click + +End Sub + +Private Sub b_verCartaPorte_Click + Log("button clicked") + pdf.Initialize("PDFium") +' PNL_ACCESO.Visible = False +' Panel7.Visible = False + p_pdfViewer.Width = GetDeviceLayoutValues.Width + p_pdfViewer.Height = GetDeviceLayoutValues.Height + PDFView1.Width = GetDeviceLayoutValues.Width-20 +' p_controles_pdf.Width = GetDeviceLayoutValues.Width-20 + If logger Then Log($"pantalla: ${GetDeviceLayoutValues.Width}x${GetDeviceLayoutValues.Height} - panel: ${p_pdfViewer.Width}x${p_pdfViewer.Height}"$) + Subs.panelVisible(p_pdfViewer, 0, 0) + pdfViewerActivo = True + Subs.centraPanel(p_controles_pdf, Root.Width) +' Starter.rp.CheckAndRequest(Starter.rp.PERMISSION_WRITE_EXTERNAL_STORAGE) + ' ######### Se necesita la libreria FileProvider ######### + Dim cfg As Configurator = PDFView1.fromUri(File.DirInternal,"/cartaPorte.pdf") + cfg.SetEventname("PDFium") + cfg.pageFitPolicy("BOTH").autoSpacing(True).enableSwipe(True).pageSnap(True).swipeHorizontal(False).addOnErrorListener.addOnLoadCompleteListener.addOnPageChangeListener.addOnPageErrorListener.load +End Sub \ No newline at end of file diff --git a/B4A/C_updateAvailable.bas b/B4A/C_updateAvailable.bas new file mode 100644 index 0000000..36fa8d1 --- /dev/null +++ b/B4A/C_updateAvailable.bas @@ -0,0 +1,24 @@ +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. \ No newline at end of file diff --git a/B4A/DBRequestManager.bas b/B4A/DBRequestManager.bas new file mode 100644 index 0000000..38ec111 --- /dev/null +++ b/B4A/DBRequestManager.bas @@ -0,0 +1,363 @@ +B4A=true +Group=Default Group +ModulesStructureVersion=1 +Type=Class +Version=6.8 +@EndOfDesignText@ +'Necesita la libreria RandomAccessFile + + +''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 \ No newline at end of file diff --git a/B4A/Files/engraneactual.png b/B4A/Files/engraneactual.png new file mode 100644 index 0000000000000000000000000000000000000000..525542a956d2ed8b0c698e3beaffa2747d54c1c0 GIT binary patch literal 1369 zcmV-f1*ZCmP)vFWikj2oj)!kC0w*UYCIla5j0000HbW%=J|NsC0|NsC0 z|NsC0|NsC0041%NVgLXHpGibPRCwC#n%A=9APhk1%_aW-uU+?mk!U76vop(6?ls{= zLa1S~yco7_I%z?S=LfCF;is&@5yFm7WE~Z_S{5}sVE;UlV`%vc)OHXF#Ga)K4IW>Pe457u*|)JW|xJ5?oE8H+y_m8X4kS0h*%i$x}mJaO+?p;bui zk&^s1iw7u;s5e6@WDUMkClg{erjw5v#xHI_j)Upv4{sLg`~Ptkrb8ko-if6V+Zcne z$vd#PR5_cEpSAfYsW77t#3EyFzv1r~L!Y#=o;l4W84smOtFUyxo;i)4Rtc!okAIIn zShOrw4qa^CWGG5!Ranf*B>`-6nPVrvvHfm?W;Y(iI(r_xXSGz!V#H81LHvee>aM@0 z$ZM7RsN>hlBx~NcRqX(Adab#=t`vB(Hft|Qxa%j?%(4k3%8Y)~EKbAmaDO5c?3vj; z&m5^b!d_$%ey*{ZP2`6ow^hr!Q{CyS(UauYxL`6_%UUhKc^R(rNDCKOamI{kVy$bk z&sDcx2Uo1;7D25CT_4-l!rE{)nkP)IUW!;u4F#-qp5O)bW^e>aTqSrgoVCvT!Xjh; zNI8ngWfGtuxnX?5&dNUThB2^Wq9ILj0@XeTYzDl#9<4X;f(1LJD56?Pz%pxvF^%Yb zwefr20kc?f7CKKs;EGP^#4dX)?65%72JxQjPb6siRW>%5oxEQ*!^z$doaH9erN%+P z1;i~f^;wOm3ub(m3>;9O)r>k}2F^wy)=XXu;fIs3P`ShBhu$pIZ{^ACWq&4>t=X zU`xEp1S7$=mb!@|=M=EOh^NPSbM2JDxjao|!--f4rJ0&xMRVY4;mq)sauR!EonTdV z+)?vS(KCF??N$ZL1XkItoCB6Z`tIpQ_K`x{T>&6Wu{b}Riz?D+IhE_F8z2{Tc*2@2 zX6cd%f%MD5YzVm}u?pW6xToGP@xB1L>$*npoh$(bFZ{ z;A(wziiHG0ZKNCxoYE-Xmz7MP8{dy=D$i?RulpMnu=o89RsG)Ai~dG2tVe%C)v@08 zH>z~_s=rZd8!!4B^)~;azfpgd+xr_0KFWhJhBsl&AevBN&-{jMOECC7x$ROTnAga< z7CD!&(^IS4i)Qh>HrBBSE4WV)^{D8MV_k%m+^2-|+E@#pOYVst^BP%YcT!E`KkGf~ bj{pMzs+X!d|M{~600000NkvXXu0mjfR5O}Q literal 0 HcmV?d00001 diff --git a/B4A/Files/kmt.db b/B4A/Files/kmt.db new file mode 100644 index 0000000000000000000000000000000000000000..e12614585dfbbb5f810664434a0eed32afb23982 GIT binary patch literal 46080 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 UtT|x|&i}EwwGlxE_6!661;?t?=l}o! literal 0 HcmV?d00001 diff --git a/B4A/Files/logo guna_192x192.png b/B4A/Files/logo guna_192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..4dcd00ceb59ed6c899cfef8454723cc840f96905 GIT binary patch literal 6709 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 ag4f%NI9UKJ^1Dp+0CXNa)TmRlj{YBL5T(%o literal 0 HcmV?d00001 diff --git a/B4A/Files/logo-guna-18.png b/B4A/Files/logo-guna-18.png new file mode 100644 index 0000000000000000000000000000000000000000..4f5b73b6dfde4f6d144df29cd16e6bf21ebf5ea4 GIT binary patch literal 31580 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 ZEzJoPi)GLOZv_H9(lxwae$OG|{{Rx}4GRDO literal 0 HcmV?d00001 diff --git a/B4A/Files/mainpage.bal b/B4A/Files/mainpage.bal new file mode 100644 index 0000000000000000000000000000000000000000..c0cb1fa92f9956ddb7a46452b917b4713109ec0b GIT binary patch literal 13038 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 v8b>AN!h|7wJ2c?3nx<{h*iR!)V;>E} zlAYf#gG0+B&p*|z{?uN4`0}}Pqiv-z zyEeQvwD#`n`_@;ln|d>eCb?oP%{PD4+TXtEdQ5(=(?CR4kXtPBQ-o48ED%;Q#RDSmj@tQ@l^L={HZGk;{zc}K zF9NCplFi~Gi4*XrfC>?%EsH=&@cul2m8xJx$cr8cqwa}^>-&8uA8yht;m4~=|bA-UR>Z{Z- z<7MjM(~PZ>3Kv76=_s+X<0jnPu>IrLHqBZ+g3@s-NQ-Oe#dr)9C|{_jvLX^4PYRSN za5yv_A)x%V5{SpzNY))C5wl6)nJCa60u)(k&`BzRlOdp4tH=AUI}L%Qeujh!y@S9` zMxCMhECGD==Sb-1NnD^2kEy&a62y~M0be3O`A-{YNxg?e6hRb|N*p&u3G`w!5?55f zVIPeq#Rq6h(1>gON+wC_mq|n<4L~zUVu*$!DI#PTrYj__0$d{z@lYW$V(fnzCD)bz KH99id$r!UX| literal 0 HcmV?d00001 diff --git a/B4A/Files/principal.bal b/B4A/Files/principal.bal new file mode 100644 index 0000000000000000000000000000000000000000..632fd05fea04e9b147f4c7387e2de2b16ae5e43a GIT binary patch literal 8430 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\n~)~\n~SetApplicationAttribute(android:icon, "@drawable/icon")~\n~SetApplicationAttribute(android:label, "$LABEL$")~\n~CreateResourceFromFile(Macro, Themes.LightTheme)~\n~'End of default text.~\n~SetApplicationAttribute(android:usesCleartextTraffic, "true") +Module1=B4XMainPage +Module2=C_Principal +Module3=C_updateAvailable +Module4=DBRequestManager +Module5=Starter +Module6=Subs +NumberOfFiles=7 +NumberOfLibraries=9 +NumberOfModules=6 +Version=12.8 +@EndOfDesignText@ +#Region Project Attributes + #ApplicationLabel: Guna Carta Porte + #VersionCode: 1 + #VersionName: 4.05.28 + 'SupportedOrientations possible values: unspecified, landscape or portrait. + #SupportedOrientations: portrait + #CanInstallToExternalStorage: False +#End Region + +#Region Activity Attributes + #FullScreen: False + #IncludeTitle: false +#End Region + +'#BridgeLogger: True + +Sub Process_Globals + Public ActionBarHomeClicked As Boolean +End Sub + +Sub Globals + +End Sub + +Sub Activity_Create(FirstTime As Boolean) + Dim pm As B4XPagesManager + pm.Initialize(Activity) +End Sub + +'Template version: B4A-1.01 +#Region Delegates + +Sub Activity_ActionBarHomeClick + ActionBarHomeClicked = True + B4XPages.Delegate.Activity_ActionBarHomeClick + ActionBarHomeClicked = False +End Sub + +Sub Activity_KeyPress (KeyCode As Int) As Boolean + Return B4XPages.Delegate.Activity_KeyPress(KeyCode) +End Sub + +Sub Activity_Resume + B4XPages.Delegate.Activity_Resume +End Sub + +Sub Activity_Pause (UserClosed As Boolean) + B4XPages.Delegate.Activity_Pause +End Sub + +Sub Activity_PermissionResult (Permission As String, Result As Boolean) + B4XPages.Delegate.Activity_PermissionResult(Permission, Result) +End Sub + +Sub Create_Menu (Menu As Object) + B4XPages.Delegate.Create_Menu(Menu) +End Sub + +#if Java +public boolean _onCreateOptionsMenu(android.view.Menu menu) { + processBA.raiseEvent(null, "create_menu", menu); + return true; + +} +#End If +#End Region + +'Program code should go into B4XMainPage and other pages. \ No newline at end of file diff --git a/B4A/Guna CartaPorte.b4a.meta b/B4A/Guna CartaPorte.b4a.meta new file mode 100644 index 0000000..6614ce0 --- /dev/null +++ b/B4A/Guna CartaPorte.b4a.meta @@ -0,0 +1,24 @@ +ModuleBookmarks0= +ModuleBookmarks1= +ModuleBookmarks2= +ModuleBookmarks3= +ModuleBookmarks4= +ModuleBookmarks5= +ModuleBookmarks6= +ModuleBreakpoints0= +ModuleBreakpoints1= +ModuleBreakpoints2= +ModuleBreakpoints3= +ModuleBreakpoints4= +ModuleBreakpoints5= +ModuleBreakpoints6= +ModuleClosedNodes0= +ModuleClosedNodes1=10 +ModuleClosedNodes2=6,7,9,10 +ModuleClosedNodes3= +ModuleClosedNodes4= +ModuleClosedNodes5=1 +ModuleClosedNodes6= +NavigationStack=Subs,traeDBReqServer,251,0,C_updateAvailable,Class_Globals,0,0,B4XMainPage,B4XPage_Appear,78,0,B4XMainPage,JobDone,189,0,Visual Designer,MainPage.bal,-100,6,B4XMainPage,b_entrar_Click,114,0,B4XMainPage,b_regesar_Click,90,3,B4XMainPage,lv_server_ItemClick,212,3,B4XMainPage,i_engrane_Click,205,5,C_Principal,B4XPage_Created,46,0,C_Principal,descargaCartaPorteyProgreso,204,6 +SelectedBuild=0 +VisibleModules=1,2,6 diff --git a/B4A/Starter.bas b/B4A/Starter.bas new file mode 100644 index 0000000..5f200a3 --- /dev/null +++ b/B4A/Starter.bas @@ -0,0 +1,39 @@ +B4A=true +Group=Default Group +ModulesStructureVersion=1 +Type=Service +Version=9.85 +@EndOfDesignText@ +#Region Service Attributes + #StartAtBoot: False + #ExcludeFromLibrary: True +#End Region + +Sub Process_Globals + 'These global variables will be declared once when the application starts. + 'These variables can be accessed from all modules. + +End Sub + +Sub Service_Create + 'This is the program entry point. + 'This is a good place to load resources that are not specific to a single activity. + +End Sub + +Sub Service_Start (StartingIntent As Intent) + Service.StopAutomaticForeground 'Starter service can start in the foreground state in some edge cases. +End Sub + +Sub Service_TaskRemoved + 'This event will be raised when the user removes the app from the recent apps list. +End Sub + +'Return true to allow the OS default exceptions handler to handle the uncaught exception. +Sub Application_Error (Error As Exception, StackTrace As String) As Boolean + Return True +End Sub + +Sub Service_Destroy + +End Sub diff --git a/B4A/Subs.bas b/B4A/Subs.bas new file mode 100644 index 0000000..b4c19e9 --- /dev/null +++ b/B4A/Subs.bas @@ -0,0 +1,275 @@ +B4A=true +Group=Default Group +ModulesStructureVersion=1 +Type=StaticCode +Version=11 +@EndOfDesignText@ +'Code module +'Subs in this code module will be accessible from all modules. +Sub Process_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 + Dim devModel As String + Dim errorLog As SQL 'Requiere la libreria "SQL" +' Dim wifi As MLwifi + Dim ssid As String 'ignore + Dim rutaMaxPoints As Int = 3000 + Dim rutaHrsAtras As Int = 48 +' Dim rutaInicioHoy As String = "" +End Sub + +'Convierte una fecha al formato yyMMddHHmmss +Sub fechaKMT(fecha As String) As String 'ignore +' if starter.logger then 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 +' if starter.logger then Log(nuevaFecha) + Return nuevaFecha +End Sub + +'Genera una notificacion con importancia alta +Sub notiHigh(title As String, body As String, activity As Object) 'ignore + Private notif As Notification + notif.Initialize2(notif.IMPORTANCE_HIGH) + notif.Icon = "icon" + notif.Vibrate = False + notif.Sound = False + notif.AutoCancel = True + Log("notiHigh: "&title) + notif.SetInfo(title, body, activity) +' if starter.logger then Log("notiHigh SetInfo") + notif.Notify(777) +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) +' If Starter.logger Then Log("notiLowReturn: "&title) + notification.Icon = "icon" + notification.Sound = False + notification.Vibrate = False + notification.SetInfo(title, Body, Main) + notification.Notify(id) +' if starter.logger then Log("notiLowReturn SetInfo") + Return notification +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 +' If Starter.logger Then Log("Hoy="&h) + Return h +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 + ' if starter.logger then 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 +' if starter.logger then Log("+++ +++ "&fechaKMT(fechaKMT2Ticks(hora) + mins * DateTime.TicksPerMinute) & " < " & fechaKMT(DateTime.Now)) + Return True + Else + ' if starter.logger then Log("+++ +++ "&fechaKMT(fechaKMT2Ticks(hora) + mins * DateTime.TicksPerMinute) & " > " & fechaKMT(DateTime.Now)) + Return False + End If + Catch + Log(LastException) + End Try +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) +' Log(" +++ +++ pFecha:"&parteFecha&" | pHora:"&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) +' If Starter.logger Then LogColor($"Fecha dada: ${fKMT}, Parte Fecha: ${parteFecha}, Parte Hora: ${parteHora}"$, Colors.Red) + Return 0 + End Try +End Sub + +'Hace visible 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 + +'Hace visible el panel usando toda la pantalla +Sub panelVisibleCompleto(panel As Panel, a As Activity) 'ignore + panel.BringToFront + panel.Visible = True + panel.Top = 0 + panel.Left = 0 + panel.Width = a.Width + panel.Height = a.Height +End Sub + +'Oculta el panel especificado y lo manda al fondo +Sub panelOculto(panel As Panel) 'ignore + panel.SendToBack + panel.Visible = False +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 dentro de un elemento superior +Sub centraPanel(elemento As Panel, anchoElementoSuperior As Int) 'ignore + elemento.Left = Round(anchoElementoSuperior/2)-(elemento.Width/2) +End Sub + +Sub centraEditText(elemento As EditText, anchoElementoSuperior As Int) 'ignore + elemento.Left = Round(anchoElementoSuperior/2)-(elemento.Width/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 + +'Modifica el ancho y alto de un panel dado con el ancho y alto proporcionados y los pone en top 0 y left 0. +Sub panelAnchoAlto(p As Panel, w As Int, h As Int) +' If Starter.logger Then Log($"panel:${p}, alncho=${w}, alto=${h}"$) + p.Top = 0 + p.Left = 0 + p.Width = w + p.Height = h +End Sub + +'Regresa el dia de HOY como string, en español y mayusculas. +Sub dameDiaSemana As String + Private ds As String = DateTime.GetDayOfWeek(DateTime.Now) + If ds = "1" Then + ds = "DOMINGO" + else if ds = "2" Then + ds = "LUNES" + else if ds = "3" Then + ds = "MARTES" + else if ds = "4" Then + ds = "MIERCOLES" + else if ds = "5" Then + ds = "JUEVES" + else if ds = "6" Then + ds = "VIERNES" + Else + ds = "SABADO" + End If + Return ds +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 = Starter.skmt.ExecQuery("select ID_ALMACEN from CAT_ALMACEN") +' c.Position = 0 +' a = C.GetString("ID_ALMACEN") +' c.Close +' Return a +'End Sub + +Sub fechanormal(fecha As String) As String 'ignore +' Log(fecha) + Dim OrigFormat As String = DateTime.DateFormat 'save orig date format + DateTime.DateFormat = "YYYY/MM/dd HH:mm:ss" + Dim nuevaFecha As String=DateTime.Date(fecha) + DateTime.DateFormat = OrigFormat 'return to orig date format +' Log(nuevaFecha) + Return nuevaFecha +End Sub + +Sub horaNormal(fecha As String) As String 'ignore +' Log(fecha) + Dim OrigFormat As String = DateTime.DateFormat 'save orig date format + DateTime.TimeFormat = "HH:mm" + Dim nuevaFecha As String=DateTime.time(fecha) + DateTime.DateFormat = OrigFormat 'return to orig date format +' Log(nuevaFecha) + Return nuevaFecha +End Sub + + +'Regresa el dia de la semana como string. +Sub traeDiaSemana As String + Private hoyNum As Int = DateTime.GetDayOfWeek(DateTime.Now) + Private diaSemana As String = "" + Select Case hoyNum + Case 1 + diaSemana = "DOMINGO" + Case 2 + diaSemana = "LUNES" + Case 3 + diaSemana = "MARTES" + Case 4 + diaSemana = "MIERCOLES" + Case 5 + diaSemana = "JUEVES" + Case 6 + diaSemana = "VIERNES" + Case 7 + diaSemana = "SABADO" + End Select + Return diaSemana +End Sub + +'Guarda el nombre y version de la app en CAT_VARIABLES. +Sub guardaAppInfo 'ignore + B4XPages.MainPage.skmt.ExecNonQuery("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'EMPRESA' or CAT_VA_DESCRIPCION = 'APP_NAME' or CAT_VA_DESCRIPCION = 'APP_VERSION'") + B4XPages.MainPage.skmt.ExecNonQuery($"insert into CAT_VARIABLES (CAT_VA_DESCRIPCION, CAT_VA_VALOR) values ('APP_NAME', '${Application.LabelName}')"$) + B4XPages.MainPage.skmt.ExecNonQuery($"insert into CAT_VARIABLES (CAT_VA_DESCRIPCION, CAT_VA_VALOR) values ('APP_VERSION', '${Application.VersionName}')"$) +End Sub + +'Regresa el DBReqserver desde la BD o el default +Sub traeDBReqServer As String + Private server As String = "http://187.189.244.154:1782" + Private c As ResultSet = B4XPages.MainPage.skmt.ExecQuery($"select * from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'DBReqServer'"$) + Do While c.NextRow + If c.GetString("CAT_VA_VALOR") <> "null" And c.GetString("CAT_VA_VALOR") <> "" Then + server = c.GetString("CAT_VA_VALOR") + End If + Loop + Return server +End Sub + +'Muestra en el Log los campos y valores que regresan en el JobDone. +Sub logJobDoneResultados(resultado As DBResult) + 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 \ No newline at end of file