diff --git a/api/source/api_modules/classroom_compliance/api_entry.d b/api/source/api_modules/classroom_compliance/api_entry.d index 18c8860..4c85599 100644 --- a/api/source/api_modules/classroom_compliance/api_entry.d +++ b/api/source/api_modules/classroom_compliance/api_entry.d @@ -44,6 +44,7 @@ struct EntriesTableEntry { struct EntriesTableStudentResponse { ulong id; + ulong classId; string name; ushort deskNumber; bool removed; @@ -53,6 +54,7 @@ struct EntriesTableStudentResponse { JSONValue toJsonObj() const { JSONValue obj = JSONValue.emptyObject; obj.object["id"] = JSONValue(id); + obj.object["classId"] = JSONValue(classId); obj.object["name"] = JSONValue(name); obj.object["deskNumber"] = JSONValue(deskNumber); obj.object["removed"] = JSONValue(removed); @@ -107,6 +109,7 @@ void getEntries(ref HttpRequestContext ctx) { ); EntriesTableStudentResponse[] studentObjects = students.map!(s => EntriesTableStudentResponse( s.id, + s.classId, s.name, s.deskNumber, s.removed, @@ -126,7 +129,8 @@ void getEntries(ref HttpRequestContext ctx) { student.id, student.name, student.desk_number, - student.removed + student.removed, + student.class_id FROM classroom_compliance_entry entry LEFT JOIN classroom_compliance_student student ON student.id = entry.student_id @@ -166,7 +170,7 @@ void getEntries(ref HttpRequestContext ctx) { ClassroomComplianceStudent student = ClassroomComplianceStudent( r.getUlong(8), r.getString(9), - cls.id, + r.getUlong(12), r.getUshort(10), r.getBoolean(11) ); @@ -187,6 +191,7 @@ void getEntries(ref HttpRequestContext ctx) { // Their data should still be shown, so add the student here. studentObjects ~= EntriesTableStudentResponse( student.id, + student.classId, student.name, student.deskNumber, student.removed, diff --git a/api/source/api_modules/classroom_compliance/api_student.d b/api/source/api_modules/classroom_compliance/api_student.d index c8b3930..e30fa3b 100644 --- a/api/source/api_modules/classroom_compliance/api_student.d +++ b/api/source/api_modules/classroom_compliance/api_student.d @@ -218,6 +218,7 @@ void getStudentOverview(ref HttpRequestContext ctx) { void moveStudentToOtherClass(ref HttpRequestContext ctx) { Connection conn = getDb(); + conn.setAutoCommit(false); User user = getUserOrThrow(ctx, conn); auto student = getStudentOrThrow(ctx, conn, user); struct Payload { @@ -238,11 +239,24 @@ void moveStudentToOtherClass(ref HttpRequestContext ctx) { ctx.response.writeBodyString("Invalid class was selected."); return; } + // Check that the new class doesn't already have a student with the same name. + bool studentNameExistsInNewClass = recordExists( + conn, + "SELECT id FROM classroom_compliance_student WHERE class_id = ? AND name = ?", + payload.classId, + student.name + ); + if (studentNameExistsInNewClass) { + ctx.response.status = HttpStatus.BAD_REQUEST; + ctx.response.writeBodyString("A student in the selected class has the same name as this one."); + return; + } // All good, so update the student's class to the desired one, and reset their desk. update( conn, "UPDATE classroom_compliance_student SET class_id = ?, desk_number = 0 WHERE id = ?", payload.classId, student.id ); + conn.commit(); // We just return 200 OK, no response body. } diff --git a/app/src/api/classroom_compliance.ts b/app/src/api/classroom_compliance.ts index 936de2e..51163b3 100644 --- a/app/src/api/classroom_compliance.ts +++ b/app/src/api/classroom_compliance.ts @@ -57,6 +57,7 @@ export function getDefaultEntry(dateStr: string): Entry { export interface EntriesResponseStudent { id: number + classId: number name: string deskNumber: number removed: boolean diff --git a/app/src/apps/classroom_compliance/GuideView.vue b/app/src/apps/classroom_compliance/GuideView.vue new file mode 100644 index 0000000..a2f0434 --- /dev/null +++ b/app/src/apps/classroom_compliance/GuideView.vue @@ -0,0 +1,158 @@ + + + + diff --git a/app/src/apps/classroom_compliance/MainView.vue b/app/src/apps/classroom_compliance/MainView.vue index 084409a..dcdaf4e 100644 --- a/app/src/apps/classroom_compliance/MainView.vue +++ b/app/src/apps/classroom_compliance/MainView.vue @@ -1,5 +1,5 @@ diff --git a/app/src/apps/classroom_compliance/router.ts b/app/src/apps/classroom_compliance/router.ts index e2ee707..e2b6bb9 100644 --- a/app/src/apps/classroom_compliance/router.ts +++ b/app/src/apps/classroom_compliance/router.ts @@ -35,6 +35,10 @@ export function createClassroomComplianceRoutes(): RouteRecordRaw { component: () => import('@/apps/classroom_compliance/ImportStudentsView.vue'), props: true, }, + { + path: 'guide', + component: () => import('@/apps/classroom_compliance/GuideView.vue'), + }, ], } }