35 Commits

Author SHA1 Message Date
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
40 changed files with 2883 additions and 3116 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
@@ -121,6 +127,7 @@ Sub Class_Globals
Private Label4 As Label
Private clicked As Int = 0
Dim linker As C_deviceLinker
Dim aud As C_Auditoria
End Sub
Public Sub Initialize
@@ -165,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")
@@ -179,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")
@@ -258,7 +279,7 @@ Log(111)
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)
@@ -396,6 +417,7 @@ End Sub
Sub B4XPage_Appear
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")
@@ -508,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")
@@ -525,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
@@ -555,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"))
@@ -592,6 +616,11 @@ 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
@@ -856,6 +885,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"
@@ -938,12 +974,7 @@ 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)
@@ -954,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
@@ -1044,10 +1077,19 @@ Private Sub ImageView1_LongClick
' cmdX.Name = "update_usuario_guna_nobajas"
' cmdX.Parameters = Array As Object("CDAZA")
' reqManagerX.Executequery(cmdX, 0, "traeConexion")
If Subs.traeAlmacen <> "" Then
linker.VerifyAndLinkDevice(Subs.traeAlmacen, Subs.traeRuta)
End If
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
@@ -1080,8 +1122,8 @@ Sub Linker_Response(Status As String) ' << AÑADE ESTE SUB [New Query]
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 ligado y verificado exitosamente.")
ToastMessageShow("Dispositivo verificado y ligado correctamente.", False)
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.")

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,6 +409,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 Cliente"$)
indicePregunta = 0
b_noVenta.Enabled = False
Log("NoVenta False")
@@ -411,7 +418,7 @@ Sub B4XPage_Appear
clienteId = kh.traeCliente
P_DOE.Visible = False
dentroDeGeocerca = False
' Log($"TOTAL VENTA: ${kh.traeTotalCliente}"$)
B_VENTA.Visible = False
b_noVenta.Visible = False
@@ -421,11 +428,12 @@ Sub B4XPage_Appear
' 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
' 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
@@ -494,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)
@@ -509,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
@@ -772,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")
@@ -781,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")))
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (B4XPages.MainPage.promos.ts.traeMontoBonificacion(dp.GetString("CAT_DP_IDPROD"), dp.GetString("CAT_DP_PRECIO"), mPromoXMonto.Get("id")) * 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.
@@ -809,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)
@@ -888,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)
@@ -901,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
@@ -915,7 +962,7 @@ Sub GPS_LocationChanged (Location1 As Location)
If Not(p_rechazoDOE.Visible) Then pedido_doe_muestra
Else
b_noVenta.Visible = False
Log("NoVenta False")
' Log("NoVenta False")
B_VENTA.Visible = False
b_whats.Visible = False
End If
@@ -974,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)
@@ -994,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
@@ -1006,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
@@ -1036,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
@@ -1048,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
@@ -1096,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
@@ -1125,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
@@ -1153,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
@@ -1175,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
@@ -1299,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
@@ -3225,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.
@@ -3520,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)
@@ -3529,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")
@@ -3728,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
@@ -3770,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)
@@ -3927,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"))
@@ -4401,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(0)
Private ID As String = tag1(1)
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

@@ -99,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
@@ -265,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
@@ -445,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")

View File

