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
	Dim ruta As String
	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 lv_catalogos As ListView
	Dim lv_promos As ListView
	Dim entro As String
	Dim gest As Button
	Dim lfila As Label
	Dim marca As String
	Dim tipo As String
	Dim subtipo As String
	Private BUSCA As EditText
	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
	Private p_productos As Panel
	Dim clv_productos As CustomListView
	Private ImageView1 As ImageView
	Private Panel3 As Panel
	Private p_prods As Panel
	Private i_prod As ImageView
	Private l_prodX As Label
	Private b_prodMas As Button
	Private l_pCant As Label
	Private et_pCant As EditText
	Private b_prodMenos As Button
	Dim b_terminar1 As Button
	Dim b_continuar As Button
	Private l_total As Label
	Private l_totProds As Label
	Dim totalProds As Int = 0
	Dim totalCompra As Float = 0
	Dim etCantHasFocus As Boolean = False
	Dim prodsMap As Map
	Private l_Cargando As Label
	Private l_info As Label
	Private b_buscar As Button
	Private p_botonesVenta As Panel
	Private lv_tipo As ListView
	Private lv_subtipo As ListView
	Private p_vistaPreviaTrans As Panel
	Private lv_prodsPedido As ListView
	Private b_rechazar As Button
	Private b_aceptar As Button
	Private p_vistaPrevia As Panel
	Dim folio As String
	Dim result As String
	Private l_cant As Label
	Private l_total2 As Label
	Dim prodsPedidoActual As String
	Dim montoPedidoActual As String
	Dim clv_prods_ll As CustomListView
	Private PCLV As PreoptimizedCLV
	Dim listaProds As List
	' Type AirportData (Name As String, AirportID As Int, IATA As String, ICAO As String, City As String, Latitude As Float, Longitude As Float, Altitude As String)
	Dim pedidoMap As Map
	Private p_botMasMen As Panel
	Dim reiniciarlistaProds As Boolean= False
	' Dim listaRenglones As List
	Dim listaTiempos As List
	Dim clienteId As String
	Dim rutaUsuario As String
	Dim hayPedido As Boolean
	Dim listaHints As List
	Dim r As Cursor
	Dim vamoaver As List
	Dim j3 As Cursor
	Dim invTotal As Int
	Private et_pCantc As EditText
	Private b_prodMenosc As Button
	Private b_prodMasc As Button
	Dim totalcajasmaspiezas As Int
	Dim cajas As Int
	Dim piezas As Int
	Private p_botMasMenc As Panel
	
	' Este valor debe venir de la configuración del cliente que seleccionaste
	Dim tipoClienteActual As String = "DETALLE"
	Dim cantsMap As Map
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
	' Activity.RemoveAllViews
	Root.LoadLayout("productos")
	ruta = File.DirInternal
	If File.Exists(ruta, "kmt.db") = False Then
		File.Copy(File.DirAssets, "kmt.db", ruta, "kmt.db")
	End If
	PCLV.Initialize(Me, "PCLV", clv_prods_ll)
	ciclo = 1
	l_info.Width = Root.Width * 0.8
	l_info.Left = (Root.Width/2) - (l_info.Width/2)
	c = B4XPages.MainPage.skmt.ExecQuery("select distinct CAT_GP_TIPO from cat_gunaprod where CAT_GP_TIPO <> 'PROMOS' order by CAT_GP_TIPO")
	If c.RowCount > 0 Then
		Dim label1 As Label
		label1 = lv_tipo.SingleLineLayout.Label
		label1.TextSize = 17
		label1.TextColor = Colors.Black
		lv_tipo.Clear
		For i=0 To c.RowCount-1
			c.Position=i
			Log("ENTRE AQUI EN PROMOS create")
			lv_tipo.AddSingleLine(c.GetString("CAT_GP_TIPO"))
		Next
	End If
	c.Close
	' llenaCatalogo(False)
	' listaRenglones.Initialize
	listaTiempos.Initialize
	listaProds.Initialize
	pedidoMap.Initialize
	listaHints.Initialize
	' Log("Llamamos LlenaProdsLL")
	' LlenaProdsLL(Null)
	clv_prods_ll.Clear
	prodsMap.Initialize
End Sub

'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.

Sub B4XPage_Appear
	Log(Subs.traeTipoCliente2)
	tipoClienteActual = Subs.traeTipoCliente2
	Log(B4XPages.MainPage.tipo_venta)
	If B4XPages.MainPage.tipo_venta = "PREVENTA_CONTADO" Or B4XPages.MainPage.tipo_venta = "ABORDO" Then
		Starter.tabla = "CAT_GUNAPROD"
		Log("1")
	Else If B4XPages.MainPage.tipo_venta = "VENTA" Then
		Starter.tabla = "CAT_GUNAPROD2"
		Log(2)
	Else If B4XPages.MainPage.tipo_venta = "RECARGA" Then
		Starter.tabla = "CAT_GUNAPROD"
		Log(3)
	Else If B4XPages.MainPage.tipo_venta = "PREVENTA_CREDITO" Then
		Starter.tabla = "CAT_GUNAPROD4"
		Log(4)
	End If
	Log(Starter.tabla)
	clienteId = Subs.traeCliente
	rutaUsuario = Subs.traeRuta(Subs.traeCliente)
	B4XPages.MainPage.skmt.ExecNonQuery2("UPDATE CAT_GUNAPROD SET CAT_GP_TIPOPROD = (?) WHERE CAT_GP_TIPOPROD = (?) ",Array As Object("PRIORITARIO","1"))
	B4XPages.MainPage.skmt.ExecNonQuery2("UPDATE CAT_GUNAPROD SET CAT_GP_TIPOPROD = (?) WHERE CAT_GP_TIPOPROD = (?) ",Array As Object("ESTRATEGICO","2"))
	B4XPages.MainPage.skmt.ExecNonQuery2("UPDATE CAT_GUNAPROD SET CAT_GP_TIPOPROD = (?) WHERE CAT_GP_TIPOPROD = (?) ",Array As Object("COMPLEMENTARIO","3"))
	B4XPages.MainPage.skmt.ExecNonQuery2("UPDATE CAT_GUNAPROD SET CAT_GP_TIPOPROD = (?) WHERE CAT_GP_TIPOPROD = (?) ",Array As Object("CATALOGO REGULAR","0"))
	B4XPages.MainPage.skmt.ExecNonQuery2("UPDATE CAT_GUNAPROD SET CAT_GP_TIPOPROD = (?) WHERE CAT_GP_CLASIF = (?) ",Array As Object("PROMOS","PROMOS"))
	clv_prods_ll.GetBase.SetLayoutAnimated(0, 5dip, 130dip, Root.Width + 10, Root.Height * 0.74) 'Cambiamos el tamaño y posición de la lista de productos
	clv_prods_ll.Base_Resize(clv_prods_ll.GetBase.Width, clv_prods_ll.GetBase.Height) 'Cambiamos el tamaño del panel interno de la lista para que ajuste al nuevo tamaño.
	If B4XPages.MainPage.bTerminarClicked Then
		lv_catalogos.Visible = True
		lv_promos.Visible = False
		lv_tipo.Visible = False
		lv_subtipo.Visible = False
		clv_prods_ll.AsView.Visible = False
		B4XPages.MainPage.bTerminarClicked = False
	End If
	If ya_entro <> "1" Then
		If BUSCA.Text <> "" Then BUSCA.Text =""
		entro ="3"
		lv_catalogos.Clear
		Sleep(100)
		lfila.Text = "CATALOGOS"
		p_productos.Height = Root.Height
		clv_prods_ll.AsView.Visible = False
		lv_catalogos.Visible = True
		p_botonesVenta.Visible = False
		p_botonesVenta.Top = clv_prods_ll.AsView.top + clv_prods_ll.AsView.Height - 10
		lv_promos.Visible = False
	End If
	Dim label1 As Label
	label1 = lv_catalogos.SingleLineLayout.Label
	label1.TextSize = 17
	label1.TextColor = Colors.Black
	lv_catalogos.Clear
	lv_catalogos.AddSingleLine("CATALOGO")
	' c = B4XPages.MainPage.skmt.ExecQuery($"select count(*) as hayPromos from ${Starter.tabla} where CAT_GP_TIPOPROD = 'PROMOS'"$)
	c = B4XPages.MainPage.skmt.ExecQuery($"select count(*) as hayPromos from ${Starter.tabla} where CAT_GP_TIPO = 'PROMOS'"$)
	c.Position = 0
	c = B4XPages.MainPage.skmt.ExecQuery($"SELECT CUENTA FROM CUENTAA"$)
	c.Position = 0
	If c.GetString("CUENTA") <> "0" And c.GetString("CUENTA") <> "1" Then
		c2=B4XPages.MainPage.skmt.ExecQuery2($"select CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_PRECIO1, CAT_GP_ALMACEN, IFNULL(CAT_GP_IMG,0) AS CAT_GP_IMG from ${Starter.tabla} where CAT_GP_PRECIO1 > 0 AND  CAT_GP_ALMACEN > 0 AND CAT_GP_TIPO = ? AND CAT_GP_SUBTIPO = ?  AND CAT_GP_ID NOT IN (SELECT PE_PROID FROM PEDIDO WHERE PE_CLIENTE IN (Select cuenta from cuentaa))"$, Array As String("PROMOS", "PROMOS"))
'		LogColor($"select CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_PRECIO, CAT_GP_ALMACEN, IFNULL(CAT_GP_IMG,0) AS CAT_GP_IMG from ${Starter.tabla} where CAT_GP_PRECIO > 0 AND  CAT_GP_ALMACEN > 0 AND CAT_GP_TIPO = ? AND CAT_GP_SUBTIPO = ?  AND CAT_GP_ID NOT IN (SELECT PE_PROID FROM PEDIDO WHERE PE_CLIENTE IN (Select cuenta from cuentaa))"$,Colors.Cyan) 'Isaac
		' Log($"res:${c2.RowCount}, ${Value}, ${marca}, ${tipo}"$)
		Private hayPromos As Boolean = False
		If c2.RowCount > 0 Then
			Log("Esto es un conteo --->"&c2.RowCount) 'Isaac
			For i = 0 To c2.RowCount - 1
				c2.Position = i
				Log("Esto es i----->" & i) 'Isaac
				Private tm As Map = Subs.procesaPromocion(c2.GetString("CAT_GP_ID"), clienteId)
    
				' Verificar si tm es null antes de acceder a sus valores
				If tm <> Null Then
					If tm.Get("status") = "ok" Then 'Solo muestrala si hay producto.
						hayPromos = True
					End If
				Else
					Log("El Map devuelto por procesaPromocion es null")
				End If
			Next
			If hayPromos Then lv_catalogos.AddSingleLine("PROMOS")
		Else
			Log("NO HAY PROMOS")
		End If
		c2.Close
	End If
	Sleep(100)
	l_total.Visible = False
	l_totProds.Visible = False
	l_total.Left = 5dip
	l_totProds.Width = Root.Width * 0.19
	l_total.Left = l_totProds.Width + 20
	l_total.Width = Root.Width * 0.25
	' Log(Subs.traeTotalesClienteActual)
	Dim m As Map = Subs.traeTotalesClienteActual
	prodsPedidoActual = m.Get("productos")
	montoPedidoActual = m.Get("monto")
	hayPedido = Subs.hayPedido
	' LogColor("Pedido ant? - "&hayPedido, Colors.Magenta)
	B4XPages.MainPage.productos.clv_prods_ll.Clear
	If reiniciarlistaProds Then
		' Log("Llamamos LlenaProdsLL")
		' LlenaProdsLL(Null)
		clv_prods_ll.Clear
	else If hayPedido Then
		' LogColor("HAY PEDIDO ANTERIOR", Colors.red)
		' Log("Llamamos LlenaProdsLL")
		' LlenaProdsLL(Null)
		clv_prods_ll.Clear
	End If
	If clv_prods_ll.Size = 0 Then LlenaProdsLL(Null)
	clv_prods_ll.JumpToItem(0) 'Vamos al primer artículo de la lista.
	PCLV.lblHint.SetTextSizeAnimated(0,13)
	PCLV.B4XSeekBar1.Color1=Colors.Transparent
	PCLV.B4XSeekBar1.Color2=Colors.Transparent
	PCLV.B4XSeekBar1.ThumbColor=Colors.Transparent
	PCLV.B4XSeekBar1.mBase.Left=Root.Width *110
	' PCLV.B4XSeekBar1.mBase.Top=-50
	PCLV.B4XSeekBar1.mBase.Height=0
	PCLV.pnlOverlay.Height = clv_prods_ll.AsView.Height
	PCLV.B4XSeekBar1.Update
End Sub

Sub PCLV_AddProds

End Sub

Sub lv_catalogos_ItemClick (Position As Int, Value As Object)
	If Value = "CATALOGO" Then
'		' lfila.text = "TIPO"
'		lfila.text = "PRODUCTOS"
'		lv_catalogos.Visible = False
'		' lv_tipo.Visible = True
'		If clv_prods_ll.Size = 0 Then LlenaProdsLL(Null)
'		clv_prods_ll.AsView.Visible = True
'		If hayPedido Then p_botonesVenta.Visible = True 'Si ya hay pedido, entonces mostramos los botones.


	
		lv_catalogos.Visible = False
		lfila.text = "PRODUCTOS"
        
		' 1. Cargamos datos
		LlenaProdsLL(Null)
        
		' 2. Mostramos y traemos al frente
		clv_prods_ll.AsView.Visible = True
		clv_prods_ll.AsView.BringToFront
	
	Else
		clv_prods_ll.AsView.Visible = False
		lv_promos.Visible = True
		lfila.text = "PROMOCIONES"
		lv_catalogos.Visible = False
		lv_promos.Clear
		Dim label1 As Label
		label1 = lv_promos.TwoLinesLayout.Label
		label1.TextSize = 12
		label1.TextColor = Colors.Black
		Dim label2 As Label
		label2 = lv_promos.TwoLinesLayout.SecondLabel
		label2.TextSize = 12
		label2.TextColor = Colors.Black
		Dim label13 As Label
		label13 = lv_promos.TwoLinesAndBitmap.Label
		label13.TextSize = 12
		label13.TextColor = Colors.Black
		Dim label14 As Label
		label14 = lv_promos.TwoLinesAndBitmap.SecondLabel
		label14.TextSize = 12
		label14.TextColor = Colors.Black
		lfila.text = "PROMOS"
		' c2=B4XPages.MainPage.skmt.ExecQuery2($"select  CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_PRECIO, CAT_GP_ALMACEN, CAT_GP_IMG from ${Starter.tabla} where CAT_GP_PRECIO > 0 AND  CAT_GP_ALMACEN > 0 and CAT_GP_TIPOPROD = ? AND CAT_GP_TIPO = ? AND CAT_GP_SUBTIPO = ?  AND CAT_GP_ID NOT IN (SELECT PE_PROID FROM PEDIDO WHERE PE_CLIENTE IN (Select cuenta from cuentaa) )"$, Array As String(Value, Value, Value))
		c2=B4XPages.MainPage.skmt.ExecQuery2($"select  CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_PRECIO1, CAT_GP_ALMACEN, CAT_GP_IMG from ${Starter.tabla} where CAT_GP_PRECIO1 > 0 AND  CAT_GP_ALMACEN > 0 AND CAT_GP_TIPO = ? AND CAT_GP_SUBTIPO = ?  AND CAT_GP_ID NOT IN (SELECT PE_PROID FROM PEDIDO WHERE PE_CLIENTE IN (Select cuenta from cuentaa) )"$, Array As String(Value, Value))
		' Log($"res:${c2.RowCount}, ${Value}, ${marca}, ${tipo}"$)
		If c2.RowCount > 0 Then
			For i = 0 To c2.RowCount - 1
				c2.Position = i
				Private tm As Map = Subs.procesaPromocion(c2.GetString("CAT_GP_ID"), clienteId)
    
				If tm <> Null Then
					If tm.Get("status") = "ok" Then
						lv_promos.AddTwoLines(c2.GetString("CAT_GP_NOMBRE"), "# " & c2.GetString("CAT_GP_ALMACEN") & " $ " & c2.GetString("CAT_GP_PRECIO1") & " F:" & tm.Get("mp").As(Map).Get("prodsFijosCant") & " V:" & tm.Get("mp").As(Map).Get("prodsVariablesCant"))
					End If
				Else
					Log("El Map devuelto por procesaPromocion es null para el producto: " & c2.GetString("CAT_GP_NOMBRE"))
				End If
			Next
		Else
			ToastMessageShow("No hay promociones disponibles.", False)
		End If
		c2.Close
		entro = "4"
	End If
End Sub

Sub lv_catalogos2_ItemClick (Position As Int, Value As Object)
	clv_prods_ll.AsView.Visible = False
	BUSCA.Text = ""
	Dim cliente As C_Cliente = B4XPages.GetPage("Cliente")
	Log($"value=${Value}"$)
	If Value = "PROMOS" And cliente.cuenta <> "N" Then
		entro = "3"
		marca = "PROMOS"
		tipo = "PROMOS"
	Else if Value = "PROMOS" And cliente.cuenta = "N"  Then
		entro = "5"
		B4XPages.ShowPage("Cliente")
	End If
	If Value = "PROMOS" Then
		LogColor("Promos", Colors.red)
		c2=B4XPages.MainPage.skmt.ExecQuery2($"select  CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_PRECIO1, CAT_GP_ALMACEN, CAT_GP_IMG from ${Starter.tabla} where CAT_GP_PRECIO1 > 0 AND  CAT_GP_ALMACEN > 0 and CAT_GP_TIPOPROD = ? AND CAT_GP_TIPO = ? AND CAT_GP_SUBTIPO = ?  AND CAT_GP_ID NOT IN (SELECT PE_PROID FROM PEDIDO WHERE PE_CLIENTE IN (Select cuenta from cuentaa) ) ORDER BY 1"$, Array As String(Value, marca, tipo))
	Else
		LogColor("Catalogo", Colors.red)
		c2=B4XPages.MainPage.skmt.ExecQuery($"select CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_PRECIO1, CAT_GP_ALMACEN, CAT_GP_IMG, CAT_GP_TIPOPROD, CAT_GP_INICIATIVA from ${Starter.tabla} where CAT_GP_PRECIO1 > 0 AND CAT_GP_ALMACEN > 0 and CAT_GP_TIPOPROD <> 'PROMOS' "$)
	End If
	If Value = "CATALOGO" Then
		lv_catalogos.Visible = False
		lv_promos.Visible = False
		lfila.text = "CATALOGO"
		Log("PGS")
		ProgressDialogShow("Cargando catalogo ...")
		Sleep(100)
		Private inicioContador As String = DateTime.Now
		llenaCatalogo(False)
		clv_prods_ll.AsView.Visible = True
		Log("PGH")
		LogColor("TIEMPO DE PROCESO DEL CATALOGO: " & ((DateTime.Now-inicioContador)/1000), Colors.Red)
		ProgressDialogHide
		c2.Close
	Else
		clv_prods_ll.AsView.Visible = False
		lv_promos.Visible = True
		lv_catalogos.Visible = False
		lv_promos.Clear
		Dim label1 As Label
		label1 = lv_promos.TwoLinesLayout.Label
		label1.TextSize = 15
		label1.TextColor = Colors.Black
		Dim label2 As Label
		label2 = lv_promos.TwoLinesLayout.SecondLabel
		label2.TextSize = 15
		label2.TextColor = Colors.Black
		Dim label13 As Label
		label13 = lv_promos.TwoLinesAndBitmap.Label
		label13.TextSize = 15
		label13.TextColor = Colors.Black
		Dim label14 As Label
		label14 = lv_promos.TwoLinesAndBitmap.SecondLabel
		label14.TextSize = 15
		label14.TextColor = Colors.Black
		lfila.text = "PROMOS"
		If c2.RowCount > 0 Then
			For i=0 To c2.RowCount -1
				c2.Position=i
				Private tm As Map = Subs.procesaPromocion(c2.GetString("CAT_GP_ID"), clienteId)
				If tm.Get("status") = "ok" Then 'Solo muestrala si hay producto.
					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
			Next
		End If
		c2.Close
	End If
	entro = "4"
