"""Establishment models.""" from django.contrib.contenttypes import fields as generic from django.core.exceptions import ValidationError from django.db import models from django.utils.translation import gettext_lazy as _ from location.models import Address from utils.models import (ProjectBaseMixin, ImageMixin, TJSONField, TraslatedFieldsMixin, BaseAttributes) # todo: establishment type&subtypes check class EstablishmentType(ProjectBaseMixin, TraslatedFieldsMixin): """Establishment type model.""" name = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'), help_text='{"en":"some text"}') use_subtypes = models.BooleanField(_('Use subtypes'), default=True) class Meta: """Meta class.""" verbose_name = _('Establishment type') verbose_name_plural = _('Establishment types') class EstablishmentSubTypeManager(models.Manager): """Extended manager for establishment subtype.""" def make(self, name, establishment_type): obj = self.model(name=name, establishment_type=establishment_type) obj.full_clean() obj.save() return obj class EstablishmentSubType(ProjectBaseMixin, TraslatedFieldsMixin): """Establishment type model.""" name = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'), help_text='{"en":"some text"}') establishment_type = models.ForeignKey(EstablishmentType, on_delete=models.CASCADE, verbose_name=_('Type')) objects = EstablishmentSubTypeManager() class Meta: """Meta class.""" verbose_name = _('Establishment subtype') verbose_name_plural = _('Establishment subtypes') # def __str__(self): # """__str__ method.""" # return self.name def clean_fields(self, exclude=None): if not self.establishment_type.use_subtypes: raise ValidationError(_('Establishment type is not use subtypes.')) class Establishment(ProjectBaseMixin, ImageMixin, TraslatedFieldsMixin): """Establishment model.""" name = TJSONField(blank=True, null=True, default=None, verbose_name=_('Name'), help_text='{"en":"some text"}') description = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'), help_text='{"en":"some text"}') public_mark = models.PositiveIntegerField(blank=True, null=True, default=None, verbose_name=_('Public mark'),) toque_number = models.PositiveIntegerField(blank=True, null=True, default=None, verbose_name=_('Toque number'),) establishment_type = models.ForeignKey(EstablishmentType, related_name='establishment', on_delete=models.PROTECT, verbose_name=_('Type')) establishment_subtypes = models.ManyToManyField(EstablishmentSubType, related_name='subtype_establishment', verbose_name=_('Subtype')) address = models.ForeignKey(Address, blank=True, null=True, default=None, on_delete=models.PROTECT, verbose_name=_('Address')) price_level = models.PositiveIntegerField(blank=True, null=True, default=None, verbose_name=_('Price level')) awards = generic.GenericRelation(to='main.Award') tags = generic.GenericRelation(to='main.MetaDataContent') class Meta: """Meta class.""" verbose_name = _('Establishment') verbose_name_plural = _('Establishments') # todo: recalculate toque_number def recalculate_toque_number(self): self.toque_number = 4 def recalculate_price_level(self, low_price=None, high_price=None): if low_price is None or high_price is None: low_price, high_price = self.get_price_level() # todo: calculate price level self.price_level = 3 def get_price_level(self): country = self.address.city.country return country.low_price, country.high_price @property def subtypes(self): return EstablishmentSubType.objects.filter( subtype_establishment=self, establishment_type=self.establishment_type, establishment_type__use_subtypes=True) def set_establishment_type(self, establishment_type): self.establishment_type = establishment_type self.establishment_subtypes.exclude( establishement_type=establishment_type).delete() def add_establishment_subtype(self, establishment_subtype): if establishment_subtype.establishment_type != self.establishment_type: raise ValidationError('Establishment type of subtype does not match') self.establishment_subtypes.add(establishment_subtype) class EstablishmentScheduleQuerySet(models.QuerySet): """QuerySet for model EstablishmentSchedule""" class EstablishmentSchedule(BaseAttributes): """Establishment schedule model.""" establishment = models.OneToOneField(Establishment, related_name='schedule', on_delete=models.CASCADE, verbose_name=_('Establishment')) schedule = models.ManyToManyField(to='timetable.Timetable', verbose_name=_('Establishment schedule')) objects = EstablishmentScheduleQuerySet.as_manager() class Meta: """Meta class""" verbose_name = _('Establishment schedule') verbose_name_plural = _('Establishment schedules') class CommentQuerySet(models.QuerySet): """QuerySets for Comment model.""" def by_author(self, author): """Return comments by author""" return self.filter(author=author) class Comment(ProjectBaseMixin): """Comment model.""" text = models.TextField(verbose_name=_('Comment text')) mark = models.PositiveIntegerField(blank=True, null=True, default=None, verbose_name=_('Mark')) author = models.ForeignKey('account.User', related_name='comments', on_delete=models.CASCADE, verbose_name=_('Author')) establishment = models.ForeignKey(Establishment, related_name='comments', on_delete=models.CASCADE, verbose_name=_('Establishment')) objects = CommentQuerySet.as_manager() class Meta: """Meta class""" verbose_name = _('Comment') verbose_name_plural = _('Comments') def __str__(self): """String representation""" return str(self.author)