class AdminWindow(QMainWindow, Ui_MainWindow): """ Ui_MainWindow: Class containing widgets and their respective settings context: This is the overall application context, containing resources used through out the app. Seriously aren't the variable names and function names intuitive enough? """ def __init__(self, context, *args, **kwargs): super(AdminWindow, self).__init__(*args, **kwargs) self.context = context self.setupUi(self) # create widgets from Ui_MainWindow self.setWindowIcon(self.context.window_icon) self.load_tables() # create tables from database self.actionAbout.setIcon(self.context.about_icon) self.actionAbout.triggered.connect(self.show_about) self.actionLog_Out.setIcon(self.context.logout_icon) self.actionLog_Out.triggered.connect(self.logout) self.add_product_button.clicked.connect(self.add_product) self.delete_product_button.clicked.connect(lambda: self.product_model.removeRow( self.product_table_view.currentIndex().row())) self.add_user_button.clicked.connect(self.add_user) self.delete_user_button.clicked.connect( lambda: self.users_model.removeRow( self.user_table_view.currentIndex().row() )) def show_about(self): dlg = AboutDialog(self.context, self) dlg.exec_() def load_tables(self): self.connect_database() self.load_products_table() self.load_users_table() self.load_orders_table() def connect_database(self): # connection to database and open connection db = QSqlDatabase.addDatabase('QSQLITE') db.setDatabaseName(self.context.get_database) db.open() def load_products_table(self): # The model used by the view self.product_model = QSqlTableModel() self.product_model.setTable('products') self.product_model.setEditStrategy(QSqlTableModel.OnFieldChange) self.product_model.select() # Use the product model as the model. MV programming self.product_table_view.setModel(self.product_model) def load_users_table(self): self.users_model = QSqlTableModel() self.users_model.setTable('users') self.users_model.setEditStrategy(QSqlTableModel.OnFieldChange) self.users_model.select() self.user_table_view.setModel(self.users_model) def load_orders_table(self): self.orders_model = QSqlTableModel() self.orders_model.setTable('orders') self.orders_model.select() self.orders_table_view.setModel(self.orders_model) def logout(self): # Go to login window self.loginwindow = LoginWindow(context=self.context) self.loginwindow.show() self.hide() def add_product(self): self.product_model.insertRows(self.product_model.rowCount(), 1) def add_user(self): self.users_model.insertRows(self.users_model.rowCount(), 1)
@cached_property def get_database(self): return self.get_resource('database/resturant_database.db') @cached_property def cancel_icon(self): return QIcon(self.get_resource('icons/cross-button.png')) @cached_property def logout_icon(self): return QIcon(self.get_resource('icons/control-power.png')) @cached_property def about_logo(self): return QPixmap(self.get_resource('icons/restaurant128.png')) @cached_property def window_icon(self): return QIcon(self.get_resource('icons/restaurant64.png')) if __name__ == '__main__': appctxt = MyApplicationContext() # 1. Instantiate ApplicationContext window = LoginWindow(appctxt) window.show() exit_code = appctxt.app.exec_() # 2. Invoke appctxt.app.exec_() sys.exit(exit_code)
class SalesWindow(QMainWindow, Ui_MainWindow): """ username: current user login, whose name transactions will be carried on with context: The Application context that controls the whole app and contains all resources """ products_in_checkout = set() def __init__(self, username, context, *args, **kwargs): super(SalesWindow, self).__init__(*args, **kwargs) self.username = username self.context = context self.setupUi(self) self.setWindowIcon(self.context.window_icon) self.get_product_list() self.username_label.setText(self.username.title()) self.actionLog_Out.setIcon(self.context.logout_icon) self.actionAbout.setIcon(self.context.about_icon) self.actionAbout.triggered.connect(self.show_about) self.actionLog_Out.triggered.connect(self.logout) self.closing_sales_button.clicked.connect(self.select_duration) self.populate_combobox() self.items_combobox.currentTextChanged.connect(self.add_to_checkout) self.done_button.clicked.connect(self.checkout) def show_about(self): dlg = AboutDialog(self.context, self) dlg.exec_() def logout(self): self.loginwindow = LoginWindow(self.context) self.loginwindow.show() self.hide() def checkout(self): dlg = CheckoutConfirmationDialog(self) if dlg.exec_(): self.perform_transaction() self.clear_screen() print('Success') else: print('Cancel') def select_duration(self): """Creates a dialog containg two datetime edit widgets""" dlg = ClosingSalesDialog(self.context, self.username, self) if dlg.exec_(): print('Success!') else: print("Cancel!") def connect_database(self): db = QSqlDatabase.addDatabase('QSQLITE') db.setDatabaseName(self.context.get_database) db.open() def populate_combobox(self): self.connect_database() model = QSqlTableModel() model.setTable('products') column = model.fieldIndex('name') model.select() self.items_combobox.setModel(model) self.items_combobox.setModelColumn(column) def add_to_checkout(self, currenttext): # check if product already in checkout for product in self.product_list: if product.name == currenttext: break self.process_product(product) def process_product(self, product): if not product.in_checkout: product.in_checkout = True self.products_in_checkout.add(product) self.add_create_product_layout(product) def add_create_product_layout(self, product): item = ProductFrame(product, self.context, self) item.no_label.setText(str(0)) self.checkout_layout.addWidget(item) def calculate_total(self): self.total_label.setText( str(sum(product.subtotal for product in self.products_in_checkout))) def update_database(self, product): now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M") with DBHandler(self.context.get_database) as cursor: update_SQL = """ UPDATE products SET quantity_in_stock = quantity_in_stock - ? """ insert_SQL = """ INSERT INTO orders VALUES (?, ?, ?, ?, ?, ?) """ cursor.execute(update_SQL, [product.quantity]) cursor.execute(insert_SQL, [ None, self.username, now, product.name, product.quantity, product.subtotal ]) print('Success') def perform_transaction(self): for product in self.products_in_checkout: self.update_database(product) product.in_checkout = False product.quantity = 0 def clear_screen(self): for i in reversed(range(self.checkout_layout.count())): self.checkout_layout.itemAt(i).widget().setParent(None) for product in self.products_in_checkout: reset(product) self.products_in_checkout.clear() self.total_label.setText(str('0')) def get_product_list(self): with DBHandler(self.context.get_database) as cursor: cursor.execute("SELECT * FROM products") results = cursor.fetchall() # Genexpr to get all items from database self.product_list = [ self._Product(*value) for _, value in enumerate(results) ] class _Product: """ This is a private class that holds attributes of each product. """ def __init__(self, name, price, remaining_stock): self.name = name self.quantity = 0 self.price = price self.remaining_stock = remaining_stock self.in_checkout = False @property def subtotal(self): return self.price * self.quantity def __str__(self): return str(self.name)