From be4157c4c65f01ab896c1cdae7f86806770a7dcf Mon Sep 17 00:00:00 2001 From: morris-glyndwr <45186370+morris-glyndwr@users.noreply.github.com> Date: Wed, 15 May 2019 14:09:38 -0600 Subject: [PATCH] Added program files --- Email Templates/emailTemplate.html | 65 + Email Templates/online_payment_request.html | 7 + .../special_order_backordered.html | 9 + .../special_order_not_available.html | 7 + Email Templates/special_order_ordered.html | 8 + Email Templates/special_order_recieved.html | 7 + Installer Scripts/linux_install.sh | 2 + Installer Scripts/win_install.bat | 1 + config.py | 67 + gui.py | 1692 +++++++++++++++++ main.py | 42 + sendemail.py | 84 + sql.py | 440 +++++ 13 files changed, 2431 insertions(+) create mode 100644 Email Templates/emailTemplate.html create mode 100644 Email Templates/online_payment_request.html create mode 100644 Email Templates/special_order_backordered.html create mode 100644 Email Templates/special_order_not_available.html create mode 100644 Email Templates/special_order_ordered.html create mode 100644 Email Templates/special_order_recieved.html create mode 100644 Installer Scripts/linux_install.sh create mode 100644 Installer Scripts/win_install.bat create mode 100644 config.py create mode 100644 gui.py create mode 100644 main.py create mode 100644 sendemail.py create mode 100644 sql.py diff --git a/Email Templates/emailTemplate.html b/Email Templates/emailTemplate.html new file mode 100644 index 0000000..5830bb2 --- /dev/null +++ b/Email Templates/emailTemplate.html @@ -0,0 +1,65 @@ + + + + +Revolution Cycle + + +
+ + +
+
+

Revolution Cycle

+ + + + + + + + + + +
+ + + +
+

Online Payment Request

+
+ +
+ + + +
+ + + +
+
+

Hey There [CUSTOMER FIRST NAME]!

+