End Sub

Sub lv_promos_ItemClick (Position As Int, Value As Object)
	clv_prods_ll.AsView.Visible = False
	Dim cliente As C_Cliente = B4XPages.GetPage("Cliente")
	' Log($"Entro=${entro}, value=${Value}, cuenta=${cliente.cuenta}"$)
	If Value = "PROMOS" And cliente.cuenta <> "N" Then
		entro = "3"
		marca = "PROMOS"
		tipo = "PROMOS"
	Else if Value = "PROMOS" And cliente.cuenta = "N"  Then
		entro = "5"
		B4XPages.ShowPage("Cliente")
	End If
	If entro = "3" Then
		'xxxxxxxxxxxxxxxxxxxxx
	Else If entro = "4" Then
		' Log("Entro = 4")
		B4XPages.MainPage.skmt.ExecNonQuery("delete from PROID")
		B4XPages.MainPage.skmt.ExecNonQuery2("INSERT INTO PROID VALUES (?)", Array As Object(Value))
		Dim promos As C_Promos = B4XPages.GetPage("Promos")
		promos.laPromo = Subs.traeProdIdDeBD.Get("id")
		promos.elCliente = Subs.traeUsuarioDeBD
		B4XPages.ShowPage("Promos")
	End If
End Sub

'Generamos la lista de productos.
Sub llenaCatalogo(subtipo1 As String)
	' Log("LlenaCatalogo")
	' Private c2 As Cursor
	' c2=B4XPages.MainPage.skmt.ExecQuery2("select CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_PRECIO, CAT_GP_ALMACEN, CAT_GP_IMG, CAT_GP_TIPOPROD, CAT_GP_INICIATIVA from cat_gunaprod where CAT_GP_PRECIO > 0 AND CAT_GP_ALMACEN > 0 and CAT_GP_TIPOPROD <> 'PROMOS'  and CAT_GP_SUBTIPO = ? ", Array As String(subtipo1))
	' Private bgColor, textColor As Int
	' If c2.RowCount > 0 And clv_productos.Size <> c2.RowCount Then
	' clv_productos.Clear : Log("limpiamos productos")
	' For i=0 To c2.RowCount -1
	' c2.Position=i
	' If c2.GetString("CAT_GP_TIPOPROD") = "PRIORITARIO" Then
	' bgColor = Colors.RGB(255, 212, 163) 'naranja
	' Else If c2.GetString("CAT_GP_TIPOPROD") = "COMPLEMENTARIO" Then
	' bgColor = Colors.RGB(177, 200, 249)'azul
	' else If c2.GetString("CAT_GP_TIPOPROD") = "CATALOGO REGULAR" Then
	' bgColor = Colors.White
	' else If c2.GetString("CAT_GP_TIPOPROD") = "ESTRATEGICO" Then
	' bgColor = Colors.RGB(241, 255, 163) 'amarillo
	' End If
	' textColor = Colors.Black
	' clv_productos.Add(CreateListItem(c2.GetString("CAT_GP_NOMBRE"), c2.GetString("CAT_GP_PRECIO"), c2.GetString("CAT_GP_ALMACEN"), clv_productos.AsView.Width, 60dip, bmp, c2.GetString("CAT_GP_ID"), bgColor, textColor), c2.GetString("CAT_GP_NOMBRE"))
	' Next
	' End If
	' c2.Close
End Sub

Private Sub B4XPage_CloseRequest As ResumableSub
	' BACK key pressed
	' Return True To close, False To cancel
	If l_info.Visible Then
		l_info.Visible = False
		Return False
	else if p_vistaPreviaTrans.Visible Then
		p_vistaPreviaTrans.Visible = False
		Return False
	else if lv_promos.visible Then
		lv_promos.Visible = False
		lv_catalogos.Visible = True
		p_botonesVenta.Visible = False
		l_total.Visible = False
		l_totProds.Visible = False
		Return False
	else if clv_prods_ll.AsView.Visible Then
		lfila.text = "CATALOGO"
		clv_prods_ll.AsView.Visible = False
		lv_subtipo.Visible = False
		p_botonesVenta.Visible = False
		l_total.Visible = False
		l_totProds.Visible = False
		lv_catalogos.Visible = True
		Return False
		' else if lv_subtipo.Visible  Then
		' lfila.text = "TIPO"
		' lv_subtipo.Visible = False
		' lv_tipo.Visible = False
		' Return False
		' else if lv_tipo.Visible Then
		' lfila.text = "CATALOGO"
		' lv_tipo.Visible = False
		' lv_catalogos.Visible = True
		' Return False
	else If entro = "4" Then
		entro = "3"
		B4XPage_Appear
		Return True
	Else If entro = "3" Then
		B4XPages.ShowPage("Cliente")
		Return False
	Else
		B4XPages.ShowPage("Cliente")
		Return False
	End If
End Sub



Sub b_QR_Click
	If ciclo = 1 Then
		ciclo = 2
		ya_entro  = "0"
		B4XPage_Appear
	else if ciclo = 2 Then
		ciclo = 3
		ya_entro  = "0"
		B4XPage_Appear
	else if ciclo = 3 Then
		ciclo = 4
		ya_entro  = "0"
		B4XPage_Appear
	else if ciclo = 4 Then
		ciclo = 5
		ya_entro  = "0"
		B4XPage_Appear
	else if ciclo = 5 Then
		ciclo = 1
		ya_entro  = "0"
		B4XPage_Appear
	End If
End Sub

'****************************************************************************
'***************** PARA EL MAS/MENOS *************************************
'****************************************************************************
Sub CreateListItem(Text As String, precioU As String, inv As Int, Width As Int, Height As Int, img As Bitmap, prodId As String, bc As Int, tc As Int) As Panel
	' Dim p As B4XView = xui.CreatePanel("")
	' p.SetLayoutAnimated(0, 0, 0, Width, Height)
	' p.LoadLayout("prodItem")
	' p_prods.Color = bc
	' l_prodX.TextColor = tc
	' l_prodX.TextSize = 15
	' p_prods.Height = Height
	' l_prodX.Height = Height
	' l_prodX.Text = Text&CRLF&"# " & inv & " $ " & precioU
	' l_prodX.Tag = $"ID: ${prodId}${CRLF}${Text}${CRLF}Precio: $$1.2{precioU}${CRLF}Inv: ${inv} pzs"$
	' l_pCant.Tag = precioU&"|"&inv&"|"&prodId
	' et_pCant.Tag = precioU&"|"&inv&"|"&prodId
	' et_pCant.BringToFront
	' Return p
End Sub

Sub b_prodMenos_Click
	totalcajasmaspiezas = 0
	etCantHasFocus = False
	Root.RequestFocus
	' LogColor("b_prodMenos_Click", Colors.Magenta)
	Dim index As Int = clv_prods_ll.GetItemFromView(Sender)
	Dim pnl0 As B4XView = clv_prods_ll.GetPanel(index)
	Dim pnl As B4XView = pnl0.GetView(0)
	Dim laCant As B4XView = pnl.GetView(2).GetView(2)
	Dim laCant2 As B4XView = pnl.GetView(3).GetView(2)
	Dim panelbotonesc As B4XView = pnl.GetView(3)
	Dim lProdX As B4XView = pnl.GetView(1)
	Dim panelcajas As B4XView = pnl.GetView(3)
	Dim panelpiezas As B4XView = pnl.GetView(2)
	' Log($"precio|stock:${laCant.tag}"$)
	If laCant.Text = "" Then laCant.Text = 0
	' Log("lacant.text="&laCant.text)
	laCant.Text = $"${NumberFormat2(laCant.Text-1,0,0,0,False)}"$
	If laCant.Text < 0 Then laCant.Text = 0
	Private tmpMap1 As Map = clv_prods_ll.GetValue(index).As(Map)
	Private precio As String=clv_prods_ll.GetValue(index).As(Map).Get("precio")
	Private id As String=clv_prods_ll.GetValue(index).As(Map).Get("id")
	Private tmpMap As Map = CreateMap("precio":precio, "cant":laCant.Text, "almacen":Subs.traeAlmacen)
	Private nombreX As String = Subs.traeProdNombre(id)
	LogColor(tmpMap1,Colors.Magenta)
	' prodsMap.Put(id, tmpMap)
	If laCant.Text = 0 Then prodsMap.Remove(id)
	If laCant.Text = 0 Then
		panelcajas.Visible = True
	Else If laCant.Text > 0 Then
		panelcajas.Visible = False
	End If
	' If laCant2.IsInitialized Then
	' totalcajasmaspiezas = laCant.Text + laCant2.Text
	' Else
	' totalcajasmaspiezas = laCant.Text
	' End If
	LogColor("prodsMap="&prodsMap, Colors.blue)
	' (Subs.traeAlmacen, p1.Get("precio"), p1.Get("cant"), pn, p, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta)
	Log($"${Subs.traeAlmacen}, ${precio}, ${laCant.text}, ${Subs.traeProdNombre(id)}, ${id}, ${clienteId}"$)
	Subs.actualizaProducto(Subs.traeAlmacen, precio, laCant.Text, Subs.traeProdNombre(id), id, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta,0,0)
	cuentaProds
	LogColor("prodsMap="&prodsMap, Colors.blue)
	Log($"Total Prods: ${totalProds}, Total Compra: $$1.2{totalCompra}"$)
	If 1 = 1 Then
		Private cs As CSBuilder
		cs.Initialize
		Private o As Cursor = Starter.skmt.ExecQuery($"select CAT_GP_ALMACEN from ${Starter.tabla} where CAT_GP_ID = '${id}'"$)
		Private invActualizado As String = "0"
		If o.RowCount > 0 Then
			o.Position = 0
			invActualizado = o.GetString("CAT_GP_ALMACEN")
		End If
		If clv_prods_ll.GetValue(index).As(Map).Get("precio_caja").As(Float) = 0 Or clv_prods_ll.GetValue(index).As(Map).Get("conversion").As(Int) = 1 Then
			Private maxcajas As Int = 0
			Log("cajas a 0")
		Else
			Private maxcajas As Int = invActualizado/clv_prods_ll.GetValue(index).As(Map).Get("conversion")
			Log("cajas no a 0")
		End If
		' Private maxcajas As Int = invActualizado/clv_prods_ll.GetValue(index).As(Map).Get("conversion")
		If 2 = 2 Then lProdX.Text = cs.Color(Colors.red).append(nombreX).pop.Append(CRLF).Append("Existencias: " & invActualizado).Color(0xFF017F01).Append($"   $${NumberFormat2(precio, 1, 2, 2, False)}${CRLF}Max. Cajas: ${maxcajas}"$).Popall
		' Log(lProdX.Text)
	End If
	If laCant.Text = 0 Then
		If maxcajas > 0 Then
			panelcajas.Visible = True
		Else
			panelcajas.Visible = False
		End If
	Else If laCant.Text > 0 Then
		panelcajas.Visible = False
	End If
	If Subs.totalPedido < 1 Then laCant.Text = "0"
	invTotal = totalcajasmaspiezas + Subs.traeinventario(id)
	'aqui si lo comentamos aparece la parte de cajas
	If tmpMap1.Get("conversion") = "1" Or tmpMap1.Get("precio_caja") = "0" Then
		Log("invisible")
		panelbotonesc.Visible = False
	End If
	If clv_prods_ll.GetValue(index).As(Map).Get("almacen") < clv_prods_ll.GetValue(index).As(Map).Get("conversion") Then
		Log(clv_prods_ll.GetValue(index).As(Map).Get("cant"))
		If clv_prods_ll.GetValue(index).As(Map).Get("cant").As(Int) = 0 Then
			Log("Aqui debemos ponerlo invisible")
			panelcajas.Visible = False
		Else
		End If
		' p_botMasMenc.Visible = False
	End If
	'fin aparecer parte de cajas
	' LogColor("InvTotal PRODMAS: " & invTotal, Colors.Red)
End Sub

Sub b_prodMas_Click
	totalcajasmaspiezas = 0
	etCantHasFocus = False
	Root.RequestFocus
	' LogColor("b_prodMas_Click", Colors.Magenta)

	Dim index As Int = clv_prods_ll.GetItemFromView(Sender)
	Dim pnl0 As B4XView = clv_prods_ll.GetPanel(index)
	Dim pnl As B4XView = pnl0.GetView(0)
	Dim laCant As B4XView = pnl.GetView(2).GetView(2)
	Dim panelcajas As B4XView = pnl.GetView(3)
	Dim panelpiezas As B4XView = pnl.GetView(2)
	Dim laCant2 As B4XView = pnl.GetView(3).GetView(2)
	Dim lProdX As B4XView = pnl.GetView(1)

	' Private tmpMap As Map = clv_prods_ll.GetValue(index).As(Map)
	Private precio As String=clv_prods_ll.GetValue(index).As(Map).Get("precio")
	Private inv As String=clv_prods_ll.GetValue(index).As(Map).Get("almacen")
	Private existencias As String = clv_prods_ll.GetValue(index).As(Map).Get("almacen")
	Log($"Existencias: ${existencias}"$)
	If laCant.Text = "" Then laCant.Text = 0
	Private id As String=clv_prods_ll.GetValue(index).As(Map).Get("id")
	' If laCant.Text + 1 <= inv Then
	'' Log(NumberFormat2(laCant.Text+1,0,0,0,False))
	' laCant.Text = $"${NumberFormat2(laCant.Text+1,0,0,0,False)}"$
	'' Private precio As String=clv_prods_ll.GetValue(index).As(Map).Get("precio")
	' Private id As String=clv_prods_ll.GetValue(index).As(Map).Get("id")
	'' Private tmpMap As Map = CreateMap("precio":precio, "cant":laCant.Text, "almacen":Subs.traeAlmacen)
	'' Log(tmpMap)
	'' prodsMap.Put(id, tmpMap)
	'' LogColor(prodsMap, Colors.blue)
	' End If
	' Log("Cantidad + exis   " & (laCant.Text + existencias))
	' Log( (laCant.Text + 1 <= (laCant.Text + existencias)))
	' Log("inventario   "&Subs.traeinventario(id))
	' Log((Subs.totalPedido - precio > 1))
	' Log((Subs.totalPedido))
	' Log(precio)
	Log(B4XPages.MainPage.tipo_venta)
	Log(B4XPages.MainPage.cliente.credito_diponible)
	LogColor(laCant.Text,Colors.Red)
	If B4XPages.MainPage.tipo_venta = "PREVENTA_CREDITO" Then
		Dim fg As Cursor = Starter.skmt.ExecQuery("Select IFNULL(sum(PE_COSTO_TOT),0) AS COSTO FROM PEDIDO WHERE PE_CLIENTE IN (SELECT CUENTA FROM CUENTAA) AND PE_FOLIO = 'PREVENTA_CREDITO'")
		fg.Position = 0

		If fg.GetString("COSTO") + precio <= B4XPages.MainPage.cliente.credito_diponible Then
			If Subs.traeinventario(id) > 0 And (laCant.Text <= (laCant.Text + Subs.traeinventario(id))) Then 'And (Subs.totalPedido - precio > 1)
				' Log(clv_prods_ll.GetValue(index).As(Map))
				clv_prods_ll.GetValue(index).As(Map).Put("almacen", (inv - 1))
				inv = inv - 1
				' laCant.Text = $"$1.0{laCant.Text+1}"$
				laCant.Text = NumberFormat2((laCant.Text + 1), 1, 0, 0, False)
				' Log(clv_prods_ll.GetValue(index).As(Map))
			End If
			Private nombreX As String = Subs.traeProdNombre(id)
			' Subs.actualizaProducto(Subs.traeAlmacen, laCant.text, id, clienteId)

			If laCant.Text > 0 Then
				panelcajas.Visible = False
			Else If laCant.Text = 0 Then
				panelcajas.Visible = True
			End If

			LogColor(laCant.Text,Colors.Red)
			' If laCant2.IsInitialized Then
			' totalcajasmaspiezas = laCant.Text + laCant2.Text
			' Else
			' totalcajasmaspiezas = laCant.Text
			' End If

			Subs.actualizaProducto(Subs.traeAlmacen, precio, laCant.Text, Subs.traeProdNombre(id), id, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta,0,0)
			cuentaProds
			' Log($"Total Prods: ${totalProds}, Total Compra: $$1.2{totalCompra}"$)
			If 1 = 1 Then
				Private cs As CSBuilder
				cs.Initialize
				Private o As Cursor = Starter.skmt.ExecQuery($"select CAT_GP_ALMACEN from ${Starter.tabla} where CAT_GP_ID = '${id}'"$)
				Private invActualizado As String = "0"
				If o.RowCount > 0 Then
					o.Position = 0
					invActualizado = o.GetString("CAT_GP_ALMACEN")
				End If
				If clv_prods_ll.GetValue(index).As(Map).Get("precio_caja").As(Float) = 0 Or clv_prods_ll.GetValue(index).As(Map).Get("conversion").As(Int) = 1 Then
					Private maxcajas As Int = 0
					Log("cajas a 0")
				Else
					Private maxcajas As Int = invActualizado/clv_prods_ll.GetValue(index).As(Map).Get("conversion")
					Log("cajas no a 0")
				End If
				If 2 = 2 Then lProdX.Text = cs.Color(Colors.red).append(nombreX).pop.Append(CRLF).Append("Existencias: " & invActualizado).Color(0xFF017F01).Append($"   $${NumberFormat2(precio, 1, 2, 2, False)}${CRLF}Max. Cajas: ${maxcajas}"$).Popall
				' Log(lProdX.Text)
			End If
			invTotal = totalcajasmaspiezas + Subs.traeinventario(id)
			' LogColor("InvTotal PRODMAS: " & invTotal, Colors.Red)
		Else
			MsgboxAsync("No se puede meter mas venta a credito por que supera el limite del credito","Atencion")
		End If
	Else
		If Subs.traeinventario(id) > 0 And (laCant.Text <= (laCant.Text + Subs.traeinventario(id))) Then 'And (Subs.totalPedido - precio > 1)
			' Log(clv_prods_ll.GetValue(index).As(Map))
			clv_prods_ll.GetValue(index).As(Map).Put("almacen", (inv - 1))
			inv = inv - 1
			' laCant.Text = $"$1.0{laCant.Text+1}"$
			laCant.Text = NumberFormat2((laCant.Text + 1), 1, 0, 0, False)
			' Log(clv_prods_ll.GetValue(index).As(Map))
		End If
		Private nombreX As String = Subs.traeProdNombre(id)
		' Subs.actualizaProducto(Subs.traeAlmacen, laCant.text, id, clienteId)

		If laCant.Text > 0 Then
			panelcajas.Visible = False
		Else If laCant.Text = 0 Then
			panelcajas.Visible = True
		End If

		LogColor(laCant.Text,Colors.Red)
		' If laCant2.IsInitialized Then
		' totalcajasmaspiezas = laCant.Text + laCant2.Text
		' Else
		' totalcajasmaspiezas = laCant.Text
		' End If

		Subs.actualizaProducto(Subs.traeAlmacen, precio, laCant.Text, Subs.traeProdNombre(id), id, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta,0,0)
		cuentaProds
		' Log($"Total Prods: ${totalProds}, Total Compra: $$1.2{totalCompra}"$)
		If 1 = 1 Then
			Private cs As CSBuilder
			cs.Initialize
			Private o As Cursor = Starter.skmt.ExecQuery($"select CAT_GP_ALMACEN from ${Starter.tabla} where CAT_GP_ID = '${id}'"$)
			Private invActualizado As String = "0"
			If o.RowCount > 0 Then
				o.Position = 0
				invActualizado = o.GetString("CAT_GP_ALMACEN")
			End If
			If clv_prods_ll.GetValue(index).As(Map).Get("precio_caja").As(Float) = 0 Or clv_prods_ll.GetValue(index).As(Map).Get("conversion").As(Int) = 1 Then
				Private maxcajas As Int = 0
				Log("cajas a 0")
			Else
				Private maxcajas As Int = invActualizado/clv_prods_ll.GetValue(index).As(Map).Get("conversion")
				Log("cajas no a 0")
			End If
			If 2 = 2 Then lProdX.Text = cs.Color(Colors.red).append(nombreX).pop.Append(CRLF).Append("Existencias: " & invActualizado).Color(0xFF017F01).Append($"   $${NumberFormat2(precio, 1, 2, 2, False)}${CRLF}Max. Cajas: ${maxcajas}"$).Popall
			' Log(lProdX.Text)
		End If
		invTotal = totalcajasmaspiezas + Subs.traeinventario(id)
		' LogColor("InvTotal PRODMAS: " & invTotal, Colors.Red)
	End If