@@ -51,6 +51,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 NuevoCliente")
b_guardar.Visible = False
b_guardar.Enabled = False
permitirCtesNuevos = True

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
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)
If c.GetInt("hayPromos") > 0 And Subs.traeCliente <> 0 And Subs.revisaImpresa = False Then
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(">>>>>>>>>>>>> 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))
End Sub
Sub PCLV_AddProds
@@ -342,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"
@@ -492,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
@@ -604,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
@@ -620,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 <<<<<<<<<<<<<<")
@@ -629,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)
@@ -658,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}"$)
@@ -714,11 +762,12 @@ 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.
@@ -792,7 +841,7 @@ Sub b_prodMas_Click
' Log(77)
laCant.Text = "0"
End If
Log(99)
If lfila.Text = "RMI" Then
almacenX = "DUR"
@@ -841,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)
@@ -1113,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
@@ -1141,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
@@ -1150,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 ${Subs.traeTablaProds(starter.tipov)} 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
@@ -1237,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
@@ -1334,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)
@@ -1406,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
@@ -1434,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
@@ -1546,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

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,8 +157,8 @@ 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)
LogColor($"****************************************************************"$, Colors.red)
LogColor($"************ muestraPromo: ${promo} *************"$, Colors.red)
@@ -93,6 +168,7 @@ Sub muestraPromo(promo As String, cliente As String)
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)
@@ -479,29 +555,35 @@ Private Sub b_terminar1_Click
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, estaPromo)
Private bonificacion_monto As String = ts.traeMontoBonificacion(idProdFijo, prodsPrecio, estaPromo)
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), estaPromo))
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (ts.traeMontoBonificacion(prodsIds2.Get(t), estaPromo) * prodsCants2.Get(t))
Log("Monto Bonificacion -->> " & ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo))
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo) * 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")
@@ -515,29 +597,35 @@ Private Sub b_continuar_Click
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, estaPromo)
Private bonificacion_monto As String = ts.traeMontoBonificacion(idProdFijo, prodsPrecio, estaPromo)
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
Subs.guardaProductoSinGestion(estaPromo, prodsPrecios.Get(t), prodsCants.Get(t), pn, prodsIds.Get(t), Subs.traeCliente, Subs.traeFecha, Subs.traeUsuarioDeBD, Subs.traeRuta, 0, Starter.tipov)
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), estaPromo))
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (ts.traeMontoBonificacion(prodsIds2.Get(t), estaPromo) * prodsCants2.Get(t))
Log("Monto Bonificacion -->> " & ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo))
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo) * 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

454
B4A/C_TrendSpending.bas Normal file
View File

