147 lines
4.9 KiB
Python
147 lines
4.9 KiB
Python
from django.contrib import messages
|
|
from django.contrib.auth import authenticate, login, logout
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.db.models import Sum
|
|
from django.shortcuts import redirect, render
|
|
|
|
from orders.models import Order
|
|
from products.models import WishlistItem
|
|
|
|
from .forms import ProfileForm, RegistrationForm
|
|
from .models import Profile
|
|
|
|
|
|
def _sync_delivery_location_session(request, user):
|
|
profile = getattr(user, 'profile', None)
|
|
if profile and profile.short_location:
|
|
request.session['delivery_location'] = profile.short_location
|
|
else:
|
|
request.session.pop('delivery_location', None)
|
|
|
|
|
|
def _recent_delivery_points(order_queryset, *, limit=3):
|
|
points = []
|
|
seen = set()
|
|
|
|
for order in order_queryset.exclude(address='').order_by('-created_at'):
|
|
key = (order.phone.strip(), order.address.strip(), order.location_label.strip())
|
|
if key in seen:
|
|
continue
|
|
seen.add(key)
|
|
points.append(order)
|
|
if len(points) >= limit:
|
|
break
|
|
|
|
return points
|
|
|
|
|
|
def login_view(request):
|
|
if request.user.is_authenticated:
|
|
return redirect('profile')
|
|
|
|
if request.method == 'POST':
|
|
username = request.POST.get('username', '').strip()
|
|
password = request.POST.get('password', '').strip()
|
|
|
|
if not username or not password:
|
|
return render(request, 'accounts/login.html', {'error': 'Username and password are required'})
|
|
|
|
user = authenticate(request, username=username, password=password)
|
|
|
|
if user:
|
|
login(request, user)
|
|
_sync_delivery_location_session(request, user)
|
|
messages.success(request, f'Welcome back, {username}!')
|
|
return redirect('profile')
|
|
|
|
return render(request, 'accounts/login.html', {'error': 'Invalid username or password. Please check and try again.'})
|
|
|
|
return render(request, 'accounts/login.html')
|
|
|
|
|
|
def register_view(request):
|
|
if request.user.is_authenticated:
|
|
return redirect('profile')
|
|
|
|
if request.method == 'POST':
|
|
form = RegistrationForm(request.POST)
|
|
if form.is_valid():
|
|
form.save()
|
|
messages.success(request, 'Account created successfully! Please log in.')
|
|
return redirect('login')
|
|
messages.error(request, 'Please correct the highlighted fields and try again.')
|
|
else:
|
|
form = RegistrationForm(initial={'register_as_seller': request.GET.get('seller') == '1'})
|
|
|
|
return render(
|
|
request,
|
|
'accounts/register.html',
|
|
{
|
|
'form': form,
|
|
'register_as_seller': request.GET.get('seller') == '1',
|
|
},
|
|
)
|
|
|
|
|
|
def logout_view(request):
|
|
logout(request)
|
|
request.session.pop('delivery_location', None)
|
|
return redirect('/')
|
|
|
|
|
|
@login_required
|
|
def profile_view(request):
|
|
user_orders = Order.objects.filter(user=request.user)
|
|
delivered_orders = user_orders.filter(status='Delivered')
|
|
recent_orders = user_orders.order_by('-created_at')[:5]
|
|
recent_delivery_points = _recent_delivery_points(user_orders, limit=3)
|
|
profile = getattr(request.user, 'profile', None)
|
|
|
|
total_spent = delivered_orders.aggregate(total=Sum('total_price')).get('total') or 0
|
|
wishlist_count = WishlistItem.objects.filter(user=request.user).count()
|
|
|
|
profile_checks = [
|
|
bool(request.user.email),
|
|
bool(profile and profile.phone),
|
|
bool(profile and profile.formatted_delivery_address),
|
|
bool(profile and profile.has_precise_location),
|
|
]
|
|
profile_completion = int(sum(profile_checks) / len(profile_checks) * 100) if profile_checks else 0
|
|
|
|
return render(
|
|
request,
|
|
'accounts/profile.html',
|
|
{
|
|
'user': request.user,
|
|
'profile': profile,
|
|
'orders_count': user_orders.count(),
|
|
'delivered_count': delivered_orders.count(),
|
|
'pending_count': user_orders.exclude(status='Delivered').count(),
|
|
'wishlist_count': wishlist_count,
|
|
'total_spent': total_spent,
|
|
'recent_orders': recent_orders,
|
|
'recent_delivery_points': recent_delivery_points,
|
|
'profile_completion': profile_completion,
|
|
},
|
|
)
|
|
|
|
|
|
@login_required
|
|
def edit_profile(request):
|
|
profile = getattr(request.user, 'profile', None)
|
|
if profile is None:
|
|
profile = Profile.objects.create(user=request.user)
|
|
|
|
if request.method == 'POST':
|
|
form = ProfileForm(request.POST, request.FILES, instance=profile, user=request.user)
|
|
if form.is_valid():
|
|
profile = form.save()
|
|
_sync_delivery_location_session(request, request.user)
|
|
messages.success(request, 'Profile updated successfully.')
|
|
return redirect('profile')
|
|
messages.error(request, 'Please correct the errors below.')
|
|
else:
|
|
form = ProfileForm(instance=profile, user=request.user)
|
|
|
|
return render(request, 'accounts/edit_profile.html', {'form': form, 'profile': profile})
|