Add NormalCase form and related views for managing normal cases
This commit is contained in:
+117
-3
@@ -457,6 +457,8 @@ def case_detail(request, pk):
|
||||
can_edit = case.check_user_can_edit(request.user)
|
||||
|
||||
is_atlas_editor = request.user.is_superuser or request.user.groups.filter(name="atlas_editor").exists()
|
||||
is_case_author = case.author.filter(id=request.user.id).exists()
|
||||
can_mark_normal = is_atlas_editor or is_case_author or request.user.is_superuser
|
||||
|
||||
return render(
|
||||
request,
|
||||
@@ -466,6 +468,8 @@ def case_detail(request, pk):
|
||||
"cimar_sid": request.user.userprofile.cimar_sid,
|
||||
"can_edit": can_edit,
|
||||
"is_atlas_editor": is_atlas_editor,
|
||||
"is_case_author": is_case_author,
|
||||
"can_mark_normal": can_mark_normal,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -481,8 +485,11 @@ def toggle_case_normal(request, pk):
|
||||
"""
|
||||
case = get_case_for_case_detail(pk)
|
||||
|
||||
# Permission: atlas editors or superusers
|
||||
if not (request.user.is_superuser or request.user.groups.filter(name="atlas_editor").exists()):
|
||||
# Permission: atlas editors, case authors, or superusers
|
||||
is_atlas_editor = request.user.is_superuser or request.user.groups.filter(name="atlas_editor").exists()
|
||||
is_case_author = case.author.filter(id=request.user.id).exists()
|
||||
can_mark_normal = is_atlas_editor or is_case_author or request.user.is_superuser
|
||||
if not can_mark_normal:
|
||||
return HttpResponse(status=403)
|
||||
|
||||
# If already marked normal, unmark (delete the NormalCase)
|
||||
@@ -549,14 +556,121 @@ def toggle_case_normal(request, pk):
|
||||
NormalCase.objects.create(case=case, age_years=age, added_by=request.user)
|
||||
|
||||
# Render the updated fragment
|
||||
# Recompute flags for the fragment render
|
||||
is_atlas_editor = request.user.is_superuser or request.user.groups.filter(name="atlas_editor").exists()
|
||||
is_case_author = case.author.filter(id=request.user.id).exists()
|
||||
can_mark_normal = is_atlas_editor or is_case_author or request.user.is_superuser
|
||||
html = render_to_string(
|
||||
"atlas/partials/_normal_toggle.html",
|
||||
{"case": case, "user": request.user, "is_atlas_editor": is_atlas_editor},
|
||||
{"case": case, "user": request.user, "is_atlas_editor": is_atlas_editor, "is_case_author": is_case_author, "can_mark_normal": can_mark_normal},
|
||||
request=request,
|
||||
)
|
||||
return HttpResponse(html)
|
||||
|
||||
|
||||
@login_required
|
||||
def case_normal_form(request, pk):
|
||||
"""Return an HTMX modal with a NormalCaseForm prepopulated with auto-extracted values."""
|
||||
case = get_case_for_case_detail(pk)
|
||||
|
||||
# Permission check: allow atlas editors, case authors, or superusers
|
||||
is_atlas_editor = request.user.is_superuser or request.user.groups.filter(name="atlas_editor").exists()
|
||||
is_case_author = case.author.filter(id=request.user.id).exists()
|
||||
can_mark_normal = is_atlas_editor or is_case_author or request.user.is_superuser
|
||||
if not can_mark_normal:
|
||||
return HttpResponse(status=403)
|
||||
|
||||
# Extract defaults
|
||||
age = None
|
||||
inferred_examination = None
|
||||
inferred_modality = None
|
||||
try:
|
||||
for series in case.series.all():
|
||||
img = series.images.filter(removed=False).first()
|
||||
if not img:
|
||||
continue
|
||||
ds = img.get_dicom_data()
|
||||
if not ds:
|
||||
continue
|
||||
|
||||
pa = getattr(ds, "PatientAge", None)
|
||||
if pa:
|
||||
import re
|
||||
m = re.search(r"(\d+)", str(pa))
|
||||
if m:
|
||||
age = int(m.group(1))
|
||||
break
|
||||
|
||||
pbd = getattr(ds, "PatientBirthDate", None)
|
||||
sdate = getattr(ds, "StudyDate", None) or getattr(ds, "AcquisitionDate", None) or getattr(ds, "SeriesDate", None)
|
||||
if pbd and sdate:
|
||||
from datetime import datetime
|
||||
try:
|
||||
bd = datetime.strptime(str(pbd), "%Y%m%d")
|
||||
sd = datetime.strptime(str(sdate), "%Y%m%d")
|
||||
years = round((sd - bd).days / 365.25)
|
||||
age = int(years)
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Try inferring exam/modality from first series
|
||||
first_series = case.series.first()
|
||||
if first_series is not None:
|
||||
inferred_examination = getattr(first_series, "examination", None)
|
||||
inferred_modality = getattr(first_series, "modality", None)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Build form with initial values
|
||||
from .forms import NormalCaseForm
|
||||
|
||||
form = NormalCaseForm(initial={
|
||||
"age_years": age,
|
||||
"examination": inferred_examination,
|
||||
"modality": inferred_modality,
|
||||
})
|
||||
|
||||
html = render_to_string("atlas/partials/_normal_form.html", {"form": form, "case": case}, request=request)
|
||||
return HttpResponse(html)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_POST
|
||||
def create_case_normal(request, pk):
|
||||
case = get_case_for_case_detail(pk)
|
||||
|
||||
# Permission check: allow atlas editors, case authors, or superusers
|
||||
is_atlas_editor = request.user.is_superuser or request.user.groups.filter(name="atlas_editor").exists()
|
||||
is_case_author = case.author.filter(id=request.user.id).exists()
|
||||
can_mark_normal = is_atlas_editor or is_case_author or request.user.is_superuser
|
||||
if not can_mark_normal:
|
||||
return HttpResponse(status=403)
|
||||
|
||||
from .forms import NormalCaseForm
|
||||
form = NormalCaseForm(request.POST)
|
||||
if form.is_valid():
|
||||
nc = form.save(commit=False)
|
||||
nc.case = case
|
||||
nc.added_by = request.user
|
||||
nc.save()
|
||||
|
||||
# Return the updated toggle fragment and close modal via inline script
|
||||
is_atlas_editor = request.user.is_superuser or request.user.groups.filter(name="atlas_editor").exists()
|
||||
is_case_author = case.author.filter(id=request.user.id).exists()
|
||||
can_mark_normal = is_atlas_editor or is_case_author or request.user.is_superuser
|
||||
toggle_html = render_to_string(
|
||||
"atlas/partials/_normal_toggle.html",
|
||||
{"case": case, "user": request.user, "is_atlas_editor": is_atlas_editor, "is_case_author": is_case_author, "can_mark_normal": can_mark_normal},
|
||||
request=request,
|
||||
)
|
||||
toggle_html += "<script>var m = bootstrap.Modal.getOrCreateInstance(document.getElementById('normal-modal-{}')); if(m) m.hide();</script>".format(case.pk)
|
||||
return HttpResponse(toggle_html)
|
||||
else:
|
||||
# On form errors, re-render the modal with errors
|
||||
html = render_to_string("atlas/partials/_normal_form.html", {"form": form, "case": case}, request=request)
|
||||
return HttpResponse(html, status=400)
|
||||
|
||||
@login_required
|
||||
@user_is_author_or_atlas_series_checker_or_atlas_marker_or_open_access
|
||||
def series_thumbnail_fail(request, pk):
|
||||
|
||||
Reference in New Issue
Block a user