1
Fork 0
mirror of https://github.com/Steffo99/greed.git synced 2024-11-24 14:54:18 +00:00

Order display should be finished

This commit is contained in:
Steffo 2018-04-01 18:10:14 +02:00
parent 214401a509
commit aa96ac0f73
5 changed files with 72 additions and 36 deletions

2
.gitignore vendored
View file

@ -102,4 +102,4 @@ ENV/
.idea/ .idea/
config/config.ini config/config.ini
db.sqlite *.sqlite

View file

@ -5,6 +5,7 @@ import strings
import worker import worker
import configloader import configloader
def main(): def main():
"""The core code of the program. Should be run only in the main process!""" """The core code of the program. Should be run only in the main process!"""
@ -36,7 +37,8 @@ def main():
while True: while True:
# Get a new batch of 100 updates and mark the last 100 parsed as read # Get a new batch of 100 updates and mark the last 100 parsed as read
try: try:
updates = bot.get_updates(offset=next_update, timeout=int(configloader.config["Telegram"]["long_polling_timeout"])) updates = bot.get_updates(offset=next_update,
timeout=int(configloader.config["Telegram"]["long_polling_timeout"]))
# If the method times out... # If the method times out...
except telegram.error.TimedOut: except telegram.error.TimedOut:
# Increase the TimedOut counter # Increase the TimedOut counter

View file

