Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: #19

Merged
merged 1 commit into from
Jun 21, 2023
Merged

Fix: #19

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions app/controllers/ApiController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import {OfferRepository} from "../repository/OfferRepository";
import {OffreDePoste} from "../entity/OffreDePoste";
import express from "express";
import {FilterOffer} from "../utils/FilterOffer";
import {UserRepository} from "../repository/UserRepository";
import {User} from "../entity/User";

export class ApiController {
static getOffers(req: express.Request, res: express.Response) {
Expand Down
50 changes: 46 additions & 4 deletions app/controllers/CandidatureController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {CandidatureRepository} from "../repository/CandidatureRepository";
import {Candidature} from "../entity/Candidature";
import {StatutCandidatureEnum} from "../utils/StatutCandidatureEnum";
import {Piece} from "../entity/Piece";
import {PieceRepository} from "../repository/FichierRepository";
import {PieceRepository} from "../repository/PieceRepository";
import {loggedInNoRedirection} from "../passport/passportFunctions";

export class CandidatureController {
Expand Down Expand Up @@ -64,7 +64,12 @@ export class CandidatureController {

}
}
res.render("candidater", {title: "Candidater", offer: offer, alerts: alerts, userLogged: loggedInNoRedirection(req, res)});
res.render("candidater", {
title: "Candidater",
offer: offer,
alerts: alerts,
userLogged: loggedInNoRedirection(req, res)
});

}
)
Expand All @@ -73,12 +78,49 @@ export class CandidatureController {
});
}

static async getFile(req: express.Request, res: express.Response) {
let id = req.params.id;
//TODO vérifier que l'utilisateur est bien un candidat ou un recruteur et qu'il a le droit d'accéder au fichier
try {
const piece = await PieceRepository.getById(Number(id));
if (!piece) {
throw new Error("File not found");
}
res.download(piece.url);
} catch (err) {
res.statusCode = 404;
res.send("File not found");
}
}

static candidature(req: express.Request, res: express.Response) {
let email = req.params.email;
let offerNumber = req.params.numero;

CandidatureRepository.getById(email, offerNumber).then((candidature) => {
if (candidature) {
return res.render("candidature", {
title: "Candidature",
candidature: candidature,
userLogged: loggedInNoRedirection(req, res)
});
}
return res.redirect("/");
}).catch((err) => {
return res.redirect("/");
});

}

