30 Commits

Author SHA1 Message Date
f5fe4c4a52 VERSION 6.03.15
- Se corrige un error en el calculo del trade spending para que en algunos casos no calculaba bien en presupuesto.
- Se hace un cambio en subs.actualizaProducto, porque no ponia en 0 la bandera de pc_enviado.
2026-03-17 09:58:32 -06:00
60aa115e24 VERSION 6.02.03 2026-03-05 08:37:09 -06:00
eaa185bb6d VERSION 6.01.31
- Se corrigio que guarde los inventarios de loq ue trae la camionetay NO lo del almacen.
2026-02-04 13:38:09 -06:00
10a2c84997 VERSION 6.01.28
- Cambio en e manifiesto para corregir el "teclado" fantasma.
2026-02-03 09:53:58 -06:00
af1f4b9ead VERSION 5.12.18
- Se agrego auditoria en los "principales" eventos, se guardan en la tabla "auditoria"
2025-12-22 11:47:23 -06:00
af9ea44b95 VERSION 5.12.17
- Se agrego codigo para que el label de la notificacion tenga scroll vertical y se vaya al inicio del texto
2025-12-20 02:42:47 -06:00
426e8b0c87 VERSION 5.12.16
- Se agrego codigo para que el label de la notificacion tenga scroll vertical y se vaya al inicio del texto
2025-12-20 02:38:30 -06:00
5124f6c5a1 VERSION 5.12.16
- Se agrego codigo para que el label de la notificacion tenga scroll vertical y se vaya al inicio del texto
2025-12-20 02:30:16 -06:00
4e69087ff2 Version 5.12.16 2025-12-20 02:27:17 -06:00
4a5fc4dd05 Version 5.12.16 2025-12-20 02:23:30 -06:00
64a80661e8 Version 5.12.16
- Se agregó comando y script para enviar automáticamente el TAG con la version actual a GitHub.
2025-12-20 02:15:07 -06:00
96838bf61b VERSION 5.12.16
- Se agregó comando y script para enviar automáticamente el TAG con la version actual a GitHub.
2025-12-20 02:11:40 -06:00
7e19a197a1 Version 5.12.15.test
PRUEBA
2025-12-20 01:49:09 -06:00
64e9e6b389 Version 5.12.15.test
PRUEBA
2025-12-20 01:47:58 -06:00
63df3fbf39 Version 5.12.15.test
PRUEBA
2025-12-20 01:46:25 -06:00
e72a1381d5 Version 5.12.15.test
PRUEBA
2025-12-20 01:43:14 -06:00
367ff75966 Version 5.12.15.test
PRUEBA
2025-12-20 01:36:22 -06:00
2ec2e9acb3 Version 5.12.15.test
PRUEBA
2025-12-20 01:34:50 -06:00
246437fc98 Version 5.12.15.test
PRUEBA
2025-12-20 01:26:18 -06:00
67e0b906dc Version 5.12.15.test
PRUEBA
2025-12-20 00:41:20 -06:00
d7e6643f15 Version 5.12.15.test 2025-12-20 00:29:29 -06:00
cc5261c67f Version 5.12.15.test
Prueba
2025-12-20 00:28:03 -06:00
cc36c6c1da Version 5.12.15.test 2025-12-20 00:11:35 -06:00
441fe0c5fb Version 5.12.15.test
- Commit SIN cambios de codigo, solo de prueba con tags
2025-12-20 00:08:49 -06:00
136df88646 - VERSION 5.12.15
- Se agregga codigo para que si hay nulos en los datos de Trade Spending no truene la aplicacion.
2025-12-19 23:36:33 -06:00
f0116e375d - VERSION 5.12.14
- Se agrego codigo para que el label de la notificacion tenga scroll vertical y se vaya al inicio del texto
2025-12-19 20:12:14 -06:00
409c224820 - VERSION 5.12.10
- Codigo de prueba para envio de pedido en BATCH
- Se amplio el panel de las notificaciones
- Si no hay presupuesto para bonificaciones NO se muestra la opcion de PROMOS en "Productos"
2025-12-10 16:58:51 -06:00
72ce7c8806 - VERSION 5.12.5
- Se agregó que si no hay presupuesto de bonificaciones, el apartado de PROMOS no aparezca al entrar a productos.
- Se agrego en MAPA_RUTAS que ponga los globitos dinamicamente (faltaba el rojo)
2025-12-08 13:47:05 -06:00
7a88acaf4c - VERSOIN 5.11.26
- Se agregó le descripcion del "flujo" de las promociones en C_Promos
2025-11-30 02:33:43 -06:00
749cf6e7fe - VERSION 5.11.01
- Se cambio como se guarda la informacion del registro del dispositivo, antes en KeyValueStore y ahora en una base de datos propia, esto es porque al parecer en android 10 y 12 no se esta guardando la informacion.
2025-11-05 18:24:48 -06:00
38 changed files with 2200 additions and 2877 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
@@ -167,6 +174,12 @@ Private Sub B4XPage_Created (Root1 As B4XView)
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")
@@ -183,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")
@@ -400,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")
@@ -530,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
@@ -956,8 +974,6 @@ Private Sub cb_cartaPorte_CheckedChange(Checked As Boolean)
Starter.skmt.ExecNonQuery($"insert into CAT_VARIABLES (CAT_VA_DESCRIPCION, CAT_VA_VALOR) values ('CARTAPORTE', '${Checked}')"$)
End Sub
private Sub l_geocerca_Click
If cb_geocerca.Enabled = False Then ToastMessageShow("Ingrese la contraseña para modificar", True)
End Sub
@@ -1065,7 +1081,7 @@ Private Sub ImageView1_LongClick
reqManagerX.Initialize(Me, "http://keymon.net:9010/SALMA")
Private cmdX As DBCommand
cmdX.Initialize
cmdX.Name = "traeConexion4"
cmdX.Name = "update_usuario_guna_nobajas"
cmdX.Parameters = Array As Object("CDAZA", 2, 3, 4)
reqManagerX.ExecuteQuery(cmdX, 0, "prueba")

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
@@ -790,8 +796,8 @@ Sub B4XPage_Appear
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"))
Log("Monto Bonificacion -->> " & B4XPages.MainPage.promos.ts.traeMontoBonificacion(dp.GetString("CAT_DP_IDPROD"), dp.GetString("CAT_DP_PRECIO"), mPromoXMonto.Get("id"),"LOG_APPEAR1"))
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (B4XPages.MainPage.promos.ts.traeMontoBonificacion(dp.GetString("CAT_DP_IDPROD"), dp.GetString("CAT_DP_PRECIO"), mPromoXMonto.Get("id"), "APPEAR2") * dp.GetString("CAT_DP_PZAS"))
End If
Next
B4XPages.MainPage.promos.ts.modTrendSpending("RESTA", "BONIFICACIONES", elMontoTSDeLaVenta)
@@ -799,6 +805,7 @@ Sub B4XPage_Appear
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.
@@ -817,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)
@@ -896,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)
@@ -909,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
@@ -982,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)
@@ -1002,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
@@ -1045,6 +1085,8 @@ Sub Guardar_Click
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.
@@ -1060,8 +1102,9 @@ Sub Guardar_Click
End Sub
Sub mandaPendientes
B4XPages.MainPage.principal.enviaPedido(Null)
B4XPages.MainPage.principal.enviaPedidoCliente(Null)
' B4XPages.MainPage.principal.enviaPedido(Null)
' B4XPages.MainPage.principal.enviaPedidoCliente(Null)
B4XPages.MainPage.principal.enviaPedidoBatch(Null)
End Sub
Sub NUEVO_Click
@@ -1171,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
@@ -1193,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
@@ -1317,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
@@ -3243,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.
@@ -3538,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)
@@ -3547,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")
@@ -3746,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
@@ -3788,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)
@@ -3945,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"))
@@ -4419,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

@@ -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

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

View File

