Siguiente con el Listado de Ventas, vamos a crear dos funcionalidades nuevas una es el ver la factura y la otra es hacer las devoluciones.
Colabora y Suscribete a mi canal de
Ver Factura
Es una ventana que nos permite visualizar el detalle de la factura los datos del cliente y la lista de productos y permite modificar datos del encabezado de la factura. la ventana es la siguiente:
Devolución de Productos
Esta es una opción que se va agregar en la ventana de Ver Factura para mayor facilidad, cuando se visualiza la factura doy clic en el producto al que quiero hacerle la devolución, y doy clic en el botón Devolución y aparece un cuadro donde debo escribir la cantidad a devolver de la siguiente manera.
Al dar clic en el botón devolver sale un cuadro de confirmación y si confirmamos se hacer la devolución del producto.
Iniciando la Codificación
Lo primero es modificar la tabla Detalle_Venta en nuestra base de datos para agregar un campo que hace falta llamado Devolucion_dv que guardara la cantidad devuelta.
Para entender mejor lo que se quiere hacer, explico: Cuando se devuelva un producto se escribe la cantidad que se devolvió y se modifica la Cantidad_dv dejando solo cantidad que quedo.
Ejemplo: si se vendieron 10 de un producto determinado y se devolvió 1 en el campo Cantidad_dv = 9 y en el campo Devolucion_dv = 1
Lo siguiente es crear el formulario frmVerArticulosFVenta que debe quedar de la siguiente manera:
Los nombres de los controles que use son los siguientes:
txtIdentificacion_Cli
txtNombre_Cli
txtTelefono_cli
txtDireccion
cmdTipoFact
txtDias
txtFechaApro
msGrid
Para el cuadro de devolución son los siguientes nombre:
frmeDevolucion = Este es el Frame en amarillo usado para la devolución hay que cambiar la propiedad Visible = False
txtCant_Dev
txtSubtotalDev
Para los totales:
txtSubTotalFact
txtTotalFactura
txtTotalDescuento
txtImpuestoFact
NArticulos.Text
Los Totales:
cmdGuardarFact
cmdDevolucion
cmdSalir
Observación: Copie casi todo de la ventana de Ventas por que son muy parecidas para que lo tengan en cuenta y se les haga mas fácil.
En la ventana de frmListadoFactVentas hay que cambiar el nombre del botón de Devolución por cmdVerFactura y agregar el siguiente código:
Nfactura = msGrid.TextMatrix(msGrid.Row, 1) If Nfactura <> "" Then frmVerArticulosFVenta.Show End If
Con esto ya validamos que si se escogió una factura y se abre el formulario de Ver factura.
Ya en este ventana el evento load queda de la siguiente manera:
Private Sub Form_Load() Call CentrarFormulario(Me, frmPrincipal) Fila = frmListadoFactVentas.msGrid.Row g_Num_Factura = frmListadoFactVentas.msGrid.TextMatrix(Fila, 1) Call EncabezadoFactura Me.Caption = "Visualizando Factura Nº " & g_Num_Factura End Sub
En la primero linea se centra el formulario, en la segunda se toma el numero de la fila seleccionada en el grid del listado de factura, en la tercera se toma el numero de factura.
Hay que declarar una variable a nivel de formulario en pocas palabra arriba en la primera linea:
Dim g_Num_Factura
En la cuarta se llama el procedimiento EncabezadoFactura que lo que hace es hacer la consulta y traer los datos de la factura:
Sub EncabezadoFactura() Dim RecordFactura As New ADODB.RecordSet Sql = "Select FechaHora, TipoFact, Dias, c.IdCliente, c.NombreApellidos_cli, c.Identificacion_cli, c.Telefonos_cli, c.Direccion_cli From tblVentas as v, tblClientes as c Where v.IdCliente = c.IdCliente and Num_Factura = " & g_Num_Factura Set RecordFactura = ConexionADO.Execute(Sql) If RecordFactura.RecordCount > 0 Then CodigoCliente = RecordFactura("IdCliente") txtIdentificacion_Cli.Text = RecordFactura("Identificacion_cli") txtNombre_Cli.Text = RecordFactura("NombreApellidos_cli") txtTelefono_cli.Text = RecordFactura("Telefonos_cli") txtDireccion.Text = RecordFactura("Direccion_cli") cmdTipoFact.ListIndex = RecordFactura("TipoFact") txtDias.Text = RecordFactura("Dias") txtFechaApro.Text = Format(RecordFactura("FechaHora"), "dd/mm/yyyy") Call LlenarGridProductos End If End Sub
Si notamos casi en la ultima línea se llama al procedimiento LlenarGridProductos que ya se sabe que va a hacer
Este procedimiento es casi igual al que se usa en la ventana de Ventas, col algunas modificaciones que indicare a continuación:
Sub LlenarGridProductos() Dim Sql As String Dim Columnas As Integer Columnas = 11 Sql = "SELECT d.Id_detalle, d.IdProducto, p.CodigoPro, p.NombrePro, d.Cantidad_dv, d.P_Venta_dv, d.Impuesto_dv, 0 as Subtotal, d.Descuento_dv, d.Devolucion_dv, d.P_Costo_dv " _ & " FROM tblProductos as p INNER JOIN tblDetalle_Venta as d ON p.IdProducto = d.IdProducto WHERE d.Num_Factura = " & g_Num_Factura Call LlenarGrid(msGrid, Sql, Columnas) msGrid.ColWidth(0) = 0 msGrid.ColWidth(1) = 0 'ID msGrid.ColWidth(2) = 0 'item msGrid.ColWidth(3) = 900 'codigo msGrid.ColWidth(4) = 4300 'nombre msGrid.ColWidth(5) = 800 'cantidad msGrid.ColWidth(6) = 1300 'preciov msGrid.ColWidth(7) = 1300 'imp msGrid.ColWidth(8) = 1300 'subtotal msGrid.ColWidth(9) = 1300 'Desc msGrid.ColWidth(10) = 1000 'Dev msGrid.ColWidth(11) = 0 'PCosto msGrid.TextMatrix(0, 2) = "IdPro" msGrid.TextMatrix(0, 3) = "Código" msGrid.TextMatrix(0, 4) = "Nombre Producto" msGrid.TextMatrix(0, 5) = "Cant" msGrid.TextMatrix(0, 6) = "Precio V" msGrid.TextMatrix(0, 7) = "Impuesto" msGrid.TextMatrix(0, 8) = "Subtotal" msGrid.TextMatrix(0, 9) = "Descuento" msGrid.TextMatrix(0, 10) = "Dev" msGrid.ColAlignment(5) = flexAlignCenterCenter TotalVenta = 0 TotalDescuento = 0 TotalImpuesto = 0 For Filas = 1 To msGrid.Rows - 1 Cantidad = msGrid.TextMatrix(Filas, 5) PrecioVp = CCur(msGrid.TextMatrix(Filas, 6)) DescuentoP = CCur(msGrid.TextMatrix(Filas, 9)) Subtotal = (Cantidad * PrecioVp) - DescuentoP Impuesto = CCur(msGrid.TextMatrix(Filas, 7)) If G_Empresa_Regimen = "Común" And Impuesto > 0 Then ' TotalImpuesto = TotalImpuesto + Impuesto ' End If ' msGrid.TextMatrix(Filas, 6) = Format(msGrid.TextMatrix(Filas, 6), "currency") msGrid.TextMatrix(Filas, 7) = Format(msGrid.TextMatrix(Filas, 7), "currency") msGrid.TextMatrix(Filas, 8) = Format(Subtotal, "currency") msGrid.TextMatrix(Filas, 9) = Format(msGrid.TextMatrix(Filas, 9), "currency") If msGrid.TextMatrix(Filas, 10) = "" Then msGrid.TextMatrix(Filas, 10) = 0 End If TotalVenta = TotalVenta + Subtotal TotalDescuento = TotalDescuento + DescuentoP Next Filas txtSubTotalFact.Text = Format((TotalVenta - TotalImpuesto), "currency") txtTotalFactura.Text = Format(TotalVenta, "currency") txtTotalDescuento.Text = Format(TotalDescuento, "currency") txtImpuestoFact.Text = Format(TotalImpuesto, "currency") ' NArticulos.Text = msGrid.Rows - 1 End Sub
En la consulta agregue dos campos mas d.Devolucion_dv, d.P_Costo_dv que uno es la columna devolución y el otro es el Precio Costo. entonces la variable Columnas = 11
Luego se agrega 2 columnas al grid:
msGrid.ColWidth(10) = 1000 'Dev msGrid.ColWidth(11) = 0 'PCosto
Y para el titulo solo colocamos al de la columna 10 por que el otro no hay que mostrarlo:
msGrid.TextMatrix(0, 10) = “Dev”
Agregue el siguiente condicional dentro del for para validar si el campo devolución viene vació y si viene vació se coloca un cero:
If msGrid.TextMatrix(Filas, 10) = "" Then msGrid.TextMatrix(Filas, 10) = 0 End If
Eso es todo a lo referente a ver la factura ahora falta el código para hace la devolución, donde lo primero es definir el cuadro donde nos das la opción de hacer la devolución.
Cuando se da clic en el botón devolución se muestra el Frame frmeDevolucion y se carga la cantidad vendida y el subtotal de este:
Private Sub cmdDevolucion_Click() frmeDevolucion.Visible = True msGrid.Enabled = False Filas = msGrid.Row Cantidad = msGrid.TextMatrix(Filas, 5) PrecioVp = CCur(msGrid.TextMatrix(Filas, 6)) txtCant_Dev.Text = Cantidad Subtotal = (PrecioVp * Cantidad) txtSubtotalDev.Text = Format(Subtotal, "currency") End Sub
Lo primero que se hace es poner en visible el frmeDevolucion, luego se bloquea el grid poniendo la propiedad Enable = False para que el usuario no de clic en otra fila.
Se toma la fila actual del grid para poder obtener la cantidad, precio de venta y calcular el subtotal actual de ese producto y se muestra en el cuadro de texto txtSubtotalDev
Luego de esto se valida el cuadro de texto txtCant_Dev para que solo deje escribir numero y para que cuando escribamos un numero calcula automáticamente el subtotal:
Private Sub txtCant_Dev_KeyPress(KeyAscii As Integer) If SoloNumeros(KeyAscii) = False Then KeyAscii = 0 End If End Sub Private Sub txtCant_Dev_KeyUp(KeyCode As Integer, Shift As Integer) If txtCant_Dev.Text <> "" Then Filas = msGrid.Row PrecioVp = CCur(msGrid.TextMatrix(Filas, 6)) Cantidad = txtCant_Dev.Text Subtotal = (PrecioVp * Cantidad) txtSubtotalDev.Text = Format(Subtotal, "currency") End If End Sub
En La propiedad KeyPress se valida que solo deje escribir números y en el KeyUp es donde se valida que no quede vació este campo y se calcula el subtotal teniendo en cuenta el valor escrito
Para el botón cerra del cuadro de Devolución lo que hacemos es ocultar el frmeDevolucion y activar nuevamente el grid:
Private Sub cmdCerrarDev_Click() frmeDevolucion.Visible = False msGrid.Enabled = True End Sub
Para el botón Devolver que es el que va a hacer el proceso de devolución el código es el siguiente:
Private Sub cmdDevolver_Click() Res = MsgBox("¿Esta seguro de hacer la devolución?", vbYesNo, "Devolución") If Res = vbYes Then Call DevolucionProducto End If End Sub
Sub DevolucionProducto() If txtCant_Dev.Text <> "" Then If txtCant_Dev.Text > 0 Then Filas = msGrid.Row IdProducto = msGrid.TextMatrix(Filas, 2) IdDetalle = msGrid.TextMatrix(Filas, 1) CantdGr = msGrid.TextMatrix(Filas, 5) Cantidad = txtCant_Dev.Text If Cantidad > CantdGr Then MsgBox "La Cantidad a devolver no puede ser mayor a la cantidad vendida", vbExclamation, "Error" Exit Sub End If PrecioVp = CCur(msGrid.TextMatrix(Filas, 6)) Cant_Restante = CantdGr - Cantidad Sql = "Update tblDetalle_Venta Set Cantidad_dv = '" & Cant_Restante & "', Devolucion_dv = '" & Cantidad & "' where Id_detalle = " & IdDetalle ConexionADO.Execute Sql Sql = "UPDATE tblProductos as ar SET ExistPro = (ExistPro + '" & Cantidad & "') where IdProducto = " & IdProducto ConexionADO.Execute Sql '/*//*********************** crear el historial de cada articulo en el kardex Sql = "INSERT INTO tblKardex (Fecha, IdProducto, Detalle, D_C, Cantidad, Costo,Cant_Saldo) " _ & "Select NOW(), dt.IdProducto, 'Devolucion de Producto Fra. N° " & g_Num_Factura & " '," _ & g_Num_Factura & ", '" & Cantidad & "', dt.P_Costo_dv, (Select ExistPro from tblProductos where IdProducto = dt.IdProducto) " _ & " from tblDetalle_Venta as dt Where dt.Id_detalle = " & IdDetalle ConexionADO.Execute Sql frmeDevolucion.Visible = False msGrid.Enabled = True Call LlenarGridProductos Sql = "Update tblVentas SET TotalFactura = " & CCur(txtTotalFactura.Text) & " Where Num_Factura = " & g_Num_Factura ConexionADO.Execute Sql MsgBox "Devolución realizada con éxito", vbInformation, "Devolución" Else MsgBox "La Cantidad a devolver debe ser mayor a cero", vbExclamation, "Error" End If Else MsgBox "La Cantidad a devolver no debe estar vacía", vbExclamation, "Error" End If End Sub
Lo primero son las validaciones que el campo cantidad no este vació y que sea mayor a cero y que no sobre pase la cantidad vendida, luego se resta para saber cuanto quedo de lo vendido y guardarlo en la tabla detalle de venta.
Sql = "Update tblDetalle_Venta Set Cantidad_dv = '" & Cant_Restante & "', Devolucion_dv = '" & Cantidad & "' where Id_detalle = " & IdDetalle ConexionADO.Execute Sql Sql = "UPDATE tblProductos as ar SET ExistPro = (ExistPro + '" & Cantidad & "') where IdProducto = " & IdProducto ConexionADO.Execute Sql
En la primera consulta se guarda la cantidad restante y la cantidad devuelta en la tabla tblDetalle_Venta.
Luego se hace el registro en la tabla Kardex recuerde que todo movimiento que se haga en la tabla tblProductos se debe registrar en la tabla tblKardex.
Sql = "INSERT INTO tblKardex (Fecha, IdProducto, Detalle, D_C, Cantidad, Costo,Cant_Saldo) " _ & "Select NOW(), dt.IdProducto, 'Devolución de Producto Fra. N° " & g_Num_Factura & " '," _ & g_Num_Factura & ", '" & Cantidad & "', dt.P_Costo_dv, (Select ExistPro from tblProductos where IdProducto = dt.IdProducto) " _ & " from tblDetalle_Venta as dt Where dt.Id_detalle = " & IdDetalle
Ya esta consulta la hemos hecho antes lo que cambia es que se toma el numero de factura de la variable g_Num_Factura y la cantidad devuelta y el cambio se hace teniendo en cuenta el campo Id_detalle de la tablaDetalle_Venta para si poder modificar la linea correcta de esa tabla.
Solo quedo faltando el Guardar para modificar los datos del encabezado de la factura por si se desea cambiar el cliente o de el termino.
Suscribete a Youtube
Siguenos en Twitter
Siguenos en Facebook