Curso de Software de Ventas Parte 34, Ventana de Ventas 9 – Guardar Venta

En esta sección ya daremos el último paso para guardar la factura, en este caso nos falta guardar en la tabla ventas, luego descontar de inventario los productos y agregar al Kardex el movimiento.

Pero antes vamos a agregar el código que falta al llenar LlenarGridProductos

Impuesto = CCur(msGrid.TextMatrix(Filas, 7)) '
          
If G_Empresa_Regimen = "Común" And Impuesto > 0 Then '
    TotalImpuesto = TotalImpuesto + Impuesto '
End If

El Procedimiento completo quedaría de la siguiente manera, dejo marcada las lineas nuevas con la palabra «Nueva»:

Sub LlenarGridProductos()
    Dim Sql As String
    Dim Columnas As Integer
    Columnas = 9
    
    Sql = "SELECT tblDetalle_Venta.Id_detalle, tblDetalle_Venta.IdProducto, tblProductos.CodigoPro, tblProductos.NombrePro, tblDetalle_Venta.Cantidad_dv, tblDetalle_Venta.P_Venta_dv, tblDetalle_Venta.Impuesto_dv, 0 as Subtotal, tblDetalle_Venta.Descuento_dv " _
        & " FROM tblProductos INNER JOIN tblDetalle_Venta ON tblProductos.IdProducto = tblDetalle_Venta.IdProducto WHERE tblDetalle_Venta.Num_VentaTemp = " & ConsecutivoTemp
    
    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.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.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))            ' Nueva
          
          If G_Empresa_Regimen = "Común" And Impuesto > 0 Then    ' Nueva
             TotalImpuesto = TotalImpuesto + Impuesto             ' Nueva
          End If '                                                 Nueva
          
          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")
          
          TotalVenta = TotalVenta + SubTotal
          TotalDescuento = TotalDescuento + DescuentoP
    Next Filas
    txtSubTotalFact.Text = Format((TotalVenta - TotalImpuesto), "currency") 'Nueva
    txtTotalFactura.Text = Format(TotalVenta, "currency")
    txtTotalDescuento.Text = Format(TotalDescuento, "currency")
    txtImpuestoFact.Text = Format(TotalImpuesto, "currency") '               Nueva
    
    NArticulos.Text = msGrid.Rows - 1
    
End Sub

El Siguiente paso es crear la ventana de cambio que no es mas que un Frame con campos donde pedimos los datos con que el cliente va a pagar quedaría de la siguiente manera:

El Frame se le da la propiedad BorderStyle = 0 – None y se da un color de fondo &H00FFC0C0& para el borde use el control Shape con un BorderWith de 5 y color de borde &H009A620E&

El control cmbTipoPago tiene 3 item en su lista:

  • Efectivo
  • Tarjeta
  • Efectivo y Tarjeta

Las opciones de Pago tiene el siguiente código:

Sub AbrirVentanaCambio()
    'Call DesactivarBotones
    framVentanCambio.Top = 4200
    framVentanCambio.Visible = True
    cmbTipoPago.ListIndex = 0
    txtNumReciboTarjeta.Text = 0
    txtValorTarjeta.Text = 0
    txtVECambio.Text = 0
    txtCambio.Text = 0
    cmbTipoPago.SetFocus
End Sub

Sub CalcularCambioEfectivo()
    If txtCambio.Text <> "" Then
        
       If Me.txtAbonoFact.Text <> "" Then
          If CCur(Me.txtAbonoFact.Text) > 0 Then
             Valor = CCur(txtAbonoFact.Text)
          End If
       Else
          Valor = CCur(Me.txtTotalFactura.Text)
       End If
       If Me.cmbTipoPago.ListIndex = 2 Then
          Valor = CCur(txtTotalFactura.Text) - Me.txtValorTarjeta
       End If
       Cambio = txtVECambio - Valor
       If Cambio >= 0 Then
          txtCambio = Format(Cambio, "currency")
       Else
         ' txtVPCambio.SetFocus
       End If
    End If
End Sub


Private Sub cmbTipoPago_Click()
    If cmbTipoPago.ListIndex = 0 Then 'efectivo
       txtNumReciboTarjeta.Visible = False
       txtValorTarjeta.Visible = False
       lblNumReciboP.Visible = False
       lblValorTarjetaP.Visible = False
    ElseIf cmbTipoPago.ListIndex = 1 Then 'tarjeta
       txtNumReciboTarjeta.Visible = True
       lblNumReciboP.Visible = True
       txtValorTarjeta.Visible = False
       lblValorTarjetaP.Visible = False
    Else  'ambos
       txtNumReciboTarjeta.Visible = True
       txtValorTarjeta.Visible = True
       lblNumReciboP.Visible = True
       lblValorTarjetaP.Visible = True
    End If
