38086-vm/core/views.py
2026-02-02 07:39:49 +00:00

237 lines
8.8 KiB
Python

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')