ixg_platform/apps/ops/views.py

197 lines
6.7 KiB
Python

from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.db.models import Count, Q
from django.utils import timezone
from django.views.generic import TemplateView, ListView, DetailView
from django.shortcuts import get_object_or_404
from apps.batches.models import ProcessingBatch
from apps.qc.models import QCResult
from apps.shipments.models import Shipment
from apps.capa.models import CAPARecord
from apps.documents.models import Document
from apps.esg.models import ESGFieldReport
from apps.notifications.models import Notification
class OpsRequiredMixin(UserPassesTestMixin):
def test_func(self):
user = self.request.user
return user.is_authenticated and (user.role in ('ops', 'admin') or user.is_superuser)
class DashboardView(OpsRequiredMixin, TemplateView):
template_name = 'ops/dashboard.html'
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['total_batches'] = ProcessingBatch.objects.count()
ctx['batches_by_status'] = {
s: ProcessingBatch.objects.filter(status=s).count()
for s, _ in ProcessingBatch.Status.choices
}
ctx['recent_qc'] = QCResult.objects.select_related('batch').order_by('-tested_at')[:10]
ctx['qc_summary'] = QCResult.objects.aggregate(
passed=Count('id', filter=Q(overall_pass=True)),
failed=Count('id', filter=Q(overall_pass=False)),
)
ctx['active_shipments'] = Shipment.objects.exclude(status='delivered').count()
ctx['open_capas'] = CAPARecord.objects.filter(status__in=('open', 'in_progress')).count()
ctx['recent_notifications'] = Notification.objects.filter(
user=self.request.user, is_read=False
)[:5]
ctx['recent_batches'] = ProcessingBatch.objects.order_by('-created_at')[:5]
return ctx
class BatchListView(OpsRequiredMixin, ListView):
model = ProcessingBatch
template_name = 'ops/batch_list.html'
context_object_name = 'batches'
paginate_by = 25
def get_queryset(self):
qs = ProcessingBatch.objects.all()
status = self.request.GET.get('status')
grade = self.request.GET.get('grade')
search = self.request.GET.get('q')
if status:
qs = qs.filter(status=status)
if grade:
qs = qs.filter(grade=grade)
if search:
qs = qs.filter(batch_reference__icontains=search)
return qs
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['status_choices'] = ProcessingBatch.Status.choices
ctx['grade_choices'] = ProcessingBatch.Grade.choices
ctx['current_status'] = self.request.GET.get('status', '')
ctx['current_grade'] = self.request.GET.get('grade', '')
ctx['current_q'] = self.request.GET.get('q', '')
return ctx
class BatchDetailView(OpsRequiredMixin, DetailView):
model = ProcessingBatch
template_name = 'ops/batch_detail.html'
context_object_name = 'batch'
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
batch = self.object
ctx['qc_results'] = QCResult.objects.filter(batch=batch)
ctx['shipments'] = Shipment.objects.filter(batch=batch)
ctx['capa_records'] = CAPARecord.objects.filter(batch=batch)
ctx['documents'] = Document.objects.filter(batch=batch)
ctx['esg_reports'] = ESGFieldReport.objects.filter(batch=batch)
return ctx
class QCListView(OpsRequiredMixin, ListView):
model = QCResult
template_name = 'ops/qc_list.html'
context_object_name = 'results'
paginate_by = 25
def get_queryset(self):
qs = QCResult.objects.select_related('batch').all()
passed = self.request.GET.get('passed')
if passed == '1':
qs = qs.filter(overall_pass=True)
elif passed == '0':
qs = qs.filter(overall_pass=False)
return qs
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['current_passed'] = self.request.GET.get('passed', '')
return ctx
class QCDetailView(OpsRequiredMixin, DetailView):
model = QCResult
template_name = 'ops/qc_detail.html'
context_object_name = 'result'
class ShipmentListView(OpsRequiredMixin, ListView):
model = Shipment
template_name = 'ops/shipment_list.html'
context_object_name = 'shipments'
paginate_by = 25
def get_queryset(self):
qs = Shipment.objects.select_related('batch').all()
status = self.request.GET.get('status')
if status:
qs = qs.filter(status=status)
return qs
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['status_choices'] = Shipment.Status.choices
ctx['current_status'] = self.request.GET.get('status', '')
return ctx
class ShipmentDetailView(OpsRequiredMixin, DetailView):
model = Shipment
template_name = 'ops/shipment_detail.html'
context_object_name = 'shipment'
class CAPAListView(OpsRequiredMixin, ListView):
model = CAPARecord
template_name = 'ops/capa_list.html'
context_object_name = 'records'
paginate_by = 25
def get_queryset(self):
qs = CAPARecord.objects.select_related('batch').all()
status = self.request.GET.get('status')
if status:
qs = qs.filter(status=status)
return qs
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['status_choices'] = CAPARecord.Status.choices
ctx['current_status'] = self.request.GET.get('status', '')
return ctx
class CAPADetailView(OpsRequiredMixin, DetailView):
model = CAPARecord
template_name = 'ops/capa_detail.html'
context_object_name = 'record'
class DocumentListView(OpsRequiredMixin, ListView):
model = Document
template_name = 'ops/document_list.html'
context_object_name = 'documents'
paginate_by = 25
def get_queryset(self):
qs = Document.objects.select_related('batch', 'uploaded_by').all()
doc_type = self.request.GET.get('doc_type')
if doc_type:
qs = qs.filter(doc_type=doc_type)
return qs
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['doc_type_choices'] = Document.DocType.choices
ctx['current_doc_type'] = self.request.GET.get('doc_type', '')
return ctx
class ESGListView(OpsRequiredMixin, ListView):
model = ESGFieldReport
template_name = 'ops/esg_list.html'
context_object_name = 'reports'
paginate_by = 25
def get_queryset(self):
return ESGFieldReport.objects.select_related('batch').all()