diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cfddca4c7d3ec7b13cf97170eb1af03f8e56f097..09fe496a996ab2e641535413324225605d11b9e0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -19,7 +19,7 @@ code_analysis:
     - build
   only:
     - master
-    - development
+  #  - development
   before_script:
     - export PATH=$PATH:/usr/local/bin/sonar-scanner-4.2.0.1873-linux/bin/
     - export NODE_PATH=$NODE_PATH:`npm root -g`
diff --git a/angular.json b/angular.json
index 69763a2c2458c35006c180f403f91311f456b8fc..6802f0b7c145f7c413360074f45227484dad6eab 100644
--- a/angular.json
+++ b/angular.json
@@ -44,6 +44,7 @@
             "scripts": [
               "node_modules/tarteaucitronjs/tarteaucitron.js",
               "node_modules/tarteaucitronjs/lang/tarteaucitron.fr.js",
+              "node_modules/tarteaucitronjs/lang/tarteaucitron.en.js",
               "node_modules/tarteaucitronjs/tarteaucitron.services.js"
             ]
           },
diff --git a/src/app/core/services/app-config.service.ts b/src/app/core/services/app-config.service.ts
index f9e894f40356379b86519721da79c07f229ee1cc..7e846d6841d38695f7c656386409cdaeec24cf2c 100644
--- a/src/app/core/services/app-config.service.ts
+++ b/src/app/core/services/app-config.service.ts
@@ -17,6 +17,7 @@ export class AppConfig {
     proxyQuery: string;
     seo: string;
     datasetUsageStatistics: string;
+    backendDomain: string;
   };
   statistics: {
     matomoHost: string;
diff --git a/src/app/dataset-detail/components/dataset-api/resources-queryable/resource-queryable/resource-queryable.component.ts b/src/app/dataset-detail/components/dataset-api/resources-queryable/resource-queryable/resource-queryable.component.ts
index 23c3bd208bdcb3dc7844a7a390ae3ec18bb202f9..c3193e5a651f9ce24f78b10edfb263ccc899f726 100644
--- a/src/app/dataset-detail/components/dataset-api/resources-queryable/resource-queryable/resource-queryable.component.ts
+++ b/src/app/dataset-detail/components/dataset-api/resources-queryable/resource-queryable/resource-queryable.component.ts
@@ -171,7 +171,6 @@ export class ResourceQueryableComponent implements OnInit {
   }
 
   initURLCustomization() {
-    console.log ('passage ici.');
     this.projectionList = [];
 
     this.csvFieldsSeparatorList = [',',';'];
@@ -333,8 +332,6 @@ export class ResourceQueryableComponent implements OnInit {
 
     // Number features WS
     if (this.resource.type === this.linkFormats.ws) {
-      console.log ('padabam');
-      console.log(this.queryableParameters);
       if (this.queryableParameters.numberFeatures) {
         queryableUrlToDisplay += this.selectedFormat.isProjectable === 0 ?
           `<span class="is-active-parameter">?maxfeatures=${this.numberFeatures}</span>` :
@@ -411,7 +408,6 @@ export class ResourceQueryableComponent implements OnInit {
         //this.setDecimalSeparator(this.selectedDecimalseparator);
       }
       else {
-        console.log(this.selectedFormat.name);
         this.queryableParameters.baseUrl = this.resource.metadataLink.url.replace('/all.json', '');
         this.queryableParameters.baseUrl += `/${this.resource.metadataLink.name}.shp?`;
         if (this.selectedFormat.isProjectable) {
@@ -565,7 +561,7 @@ export class ResourceQueryableComponent implements OnInit {
 
   get downloadUrl() {
     return this.queryableUrl.replace(
-      'https://download.data.grandlyon.com',
+      APP_CONFIG.backendUrls.backendDomain,
       `${APP_CONFIG.backendUrls.proxyQuery}/download`,
     );
   }
diff --git a/src/app/dataset-detail/components/dataset-detail/dataset-detail.component.ts b/src/app/dataset-detail/components/dataset-detail/dataset-detail.component.ts
index d817cf7e096d1deb7644d745ace2dd84631051b8..011a0f65eca8606d8c69363ecddc8adbf47cf9bd 100644
--- a/src/app/dataset-detail/components/dataset-detail/dataset-detail.component.ts
+++ b/src/app/dataset-detail/components/dataset-detail/dataset-detail.component.ts
@@ -153,6 +153,8 @@ export class DatasetDetailComponent implements OnInit, OnDestroy {
 
     const links = this._datasetDetailService.datasetMetadata.link;
 
+    let blockedFormat = ['PNG','JPEG','TIFF','GIF','AAIGrid'];
+
     let list = links.map((link) => {
       let filteredList = link.formats;
       if (link.formats) {
@@ -170,6 +172,18 @@ export class DatasetDetailComponent implements OnInit, OnDestroy {
           } else if (f === 'PDF' && link.name.includes('Licence')) { // Remove PDF because it's Licence
             validFormat = false;
           }
+          /*if (link.service === 'WFS') {
+            if (f === 'ShapeFile') {
+              validFormat = false;
+            }
+          }*/
+
+          if (link.service === 'WMS' || link.service === 'WCS') {
+            if (blockedFormat.includes(f)) {
+              validFormat = false;
+            }
+          }
+
           return validFormat;
         });
       }
diff --git a/src/app/dataset-detail/components/dataset-downloads/dataset-downloads.component.html b/src/app/dataset-detail/components/dataset-downloads/dataset-downloads.component.html
index 8ec8ba4afb79cc85ba92f76def09bb0b11cb20fe..40e52e3af72713cf08bfa01c4d34b03b03022628 100644
--- a/src/app/dataset-detail/components/dataset-downloads/dataset-downloads.component.html
+++ b/src/app/dataset-detail/components/dataset-downloads/dataset-downloads.component.html
@@ -4,16 +4,18 @@
   </div>
   <div class="downloads" [ngClass]="{'blury': cguModalIsOpened}">
     <div class="resources-downloadable" *ngIf="hasDownloadableResources || hasStaticResources">
-      <div class="resource-download" *ngFor="let downloadable of downloadableResources | keyvalue">
-        <div class="resource-description">
-          <span>{{downloadable.key}}</span>
-        </div>
-        <div class="resource-downloadable-files" *ngFor="let resource of downloadable.value">
-          <div class="resource-download-item-wrapper" *ngFor="let format of resource.formats; let i=index">
-            <app-resource-download-item [metadata]="metadata"
-            [format]="format" [resource]="resource" [projections]="projections"
-              [isQueryable]="true">
-            </app-resource-download-item>
+      <div *ngIf="downloadableResources">
+        <div class="resource-download" *ngFor="let downloadable of downloadableResources | keyvalue" >
+          <div class="resource-description">
+            <span>{{downloadable.key}}</span>
+          </div>
+          <div class="resource-downloadable-files" *ngFor="let resource of downloadable.value">
+            <div class="resource-download-item-wrapper" *ngFor="let format of resource.formats; let i=index">
+              <app-resource-download-item [metadata]="metadata"
+              [format]="format" [resource]="resource" [projections]="projections"
+                [isQueryable]="true">
+              </app-resource-download-item>
+            </div>
           </div>
         </div>
       </div>
diff --git a/src/app/dataset-detail/components/dataset-downloads/resource-download-item/resource-download-item/resource-download-item.component.ts b/src/app/dataset-detail/components/dataset-downloads/resource-download-item/resource-download-item/resource-download-item.component.ts
index 39e3865f1c20fc1342eade15aeb2dbf6db116c3b..9ec24f38dc7525b539e4e6aebfda78a71edcf0e9 100644
--- a/src/app/dataset-detail/components/dataset-downloads/resource-download-item/resource-download-item/resource-download-item.component.ts
+++ b/src/app/dataset-detail/components/dataset-downloads/resource-download-item/resource-download-item/resource-download-item.component.ts
@@ -152,7 +152,7 @@ export class ResourceDownloadItemComponent implements OnInit {
           `${this.format.mapServerType}`;
         const projectionAndBbox = this.getProjectionAndBbox(this.format);
 
-        if (Array.isArray(this.metadata.providers) && this.metadata.providers[0].match(/ATMO/g)) {
+        if (Array.isArray(this.metadata.providers) && this.metadata.providers.length > 0 && this.metadata.providers[0].match(/ATMO/g)) {
           if (this.format.mapServerType.match(/application\/json/)) {
             outputFormat = `&${this.labelFormat[this.resource.type]}=GEOJSON`;
           }
@@ -177,6 +177,8 @@ export class ResourceDownloadItemComponent implements OnInit {
       } else if (this.resource.type === linkFormats.ws) {
         if (this.format.name === 'JSON') {
           queryableUrl += `/${this.resource.metadataLink.name}/all.json?maxfeatures=-1`;
+        } else if (this.format.name === 'CSV') {
+          queryableUrl += `/${this.resource.metadataLink.name}/all.csv?maxfeatures=-1`;
         } else {
           const projectionAndBbox = this.getProjectionAndBbox(this.format);
 
diff --git a/src/app/dataset-detail/components/dataset-map/dataset-map.component.ts b/src/app/dataset-detail/components/dataset-map/dataset-map.component.ts
index efc95cefd6ea245e9a7953851b2644cce815e0b6..5454ec216152fc1a2e4d3441c82aa6f30ae57e81 100644
--- a/src/app/dataset-detail/components/dataset-map/dataset-map.component.ts
+++ b/src/app/dataset-detail/components/dataset-map/dataset-map.component.ts
@@ -99,7 +99,7 @@ export class DatasetMapComponent implements OnInit, OnDestroy {
       }
 
       // If download data, use config url.
-      if (this.mapOptions.rasterService.url.includes('download.data')) {
+      if (this.mapOptions.rasterService.url.includes('download.data') || this.mapOptions.rasterService.url.includes('download.recette.data')) {
         const domain = this.mapOptions.rasterService.url.split('wms')[1];
         this.mapOptions.rasterService.url = `${APP_CONFIG.backendUrls.proxyQuery}/map/wms${domain}`;
       }
diff --git a/src/app/dataset-detail/services/resources.service.ts b/src/app/dataset-detail/services/resources.service.ts
index 585e355fd6d58040945a1aba73a74dbf592e5a30..e170f75c867cda045e5992bbae1ccc7f57be1077 100644
--- a/src/app/dataset-detail/services/resources.service.ts
+++ b/src/app/dataset-detail/services/resources.service.ts
@@ -44,18 +44,20 @@ export class ResourcesService {
     );
   }
 
-  getQueryableResources(link: IMetadataLink[]) {
+  getQueryableResources(links: IMetadataLink[]) {
     const queryableResources = {};
-    link.forEach((link) => {
+
+    links.forEach((link) => {
+      const linkID = link.description !== 'null' ? link.description : link.name;
       if (link.service) {
         this.resources.forEach((resource) => {
           const resourceCopy = Object.assign({}, resource);
           resourceCopy.metadataLink = link;
           if (link.service === resource.type && resourceCopy.isQueryable) {
-            if (!queryableResources[link.description]) {
-              queryableResources[link.description] = [];
+            if (!queryableResources[linkID]) {
+              queryableResources[linkID] = [];
             }
-            queryableResources[link.description].push(resourceCopy);
+            queryableResources[linkID].push(resourceCopy);
           }
         });
       }
@@ -70,6 +72,8 @@ export class ResourcesService {
 
     const links = lodashClonedeep(metadata.link);
     links.forEach((link) => {
+      const linkID = link.description !== 'null' ? link.description : link.name;
+
       if (link.service) {
         this.resources.forEach((resource) => {
           const resourceCopy = Object.assign({}, resource);
@@ -90,39 +94,42 @@ export class ResourcesService {
             // WE exclude image formats for WMS and WCS. (https://redmine.neogeo.fr/issues/12382)
             if (resourceCopy.type === this.linkFormats.wms || resourceCopy.type === this.linkFormats.wcs) {
               resourceCopy.formats = resourceCopy.formats.filter(
-                f => f.name !== 'PNG' && f.name !== 'JPEG');
+                f => f.name !== 'PNG' && f.name !== 'JPEG' && f.name !== 'TIFF'
+                      && f.name !== 'GIF' && f.name !== 'AAIGrid');
             }
 
-
-            if (!downloadableResources[link.description]) {
-              downloadableResources[link.description] = [];
+            if (resourceCopy.formats.length > 0 ) {
+              if (!downloadableResources[linkID]) {
+                downloadableResources[linkID] = [];
+              }
+
+              // Instead of using the direct link to the files we go through the dedicated proxy
+              // that is adding credentials of a technical account if the user has access to the requested file/data
+              resourceCopy.metadataLink.url = resourceCopy.metadataLink.url.replace(
+                APP_CONFIG.backendUrls.backendDomain,
+                `${APP_CONFIG.backendUrls.proxyQuery}/download`,
+              );
+              resourceCopy.metadataLink.url = resourceCopy.metadataLink.url.replace(
+                'https://download.recette.data.grandlyon.com',
+                `${APP_CONFIG.backendUrls.proxyQuery}/download`,
+              );
+
+              downloadableResources[linkID].push(resourceCopy);
             }
 
-            // Instead of using the direct link to the files we go through the dedicated proxy
-            // that is adding credentials of a technical account if the user has access to the requested file/data
-            resourceCopy.metadataLink.url = resourceCopy.metadataLink.url.replace(
-              'https://download.data.grandlyon.com',
-              `${APP_CONFIG.backendUrls.proxyQuery}/download`,
-            );
-            resourceCopy.metadataLink.url = resourceCopy.metadataLink.url.replace(
-              'https://download.recette.data.grandlyon.com',
-              `${APP_CONFIG.backendUrls.proxyQuery}/download`,
-            );
-
-            downloadableResources[link.description].push(resourceCopy);
           }
         });
       } else if (link.service === undefined) {
         if (!link.name.includes('Licence')) {
           if (link.formats) {
-            if (!staticResources[link.description]) {
-              staticResources[link.description] = [];
+            if (!staticResources[linkID]) {
+              staticResources[linkID] = [];
             }
 
             // Instead of using the direct link to the files we go through the dedicated proxy
             // that is adding credentials of a technical account if the user has access to the requested file/data
             link.url = link.url.replace(
-              'https://download.data.grandlyon.com',
+              APP_CONFIG.backendUrls.backendDomain,
               `${APP_CONFIG.backendUrls.proxyQuery}/download`,
             );
             link.url = link.url.replace(
@@ -130,7 +137,7 @@ export class ResourcesService {
               `${APP_CONFIG.backendUrls.proxyQuery}/download`,
             );
 
-            staticResources[link.description].push(link);
+            staticResources[linkID].push(link);
           } else {
             otherResources.push(link);
           }
diff --git a/src/app/elasticsearch/services/elasticsearch.service.ts b/src/app/elasticsearch/services/elasticsearch.service.ts
index c9e334bb16c820191a5952b5f44f2ce79e6f548d..58edf52469545392f9b48095afefa7f00cc7fe5a 100644
--- a/src/app/elasticsearch/services/elasticsearch.service.ts
+++ b/src/app/elasticsearch/services/elasticsearch.service.ts
@@ -597,7 +597,7 @@ export class ElasticsearchService {
       requestOptions.body['aggregations'][filter.field] = {
         date_histogram: {
           field,
-          interval: 'year',
+          calendar_interval: 'year',
           min_doc_count: 1,
           order: {
             _count: 'desc',
diff --git a/src/app/shared/components/link-copy-icon/link-copy-icon.component.ts b/src/app/shared/components/link-copy-icon/link-copy-icon.component.ts
index b785dd715016bce0a70b7805ec60ff8bedaf6434..82c1e0744917d6b321b6d217441ef8d4a4d999f9 100644
--- a/src/app/shared/components/link-copy-icon/link-copy-icon.component.ts
+++ b/src/app/shared/components/link-copy-icon/link-copy-icon.component.ts
@@ -31,7 +31,7 @@ export class LinkCopyIconComponent implements OnChanges {
 
     this.linkUrl = this.linkUrl.replace(
       `${APP_CONFIG.backendUrls.proxyQuery}/download`,
-      'https://download.data.grandlyon.com',
+      `${APP_CONFIG.backendUrls.backendDomain}`,
     );
     this.linkUrl = this.linkUrl.replace(
       `${APP_CONFIG.backendUrls.proxyQuery}/download`,