From da1724c6718a50bdfde298b46762a89d5d6106b2 Mon Sep 17 00:00:00 2001 From: "CHIEFSOFT\\ameye" Date: Sat, 23 Aug 2025 13:39:38 -0400 Subject: [PATCH] sub scription prooductds --- SQL/site_data.sql | 24 +++++++++++++++++++++++- app/api/integrations/merms_stripe.py | 15 ++++++++++----- app/api/services/login.py | 4 ++++ app/api/services/subscription.py | 25 ++++++++++++++++++++----- app/models/members.py | 2 ++ app/models/subscription_options.py | 27 +++++++++++++++++++++++++++ 6 files changed, 86 insertions(+), 11 deletions(-) diff --git a/SQL/site_data.sql b/SQL/site_data.sql index ba75352..3eb7e9b 100644 --- a/SQL/site_data.sql +++ b/SQL/site_data.sql @@ -46,7 +46,7 @@ ALTER TABLE members ALTER COLUMN password TYPE VARCHAR(250); ALTER TABLE members ADD country VARCHAR(3); ALTER TABLE members ADD stripe_customer_id VARCHAR(100) ALTER TABLE members ADD profile_completed timestamp without time zone DEFAULT NULL; - +ALTER TABLE members ADD option_name VARCHAR(100) REFERENCES subscription_options(option_name) CREATE TABLE members_profile( id SERIAL, @@ -310,6 +310,8 @@ CREATE TABLE subscription_options ( ALTER TABLE ONLY subscription_options ADD CONSTRAINT subscription_options_id_key UNIQUE (id); +ALTER TABLE subscription_options ADD stripe_product_id VARCHAR(100); +ALTER TABLE subscription_options ADD stripe_price_id VARCHAR(100); ALTER TABLE subscription_options OWNER TO merms_panel; @@ -336,6 +338,12 @@ CREATE TABLE subscription_options_items ( ALTER TABLE ONLY subscription_options_items ADD CONSTRAINT subscription_options_items_id_key UNIQUE (id); + + + + + + ALTER TABLE subscription_options_items OWNER TO merms_panel; INSERT INTO subscription_options_items (option_name,description,list_order) @@ -360,6 +368,20 @@ INSERT INTO subscription_options_items (option_name,description,list_order) INSERT INTO subscription_options_items (option_name,description,list_order) VALUES('BASIC001','Everything in Starter Plus',0); +INSERT INTO subscription_options_items (option_name,description,list_order) + VALUES('BASIC001','5 Site Plugins',2); + +INSERT INTO subscription_options_items (option_name,description,list_order) + VALUES('BASIC001','1 Automatic Content Posting per Week',4); + +INSERT INTO subscription_options_items (option_name,description,list_order) + VALUES('BASIC001','Basic Site Traffic Engagement',6); + +INSERT INTO subscription_options_items (option_name,description,list_order) + VALUES('BASIC001','Basic Site Intelligence',8); + + + INSERT INTO subscription_options_items (option_name,description,list_order) VALUES('BASIC001','',0); diff --git a/app/api/integrations/merms_stripe.py b/app/api/integrations/merms_stripe.py index 59149f0..c752d2d 100644 --- a/app/api/integrations/merms_stripe.py +++ b/app/api/integrations/merms_stripe.py @@ -22,16 +22,20 @@ class StripeIntegration: # payment_method="pm_card_visa", # Replace with a valid payment method ID or attach one later return customer - def create_product(self, data): - # Example of creating a Product and Price - product = stripe.Product.create(name="Premium Plan") + @staticmethod + def create_product(display_name, monthly): + logger.info(f"Inside Stripe_Product ===== : {display_name}") + product_name = display_name + product = stripe.Product.create(name=product_name) price = stripe.Price.create( - unit_amount=1000, # Amount in cents (e.g., $10.00) + unit_amount=monthly, # Amount in cents (e.g., $10.00) currency="usd", recurring={"interval": "month"}, product=product.id, ) + return {'product_id': product.id, 'price_id': price.id} + @staticmethod def create_subscription(self, data): subscription = stripe.Subscription.create( customer='customer.id', @@ -40,4 +44,5 @@ class StripeIntegration: ], payment_behavior="default_incomplete", # Recommended for handling initial payment expand=["latest_invoice.payment_intent"], # To get details for payment confirmation - ) \ No newline at end of file + ) + diff --git a/app/api/services/login.py b/app/api/services/login.py index 9b30410..98c8b4c 100644 --- a/app/api/services/login.py +++ b/app/api/services/login.py @@ -1,4 +1,6 @@ from flask import session, jsonify + +from app.api.integrations import StripeIntegration from app.utils.logger import logger from app.api.services.base_service import BaseService from marshmallow import ValidationError @@ -235,6 +237,8 @@ class LoginService(BaseService): Config.JWT_SECRET_KEY, algorithm="HS256" ) + # price_create_result = StripeIntegration.create_product('AmeyeTEST', 9999) + # logger.info(f"Inside Stripe_Product ===== : {price_create_result}") # Simulate processing response_data = { diff --git a/app/api/services/subscription.py b/app/api/services/subscription.py index cfe9d26..affd3c6 100644 --- a/app/api/services/subscription.py +++ b/app/api/services/subscription.py @@ -6,7 +6,7 @@ from app.api.helpers.response_helper import ResponseHelper from app.api.schemas.user import UserSchema from app.models import Members, MembersProducts, SubscriptionOptions, SubscriptionOptionsItems from app.extensions import db - +from app.api.integrations import StripeIntegration class SubscriptionService(BaseService): # def get_all_subscriptions(cls, product_id=None, member_id=None, page=1, limit=20): @@ -64,8 +64,6 @@ class SubscriptionService(BaseService): 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 @@ -78,10 +76,28 @@ class SubscriptionService(BaseService): 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']) + SubscriptionOptions.set_stripe_price_id(t.uid,price_create_result['price_id']) + res_options.append({ 'option_id': t.id, 'package_uid': t.uid, @@ -95,7 +111,7 @@ class SubscriptionService(BaseService): subscription_products_data = { "current_product": { - "display_name": "TRIAL-90", + "display_name": trial_name if option_name is None else option_name, "subs": [ 'Post Jobs', 'advanced instructors search', @@ -126,4 +142,3 @@ class SubscriptionService(BaseService): # return ['Post Jobs 222', 'advanced instructors search', 'invite candidates', 'post events', # 'Cancel anytime'] return res_options_items - diff --git a/app/models/members.py b/app/models/members.py index 8514479..02bfe50 100644 --- a/app/models/members.py +++ b/app/models/members.py @@ -23,6 +23,7 @@ class Members(db.Model): country = db.Column(db.String(3), nullable=True) profile_completed = db.Column(db.DateTime(timezone=False)) stripe_customer_id = db.Column(db.String(100), nullable=True) + option_name = db.Column(db.String(100), nullable=True) def to_dict(self): return { @@ -41,6 +42,7 @@ class Members(db.Model): "account_name": self.account_name, "firstname": self.firstname, "lastname": self.lastname, + 'option_name': self.option_name, "stripe_customer_id": self.stripe_customer_id } diff --git a/app/models/subscription_options.py b/app/models/subscription_options.py index 730457b..d616a9a 100644 --- a/app/models/subscription_options.py +++ b/app/models/subscription_options.py @@ -2,6 +2,7 @@ from datetime import datetime, timezone from app.extensions import db from sqlalchemy.sql import func +# Inside Stripe_Product ===== : {'product_id': 'prod_SvB4RlFx6qXK6v', 'price_id': 'price_1RzKi4LjZLojw6IZA246JDAa'} class SubscriptionOptions(db.Model): __tablename__ = 'subscription_options' @@ -14,6 +15,8 @@ class SubscriptionOptions(db.Model): status = db.Column(db.Integer, nullable=True, default=1) added = db.Column(db.DateTime(timezone=False), server_default=func.now()) updated = db.Column(db.DateTime(timezone=False), server_default=func.now(), onupdate=func.now()) + stripe_product_id = db.Column(db.String(100), nullable=True) + stripe_price_id = db.Column(db.String(100), nullable=True) @classmethod @@ -23,6 +26,28 @@ class SubscriptionOptions(db.Model): return None return sub_options + @classmethod + def set_stripe_product_id(cls,package_uid, stripe_product_id): + # Retrieve + sub_option = cls.query.filter_by(uid=str(package_uid)).first() + + if not sub_option: + raise ValueError(f"Reset with ID {package_uid} does not exist.") + + # Update stripe_product_id + sub_option.stripe_product_id = stripe_product_id + + @classmethod + def set_stripe_price_id(cls, package_uid, stripe_price_id): + # Retrieve + sub_option = cls.query.filter_by(uid=str(package_uid)).first() + + if not sub_option: + raise ValueError(f"Reset with ID {package_uid} does not exist.") + + # Update stripe_price_id + sub_option.stripe_price_id = stripe_price_id + def to_dict(self): return { @@ -31,6 +56,8 @@ class SubscriptionOptions(db.Model): "display_name": self.display_name, "status": self.status, "monthly": self.monthly, + "stripe_product_id": self.stripe_product_id, + "stripe_price_id": self.stripe_price_id, "added": self.added.isoformat() if self.added else None, "updated": self.updated.isoformat() if self.updated else None }