Skip to content

Commit 7184082

Browse files
Add submision conversion feature for individual submission and by module
conversion EDIT-767
1 parent 8245ca6 commit 7184082

8 files changed

Lines changed: 133 additions & 2 deletions

File tree

exercise/staff_views.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
from authorization.permissions import ACCESS
2020
from course.viewbase import CourseInstanceBaseView, CourseInstanceMixin
2121
from course.models import (
22+
CourseModule,
2223
Enrollment,
2324
USERTAG_EXTERNAL,
2425
USERTAG_INTERNAL,
2526
)
2627
from deviations.models import MaxSubmissionsRuleDeviation
2728
from exercise.cache.points import CachedPoints
29+
from exercise.exercise_models import BaseExercise
2830
from lib.helpers import settings_text, extract_form_errors
2931
from lib.viewbase import BaseRedirectView, BaseFormView, BaseView
3032
from notification.models import Notification
@@ -530,3 +532,61 @@ def form_valid(self, form):
530532
def form_invalid(self, form):
531533
messages.error(self.request, _('FAILURE_SAVING_CHANGES'))
532534
return super().form_invalid(form)
535+
536+
class SubmissionConversion(SubmissionMixin, BaseRedirectView):
537+
"""
538+
A POST-only view that updates a student's late or unofficial submission
539+
to normal submission. Changed the status and remove the penalty
540+
"""
541+
def post(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
542+
self.submission = self.get_submission_object()
543+
self.submission.convert_late_submission()
544+
self.submission.save()
545+
return self.redirect(self.submission.get_inspect_url())
546+
547+
548+
class SubmissionConversionByModule(CourseInstanceMixin, BaseRedirectView):
549+
"""
550+
A POST-only view that by module bulks updates a student's late or unofficial submission
551+
to normal submission. Changed the status and remove the penalty
552+
"""
553+
554+
user_kw = 'user_id'
555+
module_kw = 'module_id'
556+
access_mode = ACCESS.ASSISTANT
557+
558+
def get_course_module_object(self):
559+
return get_object_or_404(
560+
CourseModule,
561+
id=self.kwargs[self.module_kw],
562+
course_instance=self.instance
563+
)
564+
565+
def get_resource_objects(self):
566+
self.kwargs[self.user_kw] = self.request.POST[self.user_kw],
567+
self.kwargs[self.user_kw] = self.kwargs[self.user_kw][0]
568+
self.kwargs[self.module_kw] = self.request.POST[self.module_kw]
569+
super().get_resource_objects()
570+
571+
#getting module and user by id.
572+
self.module = get_object_or_404(
573+
CourseModule,
574+
id=self.kwargs[self.module_kw])
575+
576+
self.student = get_object_or_404(
577+
User,
578+
id=self.kwargs[self.user_kw],
579+
)
580+
581+
def post(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
582+
profile = self.student.userprofile
583+
exercises = BaseExercise.objects.filter(course_module=self.module)
584+
585+
for exercise in exercises:
586+
submissions = exercise.get_submissions_for_student(self.student.userprofile, exclude_errors=True)
587+
for submission in submissions:
588+
submission.convert_late_submission()
589+
submission.save()
590+
591+
link = reverse('user-results', kwargs={'user_id': profile.id, **self.instance.get_url_kwargs()})
592+
return self.redirect(link)

exercise/submission_models.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,16 @@ def clean_post_parameters(self):
406406
del self._files
407407
del self._data
408408

409+
def convert_late_submission(self):
410+
"""
411+
Removes penalty and Sets the points for this submission object based on original score.
412+
Then this will set the status of submission to ready
413+
414+
The method is used to convert late submission to fully graded one.
415+
"""
416+
self.set_points(self.service_points, self.service_max_points, no_penalties=True)
417+
self.set_ready()
418+
409419
def set_points(self, points, max_points, no_penalties=False):
410420
"""
411421
Sets the points and maximum points for this submissions. If the given

exercise/templates/exercise/_user_results.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,22 @@ <h3 class="panel-title">
8585

8686
{% points_progress module %}
8787
{{ module.introduction|safe }}
88+
89+
{% if module.late_allowed and module.late_percent > 0 %}
90+
91+
<form method="post" action="{% url 'submission-conversion-module' course_slug=course.url instance_slug=instance.url %}" style="display: inline-block">
92+
{% csrf_token %}
93+
<input type="hidden" id="module_id" name="module_id" value="{{ module.id }}">
94+
<input type="hidden" id="user_id" name="user_id" value="{{ student.id }}">
95+
<button
96+
class="aplus-button--secondary aplus-button--xs"
97+
type="submit"
98+
>
99+
{% translate "CONVERT_SUBMISSION_BY_MODULE" %}
100+
</button>
101+
</form>
102+
{% endif %}
103+
88104
</div>
89105
{% if not exercise_accessible and not is_course_staff %}
90106
<div class="alert alert-warning clearfix site-message">

exercise/templates/exercise/staff/_assessment_panel.html

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,23 @@
1919
{% endif %}
2020
</div>
2121
<div>
22-
<button
22+
{% if submission.late_penalty_applied %}
23+
<form method="post" action="{{ submission|url:'submission-conversion' }}" style="display: inline-block">
24+
{% csrf_token %}
25+
<button
26+
class="aplus-button--secondary aplus-button--sm aplus-button--left"
27+
type="submit"
28+
>
29+
{% translate 'CONVERT_SUBMISSION' %}
30+
</button><button
31+
data-toggle="modal"
32+
data-target="#resubmit-modal"
33+
class="aplus-button--secondary aplus-button--sm aplus-button--right"
34+
type="button"
35+
title="{% translate 'HELP' %}"
36+
>?</button>
37+
{% endif %}
38+
</form> <button
2339
data-toggle="modal"
2440
data-target="#details-modal"
2541
class="aplus-button--secondary aplus-button--sm"

exercise/tests.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,13 @@ def test_submission_late_penalty_applied(self):
571571
deviation.save()
572572
self.late_late_submission_when_late_allowed.set_points(5, 10)
573573
self.assertAlmostEqual(self.late_late_submission_when_late_allowed.late_penalty_applied, 0.2)
574+
575+
def test_submission_late_conversion(self):
576+
convert_submission_url = self.late_submission.get_url('submission-conversion')
577+
response = self.client.get(convert_submission_url)
578+
self.assertEqual(response.status_code, 302)
579+
self.assertTrue(self.late_submission.late_penalty_applied is None)
580+
574581

575582
def test_early_submission(self):
576583
self.course_module_with_late_submissions_allowed.opening_time = self.tomorrow

exercise/urls.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@
5555
url(EXERCISE_URL_PREFIX + r'submitters/next-unassessed/$',
5656
staff_views.NextUnassessedSubmitterView.as_view(),
5757
name="submission-next-unassessed"),
58+
url(SUBMISSION_URL_PREFIX + r'convert/$',
59+
staff_views.SubmissionConversion.as_view(),
60+
name="submission-conversion"
61+
),
5862
url(SUBMISSION_URL_PREFIX + r'inspect/$',
5963
staff_views.InspectSubmissionView.as_view(),
6064
name="submission-inspect"),
@@ -79,7 +83,9 @@
7983
url(EDIT_URL_PREFIX + r'fetch-metadata/$',
8084
staff_views.FetchMetadataView.as_view(),
8185
name="exercise-metadata"),
82-
86+
url(EDIT_URL_PREFIX+r'convert/module/$',
87+
staff_views.SubmissionConversionByModule.as_view(),
88+
name="submission-conversion-module"),
8389
url(EXERCISE_URL_PREFIX + r'plain/$',
8490
views.ExercisePlainView.as_view(),
8591
name="exercise-plain"),

locale/en/LC_MESSAGES/django.po

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3711,6 +3711,10 @@ msgstr "%(points)s points required to pass the module. "
37113711
msgid "CHANGES_ARE_POSSIBLE_IN_EXERCISES_BEFORE_MODULE_OPENING"
37123712
msgstr "There may be changes in the assignments before the module opens!"
37133713

3714+
#: exercise/templates/exercise/_user_results.html
3715+
msgid "CONVERT_SUBMISSION_BY_MODULE"
3716+
msgstr "Convert Late Submissions"
3717+
37143718
#: exercise/templates/exercise/_user_results.html
37153719
#: exercise/templates/exercise/staff/_submitters_table.html
37163720
#: exercise/templates/exercise/staff/inspect_submission.html
@@ -3838,6 +3842,10 @@ msgstr "Submission details"
38383842
msgid "REGRADE_AUTOMATICALLY"
38393843
msgstr "Regrade automatically"
38403844

3845+
#: exercise/templates/exercise/staff/_assessment_panel.html
3846+
msgid "CONVERT_SUBMISSION"
3847+
msgstr "Convert Submission"
3848+
38413849
#: exercise/templates/exercise/staff/_assessment_panel.html
38423850
msgid "HELP"
38433851
msgstr "Help"

locale/fi/LC_MESSAGES/django.po

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3721,6 +3721,10 @@ msgstr "Moduulin suorittamiseen vaaditaan %(points)s pistettä."
37213721
msgid "CHANGES_ARE_POSSIBLE_IN_EXERCISES_BEFORE_MODULE_OPENING"
37223722
msgstr "Tehtäviin saattaa tulla muutoksia ennen kierroksen avautumista!"
37233723

3724+
#: exercise/templates/exercise/_user_results.html
3725+
msgid "CONVERT_SUBMISSION_BY_MODULE"
3726+
msgstr "Convert Late Submissions in Finnish"
3727+
37243728
#: exercise/templates/exercise/_user_results.html
37253729
#: exercise/templates/exercise/staff/_submitters_table.html
37263730
#: exercise/templates/exercise/staff/inspect_submission.html
@@ -3848,6 +3852,10 @@ msgstr "Palautuksen lisätiedot"
38483852
msgid "REGRADE_AUTOMATICALLY"
38493853
msgstr "Lähetä uudelleenarviointiin"
38503854

3855+
#: exercise/templates/exercise/staff/_assessment_panel.html
3856+
msgid "CONVERT_SUBMISSION"
3857+
msgstr "Convert Submission(FI)"
3858+
38513859
#: exercise/templates/exercise/staff/_assessment_panel.html
38523860
msgid "HELP"
38533861
msgstr "Ohjeet"

0 commit comments

Comments
 (0)