You are on page 1of 12

Punto de Venta Visual Basic

Requisitos
Visual Studio 2010
Microsoft Access 2007/2010

Diseo de la Base de datos


Creamos una base de datos en Access con las siguientes caractersticas:

Creacin del Proyecto Creamos un proyecto llamado PVenta2012 a travs de Visual Studio 2010:

Organizamos nuestro proyecto:

Agregaremos tres carpetas y eliminaremos el formulario predeterminado (Form1.vb) pues no lo necesitamos.


Adems, a las carpetas les agregamos dos formularios y un mdulo respectivamente, como se muestra en la
imagen. Formulario de Inicio de Sesin (frmLogin.vb) Agregamos dos directivas:

Imports System.Data
Imports System.Data.OleDb

Agregamos las siguientes variables:


Dim Intentos As Integer = 0
Public Shared UserLogin As String
Public Shared Nombre As String
Public Shared Apellidos As String
Public Shared Ventas As Boolean
Public Shared Reportes As Boolean
Public Shared Administrar As Boolean
Public Shared Catalogos As Boolean
Public Shared Acceso As Boolean

Ponemos el siguiente cdigo en modMain.vb:


Module modMain
Public CnnStr As String =
"Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\Users\ddi-gcastillo\" & _
"Documents\tyrodeveloper\PVenta2012\PVenta2012.accdb;" & _
"Persist Security Info=False;"
Sub Main()
Dim _frmLogin As New frmLogin
_frmLogin.StartPosition = FormStartPosition.CenterScreen
Application.Run(_frmLogin)
If (frmLogin.Acceso = True) Then
Dim _mdiMain As New mdiMain
_mdiMain.StartPosition = FormStartPosition.CenterScreen
_mdiMain.WindowState = FormWindowState.Maximized
Application.Run(_mdiMain)
Else
Application.Exit()
End If
End Sub
End Module

Regresamos a frmLogin.vb, escribimos la siguiente funcin:


Protected Function Login() As Boolean
Dim cnn As New OleDbConnection(CnnStr)
Try
cnn.Open()
Dim cmd As New OleDbCommand
cmd.Connection = cnn
cmd.CommandText = "SELECT * FROM USERS " & _
" WHERE USER_LOGIN=@user_login " & _
" AND USER_PASSWORD=@user_password"
cmd.Parameters.Add("@user_login", OleDbType.VarChar, _
50).Value = txtUserLogin.Text
cmd.Parameters.Add("@user_password", OleDbType.VarChar, _
255).Value = txtUserPassword.Text
Dim dr As OleDbDataReader = cmd.ExecuteReader
If dr.Read Then
UserLogin = dr("USER_LOGIN").ToString()
Nombre = dr("NOMBRE").ToString()
Apellidos = dr("APELLIDOS").ToString()
Ventas = CBool(dr("VENTAS"))
Reportes = CBool(dr("REPORTES"))
Administrar = CBool(dr("ADMINISTRAR"))
Catalogos = CBool(dr("CATALOGOS"))
Else
Intentos += 1
Throw (New Exception( _
"Nombre de Usuario o contrasea incorrectos"))
End If
dr.Close()
Return True
Catch ex As Exception
Throw (ex)
Finally
cnn.Close()
End Try
End Function

Luego ponemos el cdigo del botn Aceptar:

Private Sub btnOk_Click(ByVal sender As System.Object, _


ByVal e As System.EventArgs) _
Handles btnOk.Click
Try
If (Intentos >= 3) Then
Acceso = False
MessageBox.Show("Numero de Intentos Excedidos", _
"Informacin del Sistema", _
MessageBoxButtons.OK, _
MessageBoxIcon.Error)
Me.Close()
Else
Acceso = Login()
If (Acceso) Then
Me.Close()
End If
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "Informacin del Sistema", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub

A continuacin configuramos el proyecto, nos vamos a las propiedades y establecemos el objeto inicial:

Ventana Principal (mdiMain)


