733 lines
26 KiB
Python
733 lines
26 KiB
Python
"""
|
|
QI Projects Console UI views
|
|
|
|
Provides full CRUD functionality for Quality Improvement projects,
|
|
task management, and template handling.
|
|
"""
|
|
from django.contrib import messages
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.core.paginator import Paginator
|
|
from django.db.models import Q
|
|
from django.shortcuts import get_object_or_404, redirect, render
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from apps.core.decorators import block_source_user
|
|
from apps.organizations.models import Hospital
|
|
from apps.px_action_center.models import PXAction
|
|
|
|
from .forms import ConvertToProjectForm, QIProjectForm, QIProjectTaskForm, QIProjectTemplateForm
|
|
from .models import QIProject, QIProjectTask
|
|
|
|
|
|
@block_source_user
|
|
@login_required
|
|
def project_list(request):
|
|
"""QI Projects list view with filtering and pagination"""
|
|
# Exclude templates from the list
|
|
queryset = QIProject.objects.filter(is_template=False).select_related(
|
|
'hospital', 'department', 'project_lead'
|
|
).prefetch_related('team_members', 'related_actions')
|
|
|
|
# Apply RBAC filters
|
|
user = request.user
|
|
# Get selected hospital for PX Admins (from middleware)
|
|
selected_hospital = getattr(request, 'tenant_hospital', None)
|
|
|
|
if user.is_px_admin():
|
|
# PX Admins see all, but filter by selected hospital if set
|
|
if selected_hospital:
|
|
queryset = queryset.filter(hospital=selected_hospital)
|
|
elif user.hospital:
|
|
queryset = queryset.filter(hospital=user.hospital)
|
|
|
|
# Apply filters
|
|
status_filter = request.GET.get('status')
|
|
if status_filter:
|
|
queryset = queryset.filter(status=status_filter)
|
|
|
|
hospital_filter = request.GET.get('hospital')
|
|
if hospital_filter:
|
|
queryset = queryset.filter(hospital_id=hospital_filter)
|
|
|
|
# Search
|
|
search_query = request.GET.get('search')
|
|
if search_query:
|
|
queryset = queryset.filter(
|
|
Q(name__icontains=search_query) |
|
|
Q(description__icontains=search_query) |
|
|
Q(name_ar__icontains=search_query)
|
|
)
|
|
|
|
# Ordering
|
|
queryset = queryset.order_by('-created_at')
|
|
|
|
# Pagination
|
|
page_size = int(request.GET.get('page_size', 25))
|
|
paginator = Paginator(queryset, page_size)
|
|
page_number = request.GET.get('page', 1)
|
|
page_obj = paginator.get_page(page_number)
|
|
|
|
# Get hospitals for filter
|
|
hospitals = Hospital.objects.filter(status='active')
|
|
if not user.is_px_admin() and user.hospital:
|
|
hospitals = hospitals.filter(id=user.hospital.id)
|
|
|
|
# Statistics
|
|
stats = {
|
|
'total': queryset.count(),
|
|
'active': queryset.filter(status='active').count(),
|
|
'completed': queryset.filter(status='completed').count(),
|
|
'pending': queryset.filter(status='pending').count(),
|
|
}
|
|
|
|
context = {
|
|
'page_obj': page_obj,
|
|
'projects': page_obj.object_list,
|
|
'hospitals': hospitals,
|
|
'stats': stats,
|
|
'filters': request.GET,
|
|
}
|
|
|
|
return render(request, 'projects/project_list.html', context)
|
|
|
|
|
|
@block_source_user
|
|
@login_required
|
|
def project_detail(request, pk):
|
|
"""QI Project detail view with task management"""
|
|
project = get_object_or_404(
|
|
QIProject.objects.filter(is_template=False).select_related(
|
|
'hospital', 'department', 'project_lead'
|
|
).prefetch_related(
|
|
'team_members', 'related_actions', 'tasks'
|
|
),
|
|
pk=pk
|
|
)
|
|
|
|
# Check permission
|
|
user = request.user
|
|
if not user.is_px_admin() and user.hospital and project.hospital != user.hospital:
|
|
messages.error(request, _("You don't have permission to view this project."))
|
|
return redirect('projects:project_list')
|
|
|
|
# Get tasks
|
|
tasks = project.tasks.all().order_by('order', 'created_at')
|
|
|
|
# Get related actions
|
|
related_actions = project.related_actions.all()
|
|
|
|
context = {
|
|
'project': project,
|
|
'tasks': tasks,
|
|
'related_actions': related_actions,
|
|
'can_edit': user.is_px_admin() or user.is_hospital_admin or user.is_department_manager,
|
|
}
|
|
|
|
return render(request, 'projects/project_detail.html', context)
|
|
|
|
|
|
@block_source_user
|
|
@login_required
|
|
def project_create(request, template_pk=None):
|
|
"""Create a new QI Project"""
|
|
user = request.user
|
|
|
|
# Check permission (PX Admin, Hospital Admin, or Department Manager)
|
|
if not (user.is_px_admin() or user.is_hospital_admin or user.is_department_manager):
|
|
messages.error(request, _("You don't have permission to create projects."))
|
|
return redirect('projects:project_list')
|
|
|
|
# Check for template parameter (from URL or GET)
|
|
template_id = template_pk or request.GET.get('template')
|
|
initial_data = {}
|
|
template = None
|
|
|
|
if template_id:
|
|
try:
|
|
template = QIProject.objects.get(pk=template_id, is_template=True)
|
|
initial_data = {
|
|
'name': template.name,
|
|
'name_ar': template.name_ar,
|
|
'description': template.description,
|
|
'department': template.department,
|
|
'target_completion_date': template.target_completion_date,
|
|
}
|
|
if not user.is_px_admin() and user.hospital:
|
|
initial_data['hospital'] = user.hospital
|
|
except QIProject.DoesNotExist:
|
|
pass
|
|
|
|
# Check for PX Action parameter (convert action to project)
|
|
action_id = request.GET.get('action')
|
|
if action_id:
|
|
try:
|
|
action = PXAction.objects.get(pk=action_id)
|
|
initial_data['name'] = f"QI Project: {action.title}"
|
|
initial_data['description'] = action.description
|
|
if not user.is_px_admin() and user.hospital:
|
|
initial_data['hospital'] = user.hospital
|
|
else:
|
|
initial_data['hospital'] = action.hospital
|
|
except PXAction.DoesNotExist:
|
|
pass
|
|
|
|
if request.method == 'POST':
|
|
form = QIProjectForm(request.POST, user=user)
|
|
|
|
# Check for template in POST data (hidden field)
|
|
template_id_post = request.POST.get('template_id')
|
|
if template_id_post:
|
|
try:
|
|
template = QIProject.objects.get(pk=template_id_post, is_template=True)
|
|
except QIProject.DoesNotExist:
|
|
template = None
|
|
|
|
if form.is_valid():
|
|
project = form.save(commit=False)
|
|
project.created_by = user
|
|
project.save()
|
|
form.save_m2m() # Save many-to-many relationships
|
|
|
|
# If created from template, copy tasks
|
|
task_count = 0
|
|
if template:
|
|
for template_task in template.tasks.all():
|
|
QIProjectTask.objects.create(
|
|
project=project,
|
|
title=template_task.title,
|
|
description=template_task.description,
|
|
order=template_task.order,
|
|
status='pending'
|
|
)
|
|
task_count += 1
|
|
|
|
# If created from action, link it
|
|
if action_id:
|
|
try:
|
|
action = PXAction.objects.get(pk=action_id)
|
|
project.related_actions.add(action)
|
|
except PXAction.DoesNotExist:
|
|
pass
|
|
|
|
if template and task_count > 0:
|
|
messages.success(
|
|
request,
|
|
_('QI Project created successfully with %(count)d task(s) from template.') % {'count': task_count}
|
|
)
|
|
else:
|
|
messages.success(request, _("QI Project created successfully."))
|
|
return redirect('projects:project_detail', pk=project.pk)
|
|
else:
|
|
form = QIProjectForm(user=user, initial=initial_data)
|
|
|
|
context = {
|
|
'form': form,
|
|
'is_create': True,
|
|
'template': template,
|
|
}
|
|
|
|
return render(request, 'projects/project_form.html', context)
|
|
|
|
|
|
@block_source_user
|
|
@login_required
|
|
def project_edit(request, pk):
|
|
"""Edit an existing QI Project"""
|
|
user = request.user
|
|
project = get_object_or_404(QIProject, pk=pk, is_template=False)
|
|
|
|
# Check permission
|
|
if not user.is_px_admin() and user.hospital and project.hospital != user.hospital:
|
|
messages.error(request, _("You don't have permission to edit this project."))
|
|
return redirect('projects:project_list')
|
|
|
|
# Check edit permission (PX Admin, Hospital Admin, or Department Manager)
|
|
if not (user.is_px_admin() or user.is_hospital_admin or user.is_department_manager):
|
|
messages.error(request, _("You don't have permission to edit projects."))
|
|
return redirect('projects:project_detail', pk=project.pk)
|
|
|
|
if request.method == 'POST':
|
|
form = QIProjectForm(request.POST, instance=project, user=user)
|
|
if form.is_valid():
|
|
form.save()
|
|
messages.success(request, _("QI Project updated successfully."))
|
|
return redirect('projects:project_detail', pk=project.pk)
|
|
else:
|
|
form = QIProjectForm(instance=project, user=user)
|
|
|
|
context = {
|
|
'form': form,
|
|
'project': project,
|
|
'is_create': False,
|
|
}
|
|
|
|
return render(request, 'projects/project_form.html', context)
|
|
|
|
|
|
@block_source_user
|
|
@login_required
|
|
def project_delete(request, pk):
|
|
"""Delete a QI Project"""
|
|
user = request.user
|
|
project = get_object_or_404(QIProject, pk=pk, is_template=False)
|
|
|
|
# Check permission (only PX Admin or Hospital Admin can delete)
|
|
if not (user.is_px_admin() or user.is_hospital_admin):
|
|
messages.error(request, _("You don't have permission to delete projects."))
|
|
return redirect('projects:project_detail', pk=project.pk)
|
|
|
|
if not user.is_px_admin() and user.hospital and project.hospital != user.hospital:
|
|
messages.error(request, _("You don't have permission to delete this project."))
|
|
return redirect('projects:project_list')
|
|
|
|
if request.method == 'POST':
|
|
project_name = project.name
|
|
project.delete()
|
|
messages.success(request, _('Project "%(name)s" deleted successfully.') % {'name': project_name})
|
|
return redirect('projects:project_list')
|
|
|
|
context = {
|
|
'project': project,
|
|
}
|
|
|
|
return render(request, 'projects/project_delete_confirm.html', context)
|
|
|
|
|
|
@block_source_user
|
|
@login_required
|
|
def project_save_as_template(request, pk):
|
|
"""Save an existing project and its tasks as a template"""
|
|
user = request.user
|
|
project = get_object_or_404(QIProject, pk=pk, is_template=False)
|
|
|
|
# Check permission (only PX Admin or Hospital Admin can create templates)
|
|
if not (user.is_px_admin() or user.is_hospital_admin):
|
|
messages.error(request, _("You don't have permission to create templates."))
|
|
return redirect('projects:project_detail', pk=project.pk)
|
|
|
|
# Check hospital access
|
|
if not user.is_px_admin() and user.hospital and project.hospital != user.hospital:
|
|
messages.error(request, _("You don't have permission to create templates from this project."))
|
|
return redirect('projects:project_list')
|
|
|
|
if request.method == 'POST':
|
|
template_name = request.POST.get('template_name', '').strip()
|
|
template_description = request.POST.get('template_description', '').strip()
|
|
make_global = request.POST.get('make_global') == 'on'
|
|
|
|
if not template_name:
|
|
messages.error(request, _('Please provide a template name.'))
|
|
return redirect('projects:project_save_as_template', pk=project.pk)
|
|
|
|
# Create template from project
|
|
template = QIProject.objects.create(
|
|
name=template_name,
|
|
name_ar=template_name, # Can be edited later
|
|
description=template_description or project.description,
|
|
is_template=True,
|
|
# If global, hospital is None; otherwise use project's hospital
|
|
hospital=None if make_global else project.hospital,
|
|
department=project.department,
|
|
status='pending', # Default status for templates
|
|
created_by=user
|
|
)
|
|
|
|
# Copy tasks from project to template
|
|
for task in project.tasks.all():
|
|
QIProjectTask.objects.create(
|
|
project=template,
|
|
title=task.title,
|
|
description=task.description,
|
|
order=task.order,
|
|
status='pending' # Reset status for template
|
|
)
|
|
|
|
messages.success(
|
|
request,
|
|
_('Template "%(name)s" created successfully with %(count)d task(s).') % {
|
|
'name': template_name,
|
|
'count': project.tasks.count()
|
|
}
|
|
)
|
|
return redirect('projects:template_list')
|
|
|
|
context = {
|
|
'project': project,
|
|
'suggested_name': f"Template: {project.name}",
|
|
}
|
|
|
|
return render(request, 'projects/project_save_as_template.html', context)
|
|
|
|
|
|
# =============================================================================
|
|
# Task Management Views
|
|
# =============================================================================
|
|
|
|
@block_source_user
|
|
@login_required
|
|
def task_create(request, project_pk):
|
|
"""Add a new task to a project"""
|
|
user = request.user
|
|
project = get_object_or_404(QIProject, pk=project_pk, is_template=False)
|
|
|
|
# Check permission
|
|
if not user.is_px_admin() and user.hospital and project.hospital != user.hospital:
|
|
messages.error(request, _("You don't have permission to add tasks to this project."))
|
|
return redirect('projects:project_detail', pk=project.pk)
|
|
|
|
if request.method == 'POST':
|
|
form = QIProjectTaskForm(request.POST, project=project)
|
|
if form.is_valid():
|
|
task = form.save(commit=False)
|
|
task.project = project
|
|
task.save()
|
|
messages.success(request, _("Task added successfully."))
|
|
return redirect('projects:project_detail', pk=project.pk)
|
|
else:
|
|
form = QIProjectTaskForm(project=project)
|
|
|
|
context = {
|
|
'form': form,
|
|
'project': project,
|
|
'is_create': True,
|
|
}
|
|
|
|
return render(request, 'projects/task_form.html', context)
|
|
|
|
|
|
@block_source_user
|
|
@login_required
|
|
def task_edit(request, project_pk, task_pk):
|
|
"""Edit an existing task"""
|
|
user = request.user
|
|
project = get_object_or_404(QIProject, pk=project_pk, is_template=False)
|
|
task = get_object_or_404(QIProjectTask, pk=task_pk, project=project)
|
|
|
|
# Check permission
|
|
if not user.is_px_admin() and user.hospital and project.hospital != user.hospital:
|
|
messages.error(request, _("You don't have permission to edit tasks in this project."))
|
|
return redirect('projects:project_detail', pk=project.pk)
|
|
|
|
if request.method == 'POST':
|
|
form = QIProjectTaskForm(request.POST, instance=task, project=project)
|
|
if form.is_valid():
|
|
task = form.save()
|
|
# If status changed to completed, set completed_date
|
|
if task.status == 'completed' and not task.completed_date:
|
|
from django.utils import timezone
|
|
task.completed_date = timezone.now().date()
|
|
task.save()
|
|
messages.success(request, _("Task updated successfully."))
|
|
return redirect('projects:project_detail', pk=project.pk)
|
|
else:
|
|
form = QIProjectTaskForm(instance=task, project=project)
|
|
|
|
context = {
|
|
'form': form,
|
|
'project': project,
|
|
'task': task,
|
|
'is_create': False,
|
|
}
|
|
|
|
return render(request, 'projects/task_form.html', context)
|
|
|
|
|
|
@block_source_user
|
|
@login_required
|
|
def task_delete(request, project_pk, task_pk):
|
|
"""Delete a task"""
|
|
user = request.user
|
|
project = get_object_or_404(QIProject, pk=project_pk, is_template=False)
|
|
task = get_object_or_404(QIProjectTask, pk=task_pk, project=project)
|
|
|
|
# Check permission
|
|
if not user.is_px_admin() and user.hospital and project.hospital != user.hospital:
|
|
messages.error(request, _("You don't have permission to delete tasks in this project."))
|
|
return redirect('projects:project_detail', pk=project.pk)
|
|
|
|
if request.method == 'POST':
|
|
task.delete()
|
|
messages.success(request, _("Task deleted successfully."))
|
|
return redirect('projects:project_detail', pk=project.pk)
|
|
|
|
context = {
|
|
'project': project,
|
|
'task': task,
|
|
}
|
|
|
|
return render(request, 'projects/task_delete_confirm.html', context)
|
|
|
|
|
|
@block_source_user
|
|
@login_required
|
|
def task_toggle_status(request, project_pk, task_pk):
|
|
"""Quick toggle task status between pending and completed"""
|
|
user = request.user
|
|
project = get_object_or_404(QIProject, pk=project_pk, is_template=False)
|
|
task = get_object_or_404(QIProjectTask, pk=task_pk, project=project)
|
|
|
|
# Check permission
|
|
if not user.is_px_admin() and user.hospital and project.hospital != user.hospital:
|
|
messages.error(request, _("You don't have permission to update tasks in this project."))
|
|
return redirect('projects:project_detail', pk=project.pk)
|
|
|
|
from django.utils import timezone
|
|
|
|
if task.status == 'completed':
|
|
task.status = 'pending'
|
|
task.completed_date = None
|
|
else:
|
|
task.status = 'completed'
|
|
task.completed_date = timezone.now().date()
|
|
|
|
task.save()
|
|
messages.success(request, _("Task status updated."))
|
|
return redirect('projects:project_detail', pk=project.pk)
|
|
|
|
|
|
# =============================================================================
|
|
# Template Management Views
|
|
# =============================================================================
|
|
|
|
@block_source_user
|
|
@login_required
|
|
def template_list(request):
|
|
"""List QI Project templates"""
|
|
user = request.user
|
|
|
|
# Only admins can manage templates
|
|
if not (user.is_px_admin() or user.is_hospital_admin):
|
|
messages.error(request, _("You don't have permission to view templates."))
|
|
return redirect('projects:project_list')
|
|
|
|
queryset = QIProject.objects.filter(is_template=True).select_related('hospital', 'department')
|
|
|
|
# Apply RBAC filters
|
|
if not user.is_px_admin():
|
|
from django.db.models import Q
|
|
queryset = queryset.filter(
|
|
Q(hospital=user.hospital) | Q(hospital__isnull=True)
|
|
)
|
|
|
|
# Search
|
|
search_query = request.GET.get('search')
|
|
if search_query:
|
|
queryset = queryset.filter(
|
|
Q(name__icontains=search_query) |
|
|
Q(description__icontains=search_query) |
|
|
Q(name_ar__icontains=search_query)
|
|
)
|
|
|
|
queryset = queryset.order_by('name')
|
|
|
|
context = {
|
|
'templates': queryset,
|
|
'can_create': user.is_px_admin() or user.is_hospital_admin,
|
|
'can_edit': user.is_px_admin() or user.is_hospital_admin,
|
|
}
|
|
|
|
return render(request, 'projects/template_list.html', context)
|
|
|
|
|
|
@block_source_user
|
|
@login_required
|
|
def template_detail(request, pk):
|
|
"""View template details with tasks"""
|
|
user = request.user
|
|
|
|
# Only admins can view templates
|
|
if not (user.is_px_admin() or user.is_hospital_admin):
|
|
messages.error(request, _("You don't have permission to view templates."))
|
|
return redirect('projects:project_list')
|
|
|
|
template = get_object_or_404(
|
|
QIProject.objects.filter(is_template=True).select_related('hospital', 'department'),
|
|
pk=pk
|
|
)
|
|
|
|
# Check permission for hospital-specific templates
|
|
if not user.is_px_admin():
|
|
from django.db.models import Q
|
|
if template.hospital and template.hospital != user.hospital:
|
|
messages.error(request, _("You don't have permission to view this template."))
|
|
return redirect('projects:template_list')
|
|
|
|
# Get tasks
|
|
tasks = template.tasks.all().order_by('order', 'created_at')
|
|
|
|
context = {
|
|
'template': template,
|
|
'tasks': tasks,
|
|
}
|
|
|
|
return render(request, 'projects/template_detail.html', context)
|
|
|
|
|
|
@block_source_user
|
|
@login_required
|
|
def template_create(request):
|
|
"""Create a new project template"""
|
|
user = request.user
|
|
|
|
# Only admins can create templates
|
|
if not (user.is_px_admin() or user.is_hospital_admin):
|
|
messages.error(request, _("You don't have permission to create templates."))
|
|
return redirect('projects:project_list')
|
|
|
|
if request.method == 'POST':
|
|
form = QIProjectTemplateForm(request.POST, user=user)
|
|
if form.is_valid():
|
|
template = form.save(commit=False)
|
|
template.is_template = True
|
|
template.created_by = user
|
|
template.save()
|
|
messages.success(request, _("Project template created successfully."))
|
|
return redirect('projects:template_list')
|
|
else:
|
|
form = QIProjectTemplateForm(user=user)
|
|
|
|
context = {
|
|
'form': form,
|
|
'is_create': True,
|
|
}
|
|
|
|
return render(request, 'projects/template_form.html', context)
|
|
|
|
|
|
@block_source_user
|
|
@login_required
|
|
def template_edit(request, pk):
|
|
"""Edit an existing project template"""
|
|
user = request.user
|
|
template = get_object_or_404(QIProject, pk=pk, is_template=True)
|
|
|
|
# Check permission
|
|
if not user.is_px_admin():
|
|
if template.hospital and template.hospital != user.hospital:
|
|
messages.error(request, _("You don't have permission to edit this template."))
|
|
return redirect('projects:template_list')
|
|
|
|
if request.method == 'POST':
|
|
form = QIProjectTemplateForm(request.POST, instance=template, user=user)
|
|
if form.is_valid():
|
|
form.save()
|
|
messages.success(request, _("Project template updated successfully."))
|
|
return redirect('projects:template_list')
|
|
else:
|
|
form = QIProjectTemplateForm(instance=template, user=user)
|
|
|
|
context = {
|
|
'form': form,
|
|
'template': template,
|
|
'is_create': False,
|
|
}
|
|
|
|
return render(request, 'projects/template_form.html', context)
|
|
|
|
|
|
@block_source_user
|
|
@login_required
|
|
def template_delete(request, pk):
|
|
"""Delete a project template"""
|
|
user = request.user
|
|
template = get_object_or_404(QIProject, pk=pk, is_template=True)
|
|
|
|
# Check permission
|
|
if not user.is_px_admin():
|
|
if template.hospital and template.hospital != user.hospital:
|
|
messages.error(request, _("You don't have permission to delete this template."))
|
|
return redirect('projects:template_list')
|
|
|
|
if request.method == 'POST':
|
|
template_name = template.name
|
|
template.delete()
|
|
messages.success(request, _('Template "%(name)s" deleted successfully.') % {'name': template_name})
|
|
return redirect('projects:template_list')
|
|
|
|
context = {
|
|
'template': template,
|
|
}
|
|
|
|
return render(request, 'projects/template_delete_confirm.html', context)
|
|
|
|
|
|
# =============================================================================
|
|
# PX Action Conversion View
|
|
# =============================================================================
|
|
|
|
@block_source_user
|
|
@login_required
|
|
def convert_action_to_project(request, action_pk):
|
|
"""Convert a PX Action to a QI Project"""
|
|
user = request.user
|
|
|
|
# Check permission
|
|
if not (user.is_px_admin() or user.is_hospital_admin or user.is_department_manager):
|
|
messages.error(request, _("You don't have permission to create projects."))
|
|
return redirect('px_action_center:action_detail', pk=action_pk)
|
|
|
|
action = get_object_or_404(PXAction, pk=action_pk)
|
|
|
|
# Check hospital access
|
|
if not user.is_px_admin() and user.hospital and action.hospital != user.hospital:
|
|
messages.error(request, _("You don't have permission to convert this action."))
|
|
return redirect('px_action_center:action_detail', pk=action_pk)
|
|
|
|
if request.method == 'POST':
|
|
form = ConvertToProjectForm(request.POST, user=user, action=action)
|
|
if form.is_valid():
|
|
# Create project from template or blank
|
|
template = form.cleaned_data.get('template')
|
|
|
|
if template:
|
|
# Copy from template
|
|
project = QIProject.objects.create(
|
|
name=form.cleaned_data['project_name'],
|
|
name_ar=template.name_ar,
|
|
description=template.description,
|
|
hospital=action.hospital,
|
|
department=template.department,
|
|
project_lead=form.cleaned_data['project_lead'],
|
|
target_completion_date=form.cleaned_data['target_completion_date'],
|
|
status='pending',
|
|
created_by=user
|
|
)
|
|
# Copy tasks from template
|
|
for template_task in template.tasks.all():
|
|
QIProjectTask.objects.create(
|
|
project=project,
|
|
title=template_task.title,
|
|
description=template_task.description,
|
|
order=template_task.order,
|
|
status='pending'
|
|
)
|
|
else:
|
|
# Create blank project
|
|
project = QIProject.objects.create(
|
|
name=form.cleaned_data['project_name'],
|
|
description=action.description,
|
|
hospital=action.hospital,
|
|
project_lead=form.cleaned_data['project_lead'],
|
|
target_completion_date=form.cleaned_data['target_completion_date'],
|
|
status='pending',
|
|
created_by=user
|
|
)
|
|
|
|
# Link to the action
|
|
project.related_actions.add(action)
|
|
|
|
messages.success(request, _("PX Action converted to QI Project successfully."))
|
|
return redirect('projects:project_detail', pk=project.pk)
|
|
else:
|
|
initial_data = {
|
|
'project_name': f"QI Project: {action.title}",
|
|
}
|
|
form = ConvertToProjectForm(user=user, action=action, initial=initial_data)
|
|
|
|
context = {
|
|
'form': form,
|
|
'action': action,
|
|
}
|
|
|
|
return render(request, 'projects/convert_action.html', context)
|