End Sub

Private Sub et_pCant_FocusChanged (HasFocus As Boolean)
	LogColor($"focus changed=${HasFocus}"$, Colors.Magenta)
	If et_pCant.Text = "" Then et_pCant.Text = "0"
	Dim index As Int = clv_prods_ll.GetItemFromView(Sender)
	Dim pnl0 As B4XView = clv_prods_ll.GetPanel(index)
	Dim pnl As B4XView = pnl0.GetView(0)
	Dim laCant As B4XView = pnl.GetView(2).GetView(2)
	Dim laCant2 As B4XView = pnl.GetView(3).GetView(2)
	Private id As String=clv_prods_ll.GetValue(index).As(Map).Get("id")
	If laCant.Text = "" Then laCant.Text = "0"
	etCantHasFocus = HasFocus
	LogColor(laCant.Text,Colors.Red)
	If laCant2.IsInitialized Then
		totalcajasmaspiezas = laCant.Text + laCant2.Text
	Else
		totalcajasmaspiezas = laCant.Text
	End If
	invTotal = totalcajasmaspiezas + Subs.traeinventario(id)
	' LogColor("InvTotal PRODMAS: " & invTotal, Colors.Red)
	cuentaProds
End Sub

Private Sub et_pCant_TextChanged (Old As String, New As String)
	' Log(etCantHasFocus)
	' Log("InvTotal: " & invTotal)
	If etCantHasFocus = True Then
		LogColor($"txt changed: ${Old}|${New}, hasfocus=${etCantHasFocus}"$,Colors.Magenta)
		Dim index As Int = clv_prods_ll.GetItemFromView(Sender)
		Dim pnl0 As B4XView = clv_prods_ll.GetPanel(index)
		Dim pnl As B4XView = pnl0.GetView(0)
		Dim laCant As B4XView = pnl.GetView(2).GetView(2)
		Dim laCant2 As B4XView = pnl.GetView(3).GetView(2)
		Dim lProdX As B4XView = pnl.GetView(1)
		Private id As String=clv_prods_ll.GetValue(index).As(Map).Get("id")
		Private precio As String=clv_prods_ll.GetValue(index).As(Map).Get("precio")
		Private inv As String=clv_prods_ll.GetValue(index).As(Map).Get("almacen")
		Private inv As String=Subs.traeinventario(id)
		Private nombreX As String = Subs.traeProdNombre(id)
		Dim panelcajas As B4XView = pnl.GetView(3)
		Dim panelpiezas As B4XView = pnl.GetView(2)
		If(New = "" Or New = Null Or New = "-") Then New = 0
		' If New < 0 Then New = 0
		If(New > invTotal) Then
			Sender.As(EditText).text = invTotal
		End If
		' Log($"inventario=${inv}"$)
		If New = "" Then New = 0
		If Old = "" Or Old = Null Then New = 0
		If laCant.Text = "" Then laCant.Text = 0
		LogColor(laCant.Text,Colors.Red)
		If New > 0 Then
			panelcajas.Visible = False
		Else If New = 0 Then
			panelcajas.Visible = True
		End If
		Log(Old)
		If Old <> "" Then
			Log("--------------->Credito Disponible: "&B4XPages.MainPage.cliente.credito_diponible)
			If B4XPages.MainPage.tipo_venta = "PREVENTA_CREDITO" Then
				Dim fg As Cursor = Starter.skmt.ExecQuery("Select IFNULL(sum(PE_COSTO_TOT),0) AS COSTO FROM PEDIDO WHERE PE_CLIENTE IN (SELECT CUENTA FROM CUENTAA) AND PE_FOLIO = 'PREVENTA_CREDITO'")
				fg.Position = 0
				If Old = "" Or Old = Null Then New = 0
				Log(precio &"     *    "&Old)
				Log(fg.GetString("COSTO") +(precio*New))
				If fg.GetString("COSTO") +((precio*New)-(precio*Old))  <= B4XPages.MainPage.cliente.credito_diponible Then
					' If laCant2.IsInitialized Then
					' totalcajasmaspiezas = laCant.Text + laCant2.Text
					' Else
					' totalcajasmaspiezas = laCant.Text
					' End If
					If Not(Old = "0" And New = "") And laCant.Text <> Null And laCant.Text <> "" And etCantHasFocus Then
						Log("actualizamos producto")
						Subs.actualizaProducto(Subs.traeAlmacen, precio, laCant.Text, Subs.traeProdNombre(id), id, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta,0,0)
						cuentaProds
					End If
					' If New <> "" And New.SubString2(0,0) = "0" Then
					' New.SubString(1)
					' End If
					' If New <> "" And New.SubString(1) <> "" Then
					' Log(New.SubString(1))
					' New = New.SubString(1)
					' laCant.Text = New.SubString(1)
					' Log(laCant.Text)
					' End If
					If 1 = 1 Then
						Private cs As CSBuilder
						cs.Initialize
						Private o As Cursor = Starter.skmt.ExecQuery($"select CAT_GP_ALMACEN from ${Starter.tabla} where CAT_GP_ID = '${id}'"$)
						Private invActualizado As String = "0"
						' If o.RowCount > 0 Then
						o.Position = 0
						invActualizado = Subs.traeinventario(id)
						Log(Subs.traeinventario(id))
						' End If
						If New = "" Then New = 0
						If clv_prods_ll.GetValue(index).As(Map).Get("precio_caja").As(Float) = 0 Or clv_prods_ll.GetValue(index).As(Map).Get("conversion").As(Int) = 1 Then
							Private maxcajas As Int = 0
							Log("cajas a 0")
						Else
							Private maxcajas As Int = invActualizado/clv_prods_ll.GetValue(index).As(Map).Get("conversion")
							Log("cajas no a 0")
						End If
						lProdX.Text = cs.Color(Colors.red).append(nombreX).pop.Append(CRLF).Append("Existencias: " & (Subs.traeinventario(id))).Color(0xFF017F01).Append($"   $${NumberFormat2(precio, 1, 2, 2, False)}${CRLF}Max. Cajas: ${maxcajas}"$).Popall
					End If
				Else
					laCant.Text = 0
					MsgboxAsync("No se puede meter mas venta a credito por que supera el limite del credito","Atencion")
				End If
			Else
				' If laCant2.IsInitialized Then
				' totalcajasmaspiezas = laCant.Text + laCant2.Text
				' Else
				' totalcajasmaspiezas = laCant.Text
				' End If
				If Not(Old = "0" And New = "") And laCant.Text <> Null And laCant.Text <> "" And etCantHasFocus Then
					Log("actualizamos producto")
					Subs.actualizaProducto(Subs.traeAlmacen, precio, laCant.Text, Subs.traeProdNombre(id), id, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta,0,0)
					cuentaProds
				End If
				' If New <> "" And New.SubString2(0,0) = "0" Then
				' New.SubString(1)
				' End If
				' If New <> "" And New.SubString(1) <> "" Then
				' Log(New.SubString(1))
				' New = New.SubString(1)
				' laCant.Text = New.SubString(1)
				' Log(laCant.Text)
				' End If
				If 1 = 1 Then
					Private cs As CSBuilder
					cs.Initialize
					Private o As Cursor = Starter.skmt.ExecQuery($"select CAT_GP_ALMACEN from ${Starter.tabla} where CAT_GP_ID = '${id}'"$)
					Private invActualizado As String = "0"
					' If o.RowCount > 0 Then
					o.Position = 0
					invActualizado = Subs.traeinventario(id)
					Log(Subs.traeinventario(id))
					' End If
					If New = "" Then New = 0
					If clv_prods_ll.GetValue(index).As(Map).Get("precio_caja").As(Float) = 0 Or clv_prods_ll.GetValue(index).As(Map).Get("conversion").As(Int) = 1 Then
						Private maxcajas As Int = 0
						Log("cajas a 0")
					Else
						Private maxcajas As Int = invActualizado/clv_prods_ll.GetValue(index).As(Map).Get("conversion")
						Log("cajas no a 0")
					End If
					lProdX.Text = cs.Color(Colors.red).append(nombreX).pop.Append(CRLF).Append("Existencias: " & (Subs.traeinventario(id))).Color(0xFF017F01).Append($"   $${NumberFormat2(precio, 1, 2, 2, False)}${CRLF}Max. Cajas: ${maxcajas}"$).Popall
				End If
			End If
		End If
		If New > 0 Then
			panelcajas.Visible = False
		Else If New = 0 Then
			If maxcajas = 0 Then
				panelcajas.Visible = False
			Else
				panelcajas.Visible = True
			End If
		End If
	End If
End Sub

Sub cuentaProds
	' LogColor($"Productos de la orden: ${c_prods.GetString("cantProds")}, Total: ${c_prodsX.GetString("costoTotal")}"$, Colors.red)
	Log("===========================")
	Private c As Cursor = B4XPages.MainPage.skmt.ExecQuery($"select sum(PE_COSTO_TOT) as total, sum(PE_CANT) as cant from PEDIDO where PE_CLIENTE = '${clienteId}'"$)
	' LogColor("TIEMPO cuentaProds =" & ((DateTime.Now-inicioContador)/1000), Colors.Red)
	' LogColor(prodsMap, Colors.Magenta)
	p_botonesVenta.Visible = True
	p_botonesVenta.BringToFront
	c.Position=0
	' Log($"Total Prods: ${c.GetString("cant")}, Total Compra: $$1.2{c.GetString("total")}"$)
	c.Close
	' Log($"HAY PEDIDO: ${hayPedido}"$)
End Sub

'Sub b_terminar1_Click
'	' Log("b_terminar1_Click")
'	' ya_entro = "0" : Log("ya_entro=1")
'	B4XPages.MainPage.skmt.ExecNonQuery2("delete from PEDIDO WHERE PE_PRONOMBRE = ? ", Array As Object("N/A") )
'	lv_promos.Visible = False
'	clv_prods_ll.AsView.Visible = False
'	lv_catalogos.Visible = True
'	lv_prodsPedido.Clear
'	lv_prodsPedido.TwoLinesLayout.Label.Height = 35dip
'	lv_prodsPedido.TwoLinesLayout.SecondLabel.Height = 25dip
'	Private c_prods As Cursor=B4XPages.MainPage.skmt.ExecQuery("select PE_PRONOMBRE,PE_COSTO_TOT, PE_CANT, PE_FOLIO, PE_CEDIS FROM PEDIDO WHERE PE_CLIENTE IN (Select CUENTA from cuentaa) order by PE_CEDIS, PE_PRONOMBRE")
'	If c_prods.RowCount > 0 Then
'		Private cs As CSBuilder
'		vamoaver.Initialize
'		For i=0 To c_prods.RowCount -1
'			cs.Initialize
'			c_prods.Position=i
'			Dim label1 As Label
'			label1 = lv_prodsPedido.TwoLinesLayout.Label
'			label1.TextSize = 15
'			label1.TextColor = Colors.Black
'			label1.color = Colors.White
'			Private textColor As Int = Colors.black
'			If c_prods.GetString("PE_FOLIO") = "VENTA" Then
'				textColor = Colors.RGB(48,3,195)
'			Else If c_prods.GetString("PE_FOLIO") = "PREVENTA_CONTADO" Or c_prods.GetString("PE_FOLIO") = "ABORDO" Or c_prods.GetString("PE_FOLIO") = "RECARGA" Then
'				textColor = Colors.RGB(166,0,0)
'			Else If folio = "PREVENTA_CREDITO" Then
'				textColor = Colors.RGB(0, 128, 0)
'			End If
'			If Not(IsNumber(c_prods.GetString("PE_CEDIS"))) And folio = "VENTA" Then
'				textColor = Colors.RGB(154,131,231)
'			Else If Not(IsNumber(c_prods.GetString("PE_CEDIS"))) And folio = "PREVENTA_CONTADO" Then
'				folio = "PREVENTA"
'				textColor = Colors.RGB(255,0,214)
'			Else If Not(IsNumber(c_prods.GetString("PE_CEDIS"))) And folio = "PREVENTA_CREDITO" Then
'				folio = "PREVENTA"
'				textColor = Colors.RGB(120,178,108)
'			End If
'			Dim label2 As Label
'			label2 = lv_prodsPedido.TwoLinesLayout.SecondLabel
'			label2.TextSize = 10
'			label2.TextColor = Colors.Blue
'			Dim polioreal As String
'			If folio = "VENTA" Then
'			Else If folio = "PREVENTA_CONTADO" Then
'				polioreal = "PREVENTA"
'			Else If folio = "PREVENTA_CREDITO" Then
'				polioreal = "PREVENTA"
'			End If
'			LogColor(polioreal,Colors.Gray)
'			' lv_prodsPedido.AddTwoLines(cs.Color(textColor).append(c_prods.GetString("PE_PRONOMBRE")).pop,"Cantidad #"& c_prods.GetString("PE_CANT")& " SubTotal $"& c_prods.GetString("PE_COSTO_TOT")& " Folio "& c_prods.GetString("PE_FOLIO"))
'			lv_prodsPedido.AddSingleLine(cs.Color(textColor).Size(12).append(c_prods.GetString("PE_PRONOMBRE") & " ").pop.Append(CRLF).Size(8).Color(Colors.Blue).Append("Cantidad #"& c_prods.GetString("PE_CANT")).Append(" SubTotal $"& c_prods.GetString("PE_COSTO_TOT")).Append(" "  & polioreal& " " &c_prods.GetString("PE_CEDIS")).PopAll)
'			vamoaver.Add(c_prods.GetString("PE_FOLIO"))
'			folio = c_prods.GetString("PE_FOLIO")
'		Next
'		' c=B4XPages.MainPage.skmt.ExecQuery("select pc_noart, pc_monto from pedido_cliente where pc_cliente in (Select CUENTA from cuentaa)")
'		' c = B4XPages.MainPage.skmt.ExecQuery("SELECT SUM (PE_CANT) AS CANTIDAD FROM PEDIDO WHERE PE_PROID not like 'PRO%' and PE_CLIENTE IN  (Select CUENTA from cuentaa)")
'		c = B4XPages.MainPage.skmt.ExecQuery("select sum(PE_CANT) as PC_NOART, sum (PE_COSTO_TOT) as PC_MONTO from PEDIDO where PE_CLIENTE in (Select CUENTA from cuentaa) AND PE_PROID NOT IN (SELECT CAT_PA_ID FROM PROMOS_COMP )")
'		' r = B4XPages.MainPage.skmt.ExecQuery("SELECT SUM (PE_COSTO_TOT) AS MONTO FROM PEDIDO WHERE PE_CLIENTE IN  (Select CUENTA from cuentaa)")
'		c.Position=0
'		' r.Position = 0
'		l_cant.Text = c.GetString("PC_NOART")
'		l_total2.Text = c.GetString("PC_MONTO")
'		c.Close
'		' r.Close
'	End If
'	c_prods.Close
'	p_vistaPreviaTrans.Width = Root.Width
'	p_vistaPreviaTrans.Height = Root.Height
'	Subs.centraPanel(p_vistaPrevia, Root.Width)
'	' If Subs.pedidoGuardado Then b_rechazar.Enabled = False Else b_rechazar.Enabled = True
'	Dim fg As Cursor = Starter.skmt.ExecQuery("Select IFNULL(sum(PE_COSTO_TOT),0) AS COSTO, PE_FOLIO FROM PEDIDO WHERE PE_CLIENTE IN (SELECT CUENTA FROM CUENTAA) AND PE_FOLIO = 'PREVENTA_CREDITO'")
'	fg.Position = 0
'	Dim costo As String = fg.GetString("COSTO")
'	If costo > 0 And costo < 1000 And fg.GetString("PE_FOLIO") = "PREVENTA_CREDITO" Then
'		result = Msgbox2($"¿Desea continuar?${CRLF}Si acepta, el pedido se borrará (mínimo $1,000).${CRLF}Si cancela, podrá seguir agregando productos."$,"Venta Minima de Credito", "Si", "", "No",LoadBitmap(File.DirAssets,"alert2.png"))
'		If result = DialogResponse.POSITIVE Then
'			Subs.borraPedidoCredito
'			' B4XPages.MainPage.promos.promosMap.Initialize
'			B4XPages.ShowPage("Cliente")
'		Else
'			lv_catalogos.Visible = True
'		End If
'	Else
'		p_vistaPrevia.Visible=True
'		p_vistaPreviaTrans.Visible=True
'	End If
'	fg.Close
'End Sub

