From c57407b6b3865a7c80d2a7d14f0ecdff480370b0 Mon Sep 17 00:00:00 2001 From: benjamin Date: Thu, 5 Dec 2024 15:51:10 +0100 Subject: [PATCH] feat(hebergement): add statut --- .../src/controllers/hebergement/activate.js | 69 ++++++ .../src/controllers/hebergement/get.js | 37 ++- .../src/controllers/hebergement/index.js | 2 + .../controllers/hebergement/post-brouillon.js | 11 +- .../src/controllers/hebergement/post.js | 10 +- .../hebergement/update-brouillon.js | 69 ++++++ .../src/controllers/hebergement/update.js | 2 +- .../checkPermissionBOHebergement.js | 38 ---- .../src/middlewares/checkStatutHebergement.js | 39 ++++ .../__tests__/hebergement/FU-getById.test.js | 7 +- .../hebergement/admin-getById.test.js | 7 +- .../routes/__tests__/hebergement/post.test.js | 8 +- .../__tests__/hebergement/update.test.js | 6 + packages/backend/src/routes/hebergement.js | 18 +- .../backend/src/services/DemandeSejour.js | 1 - .../src/services/hebergement/Hebergement.js | 210 +++++++++++++++--- .../src/services/hebergement/helpers.js | 3 +- .../src/components/DS/hebergements-sejour.vue | 2 + .../src/components/HebergementWithSave.vue | 15 +- .../pages/hebergements/[[hebergementId]].vue | 77 ++++++- .../src/pages/hebergements/liste.vue | 20 +- .../src/stores/hebergement.js | 30 ++- .../shared/src/components/Hebergement.vue | 134 +++++++---- 23 files changed, 645 insertions(+), 170 deletions(-) create mode 100644 packages/backend/src/controllers/hebergement/activate.js create mode 100644 packages/backend/src/controllers/hebergement/update-brouillon.js delete mode 100644 packages/backend/src/middlewares/checkPermissionBOHebergement.js create mode 100644 packages/backend/src/middlewares/checkStatutHebergement.js diff --git a/packages/backend/src/controllers/hebergement/activate.js b/packages/backend/src/controllers/hebergement/activate.js new file mode 100644 index 000000000..f6cb5f8ef --- /dev/null +++ b/packages/backend/src/controllers/hebergement/activate.js @@ -0,0 +1,69 @@ +const yup = require("yup"); +const logger = require("../../utils/logger"); +const ValidationAppError = require("../../utils/validation-error"); +const HebergementSchema = require("../../schemas/hebergement"); +const AppError = require("../../utils/error"); +const Hebergement = require("../../services/hebergement/Hebergement"); +const HebergementHelper = require("../../helpers/hebergement"); + +const log = logger(module.filename); + +module.exports = async function activate(req, res, next) { + const hebergementId = req.params.id; + const { body, decoded } = req; + const userId = decoded.id; + + const { nom, coordonnees, informationsLocaux, informationsTransport } = body; + + if ( + !nom || + !coordonnees || + !informationsLocaux || + !informationsTransport || + !hebergementId + ) { + log.w("missing or invalid parameter"); + + return next( + new AppError("Paramètre incorrect", { + statusCode: 400, + }), + ); + } + let hebergement; + + try { + hebergement = await yup.object(HebergementSchema.schema(false)).validate( + { + coordonnees, + informationsLocaux, + informationsTransport, + nom, + }, + { + abortEarly: false, + stripped: true, + }, + ); + } catch (error) { + return next(new ValidationAppError(error)); + } + + try { + await Hebergement.updateWithoutHistory( + userId, + hebergementId, + HebergementHelper.statuts.ACTIF, + hebergement, + ); + + log.i("DONE"); + return res.sendStatus(200); + } catch (error) { + if (error.cause === "archive") { + return next(new AppError(error)); + } + log.w("DONE with error"); + return next(error); + } +}; diff --git a/packages/backend/src/controllers/hebergement/get.js b/packages/backend/src/controllers/hebergement/get.js index bec42c7b9..df289a3e0 100644 --- a/packages/backend/src/controllers/hebergement/get.js +++ b/packages/backend/src/controllers/hebergement/get.js @@ -8,33 +8,30 @@ const log = logger(module.filename); module.exports = async function get(req, res) { log.i("IN"); const { id: userId } = req.decoded; + const search = req.query.search ? JSON.parse(req.query.search) : {}; let hebergements; - let searchByUserId = true; try { - const search = req.query.search ? JSON.parse(req.query.search) : {}; - if (search?.organismeId) { - const organismeUserConnected = await Organisme.getOne({ - use_id: userId, - }); - if (organismeUserConnected?.organismeId !== search.organismeId) { - // Si c'est l'organisme de l'utilisateur connecté on remonte tous les hébergements de cet utilisateur - searchByUserId = false; - const organismeSiege = await Organisme.getSiege( - organismeUserConnected.personneMorale.siret, + const organismeUserConnected = await Organisme.getOne({ + use_id: userId, + }); + const searchByUserId = + !search?.organismeId || + organismeUserConnected?.organismeId === search.organismeId; + if (!searchByUserId) { + const organismeSiege = await Organisme.getSiege( + organismeUserConnected.personneMorale.siret, + ); + // L'organisme Siege est bien le même organisme que l'utilisateur connecté + if (organismeSiege.organismeId === organismeUserConnected?.organismeId) { + hebergements = await Hebergement.getBySiren( + organismeSiege.personneMorale.siren, + search, ); - // L'organisme Siege est bien le même organisme que l'utilisateur connecté - if ( - organismeSiege.organismeId === organismeUserConnected?.organismeId - ) { - hebergements = await Hebergement.getBySiren( - organismeSiege.personneMorale.siren, - ); - } } } if (searchByUserId) { // Si c'est l'oganisme de l'utilisateur connecté on remonte tous les hébergements de cet utilisateur - hebergements = await Hebergement.getByUserId(userId); + hebergements = await Hebergement.getByUserId(userId, search); } log.d(hebergements); return res.status(200).json({ hebergements }); diff --git a/packages/backend/src/controllers/hebergement/index.js b/packages/backend/src/controllers/hebergement/index.js index cb1fada62..002577878 100644 --- a/packages/backend/src/controllers/hebergement/index.js +++ b/packages/backend/src/controllers/hebergement/index.js @@ -6,3 +6,5 @@ module.exports.getExtract = require("./getExtract"); module.exports.post = require("./post"); module.exports.postBrouillon = require("./post-brouillon"); module.exports.update = require("./update"); +module.exports.updateBrouillon = require("./update-brouillon"); +module.exports.activate = require("./activate"); diff --git a/packages/backend/src/controllers/hebergement/post-brouillon.js b/packages/backend/src/controllers/hebergement/post-brouillon.js index bc9e8417c..9d51bea21 100644 --- a/packages/backend/src/controllers/hebergement/post-brouillon.js +++ b/packages/backend/src/controllers/hebergement/post-brouillon.js @@ -4,7 +4,6 @@ const HebergementHelper = require("../../helpers/hebergement"); const HebergementSchema = require("../../schemas/hebergement"); const logger = require("../../utils/logger"); const ValidationAppError = require("../../utils/validation-error"); -const AppError = require("../../utils/error"); const FOUser = require("../../services/FoUser"); const log = logger(module.filename); @@ -37,10 +36,12 @@ module.exports = async function postbrouillon(req, res, next) { try { const organismeId = await FOUser.getUserOrganisme(userId); - const id = await Hebergement.create(userId, organismeId, { - ...hebergement, - statut: HebergementHelper.statuts.BROUILLON, - }); + const id = await Hebergement.create( + userId, + organismeId, + HebergementHelper.statuts.BROUILLON, + hebergement, + ); return res.status(200).json({ id, diff --git a/packages/backend/src/controllers/hebergement/post.js b/packages/backend/src/controllers/hebergement/post.js index 1d66da06e..418b8c586 100644 --- a/packages/backend/src/controllers/hebergement/post.js +++ b/packages/backend/src/controllers/hebergement/post.js @@ -47,10 +47,12 @@ module.exports = async function post(req, res, next) { try { const organismeId = await FOUser.getUserOrganisme(userId); - const id = await Hebergement.create(userId, organismeId, { - ...hebergement, - statut: HebergementHelper.statuts.ACTIF, - }); + const id = await Hebergement.create( + userId, + organismeId, + HebergementHelper.statuts.ACTIF, + hebergement, + ); return res.status(200).json({ id, diff --git a/packages/backend/src/controllers/hebergement/update-brouillon.js b/packages/backend/src/controllers/hebergement/update-brouillon.js new file mode 100644 index 000000000..10c94ab53 --- /dev/null +++ b/packages/backend/src/controllers/hebergement/update-brouillon.js @@ -0,0 +1,69 @@ +const yup = require("yup"); +const logger = require("../../utils/logger"); +const ValidationAppError = require("../../utils/validation-error"); +const HebergementSchema = require("../../schemas/hebergement"); +const AppError = require("../../utils/error"); +const Hebergement = require("../../services/hebergement/Hebergement"); +const HebergementHelper = require("../../helpers/hebergement"); + +const log = logger(module.filename); + +module.exports = async function updateBrouillon(req, res, next) { + const hebergementId = req.params.id; + const { body, decoded } = req; + const userId = decoded.id; + + const { nom, coordonnees, informationsLocaux, informationsTransport } = body; + + if ( + !nom || + !coordonnees || + !informationsLocaux || + !informationsTransport || + !hebergementId + ) { + log.w("missing or invalid parameter"); + + return next( + new AppError("Paramètre incorrect", { + statusCode: 400, + }), + ); + } + let hebergement; + + try { + hebergement = await yup.object(HebergementSchema.schema(true)).validate( + { + coordonnees, + informationsLocaux, + informationsTransport, + nom, + }, + { + abortEarly: false, + stripped: true, + }, + ); + } catch (error) { + return next(new ValidationAppError(error)); + } + + try { + await Hebergement.updateWithoutHistory( + userId, + hebergementId, + HebergementHelper.statuts.BROUILLON, + hebergement, + ); + + log.i("DONE"); + return res.sendStatus(200); + } catch (error) { + if (error.cause === "archive") { + return next(new AppError(error)); + } + log.w("DONE with error"); + return next(error); + } +}; diff --git a/packages/backend/src/controllers/hebergement/update.js b/packages/backend/src/controllers/hebergement/update.js index c8f7ad392..942efc72d 100644 --- a/packages/backend/src/controllers/hebergement/update.js +++ b/packages/backend/src/controllers/hebergement/update.js @@ -33,7 +33,7 @@ module.exports = async function post(req, res, next) { let hebergement; try { - hebergement = await yup.object(HebergementSchema.schema()).validate( + hebergement = await yup.object(HebergementSchema.schema(false)).validate( { coordonnees, informationsLocaux, diff --git a/packages/backend/src/middlewares/checkPermissionBOHebergement.js b/packages/backend/src/middlewares/checkPermissionBOHebergement.js deleted file mode 100644 index 3c9e12392..000000000 --- a/packages/backend/src/middlewares/checkPermissionBOHebergement.js +++ /dev/null @@ -1,38 +0,0 @@ -const logger = require("../utils/logger"); -const AppError = require("../utils/error"); -const Hebergement = require("../services/hebergement/Hebergement"); - -const log = logger(module.filename); - -async function checkPermissionHebergement(req, res, next) { - const { id: hebergementId } = req.params; - - if (!hebergementId) { - return next( - new AppError("Paramètres invalides", { - statusCode: 400, - }), - ); - } - - let statut; - - try { - statut = await Hebergement.getStatut(hebergementId); - } catch (error) { - log.w("DONE with error"); - return next(error); - } - - if (statut !== "actif") { - return next( - new AppError("Vous n'êtes pas autorisé à accéder à cet hébergement", { - statusCode: 403, - }), - ); - } - - next(); -} - -module.exports = checkPermissionHebergement; diff --git a/packages/backend/src/middlewares/checkStatutHebergement.js b/packages/backend/src/middlewares/checkStatutHebergement.js new file mode 100644 index 000000000..fd28e437f --- /dev/null +++ b/packages/backend/src/middlewares/checkStatutHebergement.js @@ -0,0 +1,39 @@ +const logger = require("../utils/logger"); +const AppError = require("../utils/error"); +const Hebergement = require("../services/hebergement/Hebergement"); + +const log = logger(module.filename); + +function checkStatutHebergement(statut) { + return async (req, res, next) => { + const { id: hebergementId } = req.params; + + if (!hebergementId) { + return next( + new AppError("Paramètres invalides", { + statusCode: 400, + }), + ); + } + + let hebergementStatut; + try { + hebergementStatut = await Hebergement.getStatut(hebergementId); + } catch (error) { + log.w("DONE with error"); + return next(error); + } + + if (statut !== hebergementStatut) { + return next( + new AppError("Vous n'êtes pas autorisé à accéder à cet hébergement", { + statusCode: 403, + }), + ); + } + + next(); + }; +} + +module.exports = checkStatutHebergement; diff --git a/packages/backend/src/routes/__tests__/hebergement/FU-getById.test.js b/packages/backend/src/routes/__tests__/hebergement/FU-getById.test.js index 8467bf1dd..5c99a8769 100644 --- a/packages/backend/src/routes/__tests__/hebergement/FU-getById.test.js +++ b/packages/backend/src/routes/__tests__/hebergement/FU-getById.test.js @@ -8,7 +8,12 @@ const checkPermissionHebergement = require("../../../middlewares/checkPermission jest.mock("../../../services/hebergement/Hebergement"); jest.mock("../../../middlewares/checkJWT"); jest.mock("../../../middlewares/checkPermissionHebergement"); - +jest.mock( + "../../../middlewares/checkStatutHebergement", + () => () => (req, res, next) => { + next(); + }, +); describe("GET /hebergement/:id", () => { const user = { id: 1, diff --git a/packages/backend/src/routes/__tests__/hebergement/admin-getById.test.js b/packages/backend/src/routes/__tests__/hebergement/admin-getById.test.js index 6f111caeb..3e124eee8 100644 --- a/packages/backend/src/routes/__tests__/hebergement/admin-getById.test.js +++ b/packages/backend/src/routes/__tests__/hebergement/admin-getById.test.js @@ -8,7 +8,12 @@ const checkPermissionHebergement = require("../../../middlewares/checkPermission jest.mock("../../../services/hebergement/Hebergement"); jest.mock("../../../middlewares/bo-check-JWT"); jest.mock("../../../middlewares/checkPermissionHebergement"); - +jest.mock( + "../../../middlewares/checkStatutHebergement", + () => () => (req, res, next) => { + next(); + }, +); describe("GET /hebergement/admin/:id", () => { const user = { id: 1, diff --git a/packages/backend/src/routes/__tests__/hebergement/post.test.js b/packages/backend/src/routes/__tests__/hebergement/post.test.js index 22407c6d5..021e3fd38 100644 --- a/packages/backend/src/routes/__tests__/hebergement/post.test.js +++ b/packages/backend/src/routes/__tests__/hebergement/post.test.js @@ -12,7 +12,12 @@ jest.mock("../../../middlewares/checkJWT"); jest.mock("../../../middlewares/checkPermissionHebergement"); jest.mock("../../../schemas/hebergement"); jest.mock("../../../services/FoUser"); - +jest.mock( + "../../../middlewares/checkStatutHebergement", + () => () => (req, res, next) => { + next(); + }, +); describe("POST /", () => { const user = { id: 1, @@ -58,6 +63,7 @@ describe("POST /", () => { expect(Hebergement.create).toHaveBeenCalledWith( 1, 1, + "actif", expect.objectContaining(body), ); }); diff --git a/packages/backend/src/routes/__tests__/hebergement/update.test.js b/packages/backend/src/routes/__tests__/hebergement/update.test.js index aae81ef44..132b3c8d3 100644 --- a/packages/backend/src/routes/__tests__/hebergement/update.test.js +++ b/packages/backend/src/routes/__tests__/hebergement/update.test.js @@ -9,6 +9,12 @@ const yup = require("yup"); jest.mock("../../../services/hebergement/Hebergement"); jest.mock("../../../middlewares/checkJWT"); jest.mock("../../../middlewares/checkPermissionHebergement"); +jest.mock( + "../../../middlewares/checkStatutHebergement", + () => () => (req, res, next) => { + next(); + }, +); jest.mock("../../../schemas/hebergement"); describe("POST /:id", () => { diff --git a/packages/backend/src/routes/hebergement.js b/packages/backend/src/routes/hebergement.js index b99d7363d..6378c68d4 100644 --- a/packages/backend/src/routes/hebergement.js +++ b/packages/backend/src/routes/hebergement.js @@ -5,9 +5,10 @@ const router = express.Router(); const checkJWT = require("../middlewares/checkJWT"); const boCheckJWT = require("../middlewares/bo-check-JWT"); const checkPermissionHebergement = require("../middlewares/checkPermissionHebergement"); -const checkPermissionBOHebergement = require("../middlewares/checkPermissionBOHebergement"); +const checkStatutHebergement = require("../middlewares/checkStatutHebergement"); const getDepartements = require("../middlewares/getDepartements"); const hebergementController = require("../controllers/hebergement"); +const HebergementHelper = require("../helpers/hebergement"); router.get( "/admin/", @@ -31,16 +32,29 @@ router.get( router.get( "/admin/:id", boCheckJWT, - checkPermissionBOHebergement, + checkStatutHebergement(HebergementHelper.statuts.ACTIF), hebergementController.getById, ); router.get("/siren/:siren", checkJWT, hebergementController.getBySiren); router.get("/", checkJWT, hebergementController.get); router.post("/", checkJWT, hebergementController.post); router.post("/brouillon", checkJWT, hebergementController.postBrouillon); +router.put( + "/:id/brouillon", + checkJWT, + checkStatutHebergement(HebergementHelper.statuts.BROUILLON), + hebergementController.updateBrouillon, +); +router.put( + "/:id/activate", + checkJWT, + checkStatutHebergement(HebergementHelper.statuts.BROUILLON), + hebergementController.activate, +); router.post( "/:id", checkJWT, + checkStatutHebergement(HebergementHelper.statuts.ACTIF), checkPermissionHebergement, hebergementController.update, ); diff --git a/packages/backend/src/services/DemandeSejour.js b/packages/backend/src/services/DemandeSejour.js index 79c8a654d..76589a58e 100644 --- a/packages/backend/src/services/DemandeSejour.js +++ b/packages/backend/src/services/DemandeSejour.js @@ -1390,7 +1390,6 @@ module.exports.update = async (type, declarationId, parametre) => { const client = await pool.connect(); try { await client.query("BEGIN"); - console.log(parametre); await linkToHebergements(client, declarationId, parametre.hebergements); response = await client.query(query.updateHebergement, [ parametre, diff --git a/packages/backend/src/services/hebergement/Hebergement.js b/packages/backend/src/services/hebergement/Hebergement.js index 3b060c0ff..9cc13509c 100644 --- a/packages/backend/src/services/hebergement/Hebergement.js +++ b/packages/backend/src/services/hebergement/Hebergement.js @@ -27,6 +27,11 @@ ${new Array(nbRows) ) .join(",")} `, + removePrestationsHoteliere: ` + DELETE FROM front.hebergement_to_prestations_hotelieres + WHERE + hebergement_id = $1; + `, create: ` INSERT INTO front.hebergement( organisme_id, @@ -116,6 +121,48 @@ ${new Array(nbRows) ) RETURNING id `, + update: ` + UPDATE front.hebergement + SET + edited_by = $2, + edited_at = NOW(), + nom = $3, + coordonnees = $4, + informations_locaux = $5, + informations_transport = $6, + email = $7, + adresse_id = $8, + telephone_1 = $9, + telephone_2 = $10, + nom_gestionnaire = $11, + type_id = (SELECT id FROM front.hebergement_type WHERE value = $12), + type_pension_id = (SELECT id FROM front.hebergement_type_pension WHERE value = $13), + nombre_lits = $14, + lit_dessus = $15, + nombre_lits_superposes = $16, + nombre_max_personnes_couchage = $17, + visite_locaux = $18, + accessibilite_id = (SELECT id FROM front.hebergement_accessibilite WHERE value = $19), + chambres_doubles = $20, + chambres_unisexes = $21, + reglementation_erp = $22, + couchage_individuel = $23, + rangement_individuel = $24, + amenagements_specifiques = $25, + description_lieu_hebergement = $26, + excursion_description = $27, + deplacement_proximite_description = $28, + vehicules_adaptes = $29, + file_reponse_exploitant_ou_proprietaire = $30, + file_dernier_arrete_autorisation_maire = $31, + file_derniere_attestation_securite = $32, + visite_locaux_at = $33, + accessibilite_precision = $34, + amenagements_specifiques_precision = $35, + statut_id = (SELECT id FROM front.hebergement_statut WHERE value = $36) + WHERE + id = $1 + `, getByDSId: ` SELECT ID as "hebergementId", @@ -200,10 +247,12 @@ ${new Array(nbRows) a.label as adresse, h.supprime, h.created_at as "createdAt", - h.edited_at as "editedAt" + h.edited_at as "editedAt", + hs.value as "statut" FROM front.hebergement h JOIN front.organismes o ON h.organisme_id = o.id LEFT JOIN front.adresse a on a.id = h.adresse_id + LEFT JOIN front.hebergement_statut hs on hs.id = h.statut_id WHERE o.personne_morale->>'siren' = $1 `, getByUserId: ` @@ -211,40 +260,34 @@ ${new Array(nbRows) h.id as "id", nom as "nom", a.label as "adresse", - a.departement as "departement" + a.departement as "departement", + hs.value as "statut" FROM front.hebergement h LEFT JOIN front.user_organisme uo ON uo.org_id = h.organisme_id LEFT JOIN front.adresse a ON a.id = h.adresse_id + LEFT JOIN front.hebergement_statut hs on hs.id = h.statut_id WHERE uo.use_id = $1 AND CURRENT IS TRUE `, getPreviousValueForHistory: ` SELECT - HEBERGEMENT_ID AS "hebergementUuid", - ORGANISME_ID as "organismeId", - CREATED_BY as "createdBy", - CREATED_AT as "createdAt", - CURRENT as "current" + h.hebergement_id AS "hebergementUuid", + h.organisme_id AS "organismeId", + h.created_by AS "createdBy", + h.created_at AS "createdAt", + h.current AS "current", + hs.value AS "statut" FROM - FRONT.HEBERGEMENT + front.hebergement h + LEFT JOIN front.hebergement_statut hs ON hs.id = h.statut_id WHERE - ID = $1; + h.id = $1; `, historize: ` UPDATE front.hebergement SET current = FALSE WHERE id = $1 `, - update: ` - UPDATE front.hebergement - SET - nom = $2, - coordonnees = $3, - informations_locaux = $4, - informations_transport = $5, - edited_at = NOW() - WHERE id = $1 - `, getStatut: ` SELECT value AS "statut" @@ -272,12 +315,10 @@ ${new Array(nbRows) */ const create = async ( client, - { createdBy, createdAt, updatedBy, organismeId }, - { nom, coordonnees, informationsLocaux, informationsTransport, statut }, + { createdBy, createdAt, updatedBy, organismeId, statut }, + { nom, coordonnees, informationsLocaux, informationsTransport }, hebergemenetUuid, ) => { - console.log("tototot", coordonnees); - const adresseId = coordonnees.adresse ? await saveAdresse(client, coordonnees.adresse) : null; @@ -326,7 +367,6 @@ const create = async ( const hebergementId = rows[0].id; const prestationsHotelieres = informationsLocaux.prestationsHotelieres; - console.log(prestationsHotelieres); if (prestationsHotelieres.length > 0) { await client.query( query.associatePrestation(prestationsHotelieres.length), @@ -337,7 +377,7 @@ const create = async ( return hebergementId; }; -module.exports.create = async (userId, organismeId, hebergement) => { +module.exports.create = async (userId, organismeId, statut, hebergement) => { const client = await pool.connect(); let hebergementId; @@ -349,6 +389,7 @@ module.exports.create = async (userId, organismeId, hebergement) => { createdAt: new Date(), createdBy: userId, organismeId, + statut, updatedBy: userId, }, hebergement, @@ -364,9 +405,87 @@ module.exports.create = async (userId, organismeId, hebergement) => { return hebergementId; }; +// Utilisée par exemple lorsque l'on modifie un hebergement en statut brouillon +module.exports.updateWithoutHistory = async ( + userId, + hebergementId, + statut, + hebergement, +) => { + const { nom, coordonnees, informationsLocaux, informationsTransport } = + hebergement; + + const client = await pool.connect(); + + try { + await client.query("BEGIN"); + const adresseId = coordonnees.adresse + ? await saveAdresse(client, coordonnees.adresse) + : null; + await client.query(query.update, [ + hebergementId, + userId, + nom, + coordonnees, + informationsLocaux, + informationsTransport, + coordonnees.email, + adresseId, + coordonnees.numTelephone1, + coordonnees.numTelephone2, + coordonnees.nomGestionnaire, + informationsLocaux.type, + informationsLocaux.pension, + informationsLocaux.nombreLits, + informationsLocaux.litsDessus, + informationsLocaux.nombreLitsSuperposes, + informationsLocaux.nombreMaxPersonnesCouchage, + informationsLocaux.visiteLocaux, + informationsLocaux.accessibilite, + informationsLocaux.chambresDoubles, + informationsLocaux.chambresUnisexes, + informationsLocaux.reglementationErp, + informationsLocaux.couchageIndividuel, + informationsLocaux.rangementIndividuel, + informationsLocaux.amenagementsSpecifiques, + informationsLocaux.descriptionLieuHebergement, + informationsTransport.excursion, + informationsTransport.deplacementProximite, + informationsTransport.vehiculesAdaptes, + informationsLocaux.fileReponseExploitantOuProprietaire?.uuid ?? null, + informationsLocaux.fileDernierArreteAutorisationMaire?.uuid ?? null, + informationsLocaux.fileDerniereAttestationSecurite?.uuid ?? null, + informationsLocaux.visiteLocauxAt, + informationsLocaux.accessibilitePrecision, + informationsLocaux.precisionAmenagementsSpecifiques, + statut, + ]); + + await client.query(query.removePrestationsHoteliere, [hebergementId]); + const prestationsHotelieres = informationsLocaux.prestationsHotelieres; + if (prestationsHotelieres.length > 0) { + await client.query( + query.associatePrestation(prestationsHotelieres.length), + [hebergementId, ...prestationsHotelieres], + ); + } + + await client.query("COMMIT"); + } catch (error) { + await client.query("ROLLBACK"); + throw error; + } finally { + client.release(); + } + + return hebergementId; +}; + module.exports.update = async (userId, hebergementId, hebergement) => { const { - rows: [{ hebergementUuid, organismeId, createdBy, createdAt, current }], + rows: [ + { hebergementUuid, organismeId, createdBy, createdAt, current, statut }, + ], } = await pool.query(query.getPreviousValueForHistory, [hebergementId]); const client = await pool.connect(); @@ -386,6 +505,7 @@ module.exports.update = async (userId, hebergementId, hebergement) => { createdAt, createdBy, organismeId, + statut, updatedBy: userId, }, hebergement, @@ -412,17 +532,39 @@ module.exports.getByDepartementCodes = async (departementsCodes, params) => { return rows[0]; }; -module.exports.getByUserId = async (userId) => { +module.exports.getByUserId = async (userId, search) => { log.i("getByUserId - IN", { userId }); - const response = await pool.query(query.getByUserId, [userId]); + + let queryGet = query.getByUserId; + const params = [userId]; + if (search.statut) { + queryGet = ` + ${queryGet} + AND h.statut_id = (SELECT id FROM front.hebergement_statut WHERE value = $2) + `; + params.push(search.statut); + } + + const response = await pool.query(queryGet, params); log.d("getByUserId - DONE"); const hebergements = response.rows; return hebergements; }; -module.exports.getBySiren = async (siren) => { +module.exports.getBySiren = async (siren, search) => { log.i("getBySiren - IN", { siren }); - const response = await pool.query(query.getBySiren, [siren]); + + let queryGet = query.getBySiren; + const params = [siren]; + if (search.statut) { + queryGet = ` + ${queryGet} + AND h.statut_id = (SELECT id FROM front.hebergement_statut WHERE value = $2) + `; + params.push(search.statut); + } + + const response = await pool.query(queryGet, params); log.d("getBySiren - DONE"); return response.rows; }; @@ -447,11 +589,11 @@ module.exports.getById = async (id) => { if (rowCount === 0) { return null; } + const hebergement = hebergements[0]; - const adresse = - hebergement.adresseId ?? - (await getAdressById(hebergement.adresseId)) ?? - null; + const adresse = hebergement.adresseId + ? await getAdressById(hebergement.adresseId) + : null; log.d("getById - DONE"); return await mapDBHebergement(hebergement, adresse); diff --git a/packages/backend/src/services/hebergement/helpers.js b/packages/backend/src/services/hebergement/helpers.js index b5bae82a2..56ea591a7 100644 --- a/packages/backend/src/services/hebergement/helpers.js +++ b/packages/backend/src/services/hebergement/helpers.js @@ -51,7 +51,7 @@ module.exports.queryGetFields = ` H.DEPLACEMENT_PROXIMITE_DESCRIPTION AS "deplacementProximiteDescription", H.VEHICULES_ADAPTES AS "vehiculesAdaptes", H.FILE_REPONSE_EXPLOITANT_OU_PROPRIETAIRE AS "fileReponseExploitantOuProprietaire", - H.FILE_DERNIER_ARRETE_AUTORISATION_MAIRE AS "fileDernierArreteAutorisationMaire", + H.file_dernier_arrete_autorisation_maire AS "fileDernierArreteAutorisationMaire", H.FILE_DERNIERE_ATTESTATION_SECURITE AS "fileDerniereAttestationSecurite", ( SELECT @@ -66,6 +66,7 @@ module.exports.queryGetFields = ` `; const mapHebergementToCoordonnees = (hebergement, adresse) => { + console.log("adresse", adresse); return { adresse: adresse ? { diff --git a/packages/frontend-usagers/src/components/DS/hebergements-sejour.vue b/packages/frontend-usagers/src/components/DS/hebergements-sejour.vue index 5a9a38f0e..48ae33848 100644 --- a/packages/frontend-usagers/src/components/DS/hebergements-sejour.vue +++ b/packages/frontend-usagers/src/components/DS/hebergements-sejour.vue @@ -84,6 +84,7 @@ import { DsfrButtonGroup } from "@gouvminint/vue-dsfr"; import { useField, useForm } from "vee-validate"; import dayjs from "dayjs"; +import { hebergement as hebergementUtils } from "@vao/shared"; const toaster = useToaster(); @@ -141,6 +142,7 @@ const { value: hebergements, handleChange: onHebergementsChange } = hebergementStore.fetch({ organismeId: demandeSejourStore.demandeCourante.organismeId, + statut: hebergementUtils.statut.ACTIF, }); const syntheseRows = computed(() => { diff --git a/packages/frontend-usagers/src/components/HebergementWithSave.vue b/packages/frontend-usagers/src/components/HebergementWithSave.vue index b7cf2408b..7ca607a8b 100644 --- a/packages/frontend-usagers/src/components/HebergementWithSave.vue +++ b/packages/frontend-usagers/src/components/HebergementWithSave.vue @@ -7,8 +7,11 @@ :message="props.message" :is-save-visible="props.isSaveVisible" :default-back-route="props.defaultBackRoute" + :mode-brouillon-activated="props.modeBrouillonActivated" :cdn-url="props.cdnUrl" @submit="submit" + @submit-brouillon="submitBrouillon" + @activate="activate" @cancel="cancel" > diff --git a/packages/frontend-usagers/src/stores/hebergement.js b/packages/frontend-usagers/src/stores/hebergement.js index e0270ce6c..2d73ac0dd 100644 --- a/packages/frontend-usagers/src/stores/hebergement.js +++ b/packages/frontend-usagers/src/stores/hebergement.js @@ -1,5 +1,5 @@ import { defineStore } from "pinia"; -import { logger, $fetchBackend } from "#imports"; +import { $fetchBackend, logger } from "#imports"; import UploadFile from "~/utils/UploadFile"; const log = logger("stores/hebergement"); @@ -78,7 +78,35 @@ export const useHebergementStore = defineStore("hebergement", { log.i("updateOrCreate - Done", { id }); return id ?? hebergementId; }, + async updateOrCreateBrouillon(hebergement, hebergementId) { + log.i("updateOrCreate - IN", { hebergement }); + + const url = hebergementId + ? `/hebergement/${hebergementId}/brouillon` + : `/hebergement/brouillon`; + + const { id } = await $fetchBackend(url, { + method: hebergementId ? "PUT" : "POST", + body: hebergement, + credentials: "include", + }); + log.i("updateOrCreate - Done", { id }); + return id ?? hebergementId; + }, + async activate(hebergement, hebergementId) { + log.i("updateOrCreate - IN", { hebergement }); + const { id } = await $fetchBackend( + `/hebergement/${hebergementId}/activate`, + { + method: "PUT", + body: hebergement, + credentials: "include", + }, + ); + log.i("updateOrCreate - Done", { id }); + return id ?? hebergementId; + }, async updaloadFiles(hebergement) { if (hebergement.informationsLocaux.reglementationErp) { const fileDAS = diff --git a/packages/shared/src/components/Hebergement.vue b/packages/shared/src/components/Hebergement.vue index 3b2030e7d..dc6ee6a0a 100644 --- a/packages/shared/src/components/Hebergement.vue +++ b/packages/shared/src/components/Hebergement.vue @@ -522,45 +522,55 @@ @update:model-value="onExcursionChange" /> -
-
-
-
- - Retour - -
-
-
-
- Enregistrer en mode brouillon - - -
-
- {{ labelNext }} - - -
-
+
+ + Retour + +
+ Enregistrer le brouillon + + Activer l'hebergement + + {{ + hebergementId ? "Modifier l'hebergement" : "Ajouter l'hebergement" + }} +
+
@@ -583,7 +593,7 @@ import createLogger from "../utils/createLogger"; const toaster = useToaster(); -const emit = defineEmits(["cancel", "submit"]); +const emit = defineEmits(["cancel", "submit", "submit-brouillon", "activate"]); const ouiNonOptions = [ { @@ -602,12 +612,12 @@ const props = defineProps({ default: () => ({}), }, isDisabled: { type: Boolean, default: false }, - labelNext: { type: String, default: "Ajouter hébergement" }, isDownloading: { type: Boolean, default: false }, message: { type: String, required: false, default: null }, isSaveVisible: { type: Boolean, default: false }, defaultBackRoute: { type: String, required: true }, cdnUrl: { type: String, required: true }, + modeBrouillonActivated: { type: Boolean, default: false }, }); const logger = createLogger("vao-shared"); @@ -615,6 +625,9 @@ const log = logger("components/hebergement"); const validationSchema = yup.object(hebergementUtils.schema); +const hebergementId = computed(() => props.initHebergement.id); +const hebergementStatut = computed(() => props.initHebergement.statut); + const initialValues = { nom: props.initHebergement.nom ?? null, coordonnees: { @@ -866,13 +879,8 @@ function verifFormatFile(file, toasterMessage) { } } -function submitBrouillon() { - emit("submit", { ...toRaw(values) }); -} - -function submit() { - // Vérification du format des fichiers avant enregistrement - if ( +const formatFilesOk = computed( + () => (reglementationErp.value === true && verifFormatFile( fileDernierArreteAutorisationMaire, @@ -886,8 +894,22 @@ function submit() { verifFormatFile( fileReponseExploitantOuProprietaire, "La réponse de l'exploitant/propriétaire", - )) - ) { + )), +); + +function activate() { + if (formatFilesOk.value) { + emit("activate", { ...toRaw(values) }); + } +} + +function submitBrouillon() { + emit("submit-brouillon", { ...toRaw(values) }); +} + +function submit() { + // Vérification du format des fichiers avant enregistrement + if (formatFilesOk.value) { log.i("submit", { ...toRaw(values) }); emit("submit", { ...toRaw(values) }); } @@ -898,4 +920,18 @@ function submit() { .back-button { background-image: none; } + +.button-container { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0.5rem; +} + +.crud-button-container { + display: flex; + align-items: center; + justify-content: center; + gap: 1rem; +}