mirror of
https://github.com/Steffo99/greed.git
synced 2024-11-21 21:44:19 +00:00
Almost completed work on the orders menu
This commit is contained in:
parent
712fd29f6a
commit
c28675f395
3 changed files with 102 additions and 14 deletions
11
database.py
11
database.py
|
@ -148,6 +148,8 @@ class Transaction(TableDeclarativeBase):
|
||||||
user = relationship("User")
|
user = relationship("User")
|
||||||
# The value of this transaction. Can be both negative and positive.
|
# The value of this transaction. Can be both negative and positive.
|
||||||
value = Column(Integer, nullable=False)
|
value = Column(Integer, nullable=False)
|
||||||
|
# Refunded status: if True, ignore the value of this transaction when recalculating
|
||||||
|
refunded = Column(Boolean, default=False)
|
||||||
# Extra notes on the transaction
|
# Extra notes on the transaction
|
||||||
notes = Column(Text)
|
notes = Column(Text)
|
||||||
|
|
||||||
|
@ -190,8 +192,9 @@ class Admin(TableDeclarativeBase):
|
||||||
user_id = Column(BigInteger, ForeignKey("users.user_id"), primary_key=True)
|
user_id = Column(BigInteger, ForeignKey("users.user_id"), primary_key=True)
|
||||||
user = relationship("User")
|
user = relationship("User")
|
||||||
# Permissions
|
# Permissions
|
||||||
|
edit_products = Column(Boolean, default=True)
|
||||||
receive_orders = Column(Boolean, default=True)
|
receive_orders = Column(Boolean, default=True)
|
||||||
# TODO: unfinished
|
view_transactions = Column(Boolean, default=True)
|
||||||
|
|
||||||
# Extra table parameters
|
# Extra table parameters
|
||||||
__tablename__ = "admins"
|
__tablename__ = "admins"
|
||||||
|
@ -211,8 +214,12 @@ class Order(TableDeclarativeBase):
|
||||||
user = relationship("User")
|
user = relationship("User")
|
||||||
# Date of creation
|
# Date of creation
|
||||||
creation_date = Column(DateTime, nullable=False)
|
creation_date = Column(DateTime, nullable=False)
|
||||||
# Date of delivery, None if the item hasn't been delivered yet
|
# Date of delivery
|
||||||
delivery_date = Column(DateTime)
|
delivery_date = Column(DateTime)
|
||||||
|
# Date of refund: if null, product hasn't been refunded
|
||||||
|
refund_date = Column(DateTime)
|
||||||
|
# Refund reason: if null, product hasn't been refunded
|
||||||
|
refund_reason = Column(Text)
|
||||||
# List of items in the order
|
# List of items in the order
|
||||||
items = relationship("OrderItem")
|
items = relationship("OrderItem")
|
||||||
# Extra details specified by the purchasing user
|
# Extra details specified by the purchasing user
|
||||||
|
|
36
strings.py
36
strings.py
|
@ -113,6 +113,15 @@ menu_done = "✅️ Fatto"
|
||||||
# Menu: pay invoice
|
# Menu: pay invoice
|
||||||
menu_pay = "💳 Paga"
|
menu_pay = "💳 Paga"
|
||||||
|
|
||||||
|
# Menu: complete
|
||||||
|
menu_complete = "✅ Completa"
|
||||||
|
|
||||||
|
# Menu: refund
|
||||||
|
menu_refund = "✴️ Rimborsa"
|
||||||
|
|
||||||
|
# Menu: stop
|
||||||
|
menu_stop = "🛑 Interrompi"
|
||||||
|
|
||||||
# Menu: add to cart
|
# Menu: add to cart
|
||||||
menu_add_to_cart = "➕ Aggiungi"
|
menu_add_to_cart = "➕ Aggiungi"
|
||||||
|
|
||||||
|
@ -136,6 +145,10 @@ ask_product_image = "Che immagine vuoi che abbia il prodotto?"
|
||||||
ask_order_notes = "Vuoi lasciare un messaggio insieme all'ordine?\n" \
|
ask_order_notes = "Vuoi lasciare un messaggio insieme all'ordine?\n" \
|
||||||
"Sarà visibile al negoziante."
|
"Sarà visibile al negoziante."
|
||||||
|
|
||||||
|
# Refund product: reason?
|
||||||
|
ask_refund_reason = "Allega una motivazione a questo rimborso.\n" \
|
||||||
|
"Sarà visibile al cliente."
|
||||||
|
|
||||||
# Thread has started downloading an image and might be unresponsive
|
# Thread has started downloading an image and might be unresponsive
|
||||||
downloading_image = "Sto scaricando la tua foto!\n" \
|
downloading_image = "Sto scaricando la tua foto!\n" \
|
||||||
"Potrei metterci un po'... Abbi pazienza!\n" \
|
"Potrei metterci un po'... Abbi pazienza!\n" \
|
||||||
|
@ -168,6 +181,17 @@ payment_invoice_fee_label = "Supplemento carta"
|
||||||
notification_order_placed = "*️⃣ E' stato piazzato un nuovo ordine:\n" \
|
notification_order_placed = "*️⃣ E' stato piazzato un nuovo ordine:\n" \
|
||||||
"{order}"
|
"{order}"
|
||||||
|
|
||||||
|
# Notification: order has been completed
|
||||||
|
notification_order_completed = "✅ Un tuo ordine è stato completato!\n" \
|
||||||
|
"{order}"
|
||||||
|
|
||||||
|
# Notification: order has been refunded
|
||||||
|
notification_order_refunded = "✴️ Un tuo ordine è stato rimborsato!\n" \
|
||||||
|
"{order}\n" \
|
||||||
|
"\n" \
|
||||||
|
"Motivazione data dal negoziante:\n" \
|
||||||
|
"{reason}"
|
||||||
|
|
||||||
# Info: informazioni sul bot
|
# Info: informazioni sul bot
|
||||||
bot_info = 'Questo bot utilizza <a href="https://github.com/Steffo99/greed">greed</a>,' \
|
bot_info = 'Questo bot utilizza <a href="https://github.com/Steffo99/greed">greed</a>,' \
|
||||||
' un framework di @Steffo per i pagamenti su Telegram rilasciato sotto la' \
|
' un framework di @Steffo per i pagamenti su Telegram rilasciato sotto la' \
|
||||||
|
@ -180,15 +204,15 @@ success_product_edited = "✅ Il prodotto è stato aggiunto/modificato con succe
|
||||||
# Success: product has been added/edited to the database
|
# Success: product has been added/edited to the database
|
||||||
success_product_deleted = "✅ Il prodotto è stato eliminato con successo!"
|
success_product_deleted = "✅ Il prodotto è stato eliminato con successo!"
|
||||||
|
|
||||||
# Order: set as complete
|
|
||||||
order_complete = "✅ Completa"
|
|
||||||
|
|
||||||
# Order: set as refunded
|
|
||||||
order_refund = "✴️ Rimborsa"
|
|
||||||
|
|
||||||
# Success: order has been created
|
# Success: order has been created
|
||||||
success_order_created = "✅ L'ordine è stato inviato con successo!"
|
success_order_created = "✅ L'ordine è stato inviato con successo!"
|
||||||
|
|
||||||
|
# Success: order was marked as completed
|
||||||
|
success_order_completed = "✅ Hai segnato l'ordine #{order_id} come completato."
|
||||||
|
|
||||||
|
# Success: order was refunded successfully
|
||||||
|
success_order_refunded = "✴️ L'ordine #{order_id} è stato rimborsato con successo."
|
||||||
|
|
||||||
# Error: message received not in a private chat
|
# Error: message received not in a private chat
|
||||||
error_nonprivate_chat = "⚠️ Questo bot funziona solo in chat private."
|
error_nonprivate_chat = "⚠️ Questo bot funziona solo in chat private."
|
||||||
|
|
||||||
|
|
69
worker.py
69
worker.py
|
@ -184,11 +184,15 @@ class ChatWorker(threading.Thread):
|
||||||
# Return the photo array
|
# Return the photo array
|
||||||
return update.message.photo
|
return update.message.photo
|
||||||
|
|
||||||
def __wait_for_inlinekeyboard_callback(self) -> telegram.CallbackQuery:
|
def __wait_for_inlinekeyboard_callback(self, cancellable:bool=True) -> typing.Union[telegram.CallbackQuery, CancelSignal]:
|
||||||
"""Continue getting updates until an inline keyboard callback is received, then return it."""
|
"""Continue getting updates until an inline keyboard callback is received, then return it."""
|
||||||
while True:
|
while True:
|
||||||
# Get the next update
|
# Get the next update
|
||||||
update = self.__receive_next_update()
|
update = self.__receive_next_update()
|
||||||
|
# Ensure the update isn't a CancelSignal
|
||||||
|
if cancellable and isinstance(update, CancelSignal):
|
||||||
|
# Return the CancelSignal
|
||||||
|
return update
|
||||||
# Ensure the update is a CallbackQuery
|
# Ensure the update is a CallbackQuery
|
||||||
if update.callback_query is None:
|
if update.callback_query is None:
|
||||||
continue
|
continue
|
||||||
|
@ -685,17 +689,70 @@ class ChatWorker(threading.Thread):
|
||||||
|
|
||||||
def __orders_menu(self):
|
def __orders_menu(self):
|
||||||
"""Display a live flow of orders."""
|
"""Display a live flow of orders."""
|
||||||
|
# Create a cancel and a stop keyboard
|
||||||
|
stop_keyboard = telegram.InlineKeyboardMarkup([[telegram.InlineKeyboardButton(strings.menu_stop, callback_data="cmd_cancel")]])
|
||||||
|
cancel_keyboard = telegram.InlineKeyboardMarkup([[telegram.InlineKeyboardButton(strings.menu_cancel, callback_data="cmd_cancel")]])
|
||||||
# Send a small intro message on the Live Orders mode
|
# Send a small intro message on the Live Orders mode
|
||||||
self.bot.send_message(self.chat.id, strings.conversation_live_orders_start)
|
self.bot.send_message(self.chat.id, strings.conversation_live_orders_start, reply_markup=stop_keyboard)
|
||||||
# Create the order keyboard
|
# Create the order keyboard
|
||||||
order_keyboard = telegram.InlineKeyboardMarkup([[telegram.InlineKeyboardButton(strings.order_complete)],
|
order_keyboard = telegram.InlineKeyboardMarkup([[telegram.InlineKeyboardButton(strings.menu_complete, callback_data="order_complete")],
|
||||||
[telegram.InlineKeyboardButton(strings.order_refund)]])
|
[telegram.InlineKeyboardButton(strings.menu_refund, callback_data="order_refund")]])
|
||||||
# Display the past pending orders
|
# Display the past pending orders
|
||||||
orders = self.session.query(db.Order).filter(db.Order.delivery_date == None).all()
|
orders = self.session.query(db.Order).filter_by(delivery_date=None, refund_date=None).join(db.Transaction).join(db.User).all()
|
||||||
|
# Create a dict linking the message ids to the orders
|
||||||
|
order_dict: typing.Dict[int, db.Order] = {}
|
||||||
# Create a message for every one of them
|
# Create a message for every one of them
|
||||||
for order in orders:
|
for order in orders:
|
||||||
# Send the created message
|
# Send the created message
|
||||||
self.bot.send_message(self.chat.id, order.get_text(session=self.session), reply_markup=order_keyboard)
|
message = self.bot.send_message(self.chat.id, order.get_text(session=self.session), reply_markup=order_keyboard)
|
||||||
|
# Add the message to the order_dict
|
||||||
|
order_dict[message.message_id] = order
|
||||||
|
# Set the listening mode flag to True
|
||||||
|
self.listening_mode = True
|
||||||
|
while True:
|
||||||
|
# Wait for any message to stop the listening mode
|
||||||
|
update = self.__wait_for_inlinekeyboard_callback(cancellable=True)
|
||||||
|
# If the user pressed the stop button, exit listening mode
|
||||||
|
if isinstance(update, CancelSignal):
|
||||||
|
# Stop the listening mode
|
||||||
|
self.listening_mode = False
|
||||||
|
# If the user pressed the complete order button, complete the order
|
||||||
|
elif update.data == "order_complete":
|
||||||
|
# Find the order
|
||||||
|
order = order_dict[update.message.message_id]
|
||||||
|
# Mark the order as complete
|
||||||
|
order.completition_date = datetime.datetime.now()
|
||||||
|
# Commit the transaction
|
||||||
|
self.session.commit()
|
||||||
|
# Notify the admin of the completition
|
||||||
|
self.bot.send_message(self.chat.id, strings.success_order_completed.format(order_id=order.order_id))
|
||||||
|
# Notify the user of the completition
|
||||||
|
self.bot.send_message(order.user_id, strings.notification_order_completed.format(order=order.get_text(self.session)))
|
||||||
|
# If the user pressed the refund order button, refund the order...
|
||||||
|
elif update.data == "order_refund":
|
||||||
|
# Find the order
|
||||||
|
order = order_dict[update.message.message_id]
|
||||||
|
# Ask for a refund reason
|
||||||
|
self.bot.send_message(self.chat.id, strings.ask_refund_reason, reply_markup=cancel_keyboard)
|
||||||
|
# Wait for a reply
|
||||||
|
reply = self.__wait_for_regex("(.*)", cancellable=True)
|
||||||
|
# If the user pressed the cancel button, cancel the refund
|
||||||
|
if isinstance(reply, CancelSignal):
|
||||||
|
continue
|
||||||
|
# Mark the order as refunded
|
||||||
|
order.refund_date = datetime.datetime.now()
|
||||||
|
# Save the refund reason
|
||||||
|
order.refund_reason = reply
|
||||||
|
# Refund the credit, reverting the old transaction
|
||||||
|
order.transaction.refunded = True
|
||||||
|
# Restore the credit to the user
|
||||||
|
order.user.credit -= order.transaction.value
|
||||||
|
# Commit the changes
|
||||||
|
self.session.commit()
|
||||||
|
# Notify the shopkeeper of the successful refund
|
||||||
|
self.bot.send_message(self.chat.id, strings.success_order_refunded.format(order_id=order.order_id))
|
||||||
|
# Notify the user of the refund
|
||||||
|
self.bot.send_message(order.user_id, strings.notification_order_refunded.format(order=order.get_text(self.session), reason=reply))
|
||||||
|
|
||||||
|
|
||||||
def __graceful_stop(self):
|
def __graceful_stop(self):
|
||||||
|
|
Loading…
Reference in a new issue