From be7bdec84f2878393618cd688ff116663b3a69b0 Mon Sep 17 00:00:00 2001 From: Ruidy Nemausat Date: Tue, 3 Dec 2019 13:39:43 +0100 Subject: [PATCH] Quotation returned after succesful booking --- .gitignore | 1 + README.md | 102 ++++++++++++++++------------- rental/models.py | 62 ++++++++++-------- rental/pricing.py | 32 +++++---- rental/templates/rental/merci.html | 28 ++++---- rental/views.py | 28 ++++---- 6 files changed, 139 insertions(+), 114 deletions(-) diff --git a/.gitignore b/.gitignore index eaba9a1..0379eab 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ rental/__pycache__ rental/migrations villafleurie/__pycache__ .DS_Store +.vscode/ diff --git a/README.md b/README.md index ec40e5e..f2f5c96 100644 --- a/README.md +++ b/README.md @@ -7,76 +7,88 @@ ## Projet Créer un site vitrine présentant l'activité de Villafleurie : -* location de logements : T2 et T3 -* navette entre l'aéroport, la gare maritime et la résidence -* découverte de l'archipel + +- location de logements : T2 et T3 +- navette entre l'aéroport, la gare maritime et la résidence +- découverte de l'archipel Le visiteur doit pouvoir : -* connaitre les disponibilité de chaque logement, -* leur tarif, -* pouvoir contacter les propriétaires, -* et pouvoir réserver + +- connaitre les disponibilité de chaque logement, +- leur tarif, +- pouvoir contacter les propriétaires, +- et pouvoir réserver ## Structure ### Pages 1. Page d'accueil -* Landing page -* CTA = "Réserver maintenant" + +- Landing page +- CTA = "Réserver maintenant" + 2. Page logement -* photos, -* disponibilités, -* tarif pour la période sélectionnée, + +- photos, +- disponibilités, +- tarif pour la période sélectionnée, + 3. Page réservation -* Entrer ses coordonnées -* Prépayer la réservation ou la caution, + +- Entrer ses coordonnées +- Prépayer la réservation ou la caution, + 4. Page remerciements -* Expliquer les prochaines étapes + +- Expliquer les prochaines étapes + 5. Page contact 6. Page légale ### Données 1. Logement : -* nom, -* photos, -* description, -* calendrier, -* tarif + +- nom, +- photos, +- description, +- calendrier, +- tarif 2. Client : -* nom, -* mail, -* téléphone, -* _réservation_ + +- nom, +- mail, +- téléphone, +- _réservation_ 3. Réservation : -* _client_, -* _logement_, -* dates de calendrier, + +- _client_, +- _logement_, +- dates de calendrier, 4. Témoignages : -* _client_, -* _reservation_, -* témoignage + +- _client_, +- _reservation_, +- témoignage ## TO DO -* Page service : navette + location -* Gestion du calendrier -..* Google calendar pour afficher les disponibilités -.. * Check si les dates choisies sont libres -* Module calcul prix réservation, afficher le résultat sur la page remerciement -ou envoyer devis par mail … -* 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 -* ajouter un diaporama en bas de page de location ? -* deploy on Heroku or somewhere else … don't care -* change placeholders for dates -* factoriser le code de réservation - +- Page service : navette + location +- Gestion du calendrier + .._ Google calendar pour afficher les disponibilités + .._ Check si les dates choisies sont libres +- Envoyer devis réservation par mail et notification aux hôtes +- 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 +- ajouter un diaporama en bas de page de location ? +- deploy on Heroku or somewhere else … don't care +- change placeholders for dates +- factoriser le code de réservation ## BUGS diff --git a/rental/models.py b/rental/models.py index 958a09e..5f7ab58 100644 --- a/rental/models.py +++ b/rental/models.py @@ -6,8 +6,8 @@ class Image(models.Model): def __str__(self): return self.alt - img=models.ImageField(upload_to='img/', null=True,blank=True) - alt=models.CharField(max_length=100) + img = models.ImageField(upload_to='img/', null=True, blank=True) + alt = models.CharField(max_length=100) class Place(models.Model): @@ -17,17 +17,18 @@ class Place(models.Model): def __str__(self): return self.name - name=models.CharField(max_length=10, unique=True) - description=models.TextField(blank=True) - info=models.TextField(blank=True) - subname=models.CharField(max_length=100, blank=True) - tagline=models.CharField(max_length=100, blank=True) - price=models.DecimalField(max_digits=6, decimal_places=2, null=True) - surface=models.IntegerField(null=True,blank=True) - beds=models.IntegerField(null=True,blank=True) - max_occupation=models.IntegerField(null=True,blank=True) - thumbnail=models.ForeignKey(Image, on_delete=models.CASCADE, blank=True, null=True) - images=models.ManyToManyField(Image, related_name = "places", blank=True) + name = models.CharField(max_length=10, unique=True) + description = models.TextField(blank=True) + info = models.TextField(blank=True) + subname = models.CharField(max_length=100, blank=True) + tagline = models.CharField(max_length=100, blank=True) + price = models.DecimalField(max_digits=6, decimal_places=2, null=True) + surface = models.IntegerField(null=True, blank=True) + beds = models.IntegerField(null=True, blank=True) + max_occupation = models.IntegerField(null=True, blank=True) + thumbnail = models.ForeignKey( + Image, on_delete=models.CASCADE, blank=True, null=True) + images = models.ManyToManyField(Image, related_name="places", blank=True) class Guest(models.Model): @@ -37,9 +38,9 @@ class Guest(models.Model): def __str__(self): return self.name - name=models.CharField(max_length=100) - email=models.EmailField(unique=True) - phone=PhoneNumberField(blank=True) + name = models.CharField(max_length=100) + email = models.EmailField(unique=True) + phone = PhoneNumberField(blank=True) class Reservation(models.Model): @@ -49,23 +50,26 @@ class Reservation(models.Model): def __str__(self): return "Réservation du {} par {}".format(self.place, self.guest) - place=models.ForeignKey(Place,on_delete=models.CASCADE) - guest=models.ForeignKey(Guest,on_delete=models.CASCADE) - message=models.TextField(blank=True) - start=models.DateField() - end=models.DateField() + place = models.ForeignKey(Place, on_delete=models.CASCADE) + guest = models.ForeignKey(Guest, on_delete=models.CASCADE) + message = models.TextField(blank=True) + start = models.DateField() + end = models.DateField() + price = models.DecimalField(max_digits=6, decimal_places=2, null=True) class Testimonial(models.Model): class Meta: - verbose_name="Témoignage" + verbose_name = "Témoignage" def __str__(self): - return self.author + return f"Témoignage de {self.author}" - author=models.CharField(max_length=100) - text=models.TextField() - picture=models.ImageField(upload_to='img/',null=True,blank=True) - link=models.URLField(null=True,blank=True) - guest=models.OneToOneField(Guest,on_delete=models.CASCADE,blank=True,null=True) - reservation=models.OneToOneField(Reservation,on_delete=models.CASCADE,blank=True,null=True) + author = models.CharField(max_length=100) + text = models.TextField() + picture = models.ImageField(upload_to='img/', null=True, blank=True) + link = models.URLField(null=True, blank=True) + guest = models.OneToOneField( + Guest, on_delete=models.CASCADE, blank=True, null=True) + reservation = models.OneToOneField( + Reservation, on_delete=models.CASCADE, blank=True, null=True) diff --git a/rental/pricing.py b/rental/pricing.py index 55c08fc..3b98d8a 100644 --- a/rental/pricing.py +++ b/rental/pricing.py @@ -1,20 +1,18 @@ -""" -Compute booking price as a function of place and dates -""" -from models import Place -from datetime import * -from django.shortcuts import get_object_or_404 +def get_reservation_price(place, start, end): + """ + Compute booking price as a function of place and dates + """ + nights = (end - start).days + return place.price * nights -place_name = 'T2' -start = datetime(2019, 11, 14) -end = datetime(2019, 11, 20) -stay = end-start -nights = stay.days - -def quotation(place_name, nights): +if __name__ == '__main__': + from rental.models import Place + from datetime import * + from django.shortcuts import get_object_or_404 + place_name = 'T2' place = get_object_or_404(Place, name=place_name) - return place.price_per_night * (end - start) - -x = quotation(place_name, nights) -print(x) + start = datetime(2019, 11, 14) + end = datetime(2019, 11, 20) + x = get_reservation_price(place_name, start, end) + print(x) diff --git a/rental/templates/rental/merci.html b/rental/templates/rental/merci.html index ebe041c..071d4ec 100644 --- a/rental/templates/rental/merci.html +++ b/rental/templates/rental/merci.html @@ -1,19 +1,24 @@ -{% extends 'rental/base.html' %} -{% load static %} - -{% block content %} +{% extends 'rental/base.html' %} {% load static %} {% block content %}
-

