Spanish Cabecera detalle

Miguel Santillan

Member
Licensed User
Buenas noches, el problema que tengo es que grabo un pedido y el detalle en la base sqlite de android. Luego me conecto a mi servidor web y le paso la cabecera y detalle.
El problema es que algunas veces el detalle se mezcla con el siguiente y me he dado cuenta que es debido a que no deja terminar un detalle completo y comienza otro.
o sea a veces, no todas, el detalle se corta debido a que inicia antes de que termine la transaccion. Paso el código para ver si alguien me puede dar una mano con este tema, que tengo
bien en claro que es por falta de conocimiento. Muchas gracias.
MIGUEL
Espero haber pegado bien el código
Prog:
Sub Btnsincronizacion_Click
    LblTipo.Text = "Preparando Actualizacion en Central"
    LblTipo.Color = Colors.Blue
    LblTipo.TextColor = Colors.Yellow

    Dim Proceso As String
    rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result Then
    Log("Con Permisos")
    Else
    Log("Sin Permisos")
    End If
    Log(File.DirAssets & " - Internal: " & File.DirRootExternal & " - External: " & File.DirRootExternal)
    
    If SQL1.IsInitialized = False Then
        SQL1.Initialize(File.DirRootExternal, "db_xxxx.db", True)
        'Log(File.DirRootExternal)
    End If
    
    Dim Query As String
    
    Registro = SQL1.ExecQuery("select id_repartidor, nombre_vendedor from usuarios")
    For n = 0 To Registro.RowCount - 1
        Registro.Position = n
        X_id_vendedor     = Registro.GetInt("id_repartidor")
        X_nombre_vendedor = Registro.GetString("nombre_vendedor")
    Next
    X_Cerrado = "S"
    Registro = SQL1.ExecQuery2("select id_pedido, usuario, fecha, hora, pedidos.id_cliente, total, descuento_total, leyenda, cerrado, clientes.nombres from pedidos inner join clientes on pedidos.id_cliente = clientes.id_cliente where cerrado = ?", Array As String(X_Cerrado))
    
    Log(Registro.RowCount)
    For n = 0 To Registro.RowCount - 1
        Registro.Position = n
        X_id_pedido       = Registro.GetInt("id_pedido")
        X_Usuario         = Registro.GetString("usuario")
        X_fecha           = Registro.GetString("fecha")
        X_hora            = Registro.GetString("hora")
        X_id_cliente      = Registro.GetInt("id_cliente")
        X_Total           = Registro.GetDouble("total")
        X_descuento_total = Registro.GetDouble("descuento_total")
        X_Leyenda         = Registro.GetString("leyenda")
        X_Cerrado         = Registro.GetString("cerrado")
        X_nombre_cliente  = Registro.GetString("nombres")
        If X_id_pedido <> 0  Then
            Proceso = "Procesa Pedidos"
            Registro9 = SQL1.ExecQuery("select sum(precio) as precio from itemsped where id_pedido = " & X_id_pedido)
            For x = 0 To Registro9.RowCount - 1
                Registro9.Position = x
                X_Total     = Registro9.GetDouble("precio")
            Next
            LblTipo.Text = "Procesando Pedido " & X_id_pedido
            Dim Query As String
            Query="insert into pedidos (id_pedido, usuario, fecha, hora, id_cliente, nombre_cliente, total, dto_total, fecha_ingreso, fecha_grabacion_tablet, hora_grabacion_tablet, fecha_ingreso_servidor, hora_ingreso_servidor, leyenda) values (" & X_id_pedido & ",'" & X_Usuario.Trim & "','" & X_fecha.Trim & "','" & X_hora.Trim & "'," & X_id_cliente & ",'" & X_nombre_cliente.Trim & "'," & X_Total & "," & X_descuento_total & ",'" & Fecha_hoy & "','" & X_fecha.Trim & "','" & X_hora.Trim & "','" & Fecha_hoy & "','" & Hora_hoy & "','" & X_Leyenda & "')"
            Dim Cantidad_registros As Int
            Dim Registros As List
            Dim Job As HttpJob
            Dim Jobname As String
            Job.JobName = "Procesa Pedido"
            Job.Initialize(Jobname, Me)
            Job.PostString("http://" & Main.Direccion_ip & "/Todocerca/sincroniza1.php", Query)
            wait for(Job) JobDone(Job As HttpJob)
            
            If Job.Success Then
                Dim res As String
                res = Job.GetString
                Dim parser As JSONParser
                parser.Initialize(res)
                Log("Respuesta del Servidor para Cabecera Pedido: " & res)
                Dim req As OkHttpRequest
                Dim Query As String
                ProgressDialogHide
                Dim m As Map
                m = parser.NextObject
                Registros = m.Get("Respuesta")
                Cantidad_registros = Registros.Size
                If Registros.Size > 0 Then
                    For i = 0 To Registros.Size - 1
                        m = Registros.Get(i)
                        Codigo_error      = m.Get("codigo_error")
                        If Codigo_error = "OK" Then
                            Proceso = "Procesa Detalle Pedidos"
                            Dim X_Cerrado As String = "S"
                            SQL1.ExecNonQuery("update pedidos set cerrado = '" & X_Cerrado.Trim &  "' where id_pedido = " & X_id_pedido)
                            Registro_Detalle = SQL1.ExecQuery("select id_orden_itemsped, id_pedido, itemsped.id_articulo, cantidad, descuento, id_cliente, unitario, itemsped.precio, bonificado, unitario_lista, id_usuario, nombre_articulo from itemsped inner join articulos on itemsped.id_articulo = articulos.articulo where id_pedido = " & X_id_pedido)
                            For x = 0 To Registro_Detalle.RowCount - 1
                                Registro_Detalle.Position = x
                                X_id_articulo     = Registro_Detalle.GetString("itemsped.id_articulo")
                                X_Cantidad        = Registro_Detalle.GetInt("cantidad")
                                X_Descuento       = Registro_Detalle.GetDouble("descuento")
                                X_id_cliente      = Registro_Detalle.GetInt("id_cliente")
                                X_Unitario        = Registro_Detalle.GetDouble("unitario")
                                X_Precio          = Registro_Detalle.GetDouble("itemsped.precio")
                                X_Bonificado      = Registro_Detalle.GetInt("bonificado")
                                X_unitario_lista  = Registro_Detalle.GetDouble("unitario_lista")
                                X_Usuario         = Registro_Detalle.GetString("id_usuario")
                                X_Orden_itemsped  = Registro_Detalle.GetInt("id_orden_itemsped")
                                x_nombre_articulo = Registro_Detalle.GetString("nombre_articulo")
                                Dim Query2 As String
                                Dim Pedido_grabado As String
                                Pedido_grabado = " Select pedidos.id_orden_pedido from pedidos where pedidos.id_pedido = "
                                Query2 = "insert into itemsped (id_pedido, articulo, aplicacion, cantidad, bonificada, id_cliente, porcentaje_descuento, unitario_lista, unitario, id_orden_pedido) values (" & X_id_pedido & ",'" & X_id_articulo.Trim & "','" & x_nombre_articulo.Trim & "'," & X_Cantidad & "," & X_Bonificado & "," & X_id_cliente & "," & X_Descuento & "," & X_unitario_lista & "," & X_Unitario & ",(" & Pedido_grabado & X_id_pedido & "))"
                                Log(Query2)
                                Dim Cantidad_registros As Int
                                Dim Registros As List
                                Dim Job As HttpJob
                                Dim Jobname As String
                                Job.JobName = "Procesa Pedido"
                                Job.Initialize(Jobname, Me)
                                Log(Query)
                                Job.PostString("http://" & Main.Direccion_ip & "/Todocerca/sincroniza1.php", Query2)
                                wait for(Job) JobDone(Job As HttpJob)
                                
                                If Job.Success Then
                                    Dim res As String
                                    res = Job.GetString
                                    Dim parser As JSONParser
                                    parser.Initialize(res)
