You are on page 1of 12

Point of Sale in Visual Basic (Part 1)

Next Hello tyrodeveloper's, here is my first english publication, i hope that you like. Requirements: Microsoft Visual Studio 2010 Microsoft Access 2007/2010

Data Base Design We need to create a database like is showed in the picture:

Project creation We create a project called PointOfSale:

Here is the project organization:

We have three folders. Add two forms to the Forms folder and a module in the Modules folder like is showed in the picture. Login Form (frmLogin) Add this Imports directives:
Imports System.Data Imports System.Data.OleDb

Add this Variables:


''Variables Dim Attempts As Integer = 0 Public Shared UserLogin As String Public Shared FirstName As String Public Shared LastName As String Public Shared Sales As Boolean Public Shared Reporting As Boolean Public Shared Management As Boolean Public Shared Catalog As Boolean Public Shared Access As Boolean

Open the modMain.vb module and add this code:


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

Design the login form like this:

On the frmLogin.vb form, add this function:


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() FirstName = dr("FIRST_NAME").ToString() LastName = dr("LAST_NAME").ToString() Sales = CBool(dr("SALES")) Reporting = CBool(dr("REPORTING")) Management = CBool(dr("MANAGEMENT")) Catalog = CBool(dr("CATALOG")) Else Attempts += 1 Throw (New Exception( _ "Username or password incorrect")) End If dr.Close() Return True Catch ex As Exception Throw (ex) Finally cnn.Close() End Try End Function

And here is the code for the Ok button:


