Add EvaluationSummary
This commit is contained in:
parent
d9a6f2dd94
commit
2d6cee9f9f
|
|
@ -4,14 +4,9 @@ import EvaluationContainer from "@/pages/cockpit/assignmentEvaluationPage/Evalua
|
|||
import AssignmentSubmissionResponses from "@/pages/learningPath/learningContentPage/assignment/AssignmentSubmissionResponses.vue";
|
||||
import { useAssignmentStore } from "@/stores/assignmentStore";
|
||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
||||
import {
|
||||
Assignment,
|
||||
AssignmentCompletion,
|
||||
CourseSessionAssignmentDetails,
|
||||
CourseSessionUser,
|
||||
} from "@/types";
|
||||
import { Assignment, CourseSessionAssignmentDetails, CourseSessionUser } from "@/types";
|
||||
import log from "loglevel";
|
||||
import { onMounted, reactive } from "vue";
|
||||
import { computed, onMounted, reactive } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const props = defineProps<{
|
||||
|
|
@ -25,14 +20,12 @@ log.debug("AssignmentEvaluationPage created", props.assignmentId, props.userId);
|
|||
export interface StateInterface {
|
||||
assignment: Assignment | undefined;
|
||||
courseSessionAssignmentDetails: CourseSessionAssignmentDetails | undefined;
|
||||
completionData: AssignmentCompletion | undefined;
|
||||
assignmentUser: CourseSessionUser | undefined;
|
||||
}
|
||||
|
||||
const state: StateInterface = reactive({
|
||||
assignment: undefined,
|
||||
courseSessionAssignmentDetails: undefined,
|
||||
completionData: undefined,
|
||||
assignmentUser: undefined,
|
||||
});
|
||||
|
||||
|
|
@ -51,7 +44,7 @@ onMounted(async () => {
|
|||
|
||||
try {
|
||||
state.assignment = await assignmentStore.loadAssignment(props.assignmentId);
|
||||
state.completionData = await assignmentStore.loadAssignmentCompletion(
|
||||
await assignmentStore.loadAssignmentCompletion(
|
||||
props.assignmentId,
|
||||
courseSessionStore.currentCourseSession.id,
|
||||
props.userId
|
||||
|
|
@ -66,11 +59,13 @@ function exit() {
|
|||
path: `/course/${props.courseSlug}/cockpit/assignment`,
|
||||
});
|
||||
}
|
||||
|
||||
const assignmentCompletion = computed(() => assignmentStore.assignmentCompletion);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="absolute bottom-0 top-0 z-10 w-full bg-white">
|
||||
<div v-if="state.assignment && state.completionData" class="relative">
|
||||
<div v-if="state.assignment && assignmentCompletion" class="relative">
|
||||
<header
|
||||
class="relative flex h-12 w-full items-center justify-between border-b border-b-gray-400 bg-white px-4 lg:h-16 lg:px-8"
|
||||
>
|
||||
|
|
@ -102,14 +97,14 @@ function exit() {
|
|||
</div>
|
||||
<AssignmentSubmissionResponses
|
||||
:assignment="state.assignment"
|
||||
:assignment-completion-data="state.completionData?.completion_data"
|
||||
:assignment-completion-data="assignmentCompletion.completion_data"
|
||||
:allow-edit="false"
|
||||
></AssignmentSubmissionResponses>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-1/2 overflow-y-auto bg-gray-200">
|
||||
<EvaluationContainer
|
||||
:assignment-completion="state.completionData"
|
||||
:assignment-completion="assignmentCompletion"
|
||||
:assignment-user="state.assignmentUser"
|
||||
:assignment="state.assignment"
|
||||
></EvaluationContainer>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,19 @@
|
|||
<script setup lang="ts">
|
||||
import EvaluationIntro from "@/pages/cockpit/assignmentEvaluationPage/EvaluationIntro.vue";
|
||||
import EvaluationSummary from "@/pages/cockpit/assignmentEvaluationPage/EvaluationSummary.vue";
|
||||
import EvaluationTask from "@/pages/cockpit/assignmentEvaluationPage/EvaluationTask.vue";
|
||||
import { calcAssignmentLearningContents } from "@/services/assignmentService";
|
||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
||||
import { useLearningPathStore } from "@/stores/learningPath";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import type { Assignment, AssignmentCompletion, CourseSessionUser } from "@/types";
|
||||
import type {
|
||||
Assignment,
|
||||
AssignmentCompletion,
|
||||
AssignmentEvaluationTask,
|
||||
CourseSessionUser,
|
||||
} from "@/types";
|
||||
import dayjs from "dayjs";
|
||||
import { findIndex } from "lodash";
|
||||
import * as log from "loglevel";
|
||||
import { computed, reactive } from "vue";
|
||||
|
||||
|
|
@ -24,7 +31,7 @@ interface StateInterface {
|
|||
}
|
||||
|
||||
const state: StateInterface = reactive({
|
||||
pageIndex: 0,
|
||||
pageIndex: 6,
|
||||
});
|
||||
|
||||
const courseSessionStore = useCourseSessionsStore();
|
||||
|
|
@ -41,6 +48,15 @@ function nextPage() {
|
|||
state.pageIndex = Math.min(numTasks.value + 1, state.pageIndex + 1);
|
||||
}
|
||||
|
||||
function editTask(task: AssignmentEvaluationTask) {
|
||||
log.debug("editTask", task);
|
||||
const taskIndex =
|
||||
findIndex(props.assignment.evaluation_tasks, {
|
||||
id: task.id,
|
||||
}) ?? 0;
|
||||
state.pageIndex = taskIndex + 1;
|
||||
}
|
||||
|
||||
function findAssignmentDetail() {
|
||||
const learningPathStore = useLearningPathStore();
|
||||
const userStore = useUserStore();
|
||||
|
|
@ -88,10 +104,18 @@ const dueDate = computed(() =>
|
|||
:assignment="props.assignment"
|
||||
:task-index="state.pageIndex - 1"
|
||||
/>
|
||||
<EvaluationSummary
|
||||
v-else
|
||||
:assignment-user="props.assignmentUser"
|
||||
:assignment="props.assignment"
|
||||
:assignment-completion="props.assignmentCompletion"
|
||||
:due-date="dueDate"
|
||||
@edit-task="editTask($event)"
|
||||
></EvaluationSummary>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<nav class="sticky bottom-0 border-t p-6">
|
||||
<nav class="sticky bottom-0 border-t bg-gray-200 p-6" v-if="state.pageIndex > 0">
|
||||
<div class="relative flex flex-row place-content-end">
|
||||
<button
|
||||
v-if="true"
|
||||
|
|
|
|||
|
|
@ -51,9 +51,8 @@ async function startEvaluation() {
|
|||
</p>
|
||||
|
||||
<p class="my-4">
|
||||
Auf Grund dieser Bewertung wird eine Gesamtpunktzahl und die daraus reslutierende
|
||||
Note berechnet. Genauere Informationen dazu findest du im folgenden
|
||||
Beurteilungsinstrument:
|
||||
Die Gesamtpunktzahl und die daruas resultierende Note wird auf Grund des
|
||||
hinterlegeten Beurteilungsinstrument berechnet. Willst du mehr dazu erfahren:
|
||||
</p>
|
||||
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,131 @@
|
|||
<script setup lang="ts">
|
||||
import {
|
||||
maxAssignmentPoints,
|
||||
pointsToGrade,
|
||||
userAssignmentPoints,
|
||||
} from "@/services/assignmentService";
|
||||
import { useAssignmentStore } from "@/stores/assignmentStore";
|
||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
||||
import type { Assignment, AssignmentEvaluationTask, CourseSessionUser } from "@/types";
|
||||
import { AssignmentCompletion } from "@/types";
|
||||
import { Dayjs } from "dayjs";
|
||||
import * as log from "loglevel";
|
||||
import { computed } from "vue";
|
||||
|
||||
const props = defineProps<{
|
||||
assignmentUser: CourseSessionUser;
|
||||
assignment: Assignment;
|
||||
assignmentCompletion: AssignmentCompletion;
|
||||
dueDate?: Dayjs;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits(["submitEvaluation", "editTask"]);
|
||||
|
||||
log.debug("EvaluationSummary setup");
|
||||
|
||||
const courseSessionStore = useCourseSessionsStore();
|
||||
const assignmentStore = useAssignmentStore();
|
||||
|
||||
async function submitEvaluation() {
|
||||
log.debug("submitEvaluation");
|
||||
await assignmentStore.evaluateAssignmentCompletion({
|
||||
assignment_user_id: Number(props.assignmentUser.user_id),
|
||||
assignment_id: props.assignment.id,
|
||||
course_session_id: courseSessionStore.currentCourseSession!.id,
|
||||
completion_data: {},
|
||||
completion_status: "evaluation_submitted",
|
||||
});
|
||||
emit("submitEvaluation");
|
||||
}
|
||||
|
||||
function subTaskByPoints(task: AssignmentEvaluationTask, points = 0) {
|
||||
return task.value.sub_tasks.find((subTask) => subTask.points === points);
|
||||
}
|
||||
|
||||
function evaluationForTask(task: AssignmentEvaluationTask) {
|
||||
const expertData = props.assignmentCompletion.completion_data[task.id]?.expert_data;
|
||||
if (task.id === "0e701176-a817-427b-b8ea-a7cd59f212cb") {
|
||||
console.log("######################## ", expertData.text, expertData.points);
|
||||
}
|
||||
if (!expertData) {
|
||||
return {
|
||||
points: 0,
|
||||
text: "",
|
||||
};
|
||||
}
|
||||
|
||||
return expertData;
|
||||
}
|
||||
|
||||
const maxPoints = computed(() => maxAssignmentPoints(props.assignment));
|
||||
const userPoints = computed(() =>
|
||||
userAssignmentPoints(props.assignment, props.assignmentCompletion)
|
||||
);
|
||||
const grade = computed(() => pointsToGrade(userPoints.value, maxPoints.value));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h3>Bewertung Freigabe</h3>
|
||||
|
||||
<section class="mb-6 border p-6">
|
||||
<div class="text-lg font-bold">Note: {{ grade }}</div>
|
||||
<div>Gesamtpunktezahl {{ userPoints }} / {{ maxPoints }}</div>
|
||||
|
||||
<p class="my-4">
|
||||
Die Gesamtpunktzahl und die daraus resultierende Note wird auf Grund des
|
||||
hinterlegeten Beurteilungsinstrument berechnet. Willst du mehr dazu erfahren:
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<button class="btn-primary" @click="submitEvaluation()">
|
||||
Bewertung freigeben
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div v-for="(task, index) in props.assignment.evaluation_tasks" :key="task.id">
|
||||
<article class="border-t py-4">
|
||||
<div class="flex flex-row justify-between">
|
||||
<div class="mb-4">
|
||||
Bewertungskriterium {{ index + 1 }}: {{ task.value.title }}
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
class="link pl-2text-sm whitespace-nowrap"
|
||||
@click="emit('editTask', task)"
|
||||
>
|
||||
{{ $t("assignment.edit") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="default-wagtail-rich-text mb-2 font-bold">
|
||||
{{ task.value.description }}
|
||||
</div>
|
||||
|
||||
<section class="mb-4">
|
||||
<div
|
||||
v-html="subTaskByPoints(task, evaluationForTask(task).points).title"
|
||||
></div>
|
||||
<p
|
||||
class="default-wagtail-rich-text"
|
||||
v-html="subTaskByPoints(task, evaluationForTask(task).points).description"
|
||||
></p>
|
||||
<div class="text-sm text-gray-800">
|
||||
{{ evaluationForTask(task).points }} Punkte
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div>
|
||||
<span class="font-bold">Begründung:</span>
|
||||
{{ evaluationForTask(task).text }}
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
@ -7,7 +7,6 @@ import { useAssignmentStore } from "@/stores/assignmentStore";
|
|||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
||||
import type {
|
||||
Assignment,
|
||||
AssignmentCompletion,
|
||||
AssignmentTask,
|
||||
CourseSessionAssignmentDetails,
|
||||
LearningContent,
|
||||
|
|
@ -24,14 +23,12 @@ const assignmentStore = useAssignmentStore();
|
|||
interface State {
|
||||
assignment: Assignment | undefined;
|
||||
courseSessionAssignmentDetails: CourseSessionAssignmentDetails | undefined;
|
||||
assignmentCompletion: AssignmentCompletion | undefined;
|
||||
pageIndex: number;
|
||||
}
|
||||
|
||||
const state: State = reactive({
|
||||
assignment: undefined,
|
||||
courseSessionAssignmentDetails: undefined,
|
||||
assignmentCompletion: undefined,
|
||||
// 0 = introduction, 1 - n = tasks, n+1 = submission
|
||||
pageIndex: 0,
|
||||
});
|
||||
|
|
@ -51,7 +48,7 @@ onMounted(async () => {
|
|||
state.courseSessionAssignmentDetails = courseSessionsStore.findAssignmentDetails(
|
||||
props.learningContent.id
|
||||
);
|
||||
state.assignmentCompletion = await assignmentStore.loadAssignmentCompletion(
|
||||
await assignmentStore.loadAssignmentCompletion(
|
||||
props.assignmentId,
|
||||
courseSessionId.value
|
||||
);
|
||||
|
|
@ -78,6 +75,7 @@ const currentTask = computed(() => {
|
|||
}
|
||||
return undefined;
|
||||
});
|
||||
const assignmentCompletion = computed(() => assignmentStore.assignmentCompletion);
|
||||
|
||||
const handleBack = () => {
|
||||
log.debug("handleBack");
|
||||
|
|
@ -115,7 +113,7 @@ const getTitle = () => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="state.assignment && state.assignmentCompletion"></div>
|
||||
<div v-if="state.assignment && assignmentCompletion"></div>
|
||||
<LearningContentMultiLayout
|
||||
:current-step="state.pageIndex"
|
||||
:subtitle="state.assignment?.title ?? ''"
|
||||
|
|
@ -147,7 +145,7 @@ const getTitle = () => {
|
|||
v-if="state.pageIndex + 1 === numPages && state.assignment && courseSessionId"
|
||||
:due-date="dueDate"
|
||||
:assignment="state.assignment!"
|
||||
:assignment-completion-data="state.assignmentCompletion?.completion_data ?? {}"
|
||||
:assignment-completion-data="assignmentCompletion?.completion_data ?? {}"
|
||||
:course-session-id="courseSessionId!"
|
||||
@edit-task="jumpToTask($event)"
|
||||
></AssignmentSubmissionView>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
import { describe, it } from "vitest";
|
||||
import { pointsToGrade } from "../assignmentService";
|
||||
|
||||
describe("assignmentService", () => {
|
||||
it("pointsToGrade", () => {
|
||||
expect(pointsToGrade(24, 24)).toBe(6);
|
||||
expect(pointsToGrade(23, 24)).toBe(6);
|
||||
expect(pointsToGrade(22, 24)).toBe(5.5);
|
||||
expect(pointsToGrade(21, 24)).toBe(5.5);
|
||||
expect(pointsToGrade(20, 24)).toBe(5);
|
||||
expect(pointsToGrade(19, 24)).toBe(5);
|
||||
expect(pointsToGrade(18, 24)).toBe(5);
|
||||
expect(pointsToGrade(17, 24)).toBe(4.5);
|
||||
expect(pointsToGrade(16, 24)).toBe(4.5);
|
||||
expect(pointsToGrade(15, 24)).toBe(4);
|
||||
expect(pointsToGrade(14, 24)).toBe(4);
|
||||
expect(pointsToGrade(13, 24)).toBe(3.5);
|
||||
expect(pointsToGrade(12, 24)).toBe(3.5);
|
||||
expect(pointsToGrade(11, 24)).toBe(3.5);
|
||||
expect(pointsToGrade(10, 24)).toBe(3);
|
||||
expect(pointsToGrade(9, 24)).toBe(3);
|
||||
expect(pointsToGrade(8, 24)).toBe(2.5);
|
||||
expect(pointsToGrade(7, 24)).toBe(2.5);
|
||||
expect(pointsToGrade(6, 24)).toBe(2.5);
|
||||
expect(pointsToGrade(5, 24)).toBe(2);
|
||||
expect(pointsToGrade(4, 24)).toBe(2);
|
||||
expect(pointsToGrade(3, 24)).toBe(1.5);
|
||||
expect(pointsToGrade(2, 24)).toBe(1.5);
|
||||
expect(pointsToGrade(1, 24)).toBe(1);
|
||||
expect(pointsToGrade(0, 24)).toBe(1);
|
||||
});
|
||||
});
|
||||
|
|
@ -3,10 +3,14 @@ import { itGet } from "@/fetchHelpers";
|
|||
import type { LearningPath } from "@/services/learningPath";
|
||||
import { useCockpitStore } from "@/stores/cockpit";
|
||||
import type {
|
||||
Assignment,
|
||||
AssignmentCompletion,
|
||||
AssignmentCompletionStatus,
|
||||
CourseSessionUser,
|
||||
LearningContent,
|
||||
} from "@/types";
|
||||
import { sum } from "d3";
|
||||
import pick from "lodash/pick";
|
||||
|
||||
export interface AssignmentLearningContent extends LearningContent {
|
||||
assignmentId: number;
|
||||
|
|
@ -59,10 +63,42 @@ export function calcUserAssignmentCompletionStatus(
|
|||
userStatus = userAssignmentStatus.completion_status;
|
||||
}
|
||||
let progressStatus: StatusCountKey = "unknown";
|
||||
if (["submitted", "evaluation_in_progress", "evaluated"].includes(userStatus)) {
|
||||
if (
|
||||
["submitted", "evaluation_in_progress", "evaluation_submitted"].includes(
|
||||
userStatus
|
||||
)
|
||||
) {
|
||||
progressStatus = "success";
|
||||
}
|
||||
|
||||
return { userId: u.user_id, userStatus, progressStatus };
|
||||
});
|
||||
}
|
||||
|
||||
export function maxAssignmentPoints(assignment: Assignment) {
|
||||
return sum(assignment.evaluation_tasks.map((task) => task.value.max_points));
|
||||
}
|
||||
|
||||
export function userAssignmentPoints(
|
||||
assignment: Assignment,
|
||||
assignmentCompletion: AssignmentCompletion
|
||||
) {
|
||||
const evaluationTaskIds = assignment.evaluation_tasks.map((task) => {
|
||||
return task.id;
|
||||
});
|
||||
|
||||
return sum(
|
||||
Object.entries(pick(assignmentCompletion.completion_data, evaluationTaskIds)).map(
|
||||
(entry) => {
|
||||
return entry[1]?.expert_data?.points ?? 0;
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function pointsToGrade(points: number, maxPoints: number) {
|
||||
// round to half-grades
|
||||
const grade = Math.round((points / maxPoints) * 10);
|
||||
const halfGrade = grade / 2;
|
||||
return Math.min(halfGrade, 5) + 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -509,7 +509,7 @@ export type AssignmentCompletionStatus =
|
|||
| "in_progress"
|
||||
| "submitted"
|
||||
| "evaluation_in_progress"
|
||||
| "evaluated";
|
||||
| "evaluation_submitted";
|
||||
|
||||
export interface UserDataText {
|
||||
text: string;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ from django.db import migrations, models
|
|||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
|
|
@ -261,7 +260,7 @@ class Migration(migrations.Migration):
|
|||
(1, "in_progress"),
|
||||
(2, "submitted"),
|
||||
(3, "evaluation_in_progress"),
|
||||
(4, "evaluated"),
|
||||
(4, "evaluation_submitted"),
|
||||
],
|
||||
default="in_progress",
|
||||
max_length=255,
|
||||
|
|
@ -337,7 +336,7 @@ class Migration(migrations.Migration):
|
|||
(1, "in_progress"),
|
||||
(2, "submitted"),
|
||||
(3, "evaluation_in_progress"),
|
||||
(4, "evaluated"),
|
||||
(4, "evaluation_submitted"),
|
||||
],
|
||||
default="in_progress",
|
||||
max_length=255,
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ class Assignment(CourseBasePage):
|
|||
|
||||
AssignmentCompletionStatus = Enum(
|
||||
"AssignmentCompletionStatus",
|
||||
["in_progress", "submitted", "evaluation_in_progress", "evaluated"],
|
||||
["in_progress", "submitted", "evaluation_in_progress", "evaluation_submitted"],
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -262,7 +262,7 @@ class AssignmentCompletion(models.Model):
|
|||
|
||||
class AssignmentCompletionAuditLog(models.Model):
|
||||
"""
|
||||
This model is used to store the "submitted" and "evaluated" data separately
|
||||
This model is used to store the "submitted" and "evaluation_submitted" data separately
|
||||
"""
|
||||
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ def update_assignment_completion(
|
|||
},
|
||||
}
|
||||
:param copy_task_data: if true, the task data will be copied to the completion data
|
||||
used for "submitted" and "evaluated" status, so that we don't lose the question
|
||||
used for "submitted" and "evaluation_submitted" status, so that we don't lose the question
|
||||
context
|
||||
:return: AssignmentCompletion
|
||||
"""
|
||||
|
|
@ -59,31 +59,33 @@ def update_assignment_completion(
|
|||
if ac.completion_status in [
|
||||
"submitted",
|
||||
"evaluation_in_progress",
|
||||
"evaluated",
|
||||
"evaluation_submitted",
|
||||
]:
|
||||
raise serializers.ValidationError(
|
||||
{
|
||||
"completion_status": f"Cannot update completion status from {ac.completion_status} to submitted"
|
||||
}
|
||||
)
|
||||
elif completion_status == "evaluated":
|
||||
if ac.completion_status == "evaluated":
|
||||
elif completion_status == "evaluation_submitted":
|
||||
if ac.completion_status == "evaluation_submitted":
|
||||
raise serializers.ValidationError(
|
||||
{
|
||||
"completion_status": f"Cannot update completion status from {ac.completion_status} to evaluated"
|
||||
"completion_status": f"Cannot update completion status from {ac.completion_status} to evaluation_submitted"
|
||||
}
|
||||
)
|
||||
|
||||
if completion_status in ["evaluated", "evaluation_in_progress"]:
|
||||
if completion_status in ["evaluation_submitted", "evaluation_in_progress"]:
|
||||
if evaluation_user is None:
|
||||
raise serializers.ValidationError(
|
||||
{"evaluation_user": "evaluation_user is required for evaluated status"}
|
||||
{
|
||||
"evaluation_user": "evaluation_user is required for evaluation_submitted status"
|
||||
}
|
||||
)
|
||||
ac.evaluation_user = evaluation_user
|
||||
|
||||
if completion_status == "submitted":
|
||||
ac.submitted_at = timezone.now()
|
||||
elif completion_status == "evaluated":
|
||||
elif completion_status == "evaluation_submitted":
|
||||
ac.evaluated_at = timezone.now()
|
||||
|
||||
ac.completion_status = completion_status
|
||||
|
|
@ -105,7 +107,7 @@ def update_assignment_completion(
|
|||
|
||||
ac.save()
|
||||
|
||||
if completion_status in ["evaluated", "submitted"]:
|
||||
if completion_status in ["evaluation_submitted", "submitted"]:
|
||||
acl = AssignmentCompletionAuditLog.objects.create(
|
||||
assignment_user=assignment_user,
|
||||
assignment=assignment,
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ class AssignmentApiTestCase(APITestCase):
|
|||
"assignment_id": self.assignment.id,
|
||||
"assignment_user_id": self.student.id,
|
||||
"course_session_id": self.cs.id,
|
||||
"completion_status": "evaluated",
|
||||
"completion_status": "evaluation_submitted",
|
||||
"completion_data": {
|
||||
user_text_input["id"]: {
|
||||
"expert_data": {"points": 1, "comment": "Gut gemacht!"}
|
||||
|
|
@ -245,7 +245,7 @@ class AssignmentApiTestCase(APITestCase):
|
|||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response_json["assignment_user"], self.student.id)
|
||||
self.assertEqual(response_json["assignment"], self.assignment.id)
|
||||
self.assertEqual(response_json["completion_status"], "evaluated")
|
||||
self.assertEqual(response_json["completion_status"], "evaluation_submitted")
|
||||
self.assertDictEqual(
|
||||
response_json["completion_data"],
|
||||
{
|
||||
|
|
@ -261,7 +261,7 @@ class AssignmentApiTestCase(APITestCase):
|
|||
course_session_id=self.cs.id,
|
||||
assignment_id=self.assignment.id,
|
||||
)
|
||||
self.assertEqual(db_entry.completion_status, "evaluated")
|
||||
self.assertEqual(db_entry.completion_status, "evaluation_submitted")
|
||||
self.assertDictEqual(
|
||||
db_entry.completion_data,
|
||||
{
|
||||
|
|
@ -272,12 +272,12 @@ class AssignmentApiTestCase(APITestCase):
|
|||
},
|
||||
)
|
||||
|
||||
# `evaluated` will create a new AssignmentCompletionAuditLog
|
||||
# `evaluation_submitted` will create a new AssignmentCompletionAuditLog
|
||||
acl = AssignmentCompletionAuditLog.objects.get(
|
||||
assignment_user=self.student,
|
||||
course_session_id=self.cs.id,
|
||||
assignment_id=self.assignment.id,
|
||||
completion_status="evaluated",
|
||||
completion_status="evaluation_submitted",
|
||||
)
|
||||
self.maxDiff = None
|
||||
self.assertDictEqual(
|
||||
|
|
|
|||
Loading…
Reference in New Issue