Merci pour votre réservation

- Nous avons enregistré la réservation de {{ guest.name }} du {{ place.name }}.
Nous nous recontactons rapidement !
+

Merci pour votre réservation

+ Nous avons enregistré la réservation du {{reservation.place.name}} + sous le nom de {{reservation.guest.name}} pour un montant de + {{reservation.price}}.
+ Nous nous recontactons rapidement ! +
-
- {% endblock %} diff --git a/rental/views.py b/rental/views.py index e97f27a..57eb74a 100644 --- a/rental/views.py +++ b/rental/views.py @@ -5,14 +5,15 @@ from django.urls import reverse_lazy from django.views.generic.base import TemplateView from .forms import ReservationForm from django.db import IntegrityError +from rental.pricing import get_reservation_price def index(request): places = Place.objects.all() temoignages = Testimonial.objects.all() context = { - 'places' : places, - 'temoignages' : temoignages + 'places': places, + 'temoignages': temoignages } return render(request, 'rental/index.html', context) @@ -24,8 +25,8 @@ def liste_location(request): imgs = place.images.all() images.append(imgs) context = { - 'places' : places, - 'images' : images + 'places': places, + 'images': images } return render(request, 'rental/list_place.html', context) @@ -34,11 +35,12 @@ def location(request, place_name='T2'): place = get_object_or_404(Place, name=place_name) images = place.images.all() context = { - 'place' : place, - 'images' : images + 'place': place, + 'images': images } if request.method == 'POST': - form = ReservationForm(request.POST)#, error_class=ParagraphErrorList) + # , error_class=ParagraphErrorList) + form = ReservationForm(request.POST) if form.is_valid(): name = form.cleaned_data['name'] email = form.cleaned_data['email'] @@ -58,16 +60,17 @@ def location(request, place_name='T2'): guest = guest.first() place = get_object_or_404(Place, name=place_name) + price = get_reservation_price(place, start, end) reservation = Reservation.objects.create( guest=guest, place=place, message=message, start=start, - end=end + end=end, + price=price ) context = { - 'guest': guest, - 'place': place + 'reservation': reservation } return render(request, 'rental/merci.html', context) except IntegrityError: @@ -82,7 +85,8 @@ def location(request, place_name='T2'): def reservation(request): if request.method == 'POST': - form = ReservationForm(request.POST)#, error_class=ParagraphErrorList) + # , error_class=ParagraphErrorList) + form = ReservationForm(request.POST) if form.is_valid(): name = form.cleaned_data['name'] email = form.cleaned_data['email'] @@ -117,7 +121,7 @@ def reservation(request): form.errors['internal'] = "Une erreur interne est apparue. Merci de recommencer votre requête." else: form = ReservationForm() - context = {'form' : form} + context = {'form': form} context['errors'] = form.errors.items() return render(request, 'rental/reservation.html', context)