""" Views for integrations app. """ from django.contrib.auth.mixins import LoginRequiredMixin from django.urls import reverse_lazy from django.views.generic import ListView, CreateView, DetailView, UpdateView, TemplateView from django.utils.translation import gettext_lazy as _ from django.contrib import messages from core.mixins import TenantFilterMixin from .models import ( ExternalOrder, NphiesMessage, PayerContract, EInvoice, ZatcaCredential, ) from .forms import ExternalOrderForm, PayerContractForm, ZatcaCredentialForm # ============================================================================ # Dashboard # ============================================================================ class IntegrationsDashboardView(LoginRequiredMixin, TenantFilterMixin, TemplateView): """Integrations dashboard with overview of all integration modules.""" template_name = 'integrations/integrations_dashboard.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) tenant = self.request.user.tenant # Get counts for dashboard stats context['stats'] = { 'external_orders_count': ExternalOrder.objects.filter(tenant=tenant).count(), 'nphies_messages_count': NphiesMessage.objects.filter(tenant=tenant).count(), 'einvoices_count': EInvoice.objects.filter(tenant=tenant).count(), 'payer_contracts_count': PayerContract.objects.filter(tenant=tenant).count(), } return context # ============================================================================ # External Orders (Lab & Radiology) # ============================================================================ class ExternalOrderListView(LoginRequiredMixin, TenantFilterMixin, ListView): """List all external orders.""" model = ExternalOrder template_name = 'integrations/external_order_list.html' context_object_name = 'orders' paginate_by = 20 def get_queryset(self): queryset = super().get_queryset().filter( tenant=self.request.user.tenant ).select_related('patient', 'ordered_by') # Filter by order type if provided order_type = self.request.GET.get('order_type') if order_type: queryset = queryset.filter(order_type=order_type) # Filter by status if provided status = self.request.GET.get('status') if status: queryset = queryset.filter(status=status) return queryset.order_by('-ordered_at') def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['order_types'] = ExternalOrder.OrderType.choices context['statuses'] = ExternalOrder.Status.choices return context class ExternalOrderCreateView(LoginRequiredMixin, TenantFilterMixin, CreateView): """Create a new external order.""" model = ExternalOrder form_class = ExternalOrderForm template_name = 'integrations/external_order_form.html' success_url = reverse_lazy('integrations:order-list') def form_valid(self, form): form.instance.tenant = self.request.user.tenant form.instance.ordered_by = self.request.user messages.success(self.request, _('External order created successfully.')) return super().form_valid(form) class ExternalOrderDetailView(LoginRequiredMixin, TenantFilterMixin, DetailView): """View external order details.""" model = ExternalOrder template_name = 'integrations/external_order_detail.html' context_object_name = 'order' def get_queryset(self): return super().get_queryset().filter( tenant=self.request.user.tenant ).select_related('patient', 'ordered_by') class ExternalOrderUpdateView(LoginRequiredMixin, TenantFilterMixin, UpdateView): """Update an external order.""" model = ExternalOrder form_class = ExternalOrderForm template_name = 'integrations/external_order_form.html' def get_queryset(self): return super().get_queryset().filter(tenant=self.request.user.tenant) def get_success_url(self): return reverse_lazy('integrations:order-detail', kwargs={'pk': self.object.pk}) def form_valid(self, form): messages.success(self.request, _('External order updated successfully.')) return super().form_valid(form) # ============================================================================ # NPHIES Messages # ============================================================================ class NphiesMessageListView(LoginRequiredMixin, TenantFilterMixin, ListView): """List all NPHIES messages.""" model = NphiesMessage template_name = 'integrations/nphies_message_list.html' context_object_name = 'messages' paginate_by = 20 def get_queryset(self): queryset = super().get_queryset().filter(tenant=self.request.user.tenant) # Filter by direction if provided direction = self.request.GET.get('direction') if direction: queryset = queryset.filter(direction=direction) # Filter by resource type if provided resource_type = self.request.GET.get('resource_type') if resource_type: queryset = queryset.filter(resource_type=resource_type) # Filter by status if provided status = self.request.GET.get('status') if status: queryset = queryset.filter(status=status) return queryset.order_by('-created_at') def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['directions'] = NphiesMessage.Direction.choices context['resource_types'] = NphiesMessage.ResourceType.choices context['statuses'] = NphiesMessage.Status.choices return context class NphiesMessageDetailView(LoginRequiredMixin, TenantFilterMixin, DetailView): """View NPHIES message details.""" model = NphiesMessage template_name = 'integrations/nphies_message_detail.html' context_object_name = 'message' def get_queryset(self): return super().get_queryset().filter(tenant=self.request.user.tenant) # ============================================================================ # Payer Contracts # ============================================================================ class PayerContractListView(LoginRequiredMixin, TenantFilterMixin, ListView): """List all payer contracts.""" model = PayerContract template_name = 'integrations/payer_contract_list.html' context_object_name = 'payers' paginate_by = 20 def get_queryset(self): queryset = super().get_queryset().filter(tenant=self.request.user.tenant) # Filter by active status if provided is_active = self.request.GET.get('is_active') if is_active: queryset = queryset.filter(is_active=is_active == 'true') return queryset.order_by('payer_name') class PayerContractCreateView(LoginRequiredMixin, TenantFilterMixin, CreateView): """Create a new payer contract.""" model = PayerContract form_class = PayerContractForm template_name = 'integrations/payer_contract_form.html' success_url = reverse_lazy('integrations:payer-list') def form_valid(self, form): form.instance.tenant = self.request.user.tenant messages.success(self.request, _('Payer contract created successfully.')) return super().form_valid(form) class PayerContractUpdateView(LoginRequiredMixin, TenantFilterMixin, UpdateView): """Update a payer contract.""" model = PayerContract form_class = PayerContractForm template_name = 'integrations/payer_contract_form.html' success_url = reverse_lazy('integrations:payer-list') def get_queryset(self): return super().get_queryset().filter(tenant=self.request.user.tenant) def form_valid(self, form): messages.success(self.request, _('Payer contract updated successfully.')) return super().form_valid(form) # ============================================================================ # E-Invoices (ZATCA) # ============================================================================ class EInvoiceListView(LoginRequiredMixin, TenantFilterMixin, ListView): """List all e-invoices.""" model = EInvoice template_name = 'integrations/einvoice_list.html' context_object_name = 'einvoices' paginate_by = 20 def get_queryset(self): queryset = super().get_queryset().filter( tenant=self.request.user.tenant ).select_related('invoice') # Filter by clearance status if provided clearance_status = self.request.GET.get('clearance_status') if clearance_status: queryset = queryset.filter(clearance_status=clearance_status) # Filter by submission mode if provided submission_mode = self.request.GET.get('submission_mode') if submission_mode: queryset = queryset.filter(submission_mode=submission_mode) return queryset.order_by('-created_at') def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['clearance_statuses'] = EInvoice.ClearanceStatus.choices context['submission_modes'] = EInvoice.SubmissionMode.choices return context class EInvoiceDetailView(LoginRequiredMixin, TenantFilterMixin, DetailView): """View e-invoice details.""" model = EInvoice template_name = 'integrations/einvoice_detail.html' context_object_name = 'einvoice' def get_queryset(self): return super().get_queryset().filter( tenant=self.request.user.tenant ).select_related('invoice') # ============================================================================ # ZATCA Credentials # ============================================================================ class ZatcaCredentialListView(LoginRequiredMixin, TenantFilterMixin, ListView): """List all ZATCA credentials.""" model = ZatcaCredential template_name = 'integrations/zatca_credential_list.html' context_object_name = 'credentials' paginate_by = 20 def get_queryset(self): queryset = super().get_queryset().filter(tenant=self.request.user.tenant) # Filter by environment if provided environment = self.request.GET.get('environment') if environment: queryset = queryset.filter(environment=environment) return queryset.order_by('-created_at') def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['environments'] = ZatcaCredential.Environment.choices return context class ZatcaCredentialCreateView(LoginRequiredMixin, TenantFilterMixin, CreateView): """Create a new ZATCA credential.""" model = ZatcaCredential form_class = ZatcaCredentialForm template_name = 'integrations/zatca_credential_form.html' success_url = reverse_lazy('integrations:credential-list') def form_valid(self, form): form.instance.tenant = self.request.user.tenant messages.success(self.request, _('ZATCA credential created successfully.')) return super().form_valid(form)