38193-vm/core/views.py
2026-02-06 17:02:42 +00:00

378 lines
13 KiB
Python

from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth import login
from .models import Category, Product, Vendor, Order, OrderItem, Profile, ProductReview, ProductImage, Article
from .forms import ProductForm, SignUpForm # Added SignUpForm
from django.contrib import messages
from django.db.models import Q, Avg
def home(request):
categories = Category.objects.all()[:6]
featured_products = Product.objects.filter(is_available=True)[:8]
new_arrivals = Product.objects.filter(is_available=True).order_by('-created_at')[:8]
selected_kebele = request.GET.get('kebele')
local_vendors = Vendor.objects.filter(is_verified=True)
if selected_kebele:
local_vendors = local_vendors.filter(kebele=selected_kebele)
local_vendors = local_vendors[:4]
latest_articles = Article.objects.filter(is_published=True).order_by('-created_at')[:3]
kebeles = [k[0] for k in Vendor.JIMMA_KEBELES]
return render(request, 'core/index.html', {
'categories': categories,
'featured_products': featured_products,
'new_arrivals': new_arrivals,
'local_vendors': local_vendors,
'latest_articles': latest_articles,
'kebeles': kebeles,
'selected_kebele': selected_kebele,
})
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
messages.success(request, "Registration successful. Welcome to Jimma Market!")
return redirect('index')
else:
form = SignUpForm()
return render(request, 'registration/signup.html', {'form': form})
def product_list(request):
query = request.GET.get('q')
category_slug = request.GET.get('category')
sort = request.GET.get('sort')
kebele = request.GET.get('kebele')
products = Product.objects.filter(is_available=True)
if query:
products = products.filter(
Q(name__icontains=query) |
Q(description__icontains=query)
)
if category_slug:
products = products.filter(category__slug=category_slug)
if kebele:
products = products.filter(vendor__kebele=kebele)
if sort == 'price_low':
products = products.order_by('price')
elif sort == 'price_high':
products = products.order_by('-price')
elif sort == 'newest':
products = products.order_by('-created_at')
categories = Category.objects.all()
kebeles = [k[0] for k in Vendor.JIMMA_KEBELES]
return render(request, 'core/product_list.html', {
'products': products,
'categories': categories,
'kebeles': kebeles,
'current_category': category_slug,
'current_sort': sort,
'current_kebele': kebele,
})
def product_detail(request, slug):
product = get_object_or_404(Product, slug=slug, is_available=True)
related_products = Product.objects.filter(category=product.category).exclude(id=product.id)[:4]
reviews = product.reviews.all().order_by('-created_at')
return render(request, 'core/product_detail.html', {
'product': product,
'related_products': related_products,
'reviews': reviews,
})
def product_review_submit(request, product_id):
if request.method == 'POST':
product = get_object_or_404(Product, id=product_id)
rating = request.POST.get('rating')
comment = request.POST.get('comment')
full_name = request.POST.get('full_name', 'Anonymous')
if request.user.is_authenticated:
full_name = f"{request.user.first_name} {request.user.last_name}".strip() or request.user.username
ProductReview.objects.create(
product=product,
user=request.user if request.user.is_authenticated else None,
full_name=full_name,
rating=rating,
comment=comment
)
messages.success(request, "Thank you for your review!")
return redirect('product_detail', slug=product.slug)
def category_products(request, slug):
category = get_object_or_404(Category, slug=slug)
products = category.products.filter(is_available=True)
kebele = request.GET.get('kebele')
if kebele:
products = products.filter(vendor__kebele=kebele)
kebeles = [k[0] for k in Vendor.JIMMA_KEBELES]
return render(request, 'core/category_products.html', {
'category': category,
'products': products,
'kebeles': kebeles,
'current_kebele': kebele
})
# Basic Cart System using Session
def get_cart(request):
cart = request.session.get('cart', {})
return cart
def cart_add(request, product_id):
cart = get_cart(request)
product_id_str = str(product_id)
quantity = int(request.POST.get('quantity', 1))
if product_id_str in cart:
cart[product_id_str] += quantity
else:
cart[product_id_str] = quantity
request.session['cart'] = cart
messages.success(request, "Product added to cart")
return redirect('cart_detail')
def cart_remove(request, product_id):
cart = get_cart(request)
product_id_str = str(product_id)
if product_id_str in cart:
del cart[product_id_str]
request.session['cart'] = cart
return redirect('cart_detail')
def cart_detail(request):
cart = get_cart(request)
cart_items = []
total = 0
for product_id, quantity in cart.items():
try:
product = Product.objects.get(id=product_id)
subtotal = product.price * quantity
total += subtotal
cart_items.append({'product': product, 'quantity': quantity, 'subtotal': subtotal})
except Product.DoesNotExist:
continue
return render(request, 'core/cart_detail.html', {'cart_items': cart_items, 'total': total})
def checkout(request):
cart = get_cart(request)
if not cart:
return redirect('product_list')
if request.method == 'POST':
full_name = request.POST.get('full_name')
email = request.POST.get('email')
phone = request.POST.get('phone')
address = request.POST.get('address')
kebele = request.POST.get('kebele')
delivery_time_slot = request.POST.get('delivery_time_slot')
payment_method = request.POST.get('payment_method')
total = 0
order_items_data = []
for product_id, quantity in cart.items():
product = get_object_or_404(Product, id=product_id)
total += product.price * quantity
order_items_data.append((product, quantity, product.price))
order = Order.objects.create(
user=request.user if request.user.is_authenticated else None,
full_name=full_name,
email=email,
phone=phone,
address=address,
kebele=kebele,
delivery_time_slot=delivery_time_slot,
total_price=total,
payment_method=payment_method
)
for product, quantity, price in order_items_data:
OrderItem.objects.create(order=order, product=product, quantity=quantity, price=price)
request.session['cart'] = {}
messages.success(request, "Order placed successfully!")
return redirect('order_success', order_id=order.id)
kebeles = Order.JIMMA_KEBELES
time_slots = Order.TIME_SLOTS
total = 0
for product_id, quantity in cart.items():
product = get_object_or_404(Product, id=product_id)
total += product.price * quantity
return render(request, 'core/checkout.html', {
'kebeles': kebeles,
'time_slots': time_slots,
'total': total,
})
def order_success(request, order_id):
order = get_object_or_404(Order, id=order_id)
return render(request, 'core/order_success.html', {'order': order})
@login_required
def vendor_register(request):
if hasattr(request.user, 'vendor'):
return redirect('vendor_dashboard')
if request.method == 'POST':
business_name = request.POST.get('business_name')
description = request.POST.get('description')
address = request.POST.get('address')
kebele = request.POST.get('kebele')
phone = request.POST.get('phone')
Vendor.objects.create(
user=request.user,
business_name=business_name,
description=description,
address=address,
kebele=kebele,
phone=phone
)
# Update user role
profile, created = Profile.objects.get_or_create(user=request.user)
profile.role = 'seller'
profile.save()
messages.success(request, "Vendor registration successful. Wait for admin verification.")
return redirect('vendor_dashboard')
return render(request, 'core/vendor_register.html', {'kebeles': Vendor.JIMMA_KEBELES})
@login_required
def vendor_dashboard(request):
vendor = get_object_or_404(Vendor, user=request.user)
products = vendor.products.all().order_by('-created_at')
# Get all orders that contain products from this vendor
# We use a set of order IDs to avoid duplicates if multiple products from same vendor in one order
vendor_order_items = OrderItem.objects.filter(product__vendor=vendor).select_related('order', 'product').order_by('-order__created_at')
return render(request, 'core/vendor_dashboard.html', {
'vendor': vendor,
'products': products,
'order_items': vendor_order_items
})
@login_required
def vendor_product_add(request):
vendor = get_object_or_404(Vendor, user=request.user)
if request.method == 'POST':
form = ProductForm(request.POST, request.FILES)
if form.is_valid():
product = form.save(commit=False)
product.vendor = vendor
product.save()
messages.success(request, "Product added successfully!")
return redirect('vendor_dashboard')
else:
form = ProductForm()
return render(request, 'core/vendor_product_form.html', {'form': form, 'title': 'Add New Product'})
@login_required
def vendor_product_edit(request, pk):
vendor = get_object_or_404(Vendor, user=request.user)
product = get_object_or_404(Product, pk=pk, vendor=vendor)
if request.method == 'POST':
form = ProductForm(request.POST, request.FILES, instance=product)
if form.is_valid():
form.save()
messages.success(request, "Product updated successfully!")
return redirect('vendor_dashboard')
else:
form = ProductForm(instance=product)
return render(request, 'core/vendor_product_form.html', {'form': form, 'title': f'Edit {product.name}'})
@login_required
def vendor_product_delete(request, pk):
vendor = get_object_or_404(Vendor, user=request.user)
product = get_object_or_404(Product, pk=pk, vendor=vendor)
if request.method == 'POST':
product.delete()
messages.success(request, "Product deleted successfully!")
return redirect('vendor_dashboard')
return render(request, 'core/vendor_product_confirm_delete.html', {'product': product})
@login_required
def vendor_order_status_update(request, order_id):
vendor = get_object_or_404(Vendor, user=request.user)
order = get_object_or_404(Order, id=order_id)
# Check if this vendor has products in this order
if not OrderItem.objects.filter(order=order, product__vendor=vendor).exists():
messages.error(request, "You don't have permission to update this order.")
return redirect('vendor_dashboard')
if request.method == 'POST':
new_status = request.POST.get('status')
if new_status in dict(Order.STATUS_CHOICES):
order.status = new_status
order.save()
messages.success(request, f"Order status updated to {new_status}")
return redirect('vendor_dashboard')
# Essential Pages
def about_us(request):
return render(request, 'core/about_us.html')
def how_it_works(request):
return render(request, 'core/how_it_works.html')
def seller_info(request):
return render(request, 'core/seller_info.html')
def delivery_info(request):
return render(request, 'core/delivery_info.html')
def contact_us(request):
if request.method == 'POST':
messages.success(request, "Thank you for your message. We will get back to you soon!")
return redirect('contact_us')
return render(request, 'core/contact_us.html')
def track_order(request):
order = None
if request.method == 'POST':
order_id = request.POST.get('order_id')
phone = request.POST.get('phone')
try:
order = Order.objects.get(id=order_id, phone=phone)
except (Order.DoesNotExist, ValueError):
messages.error(request, "Order not found. Please check your order ID and phone number.")
return render(request, 'core/track_order.html', {'order': order})
# Blog/Article Views
def article_list(request):
articles = Article.objects.filter(is_published=True).order_by('-created_at')
return render(request, 'core/article_list.html', {'articles': articles})
def article_detail(request, slug):
article = get_object_or_404(Article, slug=slug, is_published=True)
return render(request, 'core/article_detail.html', {'article': article})