diff --git a/DESCRIPTION b/DESCRIPTION
index 3eada66b4af238ccf496852f584ebfdb20a4a76a..b2a02ff4b9415e04c0e34e6608de0d9ae989a7d5 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -7,6 +7,11 @@ Authors@R:
 Description: Import des données nitrates à partir des sources ARS et
     Hub'eau dans une base de données PostgreSQL.
 License: MIT + file LICENSE
+Imports: 
+    datalibaba,
+    DBI,
+    dplyr,
+    glue
 Suggests: 
     knitr,
     rmarkdown
diff --git a/NAMESPACE b/NAMESPACE
index 6ae926839dd1829f1016a96f766d970ff184ad97..c52bc4d7aec300bb94e4b110685e1b71bbf81cb3 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -1,2 +1,10 @@
 # Generated by roxygen2: do not edit by hand
 
+export(add_code_prelevement)
+export(create_nitrate_analyse_table)
+export(create_nitrate_prelevement_table)
+importFrom(DBI,dbDisconnect)
+importFrom(DBI,dbGetQuery)
+importFrom(datalibaba,connect_to_db)
+importFrom(dplyr,mutate)
+importFrom(glue,glue)
diff --git a/R/add_code_prelevement.R b/R/add_code_prelevement.R
new file mode 100644
index 0000000000000000000000000000000000000000..b3b98ea269059c1d1cd88b54e02cdc376a2b21b9
--- /dev/null
+++ b/R/add_code_prelevement.R
@@ -0,0 +1,48 @@
+# WARNING - Generated by {fusen} from dev/flat_insert_ars_into_prelevement.Rmd: do not edit by hand
+
+#' Ajouter une variable code_prelevement au dataframe
+#'
+#' @description Cette fonction ajoute une nouvelle variable `code_prelevement` 
+#' au dataframe en utilisant une séquence PostgreSQL dynamique. La séquence est 
+#' construite en fonction du paramètre `version` fourni.
+#'
+#' @param dataframe Un dataframe contenant les données sur lesquelles ajouter 
+#' la variable `code_prelevement`.
+#' @param version Une chaîne de caractères représentant la version de la 
+#' séquence à utiliser.
+#'
+#' @return Un dataframe avec une nouvelle colonne `code_prelevement` contenant 
+#' les valeurs de la séquence PostgreSQL.
+#' 
+#' @importFrom DBI dbGetQuery dbDisconnect
+#' @importFrom dplyr mutate
+#' @importFrom glue glue
+#' @importFrom datalibaba connect_to_db
+#' @export
+add_code_prelevement <- function(dataframe, version) {
+  # Établir une connexion à la base de données PostgreSQL
+  connexion <- datalibaba::connect_to_db(db = "si_eau", user = "admin")
+  
+  # Construire le nom de la séquence
+  sequence_name <- glue::glue("nitrates.nitrate_prelevement_{version}_code_prelevement_seq")
+  
+  # Initialiser une liste pour stocker les valeurs de la séquence
+  code_prelevements <- c()
+  
+  # Pour chaque ligne du dataframe, obtenir une valeur de la séquence
+  for (i in 1:nrow(dataframe)) {
+    query <- glue::glue("SELECT nextval(\'{sequence_name}\') AS code_prelevement")
+    result <- DBI::dbGetQuery(connexion, query)
+    code_prelevements <- c(code_prelevements, result$code_prelevement)
+  }
+  
+  # Ajouter la nouvelle variable au dataframe
+  dataframe <- dataframe |>
+    dplyr::mutate(code_prelevement = code_prelevements)
+  
+  # Fermer la connexion à la base de données
+  DBI::dbDisconnect(connexion)
+  
+  return(dataframe)
+}
+
diff --git a/R/create_nitrate_prelevement_table.R b/R/create_nitrate_prelevement_table.R
new file mode 100644
index 0000000000000000000000000000000000000000..4e87ea70feae25fd5e95fac52a661c5b7662916e
--- /dev/null
+++ b/R/create_nitrate_prelevement_table.R
@@ -0,0 +1,191 @@
+# WARNING - Generated by {fusen} from dev/flat_create_tables.Rmd: do not edit by hand
+
+#' Créer une table d'analyses de nitrates
+#'
+#' @description Cette fonction crée une table dans une base de données PostgreSQL 
+#' pour stocker les informations relatives aux analyses de nitrates, incluant 
+#' les contraintes et les séquences nécessaires.
+#'
+#' @param version String. Version de la table (par exemple, 'v1').
+#' @param last_year Integer. L'année la plus récente incluse dans les données de la table.
+#' @param connexion DBIConnection. Connexion active à la base de données PostgreSQL.
+#'
+#' @return String. Le script SQL utilisé pour créer la table.
+#' @export
+#' @importFrom datalibaba connect_to_db
+#' @examples
+#' # Connexion à la base de données
+#' connexion <- datalibaba::connect_to_db(db = "si_eau", user = "admin")
+#'
+#' # Création du script SQL avec la version choisie
+#' version <- "v0_15"
+#' last_year <- "2023"
+#' sql <- create_nitrate_analyse_table(version, last_year, connexion)
+create_nitrate_analyse_table <- function(version, last_year, connexion) {
+
+  # Génération de la date du jour
+  date_now <- format(Sys.Date(), "%d/%m/%Y")
+
+  # Création du script avec l'ajout des paramètres
+  sql_script <- glue::glue("
+    CREATE TABLE IF NOT EXISTS nitrates.nitrate_analyse_{version}
+    (
+      code_analyse serial NOT NULL,
+      code_intervenant character varying(20),
+      code_prelevement integer,
+      code_parametre bigint,
+      code_fraction_analysee integer,
+      date_analyse date,
+      resultat_analyse double precision,
+      code_remarque integer,
+      limite_detection double precision,
+      limite_quantification double precision,
+      CONSTRAINT pk_nitrate_analyse_{version} PRIMARY KEY (code_analyse),
+      CONSTRAINT fk_n_fraction_analysee FOREIGN KEY (code_fraction_analysee)
+          REFERENCES sandre.n_fraction_analysee (code_fraction_analysee) MATCH SIMPLE
+          ON UPDATE CASCADE ON DELETE SET DEFAULT,
+      -- CONSTRAINT fk_n_intervenant FOREIGN KEY (code_intervenant)
+         -- REFERENCES qualite_cours_d_eau.n_intervenant (code_intervenant) MATCH SIMPLE
+         -- ON UPDATE CASCADE ON DELETE SET DEFAULT,
+      CONSTRAINT fk_n_remarque FOREIGN KEY (code_remarque)
+          REFERENCES sandre.n_remarque (code_remarque) MATCH SIMPLE
+          ON UPDATE NO ACTION ON DELETE NO ACTION,
+      CONSTRAINT fk_parametre FOREIGN KEY (code_parametre)
+          REFERENCES qualite_cours_d_eau.parametre (code_parametre) MATCH SIMPLE
+          ON UPDATE CASCADE ON DELETE SET DEFAULT
+    )
+    WITH (
+      OIDS=FALSE
+    );
+
+    ALTER TABLE nitrates.nitrate_analyse_{version}
+      OWNER TO adminpsql;
+
+    GRANT ALL ON TABLE nitrates.nitrate_analyse_{version} TO adminpsql;
+    GRANT ALL ON TABLE nitrates.nitrate_analyse_{version} TO writer_production;
+    GRANT SELECT ON TABLE nitrates.nitrate_analyse_{version} TO reader_production;
+
+    COMMENT ON TABLE nitrates.nitrate_analyse_{version}
+      IS 'Table des analyses 2007-{last_year} (version {version} du {date_now})';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.code_analyse IS 'Identifiant de l''analyse';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.code_intervenant IS 'Identifiant du laboratoire ayant effectu\u00e9 l''analyse';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.code_prelevement IS 'Identifiant du pr\u00e9l\u00e8vement';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.code_parametre IS 'Identifiant du param\u00e8tre analys\u00e9';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.code_fraction_analysee IS 'Identifiant de la fraction analys\u00e9e';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.date_analyse IS 'Date de l''analyse';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.resultat_analyse IS 'R\u00e9sultat de l''analyse';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.code_remarque IS 'Code validant la donn\u00e9e';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.limite_detection IS 'Limite de d\u00e9tection';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.limite_quantification IS 'Limite de quantification';
+
+    CREATE SEQUENCE IF NOT EXISTS nitrates.nitrate_analyse_{version}_code_analyse_seq
+        INCREMENT 1
+        START 1
+        MINVALUE 1
+        MAXVALUE 2147483647
+        CACHE 1;
+
+    ALTER SEQUENCE nitrates.nitrate_analyse_{version}_code_analyse_seq
+        OWNER TO adminpsql;
+  ")
+
+  # Exécution du script dans la base de données
+  DBI::dbExecute(connexion, sql_script)
+
+  # Fermeture de la connexion à la base de données
+  DBI::dbDisconnect(connexion)
+
+  return(sql_script)
+}
+
+
+#' Créer une table de prélèvements de nitrates
+#'
+#' @description Cette fonction crée une table dans une base de données PostgreSQL 
+#' pour stocker les informations relatives aux prélèvements de nitrates, 
+#' incluant les contraintes et les séquences nécessaires.
+#'
+#' @param version String. Version de la table (par exemple, 'v1').
+#' @param last_year Integer. L'année la plus récente incluse dans les données de la table.
+#' @param connexion DBIConnection. Connexion active à la base de données PostgreSQL.
+#'
+#' @return String. Le script SQL utilisé pour créer la table.
+#' @export
+#' @importFrom datalibaba connect_to_db
+#' @examples
+#' # Connexion à la base de données
+#' connexion <- datalibaba::connect_to_db(db = "si_eau", user = "admin")
+#'
+#' # Création du script SQL avec la version choisie
+#' version <- "v0_15"
+#' last_year <- "2023"
+#' sql <- create_nitrate_prelevement_table(version, last_year, connexion)
+create_nitrate_prelevement_table  <- function(version, last_year, connexion) {
+  
+  # Génération de la date du jour
+  date_now <- format(Sys.Date(), "%d/%m/%Y")
+  
+  # Création du script avec l'ajout des paramètres
+  sql_script <- glue::glue("
+    CREATE TABLE IF NOT EXISTS nitrates.nitrate_prelevement_{version}
+    (
+      code_prelevement serial NOT NULL,
+      code_intervenant character varying(20),
+      source character varying(10),
+      code_reseau character varying(254),
+      code_station character varying(10),
+      date_prelevement date,
+      heure_prelevement character varying(8),
+      code_support int,
+      id_usage character varying(3),
+      id_prelevement_motif character varying(2),
+      commentaire character varying(254),
+      CONSTRAINT pk_nitrate_prelevement_{version} PRIMARY KEY (code_prelevement),
+      CONSTRAINT fk_n_support FOREIGN KEY (code_support)
+          REFERENCES sandre.n_support (code_support) MATCH SIMPLE
+          ON UPDATE CASCADE ON DELETE SET DEFAULT
+    )
+    WITH (
+      OIDS=FALSE
+    );
+
+    ALTER TABLE nitrates.nitrate_prelevement_{version}
+      OWNER TO adminpsql;
+
+    GRANT ALL ON TABLE nitrates.nitrate_prelevement_{version} TO adminpsql;
+    GRANT ALL ON TABLE nitrates.nitrate_prelevement_{version} TO writer_production;
+    GRANT SELECT ON TABLE nitrates.nitrate_prelevement_{version} TO reader_production;
+
+    COMMENT ON TABLE nitrates.nitrate_prelevement_{version}
+      IS 'Table des pr\u00e9l\u00e8vements 2007-{last_year} (version {version} du {date_now})';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.code_prelevement IS 'Identifiant du pr\u00e9l\u00e8vement';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.code_intervenant IS 'Identifiant de l''intervenant';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.source IS 'Source de la donn\u00e9e';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.code_reseau IS 'Identifiant du r\u00e9seau';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.code_station IS 'Identifiant de la station';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.date_prelevement IS 'Date du pr\u00e9l\u00e8vement';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.heure_prelevement IS 'Heure du pr\u00e9l\u00e8vement';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.code_support IS 'Code du support de pr\u00e9l\u00e8vement';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.id_usage IS 'Code de l''usage du pr\u00e9l\u00e8vement';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.id_prelevement_motif IS 'Code du motif du pr\u00e9l\u00e8vement';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.commentaire IS 'Commentaire';
+
+    CREATE SEQUENCE IF NOT EXISTS nitrates.nitrate_prelevement_{version}_code_prelevement_seq
+        INCREMENT 1
+        START 1
+        MINVALUE 1
+        MAXVALUE 2147483647
+        CACHE 1;
+
+    ALTER SEQUENCE nitrates.nitrate_prelevement_{version}_code_prelevement_seq
+        OWNER TO adminpsql;
+  ")
+  
+  # Exécution du script dans la base de données
+  DBI::dbExecute(connexion, sql_script)
+  
+  # Fermeture de la connexion à la base de données
+  DBI::dbDisconnect(connexion)
+  
+  return(sql_script)
+}
diff --git a/dev/config_fusen.yaml b/dev/config_fusen.yaml
index cb722c42e979eea1cbbac7c08a7b6d4b090026d0..9060038f32a7c30350f31266dc8df4d6fd61b355 100644
--- a/dev/config_fusen.yaml
+++ b/dev/config_fusen.yaml
@@ -1,3 +1,16 @@
+flat_create_tables.Rmd:
+  path: dev/flat_create_tables.Rmd
+  state: active
+  R: R/create_nitrate_prelevement_table.R
+  tests: []
+  vignettes: vignettes/creation-des-tables-finales.Rmd
+  inflate:
+    flat_file: dev/flat_create_tables.Rmd
+    vignette_name: Création des tables finales
+    open_vignette: true
+    check: true
+    document: true
+    overwrite: ask
 flat_import_ars_data.Rmd:
   path: dev/flat_import_ars_data.Rmd
   state: active
@@ -50,3 +63,55 @@ flat_import_hubeau_rw_data.Rmd:
     check: true
     document: true
     overwrite: ask
+flat_insert_ars_into_prelevement.Rmd:
+  path: dev/flat_insert_ars_into_prelevement.Rmd
+  state: active
+  R: R/add_code_prelevement.R
+  tests: []
+  vignettes: vignettes/insertion-des-prelevements-ars.Rmd
+  inflate:
+    flat_file: dev/flat_insert_ars_into_prelevement.Rmd
+    vignette_name: Insertion des prélèvements ARS
+    open_vignette: true
+    check: true
+    document: true
+    overwrite: ask
+flat_insert_hubeau_eso_into_prelevement.Rmd:
+  path: dev/flat_insert_hubeau_eso_into_prelevement.Rmd
+  state: active
+  R: []
+  tests: []
+  vignettes: vignettes/insertion-des-prelevements-hubeau-eso.Rmd
+  inflate:
+    flat_file: dev/flat_insert_hubeau_eso_into_prelevement.Rmd
+    vignette_name: Insertion des prélèvements Hubeau ESO
+    open_vignette: true
+    check: true
+    document: true
+    overwrite: ask
+flat_insert_hubeau_esu_into_prelevement.Rmd:
+  path: dev/flat_insert_hubeau_esu_into_prelevement.Rmd
+  state: active
+  R: []
+  tests: []
+  vignettes: vignettes/insertion-des-prelevements-hubeau-esu.Rmd
+  inflate:
+    flat_file: dev/flat_insert_hubeau_esu_into_prelevement.Rmd
+    vignette_name: Insertion des prélèvements Hubeau ESU
+    open_vignette: true
+    check: true
+    document: true
+    overwrite: ask
+flat_insert_into_prelevement.Rmd:
+  path: dev/flat_insert_into_prelevement.Rmd
+  state: active
+  R: R/add_code_prelevement.R
+  tests: []
+  vignettes: vignettes/mise-a-jour-de-la-table-des-prelevements.Rmd
+  inflate:
+    flat_file: dev/flat_insert_into_prelevement.Rmd
+    vignette_name: Mise à jour de la table des prélèvements
+    open_vignette: true
+    check: true
+    document: true
+    overwrite: ask
diff --git a/dev/flat_create_tables.Rmd b/dev/flat_create_tables.Rmd
new file mode 100644
index 0000000000000000000000000000000000000000..059dd427c3c457484378c65c1e5b7a82c572769f
--- /dev/null
+++ b/dev/flat_create_tables.Rmd
@@ -0,0 +1,229 @@
+---
+title: "Cr\u00e9ation des tables finales"
+output: html_document
+editor_options: 
+  chunk_output_type: console
+---
+
+```{r development, include=FALSE}
+library(testthat)
+library(glue)
+library(DBI)
+library(datalibaba)
+```
+
+```{r development-load}
+# Load already included functions if relevant
+pkgload::load_all(export_all = FALSE)
+```
+
+# Présentation
+
+> Cette page contient la logique métier concernant la création des tables de prélèvements et d'analyses concernant les nitrates.
+
+# Table des prélèvements
+
+```{r function-create_nitrate_prelevement_table}
+#' Créer une table de prélèvements de nitrates
+#'
+#' @description Cette fonction crée une table dans une base de données PostgreSQL 
+#' pour stocker les informations relatives aux prélèvements de nitrates, 
+#' incluant les contraintes et les séquences nécessaires.
+#'
+#' @param version String. Version de la table (par exemple, 'v1').
+#' @param last_year Integer. L'année la plus récente incluse dans les données de la table.
+#' @param connexion DBIConnection. Connexion active à la base de données PostgreSQL.
+#'
+#' @return String. Le script SQL utilisé pour créer la table.
+#' @export
+#' @importFrom datalibaba connect_to_db
+create_nitrate_prelevement_table  <- function(version, last_year, connexion) {
+  
+  # Génération de la date du jour
+  date_now <- format(Sys.Date(), "%d/%m/%Y")
+  
+  # Création du script avec l'ajout des paramètres
+  sql_script <- glue::glue("
+    CREATE TABLE IF NOT EXISTS nitrates.nitrate_prelevement_{version}
+    (
+      code_prelevement serial NOT NULL,
+      code_intervenant character varying(20),
+      source character varying(10),
+      code_reseau character varying(254),
+      code_station character varying(10),
+      date_prelevement date,
+      heure_prelevement character varying(8),
+      code_support int,
+      id_usage character varying(3),
+      id_prelevement_motif character varying(2),
+      commentaire character varying(254),
+      CONSTRAINT pk_nitrate_prelevement_{version} PRIMARY KEY (code_prelevement),
+      CONSTRAINT fk_n_support FOREIGN KEY (code_support)
+          REFERENCES sandre.n_support (code_support) MATCH SIMPLE
+          ON UPDATE CASCADE ON DELETE SET DEFAULT
+    )
+    WITH (
+      OIDS=FALSE
+    );
+
+    ALTER TABLE nitrates.nitrate_prelevement_{version}
+      OWNER TO adminpsql;
+
+    GRANT ALL ON TABLE nitrates.nitrate_prelevement_{version} TO adminpsql;
+    GRANT ALL ON TABLE nitrates.nitrate_prelevement_{version} TO writer_production;
+    GRANT SELECT ON TABLE nitrates.nitrate_prelevement_{version} TO reader_production;
+
+    COMMENT ON TABLE nitrates.nitrate_prelevement_{version}
+      IS 'Table des pr\u00e9l\u00e8vements 2007-{last_year} (version {version} du {date_now})';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.code_prelevement IS 'Identifiant du pr\u00e9l\u00e8vement';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.code_intervenant IS 'Identifiant de l''intervenant';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.source IS 'Source de la donn\u00e9e';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.code_reseau IS 'Identifiant du r\u00e9seau';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.code_station IS 'Identifiant de la station';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.date_prelevement IS 'Date du pr\u00e9l\u00e8vement';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.heure_prelevement IS 'Heure du pr\u00e9l\u00e8vement';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.code_support IS 'Code du support de pr\u00e9l\u00e8vement';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.id_usage IS 'Code de l''usage du pr\u00e9l\u00e8vement';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.id_prelevement_motif IS 'Code du motif du pr\u00e9l\u00e8vement';
+    COMMENT ON COLUMN nitrates.nitrate_prelevement_{version}.commentaire IS 'Commentaire';
+
+    CREATE SEQUENCE IF NOT EXISTS nitrates.nitrate_prelevement_{version}_code_prelevement_seq
+        INCREMENT 1
+        START 1
+        MINVALUE 1
+        MAXVALUE 2147483647
+        CACHE 1;
+
+    ALTER SEQUENCE nitrates.nitrate_prelevement_{version}_code_prelevement_seq
+        OWNER TO adminpsql;
+  ")
+  
+  # Exécution du script dans la base de données
+  DBI::dbExecute(connexion, sql_script)
+  
+  # Fermeture de la connexion à la base de données
+  DBI::dbDisconnect(connexion)
+  
+  return(sql_script)
+}
+```
+
+```{r examples-create_nitrate_prelevement_table, eval=FALSE}
+# Connexion à la base de données
+connexion <- datalibaba::connect_to_db(db = "si_eau", user = "admin")
+
+# Création du script SQL avec la version choisie
+version <- "v0_15"
+last_year <- "2023"
+sql <- create_nitrate_prelevement_table(version, last_year, connexion)
+```
+
+```{r function-create_nitrate_analyse_table} 
+#' Créer une table d'analyses de nitrates
+#'
+#' @description Cette fonction crée une table dans une base de données PostgreSQL 
+#' pour stocker les informations relatives aux analyses de nitrates, incluant 
+#' les contraintes et les séquences nécessaires.
+#'
+#' @param version String. Version de la table (par exemple, 'v1').
+#' @param last_year Integer. L'année la plus récente incluse dans les données de la table.
+#' @param connexion DBIConnection. Connexion active à la base de données PostgreSQL.
+#'
+#' @return String. Le script SQL utilisé pour créer la table.
+#' @export
+#' @importFrom datalibaba connect_to_db
+create_nitrate_analyse_table <- function(version, last_year, connexion) {
+
+  # Génération de la date du jour
+  date_now <- format(Sys.Date(), "%d/%m/%Y")
+
+  # Création du script avec l'ajout des paramètres
+  sql_script <- glue::glue("
+    CREATE TABLE IF NOT EXISTS nitrates.nitrate_analyse_{version}
+    (
+      code_analyse serial NOT NULL,
+      code_intervenant character varying(20),
+      code_prelevement integer,
+      code_parametre bigint,
+      code_fraction_analysee integer,
+      date_analyse date,
+      resultat_analyse double precision,
+      code_remarque integer,
+      limite_detection double precision,
+      limite_quantification double precision,
+      CONSTRAINT pk_nitrate_analyse_{version} PRIMARY KEY (code_analyse),
+      CONSTRAINT fk_n_fraction_analysee FOREIGN KEY (code_fraction_analysee)
+          REFERENCES sandre.n_fraction_analysee (code_fraction_analysee) MATCH SIMPLE
+          ON UPDATE CASCADE ON DELETE SET DEFAULT,
+      -- CONSTRAINT fk_n_intervenant FOREIGN KEY (code_intervenant)
+         -- REFERENCES qualite_cours_d_eau.n_intervenant (code_intervenant) MATCH SIMPLE
+         -- ON UPDATE CASCADE ON DELETE SET DEFAULT,
+      CONSTRAINT fk_n_remarque FOREIGN KEY (code_remarque)
+          REFERENCES sandre.n_remarque (code_remarque) MATCH SIMPLE
+          ON UPDATE NO ACTION ON DELETE NO ACTION,
+      CONSTRAINT fk_parametre FOREIGN KEY (code_parametre)
+          REFERENCES qualite_cours_d_eau.parametre (code_parametre) MATCH SIMPLE
+          ON UPDATE CASCADE ON DELETE SET DEFAULT
+    )
+    WITH (
+      OIDS=FALSE
+    );
+
+    ALTER TABLE nitrates.nitrate_analyse_{version}
+      OWNER TO adminpsql;
+
+    GRANT ALL ON TABLE nitrates.nitrate_analyse_{version} TO adminpsql;
+    GRANT ALL ON TABLE nitrates.nitrate_analyse_{version} TO writer_production;
+    GRANT SELECT ON TABLE nitrates.nitrate_analyse_{version} TO reader_production;
+
+    COMMENT ON TABLE nitrates.nitrate_analyse_{version}
+      IS 'Table des analyses 2007-{last_year} (version {version} du {date_now})';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.code_analyse IS 'Identifiant de l''analyse';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.code_intervenant IS 'Identifiant du laboratoire ayant effectu\u00e9 l''analyse';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.code_prelevement IS 'Identifiant du pr\u00e9l\u00e8vement';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.code_parametre IS 'Identifiant du param\u00e8tre analys\u00e9';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.code_fraction_analysee IS 'Identifiant de la fraction analys\u00e9e';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.date_analyse IS 'Date de l''analyse';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.resultat_analyse IS 'R\u00e9sultat de l''analyse';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.code_remarque IS 'Code validant la donn\u00e9e';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.limite_detection IS 'Limite de d\u00e9tection';
+    COMMENT ON COLUMN nitrates.nitrate_analyse_{version}.limite_quantification IS 'Limite de quantification';
+
+    CREATE SEQUENCE IF NOT EXISTS nitrates.nitrate_analyse_{version}_code_analyse_seq
+        INCREMENT 1
+        START 1
+        MINVALUE 1
+        MAXVALUE 2147483647
+        CACHE 1;
+
+    ALTER SEQUENCE nitrates.nitrate_analyse_{version}_code_analyse_seq
+        OWNER TO adminpsql;
+  ")
+
+  # Exécution du script dans la base de données
+  DBI::dbExecute(connexion, sql_script)
+
+  # Fermeture de la connexion à la base de données
+  DBI::dbDisconnect(connexion)
+
+  return(sql_script)
+}
+
+```
+
+```{r examples-create_nitrate_analyse_table, eval=FALSE}
+# Connexion à la base de données
+connexion <- datalibaba::connect_to_db(db = "si_eau", user = "admin")
+
+# Création du script SQL avec la version choisie
+version <- "v0_15"
+last_year <- "2023"
+sql <- create_nitrate_analyse_table(version, last_year, connexion)
+```
+
+```{r development-inflate, eval=FALSE}
+# Run but keep eval=FALSE to avoid infinite loop
+# Execute in the console directly
+fusen::inflate(flat_file = "dev/flat_create_tables.Rmd", vignette_name = "Cr\u00e9ation des tables finales")
+```
+
diff --git a/dev/flat_insert_ars_into_prelevement.Rmd b/dev/flat_insert_ars_into_prelevement.Rmd
new file mode 100644
index 0000000000000000000000000000000000000000..2507cc574230d42bc5c14a05aad6a9cef405ed5c
--- /dev/null
+++ b/dev/flat_insert_ars_into_prelevement.Rmd
@@ -0,0 +1,170 @@
+---
+title: "Insertion des pr\u00e9l\u00e8vements ARS"
+output: html_document
+editor_options: 
+  chunk_output_type: console
+---
+
+```{r development, include=FALSE}
+library(testthat)
+library(datalibaba)
+library(dplyr)
+library(stringr)
+library(glue)
+library(DBI)
+library(RPostgres)
+```
+
+```{r development-load}
+# Load already included functions if relevant
+pkgload::load_all(export_all = FALSE)
+```
+
+# Consolidation et insertion des données de l'ARS dans la table des prélèvements
+
+## Chargement des données ARS brutes
+
+La table des données brutes Nitrates de l'ARS est chargée :
+```{r load-nitrate_data_analyse_ars, eval=FALSE}
+nitrate_data_analyse_ars <- datalibaba::importer_data(
+  table = "nitrate_data_analyse_ars",
+  schema = "nitrates",
+  db = "si_eau",
+  user = "admin"
+)
+```
+
+## Consolidation des données ARS
+
+On ajoute les variables `source` et `code_support` :
+```{r add-source_code_support_ars, eval=FALSE}
+# Ajouter les variables source et code_support
+nitrate_data_analyse_ars <- nitrate_data_analyse_ars |>
+  dplyr::mutate(
+    source = "ARS",
+    code_support = 3
+  )
+```
+
+On remplace "h" par ":" dans la variable `plv_heure` :
+```{r replace-in_plv_heure, eval=FALSE}
+# Remplacer "h" par ":" dans la colonne plv_heure
+nitrate_data_analyse_ars <- nitrate_data_analyse_ars |>
+  dplyr::mutate(plv_heure = stringr::str_replace_all(plv_heure, "h", ":"))
+```
+
+On sélectionne les champs utiles à la table des prélèvements :
+```{r select-variables-ars, eval=FALSE}
+# Sélectionner les variables
+nitrate_data_analyse_ars <- nitrate_data_analyse_ars |>
+  dplyr::select(code_intervenant = geo_dept_ddass_gest_code,
+                source,
+                code_station = ins_code_national,
+                date_prelevement = plv_date,
+                heure_prelevement = plv_heure,
+                code_support,
+                id_usage = usage,
+                id_prelevement_motif = plv_motif)
+
+```
+
+On dédoublonne les lignes en utilisant les champs `code_station` et `date_prelevement` 
+afin de ne conserver qu'un prélèvement par station et date donnée :
+```{r select-distinct-rows-ars, eval=FALSE}
+# Dédoublonner les lignes sur les colonnes code_station et date_prelevement
+nitrate_data_analyse_ars <- nitrate_data_analyse_ars |>
+  dplyr::distinct(code_station, date_prelevement, .keep_all = TRUE)
+```
+
+```{r function-add_code_prelevement, eval=FALSE} 
+#' Ajouter une variable code_prelevement au dataframe
+#'
+#' @description Cette fonction ajoute une nouvelle variable `code_prelevement` 
+#' au dataframe en utilisant une séquence PostgreSQL dynamique. La séquence est 
+#' construite en fonction du paramètre `version` fourni.
+#'
+#' @param dataframe Un dataframe contenant les données sur lesquelles ajouter 
+#' la variable `code_prelevement`.
+#' @param version Une chaîne de caractères représentant la version de la 
+#' séquence à utiliser.
+#'
+#' @return Un dataframe avec une nouvelle colonne `code_prelevement` contenant 
+#' les valeurs de la séquence PostgreSQL.
+#' 
+#' @importFrom DBI dbGetQuery dbDisconnect
+#' @importFrom dplyr mutate
+#' @importFrom glue glue
+#' @importFrom datalibaba connect_to_db
+#' @export
+add_code_prelevement <- function(dataframe, version) {
+  # Établir une connexion à la base de données PostgreSQL
+  connexion <- datalibaba::connect_to_db(db = "si_eau", user = "admin")
+  
+  # Construire le nom de la séquence
+  sequence_name <- glue::glue("nitrates.nitrate_prelevement_{version}_code_prelevement_seq")
+  
+  # Initialiser une liste pour stocker les valeurs de la séquence
+  code_prelevements <- c()
+  
+  # Pour chaque ligne du dataframe, obtenir une valeur de la séquence
+  for (i in 1:nrow(dataframe)) {
+    query <- glue::glue("SELECT nextval(\'{sequence_name}\') AS code_prelevement")
+    result <- DBI::dbGetQuery(connexion, query)
+    code_prelevements <- c(code_prelevements, result$code_prelevement)
+  }
+  
+  # Ajouter la nouvelle variable au dataframe
+  dataframe <- dataframe |>
+    dplyr::mutate(code_prelevement = code_prelevements)
+  
+  # Fermer la connexion à la base de données
+  DBI::dbDisconnect(connexion)
+  
+  return(dataframe)
+}
+
+```
+
+On ajoute un identifiant unique s'appuyant sur une séquence stockée en base :
+```{r add_code_prelevement_ars, eval=FALSE}
+# Utiliser la fonction add_code_prelevement_ars avec la version souhaitée
+nitrate_data_analyse_ars <- add_code_prelevement(
+  nitrate_data_analyse_ars, "v0_15")
+
+# Afficher le dataframe pour vérifier les modifications
+print(nitrate_data_analyse_ars)
+
+```
+
+On charge les données consolidées dans un table dédiée :
+```{r insert-into_nitrate_prelevement_v0_15, eval=FALSE}
+# Charger les données dans une nouvelle table en base
+datalibaba::poster_data(data = nitrate_data_analyse_ars, 
+                        table = "nitrate_prelevement_ars_v0_15", 
+                        schema = "nitrates", 
+                        db = "si_eau",
+                        overwrite = TRUE,
+                        pk = "code_prelevement",
+                        user = "admin")
+```
+
+# Insertion des données ARS du nouveau millésime en base dans la table globale
+
+On insère enfin les enregistrements de cette table dans la table globale :
+```{r import_and_merge_tables_ars, eval=FALSE}
+# Insérer les données de la table du dernier millésime vers la table complète
+collectr::import_and_merge_tables(database = "si_eau",
+                                  source_table = "nitrate_prelevement_ars_v0_15", 
+                                  source_schema = "nitrates", 
+                                  target_table = "nitrate_prelevement_v0_15", 
+                                  target_schema = "nitrates",
+                                  role = "admin")
+
+```
+
+```{r development-inflate, eval=FALSE}
+# Run but keep eval=FALSE to avoid infinite loop
+# Execute in the console directly
+fusen::inflate(flat_file = "dev/flat_insert_ars_into_prelevement.Rmd", vignette_name = "Insertion des pr\u00e9l\u00e8vements ARS")
+```
+
diff --git a/dev/flat_insert_hubeau_eso_into_prelevement.Rmd b/dev/flat_insert_hubeau_eso_into_prelevement.Rmd
new file mode 100644
index 0000000000000000000000000000000000000000..9672477f2e432100ca3615459ff3949d4d563785
--- /dev/null
+++ b/dev/flat_insert_hubeau_eso_into_prelevement.Rmd
@@ -0,0 +1,126 @@
+---
+title: "Insertion des pr\u00e9l\u00e8vements Hubeau ESO"
+output: html_document
+editor_options: 
+  chunk_output_type: console
+---
+
+```{r development, include=FALSE}
+library(testthat)
+library(datalibaba)
+library(dplyr)
+library(stringr)
+library(glue)
+library(DBI)
+library(RPostgres)
+```
+
+```{r development-load}
+# Load already included functions if relevant
+pkgload::load_all(export_all = FALSE)
+```
+
+# Consolidation et insertion des données Hub'eau ESO dans la table des prélèvements
+
+## Chargement des données Hub'eau ESO
+
+La table des données brutes Nitrates Hub'eau ESO est chargée :
+```{r load-nitrate_data_analyse_hubeau_eso, eval=FALSE}
+nitrate_qualite_nappes_analyses <- datalibaba::importer_data(
+  table = "nitrate_qualite_nappes_analyses",
+  schema = "qualite_nappes_eau_souterraine",
+  db = "si_eau",
+  user = "admin"
+)
+```
+
+## Filtre par code_producteur pour exclure les données ARS
+
+On sélectionne les code_producteur correspondants aux enregistrements hors 
+données ARS de la région :
+```{r select-code_producteur_hubeau_eso, eval=FALSE}
+nitrate_qualite_nappes_analyses <- nitrate_qualite_nappes_analyses |>
+  dplyr::filter(!code_producteur %in% c('44','49','53','72','85'))
+```
+
+## Consolidation des données Hub'eau ESO
+
+On ajoute les variables `source` et `code_support` :
+```{r add-source_code_support_hubeau_eso, eval=FALSE}
+# Ajouter les variables source et code_support
+nitrate_qualite_nappes_analyses <- nitrate_qualite_nappes_analyses |>
+  dplyr::mutate(
+    source = "ADES",
+    code_support = 3)
+```
+
+On sélectionne les champs utiles à la table des prélèvements :
+```{r select-variables_hubeau_eso, eval=FALSE}
+# Sélectionner les variables
+nitrate_qualite_nappes_analyses <- nitrate_qualite_nappes_analyses |>
+  dplyr::select(source,
+                code_reseau = codes_reseau,
+                code_station = bss_id,
+                date_prelevement = date_debut_prelevement,
+                code_support)
+```
+
+On modifie le type de la variable `code_support` de character en integer :
+```{r change-type_code_support, eval=FALSE}
+# Convertir la variable code_support de character en integer
+nitrate_qualite_nappes_analyses <- nitrate_qualite_nappes_analyses |>
+  dplyr::mutate(code_support = as.integer(code_support))
+```
+
+On dédoublonne les lignes en utilisant les champs `code_station` et 
+`date_prelevement` afin de ne conserver qu'un prélèvement par station et date 
+donnée :
+```{r select-distinct-rows_hubeau_eso, eval=FALSE}
+# Dédoublonner les lignes sur les colonnes code_station et date_prelevement
+nitrate_qualite_nappes_analyses <- nitrate_qualite_nappes_analyses |>
+  dplyr::distinct(code_station, date_prelevement, .keep_all = TRUE)
+```
+
+On ajoute un identifiant unique s'appuyant sur une séquence stockée en base :
+```{r add_code_prelevement_hubeau_eso, eval=FALSE}
+# Utiliser la fonction add_code_prelevement avec la version souhaitée
+nitrate_qualite_nappes_analyses <- add_code_prelevement(
+  nitrate_qualite_nappes_analyses, "v0_15")
+
+# Afficher le dataframe pour vérifier les modifications
+print(nitrate_qualite_nappes_analyses)
+
+```
+
+On charge les données consolidées dans un table dédiée :
+```{r insert-into_nitrate_prelevement_hubeau_eso, eval=FALSE}
+# Charger les données dans une nouvelle table en base
+datalibaba::poster_data(data = nitrate_qualite_nappes_analyses, 
+                        table = "nitrate_prelevement_hubeau_eso_v0_15", 
+                        schema = "nitrates", 
+                        db = "si_eau",
+                        overwrite = TRUE,
+                        pk = "code_prelevement",
+                        user = "admin")
+```
+
+# Insertion des données Hub'eau ESO du nouveau millésime en base dans la table globale
+
+On insère enfin les enregistrements de cette table dans la table globale :
+```{r import_and_merge_tables_hubeau_eso, eval=FALSE}
+# Insérer les données de la table du dernier millésime vers la table complète
+collectr::import_and_merge_tables(database = "si_eau",
+                                  source_table = "nitrate_prelevement_hubeau_eso_v0_15", 
+                                  source_schema = "nitrates", 
+                                  target_table = "nitrate_prelevement_v0_15", 
+                                  target_schema = "nitrates",
+                                  role = "admin")
+
+```
+
+```{r development-inflate, eval=FALSE}
+# Run but keep eval=FALSE to avoid infinite loop
+# Execute in the console directly
+fusen::inflate(flat_file = "dev/flat_insert_hubeau_eso_into_prelevement.Rmd", vignette_name = "Insertion des pr\u00e9l\u00e8vements Hubeau ESO")
+```
+
diff --git a/dev/flat_insert_hubeau_esu_into_prelevement.Rmd b/dev/flat_insert_hubeau_esu_into_prelevement.Rmd
new file mode 100644
index 0000000000000000000000000000000000000000..d2f7c95009abaf2b3c5dc67471ab7f63a7fe03e0
--- /dev/null
+++ b/dev/flat_insert_hubeau_esu_into_prelevement.Rmd
@@ -0,0 +1,127 @@
+---
+title: "Insertion des pr\u00e9l\u00e8vements Hubeau ESU"
+output: html_document
+editor_options: 
+  chunk_output_type: console
+---
+
+```{r development, include=FALSE}
+library(testthat)
+library(datalibaba)
+library(dplyr)
+library(stringr)
+library(glue)
+library(DBI)
+library(RPostgres)
+```
+
+```{r development-load}
+# Load already included functions if relevant
+pkgload::load_all(export_all = FALSE)
+```
+
+# Consolidation et insertion des données Hub'eau ESU dans la table des prélèvements
+
+## Chargement des données Hub'eau ESU
+
+La table des données brutes Nitrates Hub'eau ESU est chargée :
+```{r load-nitrate_data_analyse_hubeau_esu, eval=FALSE}
+nitrate_qualite_rivieres_analyse_pc <- datalibaba::importer_data(
+  table = "nitrate_qualite_rivieres_analyse_pc",
+  schema = "qualite_cours_d_eau",
+  db = "si_eau",
+  user = "admin"
+)
+```
+
+## Consolidation des données Hub'eau ESU
+
+On remplace "." par "," dans les variables `limite_detection` et `limite_quantification` :
+```{r replace-in_limite_detection, eval=FALSE}
+# Remplacer "." par "," dans les colonnes limite_detection et limite_quantification
+nitrate_qualite_rivieres_analyse_pc <- nitrate_qualite_rivieres_analyse_pc |>
+  dplyr::mutate(
+    limite_detection = stringr::str_replace_all(limite_detection, ".", ","),
+    limite_quantification = stringr::str_replace_all(limite_quantification, ".", ",")
+    )
+```
+
+On ajoute la variable `source` :
+```{r add-source_code_support_hubeau_esu, eval=FALSE}
+# Ajouter les variables source et code_support
+nitrate_qualite_rivieres_analyse_pc <- nitrate_qualite_rivieres_analyse_pc |>
+  dplyr::mutate(source = "Na\u00efades")
+```
+
+On sélectionne les champs utiles à la table des prélèvements :
+```{r select-variables_hubeau_esu, eval=FALSE}
+# Sélectionner les variables
+nitrate_qualite_rivieres_analyse_pc <- nitrate_qualite_rivieres_analyse_pc |>
+  dplyr::select(source,
+                code_reseau,
+                code_station,
+                date_prelevement,
+                heure_prelevement,
+                code_support,
+                commentaire = commentaires_analyse)
+```
+
+On modifie le type de la variable `code_support` de character en integer :
+```{r change-type_code_support, eval=FALSE}
+# Convertir la variable code_support de character en integer
+nitrate_qualite_rivieres_analyse_pc <- nitrate_qualite_rivieres_analyse_pc |>
+  dplyr::mutate(code_support = as.integer(code_support))
+```
+
+On dédoublonne les lignes en utilisant les champs `code_station` et 
+`date_prelevement` afin de ne conserver qu'un prélèvement par station et date 
+donnée :
+```{r select-distinct-rows_hubeau_esu, eval=FALSE}
+# Dédoublonner les lignes sur les colonnes code_station et date_prelevement
+nitrate_qualite_rivieres_analyse_pc <- nitrate_qualite_rivieres_analyse_pc |>
+  dplyr::distinct(code_station, date_prelevement, .keep_all = TRUE)
+```
+
+On ajoute un identifiant unique s'appuyant sur une séquence stockée en base :
+```{r add_code_prelevement_hubeau_esu, eval=FALSE}
+# Utiliser la fonction add_code_prelevement avec la version souhaitée
+nitrate_qualite_rivieres_analyse_pc <- add_code_prelevement(
+  nitrate_qualite_rivieres_analyse_pc, "v0_15")
+
+# Afficher le dataframe pour vérifier les modifications
+print(nitrate_qualite_rivieres_analyse_pc)
+
+```
+
+On charge les données consolidées dans un table dédiée :
+```{r insert-into_nitrate_prelevement_hubeau_esu, eval=FALSE}
+# Charger les données dans une nouvelle table en base
+datalibaba::poster_data(data = nitrate_qualite_rivieres_analyse_pc, 
+                        table = "nitrate_prelevement_hubeau_esu_v0_15", 
+                        schema = "nitrates", 
+                        db = "si_eau",
+                        overwrite = TRUE,
+                        pk = "code_prelevement",
+                        user = "admin")
+```
+
+# Insertion des données Hub'eau ESU du nouveau millésime en base dans la table globale
+
+On insère enfin les enregistrements de cette table dans la table globale :
+```{r import_and_merge_tables_hubeau_esu, eval=FALSE}
+# Insérer les données de la table du dernier millésime vers la table complète
+collectr::import_and_merge_tables(database = "si_eau",
+                                  source_table = "nitrate_prelevement_hubeau_esu_v0_15", 
+                                  source_schema = "nitrates", 
+                                  target_table = "nitrate_prelevement_v0_15", 
+                                  target_schema = "nitrates",
+                                  role = "admin")
+
+```
+
+```{r development-inflate, eval=FALSE}
+# Run but keep eval=FALSE to avoid infinite loop
+# Execute in the console directly
+fusen::inflate(flat_file = "dev/flat_insert_hubeau_esu_into_prelevement.Rmd", vignette_name = "Insertion des pr\u00e9l\u00e8vements Hubeau ESU")
+```
+
diff --git a/man/add_code_prelevement.Rd b/man/add_code_prelevement.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..f325b8e38fe56bcf26f684968b4f102b51d84966
--- /dev/null
+++ b/man/add_code_prelevement.Rd
@@ -0,0 +1,24 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/add_code_prelevement.R
+\name{add_code_prelevement}
+\alias{add_code_prelevement}
+\title{Ajouter une variable code_prelevement au dataframe}
+\usage{
+add_code_prelevement(dataframe, version)
+}
+\arguments{
+\item{dataframe}{Un dataframe contenant les données sur lesquelles ajouter
+la variable \code{code_prelevement}.}
+
+\item{version}{Une chaîne de caractères représentant la version de la
+séquence à utiliser.}
+}
+\value{
+Un dataframe avec une nouvelle colonne \code{code_prelevement} contenant
+les valeurs de la séquence PostgreSQL.
+}
+\description{
+Cette fonction ajoute une nouvelle variable \code{code_prelevement}
+au dataframe en utilisant une séquence PostgreSQL dynamique. La séquence est
+construite en fonction du paramètre \code{version} fourni.
+}
diff --git a/man/create_nitrate_analyse_table.Rd b/man/create_nitrate_analyse_table.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..8e3c978d34ab80f82b2e924a3149faedd4a3b71b
--- /dev/null
+++ b/man/create_nitrate_analyse_table.Rd
@@ -0,0 +1,32 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/create_nitrate_prelevement_table.R
+\name{create_nitrate_analyse_table}
+\alias{create_nitrate_analyse_table}
+\title{Créer une table d'analyses de nitrates}
+\usage{
+create_nitrate_analyse_table(version, last_year, connexion)
+}
+\arguments{
+\item{version}{String. Version de la table (par exemple, 'v1').}
+
+\item{last_year}{Integer. L'année la plus récente incluse dans les données de la table.}
+
+\item{connexion}{DBIConnection. Connexion active à la base de données PostgreSQL.}
+}
+\value{
+String. Le script SQL utilisé pour créer la table.
+}
+\description{
+Cette fonction crée une table dans une base de données PostgreSQL
+pour stocker les informations relatives aux analyses de nitrates, incluant
+les contraintes et les séquences nécessaires.
+}
+\examples{
+# Connexion à la base de données
+connexion <- datalibaba::connect_to_db(db = "si_eau", user = "admin")
+
+# Création du script SQL avec la version choisie
+version <- "v0_15"
+last_year <- "2023"
+sql <- create_nitrate_analyse_table(version, last_year, connexion)
+}
diff --git a/man/create_nitrate_prelevement_table.Rd b/man/create_nitrate_prelevement_table.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..1ce577962fedd7b01dce091861201205d786caee
--- /dev/null
+++ b/man/create_nitrate_prelevement_table.Rd
@@ -0,0 +1,32 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/create_nitrate_prelevement_table.R
+\name{create_nitrate_prelevement_table}
+\alias{create_nitrate_prelevement_table}
+\title{Créer une table de prélèvements de nitrates}
+\usage{
+create_nitrate_prelevement_table(version, last_year, connexion)
+}
+\arguments{
+\item{version}{String. Version de la table (par exemple, 'v1').}
+
+\item{last_year}{Integer. L'année la plus récente incluse dans les données de la table.}
+
+\item{connexion}{DBIConnection. Connexion active à la base de données PostgreSQL.}
+}
+\value{
+String. Le script SQL utilisé pour créer la table.
+}
+\description{
+Cette fonction crée une table dans une base de données PostgreSQL
+pour stocker les informations relatives aux prélèvements de nitrates,
+incluant les contraintes et les séquences nécessaires.
+}
+\examples{
+# Connexion à la base de données
+connexion <- datalibaba::connect_to_db(db = "si_eau", user = "admin")
+
+# Création du script SQL avec la version choisie
+version <- "v0_15"
+last_year <- "2023"
+sql <- create_nitrate_prelevement_table(version, last_year, connexion)
+}
diff --git a/vignettes/creation-des-tables-finales.Rmd b/vignettes/creation-des-tables-finales.Rmd
new file mode 100644
index 0000000000000000000000000000000000000000..37b8ba7edc61e4a1323fef0f2acd29304684151b
--- /dev/null
+++ b/vignettes/creation-des-tables-finales.Rmd
@@ -0,0 +1,49 @@
+---
+title: "Création des tables finales"
+output: rmarkdown::html_vignette
+vignette: >
+  %\VignetteIndexEntry{creation-des-tables-finales}
+  %\VignetteEngine{knitr::rmarkdown}
+  %\VignetteEncoding{UTF-8}
+---
+
+```{r, include = FALSE}
+knitr::opts_chunk$set(
+  collapse = TRUE,
+  comment = "#>"
+)
+```
+
+```{r setup}
+library(data.nitrates)
+```
+
+<!-- WARNING - This vignette is generated by {fusen} from dev/flat_create_tables.Rmd: do not edit by hand -->
+
+# Présentation
+
+> Cette page contient la logique métier concernant la création des tables de prélèvements et d'analyses concernant les nitrates.
+
+
+# Table des prélèvements
+
+```{r examples-create_nitrate_prelevement_table, eval = FALSE}
+# Connexion à la base de données
+connexion <- datalibaba::connect_to_db(db = "si_eau", user = "admin")
+
+# Création du script SQL avec la version choisie
+version <- "v0_15"
+last_year <- "2023"
+sql <- create_nitrate_prelevement_table(version, last_year, connexion)
+```
+
+```{r examples-create_nitrate_analyse_table, eval = FALSE}
+# Connexion à la base de données
+connexion <- datalibaba::connect_to_db(db = "si_eau", user = "admin")
+
+# Création du script SQL avec la version choisie
+version <- "v0_15"
+last_year <- "2023"
+sql <- create_nitrate_analyse_table(version, last_year, connexion)
+```
+
diff --git a/vignettes/insertion-des-prelevements-ars.Rmd b/vignettes/insertion-des-prelevements-ars.Rmd
new file mode 100644
index 0000000000000000000000000000000000000000..0d13459ca561cd9605e756675d9f7dfb7ae83fe9
--- /dev/null
+++ b/vignettes/insertion-des-prelevements-ars.Rmd
@@ -0,0 +1,123 @@
+---
+title: "Insertion des prélèvements ARS"
+output: rmarkdown::html_vignette
+vignette: >
+  %\VignetteIndexEntry{insertion-des-prelevements-ars}
+  %\VignetteEngine{knitr::rmarkdown}
+  %\VignetteEncoding{UTF-8}
+---
+
+```{r, include = FALSE}
+knitr::opts_chunk$set(
+  collapse = TRUE,
+  comment = "#>"
+)
+```
+
+```{r setup}
+library(data.nitrates)
+```
+
+<!-- WARNING - This vignette is generated by {fusen} from dev/flat_insert_ars_into_prelevement.Rmd: do not edit by hand -->
+
+# Consolidation et insertion des données de l'ARS dans la table des prélèvements
+
+## Chargement des données ARS brutes
+
+La table des données brutes Nitrates de l'ARS est chargée :
+
+```{r load-nitrate_data_analyse_ars, eval = FALSE}
+nitrate_data_analyse_ars <- datalibaba::importer_data(
+  table = "nitrate_data_analyse_ars",
+  schema = "nitrates",
+  db = "si_eau",
+  user = "admin"
+)
+```
+
+## Consolidation des données ARS
+
+On ajoute les variables `source` et `code_support` :
+
+```{r add-source_code_support_ars, eval = FALSE}
+# Ajouter les variables source et code_support
+nitrate_data_analyse_ars <- nitrate_data_analyse_ars |>
+  dplyr::mutate(
+    source = "ARS",
+    code_support = 3
+  )
+```
+
+On remplace "h" par ":" dans la variable `plv_heure` :
+
+```{r replace-in_plv_heure, eval = FALSE}
+# Remplacer "h" par ":" dans la colonne plv_heure
+nitrate_data_analyse_ars <- nitrate_data_analyse_ars |>
+  dplyr::mutate(plv_heure = stringr::str_replace_all(plv_heure, "h", ":"))
+```
+
+On sélectionne les champs utiles à la table des prélèvements :
+
+```{r select-variables-ars, eval = FALSE}
+# Sélectionner les variables
+nitrate_data_analyse_ars <- nitrate_data_analyse_ars |>
+  dplyr::select(code_intervenant = geo_dept_ddass_gest_code,
+                source,
+                code_station = ins_code_national,
+                date_prelevement = plv_date,
+                heure_prelevement = plv_heure,
+                code_support,
+                id_usage = usage,
+                id_prelevement_motif = plv_motif)
+
+```
+
+On dédoublonne les lignes en utilisant les champs `code_station` et `date_prelevement` 
+afin de ne conserver qu'un prélèvement par station et date donnée :
+
+```{r select-distinct-rows-ars, eval = FALSE}
+# Dédoublonner les lignes sur les colonnes code_station et date_prelevement
+nitrate_data_analyse_ars <- nitrate_data_analyse_ars |>
+  dplyr::distinct(code_station, date_prelevement, .keep_all = TRUE)
+```
+
+On ajoute un identifiant unique s'appuyant sur une séquence stockée en base :
+
+```{r add_code_prelevement_ars, eval = FALSE}
+# Utiliser la fonction add_code_prelevement_ars avec la version souhaitée
+nitrate_data_analyse_ars <- add_code_prelevement(
+  nitrate_data_analyse_ars, "v0_15")
+
+# Afficher le dataframe pour vérifier les modifications
+print(nitrate_data_analyse_ars)
+
+```
+
+On charge les données consolidées dans un table dédiée :
+
+```{r insert-into_nitrate_prelevement_v0_15, eval = FALSE}
+# Charger les données dans une nouvelle table en base
+datalibaba::poster_data(data = nitrate_data_analyse_ars, 
+                        table = "nitrate_prelevement_ars_v0_15", 
+                        schema = "nitrates", 
+                        db = "si_eau",
+                        overwrite = TRUE,
+                        pk = "code_prelevement",
+                        user = "admin")
+```
+
+# Insertion des données ARS du nouveau millésime en base dans la table globale
+
+On insère enfin les enregistrements de cette table dans la table globale :
+
+```{r import_and_merge_tables_ars, eval = FALSE}
+# Insérer les données de la table du dernier millésime vers la table complète
+collectr::import_and_merge_tables(database = "si_eau",
+                                  source_table = "nitrate_prelevement_ars_v0_15", 
+                                  source_schema = "nitrates", 
+                                  target_table = "nitrate_prelevement_v0_15", 
+                                  target_schema = "nitrates",
+                                  role = "admin")
+
+```
+
diff --git a/vignettes/insertion-des-prelevements-hubeau-eso.Rmd b/vignettes/insertion-des-prelevements-hubeau-eso.Rmd
new file mode 100644
index 0000000000000000000000000000000000000000..28e1dd5e8ac46dbb14876a722a435c6b2d6d7c34
--- /dev/null
+++ b/vignettes/insertion-des-prelevements-hubeau-eso.Rmd
@@ -0,0 +1,129 @@
+---
+title: "Insertion des prélèvements Hubeau ESO"
+output: rmarkdown::html_vignette
+vignette: >
+  %\VignetteIndexEntry{insertion-des-prelevements-hubeau-eso}
+  %\VignetteEngine{knitr::rmarkdown}
+  %\VignetteEncoding{UTF-8}
+---
+
+```{r, include = FALSE}
+knitr::opts_chunk$set(
+  collapse = TRUE,
+  comment = "#>"
+)
+```
+
+```{r setup}
+library(data.nitrates)
+```
+
+<!-- WARNING - This vignette is generated by {fusen} from dev/flat_insert_hubeau_eso_into_prelevement.Rmd: do not edit by hand -->
+
+# Consolidation et insertion des données Hub'eau ESO dans la table des prélèvements
+
+## Chargement des données Hub'eau ESO
+
+La table des données brutes Nitrates Hub'eau ESO est chargée :
+
+```{r load-nitrate_data_analyse_hubeau_eso, eval = FALSE}
+nitrate_qualite_nappes_analyses <- datalibaba::importer_data(
+  table = "nitrate_qualite_nappes_analyses",
+  schema = "qualite_nappes_eau_souterraine",
+  db = "si_eau",
+  user = "admin"
+)
+```
+
+## Filtre par code_producteur pour exclure les données ARS
+
+On sélectionne les code_producteur correspondants aux enregistrements hors 
+données ARS de la région :
+
+```{r select-code_producteur_hubeau_eso, eval = FALSE}
+nitrate_qualite_nappes_analyses <- nitrate_qualite_nappes_analyses |>
+  dplyr::filter(!code_producteur %in% c('44','49','53','72','85'))
+```
+
+## Consolidation des données Hub'eau ESO
+
+On ajoute les variables `source` et `code_support` :
+
+```{r add-source_code_support_hubeau_eso, eval = FALSE}
+# Ajouter les variables source et code_support
+nitrate_qualite_nappes_analyses <- nitrate_qualite_nappes_analyses |>
+  dplyr::mutate(
+    source = "ADES",
+    code_support = 3)
+```
+
+On sélectionne les champs utiles à la table des prélèvements :
+
+```{r select-variables_hubeau_eso, eval = FALSE}
+# Sélectionner les variables
+nitrate_qualite_nappes_analyses <- nitrate_qualite_nappes_analyses |>
+  dplyr::select(source,
+                code_reseau = codes_reseau,
+                code_station = bss_id,
+                date_prelevement = date_debut_prelevement,
+                code_support)
+```
+
+On modifie le type de la variable `code_support` de character en integer :
+
+```{r change-type_code_support, eval = FALSE}
+# Convertir la variable code_support de character en integer
+nitrate_qualite_nappes_analyses <- nitrate_qualite_nappes_analyses |>
+  dplyr::mutate(code_support = as.integer(code_support))
+```
+
+On dédoublonne les lignes en utilisant les champs `code_station` et 
+`date_prelevement` afin de ne conserver qu'un prélèvement par station et date 
+donnée :
+
+```{r select-distinct-rows_hubeau_eso, eval = FALSE}
+# Dédoublonner les lignes sur les colonnes code_station et date_prelevement
+nitrate_qualite_nappes_analyses <- nitrate_qualite_nappes_analyses |>
+  dplyr::distinct(code_station, date_prelevement, .keep_all = TRUE)
+```
+
+On ajoute un identifiant unique s'appuyant sur une séquence stockée en base :
+
+```{r add_code_prelevement_hubeau_eso, eval = FALSE}
+# Utiliser la fonction add_code_prelevement avec la version souhaitée
+nitrate_qualite_nappes_analyses <- add_code_prelevement(
+  nitrate_qualite_nappes_analyses, "v0_15")
+
+# Afficher le dataframe pour vérifier les modifications
+print(nitrate_qualite_nappes_analyses)
+
+```
+
+On charge les données consolidées dans un table dédiée :
+
+```{r insert-into_nitrate_prelevement_hubeau_eso, eval = FALSE}
+# Charger les données dans une nouvelle table en base
+datalibaba::poster_data(data = nitrate_qualite_nappes_analyses, 
+                        table = "nitrate_prelevement_hubeau_eso_v0_15", 
+                        schema = "nitrates", 
+                        db = "si_eau",
+                        overwrite = TRUE,
+                        pk = "code_prelevement",
+                        user = "admin")
+```
+
+# Insertion des données Hub'eau ESO du nouveau millésime en base dans la table globale
+
+On insère enfin les enregistrements de cette table dans la table globale :
+
+```{r import_and_merge_tables_hubeau_eso, eval = FALSE}
+# Insérer les données de la table du dernier millésime vers la table complète
+collectr::import_and_merge_tables(database = "si_eau",
+                                  source_table = "nitrate_prelevement_hubeau_eso_v0_15", 
+                                  source_schema = "nitrates", 
+                                  target_table = "nitrate_prelevement_v0_15", 
+                                  target_schema = "nitrates",
+                                  role = "admin")
+
+```
+
diff --git a/vignettes/insertion-des-prelevements-hubeau-esu.Rmd b/vignettes/insertion-des-prelevements-hubeau-esu.Rmd
new file mode 100644
index 0000000000000000000000000000000000000000..cd203ae33302ed7694619eecc6393a49e4b338df
--- /dev/null
+++ b/vignettes/insertion-des-prelevements-hubeau-esu.Rmd
@@ -0,0 +1,130 @@
+---
+title: "Insertion des prélèvements Hubeau ESU"
+output: rmarkdown::html_vignette
+vignette: >
+  %\VignetteIndexEntry{insertion-des-prelevements-hubeau-esu}
+  %\VignetteEngine{knitr::rmarkdown}
+  %\VignetteEncoding{UTF-8}
+---
+
+```{r, include = FALSE}
+knitr::opts_chunk$set(
+  collapse = TRUE,
+  comment = "#>"
+)
+```
+
+```{r setup}
+library(data.nitrates)
+```
+
+<!-- WARNING - This vignette is generated by {fusen} from dev/flat_insert_hubeau_esu_into_prelevement.Rmd: do not edit by hand -->
+
+# Consolidation et insertion des données Hub'eau ESU dans la table des prélèvements
+
+## Chargement des données Hub'eau ESU
+
+La table des données brutes Nitrates Hub'eau ESU est chargée :
+
+```{r load-nitrate_data_analyse_hubeau_esu, eval = FALSE}
+nitrate_qualite_rivieres_analyse_pc <- datalibaba::importer_data(
+  table = "nitrate_qualite_rivieres_analyse_pc",
+  schema = "qualite_cours_d_eau",
+  db = "si_eau",
+  user = "admin"
+)
+```
+
+## Consolidation des données Hub'eau ESU
+
+On remplace "." par "," dans les variables `limite_detection` et `limite_quantification` :
+
+```{r replace-in_limite_detection, eval = FALSE}
+# Remplacer "." par "," dans les colonnes limite_detection et limite_quantification
+nitrate_qualite_rivieres_analyse_pc <- nitrate_qualite_rivieres_analyse_pc |>
+  dplyr::mutate(
+    limite_detection = stringr::str_replace_all(limite_detection, ".", ","),
+    limite_quantification = stringr::str_replace_all(limite_quantification, ".", ",")
+    )
+```
+
+On ajoute la variable `source` :
+
+```{r add-source_code_support_hubeau_esu, eval = FALSE}
+# Ajouter les variables source et code_support
+nitrate_qualite_rivieres_analyse_pc <- nitrate_qualite_rivieres_analyse_pc |>
+  dplyr::mutate(source = "Na\u00efades")
+```
+
+On sélectionne les champs utiles à la table des prélèvements :
+
+```{r select-variables_hubeau_esu, eval = FALSE}
+# Sélectionner les variables
+nitrate_qualite_rivieres_analyse_pc <- nitrate_qualite_rivieres_analyse_pc |>
+  dplyr::select(source,
+                code_reseau,
+                code_station,
+                date_prelevement,
+                heure_prelevement,
+                code_support,
+                commentaire = commentaires_analyse)
+```
+
+On modifie le type de la variable `code_support` de character en integer :
+
+```{r change-type_code_support, eval = FALSE}
+# Convertir la variable code_support de character en integer
+nitrate_qualite_rivieres_analyse_pc <- nitrate_qualite_rivieres_analyse_pc |>
+  dplyr::mutate(code_support = as.integer(code_support))
+```
+
+On dédoublonne les lignes en utilisant les champs `code_station` et 
+`date_prelevement` afin de ne conserver qu'un prélèvement par station et date 
+donnée :
+
+```{r select-distinct-rows_hubeau_esu, eval = FALSE}
+# Dédoublonner les lignes sur les colonnes code_station et date_prelevement
+nitrate_qualite_rivieres_analyse_pc <- nitrate_qualite_rivieres_analyse_pc |>
+  dplyr::distinct(code_station, date_prelevement, .keep_all = TRUE)
+```
+
+On ajoute un identifiant unique s'appuyant sur une séquence stockée en base :
+
+```{r add_code_prelevement_hubeau_esu, eval = FALSE}
+# Utiliser la fonction add_code_prelevement avec la version souhaitée
+nitrate_qualite_rivieres_analyse_pc <- add_code_prelevement(
+  nitrate_qualite_rivieres_analyse_pc, "v0_15")
+
+# Afficher le dataframe pour vérifier les modifications
+print(nitrate_qualite_rivieres_analyse_pc)
+
+```
+
+On charge les données consolidées dans un table dédiée :
+
+```{r insert-into_nitrate_prelevement_hubeau_esu, eval = FALSE}
+# Charger les données dans une nouvelle table en base
+datalibaba::poster_data(data = nitrate_qualite_rivieres_analyse_pc, 
+                        table = "nitrate_prelevement_hubeau_esu_v0_15", 
+                        schema = "nitrates", 
+                        db = "si_eau",
+                        overwrite = TRUE,
+                        pk = "code_prelevement",
+                        user = "admin")
+```
+
+# Insertion des données Hub'eau ESU du nouveau millésime en base dans la table globale
+
+On insère enfin les enregistrements de cette table dans la table globale :
+
+```{r import_and_merge_tables_hubeau_esu, eval = FALSE}
+# Insérer les données de la table du dernier millésime vers la table complète
+collectr::import_and_merge_tables(database = "si_eau",
+                                  source_table = "nitrate_prelevement_hubeau_esu_v0_15", 
+                                  source_schema = "nitrates", 
+                                  target_table = "nitrate_prelevement_v0_15", 
+                                  target_schema = "nitrates",
+                                  role = "admin")
+
+```
+