Vbnet+billing+software+source+code

CREATE TABLE tbl_Users (
    UserID INT PRIMARY KEY IDENTITY(1,1),
    Username NVARCHAR(50) NOT NULL,
    Password NVARCHAR(50) NOT NULL,
    Role NVARCHAR(20) NOT NULL -- Admin / Cashier
);

Add a PrintDocument and PrintPreviewDialog control to the form. Then handle the PrintPage event.

Private Sub btnPrint_Click(sender As Object, e As EventArgs) Handles btnPrint.Click
    PrintPreviewDialog1.Document = PrintDocument1
    PrintPreviewDialog1.ShowDialog()
End Sub

Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage Dim fontTitle As New Font("Arial", 18, FontStyle.Bold) Dim fontBody As New Font("Arial", 10) Dim yPos As Single = e.MarginBounds.Top Dim leftMargin As Single = e.MarginBounds.Left

e.Graphics.DrawString("TAX INVOICE", fontTitle, Brushes.Black, leftMargin, yPos)
yPos += 40
e.Graphics.DrawString("Invoice No: " & txtInvoiceNo.Text, fontBody, Brushes.Black, leftMargin, yPos)
yPos += 20
e.Graphics.DrawString("Date: " & txtInvoiceDate.Text, fontBody, Brushes.Black, leftMargin, yPos)
yPos += 30
' Draw headers
e.Graphics.DrawString("Item", fontBody, Brushes.Black, leftMargin, yPos)
e.Graphics.DrawString("Qty", fontBody, Brushes.Black, leftMargin + 200, yPos)
e.Graphics.DrawString("Rate", fontBody, Brushes.Black, leftMargin + 300, yPos)
e.Graphics.DrawString("Amount", fontBody, Brushes.Black, leftMargin + 400, yPos)
yPos += 20
For Each row As DataRow In dtDetails.Rows
    e.Graphics.DrawString(row("ProductName").ToString(), fontBody, Brushes.Black, leftMargin, yPos)
    e.Graphics.DrawString(row("Quantity").ToString(), fontBody, Brushes.Black, leftMargin + 200, yPos)
    e.Graphics.DrawString(row("Rate").ToString(), fontBody, Brushes.Black, leftMargin + 300, yPos)
    e.Graphics.DrawString(row("TaxableValue").ToString(), fontBody, Brushes.Black, leftMargin + 400, yPos)
    yPos += 20
Next
yPos += 20
e.Graphics.DrawString("Total: " & lblGrandTotal.Text, New Font("Arial", 12, FontStyle.Bold), Brushes.Black, leftMargin + 350, yPos)

End Sub

Public Class frmBilling
    Dim cartTable As New DataTable()
    Dim currentGrandTotal As Decimal = 0
Private Sub frmBilling_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    ' Define cart table columns
    cartTable.Columns.Add("ProductID", GetType(Integer))
    cartTable.Columns.Add("ProductName", GetType(String))
    cartTable.Columns.Add("Quantity", GetType(Integer))
    cartTable.Columns.Add("Price", GetType(Decimal))
    cartTable.Columns.Add("GST_Percent", GetType(Integer))
    cartTable.Columns.Add("GST_Amount", GetType(Decimal))
    cartTable.Columns.Add("Total", GetType(Decimal))
    dgvCart.DataSource = cartTable
End Sub
Private Sub txtProductCode_KeyDown(sender As Object, e As KeyEventArgs) Handles txtProductCode.KeyDown
    If e.KeyCode = Keys.Enter Then
        Dim productCode As String = txtProductCode.Text.Trim()
        Dim query As String = $"SELECT ProductID, ProductName, UnitPrice, StockQuantity, GST_Percent FROM tbl_Products WHERE ProductCode='productCode'"
        Dim dt As DataTable = ExecuteQuery(query)
If dt.Rows.Count > 0 Then
            Dim productID As Integer = dt.Rows(0)("ProductID")
            Dim pName As String = dt.Rows(0)("ProductName")
            Dim price As Decimal = Convert.ToDecimal(dt.Rows(0)("UnitPrice"))
            Dim gstPercent As Integer = Convert.ToInt32(dt.Rows(0)("GST_Percent"))