@@ -309,6 +309,10 @@ Private Sub B4XPage_Created (Root1 As B4XView)
kh.centraPanel(Panel2, Root.Width)
kh.centraPanel(Panel1, Root.Width)
kh.centraPanel(p_botonesResumen, Root.Width)
p_transparente.Top = 0 : p_transparente.left = 0
p_transparente.Height = Root.Height : p_transparente.Width = Root.Width
' PNL_ACCESO.Top = 0 : PNL_ACCESO.left = 0
' PNL_ACCESO.Height = Root.Height : PNL_ACCESO.Width = Root.Width
' kh.centraPanel(Panel7, Root.Width)
' kh.centraPanel(PNL_ACCESO, Root.Width)
@@ -324,6 +328,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 Principal")
' Log(Subs.traeDiaSemana)
linker.Initialize(Me, "Linker", True)
Starter.errorConnDBReq = False
@@ -564,7 +569,7 @@ Sub B4XPage_Appear
NUEVO.Enabled = True
B_PROXIMA.Enabled = True
End If
'############# Deshabilitamos botones para validacion de ruta y vinculo #########
c = Starter.skmt.ExecQuery("select count(*) as cuantos from CAT_VARIABLES WHERE CAT_VA_DESCRIPCION = 'LIGADO' and CAT_VA_VALOR = 1")
c.Position = 0
@@ -595,6 +600,9 @@ Sub B4XPage_Appear
If n.GetString("cuantos") >= kh.traeMaxClientesNuevos Then NUEVO.Enabled = False
' LogColor(">>>>>>>> REVISAMOS GUID <<<<<<<<<", Colors.red)
' Subs.generaGUID_EnExterno
Subs.RecalcularInventario
End Sub
Sub trabajar_Click
@@ -623,7 +631,6 @@ Sub trabajar_Click
End Sub
Sub Subir_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
@@ -635,9 +642,8 @@ Sub Subir_Click
' 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)
CARGA = "SUBIR"
' P1.Visible = True
trabajar.Visible = False
@@ -692,6 +698,18 @@ Sub Subir_Click
End If
End If
End If
Private hn As Cursor = Starter.skmt.ExecQuery($"select distinct HN_CODIGO, HN_ID from hist_notificaciones"$)
If hn.RowCount > 0 Then
For i = 0 To hn.RowCount - 1
hn.Position = i
cmd.Initialize
cmd.Name = "borraHistNotificaciones"
cmd.Parameters = Array As Object( hn.GetString("HN_CODIGO"), hn.GetString("HN_ID"))
reqManager.ExecuteCommand(cmd , "borraHistNotificaciones_"&hn.GetString("HN_CODIGO")&"_"&hn.GetString("HN_ID"))
Next
End If
hn.Close
End Sub
Sub cargar_Click
@@ -810,6 +828,7 @@ Sub cargar_Click
Starter.skmt.ExecNonQuery("delete from DESC_CLIENTES")
Starter.skmt.ExecNonQuery("delete from CAT_ENCUESTA_PREGUNTA")
Starter.skmt.ExecNonQuery("delete from CAT_PROMO_MONTO")
Starter.skmt.ExecNonQuery("delete from CAT_NOTIFICACIONES")
''' PEDIDO DOE
Starter.skmt.ExecNonQuery("delete from CAT_GUNAPROD_DOE")
Starter.skmt.ExecNonQuery("delete from PEDIDO_DOE")
@@ -1029,17 +1048,17 @@ Sub cargar_Click
cmd.Name = "select_cat_clientes_guna_KELL2"
cmd.Parameters = Array As Object(E_RUTA2.text, ALMACEN)
' reqManager.ExecuteQuery(cmd , 0, "kmt_datos")
cmd.Initialize
cmd.Name = "select_hist_datos_KELL"
cmd.Parameters = Array As Object(E_RUTA2.text, ALMACEN,e_ruta.text, ALMACEN)
reqManager.ExecuteQuery(cmd , 0, "hist_datos")
cmd.Initialize
cmd.Name = "select_hist_promos_KELL"
cmd.Parameters = Array As Object(E_RUTA2.text, ALMACEN)
reqManager.ExecuteQuery(cmd , 0, "hist_promos")
cmd.Initialize
cmd.Name = "select_hist_cliente_promos_KELL"
cmd.Parameters = Array As Object(E_RUTA2.text, ALMACEN)
@@ -1156,18 +1175,23 @@ Sub cargar_Click
cmd.Name = "select_pedido_doe"
cmd.Parameters = Array As Object( ALMACEN,e_ruta.text )
reqManager.ExecuteQuery(cmd , 0, "pedido_doe")
cmd.Initialize
cmd.Name = "select_cat_gunaprod_doe"
cmd.Parameters = Array As Object( ALMACEN,e_ruta.text )
reqManager.ExecuteQuery(cmd , 0, "cat_gunaprod_doe")
''' FIN DOE
cmd.Initialize
cmd.Name = "select_cat_devoluciones_KELL"
cmd.Parameters = Array As Object(ALMACEN)
reqManager.ExecuteQuery(cmd , 0, "prods_rmi")
cmd.Initialize
cmd.Name = "selectNotificaciones"
cmd.Parameters = Array As Object(ALMACEN, e_ruta.Text)
reqManager.ExecuteQuery(cmd , 0, "selectNotificaciones")
cargar.Visible = False
Subir.Visible = False
trabajar.Visible=False
@@ -1425,7 +1449,6 @@ Sub JobDone(Job As HttpJob)
'CAT_GP_INICIATIVA = 5
' skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD(CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG,CAT_GP_ALMACEN,CAT_GP_DEV) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", Array As Object (CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG, CAT_GP_ALMACEN,CAT_GP_DEV))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD(CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG,CAT_GP_ALMACEN,CAT_GP_TIPOPROD,CAT_GP_INICIATIVA,CAT_GP_DEV,CAT_GP_CODPROMO,CAT_GP_TIPOPROD2,CAT_GP_PROMOCION) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,0,?,?)", Array As Object (CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG, CAT_GP_ALMACEN,CAT_GP_TIPOPROD, CAT_GP_INICIATIVA,CAT_GP_DEV, CAT_GP_TIPOPROD2,CAT_GP_PROMOCION))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_INVENTARIO(CI_IDPROD,CI_INVENTARIO) VALUES (?,?)", Array As Object (CAT_GP_ID,CAT_GP_ALMACEN))
Next
Starter.skmt.TransactionSuccessful
Starter.skmt.EndTransaction
@@ -1479,6 +1502,7 @@ Sub JobDone(Job As HttpJob)
' skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD(CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG,CAT_GP_ALMACEN,CAT_GP_DEV) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", Array As Object (CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG, CAT_GP_ALMACEN,CAT_GP_DEV))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD2(CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG,CAT_GP_ALMACEN,CAT_GP_TIPOPROD,CAT_GP_INICIATIVA,CAT_GP_DEV,CAT_GP_CODPROMO,CAT_GP_TIPOPROD2) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", Array As Object (CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG, CAT_GP_ALMACEN,CAT_GP_TIPOPROD, CAT_GP_INICIATIVA,CAT_GP_DEV,CAT_GP_CODPROMO,CAT_GP_TIPOPROD))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD5(CAT_GP_ID,CAT_GP_ALMACEN) VALUES (?,?)", Array As Object (CAT_GP_ID,CAT_GP_ALMACEN))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_INVENTARIO(CI_IDPROD,CI_INVENTARIO) VALUES (?,?)", Array As Object (CAT_GP_ID,CAT_GP_ALMACEN))
Next
Starter.skmt.TransactionSuccessful
Starter.skmt.EndTransaction
@@ -1525,6 +1549,7 @@ Sub JobDone(Job As HttpJob)
Dim CAT_GP_TIPOPROD As Int = records(RESULT.Columns.Get("CAT_GP_TIPOPROD"))
' Dim CAT_GP_DEV As String = records(RESULT.Columns.Get("CAT_GP_DEV"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD2(CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG,CAT_GP_ALMACEN,CAT_GP_TIPOPROD,CAT_GP_DEV,CAT_GP_CODPROMO) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,0)", Array As Object (CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG, CAT_GP_ALMACEN,CAT_GP_TIPOPROD,"0"))
' Starter.skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD5(CAT_GP_ID,CAT_GP_ALMACEN) VALUES (?,?)", Array As Object (CAT_GP_ID,CAT_GP_ALMACEN))
' skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD2(CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG,CAT_GP_ALMACEN,CAT_GP_TIPOPROD,CAT_GP_DEV,CAT_GP_CODPROMO) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,0)", Array As Object (CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG, CAT_GP_ALMACEN,CAT_GP_TIPOPROD,"0"))
Next
Starter.skmt.TransactionSuccessful
@@ -1569,6 +1594,7 @@ Sub JobDone(Job As HttpJob)
Dim CAT_GP_ALMACEN As Int = records(RESULT.Columns.Get("CAT_GP_ALMACEN"))
Dim CAT_GP_TIPOPROD As Int = records(RESULT.Columns.Get("CAT_GP_TIPOPROD"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD2(CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG,CAT_GP_ALMACEN,CAT_GP_TIPOPROD) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", Array As Object (CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG, CAT_GP_ALMACEN,CAT_GP_TIPOPROD))
' Starter.skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD5(CAT_GP_ID,CAT_GP_ALMACEN) VALUES (?,?)", Array As Object (CAT_GP_ID,CAT_GP_ALMACEN))
' skmt.ExecNonQuery2("INSERT INTO CAT_GUNAPROD2(CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG,CAT_GP_ALMACEN,CAT_GP_TIPOPROD) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", Array As Object (CAT_GP_ID,CAT_GP_NOMBRE,CAT_GP_IMP1,CAT_GP_IMP2,CAT_GP_PRECIO,CAT_GP_CLASIF,CAT_GP_STS,CAT_GP_TIPO,CAT_GP_SUBTIPO,CAT_GP_IMG, CAT_GP_ALMACEN,CAT_GP_TIPOPROD))
Next
Starter.skmt.TransactionSuccessful
@@ -1849,6 +1875,19 @@ Sub JobDone(Job As HttpJob)
PB2.Progress = 100
S_CP.Text = "VALIDANDO"
End If
If RESULT.Tag.As(String).StartsWith("pedido_completo_") Then 'query tag
For Each records() As Object In RESULT.Rows
Private temp() As String = Regex.Split("_", RESULT.Tag)
' Log(temp(2))
If temp.Length > 1 Then
Starter.skmt.ExecNonQuery($"update pedido_cliente set pc_enviado = 1 where pc_cliente = '${temp(2)}'"$)
Log($"update pedido_cliente set pc_enviado = 1 where pc_cliente = '${temp(2)}'"$)
Starter.skmt.ExecNonQuery($"update pedido set pe_enviado = 1 where pe_cliente = '${temp(2)}'"$)
Log($"update pedido set pe_enviado = 1 where pe_cliente = '${temp(2)}'"$)
End If
Next
End If
If RESULT.Tag = "version" Then 'query tag
connecta.TextColor = Colors.White
@@ -1885,9 +1924,12 @@ Sub JobDone(Job As HttpJob)
End If
If RESULT.Tag = "ruta" Then 'query tag
Log(654)
Subs.logJobDoneResultados(RESULT)
e_ruta.Enabled = True
' Log(RESULT)
' Log(RESULT.Columns.Get("VALIDO"))
Log(RESULT)
Log(RESULT.Columns.Get("VALIDO"))
' Log(RESULT.Rows.Size)
If RESULT.Columns.Get("VALIDO") = "0" Then ToastMessageShow("Ruta incorrecta", True)
If RESULT.Rows.Size = 0 Then ToastMessageShow("No hay ruta para ese usuario", True)
For Each records() As Object In RESULT.Rows
@@ -2184,7 +2226,7 @@ Sub JobDone(Job As HttpJob)
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_RMI (CAT_ID, CAT_DESCRIPCION, CAT_MONTO) VALUES (?,?,?)", Array As Object (CAT_ID, CAT_DESCRIPCION, CAT_MONTO))
Next
End If
If RESULT.Tag = "semanaCalLaboral" Then 'query tag
' Subs.logJobDoneResultados(RESULT)
For Each records() As Object In RESULT.Rows
@@ -2194,6 +2236,17 @@ Sub JobDone(Job As HttpJob)
Next
End If
If RESULT.Tag = "selectNotificaciones" Then 'query tag
Subs.logJobDoneResultados(RESULT)
For Each records() As Object In RESULT.Rows
Dim CN_CLIENTE As String = records(RESULT.COLUMNS.GET("HIST_NTC_IDCLIENTE"))
Dim CN_NOTIFICACION As String = records(RESULT.COLUMNS.GET("HIST_NTC_NOTIFICACION"))
Dim CN_CODIGO As String = records(RESULT.COLUMNS.GET("HIST_NTC_CODIGO"))
Dim CN_ID As String = records(RESULT.COLUMNS.GET("HIST_NTC_ID"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_NOTIFICACIONES (CN_CODIGO, CN_ID, CN_CLIENTE, CN_NOTIFICACION) VALUES (?,?,?,?)", Array As Object (CN_CODIGO, CN_ID, CN_CLIENTE, CN_NOTIFICACION))
Next
End If
If RESULT.Tag = "trendSpending" Then 'query tag
' Subs.logJobDoneResultados(RESULT)
Starter.skmt.ExecNonQuery("delete from HIST_TREND_SPENDING_SEMANAL")
@@ -2220,6 +2273,10 @@ Sub JobDone(Job As HttpJob)
' Subs.logJobDoneResultados(RESULT)
ts.Initialize(Me, "ts", Starter.skmt)
End If
' If RESULT.Tag = "borraHistNotificaciones" Then enviaHistNotificaciones
' If RESULT.Tag = "insertHistNotificaciones" Then revisaHistNotificaciones
End If
End If
@@ -2230,15 +2287,21 @@ Sub JobDone(Job As HttpJob)
If reqManager.reqsList.IsInitialized Then
LogColor(reqManager.reqsList, Colors.blue)
' LogColor(reqManager.reqsList.Size, Colors.blue)
actualizaProgressBar
LogColor(reqManager.reqsList.Size, Colors.blue)
If CARGA = "SUBIR" Then actualizaProgressBar
'Si ya se procesaron TODAS las peticiones, entonces realizamos validaciones.
If reqManager.reqsList.Size = 0 Then
If CARGA = "SUBIR" Then revisaHistNotificaciones
End If
End If
' LogColor(reqTotales, Colors.blue)
' If Starter.Logger Then Log($"tiempo Request "${Job.Tag}": ${((reqManager.inicioJobDone - reqManager.inicioRequest)/1000)}"$)
' If Starter.Logger Then Log($"tiempo JobDone "${Job.Tag}": ${((DateTime.Now - reqManager.inicioJobDone)/1000)}"$)
' If Starter.Logger Then Log($"tiempo Total "${Job.Tag}": ${((DateTime.Now - inicioContador)/1000)}"$)
If CARGA = "CARGAR" And S_CP.Text = "LISTO" And S_CC.Text = "LISTO" And S_CH.Text = "LISTO" Then
' LogColor("TERMINAMOS", Colors.red)
B_OK_PAS.Text = "OK"
@@ -2250,6 +2313,48 @@ Sub JobDone(Job As HttpJob)
' reqManager.PrintTable(RESULT)2
End Sub
'Envia el historial de notificaciones despues de haberlas borrado para que no se dupliquen.
Sub enviaHistNotificaciones
Private hn As Cursor = Starter.skmt.ExecQuery($"select * from hist_notificaciones"$)
If hn.RowCount > 0 Then
For i = 0 To hn.RowCount - 1
hn.Position = i
cmd.Initialize
cmd.Name = "insertHistNotificaciones"
cmd.Parameters = Array As Object( hn.GetString("HN_CODIGO"), hn.GetString("HN_ID"), hn.GetString("HN_FECHA"))
reqManager.ExecuteCommand(cmd , "insertHistNotificaciones")
Next
hn.Close
End If
End Sub
' Revisa que en web haya el numero correcto de notificaciones en el historial
Sub revisaHistNotificaciones
LogColor("####################### REVISA NOTIS ########", Colors.red)
Private cn As Cursor = Starter.skmt.ExecQuery("select count(HN_CODIGO) as cuantos, HN_CODIGO, HN_ID from HIST_NOTIFICACIONES")
If cn.RowCount > 0 Then
cn.Position = 0
Private CuantasN As Int = cn.GetInt("cuantos")
cmd.Name = "selectCuantasNotificaciones"
cmd.Parameters = Array As Object(cn.GetString("HN_ID"), cn.GetString("HN_CODIGO"))
reqManagerW.ExecuteQuery(Starter.DBReqServer, cmd, Me, "selectCuantasNotificaciones")
Wait For selectCuantasNotificaciones_Completed (r As TResultado)
If r.Success Then
LogColor("####################### selectCuantasNotificaciones ########", Colors.red)
Subs.logJobDoneResultados(r.resultado)
For Each records() As Object In r.resultado.Rows
Dim CuantasN As Int = records(r.resultado.Columns.Get("CUANTOS"))
If cn.GetInt("cuantos") > CuantasN Then
enviaHistNotificaciones
End If
Next
Else
Log(r.ErrorMessage)
End If
End If
End Sub
Sub actualizaProgressBar
Log($"Porcentaje = ${(((reqTotales-reqManager.reqsList.Size)/reqTotales)*100).As(Int)}"$)
Private porcentajePB2 As Int = (((reqTotales-reqManager.reqsList.Size)/reqTotales)*100).As(Int)
@@ -2363,6 +2468,8 @@ Sub connecta_Click
reqManager.trackInit
' EL EVENTO DE CONECTAR AHORA SE DISPARA DESPUES DE REVISAR SI LA RUTA ESTA LIGADA O NO AL DISPOSITIVO (verifyDevice).
' REVISAR EL SUB "Linker_Response"
linker.verifyDevice(Subs.traeAlmacen, e_ruta.text)
' Else
@@ -2379,22 +2486,25 @@ Sub connecta2
If vv.GetString("CAT_VA_VALOR") = 0 Then revisaVersion = False
End If
If revisaVersion Then ' Si VALIDA_VERSION no está en CERO ... revisamos.
Log(123)
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "select_version_KELL"
cmd.Parameters = Array As Object(ALMACEN, e_ruta.text)
reqManager.ExecuteQuery(cmd , 0, "version")
Else ' Si está en CERO (Validacion deshabilitada), continuamos a connecta3.
' Log(456)
connecta3
End If
End Sub
Sub connecta3
' Log(789)
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "select_ruta5_KELL"
cmd.Parameters = Array As Object(ALMACEN, e_ruta.text, usuario)
' Log($"******* Almacen: ${ALMACEN}, ${e_ruta.text}, ${usuario}"$)
Log($"******* Almacen: ${ALMACEN}, ${e_ruta.text}, ${usuario}"$)
reqManager.ExecuteQuery(cmd , 0, "ruta")
e_ruta.Enabled = False
If e_ruta.Text = "KMTSKLL1" Then e_ruta.Enabled = True
@@ -2416,6 +2526,7 @@ Private Sub connecta_LongClick
'' End If
' Log("MANDAMOS BITACORA")
If e_ruta.Text = "KMTKLL1" Then Subs.deshabilitaValidaciones
' B4XPages.MainPage.recordatorio.agregaPanelRecordatorio(Root)
End Sub
Sub BUSCA_Click
@@ -2467,6 +2578,7 @@ Sub e_ruta_EnterPressed
Starter.skmt.ExecNonQuery("delete from TREND_SPENDING")
Starter.skmt.ExecNonQuery("delete from HIST_TREND_SPENDING_SEMANAL")
Starter.skmt.ExecNonQuery("delete from VERSIONES")
Starter.skmt.ExecNonQuery("delete from auditoria")
Starter.skmt.ExecNonQuery2("INSERT INTO HIST_ENVIOS VALUES (?,0,?)", Array As Object(sTime, "PEDIDO"))
Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("NUMERO_PEDIDO"))
@@ -2719,6 +2831,7 @@ Sub B_OK_RES_Click
End Sub
Sub Resumen_Click
B4XPages.MainPage.aud.guarda("Entrada a resumenDia")
Log("###############")
L_ABORDO.Text = "0"
P_RESUMEN.Visible = True
@@ -3178,7 +3291,7 @@ Sub SUBIR_INFO_PEDIDO
If d.GetString("MONTO") <> Null And d.GetString("MONTO") <> "" Then monto1 = d.GetString("MONTO")
Private abordo1 As String = L_ABORDO.Text
If abordo1 = "" Then abordo1 = "0"
Log($"${monto1}, ${abordo1}"$)
' Log($"${monto1}, ${abordo1}"$)
monto1 = monto1 - abordo1
reqManager.trackInit
@@ -3188,6 +3301,8 @@ Sub SUBIR_INFO_PEDIDO
cmd.Name ="insert_drop2_KELL"
cmd.Parameters = Array As Object(usuario, l_ruta.Text, fecha, l_porvisitar.Text, l_drop.Text, l_efectiva.Text, l_cuantosc.Text, l_cuantosn.Text, monto1, "ENVIO", ALMACEN, abordo1)
reqManager.ExecuteCommand(cmd , "inst_noventa_ins_drop_kell")
' Log($"${usuario}, ${l_ruta.Text}, ${fecha}, ${l_porvisitar.Text}, ${l_drop.Text}, ${l_efectiva.Text}, ${l_cuantosc.Text}, ${l_cuantosn.Text}, ${monto1}, "ENVIO", ${ALMACEN}, ${abordo1}"$)
Log("################## inst_noventa_ins_drop_kell")
img2.Visible =True
contador_env = contador_env + 1
S_CP.Text = "Envio Cabecera"
@@ -3289,7 +3404,7 @@ Sub SUBIR_INFO_PEDIDO
PB2.Progress = 1
' PEDIO_CLIENTE
enviaPedidoCliente("Todos")
' enviaPedidoCliente("Todos")
d = Starter.skmt.ExecQuery("SELECT COUNT(*) as CUANTOS_PEDIDOSC FROM PEDIDO_CLIENTE ")
d.Position=0
@@ -3301,10 +3416,12 @@ Sub SUBIR_INFO_PEDIDO
PORENVIAR = 0
' PEDIDO
t3.Initialize("T3", 500) ' 1000 = 1 second
t3.Enabled = True
Wait For t3_tick
enviaPedido("Todos")
' t3.Initialize("T3", 500) ' 1000 = 1 second
' t3.Enabled = True
' Wait For t3_tick
' enviaPedido("Todos")
enviaPedidoBatch("Todos") ' ****** AQUI VA PEDIDO_CLIENTE Y PEDIDO JUNTOS *****
d = Starter.skmt.ExecQuery("SELECT COUNT(*) as CUANTOS_PEDIDO FROM PEDIDO")
d.Position=0
@@ -3404,6 +3521,187 @@ Sub SUBIR_INFO_PEDIDO
DateTime.TimeFormat = "HH:mm:ss"
End Sub
' 1. Recopila encabezados y detalles de pedidos locales (todos o solo los pendientes).
' 2. Genera un ID único (Arch) para vincular exactamente cada venta con sus productos.
' 3. Empaqueta todo en una lista de comandos (Batch) para enviarlo al servidor en una sola transacción.
Sub enviaPedidoBatch(filtro As String)
' Creamos una lista llamada BatchCommands. Aquí vamos a guardar todas las instrucciones
' de base de datos que queremos mandar al servidor de un solo golpe (en lote o "batch").
Dim BatchCommands As List
BatchCommands.Initialize
Log($"enviaPedidoBatch(${filtro})"$)
' Preparamos una variable para filtrar la consulta a la base de datos.
' Si el filtro no dice "Todos", armamos la condición para traer solo los pedidos que no se han enviado (PC_ENVIADO = 0).
Private condicion As String = ""
If filtro <> "Todos" Then condicion = "where PC_ENVIADO = 0"
' Ejecutamos una consulta (Query) a la base de datos local de SQLite (skmt).
' Buscamos los ENCABEZADOS de los pedidos en la tabla PEDIDO_CLIENTE usando la condición que armamos arriba.
' El resultado se guarda en un Cursor llamado 'cx', que es como una tabla en memoria por la que podemos navegar.
Private cx As Cursor = Starter.skmt.ExecQuery($"SELECT PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT, PC_COSTO_SIN, PC_RUTA, PC_ALMACEN, PC_ENVIADO FROM PEDIDO_CLIENTE ${condicion}"$)
Log($"SELECT PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT, PC_COSTO_SIN, PC_RUTA, PC_ALMACEN, PC_ENVIADO FROM PEDIDO_CLIENTE ${condicion}"$)
Log("pedido_cliente: " & cx.RowCount)
' Reiniciamos la variable de condición para usarla ahora en el DETALLE de los pedidos.
Private condicion As String = ""
If filtro <> "Todos" Then condicion = "where PE_ENVIADO = 0"
' Verificamos si en la tabla de envíos históricos (HIST_ENVIOS) hay registros del tipo "ABORDO" (Ventas en ruta directa).
c = Starter.skmt.ExecQuery2("SELECT COUNT(*) as CANTIDAD FROM HIST_ENVIOS WHERE HE_TIPO = ?",Array As String("ABORDO") )
c.Position = 0
' Si encontramos que sí hay ventas a bordo...
If c.GetString("CANTIDAD") > 0 Then
Log($"pe_cedis_0"$)
' Actualizamos la tabla PEDIDO para que los artículos del cliente "0" (que suele ser el inventario a bordo)
' y que no tengan un número de folio, se marquen con el almacén/cedis "RECARGA".
Starter.skmt.ExecNonQuery2("update PEDIDO set PE_CEDIS = ? where PE_CLIENTE =? AND PE_FOLIO IS NULL ", Array As Object("RECARGA", "0"))
End If
' Hacemos una actualización rápida a los registros de PEDIDO que no tengan folio (folio 0 o 1).
' Les asignamos temporalmente el 'rowid' (el número de fila interno de SQLite) como folio para identificarlos.
Starter.skmt.ExecNonQuery("UPDATE PEDIDO SET PE_FOLIO = rowid where PE_FOLIO = 0 or PE_FOLIO = 1")
' Revisamos si nuestro cursor 'cx' (los encabezados de pedido) trajo algún resultado.
If cx.RowCount > 0 Then ' Si hay pedido entonces lo enviamos.
' Iniciamos un bucle (For) para recorrer cada uno de los encabezados de pedido encontrados.
For j = 0 To cx.RowCount - 1
Log("===== ENVIAMOS PRODUCTOS DE PEDIDO =====")
' Movemos el cursor 'cx' a la posición 'j' actual del bucle.
cx.Position = j
' Generamos un identificador único (Arch) concatenando el almacén, la ruta, el cliente y la fecha/hora actual.
' Esto sirve para agrupar en el servidor el encabezado con sus respectivos detalles.
Dim Arch As String = Subs.traeAlmacen & "_" & Subs.traeRuta & "_" & cx.GetString("PC_CLIENTE") & "_" & DateTime.Now
' Preparamos un comando de base de datos (DBCommand) para mandar al servidor.
Dim cmdHeader As DBCommand
cmdHeader.Initialize
' Asignamos el nombre del procedimiento almacenado o query que está en el servidor (jRDC2).
cmdHeader.Name = "insert_pedidos_KELL_arch"
' Pasamos los parámetros leyendo los datos del cursor 'cx' (encabezado) y le pasamos el ID único 'Arch'.
cmdHeader.Parameters = Array As Object(cx.GetString("PC_CLIENTE"),cx.GetString("PC_FECHA"),cx.GetString("PC_USER"),cx.GetString("PC_NOART"),cx.GetString("PC_MONTO"),cx.GetString("PC_LON"),cx.GetString("PC_LAT"),ALMACEN,l_ruta.text,cx.GetString("PC_COSTO_SIN"), Arch)
' Añadimos este comando a nuestra lista del lote (Batch).
BatchCommands.Add(cmdHeader)
' Ahora hacemos una consulta para buscar el DETALLE de este pedido (los productos individuales).
' Filtramos por la condición (si se envió o no) y lo amarramos al cliente actual del bucle (PC_CLIENTE).
Private cPed As Cursor = Starter.skmt.ExecQuery($"SELECT PE_CEDIS, PE_COSTO_TOT, PE_COSTOU, PE_CANT, PE_PRONOMBRE, PE_PROID, PE_CLIENTE, PE_FECHA, PE_USUARIO, PE_COSTO_SIN, PE_RUTA, PE_DESC, PE_FOLIO, PE_TIPO, PE_ARCH FROM PEDIDO ${condicion} ${(IIf(condicion = "","where", "and"))} pe_cliente = '${cx.GetString("PC_CLIENTE")}' "$)
' Si hay detalles para este encabezado...
If cPed.RowCount > 0 Then
' Iniciamos un bucle interno para recorrer cada producto de este pedido.
For i = 0 To cPed.RowCount - 1
Log("==== ENVIAMOS PRODS ====")
' Movemos el cursor de detalles a la posición actual.
cPed.Position = i
' Preparamos el comando para enviar este producto al servidor.
Dim cmdDetail As DBCommand
cmdDetail.Initialize
' Si el perfil del vendedor es especial ("V-ESPECIAL")...
If PERFIL = "V-ESPECIAL" Then
Log("===== V-ESPECIAL =====")
' Nota: Aquí el código original tiene un detalle, usa la variable global 'cmd' en lugar de 'cmdDetail'
' que acaba de inicializar, pero la copiamos tal cual. Utiliza un query distinto para ventas especiales.
cmd.Name = "insert_pedido_esp_KELL"
cmd.Parameters = Array As Object(cPed.GetString("PE_CEDIS"),ALMACEN,cPed.GetString("PE_COSTO_TOT"),cPed.GetString("PE_COSTOU"),cPed.GetString("PE_CANT"),cPed.GetString("PE_PRONOMBRE"),cPed.GetString("PE_PROID"),cPed.GetString("PE_CLIENTE"),cPed.GetString("PE_FECHA"),cPed.GetString("PE_USUARIO"),cPed.GetString("PE_RUTA"),cPed.GetString("PE_COSTO_SIN"),cPed.GetString("PE_DESC"),cPed.GetString("PE_FOLIO"),cPed.GetString("PE_TIPO"),NUMERO_PEDIDO)
Else
' Si es un vendedor normal, usa el comando estándar para insertar el detalle
' y le pasa la misma variable 'Arch' para que en el servidor sepa de qué encabezado es.
cmdDetail.Name = "insert_pedido_KELL_arch"
cmdDetail.Parameters = Array As Object (cPed.GetString("PE_CEDIS"),ALMACEN,cPed.GetString("PE_COSTO_TOT"),cPed.GetString("PE_COSTOU"),cPed.GetString("PE_CANT"),cPed.GetString("PE_PRONOMBRE"),cPed.GetString("PE_PROID"),cPed.GetString("PE_CLIENTE"),cPed.GetString("PE_FECHA"),cPed.GetString("PE_USUARIO"),cPed.GetString("PE_RUTA"), cPed.GetString("PE_COSTO_SIN"),cPed.GetString("PE_DESC"),cPed.GetString("PE_FOLIO"), cPed.GetString("PE_TIPO"), Arch)
End If
' Añadimos la instrucción del producto al lote de envío.
BatchCommands.Add(cmdDetail)
Next
End If
Next
' Al terminar de empaquetar, enviamos toda la lista de instrucciones (BatchCommands) al servidor de un solo golpe.
' Se le asigna un nombre de etiqueta (Tag) para saber qué responderá el JobDone ("pedido_completo_" + id de cliente).
' (Ojo visual para el programador: Esta línea está dentro del 'If' general, pero también después de armar los batches en el bucle 'For'. Al procesar el último item del bucle cx, tomará el ID del último cliente para el Tag).
reqManager.ExecuteBatch(BatchCommands, "pedido_completo_" & cx.GetString("PC_CLIENTE"))
End If
' Por buena práctica y para evitar fugas de memoria (memory leaks),
' cerramos siempre los cursores que abrimos hacia la base de datos local.
c.Close
cx.Close
End Sub
Sub enviaPedidoBatch0(filtro As String)
' Crear una lista para almacenar TODAS las operaciones de UN pedido
Dim BatchCommands As List
BatchCommands.Initialize
' DE PEDIDO_CLIENTE
Log($"enviaPedidoBatch(${filtro})"$)
Private condicion As String = ""
If filtro <> "Todos" Then condicion = "where PC_ENVIADO = 0"
Private cx As Cursor = Starter.skmt.ExecQuery($"SELECT PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT, PC_COSTO_SIN, PC_RUTA, PC_ALMACEN, PC_ENVIADO FROM PEDIDO_CLIENTE ${condicion}"$)
Log($"SELECT PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT, PC_COSTO_SIN, PC_RUTA, PC_ALMACEN, PC_ENVIADO FROM PEDIDO_CLIENTE ${condicion}"$)
Log("pedido_cliente: " & cx.RowCount)
' DE PEDIDO
Private condicion As String = ""
If filtro <> "Todos" Then condicion = "where PE_ENVIADO = 0"
c = Starter.skmt.ExecQuery2("SELECT COUNT(*) as CANTIDAD FROM HIST_ENVIOS WHERE HE_TIPO = ?",Array As String("ABORDO") )
c.Position = 0
If c.GetString("CANTIDAD") > 0 Then
Log($"pe_cedis_0"$)
Starter.skmt.ExecNonQuery2("update PEDIDO set PE_CEDIS = ? where PE_CLIENTE =? AND PE_FOLIO IS NULL ", Array As Object("RECARGA", "0"))
End If
Starter.skmt.ExecNonQuery("UPDATE PEDIDO SET PE_FOLIO = rowid where PE_FOLIO = 0 or PE_FOLIO = 1")
If cx.RowCount > 0 Then ' Si hay pedido entonces lo enviamos.
For j = 0 To cx.RowCount - 1
Log("===== ENVIAMOS PRODUCTOS DE PEDIDO =====")
cx.Position = j
Dim Arch As String = Subs.traeAlmacen & "_" & Subs.traeRuta & "_" & cx.GetString("PC_CLIENTE") & "_" & DateTime.Now
' 1. Agregar comando del Encabezado (PEDIDO_CLIENTE)
Dim cmdHeader As DBCommand
cmdHeader.Initialize
cmdHeader.Name = "insert_pedidos_KELL_arch"
cmdHeader.Parameters = Array As Object(cx.GetString("PC_CLIENTE"),cx.GetString("PC_FECHA"),cx.GetString("PC_USER"),cx.GetString("PC_NOART"),cx.GetString("PC_MONTO"),cx.GetString("PC_LON"),cx.GetString("PC_LAT"),ALMACEN,l_ruta.text,cx.GetString("PC_COSTO_SIN"), Arch)
BatchCommands.Add(cmdHeader)
' 2. Agregar comandos del Detalle (PEDIDO) dentro del bucle
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 ${condicion} ${(IIf(condicion = "","where", "and"))} pe_cliente = '${cx.GetString("PC_CLIENTE")}' "$)
' Log($"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 ${condicion} ${(IIf(condicion = "","where ", "and"))} pe_cliente = '${cx.GetString("PC_CLIENTE")}' "$)
If cPed.RowCount > 0 Then
For i = 0 To cPed.RowCount - 1
Log("==== ENVIAMOS PRODS ====")
cPed.Position = i
Dim cmdDetail As DBCommand
cmdDetail.Initialize
If PERFIL = "V-ESPECIAL" Then
Log("===== V-ESPECIAL =====")
cmd.Name = "insert_pedido_esp_KELL"
cmd.Parameters = Array As Object(cPed.GetString("PE_CEDIS"),ALMACEN,cPed.GetString("PE_COSTO_TOT"),cPed.GetString("PE_COSTOU"),cPed.GetString("PE_CANT"),cPed.GetString("PE_PRONOMBRE"),cPed.GetString("PE_PROID"),cPed.GetString("PE_CLIENTE"),cPed.GetString("PE_FECHA"),cPed.GetString("PE_USUARIO"),cPed.GetString("PE_RUTA"),cPed.GetString("PE_COSTO_SIN"),cPed.GetString("PE_DESC"),cPed.GetString("PE_FOLIO"),cPed.GetString("PE_TIPO"),NUMERO_PEDIDO)
Else
cmdDetail.Name = "insert_pedido_KELL_arch"
cmdDetail.Parameters = Array As Object (cPed.GetString("PE_CEDIS"),ALMACEN,cPed.GetString("PE_COSTO_TOT"),cPed.GetString("PE_COSTOU"),cPed.GetString("PE_CANT"),cPed.GetString("PE_PRONOMBRE"),cPed.GetString("PE_PROID"),cPed.GetString("PE_CLIENTE"),cPed.GetString("PE_FECHA"),cPed.GetString("PE_USUARIO"),cPed.GetString("PE_RUTA"), cPed.GetString("PE_COSTO_SIN"),cPed.GetString("PE_DESC"),cPed.GetString("PE_FOLIO"), cPed.GetString("PE_TIPO"), Arch)
End If
BatchCommands.Add(cmdDetail)
Next
End If
Next
' 3. Enviar TODO junto en una sola petición HTTP
' Si esto falla, no se guarda nada en Oracle y el pedido sigue pendiente en local.
reqManager.ExecuteBatch(BatchCommands, "pedido_completo_" & cx.GetString("PC_CLIENTE"))
End If
c.Close
cx.Close
End Sub
'Envio de la tabla pedido
Sub enviaPedido(filtro As String)
Log($"enviaPedido(${filtro})"$)
@@ -3416,11 +3714,11 @@ Sub enviaPedido(filtro As String)
Starter.skmt.ExecNonQuery2("update PEDIDO set PE_CEDIS = ? where PE_CLIENTE =? AND PE_FOLIO IS NULL ", Array As Object("RECARGA", "0"))
End If
Starter.skmt.ExecNonQuery("UPDATE PEDIDO SET PE_FOLIO = rowid where PE_FOLIO = 0 or PE_FOLIO = 1")
Log("####################################################")
Log(PERFIL)
Log("####################################################")
If PERFIL = "V-ESPECIAL" Then
Log($"pe_cedis_1"$)
c = 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 FROM PEDIDO ${condicion} ORDER BY PE_CLIENTE"$)
@@ -3441,7 +3739,7 @@ Sub enviaPedido(filtro As String)
Else
' Log($"pe_cedis_3"$)
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 FROM PEDIDO ${condicion}"$)
Log($"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 FROM PEDIDO ${condicion}"$)
' Log($"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 FROM PEDIDO ${condicion}"$)
' TIEMPO = 0
S_CP.Text = "Envio de Pedidos"
PB2.Progress = 1
@@ -3896,6 +4194,7 @@ Sub IsConnectedToInternet As Boolean 'ignore
End Sub
Private Sub b_motivoNoVisita_Click
B4XPages.MainPage.aud.guarda("Entrada a motivoNoVisita")
r_1.Checked = True
r_razonNoVisita = "FALLA MECANICA"
If Not(kh.motivoNoVisitaActivo) Then
@@ -3921,6 +4220,7 @@ Private Sub b_noVisita_Click
Msgbox2Async("Si se envia la información, ya NO se va a poder continuar con la ruta, los clientes por visitar se van a bloquear.", "AVISO", "Continuar", "Cancelar", "", LoadBitmap(File.DirAssets,"alert2.png"), False)
Wait For Msgbox_Result (result As Int)
If result = DialogResponse.POSITIVE Then
B4XPages.MainPage.aud.guarda($"Se envió MotivoNoVisita: "${r_razonNoVisita}""$)
ToastMessageShow("CONTINUAR", False)
Starter.skmt.ExecNonQuery($"delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'NOVISITA_ACTIVA'"$)
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("NOVISITA_ACTIVA", 1))
@@ -3942,10 +4242,17 @@ Private Sub b_noVisita_Click
Do While mnv.NextRow
Subs.bitacora(Subs.fechanormal(DateTime.Now), usuario, alm, rut, "NO VISITADO", mnv.GetString("CAT_CL_CODIGO"), fech, fech, Starter.lat_gps, Starter.lon_gps, 2, "", r_razonNoVisita)
Log($"NO VISITADO - ${mnv.GetString("CAT_CL_CODIGO")}"$)
DateTime.DateFormat = "yyyy-MM-dd HH:mm:ss"
' Actualizamos HIST_NOTIFICACIONES con la hora y el motivo.
cmd.Initialize
cmd.Name = "updateHistNotificacionesMotivo"
' ("", DateTime.Date(DateTime.Now), Subs.traeRuta, usuario, Subs.traeAlmacen, clienteId)
cmd.Parameters = Array As Object(r_razonNoVisita, DateTime.Date(DateTime.Now), Subs.traeRuta, usuario, ALMACEN, mnv.GetString("CAT_CL_CODIGO"))
reqManager.ExecuteCommand(cmd , "insertHistNotificaciones")
Loop
' b_motivoNoVisita.Color = Colors.RGB(247, 94, 0)
Private cd1 As ColorDrawable
cd1.Initialize(Colors.RGB(247, 94, 0), 5dip)

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
@@ -170,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")
@@ -243,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
@@ -289,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
@@ -345,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"
@@ -495,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
@@ -661,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}"$)
@@ -717,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.
@@ -844,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)
@@ -1116,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
@@ -1144,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
@@ -1160,6 +1209,7 @@ Private Sub lv_promos_ItemLongClick (Position As Int, Value As Object)
End If
l_info.Text = $"ID: ${id}${CRLF}${Value}"$
l_info.Visible = True
c.Close
End Sub
Private Sub b_buscar_Click
@@ -1240,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
@@ -1337,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)
@@ -1409,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
@@ -1441,8 +1494,8 @@ Private Sub clv_prods_ll_VisibleRangeChanged (FirstIndex As Int, LastIndex As In
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)
' 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
'#######################################################
@@ -1557,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
@@ -74,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
@@ -88,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)
@@ -99,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)
@@ -494,7 +564,7 @@ Private Sub b_terminar1_Click
' ' Asumimos que el índice 0 es el encabezado de la promoción (estaPromo) y no tiene bonificación de producto.
If t > 0 Then
Private bonificacion_monto As String = ts.traeMontoBonificacion(idProdFijo, prodsPrecio, estaPromo)
Private bonificacion_monto As String = ts.traeMontoBonificacion(idProdFijo, prodsPrecio, estaPromo, "b_terminar1_Click")
Log(bonificacion_monto)
Log("elMontoTSDeLaVenta=" & elMontoTSDeLaVenta)
Log($"${elMontoTSDeLaVenta} + (${bonificacion_monto} * ${cantProdFijo})"$)
@@ -508,8 +578,8 @@ Private Sub b_terminar1_Click
Private pn As String = Subs.traeProdNombre(prodsIds2.Get(t))
Subs.guardaProductoSinGestion(estaPromo, prodsPrecios2.Get(t), prodsCants2.Get(t), pn, prodsIds2.Get(t), Subs.traeCliente, Subs.traeFecha, Subs.traeUsuarioDeBD, Subs.traeRuta, 0, Starter.tipov)
' Traemos el monto de las bonificacionos a guardar. -- Trade Spending
Log("Monto Bonificacion -->> " & ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo))
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo) * prodsCants2.Get(t))
Log("Monto Bonificacion -->> " & ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo, "LOG_b_terminar1_Click2"))
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo, "b_terminar1_Click3") * prodsCants2.Get(t))
Log("Acumulado: " & elMontoTSDeLaVenta)
Next
ts.modTrendSpending("RESTA", "BONIFICACIONES", elMontoTSDeLaVenta)
@@ -536,7 +606,7 @@ Private Sub b_continuar_Click
' ' Asumimos que el índice 0 es el encabezado de la promoción (estaPromo) y no tiene bonificación de producto.
If t > 0 Then
Private bonificacion_monto As String = ts.traeMontoBonificacion(idProdFijo, prodsPrecio, estaPromo)
Private bonificacion_monto As String = ts.traeMontoBonificacion(idProdFijo, prodsPrecio, estaPromo, "b_continuar_Click")
Log(bonificacion_monto)
Log("elMontoTSDeLaVenta=" & elMontoTSDeLaVenta)
Log($"${elMontoTSDeLaVenta} + (${bonificacion_monto} * ${cantProdFijo})"$)
@@ -550,8 +620,8 @@ Private Sub b_continuar_Click
Private pn As String = Subs.traeProdNombre(prodsIds2.Get(t))
Subs.guardaProductoSinGestion(estaPromo, prodsPrecios2.Get(t), prodsCants2.Get(t), pn, prodsIds2.Get(t), Subs.traeCliente, Subs.traeFecha, Subs.traeUsuarioDeBD, Subs.traeRuta, 0, Starter.tipov)
' Traemos el monto de las bonificacionos a guardar. -- Trade Spending
Log("Monto Bonificacion -->> " & ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo))
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo) * prodsCants2.Get(t))
Log("Monto Bonificacion -->> " & ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo, "LOG_b_continuar_Click2"))
elMontoTSDeLaVenta = elMontoTSDeLaVenta + (ts.traeMontoBonificacion(prodsIds2.Get(t), prodsPrecios2.Get(t), estaPromo, "b_continuar_Click3") * prodsCants2.Get(t))
Log("Acumulado: " & elMontoTSDeLaVenta)
Next
ts.modTrendSpending("RESTA", "BONIFICACIONES", elMontoTSDeLaVenta)

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,9 +91,10 @@ Sub Activity_KeyPress (key As Int) As Boolean
End Sub
Sub ListView1_ItemLongClick (Position As Int, Value As Object)
Log(value)
Log(Value)
Starter.skmt.ExecNonQuery("delete from CUENTAA")
Starter.skmt.ExecNonQuery2("INSERT INTO CUENTAA VALUES (?)", Array As Object(Value))
B4XPages.MainPage.aud.guarda($"Clic largo TicketsDia: ${Value}"$)
Subs.iniciaActividad("Cliente")
End Sub