@ -140,6 +140,7 @@ class Product(TableDeclarativeBase):
class Transaction(TableDeclarativeBase): class Transaction(TableDeclarativeBase):
"""A greed wallet transaction. """A greed wallet transaction.
Wallet credit ISN'T calculated from these, but they can be used to recalculate it.""" Wallet credit ISN'T calculated from these, but they can be used to recalculate it."""
# TODO: split this into multiple tables
# The internal transaction ID # The internal transaction ID
transaction_id = Column(Integer, primary_key=True) transaction_id = Column(Integer, primary_key=True)
@ -195,6 +196,8 @@ class Admin(TableDeclarativeBase):
edit_products = Column(Boolean, default=True) edit_products = Column(Boolean, default=True)
receive_orders = Column(Boolean, default=True) receive_orders = Column(Boolean, default=True)
view_transactions = Column(Boolean, default=True) view_transactions = Column(Boolean, default=True)
# Live mode enabled
live_mode = Column(Boolean, default=False)
# Extra table parameters # Extra table parameters
__tablename__ = "admins" __tablename__ = "admins"
@ -238,12 +241,19 @@ class Order(TableDeclarativeBase):
items = "" items = ""
for item in self.items: for item in self.items:
items += str(item) + "\n" items += str(item) + "\n"
return strings.order_format_string.format(id=self.order_id, if self.delivery_date is not None:
user=self.user.mention(), status_emoji = strings.emoji_completed
date=self.creation_date.isoformat(), elif self.refund_date is not None:
items=items, status_emoji = strings.emoji_refunded
notes=self.notes if self.notes is not None else "", else:
value=str(Price(-joined_self.transaction.value))) status_emoji = strings.emoji_not_processed
return status_emoji + " " + \
strings.order_number.format(id=self.order_id) + "\n" + \
strings.order_format_string.format(user=self.user.mention(),
date=self.creation_date.isoformat(),
items=items,
notes=self.notes if self.notes is not None else "",
value=str(Price(-joined_self.transaction.value)))
class OrderItem(TableDeclarativeBase): class OrderItem(TableDeclarativeBase):

View file

@ -14,9 +14,11 @@ in_stock_format_string = "{quantity} disponibili"
# Copies of a product in cart # Copies of a product in cart
in_cart_format_string = "{quantity} nel carrello" in_cart_format_string = "{quantity} nel carrello"
# Order number, displayed in the order info
order_number = "Ordine #{id}"
# Order info displayed string # Order info displayed string
order_format_string = "Ordine #{id}\n" \ order_format_string = "di {user}\n" \
"di {user}\n" \
"{value}\n" \ "{value}\n" \
"Creato {date}\n" \ "Creato {date}\n" \
"\n" \ "\n" \
@ -131,6 +133,15 @@ menu_add_to_cart = " Aggiungi"
# Menu: remove from cart # Menu: remove from cart
menu_remove_from_cart = " Rimuovi" menu_remove_from_cart = " Rimuovi"
# Emoji: unprocessed order
emoji_not_processed = "*️⃣ "
# Emoji: completed order
emoji_completed = ""
# Emoji: refunded order
emoji_refunded = "✴️"
# Add product: name? # Add product: name?
ask_product_name = "Come si deve chiamare il prodotto?" ask_product_name = "Come si deve chiamare il prodotto?"
@ -185,11 +196,11 @@ notification_order_placed = "*️⃣ E' stato piazzato un nuovo ordine:\n" \
"{order}" "{order}"
# Notification: order has been completed # Notification: order has been completed
notification_order_completed = "Un tuo ordine è stato completato!\n" \ notification_order_completed = "Un tuo ordine è stato completato!\n" \
"{order}" "{order}"
# Notification: order has been refunded # Notification: order has been refunded
notification_order_refunded = "✴️ Un tuo ordine è stato rimborsato!\n" \ notification_order_refunded = "Un tuo ordine è stato rimborsato!\n" \
"{order}\n" \ "{order}\n" \
"\n" \ "\n" \
"Motivazione data dal negoziante:\n" \ "Motivazione data dal negoziante:\n" \
@ -237,3 +248,6 @@ error_duplicate_name = "️⚠️ Esiste già un prodotto con questo nome."
# Error: not enough credit to order # Error: not enough credit to order
error_not_enough_credit = "⚠️ Non hai credito sufficiente per effettuare l'ordine." error_not_enough_credit = "⚠️ Non hai credito sufficiente per effettuare l'ordine."
# Error: order has already been cleared
error_order_already_cleared = "⚠️ Questo ordine è già stato processato."

View file

@ -42,8 +42,6 @@ class ChatWorker(threading.Thread):
self.queue = queuem.Queue() self.queue = queuem.Queue()
# The current active invoice payload; reject all invoices with a different payload # The current active invoice payload; reject all invoices with a different payload
self.invoice_payload = None self.invoice_payload = None
# Listening mode flag: if set, display the received orders in real time
self.listening_mode = False
def run(self): def run(self):
"""The conversation code.""" """The conversation code."""
@ -196,6 +194,8 @@ class ChatWorker(threading.Thread):
# 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
# Answer the callbackquery
self.bot.answer_callback_query(update.callback_query.id)
# Return the callbackquery # Return the callbackquery
return update.callback_query return update.callback_query
@ -378,11 +378,17 @@ class ChatWorker(threading.Thread):
self.session.commit() self.session.commit()
# Notify the user of the order result # Notify the user of the order result
self.bot.send_message(self.chat.id, strings.success_order_created) self.bot.send_message(self.chat.id, strings.success_order_created)
# Notify the admins (with Order Notifications enabled) of the new order created # Notify the admins (in Live Orders mode) of the new order
admins = self.session.query(db.Admin).filter_by(receive_orders=True).all() admins = self.session.query(db.Admin).filter_by(live_mode=True).all()
# Create the order keyboard
order_keyboard = telegram.InlineKeyboardMarkup(
[[telegram.InlineKeyboardButton(strings.menu_complete, callback_data="order_complete")],
[telegram.InlineKeyboardButton(strings.menu_refund, callback_data="order_refund")]])
# Notify them of the new placed order # Notify them of the new placed order
for admin in admins: for admin in admins:
self.bot.send_message(admin.user_id, f"{strings.notification_order_placed.format(order=order.get_text(self.session))}") self.bot.send_message(admin.user_id,
f"{strings.notification_order_placed.format(order=order.get_text(self.session))}",
reply_markup=order_keyboard)
def __order_status(self): def __order_status(self):
"""Display the status of the sent orders.""" """Display the status of the sent orders."""
@ -449,10 +455,10 @@ class ChatWorker(threading.Thread):
# Convert the amount to an integer # Convert the amount to an integer
value = Price(selection) value = Price(selection)
# Ensure the amount is within the range # Ensure the amount is within the range
if value > int(configloader.config["Payments"]["max_amount"]): if value > Price(int(configloader.config["Credit Card"]["max_amount"])):
self.bot.send_message(self.chat.id, strings.error_payment_amount_over_max.format(max_amount=Price(configloader.config["Payments"]["max_amount"]))) self.bot.send_message(self.chat.id, strings.error_payment_amount_over_max.format(max_amount=Price(configloader.config["Payments"]["max_amount"])))
continue continue
elif value < int(configloader.config["Payments"]["min_amount"]): elif value < Price(int(configloader.config["Credit Card"]["min_amount"])):
self.bot.send_message(self.chat.id, strings.error_payment_amount_under_min.format(min_amount=Price(configloader.config["Payments"]["min_amount"]))) self.bot.send_message(self.chat.id, strings.error_payment_amount_under_min.format(min_amount=Price(configloader.config["Payments"]["min_amount"])))
continue continue
break break
@ -702,40 +708,44 @@ class ChatWorker(threading.Thread):
[telegram.InlineKeyboardButton(strings.menu_refund, callback_data="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_by(delivery_date=None, refund_date=None).join(db.Transaction).join(db.User).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
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 # Set the Live mode flag to True
order_dict[message.message_id] = order self.admin.live_mode = True
# Set the listening mode flag to True # Commit the change to the database
self.listening_mode = True self.session.commit()
while True: while True:
# Wait for any message to stop the listening mode # Wait for any message to stop the listening mode
update = self.__wait_for_inlinekeyboard_callback(cancellable=True) update = self.__wait_for_inlinekeyboard_callback(cancellable=True)
# If the user pressed the stop button, exit listening mode # If the user pressed the stop button, exit listening mode
if isinstance(update, CancelSignal): if isinstance(update, CancelSignal):
# Stop the listening mode # Stop the listening mode
self.listening_mode = False self.admin.live_mode = False
break
# Find the order
# TODO: debug the regex?
order_id = re.search(strings.order_number.replace("{id}", "([0-9]+)"), update.message.text).group(1)
order = self.session.query(db.Order).filter(db.Order.order_id == order_id).one()
# Check if the order hasn't been already cleared
if order.delivery_date is not None or order.refund_date is not None:
# Notify the admin and skip that order
self.bot.edit_message_text(self.chat.id, strings.error_order_already_cleared)
break break
# If the user pressed the complete order button, complete the order # If the user pressed the complete order button, complete the order
elif update.data == "order_complete": if update.data == "order_complete":
# Find the order
order = order_dict[update.message.message_id]
# Mark the order as complete # Mark the order as complete
order.completition_date = datetime.datetime.now() order.delivery_date = datetime.datetime.now()
# Commit the transaction # Commit the transaction
self.session.commit() self.session.commit()
# Notify the admin of the completition # Update order message
self.bot.send_message(self.chat.id, strings.success_order_completed.format(order_id=order.order_id)) self.bot.edit_message_text(order.get_text(session=self.session), chat_id=self.chat.id,
message_id=update.message.message_id)
# Notify the user of the completition # Notify the user of the completition
self.bot.send_message(order.user_id, strings.notification_order_completed.format(order=order.get_text(self.session))) 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... # If the user pressed the refund order button, refund the order...
elif update.data == "order_refund": elif update.data == "order_refund":
# Find the order
order = order_dict[update.message.message_id]
# Ask for a refund reason # Ask for a refund reason
self.bot.send_message(self.chat.id, strings.ask_refund_reason, reply_markup=cancel_keyboard) self.bot.send_message(self.chat.id, strings.ask_refund_reason, reply_markup=cancel_keyboard)
# Wait for a reply # Wait for a reply
@ -753,8 +763,8 @@ class ChatWorker(threading.Thread):
order.user.credit -= order.transaction.value order.user.credit -= order.transaction.value
# Commit the changes # Commit the changes
self.session.commit() self.session.commit()
# Notify the shopkeeper of the successful refund # Update the order message
self.bot.send_message(self.chat.id, strings.success_order_refunded.format(order_id=order.order_id)) self.bot.edit_message_text(order.get_text(session=self.session), chat_id=self.chat.id, message_id=update.message.message_id)
# Notify the user of the refund # 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)) self.bot.send_message(order.user_id, strings.notification_order_refunded.format(order=order.get_text(self.session), reason=reply))