diff --git a/README.md b/README.md index 581498342a7eda3969c86cc52a259ee1b09e72e5..01316cc457546ea70ff5f9062f0c97f19fd8f605 100644 --- a/README.md +++ b/README.md @@ -18,4 +18,10 @@ You will now have the SQL database on your own system. Remember any word done to To get database connected within coding: 1. Each person will need to update constants.py file 2. In file find row 4-7. -3. Update username & password with your own SQL workbench credentials. \ No newline at end of file +3. Update username & password with your own SQL workbench credentials. + + + + +questions for clarification: +- in user.createBooking and tblBookings is the 'booking_date' the time that the booking is created or the time of the showing? \ No newline at end of file diff --git a/main.py b/main.py index e09e231d9bdc5a9282d6e6d2b648c0b5be189f5a..fcaa8c0f71f473b82bd916a76f9ef8d0ce09e6cd 100644 --- a/main.py +++ b/main.py @@ -41,6 +41,8 @@ def loginAttempt(username: str, password: str): # using dbfuncs to do this: cursor.execute("SELECT username, password_hash, role FROM users WHERE username = %s AND password_hash = %s", (username, password)) user_data = select_from_table_where("tblUsers", f"username = '{username}' AND password_hash = '{password}'", "user_id, username, password_hash, role, cinemas") + if user_data == None: + return None user_data = user_data[0] logging.debug(user_data) @@ -63,10 +65,82 @@ def loginAttempt(username: str, password: str): logging.warning("Invalid username or password.") return None # Return None if no user found +def veiwBookings_cli(user): + data = user.veiwBookings() + logging.debug(f"\n# {data}") + print("\n\n") + for i in data: + print(i) + +def createBooking_cli(user): + # input data and validation loop + while True: + print("Please input booking info.") + + showing_id = int(input("\nShowing ID:")) + seats = input("\nSeats in format '1' or '1 2 3' (no dupes):") + if showing_id == "exit" or seats == "exit": + return + elif showing_id != None and seats != None: + status = user.createBooking(showing_id, seats) + if status == True: + print("Booking created.") + createTicket_cli(user, booking_id) + break + else: + print(status) + else: + print("Missing input please try again.") + +def removeBooking_cli(user): + booking_id = int(input("\nInput Id of booking to remove: ")) + user.removeBooking(booking_id) + +def manageBookings_cli(user): + veiwBookings_cli(user) + selected_booking = 0 + # input val loop for booking_id + while True: + selected_booking = int(input("\nSelect booking_id to be managed: ")) + logging.debug(f"selected_booking={selected_booking}") + if selected_booking == None or selected_booking == 0: + print("Invalid input try again.") + else: + selected_booking = select_from_table_where(table="tblBookings", selection="*", condition=f"booking_id={selected_booking}") + logging.debug(f"selected_booking={selected_booking}") + if selected_booking is not None: + break + else: + print("db error, try again.") # lol + # input for new vals + print("Input new values for booking, or leave blank for no change.") + user_id = int(input("user_id: ")) + showing_id = int(input("showing_id: ")) + seat_numbers= input("seat_numbers: ") + total_price= float(input("total_price: ")) + booking_date= input("booking_date: ") + + status = user.updateBooking(booking_id=selected_booking, user_id=user_id, showing_id=showing_id, seat_numbers=seat_numbers, total_price=total_price, booking_date=booking_date) + if status: + print("Booking updated") + else: + print("Failed to update booking.") + +def createTicket_cli(user, booking_id=None): + while booking_id == None: + booking_id = intput("Input booking_id to create a ticket") + if booking_id.isdigit(): + booking_id = int(booking_id) + break + else: + print("Invalid booking_id.") + pass + # create ticket... + def staffUser_options_cli(user:StaffUser) -> None: logging.debug("loaded into staffUser_options_cli.") while True: - selection = input("Menu options:\n" + selection = input("\nMenu options:\n" " 1. View bookings\n" " 2. Create booking \n" " 3. Remove booking\n" @@ -82,20 +156,16 @@ def staffUser_options_cli(user:StaffUser) -> None: # switch case: if selection == "1": logging.debug("selection 1, loading View bookings") - data = user.veiwBookings() - print(data) - print(type(data)) - logging.debug(f"\n# {data}") + veiwBookings_cli(user) elif selection == "2": logging.debug("selection 2, loading Create booking") - user.createBooking() + createBooking_cli(user) elif selection == "3": logging.debug("selection 3, Remove booking") - user.removeBooking() + removeBooking_cli(user) elif selection == "4": logging.debug("selection 4, Manage existing booking") - user.veiwBookings() - user.updateBooking() + manageBookings_cli(user) elif selection == "5": logging.debug("selection 5, Create ticket") user.createTicket() @@ -113,7 +183,7 @@ def staffUser_options_cli(user:StaffUser) -> None: def adminUser_options_cli(user:AdminUser) -> None: logging.debug("loaded into adminUser_options_cli.") while True: - selection = input("Menu options:\n" + selection = input("\nMenu options:\n" " 1. View bookings\n" " 2. Create booking \n" " 3. Remove booking\n" @@ -188,7 +258,7 @@ def adminUser_options_cli(user:AdminUser) -> None: def managerUser_options_cli(user:ManagerUser) -> None: logging.debug("loaded into managerUser_options_cli.") while True: - selection = input("Menu options:\n" + selection = input("\nMenu options:\n" " 1. View bookings\n" " 2. Create booking \n" " 3. Remove booking\n" @@ -333,9 +403,10 @@ def encrypt(string:str) -> str: def main_cli() -> None: print("\n\nSTARTING CINEMA MANAGEMENT SYSTEM.\n\n") # test db is connected.... - #if not getConnection(): - # logging.critical("Database cannot connect, or dose not exist. \nClosing application.") - # exit() + if not get_connection(): + logging.critical("Database cannot connect, or dose not exist. \nClosing application.") + exit() + # cli loggin attempt print("To login please enter your credentials.\n") while True: username = encrypt(sanitize(input("username: "))) diff --git a/src/__pycache__/constants.cpython-38.pyc b/src/__pycache__/constants.cpython-38.pyc index 5ea3abf5d9a57105ebe07c9c1a834cae2e71d7a8..87b52b088241433803228ade4bd96969d18f15de 100644 Binary files a/src/__pycache__/constants.cpython-38.pyc and b/src/__pycache__/constants.cpython-38.pyc differ diff --git a/src/__pycache__/dbfunc.cpython-38.pyc b/src/__pycache__/dbfunc.cpython-38.pyc index 8346d03f6a931ec3d5de2fd06882ba260d0076ca..af1388cc55098aac94986f5c8c7e356c1403c902 100644 Binary files a/src/__pycache__/dbfunc.cpython-38.pyc and b/src/__pycache__/dbfunc.cpython-38.pyc differ diff --git a/src/__pycache__/staffUser.cpython-38.pyc b/src/__pycache__/staffUser.cpython-38.pyc index f2c28d2f5ea35cd2431b03f79b2148e91e4e7a19..e56a1ec292d1c9bcb4822fff91787f8ac3f0476b 100644 Binary files a/src/__pycache__/staffUser.cpython-38.pyc and b/src/__pycache__/staffUser.cpython-38.pyc differ diff --git a/src/dbfunc.py b/src/dbfunc.py index 828e58ab95364d930d8a4fdbc3fd5e90c5f26d97..fd4179cebca5fb1780b3cdba0ee294778e4e44f3 100644 --- a/src/dbfunc.py +++ b/src/dbfunc.py @@ -95,7 +95,8 @@ def insert_into_table(table:str, data:dict): columns = ', '.join(data.keys()) values = ', '.join(['%s'] * len(data)) query = f"INSERT INTO {table} ({columns}) VALUES ({values})" - cursor.execute(query, data.values()) + logging.debug(f"query='{query}', data.values={tuple(data.values())}") + cursor.execute(query, tuple(data.values())) conn.commit() logging.info("Data inserted successfully.") return True @@ -138,7 +139,9 @@ def update_table(table, data, condition): cursor = conn.cursor() set_clause = ', '.join([f"{key} = %s" for key in data.keys()]) query = f"UPDATE {table} SET {set_clause} WHERE {condition}" - cursor.execute(query, tuple(data.values())) + data_arry = tuple(data.values()) + logging.debug(f"query='{query}', data.values()={data_arry}") + cursor.execute(query, data_arry) conn.commit() logging.info("Data updated successfully.") return True diff --git a/src/staffUser.py b/src/staffUser.py index 2d9b4e443fea076b0e136f8b08f2e004db2df2d4..560b6c40639859ea6bf5187227f161b18635b7dd 100644 --- a/src/staffUser.py +++ b/src/staffUser.py @@ -74,54 +74,68 @@ class StaffUser: """ raise NotImplementedError() - def createBooking(self): + def createBooking(self, showing_id:int, seats:str): """ Adds booking to db and returns ticket if succsessful. """ - # input data and validation loop - while True: - print("Please input booking info.") + + # import showing data + showing_data = select_from_table_where(table="tblShowings", + selection="*", + condition=f"showing_id={showing_id}") + showing_data = showing_data[0] + logging.debug(type(showing_data)) + logging.debug(f"showing_data={showing_data}") + + # check if showing_data was returned from db + if showing_data != None: + # validate selected seats + seats = seats.split(" ") + logging.debug(f"seats.split={seats}") + seats = [int(x) for x in seats] # use while seats are int, remove when seats are str. + logging.debug(f"seats.int={seats}") + seating_cap = select_from_table_where(table="tblScreens", + selection="seating_capacity", + condition=f"screen_id={showing_data['screen_id']}") + seating_cap = seating_cap[0]['seating_capacity'] + logging.debug(f"seating_cap={seating_cap}") - showing_id = int(input("\nShowing ID:")) - seats = input("\nSeats in format '1' or '1 2 3' (no dupes):") - if showing_id != None and seats != None: - # import showing data - showing_data = select_from_table_where(table="tblShowings", - selection="*", - condition=f"showing_id={showing_id}") - showing_data = showing_data[0] - logging.debug(type(showing_data)) - logging.debug(f"showing_data={showing_data}") - # check if showing_data was returned from db - if showing_data != None: - # validate selected seats - seats = seats.split(" ") - logging.debug(f"seats.split={seats}") - seats = [int(x) for x in seats] # use while seats are int, remove when seats are str. - logging.debug(f"seats.int={seats}") - seating_cap = select_from_table_where(table="tblScreens", - selection="seating_capacity", - condition=f"screen_id={showing_data['screen_id']}") - seating_cap = seating_cap[0]['seating_capacity'] - logging.debug(f"seating_cap={seating_cap}") - # check if seat selection in range - if max(seats) <= int(seating_cap) and min(seats) > 0: - # showing_id and seats exist, and seat selection is in range now save to tblBookings - price = showing_data['price'] * len(seats) - insert_data=dict(user_id=self.user_id, showing_id=showing_data['showing_id'], seat_numbers=seats, total_price=price, booking_date=showing_data['show_time']) - logging.debug(f"insert_data={insert_data}") - insert_into_table(table="tblBookings", - data=insert_data) - return - - print("Invalid seating selection.") - - else: - print("Invalid showing_id.") + # check if seat selection in range + if max(seats) <= int(seating_cap) and min(seats) > 0: # if seats are str this needs reworking. + # now save to tblBookings + price = showing_data['price'] * len(seats) + seats_str = "" + + for i in range(len(seats)): + seats_str = seats_str + str(seats[i]) + "," - else: - print("Missing input please try again.") + seats_str = seats_str[:-1] + insert_data=dict(user_id=self.user_id, showing_id=showing_data['showing_id'], seat_numbers=seats_str, total_price=float(price), booking_date=showing_data['show_time']) + logging.debug(f"insert_data={insert_data}") + insert_into_table(table="tblBookings", + data=insert_data) + return True + + return "Invalid seating selection." # needs to be updated for non cli use + + else: + return "Invalid showing_id." # needs to be updated for non cli use + + def removeBooking(self, booking_id): + """ remove bookings from db + """ + logging.debug("called StaffUser.removeBooking method") + booking_exists = select_from_table_where(table="tblBookings", selection="booking_id", condition=f"booking_id={booking_id}") - + if booking_exists == None: + return False + + if delete_from_table(table="tblBookings", condition=f"booking_id={booking_id}"): + return True + else: + return "db error." # needs to be updated for non cli use + + + def veiwBookings(self) -> dict: """ Gets bookings from db @@ -131,23 +145,37 @@ class StaffUser: logging.debug(data) return data - def updateBooking(self, booking_id, user_id:int=None, showing_id:int=None, seat_numbers:list=None, total_price:float=None, booking_date=None): + def updateBooking(self, booking_id, **kwargs): + #user_id:int=None, showing_id:int=None, seat_numbers:list=None, total_price:float=None, booking_date=None): """ updates existing booking from db """ logging.debug("called manageBooking method") + logging.debug(f"kwargs={kwargs}, {type(kwargs)}") set_data = {} - if user_id is not None: - set_data.update({'user_id':user_id}) - if showing_id is not None: - set_data.update({'showing_id':showing_id}) - if seat_numbers is not None: - set_data.update({'seat_numbers':seat_numbers}) - if total_price is not None: - set_data.update({'total_price':total_price}) - if booking_date is not None: - set_data.update({'booking_date':booking_date}) + for key, value in kwargs.items(): + if value: + set_data.update({key: value}) + + #dict({key:value} for key, value in kwargs.items() if not value) + - update_table("tblBookings", data=set_data, condition=f"booking_id = {booking_id}") + + + """ + if kwargs['user_id'] != None or kwargs['user_id'] != "": + set_data.update({'user_id':kwargs['user_id']}) + if kwargs['showing_id'] != None or kwargs['showing_id'] != "": + set_data.update({'showing_id':kwargs['showing_id']}) + if kwargs['seat_numbers'] is not None or kwargs['seat_numbers'] != "": + set_data.update({'seat_numbers':kwargs['seat_numbers']}) + if kwargs['total_price'] is not None or kwargs['total_price'] != "": + set_data.update({'total_price':kwargs['total_price']}) + if kwargs['booking_date'] is not None or kwargs['booking_date'] != "": + set_data.update({'booking_date':kwargs['booking_date']}) + """ + logging.debug(f"set_data={set_data}, booking_id={booking_id}") + status = update_table("tblBookings", data=set_data, condition=f"booking_id = {booking_id}") + return status def veiwShowings(self): """ Gets showings from db