Agregamos formularios (frmVenta y frmCobrar) como se muestra en la imagen:

Luego, le damos el siguiente diseo al formulario mdiMain:

Y le ponemos el siguiente cdigo en el Form_Load:


''Permisos
mnuVentas.Visible = frmLogin.Ventas
btnVentas.Visible = frmLogin.Ventas
mnuReportes.Visible = frmLogin.Reportes
mnuAdministrar.Visible = frmLogin.Administrar
mnuCatalogos.Visible = frmLogin.Catalogos

De esta manera, cuando un usuario inicie sesin, se aplicarn los permisos.

Pantalla de Cobranza (frmCobrar)


Diseamos la ventana de cobranza (frmCobrar) de la siguiente manera:

Agregamos tres propiedades:


Protected _success As Boolean = False
Public ReadOnly Property Success As Boolean
Get
Return _success
End Get
End Property
Protected _folioVenta As Integer = 0
Public ReadOnly Property FolioVenta As Integer
Get
Return _folioVenta
End Get
End Property
Public Property TotalVenta As Double
Get
Return varTotal
End Get
Set(ByVal value As Double)
varTotal = value
End Set
End Property
Dim varTotal As Double = 0

Esta es la funcin que guarda las ventas:


Protected Function RealizarVenta() As Boolean
Dim cnn As New OleDbConnection(CnnStr)
Dim RowCount As Integer = 0
Dim varFolioVenta As Integer = 0
_folioVenta = 0
Try
cnn.Open()
Dim tran As OleDbTransaction = cnn.BeginTransaction()
Dim cmd As New OleDbCommand
cmd.Connection = cnn
cmd.Transaction = tran
Try
''validamos si existe el producto
cmd.CommandText = "SELECT COUNT(*) " & _
"FROM VENTA_DETALLE_TMP " & _
" WHERE USER_LOGIN=@USER_LOGIN"
cmd.Parameters.Add("@USER_LOGIN", OleDbType.VarChar, _
50).Value = frmLogin.UserLogin
RowCount = CInt(cmd.ExecuteScalar)
cmd.Parameters.Clear() ''Limpiamos parmetros
If (RowCount = 0) Then
Throw (New Exception("No hay registros"))
End If
''insertamos la venta

cmd.CommandText = "INSERT INTO VENTA" & _