' Check if already in cart
            Dim existingRow() As DataRow = cartTable.Select($"ProductID = productID")
            If existingRow.Length > 0 Then
                existingRow(0)("Quantity") += 1
                Dim qty As Integer = Convert.ToInt32(existingRow(0)("Quantity"))
                Dim totalBeforeGST As Decimal = qty * price
                Dim gstAmt As Decimal = totalBeforeGST * (gstPercent / 100)
                existingRow(0)("GST_Amount") = gstAmt
                existingRow(0)("Total") = totalBeforeGST + gstAmt
            Else
                Dim gstAmt As Decimal = price * (gstPercent / 100)
                Dim totalWithGST As Decimal = price + gstAmt
                cartTable.Rows.Add(productID, pName, 1, price, gstPercent, gstAmt, totalWithGST)
            End If
            CalculateTotals()
            txtProductCode.Clear()
            txtProductCode.Focus()
        Else
            MessageBox.Show("Product not found!")
        End If
    End If
End Sub
Private Sub CalculateTotals()
    Dim subTotal As Decimal = 0
    Dim totalGST As Decimal = 0
    For Each row As DataRow In cartTable.Rows
        subTotal += Convert.ToDecimal(row("Price")) * Convert.ToInt32(row("Quantity"))
        totalGST += Convert.ToDecimal(row("GST_Amount"))
    Next
    Dim grandTotal As Decimal = subTotal + totalGST
    lblSubTotal.Text = subTotal.ToString("N2")
    lblGST.Text = totalGST.ToString("N2")
    lblGrandTotal.Text = grandTotal.ToString("N2")
    currentGrandTotal = grandTotal
End Sub
Private Sub btnGenerateInvoice_Click(sender As Object, e As EventArgs) Handles btnGenerateInvoice.Click
    If cartTable.Rows.Count = 0 Then
        MessageBox.Show("Cart is empty!")
        Return
    End If
Dim invoiceNo As String = "INV-" & DateTime.Now.ToString("yyyyMMddHHmmss")
    Dim customerID As Integer = GetOrCreateCustomer(txtCustomerMobile.Text) ' Function to fetch/add customer
    Dim userId As Integer = CurrentUserID ' Assume global login user ID
' Insert into tbl_Invoices
    Dim insertInvoice As String = $"INSERT INTO tbl_Invoices (InvoiceNo, CustomerID, SubTotal, GST_Amount, GrandTotal, UserID) VALUES ('invoiceNo', customerID, lblSubTotal.Text, lblGST.Text, lblGrandTotal.Text, userId)"
    ExecuteNonQuery(insertInvoice)
' Insert into tbl_InvoiceDetails
    For Each row As DataRow In cartTable.Rows
        Dim productID As Integer = Convert.ToInt32(row("ProductID"))
        Dim qty As Integer = Convert.ToInt32(row("Quantity"))
        Dim price As Decimal = Convert.ToDecimal(row("Price"))
        Dim gstAmt As Decimal = Convert.ToDecimal(row("GST_Amount"))
        Dim total As Decimal = Convert.ToDecimal(row("Total"))
Dim detailQuery As String = $"INSERT INTO tbl_InvoiceDetails (InvoiceNo, ProductID, Quantity, Price, GST_Amount, Total) VALUES ('invoiceNo', productID, qty, price, gstAmt, total)"
        ExecuteNonQuery(detailQuery)
' Reduce stock
        Dim updateStock As String = $"UPDATE tbl_Products SET StockQuantity = StockQuantity - qty WHERE ProductID = productID"
        ExecuteNonQuery(updateStock)
    Next
MessageBox.Show($"Invoice Generated: invoiceNo")
    PrintInvoice(invoiceNo)
    ' Clear cart and reset
    cartTable.Clear()
    CalculateTotals()
End Sub

End Class


Create a database named BillingDB and run the following scripts: vbnet+billing+software+source+code

The system uses a standard SQL Server connection.

Imports System.Data.SqlClient
Public Class DatabaseHelper
    ' Connection string should ideally be stored in a config file
    Private connString As String = "Data Source=.;Initial Catalog=BillingDB;Integrated Security=True"
Public Function GetConnection() As SqlConnection
        Return New SqlConnection(connString)
    End Function
' Generic method to execute Non-Query (Insert, Update, Delete)
    Public Function ExecuteNonQuery(query As String, parameters As List(Of SqlParameter)) As Boolean
        Using conn As SqlConnection = GetConnection()
            Using cmd As New SqlCommand(query, conn)
                If parameters IsNot Nothing Then
                    cmd.Parameters.AddRange(parameters.ToArray())
                End If
                conn.Open()
                Dim rowsAffected As Integer = cmd.ExecuteNonQuery()
                Return rowsAffected > 0
            End Using
        End Using
    End Function
End Class

Our billing software will include:

  • Transaction Module
  • Database Operations
  • Printing & PDF
  • Backup & Restore (Bonus)