diff --git a/.Rbuildignore b/.Rbuildignore
index 395d638073cc0922cba8d5f86176f70be303dab6..ce5e3c0abe241dd075ce7fcf2097bb624819f53c 100644
--- a/.Rbuildignore
+++ b/.Rbuildignore
@@ -9,3 +9,4 @@ inst/rmarkdown/templates/ecln_conjoncture/skeleton/skeleton.html
 R/graphique_synthese.R
 ^\.gitlab-ci\.yml$
 ^ci/lib$
+^dev$
diff --git a/DESCRIPTION b/DESCRIPTION
index 2e2f2d28261cce1487e42ad3cf78dc38ed077bff..e467e45fe02dc1c43d886dbcec2908b89d554fd8 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -36,7 +36,10 @@ Imports:
     scales,
     sf,
     stringr,
-    tidyr
+    tidyr,
+    utils
+Suggests: 
+    testthat
 Remotes: 
     gitlab::dreal-datalab/drealdown,
     gitlab::dreal-datalab/mapfactory,
diff --git a/data-raw/07_chargement_ecln.R b/data-raw/07_chargement_ecln.R
new file mode 100644
index 0000000000000000000000000000000000000000..b7c2c06d7d02709fa86ce4ccc66d1ca31eaf92ed
--- /dev/null
+++ b/data-raw/07_chargement_ecln.R
@@ -0,0 +1,45 @@
+# chargement des données ecln annuelles sur le serveur ecosql
+
+library(dplyr)
+library(stringr)
+library(tidyverse)
+
+rm(list = ls())
+
+
+# indic_ecln <- propre.ecln::indic_ecln
+
+# filtre pour ne garder que les données annuelles
+tab_ecln <- indic_ecln %>%
+  filter(TypeIndicateur=="Cumul annuel",
+         str_detect(Periode, "-12-31")) %>%
+  mutate(Indicateur=tolower(Indicateur),
+         Indicateur=str_replace(Indicateur," - ","."),
+         Indicateur=str_replace(Indicateur,"appartements","appart"),
+         Indicateur=str_replace(Indicateur,"constructions neuves","cons_neuves"),
+         Indicateur=str_replace(Indicateur,"constructions sur existant","cons_sur_exist"),
+         Indicateur=str_replace(Indicateur,"mises en vente","mev"))
+
+tab_valeurs <- tab_ecln %>%
+  select(TypeZone,Zone,CodeZone,date=Periode,variable=Indicateur, valeur=Valeur)
+tab_evol <- tab_ecln %>%
+  select(TypeZone,Zone,CodeZone,date=Periode,variable=Indicateur, valeur=TauxEvolution12Mois) %>%
+  mutate(variable = paste("evol12m_",variable))
+source_ecln <- bind_rows(tab_valeurs,tab_evol) %>%
+  mutate(valeur = format(valeur, scientific = FALSE)) %>%
+  pivot_wider(names_from = variable,values_from = valeur)
+
+# versement dans le sgbd EcoSQL/datamart.portrait_territoires -------------
+
+source("data-raw/poster_documenter_ind.R", encoding = "UTF-8")
+poster_documenter_ind(
+  df = source_ecln,
+  nom_table_sgbd = "source_ecln",
+  nom_script_sce = "chargement_ecln",
+  comm_source_en_plus = "Données chargées depuis le serveur RStudio du SDES pour les DREALs",
+  secret = TRUE,
+  user = "ecosql_stat",
+  serveur = Sys.getenv("server_ecosql")
+)
+
+
diff --git a/data-raw/poster_documenter_ind.R b/data-raw/poster_documenter_ind.R
new file mode 100644
index 0000000000000000000000000000000000000000..e0b691b14c592aa1b00b9db1e5e7e4a21198ac5d
--- /dev/null
+++ b/data-raw/poster_documenter_ind.R
@@ -0,0 +1,109 @@
+library(datalibaba)
+library(googlesheets4)
+
+poster_documenter_ind <- function(df = indicateur_bimotor_menages, nom_table_sgbd = "indicateur_bimotor_menages", 
+                                  comm_source_en_plus = "", nom_script_sce = NULL, user = "does", serveur = NULL, secret = FALSE) {
+  
+  # Vérif clé primaire : une ligne par commune et par date
+  doublons <- df %>% 
+    dplyr::count(across(contains("Zone")), date) %>% 
+    dplyr::filter(n>1) %>% 
+    nrow()
+  attempt::stop_if(doublons > 0, msg =  glue::glue("La table df contient plusieurs lignes qui ont \u00e0 la fois le m\u00eame code zone et la m\u00eame date"))
+  
+  
+  # CHARGEMENT de la table dans le SGBD
+  datalibaba::poster_data(data = df,
+                          server = serveur,
+                          db = "datamart",
+                          schema = "portrait_territoires", 
+                          table = nom_table_sgbd,
+                          post_row_name = FALSE, 
+                          overwrite = TRUE,
+                          droits_schema = !secret,
+                          pk = c("TypeZone", "CodeZone", "date"), # déclaration d'une clé primaire sur la table postée : on ne doit pas avoir deux lignes avec à la fois la même zone et la meme date
+                          user = user) 
+  
+  
+  # RECUPERATION DES METADONNEES
+  
+  ## On récupère la liste des variables qui sont à documenter dans le tableur google sheet à partir du jeu de données posté
+  var <- dplyr::setdiff(names(df), c("date", "typezone", "TypeZone", "CodeZone", "codezone", "Zone", "zone"))
+  
+  ## récupération du nom du présent script source pour filtrer ensuite le référentiel des indicateurs
+  if(is.null(nom_script_sce)) {
+    nom_script_sce <- rstudioapi::getSourceEditorContext()$path %>% # utilisation de rstudioapi pour récupérer le nom du présent script 
+      basename() %>% # on enlève le chemin d'accès pour ne garder que le nom du fichier
+      gsub(pattern = ".R$", "", .)  }# on enlève l'extension '.R'
+    if(nom_script_sce == "cogifier_en_masse") {
+      nom_script_sce <- nom_table_sgbd
+    }
+ 
+  message("nom_script_sce détecté ", nom_script_sce)
+  ## authentification google sheet grâce au .Renviron
+  googlesheets4::gs4_auth_configure(api_key = Sys.getenv("google_api_key"))
+  googlesheets4::gs4_deauth()
+  
+  ## chargement du référentiel indicateurs google sheet
+  metadata_indicateur0 <- googlesheets4::read_sheet("https://docs.google.com/spreadsheets/d/1n-dhtrJM3JwFVz5WSEGOQzQ8A0G7VT_VcxDe5gh6zSo/edit#gid=60292277",
+                                                    sheet = "indicateurs")
+  metadata_indicateur <- metadata_indicateur0 %>%
+    # on ne garde que les variables concernées par le présent script de chargement
+    dplyr::filter(source == nom_script_sce)  %>% 
+    # on ajoute l'unité dans le libellé de la variable
+    dplyr::mutate(libelle_variable = paste0(libelle_variable, " (unit\u00e9 : ", unite, ")")) %>% 
+    dplyr::select(variable, libelle_variable) %>% 
+    # ajout des libellés pour depcom et date
+    dplyr::bind_rows(
+      tidyr::tribble(
+        ~variable, ~libelle_variable,
+        "Zone", "Nom de la zone géo",
+        "CodeZone", "Code officiel géo de la zone",
+        "TypeZone", "Echelle géo",
+        "date", "Millesime"
+      )
+    )
+  
+  ## Vérification que la documentation des indicateurs est complète
+  var_mq <- dplyr::setdiff(var, metadata_indicateur$variable) %>% paste(collapse = "\n")
+  
+  var_en_trop <- dplyr::setdiff(metadata_indicateur$variable, c("date", "typezone", "TypeZone", "CodeZone", "codezone", "Zone", "zone", var)) %>% paste(collapse = "\n")
+  attempt::stop_if_not(all(var %in% metadata_indicateur$variable),
+                       msg = glue::glue("La table df contient des variables non document\u00e9es dans le r\u00e9f\u00e9rentiel google sheet : \n{var_mq}\n"))
+  attempt::stop_if_not(all(metadata_indicateur$variable %in% c("date", "typezone", "TypeZone", "CodeZone", "codezone", "Zone", "zone", var)),
+                       msg = glue::glue("Le r\u00e9f\u00e9rentiel google sheet des indicateurs contient des variables absentes de la table df :\n{var_en_trop}\n",
+                                        "V\u00e9rifier si df contient bien toutes les variables attendues et adapatez le r\u00e9f\u00e9rentiel des indicateurs au besoin."))
+  
+  
+  ## Envoi des libellés de variable dans le SGBD
+  datalibaba::post_dico_attr(dico = metadata_indicateur, table = nom_table_sgbd, schema = "portrait_territoires",
+                             db = "datamart", server = serveur, user = user)
+  
+  ## Récupération des métadonnées de la source
+  nom_sce <- stringr::str_replace(nom_script_sce, "chargement_|ref_|specifique_", "") %>%
+    stringr::str_replace("indicateur_", "") %>%
+    stringr::str_replace("_cogiter|_cog$", "")
+  
+  metadata_source0 <- googlesheets4::read_sheet("https://docs.google.com/spreadsheets/d/1n-dhtrJM3JwFVz5WSEGOQzQ8A0G7VT_VcxDe5gh6zSo/edit#gid=60292277",
+                                                sheet = "sources") 
+  metadata_source <- metadata_source0  %>%
+    dplyr::filter(source == nom_sce) %>% 
+    dplyr::mutate(com_table = paste0(source_lib, " - ", producteur, ".\n", descriptif_sources)) %>% 
+    dplyr::pull(com_table) %>% 
+    # ajout de complement sur la généalogie
+    paste0("\n", comm_source_en_plus)
+  
+  
+  ## commentaires de la table
+  
+  datalibaba::commenter_table(comment = metadata_source,
+                              db = "datamart",
+                              schema = "portrait_territoires",
+                              table = nom_table_sgbd, 
+                              user = user, server = serveur)
+  
+}
+
+
+
+
diff --git a/man/indic_ecln.Rd b/man/indic_ecln.Rd
index 48272c24cc244d7aec72a129f571a5b3d07aac17..1f7e5d3a959d063490ce6b89861629b951e628ee 100644
--- a/man/indic_ecln.Rd
+++ b/man/indic_ecln.Rd
@@ -6,7 +6,7 @@
 \alias{indic_ecln}
 \title{Table contenant les différents indicateurs de la source ecln utiles pour la publication.}
 \format{
-Table de 2704192 lignes et 9 colonnes:
+Table de 2619686 lignes et 9 colonnes:
 \describe{
 \item{TypeZone}{Type de territoire}
 \item{CodeZone}{Code du territoire}