Private Sub btnOk_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnOk.Click Try If (Attempts >= 3) Then Access = False MessageBox.Show("Attempts exceeded", _ "System Information", _ MessageBoxButtons.OK, _ MessageBoxIcon.Error) Me.Close() Else Access = Login() If (Access) Then Me.Close() End If End If Catch ex As Exception MessageBox.Show(ex.Message, "System Information", _

MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub

Go to the project configuration and set:

Point of Sale in Visual Basic (Part 2)


Previous |Next Add two new forms (frmSale, frmPayment) like:

Design mdiMain like the picture:

Add this code on the "Form_Load":


''Allows mnuSales.Visible = frmLogin.Sales btnSales.Visible = frmLogin.Sales mnuReporting.Visible = frmLogin.Reporting mnuManagement.Visible = frmLogin.Management mnuCatalog.Visible = frmLogin.Catalog

Point of Sale in Visual Basic (Part 3)


Previous |Next Payment Window (frmPayment) Design the payment form like the picture :

Add three properties:


Protected _success As Boolean = False Public ReadOnly Property Success As Boolean Get Return _success End Get End Property

Protected _idSale As Integer = 0 Public ReadOnly Property IdSale As Integer Get Return _idSale End Get End Property Public Property TotalSale As Double Get Return varTotal End Get Set(ByVal value As Double) varTotal = value End Set End Property Dim varTotal As Double = 0

This is the function that saves the Sales:


Protected Function DoSale() As Boolean Dim cnn As New OleDbConnection(CnnStr) Dim RowCount As Integer = 0 Dim varFolioVenta As Integer = 0 _idSale = 0 Try cnn.Open() Dim tran As OleDbTransaction = cnn.BeginTransaction() Dim cmd As New OleDbCommand cmd.Connection = cnn cmd.Transaction = tran Try ''validate if exists product cmd.CommandText = "SELECT COUNT(*) " & _ "FROM SALE_DETAIL_TMP " & _ " WHERE USER_LOGIN=@USER_LOGIN" cmd.Parameters.Add("@USER_LOGIN", OleDbType.VarChar, _ 50).Value = frmLogin.UserLogin RowCount = CInt(cmd.ExecuteScalar) cmd.Parameters.Clear() ''Clerar parems If (RowCount = 0) Then Throw (New Exception("No Data")) End If ''insert the sale cmd.CommandText = "INSERT INTO SALE" & _ "(USER_LOGIN,REG_DATE," & _ " SALE_DATE,TOTAL,CASH,CHANGE)" & _ " VALUES (@USER_LOGIN,NOW(),NOW()," & _ " @TOTAL,@CASH,@CHANGE)" cmd.Parameters.Add("@USER_LOGIN", _ OleDbType.VarChar, 50).Value = frmLogin.UserLogin cmd.Parameters.Add("@TOTAL", _ OleDbType.Double).Value = varTotal cmd.Parameters.Add("@CASH", _ OleDbType.Double).Value = txtCash.Text cmd.Parameters.Add("@CHANGE", _ OleDbType.Double).Value = _ CDbl(txtCash.Text) - varTotal cmd.ExecuteNonQuery() cmd.Parameters.Clear() ''clear params ''get the Id cmd.CommandText = "SELECT @@IDENTITY" varFolioVenta = CInt(cmd.ExecuteScalar()) ''insert sale detail cmd.CommandText = "INSERT INTO SALE_DETAIL" & _ " (ID_SALE,ID_PRODUCT,QUANTITY," & _ " SALE_PRICE,TAX,BUY_PRICE)" & _ " SELECT @ID_SALE, ID_PRODUCT,QUANTITY," & _ " SALE_PRICE,TAX," & _ " BUY_PRICE FROM SALE_DETAIL_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() ''Clear params

''Update the Stock cmd.CommandText = "UPDATE PRODUCTS " & _ " INNER JOIN SALE_DETAIL_TMP " & _ " ON PRODUCTS.ID_PRODUCT = " & _ " SALE_DETAIL_TMP.ID_PRODUCT " & _ " SET PRODUCTS.STOCK = " & _ " PRODUCTS.STOCK-SALE_DETAIL_TMP.QUANTITY" + " WHERE ((SALE_DETAIL_TMP.USER_LOGIN= @USER_LOGIN));" cmd.Parameters.Add("@USER_LOGIN", _ OleDbType.VarChar, 50).Value = frmLogin.UserLogin cmd.ExecuteNonQuery() cmd.Parameters.Clear() ''Clear Params ''delete the temp table cmd.CommandText = "DELETE FROM SALE_DETAIL_TMP " & _ "WHERE USER_LOGIN=@USER_LOGIN" cmd.Parameters.Add("@USER_LOGIN", _ OleDbType.VarChar, 50).Value = frmLogin.UserLogin cmd.ExecuteNonQuery() _idSale = varFolioVenta ''set the ID 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

The "Ok" button:


Private Sub btnOk_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnOk.Click Try _success = DoSale() If (_success) Then Me.Close() End If Catch ex As Exception MessageBox.Show(ex.Message, "System Information", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub

The "Cancel" button:


Private Sub btnCancel_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnCancel.Click _success = False Me.Close() End Sub

The "txtCash" TextBox, when a key is pressed:


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

End Sub

The "Form_Load";
Private Sub frmPayment_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Try txtTotal.Text = String.Format("{0:C}", varTotal) txtTotal.Enabled = False txtChange.Enabled = False txtCash.Text = varTotal.ToString() Catch ex As Exception MessageBox.Show(ex.Message, "System Information", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub

Point of Sale in Visual Basic (Part 4)


Previous|Next Sales window (frmSale) Design the form like the picture:

Declare a variable to store the total:


Dim varTotal As Double = 0

The Sales logic process:


1.Type the Product ID and the Quantity 2.Validate if the Product exists on the Products Catalog. 3. 4.

5. 6.

If the Product does not exists generate an exception (Throw)

7.Validate if the product exists in the temporal sales list. 8. 9.

If not exists, add new.

10. If exists, update the Quantity

11. 12.

The function to add items to the temporal sales list:


Protected Function AddItem() As Boolean Dim cnn As New OleDbConnection(CnnStr) Dim RowCount As Integer = 0 Try cnn.Open() Dim cmd As New OleDbCommand cmd.Connection = cnn ''Validate if the product exists cmd.CommandText = "SELECT COUNT(*) FROM PRODUCTS " & _ "WHERE ID_PRODUCT=@ID_PRODUCT" cmd.Parameters.Add("@ID_PRODUCT", _ OleDbType.VarChar, 50).Value = txtIdProduct.Text RowCount = CInt(cmd.ExecuteScalar) cmd.Parameters.Clear() ''Clear params If (RowCount = 0) Then Throw (New Exception("The product does not exists")) End If ''Validate if the product is in the sales list cmd.CommandText = "SELECT COUNT(*) " & _ " FROM SALE_DETAIL_TMP " & _ " WHERE ID_PRODUCT=@ID_PRODUCT" & _ " AND USER_LOGIN=@USER_LOGIN" cmd.Parameters.Add("@ID_PRODUCT", _ OleDbType.VarChar, 50).Value = txtIdProduct.Text cmd.Parameters.Add("@USER_LOGIN", _ OleDbType.VarChar, 50).Value = frmLogin.UserLogin RowCount = CInt(cmd.ExecuteScalar) cmd.Parameters.Clear() ''Clear params If (RowCount = 0) Then ''Insert New cmd.CommandText = "INSERT INTO SALE_DETAIL_TMP " & _ " (USER_LOGIN, ID_PRODUCT,QUANTITY," & _ "SALE_PRICE,BUY_PRICE,TAX) " & _ " SELECT @USER_LOGIN, ID_PRODUCT, @QTY, " & _ " SALE_PRICE, BUY_PRICE, TAX " & _ " FROM PRODUCTS WHERE ID_PRODUCT=@ID_PRODUCT" cmd.Parameters.Add("@USER_LOGIN", _ OleDbType.VarChar, 50).Value = frmLogin.UserLogin cmd.Parameters.Add("@QTY", _ OleDbType.Double).Value = txtQuantity.Text cmd.Parameters.Add("@ID_PRODUCT", _ OleDbType.VarChar, 50).Value = txtIdProduct.Text Else ''Edit Quantity cmd.CommandText = "UPDATE SALE_DETAIL_TMP " & _ " SET QUANTITY = QUANTITY + @QTY " & _ " WHERE ID_PRODUCT=@ID_PRODUCTO " & _ " AND USER_LOGIN=@USER_LOGIN " cmd.Parameters.Add("@QTY", OleDbType.Double).Value = txtQuantity.Text cmd.Parameters.Add("@ID_PRODUCT", OleDbType.VarChar, 50).Value = txtIdProduct.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

The code to cancel the sales is:


Protected Function CancelSale() As Boolean Dim cnn As New OleDbConnection(CnnStr) Try cnn.Open() Dim cmd As New OleDbCommand cmd.Connection = cnn cmd.CommandText = "DELETE FROM SALE_DETAIL_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

To generate the ListView headers:


Protected Sub Headers() With lvSale .View = View.Details .FullRowSelect = True .GridLines = True .HideSelection = False .Columns.Add("Id", 50) .Columns.Add("Product", 250) .Columns.Add("Qty", 50, HorizontalAlignment.Right) .Columns.Add("Price", 50, HorizontalAlignment.Right) .Columns.Add("Total", 80, HorizontalAlignment.Right) End With End Sub

To display the temporal sale items:


Protected Sub DisplaySale() Dim cnn As New OleDbConnection(CnnStr) varTotal = 0 Try cnn.Open() Dim cmd As New OleDbCommand cmd.Connection = cnn cmd.CommandText = "SELECT P.ID_PRODUCT, " & _ "P.PRODUCT, T.QUANTITY, T.SALE_PRICE," & _ "(T.QUANTITY * T.SALE_PRICE) AS TOTAL " & _ " FROM SALE_DETAIL_TMP T, PRODUCTS P " & _ " WHERE T.ID_PRODUCT=P.ID_PRODUCT " & _ " 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 lvSale.Items.Clear() While (dr.Read()) With lvSale .Items.Add(dr("ID_PRODUCT").ToString()) .Items(i).SubItems.Add(dr("PRODUCT").ToString()) .Items(i).SubItems.Add(String.Format("{0:N}", dr("QUANTITY"))) .Items(i).SubItems.Add(String.Format("{0:C}", dr("SALE_PRICE"))) .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

The "Add" button:


Private Sub btnAdd_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnAdd.Click Try If (AddItem()) Then DisplaySale() txtQuantity.Text = "1" txtIdProduct.Text = "" txtIdProduct.Focus() End If Catch ex As Exception MessageBox.Show(ex.Message, "System Information", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub

The "Cancel" button:


Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click Try If (CancelSale()) Then lvSale.Items.Clear() End If Catch ex As Exception MessageBox.Show(ex.Message, "System Information", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub

The "Payment" button:


Private Sub btnPayment_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPayment.Click If (lvSale.Items.Count > 0) Then Dim frm As New frmPayment frm.TotalSale = varTotal frm.StartPosition = FormStartPosition.CenterScreen frm.ShowInTaskbar = False frm.ShowDialog() If (frm.Success) Then lvSale.Items.Clear() End If Else MessageBox.Show("No items", "System Information", MessageBoxButtons.OK, MessageBoxIcon.Error) End If End Sub

The "Form_Load" method:


Private Sub frmSale_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Try Headers() DisplaySale() Catch ex As Exception MessageBox.Show(ex.Message, "System Information", _ MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub

It is the end of the Sales process. After we do the reports using the Visual Studio Reporting options (rdlc reports). Thanks...