""" HTML Views для модуля закупок (Frontend). """ from django.contrib.auth import get_user_model from django.contrib.auth.decorators import login_required from django.core.paginator import Paginator from django.shortcuts import get_object_or_404, render, redirect from django.utils import timezone from employees.models import Department from .models import ( Budget, Equipment, EquipmentCategory, ProcurementRequest, ) from .constants import ProcurementStatus User = get_user_model() @login_required def dashboard(request): """Главная страница модуля закупок.""" user = request.user now = timezone.now() quarter = (now.month - 1) // 3 + 1 # Получаем отделы пользователя user_departments = user.departments.filter( employeedepartment__is_active=True ) # Статистика stats = { 'pending': ProcurementRequest.objects.filter( status=ProcurementStatus.PENDING ).count(), 'approved': ProcurementRequest.objects.filter( status=ProcurementStatus.APPROVED ).count(), 'equipment': Equipment.objects.count(), } # Бюджет отдела (берём первый отдел пользователя) budget = None if user_departments.exists(): budget = Budget.objects.filter( department=user_departments.first(), year=now.year, quarter=quarter ).first() # Последние заявки (мои или моего отдела) recent_requests = ProcurementRequest.objects.filter( department__in=user_departments ).select_related( 'department', 'requestor' ).order_by('-created_at')[:5] # Права на согласование can_approve = user.is_staff or user.headed_departments.exists() context = { 'stats': stats, 'budget': budget, 'recent_requests': recent_requests, 'can_approve': can_approve, } return render(request, 'procurement/dashboard.html', context) @login_required def request_list(request): """Список заявок на закупку.""" user = request.user scope = request.GET.get('scope', 'mine') # Базовый queryset queryset = ProcurementRequest.objects.select_related( 'department', 'requestor' ).prefetch_related('items') # Фильтрация по области видимости if scope == 'mine': queryset = queryset.filter(requestor=user) page_title = 'Мои заявки' elif scope == 'department': user_departments = user.departments.filter( employeedepartment__is_active=True ) queryset = queryset.filter(department__in=user_departments) page_title = 'Заявки отдела' elif scope == 'all' and user.is_staff: page_title = 'Все заявки' else: queryset = queryset.filter(requestor=user) page_title = 'Мои заявки' scope = 'mine' # Фильтры filters = {} if status := request.GET.get('status'): queryset = queryset.filter(status=status) filters['status'] = status if urgency := request.GET.get('urgency'): queryset = queryset.filter(urgency=urgency) filters['urgency'] = urgency # Сортировка queryset = queryset.order_by('-created_at') # Пагинация paginator = Paginator(queryset, 20) page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) context = { 'requests': page_obj, 'page_obj': page_obj, 'page_title': page_title, 'scope': scope, 'filters': filters, 'can_view_all': user.is_staff or user.headed_departments.exists(), } return render(request, 'procurement/request_list.html', context) @login_required def my_requests(request): """Мои заявки.""" return redirect('procurement:request_list', permanent=False) @login_required def pending_approvals(request): """Заявки на согласовании (для руководителей).""" user = request.user # Получаем отделы, которыми руководит пользователь headed_depts = user.headed_departments.all() if not headed_depts.exists() and not user.is_staff: return redirect('procurement:dashboard') queryset = ProcurementRequest.objects.filter( status=ProcurementStatus.PENDING ).select_related( 'department', 'requestor' ) # Для не-staff показываем только заявки своих отделов if not user.is_staff: queryset = queryset.filter(department__in=headed_depts) queryset = queryset.order_by('-created_at') paginator = Paginator(queryset, 20) page_obj = paginator.get_page(request.GET.get('page')) context = { 'requests': page_obj, 'page_obj': page_obj, 'page_title': 'На согласовании', 'scope': 'pending', 'can_view_all': user.is_staff, } return render(request, 'procurement/request_list.html', context) @login_required def request_detail(request, pk): """Детальная страница заявки.""" procurement_request = get_object_or_404( ProcurementRequest.objects.select_related( 'department', 'requestor' ).prefetch_related( 'items__supplier', 'approvals__approver' ), pk=pk ) context = { 'request_obj': procurement_request, 'can_edit': ( procurement_request.requestor == request.user and procurement_request.status == ProcurementStatus.DRAFT ), 'can_approve': ( request.user.is_staff or request.user.headed_departments.filter( pk=procurement_request.department_id ).exists() ), } return render(request, 'procurement/request_detail.html', context) @login_required def request_create(request): """Страница/обработка создания заявки.""" if request.method == 'POST': # Обработка формы - для простоты перенаправляем на API # В реальности можно обработать здесь или использовать Django Forms pass context = {} return render(request, 'procurement/request_form.html', context) @login_required def equipment_list(request): """Список оборудования.""" queryset = Equipment.objects.select_related( 'category', 'department', 'responsible_person' ) # Фильтры filters = {} if category := request.GET.get('category'): queryset = queryset.filter(category_id=category) filters['category'] = category if status := request.GET.get('status'): queryset = queryset.filter(status=status) filters['status'] = status if department := request.GET.get('department'): queryset = queryset.filter(department_id=department) filters['department'] = department # Поиск if search := request.GET.get('q'): queryset = queryset.filter( name__icontains=search ) | queryset.filter( inventory_number__icontains=search ) queryset = queryset.order_by('-purchase_date') # Пагинация paginator = Paginator(queryset, 24) page_obj = paginator.get_page(request.GET.get('page')) context = { 'equipment_list': page_obj, 'page_obj': page_obj, 'filters': filters, 'categories': EquipmentCategory.objects.all(), 'departments': Department.objects.all(), 'users': User.objects.filter( is_active=True ).order_by('last_name', 'first_name'), 'can_manage': request.user.is_staff, } return render(request, 'procurement/equipment_list.html', context) @login_required def equipment_detail(request, pk): """Детальная страница оборудования.""" equipment = get_object_or_404( Equipment.objects.select_related( 'category', 'department', 'responsible_person' ).prefetch_related( 'maintenance_records', 'transfer_logs' ), pk=pk ) context = { 'equipment': equipment, 'can_manage': ( request.user.is_staff or equipment.responsible_person == request.user ), } return render(request, 'procurement/equipment_detail.html', context)