Skip to content

Commit

Permalink
Feat/bo liste territoires 636 (#598)
Browse files Browse the repository at this point in the history
Ajout de la liste des territoires avec les infos du territoire.
Ajout de l'écran de détail des infos du territoire, modifiable par le
territoire lui même et la région si c'est un département.
  • Loading branch information
l-scherer authored Nov 14, 2024
2 parents 2c3975f + 114fd35 commit 9403de7
Show file tree
Hide file tree
Showing 21 changed files with 765 additions and 4 deletions.
1 change: 1 addition & 0 deletions packages/backend/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ app.use(`/geo`, routes.geo);
// TODO(eig): unhide when ok
//app.use(`/eig`, routes.eig);
app.use(`/message`, routes.message);
app.use(`/territoire`, routes.territoire);
app.use(`/healthz`, routes.healthz);

if (config.sentry.environment !== "production") {
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/controllers/bo-user/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module.exports.list = require("./list");
module.exports.listUsersTerritoire = require("./list-users-territoire");
module.exports.getExtract = require("./getExtract");
module.exports.getOne = require("./get-one");
module.exports.getMe = require("./get-me");
Expand Down
17 changes: 17 additions & 0 deletions packages/backend/src/controllers/bo-user/list-users-territoire.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const BoUser = require("../../services/BoUser");
const logger = require("../../utils/logger");

const log = logger(module.filename);

module.exports = async function listUsersTerritoire(req, res, next) {
log.i("IN");
const territoireCode = req.params.territoireCode;
try {
const result = await BoUser.readTerritoires(territoireCode);
log.d(result);
return res.status(200).json(result);
} catch (error) {
log.w("DONE with error");
return next(error);
}
};
1 change: 1 addition & 0 deletions packages/backend/src/controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ module.exports.demandeSejourController = require("./demandeSejour");
module.exports.hebergementController = require("./hebergement");
module.exports.eigController = require("./eig");
module.exports.messageController = require("./message");
module.exports.territoireController = require("./territoire");
30 changes: 30 additions & 0 deletions packages/backend/src/controllers/territoire/get-one.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const AppError = require("../../utils/error");
const Territoire = require("../../services/Territoire");

const logger = require("../../utils/logger");

const log = logger(module.filename);

module.exports = async function getOne(req, res, next) {
log.i("IN");
const { idTerritoire } = req.params;

if (!idTerritoire || isNaN(idTerritoire)) {
return next(
new AppError("Paramètre manquant id", {
statusCode: 400,
}),
);
}
const territoire = await Territoire.readOne(idTerritoire);
if (!territoire) {
log.w("DONE with error");
return next(
new AppError("Territoire non trouvée", {
statusCode: 404,
}),
);
}
log.i("DONE");
return res.json({ territoire });
};
3 changes: 3 additions & 0 deletions packages/backend/src/controllers/territoire/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports.getOne = require("./get-one");
module.exports.list = require("./list");
module.exports.update = require("./update");
12 changes: 12 additions & 0 deletions packages/backend/src/controllers/territoire/list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const Territoire = require("../../services/Territoire");

const logger = require("../../utils/logger");

const log = logger(module.filename);

module.exports = async function list(_req, res) {
log.i("IN");
const territoires = await Territoire.fetch();
log.i("DONE");
return res.json({ territoires });
};
35 changes: 35 additions & 0 deletions packages/backend/src/controllers/territoire/update.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const AppError = require("../../utils/error");
const Territoire = require("../../services/Territoire");
const logger = require("../../utils/logger");

const log = logger(module.filename);

module.exports = async function update(req, res, next) {
log.i("IN");
const { id } = req.params;
const { territoire, parent } = req.body;
const { territoireCode } = req.decoded;
if (!id || !territoire || !parent || !territoireCode) {
return next(
new AppError("Paramètre manquant", {
statusCode: 400,
}),
);
}
let response;
if (
territoireCode === "FRA" ||
territoireCode === territoire ||
territoireCode === parent
) {
response = await Territoire.update(id, req.body);
} else {
return next(
new AppError("Bad request unauthorized", {
statusCode: 401,
}),
);
}
log.i("DONE");
return res.json({ response });
};
6 changes: 6 additions & 0 deletions packages/backend/src/routes/bo-user.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ router.get(
);
// Gère une connexion via mot de passe.
router.get("/me", BOcheckJWT, BOUserController.getMe);
// Liste des utilisateurs BO Liés à un territoire et sous territoires
router.get(
"/territoires/:territoireCode",
BOcheckJWT,
BOUserController.listUsersTerritoire,
);
// Renvoie les informations liées à l'utilisateur
router.get("/:userId", BOcheckJWT, BOcheckRoleCompte, BOUserController.getOne);
// Mise à jour de mes informations
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports.sejour = require("./sejour");
module.exports.hebergement = require("./hebergement");
module.exports.agrement = require("./agrement");
module.exports.message = require("./message");
module.exports.territoire = require("./territoire");

module.exports.documents = require("./documents");

Expand Down
12 changes: 12 additions & 0 deletions packages/backend/src/routes/territoire.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const express = require("express");

const router = express.Router();

const territoireController = require("../controllers/territoire");
const BOcheckJWT = require("../middlewares/bo-check-JWT");

router.get("/list", BOcheckJWT, territoireController.list);
router.get("/get-one/:idTerritoire", BOcheckJWT, territoireController.getOne);
router.put("/:id", BOcheckJWT, territoireController.update);

module.exports = router;
48 changes: 45 additions & 3 deletions packages/backend/src/services/BoUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,21 @@ ${additionalParamsQuery}
`,
additionalParams,
],
listUsersTerritoire: `
SELECT
us.mail as email,
us.blocked as "isBlocked",
us.nom as nom,
us.prenom as prenom,
us.ter_code as "territoireCode",
terp.label as "territoireLibelle"
FROM geo.territoires terp
LEFT JOIN geo.territoires ters ON ters.parent_code = terp.code
INNER JOIN back.users us ON (terp.code = us.ter_code OR ters.code = us.ter_code) AND us.ter_code <> 'FRA'
WHERE terp.code = $1 AND us.validated = true AND us.deleted = false
GROUP BY 1,2,3,4,5,6
ORDER BY nom
`,
login: `
SELECT
us.id as id,
Expand Down Expand Up @@ -407,7 +422,6 @@ module.exports.read = async (
let searchQuery = "";
let territoireSearchParamId = "";
const searchParams = [];

// Search management
if (search?.nom && search.nom.length) {
searchQuery += ` AND unaccent(us.nom) ILIKE unaccent($${searchParams.length + 1})\n`;
Expand All @@ -424,16 +438,31 @@ module.exports.read = async (
if (
search?.territoire &&
search?.territoire !== "FRA" &&
search.territoire.length
search?.territoire.length
) {
searchQuery += ` AND (
unaccent(ter.label) ILIKE unaccent($${searchParams.length + 1})
OR code ILIKE $${searchParams.length + 1}
OR ter.code ILIKE $${searchParams.length + 1}
OR ter.parent_code IN (SELECT code FROM matched_elements)
)\n`;
territoireSearchParamId = searchParams.length + 1;
searchParams.push(`%${search.territoire}%`);
}

// Filtre utilisé pour rechercher tous les users pour un territoire et ses enfants
if (
search?.territoireParent &&
search?.territoireParent !== "FRA" &&
search.territoireParent.length
) {
searchQuery += ` AND (
ter.code = $${searchParams.length + 1}
OR ter.parent_code = $${searchParams.length + 1}
)\n`;
territoireSearchParamId = searchParams.length + 1;
searchParams.push(`%${search.territoireParent}%`);
}

if (search?.statut === "validated") {
searchQuery += `AND us.validated = true\n`;
}
Expand Down Expand Up @@ -495,6 +524,7 @@ module.exports.read = async (
WHERE unaccent(label) ILIKE unaccent($${territoireSearchParamId})
OR code ILIKE $${territoireSearchParamId}
)\n`;

const response = await pool.query(
`${territoireSearchParamId ? territoirePreQuery : ""}
${queryPrepared[0]}`,
Expand All @@ -515,6 +545,18 @@ module.exports.read = async (
};
};

module.exports.readTerritoires = async (territoireParent) => {
log.i("readTerritoires - IN", territoireParent);
const userTerritoire = await pool.query(query.listUsersTerritoire, [
territoireParent,
]);
log.i("readTerritoires - DONE");
return {
total: userTerritoire.rows.count,
users: userTerritoire.rows,
};
};

module.exports.readOne = async (id, territoireCode) => {
log.i("readOne - IN", { id });

Expand Down
98 changes: 98 additions & 0 deletions packages/backend/src/services/Territoire.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
const AppError = require("../utils/error");
const logger = require("../utils/logger");
const pool = require("../utils/pgpool").getPool();

const log = logger(module.filename);

const query = {
getOne: `
select
fte.id AS territoire_id,
CASE (ter.code ~ '[0-9]')
WHEN true THEN 'DEP'
ELSE 'REG'
END AS type,
ter.code AS value,
ter.label AS text,
ter.parent_code AS parent,
fte.service_mail AS service_mail,
fte.service_telephone AS service_telephone,
fte.corresp_vao_nom AS corresp_vao_nom,
fte.corresp_vao_prenom AS corresp_vao_prenom,
fte.edited_at AS edited_at
FROM back.fiche_territoire fte
INNER JOIN geo.territoires ter ON fte.ter_code = ter.code
WHERE fte.id = $1`,
select: `
select
fte.id AS territoire_id,
CASE (ter.code ~ '[0-9]')
WHEN true THEN 'DEP'
ELSE 'REG'
END AS type,
ter.code AS value,
ter.label AS text,
fte.service_telephone AS service_telephone,
fte.corresp_vao_nom AS corresp_vao_nom,
fte.corresp_vao_prenom AS corresp_vao_prenom,
fte.service_mail as service_mail,
COUNT(distinct(usr.id)) as nbusersbo
FROM geo.territoires ter
INNER JOIN back.fiche_territoire fte ON fte.ter_code = ter.code
LEFT JOIN back.users usr ON usr.ter_code = ter.code
WHERE code <> 'FRA'
GROUP BY territoire_id,type,value,text,service_telephone,corresp_vao_nom,corresp_vao_prenom,service_mail
ORDER BY type, text ASC`,
update: `
UPDATE back.fiche_territoire
SET
corresp_vao_nom = $2,
corresp_vao_prenom = $3,
service_mail = $4,
service_telephone = $5,
edited_at = NOW()
WHERE
id = $1
RETURNING *
`,
};

module.exports.fetch = async (criterias = {}) => {
log.i("fetch - IN");
const { rows } = await pool.query(query.select);

return rows.filter((territoire) => {
return Object.entries(criterias).every(
([key, value]) => territoire[key] == value,
);
});
};

module.exports.readOne = async (idTerritoire) => {
log.i("fetch - IN");
const { rows } = await pool.query(query.getOne, [idTerritoire]);
log.i("fetch - DONE");
return rows[0];
};

module.exports.update = async (id, { nom, prenom, email, telephone }) => {
log.i("update - IN", { id });

const response = await pool.query(query.update, [
id,
nom,
prenom,
email,
telephone,
]);

if (response.rows.Count === 0) {
log.d("update - DONE - fiche territoire inexistante");
throw new AppError("Fiche territoire déjà inexistant", {
name: "FicheTerritoireNotFound",
});
}

log.i("update - DONE");
return { territoire: response.rows[0] };
};
1 change: 0 additions & 1 deletion packages/frontend-bo/src/components/user/Compte.vue
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,6 @@ const closeModal = () => (popUpParams.value = null);
const modalOpenCounter = ref(0);
const openModal = (p) => {
console.log(p);
modalOpenCounter.value++;
popUpParams.value = {
cb: () => {
Expand Down
4 changes: 4 additions & 0 deletions packages/frontend-bo/src/composables/useMenuNavItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ export const useMenuNavItems = () => {
text: "Organismes",
to: "/organismes/liste",
},
{
text: "Territoires",
to: "/territoires/liste",
},
...(roles.includes("DemandeSejour_Lecture") ||
roles.includes("DemandeSejour_Ecriture")
? [
Expand Down
Loading

0 comments on commit 9403de7

Please sign in to comment.