diff --git a/backend/apis/nodejs/src/app.js b/backend/apis/nodejs/src/app.js index 22e6bd6..cb9591f 100644 --- a/backend/apis/nodejs/src/app.js +++ b/backend/apis/nodejs/src/app.js @@ -26,7 +26,7 @@ const organizationAdminRoutes = require('./routes/organization_admin_routes.js') const jobOffersRoutes = require('./routes/job_offer_routes.js'); const serverRoutes = require('./routes/server_routes.js'); const resetPasswordRoutes = require('./routes/reset_password_routes.js'); -const applicationRoutes = require('./routes/applicant_routes.js'); +const applicationRoutes = require('./routes/job_application_routes.js'); /* ===== END IMPORTING MODULES ===== diff --git a/backend/apis/nodejs/src/models/applicant_model.js b/backend/apis/nodejs/src/models/job_application_model.js similarity index 50% rename from backend/apis/nodejs/src/models/applicant_model.js rename to backend/apis/nodejs/src/models/job_application_model.js index 58546e7..21a6c98 100644 --- a/backend/apis/nodejs/src/models/applicant_model.js +++ b/backend/apis/nodejs/src/models/job_application_model.js @@ -12,8 +12,16 @@ */ const knex = require('../utils/knex_config'); +/** + * Inserts a new JobApplication. + * + * @param {*} personId The ID of the Person applying for the job + * @param {*} jobOfferId The ID of the job + * @returns The inserted JobApplication object if successful, throws an + * exception otherwise + */ async function insert(personId, jobOfferId) { - return await knex('Applicant') + return await knex('JobApplication') .insert({ person_id: personId, job_offer_id: jobOfferId @@ -22,7 +30,7 @@ async function insert(personId, jobOfferId) { } async function userAlreadyApplicated(personId, jobOfferId){ - const person = await knex('Applicant') + const person = await knex('JobApplication') .where('person_id', personId) .where('job_offer_id', jobOfferId) .select('*') @@ -33,7 +41,23 @@ async function userAlreadyApplicated(personId, jobOfferId){ return false; } +/** + * Retrieves all the applications of the specified Person, includinf data from + * JobOffer and Organization + * @param {*} personId + * @returns All the applications of the specified Person, throws an exception + * otherwise + */ +async function getApplications(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'); +} + module.exports = { insert, - userAlreadyApplicated + userAlreadyApplicated, + getApplications } \ No newline at end of file diff --git a/backend/apis/nodejs/src/models/job_offer_model.js b/backend/apis/nodejs/src/models/job_offer_model.js index b2f5de8..bf54ac6 100644 --- a/backend/apis/nodejs/src/models/job_offer_model.js +++ b/backend/apis/nodejs/src/models/job_offer_model.js @@ -131,5 +131,6 @@ async function filter(title, description, requirements, salary, salaryOperator, module.exports = { insert, remove, - findByOrganizationId + findByOrganizationId, + findById } \ No newline at end of file diff --git a/backend/apis/nodejs/src/routes/applicant_routes.js b/backend/apis/nodejs/src/routes/applicant_routes.js deleted file mode 100644 index b8f2bfe..0000000 --- a/backend/apis/nodejs/src/routes/applicant_routes.js +++ /dev/null @@ -1,47 +0,0 @@ -/* - This code is part of Blink - licensed under GPLv3 - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. -*/ - -const Applicant = require('../models/applicant_model'); -const express = require('express'); -const jwtUtils = require('../utils/jwt_utils'); - -/** - * POST - * @param {*} req - * @param {*} res - * @returns - */ -async function insert(req, res) { - try { - if(await Applicant.userAlreadyApplicated(req.jwt.person_id, req.body.jobOfferId)){ - return res.status(401).json({ - error: 'User has already applied to this job' - }); - } - const application = await Applicant.insert(req.jwt.person_id, req.body.jobOfferId); - res.set('Location', `/api/applications/${application.id}`); - return res.status(201).json(application); - } catch (error) { - console.error(`Error in function ${registerPerson.name}: ${error}`); - res.status(500).json({ - error: 'Internal server error' - }); - } - } - - const routes = express.Router(); - routes.post('/', jwtUtils.extractToken, insert); - - module.exports = { - routes - }; \ 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 new file mode 100644 index 0000000..6c1150f --- /dev/null +++ b/backend/apis/nodejs/src/routes/job_application_routes.js @@ -0,0 +1,80 @@ +/* + This code is part of Blink + licensed under GPLv3 + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +const Application = require('../models/job_application_model'); +const JobOffer = require('../models/job_offer_model'); +const express = require('express'); +const jwtUtils = require('../utils/jwt_utils'); + +/** + * POST Request + * + * Inserts a new job application + * @param {*} req + * @param {*} res + * @returns + */ +async function insert(req, res) { + try { + // Check if the job offer exists + if (await JobOffer.findById(req.body.jobOfferId) == null) { + return res.status(404).json({ + error: 'This job offer does not exist' + }); + } + + // 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({ + error: 'User has already applied to this job' + }); + } + + const application = await Application.insert(req.jwt.person_id, req.body.jobOfferId); + res.set('Location', `/api/applications/${application.id}`); + return res.status(201).json(application); + } catch (error) { + console.error(`Error in function ${insert.name}: ${error}`); + res.status(500).json({ + error: 'Internal server error' + }); + } +} + +/** + * GET Request + * + * Retrieves all the job applications of the logged in user + * @param {*} req + * @param {*} res + * @returns + */ +async function myApplications(req, res) { + try { + const applications = await Application.getApplications(req.jwt.person_id); + return res.status(201).send(applications); + } catch (error) { + console.error(`Error in function ${myApplications.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); + +module.exports = { + routes +}; \ No newline at end of file diff --git a/backend/sql/1-create_tables.sql b/backend/sql/1-create_tables.sql index 11e8d8f..3002976 100644 --- a/backend/sql/1-create_tables.sql +++ b/backend/sql/1-create_tables.sql @@ -76,8 +76,8 @@ CREATE TABLE IF NOT EXISTS "JobOfferTag" ( CONSTRAINT "TagFk" FOREIGN KEY (tag_id) REFERENCES "Tag" (id) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE ); --- Table: Applicant -CREATE TABLE IF NOT EXISTS "Applicant" ( +-- Table: JobApplication +CREATE TABLE IF NOT EXISTS "JobApplication" ( id SERIAL PRIMARY KEY, person_id INTEGER NOT NULL, job_offer_id INTEGER NOT NULL, diff --git a/backend/sql/BlinkClassDiagram.png b/backend/sql/BlinkClassDiagram.png index 6b435e8..1bbc911 100644 Binary files a/backend/sql/BlinkClassDiagram.png and b/backend/sql/BlinkClassDiagram.png differ