'                                    Log("Respuesta detalle Pedido: " & res)
                                    Dim req As OkHttpRequest
                                    Dim Query As String
                                    ProgressDialogHide
                                    Dim m As Map
                                    m = parser.NextObject
                                    Registros = m.Get("Respuesta")
                                    Cantidad_registros = Registros.Size
                                    If Registros.Size > 0 Then
                                        For i = 0 To Registros.Size - 1
                                            m = Registros.Get(i)
                                            Codigo_error      = m.Get("codigo_error")
                                        Next
                                        Job.Release
                                    End If
                                End If
                            Next
                        End If
                    Next
                    Job.Release
                End If
            End If
        End If
    Next
    LblTipo.Text = "Pedidos en Central Actualizados"
    Activity.Finish
 
Last edited:

Miguel Santillan

Member
Licensed User
Edgard, muchas gracias por tu respuesta.
El tema de los "wait" es algo que todavía no lo puedo solucionar correctamente.
Tal vez me puedas ayudar un poquito, sin querer abusar de tu amabilidad. Al colocar un wait for significa que hasta que no procese el job, el hilo del programa no continua?
es así o me equivoco.

Si llegas a tener algún pequeño ejemplo de cabecera detalle con wait for, sería bienvenido. (es mucho pedir)

Con respecto a lo adicional. Tienes toda la razón, es un id aleatorio de 7 cifras que muy difícil se pueda repetir (pero puede ocurrir)
Me dices que no es recomendable tener servicios web que realicen directamente comandos a la base de datos. Estos significaría pasar los valores y que el programa en php
realice la ejecución en el servidor?

