You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
3.9 KiB
112 lines
3.9 KiB
import logging
|
|
import string
|
|
|
|
import random
|
|
|
|
from django.conf import settings
|
|
from django.contrib.auth import get_user_model
|
|
from django.contrib.sites.models import Site
|
|
from django.db import models
|
|
from django.db.models.signals import post_save
|
|
from django.dispatch import receiver
|
|
from django.urls import reverse_lazy
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
# Create your models here.
|
|
from registration.signals import user_activated
|
|
|
|
# from cart.models import Buying
|
|
# from cart.signals import buying_bought
|
|
from core.models import AbstractStatusModel, STATUS_ACTIVE, STATUS_CHOICES
|
|
from referral.mixins import StatsFormatterMixin
|
|
from referral.utils import get_cookie
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# --------------------------------- Referral status list ----------------------------#
|
|
|
|
REFERRAL_DEFAULT_CHOICE = STATUS_ACTIVE
|
|
|
|
|
|
# @TODO: translate into english and use translation
|
|
class Referral(AbstractStatusModel):
|
|
CODE_LENGTH = 8
|
|
|
|
user = models.OneToOneField(get_user_model(), verbose_name=_('пользователь'), on_delete=models.CASCADE,
|
|
primary_key=True
|
|
)
|
|
code = models.CharField(_('код'), max_length=255)
|
|
status = models.SmallIntegerField(_('статус'), default=REFERRAL_DEFAULT_CHOICE, choices=STATUS_CHOICES)
|
|
|
|
@classmethod
|
|
def create(cls, user, code):
|
|
referral = cls(user=user, code=code)
|
|
return referral
|
|
|
|
@staticmethod
|
|
def generate_code():
|
|
def _generate_code():
|
|
return ''.join([random.choice(string.ascii_uppercase + string.digits) for n in range(Referral.CODE_LENGTH)])
|
|
|
|
code = _generate_code()
|
|
while Referral.active.filter(code=code).exists():
|
|
code = _generate_code()
|
|
return code
|
|
|
|
@property
|
|
def url(self):
|
|
path = reverse_lazy('index:index')
|
|
site_url = settings.DEFAULT_SITE_URL
|
|
return "{}{}".format(site_url, path)
|
|
|
|
def __str__(self):
|
|
return self.code
|
|
|
|
class Meta:
|
|
verbose_name = _('Реферал')
|
|
verbose_name_plural = _('Рефералы')
|
|
|
|
|
|
class ReferralStats(StatsFormatterMixin, AbstractStatusModel):
|
|
referral = models.OneToOneField(Referral, verbose_name=_('Реферал'), on_delete=models.CASCADE, primary_key=True)
|
|
visits = models.IntegerField(_('Посищения'), default=0)
|
|
registrations = models.IntegerField(_('Регистрации'), default=0)
|
|
points = models.IntegerField(_('партенрские балы'), default=0)
|
|
|
|
class Meta:
|
|
verbose_name = _('Реферальная статистика')
|
|
verbose_name_plural = _('Реферальная статистика')
|
|
|
|
|
|
@receiver(post_save, sender=get_user_model())
|
|
def create_user_referral(sender, instance, created, **kwargs):
|
|
if created and Referral.objects.filter(user=instance).first() is None:
|
|
Referral.create(user=instance, code=Referral.generate_code()).save()
|
|
|
|
|
|
@receiver(post_save, sender=Referral)
|
|
def init_referral_stuff(sender, instance, created, *args, **kwargs):
|
|
if created:
|
|
if ReferralStats.active.filter(referral=instance).count() == 0:
|
|
ReferralStats.active.create(referral=instance).save()
|
|
|
|
|
|
@receiver(user_activated)
|
|
def update_ref_stats(sender, user, request, **kwargs):
|
|
referral_code = get_cookie(request.COOKIES, 'referral')
|
|
if referral_code:
|
|
referral = Referral.objects.filter(code__exact=referral_code).first()
|
|
if referral:
|
|
referral.referralstats.registrations += 1
|
|
referral.referralstats.points += settings.DEFAULT_REFERRAL_POINTS
|
|
referral.referralstats.save()
|
|
user.referral_user = referral.user
|
|
user.save()
|
|
else:
|
|
logger.warning("Missing referral code in database: " + referral_code)
|
|
|
|
|
|
# @receiver(buying_bought, sender=Buying)
|
|
# def charge_referral_points(sender, buying, *args, **kwargs):
|
|
# pass
|
|
#
|
|
|