Added paddle
This commit is contained in:
@@ -6,7 +6,7 @@ import time
|
||||
|
||||
from django.shortcuts import render, redirect , get_object_or_404
|
||||
from .forms import OrganizationForm, ContactForm
|
||||
from .models import Organization,Document, DocumentTemplate, DemoCode, DocumentRiskControl, Risk, Control
|
||||
from .models import Organization,Document, DocumentTemplate, DemoCode, PaymentRecord, DocumentRiskControl, Risk, Control
|
||||
from backend.accounts.utils import send_confirmation_email, send_document_email, send_documet_to_expert, send_document_to_reviewer
|
||||
from django.contrib.admin.views.decorators import staff_member_required
|
||||
from .utils import generate_pdf, generate_risk_graph, generate_residual_risk_graph
|
||||
@@ -22,7 +22,11 @@ from django.template.loader import render_to_string
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from backend.accounts.models import ExpertAnalysisEmails
|
||||
from django.core.mail import send_mail
|
||||
|
||||
from django.views import View
|
||||
import re
|
||||
from decimal import Decimal
|
||||
from django.urls import reverse
|
||||
from urllib.parse import urlencode
|
||||
|
||||
# @login_required
|
||||
# def index(request):
|
||||
@@ -118,57 +122,141 @@ def pdf_view(request, document_id):
|
||||
document = get_object_or_404(Document, id=document_id)
|
||||
return generate_pdf(document)
|
||||
|
||||
def payment_page(request):
|
||||
error = None
|
||||
email = request.GET.get('email')
|
||||
if request.method == 'POST':
|
||||
import re
|
||||
class PaymentView(View):
|
||||
|
||||
template_name = 'payment.html'
|
||||
|
||||
def get(self,request):
|
||||
email = request.GET.get('email','').strip()
|
||||
status_view = request.GET.get('status')
|
||||
|
||||
pdl_client = settings.PADDLE_CLIENT_ID
|
||||
pdl_price = settings.PADDLE_PRICE_ID
|
||||
|
||||
if status_view == 'review':
|
||||
document = Document.objects.filter(organization__email__iexact=email).first()
|
||||
return render(request, 'payment_review.html', {'email': email, 'document': document})
|
||||
|
||||
if status_view == 'expert':
|
||||
document = Document.objects.filter(organization__email__iexact=email).first()
|
||||
return render(request, 'payment_expert_analysis.html', {'email': email, 'document': document})
|
||||
|
||||
return render(request, self.template_name, {
|
||||
'email': email,
|
||||
'pdl_client': pdl_client,
|
||||
'pdl_price': pdl_price})
|
||||
|
||||
def post(self, request):
|
||||
content_type = request.META.get('CONTENT_TYPE', '')
|
||||
if 'application/json' in content_type:
|
||||
try:
|
||||
payload = json.loads(request.body)
|
||||
return self._handle_paddle_payment(payload)
|
||||
except json.JSONDecodeError:
|
||||
return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)
|
||||
else:
|
||||
return self._handle_demo_code(request)
|
||||
|
||||
|
||||
def _handle_demo_code(self, request):
|
||||
email = request.GET.get('email', '').strip()
|
||||
error = None
|
||||
code = re.sub(r'\s+', '', request.POST.get('code', '')).upper()[:10]
|
||||
try:
|
||||
payment_code = DemoCode.objects.get(code=code)
|
||||
if payment_code.used:
|
||||
error = "CODE INVALID"
|
||||
else:
|
||||
org = Organization.objects.filter(email__iexact=email).first()
|
||||
payment_code.used = True
|
||||
payment_code.used_at = timezone.now()
|
||||
payment_code.company = org
|
||||
payment_code.save()
|
||||
document = Document.objects.get(organization = org)
|
||||
url = f"{site_domain}/pdf/{document.id}/"
|
||||
expert_emails_qs = ExpertAnalysisEmails.objects.values_list('email', flat=True).distinct()
|
||||
error = "Invalid demo code"
|
||||
return render(request, self.template_name, {'email': email, 'error': error})
|
||||
|
||||
# If document is incomplete, notify reviewers
|
||||
if document.status == Document.STATUS_INCOMPLETE:
|
||||
if expert_emails_qs:
|
||||
for email_addr in expert_emails_qs:
|
||||
try:
|
||||
send_document_to_reviewer(email_addr, document)
|
||||
except Exception:
|
||||
logger.exception("Failed to send incomplete document email to %s", email_addr)
|
||||
return render(request, 'payment_review.html', {'email': email, 'document': document})
|
||||
org = Organization.objects.filter(email__iexact=email).first()
|
||||
payment_code.used = True
|
||||
payment_code.used_at = timezone.now()
|
||||
payment_code.company = org
|
||||
payment_code.save()
|
||||
|
||||
# If organization requested expert analysis, mark waiting and notify experts
|
||||
if org.expert_analysis:
|
||||
document.status = Document.STATUS_WAITING
|
||||
document.save(update_fields=['status', 'modified_at'])
|
||||
expert_emails = [e for e in expert_emails_qs if e]
|
||||
if expert_emails:
|
||||
for email_addr in expert_emails:
|
||||
try:
|
||||
send_documet_to_expert(email_addr, document)
|
||||
except Exception:
|
||||
logger.exception("Failed to send expert analysis email to %s", email_addr)
|
||||
else:
|
||||
logger.info("No expert emails configured; skipping expert notifications.")
|
||||
return render(request, 'payment_expert_analysis.html', {'email': email, 'document': document})
|
||||
send_document_email(email, url, document)
|
||||
document.status = Document.STATUS_DONE
|
||||
document.save(update_fields=['status', 'modified_at'])
|
||||
return redirect(url)
|
||||
print(org, email)
|
||||
document = Document.objects.get(organization=org)
|
||||
return self._handle_document_flow(org, document, email)
|
||||
|
||||
except DemoCode.DoesNotExist:
|
||||
error = "❌ Invalid code"
|
||||
return render(request, 'payment.html', {'error': error})
|
||||
error = "Invalid demo code"
|
||||
return render(request, self.template_name, {'email': email, 'error': error})
|
||||
|
||||
def _handle_paddle_payment(self, data):
|
||||
try:
|
||||
customer_email = data.get('customer_email')
|
||||
transaction_id = data.get('transaction_id')
|
||||
amount = Decimal(data.get('amount', 0))
|
||||
currency = data.get('currency', 'EUR')
|
||||
|
||||
org = Organization.objects.filter(email__iexact=customer_email).first()
|
||||
if not org:
|
||||
return JsonResponse({'status': 'error', 'message': 'Organization not found'}, status=404)
|
||||
|
||||
PaymentRecord.objects.create(
|
||||
company=org,
|
||||
amount=amount,
|
||||
currency=currency,
|
||||
transaction_id=transaction_id,
|
||||
payment_date=timezone.now()
|
||||
)
|
||||
document = Document.objects.get(organization=org)
|
||||
return self._handle_document_flow(org, document, customer_email, json_response=True)
|
||||
|
||||
except Exception as e:
|
||||
logger.exception("Error saving Paddle payment: %s", e)
|
||||
return JsonResponse({'status': 'error', 'message': str(e)}, status=500)
|
||||
|
||||
def validate_code(request):
|
||||
if request.method == "POST":
|
||||
try:
|
||||
data = json.loads(request.body)
|
||||
code = data.get("code", "").strip().upper()
|
||||
valid = DemoCode.objects.filter(code=code, used=False).exists()
|
||||
time.sleep(1)
|
||||
return JsonResponse({"valid": valid})
|
||||
except Exception:
|
||||
return JsonResponse({"valid": False})
|
||||
return JsonResponse({"valid": False})
|
||||
|
||||
def _handle_document_flow(self, org, document, email, json_response=False):
|
||||
site_domain = settings.SITE_DOMAIN
|
||||
url = f"{site_domain}/pdf/{document.id}/"
|
||||
expert_emails_qs = ExpertAnalysisEmails.objects.values_list('email', flat=True).distinct()
|
||||
|
||||
if document.status == Document.STATUS_INCOMPLETE:
|
||||
review_url = f"{reverse('core:payment_page')}?{urlencode({'email': email, 'status': 'review'})}"
|
||||
for email_addr in expert_emails_qs:
|
||||
try:
|
||||
send_document_to_reviewer(email_addr, document)
|
||||
except Exception:
|
||||
logger.exception("Failed to send incomplete document email to %s", email_addr)
|
||||
if json_response:
|
||||
return JsonResponse({'status': 'review', 'redirect_url': review_url})
|
||||
return render(self.request, 'payment_review.html', {'email': email, 'document': document})
|
||||
|
||||
if org.expert_analysis:
|
||||
document.status = Document.STATUS_WAITING
|
||||
document.save(update_fields=['status', 'modified_at'])
|
||||
expert_url = f"{reverse('core:payment_page')}?{urlencode({'email': email, 'status': 'expert'})}"
|
||||
expert_emails = [e for e in expert_emails_qs if e]
|
||||
for email_addr in expert_emails:
|
||||
try:
|
||||
send_documet_to_expert(email_addr, document)
|
||||
except Exception:
|
||||
logger.exception("Failed to send expert analysis email to %s", email_addr)
|
||||
if json_response:
|
||||
return JsonResponse({'status': 'expert', 'redirect_url': expert_url})
|
||||
return render(self.request, 'payment_expert_analysis.html', {'email': email, 'document': document})
|
||||
|
||||
send_document_email(email, url, document)
|
||||
document.status = Document.STATUS_DONE
|
||||
document.save(update_fields=['status', 'modified_at'])
|
||||
|
||||
if json_response:
|
||||
return JsonResponse({'status': 'ok', 'redirect_url': url})
|
||||
return redirect(url)
|
||||
|
||||
|
||||
def no_confidential_data(request):
|
||||
return render(request, "no_confidential_data.html")
|
||||
@@ -217,16 +305,3 @@ def demo_codes_pdf_view(request):
|
||||
response['Content-Disposition'] = f'inline; filename=demo_codes_{timezone.now().strftime("%Y%m%d_%H%M%S")}.pdf'
|
||||
return response
|
||||
|
||||
@csrf_exempt
|
||||
def validate_code(request):
|
||||
if request.method == "POST":
|
||||
try:
|
||||
data = json.loads(request.body)
|
||||
code = data.get("code", "").strip().upper()
|
||||
from .models import DemoCode
|
||||
valid = DemoCode.objects.filter(code=code, used=False).exists()
|
||||
time.sleep(3)
|
||||
return JsonResponse({"valid": valid})
|
||||
except Exception:
|
||||
return JsonResponse({"valid": False})
|
||||
return JsonResponse({"valid": False})
|
||||
Reference in New Issue
Block a user