Skip to content

Commit

Permalink
CPTs
Browse files Browse the repository at this point in the history
  • Loading branch information
ngoerlitz committed Nov 21, 2023
1 parent 3748ac2 commit dfa6302
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 40 deletions.
2 changes: 2 additions & 0 deletions src/Router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ router.use(
r.use(
"/cpt",
routerGroup((r: Router) => {
r.post("/", CPTAdminController.createCPT);
r.get("/open", CPTAdminController.getOpen);
r.get("/available", CPTAdminController.getAvailable);
})
);
Expand Down
130 changes: 130 additions & 0 deletions src/controllers/cpt/CPTAdminController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,59 @@ import { NextFunction, Request, Response } from "express";
import { TrainingSession } from "../../models/TrainingSession";
import { Op } from "sequelize";
import dayjs from "dayjs";
import { TrainingRequest } from "../../models/TrainingRequest";
import _CPTAdminValidator from "./_CPTAdmin.validator";
import { UsersBelongsToCourses } from "../../models/through/UsersBelongsToCourses";
import { HttpStatusCode } from "axios";
import { generateUUID } from "../../utility/UUID";
import { TrainingSessionBelongsToUsers } from "../../models/through/TrainingSessionBelongsToUsers";
import { sequelize } from "../../core/Sequelize";
import { User } from "../../models/User";
import { ValidationException } from "../../exceptions/ValidationException";

/**
* Returns a list of currently scheduled CPTs without a mentor (Beisitzer) assigned to it
* @param request
* @param response
* @param next
*/
async function getOpen(request: Request, response: Response, next: NextFunction) {
// TODO: Limit response to mentor groups able to mentor this
// from the course, since we have this relationship anyway

try {
let requests = await TrainingSession.findAll({
where: {
mentor_id: null,
date: {
[Op.gt]: dayjs.utc().toDate(),
},
},
include: [
TrainingSession.associations.users,
TrainingSession.associations.training_station,
TrainingSession.associations.training_type,
TrainingSession.associations.mentor,
TrainingSession.associations.cpt_examiner,
],
});

requests = requests.filter(r => {
return r.training_type?.type == "cpt";
});

response.send(requests);
} catch (e) {
next(e);
}
}

/**
* Returns a list of Training Requests of type CPT, where no examiner is present yet
* @param request
* @param response
* @param next
*/
async function getAvailable(request: Request, response: Response, next: NextFunction) {
try {
let availableCPTs = await TrainingSession.findAll({
Expand Down Expand Up @@ -30,6 +82,84 @@ async function getAvailable(request: Request, response: Response, next: NextFunc
}
}

async function createCPT(request: Request, response: Response, next: NextFunction) {
const t = await sequelize.transaction();

try {
const body = request.body as { trainee_id: string; course_id: string; date: string; training_type_id: string; training_station_id: string };
_CPTAdminValidator.validateCreateRequest(body);

// Check if user already has CPT planned!
const user = await User.findOne({
where: {
id: body.trainee_id,
},
include: [
{
association: User.associations.training_sessions,
include: [TrainingSession.associations.training_type],
},
],
});

for (const sess of user?.training_sessions ?? []) {
if (sess.training_type?.type == "cpt" && sess.completed == false) {
throw new ValidationException({ invalid: true, message: ["The user already has a CPT planned"] });
}
}

// Check if the user is in the course
const userInCourse = await UsersBelongsToCourses.findOne({
where: {
user_id: body.trainee_id,
course_id: body.course_id,
},
});

if (userInCourse == null || user == null) {
// User is not in course
response.sendStatus(HttpStatusCode.BadRequest);
return;
}

const session = await TrainingSession.create(
{
uuid: generateUUID(),
course_id: Number(body.course_id),
training_type_id: Number(body.training_type_id),
training_station_id: Number(body.training_station_id),
date: dayjs.utc(body.date).toDate(),
},
{
transaction: t,
}
);

const userBelongsToSession = await TrainingSessionBelongsToUsers.create(
{
training_session_id: session.id,
user_id: Number(body.trainee_id),
log_id: null,
passed: null,
},
{
transaction: t,
}
);

// TODO: Create ATSIM Request here!

await t.commit();

response.sendStatus(HttpStatusCode.Created);
} catch (e) {
await t.rollback();
next(e);
}
}

export default {
getOpen,
getAvailable,
createCPT,
};
40 changes: 40 additions & 0 deletions src/controllers/cpt/_CPTAdmin.validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import ValidationHelper, { ValidationOptions } from "../../utility/helper/ValidationHelper";
import { ValidationException } from "../../exceptions/ValidationException";

function validateCreateRequest(data: any) {
const validation = ValidationHelper.validate([
{
name: "date",
validationObject: data.date,
toValidate: [{ val: ValidationOptions.NON_NULL }, { val: ValidationOptions.VALID_DATE }],
},
{
name: "trainee_id",
validationObject: data.trainee_id,
toValidate: [{ val: ValidationOptions.NON_NULL }, { val: ValidationOptions.NUMBER }],
},
{
name: "course_id",
validationObject: data.course_id,
toValidate: [{ val: ValidationOptions.NON_NULL }, { val: ValidationOptions.NUMBER }],
},
{
name: "training_type_id",
validationObject: data.training_type_id,
toValidate: [{ val: ValidationOptions.NON_NULL }, { val: ValidationOptions.NUMBER }],
},
{
name: "training_station_id",
validationObject: data.training_station_id,
toValidate: [{ val: ValidationOptions.NON_NULL }, { val: ValidationOptions.NUMBER }],
},
]);

if (validation.invalid) {
throw new ValidationException(validation);
}
}

export default {
validateCreateRequest,
};
49 changes: 14 additions & 35 deletions src/controllers/training-session/TrainingSessionAdminController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ async function createTrainingSession(request: Request, response: Response) {
const requestUser: User = request.body.user as User;
const data = request.body as {
course_uuid?: string;
cpt_beisitzer?: boolean;
date?: string;
training_type_id?: number;
training_station_id?: number;
Expand Down Expand Up @@ -77,27 +76,15 @@ async function createTrainingSession(request: Request, response: Response) {
}

let trainingSession;
if (trainingType.type != "cpt" || data.cpt_beisitzer) {
// Either the training type is NOT CPT, or - if it is CPT - the user wants to be beisitzer

// Create Session
trainingSession = await TrainingSession.create({
uuid: generateUUID(),
mentor_id: requestUser.id,
training_station_id: data.training_station_id,
date: dayjs.utc(data.date).toDate(),
training_type_id: data.training_type_id,
course_id: course.id,
});
} else {
trainingSession = await TrainingSession.create({
uuid: generateUUID(),
training_station_id: data.training_station_id,
date: dayjs.utc(data.date).toDate(),
training_type_id: data.training_type_id,
course_id: course.id,
});
}
// Create Session
trainingSession = await TrainingSession.create({
uuid: generateUUID(),
mentor_id: requestUser.id,
training_station_id: data.training_station_id,
date: dayjs.utc(data.date).toDate(),
training_type_id: data.training_type_id,
course_id: course.id,
});

if (trainingSession == null) {
response.sendStatus(HttpStatusCode.InternalServerError);
Expand Down Expand Up @@ -160,19 +147,11 @@ async function updateByUUID(request: Request, response: Response, next: NextFunc
}

const trainingStationIDNum = Number(body.training_station_id);
if (body.mentor_id == "-1") {
await session.update({
mentor_id: null,
date: dayjs.utc(body.date).toDate(),
training_station_id: trainingStationIDNum == -1 ? null : trainingStationIDNum,
});
} else {
await session.update({
mentor_id: Number(body.mentor_id),
date: dayjs.utc(body.date).toDate(),
training_station_id: trainingStationIDNum == -1 ? null : trainingStationIDNum,
});
}
await session.update({
mentor_id: Number(body.mentor_id),
date: dayjs.utc(body.date).toDate(),
training_station_id: trainingStationIDNum == -1 ? null : trainingStationIDNum,
});

response.sendStatus(HttpStatusCode.Ok);
} catch (e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ function validateCreateSessionRequest(data: any): ValidatorType {
validationObject: data.course_uuid,
toValidate: [{ val: ValidationOptions.NON_NULL }],
},
{
name: "cpt_beisitzer",
validationObject: data.cpt_beisitzer,
toValidate: [{ val: ValidationOptions.NON_NULL }],
},
{
name: "date",
validationObject: data.date,
Expand Down

0 comments on commit dfa6302

Please sign in to comment.