"(USER_LOGIN,FECHA_REGISTRO," & _
" FECHA_VENTA,TOTAL,EFECTIVO,CAMBIO)" & _
" VALUES (@USER_LOGIN,NOW(),NOW()," & _
" @TOTAL,@EFECTIVO,@CAMBIO)"
cmd.Parameters.Add("@USER_LOGIN", _
OleDbType.VarChar, 50).Value = frmLogin.UserLogin
cmd.Parameters.Add("@TOTAL", _
OleDbType.Double).Value = varTotal
cmd.Parameters.Add("@EFECTIVO", _
OleDbType.Double).Value = txtEfectivo.Text
cmd.Parameters.Add("@CAMBIO", _
OleDbType.Double).Value = _
CDbl(txtEfectivo.Text) - varTotal
cmd.ExecuteNonQuery()
cmd.Parameters.Clear() ''Limpiamos parametros
''obtenemos el folio
cmd.CommandText = "SELECT @@IDENTITY"
varFolioVenta = CInt(cmd.ExecuteScalar())
''insertamos el detalle de venta
cmd.CommandText = "INSERT INTO VENTA_DETALLE" & _
"(ID_VENTA,ID_PRODUCTO,CANTIDAD," & _
"PRECIO_VENTA,IMPUESTO,PRECIO_COMPRA)" & _
"SELECT @ID_VENTA, ID_PRODUCTO,CANTIDAD," & _
"PRECIO_VENTA,IMPUESTO," & _
"PRECIO_COMPRA FROM VENTA_DETALLE_TMP " & _
" WHERE USER_LOGIN=@USER_LOGIN"
cmd.Parameters.Add("@ID_VENTA", _
OleDbType.Integer).Value = varFolioVenta
cmd.Parameters.Add("@USER_LOGIN", _
OleDbType.VarChar, 50).Value = frmLogin.UserLogin
cmd.ExecuteNonQuery()
cmd.Parameters.Clear() ''Limpiamos parametros
''Actualizamos existencias
cmd.CommandText = "UPDATE PRODUCTOS " & _
" INNER JOIN VENTA_DETALLE_TMP " & _
" ON PRODUCTOS.ID_PRODUCTO = " & _
" VENTA_DETALLE_TMP.ID_PRODUCTO " & _
" SET PRODUCTOS.STOCK = " & _
" PRODUCTOS.STOCK-VENTA_DETALLE_TMP.CANTIDAD" +
" WHERE ((VENTA_DETALLE_TMP.USER_LOGIN= @USER_LOGIN));"
cmd.Parameters.Add("@USER_LOGIN", _
OleDbType.VarChar, 50).Value = frmLogin.UserLogin
cmd.ExecuteNonQuery()
cmd.Parameters.Clear() ''Limpiamos parametros
''borramos la tabla temporal
cmd.CommandText = "DELETE FROM VENTA_DETALLE_TMP " & _
"WHERE USER_LOGIN=@USER_LOGIN"
cmd.Parameters.Add("@USER_LOGIN", _
OleDbType.VarChar, 50).Value = frmLogin.UserLogin
cmd.ExecuteNonQuery()
_folioVenta = varFolioVenta ''Asignamos el folio
tran.Commit()
Return True
Catch ex1 As OleDb.OleDbException
tran.Rollback()
Throw (ex1)
End Try
Catch ex As Exception
Throw (ex)
Finally
cnn.Close()
End Try
End Function

Botn "Aceptar":
Private Sub btnOk_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnOk.Click
Try
_success = RealizarVenta()
If (_success) Then
Me.Close()

