diff --git a/anatomy/migrations/0004_exam_candidates_only_alter_exam_active_and_more.py b/anatomy/migrations/0004_exam_candidates_only_alter_exam_active_and_more.py new file mode 100644 index 00000000..757b7341 --- /dev/null +++ b/anatomy/migrations/0004_exam_candidates_only_alter_exam_active_and_more.py @@ -0,0 +1,43 @@ +# Generated by Django 4.1.4 on 2023-07-24 09:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('anatomy', '0003_alter_anatomyquestion_modality_delete_modality'), + ] + + operations = [ + migrations.AddField( + model_name='exam', + name='candidates_only', + field=models.BooleanField(default=True, help_text='If the exam/collection is only available to candidates who have been added'), + ), + migrations.AlterField( + model_name='exam', + name='active', + field=models.BooleanField(default=False, help_text='If an exam/collection should be available to take'), + ), + migrations.AlterField( + model_name='exam', + name='archive', + field=models.BooleanField(default=False, help_text='Archived exams/collections will remain on the test system but will not be displayed by default'), + ), + migrations.AlterField( + model_name='exam', + name='name', + field=models.CharField(help_text='Name of the exam/collection', max_length=200), + ), + migrations.AlterField( + model_name='exam', + name='open_access', + field=models.BooleanField(default=False, help_text='If the exam/collection is freely accessible (to view and edit on the test system)'), + ), + migrations.AlterField( + model_name='exam', + name='publish_results', + field=models.BooleanField(default=False, help_text='If an exam/collections results should be available'), + ), + ] diff --git a/atlas/migrations/0005_casecollection_user_user_groups_and_more.py b/atlas/migrations/0005_casecollection_user_user_groups_and_more.py new file mode 100644 index 00000000..e7542028 --- /dev/null +++ b/atlas/migrations/0005_casecollection_user_user_groups_and_more.py @@ -0,0 +1,36 @@ +# Generated by Django 4.1.4 on 2023-07-24 09:06 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('generic', '0006_alter_ciduserexam_completed'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('atlas', '0004_casecollection_self_review'), + ] + + operations = [ + migrations.AddField( + model_name='casecollection', + name='user_user_groups', + field=models.ManyToManyField(blank=True, help_text='These groups define which candidates are able to be added to the exams/collection.', related_name='casecollection_user_user_groups', to='generic.userusergroup'), + ), + migrations.AddField( + model_name='casecollection', + name='valid_user_users', + field=models.ManyToManyField(blank=True, related_name='user_casecollection_exams', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='casecollection', + name='author', + field=models.ManyToManyField(blank=True, help_text='Author of the collection', related_name='casecollection_authored_cases', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='casecollection', + name='cid_user_groups', + field=models.ManyToManyField(blank=True, help_text='These groups define which candidates are able to be added to the exams/collection.', related_name='casecollection_cid_user_groups', to='generic.cidusergroup'), + ), + ] diff --git a/atlas/migrations/0006_casecollection_candidates_only_and_more.py b/atlas/migrations/0006_casecollection_candidates_only_and_more.py new file mode 100644 index 00000000..3a054af1 --- /dev/null +++ b/atlas/migrations/0006_casecollection_candidates_only_and_more.py @@ -0,0 +1,43 @@ +# Generated by Django 4.1.4 on 2023-07-24 09:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('atlas', '0005_casecollection_user_user_groups_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='casecollection', + name='candidates_only', + field=models.BooleanField(default=True, help_text='If the exam/collection is only available to candidates who have been added'), + ), + migrations.AlterField( + model_name='casecollection', + name='active', + field=models.BooleanField(default=False, help_text='If an exam/collection should be available to take'), + ), + migrations.AlterField( + model_name='casecollection', + name='archive', + field=models.BooleanField(default=False, help_text='Archived exams/collections will remain on the test system but will not be displayed by default'), + ), + migrations.AlterField( + model_name='casecollection', + name='name', + field=models.CharField(help_text='Name of the exam/collection', max_length=200), + ), + migrations.AlterField( + model_name='casecollection', + name='open_access', + field=models.BooleanField(default=False, help_text='If the exam/collection is freely accessible (to view and edit on the test system)'), + ), + migrations.AlterField( + model_name='casecollection', + name='publish_results', + field=models.BooleanField(default=False, help_text='If an exam/collections results should be available'), + ), + ] diff --git a/atlas/models.py b/atlas/models.py index 9b08d44c..4b29835f 100644 --- a/atlas/models.py +++ b/atlas/models.py @@ -2,7 +2,7 @@ import json import os import pathlib -from django.http import Http404 +from django.http import Http404, HttpRequest from rad.settings import REMOTE_URL from django.db.models.fields.files import ImageField from django.db.models.fields.related import ForeignKey @@ -46,6 +46,7 @@ from generic.models import ( SeriesBase, SeriesImageBase, Modality, + UserUserGroup, ) # from generic.models import Examination, Site, Condition, Sign @@ -413,18 +414,8 @@ class Series(SeriesBase): class CaseCollection(ExamCollectionGenericBase): app_name = "atlas" - name = models.CharField(max_length=255, unique=True) - cases = models.ManyToManyField(Case, through="CaseDetail") - publish_results = models.BooleanField( - help_text="If a collection should published", default=False - ) - - active = models.BooleanField( - help_text="If a collection should be available", default=True - ) - show_title_pre = models.BooleanField( default=False, help_text="Show the title of the cases (pre exam)" ) @@ -461,20 +452,31 @@ class CaseCollection(ExamCollectionGenericBase): settings.AUTH_USER_MODEL, blank=True, help_text="Author of the collection", - # related_name="atlas_authored_cases", + related_name="casecollection_authored_cases", ) valid_cid_users = models.ManyToManyField( CidUser, blank=True, related_name="casecollection_exams" ) + valid_user_users = models.ManyToManyField( + settings.AUTH_USER_MODEL, blank=True, related_name="user_casecollection_exams" + ) + cid_user_groups = models.ManyToManyField( CidUserGroup, blank=True, help_text="These groups define which candidates are able to be added to the exams/collection.", + related_name="casecollection_cid_user_groups", + ) + + user_user_groups = models.ManyToManyField( + UserUserGroup, + blank=True, + help_text="These groups define which candidates are able to be added to the exams/collection.", + related_name="casecollection_user_user_groups", ) - archive = models.BooleanField(default=False) exam_mode = models.BooleanField(default=False) # This should override the publish setting @@ -483,11 +485,6 @@ class CaseCollection(ExamCollectionGenericBase): help_text="If true allows users self complete and review cases in a self directed way.", ) - open_access = models.BooleanField( - help_text="If the exam is freely accessible (to view and edit on the test system)", - default=False, - ) - class COLLECTION_TYPE_CHOICES(models.TextChoices): REVIEW = ( "REV", @@ -525,30 +522,6 @@ class CaseCollection(ExamCollectionGenericBase): return False - def check_user_can_take(self, cid, passcode, request): - """ - Helper to check if a user is allowed to access a collection - - Args: - cid (_type_): _description_ - passcode (_type_): _description_ - request (_type_): _description_ - - Raises: - Http404: If user does not have access - """ - if not self.active: - raise Http404("Exam not found") - - #if self.collection_is_review(): - # return True - - #if not self.self_review: - - if not self.check_cid_user(cid, passcode, request): - raise Http404("Error accessing exam") - - class CaseDetail(models.Model): case = models.ForeignKey(Case, on_delete=models.CASCADE) collection = models.ForeignKey(CaseCollection, on_delete=models.CASCADE) diff --git a/atlas/tables.py b/atlas/tables.py index f95ac078..737ed241 100755 --- a/atlas/tables.py +++ b/atlas/tables.py @@ -273,7 +273,7 @@ class SubspecialtyTable(tables.Table): class CaseCollectionTable(tables.Table): edit = tables.LinkColumn( - "atlas:collection_update", text="Edit", args=[A("pk")], orderable=False + "atlas:exam_update", text="Edit", args=[A("pk")], orderable=False ) view = tables.LinkColumn( "atlas:collection_detail", text="View", args=[A("pk")], orderable=False @@ -282,7 +282,7 @@ class CaseCollectionTable(tables.Table): # "atlas:case_clone", text="Clone", args=[A("pk")], orderable=False #) delete = tables.LinkColumn( - "atlas:collection_delete", text="Delete", args=[A("pk")], orderable=False + "atlas:exam_deleted", text="Delete", args=[A("pk")], orderable=False ) #differential = tables.ManyToManyColumn(verbose_name="Differential") diff --git a/atlas/templates/atlas/base.html b/atlas/templates/atlas/base.html index f3d008ba..5d5d4c09 100755 --- a/atlas/templates/atlas/base.html +++ b/atlas/templates/atlas/base.html @@ -4,16 +4,6 @@ Atlas {% endblock %} -{% block css %} -{% endblock %} - -{% block js %} -{% endblock %} - - - -{% block content %} -{% endblock %} {% block navigation %} Atlas: {% if request.user.is_authenticated %} @@ -28,3 +18,6 @@ Questions by: {% endcomment %} {% endblock %} + +{% block content %} +{% endblock %} \ No newline at end of file diff --git a/atlas/templates/atlas/case_form.html b/atlas/templates/atlas/case_form.html index 0e43584b..8a5b9f1a 100755 --- a/atlas/templates/atlas/case_form.html +++ b/atlas/templates/atlas/case_form.html @@ -53,7 +53,7 @@ Use this form to create a atlas case. Existing associated image sets can be added using this form. {% if form.collection %} -