From 7cf2557cf2d83fa5d0b7d59fc86c55fe68ce51c6 Mon Sep 17 00:00:00 2001 From: JisanAR03 Date: Sun, 25 Feb 2024 11:39:56 +0600 Subject: [PATCH] fix Invites & Referrals --- blt/urls.py | 8 +- website/forms.py | 8 +- ...083_alter_invitefriend_options_and_more.py | 55 ++++++++++++ website/models.py | 13 ++- website/templates/invite_friend.html | 48 +++++------ website/views.py | 86 ++++++++++--------- 6 files changed, 132 insertions(+), 86 deletions(-) create mode 100644 website/migrations/0083_alter_invitefriend_options_and_more.py diff --git a/blt/urls.py b/blt/urls.py index e4737f041..4eb84e269 100644 --- a/blt/urls.py +++ b/blt/urls.py @@ -30,7 +30,6 @@ DomainDetailView, StatsDetailView, InviteCreate, - CreateInviteFriend, ScoreboardView, CustomObtainAuthToken, CreateHunt, @@ -117,6 +116,8 @@ handler500 = "website.views.handler500" urlpatterns = [ + path('invite-friend/', website.views.invite_friend, name='invite_friend'), + path('referral/', website.views.referral_signup, name='referral_signup'), path("captcha/", include("captcha.urls")), re_path(r"^auth/registration/", include("dj_rest_auth.registration.urls")), path('rest-auth/password/reset/confirm//', PasswordResetConfirmView.as_view(), @@ -354,11 +355,6 @@ re_path(r"^hunt/$", login_required(HuntCreate.as_view()), name="hunt"), re_path(r"^hunts/$", ListHunts.as_view(), name="hunts"), re_path(r"^invite/$", InviteCreate.as_view(template_name="invite.html")), - re_path( - r"^invite-friend/$", - login_required(CreateInviteFriend.as_view()), - name="invite_friend", - ), re_path(r"^terms/$", TemplateView.as_view(template_name="terms.html"),name="terms"), re_path(r"^about/$", TemplateView.as_view(template_name="about.html")), re_path(r"^privacypolicy/$", TemplateView.as_view(template_name="privacy.html")), diff --git a/website/forms.py b/website/forms.py index a61ca24e3..24f74cd7d 100644 --- a/website/forms.py +++ b/website/forms.py @@ -1,15 +1,9 @@ from django import forms -from .models import InviteFriend, UserProfile, Hunt +from .models import UserProfile, Hunt from mdeditor.fields import MDTextFormField from captcha.fields import CaptchaField -class FormInviteFriend(forms.ModelForm): - class Meta: - model = InviteFriend - fields = ['recipient'] - widgets = {'recipient': forms.TextInput(attrs={'class': 'form-control'})} - class UserProfileForm(forms.ModelForm): class Meta: diff --git a/website/migrations/0083_alter_invitefriend_options_and_more.py b/website/migrations/0083_alter_invitefriend_options_and_more.py new file mode 100644 index 000000000..6d00da702 --- /dev/null +++ b/website/migrations/0083_alter_invitefriend_options_and_more.py @@ -0,0 +1,55 @@ +# Generated by Django 5.0.2 on 2024-02-25 05:39 + +import django.db.models.deletion +import uuid +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("website", "0082_issue_reporter_ip_address"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AlterModelOptions( + name="invitefriend", + options={}, + ), + migrations.RemoveField( + model_name="invitefriend", + name="recipient", + ), + migrations.RemoveField( + model_name="invitefriend", + name="sent", + ), + migrations.AddField( + model_name="invitefriend", + name="point_by_referral", + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name="invitefriend", + name="recipients", + field=models.ManyToManyField( + blank=True, related_name="received_invites", to=settings.AUTH_USER_MODEL + ), + ), + migrations.AddField( + model_name="invitefriend", + name="referral_code", + field=models.CharField(default=uuid.uuid4, editable=False, max_length=100), + ), + migrations.AlterField( + model_name="invitefriend", + name="sender", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="sent_invites", + to=settings.AUTH_USER_MODEL, + ), + ), + ] diff --git a/website/models.py b/website/models.py index b3d2aaed6..f2a080b93 100644 --- a/website/models.py +++ b/website/models.py @@ -378,14 +378,13 @@ class Points(models.Model): class InviteFriend(models.Model): - sender = models.ForeignKey(User, on_delete=models.CASCADE) - recipient = models.EmailField() - sent = models.DateTimeField(auto_now_add=True, db_index=True) + sender = models.ForeignKey(User, related_name='sent_invites', on_delete=models.CASCADE) + recipients = models.ManyToManyField(User, related_name='received_invites', blank=True) + referral_code = models.CharField(max_length=100, default=uuid.uuid4, editable=False) + point_by_referral = models.IntegerField(default=0) - class Meta: - ordering = ("-sent",) - verbose_name = "invitation" - verbose_name_plural = "invitations" + def __str__(self): + return f"Invite from {self.sender}" def user_images_path(instance, filename): diff --git a/website/templates/invite_friend.html b/website/templates/invite_friend.html index 051aaf923..8bdbc7435 100644 --- a/website/templates/invite_friend.html +++ b/website/templates/invite_friend.html @@ -1,26 +1,26 @@ {% extends "base.html" %} {% block content %} -
- {% csrf_token %} -
- {% for error in form.non_field_errors %} -
{{ error }}
- {% endfor %} -
-
-
- {% if form.recipient.errors %} -
{{ form.recipient.errors }}
- {% endif %} -
-
-
-
- - - {{ form.recipient }} - -
-
-
-{% endblock %} +
+ +
+ + + or + Send Mail +
+
+

+ Invite a friend to join the site and earn 2 points! +

+
+
+ +{% endblock %} \ No newline at end of file diff --git a/website/views.py b/website/views.py index a59b28e9f..7508be549 100644 --- a/website/views.py +++ b/website/views.py @@ -81,7 +81,7 @@ Company, IssueScreenshot ) -from .forms import FormInviteFriend, UserProfileForm, HuntForm, CaptchaForm, QuickIssueForm +from .forms import UserProfileForm, HuntForm, CaptchaForm, QuickIssueForm from decimal import Decimal from django.conf import settings @@ -90,6 +90,8 @@ from django.core.exceptions import ValidationError from django.http import HttpRequest from django.utils.timezone import now +from django.contrib.sites.shortcuts import get_current_site +from allauth.account.signals import user_signed_up def is_valid_https_url(url): validate = URLValidator(schemes=['https']) # Only allow HTTPS URLs @@ -2058,47 +2060,6 @@ def assign_issue_to_user(request, user, **kwargs): assigner.request = request assigner.process_issue(user, issue, created, domain) - -class CreateInviteFriend(CreateView): - template_name = "invite_friend.html" - model = InviteFriend - form_class = FormInviteFriend - success_url = reverse_lazy("invite_friend") - - def form_valid(self, form): - from django.conf import settings - from django.contrib.sites.shortcuts import get_current_site - - instance = form.save(commit=False) - instance.sender = self.request.user - instance.save() - - site = get_current_site(self.request) - - mail_status = send_mail( - "Inivtation to {site} from {user}".format( - site=site.name, user=self.request.user.username - ), - "You have been invited by {user} to join {site} community.".format( - user=self.request.user.username, site=site.name - ), - settings.DEFAULT_FROM_EMAIL, - [instance.recipient], - ) - - if ( - mail_status - and InviteFriend.objects.filter(sender=self.request.user).count() == 2 - ): - Points.objects.create(user=self.request.user, score=1) - InviteFriend.objects.filter(sender=self.request.user).delete() - - messages.success( - self.request, - "An email has been sent to your friend. Keep inviting your friends and get points!", - ) - return HttpResponseRedirect(self.success_url) - @login_required(login_url="/accounts/login") def follow_user(request, user): if request.method == "GET": @@ -3735,6 +3696,47 @@ def get_context_data(self, **kwargs): return context +@receiver(user_signed_up) +def handle_user_signup(request, user, **kwargs): + referral_token = request.session.get('ref') + if referral_token: + try: + invite = InviteFriend.objects.get(referral_code=referral_token) + invite.recipients.add(user) + invite.point_by_referral += 2 + invite.save() + reward_sender_with_points(invite.sender) + del request.session['ref'] + except InviteFriend.DoesNotExist: + pass + +def reward_sender_with_points(sender): + # Create or update points for the sender + points, created = Points.objects.get_or_create(user=sender, defaults={'score': 0}) + points.score += 2 # Reward 2 points for each successful referral signup + points.save() + +def referral_signup(request): + referral_token = request.GET.get('ref') + # check the referral token is present on invitefriend model or not and if present then set the referral token in the session + if referral_token: + try: + invite = InviteFriend.objects.get(referral_code=referral_token) + request.session['ref'] = referral_token + except InviteFriend.DoesNotExist: + messages.error(request, "Invalid referral token") + return redirect('account_signup') + return redirect('account_signup') + + +def invite_friend(request): + current_site = get_current_site(request) + referral_code, created = InviteFriend.objects.get_or_create(sender=request.user) + referral_link = f"https://{current_site.domain}/referral/?ref={referral_code.referral_code}" + context = { + 'referral_link': referral_link, + } + return render(request, 'invite_friend.html', context) # class CreateIssue(CronJobBase): # RUN_EVERY_MINS = 1