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