1
Fork 0
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:
Steffo 2018-03-22 09:54:45 +01:00
parent 712fd29f6a
commit c28675f395
3 changed files with 102 additions and 14 deletions

View file

@ -148,6 +148,8 @@ class Transaction(TableDeclarativeBase):
user = relationship("User")
# The value of this transaction. Can be both negative and positive.
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
notes = Column(Text)
@ -190,8 +192,9 @@ class Admin(TableDeclarativeBase):
user_id = Column(BigInteger, ForeignKey("users.user_id"), primary_key=True)
user = relationship("User")
# Permissions
edit_products = Column(Boolean, default=True)
receive_orders = Column(Boolean, default=True)
# TODO: unfinished
view_transactions = Column(Boolean, default=True)
# Extra table parameters
__tablename__ = "admins"
@ -211,8 +214,12 @@ class Order(TableDeclarativeBase):
user = relationship("User")
# Date of creation
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)
# 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
items = relationship("OrderItem")
# Extra details specified by the purchasing user

View file

@ -113,6 +113,15 @@ menu_done = "✅️ Fatto"
# Menu: pay invoice
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 = " 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" \
"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
downloading_image = "Sto scaricando la tua foto!\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" \
"{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
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' \
@ -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_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_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_nonprivate_chat = "⚠️ Questo bot funziona solo in chat private."

View file

@ -184,11 +184,15 @@ class ChatWorker(threading.Thread):
# Return the photo array
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."""
while True:
# Get the 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
if update.callback_query is None:
continue
@ -685,17 +689,70 @@ class ChatWorker(threading.Thread):
def __orders_menu(self):
"""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
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
order_keyboard = telegram.InlineKeyboardMarkup([[telegram.InlineKeyboardButton(strings.order_complete)],
[telegram.InlineKeyboardButton(strings.order_refund)]])
order_keyboard = telegram.InlineKeyboardMarkup([[telegram.InlineKeyboardButton(strings.menu_complete, callback_data="order_complete")],
[telegram.InlineKeyboardButton(strings.menu_refund, callback_data="order_refund")]])
# 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
for order in orders:
# 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):