End If
Catch ex As Exception
MessageBox.Show(ex.Message, "Informacin del Sistema",
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub

Botn "Cancelar":
Private Sub btnCancel_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnCancel.Click
Me.Close()
End Sub

txtEfectivo (Cuando se presiona una tecla se actualizar txtCambio):


Private Sub txtEfectivo_TextChanged(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles txtEfectivo.TextChanged
Try
Dim varCambio As Double = _
Convert.ToDouble(txtEfectivo.Text) - varTotal
If (varCambio >= 0) Then
txtCambio.Text = String.Format("{0:C}",
(Convert.ToDouble(txtEfectivo.Text) - varTotal))
btnOk.Enabled = True
Else
btnOk.Enabled = False
End If
Catch ex As Exception
txtCambio.Text = ex.Message
btnOk.Enabled = False
End Try
End Sub

Form_Load:
Private Sub frmCobrar_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Try
txtTotalPagar.Text = String.Format("{0:C}", varTotal)
txtTotalPagar.Enabled = False
txtCambio.Enabled = False
txtEfectivo.Text = varTotal.ToString()
Catch ex As Exception
MessageBox.Show(ex.Message, "Informacin del Sistema",
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub

Pantalla de Ventas (frmVenta)


Diseamos el formulario (frmVenta) de la siguiente manera:

Declaramos la variable que almacenar el total de la venta:


Dim varTotal As Double = 0

Proceso para agregar articulos a la lista de ventas:


Protected Function Agregar() As Boolean
Dim cnn As New OleDbConnection(CnnStr)
Dim RowCount As Integer = 0
Try
cnn.Open()
Dim cmd As New OleDbCommand
cmd.Connection = cnn
''validamos si existe el producto
cmd.CommandText = "SELECT COUNT(*) FROM PRODUCTOS " & _
"WHERE ID_PRODUCTO=@ID_PRODUCTO"
cmd.Parameters.Add("@ID_PRODUCTO", _
OleDbType.VarChar, 50).Value = txtIdProducto.Text
RowCount = CInt(cmd.ExecuteScalar)
cmd.Parameters.Clear() ''Limpiamos parametros
If (RowCount = 0) Then
Throw (New Exception("El producto no existe"))
End If
''insertamos el producto a la tabla temporal
cmd.CommandText = "SELECT COUNT(*) " & _
" FROM VENTA_DETALLE_TMP " & _
" WHERE ID_PRODUCTO=@ID_PRODUCTO" & _
" AND USER_LOGIN=@USER_LOGIN"
cmd.Parameters.Add("@ID_PRODUCTO", _
OleDbType.VarChar, 50).Value = txtIdProducto.Text
cmd.Parameters.Add("@USER_LOGIN", _
OleDbType.VarChar, 50).Value = frmLogin.UserLogin
RowCount = CInt(cmd.ExecuteScalar)
cmd.Parameters.Clear() ''Limpiamos parametros
If (RowCount = 0) Then
''Nuevo
cmd.CommandText = "INSERT INTO VENTA_DETALLE_TMP " & _
" (USER_LOGIN, ID_PRODUCTO,CANTIDAD," & _
"PRECIO_VENTA,PRECIO_COMPRA,IMPUESTO) " & _
" SELECT @USER_LOGIN, ID_PRODUCTO, @CANTIDAD, " & _
" PRECIO_VENTA, PRECIO_COMPRA, IMPUESTO " & _
" FROM PRODUCTOS WHERE ID_PRODUCTO=@ID_PRODUCTO"
cmd.Parameters.Add("@USER_LOGIN", _
OleDbType.VarChar, 50).Value = frmLogin.UserLogin
cmd.Parameters.Add("@CANTIDAD", _
OleDbType.Double).Value = txtCantidad.Text
cmd.Parameters.Add("@ID_PRODUCTO", _
OleDbType.VarChar, 50).Value = txtIdProducto.Text
Else
''Editar
cmd.CommandText = "UPDATE VENTA_DETALLE_TMP " & _
" SET CANTIDAD = CANTIDAD + @CANTIDAD " & _
" WHERE ID_PRODUCTO=@ID_PRODUCTO " & _

" AND USER_LOGIN=@USER_LOGIN "


cmd.Parameters.Add("@CANTIDAD",
OleDbType.Double).Value = txtCantidad.Text
cmd.Parameters.Add("@ID_PRODUCTO",
OleDbType.VarChar, 50).Value = txtIdProducto.Text
cmd.Parameters.Add("@USER_LOGIN",
OleDbType.VarChar, 50).Value = frmLogin.UserLogin
End If
cmd.ExecuteNonQuery()
Return True
Catch ex As Exception
Throw (ex)
Finally
cnn.Close()
End Try
End Function

Lgica del proceso:


1.

Se indica el producto y la cantidad

2.

Se valida si existe el producto.

3.
4.

Si no existe el producto se genera un error (Throw)

5.
6.

7.

Se valida si el producto ya existe en la lista de ventas

8.
9.

Si no existe se agrega nuevo

Si existe, se actualiza la cantidad

10.

11.
12.

Cdigo para cancelar la venta:


Protected Function CancelarVenta() As Boolean
Dim cnn As New OleDbConnection(CnnStr)
Try
cnn.Open()
Dim cmd As New OleDbCommand
cmd.Connection = cnn
cmd.CommandText = "DELETE FROM VENTA_DETALLE_TMP " & _
"WHERE USER_LOGIN=@USER_LOGIN"
cmd.Parameters.Add("@USER_LOGIN",
OleDbType.VarChar, 50).Value = frmLogin.UserLogin
cmd.ExecuteNonQuery()
Return True
Catch ex As Exception
Throw (ex)
Finally

cnn.Close()
End Try
End Function

El siguiente cdigo genera los encabezados del LisView:


Protected Sub Encabezados()
With lvVenta
.View = View.Details
.FullRowSelect = True
.GridLines = True
.HideSelection = False
.Columns.Add("Id", 50)
.Columns.Add("Producto", 250)
.Columns.Add("Cant", 50, HorizontalAlignment.Right)
.Columns.Add("Prec", 50, HorizontalAlignment.Right)
.Columns.Add("Total", 80, HorizontalAlignment.Right)
End With
End Sub

El siguiente cdigo Muestra los productos en el ListView:


Protected Sub MostrarVenta()
Dim cnn As New OleDbConnection(CnnStr)
varTotal = 0
Try
cnn.Open()
Dim cmd As New OleDbCommand
cmd.Connection = cnn
cmd.CommandText = "SELECT P.ID_PRODUCTO, " & _
"P.PRODUCTO, T.CANTIDAD, T.PRECIO_VENTA," & _
"(T.CANTIDAD * T.PRECIO_VENTA) AS TOTAL " & _
" FROM VENTA_DETALLE_TMP T, PRODUCTOS P " & _
" WHERE T.ID_PRODUCTO=P.ID_PRODUCTO " & _
" AND T.USER_LOGIN=@USER_LOGIN"
cmd.Parameters.Add("@USER_LOGIN",
OleDbType.VarChar, 50).Value = frmLogin.UserLogin
Dim dr As OleDbDataReader = cmd.ExecuteReader
Dim i As Integer = 0
lvVenta.Items.Clear()
While (dr.Read())
With lvVenta
.Items.Add(dr("ID_PRODUCTO").ToString())
.Items(i).SubItems.Add(dr("PRODUCTO").ToString())
.Items(i).SubItems.Add(String.Format("{0:N}",
dr("CANTIDAD")))
.Items(i).SubItems.Add(String.Format("{0:C}",
dr("PRECIO_VENTA")))
.Items(i).SubItems.Add(String.Format("{0:C}",
dr("TOTAL")))
End With
varTotal += CDbl(dr("TOTAL"))
i += 1
End While
dr.Close()
lblTotal.Text = String.Format("{0:C}", varTotal)
Catch ex As Exception
Throw (ex)
Finally
cnn.Close()
End Try
End Sub

Botn "Agregar":
Private Sub btnAgregar_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnAgregar.Click
Try
If (Agregar()) Then
MostrarVenta()
txtCantidad.Text = "1"
txtIdProducto.Text = ""

txtIdProducto.Focus()
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "Informacin del Sistema",
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub

Botn "Cancelar":
Private Sub btnCancelar_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnCancelar.Click
Try
If (CancelarVenta()) Then
lvVenta.Items.Clear()
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "Informacin del Sistema",
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub

Botn "Cobrar":
Private Sub btnCobrar_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnCobrar.Click
If (lvVenta.Items.Count > 0) Then
Dim frm As New frmCobrar
frm.TotalVenta = varTotal
frm.StartPosition = FormStartPosition.CenterScreen
frm.ShowInTaskbar = False
frm.ShowDialog()
If (frm.Success) Then
lvVenta.Items.Clear()
End If
Else
MessageBox.Show("No hay elementos", "Informacin del Sistema",
MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End Sub

Form_Load:
Private Sub frmVenta_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Try
Encabezados()
MostrarVenta()
Catch ex As Exception
MessageBox.Show(ex.Message, "Informacin del Sistema", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub

Ahora vamos al furmulario mdiMain y creamos el siguiente proceso:


Protected Sub Ventas()
Dim frm As New frmVenta
frm.StartPosition =
FormStartPosition.CenterScreen
frm.ShowInTaskbar = False
frm.ShowDialog()
End Sub

De esta manera podremos mandar llamar al formulario frmVenta. Por ejemplo, si deseamos llamarlo desde el
botn btnVentas:
Private Sub btnVentas_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnVentas.Click
Ventas()

End Sub

Si todo est bien hasta este punto, hemos terminado el proceso de ventas. Mas adelante veremos como crear
el Ticket de Venta utlizando el generador de reportes de Visual Studio.

You might also like