Muchísimas gracias.
Miguel
 

edgar_ortiz

Active Member
Licensed User
Longtime User
Miguel

Con el tema del Wait: desde la perspectiva de la subrutina que llama, usar Sleep y/o Wait For son equivalentes a llamar un "Return".
https://www.b4x.com/android/forum/threads/b4x-okhttputils2-with-wait-for.79345/

Con el codigo de ejemplo, utilizando tu codigo, esto "deberia" de funcionar
B4X:
Sub Btnsincronizacion_Click
    LblTipo.Text = "Preparando Actualizacion en Central"
    LblTipo.Color = Colors.Blue
    LblTipo.TextColor = Colors.Yellow

    Dim Proceso As String
    rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result Then
    Log("Con Permisos")
    Else
    Log("Sin Permisos")
    End If
    Log(File.DirAssets & " - Internal: " & File.DirRootExternal & " - External: " & File.DirRootExternal)
   
    If SQL1.IsInitialized = False Then
        SQL1.Initialize(File.DirRootExternal, "db_xxxx.db", True)
        'Log(File.DirRootExternal)
    End If
   
    Dim Query As String
   
    Registro = SQL1.ExecQuery("select id_repartidor, nombre_vendedor from usuarios")
    For n = 0 To Registro.RowCount - 1
        Registro.Position = n
        X_id_vendedor     = Registro.GetInt("id_repartidor")
        X_nombre_vendedor = Registro.GetString("nombre_vendedor")
    Next
    X_Cerrado = "S"
    Registro = SQL1.ExecQuery2("select id_pedido, usuario, fecha, hora, pedidos.id_cliente, total, descuento_total, leyenda, cerrado, clientes.nombres from pedidos inner join clientes on pedidos.id_cliente = clientes.id_cliente where cerrado = ?", Array As String(X_Cerrado))
   
    Log(Registro.RowCount)
    For n = 0 To Registro.RowCount - 1
        Registro.Position = n
        X_id_pedido       = Registro.GetInt("id_pedido")
        X_Usuario         = Registro.GetString("usuario")
        X_fecha           = Registro.GetString("fecha")
        X_hora            = Registro.GetString("hora")
        X_id_cliente      = Registro.GetInt("id_cliente")
        X_Total           = Registro.GetDouble("total")
        X_descuento_total = Registro.GetDouble("descuento_total")
        X_Leyenda         = Registro.GetString("leyenda")
        X_Cerrado         = Registro.GetString("cerrado")
        X_nombre_cliente  = Registro.GetString("nombres")
        If X_id_pedido <> 0  Then
            Proceso = "Procesa Pedidos"
            Registro9 = SQL1.ExecQuery("select sum(precio) as precio from itemsped where id_pedido = " & X_id_pedido)
            For x = 0 To Registro9.RowCount - 1
                Registro9.Position = x
                X_Total     = Registro9.GetDouble("precio")
            Next
            LblTipo.Text = "Procesando Pedido " & X_id_pedido
            Dim Query As String
            Query="insert into pedidos (id_pedido, usuario, fecha, hora, id_cliente, nombre_cliente, total, dto_total, fecha_ingreso, fecha_grabacion_tablet, hora_grabacion_tablet, fecha_ingreso_servidor, hora_ingreso_servidor, leyenda) values (" & X_id_pedido & ",'" & X_Usuario.Trim & "','" & X_fecha.Trim & "','" & X_hora.Trim & "'," & X_id_cliente & ",'" & X_nombre_cliente.Trim & "'," & X_Total & "," & X_descuento_total & ",'" & Fecha_hoy & "','" & X_fecha.Trim & "','" & X_hora.Trim & "','" & Fecha_hoy & "','" & Hora_hoy & "','" & X_Leyenda & "')"
            Dim Cantidad_registros As Int
            Dim Registros As List
            '
            Dim rs as ResumableSub = Enviar(Query)
            Wait For (rs) Complete (Job_Datos as String)
            '
            If Job_Datos <> "" Then
                Dim res As String
                res = Job_Datos
                Dim parser As JSONParser
                parser.Initialize(res)
                Log("Respuesta del Servidor para Cabecera Pedido: " & res)
                Dim req As OkHttpRequest
                Dim Query As String
                ProgressDialogHide
                Dim m As Map
                m = parser.NextObject
                Registros = m.Get("Respuesta")
                Cantidad_registros = Registros.Size
                If Registros.Size > 0 Then
                    For i = 0 To Registros.Size - 1
                        m = Registros.Get(i)
                        Codigo_error      = m.Get("codigo_error")
                        If Codigo_error = "OK" Then
                            Proceso = "Procesa Detalle Pedidos"
                            Dim X_Cerrado As String = "S"
                            SQL1.ExecNonQuery("update pedidos set cerrado = '" & X_Cerrado.Trim &  "' where id_pedido = " & X_id_pedido)
                            Registro_Detalle = SQL1.ExecQuery("select id_orden_itemsped, id_pedido, itemsped.id_articulo, cantidad, descuento, id_cliente, unitario, itemsped.precio, bonificado, unitario_lista, id_usuario, nombre_articulo from itemsped inner join articulos on itemsped.id_articulo = articulos.articulo where id_pedido = " & X_id_pedido)
                            For x = 0 To Registro_Detalle.RowCount - 1
                                Registro_Detalle.Position = x
                                X_id_articulo     = Registro_Detalle.GetString("itemsped.id_articulo")
                                X_Cantidad        = Registro_Detalle.GetInt("cantidad")
                                X_Descuento       = Registro_Detalle.GetDouble("descuento")
                                X_id_cliente      = Registro_Detalle.GetInt("id_cliente")
                                X_Unitario        = Registro_Detalle.GetDouble("unitario")
                                X_Precio          = Registro_Detalle.GetDouble("itemsped.precio")
                                X_Bonificado      = Registro_Detalle.GetInt("bonificado")
                                X_unitario_lista  = Registro_Detalle.GetDouble("unitario_lista")
                                X_Usuario         = Registro_Detalle.GetString("id_usuario")
                                X_Orden_itemsped  = Registro_Detalle.GetInt("id_orden_itemsped")
                                x_nombre_articulo = Registro_Detalle.GetString("nombre_articulo")
                                Dim Query2 As String
                                Dim Pedido_grabado As String
                                Pedido_grabado = " Select pedidos.id_orden_pedido from pedidos where pedidos.id_pedido = "
                                Query2 = "insert into itemsped (id_pedido, articulo, aplicacion, cantidad, bonificada, id_cliente, porcentaje_descuento, unitario_lista, unitario, id_orden_pedido) values (" & X_id_pedido & ",'" & X_id_articulo.Trim & "','" & x_nombre_articulo.Trim & "'," & X_Cantidad & "," & X_Bonificado & "," & X_id_cliente & "," & X_Descuento & "," & X_unitario_lista & "," & X_Unitario & ",(" & Pedido_grabado & X_id_pedido & "))"
                                Log(Query2)
                                Dim Cantidad_registros As Int
                                Dim Registros As List
                                '
                                Dim rs as ResumableSub = Enviar(Query2)
                                Wait For (rs) Complete (Job_Datos as String)
                                '
                                If Job_Datos <> "" Then
                                    Dim res As String
                                    res = Job_Datos
                                    Dim parser As JSONParser
                                    parser.Initialize(res)
