diff --git a/packages/backend/src/controllers/hebergement/post.js b/packages/backend/src/controllers/hebergement/post.js index 38c11be8f..37ae6c5bf 100644 --- a/packages/backend/src/controllers/hebergement/post.js +++ b/packages/backend/src/controllers/hebergement/post.js @@ -4,6 +4,7 @@ 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); @@ -44,11 +45,12 @@ module.exports = async function post(req, res, next) { } try { - const id = await Hebergement.create(userId, hebergement); + const organismeId = await FOUser.getUserOrganisme(userId); + const id = await Hebergement.create(userId, organismeId, hebergement); return res.status(200).json({ id, - message: "sauvegarde organisme OK", + message: "sauvegarde hebegement OK", }); } catch (error) { log.w("DONE with error"); diff --git a/packages/backend/src/controllers/hebergement/update.js b/packages/backend/src/controllers/hebergement/update.js index c400233a6..e782005bc 100644 --- a/packages/backend/src/controllers/hebergement/update.js +++ b/packages/backend/src/controllers/hebergement/update.js @@ -10,15 +10,10 @@ const log = logger(module.filename); module.exports = async function post(req, res, next) { const hebergementId = req.params.id; - const { nom, coordonnees, informationsLocaux, informationsTransport } = - req.body; - log.i("IN", { - coordonnees, - hebergementId, - informationsLocaux, - informationsTransport, - nom, - }); + const { body, decoded } = req; + const userId = decoded.id; + + const { nom, coordonnees, informationsLocaux, informationsTransport } = body; if ( !nom || @@ -36,6 +31,7 @@ module.exports = async function post(req, res, next) { ); } let hebergement; + try { hebergement = await yup.object(HebergementSchema.schema()).validate( { @@ -54,7 +50,7 @@ module.exports = async function post(req, res, next) { } try { - await Hebergement.update(hebergementId, hebergement); + await Hebergement.update(userId, hebergementId, hebergement); log.i("DONE"); return res.sendStatus(200); } catch (error) { diff --git a/packages/backend/src/schemas/parts/adresse.js b/packages/backend/src/schemas/parts/adresse.js index 0d2c8a87f..0710558de 100644 --- a/packages/backend/src/schemas/parts/adresse.js +++ b/packages/backend/src/schemas/parts/adresse.js @@ -3,6 +3,7 @@ const yup = require("yup"); const schema = ({ isFromAPIAdresse } = {}) => { return isFromAPIAdresse ? { + cleInsee: yup.string().nullable(true), codeInsee: yup.string().required("ce champ est obligatoire"), codePostal: yup.string().required("ce champ est obligatoire"), coordinates: yup.array().required("ce champ est obligatoire"), diff --git a/packages/backend/src/services/DemandeSejour.js b/packages/backend/src/services/DemandeSejour.js index 119d6e05b..6ea205643 100644 --- a/packages/backend/src/services/DemandeSejour.js +++ b/packages/backend/src/services/DemandeSejour.js @@ -797,6 +797,38 @@ WHERE RETURNING id as "declarationId" `, + unlinkToHebergement: ` +DELETE FROM FRONT.DEMANDE_SEJOUR_TO_HEBERGEMENT +WHERE + DEMANDE_SEJOUR_ID = $1; + `, + linkToHebergements: (nbRows) => ` +INSERT INTO + FRONT.DEMANDE_SEJOUR_TO_HEBERGEMENT ( + DEMANDE_SEJOUR_ID, + HEBERGEMENT_ID, + DATE_DEBUT, + DATE_FIN + ) +VALUES +${new Array(nbRows) + .fill(null) + .map( + (_, index) => + `($1, $${3 * index + 2}, $${3 * index + 3}, $${3 * index + 4})`, + ) + .join(",")} + `, +}; + +const linkToHebergements = async (client, declarationId, hebergements) => { + await client.query(query.unlinkToHebergement, [declarationId]); + if (hebergements.length > 0) { + await client.query(query.linkToHebergements(hebergements.length), [ + declarationId, + ...hebergements.flatMap((h) => [h.hebergementId, h.dateDebut, h.dateFin]), + ]); + } }; module.exports.create = async ({ @@ -841,33 +873,50 @@ module.exports.create = async ({ module.exports.copy = async (declaration) => { log.i("copy - IN"); - const response = await pool.query( - ...query.copy( - declaration.organismeId, - `COPIE - ${declaration.libelle}`, - declaration.dateDebut, - declaration.dateFin, - declaration.duree, - declaration.periode, - declaration.responsableSejour, - declaration.organisme, - declaration.hebergement, - declaration.informationsVacanciers, - declaration.informationsPersonnel, - declaration.informationsTransport, - declaration.projetSejour, - declaration.informationsSanitaires, - declaration.files, - ), - ); - log.d(response); - const { declarationId } = response.rows[0]; + const client = await pool.connect(); + let declarationId; + try { + await client.query("BEGIN"); + const response = await client.query( + ...query.copy( + declaration.organismeId, + `COPIE - ${declaration.libelle}`, + declaration.dateDebut, + declaration.dateFin, + declaration.duree, + declaration.periode, + declaration.responsableSejour, + declaration.organisme, + declaration.hebergement, + declaration.informationsVacanciers, + declaration.informationsPersonnel, + declaration.informationsTransport, + declaration.projetSejour, + declaration.informationsSanitaires, + declaration.files, + ), + ); + log.d(response); + declarationId = response.rows[0].declarationId; + await linkToHebergements( + client, + declarationId, + declaration.hebergement?.hebergements ?? [], + ); + await client.query("COMMIT"); + } catch (error) { + await client.query("ROLLBACK"); + throw error; + } finally { + client.release(); + } log.i("copy - DONE", { declarationId }); return declarationId; }; module.exports.delete = async (declarationId, userId) => { log.i("delete - IN"); + await pool.query(query.unlinkToHebergement, [declarationId]); const { rowCount } = await pool.query(...query.delete(declarationId, userId)); log.i("delete - DONE"); return rowCount; @@ -1182,10 +1231,21 @@ module.exports.update = async (type, declarationId, parametre) => { } case "hebergements": { log.d("hebergements", declarationId); - response = await pool.query(query.updateHebergement, [ - parametre, - declarationId, - ]); + const client = await pool.connect(); + try { + await client.query("BEGIN"); + await linkToHebergements(client, declarationId, parametre.hebergements); + response = await client.query(query.updateHebergement, [ + parametre, + declarationId, + ]); + await client.query("COMMIT"); + } catch (error) { + await client.query("ROLLBACK"); + throw error; + } finally { + client.release(); + } break; } default: diff --git a/packages/backend/src/services/FoUser.js b/packages/backend/src/services/FoUser.js index 3198f23bb..2ad922954 100644 --- a/packages/backend/src/services/FoUser.js +++ b/packages/backend/src/services/FoUser.js @@ -47,6 +47,7 @@ ${additionalParamsQuery} `, additionalParams, ], + getUserOragnisme: `SELECT org_id as "organismeId" FROM front.user_organisme WHERE use_id = $1`, }; module.exports.read = async ({ @@ -150,3 +151,8 @@ module.exports.readOne = async (id) => { log.i("readOne - DONE"); return users[0]; }; + +module.exports.getUserOrganisme = async (userId) => { + const { rows } = await pool.query(query.getUserOragnisme, [userId]); + return rows[0]?.organismeId ?? null; +}; diff --git a/packages/backend/src/services/Hebergement.js b/packages/backend/src/services/Hebergement.js index ee9234dbc..d4f0b2770 100644 --- a/packages/backend/src/services/Hebergement.js +++ b/packages/backend/src/services/Hebergement.js @@ -1,6 +1,6 @@ /* eslint-disable no-param-reassign */ -const AppError = require("../utils/error"); const logger = require("../utils/logger"); +const { saveAdresse } = require("./adresse"); const pool = require("../utils/pgpool").getPool(); const log = logger(module.filename); @@ -9,24 +9,102 @@ const query = { create: ` INSERT INTO front.hebergement( organisme_id, + CREATED_BY, + EDITED_BY, + created_at, + edited_at, + HEBERGEMENT_ID, + CURRENT, nom, coordonnees, informations_locaux, informations_transport, - created_at, - edited_at + EMAIL, + ADRESSE_ID, + TELEPHONE_1, + TELEPHONE_2, + NOM_GESTIONNAIRE, + TYPE_ID, + TYPE_PENSION_ID, + NOMBRE_LITS, + LIT_DESSUS, + NOMBRE_LITS_SUPERPOSES, + NOMBRE_MAX_PERSONNES_COUCHAGE, + VISITE_LOCAUX, + ACCESSIBILITE_ID, + CHAMBRES_DOUBLES, + CHAMBRES_UNISEXES, + REGLEMENTATION_ERP, + COUCHAGE_INDIVIDUEL, + RANGEMENT_INDIVIDUEL, + AMENAGEMENTS_SPECIFIQUES, + DESCRIPTION_LIEU_HEBERGEMENT, + EXCURSION_DESCRIPTION, + DEPLACEMENT_PROXIMITE_DESCRIPTION, + VEHICULES_ADAPTES, + FILE_REPONSE_EXPLOITANT_OU_PROPRIETAIRE, + FILE_DERNIER_ARRETE_AUTORISATION_MAIRE, + FILE_DERNIERE_ATTESTATION_SECURITE, + VISITE_LOCAUX_AT, + ACCESSIBILITE_PRECISION, + AMENAGEMENTS_SPECIFIQUES_PRECISION ) VALUES ( - (SELECT org_id FROM front.user_organisme WHERE use_id = $1), - $2, - $3, - $4, - $5, - NOW(), - NOW() + $1, --organisme_id, + $2, --CREATED_BY, + $3, --EDITED_BY, + $4, --created_at, + NOW(), --edited_at, + $5, --HEBERGEMENT_ID, + TRUE, --CURRENT, + $6, --nom, + $7, --coordonnees, + $8, --informations_locaux, + $9, --informations_transport, + $10, --EMAIL, + $11, --ADRESSE_ID, + $12, --TELEPHONE_1, + $13, --TELEPHONE_2, + $14, --NOM_GESTIONNAIRE, + (SELECT ID FROM FRONT.HEBERGEMENT_TYPE WHERE VALUE = $15), --TYPE_ID, + (SELECT ID FROM FRONT.HEBERGEMENT_TYPE_PENSION WHERE VALUE = $16), --TYPE_PENSION_ID, + $17, --NOMBRE_LITS, + $18, --LIT_DESSUS, + $19, --NOMBRE_LITS_SUPERPOSES, + $20, --NOMBRE_MAX_PERSONNES_COUCHAGE, + $21, --VISITE_LOCAUX, + (SELECT ID FROM FRONT.HEBERGEMENT_ACCESSIBILITE WHERE VALUE = $22), --ACCESSIBILITE_ID, + $23, --CHAMBRES_DOUBLES, + $24, --CHAMBRES_UNISEXES, + $25, --REGLEMENTATION_ERP, + $26, --COUCHAGE_INDIVIDUEL, + $27, --RANGEMENT_INDIVIDUEL, + $28, --AMENAGEMENTS_SPECIFIQUES, + $29, --DESCRIPTION_LIEU_HEBERGEMENT, + $30, --EXCURSION_DESCRIPTION, + $31, --DEPLACEMENT_PROXIMITE_DESCRIPTION, + $32, --VEHICULES_ADAPTES, + $33, --FILE_REPONSE_EXPLOITANT_OU_PROPRIETAIRE, + $34, --FILE_DERNIER_ARRETE_AUTORISATION_MAIRE, + $35, --FILE_DERNIERE_ATTESTATION_SECURITE + $36, --VISITE_LOCAUX_AT + $37, --ACCESSIBILITE_PRECISION + $38 --AMENAGEMENTS_SPECIFIQUES_PRECISION ) RETURNING id `, + associatePrestation: (nbRows) => ` +INSERT INTO + FRONT.HEBERGEMENT_TO_PRESTATIONS_HOTELIERES (HEBERGEMENT_ID, PRESTATION_ID) +VALUES +${new Array(nbRows) + .fill(null) + .map( + (_, index) => + `($1, (SELECT ID FROM FRONT.HEBERGEMENT_PRESTATIONS_HOTELIERES WHERE VALUE = $${index + 2}))`, + ) + .join(",")} + `, getByDepartementCodes: ( departementCodes, { search, limit, offset, order, sort }, @@ -57,6 +135,7 @@ const query = { h.coordonnees ->> 'email' ILIKE '%' || $2 || '%' OR unaccent(h.coordonnees -> 'adresse' ->> 'label') ILIKE '%' || unaccent($2) || '%' ) + AND CURRENT IS TRUE ORDER BY "${sort}" ${order} ), total_count AS ( @@ -102,8 +181,25 @@ const query = { edited_at as "editedAt" FROM front.hebergement h JOIN front.user_organisme uo ON uo.org_id = h.organisme_id - WHERE uo.use_id = $1 + 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" + FROM + FRONT.HEBERGEMENT + WHERE + ID = $1; + `, + historize: ` + UPDATE front.hebergement + SET current = FALSE + WHERE id = $1 + `, update: ` UPDATE front.hebergement SET @@ -116,40 +212,142 @@ const query = { `, }; -module.exports.create = async ( - userId, +/* +* La fonction create est utilisée à la fois pour créer un nouvel hébergement et pour mettre à jour un +* hébergement existant. Dans le cas d'une mise à jour, elle archive l'hébergement précédent en définissant +* le champ current à false, puis insère une nouvelle ligne pour l'hébergement mis à jour. + +* Pour garantir l'intégrité des données lors de ces opérations, qui impliquent plusieurs interactions avec la base +* de données, celles-ci sont exécutées dans le cadre d'une transaction. La fonction prend donc en paramètre le client +* de transaction fourni par pg (node-postgres). +* +* Les transactions doivent être écrites dans les fonctions appelantes. + +* Pour plus d'informations, consultez la documentation sur les transactions de +* node-postgres : https://node-postgres.com/features/transactions. +*/ +const create = async ( + client, + { createdBy, createdAt, updatedBy, organismeId }, { nom, coordonnees, informationsLocaux, informationsTransport }, + hebergemenetUuid, ) => { - log.i("create - IN"); - const { - rows: [{ id }], - } = await pool.query(query.create, [ - userId, + const adresseId = await saveAdresse(client, coordonnees.adresse); + const { rows } = await client.query(query.create, [ + organismeId, // $1 + createdBy, + updatedBy, + createdAt, + hebergemenetUuid ?? crypto.randomUUID(), // 5 nom, coordonnees, informationsLocaux, informationsTransport, + coordonnees.email, // 10 + adresseId, + coordonnees.numTelephone1, + coordonnees.numTelephone2, + coordonnees.nomGestionnaire, + informationsLocaux.type, // 15 + informationsLocaux.pension, + informationsLocaux.nombreLits, + informationsLocaux.litsDessus, + informationsLocaux.nombreLitsSuperposes, + informationsLocaux.nombreMaxPersonnesCouchage, // 20 + informationsLocaux.visiteLocaux, + informationsLocaux.accessibilite, + informationsLocaux.chambresDoubles, + informationsLocaux.chambresUnisexes, + informationsLocaux.reglementationErp, // 25 + informationsLocaux.couchageIndividuel, + informationsLocaux.rangementIndividuel, + informationsLocaux.amenagementsSpecifiques, + informationsLocaux.descriptionLieuHebergement, + informationsTransport.excursion, // 30 + informationsTransport.deplacementProximite, + informationsTransport.vehiculesAdaptes, + informationsLocaux.fileReponseExploitantOuProprietaire?.uuid ?? null, + informationsLocaux.fileDernierArreteAutorisationMaire?.uuid ?? null, + informationsLocaux.fileDerniereAttestationSecurite?.uuid ?? null, + informationsLocaux.visiteLocauxAt, + informationsLocaux.accessibilitePrecision, + informationsLocaux.precisionAmenagementsSpecifiques, ]); - log.d("create - DONE", { id }); - return id; + + const hebergementId = rows[0].id; + const prestationsHotelieres = informationsLocaux.prestationsHotelieres; + if (prestationsHotelieres.length > 0) { + await client.query( + query.associatePrestation(prestationsHotelieres.length), + [hebergementId, ...prestationsHotelieres], + ); + } + + return hebergementId; }; -module.exports.update = async ( - hebergementId, - { nom, coordonnees, informationsLocaux, informationsTransport }, -) => { - log.i("update - IN"); - const { rowCount } = await pool.query(query.update, [ - hebergementId, - nom, - coordonnees, - informationsLocaux, - informationsTransport, - ]); - if (rowCount === 0) { - throw new AppError("hebergement " + hebergementId + " not found"); +module.exports.create = async (userId, organismeId, hebergement) => { + const client = await pool.connect(); + let hebergementId; + + try { + await client.query("BEGIN"); + hebergementId = await create( + client, + { + createdAt: new Date(), + createdBy: userId, + updatedBy: userId, + organismeId, + }, + hebergement, + ); + await client.query("COMMIT"); + } catch (error) { + await client.query("ROLLBACK"); + throw error; + } finally { + client.release(); } - log.i("update - DONE"); + + return hebergementId; +}; + +module.exports.update = async (userId, hebergementId, hebergement) => { + const { + rows: [{ hebergementUuid, organismeId, createdBy, createdAt, current }], + } = await pool.query(query.getPreviousValueForHistory, [hebergementId]); + const client = await pool.connect(); + + if (!current) { + throw new Error("L'hebergement est archivé et ne peux pas etre modifié"); + } + + let newHebergementId; + try { + await client.query("BEGIN"); + await client.query(query.historize, [hebergementId]); + newHebergementId = await create( + client, + { + createdBy, + createdAt, + updatedBy: userId, + organismeId, + }, + hebergement, + hebergementUuid, + ); + + await client.query("COMMIT"); + } catch (error) { + await client.query("ROLLBACK"); + throw error; + } finally { + client.release(); + } + + return newHebergementId; }; module.exports.getByDepartementCodes = async (departementsCodes, params) => { diff --git a/packages/backend/src/services/adresse.js b/packages/backend/src/services/adresse.js new file mode 100644 index 000000000..0906016d7 --- /dev/null +++ b/packages/backend/src/services/adresse.js @@ -0,0 +1,75 @@ +const pool = require("../utils/pgpool").getPool(); + +const query = { + editCleInsee: ` + UPDATE FRONT.ADRESSE + SET + CLE_INSEE = $2 + WHERE + ID = $1 + RETURNING id + `, + getByCleInseeOrLabel: ` + SELECT + ID, CLE_INSEE as "cleInsee" + FROM + FRONT.ADRESSE + WHERE + CLE_INSEE = $1 + OR LABEL = $2 + `, + insert: ` + INSERT INTO + FRONT.ADRESSE ( + CLE_INSEE, + LABEL, + CODE_INSEE, + CODE_POSTAL, + LONG, + LAT, + DEPARTEMENT + ) + VALUES + ($1, $2, $3, $4, $5, $6, $7) + RETURNING id + `, +}; + +const getByCleInseeOrLabel = async (client, { cleInsee, label }) => { + const { rows } = await client.query(query.getByCleInseeOrLabel, [ + cleInsee, + label, + ]); + return rows?.[0] ?? null; +}; + +module.exports.saveAdresse = async (client, adresse) => { + const existingAdresse = await getByCleInseeOrLabel(client, { + cleInsee: adresse.cleInsee, + label: adresse.label, + }); + + if (existingAdresse && !existingAdresse.cleInsee && adresse.cleInsee) { + const { rows } = await client.query(query.editCleInsee, [ + existingAdresse.id, + adresse.cleInsee, + ]); + return rows[0].id; + } + + if (!existingAdresse) { + const { rows } = await client.query(query.insert, [ + adresse.cleInsee, + adresse.label, + adresse.codeInsee, + adresse.codePostal, + adresse.coordinates[0], + adresse.coordinates[1], + adresse.departement, + ]); + + return rows[0].id; + } + + return existingAdresse.id; +}; diff --git a/packages/frontend-bo/src/components/user/Compte.vue b/packages/frontend-bo/src/components/user/Compte.vue index 4cb009fa9..e4b09ed7d 100644 --- a/packages/frontend-bo/src/components/user/Compte.vue +++ b/packages/frontend-bo/src/components/user/Compte.vue @@ -9,9 +9,9 @@
(popUpParams.value = null); const modalOpenCounter = ref(0); const openModal = (p) => { - console.log(p); modalOpenCounter.value++; popUpParams.value = { cb: () => { diff --git a/packages/frontend-bo/src/stores/demande-sejour.js b/packages/frontend-bo/src/stores/demande-sejour.js index 2f80f7d27..7e7fe0643 100644 --- a/packages/frontend-bo/src/stores/demande-sejour.js +++ b/packages/frontend-bo/src/stores/demande-sejour.js @@ -68,18 +68,6 @@ export const useDemandeSejourStore = defineStore("demandeSejour", { credentials: "include", }); - for (const hebergement of demande?.hebergement?.hebergements ?? []) { - hebergement.nom = ( - await $fetchBackend( - `/hebergement/admin/${hebergement.hebergementId}`, - { - method: "GET", - credentials: "include", - }, - ) - ).hebergement.nom; - } - if (demande) { log.i("fetchDemandes for one id - DONE"); this.currentDemande = demande; diff --git a/packages/frontend-usagers/src/components/DS/hebergements-sejour-detail.vue b/packages/frontend-usagers/src/components/DS/hebergements-sejour-detail.vue index 342acb5c6..7ea130846 100644 --- a/packages/frontend-usagers/src/components/DS/hebergements-sejour-detail.vue +++ b/packages/frontend-usagers/src/components/DS/hebergements-sejour-detail.vue @@ -62,7 +62,7 @@ label="Nom de l'hébergement" :label-visible="true" :model-value="hebergementStore.hebergementCourant.nom" - readonly + disabled />
@@ -73,7 +73,7 @@ :model-value=" hebergementStore.hebergementCourant.coordonnees.nomGestionnaire " - readonly + disabled />
@@ -84,7 +84,7 @@ :model-value=" hebergementStore.hebergementCourant.coordonnees.adresse.label " - readonly + disabled />
@@ -120,7 +120,7 @@ :model-value=" hebergementStore.hebergementCourant.coordonnees.numTelephone2 " - readonly + disabled />
@@ -129,7 +129,7 @@ label="Adresse courriel" :label-visible="true" :model-value="hebergementStore.hebergementCourant.coordonnees.email" - readonly + disabled />
@@ -140,12 +140,11 @@ name="informationsLocaux.type" legend="Type du lieu d'hébergement" :model-value="type" - :disabled="!props.modifiable" + disabled :options="hebergementUtils.typeOptions" :is-valid="typeMeta.valid" :inline="false" :error-message="typeErrorMessage" - readonly @update:model-value="onTypeChange" />
@@ -157,7 +156,7 @@ - -

- Informations ERP : Selon la circulaire du 6 octobre 2023, il sera - requis l’arrêté d’autorisation du maire et/ou la dernière - attestation du passage de la commission de sécurité datant de moins - de 5 ans pour séjours se déroulant en établissement recevant du - public (ERP). -

-

- A défaut de transmission de ces justificatifs, la DDETS met en - demeure l'organisme de produire ces pièces et propose au Préfet de - département une annulation des séjours, si absence de tous les - justificatifs. -

-

On distingue 3 catégories d’hébergements :

- -
@@ -248,7 +215,7 @@ v-model="fileReponseExploitantOuProprietaire" label="Téléchargement du document Réponse du propriétaire ou exploitant indiquant les raisons pour lesquelles le lieu d’hébergement n’est pas soumis à la réglementation ERP" hint="Taille maximale : 5 Mo. Formats supportés : jpg, png, pdf." - :modifiable="props.modifiable" + :modifiable="false" :error-message="fileReponseExploitantOuProprietaireErrorMessage" />
@@ -257,7 +224,7 @@ @@ -289,7 +257,7 @@ @@ -324,6 +292,7 @@ :model-value="descriptionLieuHebergement" :error-message="descriptionLieuHebergementErrorMessage" :is-valid="descriptionLieuHebergementMeta.valid" + disabled @update:model-value="onDescriptionLieuHebergementChange" /> @@ -339,6 +308,7 @@ :model-value="nombreLits" :error-message="nombreLitsErrorMessage" :is-valid="nombreLitsMeta.valid" + disabled @update:model-value="onNombreLitsChange" /> @@ -354,6 +324,7 @@ :model-value="nombreLitsSuperposes" :error-message="nombreLitsSuperposesErrorMessage" :is-valid="nombreLitsSuperposesMeta.valid" + disabled @update:model-value=" onNombreLitsSuperposesChange($event !== '' ? $event : null) " @@ -369,7 +340,7 @@ name="informationsLocaux.litsDessus" legend="Pour les lits superposés, les lits « du dessus » seront-ils occupés par des vacanciers ?" - :disabled="!props.modifiable" + disabled :model-value="litsDessus" :options="ouiNonOptions" :is-valid="litsDessusMeta.valid" @@ -385,7 +356,7 @@ name="informationsLocaux.nombreMaxPersonnesCouchage" label="Nombre maximum de personnes prévues par espace de couchage" type="number" - :readonly="!props.modifiable" + disabled :label-visible="true" :model-value="nombreMaxPersonnesCouchage" :error-message="nombreMaxPersonnesCouchageErrorMessage" @@ -399,7 +370,7 @@ { if (hebergementStore.hebergements.length > 0) { return hebergements.value.map((hebergement, index) => { - const currentHebergement = hebergementStore.hebergements.find((elem) => { - return elem.id.toString() === hebergement.hebergementId.toString(); - }); - if (currentHebergement) { - const buttons = [ - { - icon: "ri:delete-bin-2-line", - iconOnly: true, - tertiary: true, - noOutline: true, - disabled: !props.modifiable, - onClick: (event) => { - event.stopPropagation(); - removeHebergement(index); - }, + const buttons = [ + { + icon: "ri:delete-bin-2-line", + iconOnly: true, + tertiary: true, + noOutline: true, + disabled: !props.modifiable, + onClick: (event) => { + event.stopPropagation(); + removeHebergement(index); }, - ]; + }, + ]; - const rows = [ - `${index + 1}`, - hebergement.dateFin && hebergement.dateDebut - ? dayjs(hebergement.dateFin) - .diff(dayjs(hebergement.dateDebut), "day") - .toString() - : "", - hebergement.dateDebut - ? dayjs(hebergement.dateDebut).format("DD/MM/YYYY") - : "", - hebergement.dateFin - ? dayjs(hebergement.dateFin).format("DD/MM/YYYY") - : "", - currentHebergement.nom ?? "", - currentHebergement.adresse ?? "", - { - component: DsfrButtonGroup, - buttons: buttons, - }, - ]; - return { - rowData: rows, - rowAttrs: { - class: "pointer", - onClick: () => editNuitee(index), - }, - }; - } else return []; + const rows = [ + `${index + 1}`, + hebergement.dateFin && hebergement.dateDebut + ? dayjs(hebergement.dateFin) + .diff(dayjs(hebergement.dateDebut), "day") + .toString() + : "", + hebergement.dateDebut + ? dayjs(hebergement.dateDebut).format("DD/MM/YYYY") + : "", + hebergement.dateFin + ? dayjs(hebergement.dateFin).format("DD/MM/YYYY") + : "", + hebergement.nom ?? "", + hebergement.adresse ?? "", + { + component: DsfrButtonGroup, + buttons: buttons, + }, + ]; + return { + rowData: rows, + rowAttrs: { + class: "pointer", + onClick: () => editNuitee(index), + }, + }; }); } else return []; }); diff --git a/packages/frontend-usagers/src/components/search-address.vue b/packages/frontend-usagers/src/components/search-address.vue index c95462726..cd71c2394 100644 --- a/packages/frontend-usagers/src/components/search-address.vue +++ b/packages/frontend-usagers/src/components/search-address.vue @@ -49,6 +49,7 @@ const searchAddressDebounced = debounce(async function (queryString) { options.value = adresses.map((address) => { return { label: address.properties.label, + cleInsee: address.properties.id, codeInsee: address.properties.citycode, codePostal: address.properties.postcode, coordinates: address.geometry.coordinates, @@ -122,7 +123,7 @@ function select(_value, option) { :is-pointed="isPointed(option)" /> - +

diff --git a/packages/frontend-usagers/src/utils/adresse.js b/packages/frontend-usagers/src/utils/adresse.js deleted file mode 100644 index e3897dd8a..000000000 --- a/packages/frontend-usagers/src/utils/adresse.js +++ /dev/null @@ -1,19 +0,0 @@ -import * as yup from "yup"; - -const schema = ({ isFromAPIAdresse } = {}) => { - return isFromAPIAdresse - ? { - label: yup.string().required("ce champ est obligatoire"), - codeInsee: yup.string().required("ce champ est obligatoire"), - codePostal: yup.string().required("ce champ est obligatoire"), - coordinates: yup.array().required("ce champ est obligatoire"), - departement: yup.string().required("ce champ est obligatoire"), - } - : { - label: yup.string().required(), - }; -}; - -export default { - schema, -}; diff --git a/packages/frontend-usagers/src/utils/organisme.js b/packages/frontend-usagers/src/utils/organisme.js index 5d050231f..d0b10ab36 100644 --- a/packages/frontend-usagers/src/utils/organisme.js +++ b/packages/frontend-usagers/src/utils/organisme.js @@ -1,10 +1,10 @@ import * as yup from "yup"; import dayjs from "dayjs"; import regex from "./regex"; -import adresse from "./adresse"; import personne from "./personne"; import protocoleTransport from "./protocoleTransport"; import protocoleSanitaire from "./protocoleSanitaire"; +import { adresseSchema } from "@vao/shared/src/schema/adresse"; const types = [ { @@ -225,8 +225,8 @@ const personnePhysiqueSchema = { regex.numTelephoneRegex.test(tel), ), adresseIdentique: yup.boolean().required(), - adresseDomicile: yup.object({ ...adresse.schema(true) }).required(), - adresseSiege: yup.object({ ...adresse.schema(true) }).required(), + adresseDomicile: yup.object({ ...adresseSchema(true) }).required(), + adresseSiege: yup.object({ ...adresseSchema(true) }).required(), }; const agrementSchema = (regions) => ({ file: yup.mixed().required(), diff --git a/packages/frontend-usagers/src/utils/personne.js b/packages/frontend-usagers/src/utils/personne.js index 2694b90ef..99bfd1665 100644 --- a/packages/frontend-usagers/src/utils/personne.js +++ b/packages/frontend-usagers/src/utils/personne.js @@ -1,8 +1,8 @@ import * as yup from "yup"; import dayjs from "dayjs"; import regex from "./regex"; -import adresse from "./adresse"; import { informationsPersonnelListe } from "#imports"; +import { adresseSchema } from "@vao/shared/src/schema/adresse"; const schema = ({ showAdresse, @@ -60,7 +60,7 @@ const schema = ({ ...(showAdresse && { adresse: yup.object({ - ...adresse.schema(), + ...adresseSchema(), }), }), ...(showAttestation && { diff --git a/packages/frontend-usagers/src/utils/prestataireUtils.js b/packages/frontend-usagers/src/utils/prestataireUtils.js index dfee2273e..bcb183aed 100644 --- a/packages/frontend-usagers/src/utils/prestataireUtils.js +++ b/packages/frontend-usagers/src/utils/prestataireUtils.js @@ -1,7 +1,7 @@ import * as yup from "yup"; import dayjs from "dayjs"; import regex from "./regex"; -import adresse from "./adresse"; +import { adresseSchema } from "@vao/shared/src/schema/adresse"; const typePrestataireOptions = [ { @@ -53,7 +53,7 @@ const schema = { .required(), adresse: yup.object().when("typePrestataire", { is: (val) => val === "personne_morale", - then: () => yup.object(adresse.schema()), + then: () => yup.object(adresseSchema()), otherwise: (val) => val.nullable().strip(), }), competence: yup.string().when("typePrestataire", { diff --git a/packages/migrations/src/migrations/20241107125107_hebergement-refacto.js b/packages/migrations/src/migrations/20241107125107_hebergement-refacto.js new file mode 100644 index 000000000..df6e27dfd --- /dev/null +++ b/packages/migrations/src/migrations/20241107125107_hebergement-refacto.js @@ -0,0 +1,333 @@ +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.up = function (knex) { + return knex.raw(` +CREATE TABLE FRONT.ADRESSE ( + ID SERIAL NOT NULL, + CLE_INSEE VARCHAR(50) UNIQUE, + LABEL TEXT NOT NULL, + CODE_INSEE VARCHAR(5) NOT NULL, + CODE_POSTAL VARCHAR(5) NOT NULL, + LONG DOUBLE PRECISION NOT NULL, + LAT DOUBLE PRECISION NOT NULL, + DEPARTEMENT VARCHAR(3) REFERENCES GEO.TERRITOIRES (CODE), + CONSTRAINT PK_ADRESSE PRIMARY KEY (ID), + CONSTRAINT UNIQUE_CLE_INSEE UNIQUE (CLE_INSEE) +); + +INSERT INTO + FRONT.ADRESSE ( + LABEL, + CODE_INSEE, + CODE_POSTAL, + LONG, + LAT, + DEPARTEMENT + ) +SELECT DISTINCT + COORDONNEES -> 'adresse' ->> 'label' AS LABEL, + COORDONNEES -> 'adresse' ->> 'codeInsee' AS CODE_INSEE, + COORDONNEES -> 'adresse' ->> 'codePostal' AS CODE_POSTAL, + (COORDONNEES -> 'adresse' -> 'coordinates' -> 0)::DOUBLE PRECISION AS LONG, + (COORDONNEES -> 'adresse' -> 'coordinates' -> 1)::DOUBLE PRECISION AS LAT, + COORDONNEES -> 'adresse' ->> 'departement' AS DEPARTEMENT +FROM + FRONT.HEBERGEMENT ; + +CREATE TABLE FRONT.HEBERGEMENT_TYPE ( + ID SERIAL NOT NULL, + VALUE VARCHAR(100), + CONSTRAINT PK_HEBERGEMENT_TYPE PRIMARY KEY (ID) +); + +INSERT INTO + FRONT.HEBERGEMENT_TYPE (VALUE) +VALUES + ('hotel'), + ('meuble_tourisme'), + ('residence_tourisme'), + ('camping'), + ('autre') ; + +CREATE TABLE FRONT.HEBERGEMENT_TYPE_PENSION ( + ID SERIAL NOT NULL, + VALUE VARCHAR(100), + CONSTRAINT PK_HEBERGEMENT_TYPE_PENSION PRIMARY KEY (ID) +); + +INSERT INTO + FRONT.HEBERGEMENT_TYPE_PENSION (VALUE) +VALUES + ('hebergement_seul'), + ('petit_dejeuner'), + ('demi_pension'), + ('pension_complete') ; + +CREATE TABLE FRONT.HEBERGEMENT_ACCESSIBILITE ( + ID SERIAL NOT NULL, + VALUE VARCHAR(100), + CONSTRAINT PK_HEBERGEMENT_ACCESSIBILITE PRIMARY KEY (ID) +); + +INSERT INTO + FRONT.HEBERGEMENT_ACCESSIBILITE (VALUE) +VALUES + ('accessible'), + ('non_adapte'), + ('commentaires') ; + +CREATE TABLE FRONT.HEBERGEMENT_PRESTATIONS_HOTELIERES ( + ID SERIAL NOT NULL, + VALUE VARCHAR(100), + CONSTRAINT PK_HEBERGEMENT_PRESTATIONS_HOTELIERES PRIMARY KEY (ID) +); + +INSERT INTO + FRONT.HEBERGEMENT_PRESTATIONS_HOTELIERES (VALUE) +VALUES + ('blanchisseries'), + ('entretien_locaux') ; + +CREATE TABLE FRONT.HEBERGEMENT_TO_PRESTATIONS_HOTELIERES( + HEBERGEMENT_ID INTEGER REFERENCES FRONT.HEBERGEMENT (ID) ON DELETE CASCADE, + PRESTATION_ID INTEGER REFERENCES FRONT.HEBERGEMENT_PRESTATIONS_HOTELIERES (ID) ON DELETE CASCADE, + CONSTRAINT pk_hebergement_prestation PRIMARY KEY (HEBERGEMENT_ID, PRESTATION_ID) +); + +ALTER TABLE FRONT.HEBERGEMENT +ADD COLUMN HEBERGEMENT_ID UUID NOT NULL DEFAULT GEN_RANDOM_UUID (), +ADD COLUMN CURRENT BOOLEAN NOT NULL DEFAULT TRUE, +ADD COLUMN CREATED_BY INTEGER REFERENCES FRONT.USERS (ID), +ADD COLUMN EDITED_BY INTEGER REFERENCES FRONT.USERS (ID), +ADD COLUMN EMAIL VARCHAR(320), +ADD COLUMN ADRESSE_ID INTEGER REFERENCES FRONT.ADRESSE (ID), +ADD COLUMN TELEPHONE_1 VARCHAR(20), +ADD COLUMN TELEPHONE_2 VARCHAR(20), +ADD COLUMN NOM_GESTIONNAIRE VARCHAR(320), +ADD COLUMN TYPE_ID INTEGER REFERENCES FRONT.HEBERGEMENT_TYPE (ID), +ADD COLUMN TYPE_PENSION_ID INTEGER REFERENCES FRONT.HEBERGEMENT_TYPE_PENSION (ID), +ADD COLUMN NOMBRE_LITS INTEGER, +ADD COLUMN LIT_DESSUS BOOLEAN, +ADD COLUMN NOMBRE_LITS_SUPERPOSES INTEGER, +ADD COLUMN NOMBRE_MAX_PERSONNES_COUCHAGE INTEGER, +ADD COLUMN VISITE_LOCAUX BOOLEAN, +ADD COLUMN VISITE_LOCAUX_AT TIMESTAMP WITH TIME ZONE, +ADD COLUMN ACCESSIBILITE_ID INTEGER REFERENCES FRONT.HEBERGEMENT_ACCESSIBILITE (ID), +ADD COLUMN ACCESSIBILITE_PRECISION TEXT, +ADD COLUMN CHAMBRES_DOUBLES BOOLEAN, +ADD COLUMN CHAMBRES_UNISEXES BOOLEAN, +ADD COLUMN REGLEMENTATION_ERP BOOLEAN, +ADD COLUMN COUCHAGE_INDIVIDUEL BOOLEAN, +ADD COLUMN RANGEMENT_INDIVIDUEL BOOLEAN, +ADD COLUMN AMENAGEMENTS_SPECIFIQUES BOOLEAN, +ADD COLUMN AMENAGEMENTS_SPECIFIQUES_PRECISION TEXT, +ADD COLUMN DESCRIPTION_LIEU_HEBERGEMENT TEXT, +ADD COLUMN EXCURSION_DESCRIPTION TEXT, +ADD COLUMN DEPLACEMENT_PROXIMITE_DESCRIPTION TEXT, +ADD COLUMN VEHICULES_ADAPTES TEXT, +ADD COLUMN FILE_REPONSE_EXPLOITANT_OU_PROPRIETAIRE UUID, +ADD COLUMN FILE_DERNIER_ARRETE_AUTORISATION_MAIRE UUID, +ADD COLUMN FILE_DERNIERE_ATTESTATION_SECURITE UUID; + +UPDATE FRONT.HEBERGEMENT +SET + EMAIL = COORDONNEES ->> 'email', + ADRESSE_ID = ( + SELECT + ID + FROM + FRONT.ADRESSE A + WHERE + A.LABEL = COORDONNEES -> 'adresse' ->> 'label' + AND A.CODE_INSEE = COORDONNEES -> 'adresse' ->> 'codeInsee' + AND A.CODE_POSTAL = COORDONNEES -> 'adresse' ->> 'codePostal' + AND A.LONG = (COORDONNEES -> 'adresse' -> 'coordinates' -> 0)::DOUBLE PRECISION + AND A.LAT = (COORDONNEES -> 'adresse' -> 'coordinates' -> 1)::DOUBLE PRECISION + AND A.DEPARTEMENT = COORDONNEES -> 'adresse' ->> 'departement' + ), + TELEPHONE_1 = COORDONNEES ->> 'numTelephone1', + TELEPHONE_2 = COORDONNEES ->> 'numTelephone2', + NOM_GESTIONNAIRE = COORDONNEES ->> 'nomGestionnaire', + TYPE_ID = ( + SELECT + ID + FROM + FRONT.HEBERGEMENT_TYPE + WHERE + VALUE = INFORMATIONS_LOCAUX ->> 'type' + ), + TYPE_PENSION_ID = ( + SELECT + ID + FROM + FRONT.HEBERGEMENT_TYPE_PENSION + WHERE + VALUE = INFORMATIONS_LOCAUX ->> 'pension' + ), + LIT_DESSUS = (INFORMATIONS_LOCAUX ->> 'litsDessus')::BOOLEAN, + NOMBRE_LITS = (INFORMATIONS_LOCAUX ->> 'nombreLits')::INTEGER, + NOMBRE_LITS_SUPERPOSES = (INFORMATIONS_LOCAUX ->> 'nombreLitsSuperposes')::INTEGER, + NOMBRE_MAX_PERSONNES_COUCHAGE = ( + INFORMATIONS_LOCAUX ->> 'nombreMaxPersonnesCouchage' + )::INTEGER, + VISITE_LOCAUX = (INFORMATIONS_LOCAUX ->> 'visiteLocaux')::BOOLEAN, + VISITE_LOCAUX_AT = (INFORMATIONS_LOCAUX ->> 'visiteLocauxAt')::TIMESTAMP WITH TIME ZONE, + ACCESSIBILITE_ID = ( + SELECT + ID + FROM + FRONT.HEBERGEMENT_ACCESSIBILITE + WHERE + VALUE = INFORMATIONS_LOCAUX ->> 'accessibilite' + ), + ACCESSIBILITE_PRECISION = (INFORMATIONS_LOCAUX ->> 'accessibilitePrecision')::TEXT, + CHAMBRES_DOUBLES = (INFORMATIONS_LOCAUX ->> 'chambresDoubles')::BOOLEAN, + CHAMBRES_UNISEXES = (INFORMATIONS_LOCAUX ->> 'chambresUnisexes')::BOOLEAN, + REGLEMENTATION_ERP = (INFORMATIONS_LOCAUX ->> 'reglementationErp')::BOOLEAN, + COUCHAGE_INDIVIDUEL = (INFORMATIONS_LOCAUX ->> 'couchageIndividuel')::BOOLEAN, + RANGEMENT_INDIVIDUEL = (INFORMATIONS_LOCAUX ->> 'rangementIndividuel')::BOOLEAN, + AMENAGEMENTS_SPECIFIQUES = (INFORMATIONS_LOCAUX ->> 'amenagementsSpecifiques')::BOOLEAN, + AMENAGEMENTS_SPECIFIQUES_PRECISION = (INFORMATIONS_LOCAUX ->> 'precisionAmenagementsSpecifiques')::TEXT, + DESCRIPTION_LIEU_HEBERGEMENT = INFORMATIONS_LOCAUX ->> 'descriptionLieuHebergement', + EXCURSION_DESCRIPTION = INFORMATIONS_TRANSPORT ->> 'excursion', + DEPLACEMENT_PROXIMITE_DESCRIPTION = INFORMATIONS_TRANSPORT ->> 'deplacementProximite', + VEHICULES_ADAPTES = (INFORMATIONS_TRANSPORT ->> 'vehiculesAdaptes')::BOOLEAN, + FILE_REPONSE_EXPLOITANT_OU_PROPRIETAIRE = ( + INFORMATIONS_LOCAUX -> 'fileReponseExploitantOuProprietaire' ->> 'uuid' + )::UUID, + FILE_DERNIER_ARRETE_AUTORISATION_MAIRE = ( + INFORMATIONS_LOCAUX -> 'fileDernierArreteAutorisationMaire' ->> 'uuid' + )::UUID, + FILE_DERNIERE_ATTESTATION_SECURITE = ( + INFORMATIONS_LOCAUX -> 'fileDerniereAttestationSecurite' ->> 'uuid' + )::UUID; + +INSERT INTO + FRONT.HEBERGEMENT_TO_PRESTATIONS_HOTELIERES (HEBERGEMENT_ID, PRESTATION_ID) +SELECT + HEBERGEMENT_ID, + ( + SELECT + ID + FROM + FRONT.HEBERGEMENT_PRESTATIONS_HOTELIERES + WHERE + VALUE = SUB_HEBERGEMENT.HEBERGEMENT_PRESTATIONS_HOTELIERES_VALUE + ) +FROM + ( + SELECT + ID AS HEBERGEMENT_ID, + JSONB_ARRAY_ELEMENTS( + INFORMATIONS_LOCAUX -> 'prestationsHotelieres'::TEXT + ) ->> 0 AS HEBERGEMENT_PRESTATIONS_HOTELIERES_VALUE + FROM + FRONT.HEBERGEMENT + ) SUB_HEBERGEMENT; + +CREATE TABLE FRONT.DEMANDE_SEJOUR_TO_HEBERGEMENT ( + HEBERGEMENT_ID INTEGER REFERENCES FRONT.HEBERGEMENT (ID), + DEMANDE_SEJOUR_ID INTEGER REFERENCES FRONT.DEMANDE_SEJOUR (ID), + DATE_DEBUT TIMESTAMP WITH TIME ZONE NOT NULL, + DATE_FIN TIMESTAMP WITH TIME ZONE NOT NULL, + CONSTRAINT UNIQUE_IDS_DATES UNIQUE ( + HEBERGEMENT_ID, + DEMANDE_SEJOUR_ID, + DATE_DEBUT, + DATE_FIN + ) +) ; + +INSERT INTO + FRONT.DEMANDE_SEJOUR_TO_HEBERGEMENT ( + HEBERGEMENT_ID, + DEMANDE_SEJOUR_ID, + DATE_DEBUT, + DATE_FIN + ) +SELECT + ( + JSONB_ARRAY_ELEMENTS(HEBERGEMENT -> 'hebergements') -> 'hebergementId' ->> 0 + )::INTEGER AS HEBERGEMENT_ID, + ID AS DEMANDE_SEJOUR_ID, + ( + JSONB_ARRAY_ELEMENTS(HEBERGEMENT -> 'hebergements') -> 'dateDebut' ->> 0 + )::TIMESTAMP WITH TIME ZONE AS DATE_DEBUT, + ( + JSONB_ARRAY_ELEMENTS(HEBERGEMENT -> 'hebergements') -> 'dateFin' ->> 0 + )::TIMESTAMP WITH TIME ZONE AS DATE_FIN +FROM + FRONT.DEMANDE_SEJOUR ; + +CREATE UNIQUE INDEX idx_hebergement_hebergement_id ON FRONT.HEBERGEMENT (hebergement_id) WHERE (CURRENT IS TRUE); + +GRANT ALL ON TABLE FRONT.ADRESSE TO vao_u ; +GRANT ALL ON TABLE FRONT.HEBERGEMENT_TYPE TO vao_u ; +GRANT ALL ON TABLE FRONT.HEBERGEMENT_TYPE_PENSION TO vao_u ; +GRANT ALL ON TABLE FRONT.HEBERGEMENT_ACCESSIBILITE TO vao_u ; +GRANT ALL ON TABLE FRONT.HEBERGEMENT_PRESTATIONS_HOTELIERES TO vao_u ; +GRANT ALL ON TABLE FRONT.HEBERGEMENT_TO_PRESTATIONS_HOTELIERES TO vao_u ; +GRANT ALL ON TABLE FRONT.DEMANDE_SEJOUR_TO_HEBERGEMENT TO vao_u ; + +GRANT ALL ON SEQUENCE FRONT.ADRESSE_ID_SEQ TO VAO_U ; +GRANT ALL ON SEQUENCE FRONT.HEBERGEMENT_TYPE_ID_SEQ TO VAO_U ; +GRANT ALL ON SEQUENCE FRONT.HEBERGEMENT_TYPE_PENSION_ID_SEQ TO VAO_U ; +GRANT ALL ON SEQUENCE FRONT.HEBERGEMENT_ACCESSIBILITE_ID_SEQ TO VAO_U ; +GRANT ALL ON SEQUENCE FRONT.HEBERGEMENT_PRESTATIONS_HOTELIERES_ID_SEQ TO VAO_U ; + + `); +}; + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.down = function (knex) { + return knex.raw(` +ALTER TABLE FRONT.HEBERGEMENT +DROP COLUMN HEBERGEMENT_ID, +DROP COLUMN CURRENT, +DROP COLUMN CREATED_BY, +DROP COLUMN EDITED_BY, +DROP COLUMN EMAIL, +DROP COLUMN ADRESSE_ID, +DROP COLUMN TELEPHONE_1, +DROP COLUMN TELEPHONE_2, +DROP COLUMN NOM_GESTIONNAIRE, +DROP COLUMN TYPE_ID, +DROP COLUMN TYPE_PENSION_ID, +DROP COLUMN NOMBRE_LITS, +DROP COLUMN LIT_DESSUS, +DROP COLUMN NOMBRE_LITS_SUPERPOSES, +DROP COLUMN NOMBRE_MAX_PERSONNES_COUCHAGE, +DROP COLUMN VISITE_LOCAUX, +DROP COLUMN ACCESSIBILITE_ID, +DROP COLUMN CHAMBRES_DOUBLES, +DROP COLUMN CHAMBRES_UNISEXES, +DROP COLUMN REGLEMENTATION_ERP, +DROP COLUMN COUCHAGE_INDIVIDUEL, +DROP COLUMN RANGEMENT_INDIVIDUEL, +DROP COLUMN AMENAGEMENTS_SPECIFIQUES, +DROP COLUMN DESCRIPTION_LIEU_HEBERGEMENT, +DROP COLUMN EXCURSION_DESCRIPTION, +DROP COLUMN DEPLACEMENT_PROXIMITE_DESCRIPTION, +DROP COLUMN VEHICULES_ADAPTES, +DROP COLUMN FILE_REPONSE_EXPLOITANT_OU_PROPRIETAIRE, +DROP COLUMN FILE_DERNIER_ARRETE_AUTORISATION_MAIRE, +DROP COLUMN FILE_DERNIERE_ATTESTATION_SECURITE, +DROP COLUMN VISITE_LOCAUX_AT, +DROP COLUMN ACCESSIBILITE_PRECISION, +DROP COLUMN AMENAGEMENTS_SPECIFIQUES_PRECISION; + +DROP TABLE FRONT.HEBERGEMENT_TO_PRESTATIONS_HOTELIERES ; +DROP TABLE FRONT.HEBERGEMENT_PRESTATIONS_HOTELIERES ; +DROP TABLE FRONT.HEBERGEMENT_ACCESSIBILITE ; +DROP TABLE FRONT.HEBERGEMENT_TYPE_PENSION ; +DROP TABLE FRONT.HEBERGEMENT_TYPE ; +DROP TABLE FRONT.ADRESSE ; + +DROP TABLE FRONT.DEMANDE_SEJOUR_TO_HEBERGEMENT ; + `); +}; diff --git a/packages/shared/src/schema/adresse.js b/packages/shared/src/schema/adresse.js index 023eae706..945b3acbb 100644 --- a/packages/shared/src/schema/adresse.js +++ b/packages/shared/src/schema/adresse.js @@ -3,6 +3,7 @@ import * as yup from "yup"; export const adresseSchema = ({ isFromAPIAdresse } = {}) => { return isFromAPIAdresse ? { + cleInsee: yup.string().nullable(true), codeInsee: yup.string().required("ce champ est obligatoire"), codePostal: yup.string().required("ce champ est obligatoire"), coordinates: yup.array().required("ce champ est obligatoire"),