diff --git a/rental/admin.py b/rental/admin.py index 25a7fc3..18550d1 100644 --- a/rental/admin.py +++ b/rental/admin.py @@ -1,10 +1,15 @@ from django.contrib import admin -from .models import Testimonial, Reservation, Guest, Place, Image, Contact +from rental.models.booking import Booking +from rental.models.contact import Contact +from rental.models.guest import Guest +from rental.models.picture import Picture +from rental.models.place import Place +from rental.models.testimonial import Testimonial -admin.site.register(Contact) +admin.site.register(Booking) admin.site.register(Guest) -admin.site.register(Image) admin.site.register(Place) -admin.site.register(Reservation) +admin.site.register(Contact) +admin.site.register(Picture) admin.site.register(Testimonial) diff --git a/rental/bookings.py b/rental/bookings.py index 532f3d9..d3a0ca1 100644 --- a/rental/bookings.py +++ b/rental/bookings.py @@ -1,6 +1,10 @@ -from rental.pricing import get_reservation_price from django.shortcuts import get_object_or_404 -from rental.models import Reservation, Place, Guest +from rental.models.booking import Booking +from rental.models.contact import Contact +from rental.models.guest import Guest +from rental.models.picture import Picture +from rental.models.place import Place +from rental.models.testimonial import Testimonial from villafleurie.settings import BASE_DIR import datetime from google.auth.transport.requests import Request @@ -77,11 +81,14 @@ def synchronize_calendars(place): reservation = get_calendar_reservations(place) place = get_object_or_404(Place, name=place.name) - price = get_reservation_price( - place, - reservation['start'], - reservation['end'] - ) + + # After refactoring models, Move this method to the Booking model and get price later by calling Booking method + # price = get_reservation_price( + # place, + # reservation['start'], + # reservation['end'] + # ) + start = reservation['start'] end = reservation['end'] @@ -90,23 +97,23 @@ def synchronize_calendars(place): guest = Guest.objects.create(name=reservation['guest']) else: guest = guest.first() - db_booking = Reservation.objects.filter( + db_booking = Booking.objects.filter( guest=guest ) if not db_booking.exists(): - Reservation.objects.create( + Booking.objects.create( place=place, guest=guest, start=start, end=end, - price=price + # 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.price = price def get_bookings(place): @@ -114,7 +121,7 @@ def get_bookings(place): Returns a list of all related place reservations """ synchronize_calendars(place) - booked_dates = Reservation.objects.filter(place=place) + booked_dates = Booking.objects.filter(place=place) return [booking for booking in booked_dates] diff --git a/rental/forms.py b/rental/forms.py index 058ef20..76fbb92 100644 --- a/rental/forms.py +++ b/rental/forms.py @@ -1,6 +1,11 @@ from django import forms -from .models import Reservation, Place, Guest -from .enums import PlaceNames +from rental.models.booking import Booking +from rental.models.contact import Contact +from rental.models.guest import Guest +from rental.models.picture import Picture +from rental.models.place import Place +from rental.models.testimonial import Testimonial +from rental.enums import PlaceNames class ReservationForm(forms.Form): diff --git a/rental/migrations/0031_auto_20200407_0520.py b/rental/migrations/0031_auto_20200407_0520.py new file mode 100644 index 0000000..2d5e4b6 --- /dev/null +++ b/rental/migrations/0031_auto_20200407_0520.py @@ -0,0 +1,21 @@ +# Generated by Django 3.0.4 on 2020-04-07 09:20 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('rental', '0030_auto_20200331_0439'), + ] + + operations = [ + migrations.RenameModel( + old_name='Reservation', + new_name='Booking', + ), + migrations.RenameModel( + old_name='Image', + new_name='Picture', + ), + ] diff --git a/rental/models.py b/rental/models.py deleted file mode 100644 index d1883e3..0000000 --- a/rental/models.py +++ /dev/null @@ -1,88 +0,0 @@ -from django.db import models - - -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) - - -class Place(models.Model): - class Meta: - verbose_name = "Appartement" - - 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) - calendar = models.CharField(max_length=350, blank=True, null=True) - - -class Guest(models.Model): - class Meta: - verbose_name = "Voyageur" - - def __str__(self): - return self.name - - name = models.CharField(max_length=100) - email = models.EmailField(unique=False) - phone = models.CharField(max_length=30, blank=True) - - -class Reservation(models.Model): - class Meta: - verbose_name = 'Réservation' - - 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() - price = models.DecimalField(max_digits=6, decimal_places=2, null=True) - - -class Testimonial(models.Model): - class Meta: - verbose_name = "Témoignage" - - def __str__(self): - return f"Témoignage de {self.author}" - - author = models.CharField(max_length=200) - text = models.TextField(max_length=1000) - picture = models.ImageField( - max_length=200, upload_to='img/', null=True, blank=True) - link = models.URLField(max_length=200, 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) - - -class Contact(models.Model): - - def __str__(self): - return f"Message de {self.name}, le {self.date}" - - name = models.CharField(max_length=50) - email = models.EmailField(max_length=50) - subject = models.EmailField(max_length=50) - message = models.TextField(max_length=50) - date = models.DateTimeField(auto_now_add=True) diff --git a/rental/models/booking.py b/rental/models/booking.py new file mode 100644 index 0000000..b0b72cc --- /dev/null +++ b/rental/models/booking.py @@ -0,0 +1,30 @@ +from datetime import datetime +from django.db import models +from rental.models.guest import Guest +from rental.models.place import Place + + +class Booking(models.Model): + class Meta: + verbose_name = 'Réservation' + + 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() + price = models.DecimalField(max_digits=6, decimal_places=2, null=True) + + def get_reservation_price(place, start, end): + """ Compute booking price as a function of place and dates """ + + 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/models/contact.py b/rental/models/contact.py new file mode 100644 index 0000000..fb8ca79 --- /dev/null +++ b/rental/models/contact.py @@ -0,0 +1,14 @@ +from django.db import models + + + +class Contact(models.Model): + + def __str__(self): + return f"Message de {self.name}, le {self.date}" + + name = models.CharField(max_length=50) + email = models.EmailField(max_length=50) + subject = models.EmailField(max_length=50) + message = models.TextField(max_length=50) + date = models.DateTimeField(auto_now_add=True) diff --git a/rental/models/guest.py b/rental/models/guest.py new file mode 100644 index 0000000..06f7b05 --- /dev/null +++ b/rental/models/guest.py @@ -0,0 +1,14 @@ +from django.db import models + + + +class Guest(models.Model): + class Meta: + verbose_name = "Voyageur" + + def __str__(self): + return self.name + + name = models.CharField(max_length=100) + email = models.EmailField(unique=False) + phone = models.CharField(max_length=30, blank=True) diff --git a/rental/models/picture.py b/rental/models/picture.py new file mode 100644 index 0000000..7a5dc36 --- /dev/null +++ b/rental/models/picture.py @@ -0,0 +1,9 @@ +from django.db import models + + +class Picture(models.Model): + def __str__(self): + return self.alt + + img = models.ImageField(upload_to='img/', null=True, blank=True) + alt = models.CharField(max_length=100) diff --git a/rental/models/place.py b/rental/models/place.py new file mode 100644 index 0000000..e340c98 --- /dev/null +++ b/rental/models/place.py @@ -0,0 +1,24 @@ +from django.db import models +from rental.models.picture import Picture + + +class Place(models.Model): + class Meta: + verbose_name = "Appartement" + + 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( + Picture, on_delete=models.CASCADE, blank=True, null=True) + images = models.ManyToManyField(Picture, related_name="places", blank=True) + calendar = models.CharField(max_length=350, blank=True, null=True) diff --git a/rental/models/testimonial.py b/rental/models/testimonial.py new file mode 100644 index 0000000..3049d2a --- /dev/null +++ b/rental/models/testimonial.py @@ -0,0 +1,21 @@ +from django.db import models +from rental.models.booking import Booking +from rental.models.guest import Guest + + +class Testimonial(models.Model): + class Meta: + verbose_name = "Témoignage" + + def __str__(self): + return f"Témoignage de {self.author}" + + author = models.CharField(max_length=200) + text = models.TextField(max_length=1000) + picture = models.ImageField( + max_length=200, upload_to='img/', null=True, blank=True) + link = models.URLField(max_length=200, null=True, blank=True) + guest = models.OneToOneField( + Guest, on_delete=models.CASCADE, blank=True, null=True) + reservation = models.OneToOneField( + Booking, on_delete=models.CASCADE, blank=True, null=True) diff --git a/rental/pricing.py b/rental/pricing.py deleted file mode 100644 index e598506..0000000 --- a/rental/pricing.py +++ /dev/null @@ -1,25 +0,0 @@ -from datetime import datetime - - -def get_reservation_price(place, start, end): - """ Compute booking price as a function of place and dates """ - - 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 - - -if __name__ == '__main__': - from rental.models import Place - from datetime import datetime - from django.shortcuts import get_object_or_404 - place_name = 'T2' - place = get_object_or_404(Place, name=place_name) - start = datetime(2019, 11, 14) - end = datetime(2019, 11, 20) - x = get_reservation_price(place_name, start, end) - print(x) diff --git a/rental/tests.py b/rental/tests.py index 7ce503c..7a9c6eb 100644 --- a/rental/tests.py +++ b/rental/tests.py @@ -1,3 +1,40 @@ +from datetime import datetime +from django.shortcuts import get_object_or_404 from django.test import TestCase +from rental.models.place import Place +from rental.models.booking import Booking +from rental.models.guest import Guest -# Create your tests here. +place_name = 'T2' +place = get_object_or_404(Place, name=place_name) + + +x = get_reservation_price(place_name, start, end) +print(x) + + +class TestBooking(TestCase): + def setUp(self): + self.place = Place.objects.create( + name='TX', + price=100 + ) + self.guest = Guest.objects.create( + name="Ruidy", + email="r@mail.com", + phone="1092198YE8939798" + ) + + self.start = datetime(2019, 11, 14) + self.end = datetime(2019, 11, 20) + + def test_bookingPrice(self): + # place = Place.objects.get(name='TX') + booking = Booking.objects.create( + place=self.place, + start=self.start, + end=self.end, + guest=self.guest + ) + + self.assertEqual(booking.get_reservation_price()) diff --git a/rental/urls.py b/rental/urls.py index 2f0c368..d3f521e 100644 --- a/rental/urls.py +++ b/rental/urls.py @@ -1,7 +1,12 @@ from django.urls import path from . import views from villafleurie import settings -from .models import Testimonial, Reservation, Guest, Place +from rental.models.booking import Booking +from rental.models.contact import Contact +from rental.models.guest import Guest +from rental.models.picture import Picture +from rental.models.place import Place +from rental.models.testimonial import Testimonial from django.contrib.staticfiles.urls import static, staticfiles_urlpatterns app_name = 'rental' diff --git a/rental/views.py b/rental/views.py index c018a6e..725457e 100644 --- a/rental/views.py +++ b/rental/views.py @@ -4,8 +4,13 @@ from django.shortcuts import render, get_object_or_404 from django.views.generic.base import TemplateView from django.utils.translation import gettext_lazy as _ from rental.forms import ReservationForm, ContactForm -from rental.models import Testimonial, Reservation, Guest, Place, Contact -from rental.pricing import get_reservation_price +from rental.models.booking import Booking +from rental.models.contact import Contact +from rental.models.guest import Guest +from rental.models.picture import Picture +from rental.models.place import Place +from rental.models.testimonial import Testimonial + from rental.bookings import check_availability, synchronize_calendars, update_calendar from rental.tasks.apiMailer import * # or gMailer @@ -78,7 +83,7 @@ def handle_reservation_form(request, context={}, init_template='rental/reservati available = check_availability(place, start, end) price = get_reservation_price(place, start, end) if available: - reservation = Reservation.objects.create( + reservation = Booking.objects.create( guest=guest, place=place, message=message, @@ -119,7 +124,7 @@ def calendar(request, place_name): returns a list of all related place reservations """ # synchronize_calendars() - booked_dates = Reservation.objects.all() + booked_dates = Booking.objects.all() bookings = [ booking for booking in booked_dates if booking.place.name == place_name] context = {