'                                    Log("Respuesta detalle Pedido: " & res)
                                    Dim req As OkHttpRequest
                                    Dim Query As String
                                    ProgressDialogHide
                                    Dim m As Map
                                    m = parser.NextObject
                                    Registros = m.Get("Respuesta")
                                    Cantidad_registros = Registros.Size
                                    If Registros.Size > 0 Then
                                        For i = 0 To Registros.Size - 1
                                            m = Registros.Get(i)
                                            Codigo_error      = m.Get("codigo_error")
                                        Next
                                        Job.Release
                                    End If
                                End If
                            Next
                        End If
                    Next
                    ' Job.Release  <- Ya NO aplica
                End If
            End If
        End If
    Next
    LblTipo.Text = "Pedidos en Central Actualizados"
    Activity.Finish
   
    Sub Enviar (ParQuery as String) as ResumableSub
        Dim Resultado as String
        Dim Job As HttpJob
        Dim Jobname As String
        Job.JobName = "Procesa Pedido"
        Job.Initialize(Jobname, Me)
        Job.PostString("http://" & Main.Direccion_ip & "/Todocerca/sincroniza1.php", ParQuery)
        wait for(Job) JobDone(Job As HttpJob)
        '
        If Job.Success Then
            Resultado = Job.GetString
        Else
            Resultado = ""
        End If
        '
        Job.Release
        '
        Return Resultado
    End Sub