@@ -0,0 +1,454 @@
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), 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: Precio original.
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 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("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 = False
Private Maxs As Int = 10000000
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 maxProds As Int = traeBonificacionesMaximas("bonificaciones", traeCliente, idProdsVariables.Get(i), prodsVariablesRequeridos, 1, 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!!

View File

@@ -9,6 +9,41 @@ Version=12.8
' 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
@@ -28,6 +63,7 @@ Sub Class_Globals
' - KeyValueStore2
' - DBRequestManager
' - XUI
Dim dlDB As SQL
End Sub
' Inicializa la clase DeviceLinker.
@@ -42,12 +78,16 @@ Public Sub Initialize (PageObject As Object, NameOfEvent As String, AppLogger As
' 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, "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.")
@@ -56,43 +96,87 @@ 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 VerifyAndLinkDevice(Almacen_ As String, Ruta_ As String)
Dim DeviceId_ As String = GetDeviceGUID ' Obtenemos o generamos el GUID del dispositivo.
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")
End If
Return
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_}"$)
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 = "verify_device"
cmd.Name = "registarMovil"
' Pasamos el almacén, la ruta y el GUID del dispositivo como parámetros.
cmd.Parameters = Array As Object(Almacen_, Ruta_) ', DeviceId_
' Ejecutamos el comando en el servidor. 'Me' indica que DBRequestManager_JobDone en esta clase manejará la respuesta.
reqManager.ExecuteQuery(cmd, 0, "verify_device")
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
' 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
kvs.Put(GUID_KEY_ALIAS, NewGUID) ' Lo guardamos de forma segura en el KeyStore.
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 = kvs.Get(GUID_KEY_ALIAS) ' Recuperamos el GUID existente.
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
@@ -115,7 +199,7 @@ Public Sub JobDone(Job As HttpJob) ' El nombre del sub debe ser 'JobDone' o el q
LogColor("############################################", Colors.red)
' Enviar una respuesta de error HTTP al callback.
If SubExists(CallBack, EventName & "_Response") Then
CallSub2(CallBack, EventName & "_Response", "HTTP_ERROR")
CallSub2(CallBack, EventName & "_Response", "HTTP_ERROR") ' Dispara el evento Linker_Response("HTTP_ERROR")
End If
Else 'If Job Success then ...
lastJobDoneError = ""
@@ -144,48 +228,54 @@ Public Sub JobDone(Job As HttpJob) ' El nombre del sub debe ser 'JobDone' o el q
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
Log(">>> NUEVO")
' Status = "REGISTRO_NUEVO"
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")
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", "REGISTRO_NUEVO")
CallSub2(CallBack, EventName & "_Response", "SIN_REGISTRO")
End If
else if CAT_RU_IDTELEFONO = deviceId Then
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.
If SubExists(CallBack, EventName & "_Response") Then
CallSub2(CallBack, EventName & "_Response", Status)
End If
Next
' Else
' If logger Then LogColor($"El servidor respondió con éxito, pero no encontró registros.${CRLF}Quiere decir que la ruta NO esta registrada en el servidor."$, Colors.Red)
' 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(almacen, ruta, deviceId)
' reqManager.ExecuteCommand(cmd, "registramosGUID")
' If SubExists(CallBack, EventName & "_Response") Then
' CallSub2(CallBack, EventName & "_Response", "NO_REGISTRADO")
' End If
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_NUEVO")
CallSub2(CallBack, EventName & "_Response", "REGISTRO_COMPLETO") ' Dispara el evento Linker_Response("REGISTRO_COMPLETO")
End If
End If
End If
@@ -207,4 +297,14 @@ Sub generaGUID As String
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

View File

@@ -99,6 +99,8 @@ End Sub
'This sub will be called by the DBRequestManager when the job is done
Public Sub JobDone(job As HttpJob)
Log("===== JDDBRW =====")
LogColor("JobDone: '" & reqManager.HandleJob(job).tag & "' - Registros: " & reqManager.HandleJob(job).Rows.Size, Colors.Green) 'Mod por CHV - 211110
'<<< Obtenemos el Tag único que asignamos al job
Dim currentJobTag As String = job.Tag

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -26,6 +26,7 @@ ModuleBookmarks30=
ModuleBookmarks31=
ModuleBookmarks32=
ModuleBookmarks33=
ModuleBookmarks34=
ModuleBookmarks4=
ModuleBookmarks5=
ModuleBookmarks6=
@@ -60,6 +61,7 @@ ModuleBreakpoints30=
ModuleBreakpoints31=
ModuleBreakpoints32=
ModuleBreakpoints33=
ModuleBreakpoints34=
ModuleBreakpoints4=
ModuleBreakpoints5=
ModuleBreakpoints6=
@@ -67,17 +69,17 @@ ModuleBreakpoints7=
ModuleBreakpoints8=
ModuleBreakpoints9=
ModuleClosedNodes0=
ModuleClosedNodes1=6,46,47
ModuleClosedNodes1=
ModuleClosedNodes10=
ModuleClosedNodes11=
ModuleClosedNodes12=3,5
ModuleClosedNodes13=7,8,9,10,11,12
ModuleClosedNodes14=6,7,8,9,12,13
ModuleClosedNodes12=
ModuleClosedNodes13=42
ModuleClosedNodes14=
ModuleClosedNodes15=
ModuleClosedNodes16=3,8,17
ModuleClosedNodes16=1,2,7,8,9
ModuleClosedNodes17=
ModuleClosedNodes18=
ModuleClosedNodes19=7,8,9,10,11,12,13,14
ModuleClosedNodes19=
ModuleClosedNodes2=
ModuleClosedNodes20=
ModuleClosedNodes21=
@@ -85,21 +87,22 @@ ModuleClosedNodes22=
ModuleClosedNodes23=
ModuleClosedNodes24=
ModuleClosedNodes25=
ModuleClosedNodes26=24,26,27,31,32,33,35
ModuleClosedNodes26=
ModuleClosedNodes27=
ModuleClosedNodes28=4
ModuleClosedNodes28=
ModuleClosedNodes29=
ModuleClosedNodes3=1,3,5,6
ModuleClosedNodes30=
ModuleClosedNodes3=
ModuleClosedNodes30=3
ModuleClosedNodes31=
ModuleClosedNodes32=116
ModuleClosedNodes32=
ModuleClosedNodes33=
ModuleClosedNodes4=
ModuleClosedNodes34=
ModuleClosedNodes4=1,128
ModuleClosedNodes5=
ModuleClosedNodes6=
ModuleClosedNodes7=
ModuleClosedNodes8=
ModuleClosedNodes9=
NavigationStack=C_Principal,JobDone,1779,0,B4XMainPage,B4XPage_Appear,392,0,B4XMainPage,Label4_Click,1062,0,B4XMainPage,Linker_Response,1063,3,C_Principal,l_efectiva_Click,3892,0,C_Principal,Class_Globals,214,0,C_Principal,B4XPage_Created,312,0,C_Principal,B4XPage_Appear,321,0,C_Principal,Linker_Response,3917,6,C_deviceLinker,JobDone,132,6,C_deviceLinker,Initialize,44,0
NavigationStack=C_Cliente,JobDone,4283,0,C_Principal,enviaPedidoBatch0,3517,0,C_Principal,SUBIR_INFO_PEDIDO,3519,0,C_Principal,enviaPedidoBatch,3619,0,C_Cliente,Guardar_Click,1084,0,C_Cliente,mandaPendientes,1099,0,C_TrendSpending,traeInfoTrendSpending,75,0,C_Principal,JobDone,2243,0,Diseñador Visual,principal.bal,-100,1,C_Principal,cargar_Click,1030,0,C_Principal,B4XPage_Appear,555,0
SelectedBuild=0
VisibleModules=31,1,12,5,16,26,3,32,13,14,8,33,10,28,19
VisibleModules=32,1,13,4,33,16,34,14,15,18

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,7 +56,7 @@ 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
End Sub
@@ -72,6 +72,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"
@@ -189,17 +190,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)
@@ -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
@@ -1083,6 +1094,7 @@ Sub traePromo(promo As String, cliente As String) As Map
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
@@ -1096,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
@@ -1113,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
@@ -1134,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.
@@ -1164,7 +1183,7 @@ 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(promoMap As Map, inventarioSinFijos As Map) As Boolean 'ignore
Private thisLog As Boolean = True 'Si es verdadero, muestra los logs de este sub.
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 prodsmap As Map = promoMap.Get("productos") 'Obtenemos un mapa con todos los productos de la promoción.
@@ -1211,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
@@ -1231,16 +1251,17 @@ 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
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($"****************************************************************"$, Colors.red)
If thisLog Then LogColor($"********* Iniciamos revision de Promo ${idPromo} *********"$, Colors.red)
If thisLog Then LogColor($"****************************************************************"$, Colors.red)
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)
@@ -1250,7 +1271,9 @@ Sub procesaPromocion(idPromo As String, cliente As String) As Map 'ignore
' Log("|"&revisaMaxPromosProdsFijosPorInventario(pm)&"|")
Private maxPromosXprodsFijos As Int = revisaMaxPromosProdsFijosPorInventario(pm)
If maxPromosXprodsFijos < 1 Then pm.Put("resultado", 0)
LogColor($">>> Promos disponibles por productos fijos = ${maxPromosXprodsFijos}"$, Colors.Magenta)
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)
@@ -1266,7 +1289,9 @@ Sub procesaPromocion(idPromo As String, cliente As String) As Map 'ignore
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 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)
@@ -1283,6 +1308,8 @@ Sub procesaPromocion(idPromo As String, cliente As String) As Map 'ignore
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
@@ -1331,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}, pzasReq=${prodsFijosPiezas.Get(p)}"$)
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.
t.Add(x(0).As(Int)) 'Solo guardamos la parte del entero de la division.
If thisLog Then Log(">> Promos x Prods Fijos: " & x(0))
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")))
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")))
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 x inv de prodsFijos = " & 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
@@ -1381,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")
@@ -1412,7 +1452,7 @@ Sub revisaMaxPromosProdsVariablesPorInventario(pm As Map) As Int 'ignore
' Log(pm.Get("prodsFijos").As(List).Size)
' Log(maxPromosXFijos)
For x = 1 To maxPromosXFijos
If thisLog Then Log("==================== maxPromosXFijos "& x &" ========================")
If thisLog Then Log("=====================================================")
@@ -1430,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)
@@ -1477,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
@@ -1539,7 +1580,7 @@ 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
@@ -1553,7 +1594,8 @@ Sub borraPedidoClienteActual As String
Log("precioConDesc: " & precioConDesc)
Log(">>>>>>>>>>>>> " & (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_CEDIS"))
Private desc As String = B4XPages.MainPage.promos.ts.traeMontoBonificacion(thisC.GetString("PE_PROID"), thisC.GetString("PE_COSTOU"), thisC.GetString("PE_CEDIS"))
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.
@@ -1668,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
@@ -1709,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)")
@@ -2023,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
@@ -2081,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
@@ -2093,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
@@ -2160,7 +2214,7 @@ Sub modTrendSpending(accion As String, tipo As String, monto As String)
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}'"$)
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
@@ -2358,4 +2412,140 @@ Sub revisaContrasenaHoy
' 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