+
+
+ +
+ +
+ + + + + +
+
+
+ + \ No newline at end of file diff --git a/Email Templates/online_payment_request.html b/Email Templates/online_payment_request.html new file mode 100644 index 0000000..4e3defc --- /dev/null +++ b/Email Templates/online_payment_request.html @@ -0,0 +1,7 @@ + +[CUSTOMER FIRST NAME] +[PRODUCT NAME HERE] +[PRODUCT LINK] +[SALESPERSON] \ No newline at end of file diff --git a/Email Templates/special_order_backordered.html b/Email Templates/special_order_backordered.html new file mode 100644 index 0000000..9b6ab4f --- /dev/null +++ b/Email Templates/special_order_backordered.html @@ -0,0 +1,9 @@ + +[CUSTOMER FIRST NAME] +[PRODUCT NAME HERE] +[ORDER NUMBER], +[BACKORDER ETA] +[ETA] +[SALESPERSON] \ No newline at end of file diff --git a/Email Templates/special_order_not_available.html b/Email Templates/special_order_not_available.html new file mode 100644 index 0000000..26444df --- /dev/null +++ b/Email Templates/special_order_not_available.html @@ -0,0 +1,7 @@ + +[CUSTOMER FIRST NAME] +[PRODUCT NAME HERE] +[ORDER NUMBER] +[SALESPERSON] diff --git a/Email Templates/special_order_ordered.html b/Email Templates/special_order_ordered.html new file mode 100644 index 0000000..e9748ad --- /dev/null +++ b/Email Templates/special_order_ordered.html @@ -0,0 +1,8 @@ + +[CUSTOMER FIRST NAME] +[PRODUCT NAME HERE] +[ORDER NUMBER] +[ETA] +[SALESPERSON] diff --git a/Email Templates/special_order_recieved.html b/Email Templates/special_order_recieved.html new file mode 100644 index 0000000..a42a905 --- /dev/null +++ b/Email Templates/special_order_recieved.html @@ -0,0 +1,7 @@ + +[CUSTOMER FIRST NAME] +[PRODUCT NAME HERE] +[ORDER NUMBER] +[SALESPERSON] \ No newline at end of file diff --git a/Installer Scripts/linux_install.sh b/Installer Scripts/linux_install.sh new file mode 100644 index 0000000..fd5f5f9 --- /dev/null +++ b/Installer Scripts/linux_install.sh @@ -0,0 +1,2 @@ +apt-get install python3 +pip install mysql-connector-python PyQt3 woocommerce \ No newline at end of file diff --git a/Installer Scripts/win_install.bat b/Installer Scripts/win_install.bat new file mode 100644 index 0000000..ecd94fa --- /dev/null +++ b/Installer Scripts/win_install.bat @@ -0,0 +1 @@ +py -m pip install mysql-connector-python PyQt5 woocommerce validate_email py3DNS diff --git a/config.py b/config.py new file mode 100644 index 0000000..5b19bbc --- /dev/null +++ b/config.py @@ -0,0 +1,67 @@ +from datetime import date + +versionNumber = "v0.1.11" + +sqlConfig = { + 'user':'', + 'password':'', + 'host':'', + 'database':'' +} + +wcAPIConfig = { + 'url':"", + 'consumer_key':"", + 'consumer_secret':"", + 'wp_api':False, + 'version':"" +} + +wcAPILegacyConfig = { + 'url':"", + 'consumer_key':"", + 'consumer_secret':"", + 'wp_api':True, + 'version':"", + 'verify_ssl':True, + 'timeout':30, +} + +emailConfig = { + 'username':'', + 'password':'', +} + +orderTemplate = { + 'customerFirstName':'Foo', #Type TEXT + 'customerLastName':'Bar', #Type TEXT + 'customerPhoneNo':1234567890, #Type BIGINT + 'customerEmail' :'foo@bar.com', #Type TEXT + 'productDesc' :'Foo Bar', #Type TEXT + 'productPartNo' :'42069-01', #Type TEXT + 'productSupplier' :'ACME', #Type TEXT + 'dateRequested' :date(2018,11,26), #Type DATE + 'dateOrdered' :date(2018,11,26), #Type DATE + 'orderID' :65902, #Type BIGINT + 'orderStatus' :0, #Type TINYINT + 'orderDesc' :'ACME part for Foo Bar', #Type Text + 'paymentStatus' :1, #Type TINTINT + 'isWorkOrder' :False, #Type BOOLEAN + 'salesRep':'John Doe', #Type TEXT + 'objectID':0, #Type INT + 'price':123456.78, #Type FLOAT + 'weight':35, #Type INT + 'dimLength': 55, #Type INT + 'dimWidth':9, #Type INT + 'dimHeight':33, #Type INT +} + +staffMembers = [ + '--Choose One--', + '', +] + +suppliers = [ + '--Choose One--', + '', +] \ No newline at end of file diff --git a/gui.py b/gui.py new file mode 100644 index 0000000..f8c17d3 --- /dev/null +++ b/gui.py @@ -0,0 +1,1692 @@ +import sys +from time import sleep +from pprint import * +from woocommerce import * +from sql import * +from sendemail import * + +from PyQt5 import QtWidgets, QtGui +from PyQt5.QtWidgets import * +from PyQt5.QtGui import QIcon, QFont, QStandardItemModel, QStandardItem, QColor, QBrush, QStaticText +from PyQt5.QtCore import (QDate, QDateTime, QRegExp, QSortFilterProxyModel, Qt, QTime) + +from sql import * + +class mainWindow(QMainWindow): + def __init__(self): + super().__init__() + self.initUI() + + def initUI(self): + #Setting up the menu bar + menubar=self.menuBar() + self.statusBar = QStatusBar() + self.theWindowArea = mainWindowArea(self) + self.buttonBox = QDialogButtonBox() + self.groupBox = QWidget() + self.inner = QVBoxLayout() + + #File Menu Operations + #Object Declarations + fileMenu = menubar.addMenu('File') + newMenu = QMenu('New', self) + newSpecOrd = QAction('Special Order', self) + newWarClaim = QAction('Warranty Claims', self) + newOnOrd = QAction('Payment Request', self) + newProdInfoReq = QAction('Product Info Request', self) + refresh = QAction('Refresh', self) + exit = QAction('Exit', self) + + #Trigger Action Assignments + exit.triggered.connect(self.close) + refresh.triggered.connect(self.reloadOrders) + + #Add objects to menus + newMenu.addAction(newSpecOrd) + newMenu.addAction(newWarClaim) + newMenu.addAction(newOnOrd) + newMenu.addAction(newProdInfoReq) + newSpecOrd.triggered.connect(self.theWindowArea.createSpecialOrder) + newWarClaim.triggered.connect(self.createWarrantyClaim) + newOnOrd.triggered.connect(self.createOnlineOrder) + newProdInfoReq.triggered.connect(self.theWindowArea.createInfoRequest) + fileMenu.addMenu(newMenu) + fileMenu.addAction(refresh) + fileMenu.addAction(exit) + + #Edit Menu Operations + #Object Declarations + editMenu = menubar.addMenu('Edit') + editSelected = QAction('Selected Order...', self) + editPrefrences = QAction('Prefrences', self) + editSettings = QAction('Settings', self) + + #Add objects to menus + editMenu.addAction(editSelected) + editMenu.addAction(editPrefrences) + editMenu.addAction(editSettings) + + #Trigger Action Assignments + editSelected.triggered.connect(self.theWindowArea.editSpecialOrder) + editPrefrences.triggered.connect(self.prefrencesWindow) + editSettings.triggered.connect(self.settingsWindow) + + #Help Menu Operations + #Object Declarations + helpMenu = menubar.addMenu('Help') + helpAbout = QAction('About', self) + + #Trigger Action Assignments + helpAbout.triggered.connect(self.aboutDialog) + + #Add objects to menus + helpMenu.addAction(helpAbout) + + #Draw the window + create = self.buttonBox.addButton(QDialogButtonBox.Ok) + edit = self.buttonBox.addButton(QDialogButtonBox.Cancel) + delete = self.buttonBox.addButton(QDialogButtonBox.Ok) + + create.setText('Create') + edit.setText('Edit') + delete.setText('Delete') + + create.clicked.connect(self.theWindowArea.createSpecialOrder) + edit.clicked.connect(self.theWindowArea.editSpecialOrder) + delete.clicked.connect(self.theWindowArea.delete) + + self.setGeometry(300, 300, 800, 600) + self.setWindowTitle('Order Manager '+versionNumber) + self.setWindowIcon(QIcon('web.png')) + self.inner.addWidget(self.theWindowArea) + self.inner.addWidget(self.buttonBox) + self.groupBox.setLayout(self.inner) + self.setCentralWidget(self.groupBox) + #self.setStatusBar(self.statusBar) + + self.statusBar.showMessage('Status: Online') + + self.show() + self.w = None + + def reloadOrders(self): + print('Refreshing Orders') + self.theWindowArea.tableWidgetSO.clear() + self.theWindowArea.tableWidgetWC.clear() + self.statusBar.showMessage('Status: Loading Orders') + self.theWindowArea.addOrdersLoop() + self.theWindowArea.addClaimsLoop() + self.statusBar.showMessage('Status: Online') + print('Orders Refreshed') + return + + def aboutDialog(self): + about = QMessageBox.about(self, 'About', "ORDER MANAGER "+versionNumber+ + "\nDeveloped by Glyndwr Morris" + "\n" + "\nOrder Manager relies on these technologies:" + "\n-Python 3" + "\n-Qt 5" + "\n-MySQL" + "\n" + "\n(C) Glyndwr Morris 2017 All rights reserved") + + def prefrencesWindow(self): + about = QMessageBox.about(self, 'Prefrences', "Coming Soon! :)") + return + + def settingsWindow(self): + self.w=newOrderWindow() + + self.user = QLineEdit() + self.user.setText(sqlConfig['user']) + self.pword = QLineEdit() + self.pword.setText(sqlConfig['password']) + self.pword.setEchoMode(QLineEdit.Password) + self.host = QLineEdit() + self.host.setText(sqlConfig['host']) + self.dataBase = QLineEdit() + self.dataBase.setText(sqlConfig['database']) + self.title1 = QLabel('Database Connection Settings:') + self.title2 = QLabel('WooCommerce Connection Settings:') + + self.wLayout = QFormLayout() + self.wLayout.addRow(self.title1) + self.wLayout.addRow('Username:', self.user) + self.wLayout.addRow('Password:', self.pword) + self.wLayout.addRow('Host:', self.host) + self.wLayout.addRow('Database:', self.dataBase) + self.wLayout.addRow(self.title2) + + self.w.setGeometry(500, 400, 400, 300) + self.w.setWindowTitle('Settings') + self.w.setLayout(self.wLayout) + + self.w.show() + return + + def createWarrantyClaim(self): + self.w = newOrderWindow() + self.w.setGeometry(500, 400, 400, 400) + self.w.setWindowTitle('New Warranty Claim') + self.w.show() + return + + def createOnlineOrder(self): + self.w = newOrderWindow() + + self.custFirstName = QLineEdit() + self.custLastName = QLineEdit() + self.custPhoneNumber = QLineEdit() + self.custEmail = QLineEdit() + self.layawayNumber = QLineEdit() + self.layawaySubtotal = QLineEdit() + self.productName = QLineEdit() + self.salesRep = QComboBox() + self.sendOrder = QPushButton("Send") + self.cancelCreation = QPushButton("Cancel") + + self.salesRep.addItems(staffMembers) + self.wButtons = QHBoxLayout() + self.wProgLayout = QVBoxLayout() + self.wLayout = QFormLayout() + self.wLayout.addRow("Fist Name", self.custFirstName) + self.wLayout.addRow("Last Name", self.custLastName) + self.wLayout.addRow("Phone Number", self.custPhoneNumber) + self.wLayout.addRow("E-Mail Address", self.custEmail) + self.wLayout.addRow("Product Name", self.productName) + self.wLayout.addRow("Layaway/Work Order Number", self.layawayNumber) + self.wLayout.addRow("Layaway Total (Before Tax)", self.layawaySubtotal) + self.wLayout.addRow("Staff Name", self.salesRep) + self.wButtons.addWidget(self.sendOrder) + self.wButtons.addWidget(self.cancelCreation) + + self.progress = QProgressBar() + self.progressLabel = QLabel() + self.progress.setMinimum(0) + self.progress.setMaximum(100) + self.progress.setTextVisible(True) + self.wProgLayout.addWidget(self.progressLabel) + self.wProgLayout.addWidget(self.progress) + + self.wLayout.addRow(self.wProgLayout) + self.wLayout.addRow(self.wButtons) + + + self.w.setGeometry(500, 400, 400, 300) + self.w.setWindowTitle('Send Payment Request') + self.w.setLayout(self.wLayout) + + self.w.show() + self.sendOrder.clicked.connect(self.sendRequest) + self.cancelCreation.clicked.connect(self.w.close) + return + + def editWarrantyClaim(self): + self.w = newOrderWindow() + self.w.setGeometry(500, 400, 400, 400) + self.w.setWindowTitle('Edit Warranty Claim') + self.w.show() + return + + def editOnlineOrder(self): + self.w = newOrderWindow() + self.w.setGeometry(500, 400, 400, 400) + self.w.setWindowTitle('Edit Online Order') + self.w.show() + return + + def editSpecialOrder(self): + self.w = newOrderWindow() + self.w.setGeometry(500, 400, 400, 400) + self.w.setWindowTitle('Edit Special Order') + self.w.show() + return + + def createWooProduct(self, first_name, last_name, layaway, total, weight='', length='', width='', height=''): + #Connecting to the Woo Commerce REST API + wcapi = API( + url=wcAPILegacyConfig['url'], + consumer_key=wcAPILegacyConfig['consumer_key'], + consumer_secret=wcAPILegacyConfig['consumer_secret'], + wp_api=wcAPILegacyConfig['wp_api'], + version=wcAPILegacyConfig['version'], + verify_ssl=wcAPILegacyConfig['verify_ssl'], + timeout=wcAPILegacyConfig['timeout'], + ) + + check = wcapi.get('products?sku='+layaway).json() + + if check == 0: + data = { + "name": "Online Payment - "+layaway, + "catalog_visibility": "visible", + "type": "simple", + "price": total, + "regular_price": total, + "manage_stock": True, + "stock_quantity": 1, + "in_stock": True, + "sku":layaway, + "description": "Online Payment for Special Order #"+layaway, + "weight": weight, + "dimensions": { + "length": length, + "width": width, + "height": height + }, + "purchasable": True, + "images": [{ + "src": "https://www.revolutioncycle.com/wp-content/uploads/2015/06/Online-purchase-template1.jpg", + "position": 0 + }] + } + return wcapi.post("products", data).json()['permalink'] + else: + return check[0]['permalink'] + + def sendRequest(self): + self.progress.show() + self.progressLabel.show() + self.progressLabel.setText('Building/Re-Sending Online Payment') + self.progress.setValue(33) + + self.data = { + 'firstName':self.custFirstName.text(), + 'lastName':self.custLastName.text(), + 'email':self.custEmail.text(), + 'product':self.productName.text(), + 'link':self.theWindowArea.createWooProduct( + self.custFirstName.text(), + self.custLastName.text(), + self.layawayNumber.text(), + self.layawaySubtotal.text() + ), + 'salesperson':self.salesRep.currentText(), + 'orderNo':self.layawayNumber.text(), + 'backETA':'idk', + 'shipETA':'idk', + } + print(self.data) + sendEmail('request', self.data) + self.w.close() + return + +class mainWindowArea(QWidget): + def __init__(self, parent): + super(QWidget, self).__init__(parent) + self.layout = QVBoxLayout(self) + + # Initialize tab screen + self.search = QLineEdit() + self.search.setPlaceholderText('[Press Enter to Search] First and Last name, ' + 'Phone Number, Email, Product, Part Number, or Order Notes.') + self.search.returnPressed.connect(self.searchOrders) + self.search.setDisabled(False) + self.searchArea=QFormLayout() + self.searchArea.addRow('Search:', self.search) + self.tabs = QTabWidget() + self.tab1 = QWidget() + self.tab2 = QWidget() + self.tab3 = QWidget() + self.tabs.resize(300,200) + self.tabs.addTab(self.tab3,"Special Orders") + self.tabs.addTab(self.tab1,"Online Orders") + self.tabs.addTab(self.tab2,"Warranty Claims") + + # Build Online Order Tab. + #Widget declaration + self.tab1.layout = QVBoxLayout(self) + self.tab1Splitter = QSplitter() + self.tableWidgetOO = QTreeWidget() + self.tableWidgetOO2 = QTreeWidget() + self.headerListOO = ['First Name', + 'Last Name','Phone Number','Email','Product Name','Quantity', + 'Price','UPC','Date Requested','Date Ordered','Order Number', + 'Order Status','Price','Payment Status', + 'Order Type','Sales Rep'] + self.tableWidgetOO.setHeaderLabels(self.headerListOO) + self.tableWidgetOO2.setHeaderLabels(self.headerListOO) + self.tableWidgetOO.setSortingEnabled(True) + self.tableWidgetOO2.setSortingEnabled(True) + + self.addOnlineLoop() + + self.tab1Splitter.addWidget(self.tableWidgetOO) + self.tab1Splitter.addWidget(self.tableWidgetOO2) + self.tab1Splitter.setOrientation(Qt.Vertical) + self.tab1Splitter.setCollapsible(0,False) + self.tab1Splitter.setCollapsible(1,False) + self.tab1Splitter.setSizes([400,400]) + self.tab1.layout.addWidget(self.tab1Splitter) + self.tab1.setLayout(self.tab1.layout) + + # Build Warranty Claim Tab. + self.tab2.layout = QVBoxLayout(self) + self.tab2Splitter = QSplitter() + self.tableWidgetWC = QTreeWidget() + self.headerListWC = ['First Name', + 'Last Name','Phone Number','Email','Product Name','Part Number', + 'Supplier','Date Requested','Date Ordered','Order Number', + 'Order Status','Price','Payment Status', + 'Order Type','Sales Rep'] + self.tableWidgetWC.setHeaderLabels(self.headerListWC) + self.tableWidgetWC.setSortingEnabled(True) + + self.addClaimsLoop() + + #self.tableWidgetSO.itemDoubleClicked.connect(self.editSpecialOrder) + + #self.deleteSOButton.clicked.connect(self.delete) + #self.addSOButton.clicked.connect(self.createSpecialOrder) + #self.editSOButton.clicked.connect(self.editSpecialOrder) + + #Widget Organization + self.tab2Splitter.addWidget(self.tableWidgetWC) + self.notesSectionWC = QTextEdit() + self.notesSectionWC.setReadOnly(True) + + self.tab2Splitter.addWidget(self.notesSectionWC) + self.tab2Splitter.setOrientation(Qt.Vertical) + self.tab2Splitter.setCollapsible(0,False) + self.tab2Splitter.setCollapsible(1,False) + self.tab2Splitter.setSizes([400,20]) + self.tab2.layout.addWidget(self.tab2Splitter) + self.tab2.setLayout(self.tab2.layout) + + print('Reading claim entrys from database') + self.layout.addWidget(self.tabs) + self.setLayout(self.layout) + #self.tableWidgetSO.itemClicked.connect(self.setNotesSection) + + # Build Special Order Tab. + self.tab3.layout = QVBoxLayout(self) + self.tab3Splitter = QSplitter() + self.addSOButton = QPushButton("Create") + self.editSOButton = QPushButton("Edit") + self.deleteSOButton = QPushButton("Delete") + self.tableWidgetSO = QTreeWidget() + self.headerListSO = ['First Name', + 'Last Name','Phone Number','Email','Product Name','Part Number', + 'Supplier','Date Requested','Date Ordered','Order Number', + 'Order Status','Price','Payment Status', + 'Order Type','Sales Rep'] + self.tableWidgetSO.setHeaderLabels(self.headerListSO) + self.tableWidgetSO.setSortingEnabled(True) + + self.addOrdersLoop() + + self.tableWidgetSO.itemDoubleClicked.connect(self.editSpecialOrder) + + self.deleteSOButton.clicked.connect(self.delete) + self.addSOButton.clicked.connect(self.createSpecialOrder) + self.editSOButton.clicked.connect(self.editSpecialOrder) + + #Widget Organization + self.tab3Splitter.addWidget(self.tableWidgetSO) + self.notesSectionSO = QTextEdit() + self.notesSectionSO.setReadOnly(True) + + self.tab3Splitter.addWidget(self.notesSectionSO) + self.tab3Splitter.setOrientation(Qt.Vertical) + self.tab3Splitter.setCollapsible(0,False) + self.tab3Splitter.setCollapsible(1,False) + self.tab3Splitter.setSizes([400,20]) + self.tab3.layout.addWidget(self.tab3Splitter) + self.tab3.setLayout(self.tab3.layout) + + # Finish up everything and present. + print('Reading order entrys from database') + self.layout.addLayout(self.searchArea) + self.layout.addWidget(self.tabs) + self.setLayout(self.layout) + self.tableWidgetSO.itemClicked.connect(self.setNotesSection) + + +# Order Realted Functions + def addOrdersLoop(self): + self.orderList = [] + self.objectIDs = {} + matrixOrders = {} + matrixParents = {} + self.orderStatus = ['Requested','Order Placed','Order Recieved', + 'Backordered','Not Available', 'Info Requested', 'Insuffecient Information'] + self.paymentStatus = ['Pending Payment','Partially Paid','Fully Paid'] + + specialOrders = fetchOrders() #fetchOrders[x][9] is the Layaway Number + importantFont = QFont() + + for stuff in specialOrders: + if stuff[9] in matrixOrders: + matrixOrders[stuff[9]].append(stuff[15]) + else: + matrixOrders[stuff[9]] = [stuff[15]] + + for obj in matrixOrders: + if len(matrixOrders[obj]) > 1: + matrixParents[obj] = QTreeWidgetItem() + self.tableWidgetSO.addTopLevelItem(matrixParents[obj]) + matrixParents[obj].setText(4, 'Multi-part Order') + for i in range(15): + matrixParents[obj].setBackground(i,QColor(255, 255, 150)) + + j=0 + for item in specialOrders: + if self.orderStatus[item[10]] == 'Requested' or self.orderStatus[item[10]] == 'Info Requested': + importantFont.setBold(True) + else: + importantFont.setBold(False) + + if len(matrixOrders[item[9]]) > 1: + + #Scan array to see if there are any entries for this is objectIDs + + #if there isnt, we need to make a new QTreeWidgetItem and add an + #an order as a child + + #if there is, we add the order as a child to the existing QTreeWidgetItem + + self.orderList.append(QTreeWidgetItem()) + matrixParents[item[9]].addChild(self.orderList[len(self.orderList)-1]) + matrixParents[item[9]].setText(0, str(item[0])) + matrixParents[item[9]].setFont(0, importantFont) + matrixParents[item[9]].setText(1, str(item[1])) + matrixParents[item[9]].setFont(1, importantFont) + matrixParents[item[9]].setText(2, self.parsePhoneNumber(str(item[2]))) + matrixParents[item[9]].setFont(2, importantFont) + matrixParents[item[9]].setText(3, str(item[3])) + matrixParents[item[9]].setFont(3, importantFont) + matrixParents[item[9]].setFont(4, importantFont) + matrixParents[item[9]].setText(9, str(item[9])) + matrixParents[item[9]].setFont(9, importantFont) + if item[13] == 1: + matrixParents[item[9]].setText(13, "Workorder") + matrixParents[item[9]].setForeground(13,QColor("Blue")) + matrixParents[item[9]].setFont(13, importantFont) + else: + matrixParents[item[9]].setText(13, "Layaway") + matrixParents[item[9]].setForeground(13,QColor("Green")) + matrixParents[item[9]].setFont(13, importantFont) + + self.objectIDs[j] = item[15] + #First Name Column + self.orderList[j].setText(0, str(item[0])) + self.orderList[j].setFont(0, importantFont) + #Last Name Column + self.orderList[j].setText(1, str(item[1])) + self.orderList[j].setBackground(1,QColor("lightGray")) + self.orderList[j].setFont(1, importantFont) + #Phone Column + self.orderList[j].setText(2, self.parsePhoneNumber(str(item[2]))) + self.orderList[j].setFont(2, importantFont) + #Email Column + self.orderList[j].setText(3, str(item[3])) + self.orderList[j].setBackground(3,QColor("lightGray")) + self.orderList[j].setFont(3, importantFont) + #Things + self.orderList[j].setText(4, str(item[4])) + self.orderList[j].setFont(4, importantFont) + #Things + self.orderList[j].setText(5, str(item[5])) + self.orderList[j].setBackground(5,QColor("lightGray")) + self.orderList[j].setFont(5, importantFont) + #Things + self.orderList[j].setText(6, str(item[6])) + self.orderList[j].setFont(6, importantFont) + #Things + self.orderList[j].setText(7, str(item[7])) + self.orderList[j].setBackground(7,QColor("lightGray")) + self.orderList[j].setFont(7, importantFont) + #Date Ordered + if self.orderStatus[item[10]] == 'Requested': + self.orderList[j].setText(8, '') + elif item[8] == None: + self.orderList[j].setText(8, '') + else: + self.orderList[j].setText(8, str(item[8])) + self.orderList[j].setFont(8, importantFont) + #Things + self.orderList[j].setText(9, str(item[9])) + self.orderList[j].setBackground(9,QColor("lightGray")) + self.orderList[j].setFont(9, importantFont) + #Order Status Column + self.orderList[j].setText(10, self.orderStatus[item[10]]) + self.orderList[j].setFont(10, importantFont) + #Order Status Column + self.orderList[j].setText(11, str(round(item[16], 3))) + self.orderList[j].setBackground(11,QColor("lightGray")) + self.orderList[j].setFont(11, importantFont) + #Payment Status Colum + self.orderList[j].setText(12, self.paymentStatus[item[12]]) + self.orderList[j].setFont(12, importantFont) + #Order Type Column + if item[13] == 1: + self.orderList[j].setText(13, "Workorder") + self.orderList[j].setForeground(13,QColor("Blue")) + self.orderList[j].setBackground(13,QColor("lightGray")) + else: + self.orderList[j].setText(13, "Layaway") + self.orderList[j].setForeground(13,QColor("Green")) + self.orderList[j].setBackground(13,QColor("lightGray")) + self.orderList[j].setFont(13, importantFont) + #Things + self.orderList[j].setText(14, str(item[14])) + self.orderList[j].setFont(14, importantFont) + + self.tableWidgetSO.addTopLevelItem(self.orderList[j]) + + else: + self.orderList.append(QTreeWidgetItem()) + self.objectIDs[j] = item[15] + #First Name Column + self.orderList[j].setText(0, str(item[0])) + self.orderList[j].setFont(0, importantFont) + #Last Name Column + self.orderList[j].setText(1, str(item[1])) + self.orderList[j].setBackground(1,QColor("lightGray")) + self.orderList[j].setFont(1, importantFont) + #Phone Column + self.orderList[j].setText(2, self.parsePhoneNumber(str(item[2]))) + self.orderList[j].setFont(2, importantFont) + #Email Column + self.orderList[j].setText(3, str(item[3])) + self.orderList[j].setBackground(3,QColor("lightGray")) + self.orderList[j].setFont(3, importantFont) + #Things + self.orderList[j].setText(4, str(item[4])) + self.orderList[j].setFont(4, importantFont) + #Things + self.orderList[j].setText(5, str(item[5])) + self.orderList[j].setBackground(5,QColor("lightGray")) + self.orderList[j].setFont(5, importantFont) + #Things + self.orderList[j].setText(6, str(item[6])) + self.orderList[j].setFont(6, importantFont) + #Things + self.orderList[j].setText(7, str(item[7])) + self.orderList[j].setBackground(7,QColor("lightGray")) + self.orderList[j].setFont(7, importantFont) + #Date Ordered + if self.orderStatus[item[10]] == 'Requested': + self.orderList[j].setText(8, '') + elif item[8] == None: + self.orderList[j].setText(8, '') + else: + self.orderList[j].setText(8, str(item[8])) + self.orderList[j].setFont(8, importantFont) + #Things + self.orderList[j].setText(9, str(item[9])) + self.orderList[j].setBackground(9,QColor("lightGray")) + self.orderList[j].setFont(9, importantFont) + #Order Status Column + self.orderList[j].setText(10, self.orderStatus[item[10]]) + self.orderList[j].setFont(10, importantFont) + #Order Status Column + self.orderList[j].setText(11, str(round(item[16], 3))) + self.orderList[j].setBackground(11,QColor("lightGray")) + self.orderList[j].setFont(11, importantFont) + #Payment Status Colum + self.orderList[j].setText(12, self.paymentStatus[item[12]]) + self.orderList[j].setFont(12, importantFont) + #Order Type Column + if item[13] == 1: + self.orderList[j].setText(13, "Workorder") + self.orderList[j].setForeground(13,QColor("Blue")) + self.orderList[j].setBackground(13,QColor("lightGray")) + else: + self.orderList[j].setText(13, "Layaway") + self.orderList[j].setForeground(13,QColor("Green")) + self.orderList[j].setBackground(13,QColor("lightGray")) + self.orderList[j].setFont(13, importantFont) + #Things + self.orderList[j].setText(14, str(item[14])) + self.orderList[j].setFont(14, importantFont) + + self.tableWidgetSO.addTopLevelItem(self.orderList[j]) + + j+=1 + #print(self.objectIDs) + for i in range(len(self.headerListSO)): + self.tableWidgetSO.resizeColumnToContents(i) + + def searchedOrdersLoop(self): + self.orderList = [] + self.objectIDs = {} + matrixOrders = {} + matrixParents = {} + self.orderStatus = ['Requested','Order Placed','Order Recieved', + 'Backordered','Not Available', 'Info Requested', 'Insuffecient Information'] + self.paymentStatus = ['Pending Payment','Partially Paid','Fully Paid'] + + specialOrders = findOrder(self.search.text()) + importantFont = QFont() + + for stuff in specialOrders: + if stuff['orderID'] in matrixOrders: + matrixOrders[stuff['orderID']].append(stuff['orderID']) + else: + matrixOrders[stuff['orderID']] = [stuff['objectID']] + + for obj in matrixOrders: + if len(matrixOrders[obj]) > 1: + matrixParents[obj] = QTreeWidgetItem() + self.tableWidgetSO.addTopLevelItem(matrixParents[obj]) + matrixParents[obj].setText(4, 'Multi-part Order') + for i in range(15): + matrixParents[obj].setBackground(i,QColor(255, 255, 150)) + + j=0 + for item in specialOrders: + if self.orderStatus[item['orderStatus']] == 'Requested' or \ + self.orderStatus[item['orderStatus']] == 'Info Requested': + importantFont.setBold(True) + else: + importantFont.setBold(False) + + if len(matrixOrders[item['orderID']]) > 1: + + #Scan array to see if there are any entries for this is objectIDs + + #if there isnt, we need to make a new QTreeWidgetItem and add an + #an order as a child + + #if there is, we add the order as a child to the existing QTreeWidgetItem + + self.orderList.append(QTreeWidgetItem()) + matrixParents[item['orderID']].addChild(self.orderList[len(self.orderList)-1]) + matrixParents[item['orderID']].setText(0, str(item['customerFirstName'])) + matrixParents[item['orderID']].setFont(0, importantFont) + matrixParents[item['orderID']].setText(1, str(item['customerLastName'])) + matrixParents[item['orderID']].setFont(1, importantFont) + matrixParents[item['orderID']].setText(2, self.parsePhoneNumber(str(item['customerPhoneNo']))) + matrixParents[item['orderID']].setFont(2, importantFont) + matrixParents[item['orderID']].setText(3, str(item['customerEmail'])) + matrixParents[item['orderID']].setFont(3, importantFont) + matrixParents[item['orderID']].setFont(4, importantFont) + matrixParents[item['orderID']].setText(9, str(item['orderID'])) + matrixParents[item['orderID']].setFont(9, importantFont) + if item['isWorkOrder'] == 1: + matrixParents[item['orderID']].setText(13, "Workorder") + matrixParents[item['orderID']].setForeground(13,QColor("Blue")) + matrixParents[item['orderID']].setFont(13, importantFont) + else: + matrixParents[item['orderID']].setText(13, "Layaway") + matrixParents[item['orderID']].setForeground(13,QColor("Green")) + matrixParents[item['orderID']].setFont(13, importantFont) + + self.objectIDs[j] = item['objectID'] + #First Name Column + self.orderList[j].setText(0, str(item['customerFirstName'])) + self.orderList[j].setFont(0, importantFont) + #Last Name Column + self.orderList[j].setText(1, str(item['customerLastName'])) + self.orderList[j].setBackground(1,QColor("lightGray")) + self.orderList[j].setFont(1, importantFont) + #Phone Column + self.orderList[j].setText(2, self.parsePhoneNumber(str(item['customerPhoneNo']))) + self.orderList[j].setFont(2, importantFont) + #Email Column + self.orderList[j].setText(3, str(item['customerEmail'])) + self.orderList[j].setBackground(3,QColor("lightGray")) + self.orderList[j].setFont(3, importantFont) + #Things + self.orderList[j].setText(4, str(item['productDesc'])) + self.orderList[j].setFont(4, importantFont) + #Things + self.orderList[j].setText(5, str(item['productPartNo'])) + self.orderList[j].setBackground(5,QColor("lightGray")) + self.orderList[j].setFont(5, importantFont) + #Things + self.orderList[j].setText(6, str(item['productSupplier'])) + self.orderList[j].setFont(6, importantFont) + #Things + self.orderList[j].setText(7, str(item['dateRequested'])) + self.orderList[j].setBackground(7,QColor("lightGray")) + self.orderList[j].setFont(7, importantFont) + #Date Ordered + if self.orderStatus[item['orderStatus']] == 'Requested': + self.orderList[j].setText(8, '') + elif item['dateOrdered'] == None: + self.orderList[j].setText(8, '') + else: + self.orderList[j].setText(8, str(item['dateOrdered'])) + self.orderList[j].setFont(8, importantFont) + #Things + self.orderList[j].setText(9, str(item['orderID'])) + self.orderList[j].setBackground(9,QColor("lightGray")) + self.orderList[j].setFont(9, importantFont) + #Order Status Column + self.orderList[j].setText(10, self.orderStatus[item['orderStatus']]) + self.orderList[j].setFont(10, importantFont) + #Order Status Column + self.orderList[j].setText(11, str(round(item['price'], 3))) + self.orderList[j].setBackground(11,QColor("lightGray")) + self.orderList[j].setFont(11, importantFont) + #Payment Status Colum + self.orderList[j].setText(12, self.paymentStatus[item['paymentStatus']]) + self.orderList[j].setFont(12, importantFont) + #Order Type Column + if item['isWorkOrder'] == 1: + self.orderList[j].setText(13, "Workorder") + self.orderList[j].setForeground(13,QColor("Blue")) + self.orderList[j].setBackground(13,QColor("lightGray")) + else: + self.orderList[j].setText(13, "Layaway") + self.orderList[j].setForeground(13,QColor("Green")) + self.orderList[j].setBackground(13,QColor("lightGray")) + self.orderList[j].setFont(13, importantFont) + #Things + self.orderList[j].setText(14, str(item['salesRep'])) + self.orderList[j].setFont(14, importantFont) + + self.tableWidgetSO.addTopLevelItem(self.orderList[j]) + + else: + self.orderList.append(QTreeWidgetItem()) + self.objectIDs[j] = item['objectID'] + #First Name Column + self.orderList[j].setText(0, str(item['customerFirstName'])) + self.orderList[j].setFont(0, importantFont) + #Last Name Column + self.orderList[j].setText(1, str(item['customerLastName'])) + self.orderList[j].setBackground(1,QColor("lightGray")) + self.orderList[j].setFont(1, importantFont) + #Phone Column + self.orderList[j].setText(2, self.parsePhoneNumber(str(item['customerPhoneNo']))) + self.orderList[j].setFont(2, importantFont) + #Email Column + self.orderList[j].setText(3, str(item['customerEmail'])) + self.orderList[j].setBackground(3,QColor("lightGray")) + self.orderList[j].setFont(3, importantFont) + #Things + self.orderList[j].setText(4, str(item['productDesc'])) + self.orderList[j].setFont(4, importantFont) + #Things + self.orderList[j].setText(5, str(item['productPartNo'])) + self.orderList[j].setBackground(5,QColor("lightGray")) + self.orderList[j].setFont(5, importantFont) + #Things + self.orderList[j].setText(6, str(item['productSupplier'])) + self.orderList[j].setFont(6, importantFont) + #Things + self.orderList[j].setText(7, str(item['dateRequested'])) + self.orderList[j].setBackground(7,QColor("lightGray")) + self.orderList[j].setFont(7, importantFont) + #Date Ordered + if self.orderStatus[item['orderStatus']] == 'Requested': + self.orderList[j].setText(8, '') + elif item['dateOrdered'] == None: + self.orderList[j].setText(8, '') + else: + self.orderList[j].setText(8, str(item['dateOrdered'])) + self.orderList[j].setFont(8, importantFont) + #Things + self.orderList[j].setText(9, str(item['orderID'])) + self.orderList[j].setBackground(9,QColor("lightGray")) + self.orderList[j].setFont(9, importantFont) + #Order Status Column + self.orderList[j].setText(10, self.orderStatus[item['orderStatus']]) + self.orderList[j].setFont(10, importantFont) + #Order Status Column + self.orderList[j].setText(11, str(round(item['price'], 3))) + self.orderList[j].setBackground(11,QColor("lightGray")) + self.orderList[j].setFont(11, importantFont) + #Payment Status Colum + self.orderList[j].setText(12, self.paymentStatus[item['paymentStatus']]) + self.orderList[j].setFont(12, importantFont) + #Order Type Column + if item['isWorkOrder'] == 1: + self.orderList[j].setText(13, "Workorder") + self.orderList[j].setForeground(13,QColor("Blue")) + self.orderList[j].setBackground(13,QColor("lightGray")) + else: + self.orderList[j].setText(13, "Layaway") + self.orderList[j].setForeground(13,QColor("Green")) + self.orderList[j].setBackground(13,QColor("lightGray")) + self.orderList[j].setFont(13, importantFont) + #Things + self.orderList[j].setText(14, str(item['salesRep'])) + self.orderList[j].setFont(14, importantFont) + + self.tableWidgetSO.addTopLevelItem(self.orderList[j]) + + j+=1 + #print(self.objectIDs) + for i in range(len(self.headerListSO)): + self.tableWidgetSO.resizeColumnToContents(i) + + def getSelectedOrderNumber(self): + i = 0 + for item in self.orderList: + if item.isSelected(): + #9 Pulls Order ID Number to pass + return self.objectIDs[i] + i+=1 + + def delete(self): + i=0 + for item in self.orderList: + if item.isSelected(): + answer = QMessageBox.question(self, 'Deletion', + "Are you sure you want to delete this special order?") + if answer == QMessageBox.Yes: + print('Deleting Order #' + str(self.objectIDs[i])) + deleteOrder(self.objectIDs[i]) + item.setHidden(True) + i+=1 + + def deleteSilent(self): + i=0 + for item in self.orderList: + if item.isSelected(): + print('Deleting Order #' + str(self.objectIDs[i])) + deleteOrder(self.objectIDs[i]) + item.setHidden(True) + i+=1 + + def closeRefresh(self): + self.w.close() + self.tableWidgetSO.clear() + self.addOrdersLoop() + self.search.setText('') + + def closeBasic(self): + self.w.close() + self.search.setText('') + + def createSpecialOrder(self): + self.w = newOrderWindow() + self.selectedOrderNumber = None + + self.custFirstName = QLineEdit() + self.custLastName = QLineEdit() + self.custPhoneNumber = QLineEdit() + self.custEmail = QLineEdit() + self.prodDesc = QLineEdit() + self.partNo = QLineEdit() + self.supplier = QComboBox() + self.partPrice = QLineEdit() + self.orderNumber = QLineEdit() + self.orderStatusChoice = QComboBox() + self.orderDesc = QTextEdit() + self.payStatus = QComboBox() + self.orderType = QCheckBox() + self.salesRep = QComboBox() + + self.payStatus.addItems(self.paymentStatus) + self.salesRep.addItems(staffMembers) + self.supplier.addItems(suppliers) + + #self.sendOrder = QPushButton("Create") + #self.cancelCreation = QPushButton("Cancel") + + self.wButtons = QHBoxLayout() + self.buttonBox = QDialogButtonBox() + self.wLayout = QGridLayout() + self.wLayoutCust = QFormLayout() + self.wLayoutPart = QFormLayout() + self.wLayoutNotes = QFormLayout() + + self.wLayoutCust.addRow("Fist Name", self.custFirstName) + self.wLayoutCust.addRow("Last Name", self.custLastName) + self.wLayoutCust.addRow("Phone Number", self.custPhoneNumber) + self.wLayoutCust.addRow("E-Mail Address", self.custEmail) + self.wLayoutCust.addRow("Order Number", self.orderNumber) + self.wLayoutCust.addRow("Workorder?", self.orderType) + self.wLayoutCust.addRow("Payment Status", self.payStatus) + + self.wLayoutPart.addRow("Product", self.prodDesc) + self.wLayoutPart.addRow("Part Number", self.partNo) + self.wLayoutPart.addRow("Supplier", self.supplier) + self.wLayoutPart.addRow("Price", self.partPrice) + self.wLayoutPart.addRow("Placed By", self.salesRep) + + self.wLayoutNotes.addRow("Notes:", self.orderDesc) + self.objectID = 0 + + self.cancelCreation = self.buttonBox.addButton(QDialogButtonBox.Cancel) + self.sendOrder = self.buttonBox.addButton(QDialogButtonBox.Ok) + self.wButtons.addWidget(self.buttonBox) + self.dateOrderedVar = None + + self.wLayout.addLayout(self.wLayoutCust,0,0) + self.wLayout.addLayout(self.wLayoutPart,0,1) + self.wLayout.addLayout(self.wLayoutNotes,1,0,1,2) + self.wLayout.addLayout(self.wButtons,2,0,1,2) + + self.sendOrder.clicked.connect(self.commitSpecialOrder) + self.cancelCreation.clicked.connect(self.closeBasic) + + self.w.setGeometry(500, 400, 500, 350) + self.w.setWindowTitle('New Special Order') + self.w.setLayout(self.wLayout) + self.w.show() + self.stickyDate = None + return + + def createInfoRequest(self): + self.w = newOrderWindow() + self.selectedOrderNumber = None + + self.custFirstName = QLineEdit() + self.custLastName = QLineEdit() + self.custPhoneNumber = QLineEdit() + self.custEmail = QLineEdit() + self.prodDesc = QLineEdit() + self.partNo = QLineEdit() + self.supplier = QComboBox() + self.partPrice = QLineEdit() + self.orderNumber = QLineEdit() + self.orderStatusChoice = QComboBox() + self.orderDesc = QTextEdit() + self.payStatus = QComboBox() + self.orderType = QCheckBox() + self.salesRep = QComboBox() + + self.payStatus.addItems(self.paymentStatus) + self.salesRep.addItems(staffMembers) + self.supplier.addItems(suppliers) + + #self.sendOrder = QPushButton("Create") + #self.cancelCreation = QPushButton("Cancel") + + self.wButtons = QHBoxLayout() + self.buttonBox = QDialogButtonBox() + self.wLayout = QGridLayout() + self.wLayoutCust = QFormLayout() + self.wLayoutPart = QFormLayout() + self.wLayoutNotes = QFormLayout() + + self.wLayoutCust.addRow("Fist Name", self.custFirstName) + self.wLayoutCust.addRow("Last Name", self.custLastName) + self.wLayoutCust.addRow("Phone Number", self.custPhoneNumber) + self.wLayoutCust.addRow("E-Mail Address", self.custEmail) + #self.wLayoutCust.addRow("Order Number", self.orderNumber) + #self.wLayoutCust.addRow("Workorder?", self.orderType) + #self.wLayoutCust.addRow("Payment Status", self.payStatus) + + self.wLayoutPart.addRow("Product", self.prodDesc) + #self.wLayoutPart.addRow("Part Number", self.partNo) + #self.wLayoutPart.addRow("Supplier", self.supplier) + #self.wLayoutPart.addRow("Price", self.partPrice) + self.wLayoutPart.addRow("Placed By", self.salesRep) + + self.wLayoutNotes.addRow("Notes:", self.orderDesc) + self.objectID = 0 + + + + self.cancelCreation = self.buttonBox.addButton(QDialogButtonBox.Cancel) + self.sendOrder = self.buttonBox.addButton(QDialogButtonBox.Ok) + self.wButtons.addWidget(self.buttonBox) + self.dateOrderedVar = None + + self.wLayout.addLayout(self.wLayoutCust,0,0) + self.wLayout.addLayout(self.wLayoutPart,0,1) + self.wLayout.addLayout(self.wLayoutNotes,1,0,1,2) + self.wLayout.addLayout(self.wButtons,2,0,1,2) + + self.sendOrder.clicked.connect(self.commitInfoRequest) + self.cancelCreation.clicked.connect(self.closeBasic) + + self.w.setGeometry(500, 400, 500, 350) + self.w.setWindowTitle('Product Info Request') + self.w.setLayout(self.wLayout) + self.w.show() + self.stickyDate = None + return + + def createChildOrder(self): + self.w = newOrderWindow() + self.selectedOrderNumber = self.getSelectedOrderNumber() + + self.custFirstName = QLineEdit() + self.custLastName = QLineEdit() + self.custPhoneNumber = QLineEdit() + self.custEmail = QLineEdit() + self.prodDesc = QLineEdit() + self.partNo = QLineEdit() + self.supplier = QComboBox() + self.partPrice = QLineEdit() + self.orderNumber = QLineEdit() + self.orderStatusChoice = QComboBox() + self.orderDesc = QTextEdit() + self.payStatus = QComboBox() + self.orderType = QCheckBox() + self.salesRep = QComboBox() + + + data = fetchOrder(self.selectedOrderNumber) + self.custFirstName.setDisabled(True) + self.custLastName.setDisabled(True) + self.custPhoneNumber.setDisabled(True) + self.custEmail.setDisabled(True) + self.orderNumber.setDisabled(True) + self.orderType.setDisabled(True) + self.custFirstName.setText(data['customerFirstName']) + self.custLastName.setText(data['customerLastName']) + self.custPhoneNumber.setText(str(data['customerPhoneNo'])) + self.custEmail.setText(data['customerEmail']) + self.orderNumber.setText(str(data['orderID'])) + if data['isWorkOrder'] == 1: + self.orderType.setChecked(True) + + self.payStatus.addItems(self.paymentStatus) + self.salesRep.addItems(staffMembers) + self.supplier.addItems(suppliers) + + self.wButtons = QHBoxLayout() + self.buttonBox = QDialogButtonBox() + self.wLayout = QGridLayout() + self.wLayoutCust = QFormLayout() + self.wLayoutPart = QFormLayout() + self.wLayoutNotes = QFormLayout() + + self.wLayoutCust.addRow("Fist Name", self.custFirstName) + self.wLayoutCust.addRow("Last Name", self.custLastName) + self.wLayoutCust.addRow("Phone Number", self.custPhoneNumber) + self.wLayoutCust.addRow("E-Mail Address", self.custEmail) + self.wLayoutCust.addRow("Order Number", self.orderNumber) + self.wLayoutCust.addRow("Workorder?", self.orderType) + self.wLayoutCust.addRow("Payment Status", self.payStatus) + + self.wLayoutPart.addRow("Product", self.prodDesc) + self.wLayoutPart.addRow("Part Number", self.partNo) + self.wLayoutPart.addRow("Supplier", self.supplier) + self.wLayoutPart.addRow("Price", self.partPrice) + self.wLayoutPart.addRow("Placed By", self.salesRep) + + self.wLayoutNotes.addRow("Notes:", self.orderDesc) + self.objectID = 0 + + self.cancelCreation = self.buttonBox.addButton(QDialogButtonBox.Cancel) + self.sendOrder = self.buttonBox.addButton(QDialogButtonBox.Ok) + self.wButtons.addWidget(self.buttonBox) + self.dateOrderedVar = None + + self.wLayout.addLayout(self.wLayoutCust,0,0) + self.wLayout.addLayout(self.wLayoutPart,0,1) + self.wLayout.addLayout(self.wLayoutNotes,1,0,1,2) + self.wLayout.addLayout(self.wButtons,2,0,1,2) + + self.sendOrder.clicked.connect(self.commitSpecialOrder) + self.cancelCreation.clicked.connect(self.closeBasic) + + self.w.setGeometry(500, 400, 500, 350) + self.w.setWindowTitle('Add Item To Order') + self.w.setLayout(self.wLayout) + self.w.show() + self.stickyDate = None + return + + def editSpecialOrder(self): + self.selectedOrderNumber = self.getSelectedOrderNumber() + print('Editing Order #' + str(self.selectedOrderNumber)) + self.w = newOrderWindow() + + self.custFirstName = QLineEdit() + self.custLastName = QLineEdit() + self.custPhoneNumber = QLineEdit() + self.custEmail = QLineEdit() + self.prodDesc = QLineEdit() + self.partNo = QLineEdit() + self.supplier = QComboBox() + self.partPrice = QLineEdit() + self.orderNumber = QLineEdit() + self.orderStatusChoice = QComboBox() + self.orderDesc = QTextEdit() + self.payStatus = QComboBox() + self.orderType = QCheckBox() + self.salesRep = QComboBox() + self.dateOrdered = QCalendarWidget() + self.dateRequested = QLabel() + + self.payStatus.addItems(self.paymentStatus) + self.salesRep.addItems(staffMembers) + self.supplier.addItems(suppliers) + self.orderStatusChoice.addItems(self.orderStatus) + + self.wButtons = QHBoxLayout() + self.buttonBox = QDialogButtonBox() + self.wLayout = QGridLayout() + self.wLayoutCust = QFormLayout() + self.wLayoutPart = QFormLayout() + self.wLayoutNotes = QFormLayout() + + self.wLayoutCust.addRow("Fist Name", self.custFirstName) + self.wLayoutCust.addRow("Last Name", self.custLastName) + self.wLayoutCust.addRow("Phone Number", self.custPhoneNumber) + self.wLayoutCust.addRow("E-Mail Address", self.custEmail) + self.wLayoutCust.addRow("Order Number", self.orderNumber) + self.wLayoutCust.addRow("Workorder?", self.orderType) + self.wLayoutCust.addRow("Payment Status", self.payStatus) + + self.wLayoutPart.addRow("Product", self.prodDesc) + self.wLayoutPart.addRow("Part Number", self.partNo) + self.wLayoutPart.addRow("Supplier", self.supplier) + self.wLayoutPart.addRow("Price", self.partPrice) + self.wLayoutPart.addRow("Placed By", self.salesRep) + self.wLayoutPart.addRow("Requested On:", self.dateRequested) + self.wLayoutPart.addRow("Order Status:", self.orderStatusChoice) + + self.wLayoutNotes.addRow("Date Ordered", self.dateOrdered) + self.wLayoutNotes.addRow("Notes:", self.orderDesc) + + if self.selectedOrderNumber != None: + data = fetchOrder(self.selectedOrderNumber) + self.custFirstName.setText(data['customerFirstName']) + self.custLastName.setText(data['customerLastName']) + self.custPhoneNumber.setText(str(data['customerPhoneNo'])) + self.custEmail.setText(data['customerEmail']) + self.orderNumber.setText(str(data['orderID'])) + if data['isWorkOrder'] == 1: + self.orderType.setChecked(True) + self.payStatus.setCurrentIndex(data['paymentStatus']) + self.orderStatusChoice.setCurrentIndex(data['orderStatus']) + + self.prodDesc.setText(data['productDesc']) + if type(data['dateOrdered']) == type(date.today()): + self.dateOrdered.setSelectedDate(data['dateOrdered']) + self.partNo.setText(data['productPartNo']) + self.supplier.setCurrentText(data['productSupplier']) + self.partPrice.setText(str(data['price'])) + self.salesRep.setCurrentText(data['salesRep']) + self.orderDesc.setText(data['orderDesc']) + self.dateOrdered.setGridVisible(True) + self.dateRequested.setText(data['dateRequested'].isoformat()) + self.stickyDate = data['dateRequested'].isoformat() + self.objectID = data['objectID'] + + self.cancelCreation = self.buttonBox.addButton(QDialogButtonBox.Cancel) + self.removeOrder = self.buttonBox.addButton(QDialogButtonBox.Cancel) + self.sendOrder = self.buttonBox.addButton(QDialogButtonBox.Ok) + self.addToOrder = self.buttonBox.addButton(QDialogButtonBox.Ok) + if self.payStatus.currentText() == "Pending Payment": + self.sendRequestButton = self.buttonBox.addButton(QDialogButtonBox.Reset) + self.sendRequestButton.setText('Send Payment Request') + self.sendRequestButton.clicked.connect(self.sendRequest) + self.wButtons.addWidget(self.buttonBox) + self.removeOrder.setText('Delete') + self.sendOrder.setText('Update') + self.addToOrder.setText('Add Item') + + self.wLayout.addLayout(self.wLayoutCust,0,0) + self.wLayout.addLayout(self.wLayoutPart,0,1) + self.wLayout.addLayout(self.wLayoutNotes,1,0,1,2) + self.wLayout.addLayout(self.wButtons,2,0,1,2) + + self.sendOrder.clicked.connect(self.cleanupEditied) + self.removeOrder.clicked.connect(self.delete) + self.cancelCreation.clicked.connect(self.closeBasic) + self.addToOrder.clicked.connect(self.createChildOrder) + + self.w.setGeometry(500, 400, 500, 550) + self.w.setWindowTitle('Edit Special Order') + self.w.setLayout(self.wLayout) + self.w.show() + return + + def cleanupEditied(self): + self.dateOrderedVar = self.dateOrdered.selectedDate().toPyDate() + if self.preCommitCheck(): + self.deleteSilent() + self.commitSpecialOrder() + + def setNotesSection(self): + thing = self.getSelectedOrderNumber() + data = fetchOrder(thing) + if data != None: + self.notesSectionSO.setText(data['orderDesc']) + else: + self.notesSectionSO.setText('') + + def preCommitCheck(self): + incomplete = False + mandatoryList = [ + self.custFirstName, + self.custLastName, + self.custPhoneNumber, + self.custEmail, + self.orderNumber, + self.prodDesc, + self.partNo, + self.partPrice, + ] + + + if self.salesRep.currentText() == '--Choose One--': + incomplete = True + if self.supplier.currentText() == '--Choose One--': + incomplete = True + + for item in mandatoryList: + if item.text() == '': + item.setStyleSheet("background-color: rgb(255, 193, 193);") + incomplete = True + else: + item.setStyleSheet("background-color: white;") + + if not self.isInt(self.orderNumber.text()): + self.orderNumber.setStyleSheet("background-color: rgb(255, 193, 193);") + incomplete = True + else: + self.orderNumber.setStyleSheet("background-color: white;") + + if not self.isFloat(self.partPrice.text()): + self.partPrice.setStyleSheet("background-color: rgb(255, 193, 193);") + incomplete = True + else: + self.partPrice.setStyleSheet("background-color: white;") + if self.intPhoneNumber(self.custPhoneNumber.text()) == None: + self.custPhoneNumber.setStyleSheet("background-color: rgb(255, 193, 193);") + incomplete = True + else: + self.custPhoneNumber.setStyleSheet("background-color: white;") + if not incomplete: + return True + else: + return False + + def commitSpecialOrder(self): + if self.preCommitCheck(): + if self.stickyDate == None: + theDate = date.today() + else: + theDate = self.stickyDate + + if self.orderNumber.text() == '0': + theNumber = self.objectID + else: + theNumber = int(self.orderNumber.text()) + + data = { + 'customerFirstName':self.custFirstName.text(), + 'customerLastName':self.custLastName.text(), + 'customerPhoneNo':self.intPhoneNumber(self.custPhoneNumber.text()), + 'customerEmail' :self.custEmail.text(), + 'productDesc' :self.prodDesc.text(), + 'productPartNo' :self.partNo.text(), + 'productSupplier' :self.supplier.currentText(), + 'dateRequested' :theDate, + 'dateOrdered' :self.dateOrderedVar, + 'orderID' :theNumber, + 'orderStatus' :self.orderStatusChoice.currentIndex(), + 'orderDesc' :self.orderDesc.toPlainText(), + 'paymentStatus' :self.payStatus.currentIndex(), + 'isWorkOrder' :self.orderType.isChecked(), + 'salesRep':self.salesRep.currentText(), + 'objectID':self.objectID, + 'price':float(self.partPrice.text()), #Type FLOAT + 'weight':35, #Type INT + 'dimLength': 55, #Type INT + 'dimWidth':9, #Type INT + 'dimHeight':33, #Type INT + } + if data['orderStatus'] == -1: + data['orderStatus'] = 0 + self.selectedOrderNumber = writeOrder(data) + print('Creating Order #' + str(self.selectedOrderNumber)) + self.closeRefresh() + return True + else: + return False + + def commitInfoRequest(self): + if not self.preCommitCheck(): + if self.stickyDate == None: + theDate = date.today() + else: + theDate = self.stickyDate + + data = { + 'customerFirstName':self.custFirstName.text(), + 'customerLastName':self.custLastName.text(), + 'customerPhoneNo':self.intPhoneNumber(self.custPhoneNumber.text()), + 'customerEmail' :self.custEmail.text(), + 'productDesc' :self.prodDesc.text(), + 'productPartNo' :'0', + 'productSupplier' :'Other', + 'dateRequested' :theDate, + 'dateOrdered' :self.dateOrderedVar, + 'orderID' :self.intPhoneNumber(self.custPhoneNumber.text())/3, + 'orderStatus' :5, + 'orderDesc' :self.orderDesc.toPlainText(), + 'paymentStatus' :0, + 'isWorkOrder' :True, + 'salesRep':self.salesRep.currentText(), + 'objectID':0, + 'price':0.0, #Type FLOAT + 'weight':35, #Type INT + 'dimLength': 55, #Type INT + 'dimWidth':9, #Type INT + 'dimHeight':33, #Type INT + } + if data['orderStatus'] == -1: + data['orderStatus'] = 0 + self.selectedOrderNumber = writeOrder(data) + print('Creating Order #' + str(self.selectedOrderNumber)) + self.closeRefresh() + return True + else: + return False + + def searchOrders(self): + if self.search.text() == '': + self.tableWidgetSO.clear() + self.addOrdersLoop() + return + self.tableWidgetSO.clear() + self.searchedOrdersLoop() + +# Claim Related Functions + def addClaimsLoop(self): + self.claimList = [] + self.objectClaimIDs = {} + self.orderStatus = ['Requested','Order Placed','Order Recieved', + 'Backordered','Not Available', 'Info Requested'] + self.paymentStatus = ['Pending Payment','Partially Paid','Fully Paid'] + + warrantyClaims = fetchClaims() + importantFont = QFont() + + j=0 + for item in warrantyClaims: + if self.orderStatus[item[10]] == 'Requested': + #if self.orderStatus[item[10]] == 'Requested' and self.paymentStatus[item[12]] == 'Fully Paid': + importantFont.setBold(True) + else: + importantFont.setBold(False) + + self.claimList.append(QTreeWidgetItem()) + self.objectClaimIDs[j] = item[15] + #First Name Column + self.claimList[j].setText(0, str(item[0])) + self.claimList[j].setFont(0, importantFont) + #Last Name Column + self.claimList[j].setText(1, str(item[1])) + self.claimList[j].setBackground(1,QColor("lightGray")) + self.claimList[j].setFont(1, importantFont) + #Phone Column + self.claimList[j].setText(2, self.parsePhoneNumber(str(item[2]))) + self.claimList[j].setFont(2, importantFont) + #Email Column + self.claimList[j].setText(3, str(item[3])) + self.claimList[j].setBackground(3,QColor("lightGray")) + self.claimList[j].setFont(3, importantFont) + #Things + self.claimList[j].setText(4, str(item[4])) + self.claimList[j].setFont(4, importantFont) + #Things + self.claimList[j].setText(5, str(item[5])) + self.claimList[j].setBackground(5,QColor("lightGray")) + self.claimList[j].setFont(5, importantFont) + #Things + self.claimList[j].setText(6, str(item[6])) + self.claimList[j].setFont(6, importantFont) + #Things + self.claimList[j].setText(7, str(item[7])) + self.claimList[j].setBackground(7,QColor("lightGray")) + self.claimList[j].setFont(7, importantFont) + #Date Ordered + if self.orderStatus[item[10]] == 'Requested': + self.claimList[j].setText(8, '') + elif item[8] == None: + self.claimList[j].setText(8, '') + else: + self.claimList[j].setText(8, str(item[8])) + self.claimList[j].setFont(8, importantFont) + #Things + self.claimList[j].setText(9, str(item[9])) + self.claimList[j].setBackground(9,QColor("lightGray")) + self.claimList[j].setFont(9, importantFont) + #Order Status Column + self.claimList[j].setText(10, self.orderStatus[item[10]]) + self.claimList[j].setFont(10, importantFont) + #Order Status Column + self.claimList[j].setText(11, str(round(item[16], 3))) + self.claimList[j].setBackground(11,QColor("lightGray")) + self.claimList[j].setFont(11, importantFont) + #Payment Status Colum + self.claimList[j].setText(12, self.paymentStatus[item[12]]) + self.claimList[j].setFont(12, importantFont) + #Order Type Column + if item[13] == 1: + self.claimList[j].setText(13, "Workorder") + self.claimList[j].setForeground(13,QColor("Blue")) + self.claimList[j].setBackground(13,QColor("lightGray")) + else: + self.claimList[j].setText(13, "Layaway") + self.claimList[j].setForeground(13,QColor("Green")) + self.claimList[j].setBackground(13,QColor("lightGray")) + self.claimList[j].setFont(13, importantFont) + #Things + self.claimList[j].setText(14, str(item[14])) + self.claimList[j].setFont(14, importantFont) + + + self.tableWidgetWC.addTopLevelItem(self.claimList[j]) + j+=1 + + for i in range(len(self.headerListWC)): + self.tableWidgetWC.resizeColumnToContents(i) + + def getSelectedClaimNumber(self): + i = 0 + for item in self.claimList: + if item.isSelected(): + #9 Pulls Order ID Number to pass + return self.objectClaimIDs[i] + i+=1 + +# Online Realted Functions + def addOnlineLoop(self): + '''onlineOrders = self.wooConnect().get('orders/72015').json() + test = QTreeWidgetItem() + test2 = QTreeWidgetItem() + test3 = QTreeWidgetItem() + self.tableWidgetOO2.addTopLevelItem(test) + test.addChildren([test2, test3]) + + test.setText(0, onlineOrders['shipping']['first_name']) + test.setText(1, onlineOrders['shipping']['last_name']) + test.setText(2, onlineOrders['billing']['phone']) + test.setText(3, onlineOrders['billing']['email']) + test.setText(4, '------') + test.setText(5, '------') + test.setText(6, '$'+onlineOrders['total']) + test.setText(7, '------') + for i in range(8): + test.setBackground(i, QColor("lightGray")) + + test2.setText(0, onlineOrders['shipping']['first_name']) + test2.setText(1, onlineOrders['shipping']['last_name']) + test2.setText(2, onlineOrders['billing']['phone']) + test2.setText(3, onlineOrders['billing']['email']) + test2.setText(4, onlineOrders['line_items'][0]['name']) + test2.setText(5, str(onlineOrders['line_items'][0]['quantity'])) + test2.setText(6, '$'+str(onlineOrders['line_items'][0]['subtotal'])) + test2.setText(7, str(onlineOrders['line_items'][0]['sku'])) + + test3.setText(0, onlineOrders['shipping']['first_name']) + test3.setText(1, onlineOrders['shipping']['last_name']) + test3.setText(2, onlineOrders['billing']['phone']) + test3.setText(3, onlineOrders['billing']['email']) + test3.setText(4, onlineOrders['line_items'][1]['name']) + test3.setText(5, str(onlineOrders['line_items'][1]['quantity'])) + test3.setText(6, '$'+str(onlineOrders['line_items'][1]['subtotal'])) + test3.setText(7, str(onlineOrders['line_items'][1]['sku']))''' + + return + +# Core Functions + def isFloat(self, i): + try: + float(i) + return True + except ValueError: + return False + + def isInt(self, i): + try: + int(i) + return True + except ValueError: + return False + + def intPhoneNumber(self, number): + if len(number) == 0: + return None + + i = 0 + newNumber = "" + forbiddenChars = ["-"," ","(",")","+","."] + + for item in number: + if item not in forbiddenChars: + newNumber += item + + if newNumber[0] == "1": + newNumber = newNumber[1:] + dashNumber = "" + for item in newNumber: + dashNumber += item + i+=1 + + if self.isInt(dashNumber): + return int(dashNumber) + else: + return None + + def parsePhoneNumber(self, number): + i = 0 + newNumber = "" + forbiddenChars = ["-"," ","(",")","+","."] + + for item in number: + if item not in forbiddenChars: + newNumber += item + + if newNumber[0] == "1": + newNumber = newNumber[1:] + newNumber = "1 " + newNumber + dashNumber = "" + for item in newNumber: + if i == 5: + dashNumber += " " + dashNumber += item + elif i == 8: + dashNumber += " " + dashNumber += item + else: + dashNumber += item + i+=1 + + return dashNumber + + def wooConnect(self): + wcapi = API( + url = wcAPIConfig['url'], + consumer_key = wcAPIConfig['consumer_key'], + consumer_secret = wcAPIConfig['consumer_secret'], + wp_api = True, + version = "wc/v3" + ) + + return wcapi + + def createWooProduct(self, first_name, last_name, layaway, total, weight='', length='', width='', height=''): + #Connecting to the Woo Commerce REST API + print('Building WooCommerce Product') + wcapi = API( + url=wcAPILegacyConfig['url'], + consumer_key=wcAPILegacyConfig['consumer_key'], + consumer_secret=wcAPILegacyConfig['consumer_secret'], + wp_api=wcAPILegacyConfig['wc_api'], + version=wcAPILegacyConfig['version'], + verify_ssl=wcAPILegacyConfig['verify_ssl'], + timeout=wcAPILegacyConfig['timeout'], + ) + + check = wcapi.get('products?sku='+layaway).json() + + if check == []: + print('Payment for this order hasn\'t been sent yet. Building new Product') + data = { + "name": "Online Payment - "+layaway, + "catalog_visibility": "visible", + "type": "simple", + "price": total, + "regular_price": total, + "manage_stock": True, + "stock_quantity": 1, + "in_stock": True, + "sku":layaway, + "description": "Online Payment for Special Order #"+layaway, + "weight": weight, + "dimensions": { + "length": length, + "width": width, + "height": height + }, + "purchasable": True, + "images": [{ + "src": "https://www.revolutioncycle.com/wp-content/uploads/2015/06/Online-purchase-template1.jpg", + "position": 0 + }] + } + return wcapi.post("products", data).json()['permalink'] + else: + print('Payment for this order has already been sent.') + return check[0]['permalink'] + + def sendRequest(self): + self.progress = QProgressBar() + self.progressLabel = QLabel() + self.progress.setMinimum(0) + self.progress.setMaximum(100) + self.progress.setTextVisible(True) + self.wLayoutNotes.addWidget(self.progressLabel) + self.wLayoutNotes.addWidget(self.progress) + self.progress.show() + self.progressLabel.show() + + self.progressLabel.setText('Building/Re-Sending Online Payment') + self.progress.setValue(33) + + self.data = { + 'firstName':self.custFirstName.text(), + 'lastName':self.custLastName.text(), + 'email':self.custEmail.text(), + 'product':self.prodDesc.text(), + 'link':self.createWooProduct( + self.custFirstName.text(), + self.custLastName.text(), + self.orderNumber.text(), + self.partPrice.text() + ), + 'salesperson':self.salesRep.currentText(), + 'orderNo':int(self.orderNumber.text()), + 'backETA':'idk', + 'shipETA':'idk', + } + print(self.data) + self.progressLabel.setText('Sending Email') + self.progress.setValue(66) + if isEmail(self.data['email']): + sendEmail('request', self.data) + self.progressLabel.setText('Email Sent!') + self.progress.setValue(100) + sleep(1) + self.w.close() + return + else: + self.progressLabel.setText('Error: Invalid Email Address Entered.') + self.progress.setValue(0) + return + +class newOrderWindow(QWidget): + def __init__(self): + QWidget.__init__(self) + self.initUI() + def initUI(self): + return \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..f0523b6 --- /dev/null +++ b/main.py @@ -0,0 +1,42 @@ +from gui import * +import time + +def exitOM(): + app.exec_() + print('Shutting Down... No hard feelings') + return + +if __name__ == '__main__': + print('+-------------------- ',date.today().isoformat(),time.strftime("%I:%M"),' --------------------+') + print('This is Order Manager '+versionNumber) + print('All debugging messages will appear here') + print('Logs are not built in yet and are planned for later versions') + print() + for item in sqlConfig: + if item == '': + print('[ERROR]: Incomplete config file') + exit() + for item in wcAPIConfig: + if item == '': + print('[ERROR]: Incomplete config file') + exit() + for item in wcAPILegacyConfig: + if item == '': + print('[ERROR]: Incomplete config file') + exit() + for item in emailConfig: + if item == '': + print('[ERROR]: Incomplete config file') + exit() + for item in staffMembers: + if item == '': + print('[ERROR]: Incomplete config file') + exit() + for item in suppliers: + if item == '': + print('[ERROR]: Incomplete config file') + exit() + app = QApplication(sys.argv) + ex = mainWindow() + sys.exit(exitOM()) + \ No newline at end of file diff --git a/sendemail.py b/sendemail.py new file mode 100644 index 0000000..119e279 --- /dev/null +++ b/sendemail.py @@ -0,0 +1,84 @@ +import email +import smtplib +import os +from config import * + +scriptDir = os.path.dirname(__file__) + +default = { + 'firstName':'Foo', + 'lastName':'Bar', + 'email':'foo@bar.com', + 'product':'ACME Part', + 'link':'https://morris.glyndwr.io/', + 'salesperson':'John Doe', + 'orderNo':'55634', + 'backETA':'idk', + 'shipETA':'idk', +} + +def readTemplate(template): + if template == 'request': + relPath = "Email Templates/online_payment_request.html" + elif template == 'backordered': + relPath = "Email Templates/special_order_backordered.html" + elif template == 'notAvailable': + relPath = "Email Templates/special_order_not_available.html" + elif template == 'ordered': + relPath = "Email Templates/special_order_ordered.html" + elif template == 'received': + relPath = "Email Templates/special_order_recieved.html" + else: + return + with open(os.path.join(scriptDir, relPath), 'r') as html: + data = html.read() + return data + +def sendEmail(template, info=default): + + msg_header = ('From: [Store Name] [Store Eamil]\n' + 'To: '+info['firstName']+" "+info['lastName']+' <'+info['email']+'>' + 'MIME-Version: 1.0\n' + 'Content-type: text/html\n' + 'Subject: Online Payment Request from [Store Name]\n') + title = 'Hello '+info['firstName'] + + msg_content = readTemplate(template) + if msg_content == None: + return + msg_content = msg_content.replace('[CUSTOMER FIRST NAME]', info['firstName']) + msg_content = msg_content.replace('[PRODUCT NAME HERE]', info['product']) + msg_content = msg_content.replace('[SALESPERSON]', info['salesperson']) + msg_content = msg_content.replace('[PRODUCT LINK]', info['link']) + msg_content = msg_content.replace('[ORDER NUMBER]', info['orderNo']) + + msg = (''.join([msg_header, msg_content])).encode() + + server = smtplib.SMTP_SSL('mail.hover.com', 465) # + server.ehlo() + #server.starttls() + server.ehlo() + server.login(emailConfig['username'], emailConfig['password']) + + server.sendmail(emailConfig['username'], info['email'], msg) + + server.quit() + +def isEmail(email): + try: + str(email) + + atIndex = 0 + dotIndex = 0 + for i in range(len(email)): + if email[i] == '@': + atIndex = i + elif email[i] == '.': + dotIndex = i + if dotIndex == 0 or atIndex == 0: + return False + elif dotIndex < atIndex: + return False + return True + except: + return False \ No newline at end of file diff --git a/sql.py b/sql.py new file mode 100644 index 0000000..c2ae74f --- /dev/null +++ b/sql.py @@ -0,0 +1,440 @@ +#-ORDER MANAGER - SQL.py +# +# This library handles all MariaDB/MySQL Interaction for Order Manager such as read, +# write, and delete. Functions are named apropriatley. + +import mysql.connector +from config import * + +#-----General Operation Functions------------------------------------------------------- + +def connect(): + cnx = mysql.connector.connect( + user=sqlConfig['user'], + password=sqlConfig['password'], + host=sqlConfig['host'], + database=sqlConfig['database']) + return cnx + +def generateID(): + + cnx = connect() + + query="SELECT MAX(objectID) FROM Orders" + output =[] + + #Open Cursor for executing the query + cursor = cnx.cursor() + + #Run the SELECT query + cursor.execute(query) + + #DEBUG: Print Query output to command line + for item in cursor: + output.append(item) + + #Tie up loose ends and return + cursor.close() + cnx.close() + if output[0][0] == None: + return 0 + return (output[0][0]+1) + +def makeFakeOrders(): + for i in range(20): + fakeOrder = orderTemplate + orderTemplate['orderID']+=i + writeOrder(fakeOrder) + +def sanitizeInput(userInput): + output = '' + okSpecialChars = [46, 64, 95] + if type(userInput) != type(''): + return '' + + for item in userInput: + if item in userInput: + if ord(item) in range(48,58) or ord(item) in range(65,91) \ + or ord(item) in range(97,123) or ord(item) in okSpecialChars: + output+=item + return output + +def performQuery(userInput): + cnx = connect() + + output =[] + + #Open Cursor for executing the query + cursor = cnx.cursor() + + #Run the user query + cursor.execute(userInput) + + #DEBUG: Print Query output to command line + for item in cursor: + output.append(item) + + #Tie up loose ends and return + cursor.close() + cnx.close() + return output + +#-----Functions for Special Order Writing----------------------------------------------- + +def writeOrder(dataOrder=orderTemplate): + + cnx = connect() + + if dataOrder['objectID'] == 0: + dataOrder['objectID']=generateID() + + #Open Cursor for executing the query + cursor = cnx.cursor() + + #The Query that we will execute + addOrder = ("INSERT INTO Orders " + "(customerFirstName, customerLastName, customerPhoneNo, customerEmail," + "productDesc, productPartNo, productSupplier, dateRequested, dateOrdered," + "orderID,orderStatus,orderDesc,paymentStatus,isWorkOrder,salesRep," + "objectID,price,weight,dimLength,dimWidth,dimHeight)" + " VALUES (%(customerFirstName)s, %(customerLastName)s, %(customerPhoneNo)s," + " %(customerEmail)s, %(productDesc)s, %(productPartNo)s, %(productSupplier)s," + " %(dateRequested)s, %(dateOrdered)s, %(orderID)s, %(orderStatus)s," + " %(orderDesc)s, %(paymentStatus)s, %(isWorkOrder)s, %(salesRep)s," + " %(objectID)s, %(price)s, %(weight)s, %(dimLength)s, %(dimWidth)s," + " %(dimHeight)s);") + + #Write and commit changes to database + cursor.execute(addOrder, dataOrder) + cnx.commit() + + #Tie up loose ends and return + cursor.close() + cnx.close() + return dataOrder['objectID'] + +def fetchOrders(): + + cnx = connect() + + query="SELECT * FROM Orders" + output =[] + + #Open Cursor for executing the query + cursor = cnx.cursor() + + #Run the SELECT query + cursor.execute(query) + + #DEBUG: Print Query output to command line + for item in cursor: + output.append(item) + + #Tie up loose ends and return + cursor.close() + cnx.close() + return output + +def fetchOrder(orderNo): + + cnx = connect() + + if orderNo == None: + cnx.close() + return + + query=("SELECT * FROM Orders WHERE objectID = "+str(orderNo)) + output=[] + + #Open Cursor for executing the query + cursor = cnx.cursor() + + #Run the SELECT query + cursor.execute(query) + + for item in cursor: + output.append(item) + + #DEBUG: Print Query output to command line + data = { + 'customerFirstName':output[0][0], #Type TEXT + 'customerLastName':output[0][1], #Type TEXT + 'customerPhoneNo':output[0][2], #Type BIGINT + 'customerEmail' :output[0][3], #Type TEXT + 'productDesc' :output[0][4], #Type TEXT + 'productPartNo' :output[0][5], #Type TEXT + 'productSupplier' :output[0][6], #Type TEXT + 'dateRequested' :output[0][7], #Type DATE + 'dateOrdered' :output[0][8], #Type DATE + 'orderID' :output[0][9], #Type BIGINT + 'orderStatus' :output[0][10], #Type TINYINT + 'orderDesc' :output[0][11], #Type Text + 'paymentStatus' :output[0][12], #Type TINTINT + 'isWorkOrder' :output[0][13], #Type BOOLEAN + 'salesRep':output[0][14], #Type TEXT + 'objectID':output[0][15], #Type INT + 'price':output[0][16], #Type FLOAT + 'weight':output[0][17], #Type INT + 'dimLength':output[0][18], #Type INT + 'dimWidth':output[0][19], #Type INT + 'dimHeight':output[0][20], #Type INT + } + + #Tie up loose ends and return + cursor.close() + cnx.close() + return data + +def findOrder(searchText): + + cnx = connect() + + if searchText == None: + cnx.close() + return + elif type(searchText) != type(''): + cnx.close() + return + + searchText=sanitizeInput(searchText) + + query=("SELECT * FROM Orders" + " WHERE customerFirstName LIKE \'%"+searchText+"%\' " + " OR customerLastName LIKE \'%"+searchText+"%\' " + " OR customerPhoneNo LIKE \'%"+searchText+"%\' " + " OR customerEmail LIKE \'%"+searchText+"%\' " + " OR productDesc LIKE \'%"+searchText+"%\' " + " OR productPartNo LIKE \'%"+searchText+"%\' " + " OR orderDesc LIKE \'%"+searchText+"%\' " + " OR orderID LIKE \'%"+searchText+"%\' " + ) + + output=[] + results=[] + + #Open Cursor for executing the query + cursor = cnx.cursor() + + #Run the SELECT query + cursor.execute(query) + + for item in cursor: + output.append(item) + + #DEBUG: Print Query output to command line + + for i in range(len(output)): + results.append({ + 'customerFirstName':output[i][0], #Type TEXT + 'customerLastName':output[i][1], #Type TEXT + 'customerPhoneNo':output[i][2], #Type BIGINT + 'customerEmail' :output[i][3], #Type TEXT + 'productDesc' :output[i][4], #Type TEXT + 'productPartNo' :output[i][5], #Type TEXT + 'productSupplier' :output[i][6], #Type TEXT + 'dateRequested' :output[i][7], #Type DATE + 'dateOrdered' :output[i][8], #Type DATE + 'orderID' :output[i][9], #Type BIGINT + 'orderStatus' :output[i][10], #Type TINYINT + 'orderDesc' :output[i][11], #Type Text + 'paymentStatus' :output[i][12], #Type TINTINT + 'isWorkOrder' :output[i][13], #Type BOOLEAN + 'salesRep':output[i][14], #Type TEXT + 'objectID':output[i][15], #Type INT + 'price':output[i][16], #Type FLOAT + 'weight':output[i][17], #Type INT + 'dimLength':output[i][18], #Type INT + 'dimWidth':output[i][19], #Type INT + 'dimHeight':output[i][20], #Type INT + }) + + #Tie up loose ends and return + cursor.close() + cnx.close() + return results + +def deleteOrder(ID): + cnx = connect() + + if ID == None: + return + + #If ID is passed into function, then operate + query = "DELETE FROM Orders WHERE objectID = "+str(ID) + + #Open Cursor for executing the query + cursor = cnx.cursor() + + #Run and commit the DELETE query + cursor.execute(query) + cnx.commit() + + #Tie up loose ends and return + cursor.close() + cnx.close() + return + +def updateOrders(col1='customerFirstName', col2='customerLastName', + data=('Steve', 'Morris')): + + cnx = connect() + + query = "UPDATE Orders SET "+col1+" = %s WHERE "+col2+" = %s;" + + #Open Cursor for executing the query + cursor = cnx.cursor() + + #Run and commit the DELETE query + cursor.execute(query, data) + cnx.commit() + + #Tie up loose ends and return + cursor.close() + cnx.close() + return + +#-----Functions for Warranty Claims---------------------------------------------------- + +def writeClaim(dataOrder=orderTemplate): + + cnx = connect() + + if dataOrder['objectID'] == 0: + dataOrder['objectID']=generateID() + + #Open Cursor for executing the query + cursor = cnx.cursor() + + #The Query that we will execute + addOrder = ("INSERT INTO Claims " + "(customerFirstName, customerLastName, customerPhoneNo, customerEmail," + "productDesc, productPartNo, productSupplier, dateRequested, dateOrdered," + "orderID,orderStatus,orderDesc,paymentStatus,isWorkOrder,salesRep," + "objectID,price,weight,dimLength,dimWidth,dimHeight)" + " VALUES (%(customerFirstName)s, %(customerLastName)s, %(customerPhoneNo)s," + " %(customerEmail)s, %(productDesc)s, %(productPartNo)s, %(productSupplier)s," + " %(dateRequested)s, %(dateOrdered)s, %(orderID)s, %(orderStatus)s," + " %(orderDesc)s, %(paymentStatus)s, %(isWorkOrder)s, %(salesRep)s," + " %(objectID)s, %(price)s, %(weight)s, %(dimLength)s, %(dimWidth)s," + " %(dimHeight)s);") + + #Write and commit changes to database + cursor.execute(addOrder, dataOrder) + cnx.commit() + + #Tie up loose ends and return + cursor.close() + cnx.close() + return dataOrder['objectID'] + +def fetchClaims(): + + cnx = connect() + + query="SELECT * FROM Claims" + output =[] + + #Open Cursor for executing the query + cursor = cnx.cursor() + + #Run the SELECT query + cursor.execute(query) + + #DEBUG: Print Query output to command line + for item in cursor: + output.append(item) + + #Tie up loose ends and return + cursor.close() + cnx.close() + return output + +def fetchClaim(claimNo): + + cnx = connect() + + if orderNo == None: + cnx.close() + return + + query=("SELECT * FROM Claims WHERE objectID = "+str(claimNo)) + output=[] + + #Open Cursor for executing the query + cursor = cnx.cursor() + + #Run the SELECT query + cursor.execute(query) + + for item in cursor: + output.append(item) + + #DEBUG: Print Query output to command line + data = { + 'customerFirstName':output[0][0], #Type TEXT + 'customerLastName':output[0][1], #Type TEXT + 'customerPhoneNo':output[0][2], #Type BIGINT + 'customerEmail' :output[0][3], #Type TEXT + 'productDesc' :output[0][4], #Type TEXT + 'productPartNo' :output[0][5], #Type TEXT + 'productSupplier' :output[0][6], #Type TEXT + 'dateRequested' :output[0][7], #Type DATE + 'dateOrdered' :output[0][8], #Type DATE + 'orderID' :output[0][9], #Type BIGINT + 'orderStatus' :output[0][10], #Type TINYINT + 'orderDesc' :output[0][11], #Type Text + 'paymentStatus' :output[0][12], #Type TINTINT + 'isWorkOrder' :output[0][13], #Type BOOLEAN + 'salesRep':output[0][14], #Type TEXT + 'objectID':output[0][15], #Type INT + 'price':output[0][16], #Type FLOAT + 'weight':output[0][17], #Type INT + 'dimLength':output[0][18], #Type INT + 'dimWidth':output[0][19], #Type INT + 'dimHeight':output[0][20], #Type INT + } + + #Tie up loose ends and return + cursor.close() + cnx.close() + return data + +def deleteClaim(ID): + cnx = connect() + + if ID == None: + return + + #If ID is passed into function, then operate + query = "DELETE FROM Claims WHERE objectID = "+str(ID) + + #Open Cursor for executing the query + cursor = cnx.cursor() + + #Run and commit the DELETE query + cursor.execute(query) + cnx.commit() + + #Tie up loose ends and return + cursor.close() + cnx.close() + return + +def updateClaims(col1='customerFirstName', col2='customerLastName', + data=('Steve', 'Morris')): + + cnx = connect() + + query = "UPDATE Claims SET "+col1+" = %s WHERE "+col2+" = %s;" + + #Open Cursor for executing the query + cursor = cnx.cursor() + + #Run and commit the DELETE query + cursor.execute(query, data) + cnx.commit() + + #Tie up loose ends and return + cursor.close() + cnx.close() + return \ No newline at end of file