diff --git a/backend/apis/nodejs/src/models/job_application_model.js b/backend/apis/nodejs/src/models/job_application_model.js index 21a6c98..509b629 100644 --- a/backend/apis/nodejs/src/models/job_application_model.js +++ b/backend/apis/nodejs/src/models/job_application_model.js @@ -29,35 +29,83 @@ async function insert(personId, jobOfferId) { .returning("*"); } -async function userAlreadyApplicated(personId, jobOfferId){ +async function userAlreadyApplicated(personId, jobOfferId) { const person = await knex('JobApplication') .where('person_id', personId) .where('job_offer_id', jobOfferId) .select('*') .first(); - if(person){ + if (person) { return true; } return false; } /** - * Retrieves all the applications of the specified Person, includinf data from - * JobOffer and Organization + * Retrieves all the applications of the specified Person, including data from + * JobOffer and Organization. It is useful when a person wants to retrieve + * their applications * @param {*} personId * @returns All the applications of the specified Person, throws an exception * otherwise */ -async function getApplications(personId){ +async function getMyApplications(personId) { return await knex('JobApplication') .where('person_id', personId) .join('JobOffer', 'JobOffer.id', 'JobApplication.job_offer_id') .join('Organization', 'Organization.id', 'JobOffer.organization_id') - .select('JobApplication.id', 'JobOffer.title', 'JobOffer.description', 'Organization.name', 'Organization.location'); + .select('JobApplication.id', 'JobOffer.title', 'JobOffer.description', 'Organization.name', 'Organization.location'); +} + +/** + * Retrieves all the applicants of the specified JobOffer + * under the form of a subset of properties of the Person + * object + * + * @param {*} organizationId + */ +async function getApplicantsByJobOffer(jobOfferId) { + return await knex('JobApplication') + .where('job_offer_id', jobOfferId) + .join('Person', 'Person.id', 'JobApplication.person_id') + .select('Person.id AS person_id', 'Person.display_name', 'Person.qualification', 'Person.about_me'); +} + +/** + * Retrieves all the applicants and the relative JobOffer they + * applied to + * + * @param {*} organizationId + * @returns An array of Person and JobOffer objects. Throws an exception if an error occurs + */ +async function getApplicansByOrganization(organizationId) { + const applicants = await knex('JobApplication') + .join('Person', 'Person.id', 'JobApplication.person_id') + .join('JobOffer', 'JobOffer.id', 'JobApplication.job_offer_id') + .join('Organization', 'Organization.id', 'JobOffer.organization_id') + .where('Organization.id', organizationId) + .select('Person.id AS person_id', 'Person.display_name', 'Person.qualification', 'Person.about_me', 'JobOffer.id AS job_offer_id', 'JobOffer.title', 'JobOffer.description'); + + return applicants.map(applicant => ({ + Person: { + person_id: applicant.person_id, + display_name: applicant.display_name, + qualification: applicant.qualification, + about_me: applicant.about_me, + }, + JobOffer: { + job_offer_id: applicant.job_offer_id, + title: applicant.title, + description: applicant.description, + }, + })); + } module.exports = { insert, userAlreadyApplicated, - getApplications + getMyApplications, + getApplicantsByJobOffer, + getApplicansByOrganization } \ No newline at end of file diff --git a/backend/apis/nodejs/src/routes/job_application_routes.js b/backend/apis/nodejs/src/routes/job_application_routes.js index 6c1150f..e51ae96 100644 --- a/backend/apis/nodejs/src/routes/job_application_routes.js +++ b/backend/apis/nodejs/src/routes/job_application_routes.js @@ -13,6 +13,7 @@ const Application = require('../models/job_application_model'); const JobOffer = require('../models/job_offer_model'); +const OrganizationAdmin = require('../models/organization_admin_model'); const express = require('express'); const jwtUtils = require('../utils/jwt_utils'); @@ -35,7 +36,7 @@ async function insert(req, res) { // Check if the user has already applied for this position if (await Application.userAlreadyApplicated(req.jwt.person_id, req.body.jobOfferId)) { - return res.status(401).json({ + return res.status(400).json({ error: 'User has already applied to this job' }); } @@ -61,8 +62,8 @@ async function insert(req, res) { */ async function myApplications(req, res) { try { - const applications = await Application.getApplications(req.jwt.person_id); - return res.status(201).send(applications); + const applications = await Application.getMyApplications(req.jwt.person_id); + return res.status(200).json(applications); } catch (error) { console.error(`Error in function ${myApplications.name}: ${error}`); res.status(500).json({ @@ -71,9 +72,60 @@ async function myApplications(req, res) { } } +/** + * GET Request. Retrieve all the applicants who applicated to a job offer. + * Only an organization administrator is allowed to perform this action. + * @param {*} req + * @param {*} res + */ +async function getApplicantsByJobOffer(req, res) { + try { + const isAdmin = await OrganizationAdmin.isAdmin(req.jwt.person_id, jobOffer.organization_id); + if(!isAdmin){ + return res.status(401).json({ + error: 'Forbidden' + }); + } + const applicants = await Application.getApplicantsByJobOffer(req.body.jobOfferId); + return res.status(200).json(applicants); + } catch (error) { + console.error(`Error in function ${getApplicantsByJobOffer.name}: ${error}`); + res.status(500).json({ + error: 'Internal server error' + }); + } +} + +/** + * GET Request. Retrieve all the applicants who applicated to a job offer created + * by the specific organization. + * Only an organization administrator is allowed to perform this action. + * @param {*} req + * @param {*} res + */ +async function getApplicantsByOrganization(req, res){ + try { + const isAdmin = await OrganizationAdmin.isAdmin(req.jwt.person_id, req.body.organizationId); + if(!isAdmin){ + return res.status(401).json({ + error: 'Forbidden' + }); + } + const applicants = await Application.getApplicansByOrganization(req.body.organizationId); + return res.status(200).json(applicants); + } catch (error) { + console.error(`Error in function ${getApplicantsByOrganization.name}: ${error}`); + res.status(500).json({ + error: 'Internal server error' + }); + } +} + const routes = express.Router(); routes.post('/', jwtUtils.extractToken, insert); routes.get('/myapplications', jwtUtils.extractToken, myApplications); +routes.get('/applicantsbyjoboffer', jwtUtils.extractToken, getApplicantsByJobOffer); +routes.get('/applicantsbyorganization', jwtUtils.extractToken, getApplicantsByOrganization); module.exports = { routes