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:
parent
214401a509
commit
aa96ac0f73
5 changed files with 72 additions and 36 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -102,4 +102,4 @@ ENV/
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
config/config.ini
|
config/config.ini
|
||||||
db.sqlite
|
*.sqlite
|
4
core.py
4
core.py
|
@ -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
|
||||||
|
|
14
database.py
14
database.py
|
@ -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,8 +241,15 @@ 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
|
||||||
|
elif self.refund_date is not None:
|
||||||
|
status_emoji = strings.emoji_refunded
|
||||||
|
else:
|
||||||
|
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(),
|
date=self.creation_date.isoformat(),
|
||||||
items=items,
|
items=items,
|
||||||
notes=self.notes if self.notes is not None else "",
|
notes=self.notes if self.notes is not None else "",
|
||||||
|
|
22
strings.py
22
strings.py
|
@ -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."
|
58
worker.py
58
worker.py
|
@ -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))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue