def finish_current_order(self): """ Finished the current order """ # Grab the list of added meals from the Current Order View meals_list = self._current_order_view.added_meals order_form = self._current_order_view.order_form OrdersService.create_new_order(meals_list, order_form) # TODO: Only reset, if every step before succeeded! # Reset Current Order View self._current_order_view.remove_all()
def on_tile_clicked_async(self, order, new_state): if REFS.MAIN_STATION: # If we are in CashDesk: OrdersService.update_order(order, active=True) # Send Message to other station about order creation (fire and forget) OrderMessagingService.notify_of_changes( changed_order=order, prefix=REFS.ORDER_CHANGED_PREFIX) self.show_view() else: OrderMessagingService.request_order_update(order=order, state=new_state)
def finish_current_order(self): """ Finished the current order """ new_order = None # Grab the list of added meals from the Current Order View meals_list = self._current_order_view.added_meals order_form = self._current_order_view.order_form try: new_order = OrdersService.create_new_order(meals_list, order_form) except: print("Creating new order failed.") raise if new_order == None: return self.show_receipt(order=new_order) # Send Message to other station about order creation (fire and forget) OrderMessagingService.notify_of_changes( changed_order=new_order, prefix=REFS.ORDER_CREATED_PREFIX) # Reset Current Order View self._current_order_view.remove_all()
def initialize(self, debug: bool = False): """ Has to be called, when the GUI is finished with initialization. """ self._main_cycle_thread() ##### Handler Registration # EncryptionHandler self._encryption_handler = EncryptionHandler(key=REFS.PUBLIC_KEY_16BIT) # Initialize database handler self._database_handler = DatabaseHandler(debug=debug) # Initialize network handler self._network_handler = NetworkHandler(main_station = REFS.MAIN_STATION) # Start continous receive-loop self._network_handler.start_receive_loop() self._secondary_cycle_thread() ##### Service Registration # Initialize meals service (which is using the database handler) self._meals_service = MealsService() self._orders_service = OrdersService() self._order_messaging_service = OrderMessagingService() # If the db connection has been established: trigger the event if self._database_handler.CONNECTION_READY: self._db_connection_ready_event()
def finish_current_order_async(self, meal, order_type): try: new_order = OrdersService.create_new_order([meal], order_type) except: print("Creating new order failed.") raise if new_order == None: return new_order._price = new_order.calculate_price() self._set_breadcrumb_text( text= f"Letzte Bestellung: #{new_order.id} {meal.name} - {OrdersService.convert_timestamp(new_order.timestamp)} - {new_order.price_str}€" ) #NotificationService.show_toast( # title=REFS.ORDER_SUMMARY_TOAST[0], # text=REFS.ORDER_SUMMARY_TOAST[1].format(new_order.id, new_order.meals[0].name, f"{new_order.price_str} {REFS.CURRENCY}") #) # Send Message to other station about order creation OrderMessagingService.notify_of_changes( changed_order=new_order, prefix=REFS.ORDER_CREATED_PREFIX)
def update_view_and_database_content(self): # Get all orders from the database sorted by their timestamp orders_sorted_by_timestamp = OrdersService.get_orders( order_by=f"{REFS.ORDERS_TABLE_TIMESTAMP} DESC") # Safe the result in this class's array self.order_items.clear() self.order_items.extend(orders_sorted_by_timestamp) self.update_view()
def clear_history(self): if REFS.MAIN_STATION: if OrdersService.delete_from_table( condition= f"{REFS.ORDERS_TABLE_ACTIVE}='{REFS.ORDERS_TABLE_ACTIVE_FALSE}'", confirm=True): self.update_view_and_database_content() else: OrderMessagingService.request_table_deletion(only_inactive=True)
def edit_order_command(self): # Step 1: Connect to database and check if the order is still in state "OPEN" or "CHANGED" # Still "OPEN" or "CHANGED"? # -> Y: Continue with Step 2 # -> N: Disable the edit button and return from this method results = OrdersService.get_orders( row_filter=f"{REFS.ORDERS_TABLE_ID}={self._order.id}") if results == None or len(results) == 0 or results[0] == "": raise RuntimeError("Order doesn't exist in the database") new_order_obj = OrdersService.convert_to_order_object(results[0]) if new_order_obj.state != REFS.OPEN and new_order_obj.state != REFS.CHANGED: self.edit.config(state="disabled") return # Step 2: Open the actual editor view self.expand_button_command(mode=HistoryItem.EDIT_CONTENT_MODE)
def update_view_and_database_content(self): all_active_orders = OrdersService.get_orders( # Ordered by timestamp (newest first) order_by=f"{REFS.ORDERS_TABLE_TIMESTAMP} ASC", # Only orders that are active (column 'active' = 'Y') row_filter= f"{REFS.ORDERS_TABLE_ACTIVE}='{REFS.ORDERS_TABLE_ACTIVE_TRUE}'") self.page_system.update(all_active_orders) self.update_view()
def _save_order(self): if REFS.MAIN_STATION: OrdersService.update_order(self._changed_order) # Send Message to other station about order creation (fire and forget) OrderMessagingService.notify_of_changes( changed_order=self._changed_order, prefix=REFS.ORDER_CHANGED_PREFIX) else: OrderMessagingService.request_order_update( order=self._changed_order, form=self._changed_order.form) self._order = self._changed_order.copy() self.form.config(text=OrdersService.convert_form(self._order.form)) self.state.config(text=OrdersService.convert_status(self._order.state)) self.state.config( background=REFS.ORDER_STATE_COLORS[self._order.state]) if self._order.state != REFS.OPEN and self._order.state != REFS.CHANGED: self.edit.config(state="disabled")
def update_view(self): if len(self.page_system.current_items) > len(self._order_tiles): raise RuntimeError("More items on the page than allowed.") for idx in range(0, len(self._order_tiles)): if idx >= len(self.page_system.current_items): # Make order tile empty self._order_tiles[idx].empty_tile(self._background) else: # Fill order tile with order content order = self.page_system.current_items[idx] new_order_obj = OrdersService.convert_to_order_object(order) self._order_tiles[idx].order = new_order_obj
def _update_content(self): if self._order == None: return timestamp_str = OrdersService.convert_timestamp(self._order.timestamp) self._id_label.config(text=f"#{self._order.id}") self._timestamp_label.config(text=timestamp_str) self._form_label.config(text=REFS.ORDER_FORMS[self._order.form]) self._state_label.config(text=REFS.ORDER_STATES[self._order.state]) self._set_meals_list_text() self.update_colors( background_light=REFS.ORDER_STATE_COLORS[self._order.state], background_dark=REFS.ORDER_STATE_COLORS_BGD[self._order.state])
def __init__(self, parent, order, background='white'): super().__init__(parent=parent, height=HistoryItem.HEIGHT, background='#F4F4F4') self._background = '#F4F4F4' self._order = OrdersService.convert_to_order_object(order) self.expanded = False self._changed_order = self._order.copy() self.edit_view_shown = False self.meals_view_shown = False column_names: [] = OrdersService.get_column_names() self._edit_img = IMAGES.create(IMAGES.EDIT) self._check_img = IMAGES.create(IMAGES.CHECK_MARK) self._down_img = IMAGES.create(IMAGES.DOWN) self._up_img = IMAGES.create(IMAGES.UP) self._empty_img = IMAGES.create(IMAGES.EMPTY) ########## COLUMNS ########## self.row_frame = Frame(master=self, background=background, height=HistoryItem.HEIGHT) self.row_frame.pack(side=TOP, fill='x') self.row_frame.pack_propagate(0) self.meals_frame = Frame(master=self, background='#F4F4F4') self.set_meals_content() self.edit_frame = Frame(master=self, background='#F4F4F4') self.set_edit_view() ##### TIMESTAMP ##### self.timestamp = Label(master=self.row_frame, text=OrdersService.convert_timestamp( self._order.timestamp, extended=True), font=Fonts.xsmall(), background=background, width=18) self.timestamp.pack(side=LEFT, padx=HistoryView.PADX_COL) ##### NUMBER ##### self.number = Label(master=self.row_frame, text=f"#{self._order.id}", font=Fonts.xsmall(bold=True), background=background, width=8) self.number.pack(side=LEFT, padx=HistoryView.PADX_COL) ##### FORM ##### self.form = Label(master=self.row_frame, text=OrdersService.convert_form(self._order.form), font=Fonts.xsmall(), background=background, width=10) self.form.pack(side=LEFT, padx=HistoryView.PADX_COL) ##### PRICE ##### self.price = Label(master=self.row_frame, text=f"{self._order.price_str}{REFS.CURRENCY}", font=Fonts.xsmall(), background=background, width=6) self.price.pack(side=LEFT, padx=HistoryView.PADX_COL) ##### EDIT BUTTON ##### self.edit_container = Frame(master=self.row_frame, width=HistoryView.EDIT_HEADER_WIDTH, height=60, bg=background) self.edit_container.pack(side=RIGHT, padx=HistoryView.PADX_COL) self.edit = Button(master=self.edit_container, image=self._edit_img, command=self.edit_order_command) self.edit.place(relx=0.5, rely=0.5, anchor="center") self.initial_button_background = self.edit.cget('background') if self._order.state != REFS.OPEN and self._order.state != REFS.CHANGED: self.edit.config(state="disabled") ##### EXPAND BUTTON ##### self.expand_container = Frame(master=self.row_frame, width=HistoryView.EXPAND_HEADER_WIDTH, height=60, bg=background) self.expand_container.pack(side=RIGHT, padx=(HistoryView.PADX_COL, 0)) expand_button_cmd = partial(self.expand_button_command, HistoryItem.MEALS_CONTENT_MODE) self.expand = Button(master=self.expand_container, image=self._down_img, command=expand_button_cmd) self.expand.place(relx=0.5, rely=0.5, anchor="center") ##### ACTIVE ##### active_i = column_names.index(REFS.ORDERS_TABLE_ACTIVE) self.active = Label(master=self.row_frame, text=OrdersService.convert_active(order[active_i]), font=Fonts.xsmall(), background=background, width=8) self.active.pack(side=RIGHT, padx=HistoryView.PADX_COL) ##### STATUS ##### state_i = column_names.index(REFS.ORDERS_TABLE_STATE) self.state = Label(master=self.row_frame, text=OrdersService.convert_status(order[state_i]), font=Fonts.xsmall(), background=REFS.ORDER_STATE_COLORS[int( order[state_i])], width=10) self.state.pack(side=RIGHT, padx=HistoryView.PADX_COL)
def reset_order_counter(self): if REFS.MAIN_STATION: if OrdersService.truncate_table(): self.update_view_and_database_content() else: OrderMessagingService.request_table_deletion(only_inactive=False)
def process_message(self, message: str): """ Gets called, whenever the network handler receives a message, that is for this specific service. message: contains only the main body; no service- and msg-id """ print("Message to process:", message) # Message says: DB content has changed if message.startswith(REFS.DB_CHANGED_PREFIX): if not message[1:].startswith(REFS.SILENT_PREFIX): order_id = message[2:] if order_id == "0": if OrderMessagingService.AUTO_REFRESH_ENABLED: OrderMessagingService.on_database_changed_event() return toast_title = "DB CHANGED" toast_text = "<text>" # More precise: a new order has been created if message[1:].startswith(REFS.ORDER_CREATED_PREFIX): order_timestamp = OrdersService.get_orders( row_filter=f"{REFS.ORDERS_TABLE_ID}={order_id}", columns=[f"{REFS.ORDERS_TABLE_TIMESTAMP}"])[0][0] order_timestamp = OrdersService.convert_timestamp( order_timestamp) toast_title = REFS.ORDER_CREATED_TOAST[0] toast_text = REFS.ORDER_CREATED_TOAST[1].format( order_id, order_timestamp) # More precise: a new order has been changed elif message[1:].startswith(REFS.ORDER_CHANGED_PREFIX): # First: get the order's current data result = OrdersService.get_orders( row_filter=f"{REFS.ORDERS_TABLE_ID}={order_id}") if result == None or len(result) == 0: raise RuntimeError( "The given order can not be changed because it's not in the database." ) changed_order = OrdersService.convert_to_order_object( result[0]) # order_details = OrdersService.get_orders( # row_filter=f"{REFS.ORDERS_TABLE_ID}={order_id}", # columns=[f"{REFS.ORDERS_TABLE_TIMESTAMP}", f"{REFS.ORDERS_TABLE_STATE}"] # )[0] order_timestamp = OrdersService.convert_timestamp( changed_order.timestamp) # order_state = int(order_details[1]) order_change = f"Status > {REFS.ORDER_STATES[changed_order.state]}" # OrdersService.handle_timer(changed_order) toast_title = REFS.ORDER_CHANGED_TOAST[0] toast_text = REFS.ORDER_CHANGED_TOAST[1].format( order_id, order_timestamp, order_change) #NotificationService.show_toast( # title=toast_title, # text=toast_text, # keep_alive=False #) else: # SILENT prefix if message[2:].startswith(REFS.DELETING_NOT_CONFIRMED): messagebox.showwarning( title="Delete response", message="Deleting from table has been denied.") elif message[2:].startswith(REFS.DELETING_CONFIRMED): print("Deleting worked") # Fire event to inform subscribed classes, like views OrderMessagingService.on_database_changed_event() # Message says: Request to change given order in DB elif message.startswith( REFS.ORDER_CHANGE_REQUEST_PREFIX) and REFS.MAIN_STATION: order_id = message[2:-1] change = message[-1:] print("Order id:", order_id) print("Change to:", change) # First: get the order's current data result = OrdersService.get_orders( row_filter=f"{REFS.ORDERS_TABLE_ID}={order_id}") if result == None or len(result) == 0: raise RuntimeError( "The given order can not be changed because it's not in the database." ) old_order = OrdersService.convert_to_order_object(result[0]) if message[1:].startswith(REFS.ORDER_STATUS_CHANGED_PREFIX): old_order.state = int(change) elif message[1:].startswith(REFS.ORDER_TYPE_CHANGED_PREFIX): old_order.form = int(change) OrdersService.update_order(old_order, active=True) ## Send Message to other station about order creation #OrderMessagingService.notify_of_changes( # changed_order=old_order, # prefix=REFS.ORDER_CHANGED_PREFIX #) # Fire event to inform subscribed classes, like views OrderMessagingService.on_database_changed_event() # Message says: Request to delete rows in orders table elif message.startswith( REFS.CLEAR_TABLE_REQUEST_PREFIX) and REFS.MAIN_STATION: clear_type = message[1:] result = False if clear_type == REFS.DELETE_INACTIVE_PREFIX: result = OrdersService.delete_from_table( condition= f"{REFS.ORDERS_TABLE_ACTIVE}='{REFS.ORDERS_TABLE_ACTIVE_FALSE}'", confirm=True) elif clear_type == REFS.DELETE_ALL_PREFIX: result = OrdersService.truncate_table() addinfo = REFS.DELETING_NOT_CONFIRMED if result: # Fire event to inform subscribed classes, like views OrderMessagingService.on_database_changed_event() addinfo = REFS.DELETING_CONFIRMED OrderMessagingService.notify_of_changes(changed_order=None, prefix=REFS.SILENT_PREFIX, additional_prefix=addinfo)
def __init__(self, parent, order, background='white'): super().__init__( parent=parent, height=800, background=background ) self._order = order self._timestamp_str = OrdersService.convert_timestamp( timestamp=order.timestamp, extended=True ) self._background = background ########## COLUMNS ########## self.text_container = Frame( master=self, background=background ) self.text_container.pack(side=TOP, fill='x', padx=5, pady=5) receipt_text_lines = self.create_text(order, raw_array=True) self._raw_lines = [] Fonts.family(family="Consolas", sustain=True) for line in receipt_text_lines: self.row_frame = Frame( master=self.text_container, background=background ) self.row_frame.pack(side=TOP, fill='x') content = line line_components = line.split(Receipt.DEL) bold = False size = 1 if len(line_components) >= 1: content = line_components[len(line_components) - 1] for index,comp in enumerate(line_components): if index != (len(line_components) - 1): if comp == Receipt.LARGE: size = 2 elif comp == Receipt.SMALL: size = 0 elif comp == Receipt.BOLD: bold = True font = Fonts.medium(bold=bold) if size == 0: font = Fonts.small(bold=bold) elif size == 2: font = Fonts.xxlarge(bold=bold) self._raw_lines.append(content) self._text = Label( master=self.row_frame, text=content, background=background, font=font ) self._text.pack(side=LEFT)#, padx=5, pady=(5,0)) Fonts.family(family=Fonts.DEFAULT_FAMILY, sustain=False) self.update()