From 584e11d2b05b5e3900d929cd345e870cea49c7e2 Mon Sep 17 00:00:00 2001 From: Ruidy Nemausat Date: Sun, 15 Dec 2019 14:08:15 +0100 Subject: [PATCH] Synchronizes to MasterCalendar when new booking to avoid overbooking. Checks for duplicates also --- README.md | 7 ++- rental/bookings.py | 146 +++++++++++++++++++++------------------------ rental/pricing.py | 7 ++- rental/views.py | 3 +- 4 files changed, 79 insertions(+), 84 deletions(-) diff --git a/README.md b/README.md index ee9c028..89e59ec 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ Le visiteur doit pouvoir : - Ajout page/module de paiement - ajouter les témoignages depuis Booking, AirBnb, ajouter le lien - changer la couleur des liens hypertextes -- changer l'adresse de l'admin, personnaliser le back-end +- changer l'adresse de l'admin, personnaliser le back-end (design et les infos displayed per model) - ajouter un diaporama en bas de page de location ? - deploy on Heroku or somewhere else … don't care - change placeholders for dates, add a date picker @@ -98,8 +98,11 @@ Le visiteur doit pouvoir : - configure nginx server to serve media files - Centrer Bouton "Reserver" page location - Ajouter un titre "Disponibilités" au dessus du calendrier -- page réservation : égayer avec des petites photos … +- page réservation/services : égayer avec des petites photos … +- Are guest unique ? ## BUGS - La synchro ne gère pas les heures dans le calendriers. + +élminer les variables inutiles dans synchro_calendar diff --git a/rental/bookings.py b/rental/bookings.py index 24d2732..e5e335d 100644 --- a/rental/bookings.py +++ b/rental/bookings.py @@ -11,26 +11,7 @@ import pickle from villafleurie.settings import BASE_DIR -def get_bookings(place): - """ - returns a list of all related place reservations - """ - booked_dates = Reservation.objects.all() - return [booking for booking in booked_dates if booking.place.name == f"{place.name}"] - - -def check_availability(place, start_date, end_date): - """ - check if the related place is available during a given period - """ - bookings = get_bookings(place) - for booking in bookings: - if (booking.start <= start_date <= booking.end) or (booking.start <= end_date <= booking.end): - return False - return True - - -def synchronize_calendars(): +def synchronize_calendars(place): """ Get a complete list of existing bookings in calendar Creates reservation if not in db, update if already in db @@ -59,74 +40,85 @@ def synchronize_calendars(): pickle.dump(creds, token) service = build('calendar', 'v3', credentials=creds) + calendar = place.name calendars = { 'T2': "burik7aclvhc7vsboh06c179uo@group.calendar.google.com", 'T3': "fu7h30p0gk4a2p4nvo7nsbgpok@group.calendar.google.com" } now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time - for calendar in calendars: - print(f"Upcoming {calendar} events:") - events_result = service.events().list( - calendarId=calendars[calendar], - timeMin=now, - singleEvents=True, - orderBy='startTime').execute() - events = events_result.get('items', []) - if not events: - print('No upcoming events found.') - else: - for event in events: - reservation = { - 'place': calendar, - 'guest': event['summary'], - 'start': event['start'].get('dateTime', event['start'].get('date')), - 'end': event['end'].get('dateTime', event['end'].get('date')) - } - print(reservation) + # for calendar in calendars: + events_result = service.events().list( + calendarId=calendars[calendar], + timeMin=now, + singleEvents=True, + orderBy='startTime' + ).execute() + events = events_result.get('items', []) + if not events: + print('No upcoming events found.') + else: + for event in events: + reservation = { + 'place': calendar.strip(), + 'guest': event['summary'].strip(), + 'start': event['start'].get('dateTime', event['start'].get('date')).strip(), + 'end': event['end'].get('dateTime', event['end'].get('date')).strip() + } -# if booking not in db -> create -# if booking in db and modification_date_cal > update_date_db -> update -# try : create/update -# except : send a log message - try: - place = get_object_or_404(Place, name=calendar) - price = get_reservation_price( - place, reservation['start'], reservation['end']) + place = get_object_or_404(Place, name=calendar) + price = get_reservation_price( + place, reservation['start'], reservation['end']) + start = reservation['start'] + end = reservation['end'] - guest = Guest.objects.filter(name=reservation['guest']) - if not guest.exists(): - guest = Guest.objects.create(name=reservation['guest']) + guest = Guest.objects.filter(name=reservation['guest']) + if not guest.exists(): + guest = Guest.objects.create(name=reservation['guest']) + else: + # guest = guest[0] + guest = guest.first() - start = reservation['start'] - end = reservation['end'] + db_booking = Reservation.objects.filter( + guest=guest + ) - # print("here") + if not db_booking.exists(): + Reservation.objects.create( + place=place, + guest=guest, + start=start, + end=end, + price=price + ) + else: + db_booking.place = place, + db_booking.guest = guest, + db_booking.start = start, + db_booking.end = end, + db_booking.price = price - # db_booking = Reservation.objects.filter( - # guest=guest, - # # place=place, - # # start=start - # ) - # print("there") - db_booking = None - if not db_booking.exists(): - print("yo") - Reservation.objects.create( - place=place, - guest=guest, - start=start, - end=end, - price=price) - else: - db_booking = Reservation.objects.filter( - guest=reservation['guest'], - place=place, - start=start - ) - except: - print( - f"######## ERROR ! Can't create {guest} reservation ########") + +def get_bookings(place): + """ + Synchronize with Master calendar via a call to synchronize_calendar + Returns a list of all related place reservations + """ + synchronize_calendars(place) + booked_dates = Reservation.objects.filter(place=place) + # if booking.place.name == f"{place.name}"] + return [booking for booking in booked_dates] + + +def check_availability(place, start_date, end_date): + """ + check if the related place is available during a given period + """ + bookings = get_bookings(place) + for booking in bookings: + if (booking.start <= start_date <= booking.end) or (booking.start <= end_date <= booking.end): + return False + return True if __name__ == '__main__': diff --git a/rental/pricing.py b/rental/pricing.py index 019e346..25ab6e5 100644 --- a/rental/pricing.py +++ b/rental/pricing.py @@ -5,9 +5,10 @@ def get_reservation_price(place, start, end): """ Compute booking price as a function of place and dates """ - start = datetime.strptime(start, '%Y-%m-%d') - end = datetime.strptime(end, '%Y-%m-%d') - + if type(start) == str: + start = datetime.strptime(start, '%Y-%m-%d') + if type(end) == str: + end = datetime.strptime(end, '%Y-%m-%d') nights = (end - start).days return place.price * nights diff --git a/rental/views.py b/rental/views.py index 9734eba..a50f399 100644 --- a/rental/views.py +++ b/rental/views.py @@ -143,11 +143,10 @@ def calendar(request, place_name): """ returns a list of all related place reservations """ - synchronize_calendars() + # synchronize_calendars() booked_dates = Reservation.objects.all() bookings = [ booking for booking in booked_dates if booking.place.name == place_name] - # synchronize_calendars(sys.argv) context = { 'place_name': place_name, 'bookings': bookings