'Sub b_terminar1_Click
'	' Limpieza previa de registros inválidos
'	B4XPages.MainPage.skmt.ExecNonQuery2("delete from PEDIDO WHERE PE_PRONOMBRE = ? ", Array As Object("N/A") )
'    
'	lv_promos.Visible = False
'	clv_prods_ll.AsView.Visible = False
'	lv_catalogos.Visible = True
'	lv_prodsPedido.Clear
'    
'	' =========================================================
'	' 1. CONFIGURACIÓN DEL LAYOUT (ESPACIADO OPTIMIZADO)
'	' =========================================================
'	' Aumentamos un poco más el alto para compensar el nuevo salto de línea
'	lv_prodsPedido.TwoLinesLayout.ItemHeight = 140dip
'    
'	' Ajuste del Título (Nombre del Producto)
'	lv_prodsPedido.TwoLinesLayout.Label.Height = 45dip
'	lv_prodsPedido.TwoLinesLayout.Label.TextSize = 14
'	lv_prodsPedido.TwoLinesLayout.Label.Typeface = Typeface.DEFAULT_BOLD
'	lv_prodsPedido.TwoLinesLayout.Label.TextColor = Colors.RGB(150, 0, 0)
'	lv_prodsPedido.TwoLinesLayout.Label.Gravity = Gravity.CENTER_VERTICAL
'    
'	' Ajuste del Subtítulo (Bajamos el Top para que el CRLF extra no lo encime)
'	lv_prodsPedido.TwoLinesLayout.SecondLabel.Height = 90dip
'	lv_prodsPedido.TwoLinesLayout.SecondLabel.Top = 50dip
'	lv_prodsPedido.TwoLinesLayout.SecondLabel.TextSize = 14
'	' =========================================================
'
'	Private q As String = "SELECT PE_PRONOMBRE, PE_COSTO_TOT, PE_CANT, PE_FOLIO, PE_CEDIS, PE_PRESENTACION, PE_CANTC, PE_UVM, PE_PROID, PE_DIRIGIDA " & _
'                          "FROM PEDIDO WHERE PE_CLIENTE IN (Select CUENTA from cuentaa) order by PE_CEDIS, PE_PRONOMBRE"
'    
'	Private c_prods As Cursor = B4XPages.MainPage.skmt.ExecQuery(q)
'    
'	If c_prods.RowCount > 0 Then
'		vamoaver.Initialize
'        
'		For i = 0 To c_prods.RowCount - 1
'			c_prods.Position = i
'            
'			' Obtención de datos
'			Dim nomProd As String = c_prods.GetString("PE_PRONOMBRE")
'			Dim idProd As String = c_prods.GetString("PE_PROID")
'			Dim presName As String = c_prods.GetString("PE_PRESENTACION")
'			Dim cantPres As String = c_prods.GetString("PE_CANTC")
'			Dim uvmVal As Int = c_prods.GetInt("PE_UVM")
'			Dim cedisFila As String = c_prods.GetString("PE_CEDIS")
'			Dim folioFila As String = c_prods.GetString("PE_FOLIO")
'			Dim dirFila As String = c_prods.GetString("PE_DIRIGIDA")
'			Dim cantPzs As Int = c_prods.GetInt("PE_CANT")
'            
'			If cantPres = "" Or cantPres = "null" Then cantPres = "0"
'            
'			' 2. CONSTRUCCIÓN DEL SUBTÍTULO CON SALTO DE LÍNEA EXTRA
'			Dim detalle As CSBuilder
'			detalle.Initialize
'            
'			' --- EL CAMBIO ESTÁ AQUÍ ---
'			' Agregamos un salto de línea inicial para separar el bloque azul del nombre rojo
'			detalle.Append(CRLF)
'            
'			' REGLA: Si UVM > 1, mostrar la presentación azul
'			If uvmVal > 1 Then
'				detalle.Color(Colors.Blue).Size(14).Append(presName.ToUpperCase & ": " & (cantPzs/uvmVal)).Pop.Pop.Append(CRLF)
'				detalle.Size(6).Append(CRLF).Pop
'			End If
'            
'			detalle.Color(Colors.DarkGray).Size(13).Append("Piezas: ").Color(Colors.Black).Append("#" & cantPzs).Pop
'			detalle.Append("  |  ").Color(Colors.DarkGray).Append("Subtotal: ").Color(0xFF008000).Append("$" & NumberFormat2(c_prods.GetDouble("PE_COSTO_TOT"), 1, 2, 2, False)).PopAll
'            
'			' 3. MAPA DE IDENTIDAD
'			Dim datosIdentidad As Map = CreateMap("id": idProd, "nombre": nomProd, "cedis": cedisFila, "pres": presName, "uvm": uvmVal, "dir": dirFila, "folio": folioFila, "cant": cantPzs)
'
'			' Añadimos al ListView
'			lv_prodsPedido.AddTwoLines2(nomProd, detalle, datosIdentidad)
'            
'			vamoaver.Add(folioFila)
'		Next
'        
'		ActualizarEtiquetasTotales
'	End If
'	c_prods.Close
'    
'	' Configuración de paneles
'	p_vistaPreviaTrans.Width = Root.Width
'	p_vistaPreviaTrans.Height = Root.Height
'	Subs.centraPanel(p_vistaPrevia, Root.Width)
'	p_vistaPrevia.Visible = True
'	p_vistaPreviaTrans.Visible = True
'End Sub

Sub b_terminar1_Click
	' Limpieza previa de registros inválidos
	B4XPages.MainPage.skmt.ExecNonQuery2("delete from PEDIDO WHERE PE_PRONOMBRE = ? ", Array As Object("N/A") )
    
	lv_promos.Visible = False
	clv_prods_ll.AsView.Visible = False
	lv_catalogos.Visible = True
	lv_prodsPedido.Clear
    
	' =========================================================
	' 1. CONFIGURACIÓN DEL LAYOUT (ESPACIADO OPTIMIZADO)
	' =========================================================
	lv_prodsPedido.TwoLinesLayout.ItemHeight = 140dip
    
	' Título (Configuración base, el CSBuilder mandará sobre el color)
	lv_prodsPedido.TwoLinesLayout.Label.Height = 45dip
	lv_prodsPedido.TwoLinesLayout.Label.TextSize = 14
	lv_prodsPedido.TwoLinesLayout.Label.Typeface = Typeface.DEFAULT_BOLD
	lv_prodsPedido.TwoLinesLayout.Label.Gravity = Gravity.CENTER_VERTICAL
    
	' Subtítulo
	lv_prodsPedido.TwoLinesLayout.SecondLabel.Height = 90dip
	lv_prodsPedido.TwoLinesLayout.SecondLabel.Top = 50dip
	lv_prodsPedido.TwoLinesLayout.SecondLabel.TextSize = 14
	' =========================================================

	Private q As String = "SELECT PE_PRONOMBRE, PE_COSTO_TOT, PE_CANT, PE_FOLIO, PE_CEDIS, PE_PRESENTACION, PE_CANTC, PE_UVM, PE_PROID, PE_DIRIGIDA " & _
                          "FROM PEDIDO WHERE PE_CLIENTE IN (Select CUENTA from cuentaa) order by PE_CEDIS,PE_COSTO_TOT, PE_PRONOMBRE"
    
	Private c_prods As Cursor = B4XPages.MainPage.skmt.ExecQuery(q)
    
	If c_prods.RowCount > 0 Then
		vamoaver.Initialize
		Dim almacenActual As String = Subs.traeAlmacen ' Obtenemos el almacén actual una sola vez
        
		For i = 0 To c_prods.RowCount - 1
			c_prods.Position = i
            
			' Obtención de datos
			Dim nomProd As String = c_prods.GetString("PE_PRONOMBRE")
			Dim idProd As String = c_prods.GetString("PE_PROID")
			Dim presName As String = c_prods.GetString("PE_PRESENTACION")
			Dim cantPres As String = c_prods.GetString("PE_CANTC")
			Dim uvmVal As Int = c_prods.GetInt("PE_UVM")
			Dim cedisFila As String = c_prods.GetString("PE_CEDIS")
			Dim folioFila As String = c_prods.GetString("PE_FOLIO")
			Dim dirFila As String = c_prods.GetString("PE_DIRIGIDA")
			Dim cantPzs As Int = c_prods.GetInt("PE_CANT")
            
			If cantPres = "" Or cantPres = "null" Then cantPres = "0"

			' ---------------------------------------------------------
			' 2. CONSTRUCCIÓN DEL TÍTULO (Lógica de Color por CEDIS)
			' ---------------------------------------------------------
			Dim csTitulo As CSBuilder
			csTitulo.Initialize
			
			If cedisFila <> almacenActual Then
				' ES PROMOCIÓN (Color Verde Esmeralda/Teal)
				csTitulo.Color(Colors.RGB(0, 150, 136)).Typeface(Typeface.DEFAULT_BOLD).Append(nomProd & " (PROMO)").PopAll
			Else
				' VENTA NORMAL (Rojo Oscuro)
				csTitulo.Color(Colors.RGB(150, 0, 0)).Typeface(Typeface.DEFAULT_BOLD).Append(nomProd).PopAll
			End If
            
			' ---------------------------------------------------------
			' 3. CONSTRUCCIÓN DEL SUBTÍTULO
			' ---------------------------------------------------------
			Dim detalle As CSBuilder
			detalle.Initialize
			detalle.Append(CRLF) ' Salto de línea inicial para espaciado
            
			' Regla UVM
			If uvmVal > 1 Then
				detalle.Color(Colors.Blue).Size(14).Append(presName.ToUpperCase & ": " & (cantPzs/uvmVal)).Pop.Pop.Append(CRLF)
				detalle.Size(6).Append(CRLF).Pop
			End If
            
			detalle.Color(Colors.DarkGray).Size(13).Append("Piezas: ").Color(Colors.Black).Append("#" & cantPzs).Pop
			detalle.Append("  |  ").Color(Colors.DarkGray).Append("Subtotal: ").Color(0xFF008000).Append("$" & NumberFormat2(c_prods.GetDouble("PE_COSTO_TOT"), 1, 2, 2, False)).PopAll
            
			' 4. MAPA DE IDENTIDAD
			Dim datosIdentidad As Map = CreateMap("id": idProd, "nombre": nomProd, "cedis": cedisFila, "pres": presName, "uvm": uvmVal, "dir": dirFila, "folio": folioFila, "cant": cantPzs)

			' Añadimos al ListView usando csTitulo en lugar de nomProd
			lv_prodsPedido.AddTwoLines2(csTitulo, detalle, datosIdentidad)
            
			vamoaver.Add(folioFila)
		Next
        
		ActualizarEtiquetasTotales
	End If
	c_prods.Close
    
	' Configuración de paneles
	p_vistaPreviaTrans.Width = Root.Width
	p_vistaPreviaTrans.Height = Root.Height
	Subs.centraPanel(p_vistaPrevia, Root.Width)
	p_vistaPrevia.Visible = True
	p_vistaPreviaTrans.Visible = True
End Sub


Private Sub ActualizarEtiquetasTotales
	Dim h As Cursor = B4XPages.MainPage.skmt.ExecQuery("select ifnull(sum(PE_CANT),0) as PC_NOART, ifnull(sum (PE_COSTO_TOT),0) as PC_MONTO from PEDIDO where PE_CLIENTE in (Select CUENTA from cuentaa) AND PE_PROID NOT IN (SELECT CAT_PA_ID FROM PROMOS_COMP )")
	h.Position = 0
	
	l_cant.Text = h.GetString("PC_NOART")
	l_total2.Text = NumberFormat2(h.GetDouble("PC_MONTO"), 1, 2, 2, False)
	
	h.Close
End Sub

Private Sub b_continuar_Click
	Log("b_continuar_Click")
	cuentaProds
	' Private p1 As Map
	Log($"prodsMap=${prodsMap}"$)
	' For Each p As String In prodsMap.Keys
	' p1 = prodsMap.Get(p)
	' Log(p & "|" & p1)
	' Private pn As String = Subs.traeProdNombre(p)
	' Subs.guardaProductoSinGestion(Subs.traeAlmacen, p1.Get("precio"), p1.Get("cant"), pn, p, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta)
	' Next
	Log("promos-inv, prods-inv, cat-vis")
	lv_promos.Visible = False
	clv_prods_ll.AsView.Visible = False
	lv_subtipo.Visible = False
	lv_tipo.Visible = False
	lv_catalogos.Visible = True
	Log("Continuar")
	Dim m As Map = Subs.traeTotalesClienteActual
	prodsPedidoActual = m.Get("productos")
	montoPedidoActual = m.Get("monto")
	Dim fg As Cursor = Starter.skmt.ExecQuery("Select IFNULL(sum(PE_COSTO_TOT),0) AS COSTO FROM PEDIDO WHERE PE_CLIENTE IN (SELECT CUENTA FROM CUENTAA) AND PE_FOLIO = 'PREVENTA_CREDITO'")
	fg.Position = 0
	Dim costo As String = fg.GetString("COSTO")

	If costo > 0 And costo < 1000 Then
		result = Msgbox2($"¿Desea continuar?${CRLF}Si acepta, el pedido se borrará (mínimo $1,000).${CRLF}Si cancela, podrá seguir agregando productos."$,"Venta Minima de Credito", "Si", "", "No",LoadBitmap(File.DirAssets,"alert2.png"))
		If result = DialogResponse.POSITIVE Then
			Subs.borraPedidoCredito
			B4XPages.MainPage.promos.promosMap.Initialize
			B4XPages.ShowPage("Cliente")
		Else
			lv_catalogos.Visible = True
		End If
	End If
	fg.Close
End Sub

Private Sub l_prodX_LongClick
	Log("longclic = "&Sender.as(Label).tag)
	l_info.Text = Sender.as(Label).tag
	l_info.Visible = True
End Sub

Private Sub l_info_Click
	l_info.Visible = False
End Sub

Private Sub lv_promos_ItemLongClick (Position As Int, Value As Object)
	Log("Promo longclic = "&Value)
	Private id As String = ""
	Dim c As Cursor = B4XPages.MainPage.skmt.ExecQuery($"select CAT_GP_ID from ${Starter.tabla} where CAT_GP_TIPO = 'PROMOS' and CAT_GP_NOMBRE = '${Value}'"$)
	If c.RowCount > 0 Then
		c.Position = 0
		id = c.GetString("CAT_GP_ID")
	End If
	l_info.Text = $"ID: ${id}${CRLF}${Value}"$
	l_info.Visible = True
End Sub

'Private Sub b_buscar_Click
' forzarBusqueda = True
' Busca_TextChanged("",BUSCA.Text)
'End Sub

Private Sub lv_tipo_ItemClick (Position As Int, Value As Object)
	' lfila.text = "SUB TIPO"
	' lv_tipo.Visible = False
	' lv_subtipo.Height = Root.Height * 0.7
	' lv_subtipo.Visible = True
	' Private c As Cursor = B4XPages.MainPage.skmt.ExecQuery2("select distinct CAT_GP_SUBTIPO from cat_gunaprod where CAT_GP_TIPO = ? order by CAT_GP_SUBTIPO", Array As String(Value))
	' If c.RowCount > 0 Then
	' Dim label1 As Label
	' label1 = lv_subtipo.SingleLineLayout.Label
	' label1.TextSize = 17
	' label1.TextColor = Colors.Black
	' lv_subtipo.Clear
	' For i=0 To c.RowCount-1
	' c.Position=i
	' lv_subtipo.AddSingleLine(c.GetString("CAT_GP_SUBTIPO"))
	' Next
	' End If
	' c.Close
End Sub

Private Sub lv_subtipo_ItemClick (Position As Int, Value As Object)
	' lfila.text = "SUB TIPO"
	' LogColor("Catalogo", Colors.red)
	' lv_catalogos.Visible = False
	' lv_subtipo.Visible = False
	' lv_promos.Visible = False
	' lfila.text = "CATALOGO"
	' ProgressDialogShow("Cargando catalogo ...")
	' Sleep(100)
	' Private inicioContador As String = DateTime.Now
	' llenaCatalogo(Value)
	' clv_prods_ll.AsView.Visible = True
	' LogColor("TIEMPO DE PROCESO DEL CATALOGO: " & ((DateTime.Now-inicioContador)/1000), Colors.Red)
	' ProgressDialogHide
End Sub

Private Sub p_vistaPreviaTrans_Click

End Sub

Private Sub b_rechazar_Click
	' If folio <> "" Then
	result =  Msgbox2($"Seguro que desea borrar el pedido completo?${CRLF}Haciendo clic largo sobre un producto se pueden borrar articulos independientes."$,"Rechazar Pedido", "Si", "", "No",LoadBitmap(File.DirAssets,"alert2.png")) 'ignore
	If result = DialogResponse.POSITIVE Then
		Subs.borraPedidoClienteActual
		prodsMap.Initialize
		B4XPages.MainPage.promos.promosMap.Initialize
		' Log("Llamamos LlenaProdsLL")
		' LlenaProdsLL(Null)
		clv_prods_ll.Clear
		Log("Positivo")
		B4XPages.ShowPage("Cliente")
	Else
		Log("NO Positivo")
		p_vistaPreviaTrans.Visible = False
	End If
	' Else
	' Msgbox("CLIENTE YA SE TRANSMITIO, FAVOR DE LLAMAR A SOPORTE PARA ASISTENCIA","AVISO") 'ignore
	' End If
	p_vistaPreviaTrans.Visible=False
	B4XPages.ShowPage("Cliente")
End Sub

Private Sub b_aceptar_Click
	p_vistaPreviaTrans.Visible=False
	B4XPages.ShowPage("Cliente")
End Sub