@@ -1,166 +0,0 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=12.8
@EndOfDesignText@
'Class module: jRDC1Wrapper
'Version 1.3 - Thread-Safe with ExecuteCommand support
Public Sub Class_Globals
' Public properties to be accessed after the wait for completes
Type TResultado(Tag As String, Success As Boolean, resultado As DBResult, ErrorMessage As String)
' Type TCommandResult(Tag As String, Success As Boolean, RowsAffected As Int, ErrorMessage As String)
'C <<< Definimos un tipo para almacenar la información de cada job
Type TJobInfo (Target As Object, EventName As String, IsQuery As Boolean)
'C <<< Un mapa para mantener un registro de los jobs activos
Private activeJobs As Map
'C <<< Un contador para generar tags únicos para cada job
Private jobCounter As Int
Public reqManager As DBRequestManager
Public cmd As DBCommand
Public resultado As TResultado
' Public commandResult As TCommandResult
Private logger As Boolean = False
End Sub
'Initializes the object.
Public Sub Initialize
'C <<< Inicializamos el mapa y el contador
activeJobs.Initialize
jobCounter = 0
End Sub
'Executes the query using the old jRDC1 mechanism.
'Parameters:
' - rdcLink: The link for the reqManager initialization.
' - Command: The DBCommand to execute.
' - Target: The module (like 'Me') where the completed event should be raised.
' - Event: The name of the event to raise when the query completes (e.g., "WrapperEvent").
Public Sub ExecuteQuery(rdcLink As String, Command As DBCommand, Target As Object, Event As String)
'<<< Incrementamos el contador para obtener un ID único
jobCounter = jobCounter + 1
Dim currentJobTag As String = "jRDCWrapJob_" & jobCounter
If logger Then Log($"ExecuteQuery (Tag: ${currentJobTag}): Command=${Command.Name}, Event=${Event}"$)
'<<< Creamos una instancia de TJobInfo para guardar el target y el evento
Dim jobInfo As TJobInfo
jobInfo.Initialize
jobInfo.Target = Target
jobInfo.EventName = Event
jobInfo.IsQuery = True ' Mark as query job
'<<< Guardamos la información del job en el mapa, usando el tag único como llave
activeJobs.Put(currentJobTag, jobInfo)
reqManager.Initialize(Me, rdcLink)
cmd = Command
'<<< Ejecutamos la consulta pasando nuestro TAG ÚNICO
reqManager.ExecuteQuery(cmd, 0, currentJobTag)
End Sub
'Executes a command (INSERT, UPDATE, DELETE) using the old jRDC1 mechanism.
'Parameters:
' - rdcLink: The link for the reqManager initialization.
' - Command: The DBCommand to execute.
' - Target: The module (like 'Me') where the completed event should be raised.
' - Event: The name of the event to raise when the command completes (e.g., "WrapperEvent").
Public Sub ExecuteCommand(rdcLink As String, Command As DBCommand, Target As Object, Event As String)
'<<< Incrementamos el contador para obtener un ID único
jobCounter = jobCounter + 1
Dim currentJobTag As String = "jRDCWrapJob_" & jobCounter
if logger then Log($"ExecuteCommand (Tag: ${currentJobTag}): Command=${Command.Name}, Event=${Event}"$)
'<<< Creamos una instancia de TJobInfo para guardar el target y el evento
Dim jobInfo As TJobInfo
jobInfo.Initialize
jobInfo.Target = Target
jobInfo.EventName = Event
jobInfo.IsQuery = False ' Mark as command job
'<<< Guardamos la información del job en el mapa, usando el tag único como llave
activeJobs.Put(currentJobTag, jobInfo)
reqManager.Initialize(Me, rdcLink)
cmd = Command
'<<< Ejecutamos el comando pasando nuestro TAG ÚNICO
reqManager.ExecuteCommand(cmd, currentJobTag)
End Sub
'This sub will be called by the DBRequestManager when the job is done
Public Sub JobDone(job As HttpJob)
'<<< Obtenemos el Tag único que asignamos al job
Dim currentJobTag As String = job.Tag
'C <<< Verificamos si este job fue iniciado por nuestro wrapper
If activeJobs.ContainsKey(currentJobTag) = False Then
If logger Then Log($"JobDone: Se recibió un job con un tag desconocido: ${currentJobTag}"$)
job.Release
Return
End If
'<<< Recuperamos la información específica de este job desde el mapa
Dim jobInfo As TJobInfo = activeJobs.Get(currentJobTag)
Try
If jobInfo.IsQuery Then
' Handle query result
resultado.Initialize
resultado.Tag = jobInfo.EventName ' Usamos el nombre del evento original como Tag del resultado
If job.Success Then
Dim dbResult As DBResult = reqManager.HandleJob(job)
resultado.Success = True
resultado.Resultado = dbResult
resultado.ErrorMessage = ""
Else
resultado.Success = False
resultado.Resultado = Null
resultado.ErrorMessage = job.ErrorMessage
End If
job.Release
'<<< Usamos la información recuperada del mapa para llamar al Sub correcto
if logger then LogColor($"EVENTO: ${jobInfo.EventName}_Completed"$, Colors.Magenta)
CallSubDelayed2(jobInfo.Target, jobInfo.EventName & "_Completed", resultado)
Else
' Handle command result
resultado.Initialize
resultado.Tag = jobInfo.EventName
If job.Success Then
Dim dbResult As DBResult = reqManager.HandleJob(job)
' Dim rowsAffected As Int = reqManager.HandleCommandResult(job)
' For Each records() As Object In dbResult.Rows
' Dim rowsAffected As Int = records(dbResult.Columns.Get("AffectedRows"))
' Next
resultado.Success = True
resultado.resultado = dbResult
resultado.ErrorMessage = ""
Else
resultado.Success = False
resultado.resultado = Null
resultado.ErrorMessage = job.ErrorMessage
End If
job.Release
'<<< Usamos la información recuperada del mapa para llamar al Sub correcto
If logger Then LogColor($"EVENTO: ${jobInfo.EventName}_Completed"$, Colors.Magenta)
CallSubDelayed2(jobInfo.Target, jobInfo.EventName & "_Completed", resultado)
End If
'C <<< Se remueve el job del mapa en caso de ÉXITO
activeJobs.Remove(currentJobTag)
Catch
if logger then LogColor("Error en jRDC1Wrapper.JobDone: " & LastException, Colors.Red)
'<<< MUY IMPORTANTE: Remover el job del mapa para no tener fugas de memoria
activeJobs.Remove(currentJobTag)
End Try
End Sub

