638 lines
24 KiB
Python
638 lines
24 KiB
Python
"""
|
|
Referrals views for the Tenhal Multidisciplinary Healthcare Platform.
|
|
|
|
This module contains views for referral management including:
|
|
- Inter-discipline referrals
|
|
- External provider referrals
|
|
- Referral tracking and status
|
|
- Auto-referral rules (e.g., ASD→Pediatrician)
|
|
"""
|
|
|
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
|
from django.db.models import Q
|
|
from django.shortcuts import get_object_or_404, redirect
|
|
from django.utils import timezone
|
|
from django.views.generic import ListView, DetailView, CreateView, UpdateView, TemplateView, FormView
|
|
from django.urls import reverse_lazy
|
|
from django.contrib import messages
|
|
from django.http import JsonResponse
|
|
from django.views import View
|
|
|
|
from core.mixins import (
|
|
TenantFilterMixin,
|
|
RolePermissionMixin,
|
|
AuditLogMixin,
|
|
HTMXResponseMixin,
|
|
SuccessMessageMixin,
|
|
PaginationMixin,
|
|
)
|
|
from core.models import User, Patient, Tenant
|
|
from .models import Referral
|
|
from .forms import ReferralForm, ExternalReferralForm
|
|
|
|
|
|
class ReferralListView(LoginRequiredMixin, TenantFilterMixin, PaginationMixin,
|
|
HTMXResponseMixin, ListView):
|
|
"""
|
|
Referral list view.
|
|
|
|
Features:
|
|
- Filter by patient, from/to discipline, status, urgency
|
|
- Search by patient name/MRN
|
|
- Role-based filtering (providers see their referrals)
|
|
"""
|
|
model = Referral
|
|
template_name = 'referrals/referral_list.html'
|
|
htmx_template_name = 'referrals/partials/referral_list_partial.html'
|
|
context_object_name = 'referrals'
|
|
paginate_by = 25
|
|
|
|
def get_queryset(self):
|
|
"""Get filtered queryset."""
|
|
queryset = super().get_queryset()
|
|
user = self.request.user
|
|
|
|
# Role-based filtering
|
|
if user.role in [User.Role.DOCTOR, User.Role.NURSE, User.Role.OT,
|
|
User.Role.SLP, User.Role.ABA]:
|
|
# Clinical staff see referrals from or to them, plus external referrals to their clinic
|
|
queryset = queryset.filter(
|
|
Q(referred_by=user) |
|
|
Q(referred_to=user) |
|
|
Q(from_discipline=Referral.Discipline.EXTERNAL, to_clinic__isnull=False)
|
|
)
|
|
# Admins and other roles see all referrals (no additional filtering needed)
|
|
|
|
# Apply search
|
|
search_query = self.request.GET.get('search', '').strip()
|
|
if search_query:
|
|
queryset = queryset.filter(
|
|
Q(patient__first_name_en__icontains=search_query) |
|
|
Q(patient__last_name_en__icontains=search_query) |
|
|
Q(patient__mrn__icontains=search_query)
|
|
)
|
|
|
|
# Apply filters
|
|
patient_id = self.request.GET.get('patient')
|
|
if patient_id:
|
|
queryset = queryset.filter(patient_id=patient_id)
|
|
|
|
from_discipline = self.request.GET.get('from_discipline')
|
|
if from_discipline:
|
|
queryset = queryset.filter(from_discipline=from_discipline)
|
|
|
|
to_discipline = self.request.GET.get('to_discipline')
|
|
if to_discipline:
|
|
queryset = queryset.filter(to_discipline=to_discipline)
|
|
|
|
status = self.request.GET.get('status')
|
|
if status:
|
|
queryset = queryset.filter(status=status)
|
|
|
|
urgency = self.request.GET.get('urgency')
|
|
if urgency:
|
|
queryset = queryset.filter(urgency=urgency)
|
|
|
|
date_from = self.request.GET.get('date_from')
|
|
if date_from:
|
|
queryset = queryset.filter(created_at__gte=date_from)
|
|
|
|
date_to = self.request.GET.get('date_to')
|
|
if date_to:
|
|
queryset = queryset.filter(created_at__lte=date_to)
|
|
|
|
return queryset.select_related(
|
|
'patient', 'referred_by', 'referred_to'
|
|
).order_by('-created_at')
|
|
|
|
def get_context_data(self, **kwargs):
|
|
"""Add filter options."""
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
# Add filter options
|
|
context['status_choices'] = Referral.Status.choices
|
|
context['priority_choices'] = Referral.Priority.choices
|
|
context['referral_type_choices'] = Referral.ReferralType.choices
|
|
|
|
# Add current filters
|
|
context['current_filters'] = {
|
|
'search': self.request.GET.get('search', ''),
|
|
'patient': self.request.GET.get('patient', ''),
|
|
'from_discipline': self.request.GET.get('from_discipline', ''),
|
|
'to_discipline': self.request.GET.get('to_discipline', ''),
|
|
'status': self.request.GET.get('status', ''),
|
|
'urgency': self.request.GET.get('urgency', ''),
|
|
'date_from': self.request.GET.get('date_from', ''),
|
|
'date_to': self.request.GET.get('date_to', ''),
|
|
}
|
|
|
|
# Get all referrals
|
|
queryset = self.get_queryset()
|
|
|
|
# Split into sent and received
|
|
user = self.request.user
|
|
if user.role == User.Role.ADMIN:
|
|
# Admins see all referrals in both tabs
|
|
context['sent_referrals'] = queryset.filter(referred_by__isnull=False)
|
|
context['received_referrals'] = queryset
|
|
else:
|
|
# Clinical staff see their sent and received referrals
|
|
context['sent_referrals'] = queryset.filter(referred_by=user)
|
|
context['received_referrals'] = queryset.filter(
|
|
Q(referred_to=user) |
|
|
Q(from_discipline=Referral.Discipline.EXTERNAL, to_clinic__isnull=False)
|
|
)
|
|
|
|
# Add statistics
|
|
context['stats'] = {
|
|
'total_referrals': queryset.count(),
|
|
'pending': queryset.filter(status=Referral.Status.PENDING).count(),
|
|
'accepted': queryset.filter(status=Referral.Status.ACKNOWLEDGED).count(),
|
|
'completed': queryset.filter(status=Referral.Status.COMPLETED).count(),
|
|
'urgent': queryset.filter(priority=Referral.Priority.URGENT).count(),
|
|
}
|
|
|
|
return context
|
|
|
|
|
|
class ReferralDetailView(LoginRequiredMixin, TenantFilterMixin, DetailView):
|
|
"""
|
|
Referral detail view.
|
|
|
|
Features:
|
|
- Full referral details
|
|
- From/to discipline and provider
|
|
- Reason, urgency, status
|
|
- Response and notes
|
|
- Status history
|
|
"""
|
|
model = Referral
|
|
template_name = 'referrals/referral_detail.html'
|
|
context_object_name = 'referral'
|
|
|
|
def get_context_data(self, **kwargs):
|
|
"""Add status history and available actions."""
|
|
context = super().get_context_data(**kwargs)
|
|
referral = self.object
|
|
|
|
# Get status history if available
|
|
if hasattr(referral, 'history'):
|
|
context['status_history'] = referral.history.all()[:10]
|
|
|
|
# Check if user can accept/reject
|
|
user = self.request.user
|
|
context['can_respond'] = (
|
|
referral.status == Referral.Status.PENDING and
|
|
(user == referral.referred_to or user.role == User.Role.ADMIN)
|
|
)
|
|
|
|
# Check if user can cancel
|
|
context['can_cancel'] = (
|
|
referral.status in [Referral.Status.PENDING, Referral.Status.ACKNOWLEDGED] and
|
|
(user == referral.referred_by or user.role == User.Role.ADMIN)
|
|
)
|
|
|
|
return context
|
|
|
|
|
|
class ReferralCreateView(LoginRequiredMixin, RolePermissionMixin, AuditLogMixin,
|
|
SuccessMessageMixin, CreateView):
|
|
"""
|
|
Referral creation view.
|
|
|
|
Features:
|
|
- Create inter-discipline or external referral
|
|
- From/to discipline
|
|
- Reason, urgency
|
|
- Auto-referral rules (e.g., ASD→Pediatrician)
|
|
"""
|
|
model = Referral
|
|
form_class = ReferralForm
|
|
template_name = 'referrals/referral_form.html'
|
|
success_message = "Referral created successfully!"
|
|
allowed_roles = [User.Role.ADMIN, User.Role.DOCTOR, User.Role.NURSE,
|
|
User.Role.OT, User.Role.SLP, User.Role.ABA]
|
|
|
|
def get_success_url(self):
|
|
"""Redirect to referral detail."""
|
|
return reverse_lazy('referrals:referral_detail', kwargs={'pk': self.object.pk})
|
|
|
|
def form_valid(self, form):
|
|
"""Set tenant and referred_by."""
|
|
# Set tenant
|
|
form.instance.tenant = self.request.user.tenant
|
|
|
|
# Set referred_by
|
|
form.instance.referred_by = self.request.user
|
|
|
|
# Set from_discipline based on user role
|
|
form.instance.from_discipline = self._get_discipline_from_role(self.request.user.role)
|
|
|
|
# Set referral date if not provided
|
|
if not form.instance.referral_date:
|
|
form.instance.referral_date = timezone.now().date()
|
|
|
|
# Set initial status
|
|
form.instance.status = Referral.Status.PENDING
|
|
|
|
# Save referral
|
|
response = super().form_valid(form)
|
|
|
|
# Send notification to recipient (TODO)
|
|
self._send_referral_notification()
|
|
|
|
return response
|
|
|
|
def _get_discipline_from_role(self, role):
|
|
"""Map user role to discipline."""
|
|
role_to_discipline = {
|
|
User.Role.DOCTOR: Referral.Discipline.MEDICAL,
|
|
User.Role.NURSE: Referral.Discipline.NURSING,
|
|
User.Role.OT: Referral.Discipline.OT,
|
|
User.Role.SLP: Referral.Discipline.SLP,
|
|
User.Role.ABA: Referral.Discipline.ABA,
|
|
}
|
|
return role_to_discipline.get(role, Referral.Discipline.MEDICAL)
|
|
|
|
def _send_referral_notification(self):
|
|
"""Send notification to recipient."""
|
|
# TODO: Implement notification
|
|
pass
|
|
|
|
def get_initial(self):
|
|
"""Set initial form values."""
|
|
initial = super().get_initial()
|
|
|
|
# Pre-populate patient if provided in URL
|
|
patient_id = self.request.GET.get('patient')
|
|
if patient_id:
|
|
try:
|
|
patient = Patient.objects.get(
|
|
pk=patient_id,
|
|
tenant=self.request.user.tenant
|
|
)
|
|
initial['patient'] = patient
|
|
except Patient.DoesNotExist:
|
|
pass
|
|
|
|
return initial
|
|
|
|
def get_context_data(self, **kwargs):
|
|
"""Add form title and patient info."""
|
|
context = super().get_context_data(**kwargs)
|
|
context['form_title'] = 'Create Referral'
|
|
context['submit_text'] = 'Create Referral'
|
|
|
|
# Get patient if provided
|
|
patient_id = self.request.GET.get('patient')
|
|
if patient_id:
|
|
try:
|
|
context['patient'] = Patient.objects.get(
|
|
pk=patient_id,
|
|
tenant=self.request.user.tenant
|
|
)
|
|
except Patient.DoesNotExist:
|
|
pass
|
|
|
|
return context
|
|
|
|
|
|
class ReferralUpdateView(LoginRequiredMixin, RolePermissionMixin, TenantFilterMixin,
|
|
AuditLogMixin, SuccessMessageMixin, UpdateView):
|
|
"""
|
|
Referral update view.
|
|
|
|
Features:
|
|
- Update referral details
|
|
- Only creator can update pending referrals
|
|
"""
|
|
model = Referral
|
|
form_class = ReferralForm
|
|
template_name = 'referrals/referral_form.html'
|
|
success_message = "Referral updated successfully!"
|
|
allowed_roles = [User.Role.ADMIN, User.Role.DOCTOR, User.Role.NURSE,
|
|
User.Role.OT, User.Role.SLP, User.Role.ABA]
|
|
|
|
def get_success_url(self):
|
|
"""Redirect to referral detail."""
|
|
return reverse_lazy('referrals:referral_detail', kwargs={'pk': self.object.pk})
|
|
|
|
def get_form(self, form_class=None):
|
|
"""Disable fields if referral is not pending."""
|
|
form = super().get_form(form_class)
|
|
|
|
if self.object.status != Referral.Status.PENDING:
|
|
for field in form.fields:
|
|
form.fields[field].disabled = True
|
|
|
|
return form
|
|
|
|
def get_context_data(self, **kwargs):
|
|
"""Add form title."""
|
|
context = super().get_context_data(**kwargs)
|
|
context['form_title'] = f'Update Referral - {self.object.patient.mrn}'
|
|
context['submit_text'] = 'Update Referral'
|
|
return context
|
|
|
|
|
|
class ReferralAcceptView(LoginRequiredMixin, RolePermissionMixin, TenantFilterMixin, View):
|
|
"""
|
|
Accept referral view.
|
|
|
|
Features:
|
|
- Accept pending referral
|
|
- Redirect to detail page with success message
|
|
"""
|
|
allowed_roles = [User.Role.ADMIN, User.Role.DOCTOR, User.Role.NURSE,
|
|
User.Role.OT, User.Role.SLP, User.Role.ABA]
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
"""Mark referral as accepted."""
|
|
referral = get_object_or_404(Referral, pk=kwargs['pk'], tenant=request.user.tenant)
|
|
|
|
# Check if user can accept
|
|
if referral.status != Referral.Status.PENDING:
|
|
messages.error(request, 'Only pending referrals can be accepted.')
|
|
return redirect('referrals:referral_detail', pk=referral.pk)
|
|
|
|
if request.user != referral.referred_to and request.user.role != User.Role.ADMIN:
|
|
messages.error(request, 'You do not have permission to accept this referral.')
|
|
return redirect('referrals:referral_detail', pk=referral.pk)
|
|
|
|
# Update status
|
|
referral.status = Referral.Status.ACKNOWLEDGED
|
|
referral.responded_at = timezone.now()
|
|
referral.save()
|
|
|
|
# Send notification to referrer (TODO)
|
|
self._send_acceptance_notification(referral)
|
|
|
|
messages.success(request, 'Referral accepted successfully!')
|
|
return redirect('referrals:referral_detail', pk=referral.pk)
|
|
|
|
def _send_acceptance_notification(self, referral):
|
|
"""Send notification to referrer."""
|
|
# TODO: Implement notification
|
|
pass
|
|
|
|
|
|
class ReferralRejectView(LoginRequiredMixin, RolePermissionMixin, TenantFilterMixin, View):
|
|
"""
|
|
Reject referral view.
|
|
|
|
Features:
|
|
- Reject pending referral
|
|
- Redirect to detail page with message
|
|
"""
|
|
allowed_roles = [User.Role.ADMIN, User.Role.DOCTOR, User.Role.NURSE,
|
|
User.Role.OT, User.Role.SLP, User.Role.ABA]
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
"""Mark referral as rejected."""
|
|
referral = get_object_or_404(Referral, pk=kwargs['pk'], tenant=request.user.tenant)
|
|
|
|
# Check if user can reject
|
|
if referral.status != Referral.Status.PENDING:
|
|
messages.error(request, 'Only pending referrals can be rejected.')
|
|
return redirect('referrals:referral_detail', pk=referral.pk)
|
|
|
|
if request.user != referral.referred_to and request.user.role != User.Role.ADMIN:
|
|
messages.error(request, 'You do not have permission to reject this referral.')
|
|
return redirect('referrals:referral_detail', pk=referral.pk)
|
|
|
|
# Update status
|
|
referral.status = Referral.Status.DECLINED
|
|
referral.responded_at = timezone.now()
|
|
referral.save()
|
|
|
|
# Send notification to referrer (TODO)
|
|
self._send_rejection_notification(referral)
|
|
|
|
messages.warning(request, 'Referral rejected.')
|
|
return redirect('referrals:referral_detail', pk=referral.pk)
|
|
|
|
def _send_rejection_notification(self, referral):
|
|
"""Send notification to referrer."""
|
|
# TODO: Implement notification
|
|
pass
|
|
|
|
|
|
class ReferralCompleteView(LoginRequiredMixin, RolePermissionMixin, TenantFilterMixin, View):
|
|
"""
|
|
Complete referral view.
|
|
|
|
Features:
|
|
- Mark accepted referral as completed
|
|
- Redirect to detail page with success message
|
|
"""
|
|
allowed_roles = [User.Role.ADMIN, User.Role.DOCTOR, User.Role.NURSE,
|
|
User.Role.OT, User.Role.SLP, User.Role.ABA]
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
"""Mark referral as completed."""
|
|
referral = get_object_or_404(Referral, pk=kwargs['pk'], tenant=request.user.tenant)
|
|
|
|
# Check if user can complete
|
|
if referral.status != Referral.Status.ACKNOWLEDGED:
|
|
messages.error(request, 'Only accepted referrals can be completed.')
|
|
return redirect('referrals:referral_detail', pk=referral.pk)
|
|
|
|
if request.user != referral.referred_to and request.user.role != User.Role.ADMIN:
|
|
messages.error(request, 'You do not have permission to complete this referral.')
|
|
return redirect('referrals:referral_detail', pk=referral.pk)
|
|
|
|
# Update status
|
|
referral.status = Referral.Status.COMPLETED
|
|
referral.completed_at = timezone.now()
|
|
referral.save()
|
|
|
|
# Send notification to referrer (TODO)
|
|
self._send_completion_notification(referral)
|
|
|
|
messages.success(request, 'Referral marked as completed!')
|
|
return redirect('referrals:referral_detail', pk=referral.pk)
|
|
|
|
def _send_completion_notification(self, referral):
|
|
"""Send notification to referrer."""
|
|
# TODO: Implement notification
|
|
pass
|
|
|
|
|
|
class ExternalReferralCreateView(FormView):
|
|
"""
|
|
Public view for external centers to submit referrals.
|
|
Does not require authentication.
|
|
"""
|
|
form_class = ExternalReferralForm
|
|
template_name = 'referrals/external_referral_form.html'
|
|
success_url = reverse_lazy('referrals:external_referral_success')
|
|
|
|
def get_context_data(self, **kwargs):
|
|
"""Add tenant information to context."""
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
# Get tenant from subdomain or settings (you may need to adjust this)
|
|
# For now, we'll get the first active tenant
|
|
try:
|
|
tenant = Tenant.objects.filter(is_active=True).first()
|
|
context['tenant'] = tenant
|
|
except Tenant.DoesNotExist:
|
|
context['tenant'] = None
|
|
|
|
return context
|
|
|
|
def form_valid(self, form):
|
|
"""Process the external referral submission."""
|
|
# Get tenant (adjust based on your multi-tenancy setup)
|
|
tenant = Tenant.objects.filter(is_active=True).first()
|
|
|
|
if not tenant:
|
|
messages.error(self.request, 'Unable to process referral at this time.')
|
|
return self.form_invalid(form)
|
|
|
|
# Create or get patient
|
|
patient_data = {
|
|
'first_name_en': form.cleaned_data['patient_first_name'],
|
|
'last_name_en': form.cleaned_data['patient_last_name'],
|
|
'date_of_birth': form.cleaned_data['patient_date_of_birth'],
|
|
'sex': form.cleaned_data['patient_sex'],
|
|
'national_id': form.cleaned_data.get('patient_national_id', ''),
|
|
'caregiver_name': form.cleaned_data['caregiver_name'],
|
|
'caregiver_phone': form.cleaned_data['caregiver_phone'],
|
|
'caregiver_relationship': form.cleaned_data['caregiver_relationship'],
|
|
'tenant': tenant,
|
|
}
|
|
|
|
# Try to find existing patient by national_id or create new
|
|
patient = None
|
|
if patient_data['national_id']:
|
|
patient = Patient.objects.filter(
|
|
tenant=tenant,
|
|
national_id=patient_data['national_id']
|
|
).first()
|
|
|
|
if not patient:
|
|
# Create new patient (MRN will be auto-generated by signal)
|
|
patient = Patient.objects.create(**patient_data)
|
|
|
|
# Get or create an "External" clinic for external referrals
|
|
from core.models import Clinic
|
|
from_clinic, _ = Clinic.objects.get_or_create(
|
|
tenant=tenant,
|
|
code='EXT',
|
|
defaults={
|
|
'name_en': 'External Referrals',
|
|
'name_ar': 'الإحالات الخارجية',
|
|
'specialty': 'EXTERNAL',
|
|
'is_active': True,
|
|
}
|
|
)
|
|
|
|
# Map requested specialty to target clinic
|
|
to_clinic = None
|
|
to_discipline = None
|
|
requested_specialty = form.cleaned_data.get('requested_specialty')
|
|
if requested_specialty:
|
|
to_clinic = Clinic.objects.filter(
|
|
tenant=tenant,
|
|
specialty=requested_specialty,
|
|
is_active=True
|
|
).first()
|
|
if to_clinic:
|
|
to_discipline = requested_specialty
|
|
|
|
# Create referral object
|
|
referral = Referral.objects.create(
|
|
tenant=tenant,
|
|
patient=patient,
|
|
from_clinic=from_clinic,
|
|
external_provider_name=form.cleaned_data['referring_center_name'],
|
|
external_provider_contact=(
|
|
f"Doctor: {form.cleaned_data['referring_doctor_name']}\n"
|
|
f"Phone: {form.cleaned_data['referring_contact_phone']}\n"
|
|
f"Email: {form.cleaned_data['referring_contact_email']}"
|
|
),
|
|
reason=form.cleaned_data['reason'],
|
|
urgency=form.cleaned_data['urgency'],
|
|
clinical_summary=form.cleaned_data.get('clinical_summary', ''),
|
|
from_discipline=Referral.Discipline.EXTERNAL,
|
|
status=Referral.Status.PENDING,
|
|
to_clinic=to_clinic,
|
|
to_discipline=to_discipline,
|
|
notes=(
|
|
f"External Referral from: {form.cleaned_data['referring_center_name']}\n"
|
|
f"Referring Doctor: {form.cleaned_data['referring_doctor_name']}\n"
|
|
f"Contact: {form.cleaned_data['referring_contact_phone']} / {form.cleaned_data['referring_contact_email']}"
|
|
)
|
|
)
|
|
|
|
# Send notification to staff (TODO: implement)
|
|
self._send_staff_notification(referral, form.cleaned_data)
|
|
|
|
# Send confirmation email to referring center
|
|
self._send_confirmation_email(referral, form.cleaned_data)
|
|
|
|
messages.success(
|
|
self.request,
|
|
'Referral submitted successfully! We will contact you soon with updates.'
|
|
)
|
|
|
|
return super().form_valid(form)
|
|
|
|
def _send_staff_notification(self, referral, form_data):
|
|
"""Send notification to internal staff about new external referral."""
|
|
# TODO: Implement notification to staff
|
|
pass
|
|
|
|
def _send_confirmation_email(self, referral, form_data):
|
|
"""Send confirmation email to referring center."""
|
|
# TODO: Implement confirmation email
|
|
pass
|
|
|
|
|
|
class ExternalReferralSuccessView(TemplateView):
|
|
"""Success page after external referral submission."""
|
|
template_name = 'referrals/external_referral_success.html'
|
|
|
|
|
|
class GetProvidersByClinicView(LoginRequiredMixin, View):
|
|
"""
|
|
AJAX endpoint to get providers filtered by clinic.
|
|
Returns JSON list of providers for the selected clinic.
|
|
"""
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
"""Get providers for the specified clinic."""
|
|
clinic_id = request.GET.get('clinic_id')
|
|
|
|
if not clinic_id:
|
|
return JsonResponse({'providers': []})
|
|
|
|
try:
|
|
# Get providers who have this clinic in their specialties
|
|
from appointments.models import Provider
|
|
providers = Provider.objects.filter(
|
|
tenant=request.user.tenant,
|
|
specialties__id=clinic_id,
|
|
is_available=True,
|
|
user__is_active=True
|
|
).select_related('user').values(
|
|
'user__id',
|
|
'user__first_name',
|
|
'user__last_name'
|
|
).distinct()
|
|
|
|
# Format provider data
|
|
provider_list = [
|
|
{
|
|
'id': str(provider['user__id']),
|
|
'name': f"{provider['user__first_name']} {provider['user__last_name']}"
|
|
}
|
|
for provider in providers
|
|
]
|
|
|
|
return JsonResponse({'providers': provider_list})
|
|
|
|
except Exception as e:
|
|
return JsonResponse({'error': str(e)}, status=400)
|