462
B4A/C_TrendSpending.bas Normal file
View File

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

View File

@@ -63,6 +63,7 @@ Sub Class_Globals
' - KeyValueStore2
' - DBRequestManager
' - XUI
Dim dlDB As SQL
End Sub
' Inicializa la clase DeviceLinker.
@@ -77,6 +78,9 @@ 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.
@@ -145,17 +149,34 @@ Sub linkDevice(Almacen_ As String, Ruta_ As String)
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
@@ -207,6 +228,7 @@ 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
@@ -275,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.

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,10,11,12,13,14,15,16,18,19,20,21,22,23,24,25,26,27,28,29,31,33,34,35,37,38,39,40,41,42,43,45,46,47
ModuleClosedNodes1=
ModuleClosedNodes10=
ModuleClosedNodes11=
ModuleClosedNodes12=
ModuleClosedNodes13=1,7,8,9,10,11,12
ModuleClosedNodes14=6,7,8,9,12,13
ModuleClosedNodes13=42
ModuleClosedNodes14=
ModuleClosedNodes15=
ModuleClosedNodes16=3,8,17
ModuleClosedNodes16=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,31,32,33,35
ModuleClosedNodes26=
ModuleClosedNodes27=
ModuleClosedNodes28=4
ModuleClosedNodes28=
ModuleClosedNodes29=
ModuleClosedNodes3=5,6
ModuleClosedNodes30=
ModuleClosedNodes3=
ModuleClosedNodes30=3
ModuleClosedNodes31=
ModuleClosedNodes32=101,116
ModuleClosedNodes32=
ModuleClosedNodes33=
ModuleClosedNodes4=
ModuleClosedNodes34=
ModuleClosedNodes4=1,128
ModuleClosedNodes5=
ModuleClosedNodes6=
ModuleClosedNodes7=
ModuleClosedNodes8=
ModuleClosedNodes9=
NavigationStack=Diseñador Visual,principal.bal,-100,6,C_Principal,SUBIR_INFO_PEDIDO,3371,6,C_Principal,B4XPage_Created,228,0,C_Principal,descargaCartaPorteyProgreso,3693,0,C_Principal,VALIDAR_INFO,3548,0,C_Principal,t1_tick,2536,0,C_Principal,cargar_Click,690,0,C_Principal,Subir_Click,679,6,C_Principal,actualizaProgressBar,2250,1,C_Principal,JobDone,2232,6
NavigationStack=B4XMainPage,ImageView1_LongClick,1073,0,C_Productos,lv_catalogos_ItemClick,357,0,C_Principal,Subir_Click,688,0,C_Principal,enviaPedidoBatch,3520,0,C_Principal,SUBIR_INFO_PEDIDO,3516,0,C_Productos,Class_Globals,32,0,C_Productos,b_prodMas_Click,845,0,Subs,actualizaProducto,966,2,Subs,guardaProducto,896,0,Subs,traeInvDeBD,893,0,Subs,traeUsuarioDeBD,881,0
SelectedBuild=0
VisibleModules=31,1,12,5,16,3,32,13,14,9
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