Con respecto al Codigo del Pedido, lo que yo hago es:
- utilizar un campo "auto-incrementable (PK)" en la base de datos
- primero verificar si ya hay pedido con esas características en la base de datos, de ser así devuelvo el "PK"
- NO existe: Grabo los datos y devuelvo "PK" asignado por la base de datos LAST_INSERT_ID()

Con respecto al programa PHP, en efecto, deberias de tener la "funcion" a ejecutar y los "campos correspondientes", de lo contrario alguien puede mandar un "delete from tabla" y ya es historia tu base de datos.

Revisa los links mencionados, así te quedará mas claro como funciona.

Saludos,

Edgar
 
Last edited:

Miguel Santillan

Member
Licensed User
Muchísimas gracias, ha funcionado correctamente y lo voy a estudiar detenidamente.
Una última consultita (por ahora espero) donde me pusiste Job.Release <- ya no aplica, entiendo que el Job.Relase que está antes tampoco debería ir o me equivoco.
y faltaría el end sub despues del Activity.Finish.

sería asi. Disculpas por las preguntas, pero recién este año he comenzado con b4a y como veo que tiene un potencial enorme me entusiasmo demasiado, sin conocer algunas cosas en detalle.
Nuevamente muchas gracias.
Miguel
 

edgar_ortiz

Active Member
Licensed User
Longtime User
Muchísimas gracias, ha funcionado correctamente y lo voy a estudiar detenidamente.
Una última consultita (por ahora espero) donde me pusiste Job.Release <- ya no aplica, entiendo que el Job.Relase que está antes tampoco debería ir o me equivoco.
y faltaría el end sub despues del Activity.Finish.

sería asi. Disculpas por las preguntas, pero recién este año he comenzado con b4a y como veo que tiene un potencial enorme me entusiasmo demasiado, sin conocer algunas cosas en detalle.
Nuevamente muchas gracias.
Miguel

- Correcto el job.release que está antes tampoco aplica y falta el End Sub.
 

Miguel Santillan

Member
Licensed User
Hola Edgar, me estuviste ayudando con el wait for ya que tenía problemas cuando grababa cabecera y detalle. Hasta ahora venia funcionando bien, pero he vuelto con lo mismo. Ocurre lo siguiente y precisaría, si es posible nuevamente tu ayuda.
Algunos items de un pedido los coloca al final de otros, o sea me los mezcla y en otro casos directamente corta el detalle. (si tengo 10 items, pasan 8 solamente)
O sea, puedo tener de mas porque se mezclan o de menos porque se corta.
Tal vez este envíando mal los items o algo que pueda estar haciendo muy mal, o no es la forma correcta de grabarlos por desconocimiento.

Repito, no se da siempre, tal vez un caso en 50, pero con uno solo ya es un caos.

Muchas gracias
Miguel
 

edgar_ortiz

Active Member
Licensed User
Longtime User
Hola Edgar, me estuviste ayudando con el wait for ya que tenía problemas cuando grababa cabecera y detalle. Hasta ahora venia funcionando bien, pero he vuelto con lo mismo. Ocurre lo siguiente y precisaría, si es posible nuevamente tu ayuda.
Algunos items de un pedido los coloca al final de otros, o sea me los mezcla y en otro casos directamente corta el detalle. (si tengo 10 items, pasan 8 solamente)
O sea, puedo tener de mas porque se mezclan o de menos porque se corta.
Tal vez este envíando mal los items o algo que pueda estar haciendo muy mal, o no es la forma correcta de grabarlos por desconocimiento.

Repito, no se da siempre, tal vez un caso en 50, pero con uno solo ya es un caos.

Muchas gracias
Miguel

Miguel,
Has un nuevo proyecto, el cual únicamente incluya:
  • - Una actividad con:
    • "Botón de Abrir Base de Datos" y su código correspondiente
    • "Botón de Enviar" y su código correspondiente
  • - La base de datos con información previamente ingresada
Este nuevo proyecto exportas a un Zip y lo envias en un siguiente post, así cualquier podrá revisarlo.

Saludos,

Edgar
 
Top