View File

@@ -100,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"
@@ -118,9 +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
@@ -1072,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

@@ -13,6 +13,11 @@ Version=12.8
' 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,7 +34,7 @@ Public Sub Initialize (vCallback As Object, vEventName As String, db As SQL) As
CallBack = vCallback
tsdb = db
Private mx As Map = traeInfoTrendSpending
' LogColor(mx, Colors.red)
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"))
@@ -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,7 +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)
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"
@@ -110,13 +119,13 @@ 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
@@ -221,6 +230,7 @@ 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 LogColor("RMI RESTANTES: " & (TS_RMI(0) - TS_RMI(1) - traeAcumuladoHoyTS("rmi")), Colors.red)
Return lasMaximas & "|" & elMonto
@@ -228,6 +238,7 @@ Sub trendSpending(accion As String, tipo As String, clienteId As String, id As S
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
@@ -324,45 +335,66 @@ 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, promoId As String) As Int
Private tsMaximas As Int = 10000000
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
LogColor($"Presupuesto: ${TS_BONIFICACIONES(0)} - Acumulado ayer: ${TS_BONIFICACIONES(1)} - Hoy: ${traeAcumuladoHoyTS("bonificaciones")}"$, Colors.Red)
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($"Monto de bonificacion: ${tsMonto}"$)
Log($"Presupuesto disponible: ${tsRestantes}"$)
Log($"Cantidad: ${laCant}"$)
Log($"Floor(tsRestantes / (tsMonto * laCant))= ${Floor(tsRestantes / (tsMonto * laCant))}"$)
Log($"Floor(${tsRestantes} / (${tsMonto} * ${laCant}))= ${Floor(tsRestantes / (tsMonto * 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))
End If
Log(">>> tsMaximas: " & tsMaximas)
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.
End If
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"))
Log($"Precio normal: ${c.GetString("CAT_GP_PRECIO")}, Precio desc: ${c.GetString("CAT_DP_PRECIO")}, Monto bonificacion: ${tsMonto}"$)
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
' Log("ROWCOUNT: " & c.RowCount)
If thisLog Then LogColor($" ============ TERMINA MONTO BONIFICACION ========"$, Colors.RGB(151,0,171))
Return tsMonto
End Sub
@@ -374,7 +406,7 @@ End Sub
' 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 logger As Boolean = False
Private Maxs As Int = 10000000
Private prodsVariablesXPresupuestoBonificaciones As List
Private prodsVariablesRequeridos As Int = traeProdsVariablesRequeridos(promo)
@@ -383,8 +415,8 @@ Sub maxPromosPorProdsVariables(idProdsVariables As List, promo As String)As Int
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), 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)
Next
prodsVariablesXPresupuestoBonificaciones.Sort(True)