Merge pull request #212 from SELab-2/fix/208-add-students-not-in-class
fix: Student mag niet toegevoegd worden aan een groep wanneer die niet in een klas zit
This commit is contained in:
		
						commit
						b6b87c81cd
					
				
					 4 changed files with 30 additions and 13 deletions
				
			
		|  | @ -3,8 +3,6 @@ import { createGroup, deleteGroup, getAllGroups, getGroup, getGroupSubmissions, | ||||||
| import { GroupDTO } from '@dwengo-1/common/interfaces/group'; | import { GroupDTO } from '@dwengo-1/common/interfaces/group'; | ||||||
| import { requireFields } from './error-helper.js'; | import { requireFields } from './error-helper.js'; | ||||||
| import { BadRequestException } from '../exceptions/bad-request-exception.js'; | import { BadRequestException } from '../exceptions/bad-request-exception.js'; | ||||||
| import { EntityDTO } from '@mikro-orm/core'; |  | ||||||
| import { Group } from '../entities/assignments/group.entity.js'; |  | ||||||
| 
 | 
 | ||||||
| function checkGroupFields(classId: string, assignmentId: number, groupId: number): void { | function checkGroupFields(classId: string, assignmentId: number, groupId: number): void { | ||||||
|     requireFields({ classId, assignmentId, groupId }); |     requireFields({ classId, assignmentId, groupId }); | ||||||
|  | @ -35,7 +33,11 @@ export async function putGroupHandler(req: Request, res: Response): Promise<void | ||||||
|     const groupId = parseInt(req.params.groupid); |     const groupId = parseInt(req.params.groupid); | ||||||
|     checkGroupFields(classId, assignmentId, groupId); |     checkGroupFields(classId, assignmentId, groupId); | ||||||
| 
 | 
 | ||||||
|     const group = await putGroup(classId, assignmentId, groupId, req.body as Partial<EntityDTO<Group>>); |     // Only members field can be changed
 | ||||||
|  |     const members = req.body.members; | ||||||
|  |     requireFields({ members }); | ||||||
|  | 
 | ||||||
|  |     const group = await putGroup(classId, assignmentId, groupId, { members } as Partial<GroupDTO>); | ||||||
| 
 | 
 | ||||||
|     res.json({ group }); |     res.json({ group }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -7,8 +7,17 @@ import { GroupDTO, GroupDTOId } from '@dwengo-1/common/interfaces/group'; | ||||||
| import { SubmissionDTO, SubmissionDTOId } from '@dwengo-1/common/interfaces/submission'; | import { SubmissionDTO, SubmissionDTOId } from '@dwengo-1/common/interfaces/submission'; | ||||||
| import { fetchAssignment } from './assignments.js'; | import { fetchAssignment } from './assignments.js'; | ||||||
| import { NotFoundException } from '../exceptions/not-found-exception.js'; | import { NotFoundException } from '../exceptions/not-found-exception.js'; | ||||||
| import { putObject } from './service-helper.js'; |  | ||||||
| import { fetchStudents } from './students.js'; | import { fetchStudents } from './students.js'; | ||||||
|  | import { fetchClass } from './classes.js'; | ||||||
|  | import { BadRequestException } from '../exceptions/bad-request-exception.js'; | ||||||
|  | import { Student } from '../entities/users/student.entity.js'; | ||||||
|  | import { Class } from '../entities/classes/class.entity.js'; | ||||||
|  | 
 | ||||||
|  | async function assertMembersInClass(members: Student[], cls: Class): Promise<void> { | ||||||
|  |     if (!members.every((student) => cls.students.contains(student))) { | ||||||
|  |         throw new BadRequestException('Student does not belong to class'); | ||||||
|  |     } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| export async function fetchGroup(classId: string, assignmentNumber: number, groupNumber: number): Promise<Group> { | export async function fetchGroup(classId: string, assignmentNumber: number, groupNumber: number): Promise<Group> { | ||||||
|     const assignment = await fetchAssignment(classId, assignmentNumber); |     const assignment = await fetchAssignment(classId, assignmentNumber); | ||||||
|  | @ -28,15 +37,18 @@ export async function getGroup(classId: string, assignmentNumber: number, groupN | ||||||
|     return mapToGroupDTO(group, group.assignment.within); |     return mapToGroupDTO(group, group.assignment.within); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function putGroup( | export async function putGroup(classId: string, assignmentNumber: number, groupNumber: number, groupData: Partial<GroupDTO>): Promise<GroupDTO> { | ||||||
|     classId: string, |  | ||||||
|     assignmentNumber: number, |  | ||||||
|     groupNumber: number, |  | ||||||
|     groupData: Partial<EntityDTO<Group>> |  | ||||||
| ): Promise<GroupDTO> { |  | ||||||
|     const group = await fetchGroup(classId, assignmentNumber, groupNumber); |     const group = await fetchGroup(classId, assignmentNumber, groupNumber); | ||||||
| 
 | 
 | ||||||
|     await putObject<Group>(group, groupData, getGroupRepository()); |     const memberUsernames = groupData.members as string[]; | ||||||
|  |     const members = await fetchStudents(memberUsernames); | ||||||
|  | 
 | ||||||
|  |     const cls = await fetchClass(classId); | ||||||
|  |     await assertMembersInClass(members, cls); | ||||||
|  | 
 | ||||||
|  |     const groupRepository = getGroupRepository(); | ||||||
|  |     groupRepository.assign(group, { members } as Partial<EntityDTO<Group>>); | ||||||
|  |     await groupRepository.getEntityManager().persistAndFlush(group); | ||||||
| 
 | 
 | ||||||
|     return mapToGroupDTO(group, group.assignment.within); |     return mapToGroupDTO(group, group.assignment.within); | ||||||
| } | } | ||||||
|  | @ -63,6 +75,9 @@ export async function createGroup(groupData: GroupDTO, classid: string, assignme | ||||||
|     const memberUsernames = (groupData.members as string[]) || []; |     const memberUsernames = (groupData.members as string[]) || []; | ||||||
|     const members = await fetchStudents(memberUsernames); |     const members = await fetchStudents(memberUsernames); | ||||||
| 
 | 
 | ||||||
|  |     const cls = await fetchClass(classid); | ||||||
|  |     await assertMembersInClass(members, cls); | ||||||
|  | 
 | ||||||
|     const assignment = await fetchAssignment(classid, assignmentNumber); |     const assignment = await fetchAssignment(classid, assignmentNumber); | ||||||
| 
 | 
 | ||||||
|     const groupRepository = getGroupRepository(); |     const groupRepository = getGroupRepository(); | ||||||
|  |  | ||||||
|  | @ -61,7 +61,7 @@ export function makeTestGroups(em: EntityManager, students: Student[], assignmen | ||||||
|      */ |      */ | ||||||
|     group1ConditionalLearningPath = em.create(Group, { |     group1ConditionalLearningPath = em.create(Group, { | ||||||
|         assignment: getConditionalPathAssignment(), |         assignment: getConditionalPathAssignment(), | ||||||
|         groupNumber: 1, |         groupNumber: 21005, | ||||||
|         members: [getTestleerling1()], |         members: [getTestleerling1()], | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -11,7 +11,7 @@ | ||||||
|     const { t, locale } = useI18n(); |     const { t, locale } = useI18n(); | ||||||
| 
 | 
 | ||||||
|     const role = auth.authState.activeRole; |     const role = auth.authState.activeRole; | ||||||
|     const router = useRouter(); |     const _router = useRouter(); // Zonder '_' gaf dit een linter error voor unused variable | ||||||
| 
 | 
 | ||||||
|     const name: string = auth.authState.user!.profile.name!; |     const name: string = auth.authState.user!.profile.name!; | ||||||
|     const initials: string = name |     const initials: string = name | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 Adriaan J.
						Adriaan J.