"""Main app models.""" from typing import Iterable from django.conf import settings from django.contrib.contenttypes import fields as generic from django.contrib.contenttypes.models import ContentType from django.contrib.postgres.fields import JSONField from django.core.validators import EMPTY_VALUES from django.db import models from django.db.models import Q from django.utils.translation import gettext_lazy as _ from advertisement.models import Advertisement from configuration.models import TranslationSettings from location.models import Country from main import methods from review.models import Review from utils.models import (ProjectBaseMixin, TJSONField, URLImageMixin, TranslatedFieldsMixin, PlatformMixin) class Currency(TranslatedFieldsMixin, models.Model): """Currency model.""" name = TJSONField( _('name'), null=True, blank=True, default=None, help_text='{"en-GB":"some text"}') sign = models.CharField(_('sign'), max_length=255) slug = models.SlugField(max_length=255, unique=True) class Meta: verbose_name = _('currency') verbose_name_plural = _('currencies') def __str__(self): return f'{self.name}' class SiteSettingsQuerySet(models.QuerySet): """Extended queryset for SiteSettings model.""" def with_country(self): return self.filter(country__isnull=False) class SiteSettings(ProjectBaseMixin): subdomain = models.CharField(max_length=255, db_index=True, unique=True, verbose_name=_('Subdomain')) country = models.OneToOneField(Country, on_delete=models.PROTECT, null=True, blank=True, default=None, verbose_name=_('Country')) default_site = models.BooleanField(default=False, verbose_name=_('Default site')) pinterest_page_url = models.URLField(blank=True, null=True, default=None, verbose_name=_('Pinterest page URL')) twitter_page_url = models.URLField(blank=True, null=True, default=None, verbose_name=_('Twitter page URL')) facebook_page_url = models.URLField(blank=True, null=True, default=None, verbose_name=_('Facebook page URL')) instagram_page_url = models.URLField(blank=True, null=True, default=None, verbose_name=_('Instagram page URL')) contact_email = models.EmailField(blank=True, null=True, default=None, verbose_name=_('Contact email')) config = JSONField(blank=True, null=True, default=None, verbose_name=_('Config')) ad_config = models.TextField(blank=True, null=True, default=None, verbose_name=_('AD config')) currency = models.ForeignKey(Currency, on_delete=models.PROTECT, null=True, default=None) objects = SiteSettingsQuerySet.as_manager() class Meta: """Meta class.""" verbose_name = _('Site setting') verbose_name_plural = _('Site settings') def __str__(self): return f'ID: "{self.id}". Site: "{self.subdomain}"' @property def published_features(self): return self.feature_set.filter(sitefeature__site_settings=self, sitefeature__published=True) @property def published_sitefeatures(self): return self.sitefeature_set. \ filter(Q(published=True) & Q(feature__source__in=[PlatformMixin.WEB, PlatformMixin.ALL])) @property def site_url(self): return methods.site_url(schema=settings.SCHEMA_URI, subdomain=self.subdomain, domain=settings.SITE_DOMAIN_URI) class Page(models.Model): """Page model.""" page_name = models.CharField(max_length=255, unique=True) advertisements = models.ManyToManyField(Advertisement) class Meta: """Meta class.""" verbose_name = _('Page') verbose_name_plural = _('Pages') def __str__(self): return f'{self.page_name}' class Feature(ProjectBaseMixin, PlatformMixin): """Feature model.""" slug = models.SlugField(max_length=255, unique=True) priority = models.IntegerField(unique=True, null=True, default=None) route = models.ForeignKey(Page, on_delete=models.PROTECT, null=True, default=None) site_settings = models.ManyToManyField(SiteSettings, through='SiteFeature') class Meta: """Meta class.""" verbose_name = _('Feature') verbose_name_plural = _('Features') def __str__(self): return f'{self.slug}' class SiteFeatureQuerySet(models.QuerySet): """Extended queryset for SiteFeature model.""" def published(self, switcher=True): return self.filter(published=switcher) def by_country_code(self, country_code: str): return self.filter(site_settings__country__code=country_code) def by_sources(self, sources: Iterable[int]): return self.filter(feature__source__in=sources) class SiteFeature(ProjectBaseMixin): """SiteFeature model.""" site_settings = models.ForeignKey(SiteSettings, on_delete=models.CASCADE) feature = models.ForeignKey(Feature, on_delete=models.PROTECT) published = models.BooleanField(default=False, verbose_name=_('Published')) main = models.BooleanField(default=False, verbose_name=_('Main')) objects = SiteFeatureQuerySet.as_manager() class Meta: """Meta class.""" verbose_name = _('Site feature') verbose_name_plural = _('Site features') unique_together = ('site_settings', 'feature') class Award(TranslatedFieldsMixin, URLImageMixin, models.Model): """Award model.""" award_type = models.ForeignKey('main.AwardType', on_delete=models.CASCADE) title = TJSONField( _('title'), null=True, blank=True, default=None, help_text='{"en-GB":"some text"}') vintage_year = models.CharField(_('vintage year'), max_length=255, default='') content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type', 'object_id') def __str__(self): title = 'None' lang = TranslationSettings.get_solo().default_language if self.title and lang in self.title: title = self.title[lang] return f'id:{self.id}-{title}' class AwardType(models.Model): """AwardType model.""" country = models.ForeignKey( 'location.Country', verbose_name=_('country'), on_delete=models.CASCADE) name = models.CharField(_('name'), max_length=255) def __str__(self): return self.name class CarouselQuerySet(models.QuerySet): """Carousel QuerySet.""" def is_parsed(self): """Parsed carousel objects.""" return self.filter(is_parse=True) def active(self): """Active carousel objects.""" return self.filter(active=True) def by_country_code(self, code): """Filter collection by country code.""" return self.filter(country__code=code) class Carousel(models.Model): """Carousel model.""" content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE, blank=True, null=True, default=None) object_id = models.PositiveIntegerField(blank=True, null=True, default=None) content_object = generic.GenericForeignKey('content_type', 'object_id') old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None) title = models.CharField(_('old title'), max_length=255, blank=True, null=True, default=None) link = models.CharField(_('old link'), max_length=255, blank=True, null=True, default=None) attachment_suffix_url = models.TextField(_('old attachment_suffix_url'), blank=True, null=True, default=None) description = models.CharField(_('old description'), max_length=255, blank=True, null=True, default=None) link_title = models.CharField(_('old link_title'), max_length=255, blank=True, null=True, default=None) country = models.ForeignKey( Country, blank=True, null=True, on_delete=models.SET_NULL, verbose_name=_('country') ) active = models.BooleanField(_('old active'), default=False) is_parse = models.BooleanField(_('is parse'), default=False) objects = CarouselQuerySet.as_manager() class Meta: """Meta class.""" verbose_name = _('Carousel') verbose_name_plural = _('Carousel') @property def name(self): # Check if Generic obj has name or title if hasattr(self.content_object, 'name'): return self.content_object.name if hasattr(self.content_object, 'title'): return self.content_object.title_translated @property def awards(self): if hasattr(self.content_object, 'awards'): return self.content_object.awards @property def vintage_year(self): if hasattr(self.content_object, 'reviews'): last_review = self.content_object.reviews.by_status(Review.READY).last() if last_review: return last_review.vintage @property def toque_number(self): if hasattr(self.content_object, 'toque_number'): return self.content_object.toque_number @property def public_mark(self): if hasattr(self.content_object, 'public_mark'): return self.content_object.public_mark @property def image_url(self): if self.attachment_suffix_url: return f'https://s3.eu-central-1.amazonaws.com/gm-test.com/media/{self.attachment_suffix_url}' if hasattr(self.content_object, 'image_url'): return self.content_object.image_url @property def slug(self): if hasattr(self.content_object, 'slug'): return self.content_object.slug @property def the_most_recent_award(self): if hasattr(self.content_object, 'the_most_recent_award'): return self.content_object.the_most_recent_award @property def model_name(self): from establishment.models import Establishment from news.models import News if isinstance(self.content_object, Establishment): return self.content_object.establishment_type.index_name elif isinstance(self.content_object, News): return self.content_type.model elif self.link not in EMPTY_VALUES: return 'external' return None