From 16ae51fb08f35bc4dda9adfcdbf84d6866b732af Mon Sep 17 00:00:00 2001 From: Andrea Date: Fri, 19 Jan 2024 01:15:20 +0100 Subject: [PATCH] [wip5] Client error display --- app.py | 2 +- ext.py | 14 +++++- room.py | 75 ------------------------------- tpl/blocks/room.html | 9 ++++ tpl/view_room.html | 2 +- utils.py | 103 +++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 123 insertions(+), 82 deletions(-) diff --git a/app.py b/app.py index 87bd8d1..d53b49b 100644 --- a/app.py +++ b/app.py @@ -140,7 +140,7 @@ async def welcome(request, order: Order, quota: Quotas): room_members.append(await app.ctx.om.get_order(code=member_id, cached=True)) tpl = app.ctx.tpl.get_template('welcome.html') - return html(tpl.render(order=order, quota=quota, room_members=room_members, pending_roommates=pending_roommates)) + return html(tpl.render(order=order, quota=quota, room_members=room_members, pending_roommates=pending_roommates, ROOM_ERROR_MESSAGES=ROOM_ERROR_MESSAGES)) @app.route("/manage/download_ticket") diff --git a/ext.py b/ext.py index 77db90b..e9afd1d 100644 --- a/ext.py +++ b/ext.py @@ -98,6 +98,7 @@ class Order: self.payment_provider = data['payment_provider'] self.comment = data['comment'] self.phone = data['phone'] + self.room_issues = [] self.loadAns() def loadAns(self): self.shirt_size = self.ans('shirt_size') @@ -130,6 +131,9 @@ class Order: self.telegram_username = self.ans('telegram_username').strip('@') if self.ans('telegram_username') else None def __getitem__(self, var): return self.data[var] + + def set_room_errors (self, to_set): + for s in to_set: self.room_issues.append (s) def ans(self, name): for p in self.data['positions']: @@ -220,6 +224,7 @@ class Order: self.pending_update = False self.time = -1 self.loadAns() + @dataclass class Quotas: @@ -255,9 +260,9 @@ class OrderManager: async def updateCache(self): t = time() if(t - self.lastCacheUpdate > CACHE_EXPIRE_TIME): - print("Re-filling cache!") + print("[TIME] Re-filling cache!") await self.fill_cache() - self.lastCacheUpdate = t + self.lastCacheUpdate = t def add_cache(self, order): self.cache[order.code] = order @@ -289,6 +294,11 @@ class OrderManager: self.remove_cache(o.code) else: self.add_cache(Order(o)) + self.lastCacheUpdate = time() + for o in self.cache.values(): + if o.code == o.room_id: + print(o.room_name) + await validate_room(None, o, self) async def get_order(self, request=None, code=None, secret=None, nfc_id=None, cached=False): diff --git a/room.py b/room.py index 2d9a5ee..8141c3a 100644 --- a/room.py +++ b/room.py @@ -1,6 +1,3 @@ -from email.mime.text import MIMEText -from messages import ROOM_ERROR_MESSAGES -import smtplib from sanic.response import html, redirect, text from sanic import Blueprint, exceptions from random import choice @@ -360,78 +357,6 @@ async def confirm_room(request, order: Order, quotas: Quotas): return redirect('/manage/welcome') -async def unconfirm_room_by_order(order, throw=True, request=None): - if not order.room_confirmed and throw: - raise exceptions.BadRequest("Room is not confirmed!") - - ppl = get_people_in_room_by_code(request, order.code) - for p in ppl: - await p.edit_answer('room_confirmed', "False") - await p.send_answers() - -async def validate_room(request, order): - check, room_errors, member_orders = await check_room(request, order) - if check == True: return - try: - # Build message - issues_str = "" - for err in room_errors: - if err in ROOM_ERROR_MESSAGES: - issues_str += f" - {ROOM_ERROR_MESSAGES['err']}" - memberMessages = [] - for member in member_orders: - msg = MIMEText(f"Hello {member.name}!\n\nWe had to unconfirm your room {order.room_name} due to th{'ese issues' if len(room_errors) > 1 else 'is issue'}:\n{issues_str}\n\nPlease contact your room's owner or contact our support for further informations at https://furizon.net/contact/.\nThank you") - msg['Subject'] = '[Furizon] Your room cannot be confirmed' - msg['From'] = 'Furizon ' - msg['To'] = f"{member.name} <{member.email}>" - memberMessages.append(msg) - - if (len(memberMessages) == 0): return - - s = smtplib.SMTP_SSL(SMTP_HOST) - s.login(SMTP_USER, SMTP_PASSWORD) - for message in memberMessages: - s.sendmail(message['From'], message['to'], message.as_string()) - s.quit() - except Exception as ex: - if EXTRA_PRINTS: print(ex) - - -async def check_room(request, order): - room_errors = [] - room_members = [] - if not order or not order.room_id or order.room_id != order.code: return False, room_errors, room_members - - # This is not needed anymore you buy tickets already - #if quotas.get_left(len(order.room_members)) == 0: - # raise exceptions.BadRequest("There are no more rooms of this size to reserve.") - - bed_in_room = order.bed_in_room # Variation id of the ticket for that kind of room - for m in order.room_members: - if m == order.code: - res = order - else: - res = await request.app.ctx.om.get_order(code=m) - - # Room user in another room - if res.room_id != order.code: - room_errors.append('room_id_mismatch') - - if res.status != 'paid': - room_errors.append('unpaid') - - if res.bed_in_room != bed_in_room: - room_errors.append('type_mismatch') - - if res.daily: - room_errors.append('daily') - - room_members.append(res) - - if len(room_members) != order.room_person_no and order.room_person_no != None: - room_errors.append('capacity_mismatch') - return len(room_errors) == 0, room_errors, room_members - async def get_room (request, code): order_data = await request.app.ctx.om.get_order(code=code) if not order_data or not order_data.room_owner: return None diff --git a/tpl/blocks/room.html b/tpl/blocks/room.html index df3c548..82a0cb0 100644 --- a/tpl/blocks/room.html +++ b/tpl/blocks/room.html @@ -14,6 +14,15 @@ {% if order.room_id and not order.room_confirmed %}

