started implementing stripe

This commit is contained in:
2025-06-26 15:15:16 +02:00
parent 3a0659b63b
commit 9b85f3bb8d
24 changed files with 2025 additions and 103 deletions

View File

@@ -1,11 +1,12 @@
from flask import Blueprint, jsonify, request
from flask import Blueprint, jsonify, request, render_template, flash, redirect, url_for, current_app
from flask_login import login_required, current_user
from models import db, Room, RoomFile, User, DocuPulseSettings, HelpArticle
from models import db, Room, RoomFile, User, DocuPulseSettings, HelpArticle, Customer
from extensions import csrf
from utils.event_logger import log_event
import os
from datetime import datetime
import json
from routes.auth import require_password_change
admin = Blueprint('admin', __name__)
@@ -461,6 +462,7 @@ def create_pricing_plan():
try:
from models import PricingPlan
from utils.stripe_utils import create_stripe_product
# Get form data
name = request.form.get('name')
@@ -469,12 +471,15 @@ def create_pricing_plan():
annual_price = float(request.form.get('annual_price'))
features = json.loads(request.form.get('features', '[]'))
button_text = request.form.get('button_text', 'Get Started')
monthly_stripe_link = request.form.get('monthly_stripe_link', '')
annual_stripe_link = request.form.get('annual_stripe_link', '')
is_popular = request.form.get('is_popular') == 'true'
is_custom = request.form.get('is_custom') == 'true'
is_active = request.form.get('is_active') == 'true'
# Get Stripe ID fields
stripe_product_id = request.form.get('stripe_product_id', '')
stripe_monthly_price_id = request.form.get('stripe_monthly_price_id', '')
stripe_annual_price_id = request.form.get('stripe_annual_price_id', '')
# Get quota fields
room_quota = int(request.form.get('room_quota', 0))
conversation_quota = int(request.form.get('conversation_quota', 0))
@@ -497,8 +502,9 @@ def create_pricing_plan():
annual_price=annual_price,
features=features,
button_text=button_text,
monthly_stripe_link=monthly_stripe_link,
annual_stripe_link=annual_stripe_link,
stripe_product_id=stripe_product_id,
stripe_monthly_price_id=stripe_monthly_price_id,
stripe_annual_price_id=stripe_annual_price_id,
is_popular=is_popular,
is_custom=is_custom,
is_active=is_active,
@@ -514,6 +520,18 @@ def create_pricing_plan():
db.session.add(plan)
db.session.commit()
# If no Stripe IDs provided and plan is not custom, try to create Stripe product
if not is_custom and not stripe_product_id:
try:
stripe_data = create_stripe_product(plan)
plan.stripe_product_id = stripe_data['product_id']
plan.stripe_monthly_price_id = stripe_data['monthly_price_id']
plan.stripe_annual_price_id = stripe_data['annual_price_id']
db.session.commit()
except Exception as stripe_error:
# Log the error but don't fail the plan creation
current_app.logger.warning(f"Failed to create Stripe product for plan {plan.name}: {str(stripe_error)}")
return jsonify({'success': True, 'message': 'Pricing plan created successfully'})
except Exception as e:
@@ -544,6 +562,9 @@ def get_pricing_plan(plan_id):
'features': plan.features,
'button_text': plan.button_text,
'button_url': plan.button_url,
'stripe_product_id': plan.stripe_product_id,
'stripe_monthly_price_id': plan.stripe_monthly_price_id,
'stripe_annual_price_id': plan.stripe_annual_price_id,
'is_popular': plan.is_popular,
'is_custom': plan.is_custom,
'is_active': plan.is_active,
@@ -572,6 +593,7 @@ def update_pricing_plan(plan_id):
try:
from models import PricingPlan
from utils.stripe_utils import update_stripe_product
plan = PricingPlan.query.get(plan_id)
if not plan:
@@ -584,12 +606,15 @@ def update_pricing_plan(plan_id):
annual_price = float(request.form.get('annual_price'))
features = json.loads(request.form.get('features', '[]'))
button_text = request.form.get('button_text', 'Get Started')
monthly_stripe_link = request.form.get('monthly_stripe_link', '')
annual_stripe_link = request.form.get('annual_stripe_link', '')
is_popular = request.form.get('is_popular') == 'true'
is_custom = request.form.get('is_custom') == 'true'
is_active = request.form.get('is_active') == 'true'
# Get Stripe ID fields
stripe_product_id = request.form.get('stripe_product_id', '')
stripe_monthly_price_id = request.form.get('stripe_monthly_price_id', '')
stripe_annual_price_id = request.form.get('stripe_annual_price_id', '')
# Get quota fields
room_quota = int(request.form.get('room_quota', 0))
conversation_quota = int(request.form.get('conversation_quota', 0))
@@ -608,8 +633,9 @@ def update_pricing_plan(plan_id):
plan.annual_price = annual_price
plan.features = features
plan.button_text = button_text
plan.monthly_stripe_link = monthly_stripe_link
plan.annual_stripe_link = annual_stripe_link
plan.stripe_product_id = stripe_product_id
plan.stripe_monthly_price_id = stripe_monthly_price_id
plan.stripe_annual_price_id = stripe_annual_price_id
plan.is_popular = is_popular
plan.is_custom = is_custom
plan.is_active = is_active
@@ -621,6 +647,18 @@ def update_pricing_plan(plan_id):
db.session.commit()
# If plan has existing Stripe product and is not custom, try to update it
if not is_custom and plan.stripe_product_id:
try:
stripe_data = update_stripe_product(plan)
plan.stripe_product_id = stripe_data['product_id']
plan.stripe_monthly_price_id = stripe_data['monthly_price_id']
plan.stripe_annual_price_id = stripe_data['annual_price_id']
db.session.commit()
except Exception as stripe_error:
# Log the error but don't fail the plan update
current_app.logger.warning(f"Failed to update Stripe product for plan {plan.name}: {str(stripe_error)}")
return jsonify({'success': True, 'message': 'Pricing plan updated successfully'})
except Exception as e:
@@ -735,5 +773,62 @@ def get_pricing_plans():
'plans': plans_data
})
except Exception as e:
return jsonify({'error': str(e)}), 500
@admin.route('/customers')
@login_required
@require_password_change
def customers():
"""View all customers"""
if not current_user.is_admin:
flash('Access denied. Admin privileges required.', 'error')
return redirect(url_for('main.dashboard'))
# Check if this is a MASTER instance
is_master = os.environ.get('MASTER', 'false').lower() == 'true'
if not is_master:
flash('Access denied. Master admin privileges required.', 'error')
return redirect(url_for('main.dashboard'))
# Get all customers with pagination
page = request.args.get('page', 1, type=int)
per_page = 20
customers = Customer.query.order_by(Customer.created_at.desc()).paginate(
page=page, per_page=per_page, error_out=False
)
return render_template('admin/customers.html', customers=customers)
@admin.route('/customers/<int:customer_id>')
@login_required
@require_password_change
def get_customer_details(customer_id):
"""Get customer details for modal"""
if not current_user.is_admin:
return jsonify({'error': 'Access denied'}), 403
# Check if this is a MASTER instance
is_master = os.environ.get('MASTER', 'false').lower() == 'true'
if not is_master:
return jsonify({'error': 'Access denied'}), 403
try:
customer = Customer.query.get_or_404(customer_id)
# Get the associated plan
plan = None
if customer.subscription_plan_id:
from models import PricingPlan
plan = PricingPlan.query.get(customer.subscription_plan_id)
html = render_template('admin/customer_details_modal.html', customer=customer, plan=plan)
return jsonify({
'success': True,
'html': html
})
except Exception as e:
return jsonify({'error': str(e)}), 500