from django.contrib.gis.db import models from django.utils import timezone from django.contrib.gis.db.models.functions import Distance from django.dispatch import receiver from django.db.models.signals import post_save from clients.models import ClientProfile from partners.models import Establishment, RoomCategory from dbsettings.functions import getValue from datetime import timedelta import uuid class LengthChoices(models.IntegerChoices): ANY = 0 SHORT = 1 LONG = 2 class Inquiry(models.Model): uuid = models.UUIDField(default=uuid.uuid4, unique=True) client = models.ForeignKey(ClientProfile, models.PROTECT, null=True, blank=True) destination_name = models.CharField(max_length=128) destination_coords = models.PointField() destination_radius = models.IntegerField() arrival = models.DateField() min_nights = models.IntegerField(default=0, choices=LengthChoices.choices) budget = models.DecimalField(max_digits=10, decimal_places=2) adults = models.IntegerField() children = models.IntegerField() comment = models.TextField(null=True, blank=True) activated = models.DateTimeField(null=True, blank=True) bidding_end = models.DateTimeField(null=True, blank=True) auction_end = models.DateTimeField(null=True, blank=True) expiry = models.DateTimeField(null=True, blank=True) gateway = models.CharField(max_length=128, null=True, blank=True) @property def is_paid(self): if not self.invoice: return False return self.invoice.is_paid def activate(self): if self.activated: return False self.activated = timezone.now() self.bidding_end = self.activated + timedelta(hours=int(getValue("auction.bidding_period", 24))) self.auction_end = self.bidding_end + timedelta(hours=int(getValue("auction.selection_period", 24))) self.save() def process_payment(self): if self.invoice.is_paid: self.activate() @property def expired(self): return self.expiry and (self.expiry < timezone.now()) @property def in_bidding(self): return self.active and (self.bidding_end > timezone.now()) @property def in_selection(self): return self.active and (self.auction_end > timezone.now()) and not self.in_bidding @property def active(self): try: return bool(self.activated) and not self.expired except: return False @property def accepted(self): try: return Offer.objects.get(inquiry=self, accepted__isnull=False) except Offer.DoesNotExist: return False class Offer(models.Model): uuid = models.UUIDField(default=uuid.uuid4, unique=True) inquiry = models.ForeignKey(Inquiry, models.PROTECT) roomcategory = models.ForeignKey(RoomCategory, models.PROTECT) departure = models.DateField() comment = models.TextField(null=True, blank=True) accepted = models.DateTimeField(null=True, blank=True) hidden = models.BooleanField(default=False) @property def establishment(self): return self.roomcategory.establishment @property def nights(self): return (self.departure - self.inquiry.arrival).days @property def distance(self): return self.inquiry.destination_coords.distance(self.roomcategory.establishment.coords) @receiver(post_save, sender=Inquiry) def inquiry_expiry(sender, instance, created, **kwargs): if not instance.expiry: instance.expiry = min(instance.arrival, (timezone.now() + timedelta(hours=int(getValue("auction.payment_period", 168)))).date()) instance.save()