VERSION 6.03.28

- Se agrego vaidacion para que cuando envie un pedido, antes de borrar el anerior revise que no este cerrada o liquidada!
This commit is contained in:
2026-03-30 16:09:05 -06:00
parent 44d97b4845
commit b0b10b22a6
3 changed files with 340 additions and 105 deletions

View File

@@ -3523,8 +3523,218 @@ End Sub
' 1. Recopila encabezados y detalles de pedidos locales (todos o solo los pendientes).
' 2. Genera un ID único (Arch) para vincular exactamente cada venta con sus productos.
' 3. Empaqueta todo en una lista de comandos (Batch) para enviarlo al servidor en una sola transacción.
' 3. Valida contra el servidor si el pedido es modificable (no liquidado/arqueado).
' 4. Empaqueta todo en una lista de comandos (Batch) para enviarlo al servidor en una sola transacción.
Sub enviaPedidoBatch(filtro As String)
' Preparamos una variable para filtrar la consulta a la base de datos local.
' Si el filtro no dice "Todos", armamos la condición para traer solo los pedidos que no se han enviado (PC_ENVIADO = 0).
Private condicion As String = ""
' If filtro <> "Todos" Then condicion = "where PC_ENVIADO = 0"
If filtro <> "Todos" Then
condicion = "WHERE PC_ENVIADO = 0 OR PC_CLIENTE IN (SELECT PE_CLIENTE FROM PEDIDO WHERE PE_ENVIADO = 0)" ' Si se actualizo un producto, hay que volver a enviar todo el pedido.
End If
' Reiniciamos la variable de condición para usarla ahora en el DETALLE de los pedidos.
' Private condicion As String = ""
' If filtro <> "Todos" Then condicion = "where PE_ENVIADO = 0"
' Verificamos si en la tabla de envíos históricos (HIST_ENVIOS) hay registros del tipo "ABORDO" (Ventas en ruta directa).
c = Starter.skmt.ExecQuery2("SELECT COUNT(*) as CANTIDAD FROM HIST_ENVIOS WHERE HE_TIPO = ?",Array As String("ABORDO") )
c.Position = 0
' Si encontramos que sí hay ventas a bordo...
If c.GetString("CANTIDAD") > 0 Then
Log($"pe_cedis_0"$)
' Actualizamos la tabla PEDIDO local para que los artículos del cliente "0" (que suele ser el inventario a bordo)
' y que no tengan un número de folio, se marquen con el almacén/cedis "RECARGA".
Starter.skmt.ExecNonQuery2("update PEDIDO set PE_CEDIS = ? where PE_CLIENTE =? AND PE_FOLIO IS NULL ", Array As Object("RECARGA", "0"))
End If
' Hacemos una actualización rápida a los registros de PEDIDO locales que no tengan folio (folio 0 o 1).
' Les asignamos temporalmente el 'rowid' (el número de fila interno de SQLite) como folio para identificarlos.
Starter.skmt.ExecNonQuery("UPDATE PEDIDO SET PE_FOLIO = rowid where PE_FOLIO = 0 or PE_FOLIO = 1")
' Buscamos los ENCABEZADOS de los pedidos en la tabla PEDIDO_CLIENTE usando la condición que armamos arriba.
' El resultado se guarda en un Cursor llamado 'cx', que es como una tabla en memoria por la que podemos navegar.
Private cx As Cursor = Starter.skmt.ExecQuery($"SELECT PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT, PC_COSTO_SIN, PC_RUTA, PC_ALMACEN, PC_ENVIADO FROM PEDIDO_CLIENTE ${condicion}"$)
Log($"SELECT PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT, PC_COSTO_SIN, PC_RUTA, PC_ALMACEN, PC_ENVIADO FROM PEDIDO_CLIENTE ${condicion}"$)
Log("pedido_cliente: " & cx.RowCount)
' Revisamos si nuestro cursor 'cx' (los encabezados de pedido) trajo algún resultado.
If cx.RowCount > 0 Then ' Si hay pedido entonces comenzamos el proceso de envío.
' Iniciamos un bucle (For) para recorrer cada uno de los encabezados de pedido encontrados localmente.
For j = 0 To cx.RowCount - 1
' =========================================================================================
' BLOQUE DE VALIDACIÓN REMOTA: Revisar si el pedido ya está liquidado o el arqueo cerrado
' =========================================================================================
' sql.revisaArqueoYLiquidacion_Kelloggs = select NVL(HVD_ESTATUS, 'NO') as liquidado, HVD_DTECIERRE, (select hist_ca_fecha from KELLOGGS.hist_cierre_arqueo where hist_ca_idalmacen = (?) and hist_ca_ruta = (?) and trunc(sysdate) = trunc(hist_ca_fecha)) as arqueo from KELLOGGS.HIST_VENTAS_DETALLE where HVD_ALMACEN = (?) and HVD_RUTA = (?) and trunc(sysdate) = trunc(HVD_FECHA) and HVD_TIPOVENTA = 'VENTA' and rownum <= 1
' 1. Preparamos el comando para consultar el estatus directamente en la base de datos del servidor.
cmd.Initialize
cmd.Name = "revisaArqueoYLiquidacion_Kelloggs"
Private ruta_ As String = Subs.traeRuta
cmd.Parameters = Array As Object(ALMACEN, ruta_, ALMACEN, ruta_)
' 2. Disparamos la consulta al servidor de forma asíncrona usando reqManagerW.
reqManagerW.ExecuteQuery(Starter.DBReqServer, cmd, Me, "revisaPedidoLiquidado")
' 3. Pausamos la ejecución de este bloque local hasta que el servidor nos responda.
Wait For revisaPedidoLiquidado_Completed (rpd As TResultado)
' 4. Evaluamos la respuesta del servidor.
If rpd.Success Then
Log("SUCCESS - revisaPedidoLiquidado")
' Inicializamos variables asumiendo que el pedido NO está liquidado y NO hay arqueo.
Dim liquidado As String = "NO"
Dim arqueo As String = "null"
' Leemos los registros devueltos por el servidor para actualizar nuestras variables.
For Each records() As Object In rpd.resultado.Rows
liquidado = records(rpd.resultado.Columns.Get("LIQUIDADO"))
arqueo = records(rpd.resultado.Columns.Get("ARQUEO"))
Next
Subs.logJobDoneResultados(rpd.resultado)
' 5. Regla de negocio: Si el estatus es "NO" liquidado y el arqueo es "null" (abierto),
' entonces es seguro proceder a modificar/enviar la información.
If liquidado = "NO" And arqueo = "null" Then
Log("==== BORRAMOS Y ENVIAMOS PEDIDO ===")
' =========================================================================================
' INICIA PREPARACIÓN DEL BATCH (EMPAQUETADO DE DELETES E INSERTS)
' =========================================================================================
' Creamos una lista llamada BatchCommands. Aquí vamos a guardar todas las instrucciones
' de base de datos que queremos mandar al servidor de un solo golpe (en lote o "batch").
Dim BatchCommands As List
BatchCommands.Initialize
Log($"enviaPedidoBatch(${filtro})"$)
Log("===== AGREGAMOS HEADER DE PEDIDO =====")
' Movemos el cursor 'cx' a la posición 'j' actual del bucle de encabezados.
cx.Position = j
' ===== EJECUTAR DELETES PRIMERO =====
' Preparamos la eliminación de los registros viejos en el servidor para evitar duplicados.
Log("===== LIMPIANDO PEDIDOS PREVIOS EN SERVER =====")
' Borrar Pedido (Detalle) en el servidor
Dim cmdDelPed As DBCommand
cmdDelPed.Initialize
cmdDelPed.Name = "borraPedido_Kelloggs"
cmdDelPed.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
BatchCommands.Add(cmdDelPed)
' Borrar Pedido Cliente (Header) en el servidor
Dim cmdDelHeader As DBCommand
cmdDelHeader.Initialize
cmdDelHeader.Name = "borraPedidoCliente_Kelloggs"
cmdDelHeader.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
BatchCommands.Add(cmdDelHeader)
' Borrar Hist_Ventas (Header) en el servidor
Dim cmdDelHV As DBCommand
cmdDelHV.Initialize
cmdDelHV.Name = "borraHV_Kelloggs"
cmdDelHV.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
BatchCommands.Add(cmdDelHV)
' Borrar Hist_Ventas_Detalle (Detalle) en el servidor
Dim cmdDelHVD As DBCommand
cmdDelHVD.Initialize
cmdDelHVD.Name = "borraHVD_Kelloggs"
cmdDelHVD.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
BatchCommands.Add(cmdDelHVD)
' ===== GENERACIÓN DE ID ÚNICO (ARCH) =====
' Generamos un identificador único (Arch) concatenando el almacén, la ruta, el cliente y la fecha/hora actual.
' Esto sirve para agrupar y amarrar lógicamente en el servidor el encabezado con sus respectivos detalles.
Dim Arch As String = Subs.traeAlmacen & "_" & Subs.traeRuta & "_" & cx.GetString("PC_CLIENTE") & "_" & DateTime.Now
' Actualizamos las tablas locales asignándoles este nuevo ID 'Arch'.
Starter.skmt.ExecNonQuery2($"UPDATE PEDIDO SET PE_ARCH = ? WHERE PE_CLIENTE = ?"$, Array As Object(Arch, cx.GetString("PC_CLIENTE")))
Starter.skmt.ExecNonQuery2($"UPDATE PEDIDO_CLIENTE SET PC_ARCH = ? WHERE PC_CLIENTE = ?"$, Array As Object(Arch, cx.GetString("PC_CLIENTE")))
' ===== INSERCIÓN DEL NUEVO ENCABEZADO =====
' Preparamos el comando de inserción del encabezado para mandar al servidor.
Dim cmdHeader As DBCommand
cmdHeader.Initialize
' Asignamos el nombre del procedimiento almacenado o query de inserción.
cmdHeader.Name = "insert_pedidos_KELL_arch"
' Pasamos los parámetros leyendo los datos del cursor local 'cx' y le añadimos el ID único 'Arch'.
cmdHeader.Parameters = Array As Object(cx.GetString("PC_CLIENTE"),cx.GetString("PC_FECHA"),cx.GetString("PC_USER"),cx.GetString("PC_NOART"),cx.GetString("PC_MONTO"),cx.GetString("PC_LON"),cx.GetString("PC_LAT"),ALMACEN,l_ruta.text,cx.GetString("PC_COSTO_SIN"), Arch)
' Añadimos este comando de inserción a nuestra lista del lote (Batch).
BatchCommands.Add(cmdHeader)
' ===== INSERCIÓN DE LOS DETALLES (PRODUCTOS) =====
' Hacemos una consulta local para buscar los productos individuales de este pedido en específico.
Private cPed As Cursor = Starter.skmt.ExecQuery($"SELECT 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, PE_TIPO, PE_ARCH FROM PEDIDO where pe_cliente = '${cx.GetString("PC_CLIENTE")}' "$)
' Si la consulta arrojó productos para este cliente...
If cPed.RowCount > 0 Then
' Iniciamos un bucle interno para recorrer cada uno de esos productos.
For i = 0 To cPed.RowCount - 1
Log("==== AGREGAMOS PRODS DE PEDIDO ====")
' Movemos el cursor de detalles a la posición actual 'i'.
cPed.Position = i
' Preparamos el comando de inserción para este producto en el servidor.
Dim cmdDetail As DBCommand
cmdDetail.Initialize
' Verificamos si el vendedor tiene un perfil especial.
If PERFIL = "V-ESPECIAL" Then
Log("===== V-ESPECIAL =====")
' Utilizamos el query específico para ventas especiales y pasamos sus parámetros.
cmdDetail.Name = "insert_pedido_esp_KELL"
cmdDetail.Parameters = Array As Object(cPed.GetString("PE_CEDIS"),ALMACEN,cPed.GetString("PE_COSTO_TOT"),cPed.GetString("PE_COSTOU"),cPed.GetString("PE_CANT"),cPed.GetString("PE_PRONOMBRE"),cPed.GetString("PE_PROID"),cPed.GetString("PE_CLIENTE"),cPed.GetString("PE_FECHA"),cPed.GetString("PE_USUARIO"),cPed.GetString("PE_RUTA"),cPed.GetString("PE_COSTO_SIN"),cPed.GetString("PE_DESC"),cPed.GetString("PE_FOLIO"),cPed.GetString("PE_TIPO"),NUMERO_PEDIDO)
Else
' Si es un vendedor normal, usamos el query estándar y lo vinculamos usando la variable 'Arch'.
cmdDetail.Name = "insert_pedido_KELL_arch"
cmdDetail.Parameters = Array As Object (cPed.GetString("PE_CEDIS"),ALMACEN,cPed.GetString("PE_COSTO_TOT"),cPed.GetString("PE_COSTOU"),cPed.GetString("PE_CANT"),cPed.GetString("PE_PRONOMBRE"),cPed.GetString("PE_PROID"),cPed.GetString("PE_CLIENTE"),cPed.GetString("PE_FECHA"),cPed.GetString("PE_USUARIO"),cPed.GetString("PE_RUTA"), cPed.GetString("PE_COSTO_SIN"),cPed.GetString("PE_DESC"),cPed.GetString("PE_FOLIO"), cPed.GetString("PE_TIPO"), Arch)
End If
' Añadimos la instrucción de inserción de este producto al lote (Batch).
BatchCommands.Add(cmdDetail)
Next
End If
' Cerramos el cursor de detalles locales para liberar memoria.
cPed.Close
' ===== ENVÍO DEL LOTE AL SERVIDOR =====
' Mandamos a ejecutar toda la lista de instrucciones (Deletes + Inserts) al servidor en una sola petición HTTP.
' Le ponemos una etiqueta (Tag) con el ID del cliente para poder identificar la respuesta en el evento JobDone.
reqManager.ExecuteBatch(BatchCommands, "pedido_completo_" & cx.GetString("PC_CLIENTE"))
Log("==== ENVIAMOS PEDIDO COMPLETO ====")
Else
' Si la validación falló (el pedido ESTÁ liquidado o el arqueo ESTÁ cerrado),
' bloqueamos la operación y le mostramos advertencias al usuario en pantalla.
ToastMessageShow("Pedido liquidado o cerrado", True)
MsgboxAsync("¡El pedido esta liquidado o el arqueo cerrado, la información NO fue enviada a web!", "AVISO")
End If
Else
' Si la consulta de validación (revisaArqueoYLiquidacion) falló por problemas de red o servidor,
' registramos el error en el log local. No procedemos con el envío por seguridad.
Log("===== ERROR =====")
Log(rpd.ErrorMessage)
End If
Next
End If
' Cerramos los cursores principales abiertos al inicio de la función para evitar memory leaks.
c.Close
cx.Close
End Sub
' 1. Recopila encabezados y detalles de pedidos locales (todos o solo los pendientes).
' 2. Genera un ID único (Arch) para vincular exactamente cada venta con sus productos.
' 3. Empaqueta todo en una lista de comandos (Batch) para enviarlo al servidor en una sola transacción.
Sub enviaPedidoBatch1(filtro As String)
' Preparamos una variable para filtrar la consulta a la base de datos.
' Si el filtro no dice "Todos", armamos la condición para traer solo los pedidos que no se han enviado (PC_ENVIADO = 0).
Private condicion As String = ""
@@ -3559,115 +3769,140 @@ Sub enviaPedidoBatch(filtro As String)
' Hacemos una actualización rápida a los registros de PEDIDO que no tengan folio (folio 0 o 1).
' Les asignamos temporalmente el 'rowid' (el número de fila interno de SQLite) como folio para identificarlos.
Starter.skmt.ExecNonQuery("UPDATE PEDIDO SET PE_FOLIO = rowid where PE_FOLIO = 0 or PE_FOLIO = 1")
' Revisamos si nuestro cursor 'cx' (los encabezados de pedido) trajo algún resultado.
If cx.RowCount > 0 Then ' Si hay pedido entonces lo enviamos.
' Iniciamos un bucle (For) para recorrer cada uno de los encabezados de pedido encontrados.
For j = 0 To cx.RowCount - 1
' Creamos una lista llamada BatchCommands. Aquí vamos a guardar todas las instrucciones
' de base de datos que queremos mandar al servidor de un solo golpe (en lote o "batch").
Dim BatchCommands As List
BatchCommands.Initialize
Log($"enviaPedidoBatch(${filtro})"$)
Log("===== AGREGAMOS HEADER DE PEDIDO =====")
' Movemos el cursor 'cx' a la posición 'j' actual del bucle.
cx.Position = j
' ===== 1. EJECUTAR DELETES PRIMERO =====
Log("===== LIMPIANDO PEDIDOS PREVIOS EN SERVER =====")
' Borrar Pedido (Detalle)
Dim cmdDelPed As DBCommand
cmdDelPed.Initialize
cmdDelPed.Name = "borraPedido_Kelloggs"
cmdDelPed.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
BatchCommands.Add(cmdDelPed)
' Borrar Pedido Cliente (Header)
Dim cmdDelHeader As DBCommand
cmdDelHeader.Initialize
cmdDelHeader.Name = "borraPedidoCliente_Kelloggs"
cmdDelHeader.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
BatchCommands.Add(cmdDelHeader)
' Borrar Hist_Ventas (Header)
Dim cmdDelHV As DBCommand
cmdDelHV.Initialize
cmdDelHV.Name = "borraHV_Kelloggs"
cmdDelHV.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
BatchCommands.Add(cmdDelHV)
' Borrar Hist_Ventas_Detalle (Detalle)
Dim cmdDelHVD As DBCommand
cmdDelHVD.Initialize
cmdDelHVD.Name = "borraHVD_Kelloggs"
cmdDelHVD.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
BatchCommands.Add(cmdDelHVD)
' Generamos un identificador único (Arch) concatenando el almacén, la ruta, el cliente y la fecha/hora actual.
' Esto sirve para agrupar en el servidor el encabezado con sus respectivos detalles.
Dim Arch As String = Subs.traeAlmacen & "_" & Subs.traeRuta & "_" & cx.GetString("PC_CLIENTE") & "_" & DateTime.Now
Starter.skmt.ExecNonQuery2($"UPDATE PEDIDO SET PE_ARCH = ? WHERE PE_CLIENTE = ?"$, Array As Object(Arch, cx.GetString("PC_CLIENTE")))
Starter.skmt.ExecNonQuery2($"UPDATE PEDIDO_CLIENTE SET PC_ARCH = ? WHERE PC_CLIENTE = ?"$, Array As Object(Arch, cx.GetString("PC_CLIENTE")))
' Preparamos un comando de base de datos (DBCommand) para mandar al servidor.
Dim cmdHeader As DBCommand
cmdHeader.Initialize
' Asignamos el nombre del procedimiento almacenado o query que está en el servidor (jRDC2).
cmdHeader.Name = "insert_pedidos_KELL_arch"
' Pasamos los parámetros leyendo los datos del cursor 'cx' (encabezado) y le pasamos el ID único 'Arch'.
cmdHeader.Parameters = Array As Object(cx.GetString("PC_CLIENTE"),cx.GetString("PC_FECHA"),cx.GetString("PC_USER"),cx.GetString("PC_NOART"),cx.GetString("PC_MONTO"),cx.GetString("PC_LON"),cx.GetString("PC_LAT"),ALMACEN,l_ruta.text,cx.GetString("PC_COSTO_SIN"), Arch)
' Añadimos este comando a nuestra lista del lote (Batch).
BatchCommands.Add(cmdHeader)
' Ahora hacemos una consulta para buscar el DETALLE de este pedido (los productos individuales).
' Filtramos por la condición (si se envió o no) y lo amarramos al cliente actual del bucle (PC_CLIENTE).
Private cPed As Cursor = Starter.skmt.ExecQuery($"SELECT 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, PE_TIPO, PE_ARCH FROM PEDIDO where pe_cliente = '${cx.GetString("PC_CLIENTE")}' "$)
' Si hay detalles para este encabezado...
If cPed.RowCount > 0 Then
' Iniciamos un bucle interno para recorrer cada producto de este pedido.
For i = 0 To cPed.RowCount - 1
Log("==== AGREGAMOS PRODS DE PEDIDO ====")
' Movemos el cursor de detalles a la posición actual.
cPed.Position = i
' Preparamos el comando para enviar este producto al servidor.
Dim cmdDetail As DBCommand
cmdDetail.Initialize
' Si el perfil del vendedor es especial ("V-ESPECIAL")...
If PERFIL = "V-ESPECIAL" Then
Log("===== V-ESPECIAL =====")
' Nota: Aquí el código original tiene un detalle, usa la variable global 'cmd' en lugar de 'cmdDetail'
' que acaba de inicializar, pero la copiamos tal cual. Utiliza un query distinto para ventas especiales.
cmdDetail.Name = "insert_pedido_esp_KELL"
cmdDetail.Parameters = Array As Object(cPed.GetString("PE_CEDIS"),ALMACEN,cPed.GetString("PE_COSTO_TOT"),cPed.GetString("PE_COSTOU"),cPed.GetString("PE_CANT"),cPed.GetString("PE_PRONOMBRE"),cPed.GetString("PE_PROID"),cPed.GetString("PE_CLIENTE"),cPed.GetString("PE_FECHA"),cPed.GetString("PE_USUARIO"),cPed.GetString("PE_RUTA"),cPed.GetString("PE_COSTO_SIN"),cPed.GetString("PE_DESC"),cPed.GetString("PE_FOLIO"),cPed.GetString("PE_TIPO"),NUMERO_PEDIDO)
Else
' Si es un vendedor normal, usa el comando estándar para insertar el detalle
' y le pasa la misma variable 'Arch' para que en el servidor sepa de qué encabezado es.
cmdDetail.Name = "insert_pedido_KELL_arch"
cmdDetail.Parameters = Array As Object (cPed.GetString("PE_CEDIS"),ALMACEN,cPed.GetString("PE_COSTO_TOT"),cPed.GetString("PE_COSTOU"),cPed.GetString("PE_CANT"),cPed.GetString("PE_PRONOMBRE"),cPed.GetString("PE_PROID"),cPed.GetString("PE_CLIENTE"),cPed.GetString("PE_FECHA"),cPed.GetString("PE_USUARIO"),cPed.GetString("PE_RUTA"), cPed.GetString("PE_COSTO_SIN"),cPed.GetString("PE_DESC"),cPed.GetString("PE_FOLIO"), cPed.GetString("PE_TIPO"), Arch)
End If
' Añadimos la instrucción del producto al lote de envío.
BatchCommands.Add(cmdDetail)
' sql.revisaArqueoYLiquidacion_Kelloggs = select NVL(HVD_ESTATUS, 'NO') as liquidado, HVD_DTECIERRE, (select hist_ca_fecha from KELLOGGS.hist_cierre_arqueo where hist_ca_idalmacen = (?) and hist_ca_ruta = (?) and trunc(sysdate) = trunc(hist_ca_fecha)) as arqueo from KELLOGGS.HIST_VENTAS_DETALLE where HVD_ALMACEN = (?) and HVD_RUTA = (?) and trunc(sysdate) = trunc(HVD_FECHA) and HVD_TIPOVENTA = 'VENTA' and rownum <= 1
cmd.Initialize
cmd.Name = "revisaArqueoYLiquidacion_Kelloggs"
Private ruta_ As String = Subs.traeRuta
cmd.Parameters = Array As Object(ALMACEN, ruta_, ALMACEN, ruta_)
reqManagerW.ExecuteQuery(Starter.DBReqServer, cmd, Me, "revisaPedidoLiquidado")
Wait For revisaPedidoLiquidado_Completed (rpd As TResultado)
If rpd.Success Then
Log("SUCCESS - revisaPedidoLiquidado")
Dim liquidado As String = "NO"
Dim arqueo As String = "null"
For Each records() As Object In rpd.resultado.Rows
liquidado = records(rpd.resultado.Columns.Get("LIQUIDADO"))
arqueo = records(rpd.resultado.Columns.Get("ARQUEO"))
Next
Subs.logJobDoneResultados(rpd.resultado)
If liquidado = "NO" And arqueo = "null" Then
Log("==== BORRAMOS Y ENVIAMOS PEDIDO ===")
' Creamos una lista llamada BatchCommands. Aquí vamos a guardar todas las instrucciones
' de base de datos que queremos mandar al servidor de un solo golpe (en lote o "batch").
Dim BatchCommands As List
BatchCommands.Initialize
Log($"enviaPedidoBatch(${filtro})"$)
Log("===== AGREGAMOS HEADER DE PEDIDO =====")
' Movemos el cursor 'cx' a la posición 'j' actual del bucle.
cx.Position = j
' ===== 1. EJECUTAR DELETES PRIMERO =====
Log("===== LIMPIANDO PEDIDOS PREVIOS EN SERVER =====")
' Borrar Pedido (Detalle)
Dim cmdDelPed As DBCommand
cmdDelPed.Initialize
cmdDelPed.Name = "borraPedido_Kelloggs"
cmdDelPed.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
BatchCommands.Add(cmdDelPed)
' Borrar Pedido Cliente (Header)
Dim cmdDelHeader As DBCommand
cmdDelHeader.Initialize
cmdDelHeader.Name = "borraPedidoCliente_Kelloggs"
cmdDelHeader.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
BatchCommands.Add(cmdDelHeader)
' Borrar Hist_Ventas (Header)
Dim cmdDelHV As DBCommand
cmdDelHV.Initialize
cmdDelHV.Name = "borraHV_Kelloggs"
cmdDelHV.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
BatchCommands.Add(cmdDelHV)
' Borrar Hist_Ventas_Detalle (Detalle)
Dim cmdDelHVD As DBCommand
cmdDelHVD.Initialize
cmdDelHVD.Name = "borraHVD_Kelloggs"
cmdDelHVD.Parameters = Array As Object(ALMACEN, l_ruta.text, cx.GetString("PC_USER"), cx.GetString("PC_CLIENTE"))
BatchCommands.Add(cmdDelHVD)
' Generamos un identificador único (Arch) concatenando el almacén, la ruta, el cliente y la fecha/hora actual.
' Esto sirve para agrupar en el servidor el encabezado con sus respectivos detalles.
Dim Arch As String = Subs.traeAlmacen & "_" & Subs.traeRuta & "_" & cx.GetString("PC_CLIENTE") & "_" & DateTime.Now
Starter.skmt.ExecNonQuery2($"UPDATE PEDIDO SET PE_ARCH = ? WHERE PE_CLIENTE = ?"$, Array As Object(Arch, cx.GetString("PC_CLIENTE")))
Starter.skmt.ExecNonQuery2($"UPDATE PEDIDO_CLIENTE SET PC_ARCH = ? WHERE PC_CLIENTE = ?"$, Array As Object(Arch, cx.GetString("PC_CLIENTE")))
' Preparamos un comando de base de datos (DBCommand) para mandar al servidor.
Dim cmdHeader As DBCommand
cmdHeader.Initialize
' Asignamos el nombre del procedimiento almacenado o query que está en el servidor (jRDC2).
cmdHeader.Name = "insert_pedidos_KELL_arch"
' Pasamos los parámetros leyendo los datos del cursor 'cx' (encabezado) y le pasamos el ID único 'Arch'.
cmdHeader.Parameters = Array As Object(cx.GetString("PC_CLIENTE"),cx.GetString("PC_FECHA"),cx.GetString("PC_USER"),cx.GetString("PC_NOART"),cx.GetString("PC_MONTO"),cx.GetString("PC_LON"),cx.GetString("PC_LAT"),ALMACEN,l_ruta.text,cx.GetString("PC_COSTO_SIN"), Arch)
' Añadimos este comando a nuestra lista del lote (Batch).
BatchCommands.Add(cmdHeader)
' Ahora hacemos una consulta para buscar el DETALLE de este pedido (los productos individuales).
' Filtramos por la condición (si se envió o no) y lo amarramos al cliente actual del bucle (PC_CLIENTE).
Private cPed As Cursor = Starter.skmt.ExecQuery($"SELECT 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, PE_TIPO, PE_ARCH FROM PEDIDO where pe_cliente = '${cx.GetString("PC_CLIENTE")}' "$)
' Si hay detalles para este encabezado...
If cPed.RowCount > 0 Then
' Iniciamos un bucle interno para recorrer cada producto de este pedido.
For i = 0 To cPed.RowCount - 1
Log("==== AGREGAMOS PRODS DE PEDIDO ====")
' Movemos el cursor de detalles a la posición actual.
cPed.Position = i
' Preparamos el comando para enviar este producto al servidor.
Dim cmdDetail As DBCommand
cmdDetail.Initialize
' Si el perfil del vendedor es especial ("V-ESPECIAL")...
If PERFIL = "V-ESPECIAL" Then
Log("===== V-ESPECIAL =====")
' Nota: Aquí el código original tiene un detalle, usa la variable global 'cmd' en lugar de 'cmdDetail'
' que acaba de inicializar, pero la copiamos tal cual. Utiliza un query distinto para ventas especiales.
cmdDetail.Name = "insert_pedido_esp_KELL"
cmdDetail.Parameters = Array As Object(cPed.GetString("PE_CEDIS"),ALMACEN,cPed.GetString("PE_COSTO_TOT"),cPed.GetString("PE_COSTOU"),cPed.GetString("PE_CANT"),cPed.GetString("PE_PRONOMBRE"),cPed.GetString("PE_PROID"),cPed.GetString("PE_CLIENTE"),cPed.GetString("PE_FECHA"),cPed.GetString("PE_USUARIO"),cPed.GetString("PE_RUTA"),cPed.GetString("PE_COSTO_SIN"),cPed.GetString("PE_DESC"),cPed.GetString("PE_FOLIO"),cPed.GetString("PE_TIPO"),NUMERO_PEDIDO)
Else
' Si es un vendedor normal, usa el comando estándar para insertar el detalle
' y le pasa la misma variable 'Arch' para que en el servidor sepa de qué encabezado es.
cmdDetail.Name = "insert_pedido_KELL_arch"
cmdDetail.Parameters = Array As Object (cPed.GetString("PE_CEDIS"),ALMACEN,cPed.GetString("PE_COSTO_TOT"),cPed.GetString("PE_COSTOU"),cPed.GetString("PE_CANT"),cPed.GetString("PE_PRONOMBRE"),cPed.GetString("PE_PROID"),cPed.GetString("PE_CLIENTE"),cPed.GetString("PE_FECHA"),cPed.GetString("PE_USUARIO"),cPed.GetString("PE_RUTA"), cPed.GetString("PE_COSTO_SIN"),cPed.GetString("PE_DESC"),cPed.GetString("PE_FOLIO"), cPed.GetString("PE_TIPO"), Arch)
End If
' Añadimos la instrucción del producto al lote de envío.
BatchCommands.Add(cmdDetail)
Next
End If
cPed.Close
' Al terminar de empaquetar, enviamos toda la lista de instrucciones (BatchCommands) al servidor de un solo golpe.
' Se le asigna un nombre de etiqueta (Tag) para saber qué responderá el JobDone ("pedido_completo_" + id de cliente).
' (Ojo visual para el programador: Esta línea está dentro del 'If' general, pero también después de armar los batches en el bucle 'For'. Al procesar el último item del bucle cx, tomará el ID del último cliente para el Tag).
reqManager.ExecuteBatch(BatchCommands, "pedido_completo_" & cx.GetString("PC_CLIENTE"))
Log("==== ENVIAMOS PEDIDO COMPLETO ====")
Else
ToastMessageShow("Pedido liquidado o cerrado", True)
MsgboxAsync("¡El pedido esta liquidado o el arqueo cerrado, la información NO fue enviada a web!", "AVISO")
End If
Else
Log("===== ERROR =====")
Log(rpd.ErrorMessage)
End If
cPed.Close
' Al terminar de empaquetar, enviamos toda la lista de instrucciones (BatchCommands) al servidor de un solo golpe.
' Se le asigna un nombre de etiqueta (Tag) para saber qué responderá el JobDone ("pedido_completo_" + id de cliente).
' (Ojo visual para el programador: Esta línea está dentro del 'If' general, pero también después de armar los batches en el bucle 'For'. Al procesar el último item del bucle cx, tomará el ID del último cliente para el Tag).
reqManager.ExecuteBatch(BatchCommands, "pedido_completo_" & cx.GetString("PC_CLIENTE"))
Log("==== ENVIAMOS PEDIDO COMPLETO ====")
Next
End If
' Por buena práctica y para evitar fugas de memoria (memory leaks),
' cerramos siempre los cursores que abrimos hacia la base de datos local.
c.Close
cx.Close
End Sub

