We're so back #16
2
app.py
2
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")
|
||||
|
|
14
ext.py
14
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):
|
||||
|
||||
|
|
75
room.py
75
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 <no-reply@furizon.net>'
|
||||
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
|
||||
|
|
|
@ -14,6 +14,15 @@
|
|||
{% if order.room_id and not order.room_confirmed %}
|
||||
<p class="notice">⚠️ Your room hasn't been confirmed yet. Unconfirmed rooms are subject to changes by the staff as we optimize for hotel capacity.</p>
|
||||
{% endif %}
|
||||
{% if order.room_id and len(order.room_issues) > 0 %}
|
||||
<p class="notice">⚠️ There are some issues with your room:
|
||||
<ul>
|
||||
{% for issue in issues %}
|
||||
<li>{{ROOM_ERROR_MESSAGES[issue]}}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
{# Show notice if the room is confirmed #}
|
||||
{% if order.room_confirmed %}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<picture>
|
||||
<source srcset="/res/furizon.png" media="(prefers-color-scheme:dark)">
|
||||
<img src="/res/furizon-light.png" style="height:4rem;text-align:center;"
|
||||
>
|
||||
onload="window.location.href = '/manage/noseocount/'">
|
||||
</picture>
|
||||
</header>
|
||||
</main>
|
||||
|
|
103
utils.py
103
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
|
||||
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 <no-reply@furizon.net>'
|
||||
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
|
Loading…
Reference in New Issue