diff --git a/core/migrations/0019_auto_20240630_1037.py b/core/migrations/0019_auto_20240630_1037.py new file mode 100644 index 00000000..bdb0c114 --- /dev/null +++ b/core/migrations/0019_auto_20240630_1037.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.28 on 2024-06-30 10:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0018_auto_20230319_1707'), + ] + + operations = [ + migrations.AddField( + model_name='subscription', + name='cancelled', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='subscription', + name='cancelled_date', + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/core/models.py b/core/models.py index 9cac491d..658fbedd 100644 --- a/core/models.py +++ b/core/models.py @@ -311,3 +311,5 @@ class Subscription(models.Model): on_delete=models.CASCADE, related_name='organization_subscription' ) + cancelled = models.BooleanField(default=False) + cancelled_date = models.DateTimeField(null=True, blank=True) diff --git a/core/views/subscription.py b/core/views/subscription.py index 8b0a8037..9cfa6707 100644 --- a/core/views/subscription.py +++ b/core/views/subscription.py @@ -27,7 +27,7 @@ class SubscriptionViewSet(viewsets.ModelViewSet): All the subscriptions related actions """ - queryset = Subscription.objects.all() + queryset = Subscription.objects.filter(cancelled=False).order_by('-create_date') serializer_class = SubscriptionSerializer permission_classes = (AllowAny, IsAuthenticated) @@ -54,61 +54,39 @@ def create(self, request, *args, **kwargs): status=status.HTTP_400_BAD_REQUEST ) - # def update(self, request, *args, **kwargs): - # instance = self.get_object() - # if settings.STRIPE_SECRET: - # stripe.api_key = settings.STRIPE_SECRET - # stripe.api_version = '2022-11-15' - # data = self.get_stripe_details() - # if data: - # serializer = self.get_serializer(instance, data=data, partial=True) - # serializer.is_valid(raise_exception=True) - # self.perform_create(serializer) - - # product_info = data.get('stripe_product_info', {}) - # # send the email - # context = { - # 'frontend_link': settings.FRONTEND_URL, - # 'product_name': product_info.get('name'), - # 'product_description': product_info.get('description') - # } - # subject = 'Subscription Success' - # template_name = 'email/coreuser/subscription.txt' - # html_template_name = 'email/coreuser/subscription.html' - # send_email( - # self.request.user.email, - # subject, - # context, - # template_name, - # html_template_name - # ) - - # return Response( - # serializer.data, - # status=status.HTTP_201_CREATED - # ) - # return Response( - # dict( - # code='stripe_api_error', - # message='There was an error creating subscription' - # ), - # status=status.HTTP_400_BAD_REQUEST - # ) - - # return Response( - # dict( - # code='missing_stripe_details', - # message='Please pass valid product/card or stripe secret' - # ), - # status=status.HTTP_400_BAD_REQUEST - # ) - def perform_create(self, serializer): serializer.save( user=self.request.user, created_by=self.request.user, ) + def destroy(self, request, *args, **kwargs): + instance = self.get_object() + cancelled = self.perform_destroy(instance) + if not cancelled: + return Response( + dict( + code='stripe_api_error', + message='There was an error cancelling subscription', + ), + status=status.HTTP_400_BAD_REQUEST + ) + return Response( + dict(code='subscription_cancelled'), + status=status.HTTP_204_NO_CONTENT + ) + + def perform_destroy(self, instance): + # delete the subscription on stripe + cancelled = self.cancel_subscription_on_stripe(instance) + + if cancelled: + # delete the subscription + instance.cancelled = True + instance.cancelled_date = timezone.now() + instance.save() + return cancelled + @action( detail=False, methods=['get'], @@ -124,7 +102,7 @@ def stripe_products(self, request, *args, **kwargs): if settings.STRIPE_SECRET: stripe.api_key = settings.STRIPE_SECRET stripe.api_version = '2022-11-15' - stripe_products = stripe.Product.search(query="active:'true'",) + stripe_products = stripe.Product.search(query="active:'true'", ) products = stripe_products.data return Response( @@ -198,3 +176,21 @@ def get_stripe_details(self): return None return data + + @staticmethod + def cancel_subscription_on_stripe(instance): + """ + Cancel a subscription + """ + if settings.STRIPE_SECRET: + stripe.api_key = settings.STRIPE_SECRET + # stripe.api_version = '2022-11-15' + try: + # stripe.Subscription.cancel(instance.stripe_subscription_id) + subscription = stripe.Subscription.retrieve(instance.stripe_subscription_id) + subscription.delete() + return True + + except Exception as e: + pass + return False