45 Commits

Author SHA1 Message Date
048deef8c1 VERSION 6.03.30
- Cambios en DBRequestManagerW para evitar un error cuando no hay internet
2026-04-01 17:07:51 -06:00
b0b10b22a6 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!
2026-03-30 16:09:08 -06:00
44d97b4845 VERSION 6.03.24
- Se agrego codigo para que cuando envie un pedido o modificacipn deun pedido, borre antes de web todo lo que encuentre de ese cliente y luego mande el nuevo.
2026-03-26 16:58:52 -06:00
f5fe4c4a52 VERSION 6.03.15
- Se corrige un error en el calculo del trade spending para que en algunos casos no calculaba bien en presupuesto.
- Se hace un cambio en subs.actualizaProducto, porque no ponia en 0 la bandera de pc_enviado.
2026-03-17 09:58:32 -06:00
60aa115e24 VERSION 6.02.03 2026-03-05 08:37:09 -06:00
eaa185bb6d VERSION 6.01.31
- Se corrigio que guarde los inventarios de loq ue trae la camionetay NO lo del almacen.
2026-02-04 13:38:09 -06:00
10a2c84997 VERSION 6.01.28
- Cambio en e manifiesto para corregir el "teclado" fantasma.
2026-02-03 09:53:58 -06:00
af1f4b9ead VERSION 5.12.18
- Se agrego auditoria en los "principales" eventos, se guardan en la tabla "auditoria"
2025-12-22 11:47:23 -06:00
af9ea44b95 VERSION 5.12.17
- Se agrego codigo para que el label de la notificacion tenga scroll vertical y se vaya al inicio del texto
2025-12-20 02:42:47 -06:00
426e8b0c87 VERSION 5.12.16
- Se agrego codigo para que el label de la notificacion tenga scroll vertical y se vaya al inicio del texto
2025-12-20 02:38:30 -06:00
5124f6c5a1 VERSION 5.12.16
- Se agrego codigo para que el label de la notificacion tenga scroll vertical y se vaya al inicio del texto
2025-12-20 02:30:16 -06:00
4e69087ff2 Version 5.12.16 2025-12-20 02:27:17 -06:00
4a5fc4dd05 Version 5.12.16 2025-12-20 02:23:30 -06:00
64a80661e8 Version 5.12.16
- Se agregó comando y script para enviar automáticamente el TAG con la version actual a GitHub.
2025-12-20 02:15:07 -06:00
96838bf61b VERSION 5.12.16
- Se agregó comando y script para enviar automáticamente el TAG con la version actual a GitHub.
2025-12-20 02:11:40 -06:00
7e19a197a1 Version 5.12.15.test
PRUEBA
2025-12-20 01:49:09 -06:00
64e9e6b389 Version 5.12.15.test
PRUEBA
2025-12-20 01:47:58 -06:00
63df3fbf39 Version 5.12.15.test
PRUEBA
2025-12-20 01:46:25 -06:00
e72a1381d5 Version 5.12.15.test
PRUEBA
2025-12-20 01:43:14 -06:00
367ff75966 Version 5.12.15.test
PRUEBA
2025-12-20 01:36:22 -06:00
2ec2e9acb3 Version 5.12.15.test
PRUEBA
2025-12-20 01:34:50 -06:00
246437fc98 Version 5.12.15.test
PRUEBA
2025-12-20 01:26:18 -06:00
67e0b906dc Version 5.12.15.test
PRUEBA
2025-12-20 00:41:20 -06:00
d7e6643f15 Version 5.12.15.test 2025-12-20 00:29:29 -06:00
cc5261c67f Version 5.12.15.test
Prueba
2025-12-20 00:28:03 -06:00
cc36c6c1da Version 5.12.15.test 2025-12-20 00:11:35 -06:00
441fe0c5fb Version 5.12.15.test
- Commit SIN cambios de codigo, solo de prueba con tags
2025-12-20 00:08:49 -06:00
136df88646 - VERSION 5.12.15
- Se agregga codigo para que si hay nulos en los datos de Trade Spending no truene la aplicacion.
2025-12-19 23:36:33 -06:00
f0116e375d - VERSION 5.12.14
- Se agrego codigo para que el label de la notificacion tenga scroll vertical y se vaya al inicio del texto
2025-12-19 20:12:14 -06:00
409c224820 - VERSION 5.12.10
- Codigo de prueba para envio de pedido en BATCH
- Se amplio el panel de las notificaciones
- Si no hay presupuesto para bonificaciones NO se muestra la opcion de PROMOS en "Productos"
2025-12-10 16:58:51 -06:00
72ce7c8806 - VERSION 5.12.5
- Se agregó que si no hay presupuesto de bonificaciones, el apartado de PROMOS no aparezca al entrar a productos.
- Se agrego en MAPA_RUTAS que ponga los globitos dinamicamente (faltaba el rojo)
2025-12-08 13:47:05 -06:00
7a88acaf4c - VERSOIN 5.11.26
- Se agregó le descripcion del "flujo" de las promociones en C_Promos
2025-11-30 02:33:43 -06:00
749cf6e7fe - VERSION 5.11.01
- Se cambio como se guarda la informacion del registro del dispositivo, antes en KeyValueStore y ahora en una base de datos propia, esto es porque al parecer en android 10 y 12 no se esta guardando la informacion.
2025-11-05 18:24:48 -06:00
bca0d31469 - VERSION 5.10.20
- Correcciones en el envio de informacion despues de agregar el mandaPendientes, no se estaba enviando el pedido cuando se enviaba informacion desde la pantalla principal (por un timer que no funciona bien).
2025-10-24 00:47:32 -06:00
6fc81fcf0d - VERSION 5.10.16
- Se corrigieron errores en resumen dia e impresion de inventario
2025-10-21 20:03:51 -06:00
ceaa5246e5 - VERSION 5.10.15
- Se pusieron los regalos y exhibidores como categorias exentas de bonificacion.
2025-10-20 16:20:47 -06:00
7a547503b9 - VERSION 5.10.15
- Se hicieron correcciones al codigo de Trade Spending.
- Se cambio la tabla de donde lee los datos para dar de alta clientes nuevos, antes en CLIENTES_NUEVOS_X_RUTA, ahora CAT_RUTAS.
2025-10-16 16:07:41 -06:00
6446187478 - VERSION 5.10.01
- Se cambio el query de conectar (select_ruta4_KELL) a nueva version (select_ruta5_KELL) para preveeer cuando se quiera bloquear la conexion de versiones viejas.
2025-10-03 10:32:23 -06:00
48a1221ef9 - VERSION 5.10.01
- Se agregó el mandaPendientes en el boton de "Guardar" de "Cliente"
2025-10-02 23:47:22 -06:00
e6455d8147 - VERSION 5.09.10.2
- Se corrigio que Trade Spending no consideraba los productos fijos de las promos a la hora de afectar el presupuesto.
- Se agregó la validacion de la version de la app desde cat_rutas (CAT_RU_VERSION_REQUERIDA).
- Se agregó el ligar el telefono a una ruta desde cat_rutas (CAT_RU_IDTELEFONO).
2025-09-23 18:28:06 -06:00
ae8ac63b1d - VERSION 5.09.10
- Se escondio el boton de NoVenta en cliente hata tener ubicacion.
- Se habilitó los clientes nuevos POR RUTA, en la tabla "CLIENTES_NUEVOS_X_RUTA", y si ya llegaron a limite, se "deshabilita" el boton en principal.
- Se corrige que para Trade Spending, estaba todavia la ruta y almacen en duro.
2025-09-17 18:51:53 -06:00
d54ebd7994 - VERSION 5.09.01
- Se quito el almacen y ruta en duro al traer los datos de Trade Spending
- Se corrigio la barra de busqueda de productos que no regresaba los datos correctos.
2025-09-09 15:53:01 -06:00
42eeb55fe5 - VERSION 5.07.30
- Se aumento el credito por default para trade spending cuando NO tienen datos de 100,000 a 1,000,000
- Se cambio la ruta de prueba 238 almacen 2 por la ruta y almacen reales.
- Cambios varios para trade spending.
2025-07-31 17:27:29 -06:00
672953f0b4 -VERSION 5.07.05
- Se quito en duro la ruta y almacen para el trendSpending (r:238, almacen:2)
2025-07-05 14:36:49 -06:00
32ba186a60 - VERSION 5.06.25
- Se quito que el almacen de guadalajara NO tuviera geocerca.
- Se corrigio el error de que cuando se desinstala la app y se vuelve a instalar, en la priera venta se trababa la aplicacion.
- Se puso codigo de prueba para usar el "wait for" con el DBReqManager.
2025-07-01 17:41:25 -06:00
41 changed files with 4431 additions and 3400 deletions

View File

@@ -12,14 +12,20 @@ Version=9.85
'###################### PULL #############################################################
'Ctrl + click ide://run?file=%WINDIR%\System32\cmd.exe&Args=/c&Args=git&Args=pull
'###########################################################################################################
'###################### PULL FORZADO #############################################################
'Ctrl + click Respaldar y Pull: ide://run?file=%WINDIR%\System32\cmd.exe&Args=/c&Args=start&Args=powershell.exe&Args=-ExecutionPolicy&Args=Bypass&Args=-File&Args=..\..\_sync_project.ps1
'###########################################################################################################
'###################### 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
'###########################################################################################################
'###################### PUSH TORTOISE GIT CON TAG ##################################################
'Ctrl + clic para Git: ide://run?file=%WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe&Args=-ExecutionPolicy&Args=Bypass&Args=-File&Args=..\_git_tag.ps1&Args=%22%PROJECT%%22&Args=%22%PROJECT_NAME%%22
'###########################################################################################################
#End Region
'Ctrl + click ide://run?file=%WINDIR%\System32\cmd.exe&Args=/c&Args=github&Args=..\..\
Sub Class_Globals
@@ -117,6 +123,11 @@ Sub Class_Globals
Dim intentUsado As Boolean = False
Private p_importarBDWA As Panel
Private cb_importarBDWA As CheckBox
' Type TResultado(Tag As String, Success As Boolean, resultado As DBResult, ErrorMessage As String)
Private Label4 As Label
Private clicked As Int = 0
Dim linker As C_deviceLinker
Dim aud As C_Auditoria
End Sub
Public Sub Initialize
@@ -129,6 +140,7 @@ End Sub
'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
Log(">>>>>> CREATE - INICIAMOS MAIN PAGE <<<<<<<<<")
If Not(Starter.Logger) Then logger = False
Dim sDate, sTime As String
DateTime.DateFormat = "yyyyMMdd"
@@ -160,9 +172,19 @@ Private Sub B4XPage_Created (Root1 As B4XView)
Starter.skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS HIST_TREND_SPENDING_SEMANAL (HIST_TSS_RUTA TEXT, HIST_TSS_IDALMACEN TEXT, HIST_TSS_TIPO TEXT, HIST_TSS_SEMANA1 TEXT, HIST_TSS_SEMANA1_ACUM TEXT, HIST_TSS_SEMANA2 TEXT, HIST_TSS_SEMANA2_ACUM TEXT, HIST_TSS_SEMANA3 TEXT, HIST_TSS_SEMANA3_ACUM TEXT, HIST_TSS_SEMANA4 TEXT, HIST_TSS_SEMANA4_ACUM TEXT, HIST_TSS_SEMANA5 TEXT, HIST_TSS_SEMANA5_ACUM TEXT, HIST_TSS_SEMANA6 TEXT, HIST_TSS_SEMANA6_ACUM TEXT, HIST_TSS_GRUPO TEXT)")
Starter.skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS TREND_SPENDING (TIPO TEXT, MONTO_SEMANA TEXT, ACUMULADO TEXT)")
Starter.skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS VERSIONES (VERSION TEXT, FECHA TEXT)")
Starter.skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS CAT_INVENTARIO(CI_IDPROD TEXT, CI_INVENTARIO TEXT)")
''' FIN DOE
Starter.skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS CAT_NOTIFICACIONES(CN_CODIGO TEXT, CN_ID TEXT,CN_CLIENTE TEXT, CN_NOTIFICACION TEXT)")
Starter.skmt.ExecNonQuery("CREATE TABLE If Not EXISTS HIST_NOTIFICACIONES (HN_CODIGO TEXT, HN_ID TEXT, HN_FECHA TEXT)")
Starter.skmt.ExecNonQuery("CREATE TABLE If Not EXISTS CAT_GUNAPROD5 (CAT_GP_ID TEXT, CAT_GP_ALMACEN TEXT)")
Starter.skmt.ExecNonQuery("CREATE INDEX IF NOT EXISTS idx_pedido_proid ON PEDIDO(PE_PROID)")
Starter.skmt.ExecNonQuery("CREATE INDEX IF NOT EXISTS idx_pedido_cliente ON PEDIDO(PE_CLIENTE)")
Starter.skmt.ExecNonQuery("CREATE INDEX IF NOT EXISTS idx_cat5_id ON CAT_GUNAPROD5(CAT_GP_ID)")
kh.agregaColumna(Starter.skmt, "kmt_info", "IMPRESION", "INTEGER")
kh.agregaColumna(Starter.skmt, "kmt_info", "CREDITO", "INTEGER")
kh.agregaColumna(Starter.skmt, "PEDIDO", "PE_ENVIADO", "INTEGER DEFAULT 0")
kh.agregaColumna(Starter.skmt, "PEDIDO3", "PE_ENVIADO", "INTEGER DEFAULT 0")
kh.agregaColumna(Starter.skmt, "PEDIDO_CLIENTE", "PC_ENVIADO", "INTEGER DEFAULT 0")
kh.agregaColumna(Starter.skmt, "USUARIOA", "FECHA", "TEXT")
kh.agregaColumna(Starter.skmt, "PROMOS_COMP", "CAT_PA_PORCENTAJE_PAQUETE", "TEXT")
kh.agregaColumna(Starter.skmt, "PROMOS_COMP", "CAT_PA_PRECIO1", "TEXT")
@@ -174,6 +196,10 @@ Private Sub B4XPage_Created (Root1 As B4XView)
kh.agregaColumna(Starter.skmt, "CAT_GUNAPROD2", "CAT_GP_PROMOCION", "TEXT")
kh.agregaColumna(Starter.skmt, "TREND_SPENDING", "TIPO", "TEXT")
kh.agregaColumna(Starter.skmt, "CAT_DETALLES_PAQ", "CAT_DP_PRECIOB", "TEXT")
kh.agregaColumna(Starter.skmt, "PEDIDO", "PE_ARCH", "TEXT")
kh.agregaColumna(Starter.skmt, "PEDIDO_CLIENTE", "PC_ARCH", "TEXT")
kh.agregaColumna(Starter.skmt, "PEDIDO3", "PE_ARCH", "TEXT")
aud.Initialize(Starter.skmt)
Root = Root1
' Root.LoadLayout("MainPage")
Root.LoadLayout("login")
@@ -212,7 +238,7 @@ Private Sub B4XPage_Created (Root1 As B4XView)
ruta = Starter.ruta
Starter.tiempos.Initialize
kh.guardaAppInfo
Log(111)
'Revisamos si se disparo el intent de cargar la base de datos desde WhatApp.
If kh.traeUsarIntentBDWA Then kh.importaBDDesdeWhatsApp
@@ -253,7 +279,7 @@ Private Sub B4XPage_Created (Root1 As B4XView)
End If
' reqManager.Initialize(Me, Starter.server)
' Activity.LoadLayout("login")
Label1.Text = Application.VersionName
Label1.Text = Application.VersionName & " "
' Log("Pedimos permisos de almacenamiento externo")
' Starter.rp.CheckAndRequest(Starter.rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
@@ -312,6 +338,7 @@ Private Sub B4XPage_Created (Root1 As B4XView)
Msgbox("No se puede crear el archivo de foto","Aviso") 'ignore
End Try
End If
Log(222)
' Dim ph As Phone 'Get Id Device
' Dim DeviceID As String = Starter.ph.GetSettings("android_id").ToUpperCase
' If logger Then Log($"Marca: ${Starter.ph.manufacturer}, Modelo: ${Starter.ph.model}"$)
@@ -346,7 +373,7 @@ Private Sub B4XPage_Created (Root1 As B4XView)
Else
ToastMessageShow("Sin permisos para GPS", True)
End If
Log("***********************************************")
Log("33***********************************************33")
MES1.Initialize(Me, "MES1")
' Log("SDK: " & device.SdkVersion)
' Get the device SDK version
@@ -376,7 +403,7 @@ Private Sub B4XPage_Created (Root1 As B4XView)
End If
Log(MES1.IsInitialized)
Log(MES1.HasPermission)
Log("***********************************************")
Log("44***********************************************44")
MES1.Initialize(Me, "MES1")
' Log("Permisos BT: " & rp.Check("android.permission.BLUETOOTH_CONNECT"))
' Log("REVISAMOS PERMISOS DE BT")
@@ -389,8 +416,12 @@ Private Sub B4XPage_Created (Root1 As B4XView)
End Sub
Sub B4XPage_Appear
Log(">>>>>> INICIAMOS MAIN PAGE <<<<<<<<<")
Log(DateTime.GetDayOfWeek(DateTime.Now))
Log(">>>>>> APPEAR - INICIAMOS MAIN PAGE <<<<<<<<<")
aud.guarda($"Entrada a Login"$)
linker.Initialize(Me, "Linker", True)
clicked = 0
If Not(MES1.IsInitialized) Then MES1.Initialize(Me, "MES1")
' Log(DateTime.GetDayOfWeek(DateTime.Now))
kh.RD_Init
kh.SetButtonTintList(cb_geocerca, Colors.LightGray, Colors.RGB(43, 154, 211))
kh.SetButtonTintList(cb_cartaPorte, Colors.LightGray, Colors.RGB(43, 154, 211))
@@ -458,14 +489,14 @@ Sub B4XPage_Appear
cmd.Name = "select_fecha"
' cmd.Parameters = Array As Object(Null)
reqManager.ExecuteQuery(cmd , 0, "fecha")
Log("############### APPEAR PAGE ####################")
Log("############### PAGE_APPEAR ####################")
Log(MES1.IsInitialized)
If MES1.IsInitialized Then
LogColor("Permisos de almacenamiento: " & MES1.HasPermission, Colors.Magenta)
If MES1.HasPermission Then kh.revisaSiExisteRespaldo
' If MES1.HasPermission Then kh.revisaSiExisteRespaldo '' Se comenta causa el error de que en el primer cliente,al guardar la venta se trabe la aplicacion!!
End If
DateTime.DateFormat = "yyyy-MM-dd HH:mm:ss"
Starter.skmt.ExecNonQuery($"insert into versiones (version, fecha) values ('${Application.VersionName}', '${datetime.Date(DateTime.Now)}')"$)
Starter.skmt.ExecNonQuery($"insert into versiones (version, fecha) values ('${Application.VersionName}', '${DateTime.Date(DateTime.Now)}')"$)
End Sub
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
@@ -482,8 +513,8 @@ Sub Entrar_Click
Starter.skmt.ExecNonQuery2("INSERT INTO USUARIOA VALUES (?,?,?)", Array As Object(user.Text, pass.Text, DateTime.Date(DateTime.Now)))
Starter.skmt.ExecNonQuery("delete from cat_almacen")
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_ALMACEN(ID_ALMACEN) VALUES (?)", Array As Object (pass.Text))
Starter.skmt.ExecNonQuery("delete from VERSION")
Starter.skmt.ExecNonQuery2("INSERT INTO VERSION(NOVERSION) VALUES (?)", Array As Object ("2.95"))
' Starter.skmt.ExecNonQuery("delete from VERSION")
' Starter.skmt.ExecNonQuery2("INSERT INTO VERSION(NOVERSION) VALUES (?)", Array As Object ("2.95"))
B4XPages.ShowPage("Principal")
End If
' c=Starter.skmt.ExecQuery2("select count(*) as EXISTE1 from usuarioa where usuario = ?", Array As String(user.Text))
@@ -499,10 +530,11 @@ Sub Entrar_Click
cmd.Name = "select_usuario_guna_KELL"
cmd.Parameters = Array As Object(user.Text, pass.Text)
reqManager.ExecuteQuery(cmd , 0, "usuario")
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "select_version_KELL"
reqManager.ExecuteQuery(cmd , 0, "version")
' Dim cmd As DBCommand
' cmd.Initialize
' cmd.Name = "select_version_KELL"
' reqManager.ExecuteQuery(cmd , 0, "version")
Else
Subs.iniciaActividad("Principal")
' B4XPages.ShowPage("Principal")
@@ -516,7 +548,7 @@ Sub JobDone(Job As HttpJob)
LogColor("Error: " & Job.tag & " : " & Subs.parseHTTPError(Job.ErrorMessage), Colors.red)
ToastMessageShow("Error: " & Job.ErrorMessage, True)
Else
' If logger Then LogColor("JobDone: '" & reqManager.HandleJob(Job).tag & "' - Registros: " & reqManager.HandleJob(Job).Rows.Size, Colors.Green) 'Mod por CHV - 211110
If logger Then LogColor("JobDone: '" & reqManager.HandleJob(Job).tag & "' - Registros: " & reqManager.HandleJob(Job).Rows.Size, Colors.Green) 'Mod por CHV - 211110
If Job.JobName = "DBRequest" Then
Dim result As DBResult = reqManager.HandleJob(Job)
If result.Tag = "version" Then 'query tag
@@ -546,6 +578,7 @@ Sub JobDone(Job As HttpJob)
Dim result As DBResult = reqManager.HandleJob(Job)
If result.Tag = "usuario" Then 'query tag
Subs.logJobDoneResultados(result)
For Each records() As Object In result.Rows
Dim name As String = records(result.Columns.Get("USUARIO"))
Dim ID_ALMACEN As String = records(result.Columns.Get("CAT_LO_AGENCIA"))
@@ -583,6 +616,14 @@ Sub JobDone(Job As HttpJob)
p_importarBDWA.Visible = False
End If
End If
If result.Tag = "prueba" Then
Subs.logJobDoneResultados(result)
End If
If result.tag = "traeConexion" Then
Subs.logJobDoneResultados(result)
End If
End If
Job.Release
End If
@@ -705,6 +746,54 @@ Private Sub i_engranes_LongClick
' Wait For B4XPage_PermissionResult (Permission As String, Result As Boolean)
' Subs.copiaDB(Result)
' Dim x As Int = "a"
Dim reqManagerW As DBRequestManagerW
reqManagerW.Initialize
cmd.Initialize
Dim a As Int = "abc"
cmd.Name = "select_usuario_guna_KELL"
cmd.Parameters = Array As Object(user.Text, pass.Text)
reqManagerW.ExecuteQuery(Starter.DBReqServer, cmd, Me, "elUsuario")
Wait For elUsuario_Completed (res1 As TResultado)
Log("tag: " & res1.tag & " Success: " & res1.Success)
If res1.Success Then
Subs.logJobDoneResultados(res1.resultado)
Else
Log(res1.ErrorMessage)
End If
cmd.Name = "select_version_KELL"
cmd.Parameters = Array()
reqManagerW.ExecuteQuery(Starter.DBReqServer, cmd, Me, "laVersion")
Wait For laVersion_Completed (res2 As TResultado)
Log("tag: " & res2.tag & " Success: " & res2.Success)
If res2.Success Then
Subs.logJobDoneResultados(res2.resultado)
Else
Log(res2.ErrorMessage)
End If
cmd.Name = "delete_geoPass"
cmd.Parameters = Array As Object( Subs.traeAlmacen, Subs.traeRuta)
reqManagerW.ExecuteCommand(Starter.DBReqServer, cmd, Me, "borraGeoPass")
Wait For borraGeoPass_Completed (res3 As TResultado)
Log("tag: " & res3.tag & " Success: " & res3.Success)
If res3.Success Then
Subs.logJobDoneResultados(res3.resultado)
Else
Log(res3.ErrorMessage)
End If
End Sub
Sub elUsuario_Completed (res As DBResult)
Log("abc: " & res.tag)
Log("wrapper: " & res)
End Sub
Sub laVersion_Completed (res As DBResult)
Log("def: " & res.tag)
Log("wrapper2: " & res)
End Sub
Sub B_SERVER_Click
@@ -798,6 +887,13 @@ Private Sub b_cargaLocalOk_Click
p_cargaLocal.Visible = False
' Log(et_cargaLocal.Text.Length > pass1.Length)
Log("Deshabilitamos VERIFY_DEVICE")
Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("VERIFY_DEVICE"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("VERIFY_DEVICE", 0))
Log("Deshabilitamos VALIDA_VERSION")
Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("VALIDA_VERSION"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("VALIDA_VERSION", 0))
Log(et_cargaLocal.text)
If et_cargaLocal.Text.Length = pass1.Length Then ' Si no se especifica nada, la fecha es hoy MENOS un día.
et_cargaLocal.text = et_cargaLocal.text & "-1"
@@ -880,13 +976,6 @@ Private Sub cb_cartaPorte_CheckedChange(Checked As Boolean)
Starter.skmt.ExecNonQuery($"insert into CAT_VARIABLES (CAT_VA_DESCRIPCION, CAT_VA_VALOR) values ('CARTAPORTE', '${Checked}')"$)
End Sub
Private Sub et_maxClientesNuevos_TextChanged (Old As String, New As String)
If IsNumber(New) Then
Starter.skmt.ExecNonQuery("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'MAXCTESNUEVOS'")
Starter.skmt.ExecNonQuery($"insert into CAT_VARIABLES (CAT_VA_DESCRIPCION, CAT_VA_VALOR) values ('MAXCTESNUEVOS', '${New}')"$)
End If
End Sub
private Sub l_geocerca_Click
If cb_geocerca.Enabled = False Then ToastMessageShow("Ingrese la contraseña para modificar", True)
End Sub
@@ -896,6 +985,8 @@ Private Sub et_geocerca_TextChanged (Old As String, New As String)
Log(New & "|" & Starter.passSupervisor)
If x.RowCount > 0 Then
x.Position = 0
Log("Pass FinDia: |" & x.GetString("CAT_VA_VALOR")&"|"&New&"|")
Log(New.Trim = x.GetString("CAT_VA_VALOR").Trim)
If New = x.GetString("CAT_VA_VALOR") Or New = Starter.passSupervisor Then
cb_geocerca.Enabled = True
cb_cartaPorte.Enabled = True
@@ -975,6 +1066,77 @@ Sub GetFecha
End Sub
Private Sub ImageView1_LongClick
Log("###### TRAEMOS FECHA #######")
GetFecha
' Log("###### TRAEMOS FECHA #######")
' GetFecha
' Log("traeConexion")
' Private reqManagerX As DBRequestManager
' reqManagerX.Initialize(Me, "http://keymon.net:9010")
' Private cmdX As DBCommand
' cmdX.Initialize
' cmdX.Name = "update_usuario_guna_nobajas"
' cmdX.Parameters = Array As Object("CDAZA")
' reqManagerX.Executequery(cmdX, 0, "traeConexion")
Log("traeConexion")
Private reqManagerX As DBRequestManager
reqManagerX.Initialize(Me, "http://keymon.net:9010/SALMA")
Private cmdX As DBCommand
cmdX.Initialize
cmdX.Name = "update_usuario_guna_nobajas"
cmdX.Parameters = Array As Object("CDAZA", 2, 3, 4)
reqManagerX.ExecuteQuery(cmdX, 0, "prueba")
' If Subs.traeAlmacen <> "" Then
' linker.VerifyDevice(Subs.traeAlmacen, Subs.traeRuta)
' End If
End Sub
Sub ponUsuario
Private cu As Cursor = Starter.skmt.ExecQuery("select USUARIO from USUARIOA")
If cu.RowCount > 0 Then
cu.Position = 0
If cu.GetString("USUARIO") <> "" Then user.Text = cu.GetString("USUARIO")
End If
End Sub
Private Sub Label4_Click
clicked = clicked + 1
Log(clicked)
If clicked >= 5 Then
clicked = 0
ponUsuario
End If
End Sub
Sub Linker_Response(Status As String) ' << AÑADE ESTE SUB [New Query]
If Starter.Logger Then LogColor($"Respuesta de DeviceLinker para la verificación del dispositivo: ${Status}"$, Colors.Magenta) '
Select Status
Case "UUID_ERROR"
Log("Error interno al obtener el identificador único del dispositivo.")
ToastMessageShow("Error interno al obtener el identificador único del dispositivo.", True)
Case "HTTP_ERROR"
LogColor("Error HTTP al verificar el dispositivo: " & linker.lastJobDoneError, Colors.Red)
ToastMessageShow("Error de conexión al servidor durante la verificación del dispositivo.", True)
Case "SERVER_LOGIC_ERROR"
Log("El servidor no proporcionó un estado de verificación válido. Contacte a soporte.")
ToastMessageShow("El servidor no proporcionó un estado de verificación válido. Contacte a soporte.", True)
Case "OK"
Log("Dispositivo vinculado y verificado exitosamente.")
ToastMessageShow("Dispositivo verificado y vinculado correctamente.", False)
' Aquí puedes añadir lógica adicional si la verificación es exitosa, por ejemplo, habilitar ciertos botones o continuar con el flujo normal.
Case "NO_REGISTRADO"
Log("Dispositivo NO registrado.")
ToastMessageShow("Dispositivo NO registrado.", False)
Case "REGISTRO_NUEVO"
Log("¡¡Registro nuevo!!")
ToastMessageShow("¡¡Registro nuevo!!", False)
Case "YA_REGISTRADO"
Log("¡¡El dispositivo ya esta registrado con otra ruta!!")
ToastMessageShow("¡¡El dispositivo ya esta registrado con otra ruta!!", True)
Case Else ' Otros estados que tu servidor pueda devolver (ej. "UNAUTHORIZED", "PENDING_APPROVAL")
Log($"Estado de verificación del dispositivo: ${Status}"$)
ToastMessageShow($"Verificación del dispositivo: ${Status}"$, True)
' Puedes decidir si bloquear la funcionalidad o mostrar un mensaje específico según el estado.
End Select
End Sub

84
B4A/C_Auditoria.bas Normal file
View File

@@ -0,0 +1,84 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=12.8
@EndOfDesignText@
Sub Class_Globals
Dim audb As SQL
Dim ruta As String = File.DirInternal
End Sub
'You can add more parameters here.
Public Sub Initialize(db As SQL) As Object
If Not(audb.IsInitialized) Then audb.Initialize(ruta,"kmt.db", True)
audb = db
audb.ExecNonQuery("CREATE TABLE IF NOT EXISTS auditoria(almacen text, ruta text, usuario text, cliente text, evento text, fecha text, lat text, lon text)")
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.
Sub guarda(evento As String)
DateTime.DateFormat = "yyyy-MM-dd HH:mm:ss"
audb.ExecNonQuery2("insert into auditoria (almacen, ruta, usuario, cliente, evento, fecha, lat, lon) values (?, ?, ?, ?, ?, ?, ?, ?)", Array As String(traeAlmacen, traeRuta, traeUsuarioDeBD, traeCliente, evento, DateTime.Date(DateTime.Now)))
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 = audb.ExecQuery("select ID_ALMACEN from CAT_ALMACEN")
If c.RowCount > 0 Then
c.Position = 0
a = C.GetString("ID_ALMACEN")
End If
c.Close
Return a
End Sub
'Regresa la ruta actual de la base de datos.
Sub traeRuta As String 'ignore
Private c As Cursor
Private r As String
c = audb.ExecQuery("select CAT_CL_RUTA from kmt_info limit 1")
r = "0"
If c.RowCount > 0 Then
c.Position = 0
r = c.GetString("CAT_CL_RUTA")
End If
c.Close
Return r
End Sub
'Regresa el usuario de la tabla USUARIOA
Sub traeUsuarioDeBD As String 'ignore
Private c As Cursor
Private u As String = "SinUsuario"
c = audb.ExecQuery("select USUARIO from usuarioa")
If c.RowCount > 0 Then
c.Position = 0
u = c.GetString("USUARIO")
End If
c.Close
Return u
End Sub
'Trae el cliente de CUENTAA
Sub traeCliente As String 'ignore
Private c As Cursor
Private cl As String = ""
c = audb.ExecQuery("Select CUENTA from cuentaa")
If c.RowCount > 0 Then
c.Position = 0
cl = c.GetString("CUENTA")
End If
c.Close
Return cl
End Sub

View File

@@ -11,6 +11,7 @@ Sub Class_Globals
Dim g As GPS
Dim kh As kms_helperSubs
Dim reqManager As DBRequestManager
Dim cmd As DBCommand
Dim ruta As String
Dim clie_id As String
Dim sDate,sTime As String
@@ -48,6 +49,8 @@ Sub Class_Globals
Dim C1 As Cursor
Dim C3 As Cursor
Dim C4, C5, C6, C8 As Cursor
Dim c2 As Cursor
Dim S2 As Cursor
Dim RMI As String
Dim ListView1 As ListView
Dim la_cuenta As Label
@@ -79,9 +82,6 @@ Sub Class_Globals
Dim Guardar As Button
' Dim NUEVO As Button
Dim l_total As Label
Dim c2 As Cursor
Dim S2 As Cursor
Private s As Cursor
Dim res As String
Private HIST As Button
Private MONTO_COMPRA As String
@@ -295,6 +295,12 @@ Sub Class_Globals
Private e_comm As EditText
Private p_infoGral2 As Panel
Dim indicePregunta As Int
Private p_transparenciaNoti As Panel
Private p_Notificacion As Panel
Private l_notificacionTexto As Label
Private l_notificacionTitulo As Label
Private b_notificacion As Button
Dim reqManagerW As DBRequestManagerW
End Sub
'You can add more parameters here.
@@ -375,6 +381,7 @@ Private Sub B4XPage_Created (Root1 As B4XView)
Else
RutaBoleta=Starter.rutaV
End If
If s.IsInitialized Then s.Close
End If
c=Starter.skmt.ExecQuery2("select CAT_VA_VALOR from CAT_VARIABLES WHERE CAT_VA_DESCRIPCION = ?", Array As String ("MACIMP"))
c.Position = 0
@@ -390,7 +397,6 @@ Private Sub B4XPage_Created (Root1 As B4XView)
c.Close
Panel_INV_A.Left = 0 : Panel_INV_A.top = 0
Panel10.Left = 0 : Panel10.top = 0
If s.IsInitialized Then s.Close
' Log("################# PERMISOS BT: " & Starter.rp.Check("android.permission.BLUETOOTH_CONNECT"))
' Log("Permisos BT: " & Starter.rp.Check("android.permission.BLUETOOTH_CONNECT"))
' Log("REVISAMOS PERMISOS DE BT")
@@ -403,27 +409,31 @@ End Sub
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
Sub B4XPage_Appear
B4XPages.MainPage.aud.guarda($"Entrada a Cliente"$)
indicePregunta = 0
b_noVenta.Enabled = False
Log("NoVenta False")
' Log(kh.traeTotalCliente)
If kh.traeTotalCliente = 0 Then b_noVenta.Enabled = True
clienteId = kh.traeCliente
P_DOE.Visible = False
dentroDeGeocerca = False
' Log($"TOTAL VENTA: ${kh.traeTotalCliente}"$)
B_VENTA.Visible = False
b_noVenta.Visible = False
Log("NoVenta False")
If clienteId.StartsWith("N") Then b_noVenta.Visible = False
l_doe.Text = "HAY PEDIDO DOE"
' Log(Starter.rp.Check("android.permission.BLUETOOTH_CONNECT"))
reqManager.Initialize(Me, Starter.DBReqServer)
reqManagerW.Initialize
usarGeocerca = kh.traeUsarGeocerca
'Para el almacen 12 (GDL) no se usa la geocerca
If kh.traeAlmacen = 12 Then usarGeocerca = False
' If kh.traeAlmacen = 12 Then usarGeocerca = False
' Log(Subs.traeUltimaActividadBD)
c = Starter.skmt.ExecQuery2("select CAT_VA_VALOR from CAT_VARIABLES WHERE CAT_VA_DESCRIPCION = ?", Array As String ("MACIMP"))
c.Position = 0
@@ -492,10 +502,8 @@ Sub B4XPage_Appear
l_atiende.Text = "N/A"
If c.GetString("CAT_CL_ATIENDE1") <> Null And c.GetString("CAT_CL_ATIENDE1") <> "null" Then l_atiende.Text = c.GetString("CAT_CL_ATIENDE1")
l_atiende2.Text = c.GetString("CAT_CL_ATIENTE2")
l_segmento2.text = "N/A"
If c.GetString("CAT_CL_SEGMENTO") <> Null Then l_segmento2.text = c.GetString("CAT_CL_SEGMENTO")
b_inicioFinVenta.Text = "INICIAR VENTA"
b_inicioFinVenta.BringToFront
' LogColor(">>>>>> EN VENTA: " & Starter.enVenta, Colors.red)
@@ -507,7 +515,7 @@ Sub B4XPage_Appear
b_inicioFinVenta.Visible = False
End If
' LogColor(">>>>>> EN VENTA: " & Starter.enVenta, Colors.red)
' LONGITUD = 0
' If c.GetString("CAT_CL_LONG") <> Null And c.GetString("CAT_CL_LONG") <> "null" And IsNumber(c.GetString("CAT_CL_LONG")) Then LONGITUD = c.GetString("CAT_CL_LONG")
' LATITUD = 0
@@ -545,9 +553,13 @@ Sub B4XPage_Appear
End If
If kh.traeTotalCliente < 0.01 And kh.traeTotalClienteDOE < 0.01 Then
If Not(clienteId.StartsWith("N")) And la_cuenta.Text <> "0" Then b_noVenta.Visible = True 'Ni cliente nuevo, ni abordo.
If Not(clienteId.StartsWith("N")) And la_cuenta.Text <> "0" Then
' b_noVenta.Visible = True 'Ni cliente nuevo, ni abordo. ... Si apagan el GPS, y este esta habilitado, les da tiempo de meter NoVenta aun estando fuera de la geocerca.
' Log("NoVenta True")
End If
Else
b_noVenta.Visible = False
Log("NoVenta False")
If la_cuenta.text = 0 Then
CREDITO_DISPONIBLE = 10000000
CREDITO = 0
@@ -681,7 +693,10 @@ Sub B4XPage_Appear
c = Starter.skmt.ExecQuery("select count(*) as conNoVenta FROM NOVENTA WHERE NV_CLIENTE IN (Select CUENTA from cuentaa)")
c.Position = 0
If c.GetString("conNoVenta") = 1 Then b_noVenta.Visible = False 'Si ya tiene NoVenta, ocultamos el boton.
If c.GetString("conNoVenta") = 1 Then
b_noVenta.Visible = False 'Si ya tiene NoVenta, ocultamos el boton.
Log("NoVenta False")
End If
c.Close
Else
RutaBoleta=Starter.rutaV
@@ -763,8 +778,9 @@ Sub B4XPage_Appear
'PROMOS POR MONTO
Private mPromoXMonto As Map = Subs.revisaPromoPorMonto
Private elMontoTSDeLaVenta As String = 0
' LogColor("PROMOXMONTO:" & mPromoXMonto, Colors.Blue)
If mPromoXMonto.Size > 0 And clienteId <> 0 Then ' El "clienteId <> 0" es para que no la promo cuando se pida ABORDO
If mPromoXMonto.Size > 0 And clienteId <> 0 Then ' El "clienteId <> 0" es para que no de la promo cuando sea ABORDO
If l_total.Text > mPromoXMonto.Get("rangoMin") And l_total.Text < mPromoXMonto.Get("precio1") Then
Log("Eres candidato a una promocion")
MsgboxAsync($"Si agregas venta para que supere los $${mPromoXMonto.Get("precio1")}, la promoción "${Subs.traeProdNombre(mPromoXMonto.Get("id"))}" se agregará automáticamente."$, "AGREGA VENTA")
@@ -772,16 +788,24 @@ Sub B4XPage_Appear
'Agregamos la promocion y sus productos FIJOS.
Private dp As Cursor = Starter.skmt.ExecQuery($"select * from cat_detalles_paq where cat_dp_id = '${mPromoXMonto.Get("id")}'"$)
If dp.RowCount > 0 Then
Log(">>>> GUARDAMOS PROMOXMONTO HEADER")
Subs.guardaProductoSinGestion(mPromoXMonto.Get("id"), 0, 1, Subs.traeProdNombre(mPromoXMonto.Get("id")), mPromoXMonto.Get("id"), Subs.traeCliente, Subs.traeFecha, Subs.traeUsuarioDeBD, Subs.traeRuta, 0, Starter.tipov)
For i = 0 To dp.RowCount - 1
dp.Position = i
If dp.GetString("CAT_DP_TIPO") = "0" Then
Log(">>>> GUARDAMOS PROMOXMONTO PRODS")
Subs.guardaProductoSinGestion(mPromoXMonto.Get("id"), dp.GetString("CAT_DP_PRECIO"), dp.GetString("CAT_DP_PZAS"), Subs.traeProdNombre(dp.GetString("CAT_DP_IDPROD")), dp.GetString("CAT_DP_IDPROD"), Subs.traeCliente, Subs.traeFecha, Subs.traeUsuarioDeBD, Subs.traeRuta, 0, Starter.tipov)
' Traemos el monto de las bonificacionos a guardar. -- Trade Spending
Log("Monto Bonificacion -->> " & B4XPages.MainPage.promos.ts.traeMontoBonificacion(dp.GetString("CAT_DP_IDPROD"), dp.GetString("CAT_DP_PRECIO"), mPromoXMonto.Get("id"),"LOG_APPEAR1"))
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (B4XPages.MainPage.promos.ts.traeMontoBonificacion(dp.GetString("CAT_DP_IDPROD"), dp.GetString("CAT_DP_PRECIO"), mPromoXMonto.Get("id"), "APPEAR2") * dp.GetString("CAT_DP_PZAS"))
End If
Next
B4XPages.MainPage.promos.ts.modTrendSpending("RESTA", "BONIFICACIONES", elMontoTSDeLaVenta)
Log($"### modTrendSpending("RESTA", "BONIFICACIONES", ${elMontoTSDeLaVenta})"$)
MsgboxAsync($"Promo por monto "${Subs.traeProdNombre(mPromoXMonto.Get("id"))}" agregada."$,"AVISO")
B4XPage_Appear
End If
dp.Close
End If
End If
Private ppm As Cursor = Starter.skmt.ExecQuery($"select (select ifnull(sum(PE_COSTO_TOT),0) from pedido where CAT_PA_ID <> pe_cedis) as CT, ifnull((select pe_cedis from pedido where pe_cedis = CAT_PA_ID), 0) as existe, * from PROMOS_COMP where CAT_PA_TIPO_PROMONTO = '1' and CT < cast(cat_pa_precio1 as integer)"$) 'Traemos las promos por monto donde la venta es menor al precio1 para borrarlas.
@@ -800,10 +824,41 @@ Sub B4XPage_Appear
B4XPage_Appear
End If
End If
ppm.Close
If Not(Subs.revisaHora) Then
Log("***************** HORA INCORRECTA")
MsgboxAsync("La hora del equipo NO coincide con la hora del servidor, es necesario corregirla", "AVISO IMPORTANTE")
End If
c = Starter.skmt.ExecQuery($"select * from cat_notificaciones where CN_CLIENTE = '${Subs.traeCliente}'"$)
Log("###############################################################")
Log(c.RowCount)
Log("###############################################################")
If c.RowCount > 0 Then
c.Position = 0
l_notificacionTexto.Text = c.GetString("CN_NOTIFICACION")
p_transparenciaNoti.Top = 0 : p_transparenciaNoti.Left = 0
p_transparenciaNoti.Height = Root.Height
p_transparenciaNoti.Width = Root.Width
Subs.centraPanel(p_Notificacion, Root.Width)
p_transparenciaNoti.Visible = True
Log(c.GetString("CN_ID") & "|" & c.GetString("CN_CODIGO"))
b_notificacion.Tag = c.GetString("CN_ID") & "|" & c.GetString("CN_CODIGO")
p_transparenciaNoti.BringToFront
End If
c.Close
' Este codigo es para hacer que el Label de las notificaciones tenga SCROLLVERTICAL.
Dim labeljo, scrollerjo As JavaObject
labeljo = l_notificacionTexto
scrollerjo.InitializeNewInstance("android.text.method.ScrollingMovementMethod", Null)
labeljo.RunMethod("setMovementMethod", Array(scrollerjo)) ' Asigna el método de movimiento para permitir scroll
labeljo.RunMethod("setHorizontallyScrolling", Array(False)) ' CAMBIO: Para scroll vertical, esto DEBE ser False
labeljo.RunMethod("setVerticalScrollBarEnabled", Array(True)) ' Opcional: Forzar a que el scroll sea vertical explícitamente si el contenido es grande
' Forzar el scroll al inicio (0,0)
Sleep(0)
' El primer 0 es la posición X (horizontal), el segundo es la posición Y (vertical)
labeljo.RunMethod("scrollTo", Array(0, 0))
'Termina codigo de label horzontal
End Sub
Sub Printer1_Connected (Success As Boolean)
@@ -855,7 +910,7 @@ Sub GPS_LocationChanged (Location1 As Location)
End If
laDist= Location1.DistanceTo(ubicacionTienda)
l_ubicacion2.Text = $"Dist: $1.0{laDist} mts."$
If laDist > 300 Then
If laDist > 50 Then ' Antes 300
l_ubicacion2.TextColor = Colors.Red
dentroDeGeocerca = False
Else
@@ -879,7 +934,7 @@ Sub GPS_LocationChanged (Location1 As Location)
If c.RowCount > 0 Then
gps_boton_doe = c.GetString("CAT_CL_EMAIL")
End If
c.Close
' gest.Visible = True
' gps_boton_doe ="1"
' LogColor($"Distancia actual: ${distance}"$, Colors.Blue)
@@ -892,6 +947,7 @@ Sub GPS_LocationChanged (Location1 As Location)
clienteConPromo = x.GetString("clienteConPromo")
' Log($"${x.GetString("clienteConPromo")}"$)
End If
x.Close
' If pgs_boton_noventa = "1" Then b_noVenta.Visible = True
' If gps_boton_doe ="1" Then b_whats.Visible = True
@@ -899,10 +955,14 @@ Sub GPS_LocationChanged (Location1 As Location)
' If gps_boton_doe = "1" And clienteConPromo = "0" And revisaExistenciasDOE Then b_whats.Visible = True
If Not(clienteDeudor) Then B_VENTA.Visible = True 'Si el cliente no tiene adeudo, habilitamos el boton de venta
If Not(clienteId.StartsWith("N")) And la_cuenta.Text <> "0" Then b_noVenta.Visible = True 'Ni cliente nuevo, ni abordo.
If Not(clienteId.StartsWith("N")) And la_cuenta.Text <> "0" Then
b_noVenta.Visible = True 'Ni cliente nuevo, ni abordo.
' Log("NoVenta False")
End If
If Not(p_rechazoDOE.Visible) Then pedido_doe_muestra
Else
b_noVenta.Visible = False
' Log("NoVenta False")
B_VENTA.Visible = False
b_whats.Visible = False
End If
@@ -961,6 +1021,7 @@ Sub DATOS_Click
End Sub
Sub Guardar_Click
B4XPages.MainPage.aud.guarda($"Guarda Venta Cliente"$)
DateTime.DateFormat = "MM/dd/yyyy"
sDate=DateTime.Date(DateTime.Now)
sTime=DateTime.Time(DateTime.Now)
@@ -981,7 +1042,7 @@ Sub Guardar_Click
Starter.skmt.ExecNonQuery("delete from NOVENTA where NV_CLIENTE In (select cuenta from cuentaa)")
Starter.skmt.ExecNonQuery("delete from pedido_cliente where PC_CLIENTE In (select cuenta from cuentaa)")
If logger Then LogColor($"Insertamos coordenadas en pedido: ${Starter.lon_gps}, ${Starter.lat_gps}"$, Colors.Magenta)
Starter.skmt.ExecNonQuery2("insert into pedido_cliente(PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT) VALUES (?,?,?,?,?,?,?)", Array As Object(clie_id, sDate & sTime, usuario, c.GetString("CANT_CLIE"),c.GetString("TOTAL_CLIE"), Starter.lon_gps, Starter.lat_gps))
Starter.skmt.ExecNonQuery2("insert into pedido_cliente(PC_RUTA, PC_ALMACEN, PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT) VALUES (?,?,?,?,?,?,?,?,?)", Array As Object(Subs.traeAlmacen, Subs.traeRuta, clie_id, sDate & sTime, usuario, c.GetString("CANT_CLIE"),c.GetString("TOTAL_CLIE"), Starter.lon_gps, Starter.lat_gps))
Log("Actualizamos gestion")
Starter.skmt.ExecNonQuery("UPDATE kmt_info set gestion = 2 where CAT_CL_CODIGO In (select cuenta from cuentaa)")
End If
@@ -993,8 +1054,8 @@ Sub Guardar_Click
End If
s.Close
Starter.skmt.ExecNonQuery("delete from pedido3")
Starter.skmt.ExecNonQuery("INSERT INTO PEDIDO3 (PE_PRECIO2, PE_TIPO, PE_DESC, PE_COSTO_SIN, PE_RUTA, PE_CEDIS, PE_COSTO_TOT, PE_COSTOU, PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_USUARIO ) SELECT PE_PRECIO2, PE_TIPO, PE_DESC, PE_COSTO_SIN, PE_RUTA, PE_CEDIS, SUM(PE_COSTO_TOT) AS PE_COSTO_TOT, PE_COSTOU, SUM(PE_CANT) As PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_USUARIO FROM PEDIDO WHERE PE_CLIENTE IN (Select CUENTA from cuentaa) GROUP BY PE_PRECIO2, PE_TIPO, PE_DESC, PE_COSTO_SIN, PE_RUTA, PE_CEDIS, PE_COSTOU, PE_PRONOMBRE, PE_PROID, PE_CLIENTE ")
c=Starter.skmt.ExecQuery("select PE_PRECIO2,PE_TIPO,PE_DESC,PE_COSTO_SIN,PE_RUTA,PE_CEDIS,PE_COSTO_TOT,PE_COSTOU,PE_CANT,PE_PRONOMBRE,PE_PROID,PE_CLIENTE, PE_FECHA,PE_USUARIO FROM PEDIDO WHERE PE_CLIENTE IN (Select CUENTA from cuentaa)")
Starter.skmt.ExecNonQuery("INSERT INTO PEDIDO3 (PE_PRECIO2, PE_TIPO, PE_DESC, PE_COSTO_SIN, PE_RUTA, PE_CEDIS, PE_COSTO_TOT, PE_COSTOU, PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_USUARIO, PE_ENVIADO) SELECT PE_PRECIO2, PE_TIPO, PE_DESC, PE_COSTO_SIN, PE_RUTA, PE_CEDIS, SUM(PE_COSTO_TOT) AS PE_COSTO_TOT, PE_COSTOU, SUM(PE_CANT) As PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_USUARIO, PE_ENVIADO FROM PEDIDO WHERE PE_CLIENTE IN (Select CUENTA from cuentaa) GROUP BY PE_PRECIO2, PE_TIPO, PE_DESC, PE_COSTO_SIN, PE_RUTA, PE_CEDIS, PE_COSTOU, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_ENVIADO")
c=Starter.skmt.ExecQuery("select PE_PRECIO2,PE_TIPO,PE_DESC,PE_COSTO_SIN,PE_RUTA,PE_CEDIS,PE_COSTO_TOT,PE_COSTOU,PE_CANT,PE_PRONOMBRE,PE_PROID,PE_CLIENTE,PE_FECHA,PE_USUARIO,PE_ENVIADO FROM PEDIDO WHERE PE_CLIENTE IN (Select CUENTA from cuentaa)")
If c.RowCount>0 Then
For i=0 To c.RowCount -1
c.Position=i
@@ -1023,6 +1084,11 @@ Sub Guardar_Click
b_inicioFinVenta.Text = "TERMINAR VENTA"
Log("RESPALDO")
kh.RD_respaldoBatch
' Subir_Pedido_Con_Integridad(clie_id)
mandaPendientes
If la_cuenta.Text <> "0" Then 'Si es ABORDO, no mostramos el boton b_inicioFinVenta y regresamos a Principal.
b_inicioFinVenta.Visible = True
Else
@@ -1035,6 +1101,12 @@ Sub Guardar_Click
End If
End Sub
Sub mandaPendientes
' B4XPages.MainPage.principal.enviaPedido(Null)
' B4XPages.MainPage.principal.enviaPedidoCliente(Null)
B4XPages.MainPage.principal.enviaPedidoBatch(Null)
End Sub
Sub NUEVO_Click
' Subs.iniciaActividad("nuevocliente")
End Sub
@@ -1083,24 +1155,26 @@ End Sub
Sub B_IMP_Click
' Buscamos los clientes que tienen pedido y NO estan impresos.
Private t As Cursor = Starter.skmt.ExecQuery("Select cat_cl_codigo from kmt_info where impresion = 0 and cat_cl_codigo not in (select ci_cuenta from cliente_impreso) and cat_cl_codigo in (select distinct pe_cliente from pedido)")
If t.RowCount > 0 Then
For i = 0 To t.RowCount - 1
t.Position = i ' Y los BORRAMOS.
Log(t.GetString("CAT_CL_CODIGO"))
Starter.skmt.ExecNonQuery($"update CUENTAA set CUENTA = '${t.GetString("CAT_CL_CODIGO")}'"$)
Subs.borraPedidoClienteActual
' Msgbox2Async($"El pedido del cliente ${t.GetString("CAT_CL_CODIGO")} no está impreso, se va a borrar"$, "PEDIDO NO IMPRESO", "Aceptar", "", "", Null, True)
Next
End If
' Private t As Cursor = Starter.skmt.ExecQuery("Select cat_cl_codigo from kmt_info where impresion = 0 and cat_cl_codigo not in (select ci_cuenta from cliente_impreso) and cat_cl_codigo in (select distinct pe_cliente from pedido)")
' If t.RowCount > 0 Then
' For i = 0 To t.RowCount - 1
' t.Position = i ' Y los BORRAMOS.
' Log(t.GetString("CAT_CL_CODIGO"))
' Starter.skmt.ExecNonQuery($"update CUENTAA set CUENTA = '${t.GetString("CAT_CL_CODIGO")}'"$)
' Subs.borraPedidoClienteActual
'' Msgbox2Async($"El pedido del cliente ${t.GetString("CAT_CL_CODIGO")} no está impreso, se va a borrar"$, "PEDIDO NO IMPRESO", "Aceptar", "", "", Null, True)
' Next
' End If
Sleep(1000)
Starter.skmt.Close : Log("Cerramos BD") : Starter.revisaBD
Subs.panelAnchoAlto(Panel_INV_A, Root.Width, Root.Height)
Panel_INV_A.Visible = True
P_INF_GENERAL.Visible = False
If logger Then Log("Panel general="&P_INF_GENERAL.Visible)
L_INVA.Left = 5dip
L_INVA.Width = Root.Width * 0.98
L_INVA.Clear
Dim label1 As Label
label1 = L_INVA.TwoLinesLayout.Label
@@ -1112,10 +1186,10 @@ Sub B_IMP_Click
label2.TextColor = Colors.Black
' Aqui es donde esta el pedo de julieta de los descuentos, quitar el precio2 pero meter un if para saber si es ruta especial o es normal o que show.
s=Starter.skmt.ExecQuery2 ("select CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_ALMACEN from cat_gunaprod2 where CAT_GP_CLASIF <> ? ORDER BY CAT_GP_NOMBRE ", Array As String("PROMOS"))
If s.RowCount>0 Then
For i=0 To S.RowCount -1
If s.RowCount > 0 Then
For i = 0 To S.RowCount - 1
s.Position=i
S1=Starter.skmt.ExecQuery2("select CAT_GP_ALMACEN from cat_gunaprod5 where CAT_GP_ID = ?", Array As String(s.GetString("CAT_GP_ID")))
S1=Starter.skmt.ExecQuery2("select CAT_GP_ALMACEN from cat_gunaprod2 where CAT_GP_ID = ?", Array As String(s.GetString("CAT_GP_ID")))
S1.Position=0
S3=Starter.skmt.ExecQuery2("select count(*) as CUANTOS from HIST_ABORDO where HIST_PROID = ?", Array As String(s.GetString("CAT_GP_ID")))
S3.Position=0
@@ -1140,12 +1214,13 @@ Sub B_IMP_Click
C3.Position=0
a_venta = C3.GetString("CANTIDAD")
a_VENTA_F = C3.GetString("TOTAL")
C3.Close
Else
a_venta = 0
a_VENTA_F = 0
End If
C4.Close
C4=Starter.skmt.ExecQuery2("select count(*) as CUANTOS from pedido where substr(pe_pronombre,1,6) = ? AND PE_PROID = ? ", Array As String("CAMBIO", s.GetString("CAT_GP_ID")))
C4.Position=0
If C4.GetString("CUANTOS") > 0 Then
@@ -1162,6 +1237,10 @@ Sub B_IMP_Click
Next
End If
s.Close
If S1.IsInitialized Then S1.Close
If S3.IsInitialized Then S3.Close
If S2.IsInitialized Then S2.Close
If C4.IsInitialized Then C4.Close
End Sub
Sub B_IMP2_Click
@@ -1286,6 +1365,7 @@ Sub Imprime_ticket
cr.Position = 0
If cr.GetInt("CREDITO") = 1 Then formaPago = "Crédito"
End If
cr.Close
If la_cuenta.Text = "0" Then
LogColor(123, Colors.red)
Try
@@ -1301,8 +1381,8 @@ Sub Imprime_ticket
Printer1.WriteString("Entre calle1: " & l_entre1.Text & CRLF)
Printer1.WriteString("Entre Calle2: " & l_entre2.Text & CRLF)
LogColor("Entre Calle2: " & l_entre2.Text, Colors.red)
Printer1.WriteString("Forma de pago: " & formaPago & CRLF)
LogColor("Forma de pago: " & formaPago, Colors.red)
' Printer1.WriteString("Forma de pago: " & formaPago & CRLF)
' LogColor("Forma de pago: " & formaPago, Colors.red)
Printer1.WriteString(" " & CRLF)
Printer1.WriteString("------------------------------" & CRLF)
Printer1.WriteString("PEDIDO" & CRLF)
@@ -1431,7 +1511,7 @@ Sub Imprime_ticket
End Try
Else
Try
LogColor(456, Colors.red)
' LogColor(456, Colors.red)
DateTime.DateFormat = "yyyymmdd"
sDate=DateTime.Date(DateTime.Now)
Printer1.WriteString("KELLOGG COMPANY MEXICO" & CRLF)
@@ -1450,9 +1530,9 @@ Sub Imprime_ticket
Printer1.WriteString("C.P.: " & la_cp.Text & CRLF)
Printer1.WriteString("Entre calle1: " & l_entre1.Text & CRLF)
Printer1.WriteString("Entre Calle2: " & l_entre2.Text & CRLF)
LogColor("Entre Calle2: " & l_entre2.Text, Colors.red)
' LogColor("Entre Calle2: " & l_entre2.Text, Colors.red)
Printer1.WriteString("Forma de pago: " & formaPago & CRLF)
LogColor("Forma de pago: " & formaPago, Colors.red)
' LogColor("Forma de pago: " & formaPago, Colors.red)
Printer1.WriteString(" " & CRLF)
''''''' PEDIDOS DOE
@@ -1629,8 +1709,8 @@ Sub Imprime_ticket
Printer1.WriteString(Printer1.UNREVERSE & Printer1.BOLD & "Sub Total CAMBIOS: $" & NumberFormat2(sTotal3, 1, 2, 2, False) & CRLF)
Private cantidad2 As String = "0"
If s.GetString("CANTIDAD") <> Null And IsNumber(s.GetString("CANTIDAD")) Then cantidad2 = s.GetString("CANTIDAD")
Log("|" & cantidad1 & "|")
Log("|" & s.GetString("CANTIDAD") & "|" & cantidad1 & "|")
' Log("|" & cantidad1 & "|")
' Log("|" & s.GetString("CANTIDAD") & "|" & cantidad1 & "|")
Printer1.WriteString( Printer1.UNREVERSE & Printer1.BOLD & "No. Productos: " & cantidad2 & CRLF)
Printer1.WriteString(CRLF)
s.Close
@@ -3212,7 +3292,7 @@ Sub B_IMP_INVBAK_Click
Printer1.WriteString("RESUMEN DIA" & CRLF)
Printer1.WriteString(sDate & " " & sTime & CRLF)
Printer1.WriteString("Vendedor:" & usuario & CRLF)
Printer1.WriteString("-------INVENTARIO A BORDO----------" & CRLF)
Printer1.WriteString("-------INVENTARIO ABORDO----------" & CRLF)
Printer1.WriteString("---II---CD---IIT---VT---RMI---IF---" & CRLF)
' aqui es donde esta el pedo de julieta de los descuentos quitar el precio2 pero meter un if para saber si es ruta especial o es normal o que show.
@@ -3507,7 +3587,7 @@ Sub B_IMP_INV_Click
Printer1.WriteString("RESUMEN DIA" & CRLF)
Printer1.WriteString(sDate & " " & sTime & CRLF)
Printer1.WriteString("Vendedor:" & usuario & CRLF)
Printer1.WriteString("-------INVENTARIO A BORDO----------" & CRLF)
Printer1.WriteString("-------INVENTARIO ABORDO----------" & CRLF)
''' se cambia este Printer1.WriteString("---II---CD---IIT---VT---RMI---IF---" & CRLF) ------- sin RMI
Printer1.WriteString("---II---CD---IIT---VT---------IF---" & CRLF)
@@ -3516,11 +3596,11 @@ Sub B_IMP_INV_Click
Log($"Reglones: ${s.RowCount}"$)
If s.RowCount > 0 Then
For i = 0 To S.RowCount - 1
Log(i)
' Log(i)
Try
s.Position = i
Printer1.WriteString(s.GetString("CAT_GP_NOMBRE") & CRLF)
Log("p"&i)
' Log("p"&i)
Catch
Log(LastException)
If logger Then Log("Saliendo con Try/Catch")
@@ -3715,14 +3795,14 @@ Sub B_IMP_INV_Click
Printer1.WriteString(CRLF)
End Try
End If
' TOTALES DE LOS ARCHIVOS
s.Close
S = Starter.skmt.ExecQuery2("select SUM(CAT_GP_ALMACEN) AS CAT_GP_ALMACEN from cat_gunaprod2 WHERE CAT_GP_CLASIF <> ? ", Array As String("PROMOS"))
S.Position = 0
a_final =s.GetString("CAT_GP_ALMACEN")
S1.Close
S1 = Starter.skmt.ExecQuery("select SUM(CAT_GP_ALMACEN) AS CAT_GP_ALMACEN from cat_gunaprod5 ")
S1.Position = 0
@@ -3757,6 +3837,7 @@ Sub B_IMP_INV_Click
Printer1.WriteString(Printer1.BOLD & "----RESUMEN TOTAL---- " & CRLF)
'' se cambia por lo del rmi Printer1.WriteString("---" & a_inicial & "..." & ABORDO & "..." & a_total & "..." & a_venta & "..." & a_final & "..." & RMI & CRLF)
Printer1.WriteString("---" & a_inicial & "..." & ABORDO & "..." & a_total & "..." & a_venta & "..." & a_final & "..." & CRLF)
Log("---" & a_inicial & "..." & ABORDO & "..." & a_total & "..." & a_venta & "..." & a_final & "..." & CRLF)
Printer1.WriteString(Printer1.BOLD & "TOTAL VENTA " & Subs.sumaPedido(Subs.traeCliente) & CRLF)
Printer1.WriteString("------------------------------" & CRLF)
Printer1.WriteString("Nombre y Firma" & CRLF)
@@ -3914,6 +3995,7 @@ Sub revisaPromoEspecial As Map
y.Position = 0
nombreProd = y.GetString("nombreProd")
End If
y.Close
Log("El cliente tiene asignada la promo especial.")
Private p As Cursor
p=Starter.skmt.ExecQuery("select count(*) as hayInventario from CAT_GUNAPROD where CAT_GP_ALMACEN > 0 and CAT_GP_ID = " & x.GetString("CPM_PROID"))
@@ -4388,4 +4470,154 @@ Sub revisaExistenciasDOE As Boolean 'ignore
' 1, "LECHE ALL BRAN NUEZ 236ML", "1008027228"
' 1, "LECHE CHOCO MELVIN 236ML", "1008013799"
Return suficiente
End Sub
Private Sub p_transparenciaNoti_Click
End Sub
Private Sub b_notificacion_Click
Private tag As String = Sender.As(Button).Tag
Log("-" & tag & "-")
Private tag1() As String = Regex.Split("\|", tag)
Log(tag1.Length & "-" & tag1(0) & "-" & tag1(1))
Private CODIGO As String = tag1(1)
Private ID As String = tag1(0)
p_transparenciaNoti.Visible = False
DateTime.DateFormat = "yyyy-MM-dd HH:mm:ss"
Starter.skmt.ExecNonQuery($"insert into HIST_NOTIFICACIONES (HN_CODIGO, HN_ID, HN_FECHA) values ('${CODIGO}', '${ID}', '${DateTime.Date(DateTime.Now)}')"$)
Log(123)
cmd.Initialize
cmd.Name = "updateHistNotificacionesMotivo"
cmd.Parameters = Array As Object("", DateTime.Date(DateTime.Now), Subs.traeRuta, usuario, Subs.traeAlmacen, clienteId)
reqManager.ExecuteCommand(cmd , "updateHistNotificacionesMotivo")
End Sub
' Subrutina principal para subir pedidos con validación de integridad ARCH
' Llama a esto desde tu botón Subir_Click
' Devuelve un ResumableSub que puedes esperar con Wait For
Sub Subir_Pedido_Con_Integridad(cliente As String) As ResumableSub
Log("--- Iniciando Envío Seguro para Cliente: " & cliente & " ---")
' 1. Generar ARCH (Identificador Único del Paquete)
Dim Arch As String = Subs.traeAlmacen & "_" & Subs.traeRuta & "_" & cliente & "_" & DateTime.Now
' 2. Marcar registros pendientes con este ARCH localmente
' CORRECCIÓN CRÍTICA: El orden es (Valor_a_Asignar, Filtro) -> (Arch, cliente)
Starter.skmt.ExecNonQuery2($"UPDATE PEDIDO SET PE_ARCH = ? WHERE PE_CLIENTE = ? AND PE_ENVIADO = 0"$, Array As Object(Arch, cliente))
Starter.skmt.ExecNonQuery2($"UPDATE PEDIDO_CLIENTE SET PC_ARCH = ? WHERE PC_CLIENTE = ? AND PC_ENVIADO = 0"$, Array As Object(Arch, cliente))
' 3. Contar qué vamos a enviar
Dim cCheck As Cursor = Starter.skmt.ExecQuery($"SELECT COUNT(*) as total FROM PEDIDO WHERE PE_ARCH = '${Arch}'"$)
cCheck.Position = 0
Dim TotalProductosLocal As Int = cCheck.GetInt("total")
cCheck.Close
If TotalProductosLocal = 0 Then
Log("Nada pendiente para enviar con este ARCH.")
Return "Vacio"
End If
Log($"Total a enviar: ${TotalProductosLocal} productos. ID Paquete: ${Arch}"$)
Dim envioCorrecto As Boolean = True
' 4. Enviar Encabezados (PEDIDO_CLIENTE)
Log("Enviando encabezado con ARCH: " & Arch)
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, PC_ARCH FROM PEDIDO_CLIENTE WHERE PC_ARCH = '${Arch}'"$)
If cx.RowCount > 0 Then
For i = 0 To cx.RowCount - 1
cx.Position = i
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "insert_pedidos_KELL_arch"
cmd.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"), cx.GetString("PC_ALMACEN"), cx.GetString("PC_RUTA"), cx.GetString("PC_COSTO_SIN"), cx.GetString("PC_ARCH"))
Log($"insert_pedidos_KELL_arch: ${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")}, ${cx.GetString("PC_ALMACEN")}, ${cx.GetString("PC_RUTA")}, ${cx.GetString("PC_COSTO_SIN")}, ${cx.GetString("PC_ARCH")}"$)
reqManagerW.ExecuteCommand(Starter.DBReqServer, cmd, Me, "header_envio")
Wait For header_envio_Completed (ResultHeader As TResultado)
If ResultHeader.Success = False Then
Log("Error crítico enviando encabezado: " & ResultHeader.ErrorMessage)
envioCorrecto = False
Exit
End If
Next
cx.Close
End If
If envioCorrecto = False Then
Msgbox("Error al enviar encabezado del pedido. Intente nuevamente.", "Error de Conexión")
Return "Error PC"
End If
' 5. Enviar Detalles (PEDIDO)
Log("Enviando detalle con ARCH: " & Arch)
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_ARCH = '${Arch}'"$)
If cPed.RowCount > 0 Then
For i = 0 To cPed.RowCount - 1
cPed.Position = i
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "insert_pedido_KELL_arch"
cmd.Parameters = Array As Object(cPed.GetString("PE_CEDIS"), Subs.traeAlmacen, 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"), cPed.GetString("PE_ARCH"))
reqManagerW.ExecuteCommand(Starter.DBReqServer, cmd, Me, "detalle_envio")
Wait For detalle_envio_Completed (ResultDet As TResultado)
If ResultDet.Success = False Then
Log("Error enviando producto " & cPed.GetString("PE_PRONOMBRE"))
envioCorrecto = False
Exit
End If
Next
cPed.Close
End If
If envioCorrecto = False Then
Return "Error PE"
End If
' 6. VALIDACIÓN FINAL
Log("Validando integridad con Oracle...")
Dim cmdVal As DBCommand
cmdVal.Initialize
cmdVal.Name = "validar_integridad_arch"
cmdVal.Parameters = Array As Object(Arch, TotalProductosLocal)
reqManagerW.ExecuteQuery(Starter.DBReqServer, cmdVal, Me, "validacion_integridad")
Wait For validacion_integridad_Completed (ResultVal As TResultado)
If ResultVal.Success Then
Dim estado As String = ""
For Each row() As Object In ResultVal.resultado.Rows
estado = row(ResultVal.resultado.Columns.Get("ESTADO"))
Next
If estado = "COMPLETO" Then
Log("¡Validación Exitosa! Marcando pedido como enviado.")
' Marcamos como enviado localmente usando el ARCH
Starter.skmt.ExecNonQuery2("UPDATE PEDIDO SET PE_ENVIADO = 1 WHERE PE_ARCH = ?", Array As Object(Arch))
Starter.skmt.ExecNonQuery2("UPDATE PEDIDO_CLIENTE SET PC_ENVIADO = 1 WHERE PC_ARCH = ?", Array As Object(Arch))
ToastMessageShow("Pedido enviado y verificado correctamente", False)
Return "Validado OK"
Else
Log("ERROR DE INTEGRIDAD: El servidor reporta " & estado)
Msgbox("El servidor recibió datos incompletos. El pedido NO se marcó como enviado. Por favor intente subir de nuevo.", "Error de Integridad")
Return "Error Validacion"
End If
Else
Log("Error al ejecutar query de validación: " & ResultVal.ErrorMessage)
Msgbox("No se pudo verificar el pedido por error de red. Intente de nuevo.", "Error de Red")
Return "Error Validacion (Red)"
End If
End Sub

View File

@@ -101,6 +101,7 @@ Private Sub B4XPage_CloseRequest As ResumableSub
End Sub
Sub ListView1_ItemClick (Position As Int, Value As Object)
Log(Value)
' If Logger Then Log(Regex.Split("\.",Me)(Regex.Split("\.",Me).Length-1))
Private Subrutina As Map =CreateMap("nombre":"ListView1_ItemClick", "param1":Position, "param2":Value)
Starter.sesion = CreateMap("actividad":Me, "sub":Subrutina)

View File

@@ -50,6 +50,7 @@ End Sub
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
Sub B4XPage_Appear
B4XPages.MainPage.aud.guarda("Entrada a Historico")
L_CANT.Text =""
L_TOTAL.Text=""
c=Starter.skmt.ExecQuery("select count(*) as EXISTE from HIST_VENTAS WHERE HVD_CLIENTE IN (Select CUENTA from cuentaa)")

View File

@@ -54,6 +54,7 @@ End Sub
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
Sub B4XPage_Appear
B4XPages.MainPage.aud.guarda("Entrada a Mapas")
GPS.Initialize("GPS")
Log(1)
rp.CheckAndRequest(rp.PERMISSION_ACCESS_FINE_LOCATION)

View File

@@ -46,6 +46,7 @@ End Sub
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
Sub B4XPage_Appear
B4XPages.MainPage.aud.guarda("Entrada a No Venta")
e_comm.Text=""
lat_gps = 0
lon_gps = 0
@@ -86,6 +87,7 @@ Sub GUARDA_Click
Else
motivo = "NO ESTA EL ENCARGADO"
End If
B4XPages.MainPage.aud.guarda($"Guarda No Venta: ${motivo}"$)
usuario = Subs.traeUsuarioDeBD
If B4XPages.MainPage.cliente.IsInitialized Then
B4XPages.MainPage.cliente.motivoNoVenta = motivo

View File

@@ -41,11 +41,13 @@ Sub Class_Globals
Private L_TOTAL_D As Label
Private l_tipoPedido As Label
Dim pedidoMostrado As String = "NORMAL"
Dim ts As C_TrendSpending
End Sub
'You can add more parameters here.
Public Sub Initialize As Object
kh.Initialize(Me, "kh", Starter.skmt)
ts.Initialize(Me, "ts", Starter.skmt)
Return Me
End Sub
@@ -97,6 +99,7 @@ End Sub
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
Sub B4XPage_Appear
B4XPages.MainPage.aud.guarda("Entrada a Nota")
If kh.clienteConDOE And l_tipoPedido.IsInitialized Then
l_tipoPedido.Visible = True
Else
@@ -142,7 +145,7 @@ Sub B4XPage_Appear
C_DOE=Starter.skmt.ExecQuery2("select sum(pe_cant) AS CANTIDAD, sum(pe_costo_tot) AS MONTO from pedido where PE_CEDIS <> PE_PROID and pe_cliente in (Select CUENTA from cuentaa) AND PE_CEDIS = ?", Array As String("DOE"))
C_DOE.Position=0
L_CANT_D.Text = C_DOE.GetString("CANTIDAD")
L_TOTAL_D.Text = numberformat2(kh.traeTotalCliente, 1, 2, 2, True)
L_TOTAL_D.Text = NumberFormat2(kh.traeTotalCliente, 1, 2, 2, True)
c.Close
Else
B_PEDIDO_DOE.VISIBLE = False
@@ -263,6 +266,7 @@ Sub borra_Click
If folio = "0" Or 1 = 1 Then 'Si el folio es 0 o el cliente actual es "abordo", los deja borrar. - Mod por CHV 220512 'Para que el abordo borre siempre agregar -> " Or Subs.clienteActual = "0""
result = Msgbox2($"¿Seguro que desea borrar el pedido${textoExtra}?"$,"Cancelar pedido", "Si", "", "No", LoadBitmap(File.DirAssets,"alert2.png")) 'ignore
If result = DialogResponse.POSITIVE Then
B4XPages.MainPage.aud.guarda($"Borrar Nota Ok"$)
' c = Starter.skmt.ExecQuery("select PE_PROID, PE_CANT, PE_TIPO, PE_CEDIS FROM PEDIDO where pe_cliente in (Select CUENTA from cuentaa) ")
' If c.RowCount>0 Then
' For i=0 To c.RowCount -1
@@ -274,7 +278,11 @@ Sub borra_Click
' Starter.skmt.ExecNonQuery("delete from pedido_cliente where pc_cliente in (Select CUENTA from cuentaa)")
' Starter.skmt.ExecNonQuery("delete from pedido where pe_cliente in (Select CUENTA from cuentaa)")
' Starter.skmt.ExecNonQuery("UPDATE kmt_info set gestion = 0 where CAT_CL_CODIGO In (select cuenta from cuentaa)")
If pedidoMostrado = "DOE" Then Subs.borraPedidoDOEClienteActual Else Subs.borraPedidoClienteActual
If pedidoMostrado = "DOE" Then
Subs.borraPedidoDOEClienteActual
Else
Subs.borraPedidoClienteActual
End If
' B4XPages.MainPage.productos.prodsMap.Initialize 'inicializamos mapa de productos para que no aparezcan como vendidos en la lista
B4XPages.MainPage.promos.promosMap.Initialize
' Log("Llamamos LlenaProdsLL")
@@ -439,11 +447,11 @@ End Sub
Private Sub clv_pedidos_ItemLongClick (position As Int, Value As Object)
Private thisLog As Boolean = False
c = Starter.skmt.ExecQuery("select count(*) as hayImpresos from CLIENTE_IMPRESO where CI_CUENTA in (Select CUENTA from cuentaa)")
c.Position = 0
' c = Starter.skmt.ExecQuery("select count(*) as hayImpresos from CLIENTE_IMPRESO where CI_CUENTA in (Select CUENTA from cuentaa)")
' c.Position = 0
If thisLog Then Log("lista prods="&list_prodsPedido.Get(position))
Private m As Map = list_prodsPedido.Get(position)
If c.GetString("hayImpresos") = 0 Then 'Si la venta no está impresa o es abordo entonces continuamos ... 'Para que el abordo borre siempre " Or Subs.clienteActual = "0""
If kh.revisaImpresa = False Then 'Si la venta no está impresa o es abordo entonces continuamos ... 'Para que el abordo borre siempre " Or Subs.clienteActual = "0""
c=Starter.skmt.ExecQuery2("select count(*) as CUANTOS FROM PEDIDO WHERE PE_CEDIS = ? AND PE_CLIENTE IN (Select CUENTA from cuentaa)", Array As String("DUR"))
c.Position = 0
CAMBIOS = c.GetString("CUANTOS")
@@ -469,12 +477,18 @@ Private Sub clv_pedidos_ItemLongClick (position As Int, Value As Object)
Starter.skmt.ExecNonQuery($"update ${Subs.traeTablaProds(Starter.tipov)} set cat_gp_almacen = cat_gp_almacen + ${pPromos.GetString("PE_CANT")} where cat_gp_id = '${pPromos.Getstring("PE_PROID")}'"$)
Next
Starter.skmt.ExecNonQuery2("delete from pedido where pe_cedis in (select pe_cedis from pedido where PE_CEDIS = ? and pe_pronombre = ?) and pe_cliente in (Select CUENTA from cuentaa)", Array As Object(m.Get("cedis"), Value))
Private precio0 As String = Subs.traePrecio(prod.GetString("PE_PROID"))
Private precioConDesc As String = (B4XPages.MainPage.cliente.kh.traeDescXSku(Subs.traeCliente, prod.GetString("PE_PROID"))/100)*precio0
ts.modTrendSpending("suma", "descuentos", (precioConDesc * prod.GetString("PE_CANT")))
Else
If thisLog Then Log($"SUMAMOS ${m.get("cant")} a ${m.get("prodId")} "$)
'Si no es RMI, actualizamos el inventario.
If prod.GetString("PE_CEDIS") <> "DUR" Then Starter.skmt.ExecNonQuery2($"update ${Subs.traeTablaProds(Starter.tipov)} set cat_gp_almacen = cat_gp_almacen + ? where cat_gp_id = ?"$, Array As Object(m.get("cant"), m.get("prodId")))
If thisLog Then Log($"BORRAMOS ${Value}, ${m.Get("cedis")}"$)
Starter.skmt.ExecNonQuery2("delete from pedido where pe_pronombre = ? and pe_cedis = ? and pe_cant = ? and pe_cliente in (Select CUENTA from cuentaa)", Array As Object(Value, m.Get("cedis"), m.Get("cant")))
Private precio0 As String = Subs.traePrecio(prod.GetString("PE_PROID"))
Private precioConDesc As String = (B4XPages.MainPage.cliente.kh.traeDescXSku(Subs.traeCliente, prod.GetString("PE_PROID"))/100)*precio0
ts.modTrendSpending("suma", "descuentos", (precioConDesc * prod.GetString("PE_CANT")))
End If
prod.Close
DateTime.DateFormat = "MM/dd/yyyy"

View File

@@ -51,6 +51,8 @@ End Sub
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
Sub B4XPage_Appear
B4XPages.MainPage.aud.guarda("Entrada a NuevoCliente")
b_guardar.Visible = False
b_guardar.Enabled = False
permitirCtesNuevos = True
b_guardar.Text = "Sin Ubicación ..."
@@ -61,22 +63,24 @@ Sub B4XPage_Appear
c.Position = 0
maxClientesNuevos = c.GetString("CAT_VA_VALOR")
End If
' Log("MaxClientesNuevos: " & maxClientesNuevos)
Log("MaxClientesNuevos: " & maxClientesNuevos)
'Para el almacen 12 (GDL) no hay limite de clientes nuevos.
If kh.traeAlmacen = 12 Then maxClientesNuevos = 0
' If kh.traeAlmacen = 12 Then maxClientesNuevos = 0
If maxClientesNuevos <> 0 Then
Private d As Cursor = Starter.skmt.ExecQuery($"select count(CAT_CL_CODIGO) as ctesNuevos from kmt_info where CAT_CL_CODIGO like 'N%'"$)
If d.RowCount > 0 Then
d.Position = 0
' Log($"Clientes nuevos actuales: ${d.GetString("ctesNuevos")}"$)
Log($"Clientes nuevos actuales: ${d.GetString("ctesNuevos")}"$)
If d.GetString("ctesNuevos") >= maxClientesNuevos Then
b_guardar.Enabled = False
permitirCtesNuevos = False
ToastMessageShow("¡Ha alcanzado el LIMITE de usuarios nuevos por día!", True)
End If
End If
Else
b_guardar.Visible = True
End If
End Sub
@@ -87,6 +91,7 @@ Sub GPS_LocationChanged (Location1 As Location)
b_guardar.Enabled = False
Else
b_guardar.Enabled = True
b_guardar.Visible = True
End If
b_guardar.Text = "Guardar"
End Sub
@@ -128,7 +133,7 @@ Sub b_guardar_Click
Starter.skmt.ExecNonQuery2("INSERT INTO CUENTAA VALUES (?)", Array As Object(no_cliente))
Subs.iniciaActividad("cliente")
Else
ToastMessageShow("No hay clientes para visitar el día de hoy.", true)
ToastMessageShow("No hay clientes para visitar el día de hoy.", True)
End If
End If
End Sub

File diff suppressed because it is too large Load Diff

View File

@@ -13,10 +13,7 @@ Sub Class_Globals
Dim q_buscar As String
Dim forzarBusqueda As Boolean = False
Dim skmt As SQL
Dim c As Cursor
Dim c2 As Cursor
Dim C3 As Cursor
Dim s As Cursor
Dim ab, c, c2, c3, c_prods, pPromo, p1, prod, pPromos, s, s1 As Cursor
Dim lv_catalogos As ListView
Dim lv_promos As ListView
Dim entro As String
@@ -29,7 +26,6 @@ Sub Class_Globals
Dim ya_entro As String
Dim TIENE_PROMOS As String
Dim RES As String
Dim S1 As Cursor
Dim bmp As Bitmap
Dim ciclo As String
Private b_qr As Button
@@ -113,6 +109,9 @@ End Sub
Public Sub Initialize As Object
kh.Initialize(Me, "kh", Starter.skmt)
ts.Initialize(Me, "ts", Starter.skmt)
Log(TS_RMI)
Log(TS_DESCUENTOS)
Log(TS_BONIFICACIONES)
' promosC.Initialize(Me, "promosC", Starter.skmt)
Return Me
End Sub
@@ -167,6 +166,7 @@ End Sub
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
Sub B4XPage_Appear
B4XPages.MainPage.aud.guarda("Entrada a Productos")
If Starter.Logger Then Log("Entro: " & entro)
' Log($"LIMITE ABORDO: ${limiteAbordo}"$)
' clv_prods_ll.Initialize(Me, "clv_prods_ll")
@@ -240,10 +240,24 @@ Sub B4XPage_Appear
' Log(Starter.tipov)
c = Starter.skmt.ExecQuery("select count(*) as hayPromos from promos_comp")
c.Position = 0
' Log(Subs.revisaImpresa)
If c.GetInt("hayPromos") > 0 And Subs.traeCliente <> 0 And Subs.revisaImpresa = False Then
Private mx As Map = ts.traeInfoTrendSpending
TS_RMI = Regex.Split(",", mx.Get("RMI"))
TS_DESCUENTOS = Regex.Split(",", mx.Get("DESCUENTOS"))
TS_BONIFICACIONES = Regex.Split(",", mx.Get("BONIFICACIONES"))
Dim bonificacionesDisp As String = TS_BONIFICACIONES(0)
Log(">>>>>>>>>>>>> TRADESPENDING: " & mx)
Log("RMI: " & TS_RMI(0) & "|" & TS_RMI(1))
Log("DESCUENTOS: " & TS_DESCUENTOS(0) & "|" & TS_DESCUENTOS(1))
Log("BONIFICACIONES: " & TS_BONIFICACIONES(0) & "|" & TS_BONIFICACIONES(1))
Log("revisaImpresa: " & Subs.revisaImpresa)
Log("bonificacionesDisp: " & bonificacionesDisp)
If bonificacionesDisp = 0 Then ToastMessageShow("¡No hay presupuesto para promociones!", False)
If bonificacionesDisp > 0 And c.GetInt("hayPromos") > 0 And Subs.traeCliente <> 0 And Subs.revisaImpresa = False Then
lv_catalogos.AddSingleLine("PROMOS")
End If
c.Close
Sleep(100)
' l_total.Visible = False
' l_totProds.Visible = False
@@ -286,14 +300,6 @@ Sub B4XPage_Appear
End If
If B4XPages.MainPage.cliente.la_cuenta.text = "0" Then b_rmi.Visible = False
' Log(Starter.tipov)
Private mx As Map = ts.traeInfoTrendSpending
TS_RMI = Regex.Split(",", mx.Get("RMI"))
TS_DESCUENTOS = Regex.Split(",", mx.Get("DESCUENTOS"))
TS_BONIFICACIONES = Regex.Split(",", mx.Get("BONIFICACIONES"))
Log(">>>>>>>>>>>>> TRENDSPENDING: " & mx)
Log("RMI: " & TS_RMI(0) & "|" & TS_RMI(1))
Log("DESCUENTOS: " & TS_DESCUENTOS(0) & "|" & TS_DESCUENTOS(1))
Log("BONIFICACIONES: " & TS_BONIFICACIONES(0) & "|" & TS_BONIFICACIONES(1))
End Sub
Sub PCLV_AddProds
@@ -314,6 +320,7 @@ Sub lv_catalogos_ItemClick (Position As Int, Value As Object)
If hayPedido Then p_botonesVenta.Visible = True 'Si ya hay pedido, entonces mostramos los botones.
l_mDisponible.Visible = False
Else
Log("ENTRAMOS A PROMOS")
clv_prods_ll.AsView.Visible = False
lv_promos.Visible = True
lfila.text = "PROMOCIONES"
@@ -341,26 +348,62 @@ Sub lv_catalogos_ItemClick (Position As Int, Value As Object)
c2 = Starter.skmt.ExecQuery($"select CAT_PA_TIPO_PROMONTO, CAT_PA_PORCENTAJE_PAQUETE, CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_TIPOPROD2, CAT_GP_PRECIO, CAT_GP_ALMACEN, CAT_GP_IMG from ${Subs.traeTablaProds(Starter.tipov)} left join PROMOS_COMP on CAT_GP_ID = CAT_PA_ID where CAT_GP_ALMACEN > 0 AND CAT_GP_TIPO = '${Value}' AND CAT_GP_SUBTIPO = '${Value}' AND CAT_GP_TIPOPROD <> 1 and length(CAT_GP_CODPROMO) = 1 OR CAT_GP_CODPROMO = CAT_GP_ID ORDER BY CAT_GP_TIPOPROD2 DESC, CAT_GP_NOMBRE"$)
Log($"select CAT_PA_TIPO_PROMONTO, CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_TIPOPROD2, CAT_GP_PRECIO, CAT_GP_ALMACEN, CAT_GP_IMG from ${Subs.traeTablaProds(Starter.tipov)} left join PROMOS_COMP on CAT_GP_ID = CAT_PA_ID where CAT_GP_ALMACEN > 0 AND CAT_GP_TIPO = '${Value}' AND CAT_GP_SUBTIPO = '${Value}' AND CAT_GP_TIPOPROD <> 1 and length(CAT_GP_CODPROMO) = 1 OR CAT_GP_CODPROMO = CAT_GP_ID ORDER BY CAT_GP_TIPOPROD2 DESC, CAT_GP_NOMBRE"$)
' Log($"select CAT_PA_TIPO_PROMONTO, CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_TIPOPROD2, CAT_GP_PRECIO, CAT_GP_ALMACEN, 1 as CAT_GP_IMG from ${Subs.traeTablaProds(Starter.tipov)} left join PROMOS_COMP on CAT_GP_ID = CAT_PA_ID where CAT_GP_ALMACEN > 0 AND CAT_GP_TIPO = '${Value}' AND CAT_GP_SUBTIPO = '${Value}' AND CAT_GP_TIPOPROD <> 1 and length(CAT_GP_CODPROMO) = 1 OR CAT_GP_CODPROMO = CAT_GP_ID ORDER BY CAT_GP_TIPOPROD2 DESC, CAT_GP_NOMBRE"$)
' Log($"Resultados : ${c2.RowCount}, ${Value}, ${marca}, ${tipo}"$)
If c2.RowCount > 0 Then
LogColor("=== INICIO DIAGNÓSTICO DE PROMOS ===", Colors.Magenta)
LogColor($"Cliente: ${clienteId} | Total Candidatas en BD: ${c2.RowCount}"$, Colors.Magenta)
Dim MotorNuevo As C_Promociones
MotorNuevo.Initialize(Starter.skmt, ts)
For i=0 To c2.RowCount -1
c2.Position=i
Private tm As Map = Subs.procesaPromocion(c2.GetString("CAT_GP_ID"), clienteId)
' promosC.procesaPromocion(c2.GetString("CAT_GP_ID"), clienteId)
If tm.Get("status") = "ok" Then 'Solo muestrala si hay producto.
Log(c2.GetString("CAT_GP_ID"))
Log(c2.GetString("CAT_PA_TIPO_PROMONTO"))
Log(c2.GetString("CAT_PA_PORCENTAJE_PAQUETE"))
If c2.GetString("CAT_PA_TIPO_PROMONTO") = "0" Then ' Si NO es promo por monto entonces la mostamos.
Dim idPromo As String = c2.GetString("CAT_GP_ID")
Log($"[${i}] Revisando ID: ${idPromo} (${c2.GetString("CAT_GP_NOMBRE")})"$)
' --- 1. DIAGNÓSTICO MAPAS (VIEJO) ---
Dim tm As Map = Subs.procesaPromocion(idPromo, clienteId)
Dim statusViejo As String = tm.Get("status")
Dim maxViejo As Int = Subs.revisaMaxPromosProdsFijosPorInventario(tm.Get("mp"))
If statusViejo <> "ok" Then
LogColor($" >> MAPA rechaza: Status='${statusViejo}'"$, Colors.Red)
Else
LogColor($" >> MAPA acepta: MaxFijos=${maxViejo}"$, Colors.Green)
End If
' --- 2. DIAGNÓSTICO TYPES (NUEVO) ---
Try
Dim tPromo As TPromoLegacy = MotorNuevo.TraePromo(idPromo, clienteId)
Dim maxNuevo As Int = MotorNuevo.RevisaMaxPromosProdsFijos(tPromo)
Log($" >> TYPE Info Interna: Res='${tPromo.Resultado}', Msg='${tPromo.MensajeError}'"$)
Log($" >> TYPE Listas: Fijos=${tPromo.ProdsFijos.Size}, Vars=${tPromo.ProdsVariables.Size}"$)
If tPromo.Resultado = "ok" And maxNuevo > 0 Then
LogColor($" >> TYPE acepta: MaxFijos=${maxNuevo}"$, Colors.Green)
Else
LogColor($" >> TYPE rechaza: Resultado='${tPromo.Resultado}' | MaxCalculado=${maxNuevo}"$, Colors.Red)
End If
Catch
LogColor(" >> CRASH en Nuevo: " & LastException.Message, Colors.Red)
End Try
Log("-") ' Separador
' --- 3. CODIGO VISUAL ORIGINAL ---
If tm.Get("status") = "ok" Then
If c2.GetString("CAT_PA_TIPO_PROMONTO") = "0" Then
lv_promos.AddTwoLines(c2.GetString("CAT_GP_NOMBRE"),"# " & c2.GetString("CAT_GP_ALMACEN") & " $ " & c2.GetString("CAT_GP_PRECIO") & " F:" & tm.Get("mp").As(Map).Get("prodsFijosCant") & " V:" & tm.Get("mp").As(Map).Get("prodsVariablesCant"))
End If
End If
Next
LogColor("=== FIN DIAGNÓSTICO ===", Colors.Magenta)
Else
ToastMessageShow("No hay promociones disponibles.", False)
ToastMessageShow("No hay promociones en la consulta inicial.", False)
End If
c2.Close
entro = "4"
@@ -491,6 +534,11 @@ Sub llenaCatalogo(subtipo1 As String)
End Sub
Private Sub B4XPage_CloseRequest As ResumableSub
If c.IsInitialized Then c.Close
If c2.IsInitialized Then c2.Close
If c3.IsInitialized Then c3.Close
If s.IsInitialized Then s.Close
If s1.IsInitialized Then s1.Close
' BACK key pressed
' Return True To close, False To cancel
If p_rmi.Visible Then p_rmi.Visible = False
@@ -603,7 +651,7 @@ Sub b_prodMenos_Click
Private id As String=clv_prods_ll.GetValue(index).As(Map).Get("id")
' Private tmpMap As Map = CreateMap("precio":precio, "cant":laCant.Text, "almacen":Subs.traeAlmacen)
Log(clv_prods_ll.GetValue(index).As(Map))
' ######## Trend Spending - Poner estas lineas antes de que si es negativo se ponga en CERO.
' Private laBonificacion As String = kh.traePrecio(id)*(kh.traeDescXSku(clienteId, id)/100)
' If laBonificacion > 0 Then
@@ -619,7 +667,7 @@ Sub b_prodMenos_Click
' Subs.modTrendSpending("suma", "bonificaciones", laBonificacion)
' End If
' #######################
' ######## Trend Spending - Poner estas lineas antes de que si es negativo se ponga en CERO.
If lfila.Text = "PRODUCTOS" Then
Log(">>>>>>>>>> PRODUCTOS <<<<<<<<<<<<<<")
@@ -628,7 +676,7 @@ Sub b_prodMenos_Click
ts.trendSpending("prodMenos", "rmi", clienteId, id, laCant.Text, 0)
End If
' #######################
If laCant.Text < 0 Then laCant.Text = 0
' Log(tmpMap)
' prodsMap.Put(id, tmpMap)
@@ -657,6 +705,7 @@ Sub b_prodMenos_Click
invActualizado = i.GetString("CAT_GP_ALMACEN")
End If
If Starter.tipov <> "ABORDO" Then lProdX.Text = cs.Color(Colors.red).append(nombreX).pop.append(CRLF).Append("Existencias: " & invActualizado).Color(0xFF017F01).Append($" $${NumberFormat2(precio, 1, 2, 2, False)}"$).Popall
i.Close
End If
If kh.totalPedido < 1 Then laCant.Text = "0"
' Log($"Total Prods: ${totalProds}, Total Compra: $$1.2{totalCompra}"$)
@@ -686,7 +735,7 @@ Sub b_prodMas_Click
' Private inv As Int = clv_prods_ll.GetValue(index).As(Map).Get("almacen")
' Log($"Existencias: ${inv}, inv: ${Subs.traeinventario(pnl.GetView(1).Tag)}"$)
Private inv As Int = Subs.traeinventario(pnl.GetView(1).Tag)
Log($"inv: ${Subs.traeinventario(pnl.GetView(1).Tag)}"$)
' Log($"inv: ${Subs.traeinventario(pnl.GetView(1).Tag)}"$)
Private id As String=clv_prods_ll.GetValue(index).As(Map).Get("id")
Private almacenX As String = Subs.traeAlmacen
Private nombreX As String = Subs.traeProdNombre(id)
@@ -713,18 +762,19 @@ Sub b_prodMas_Click
' Subs.modTrendSpending("resta", "bonificaciones", laBonificacion)
' Log(Subs.traeAcumuladoHoyTS("bonificaciones"))
' End If
' Log("BONIFCACIONES RESTANTES: " & (TS_BONIFICACIONES(0) - TS_BONIFICACIONES(1) - Subs.traeAcumuladoHoyTS("bonificaciones")))
Log("BONIFCACIONES RESTANTES: " & (TS_BONIFICACIONES(0) - TS_BONIFICACIONES(1) - ts.traeAcumuladoHoyTS("bonificaciones")))
Private tsMonto As String = 0
Private tsMaximas As Int = 0
If lfila.Text = "PRODUCTOS" Then
Log(">>>>>>>>>> PRODUCTOS <<<<<<<<<<<<<<")
Log($"${TS_DESCUENTOS(0)} - ${TS_DESCUENTOS(1)} - ${ts.traeAcumuladoHoyTS("descuentos")}"$)
Private tsRestantes As String = (TS_DESCUENTOS(0) - TS_DESCUENTOS(1) - ts.traeAcumuladoHoyTS("descuentos")) ' Traemos monto restante de Trend Spending para bonificaciones.
tsMonto = NumberFormat2(ts.traePrecio(id)*(ts.traeDescXSku(clienteId, id)/100), 1, 2, 2, False) ' Traemos el monto (descuento total) del producto actual.
tsMaximas = ((laCant.text * tsMonto) + tsRestantes) / tsMonto ' Traemos la cantidad maxima de descuentos por presupuesto de Trend Spending.
Log("tsRestantes: " & tsRestantes)
' Log("tsRestantes: " & tsRestantes)
' Log("tsMonto: " & tsMonto)
Log("tsMaximas: " & tsMaximas)
Log("tsMaximas2: " & ts.traeMaximas("descuentos", clienteId, id, laCant.Text, ""))
' Log("tsMaximas2: " & ts.traeMaximas("descuentos", clienteId, id, laCant.Text, ""))
' Log("tsMonto2: " & ts.traeMonto(clienteId, id))
Else if lfila.Text = "RMI" Then
Log(">>>>>>>>>> RMI <<<<<<<<<<<<<<")
@@ -748,13 +798,16 @@ Sub b_prodMas_Click
' Log(inv > 0)
' Log(tsMonto.As(Int) = 0)
If laCant.Text + 1 > tsMaximas Then 'lfila.Text = "PRODUCTOS" and
ToastMessageShow("¡Presupuesto de descuentos alcanzado!", False)
End If
If 1 = 2 And buttonTag = "vendido" And lfila.Text = "PRODUCTOS" Then
' Log(11)
' Log("VENDIDO")
Log($"${(laCant.Text + 1 <= inv)} And ${(kh.totalPedido - precio > 1)}"$)
' If inv > 0 And (laCant.Text + 1 <= (laCant.Text + existencias)) And (kh.totalPedido - precio > 1) Then
If inv > 0 And (kh.totalPedido - precio > 1) Then
Log(2)
' Log(2)
' Log(clv_prods_ll.GetValue(index).As(Map))
clv_prods_ll.GetValue(index).As(Map).Put("almacen", (inv - 1))
inv = inv - 1
@@ -788,7 +841,8 @@ Sub b_prodMas_Click
' Log(77)
laCant.Text = "0"
End If
' Log(99)
Log(99)
If lfila.Text = "RMI" Then
almacenX = "DUR"
nombreX = "CAMBIO"&Subs.traeRMINombre(id)
@@ -836,6 +890,7 @@ Sub b_prodMas_Click
invActualizado = i.GetString("CAT_GP_ALMACEN")
End If
If Starter.tipov <> "ABORDO" Then lProdX.Text = cs.Color(Colors.red).append(nombreX).pop.append(CRLF).Append("Existencias: " & invActualizado).Color(0xFF017F01).Append($" $${NumberFormat2(precio, 1, 2, 2, False)}"$).Popall
i.Close
End If
Log($"Total Prods: ${totalProds}, Total Compra: $$1.2{totalCompra}"$)
Sleep(300)
@@ -1108,6 +1163,7 @@ Sub b_terminar1_Click
If Subs.revisaImpresa Then b_rechazar.Visible = False Else b_rechazar.Visible = True
p_vistaPrevia.Visible=True
p_vistaPreviaTrans.Visible=True
Subs.RecalcularInventario
End Sub
Private Sub b_continuar_Click
@@ -1136,6 +1192,7 @@ Private Sub b_continuar_Click
montoPedidoActual = m.Get("monto")
' LlenaProdsLL(Null)
' BUSCA.Text = " "
Subs.RecalcularInventario
End Sub
Private Sub l_info_Click
@@ -1145,13 +1202,14 @@ End Sub
Private Sub lv_promos_ItemLongClick (Position As Int, Value As Object)
Log("Promo longclic = "&Value)
Private id As String = ""
Dim c As Cursor = Starter.skmt.ExecQuery($"select CAT_GP_ID from cat_gunaprod where CAT_GP_TIPO = 'PROMOS' and CAT_GP_NOMBRE = '${Value}'"$)
Dim c As Cursor = Starter.skmt.ExecQuery($"select CAT_GP_ID from ${Subs.traeTablaProds(Starter.tipov)} where CAT_GP_TIPO = 'PROMOS' and CAT_GP_NOMBRE = '${Value}'"$)
If c.RowCount > 0 Then
c.Position = 0
id = c.GetString("CAT_GP_ID")
End If
l_info.Text = $"ID: ${id}${CRLF}${Value}"$
l_info.Visible = True
c.Close
End Sub
Private Sub b_buscar_Click
@@ -1232,6 +1290,7 @@ Private Sub b_aceptar_Click
' LogColor(p.GetString("total"), Colors.red)
If p.GetString("total") < 1 Then LlenaProdsLL(Null, Null)
p_vistaPreviaTrans.Visible=False
p.Close
Subs.iniciaActividad("Cliente")
' B4XPages.ShowPage("Cliente")
End Sub
@@ -1329,6 +1388,7 @@ Sub l_prodX_Click
Log(Sender.as(Label).tag)
l_info.BringToFront
l_info.Visible = True
i.Close
' Dim index As Int = clv_prods_ll.GetItemFromView(Sender)
' Private p0 As B4XView = clv_prods_ll.GetPanel(index)
' Private p As B4XView = p0.GetView(0)
@@ -1401,6 +1461,7 @@ Private Sub clv_prods_ll_VisibleRangeChanged (FirstIndex As Int, LastIndex As In
prioridad = p1.GetInt("CAT_GP_TIPOPROD2")
' Log(prioridad)
End If
p1.Close
' Log("NIVEL: " & lfila.Text)
If lfila.Text = "RMI" Then ' Si es RMI, la cantidad solo se puede cambiar con los botones.
et_pCant.Enabled = False
@@ -1429,7 +1490,15 @@ Private Sub clv_prods_ll_VisibleRangeChanged (FirstIndex As Int, LastIndex As In
Else
l_prodX.Text = cs.Color(Colors.red).append(clv_prods_ll.GetValue(i).As(Map).Get("prod")).pop.append(CRLF).Append("Almacen: " & clv_prods_ll.GetValue(i).As(Map).Get("almacen")).color(Colors.RGB(48,99,192)).Append(" Abordo: " & clv_prods_ll.GetValue(i).As(Map).Get("abordo")).Color(0xFF017F01).Append($" $${NumberFormat2(precio,1,2,2,False)}"$).Popall
End If
'#######################################################
If clv_prods_ll.GetValue(i).As(Map).Get("almacen").As(Int) = Subs.traeExistenciasPorId(clv_prods_ll.GetValue(i).As(Map).Get("id")) Then
' Log("|"&clv_prods_ll.GetValue(i).As(Map).Get("almacen") & "|" & Subs.traeExistenciasPorId(clv_prods_ll.GetValue(i).As(Map).Get("id"))&"|")
Else
' LogColor("|"&clv_prods_ll.GetValue(i).As(Map).Get("almacen") & "|" & Subs.traeExistenciasPorId(clv_prods_ll.GetValue(i).As(Map).Get("id"))&"|"&clv_prods_ll.GetValue(i).As(Map).Get("prod")&"|", Colors.red)
' LogColor("#### ERROR DE INVENTARIO ####" , Colors.red)
End If
'#######################################################
l_prodX.Tag = clv_prods_ll.GetValue(i).As(Map).Get("id")
l_pCant.Tag = clv_prods_ll.GetValue(i).As(Map).Get("id")
End If
@@ -1482,7 +1551,11 @@ Sub Busca_TextChanged (Old As String, New As String)
listaProds.Initialize
listaHints.Initialize
Sleep(0)
Dim p As ResultSet = Starter.skmt.ExecQuery($"select CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_GP_PRECIO, CAT_GP_TIPO, CAT_GP_TIPOPROD from ${Subs.traeTablaProds(Starter.tipov)} where CAT_GP_NOMBRE like '%${New}%' and CAT_GP_PRECIO > 0 AND CAT_GP_ALMACEN > 0 and CAT_GP_CLASIF <> 'PROMOS' and CAT_GP_PROMOCION <> '1' order by CAT_GP_NOMBRE"$)
If clienteId = "0" Then
Dim p As ResultSet = Starter.skmt.ExecQuery($"select CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_GP_PRECIO, CAT_GP_TIPO, CAT_GP_TIPOPROD from ${Subs.traeTablaProds(Starter.tipov)} where CAT_GP_NOMBRE like '%${New}%' and CAT_GP_PRECIO > 0 And CAT_GP_CLASIF <> 'PROMOS' ORDER BY CAT_GP_TIPOPROD2 DESC, CAT_GP_NOMBRE"$)
Else
Dim p As ResultSet = Starter.skmt.ExecQuery($"select CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_GP_PRECIO, CAT_GP_TIPO, CAT_GP_TIPOPROD from ${Subs.traeTablaProds(Starter.tipov)} where CAT_GP_NOMBRE like '%${New}%' and CAT_GP_PRECIO > 0 And CAT_GP_CLASIF <> 'PROMOS' and CAT_GP_PROMOCION <> '1' ORDER BY CAT_GP_TIPOPROD2 DESC, CAT_GP_NOMBRE"$)
End If
' c2 = Starter.skmt.ExecQuery2("select CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_PRECIO, CAT_GP_ALMACEN, CAT_GP_IMG from " & query & " where CAT_GP_ALMACEN > 0 AND CAT_GP_TIPO = ? AND CAT_GP_SUBTIPO =? AND CAT_GP_TIPOPROD <> 1 and (length(CAT_GP_CODPROMO) = 1 OR CAT_GP_CODPROMO = CAT_GP_ID) ", Array As String( Value, Value)
Log("Llamamos LlenaProdsLL")
LlenaProdsLL(p, Null)
@@ -1510,14 +1583,18 @@ Sub LlenaProdsLL(p As ResultSet, extra As String)
' Log("CANTSMAP: " & cantsMap)
pe.Close
End If
' Log(p.IsInitialized)
Log(p.IsInitialized)
' If query = "" Or query = Null Then query = "cat_gunaprod2"
If p.IsInitialized Then
Log($"YA HAY RESULTSET ${p.RowCount}"$)
Log($"RECIBIMOS RESULTSET ${p.RowCount}"$)
Else
' Log("NO HAY RESULTSET")
Dim p As ResultSet = Starter.skmt.ExecQuery($"select CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_GP_PRECIO, CAT_GP_TIPO, CAT_GP_TIPOPROD from ${Subs.traeTablaProds(Starter.tipov)} where CAT_GP_PRECIO > 0 And CAT_GP_CLASIF <> 'PROMOS' and CAT_GP_PROMOCION <> '1' ORDER BY CAT_GP_TIPOPROD2 DESC, CAT_GP_NOMBRE"$)
If Starter.Logger Then Log($"select CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_GP_PRECIO, CAT_GP_TIPO, CAT_GP_TIPOPROD from ${Subs.traeTablaProds(Starter.tipov)} where CAT_GP_PRECIO > 0 And CAT_GP_CLASIF <> 'PROMOS' and CAT_GP_PROMOCION <> '1' ORDER BY CAT_GP_TIPOPROD2 DESC, CAT_GP_NOMBRE"$)
If clienteId = "0" Then
Dim p As ResultSet = Starter.skmt.ExecQuery($"select CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_GP_PRECIO, CAT_GP_TIPO, CAT_GP_TIPOPROD from ${Subs.traeTablaProds(Starter.tipov)} where CAT_GP_PRECIO > 0 And CAT_GP_CLASIF <> 'PROMOS' ORDER BY CAT_GP_TIPOPROD2 DESC, CAT_GP_NOMBRE"$)
Else
Dim p As ResultSet = Starter.skmt.ExecQuery($"select CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_GP_PRECIO, CAT_GP_TIPO, CAT_GP_TIPOPROD from ${Subs.traeTablaProds(Starter.tipov)} where CAT_GP_PRECIO > 0 And CAT_GP_CLASIF <> 'PROMOS' and CAT_GP_PROMOCION <> '1' ORDER BY CAT_GP_TIPOPROD2 DESC, CAT_GP_NOMBRE"$)
End If
' If Starter.Logger Then Log($"select CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_GP_PRECIO, CAT_GP_TIPO, CAT_GP_TIPOPROD from ${Subs.traeTablaProds(Starter.tipov)} where CAT_GP_PRECIO > 0 And CAT_GP_CLASIF <> 'PROMOS' and CAT_GP_PROMOCION <> '1' ORDER BY CAT_GP_TIPOPROD2 DESC, CAT_GP_NOMBRE"$)
' Log(p.RowCount & " - " & Subs.traeTablaProds(Starter.tipov))
End If
@@ -1533,6 +1610,7 @@ Sub LlenaProdsLL(p As ResultSet, extra As String)
invAbordo = ab.GetString("CAT_GP_ALMACEN")
' Log(invAbordo)
End If
ab.Close
End If
Private precio As String = NumberFormat2(p.GetDouble("CAT_GP_PRECIO"),1,2,2,False)
'Descuentos de condiciones comerciales por TIPO
@@ -1556,7 +1634,7 @@ Sub LlenaProdsLL(p As ResultSet, extra As String)
listaProdsConCant.Initialize
listaProdsConCantIndex.Initialize
listaHints.Initialize
Log(listaProds)
' Log(listaProds)
For q = 0 To listaProds.Size - 1' Sacamos los productos con cantidad previa.
If listaProds.Get(q).As(Map).Get("cant").As(Int) <> 0 Then
' Log(listaProds.Get(q).As(Map).Get("cant"))

File diff suppressed because it is too large Load Diff

379
B4A/C_Promociones.bas Normal file
View File

@@ -0,0 +1,379 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=12.8
@EndOfDesignText@
'Class module: C_Promociones
Sub Class_Globals
Private sql As SQL
' Referencia a tu clase de Trade Spending (ajusta el tipo si se llama diferente)
Private ts As Object ' Lo dejo como Object para que no te marque error si no has copiado esa clase aun
' Variable local para el cliente actual (para no depender de Subs.traeCliente)
Private mClienteActual As String
End Sub
' Inicializa la clase.
' db: La conexión SQL (Starter.skmt)
' tradeSpending: La instancia de tu clase de TradeSpending (B4XPages.MainPage.promos.ts)
Public Sub Initialize(db As SQL, tradeSpendingInstance As Object)
sql = db
ts = tradeSpendingInstance
End Sub
' =============================================================================
' CONTROLADOR PRINCIPAL: ORQUESTADOR DE VALIDACIONES
' =============================================================================
Public Sub procesaPromocion(idPromo As String, cliente As String) As Map
Private thisLog As Boolean = True 'Si es verdadero, muestra los logs de este sub.
Private inicioContador As String = DateTime.Now
Private mp As Int = 0
If thisLog Then LogColor($"****************************************************************"$, Colors.RGB(142,0,255))
If thisLog Then LogColor($"********* Iniciamos revision de Promo ${idPromo} *********"$, Colors.RGB(142,0,255))
If thisLog Then LogColor($"****************************************************************"$, Colors.RGB(142,0,255))
Try
Private pm As TPromoLegacy = TraePromo(idPromo, cliente)
If thisLog Then LogColor(pm, Colors.Blue)
Private maxPromosXprodsFijos As Int = RevisaMaxPromosProdsFijos(pm)
If maxPromosXprodsFijos < 1 Then pm.Resultado = "0"
If thisLog Then LogColor($"***********************************************************************"$, Colors.Blue)
LogColor($"*** PROMOS DISPONIBLES X PRODS FIJOS (${idPromo}) = ${maxPromosXprodsFijos} ***"$, Colors.Blue)
If thisLog Then LogColor($"***********************************************************************"$, Colors.Blue)
If pm.Resultado = "ok" Then 'Si encontramos la promoción, entonces ...
mp = TraeMaxPromos(pm)
If mp < 1 Then
If thisLog Then LogColor("Ya se vendieron las promos PERMITIDAS para el cliente", Colors.red)
Return CreateMap("status":"ko", "mp":pm)
End If
Private inventarioSinFijos As Map = restaFijosPromo(pm)
If thisLog Then LogColor("inventariosfijos="&inventarioSinFijos, Colors.Magenta)
If inventarioSinFijos.Get("resultado") = "ok" Then
Private pv As Boolean = alcanzanLosVariablesParaPromo(pm, inventarioSinFijos)
If thisLog Then LogColor($"****************************************************"$, Colors.Blue)
If thisLog Then LogColor($"***** ¿ALCANZAN LOS VARIABLES? ==> ${IIf(pv, "SI", "NO")} *****"$, Colors.Blue)
If thisLog Then LogColor($"****************************************************"$, Colors.Blue)
If pv Then Return CreateMap("status":"ok", "mp":pm) Else Return CreateMap("status":"ko", "mp":pm)
Else
If thisLog Then LogColor("NO HAY INVENTARIO SUFICIENTE " & idPromo, Colors.red)
Return CreateMap("status":"ko", "mp":pm)
End If
Else
Return CreateMap("status":"ko", "mp":pm)
End If
LogColor("TIEMPO DE PROCESO ESTA PROMO: " & ((DateTime.Now-inicioContador)/1000), Colors.Red)
Catch
Log($"Promo ${idPromo} mal configurada"$)
ToastMessageShow($"Promo ${idPromo} mal configurada"$, True)
Log(LastException)
Return CreateMap("status":"ko", "mp":Null)
End Try
End Sub
' =============================================================================
' RUTINA PRINCIPAL: ARMA LA ESTRUCTURA (Clon de Subs.traePromo)
' =============================================================================
Public Sub TraePromo(promo As String, cliente As String) As TPromoLegacy
mClienteActual = cliente ' Guardamos el cliente para uso interno
Dim t As TPromoLegacy
t.Initialize
' Inicialización de Listas y Mapas (CRÍTICO para evitar Nulls)
t.ProdsFijos.Initialize
t.ProdsFijosPiezas.Initialize
t.ProdsFijosPrecios.Initialize
t.ProdsVariables.Initialize
t.ProdsVariablesPrecios.Initialize
t.Productos.Initialize
t.Tipos.Initialize
t.Id = promo
t.MaxXCliente = 0
t.MaxRecurrente = 0
t.MaxPromos = 0
' --- 1. LECTURA GENERAL ---
Dim c As Cursor = sql.ExecQuery("Select * from promos_comp where cat_pa_id = '"& promo&"'")
If c.RowCount > 0 Then
c.Position = 0
t.MaxXCliente = c.GetString("CAT_PA_MAXPROMCLIE")
t.MaxRecurrente = c.GetString("CAT_PA_MAXPROMREC")
t.MaxPromos = c.GetString("CAT_PA_MAXPROM")
End If
c.Close
' --- 2. SEGMENTACIÓN ---
Dim ps As Cursor = sql.ExecQuery($"select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}'"$)
If ps.RowCount > 0 Then
' Es segmentada -> Bloqueamos por defecto
t.MaxXCliente = "0"
t.MaxRecurrente = "0"
t.MaxPromos = "0"
Dim ps2 As Cursor = sql.ExecQuery($"Select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${cliente}' and HCCP_CANT > HCCP_CANT_VENDIDA"$)
If ps2.RowCount > 0 Then
ps2.Position = 0
t.MaxXCliente = (ps2.GetInt("HCCP_CANT") - ps2.GetInt("HCCP_CANT_VENDIDA"))
t.MaxRecurrente = ps2.GetString("HCCP_CANT")
t.MaxPromos = ps2.GetString("HCCP_CANT")
End If
ps2.Close
End If
ps.Close
' --- 3. HISTÓRICO ---
Dim siHistorico As String = "0"
c = sql.ExecQuery("Select count(*) as hist from HIST_PROMOS where HP_CLIENTE = '"& cliente & "' and HP_CODIGO_PROMOCION = '" & promo & "'")
c.Position = 0
If c.GetInt("hist") > 0 Then siHistorico = "1"
t.Historico = siHistorico
c.Close
' --- 4. DETALLES Y PRODUCTOS ---
c = sql.ExecQuery("Select * from CAT_DETALLES_PAQ where CAT_DP_ID = '"& promo & "'")
If c.RowCount > 0 Then
t.Resultado = "ok"
For i = 0 To c.RowCount -1
c.Position = i
Dim idProd As String = c.GetString("CAT_DP_IDPROD")
' Llenamos el mapa de productos (igual que el original para compatibilidad)
t.Productos.Put(idProd, CreateMap("idProducto":idProd, "precioSimptos":c.GetString("CAT_DP_PRECIO_SIMPTOS"), "precio":c.GetString("CAT_DP_PRECIO"), "tipo":c.GetString("CAT_DP_TIPO"), "piezas":c.GetString("CAT_DP_PZAS"), "regalo":c.GetString("CAT_DP_REGALO"), "clasif":c.GetString("CAT_DP_CLASIF")))
t.Tipos.Put(idProd, c.GetString("CAT_DP_TIPO"))
If c.GetString("CAT_DP_TIPO") = "0" Then
t.ProdsFijos.Add(idProd)
t.ProdsFijosPrecios.Add(c.GetString("CAT_DP_PRECIO"))
t.ProdsFijosPiezas.Add(c.GetString("CAT_DP_PZAS"))
End If
If c.GetString("CAT_DP_TIPO") = "1" Then
t.ProdsVariables.Add(idProd)
t.ProdsVariablesPrecios.Add(c.GetString("CAT_DP_PRECIO"))
End If
Next
Else
t.Resultado = "No hay datos de la promoción."
t.MensajeError = "Sin detalles"
End If
c.Close
' --- 5. VARIABLES REQUERIDAS ---
c = sql.ExecQuery("Select CAT_GP_STS, CAT_GP_NOMBRE from CAT_GUNAPROD2 where CAT_GP_ID = '"& promo & "'")
If c.RowCount > 0 Then
c.Position = 0
t.ProdsVariablesRequeridos = c.GetInt("CAT_GP_STS")
t.Descripcion = c.GetString("CAT_GP_NOMBRE")
Else
t.ProdsVariablesRequeridos = 0
End If
c.Close
Return t
End Sub
' =============================================================================
' LÓGICA DE CÁLCULO 1: FIJOS (Clon de Subs.revisaMaxPromosProdsFijosPorInventario)
' =============================================================================
Public Sub RevisaMaxPromosProdsFijos(pm As TPromoLegacy) As Int
Dim tLista As List
tLista.Initialize
' 1. Agregamos el máximo configurado
tLista.Add(TraeMaxPromos(pm))
' 2. Obtenemos inventario real
Dim invDispParaPromo As Map = TraemosInventarioDisponibleParaPromo(pm.Id)
Dim prodsFijosPiezas As List = pm.ProdsFijosPiezas
Dim idProdsFijos As List = pm.ProdsFijos
Dim idProdsFijosPrecios As List = pm.ProdsFijosPrecios
' 3. Iteramos sobre los fijos
For p = 0 To idProdsFijos.Size -1
Dim thisInvDisp As Int = 0
If invDispParaPromo.Get(idProdsFijos.Get(p)) <> Null Then
thisInvDisp = invDispParaPromo.Get(idProdsFijos.Get(p))
End If
Dim pzasReq As Int = prodsFijosPiezas.Get(p)
If pzasReq > 0 Then
Dim division As Double = thisInvDisp / pzasReq
Dim x() As String = Regex.Split("\.", $"${division}"$)
tLista.Add(x(0).As(Int))
' --- AQUI ESTA TU CAMBIO (DIRECTO Y SIN DOLOR) ---
' Nota: Cambié pm.Get("id") por pm.Id porque ahora es un Type
Dim maxTS As Int = B4XPages.MainPage.promos.ts.traeBonificacionesMaximas("bonificaciones", mClienteActual, idProdsFijos.Get(p), pzasReq, idProdsFijosPrecios.Get(p), pm.Id)
tLista.Add(maxTS)
' -------------------------------------------------
Else
Log($"Promo ${pm.Id} mal configurada (0 piezas requeridas en producto fijo)"$)
ToastMessageShow($"Promo ${pm.Id} mal configurada"$, True)
tLista.Add(0)
End If
Next
tLista.Sort(True)
Return tLista.Get(0)
End Sub
' =============================================================================
' LÓGICA DE CÁLCULO 2: MÁXIMOS (Clon de Subs.traeMaxPromos)
' =============================================================================
Public Sub TraeMaxPromos(pm As TPromoLegacy) As Int
Dim maxPromos As List
maxPromos.Initialize
' A. Histórico del Cliente (HCCP)
Dim hccp As Cursor = sql.ExecQuery($"select HCCP_CANT from HIST_CLIENTE_CANT_PROMOS where HCCP_CLIENTE = '${mClienteActual}' and HCCP_PROMO = '${pm.Id}'"$)
If hccp.RowCount > 0 Then
hccp.Position = 0
maxPromos.Add(hccp.GetInt("HCCP_CANT"))
End If
hccp.Close
' B. Trade Spending Variables
If ts <> Null Then
Dim maxPromosXDescPV As String = B4XPages.MainPage.promos.ts.maxPromosPorProdsVariables(pm.ProdsVariables, pm.Id)
maxPromos.Add(maxPromosXDescPV.As(Int))
End If
' C. Límites Generales
If pm.Historico = "1" And pm.MaxRecurrente <> "null" Then maxPromos.Add(pm.MaxRecurrente.As(Int))
If pm.MaxPromos <> "null" Then maxPromos.Add(pm.MaxPromos.As(Int))
If pm.MaxXCliente <> "null" Then maxPromos.Add(pm.MaxXCliente.As(Int))
maxPromos.Sort(True)
Dim mp As Int = 0
If maxPromos.Size > 0 Then
Dim mp0 As Int = maxPromos.Get(0)
' Restamos lo ya vendido
mp = mp0 - TraePromosVendidas(pm.Id, mClienteActual)
End If
Return mp
End Sub
' =============================================================================
' LÓGICA DE CÁLCULO 3: RESTA INVENTARIO FIJO (Clon de Subs.restaFijosPromo)
' =============================================================================
Public Sub restaFijosPromo(pm As TPromoLegacy) As Map
Private thisLog As Boolean = False 'Si es verdadero, muestra los logs de este sub.
Private inventariosDisponiblesParaEstaPromo As Map = TraemosInventarioDisponibleParaPromo(pm.Id) 'Obtenemos un mapa con el inventario disponible para cada producto de la promocion desde la base de datos.
If thisLog Then LogColor(inventariosDisponiblesParaEstaPromo, Colors.red)
If thisLog Then LogColor("Inventario inicial antes de FIJOS: "&inventariosDisponiblesParaEstaPromo, Colors.Gray) 'Inventario inicial.
Private i As Int
Private prodsmap As Map = pm.productos 'Obtenemos un mapa con todos los productos de la promoción.
Private prodsFijos As List = pm.ProdsFijos 'Obtenemos una lista con los productos fijos de la promoción.
If thisLog Then LogColor("ProdsFijos -> " & prodsFijos, Colors.red)
inventariosDisponiblesParaEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.") 'Valor por default
If thisLog Then Log($"Prods fijos requeridos ${prodsFijos.Size}"$)
If prodsFijos.Size = 0 Then inventariosDisponiblesParaEstaPromo.Put("resultado", "ok") 'Si no lleva prods fijos la promo, entonces ponemos FIJOS OK.
For p = 0 To prodsFijos.Size - 1
Private t As String = prodsFijos.Get(p) 'Obtenemos el Id de este producto desde la lista de productos fijos.
Private p2 As Map = prodsmap.Get(t) 'Obtenemos un mapa con los datos de este producto (id, precio, almacen, tipo, piezas, etc.)
If thisLog Then Log($"T: ${t}, prod ${p2.Get("idProducto")}, piezas: ${p2.Get("piezas")}"$) 'Producto y piezas requeridas
If thisLog Then Log("inventariosDisponiblesParaEstaPromo="&inventariosDisponiblesParaEstaPromo)
If inventariosDisponiblesParaEstaPromo.ContainsKey(t) Then 'Si el mapa del inventario contiene el id del producto entonces ...
i = inventariosDisponiblesParaEstaPromo.get(t) 'Obtenemos del mapa el inventario de este producto.
Private nuevoInv As Int = NumberFormat2((i - pm.ProdsFijosPiezas.Get(p)), 1, 0,0,False)
If thisLog Then Log($"Nuevo inventario de ${t}: ${i}-${pm.ProdsFijosPiezas.Get(p)} = ${nuevoInv}"$) 'El nuevo inventario.
inventariosDisponiblesParaEstaPromo.Put(t, $"${nuevoInv}"$) 'Restamos del inventario las piezas requeridas para la promoción y guardamos el nuevo inventario en el mapa.
inventariosDisponiblesParaEstaPromo.Put("resultado", "ok")
Else 'Si en el mapa no esta el id del producto, entonces no tenemos inventario.
inventariosDisponiblesParaEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.")
If thisLog Then LogColor("Sin suficiente inventario fijo: " & t, Colors.Blue)
Exit
End If
If i - p2.Get("piezas") < 0 Then
inventariosDisponiblesParaEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.") 'Si el inventario de este producto sale negativo, quiere decir que no tenemos suficiente inventario para la promoción.
Exit
End If
Next
If thisLog Then LogColor("Inventario final despues de FIJOS: "&inventariosDisponiblesParaEstaPromo, Colors.blue) 'Inventario final.
Return inventariosDisponiblesParaEstaPromo
End Sub
' =============================================================================
' LÓGICA DE CÁLCULO 4: VARIABLES (Clon de Subs.alcanzanLosVariablesParaPromo)
' =============================================================================
Public Sub alcanzanLosVariablesParaPromo(pm As TPromoLegacy, inventarioSinFijos As Map) As Boolean
Private thisLog As Boolean = False 'Si es verdadero, muestra los logs de este sub.
If thisLog Then LogColor("Inventario inicial: "&inventarioSinFijos, Colors.Gray) 'Inventario inicial.
Private totalProdsVariables As Int = 0
Private prodsVariables As List = pm.ProdsVariables 'Obtenemos la lista con los productos variables de la promoción.
For p = 0 To prodsVariables.Size - 1
Private t As String = prodsVariables.Get(p) 'Obtenemos el Id de este producto desde la lista de productos fijos.
If inventarioSinFijos.ContainsKey(t) Then 'Si existe el producto en la lista del inventario, entonces ...
Private p2 As Int = inventarioSinFijos.Get(t) 'Obtenemos el inventario disponible este producto.
If thisLog Then Log($"prod ${t}, hay: ${p2}"$) 'Producto y piezas requeridas
totalProdsVariables = totalProdsVariables + p2
End If
Next
If thisLog Then Log("Total prods variables=" & totalProdsVariables & ", requeridos=" & pm.ProdsVariablesRequeridos)
Private res As Boolean = False
If totalProdsVariables >= pm.ProdsVariablesRequeridos Then res = True 'Si el total de inventario de productos variables (totalProdsVariables) es mayor o igual a los productos requeridos entonces regresamos TRUE
Return res
End Sub
' =============================================================================
' HELPERS PRIVADOS (Para hacer la clase portable sin depender de Subs.bas)
' =============================================================================
Private Sub TraePromosVendidas(promo As String, cliente As String) As Int
Dim c As Cursor
Dim pv As Int = 0
c = sql.ExecQuery($"select sum(PE_CANT) as cuantas from PEDIDO where PE_PROID = '${promo}' and PE_CLIENTE = '${cliente}'"$)
If c.RowCount > 0 Then
c.Position = 0
If c.GetString("cuantas") <> Null Then pv = c.GetInt("cuantas")
End If
c.Close
Return pv
End Sub
Private Sub TraemosInventarioDisponibleParaPromo(promo As String) As Map
Dim c As Cursor
c = sql.ExecQuery2("SELECT CAT_GP_ID, CAT_GP_ALMACEN FROM CAT_GUNAPROD2 WHERE CAT_GP_ID IN (select CAT_DP_IDPROD FROM CAT_DETALLES_PAQ WHERE CAT_DP_ID = ?)", Array As String(promo))
Dim prods As Map
prods.Initialize
If c.RowCount > 0 Then
For i=0 To c.RowCount -1
c.Position=i
prods.Put(c.GetString("CAT_GP_ID"), c.GetString("CAT_GP_ALMACEN"))
Next
End If
c.Close
Return prods
End Sub

View File

@@ -4,6 +4,74 @@ ModulesStructureVersion=1
Type=Class
Version=11.5
@EndOfDesignText@
Sub Descripcion
' *** FLUJO DE LAS PROMOCIONES ***
' Aquí está el desglose del flujo actual de decisión para mostrar una promoción, calculando los máximos y aplicando las restricciones de Segmentación, Inventario y Trade Spending (Bonificaciones).
'
' ### Flujo Maestro: ¿Se muestra la promo y cuántas alcanzan?
'
' El proceso se ejecuta secuencialmente. Si en algún punto el resultado es 0, la promoción no se muestra o se marca como agotada.
'
' #### 1. Cálculo de Límites Administrativos (La Base)
'
' Lo primero que hace el sistema es determinar el "Techo Teórico" de cuántas promociones se pueden vender Sin mirar inventario ni dinero aún.
' * **Paso A: Datos Generales:** Se obtienen los límites configurados en `PROMOS_COMP`: Máximo por Cliente, Máximo Recurrente y Máximo Global.
' * **Paso B: Lógica de Promociones Segmentadas:** Aquí entra el filtro crítico.
' * El sistema consulta `HIST_CLIENTE_CANT_PROMOS`.
' * **Si la promo es segmentada:**
' * Si el cliente **NO** está en la lista: Se establecen todos los máximos a 0. La promo se oculta.
' * Si el cliente **SÍ** está en la lista: Se ignoran los límites generales y se usan los específicos asignados al cliente.
' * **Fórmula:** `MaxDisponible = Asignado - Vendido`.
' * **Paso C: Cálculo del Mínimo:** Se comparan todos los límites (Global, Recurrente, Cliente/Segmentado) y se toma el **valor más pequeño** como el `MaxPromos` inicial.
'
' #### 2. Restricción por Inventario de Productos FIJOS
'
' Una vez que sabemos cuántas *podríamos* vender administrativamente, revisamos si tenemos los productos obligatorios (Fijos).
' * El sistema itera sobre cada producto fijo de la promoción.
' * **Cálculo:** `InventarioDisponible / PiezasRequeridasPorPromo`.
' * **Resultado:** El `MaxPromos` se actualiza al **mínimo** entre el valor del Paso 1 y lo que permite el inventario de cada producto fijo.
' * *Nota Crítica:* Si este valor es 0, la promo se marca como "KO" (No disponible).
'
' #### 3. El Cruce de Inventarios (La Resta)
'
' Este es el punto que mencionaste y es vital en el flujo actual. Antes de evaluar si alcanzan los productos variables, el código **simula la venta de los productos fijos**.
' * Se toma el mapa de inventario actual.
' * Se ejecuta `restaFijosDePromo`.
' * **Acción:** Para cada producto fijo, se resta: `(MaxPromosCalculado * PiezasRequeridas)`.
' * **Resultado:** Se genera un *Nuevo Mapa de Inventario Virtual* que contiene solo lo que sobró después de apartar lo necesario para la parte fija. Este mapa es el que se pasa a la siguiente etapa.
'
' #### 4. Cálculo de Variables y Restricción de Trade Spending (TS)
'
' Aquí es donde la lógica se vuelve compleja y utiliza los bucles iterativos para validar tanto existencia física como presupuesto financiero (Bonificaciones).
' Se ejecuta `revisaMaxPromosProdsVariablesPorInventario`, que usa el *Inventario Virtual* del paso anterior.
' **El Bucle de Validación (Paso a Paso):**
' El código prueba vender 1 promo, luego 2, hasta llegar al `MaxPromos` calculado en el paso 2.
' 1. **Iteración `x` (Número de promos a probar):**
' 2. **Consumo de Fijos en Variables:** Si un producto variable *también* es fijo, el código descuenta (otra vez) el inventario necesario para la parte fija dentro de este bucle para asegurar integridad.
' 3. **Suma de Inventario Variable:** Se suman las existencias de todos los productos que califican como variables para esta promo.
' 4. **Validación de Trade Spending (El Presupuesto):**
' * Dentro del bucle, para cada producto variable disponible, se llama a `ts.traeBonificacionesMaximas`.
' * **La Lógica de ts:** El sistema verifica si el producto actual califica como bonificación (precio especial/cero).
' * **Si califica:** Verifica si hay saldo en el presupuesto de "BONIFICACIONES". Si no hay saldo, este producto variable **no se cuenta** como disponible para armar la promo en esta iteración.
' * **Si NO califica:** (Es un producto de precio normal dentro de la promo), no consume presupuesto y se cuenta libremente según su inventario físico.
' 5. **Prueba de Fuego:**
' * Se compara: `InventarioVariableValidado (Físico + Financiero)` vs `(PiezasVariablesRequeridas * x)`.
' * Si alcanza, el ciclo continúa para probar `x + 1`.
' * Si no alcanza, el ciclo se rompe y se define el máximo posible.
'
' ### Resumen del Factor TS en el Flujo
'
' El presupuesto de ts no bloquea la promo "per se", sino que **filtra qué productos variables están disponibles**.
' * Si la promo pide 3 variables.
' * Tienes 5 opciones en inventario físico.
' * 2 opciones son "Bonificación" (consumen presupuesto) y 3 son venta normal.
' * **Escenario Sin Presupuesto:** Al iterar, `ts.traeBonificacionesMaximas` devolverá 0 para los 2 productos de bonificación. El sistema solo verá 3 productos disponibles (los normales).
' * **Resultado:** Como la promo pide 3 y el sistema "ve" 3 disponibles, la promo **SÍ SE MUESTRA**.
' * **Bloqueo:** Solo se bloquearía si la promo pidiera 4 variables, ya que Sin presupuesto ts solo "vemos" 3 productos disponibles, insuficientes para armar el paquete.
'
' ### Este flujo garantiza que la promo se muestre siempre que sea *físicamente* posible armarla, restringiendo la parte financiera solo a los ítems que realmente cuestan dinero al presupuesto de bonificaciones.
End Sub
Sub Class_Globals
Private Root As B4XView 'ignore
Private xui As XUI
@@ -44,12 +112,18 @@ Sub Class_Globals
Dim montoPedidoActual As String
Dim promosMap As Map
Dim ts As C_TrendSpending
Dim TS_RMI() As String
Dim TS_DESCUENTOS() As String
Dim TS_BONIFICACIONES() As String
End Sub
'You can add more parameters here.
Public Sub Initialize As Object
' promosC.Initialize(Me, "promosC", Starter.skmt)
ts.Initialize("ts", "ts", Starter.skmt)
Log(TS_RMI)
Log(TS_DESCUENTOS)
Log(TS_BONIFICACIONES)
Return Me
End Sub
@@ -68,6 +142,7 @@ Private Sub B4XPage_Created (Root1 As B4XView)
End Sub
Sub B4XPage_Appear
B4XPages.MainPage.aud.guarda("Entrada a Promos")
B4XPages.MainPage.productos.entro = 3
' LogColor(B4XPages.MainPage.productos.prodsMap, Colors.blue)
prodsIds.Initialize
@@ -82,15 +157,18 @@ Sub B4XPage_Appear
Log($"laPromo=${laPromo}, el cliente=${elCliente}"$)
If laPromo <> "" Then muestraPromo(laPromo, elCliente)
End Sub
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
Sub muestraPromo(promo As String, cliente As String)
Log("muestraPromo:"&promo)
LogColor($"****************************************************************"$, Colors.red)
LogColor($"************ muestraPromo: ${promo} *************"$, Colors.red)
' Log("muestraPromo: "&promo)
Private thisLog As Boolean = False
' If thisLog Then Log(promo)
estaPromo = promo
esteCliente = cliente
Private mp As Map = Subs.traePromo(promo, cliente)
If thisLog Then LogColor(mp, Colors.blue)
Private prodsPromo As Map = mp.Get("productos") 'Los productos de la promoción.
' Private invDispPromo As Map = Subs.traemosInventarioDisponibleParaPromo(promo)
@@ -166,7 +244,7 @@ Sub muestraPromo(promo As String, cliente As String)
Private thisProd As Map = prodsPromo.Get(p)
If thisLog Then Log(thisProd)
If existenciaProdVariable > 0 Then
Log($">>>>> AGREGAMOS PROD VARIABLE ${p}"$)
If thisLog Then Log($">>>>> AGREGAMOS PROD VARIABLE ${p}"$)
clv_prodsVariabes.Add(CreateListItem(Subs.traeProdNombre(p)&CRLF&"Hay " & invDispPromo.Get(p) & " $" & estePrecio, estePrecio, invDispPromo.Get(p), clv_prodsVariabes.AsView.Width, 50dip, Null, p), p)
End If
End If
@@ -338,6 +416,7 @@ Sub cuentaProds
End If
l_total.Text = $"Total: $$1.2{totalCompra}"$
l_totProds.text = $"Productos: ${totalProds}"$
' Log(esteTag.Get(2) & "|" & estaPromo)
Next
If thisLog Then Log($"Total Prods: ${totalProds}, Total: $$1.2{totalCompra}"$)
l_total.Text = $"Total: $$1.2{totalCompra}"$
@@ -365,6 +444,7 @@ Sub cuentaProds
' cant1.Text = 0
' Next
' End If
End Sub
Private Sub et_pCant_FocusChanged (HasFocus As Boolean)
@@ -470,16 +550,40 @@ End Sub
Private Sub b_terminar1_Click
cuentaProds
Private elMontoTSDeLaVenta As String = 0
' Log("====================================================================")
' Log($"${prodsIds}${CRLF}${prodsCants}${CRLF}${prodsPrecios}"$)
Log($"${prodsIds}${CRLF}${prodsCants}${CRLF}${prodsPrecios}"$)
For t = 0 To prodsIds.Size - 1 'Guardamos los productos fijos de la promocion en pedido.
Private pn As String = Subs.traeProdNombre(prodsIds.Get(t))
Private idProdFijo As String = prodsIds.Get(t)
Private cantProdFijo As Int = prodsCants.Get(t)
Private prodsPrecio As String = prodsPrecios.Get(t)
Log($"#### idProdFijo: ${idProdFijo}, ${cantProdFijo}, ${prodsPrecio}"$)
' ' Asumimos que el índice 0 es el encabezado de la promoción (estaPromo) y no tiene bonificación de producto.
If t > 0 Then
Private bonificacion_monto As String = ts.traeMontoBonificacion(idProdFijo, prodsPrecio, estaPromo, "b_terminar1_Click")
Log(bonificacion_monto)
Log("elMontoTSDeLaVenta=" & elMontoTSDeLaVenta)
Log($"${elMontoTSDeLaVenta} + (${bonificacion_monto} * ${cantProdFijo})"$)
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (bonificacion_monto * cantProdFijo)
Log($"TS Fijo Acumulado: ${elMontoTSDeLaVenta}, Prod: ${idProdFijo}"$)
End If
If prodsCants.Get(t) > 0 Then Subs.guardaProductoSinGestion(estaPromo, prodsPrecios.Get(t), prodsCants.Get(t), pn, prodsIds.Get(t), Subs.traeCliente, Subs.traeFecha, Subs.traeUsuarioDeBD, Subs.traeRuta, 0, Starter.tipov)
Next
For t = 0 To prodsIds2.Size - 1 'Guardamos los productos variables de la promocion en pedido.
Private pn As String = Subs.traeProdNombre(prodsIds2.Get(t))
Subs.guardaProductoSinGestion(estaPromo, prodsPrecios2.Get(t), prodsCants2.Get(t), pn, prodsIds2.Get(t), Subs.traeCliente, Subs.traeFecha, Subs.traeUsuarioDeBD, Subs.traeRuta, 0, Starter.tipov)
' Traemos el monto de las bonificacionos a guardar. -- Trade Spending
Log("Monto Bonificacion -->> " & ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo, "LOG_b_terminar1_Click2"))
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo, "b_terminar1_Click3") * prodsCants2.Get(t))
Log("Acumulado: " & elMontoTSDeLaVenta)
Next
ts.modTrendSpending("RESTA", "BONIFICACIONES", elMontoTSDeLaVenta)
Log($"### modTrendSpending("RESTA", "BONIFICACIONES", ${elMontoTSDeLaVenta})"$)
lv_prodsFijos.Clear
B4XPages.MainPage.bTerminarClicked = True
B4XPages.ShowPage("productos")
@@ -488,16 +592,40 @@ End Sub
Private Sub b_continuar_Click
cuentaProds
Private elMontoTSDeLaVenta As String = 0
' Log("====================================================================")
Log($"${prodsIds}${CRLF}${prodsCants}${CRLF}${prodsPrecios}"$)
For t = 0 To prodsIds.Size - 1 'Guardamos los productos fijos de la promocion en pedido.
Private pn As String = Subs.traeProdNombre(prodsIds.Get(t))
Subs.guardaProductoSinGestion(estaPromo, prodsPrecios.Get(t), prodsCants.Get(t), pn, prodsIds.Get(t), Subs.traeCliente, Subs.traeFecha, Subs.traeUsuarioDeBD, Subs.traeRuta, 0, Starter.tipov)
Private idProdFijo As String = prodsIds.Get(t)
Private cantProdFijo As Int = prodsCants.Get(t)
Private prodsPrecio As String = prodsPrecios.Get(t)
Log($"#### idProdFijo: ${idProdFijo}, ${cantProdFijo}, ${prodsPrecio}"$)
' ' Asumimos que el índice 0 es el encabezado de la promoción (estaPromo) y no tiene bonificación de producto.
If t > 0 Then
Private bonificacion_monto As String = ts.traeMontoBonificacion(idProdFijo, prodsPrecio, estaPromo, "b_continuar_Click")
Log(bonificacion_monto)
Log("elMontoTSDeLaVenta=" & elMontoTSDeLaVenta)
Log($"${elMontoTSDeLaVenta} + (${bonificacion_monto} * ${cantProdFijo})"$)
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (bonificacion_monto * cantProdFijo)
Log($"TS Fijo Acumulado: ${elMontoTSDeLaVenta}, Prod: ${idProdFijo}"$)
End If
If prodsCants.Get(t) > 0 Then Subs.guardaProductoSinGestion(estaPromo, prodsPrecios.Get(t), prodsCants.Get(t), pn, prodsIds.Get(t), Subs.traeCliente, Subs.traeFecha, Subs.traeUsuarioDeBD, Subs.traeRuta, 0, Starter.tipov)
Next
For t = 0 To prodsIds2.Size - 1 'Guardamos los productos variables de la promocion en pedido.
Private pn As String = Subs.traeProdNombre(prodsIds2.Get(t))
Subs.guardaProductoSinGestion(estaPromo, prodsPrecios2.Get(t), prodsCants2.Get(t), pn, prodsIds2.Get(t), Subs.traeCliente, Subs.traeFecha, Subs.traeUsuarioDeBD, Subs.traeRuta, 0, Starter.tipov)
' Traemos el monto de las bonificacionos a guardar. -- Trade Spending
Log("Monto Bonificacion -->> " & ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo, "LOG_b_continuar_Click2"))
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo, "b_continuar_Click3") * prodsCants2.Get(t))
Log("Acumulado: " & elMontoTSDeLaVenta)
Next
ts.modTrendSpending("RESTA", "BONIFICACIONES", elMontoTSDeLaVenta)
Log($"### modTrendSpending("RESTA", "BONIFICACIONES", ${elMontoTSDeLaVenta})"$)
lv_prodsFijos.Clear
' Activity_KeyPress(KeyCodes.KEYCODE_BACK)
' CallSubDelayed2(productos, "Activity_KeyPress", KeyCodes.KEYCODE_BACK)

View File

@@ -1,24 +0,0 @@
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.

View File

@@ -48,6 +48,7 @@ End Sub
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
Sub B4XPage_Appear
B4XPages.MainPage.aud.guarda("Entrada a TicketsDia")
nombre_boton = "NOVENTA"
c=Starter.skmt.ExecQuery("select PC_CLIENTE,PC_MONTO,PC_NOART,(select CAT_CL_NOMBRE from kmt_info where cat_cl_codigo = pc_cliente ) as NOMBRE FROM PEDIDO_CLIENTE ORDER BY PC_FECHA asc")
ListView1.Clear
@@ -90,8 +91,10 @@ Sub Activity_KeyPress (key As Int) As Boolean
End Sub
Sub ListView1_ItemLongClick (Position As Int, Value As Object)
Log(Value)
Starter.skmt.ExecNonQuery("delete from CUENTAA")
Starter.skmt.ExecNonQuery2("INSERT INTO CUENTAA VALUES (?)", Array As Object(Value))
B4XPages.MainPage.aud.guarda($"Clic largo TicketsDia: ${Value}"$)
Subs.iniciaActividad("Cliente")
End Sub

462
B4A/C_TrendSpending.bas Normal file
View File

@@ -0,0 +1,462 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=12.8
@EndOfDesignText@
' Clase para las funciones de Trend Spending.
' Trend spending son 3 presupuestos que tiene Kelloggs, que son bonificaciones, descuentos y RMIs, estos se calculan semanalmente
' y se descargan de la tabla HIST_TRADE_SPENDING_SEMANAL, de ahi obtenemos el presupuesto de la semana y el acumulado hasta ayer
' en la noche, a cada presupuesto le vamos sumando cada que agregamos a pedido un DESCUENTO (Precios diferentes al original que
' NO están en PROMOS), una BONIFICACION (precios con descuento que estan en promociones) o un RMI (de estos sumamos al presupuesto
' el precio del RMI seleccionado), de acuerdo al presupuesto disponible de cada tipo, se limitan los productos, es decir que si
' el presupuesto de bonificaciones ya se agoto, ya no aparecen promociones, o si el de descuentos se agoto, ya no se pueden agregar
' mas productos con descuento.
' Descuento es TODO lo que tenga un precio diferente al precio de lista y NO esta en promo.
' Bonificacion es lo que tiene precio diferente al orginal y esta en promo y NO es regalo o exhibidor.
Sub Class_Globals
Private EventName As String 'ignore
Private CallBack As Object 'ignore
Dim tsMaximas As Int = 0
Private tsdb As SQL
Dim TS_RMI() As String
Dim TS_DESCUENTOS() As String
Dim TS_BONIFICACIONES() As String
End Sub
'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize (vCallback As Object, vEventName As String, db As SQL) As Object
EventName = vEventName
CallBack = vCallback
tsdb = db
Private mx As Map = traeInfoTrendSpending
LogColor(mx, Colors.red)
TS_RMI = Regex.Split(",", mx.Get("RMI"))
TS_DESCUENTOS = Regex.Split(",", mx.Get("DESCUENTOS"))
TS_BONIFICACIONES = Regex.Split(",", mx.Get("BONIFICACIONES"))
LogColor(">>>>>>>>>>>>> TRENDSPENDING: " & mx, Colors.red)
LogColor("RMI: " & TS_RMI(0) & "|" & TS_RMI(1), Colors.red)
LogColor("DESCUENTOS: " & TS_DESCUENTOS(0) & "|" & TS_DESCUENTOS(1), Colors.red)
LogColor("BONIFICACIONES: " & TS_BONIFICACIONES(0) & "|" & TS_BONIFICACIONES(1), Colors.red)
Return Me
End Sub
'Regresa la tabla de productos (cat_gunaprod o cat_gunaprod2) dependiendo del tipo de venta.
Sub traeTablaProds(tipoventa As String) As String
Private tablaProds As String = "cat_gunaprod2"
If tipoventa = "ABORDO" Or tipoventa = "PREVENTA" Then tablaProds = "cat_gunaprod"
' LogColor($"Tipo= ${tipoventa}, tabla=${tablaProds}"$, Colors.RGB(200,136,0))
Return tablaProds
End Sub
'Regresa el descuento de condiciones comerciales por SKU.
Sub traeDescXSku(clienteId As String, prodId As String) As String 'ignore
Private desc As String = "0"
Private c As Cursor = tsdb.ExecQuery($"Select * from CAT_DESCUENTOS_SKU where CAT_DS_CLIENTE = '${clienteId}' and CAT_DS_PRODID = '${prodId}'"$)
If c.RowCount > 0 Then
c.Position = 0
desc = c.GetString("CAT_DS_PORCENTAJE")
End If
Return desc
End Sub
' Regresa un mapa con el tipo, monto permitido semanal y el acumulado hasta el día anterior:
' ej:
' - RMI=1500,0
' - DESCUENTOS=1500,0
' - BONIFICACIONES=1500,480
Sub traeInfoTrendSpending As Map
Private semana As Int = 0
Private HIST_TSS_SEMANA As String = 0
Private HIST_TSS_SEMANA_ACUM As String = 0
Private m As Map = CreateMap("RMI": 10000000 & "," & 0, "DESCUENTOS": 10000000 & "," & 0, "BONIFICACIONES": 10000000 & "," & 0) ' El 100,000 es el default del presupuesto, por si NO HAY datos de trend spending.
' m.Initialize
Private c As Cursor = tsdb.ExecQuery($"select cat_va_valor from cat_variables where cat_va_descripcion = 'SEM_CAL_LABORAL'"$)
If c.RowCount > 0 Then
c.Position = 0
semana = c.GetInt("CAT_VA_VALOR")
End If
If semana > 0 Then
c = tsdb.ExecQuery($"select HIST_TSS_TIPO, HIST_TSS_SEMANA${semana}, ifnull(HIST_TSS_SEMANA${semana}_ACUM,0) as HIST_TSS_SEMANA${semana}_ACUM from HIST_TREND_SPENDING_SEMANAL"$)
Log($"select HIST_TSS_TIPO, HIST_TSS_SEMANA${semana}, ifnull(HIST_TSS_SEMANA${semana}_ACUM,0) as HIST_TSS_SEMANA${semana}_ACUM from HIST_TREND_SPENDING_SEMANAL"$)
If c.RowCount > 0 Then
For i = 0 To c.RowCount - 1
c.Position = i
HIST_TSS_SEMANA = c.GetString($"HIST_TSS_SEMANA${semana}"$)
If Not(IsNumber(HIST_TSS_SEMANA)) Then HIST_TSS_SEMANA = 0
Private xx As String = c.GetString($"HIST_TSS_SEMANA${semana}_ACUM"$)
If xx = "null" Then xx = 0
HIST_TSS_SEMANA_ACUM = xx
If c.GetString("HIST_TSS_TIPO") = "RMI" Then
m.Put("RMI", HIST_TSS_SEMANA & "," & HIST_TSS_SEMANA_ACUM)
else if c.GetString("HIST_TSS_TIPO") = "DESCUENTOS" Then
m.Put("DESCUENTOS", HIST_TSS_SEMANA & "," & HIST_TSS_SEMANA_ACUM)
else if c.GetString("HIST_TSS_TIPO") = "BONIFICACIONES" Then
m.Put("BONIFICACIONES", HIST_TSS_SEMANA & "," & HIST_TSS_SEMANA_ACUM)
End If
Next
End If
End If
Return m
End Sub
' Modifica el acumulado del Trend Speding, le "suma" o "resta" al presupuesto especificado (RMI, BONIFICACIONES o DESCUENTOS)
Sub modTrendSpending(accion As String, tipo As String, monto As String)
LogColor($"#### ACCION: ${accion}, Tipo: ${tipo}, Monto: ${monto}"$, Colors.Blue)
Private HIST_TSS_SEMANA As String
Private HIST_TSS_SEMANA_ACUM As String
Private acumulado As String = "0"
If Starter.semana = 0 Then
Private c As Cursor = tsdb.ExecQuery($"select cat_va_valor from cat_variables where cat_va_descripcion = 'SEM_CAL_LABORAL'"$)
If c.RowCount > 0 Then
c.Position = 0
Starter.semana = c.GetInt("CAT_VA_VALOR")
End If
End If
HIST_TSS_SEMANA = $"HIST_TSS_SEMANA${Starter.semana}"$
HIST_TSS_SEMANA_ACUM = $"HIST_TSS_SEMANA${Starter.semana}_ACUM"$
Private d As Cursor = tsdb.ExecQuery($"select ifnull(acumulado, 0) as ACUMULADO from TREND_SPENDING where tipo = '${tipo.ToUpperCase}'"$)
If d.RowCount > 0 Then
d.Position = 0
acumulado = d.GetString("ACUMULADO")
End If
Log("acumulado:" & acumulado & " | monto: " & monto)
Private c As Cursor = tsdb.ExecQuery($"select HIST_TSS_TIPO, ifnull(${HIST_TSS_SEMANA},0) as disponible, ifnull(${HIST_TSS_SEMANA_ACUM},0) as acumulado from HIST_TREND_SPENDING_SEMANAL where HIST_TSS_TIPO = '${tipo.ToUpperCase}'"$)
' Log(($"select HIST_TSS_TIPO, ${HIST_TSS_SEMANA} as disponible, ${HIST_TSS_SEMANA_ACUM} as acumulado from HIST_TREND_SPENDING_SEMANAL where HIST_TSS_TIPO = '${tipo.ToUpperCase}'"$))
Log("---- " & c.RowCount)
If accion.ToUpperCase = "RESTA" Then
If c.RowCount > 0 Then
c.Position = 0
If tipo.ToUpperCase = "DESCUENTOS" Or tipo.ToUpperCase = "RMI" Or tipo.ToUpperCase = "BONIFICACIONES" Then
Private nuevaBonificacion As String = NumberFormat2((acumulado + monto), 1, 2, 2, False)
LogColor($"Nuevo acumulado ${tipo} = ${nuevaBonificacion}"$, Colors.Magenta)
tsdb.ExecNonQuery($"delete from TREND_SPENDING where tipo = '${tipo.ToUpperCase}' "$)
tsdb.ExecNonQuery($"insert into TREND_SPENDING (tipo, acumulado) values ('${tipo.ToUpperCase}', '${nuevaBonificacion}')"$)
Log($"Insertamos en TRADE_SPENDING: ${nuevaBonificacion}"$)
' else if tipo.ToUpperCase = "RMI" Then
End If
End If
else if accion.ToUpperCase = "SUMA" Then
If c.RowCount > 0 Then
c.Position = 0
If tipo.ToUpperCase = "DESCUENTOS" Or tipo.ToUpperCase = "RMI" Or tipo.ToUpperCase = "BONIFICACIONES" Then
Private nuevaBonificacion As String = NumberFormat2((acumulado - monto), 1, 2, 2, False)
LogColor($"Nueva bonificacion = ${nuevaBonificacion}"$, Colors.Magenta)
tsdb.ExecNonQuery($"delete from TREND_SPENDING where tipo = '${tipo.ToUpperCase}' "$)
tsdb.ExecNonQuery($"insert into TREND_SPENDING (tipo, acumulado) values ('${tipo.ToUpperCase}', '${nuevaBonificacion}')"$)
End If
End If
End If
End Sub
Sub traeAcumuladoHoyTS(tipo As String) As String
' Private HIST_TSS_SEMANA As String
' Private HIST_TSS_SEMANA_ACUM As String
Private acumulado As String = "0"
If Starter.semana = 0 Then
Private c As Cursor = tsdb.ExecQuery($"select cat_va_valor from cat_variables where cat_va_descripcion = 'SEM_CAL_LABORAL'"$)
If c.RowCount > 0 Then
c.Position = 0
Starter.semana = c.GetInt("CAT_VA_VALOR")
End If
End If
' HIST_TSS_SEMANA = $"HIST_TSS_SEMANA${Starter.semana}"$
' HIST_TSS_SEMANA_ACUM = $"HIST_TSS_SEMANA${Starter.semana}_ACUM"$
Private d As Cursor = tsdb.ExecQuery($"select acumulado from TREND_SPENDING where tipo = '${tipo.ToUpperCase}'"$)
If d.RowCount > 0 Then
d.Position = 0
acumulado = d.GetString("ACUMULADO")
End If
' LogColor($"Acumulado hoy de ${tipo}: "$ & acumulado, Colors.Blue)
Return NumberFormat2(acumulado, 1, 2, 2, False)
End Sub
'Trae el cliente de CUENTAA
Sub traeCliente As String 'ignore
Private c As Cursor
Private cl As String
c = Starter.skmt.ExecQuery("Select CUENTA from cuentaa")
c.Position = 0
cl = c.GetString("CUENTA")
c.Close
Return cl
End Sub
Sub traePrecio(id As String) As String
Private precio As String = "0"
Private c As Cursor = tsdb.ExecQuery($"select cat_gp_precio from ${traeTablaProds(Starter.tipov)} where cat_gp_id = '${id}'"$)
If c.RowCount > 0 Then
c.Position = 0
precio = c.GetString("CAT_GP_PRECIO")
End If
Return precio
End Sub
Sub trendSpending(accion As String, tipo As String, clienteId As String, id As String, laCant As String, inv As Int) As String
Private logger As Boolean = True
LogColor("-------- > TRADE SPENDING < ---------", Colors.red)
' Log("DescxSku: " & traeDescXSku(clienteId, id))
Dim TS_RMI() As String
Dim TS_DESCUENTOS() As String
Dim TS_BONIFICACIONES() As String
Private mx As Map = traeInfoTrendSpending
TS_RMI = Regex.Split(",", mx.Get("RMI"))
TS_DESCUENTOS = Regex.Split(",", mx.Get("DESCUENTOS"))
TS_BONIFICACIONES = Regex.Split(",", mx.Get("BONIFICACIONES"))
If tipo.ToUpperCase = "RMI" Then
Private lasMaximas As Int = 0
Log($"Acumulado de RMIs: ${traeAcumuladoHoyTS("rmi")}"$)
Private elMonto As String = NumberFormat2(traePrecioRMI(id), 1, 2, 2, False)
If logger Then Log($"elMonto: ${elMonto}"$)
' If logger Then Log($"TS_RMI(0): ${TS_RMI(0)}"$)
' If logger Then Log($"TS_RMI(1): ${TS_RMI(1)}"$)
If logger Then Log($"LaCant: ${laCant}"$)
Private tsRestantes As String = (TS_RMI(0) - TS_RMI(1) - traeAcumuladoHoyTS("rmi"))
Log($"tsRestantes: ${tsRestantes}"$)
If accion.ToUpperCase = "PRODMAS" Then 'Regresa lasMaximas y elMonto separadas por un "|"
If elMonto > 0 Then
lasMaximas = ((laCant * elMonto) + tsRestantes) / elMonto
If logger Then Log("lasMaximas: " & lasMaximas)
If logger Then Log("traeAcumuladoHoyTS: " & traeAcumuladoHoyTS("rmi"))
End If
' If laCant + 1 = lasMaximas Then
' ToastMessageShow("El presupuesto de RMI no permite agregar mas productos!!", False)
' End If
If logger Then Log("EL RMI: " & elMonto)
If logger Then Log($"lacant=${laCant} < lasMaximas=${lasMaximas} = ${laCant<lasMaximas}"$)
If laCant < lasMaximas Then
modTrendSpending("resta", "rmi", elMonto) ' Restamos al presupuesto de hoy (agregamos al acumulado).
Log($"modTrendSpending("resta", "rmi", ${elMonto})"$)
End If
If logger Then LogColor("RMI RESTANTES: " & (TS_RMI(0) - TS_RMI(1) - traeAcumuladoHoyTS("rmi")), Colors.red)
Return lasMaximas & "|" & elMonto
else if accion.ToUpperCase = "PRODMENOS" Then
If logger Then Log("LaCANT= " & laCant & ", elMonto= " & elMonto)
If laCant >= 0 Then
modTrendSpending("suma", "rmi", elMonto) ' Agregamos al presupuesto de hoy (restamos del acumulado).
Log($"modTrendSpending("suma", "rmi", ${elMonto})"$)
End If
Return lasMaximas & "|" & elMonto
End If
else If tipo.ToUpperCase = "DESCUENTOS" Then
Dim lasMaximas As Int = 0
Dim elMonto As String = 0
Private elMonto As String = NumberFormat2(traePrecio(id)*(traeDescXSku(clienteId, id)/100), 1, 2, 2, False)
Private tsRestantes As String = (TS_DESCUENTOS(0) - TS_DESCUENTOS(1) - traeAcumuladoHoyTS("descuentos"))
If logger Then Log("EL MONTO: " & elMonto)
If logger Then LogColor("Monto del presupuesto disponible: " & tsRestantes, Colors.blue)
If accion.ToUpperCase = "PRODMAS" Then 'Regresa lasMaximas y elMonto separadas por un "|"
' If logger Then Log("PMAS")
If elMonto > 0 Then
lasMaximas = ((laCant * elMonto) + tsRestantes) / elMonto
If logger Then Log("lasMaximas: " & lasMaximas)
' If logger Then Log("lasMaximas2: " & traeMaximas("descuentos", clienteId, id, laCant, ""))
If logger Then Log("Acumulado hoy: " & traeAcumuladoHoyTS("descuentos"))
End If
If laCant = lasMaximas Then
ToastMessageShow("El presupuesto de DESCUENTOS no permite agregar mas productos!!", False)
End If
If logger Then Log("EL MONTO: " & elMonto)
If inv > 0 And laCant < lasMaximas Then
modTrendSpending("resta", "descuentos", elMonto) ' Restamos al presupuesto de hoy (agregamos al acumulado).
End If
If logger Then Log(">>>> MONTO RESTANTE PRESUPUESTO: " & (TS_DESCUENTOS(0) - TS_DESCUENTOS(1) - traeAcumuladoHoyTS("descuentos")))
Return lasMaximas & "|" & elMonto
else if accion.ToUpperCase = "PRODMENOS" Then 'Regresa descuentosMaximas y elMonto separadas por un "|"
If logger Then Log("LaCANT= " & laCant & ", elMonto= " & elMonto)
If laCant >= 0 Then
modTrendSpending("suma", "descuentos", elMonto) ' Agregamos al presupuesto de hoy (restamos del acumulado).
End If
Return lasMaximas & "|" & elMonto
else if accion.ToUpperCase = "TEXTCHANGED" Then
If logger Then Log("TC")
else if accion.ToUpperCase = "FOCUSCHANGED" Then 'Regresa descuentos maximas, SOLO correr esta parte si HASFOCUS es VERDADERO.
If logger Then Log("FC")
Private elMonto As String = traePrecio(id)*(traeDescXSku(clienteId, id)/100)
If elMonto > 0 Then 'And HasFocus
If logger Then Log("LA BONIFICACION: " & elMonto)
Private tsRestantes As String = (TS_DESCUENTOS(0) - TS_DESCUENTOS(1) - traeAcumuladoHoyTS("descuentos"))
If logger Then Log("Monto del PRESUPUESTO disponible: " & tsRestantes)
lasMaximas = ((laCant * elMonto) + tsRestantes) / elMonto
If logger Then Log("tsMaximas: " & lasMaximas)
End If
Return lasMaximas
End If
End If
End Sub
' Trae el precio del RMI desde CAT_RMI.
Sub traePrecioRMI(id As String) As String
Private precio As String = "0"
Private c As Cursor = tsdb.ExecQuery($"select cat_monto from cat_rmi where cat_id = '${id}'"$)
If c.RowCount > 0 Then
c.Position = 0
precio = c.GetString("CAT_MONTO")
End If
Return precio
End Sub
' Traemos el monto (descuento total) del producto actual.
' Utiliza el descuento de condiciones comerciales por SKU (tabla CAT_DESCUENTOS).
Sub traeMonto(clienteId As String, id As String) As String
Private tsMonto As String
tsMonto = NumberFormat2(traePrecio(id)*(traeDescXSku(clienteId, id)/100), 1, 2, 2, False)
Return tsMonto
End Sub
' Trae la cantidad máxima de rmis, bonificaciones o descuentos por presupuesto.
Sub traeMaximas(tipo As String, clienteId As String, id As String, laCant As String, promoId As String) As Int
Private tsMaximas As Int = 10000000
Private tsRestantes As String = 0
Private tsMonto As String '= traeMonto(clienteId, id)
' If tsMonto > 0 Then
If tipo.ToUpperCase = "DESCUENTOS" Then
tsMonto = NumberFormat2(traePrecio(id)*(traeDescXSku(clienteId, id)/100), 1, 2, 2, False)
tsRestantes = (TS_DESCUENTOS(0) - TS_DESCUENTOS(1) - traeAcumuladoHoyTS("descuentos")) ' Traemos monto restante de Trend Spending para descuentos.
else If tipo.ToUpperCase = "RMI" Then
tsMonto = NumberFormat2(traePrecioRMI(id), 1, 2, 2, False)
tsRestantes = (TS_RMI(0) - TS_RMI(1) - traeAcumuladoHoyTS("rmi")) ' Traemos monto restante de Trend Spending para rmis.
' else If tipo.ToUpperCase = "BONIFICACIONES" Then
' tsMonto = NumberFormat2(traeMontoBonificacion(id, promoId), 1, 2, 2, False)
' tsRestantes = (TS_BONIFICACIONES(0) - TS_BONIFICACIONES(1) - traeAcumuladoHoyTS("bonificaciones")) ' Traemos monto restante de Trend Spending para bonificaciones.
End If
' Log($"${TS_BONIFICACIONES(0)} - ${TS_BONIFICACIONES(1)} - ${traeAcumuladoHoyTS("bonificaciones")}"$)
' Log($"((${laCant} * ${tsMonto}) + ${tsRestantes}) / ${tsMonto}"$)
Log($"tsMonto: ${tsMonto}"$)
Log($"tsRestantes: ${tsRestantes}"$)
tsMaximas = ((laCant * tsMonto) + tsRestantes) / tsMonto
' End If
Return tsMaximas
End Sub
' Trae la cantidad máxima de productos con bonificacion por presupuesto.
' Si el presupuesto es 10 y la bonificacion del producto es 2, el máximo es 5 productos.
Sub traeBonificacionesMaximas(tipo As String, clienteId As String, id As String, laCant As String, elPrecioVenta As String, promoId As String) As Int
Private thisLog As Boolean = True
Private tsMaximas As Int = 100000000
Private tsRestantes As String = 0
Private tsMonto As String
Private mx As Map = traeInfoTrendSpending
TS_RMI = Regex.Split(",", mx.Get("RMI"))
TS_DESCUENTOS = Regex.Split(",", mx.Get("DESCUENTOS"))
TS_BONIFICACIONES = Regex.Split(",", mx.Get("BONIFICACIONES"))
If thisLog Then LogColor($" ============ INICIA BONIFICACIONES MAXIMAS (${id}) ========"$, Colors.RGB(0,197,110))
If thisLog Then LogColor($" Presupuesto: ${TS_BONIFICACIONES(0)} - Acumulado ayer: ${TS_BONIFICACIONES(1)} - Hoy: ${traeAcumuladoHoyTS("bonificaciones")}"$, Colors.Magenta)
If tipo.ToUpperCase = "BONIFICACIONES" Then
tsMonto = NumberFormat2(traeMontoBonificacion(id, elPrecioVenta, promoId, "traeBonificacionesMaximas"), 1, 2, 2, False)
tsRestantes = (TS_BONIFICACIONES(0) - TS_BONIFICACIONES(1) - traeAcumuladoHoyTS("bonificaciones")) ' Traemos monto restante de Trend Spending para bonificaciones.
Log($" PresupuestoBonifs: ${TS_BONIFICACIONES(0)}, AcumuladoBonifs: ${TS_BONIFICACIONES(1)}, traeAcumuladoHoyTS('bonificaciones'): ${traeAcumuladoHoyTS("bonificaciones")}"$)
' Log($" ${TS_BONIFICACIONES(0)} - ${TS_BONIFICACIONES(1)} - ${traeAcumuladoHoyTS("bonificaciones")}"$)
End If
If thisLog Then Log($" Monto de bonificacion: ${tsMonto}"$)
If thisLog Then Log($" Presupuesto disponible: ${tsRestantes}"$)
' If thisLog Then Log($"Cantidad: ${laCant}"$)
If thisLog Then Log($" Floor(tsRestantes / (tsMonto * laCant)) <==> Floor(${tsRestantes} / (${tsMonto} * ${laCant})) = ${Floor(tsRestantes / (tsMonto * laCant))}"$)
' If thisLog Then Log($"Floor(${tsRestantes} / (${tsMonto} * ${laCant}))= ${Floor(tsRestantes / (tsMonto * laCant))}"$)
If tsMonto > 0 Then
tsMaximas = Floor(tsRestantes / (tsMonto * laCant))
End If
If thisLog Then LogColor(" ************************************************", Colors.red)
If thisLog Then LogColor(" ***** BONIFICACIONES MAXIMAS: " & tsMaximas & " *****", Colors.red)
If thisLog Then LogColor(" ************************************************", Colors.red)
If thisLog Then LogColor(" ============ TERMINA BONIFICACIONNES MAXIMAS ========", Colors.RGB(0,197,110))
Return tsMaximas
End Sub
' Trae el monto de la bonificacion, que es el precio original MENOS el precio de venta con descuento.
' - Si CAT_DP_PRECIOB es 1, la bonificacion es: Precio original - precio de venta.
' - Si CAT_DP_PRECIOB es 0, la bonificacion es: .
Sub traeMontoBonificacion(id As String, precio As String, promoId As String, parent As String) As String
Private thisLog As Boolean = True
If thisLog Then LogColor($" ============ INICIA MONTO BONIFICACION (${id}) ========"$, Colors.RGB(151,0,171))
If thisLog Then LogColor($" ###### ${id}, ${precio}, ${promoId}, ${parent}"$, Colors.Magenta)
Private tsMonto As String = 0
Private re As Cursor = Starter.skmt.ExecQuery($"select cat_gp_id from cat_gunaprod2 where (cat_gp_tipo like 'REGALO%' or cat_gp_tipo like 'EXHIBIDOR%') and cat_gp_id = '${id}'"$) ' Revisamos si el producto es regalo o exhibidor.
If re.RowCount = 0 Then' No es regalo ni exhibidor.
Private c As Cursor = tsdb.ExecQuery($"SELECT CAT_DP_ID, CAT_DP_IDPROD, CAT_DP_PRECIO, CAT_DP_TIPO, CAT_GP_PRECIO, CAT_DP_PRECIOB FROM CAT_DETALLES_PAQ join ${traeTablaProds(Starter.tipov)} on CAT_GP_ID = CAT_DP_IDPROD where CAT_GP_ID = '${id}' and CAT_DP_PRECIO = '${precio}' and CAT_DP_ID = '${promoId}'"$)
' Log($"SELECT CAT_DP_ID, CAT_DP_IDPROD, CAT_DP_PRECIO, CAT_DP_TIPO, CAT_GP_PRECIO, CAT_DP_PRECIOB FROM CAT_DETALLES_PAQ join ${traeTablaProds(Starter.tipov)} on CAT_GP_ID = CAT_DP_IDPROD where CAT_GP_ID = '${id}' and CAT_DP_PRECIO = '${precio}' and CAT_DP_ID = '${promoId}'"$)
If thisLog Then Log($" Rowcount DP y CGP2: ${c.RowCount}"$)
If c.RowCount > 0 Then
c.Position = 0
LogColor($"Precio original:${c.GetString("CAT_GP_PRECIO")} - Precio Venta:${c.GetString("CAT_DP_PRECIO")}"$, Colors.Blue)
If c.GetInt("CAT_DP_PRECIOB") = 1 Or (c.GetInt("CAT_DP_PRECIOB") = 0 And c.GetString("CAT_GP_PRECIO") = c.GetString("CAT_DP_PRECIO")) Then
tsMonto = c.GetString("CAT_GP_PRECIO") - c.GetString("CAT_DP_PRECIO") ' Precio original - precio de venta.
Else
tsMonto = c.GetString("CAT_GP_PRECIO") ' Precio original.
End If
' Log("PRECIOB: " & c.GetInt("CAT_DP_PRECIOB"))
If thisLog Then Log($" Precio normal: ${c.GetString("CAT_GP_PRECIO")}, Precio desc: ${c.GetString("CAT_DP_PRECIO")}, Monto bonificacion: ${tsMonto}"$)
End If
' Log("ROWCOUNT: " & c.RowCount)
End If
If thisLog Then LogColor($" ============ TERMINA MONTO BONIFICACION ========"$, Colors.RGB(151,0,171))
Return tsMonto
End Sub
' Recibe una lista con los ids de los productos variables, revisa cada id para traer los maximos por presupuesto para ese producto
' y pone ese maximo en una lista, luego ordena esa lista para obtener el mas chico y regresa ese como maximo.
' esta funcion se va a aplicar en la funcion maxpromos como un limite mas para que no muestre las promociones.
' NOTA: hay que ver como y cuando dejar de mostrar promociones cuando quede poco presupuesto para bonificaciones.
' NOTA: Talvez se pueda hacer que cuando se entre a PROMOS, si ya no hay presupuesto suficiente, mande un toast o msgbox diciendo que ya
' se agoto el presupuesto.
' Aunque si hay suficiente para mostrar algunas promos ... pues que si las muestre.
Sub maxPromosPorProdsVariables(idProdsVariables As List, promo As String)As Int
Private logger As Boolean = True
Private Maxs As Int = 10000000
Private elPrecio As String = 0
Private prodsVariablesXPresupuestoBonificaciones As List
Private prodsVariablesRequeridos As Int = traeProdsVariablesRequeridos(promo)
prodsVariablesXPresupuestoBonificaciones.Initialize
' LogColor("===========> Prods Variables: " & idProdsVariables.Size & " <==========", Colors.red)
For i = 0 To idProdsVariables.Size - 1 'Obtenemos total de productos variables disponibes.
If logger Then LogColor($"=>> prodVariable ${i} : ${idProdsVariables.Get(i)}, ${Subs.traeProdNombre(idProdsVariables.Get(i))} <<=="$, Colors.blue)
' Log($"Este invDisponible: ${invDispParaPromo.Get(idProdsVariables.Get(i))}"$)
' If logger Then Log(">> Monto Bonificacion: " & traeMontoBonificacion(idProdsVariables.Get(i), 1, promo))
Private ep As Cursor = Starter.skmt.ExecQuery($"select cat_dp_precio from cat_detalles_paq where cat_dp_id = '${promo}' and cat_dp_idprod = '${idProdsVariables.Get(i)}'"$)
If ep.RowCount > 0 Then
ep.Position = 0
Log("=========>>>> " & ep.GetString("CAT_DP_PRECIO"))
elPrecio = ep.GetString("CAT_DP_PRECIO")
End If
Private maxProds As Int = traeBonificacionesMaximas("bonificaciones", traeCliente, idProdsVariables.Get(i), prodsVariablesRequeridos, elPrecio, promo)
prodsVariablesXPresupuestoBonificaciones.Add(maxProds)
Next
prodsVariablesXPresupuestoBonificaciones.Sort(True)
If prodsVariablesXPresupuestoBonificaciones.Size > 0 Then
Maxs = prodsVariablesXPresupuestoBonificaciones.Get(0)
End If
If logger Then LogColor("=====>> Max prods variables x monto de bonificaciones: " & Maxs, Colors.blue)
Return Maxs
End Sub
' Regresa los productos variables requeridos de la promocion dada.
Sub traeProdsVariablesRequeridos(promo As String) As Int
Private pvr As Int = 0
Private c As Cursor = Starter.skmt.ExecQuery("Select CAT_GP_STS, CAT_GP_NOMBRE from CAT_GUNAPROD2 where CAT_GP_ID = '"& promo & "'") 'Obtenemos las piezas requeridas de productos variables para la promoción.
If c.RowCount > 0 Then
c.Position = 0
If c.RowCount > 0 Then
c.Position = 0
pvr = c.GetString("CAT_GP_STS")
End If
End If
c.Close
Return pvr
End Sub
'########################################################################################
' Los productos fijos NO estan restando del presupuesto de BONIFICACIONES
'########################################################################################
'Poner en una funcion (maxPromosPorProdsFijos) el codigo para traer las promos maximas por productos fijos, igual que la de productos
' variables, y ponerla igual en "traeMaxPromos" en lugar de en "revisaMaxPromosProdsFijosPorInventario".
' Falta el codigo para el funcionamiento diferente de las bonificaciones:
' Si CAT_DP_PRECIOB es 1 --> (Precio de original (cat_precio) - precio de venta) y se suma al acumulado de BONIFICACIONES
' Si CAT_DP_PRECIOB es 0 --> precio orginal se suma al acumulado de BONIFICACIONES
'Hay que traer desde web la columna "CAT_DP_PRECIOB" y gardarla en algun lado en movil!!

310
B4A/C_deviceLinker.bas Normal file
View File

@@ -0,0 +1,310 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=12.8
@EndOfDesignText@
'-----------------------------------------------------------------------------------
' Modulo de Clase: DeviceLinker.bas
' Propósito: Gestionar el GUID del dispositivo y verificar/ligar el dispositivo
' a un almacén y ruta en el servidor de forma segura.
'-----------------------------------------------------------------------------------
' Ejemplo de uso:
' ==== En config.properties ====
' sql.verify_device=Select nvl(CAT_RU_IDTELEFONO, 0) As CAT_RU_IDTELEFONO from kelloggs.CAT_RUTAS where cat_ru_idalmacen = ? And cat_ru_ruta = ?
' sql.registarMovil=update kelloggs.CAT_RUTAS set CAT_RU_IDTELEFONO = ? where cat_ru_idalmacen = ? And cat_ru_ruta = ?
' ==== En Class_Globals ====
' Dim linker As C_deviceLinker '<<<< Class_Globals
' ==== En B4XPage_Created ====
' linker.Initialize(Me, "Linker", True) '<<<<<< B4XPage_Created
' ==== En donde se quiera llamar ====
' linker.VerifyDevice(Subs.traeAlmacen, Subs.traeRuta)
' Sub Linker_Response(Status As String) ' << AÑADE ESTE SUB [New Query]
' If Starter.Logger Then LogColor($"Respuesta de DeviceLinker para la verificación del dispositivo: ${Status}"$, Colors.Magenta) '
' Select Status
' Case "OK"
' Log("########################################################")
' ToastMessageShow("Dispositivo verificado y vinculado correctamente.", False)
' ' Aquí puedes añadir lógica adicional si la verificación es exitosa, por ejemplo, habilitar ciertos botones o continuar con el flujo normal.
' Case "REGISTRO_COMPLETO"
' Log("########################################################")
' ToastMessageShow("¡Registro completo!", False)
' Case "SIN_REGISTRO"
' Log("########################################################")
' ToastMessageShow("¡Dispositivo sin registro!", False)
' linker.linkDevice(Subs.traeAlmacen, e_ruta.text) '<<<<<<<<< Si no esta registrado lo registramos.
' Case "REGISTRANDO"
' ToastMessageShow("¡Registro en proceso!", True)
' Case "YA_REGISTRADO"
' Log("########################################################")
' ToastMessageShow("¡¡El dispositivo ya esta registrado con otra ruta!!", True)
' Case Else ' Otros estados que tu servidor pueda devolver (ej. "UNAUTHORIZED", "PENDING_APPROVAL")
' Log("########################################################")
' ToastMessageShow($"Verificación del dispositivo: ${Status}"$, True)
' ' Puedes decidir si bloquear la funcionalidad o mostrar un mensaje específico según el estado.
' End Select
' End Sub
Sub Class_Globals
' Configuración del servidor y comandos
Private Const GUID_KEY_ALIAS As String = "DeviceGUID" ' << ALIAS PARA EL GUID EN EL KEYSTORE
' Objetos y variables internas
Private kvs As KeyValueStore ' << ALMACENAMIENTO SEGURO PARA EL GUID
Private CallBack As Object ' << OBJETO DE CALLBACK PARA ENVIAR RESPUESTAS
Private EventName As String ' << NOMBRE DEL EVENTO DE RESPUESTA
Public reqManager As DBRequestManager ' << GESTOR DE PETICIONES AL SERVIDOR jRDC
Private logger As Boolean ' << PARA CONTROLAR LOS LOGS DE ESTA CLASE
Dim lastJobDoneError As String = ""
Dim almacen As String = ""
Dim ruta As String = ""
Dim deviceId As String = ""
' Se requieren las siguientes librerías:
' - KeyValueStore2
' - DBRequestManager
' - XUI
Dim dlDB As SQL
End Sub
' Inicializa la clase DeviceLinker.
' PageObject: El módulo (ej. C_Principal) que inicializa esta clase y manejará sus respuestas (normalmente "Me").
' NameOfEvent: El prefijo para el evento de respuesta (ej. "DeviceLinker_Response").
' AppLogger: Booleano para activar/desactivar los logs internos de esta clase, siguiendo el Starter.Logger de la app.
Public Sub Initialize (PageObject As Object, NameOfEvent As String, AppLogger As Boolean)
CallBack = PageObject
EventName = NameOfEvent
logger = AppLogger ' Asignamos el estado del logger de la aplicación.
' Inicializamos el KeyValueStore para almacenamiento seguro del GUID
kvs.Initialize(File.DirInternal, "DeviceKeyStore.b4xkey")
If logger Then Log("B4XKeyStore 'DeviceKeyStore' inicializado.")
dlDB.Initialize(File.DirInternal, "deviceLink.db", True)
dlDB.ExecNonQuery("CREATE TABLE IF NOT EXISTS Registro (GUID_KEY_ALIAS TEXT)") ' Creamos la tabla si no existe
' Inicializamos el DBRequestManager para las comunicaciones con el servidor.
' 'Me' indica que el evento JobDone de esta clase se encargará de las respuestas de reqManager.
' reqManager.Initialize(Me, Starter.DBReqServer)
' reqManager.Initialize(Me, "http://keymon.net:9010/DB2") 'Servidor de pruebas
' reqManager.Initialize(Me, "http://keymon.net:1781") 'Servidor productivo
reqManager.Initialize(Me, Starter.DBReqServer) 'Servidor productivo
If logger Then Log("DBRequestManager para DeviceLinker inicializado.")
If logger Then Log("DeviceLinker inicializado y listo para operar.")
End Sub
' Verifica y liga el dispositivo con un almacén y una ruta en el servidor.
' Almacen: El identificador del almacén.
' Ruta: El identificador de la ruta.
Public Sub verifyDevice(Almacen_ As String, Ruta_ As String)
Private verificar As Boolean = True ' La verificacion se realiza por default
Private tv As Cursor = Starter.skmt.ExecQuery("select * from cat_variables where CAT_VA_DESCRIPCION = 'VERIFY_DEVICE'")
If tv.RowCount > 0 Then
tv.Position = 0
If tv.GetString("CAT_VA_VALOR") = 0 Then verificar = False
End If
If verificar Then ' Si VERIFY_DEVICE no está en CERO ... verificamos.
Dim DeviceId_ As String = GetDeviceGUID ' Obtenemos o generamos el GUID del dispositivo.
LogColor(DeviceId_, Colors.red)
almacen = Almacen_
ruta = Ruta_
deviceId = DeviceId_
If DeviceId_ = "" Then
If logger Then LogColor("Error: GUID del dispositivo no pudo ser obtenido o generado.", Colors.Red)
' Enviar una respuesta de error al callback si no se pudo obtener el GUID.
If SubExists(CallBack, EventName & "_Response") Then ' [New Query]
CallSub2(CallBack, EventName & "_Response", "GUID_ERROR") ' Dispara el evento Linker_Response("GUID_ERROR")
End If
Return
End If
If logger Then Log($"Enviando solicitud de verificación para DeviceId: ${DeviceId_}, Almacen: ${Almacen_}, Ruta: ${Ruta_}"$)
Dim cmd As DBCommand ' Creamos un comando para enviar al servidor.
cmd.Initialize
cmd.Name = "verify_device"
' Pasamos el almacén, la ruta y el GUID del dispositivo como parámetros.
cmd.Parameters = Array As Object(Almacen_, Ruta_) ', DeviceId_
Log($"Enviamos almacen: ${Almacen_} y ruta: ${Ruta_}"$)
' Ejecutamos el comando en el servidor. 'Me' indica que DBRequestManager_JobDone en esta clase manejará la respuesta.
reqManager.ExecuteQuery(cmd, 0, "verify_device")
Else ' Si está en CERO (Verificacion deshabilitada), regresamos "OK".
CallSub2(CallBack, EventName & "_Response", "OK")
End If
End Sub
Sub linkDevice(Almacen_ As String, Ruta_ As String)
Dim deviceId As String = GetDeviceGUID ' Obtenemos o generamos el GUID del dispositivo.
Log("########################################################")
Log("REGISTRANDO")
Dim cmd As DBCommand ' Creamos un comando para enviar al servidor.
cmd.Initialize
cmd.Name = "registarMovil"
' Pasamos el almacén, la ruta y el GUID del dispositivo como parámetros.
cmd.Parameters = Array As Object(deviceId, Almacen_, Ruta_)
reqManager.ExecuteCommand(cmd, "registramosGUID")
If SubExists(CallBack, EventName & "_Response") Then
CallSub2(CallBack, EventName & "_Response", "REGISTRANDO") ' Dispara el evento Linker_Response("REGISTRANDO")
End If
End Sub
'244500
' Obtiene el GUID único del dispositivo desde B4XKeyStore.
' Si no existe, lo genera y lo guarda utilizando Subs.GUID.
Private Sub GetDeviceGUID As String
' If kvs.ContainsKey(GUID_KEY_ALIAS) = False Then
' ' Corrección: Usamos la función GUID ya existente en el módulo Subs [1].
' Dim NewGUID As String = generaGUID
' kvs.Put(GUID_KEY_ALIAS, NewGUID) ' Lo guardamos de forma segura en el KeyStore.
' If logger Then LogColor($"Nuevo GUID generado y guardado: ${NewGUID}"$, Colors.Blue)
' Return NewGUID
' Else
' Dim ExistingGUID As String = kvs.Get(GUID_KEY_ALIAS) ' Recuperamos el GUID existente.
' If logger Then LogColor($"GUID existente cargado: ${ExistingGUID}"$, Colors.Blue)
' Return ExistingGUID
' End If
If deviceLinked = False Then
' Corrección: Usamos la función GUID ya existente en el módulo Subs [1].
Dim NewGUID As String = generaGUID
dlDB.ExecNonQuery($"insert into registro ('GUID_KEY_ALIAS') values ('${NewGUID}')"$) ' Guardamos nuevo registro
If logger Then LogColor($"Nuevo GUID generado y guardado: ${NewGUID}"$, Colors.Blue)
Return NewGUID
Else
Dim ExistingGUID As String
Private e As Cursor = dlDB.ExecQuery("select GUID_KEY_ALIAS from registro")
e.Position = 0
ExistingGUID = e.GetString("GUID_KEY_ALIAS")
If logger Then LogColor($"GUID existente cargado: ${ExistingGUID}"$, Colors.Blue)
Return ExistingGUID
End If
End Sub
' Callback para manejar las respuestas del DBRequestManager de esta clase.
Public Sub JobDone(Job As HttpJob) ' El nombre del sub debe ser 'JobDone' o el que se haya especificado en reqManager.Initialize(Me, ApiUrl)
If logger Then Log("INICA JOBDONE DEVICELINKER - " & Job.Tag)
If reqManager.reqsList.IsInitialized Then 'Si tenemos lista de requests, la procesamos.
If reqManager.reqsList.IndexOf(Job.tag) <> -1 Then
reqManager.reqsList.RemoveAt(reqManager.reqsList.IndexOf(Job.tag))
LogColor($">>>>>> Recibimos y quitamos ${Job.tag.As(String).ToUpperCase}"$, Colors.Blue)
End If
LogColor(">>>>>> " & reqManager.reqsList.Size & " - " & reqManager.reqsList, Colors.Blue)
End If
If Job.Success = False Then
lastJobDoneError = Job.ErrorMessage
LogColor("############################################", Colors.red)
LogColor("###### JobError: " & Job.Tag & " ######" & CRLF & "#### " & Job.ErrorMessage, Colors.red)
LogColor("############################################", Colors.red)
' Enviar una respuesta de error HTTP al callback.
If SubExists(CallBack, EventName & "_Response") Then
CallSub2(CallBack, EventName & "_Response", "HTTP_ERROR") ' Dispara el evento Linker_Response("HTTP_ERROR")
End If
Else 'If Job Success then ...
lastJobDoneError = ""
If Job.JobName = "DBRequest" Then ' Asegurarse de que sea una respuesta de DBRequestManager.
' Primero verificamos Job.Success para saber si la comunicación HTTP fue exitosa [New Query]
If Job.Success Then
Dim result As DBResult = reqManager.HandleJob(Job) ' Procesamos el HttpJob para obtener el DBResult.
If logger Then LogColor($"Petición exitosa al servidor. Registros devueltos: ${result.Rows.Size}"$, Colors.Green)
' If result.Tag = "hist_cliente_promos" Then 'query tag
' Starter.skmt.BeginTransaction
' For Each records() As Object In result.Rows
' Dim HCCP_CLIENTE As String = records(result.Columns.Get("HCCP_CLIENTE"))
' Starter.skmt.ExecNonQuery2("INSERT INTO HIST_CLIENTE_CANT_PROMOS(HCCP_CLIENTE, HCCP_PROMO, HCCP_CANT, HCCP_CANT_VENDIDA) VALUES (?,?,?,?)", Array As Object (HCCP_CLIENTE))
' Next
' Starter.skmt.TransactionSuccessful
' Starter.skmt.EndTransaction
' ' ToastMessageShow(" Historico Clientes Promociones Actualizado." , True)
' End If
If result.Tag = "verify_device" Then 'query tag
' Aquí es donde la lógica de la aplicación interpreta el éxito/falla de la operación en el servidor.
If result.Rows.Size > 0 Then
Subs.logJobDoneResultados(result)
For Each records() As Object In result.Rows
Dim Status As String = "" 'records(result.Columns.Get("ESTATUS"))
Dim CAT_RU_IDTELEFONO As String = records(result.Columns.Get("CAT_RU_IDTELEFONO"))
deviceId = GetDeviceGUID
Log($"|${deviceId}|${CAT_RU_IDTELEFONO}|"$)
' If deviceId <> CAT_RU_IDTELEFONO Then Status = "YA_REGISTRADO" ' Ya existe OTRO registro.
If CAT_RU_IDTELEFONO = 0 Or CAT_RU_IDTELEFONO.Length < 5 Then
Status = "SIN_REGISTRO"
' Log("########################################################")
' Log("REGISTRANDO")
' Dim cmd As DBCommand ' Creamos un comando para enviar al servidor.
' cmd.Initialize
' cmd.Name = "registarMovil"
' ' Pasamos el almacén, la ruta y el GUID del dispositivo como parámetros.
' cmd.Parameters = Array As Object(deviceId, almacen, ruta)
' reqManager.ExecuteCommand(cmd, "registramosGUID")
If SubExists(CallBack, EventName & "_Response") Then
CallSub2(CallBack, EventName & "_Response", "SIN_REGISTRO")
End If
else if CAT_RU_IDTELEFONO = deviceId Then
Status = "OK"
Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("LIGADO"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("LIGADO", 1))
Log("OK")
LogColor("######### GUARDAMOS ###########", Colors.red)
Else
Status = "YA_REGISTRADO"
Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("LIGADO"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("LIGADO", 0))
Log("YA_REGISTRADO")
LogColor("######### GUARDAMOS ###########", Colors.red)
End If
' Invocamos el callback en el módulo principal con el estado.
Next
Else
Status = "NO_EXISTE_RUTA"
End If
If SubExists(CallBack, EventName & "_Response") Then
CallSub2(CallBack, EventName & "_Response", Status) ' Dispara el evento Linker_Response("OK") o Linker_Response("YA_REGISTRADO")
End If
End If
If result.Tag = "registramosGUID" Then
Log("########################################################")
Log("REGISTRO_COMPLETO")
LogColor("######### GUARDAMOS ###########", Colors.red)
Subs.logJobDoneResultados(result)
Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("LIGADO"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("LIGADO", 1))
If SubExists(CallBack, EventName & "_Response") Then
CallSub2(CallBack, EventName & "_Response", "REGISTRO_COMPLETO") ' Dispara el evento Linker_Response("REGISTRO_COMPLETO")
End If
End If
End If
End If
Job.Release ' Muy importante liberar el HttpJob para evitar fugas de memoria.
End If
End Sub
'Genera un GUID (globally unique identifier)
Sub generaGUID As String
Dim sb As StringBuilder
sb.Initialize
For Each stp As Int In Array(8, 4, 4, 4, 12)
If sb.Length > 0 Then sb.Append("-")
For n = 1 To stp
Dim c As Int = Rnd(0, 16)
If c < 10 Then c = c + 48 Else c = c + 55
sb.Append(Chr(c))
Next
Next
Return sb.ToString
End Sub
'Regresa true si existe registro
Sub deviceLinked As Boolean
Private e As Cursor = dlDB.ExecQuery("select * from registro")
If e.RowCount > 0 Then
Return True
Else
Return False
End If
End Sub

View File

@@ -1,360 +0,0 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=6.8
@EndOfDesignText@
''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

View File

@@ -1,201 +0,0 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=6.8
@EndOfDesignText@
'Requires support for resumable subs
'Class module
Sub Class_Globals
Private mTarget As Object
Private link As String
Private VERSION As Float = 2
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) As HttpJob
Dim ser As B4XSerializator
Dim data() As Byte = ser.ConvertObjectToBytes(CreateMap("command": Command, "limit": Limit, "version": VERSION))
Return SendJob(CreateJob, data, Tag, "query2")
End Sub
Private Sub SendJob(j As HttpJob, Data() As Byte, Tag As Object, Method As String) As HttpJob
j.Tag = Tag
j.PostBytes(link & "?method=" & Method , Data)
Return j
End Sub
Private Sub CreateJob As HttpJob
Dim j As HttpJob
j.Initialize("DBRequest", mTarget)
Return j
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) As HttpJob
Dim j As HttpJob = CreateJob
ExecuteBatchImpl(j, ListOfCommands, Tag)
Return j
End Sub
Private Sub ExecuteBatchImpl(Job As HttpJob, ListOfCommands As List, Tag As Object)
Dim ser As B4XSerializator
ser.ConvertObjectToBytesAsync(CreateMap("commands": ListOfCommands, "version": VERSION), "ser")
Wait For (ser) ser_ObjectToBytes (Success As Boolean, Bytes() As Byte)
If Success = False Then
Log("Error building command: " & LastException)
Return
End If
Dim ser As B4XSerializator = Sender
SendJob(Job, Bytes, Tag, "batch2")
End Sub
'Similar to ExecuteBatch. Sends a single command.
Public Sub ExecuteCommand(Command As DBCommand, Tag As Object) As HttpJob
Return ExecuteBatch(Array As DBCommand(Command), Tag)
End Sub
'Handles the Job result and returns a DBResult.
'It is recommended to use HandleJobAsync instead.
Public Sub HandleJob(Job As HttpJob) As DBResult
Dim ser As B4XSerializator
Dim data() As Byte = Bit.InputStreamToBytes(Job.GetInputStream)
Dim res As DBResult = ser.ConvertBytesToObject(data)
res.Tag = Job.Tag
Return res
End Sub
'Handles the Job result and raises the Result event when the data is ready.
Public Sub HandleJobAsync(Job As HttpJob, EventName As String)
Dim ser As B4XSerializator
Dim data() As Byte = Bit.InputStreamToBytes(Job.GetInputStream)
ser.ConvertBytesToObjectAsync(data, "ser")
Wait For (ser) ser_BytesToObject (Success As Boolean, NewObject As Object)
If Success = False Then
Log("Error reading response: " & LastException)
Return
End If
Dim res As DBResult = NewObject
res.Tag = Job.Tag
CallSubDelayed2(mTarget, EventName & "_result", res)
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
#if Not(B4J)
'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
#End If
'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

156
B4A/DBRequestManagerW.bas Normal file
View File

@@ -0,0 +1,156 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=12.8
@EndOfDesignText@
'#######################################################################################
' Módulo de Clase: jRDC1Wrapper
' Versión: 1.9.2 - Thread-Safe, Async Support, B4A Memory Safe, State Persistent & Dynamic Link Support
' Autor: Cheve (José Alberto)
'
' DESCRIPCIÓN:
' Este módulo actúa como un "Wrapper" (envoltorio) especializado para DBRequestManager
' en entornos jRDC1. Su objetivo principal es modernizar el flujo de trabajo de
' versiones antiguas de B4X, permitiendo el uso de la sintaxis "Wait For" en lugar
' de depender exclusivamente del evento JobDone global.
'
' Ejemplo de uso:
' Dim reqManagerW As DBRequestManagerW
' reqManagerW.Initialize
' cmd.Initialize
' cmd.Name = "selectAlgoDeAlgunLado"
' cmd.Parameters = Array As Object(user.Text, pass.Text)
' reqManagerW.ExecuteQuery(Starter.DBReqServer, cmd, Me, "loSeleccionado")
' Wait For loSeleccionado_Completed (res1 As TResultado)
' Log("tag: " & res1.tag & " Success: " & res1.Success)
' If res1.Success Then
' Subs.logJobDoneResultados(res1.resultado)
' Else
' Log(res1.ErrorMessage)
' End If
'#######################################################################################
Public Sub Class_Globals
Type TResultado(Tag As String, Success As Boolean, resultado As DBResult, ErrorMessage As String)
Type TJobInfo (Target As Object, EventName As String, IsQuery As Boolean)
Private activeJobs As Map
Private jobCounter As Int
Private logger As Boolean = False
' Instancia centralizada.
Private reqManager As DBRequestManager
' Rastreo del EndPoint activo para evitar reinicializaciones redundantes
Private currentActiveLink As String = ""
End Sub
Public Sub Initialize
If activeJobs.IsInitialized = False Then
activeJobs.Initialize
End If
jobCounter = 0
currentActiveLink = ""
End Sub
Public Sub ExecuteQuery(rdcLink As String, Command As DBCommand, Target As Object, Event As String)
jobCounter = jobCounter + 1
Dim currentJobTag As String = $"reqManagerWJob_${DateTime.Now}_${jobCounter}"$
If logger Then Log($"ExecuteQuery (Tag: ${currentJobTag}): Command=${Command.Name}, Event=${Event}"$)
' Actualización dinámica de EndPoint solo si el Link cambió
If reqManager.IsInitialized = False Or currentActiveLink <> rdcLink Then
reqManager.Initialize(Me, rdcLink)
currentActiveLink = rdcLink
End If
Dim jobInfo As TJobInfo
jobInfo.Initialize
jobInfo.Target = Target
jobInfo.EventName = Event
jobInfo.IsQuery = True
activeJobs.Put(currentJobTag, jobInfo)
reqManager.ExecuteQuery(Command, 0, currentJobTag)
End Sub
Public Sub ExecuteCommand(rdcLink As String, Command As DBCommand, Target As Object, Event As String)
jobCounter = jobCounter + 1
Dim currentJobTag As String = $"reqManagerWJob_${DateTime.Now}_${jobCounter}"$
If logger Then Log($"ExecuteCommand (Tag: ${currentJobTag}): Command=${Command.Name}, Event=${Event}"$)
' Actualización dinámica de EndPoint solo si el Link cambió
If reqManager.IsInitialized = False Or currentActiveLink <> rdcLink Then
reqManager.Initialize(Me, rdcLink)
currentActiveLink = rdcLink
End If
Dim jobInfo As TJobInfo
jobInfo.Initialize
jobInfo.Target = Target
jobInfo.EventName = Event
jobInfo.IsQuery = False
activeJobs.Put(currentJobTag, jobInfo)
reqManager.ExecuteCommand(Command, currentJobTag)
End Sub
Public Sub JobDone(job As HttpJob)
If logger Then Log("===== JDDBRW =====")
Dim currentJobTag As String = ""
Try
If job <> Null And job.Tag <> Null And job.Tag Is String Then
currentJobTag = job.Tag
End If
If activeJobs.ContainsKey(currentJobTag) Then
Dim jobInfo As TJobInfo = activeJobs.Get(currentJobTag)
Dim res As TResultado
res.Initialize
res.Tag = jobInfo.EventName
If job.Success Then
Dim dbResult As DBResult = reqManager.HandleJob(job)
If logger Then LogColor("JobDone: '" & dbResult.tag & "' - Registros: " & dbResult.Rows.Size, Colors.Green)
res.Success = True
res.resultado = dbResult
res.ErrorMessage = ""
Else
res.Success = False
res.resultado = Null
res.ErrorMessage = job.ErrorMessage
End If
activeJobs.Remove(currentJobTag)
If logger Then LogColor($"EVENTO: ${jobInfo.EventName}_Completed"$, Colors.Magenta)
CallSubDelayed2(jobInfo.Target, jobInfo.EventName & "_Completed", res)
Else
If logger Then Log($"JobDone: Job descartado (Tag desconocido o nulo): ${currentJobTag}"$)
End If
Catch
If logger Then LogColor("Error Crítico en jRDC1Wrapper.JobDone: " & LastException, Colors.Red)
If currentJobTag <> "" And activeJobs.ContainsKey(currentJobTag) Then
Dim jobInfo As TJobInfo = activeJobs.Get(currentJobTag)
Dim resErr As TResultado
resErr.Initialize
resErr.Tag = jobInfo.EventName
resErr.Success = False
resErr.ErrorMessage = "Error interno procesando la respuesta DB: " & LastException.Message
activeJobs.Remove(currentJobTag)
CallSubDelayed2(jobInfo.Target, jobInfo.EventName & "_Completed", resErr)
End If
End Try
If job <> Null Then job.Release
End Sub

Binary file not shown.

BIN
B4A/Files/compra_y_gana.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
B4A/Files/qr_kelloggs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -24,6 +24,9 @@ ModuleBookmarks29=
ModuleBookmarks3=
ModuleBookmarks30=
ModuleBookmarks31=
ModuleBookmarks32=
ModuleBookmarks33=
ModuleBookmarks34=
ModuleBookmarks4=
ModuleBookmarks5=
ModuleBookmarks6=
@@ -56,6 +59,9 @@ ModuleBreakpoints29=
ModuleBreakpoints3=
ModuleBreakpoints30=
ModuleBreakpoints31=
ModuleBreakpoints32=
ModuleBreakpoints33=
ModuleBreakpoints34=
ModuleBreakpoints4=
ModuleBreakpoints5=
ModuleBreakpoints6=
@@ -66,11 +72,11 @@ ModuleClosedNodes0=
ModuleClosedNodes1=
ModuleClosedNodes10=
ModuleClosedNodes11=
ModuleClosedNodes12=3,7,8,9,10,11,12
ModuleClosedNodes13=6,7,8,9,10,11,12,13,14,16,17
ModuleClosedNodes12=
ModuleClosedNodes13=42,43
ModuleClosedNodes14=
ModuleClosedNodes15=
ModuleClosedNodes16=
ModuleClosedNodes16=2,7,8,9
ModuleClosedNodes17=
ModuleClosedNodes18=
ModuleClosedNodes19=
@@ -79,21 +85,24 @@ ModuleClosedNodes20=
ModuleClosedNodes21=
ModuleClosedNodes22=
ModuleClosedNodes23=
ModuleClosedNodes24=4,24,25,26,27,31,32,33,35
ModuleClosedNodes24=
ModuleClosedNodes25=
ModuleClosedNodes26=4
ModuleClosedNodes26=
ModuleClosedNodes27=
ModuleClosedNodes28=
ModuleClosedNodes29=
ModuleClosedNodes3=5,6,7
ModuleClosedNodes30=115
ModuleClosedNodes3=
ModuleClosedNodes30=3
ModuleClosedNodes31=
ModuleClosedNodes4=
ModuleClosedNodes32=
ModuleClosedNodes33=
ModuleClosedNodes34=
ModuleClosedNodes4=1,3
ModuleClosedNodes5=
ModuleClosedNodes6=
ModuleClosedNodes7=
ModuleClosedNodes8=
ModuleClosedNodes9=
NavigationStack=C_Clientes,Class_Globals,23,0,C_Clientes,B_IMP_Click,236,0,C_Cliente,B4XPage_Created,316,0,B4XMainPage,B4XPage_Created,155,1,C_Principal,JobDone,1064,0,Diseñador Visual,cliente.bal,-100,3,C_Cliente,B_IMP_Click,1138,0,Subs,ponImpreso,658,0,C_Cliente,Imprime_ticket,1210,6,kms_helperSubs,RD_respalda_kmt_info,362,0,kms_helperSubs,RD_Init,94,4
NavigationStack=Subs,parseHTTPError,2013,0,C_Principal,revisaHistNotificaciones,2355,6,C_Principal,enviaHistNotificaciones,2325,6,C_NuevoCliente,Class_Globals,2,0,B4XMainPage,i_engranes_LongClick,745,0,DBRequestManagerW,ExecuteQuery,50,0,DBRequestManagerW,Initialize,42,0,DBRequestManagerW,JobDone,135,6,DBRequestManagerW,Class_Globals,20,0,DBRequestManagerW,ExecuteCommand,105,0
SelectedBuild=0
VisibleModules=1,29,11,3,30,13,12,7,27,26,24,4
VisibleModules=32,1,13,4,33,16,34,14,15,24,22

View File

@@ -115,6 +115,7 @@ Sub Activity_Create(FirstTime As Boolean)
End Sub
Sub Activity_Resume
B4XPages.MainPage.aud.guarda("Entrada a MapaRutas")
If GPS.GPSEnabled = False Then
ToastMessageShow("Debe Activar el GPS del Equipo.", True)
StartActivity(GPS.LocationSettingsIntent)
@@ -186,9 +187,9 @@ Sub MapFragment1_Ready
Next
c2 .Close
End If
'''''''---------------------------- MARKER ROJO - NO VENTA
If rojo =1 Or todos = 1 Then
c3.IsInitialized
c3=Starter.skmt.ExecQuery("select CAT_CL_CODIGO, CAT_CL_NOMBRE,CAT_CL_LONG,CAT_CL_LAT ,CAT_CL_NUM_SERIEFISICO from kmt_info where CAT_CL_NOMBRE <>'VENTA ABORDO' AND CAT_CL_CODIGO In (Select NV_CLIENTE from NOVENTA ) AND CAT_CL_CODIGO NOT IN (Select PE_CLIENTE from PEDIDO) and CAT_CL_DIAS_VISITA = (SELECT CAT_VA_VALOR FROM CAT_VARIABLES WHERE CAT_VA_DESCRIPCION = 'DIA_VISITA')order by CAT_CL_NUM_SERIEFISICO")
@@ -200,7 +201,8 @@ Sub MapFragment1_Ready
CODIGO=c3.GetString("CAT_CL_CODIGO")
Tienda= c3.GetString("CAT_CL_NOMBRE")
NumSerie=c3.GetInt("CAT_CL_NUM_SERIEFISICO")
MARK_ROJO = gmap.AddMarker3(LatitudRU,LongitudRU,CODIGO, LoadBitmap(File.DirAssets, "marker-rojo-" & NumSerie &".png"))
' MARK_ROJO = gmap.AddMarker3(LatitudRU,LongitudRU,CODIGO, LoadBitmap(File.DirAssets, "marker-rojo-" & NumSerie &".png"))
MARK_ROJO = gmap.AddMarker3(LatitudRU, LongitudRU, CODIGO, CreateBitmapWithNumber(LoadBitmap(File.DirAssets, "marker-rojo.png"), NumSerie))
MARK_ROJO.Snippet = Tienda
Next
c3.Close
@@ -231,6 +233,7 @@ Sub OnInfoWindowClickListener1_click(Marker1 As Marker)
Starter.skmt.ExecNonQuery("delete from CUENTAA")
Starter.skmt.ExecNonQuery2("INSERT INTO CUENTAA VALUES (?) ", Array As Object(Marker1.Title))
Activity.Finish
B4XPages.MainPage.aud.guarda($"Clic Tooltip Mapas Ruta: ${Marker1.Title}"$)
Subs.iniciaActividad("Cliente")
End Sub

View File

@@ -1,587 +0,0 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=12.8
@EndOfDesignText@
Sub Class_Globals
Dim ruta As String
Dim almacen As String
Dim cliente As String
Dim db As SQL
Private EventName As String 'ignore
Private CallBack As Object 'ignore
Dim tablaProds As String
Dim muestraLogs As Boolean
Dim releaseMode As Boolean
End Sub
'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize (vCallback As Object, vEventName As String, db0 As SQL) As Object
EventName = vEventName
CallBack = vCallback
db = db0
' Log("PROMOS INIT")
db.ExecNonQuery("CREATE TABLE IF NOT EXISTS PROMOCIONES_INFO (P_ID TEXT, P_ESTATUS TEXT, P_MAXXCLIENTE NUMERIC, P_MAXRECURRENTE NUMERIC, P_MAXPROMOS NUMERIC, HISTORICO TEXT, P_TIPOS TEXT, P_PRODSFIJOS TEXT, P_PRODSFIJOS_CANT NUMERIC, P_PRODSFIJOS_PIEZAS TEXT, P_PRODSFIJOS_PRECIOS TEXT, P_PRODSVARIABLES TEXT, P_PRODSVARIABLES_CANT NUMERIC, P_PRODSVARIABLES_PRECIOS TEXT, P_PRODSVARIABLES_REQUERIDOS NUMERIC)")
db.ExecNonQuery("DELETE FROM PROMOCIONES_INFO")
#if RELEASE
releaseMode = True
#Else if DEBUG
releaseMode = False
#end if
Return Me
End Sub
Sub procesaPromocion(idPromo As String, cliente0 As String, tipoVenta As String) As Map 'ignore
'######################################################
muestraLogs = True ' Si es verdadero, se muestran los logs de la clase.
'######################################################
If releaseMode Then muestraLogs = False
cliente = cliente0
' Private inicioContador As String = DateTime.Now
Private maxPromos As Int = 0
Private maxPromosXFijos As Int = 0
tablaProds = "cat_gunaprod2"
If tipoVenta = "ABORDO" Or tipoVenta = "PREVENTA" Then tablaProds = "cat_gunaprod"
If muestraLogs Then LogColor($"**********************************************************************"$, Colors.Green)
If muestraLogs Then LogColor($"********* INICIAMOS REVISION DE PROMO ${idPromo} *********"$, Colors.Green)
If muestraLogs Then LogColor($"**********************************************************************"$, Colors.Green)
' LogColor("**************************** " & traeInfoDePromo("P_PRODSFIJOS", idPromo), Colors.blue)
traePromo(idPromo, cliente0) ' Generamos la tabla con la información d la promoción.
maxPromosXFijos = revisaMaxPromosProdsFijosPorInventario(idPromo)
If maxPromosXFijos < 1 Then
db.ExecNonQuery($"update PROMOCIONES_INFO set P_ESTATUS = 'ko' where P_ID = '${idPromo}'"$)
End If
Private logColor1 As String
If traeInfoDePromo("P_ESTATUS", idPromo) = "ok" Then logColor1 = Colors.RGB(0,143,0) Else logColor1 = Colors.Red
If muestraLogs And traeInfoDePromo("P_ESTATUS", idPromo) = "ok" Then LogColor($"### MAX PROMOS X FIJOS = ${maxPromosXFijos}"$, logColor1)
If traeInfoDePromo("P_ESTATUS", idPromo) = "ok" Then 'Si encontramos la promoción, entonces ...
maxPromos = traeMaxPromos(idPromo) ' Buscamos el máximo de promociones permitidas.
If muestraLogs Then LogColor($"Promociones permitidas=${maxPromos}"$, Colors.Blue)
' If muestraLogs Then Log("Promos vendidas: " & traePromosVendidas(idPromo))
If maxPromos < 1 Then
If muestraLogs Then LogColor("Ya se vendieron las promos PERMITIDAS para el cliente", Colors.red)
Return CreateMap("status":"ko") ' , "mp":pm
End If
'👇🏼 Restamos del inventario (mapa) las piezas necesarias para los productos fijos. 👇🏼
Private inventarioSinFijos As Map = restaFijosDePromo(idPromo)
If muestraLogs Then LogColor("inventarioSinFijos="&inventarioSinFijos, Colors.Magenta)
If inventarioSinFijos.Get("resultado") = "ok" Then
'Revisamos que los productos variables requeridos sean menos que el inventario total (mapa).
Private pv As Boolean = alcanzanLosVariablesParaPromo(idPromo, inventarioSinFijos)
If pv Then logColor1 = Colors.RGB(0,143,0) Else logColor1 = Colors.Red
If muestraLogs And pv Then
LogColor("### ALCANZAN LOS VARIABLES? --> " & pv, logColor1)
End If
' LogColor("TIEMPO DE PROCESO ESTA PROMO: " & ((DateTime.Now-inicioContador)/1000), Colors.Red)
If pv Then
Return CreateMap("status":"ok", "prodsFijosCant":traeInfoDePromo("P_PRODSFIJOS_CANT", idPromo), "prodsVariablesCant":traeInfoDePromo("P_PRODSVARIABLES_CANT", idPromo))
Else
If muestraLogs Then LogColor("NO HAY INVENTARIO SUFICIENTE " & idPromo, Colors.red)
Return CreateMap("status":"ko")
End If
Else
If muestraLogs Then LogColor("NO HAY INVENTARIO SUFICIENTE " & idPromo, Colors.red)
' LogColor("TIEMPO DE PROCESO ESTA PROMO: " & ((DateTime.Now-inicioContador)/1000), Colors.Red)
Return CreateMap("status":"ko")
End If
Else
If muestraLogs Then LogColor("NO HAY INVENTARIO SUFICIENTE " & idPromo, Colors.red)
' LogColor("TIEMPO DE PROCESO ESTA PROMO: " & ((DateTime.Now-inicioContador)/1000), Colors.Red)
Return CreateMap("status":"ko") ' , "mp":pm
End If
' Si tenemos suficiente inventario para los variables mostramos la promocion, si no ...
' break 'NO HAY INVENTARIO SUFICIENTE PARA LA PROMOCION.
End Sub
'Genera una tabla (PROMOCIONES_INFO) con la información de la promo.
'Columnas: P_ID, P_MAXXCLIENTE, P_MAXRECURRENTE, P_MAXPROMOS, HISTORICO,
' P_TIPOS={idProducto=tipo} 'Mapa con id y tipo del producto, 0 si es fijo y 1 si es variable.
' P_PRODSFIJOS=[idProducto,idProducto] 'Lista con los ids de los productos fijos.
' P_PRODSVARIABLES=[idProducto,idProducto] 'Lista con los ids de los productos variables.
' P_ESTATUS="OK" 'Ok si existe la promocion.
' P_PRODSVARIABLES_REQUERIDOS=5 'Cantidad de productos variables requeridos para la promoción.
Sub traePromo(promo As String, cliente0 As String) As Map
'######################################################
muestraLogs = True ' Si es verdadero, se muestran los logs de la clase.
'######################################################
If releaseMode Then muestraLogs = False
If muestraLogs Then LogColor("> TraePromo: " & promo, Colors.blue)
' Private inicioContador As String = DateTime.Now
Private c As Cursor = Starter.skmt.ExecQuery("Select * from promos_comp where cat_pa_id = '"& promo&"'") 'Obtenemos las el maximo de promocioones a otorgar.
Private siHistorico As String = 0
Private promoMap As Map
Private prodsFijos, prodsFijosPrecios, prodsFijosReq, prodsVariables, prodsVariablesPrecios As List
promoMap.Initialize
prodsFijos.Initialize
prodsFijosPrecios.Initialize
prodsFijosReq.Initialize
prodsVariables.Initialize
prodsVariablesPrecios.Initialize
c.Position = 0
' promoMap = CreateMap("id":promo, "maxXcliente":0, "maxRecurrente":0, "maxPromos":0) 'Ponemos el DEFAULT en CERO.
Private yaExistePromo As Cursor = db.ExecQuery($"SELECT P_ID from PROMOCIONES_INFO where P_ID = '${promo}'"$)
If yaExistePromo.RowCount > 0 Then
db.ExecNonQuery($"update PROMOCIONES_INFO set P_MAXXCLIENTE = 0, P_MAXRECURRENTE = 0, P_MAXPROMOS = 0 where P_ID = '${promo}'"$)
Else
db.ExecNonQuery($"insert into PROMOCIONES_INFO (P_ID, P_MAXXCLIENTE, P_MAXRECURRENTE, P_MAXPROMOS) values ('${promo}', 0, 0, 0)"$)
End If
If c.RowCount > 0 Then
' promoMap = CreateMap("id":promo, "maxXcliente":c.GetString("CAT_PA_MAXPROMCLIE"), "maxRecurrente":c.GetString("CAT_PA_MAXPROMREC"), "maxPromos":c.GetString("CAT_PA_MAXPROM"))
db.ExecNonQuery($"update PROMOCIONES_INFO set P_MAXXCLIENTE = ${c.GetInt("CAT_PA_MAXPROMCLIE")}, P_MAXRECURRENTE = ${c.GetInt("CAT_PA_MAXPROMREC")}, P_MAXPROMOS = ${c.GetInt("CAT_PA_MAXPROM")} where P_ID = '${promo}'"$)
' Log($"update PROMOCIONES_INFO set P_MAXXCLIENTE = ${c.GetInt("CAT_PA_MAXPROMREC")}, P_MAXRECURRENTE = ${c.GetInt("CAT_PA_MAXPROMREC")}, P_MAXPROMOS = ${c.GetInt("CAT_PA_MAXPROM")} where P_ID = '${promo}'"$)
End If
'######### PROMOCIONES SEGMENTADAS ##########
' Si la promo esta en la lista, SOLO los clientes que la tengan la pueden ver.
Private ps As Cursor = Starter.skmt.ExecQuery($"select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${cliente0}' "$)
' Log($"select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${cliente0}' "$)
If muestraLogs Then Log($"PROMOS SEGMENTADAS DISPONIBLES: ${ps.RowCount}"$)
If ps.RowCount > 0 Then
ps.Position = 0
db.ExecNonQuery($"update PROMOCIONES_INFO set P_MAXXCLIENTE = 0, P_MAXRECURRENTE = 0, P_MAXPROMOS = 0 where P_ID = '${promo}'"$) 'Si es segmentada la ponemos en cero, porque SOLO le debe de aparecer a ciertos clientes.
' promoMap = CreateMap("id":promo, "maxXcliente":0, "maxRecurrente":0, "maxPromos":0) 'Si es segmentada la ponemos en cero, porque SOLO le debe de aparecer a ciertos clientes.
If muestraLogs Then LogColor($">>> PROMO "${promo}" SEGMENTADA PARA EL CLIENTE ${ps.GetString("HCCP_CLIENTE")}"$, Colors.Magenta)
' Select hccp_cliente As valido from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${traecliente}'
Private ps2 As Cursor = Starter.skmt.ExecQuery($"Select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${cliente0}' and HCCP_CANT > HCCP_CANT_VENDIDA"$)
' Log($"Select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${traeCliente}' and HCCP_CANT > HCCP_CANT_VENDIDA"$)
If muestraLogs Then Log($"registros:${ps2.RowCount}"$)
If ps2.RowCount > 0 Then
ps2.Position = 0
' Log($"registros:${ps2.RowCount}, cliente: ${ps2.GetString("HCCP_CLIENTE")} cant:${ps2.GetString("HCCP_CANT")}, Vendidas: ${ps2.GetString("HCCP_CANT_VENDIDA")}"$)
db.ExecNonQuery($"update PROMOCIONES_INFO set P_MAXXCLIENTE = ${(ps2.getint("HCCP_CANT")-ps2.GetInt("HCCP_CANT_VENDIDA"))}, P_MAXRECURRENTE = ${ps2.GetString("HCCP_CANT")}, P_MAXPROMOS = ${ps2.GetString("HCCP_CANT")} where P_ID = '${promo}'"$) 'Si es segmentada SOLO le aparece a ciertos clientes.
' Log($"update PROMOCIONES_INFO set P_MAXXCLIENTE = ${(ps2.GetString("HCCP_CANT")-ps2.GetString("HCCP_CANT_VENDIDA"))}, P_MAXRECURRENTE = ${ps2.GetString("HCCP_CANT")}, P_MAXPROMOS = ${ps2.GetString("HCCP_CANT")} where P_ID = '${promo}'"$)
' promoMap = CreateMap("id":promo, "maxXcliente":(ps2.GetString("HCCP_CANT")-ps2.GetString("HCCP_CANT_VENDIDA")), "maxRecurrente":ps2.GetString("HCCP_CANT"), "maxPromos":ps2.GetString("HCCP_CANT")) 'Si es segmentada SOLO le aparece a ciertos clientes.
End If
End If
' Log(promoMap)
' Log($"P_MAXXCLIENTE = ${(ps2.GetString("HCCP_CANT")-ps2.GetString("HCCP_CANT_VENDIDA"))}, P_MAXRECURRENTE = ${ps2.GetString("HCCP_CANT")}, P_MAXPROMOS = ${ps2.GetString("HCCP_CANT")}'"$)
' ########## TERMINA PROMOS SEGMENTADAS ##########
c = Starter.skmt.ExecQuery("Select count(*) as hist from HIST_PROMOS where HP_CLIENTE = '"& cliente0 & "' and HP_CODIGO_PROMOCION = '" & promo & "'") 'Revisamos si hay historico de la promoción.
c.Position = 0
If c.GetString("hist") > 0 Then siHistorico = 1
db.ExecNonQuery($"update PROMOCIONES_INFO set HISTORICO = ${siHistorico} where P_ID = '${promo}'"$)
' promoMap.Put("historico", siHistorico)
c = Starter.skmt.ExecQuery("Select * from CAT_DETALLES_PAQ where CAT_DP_ID = '"& promo & "'") 'Obtenemos los detalles de la promoción.
c.Position = 0
If c.RowCount > 0 Then
Private prods, tipos As Map
prods.Initialize
tipos.Initialize
For i = 0 To c.RowCount -1
c.Position=i
prods.Put(c.GetString("CAT_DP_IDPROD"), CreateMap("idProducto":c.GetString("CAT_DP_IDPROD"), "precioSimptos":c.GetString("CAT_DP_PRECIO_SIMPTOS"), "precio":c.GetString("CAT_DP_PRECIO"), "tipo":c.GetString("CAT_DP_TIPO"), "piezas":c.GetString("CAT_DP_PZAS"), "regalo":c.GetString("CAT_DP_REGALO"), "clasif":c.GetString("CAT_DP_CLASIF")))
tipos.Put(c.GetString("CAT_DP_IDPROD"), c.GetString("CAT_DP_TIPO"))
If c.GetString("CAT_DP_TIPO") = "0" Then
prodsFijos.Add(c.GetString("CAT_DP_IDPROD"))
prodsFijosPrecios.Add(c.GetString("CAT_DP_PRECIO"))
prodsFijosReq.Add(c.GetString("CAT_DP_PZAS"))
End If
If c.GetString("CAT_DP_TIPO") = "1" Then
prodsVariables.Add(c.GetString("CAT_DP_IDPROD"))
prodsVariablesPrecios.Add(c.GetString("CAT_DP_PRECIO"))
End If
' If muestraLogs Then Log($"id:${c.GetString("CAT_DP_IDPROD")}, tipo:${c.GetString("CAT_DP_TIPO")}"$)
Next
db.ExecNonQuery($"update PROMOCIONES_INFO set P_TIPOS = '${tipos}', P_PRODSFIJOS = '${prodsFijos}', P_PRODSFIJOS_CANT = ${prodsFijos.Size}, P_PRODSFIJOS_PRECIOS = '${prodsFijosPrecios}', P_PRODSFIJOS_PIEZAS = '${prodsFijosReq}', P_PRODSVARIABLES = '${prodsVariables}', P_PRODSVARIABLES_CANT = ${prodsVariables.Size}, P_PRODSVARIABLES_PRECIOS = '${prodsVariablesPrecios}', P_ESTATUS = 'ok' where P_ID = '${promo}'"$)
' promoMap.Put("productos", prods) 'Mapa con los productos de la promocion (id, precio, almacen, tipo, piezas, etc.)
' promoMap.Put("tipos", tipos) 'Mapa con los productos de la promoción y su tipo (fijo o variable).
' promoMap.Put("prodsFijos", prodsFijos) 'Lista de los productos fijos de la promoción.
' promoMap.Put("prodsFijosCant", prodsFijos.Size)
' promoMap.Put("prodsFijosPrecios", prodsFijosPrecios)
' promoMap.Put("prodsFijosReq", prodsFijosReq)
' promoMap.Put("prodsVariables", prodsVariables) 'Lista de los productos variables de la promoción.
' promoMap.Put("prodsVariablesCant", prodsVariables.Size)
' promoMap.Put("prodsVariablesPrecios", prodsVariablesPrecios)
' promoMap.Put("resultado", "ok")
Else
' promoMap.Put("resultado", "No hay datos de la promoción.")
db.ExecNonQuery($"update PROMOCIONES_INFO set P_ESTATUS = 'No hay datos de la promoción.' where P_ID = '${promo}'"$)
End If
c = Starter.skmt.ExecQuery($"Select CAT_GP_STS, CAT_GP_NOMBRE from ${tablaProds} where CAT_GP_ID = '"$& promo & "'") 'Obtenemos las piezas requeridas de productos variables para la promoción.
c.Position = 0
Private pvr As String = 0
If c.RowCount > 0 Then
c.Position = 0
pvr = c.GetString("CAT_GP_STS")
' promoMap.Put("prodsVariablesRequeridos", pvr) 'Cantidad de productos variables requeridos para la promoción.
promoMap.put("descripcion", c.GetString("CAT_GP_NOMBRE"))
db.ExecNonQuery($"update PROMOCIONES_INFO set P_PRODSVARIABLES_REQUERIDOS = ${pvr} where P_ID = '${promo}'"$) 'Cantidad de productos variables requeridos para la promoción.
End If
c.Close
' If muestraLogs Then Log($"Inv variables: ${cuantosVariablesDisponiblesDB(promo)}"$)
' If muestraLogs Then Log($"Inv dispo: ${traemosInvDispParaPromo(promo)}"$)
' If muestraLogs Then LogColor($"Promo ${promo}: ${promoMap}"$, Colors.Blue)
' If muestraLogs Then LogColor("TIEMPO para traePromo -=" & promo & "=- : " & ((DateTime.Now-inicioContador)/1000), Colors.Blue)
Return promoMap
End Sub
' Regresa cuantas promos alcanzan con los productos FIJOS que hay en inventario.
Sub revisaMaxPromosProdsFijosPorInventario(idPromo As String) As Int
If muestraLogs Then LogColor("> revisaMaxPromosProdsFijosPorInventario: " & idPromo, Colors.blue)
Private maxPromosPermitidas As List
Private promosDispEsteProd, InvDispEsteProd, pzasReqEsteProd As Int
Private esteColor As Double
Private esteMensaje As String
maxPromosPermitidas.Initialize
maxPromosPermitidas.Add(traeMaxPromos(idPromo)) ' Agregamos a la lista las promos maximas permitidas (por cliente, recurrentes y maxpromos).
' 👇🏼 Traemos los productos fijos y piezas requeridas de la promoción. 👇🏼
Private c As ResultSet = db.ExecQuery($"select CAT_DP_IDPROD, sum(CAT_DP_PZAS) as totalPzas from CAT_DETALLES_PAQ where CAT_DP_ID = '${idPromo}' and CAT_DP_TIPO = '0' group by CAT_DP_IDPROD"$)
Do While c.NextRow
InvDispEsteProd = traeInventario(c.GetString("CAT_DP_IDPROD"))
pzasReqEsteProd = c.GetString("totalPzas")
esteColor = Colors.green
esteMensaje = "INVENTARIO OK"
If pzasReqEsteProd > InvDispEsteProd Then
esteColor = Colors.red
esteMensaje = "INVENTARIO INSUFICIENTE"
End If
If muestraLogs Then LogColor($"PROD FIJO=${c.GetString("CAT_DP_IDPROD")}, INV=${InvDispEsteProd}, REQ=${pzasReqEsteProd} --> ${esteMensaje}"$, esteColor)
promosDispEsteProd = (InvDispEsteProd/pzasReqEsteProd).As(Int) 'Agregamos el as(int) para que solo nos regrese la parte entera de la division.
maxPromosPermitidas.Add(promosDispEsteProd) ' Agregamos a la lista las promociones permitidas por inventario de este producto.
Loop
maxPromosPermitidas.Sort(True) ' Ordenamos la lista para que el primer elemento sea el MAS pequeño.
If muestraLogs Then LogColor("Max promos de prodsFijos POR inventario = " & maxPromosPermitidas.Get(0), Colors.Magenta)
Return maxPromosPermitidas.Get(0) 'Regresamos el MENOR numero de promociones permitidas.
End Sub
'Regresa cuantas promos alcanzan con los productos VARIABLES que hay en inventario.
'La cantidad de promos disponibles se calcula DESPUES de descontar los productos fijos, y si las
'promos por productos fijos llegan al maximo, aunque se puedan mas de producos variables, solo se
'regresa el maximo por productos fijos. Ej. si las promos por variables es 10, pero el maximo por
'fijos es 5, entonces regresamos 5.
Sub revisaMaxPromosProdsVariablesPorInventario(idPromo As String) As Int 'ignore
If muestraLogs Then LogColor("> revisaMaxPromosProdsVariablesPorInventario: " & idPromo, Colors.blue)
Private invFijoXpromo As Map
invFijoXpromo.Initialize
Private totalProdsVariablesDisponibles As Int = 0
' If muestraLogs Then LogColor($"pm=${pm}"$, Colors.Blue)
Private invDispParaPromo As Map = traemosInvDispParaPromo(idPromo)
' If muestraLogs Then
Log($"invDispParaPromo=${invDispParaPromo}"$)
Private maxPromos As String = traeMaxPromos(idPromo)
Private maxPromosXFijos As Int = revisaMaxPromosProdsFijosPorInventario(idPromo)
Private idProdsVariables As List = traeListaDePromo("P_PRODSVARIABLES", idPromo)
Private prodsVariablesRequeridos As Int = traeInfoDePromo("P_PRODSVARIABLES_REQUERIDOS", idPromo)
Private prodsFijosReq As List = traeListaDePromo("P_PRODSFIJOS_PIEZAS", idPromo)
Private idProdsFijos As List = traeListaDePromo("P_PRODSFIJOS", idPromo)
For p = 0 To idProdsFijos.Size -1 'Generamos mapa con los productos fijos y piezas requeridas por promo.
invFijoXpromo.Put(idProdsFijos.Get(p), prodsFijosReq.Get(p))
Log(idProdsFijos)
Private idEsteProd As String = idProdsFijos.Get(p)
Log(idEsteProd)
Private invEsteProd As Int = invDispParaPromo.Get(idEsteProd)
Private pzasReqEsteProd As Int = prodsFijosReq.Get(p)
If muestraLogs Then Log($"id=${idEsteProd}, inv=${invEsteProd}, pzas=${pzasReqEsteProd}"$)
' invDispParaPromo.Put( idEsteProd, (invEsteProd - (1)) )
Next
If muestraLogs Then LogColor($"MaxPromos=${maxPromos}, promosXFijos=${maxPromosXFijos}"$, Colors.Blue)
If muestraLogs Then LogColor($"prodsFijos=${idProdsFijos}"$, Colors.Blue)
If muestraLogs Then LogColor($"prodsFijosReq=${prodsFijosReq}"$, Colors.Blue)
If muestraLogs Then LogColor($"prodsVariables=${idProdsVariables}${CRLF}Variables Req=${prodsVariablesRequeridos} "$, Colors.Blue)
If muestraLogs Then LogColor($"invFijoXpromo=${invFijoXpromo}"$, Colors.Blue)
If muestraLogs Then Log($"Prods variables disponibles = ${totalProdsVariablesDisponibles}"$)
Private maxPromosXVariables As Int = 0
If Not(releaseMode) Then muestraLogs = True
For x = 1 To maxPromosXFijos
If muestraLogs Then Log("=====================================================")
For i = 0 To idProdsFijos.Size - 1
' Log(prodsFijosReq.Get(i))
Private prodsFijosRequeridos As Int = prodsFijosReq.Get(i)
Private esteProdFijo As String = idProdsFijos.Get(i)
' Log(invDispParaPromo)
If muestraLogs Then Log($"FIJO - ${idProdsFijos.Get(i)}, ${invDispParaPromo.Get(esteProdFijo)} - ${prodsFijosRequeridos*(i+1)}"$)
invDispParaPromo.Put(esteProdFijo, invDispParaPromo.Get(esteProdFijo) - prodsFijosRequeridos*(i+1)) 'Restamos las piezas de los productos fijos del inventario disponible.
Next
If muestraLogs Then LogColor("Inv disponible despues de restar fijos = " & invDispParaPromo, Colors.Blue)
totalProdsVariablesDisponibles = 0
For i = 0 To idProdsVariables.Size - 1 'Obtenemos total de productos variables disponibes.
Private thisProdVariable As String = idProdsVariables.Get(i)
If invDispParaPromo.ContainsKey(thisProdVariable) Then
totalProdsVariablesDisponibles = totalProdsVariablesDisponibles + invDispParaPromo.Get(thisProdVariable)
End If
Next
'Revisamos variables.
If muestraLogs Then Log($"Var disponibles - var requeridos : ${totalProdsVariablesDisponibles} - ${prodsVariablesRequeridos*x}"$)
totalProdsVariablesDisponibles = totalProdsVariablesDisponibles - (prodsVariablesRequeridos*x)
If muestraLogs Then Log("prodsVariables disponibles despues de promo = " & totalProdsVariablesDisponibles)
If totalProdsVariablesDisponibles < 0 Then Exit 'Ya no hay inventario disponible.
maxPromosXVariables = x
Next
'Restamos fijos.
' LogColor("Max promos de prodsVariables POR inventario = " & maxPromosXVariables, Colors.red)
Return maxPromosXVariables
End Sub
'Regresa un mapa con el inventario disponible por producto para la promoción (desde la base de datos).
Sub traemosInvDispParaPromo(idPromo As String) As Map 'ignore
If muestraLogs Then LogColor("> traemosInvDispParaPromo: " & idPromo, Colors.blue)
Private c As Cursor
c = Starter.skmt.ExecQuery2($"SELECT CAT_GP_ID, CAT_GP_ALMACEN FROM ${tablaProds} WHERE CAT_GP_ID IN (select CAT_DP_IDPROD FROM CAT_DETALLES_PAQ WHERE CAT_DP_ID = ?)"$, Array As String(idPromo))
' Private prodInv As Map
' prodInv.Initialize
Private prods As Map
prods.Initialize
If c.RowCount > 0 Then
For i = 0 To c.RowCount -1
c.Position = i
prods.Put(c.GetString("CAT_GP_ID"), c.GetString("CAT_GP_ALMACEN"))
' Log($"prod:${c.GetString("CAT_GP_ID")}, inventario:${c.GetString("CAT_GP_ALMACEN")}"$)
Next
' prodInv.Put("inventarios", prods)
End If
Return prods
End Sub
'Resta los productos fijos del inventario de la promoción y regresa un mapa con el nuevo inventario.
'Hay que darle como parametro el Id de la promocion.
'Regresa en el mapa la llave "resultado" que nos da "ok" o "No hay suficiente producto para la promocion".
Sub restaFijosDePromo(idPromo As String) As Map 'ignore
If muestraLogs Then LogColor("> restaFijosDePromo: " & idPromo, Colors.blue)
Private invDispEstaPromo As Map = traemosInvDispParaPromo(idPromo) 'Obtenemos un mapa con el inventario disponible para cada producto de la promocion desde la base de datos.
If muestraLogs Then LogColor("Inventario inicial antes de FIJOS: "&invDispEstaPromo, Colors.Magenta) 'Inventario inicial.
Private InvDispEsteProd, pzasReqEsteProd As Int
Private esteProd As String
invDispEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.") 'Valor por DEFAULT.
Private nuevoInv As Int
' 👇🏼 Traemos los productos fijos y piezas requeridas de la promoción. 👇🏼
Private c As ResultSet = db.ExecQuery($"select CAT_DP_IDPROD, sum(CAT_DP_PZAS) as totalPzas from CAT_DETALLES_PAQ where CAT_DP_ID = '${idPromo}' and CAT_DP_TIPO = '0' group by CAT_DP_IDPROD"$)
Do While c.NextRow
esteProd = c.GetString("CAT_DP_IDPROD")
pzasReqEsteProd = c.GetString("totalPzas")
If muestraLogs Then Log($"esteProd ${esteProd}, piezasReq: ${pzasReqEsteProd}"$) 'Producto y piezas requeridas
If muestraLogs Then Log("invDispEstaPromo="&invDispEstaPromo)
If invDispEstaPromo.ContainsKey(esteProd) Then 'Si el mapa del inventario contiene el id del producto entonces ...
InvDispEsteProd = invDispEstaPromo.get(esteProd) 'Obtenemos del mapa el inventario de este producto.
nuevoInv = NumberFormat2((InvDispEsteProd - pzasReqEsteProd), 1, 0,0,False)
If muestraLogs Then Log($"Nuevo inventario de ${esteProd}: ${InvDispEsteProd}-${pzasReqEsteProd} = ${nuevoInv}"$) 'El nuevo inventario.
invDispEstaPromo.Put(esteProd.Trim, nuevoInv) 'Restamos del inventario las piezas requeridas para la promoción y guardamos el nuevo inventario en el mapa.
invDispEstaPromo.Put("resultado", "ok")
Else 'Si en el mapa no esta el id del producto, entonces no tenemos inventario.
invDispEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.")
If muestraLogs Then LogColor("Sin suficiente inventario fijo: " & esteProd, Colors.Blue)
Exit
End If
If nuevoInv < 0 Then
invDispEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.") 'Si el inventario de este producto sale negativo, quiere decir que no tenemos suficiente inventario para la promoción.
Exit
End If
Loop
If muestraLogs Then LogColor("Inventario final despues de FIJOS: "&invDispEstaPromo, Colors.blue) 'Inventario final.
Return invDispEstaPromo
End Sub
'Revisa si tenemos los productos variables requeridos para la promoción (mapa).
'Hay que darle como parametro un mapa (traePromo(promo)) con toda la informacion de la promocion.
Sub alcanzanLosVariablesParaPromo(idPromo As String, inventarioSinFijos As Map) As Boolean 'ignore
If muestraLogs Then LogColor("> alcanzanLosVariablesParaPromo: " & idPromo, Colors.blue)
If muestraLogs Then LogColor("Inventario inicial: "&inventarioSinFijos, Colors.Gray) 'Inventario inicial.
Private totalProdsVariables As Int = 0
' Private prodsmap As Map = promoMap.Get("productos") 'Obtenemos un mapa con todos los productos de la promoción.
Private prodsVariables As List = traeListaDePromo("P_PRODSVARIABLES", idPromo) ' promoMap.get("prodsVariables") 'Obtenemos un a lista con los productos variables de la promoción.
For p = 0 To prodsVariables.Size - 1
Private t As String = prodsVariables.Get(p) 'Obtenemos el Id de este producto desde la lista de productos fijos.
If inventarioSinFijos.ContainsKey(t) Then 'Si existe el producto en la lista del inventario, entonces ...
Private p2 As Int = inventarioSinFijos.Get(t) 'Obtenemos el inventario disponible este producto.
If muestraLogs Then Log($"prod ${t}, hay: ${p2}"$) 'Producto y piezas requeridas
totalProdsVariables = totalProdsVariables + p2
End If
Next
Private prodsVariablesRequeridos As Int = traeInfoDePromo("P_PRODSVARIABLES_REQUERIDOS", idPromo)
If muestraLogs Then Log("Total prods variables=" & totalProdsVariables & ", requeridos=" & prodsVariablesRequeridos)
Private res As Boolean = False
If totalProdsVariables >= prodsVariablesRequeridos Then res = True 'Si el total de inventario de productos variables (totalProdsVariables) es mayor o igual a los productos requeridos entonces regresamos TRUE
Return res
End Sub
'Regresa el numero máximo de promociones permitidas, tomando en cuenta recurrentes, clientes y maxPromos.
Sub traeMaxPromos(idPromo As String) As Int
If muestraLogs Then LogColor("> traeMaxPromos: " & idPromo, Colors.blue)
Private maxPromos As List
Private mp0, mp As String = "0"
maxPromos.Initialize
Private hccp As Cursor = db.ExecQuery($"select HCCP_CANT from HIST_CLIENTE_CANT_PROMOS where HCCP_CLIENTE = '${cliente}' and HCCP_PROMO = '${idPromo}'"$)
If muestraLogs Then LogColor("Historico: "&traeInfoDePromo("HISTORICO", idPromo), Colors.Blue)
' If muestraLogs Then Log(pm)
If traeInfoDePromo("HISTORICO", idPromo) = "1" Then maxPromos.Add(traeInfoDePromo("P_MAXRECURRENTE", idPromo).As(Int)) 'Si hay historico, agregamos maxRecurrente
If traeInfoDePromo("P_MAXPROMOS", idPromo) <> "null" Then maxPromos.Add(traeInfoDePromo("P_MAXPROMOS", idPromo).As(Int)) 'Agregamos maxPromos
If traeInfoDePromo("P_MAXXCLIENTE", idPromo) <> "null" Then maxPromos.Add(traeInfoDePromo("P_MAXXCLIENTE", idPromo).As(Int)) 'Agregamos maxXcliente
If hccp.RowCount > 0 Then 'Agregamos promos HCCP
hccp.Position = 0
maxPromos.Add(hccp.GetInt("HCCP_CANT"))
End If
' Log($"|${traeInfoDePromo("HISTORICO", idPromo)}|${traeInfoDePromo("P_MAXPROMOS", idPromo)}|${traeInfoDePromo("P_MAXXCLIENTE", idPromo)}|"$)
' Log(maxPromos)
maxPromos.Sort(True)
' If muestraLogs Then Log($"Max promos : ${maxPromos}"$)
mp = 0
If maxPromos.Size > 0 Then
mp0 = maxPromos.Get(0)
' Log(mp0)
Private promosVendidas As Int = traePromosVendidas(idPromo)
mp = mp0 - promosVendidas
If muestraLogs Then Log($"Max Promos (${mp0}) - Promos Vendidas (${(promosVendidas)}) = Promos Disponibles (${mp})"$)
End If
Return mp 'Regresamos el numero mas pequeño de las opciones.
End Sub
'Regresa la cantidad de promos que se le han vendido al cliente.
Sub traePromosVendidas(idPromo As String) As Int
If muestraLogs Then LogColor("> traePromosVendidas: " & idPromo, Colors.blue)
Private c As Cursor
Private pv As Int = 0
c=db.ExecQuery($"select sum(PE_CANT) as cuantas from PEDIDO where PE_PROID = '${idPromo}' and PE_CLIENTE = '${cliente}'"$)
If c.RowCount > 0 Then
c.Position = 0
If c.GetString("cuantas") <> Null Then pv = c.GetString("cuantas")
End If
Return pv
End Sub
'Trae el valor de la columna especificada de la promo dada.
Sub traeInfoDePromo(col As String, idPromo As String) As String
Private res As String = ""
Private c As ResultSet = db.ExecQuery($"select ${col} from PROMOCIONES_INFO where P_ID = '${idPromo}'"$)
' Log($"select ${col} from PROMOCIONES_INFO where P_ID = '${idPromo}'"$)
Do While c.NextRow
res = c.GetString(col)
Loop
Return res
End Sub
'Regresa una lista de la BD, en la BD se guarda como string y esta funcion la convierte en lista nuevamente.
Sub traeListaDePromo(col As String, promo As String) As List
' Log($"${col}, ${promo}"$)
Private res As List
Private s As String
Private c As ResultSet = db.ExecQuery($"select ${col} from PROMOCIONES_INFO where P_ID = '${promo}'"$)
Do While c.NextRow
s = c.GetString(col)
Loop
If s.StartsWith("[") And s.EndsWith("]") Then
' Private j As JSONParser
' j.Initialize(s)
' res.Initialize2(j.NextArray)
res.Initialize
s = s.Replace("[", "")
s = s.Replace("]", "")
Private s2() As String = Regex.Split(",", s)
For i = 0 To s2.Length - 1
res.Add(s2(i).as(String).trim)
Next
Else
res.Initialize
End If
Return res
End Sub
'Regresa una lista de la BD, en la BD se guarda como string y esta funcion la convierte en lista nuevamente.
Sub traeMapaDePromo(col As String, promo As String) As List
Private res As List
Private s As String
Private c As ResultSet = db.ExecQuery($"select ${col} from PROMOCIONES_INFO where P_ID = '${promo}'"$)
Do While c.NextRow
s = c.GetString(col)
Loop
If s.StartsWith("{") And s.EndsWith("}") Then
Private j As JSONParser
j.Initialize(s)
res.Initialize2(j.NextArray)
Else
res.Initialize
End If
Return res
End Sub
'Regresa el inventario de un producto dado o CERO si no lo encuentra.
Sub traeInventario(id As String) As Int
Private inv As Int = 0
Private c As ResultSet = db.ExecQuery($"select CAT_GP_ALMACEN from ${tablaProds} where CAT_GP_ID = ${id}"$)
Do While c.NextRow
inv = c.GetInt("CAT_GP_ALMACEN")
Loop
Return inv
End Sub
'Regresa cuantas promos alcanzan con los productos FIJOS que hay en inventario.
Sub revisaMaxPromosProdsFijosPorInventarioXXX(id As String) As Int
If muestraLogs Then LogColor("> revisaMaxPromosProdsFijosPorInventario: " & id, Colors.blue)
' Private invFijoXpromo As Map
Private t As List
t.Initialize
t.Add(traeMaxPromos(id)) ' Agregamos a la lista las promos maximas permitidas (recurrente, cliente y promo).
' invFijoXpromo.Initialize
' If muestraLogs Then LogColor($"pm=${pm}"$, Colors.Blue)
Private prodsFijosReq As List = traeListaDePromo("P_PRODSFIJOS_PIEZAS", id)
Private idProdsFijos As List = traeListaDePromo("P_PRODSFIJOS", id)
If muestraLogs Then Log($"ProdsFijos: ${idProdsFijos}, PiezasReq: ${prodsFijosReq}"$)
Private invDispParaPromo As Map = traemosInvDispParaPromo(id)
If muestraLogs Then Log(">>> " & $"invDispParaPromo=${invDispParaPromo}"$)
For p = 0 To idProdsFijos.Size -1 'Generamos una lista con las promos disponibles por producto (dividimos el inventario total entre las piezas requeridas).
Private thisInvDisp As Int = 0
If invDispParaPromo.Get(idProdsFijos.Get(p).As(String)) <> Null Then
thisInvDisp = invDispParaPromo.Get(idProdsFijos.Get(p).As(String))
End If
Private esteColor As Double = Colors.green
Private esteMensaje As String = "INVENTARIO OK"
If prodsFijosReq.Get(p) > thisInvDisp Then
esteColor = Colors.red
esteMensaje = "INVENTARIO INSUFICIENTE"
End If
If muestraLogs Then LogColor($"PROD=${idProdsFijos.Get(p)}, INV=${thisInvDisp}, REQ=${prodsFijosReq.Get(p)} - ${esteMensaje}"$, esteColor)
' If muestraLogs Then Log($"${(thisInvDisp / prodsFijosReq.Get(p))}"$)
Private x() As String = Regex.Split("\.", $"${(thisInvDisp / prodsFijosReq.Get(p))}"$) 'Separamos el resultado de la division por el punto decimal.
' If muestraLogs Then Log($"PROD: ${idProdsFijos.Get(p)}, INV: ${x(0)}, REQ: ${prodsFijosReq.Get(p)}"$)
t.Add(x(0).As(Int)) 'Solo guardamos la parte del entero de la division.
Next
t.Sort(True) 'Ordenamos la lista para que en el lugar 0 este el resultado mas pequeño.
' If muestraLogs Then LogColor($"prodsFijos=${idProdsFijos}"$, Colors.Blue)
' If muestraLogs Then LogColor($"prodsFijosReq=${prodsFijosReq}"$, Colors.Blue)
' If muestraLogs Then LogColor($"promosProdsFijosDisp=${t}"$, Colors.Blue)
' If muestraLogs Then LogColor($"invFijoXpromo=${invFijoXpromo}"$, Colors.Blue)
If muestraLogs Then LogColor("Max promos de prodsFijos POR inventario = " & t.Get(0), Colors.Magenta)
Return t.Get(0) 'Regresamos el resultado mas pequeño.
End Sub
'Resta los productos fijos del inventario de la promoción y regresa un mapa con el nuevo inventario.
'Hay que darle como parametro el Id de la promocion.
'Regresa en el mapa la llave "resultado" que nos da "ok" o "No hay suficiente producto para la promocion".
Sub restaFijosDePromoXXX(idPromo As String) As Map 'ignore
If muestraLogs Then LogColor("> restaFijosDePromo: " & idPromo, Colors.blue)
Private invDispEstaPromo As Map = traemosInvDispParaPromo(idPromo) 'Obtenemos un mapa con el inventario disponible para cada producto de la promocion desde la base de datos.
If muestraLogs Then LogColor("Inventario inicial antes de FIJOS: "&invDispEstaPromo, Colors.Magenta) 'Inventario inicial.
Private inv As Int
Private prodsFijos As List = traeListaDePromo("P_PRODSFIJOS", idPromo) 'Obtenemos una lista con los productos fijos de la promoción.
Private prodsFijosReq As List = traeListaDePromo("P_PRODSFIJOS_PIEZAS", idPromo) 'Obtenemos un a lista con los productos fijos de la promoción.
If muestraLogs Then LogColor("ProdsFijos -> " & prodsFijos, Colors.red)
invDispEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.") 'Valor por DEFAULT.
If muestraLogs Then Log($"Prods fijos requeridos ${prodsFijos.Size}"$)
If prodsFijos.Size = 0 Then invDispEstaPromo.Put("resultado", "ok") 'Si no lleva prods fijos la promo, entonces ponemos FIJOS OK.
Private nuevoInv As Int
For p = 0 To prodsFijos.Size - 1
Private esteProd As String = prodsFijos.Get(p) 'Obtenemos el Id de este producto desde la lista de productos fijos.
If muestraLogs Then Log($"esteProd ${esteProd}, piezasReq: ${prodsFijosReq.Get(p)}"$) 'Producto y piezas requeridas
If muestraLogs Then Log("invDispEstaPromo="&invDispEstaPromo)
If invDispEstaPromo.ContainsKey(esteProd) Then 'Si el mapa del inventario contiene el id del producto entonces ...
inv = invDispEstaPromo.get(esteProd) 'Obtenemos del mapa el inventario de este producto.
nuevoInv = NumberFormat2((inv - prodsFijosReq.get(p)), 1, 0,0,False)
If muestraLogs Then Log($"Nuevo inventario de ${esteProd}: ${inv}-${prodsFijosReq.get(p)} = ${nuevoInv}"$) 'El nuevo inventario.
invDispEstaPromo.Put(esteProd, $"${nuevoInv}"$) 'Restamos del inventario las piezas requeridas para la promoción y guardamos el nuevo inventario en el mapa.
invDispEstaPromo.Put("resultado", "ok")
Else 'Si en el mapa no esta el id del producto, entonces no tenemos inventario.
invDispEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.")
If muestraLogs Then LogColor("Sin suficiente inventario fijo: " & esteProd, Colors.Blue)
Exit
End If
If nuevoInv < 0 Then
invDispEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.") 'Si el inventario de este producto sale negativo, quiere decir que no tenemos suficiente inventario para la promoción.
Exit
End If
Next
If muestraLogs Then LogColor("Inventario final despues de FIJOS: "&invDispEstaPromo, Colors.blue) 'Inventario final.
Return invDispEstaPromo
End Sub

View File

@@ -56,8 +56,9 @@ Sub Process_Globals
Dim pingShell As Boolean = False
Dim errorConnDBReq As Boolean = False
Dim GUID As String = ""
Dim passSupervisor As String = "13X#X$X46" ' Valor predeterminado DIFERENTE a ""
Dim passSupervisor As String = "135###" ' Valor predeterminado DIFERENTE a ""
Dim semana As Int = 0
dim revisandoNotifiaciones as Boolean = false
End Sub
Sub Service_Create
@@ -72,6 +73,7 @@ Sub Service_Create
GPS.Initialize("GPS")
ubicacionActual.Initialize
Subs.revisaBD
' promociones.Initialize
pe.Initialize("pe") 'Para obtener la bateria
' skmt = s.dbInit 'Inicializamos BD.
DBReqServer = "http://keymon.net:1781"
@@ -85,9 +87,9 @@ Sub Service_Create
reqManager.Initialize(Me, DBReqServer) 'Inicializamos reqManager.
If Logger Then Log($"Starter reqManager server: ${DBReqServer}"$)
'Para los Logs
#if RELEASE
' #if RELEASE
logcat.LogCatStart(Array As String("-v","raw","*:F","B4A:v"), "logcat")
#end if
' #end if
logs.Initialize
sesion.Initialize
End Sub
@@ -123,7 +125,7 @@ Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
logs.Append(StackTrace)
Subs.revisaBD
LogColor(logs, Colors.blue)
errorLog.ExecNonQuery($"INSERT INTO errores(fecha, error) VALUES ('${Subs.fechaKMT(DateTime.now)}', '${logs}')"$)
skmt.ExecNonQuery($"INSERT INTO errores(fecha, error) VALUES ('${Subs.fechaKMT(DateTime.now)}', '${logs}')"$)
LogColor("insertamos Error", Colors.red)
StartActivity(errorManager)
Return True
@@ -189,17 +191,20 @@ Sub ENVIA_ULTIMA_GPS
If i = "SALTY SNACKS" Then salty = x
Next
h.Close
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "UPDATE_KELL_ACTUAL3_GPS"
cmd.Parameters = Array As Object(montoActual, clientesVisitaHoy, clientesVenta, clientesVisitados, lat_gps, lon_gps, batt, 0, 0, 0, Application.VersionName, rtec, ping, salty, Subs.dameClientesFueraDeFrecuencia, almacen, rutaPreventa)
' If Logger Then LogColor(montoActual&","&clientesVisitaHoy&","&clientesVenta&","&clientesVisitados&","&lat_gps&","&lon_gps&","&batt&","&0&","&0&","&0&","&Application.VersionName&","&rtec&","&ping&","&salty&","& Subs.dameClientesFueraDeFrecuencia&","&almacen&","&rutaPreventa, Colors.Magenta)
reqManager.ExecuteCommand(cmd,"updateKell_UTR")
cmd.Name = "select_hora"
reqManager.ExecuteQuery(cmd , 0, "hora")
If Subs.EstaEnHorarioPermitido Then
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "UPDATE_KELL_ACTUAL3_GPS"
cmd.Parameters = Array As Object(montoActual, clientesVisitaHoy, clientesVenta, clientesVisitados, lat_gps, lon_gps, batt, 0, 0, 0, Application.VersionName, rtec, ping, salty, Subs.dameClientesFueraDeFrecuencia, almacen, rutaPreventa)
' If Logger Then LogColor(montoActual&","&clientesVisitaHoy&","&clientesVenta&","&clientesVisitados&","&lat_gps&","&lon_gps&","&batt&","&0&","&0&","&0&","&Application.VersionName&","&rtec&","&ping&","&salty&","& Subs.dameClientesFueraDeFrecuencia&","&almacen&","&rutaPreventa, Colors.Magenta)
reqManager.ExecuteCommand(cmd,"updateKell_UTR")
cmd.Name = "select_hora"
reqManager.ExecuteQuery(cmd , 0, "hora")
' log(subs.revisaHora)
End If
' If Logger Then Log(reqManager)
' If Logger Then Log("++ ++ ++ Envia_Ultima GPS - Inst_visitas - server: "& server)
skmt.ExecNonQuery2("Update cat_variables set CAT_VA_VALOR = ? WHERE CAT_VA_DESCRIPCION = ?" , Array As String(DateTime.Time(DateTime.Now),"HoraIngreso"))

View File

@@ -863,6 +863,7 @@ Sub traeNombreCliente(id As String) As String
Do While c.NextRow
n = c.GetString("CAT_CL_NOMBRE")
Loop
c.Close
Return n
End Sub
@@ -906,7 +907,7 @@ Sub guardaProducto(cedis As String, costoTot As String, costoU As String, cant A
LogColor("guardaProducto", Colors.Magenta)
Log($"Guardamos producto ${prodId}"$)
LogColor("TIPO VENTA="&tipoV, Colors.Magenta)
Starter.skmt.ExecNonQuery2("INSERT INTO PEDIDO (PE_CEDIS, PE_COSTO_TOT, PE_COSTOU, PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_FECHA, PE_USUARIO, PE_TIPO, PE_PRECIO2, PE_RUTA) VALUES(?,?,?,?,?,?,?,?,?,?,?,?) ", Array As Object (cedis, costoTot, costoU, cant, nombre, prodId, clienteId, fecha, usuario, tipoV, precio2, Starter.rutaV))
Starter.skmt.ExecNonQuery2("INSERT INTO PEDIDO (PE_CEDIS, PE_COSTO_TOT, PE_COSTOU, PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_FECHA, PE_USUARIO, PE_TIPO, PE_PRECIO2, PE_RUTA, PE_ENVIADO) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,0) ", Array As Object (cedis, costoTot, costoU, cant, nombre, prodId, clienteId, fecha, usuario, tipoV, precio2, Starter.rutaV))
Starter.skmt.ExecNonQuery2("update " & query & " set cat_gp_almacen = cat_gp_almacen - ? where cat_gp_id = ? ", Array As Object(cant, prodId))
ToastMessageShow("guardaProd", False)
End Sub
@@ -915,22 +916,26 @@ End Sub
'NO ACTUALIZA LA BANDERA DE GESTION EN LA TABLA "kmt_info".
'Si "gestion=2" entonces el sistema considera que el pedido ya se guardó y ya no se debe modificar.
Sub guardaProductoSinGestion(cedis As String, costoU As String, cant As String, nombre As String, prodId As String, clienteId As String, fecha As String, usuario As String, rutaV As String, precioSin As String, tipoVenta As String)
Log($"Guarda producto ${nombre}, cant: ${cant}, cedis: ${cedis}"$)
If nombre.Length < 6 Then ToastMessageShow("(guardaProductoSinGestion) El nombre del producto no es valido " & nombre, True)
precioSin = NumberFormat2(precioSin, 1, 2, 2, False)
costoU = NumberFormat2(costoU, 1, 2, 2, False)
' LogColor("guardaProductoSinGestion: "&prodId&", cant="&cant&", tipo="&tipoVenta, Colors.Magenta)
LogColor("guardaProductoSinGestion: "&prodId&", cant="&cant&", tipo="&tipoVenta, Colors.Magenta)
Private c As Cursor
' Private tablaProds As String = "cat_gunaprod2"
' If tipoVenta = "ABORDO" Then tablaProds = "cat_gunaprod"
Starter.skmt.ExecNonQuery2("INSERT INTO PEDIDO (PE_CEDIS, PE_COSTO_TOT, PE_COSTOU, PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_FECHA, PE_USUARIO, PE_RUTA, PE_COSTO_SIN, PE_TIPO) VALUES(?,?,?,?,?,?,?,?,?,?,?,?) ", Array As Object (cedis, (cant * costoU), costoU, cant, nombre, prodId, clienteId, fecha, usuario, rutaV, precioSin, tipoVenta))
Starter.skmt.ExecNonQuery2("INSERT INTO PEDIDO (PE_CEDIS, PE_COSTO_TOT, PE_COSTOU, PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_FECHA, PE_USUARIO, PE_RUTA, PE_COSTO_SIN, PE_TIPO, PE_ENVIADO) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,0) ", Array As Object (cedis, (cant * costoU), costoU, cant, nombre, prodId, clienteId, fecha, usuario, rutaV, precioSin, tipoVenta))
'Actualizamos el inventario en cat_gunaprod solo si no es RMI
If cedis <> "DUR" Then Starter.skmt.ExecNonQuery2($"update ${traeTablaProds(tipoVenta)} set cat_gp_almacen = cat_gp_almacen - ? where cat_gp_id = ? "$, Array As Object(cant, prodId))
If cedis <> "DUR" Then
Starter.skmt.ExecNonQuery2($"update ${traeTablaProds(tipoVenta)} set cat_gp_almacen = cat_gp_almacen - ? where cat_gp_id = ? "$, Array As Object(cant, prodId))
Log($"update ${traeTablaProds(tipoVenta)} set cat_gp_almacen = cat_gp_almacen - ? where cat_gp_id = ? -- ${cant}, ${prodId}"$)
End If
c=Starter.skmt.ExecQuery("select sum(pe_costo_tot) as TOTAL_CLIE, SUM(PE_CANT) AS CANT_CLIE, SUM(PE_COSTO_SIN) AS TOTAL_CLIE_SIN FROM PEDIDO WHERE PE_CLIENTE IN (Select CUENTA from cuentaa)")
c.Position=0
' Log("###### delete from pedido_cliente - " & traeCliente & "|" & clienteId)
' Log($"delete from pedido_cliente where PC_CLIENTE = '${traeCliente}'"$)
Starter.skmt.ExecNonQuery($"delete from pedido_cliente where PC_CLIENTE = '${traeCliente}'"$)
Starter.skmt.ExecNonQuery2("insert into pedido_cliente(PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT,PC_ALMACEN,PC_RUTA,PC_COSTO_SIN) VALUES (?,?,?,?,?,?,?,?,?,?)", Array As Object(clienteId, fecha, usuario, c.GetString("CANT_CLIE"), c.GetString("TOTAL_CLIE"), B4XPages.MainPage.lon_gps, B4XPages.MainPage.lat_gps, cedis, rutaV, c.GetString("TOTAL_CLIE_SIN")))
Starter.skmt.ExecNonQuery2("insert into pedido_cliente(PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT,PC_ALMACEN,PC_RUTA,PC_COSTO_SIN,PC_ENVIADO) VALUES (?,?,?,?,?,?,?,?,?,?,0)", Array As Object(clienteId, fecha, usuario, c.GetString("CANT_CLIE"), c.GetString("TOTAL_CLIE"), B4XPages.MainPage.lon_gps, B4XPages.MainPage.lat_gps, cedis, rutaV, c.GetString("TOTAL_CLIE_SIN")))
End Sub
Sub guardaProductoSin(cedis As String, costoTot As String, costoU As String, cant As String, nombre As String, prodId As String, clienteId As String, fecha As String, usuario As String, rutaV As String, precioSin As String, tipoV As String, precio2 As String, query As String) 'ignore
@@ -940,7 +945,7 @@ Sub guardaProductoSin(cedis As String, costoTot As String, costoU As String, can
costoU = NumberFormat2(costoU, 1, 2, 2, False)
costoTot = NumberFormat2(costoTot, 1, 2, 2, False)
LogColor("guardaProductoSin", Colors.Magenta)
Starter.skmt.ExecNonQuery2("INSERT INTO PEDIDO (PE_CEDIS, PE_COSTO_TOT, PE_COSTOU, PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_FECHA, PE_USUARIO, PE_RUTA, PE_COSTO_SIN, PE_TIPO, PE_PRECIO2) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?) ", Array As Object (cedis, costoTot, costoU, cant, nombre, prodId, clienteId, fecha, usuario, rutaV, precioSin, tipoV, precio2))
Starter.skmt.ExecNonQuery2("INSERT INTO PEDIDO (PE_CEDIS, PE_COSTO_TOT, PE_COSTOU, PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_FECHA, PE_USUARIO, PE_RUTA, PE_COSTO_SIN, PE_TIPO, PE_PRECIO2, PE_ENVIADO) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,0) ", Array As Object (cedis, costoTot, costoU, cant, nombre, prodId, clienteId, fecha, usuario, rutaV, precioSin, tipoV, precio2))
Starter.skmt.ExecNonQuery2("update " & query & " set cat_gp_almacen = cat_gp_almacen - ? where cat_gp_id = ? ", Array As Object(cant, prodId))
DateTime.DateFormat = "MM/dd/yyyy"
Private sDate As String =DateTime.Date(DateTime.Now)
@@ -949,7 +954,7 @@ Sub guardaProductoSin(cedis As String, costoTot As String, costoU As String, can
c.Position=0
Log("###### delete from pedido_cliente - " & traeCliente & "|" & clienteId)
Starter.skmt.ExecNonQuery("delete from pedido_cliente where PC_CLIENTE In (select cuenta from cuentaa)")
Starter.skmt.ExecNonQuery2("insert into pedido_cliente(PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT,PC_ALMACEN,PC_RUTA,PC_COSTO_SIN) VALUES (?,?,?,?,?,?,?,?,?,?)", Array As Object(clienteId, sDate & sTime, usuario, c.GetString("CANT_CLIE"),c.GetString("TOTAL_CLIE"), Starter.lon_gps, Starter.lat_gps, cedis, rutaV, c.GetString("TOTAL_CLIE_SIN")))
Starter.skmt.ExecNonQuery2("insert into pedido_cliente(PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT,PC_ALMACEN,PC_RUTA,PC_COSTO_SIN,PC_ENVIADO) VALUES (?,?,?,?,?,?,?,?,?,?,0)", Array As Object(clienteId, sDate & sTime, usuario, c.GetString("CANT_CLIE"),c.GetString("TOTAL_CLIE"), Starter.lon_gps, Starter.lat_gps, cedis, rutaV, c.GetString("TOTAL_CLIE_SIN")))
Starter.skmt.ExecNonQuery("UPDATE kmt_info set gestion = 2 where CAT_CL_CODIGO In (select cuenta from cuentaa)")
c.Close
' ToastMessageShow("guardaProdSin", False)
@@ -970,7 +975,7 @@ Sub actualizaProducto(cedis As String, costoU As String, cant As String, nombre
Private antCant As Int = 0
If IsNumber(c.GetInt("PE_CANT")) Then antCant=c.GetInt("PE_CANT")
Private difCant As Int = cant - antCant
Starter.skmt.ExecNonQuery($"update pedido set pe_cant = ${cant}, pe_costou = ${costoU}, pe_costo_tot = ${NumberFormat2((cant*c.GetString("PE_COSTOU")), 1, 2, 2, False)}, pe_tipo = '${tipoVenta}' where pe_cedis = '${cedis}' and pe_proid = '${prodId}' and pe_cliente = '${clienteId}' "$)
Starter.skmt.ExecNonQuery($"update pedido set pe_cant = ${cant}, pe_costou = ${costoU}, pe_costo_tot = ${NumberFormat2((cant*c.GetString("PE_COSTOU")), 1, 2, 2, False)}, pe_tipo = '${tipoVenta}', pe_enviado = 0 where pe_cedis = '${cedis}' and pe_proid = '${prodId}' and pe_cliente = '${clienteId}' "$)
If cedis <> "DUR" Then Starter.skmt.ExecNonQuery($"update ${traeTablaProds(tipoVenta)} set cat_gp_almacen = cat_gp_almacen - (${difCant}) where cat_gp_id = '${prodId}' "$)
If cant = 0 Then
LogColor($"BORRAMOS PRODUCTO - ${prodId}"$, Colors.Red)
@@ -1004,10 +1009,10 @@ End Sub
' resultado="OK" 'Ok si existe la promocion.
' prodsVariablesRequeridos=5} 'Cantidad de productos variables requeridos para la promoción.
Sub traePromo(promo As String, cliente As String) As Map
Private thisLog As Boolean = False
Private thisLog As Boolean = false
If thisLog Then Log("traePromo:"&promo)
Private inicioContador As String = DateTime.Now
Private c As Cursor = Starter.skmt.ExecQuery("Select * from promos_comp where cat_pa_id = '"& promo&"'") 'Obtenemos las el maximo de promocioones a otorgar.
Private c As Cursor = Starter.skmt.ExecQuery("Select * from promos_comp where cat_pa_id = '"& promo&"'") 'Obtenemos el maximo de promociones a otorgar.
Private siHistorico As String = 0
Private promoMap As Map
Private prodsFijos, prodsFijosPrecios, prodsFijosPiezas, prodsVariables, prodsVariablesPrecios As List
@@ -1019,32 +1024,38 @@ Sub traePromo(promo As String, cliente As String) As Map
prodsVariablesPrecios.Initialize
c.Position = 0
promoMap = CreateMap("id":promo, "maxXcliente":0, "maxRecurrente":0, "maxPromos":0) 'Ponemos el DEFAULT en CERO.
If c.RowCount > 0 Then promoMap = CreateMap("id":promo, "maxXcliente":c.GetString("CAT_PA_MAXPROMCLIE"), "maxRecurrente":c.GetString("CAT_PA_MAXPROMREC"), "maxPromos":c.GetString("CAT_PA_MAXPROM"))
If c.RowCount > 0 Then
promoMap = CreateMap("id":promo, "maxXcliente":c.GetString("CAT_PA_MAXPROMCLIE"), "maxRecurrente":c.GetString("CAT_PA_MAXPROMREC"), "maxPromos":c.GetString("CAT_PA_MAXPROM"))
End If
'######### PROMOCIONES SEGMENTADAS ##########
' Si la promo esta en la lista, SOLO los clientes que la tengan la pueden ver.
Private ps As Cursor = Starter.skmt.ExecQuery($"select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${cliente}'"$)
Private ps As Cursor = Starter.skmt.ExecQuery($"select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}'"$) ' and HCCP_CLIENTE = '${cliente}'
' Log($"select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}'"$)
If thisLog Then Log($"PROMOS SEGMENTADAS DISPONIBLES: ${ps.RowCount}"$)
If thisLog Then Log($"PROMOS SEGMENTADAS ENCONTRADAS: ${ps.RowCount}"$)
If thisLog Then Log(promoMap)
If ps.RowCount > 0 Then
ps.Position = 0
promoMap = CreateMap("id":promo, "maxXcliente":0, "maxRecurrente":0, "maxPromos":0) 'Si es segmentada la ponemos en cero, porque SOLO le debe de aparecer a ciertos clientes.
If thisLog Then Log($">>> PROMO "${promo}" SEGMENTADA PARA EL CLIENTE ${ps.GetString("HCCP_CLIENTE")}"$)
' Select hccp_cliente As valido from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${traecliente}'
Private ps2 As Cursor = Starter.skmt.ExecQuery($"Select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${traeCliente}' and HCCP_CANT > HCCP_CANT_VENDIDA"$)
' Log($"Select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${traeCliente}' and HCCP_CANT > HCCP_CANT_VENDIDA"$)
' Log($"registros:${ps2.RowCount}"$)
Log($"Select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}' and HCCP_CLIENTE = '${traeCliente}' and HCCP_CANT > HCCP_CANT_VENDIDA"$)
Log($"registros:${ps2.RowCount}"$)
If ps2.RowCount > 0 Then
ps2.Position = 0
If thisLog Then Log($"registros:${ps2.RowCount}, cliente: ${ps2.GetString("HCCP_CLIENTE")} cant:${ps2.GetString("HCCP_CANT")}"$)
promoMap = CreateMap("id":promo, "maxXcliente":(ps2.GetString("HCCP_CANT")-ps2.GetString("HCCP_CANT_VENDIDA")), "maxRecurrente":ps2.GetString("HCCP_CANT"), "maxPromos":ps2.GetString("HCCP_CANT")) 'Si es segmentada SOLO le aparece a ciertos clientes.
End If
ps2.Close
End If
ps.Close
If thisLog Then Log(promoMap)
' ########## TERMINA PROMOS SEGMENTADAS ##########
c = Starter.skmt.ExecQuery("Select count(*) as hist from HIST_PROMOS where HP_CLIENTE = '"& cliente & "' and HP_CODIGO_PROMOCION = '" & promo & "'") 'Revisamos si hay historico de la promoción.
c.Position = 0
If c.GetString("hist") > 0 Then siHistorico = 1
promoMap.Put("historico", siHistorico)
c.Close
c = Starter.skmt.ExecQuery("Select * from CAT_DETALLES_PAQ where CAT_DP_ID = '"& promo & "'") 'Obtenemos los detalles de la promoción.
c.Position = 0
If c.RowCount > 0 Then
@@ -1076,10 +1087,14 @@ Sub traePromo(promo As String, cliente As String) As Map
promoMap.Put("prodsVariablesCant", prodsVariables.Size)
promoMap.Put("prodsVariablesPrecios", prodsVariablesPrecios)
promoMap.Put("resultado", "ok")
' LogColor($"****************************************************************"$, Colors.red)
LogColor("*********** Prods Fijos: " & prodsFijos.Size & " Prods Variables: " & prodsVariables.Size & " ************", Colors.red)
' LogColor("***************** Prods Variables: " & prodsVariables.Size & " *************", Colors.red)
LogColor($"****************************************************************"$, Colors.red)
Else
promoMap.Put("resultado", "No hay datos de la promoción.")
End If
c.Close
c = Starter.skmt.ExecQuery("Select CAT_GP_STS, CAT_GP_NOMBRE from CAT_GUNAPROD2 where CAT_GP_ID = '"& promo & "'") 'Obtenemos las piezas requeridas de productos variables para la promoción.
c.Position = 0
Private pvr As String = 0
@@ -1093,12 +1108,13 @@ Sub traePromo(promo As String, cliente As String) As Map
If thisLog Then Log($"Inv variables: ${cuantosVariablesDisponiblesDB(promo)}"$)
If thisLog Then Log($"Inv dispo: ${traemosInventarioDisponibleParaPromo(promo)}"$)
If thisLog Then LogColor($"Promo ${promo}: ${promoMap}"$, Colors.Blue)
If thisLog Then LogColor("TIEMPO para traePromo -=" & promo & "=- : " & ((DateTime.Now-inicioContador)/1000), Colors.Red)
' If thisLog Then LogColor("TIEMPO para traePromo -=" & promo & "=- : " & ((DateTime.Now-inicioContador)/1000), Colors.Red)
Return promoMap
End Sub
'Regresa un mapa con el inventario disponible por producto para la promoción (desde la base de datos).
Sub traemosInventarioDisponibleParaPromo(promo As String) As Map 'ignore
Private thisLog As Boolean = False
Private c As Cursor
c = Starter.skmt.ExecQuery2("SELECT CAT_GP_ID, CAT_GP_ALMACEN FROM CAT_GUNAPROD2 WHERE CAT_GP_ID IN (select CAT_DP_IDPROD FROM CAT_DETALLES_PAQ WHERE CAT_DP_ID = ?)", Array As String(promo))
' Private prodInv As Map
@@ -1110,9 +1126,15 @@ Sub traemosInventarioDisponibleParaPromo(promo As String) As Map 'ignore
c.Position=i
prods.Put(c.GetString("CAT_GP_ID"), c.GetString("CAT_GP_ALMACEN"))
' Log($"prod:${c.GetString("CAT_GP_ID")}, inventario:${c.GetString("CAT_GP_ALMACEN")}"$)
If thisLog Then LogColor($"#### prod:${c.GetString("CAT_GP_ID")}, inventario:${c.GetString("CAT_GP_ALMACEN")}, inv2: ${traeExistenciasPorId(c.GetString("CAT_GP_ID"))}"$, Colors.Magenta)
If c.GetString("CAT_GP_ALMACEN") <> traeExistenciasPorId(c.GetString("CAT_GP_ID")) Then
If thisLog Then LogColor("#### ERROR DE INVENTARIO ####" , Colors.red)
End If
Next
' prodInv.Put("inventarios", prods)
End If
c.Close
Return prods
End Sub
@@ -1131,7 +1153,7 @@ Sub restaFijosPromo(promoMap As Map) As Map 'ignore
Private prodsFijos As List = promoMap.get("prodsFijos") 'Obtenemos un a lista con los productos fijos de la promoción.
If thisLog Then LogColor("ProdsFijos -> " & prodsFijos, Colors.red)
inventariosDisponiblesParaEstaPromo.Put("resultado", "No hay suficiente producto para la promocion.") 'Valor por default
Log($"Prods fijos requeridos ${prodsFijos.Size}"$)
If thisLog Then Log($"Prods fijos requeridos ${prodsFijos.Size}"$)
If prodsFijos.Size = 0 Then inventariosDisponiblesParaEstaPromo.Put("resultado", "ok") 'Si no lleva prods fijos la promo, entonces ponemos FIJOS OK.
For p = 0 To prodsFijos.Size - 1
Private t As String = prodsFijos.Get(p) 'Obtenemos el Id de este producto desde la lista de productos fijos.
@@ -1180,8 +1202,6 @@ Sub alcanzanLosVariablesParaPromo(promoMap As Map, inventarioSinFijos As Map) As
Return res
End Sub
'prodsFijos=[1000000126, 1008013885]
'Regresa el numero máximo de promociones permitidas, tomando en cuenta recurrentes, clientes y maxPromos.
Sub traeMaxPromos(pm As Map) As Int
Private thisLog As Boolean = True 'Si es verdadero, muestra los logs de este sub.
@@ -1196,11 +1216,11 @@ Sub traeMaxPromos(pm As Map) As Int
' Else
' LogColor("SIN HCCP CANT", Colors.Magenta)
' End If
If thisLog Then LogColor("==== HISTORICO:"&pm.Get("historico"), Colors.Red)
' If thisLog Then LogColor("==== Historico: "&pm.Get("historico"), Colors.Red)
' Log("### PRODS VARIABLES: " & pm.Get("prodsVariables"))
Private maxPromosXDescPV As String = B4XPages.MainPage.promos.ts.maxPromosPorProdsVariables(pm.Get("prodsVariables"), pm.Get("id"))
Log("########### " & maxPromosXDescPV)
If thisLog Then Log(pm)
Logcolor("########### maxPromosXDescPV " & maxPromosXDescPV, Colors.Yellow)
' If thisLog Then Log(pm)
maxPromos.Add(maxPromosXDescPV.As(Int))
If pm.Get("historico") = "1" Then maxPromos.Add(pm.Get("maxRecurrente")) 'Si hay historico, agregamos maxRecurrente
If pm.Get("maxPromos") <> "null" Then maxPromos.Add(pm.Get("maxPromos").As(Int)) 'Agregamos maxPromos
@@ -1210,14 +1230,15 @@ Sub traeMaxPromos(pm As Map) As Int
maxPromos.Add(hccp.GetInt("HCCP_CANT"))
End If
maxPromos.Sort(True)
If thisLog Then Log($">>>>> Max promos : ${maxPromos}"$)
If thisLog Then Log($" >>>>> MAX PROMOS X CONF : ${maxPromos} <==> ${maxPromos.Get(0)}"$)
mp = 0
If maxPromos.Size > 0 Then
mp0 = maxPromos.Get(0)
' Log(mp0)
mp = mp0 - traePromosVendidas(pm.Get("id"), traeCliente)
If thisLog Then Log($"Max Promos (${mp0}) - promos vendidas (${(traePromosVendidas(pm.Get("id"), traeCliente)).As(Int)}) = ${mp}"$)
If thisLog Then Log($" >>>>> MAX PROMOS - PROMOS VENDIDAS <==> ${mp0} - ${(traePromosVendidas(pm.Get("id"), traeCliente)).As(Int)} = ${mp}"$)
End If
hccp.Close
Return mp 'Regresamos el numero mas pequeño de las opciones.
End Sub
@@ -1230,52 +1251,66 @@ Sub traePromosVendidas(promo As String, cliente As String) As Int
c.Position = 0
If c.GetString("cuantas") <> Null Then pv = c.GetString("cuantas")
End If
c.Close
Return pv
End Sub
'3799, 7226, 7228, 7230
Sub procesaPromocion(idPromo As String, cliente As String) As Map 'ignore
Private thisLog As Boolean = True 'Si es verdadero, muestra los logs de este sub.
Private thisLog As Boolean = True 'Si es verdadero, muestra los logs de este sub.
Private inicioContador As String = DateTime.Now
Private mp As Int = 0
If thisLog Then LogColor($"********* Iniciamos revision de Promo ${idPromo} *********"$, Colors.red)
'Obtenemos el mapa con toda la info de la promoción.
Private pm As Map = traePromo(idPromo, cliente)
' B4XPages.MainPage.productos.promosC.traePromo(idPromo, cliente)
If thisLog Then LogColor(pm, Colors.Blue)
' If thisLog Then LogColor("|" & pm.Get("maxPromos") & "|", Colors.Blue)
' Log("|"&revisaMaxPromosProdsFijosPorInventario(pm)&"|")
If revisaMaxPromosProdsFijosPorInventario(pm) < 1 Then pm.Put("resultado", 0)
' Log($"resultado = ${pm.Get("resultado")}"$)
If pm.Get("resultado") = "ok" Then 'Si encontramos la promoción, entonces ...
'Buscamos el máximo de promociones permitidas.
mp = traeMaxPromos(pm)
' If thisLog Then LogColor($"Promociones permitidas=${mp}"$, Colors.Blue)
' If thisLog Then Log("Promos vendidas: " & traePromosVendidas(idPromo, cliente))
If mp < 1 Then
If thisLog Then LogColor("Ya se vendieron las promos PERMITIDAS para el cliente", Colors.red)
Return CreateMap("status":"ko", "mp":pm)
End If
'Restamos del inventario (mapa) las piezas necesarias para los productos fijos.
Private inventarioSinFijos As Map = restaFijosPromo(pm)
If thisLog Then LogColor("inventariosfijos="&inventarioSinFijos, Colors.Magenta)
If inventarioSinFijos.Get("resultado") = "ok" Then
'Revisamos que los productos variables requeridos sean menos que el inventario total (mapa).
Private pv As Boolean = alcanzanLosVariablesParaPromo(pm, inventarioSinFijos)
If thisLog Then Log("Alcanzan los variables? --> " & pv)
If pv Then Return CreateMap("status":"ok", "mp":pm) Else Return CreateMap("status":"ko", "mp":pm)
If thisLog Then LogColor($"****************************************************************"$, Colors.RGB(142,0,255))
If thisLog Then LogColor($"********* Iniciamos revision de Promo ${idPromo} *********"$, Colors.RGB(142,0,255))
If thisLog Then LogColor($"****************************************************************"$, Colors.RGB(142,0,255))
Try
'Obtenemos el mapa con toda la info de la promoción.
Private pm As Map = traePromo(idPromo, cliente)
' B4XPages.MainPage.productos.promosC.traePromo(idPromo, cliente)
If thisLog Then LogColor(pm, Colors.Blue)
' If thisLog Then LogColor("|" & pm.Get("maxPromos") & "|", Colors.Blue)
' Log("|"&revisaMaxPromosProdsFijosPorInventario(pm)&"|")
Private maxPromosXprodsFijos As Int = revisaMaxPromosProdsFijosPorInventario(pm)
If maxPromosXprodsFijos < 1 Then pm.Put("resultado", 0)
If thisLog Then LogColor($"***********************************************************************"$, Colors.Blue)
LogColor($"*** PROMOS DISPONIBLES X PRODS FIJOS (${idPromo}) = ${maxPromosXprodsFijos} ***"$, Colors.Blue)
If thisLog Then LogColor($"***********************************************************************"$, Colors.Blue)
If pm.Get("resultado") = "ok" Then 'Si encontramos la promoción, entonces ...
'Buscamos el máximo de promociones permitidas.
mp = traeMaxPromos(pm)
' If thisLog Then LogColor($"Promociones permitidas=${mp}"$, Colors.Blue)
' If thisLog Then Log("Promos vendidas: " & traePromosVendidas(idPromo, cliente))
If mp < 1 Then
If thisLog Then LogColor("Ya se vendieron las promos PERMITIDAS para el cliente", Colors.red)
Return CreateMap("status":"ko", "mp":pm)
End If
'Restamos del inventario (mapa) las piezas necesarias para los productos fijos.
Private inventarioSinFijos As Map = restaFijosPromo(pm)
If thisLog Then LogColor("inventariosfijos="&inventarioSinFijos, Colors.Magenta)
If inventarioSinFijos.Get("resultado") = "ok" Then
'Revisamos que los productos variables requeridos sean menos que el inventario total (mapa).
Private pv As Boolean = alcanzanLosVariablesParaPromo(pm, inventarioSinFijos)
If thisLog Then LogColor($"****************************************************"$, Colors.Blue)
If thisLog Then LogColor($"***** ¿ALCANZAN LOS VARIABLES? ==> ${IIf(pv, "SI", "NO")} *****"$, Colors.Blue)
If thisLog Then LogColor($"****************************************************"$, Colors.Blue)
If pv Then Return CreateMap("status":"ok", "mp":pm) Else Return CreateMap("status":"ko", "mp":pm)
Else
If thisLog Then LogColor("NO HAY INVENTARIO SUFICIENTE " & idPromo, Colors.red)
Return CreateMap("status":"ko", "mp":pm)
End If
Else
If thisLog Then LogColor("NO HAY INVENTARIO SUFICIENTE " & idPromo, Colors.red)
Return CreateMap("status":"ko", "mp":pm)
End If
Else
Return CreateMap("status":"ko", "mp":pm)
End If
' Si tenemos suficiente inventario para los variables mostramos la promocion, si no ...
' break 'NO HAY INVENTARIO SUFICIENTE PARA LA PROMOCION.
' Si tenemos suficiente inventario para los variables mostramos la promocion, si no ...
' break 'NO HAY INVENTARIO SUFICIENTE PARA LA PROMOCION.
LogColor("TIEMPO DE PROCESO ESTA PROMO: " & ((DateTime.Now-inicioContador)/1000), Colors.Red)
LogColor("TIEMPO DE PROCESO ESTA PROMO: " & ((DateTime.Now-inicioContador)/1000), Colors.Red)
Catch
Log($"Promo ${idPromo} mal configurada"$)
ToastMessageShow($"Promo ${idPromo} mal configurada"$, True)
Log(LastException)
' Agregamos esta línea para evitar el NullPointerException
Return CreateMap("status":"ko", "mp":Null)
End Try
End Sub
'Regresa cuantas promos alcanzan con los productos FIJOS que hay en inventario.
@@ -1323,35 +1358,47 @@ End Sub
'Regresa cuantas promos alcanzan con los productos FIJOS que hay en inventario.
Sub revisaMaxPromosProdsFijosPorInventario(pm As Map) As Int
Private thisLog As Boolean = True
Private thisLog As Boolean = False
Private invFijoXpromo As Map
Private t As List
t.Initialize
t.Add(traeMaxPromos(pm)) ' Agregamos a la lista las promos maximas permitidas (recurrente, cliente y promo).
If thisLog Then LogColor($"============ INICIA MAX PROMOS X PRODS FIJOS X INV ========"$, Colors.RGB(176,0,0))
If thisLog Then LogColor($" ### MAX PROMOS (recurrente, cliente y promo): ${t}"$, Colors.Green)
invFijoXpromo.Initialize
If thisLog Then LogColor($"pm=${pm}"$, Colors.Blue)
If thisLog Then LogColor($" pm=${pm}"$, Colors.Blue)
Private invDispParaPromo As Map = traemosInventarioDisponibleParaPromo(pm.Get("id"))
If thisLog Then Log($"invDispParaPromo=${invDispParaPromo}"$)
If thisLog Then Log($" invDispParaPromo=${invDispParaPromo}"$)
Private prodsFijosPiezas As List = pm.Get("prodsFijosPiezas")
Private idProdsFijos As List = pm.Get("prodsFijos")
Private idProdsFijosPrecios As List = pm.Get("prodsFijosPrecios")
For p = 0 To idProdsFijos.Size -1 'Generamos una lista con las promos disponibles por producto (dividimos el inventario total entre las piezas requeridas).
Private thisInvDisp As Int = 0
If invDispParaPromo.Get(idProdsFijos.Get(p)) <> Null Then thisInvDisp = invDispParaPromo.Get(idProdsFijos.Get(p))
If thisLog Then Log($"id=${idProdsFijos.Get(p)}, inv=${thisInvDisp}, pzas=${prodsFijosPiezas.Get(p)}"$)
' Log(">>>>> Monto Bonificacion: " & B4XPages.MainPage.promos.ts.traeMontoBonificacion(idProdsFijos.Get(p), pm.Get("id")))
' If thisLog Then LogColor(">> Max prods fijos x Bonificaciones: " & B4XPages.MainPage.promos.ts.traeBonificacionesMaximas("bonificaciones", clienteActual, idProdsFijos.Get(p), prodsFijosPiezas.Get(p), pm.Get("id")), Colors.blue)
t.Add(B4XPages.MainPage.promos.ts.traeBonificacionesMaximas("bonificaciones", clienteActual, idProdsFijos.Get(p), prodsFijosPiezas.Get(p), pm.Get("id")))
If thisLog Then Log($" id=${idProdsFijos.Get(p)}, inv=${thisInvDisp}, pzasReq=${prodsFijosPiezas.Get(p)}"$)
' LogColor($" ====== ${idProdsFijos.Get(p)} - Inv1:${thisInvDisp}, inv2: ${traeExistenciasPorId(idProdsFijos.Get(p))}"$, Colors.Magenta)
' If thisInvDisp <> traeExistenciasPorId(idProdsFijos.Get(p)) Then
' LogColor(" #### ERROR DE INVENTARIO ####" , Colors.red)
' End If
' If thisLog Then Log($"${(thisInvDisp / prodsFijosPiezas.Get(p))}"$)
Private x() As String = Regex.Split("\.", $"${(thisInvDisp / prodsFijosPiezas.Get(p))}"$) 'Separamos el resultado de la division por el punto decimal.
If thisLog Then Log(x(0))
t.Add(x(0).As(Int)) 'Solo guardamos la parte del entero de la division.
t.Add(x(0).As(Int)) 'Solo guardamos la parte del entero de la division. (promos por inventario)
' If thisLog Then LogColor($" ### T: ${t}"$, Colors.Green) 'promos por inventario
If thisLog Then LogColor($" >>>>> PROMOS X PRODS FIJOS (${idProdsFijos.Get(p)}): ${x(0)} <<<<<"$, Colors.red)
Log($" >>>>> Monto Bonificacion FIJOS (${idProdsFijos.Get(p)}): "$ & B4XPages.MainPage.promos.ts.traeMontoBonificacion(idProdsFijos.Get(p), idProdsFijosPrecios.Get(p), pm.Get("id"),"LOG_revisaMaxPromosProdsFijosPorInventario"))
If thisLog Then LogColor(" >> MAX PRODS FIJOS X BONIFICACIONES: " & B4XPages.MainPage.promos.ts.traeBonificacionesMaximas("bonificaciones", clienteActual, idProdsFijos.Get(p), prodsFijosPiezas.Get(p), idProdsFijosPrecios.Get(p), pm.Get("id")), Colors.blue)
t.Add(B4XPages.MainPage.promos.ts.traeBonificacionesMaximas("bonificaciones", clienteActual, idProdsFijos.Get(p), prodsFijosPiezas.Get(p), idProdsFijosPrecios.Get(p), pm.Get("id"))) 'Agregamos las promos disponibles por Trade Spending
If thisLog Then LogColor($" ### PROMOS X INV: ${t}"$, Colors.Green) 'promos por inventario
Next
t.Sort(True) 'Ordenamos la lista para que en el lugar 0 este el resultao mas pequeño.
If thisLog Then LogColor($"prodsFijos=${idProdsFijos}"$, Colors.Blue)
If thisLog Then LogColor($"prodsFijosPiezasReq=${prodsFijosPiezas}"$, Colors.Blue)
' If thisLog Then LogColor($"invFijoXpromo=${invFijoXpromo}"$, Colors.Blue)
LogColor(">>>>>> T: " & t, Colors.red)
If thisLog Then LogColor("Max promos de prodsFijos POR inventario = " & t.Get(0), Colors.red)
If thisLog Then LogColor($" prodsFijos=${idProdsFijos}"$, Colors.Blue)
If thisLog Then LogColor($" prodsFijosPiezasReq=${prodsFijosPiezas}"$, Colors.Blue)
' If thisLog Then LogColor($" invFijoXpromo=${invFijoXpromo}"$, Colors.Blue)
If thisLog Then LogColor(" >>>>>> T: " & t, Colors.Magenta)
LogColor(" ***********************************************************************", Colors.RGB(156,0,0))
LogColor($" ****** MAX PROMOS X INV DE PRODS FIJOS (${pm.get("id")}): "$ & t.Get(0) & " ******", Colors.RGB(156,0,0))
LogColor(" ***********************************************************************", Colors.RGB(156,0,0))
If thisLog Then LogColor($"============ TERMINA MAX PROMOS X PRODS FIJOS X INV ========"$, Colors.RGB(176,0,0))
Return t.Get(0) 'Regresamos el resultado mas pequeño.
End Sub
@@ -1361,7 +1408,7 @@ End Sub
'regresa el maximo por productos fijos. Ej. si las promos por variables es 10, pero el maximo por
'fijos es 5, entonces regresamos 5.
Sub revisaMaxPromosProdsVariablesPorInventario(pm As Map) As Int 'ignore
Private thisLog As Boolean = True
Private thisLog As Boolean = False
If thisLog Then LogColor("==================revisaMaxPromosProdsVariablesPorInventario====================", Colors.red)
If thisLog Then Log("======================================================")
Private invFijoXpromo As Map
@@ -1373,6 +1420,7 @@ Sub revisaMaxPromosProdsVariablesPorInventario(pm As Map) As Int 'ignore
Private maxPromos As String = traeMaxPromos(pm)
Private maxPromosXFijos As Int = revisaMaxPromosProdsFijosPorInventario(pm)
Private idProdsVariables As List = pm.Get("prodsVariables")
Private prodsVariablesPrecios As List = pm.Get("prodsVariablesPrecios")
Private prodsVariablesRequeridos As Int = pm.Get("prodsVariablesRequeridos")
Private prodsFijosPiezas As List = pm.Get("prodsFijosPiezas")
Private idProdsFijos As List = pm.Get("prodsFijos")
@@ -1402,9 +1450,9 @@ Sub revisaMaxPromosProdsVariablesPorInventario(pm As Map) As Int 'ignore
End If
Log(pm.Get("prodsFijos").As(List).Size)
Log(maxPromosXFijos)
' Log(pm.Get("prodsFijos").As(List).Size)
' Log(maxPromosXFijos)
For x = 1 To maxPromosXFijos
If thisLog Then Log("==================== maxPromosXFijos "& x &" ========================")
If thisLog Then Log("=====================================================")
@@ -1422,12 +1470,12 @@ Sub revisaMaxPromosProdsVariablesPorInventario(pm As Map) As Int 'ignore
Log($"Este prodVariable: ${idProdsVariables.Get(i)}"$)
Log($"Este invDisponible: ${invDispParaPromo.Get(idProdsVariables.Get(i))}"$)
' Log(">> Monto Bonificacion: " & B4XPages.MainPage.promos.ts.traeMontoBonificacion(idProdsVariables.Get(i), pm.Get("id")))
prodsVariablesXPresupuestoBonificaciones.Add(B4XPages.MainPage.promos.ts.traeBonificacionesMaximas("bonificaciones", clienteActual, idProdsVariables.Get(i), prodsVariablesRequeridos, pm.Get("id")))
prodsVariablesXPresupuestoBonificaciones.Add(B4XPages.MainPage.promos.ts.traeBonificacionesMaximas("bonificaciones", clienteActual, idProdsVariables.Get(i), prodsVariablesRequeridos, prodsVariablesPrecios.Get(i), pm.Get("id")))
' If thisLog Then LogColor(">> Max prods fijos x Bonificaciones: " & B4XPages.MainPage.promos.ts.traeBonificacionesMaximas("bonificaciones", clienteActual, idProdsVariables.Get(i), prodsVariablesRequeridos, pm.Get("id")), Colors.blue)
totalProdsVariablesDisponibles = totalProdsVariablesDisponibles + invDispParaPromo.Get(idProdsVariables.Get(i))
End If
Next
If thisLog Then Log($"prodsVariablesXPresupuestoBonificaciones: ${prodsVariablesXPresupuestoBonificaciones}"$)
If thisLog Then Log($"1924: ${prodsVariablesXPresupuestoBonificaciones}"$)
'Revisamos variables.
If thisLog Then Log($"Var disponibles - var requeridos : ${totalProdsVariablesDisponibles} - ${prodsVariablesRequeridos*x}"$)
totalProdsVariablesDisponibles = totalProdsVariablesDisponibles - (prodsVariablesRequeridos*x)
@@ -1469,6 +1517,7 @@ Sub cuantosVariablesDisponiblesDB(promo As String)
If c.GetString("CAT_GP_ALMACEN") <> Null Then x = c.GetString("CAT_GP_ALMACEN")
Next
End If
c.Close
End If
Return x
End Sub
@@ -1531,20 +1580,30 @@ Sub borraPedidoClienteActual As String
Log($"Borramos pedido del cliente ${traeCliente}"$)
Private thisC As Cursor
' Private tablaProds As String = "cat_gunaprod2"
thisC = Starter.skmt.ExecQuery("select PE_PROID, PE_CANT, PE_CEDIS FROM PEDIDO where pe_cliente in (Select CUENTA from cuentaa) and PE_CEDIS <> 'DOE'")
thisC = Starter.skmt.ExecQuery("select PE_PROID, PE_CANT, PE_CEDIS, PE_COSTOU FROM PEDIDO where pe_cliente in (Select CUENTA from cuentaa) and PE_CEDIS <> 'DOE'")
Log($"Registros = ${thisC.RowCount}"$)
If thisC.RowCount > 0 Then
For i = 0 To thisC.RowCount - 1
thisC.Position=i
thisC.Position = i
Log($"Posicion: ${i}, PE_CEDIS=${thisC.GetString("PE_CEDIS")}"$)
If thisC.GetString("PE_CEDIS") <> "DUR" Then
Starter.skmt.ExecNonQuery2($"update ${traeTablaProds(Starter.tipov)} set cat_gp_almacen = cat_gp_almacen + ? where cat_gp_id = ?"$, Array As Object(thisC.GetString("PE_CANT"), thisC.GetString("PE_PROID")))
Log("No DUR")
'Codigo para regresar dinero al presupuesto de BONIFICACIONES (Trend Spending)
Private precio0 As String = traePrecio(thisC.GetString("PE_PROID"))
Private precioConDesc As String = (B4XPages.MainPage.cliente.kh.traeDescXSku(traeCliente, thisC.GetString("PE_PROID"))/100)*precio0
Log(precioConDesc)
Log("precioConDesc: " & precioConDesc)
Log(">>>>>>>>>>>>> " & (precioConDesc * thisC.GetString("PE_CANT")))
modTrendSpending("suma", "bonificaciones", (precioConDesc * thisC.GetString("PE_CANT")))
If Not(IsNumber(thisC.GetString("PE_CEDIS"))) Then ' Si es promo, entonces es bonificacion.
Private desc As String = B4XPages.MainPage.promos.ts.traeMontoBonificacion(thisC.GetString("PE_PROID"), thisC.GetString("PE_COSTOU"), thisC.GetString("PE_CEDIS"),"borraPedidoClienteActual")
desc = desc * thisC.GetString("PE_CANT")
Log("Regresamos bonificaciones " & thisC.GetString("PE_PROID") & "=" & desc)
modTrendSpending("suma", "bonificaciones", desc)
Else ' Si no es promo, entonces es descuento.
Log("Regresamos descuentos " & thisC.GetString("PE_PROID") & "=" & (precioConDesc * thisC.GetString("PE_CANT")))
modTrendSpending("suma", "descuentos", (precioConDesc * thisC.GetString("PE_CANT")))
End If
'Termina Trend Spending
Starter.skmt.ExecNonQuery2($"update ${traeTablaProds(Starter.tipov)} set cat_gp_almacen = cat_gp_almacen + ? where cat_gp_id = ?"$, Array As Object(thisC.GetString("PE_CANT"), thisC.GetString("PE_PROID")))
End If
' Starter.skmt.ExecNonQuery2("INSERT INTO INVENT_X_ENVIAR (ALMACEN , PROID , CANTIDAD ) VALUES(?,?,?) ", Array As Object (traeAlmacen, thisC.GetString("PE_PROID"),thisC.GetString("PE_CANT")* -1))
Next
@@ -1555,9 +1614,6 @@ Sub borraPedidoClienteActual As String
If thisC.RowCount < 1 Then Starter.skmt.ExecNonQuery("delete from pedido_cliente where pc_cliente in (Select CUENTA from cuentaa)")
Log("###### delete from pedido_cliente - " & traeCliente)
Starter.skmt.ExecNonQuery("UPDATE kmt_info set gestion = 0 where CAT_CL_CODIGO In (select cuenta from cuentaa)")
Return 1
End Sub
@@ -1654,7 +1710,7 @@ Sub guardaCambiosDeProducto(cantidad, prodNombre, prodId, precio2, query) 'ignor
a = Starter.skmt.ExecQuery("select USUARIO from usuarioa")
a.Position=0
usuario = a.GetString("USUARIO")
Starter.skmt.ExecNonQuery2("INSERT INTO PEDIDO (PE_CEDIS, PE_COSTO_TOT, PE_COSTOU, PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_FECHA, PE_USUARIO, PE_TIPO, PE_PRECIO2) VALUES(?,?,?,?,?,?,?,?,?,?,?) ", Array As Object ("DUR", (precio2 * -1), ((precio2/cantidad) * -1), cantidad, "CAMBIO" & prodNombre, prodId, clie_id, sDate & sTime, usuario, Starter.tipov, precio2))
Starter.skmt.ExecNonQuery2("INSERT INTO PEDIDO (PE_CEDIS, PE_COSTO_TOT, PE_COSTOU, PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_FECHA, PE_USUARIO, PE_TIPO, PE_PRECIO2, PE_ENVIADO) VALUES(?,?,?,?,?,?,?,?,?,?,?,0) ", Array As Object ("DUR", (precio2 * -1), ((precio2/cantidad) * -1), cantidad, "CAMBIO" & prodNombre, prodId, clie_id, sDate & sTime, usuario, Starter.tipov, precio2))
Starter.skmt.ExecNonQuery2("update " & query & " set cat_gp_almacen = cat_gp_almacen - ? where cat_gp_id = ? ", Array As Object(cantidad, prodId))
End Sub
@@ -1695,7 +1751,7 @@ Sub agrupador()
' Log($"Ya imprimio=${YA_IMPRIMIO}"$)
Starter.skmt.ExecNonQuery("delete from pedido3")
Starter.skmt.ExecNonQuery("UPDATE PEDIDO SET PE_FOLIO = 0 where PE_FOLIO IS NULL")
Starter.skmt.ExecNonQuery("INSERT INTO PEDIDO3 (PE_PRECIO2, PE_TIPO, PE_DESC, PE_COSTO_SIN, PE_RUTA, PE_CEDIS, PE_COSTO_TOT, PE_COSTOU, PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_USUARIO ) SELECT PE_PRECIO2, PE_TIPO, PE_DESC, PE_COSTO_SIN, PE_RUTA, PE_CEDIS, SUM(PE_COSTO_TOT) AS PE_COSTO_TOT, PE_COSTOU, SUM(PE_CANT) As PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_USUARIO FROM PEDIDO WHERE PE_CLIENTE IN (Select CUENTA from cuentaa) GROUP BY PE_PRECIO2, PE_TIPO, PE_DESC, PE_COSTO_SIN, PE_RUTA, PE_CEDIS, PE_COSTOU, PE_PRONOMBRE, PE_PROID, PE_CLIENTE ")
Starter.skmt.ExecNonQuery("INSERT INTO PEDIDO3 (PE_PRECIO2, PE_TIPO, PE_DESC, PE_COSTO_SIN, PE_RUTA, PE_CEDIS, PE_COSTO_TOT, PE_COSTOU, PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_USUARIO, PE_ENVIADO) SELECT PE_PRECIO2, PE_TIPO, PE_DESC, PE_COSTO_SIN, PE_RUTA, PE_CEDIS, SUM(PE_COSTO_TOT) AS PE_COSTO_TOT, PE_COSTOU, SUM(PE_CANT) As PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_USUARIO, PE_ENVIADO FROM PEDIDO WHERE PE_CLIENTE IN (Select CUENTA from cuentaa) GROUP BY PE_PRECIO2, PE_TIPO, PE_DESC, PE_COSTO_SIN, PE_RUTA, PE_CEDIS, PE_COSTOU, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_ENVIADO")
' Log("update pedido3")
Starter.skmt.ExecNonQuery2("UPDATE PEDIDO3 SET PE_FOLIO = ? WHERE PE_CLIENTE IN (Select CUENTA from cuentaa)", Array As Object(YA_IMPRIMIO))
Starter.skmt.ExecNonQuery("delete from pedido WHERE PE_CLIENTE IN (Select CUENTA from cuentaa)")
@@ -1743,7 +1799,8 @@ Sub horaNormal(fecha As String) As String 'ignore
Return nuevaFecha
End Sub
'En geocerca si mete la contraseña poner 0 en precision gps y si esta dentro de los 50 mts poner 1 y 2 para eventos que no lo ocupen
'Guarda en la tabla BitacoraGPS el evento espcificado en eventob, junto con coordenadas y otros datos.
'En precision,si metio contraseña para brincar la geocerca, poner 0 gps, si esta dentro de los 50 mts poner 1 y 2 para eventos que no lo ocupen.
'Mandar fecha de sync(sysdate)
Sub bitacora(fechab As String, usuariob As String, almacenb As String, rutab As String, eventob As String, clienteb As String, iniciob As String, finb As String, latitudb As String, longitudb As String, precision As String, motivonoventa As String, motivonovisita As String )
Log(motivonovisita)
@@ -2008,7 +2065,7 @@ Sub revisaHora As Boolean
Private hr As Int = h.GetString("CAT_VA_VALOR")
DateTime.DateFormat = "HH"
Private ahora As String = DateTime.Date(DateTime.Now)
' Log($"${hr} >= ${(ahora - 2)} and ${hr} <= ${(ahora + 2)}"$)
Log($"${hr} >= ${(ahora - 2)} and ${hr} <= ${(ahora + 2)}"$)
If hr >= ahora - 2 And hr <= ahora + 2 Then
horaCorrecta = True
End If
@@ -2066,11 +2123,23 @@ End Sub
' 0 si son IGUALES
' 1 si versionActual es MAYOR que versionMinima
Sub comparaVersiones(versionMinima As String, versionActual As String) As Int
Dim Pattern As String = "[^0-9.]"
Log(versionMinima)
If versionMinima = "NA" Then Return 0 ' Si version minima es igal a "NA" regresamos "Version valida"
versionMinima = Regex.Replace(Pattern, versionMinima, "") ' Quitamos todo lo que no sea numero o punto.
versionActual = Regex.Replace(Pattern, versionActual, "") ' Quitamos todo lo que no sea numero o punto.
Log($"${versionMinima}|${versionActual}"$)
Dim partesMin() As String = Regex.Split("\.", versionMinima)
Dim partesAct() As String = Regex.Split("\.", versionActual)
If partesMin.Length < 2 Then
' ToastMessageShow("Version incorrecta", False)
LogColor("VERSION INCORRECTA", Colors.red)
Return -1 ' ← Actual no cumple el formato mínimo
End If
' Si la actual tiene MENOS partes que la mínima, es inválida (opcional)
If partesAct.Length < partesMin.Length Then
ToastMessageShow("Version incorrecta", False)
' ToastMessageShow("Version incorrecta", False)
LogColor("VERSION INCORRECTA", Colors.red)
Return -1 ' ← Actual no cumple el formato mínimo
End If
' Compara solo las partes que existen en la versión mínima
@@ -2078,7 +2147,7 @@ Sub comparaVersiones(versionMinima As String, versionActual As String) As Int
Dim numMin As Int = partesMin(i)
Dim numAct As Int = partesAct(i)
If numAct < numMin Then
ToastMessageShow("Versión vieja, por favor actualizar!", False)
ToastMessageShow("Versión descontinuada, por favor actualizar!", False)
Return -1 ' Actual es menor
Else If numAct > numMin Then
Return 1 ' Actual es mayor
@@ -2144,12 +2213,12 @@ Sub modTrendSpending(accion As String, tipo As String, monto As String)
d.Position = 0
acumulado = d.GetString("ACUMULADO")
End If
Log("acumulado:" & acumulado & " | monto: " & monto)
Private c As Cursor = Starter.skmt.ExecQuery($"select HIST_TSS_TIPO, ${HIST_TSS_SEMANA} as disponible, ${HIST_TSS_SEMANA_ACUM} as acumulado from HIST_TREND_SPENDING_SEMANAL where HIST_TSS_TIPO = '${tipo.ToUpperCase}'"$)
Log("acumulado: " & acumulado & " | monto: " & monto)
Private c As Cursor = Starter.skmt.ExecQuery($"select HIST_TSS_TIPO, ifnull(${HIST_TSS_SEMANA},0) as disponible, ifnull(${HIST_TSS_SEMANA_ACUM},0) as acumulado from HIST_TREND_SPENDING_SEMANAL where HIST_TSS_TIPO = '${tipo.ToUpperCase}'"$)
If accion.ToUpperCase = "RESTA" Then
If c.RowCount > 0 Then
c.Position = 0
If tipo.ToUpperCase = "BONIFICACIONES" Or tipo.ToUpperCase = "RMI" Then
If tipo.ToUpperCase = "BONIFICACIONES" Or tipo.ToUpperCase = "RMI" Or tipo.ToUpperCase = "DESCUENTOS" Then
Private nuevaBonificacion As String = NumberFormat2((acumulado + monto), 1, 2, 2, False)
LogColor($"Nuevo acumulado ${tipo} = ${nuevaBonificacion}"$, Colors.Magenta)
Starter.skmt.ExecNonQuery($"delete from TREND_SPENDING where tipo = '${tipo.ToUpperCase}' "$)
@@ -2160,9 +2229,9 @@ Sub modTrendSpending(accion As String, tipo As String, monto As String)
else if accion.ToUpperCase = "SUMA" Then
If c.RowCount > 0 Then
c.Position = 0
If tipo.ToUpperCase = "BONIFICACIONES" Or tipo.ToUpperCase = "RMI" Then
If tipo.ToUpperCase = "BONIFICACIONES" Or tipo.ToUpperCase = "RMI" Or tipo.ToUpperCase = "DESCUENTOS" Then
Private nuevaBonificacion As String = NumberFormat2((acumulado - monto), 1, 2, 2, False)
LogColor($"Nueva bonificacion = ${nuevaBonificacion}"$, Colors.Magenta)
LogColor($"Nueva ${tipo} = ${nuevaBonificacion}"$, Colors.Magenta)
Starter.skmt.ExecNonQuery($"delete from TREND_SPENDING where tipo = '${tipo.ToUpperCase}' "$)
Starter.skmt.ExecNonQuery($"insert into TREND_SPENDING (tipo, acumulado) values ('${tipo.ToUpperCase}', '${nuevaBonificacion}')"$)
End If
@@ -2328,4 +2397,155 @@ End Sub
' precio = c.GetString("CAT_MONTO")
' End If
' Return precio
'End Sub
'End Sub
' Revisa que la contraseña sea la correcta: pass1 + dia (sin ceros) + hora (24 hrs sin ceros)
Sub revisaContrasenaHoy
Private pass1 As String = "KMT"
Private contrasenaHoy As String = pass1 & DateTime.GetDayOfMonth(DateTime.Now) & DateTime.GetHour(DateTime.now)
Log($"${contrasenaHoy}"$)
' Log(New)
' If New = contrasenaHoy Then
' p_login.Visible = False
' Sleep(80)
' et_usuario.Text = ""
' If Not(versionOk) Then ExitApplication 'Si la version no es correcta, salimos de la aplicacion.
' kb.HideKeyboard
' End If
End Sub
' Trae las existencias de un producto dado desde CAT_GUNAPROD5 (inventario original) menos el total de producto en PEDIDO.
Sub traeExistenciasPorId(id As String) As Int
' Private inv As Cursor = Starter.skmt.ExecQuery($"Select
' inv.cat_gp_id, inv.cat_gp_almacen - IFNULL(ventas.total_vendido, 0) As inventario_final
' FROM ${traeTablaProds(Starter.tipov)} As inv
' LEFT JOIN
' (Select pe_proid, SUM(pe_cant) As total_vendido FROM pedido
' WHERE pe_tipo = 'VENTA' GROUP BY pe_proid) As ventas
' ON inv.cat_gp_id = ventas.pe_proid
' WHERE inv.cat_gp_id = '${id}'"$)
Dim vendido As Int = 0
Dim existencias As Int = 0
Private inv As Cursor = Starter.skmt.ExecQuery($"select cat_gp_almacen from cat_gunaprod5 where cat_gp_id = '${id}'"$)
If inv.RowCount > 0 Then
inv.position = 0
existencias = inv.GetString("CAT_GP_ALMACEN").As(Int)
End If
' Log("ex:" & existencias)
inv = Starter.skmt.ExecQuery($"Select ifnull(SUM(pe_cant),0) As total_vendido FROM pedido WHERE pe_tipo = 'VENTA' and pe_proid = '${id}'"$)
inv.Position = 0
vendido = inv.GetInt("total_vendido")
' Log("ven:" & vendido)
existencias = (existencias - vendido)
inv.Close
Return existencias
End Sub
' Devuelve True si la hora actual está entre las 5:00 AM y las 22:30 PM
Sub EstaEnHorarioPermitido As Boolean
' Obtener la hora y el minuto actual
Dim HoraActual As Int = DateTime.GetHour(DateTime.Now)
Dim MinutoActual As Int = DateTime.GetMinute(DateTime.Now)
' Convertir la hora actual a minutos totales desde la medianoche para una comparación simple
Dim TiempoActualEnMinutos As Int = (HoraActual * 60) + MinutoActual
' Definir los límites del horario permitido en minutos
Dim InicioEnMinutos As Int = (5 * 60) + 0 ' 5:00 AM = 300 minutos
Dim FinEnMinutos As Int = (22 * 60) + 30 ' 22:30 PM = 1350 minutos
' Comprobar si la hora actual está dentro del rango
If TiempoActualEnMinutos >= InicioEnMinutos And TiempoActualEnMinutos <= FinEnMinutos Then
Return True
Else
Return False
End If
End Sub
'Desahabilita validaciones de Ruta y Version
Sub deshabilitaValidaciones
Log("Deshabilitamos VERIFY_DEVICE")
Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("VERIFY_DEVICE"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("VERIFY_DEVICE", 0))
Log("Deshabilitamos VALIDA_VERSION")
Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("VALIDA_VERSION"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("VALIDA_VERSION", 0))
Log("Espeificamos LIGADO")
Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("LIGADO"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("LIGADO", 1))
' B4XPages.MainPage.principal.Btn_CheckList.Enabled = True
' B4XPages.MainPage.principal.trabajar.Enabled = True
' B4XPages.MainPage.principal.Resumen.Enabled = True
' B4XPages.MainPage.principal.BUSCA.Enabled = True
ToastMessageShow("REALIZADO", False)
End Sub
' Recalcula en inventario actual, utiliza la tabla CAT_GUNAPROD5 que tiene el inventario INICIAL y le resta
' lo que hay en PEDIDO, y actualiza CAT_GUNAPROD2 con el valor calculado.
Public Sub RecalcularInventario
Private inicial As Long = DateTime.Now
' 1. Índices: ESTO ES CRUCIAL. Si no tienes estos índices, ningún query será rápido.
' Ejecuta esto una sola vez al crear la BD o al iniciar la app, no en cada cálculo.
' skmt.ExecNonQuery("CREATE INDEX IF NOT EXISTS idx_pedido_proid ON PEDIDO(PE_PROID)")
' skmt.ExecNonQuery("CREATE INDEX IF NOT EXISTS idx_pedido_cliente ON PEDIDO(PE_CLIENTE)")
' skmt.ExecNonQuery("CREATE INDEX IF NOT EXISTS idx_cat5_id ON CAT_GUNAPROD5(CAT_GP_ID)")
Starter.skmt.BeginTransaction
Try
' Lógica del Query:
' 1. Toma el inventario inicial del día desde CAT_GUNAPROD5 (T5).
' 2. Le resta SOLO las ventas reales de la tabla PEDIDO.
' 3. FILTRA (Ignora) los RMIs usando PE_CEDIS <> 'DUR' y el nombre '%CAMBIO%'.
' 4. Actualiza CAT_GUNAPROD2 masivamente.
' Dim sql As String = _
' "UPDATE CAT_GUNAPROD2 " & _
' "SET CAT_GP_ALMACEN = ( " & _
' " SELECT (IFNULL(T5.CAT_GP_ALMACEN, 0) - IFNULL(Ventas.CantidadVendida, 0)) " & _
' " FROM CAT_GUNAPROD5 T5 " & _
' " LEFT JOIN ( " & _
' " SELECT PE_PROID, SUM(PE_CANT) AS CantidadVendida " & _
' " FROM PEDIDO " & _
' " WHERE PE_CLIENTE <> '0' " & _
' " AND PE_CEDIS <> 'DUR' " & _
' " AND PE_PRONOMBRE NOT LIKE '%CAMBIO%' " & _
' " GROUP BY PE_PROID " & _
' " ) Ventas ON T5.CAT_GP_ID = Ventas.PE_PROID " & _
' " WHERE T5.CAT_GP_ID = CAT_GUNAPROD2.CAT_GP_ID " & _
' ") " & _
' "WHERE EXISTS ( " & _ '<-- ESTA ES LA CLAVE QUE EVITA LOS NULLS
' " SELECT 1 FROM CAT_GUNAPROD5 T5 " & _
' " WHERE T5.CAT_GP_ID = CAT_GUNAPROD2.CAT_GP_ID " & _
' ")"
Dim sql As String = _
"UPDATE CAT_GUNAPROD2 " & _
"SET CAT_GP_ALMACEN = ( " & _
" SELECT (IFNULL(INV.CI_INVENTARIO, 0) - IFNULL(Ventas.CantidadVendida, 0)) " & _
" FROM CAT_INVENTARIO INV " & _
" LEFT JOIN ( " & _
" SELECT PE_PROID, SUM(PE_CANT) AS CantidadVendida " & _
" FROM PEDIDO " & _
" WHERE PE_CLIENTE <> '0' " & _
" AND PE_CEDIS <> 'DUR' " & _
" AND PE_PRONOMBRE NOT LIKE '%CAMBIO%' " & _
" GROUP BY PE_PROID " & _
" ) Ventas ON INV.CI_IDPROD = Ventas.PE_PROID " & _
" WHERE INV.CI_IDPROD = CAT_GUNAPROD2.CAT_GP_ID " & _
") " & _
"WHERE EXISTS ( " & _
" SELECT 1 FROM CAT_INVENTARIO INV " & _
" WHERE INV.CI_IDPROD = CAT_GUNAPROD2.CAT_GP_ID " & _
")"
' Ejecutamos el cálculo masivo
Starter.skmt.ExecNonQuery(sql)
Starter.skmt.TransactionSuccessful
If Starter.Logger Then Log("Inventario Sincronizado (Excluyendo RMIs)")
Catch
Log("Error al recalcular inventario: " & LastException)
End Try
Starter.skmt.EndTransaction
LogColor(">>>>> Tiempo de RecalcularInventario: " & ((DateTime.Now - inicial)/1000), Colors.red)
End Sub

127
B4A/_git_tag.ps1 Normal file
View File

@@ -0,0 +1,127 @@
# --- SCRIPT DE COMMIT Y TAG (MODO IDE B4A) ---
# 0. CONFIGURACIÓN
$HacerPush = $true # Cambia a $true para que suba los cambios a GitHub
# Cargar librería visual para el MessageBox (por si se necesita en el Push)
Add-Type -AssemblyName System.Windows.Forms
# 1. AUTODESCUBRIMIENTO
$projectPath = $PSScriptRoot
Write-Host "Ruta del proyecto: $projectPath"
$b4aFileItem = Get-ChildItem -Path $projectPath -Filter "*.b4a" | Select-Object -First 1
if (-Not $b4aFileItem) {
Write-Host "ERROR: No hay archivo .b4a en esta carpeta."
return
}
$projectName = $b4aFileItem.BaseName
Write-Host "Proyecto detectado: $projectName"
# 2. LEER VERSIÓN
$versionLine = Get-Content $b4aFileItem.FullName | Select-String "#VersionName:"
if (-Not $versionLine) {
Write-Host "ERROR: Falta #VersionName en el archivo .b4a"
return
}
$version = ($versionLine -split ":")[1].Trim()
# Reemplaza cualquier espacio en blanco por un guion bajo solo para el tag
$tagName = "$version".Replace(" ", "_")
Set-Location $projectPath
# 3. COMMIT CON TORTOISEGIT
$oldCommit = git rev-parse HEAD 2>$null
Write-Host "----------------------------------------"
Write-Host "Version a etiquetar: $version"
Write-Host "Abriendo ventana de TortoiseGit..."
$pathArg = '/path:"{0}"' -f $projectPath
$msgArg = '/logmsg:"VERSION {0}"' -f $version
$cmdArg = "/command:commit"
Start-Process "TortoiseGitProc.exe" -ArgumentList $cmdArg, $pathArg, $msgArg
Write-Host "Esperando a que termines el commit en TortoiseGit..."
# El freno de mano: espera a que cierres la ventana
while (Get-Process "TortoiseGitProc" -ErrorAction SilentlyContinue) {
Start-Sleep -Seconds 1
}
$newCommit = git rev-parse HEAD 2>$null
# 4. VALIDACIÓN
if ($oldCommit -eq $newCommit) {
Write-Host "WARNING: Commit cancelado o sin cambios detectados."
return
}
Write-Host "Commit registrado exitosamente: $newCommit"
# 5. GESTIÓN DE TAGS
$tagGenerado = $false
# Revisamos si el tag ya existe localmente y lo borramos para recrearlo con el nuevo commit
if (git tag -l $tagName) {
git tag -d $tagName 2>$null | Out-Null
}
# Creamos el tag nuevo apuntando al commit que acabamos de hacer
git tag -a $tagName -m "Release version $version"
if ($?) { $tagGenerado = $true }
# 6. LÓGICA DE PUSH
if ($HacerPush) {
Write-Host "Conectando con GitHub..."
$remoteTagInfo = git ls-remote --tags origin $tagName
if ($remoteTagInfo) {
# Conflicto: Ya existe en remoto
$topForm = New-Object System.Windows.Forms.Form
$topForm.TopMost = $true
$topForm.Opacity = 0
$topForm.ShowInTaskbar = $false
$topForm.StartPosition = "CenterScreen"
$topForm.Show()
$topForm.Activate()
[System.Console]::Beep(1000, 200)
$msgBody = "El tag '$tagName' YA EXISTE en GitHub.`n`nDeseas SOBRESCRIBIRLO?`n`nSi = Borrar anterior y actualizar (Force Push).`nNo = Subir solo codigo (mantener tag viejo)."
$msgTitle = "Conflicto de Versiones - $projectName"
$respuesta = [System.Windows.Forms.MessageBox]::Show($topForm, $msgBody, $msgTitle, "YesNo", "Warning")
$topForm.Dispose()
if ($respuesta -eq "Yes") {
Write-Host "Sobrescribiendo tag en GitHub (Force Push)..."
git push origin
git push origin $tagName --force
} else {
Write-Host "Conservando tag anterior en GitHub..."
git push origin
}
} else {
# Tag Nuevo
Write-Host "Subiendo codigo y tag nuevo a GitHub..."
git push origin --follow-tags
}
} else {
Write-Host "Push OMITIDO (Switch de control apagado)."
}
# 7. REPORTE FINAL PARA EL IDE
$EstadoPush = if($HacerPush) { "SI" } else { "NO (Modo de prueba local)" }
$EstadoTag = if($tagGenerado) { "SI ($tagName)" } else { "NO (Error al generar)" }
Write-Host ""
Write-Host "========================================"
Write-Host " REPORTE DE VERSION "
Write-Host "========================================"
Write-Host " PROYECTO : $projectName"
Write-Host " TAG CREADO : $EstadoTag"
Write-Host " PUSH GITHUB: $EstadoPush"
Write-Host "========================================"

127
B4A/_juntaBas.ps1 Normal file
View File

@@ -0,0 +1,127 @@
# SCRIPT: _juntaBas_Master_FinalIA.ps1
# FIX: Corregida sintaxis de comillas y concatenación de tags XML.
# OBJETIVO: Fuente de verdad para IA con navegación ultra estructurada.
$ErrorActionPreference = 'SilentlyContinue'
$Dir = Get-Location
$LT = [char]60; $GT = [char]62; $SL = [char]47
$NL = [Environment]::NewLine
Write-Output '--- GENERANDO MASTER IA DEFINITIVO (FIX ESTRUCTURAL) ---'
# 1. PARSEO DEL PROYECTO .B4A
$b4a = Get-ChildItem -Path ".\*" -Include "*.b4a" -Recurse | Select-Object -First 1
$Name = 'App'; $Ver = '0.0'; $ModulosValidos = @(); $Librerias = @()
if ($b4a) {
$lines = [System.IO.File]::ReadAllLines($b4a.FullName)
foreach ($L in $lines) {
if ($L -match '#ApplicationLabel:\s*(.*)') { $Name = $Matches[1].Trim() }
if ($L -match '#VersionName:\s*(.*)') { $Ver = $Matches[1].Trim() }
if ($L -match '^Module\d+=(.*)') {
$m = [System.IO.Path]::GetFileName($Matches[1].Trim())
if (-not $m.EndsWith(".bas") -and $m -ne "Main") { $m += ".bas" }
$ModulosValidos += $m
}
if ($L -match '^Library\d+=(.*)') { $Librerias += $Matches[1].Trim() }
}
}
$OutName = "_" + $Name + "_" + $Ver + "_IA.md"
$OutFile = Join-Path $Dir $OutName
# 2. HEADER CON TUS INSTRUCCIONES CRÍTICAS
$CurrentDate = Get-Date -Format 'yyyy-MM-dd HH:mm'
$Header = @"
# PROYECTO: $Name
- Version: $Ver
- Fecha: $CurrentDate
- Librerias Activas: $($Librerias -join ", ")
## INSTRUCCIONES CRITICAS (B4A / BASIC4ANDROID)
0. **Integridad del Contexto:** Antes de procesar peticiones, cuenta si el numero de modulos listados en el indice coincide con los detallados en el cuerpo.
1. **Source of Truth (Codigo):** Este archivo contiene el codigo fuente ACTUAL del proyecto.
2. **Source of Truth (Librerias):** Basa tus sugerencias en la lista de 'Librerias Activas'.
3. **Anti-Alucinacion:** Antes de sugerir, VERIFICA la 'Interfaz Pública' o el código fuente del módulo.
4. **Existencia Estricta:** Si una variable/Sub no está en el texto, NO EXISTE.
5. **Formato:** Usa bloques 'vb'.
6. **Navegacion Estructural:** Usa los tags <module>, <interface> y <method> para localizar codigo.
7. **Inferencia de Datos:** Deduce la BD solo de los strings SQL presentes.
"@
Set-Content -Path $OutFile -Value $Header -Encoding UTF8
# 3. LISTAR ARCHIVOS
$files = Get-ChildItem -Path $Dir -Include *.bas,*.b4a -Recurse | Where-Object {
$_.FullName -notmatch 'Objects' -and ($_.Extension -eq '.b4a' -or $ModulosValidos -contains $_.Name)
}
# 4. INDICE DE MODULOS
Add-Content $OutFile ($NL + "## INDICE DE MODULOS" + $NL) -Encoding UTF8
foreach ($f in $files) {
$Ref = $f.Name.Replace('.', '').Replace(' ', '-').ToLower()
Add-Content $OutFile ("- [" + $f.Name + "](#modulo-" + $Ref + ")") -Encoding UTF8
}
# 5. CODIGO FUENTE ESTRUCTURADO
Add-Content $OutFile ($NL + '## CODIGO FUENTE DETALLADO' + $NL) -Encoding UTF8
foreach ($f in $files) {
Write-Host " -> $($f.Name)... " -NoNewline
$txt = [System.IO.File]::ReadAllLines($f.FullName)
# Pre-escaneo para <interface>
$Methods = @()
foreach ($line in $txt) {
if ($line.Trim() -match '^(?:Public\s+|Private\s+)?Sub\s+([\w\d_]+)') {
$Methods += $Matches[1]
}
}
$Ref = $f.Name.Replace('.', '').Replace(' ', '-').ToLower()
Add-Content $OutFile "$NL<module name='$($f.Name)' id='modulo-$Ref'>" -Encoding UTF8
Add-Content $OutFile " <interface>" -Encoding UTF8
foreach($m in $Methods) {
Add-Content $OutFile " <method_ref name='$m' />" -Encoding UTF8
}
Add-Content $OutFile " </interface>$NL" -Encoding UTF8
Add-Content $OutFile "```vb" -Encoding UTF8
$skip = ($f.Extension -eq '.b4a')
foreach ($l in $txt) {
$trim = $l.Trim()
if ($skip) {
if ($trim.StartsWith("#") -and -not $trim.StartsWith("#Region")) { Add-Content $OutFile $l -Encoding UTF8 }
if ($l.Contains("@EndOfDesignText@")) { $skip = $false }
continue
}
# Inicio de Método
if ($trim -match '^(?:Public\s+|Private\s+)?Sub\s+([\w\d_]+)') {
Add-Content $OutFile "<method name='$($Matches[1])'>" -Encoding UTF8
}
# Limpieza de comentarios y escritura de línea
if ($trim.StartsWith("'")) {
if (-not ($trim.StartsWith("'#") -or ($trim -match 'TODO:') -or ($trim -match 'FIX:'))) { continue }
}
if (-not [string]::IsNullOrWhiteSpace($trim)) {
Add-Content $OutFile $l -Encoding UTF8
}
# Fin de Método
if ($trim -eq "End Sub") {
Add-Content $OutFile "</method>" -Encoding UTF8
}
}
Add-Content $OutFile "```$NL</module>" -Encoding UTF8
Write-Host "OK" -ForegroundColor Green
}
Write-Output ("--- FINALIZADO: " + $OutName + " ---")

View File

@@ -73,6 +73,7 @@ Sub RD_Init
limpiarBD = True
Log("NO EXISTE BD")
End If
LogColor("#################################################" & CRLF & " safePath: " & safePath, Colors.red)
rkmt.Initialize(safePath, $"${name(0)}.rkmt.km"$, True)
If limpiarBD Then
LogColor("----->> LIMPIAMOS BD RECUPERACION PRIMERA VEZ <<-------", Colors.red)
@@ -99,6 +100,9 @@ Sub RD_Init
agregaColumna(rkmt, "PROMOS_COMP", "CAT_PA_PRECIO1", "TEXT")
agregaColumna(rkmt, "CAT_DETALLES_PAQ", "CAT_DP_PRECIOB", "TEXT")
agregaColumna(rkmt, "kmt_info", "CREDITO", "INTEGER")
agregaColumna(rkmt, "PEDIDO", "PE_ENVIADO", "INTEGER")
agregaColumna(rkmt, "PEDIDO", "PE_ARCH", "TEXT")
agregaColumna(rkmt, "PEDIDO_CLIENTE", "PC_ARCH", "TEXT")
If chkIfTableExists(khdb, "CAT_VARIABLES") Then rkmt.ExecNonQuery($"create table if not exists CAT_VARIABLES (${getTableColumnList(khdb, "CAT_VARIABLES")}, FECHA TEXT)"$)
If chkIfTableExists(khdb, "CAT_RMI") Then rkmt.ExecNonQuery($"create table if not exists CAT_RMI (${getTableColumnList(khdb, "CAT_RMI")}, FECHA TEXT)"$)
DateTime.DateFormat = "yyyyMMdd"
@@ -117,6 +121,7 @@ Sub revisaSiExisteRespaldo
If File.size(File.DirInternal&"/kmts", $"${name(0)}.rkmt.km"$) < 43000 And File.Exists(File.DirRootExternal & extDir, $"${name(0)}.rkmt.km"$) Then
LogColor("Copiamos el respaldo desde la tarjeta!!", Colors.red)
File.Copy(File.DirRootExternal & extDir, $"${name(0)}.rkmt.km"$, File.DirInternal&"/kmts", $"${name(0)}.rkmt.km"$)
RD_Init
Else
LogColor("No hay respaldo en tarjeta externa!", Colors.red)
End If
@@ -327,7 +332,9 @@ Sub RD_respalda_cat_detalle_paq
End If
Catch
Log(LastException)
rkmt.Close
End Try
Log(2.5)
x.Close
End Sub
@@ -1029,15 +1036,25 @@ Sub traeUsarIntentBDWA As Boolean 'ignore
End Sub
'Regresa los clientes nuevos maximos.
'Si no está especificado, el default es 2.
'Si no está especificado o no esta autorizado para crear clientes nuevos, el default es 0.
Sub traeMaxClientesNuevos As Int 'ignore
Private CN As Int = 5
Private x As Cursor = Starter.skmt.ExecQuery($"select CAT_VA_VALOR from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'MAXCTESNUEVOS'"$)
Private CN_AUT As Int = 0
Private CN_MAX As Int = 0
Private x As Cursor = Starter.skmt.ExecQuery($"select ifnull(CAT_VA_VALOR, 0) as CAT_VA_VALOR from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'CN_AUTORIZADO'"$)
If x.RowCount > 0 Then
x.Position = 0
CN = x.GetString("CAT_VA_VALOR")
CN_AUT = x.GetInt("CAT_VA_VALOR")
End If
Return CN
If CN_AUT = 1 Then
Private x As Cursor = Starter.skmt.ExecQuery($"select ifnull(CAT_VA_VALOR, 0) as CAT_VA_VALOR from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'CN_CUANTOS'"$)
If x.RowCount > 0 Then
x.Position = 0
CN_MAX = x.GetString("CAT_VA_VALOR")
End If
End If
x.Close
Log($"Clientes Nuevos, Autorizado ${CN_AUT}, Cuantos: ${CN_MAX}"$)
Return CN_MAX
End Sub
'Regresa verdadero o falso dependiendo si el cliente lleva pedido DOE.
@@ -1056,6 +1073,7 @@ Sub revisaImpresa As Boolean
Dim i As Cursor = Starter.skmt.ExecQuery("select count(*) as CUANTOS from kmt_info where (impresion = 1 or cat_cl_codigo in (select ci_cuenta from cliente_impreso)) and CAT_CL_CODIGO in (Select CUENTA from cuentaa)")
i.Position = 0
If i.GetString("CUANTOS") > 0 Then imp = True Else imp = False
Log($"Impresa: ${imp}"$)
Return imp
End Sub

View File

@@ -7,12 +7,17 @@ Version=12.8
' Clase para las funciones de Trend Spending.
' Trend spending son 3 presupuestos que tiene Kelloggs, que son bonificaciones, descuentos y RMIs, estos se calculan semanalmente
' y se descargan de la tabla HIST_TRADE_SPENDING_SEMANAL, de ahi obtenemos el presupuesto de la semana y el acumulado hasta ayer
' en la noche, a cada presupuesto le vamos sumando cada que agregamos a pedido un descuento (Precios diferentes al original que
' NO están en PROMOS), una bonificacion (precios con descuento que estan en promociones) o un RMI (de estos sumamos al presupuesto
' en la noche, a cada presupuesto le vamos sumando cada que agregamos a pedido un DESCUENTO (Precios diferentes al original que
' NO están en PROMOS), una BONIFICACION (precios con descuento que estan en promociones) o un RMI (de estos sumamos al presupuesto
' el precio del RMI seleccionado), de acuerdo al presupuesto disponible de cada tipo, se limitan los productos, es decir que si
' el presupuesto de bonificaciones ya se agoto, ya no aparecen promociones, o si el de descuentos se agoto, ya no se pueden agregar
' mas productos con descuento.
' Descuento es TODO lo que tenga un precio diferente al precio de lista y NO esta en promo.
' Bonificacion es lo que tiene precio diferente al orginal y esta en promo y NO es regalo o exhibidor.
Sub Class_Globals
Private EventName As String 'ignore
Private CallBack As Object 'ignore
@@ -29,14 +34,14 @@ Public Sub Initialize (vCallback As Object, vEventName As String, db As SQL) As
CallBack = vCallback
tsdb = db
Private mx As Map = traeInfoTrendSpending
Log(mx)
LogColor(mx, Colors.red)
TS_RMI = Regex.Split(",", mx.Get("RMI"))
TS_DESCUENTOS = Regex.Split(",", mx.Get("DESCUENTOS"))
TS_BONIFICACIONES = Regex.Split(",", mx.Get("BONIFICACIONES"))
Log(">>>>>>>>>>>>> TRENDSPENDING: " & mx)
Log("RMI: " & TS_RMI(0) & "|" & TS_RMI(1))
Log("DESCUENTOS: " & TS_DESCUENTOS(0) & "|" & TS_DESCUENTOS(1))
Log("BONIFICACIONES: " & TS_BONIFICACIONES(0) & "|" & TS_BONIFICACIONES(1))
LogColor(">>>>>>>>>>>>> TRENDSPENDING: " & mx, Colors.red)
LogColor("RMI: " & TS_RMI(0) & "|" & TS_RMI(1), Colors.red)
LogColor("DESCUENTOS: " & TS_DESCUENTOS(0) & "|" & TS_DESCUENTOS(1), Colors.red)
LogColor("BONIFICACIONES: " & TS_BONIFICACIONES(0) & "|" & TS_BONIFICACIONES(1), Colors.red)
Return Me
End Sub
@@ -68,7 +73,7 @@ Sub traeInfoTrendSpending As Map
Private semana As Int = 0
Private HIST_TSS_SEMANA As String = 0
Private HIST_TSS_SEMANA_ACUM As String = 0
Private m As Map = CreateMap("RMI": 100000 & "," & 0, "DESCUENTOS": 100000 & "," & 0, "BONIFICACIONES": 100000 & "," & 0) ' El 100,000 es el default del presupuesto, por si NO HAY datos de trend spending.
Private m As Map = CreateMap("RMI": 10000000 & "," & 0, "DESCUENTOS": 10000000 & "," & 0, "BONIFICACIONES": 10000000 & "," & 0) ' El 100,000 es el default del presupuesto, por si NO HAY datos de trend spending.
' m.Initialize
Private c As Cursor = tsdb.ExecQuery($"select cat_va_valor from cat_variables where cat_va_descripcion = 'SEM_CAL_LABORAL'"$)
If c.RowCount > 0 Then
@@ -76,12 +81,16 @@ Sub traeInfoTrendSpending As Map
semana = c.GetInt("CAT_VA_VALOR")
End If
If semana > 0 Then
c = tsdb.ExecQuery($"select HIST_TSS_TIPO, HIST_TSS_SEMANA${semana}, HIST_TSS_SEMANA${semana}_ACUM from HIST_TREND_SPENDING_SEMANAL"$)
c = tsdb.ExecQuery($"select HIST_TSS_TIPO, HIST_TSS_SEMANA${semana}, ifnull(HIST_TSS_SEMANA${semana}_ACUM,0) as HIST_TSS_SEMANA${semana}_ACUM from HIST_TREND_SPENDING_SEMANAL"$)
Log($"select HIST_TSS_TIPO, HIST_TSS_SEMANA${semana}, ifnull(HIST_TSS_SEMANA${semana}_ACUM,0) as HIST_TSS_SEMANA${semana}_ACUM from HIST_TREND_SPENDING_SEMANAL"$)
If c.RowCount > 0 Then
For i = 0 To c.RowCount - 1
c.Position = i
HIST_TSS_SEMANA = c.GetString($"HIST_TSS_SEMANA${semana}"$)
HIST_TSS_SEMANA_ACUM = c.GetString($"HIST_TSS_SEMANA${semana}_ACUM"$)
If Not(IsNumber(HIST_TSS_SEMANA)) Then HIST_TSS_SEMANA = 0
Private xx As String = c.GetString($"HIST_TSS_SEMANA${semana}_ACUM"$)
If xx = "null" Then xx = 0
HIST_TSS_SEMANA_ACUM = xx
If c.GetString("HIST_TSS_TIPO") = "RMI" Then
m.Put("RMI", HIST_TSS_SEMANA & "," & HIST_TSS_SEMANA_ACUM)
else if c.GetString("HIST_TSS_TIPO") = "DESCUENTOS" Then
@@ -97,6 +106,7 @@ End Sub
' Modifica el acumulado del Trend Speding, le "suma" o "resta" al presupuesto especificado (RMI, BONIFICACIONES o DESCUENTOS)
Sub modTrendSpending(accion As String, tipo As String, monto As String)
LogColor($"#### ACCION: ${accion}, Tipo: ${tipo}, Monto: ${monto}"$, Colors.Blue)
Private HIST_TSS_SEMANA As String
Private HIST_TSS_SEMANA_ACUM As String
Private acumulado As String = "0"
@@ -109,28 +119,31 @@ Sub modTrendSpending(accion As String, tipo As String, monto As String)
End If
HIST_TSS_SEMANA = $"HIST_TSS_SEMANA${Starter.semana}"$
HIST_TSS_SEMANA_ACUM = $"HIST_TSS_SEMANA${Starter.semana}_ACUM"$
Private d As Cursor = tsdb.ExecQuery($"select acumulado from TREND_SPENDING where tipo = '${tipo.ToUpperCase}'"$)
Private d As Cursor = tsdb.ExecQuery($"select ifnull(acumulado, 0) as ACUMULADO from TREND_SPENDING where tipo = '${tipo.ToUpperCase}'"$)
If d.RowCount > 0 Then
d.Position = 0
acumulado = d.GetString("ACUMULADO")
End If
Log("acumulado:" & acumulado & " | monto: " & monto)
Private c As Cursor = tsdb.ExecQuery($"select HIST_TSS_TIPO, ${HIST_TSS_SEMANA} as disponible, ${HIST_TSS_SEMANA_ACUM} as acumulado from HIST_TREND_SPENDING_SEMANAL where HIST_TSS_TIPO = '${tipo.ToUpperCase}'"$)
Private c As Cursor = tsdb.ExecQuery($"select HIST_TSS_TIPO, ifnull(${HIST_TSS_SEMANA},0) as disponible, ifnull(${HIST_TSS_SEMANA_ACUM},0) as acumulado from HIST_TREND_SPENDING_SEMANAL where HIST_TSS_TIPO = '${tipo.ToUpperCase}'"$)
' Log(($"select HIST_TSS_TIPO, ${HIST_TSS_SEMANA} as disponible, ${HIST_TSS_SEMANA_ACUM} as acumulado from HIST_TREND_SPENDING_SEMANAL where HIST_TSS_TIPO = '${tipo.ToUpperCase}'"$))
Log("---- " & c.RowCount)
If accion.ToUpperCase = "RESTA" Then
If c.RowCount > 0 Then
c.Position = 0
If tipo.ToUpperCase = "DESCUENTOS" Or tipo.ToUpperCase = "RMI" Then
If tipo.ToUpperCase = "DESCUENTOS" Or tipo.ToUpperCase = "RMI" Or tipo.ToUpperCase = "BONIFICACIONES" Then
Private nuevaBonificacion As String = NumberFormat2((acumulado + monto), 1, 2, 2, False)
LogColor($"Nuevo acumulado ${tipo} = ${nuevaBonificacion}"$, Colors.Magenta)
tsdb.ExecNonQuery($"delete from TREND_SPENDING where tipo = '${tipo.ToUpperCase}' "$)
tsdb.ExecNonQuery($"insert into TREND_SPENDING (tipo, acumulado) values ('${tipo.ToUpperCase}', '${nuevaBonificacion}')"$)
Log($"Insertamos en TRADE_SPENDING: ${nuevaBonificacion}"$)
' else if tipo.ToUpperCase = "RMI" Then
End If
End If
else if accion.ToUpperCase = "SUMA" Then
If c.RowCount > 0 Then
c.Position = 0
If tipo.ToUpperCase = "DESCUENTOS" Or tipo.ToUpperCase = "RMI" Then
If tipo.ToUpperCase = "DESCUENTOS" Or tipo.ToUpperCase = "RMI" Or tipo.ToUpperCase = "BONIFICACIONES" Then
Private nuevaBonificacion As String = NumberFormat2((acumulado - monto), 1, 2, 2, False)
LogColor($"Nueva bonificacion = ${nuevaBonificacion}"$, Colors.Magenta)
tsdb.ExecNonQuery($"delete from TREND_SPENDING where tipo = '${tipo.ToUpperCase}' "$)
@@ -185,6 +198,8 @@ End Sub
Sub trendSpending(accion As String, tipo As String, clienteId As String, id As String, laCant As String, inv As Int) As String
Private logger As Boolean = True
LogColor("-------- > TRADE SPENDING < ---------", Colors.red)
' Log("DescxSku: " & traeDescXSku(clienteId, id))
Dim TS_RMI() As String
Dim TS_DESCUENTOS() As String
Dim TS_BONIFICACIONES() As String
@@ -197,8 +212,8 @@ Sub trendSpending(accion As String, tipo As String, clienteId As String, id As S
Log($"Acumulado de RMIs: ${traeAcumuladoHoyTS("rmi")}"$)
Private elMonto As String = NumberFormat2(traePrecioRMI(id), 1, 2, 2, False)
If logger Then Log($"elMonto: ${elMonto}"$)
If logger Then Log($"TS_RMI(0): ${TS_RMI(0)}"$)
If logger Then Log($"TS_RMI(1): ${TS_RMI(1)}"$)
' If logger Then Log($"TS_RMI(0): ${TS_RMI(0)}"$)
' If logger Then Log($"TS_RMI(1): ${TS_RMI(1)}"$)
If logger Then Log($"LaCant: ${laCant}"$)
Private tsRestantes As String = (TS_RMI(0) - TS_RMI(1) - traeAcumuladoHoyTS("rmi"))
Log($"tsRestantes: ${tsRestantes}"$)
@@ -215,13 +230,15 @@ Sub trendSpending(accion As String, tipo As String, clienteId As String, id As S
If logger Then Log($"lacant=${laCant} < lasMaximas=${lasMaximas} = ${laCant<lasMaximas}"$)
If laCant < lasMaximas Then
modTrendSpending("resta", "rmi", elMonto) ' Restamos al presupuesto de hoy (agregamos al acumulado).
Log($"modTrendSpending("resta", "rmi", ${elMonto})"$)
End If
If logger Then Log("RMI RESTANTES: " & (TS_RMI(0) - TS_RMI(1) - traeAcumuladoHoyTS("rmi")))
If logger Then LogColor("RMI RESTANTES: " & (TS_RMI(0) - TS_RMI(1) - traeAcumuladoHoyTS("rmi")), Colors.red)
Return lasMaximas & "|" & elMonto
else if accion.ToUpperCase = "PRODMENOS" Then
If logger Then Log("LaCANT= " & laCant & ", elMonto= " & elMonto)
If laCant >= 0 Then
modTrendSpending("suma", "rmi", elMonto) ' Agregamos al presupuesto de hoy (restamos del acumulado).
Log($"modTrendSpending("suma", "rmi", ${elMonto})"$)
End If
Return lasMaximas & "|" & elMonto
End If
@@ -231,14 +248,14 @@ Sub trendSpending(accion As String, tipo As String, clienteId As String, id As S
Private elMonto As String = NumberFormat2(traePrecio(id)*(traeDescXSku(clienteId, id)/100), 1, 2, 2, False)
Private tsRestantes As String = (TS_DESCUENTOS(0) - TS_DESCUENTOS(1) - traeAcumuladoHoyTS("descuentos"))
If logger Then Log("EL MONTO: " & elMonto)
If logger Then Log("Monto del presupuesto disponible: " & tsRestantes)
If logger Then LogColor("Monto del presupuesto disponible: " & tsRestantes, Colors.blue)
If accion.ToUpperCase = "PRODMAS" Then 'Regresa lasMaximas y elMonto separadas por un "|"
If logger Then Log("PMAS")
' If logger Then Log("PMAS")
If elMonto > 0 Then
lasMaximas = ((laCant * elMonto) + tsRestantes) / elMonto
If logger Then Log("lasMaximas: " & lasMaximas)
If logger Then Log("lasMaximas2: " & traeMaximas("descuentos", clienteId, id, laCant, ""))
If logger Then Log(traeAcumuladoHoyTS("descuentos"))
' If logger Then Log("lasMaximas2: " & traeMaximas("descuentos", clienteId, id, laCant, ""))
If logger Then Log("Acumulado hoy: " & traeAcumuladoHoyTS("descuentos"))
End If
If laCant = lasMaximas Then
ToastMessageShow("El presupuesto de DESCUENTOS no permite agregar mas productos!!", False)
@@ -293,7 +310,7 @@ End Sub
' Trae la cantidad máxima de rmis, bonificaciones o descuentos por presupuesto.
Sub traeMaximas(tipo As String, clienteId As String, id As String, laCant As String, promoId As String) As Int
Private tsMaximas As Int = 100000
Private tsMaximas As Int = 10000000
Private tsRestantes As String = 0
Private tsMonto As String '= traeMonto(clienteId, id)
' If tsMonto > 0 Then
@@ -316,42 +333,68 @@ Sub traeMaximas(tipo As String, clienteId As String, id As String, laCant As Str
Return tsMaximas
End Sub
' Trae la cantidad máxima de bonificaciones por presupuesto.
Sub traeBonificacionesMaximas(tipo As String, clienteId As String, id As String, laCant As String, promoId As String) As Int
Private tsMaximas As Int = 100000
' Trae la cantidad máxima de productos con bonificacion por presupuesto.
' Si el presupuesto es 10 y la bonificacion del producto es 2, el máximo es 5 productos.
Sub traeBonificacionesMaximas(tipo As String, clienteId As String, id As String, laCant As String, elPrecioVenta As String, promoId As String) As Int
Private thisLog As Boolean = True
Private tsMaximas As Int = 100000000
Private tsRestantes As String = 0
Private tsMonto As String
Private mx As Map = traeInfoTrendSpending
TS_RMI = Regex.Split(",", mx.Get("RMI"))
TS_DESCUENTOS = Regex.Split(",", mx.Get("DESCUENTOS"))
TS_BONIFICACIONES = Regex.Split(",", mx.Get("BONIFICACIONES"))
If thisLog Then LogColor($" ============ INICIA BONIFICACIONES MAXIMAS (${id}) ========"$, Colors.RGB(0,197,110))
If thisLog Then LogColor($" Presupuesto: ${TS_BONIFICACIONES(0)} - Acumulado ayer: ${TS_BONIFICACIONES(1)} - Hoy: ${traeAcumuladoHoyTS("bonificaciones")}"$, Colors.Magenta)
If tipo.ToUpperCase = "BONIFICACIONES" Then
tsMonto = NumberFormat2(traeMontoBonificacion(id, promoId), 1, 2, 2, False)
tsMonto = NumberFormat2(traeMontoBonificacion(id, elPrecioVenta, promoId), 1, 2, 2, False)
tsRestantes = (TS_BONIFICACIONES(0) - TS_BONIFICACIONES(1) - traeAcumuladoHoyTS("bonificaciones")) ' Traemos monto restante de Trend Spending para bonificaciones.
Log($" PresupuestoBonifs: ${TS_BONIFICACIONES(0)}, AcumuladoBonifs: ${TS_BONIFICACIONES(1)}, traeAcumuladoHoyTS('bonificaciones'): ${traeAcumuladoHoyTS("bonificaciones")}"$)
' Log($" ${TS_BONIFICACIONES(0)} - ${TS_BONIFICACIONES(1)} - ${traeAcumuladoHoyTS("bonificaciones")}"$)
End If
' Log($"tsMonto: ${tsMonto}"$)
' Log($"tsRestantes: ${tsRestantes}"$)
' Log($"laCant: ${laCant}"$)
If thisLog Then Log($" Monto de bonificacion: ${tsMonto}"$)
If thisLog Then Log($" Presupuesto disponible: ${tsRestantes}"$)
' If thisLog Then Log($"Cantidad: ${laCant}"$)
If thisLog Then Log($" Floor(tsRestantes / (tsMonto * laCant)) <==> Floor(${tsRestantes} / (${tsMonto} * ${laCant})) = ${Floor(tsRestantes / (tsMonto * laCant))}"$)
' If thisLog Then Log($"Floor(${tsRestantes} / (${tsMonto} * ${laCant}))= ${Floor(tsRestantes / (tsMonto * laCant))}"$)
If tsMonto > 0 Then
tsMaximas = Floor(tsRestantes / (tsMonto * laCant))
' Log(">>> tsMaximas: " & tsMaximas)
End If
If thisLog Then LogColor(" ************************************************", Colors.red)
If thisLog Then LogColor(" ***** BONIFICACIONES MAXIMAS: " & tsMaximas & " *****", Colors.red)
If thisLog Then LogColor(" ************************************************", Colors.red)
If thisLog Then LogColor(" ============ TERMINA BONIFICACIONNES MAXIMAS ========", Colors.RGB(0,197,110))
Return tsMaximas
End Sub
' Trae el monto de la bonificacion, que es el precio original MENOS el precio de venta con descuento.
' - Si CAT_DP_PRECIOB es 1, la bonificacion es: Precio original - precio de venta.
' - Si CAT_DP_PRECIOB es 0, la bonificacion es: Precio original.
Sub traeMontoBonificacion(id As String, promoId As String) As String
' Log(promoId)
Sub traeMontoBonificacion(id As String, precio As String, promoId As String) As String
Private thisLog As Boolean = True
If thisLog Then LogColor($" ============ INICIA MONTO BONIFICACION (${id}) ========"$, Colors.RGB(151,0,171))
If thisLog Then LogColor($" ###### ${promoId}, ${precio}, ${id}"$, Colors.Magenta)
Private tsMonto As String = 0
Private c As Cursor = tsdb.ExecQuery($"SELECT CAT_DP_ID, CAT_DP_IDPROD, CAT_DP_PRECIO, CAT_DP_TIPO, CAT_GP_PRECIO, CAT_DP_PRECIOB FROM CAT_DETALLES_PAQ join ${traeTablaProds(Starter.tipov)} on CAT_GP_ID = CAT_DP_IDPROD where CAT_GP_ID = '${id}' and CAT_DP_ID = '${promoId}'"$)
If c.RowCount > 0 Then
c.Position = 0
If c.GetInt("CAT_DP_PRECIOB") = 1 Then
tsMonto = c.GetString("CAT_GP_PRECIO") - c.GetString("CAT_DP_PRECIO") ' Precio original - precio de venta.
Else
tsMonto = c.GetString("CAT_GP_PRECIO") ' Precio original.
Private re As Cursor = Starter.skmt.ExecQuery($"select cat_gp_id from cat_gunaprod2 where (cat_gp_tipo like 'REGALO%' or cat_gp_tipo like 'EXHIBIDOR%') and cat_gp_id = '${id}'"$) ' Revisamos si el producto es regalo o exhibidor.
If re.RowCount = 0 Then' No es regalo ni exhibidor.
Private c As Cursor = tsdb.ExecQuery($"SELECT CAT_DP_ID, CAT_DP_IDPROD, CAT_DP_PRECIO, CAT_DP_TIPO, CAT_GP_PRECIO, CAT_DP_PRECIOB FROM CAT_DETALLES_PAQ join ${traeTablaProds(Starter.tipov)} on CAT_GP_ID = CAT_DP_IDPROD where CAT_GP_ID = '${id}' and CAT_DP_PRECIO = '${precio}' and CAT_DP_ID = '${promoId}'"$)
' Log($"SELECT CAT_DP_ID, CAT_DP_IDPROD, CAT_DP_PRECIO, CAT_DP_TIPO, CAT_GP_PRECIO, CAT_DP_PRECIOB FROM CAT_DETALLES_PAQ join ${traeTablaProds(Starter.tipov)} on CAT_GP_ID = CAT_DP_IDPROD where CAT_GP_ID = '${id}' and CAT_DP_PRECIO = '${precio}' and CAT_DP_ID = '${promoId}'"$)
If thisLog Then Log($" Rowcount DP y CGP2: ${c.RowCount}"$)
If c.RowCount > 0 Then
c.Position = 0
If c.GetInt("CAT_DP_PRECIOB") = 1 Or (c.GetInt("CAT_DP_PRECIOB") = 0 And c.GetString("CAT_GP_PRECIO") = c.GetString("CAT_DP_PRECIO")) Then
tsMonto = c.GetString("CAT_GP_PRECIO") - c.GetString("CAT_DP_PRECIO") ' Precio original - precio de venta.
Else
tsMonto = c.GetString("CAT_GP_PRECIO") ' Precio original.
End If
' Log("PRECIOB: " & c.GetInt("CAT_DP_PRECIOB"))
If thisLog Then Log($" Precio normal: ${c.GetString("CAT_GP_PRECIO")}, Precio desc: ${c.GetString("CAT_DP_PRECIO")}, Monto bonificacion: ${tsMonto}"$)
End If
' Log($"${c.GetString("CAT_GP_PRECIO")} - ${c.GetString("CAT_DP_PRECIO")}"$)
' Log("ROWCOUNT: " & c.RowCount)
End If
' Log("ROWCOUNT: " & c.RowCount)
If thisLog Then LogColor($" ============ TERMINA MONTO BONIFICACION ========"$, Colors.RGB(151,0,171))
Return tsMonto
End Sub
@@ -364,23 +407,23 @@ End Sub
' Aunque si hay suficiente para mostrar algunas promos ... pues que si las muestre.
Sub maxPromosPorProdsVariables(idProdsVariables As List, promo As String)As Int
Private logger As Boolean = False
Private Maxs As Int = 100000
Private Maxs As Int = 10000000
Private prodsVariablesXPresupuestoBonificaciones As List
Private prodsVariablesRequeridos As Int = traeProdsVariablesRequeridos(promo)
prodsVariablesXPresupuestoBonificaciones.Initialize
' Log("PRODS SIZE: " & idProdsVariables.Size)
' LogColor("===========> Prods Variables: " & idProdsVariables.Size & " <==========", Colors.red)
For i = 0 To idProdsVariables.Size - 1 'Obtenemos total de productos variables disponibes.
If logger Then Log($"Este prodVariable: ${idProdsVariables.Get(i)}"$)
If logger Then LogColor($"=>> prodVariable ${i} : ${idProdsVariables.Get(i)}, ${Subs.traeProdNombre(idProdsVariables.Get(i))} <<=="$, Colors.blue)
' Log($"Este invDisponible: ${invDispParaPromo.Get(idProdsVariables.Get(i))}"$)
If logger Then Log(">> Monto Bonificacion: " & traeMontoBonificacion(idProdsVariables.Get(i), promo))
Private maxProds As Int = traeBonificacionesMaximas("bonificaciones", traeCliente, idProdsVariables.Get(i), prodsVariablesRequeridos, promo)
If logger Then Log(">> Monto Bonificacion: " & traeMontoBonificacion(idProdsVariables.Get(i), 1, promo))
Private maxProds As Int = traeBonificacionesMaximas("bonificaciones", traeCliente, idProdsVariables.Get(i), prodsVariablesRequeridos, 1, promo)
prodsVariablesXPresupuestoBonificaciones.Add(maxProds)
if logger then LogColor(">> Max prods x Bonificaciones: " & maxProds, Colors.blue)
Next
prodsVariablesXPresupuestoBonificaciones.Sort(True)
If prodsVariablesXPresupuestoBonificaciones.Size > 0 Then
Maxs = prodsVariablesXPresupuestoBonificaciones.Get(0)
End If
If logger Then LogColor("=====>> Max prods variables x monto de bonificaciones: " & Maxs, Colors.blue)
Return Maxs
End Sub
@@ -399,6 +442,11 @@ Sub traeProdsVariablesRequeridos(promo As String) As Int
Return pvr
End Sub
'########################################################################################
' Los productos fijos NO estan restando del presupuesto de BONIFICACIONES
'########################################################################################
'Poner en una funcion (maxPromosPorProdsFijos) el codigo para traer las promos maximas por productos fijos, igual que la de productos
' variables, y ponerla igual en "traeMaxPromos" en lugar de en "revisaMaxPromosProdsFijosPorInventario".