@@ -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"

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
@@ -974,7 +975,7 @@ Sub actualizaProducto(cedis As String, costoU As String, cant As String, nombre
Private antCant As Int = 0
If IsNumber(c.GetInt("PE_CANT")) Then antCant=c.GetInt("PE_CANT")
Private difCant As Int = cant - antCant
Starter.skmt.ExecNonQuery($"update pedido set pe_cant = ${cant}, pe_costou = ${costoU}, pe_costo_tot = ${NumberFormat2((cant*c.GetString("PE_COSTOU")), 1, 2, 2, False)}, pe_tipo = '${tipoVenta}' where pe_cedis = '${cedis}' and pe_proid = '${prodId}' and pe_cliente = '${clienteId}' "$)
Starter.skmt.ExecNonQuery($"update pedido set pe_cant = ${cant}, pe_costou = ${costoU}, pe_costo_tot = ${NumberFormat2((cant*c.GetString("PE_COSTOU")), 1, 2, 2, False)}, pe_tipo = '${tipoVenta}', pe_enviado = 0 where pe_cedis = '${cedis}' and pe_proid = '${prodId}' and pe_cliente = '${clienteId}' "$)
If cedis <> "DUR" Then Starter.skmt.ExecNonQuery($"update ${traeTablaProds(tipoVenta)} set cat_gp_almacen = cat_gp_almacen - (${difCant}) where cat_gp_id = '${prodId}' "$)
If cant = 0 Then
LogColor($"BORRAMOS PRODUCTO - ${prodId}"$, Colors.Red)
@@ -1008,7 +1009,7 @@ 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 = True
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 el maximo de promociones a otorgar.
@@ -1029,7 +1030,7 @@ Sub traePromo(promo As String, cliente As String) As Map
'######### 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}'
Log($"select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}'"$)
' Log($"select * from HIST_CLIENTE_CANT_PROMOS where HCCP_PROMO = '${promo}'"$)
If thisLog Then Log($"PROMOS SEGMENTADAS ENCONTRADAS: ${ps.RowCount}"$)
If thisLog Then Log(promoMap)
If ps.RowCount > 0 Then
@@ -1045,13 +1046,16 @@ Sub traePromo(promo As String, cliente As String) As Map
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
@@ -1090,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
@@ -1109,7 +1114,7 @@ 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 = True
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
@@ -1129,6 +1134,7 @@ Sub traemosInventarioDisponibleParaPromo(promo As String) As Map 'ignore
Next
' prodInv.Put("inventarios", prods)
End If
c.Close
Return prods
End Sub
@@ -1147,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.
@@ -1198,7 +1204,7 @@ End Sub
'Regresa el numero máximo de promociones permitidas, tomando en cuenta recurrentes, clientes y maxPromos.
Sub traeMaxPromos(pm As Map) As Int
Private thisLog As Boolean = true 'Si es verdadero, muestra los logs de este sub.
Private thisLog As Boolean = True 'Si es verdadero, muestra los logs de este sub.
Private maxPromos As List
Private mp0, mp As String = "0"
maxPromos.Initialize
@@ -1213,7 +1219,7 @@ Sub traeMaxPromos(pm As Map) As Int
' If thisLog Then LogColor("==== Historico: "&pm.Get("historico"), Colors.Red)
' Log("### PRODS VARIABLES: " & pm.Get("prodsVariables"))
Private maxPromosXDescPV As String = B4XPages.MainPage.promos.ts.maxPromosPorProdsVariables(pm.Get("prodsVariables"), pm.Get("id"))
' Log("########### " & maxPromosXDescPV)
Logcolor("########### maxPromosXDescPV " & maxPromosXDescPV, Colors.Yellow)
' If thisLog Then Log(pm)
maxPromos.Add(maxPromosXDescPV.As(Int))
If pm.Get("historico") = "1" Then maxPromos.Add(pm.Get("maxRecurrente")) 'Si hay historico, agregamos maxRecurrente
@@ -1224,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
@@ -1244,6 +1251,7 @@ 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
@@ -1251,9 +1259,9 @@ 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 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)
@@ -1263,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)
@@ -1279,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)
@@ -1296,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
@@ -1344,45 +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($"### T: ${t}"$, Colors.Green)
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)}"$)
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($" 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. (promos por inventario)
If thisLog Then LogColor($"### T: ${t}"$, Colors.Green) 'promos por inventario
If thisLog Then Log(">> Promos x Prods Fijos: " & x(0))
Log(">>>>> Monto Bonificacion: " & 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)
' If thisLog Then LogColor($" ### T: ${t}"$, Colors.Green) 'promos por inventario
If thisLog Then LogColor($" >>>>> PROMOS X PRODS FIJOS (${idProdsFijos.Get(p)}): ${x(0)} <<<<<"$, Colors.red)
Log($" >>>>> Monto Bonificacion FIJOS (${idProdsFijos.Get(p)}): "$ & B4XPages.MainPage.promos.ts.traeMontoBonificacion(idProdsFijos.Get(p), idProdsFijosPrecios.Get(p), pm.Get("id"),"LOG_revisaMaxPromosProdsFijosPorInventario"))
If thisLog Then LogColor(" >> MAX PRODS FIJOS X BONIFICACIONES: " & B4XPages.MainPage.promos.ts.traeBonificacionesMaximas("bonificaciones", clienteActual, idProdsFijos.Get(p), prodsFijosPiezas.Get(p), idProdsFijosPrecios.Get(p), pm.Get("id")), Colors.blue)
t.Add(B4XPages.MainPage.promos.ts.traeBonificacionesMaximas("bonificaciones", clienteActual, idProdsFijos.Get(p), prodsFijosPiezas.Get(p), idProdsFijosPrecios.Get(p), pm.Get("id"))) 'Agregamos las promos disponibles por Trade Spending
If thisLog Then LogColor($"### T: ${t}"$, Colors.Green)
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)
If thisLog Then 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
@@ -1436,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("=====================================================")
@@ -1459,7 +1475,7 @@ Sub revisaMaxPromosProdsVariablesPorInventario(pm As Map) As Int 'ignore
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)
@@ -1501,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
@@ -1577,7 +1594,7 @@ 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_COSTOU"), 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"),"borraPedidoClienteActual")
desc = desc * thisC.GetString("PE_CANT")
Log("Regresamos bonificaciones " & thisC.GetString("PE_PROID") & "=" & desc)
modTrendSpending("suma", "bonificaciones", desc)
@@ -2048,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
@@ -2197,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
@@ -2415,7 +2432,7 @@ Sub traeExistenciasPorId(id As String) As Int
existencias = inv.GetString("CAT_GP_ALMACEN").As(Int)
End If
' Log("ex:" & existencias)
Private inv As Cursor = Starter.skmt.ExecQuery($"Select ifnull(SUM(pe_cant),0) As total_vendido FROM pedido WHERE pe_tipo = 'VENTA' and pe_proid = '${id}'"$)
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)
@@ -2461,4 +2478,74 @@ Sub deshabilitaValidaciones
' 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

