178 lines
5.9 KiB
Python
178 lines
5.9 KiB
Python
"""Notification app models."""
|
|
|
|
from django.conf import settings
|
|
from django.db import models
|
|
from django.utils.timezone import now
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
from account.models import User
|
|
from location.models import Country
|
|
from notification.tasks import send_unsubscribe_email
|
|
from utils.methods import generate_string_code
|
|
from utils.models import ProjectBaseMixin, TJSONField, TranslatedFieldsMixin
|
|
|
|
|
|
class SubscriptionType(ProjectBaseMixin, TranslatedFieldsMixin):
|
|
index_name = models.CharField(max_length=255, verbose_name=_('Index name'), unique=True)
|
|
name = TJSONField(blank=True, null=True, default=None,
|
|
verbose_name=_('name'),
|
|
help_text='{"en-GB":"some text"}')
|
|
country = models.ForeignKey(Country, on_delete=models.PROTECT,
|
|
blank=True, null=True, default=None,
|
|
verbose_name=_('country'))
|
|
|
|
|
|
# todo: associate user & subscriber after users registration
|
|
class SubscriberManager(models.Manager):
|
|
"""Extended manager for Subscriber model."""
|
|
|
|
def make_subscriber(self, email=None, user=None, ip_address=None, country_code=None,
|
|
locale=None, subscription_types=None, *args, **kwargs):
|
|
"""Make subscriber and update info."""
|
|
# search existing object
|
|
if not user:
|
|
user = User.objects.filter(email=email).first()
|
|
|
|
if user:
|
|
obj = self.model.objects.filter(models.Q(user=user) | models.Q(email=user.email)).first()
|
|
else:
|
|
obj = self.model.objects.filter(email=email).first()
|
|
|
|
if subscription_types is None:
|
|
subscription_types = []
|
|
|
|
# update or create
|
|
if obj:
|
|
if user:
|
|
obj.user = user
|
|
obj.email = None
|
|
|
|
else:
|
|
obj.email = email
|
|
|
|
obj.ip_address = ip_address
|
|
obj.country_code = country_code
|
|
obj.locale = locale
|
|
obj.update_code = generate_string_code()
|
|
obj.subscription_types.set(subscription_types)
|
|
obj.subscribe_set.update(unsubscribe_date=None)
|
|
obj.save()
|
|
|
|
else:
|
|
obj = self.model.objects.create(
|
|
user=user, email=email, ip_address=ip_address,
|
|
country_code=country_code, locale=locale,
|
|
subscription_types=subscription_types,
|
|
)
|
|
|
|
return obj
|
|
|
|
def associate_user(self, user):
|
|
"""Associate user."""
|
|
obj = self.model.objects.filter(user=user).first()
|
|
|
|
if obj is None:
|
|
obj = self.model.objects.filter(email=user.email_confirmed, user__isnull=True).first()
|
|
|
|
if obj:
|
|
obj.user = user
|
|
obj.email = None
|
|
obj.save()
|
|
|
|
return obj
|
|
|
|
|
|
class Subscriber(ProjectBaseMixin):
|
|
"""Subscriber model."""
|
|
|
|
user = models.ForeignKey(
|
|
User,
|
|
blank=True,
|
|
null=True,
|
|
default=None,
|
|
on_delete=models.SET_NULL,
|
|
related_name='subscriber',
|
|
verbose_name=_('User'),
|
|
)
|
|
email = models.EmailField(blank=True, null=True, default=None, unique=True, verbose_name=_('Email'))
|
|
ip_address = models.GenericIPAddressField(blank=True, null=True, default=None, verbose_name=_('IP address'))
|
|
country_code = models.CharField(max_length=10, blank=True, null=True, default=None, verbose_name=_('Country code'))
|
|
locale = models.CharField(blank=True, null=True, default=None, max_length=10, verbose_name=_('Locale identifier'))
|
|
update_code = models.CharField(
|
|
max_length=254,
|
|
blank=True,
|
|
null=True,
|
|
default=None,
|
|
db_index=True,
|
|
verbose_name=_('Token'),
|
|
)
|
|
old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None)
|
|
|
|
subscription_types = models.ManyToManyField(SubscriptionType, through='Subscribe')
|
|
|
|
objects = SubscriberManager()
|
|
|
|
class Meta:
|
|
"""Meta class."""
|
|
|
|
verbose_name = _('Subscriber')
|
|
verbose_name_plural = _('Subscribers')
|
|
|
|
def save(self, *args, **kwargs):
|
|
"""Overrided save method."""
|
|
if self.update_code is None:
|
|
self.update_code = generate_string_code()
|
|
return super(Subscriber, self).save(*args, **kwargs)
|
|
|
|
def unsubscribe(self, query: dict):
|
|
"""Unsubscribe user."""
|
|
self.subscribe_set.update(unsubscribe_date=now())
|
|
|
|
if settings.USE_CELERY:
|
|
send_unsubscribe_email.delay(self.pk)
|
|
else:
|
|
send_unsubscribe_email(self.pk)
|
|
|
|
@property
|
|
def send_to(self):
|
|
"""Actual email."""
|
|
return self.user.email if self.user else self.email
|
|
|
|
@property
|
|
def link_to_unsubscribe(self):
|
|
"""Link to unsubscribe."""
|
|
schema = settings.SCHEMA_URI
|
|
site_domain = settings.SITE_DOMAIN_URI
|
|
url = settings.SITE_REDIRECT_URL_UNSUBSCRIBE
|
|
query = f'?code={self.update_code}'
|
|
return f'{schema}://{site_domain}{url}{query}'
|
|
|
|
@property
|
|
def active_subscriptions(self):
|
|
return self.subscription_types.exclude(subscriber__subscribe__unsubscribe_date__isnull=False)
|
|
|
|
|
|
class SubscribeQuerySet(models.QuerySet):
|
|
|
|
def active(self, switcher=True):
|
|
"""Fetches active subscriptions."""
|
|
return self.exclude(unsubscribe_date__isnull=not switcher)
|
|
|
|
|
|
class Subscribe(ProjectBaseMixin):
|
|
"""Subscribe model."""
|
|
|
|
subscribe_date = models.DateTimeField(_('Last subscribe date'), blank=True, null=True, default=now)
|
|
unsubscribe_date = models.DateTimeField(_('Last unsubscribe date'), blank=True, null=True, default=None)
|
|
|
|
subscriber = models.ForeignKey(Subscriber, on_delete=models.CASCADE)
|
|
subscription_type = models.ForeignKey(SubscriptionType, on_delete=models.CASCADE)
|
|
|
|
objects = SubscribeQuerySet.as_manager()
|
|
|
|
class Meta:
|
|
"""Meta class."""
|
|
|
|
verbose_name = _('Subscribe')
|
|
verbose_name_plural = _('Subscribes')
|