static candidatures(req: express.Request, res: express.Response) {
//TODO Vérifier que l'utilisateur est bien un candidat
let user: User = new User('[email protected]', 'Doe', 'John', '123456789', new Date(), true, 'password123', 'Candidat', 'En attente', null);
let user: User = req.user as User;
CandidatureRepository.getByUser(user).then((candidatures) => {
res.render("candidatures", {title: "Mes candidatures", candidatures: candidatures, userLogged: loggedInNoRedirection(req, res)});
res.render("candidatures", {
title: "Mes candidatures",
candidatures: candidatures,
userLogged: loggedInNoRedirection(req, res)
});

}).catch((err) => {
console.log(err);
Expand Down
3 changes: 0 additions & 3 deletions app/controllers/FicheController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ export class FicheController {
if (req.method === "POST") {
//TODO validation data
let teletravail: boolean = req.body.teletravail === "on";
//TODO get the siren from the recruiter
//random number 9 digits

let siren: string = req.user.organisation?.siren as string;
let nbHeures: number = parseInt(req.body.nbHeures);
Expand Down Expand Up @@ -41,7 +39,6 @@ export class FicheController {
});

}
//TODO get the siren from the recruiter
res.render("fiche/creation", {title: "Créer une fiche de poste", alerts: alerts, userLogged: loggedInNoRedirection(req, res)});

}
Expand Down
20 changes: 8 additions & 12 deletions app/controllers/OfferController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@ export class OfferController {
public static async creation(req: express.Request, res: express.Response) {

const alerts: Alert[] = [];
console.log(req.method);

if (req.method === "POST") {

let csrfToken = req.body._csrf;
if (!csrfValidation(req, csrfToken)) {
alerts.push(new Alert("danger", "Erreur CSRF"));
//TODO message d'erreur
return res.redirect("/logout");
}
//TODO validation data
Expand Down Expand Up @@ -48,7 +46,6 @@ export class OfferController {
nbPiece,
listePiece,
ficheDePoste);
//TODO save the ficheDePoste in the database
await OfferRepository.create(offreDePoste).then((offreDePoste) => {
let alert = new Alert("success", "L'offre a été créée.");
alerts.push(alert);
Expand All @@ -67,20 +64,19 @@ export class OfferController {

}
//TODO selectionner seulement les fiches de postes de l'organisation du recruteur
let ficheDePostes: FicheDePoste[] = await FicheDePosteRepository.getAll();
let siren: string = req.user.organisation?.siren as string;
let ficheDePostes: FicheDePoste[] = await FicheDePosteRepository.getBySiren(siren);
if (ficheDePostes.length === 0) {
let alert = new Alert("danger", "Vous n'avez pas encore créé de fiche de poste.");
alerts.push(alert);
return res.redirect("/fiche-de-poste/creation");
}
FicheDePosteRepository.getAll().then((ficheDePostes) => {
return res.render("offre/creation", {
title: "Créer une offre",
ficheDePostes: ficheDePostes,
alerts: alerts,
userLogged: loggedInNoRedirection(req, res),
csrfToken: req.session.csrfSecret
});
return res.render("offre/creation", {
title: "Créer une offre",
ficheDePostes: ficheDePostes,
alerts: alerts,
userLogged: loggedInNoRedirection(req, res),
csrfToken: req.session.csrfSecret
});
}
}
5 changes: 4 additions & 1 deletion app/entity/Candidature.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {User} from "./User";
import {OffreDePoste} from "./OffreDePoste";
import {StatutCandidatureEnum} from "../utils/StatutCandidatureEnum";
import {Piece} from "./Piece";

/**
* Candidature
Expand All @@ -15,13 +16,15 @@ export class Candidature {
offre: OffreDePoste;
statut: StatutCandidatureEnum;
motivation: string;
pieces: Piece[] | undefined;

constructor(date: Date, candidat: User, offre: OffreDePoste, status: StatutCandidatureEnum, motivation: string) {
constructor(date: Date, candidat: User, offre: OffreDePoste, status: StatutCandidatureEnum, motivation: string, pieces?: Piece[]) {
this.date = date;
this.candidat = candidat;
this.offre = offre;
this.statut = status;
this.motivation = motivation;
this.pieces = pieces;
}

}
3 changes: 2 additions & 1 deletion app/entity/Piece.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ export class Piece {
candidat: User;
offre: OffreDePoste;

constructor(nom: string, url: string, candidat: User, offre: OffreDePoste) {
constructor(nom: string, url: string, candidat: User, offre: OffreDePoste, id ?: number) {
this.nom = nom;
this.url = url;
this.candidat = candidat;
this.offre = offre;
this.id = id;
}
}
3 changes: 2 additions & 1 deletion app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {ficheRouter} from "./routes/FicheRouter";
import bodyParser from "body-parser";
import {recruterRouter} from "./routes/RecruterRouter";
import {apiRouter} from "./routes/ApiRouter";

const {passport} = require("./passport/passportFunctions");

dotenv.config();
Expand All @@ -33,6 +34,6 @@ app.use("/api", apiRouter);
const port = process.env.PORT || 8000;

app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
console.log(`web-app-recrutement listening on port ${port}`)
});

21 changes: 11 additions & 10 deletions app/public/js/filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@ function filterOffer() {
}
let filter = "salary=" + salary + region;
//Get all the offers from the /api/offers route and adding the filter parameters
fetch("/api/offers?" + filter).then(r => r.json()).then(offers => {
let offersDiv = document.getElementById("offers");
if (offers.length === 0) {
offersDiv.innerHTML = "Aucune offre ne correspond à vos critères";
return;
fetch("/api/offers?" + filter).then(r => r.json())
.then(offers => {
let offersDiv = document.getElementById("offers");
if (offers.length === 0) {
offersDiv.innerHTML = "Aucune offre ne correspond à vos critères";
return;
}
offersDiv.innerHTML = "";
offersDiv.append(...generateOffers(offers));
}
offersDiv.innerHTML = "";
offersDiv.append(...generateOffers(offers));
}
);
);
}


Expand All @@ -46,7 +47,7 @@ function generateOfferPrototype(offer) {
p1.innerHTML = offer.ficheDePoste.description;

const p2 = document.createElement('p');
p2.innerHTML = `Organisation: ${offer.ficheDePoste.siren}`;
p2.innerHTML = `Organisation: ${offer.ficheDePoste.organisation.nom}`;

const a = document.createElement('a');
a.href = `/canditature/${offer.numero}`;
Expand Down
88 changes: 83 additions & 5 deletions app/repository/CandidatureRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {User} from "../entity/User";
import {OffreDePoste} from "../entity/OffreDePoste";
import {FicheDePoste} from "../entity/FicheDePoste";
import {Organisation} from "../entity/Organisation";
import {PieceRepository} from "./PieceRepository";

export class CandidatureRepository {
static create(candidature: Candidature): Promise<Candidature> {
Expand Down Expand Up @@ -39,9 +40,9 @@ export class CandidatureRepository {
FDP.salaire,
FDP.description,
FDP.siren,
O.nom as nom_organisation,
O.type as type_organisation,
O.siege as siege_organisation
O.nom as nom_organisation,
O.type as type_organisation,
O.siege as siege_organisation
FROM Candidature
LEFT JOIN OffreDePoste ODP on Candidature.offre = ODP.numero
LEFT JOIN FicheDePoste FDP on ODP.fiche = FDP.numero
Expand Down Expand Up @@ -100,11 +101,15 @@ export class CandidatureRepository {
FDP.nb_heures,
FDP.salaire,
FDP.description,
FDP.siren
FDP.siren,
O.nom,
O.type,
O.siege
FROM Candidature
LEFT JOIN OffreDePoste ODP on Candidature.offre = ODP.numero
LEFT JOIN FicheDePoste FDP on ODP.fiche = FDP.numero
LEFT JOIN Utilisateur U on Candidature.candidat = U.email
LEFT JOIN Organisation O on FDP.siren = O.siren
WHERE FDP.siren = ?`;
return new Promise<Candidature[]>((resolve, reject) => {
pool.query(query, [siren], (err, result) => {
Expand All @@ -113,7 +118,8 @@ export class CandidatureRepository {
}
let candidatures: Candidature[] = [];
for (let i = 0; i < result.length; i++) {
let fiche = new FicheDePoste(result[i].fiche_numero, result[i].fiche_statut, result[i].responsable, result[i].type_metier, result[i].lieu, result[i].teletravail, result[i].nb_heures, result[i].salaire, result[i].description, result[i].siren);
let organisation = new Organisation(result[i].siren, result[i].nom, result[i].type, result[i].siege);
let fiche = new FicheDePoste(result[i].fiche_numero, result[i].fiche_statut, result[i].responsable, result[i].type_metier, result[i].lieu, result[i].teletravail, result[i].nb_heures, result[i].salaire, result[i].description, result[i].siren, organisation);
let offre = new OffreDePoste(result[i].offre_numero, result[i].etat, result[i].date_validite, result[i].nb_piece, result[i].liste_piece, fiche);
let candidat = new User(result[i].candidat, result[i].email, result[i].prenom, result[i].telephone, result[i].date_creation, result[i].user_statut, result[i].password, result[i].role, result[i].demande_organisation, result[i].user_siren);
candidatures.push(new Candidature(
Expand All @@ -129,4 +135,76 @@ export class CandidatureRepository {
});
}

static getById(email: string, offerNumber: string): Promise<Candidature | null> {
const query = `SELECT Candidature.candidat,
U.email,
U.nom as user_nom,
U.prenom,
U.telephone,
U.date_creation,
U.statut as user_statut,
U.password,
U.role,
U.demande_organisation,
U.siren as user_siren,
Candidature.offre,
Candidature.statut as candidature_statut,
Candidature.motivation,
Candidature.date_candidature,
ODP.numero as offre_numero,
ODP.etat,
ODP.date_validite,
ODP.nb_piece,
ODP.liste_piece,
FDP.numero as fiche_numero,
FDP.status as fiche_statut,
FDP.responsable,
FDP.type_metier,
FDP.lieu,
FDP.teletravail,
FDP.nb_heures,
FDP.salaire,
FDP.description,
FDP.siren,
O.nom,
O.type,
O.siege
FROM Candidature
LEFT JOIN OffreDePoste ODP on Candidature.offre = ODP.numero
LEFT JOIN FicheDePoste FDP on ODP.fiche = FDP.numero
LEFT JOIN Utilisateur U on Candidature.candidat = U.email
LEFT JOIN Organisation O on FDP.siren = O.siren
WHERE Candidature.candidat = ?
AND Candidature.offre = ?`;

return new Promise<Candidature | null>((resolve, reject) => {
pool.query(query, [email, offerNumber], async (err, result) => {
if (err) {
return reject(err);
}
if (result.length === 0) {
return resolve(null);
}
let pieces = await PieceRepository.getByCandidature(result[0].email, result[0].offre_numero).then((pieces) => {
return pieces;
}).catch((err) => {
return [];
});

let organisation = new Organisation(result[0].siren, result[0].nom, result[0].type, result[0].siege);
let fiche = new FicheDePoste(result[0].fiche_numero, result[0].fiche_statut, result[0].responsable, result[0].type_metier, result[0].lieu, result[0].teletravail, result[0].nb_heures, result[0].salaire, result[0].description, result[0].siren, organisation);
let offre = new OffreDePoste(result[0].offre_numero, result[0].etat, result[0].date_validite, result[0].nb_piece, result[0].liste_piece, fiche);
let candidat = new User(result[0].candidat, result[0].user_nom, result[0].prenom, result[0].telephone, result[0].date_creation, result[0].user_statut, result[0].password, result[0].role, result[0].demande_organisation, result[0].user_siren);
return resolve(new Candidature(
result[0].date_candidature,
candidat,
offre,
result[0].candidature_statut,
result[0].motivation,
pieces
));
});
});

}
}
21 changes: 0 additions & 21 deletions app/repository/FichierRepository.ts

This file was deleted.

Loading