⚠️ Your room hasn't been confirmed yet. Unconfirmed rooms are subject to changes by the staff as we optimize for hotel capacity.

{% endif %} + {% if order.room_id and len(order.room_issues) > 0 %} +

⚠️ There are some issues with your room: +

+

+ {% endif %} {# Show notice if the room is confirmed #} {% if order.room_confirmed %} diff --git a/tpl/view_room.html b/tpl/view_room.html index f998072..4ecadd9 100644 --- a/tpl/view_room.html +++ b/tpl/view_room.html @@ -17,7 +17,7 @@ + onload="window.location.href = '/manage/noseocount/'"> diff --git a/utils.py b/utils.py index 6a1ba1a..9b088d3 100644 --- a/utils.py +++ b/utils.py @@ -2,6 +2,9 @@ from os.path import join from sanic import exceptions from config import * import httpx +from email.mime.text import MIMEText +from messages import ROOM_ERROR_MESSAGES +import smtplib METADATA_TAG = "meta_data" VARIATIONS_TAG = "variations" @@ -133,10 +136,104 @@ async def get_order_by_code(request, code, throwException=False): raise exceptions.BadRequest(f"[getOrderByCode] Code {code} not found!") return res -def get_people_in_room_by_code(request, code): - c = request.app.ctx.om.cache +def get_people_in_room_by_code(request, code, om=None): + if not om: om = request.app.ctx.om + c = om.cache ret = [] for person in c.values(): if person.room_id == code: ret.append(person) - return ret \ No newline at end of file + return ret + +async def unconfirm_room_by_order(order, throw=True, request=None, om=None): + if not om: om = request.app.ctx.om + if not order.room_confirmed: + if throw: + raise exceptions.BadRequest("Room is not confirmed!") + else: + return + + ppl = get_people_in_room_by_code(request, order.code, om) + for p in ppl: + await p.edit_answer('room_confirmed', "False") + await p.send_answers() + +async def validate_room(request, order, om): + if not om: om = request.app.ctx.om + # Validate room + check, room_errors, member_orders = await check_room(request, order, om) + if check == True: return + print(f'[ROOM VALIDATION FAILED] {order.code} has failed room validation.', room_errors) + order.set_room_errors(room_errors) + + # End here if room is not confirmed + if not order.room_confirmed: return + + # Unconfirm and email users about the room + await unconfirm_room_by_order(order, False, None, om) + try: + # Build message + issues_str = "" + for err in room_errors: + if err in ROOM_ERROR_MESSAGES: + issues_str += f" - {ROOM_ERROR_MESSAGES[err]}" + + memberMessages = [] + + for member in member_orders: + msg_text = f"Hello {member.name}!\n\n" + msg_text += f"We had to unconfirm your room '{order.room_name}'" + msg_text += f" due to th{'ese issues' if len(room_errors) > 1 else 'is issue'}:\n{issues_str}\n\n" + msg_text += f"Please contact your room's owner or contact our support for further informations at https://furizon.net/contact/.\nThank you" + msg = MIMEText(msg_text) + msg['Subject'] = '[Furizon] Your room cannot be confirmed' + msg['From'] = 'Furizon ' + msg['To'] = f"{member.name} <{member.email}>" + memberMessages.append(msg) + + if len(memberMessages) == 0: return + + s = smtplib.SMTP_SSL(SMTP_HOST, 587) + s.login(SMTP_USER, SMTP_PASSWORD) + for message in memberMessages: + s.sendmail(message['From'], message['to'], message.as_string()) + s.quit() + except Exception as ex: + if EXTRA_PRINTS: print('could not send emails', ex) + + +async def check_room(request, order, om=None): + room_errors = [] + room_members = [] + if not om: om = request.app.ctx.om + if not order or not order.room_id or order.room_id != order.code: return False, room_errors, room_members + + # This is not needed anymore you buy tickets already + #if quotas.get_left(len(order.room_members)) == 0: + # raise exceptions.BadRequest("There are no more rooms of this size to reserve.") + + bed_in_room = order.bed_in_room # Variation id of the ticket for that kind of room + for m in order.room_members: + if m == order.code: + res = order + else: + res = await om.get_order(code=m) + + # Room user in another room + if res.room_id != order.code: + room_errors.append('room_id_mismatch') + + if res.status != 'paid': + room_errors.append('unpaid') + + if res.bed_in_room != bed_in_room: + room_errors.append('type_mismatch') + + if res.daily: + room_errors.append('daily') + + room_members.append(res) + + if len(room_members) != order.room_person_no and order.room_person_no != None: + room_errors.append('capacity_mismatch') + return len(room_errors) == 0, room_errors, room_members \ No newline at end of file