updated subscription 2

This commit is contained in:
rizwanisready
2024-03-18 18:36:29 +05:30
parent 9c39ec0a19
commit 6bf0dc03e6
9 changed files with 242 additions and 47 deletions

View File

@@ -0,0 +1,23 @@
# Generated by Django 5.0.2 on 2024-03-18 11:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("accounts", "0003_iamprincipal_player_id"),
]
operations = [
migrations.AlterField(
model_name="iamprincipallocation",
name="latitude",
field=models.DecimalField(decimal_places=15, max_digits=18),
),
migrations.AlterField(
model_name="iamprincipallocation",
name="longitude",
field=models.DecimalField(decimal_places=15, max_digits=18),
),
]

View File

@@ -371,8 +371,8 @@ class IAmPrincipalLocation(BaseModel):
principal = models.ForeignKey(
IAmPrincipal, related_name="principal_location", on_delete=models.CASCADE
)
latitude = models.DecimalField(max_digits=14, decimal_places=8)
longitude = models.DecimalField(max_digits=14, decimal_places=8)
latitude = models.DecimalField(max_digits=18, decimal_places=15)
longitude = models.DecimalField(max_digits=18, decimal_places=15)
class Meta:
db_table = "iam_principal_location"

View File

@@ -332,6 +332,7 @@ CRONJOBS = [
]
GOOGLE_MAPS_API_KEY = env.str("GOOGLE_MAPS_API_KEY")
PLACES_MAPS_API_KEY = env.str("GOOGLE_MAPS_API_KEY")
PLACES_MAP_WIDGET_HEIGHT = 480
PLACES_MAP_OPTIONS = '{"center": { "lat": 38.971584, "lng": -95.235072 }, "zoom": 10}'

View File

