seller_central_backend/api/views.py
vickytechkey 1591802c8e
All checks were successful
Build and Deploy Beta / build-and-push (push) Successful in 1m14s
Build and Deploy Beta / deploy (push) Successful in 10s
move CsrfExemptSessionAuthentication definition to api/authentication.py to break import cycles and clean register/onboarding flow
2026-08-09 13:43:22 +05:30

210 lines
9.5 KiB
Python

import random
from datetime import date
from django.contrib.auth import authenticate, login
from django.contrib.auth.models import User
from rest_framework import viewsets, status
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.decorators import action
from .models import SupplierProfile, Product, Order, ReturnRequest, Wallet, WalletTransaction
from .serializers import (
UserSerializer, RegisterSerializer, ProductSerializer,
OrderSerializer, ReturnRequestSerializer, WalletSerializer
)
def get_active_user(request):
if request.user and request.user.is_authenticated:
return request.user
user, created = User.objects.get_or_create(username='demo_seller', email='demo@example.com')
if created:
user.set_password('super_secure_pass_123')
user.save()
SupplierProfile.objects.get_or_create(user=user, phone='9876543210', store_name='Teak Wood Craft Store')
Wallet.objects.get_or_create(supplier=user, outstanding=850.00, withdrawn=1250.00)
return user
class RegisterView(APIView):
def post(self, request):
serializer = RegisterSerializer(data=request.data)
if serializer.is_valid():
user = serializer.save()
login(request, user)
return Response(UserSerializer(user).data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class LoginView(APIView):
def post(self, request):
username = request.data.get('username')
password = request.data.get('password')
user = authenticate(username=username, password=password)
if user:
login(request, user)
return Response(UserSerializer(user).data)
return Response({'error': 'Invalid credentials'}, status=status.HTTP_400_BAD_REQUEST)
class VerifyOtpView(APIView):
def post(self, request):
otp = request.data.get('otp')
# Simulate verification - code '123456' is always verified
if otp == '123456':
return Response({'verified': True})
return Response({'verified': False, 'error': 'Invalid OTP code'}, status=status.HTTP_400_BAD_REQUEST)
class ProfileView(APIView):
def get(self, request):
user = get_active_user(request)
profile, _ = SupplierProfile.objects.get_or_create(user=user)
return Response(UserSerializer(user).data)
def put(self, request):
user = get_active_user(request)
profile, _ = SupplierProfile.objects.get_or_create(user=user)
# Update fields
profile.phone = request.data.get('phone', profile.phone)
profile.phone_verified = request.data.get('phone_verified', profile.phone_verified)
profile.email_verified = request.data.get('email_verified', profile.email_verified)
profile.gstin = request.data.get('gstin', profile.gstin)
profile.is_gstin_verified = request.data.get('is_gstin_verified', profile.is_gstin_verified)
profile.aadhar_file = request.data.get('aadhar_file', profile.aadhar_file)
profile.pan_file = request.data.get('pan_file', profile.pan_file)
profile.store_name = request.data.get('store_name', profile.store_name)
profile.store_logo = request.data.get('store_logo', profile.store_logo)
profile.business_bio = request.data.get('business_bio', profile.business_bio)
profile.street = request.data.get('street', profile.street)
profile.city = request.data.get('city', profile.city)
profile.state = request.data.get('state', profile.state)
profile.pincode = request.data.get('pincode', profile.pincode)
profile.latitude = request.data.get('latitude', profile.latitude)
profile.longitude = request.data.get('longitude', profile.longitude)
profile.is_profile_complete = request.data.get('is_profile_complete', profile.is_profile_complete)
profile.save()
return Response(UserSerializer(user).data)
class ProductViewSet(viewsets.ModelViewSet):
serializer_class = ProductSerializer
def get_queryset(self):
user = get_active_user(self.request)
return Product.objects.filter(supplier=user)
def perform_create(self, serializer):
user = get_active_user(self.request)
serializer.save(supplier=user)
class BulkUploadView(APIView):
def post(self, request):
user = get_active_user(request)
products_data = request.data.get('products', [])
created_products = []
for p_data in products_data:
sku = p_data.get('sku')
# Avoid duplicate sku
Product.objects.filter(sku=sku).delete()
product = Product.objects.create(
supplier=user,
title=p_data.get('title'),
category=p_data.get('category'),
price=p_data.get('price'),
stock=p_data.get('stock'),
sku=sku,
image=p_data.get('image', 'https://images.unsplash.com/photo-1544022613-e87ca75a784a?auto=format&fit=crop&q=80&w=100')
)
created_products.append(ProductSerializer(product).data)
return Response({'success': True, 'products': created_products})
class OrderViewSet(viewsets.ModelViewSet):
serializer_class = OrderSerializer
def get_queryset(self):
user = get_active_user(self.request)
if user.username == 'demo_seller':
if not Order.objects.filter(supplier=user).exists():
Order.objects.create(supplier=user, order_id='ORD-8492', date=date.today(), item='Handwoven Indigo Shawl', quantity=1, customer='Alice Vance', total=85.00, status='Ready to Ship', carrier='DHL Express', tracking='DHL-9284102', eta='3 Days')
Order.objects.create(supplier=user, order_id='ORD-8488', date=date.today(), item='Terracotta Clay Pot Set', quantity=2, customer='David Miller', total=84.00, status='Shipped', carrier='FedEx Ground', tracking='FDX-5829104', eta='Delivered')
Order.objects.create(supplier=user, order_id='ORD-8501', date=date.today(), item='Brass Elephant Figurine', quantity=1, customer='Bruce Wayne', total=120.00, status='Pending Acceptance', carrier='Pending', tracking='Pending', eta='N/A')
if not Order.objects.filter(supplier=user, status='Pending Acceptance').exists():
Order.objects.filter(supplier=user, order_id='ORD-8501').update(
status='Pending Acceptance',
carrier='Pending',
tracking='Pending',
eta='N/A'
)
return Order.objects.filter(supplier=user)
@action(detail=True, methods=['post'])
def accept(self, request, pk=None):
order = self.get_object()
order.status = 'Ready to Ship'
order.carrier = 'DHL Express'
order.tracking = f'DHL-{random.randint(100000, 999000)}'
order.eta = '3 Days'
order.save()
return Response(OrderSerializer(order).data)
@action(detail=True, methods=['post'])
def reject(self, request, pk=None):
order = self.get_object()
order.status = 'Rejected'
order.carrier = 'N/A'
order.tracking = 'N/A'
order.eta = 'N/A'
order.save()
return Response(OrderSerializer(order).data)
class ReturnRequestViewSet(viewsets.ModelViewSet):
serializer_class = ReturnRequestSerializer
def get_queryset(self):
user = get_active_user(self.request)
if user.username == 'demo_seller':
if not ReturnRequest.objects.filter(supplier=user).exists():
ReturnRequest.objects.create(supplier=user, return_id='RET-019', order_id='ORD-8411', customer='Lillian G.', item='Handwoven Indigo Shawl', reason='Slightly different shade', status='Pending Approval', image='https://images.unsplash.com/photo-1544022613-e87ca75a784a?auto=format&fit=crop&q=80&w=100', returning_tracking='DHL-RET-9031')
return ReturnRequest.objects.filter(supplier=user)
@action(detail=True, methods=['post'])
def action(self, request, pk=None):
ret = self.get_object()
action_type = request.data.get('action')
if action_type == 'Approved':
ret.status = 'In Transit'
else:
ret.status = 'Rejected'
ret.save()
return Response(ReturnRequestSerializer(ret).data)
class WalletView(APIView):
def get(self, request):
user = get_active_user(request)
wallet, _ = Wallet.objects.get_or_create(supplier=user)
return Response(WalletSerializer(wallet).data)
class WithdrawView(APIView):
def post(self, request):
user = get_active_user(request)
wallet, _ = Wallet.objects.get_or_create(supplier=user)
amount_str = request.data.get('amount')
try:
amount = float(amount_str)
except (TypeError, ValueError):
return Response({'error': 'Invalid amount'}, status=status.HTTP_400_BAD_REQUEST)
if amount <= 0 or amount > float(wallet.outstanding):
return Response({'error': 'Insufficient funds or invalid amount'}, status=status.HTTP_400_BAD_REQUEST)
wallet.outstanding = float(wallet.outstanding) - amount
wallet.withdrawn = float(wallet.withdrawn) + amount
wallet.save()
tx = WalletTransaction.objects.create(
wallet=wallet,
tx_id=f"TX-{random.randint(1000, 9999)}",
date=date.today(),
amount=amount,
status='Transferred'
)
return Response(WalletSerializer(wallet).data)