'Private Sub lv_prodsPedido_ItemLongClick (Position As Int, Value As Object)
'	Private sDate,sTime, clie_id, usuario As String
'	Log(Value)
'	Private X() As String = Regex.Split(" ", Value)
'	' Log(X.Length)
'	Private nom As String = ""
'	For i = 0 To X.Length -1
'		If X(i).Contains(CRLF) Then
'		End If
'		If Not(X(i).Contains(CRLF)) Then
'			nom = nom & " " & X(i)
'		Else
'			Exit
'		End If
'	Next
'	nom = nom.Trim
'	Log(nom)
'	Private cedis As String = X(X.Length-1)
'	Log(cedis)
'	' If Not(Subs.pedidoGuardado) Then
'	result =  Msgbox2("Seguro que desea borrar este articulo?","Borrar Articulo", "Si", "", "No",LoadBitmap(File.DirAssets,"alert2.png")) 'ignore
'	If result = DialogResponse.POSITIVE Then
'		c =B4XPages.MainPage.skmt.ExecQuery2("select PE_PROID,PE_CANT, PE_FOLIO FROM PEDIDO where pe_pronombre = ? and pe_cliente in (Select CUENTA from cuentaa) AND PE_CEDIS = ? ", Array As String(nom, cedis))
'		c.Position = 0
'		Log(vamoaver.Get(Position))
'		If vamoaver.Get(Position) = "VENTA" Then
'			Log("CAT_GUNAPROD2")
'			Log(Position)
'			Log(Value)
'			Starter.tabla = "CAT_GUNAPROD2"
'		Else
'			Log("CAT_GUNAPROD")
'			Log(Position)
'			Log(Value)
'			Starter.tabla = "CAT_GUNAPROD"
'		End If
'		Log(Subs.traeAlmacen)
'		' B4XPages.MainPage.skmt.ExecNonQuery2($"update ${Starter.tabla} set cat_gp_almacen = cat_gp_almacen + ? where cat_gp_id = ?"$, Array As Object(c.GetString("PE_CANT"),c.GetString("PE_PROID")))
'		' Log(c.GetString("PE_CANT"))
'		B4XPages.MainPage.skmt.ExecNonQuery2("INSERT INTO  INVENT_X_ENVIAR (ALMACEN , PROID , CANTIDAD ) VALUES(?,?,?) ", Array As Object (Subs.traeAlmacen,c.GetString("PE_PROID"),c.GetString("PE_CANT")* -1))
'		' c2=B4XPages.MainPage.skmt.ExecQuery2($"select count(*) AS CUANTOS from ${Starter.tabla} where  CAT_GP_ID in (select pe_cedis from pedido where pe_pronombre = ? and pe_cliente in (Select CUENTA from cuentaa)) and CAT_GP_CLASIF = 'PROMOS' AND CAT_GP_TIPO = 'PROMOS' AND CAT_GP_SUBTIPO = 'PROMOS'"$, Array As String(Value))
'		' c2.Position=0
'		If cedis <> Subs.traeAlmacen Then
'			j3 = B4XPages.MainPage.skmt.ExecQuery2("SELECT PE_CEDIS, PE_CANT,PE_PROID, PE_PRONOMBRE, PE_FOLIO FROM PEDIDO WHERE PE_CEDIS IN (SELECT PE_CEDIS FROM PEDIDO WHERE PE_PRONOMBRE = ? and PE_CEDIS = ?)",Array As String(nom,cedis))
'			Log(j3.RowCount)
'			If j3.RowCount > 0 Then
'				Log("Soy promo")
'				For j = 0 To j3.RowCount -1
'					Log("aqui tronare?")
'					j3.Position = j
'					Log(j3.GetString("PE_CANT"))
'					Log($"update ${Starter.tabla} set CAT_GP_ALMACEN = CAT_GP_ALMACEN + '${j3.GetString("PE_CANT")}' where CAT_GP_ID = '${j3.GetString("PE_PROID")}'"$)
'					If vamoaver.Get(Position) = "PREVENTA_CREDITO" Then
'						Starter.skmt.ExecNonQuery($"update CAT_GUNAPROD4 set CAT_GP_ALMACEN = CAT_GP_ALMACEN + ${j3.GetString("PE_CANT")} where CAT_GP_ID = '${j3.GetString("PE_PROID")}'"$)
'						B4XPages.MainPage.skmt.ExecNonQuery($"delete from pedido where pe_cedis= '${cedis}' and pe_cliente in (Select CUENTA from cuentaa) AND PE_FOLIO = '${j3.GetString("PE_FOLIO")}' AND PE_PROID = '${j3.GetString("PE_PROID")}'"$)', Array As Object(cedis, c.GetString("PE_FOLIO")))
'					Else
'						Starter.skmt.ExecNonQuery($"update ${Starter.tabla} set CAT_GP_ALMACEN = CAT_GP_ALMACEN + ${j3.GetString("PE_CANT")} where CAT_GP_ID = '${j3.GetString("PE_PROID")}'"$)
'						B4XPages.MainPage.skmt.ExecNonQuery($"delete from pedido where pe_cedis= '${cedis}' and pe_cliente in (Select CUENTA from cuentaa) AND PE_FOLIO = '${j3.GetString("PE_FOLIO")}' AND PE_PROID = '${j3.GetString("PE_PROID")}'"$)', Array As Object(cedis, c.GetString("PE_FOLIO")))
'					End If
'				Next
'			End If
'			j3.Close
'		Else
'			Log(c.GetString("PE_CANT"))
'			Log(c.Getstring("PE_PROID"))
'			If vamoaver.Get(Position) = "PREVENTA_CREDITO" Then
'				B4XPages.MainPage.skmt.ExecNonQuery($"update CAT_GUNAPROD4 set cat_gp_almacen = cat_gp_almacen + ${c.GetString("PE_CANT")} where cat_gp_id = '${c.Getstring("PE_PROID")}'"$)
'				B4XPages.MainPage.skmt.ExecNonQuery2("delete from pedido where pe_pronombre = ? and pe_cedis = ? and pe_cliente in (Select CUENTA from cuentaa) AND PE_FOLIO = ?", Array As Object(nom, cedis, vamoaver.Get(Position)))
'			Else
'				B4XPages.MainPage.skmt.ExecNonQuery($"update ${Starter.tabla} set cat_gp_almacen = cat_gp_almacen + ${c.GetString("PE_CANT")} where cat_gp_id = '${c.Getstring("PE_PROID")}'"$)
'				B4XPages.MainPage.skmt.ExecNonQuery2("delete from pedido where pe_pronombre = ? and pe_cedis = ? and pe_cliente in (Select CUENTA from cuentaa) AND PE_FOLIO = ?", Array As Object(nom, cedis, vamoaver.Get(Position)))
'			End If
'		End If
'		c.Close
'		' c2.Close
'		DateTime.DateFormat = "MM/dd/yyyy"
'		sDate=DateTime.Date(DateTime.Now)
'		sTime=DateTime.Time(DateTime.Now)
'		c=B4XPages.MainPage.skmt.ExecQuery("Select CUENTA from cuentaa")
'		c.Position=0
'		clie_id = c.GetString("CUENTA")
'		c=B4XPages.MainPage.skmt.ExecQuery("select USUARIO from usuarioa")
'		c.Position=0
'		usuario = c.GetString("USUARIO")
'		c=B4XPages.MainPage.skmt.ExecQuery("select sum(pe_costo_tot) as TOTAL_CLIE, SUM(PE_CANT) AS CANT_CLIE, count(*) as CUANTOS FROM PEDIDO WHERE PE_CLIENTE IN (Select CUENTA from cuentaa)")
'		c.Position=0
'		If c.GetString("CUANTOS") > 0 Then
'			Log("aqui5")
'			B4XPages.MainPage.skmt.ExecNonQuery("delete from pedido_cliente where PC_CLIENTE In (select cuenta from cuentaa)")
'			B4XPages.MainPage.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"), B4XPages.MainPage.lon_gps, B4XPages.MainPage.lat_gps))
'			B4XPages.MainPage.skmt.ExecNonQuery("delete from pedido_cliente where PC_CLIENTE In (select cuenta from cuentaa)")
'			B4XPages.MainPage.skmt.ExecNonQuery("UPDATE kmt_info set gestion = 0  where CAT_CL_CODIGO In (select cuenta from cuentaa)")
'			Private h As Cursor = B4XPages.MainPage.skmt.ExecQuery("select sum(PE_CANT) as PC_NOART, sum (PE_COSTO_TOT) as PC_MONTO from PEDIDO where PE_CLIENTE in (Select CUENTA from cuentaa) AND PE_PROID NOT IN (SELECT CAT_PA_ID FROM PROMOS_COMP )")
'			Log($"select sum(PE_CANT) as PC_NOART, sum (PE_COSTO_TOT) as PC_MONTO from PEDIDO where PE_CLIENTE in (Select CUENTA from cuentaa) AND PE_PROID NOT IN (SELECT CAT_PA_ID FROM PROMOS_COMP )"$)
'			h.Position=0
'			l_cant.Text = h.GetString("PC_NOART")
'			l_total2.Text = h.GetString("PC_MONTO")
'			h.Close
'		Else
'			Log("aqui6")
'			B4XPages.MainPage.skmt.ExecNonQuery("delete from pedido_cliente where PC_CLIENTE In (select cuenta from cuentaa)")
'			B4XPages.MainPage.skmt.ExecNonQuery("UPDATE kmt_info set gestion = 0  where CAT_CL_CODIGO In (select cuenta from cuentaa)")
'			Private h As Cursor = B4XPages.MainPage.skmt.ExecQuery("select sum(PE_CANT) as PC_NOART, sum (PE_COSTO_TOT) as PC_MONTO from PEDIDO where PE_CLIENTE in (Select CUENTA from cuentaa) AND PE_PROID NOT IN (SELECT CAT_PA_ID FROM PROMOS_COMP )")
'			h.Position=0
'			l_cant.Text = 0
'			l_total2.Text = 0
'			h.Close
'		End If
'		b_terminar1_Click
'	End If
'	' Else
'	' ToastMessageShow("Esta venta ya esta guardada, no se puede editar ni borrar.", False)
'	' End If
'End Sub

'Private Sub lv_prodsPedido_ItemLongClick (Position As Int, Value As Object)
'	Private sDate, sTime, clie_id, usuario As String
'    
'	' 1. Extraer el nombre del producto del texto del ListView
'	' (Separamos por espacio y reconstruimos hasta encontrar el salto de línea)
'	Private X() As String = Regex.Split(" ", Value)
'	Private nom As String = ""
'	For i = 0 To X.Length - 1
'		If Not(X(i).Contains(CRLF)) Then
'			nom = nom & " " & X(i)
'		Else
'			' El nombre termina donde empieza el CRLF (Cantidad...)
'			Dim partes() As String = Regex.Split(CRLF, X(i))
'			nom = nom & " " & partes(0)
'			Exit
'		End If
'	Next
'	nom = nom.Trim
'    
'	' Extraer el CEDIS (Almacén) que viene al final de la cadena
'	Private cedis As String = X(X.Length - 1).Trim
'
'	result = Msgbox2("¿Seguro que desea borrar este artículo?", "Borrar Artículo", "Si", "", "No", LoadBitmap(File.DirAssets, "alert2.png"))
'    
'	If result = DialogResponse.POSITIVE Then
'		' 2. BUSQUEDA ESPECÍFICA: Traemos los datos de la presentación exacta que el usuario clickeó
'		' Usamos PE_PRONOMBRE y PE_CEDIS para identificar la fila
'		Dim q As String = "SELECT PE_PROID, PE_CANT, PE_FOLIO, PE_PRESENTACION, PE_UVM, PE_DIRIGIDA " & _
'                          "FROM PEDIDO WHERE PE_PRONOMBRE = ? AND PE_CEDIS = ? " & _
'                          "AND PE_CLIENTE IN (SELECT CUENTA FROM CUENTAA)"
'        
'		c = B4XPages.MainPage.skmt.ExecQuery2(q, Array As String(nom, cedis))
'        
'		If c.RowCount > 0 Then
'			c.Position = 0
'			Dim idProd As String = c.GetString("PE_PROID")
'			Dim cantRegresar As Int = c.GetInt("PE_CANT")
'			Dim folioActual As String = c.GetString("PE_FOLIO")
'			Dim presName As String = c.GetString("PE_PRESENTACION")
'			Dim uvmVal As String = c.GetString("PE_UVM")
'			Dim dirTarget As String = c.GetString("PE_DIRIGIDA")
'
'			' 3. DEVOLVER AL INVENTARIO (Tabla dinámica según el folio)
'			Dim tablaInventario As String = Starter.tabla
'			If folioActual = "PREVENTA_CREDITO" Then tablaInventario = "CAT_GUNAPROD4"
'            
'			B4XPages.MainPage.skmt.ExecNonQuery($"UPDATE ${tablaInventario} SET CAT_GP_ALMACEN = CAT_GP_ALMACEN + ${cantRegresar} WHERE CAT_GP_ID = '${idProd}'"$)
'
'			' 4. REGISTRAR MOVIMIENTO EN INVENTARIO (Opcional pero recomendado)
'			B4XPages.MainPage.skmt.ExecNonQuery2("INSERT INTO INVENT_X_ENVIAR (ALMACEN, PROID, CANTIDAD) VALUES(?,?,?)", _
'                Array As Object(cedis, idProd, cantRegresar * -1))
'
'			' 5. BORRADO QUIRÚRGICO: Usamos todos los criterios para no borrar otras presentaciones
'			Dim qDelete As String = "DELETE FROM PEDIDO WHERE PE_PROID = ? AND PE_PRESENTACION = ? " & _
'                                    "AND PE_UVM = ? AND PE_DIRIGIDA = ? AND PE_CEDIS = ? " & _
'                                    "AND PE_CLIENTE IN (SELECT CUENTA FROM CUENTAA)"
'            
'			B4XPages.MainPage.skmt.ExecNonQuery2(qDelete, Array As Object(idProd, presName, uvmVal, dirTarget, cedis))
'            
'			LogColor("Borrado exitoso: " & nom & " (" & presName & ")", Colors.Green)
'		End If
'		c.Close
'
'		' 6. RECALCULAR TOTALES Y REFRESCAR VISTA
'		ActualizarTotalesPedido(clienteId)
'        
'		' Volvemos a llamar al método que arma el panel de vista previa para que desaparezca el item
'		b_terminar1_Click
'	End If
'End Sub

Private Sub lv_prodsPedido_ItemLongClick (Position As Int, Value As Object)
	' 1. VALIDACIÓN: Si Value no es un Mapa, hay un error en el llenado
	If Not(Value Is Map) Then
		Log("Error: El valor recibido no es un Mapa de datos.")
		Return
	End If

	' 2. EXTRAER DIRECTAMENTE DE LAS LLAVES DEL MAPA
	Dim datos As Map = Value
	Dim idProd As String = datos.Get("id")
	Dim nom As String = datos.Get("nombre")
	Dim presName As String = datos.Get("pres")
	Dim uvmVal As Int = datos.Get("uvm")
	Dim cedis As String = datos.Get("cedis")
	Dim dirTarget As String = datos.Get("dir")
	Dim folioActual As String = datos.Get("folio")
	Dim cantRegresar As Int = datos.Get("cant")
	Log(cedis)
	Log(folioActual)
	' Log de depuración para confirmar que los datos vienen limpios
	Log("Intentando borrar -> ID: " & idProd & " | Nombre: " & nom & " | Almacen: " & cedis)

	result = Msgbox2("¿Seguro que desea borrar " & nom & " (" & presName & ")?", "Borrar Artículo", "Si", "", "No", LoadBitmap(File.DirAssets, "alert2.png"))
    
	If result = DialogResponse.POSITIVE Then
		' 3. DEVOLVER AL INVENTARIO (Tabla dinámica)
		Dim tablaInventario As String
'		If folioActual = "PREVENTA_CREDITO" Then tablaInventario = "CAT_GUNAPROD4"
		If folioActual = "PREVENTA_CONTADO" Or folioActual = "ABORDO" Then
			tablaInventario = "CAT_GUNAPROD"
			Log("1")
		Else If folioActual = "VENTA" Then
			tablaInventario = "CAT_GUNAPROD2"
			Log(2)
		Else If folioActual = "RECARGA" Then
			tablaInventario = "CAT_GUNAPROD"
			Log(3)
		Else If folioActual = "PREVENTA_CREDITO" Then
			tablaInventario = "CAT_GUNAPROD4"
			Log(4)
		End If
		
		
		If cedis <> Subs.traeAlmacen Then
			Log("entre")
			j3 = B4XPages.MainPage.skmt.ExecQuery2("SELECT PE_CEDIS, PE_CANT,PE_PROID, PE_PRONOMBRE, PE_FOLIO FROM PEDIDO WHERE PE_CEDIS IN (SELECT PE_CEDIS FROM PEDIDO WHERE PE_PRONOMBRE = ? and PE_CEDIS = ?) AND PE_FOLIO = ?",Array As String(nom,cedis,folioActual))
			Log(j3.RowCount)
			If j3.RowCount > 0 Then
				Log("Soy promo")
				For j = 0 To j3.RowCount -1
					Log("aqui tronare?")
				
					j3.Position = j
					Log(j3.GetString("PE_CANT"))
					Log($"update ${tablaInventario} set CAT_GP_ALMACEN = CAT_GP_ALMACEN + '${j3.GetString("PE_CANT")}' where CAT_GP_ID = '${j3.GetString("PE_PROID")}'"$)
					If vamoaver.Get(Position) = "PREVENTA_CREDITO" Then
						Starter.skmt.ExecNonQuery($"update CAT_GUNAPROD4 set CAT_GP_ALMACEN = CAT_GP_ALMACEN + ${j3.GetString("PE_CANT")} where CAT_GP_ID = '${j3.GetString("PE_PROID")}'"$)
						B4XPages.MainPage.skmt.ExecNonQuery($"delete from pedido where pe_cedis= '${cedis}' and pe_cliente in (Select CUENTA from cuentaa) AND PE_FOLIO = '${j3.GetString("PE_FOLIO")}' AND PE_PROID = '${j3.GetString("PE_PROID")}'"$)', Array As Object(cedis, c.GetString("PE_FOLIO")))
					Else
						Starter.skmt.ExecNonQuery($"update ${tablaInventario} set CAT_GP_ALMACEN = CAT_GP_ALMACEN + ${j3.GetString("PE_CANT")} where CAT_GP_ID = '${j3.GetString("PE_PROID")}'"$)
						B4XPages.MainPage.skmt.ExecNonQuery($"delete from pedido where pe_cedis= '${cedis}' and pe_cliente in (Select CUENTA from cuentaa) AND PE_FOLIO = '${j3.GetString("PE_FOLIO")}' AND PE_PROID = '${j3.GetString("PE_PROID")}'"$)', Array As Object(cedis, c.GetString("PE_FOLIO")))
								
					End If
				Next
			End If
			j3.Close
		
			ActualizarTotalesPedido(clienteId)
			b_terminar1_Click
			
		Else
			  
			B4XPages.MainPage.skmt.ExecNonQuery($"UPDATE ${tablaInventario} SET CAT_GP_ALMACEN = CAT_GP_ALMACEN + ${cantRegresar} WHERE CAT_GP_ID = '${idProd}'"$)

			' 4. REGISTRAR MOVIMIENTO
			B4XPages.MainPage.skmt.ExecNonQuery2("INSERT INTO INVENT_X_ENVIAR (ALMACEN, PROID, CANTIDAD) VALUES(?,?,?)", _
            Array As Object(cedis, idProd, cantRegresar * -1))

			' 5. BORRADO QUIRÚRGICO (Usando los datos exactos del Map)
			Dim qDelete As String = "DELETE FROM PEDIDO WHERE PE_PROID = ? AND PE_PRESENTACION = ? " & _
                                "AND PE_UVM = ? AND PE_DIRIGIDA = ? AND PE_CEDIS = ? " & _
                                "AND PE_CLIENTE IN (SELECT CUENTA FROM CUENTAA) AND PE_FOLIO = ?"
        
			B4XPages.MainPage.skmt.ExecNonQuery2(qDelete, Array As Object(idProd, presName, uvmVal, dirTarget, cedis, folioActual))
        
			LogColor("Borrado exitoso de base de datos.", Colors.Green)

			' 6. REFRESCAR TOTALES Y LISTA
			ActualizarTotalesPedido(clienteId)
			b_terminar1_Click
		End If
		
      
	End If
End Sub

' Sub auxiliar para mantener limpia la lógica de base de datos
Private Sub ActualizarTotalesPedido(idClie As String)
	DateTime.DateFormat = "MM/dd/yyyy"
	Dim sDate As String = DateTime.Date(DateTime.Now)
	Dim sTime As String = DateTime.Time(DateTime.Now)
    
	' Traemos el total actualizado
	Dim h As Cursor = B4XPages.MainPage.skmt.ExecQuery("SELECT SUM(PE_CANT) as PC_NOART, SUM(PE_COSTO_TOT) as PC_MONTO FROM PEDIDO WHERE PE_CLIENTE = '" & idClie & "'")
	h.Position = 0
    
	If h.RowCount > 0 And h.GetString("PC_NOART") <> Null Then
		' Actualizamos tabla encabezado (pedido_cliente)
		B4XPages.MainPage.skmt.ExecNonQuery("DELETE FROM pedido_cliente WHERE PC_CLIENTE = '" & idClie & "'")
        
		Dim usuario As String = Subs.traeUsuarioDeBD 'Asumiendo que tienes este helper
		B4XPages.MainPage.skmt.ExecNonQuery2("INSERT INTO pedido_cliente(PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO, PC_LON, PC_LAT) VALUES (?,?,?,?,?,?,?)", _
            Array As Object(idClie, sDate & " " & sTime, usuario, h.GetString("PC_NOART"), h.GetString("PC_MONTO"), B4XPages.MainPage.lon_gps, B4XPages.MainPage.lat_gps))
            
		l_cant.Text = h.GetString("PC_NOART")
		l_total2.Text = NumberFormat2(h.GetDouble("PC_MONTO"), 1, 2, 2, False)
	Else
		' Si ya no queda nada en el pedido
		B4XPages.MainPage.skmt.ExecNonQuery("DELETE FROM pedido_cliente WHERE PC_CLIENTE = '" & idClie & "'")
		B4XPages.MainPage.skmt.ExecNonQuery("UPDATE kmt_info SET gestion = 0 WHERE CAT_CL_CODIGO = '" & idClie & "'")
		l_cant.Text = "0"
		l_total2.Text = "0.00"
	End If
	h.Close
End Sub

Private Sub clv_prods_ll_ItemClick (Index As Int, Value As Object)
End Sub

Sub l_prodx_click
	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)
	Private cant1 As B4XView = p.GetView(2).GetView(2)
	Dim index As Int = clv_prods_ll.GetItemFromView(Sender)
	' Log(clv_prods_ll.GetValue(index))
	Log(cant1.Text)
End Sub