@@ -1,5 +1,6 @@
from rest_framework import serializers
from accounts.models import IAmPrincipalLocation
from manage_events.utils import get_location_info
from accounts.api.serializers import ProfileSerializer
from manage_events.models import (
EventMaster,
@@ -167,6 +168,26 @@ class IAmPrincipalLocationSerializer(serializers.ModelSerializer):
def create(self, validated_data):
principal = self.context["request"].user
latitude = validated_data.get("latitude")
longitude = validated_data.get("longitude")
location = get_location_info(latitude=latitude, longitude=longitude)
print("location: ", location)
city = location.get("city")
state = location.get("state")
country = location.get("country")
country_code = location.get("country_code")
if hasattr(principal, "city"):
principal.city = city or state # Use state as city if city is not found
if hasattr(principal, "state"):
principal.state = state
if hasattr(principal, "country"):
principal.country = country
if hasattr(principal, "address_line1"):
principal.address_line1 = country_code
# save the principal object after making changes
principal.save()
return IAmPrincipalLocation.objects.create(
principal=principal, **validated_data
)

View File

@@ -1,6 +1,8 @@
import math
from accounts.models import IAmPrincipalLocation
from manage_events.models import Event, Venue
from django.utils.timezone import now
import googlemaps
from django.conf import settings
def haversine(lon1, lat1, lon2, lat2):
@@ -68,5 +70,37 @@ def haversine_one(lon1, lat1, lon2, lat2):
return R * c
# Example usage:
API_KEY = settings.GOOGLE_MAPS_API_KEY
gmaps = googlemaps.Client(key=API_KEY)
def get_location_info(latitude, longitude):
reverse_geocode_result = gmaps.reverse_geocode((latitude, longitude))
if reverse_geocode_result:
location = reverse_geocode_result[0]
city = None
state = None
country = None
for component in location.get("address_components", []):
types = component.get("types", [])
print("types: ", types)
if "locality" in types:
city = component.get("long_name")
elif "administrative_area_level_1" in types:
state = component.get("long_name")
elif "country" in types:
country = component.get("long_name")
country_code = component.get("short_name")
if city is None and state is not None:
city = state
return {
"city": city,
"state": state,
"country": country,
"country_code": country_code,
}
else:
return {}

View File

@@ -1,6 +1,11 @@
from django.utils.timezone import now
import googlemaps
from manage_subscriptions.models import PrincipalSubscription, SubscriptionStatus
from django.conf import settings
API_KEY = settings.GOOGLE_MAPS_API_KEY
gmaps = googlemaps.Client(key=API_KEY)
def get_active_subscription_id_for_principal(principal):
@@ -8,7 +13,10 @@ def get_active_subscription_id_for_principal(principal):
active_subscriptions = PrincipalSubscription.objects.filter(
principal=principal,
status=SubscriptionStatus.ACTIVE,
is_paid=True,
cancelled=False,
deleted=False,
active=True,
end_date__gte=now().date(), # Ensure the subscription hasn't expired
).order_by(
"-end_date"
@@ -18,3 +26,27 @@ def get_active_subscription_id_for_principal(principal):
# Return the ID of the most recent active subscription
return active_subscriptions.first().id
return None
def get_location_info(latitude, longitude):
reverse_geocode_result = gmaps.reverse_geocode((latitude, longitude))
if reverse_geocode_result:
location = reverse_geocode_result[0]
city = None
state = None
country = None
for component in location.get("address_components", []):
types = component.get("types", [])
print("types: ", types)
if "locality" in types:
city = component.get("long_name")
elif "administrative_area_level_1" in types:
state = component.get("long_name")
elif "country" in types:
country = component.get("long_name")
return {"city": city, "state": state, "country": country}
else:
return {}

View File

@@ -438,23 +438,23 @@ def create_checkout_session(request):
)
try:
customer = stripe.Customer.create(
email=request.user.email,
shipping={
"name": request.user.first_name,
"address": {
"line1": "Test Address",
"city": "Test City",
"postal_code": "SW1A 2AA",
"country": "GB", # Adjust accordingly
},
},
)
# 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
# customer=customer.id, # Optional: Link the session to the Stripe customer created above
line_items=[
{
"price_data": {

View File

@@ -259,6 +259,63 @@ header nav ul li a:hover:after {
color: var(--white-other);
}
.plan-box {
display: none;
}
.your-plan {
width: 280px;
height: 100%;
background-color: white;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
border-radius: 8px;
margin-top: 15px;
}
.your-plans-main {
padding: 15px 20px 30px;
}
.your-plans-main .head {
font-size: 25px;
color: black;
font-weight: 500;
}
.your-plans-main .monthly-div-main {
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
padding: 15px 20px;
border-radius: 8px;
}
.your-plans-main .monthly-div-main .monthly-div {
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
padding: 6px 10px;
border-radius: 8px;
border: 1px solid rgb(215 169 72 / 28%);
}
.your-plans-main .your-heading {
color: var(--main-yellow);
font-size: 24px;
font-weight: 500;
}
.your-plans-main .your-subheading {
font-size: 24px;
font-weight: 500;
color: black;
}
.your-plans-main .your-subheading span {
font-size: 18px;
font-weight: 400;
}
.your-plans-btn {
text-align: center;
margin-top: 15px;
}
.baner-btn {
margin-top: 24px;
@@ -588,8 +645,17 @@ div#accordionExample {
}
@media (max-width: 767px) {
.plan-box {
display: block;
display: flex;
justify-content: center;
}
.baner-btn {
display: none;
}
.ptb {
padding: 20px 0 40px 0;
}

View File

@@ -71,8 +71,26 @@
</div>
<div class="baner-btn">
<button class="common-btn" id="submitBtn">Join now</button>
<button class="common-btn" id="popup-payment">Join now</button>
</div>
<div class="plan-box">
<div class="your-plan">
<div class="your-plans-main">
<p class="head">Your Plans</p>
<div class="monthly-div-main">
<div class="monthly-div">
<p class="your-heading">Monthly</p>
<p class="your-subheading">$5.55 /<span> month</span></p>
</div>
</div>
<div class="your-plans-btn">
<button class="common-btn" id="submitBtn">Join now</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
@@ -251,15 +269,15 @@
<div class="accordion-body">
<strong>This is the second item's accordion
body.</strong> It is hidden by default,
until the collapse plugin adds the
appropriate classes that we use to style
each element. These classes control the
overall appearance, as well as the showing
and hiding via CSS transitions. You can
modify any of this with custom CSS or
overriding our default variables. It's also
worth noting that just about any HTML can go
within the transition does limit overflow.
until the collapse plugin adds the
appropriate classes that we use to style
each element. These classes control the
overall appearance, as well as the showing
and hiding via CSS transitions. You can
modify any of this with custom CSS or
overriding our default variables. It's also
worth noting that just about any HTML can go
within the transition does limit overflow.
</div>
</div>
</div>
@@ -275,15 +293,15 @@
<div class="accordion-body">
<strong>This is the third item's accordion
body.</strong> It is hidden by default,
until the collapse plugin adds the
appropriate classes that we use to style
each element. These classes control the
overall appearance, as well as the showing
and hiding via CSS transitions. You can
modify any of this with custom CSS or
overriding our default variables. It's also
worth noting that just about any HTML can go
within the transition does limit overflow.
until the collapse plugin adds the
appropriate classes that we use to style
each element. These classes control the
overall appearance, as well as the showing
and hiding via CSS transitions. You can
modify any of this with custom CSS or
overriding our default variables. It's also
worth noting that just about any HTML can go
within the transition does limit overflow.
</div>
</div>
</div>
@@ -299,15 +317,15 @@
<div class="accordion-body">
<strong>This is the third item's accordion
body.</strong> It is hidden by default,
until the collapse plugin adds the
appropriate classes that we use to style
each element. These classes control the
overall appearance, as well as the showing
and hiding via CSS transitions. You can
modify any of this with custom CSS or
overriding our default variables. It's also
worth noting that just about any HTML can go
within the transition does limit overflow.
until the collapse plugin adds the
appropriate classes that we use to style
each element. These classes control the
overall appearance, as well as the showing
and hiding via CSS transitions. You can
modify any of this with custom CSS or
overriding our default variables. It's also
worth noting that just about any HTML can go
within the transition does limit overflow.
</div>
</div>
</div>