Skip to content

Commit

Permalink
feat(eig): differentiate read by ddets and dreets
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminDNUM committed Sep 18, 2024
1 parent a90d7c9 commit 11ce26e
Show file tree
Hide file tree
Showing 16 changed files with 293 additions and 42 deletions.
1 change: 0 additions & 1 deletion packages/backend/src/controllers/eig/get-by-ds-id-admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ module.exports = async function get(req, res, next) {

try {
const eigs = await eigService.getByDsIdAdmin(declarationId);

return res.status(200).json({ eigs });
} catch (error) {
log.w("DONE with error");
Expand Down
37 changes: 34 additions & 3 deletions packages/backend/src/controllers/eig/mark-as-read.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ const AppError = require("../../utils/error");
const eigService = require("../../services/eig");

const logger = require("../../utils/logger");
const { statuts } = require("../../helpers/eig");
const {
statuts,
isUserDreetsWhoDeliveredAgrement,
isUserDdetsWhereEigHappened,
mustMarkAsRead,
} = require("../../helpers/eig");
const DemandeSejour = require("../../services/DemandeSejour");
const MailUtils = require("../../utils/mail");
const Send = require("../../services/mail").mailService.send;
Expand Down Expand Up @@ -41,10 +46,36 @@ module.exports = async function markAsRead(req, res, next) {
);
}

if (!mustMarkAsRead(territoireCode, eig)) {
log.w("L'EIG n'as pas à être marqué comme lu par le user");
return next(
new AppError("Statut incompatible", {
statusCode: 400,
}),
);
}

const typeReader = isUserDreetsWhoDeliveredAgrement(
territoireCode,
eig.agrementRegionObtention,
)
? "DREETS"
: isUserDdetsWhereEigHappened(territoireCode, eig.departement)
? "DDETS"
: null;

if (!typeReader) {
return next(
new AppError("L'utilisateur BO n'a aucune action a faire", {
statusCode: 400,
}),
);
}

try {
await eigService.markAsRead(eigId);
await eigService.markAsRead(eigId, typeReader);
await DemandeSejour.insertEvent(
`DDETS/DREETS ${territoireCode}`,
`${typeReader} ${territoireCode}`,
eig.declarationId,
null,
userId,
Expand Down
25 changes: 25 additions & 0 deletions packages/backend/src/helpers/eig.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,28 @@ module.exports.isDeclarationligibleToEig = (d) =>
dsStatuts.statuts.SEJOUR_EN_COURS,
dsStatuts.statuts.TERMINEE,
].includes(d.statut);

const isUserDreetsWhoDeliveredAgrement = (
territoireCode,
agrementRegionObtention,
) => territoireCode === agrementRegionObtention;

const isUserDdetsWhereEigHappened = (territoireCode, eigDepartement) =>
territoireCode === eigDepartement;

module.exports.isUserDreetsWhoDeliveredAgrement =
isUserDreetsWhoDeliveredAgrement;

module.exports.isUserDdetsWhereEigHappened = isUserDdetsWhereEigHappened;

module.exports.mustMarkAsRead = (territoireCode, eig) => {
return (
(!eig.readByDdets &&
isUserDdetsWhereEigHappened(territoireCode, eig.departement)) ||
(!eig.readByDreets &&
isUserDreetsWhoDeliveredAgrement(
territoireCode,
eig.agrementRegionObtention,
))
);
};
58 changes: 58 additions & 0 deletions packages/backend/src/middlewares/checkPermissionBOEIG.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
const logger = require("../utils/logger");
const AppError = require("../utils/error");
const { getById } = require("../services/eig");
const { statuts, mustMarkAsRead } = require("../helpers/eig");

const log = logger(module.filename);

async function checkPermissionEIG(req, res, next) {
const { id: userId, territoireCode } = req.decoded;
const { id: eigId } = req.params;

if (!eigId || isNaN(eigId)) {
return next(
new AppError("Vous n'êtes pas autorisé à accéder à cet EIG", {
statusCode: 403,
}),
);
}
if (isNaN(eigId)) {
return next(
new AppError("Invalid param type", {
statusCode: 403,
}),
);
}
log.i("IN", { eigId, userId });

let eig;

try {
eig = await getById({ eigId });
} catch (err) {
return res.status(400).send({ errors: err.errors, name: err.name });
}

if (eig.statut === statuts.BROUILLON) {
log.w("L'EIG a un statut brouillon et ne peut pas être lu");
return next(
new AppError("Statut incompatible", {
statusCode: 400,
}),
);
}

if (mustMarkAsRead(territoireCode, eig)) {
log.w("L'EIG doit d'abord être marqué comme lu");
return next(
new AppError("l'EIG doit d'abord être marqué comme lu", {
statusCode: 400,
}),
);
}

log.i("DONE");
next();
}

module.exports = checkPermissionEIG;
9 changes: 8 additions & 1 deletion packages/backend/src/routes/eig.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const canUpdateEig = require("../middlewares/can-update-or-delete-eig");
const checkPermissionDeclarationSejourForEig = require("../middlewares/checkPermissionDeclarationSejourEig");
const checkPermissionDeclarationSejour = require("../middlewares/checkPermissionDeclarationSejour");
const checkPermissionEIG = require("../middlewares/checkPermissionEIG");
const checkPermissionBOEIG = require("../middlewares/checkPermissionBOEIG");
const boCheckRole = require("../middlewares/bo-check-role");
const boCheckJWT = require("../middlewares/bo-check-JWT");

Expand Down Expand Up @@ -37,7 +38,13 @@ router.get(
);
router.get("/admin", boCheckJWT, boCheckRoleEig, eigController.getAdmin);
router.get("/:id", checkJWT, checkPermissionEIG, eigController.getById);
router.get("/admin/:id", boCheckJWT, boCheckRoleEig, eigController.getById);
router.get(
"/admin/:id",
boCheckJWT,
boCheckRoleEig,
checkPermissionBOEIG,
eigController.getById,
);
router.post(
"/",
checkJWT,
Expand Down
74 changes: 57 additions & 17 deletions packages/backend/src/services/eig.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ SELECT
EIG.created_at as "createdAt",
EIG.date as "date",
EIG.DEPARTEMENT as "departement",
EIG.READ_BY_DREETS as "readByDreets",
EIG.READ_BY_DDETS as "readByDdets",
S.STATUT AS "statut",
DS.ID_FONCTIONNELLE AS "idFonctionnelle",
DS.LIBELLE,
Expand All @@ -60,10 +62,12 @@ SELECT
DS.ORGANISME -> 'personneMorale' ->> 'raisonSociale' AS "raisonSociale",
DS.ORGANISME -> 'personnePhysique' ->> 'prenom' AS "prenom",
DS.ORGANISME -> 'personnePhysique' ->> 'nomUsage' AS "nom",
ARRAY_AGG(ET.TYPE) as "types"
ARRAY_AGG(ET.TYPE) as "types",
AGR.region_obtention as "agrementRegionObtention"
FROM
FRONT.EIG EIG
INNER JOIN FRONT.USER_ORGANISME UO ON EIG.USER_ID = UO.USE_ID
LEFT JOIN FRONT.AGREMENTS AGR on AGR.ORGANISME_ID = UO.ORG_ID
LEFT JOIN FRONT.EIG_TO_EIG_TYPE E2ET ON E2ET.EIG_ID = EIG.ID
LEFT JOIN FRONT.EIG_TYPE ET ON ET.ID = E2ET.EIG_TYPE_ID
LEFT JOIN FRONT.DEMANDE_SEJOUR DS ON DS.ID = EIG.DEMANDE_SEJOUR_ID
Expand All @@ -74,7 +78,8 @@ WHERE
GROUP BY
EIG.ID,
S.ID,
DS.ID
DS.ID,
AGR.ID
`,
getById: `
SELECT
Expand All @@ -83,6 +88,8 @@ EIG.ID,
S.STATUT AS "statut",
EIG.DEPARTEMENT AS "departement",
EIG.date as "date",
EIG.READ_BY_DREETS as "readByDreets",
EIG.READ_BY_DDETS as "readByDdets",
DS.ID AS "declarationId",
DS.ID_FONCTIONNELLE AS "idFonctionnelle",
DS.LIBELLE as "libelle",
Expand All @@ -104,8 +111,11 @@ EIG.ID,
EIG.DISPOSITION_INFORMATIONS as "dispositionInformations",
EIG.IS_ATTESTE as "isAtteste",
EIG.PERSONNEL as "personnel",
EIG.EMAIL_AUTRES_DESTINATAIRES as "emailAutresDestinataires"
EIG.EMAIL_AUTRES_DESTINATAIRES as "emailAutresDestinataires",
AGR.region_obtention as "agrementRegionObtention"
FROM FRONT.EIG EIG
INNER JOIN FRONT.USER_ORGANISME UO ON EIG.USER_ID = UO.USE_ID
LEFT JOIN FRONT.AGREMENTS AGR on AGR.ORGANISME_ID = UO.ORG_ID
LEFT JOIN FRONT.EIG_TO_EIG_TYPE E2ET ON E2ET.EIG_ID = EIG.ID
LEFT JOIN FRONT.EIG_TYPE ET ON ET.ID = E2ET.EIG_TYPE_ID
LEFT JOIN FRONT.EIG_CATEGORIE EC ON EC.ID = ET.EIG_CATEGORIE_ID
Expand All @@ -116,7 +126,8 @@ WHERE
GROUP BY
EIG.ID,
S.ID,
DS.ID;
DS.ID,
AGR.ID;
`,
getEmailByTerCode: `
WITH
Expand Down Expand Up @@ -161,20 +172,44 @@ WHERE
VALUES
${values.join(",")}
`,
markAsRead: `
markAsReadDdets: `
UPDATE FRONT.EIG
SET
STATUT_ID = (
SELECT
ID
FROM
FRONT.EIG_STATUT
WHERE
STATUT = 'LU'
)
READ_BY_DDETS = TRUE,
STATUT_ID = CASE
WHEN READ_BY_DREETS THEN (
SELECT
ID
FROM
FRONT.EIG_STATUT
WHERE
STATUT = 'LU'
)
ELSE STATUT_ID
END,
EDITED_AT = NOW()
WHERE
ID = $1
`,
markAsReadDreets: `
UPDATE FRONT.EIG
SET
READ_BY_DREETS = TRUE,
STATUT_ID = CASE
WHEN READ_BY_DDETS THEN (
SELECT
ID
FROM
FRONT.EIG_STATUT
WHERE
STATUT = 'LU'
)
ELSE STATUT_ID
END,
EDITED_AT = NOW()
WHERE
ID = $1
`,
updateDs: `
UPDATE FRONT.EIG
SET
Expand Down Expand Up @@ -580,9 +615,14 @@ module.exports.delete = async ({ eigId }) => {
return eigId;
};

module.exports.markAsRead = async (eigId) => {
log.i("updateStatut - IN", { eigId });
await pool.query(query.markAsRead, [eigId]);
log.i("updateStatut - DONE");
module.exports.markAsRead = async (eigId, type) => {
log.i("markAsReadDdets - IN", { eigId });
if (type === "DREETS") {
await pool.query(query.markAsReadDreets, [eigId]);
}
if (type === "DDETS") {
await pool.query(query.markAsReadDdets, [eigId]);
}
log.i("markAsReadDdets - DONE");
return eigId;
};
5 changes: 3 additions & 2 deletions packages/frontend-bo/src/components/demandes-sejour/eigs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</template>

<script setup>
import { eigModel, ValidationModal } from "@vao/shared";
import { ValidationModal } from "@vao/shared";
import dayjs from "dayjs";
const props = defineProps({
Expand All @@ -34,6 +34,7 @@ const props = defineProps({
});
const eigStore = useEigStore();
const userStore = useUserStore();
const getTitle = (eig) =>
`EIG ${eig.id} déposé le ${dayjs(eig.dateDepot).format("DD/MM/YYYY")} / statut : ${eig.statut}`;
Expand All @@ -60,7 +61,7 @@ const openModal = async (index) => {
return;
}
if (eig.statut === eigModel.Statuts.ENVOYE) {
if (utilsEig.mustMarkAsRead(eig, userStore.user)) {
expandedIndex.value = -1;
modalDetails.value = { eigId: eig.id, index };
} else {
Expand Down
22 changes: 13 additions & 9 deletions packages/frontend-bo/src/pages/eig/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@
<ValidationModal
modal-ref="modal-eig-list-consult"
name="consult-eig"
:opened="eigToRead != null"
:opened="eigIdToRead != null"
title="Consultation d’un EIG"
:on-close="closeEigModal"
:on-validate="() => readEig(eigToRead)"
:on-validate="() => readEig(eigIdToRead)"
>Vous vous apprêtez à consulter un Evènement Indésirable Grave. Cette
consultation enverra un email de notification à l’organisme.
</ValidationModal>
Expand All @@ -151,10 +151,11 @@ definePageMeta({
});
const departementStore = useDepartementStore();
const usersStore = useUserStore();
const eigStore = useEigStore();
const toaster = useToaster();
const eigStore = useEigStore();
const defaultLimit = 10;
const defaultOffset = 0;
Expand Down Expand Up @@ -319,9 +320,11 @@ const headers = [
{
column: "statut",
text: "Statut",
component: ({ statut }) => ({
component: ({ statut, readByDreets, readByDdets }) => ({
component: EigStatusBadge,
statut: statut,
statut,
readByDreets,
readByDdets,
}),
sort: true,
},
Expand Down Expand Up @@ -352,14 +355,15 @@ const readEig = async (id) => {
}
};
const eigToRead = ref(null);
const eigIdToRead = ref(null);
const openModal = (state) => {
if (eigStore.getStatut(state.id) === eigModel.Statuts.ENVOYE) {
eigToRead.value = state.id;
const eig = eigStore.getById(state.id);
if (utilsEig.mustMarkAsRead(eig, usersStore.user)) {
eigIdToRead.value = state.id;
} else {
navigateTo(`/eig/${state.id}`);
}
};
const closeEigModal = () => (eigToRead.value = null);
const closeEigModal = () => (eigIdToRead.value = null);
</script>
Loading

0 comments on commit 11ce26e

Please sign in to comment.