End Sub

Private Sub cmbTipoPago_KeyPress(KeyAscii As Integer)
    If KeyAscii = 13 Then
       If cmbTipoPago.ListIndex = 0 Then
          txtVECambio.SetFocus
       End If
       If cmbTipoPago.ListIndex >= 1 Then
          txtNumReciboTarjeta.SetFocus
       End If
       
    End If
End Sub

Private Sub txtNumReciboTarjeta_KeyPress(KeyAscii As Integer)
    If KeyAscii = 13 Then
       If txtNumReciboTarjeta = "" Then
          txtNumReciboTarjeta.Text = "0"
       End If
       If cmbTipoPago.ListIndex = 1 Then
          txtVECambio.SetFocus
       Else
          txtValorTarjeta.SetFocus
       End If
    End If
End Sub

Private Sub txtValorTarjeta_GotFocus()
    txtValorTarjeta.SelStart = 0
    txtValorTarjeta.SelLength = Len(txtValorTarjeta.Text)
End Sub

Private Sub txtValorTarjeta_KeyPress(KeyAscii As Integer)
    If KeyAscii = 13 Then
       txtVECambio.SetFocus
    End If
    
End Sub

Private Sub txtValorTarjeta_LostFocus()
    txtValorTarjeta.Text = Format(txtValorTarjeta.Text, "currency")
End Sub

Private Sub txtVECambio_GotFocus()
    txtVECambio.Text = CCur(txtVECambio.Text)
    txtVECambio.SelStart = 0
    txtVECambio.SelLength = Len(txtVECambio.Text)
End Sub

Private Sub txtVECambio_KeyPress(KeyAscii As Integer)
    If KeyAscii = 13 Then
       Call CalcularCambioEfectivo
       txtCambio.SetFocus
    End If
End Sub

Private Sub txtCambio_KeyPress(KeyAscii As Integer)
    If KeyAscii = 13 Then
       Call Finalizar_Guardado_Factura
    End If
End Sub

Al abrir la ventana de cambio necesitamos 2 procedimientos uno para desactivar los botones y los otros campos del formulario y otro para volverlo a activar:

Sub ActivarBotones()
    cmdNuevaFact.Enabled = True
    cmdIngresarPro.Enabled = True
    cmdGuardarFact.Enabled = True
    cmdBorrarPro.Enabled = True
    cmdFactAbiertas.Enabled = True
    cmdSalir.Enabled = True
    Frame1.Enabled = True 'clientes
    Frame2.Enabled = True 'producto
End Sub

Sub DesactivarBotones()
    cmdNuevaFact.Enabled = False
    cmdIngresarPro.Enabled = False
    cmdGuardarFact.Enabled = False
    cmdBorrarPro.Enabled = False
    cmdFactAbiertas.Enabled = False
    cmdSalir.Enabled = False
    Frame1.Enabled = False 'clientes
    Frame2.Enabled = False 'producto
End Sub

El paso a seguir ya es guardar la factura y para ellos hay que guardar el encabezado de la factura en la tabla tblVentas que lleva la siguiente estructura:

Para guardar la factura necesitamos el últmo numero que se ingreso en la tabla para eso usamos una Función que nos devuelva ese dato:

Function Ultima_Factura_Venta()
    Dim RecordSetNumFact As New ADODB.RecordSet
    Dim Sql As String
    
    Sql = "SELECT Max(Num_Factura) AS UltimoNumero FROM tblVentas ORDER BY Max(Num_Factura) DESC;"
    
    Set RecordSetNumFact = ConexionADO.Execute(Sql)
    
    If RecordSetNumFact.RecordCount > 0 Then
       If IsNull(RecordSetNumFact("UltimoNumero")) = False Then
          Ultima_Factura_Venta = RecordSetNumFact("UltimoNumero") + 1
       Else
          Ultima_Factura_Venta = 1
       End If
    Else
       Ultima_Factura_Venta = 1
    End If
End Function

Después de esto si procedemos a terminar de guardar la factura:

