diff options
Diffstat (limited to 'alphabetlearning/payments')
6 files changed, 132 insertions, 33 deletions
diff --git a/alphabetlearning/payments/admin.py b/alphabetlearning/payments/admin.py index e9b70db..3980f67 100644 --- a/alphabetlearning/payments/admin.py +++ b/alphabetlearning/payments/admin.py @@ -1,14 +1,11 @@ from django.contrib import admin from .models import CartItem +from .models import EmailSignup +from .models import PendingEmailVerification from .models import Price -from .models import Product from .models import ShoppingCart from .models import Subscription -from .models import SubscriptionPlan -from .models import EmailSignup -from alphabetlearning.resources.models import Resource - # class PriceAdmin(admin.ModelAdmin): # list_display = @@ -43,7 +40,8 @@ class SubscriptionAdmin(admin.ModelAdmin): # admin.site.register(Product, ProductAdmin) admin.site.register(Price) +admin.site.register(PendingEmailVerification) admin.site.register(ShoppingCart, ShoppingCartAdmin) admin.site.register(CartItem) admin.site.register(Subscription, SubscriptionAdmin) -admin.site.register(EmailSignup, SuccessEmailSignupAdmin)
\ No newline at end of file +admin.site.register(EmailSignup, SuccessEmailSignupAdmin) diff --git a/alphabetlearning/payments/migrations/0010_pendingemailverification.py b/alphabetlearning/payments/migrations/0010_pendingemailverification.py new file mode 100644 index 0000000..c49a2cb --- /dev/null +++ b/alphabetlearning/payments/migrations/0010_pendingemailverification.py @@ -0,0 +1,26 @@ +# Generated by Django 5.0.4 on 2024-12-03 16:18 + +import uuid +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('payments', '0009_emailsignup_alter_price_resource'), + ] + + operations = [ + migrations.CreateModel( + name='PendingEmailVerification', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('email', models.EmailField(max_length=254)), + ('first_name', models.CharField(max_length=100)), + ('last_name', models.CharField(max_length=100)), + ('verification_token', models.UUIDField(default=uuid.uuid4, editable=False)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('is_verified', models.BooleanField(default=False)), + ], + ), + ] diff --git a/alphabetlearning/payments/migrations/0011_remove_pendingemailverification_first_name_and_more.py b/alphabetlearning/payments/migrations/0011_remove_pendingemailverification_first_name_and_more.py new file mode 100644 index 0000000..e13f6d3 --- /dev/null +++ b/alphabetlearning/payments/migrations/0011_remove_pendingemailverification_first_name_and_more.py @@ -0,0 +1,21 @@ +# Generated by Django 5.0.4 on 2024-12-03 16:38 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('payments', '0010_pendingemailverification'), + ] + + operations = [ + migrations.RemoveField( + model_name='pendingemailverification', + name='first_name', + ), + migrations.RemoveField( + model_name='pendingemailverification', + name='last_name', + ), + ] diff --git a/alphabetlearning/payments/models.py b/alphabetlearning/payments/models.py index 7a8c7bb..0702427 100644 --- a/alphabetlearning/payments/models.py +++ b/alphabetlearning/payments/models.py @@ -1,3 +1,5 @@ +import uuid + from django.conf import settings from django.core.exceptions import ValidationError from django.db import models @@ -5,6 +7,13 @@ from django.db import models from alphabetlearning.resources.models import Resource +class PendingEmailVerification(models.Model): + email = models.EmailField() + verification_token = models.UUIDField(default=uuid.uuid4, editable=False) + created_at = models.DateTimeField(auto_now_add=True) + is_verified = models.BooleanField(default=False) + + class EmailSignup(models.Model): email = models.EmailField(unique=True) date_added = models.DateTimeField(auto_now_add=True) diff --git a/alphabetlearning/payments/urls.py b/alphabetlearning/payments/urls.py index 12f445d..38393e0 100644 --- a/alphabetlearning/payments/urls.py +++ b/alphabetlearning/payments/urls.py @@ -21,7 +21,9 @@ urlpatterns = [ path("landing/", views.ProductLandingPageView.as_view(), name="landing"), path("delete-cart-item/<int:pk>", views. DeleteCartItem.as_view(), name="delete_cart_item"), path("webhooks/stripe/", views.stripe_webhook, name="stripe-webhook"), - path("email_signup/", views.email_signup, name="email_signup"), + # path("email_signup/", views.email_signup, name="email_signup"), + path("email-sign-up-verification/", views.email_signup_verification, name="email_signup_verification"), + path("verify-email/<str:token>/", views.verify_email, name="verify_email"), path("success_email_signup/", views.SuccessEmailSignupView.as_view(), name="success_email_signup"), path('privacy-policy/', privacy_policy, name='privacy_policy'), # Add this line ] diff --git a/alphabetlearning/payments/views.py b/alphabetlearning/payments/views.py index d0172d0..9691a9f 100644 --- a/alphabetlearning/payments/views.py +++ b/alphabetlearning/payments/views.py @@ -15,6 +15,7 @@ from django.views.generic import DeleteView from django.views.generic import TemplateView from alphabetlearning.payments.models import EmailSignup +from alphabetlearning.payments.models import PendingEmailVerification from alphabetlearning.resources.models import Resource from alphabetlearning.users.models import User @@ -43,38 +44,78 @@ from .models import ShoppingCart stripe.api_key = settings.STRIPE_SECRET_KEY + class SuccessEmailSignupView(TemplateView): template_name = "payments/success_email_signup.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['email'] = self.request.POST.get('email') + context["email"] = self.request.POST.get("email") return context -def email_signup(request): - if request.method == 'POST': - email = request.POST.get('email') - if email: - EmailSignup.objects.get_or_create(email=email) - # Send email to user - send_mail( - "Thank you for signing up", - "You have successfully signed up for our newsletter.", - settings.DEFAULT_FROM_EMAIL, - [email], - fail_silently=False, - ) - # Send email to admin - admin_email = "admin@example.com" # Replace with actual admin email - send_mail( - "New Email Signup", - f"A new user has signed up with the email: {email}", - settings.DEFAULT_FROM_EMAIL, - [admin_email], - fail_silently=False, - ) - return redirect(reverse('payments:success_email_signup')) # Redirect to a success page or similar - return render(request, 'pages/home.html') # Adjust as necessary + +def email_signup_verification(request): + if request.method == "POST": + email = request.POST.get("email") + + # Create pending verification + pending_verification = PendingEmailVerification.objects.create( + email=email, + ) + + # Generate verification URL + verification_url = request.build_absolute_uri( + reverse('payments:verify_email', args=[str(pending_verification.verification_token)]) + ) + + # Send verification email + subject = 'Alphabet Learning - Email Verification' + message = f''' + Hello!, + + You recently requested to sign up to the Alpabet Learning contract list. + + Please click the following link to verify your email address: + {verification_url} + + If you didn't request this, please ignore this email. + + Best regards, + The Alphabet Learning Team + ''' + send_mail( + subject, + message, + settings.DEFAULT_FROM_EMAIL, + [email], + fail_silently=False, + ) + return render(request, 'payments/verification_sent.html', { + 'email': email + }) + return render(request, "pages/home.html") # Adjust as necessary + +def verify_email(request, token): + try: + pending = PendingEmailVerification.objects.get( + verification_token=token, + is_verified=False + ) + + # Create the subscriber + EmailSignup.objects.create( + email=pending.email, + ) + + # Mark as verified + pending.is_verified = True + pending.save() + + return render(request, 'payments/verification_success.html') + + except PendingEmailVerification.DoesNotExist: + return render(request, 'payments/verification_failed.html') + def create_line_items(resources): price_objs = [r.price_obj.first() for r in resources] @@ -205,6 +246,7 @@ def stripe_webhook(request): ) return HttpResponse(status=200) + class DeleteCartItem(DeleteView): model = CartItem success_url = reverse_lazy("payments:cart_detail") @@ -219,5 +261,6 @@ class DeleteCartItem(DeleteView): request.user.shoppingcart.delete() return redirect("resources:resource_list") + def privacy_policy(request): - return render(request, 'pages/privacy_policy.html') + return render(request, "pages/privacy_policy.html") |