diff --git a/AddPurchaseClass.py b/AddPurchaseClass.py
new file mode 100644
index 0000000..0b4de47
--- /dev/null
+++ b/AddPurchaseClass.py
@@ -0,0 +1,297 @@
+# Importing essential modules
+import typing
+from PyQt6 import QtCore, QtWidgets, uic
+from PyQt6.QtCore import QDate
+from PyQt6.QtWidgets import QApplication, QMessageBox,QMainWindow, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget, QHeaderView
+import sys
+import pyodbc
+
+from ConnectionString import connection, cursor
+
+class AddPurchaseScreen(QtWidgets.QMainWindow):
+ def __init__(self):
+ super(AddPurchaseScreen, self).__init__()
+ uic.loadUi("Screens/AddPurchase.ui", self)
+
+ self.PopulateMaterialTable()
+ self.PopulateVendorTable()
+
+ self.MaterialTable.itemSelectionChanged.connect(self.get_selected_material_data)
+ self.vendorTable.itemSelectionChanged.connect(self.get_selected_vendor_data)
+
+ self.MaterialID.setDisabled(True)
+ self.MaterialName.setDisabled(True)
+ self.VendorID.setDisabled(True)
+ self.VendorName.setDisabled(True)
+
+ self.AddMaterialVendor.clicked.connect(self.add_material)
+ self.AddPurchase.clicked.connect(self.add_purchase)
+ self.ClearPurchase.clicked.connect(self.clear)
+ self.SearchMaterial.clicked.connect(self.search_material)
+ self.SearchVendor.clicked.connect(self.search_vendor)
+
+
+ def PopulateMaterialTable(self):
+
+ cursor.execute("SELECT * FROM Material")
+ self.MaterialTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.MaterialTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.MaterialTable.setItem(row_index, col_index, item)
+
+ def PopulateVendorTable(self):
+
+ cursor.execute("SELECT * FROM Vendor")
+ self.vendorTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.vendorTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.vendorTable.setItem(row_index, col_index, item)
+
+ def get_selected_material_data(self):
+
+ selected_row = self.MaterialTable.currentRow()
+ if selected_row is not None:
+ MaterialID_item = self.MaterialTable.item(selected_row, 0)
+ MaterialName_item = self.MaterialTable.item(selected_row, 1)
+
+ if MaterialID_item is not None and MaterialName_item is not None:
+ MaterialID = MaterialID_item.text()
+ MaterialName = MaterialName_item.text()
+
+ self.MaterialID.setText(MaterialID)
+ self.MaterialName.setText(MaterialName)
+ else:
+ # Show an error message if the items are None
+ error_message = "Error: Row Already Selected!."
+ QMessageBox.critical(self, "Error", error_message)
+ else:
+ # Show an error message if no row is selected
+ error_message = "Error: No row is selected."
+ QMessageBox.critical(self, "Error", error_message)
+
+ def get_selected_vendor_data(self):
+ selected_row = self.vendorTable.currentRow()
+
+ if selected_row is not None:
+ VendorID_item = self.vendorTable.item(selected_row, 0)
+ VendorName_item = self.vendorTable.item(selected_row, 1)
+
+ if VendorID_item is not None and VendorName_item is not None:
+ VendorID = VendorID_item.text()
+ VendorName = VendorName_item.text()
+
+ self.VendorID.setText(VendorID)
+ self.VendorName.setText(VendorName)
+ else:
+ # Show an error message if the items are None
+ error_message = "Error: Row Already Selected!"
+ QMessageBox.critical(self, "Error", error_message)
+ else:
+ # Show an error message if no row is selected
+ error_message = "Error: No row is selected."
+ QMessageBox.critical(self, "Error", error_message)
+
+ def add_material(self):
+ # Get text from line edits
+ material_id = self.MaterialID.text()
+ material_name = self.MaterialName.text()
+ unit_cost = self.UnitCost.text()
+ quantity = self.Quantity.text()
+ vendor_id = self.VendorID.text()
+ vendor_name = self.VendorName.text()
+ total = int(quantity)*int(unit_cost)
+
+ # Check the condition
+ if (
+ material_id == ""
+ or material_name == ""
+ or unit_cost == ""
+ or quantity == ""
+ or vendor_id == ""
+ or vendor_name == ""
+ ):
+ msgBox = QtWidgets.QMessageBox()
+ msgBox.setText("Please Enter All Required Attributes!")
+ msgBox.setWindowTitle("Confirmation Box")
+ msgBox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
+ msgBox.exec()
+
+ else:
+ row_position = self.purchaseDetailsTable.rowCount()
+ self.purchaseDetailsTable.insertRow(row_position)
+
+ self.purchaseDetailsTable.setItem(
+ row_position, 0, QTableWidgetItem(material_id))
+ self.purchaseDetailsTable.setItem(
+ row_position, 1, QTableWidgetItem(material_name))
+ self.purchaseDetailsTable.setItem(
+ row_position, 2, QTableWidgetItem(vendor_id))
+ self.purchaseDetailsTable.setItem(
+ row_position, 3, QTableWidgetItem(vendor_name))
+ self.purchaseDetailsTable.setItem(
+ row_position, 4, QTableWidgetItem(unit_cost))
+ self.purchaseDetailsTable.setItem(
+ row_position, 5, QTableWidgetItem(quantity))
+ self.purchaseDetailsTable.setItem(
+ row_position, 6, QTableWidgetItem(str(total)))
+
+ self.MaterialID.setText("")
+ self.MaterialName.setText("")
+ self.UnitCost.setText("")
+ self.Quantity.setText("")
+ self.VendorID.setText("")
+ self.VendorName.setText("")
+
+ def add_purchase(self):
+
+ connection = pyodbc.connect(connection_string)
+ cursor = connection.cursor()
+
+ cursor.execute("SELECT max(purchaseid) AS PurchaseID from Purchase")
+ result = cursor.fetchone()
+ PurchaseID = result[0]+1
+
+ PurchaseDate = self.PurchaseDate.date().toString("yyyy-MM-dd")
+
+ num_rows = self.purchaseDetailsTable.rowCount()
+ TotalAmount = 0
+ for row in range(num_rows):
+ TotalAmount = TotalAmount + int(self.purchaseDetailsTable.item(row, 4).text()) * int(self.purchaseDetailsTable.item(row, 5).text())
+
+ VendorID = int(self.purchaseDetailsTable.item(row, 2).text())
+
+ sql_query = """
+ INSERT INTO [Purchase]
+ ([purchaseDate], [totalAmount], [vendorID])
+ VALUES (?, ?, ?)
+ """
+ cursor.execute(sql_query, (PurchaseDate, int(TotalAmount), int(VendorID)))
+ connection.commit()
+
+ for row in range(num_rows):
+
+ MaterialID = int(self.purchaseDetailsTable.item(row, 0).text())
+ VendorID = int(self.purchaseDetailsTable.item(row, 2).text())
+ UnitCost = int(self.purchaseDetailsTable.item(row, 4).text())
+ Quantity = int(self.purchaseDetailsTable.item(row, 5).text())
+
+ sql_query = """
+ INSERT INTO [PurchaseMaterial]
+ ([purchaseid], [materialID], [quantity], [cost])
+ VALUES (?, ?, ?, ?)
+ """
+ cursor.execute(sql_query, (int(PurchaseID), int(MaterialID), int(Quantity), int(UnitCost)))
+ connection.commit()
+
+ TotalAmount = TotalAmount + (Quantity*UnitCost)
+
+ sql_query = """
+ UPDATE Purchase
+ SET totalAmount = ?
+ WHERE purchaseid = (?)
+ """
+
+ cursor.execute(sql_query, (TotalAmount, PurchaseID))
+ connection.commit()
+
+ QtWidgets.QMessageBox.information(
+ self, "Purchase Added", f"Purchase ID: {PurchaseID} has been added successfully.")
+
+ connection.close()
+ self.close()
+
+ def clear(self):
+ self.MaterialID.setText("")
+ self.MaterialName.setText("")
+ self.UnitCost.setText("")
+ self.Quantity.setText("")
+ self.VendorID.setText("")
+ self.VendorName.setText("")
+ self.PurchaseDate.setDate(QDate(2000, 1, 1))
+ self.purchaseDetailsTable.setRowCount(0)
+
+ def search_material(self):
+ connection = pyodbc.connect(connection_string)
+ cursor = connection.cursor()
+
+ if self.MaterialDropDown.currentText() == 'Material ID':
+ try:
+ search_text = int(self.SearchMaterial_2.text())
+ cursor.execute("SELECT * from Material where materialID = ?", (search_text,))
+ except ValueError:
+ msgBox = QMessageBox()
+ msgBox.setText("Please enter a valid integer for Material ID.")
+ msgBox.setWindowTitle("Confirmation Box")
+ msgBox.setStandardButtons(QMessageBox.StandardButton.Ok)
+ msgBox.exec()
+ return
+
+ elif self.MaterialDropDown.currentText() == 'Material Name':
+ try:
+ search_text = str(self.SearchMaterial_2.text())
+ except ValueError:
+ msgBox = QMessageBox()
+ msgBox.setText("Please enter a valid string for Material Name.")
+ msgBox.setWindowTitle("Confirmation Box")
+ msgBox.setStandardButtons(QMessageBox.StandardButton.Ok)
+ msgBox.exec()
+ return
+
+ query = """
+ SELECT * from Material where materialName like (?)
+ """
+ cursor.execute(query, ('%' + search_text + '%'))
+
+ self.MaterialTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.MaterialTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.MaterialTable.setItem(row_index, col_index, item)
+
+ def search_vendor(self):
+ connection = pyodbc.connect(connection_string)
+ cursor = connection.cursor()
+
+ if self.VendorDropDown.currentText() == 'Vendor ID':
+ try:
+ search_text = int(self.SearchVendor_2.text())
+ cursor.execute("SELECT * from Vendor where vendorID = ?", (search_text,))
+ except ValueError:
+ msgBox = QMessageBox()
+ msgBox.setText("Please enter a valid integer for Vendor ID.")
+ msgBox.setWindowTitle("Confirmation Box")
+ msgBox.setStandardButtons(QMessageBox.StandardButton.Ok)
+ msgBox.exec()
+ return
+
+ elif self.VendorDropDown.currentText() == 'Vendor Name':
+ try:
+ search_text = str(self.SearchVendor_2.text())
+ except ValueError:
+ msgBox = QMessageBox()
+ msgBox.setText("Please enter a valid string for Vendor Name.")
+ msgBox.setWindowTitle("Confirmation Box")
+ msgBox.setStandardButtons(QMessageBox.StandardButton.Ok)
+ msgBox.exec()
+ return
+
+ query = """
+ SELECT * from Vendor where vendorName like (?)
+ """
+ cursor.execute(query, ('%' + search_text + '%'))
+
+ self.vendorTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.vendorTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.vendorTable.setItem(row_index, col_index, item)
\ No newline at end of file
diff --git a/AddSaleClass.py b/AddSaleClass.py
new file mode 100644
index 0000000..6305f29
--- /dev/null
+++ b/AddSaleClass.py
@@ -0,0 +1,379 @@
+# Importing essential modules
+import typing
+from PyQt6 import QtCore, QtWidgets, uic
+from PyQt6.QtCore import QDate
+from PyQt6.QtWidgets import QApplication, QMessageBox,QMainWindow, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget, QHeaderView
+import sys
+import pyodbc
+
+from ConnectionString import connection, cursor
+
+class AddSaleScreen(QtWidgets.QMainWindow):
+ def __init__(self):
+ super(AddSaleScreen, self).__init__()
+ uic.loadUi("Screens/AddSales.ui", self)
+
+ self.PopulateProductTable()
+ self.PopulateCustomerTable()
+
+ self.ProductTable.itemSelectionChanged.connect(self.get_selected_product_data)
+ self.CustomerTable.itemSelectionChanged.connect(self.get_selected_customer_data)
+
+ self.ProductID.setDisabled(True)
+ self.ProductName.setDisabled(True)
+ self.CustomerID.setDisabled(True)
+ self.CustomerName.setDisabled(True)
+
+ self.AddProductCustomer.clicked.connect(self.add_product_customer)
+ self.AddSale.clicked.connect(self.add_sale)
+ self.ClearSale.clicked.connect(self.clear)
+ self.SearchProduct.clicked.connect(self.search_product)
+ self.SearchCustomer.clicked.connect(self.search_customer)
+
+ def PopulateProductTable(self):
+
+ cursor.execute("SELECT * FROM Products")
+ self.ProductTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.ProductTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.ProductTable.setItem(row_index, col_index, item)
+
+ def PopulateCustomerTable(self):
+
+ cursor.execute("SELECT * FROM Customer")
+ self.CustomerTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.CustomerTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.CustomerTable.setItem(row_index, col_index, item)
+
+ def get_selected_product_data(self):
+
+ selected_row = self.ProductTable.currentRow()
+ if selected_row is not None:
+ ProductID_item = self.ProductTable.item(selected_row, 0)
+ ProductName_item = self.ProductTable.item(selected_row, 1)
+ ProductPrice_item = self.ProductTable.item(selected_row, 3)
+
+ if ProductID_item is not None and ProductName_item is not None:
+ ProductID = ProductID_item.text()
+ ProductName = ProductName_item.text()
+ ProductPrice = ProductPrice_item.text()
+
+ self.ProductID.setText(ProductID)
+ self.ProductName.setText(ProductName)
+ self.Price.setText(ProductPrice)
+ else:
+ error_message = "Error: No row is selected."
+ QMessageBox.critical(self, "Error", error_message)
+
+ def get_selected_customer_data(self):
+
+ selected_row = self.CustomerTable.currentRow()
+
+ if selected_row is not None:
+ CustomerID_item = self.CustomerTable.item(selected_row, 0)
+ CustomerName_item = self.CustomerTable.item(selected_row, 1)
+ Address_item = self.CustomerTable.item(selected_row, 6)
+ ContactNumber_item = self.CustomerTable.item(selected_row, 3)
+ BackupContactNumber_item = self.CustomerTable.item(selected_row, 4)
+ Email_item = self.CustomerTable.item(selected_row, 5)
+
+ if CustomerID_item is not None and CustomerName_item is not None and Address_item is not None and ContactNumber_item is not None and BackupContactNumber_item is not None and Email_item is not None:
+ CustomerID = CustomerID_item.text()
+ CustomerName = CustomerName_item.text()
+ Address = Address_item.text()
+ ContactNumber = ContactNumber_item.text()
+ BackupContactNumber = BackupContactNumber_item.text()
+ Email = Email_item.text()
+
+ self.CustomerID.setText(CustomerID)
+ self.CustomerName.setText(CustomerName)
+ self.Address.setText(Address)
+ self.ContactNumber.setText(ContactNumber)
+ self.BackupContactNumber.setText(BackupContactNumber)
+ self.Email.setText(Email)
+
+ else:
+ # Show an error message if the items are None
+ error_message = "Error: Row Already Selected!"
+ QMessageBox.critical(self, "Error", error_message)
+ else:
+ # Show an error message if no row is selected
+ error_message = "Error: No row is selected."
+ QMessageBox.critical(self, "Error", error_message)
+
+ def add_product_customer(self):
+ # Get text from line edits
+ product_id = self.ProductID.text()
+ product_name = self.ProductName.text()
+ quantity = self.Quantity.text()
+ customer_id = self.CustomerID.text()
+ customer_name = self.CustomerName.text()
+ price = self.Price.text()
+ discount = self.Discount.text()
+ address = self.Address.text()
+ contact_number = self.ContactNumber.text()
+ backup_contact_number = self.BackupContactNumber.text()
+ email = self.Email.text()
+ total = int(price)*int(quantity)
+
+ if (
+ product_id == ""
+ or product_name == ""
+ or quantity == ""
+ or customer_id == ""
+ or customer_name == ""
+ or price == ""
+ or discount == ""
+ or address == ""
+ or contact_number == ""
+ or backup_contact_number == ""
+ or email == ""
+ ):
+ msgBox = QtWidgets.QMessageBox()
+ msgBox.setText("Please Enter All Required Attributes!")
+ msgBox.setWindowTitle("Confirmation Box")
+ msgBox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
+ msgBox.exec()
+
+ else:
+
+ cursor.execute(" select quanityProduced from Products where ProductID = ? ", (product_id,))
+ availableQuantity = cursor.fetchone()
+
+ if int(availableQuantity.quanityProduced) >= int(quantity):
+
+ row_position = self.SaleDetailsTable.rowCount()
+ self.SaleDetailsTable.insertRow(row_position)
+
+ self.SaleDetailsTable.setItem(
+ row_position, 0, QTableWidgetItem(product_id))
+ self.SaleDetailsTable.setItem(
+ row_position, 1, QTableWidgetItem(product_name))
+ self.SaleDetailsTable.setItem(
+ row_position, 2, QTableWidgetItem(customer_id))
+ self.SaleDetailsTable.setItem(
+ row_position, 3, QTableWidgetItem(customer_name))
+ self.SaleDetailsTable.setItem(
+ row_position, 4, QTableWidgetItem(quantity))
+ self.SaleDetailsTable.setItem(
+ row_position, 5, QTableWidgetItem(price))
+ self.SaleDetailsTable.setItem(
+ row_position, 6, QTableWidgetItem(discount))
+ self.SaleDetailsTable.setItem(
+ row_position, 7, QTableWidgetItem(str(total)))
+
+ self.ProductID.setText("")
+ self.ProductName.setText("")
+ self.CustomerID.setText("")
+ self.CustomerName.setText("")
+ self.Price.setText("")
+ self.Quantity.setText("")
+ self.Discount.setText("")
+
+ else:
+ error_message = "Error: Required Quantity Is Not In Stock!."
+ QMessageBox.critical(self, "Error", error_message)
+
+ def add_sale(self):
+
+ connection = pyodbc.connect(connection_string)
+ cursor = connection.cursor()
+
+ cursor.execute("SELECT max(saleID) AS SaleID from Sale")
+ result = cursor.fetchone()
+ SaleID = result[0]+1
+ UserID = 2
+
+ SaleDate = self.SaleDate.date().toString("yyyy-MM-dd")
+
+ num_rows = self.SaleDetailsTable.rowCount()
+ TotalAmount = 0
+ for row in range(num_rows):
+ TotalAmount = TotalAmount + int(self.SaleDetailsTable.item(row, 4).text()) * int(self.SaleDetailsTable.item(row, 5).text())
+
+ CustomerID = int(self.SaleDetailsTable.item(row, 2).text())
+
+ sql_query = """
+ INSERT INTO [Sale]
+ ([saleDate], [totalAmount], [customerID], [userID])
+ VALUES (?, ?, ?, ?)
+ """
+ cursor.execute(sql_query, (SaleDate, int(TotalAmount), int(CustomerID), UserID))
+ connection.commit()
+
+ for row in range(num_rows):
+
+ ProductID = int(self.SaleDetailsTable.item(row, 0).text())
+ CustomerID = int(self.SaleDetailsTable.item(row, 2).text())
+ Quantity = int(self.SaleDetailsTable.item(row, 4).text())
+ Price = int(self.SaleDetailsTable.item(row, 5).text())
+ Discount = int(self.SaleDetailsTable.item(row, 6).text())
+
+ sql_query = """
+ INSERT INTO [SaleProduct]
+ ([Saleid], [ProductID], [quantity], [soldPrice], [discount])
+ VALUES (?, ?, ?, ?, ?)
+ """
+ cursor.execute(sql_query, (int(SaleID), int(ProductID), int(Quantity), int(Price), int(Discount)))
+ connection.commit()
+
+ sql_query = """
+ UPDATE Products
+ SET quanityProduced = quanityProduced - (?)
+ WHERE productID = (?)
+ """
+ cursor.execute(sql_query, (Quantity, ProductID))
+ connection.commit()
+
+ TotalAmount += Quantity*Price
+
+ sql_query = """
+ UPDATE Sale
+ SET totalAmount = ?
+ WHERE saleID = (?)
+ """
+
+ cursor.execute(sql_query, (TotalAmount, SaleID))
+ connection.commit()
+
+ QtWidgets.QMessageBox.information(
+ self, "Sale Added", f"Sale ID: {SaleID} has been added successfully.")
+
+ connection.close()
+ self.close()
+
+ def clear(self):
+ self.ProductID.setText("")
+ self.ProductName.setText("")
+ self.Quantity.setText("")
+ self.Price.setText("")
+ self.Discount.setText("")
+ self.CustomerName.setText("")
+ self.SaleDate.setDate(QDate(2000, 1, 1))
+ self.CustomerID.setText("")
+ self.ContactNumber.setText("")
+ self.BackupContactNumber.setText("")
+ self.Email.setText("")
+ self.Address.setText("")
+ self.SaleDetailsTable.setRowCount(0)
+
+ def search_product(self):
+ connection = pyodbc.connect(connection_string)
+ cursor = connection.cursor()
+
+ if self.ProductDropDown.currentText() == 'Product ID':
+ try:
+ search_text = int(self.SearchProductBar.text())
+ cursor.execute("SELECT * from Products where productID = ?", (search_text,))
+
+ self.ProductTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.ProductTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.ProductTable.setItem(row_index, col_index, item)
+
+ except ValueError:
+ msgBox = QtWidgets.QMessageBox()
+ msgBox.setText("Please enter a valid integer for Product ID.")
+ msgBox.setWindowTitle("Confirmation Box")
+ msgBox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
+ msgBox.exec()
+ return
+
+ elif self.ProductDropDown.currentText() == 'Product Name':
+ try:
+ search_text = str(self.SearchProductBar.text())
+ query = """ SELECT * from Products where productName like (?) """
+ cursor.execute(query, ('%' + search_text + '%'))
+
+ self.ProductTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.ProductTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.ProductTable.setItem(row_index, col_index, item)
+
+ except ValueError:
+ msgBox = QtWidgets.QMessageBox()
+ msgBox.setText("Please enter a valid string for Product Name.")
+ msgBox.setWindowTitle("Confirmation Box")
+ msgBox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
+ msgBox.exec()
+ return
+
+ elif self.ProductDropDown.currentText() == 'Select':
+ cursor.execute("SELECT * FROM Products")
+ self.ProductTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.ProductTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.ProductTable.setItem(row_index, col_index, item)
+
+ def search_customer(self):
+ connection = pyodbc.connect(connection_string)
+ cursor = connection.cursor()
+
+ if self.CustomerDropDown.currentText() == 'Customer ID':
+ try:
+ search_text = int(self.SearchCustomerBar.text())
+ cursor.execute("SELECT * from Customer where customerID = ?", (search_text,))
+
+ self.CustomerTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.CustomerTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.CustomerTable.setItem(row_index, col_index, item)
+
+ except ValueError:
+ msgBox = QtWidgets.QMessageBox()
+ msgBox.setText("Please enter a valid integer for Customer ID.")
+ msgBox.setWindowTitle("Confirmation Box")
+ msgBox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
+ msgBox.exec()
+ return
+
+ elif self.CustomerDropDown.currentText() == 'Customer Name':
+ try:
+ search_text = str(self.SearchCustomerBar.text())
+ query = """ SELECT * from Customer where customerName like (?) """
+ cursor.execute(query, ('%' + search_text + '%'))
+
+ self.CustomerTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.CustomerTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.CustomerTable.setItem(row_index, col_index, item)
+
+ except ValueError:
+ msgBox = QtWidgets.QMessageBox()
+ msgBox.setText("Please enter a valid string for Customer Name.")
+ msgBox.setWindowTitle("Confirmation Box")
+ msgBox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
+ msgBox.exec()
+ return
+
+ else:
+ cursor.execute("SELECT * FROM Customer")
+ self.CustomerTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.CustomerTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.CustomerTable.setItem(row_index, col_index, item)
\ No newline at end of file
diff --git a/ConnectionString.py b/ConnectionString.py
new file mode 100644
index 0000000..56b4299
--- /dev/null
+++ b/ConnectionString.py
@@ -0,0 +1,19 @@
+import pyodbc
+server = 'DESKTOP-UMMHQQL\SQLEXPRESS01'
+database = 'Inventory_Management_System' # Name of your Northwind database
+use_windows_authentication = False # Set to True to use Windows Authentication
+username = 'sa' # Specify a username if not using Windows Authentication
+password = 'Sirmehdi69' # Specify a password if not using Windows Authentication
+
+if use_windows_authentication:
+ connection_string = f'DRIVER={{ODBC Driver 17 for SQL Server}};SERVER={server};DATABASE={database};Trusted_Connection=yes;'
+else:
+ connection_string = (
+ 'DRIVER={ODBC Driver 18 for SQL Server};SERVER=localhost;DATABASE=Inventory_Management_System;UID=sa;PWD=Sirmehdi69;TrustServerCertificate=yes;Connection Timeout=30;'
+ )
+
+# Establish a connection to the database
+connection = pyodbc.connect(connection_string)
+
+# Create a cursor to interact with the database
+cursor = connection.cursor()
\ No newline at end of file
diff --git a/CustomerClass.py b/CustomerClass.py
new file mode 100644
index 0000000..5bbae18
--- /dev/null
+++ b/CustomerClass.py
@@ -0,0 +1,149 @@
+# Importing essential modules
+from PyQt6 import QtWidgets, uic
+from PyQt6.QtCore import QDate
+from PyQt6.QtWidgets import QApplication, QMainWindow, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget, QHeaderView
+import sys
+import pyodbc
+import EditCustomerClass
+
+from ConnectionString import connection, cursor
+
+class CustomerScreen(QtWidgets.QMainWindow):
+ def __init__(self):
+ # Call the inherited classes __init__ method
+ super(CustomerScreen, self).__init__()
+
+ # Load the .ui file
+ uic.loadUi('Screens/Customers.ui', self)
+
+ self.PopulateCustomerTable()
+ self.searchCustomerValue.setPlaceholderText("Search")
+ self.addCustomerButton.clicked.connect(self.AddCustomer)
+ self.editCustomerButton.clicked.connect(self.EditCustomer)
+ self.searchCustomerButton.clicked.connect(self.SearchCustomer)
+ self.deleteCustomerButton.clicked.connect(self.DeleteCustomer)
+
+ def PopulateCustomerTable(self):
+ cursor.execute("select * from Customer")
+ self.customerTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.customerTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.customerTable.setItem(row_index, col_index, item)
+
+ def AddCustomer(self):
+ name = self.customerName.text()
+ gender = self.customerGender.currentText()
+ contact = self.customerContact.text()
+ backupContact = self.customerBackup.text()
+ email = self.customerEmail.text()
+ address = self.customerAddress.text()
+ self.msg = QtWidgets.QMessageBox()
+ if name == '' or contact == '' or backupContact == '' or email == '' or address == '':
+ self.msg.setWindowTitle("Error")
+ self.msg.setText("Please enter complete information.")
+ else:
+ sql_query = "insert into Customer values(?, ?, ?, ?, ?, ?)"
+ cursor.execute(sql_query, (name, gender, contact, backupContact, email, address))
+ connection.commit()
+ self.msg.setWindowTitle("Success")
+ self.msg.setText("Customer added successfully.")
+ self.PopulateCustomerTable()
+ self.msg.show()
+
+ def SearchCustomer(self):
+ criteria = self.searchCustomerCriteria.currentText()
+ if criteria == "Customer Name":
+ criteria = "customerName"
+ elif criteria == "Contact Number":
+ criteria = "contactNumber"
+ elif criteria == "Email":
+ criteria = "email"
+ value = self.searchCustomerValue.text()
+ if not value:
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Error")
+ self.msg.setText("Please enter a search value.")
+ self.msg.show()
+ return
+
+ sql_query = f"select * from Customer where {criteria} like ?"
+ cursor.execute(sql_query, ('%' + value + '%',))
+
+ rows = cursor.fetchall()
+
+ if not rows:
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("No Results")
+ self.msg.setText("No results found for the given search criteria.")
+ self.msg.show()
+ self.PopulateCustomerTable()
+ return
+
+ self.customerTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(rows):
+ self.customerTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.customerTable.setItem(row_index, col_index, item)
+
+ def EditCustomer(self):
+ selected_items = self.customerTable.selectedItems()
+
+ if not selected_items:
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Error")
+ self.msg.setText("Please select an entry to edit.")
+ self.msg.show()
+ return
+
+ selected_row = selected_items[0].row()
+ customer_data = [self.customerTable.item(selected_row, col_index).text() for col_index in range(self.customerTable.columnCount())]
+
+ self.editCustomer = EditCustomerClass.EditCustomerScreen(customer_data)
+ self.editCustomer.customerUpdated.connect(self.PopulateCustomerTable)
+ self.editCustomer.show()
+
+ def DeleteCustomer(self):
+ selected_items = self.customerTable.selectedItems()
+
+ if not selected_items:
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Error")
+ self.msg.setText("Please select an entry to delete.")
+ self.msg.show()
+ return
+
+ selected_row = selected_items[0].row()
+ customer_id = int(self.customerTable.item(selected_row, 0).text())
+
+ # Code block to check if the customer has made any sale. If yes, then customer cannot be deleted
+ sql_check_sales = "select count(*) from Sale where customerID = ?"
+ cursor.execute(sql_check_sales, (customer_id,))
+ result = cursor.fetchone()
+
+ # Throw error message if customers has pre-existing sales record
+ if result and result[0] > 0:
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Error")
+ self.msg.setText("Cannot delete customer with existing sales records.")
+ self.msg.show()
+ return
+
+ # Delete if customer has no sales record
+ sql_query = "delete from Customer WHERE customerID = ?"
+ cursor.execute(sql_query, (customer_id))
+ connection.commit()
+
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Success")
+ self.msg.setText("Customer deleted successfully.")
+ self.msg.show()
+
+ self.PopulateCustomerTable() # Update the vendorTable after deletion
+
+
+
diff --git a/EditCustomerClass.py b/EditCustomerClass.py
new file mode 100644
index 0000000..7b99565
--- /dev/null
+++ b/EditCustomerClass.py
@@ -0,0 +1,71 @@
+import typing
+from PyQt6 import QtCore, QtWidgets, uic
+from PyQt6.QtCore import QDate
+from PyQt6.QtWidgets import QApplication, QMessageBox,QMainWindow, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget, QHeaderView
+import sys
+import pyodbc
+
+from ConnectionString import connection, cursor
+
+class EditCustomerScreen(QtWidgets.QMainWindow):
+ customerUpdated = QtCore.pyqtSignal()
+ def __init__(self, customer_data):
+ super(EditCustomerScreen, self).__init__()
+ uic.loadUi('Screens/EditCustomer.ui', self)
+
+ # Assuming your UI file has QLineEdit widgets named vendorNameEdit, contactNumberEdit, emailEdit, addressEdit
+ self.nameText.setText(customer_data[1])
+ self.contactText.setText(customer_data[3])
+ self.backupText.setText(customer_data[4])
+ self.emailText.setText(customer_data[5])
+ self.addressText.setText(customer_data[6])
+ gender_index = self.genderComboBox.findText(customer_data[2])
+ if gender_index != -1:
+ self.genderComboBox.setCurrentIndex(gender_index)
+
+ # Save customer_data as an instance variable
+ self.customer_data = customer_data
+
+ self.clearButton.clicked.connect(self.ClearEntries)
+ self.saveButton.clicked.connect(self.SaveChanges)
+
+ def ClearEntries(self):
+ # Reset the text of the QLineEdit widgets to an empty string
+ self.nameText.clear()
+ self.contactText.clear()
+ self.backupText.clear()
+ self.emailText.clear()
+ self.addressText.clear()
+
+ def SaveChanges(self):
+ # Get the updated information from the QLineEdit widgets
+ updated_name = self.nameText.text()
+ updated_gender = self.genderComboBox.currentText()
+ updated_contact = self.contactText.text()
+ updated_backup = self.backupText.text()
+ updated_email = self.emailText.text()
+ updated_address = self.addressText.text()
+
+ # Assuming vendor_id is the first element in vendor_data
+ customer_id = self.customer_data[0]
+
+ self.msg = QtWidgets.QMessageBox()
+ if updated_name == '' or updated_contact == '' or updated_backup == '' or updated_email == '' or updated_address == '':
+ self.msg.setWindowTitle("Error")
+ self.msg.setText("Please enter complete information.")
+ self.msg.show()
+ else:
+ # Run SQL query to update records in the database
+ update_query = "UPDATE Customer SET customerName=?, gender=?, contactNumber=?, backupContact=?, email=?, address=? WHERE customerID=?"
+ cursor.execute(update_query, (updated_name, updated_gender ,updated_contact, updated_backup, updated_email, updated_address, customer_id))
+ connection.commit()
+
+ # Optionally, show a success message
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Success")
+ self.msg.setText("Customer information updated successfully.")
+ self.msg.show()
+
+ # Emit the signal indicating that the vendor has been updated
+ self.customerUpdated.emit()
+
diff --git a/EditMaterialClass.py b/EditMaterialClass.py
new file mode 100644
index 0000000..3d6a451
--- /dev/null
+++ b/EditMaterialClass.py
@@ -0,0 +1,48 @@
+import typing
+from PyQt6 import QtCore, QtWidgets, uic
+from PyQt6.QtCore import QDate
+from PyQt6.QtWidgets import QApplication, QMessageBox,QMainWindow, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget, QHeaderView
+import sys
+import pyodbc
+
+from ConnectionString import connection, cursor
+
+class EditMaterialScreen(QtWidgets.QMainWindow):
+ def __init__(self, id, name, desc, units):
+ # Call the inherited classes __init__ method
+ super(EditMaterialScreen, self).__init__()
+
+ # Load the .ui file
+ uic.loadUi('Screens/EditMaterial.ui', self)
+
+ self.materialIdBox.setText(id)
+ self.materialNameBox.setText(name)
+ self.unitsBox.setText(units)
+ self.materialDescBox.setPlainText(desc)
+
+ self.cancelButton.clicked.connect(self.CancelEdit)
+ self.doneButton.clicked.connect(self.EditDone)
+
+ def CancelEdit(self):
+ self.close()
+
+ def EditDone(self):
+ id = self.materialIdBox.text()
+ newName = self.materialNameBox.text()
+ newUnits = self.unitsBox.text()
+ newDesc = self.materialDescBox.toPlainText()
+
+ sql_query = """
+ update material
+ set materialName = (?), description = (?), units = (?)
+ where materialID = (?)
+ """
+
+ cursor.execute(sql_query, (newName, newDesc, newUnits, id))
+ connection.commit()
+
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Success")
+ self.msg.setText("Edit done successfully.")
+ self.msg.show()
+
diff --git a/EditProductClass.py b/EditProductClass.py
new file mode 100644
index 0000000..b56b547
--- /dev/null
+++ b/EditProductClass.py
@@ -0,0 +1,54 @@
+import typing
+from PyQt6 import QtCore, QtWidgets, uic
+from PyQt6.QtCore import QDate
+from PyQt6.QtWidgets import QApplication, QMessageBox,QMainWindow, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget, QHeaderView
+import sys
+import pyodbc
+
+from ConnectionString import connection, cursor
+
+class EditProductScreen(QtWidgets.QMainWindow):
+ def __init__(self, id, name, qtyProduced, currentPrice, categoryName, desc):
+ super(EditProductScreen, self).__init__()
+ uic.loadUi("Screens/EditProducts.ui", self)
+
+ # self.productId = id
+ self.productIdBox.setText(id)
+ self.productNameBox.setText(name)
+ self.qtyProducedBox.setText(qtyProduced)
+ self.priceBox.setText(currentPrice)
+ self.categoryBox.setCurrentText(categoryName)
+ self.productDesc.setText(desc)
+
+ self.cancelButton.clicked.connect(self.CancelEdit)
+ self.doneButton.clicked.connect(self.DoneEdit)
+
+ def CancelEdit(self):
+ self.close()
+
+ def DoneEdit(self):
+ id = self.productIdBox.text()
+ newName = self.productNameBox.text()
+ newQuantityProduced = self.qtyProducedBox.text()
+ newPrice = self.priceBox.text()
+ newCategory = self.categoryBox.currentText()
+ newDesc = self.productDesc.toPlainText()
+
+ cursor.execute('select categoryId from category where categoryName = (?)', (newCategory,))
+ categoryID = cursor.fetchone()
+ categoryID = categoryID[0] if categoryID else None
+
+ sql_query = """
+ update products
+ set productName = (?), quantityProduced = (?), price = (?),
+ categoryID = (?), description = (?)
+ where productID = (?)
+ """
+ cursor.execute(sql_query, (newName, newQuantityProduced, newPrice, categoryID, newDesc, id))
+ connection.commit()
+
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle('Success')
+ self.msg.setText('Product edit successful')
+
+ self.msg.show()
diff --git a/EditVendorClass.py b/EditVendorClass.py
new file mode 100644
index 0000000..b6f789a
--- /dev/null
+++ b/EditVendorClass.py
@@ -0,0 +1,66 @@
+import typing
+from PyQt6 import QtCore, QtWidgets, uic
+from PyQt6.QtCore import QDate
+from PyQt6.QtWidgets import QApplication, QMessageBox,QMainWindow, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget, QHeaderView
+import sys
+import pyodbc
+
+from ConnectionString import connection, cursor
+
+class EditVendorScreen(QtWidgets.QMainWindow):
+ vendorUpdated = QtCore.pyqtSignal()
+ def __init__(self, vendor_data):
+ super(EditVendorScreen, self).__init__()
+ uic.loadUi('Screens/EditVendors.ui', self)
+
+ self.nameText.setText(vendor_data[1])
+ self.contactText.setText(vendor_data[2])
+ self.backupText.setText(vendor_data[3])
+ self.emailText.setText(vendor_data[4])
+ self.addressText.setText(vendor_data[5])
+
+ # Save vendor_data as an instance variable
+ self.vendor_data = vendor_data
+
+ self.resetButton.clicked.connect(self.ResetEntries)
+ self.saveButton.clicked.connect(self.SaveChanges)
+
+ def ResetEntries(self):
+ # Reset the text of the QLineEdit widgets to an empty string
+ self.nameText.clear()
+ self.contactText.clear()
+ self.backupText.clear()
+ self.emailText.clear()
+ self.addressText.clear()
+
+ def SaveChanges(self):
+ # Get the updated information from the QLineEdit widgets
+ updated_name = self.nameText.text()
+ updated_contact = self.contactText.text()
+ updated_backup = self.backupText.text()
+ updated_email = self.emailText.text()
+ updated_address = self.addressText.text()
+
+ # Assuming vendor_id is the first element in vendor_data
+ vendor_id = self.vendor_data[0]
+
+ self.msg = QtWidgets.QMessageBox()
+ if updated_name == '' or updated_contact == '' or updated_backup == '' or updated_email == '' or updated_address == '':
+ self.msg.setWindowTitle("Error")
+ self.msg.setText("Please enter complete information.")
+ self.msg.show()
+ else:
+ # Run SQL query to update records in the database
+ update_query = "UPDATE Vendor SET vendorName=?, contactNumber=?, backupContact=?, email=?, address=? WHERE vendorID=?"
+ cursor.execute(update_query, (updated_name, updated_contact, updated_backup, updated_email, updated_address, vendor_id))
+ connection.commit()
+
+ # Optionally, show a success message
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Success")
+ self.msg.setText("Vendor information updated successfully.")
+ self.msg.show()
+
+ # Emit the signal indicating that the vendor has been updated
+ self.vendorUpdated.emit()
+
diff --git a/MaterialClass.py b/MaterialClass.py
new file mode 100644
index 0000000..70eba83
--- /dev/null
+++ b/MaterialClass.py
@@ -0,0 +1,193 @@
+import typing
+from PyQt6 import QtCore, QtWidgets, uic
+from PyQt6.QtCore import QDate
+from PyQt6.QtWidgets import QApplication, QMessageBox,QMainWindow, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget, QHeaderView
+import sys
+import pyodbc
+from EditMaterialClass import EditMaterialScreen
+
+from ConnectionString import connection, cursor
+
+class MaterialScreen(QtWidgets.QMainWindow):
+ def __init__(self):
+ # Call the inherited classes __init__ method
+ super(MaterialScreen, self).__init__()
+
+ # Load the .ui file
+ uic.loadUi('Screens/Materials.ui', self)
+
+ self.PopulateMaterialTable()
+
+ self.searchMaterialButton.clicked.connect(self.SearchMaterial)
+
+ self.editMaterialButton.clicked.connect(self.EditMaterial)
+
+ # self.refreshButton.clicked.connect(self.ClearSearch)
+
+ self.deleteButton.clicked.connect(self.DeleteMaterial)
+
+ self.addMaterialButton.clicked.connect(self.AddMaterial)
+
+ self.clearMaterialButton.clicked.connect(self.ClearMaterialInfo)
+
+ def ClearMaterialInfo(self):
+ self.materialNameBox.setText('')
+ self.unitsBox.setText('')
+ self.materialDescBox.setText('')
+
+ def AddMaterial(self):
+ name = self.materialNameBox.text()
+ units = self.unitsBox.text()
+ desc = self.materialDescBox.toPlainText()
+
+ self.msg = QtWidgets.QMessageBox()
+
+ if name == '' or units == '' or desc == '':
+ self.msg.setWindowTitle('Error')
+ self.msg.setText('Please enter complete info')
+ else:
+ if not units.isdigit():
+ self.msg.setWindowTitle('Error')
+ self.msg.setText('Units should be a numeric value')
+ self.msg.show()
+ else:
+ sql_query = f"insert into Material values(?, ?, ?)"
+ cursor.execute(sql_query, (name, desc, units))
+ connection.commit()
+
+ self.msg.setWindowTitle('Success')
+ self.msg.setText('Material added successfully')
+
+ self.PopulateMaterialTable()
+
+ self.msg.show()
+
+ # def ClearSearch(self):
+ # self.PopulateMaterialTable()
+ # self.searchMaterialValue.setText('')
+
+ def EditMaterial(self):
+ row = self.materialTable.currentRow()
+ id = self.materialTable.item(row, 0).text()
+ name = self.materialTable.item(row, 1).text()
+ desc = self.materialTable.item(row, 2).text()
+ units = self.materialTable.item(row, 3).text()
+
+ self.editMaterialScreen = EditMaterialScreen(id, name, desc, units)
+ self.editMaterialScreen.show()
+
+ def PopulateMaterialTable(self):
+ cursor.execute('select * from material')
+ self.materialTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.materialTable.insertRow(row_index)
+
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.materialTable.setItem(row_index, col_index, item)
+
+ def SearchMaterial(self):
+ criteria = self.searchMaterialCriteria.currentText().strip()
+ criteriaValue = self.searchMaterialValue.text().strip()
+
+ if (criteria != '' and criteriaValue != ''):
+ # print('criteria: ', criteria)
+
+ if criteria == 'Material Name':
+ sql_query = 'select * from Material where materialName like (?)'
+ cursor.execute(sql_query, ('%' + criteriaValue + '%',))
+ #connection.commit()
+ self.materialTable.clearContents()
+ self.materialTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ print('populating row')
+ self.materialTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ print('Adding item to material table.')
+ self.materialTable.setItem(row_index, col_index, item)
+
+ elif criteria == 'Description':
+ sql_query = 'select * from Material where description like (?)'
+ cursor.execute(sql_query, ('%' + criteriaValue + '%',))
+ #connection.commit()
+ self.materialTable.clearContents()
+ self.materialTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ print('populating row')
+ self.materialTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ print('Adding item to material table.')
+ self.materialTable.setItem(row_index, col_index, item)
+
+ elif criteria == 'Units':
+ if criteriaValue.isdigit():
+ sql_query = 'select * from Material where units = (?)'
+ cursor.execute(sql_query, (criteriaValue,))
+
+ self.materialTable.clearContents()
+ self.materialTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ print('populating row')
+ self.materialTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ print('Adding item to material table.')
+ self.materialTable.setItem(row_index, col_index, item)
+
+ else:
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle('Error')
+ self.msg.setText('Units should be a numeric value')
+ self.msg.show()
+
+ print('Query executed')
+
+ else:
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle('Error')
+ self.msg.setText('Please select search criteria and/or enter search value')
+
+ def DeleteMaterial(self):
+ selected_items = self.materialTable.selectedItems()
+
+ if not selected_items:
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Error")
+ self.msg.setText("Please select an entry to delete.")
+ self.msg.show()
+ return
+
+ # Assuming the first column contains a unique identifier (e.g., vendor_id)
+ selected_row = selected_items[0].row()
+ material_id = int(self.materialTable.item(selected_row, 0).text())
+
+ # Code block to check if the material exists as foreign key in another table.
+ sql_check_material = "select count(*) from PurchaseMaterial where materialID = ?"
+ cursor.execute(sql_check_material, (material_id,))
+ result = cursor.fetchone()
+
+ # Throw error message if customers has pre-existing sales record
+ if result and result[0] > 0:
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Error")
+ self.msg.setText("Cannot delete material that has been purchased.")
+ self.msg.show()
+ return
+
+ sql_query = "delete from Material WHERE materialID = ?"
+ cursor.execute(sql_query, (material_id))
+ connection.commit()
+
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Success")
+ self.msg.setText("Material deleted successfully.")
+ self.msg.show()
+
+ self.PopulateMaterialTable() # Update the vendorTable after deletion
+
diff --git a/ProductsClass.py b/ProductsClass.py
new file mode 100644
index 0000000..1e3a1a8
--- /dev/null
+++ b/ProductsClass.py
@@ -0,0 +1,190 @@
+import typing
+from PyQt6 import QtCore, QtWidgets, uic
+from PyQt6.QtCore import QDate
+from PyQt6.QtWidgets import QApplication, QMessageBox,QMainWindow, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget, QHeaderView
+import sys
+import pyodbc
+from EditProductClass import EditProductScreen
+
+from ConnectionString import connection, cursor
+
+class ProductScreen(QtWidgets.QMainWindow):
+ def __init__(self):
+ # Call the inherited classes __init__ method
+ super(ProductScreen, self).__init__()
+
+ # Load the .ui file
+ uic.loadUi('Screens/Products.ui', self)
+
+ self.PopulateProductTable()
+
+ self.addProductButton.clicked.connect(self.AddProduct)
+
+ self.searchProductButton.clicked.connect(self.SearchProduct)
+
+ self.clearProductButton.clicked.connect(self.ClearProduct)
+
+ # self.productTable.itemClicked.connect(self.EditProduct)
+ # self.editProductButton.clicked.connect(self.OpenProductToEdit(id, self.name, self.qtyProduced, self.currentPrice, self.categoryName, self.desc))
+
+ self.editProductButton.clicked.connect(self.EditProduct)
+ self.deleteProductButton.clicked.connect(self.DeleteProduct)
+ # row = id = name = desc = currentPrice = qtyProduced = categoryName = None
+
+ def EditProduct(self):
+ # row = product.row()
+ row = self.productTable.currentRow()
+ id = self.productTable.item(row, 0).text()
+ name = self.productTable.item(row, 1).text()
+ desc = self.productTable.item(row, 2).text()
+ currentPrice = self.productTable.item(row, 3).text()
+ qtyProduced = self.productTable.item(row, 4).text()
+ categoryName = self.productTable.item(row, 6).text()
+
+ self.editProductScreen = EditProductScreen(id, name, qtyProduced, currentPrice, categoryName, desc)
+ self.editProductScreen.show()
+
+ # self.editProductButton.clicked.connect(self.OpenProductToEdit(id, self.name, self.qtyProduced, self.currentPrice, self.categoryName, self.desc))
+ # self.OpenProductToEdit(id, name, qtyProduced, currentPrice, categoryName, desc)
+
+ # def OpenProductToEdit(self, id, name, qtyProduced, currentPrice, categoryName, desc):
+ # self.editProductScreen = EditProductScreen(id, name, qtyProduced, currentPrice, categoryName, desc)
+ # self.editProductScreen.show()
+
+
+ def ClearProduct(self):
+ self.productNameBox.setText('')
+ self.productQuantityBox.setText('')
+ self.unitPriceBox.setText('')
+ self.productCategoryBox.setCurrentText('Men')
+ self.productDescBox.setText('')
+
+
+ def PopulateProductTable(self):
+ cursor.execute('select productID, productName, [description], price, quantityProduced, quantitySold, categoryName from Products inner join Category on products.categoryID = Category.categoryID')
+ self.productTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.productTable.insertRow(row_index)
+
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.productTable.setItem(row_index, col_index, item)
+
+ def AddProduct(self):
+ # ID = self.productIdBox.text()
+ name = self.productNameBox.text()
+ quantityProduced = self.productQuantityBox.text()
+ quantitySold = 0
+ price = self.unitPriceBox.text()
+ category = self.productCategoryBox.currentText()
+ desc = self.productDescBox.toPlainText()
+
+ sql_query = 'select categoryID from Category where categoryName = (?)'
+ cursor.execute(sql_query, (category,))
+ categoryID = cursor.fetchone()
+ categoryID = categoryID[0] if categoryID else None
+
+ self.msg = QtWidgets.QMessageBox()
+
+ if name == '' or quantityProduced == '' or price == '' or category == '' or desc == '':
+ self.msg.setWindowTitle("Error")
+ self.msg.setText("Please enter complete information.")
+ else:
+ sql_query = 'insert into Products([productName], [description], price, quantityProduced, quantitySold, categoryID) values(?, ?, ?, ?, ?, ?)'
+ cursor.execute(sql_query, (name, desc, price, quantityProduced, quantitySold, categoryID))
+ connection.commit()
+ self.msg.setWindowTitle("Success")
+ self.msg.setText("Product added successfully.")
+
+
+ self.msg.show()
+ self.PopulateProductTable()
+
+
+ def SearchProduct(self):
+ criteria = self.searchProductCriteria.currentText().strip()
+ criteriaValue = self.searchProductValue.text().strip()
+
+ if (criteria != '' and criteriaValue != ''):
+ # print('criteria: ', criteria)
+
+ if criteria == 'Product Name':
+ sql_query = 'select productID, productName, [description], price, quantityProduced, quantitySold, categoryName from Products inner join Category on products.categoryID = Category.categoryID where productName = (?)'
+ elif criteria == 'Quantity Produced':
+ sql_query = 'select productID, productName, [description], price, quantityProduced, quantitySold, categoryName from Products inner join Category on products.categoryID = Category.categoryID where quantityProduced = (?)'
+ elif criteria == 'Quantity Sold':
+ sql_query = 'select productID, productName, [description], price, quantityProduced, quantitySold, categoryName from Products inner join Category on products.categoryID = Category.categoryID where quantitySold = (?)'
+ elif criteria == 'Quantity Available':
+ sql_query = "select productID, productName, [description], price, quantityProduced, quantitySold, categoryName from Products inner join Category on products.categoryID = Category.categoryID where quantityProduced - quantitySold = (?)"
+ elif criteria == 'Category Name':
+ sql_query = 'select productID, productName, [description], price, quantityProduced, quantitySold, categoryName from Products inner join Category on products.categoryID = Category.categoryID where categoryName = (?)'
+ elif criteria == 'Price':
+ sql_query = 'select productID, productName, [description], price, quantityProduced, quantitySold, categoryName from Products inner join Category on products.categoryID = Category.categoryID where price = (?)'
+
+ cursor.execute(sql_query, (criteriaValue,))
+
+ print('Query executed')
+
+ self.productTable.clearContents()
+ self.productTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ print('populating row')
+ self.productTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ print('Adding item to vendor table.')
+ self.productTable.setItem(row_index, col_index, item)
+
+ else:
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle('Error')
+ self.msg.setText('Please select search criteria and/or enter search value')
+
+ def DeleteProduct(self):
+ selected_items = self.productTable.selectedItems()
+
+ if not selected_items:
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Error")
+ self.msg.setText("Please select an entry to delete.")
+ self.msg.show()
+ return
+
+ # Assuming the first column contains a unique identifier (e.g., vendor_id)
+ selected_row = selected_items[0].row()
+ product_id = int(self.productTable.item(selected_row, 0).text())
+
+ # Code block to check if the productID exists as foreign key in other tables. If yes, then product cannot be deleted
+ check_in_saleproduct = "SELECT COUNT(*) FROM SaleProduct WHERE productID = ?"
+ cursor.execute(check_in_saleproduct, (product_id,))
+ result1 = cursor.fetchone()
+
+ check_in_productsmanufactured = "SELECT COUNT(*) FROM ProductsManufactured WHERE productID = ?"
+ cursor.execute(check_in_productsmanufactured, (product_id,))
+ result2 = cursor.fetchone()
+
+ if (result1 or result2) and (result1[0] > 0 or result2[0] > 0):
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Error")
+ self.msg.setText("Cannot delete product with existing records in database.")
+ self.msg.show()
+ return
+
+ sql_query = "delete from Products WHERE productID = ?"
+ cursor.execute(sql_query, (product_id,))
+ connection.commit()
+
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Success")
+ self.msg.setText("Product deleted successfully.")
+ self.msg.show()
+
+ self.PopulateProductTable() # Update the vendorTable after deletion
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PurchaseClass.py b/PurchaseClass.py
new file mode 100644
index 0000000..04f3d31
--- /dev/null
+++ b/PurchaseClass.py
@@ -0,0 +1,133 @@
+# Importing essential modules
+import typing
+from PyQt6 import QtCore, QtWidgets, uic
+from PyQt6.QtCore import QDate
+from PyQt6.QtWidgets import QApplication, QMessageBox,QMainWindow, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget, QHeaderView
+import sys
+import pyodbc
+from AddPurchaseClass import AddPurchaseScreen
+from ViewPurchaseClass import ViewPurchaseScreen
+import PurchaseReportClass
+
+from ConnectionString import connection, cursor
+
+class PurchaseScreen(QtWidgets.QMainWindow):
+
+ def __init__(self):
+
+ super(PurchaseScreen, self).__init__()
+ uic.loadUi('Screens/Purchase.ui', self)
+
+ self.PopulatePurchaseTable()
+ self.viewPurchaseButton.clicked.connect(self.ViewPurchase)
+ self.addPurchaseButton.clicked.connect(self.AddPurchase)
+ self.deletePurchaseButton.clicked.connect(self.DeletePurchase)
+ self.searchPurchaseButton.clicked.connect(self.SearchPurchase)
+ self.reportPurchaseButton.clicked.connect(self.ReportPurchase)
+
+ def PopulatePurchaseTable(self):
+
+ cursor.execute("select purchase.purchaseID, Purchase.purchaseDate, Purchase.totalAmount, vendor.vendorName from purchase join Vendor on purchase.vendorID = Vendor.vendorID")
+ self.purchaseTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.purchaseTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.purchaseTable.setItem(row_index, col_index, item)
+
+ def ViewPurchase(self):
+
+ selected_row = self.purchaseTable.currentRow()
+
+ purchase_id = str(self.purchaseTable.item(selected_row, 0).text())
+ purchase_date = str(self.purchaseTable.item(selected_row, 1).text())
+ total_amount = int(self.purchaseTable.item(selected_row, 2).text())
+ vendor_name = str(self.purchaseTable.item(selected_row, 3).text())
+
+ self.viewPurchase = ViewPurchaseScreen(purchase_id, purchase_date, total_amount, vendor_name)
+ self.viewPurchase.show()
+
+ def AddPurchase(self):
+ self.addPurchase = AddPurchaseScreen()
+ self.addPurchase.show()
+
+ def DeletePurchase(self):
+
+ selected_items = self.purchaseTable.selectedItems ()
+ if not selected_items:
+ self.msg = QtWidgets. QMessageBox()
+ self.msg.setWindowTitle("Error")
+ self.msg.setText ("Please select an entry to delete.")
+ self.msg.show()
+ return
+
+ msgBox = QtWidgets.QMessageBox()
+ msgBox.setText("Are you sure you want to delete this purchase?")
+ msgBox.setWindowTitle("Confirmation Box")
+ msgBox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok | QtWidgets.QMessageBox.StandardButton.Cancel)
+
+ returnValue = msgBox.exec()
+
+ if returnValue == QtWidgets.QMessageBox.StandardButton.Ok:
+
+ selected_row = selected_items[0].row()
+ purchase_id = int(self.purchaseTable.item(selected_row, 0). text())
+ cursor.execute("select * from PurchaseMaterial where purchaseID = ?", (purchase_id,))
+
+ for row in cursor.fetchall():
+ material_id = row[1]
+ quantity = row[2]
+ cursor.execute ("update Material set units = units - (?) where materialID = ?", (quantity, material_id,))
+ cursor.execute ("update Material set units = (?) where materialID = ? and units < 0", (0, material_id,))
+
+ cursor.execute("delete from PurchaseMaterial WHERE purchaseID = ?", (purchase_id,))
+ cursor.execute("delete from Purchase WHERE purchaseID = ?", (purchase_id,))
+ connection.commit ()
+
+ self.msg = QtWidgets.QMessageBox()
+ self.msg. setWindowTitle ("Success")
+ self.msg.setText ("Purchase deleted successfully.")
+ self.msg.show()
+ self.PopulatePurchaseTable()
+
+ def SearchPurchase(self):
+ purchaseId = self.searchPurchaseId.text()
+ vendorName = self.searchVendorName.text()
+ fromDate = self.searchFromDate.date().toString("yyyy-MM-dd")
+ toDate = self.searchToDate.date().toString("yyyy-MM-dd")
+
+ query = """
+ SELECT purchase.purchaseID, Purchase.purchaseDate, Purchase.totalAmount, vendor.vendorName
+ FROM purchase
+ JOIN Vendor ON purchase.vendorID = Vendor.vendorID
+ WHERE 1 = 1
+ """
+
+ params = []
+
+ if purchaseId:
+ query += " AND purchase.purchaseID = ? "
+ params.append(purchaseId)
+
+ if vendorName:
+ query += " AND vendor.vendorName LIKE ? "
+ params.append('%' + vendorName + '%')
+
+ if fromDate != "2000-01-01" and toDate != "2000-01-01":
+ query += " AND Purchase.purchaseDate BETWEEN ? AND ? "
+ params.extend([fromDate, toDate])
+
+ cursor.execute(query, params)
+
+ self.purchaseTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.purchaseTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.purchaseTable.setItem(row_index, col_index, item)
+
+ def ReportPurchase(self):
+ self.reportPurchase = PurchaseReportClass.PurchaseReportScreen()
+ self.reportPurchase.show()
\ No newline at end of file
diff --git a/PurchaseReportClass.py b/PurchaseReportClass.py
new file mode 100644
index 0000000..9a84fec
--- /dev/null
+++ b/PurchaseReportClass.py
@@ -0,0 +1,105 @@
+# Importing essential modules
+from PyQt6 import QtWidgets, uic
+from PyQt6.QtCore import QDate
+from PyQt6.QtWidgets import QApplication, QMainWindow, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget, QHeaderView
+
+from ConnectionString import connection, cursor
+
+
+class PurchaseReportScreen(QtWidgets.QMainWindow):
+ def __init__(self):
+ super(PurchaseReportScreen, self).__init__()
+
+ uic.loadUi('Screens/PurchaseReport.ui', self)
+
+ self.generate.clicked.connect(self.GenerateReport)
+ self.moneytext.setReadOnly(True)
+ self.materialText.setReadOnly(True)
+
+ self.moneyfrom.setEnabled(False)
+ self.moneyto.setEnabled(False)
+ self.materialfrom.setEnabled(False)
+ self.materialto.setEnabled(False)
+
+ self.radioButton_2.toggled.connect(self.toggleMoneyDateFields)
+ self.radioButton_4.toggled.connect(self.toggleVendorDateFields)
+
+ def toggleMoneyDateFields(self):
+ # Enable/disable money date fields based on the state of radioButton_2
+ self.moneyfrom.setEnabled(self.radioButton_2.isChecked())
+ self.moneyto.setEnabled(self.radioButton_2.isChecked())
+
+ def toggleVendorDateFields(self):
+ # Enable/disable vendor date fields based on the state of radioButton_4
+ self.materialfrom.setEnabled(self.radioButton_4.isChecked())
+ self.materialto.setEnabled(self.radioButton_4.isChecked())
+
+ def GenerateReport(self):
+ if (not self.radioButton.isChecked() and not self.radioButton_2.isChecked() and not self.radioButton_3.isChecked() and not self.radioButton_4.isChecked()):
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Error")
+ self.msg.setText("Please select the timeframe.")
+ self.msg.show()
+ return
+
+ if self.radioButton_3.isChecked():
+ query = """
+ SELECT STRING_AGG(materialInfo, CHAR(13) + CHAR(10)) as MostPurchasedMaterials
+ FROM (
+ SELECT TOP 1 WITH TIES
+ materialName + ' (Description: ' + description + ', Quantity: ' + CAST(SUM(quantity) AS NVARCHAR) + ')' as materialInfo
+ from Purchase P join PurchaseMaterial PM on P.purchaseID = PM.purchaseID join Material M on PM.materialID = M.materialID
+ GROUP BY materialName, description
+ ORDER BY SUM(quantity) DESC
+ ) AS MostPurchasedMaterialsSubquery
+ """
+
+ cursor.execute(query)
+ result = cursor.fetchone()
+ self.materialText.setText(
+ str(result[0]) if result and result[0] is not None else "N/A")
+
+ if self.radioButton_4.isChecked():
+ material_from_date = self.materialfrom.date().toString("yyyy-MM-dd")
+ material_to_date = self.materialto.date().toString("yyyy-MM-dd")
+
+ # Query to find the most frequented vendor within the specified time frame
+ query = f"""
+ SELECT STRING_AGG(materialInfo, CHAR(13) + CHAR(10)) as MostPurchasedMaterials
+ FROM (
+ SELECT TOP 1 WITH TIES
+ materialName + ' (Description: ' + description + ', Quantity: ' + CAST(SUM(quantity) AS NVARCHAR) + ')' as materialInfo
+ FROM Purchase P
+ JOIN PurchaseMaterial PM ON P.purchaseID = PM.purchaseID
+ JOIN Material M ON PM.materialID = M.materialID
+ WHERE P.purchaseDate BETWEEN '{material_from_date}' AND '{material_to_date}'
+ GROUP BY materialName, description
+ ORDER BY SUM(quantity) DESC
+ ) AS MostPurchasedMaterialsSubquery
+ """
+ cursor.execute(query)
+ result = cursor.fetchone()
+ self.materialText.setText(
+ str(result[0]) if result and result[0] is not None else "N/A")
+
+ if self.radioButton.isChecked():
+ query = "select sum(totalAmount) from Purchase"
+ cursor.execute(query)
+ result = cursor.fetchone()
+ self.moneytext.setText(
+ "RS. " + str(result[0]) if result and result[0] is not None else "N/A")
+
+ if self.radioButton_2.isChecked():
+ money_from_date = self.moneyfrom.date().toString("yyyy-MM-dd")
+ money_to_date = self.moneyto.date().toString("yyyy-MM-dd")
+
+ # Query to calculate the sum of the total amount for purchases during the specified time frame
+ query = f"""
+ SELECT SUM(totalAmount) as totalAmountSum
+ FROM Purchase
+ WHERE purchaseDate BETWEEN '{money_from_date}' AND '{money_to_date}'
+ """
+ cursor.execute(query)
+ result = cursor.fetchone()
+ self.moneytext.setText(
+ "RS. " + str(result[0]) if result and result[0] is not None else "N/A")
diff --git a/SaleClass.py b/SaleClass.py
new file mode 100644
index 0000000..bd15315
--- /dev/null
+++ b/SaleClass.py
@@ -0,0 +1,141 @@
+# Importing essential modules
+import typing
+from PyQt6 import QtCore, QtWidgets, uic
+from PyQt6.QtCore import QDate
+from PyQt6.QtWidgets import QApplication, QMessageBox,QMainWindow, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget, QHeaderView
+import sys
+import pyodbc
+from ViewSaleClass import ViewSaleScreen
+from AddSaleClass import AddSaleScreen
+import SaleReportClass
+
+from ConnectionString import connection, cursor
+
+class SaleScreen(QtWidgets.QMainWindow):
+
+ def __init__(self):
+
+ super(SaleScreen, self).__init__()
+ uic.loadUi('Screens/Sale.ui', self)
+
+ self.PopulateSaleTable()
+ self.viewSaleButton.clicked.connect(self.ViewSale)
+ self.addSaleButton.clicked.connect(self.AddSale)
+ self.deleteSaleButton.clicked.connect(self.DeleteSale)
+ self.searchSaleButton.clicked.connect(self.SearchSale)
+ self.reportSaleButton.clicked.connect(self.ReportSale)
+
+ def PopulateSaleTable(self):
+
+ cursor.execute("SELECT Sale.saleID, Sale.saleDate, Sale.totalAmount, Customer.customerName, Customer.contactNumber FROM Sale join Customer on sale.customerID = Customer.customerID")
+ self.saleTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.saleTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.saleTable.setItem(row_index, col_index, item)
+
+ def ViewSale(self):
+
+ selected_row = self.saleTable.currentRow()
+
+ sale_id = str(self.saleTable.item(selected_row, 0).text())
+ sale_date = str(self.saleTable.item(selected_row, 1).text())
+ total_amount = int(self.saleTable.item(selected_row, 2).text())
+ customer_name= str(self.saleTable.item(selected_row, 3).text())
+
+ self.viewSale = ViewSaleScreen(sale_id, sale_date, total_amount, customer_name)
+ self.viewSale.show()
+
+ def AddSale(self):
+ self.addSale = AddSaleScreen()
+ self.addSale.show()
+
+ def DeleteSale(self):
+
+ selected_items = self.saleTable.selectedItems ()
+ if not selected_items:
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Error")
+ self.msg.setText ("Please select an entry to delete.")
+ self.msg.show()
+ return
+
+ msgBox = QtWidgets.QMessageBox()
+ msgBox.setText("Are you sure you want to delete this sale?")
+ msgBox.setWindowTitle("Confirmation Box")
+ msgBox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok | QtWidgets.QMessageBox.StandardButton.Cancel)
+
+ returnValue = msgBox.exec()
+
+ if returnValue == QtWidgets.QMessageBox.StandardButton.Ok:
+
+ selected_row = selected_items[0].row()
+ sale_id = int(self.saleTable.item(selected_row, 0). text())
+ cursor.execute("select * from SaleProduct where saleID = ?", (sale_id,))
+
+ for row in cursor.fetchall():
+ Product_id = row[1]
+ quantity = row[2]
+ cursor.execute ("update Product set units = units - (?) where ProductID = ?", (quantity, Product_id,))
+ cursor.execute ("update Product set units = (?) where ProductID = ? and units < 0", (0, Product_id,))
+
+ cursor.execute("delete from saleProduct WHERE saleID = ?", (sale_id,))
+ cursor.execute("delete from sale WHERE saleID = ?", (sale_id,))
+ connection.commit ()
+
+ self.msg = QtWidgets.QMessageBox()
+ self.msg. setWindowTitle ("Success")
+ self.msg.setText ("sale deleted successfully.")
+ self.msg.show()
+ self.PopulatesaleTable()
+
+ def SearchSale(self):
+ saleID = self.searchSaleId.text()
+ customerName = self.searchCustomerName.text()
+ contactNumber = self.searchPhoneNumber.text()
+ fromDate = self.searchFromDate.date().toString("yyyy-MM-dd")
+ toDate = self.searchToDate.date().toString("yyyy-MM-dd")
+
+ query = """
+ SELECT Sale.saleID, Sale.saleDate, Sale.totalAmount, customer.customerName, customer.contactNumber
+ FROM Sale
+ JOIN Customer ON Sale.customerID = Customer.customerID
+ WHERE 1 = 1
+ """
+
+ params = []
+
+ if saleID:
+ query += " AND Sale.saleID = ? "
+ params.append(saleID)
+
+ if customerName:
+ query += " AND customer.customerName LIKE ? "
+ params.append('%' + customerName + '%')
+
+ if fromDate != "2000-01-01" and toDate != "2000-01-01":
+ query += " AND Sale.SaleDate BETWEEN ? AND ? "
+ params.extend([fromDate, toDate])
+
+ if contactNumber:
+ query += " AND customer.contactNumber LIKE ? "
+ params.append('%' + contactNumber + '%')
+
+ cursor.execute(query, params)
+
+ self.saleTable.setRowCount(0)
+
+ for row_index, row_data in enumerate(cursor.fetchall()):
+ self.saleTable.insertRow(row_index)
+ for col_index, cell_data in enumerate(row_data):
+ item = QTableWidgetItem(str(cell_data))
+ self.saleTable.setItem(row_index, col_index, item)
+
+ def ReportSale(self):
+ self.reportSale = SaleReportClass.SaleReportScreen()
+ self.reportSale.show()
+
+
+
\ No newline at end of file
diff --git a/SaleReportClass.py b/SaleReportClass.py
new file mode 100644
index 0000000..198152d
--- /dev/null
+++ b/SaleReportClass.py
@@ -0,0 +1,189 @@
+# Importing essential modules
+from PyQt6 import QtWidgets, uic
+from PyQt6.QtCore import QDate
+from PyQt6.QtWidgets import QApplication, QMainWindow, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget, QHeaderView
+
+from ConnectionString import connection, cursor
+
+class SaleReportScreen(QtWidgets.QMainWindow):
+ def __init__(self):
+ super(SaleReportScreen, self).__init__()
+
+ uic.loadUi('Screens/SaleReport.ui', self)
+
+ self.generateItemButton.clicked.connect(self.GenerateItemReport)
+ self.generateRevenueButton.clicked.connect(self.GenerateRevenueReport)
+ self.revenueText.setReadOnly(True)
+ self.itemText.setReadOnly(True)
+
+ self.itemFrom.setEnabled(False)
+ self.itemTo.setEnabled(False)
+ self.dateEdit.setEnabled(False)
+
+ self.radioButton_4.toggled.connect(self.toggleCustomerDateFields)
+ self.radioButton_allTime.toggled.connect(self.toggleRevenueDate)
+ self.radioButton_yearly.toggled.connect(self.toggleRevenueDate)
+ self.radioButton_monthly.toggled.connect(self.toggleRevenueDate)
+ def toggleRevenueDate(self):
+ enabled = (
+ self.radioButton_yearly.isChecked() or
+ self.radioButton_monthly.isChecked()
+ )
+ self.dateEdit.setEnabled(enabled)
+
+ def toggleCustomerDateFields(self):
+ # Enable/disable vendor date fields based on the state of radioButton_4
+ self.itemFrom.setEnabled(self.radioButton_4.isChecked())
+ self.itemTo.setEnabled(self.radioButton_4.isChecked())
+
+ def GenerateItemReport(self):
+ if (not self.radioButton_3.isChecked() and not self.radioButton_4.isChecked()):
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Error")
+ self.msg.setText("Please select the timeframe.")
+ self.msg.show()
+ return
+
+ # for best selling item all time
+
+ if self.radioButton_3.isChecked():
+ query = """
+ SELECT STRING_AGG(productInfo, CHAR(13) + CHAR(10)) as BestSellingProducts
+ FROM (
+ SELECT TOP 1 WITH TIES
+ productName + ' (Description: ' + description + ', Quantity: ' + CAST(SUM(quantity) AS NVARCHAR) + ')' as productInfo
+ FROM Sale S
+ JOIN SaleProduct SP ON S.saleID = SP.saleID
+ JOIN Products P ON SP.productID = P.productID
+ GROUP BY productName, description
+ ORDER BY SUM(quantity) DESC
+ ) AS BestSellingProductsSubquery
+ """
+
+ cursor.execute(query)
+ result = cursor.fetchone()
+ self.itemText.setText(
+ str(result[0]) if result and result[0] is not None else "N/A")
+
+ # for best selling item within a specific timeframe
+
+ if self.radioButton_4.isChecked():
+ item_from_date = self.itemFrom.date().toString("yyyy-MM-dd")
+ item_to_date = self.itemTo.date().toString("yyyy-MM-dd")
+
+ query = f"""
+ SELECT STRING_AGG(productInfo, CHAR(13) + CHAR(10)) as BestSellingProducts
+ FROM (
+ SELECT TOP 1 WITH TIES
+ productName + ' (Description: ' + description + ', Quantity: ' + CAST(SUM(quantity) AS NVARCHAR) + ')' as productInfo
+ FROM Sale S
+ JOIN SaleProduct SP ON S.saleID = SP.saleID
+ JOIN Products P ON SP.productID = P.productID
+ WHERE S.saleDate BETWEEN '{item_from_date}' AND '{item_to_date}'
+ GROUP BY productName, description
+ ORDER BY SUM(quantity) DESC
+ ) AS BestSellingProductsSubquery
+ """
+ cursor.execute(query)
+ result = cursor.fetchone()
+ self.itemText.setText(
+ str(result[0]) if result and result[0] is not None else "N/A")
+
+
+ def GenerateRevenueReport(self):
+ if (not self.radioButton_allTime.isChecked() and not self.radioButton_yearly.isChecked() and not self.radioButton_monthly.isChecked()):
+ self.msg = QtWidgets.QMessageBox()
+ self.msg.setWindowTitle("Error")
+ self.msg.setText("Please select the timeframe.")
+ self.msg.show()
+ return
+ # Check the selected timeframe
+ if self.radioButton_allTime.isChecked():
+ # Fetch revenue data for all time
+ query = """
+ SELECT YEAR(saleDate) as Year, SUM(totalAmount) as Revenue
+ FROM Sale
+ GROUP BY YEAR(saleDate)
+ ORDER BY YEAR(MIN(saleDate))
+ """
+ cursor.execute(query)
+ result = cursor.fetchall()
+
+ self.revenueTable.setRowCount(len(result))
+ self.revenueTable.setColumnCount(2)
+ self.revenueTable.setHorizontalHeaderLabels(["Year", "Revenue"])
+
+ for row, (year, revenue) in enumerate(result):
+ # Concatenate "RS. " with the revenue values
+ formatted_revenue = "RS. " + str(revenue)
+ self.revenueTable.setItem(row, 0, QTableWidgetItem(str(year)))
+ self.revenueTable.setItem(row, 1, QTableWidgetItem(formatted_revenue))
+
+ self.revenueTable.resizeColumnsToContents()
+
+ # Calculate and display the total revenue for all years
+ total_revenue = sum(revenue for _, revenue in result)
+ formatted_total_revenue = "RS. " + str(total_revenue)
+ self.revenueText.setText(formatted_total_revenue)
+
+ elif self.radioButton_yearly.isChecked():
+ # Fetch revenue data for the selected year
+ selected_year = self.dateEdit.date().year()
+ query = f"""
+ SELECT LEFT(DATENAME(MONTH, saleDate), 3) as Month, SUM(totalAmount) as Revenue
+ FROM Sale
+ WHERE YEAR(saleDate) = {selected_year}
+ GROUP BY DATENAME(MONTH, saleDate)
+ ORDER BY MONTH(MIN(saleDate))
+ """
+ cursor.execute(query)
+ result = cursor.fetchall()
+ self.revenueTable.setRowCount(len(result))
+ self.revenueTable.setColumnCount(2)
+ self.revenueTable.setHorizontalHeaderLabels(["Month", "Revenue"])
+
+ for row, (month, revenue) in enumerate(result):
+ # Concatenate "RS. " with the revenue values
+ formatted_revenue = "RS. " + str(revenue)
+ self.revenueTable.setItem(row, 0, QTableWidgetItem(month))
+ self.revenueTable.setItem(row, 1, QTableWidgetItem(formatted_revenue))
+
+ self.revenueTable.resizeColumnsToContents()
+
+ # Calculate and display the total revenue for the selected year
+ total_revenue = sum(revenue for _, revenue in result)
+ formatted_total_revenue = "RS. " + str(total_revenue)
+ self.revenueText.setText(formatted_total_revenue)
+
+ elif self.radioButton_monthly.isChecked():
+ # Fetch revenue data for the selected month
+ selected_month = self.dateEdit.date().month()
+ selected_year = self.dateEdit.date().year()
+
+ query = f"""
+ SELECT DAY(saleDate) as Day, SUM(totalAmount) as Revenue
+ FROM Sale
+ WHERE YEAR(saleDate) = {selected_year} AND MONTH(saleDate) = {selected_month}
+ GROUP BY DAY(saleDate)
+ ORDER BY DAY(saleDate)
+ """
+ cursor.execute(query)
+ result = cursor.fetchall()
+ self.revenueTable.setRowCount(len(result))
+ self.revenueTable.setColumnCount(2)
+ self.revenueTable.setHorizontalHeaderLabels(["Date", "Revenue"])
+
+ for row, (day, revenue) in enumerate(result):
+ # Concatenate "RS. " with the revenue values
+ formatted_revenue = "RS. " + str(revenue)
+ self.revenueTable.setItem(row, 0, QTableWidgetItem(str(day)))
+ self.revenueTable.setItem(row, 1, QTableWidgetItem(formatted_revenue))
+
+ self.revenueTable.resizeColumnsToContents()
+
+ # Calculate and display the total revenue for the selected month
+ total_revenue = sum(revenue for _, revenue in result)
+ formatted_total_revenue = "RS. " + str(total_revenue)
+ self.revenueText.setText(formatted_total_revenue)
+
+
diff --git a/Screens/.DS_Store b/Screens/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/Screens/.DS_Store differ
diff --git a/Screens/AddPurchase.ui b/Screens/AddPurchase.ui
new file mode 100644
index 0000000..fe92465
--- /dev/null
+++ b/Screens/AddPurchase.ui
@@ -0,0 +1,702 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 1085
+ 734
+
+
+
+ Add Purchase
+
+
+
+
+
+ 20
+ 10
+ 311
+ 51
+
+
+
+
+ 20
+ 75
+ true
+
+
+
+ Add Purchase
+
+
+
+
+
+ 20
+ 50
+ 1051
+ 31
+
+
+
+
+ 20
+ 75
+ true
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 960
+ 460
+ 91
+ 41
+
+
+
+ true
+
+
+
+
+
+ 930
+ 600
+ 141
+ 51
+
+
+
+ Add
+
+
+
+
+
+ 10
+ 80
+ 1051
+ 301
+
+
+
+ Material/Vendor Info
+
+
+
+
+ 10
+ 80
+ 301
+ 211
+
+
+
+
+ 1
+
+
+
+
+ 2
+
+
+
+
+ 3
+
+
+
+
+ 4
+
+
+
+
+ 5
+
+
+
+
+ 6
+
+
+
+
+ 7
+
+
+
+
+ 8
+
+
+
+
+ 9
+
+
+
+
+ 10
+
+
+
+
+ 11
+
+
+
+
+ 12
+
+
+
+
+ 13
+
+
+
+
+ 14
+
+
+
+
+ 15
+
+
+
+
+ Material ID
+
+
+
+
+ Material Name
+
+
+
+
+
+
+ 380
+ 20
+ 81
+ 21
+
+
+
+ Material ID
+
+
+
+
+
+ 370
+ 90
+ 101
+ 21
+
+
+
+ Material Name
+
+
+
+
+
+ 360
+ 50
+ 111
+ 31
+
+
+
+
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+
+
+ 320
+ 120
+ 191
+ 31
+
+
+
+
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+
+
+ 380
+ 160
+ 101
+ 21
+
+
+
+ Unit Cost
+
+
+
+
+
+ 610
+ 160
+ 101
+ 21
+
+
+
+ Quantity
+
+
+
+
+
+ 350
+ 190
+ 121
+ 31
+
+
+
+
+
+
+ Qt::AlignCenter
+
+
+ false
+
+
+
+
+
+ 570
+ 190
+ 121
+ 31
+
+
+
+
+
+
+ Qt::AlignCenter
+
+
+ false
+
+
+
+
+
+ 100
+ 30
+ 151
+ 31
+
+
+
+
+
+
+
+
+
+ 10
+ 30
+ 91
+ 31
+
+
+ -
+
+ Material ID
+
+
+ -
+
+ Material Name
+
+
+
+
+
+
+ 250
+ 30
+ 61
+ 31
+
+
+
+ Search
+
+
+
+
+
+ 340
+ 240
+ 371
+ 41
+
+
+
+ Add
+
+
+
+
+
+ 740
+ 80
+ 301
+ 211
+
+
+
+
+ 1
+
+
+
+
+ 2
+
+
+
+
+ 3
+
+
+
+
+ 4
+
+
+
+
+ 5
+
+
+
+
+ 6
+
+
+
+
+ 7
+
+
+
+
+ 8
+
+
+
+
+ 9
+
+
+
+
+ 10
+
+
+
+
+ 11
+
+
+
+
+ 12
+
+
+
+
+ 13
+
+
+
+
+ 14
+
+
+
+
+ 15
+
+
+
+
+ Vendor ID
+
+
+
+
+ Vendor Name
+
+
+
+
+
+
+ 980
+ 30
+ 61
+ 31
+
+
+
+ Search
+
+
+
+
+
+ 740
+ 30
+ 101
+ 31
+
+
+ -
+
+ Vendor ID
+
+
+ -
+
+ Vendor Name
+
+
+
+
+
+
+ 840
+ 30
+ 141
+ 31
+
+
+
+
+
+
+
+
+
+ 540
+ 120
+ 191
+ 31
+
+
+
+
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+
+
+ 570
+ 50
+ 121
+ 31
+
+
+
+
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+
+
+ 600
+ 20
+ 81
+ 21
+
+
+
+ Vendor ID
+
+
+
+
+
+ 590
+ 90
+ 101
+ 20
+
+
+
+ Vendor Name
+
+
+
+
+
+
+ 960
+ 430
+ 101
+ 21
+
+
+
+ Purchase Date
+
+
+
+
+
+ 930
+ 540
+ 141
+ 51
+
+
+
+ Clear
+
+
+
+
+
+ 10
+ 0
+ 1061
+ 31
+
+
+
+
+ 20
+ 75
+ true
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 9
+ 400
+ 901
+ 271
+
+
+
+ Purchase Details
+
+
+
+
+ 10
+ 30
+ 881
+ 221
+
+
+
+
+ Material ID
+
+
+
+
+ Material Name
+
+
+
+
+ Vendor ID
+
+
+
+
+ Vendor Name
+
+
+
+
+ Unit Price
+
+
+
+
+ Quantity
+
+
+
+
+ Total
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Screens/Insert Purchase.ui b/Screens/AddSales.ui
similarity index 74%
rename from Screens/Insert Purchase.ui
rename to Screens/AddSales.ui
index d8dd3e8..e7413ad 100644
--- a/Screens/Insert Purchase.ui
+++ b/Screens/AddSales.ui
@@ -1,815 +1,879 @@
-
-
- MainWindow
-
-
-
- 0
- 0
- 1254
- 734
-
-
-
- MainWindow
-
-
-
-
-
- 20
- 20
- 221
- 51
-
-
-
-
- 20
- 75
- true
-
-
-
- Insert Purchase
-
-
-
-
-
- 10
- 60
- 1231
- 31
-
-
-
-
- 20
- 75
- true
-
-
-
- Qt::Horizontal
-
-
-
-
-
- 1060
- 480
- 141
- 41
-
-
-
- true
-
-
-
-
-
- 900
- 540
- 141
- 51
-
-
-
- Insert
-
-
-
-
-
- 10
- 80
- 611
- 301
-
-
-
- Material Info
-
-
-
-
- 20
- 80
- 301
- 211
-
-
-
-
- 1
-
-
-
-
- 2
-
-
-
-
- 3
-
-
-
-
- 4
-
-
-
-
- 5
-
-
-
-
- 6
-
-
-
-
- 7
-
-
-
-
- 8
-
-
-
-
- 9
-
-
-
-
- 10
-
-
-
-
- 11
-
-
-
-
- 12
-
-
-
-
- 13
-
-
-
-
- 14
-
-
-
-
- 15
-
-
-
-
- Material ID
-
-
-
-
- Material Name
-
-
-
-
-
-
- 340
- 40
- 81
- 21
-
-
-
- Material ID
-
-
-
-
-
- 340
- 80
- 101
- 21
-
-
-
- Material Name
-
-
-
-
-
- 480
- 40
- 113
- 31
-
-
-
-
-
-
- true
-
-
-
-
-
- 480
- 80
- 113
- 31
-
-
-
-
-
-
- true
-
-
-
-
-
- 340
- 120
- 81
- 21
-
-
-
- Description
-
-
-
-
-
- 340
- 160
- 101
- 21
-
-
-
- Unit Cost
-
-
-
-
-
- 480
- 120
- 111
- 31
-
-
-
-
-
-
- false
-
-
-
-
-
- 340
- 200
- 101
- 21
-
-
-
- Quantity
-
-
-
-
-
- 400
- 240
- 141
- 41
-
-
-
- Add
-
-
-
-
-
- 480
- 160
- 111
- 31
-
-
-
-
-
-
- false
-
-
-
-
-
- 480
- 200
- 111
- 31
-
-
-
-
-
-
- false
-
-
-
-
-
- 110
- 30
- 211
- 31
-
-
-
- Search
-
-
-
-
-
- 20
- 30
- 91
- 31
-
-
- -
-
- Material ID
-
-
- -
-
- Material Name
-
-
- -
-
- Description
-
-
-
-
-
-
-
- 930
- 490
- 101
- 21
-
-
-
- Purchase Date
-
-
-
-
-
- 1060
- 540
- 141
- 51
-
-
-
- Clear
-
-
-
-
-
- 10
- 0
- 1231
- 31
-
-
-
-
- 20
- 75
- true
-
-
-
- Qt::Horizontal
-
-
-
-
-
- 630
- 80
- 611
- 301
-
-
-
- Vendor Info
-
-
-
-
- 330
- 40
- 101
- 20
-
-
-
- Vendor Name
-
-
-
-
-
- 330
- 80
- 101
- 20
-
-
-
- Contact Number
-
-
-
-
-
- 330
- 160
- 101
- 20
-
-
-
- Email
-
-
-
-
-
- 10
- 80
- 301
- 211
-
-
-
-
- 1
-
-
-
-
- 2
-
-
-
-
- 3
-
-
-
-
- 4
-
-
-
-
- 5
-
-
-
-
- 6
-
-
-
-
- 7
-
-
-
-
- 8
-
-
-
-
- 9
-
-
-
-
- 10
-
-
-
-
- 11
-
-
-
-
- 12
-
-
-
-
- 13
-
-
-
-
- 14
-
-
-
-
- 15
-
-
-
-
- Vendor ID
-
-
-
-
- Vendor Name
-
-
-
-
-
-
- 110
- 30
- 201
- 31
-
-
-
- Search
-
-
-
-
-
- 330
- 120
- 141
- 20
-
-
-
- Backup Contact Number
-
-
-
-
-
- 480
- 190
- 111
- 31
-
-
-
-
-
-
- false
-
-
-
-
-
- 480
- 30
- 113
- 31
-
-
-
-
-
-
- true
-
-
-
-
-
- 480
- 110
- 111
- 31
-
-
-
-
-
-
- false
-
-
-
-
-
- 480
- 70
- 113
- 31
-
-
-
-
-
-
- true
-
-
-
-
-
- 480
- 150
- 111
- 31
-
-
-
-
-
-
- false
-
-
-
-
-
- 400
- 240
- 141
- 41
-
-
-
- Add
-
-
-
-
-
- 10
- 30
- 101
- 31
-
-
- -
-
- Vendor ID
-
-
- -
-
- Vendor Name
-
-
- -
-
- Contact Number
-
-
- -
-
- Backup Contact
-
-
- -
-
- Email
-
-
- -
-
- Address
-
-
-
-
-
-
- 330
- 195
- 101
- 20
-
-
-
- Address
-
-
-
-
-
-
- 9
- 400
- 831
- 271
-
-
-
- Purchase Details
-
-
-
-
- 10
- 30
- 811
- 221
-
-
-
-
- Purchase ID
-
-
-
-
- Vendor ID
-
-
-
-
- Material ID
-
-
-
-
- Quantity
-
-
-
-
- Unit Price
-
-
-
-
-
-
-
-
-
-
-
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 1255
+ 742
+
+
+
+ MainWindow
+
+
+
+
+
+ 20
+ 20
+ 211
+ 51
+
+
+
+
+ 20
+ 75
+ true
+
+
+
+ Add Sale
+
+
+
+
+
+ 10
+ 60
+ 1231
+ 31
+
+
+
+
+ 20
+ 75
+ true
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 1070
+ 460
+ 141
+ 41
+
+
+
+ true
+
+
+
+
+
+ 1070
+ 580
+ 141
+ 51
+
+
+
+ Add
+
+
+
+
+
+ 10
+ 80
+ 1231
+ 321
+
+
+
+ Product/Customer Info
+
+
+
+
+ 20
+ 90
+ 301
+ 211
+
+
+
+
+ 1
+
+
+
+
+ 2
+
+
+
+
+ 3
+
+
+
+
+ 4
+
+
+
+
+ 5
+
+
+
+
+ 6
+
+
+
+
+ 7
+
+
+
+
+ 8
+
+
+
+
+ 9
+
+
+
+
+ 10
+
+
+
+
+ 11
+
+
+
+
+ 12
+
+
+
+
+ 13
+
+
+
+
+ 14
+
+
+
+
+ 15
+
+
+
+
+ Product ID
+
+
+
+
+ Product Name
+
+
+
+
+ Description
+
+
+
+
+ Price
+
+
+
+
+
+
+ 340
+ 70
+ 101
+ 21
+
+
+
+ Product Name
+
+
+
+
+
+ 480
+ 70
+ 113
+ 31
+
+
+
+
+
+
+ true
+
+
+
+
+
+ 340
+ 120
+ 81
+ 21
+
+
+
+ Quantity
+
+
+
+
+
+ 340
+ 170
+ 101
+ 21
+
+
+
+ Price
+
+
+
+
+
+ 480
+ 120
+ 111
+ 31
+
+
+
+
+
+
+ false
+
+
+
+
+
+ 340
+ 220
+ 101
+ 21
+
+
+
+ Discount
+
+
+
+
+
+ 340
+ 270
+ 531
+ 41
+
+
+
+ Add
+
+
+
+
+
+ 480
+ 170
+ 111
+ 31
+
+
+
+
+
+
+ false
+
+
+
+
+
+ 480
+ 220
+ 111
+ 31
+
+
+
+
+
+
+ false
+
+
+
+
+
+ 110
+ 30
+ 151
+ 31
+
+
+
+
+
+
+
+
+
+ 20
+ 30
+ 91
+ 31
+
+
+ -
+
+ Select
+
+
+ -
+
+ Product ID
+
+
+ -
+
+ Product Name
+
+
+
+
+
+
+ 260
+ 30
+ 61
+ 31
+
+
+
+ Search
+
+
+
+
+
+ 480
+ 20
+ 113
+ 31
+
+
+
+
+
+
+ true
+
+
+
+
+
+ 340
+ 20
+ 101
+ 21
+
+
+
+ Product ID
+
+
+
+
+
+ 760
+ 100
+ 113
+ 31
+
+
+
+
+
+
+ true
+
+
+
+
+
+ 760
+ 60
+ 113
+ 31
+
+
+
+
+
+
+ true
+
+
+
+
+
+ 760
+ 20
+ 113
+ 31
+
+
+
+
+
+
+ true
+
+
+
+
+
+ 610
+ 60
+ 101
+ 20
+
+
+
+ Customer Name
+
+
+
+
+
+ 610
+ 180
+ 141
+ 20
+
+
+
+ Backup Contact Number
+
+
+
+
+
+ 760
+ 180
+ 111
+ 31
+
+
+
+
+
+
+ false
+
+
+
+
+
+ 610
+ 20
+ 101
+ 20
+
+
+
+ Customer ID
+
+
+
+
+
+ 610
+ 140
+ 101
+ 20
+
+
+
+ Contact Number
+
+
+
+
+
+ 610
+ 220
+ 101
+ 20
+
+
+
+ Email
+
+
+
+
+
+ 760
+ 140
+ 111
+ 31
+
+
+
+
+
+
+ false
+
+
+
+
+
+ 610
+ 100
+ 101
+ 20
+
+
+
+ Address
+
+
+
+
+
+ 760
+ 220
+ 111
+ 31
+
+
+
+
+
+
+ false
+
+
+
+
+
+ 1150
+ 30
+ 61
+ 31
+
+
+
+ Search
+
+
+
+
+
+ 910
+ 90
+ 301
+ 211
+
+
+
+
+ 1
+
+
+
+
+ 2
+
+
+
+
+ 3
+
+
+
+
+ 4
+
+
+
+
+ 5
+
+
+
+
+ 6
+
+
+
+
+ 7
+
+
+
+
+ 8
+
+
+
+
+ 9
+
+
+
+
+ 10
+
+
+
+
+ 11
+
+
+
+
+ 12
+
+
+
+
+ 13
+
+
+
+
+ 14
+
+
+
+
+ 15
+
+
+
+
+ Customer ID
+
+
+
+
+ Customer Name
+
+
+
+
+ Gender
+
+
+
+
+ Contact Number
+
+
+
+
+ Backup Contact Number
+
+
+
+
+ Email
+
+
+
+
+ Address
+
+
+
+
+
+
+ 910
+ 30
+ 101
+ 31
+
+
+ -
+
+ Select
+
+
+ -
+
+ Customer ID
+
+
+ -
+
+ Customer Name
+
+
+
+
+
+
+ 1010
+ 30
+ 141
+ 31
+
+
+
+
+
+
+
+
+
+
+ 1100
+ 430
+ 101
+ 21
+
+
+
+ Order Date
+
+
+
+
+
+ 1070
+ 520
+ 141
+ 51
+
+
+
+ Clear
+
+
+
+
+
+ 10
+ 0
+ 1231
+ 31
+
+
+
+
+ 20
+ 75
+ true
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 9
+ 400
+ 1031
+ 271
+
+
+
+ Sale Details
+
+
+
+
+ 10
+ 30
+ 1011
+ 221
+
+
+
+
+ Product ID
+
+
+
+
+ Product Name
+
+
+
+
+ Customer ID
+
+
+
+
+ Customer Name
+
+
+
+
+ Quantity
+
+
+
+
+ Price
+
+
+
+
+ Discount
+
+
+
+
+ Total
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Screens/Customers.ui b/Screens/Customers.ui
index 35bbe22..9e715be 100644
--- a/Screens/Customers.ui
+++ b/Screens/Customers.ui
@@ -6,8 +6,8 @@
0
0
- 1303
- 456
+ 1242
+ 506
@@ -34,13 +34,13 @@
Customers
-
+
20
170
- 921
- 221
+ 851
+ 280
@@ -196,20 +196,15 @@
-
+
- 800
+ 20
90
131
41
- -
-
- Customer ID
-
-
-
Customer Name
@@ -226,56 +221,17 @@
-
+
- 170
+ 150
90
611
41
- Search Customers
-
-
-
-
-
- 60
- 110
- 71
- 21
-
-
-
-
- 10
- 75
- true
- false
-
-
-
- 124887
-
-
-
-
-
- 40
- 90
- 121
- 21
-
-
-
-
- 9
-
-
-
- Total Customers
+
@@ -283,7 +239,7 @@
17
70
- 1271
+ 1210
20
@@ -296,7 +252,7 @@
20
140
- 911
+ 850
20
@@ -307,7 +263,7 @@
- 950
+ 890
90
341
301
@@ -342,7 +298,7 @@
Contact Number
-
+
20
@@ -352,7 +308,7 @@
-
+
20
@@ -375,7 +331,7 @@
Gender
-
+
180
@@ -398,7 +354,7 @@
Backup Contact Number
-
+
20
@@ -424,7 +380,7 @@
Email
-
+
180
@@ -457,7 +413,7 @@
Address
-
+
180
@@ -470,10 +426,10 @@
-
+
- 120
+ 100
240
131
41
@@ -496,7 +452,7 @@
20
0
- 1271
+ 1210
20
@@ -504,12 +460,12 @@
Qt::Horizontal
-
+
- 1010
- 20
- 131
+ 903
+ 410
+ 150
41
@@ -524,12 +480,32 @@
Edit
-
+
- 1160
- 20
- 131
+ 770
+ 90
+ 110
+ 40
+
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Search
+
+
+
+
+
+ 1067
+ 410
+ 150
41
@@ -550,8 +526,8 @@
0
0
- 1303
- 26
+ 1242
+ 24
diff --git a/Screens/EditCustomer.ui b/Screens/EditCustomer.ui
index 274b61c..66ec7db 100644
--- a/Screens/EditCustomer.ui
+++ b/Screens/EditCustomer.ui
@@ -105,7 +105,7 @@
Contact Number
-
+
20
@@ -115,7 +115,7 @@
-
+
20
@@ -130,7 +130,7 @@
270
110
- 141
+ 151
16
@@ -138,7 +138,7 @@
Backup Contact Number
-
+
270
@@ -148,7 +148,7 @@
-
+
20
@@ -158,7 +158,7 @@
-
+
20
@@ -194,7 +194,7 @@
Gender
-
+
270
@@ -214,7 +214,7 @@
-
+
60
@@ -248,7 +248,7 @@
Qt::Horizontal
-
+
290
@@ -258,7 +258,7 @@
- Done
+ Save
@@ -268,7 +268,7 @@
0
0
544
- 26
+ 24
diff --git a/Screens/EditMaterial.ui b/Screens/EditMaterial.ui
index 636b28c..1cce968 100644
--- a/Screens/EditMaterial.ui
+++ b/Screens/EditMaterial.ui
@@ -18,9 +18,9 @@
20
- 100
+ 90
431
- 381
+ 391
@@ -30,7 +30,7 @@
20
- 30
+ 70
101
21
@@ -39,11 +39,11 @@
Material Name
-
+
140
- 30
+ 70
271
31
@@ -59,7 +59,7 @@
20
- 80
+ 120
111
21
@@ -68,11 +68,11 @@
Units
-
+
140
- 80
+ 120
271
31
@@ -84,7 +84,7 @@
false
-
+
230
@@ -101,7 +101,7 @@
20
- 130
+ 170
81
21
@@ -110,7 +110,7 @@
Description
-
+
60
@@ -120,25 +120,51 @@
- Clear
+ Cancel
+
+
+
+
+
+ 20
+ 190
+ 391
+ 131
+
+
+
+
+
+ false
+
+
+
+ 140
+ 20
+ 271
+ 31
+
+
+
+
+
+
+ true
+
+
+
+
+
+ 20
+ 20
+ 101
+ 21
+
+
+
+ Material ID
-
-
-
-
- 40
- 260
- 391
- 161
-
-
-
-
-
-
- true
-
@@ -207,7 +233,7 @@
0
0
468
- 21
+ 26
@@ -215,4 +241,4 @@
-
+
\ No newline at end of file
diff --git a/Screens/EditProduct.ui b/Screens/EditProducts.ui
similarity index 73%
rename from Screens/EditProduct.ui
rename to Screens/EditProducts.ui
index 1468656..ed69fc0 100644
--- a/Screens/EditProduct.ui
+++ b/Screens/EditProducts.ui
@@ -1,7 +1,7 @@
- MainWindow
-
+ categoryNameBox
+
0
@@ -30,7 +30,7 @@
20
- 30
+ 70
101
21
@@ -39,11 +39,11 @@
Product Name
-
+
140
- 30
+ 70
271
31
@@ -59,20 +59,20 @@
20
- 80
+ 120
111
21
- Quantity Added
+ Quantity Produced
20
- 130
+ 170
101
21
@@ -81,11 +81,11 @@
Unit Price
-
+
140
- 80
+ 120
271
31
@@ -101,20 +101,20 @@
20
- 180
+ 220
101
21
- Category ID
+ Category Name
-
+
140
- 130
+ 170
271
31
@@ -126,23 +126,7 @@
false
-
-
-
- 140
- 180
- 271
- 31
-
-
-
-
-
-
- false
-
-
-
+
230
@@ -159,7 +143,7 @@
20
- 230
+ 260
81
21
@@ -168,7 +152,7 @@
Description
-
+
60
@@ -178,25 +162,81 @@
- Clear
+ Cancel
+
+
+
+
+
+ 20
+ 289
+ 391
+ 131
+
+
+
+
+
+
+ 140
+ 220
+ 271
+ 31
+
+
+ -
+
+ Men
+
+
+ -
+
+ Women
+
+
+ -
+
+ Boys
+
+
+ -
+
+ Girls
+
+
+
+
+
+ false
+
+
+
+ 140
+ 20
+ 271
+ 31
+
+
+
+
+
+
+ true
+
+
+
+
+
+ 20
+ 20
+ 101
+ 21
+
+
+
+ Product ID
-
-
-
-
- 40
- 360
- 391
- 161
-
-
-
-
-
-
- true
-
@@ -273,4 +313,4 @@
-
+
\ No newline at end of file
diff --git a/Screens/EditVendors.ui b/Screens/EditVendors.ui
index ce97f1a..af86a8d 100644
--- a/Screens/EditVendors.ui
+++ b/Screens/EditVendors.ui
@@ -105,7 +105,7 @@
Contact Number
-
+
20
@@ -115,7 +115,7 @@
-
+
20
@@ -130,7 +130,7 @@
270
110
- 141
+ 151
16
@@ -138,7 +138,7 @@
Backup Contact Number
-
+
270
@@ -148,7 +148,7 @@
-
+
20
@@ -158,7 +158,7 @@
-
+
20
@@ -181,7 +181,7 @@
Address
-
+
60
@@ -191,7 +191,7 @@
- Clear
+ Reset
@@ -215,7 +215,7 @@
Qt::Horizontal
-
+
290
@@ -225,7 +225,7 @@
- Done
+ Save
@@ -235,7 +235,7 @@
0
0
544
- 21
+ 24
diff --git a/Screens/Materials.ui b/Screens/Materials.ui
index 2f0f9be..676d2b3 100644
--- a/Screens/Materials.ui
+++ b/Screens/Materials.ui
@@ -34,7 +34,7 @@
Materials
-
+
20
@@ -118,20 +118,15 @@
-
+
20
70
- 131
+ 110
41
- -
-
- Material ID
-
-
-
Material Name
@@ -148,30 +143,33 @@
-
+
- 160
+ 140
70
- 311
+ 240
41
- Search
+
+
+
+ Search
-
+
- 620
+ 510
70
- 131
+ 110
41
- Edit
+ View and Edit
@@ -186,24 +184,11 @@
Add Material
-
-
-
- 30
- 60
- 81
- 21
-
-
-
- Materal ID
-
-
30
- 110
+ 70
101
21
@@ -212,43 +197,11 @@
Material Name
-
-
-
- 150
- 60
- 271
- 31
-
-
-
-
-
-
- true
-
-
-
-
-
- 150
- 110
- 271
- 31
-
-
-
-
-
-
- true
-
-
30
- 160
+ 130
101
21
@@ -257,11 +210,11 @@
Units
-
+
150
- 160
+ 130
271
31
@@ -273,7 +226,7 @@
false
-
+
610
@@ -286,27 +239,11 @@
Add
-
-
-
- 440
- 60
- 281
- 131
-
-
-
-
-
-
- true
-
-
- 440
- 30
+ 460
+ 40
81
21
@@ -315,7 +252,7 @@
Description
-
+
490
@@ -328,19 +265,32 @@
Clear
-
-
-
-
- 480
- 70
- 131
- 41
-
-
-
- Delete
-
+
+
+
+ 460
+ 70
+ 261
+ 87
+
+
+
+
+
+
+ 150
+ 70
+ 271
+ 31
+
+
+
+
+
+
+ false
+
+
@@ -368,6 +318,32 @@
Qt::Horizontal
+
+
+
+ 390
+ 70
+ 110
+ 41
+
+
+
+ Search
+
+
+
+
+
+ 630
+ 70
+ 120
+ 41
+
+
+
+ Delete
+
+
diff --git a/Screens/Products.ui b/Screens/Products.ui
index a02cf68..a8c1bce 100644
--- a/Screens/Products.ui
+++ b/Screens/Products.ui
@@ -6,8 +6,8 @@
0
0
- 972
- 755
+ 1280
+ 698
@@ -18,7 +18,7 @@
410
- -10
+ 0
171
81
@@ -34,13 +34,310 @@
Inventory
-
+
+
+
+ 20
+ 640
+ 110
+ 41
+
+
+ -
+
+ Product Name
+
+
+ -
+
+ Quantity Produced
+
+
+ -
+
+ Quantity Sold
+
+
+ -
+
+ Quantity Available
+
+
+ -
+
+ Price
+
+
+ -
+
+ Category Name
+
+
+
+
+
+
+ 160
+ 640
+ 391
+ 41
+
+
+
+ Search
+
+
+
+
+
+ 690
+ 640
+ 131
+ 41
+
+
+
+ Edit
+
+
+
+
+
+ 20
+ 70
+ 931
+ 311
+
+
+
+ Add Product
+
+
+
+
+ 30
+ 110
+ 81
+ 21
+
+
+
+ Quantity
+
+
+
+
+
+ 30
+ 170
+ 101
+ 21
+
+
+
+ Unit Price
+
+
+
+
+
+ 170
+ 110
+ 271
+ 31
+
+
+
+
+
+
+ false
+
+
+
+
+
+ 30
+ 230
+ 101
+ 21
+
+
+
+ Category Name
+
+
+
+
+
+ 170
+ 170
+ 271
+ 31
+
+
+
+
+
+
+ false
+
+
+
+
+
+ 710
+ 250
+ 141
+ 41
+
+
+
+ Add
+
+
+
+
+
+ 460
+ 40
+ 81
+ 21
+
+
+
+ Description
+
+
+
+
+
+ 510
+ 250
+ 141
+ 41
+
+
+
+ Clear
+
+
+
+
+
+ 30
+ 60
+ 101
+ 20
+
+
+
+ Product Name
+
+
+
+
+
+ 170
+ 50
+ 271
+ 31
+
+
+
+
+
+
+ false
+
+
+
+
+
+ 470
+ 70
+ 441
+ 161
+
+
+
+
+
+
+ 170
+ 230
+ 271
+ 31
+
+
+ -
+
+ Men
+
+
+ -
+
+ Women
+
+
+ -
+
+ Boys
+
+
+ -
+
+ Girls
+
+
+
+
+
+
+
+ 27
+ 60
+ 921
+ 20
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 30
+ 10
+ 921
+ 20
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 560
+ 640
+ 131
+ 41
+
+
+
+ Search
+
+
+
20
- 190
+ 450
931
- 181
+ 180
@@ -164,7 +461,7 @@
- Quantity Produced
+ Qty Produced
@@ -175,7 +472,7 @@
- Quantity Sold
+ Qty Sold
@@ -186,7 +483,7 @@
- Category ID
+ Category Name
@@ -196,396 +493,12 @@
-
+
- 50
- 140
- 111
- 41
-
-
- -
-
- Product ID
-
-
- -
-
- Product Name
-
-
- -
-
- Price
-
-
- -
-
- Quantity
-
-
- -
-
- Category ID
-
-
-
-
-
-
- 180
- 140
- 491
- 41
-
-
-
- Search
-
-
-
-
-
- 170
- 70
- 641
- 61
-
-
-
-
-
-
-
-
-
- Draft
-
-
-
- 75
- true
-
-
-
-
-
- Processing
-
-
-
- 75
- true
-
-
-
-
-
- Errors
-
-
-
- 75
- true
-
-
-
-
-
- Published
-
-
-
- 75
- true
-
-
-
-
-
- Unpublished
-
-
-
- 75
- true
-
-
-
- -
-
- 0
-
-
- AlignCenter
-
-
- -
-
- 0
-
-
- AlignCenter
-
-
- -
-
- 199
-
-
- AlignCenter
-
-
- -
-
- 1022
-
-
- AlignCenter
-
-
- -
-
- 324
-
-
- AlignCenter
-
-
-
-
-
-
- 820
- 140
- 131
- 41
-
-
-
- Edit
-
-
-
-
-
- 20
- 390
- 931
- 311
-
-
-
- Add Product
-
-
-
-
- 30
- 60
- 81
- 21
-
-
-
- Product ID
-
-
-
-
-
- 30
- 110
- 101
- 21
-
-
-
- Product Name
-
-
-
-
-
- 170
- 60
- 271
- 31
-
-
-
-
-
-
- true
-
-
-
-
-
- 170
- 110
- 271
- 31
-
-
-
-
-
-
- true
-
-
-
-
-
- 30
- 160
- 81
- 21
-
-
-
- Quantity
-
-
-
-
-
- 30
- 210
- 101
- 21
-
-
-
- Unit Price
-
-
-
-
-
- 170
- 160
- 271
- 31
-
-
-
-
-
-
- false
-
-
-
-
-
- 30
- 260
- 101
- 21
-
-
-
- Category ID
-
-
-
-
-
- 170
- 210
- 271
- 31
-
-
-
-
-
-
- false
-
-
-
-
-
- 170
- 260
- 271
- 31
-
-
-
-
-
-
- false
-
-
-
-
-
- 710
- 250
- 141
- 41
-
-
-
- Add
-
-
-
-
-
- 462
- 70
- 441
- 161
-
-
-
-
-
-
- true
-
-
-
-
-
- 460
- 40
- 81
- 21
-
-
-
- Description
-
-
-
-
-
- 510
- 250
- 141
- 41
-
-
-
- Clear
-
-
-
-
-
-
- 680
- 140
- 131
+ 820
+ 640
+ 131
41
@@ -593,40 +506,14 @@
Delete
-
-
-
- 27
- 50
- 921
- 20
-
-
-
- Qt::Horizontal
-
-
-
-
-
- 30
- 0
- 921
- 20
-
-
-
- Qt::Horizontal
-
-
diff --git a/Screens/Purchase.ui b/Screens/Purchase.ui
index 91e3ee4..3177103 100644
--- a/Screens/Purchase.ui
+++ b/Screens/Purchase.ui
@@ -6,20 +6,20 @@
0
0
- 846
- 666
+ 591
+ 601
- MainWindow
+ Purchase
20
- 30
- 141
+ 10
+ 191
51
@@ -31,15 +31,15 @@
- Purchases
+ Purchase
20
- 80
- 791
+ 50
+ 541
31
@@ -54,12 +54,12 @@
Qt::Horizontal
-
+
20
- 110
- 801
+ 80
+ 551
201
@@ -148,11 +148,6 @@
Purchase Date
-
-
- Purchase Time
-
-
Total Amount
@@ -160,41 +155,28 @@
- Vendor ID
+ Vendor Name
-
-
-
- 620
- 520
- 181
- 51
-
-
-
- Delete
-
-
20
- 320
- 541
- 281
+ 300
+ 351
+ 241
- Purchases Overview
+ Purchase Overview
20
30
- 61
+ 81
16
@@ -202,7 +184,7 @@
Purchase ID
-
+
20
@@ -215,7 +197,7 @@
- 80
+ 20
100
55
16
@@ -225,10 +207,10 @@
Date:
-
+
- 200
+ 190
50
141
31
@@ -238,20 +220,20 @@
- 200
+ 190
30
- 55
+ 81
16
- Vendor ID
+ Vendor Name
- 80
+ 190
130
55
16
@@ -261,12 +243,12 @@
To:
-
+
- 120
+ 230
130
- 110
+ 101
22
@@ -277,93 +259,34 @@
- 80
- 160
- 55
- 16
-
-
-
- From:
-
-
-
-
-
- 120
- 160
- 110
- 22
-
-
-
- true
-
-
-
-
-
- 330
+ 20
130
55
16
-
- To:
-
-
-
-
-
- 330
- 160
- 55
- 16
-
-
From:
-
+
- 330
- 100
- 55
- 16
-
-
-
- Time:
-
-
-
-
-
- 380
+ 60
130
- 118
+ 101
22
-
-
-
-
- 380
- 160
- 118
- 22
-
+
+ true
-
+
- 180
- 210
+ 80
+ 170
181
51
@@ -372,39 +295,13 @@
Search
-
-
-
- 380
- 30
- 81
- 16
-
-
-
- Amount
-
-
-
-
-
- 380
- 50
- 141
- 31
-
-
-
-
-
-
20
0
- 791
+ 541
31
@@ -419,30 +316,69 @@
Qt::Horizontal
-
+
- 620
- 450
+ 390
+ 409
181
- 51
+ 30
- Insert
+ Add
-
+
- 620
- 380
+ 390
+ 309
181
- 51
+ 30
+
+
+
+ View/Edit
+
+
+
+
+
+ 390
+ 459
+ 181
+ 30
+
+
+
+ Delete
+
+
+
+
+
+ 390
+ 359
+ 181
+ 30
+
+
+
+ Refresh
+
+
+
+
+
+ 390
+ 509
+ 181
+ 30
- View
+ Reports
@@ -451,7 +387,7 @@
0
0
- 846
+ 591
21
@@ -461,3 +397,4 @@
+
diff --git a/Screens/PurchaseReport.ui b/Screens/PurchaseReport.ui
new file mode 100644
index 0000000..a03f623
--- /dev/null
+++ b/Screens/PurchaseReport.ui
@@ -0,0 +1,359 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 364
+ 542
+
+
+
+ MainWindow
+
+
+
+
+
+ 10
+ 0
+ 340
+ 31
+
+
+
+
+ 20
+ 75
+ true
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 10
+ 50
+ 340
+ 31
+
+
+
+
+ 20
+ 75
+ true
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 10
+ 10
+ 231
+ 51
+
+
+
+
+ 20
+ 75
+ true
+
+
+
+ Purchase Report
+
+
+
+
+
+ 10
+ 80
+ 341
+ 131
+
+
+
+
+
+
+
+
+ 10
+ 10
+ 141
+ 16
+
+
+
+ Money Spent on Purchases:
+
+
+
+
+
+ 160
+ 10
+ 171
+ 21
+
+
+
+
+
+
+ 10
+ 40
+ 70
+ 13
+
+
+
+ Timeframe:
+
+
+
+
+
+ 80
+ 40
+ 82
+ 17
+
+
+
+ All Time
+
+
+
+
+
+ 80
+ 60
+ 82
+ 20
+
+
+
+ Specific
+
+
+
+
+
+ 230
+ 90
+ 101
+ 22
+
+
+
+ true
+
+
+
+
+
+ 40
+ 90
+ 55
+ 16
+
+
+
+ From:
+
+
+
+
+
+ 200
+ 90
+ 21
+ 16
+
+
+
+ To:
+
+
+
+
+
+
+ 90
+ 170
+ 101
+ 22
+
+
+
+ true
+
+
+
+
+
+ 10
+ 230
+ 341
+ 221
+
+
+
+
+
+
+
+
+ 10
+ 10
+ 141
+ 16
+
+
+
+ Most Purchased Material:
+
+
+
+
+
+ 10
+ 120
+ 70
+ 13
+
+
+
+ Timeframe:
+
+
+
+
+
+ 80
+ 120
+ 82
+ 17
+
+
+
+ All Time
+
+
+
+
+
+ 80
+ 140
+ 82
+ 20
+
+
+
+ Specific
+
+
+
+
+
+ 230
+ 170
+ 101
+ 22
+
+
+
+ true
+
+
+
+
+
+ 40
+ 170
+ 55
+ 16
+
+
+
+ From:
+
+
+
+
+
+ 200
+ 170
+ 21
+ 16
+
+
+
+ To:
+
+
+
+
+
+ 80
+ 170
+ 101
+ 22
+
+
+
+ true
+
+
+
+
+
+ 160
+ 10
+ 171
+ 111
+
+
+
+
+
+
+
+ 210
+ 460
+ 141
+ 30
+
+
+
+ Generate
+
+
+
+
+
+
+
+
+
diff --git a/Screens/Sales.ui b/Screens/Sale.ui
similarity index 64%
rename from Screens/Sales.ui
rename to Screens/Sale.ui
index e47e568..9939da5 100644
--- a/Screens/Sales.ui
+++ b/Screens/Sale.ui
@@ -1,494 +1,420 @@
-
-
- MainWindow
-
-
-
- 0
- 0
- 846
- 666
-
-
-
- MainWindow
-
-
-
-
-
- 20
- 30
- 111
- 51
-
-
-
-
- 20
- 75
- true
-
-
-
- Sales
-
-
-
-
-
- 20
- 80
- 791
- 31
-
-
-
-
- 20
- 75
- true
-
-
-
- Qt::Horizontal
-
-
-
-
-
- 20
- 110
- 801
- 201
-
-
-
-
- 1
-
-
-
-
- 2
-
-
-
-
- 3
-
-
-
-
- 4
-
-
-
-
- 5
-
-
-
-
- 6
-
-
-
-
- 7
-
-
-
-
- 8
-
-
-
-
- 9
-
-
-
-
- 10
-
-
-
-
- 11
-
-
-
-
- 12
-
-
-
-
- 13
-
-
-
-
- 14
-
-
-
-
- 15
-
-
-
-
- Sale ID
-
-
-
-
- Sale Date
-
-
-
-
- Sale Time
-
-
-
-
- User ID
-
-
-
-
- Customer ID
-
-
-
-
- Total Amount
-
-
-
-
-
-
- 620
- 520
- 181
- 51
-
-
-
- Delete
-
-
-
-
-
- 20
- 320
- 551
- 281
-
-
-
- Sales Overview
-
-
-
-
- 20
- 30
- 55
- 16
-
-
-
- Sale ID
-
-
-
-
-
- 20
- 50
- 113
- 31
-
-
-
-
-
-
- 80
- 100
- 55
- 16
-
-
-
- Date:
-
-
-
-
-
- 150
- 50
- 113
- 31
-
-
-
-
-
-
- 150
- 30
- 55
- 16
-
-
-
- User ID
-
-
-
-
-
- 80
- 130
- 55
- 16
-
-
-
- To:
-
-
-
-
-
- 120
- 130
- 110
- 22
-
-
-
- true
-
-
-
-
-
- 80
- 160
- 55
- 16
-
-
-
- From:
-
-
-
-
-
- 120
- 160
- 110
- 22
-
-
-
- true
-
-
-
-
-
- 290
- 50
- 113
- 31
-
-
-
-
-
-
-
-
-
- 290
- 30
- 81
- 16
-
-
-
- Customer ID
-
-
-
-
-
- 330
- 130
- 55
- 16
-
-
-
- To:
-
-
-
-
-
- 330
- 160
- 55
- 16
-
-
-
- From:
-
-
-
-
-
- 330
- 100
- 55
- 16
-
-
-
- Time:
-
-
-
-
-
- 380
- 130
- 118
- 22
-
-
-
-
-
-
- 380
- 160
- 118
- 22
-
-
-
-
-
-
- 180
- 210
- 181
- 51
-
-
-
- Search
-
-
-
-
-
- 420
- 30
- 81
- 16
-
-
-
- Amount
-
-
-
-
-
- 420
- 50
- 113
- 31
-
-
-
-
-
-
-
-
-
-
- 20
- 0
- 791
- 31
-
-
-
-
- 20
- 75
- true
-
-
-
- Qt::Horizontal
-
-
-
-
-
- 620
- 450
- 181
- 51
-
-
-
- Insert
-
-
-
-
-
- 620
- 380
- 181
- 51
-
-
-
- View
-
-
-
-
-
-
-
-
-
+
+
+ Sale
+
+
+
+ 0
+ 0
+ 718
+ 555
+
+
+
+ Sales
+
+
+
+
+
+ 20
+ 10
+ 111
+ 51
+
+
+
+
+ 20
+ 75
+ true
+
+
+
+ Sales
+
+
+
+
+
+ 20
+ 50
+ 681
+ 31
+
+
+
+
+ 20
+ 75
+ true
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 20
+ 80
+ 681
+ 201
+
+
+
+
+ 1
+
+
+
+
+ 2
+
+
+
+
+ 3
+
+
+
+
+ 4
+
+
+
+
+ 5
+
+
+
+
+ 6
+
+
+
+
+ 7
+
+
+
+
+ 8
+
+
+
+
+ 9
+
+
+
+
+ 10
+
+
+
+
+ 11
+
+
+
+
+ 12
+
+
+
+
+ 13
+
+
+
+
+ 14
+
+
+
+
+ 15
+
+
+
+
+ Sale ID
+
+
+
+
+ Sale Date
+
+
+
+
+ Total Amount
+
+
+
+
+ Customer Name
+
+
+
+
+ Phone Number
+
+
+
+
+
+
+ 530
+ 409
+ 171
+ 40
+
+
+
+ Delete
+
+
+
+
+
+ 20
+ 300
+ 491
+ 201
+
+
+
+ Sales Overview
+
+
+
+
+ 10
+ 30
+ 55
+ 16
+
+
+
+ Sale ID
+
+
+
+
+
+ 10
+ 50
+ 151
+ 31
+
+
+
+
+
+
+ 20
+ 100
+ 55
+ 16
+
+
+
+ Date:
+
+
+
+
+
+ 20
+ 160
+ 55
+ 16
+
+
+
+ To:
+
+
+
+
+
+ 60
+ 160
+ 110
+ 22
+
+
+
+ true
+
+
+
+
+
+ 20
+ 130
+ 55
+ 16
+
+
+
+ From:
+
+
+
+
+
+ 60
+ 130
+ 110
+ 22
+
+
+
+ true
+
+
+
+
+
+ 170
+ 50
+ 151
+ 31
+
+
+
+
+
+
+
+
+
+ 170
+ 30
+ 101
+ 16
+
+
+
+ Customer Name
+
+
+
+
+
+ 240
+ 120
+ 181
+ 51
+
+
+
+ Search
+
+
+
+
+
+ 330
+ 30
+ 101
+ 16
+
+
+
+ Phone Number
+
+
+
+
+
+ 330
+ 50
+ 151
+ 31
+
+
+
+
+
+
+
+
+
+
+ 20
+ 0
+ 681
+ 31
+
+
+
+
+ 20
+ 75
+ true
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 530
+ 359
+ 171
+ 40
+
+
+
+ Add
+
+
+
+
+
+ 530
+ 309
+ 171
+ 40
+
+
+
+ View
+
+
+
+
+
+ 530
+ 459
+ 171
+ 40
+
+
+
+ Reports
+
+
+
+
+
+
+
+
+
diff --git a/Screens/SaleReport.ui b/Screens/SaleReport.ui
new file mode 100644
index 0000000..64d4805
--- /dev/null
+++ b/Screens/SaleReport.ui
@@ -0,0 +1,382 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 904
+ 579
+
+
+
+ MainWindow
+
+
+
+
+
+ 10
+ 0
+ 880
+ 31
+
+
+
+
+ 20
+ 75
+ true
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 10
+ 50
+ 880
+ 31
+
+
+
+
+ 20
+ 75
+ true
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 10
+ 10
+ 231
+ 51
+
+
+
+
+ 20
+ 75
+ true
+
+
+
+ Sale Report
+
+
+
+
+
+ 10
+ 80
+ 570
+ 441
+
+
+
+
+
+
+
+
+ 10
+ 10
+ 141
+ 16
+
+
+
+ Sales Revenue:
+
+
+
+
+
+ 200
+ 10
+ 171
+ 21
+
+
+
+
+
+
+ 10
+ 50
+ 70
+ 13
+
+
+
+ Timeframe:
+
+
+
+
+
+ 200
+ 50
+ 82
+ 17
+
+
+
+ All Time
+
+
+
+
+
+ 200
+ 70
+ 82
+ 17
+
+
+
+ Yearly
+
+
+
+
+
+ 290
+ 70
+ 82
+ 20
+
+
+
+ Monthly
+
+
+
+
+
+ 200
+ 110
+ 171
+ 22
+
+
+
+ true
+
+
+
+
+
+ 10
+ 110
+ 70
+ 13
+
+
+
+ Date:
+
+
+
+
+
+ 10
+ 150
+ 550
+ 240
+
+
+
+
+
+
+ 220
+ 402
+ 141
+ 30
+
+
+
+ Generate
+
+
+
+
+
+
+ 590
+ 80
+ 301
+ 311
+
+
+
+
+
+
+
+
+ 10
+ 10
+ 141
+ 16
+
+
+
+ Most Sold Item:
+
+
+
+
+
+ 10
+ 140
+ 70
+ 13
+
+
+
+ Timeframe:
+
+
+
+
+
+ 120
+ 140
+ 82
+ 17
+
+
+
+ All Time
+
+
+
+
+
+ 210
+ 140
+ 82
+ 20
+
+
+
+ Specific
+
+
+
+
+
+ 190
+ 200
+ 101
+ 22
+
+
+
+ true
+
+
+
+
+
+ 120
+ 230
+ 55
+ 16
+
+
+
+ From:
+
+
+
+
+
+ 120
+ 200
+ 21
+ 16
+
+
+
+ To:
+
+
+
+
+
+ 190
+ 230
+ 101
+ 22
+
+
+
+ true
+
+
+
+
+
+ 120
+ 10
+ 171
+ 111
+
+
+
+
+
+
+ 10
+ 200
+ 70
+ 13
+
+
+
+ Date:
+
+
+
+
+
+ 79
+ 269
+ 141
+ 30
+
+
+
+ Generate
+
+
+
+
+
+
+
+
+
+
diff --git a/Screens/TopVendors.ui b/Screens/TopVendors.ui
new file mode 100644
index 0000000..45650e6
--- /dev/null
+++ b/Screens/TopVendors.ui
@@ -0,0 +1,233 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 958
+ 380
+
+
+
+ MainWindow
+
+
+
+
+
+ 0
+ 20
+ 811
+ 280
+
+
+
+
+ 1
+
+
+
+
+ 2
+
+
+
+
+ 3
+
+
+
+
+ 4
+
+
+
+
+ 5
+
+
+
+
+ 6
+
+
+
+
+ 7
+
+
+
+
+ 8
+
+
+
+
+ 9
+
+
+
+
+ 10
+
+
+
+
+ 11
+
+
+
+
+ 12
+
+
+
+
+ 13
+
+
+
+
+ 14
+
+
+
+
+ 15
+
+
+
+
+ Vendor ID
+
+
+
+ 75
+ true
+
+
+
+
+
+ Vendor Name
+
+
+
+ 75
+ true
+
+
+
+
+
+ Contact Number
+
+
+
+ 75
+ true
+
+
+
+
+
+ Backup Contact
+
+
+
+ 75
+ true
+
+
+
+
+
+ Email
+
+
+
+ 75
+ true
+
+
+
+
+
+ Address
+
+
+
+ 75
+ true
+
+
+
+
+
+ Total Spent
+
+
+
+ 75
+ true
+
+
+
+
+
+
+
+ 830
+ 70
+ 120
+ 31
+
+
+
+
+
+
+
+
+
+ 850
+ 40
+ 111
+ 16
+
+
+
+ No of Vendors
+
+
+
+
+
+ 860
+ 110
+ 61
+ 31
+
+
+
+ OK
+
+
+
+
+
+
+
+
+
diff --git a/Screens/UserAuthentication.ui b/Screens/UserAuthentication.ui
index b89b1e5..8087858 100644
--- a/Screens/UserAuthentication.ui
+++ b/Screens/UserAuthentication.ui
@@ -204,7 +204,7 @@
- LOGIN
+ LOG IN
@@ -342,6 +342,25 @@
Qt::Vertical
+
+
+
+ 160
+ 320
+ 281
+ 41
+
+
+
+
+ 9
+ true
+
+
+
+ LOG OUT
+
+
graphicsView
label
label_5
@@ -359,6 +378,7 @@
line_4
vendorsButton
line_3
+ logoutButton
@@ -374,4 +394,4 @@
-
+
\ No newline at end of file
diff --git a/Screens/VendorHistory.ui b/Screens/VendorHistory.ui
new file mode 100644
index 0000000..01a1948
--- /dev/null
+++ b/Screens/VendorHistory.ui
@@ -0,0 +1,262 @@
+
+
+ mainWindow
+
+
+
+ 0
+ 0
+ 936
+ 657
+
+
+
+ Vendor History
+
+
+
+
+
+ 10
+ 10
+ 731
+ 100
+
+
+
+ vendor Overview
+
+
+
+
+ 20
+ 30
+ 91
+ 16
+
+
+
+ Name
+
+
+
+
+
+ 180
+ 30
+ 111
+ 16
+
+
+
+ Contact Number
+
+
+
+
+ false
+
+
+
+ 20
+ 50
+ 151
+ 31
+
+
+
+
+
+ false
+
+
+
+ 180
+ 50
+ 110
+ 31
+
+
+
+
+
+ false
+
+
+
+ 300
+ 50
+ 100
+ 31
+
+
+
+
+
+
+ 300
+ 30
+ 141
+ 16
+
+
+
+ Backup Contact
+
+
+
+
+ false
+
+
+
+ 410
+ 50
+ 151
+ 31
+
+
+
+
+
+
+
+
+
+ 420
+ 30
+ 91
+ 16
+
+
+
+ Email
+
+
+
+
+
+ 580
+ 30
+ 91
+ 16
+
+
+
+ Address
+
+
+
+
+ false
+
+
+
+ 570
+ 50
+ 151
+ 31
+
+
+
+
+
+
+
+
+
+
+ 10
+ 120
+ 391
+ 421
+
+
+
+
+ PurchaseID
+
+
+
+
+ Total Amount
+
+
+
+
+ Purchase Date
+
+
+
+
+
+
+ 410
+ 120
+ 511
+ 421
+
+
+
+
+ Material Name
+
+
+
+
+ Material Desc
+
+
+
+
+ Quantity
+
+
+
+
+ Cost
+
+
+
+
+
+
+ 130
+ 560
+ 151
+ 41
+
+
+
+ Open Purchase Details
+
+
+
+
+
+ 590
+ 560
+ 151
+ 41
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
diff --git a/Screens/Vendors.ui b/Screens/Vendors.ui
index d9e9223..e5936ff 100644
--- a/Screens/Vendors.ui
+++ b/Screens/Vendors.ui
@@ -6,8 +6,8 @@
0
0
- 1202
- 461
+ 1174
+ 519
@@ -40,7 +40,7 @@
20
170
791
- 221
+ 281
@@ -140,20 +140,15 @@
-
+
- 680
+ 20
90
131
41
- -
-
- Vendor ID
-
-
-
Vendor Name
@@ -164,33 +159,23 @@
Contact Number
- -
-
- Backup Contact
-
-
-
Email
- -
-
- Address
-
-
-
+
- 20
+ 170
90
- 651
+ 501
41
- Search Vendors
+
@@ -355,7 +340,7 @@
- 120
+ 100
240
131
41
@@ -378,7 +363,7 @@
20
0
- 1271
+ 1141
20
@@ -389,9 +374,9 @@
- 890
- 20
- 131
+ 833
+ 410
+ 150
41
@@ -406,11 +391,11 @@
Edit
-
+
- 1030
- 20
+ 680
+ 90
131
41
@@ -422,17 +407,77 @@
true
+
+ Search
+
+
+
+
+
+ 997
+ 410
+ 150
+ 41
+
+
+
+
+ 8
+ 75
+ true
+
+
Delete
+
+
+
+ 1010
+ 20
+ 150
+ 41
+
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Top Vendors
+
+
+
+
+
+ 850
+ 20
+ 150
+ 41
+
+
+
+
+ 8
+ 75
+ true
+
+
+
+ Vendor History
+
+