adding multiple subscriptions
This commit is contained in:
@@ -22,6 +22,7 @@ class SubscriptionForm(forms.ModelForm):
|
||||
"title",
|
||||
"plan",
|
||||
"amount",
|
||||
"principal_types",
|
||||
] # Include all fields you want from the model
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 5.0.2 on 2024-04-07 10:07
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("accounts", "0006_iamprincipal_facebook_profile_and_more"),
|
||||
("manage_subscriptions", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="subscription",
|
||||
name="principal_types",
|
||||
field=models.ManyToManyField(
|
||||
blank=True,
|
||||
related_name="principal_type_subscriptions",
|
||||
to="accounts.iamprincipaltype",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -22,6 +22,11 @@ class Subscription(BaseModel):
|
||||
Plan, related_name="subscription_plan", on_delete=models.CASCADE
|
||||
)
|
||||
amount = models.DecimalField(max_digits=14, decimal_places=2, default=0.00)
|
||||
principal_types = models.ManyToManyField(
|
||||
IAmPrincipalType,
|
||||
related_name='principal_type_subscriptions',
|
||||
blank=True
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = "subscription"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from datetime import timedelta
|
||||
import json
|
||||
from django.http import HttpResponseBadRequest, JsonResponse
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
import stripe
|
||||
@@ -29,6 +30,7 @@ from django.urls import reverse_lazy
|
||||
from django.contrib import messages
|
||||
from goodtimes import constants
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.decorators.http import require_POST
|
||||
from django.conf import settings
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from django.views.generic.base import TemplateView
|
||||
@@ -382,19 +384,15 @@ class SubscriptionPageView(TemplateView):
|
||||
request = self.request
|
||||
if request.user.is_authenticated:
|
||||
print("request.user: ", request.user)
|
||||
if request.user.principal_type.name == "event_user":
|
||||
subscription_id = 2
|
||||
elif request.user.principal_type.name == "event_manager":
|
||||
subscription_id = 1
|
||||
else:
|
||||
subscription_id = None
|
||||
subscriptions = Subscription.objects.filter(
|
||||
principal_types=request.user.principal_type
|
||||
)
|
||||
|
||||
if subscription_id is not None:
|
||||
subscription = Subscription.objects.get(id=subscription_id)
|
||||
context['subscription_amount'] = subscription.amount
|
||||
if subscriptions.exists():
|
||||
context["subscriptions"] = subscriptions
|
||||
else:
|
||||
# Handle error or default case
|
||||
context['error'] = "Invalid principal type or subscription not found."
|
||||
# Handle the case where no subscriptions are found for the principal type.
|
||||
context["error"] = "No subscriptions found for your user type."
|
||||
return context
|
||||
|
||||
|
||||
@@ -406,106 +404,108 @@ def stripe_config(request):
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@require_POST
|
||||
def create_checkout_session(request):
|
||||
if request.method == "GET":
|
||||
stripe.api_key = settings.STRIPE_SECRET_KEY
|
||||
stripe.api_key = settings.STRIPE_SECRET_KEY
|
||||
data = json.loads(request.body)
|
||||
subscription_id = data.get("subscription_id", None)
|
||||
# if request.method == "GET":
|
||||
# subscription_id = None # Assuming 3 is a default or fallback subscription ID
|
||||
|
||||
subscription_id = None # Assuming 3 is a default or fallback subscription ID
|
||||
# if request.user.is_authenticated:
|
||||
# print("request.user: ", request.user)
|
||||
# if request.user.principal_type.name == "event_user":
|
||||
# subscription_id = 2
|
||||
# elif request.user.principal_type.name == "event_manager":
|
||||
# subscription_id = 1
|
||||
|
||||
if request.user.is_authenticated:
|
||||
print("request.user: ", request.user)
|
||||
if request.user.principal_type.name == "event_user":
|
||||
subscription_id = 2
|
||||
elif request.user.principal_type.name == "event_manager":
|
||||
subscription_id = 1
|
||||
|
||||
try:
|
||||
subscription = Subscription.objects.get(id=subscription_id)
|
||||
except Subscription.DoesNotExist:
|
||||
return ApiResponse.error(
|
||||
status=status.HTTP_404_NOT_FOUND, message="Subscription not found."
|
||||
)
|
||||
|
||||
order_id = (
|
||||
"order_" + str(timezone.localtime().timestamp()) + str(request.user.email)
|
||||
)
|
||||
print("order_id: ", order_id)
|
||||
|
||||
# Create a Transaction object with status INITIATE
|
||||
transaction = Transaction.objects.create(
|
||||
principal=request.user,
|
||||
principal_subscription=None, # Since the subscription is not created yet
|
||||
transaction_type=TransactionType.PAYMENT, # or PAYMENT, as applicable
|
||||
payment_method=PaymentMethod.CARD, # Assuming CARD for this example
|
||||
transaction_status=TransactionStatus.INITIATE,
|
||||
amount=subscription.amount, # Fetching amount from the Subscription object
|
||||
order_id=order_id,
|
||||
comment="Principal Subscription Initiated",
|
||||
try:
|
||||
subscription = Subscription.objects.get(id=subscription_id)
|
||||
except Subscription.DoesNotExist:
|
||||
return ApiResponse.error(
|
||||
status=status.HTTP_404_NOT_FOUND, message="Subscription not found."
|
||||
)
|
||||
|
||||
subscription_days = subscription.plan.days
|
||||
today = timezone.now().date()
|
||||
last_date = today + timedelta(days=int(subscription_days))
|
||||
order_id = (
|
||||
"order_" + str(timezone.localtime().timestamp()) + str(request.user.email)
|
||||
)
|
||||
print("order_id: ", order_id)
|
||||
|
||||
# To Avoid Duplicacy of Principal Subscription
|
||||
principal_subscription = PrincipalSubscription.objects.create(
|
||||
principal=request.user,
|
||||
subscription=subscription,
|
||||
is_paid=False,
|
||||
order_id=order_id,
|
||||
start_date=today,
|
||||
end_date=last_date,
|
||||
grace_period_end_date=last_date + timedelta(days=15),
|
||||
)
|
||||
# Create a Transaction object with status INITIATE
|
||||
transaction = Transaction.objects.create(
|
||||
principal=request.user,
|
||||
principal_subscription=None, # Since the subscription is not created yet
|
||||
transaction_type=TransactionType.PAYMENT, # or PAYMENT, as applicable
|
||||
payment_method=PaymentMethod.CARD, # Assuming CARD for this example
|
||||
transaction_status=TransactionStatus.INITIATE,
|
||||
amount=subscription.amount, # Fetching amount from the Subscription object
|
||||
order_id=order_id,
|
||||
comment="Principal Subscription Initiated",
|
||||
)
|
||||
|
||||
try:
|
||||
# customer = stripe.Customer.create(
|
||||
# email=request.user.email,
|
||||
# shipping={
|
||||
# "name": request.user.first_name,
|
||||
# "address": {
|
||||
# "line1": request.user.city,
|
||||
# "city": request.user.city,
|
||||
# "postal_code": "SW1A 2AA",
|
||||
# "country": request.user.address_line1, # Adjust accordingly
|
||||
# },
|
||||
# },
|
||||
# )
|
||||
subscription_days = subscription.plan.days
|
||||
today = timezone.now().date()
|
||||
last_date = today + timedelta(days=int(subscription_days))
|
||||
|
||||
# Create a checkout session
|
||||
checkout_session = stripe.checkout.Session.create(
|
||||
payment_method_types=["card"],
|
||||
# customer=customer.id, # Optional: Link the session to the Stripe customer created above
|
||||
line_items=[
|
||||
{
|
||||
"price_data": {
|
||||
"currency": "gbp",
|
||||
"product_data": {
|
||||
"name": subscription.title, # Adjust with your subscription/product name
|
||||
},
|
||||
"unit_amount": int(
|
||||
subscription.amount * 100
|
||||
), # Unit amount in cents/pence
|
||||
"tax_behavior": "inclusive", # or 'exclusive', based on your tax settings
|
||||
# To Avoid Duplicacy of Principal Subscription
|
||||
principal_subscription = PrincipalSubscription.objects.create(
|
||||
principal=request.user,
|
||||
subscription=subscription,
|
||||
is_paid=False,
|
||||
order_id=order_id,
|
||||
start_date=today,
|
||||
end_date=last_date,
|
||||
grace_period_end_date=last_date + timedelta(days=15),
|
||||
)
|
||||
|
||||
try:
|
||||
# customer = stripe.Customer.create(
|
||||
# email=request.user.email,
|
||||
# shipping={
|
||||
# "name": request.user.first_name,
|
||||
# "address": {
|
||||
# "line1": request.user.city,
|
||||
# "city": request.user.city,
|
||||
# "postal_code": "SW1A 2AA",
|
||||
# "country": request.user.address_line1, # Adjust accordingly
|
||||
# },
|
||||
# },
|
||||
# )
|
||||
|
||||
# Create a checkout session
|
||||
checkout_session = stripe.checkout.Session.create(
|
||||
payment_method_types=["card"],
|
||||
# customer=customer.id, # Optional: Link the session to the Stripe customer created above
|
||||
line_items=[
|
||||
{
|
||||
"price_data": {
|
||||
"currency": "gbp",
|
||||
"product_data": {
|
||||
"name": subscription.title, # Adjust with your subscription/product name
|
||||
},
|
||||
"quantity": 1,
|
||||
}
|
||||
],
|
||||
mode="payment",
|
||||
success_url=request.build_absolute_uri("/subscriptions/success/"),
|
||||
cancel_url=request.build_absolute_uri("/subscriptions/cancel/"),
|
||||
metadata={
|
||||
"principal": str(request.user.id),
|
||||
"order_id": str(order_id),
|
||||
# "subscription_id": str(subscription.id),
|
||||
"transaction_id": str(transaction.id),
|
||||
"principal_subscription_id": str(principal_subscription.id),
|
||||
},
|
||||
# Optionally, set shipping options, allow promotion codes, etc.
|
||||
)
|
||||
return JsonResponse({"sessionId": checkout_session["id"]})
|
||||
except Exception as e:
|
||||
return JsonResponse({"error": str(e)})
|
||||
"unit_amount": int(
|
||||
subscription.amount * 100
|
||||
), # Unit amount in cents/pence
|
||||
"tax_behavior": "inclusive", # or 'exclusive', based on your tax settings
|
||||
},
|
||||
"quantity": 1,
|
||||
}
|
||||
],
|
||||
mode="payment",
|
||||
success_url=request.build_absolute_uri("/subscriptions/success/"),
|
||||
cancel_url=request.build_absolute_uri("/subscriptions/cancel/"),
|
||||
metadata={
|
||||
"principal": str(request.user.id),
|
||||
"order_id": str(order_id),
|
||||
# "subscription_id": str(subscription.id),
|
||||
"transaction_id": str(transaction.id),
|
||||
"principal_subscription_id": str(principal_subscription.id),
|
||||
},
|
||||
# Optionally, set shipping options, allow promotion codes, etc.
|
||||
)
|
||||
return JsonResponse({"sessionId": checkout_session["id"]})
|
||||
except Exception as e:
|
||||
return JsonResponse({"error": str(e)})
|
||||
|
||||
|
||||
class SuccessView(TemplateView):
|
||||
|
||||
@@ -94,3 +94,18 @@ class WithdrawalRequestSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = models.WithdrawalRequest
|
||||
fields = ["notes"]
|
||||
|
||||
|
||||
class WithdrawalRequestViewSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = models.WithdrawalRequest
|
||||
fields = [
|
||||
"id",
|
||||
"coins",
|
||||
"amount",
|
||||
"notes",
|
||||
"reply",
|
||||
"status",
|
||||
"created_on",
|
||||
]
|
||||
read_only_fields = ["id", "created_on"]
|
||||
|
||||
@@ -13,8 +13,24 @@ urlpatterns = [
|
||||
),
|
||||
path("get-wallet/", views.GetWallet.as_view(), name="get_wallet"),
|
||||
path("get-transaction/", views.TransactionView.as_view(), name="transactions"),
|
||||
|
||||
path("create-stripe-connect/", views.CreateStripeConnectAccount.as_view(), name="stripe_connect"),
|
||||
path("add-bank-details/", views.PrincipalBankAccountCreateAPIView.as_view(), name="add_bank_account"),
|
||||
path('withdrawal-request/', views.WithdrawalRequestCreateAPI.as_view(), name='withdrawal-request-create'),
|
||||
path(
|
||||
"create-stripe-connect/",
|
||||
views.CreateStripeConnectAccount.as_view(),
|
||||
name="stripe_connect",
|
||||
),
|
||||
path(
|
||||
"add-bank-details/",
|
||||
views.PrincipalBankAccountCreateAPIView.as_view(),
|
||||
name="add_bank_account",
|
||||
),
|
||||
path(
|
||||
"create-withdrawal-request/",
|
||||
views.WithdrawalRequestCreateAPI.as_view(),
|
||||
name="withdrawal-request-create",
|
||||
),
|
||||
path(
|
||||
"view-withdrawal-request/",
|
||||
views.WithdrawalRequestView.as_view(),
|
||||
name="withdrawal-request-view",
|
||||
),
|
||||
]
|
||||
|
||||
@@ -366,7 +366,7 @@ class WithdrawalRequestCreateAPI(APIView):
|
||||
# Check if the user has a wallet and sufficient coins
|
||||
if wallet is None or wallet.coins <= 0:
|
||||
return ApiResponse.error(
|
||||
errors="Insufficient balance or no wallet found.",
|
||||
errors="Insufficient balance.",
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
message=constants.FAILURE,
|
||||
)
|
||||
@@ -389,7 +389,7 @@ class WithdrawalRequestCreateAPI(APIView):
|
||||
wallet.save()
|
||||
return ApiResponse.success(
|
||||
data=serializer.data,
|
||||
status=status.HTTP_201_CREATED,
|
||||
status=status.HTTP_200_OK,
|
||||
message=constants.SUCCESS,
|
||||
)
|
||||
else:
|
||||
@@ -398,3 +398,24 @@ class WithdrawalRequestCreateAPI(APIView):
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
message=constants.FAILURE,
|
||||
)
|
||||
|
||||
|
||||
class WithdrawalRequestView(APIView):
|
||||
authentication_classes = [JWTAuthentication]
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request):
|
||||
# Get the logged-in principal
|
||||
principal = request.user
|
||||
# Filter withdrawal requests by the logged-in principal
|
||||
withdrawal_requests = models.WithdrawalRequest.objects.filter(
|
||||
principal=principal
|
||||
).order_by("-created_on")
|
||||
serializer = serializers.WithdrawalRequestViewSerializer(
|
||||
withdrawal_requests, many=True
|
||||
)
|
||||
return ApiResponse.success(
|
||||
data=serializer.data,
|
||||
status=status.HTTP_200_OK,
|
||||
message=constants.SUCCESS,
|
||||
)
|
||||
|
||||
@@ -77,22 +77,27 @@
|
||||
<!-- <div class="container d-flex justify-content-center align-items-center"
|
||||
style="min-height: 100vh; background-color: #1a1a1a;"> -->
|
||||
<!-- Dark background for the overall page -->
|
||||
{% for subscription in subscriptions %}
|
||||
<div class="feat-card">
|
||||
<div class="card text-center mb-2">
|
||||
<!-- Dark card with gold border -->
|
||||
<h5 class="gold-text mb-0 p-1" style="background-color: #f1d59f6e;">Subscription Details
|
||||
<h5 class="gold-text mb-0 p-1" style="background-color: #f1d59f6e;">{{ subscription.title }}</h5>
|
||||
</div>
|
||||
<div class="card-body mb-2 text-center"> <!-- Golden text for the body -->
|
||||
<!-- Assuming you have a variable named subscription_amount accessible in your template. Replace accordingly. -->
|
||||
<h5 class="card-title gold-text">Subscription Amount </h5>
|
||||
<div class="text-center">
|
||||
<p class="gold-text mb-0">£ {{ subscription_amount }}</p>
|
||||
</div>
|
||||
<h5 class="card-title gold-text">Subscription Amount</h5>
|
||||
<p class="gold-text mb-0">£ {{ subscription.amount }}</p>
|
||||
</div>
|
||||
<div class="Adventure-btn text-center">
|
||||
<button class="common-btn" id="submitBtn">Join now</button>
|
||||
<!-- Add a data attribute to store subscription ID -->
|
||||
<button class="common-btn subscribe-btn"
|
||||
data-subscription-id="{{ subscription.id }}">Join now</button>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
{% empty %}
|
||||
<p>No subscriptions available.</p>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
<!-- </div> -->
|
||||
|
||||
@@ -424,7 +429,7 @@
|
||||
console.log("Sanity check!");
|
||||
var button = document.getElementById("submitBtn");
|
||||
|
||||
// Then, disable the button
|
||||
// Then, disable the button
|
||||
|
||||
|
||||
// Get Stripe publishable key
|
||||
@@ -436,21 +441,50 @@
|
||||
|
||||
// new
|
||||
// Event handler
|
||||
document.querySelector("#submitBtn").addEventListener("click", () => {
|
||||
button.disabled = true;
|
||||
// Get Checkout Session ID
|
||||
fetch("https://goodtimes.betadelivery.com/subscriptions/create-checkout-session/")
|
||||
.then((result) => { return result.json(); })
|
||||
.then((data) => {
|
||||
console.log(data);
|
||||
// Redirect to Stripe Checkout
|
||||
return stripe.redirectToCheckout({ sessionId: data.sessionId })
|
||||
// document.querySelector("#submitBtn").addEventListener("click", () => {
|
||||
// button.disabled = true;
|
||||
// // Get Checkout Session ID
|
||||
// fetch("https://goodtimes.betadelivery.com/subscriptions/create-checkout-session/")
|
||||
// .then((result) => { return result.json(); })
|
||||
// .then((data) => {
|
||||
// console.log(data);
|
||||
// // Redirect to Stripe Checkout
|
||||
// return stripe.redirectToCheckout({ sessionId: data.sessionId })
|
||||
// })
|
||||
// .then((res) => {
|
||||
// console.log(res);
|
||||
// });
|
||||
// });
|
||||
|
||||
document.querySelectorAll(".subscribe-btn").forEach(button => {
|
||||
button.addEventListener("click", () => {
|
||||
const subscriptionId = button.getAttribute("data-subscription-id");
|
||||
button.disabled = true;
|
||||
// Create checkout session for the selected subscription
|
||||
fetch("https://goodtimes.betadelivery.com/subscriptions/create-checkout-session/", {
|
||||
// fetch("http://192.168.0.101:8000/subscriptions/create-checkout-session/", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ subscriptionId: subscriptionId }),
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
});
|
||||
.then((result) => { return result.json(); })
|
||||
.then((data) => {
|
||||
// Redirect to Stripe Checkout
|
||||
return stripe.redirectToCheckout({ sessionId: data.sessionId })
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error:", error);
|
||||
button.disabled = false;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user