@@ -101,6 +101,8 @@ Sub RD_Init
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"

View File

@@ -87,6 +87,7 @@ Sub traeInfoTrendSpending As Map
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
@@ -124,7 +125,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 = 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
@@ -335,7 +336,7 @@ 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 = False
Private thisLog As Boolean = True
Private tsMaximas As Int = 100000000
Private tsRestantes As String = 0
Private tsMonto As String
@@ -345,22 +346,26 @@ Sub traeBonificacionesMaximas(tipo As String, clienteId As String, id As String,
TS_DESCUENTOS = Regex.Split(",", mx.Get("DESCUENTOS"))
TS_BONIFICACIONES = Regex.Split(",", mx.Get("BONIFICACIONES"))
If thisLog Then LogColor($"Presupuesto: ${TS_BONIFICACIONES(0)} - Acumulado ayer: ${TS_BONIFICACIONES(1)} - Hoy: ${traeAcumuladoHoyTS("bonificaciones")}"$, Colors.Red)
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("TS_BONIFICACIONES(0) - TS_BONIFICACIONES(1) - traeAcumuladoHoyTS('bonificaciones')")
Log($"${TS_BONIFICACIONES(0)} - ${TS_BONIFICACIONES(1)} - ${traeAcumuladoHoyTS("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))}"$)
If thisLog Then 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
If thisLog Then 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
@@ -369,13 +374,14 @@ End Sub
' - 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
LogColor($">>>>>>> ${promoId}, ${precio}, ${id}"$, Colors.Magenta)
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}'"$)
Log($"rowcount: ${c.RowCount}"$)
' 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
@@ -384,10 +390,11 @@ Sub traeMontoBonificacion(id As String, precio As String, promoId As String) As
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}"$)
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
@@ -399,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)