Corp/backend/procurement/views_frontend.py
Игорь Надеин 070dbc267e style: unify table styles in equipment_detail
- Replaced Bootstrap table with proc-table-header/proc-request-item
- Now maintenance history and transfer logs match request items style
- Added responsive behavior with d-lg-none labels
- Better visual consistency across procurement module
2025-12-15 10:12:42 +03:00

285 lines
9.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
HTML Views для модуля закупок (Frontend).
Все данные загружаются через API на клиенте.
Views только рендерят layout и передают минимальный контекст.
"""
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
@login_required
def dashboard(request):
"""Главная страница модуля закупок.
Данные загружаются через API:
- /api/procurement/stats/overview/ — статистика
- /api/procurement/budgets/my-department/ — бюджет отдела
- /api/procurement/requests/?ordering=-created_at&page_size=5 — последние заявки
"""
return render(request, 'procurement/dashboard.html', {})
@login_required
def request_list(request):
"""Список заявок на закупку.
Данные загружаются через API:
- /api/procurement/requests/ — с фильтрами
- /api/v1/departments/ — для фильтра по отделам
"""
scope = request.GET.get('scope', 'mine')
user = request.user
# Читаем фильтры из GET параметров
filters = {
'status': request.GET.get('status', ''),
'urgency': request.GET.get('urgency', ''),
'period': request.GET.get('period', ''),
}
# Определяем доступные представления
can_view_department = user.departments.exists()
can_view_all = (
user.is_staff or user.is_superuser or
user.has_perm('procurement.view_procurementrequest') or
user.has_perm('procurement.change_procurementrequest')
)
return render(request, 'procurement/request_list.html', {
'scope': scope,
'show_tabs': True,
'can_view_department': can_view_department,
'can_view_all': can_view_all,
'filters': filters,
})
@login_required
def my_requests(request):
"""Мои заявки — редирект на request_list."""
from django.shortcuts import redirect
return redirect('procurement_frontend:request_list')
@login_required
def pending_approvals(request):
"""Заявки на согласовании.
Данные загружаются через API:
- /api/procurement/requests/pending_approvals/
"""
user = request.user
# Определяем доступные представления
can_view_department = user.departments.exists()
can_view_all = (
user.is_staff or user.is_superuser or
user.has_perm('procurement.view_procurementrequest') or
user.has_perm('procurement.change_procurementrequest')
)
return render(request, 'procurement/request_list.html', {
'scope': 'pending',
'page_title': 'На согласовании',
'show_tabs': True,
'can_view_department': can_view_department,
'can_view_all': can_view_all,
})
@login_required
@login_required
def request_detail(request, pk):
"""Детальная страница заявки.
Загружает данные из БД и передаёт в шаблон.
Права на редактирование (can_edit):
- Админы/Staff → любая заявка в DRAFT
- Модельные права (change_procurementrequest) → любая заявка в DRAFT
- Автор заявки → своя заявка в DRAFT
- Начальник отдела → заявки своего отдела в DRAFT
Права на согласование (can_approve):
- Пользователи с активным approval для этой заявки
"""
from django.shortcuts import get_object_or_404
from procurement.models import ProcurementRequest
request_obj = get_object_or_404(
ProcurementRequest.objects.select_related(
'department', 'requestor', 'executor'
).prefetch_related('items', 'approvals__approver'),
pk=pk
)
user = request.user
# Проверяем права на редактирование (синхронизировано с API)
can_edit = False
if request_obj.is_editable: # Только DRAFT
# Админы могут редактировать
if user.is_superuser or user.is_staff:
can_edit = True
# Модельные права
elif user.has_perm('procurement.change_procurementrequest'):
can_edit = True
# Автор заявки
elif request_obj.requestor == user:
can_edit = True
# Начальник отдела
elif request_obj.department.head == user:
can_edit = True
# Проверяем права на согласование
can_approve = (
request_obj.approvals.filter(
approver=user,
status='pending'
).exists()
)
return render(request, 'procurement/request_detail.html', {
'request_id': pk,
'request_obj': request_obj,
'can_edit': can_edit,
'can_approve': can_approve,
})
@login_required
def request_create(request):
"""Страница создания заявки.
Данные загружаются через API:
- /api/v1/departments/ — список отделов
Создание через:
- POST /api/procurement/requests/
"""
return render(request, 'procurement/request_form.html', {
'page_title': 'Новая заявка',
'request_id': None,
})
@login_required
def request_edit(request, pk):
"""Страница редактирования заявки.
Данные загружаются через API:
- /api/v1/procurement/requests/{pk}/ — данные заявки
- /api/v1/departments/ — список отделов
Обновление через:
- PATCH /api/v1/procurement/requests/{pk}/
"""
return render(request, 'procurement/request_form.html', {
'page_title': 'Редактирование заявки',
'request_id': pk,
})
@login_required
def equipment_list(request):
"""Список оборудования.
Данные загружаются через API:
- /api/procurement/equipment/ — список с фильтрами
- /api/procurement/equipment-categories/ — категории для фильтра
- /api/v1/departments/ — отделы для фильтра
- /api/procurement/equipment/create-options/ — при создании
"""
return render(request, 'procurement/equipment_list.html', {})
@login_required
def equipment_detail(request, pk):
"""Детальная страница оборудования.
Загружает данные из БД и передаёт в шаблон.
Права на управление (can_manage):
- Админы/Staff → любое оборудование
- Начальник отдела → оборудование своего отдела
- Ответственный за оборудование → своё оборудование
"""
from django.shortcuts import get_object_or_404
from procurement.models import Equipment
equipment = get_object_or_404(
Equipment.objects.select_related(
'department',
'department__head',
'category',
'responsible_person',
'procurement_item',
'procurement_item__request'
).prefetch_related(
'maintenance_history',
'transfer_logs__from_department',
'transfer_logs__to_department',
'transfer_logs__from_person',
'transfer_logs__to_person'
),
pk=pk
)
user = request.user
# Проверяем права на управление
can_manage = False
if user.is_superuser or user.is_staff:
can_manage = True
elif equipment.department and equipment.department.head == user:
can_manage = True
elif equipment.responsible_person == user:
can_manage = True
return render(request, 'procurement/equipment_detail.html', {
'equipment': equipment,
'can_manage': can_manage,
})
# =============================================================================
# БЮДЖЕТЫ
# =============================================================================
@login_required
def budget_list(request):
"""Список бюджетов.
Данные загружаются через API:
- /api/procurement/budgets/ — список с фильтрами
- /api/v1/departments/ — отделы для фильтра
"""
return render(request, 'procurement/budget_list.html', {})
@login_required
def budget_create(request):
"""Создание бюджета.
Данные загружаются через API:
- /api/v1/departments/ — список отделов
Создание через:
- POST /api/procurement/budgets/
"""
return render(request, 'procurement/budget_form.html', {
'budget_id': None,
})
@login_required
def budget_edit(request, pk):
"""Редактирование бюджета.
Данные загружаются через API:
- /api/procurement/budgets/{pk}/ — текущие данные
- /api/v1/departments/ — список отделов
Обновление через:
- PATCH /api/procurement/budgets/{pk}/
"""
return render(request, 'procurement/budget_form.html', {
'budget_id': pk,
})