from django.shortcuts import render, get_object_or_404, redirect from django.db.models import Sum, Count, F from django.db.models.functions import TruncDate, TruncMonth from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt from .models import Product, Sale, Category, Customer, Supplier, Purchase, SaleItem, SystemSetting import json from datetime import timedelta from django.utils import timezone from django.contrib import messages def index(request): """ Enhanced Meezan Dashboard View """ # Summary Stats total_products = Product.objects.count() total_sales_count = Sale.objects.count() total_sales_amount = Sale.objects.aggregate(total=Sum('total_amount'))['total'] or 0 total_customers = Customer.objects.count() # Stock Alert (Low stock < 5) low_stock_products = Product.objects.filter(stock_quantity__lt=5) # Recent Transactions recent_sales = Sale.objects.order_by('-created_at')[:5] # Chart Data: Sales for the last 7 days seven_days_ago = timezone.now().date() - timedelta(days=6) sales_over_time = Sale.objects.filter(created_at__date__gte=seven_days_ago) \ .annotate(date=TruncDate('created_at')) \ .values('date') \ .annotate(total=Sum('total_amount')) \ .order_by('date') # Prepare data for Chart.js chart_labels = [] chart_data = [] date_dict = {s['date']: float(s['total']) for s in sales_over_time} for i in range(7): date = seven_days_ago + timedelta(days=i) chart_labels.append(date.strftime('%b %d')) chart_data.append(date_dict.get(date, 0)) context = { 'total_products': total_products, 'total_sales_count': total_sales_count, 'total_sales_amount': total_sales_amount, 'total_customers': total_customers, 'low_stock_products': low_stock_products, 'recent_sales': recent_sales, 'chart_labels': json.dumps(chart_labels), 'chart_data': json.dumps(chart_data), } return render(request, 'core/index.html', context) def inventory(request): products = Product.objects.all().select_related('category') categories = Category.objects.all() context = {'products': products, 'categories': categories} return render(request, 'core/inventory.html', context) def pos(request): products = Product.objects.all().filter(stock_quantity__gt=0) customers = Customer.objects.all() categories = Category.objects.all() context = {'products': products, 'customers': customers, 'categories': categories} return render(request, 'core/pos.html', context) def customers(request): customers_list = Customer.objects.all().annotate(total_sales=Sum('sale__total_amount')) context = {'customers': customers_list} return render(request, 'core/customers.html', context) def suppliers(request): suppliers_list = Supplier.objects.all() context = {'suppliers': suppliers_list} return render(request, 'core/suppliers.html', context) def purchases(request): purchases_list = Purchase.objects.all().select_related('supplier') suppliers_list = Supplier.objects.all() context = {'purchases': purchases_list, 'suppliers': suppliers_list} return render(request, 'core/purchases.html', context) def reports(request): """ Smart Reports View """ # Monthly Revenue monthly_sales = Sale.objects.annotate(month=TruncMonth('created_at')) \ .values('month') \ .annotate(total=Sum('total_amount')) \ .order_by('-month')[:12] # Top Selling Products top_products = SaleItem.objects.values('product__name_en', 'product__name_ar') \ .annotate(total_qty=Sum('quantity'), revenue=Sum('line_total')) \ .order_by('-total_qty')[:5] context = { 'monthly_sales': monthly_sales, 'top_products': top_products, } return render(request, 'core/reports.html', context) def settings_view(request): """ Smart Admin Settings View """ settings = SystemSetting.objects.first() if not settings: settings = SystemSetting.objects.create() if request.method == 'POST': settings.business_name = request.POST.get('business_name') settings.address = request.POST.get('address') settings.phone = request.POST.get('phone') settings.email = request.POST.get('email') settings.currency_symbol = request.POST.get('currency_symbol') settings.tax_rate = request.POST.get('tax_rate') settings.save() messages.success(request, "Settings updated successfully!") return redirect('settings') return render(request, 'core/settings.html', {'settings': settings}) @csrf_exempt def create_sale_api(request): if request.method == 'POST': try: data = json.loads(request.body) customer_id = data.get('customer_id') items = data.get('items', []) total_amount = data.get('total_amount', 0) discount = data.get('discount', 0) customer = None if customer_id: customer = Customer.objects.get(id=customer_id) sale = Sale.objects.create( customer=customer, total_amount=total_amount, discount=discount ) for item in items: product = Product.objects.get(id=item['id']) SaleItem.objects.create( sale=sale, product=product, quantity=item['quantity'], unit_price=item['price'], line_total=item['line_total'] ) product.stock_quantity -= item['quantity'] product.save() settings = SystemSetting.objects.first() return JsonResponse({ 'success': True, 'sale_id': sale.id, 'business': { 'name': settings.business_name, 'address': settings.address, 'phone': settings.phone, 'currency': settings.currency_symbol }, 'sale': { 'id': sale.id, 'created_at': sale.created_at.strftime("%Y-%m-%d %H:%M"), 'total': float(sale.total_amount), 'items': [ { 'name_en': item.product.name_en, 'name_ar': item.product.name_ar, 'qty': item.quantity, 'price': float(item.unit_price), 'total': float(item.line_total) } for item in sale.items.all() ] } }) except Exception as e: return JsonResponse({'success': False, 'error': str(e)}, status=400) return JsonResponse({'success': False, 'error': 'Invalid request'}, status=405) def add_customer(request): if request.method == 'POST': name = request.POST.get('name') phone = request.POST.get('phone') email = request.POST.get('email') address = request.POST.get('address') Customer.objects.create(name=name, phone=phone, email=email, address=address) messages.success(request, "Customer added successfully!") return redirect('customers') def add_supplier(request): if request.method == 'POST': name = request.POST.get('name') contact_person = request.POST.get('contact_person') phone = request.POST.get('phone') Supplier.objects.create(name=name, contact_person=contact_person, phone=phone) messages.success(request, "Supplier added successfully!") return redirect('suppliers') def add_purchase(request): if request.method == 'POST': supplier_id = request.POST.get('supplier') total_amount = request.POST.get('total_amount') supplier = get_object_or_404(Supplier, id=supplier_id) Purchase.objects.create(supplier=supplier, total_amount=total_amount) messages.success(request, "Purchase recorded successfully!") return redirect('purchases') def add_product(request): if request.method == 'POST': name_en = request.POST.get('name_en') name_ar = request.POST.get('name_ar') category_id = request.POST.get('category') sku = request.POST.get('sku') price = request.POST.get('price') stock = request.POST.get('stock') category = get_object_or_404(Category, id=category_id) Product.objects.create( name_en=name_en, name_ar=name_ar, category=category, sku=sku, price=price, stock_quantity=stock ) messages.success(request, "Product added successfully!") return redirect('inventory')