mirror of
https://github.com/sergeyyarkov/educt-server.git
synced 2026-10-11 10:19:20 +03:00
feat: detaching students list
This commit is contained in:
parent
9eaca99e3b
commit
e3575caab3
@ -10,6 +10,8 @@ import CourseService from 'App/Services/CourseService';
|
||||
* Validators
|
||||
*/
|
||||
import AddCourseToUserValidator from 'App/Validators/Course/AddCourseToUserValidator';
|
||||
import AttachStudentsValitator from 'App/Validators/Course/AttachStudentsValitator';
|
||||
import DetachStudentstValitator from 'App/Validators/Course/DetachStudentstValitator';
|
||||
import CreateCourseValidator from 'App/Validators/Course/CreateCourseValidator';
|
||||
import DelCourseFromUserValidator from 'App/Validators/Course/DelCourseFromUserValidator';
|
||||
import SetCourseStatusValidator from 'App/Validators/Course/SetCourseStatusValidator';
|
||||
@ -171,6 +173,21 @@ export default class CoursesController extends BaseController {
|
||||
return this.sendResponse(ctx, result.data, result.message, result.status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach list of students to course
|
||||
* POST /courses/:id/attach-student-list
|
||||
*/
|
||||
public async attachStudentList(ctx: HttpContextContract) {
|
||||
const payload = await ctx.request.validate(AttachStudentsValitator);
|
||||
const result = await this.courseService.attachStudentList(ctx.params.id, payload.students);
|
||||
|
||||
if (!result.success && result.error) {
|
||||
throw new Exception(result.message, result.status, result.error.code);
|
||||
}
|
||||
|
||||
return this.sendResponse(ctx, result.data, result.message, result.status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detach student from course
|
||||
* DELETE /courses/:id/detach-student
|
||||
@ -186,6 +203,21 @@ export default class CoursesController extends BaseController {
|
||||
return this.sendResponse(ctx, result.data, result.message, result.status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detach list of students to course
|
||||
* POST /courses/:id/detach-student-list
|
||||
*/
|
||||
public async detachStudentList(ctx: HttpContextContract) {
|
||||
const payload = await ctx.request.validate(DetachStudentstValitator);
|
||||
const result = await this.courseService.detachStudentList(ctx.params.id, payload.students);
|
||||
|
||||
if (!result.success && result.error) {
|
||||
throw new Exception(result.message, result.status, result.error.code);
|
||||
}
|
||||
|
||||
return this.sendResponse(ctx, result.data, result.message, result.status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch count of students of course
|
||||
* GET /courses/:id/students/count
|
||||
|
||||
@ -30,6 +30,11 @@ export default class UserRepository {
|
||||
return data;
|
||||
}
|
||||
|
||||
public async getByIds(ids: Array<string>): Promise<Array<User>> {
|
||||
const data = await this.User.query().preload('contacts').preload('roles').whereIn('id', ids);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user by column
|
||||
*
|
||||
|
||||
@ -420,6 +420,93 @@ export default class CourseService {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach list of students from course
|
||||
*
|
||||
* @param id Course id
|
||||
* @param ids Student ids
|
||||
* @returns Response
|
||||
*/
|
||||
public async attachStudentList(id: string | number, ids: Array<string>): Promise<IResponse> {
|
||||
const course = await this.courseRepository.getById(id);
|
||||
|
||||
if (!course) {
|
||||
return {
|
||||
success: false,
|
||||
status: HttpStatusEnum.NOT_FOUND,
|
||||
message: 'Course not found.',
|
||||
data: {},
|
||||
error: {
|
||||
code: 'E_NOT_FOUND',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const students = await this.userRepository.getByIds(ids);
|
||||
|
||||
try {
|
||||
await course.related('students').attach(students.map(s => s.id));
|
||||
} catch (error) {
|
||||
if (error.code === '23505') {
|
||||
return {
|
||||
success: false,
|
||||
status: HttpStatusEnum.BAD_REQUEST,
|
||||
message: 'Some student already attached to that course.',
|
||||
data: {},
|
||||
error: {
|
||||
code: 'E_BAD_REQUEST',
|
||||
},
|
||||
};
|
||||
}
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
status: HttpStatusEnum.OK,
|
||||
message: 'Student list successfully attached.',
|
||||
data: {},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Detach list of students from course
|
||||
*
|
||||
* @param id Course id
|
||||
* @param ids Student ids
|
||||
* @returns Response
|
||||
*/
|
||||
public async detachStudentList(id: string | number, ids: Array<string>): Promise<IResponse> {
|
||||
const course = await this.courseRepository.getById(id);
|
||||
|
||||
if (!course) {
|
||||
return {
|
||||
success: false,
|
||||
status: HttpStatusEnum.NOT_FOUND,
|
||||
message: 'Course not found.',
|
||||
data: {},
|
||||
error: {
|
||||
code: 'E_NOT_FOUND',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const students = await this.userRepository.getByIds(ids);
|
||||
|
||||
try {
|
||||
await course.related('students').detach(students.map(s => s.id));
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
status: HttpStatusEnum.OK,
|
||||
message: 'Student list successfully detached from course.',
|
||||
data: {},
|
||||
};
|
||||
}
|
||||
|
||||
public async detachUserCourse(id: string | number, studentId: string | number): Promise<IResponse> {
|
||||
const course = await this.courseRepository.getById(id);
|
||||
|
||||
|
||||
23
app/Validators/Course/AttachStudentsValitator.ts
Normal file
23
app/Validators/Course/AttachStudentsValitator.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { schema, rules } from '@ioc:Adonis/Core/Validator';
|
||||
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||
|
||||
export default class AttachStudentsValitator {
|
||||
constructor(protected ctx: HttpContextContract) {}
|
||||
|
||||
public schema = schema.create({
|
||||
students: schema.array().members(
|
||||
schema.string({}, [
|
||||
rules.exists({ table: 'users', column: 'id' }),
|
||||
rules.unique({
|
||||
table: 'users_courses',
|
||||
column: 'user_id',
|
||||
where: {
|
||||
course_id: this.ctx.params.id,
|
||||
},
|
||||
}),
|
||||
])
|
||||
),
|
||||
});
|
||||
|
||||
public messages = {};
|
||||
}
|
||||
12
app/Validators/Course/DetachStudentstValitator.ts
Normal file
12
app/Validators/Course/DetachStudentstValitator.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { schema, rules } from '@ioc:Adonis/Core/Validator';
|
||||
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||
|
||||
export default class DetachStudentstValitator {
|
||||
constructor(protected ctx: HttpContextContract) {}
|
||||
|
||||
public schema = schema.create({
|
||||
students: schema.array().members(schema.string({}, [rules.exists({ table: 'users', column: 'id' })])),
|
||||
});
|
||||
|
||||
public messages = {};
|
||||
}
|
||||
@ -30,6 +30,14 @@ Route.group(() => {
|
||||
.middleware('role:admin,teacher')
|
||||
.as('courses.attach-student');
|
||||
|
||||
Route.post('/:id/attach-student-list', 'Api/v1/CoursesController.attachStudentList')
|
||||
.middleware('role:admin,teacher')
|
||||
.as('courses.attach-student-list');
|
||||
|
||||
Route.patch('/:id/detach-student-list', 'Api/v1/CoursesController.detachStudentList')
|
||||
.middleware('role:admin,teacher')
|
||||
.as('courses.detach-student-list');
|
||||
|
||||
Route.delete('/:id/detach-student', 'Api/v1/CoursesController.detachStudent')
|
||||
.middleware('role:admin,teacher')
|
||||
.as('courses.detach-student');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user