'Private Sub clv_prods_ll_VisibleRangeChanged (FirstIndex As Int, LastIndex As Int)
'	' Log para confirmar en el IDE que el evento se está disparando
'	Log("Dibujando rango: " & FirstIndex & " a " & LastIndex)
'    
'	For i = Max(0, FirstIndex - 2) To Min(LastIndex + 2, clv_prods_ll.Size - 1)
'		Dim Pnl As B4XView = clv_prods_ll.GetPanel(i)
'        
'		If i >= FirstIndex And i <= LastIndex Then
'			' Solo dibujamos si el panel está vacío para evitar duplicados
'			If Pnl.NumberOfViews = 0 Then
'				Dim data As Map = clv_prods_ll.GetValue(i)
'                
'				' 1. CREAR BASE (Tarjeta del producto)
'				' Usamos color Rojo para confirmar visualmente que el panel existe
'				Dim base As B4XView = xui.CreatePanel("")
'				base.Color = Colors.Red
'                
'				' Añadimos la base al panel del ítem ocupando todo su espacio
'				Pnl.AddView(base, 0, 0, Pnl.Width, Pnl.Height)
'                
'				' 2. TÍTULO DEL PRODUCTO
'				Dim lblNom As Label : lblNom.Initialize("")
'				Dim xlbl As B4XView = lblNom
'				xlbl.Text = data.Get("prod")
'				xlbl.TextColor = Colors.Yellow ' Amarillo para resaltar sobre rojo
'				xlbl.Font = xui.CreateDefaultBoldFont(16)
'				lblNom.Gravity = Bit.Or(Gravity.LEFT, Gravity.CENTER_VERTICAL)
'				
'				' Posicionamos el título en la parte superior
'				base.AddView(xlbl, 10dip, 5dip, base.Width - 20dip, 35dip)
'                
'				' 3. DIBUJAR PRESENTACIONES (Filas dinámicas)
'				Dim presentaciones As List = data.Get("presentaciones")
'				Dim vTop As Int = 45dip ' Coordenada inicial debajo del título
'                
'				For Each pres As Map In presentaciones
'					' Label de Presentación y Precio
'					Dim lblP As Label : lblP.Initialize("")
'					lblP.Text = pres.Get("nombre") & " $" & pres.Get("precio")
'					lblP.TextColor = Colors.White
'					lblP.TextSize = 14
'					base.AddView(lblP, 10dip, vTop, 160dip, 40dip)
'					
'					' Botón de acción (+)
'					Dim bP As Button : bP.Initialize("btnMasDinamico")
'					bP.Text = "+"
'					bP.Tag = CreateMap("id": data.Get("id"), "col": pres.Get("col_index"), "pres": pres)
'					
'					' Posicionamos el botón a la derecha
'					base.AddView(bP, base.Width - 65dip, vTop, 55dip, 40dip)
'                    
'					' Incrementamos el espacio vertical para la siguiente presentación
'					vTop = vTop + 55dip
'				Next
'			End If
'		Else
'			' Si el ítem sale del rango visible, removemos las vistas para liberar memoria
'			If Pnl.NumberOfViews > 0 Then
'				Pnl.RemoveAllViews
'			End If
'		End If
'	Next
'End Sub


Private Sub clv_prods_ll_VisibleRangeChanged (FirstIndex As Int, LastIndex As Int)
	For i = Max(0, FirstIndex - 2) To Min(LastIndex + 2, clv_prods_ll.Size - 1)
		Dim Pnl As B4XView = clv_prods_ll.GetPanel(i)
        
		If i >= FirstIndex And i <= LastIndex Then
			If Pnl.NumberOfViews = 0 Then
				Dim data As Map = clv_prods_ll.GetValue(i)
                
				' 1. FONDO DE LA TARJETA CON ESQUINAS REDONDEADAS Y BORDE
				Dim base As B4XView = xui.CreatePanel("")
                
				' Parámetros: Color de fondo, Grosor del borde, Color del borde, Radio de redondeo
				' Usamos un radio de 8dip para un aspecto suave y un borde gris claro (0xFFD3D3D3)
				base.SetColorAndBorder(xui.Color_White, 1dip, xui.Color_Black, 8dip)
                
				' Agregamos el panel base al contenedor del ítem
				Pnl.AddView(base, 5dip, 2dip, Pnl.Width - 10dip, Pnl.Height - 4dip)
                
				' 2. TÍTULO Y EXISTENCIAS (Lado Izquierdo)
				Dim cs As CSBuilder
				cs.Initialize.Color(Colors.Red).Bold.Append(data.Get("prod")).Pop.Pop _
                  .Append(CRLF).Size(12).Color(Colors.Black).Append("Existencias: " & data.Get("almacen")).Pop
                
				Dim lblInfo As Label : lblInfo.Initialize("")
				Dim xlbl As B4XView = lblInfo
				xlbl.Text = cs
				lblInfo.Gravity = Gravity.TOP
				base.AddView(xlbl, 10dip, 8dip, base.Width * 0.55, 45dip)
				
				' 3. FILAS DE PRESENTACIONES (Lado Derecho)
				Dim presentaciones As List = data.Get("presentaciones")
				Dim vTop As Int = 10dip

				For Each pres As Map In presentaciones
					' 1. Label de Presentación (ARRIBA del botón Menos, letra más grande y NEGRO)
					Dim lblTipo As Label : lblTipo.Initialize("")
					lblTipo.Text = pres.Get("nombre")
					lblTipo.TextColor = Colors.Black  ' <--- Cambiado a Negro
					lblTipo.TextSize = 14             ' <--- Tamaño aumentado de 11 a 14
'					lblTipo.Font = xui.CreateDefaultBoldFont(14) ' <--- Negrita opcional para que resalte más
					lblTipo.Gravity = Gravity.LEFT
					
					' 1. Label de Presentación (Calculamos las unidades actuales)
					Dim cantPiezas As Int = pres.Get("cantidad")
					Dim factorUmv As Int = pres.Get("umv")
					Dim unidadesExistentes As Int = 0

					' Evitamos división por cero y calculamos cuántos paquetes/cajas hay ya pedidos
					If factorUmv > 0 Then unidadesExistentes = cantPiezas / factorUmv

					Dim lblTipo As Label : lblTipo.Initialize("")
					' Aquí concatenamos el nombre con las unidades (Ej: PAQUETE: 2)
					lblTipo.Text = pres.Get("nombre").As(String).ToUpperCase & ": " & unidadesExistentes
					lblTipo.TextColor = Colors.Black
					lblTipo.TextSize = 14
					lblTipo.Gravity = Gravity.LEFT
					
					' Posicionado exactamente arriba del botón menos (Width - 145dip)
					' Aumentamos la altura del label a 22dip por el tamaño de letra
					base.AddView(lblTipo, base.Width - 145dip, vTop, 140dip, 22dip)
    
					' 2. Precio (Verde) - Alineado a la izquierda de la caja de botones
					Dim lblPrice As Label : lblPrice.Initialize("")
					lblPrice.Text = "$" & NumberFormat2(pres.Get("precio"), 1, 2, 2, False)
					lblPrice.TextColor = 0xFF008000
					lblPrice.TextSize = 14            ' <--- También aumentamos el precio para equilibrio visual
					lblPrice.Gravity = Gravity.CENTER_VERTICAL
					base.AddView(lblPrice, base.Width - 215dip, vTop + 22dip, 65dip, 42dip)
					
					' --- CONTROLES DE CANTIDAD (Bajamos vTop + 22dip para dar espacio al label grande) ---
					Dim bM As Button : bM.Initialize("btnMenosDinamico")
					bM.Text = "-" : bM.TextColor = Colors.White : bM.Color = 0xFFF4511E
					
					Dim et As EditText : et.Initialize("etCantDinamico")
					et.Text = pres.Get("cantidad")
					et.InputType = et.INPUT_TYPE_NUMBERS
					et.Gravity = Gravity.CENTER
					et.Background = Null
					
					Dim bP As Button : bP.Initialize("btnMasDinamico")
					bP.Text = "+" : bP.TextColor = Colors.White : bP.Color = 0xFF000080
					
					Dim tagInfo As Map = CreateMap("id": data.Get("id"), "col": pres.Get("col_index"), "et": et, "pres": pres, "almacen": data.Get("almacen"))
					bM.Tag = tagInfo : bP.Tag = tagInfo : et.Tag = tagInfo
					
					' Posicionamiento de controles (vTop + 22dip para que no choque con el label negro)
					base.AddView(bM, base.Width - 145dip, vTop + 22dip, 38dip, 42dip)
					base.AddView(et, base.Width - 105dip, vTop + 22dip, 45dip, 42dip)
					base.AddView(bP, base.Width - 58dip, vTop + 22dip, 38dip, 42dip)
					
					' Incrementamos el salto de fila a 75dip para que la siguiente presentación tenga aire
					vTop = vTop + 75dip
					et.Enabled = False
					et.TextColor = Colors.Black
				Next
			End If
		Else
			If Pnl.NumberOfViews > 0 Then Pnl.RemoveAllViews
		End If
	Next
End Sub

'Sub Busca_TextChanged (Old As String, New As String)
'	' Private inicioContador As String = DateTime.Now
'	If Not(clv_prods_ll.AsView.Visible) Then clv_prods_ll.AsView.Visible = True
'	If (New.Length = 1 Or New.Length = 2) And Not(forzarBusqueda) Then Return
'	forzarBusqueda = False
'	clv_prods_ll.Clear
'	listaProds.Initialize
'	listaHints.Initialize
'	Sleep(0)
'	' Dim p As ResultSet = B4XPages.MainPage.skmt.ExecQuery($"select CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_GP_PRECIO, CAT_GP_TIPOPROD from ${Starter.tabla} where CAT_GP_NOMBRE like '%${New}%' and CAT_GP_PRECIO > 0 AND CAT_GP_ALMACEN > 0 and CAT_GP_CLASIF <> 'PROMOS' order by CAT_GP_NOMBRE"$)
'	If Subs.traeTipoCliente = "0" Then
'		Log("AQUI")
'		Dim p As ResultSet = B4XPages.MainPage.skmt.ExecQuery($"select distinct CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_GP_PRECIO, CAT_GP_TIPOPROD, CAT_DP_CONVERSION1, CAT_DP_PRECIO4, PE_BCAJAS from ${Starter.tabla} LEFT JOIN PEDIDO ON CAT_GP_ID = PE_PROID where CAT_GP_NOMBRE like '%${New}%' AND CAT_GP_PRECIO > 0 And CAT_GP_ALMACEN > 0 And CAT_GP_CLASIF <> 'PROMOS' union all select CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_GP_PRECIO, CAT_GP_TIPOPROD, CAT_DP_CONVERSION1, CAT_DP_PRECIO4 , PE_BCAJAS from ${Starter.tabla} LEFT JOIN PEDIDO ON CAT_GP_ID = PE_PROID where CAT_GP_PRECIO > 0 And CAT_GP_ALMACEN = 0 And CAT_GP_CLASIF <> 'PROMOS' and cat_gp_id in (select pe_proid from pedido where pe_cliente in (select cuenta from cuentaa)) order by 2"$)
'		' B4XPages.MainPage.skmt.ExecQuery($"select DISTINCT CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_GP_PRECIO, CAT_GP_TIPOPROD, CAT_DP_CONVERSION1, CAT_DP_PRECIO4, PE_BCAJAS from ${Starter.tabla} LEFT JOIN PEDIDO ON CAT_GP_ID = PE_PROID where CAT_GP_NOMBRE like '%${New}%' AND CAT_GP_PRECIO > 0 And CAT_GP_ALMACEN > 0 And CAT_GP_CLASIF <> 'PROMOS' union all select DISTINCT CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_GP_PRECIO, CAT_GP_TIPOPROD, CAT_DP_CONVERSION1, CAT_DP_PRECIO4 , PE_BCAJAS from ${Starter.tabla} LEFT JOIN PEDIDO ON CAT_GP_ID = PE_PROID where CAT_GP_PRECIO > 0 And CAT_GP_ALMACEN = 0 And CAT_GP_CLASIF <> 'PROMOS' and cat_gp_id in (select pe_proid from pedido where pe_cliente in (select cuenta from cuentaa)) order by 2"$)
'	Else
'		Log("AQUI2")
'		Dim p As ResultSet = B4XPages.MainPage.skmt.ExecQuery($"select distinct CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_DP_PRECIO${Subs.traeTipoCliente} as CAT_GP_PRECIO, CAT_GP_TIPOPROD, CAT_DP_CONVERSION1, CAT_DP_PRECIO4, PE_BCAJAS from ${Starter.tabla} LEFT JOIN PEDIDO ON CAT_GP_ID = PE_PROID where CAT_GP_NOMBRE like '%${New}%' AND CAT_DP_PRECIO${Subs.traeTipoCliente} > 0 And CAT_GP_ALMACEN > 0 And CAT_GP_CLASIF <> 'PROMOS' union all select CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_DP_PRECIO${Subs.traeTipoCliente} AS CAT_GP_PRECIO, CAT_GP_TIPOPROD, CAT_DP_CONVERSION1, CAT_DP_PRECIO4 , PE_BCAJAS from ${Starter.tabla} LEFT JOIN PEDIDO ON CAT_GP_ID = PE_PROID where CAT_DP_PRECIO${Subs.traeTipoCliente} > 0 And CAT_GP_ALMACEN = 0 And CAT_GP_CLASIF <> 'PROMOS' and cat_gp_id in (select pe_proid from pedido where pe_cliente in (select cuenta from cuentaa)) order by 2"$)
'	End If
'	' Dim p As ResultSet = B4XPages.MainPage.skmt.ExecQuery($"select DISTINCT CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_GP_PRECIO, CAT_GP_TIPOPROD, CAT_DP_CONVERSION1, CAT_DP_PRECIO4, PE_BCAJAS from ${Starter.tabla} LEFT JOIN PEDIDO ON CAT_GP_ID = PE_PROID where CAT_GP_NOMBRE like '%${New}%' AND CAT_GP_PRECIO > 0 And CAT_GP_ALMACEN > 0 And CAT_GP_CLASIF <> 'PROMOS' union all select DISTINCT CAT_GP_ID, CAT_GP_NOMBRE, CAT_GP_ALMACEN, CAT_GP_PRECIO, CAT_GP_TIPOPROD, CAT_DP_CONVERSION1, CAT_DP_PRECIO4 , PE_BCAJAS from ${Starter.tabla} LEFT JOIN PEDIDO ON CAT_GP_ID = PE_PROID where CAT_GP_PRECIO > 0 And CAT_GP_ALMACEN = 0 And CAT_GP_CLASIF <> 'PROMOS' and cat_gp_id in (select pe_proid from pedido where pe_cliente in (select cuenta from cuentaa)) order by 2"$)
'	Log("Llamamos LlenaProdsLL")
'	LlenaProdsLL(p)
'	' Do While p.NextRow
'	' Dim tempMap As Map = CreateMap("prod":p.GetString("CAT_GP_NOMBRE"), "precio":p.GetString("CAT_GP_PRECIO"), "almacen":p.GetString("CAT_GP_ALMACEN"), "id":p.GetString("CAT_GP_ID"))
'	' listaProds.Add(tempMap)
'	' listaHints.Add(p.GetString("CAT_GP_NOMBRE"))
'	' Dim Pnl As B4XView = xui.CreatePanel("")
'	' Pnl.SetLayoutAnimated(0, 0, 0, clv_prods_ll.AsView.Width, 50dip) 'Panel height + 4 for drop shadow
'	' clv_prods_ll.Add(Pnl, tempMap)
'	' Loop
'	' LogColor(clv_prods_ll.Size, Colors.red)
'	'' Log(listaProds)
'	' p.Close
'	' PCLV.B4XSeekBar1.MaxValue = clv_prods_ll.Size
'	' PCLV.B4XSeekBar1.MinValue = 0
'	' PCLV.B4XSeekBar1.Interval = clv_prods_ll.Size/10
'	' PCLV.B4XSeekBar1.Value = clv_prods_ll.Size
'	' PCLV.B4XSeekBar1.Update
'	' Log($"Min:0, max:${clv_prods_ll.Size}, Interval:${clv_prods_ll.Size/10}"$)
'	' LogColor("TIEMPO DE PROCESO DEL TEXTCHANGED: " & ((DateTime.Now-inicioContador)/1000), Colors.Red)
'End Sub

'Sub Busca_TextChanged (Old As String, New As String)
'	' 1. Control de visibilidad inicial
'	If Not(clv_prods_ll.AsView.Visible) Then clv_prods_ll.AsView.Visible = True
'	
'	' 2. Regla de búsqueda: Esperar a que el usuario escriba al menos 3 caracteres
'	' a menos que se fuerce la búsqueda (por ejemplo, al darle al botón buscar)
'	If New.Length > 0 And New.Length < 3 And Not(forzarBusqueda) Then Return
'	
'	forzarBusqueda = False
'	
'	' 3. Construcción del Query de búsqueda
'	' Filtramos por nombre y nos aseguramos de que el producto esté activo (CAT_GP_STS = 1)
'	' No filtramos aquí por presentación ni precio, de eso se encarga LlenaProdsLL
'	Dim query As String
'	If New.Trim = "" Then
'		' Si borra el texto, cargamos todo de nuevo
'		query = $"SELECT * FROM ${Starter.tabla} WHERE CAT_GP_STS = 1 ORDER BY CAT_GP_NOMBRE"$
'	Else
'		' Búsqueda por coincidencia de nombre
'		query = $"SELECT * FROM ${Starter.tabla} WHERE CAT_GP_STS = 1 AND CAT_GP_NOMBRE LIKE '%${New}%' ORDER BY CAT_GP_NOMBRE"$
'	End If
'	
'	' 4. Ejecutar consulta
'	Dim p As ResultSet = B4XPages.MainPage.skmt.ExecQuery(query)
'	
'	' 5. Delegar el llenado de la lista a la lógica de 11 niveles
'	Log("Buscando: " & New & " - Resultados iniciales: " & p.RowCount)
'	LlenaProdsLL(p)
'End Sub

Sub Busca_TextChanged (Old As String, New As String)
	' 1. Control de visibilidad inicial
	If Not(clv_prods_ll.AsView.Visible) Then clv_prods_ll.AsView.Visible = True
	
	' 2. Regla de búsqueda: Esperar a que el usuario escriba al menos 3 caracteres
	' a menos que se fuerce la búsqueda (por ejemplo, al darle al botón buscar)
	If New.Length > 0 And New.Length < 3 And Not(forzarBusqueda) Then Return
	
	forzarBusqueda = False
	Log("Texto buscado: [" & New.Trim & "]")
	
	' 3. Construcción y Ejecución
	If New.Trim = "" Then
		' Si borra el texto, le enviamos Null.
		' Así, LlenaProdsLL usará su propia consulta por defecto que ya sabe excluir PROMOS.
		Log("Búsqueda borrada. Restaurando catálogo principal...")
		LlenaProdsLL(Null)
	Else
		' Búsqueda por coincidencia de nombre.
		' IMPORTANTE: También excluimos las PROMOS aquí para que no se cuelen en los resultados de búsqueda.
		Dim query As String = $"SELECT * FROM ${Starter.tabla} WHERE CAT_GP_STS = 1 AND CAT_GP_TIPO <> 'PROMOS' AND CAT_GP_SUBTIPO <> 'PROMOS' AND CAT_GP_NOMBRE LIKE '%${New}%' ORDER BY CAT_GP_NOMBRE"$
		Dim p As ResultSet = B4XPages.MainPage.skmt.ExecQuery(query)
		
		Log("Buscando: " & New & " - Resultados encontrados: " & p.RowCount)
		LlenaProdsLL(p)
	End If
End Sub

Sub LlenaProdsLL(p As ResultSet)
	Log("--- Iniciando LlenaProdsLL (11 Niveles) ---")
	listaProds.Initialize
	listaHints.Initialize
	cantsMap.Initialize
    
	' 1. Obtener cantidades ya pedidas para este cliente
