diff --git a/packages/backend/src/schemas/parts/adresse.js b/packages/backend/src/schemas/parts/adresse.js index 0d2c8a87f..ef540e954 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().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"), diff --git a/packages/backend/src/services/Hebergement.js b/packages/backend/src/services/Hebergement.js index ee9234dbc..12bfb7a17 100644 --- a/packages/backend/src/services/Hebergement.js +++ b/packages/backend/src/services/Hebergement.js @@ -1,6 +1,7 @@ /* 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); @@ -14,19 +15,91 @@ const query = { informations_locaux, informations_transport, created_at, - edited_at + edited_at, + HEBERGEMENT_ID, + CURRENT, + CREATED_BY, + EDITED_BY, + 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 ) VALUES ( - (SELECT org_id FROM front.user_organisme WHERE use_id = $1), - $2, - $3, - $4, - $5, - NOW(), - NOW() + (SELECT org_id FROM front.user_organisme WHERE use_id = $1), --organisme_id, + $2, --nom, + $3, --coordonnees, + $4, --informations_locaux, + $5, --informations_transport, + NOW(), --created_at, + NOW(), --edited_at, + gen_random_uuid(), --HEBERGEMENT_ID, + TRUE, --CURRENT, + $1, --CREATED_BY, + $1, --EDITED_BY, + $6, --EMAIL, + $7, --ADRESSE_ID, + $8, --TELEPHONE_1, + $9, --TELEPHONE_2, + $10, --NOM_GESTIONNAIRE, + (SELECT ID FROM FRONT.HEBERGEMENT_TYPE WHERE VALUE = $11), --TYPE_ID, + (SELECT ID FROM FRONT.HEBERGEMENT_TYPE_PENSION WHERE VALUE = $12), --TYPE_PENSION_ID, + $13, --NOMBRE_LITS, + $14, --LIT_DESSUS, + $15, --NOMBRE_LITS_SUPERPOSES, + $16, --NOMBRE_MAX_PERSONNES_COUCHAGE, + $17, --VISITE_LOCAUX, + (SELECT ID FROM FRONT.HEBERGEMENT_ACCESSIBILITE WHERE VALUE = $18), --ACCESSIBILITE_ID, + $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 ) RETURNING id `, + associatePrestation: (nbRows) => ` +INSERT INTO + FRONT.HEBERGEMENT_TO_PRESTATION_RELATION (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 }, @@ -121,17 +194,64 @@ module.exports.create = async ( { nom, coordonnees, informationsLocaux, informationsTransport }, ) => { log.i("create - IN"); - const { - rows: [{ id }], - } = await pool.query(query.create, [ - userId, - nom, - coordonnees, - informationsLocaux, - informationsTransport, - ]); - log.d("create - DONE", { id }); - return id; + + const client = await pool.connect(); + + let hebergementId; + + try { + await client.query("BEGIN"); + const adresseId = await saveAdresse(coordonnees.adresse); + const { rows } = await pool.query(query.create, [ + userId, // $1 + nom, + coordonnees, + informationsLocaux, + informationsTransport, // 5 + coordonnees.email, + adresseId, + coordonnees.numTelephone1, + coordonnees.numTelephone2, + coordonnees.nomGestionnaire, // 10 + informationsLocaux.type, + informationsLocaux.pension, + informationsLocaux.nombreLits, + informationsLocaux.litsDessus, + informationsLocaux.nombreLitsSuperposes, // 15 + informationsLocaux.nombreMaxPersonnesCouchage, + informationsLocaux.visiteLocaux, + informationsLocaux.accessibilite, + informationsLocaux.chambresDoubles, + informationsLocaux.chambresUnisexes, // 20 + informationsLocaux.reglementationErp, + informationsLocaux.couchageIndividuel, + informationsLocaux.rangementIndividuel, + informationsLocaux.amenagementsSpecifiques, + informationsLocaux.descriptionLieuHebergement, // 25 + informationsTransport.excursion, + informationsTransport.deplacementProximite, + informationsTransport.vehiculesAdaptes, + informationsLocaux.fileReponseExploitantOuProprietaire?.uuid ?? null, + informationsLocaux.fileDernierArreteAutorisationMaire?.uuid ?? null, // 30 + informationsLocaux.fileDerniereAttestationSecurite?.uuid ?? null, + ]); + + hebergementId = rows[0].id; + const prestationsHotelieres = informationsLocaux.prestationsHotelieres; + await pool.query(query.associatePrestation(prestationsHotelieres.length), [ + hebergementId, + ...prestationsHotelieres, + ]); + await client.query("COMMIT"); + } catch (error) { + await client.query("ROLLBACK"); + throw error; + } finally { + client.release(); + } + + log.d("create - DONE", { hebergementId }); + return hebergementId; }; module.exports.update = async ( diff --git a/packages/backend/src/services/adresse.js b/packages/backend/src/services/adresse.js new file mode 100644 index 000000000..640472c12 --- /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 ({ cleInsee, label }) => { + const { rows } = await pool.query(query.getByCleInseeOrLabel, [ + cleInsee, + label, + ]); + return rows?.[0] ?? null; +}; + +module.exports.saveAdresse = async (adresse) => { + const existingAdresse = await getByCleInseeOrLabel({ + cleInsee: adresse.cleInsee, + label: adresse.label, + }); + + if (existingAdresse && !existingAdresse.cleInsee && adresse.cleInsee) { + const { rows } = await pool.query(query.editCleInsee, [ + existingAdresse.id, + adresse.cleInsee, + ]); + return rows[0].id; + } + + if (!existingAdresse) { + const { rows } = await pool.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-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..615f8a822 --- /dev/null +++ b/packages/migrations/src/migrations/20241107125107_hebergement-refacto.js @@ -0,0 +1,323 @@ +/** + * @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_PRESTATION_RELATION ( + 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 ACCESSIBILITE_ID INTEGER REFERENCES FRONT.HEBERGEMENT_ACCESSIBILITE (ID), +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 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, + ACCESSIBILITE_ID = ( + SELECT + ID + FROM + FRONT.HEBERGEMENT_ACCESSIBILITE + WHERE + VALUE = INFORMATIONS_LOCAUX ->> 'accessibilite' + ), + 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, + 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_PRESTATION_RELATION (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 + +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_PRESTATION_RELATION 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 TABLE FRONT.HEBERGEMENT_TO_PRESTATION_RELATION ; +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..adf24902b 100644 --- a/packages/shared/src/schema/adresse.js +++ b/packages/shared/src/schema/adresse.js @@ -4,6 +4,7 @@ export const adresseSchema = ({ isFromAPIAdresse } = {}) => { return isFromAPIAdresse ? { codeInsee: yup.string().required("ce champ est obligatoire"), + cleInsee: 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"),