Sub Finalizar_Guardado_Factura()
    
    Num_Factura = Ultima_Factura_Venta() 'Ultima venta
     
    FechaHora = txtFechaApro.Text & " " & Time 'fecha y hora
    
    Comentario = "-"
    If txtObervacionesPro.Text <> "" Then  'comentario
       Comentario = txtObervacionesPro.Text
    End If
    
        'Se guarda en la tabla ventas
    
    Sql = "Insert Into tblVentas (Num_Factura, FechaHora, TipoFact, Dias, TotalFactura, EstadoFact, Comentario, Efectivo, Cambio, IdCliente, IdUsuario) " _
        & " VALUES (" & Num_Factura & ",'" & FechaHora & "'," & Me.cmdTipoFact.ListIndex & "," & txtDias.Text & ",'" & CCur(txtTotalFactura) & "',1,'" & Comentario & "','" & CCur(txtVECambio.Text) & "','" & CCur(txtCambio.Text) & "'," & CodigoCliente & "," & Glo_IdUsuario & ")"
    
    ConexionADO.Execute Sql
    
    'A los productos del detalle se les asigna el numero de factura
    Sql = "Update tblDetalle_Venta set Num_Factura = '" & Num_Factura & "', Num_VentaTemp = '0'  where Num_VentaTemp = " & ConsecutivoTemp
    ConexionADO.Execute Sql
    
    '*************** Consulta que resta todos los articulos de inventario
   Sql = "UPDATE tblProductos as ar INNER JOIN tblDetalle_Venta as d ON ar.IdProducto = d.IdProducto SET ar.ExistPro = (ar.ExistPro - d.Cantidad_dv) where d.Num_Factura = " & Num_Factura
   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 '" & FechaHora & "', dt.IdProducto, 'Venta de Mercancia según Fra. N° " & Num_Factura & " '," _
        & Num_Factura & ", dt.Cantidad_dv * -1, dt.P_Costo_dv, (Select ExistPro from tblProductos where IdProducto = dt.IdProducto) from tblDetalle_Venta as dt Where dt.Num_Factura = " & Num_Factura
   
   ConexionADO.Execute Sql

   ConsecutivoTemp = UltimaVentaTemp
   
   Call LlenarGridProductos
   
   MsgBox "Venta Guardada", vbInformation, "Guardar"
   
   Call LimpiarVenta
   
End Sub

En el código anterior notamos varias consultas que parecen hasta extrañas o complicadas pero es la manera mas eficiente de hacer la actualización de producto y registrar el detalle en el Kardex.

 '*************** Consulta que resta todos los articulos de inventario
Sql = "UPDATE tblProductos as ar INNER JOIN tblDetalle_Venta as d ON ar.IdProducto = d.IdProducto SET ar.ExistPro = (ar.ExistPro - d.Cantidad_dv) where d.Num_Factura = " & Num_Factura
ConexionADO.Execute Sql

La consulta anterior relacionamos la tabla Productos y Detalle_Venta por medio de campo IdProducto y hacemos una actualización donde tomamos la existencia actual del producto en la tabla tblProductos y la Restamos de la Cantidad Vendida de la tabla Detalle_Venta esta sola consulta resta todos los productos que estén en el detalle de venta filtrados por el Num_Factura (Número de Factura) dejando actualizada la tabla tblProductos.

Sql = "INSERT INTO tblKardex (Fecha, IdProducto, Detalle, D_C, Cantidad, Costo,Cant_Saldo) Select '" & FechaHora & "', dt.IdProducto, 'Venta de Mercancia según Fra. N° " & Num_Factura & " '," _
        & Num_Factura & ", dt.Cantidad_dv * -1, dt.P_Costo_dv, (Select ExistPro from tblProductos where IdProducto = dt.IdProducto) from tblDetalle_Venta as dt Where dt.Num_Factura = " & Num_Factura

La consulta anterior lo que haces es tomar cada producto del Detalle_Venta filtrados por el numero de factura y agregarlo a la tabla tblKardex para llevar un registro del movimiento del producto.

Cómo es una salida de inventario multiplica el campo Cantidad_dv por -1 para que quede un valor negativo y por ultimo tomo el valor  de la existencia actual del producto y tambien lo guardo en el kardex quedando de la siguiente manera.

Después de guardar la Venta Se limpian los campos del formulario y se pone el foco en el código del producto dejando todo listo para la siguiente factura:

Sub LimpiarVenta()
    txtTotalFactura.Text = 0
    txtImpuestoFact.Text = 0
    txtSubTotalFact.Text = 0
    txtTotalDescuento.Text = 0
    NArticulos.Text = 0
    txtObervacionesPro.Text = ""
    CodigoCliente = 1
    txtAbonoFact.Text = 0
    txtDias.Text = 0
    cmdTipoFact.ListIndex = 0
    
End Sub

En la próxima lección se trabajara la impresión de la factura usando el control DataReport

 

Comentarios de Facebook

Deja un comentario