288 lines
12 KiB
Python
288 lines
12 KiB
Python
from flask import jsonify
|
|
from app.utils.logger import logger
|
|
from app.api.services.base_service import BaseService
|
|
from sqlalchemy import func, desc
|
|
from app.api.helpers.response_helper import ResponseHelper
|
|
from app.api.schemas.user import UserSchema
|
|
from app.api.schemas.subscription_session import SubscriptionSession
|
|
from marshmallow import ValidationError
|
|
from app.models import Members, MembersProducts, SubscriptionOptions, SubscriptionOptionsItems, PaymentsSession
|
|
from app.extensions import db
|
|
from app.api.integrations import StripeIntegration
|
|
import json
|
|
|
|
|
|
|
|
class SubscriptionService(BaseService):
|
|
# def get_all_subscriptions(cls, product_id=None, member_id=None, page=1, limit=20):
|
|
@staticmethod
|
|
def get_subscription_data(filters=None):
|
|
try:
|
|
if filters is None:
|
|
filters = {}
|
|
|
|
# Extract filters
|
|
product_id = filters.get('product_id')
|
|
member_id = filters.get('member_id')
|
|
|
|
# Extract pagination parameters
|
|
page = int(filters.get('page', 1))
|
|
limit = int(filters.get('limit', 20))
|
|
|
|
# Ensure page and limit are valid
|
|
if page < 1:
|
|
page = 1
|
|
if limit < 1 or limit > 100:
|
|
limit = 20
|
|
|
|
membersSubList, total_count = MembersProducts.get_all_subscriptions(product_id, member_id, page, limit)
|
|
# Convert loans to dictionary format
|
|
member_sub_data = []
|
|
for subs in membersSubList:
|
|
member_sub_data.append({
|
|
'id': subs.id,
|
|
'member_id': subs.member_id,
|
|
'product_id': subs.product_id,
|
|
'internal_url': subs.internal_url,
|
|
'external_url': subs.external_url,
|
|
'dns_group': subs.dns_group,
|
|
'status': subs.status,
|
|
'updated': subs.updated,
|
|
"added": subs.added,
|
|
})
|
|
|
|
# Calculate total pages
|
|
total_pages = (total_count + limit - 1) // limit
|
|
|
|
response_data = {
|
|
'subscriptions': member_sub_data,
|
|
'count': len(member_sub_data),
|
|
'pagination': {
|
|
'total_count': total_count,
|
|
'total_pages': total_pages,
|
|
'current_page': page,
|
|
'limit': limit,
|
|
'has_next': page < total_pages,
|
|
'has_prev': page > 1
|
|
}
|
|
}
|
|
|
|
return response_data
|
|
|
|
except Exception as e:
|
|
logger.error(f"An error occurred while getting dashboard data: {str(e)}", exc_info=True)
|
|
return jsonify({"message": "Internal Server Error"}), 500
|
|
|
|
@staticmethod
|
|
def subscription_available_products(data):
|
|
try:
|
|
with db.session.begin():
|
|
validated_data = SubscriptionService.validate_data(data, UserSchema())
|
|
token = validated_data.get('token')
|
|
uid = validated_data.get('uid')
|
|
member_data = Members.get_member_by_uid(uid)
|
|
if not member_data:
|
|
invalid_data = {
|
|
"error_message": "Member Data",
|
|
"message_key": "invalid_member",
|
|
}
|
|
return ResponseHelper.success(data=invalid_data)
|
|
# option_name
|
|
|
|
member_id = member_data.id
|
|
option_name = member_data.option_name
|
|
trial_name = "TRIAL-90"
|
|
|
|
res_options = []
|
|
sub_options = SubscriptionOptions.get_subscription_options(1)
|
|
for t in sub_options:
|
|
if t.stripe_product_id is None or t.stripe_product_id.strip() == "" or t.stripe_price_id is None or t.stripe_price_id.strip() == "":
|
|
price_create_result = StripeIntegration.create_product(t.display_name, t.monthly)
|
|
logger.info(f"Inside Stripe_Product ===== : {price_create_result}")
|
|
if price_create_result:
|
|
SubscriptionOptions.set_stripe_product_id(t.uid,price_create_result['product_id']) # only relevant if it is USA
|
|
SubscriptionOptions.set_stripe_price_id(t.uid,price_create_result['price_id']) # only relevant if it is USA
|
|
|
|
res_options.append({
|
|
'option_id': t.id,
|
|
'package_uid': t.uid,
|
|
'display_name': t.display_name,
|
|
'option_name': t.option_name,
|
|
'monthly': round(t.monthly * 0.01, 2),
|
|
'stripe_product_id': t.stripe_product_id,
|
|
'stripe_price_id': t.stripe_price_id,
|
|
"items": SubscriptionService.subscription_items_data(t.option_name),
|
|
'added': t.added.isoformat() if t.added else None,
|
|
'updated': t.updated.isoformat() if t.updated else None
|
|
})
|
|
|
|
subscription_products_data = {
|
|
"current_product": {
|
|
"display_name": trial_name if option_name is None else option_name,
|
|
"subs": [
|
|
'Post Jobs',
|
|
'advanced instructors search',
|
|
'invite candidates',
|
|
'post events',
|
|
'Cancel Anytime'
|
|
],
|
|
"next_payment": '2025-10-15 11:00:07.47214'
|
|
},
|
|
'stripe_customer_id': member_data.stripe_customer_id,
|
|
"options": res_options
|
|
}
|
|
|
|
return ResponseHelper.success(data=subscription_products_data)
|
|
|
|
except Exception as e:
|
|
logger.error(f"An error occurred while getting dashboard data: {str(e)}", exc_info=True)
|
|
return jsonify({"message": "Internal Server Error"}), 500
|
|
|
|
@staticmethod
|
|
def subscription_items_data(option_name):
|
|
items_data = SubscriptionOptionsItems.get_subscription_item(option_name)
|
|
res_options_items = []
|
|
for t in items_data:
|
|
res_options_items.append({
|
|
'description': t.description
|
|
})
|
|
|
|
# return ['Post Jobs 222', 'advanced instructors search', 'invite candidates', 'post events',
|
|
# 'Cancel anytime']
|
|
return res_options_items
|
|
|
|
@staticmethod
|
|
def subscription_session_start(data):
|
|
try:
|
|
with db.session.begin():
|
|
# logger.info(f"Incoming MyProduct data ==>>>> {data}")
|
|
validated_data = SubscriptionService.validate_data(data, SubscriptionSession())
|
|
token = validated_data.get('token')
|
|
uid = validated_data.get('uid')
|
|
customerId = validated_data.get('customerId')
|
|
priceId = validated_data.get('priceId')
|
|
member_data = Members.get_member_by_uid(uid)
|
|
member_id = member_data.id
|
|
option_name = validated_data.get('option_name')
|
|
sub_option = SubscriptionOptions.get_subscription_options_by_option_name(option_name)
|
|
|
|
if sub_option is None:
|
|
logger.error(f"Invalid Option Name")
|
|
return []
|
|
|
|
stripe_session = StripeIntegration.create_checkout_session_subscription(priceId, customerId)
|
|
logger.info(f"Inside Stripe_Session ===== : {stripe_session}")
|
|
logger.info(f"Inside Stripe_Session ID ===== : {stripe_session.id}")
|
|
PaymentsSession.add_payment_session(member_id, option_name, 'STRIPE', stripe_session.id)
|
|
#
|
|
# product_id = validated_data.get('product_id')
|
|
# product_subscription_uid=''
|
|
# product_subscription_external_url = ''
|
|
# product_subscription_internal_url = ''
|
|
# product_data = Products.get_product_by_product_id(product_id)
|
|
# product_description = ProductsDetails.get_product_details_with_product_id('A000002')
|
|
# productDataStatus = product_data.status
|
|
#
|
|
# memberSubscription = MembersProducts.get_member_product_by_product_member_id(member_id, product_id)
|
|
# if memberSubscription is not None:
|
|
# logger.info(f"Incoming MyProduct data ==>>>> {memberSubscription}")
|
|
# productDataStatus = memberSubscription.status
|
|
# product_subscription_uid = memberSubscription.uid
|
|
# product_subscription_external_url = memberSubscription.external_url
|
|
# product_subscription_internal_url = memberSubscription.internal_url
|
|
|
|
|
|
# "banner": "banner.jpg",
|
|
# myproduct_data = {
|
|
# "myproudct": {
|
|
# "banner": product_data.banner,
|
|
# "description": product_description.details,
|
|
# "sale_text" : product_description.sale_text,
|
|
# "internal_url": product_subscription_internal_url,
|
|
# "external_url": product_subscription_external_url,
|
|
# "price_text": "90 days free and 3.95/Month",
|
|
# "product_id": product_data.product_id,
|
|
# "product_name": product_data.name,
|
|
# "product_subscription_uid": product_subscription_uid,
|
|
# "product_uid": product_data.uid,
|
|
# "promotion_text": "Start Free Today !",
|
|
# "subscription_uid": product_subscription_uid,
|
|
# "status": productDataStatus,
|
|
# "subscription_text": "Start with your goals in mind and then work possible.ith yand Goals. If the plan doesn\u2019t support the vision then change it!",
|
|
# "title": "Your personal professional web presence"
|
|
# }
|
|
# }
|
|
|
|
# Simulate processing
|
|
response_data = {
|
|
"stripe_session":stripe_session.url,
|
|
"member_id": member_id,
|
|
"uid": uid,
|
|
}
|
|
|
|
return ResponseHelper.success(data=response_data)
|
|
|
|
except ValidationError as err:
|
|
|
|
logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}")
|
|
db.session.rollback()
|
|
return ResponseHelper.unprocessable_entity(result_description="Validation exception")
|
|
|
|
except ValueError as err:
|
|
logger.error(f"{getattr(err, 'messages', str(err))}")
|
|
db.session.rollback()
|
|
return ResponseHelper.error(result_description=str(err))
|
|
|
|
except Exception as e:
|
|
logger.error(f"An error occurred: {str(e)}", exc_info=True)
|
|
db.session.rollback()
|
|
return ResponseHelper.internal_server_error()
|
|
|
|
|
|
|
|
@staticmethod
|
|
def subscription_webhook_start(data):
|
|
try:
|
|
with db.session.begin():
|
|
hook_data = data["data"]["object"]
|
|
# logger.info(f"***** HOOK Data ALL ==>>>> {hook_data}")
|
|
# json_hook_output = json.dumps(hook_data["data"])
|
|
|
|
for key, value in hook_data.items():
|
|
logger.info(f"**************** Key: {key}, *********** Value: {value}")
|
|
|
|
data_id = hook_data["id"]
|
|
amount_subtotal =hook_data["amount_subtotal"]
|
|
logger.info(f"HOOK Result DATA ==>>>> {data_id} {amount_subtotal}")
|
|
|
|
|
|
|
|
|
|
|
|
# Simulate processing
|
|
response_data = {
|
|
"data_id": data_id,
|
|
"member_id": "",
|
|
"uid": "",
|
|
}
|
|
|
|
return ResponseHelper.success(data=response_data)
|
|
|
|
except ValidationError as err:
|
|
|
|
logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}")
|
|
db.session.rollback()
|
|
return ResponseHelper.unprocessable_entity(result_description="Validation exception")
|
|
|
|
except ValueError as err:
|
|
logger.error(f"{getattr(err, 'messages', str(err))}")
|
|
db.session.rollback()
|
|
return ResponseHelper.error(result_description=str(err))
|
|
|
|
except Exception as e:
|
|
logger.error(f"An error occurred: {str(e)}", exc_info=True)
|
|
db.session.rollback()
|
|
return ResponseHelper.internal_server_error()
|
|
|
|
|