'	If hayPedido Then
'		' Nota: Para que esto funcione, tu tabla PEDIDO debe tener
'		' una columna llamada PE_PRESENTACION_ID (donde guardas el 1, 2... al 11)
'		Dim pe As ResultSet = B4XPages.MainPage.skmt.ExecQuery($"SELECT PE_PROID, PE_DIRIGIDA, PE_CANT FROM PEDIDO WHERE PE_CLIENTE = '${clienteId}'"$)
'		Do While pe.NextRow
'			cantsMap.Put(pe.GetString("PE_PROID") & "_" & pe.GetString("PE_DIRIGIDA"), pe.GetInt("PE_CANT"))
'		Loop
'		pe.Close
'	End If
	
	If hayPedido Then
		Dim pe As ResultSet = B4XPages.MainPage.skmt.ExecQuery($"SELECT PE_PROID, PE_DIRIGIDA, PE_CANT FROM PEDIDO WHERE PE_CLIENTE = '${clienteId}' AND PE_FOLIO ='${B4XPages.MainPage.tipo_venta}'"$)
		Do While pe.NextRow
			' Guardamos la cantidad de piezas asociada a la combinación Producto_Columna
			cantsMap.Put(pe.GetString("PE_PROID") & "_" & pe.GetString("PE_DIRIGIDA"), pe.GetInt("PE_CANT"))
		Loop
		pe.Close
	End If

	' 2. Ejecutar Query si no hay búsqueda activa
	If p = Null Or p.IsInitialized = False Then
		Log(Starter.tabla)
		p = B4XPages.MainPage.skmt.ExecQuery($"SELECT * FROM ${Starter.tabla} WHERE CAT_GP_STS = 1 AND CAT_GP_TIPO <> 'PROMOS' AND CAT_GP_SUBTIPO <> 'PROMOS' ORDER BY CAT_GP_NOMBRE"$)
	End If

	' 3. Procesar resultados
	Do While p.NextRow
		Log(p.GetString("CAT_GP_ID"))
		Dim idProd As String = p.GetString("CAT_GP_ID")
		Dim presentacionesValidas As List : presentacionesValidas.Initialize
		
		' Revisamos las 11 columnas
		For i = 1 To 11
			Dim precio As Double = p.GetDouble("CAT_GP_PRECIO" & i)
			Dim presNombre As String = p.GetString("CAT_GP_PRESENTACION" & i)
			Dim dirigida As String = p.GetString("CAT_GP_DIRIGIDA" & i)
			Dim umvVal As Int = p.GetInt("CAT_GP_UMV" & i)
			Log(precio)
			Log(presNombre)
			Log(dirigida)
			Log(umvVal)
			

			' REGLA "TODO O NADA": Si los 3 datos principales existen...
			If precio > 0 And presNombre <> "" And dirigida <> ""  And umvVal > 0 Then
				' FILTRO DE CLIENTE
				Log(tipoClienteActual.ToUpperCase)
				If dirigida.ToUpperCase = tipoClienteActual.ToUpperCase Then
					Dim cantExistente As Int = cantsMap.GetDefault(idProd & "_" & i, 0)
                    
					presentacionesValidas.Add(CreateMap( _
    "col_index": i, _
    "nombre": presNombre, _
    "precio": precio, _
    "umv": umvVal, _
    "cantidad": cantExistente, _
    "dirigida": dirigida, _
	"listaprecio": i _  '<--- AGREGAR ESTO
))
				End If
			End If
		Next
		Log(presentacionesValidas)
		' Solo agregamos el producto si tiene presentaciones válidas
		If presentacionesValidas.Size > 0 Then
			listaProds.Add(CreateMap( _
                "id": idProd, _
                "prod": p.GetString("CAT_GP_NOMBRE"), _
                "almacen": p.GetInt("CAT_GP_ALMACEN"), _
                "presentaciones": presentacionesValidas _
            ))
			listaHints.Add(p.GetString("CAT_GP_NOMBRE"))
		End If
	Loop
	p.Close
'	Log(listaProds)
	' 4. Llenado del CLV
	clv_prods_ll.Clear
	PCLV.Commit

	For Each m As Map In listaProds
'		Log(m)
		Dim pnl As B4XView = xui.CreatePanel("")
		Dim lPres As List = m.Get("presentaciones")
		' Altura: 45dip de título + 60dip por cada fila de botones
		Dim alturaItem As Int = 45dip + (lPres.Size * 60dip)
        
		pnl.SetLayoutAnimated(0, 0, 0, clv_prods_ll.AsView.Width, alturaItem)
		clv_prods_ll.Add(pnl, m)
		
	Next
    
	If clv_prods_ll.Size > 0 Then
'		PCLV.B4XSeekBar1.MaxValue = clv_prods_ll.Size
'		PCLV.B4XSeekBar1.Update

		PCLV.B4XSeekBar1.MaxValue = clv_prods_ll.Size
		PCLV.B4XSeekBar1.MinValue = 0
		PCLV.B4XSeekBar1.Interval = clv_prods_ll.Size/20
		PCLV.B4XSeekBar1.Value = clv_prods_ll.Size
		PCLV.B4XSeekBar1.Update
	End If
End Sub

'Return the hint that will be displayed when the user fast scrolls the list. It can be a string or CSBuilder.
Sub PCLV_HintRequested(Index As Int) As Object
	Dim word As String = listaHints.get(Index)
	Return word
End Sub




Sub b_prodMenosc_Click
	totalcajasmaspiezas = 0
	etCantHasFocus = False
	Root.RequestFocus
	' LogColor("b_prodMenos_Click", Colors.Magenta)
	Dim index As Int = clv_prods_ll.GetItemFromView(Sender)
	Dim pnl0 As B4XView = clv_prods_ll.GetPanel(index)
	Dim pnl As B4XView = pnl0.GetView(0)
	Dim laCant As B4XView = pnl.GetView(2).GetView(2)
	Dim laCant2 As B4XView = pnl.GetView(3).GetView(2)
	Dim lProdX As B4XView = pnl.GetView(1)
	Dim panelcajas As B4XView = pnl.GetView(3)
	Dim panelpiezas As B4XView = pnl.GetView(2)
	' Log($"precio|stock:${laCant.tag}"$)
	If laCant2.Text = "" Then laCant2.Text = 0
	' Log("lacant.text="&laCant.text)
	laCant2.Text = $"${NumberFormat2(laCant2.Text-1,0,0,0,False)}"$
	If laCant2.Text < 0 Then laCant2.Text = 0
	Private tmpMap As Map = clv_prods_ll.GetValue(index).As(Map)
	Private precio As String=clv_prods_ll.GetValue(index).As(Map).Get("precio")
	Private id As String=clv_prods_ll.GetValue(index).As(Map).Get("id")
	Private tmpMap As Map = CreateMap("precio":precio, "cant":laCant2.Text, "almacen":Subs.traeAlmacen)
	Private nombreX As String = Subs.traeProdNombre(id)
	Private conversion As String = clv_prods_ll.GetValue(index).As(Map).Get("conversion")
	Private preciocaja As String = clv_prods_ll.GetValue(index).As(Map).Get("precio_caja")
	Log(tmpMap)
	' prodsMap.Put(id, tmpMap)
	If laCant2.Text = 0 Then prodsMap.Remove(id)
	If laCant2.Text = 0 Then
		panelpiezas.Visible = True
	Else If laCant2.Text > 0 Or clv_prods_ll.GetValue(index).As(Map).Get("conversion") < clv_prods_ll.GetValue(index).As(Map).Get("almacen") Then
		panelpiezas.Visible = False
	End If
	' If laCant.IsInitialized Then
	' totalcajasmaspiezas = laCant.Text + laCant2.Text
	' Else
	' totalcajasmaspiezas = laCant2.Text
	' End If
	LogColor("prodsMap="&prodsMap, Colors.blue)
	' (Subs.traeAlmacen, p1.Get("precio"), p1.Get("cant"), pn, p, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta)
	Log($"${Subs.traeAlmacen}, ${precio}, ${laCant2.text}, ${Subs.traeProdNombre(id)}, ${id}, ${clienteId}"$)
	' Subs.actualizaProducto(Subs.traeAlmacen, preciocaja,(laCant2.Text * conversion), Subs.traeProdNombre(id), id, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta,laCant2.Text,1)
	Subs.actualizaProducto2(Subs.traeAlmacen,  preciocaja,(laCant2.Text * conversion), Subs.traeProdNombre(id), id, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta,laCant2.Text,1)
	cuentaProds
	LogColor("prodsMap="&prodsMap, Colors.blue)
	Log($"Total Prods: ${totalProds}, Total Compra: $$1.2{totalCompra}"$)
	If 1 = 1 Then
		Private cs As CSBuilder
		cs.Initialize
		Private o As Cursor = Starter.skmt.ExecQuery($"select CAT_GP_ALMACEN from ${Starter.tabla} where CAT_GP_ID = '${id}'"$)
		Private invActualizado As String = "0"
		If o.RowCount > 0 Then
			o.Position = 0
			invActualizado = o.GetString("CAT_GP_ALMACEN")
		End If
		If clv_prods_ll.GetValue(index).As(Map).Get("precio_caja").As(Float) = 0 Or clv_prods_ll.GetValue(index).As(Map).Get("conversion").As(Int) = 1 Then
			Private maxcajas2 As Int = 0
			Log("cajas a 0")
		Else
			Private maxcajas2 As Int = invActualizado/clv_prods_ll.GetValue(index).As(Map).Get("conversion")
			Log("cajas no a 0")
		End If
		If 2 = 2 Then lProdX.Text = cs.Color(Colors.red).append(nombreX).pop.Append(CRLF).Append("Existencias: " & invActualizado).Color(0xFF017F01).Append($"   $${NumberFormat2(precio, 1, 2, 2, False)}${CRLF}Max. Cajas: ${maxcajas2}"$).Popall
		' Log(lProdX.Text)
	End If
	If Subs.totalPedido < 1 Then laCant2.Text = "0"
	invTotal = totalcajasmaspiezas + Subs.traeinventario(id)
	' LogColor("InvTotal PRODMAS: " & invTotal, Colors.Red)

End Sub

Sub b_prodMasc_Click
	etCantHasFocus = False
	Root.RequestFocus
	' LogColor("b_prodMas_Click", Colors.Magenta)

	Dim index As Int = clv_prods_ll.GetItemFromView(Sender)
	Dim pnl0 As B4XView = clv_prods_ll.GetPanel(index)
	Dim pnl As B4XView = pnl0.GetView(0)
	Dim laCant As B4XView = pnl.GetView(2).GetView(2)
	Dim laCant2 As B4XView = pnl.GetView(3).GetView(2)
	Dim lProdX As B4XView = pnl.GetView(1)
	Dim panelcajas As B4XView = pnl.GetView(3)
	Dim panelpiezas As B4XView = pnl.GetView(2)
	' Private tmpMap As Map = clv_prods_ll.GetValue(index).As(Map)
	Private precio As String=clv_prods_ll.GetValue(index).As(Map).Get("precio")
	Private inv As String=clv_prods_ll.GetValue(index).As(Map).Get("almacen")
	Private existencias As String = clv_prods_ll.GetValue(index).As(Map).Get("almacen")
	Private conversion As String = clv_prods_ll.GetValue(index).As(Map).Get("conversion")
	Private preciocaja As String = clv_prods_ll.GetValue(index).As(Map).Get("precio_caja")
	Log(conversion)
	Log($"Existencias: ${existencias}"$)
	If laCant2.Text = "" Then laCant2.Text = 0
	Private id As String=clv_prods_ll.GetValue(index).As(Map).Get("id")
	' If laCant.Text + 1 <= inv Then
	'' Log(NumberFormat2(laCant.Text+1,0,0,0,False))
	' laCant.Text = $"${NumberFormat2(laCant.Text+1,0,0,0,False)}"$
	'' Private precio As String=clv_prods_ll.GetValue(index).As(Map).Get("precio")
	' Private id As String=clv_prods_ll.GetValue(index).As(Map).Get("id")
	'' Private tmpMap As Map = CreateMap("precio":precio, "cant":laCant.Text, "almacen":Subs.traeAlmacen)
	'' Log(tmpMap)
	'' prodsMap.Put(id, tmpMap)
	'' LogColor(prodsMap, Colors.blue)
	' End If
	' Log("Cantidad + exis   " & (laCant.Text + existencias))
	' Log( (laCant.Text + 1 <= (laCant.Text + existencias)))
	' Log("inventario   "&Subs.traeinventario(id))
	' Log((Subs.totalPedido - precio > 1))
	' Log((Subs.totalPedido))

	Log(B4XPages.MainPage.tipo_venta)
	Log("--------------->Credito Disponible: "&B4XPages.MainPage.cliente.credito_diponible)
	Log(preciocaja)
	' Log(precio)
	If B4XPages.MainPage.tipo_venta = "PREVENTA_CREDITO" Then
		Dim fg As Cursor = Starter.skmt.ExecQuery("Select Ifnull(sum(PE_COSTO_TOT),0) AS COSTO FROM PEDIDO WHERE PE_CLIENTE IN (SELECT CUENTA FROM CUENTAA) AND PE_FOLIO = 'PREVENTA_CREDITO'")
		fg.Position = 0
		If fg.GetString("COSTO") + preciocaja <= B4XPages.MainPage.cliente.credito_diponible Then
			Log(Subs.traeinventario(id))
			Log((laCant2.Text * conversion) + conversion)
			Log((laCant2.Text *conversion)+ Subs.traeinventario(id))
			If Subs.traeinventario(id) > 0 And ((laCant2.Text * conversion) + conversion <= ((laCant2.Text *conversion)+ Subs.traeinventario(id))) Then 'And (Subs.totalPedido - precio > 1)
				' Log(clv_prods_ll.GetValue(index).As(Map))
				clv_prods_ll.GetValue(index).As(Map).Put("almacen", (inv - conversion))
				inv = inv - conversion
				' laCant.Text = $"$1.0{laCant.Text+1}"$
				laCant2.Text = NumberFormat2((laCant2.Text + 1), 1, 0, 0, False)
				' Log(clv_prods_ll.GetValue(index).As(Map))
				Log("cuando entro aqui?")
			End If
			Private nombreX As String = Subs.traeProdNombre(id)
			' Subs.actualizaProducto(Subs.traeAlmacen, laCant.text, id, clienteId)
			Log((laCant2.Text * conversion))
			If laCant2.Text > 0 Then
				panelpiezas.Visible = False
			Else If laCant2.Text = 0 Then
				panelpiezas.Visible = True
			End If

			' LogColor(laCant.Text,Colors.Red)
			' If laCant.IsInitialized Then
			' totalcajasmaspiezas = laCant.Text + laCant2.Text
			' Else
			' totalcajasmaspiezas = laCant2.Text
			' End If
			' Subs.actualizaProducto(Subs.traeAlmacen,preciocaja,(laCant2.Text * conversion), Subs.traeProdNombre(id), id, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta,laCant2.Text,1)
			Subs.actualizaProducto2(Subs.traeAlmacen,preciocaja,(laCant2.Text * conversion), Subs.traeProdNombre(id), id, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta,laCant2.Text,1)
			cuentaProds
			' Log($"Total Prods: ${totalProds}, Total Compra: $$1.2{totalCompra}"$)
			If 1 = 1 Then
				Private cs As CSBuilder
				cs.Initialize
				Private o As Cursor = Starter.skmt.ExecQuery($"select CAT_GP_ALMACEN from ${Starter.tabla} where CAT_GP_ID = '${id}'"$)
				Private invActualizado As String = "0"
				If o.RowCount > 0 Then
					o.Position = 0
					invActualizado = o.GetString("CAT_GP_ALMACEN")
				End If
				If clv_prods_ll.GetValue(index).As(Map).Get("precio_caja").As(Float) = 0 Or clv_prods_ll.GetValue(index).As(Map).Get("conversion").As(Int) = 1 Then
					Private maxcajas2 As Int = 0
					Log("cajas a 0")
				Else
					Private maxcajas2 As Int = invActualizado/clv_prods_ll.GetValue(index).As(Map).Get("conversion")
					Log("cajas no a 0")
				End If
				If 2 = 2 Then lProdX.Text = cs.Color(Colors.red).append(nombreX).pop.Append(CRLF).Append("Existencias: " & invActualizado).Color(0xFF017F01).Append($"   $${NumberFormat2(precio, 1, 2, 2, False)}${CRLF}Max. Cajas: ${maxcajas2}"$).Popall
				' Log(lProdX.Text)
			End If
			invTotal = totalcajasmaspiezas + Subs.traeinventario(id)
			' LogColor("InvTotal PRODMAS: " & invTotal, Colors.Red)
		Else
			MsgboxAsync("No se puede meter mas venta a credito por que supera el limite del credito","Atencion")
		End If
	Else
		Log(Subs.traeinventario(id))
		Log((laCant2.Text * conversion) + conversion)
		Log((laCant2.Text *conversion)+ Subs.traeinventario(id))
		If Subs.traeinventario(id) > 0 And ((laCant2.Text * conversion) + conversion <= ((laCant2.Text *conversion)+ Subs.traeinventario(id))) Then 'And (Subs.totalPedido - precio > 1)
			' Log(clv_prods_ll.GetValue(index).As(Map))
			clv_prods_ll.GetValue(index).As(Map).Put("almacen", (inv - conversion))
			inv = inv - conversion
			' laCant.Text = $"$1.0{laCant.Text+1}"$
			laCant2.Text = NumberFormat2((laCant2.Text + 1), 1, 0, 0, False)
			' Log(clv_prods_ll.GetValue(index).As(Map))
			Log("cuando entro aqui?")
		End If
		Private nombreX As String = Subs.traeProdNombre(id)
		' Subs.actualizaProducto(Subs.traeAlmacen, laCant.text, id, clienteId)
		Log((laCant2.Text * conversion))
		If laCant2.Text > 0 Then
			panelpiezas.Visible = False
		Else If laCant2.Text = 0 Then
			panelpiezas.Visible = True
		End If

		' LogColor(laCant.Text,Colors.Red)
		' If laCant.IsInitialized Then
		' totalcajasmaspiezas = laCant.Text + laCant2.Text
		' Else
		' totalcajasmaspiezas = laCant2.Text
		' End If
		' Subs.actualizaProducto(Subs.traeAlmacen,preciocaja,(laCant2.Text * conversion), Subs.traeProdNombre(id), id, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta,laCant2.Text,1)
		Subs.actualizaProducto2(Subs.traeAlmacen,preciocaja,(laCant2.Text * conversion), Subs.traeProdNombre(id), id, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta,laCant2.Text,1)
		cuentaProds
		' Log($"Total Prods: ${totalProds}, Total Compra: $$1.2{totalCompra}"$)
		If 1 = 1 Then
			Private cs As CSBuilder
			cs.Initialize
			Private o As Cursor = Starter.skmt.ExecQuery($"select CAT_GP_ALMACEN from ${Starter.tabla} where CAT_GP_ID = '${id}'"$)
			Private invActualizado As String = "0"
			If o.RowCount > 0 Then
				o.Position = 0
				invActualizado = o.GetString("CAT_GP_ALMACEN")
			End If
			If clv_prods_ll.GetValue(index).As(Map).Get("precio_caja").As(Float) = 0 Or clv_prods_ll.GetValue(index).As(Map).Get("conversion").As(Int) = 1 Then
				Private maxcajas2 As Int = 0
				Log("cajas a 0")
			Else
				Private maxcajas2 As Int = invActualizado/clv_prods_ll.GetValue(index).As(Map).Get("conversion")
				Log("cajas no a 0")
			End If
			If 2 = 2 Then lProdX.Text = cs.Color(Colors.red).append(nombreX).pop.Append(CRLF).Append("Existencias: " & invActualizado).Color(0xFF017F01).Append($"   $${NumberFormat2(precio, 1, 2, 2, False)}${CRLF}Max. Cajas: ${maxcajas2}"$).Popall
			' Log(lProdX.Text)
		End If
		invTotal = totalcajasmaspiezas + Subs.traeinventario(id)
		' LogColor("InvTotal PRODMAS: " & invTotal, Colors.Red)
	End If