View File

@@ -918,7 +918,7 @@ Version=12.8
#Region Project Attributes
#ApplicationLabel: Kelloggs Venta
#VersionCode: 3000
#VersionName: 6.03.24
#VersionName: 6.03.28
#SupportedOrientations: portrait
#CanInstallToExternalStorage: False
#BridgeLogger:true

View File

@@ -73,7 +73,7 @@ ModuleClosedNodes1=
ModuleClosedNodes10=
ModuleClosedNodes11=
ModuleClosedNodes12=
ModuleClosedNodes13=42
ModuleClosedNodes13=42,43
ModuleClosedNodes14=
ModuleClosedNodes15=
ModuleClosedNodes16=2,7,8,9
@@ -103,6 +103,6 @@ ModuleClosedNodes6=
ModuleClosedNodes7=
ModuleClosedNodes8=
ModuleClosedNodes9=
NavigationStack=Starter,Application_Error,120,0,Starter,Service_Start,97,0,Starter,Service_Create,88,0,C_Cliente,b_inicioFinVenta_Click,4426,0,C_Cliente,mandaPendientes,1100,0,C_Principal,enviaPedido,3731,0,C_Cliente,Guardar_Click,1081,0,C_Cliente,Subir_Pedido_Con_Integridad,4501,0,C_Principal,SUBIR_INFO_PEDIDO,3519,0,C_Principal,enviaPedidoBatch,3578,6,C_Principal,JobDone,1878,0
NavigationStack=C_Principal,JobDone,2239,0,C_Principal,Class_Globals,0,0,C_Cliente,B4XPage_Appear,793,0,C_Cliente,Guardar_Click,1084,0,C_Cliente,mandaPendientes,1100,0,DBRequestManagerW,ExecuteCommand,92,0,C_Principal,enviaPedidoBatch1,3697,0,C_Principal,SUBIR_INFO_PEDIDO,3517,0,C_Principal,enviaPedidoBatch,3565,6
SelectedBuild=0
VisibleModules=32,1,13,4,33,16,34,14,15,24
VisibleModules=32,1,13,4,33,16,34,14,15,24,22