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 + + + + + + + + + 0 + 0 + 1085 + 26 + + + + + + + + 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 - - - - - - - - - 0 - 0 - 1254 - 21 - - - - - - - - + + + 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 + + + + + + + + + 0 + 0 + 1255 + 26 + + + + + + + + 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 + + @@ -375,7 +351,7 @@ 0 0 771 - 21 + 24 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 - - 0 0 - 972 - 26 + 1280 + 24 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 + + + + + + + 0 + 0 + 364 + 24 + + + + + + + + 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 - - - - - - - 0 - 0 - 846 - 26 - - - - - - - - + + + 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 + + + + + + + 0 + 0 + 718 + 21 + + + + + + + + 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 + + + + + + + + 0 + 0 + 904 + 24 + + + + + + + + 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 + + + + + + + 0 + 0 + 958 + 24 + + + + + + + + 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 @@ -366,7 +386,7 @@ 0 0 1099 - 21 + 26 @@ -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 + + + + + + + 0 + 0 + 936 + 26 + + + + + + + + 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 + + 0 0 - 1202 + 1174 26 diff --git a/Screens/ViewPurchase.ui b/Screens/ViewPurchase.ui new file mode 100644 index 0000000..ebdf699 --- /dev/null +++ b/Screens/ViewPurchase.ui @@ -0,0 +1,359 @@ + + + MainWindow + + + + 0 + 0 + 614 + 681 + + + + View Purchase + + + + + + 10 + 10 + 591 + 431 + + + + Purchase Overview + + + + + 20 + 30 + 81 + 16 + + + + Purchase ID + + + + + + 20 + 50 + 141 + 31 + + + + Qt::AlignCenter + + + + + + 170 + 30 + 55 + 16 + + + + Date: + + + + + + 320 + 50 + 141 + 31 + + + + Qt::AlignCenter + + + + + + 320 + 30 + 81 + 16 + + + + Vendor Name + + + + + + 170 + 50 + 141 + 31 + + + + true + + + + + + 260 + 370 + 91 + 16 + + + + Total Amount + + + + + + 230 + 390 + 141 + 31 + + + + Qt::AlignCenter + + + + + + 20 + 100 + 561 + 261 + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 10 + + + + + Material Name + + + + + Quantity + + + + + Cost + + + + + Total + + + + + + + + 10 + 450 + 591 + 101 + + + + Edit Purchase + + + + + 480 + 20 + 101 + 21 + + + + Unit Cost + + + + + + 310 + 20 + 101 + 21 + + + + Quantity + + + + + + 10 + 50 + 241 + 31 + + + + + + + Qt::AlignCenter + + + true + + + + + + 280 + 50 + 121 + 31 + + + + + + + Qt::AlignCenter + + + false + + + + + + 430 + 50 + 151 + 31 + + + + + + + Qt::AlignCenter + + + false + + + + + + 90 + 20 + 101 + 21 + + + + Material Name + + + + + + + 130 + 560 + 181 + 51 + + + + Save + + + + + + 320 + 560 + 181 + 51 + + + + Done + + + + + + + 0 + 0 + 614 + 26 + + + + + + + + diff --git a/Screens/ViewSale.ui b/Screens/ViewSale.ui new file mode 100644 index 0000000..8196977 --- /dev/null +++ b/Screens/ViewSale.ui @@ -0,0 +1,396 @@ + + + MainWindow + + + + 0 + 0 + 620 + 670 + + + + MainWindow + + + + + + 120 + 560 + 181 + 51 + + + + Save + + + + + + 10 + 10 + 601 + 431 + + + + Sale Overview + + + + + 20 + 30 + 81 + 16 + + + + Sale ID + + + + + + 20 + 50 + 141 + 31 + + + + Qt::AlignCenter + + + + + + 170 + 30 + 55 + 16 + + + + Date: + + + + + + 320 + 50 + 141 + 31 + + + + Qt::AlignCenter + + + + + + 320 + 30 + 101 + 16 + + + + Customer Name + + + + + + 170 + 50 + 141 + 31 + + + + true + + + + + + 250 + 370 + 91 + 16 + + + + Total Amount + + + + + + 220 + 390 + 141 + 31 + + + + Qt::AlignCenter + + + + + + 20 + 100 + 561 + 261 + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 10 + + + + + Product ID + + + + + Product Name + + + + + Quantity + + + + + Price + + + + + Total + + + + + + + + 10 + 450 + 601 + 101 + + + + Edit Sale + + + + + 520 + 20 + 41 + 21 + + + + Price + + + + + + 380 + 20 + 101 + 21 + + + + Quantity + + + + + + 140 + 50 + 181 + 31 + + + + + + + Qt::AlignCenter + + + true + + + + + + 350 + 50 + 101 + 31 + + + + + + + Qt::AlignCenter + + + false + + + + + + 480 + 50 + 111 + 31 + + + + + + + Qt::AlignCenter + + + false + + + + + + 190 + 20 + 101 + 21 + + + + Product Name + + + + + + 30 + 20 + 101 + 21 + + + + Product ID + + + + + + 10 + 50 + 101 + 31 + + + + + + + Qt::AlignCenter + + + true + + + + + + + 310 + 560 + 181 + 51 + + + + Done + + + + + + + 0 + 0 + 620 + 26 + + + + + + + + diff --git a/TopVendorsClass.py b/TopVendorsClass.py new file mode 100644 index 0000000..c731a73 --- /dev/null +++ b/TopVendorsClass.py @@ -0,0 +1,90 @@ +# # Importing essential modules +# import typing +# from PyQt6 import QtCore, 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 TopVendorScreen(QtWidgets.QMainWindow): +# def __init__(self) : +# super(TopVendorScreen, self).__init__() + +# uic.loadUi('Screens/TopVendors.ui', self) + +# self.setWindowTitle("Top Vendors") + +# self.okButton.clicked.connect(self.PopulateTopVendorTable) + +# def PopulateTopVendorTable(self): +# noOfVendors = self.noOfVendors.text() +# if not noOfVendors or not noOfVendors.isdigit(): +# self.msg = QtWidgets.QMessageBox() +# self.msg.setWindowTitle("Error") +# self.msg.setText("Please enter a positive numeric value for number of customers to be searched.") +# self.msg.show() +# return + +# sql_query = """ +# select top (?) Vendor.vendorID, Vendor.vendorName, contactNumber, backupContact, email, [address],SUM(totalAmount) +# from Purchase inner join Vendor on Purchase.vendorID = Vendor.vendorID +# group by Vendor.vendorID, Vendor.vendorName, contactNumber, backupContact, email, [address] +# order by SUM(totalAmount) desc +# # """ +# cursor.execute(sql_query, int(noOfVendors)) + +# self.topVendorTable.setRowCount(0) +# for row_number, row_data in enumerate(cursor): +# self.topVendorTable.insertRow(row_number) +# for column_number, data in enumerate(row_data): +# self.topVendorTable.setItem(row_number, column_number, QTableWidgetItem(str(data))) + + +# Importing essential modules +import typing +from PyQt6 import QtCore, QtWidgets, uic +from PyQt6.QtCore import QDate +from PyQt6.QtWidgets import QApplication, QMainWindow, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget, QHeaderView +import sys +import pyodbc +import EditVendorClass + +from ConnectionString import connection, cursor + +class TopVendorScreen(QtWidgets.QMainWindow): + def __init__(self) : + super(TopVendorScreen, self).__init__() + + uic.loadUi('Screens/TopVendors.ui', self) + + self.setWindowTitle("Top Vendors") + + self.okButton.clicked.connect(self.PopulateTopVendorTable) + + def PopulateTopVendorTable(self): + noOfVendors = self.noOfVendors.text() + if not noOfVendors or not noOfVendors.isdigit(): + self.msg = QtWidgets.QMessageBox() + self.msg.setWindowTitle("Error") + self.msg.setText("Please enter a positive numeric value for number of Vendors to be searched.") + self.msg.show() + return + + sql_query = """ + select top (?) Vendor.vendorID, Vendor.vendorName, contactNumber, backupContact, email, [address],SUM(totalAmount) + from Purchase inner join Vendor on Purchase.vendorID = Vendor.vendorID + group by Vendor.vendorID, Vendor.vendorName, contactNumber, backupContact, email, [address] + order by SUM(totalAmount) desc + """ + + cursor.execute(sql_query, int(noOfVendors)) + + self.topVendorTable.setRowCount(0) + for row_number, row_data in enumerate(cursor): + self.topVendorTable.insertRow(row_number) + for column_number, data in enumerate(row_data): + self.topVendorTable.setItem(row_number, column_number, QTableWidgetItem(str(data))) + diff --git a/VendorClass.py b/VendorClass.py new file mode 100644 index 0000000..f313b03 --- /dev/null +++ b/VendorClass.py @@ -0,0 +1,341 @@ +# # 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 EditVendorClass +# import TopVendorsClass + +# from ConnectionString import connection, cursor + +# class VendorScreen(QtWidgets.QMainWindow): +# def __init__(self): +# # Call the inherited classes __init__ method +# super(VendorScreen, self).__init__() + +# # Load the .ui file +# uic.loadUi('Screens/Vendors.ui', self) + +# self.PopulateVendorTable() +# self.searchVendorValue.setPlaceholderText("Search") +# self.addVendorButton.clicked.connect(self.AddVendor) +# self.editVendorButton.clicked.connect(self.EditVendor) +# self.searchVendorButton.clicked.connect(self.SearchVendor) +# self.deleteVendorButton.clicked.connect(self.DeleteVendor) +# self.vendorHistoryButton.clicked.connect(self.OpenVendorHistoryScreen) +# self.topVendorsButton.clicked.connect(self.OpenTopVendorsScreen) + +# 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 AddVendor(self): +# name = self.vendorNameBox.text() +# contact = self.vendorContactNumber.text() +# backupContact = self.vendorBackupContact.text() +# email = self.vendorEmail.text() +# address = self.vendorAddress.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 vendor values(?, ?, ?, ?, ?)" +# cursor.execute(sql_query, (name, contact, +# backupContact, email, address)) +# connection.commit() +# self.msg.setWindowTitle("Success") +# self.msg.setText("Vendor added successfully.") +# self.PopulateVendorTable() +# self.msg.show() + +# def SearchVendor(self): +# criteria = self.searchVendorCriteria.currentText() +# if criteria == "Vendor Name": +# criteria = "vendorName" +# elif criteria == "Contact Number": +# criteria = "contactNumber" +# elif criteria == "Email": +# criteria = "email" +# value = self.searchVendorValue.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 vendor 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.PopulateVendorTable() +# return + +# self.vendorTable.setRowCount(0) + +# for row_index, row_data in enumerate(rows): +# 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 DeleteVendor(self): +# selected_items = self.vendorTable.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() +# vendor_id = int(self.vendorTable.item(selected_row, 0).text()) + +# # Code block to check if the vendor has purchase history. If yes, then vendor cannot be deleted +# sql_check_sales = "select count(*) from Purchase where vendorID = ?" +# cursor.execute(sql_check_sales, (vendor_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 vendor with existing purchase records.") +# self.msg.show() +# return + +# sql_query = "delete from vendor WHERE vendorID = ?" +# cursor.execute(sql_query, (vendor_id)) +# connection.commit() + +# self.msg = QtWidgets.QMessageBox() +# self.msg.setWindowTitle("Success") +# self.msg.setText("Vendor deleted successfully.") +# self.msg.show() + +# self.PopulateVendorTable() # Update the vendorTable after deletion + +# def EditVendor(self): +# selected_items = self.vendorTable.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() +# vendor_data = [self.vendorTable.item(selected_row, col_index).text( +# ) for col_index in range(self.vendorTable.columnCount())] + +# self.editVendor = EditVendorClass.EditVendorScreen(vendor_data) +# self.editVendor.vendorUpdated.connect(self.PopulateVendorTable) +# self.editVendor.show() + +# def OpenVendorHistoryScreen(self): +# pass + +# def OpenTopVendorsScreen(self): +# self.topVendors = TopVendorsClass.TopVendorScreen() +# self.topVendors.show() + +# 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 EditVendorClass +from VendorHistoryClass import VendorHistoryScreen +from TopVendorsClass import TopVendorScreen + +from ConnectionString import connection, cursor + + +class VendorScreen(QtWidgets.QMainWindow): + def __init__(self): + # Call the inherited classes __init__ method + super(VendorScreen, self).__init__() + + # Load the .ui file + uic.loadUi('Screens/Vendors.ui', self) + + self.PopulateVendorTable() + self.searchVendorValue.setPlaceholderText("Search") + self.addVendorButton.clicked.connect(self.AddVendor) + self.editVendorButton.clicked.connect(self.EditVendor) + self.searchVendorButton.clicked.connect(self.SearchVendor) + self.deleteVendorButton.clicked.connect(self.DeleteVendor) + self.VendorHistoryButton.clicked.connect(self.OpenVendorHistoryScreen) + self.topVendorsButton.clicked.connect(self.OpenTopVendorsScreen) + + 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 AddVendor(self): + name = self.vendorNameBox.text() + contact = self.vendorContactNumber.text() + backupContact = self.vendorBackupContact.text() + email = self.vendorEmail.text() + address = self.vendorAddress.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.") + elif not contact.isdigit() or not backupContact.isdigit(): + self.msg.setWindowTitle("Error") + self.msg.setText("Contact and Backup contact should be numeric") + else: + sql_query = "insert into vendor values(?, ?, ?, ?, ?)" + cursor.execute(sql_query, (name, contact, + backupContact, email, address)) + connection.commit() + self.msg.setWindowTitle("Success") + self.msg.setText("Vendor added successfully.") + self.PopulateVendorTable() + self.msg.show() + + def SearchVendor(self): + criteria = self.searchVendorCriteria.currentText() + if criteria == "Vendor Name": + criteria = "vendorName" + elif criteria == "Contact Number": + criteria = "contactNumber" + elif criteria == "Email": + criteria = "email" + value = self.searchVendorValue.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 vendor 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.PopulateVendorTable() + return + + self.vendorTable.setRowCount(0) + + for row_index, row_data in enumerate(rows): + 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 DeleteVendor(self): + selected_items = self.vendorTable.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() + vendor_id = int(self.vendorTable.item(selected_row, 0).text()) + + # Code block to check if the vendor has purchase history. If yes, then vendor cannot be deleted + sql_check_sales = "select count(*) from Purchase where vendorID = ?" + cursor.execute(sql_check_sales, (vendor_id,)) + result = cursor.fetchone() + + # Throw error message if vendors has pre-existing sales record + if result and result[0] > 0: + self.msg = QtWidgets.QMessageBox() + self.msg.setWindowTitle("Error") + self.msg.setText("Cannot delete vendor with existing purchase records.") + self.msg.show() + return + + sql_query = "delete from vendor WHERE vendorID = ?" + cursor.execute(sql_query, (vendor_id)) + connection.commit() + + self.msg = QtWidgets.QMessageBox() + self.msg.setWindowTitle("Success") + self.msg.setText("Vendor deleted successfully.") + self.msg.show() + + self.PopulateVendorTable() # Update the vendorTable after deletion + + def EditVendor(self): + selected_items = self.vendorTable.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() + vendor_data = [self.vendorTable.item(selected_row, col_index).text( + ) for col_index in range(self.vendorTable.columnCount())] + + self.editVendor = EditVendorClass.EditVendorScreen(vendor_data) + self.editVendor.vendorUpdated.connect(self.PopulateVendorTable) + self.editVendor.show() + + def OpenTopVendorsScreen(self): + self.topvendors = TopVendorScreen() + self.topvendors.show() + + def OpenVendorHistoryScreen(self): + selected_items = self.vendorTable.selectedItems() + + if not selected_items: + self.msg = QtWidgets.QMessageBox() + self.msg.setWindowTitle("Error") + self.msg.setText("Please select an entry to view history.") + self.msg.show() + return + + selected_row = selected_items[0].row() + vendor_id = int(self.vendorTable.item(selected_row, 0).text()) + vendor_name = self.vendorTable.item(selected_row, 1).text() + contact = self.vendorTable.item(selected_row, 2).text() + backup_contact = self.vendorTable.item(selected_row, 3).text() + email = self.vendorTable.item(selected_row, 4).text() + address = self.vendorTable.item(selected_row, 5).text() + + self.vendorHistory = VendorHistoryScreen(vendor_id, vendor_name, contact, backup_contact, email, address) + self.vendorHistory.show() + + + diff --git a/VendorHistoryClass.py b/VendorHistoryClass.py new file mode 100644 index 0000000..9be8fe9 --- /dev/null +++ b/VendorHistoryClass.py @@ -0,0 +1,82 @@ +# 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 EditVendorClass + +from ConnectionString import connection, cursor + +class VendorHistoryScreen(QtWidgets.QMainWindow): + def __init__(self, Vendor_id, Vendor_name, contact, backup_contact, email, address): + # Call the inherited classes __init__ method + super(VendorHistoryScreen, self).__init__() + + # Load the .ui file + uic.loadUi('Screens/VendorHistory.ui', self) + + self.Vendor_id = Vendor_id + self.Vendor_name = Vendor_name + self.contact = contact + self.backup_contact = backup_contact + self.email = email + self.address = address + + self.vendorName.setText(Vendor_name) + self.vendorContact.setText(contact) + self.vendorBackup.setText(backup_contact) + self.vendorEmail.setText(email) + self.vendorAddress.setText(address) + self.openPurchaseButton.clicked.connect(self.ShowPurchaseDetails) + self.clearButton.clicked.connect(self.ClearTable) + + self.setWindowTitle(f"Vendor History - {Vendor_name}") + + self.PopulatePurchaseSummaryTable() + + def ClearTable(self): + self.purchaseMaterialTable.setRowCount(0) + + def ShowPurchaseDetails(self): + selected_items = self.purchaseSummaryTable.selectedItems() + + if not selected_items: + self.msg = QtWidgets.QMessageBox() + self.msg.setWindowTitle("Error") + self.msg.setText("Please select an entry to view details.") + self.msg.show() + return + + selected_row = selected_items[0].row() + Purchase_id = int(self.purchaseSummaryTable.item(selected_row, 0).text()) + + self.purchaseMaterialTable.setRowCount(0) + + sql_query = """ + select Material.MaterialName, Material.description, PurchaseMaterial.quantity, PurchaseMaterial.cost from PurchaseMaterial + inner join Material on PurchaseMaterial.MaterialID = Material.MaterialID + where PurchaseID = ? + """ + cursor.execute(sql_query, (Purchase_id,)) + + for row_index, row_data in enumerate(cursor.fetchall()): + self.purchaseMaterialTable.insertRow(row_index) + for col_index, cell_data in enumerate(row_data): + item = QTableWidgetItem(str(cell_data)) + self.purchaseMaterialTable.setItem(row_index, col_index, item) + self.purchaseMaterialTable.resizeColumnsToContents() + + + def PopulatePurchaseSummaryTable(self): + sql_query = """ + select PurchaseID, totalAmount, PurchaseDate from Purchase where Purchase.VendorID = ? + """ + cursor.execute(sql_query, self.Vendor_id) + self.purchaseSummaryTable.setRowCount(0) + + for row_index, row_data in enumerate(cursor.fetchall()): + self.purchaseSummaryTable.insertRow(row_index) + for col_index, cell_data in enumerate(row_data): + item = QTableWidgetItem(str(cell_data)) + self.purchaseSummaryTable.setItem(row_index, col_index, item) \ No newline at end of file diff --git a/VendorScreen.py b/VendorScreen.py deleted file mode 100644 index 2493146..0000000 --- a/VendorScreen.py +++ /dev/null @@ -1,22 +0,0 @@ -# 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 - -server = 'localhost' -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 - - - -class VendorScreen(QtWidgets.QMainWindow): - def __init__(self): - # Call the inherited classes __init__ method - super(VendorScreen, self).__init__() - - # Load the .ui file - uic.loadUi('Screens/Vendors.ui', self) \ No newline at end of file diff --git a/ViewPurchaseClass.py b/ViewPurchaseClass.py new file mode 100644 index 0000000..c20375c --- /dev/null +++ b/ViewPurchaseClass.py @@ -0,0 +1,79 @@ +# 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 ViewPurchaseScreen(QtWidgets.QMainWindow): + def __init__(self, purchase_id, purchase_date, total_amount, vendor_name): + super(ViewPurchaseScreen, self).__init__() + uic.loadUi("Screens/ViewPurchase.ui", self) + + self.MaterialTable.itemSelectionChanged.connect(self.get_selected_material_data) + self.savePurchaseButton.clicked.connect(self.SaveEdit) + self.DonePurchaseButton.clicked.connect(self.DoneEdit) + + self.purchase_id = int(purchase_id) + self.purchase_date = QDate.fromString(str(purchase_date), 'yyyy-MM-dd') + self.total_amount = int(total_amount) + self.vendor_name = str(vendor_name) + + self.viewPurchaseId.setText(str(self.purchase_id)) + self.viewPurchaseId.setDisabled(True) + + self.viewPurchaseDate.setDate(self.purchase_date) + self.viewPurchaseDate.setDisabled(True) + + self.viewTotalAmount.setText(str(self.total_amount)) + self.viewTotalAmount.setDisabled(True) + + self.viewVendorName.setText(str(self.vendor_name)) + self.viewVendorName.setDisabled(True) + + cursor.execute("SELECT Material.materialName, PurchaseMaterial.quantity, PurchaseMaterial.cost, PurchaseMaterial.quantity*PurchaseMaterial.cost FROM PurchaseMaterial JOIN Purchase ON PurchaseMaterial.purchaseID = Purchase.purchaseID JOIN Material ON PurchaseMaterial.materialID = Material.materialID WHERE PurchaseMaterial.purchaseID = ?", (purchase_id,)) + 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 get_selected_material_data(self): + + selected_row = self.MaterialTable.currentRow() + MaterialName = self.MaterialTable.item(selected_row, 0).text() + Quantity = self.MaterialTable.item(selected_row, 1).text() + UnitCost = self.MaterialTable.item(selected_row, 2).text() + + self.MaterialName.setText(MaterialName) + self.Quantity.setText(Quantity) + self.UnitCost.setText(UnitCost) + + def DoneEdit(self): + self.close() + + def SaveEdit(self): + PurchaseID = self.viewPurchaseId.text() + Quantity = self.Quantity.text() + UnitCost = self.UnitCost.text() + + sql_query = """ + update PurchaseMaterial + set quantity = (?), cost = (?) + WHERE purchaseID = (?) + """ + + cursor.execute(sql_query, (Quantity, UnitCost, PurchaseID)) + connection.commit() + + self.msg = QtWidgets.QMessageBox() + self.msg.setWindowTitle('Success') + self.msg.setText('Product edit successful') + self.msg.show() \ No newline at end of file diff --git a/ViewSaleClass.py b/ViewSaleClass.py new file mode 100644 index 0000000..cde2a71 --- /dev/null +++ b/ViewSaleClass.py @@ -0,0 +1,146 @@ +# 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 ViewSaleScreen(QtWidgets.QMainWindow): + def __init__(self, sale_id, sale_date, total_amount, customer_name): + super(ViewSaleScreen, self).__init__() + uic.loadUi("Screens/ViewSale.ui", self) + + self.ProductTable.itemSelectionChanged.connect(self.get_selected_Product_data) + self.saveSaleButton.clicked.connect(self.SaveEdit) + self.DoneSaleButton.clicked.connect(self.DoneEdit) + + self.sale_id = int(sale_id) + self.sale_date = QDate.fromString(str(sale_date), 'yyyy-MM-dd') + self.total_amount = int(total_amount) + self.customer_name = str(customer_name) + + self.viewSaleId.setText(str(self.sale_id)) + self.viewSaleId.setDisabled(True) + + self.viewSaleDate.setDate(self.sale_date) + self.viewSaleDate.setDisabled(True) + + self.viewTotalAmount.setText(str(self.total_amount)) + self.viewTotalAmount.setDisabled(True) + + self.viewCustomerName.setText(str(self.customer_name)) + self.viewCustomerName.setDisabled(True) + + cursor.execute("SELECT Products.ProductID, Products.ProductName, SaleProduct.Quantity, SaleProduct.soldprice, SaleProduct.Quantity*SaleProduct.soldprice FROM Sale JOIN SaleProduct ON Sale.saleID = SaleProduct.saleID JOIN Products ON SaleProduct.ProductID = Products.ProductID WHERE Sale.saleID = ?", (sale_id,)) + 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 get_selected_Product_data(self): + + selected_row = self.ProductTable.currentRow() + ProductID = self.ProductTable.item(selected_row, 0).text() + ProductName = self.ProductTable.item(selected_row, 1).text() + Quantity = self.ProductTable.item(selected_row, 2).text() + Price = self.ProductTable.item(selected_row, 3).text() + + self.ProductID.setText(ProductID) + self.ProductName.setText(ProductName) + self.Quantity.setText(Quantity) + self.Price.setText(Price) + + def DoneEdit(self): + self.close() + + def SaveEdit(self): + + SaleId = self.viewSaleId.text() + + Quantity = self.Quantity.text() + Price = self.Price.text() + selected_row = self.ProductTable.currentRow() + OldQuantity = self.ProductTable.item(selected_row, 2).text() + ProductID = self.ProductTable.item(selected_row, 0).text() + + sql_query = """ + UPDATE products + SET quanityProduced = quanityProduced + (?) + WHERE productID = (?) + """ + + cursor.execute(sql_query, (OldQuantity, ProductID)) + connection.commit() + + sql_query = """ + UPDATE products + SET quantitySold = quantitySold - (?) + WHERE productID = (?) + """ + + cursor.execute(sql_query, (OldQuantity, ProductID)) + connection.commit() + + cursor.execute(" select quanityProduced from products join saleProduct on products.productID = saleProduct.productID where saleProduct.saleID = ?", (SaleId,)) + availableQuantity = cursor.fetchone() + + if int(availableQuantity.quanityProduced) >= int(Quantity): + + sql_query = """ + update SaleProduct + set quantity = (?), soldPrice = (?) + WHERE SaleId = (?) + """ + + cursor.execute(sql_query, Quantity, Price, SaleId) + connection.commit() + + sql_query = """ + UPDATE products + SET quanityProduced = quanityProduced - (?) + WHERE productID = (?) + """ + cursor.execute(sql_query, (Quantity, ProductID)) + connection.commit() + + sql_query = """ + UPDATE products + SET quantitySold = quantitySold + (?) + WHERE productID = (?) + """ + + cursor.execute(sql_query, (Quantity, ProductID)) + connection.commit() + + self.msg = QtWidgets.QMessageBox() + self.msg.setWindowTitle('Success') + self.msg.setText('Product edit successful') + self.msg.show() + + else: + + sql_query = """ + UPDATE products + SET quanityProduced = quanityProduced - (?) + WHERE productID = (?) + """ + cursor.execute(sql_query, (OldQuantity, ProductID)) + connection.commit() + + sql_query = """ + UPDATE products + SET quantitySold = quantitySold - (?) + WHERE productID = (?) + """ + + cursor.execute(sql_query, (OldQuantity, ProductID)) + connection.commit() + + error_message = "Error: Required Quantity Is Not In Stock!." + QMessageBox.critical(self, "Error", error_message) \ No newline at end of file diff --git a/__pycache__/AddPurchaseClass.cpython-310.pyc b/__pycache__/AddPurchaseClass.cpython-310.pyc new file mode 100644 index 0000000..b8f6769 Binary files /dev/null and b/__pycache__/AddPurchaseClass.cpython-310.pyc differ diff --git a/__pycache__/AddSaleClass.cpython-310.pyc b/__pycache__/AddSaleClass.cpython-310.pyc new file mode 100644 index 0000000..1ce52b6 Binary files /dev/null and b/__pycache__/AddSaleClass.cpython-310.pyc differ diff --git a/__pycache__/ConnectionString.cpython-310.pyc b/__pycache__/ConnectionString.cpython-310.pyc new file mode 100644 index 0000000..19d897f Binary files /dev/null and b/__pycache__/ConnectionString.cpython-310.pyc differ diff --git a/__pycache__/CustomerClass.cpython-310.pyc b/__pycache__/CustomerClass.cpython-310.pyc new file mode 100644 index 0000000..f028e84 Binary files /dev/null and b/__pycache__/CustomerClass.cpython-310.pyc differ diff --git a/__pycache__/EditCustomerClass.cpython-310.pyc b/__pycache__/EditCustomerClass.cpython-310.pyc new file mode 100644 index 0000000..0958f3e Binary files /dev/null and b/__pycache__/EditCustomerClass.cpython-310.pyc differ diff --git a/__pycache__/EditMaterialClass.cpython-310.pyc b/__pycache__/EditMaterialClass.cpython-310.pyc new file mode 100644 index 0000000..c9e993d Binary files /dev/null and b/__pycache__/EditMaterialClass.cpython-310.pyc differ diff --git a/__pycache__/EditProductClass.cpython-310.pyc b/__pycache__/EditProductClass.cpython-310.pyc new file mode 100644 index 0000000..602801c Binary files /dev/null and b/__pycache__/EditProductClass.cpython-310.pyc differ diff --git a/__pycache__/EditVendorClass.cpython-310.pyc b/__pycache__/EditVendorClass.cpython-310.pyc new file mode 100644 index 0000000..d371314 Binary files /dev/null and b/__pycache__/EditVendorClass.cpython-310.pyc differ diff --git a/__pycache__/MaterialClass.cpython-310.pyc b/__pycache__/MaterialClass.cpython-310.pyc new file mode 100644 index 0000000..58eae8f Binary files /dev/null and b/__pycache__/MaterialClass.cpython-310.pyc differ diff --git a/__pycache__/ProductsClass.cpython-310.pyc b/__pycache__/ProductsClass.cpython-310.pyc new file mode 100644 index 0000000..55e6a46 Binary files /dev/null and b/__pycache__/ProductsClass.cpython-310.pyc differ diff --git a/__pycache__/PurchaseClass.cpython-310.pyc b/__pycache__/PurchaseClass.cpython-310.pyc new file mode 100644 index 0000000..e846dce Binary files /dev/null and b/__pycache__/PurchaseClass.cpython-310.pyc differ diff --git a/__pycache__/PurchaseReportClass.cpython-310.pyc b/__pycache__/PurchaseReportClass.cpython-310.pyc new file mode 100644 index 0000000..1683bd2 Binary files /dev/null and b/__pycache__/PurchaseReportClass.cpython-310.pyc differ diff --git a/__pycache__/SaleClass.cpython-310.pyc b/__pycache__/SaleClass.cpython-310.pyc new file mode 100644 index 0000000..09dd6f2 Binary files /dev/null and b/__pycache__/SaleClass.cpython-310.pyc differ diff --git a/__pycache__/SaleReportClass.cpython-310.pyc b/__pycache__/SaleReportClass.cpython-310.pyc new file mode 100644 index 0000000..f31ae35 Binary files /dev/null and b/__pycache__/SaleReportClass.cpython-310.pyc differ diff --git a/__pycache__/TopVendorsClass.cpython-310.pyc b/__pycache__/TopVendorsClass.cpython-310.pyc new file mode 100644 index 0000000..726f758 Binary files /dev/null and b/__pycache__/TopVendorsClass.cpython-310.pyc differ diff --git a/__pycache__/VendorClass.cpython-310.pyc b/__pycache__/VendorClass.cpython-310.pyc new file mode 100644 index 0000000..62a545a Binary files /dev/null and b/__pycache__/VendorClass.cpython-310.pyc differ diff --git a/__pycache__/VendorHistoryClass.cpython-310.pyc b/__pycache__/VendorHistoryClass.cpython-310.pyc new file mode 100644 index 0000000..69259a3 Binary files /dev/null and b/__pycache__/VendorHistoryClass.cpython-310.pyc differ diff --git a/__pycache__/VendorScreen.cpython-310.pyc b/__pycache__/VendorScreen.cpython-310.pyc index 0ecd73e..ae6d74c 100644 Binary files a/__pycache__/VendorScreen.cpython-310.pyc and b/__pycache__/VendorScreen.cpython-310.pyc differ diff --git a/__pycache__/ViewPurchaseClass.cpython-310.pyc b/__pycache__/ViewPurchaseClass.cpython-310.pyc new file mode 100644 index 0000000..cef492b Binary files /dev/null and b/__pycache__/ViewPurchaseClass.cpython-310.pyc differ diff --git a/__pycache__/ViewSaleClass.cpython-310.pyc b/__pycache__/ViewSaleClass.cpython-310.pyc new file mode 100644 index 0000000..1f2be25 Binary files /dev/null and b/__pycache__/ViewSaleClass.cpython-310.pyc differ diff --git a/connection.py b/connection.py deleted file mode 100644 index 0137960..0000000 --- a/connection.py +++ /dev/null @@ -1,162 +0,0 @@ -# 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 -import VendorScreen - -# server = 'localhost' -# 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() - -class EditVendorScreen(QtWidgets.QMainWindow): - def __init__(self): - super(EditVendorScreen, self).__init__() - uic.loadUi("Screens/EditVendors.ui", self) - - - -class AddVendorMessageBox(QMessageBox): - def __init__(self, message, title): - super().__init__() - - self.setIcon(QMessageBox.Icon.Information) - self.setText(message) - self.setWindowTitle(title) - self.addButton(QMessageBox.StandardButton.Close) - -class VendorScreen(QtWidgets.QMainWindow): - def __init__(self): - # Call the inherited classes __init__ method - super(VendorScreen, self).__init__() - - # Load the .ui file - uic.loadUi('Screens/Vendors.ui', self) - - self.PopulateVendorTable() - - self.addVendorButton.clicked.connect(self.AddVendor) - - self.editVendorButton.clicked.connect(self.EditVendor) - - - 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 AddVendor(self): - name = self.vendorNameBox.text() - contact = self.vendorContactNumber.text() - backupContact = self.vendorBackupContact.text() - email = self.vendorEmail.text() - address = self.vendorAddress.text() - - if name == '' or contact == '' or backupContact == '' or email == '' or address == '': - self.notAddedMsg = AddVendorMessageBox("Please enter complete information to add vendor", "Failed") - self.notAddedMsg.show() - else: - sql_query = "insert into vendor values(?, ?, ?, ?, ?)" - cursor.execute(sql_query, (name, contact, backupContact, email, address)) - connection.commit() - - self.addMsg = AddVendorMessageBox("Vendor added successfully", "Success") - self.addMsg.show() - - def EditVendor(self): - self.editVendor = EditVendorScreen() - self.editVendor.show() - - -class UI(QtWidgets.QMainWindow): - def __init__(self): - # Call the inherited classes __init__ method - super(UI, self).__init__() - - # Load the .ui file - uic.loadUi('Screens/UserAuthentication.ui', self) - self.password.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password) - - self.username.setPlaceholderText("Username") - self.password.setPlaceholderText("Password") - ###hardcoded for now, will later be enabled only if user has admin priveleges - - self.vendorsButton.setEnabled(False) - self.customerButton.setEnabled(False) - self.productsButton.setEnabled(False) - self.salesButton.setEnabled(False) - self.materialButton.setEnabled(False) - self.purchaseButton.setEnabled(False) - - self.loginButton.clicked.connect(self.CheckPrivilege) - self.vendorsButton.clicked.connect(self.OpenVendorScreen) - - - def OpenVendorScreen(self): - self.vendor = VendorScreen() - self.vendor.show() - - def CheckPrivilege(self): - username = self.username.text() - password = self.password.text() - sql_query = "select privilege from [User] where userName = ? and password = ?" - cursor.execute(sql_query, (username, password)) - result = cursor.fetchone() - if result is not None: - result = result[0] - if result == 'Admin': - self.vendorsButton.setEnabled(True) - self.customerButton.setEnabled(True) - self.productsButton.setEnabled(True) - self.salesButton.setEnabled(True) - self.materialButton.setEnabled(True) - self.purchaseButton.setEnabled(True) - elif result == 'User': - self.vendorsButton.setEnabled(False) - self.customerButton.setEnabled(False) - self.productsButton.setEnabled(False) - self.salesButton.setEnabled(True) - self.materialButton.setEnabled(False) - self.purchaseButton.setEnabled(False) - else: - self.addMsg = AddVendorMessageBox("Incorrect Username and/or Password", "Error") - self.addMsg.show() - self.vendorsButton.setEnabled(False) - self.customerButton.setEnabled(False) - self.productsButton.setEnabled(False) - self.salesButton.setEnabled(False) - self.materialButton.setEnabled(False) - self.purchaseButton.setEnabled(False) - - self.username.clear() - self.password.clear() - - - - -app = QApplication(sys.argv) -loginScreen = UI() -loginScreen.show() -sys.exit(app.exec()) diff --git a/main.py b/main.py new file mode 100644 index 0000000..f917ff2 --- /dev/null +++ b/main.py @@ -0,0 +1,252 @@ +# 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 +# import VendorClass +# import CustomerClass +# import MaterialClass +# import ProductsClass + +# from ConnectionString import connection, cursor + +# class UI(QtWidgets.QMainWindow): +# def __init__(self): +# # Call the inherited classes __init__ method +# super(UI, self).__init__() + +# # Load the .ui file +# uic.loadUi('Screens/UserAuthentication.ui', self) +# self.password.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password) + +# self.username.setPlaceholderText("Username") +# self.password.setPlaceholderText("Password") + +# self.vendorsButton.setEnabled(False) +# self.customerButton.setEnabled(False) +# self.productsButton.setEnabled(False) +# self.salesButton.setEnabled(False) +# self.materialButton.setEnabled(False) +# self.purchaseButton.setEnabled(False) +# self.logoutButton.setEnabled(False) + +# self.loginButton.clicked.connect(self.CheckPrivilege) +# self.vendorsButton.clicked.connect(self.OpenVendorScreen) +# self.customerButton.clicked.connect(self.OpenCustomerScreen) +# self.logoutButton.clicked.connect(self.Logout) + +# self.logged_in = False + +# self.productsButton.clicked.connect(self.OpenProductsScreen) +# self.materialButton.clicked.connect(self.OpenMaterialScreen) + +# def OpenProductsScreen(self): +# self.products = ProductsClass.ProductScreen() +# self.products.show() + +# def OpenMaterialScreen(self): +# self.materials = MaterialClass.MaterialScreen() +# self.materials.show() + +# def OpenCustomerScreen(self): +# self.customer = CustomerClass.CustomerScreen() +# self.customer.show() + +# def OpenVendorScreen(self): +# self.vendor = VendorClass.VendorScreen() +# self.vendor.show() + +# def CheckPrivilege(self): +# username = self.username.text() +# password = self.password.text() +# sql_query = "select privilege from [User] where userName = ? and password = ?" +# cursor.execute(sql_query, (username, password)) +# result = cursor.fetchone() +# if result is not None: +# result = result[0] +# if result == 'Admin': +# self.vendorsButton.setEnabled(True) +# self.customerButton.setEnabled(True) +# self.productsButton.setEnabled(True) +# self.salesButton.setEnabled(True) +# self.materialButton.setEnabled(True) +# self.purchaseButton.setEnabled(True) +# elif result == 'User': +# self.vendorsButton.setEnabled(False) +# self.customerButton.setEnabled(False) +# self.productsButton.setEnabled(False) +# self.salesButton.setEnabled(True) +# self.materialButton.setEnabled(False) +# self.purchaseButton.setEnabled(False) +# self.logged_in = True +# self.logoutButton.setEnabled(True) +# self.loginButton.setEnabled(False) + +# else: +# self.addMsg = QtWidgets.QMessageBox() +# self.addMsg.setWindowTitle('Error') +# self.addMsg.setText('Invalid credentials') +# self.addMsg.show() +# self.vendorsButton.setEnabled(False) +# self.customerButton.setEnabled(False) +# self.productsButton.setEnabled(False) +# self.salesButton.setEnabled(False) +# self.materialButton.setEnabled(False) +# self.purchaseButton.setEnabled(False) + +# self.username.clear() +# self.password.clear() +# self.setFocus(QtCore.Qt.FocusReason.OtherFocusReason) # So that the cursor does not go the password entry + +# def Logout(self): +# self.vendorsButton.setEnabled(False) +# self.customerButton.setEnabled(False) +# self.productsButton.setEnabled(False) +# self.salesButton.setEnabled(False) +# self.materialButton.setEnabled(False) +# self.purchaseButton.setEnabled(False) +# self.logoutButton.setEnabled(False) +# self.logged_in = False +# self.logoutButton.setEnabled(False) +# self.loginButton.setEnabled(True) +# self.setFocus(QtCore.Qt.FocusReason.OtherFocusReason) # So that the cursor does not go the password entry + +# app = QApplication(sys.argv) +# loginScreen = UI() +# loginScreen.show() +# sys.exit(app.exec()) + + +# 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 +import VendorClass +import ProductsClass +import MaterialClass +import EditVendorClass +import CustomerClass +from PurchaseClass import PurchaseScreen +import SaleClass + +from ConnectionString import connection, cursor + +class UI(QtWidgets.QMainWindow): + def __init__(self): + # Call the inherited classes __init__ method + super(UI, self).__init__() + + # Load the .ui file + uic.loadUi('Screens/UserAuthentication.ui', self) + self.password.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password) + + self.username.setPlaceholderText("Username") + self.password.setPlaceholderText("Password") + ###hardcoded for now, will later be enabled only if user has admin priveleges + + self.vendorsButton.setEnabled(False) + self.customerButton.setEnabled(False) + self.productsButton.setEnabled(False) + self.salesButton.setEnabled(False) + self.materialButton.setEnabled(False) + self.purchaseButton.setEnabled(False) + self.logoutButton.setEnabled(False) + + self.loginButton.clicked.connect(self.CheckPrivilege) + self.vendorsButton.clicked.connect(self.OpenVendorScreen) + self.productsButton.clicked.connect(self.OpenProductsScreen) + self.materialButton.clicked.connect(self.OpenMaterialScreen) + self.customerButton.clicked.connect(self.OpenCustomerScreen) + self.purchaseButton.clicked.connect(self.OpenPurchaseScreen) + self.salesButton.clicked.connect(self.OpenSaleScreen) + self.logoutButton.clicked.connect(self.Logout) + + self.logged_in = False + + def OpenPurchaseScreen(self): + self.purchase = PurchaseScreen() + self.purchase.show() + + def OpenProductsScreen(self): + self.products = ProductsClass.ProductScreen() + self.products.show() + + def OpenSaleScreen(self): + self.sales = SaleClass.SaleScreen() + self.sales.show() + + def OpenMaterialScreen(self): + self.materials = MaterialClass.MaterialScreen() + self.materials.show() + + def OpenVendorScreen(self): + self.vendor = VendorClass.VendorScreen() + self.vendor.show() + + def OpenCustomerScreen(self): + self.customer = CustomerClass.CustomerScreen() + self.customer.show() + + def CheckPrivilege(self): + username = self.username.text() + password = self.password.text() + sql_query = "select privilege from [User] where userName = ? and password = ?" + cursor.execute(sql_query, (username, password)) + result = cursor.fetchone() + if result is not None: + result = result[0] + if result == 'Admin': + self.vendorsButton.setEnabled(True) + self.customerButton.setEnabled(True) + self.productsButton.setEnabled(True) + self.salesButton.setEnabled(True) + self.materialButton.setEnabled(True) + self.purchaseButton.setEnabled(True) + elif result == 'User': + self.vendorsButton.setEnabled(False) + self.customerButton.setEnabled(False) + self.productsButton.setEnabled(False) + self.salesButton.setEnabled(True) + self.materialButton.setEnabled(False) + self.purchaseButton.setEnabled(False) + self.logged_in = True + self.logoutButton.setEnabled(True) + self.loginButton.setEnabled(False) + + else: + self.addMsg = QtWidgets.QMessageBox() + self.addMsg.setWindowTitle('Error') + self.addMsg.setText('Invalid credentials') + self.addMsg.show() + self.vendorsButton.setEnabled(False) + self.customerButton.setEnabled(False) + self.productsButton.setEnabled(False) + self.salesButton.setEnabled(False) + self.materialButton.setEnabled(False) + self.purchaseButton.setEnabled(False) + + self.username.clear() + self.password.clear() + self.setFocus(QtCore.Qt.FocusReason.OtherFocusReason) # So that the cursor does not go the password entry + + def Logout(self): + self.vendorsButton.setEnabled(False) + self.customerButton.setEnabled(False) + self.productsButton.setEnabled(False) + self.salesButton.setEnabled(False) + self.materialButton.setEnabled(False) + self.purchaseButton.setEnabled(False) + self.logoutButton.setEnabled(False) + self.logged_in = False + self.logoutButton.setEnabled(False) + self.loginButton.setEnabled(True) + self.setFocus(QtCore.Qt.FocusReason.OtherFocusReason) # So that the cursor does not go the password entry + +app = QApplication(sys.argv) +loginScreen = UI() +loginScreen.show() +sys.exit(app.exec()) \ No newline at end of file