End Sub

Private Sub et_pCantc_FocusChanged (HasFocus As Boolean)
	LogColor($"focus changed=${HasFocus}"$, Colors.Magenta)
	If et_pCantc.Text = "" Then et_pCantc.Text = "0"
	Dim index As Int = clv_prods_ll.GetItemFromView(Sender)
	Dim pnl0 As B4XView = clv_prods_ll.GetPanel(index)
	Dim pnl As B4XView = pnl0.GetView(0)
	Dim laCant As B4XView = pnl.GetView(2).GetView(2)
	Dim laCant2 As B4XView = pnl.GetView(3).GetView(2)
	Private id As String=clv_prods_ll.GetValue(index).As(Map).Get("id")
	If laCant2.Text = "" Then laCant2.Text = "0"
	etCantHasFocus = HasFocus
	' LogColor(laCant.Text,Colors.Red)
	' If laCant.IsInitialized Then
	' totalcajasmaspiezas = laCant.Text + laCant2.Text
	' Else
	' totalcajasmaspiezas = laCant2.Text
	' End If
	invTotal = totalcajasmaspiezas + Subs.traeinventario(id)
	' LogColor("InvTotal PRODMAS: " & invTotal, Colors.Red)
	cuentaProds
End Sub

Private Sub et_pCantc_TextChanged (Old As String, New As String)
	' Log(etCantHasFocus)
	' Log("InvTotal: " & invTotal)
	If etCantHasFocus = True Then
		' Sleep(500)
		' LogColor($"txt changed: ${Old}|${New}, hasfocus=${etCantHasFocus}"$,Colors.Magenta)
		Dim index As Int = clv_prods_ll.GetItemFromView(Sender)
		Dim pnl0 As B4XView = clv_prods_ll.GetPanel(index)
		Dim pnl As B4XView = pnl0.GetView(0)
		Dim laCant As B4XView = pnl.GetView(2).GetView(2)
		Dim laCant2 As B4XView = pnl.GetView(3).GetView(2)
		Dim lProdX As B4XView = pnl.GetView(1)
		Private id As String=clv_prods_ll.GetValue(index).As(Map).Get("id")
		Private precio As String=clv_prods_ll.GetValue(index).As(Map).Get("precio")
		Private inv As String=clv_prods_ll.GetValue(index).As(Map).Get("almacen")
		Private inv As String=Subs.traeinventario(id)
		Private nombreX As String = Subs.traeProdNombre(id)
		Dim panelcajas As B4XView = pnl.GetView(3)
		Dim panelpiezas As B4XView = pnl.GetView(2)
		Private conversion As String = clv_prods_ll.GetValue(index).As(Map).Get("conversion")
		Private preciocaja As String = clv_prods_ll.GetValue(index).As(Map).Get("precio_caja")
		invTotal = Subs.traeinventario(id)
		Log("inventario total "& invTotal)
		If(New = "" Or New = Null Or New = "-") Then New = 0
		' If New < 0 Then New = 0
		Log(($"new*conversion  ${New * conversion} > ${invTotal} =  ${((New * conversion)  > invTotal)}"$))
		If((New * conversion)  > invTotal) Then
			' Dim maximocajas As Int = invTotal / conversion
			Sender.As(EditText).text = 0
			New = 0
			' LogColor("cajas maximas "& maximocajas, Colors.Red)
			pnl.GetView(2).Visible = True
			Log("ponemos en 0")
		End If
		Log("--------------->Credito Disponible: "&B4XPages.MainPage.cliente.credito_diponible)
		Dim fg As Cursor = Starter.skmt.ExecQuery("Select IFNULL(sum(PE_COSTO_TOT),0) AS COSTO FROM PEDIDO WHERE PE_CLIENTE IN (SELECT CUENTA FROM CUENTAA) AND PE_FOLIO = 'PREVENTA_CREDITO'")
		fg.Position = 0
		If Old = "" Or Old = Null Then New = 0
		Log(preciocaja &"     *    "&Old)
		Log((fg.GetString("COSTO") + (preciocaja*New)) & " Monto Actual<-------")
		If fg.GetString("COSTO") +((preciocaja*New))  > B4XPages.MainPage.cliente.credito_diponible Then
			laCant2.Text = 0
			MsgboxAsync("No se puede meter mas venta a credito por que supera el limite del credito","Atencion")
		End If
		' Log($"inventario=${inv}"$)
		Log("inventario total despues de max "& invTotal)
		If New = "" Then New = 0
		If laCant2.Text = "" Then laCant2.Text = 0
		' LogColor("la cant2 " &laCant2.Text,Colors.Red)
		If New > 0 Then
			Log("lo ocultamos")
			panelpiezas.Visible = False
		Else If New = 0 Then
			panelpiezas.Visible = True
		End If
		' If laCant.IsInitialized Then
		' totalcajasmaspiezas = laCant.Text + laCant2.Text
		' Else
		' totalcajasmaspiezas = laCant2.Text
		' End If
		Log("InvTotal: " & invTotal)
		If Not(Old = "0" And New = "") And laCant2.Text <> Null And laCant2.Text <> "" And etCantHasFocus Then
			If invTotal - (laCant2.Text * conversion) >= 0 Then
				LogColor("validacion inventariio " & (invTotal - (laCant2.Text * conversion)), Colors.Blue)
				Log("actualizamos producto")
				Subs.actualizaProducto2(Subs.traeAlmacen,  preciocaja,(laCant2.Text * conversion), Subs.traeProdNombre(id), id, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta,laCant2.Text,1)
				cuentaProds
			Else
				Private totalcajaspermi As Int = invTotal / conversion
				laCant2.Text = totalcajaspermi
				Log("cajas permitidas total por guerra "& totalcajaspermi)
			End If
		End If
		LogColor("la cant2 " & laCant2.Text,Colors.Green)
		' If New <> "" And New.SubString2(0,0) = "0" Then
		' New.SubString(1)
		' End If
		' If New <> "" And New.SubString(1) <> "" Then
		' Log(New.SubString(1))
		' New = New.SubString(1)
		' laCant.Text = New.SubString(1)
		' Log(laCant.Text)
		' End If
		If 1 = 1 Then
			Private cs As CSBuilder
			cs.Initialize
			Private o As Cursor = Starter.skmt.ExecQuery($"select CAT_GP_ALMACEN from ${Starter.tabla} where CAT_GP_ID = '${id}'"$)
			Private invActualizado As String = "0"
			' If o.RowCount > 0 Then
			o.Position = 0
			invActualizado = Subs.traeinventario(id)
			Log(Subs.traeinventario(id))
			' End If
			If New = "" Then New = 0
			Log(clv_prods_ll.GetValue(index).As(Map).Get("precio_caja").As(Float)&" Precio caja")
			Log(clv_prods_ll.GetValue(index).As(Map).Get("conversion").As(Int)& " Conversion" )
			If clv_prods_ll.GetValue(index).As(Map).Get("precio_caja").As(Float) = 0 Or clv_prods_ll.GetValue(index).As(Map).Get("conversion").As(Int) = 1 Then
				Private maxcajas2 As Int = 0
				Log("cajas a 0")
			Else
				Private maxcajas2 As Int = invActualizado/clv_prods_ll.GetValue(index).As(Map).Get("conversion")
				Log("cajas no a 0")
			End If
			lProdX.Text = cs.Color(Colors.red).append(nombreX).pop.Append(CRLF).Append("Existencias: " & (Subs.traeinventario(id))).Color(0xFF017F01).Append($"   $${NumberFormat2(precio, 1, 2, 2, False)}${CRLF}Max. Cajas: ${maxcajas2}"$).Popall
		End If
	End If
End Sub


'Sub btnMasDinamico_Click
'	Dim btn As Button = Sender
'	etCantHasFocus = False
'	Dim info As Map = btn.Tag
'	Dim et As EditText = info.Get("et")
'	Dim pres As Map = info.Get("pres")
'    
'	' Obtener datos
'	Dim cantActual As Int = 0
'	If et.Text <> "" Then cantActual = et.Text
'    
'	Dim nuevaCant As Int = cantActual + (1* pres.Get("umv"))
'	Log(info.Get("id")&" ,"& info.Get("col")&" ,"& nuevaCant&" ,"& pres.Get("precio")&" ,"& pres.Get("umv") &" ,"& info.Get("almacen") &" ,"& clienteId)
'	' Actualizar Interfaz
'	et.Text = nuevaCant
'    
'	' Guardar en BD (Usando tu nueva lógica de ColumnaID)
'	Subs.actualizaProductoDinamico(info.Get("id"), info.Get("col"), nuevaCant, pres.Get("precio"), pres.Get("umv"), clienteId)
'    
'	cuentaProds
'End Sub
'
'Sub btnMenosDinamico_Click
'	Dim btn As Button = Sender
'	
'	Dim info As Map = btn.Tag
'	Dim et As EditText = info.Get("et")
'	Dim pres As Map = info.Get("pres")
'    
'	Dim cantActual As Int = 0
'	If et.Text <> "" Then cantActual = et.Text
'    
'	If cantActual > 0 Then
'		Dim nuevaCant As Int = cantActual - (1* pres.Get("umv"))
'		et.Text = nuevaCant
'		Log(info.Get("id")&" ,"& info.Get("col")&" ,"& nuevaCant&" ,"& pres.Get("precio")&" ,"& pres.Get("umv")&" ,"& clienteId)
'		' Guardar en BD
'		Subs.actualizaProductoDinamico(info.Get("id"), info.Get("col"), nuevaCant, pres.Get("precio"), pres.Get("umv"), clienteId)
'		cuentaProds
'	End If
'End Sub
'
''' Este evento se dispara cuando el usuario toca el cuadro de texto
''Sub etCantDinamico_FocusChanged (HasFocus As Boolean)
''	etCantHasFocus = HasFocus
''End Sub
''
''Sub etCantDinamico_TextChanged (Old As String, New As String)
''	Dim et As EditText = Sender
''	' IMPORTANTE: Solo procesamos si el usuario tiene el foco en el campo
''	' y si el Tag ya fue inicializado
''	If etCantHasFocus And et.Tag <> Null Then
''		Dim info As Map = et.Tag
''		Dim pres As Map = info.Get("pres")
''        
''		Dim nuevaCant As Int = 0
''		If New <> "" And IsNumber(New) Then nuevaCant = New
''        
''		' Guardar en BD
'''		Subs.actualizaProductoDinamico(info.Get("id"), info.Get("col"), nuevaCant, pres.Get("precio"), pres.Get("umv"), clienteId)
''		cuentaProds
''	Else If etCantHasFocus And et.Tag <> Null Then
''		Dim nuevaCant As Int = 0
''		If New = "" Then New = 0
''	End If
''End Sub

'Sub btnMasDinamico_Click
'	Dim btn As Button = Sender
''	etCantHasFocus = False
'	Dim info As Map = btn.Tag
'	Dim et As EditText = info.Get("et")
'	Dim pres As Map = info.Get("pres")
'	Dim idProd As String = info.Get("id")
'	
''	Dim btn As Button = Sender
''	Dim info As Map = btn.Tag
''	Dim pres As Map = info.Get("pres") ' Este es el mapa que creamos en el paso anterior
'    
'	' --- LOGS SOLICITADOS ---
'	Log("=== MOVIMIENTO: MAS ===")
'	Log("Presentación: " & pres.Get("nombre"))
'	Log("Dirigida a: " & pres.Get("dirigida"))
'	Log("Lista precio: " & pres.Get("listaprecio"))
'    
'	' 1. Obtener stock actual desde la base de datos para asegurar precisión
'	' (O puedes usar info.Get("almacen") si lo actualizas globalmente)
'	Dim stockDisponible As Int = Subs.traeinventario(idProd)
'	Dim umv As Int = pres.Get("umv")
'    
'	Dim cantActual As Int = 0
'	If et.Text <> "" Then cantActual = et.Text
'    
'	' 2. VALIDACIÓN: ¿Hay suficiente stock para cubrir al menos un UMV más?
'	If stockDisponible >= umv Then
'		Dim nuevaCant As Int = cantActual + umv
'		et.Text = nuevaCant
'        
'		' 3. Actualizar BD
'''		Subs.actualizaProductoDinamico(idProd, info.Get("col"), nuevaCant, pres.Get("precio"), umv, clienteId)
'
'		Subs.actualizaProductoDinamico(Subs.traeAlmacen, pres.Get("precio"),et.Text, Subs.traeProdNombre(idProd), idProd, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta,0,0, _
'		pres.Get("listaprecio"), umv, pres.Get("nombre") _
'		)
'		
'        
'		' 4. ACTUALIZACIÓN VISUAL DE EXISTENCIAS
'		' Buscamos el Label de información en el panel padre para refrescar el texto
'		ActualizarLabelExistencias(btn, idProd)
'        
'		cuentaProds
'	Else
'		ToastMessageShow("Inventario insuficiente. Stock: " & stockDisponible, False)
'	End If
'End Sub
'
'Sub btnMenosDinamico_Click
'	Dim btn As Button = Sender
'	Dim info As Map = btn.Tag
'	Dim et As EditText = info.Get("et")
'	Dim pres As Map = info.Get("pres")
'	Dim idProd As String = info.Get("id")
'    
'	
'	Log("=== MOVIMIENTO: MENOS ===")
'	Log("Presentación: " & pres.Get("nombre"))
'	Log("Dirigida a: " & pres.Get("dirigida"))
'	Log("Lista precio: " & pres.Get("listaprecio"))
'	
'	
'	Dim cantActual As Int = 0
'	If et.Text <> "" Then cantActual = et.Text
'    
'	' Solo restamos si la cantidad actual es mayor a 0
'	If cantActual > 0 Then
'		Dim umv As Int = pres.Get("umv")
'		Dim nuevaCant As Int = cantActual - umv
'        
'		' Aseguramos que no baje de 0 por errores de redondeo
'		If nuevaCant < 0 Then nuevaCant = 0
'		et.Text = nuevaCant
'        
'		' 1. Guardar en BD (Esto internamente debería devolver el stock en tu método Subs)
''		Subs.actualizaProductoDinamico(idProd, info.Get("col"), nuevaCant, pres.Get("precio"), umv, clienteId)
'
'		Subs.actualizaProductoDinamico(Subs.traeAlmacen, pres.Get("precio"),et.Text, Subs.traeProdNombre(idProd), idProd, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta,0,0, _
'		pres.Get("listaprecio"), umv, pres.Get("nombre") _
'		)
'        
'		' 2. ACTUALIZACIÓN VISUAL DE EXISTENCIAS
'		ActualizarLabelExistencias(btn, idProd)
'        
'		cuentaProds
'	End If
'End Sub

Private Sub ActualizarLabelExistencias(v As View, idProd As String)
	' Subimos en la jerarquía de vistas hasta llegar al "base" (Panel blanco)
	' Estructura: Button -> Base -> ItemPanel
	Dim parent As B4XView = v.Parent
    
	' El label de info es la vista índice 1 según tu B4XPage_Created (lblInfo)
	' Si no estás seguro del índice, lo buscamos por el tipo:
	For Each child As B4XView In parent.GetAllViewsRecursive
		If child Is Label Then
			Dim lbl As Label = child
			' Verificamos si es el label que contiene la palabra "Existencias"
			If lbl.Text.Contains("Existencias:") Then
				Dim nuevoStock As Int = Subs.traeinventario(idProd)
				Dim prodNombre As String = Subs.traeProdNombre(idProd)
                
				Dim cs As CSBuilder
				cs.Initialize.Color(Colors.Red).Bold.Append(prodNombre).Pop.Pop _
                  .Append(CRLF).Size(12).Color(Colors.Black).Append("Existencias: " & nuevoStock).Pop
                
				lbl.Text = cs
				Exit ' Ya lo encontramos, salimos del bucle
			End If
		End If
	Next
End Sub

Sub btnMasDinamico_Click
	Dim btn As Button = Sender
	Dim info As Map = btn.Tag
	Dim et As EditText = info.Get("et")
	Dim pres As Map = info.Get("pres")
	Dim idProd As String = info.Get("id")
    
	Dim stockDisponible As Int = Subs.traeinventario(idProd)
	Dim umv As Int = pres.Get("umv")
    
	Dim cantActual As Int = 0
	If et.Text <> "" Then cantActual = et.Text
    
	If stockDisponible >= umv Then
		Dim nuevaCant As Int = cantActual + umv
		et.Text = nuevaCant
        
		' --- ACTUALIZAR EL LABEL DE PRESENTACIÓN ---
		Dim unidades As Int = nuevaCant / umv
		ActualizarLabelNombrePresentacion(btn, pres.Get("nombre"), unidades)
		' --------------------------------------------
        
		Subs.actualizaProductoDinamico(Subs.traeAlmacen, pres.Get("precio"), et.Text, Subs.traeProdNombre(idProd), idProd, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta, 0, 0, _
        pres.Get("listaprecio"), umv, pres.Get("nombre"))
        
		ActualizarLabelExistencias(btn, idProd)
		cuentaProds
	Else
		ToastMessageShow("Inventario insuficiente. Stock: " & stockDisponible, False)
	End If
End Sub

Sub btnMenosDinamico_Click
	Dim btn As Button = Sender
	Dim info As Map = btn.Tag
	Dim et As EditText = info.Get("et")
	Dim pres As Map = info.Get("pres")
	Dim idProd As String = info.Get("id")
    
	Dim cantActual As Int = 0
	If et.Text <> "" Then cantActual = et.Text
    
	If cantActual > 0 Then
		Dim umv As Int = pres.Get("umv")
		Dim nuevaCant As Int = cantActual - umv
		If nuevaCant < 0 Then nuevaCant = 0
		et.Text = nuevaCant
        
		' --- ACTUALIZAR EL LABEL DE PRESENTACIÓN ---
		Dim unidades As Int = nuevaCant / umv
		ActualizarLabelNombrePresentacion(btn, pres.Get("nombre"), unidades)
		' --------------------------------------------
        
		Subs.actualizaProductoDinamico(Subs.traeAlmacen, pres.Get("precio"), et.Text, Subs.traeProdNombre(idProd), idProd, clienteId, Subs.traeFecha, Subs.traeUsuarioDeBD, rutaUsuario, 0, B4XPages.MainPage.tipo_venta, 0, 0, _
        pres.Get("listaprecio"), umv, pres.Get("nombre"))
        
		ActualizarLabelExistencias(btn, idProd)
		cuentaProds
	End If
End Sub

Private Sub ActualizarLabelNombrePresentacion(v As View, nombrePres As String, totalUnidades As Int)
	' v es el botón que disparó el evento. Su Parent es el panel "base" de la tarjeta.
	Dim parent As B4XView = v.Parent
    
	' Buscamos entre los hijos del panel el Label que tiene el nombre de la presentación
	For Each child As B4XView In parent.GetAllViewsRecursive
		If child Is Label Then
			Dim lbl As Label = child
			' Verificamos si el texto del label comienza con el nombre de la presentación (ej: "PAQUETE")
			' O si el texto contiene el nombre buscado.
			If lbl.Text.ToUpperCase.Contains(nombrePres.ToUpperCase) Then
				lbl.Text = nombrePres.ToUpperCase & ": " & totalUnidades
				Exit
			End If
		End If
	Next
End Sub