35685-vm/core/views.py
2025-11-14 12:22:51 +00:00

134 lines
4.9 KiB
Python

from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login
from django.views.decorators.http import require_POST
from django.contrib.auth.decorators import login_required
from django.conf import settings
import requests
import json
from .models import Product, Category, Cart, CartItem, Order, OrderItem
def index(request):
"""Render the new landing page."""
products = Product.objects.filter(is_available=True)
categories = Category.objects.all()
context = {
'products': products,
'categories': categories,
}
return render(request, "core/index.html", context)
def signup(request):
"""Handle user signup."""
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
# You can log the user in directly if you want
# login(request, user)
return redirect('login')
else:
form = UserCreationForm()
return render(request, 'registration/signup.html', {'form': form})
def _get_cart(request):
if request.user.is_authenticated:
cart, created = Cart.objects.get_or_create(user=request.user)
else:
session_key = request.session.session_key
if not session_key:
request.session.create()
session_key = request.session.session_key
cart, created = Cart.objects.get_or_create(session_key=session_key)
return cart
@require_POST
def add_to_cart(request, product_id):
cart = _get_cart(request)
product = get_object_or_404(Product, id=product_id)
quantity = int(request.POST.get('quantity', 1))
cart_item, created = CartItem.objects.get_or_create(cart=cart, product=product)
if not created:
cart_item.quantity += quantity
else:
cart_item.quantity = quantity
cart_item.save()
return redirect('cart_detail')
def cart_detail(request):
cart = _get_cart(request)
return render(request, 'core/cart_detail.html', {'cart': cart})
@login_required
def checkout(request):
cart = _get_cart(request)
if not cart.items.all():
return redirect('index')
return render(request, 'core/cart_detail.html', {'cart': cart})
@login_required
def initiate_payment(request):
cart = _get_cart(request)
if not cart.items.all():
return redirect('index')
url = 'https://api.paystack.co/transaction/initialize'
headers = {
'Authorization': f'Bearer {settings.PAYSTACK_SECRET_KEY}',
'Content-Type': 'application/json',
}
data = {
"email": request.user.email,
"amount": cart.total_price_in_kobo,
"callback_.pyurl": request.build_absolute_uri(f"/verify-payment/"),
}
try:
response = requests.post(url, headers=headers, data=json.dumps(data))
response_data = response.json()
if response_data['status']:
# store the reference in the session, so we can retrieve it in the callback
request.session['payment_ref'] = response_data['data']['reference']
return redirect(response_data['data']['authorization_url'])
else:
return render(request, 'core/payment_failure.html', {'error': response_data['message']})
except requests.exceptions.RequestException as e:
return render(request, 'core/payment_failure.html', {'error': f"An error occurred: {e}"})
@login_required
def verify_payment(request):
ref = request.GET.get('reference')
if not ref:
# if the reference is not in the get request, check the session
ref = request.session.get('payment_ref')
if not ref:
return redirect('payment_failure')
url = f'https://api.paystack.co/transaction/verify/{ref}'
headers = {
'Authorization': f'Bearer {settings.PAYSTACK_SECRET_KEY}',
}
try:
response = requests.get(url, headers=headers)
response_data = response.json()
if response_data['status']:
if response_data['data']['status'] == 'success':
cart = _get_cart(request)
order = Order.objects.create(user=request.user, is_paid=True)
for item in cart.items.all():
OrderItem.objects.create(order=order, product=item.product, quantity=item.quantity)
cart.items.all().delete()
# clear the payment reference from the session
if 'payment_ref' in request.session:
del request.session['payment_ref']
return render(request, 'core/payment_success.html', {'order': order})
else:
return render(request, 'core/payment_failure.html')
else:
return render(request, 'core/payment_failure.html')
except requests.exceptions.RequestException as e:
return render(request, 'core/payment_failure.html', {'error': f"An error occurred: {e}"})