From dee44135c05634c15638d845755d764310754a3f Mon Sep 17 00:00:00 2001 From: Thibaut Dusanter Date: Tue, 1 Oct 2024 11:54:14 +0200 Subject: [PATCH 1/2] test(backend): repare tests e2e --- backend/jest-e2e.config.ts | 15 +++ backend/jest.config.ts | 4 +- backend/project.json | 7 + .../test/indicateurs/indicateurs.e2e-spec.ts | 6 +- .../indicateurs/trajectoire-snbc.e2e-spec.ts | 124 ++++++++++-------- backend/test/jest-e2e.json | 9 -- backend/tsconfig.spec-e2e.json | 12 ++ data_layer/seed/fakes/11-insert_fake_user.sql | 1 + package.json | 2 + pnpm-lock.yaml | 101 ++++++++++++++ 10 files changed, 212 insertions(+), 69 deletions(-) create mode 100644 backend/jest-e2e.config.ts delete mode 100644 backend/test/jest-e2e.json create mode 100644 backend/tsconfig.spec-e2e.json diff --git a/backend/jest-e2e.config.ts b/backend/jest-e2e.config.ts new file mode 100644 index 0000000000..c18ab2973d --- /dev/null +++ b/backend/jest-e2e.config.ts @@ -0,0 +1,15 @@ +/* eslint-disable */ +export default { + displayName: 'backend-e2e', + preset: '../jest.preset.js', + rootDir: '.', + testEnvironment: 'node', + testMatch: ['**/*/*.e2e-spec.ts'], + transform: { + '^.+\\.(t|j)s$': [ + 'ts-jest', + { tsconfig: '/tsconfig.spec-e2e.json' }, + ], + }, + coverageDirectory: '../coverage/backend-e2e', +}; diff --git a/backend/jest.config.ts b/backend/jest.config.ts index f844acaa9e..8691623322 100644 --- a/backend/jest.config.ts +++ b/backend/jest.config.ts @@ -1,11 +1,11 @@ /* eslint-disable */ export default { - displayName: 'my-nest-app', + displayName: 'backend', preset: '../jest.preset.js', testEnvironment: 'node', transform: { '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], }, moduleFileExtensions: ['ts', 'js', 'html'], - coverageDirectory: '../coverage/my-nest-app', + coverageDirectory: '../coverage/backend', }; diff --git a/backend/project.json b/backend/project.json index a54a56e3bc..8e7426c97c 100644 --- a/backend/project.json +++ b/backend/project.json @@ -28,6 +28,13 @@ "options": { "jestConfig": "backend/jest.config.ts" } + }, + "test-e2e": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "backend/jest-e2e.config.ts" + } } } } diff --git a/backend/test/indicateurs/indicateurs.e2e-spec.ts b/backend/test/indicateurs/indicateurs.e2e-spec.ts index 1d10a9e8ea..3dfea4e36d 100644 --- a/backend/test/indicateurs/indicateurs.e2e-spec.ts +++ b/backend/test/indicateurs/indicateurs.e2e-spec.ts @@ -1,7 +1,7 @@ import { INestApplication } from '@nestjs/common'; import { Test } from '@nestjs/testing'; import { createClient, SupabaseClient } from '@supabase/supabase-js'; -import * as request from 'supertest'; +import { default as request } from 'supertest'; import { AppModule } from '../../src/app.module'; import { UpsertIndicateursValeursRequest } from '../../src/indicateurs/models/upsertIndicateurs.models'; import { YOLO_DODO_CREDENTIALS } from '../auth/test-users.samples'; @@ -21,10 +21,10 @@ describe('Route de lecture / ecriture des indicateurs', () => { supabase = createClient( process.env.SUPABASE_URL!, - process.env.SUPABASE_ANON_KEY!, + process.env.SUPABASE_ANON_KEY! ); const signinResponse = await supabase.auth.signInWithPassword( - YOLO_DODO_CREDENTIALS, + YOLO_DODO_CREDENTIALS ); yoloDodoToken = signinResponse.data.session?.access_token || ''; }); diff --git a/backend/test/indicateurs/trajectoire-snbc.e2e-spec.ts b/backend/test/indicateurs/trajectoire-snbc.e2e-spec.ts index dbf606f98a..0b23686a5d 100644 --- a/backend/test/indicateurs/trajectoire-snbc.e2e-spec.ts +++ b/backend/test/indicateurs/trajectoire-snbc.e2e-spec.ts @@ -1,8 +1,8 @@ import { INestApplication } from '@nestjs/common'; import { Test } from '@nestjs/testing'; import { createClient, SupabaseClient } from '@supabase/supabase-js'; -import * as _ from 'lodash'; -import * as request from 'supertest'; +import { default as _ } from 'lodash'; +import { default as request } from 'supertest'; import { AppModule } from '../../src/app.module'; import { CalculTrajectoireResultatMode, @@ -27,10 +27,10 @@ describe('Calcul de trajectoire SNBC', () => { supabase = createClient( process.env.SUPABASE_URL!, - process.env.SUPABASE_ANON_KEY!, + process.env.SUPABASE_ANON_KEY! ); const signinResponse = await supabase.auth.signInWithPassword( - YOLO_DODO_CREDENTIALS, + YOLO_DODO_CREDENTIALS ); yoloDodoToken = signinResponse.data.session?.access_token || ''; }); @@ -84,10 +84,10 @@ describe('Calcul de trajectoire SNBC', () => { const verifcationReponseAttendue: VerificationDonneesSNBCResponseType = { status: VerificationDonneesSNBCStatus.DONNEES_MANQUANTES, epci: { - id: 19, - collectivite_id: 3829, - nom: 'CA du Pays de Laon', - siren: '200043495', + id: 2, + collectivite_id: 3812, + nom: 'CA du Bassin de Bourg-en-Bresse', + siren: '200071751', nature: 'CA', }, donnees_entree: { @@ -96,68 +96,77 @@ describe('Calcul de trajectoire SNBC', () => { valeurs: [ { identifiants_referentiel: ['cae_1.c'], - valeur: 56729, - date_min: '2015-01-01', - date_max: '2015-01-01', + valeur: null, + date_min: null, + date_max: null, }, { identifiants_referentiel: ['cae_1.d'], - valeur: 41448, - date_min: '2015-01-01', - date_max: '2015-01-01', + valeur: null, + date_min: null, + date_max: null, }, { identifiants_referentiel: ['cae_1.i'], - valeur: 19760, - date_min: '2015-01-01', - date_max: '2015-01-01', + valeur: null, + date_min: null, + date_max: null, }, { identifiants_referentiel: ['cae_1.g'], - valeur: 28860, - date_min: '2015-01-01', - date_max: '2015-01-01', + valeur: null, + date_min: null, + date_max: null, }, { identifiants_referentiel: ['cae_1.e'], - valeur: 102045, - date_min: '2015-01-01', - date_max: '2015-01-01', + valeur: null, + date_min: null, + date_max: null, }, { identifiants_referentiel: ['cae_1.f'], - valeur: 1039, - date_min: '2015-01-01', - date_max: '2015-01-01', + valeur: null, + date_min: null, + date_max: null, }, { identifiants_referentiel: ['cae_1.h'], - valeur: 3371, - date_min: '2015-01-01', - date_max: '2015-01-01', + valeur: null, + date_min: null, + date_max: null, }, { identifiants_referentiel: ['cae_1.j'], - valeur: 807, - date_min: '2015-01-01', - date_max: '2015-01-01', + valeur: null, + date_min: null, + date_max: null, }, ], - identifiants_referentiel_manquants: [], + identifiants_referentiel_manquants: [ + 'cae_1.c', + 'cae_1.d', + 'cae_1.i', + 'cae_1.g', + 'cae_1.e', + 'cae_1.f', + 'cae_1.h', + 'cae_1.j', + ], }, consommations_finales: { valeurs: [ { identifiants_referentiel: ['cae_2.e'], - valeur: 334.7, - date_min: '2015-01-01', - date_max: '2015-01-01', + valeur: null, + date_min: null, + date_max: null, }, { identifiants_referentiel: ['cae_2.f'], - valeur: 247.25, - date_min: '2015-01-01', - date_max: '2015-01-01', + valeur: null, + date_min: null, + date_max: null, }, { identifiants_referentiel: ['cae_2.k'], @@ -167,15 +176,15 @@ describe('Calcul de trajectoire SNBC', () => { }, { identifiants_referentiel: ['cae_2.i'], - valeur: 24.77, - date_min: '2015-01-01', - date_max: '2015-01-01', + valeur: null, + date_min: null, + date_max: null, }, { identifiants_referentiel: ['cae_2.g', 'cae_2.h'], - valeur: 406.57, - date_min: '2015-01-01', - date_max: '2015-01-01', + valeur: null, + date_min: null, + date_max: null, }, { identifiants_referentiel: ['cae_2.j'], @@ -191,7 +200,12 @@ describe('Calcul de trajectoire SNBC', () => { }, ], identifiants_referentiel_manquants: [ + 'cae_2.e', + 'cae_2.f', 'cae_2.k', + 'cae_2.i', + 'cae_2.g', + 'cae_2.h', 'cae_2.j', 'cae_2.l_pcaet', ], @@ -217,13 +231,13 @@ describe('Calcul de trajectoire SNBC', () => { date_max: null, }, { - identifiants_referentiel: ['cae_63.cc'], + identifiants_referentiel: ['cae_63.cd'], valeur: null, date_min: null, date_max: null, }, { - identifiants_referentiel: ['cae_63.cd'], + identifiants_referentiel: ['cae_63.cc'], valeur: null, date_min: null, date_max: null, @@ -251,8 +265,8 @@ describe('Calcul de trajectoire SNBC', () => { 'cae_63.ca', 'cae_63.cb', 'cae_63.da', - 'cae_63.cc', 'cae_63.cd', + 'cae_63.cc', 'cae_63.db', 'cae_63.b', 'cae_63.e', @@ -262,7 +276,7 @@ describe('Calcul de trajectoire SNBC', () => { }; return request(app.getHttpServer()) .get( - '/trajectoires/snbc/verification?collectivite_id=3829&epci_info=true', + '/trajectoires/snbc/verification?collectivite_id=3812&epci_info=true' ) .set('Authorization', `Bearer ${process.env.SUPABASE_SERVICE_ROLE_KEY}`) .expect(200) @@ -271,16 +285,16 @@ describe('Calcul de trajectoire SNBC', () => { it(`Calcul avec donnees manquantes`, () => { return request(app.getHttpServer()) - .get('/trajectoires/snbc?collectivite_id=3829') + .get('/trajectoires/snbc?collectivite_id=3812') .set('Authorization', `Bearer ${process.env.SUPABASE_SERVICE_ROLE_KEY}`) .expect(422) .expect({ message: - "Les indicateurs suivants n'ont pas de valeur pour l'année 2015 ou avec une interpolation possible : cae_2.k, cae_2.j, cae_2.l_pcaet, impossible de calculer la trajectoire SNBC.", + "Les indicateurs suivants n'ont pas de valeur pour l'année 2015 ou avec une interpolation possible : cae_1.c, cae_1.d, cae_1.i, cae_1.g, cae_1.e, cae_1.f, cae_1.h, cae_1.j, cae_2.e, cae_2.f, cae_2.k, cae_2.i, cae_2.g, cae_2.h, cae_2.j, cae_2.l_pcaet, impossible de calculer la trajectoire SNBC.", error: 'Unprocessable Entity', statusCode: 422, }); - }); + }, 10000); it(`Calcul sans droit suffisant (uniquement lecture)`, () => { return request(app.getHttpServer()) @@ -478,7 +492,7 @@ describe('Calcul de trajectoire SNBC', () => { }; request(app.getHttpServer()) .get( - '/trajectoires/snbc/verification?collectivite_id=4936&epci_info=true', + '/trajectoires/snbc/verification?collectivite_id=4936&epci_info=true' ) .set('Authorization', `Bearer ${yoloDodoToken}`) .expect(200) @@ -517,7 +531,7 @@ describe('Calcul de trajectoire SNBC', () => { // Si on requête de nouveau le calcul, il doit provenir de la base de données const trajectoireSnbcCalculRetourExistant = _.cloneDeep( - trajectoireSnbcCalculRetour, + trajectoireSnbcCalculRetour ); trajectoireSnbcCalculRetourExistant.mode = CalculTrajectoireResultatMode.DONNEES_EN_BDD; @@ -545,7 +559,7 @@ describe('Calcul de trajectoire SNBC', () => { .split('filename=')[1] .split(';')[0]; expect(fileName).toBe( - '"Trajectoire SNBC - 246700488 - Eurome?tropole de Strasbourg.xlsx"', + '"Trajectoire SNBC - 246700488 - Eurome?tropole de Strasbourg.xlsx"' ); }, 30000); diff --git a/backend/test/jest-e2e.json b/backend/test/jest-e2e.json deleted file mode 100644 index e9d912f3e3..0000000000 --- a/backend/test/jest-e2e.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "moduleFileExtensions": ["js", "json", "ts"], - "rootDir": ".", - "testEnvironment": "node", - "testRegex": ".e2e-spec.ts$", - "transform": { - "^.+\\.(t|j)s$": "ts-jest" - } -} diff --git a/backend/tsconfig.spec-e2e.json b/backend/tsconfig.spec-e2e.json new file mode 100644 index 0000000000..613a6b2bc1 --- /dev/null +++ b/backend/tsconfig.spec-e2e.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": ["jest", "node"] + }, + "include": [ + "jest-e2e.config.ts", + "test/**/*.e2e-spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/data_layer/seed/fakes/11-insert_fake_user.sql b/data_layer/seed/fakes/11-insert_fake_user.sql index 6a6e6f4e10..8b41ea6995 100644 --- a/data_layer/seed/fakes/11-insert_fake_user.sql +++ b/data_layer/seed/fakes/11-insert_fake_user.sql @@ -8,6 +8,7 @@ INSERT INTO private_utilisateur_droit (user_id, collectivite_id, niveau_acces, a INSERT INTO private_utilisateur_droit (user_id, collectivite_id, niveau_acces, active) VALUES ('17440546-f389-4d4f-bfdb-b0c94a1bd0f9', (select collectivite_id from epci where siren = '200043495' limit 1), 'edition', TRUE); -- Pays du Laon INSERT INTO private_utilisateur_droit (user_id, collectivite_id, niveau_acces, active) VALUES ('17440546-f389-4d4f-bfdb-b0c94a1bd0f9', (select collectivite_id from epci where siren = '246700488' limit 1), 'edition', TRUE); -- Strastbourg INSERT INTO private_utilisateur_droit (user_id, collectivite_id, niveau_acces, active) VALUES ('17440546-f389-4d4f-bfdb-b0c94a1bd0f9', (select collectivite_id from epci where siren = '200072015' limit 1), 'lecture', TRUE); -- Rhone agglo +INSERT INTO private_utilisateur_droit (user_id, collectivite_id, niveau_acces, active) VALUES ('17440546-f389-4d4f-bfdb-b0c94a1bd0f9', (select collectivite_id from epci where siren = '200071751' limit 1), 'edition', TRUE); -- CA du Bassin de Bourg-en-Bresse INSERT INTO private_collectivite_membre (user_id, collectivite_id, fonction, details_fonction, champ_intervention) VALUES ('17440546-f389-4d4f-bfdb-b0c94a1bd0f9', 1, 'referent', 'Référent YOLO de cette collectivité', '{"eci", "cae"}'); UPDATE utilisateur_verifie SET verifie = true where user_id = '17440546-f389-4d4f-bfdb-b0c94a1bd0f9'; diff --git a/package.json b/package.json index 99a33c2754..3a8c36e8ff 100644 --- a/package.json +++ b/package.json @@ -162,6 +162,7 @@ "@types/react-router-dom": "^5.1.8", "@types/react-table": "^7.7.15", "@types/retry": "^0.12.5", + "@types/supertest": "^6.0.2", "@types/uuid": "^8.3.1", "@types/zxcvbn": "^4.4.1", "@typescript-eslint/eslint-plugin": "^7.18.0", @@ -192,6 +193,7 @@ "storybook": "^7.5.3", "style-loader": "^4.0.0", "supabase": "1.151.1", + "supertest": "^7.0.0", "ts-jest": "^29.1.0", "ts-node": "10.9.1", "tsconfig-paths-webpack-plugin": "^4.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 36a18f7e59..40893ecafa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -474,6 +474,9 @@ importers: '@types/retry': specifier: ^0.12.5 version: 0.12.5 + '@types/supertest': + specifier: ^6.0.2 + version: 6.0.2 '@types/uuid': specifier: ^8.3.1 version: 8.3.4 @@ -564,6 +567,9 @@ importers: supabase: specifier: 1.151.1 version: 1.151.1 + supertest: + specifier: ^7.0.0 + version: 7.0.0 ts-jest: specifier: ^29.1.0 version: 29.2.5(@babel/core@7.25.2)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.2))(esbuild@0.18.20)(jest@29.7.0(@types/node@18.16.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.5.29(@swc/helpers@0.5.13))(@types/node@18.16.9)(typescript@5.6.2)))(typescript@5.6.2) @@ -4429,6 +4435,9 @@ packages: '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + '@types/cookiejar@2.1.5': + resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==} + '@types/cross-spawn@6.0.6': resolution: {integrity: sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA==} @@ -4561,6 +4570,9 @@ packages: '@types/mdx@2.0.13': resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + '@types/methods@1.1.4': + resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==} + '@types/mime-types@2.1.4': resolution: {integrity: sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==} @@ -4666,6 +4678,12 @@ packages: '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + '@types/superagent@8.1.9': + resolution: {integrity: sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==} + + '@types/supertest@6.0.2': + resolution: {integrity: sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg==} + '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} @@ -5171,6 +5189,9 @@ packages: resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} engines: {node: '>= 0.4'} + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + assert@2.1.0: resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} @@ -5749,6 +5770,9 @@ packages: commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + component-emitter@1.3.1: + resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} + compress-commons@6.0.2: resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} engines: {node: '>= 14'} @@ -5809,6 +5833,9 @@ packages: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} + cookiejar@2.1.4: + resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} + cookies@0.8.0: resolution: {integrity: sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==} engines: {node: '>= 0.8'} @@ -6274,6 +6301,9 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + dezalgo@1.0.4: + resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} + didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} @@ -7154,6 +7184,9 @@ packages: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} + formidable@3.5.1: + resolution: {integrity: sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==} + formik@2.4.6: resolution: {integrity: sha512-A+2EI7U7aG296q2TLGvNapDNTZp1khVt5Vk0Q/fyfSROss0V/V6+txt2aJnwEos44IxTCW/LYAi/zgWzlevj+g==} peerDependencies: @@ -7513,6 +7546,10 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true + hexoid@1.0.0: + resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} + engines: {node: '>=8'} + history@4.10.1: resolution: {integrity: sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==} @@ -11016,6 +11053,14 @@ packages: engines: {npm: '>=8'} hasBin: true + superagent@9.0.2: + resolution: {integrity: sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==} + engines: {node: '>=14.18.0'} + + supertest@7.0.0: + resolution: {integrity: sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==} + engines: {node: '>=14.18.0'} + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -17932,6 +17977,8 @@ snapshots: dependencies: '@types/node': 18.16.9 + '@types/cookiejar@2.1.5': {} + '@types/cross-spawn@6.0.6': dependencies: '@types/node': 18.16.9 @@ -18078,6 +18125,8 @@ snapshots: '@types/mdx@2.0.13': {} + '@types/methods@1.1.4': {} + '@types/mime-types@2.1.4': {} '@types/mime@1.3.5': {} @@ -18192,6 +18241,18 @@ snapshots: '@types/stack-utils@2.0.3': {} + '@types/superagent@8.1.9': + dependencies: + '@types/cookiejar': 2.1.5 + '@types/methods': 1.1.4 + '@types/node': 18.16.9 + form-data: 4.0.0 + + '@types/supertest@6.0.2': + dependencies: + '@types/methods': 1.1.4 + '@types/superagent': 8.1.9 + '@types/tough-cookie@4.0.5': {} '@types/trusted-types@2.0.7': {} @@ -18808,6 +18869,8 @@ snapshots: is-array-buffer: 3.0.4 is-shared-array-buffer: 1.0.3 + asap@2.0.6: {} + assert@2.1.0: dependencies: call-bind: 1.0.7 @@ -19447,6 +19510,8 @@ snapshots: commondir@1.0.1: {} + component-emitter@1.3.1: {} + compress-commons@6.0.2: dependencies: crc-32: 1.2.2 @@ -19506,6 +19571,8 @@ snapshots: cookie@0.6.0: {} + cookiejar@2.1.4: {} + cookies@0.8.0: dependencies: depd: 2.0.0 @@ -20007,6 +20074,11 @@ snapshots: dependencies: dequal: 2.0.3 + dezalgo@1.0.4: + dependencies: + asap: 2.0.6 + wrappy: 1.0.2 + didyoumean@1.2.2: {} diff-sequences@28.1.1: {} @@ -21139,6 +21211,12 @@ snapshots: dependencies: fetch-blob: 3.2.0 + formidable@3.5.1: + dependencies: + dezalgo: 1.0.4 + hexoid: 1.0.0 + once: 1.4.0 + formik@2.4.6(react@18.3.1): dependencies: '@types/hoist-non-react-statics': 3.3.5 @@ -21635,6 +21713,8 @@ snapshots: he@1.2.0: {} + hexoid@1.0.0: {} + history@4.10.1: dependencies: '@babel/runtime': 7.25.6 @@ -26158,6 +26238,27 @@ snapshots: transitivePeerDependencies: - supports-color + superagent@9.0.2: + dependencies: + component-emitter: 1.3.1 + cookiejar: 2.1.4 + debug: 4.3.7 + fast-safe-stringify: 2.1.1 + form-data: 4.0.0 + formidable: 3.5.1 + methods: 1.1.2 + mime: 2.6.0 + qs: 6.13.0 + transitivePeerDependencies: + - supports-color + + supertest@7.0.0: + dependencies: + methods: 1.1.2 + superagent: 9.0.2 + transitivePeerDependencies: + - supports-color + supports-color@5.5.0: dependencies: has-flag: 3.0.0 From e0091692331b4b02ce4a7e3a5c8f9fa5e56cc67a Mon Sep 17 00:00:00 2001 From: Thibaut Dusanter Date: Thu, 5 Sep 2024 01:16:40 +0200 Subject: [PATCH 2/2] feat(backend/personnalisations,badkend/referentiels): ajout du calcul de score --- backend/src/app.module.ts | 4 + .../allow-anonymous-access.decorator.ts | 3 + .../allow-public-access.decorator.ts | 3 + .../decorators/public-endpoint.decorator.ts | 3 - backend/src/auth/guards/auth.guard.ts | 28 +- .../src/collectivites/collectivites.module.ts | 3 +- .../controllers/collectivite.controller.ts | 24 + .../models/collectivite.models.ts | 88 + .../services/collectivites.service.ts | 96 +- .../common/controllers/version.controller.ts | 4 +- .../src/common/services/number.helper.spec.ts | 9 + backend/src/common/services/number.helper.ts | 7 + .../controllers/trajectoires.controller.ts | 4 +- .../personnalisations.controller.ts | 91 + ...t-personnalisation-consequences.request.ts | 16 + ...-personnalisation-consequences.response.ts | 13 + .../get-personnalisation-regles.request.ts | 15 + .../get-personnalisation-regles.response.ts | 15 + .../get-personnalisation-reponses.request.ts | 14 + .../get-personnalisation-reponses.response.ts | 15 + .../historique-reponse-binaire.table.ts | 23 + .../models/historique-reponse-choix.table.ts | 25 + .../historique-reponse-proportion.table.ts | 28 + .../personnalisation-consequence.dto.ts | 20 + .../models/personnalisation-regle.table.ts | 34 + .../models/personnalisation.table.ts | 0 .../models/reponse-binaire.table.ts | 21 + .../models/reponse-choix.table.ts | 16 + .../models/reponse-proportion.table.ts | 21 + .../cae-personnalisation-regles.sample.ts | 773 + .../eci-personnalisation-regles.sample.ts | 183 + .../personnalisations.module.ts | 15 + .../expression-parser.service.spec.ts | 622 + .../services/expression-parser.service.ts | 568 + .../services/personnalisations-service.ts | 226 + .../referentiels-scoring.controller.ts | 86 + .../controllers/referentiels.controller.ts | 31 + .../models/action-computed-points.table.ts | 26 + .../models/action-definition.table.ts | 73 + .../models/action-relation.table.ts | 27 + .../referentiels/models/action-score.dto.ts | 105 + .../models/action-statut.table.ts | 45 + .../referentiels/models/action-type.enum.ts | 8 + .../models/client-scores.table.ts | 46 + .../models/get-action-scores.response.ts | 12 + .../models/get-action-statuts.request.ts | 13 + .../models/get-action-statuts.response.ts | 19 + .../models/get-check-scores.response.ts | 21 + .../models/get-referentiel-scores.request.ts | 14 + .../models/get-referentiel-scores.response.ts | 15 + .../models/get-referentiel.response.ts | 21 + .../models/historique-action-statut.table.ts | 59 + .../referentiel-action-avec-score.dto.ts | 31 + .../models/referentiel-action.dto.ts | 27 + .../referentiels/models/referentiel.enum.ts | 9 + .../models/samples/cae-referentiel.ts | 13602 ++++++++++++++++ .../models/samples/deeper-referentiel.ts | 106 + .../models/samples/eci-referentiel.ts | 3409 ++++ .../models/samples/simple-referentiel.ts | 62 + .../src/referentiels/referentiels.module.ts | 22 + .../referentiels-scoring.service.spec.ts | 2078 +++ .../services/referentiels-scoring.service.ts | 857 + .../services/referentiels.service.spec.ts | 156 + .../services/referentiels.service.ts | 230 + backend/test/auth/auth-utils.ts | 17 + backend/test/common/app-utils.ts | 15 + .../personnalisations.e2e-spec.ts | 124 + .../referentiels-scoring.e2e-spec.ts | 218 + .../referentiels/referentiels.e2e-spec.ts | 44 + .../tests/e2e/test_evaluation_scenarios.py | 24 +- ...ute_referentiel_scores_for_collectivite.py | 29 +- .../test_execute_personnalisation_regles.py | 40 +- .../fakes/13-insert_fake_statut_and_score.sql | 4 +- .../seed/fakes/15-insert_fake_indicateurs.sql | 5 + .../seed/fakes/20-insert-fake-reponse.sql | 24 +- package.json | 1 + pnpm-lock.yaml | 47 + 77 files changed, 24774 insertions(+), 58 deletions(-) create mode 100644 backend/src/auth/decorators/allow-anonymous-access.decorator.ts create mode 100644 backend/src/auth/decorators/allow-public-access.decorator.ts delete mode 100644 backend/src/auth/decorators/public-endpoint.decorator.ts create mode 100644 backend/src/collectivites/controllers/collectivite.controller.ts create mode 100644 backend/src/common/services/number.helper.spec.ts create mode 100644 backend/src/common/services/number.helper.ts create mode 100644 backend/src/personnalisations/controllers/personnalisations.controller.ts create mode 100644 backend/src/personnalisations/models/get-personnalisation-consequences.request.ts create mode 100644 backend/src/personnalisations/models/get-personnalisation-consequences.response.ts create mode 100644 backend/src/personnalisations/models/get-personnalisation-regles.request.ts create mode 100644 backend/src/personnalisations/models/get-personnalisation-regles.response.ts create mode 100644 backend/src/personnalisations/models/get-personnalisation-reponses.request.ts create mode 100644 backend/src/personnalisations/models/get-personnalisation-reponses.response.ts create mode 100644 backend/src/personnalisations/models/historique-reponse-binaire.table.ts create mode 100644 backend/src/personnalisations/models/historique-reponse-choix.table.ts create mode 100644 backend/src/personnalisations/models/historique-reponse-proportion.table.ts create mode 100644 backend/src/personnalisations/models/personnalisation-consequence.dto.ts create mode 100644 backend/src/personnalisations/models/personnalisation-regle.table.ts create mode 100644 backend/src/personnalisations/models/personnalisation.table.ts create mode 100644 backend/src/personnalisations/models/reponse-binaire.table.ts create mode 100644 backend/src/personnalisations/models/reponse-choix.table.ts create mode 100644 backend/src/personnalisations/models/reponse-proportion.table.ts create mode 100644 backend/src/personnalisations/models/samples/cae-personnalisation-regles.sample.ts create mode 100644 backend/src/personnalisations/models/samples/eci-personnalisation-regles.sample.ts create mode 100644 backend/src/personnalisations/personnalisations.module.ts create mode 100644 backend/src/personnalisations/services/expression-parser.service.spec.ts create mode 100644 backend/src/personnalisations/services/expression-parser.service.ts create mode 100644 backend/src/personnalisations/services/personnalisations-service.ts create mode 100644 backend/src/referentiels/controllers/referentiels-scoring.controller.ts create mode 100644 backend/src/referentiels/controllers/referentiels.controller.ts create mode 100644 backend/src/referentiels/models/action-computed-points.table.ts create mode 100644 backend/src/referentiels/models/action-definition.table.ts create mode 100644 backend/src/referentiels/models/action-relation.table.ts create mode 100644 backend/src/referentiels/models/action-score.dto.ts create mode 100644 backend/src/referentiels/models/action-statut.table.ts create mode 100644 backend/src/referentiels/models/action-type.enum.ts create mode 100644 backend/src/referentiels/models/client-scores.table.ts create mode 100644 backend/src/referentiels/models/get-action-scores.response.ts create mode 100644 backend/src/referentiels/models/get-action-statuts.request.ts create mode 100644 backend/src/referentiels/models/get-action-statuts.response.ts create mode 100644 backend/src/referentiels/models/get-check-scores.response.ts create mode 100644 backend/src/referentiels/models/get-referentiel-scores.request.ts create mode 100644 backend/src/referentiels/models/get-referentiel-scores.response.ts create mode 100644 backend/src/referentiels/models/get-referentiel.response.ts create mode 100644 backend/src/referentiels/models/historique-action-statut.table.ts create mode 100644 backend/src/referentiels/models/referentiel-action-avec-score.dto.ts create mode 100644 backend/src/referentiels/models/referentiel-action.dto.ts create mode 100644 backend/src/referentiels/models/referentiel.enum.ts create mode 100644 backend/src/referentiels/models/samples/cae-referentiel.ts create mode 100644 backend/src/referentiels/models/samples/deeper-referentiel.ts create mode 100644 backend/src/referentiels/models/samples/eci-referentiel.ts create mode 100644 backend/src/referentiels/models/samples/simple-referentiel.ts create mode 100644 backend/src/referentiels/referentiels.module.ts create mode 100644 backend/src/referentiels/services/referentiels-scoring.service.spec.ts create mode 100644 backend/src/referentiels/services/referentiels-scoring.service.ts create mode 100644 backend/src/referentiels/services/referentiels.service.spec.ts create mode 100644 backend/src/referentiels/services/referentiels.service.ts create mode 100644 backend/test/auth/auth-utils.ts create mode 100644 backend/test/common/app-utils.ts create mode 100644 backend/test/personnalisations/personnalisations.e2e-spec.ts create mode 100644 backend/test/referentiels/referentiels-scoring.e2e-spec.ts create mode 100644 backend/test/referentiels/referentiels.e2e-spec.ts diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index 5fc962d952..f9d407ce45 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -5,6 +5,8 @@ import { CollectivitesModule } from './collectivites/collectivites.module'; import { CommonModule } from './common/common.module'; import { validateBackendConfiguration } from './common/services/backend-configuration.service'; import { IndicateursModule } from './indicateurs/indicateurs.module'; +import { PersonnalisationsModule } from './personnalisations/personnalisations.module'; +import { ReferentielsModule } from './referentiels/referentiels.module'; import { SheetModule } from './spreadsheets/sheet.module'; import { TrpcRouter } from './trpc.router'; import { TrpcModule } from './trpc/trpc.module'; @@ -21,6 +23,8 @@ import { TrpcModule } from './trpc/trpc.module'; CollectivitesModule, IndicateursModule, AuthModule, + PersonnalisationsModule, + ReferentielsModule, ], controllers: [], exports: [TrpcRouter], diff --git a/backend/src/auth/decorators/allow-anonymous-access.decorator.ts b/backend/src/auth/decorators/allow-anonymous-access.decorator.ts new file mode 100644 index 0000000000..dfda97fe59 --- /dev/null +++ b/backend/src/auth/decorators/allow-anonymous-access.decorator.ts @@ -0,0 +1,3 @@ +import { Reflector } from '@nestjs/core'; + +export const AllowAnonymousAccess = Reflector.createDecorator(); diff --git a/backend/src/auth/decorators/allow-public-access.decorator.ts b/backend/src/auth/decorators/allow-public-access.decorator.ts new file mode 100644 index 0000000000..8b0d399e53 --- /dev/null +++ b/backend/src/auth/decorators/allow-public-access.decorator.ts @@ -0,0 +1,3 @@ +import { Reflector } from '@nestjs/core'; + +export const AllowPublicAccess = Reflector.createDecorator(); diff --git a/backend/src/auth/decorators/public-endpoint.decorator.ts b/backend/src/auth/decorators/public-endpoint.decorator.ts deleted file mode 100644 index 2690f5035a..0000000000 --- a/backend/src/auth/decorators/public-endpoint.decorator.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Reflector } from '@nestjs/core'; - -export const PublicEndpoint = Reflector.createDecorator(); diff --git a/backend/src/auth/guards/auth.guard.ts b/backend/src/auth/guards/auth.guard.ts index 7a0b9eeaa0..ae192541c0 100644 --- a/backend/src/auth/guards/auth.guard.ts +++ b/backend/src/auth/guards/auth.guard.ts @@ -10,7 +10,8 @@ import { JwtService } from '@nestjs/jwt'; import { Request } from 'express'; import BackendConfigurationService from '../../common/services/backend-configuration.service'; import { getErrorMessage } from '../../common/services/errors.helper'; -import { PublicEndpoint } from '../decorators/public-endpoint.decorator'; +import { AllowAnonymousAccess } from '../decorators/allow-anonymous-access.decorator'; +import { AllowPublicAccess } from '../decorators/allow-public-access.decorator'; import { SupabaseJwtPayload } from '../models/auth.models'; @Injectable() @@ -19,18 +20,18 @@ export class AuthGuard implements CanActivate { constructor( private jwtService: JwtService, private reflector: Reflector, - private backendConfigurationService: BackendConfigurationService, + private backendConfigurationService: BackendConfigurationService ) {} async canActivate(context: ExecutionContext): Promise { const request = context.switchToHttp().getRequest(); - const publicEndpoint = this.reflector.get( - PublicEndpoint, - context.getHandler(), + const allowPublicAccess = this.reflector.get( + AllowPublicAccess, + context.getHandler() ); - if (publicEndpoint) { + if (allowPublicAccess) { this.logger.log(`Public endpoint`); return true; } @@ -46,15 +47,24 @@ export class AuthGuard implements CanActivate { secret: this.backendConfigurationService.getBackendConfiguration() .SUPABASE_JWT_SECRET, - }, + } ); // 💡 We're assigning the payload to the request object here // so that we can access it in our route handlers request['tokenInfo'] = payload; this.logger.log(`Token validated for user ${payload.sub}`); if (payload.is_anonymous) { - this.logger.error(`Anonymous user is not allowed`); - throw new UnauthorizedException(); + const allowAnonymousAccess = this.reflector.get( + AllowAnonymousAccess, + context.getHandler() + ); + if (allowAnonymousAccess) { + this.logger.log(`Anonymous user is allowed`); + return true; + } else { + this.logger.error(`Anonymous user is not allowed`); + throw new UnauthorizedException(); + } } } catch (err) { this.logger.error(`Failed to validate token: ${getErrorMessage(err)}`); diff --git a/backend/src/collectivites/collectivites.module.ts b/backend/src/collectivites/collectivites.module.ts index c42cc0c388..dba99f5272 100644 --- a/backend/src/collectivites/collectivites.module.ts +++ b/backend/src/collectivites/collectivites.module.ts @@ -1,5 +1,6 @@ import { Module } from '@nestjs/common'; import { CommonModule } from '../common/common.module'; +import { CollectiviteController } from './controllers/collectivite.controller'; import CollectivitesService from './services/collectivites.service'; import GroupementsService from './services/groupements.service'; @@ -7,6 +8,6 @@ import GroupementsService from './services/groupements.service'; imports: [CommonModule], providers: [CollectivitesService, GroupementsService], exports: [CollectivitesService, GroupementsService], - controllers: [], + controllers: [CollectiviteController], }) export class CollectivitesModule {} diff --git a/backend/src/collectivites/controllers/collectivite.controller.ts b/backend/src/collectivites/controllers/collectivite.controller.ts new file mode 100644 index 0000000000..25cd296daf --- /dev/null +++ b/backend/src/collectivites/controllers/collectivite.controller.ts @@ -0,0 +1,24 @@ +import { Controller, Get, Param } from '@nestjs/common'; +import { ApiOkResponse } from '@nestjs/swagger'; +import { AllowPublicAccess } from '../../auth/decorators/allow-public-access.decorator'; +import CollectivitesService from '../services/collectivites.service'; + +/** + * Création des classes de réponse à partir du schema pour générer automatiquement la documentation OpenAPI + */ +//export class VersionResponseClass extends createZodDto(versionResponseSchema) {} + +@Controller() +export class CollectiviteController { + constructor(private readonly collectiviteService: CollectivitesService) {} + + @AllowPublicAccess() + @Get('collectivites/:collectivite_id') + @ApiOkResponse({ + //type: VersionResponseClass, + description: "Récupération des informations d'une collectivite", + }) + async getCollectivite(@Param('collectivite_id') collectiviteId: number) { + return this.collectiviteService.getCollectivite(collectiviteId); + } +} diff --git a/backend/src/collectivites/models/collectivite.models.ts b/backend/src/collectivites/models/collectivite.models.ts index 72d755b59b..f01d2bf909 100644 --- a/backend/src/collectivites/models/collectivite.models.ts +++ b/backend/src/collectivites/models/collectivite.models.ts @@ -3,6 +3,7 @@ import { boolean, integer, pgEnum, + pgSchema, pgTable, serial, timestamp, @@ -13,6 +14,15 @@ import { createInsertSchema, createSelectSchema } from 'drizzle-zod'; // TODO: create domain siren as varchar(9) check ( value ~ '^\d{9}$' ); // TODO: create domain codegeo as varchar(5); +export enum CollectiviteTypeEnum { + EPCI = 'EPCI', + COMMUNE = 'commune', +} + +export enum CollectiviteSousTypeEnum { + SYNDICAT = 'syndicat', +} + export const epciNatureEnum = pgEnum('nature', [ 'SMF', 'CU', @@ -66,3 +76,81 @@ export const communeTable = pgTable('commune', { }); export type CommuneType = InferSelectModel; export type CreateCommuneType = InferInsertModel; + +export type CollectiviteAvecType = Omit< + CollectiviteType & + Partial & + Partial & { + type: CollectiviteTypeEnum; + soustype: CollectiviteSousTypeEnum | null; + population_tags: CollectivitePopulationTypeEnum[]; + drom: boolean; + }, + 'collectivite_id' +>; + +export enum CollectivitePopulationTypeEnum { + MOINS_DE_5000 = 'moins_de_5000', + MOINS_DE_10000 = 'moins_de_10000', + MOINS_DE_20000 = 'moins_de_20000', + MOINS_DE_50000 = 'moins_de_50000', + MOINS_DE_100000 = 'moins_de_100000', + PLUS_DE_20000 = 'plus_de_20000', + PLUS_DE_100000 = 'plus_de_100000', +} +export const typePopulationEnum = pgEnum('type_population', [ + CollectivitePopulationTypeEnum.MOINS_DE_5000, + CollectivitePopulationTypeEnum.MOINS_DE_10000, + CollectivitePopulationTypeEnum.MOINS_DE_20000, + CollectivitePopulationTypeEnum.MOINS_DE_50000, + CollectivitePopulationTypeEnum.MOINS_DE_100000, + CollectivitePopulationTypeEnum.PLUS_DE_20000, + CollectivitePopulationTypeEnum.PLUS_DE_100000, +]); + +export enum CollectiviteLocalisationTypeEnum { + DOM = 'DOM', + METROPOLE = 'Metropole', +} +export const typeLocalisationEnum = pgEnum('type_localisation', [ + CollectiviteLocalisationTypeEnum.DOM, + CollectiviteLocalisationTypeEnum.METROPOLE, +]); + +export interface IdentiteCollectivite { + type: CollectiviteTypeEnum; + soustype: CollectiviteSousTypeEnum | null; + population_tags: CollectivitePopulationTypeEnum[]; + drom: boolean; +} + +export const importsSchema = pgSchema('imports'); + +export const regionTable = importsSchema.table('region', { + code: varchar('code', { length: 2 }), + population: integer('population').notNull(), + libelle: varchar('libelle', { length: 30 }), + drom: boolean('drom').notNull(), +}); +export type RegionType = InferSelectModel; +export type CreateRegionType = InferInsertModel; + +export const banaticTable = importsSchema.table('banatic', { + siren: varchar('siren', { length: 9 }).primaryKey(), + libelle: varchar('libelle', { length: 250 }), + region_code: varchar('region_code', { length: 2 }), + departement_code: varchar('departement_code', { length: 3 }), + nature: epciNatureEnum('nature').notNull(), + population: integer('population').notNull(), +}); + +export type BanaticType = InferSelectModel; +export type CreateBanaticType = InferInsertModel; + +export const importCommuneTable = importsSchema.table('commune', { + code: varchar('code', { length: 5 }).primaryKey(), + region_code: varchar('region_code', { length: 2 }), + departement_code: varchar('departement_code', { length: 3 }), + libelle: varchar('libelle', { length: 30 }), + population: integer('population').notNull(), +}); diff --git a/backend/src/collectivites/services/collectivites.service.ts b/backend/src/collectivites/services/collectivites.service.ts index df2b1d8dd1..1f9442c5cf 100644 --- a/backend/src/collectivites/services/collectivites.service.ts +++ b/backend/src/collectivites/services/collectivites.service.ts @@ -1,22 +1,103 @@ import { Injectable, Logger, NotFoundException } from '@nestjs/common'; -import { eq } from 'drizzle-orm'; +import { aliasedTable, eq, or } from 'drizzle-orm'; import DatabaseService from '../../common/services/database.service'; import { + banaticTable, + CollectiviteAvecType, + CollectivitePopulationTypeEnum, + CollectiviteSousTypeEnum, collectiviteTable, + CollectiviteTypeEnum, communeTable, + CommuneType, epciTable, + EpciType, + importCommuneTable, + regionTable, } from '../models/collectivite.models'; @Injectable() export default class CollectivitesService { private readonly logger = new Logger(CollectivitesService.name); + private readonly POPULATION_BORNES_SUP = [10000, 20000, 50000, 100000]; + private readonly POPULATION_BORNES_INF = [20000, 100000]; + constructor(private readonly databaseService: DatabaseService) {} + getPopulationTags(population?: number): CollectivitePopulationTypeEnum[] { + const populationTags: CollectivitePopulationTypeEnum[] = []; + if (!population) { + return populationTags; + } + this.POPULATION_BORNES_SUP.forEach((borneSup) => { + if (population < borneSup) { + populationTags.push( + `moins_de_${borneSup}` as CollectivitePopulationTypeEnum, + ); + } + }); + this.POPULATION_BORNES_INF.forEach((borneInf) => { + if (population > borneInf) { + populationTags.push( + `plus_de_${borneInf}` as CollectivitePopulationTypeEnum, + ); + } + }); + return populationTags; + } + + getCollectiviteSousType(collectivite: { + epci: EpciType | null; + commune: CommuneType | null; + }): CollectiviteSousTypeEnum | null { + if (collectivite.epci) { + if ( + collectivite.epci.nature === 'SMF' || + collectivite.epci.nature === 'SIVOM' || + collectivite.epci.nature === 'SMO' || + collectivite.epci.nature === 'SIVU' + ) { + return CollectiviteSousTypeEnum.SYNDICAT; + } + } + return null; + } + + async getCollectiviteAvecType( + collectiviteId: number, + ): Promise { + const collectivite = await this.getCollectivite(collectiviteId); + return { + ...collectivite.banatic, + // @ts-ignore: TODO: fix this, pourquoi manque dans drizzle à cause de la jointure? + ...collectivite.import_commune, + ...collectivite.commune, + ...collectivite.epci, + ...collectivite.collectivite, + type: collectivite.epci + ? CollectiviteTypeEnum.EPCI + : CollectiviteTypeEnum.COMMUNE, + soustype: this.getCollectiviteSousType(collectivite), + population_tags: this.getPopulationTags( + collectivite.commune?.population || + // @ts-ignore: TODO: fix this, pourquoi manque dans drizzle à cause de la jointure? + collectivite.import_commune?.population || + collectivite.banatic?.population, + ), + drom: collectivite.region?.drom || false, + }; + } + async getCollectivite(collectiviteId: number) { this.logger.log( `Récupération de la collectivite avec l'identifiant ${collectiviteId}`, ); + + const importCommuneAliasedTable = aliasedTable( + importCommuneTable, + 'import_commune', + ); const collectiviteByIdResult = await this.databaseService.db .select() .from(collectiviteTable) @@ -25,7 +106,20 @@ export default class CollectivitesService { eq(communeTable.collectivite_id, collectiviteTable.id), ) .leftJoin(epciTable, eq(epciTable.collectivite_id, collectiviteTable.id)) + .leftJoin(banaticTable, eq(banaticTable.siren, epciTable.siren)) + .leftJoin( + importCommuneAliasedTable, + eq(importCommuneAliasedTable.code, communeTable.code), + ) + .leftJoin( + regionTable, + or( + eq(regionTable.code, banaticTable.region_code), + eq(regionTable.code, importCommuneAliasedTable.region_code), + ), + ) .where(eq(collectiviteTable.id, collectiviteId)); + if (!collectiviteByIdResult?.length) { throw new NotFoundException( `Commune avec l'identifiant de collectivite ${collectiviteId} introuvable`, diff --git a/backend/src/common/controllers/version.controller.ts b/backend/src/common/controllers/version.controller.ts index 602d11b13f..7aaf26e983 100644 --- a/backend/src/common/controllers/version.controller.ts +++ b/backend/src/common/controllers/version.controller.ts @@ -1,7 +1,7 @@ import { createZodDto } from '@anatine/zod-nestjs'; import { Controller, Get } from '@nestjs/common'; import { ApiOkResponse } from '@nestjs/swagger'; -import { PublicEndpoint } from '../../auth/decorators/public-endpoint.decorator'; +import { AllowPublicAccess } from '../../auth/decorators/allow-public-access.decorator'; import { versionResponseSchema } from '../models/version.models'; /** @@ -10,7 +10,7 @@ import { versionResponseSchema } from '../models/version.models'; export class VersionResponseClass extends createZodDto(versionResponseSchema) {} @Controller() export class VersionController { - @PublicEndpoint() + @AllowPublicAccess() @Get('version') @ApiOkResponse({ type: VersionResponseClass, diff --git a/backend/src/common/services/number.helper.spec.ts b/backend/src/common/services/number.helper.spec.ts new file mode 100644 index 0000000000..81e1ddb6dd --- /dev/null +++ b/backend/src/common/services/number.helper.spec.ts @@ -0,0 +1,9 @@ +import { roundTo } from './number.helper'; + +describe('number helper', () => { + describe('roundTo', () => { + it('roundTo for 1.5625', async () => { + expect(roundTo(1.5625, 3)).toBe(1.563); + }); + }); +}); diff --git a/backend/src/common/services/number.helper.ts b/backend/src/common/services/number.helper.ts new file mode 100644 index 0000000000..6a86de2c05 --- /dev/null +++ b/backend/src/common/services/number.helper.ts @@ -0,0 +1,7 @@ +export function roundTo(num: number | null, precision: number): number | null { + if (!num) { + return num; + } + const factor = Math.pow(10, precision); + return Math.round((num + Number.EPSILON) * factor + Number.EPSILON) / factor; +} diff --git a/backend/src/indicateurs/controllers/trajectoires.controller.ts b/backend/src/indicateurs/controllers/trajectoires.controller.ts index f60fba0696..69ac284e88 100644 --- a/backend/src/indicateurs/controllers/trajectoires.controller.ts +++ b/backend/src/indicateurs/controllers/trajectoires.controller.ts @@ -10,7 +10,7 @@ import { } from '@nestjs/common'; import { ApiOkResponse, ApiResponse, ApiTags } from '@nestjs/swagger'; import { NextFunction, Response } from 'express'; -import { PublicEndpoint } from '../../auth/decorators/public-endpoint.decorator'; +import { AllowPublicAccess } from '../../auth/decorators/allow-public-access.decorator'; import { TokenInfo } from '../../auth/decorators/token-info.decorators'; import type { SupabaseJwtPayload } from '../../auth/models/auth.models'; import { CollectiviteRequestClass } from '../../collectivites/models/collectivite.request'; @@ -90,7 +90,7 @@ export class TrajectoiresController { ); } - @PublicEndpoint() + @AllowPublicAccess() @Get('modele') @ApiOkResponse({ description: diff --git a/backend/src/personnalisations/controllers/personnalisations.controller.ts b/backend/src/personnalisations/controllers/personnalisations.controller.ts new file mode 100644 index 0000000000..af885d2d29 --- /dev/null +++ b/backend/src/personnalisations/controllers/personnalisations.controller.ts @@ -0,0 +1,91 @@ +import { createZodDto } from '@anatine/zod-nestjs'; +import { Controller, Get, Logger, Param, Query } from '@nestjs/common'; +import { ApiResponse, ApiTags } from '@nestjs/swagger'; +import { AllowAnonymousAccess } from '../../auth/decorators/allow-anonymous-access.decorator'; +import { AllowPublicAccess } from '../../auth/decorators/allow-public-access.decorator'; +import { TokenInfo } from '../../auth/decorators/token-info.decorators'; +import { SupabaseJwtPayload } from '../../auth/models/auth.models'; +import { getPersonnalisationConsequencesRequestSchema } from '../models/get-personnalisation-consequences.request'; +import { getPersonnalitionConsequencesResponseSchema } from '../models/get-personnalisation-consequences.response'; +import { getPersonnalisationReglesRequestSchema } from '../models/get-personnalisation-regles.request'; +import { getPersonnalisationReglesResponseSchema } from '../models/get-personnalisation-regles.response'; +import { getPersonnalisationReponsesRequestSchema } from '../models/get-personnalisation-reponses.request'; +import { getPersonnalitionReponsesResponseSchema } from '../models/get-personnalisation-reponses.response'; +import PersonnalisationService from '../services/personnalisations-service'; + +/** + * Création des classes de requête/réponse à partir du schema pour générer automatiquement la documentation OpenAPI et la validation des entrées + */ +class GetPersonnalitionReponsesResponseClass extends createZodDto( + getPersonnalitionReponsesResponseSchema +) {} +class GetPersonnalitionReponsesQueryClass extends createZodDto( + getPersonnalisationReponsesRequestSchema +) {} +class GetPersonnalitionConsequencesQueryClass extends createZodDto( + getPersonnalisationConsequencesRequestSchema +) {} + +class GetPersonnalitionConsequencesResponseClass extends createZodDto( + getPersonnalitionConsequencesResponseSchema +) {} + +class GetPersonnalisationReglesRequestClass extends createZodDto( + getPersonnalisationReglesRequestSchema +) {} + +class GetPersonnalisationReglesResponseClass extends createZodDto( + getPersonnalisationReglesResponseSchema +) {} + +@ApiTags('Personnalisations') +@Controller('') +export class PersonnalisationsController { + private readonly logger = new Logger(PersonnalisationsController.name); + + constructor( + private readonly personnalisationsService: PersonnalisationService + ) {} + + @AllowPublicAccess() + @Get('personnalisations/regles') + @ApiResponse({ type: GetPersonnalisationReglesResponseClass }) + async getPersonnalisationRegles( + @Query() request: GetPersonnalisationReglesRequestClass, + @TokenInfo() tokenInfo: SupabaseJwtPayload + ): Promise { + return this.personnalisationsService.getPersonnalisationRegles( + request.referentiel + ); + } + + @AllowAnonymousAccess() + @Get('collectivites/:collectivite_id/personnalisations/reponses') + @ApiResponse({ type: GetPersonnalitionReponsesResponseClass }) + async getPersonnalisationReponses( + @Param('collectivite_id') collectiviteId: number, + @Query() request: GetPersonnalitionReponsesQueryClass, + @TokenInfo() tokenInfo: SupabaseJwtPayload + ): Promise { + return this.personnalisationsService.getPersonnalisationReponses( + collectiviteId, + request.date, + tokenInfo + ); + } + + @AllowAnonymousAccess() + @Get('collectivites/:collectivite_id/personnalisations/consequences') + @ApiResponse({ type: GetPersonnalitionConsequencesResponseClass }) + async getPersonnalisationConsequences( + @Param('collectivite_id') collectiviteId: number, + @Query() request: GetPersonnalitionConsequencesQueryClass, + @TokenInfo() tokenInfo: SupabaseJwtPayload + ): Promise { + return this.personnalisationsService.getPersonnalisationConsequencesForCollectivite( + collectiviteId, + request, + tokenInfo + ); + } +} diff --git a/backend/src/personnalisations/models/get-personnalisation-consequences.request.ts b/backend/src/personnalisations/models/get-personnalisation-consequences.request.ts new file mode 100644 index 0000000000..4963069f6c --- /dev/null +++ b/backend/src/personnalisations/models/get-personnalisation-consequences.request.ts @@ -0,0 +1,16 @@ +import { extendApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; +import { ReferentielType } from '../../referentiels/models/referentiel.enum'; +import { getPersonnalisationReponsesRequestSchema } from './get-personnalisation-reponses.request'; + +export const getPersonnalisationConsequencesRequestSchema = extendApi( + getPersonnalisationReponsesRequestSchema.extend({ + referentiel: z.nativeEnum(ReferentielType).optional(), + }) +).openapi({ + description: + 'Paramètres de la requête pour obtenir les conséquences de personnalisation sur un référentiel pour une collectivité donnée', +}); +export type GetPersonnalisationConsequencesRequestType = z.infer< + typeof getPersonnalisationConsequencesRequestSchema +>; diff --git a/backend/src/personnalisations/models/get-personnalisation-consequences.response.ts b/backend/src/personnalisations/models/get-personnalisation-consequences.response.ts new file mode 100644 index 0000000000..a508683ac3 --- /dev/null +++ b/backend/src/personnalisations/models/get-personnalisation-consequences.response.ts @@ -0,0 +1,13 @@ +import { extendApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; +import { personnalisationConsequenceSchema } from './personnalisation-consequence.dto'; + +export const getPersonnalitionConsequencesResponseSchema = extendApi( + z.record(z.string(), personnalisationConsequenceSchema), +).openapi({ + description: 'Conséquence des règles de personnalisation sur les actions', + title: 'Conséquence des règles de personnalisation', +}); +export type GetPersonnalitionConsequencesResponseType = z.infer< + typeof getPersonnalitionConsequencesResponseSchema +>; diff --git a/backend/src/personnalisations/models/get-personnalisation-regles.request.ts b/backend/src/personnalisations/models/get-personnalisation-regles.request.ts new file mode 100644 index 0000000000..b68ed677a0 --- /dev/null +++ b/backend/src/personnalisations/models/get-personnalisation-regles.request.ts @@ -0,0 +1,15 @@ +import { extendApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; +import { ReferentielType } from '../../referentiels/models/referentiel.enum'; + +export const getPersonnalisationReglesRequestSchema = extendApi( + z.object({ + referentiel: z.nativeEnum(ReferentielType).optional(), + }) +).openapi({ + description: + 'Paramètres de la requête pour obtenir les règles de personnalisation', +}); +export type GetPersonnalisationReglesRequestType = z.infer< + typeof getPersonnalisationReglesRequestSchema +>; diff --git a/backend/src/personnalisations/models/get-personnalisation-regles.response.ts b/backend/src/personnalisations/models/get-personnalisation-regles.response.ts new file mode 100644 index 0000000000..24fa390060 --- /dev/null +++ b/backend/src/personnalisations/models/get-personnalisation-regles.response.ts @@ -0,0 +1,15 @@ +import { extendApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; +import { personnalisationRegleSchema } from './personnalisation-regle.table'; + +export const getPersonnalisationReglesResponseSchema = extendApi( + z.object({ + regles: z.array(personnalisationRegleSchema), + }), +).openapi({ + description: 'Liste des regles de personnalisation', + title: 'Liste des regles de personnalisation', +}); +export type GetPersonnalisationReglesResponseType = z.infer< + typeof getPersonnalisationReglesResponseSchema +>; diff --git a/backend/src/personnalisations/models/get-personnalisation-reponses.request.ts b/backend/src/personnalisations/models/get-personnalisation-reponses.request.ts new file mode 100644 index 0000000000..ec0b82c8ea --- /dev/null +++ b/backend/src/personnalisations/models/get-personnalisation-reponses.request.ts @@ -0,0 +1,14 @@ +import { extendApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; + +export const getPersonnalisationReponsesRequestSchema = extendApi( + z.object({ + date: z.string().datetime().optional(), + }), +).openapi({ + description: + 'Paramètres de la requête pour obtenir les réponses aux questions de personnalisation', +}); +export type GetPersonnalisationReponsesRequestType = z.infer< + typeof getPersonnalisationReponsesRequestSchema +>; diff --git a/backend/src/personnalisations/models/get-personnalisation-reponses.response.ts b/backend/src/personnalisations/models/get-personnalisation-reponses.response.ts new file mode 100644 index 0000000000..a312aba4d9 --- /dev/null +++ b/backend/src/personnalisations/models/get-personnalisation-reponses.response.ts @@ -0,0 +1,15 @@ +import { extendApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; + +export const getPersonnalitionReponsesResponseSchema = extendApi( + z.record( + z.string(), + z.union([z.string(), z.number(), z.boolean(), z.null()]), + ), +).openapi({ + description: 'Reponses aux questions de personnalisation', + title: 'Reponses de personnalisation', +}); +export type GetPersonnalisationReponsesResponseType = z.infer< + typeof getPersonnalitionReponsesResponseSchema +>; diff --git a/backend/src/personnalisations/models/historique-reponse-binaire.table.ts b/backend/src/personnalisations/models/historique-reponse-binaire.table.ts new file mode 100644 index 0000000000..c7391df0ca --- /dev/null +++ b/backend/src/personnalisations/models/historique-reponse-binaire.table.ts @@ -0,0 +1,23 @@ +import { sql } from 'drizzle-orm'; +import { boolean, integer, timestamp, varchar } from 'drizzle-orm/pg-core'; +import { collectiviteTable } from '../../collectivites/models/collectivite.models'; +import { historiqueSchema } from './historique-reponse-choix.table'; + +export const historiqueReponseBinaireTable = historiqueSchema.table( + 'reponse_binaire', + { + modified_at: timestamp('modified_at', { + withTimezone: true, + mode: 'string', + }) + .default(sql`CURRENT_TIMESTAMP`) + .notNull(), + collectivite_id: integer('collectivite_id') + .references(() => collectiviteTable.id) + .notNull(), + // TODO: failed to parse database type 'question_id' + question_id: varchar('question_id', { length: 30 }).notNull(), + reponse: boolean('reponse'), + previous_reponse: boolean('previous_reponse'), + }, +); diff --git a/backend/src/personnalisations/models/historique-reponse-choix.table.ts b/backend/src/personnalisations/models/historique-reponse-choix.table.ts new file mode 100644 index 0000000000..300f438642 --- /dev/null +++ b/backend/src/personnalisations/models/historique-reponse-choix.table.ts @@ -0,0 +1,25 @@ +import { sql } from 'drizzle-orm'; +import { integer, pgSchema, timestamp, varchar } from 'drizzle-orm/pg-core'; +import { collectiviteTable } from '../../collectivites/models/collectivite.models'; + +export const historiqueSchema = pgSchema('historique'); +export const historiqueReponseChoixTable = historiqueSchema.table( + 'reponse_choix', + { + modified_at: timestamp('modified_at', { + withTimezone: true, + mode: 'string', + }) + .default(sql`CURRENT_TIMESTAMP`) + .notNull(), + collectivite_id: integer('collectivite_id') + .references(() => collectiviteTable.id) + .notNull(), + // TODO: Reference question + question_id: varchar('question_id', { length: 30 }).notNull(), + // TODO: Reference choix_id + reponse: varchar('reponse', { length: 30 }), + // TODO: Reference choix_id + previous_reponse: varchar('previous_reponse', { length: 30 }), + }, +); diff --git a/backend/src/personnalisations/models/historique-reponse-proportion.table.ts b/backend/src/personnalisations/models/historique-reponse-proportion.table.ts new file mode 100644 index 0000000000..c4174f4e81 --- /dev/null +++ b/backend/src/personnalisations/models/historique-reponse-proportion.table.ts @@ -0,0 +1,28 @@ +import { sql } from 'drizzle-orm'; +import { + doublePrecision, + integer, + timestamp, + varchar, +} from 'drizzle-orm/pg-core'; +import { collectiviteTable } from '../../collectivites/models/collectivite.models'; +import { historiqueSchema } from './historique-reponse-choix.table'; + +export const historiqueReponseProportionTable = historiqueSchema.table( + 'reponse_proportion', + { + modified_at: timestamp('modified_at', { + withTimezone: true, + mode: 'string', + }) + .default(sql`CURRENT_TIMESTAMP`) + .notNull(), + collectivite_id: integer('collectivite_id') + .references(() => collectiviteTable.id) + .notNull(), + // TODO: Reference question + question_id: varchar('question_id', { length: 30 }).notNull(), + reponse: doublePrecision('reponse'), + previous_reponse: doublePrecision('previous_reponse'), + }, +); diff --git a/backend/src/personnalisations/models/personnalisation-consequence.dto.ts b/backend/src/personnalisations/models/personnalisation-consequence.dto.ts new file mode 100644 index 0000000000..643f63424a --- /dev/null +++ b/backend/src/personnalisations/models/personnalisation-consequence.dto.ts @@ -0,0 +1,20 @@ +import { extendApi, extendZodWithOpenApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; +extendZodWithOpenApi(z); + +export const personnalisationConsequenceSchema = extendApi( + z + .object({ + desactive: z.boolean().nullable(), + score_formule: z.string().nullable(), + potentiel_perso: z.number().nullable(), + }) + .openapi({ + title: + 'Consequence des règles de personnalisation pour une action donnée', + }), +); + +export type PersonnalisationConsequenceType = z.infer< + typeof personnalisationConsequenceSchema +>; diff --git a/backend/src/personnalisations/models/personnalisation-regle.table.ts b/backend/src/personnalisations/models/personnalisation-regle.table.ts new file mode 100644 index 0000000000..2c5d0fc731 --- /dev/null +++ b/backend/src/personnalisations/models/personnalisation-regle.table.ts @@ -0,0 +1,34 @@ +import { InferInsertModel, InferSelectModel } from 'drizzle-orm'; +import { pgEnum, pgTable, text, timestamp } from 'drizzle-orm/pg-core'; +import { sql } from 'drizzle-orm/sql'; +import { createInsertSchema, createSelectSchema } from 'drizzle-zod'; +import { actionIdReference } from '../../referentiels/models/action-definition.table'; + +export const regleTypeEnum = pgEnum('regle_type', [ + 'score', + 'desactivation', + 'reduction', +]); + +export const personnalisationRegleTable = pgTable('personnalisation_regle', { + action_id: actionIdReference.notNull(), + type: regleTypeEnum('type').notNull(), + formule: text('formule').notNull(), + description: text('description').notNull(), + modified_at: timestamp('modified_at', { withTimezone: true, mode: 'string' }) + .default(sql`CURRENT_TIMESTAMP`) + .notNull(), +}); + +export type PersonnalisationRegleType = InferSelectModel< + typeof personnalisationRegleTable +>; +export type CreatePersonnalisationRegleType = InferInsertModel< + typeof personnalisationRegleTable +>; +export const personnalisationRegleSchema = createSelectSchema( + personnalisationRegleTable, +); +export const createPersonnalisationRegleSchema = createInsertSchema( + personnalisationRegleTable, +); diff --git a/backend/src/personnalisations/models/personnalisation.table.ts b/backend/src/personnalisations/models/personnalisation.table.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/backend/src/personnalisations/models/reponse-binaire.table.ts b/backend/src/personnalisations/models/reponse-binaire.table.ts new file mode 100644 index 0000000000..bdd9d639d1 --- /dev/null +++ b/backend/src/personnalisations/models/reponse-binaire.table.ts @@ -0,0 +1,21 @@ +import { sql } from 'drizzle-orm'; +import { + boolean, + integer, + pgTable, + timestamp, + varchar, +} from 'drizzle-orm/pg-core'; +import { collectiviteTable } from '../../collectivites/models/collectivite.models'; + +export const reponseBinaireTable = pgTable('reponse_binaire', { + modified_at: timestamp('modified_at', { withTimezone: true, mode: 'string' }) + .default(sql`CURRENT_TIMESTAMP`) + .notNull(), + collectivite_id: integer('collectivite_id') + .references(() => collectiviteTable.id) + .notNull(), + // TODO: failed to parse database type 'question_id' + question_id: varchar('question_id', { length: 30 }).notNull(), + reponse: boolean('reponse'), +}); diff --git a/backend/src/personnalisations/models/reponse-choix.table.ts b/backend/src/personnalisations/models/reponse-choix.table.ts new file mode 100644 index 0000000000..3eeba61042 --- /dev/null +++ b/backend/src/personnalisations/models/reponse-choix.table.ts @@ -0,0 +1,16 @@ +import { sql } from 'drizzle-orm'; +import { integer, pgTable, timestamp, varchar } from 'drizzle-orm/pg-core'; +import { collectiviteTable } from '../../collectivites/models/collectivite.models'; + +export const reponseChoixTable = pgTable('reponse_choix', { + modified_at: timestamp('modified_at', { withTimezone: true, mode: 'string' }) + .default(sql`CURRENT_TIMESTAMP`) + .notNull(), + collectivite_id: integer('collectivite_id') + .references(() => collectiviteTable.id) + .notNull(), + // TODO: Reference question + question_id: varchar('question_id', { length: 30 }).notNull(), + // TODO: Reference choix_id + reponse: varchar('reponse', { length: 30 }), +}); diff --git a/backend/src/personnalisations/models/reponse-proportion.table.ts b/backend/src/personnalisations/models/reponse-proportion.table.ts new file mode 100644 index 0000000000..d01ed31e12 --- /dev/null +++ b/backend/src/personnalisations/models/reponse-proportion.table.ts @@ -0,0 +1,21 @@ +import { sql } from 'drizzle-orm'; +import { + doublePrecision, + integer, + pgTable, + timestamp, + varchar, +} from 'drizzle-orm/pg-core'; +import { collectiviteTable } from '../../collectivites/models/collectivite.models'; + +export const reponseProportionTable = pgTable('reponse_proportion', { + modified_at: timestamp('modified_at', { withTimezone: true, mode: 'string' }) + .default(sql`CURRENT_TIMESTAMP`) + .notNull(), + collectivite_id: integer('collectivite_id') + .references(() => collectiviteTable.id) + .notNull(), + // TODO: Reference question + question_id: varchar('question_id', { length: 30 }).notNull(), + reponse: doublePrecision('reponse'), +}); diff --git a/backend/src/personnalisations/models/samples/cae-personnalisation-regles.sample.ts b/backend/src/personnalisations/models/samples/cae-personnalisation-regles.sample.ts new file mode 100644 index 0000000000..04b55d2cb1 --- /dev/null +++ b/backend/src/personnalisations/models/samples/cae-personnalisation-regles.sample.ts @@ -0,0 +1,773 @@ +import { GetPersonnalisationReglesResponseType } from '../get-personnalisation-regles.response'; + +export const caePersonnalisationRegles: GetPersonnalisationReglesResponseType = + { + regles: [ + { + action_id: 'cae_1.1.2.0.1', + type: 'desactivation', + formule: + 'si identite(type, commune) alors VRAI\nsinon si identite(type, EPCI) et identite(population, moins_de_20000) alors VRAI\n', + description: + "

Seuls les EPCI à fiscalité propre de plus de 20 000 habitants sont concernées par l'obligation de réaliser un PCAET.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_1.1.2.0.2', + type: 'desactivation', + formule: 'identite(population, moins_de_50000)\n', + description: + "

Les collectivités de moins de 50 000 habitants ne sont pas concernées par l'obligation BEGES.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_1.1.2.1', + type: 'desactivation', + formule: + 'si identite(type, EPCI) et identite(population, plus_de_20000) alors VRAI\n', + description: + '

Seuls les EPCI à fiscalité propre de plus de 20 000 habitants ne sont pas évaluées sur cette action.

\n', + modified_at: '2023-10-27 09:19:16.433221+00', + }, + { + action_id: 'cae_1.1.2.1', + type: 'reduction', + formule: + 'si identite(type, EPCI) et identite(population, plus_de_20000) alors 0\n', + description: '', + modified_at: '2023-10-27 11:56:17.852604+00', + }, + { + action_id: 'cae_1.1.2.1.5', + type: 'desactivation', + formule: 'identite(type, EPCI)\n', + description: '', + modified_at: '2023-02-20 09:49:29.286703+00', + }, + { + action_id: 'cae_1.1.2.2', + type: 'reduction', + formule: + 'si identite(type, EPCI) et identite(population, plus_de_20000) alors 5/4\n', + description: + '

La note du référentiel actuel est à 40 %. Pour les EPCI plus de 20 000, la note de la sous-action passe à 50 %.

\n', + modified_at: '2023-10-27 09:19:16.433221+00', + }, + { + action_id: 'cae_1.1.2.5', + type: 'reduction', + formule: + 'si identite(type, EPCI) et identite(population, plus_de_20000) alors 3/2\n', + description: + '

La note du référentiel actuel est à 20 %. Pour les EPCI plus de 20 000, la note de la sous-action passe à 30 %.

\n', + modified_at: '2023-10-27 09:19:16.433221+00', + }, + { + action_id: 'cae_1.2.2', + type: 'reduction', + formule: + 'si reponse(centre_urbain, NON) et reponse (AOM_1, NON) alors 2/12 \nsinon si reponse (AOM_1, NON) alors 6/12\n', + description: + "

Pour une collectivité n'ayant pas la compétence AOM, le score de la 1.2.2 est réduit de 50 %.

\n

Pour une collectivité n'ayant pas de centre urbain de plus de 5000 habitants ET n'ayant pas la compétence AOM, le score de la 1.2.2 est réduit à 2 points.

\n

Pour une collectivité AOM, de plus de 100 000 habitants, la 1.2.2.1 est désactivée et la 1.2.2.5 est évaluée sur 40 % des points.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_1.2.2.1', + type: 'desactivation', + formule: + 'reponse(AOM_1, OUI) et identite(population, plus_de_100000)\n', + description: + '

Pour une collectivité AOM, de plus de 100 000 habitants, la 1.2.2.1 est désactivée.

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_1.2.2.1', + type: 'reduction', + formule: + 'si reponse(AOM_1, OUI) et identite(population, plus_de_100000) alors 0.0\n', + description: + '

Pour une collectivité AOM, de plus de 100 000 habitants, le potentiel passe de 10% à 0%.

\n', + modified_at: '2022-12-21 09:56:06.218724+00', + }, + { + action_id: 'cae_1.2.2.1.1', + type: 'desactivation', + formule: 'identite(type, commune)\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_1.2.2.1.3', + type: 'desactivation', + formule: 'identite(type, EPCI)\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_1.2.2.5', + type: 'reduction', + formule: + 'si reponse(AOM_1, OUI) et identite(population, plus_de_100000) alors 0.4/0.3\n', + description: + '

Pour une collectivité AOM, de plus de 100 000 habitants, la 1.2.2.5 est notée sur 40 % (au lieu de 30 %).

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_1.2.3', + type: 'reduction', + formule: + 'si reponse(dechets_1, OUI) et reponse(dechets_2, OUI) et reponse(dechets_3, OUI) alors 1.0\nsinon si reponse(dechets_1, NON) et reponse(dechets_2, NON) et reponse(dechets_3, NON) alors 2/10\nsinon si reponse(dechets_1, NON) ou reponse(dechets_2, NON) ou reponse(dechets_3, NON) alors 0.75\n', + description: + "

Pour une collectivité ne possédant que partiellement les compétences collecte, traitement des déchets et plan de prévention des déchets, le score de la 1.2.3 est réduit de 25 %.

\n

Pour une collectivité n'ayant aucune des compétences collecte, traitement des déchets et plan de prévention des déchets, le score de la 1.2.3 est réduit à 2 points.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_1.2.3.1.4', + type: 'desactivation', + formule: 'reponse(dechets_1, NON)\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_1.2.3.1.5', + type: 'desactivation', + formule: 'reponse(dechets_2, NON)\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_1.2.4', + type: 'reduction', + formule: + 'si identite(type, EPCI) et reponse(habitat_1, NON) alors 8/12 \nsinon si identite(type, commune) alors max (reponse(habitat_2), 0.5) \n', + description: + "

Pour un EPCI n'ayant pas la compétence habitat, le score de la 1.2.4 est réduit à 8 points.

\n

Si la collectivité est une commune, le potentiel est réduit à la part de la commune dans la collectivité compétente en matière de Programme Local de l’Habitat (PLH), dans la limite de 50 %.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_1.3.1', + type: 'reduction', + formule: + 'si reponse(urba_1, NON) et reponse(SCoT, NON) alors 6/12 \nsinon si reponse(urba_1, NON) et reponse(SCoT, OUI) alors 0.7 \n', + description: + "

Pour une collectivité n'ayant ni la compétence PLU, ni la compétence SCOT, le score de la 1.3.1 est réduit de 50 %.

\n

Pour une collectivité n'ayant pas la compétence PLU mais disposant de la compétence SCOT, le score de la 1.3.1 est réduit de 30 %.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_1.3.2', + type: 'reduction', + formule: + 'si reponse(amenagement_1, NON) ou reponse (amenagement_2, NON) alors 5/10 \n', + description: + "

Si une collectivité n'a pas de terrains utilisables ou vendables ou elle dispose de terrains de ce type mais n'a pas réalisé de vente ou de contrats d'utilisation alors le score de la 1.3.2 est réduit de 50 %.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_1.3.3', + type: 'desactivation', + formule: + 'reponse(urba_1, NON) et reponse (urba_2, NON) et reponse(urba_3, NON)\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_1.3.3', + type: 'reduction', + formule: + 'si reponse(urba_1, NON) et reponse (urba_2, NON) et reponse(urba_3, NON) alors 0\nsinon si reponse(urba_1, OUI) et reponse(urba_2, NON) et reponse(urba_3, NON) alors 0.5\nsinon si reponse(urba_1, NON) et reponse(urba_2, OUI) et reponse(urba_3, NON) alors 0.5\nsinon si reponse(urba_1, NON) et reponse(urba_2, NON) et reponse(urba_3, OUI) alors 0.5\n', + description: + "

Pour une collectivité n'ayant ni la compétence PLU, ni l'instruction, ni l'octroi des permis de construire, le score de la 1.3.3 est réduit de 100 % et le statut de la 1.3.3 est "non concerné".

\n

Pour une collectivité n'ayant que l'une des compétences (PLU, instruction ou octroi des permis de construire), le score de la 1.3.3 est réduit de 50 %.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_2.2.3', + type: 'reduction', + formule: + 'si identite(localisation, DOM) et reponse(ECS, NON) alors 0.3\n', + description: + "

Pour une collectivité hors France Métropolitaine, et en l'absence de besoin d'eau chaude sanitaire, le score de la 2.2.3 est réduit de 70 %.

\n

Pour une collectivité hors France Métropolitaine, le statut des sous-actions 2.2.3.1 à 2.2.3.3 est "non concerné".

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_2.2.3.1', + type: 'desactivation', + formule: 'identite(localisation, DOM) \n', + description: + '

Pour une collectivité hors France Métropolitaine, le statut de la sous-action 2.2.3.1 est "non concernée".

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_2.2.3.2', + type: 'desactivation', + formule: 'identite(localisation, DOM) \n', + description: + '

Pour une collectivité hors France Métropolitaine, le statut de la sous-action 2.2.3.2 est "non concernée".

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_2.2.3.3', + type: 'desactivation', + formule: 'identite(localisation, DOM) \n', + description: + '

Pour une collectivité hors France Métropolitaine, le statut de la sous-action 2.2.3.3 est "non concernée".

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_2.2.4.2.4', + type: 'desactivation', + formule: 'identite(localisation, Metropole)\n', + description: + '

Pour une collectivité hors DOM, la tâche "installer ou favoriser les moyens de production avec stockage de l’électricité" est non concernée.

\n', + modified_at: '2023-10-27 09:19:16.433221+00', + }, + { + action_id: 'cae_2.3.1', + type: 'desactivation', + formule: 'identite(type, EPCI) et reponse(EP_1, EP_1_c)\n', + description: + "

Si la collectivité est un EPCI sans compétence sur l'éclairage public, alors le score est réduit à 0 et les statuts sont "non concernés".

\n

Si la collectivité est un EPCI avec une compétence éclairage public limitée, alors la collectivité est évaluée sur 2 points (au lieu de 6).

\n

Si la collectivité a délégué sa compétence éclairage public à une autre structure, alors le score est proportionnel à la participation de la collectivité dans la structure.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_2.3.1', + type: 'reduction', + formule: + 'si identite(type, EPCI) et reponse(EP_1, EP_1_b) alors 2/6\nsinon si identite(type, EPCI) et reponse(EP_1, EP_1_c) alors 0\nsinon reponse(EP_2)\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_2.3.3', + type: 'desactivation', + formule: 'reponse(voirie_1, voirie_1_c)\n', + description: + "

Si la collectivité n'a pas la compétence voirie, alors le score est réduit à 0 et les statuts sont "non concernés".

\n

Si la collectivité a une compétence voirie limitée, alors la collectivité est évaluée sur 1 point (au lieu de 2).

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_2.3.3', + type: 'reduction', + formule: + 'si reponse(voirie_1, voirie_1_b) alors 0.5\nsinon si reponse(voirie_1, voirie_1_c) alors 0/2\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_3.1.1', + type: 'reduction', + formule: + 'si reponse(AOD_elec, OUI) et reponse(AOD_gaz, OUI) et reponse(AOD_chaleur, OUI) alors 1.0 \nsinon si reponse(AOD_elec, NON) et reponse(AOD_gaz, NON) et reponse(AOD_chaleur, NON) alors 2/10 \nsinon si reponse(AOD_elec, NON) et reponse(AOD_gaz, NON) alors 4/10 \nsinon si reponse(AOD_elec, NON) et reponse(AOD_chaleur, NON) alors 3/10 \nsinon si reponse(AOD_gaz, NON) et reponse(AOD_chaleur, NON) alors 3/10 \nsinon si reponse(AOD_elec, NON) ou reponse(AOD_gaz, NON) alors 7/10 \nsinon si reponse(AOD_chaleur, NON) alors 6/10 \n', + description: + "

Pour une collectivité non autorité organisatrice de la distribution d'électricité, le score de la 3.1.1 est réduit de 30 %.

\n

Pour une collectivité non autorité organisatrice de la distribution de gaz, le score de la 3.1.1 est réduit de 30 %.

\n

Pour une collectivité non autorité organisatrice de la distribution de chaleur, le score de la 3.1.1 est réduit de 40 %.

\n

Ces réductions sont cumulables dans la limite de 2 points restants pour prendre en compte la part d’influence dans les instances compétentes et les actions partenariales.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_3.1.2', + type: 'reduction', + formule: + 'si reponse(AOD_elec, NON) et reponse(AOD_gaz, NON) et reponse(AOD_chaleur, NON) alors 0.5\nsinon si reponse(fournisseur_energie, NON) alors 0.8\n', + description: + "

Pour une collectivité non autorité organisatrice de la distribution d'électricité, de gaz et de chaleur, le score de la 3.1.2 est réduit de 50 %.

\n

En l’absence de fournisseurs d’énergie maîtrisés par la collectivité (SEM/régie/exploitants de réseau de chaleur urbain liés à la collectivité par DSP), le score de la 3.1.2 est réduit de 20 % et le statut de la sous-action 3.1.2.2 liée aux actions de la facturation est "non concerné".

\n

La réduction la plus forte prévaut.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_3.1.2.2', + type: 'desactivation', + formule: 'si reponse(fournisseur_energie, NON) alors VRAI\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_3.2.1', + type: 'reduction', + formule: + 'si reponse(recuperation_cogeneration, OUI) et identite(localisation,DOM) alors 10/12\nsinon si reponse(recuperation_cogeneration, NON) alors 2/12\n', + description: + "

Le nombre de point max pour l'action 3.2.1 est de 12 points en Métropole et de 10 points pour les collectivités DOM.

\n

Pour une collectivité avec peu d'activités industrielles adaptées pour la récupération de chaleur fatale et peu de potentiel pour la cogénération voir la micro-cogénération (donc ni de chaufferies ni de consommateurs suffisants en chaleur ni de producteur-consommateur visant l’autoconsommation), le score de la 3.2.1 est réduit à 2 points et les sous-actions 3.2.1.2 et 3.2.1.3 sont automatiquement en statut "Non concerné".

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_3.2.1.2', + type: 'desactivation', + formule: 'reponse(recuperation_cogeneration, NON) \n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_3.2.1.3', + type: 'desactivation', + formule: 'reponse(recuperation_cogeneration, NON) \n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_3.2.2', + type: 'reduction', + formule: 'si identite(localisation,DOM) alors 10/12\n', + description: + "

Le nombre de point max pour l'action 3.2.2 est de 12 points en Métropole et de 10 points pour les collectivités DOM.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_3.2.3', + type: 'reduction', + formule: 'si identite(localisation,DOM) alors 12/8\n', + description: + "

Le nombre de point max pour l'action 3.2.3 est de 8 points en Métropole et de 12 points pour les collectivités DOM.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_3.3.1', + type: 'desactivation', + formule: 'reponse(eau_1, NON) \n', + description: + '

Pour une collectivité sans la compétence eau potable, le score de la 3.3.1 est réduit à 0 point et le statut de la sous-action est "non concernée".

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_3.3.1', + type: 'reduction', + formule: 'si reponse(eau_1, NON) alors 0/6 \n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_3.3.2', + type: 'desactivation', + formule: 'reponse(assainissement_1, NON)\n', + description: + "

Pour une collectivité sans la compétence assainissement collectif, le score de la 3.3.2 est réduit à 0 point et le statut de la sous-action est "non concernée".

\n

En cas d'absence de potentiel de valorisation énergétique (méthanisation ou récupération de chaleur) attestée par une étude portant sur la totalité du périmètre d’assainissement, le score de la 3.3.2 est réduit à 50 %.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_3.3.2', + type: 'reduction', + formule: + 'si reponse(assainissement_1, NON) alors 0/12\nsinon si reponse(assainissement_4, OUI) et reponse(assainissement_4bis, NON) alors 0.5\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_3.3.3', + type: 'reduction', + formule: + 'si identite(type, EPCI) alors max(reponse(assainissement_3), 0.5)\nsinon si identite(type, commune) et reponse(assainissement_1, NON) et reponse(assainissement_2, NON) alors 0.5\n', + description: + '

Pour un EPCI, en cas de compétence "assainissement" partagée ou variable sur le territoire, la réduction de potentielle est proportionnelle à la part des communes ayant délégué leur compétence assainissement, dans la limite de moins 50%. Des actions sont possibles sur d’autres compétences, notamment « gestion des milieux aquatiques et prévention des inondations ».

\n

Pour les communes sans compétence assainissement, le score de la 3.3.3 est réduit de 50 %.

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_3.3.3.3.4', + type: 'desactivation', + formule: 'identite(localisation,DOM)\n', + description: '', + modified_at: '2023-02-20 09:49:29.286703+00', + }, + { + action_id: 'cae_3.3.5', + type: 'score', + formule: 'min(score(cae_1.2.3), score(cae_3.3.5))\n', + description: + "

Pour favoriser la prévention des déchets, la note attribuée à cette action ne peut dépasser celle obtenue dans l'action 1.2.3.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_3.3.5', + type: 'reduction', + formule: + 'si identite(type, commune) et reponse(dechets_2, NON) alors 2/12\nsinon si identite(type, EPCI) et reponse(dechets_2, NON) alors max(reponse(dechets_4),2/12)\n', + description: + "

Pour une commune, la note est réduite à 2 points en l'absence de la compétence traitement des déchets.

\n

Pour un EPCI ayant transféré la compétence traitement des déchets à un syndicat compétent en la matière, la note est réduite proportionnelle à sa participation dans ce syndicat, dans la limite de 2 points restants.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_4.1.1', + type: 'reduction', + formule: 'max(reponse(AOM_2), 0.5) \n', + description: + '

Pour une collectivité non AOM, le score est proportionnel à la participation dans la structure AOM dans la limite de 50 %.

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_4.1.2', + type: 'reduction', + formule: + 'si reponse(TC_1, NON) et reponse(vehiculeCT_1, NON) alors 0.5\nsinon si reponse(TC_1, NON) alors 0.8\nsinon si reponse(vehiculeCT_1, NON) alors 0.7\n', + description: + '

Pour une collectivité dont la desserte des locaux par les transports publics est inenvisageable, le score est diminué de 20 %.

\n

Pour une collectivité ne disposant pas de véhicules, le score est diminué de 30 % et les statuts des sous-actions 4.1.2.1, 4.1.2.3 et 4.1.2.4 sont "non concerné".

\n

Ces 2 réductions sont cumulables.

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_4.1.2.1', + type: 'desactivation', + formule: 'reponse(vehiculeCT_1, NON)\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_4.1.2.3', + type: 'desactivation', + formule: 'reponse(vehiculeCT_1, NON)\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_4.1.2.4', + type: 'desactivation', + formule: 'reponse(vehiculeCT_1, NON)\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_4.2.1', + type: 'reduction', + formule: + 'si identite(type, commune) alors max(reponse(voirie_2), 2/8)\nsinon si identite(type, EPCI) et reponse(voirie_1, voirie_1_b) alors 0.5\nsinon si reponse(voirie_1, voirie_1_c) et reponse(centre_polarite, NON) alors 0.25\nsinon si identite(type, EPCI) et reponse(voirie_1, voirie_1_c) alors 0.5\n', + description: + '

Pour les communes, le score est réduit proportionnelle à la part dans l’EPCI en cas de transfert de la compétence en matière de voirie/stationnement, dans la limite de 2 points pour le pouvoir de police du maire.

\n

Pour les intercommunalités qui n’ont pas la compétence "voirie" ou uniquement sur les voiries et parcs de stationnements communautaires, le score est réduit de 50 %.

\n

En l’absence de compétences voirie et stationnement et de zones de polarités, le score est réduit de 75 %.

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_4.2.2', + type: 'reduction', + formule: + 'si reponse(pouvoir_police, NON) et reponse(trafic, NON) et reponse(voirie_1,voirie_1_b) alors 2/16\nsinon si reponse(pouvoir_police, NON) et reponse(trafic, NON) et reponse(voirie_1,voirie_1_c) alors 2/16\nsinon si reponse(pouvoir_police, NON) et reponse(trafic, NON) alors 4/16\nsinon si reponse(pouvoir_police, NON) et reponse(voirie_1,voirie_1_b) alors 4/16\nsinon si reponse(pouvoir_police, NON) et reponse(voirie_1,voirie_1_c) alors 4/16\nsinon si reponse(voirie_1,voirie_1_b) et reponse(voirie_1,voirie_1_c) alors 4/16\nsinon si reponse(voirie_1,voirie_1_b) et reponse(trafic, NON) alors 4/16\nsinon si reponse(voirie_1,voirie_1_c) et reponse(trafic, NON) alors 4/16\nsinon si reponse(pouvoir_police, NON) ou reponse(voirie_1,voirie_1_b) ou reponse(voirie_1,voirie_1_c) ou reponse\n(trafic, NON) alors 0.5\n', + description: + "

Pour les collectivités ne disposant pas des compétences en matière de circulation/gestion du trafic (pouvoir de police), le score est réduit de 50 %.

\n

Pour les collectivités ne disposant pas de compétences en matière de voirie (création, aménagement, entretien) ou qui possèdent uniquement les voiries et parcs de stationnements communautaires, le score est réduit de 50 %.

\n

Pour les collectivités pour lesquelles il n'y a manifestement pas de potentiel d'action ou de problèmes liés à la vitesse, le score est réduit de 50 %.

\n

Ces réductions sont cumulables, dans la limite de 2 points potentiel restant.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_4.2.3', + type: 'desactivation', + formule: + 'si reponse(AOM_1, NON) et reponse (voirie_1, voirie_1_c) et reponse(centre_polarite, NON) alors VRAI\nsinon si reponse(AOM_1, NON) et reponse (voirie_1, voirie_1_c) et identite(population, moins_de_10000) alors VRAI\n', + description: + "

Pour une collectivité non AOM, sans compétence voirie, de moins de 10 000 habitants ou ne comportant pas de commune ou centre-bourg de plus de 2000 habitants, le score de la 4.2.3 est réduit à 0 et l'action entière est "Non concernée".

\n", + modified_at: '2024-02-21 13:49:11.116461+00', + }, + { + action_id: 'cae_4.2.3', + type: 'reduction', + formule: + 'si reponse(AOM_1, NON) et reponse (voirie_1, voirie_1_c) et reponse(centre_polarite, NON) alors 0\nsinon si reponse(AOM_1, NON) et reponse (voirie_1, voirie_1_c) et identite(population, moins_de_10000) alors 0\nsinon si identite(population, moins_de_10000) et reponse(AOM_1, NON) alors 0.25\nsinon si reponse(centre_polarite, NON) et reponse(AOM_1, NON) alors 0.25\nsinon si identite(population, moins_de_10000) et reponse (voirie_1, voirie_1_c) alors 0.25\nsinon si reponse(centre_polarite, NON) et reponse (voirie_1, voirie_1_c) alors 0.25\nsinon si identite(population, moins_de_10000) ou reponse(centre_polarite, NON) alors 0.5\nsinon si reponse(AOM_1, NON) et reponse (voirie_1, voirie_1_c) alors 0.5 \nsinon si reponse(AOM_1, NON) alors 0.75\nsinon si reponse (voirie_1, voirie_1_c) alors 0.75\n', + description: + '

Pour une collectivité non AOM, le score de la 4.2.3 est réduit de 25 %.

\n

Pour une collectivité sans compétence voirie, le score de la 4.2.3 est réduit de 25 %.

\n

Pour une collectivité de moins de 10 000 habitants ou ne comportant pas de commune ou centre-bourg de plus de 2000 habitants, le score de la 4.2.3 est réduit de 50 %.

\n

Les réductions sont cumulables.

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_4.2.3.5', + type: 'desactivation', + formule: 'reponse(voirie_1, voirie_1_c)\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_4.3.1', + type: 'reduction', + formule: + 'si identite(type, commune) alors max(reponse(voirie_2), 0.5)\nsinon si identite(type, EPCI) et reponse(voirie_1, voirie_1_b) alors 0.5\nsinon si identite(type, EPCI) et reponse(voirie_1, voirie_1_c) alors 0.5\n', + description: + '

Pour les communes, le score de la 4.3.1 est réduit proportionnellement à la part dans l’EPCI compétent en matière de voirie (création, aménagement, entretien) dans la limite de 50 % pour prendre en compte le pouvoir de police du maire.

\n

Pour les intercommunalités qui n’ont la compétence que sur les voiries et parcs de stationnements communautaires, le score est réduit de 50 %.

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_4.3.1.2', + type: 'reduction', + formule: 'si identite(localisation, DOM) alors 3/2\n', + description: + '

Pour une collectivité hors Métropole, la 4.3.1.2 est notée sur 30 % (au lieu de 20 %).

\n', + modified_at: '2023-02-20 09:49:29.286703+00', + }, + { + action_id: 'cae_4.3.1.4', + type: 'reduction', + formule: 'si identite(localisation, DOM) alors 2/3\n', + description: + '

Pour une collectivité hors Métropole, la 4.3.1.2 est notée sur 20 % (au lieu de 30 %).

\n', + modified_at: '2023-02-20 09:49:29.286703+00', + }, + { + action_id: 'cae_4.3.2', + type: 'reduction', + formule: + 'si identite(localisation,DOM) et reponse(cyclable, NON) alors 7/16\nsinon si identite(localisation,DOM) alors 14/16\nsinon si reponse(cyclable, NON) alors 0.5\n', + description: + "

Pour une collectivité disposant de peu de compétences en matière de politique cyclable (ni AOM, ni compétente en matière d’infrastructures vélos, de stationnement vélos, de services associés aux vélos), le score de la 4.3.2 est réduit de 50 %.

\n

Le nombre de point max pour l'action 4.3.2 est de 16 points en Métropole et de 14 points pour les collectivités DOM.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_4.3.2.2', + type: 'reduction', + formule: 'si identite(localisation, DOM) alors 2\n', + description: + '

Pour une collectivité hors Métropole, la 4.3.2.2 est notée sur 10 % (au lieu de 5 %).

\n', + modified_at: '2023-02-20 09:49:29.286703+00', + }, + { + action_id: 'cae_4.3.2.3', + type: 'reduction', + formule: 'si identite(localisation, DOM) alors 2\n', + description: + '

Pour une collectivité hors Métropole, la 4.3.2.3 est notée sur 20 % (au lieu de 10 %).

\n', + modified_at: '2023-02-20 09:49:29.286703+00', + }, + { + action_id: 'cae_4.3.2.6', + type: 'desactivation', + formule: 'identite(localisation, DOM)\n', + description: + '

Pour une collectivité hors Métropole, la 4.3.2.6 est désactivée.

\n', + modified_at: '2023-02-20 09:49:29.286703+00', + }, + { + action_id: 'cae_4.3.2.6', + type: 'reduction', + formule: 'si identite(localisation, DOM) alors 0/14\n', + description: '', + modified_at: '2023-02-20 09:49:29.286703+00', + }, + { + action_id: 'cae_4.3.2.7', + type: 'reduction', + formule: 'si identite(localisation, DOM) alors 2/3\n', + description: + '

Pour une collectivité hors Métropole, la 4.3.2.7 est notée sur 20 % (au lieu de 30 %).

\n', + modified_at: '2023-02-20 09:49:29.286703+00', + }, + { + action_id: 'cae_4.3.3', + type: 'reduction', + formule: + 'si reponse(AOM_1, NON) et reponse(versement_mobilite, NON) alors min(reponse(AOM_2), 0.5)\nsinon si reponse(AOM_1, NON) et reponse(versement_mobilite, OUI) alors reponse(AOM_2)\nsinon si reponse(versement_mobilite, NON) alors 0.5\n', + description: + '

Pour une collectivité non AOM, le score de la 4.3.3 est réduit proportionnellement à la part de la collectivité dans la structure AOM.

\n

Pour les collectivités non concernée par le versement mobilité, le score de la 4.3.3 est réduit de 50 %.

\n

La réduction la plus forte prévaut.

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_4.3.4', + type: 'reduction', + formule: + 'si identite(localisation,DOM) et reponse(AOM_1, NON) alors max(reponse(AOM_2) * 10/8, 5/8)\nsinon si identite(localisation,DOM) alors 10/8\nsinon si reponse(AOM_1, NON) alors max(reponse(AOM_2), 4/8)\n', + description: + "

Pour une collectivité non AOM, le score de la 4.3.4 est réduit proportionnellement à la part de la collectivité dans la structure AOM dans la limite de 50%.

\n

Le nombre de point max pour l'action 4.3.4 est de 8 points en Métropole et de 10 points pour les collectivités DOM.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.1.2', + type: 'reduction', + formule: 'si identite(type, commune) alors 3/4\n', + description: + '

Les communes sont évaluées sur 3 points au lieu de 4.

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.1.2.3.1', + type: 'desactivation', + formule: 'identite(type, commune)\n', + description: '', + modified_at: '2023-02-20 09:49:29.286703+00', + }, + { + action_id: 'cae_6.1.2.3.2', + type: 'desactivation', + formule: 'identite(type, EPCI)\n', + description: '', + modified_at: '2023-02-20 09:49:29.286703+00', + }, + { + action_id: 'cae_6.1.2.4.1', + type: 'desactivation', + formule: 'identite(type, commune)\n', + description: '', + modified_at: '2023-02-20 09:49:29.286703+00', + }, + { + action_id: 'cae_6.1.2.4.2', + type: 'desactivation', + formule: 'identite(type, commune)\n', + description: '', + modified_at: '2023-02-20 09:49:29.286703+00', + }, + { + action_id: 'cae_6.1.2.4.3', + type: 'desactivation', + formule: 'identite(type, commune)\n', + description: '', + modified_at: '2023-02-20 09:49:29.286703+00', + }, + { + action_id: 'cae_6.1.2.4.4', + type: 'desactivation', + formule: 'identite(type, EPCI)\n', + description: '', + modified_at: '2023-02-20 09:49:29.286703+00', + }, + { + action_id: 'cae_6.1.2.4.5', + type: 'desactivation', + formule: 'identite(type, EPCI)\n', + description: '', + modified_at: '2023-02-20 09:49:29.286703+00', + }, + { + action_id: 'cae_6.2.1', + type: 'reduction', + formule: + 'si identite(type, commune) et reponse(habitat_3, NON) alors max(reponse(habitat_2), 2/10) \nsinon si identite(type, commune) et reponse(habitat_3, OUI) alors max(reponse(habitat_2), 2/10) + 1/10 \n', + description: + "

Si la collectivité est une commune, alors la réduction de potentiel est proportionnelle à la part dans l’EPCI compétent en matière de politique du logement et du cadre de vie, dans la limite de 2 points restant minimum.

\n

Si la commune participe au conseil d’administration d'un bailleur social, le potentiel, possiblement réduit est augmenté d'un point sur la 6.2.1

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.2.2', + type: 'reduction', + formule: + 'si identite(type, commune) alors max (reponse(habitat_2),1/6) \n', + description: + "

Si la collectivité est une commune, alors la réduction de potentiel est proportionnelle à la part dans l’EPCI compétent en matière de politique du logement et du cadre de vie, dans la limite d'un point restant minimum.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.2.3', + type: 'reduction', + formule: + 'si identite(type, commune) alors max (reponse(habitat_2),0.5) \n', + description: + '

Si la collectivité est une commune, alors la réduction de potentiel est proportionnelle à la part dans l’EPCI compétent en matière de politique du logement et du cadre de vie, dans la limite de 50 % des points.

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.2.4', + type: 'reduction', + formule: + 'si identite(type, commune) alors max (reponse(dev_eco_2),2/8) \n', + description: + '

Si la collectivité est une commune, alors la réduction de potentiel est proportionnelle à la part dans l’EPCI compétent en matière de développement économique, dans la limite de 2 points de potentiel restant.

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.3.1', + type: 'reduction', + formule: + 'si identite(type, commune) alors max (reponse(dev_eco_2), 2/8) \n', + description: + '

Si la collectivité est une commune, alors la réduction de potentiel est proportionnelle à la part dans l’EPCI compétent en matière de développement économique, dans la limite de 2 points de potentiel restant.

\n

En l’absence de tissu économique propice à l’émergence de projets d’écologie industrielle, le score de la 6.3.1.4 est réduit à 0 et son statut est "non concerné" : les 2 points liés sont affectés à la 6.3.1.3 et la 6.3.1.5.

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.3.1.3', + type: 'reduction', + formule: 'si reponse(dev_eco_4,NON) alors 1.625\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.3.1.4', + type: 'desactivation', + formule: 'reponse(dev_eco_4,NON) \n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.3.1.4', + type: 'reduction', + formule: 'si reponse(dev_eco_4,NON) alors 0\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.3.1.4.4', + type: 'desactivation', + formule: 'identite(localisation, DOM)\n', + description: '', + modified_at: '2022-11-29 13:18:54.370179+00', + }, + { + action_id: 'cae_6.3.1.5', + type: 'reduction', + formule: 'si reponse(dev_eco_4,NON) alors 1.625\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.3.2', + type: 'reduction', + formule: + 'si identite(type, commune) alors max (reponse(tourisme_1),1/4) \nsinon si identite(type, EPCI) et reponse(tourisme_2, NON) alors 1/4 \n', + description: + "

Si la collectivité est une commune, alors la réduction de potentiel est proportionnelle à la part dans l’EPCI compétent en matière de tourisme, dans la limite d'un point de potentiel restant.

\n

Pour les EPCI dont le territoire est très peu touristique (non dotés d’un office du tourisme, d'un syndicat d’initiative ou d'un bureau d’information touristique), le score est réduit à 1 point.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.4.1', + type: 'reduction', + formule: 'si reponse(SAU, OUI) alors 0.5 \n', + description: + '

Pour les collectivités possédant moins de 3 % de surfaces agricoles, le score de la 6.4.1 est réduit de 50 %.

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.4.1.6', + type: 'reduction', + formule: 'si identite(localisation, DOM) alors 4/3\n', + description: + '

La note du référentiel actuel est à 15 %. Pour les collectivités DOM, la note de la sous-action passe à 20 %.

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.4.1.6.4', + type: 'desactivation', + formule: 'identite(localisation, Metropole)\n', + description: + '

Dans les DOM, les mesures spécifiques DOM plan Ecophyto sont déclinées/soutenues localement donc désactivée pour les collectivités en métropole.

\n', + modified_at: '2023-10-27 09:19:16.433221+00', + }, + { + action_id: 'cae_6.4.1.8', + type: 'reduction', + formule: 'si identite(localisation, DOM) alors 2/3\n', + description: + '

La note du référentiel actuel est à 15 %. Pour les collectivités DOM, la note de la sous-action passe à 10 %.

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.4.2', + type: 'reduction', + formule: 'si reponse(foret, OUI) alors 0.5\n', + description: + '

Pour les collectivités possédant moins de 10 % de surfaces agricoles, le score de la 6.4.2 est réduit de 50 %.

\n', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.5.2', + type: 'reduction', + formule: 'si reponse(dev_eco_3, NON) alors 5/6 \n', + description: + "

Pour une collectivité non responsable de la publicité et des enseignes, le statut de la tâche 6.5.2.5 est "non concernée" et le score de la 6.5.2 est réduit d'un point.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.5.2.5', + type: 'desactivation', + formule: 'reponse(dev_eco_3, NON)\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.5.3', + type: 'desactivation', + formule: 'reponse(scolaire_2, NON)\n', + description: + "

Si le territoire de la collectivité ne compte aucun établissement scolaire ou structure d’accueil de jeunes enfants sur le territoire, le score de l'action 6.5.3 est réduit à 0.

\n

Si la collectivité n’est pas en charge des écoles, le score de l'action 6.5.3 est 'reduit de 50 % : le reste du potentiel est maintenu pour la compétence « soutien aux actions de maîtrise de la demande d'énergie » que la collectivité peut prendre de manière facultative.

\n", + modified_at: '2022-10-13 16:34:22.831904+00', + }, + { + action_id: 'cae_6.5.3', + type: 'reduction', + formule: + 'si reponse(scolaire_2, NON) alors 0\nsinon si reponse(scolaire_1, NON) alors 0.5\n', + description: '', + modified_at: '2022-10-13 16:34:22.831904+00', + }, + ], + }; diff --git a/backend/src/personnalisations/models/samples/eci-personnalisation-regles.sample.ts b/backend/src/personnalisations/models/samples/eci-personnalisation-regles.sample.ts new file mode 100644 index 0000000000..8293fe025e --- /dev/null +++ b/backend/src/personnalisations/models/samples/eci-personnalisation-regles.sample.ts @@ -0,0 +1,183 @@ +import { GetPersonnalisationReglesResponseType } from '../get-personnalisation-regles.response'; + +export const eciPersonnalisationRegles: GetPersonnalisationReglesResponseType = + { + regles: [ + { + action_id: 'eci_1.2.2', + type: 'desactivation', + formule: + 'si identite(type, syndicat) alors VRAI\nsinon si reponse(dev_eco_1, NON) alors VRAI\n', + description: + '

Les syndicats ne sont pas concernés par la sous-action 1.2.2.

\n', + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_1.2.3', + type: 'desactivation', + formule: + 'si identite(type, syndicat) alors VRAI\nsinon si reponse(dev_eco_1, NON) alors VRAI\n', + description: + '

Les syndicats ne sont pas concernés par la sous-action 1.2.3.

\n', + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_1.2.4', + type: 'desactivation', + formule: 'si identite(type, syndicat) alors FAUX sinon VRAI\n', + description: + '

Les syndicats ne sont pas concernés par la sous-action 1.2.4.

\n', + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_2.1', + type: 'desactivation', + formule: 'reponse(dechets_3, NON) \n', + description: + "

Pour les collectivités n'ayant pas la compétence "collecte des déchets", le score de l'action 2.1. est réduit à 0 et les statuts sont "non concerné".

\n", + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_2.2', + type: 'desactivation', + formule: 'reponse(dechets_1, NON) \n', + description: + "

Pour les collectivités n'ayant pas la compétence "collecte des déchets", le score de l'action 2.2. est réduit à 0 et les statuts sont "non concerné".

\n", + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_2.3', + type: 'desactivation', + formule: 'reponse(dechets_2, NON) \n', + description: + "

Pour les collectivités n'ayant pas la compétence "traitement des déchets", le score de l'action 2.3. est réduit à 0 et les statuts sont "non concerné".

\n", + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_2.4', + type: 'desactivation', + formule: 'reponse(dechets_1, NON) et reponse(dechets_2, NON)\n', + description: + "

Pour les collectivités n'ayant ni la compétence "collecte des déchets", ni la compétence "traitement des déchets", le score de l'action 2.4. est réduit à 0 et les statuts sont "non concerné".

\n

Pour les collectivités n'ayant pas la compétence "collecte des déchets", les scores des sous-actions 2.4.2 et 2.4.3 sont réduits à 0 et les statuts de ces 2 sous-actions sont "non concerné".

\n

Pour les collectivités n'ayant pas la compétence "traitement des déchets", le score de la sous-action 2.4.4 est réduit à 0 et le statut de cette sous-action est "non concerné".

\n", + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_2.4.2', + type: 'desactivation', + formule: 'reponse(dechets_1, NON) \n', + description: '', + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_2.4.3', + type: 'desactivation', + formule: 'reponse(dechets_1, NON) \n', + description: + '
                                           ˚\n
\n', + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_2.4.4', + type: 'desactivation', + formule: 'reponse(dechets_2, NON) \n', + description: '', + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_3.2.0', + type: 'desactivation', + formule: 'reponse(SPASER, OUI) \n', + description: + '

Les collectivités ayant un montant total annuel des achats inférieur à 50 millions d’euros hors-taxes ne sont pas concernées par le SPASER.

\n', + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_3.4', + type: 'desactivation', + formule: 'reponse(dev_eco_1, NON) \n', + description: + "

Pour les collectivités n'ayant pas la compétence "développement économique", le score de l'action 3.4. est réduit à 0 et les statuts sont "non concerné".

\n

Pour les collectivités ne possédant pas d'établissements de formation initiale et continue sur leur territoire, le score de la sous-action 3.4.2 est réduit à 0 et le statut est "non concerné".

\n", + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_3.4.2', + type: 'desactivation', + formule: 'reponse(formation, NON) \n', + description: '', + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_3.7.1', + type: 'reduction', + formule: 'si identite(population, moins_de_100000) alors 3 \n', + description: + '

La note du référentiel actuel est à 25 %. Pour les collectivités ayant une population inférieure à 100 000 habitants, la note de la sous-action passe à 75 %.

\n', + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_3.7.2', + type: 'reduction', + formule: 'si identite(population, moins_de_100000) alors 1/3\n', + description: + '

La note du référentiel actuel est à 75 %. Pour les collectivités ayant une population inférieure à 100 000 habitants, la note de la sous-action passe à 25 %.

\n', + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_4.1', + type: 'desactivation', + formule: 'reponse(dechets_1, NON) et reponse(dechets_2, NON)\n', + description: + "

Pour les collectivités n'ayant ni la compétence "collecte des déchets", ni la compétence "traitement des déchets", le score de l'action 4.1. est réduit à 0 et les statuts sont "non concerné".

\n", + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_4.2.1', + type: 'desactivation', + formule: 'reponse(dechets_1, NON) ou reponse(REOM, OUI) \n', + description: + "

Pour les collectivités n'ayant ni la compétence "collecte des déchets", ni la compétence "traitement des déchets", le score de l'action 4.2 est réduit à 0 et les statuts sont "non concerné".

\n

Pour les collectivités n'ayant pas la compétence "collecte des déchets", les scores des sous-actions 4.2.1 à 4.2.4 sont réduits à 0 et les statuts de ces 4 sous-actions sont "non concerné".

\n

Pour les collectivités ayant mis en place la redevance d’enlèvement des ordures ménagères (REOM), les scores des sous-action 4.2.1 et 4.2.3 sont réduits à 0 et les statuts de ces 2 sous-actions sont "non concerné".

\n

La sous-action 4.2.5 ne s'adressent qu'aux syndicats de traitement.

\n", + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_4.2.2', + type: 'desactivation', + formule: 'reponse(dechets_1, NON) \n', + description: + "

Pour les collectivités n'ayant ni la compétence "collecte des déchets", ni la compétence "traitement des déchets", le score de l'action 4.2 est réduit à 0 et les statuts sont "non concerné".

\n", + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_4.2.3', + type: 'desactivation', + formule: 'reponse(dechets_1, NON) ou reponse(REOM, OUI) \n', + description: + "

Pour les collectivités n'ayant ni la compétence "collecte des déchets", ni la compétence "traitement des déchets", le score de l'action 4.2 est réduit à 0 et les statuts sont "non concerné".

\n

Pour les collectivités ayant mis en place la redevance d’enlèvement des ordures ménagères (REOM), les scores des sous-action 4.2.1 et 4.2.3 sont réduits à 0 et les statuts de ces 2 sous-actions sont "non concerné".

\n", + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_4.2.4', + type: 'desactivation', + formule: 'reponse(dechets_1, NON) \n', + description: + "

Pour les collectivités n'ayant ni la compétence "collecte des déchets", ni la compétence "traitement des déchets", le score de l'action 4.2 est réduit à 0 et les statuts sont "non concerné".

\n

Pour les collectivités n'ayant pas la compétence "collecte des déchets", les scores des sous-actions 4.2.1 à 4.2.4 sont réduits à 0 et les statuts de ces 4 sous-actions sont "non concerné".

\n", + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_4.2.5', + type: 'desactivation', + formule: + 'si identite(type, syndicat) et reponse(dechets_2, OUI) alors FAUX sinon VRAI\n', + description: + "

Pour les collectivités n'ayant ni la compétence "collecte des déchets", ni la compétence "traitement des déchets", le score de l'action 4.2 est réduit à 0 et les statuts sont "non concerné".

\n

La sous-action 4.2.5 ne s'adressent qu'aux syndicats de traitement.

\n", + modified_at: '2022-09-12 17:13:21.389402+00', + }, + { + action_id: 'eci_4.3', + type: 'desactivation', + formule: 'reponse(dev_eco_1, NON) \n', + description: + "

Pour les collectivités n'ayant pas la compétence "développement économique", le score de l'action 4.3. est réduit à 0 et les statuts sont "non concerné".

\n", + modified_at: '2022-09-12 17:13:21.389402+00', + }, + ], + }; diff --git a/backend/src/personnalisations/personnalisations.module.ts b/backend/src/personnalisations/personnalisations.module.ts new file mode 100644 index 0000000000..0cbbd90cd5 --- /dev/null +++ b/backend/src/personnalisations/personnalisations.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common'; +import { AuthModule } from '../auth/auth.module'; +import { CollectivitesModule } from '../collectivites/collectivites.module'; +import { CommonModule } from '../common/common.module'; +import { PersonnalisationsController } from './controllers/personnalisations.controller'; +import ExpressionParserService from './services/expression-parser.service'; +import PersonnalisationsService from './services/personnalisations-service'; + +@Module({ + imports: [CommonModule, CollectivitesModule, AuthModule], + providers: [ExpressionParserService, PersonnalisationsService], + exports: [ExpressionParserService, PersonnalisationsService], + controllers: [PersonnalisationsController], +}) +export class PersonnalisationsModule {} diff --git a/backend/src/personnalisations/services/expression-parser.service.spec.ts b/backend/src/personnalisations/services/expression-parser.service.spec.ts new file mode 100644 index 0000000000..73a4091ad1 --- /dev/null +++ b/backend/src/personnalisations/services/expression-parser.service.spec.ts @@ -0,0 +1,622 @@ +import { Test } from '@nestjs/testing'; +import { + CollectivitePopulationTypeEnum, + CollectiviteTypeEnum, +} from '../../collectivites/models/collectivite.models'; +import ExpressionParserService from './expression-parser.service'; + +describe('ExpressionParserService', () => { + let expressionParserService: ExpressionParserService; + + beforeEach(async () => { + const moduleRef = await Test.createTestingModule({ + controllers: [ExpressionParserService], + }) + .useMocker((token) => {}) + .compile(); + + expressionParserService = moduleRef.get(ExpressionParserService); + }); + + describe('parseAndEvaluateExpression', () => { + it('si VRAI alors 2', async () => { + expect( + expressionParserService.parseAndEvaluateExpression('si VRAI alors 2'), + ).toBe(2); + }); + + it('si FAUX alors 2', async () => { + expect( + expressionParserService.parseAndEvaluateExpression('si FAUX alors 2'), + ).toBe(null); + }); + + it('si vrai alors 2 sinon si faux alors 4 sinon 8', async () => { + expect( + expressionParserService.parseAndEvaluateExpression( + 'si vrai alors 2 sinon si faux alors 4 sinon 8', + ), + ).toBe(2); + }); + + it('si faux alors 2 sinon si vrai alors 4 sinon 8', async () => { + expect( + expressionParserService.parseAndEvaluateExpression( + 'si faux alors 2 sinon si vrai alors 4 sinon 8', + ), + ).toBe(4); + }); + + it('si faux alors 2 sinon si faux alors 4 sinon 8', async () => { + expect( + expressionParserService.parseAndEvaluateExpression( + 'si faux alors 2 sinon si faux alors 4 sinon 8', + ), + ).toBe(8); + }); + + it('vrai ou faux', async () => { + expect( + expressionParserService.parseAndEvaluateExpression('vrai ou faux'), + ).toBe(true); + }); + + it('vrai ou faux', async () => { + expect( + expressionParserService.parseAndEvaluateExpression('faux ou vrai'), + ).toBe(true); + }); + + it('vrai ou vrai', async () => { + expect( + expressionParserService.parseAndEvaluateExpression('vrai ou vrai'), + ).toBe(true); + }); + + it('faux ou faux', async () => { + expect( + expressionParserService.parseAndEvaluateExpression('faux ou faux'), + ).toBe(false); + }); + + it('2 + 3', async () => { + expect(expressionParserService.parseAndEvaluateExpression('2 + 3')).toBe( + 2 + 3, + ); + }); + + it('3 + 2', async () => { + expect(expressionParserService.parseAndEvaluateExpression('3 + 2')).toBe( + 3 + 2, + ); + }); + + it('2 -3', async () => { + expect(expressionParserService.parseAndEvaluateExpression('2 -3')).toBe( + 2 - 3, + ); + }); + + it('3 - 2', async () => { + expect(expressionParserService.parseAndEvaluateExpression('3 - 2')).toBe( + 3 - 2, + ); + }); + + it('2 * 3', async () => { + expect(expressionParserService.parseAndEvaluateExpression('2 * 3')).toBe( + 2 * 3, + ); + }); + + it('3 * 2', async () => { + expect(expressionParserService.parseAndEvaluateExpression('3 * 2')).toBe( + 3 * 2, + ); + }); + + it('2 / 3', async () => { + expect(expressionParserService.parseAndEvaluateExpression('2 / 3')).toBe( + 2 / 3, + ); + }); + + it('3 / 2', async () => { + expect(expressionParserService.parseAndEvaluateExpression('3 / 2')).toBe( + 3 / 2, + ); + }); + + it('1 + 2 * 3 + 4', async () => { + expect( + expressionParserService.parseAndEvaluateExpression('1 + 2 * 3 + 4'), + ).toBe(1 + 2 * 3 + 4); + }); + + it('1 + 5 - 4', async () => { + expect( + expressionParserService.parseAndEvaluateExpression('1 + 5 - 4'), + ).toBe(1 + 5 - 4); + }); + + it('1 - 2 * 3 + 4', async () => { + expect( + expressionParserService.parseAndEvaluateExpression('1 - 2 * 3 + 4'), + ).toBe(1 - 2 * 3 + 4); + }); + + it('1 + 2 * 3 - 4', async () => { + // Voir https://tomo.dev/en/posts/sample-formula-parser-using-chevrotain/ pour bien gérer ce cas + expect( + expressionParserService.parseAndEvaluateExpression('1 + 2 * 3 - 4'), + ).toBe(1 + 2 * 3 - 4); + }); + + it('3 + 4 * 5 / 2', async () => { + expect( + expressionParserService.parseAndEvaluateExpression('3 + 4 * 5 / 2'), + ).toBe(3 + (4 * 5) / 2); + }); + + it('max(2, 3)', async () => { + expect( + expressionParserService.parseAndEvaluateExpression('max(2, 3)'), + ).toBe(Math.max(2, 3)); + }); + + it('max(3, 2)', async () => { + expect( + expressionParserService.parseAndEvaluateExpression('max(3, 2)'), + ).toBe(Math.max(3, 2)); + }); + + it('min(2, 3)', async () => { + expect( + expressionParserService.parseAndEvaluateExpression('min(2, 3)'), + ).toBe(Math.min(2, 3)); + }); + + it('min(3, 2)', async () => { + expect( + expressionParserService.parseAndEvaluateExpression('min(3, 2)'), + ).toBe(Math.min(3, 2)); + }); + + it('reponse(question_proportion) - 0.2', async () => { + expect( + expressionParserService.parseAndEvaluateExpression( + 'reponse(question_proportion) - 0.2', + { + question_proportion: 1, + }, + ), + ).toBe(0.8); + }); + + it('score(eci_1) - 0.2', async () => { + expect( + expressionParserService.parseAndEvaluateExpression( + 'score(eci_1) - 0.2', + null, + null, + { + eci_1: 1, + }, + ), + ).toBe(0.8); + }); + + it('score(eci_1) - 0.2 without evaluation', async () => { + expect( + expressionParserService.parseAndEvaluateExpression( + 'score(eci_1) - 0.2', + null, + null, + null, + ), + ).toBe('score(eci_1) - 0.2'); + }); + + it('Règle cae_1.2.3', async () => { + /* + Pour une collectivité ne possédant que **partiellement** + les compétences collecte, traitement des déchets et plan de prévention des déchets, + le score de la 1.2.3 est réduit de 25 %. + + Pour une collectivité n'ayant **aucune** + les compétences collecte, traitement des déchets et plan de prévention des déchets, + le score de la 1.2.3 est réduit à 2 points. + */ + + const expression = `si reponse(dechets_1, OUI) et reponse(dechets_2, OUI) et reponse(dechets_3, OUI) alors 1.0 +sinon si reponse(dechets_1, NON) et reponse(dechets_2, NON) et reponse(dechets_3, NON) alors 2/12 +sinon 0.75`; + expect(() => + expressionParserService.parseAndEvaluateExpression(expression), + ).toThrow(new Error('Reponse à la question dechets_1 non trouvée')); + + expect( + expressionParserService.parseAndEvaluateExpression(expression, { + dechets_1: true, + dechets_2: true, + dechets_3: true, + }), + ).toBe(1.0); + + expect( + expressionParserService.parseAndEvaluateExpression(expression, { + dechets_1: false, + dechets_2: true, + dechets_3: true, + }), + ).toBe(0.75); + + expect( + expressionParserService.parseAndEvaluateExpression(expression, { + dechets_1: true, + dechets_2: false, + dechets_3: true, + }), + ).toBe(0.75); + + expect( + expressionParserService.parseAndEvaluateExpression(expression, { + dechets_1: true, + dechets_2: true, + dechets_3: false, + }), + ).toBe(0.75); + + expect( + expressionParserService.parseAndEvaluateExpression(expression, { + dechets_1: true, + dechets_2: false, + dechets_3: false, + }), + ).toBe(0.75); + + expect( + expressionParserService.parseAndEvaluateExpression(expression, { + dechets_1: false, + dechets_2: false, + dechets_3: true, + }), + ).toBe(0.75); + + expect( + expressionParserService.parseAndEvaluateExpression(expression, { + dechets_1: false, + dechets_2: false, + dechets_3: false, + }), + ).toBe(2 / 12); + }); + + it('Règle cae_3.1.1', async () => { + /* + Pour une collectivité non autorité organisatrice de la distribution d'électricité, + le score de la 3.1.1 est réduit de 30 %. + Pour une collectivité non autorité organisatrice de la distribution de gaz, + le score de la 3.1.1 est réduit de 30 %. + Pour une collectivité non autorité organisatrice de la distribution de chaleur, + le score de la 3.1.1 est réduit de 40 %. + Ces réductions sont cumulables dans la limite de 2 points restants + pour prendre en compte la part d’influence dans les instances compétentes et les actions partenariales. + */ + const expression = `si reponse(AOD_elec, OUI) et reponse(AOD_gaz, OUI) et reponse(AOD_chaleur, OUI) alors 1.0 +sinon si reponse(AOD_elec, NON) et reponse(AOD_gaz, NON) et reponse(AOD_chaleur, NON) alors 2/10 +sinon si reponse(AOD_elec, NON) et reponse(AOD_gaz, NON) alors 4/10 +sinon si reponse(AOD_elec, NON) et reponse(AOD_chaleur, NON) alors 3/10 +sinon si reponse(AOD_gaz, NON) et reponse(AOD_chaleur, NON) alors 3/10 +sinon si reponse(AOD_elec, NON) ou reponse(AOD_gaz, NON) alors 7/10 +sinon si reponse(AOD_chaleur, NON) alors 6/10`; + + expect( + expressionParserService.parseAndEvaluateExpression(expression, { + AOD_elec: true, + AOD_gaz: true, + AOD_chaleur: true, + }), + ).toBe(1.0); + + // Electricité seulement + expect( + expressionParserService.parseAndEvaluateExpression(expression, { + AOD_elec: true, + AOD_gaz: false, + AOD_chaleur: false, + }), + ).toBe(3 / 10); + + // Aucun + expect( + expressionParserService.parseAndEvaluateExpression(expression, { + AOD_elec: false, + AOD_gaz: false, + AOD_chaleur: false, + }), + ).toBe(2 / 10); + + // Gaz seulement + expect( + expressionParserService.parseAndEvaluateExpression(expression, { + AOD_elec: false, + AOD_gaz: true, + AOD_chaleur: false, + }), + ).toBe(3 / 10); + + // Chaleur seulement + expect( + expressionParserService.parseAndEvaluateExpression(expression, { + AOD_elec: false, + AOD_gaz: false, + AOD_chaleur: true, + }), + ).toBe(4 / 10); + + // Chaleur et gaz + expect( + expressionParserService.parseAndEvaluateExpression(expression, { + AOD_elec: false, + AOD_gaz: true, + AOD_chaleur: true, + }), + ).toBe(7 / 10); + + // Gaz et elec + expect( + expressionParserService.parseAndEvaluateExpression(expression, { + AOD_elec: true, + AOD_gaz: true, + AOD_chaleur: false, + }), + ).toBe(6 / 10); + + // Chaleur et elec + expect( + expressionParserService.parseAndEvaluateExpression(expression, { + AOD_elec: true, + AOD_gaz: false, + AOD_chaleur: true, + }), + ).toBe(7 / 10); + }); + + it('Règle cae_3.3.3', async () => { + /* + Pour un EPCI, en cas de compétence "assainissement" partagée ou variable sur le territoire, + la réduction de potentielle est proportionnelle à la part des communes ayant délégué leur compétence assainissement, + dans la limite de moins 50%. + + Pour les communes sans compétence assainissement, + le score de la 3.3.3 est réduit de 50 %. + */ + const expression = `si identite(type, EPCI) alors max(reponse(assainissement_3), 0.5) +sinon si identite(type, commune) et reponse(assainissement_1, NON) et reponse(assainissement_2, NON) alors 0.5`; + + // Une commune avec toutes les compétences + expect( + expressionParserService.parseAndEvaluateExpression( + expression, + { + assainissement_1: true, + assainissement_2: true, + assainissement_3: 0.7, + }, + { + type: CollectiviteTypeEnum.COMMUNE, + soustype: null, + population_tags: [CollectivitePopulationTypeEnum.MOINS_DE_20000], + drom: false, + }, + ), + ).toBe(null); + + // Une commune sans aucune compétence + expect( + expressionParserService.parseAndEvaluateExpression( + expression, + { + assainissement_1: false, + assainissement_2: false, + assainissement_3: 0.7, + }, + { + type: CollectiviteTypeEnum.COMMUNE, + soustype: null, + population_tags: [CollectivitePopulationTypeEnum.MOINS_DE_20000], + drom: false, + }, + ), + ).toBe(0.5); + + // Un epci avec une part déléguée à 70% + expect( + expressionParserService.parseAndEvaluateExpression( + expression, + { + assainissement_1: false, + assainissement_2: false, + assainissement_3: 0.7, + }, + { + type: CollectiviteTypeEnum.EPCI, + soustype: null, + population_tags: [CollectivitePopulationTypeEnum.MOINS_DE_50000], + drom: false, + }, + ), + ).toBe(0.7); + + // Un epci avec une part déléguée à 30% + expect( + expressionParserService.parseAndEvaluateExpression( + expression, + { + assainissement_1: false, + assainissement_2: false, + assainissement_3: 0.3, + }, + { + type: CollectiviteTypeEnum.EPCI, + soustype: null, + population_tags: [CollectivitePopulationTypeEnum.MOINS_DE_50000], + drom: false, + }, + ), + ).toBe(0.5); + }); + + it('Règle cae_3.3.5', async () => { + /* + Pour une commune, la note est réduite à 2 points. + Pour un EPCI ayant transféré la compétence traitement des déchets à un syndicat compétent en la matière, la note est réduite proportionnelle à sa participation dans cet syndicat, dans la limite de 2 points restants. + Pour favoriser la prévention des déchets, la note attribuée à cette action ne peut dépasser celle obtenue dans l'action 1.2.3. + */ + const expression = `si identite(type, commune) et reponse(dechets_2, NON) alors min(score(cae_1.2.3), 2/12) +sinon si identite (type,EPCI) et reponse(dechets_2, OUI) alors min(score(cae_1.2.3), 1.0) +sinon si identite(type, EPCI) et reponse(dechets_2, NON) alors min(score(cae_1.2.3), max(reponse(dechets_4), 2/12)) +`; + + // une commune avec la compétence déchets + expect( + expressionParserService.parseAndEvaluateExpression( + expression, + { + dechets_2: true, + }, + { + type: CollectiviteTypeEnum.COMMUNE, + soustype: null, + population_tags: [CollectivitePopulationTypeEnum.MOINS_DE_20000], + drom: false, + }, + ), + ).toBe(null); + + // une commune sans la compétence déchets + expect( + expressionParserService.parseAndEvaluateExpression( + expression, + { + dechets_2: false, + }, + { + type: CollectiviteTypeEnum.COMMUNE, + soustype: null, + population_tags: [CollectivitePopulationTypeEnum.MOINS_DE_20000], + drom: false, + }, + ), + ).toBe('min(score(cae_1.2.3), 0.16666666666666666)'); + + // un epci avec la compétence déchets + expect( + expressionParserService.parseAndEvaluateExpression( + expression, + { + dechets_2: true, + }, + { + type: CollectiviteTypeEnum.EPCI, + soustype: null, + population_tags: [CollectivitePopulationTypeEnum.MOINS_DE_50000], + drom: false, + }, + ), + ).toBe('min(score(cae_1.2.3), 1)'); + + // un epci sans la compétence déchets, si réponse à dechets_4 + expect( + expressionParserService.parseAndEvaluateExpression( + expression, + { + dechets_2: false, + dechets_4: 1 / 12, + }, + { + type: CollectiviteTypeEnum.EPCI, + soustype: null, + population_tags: [CollectivitePopulationTypeEnum.MOINS_DE_50000], + drom: false, + }, + ), + ).toBe('min(score(cae_1.2.3), 0.16666666666666666)'); + }); + + it('Règle cae_3.2.2', async () => { + /* + Le nombre de point max pour l''action 3.2.2 est de 12 points en Métropole et de 10 points pour les collectivités DOM. + */ + const expression = `si identite(localisation,DOM) alors 10/12`; + + // une commune en métropole + expect( + expressionParserService.parseAndEvaluateExpression( + expression, + undefined, + { + type: CollectiviteTypeEnum.COMMUNE, + soustype: null, + population_tags: [CollectivitePopulationTypeEnum.MOINS_DE_20000], + drom: false, + }, + ), + ).toBe(null); + + // une commune dans les DOM + expect( + expressionParserService.parseAndEvaluateExpression( + expression, + undefined, + { + type: CollectiviteTypeEnum.COMMUNE, + soustype: null, + population_tags: [CollectivitePopulationTypeEnum.MOINS_DE_20000], + drom: true, + }, + ), + ).toBe(10 / 12); + }); + + it('Règle cae_6.3.1', async () => { + /* + Si la collectivité est une commune, alors la réduction de potentiel est proportionnelle à la part dans l’EPCI compétent en matière de développement économique, dans la limite de 2 points de potentiel restant.

\n

En l’absence de tissu économique propice à l’émergence de projets d’écologie industrielle, le score de la 6.3.1.4 est réduit à 0 et son statut est "non concerné" : les 2 points liés sont affectés à la 6.3.1.3 et la 6.3.1.5. + */ + const expression = `si identite(type, commune) alors max (reponse(dev_eco_2), 2/8) \n`; + + // une commune en métropole + expect( + expressionParserService.parseAndEvaluateExpression( + expression, + { + dev_eco_2: 0, + }, + { + type: CollectiviteTypeEnum.COMMUNE, + soustype: null, + population_tags: [CollectivitePopulationTypeEnum.MOINS_DE_20000], + drom: false, + }, + ), + ).toBe(2 / 8); + + // Pas de réponse à dev_eco_2 + expect( + expressionParserService.parseAndEvaluateExpression( + expression, + { + dev_eco_4: false, + }, + { + type: CollectiviteTypeEnum.COMMUNE, + soustype: null, + population_tags: [CollectivitePopulationTypeEnum.MOINS_DE_20000], + drom: false, + }, + ), + ).toBe(null); + }); + }); +}); diff --git a/backend/src/personnalisations/services/expression-parser.service.ts b/backend/src/personnalisations/services/expression-parser.service.ts new file mode 100644 index 0000000000..01fe43d0f4 --- /dev/null +++ b/backend/src/personnalisations/services/expression-parser.service.ts @@ -0,0 +1,568 @@ +import { HttpException, Injectable, Logger } from '@nestjs/common'; +import { createToken, CstParser, Lexer, tokenMatcher } from 'chevrotain'; +import * as _ from 'lodash'; +import { IdentiteCollectivite } from '../../collectivites/models/collectivite.models'; + +// Define all the tokens used in the grammar +const VRAI = createToken({ name: 'VRAI', pattern: /VRAI/ }); +const FAUX = createToken({ name: 'FAUX', pattern: /FAUX/ }); +const vrai = createToken({ name: 'vrai', pattern: /vrai/ }); +const faux = createToken({ name: 'faux', pattern: /faux/ }); +const OUI = createToken({ name: 'OUI', pattern: /OUI/ }); +const NON = createToken({ name: 'NON', pattern: /NON/ }); +const oui = createToken({ name: 'oui', pattern: /oui/ }); +const non = createToken({ name: 'non', pattern: /non/ }); + +const CNAME = createToken({ + name: 'CNAME', + pattern: /[a-zA-Z_][a-zA-Z_0-9\.]*/, +}); +const NUMBER = createToken({ name: 'NUMBER', pattern: /-?\d+(\.\d+)?/ }); + +const SI = createToken({ name: 'SI', pattern: /si/ }); +const ALORS = createToken({ name: 'ALORS', pattern: /alors/ }); +const SINON = createToken({ name: 'SINON', pattern: /sinon/ }); + +const IDENTITE = createToken({ name: 'IDENTITE', pattern: /identite/ }); +const REPONSE = createToken({ name: 'REPONSE', pattern: /reponse/ }); +const SCORE = createToken({ name: 'SCORE', pattern: /score/ }); +const MIN = createToken({ name: 'MIN', pattern: /min/ }); +const MAX = createToken({ name: 'MAX', pattern: /max/ }); + +const OU = createToken({ name: 'OU', pattern: /ou/ }); +const ET = createToken({ name: 'ET', pattern: /et/ }); + +const ADDITION_OPERATOR = createToken({ + name: 'ADDITION_OPERATOR', + pattern: Lexer.NA, +}); +const PLUS = createToken({ + name: 'PLUS', + pattern: /\+/, + categories: ADDITION_OPERATOR, +}); +const MINUS = createToken({ + name: 'MINUS', + pattern: /-/, + categories: ADDITION_OPERATOR, +}); + +const MULTIPLICATION_OPERATOR = createToken({ + name: 'MULTIPLICATION_OPERATOR', + pattern: Lexer.NA, +}); +const MULT = createToken({ + name: 'MULT', + pattern: /\*/, + categories: MULTIPLICATION_OPERATOR, +}); +const DIV = createToken({ + name: 'DIV', + pattern: /\//, + categories: MULTIPLICATION_OPERATOR, +}); + +const LPAR = createToken({ name: 'LPAR', pattern: /\(/ }); +const RPAR = createToken({ name: 'RPAR', pattern: /\)/ }); +const COMMA = createToken({ name: 'COMMA', pattern: /,/ }); + +// Whitespace to be skipped +const WS = createToken({ name: 'WS', pattern: /\s+/, group: Lexer.SKIPPED }); + +// All tokens +const allTokens = [ + WS, + VRAI, + FAUX, + vrai, + faux, + OUI, + NON, + oui, + non, + SINON, + SI, + ALORS, + IDENTITE, + REPONSE, + SCORE, + MIN, + MAX, + OU, + ET, + PLUS, + MINUS, + ADDITION_OPERATOR, + MULT, + DIV, + MULTIPLICATION_OPERATOR, + LPAR, + RPAR, + COMMA, + CNAME, + NUMBER, +]; + +const exprLexer = new Lexer(allTokens); + +class ExprParser extends CstParser { + constructor() { + super(allTokens); + this.performSelfAnalysis(); + } + + // Statement + public statement = this.RULE('statement', () => { + this.OR([ + { ALT: () => this.SUBRULE(this.if_statement) }, + { ALT: () => this.SUBRULE(this.expression) }, + ]); + }); + + // If Statement + private if_statement = this.RULE('if_statement', () => { + this.CONSUME(SI); + this.SUBRULE(this.expression); + this.CONSUME(ALORS); + this.SUBRULE(this.statement); + this.OPTION(() => { + this.CONSUME(SINON); + this.SUBRULE2(this.statement); + }); + }); + + // Expression + private expression = this.RULE('expression', () => { + this.SUBRULE(this.logic_or); + }); + + // Logic OR + private logic_or = this.RULE('logic_or', () => { + this.SUBRULE(this.logic_and); + this.MANY(() => { + this.CONSUME(OU); + this.SUBRULE2(this.logic_and); + }); + }); + + // Logic AND + private logic_and = this.RULE('logic_and', () => { + this.SUBRULE(this.term); + this.MANY(() => { + this.CONSUME(ET); + this.SUBRULE2(this.term); + }); + }); + + // Term + private term = this.RULE('term', () => { + this.SUBRULE(this.factor); + this.MANY(() => { + // consuming 'AdditionOperator' will consume either Plus or Minus as they are subclasses of AdditionOperator + this.CONSUME(ADDITION_OPERATOR); + this.SUBRULE2(this.factor); + }); + }); + + // Factor + private factor = this.RULE('factor', () => { + this.SUBRULE(this.unary); + this.MANY(() => { + this.CONSUME(MULTIPLICATION_OPERATOR); + this.SUBRULE2(this.unary); + }); + }); + + // Unary + private unary = this.RULE('unary', () => { + this.SUBRULE(this.call); + }); + + private call = this.RULE('call', () => { + this.OR([ + { ALT: () => this.SUBRULE(this.identite) }, + { ALT: () => this.SUBRULE(this.primary) }, + { ALT: () => this.SUBRULE(this.reponse) }, + { ALT: () => this.SUBRULE(this.min) }, + { ALT: () => this.SUBRULE(this.max) }, + { ALT: () => this.SUBRULE(this.score) }, + ]); + }); + + private identite = this.RULE('identite', () => { + this.CONSUME(IDENTITE); + this.CONSUME(LPAR); + this.SUBRULE(this.identifier); + this.CONSUME(COMMA); + this.SUBRULE2(this.primary); + this.CONSUME(RPAR); + }); + + private reponse = this.RULE('reponse', () => { + this.CONSUME(REPONSE); + this.CONSUME(LPAR); + this.SUBRULE(this.identifier); + this.OPTION(() => { + this.CONSUME(COMMA); + this.SUBRULE2(this.primary); + }); + this.CONSUME(RPAR); + }); + + private min = this.RULE('min', () => { + this.CONSUME(MIN); + this.CONSUME(LPAR); + this.SUBRULE(this.term); + this.CONSUME(COMMA); + this.SUBRULE2(this.term); + this.CONSUME(RPAR); + }); + + private max = this.RULE('max', () => { + this.CONSUME(MAX); + this.CONSUME(LPAR); + this.SUBRULE(this.term); + this.CONSUME(COMMA); + this.SUBRULE2(this.term); + this.CONSUME(RPAR); + }); + + private score = this.RULE('score', () => { + this.CONSUME(SCORE); + this.CONSUME(LPAR); + this.SUBRULE(this.identifier); + this.CONSUME(RPAR); + }); + + // Primary + private primary = this.RULE('primary', () => { + this.OR([ + { ALT: () => this.CONSUME(VRAI) }, + { ALT: () => this.CONSUME(FAUX) }, + { ALT: () => this.CONSUME(vrai) }, + { ALT: () => this.CONSUME(faux) }, + { ALT: () => this.CONSUME(OUI) }, + { ALT: () => this.CONSUME(NON) }, + { ALT: () => this.CONSUME(oui) }, + { ALT: () => this.CONSUME(non) }, + { ALT: () => this.CONSUME(CNAME) }, + { ALT: () => this.CONSUME(NUMBER) }, + ]); + }); + + // Identifier + private identifier = this.RULE('identifier', () => { + this.CONSUME(CNAME); + }); +} + +const parser = new ExprParser(); + +const BaseCSTVisitor = parser.getBaseCstVisitorConstructor(); + +class CollectiviteExpressionVisitor extends BaseCSTVisitor { + reponses: { [key: string]: boolean | number | string | null } | null = null; + identiteCollectivite: IdentiteCollectivite | null = null; + scores: { [key: string]: number } | null = null; + + constructor() { + super(); + this.validateVisitor(); + } + + statement(ctx: any) { + if (ctx.if_statement) { + return this.visit(ctx.if_statement); + } else { + return this.visit(ctx.expression); + } + } + + if_statement(ctx: any) { + const condition = this.visit(ctx.expression); + const thenBranch = this.visit(ctx.statement[0]); + const elseBranch = ctx.statement[1] ? this.visit(ctx.statement[1]) : null; + + if (condition) { + return thenBranch; + } else { + return elseBranch; + } + } + + expression(ctx: any) { + return this.visit(ctx.logic_or); + } + + logic_or(ctx: any) { + let result = this.visit(ctx.logic_and[0]); + for (let i = 1; i < ctx.logic_and.length; i++) { + const nextValue = this.visit(ctx.logic_and[i]); + result = result || nextValue; + } + return result; + } + + logic_and(ctx: any) { + let result = this.visit(ctx.term[0]); + for (let i = 1; i < ctx.term.length; i++) { + const nextValue = this.visit(ctx.term[i]); + result = result && nextValue; + } + return result; + } + + term(ctx: any) { + let result = this.visit(ctx.factor[0]); + for (let i = 1; i < ctx.factor.length; i++) { + const rightOperand = this.visit(ctx.factor[i]); + const operator = ctx.ADDITION_OPERATOR[i - 1]; + + if (tokenMatcher(operator, PLUS)) { + if (typeof result === 'string' || typeof rightOperand === 'string') { + result = `${result} - ${rightOperand}`; + } else if (_.isNil(result) || _.isNil(rightOperand)) { + result = null; + } else { + result += rightOperand; + } + } else { + if (typeof result === 'string' || typeof rightOperand === 'string') { + result = `${result} - ${rightOperand}`; + } else if (_.isNil(result) || _.isNil(rightOperand)) { + result = null; + } else { + result -= rightOperand; + } + } + } + return result; + } + + factor(ctx: any) { + let result = this.visit(ctx.unary[0]); + for (let i = 1; i < ctx.unary.length; i++) { + const rightOperand = this.visit(ctx.unary[i]); + const operator = ctx.MULTIPLICATION_OPERATOR + ? ctx.MULTIPLICATION_OPERATOR[i - 1] + : null; + if (operator) { + if (tokenMatcher(operator, MULT)) { + if (typeof result === 'string' || typeof rightOperand === 'string') { + result = `${result} * ${rightOperand}`; + } else if (_.isNil(result) || _.isNil(rightOperand)) { + result = null; + } else { + result *= rightOperand; + } + } else if (tokenMatcher(operator, DIV)) { + if (typeof result === 'string' || typeof rightOperand === 'string') { + result = `${result} / ${rightOperand}`; + } else if (_.isNil(result) || _.isNil(rightOperand)) { + result = null; + } else { + result /= rightOperand; + } + } + } + } + return result; + } + + unary(ctx: any) { + return this.visit(ctx.call); + } + + call(ctx: any) { + if (ctx.primary) { + return this.visit(ctx.primary); + } else if (ctx.identite) { + return this.visit(ctx.identite); + } else if (ctx.reponse) { + return this.visit(ctx.reponse); + } else if (ctx.score) { + return this.visit(ctx.score); + } else if (ctx.min) { + return this.visit(ctx.min); + } else if (ctx.max) { + return this.visit(ctx.max); + } + } + + primary(ctx: any) { + if (ctx.VRAI) { + return true; + } else if (ctx.FAUX) { + return false; + } else if (ctx.vrai) { + return true; + } else if (ctx.faux) { + return false; + } else if (ctx.OUI) { + return true; + } else if (ctx.NON) { + return false; + } else if (ctx.oui) { + return true; + } else if (ctx.non) { + return false; + } else if (ctx.CNAME) { + return ctx.CNAME[0].image; // Assuming string identifier + } else if (ctx.NUMBER) { + return parseFloat(ctx.NUMBER[0].image); + } + } + + identifier(ctx: any) { + return ctx.CNAME[0].image; + } + + // Implementing custom logic for functions + min(ctx: any) { + const term1 = this.visit(ctx.term[0]); + const term2 = this.visit(ctx.term[1]); + if (typeof term1 === 'string' || typeof term2 === 'string') { + // TODO: done in order to verify unit test, check if needed + return `min(${term1}, ${term2})`; + } else if (_.isNil(term1) || _.isNil(term2)) { + return null; + } else { + return Math.min(term1, term2); + } + } + + max(ctx: any) { + const term1 = this.visit(ctx.term[0]); + const term2 = this.visit(ctx.term[1]); + if (typeof term1 === 'string' || typeof term2 === 'string') { + // TODO: done in order to verify unit test, check if needed + return `max(${term1}, ${term2})`; + } else if (_.isNil(term1) || _.isNil(term2)) { + return null; + } else { + return Math.max(term1, term2); + } + } + + identite(ctx: any) { + // Règles historiques exprimées avec ces identifiants + const identifier = this.visit(ctx.identifier) as + | 'type' + | 'population' + | 'localisation'; + const primary = this.visit(ctx.primary); + if (!this.identiteCollectivite) { + throw new Error( + `Information ${identifier} d'identité de la commune non trouvée`, + ); + } + if (identifier === 'type') { + return ( + this.identiteCollectivite.type === primary || + this.identiteCollectivite.soustype === primary + ); + } else if (identifier === 'population') { + return this.identiteCollectivite.population_tags.includes(primary); + } else if (identifier === 'localisation') { + const drom = primary === 'DOM'; + return this.identiteCollectivite.drom === drom; + } + } + + reponse(ctx: any) { + const reponseId = this.visit(ctx.identifier); + + if (ctx.primary) { + const reponseVal = this.visit(ctx.primary); + if (!this.reponses) { + throw new Error(`Reponse à la question ${reponseId} non trouvée`); + } + return this.reponses && this.reponses[reponseId] === reponseVal; + + /* +(question_id, compared_choix_id) = (node[0][1], node[1][1]) + if question_id not in self.questions: + raise FormuleError(f"Id de question inconnue: {question_id}.") + question_type = self.questions[question_id].type + if question_type == "proportion": + raise FormuleError( + f"La question d'id {question_id} est de type proportion, donc la fonction réponse n'attend qu'un argument." + ) + allowed_choix_ids = ( + [choix.id for choix in self.questions[question_id].choix or []] + if question_type == "choix" + else ["OUI", "NON"] + ) + if compared_choix_id not in allowed_choix_ids: + raise FormuleError( + f"L'id de choix {compared_choix_id} est inconnu pour la question {question_id}. Choix possibles : {', '.join(allowed_choix_ids)}" + ) + return bool, "reponse" + */ + } else { + return this.reponses ? this.reponses[reponseId] : null; + + /** + * question_id = node[0][1] + if question_id not in self.questions: + raise FormuleError(f"Id de question inconnue: {question_id}.") + question_type = self.questions[question_id].type + if question_type in ["choix", "binaire"]: + raise FormuleError( + f"La question d'id {question_id} est de type {question_type}, donc la fonction réponse attend deux arguments." + ) + return float, "reponse" + + */ + } + } + + score(ctx: any) { + const referentielId = this.visit(ctx.identifier); + if (this.scores) { + if (referentielId in this.scores) { + return this.scores[referentielId]; + } else { + return null; + } + } else { + // TODO: done in order to verify unit test, check if needed + return `score(${referentielId})`; + } + } +} +const visitor = new CollectiviteExpressionVisitor(); + +@Injectable() +export default class ExpressionParserService { + private readonly logger = new Logger(ExpressionParserService.name); + + constructor() {} + + parseAndEvaluateExpression( + inputText: string, + reponses: { [key: string]: boolean | number | string | null } | null = null, + identiteCollectivite: IdentiteCollectivite | null = null, + scores: { [key: string]: number } | null = null, + ): number | boolean | string | null { + const lexingResult = exprLexer.tokenize(inputText); + + parser.input = lexingResult.tokens; + const cst = parser.statement(); + + if (parser.errors.length > 0) { + this.logger.error( + `Parsing errors detected: ${JSON.stringify(parser.errors)}`, + ); + throw new HttpException('Invalid expression', 500, { + cause: parser.errors, + }); + } else { + visitor.reponses = reponses; + visitor.identiteCollectivite = identiteCollectivite; + visitor.scores = scores; + const result = visitor.visit(cst); + return result; + } + } +} diff --git a/backend/src/personnalisations/services/personnalisations-service.ts b/backend/src/personnalisations/services/personnalisations-service.ts new file mode 100644 index 0000000000..a254d7739f --- /dev/null +++ b/backend/src/personnalisations/services/personnalisations-service.ts @@ -0,0 +1,226 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { and, asc, desc, eq, like, lte, SQL, SQLWrapper } from 'drizzle-orm'; +import { NiveauAcces, SupabaseJwtPayload } from '../../auth/models/auth.models'; +import { AuthService } from '../../auth/services/auth.service'; +import { CollectiviteAvecType, IdentiteCollectivite } from '../../collectivites/models/collectivite.models'; +import CollectivitesService from '../../collectivites/services/collectivites.service'; +import DatabaseService from '../../common/services/database.service'; +import { GetPersonnalisationConsequencesRequestType } from '../models/get-personnalisation-consequences.request'; +import { GetPersonnalitionConsequencesResponseType } from '../models/get-personnalisation-consequences.response'; +import { GetPersonnalisationReglesResponseType } from '../models/get-personnalisation-regles.response'; +import { GetPersonnalisationReponsesResponseType } from '../models/get-personnalisation-reponses.response'; +import { historiqueReponseBinaireTable } from '../models/historique-reponse-binaire.table'; +import { historiqueReponseChoixTable } from '../models/historique-reponse-choix.table'; +import { historiqueReponseProportionTable } from '../models/historique-reponse-proportion.table'; +import { + personnalisationRegleTable, + PersonnalisationRegleType, +} from '../models/personnalisation-regle.table'; +import { reponseBinaireTable } from '../models/reponse-binaire.table'; +import { reponseChoixTable } from '../models/reponse-choix.table'; +import { reponseProportionTable } from '../models/reponse-proportion.table'; +import ExpressionParserService from './expression-parser.service'; + +export type ReponseTables = + | typeof reponseBinaireTable + | typeof reponseChoixTable + | typeof reponseProportionTable + | typeof historiqueReponseBinaireTable + | typeof historiqueReponseChoixTable + | typeof historiqueReponseProportionTable; + +@Injectable() +export default class PersonnalisationsService { + private readonly logger = new Logger(PersonnalisationsService.name); + + constructor( + private readonly databaseService: DatabaseService, + private readonly collectivitesService: CollectivitesService, + private readonly expressionParserService: ExpressionParserService, + private readonly authService: AuthService + ) {} + + async getPersonnalisationReponsesForTable( + table: ReponseTables, + collectiviteId: number, + reponsesDate?: string, + ) { + const reponsesConditions: (SQLWrapper | SQL)[] = [ + eq(table.collectivite_id, collectiviteId), + ]; + if (reponsesDate) { + reponsesConditions.push(lte(table.modified_at, reponsesDate)); + } + const reponses = await this.databaseService.db + .select() + .from(table) + .where(and(...reponsesConditions)) + .orderBy(desc(table.modified_at)); + this.logger.log( + `${reponses.length} reponses (table) pour la collectivite ${collectiviteId} et la date ${reponsesDate}`, + ); + return reponses; + } + + async fillPersonnalisationReponsesForTable( + table: ReponseTables, + collectiviteId: number, + reponses: GetPersonnalisationReponsesResponseType, + reponsesDate?: string, + ): Promise { + const reponsesTable = await this.getPersonnalisationReponsesForTable( + table, + collectiviteId, + reponsesDate, + ); + reponsesTable.forEach((row) => { + // Si la question est déjà dans les réponses, on ne la remplace pas (ordonné par date de modification décroissante) + if (!(row.question_id in reponses)) { + reponses[row.question_id] = row.reponse; + } + }); + } + + async getPersonnalisationReponses( + collectiviteId: number, + reponsesDate?: string, + tokenInfo?: SupabaseJwtPayload, + ): Promise { + const reponses: GetPersonnalisationReponsesResponseType = {}; + + this.logger.log( + `Getting responses for collectivite ${collectiviteId} and date ${reponsesDate}`, + ); + + // Seulement les personnes ayant l'accès en lecture à la collectivité peuvent voir les réponses historiques + if (reponsesDate && tokenInfo) { + await this.authService.verifieAccesAuxCollectivites( + tokenInfo, + [collectiviteId], + NiveauAcces.LECTURE + ); + } + + // reponse choix + await this.fillPersonnalisationReponsesForTable( + reponsesDate ? historiqueReponseChoixTable : reponseChoixTable, + collectiviteId, + reponses, + reponsesDate, + ); + + // reponse binaires + await this.fillPersonnalisationReponsesForTable( + reponsesDate ? historiqueReponseBinaireTable : reponseBinaireTable, + collectiviteId, + reponses, + reponsesDate, + ); + + // reponses proportion + await this.fillPersonnalisationReponsesForTable( + reponsesDate ? historiqueReponseProportionTable : reponseProportionTable, + collectiviteId, + reponses, + reponsesDate, + ); + + return reponses; + } + + async getPersonnalisationRegles( + referentiel?: string, + ): Promise { + const reglesQuery = this.databaseService.db + .select() + .from(personnalisationRegleTable); + + let regles: PersonnalisationRegleType[]; + if (referentiel) { + // TODO: add referentiel to personnalisationTable + regles = await reglesQuery + .where(like(personnalisationRegleTable.action_id, `${referentiel}%`)) + .orderBy(asc(personnalisationRegleTable.action_id)); + } else { + regles = await reglesQuery.orderBy( + asc(personnalisationRegleTable.action_id), + ); + } + + this.logger.log(`${regles.length} regles trouvees`); + return { regles }; + } + + async getPersonnalisationConsequencesForCollectivite( + collectiviteId: number, + request: GetPersonnalisationConsequencesRequestType, + tokenInfo?: SupabaseJwtPayload, + collectiviteInfo?: CollectiviteAvecType + ): Promise { + + // Seulement les personnes ayant l'accès en lecture à la collectivité peuvent voir les réponses historiques + if (request.date && tokenInfo) { + await this.authService.verifieAccesAuxCollectivites( + tokenInfo, + [collectiviteId], + NiveauAcces.LECTURE + ); + } + + if (!collectiviteInfo) { + collectiviteInfo = await this.collectivitesService.getCollectiviteAvecType(collectiviteId); + } + const reponses = await this.getPersonnalisationReponses( + collectiviteId, + request.date, + ); + const regles = await this.getPersonnalisationRegles(request.referentiel); + + return this.getPersonnalisationConsequences( + regles, + reponses, + collectiviteInfo, + ); + } + + async getPersonnalisationConsequences( + regles: GetPersonnalisationReglesResponseType, + reponses: GetPersonnalisationReponsesResponseType, + collectiviteInfo: IdentiteCollectivite, + ): Promise { + const consequences: GetPersonnalitionConsequencesResponseType = {}; + + regles.regles.forEach((regle) => { + if (!consequences[regle.action_id]) { + consequences[regle.action_id] = { + desactive: null, + score_formule: null, + potentiel_perso: null, + }; + } + if (regle.formule) { + this.logger.log( + `Evaluation de la formule de type ${regle.type} pour l'action ${regle.action_id}: ${regle.formule}`, + ); + const evaluatedExpression = + this.expressionParserService.parseAndEvaluateExpression( + regle.formule, + reponses, + collectiviteInfo, + ); + if (regle.type === 'score') { + consequences[regle.action_id].score_formule = + evaluatedExpression as string; + } else if (regle.type === 'desactivation') { + consequences[regle.action_id].desactive = + evaluatedExpression as boolean; + } else if (regle.type === 'reduction') { + consequences[regle.action_id].potentiel_perso = + evaluatedExpression as number; + } + } + }); + + return consequences; + } +} diff --git a/backend/src/referentiels/controllers/referentiels-scoring.controller.ts b/backend/src/referentiels/controllers/referentiels-scoring.controller.ts new file mode 100644 index 0000000000..6a37829b96 --- /dev/null +++ b/backend/src/referentiels/controllers/referentiels-scoring.controller.ts @@ -0,0 +1,86 @@ +import { createZodDto } from '@anatine/zod-nestjs'; +import { Controller, Get, Logger, Param, Query } from '@nestjs/common'; +import { ApiExcludeEndpoint, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { AllowAnonymousAccess } from '../../auth/decorators/allow-anonymous-access.decorator'; +import { TokenInfo } from '../../auth/decorators/token-info.decorators'; +import { SupabaseJwtPayload } from '../../auth/models/auth.models'; +import { getActionStatutsRequestSchema } from '../models/get-action-statuts.request'; +import { getActionStatutsResponseSchema } from '../models/get-action-statuts.response'; +import { GetCheckScoresResponseType } from '../models/get-check-scores.response'; +import { getReferentielScoresRequestSchema } from '../models/get-referentiel-scores.request'; +import { getReferentielScoresResponseSchema } from '../models/get-referentiel-scores.response'; +import { ReferentielType } from '../models/referentiel.enum'; +import ReferentielsScoringService from '../services/referentiels-scoring.service'; + +class GetReferentielScoresRequestClass extends createZodDto( + getReferentielScoresRequestSchema, +) {} +class GetReferentielScoresResponseClass extends createZodDto( + getReferentielScoresResponseSchema, +) {} + +class GetActionStatutsRequestClass extends createZodDto( + getActionStatutsRequestSchema, +) {} + +class GetActionStatutsResponseClass extends createZodDto( + getActionStatutsResponseSchema, +) {} + +@ApiTags('Referentiels') +@Controller('collectivites/:collectivite_id/referentiels/:referentiel_id') +export class ReferentielsScoringController { + private readonly logger = new Logger(ReferentielsScoringController.name); + + constructor( + private readonly referentielsScoringService: ReferentielsScoringService, + ) {} + + @AllowAnonymousAccess() + @Get('action-statuts') + @ApiResponse({ type: GetActionStatutsResponseClass }) + async getReferentielStatuts( + @Param('collectivite_id') collectiviteId: number, + @Param('referentiel_id') referentielId: ReferentielType, + @Query() parameters: GetActionStatutsRequestClass, + @TokenInfo() tokenInfo: SupabaseJwtPayload, + ): Promise { + return this.referentielsScoringService.getReferentielActionStatuts( + referentielId, + collectiviteId, + parameters.date, + tokenInfo + ); + } + + @AllowAnonymousAccess() + @Get('scores') + @ApiResponse({ type: GetReferentielScoresResponseClass }) + async getReferentielScoring( + @Param('collectivite_id') collectiviteId: number, + @Param('referentiel_id') referentielId: ReferentielType, + @Query() parameters: GetReferentielScoresRequestClass, + @TokenInfo() tokenInfo: SupabaseJwtPayload, + ): Promise { + const scores = + await this.referentielsScoringService.computeScoreForCollectivite( + referentielId, + collectiviteId, + parameters.date, + tokenInfo + ); + return { date: parameters.date || new Date().toISOString(), scores }; + } + + @ApiExcludeEndpoint() // Not in documentation + @Get('check-scores') + async checkReferentialScore( + @Param('collectivite_id') collectiviteId: number, + @Param('referentiel_id') referentielId: ReferentielType, + ): Promise { + return await this.referentielsScoringService.checkScoreForCollectivite( + referentielId, + collectiviteId, + ); + } +} diff --git a/backend/src/referentiels/controllers/referentiels.controller.ts b/backend/src/referentiels/controllers/referentiels.controller.ts new file mode 100644 index 0000000000..4fd2ee3dcb --- /dev/null +++ b/backend/src/referentiels/controllers/referentiels.controller.ts @@ -0,0 +1,31 @@ +import { createZodDto } from '@anatine/zod-nestjs'; +import { Controller, Get, Logger, Param } from '@nestjs/common'; +import { ApiResponse, ApiTags } from '@nestjs/swagger'; +import { AllowPublicAccess } from '../../auth/decorators/allow-public-access.decorator'; +import { TokenInfo } from '../../auth/decorators/token-info.decorators'; +import { SupabaseJwtPayload } from '../../auth/models/auth.models'; +import { getReferentielResponseSchema } from '../models/get-referentiel.response'; +import { ReferentielType } from '../models/referentiel.enum'; +import ReferentielsService from '../services/referentiels.service'; + +class GetReferentielResponseClass extends createZodDto( + getReferentielResponseSchema +) {} + +@ApiTags('Referentiels') +@Controller('referentiels') +export class ReferentielsController { + private readonly logger = new Logger(ReferentielsController.name); + + constructor(private readonly referentielsService: ReferentielsService) {} + + @AllowPublicAccess() + @Get(':referentiel_id') + @ApiResponse({ type: GetReferentielResponseClass }) + async getReferentiel( + @Param('referentiel_id') referentielId: ReferentielType, + @TokenInfo() tokenInfo: SupabaseJwtPayload + ): Promise { + return this.referentielsService.getReferentiel(referentielId, true); + } +} diff --git a/backend/src/referentiels/models/action-computed-points.table.ts b/backend/src/referentiels/models/action-computed-points.table.ts new file mode 100644 index 0000000000..90489f8eb6 --- /dev/null +++ b/backend/src/referentiels/models/action-computed-points.table.ts @@ -0,0 +1,26 @@ +import { InferInsertModel, InferSelectModel, sql } from 'drizzle-orm'; +import { doublePrecision, pgTable, timestamp } from 'drizzle-orm/pg-core'; +import { createInsertSchema, createSelectSchema } from 'drizzle-zod'; +import { actionIdReference } from './action-definition.table'; + +export const actionComputedPointsTable = pgTable('action_computed_points', { + modified_at: timestamp('modified_at', { withTimezone: true, mode: 'string' }) + .default(sql`CURRENT_TIMESTAMP`) + .notNull(), + action_id: actionIdReference.primaryKey().notNull(), + value: doublePrecision('value').notNull(), +}); + +export type ActionComputedPointsType = InferSelectModel< + typeof actionComputedPointsTable +>; +export type CreateActionComputedPointsType = InferInsertModel< + typeof actionComputedPointsTable +>; + +export const actionComputedPointsSchema = createSelectSchema( + actionComputedPointsTable, +); +export const createActionComputedPointsSchema = createInsertSchema( + actionComputedPointsTable, +); diff --git a/backend/src/referentiels/models/action-definition.table.ts b/backend/src/referentiels/models/action-definition.table.ts new file mode 100644 index 0000000000..44d2b22ed5 --- /dev/null +++ b/backend/src/referentiels/models/action-definition.table.ts @@ -0,0 +1,73 @@ +import { InferInsertModel, InferSelectModel, sql } from 'drizzle-orm'; +import { + doublePrecision, + pgEnum, + pgTable, + text, + timestamp, + varchar, +} from 'drizzle-orm/pg-core'; +import { createInsertSchema, createSelectSchema } from 'drizzle-zod'; +import { z } from 'zod'; +import { ActionType } from './action-type.enum'; +import { referentielList } from './referentiel.enum'; + +// Todo: change it reference another table instead +export const referentielEnum = pgEnum('referentiel', referentielList); +export const actionCategorieEnum = pgEnum('action_categorie', [ + 'bases', + 'mise en œuvre', + 'effets', +]); +export const actionIdVarchar = varchar('action_id', { length: 30 }); +export const actionIdReference = actionIdVarchar.references( + () => actionDefinitionTable.action_id +); + +export const actionDefinitionTable = pgTable('action_definition', { + modified_at: timestamp('modified_at', { withTimezone: true, mode: 'string' }) + .default(sql`CURRENT_TIMESTAMP`) + .notNull(), + action_id: actionIdVarchar.primaryKey().notNull(), + referentiel: referentielEnum('referentiel').notNull(), + identifiant: text('identifiant').notNull(), + nom: text('nom').notNull(), + description: text('description').notNull(), + contexte: text('contexte').notNull(), + exemples: text('exemples').notNull(), + ressources: text('ressources').notNull(), + reduction_potentiel: text('reduction_potentiel').notNull(), + perimetre_evaluation: text('perimetre_evaluation').notNull(), + preuve: text('preuve'), + points: doublePrecision('points'), + pourcentage: doublePrecision('pourcentage'), + categorie: actionCategorieEnum('categorie'), +}); + +export type ActionDefinitionType = InferSelectModel< + typeof actionDefinitionTable +>; +export type CreateActionDefinitionType = InferInsertModel< + typeof actionDefinitionTable +>; + +export const actionDefinitionSchema = createSelectSchema(actionDefinitionTable); +export const actionDefinitionSeulementIdObligatoireSchema = + actionDefinitionSchema.partial(); +export const actionDefinitionMinimalWithTypeLevel = + actionDefinitionSchema.extend({ + level: z.number(), + action_type: z.nativeEnum(ActionType), + }); + +export const createActionDefinitionSchema = createInsertSchema( + actionDefinitionTable +); + +export type ActionDefinitionAvecParentType = Pick< + ActionDefinitionType, + 'action_id' +> & + Partial & { + parent_action_id: string | null; + }; diff --git a/backend/src/referentiels/models/action-relation.table.ts b/backend/src/referentiels/models/action-relation.table.ts new file mode 100644 index 0000000000..0e5f8e5662 --- /dev/null +++ b/backend/src/referentiels/models/action-relation.table.ts @@ -0,0 +1,27 @@ +import { InferInsertModel, InferSelectModel } from 'drizzle-orm'; +import { pgTable, varchar } from 'drizzle-orm/pg-core'; +import { createInsertSchema, createSelectSchema } from 'drizzle-zod'; +import { + actionDefinitionTable, + referentielEnum, +} from './action-definition.table'; + +export const actionRelationTable = pgTable('action_relation', { + id: varchar('id', { length: 30 }) + .references(() => actionDefinitionTable.action_id) + .primaryKey() + .notNull(), + referentiel: referentielEnum('referentiel').notNull(), + parent: varchar('parent', { length: 30 }).references( + () => actionDefinitionTable.action_id, + ), +}); + +export type ActionRelationType = InferSelectModel; +export type CreateActionRelationType = InferInsertModel< + typeof actionRelationTable +>; + +export const actionRelationSchema = createSelectSchema(actionRelationTable); +export const createActionRelationSchema = + createInsertSchema(actionRelationTable); diff --git a/backend/src/referentiels/models/action-score.dto.ts b/backend/src/referentiels/models/action-score.dto.ts new file mode 100644 index 0000000000..2e05f0e1e7 --- /dev/null +++ b/backend/src/referentiels/models/action-score.dto.ts @@ -0,0 +1,105 @@ +import { extendApi, extendZodWithOpenApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; +extendZodWithOpenApi(z); + +export const actionScoreSchema = extendApi( + z + .object({ + action_id: z.string().describe("L'id de l'action, ex: eci_1.1"), + point_referentiel: z + .number() + .nullable() + .describe('La valeur de base tel que calculé à partir des markdowns'), + point_fait: z + .number() + .nullable() + .describe( + 'Pour une tache avec un statut fait, est égal au point référentiel', + ), + point_programme: z + .number() + .nullable() + .describe( + 'Pour une tache avec un statut programmé, est égal au point référentiel', + ), + point_pas_fait: z + .number() + .nullable() + .describe( + 'Pour une tache avec un statut pas fait, est égal au point référentiel', + ), + point_non_renseigne: z + .number() + .nullable() + .describe('Pour une tache sans statut, est égal au point référentiel'), + point_potentiel: z + .number() + .nullable() + .describe( + 'Le potentiel personnalisé est calculé à partir du potentiel, auquel on ajoute le reliquat des points des actions désactivées', + ), + concerne: z + .boolean() + .describe( + "Faux si la collectivité s'est déclarée comme non concernée pour cette action ou pour tous ses enfants. A noter qu'une désactivation par personnalisation entraine également un non concerné", + ), + total_taches_count: z + .number() + .int() + .describe( + "Le nombre de taches d'une action, est égal à 1 si l'action est une tache", + ), + completed_taches_count: z + .number() + .int() + .nullable() + .describe('Le nombre de taches renseignées'), + fait_taches_avancement: z + .number() + .nullable() + .describe( + 'La somme des proportions du fait des tâches, si une tache à un statut fait à 50% equal à 0.5', + ), + programme_taches_avancement: z + .number() + .nullable() + .describe( + 'La somme des proportions du programme des tâches, si une tache à un statut programmé à 50% est égal à 0.5', + ), + pas_fait_taches_avancement: z + .number() + .nullable() + .describe( + 'La somme des proportions du pas fait des tâches, si une tache à un statut pas fait à 50% est égal à 0.5', + ), + pas_concerne_taches_avancement: z + .number() + .nullable() + .describe( + 'La somme du non concerné des tâches. Si une tache est déclarée non concerné, est égal à 1.0', + ), + desactive: z + .boolean() + .describe( + "Vrai si l'action ou un de ses ancêtres est désactivé du fait de la personnalisation", + ), + point_potentiel_perso: z + .number() + .nullable() + .describe( + 'Le potentiel est calculé à partir des conséquences de la personnalisation, soit point référentiel x facteur de la personnalisation', + ), + renseigne: z + .boolean() + .describe( + "Vrai si l'action est renseignée, càd non manquante à la complétion du référentiel. Tag défini en fonction du statut de l'action et de celui de ses parents", + ), + }) + .openapi({ + title: 'ActionScore', + description: + "Le score d'une action. Une action est un nœud de l'arbre constituant le référentiel. Son score représente les points obtenus ainsi que la valeur de l'action.", + }), +); + +export type ActionScoreType = z.infer; diff --git a/backend/src/referentiels/models/action-statut.table.ts b/backend/src/referentiels/models/action-statut.table.ts new file mode 100644 index 0000000000..f3c696861c --- /dev/null +++ b/backend/src/referentiels/models/action-statut.table.ts @@ -0,0 +1,45 @@ +import { InferInsertModel, InferSelectModel, sql } from 'drizzle-orm'; +import { + boolean, + doublePrecision, + integer, + pgEnum, + pgTable, + timestamp, + uuid, +} from 'drizzle-orm/pg-core'; +import { createInsertSchema, createSelectSchema } from 'drizzle-zod'; +import { collectiviteTable } from '../../collectivites/models/collectivite.models'; +import { actionIdReference } from './action-definition.table'; + +export const avancementEnum = pgEnum('avancement', [ + 'fait', + 'pas_fait', + 'programme', + 'non_renseigne', + 'detaille', +]); + +export const actionStatutTable = pgTable('action_statut', { + collectivite_id: integer('collectivite_id') + .notNull() + .references(() => collectiviteTable.id), + action_id: actionIdReference.notNull(), + avancement: avancementEnum('avancement').notNull(), + avancement_detaille: doublePrecision('avancement_detaille').array(), + concerne: boolean('concerne').notNull(), + modified_by: uuid('modified_by') + .default(sql`auth.uid()`) + .notNull(), + modified_at: timestamp('modified_at', { withTimezone: true, mode: 'string' }) + .default(sql`CURRENT_TIMESTAMP`) + .notNull(), +}); + +export type ActionStatutType = InferSelectModel; +export type CreateActionStatutTypeType = InferInsertModel< + typeof actionStatutTable +>; + +export const actionStatutSchema = createSelectSchema(actionStatutTable); +export const createActionStatutSchema = createInsertSchema(actionStatutTable); diff --git a/backend/src/referentiels/models/action-type.enum.ts b/backend/src/referentiels/models/action-type.enum.ts new file mode 100644 index 0000000000..33655de8eb --- /dev/null +++ b/backend/src/referentiels/models/action-type.enum.ts @@ -0,0 +1,8 @@ +export enum ActionType { + REFERENTIEL = 'referentiel', + AXE = 'axe', + SOUS_AXE = 'sous-axe', + ACTION = 'action', + SOUS_ACTION = 'sous-action', + TACHE = 'tache', +} diff --git a/backend/src/referentiels/models/client-scores.table.ts b/backend/src/referentiels/models/client-scores.table.ts new file mode 100644 index 0000000000..dcc442a852 --- /dev/null +++ b/backend/src/referentiels/models/client-scores.table.ts @@ -0,0 +1,46 @@ +import { InferInsertModel, InferSelectModel } from 'drizzle-orm'; +import { + foreignKey, + integer, + jsonb, + pgTable, + primaryKey, + timestamp, +} from 'drizzle-orm/pg-core'; +import { createInsertSchema, createSelectSchema } from 'drizzle-zod'; +import { collectiviteTable } from '../../collectivites/models/collectivite.models'; +import { referentielEnum } from './action-definition.table'; + +export const clientScoresTable = pgTable( + 'client_scores', + { + collectiviteId: integer('collectivite_id').notNull(), + referentiel: referentielEnum('referentiel').notNull(), // TODO: Reference referentiel table + scores: jsonb('scores').notNull(), + modifiedAt: timestamp('modified_at', { + withTimezone: true, + }).notNull(), + payloadTimestamp: timestamp('payload_timestamp', { + withTimezone: true, + }), + }, + (table) => { + return { + clientScoresCollectiviteIdFkey: foreignKey({ + columns: [table.collectiviteId], + foreignColumns: [collectiviteTable.id], + name: 'client_scores_collectivite_id_fkey', + }), + clientScoresPkey: primaryKey({ + columns: [table.collectiviteId, table.referentiel], + name: 'client_scores_pkey', + }), + }; + } +); + +export type ClientScoresType = InferSelectModel; +export type CreateClientScoresType = InferInsertModel; + +export const clientScoresSchema = createSelectSchema(clientScoresTable); +export const createClientScoresTable = createInsertSchema(clientScoresTable); diff --git a/backend/src/referentiels/models/get-action-scores.response.ts b/backend/src/referentiels/models/get-action-scores.response.ts new file mode 100644 index 0000000000..4d0ee61304 --- /dev/null +++ b/backend/src/referentiels/models/get-action-scores.response.ts @@ -0,0 +1,12 @@ +import { extendApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; +import { actionScoreSchema } from './action-score.dto'; + +export const getActionScoresResponseSchema = extendApi( + z.record(z.string(), actionScoreSchema), +).openapi({ + title: 'Scores des actions', +}); +export type GetActionScoresResponseType = z.infer< + typeof getActionScoresResponseSchema +>; diff --git a/backend/src/referentiels/models/get-action-statuts.request.ts b/backend/src/referentiels/models/get-action-statuts.request.ts new file mode 100644 index 0000000000..d6b797c4e1 --- /dev/null +++ b/backend/src/referentiels/models/get-action-statuts.request.ts @@ -0,0 +1,13 @@ +import { extendApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; + +export const getActionStatutsRequestSchema = extendApi( + z.object({ + date: z.string().datetime().optional(), + }), +).openapi({ + title: 'Date pour laquelle le statut des actions est demandé', +}); +export type GetActionStatutsRequestType = z.infer< + typeof getActionStatutsRequestSchema +>; diff --git a/backend/src/referentiels/models/get-action-statuts.response.ts b/backend/src/referentiels/models/get-action-statuts.response.ts new file mode 100644 index 0000000000..c6d7d8ed83 --- /dev/null +++ b/backend/src/referentiels/models/get-action-statuts.response.ts @@ -0,0 +1,19 @@ +import { extendApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; +import { actionStatutSchema } from './action-statut.table'; + +export const getActionStatutsResponseSchema = extendApi( + z.record( + z.string(), + actionStatutSchema.pick({ + concerne: true, + avancement: true, + avancement_detaille: true, + }), + ), +).openapi({ + title: 'Statuts des actions', +}); +export type GetActionStatutsResponseType = z.infer< + typeof getActionStatutsResponseSchema +>; diff --git a/backend/src/referentiels/models/get-check-scores.response.ts b/backend/src/referentiels/models/get-check-scores.response.ts new file mode 100644 index 0000000000..9ccf6af77d --- /dev/null +++ b/backend/src/referentiels/models/get-check-scores.response.ts @@ -0,0 +1,21 @@ +import { extendApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; +import { actionScoreSchema } from './action-score.dto'; + +export const getCheckScoresResponseSchema = extendApi( + z.object({ + date: z.string().datetime(), + differences: z.record( + z.string(), + z.object({ + calcule: actionScoreSchema.partial(), + sauvegarde: actionScoreSchema.partial(), + }) + ), + }) +).openapi({ + title: 'Résultat de la vérification de calcul de score', +}); +export type GetCheckScoresResponseType = z.infer< + typeof getCheckScoresResponseSchema +>; diff --git a/backend/src/referentiels/models/get-referentiel-scores.request.ts b/backend/src/referentiels/models/get-referentiel-scores.request.ts new file mode 100644 index 0000000000..4dae593d90 --- /dev/null +++ b/backend/src/referentiels/models/get-referentiel-scores.request.ts @@ -0,0 +1,14 @@ +import { extendApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; + +export const getReferentielScoresRequestSchema = extendApi( + z.object({ + date: z.string().datetime().optional(), + }), +).openapi({ + title: + 'Paramètres de la requête pour obtenir les scores des actions dun référentiel', +}); +export type GetReferentielScoresRequestType = z.infer< + typeof getReferentielScoresRequestSchema +>; diff --git a/backend/src/referentiels/models/get-referentiel-scores.response.ts b/backend/src/referentiels/models/get-referentiel-scores.response.ts new file mode 100644 index 0000000000..28b39c2780 --- /dev/null +++ b/backend/src/referentiels/models/get-referentiel-scores.response.ts @@ -0,0 +1,15 @@ +import { extendApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; +import { referentielActionAvecScoreDtoSchema } from './referentiel-action-avec-score.dto'; + +export const getReferentielScoresResponseSchema = extendApi( + z.object({ + date: z.string().datetime().optional(), + scores: referentielActionAvecScoreDtoSchema, + }), +).openapi({ + title: 'Score de la collectivité pour un référentiel et la date donnée', +}); +export type GetReferentielScoresResponseType = z.infer< + typeof getReferentielScoresResponseSchema +>; diff --git a/backend/src/referentiels/models/get-referentiel.response.ts b/backend/src/referentiels/models/get-referentiel.response.ts new file mode 100644 index 0000000000..6c931b6bc8 --- /dev/null +++ b/backend/src/referentiels/models/get-referentiel.response.ts @@ -0,0 +1,21 @@ +import { extendApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; +import { actionDefinitionMinimalWithTypeLevel } from './action-definition.table'; +import { ActionType } from './action-type.enum'; +import { referentielActionDtoSchema } from './referentiel-action.dto'; + +export const getReferentielResponseSchema = extendApi( + z.object({ + ordered_item_types: z.array(z.nativeEnum(ActionType)), + items_list: z.array(actionDefinitionMinimalWithTypeLevel).optional(), + items_tree: referentielActionDtoSchema.optional(), + items_map: z + .record(z.string(), actionDefinitionMinimalWithTypeLevel) + .optional(), + }) +).openapi({ + title: 'Referentiel sous forme de liste, map ou hierarchie', +}); +export type GetReferentielResponseType = z.infer< + typeof getReferentielResponseSchema +>; diff --git a/backend/src/referentiels/models/historique-action-statut.table.ts b/backend/src/referentiels/models/historique-action-statut.table.ts new file mode 100644 index 0000000000..47f1e5e901 --- /dev/null +++ b/backend/src/referentiels/models/historique-action-statut.table.ts @@ -0,0 +1,59 @@ +import { InferInsertModel, InferSelectModel, sql } from 'drizzle-orm'; +import { + boolean, + doublePrecision, + integer, + timestamp, + uuid, +} from 'drizzle-orm/pg-core'; +import { createInsertSchema, createSelectSchema } from 'drizzle-zod'; +import { collectiviteTable } from '../../collectivites/models/collectivite.models'; +import { historiqueSchema } from '../../personnalisations/models/historique-reponse-choix.table'; +import { actionIdReference } from './action-definition.table'; +import { avancementEnum } from './action-statut.table'; + +export const historiqueActionStatutTable = historiqueSchema.table( + 'action_statut', + { + collectivite_id: integer('collectivite_id') + .notNull() + .references(() => collectiviteTable.id), + action_id: actionIdReference.notNull(), + avancement: avancementEnum('avancement').notNull(), + previous_avancement: avancementEnum('previous_avancement'), + avancement_detaille: doublePrecision('avancement_detaille').array(), + previous_avancement_detaille: doublePrecision( + 'previous_avancement_detaille', + ).array(), + concerne: boolean('concerne').notNull(), + previous_concerne: boolean('previous_concerne').notNull(), + modified_by: uuid('modified_by') + .default(sql`auth.uid()`) + .notNull(), + previous_modified_by: uuid('previous_modified_by').default(sql`auth.uid()`), + modified_at: timestamp('modified_at', { + withTimezone: true, + mode: 'string', + }) + .default(sql`CURRENT_TIMESTAMP`) + .notNull(), + previous_modified_at: timestamp('previous_modified_at', { + withTimezone: true, + mode: 'string', + }).default(sql`CURRENT_TIMESTAMP`), + }, +); + +export type HistoriqueActionStatutType = InferSelectModel< + typeof historiqueActionStatutTable +>; +export type CreateHistoriqueActionStatutTypeType = InferInsertModel< + typeof historiqueActionStatutTable +>; + +export const historiqueActionStatutSchema = createSelectSchema( + historiqueActionStatutTable, +); +export const createHistoriqueActionStatutSchema = createInsertSchema( + historiqueActionStatutTable, +); diff --git a/backend/src/referentiels/models/referentiel-action-avec-score.dto.ts b/backend/src/referentiels/models/referentiel-action-avec-score.dto.ts new file mode 100644 index 0000000000..7f8cda6a53 --- /dev/null +++ b/backend/src/referentiels/models/referentiel-action-avec-score.dto.ts @@ -0,0 +1,31 @@ +import { extendApi, extendZodWithOpenApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; +import { actionDefinitionSeulementIdObligatoireSchema } from './action-definition.table'; +import { actionScoreSchema, ActionScoreType } from './action-score.dto'; +import { ActionType } from './action-type.enum'; +extendZodWithOpenApi(z); + +export type ReferentielActionAvecScoreType = z.infer< + typeof actionDefinitionSeulementIdObligatoireSchema +> & { + level: number; + action_type: ActionType; + actions_enfant: ReferentielActionAvecScoreType[]; + score: ActionScoreType; +}; + +export const referentielActionAvecScoreDtoSchema: z.ZodType = + extendApi( + actionDefinitionSeulementIdObligatoireSchema + .extend({ + level: z.number(), + action_type: z.nativeEnum(ActionType), + actions_enfant: z.lazy(() => + referentielActionAvecScoreDtoSchema.array(), + ), + score: actionScoreSchema, + }) + .openapi({ + title: "Référentiel d'actions avec le score associé", + }), + ); diff --git a/backend/src/referentiels/models/referentiel-action.dto.ts b/backend/src/referentiels/models/referentiel-action.dto.ts new file mode 100644 index 0000000000..0fc6bc897e --- /dev/null +++ b/backend/src/referentiels/models/referentiel-action.dto.ts @@ -0,0 +1,27 @@ +import { extendApi, extendZodWithOpenApi } from '@anatine/zod-openapi'; +import { z } from 'zod'; +import { actionDefinitionSeulementIdObligatoireSchema } from './action-definition.table'; +import { ActionType } from './action-type.enum'; +extendZodWithOpenApi(z); + +export type ReferentielActionType = z.infer< + typeof actionDefinitionSeulementIdObligatoireSchema +> & { + level: number; + action_type: ActionType; + actions_enfant: ReferentielActionType[]; +}; + +export const referentielActionDtoSchema: z.ZodType = + extendApi( + actionDefinitionSeulementIdObligatoireSchema + .extend({ + level: z.number(), + action_type: z.nativeEnum(ActionType), + actions_enfant: z.lazy(() => referentielActionDtoSchema.array()), + }) + .openapi({ + title: "Référentiel d'actions", + description: 'Référentiel avec ses actions enfants', + }), + ); diff --git a/backend/src/referentiels/models/referentiel.enum.ts b/backend/src/referentiels/models/referentiel.enum.ts new file mode 100644 index 0000000000..9f9d60f9c4 --- /dev/null +++ b/backend/src/referentiels/models/referentiel.enum.ts @@ -0,0 +1,9 @@ +export enum ReferentielType { + ECI = 'eci', + CAE = 'cae', +} +// WARNING: not using Object.values to use it with pgTable +export const referentielList = [ + ReferentielType.CAE, + ReferentielType.ECI, +] as const; diff --git a/backend/src/referentiels/models/samples/cae-referentiel.ts b/backend/src/referentiels/models/samples/cae-referentiel.ts new file mode 100644 index 0000000000..55427bfc9c --- /dev/null +++ b/backend/src/referentiels/models/samples/cae-referentiel.ts @@ -0,0 +1,13602 @@ +import { ActionType } from '../action-type.enum'; +import { ReferentielActionType } from '../referentiel-action.dto'; + +export const caeReferentiel: ReferentielActionType = { + action_id: 'cae', + nom: 'Climat Air Énergie', + points: 500, + pourcentage: null, + level: 0, + action_type: ActionType.REFERENTIEL, + actions_enfant: [ + { + action_id: 'cae_1', + nom: 'Planification territoriale', + points: 100, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_1.1', + nom: 'Stratégie globale climat-air-énergie', + points: 30, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_1.1.1', + nom: 'Définir la vision, les objectifs et la stratégie Climat-Air-Énergie', + points: 12, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'cae_1.1.1.1', + nom: 'Formaliser la vision et les engagements', + points: 0.6, + pourcentage: 5, + actions_enfant: [ + { + action_id: 'cae_1.1.1.1.1', + nom: 'Formaliser une vision et des engagements dans une décision de politique générale (délibération)', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.1.1.2', + nom: "S'engager dans des démarches ambitieuses et reconnues (TEPOS, Convention des Maires)", + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.1.1.2', + nom: 'Définir les principaux objectifs énergétiques et climatiques', + points: 0.6, + pourcentage: 5, + actions_enfant: [ + { + action_id: 'cae_1.1.1.2.1', + nom: 'Définir des objectifs énergétiques et climatiques directeurs chiffrés', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.1.2.2', + nom: 'Adapter les objectifs énergétiques et climatiques chiffrés au territoire', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.1.2.3', + nom: 'Définir des objectifs concernant la lutte contre la pollution de l’air', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.1.1.3', + nom: 'Détailler la stratégie et les objectifs énergétiques et climatiques par secteurs d’activités (scénarios)', + points: 1.2, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_1.1.1.3.1', + nom: 'Détailler des scénarios prospectifs et des objectifs chiffrés dans la stratégie', + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.1.3.2', + nom: 'Détailler les objectifs chiffrés pour chaque secteur d’activité', + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.1.3.3', + nom: 'Détailler les objectifs chiffrés à atteindre à l’horizon 2020, 2030 et 2050 par secteurs d’activités', + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.1.3.4', + nom: 'Définir des objectifs particulièrement ambitieux dans les domaines de la planification de l’aménagement, du bâtiment et des transports', + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.1.3.5', + nom: 'Détailler les objectifs de développement pour chaque filière de production d’énergies renouvelables', + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.1.3.6', + nom: 'Mettre en évidence les conséquences en matière d’emploi et de coût de l’inaction dans la stratégie', + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.1.1.4', + nom: 'Préciser la stratégie sur la qualité de l’air', + points: 0.6, + pourcentage: 5, + actions_enfant: [ + { + action_id: 'cae_1.1.1.4.1', + nom: "Faire apparaître une hiérarchisation des actions dans la stratégie sur la qualité de l'air", + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.1.4.2', + nom: "Réaliser un chiffrage des impacts du programme d'actions sur la qualité de l'air", + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.1.4.3', + nom: "Quantifier les actions en termes d'émissions de polluants atmosphériques évitées (En zone PPA)", + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.1.1.5', + nom: 'Décliner la stratégie climat-air-énergie de manière opérationnelle en cohérence avec les objectifs', + points: 3.6, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.1.1.6', + nom: 'Diffuser la vision, les objectifs et la stratégie Climat-Air-Énergie', + points: 1.2, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_1.1.1.6.1', + nom: 'Comparer annuellement les objectifs au rythme réel de mise en œuvre sur le territoire', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.1.6.2', + nom: 'Reprendre les objectifs dans les documents de planification', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.1.6.3', + nom: 'Communiquer en interne et en externe pour diffuser et partager la vision', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.1.6.4', + nom: 'Répondre à des appels à projets climat-air-énergie', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.1.1.7', + nom: 'Évaluer et valoriser les résultats de cette politique climat-air-énergie', + points: 4.2, + pourcentage: 35, + actions_enfant: [ + { + action_id: 'cae_1.1.1.7.1', + nom: 'Réduire la consommation énergétique totale du territoire', + points: 1.4000000000000004, + pourcentage: 33.33333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.1.7.2', + nom: 'Réduire les émissions annuelles de gaz à effet de serre du territoire', + points: 1.4000000000000004, + pourcentage: 33.33333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.1.7.3', + nom: "Réduire les émissions annuelles des 6 polluants atmosphériques règlementaires de l'arrêté PCAET (NOx ; PM10 ; PM2,5 ; COV ; SO2 et ammoniac)", + points: 1.4000000000000004, + pourcentage: 33.33333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_1.1.2', + nom: 'Réaliser le diagnostic Climat-Air-Énergie du territoire', + points: 10, + pourcentage: 33.33333333333333, + actions_enfant: [ + { + action_id: 'cae_1.1.2.0', + nom: 'Être en conformité vis-à-vis des obligations réglementaires (PCAET et BGES)', + points: 0, + pourcentage: 0, + actions_enfant: [ + { + action_id: 'cae_1.1.2.0.1', + nom: 'Être en conformité vis-à-vis des obligations réglementaires PCAET', + points: 0, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.0.2', + nom: 'Être en conformité vis-à-vis des obligations réglementaires BGES', + points: 0, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.1.2.1', + nom: 'Formaliser les engagements, recenser et synthétiser les données et études existantes', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_1.1.2.1.1', + nom: 'Formaliser les engagements par une décision politique (délibération)', + points: 0.4, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.1.2', + nom: 'Dédier des ressources humaines internes au diagnostic et/ou décider de confier une mission externe', + points: 0.4, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.1.3', + nom: "Mettre en place une base d'indicateurs du diagnostic", + points: 0.4, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.1.4', + nom: 'Recueillir les données énergétiques territoriales, GES et polluants atmosphériques existantes qui concernent le territoire', + points: 0.4, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.1.5', + nom: 'Participer à la collecte et transmission des données pour les diagnostics réalisés à l’échelle intercommunale (communes uniquement)', + points: 0.4, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.1.2.2', + nom: 'Réaliser un bilan climat-air-énergie complet (diversité des indicateurs)', + points: 4, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'cae_1.1.2.2.1', + nom: "Disposer d'un inventaire des émissions de GES et de polluants atmosphériques", + points: 0.8, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.2.2', + nom: 'Estimer la séquestration nette de dioxyde de carbone et de ses possibilités de développement', + points: 0.8, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.2.3', + nom: 'Analyser la consommation énergétique finale du territoire et le potentiel de réduction de celle-ci.', + points: 0.8, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.2.4', + nom: 'Présenter les enjeux des réseaux de distribution et de transport d’électricité, de gaz et de chaleur.', + points: 0.8, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.2.5', + nom: 'Analyser les productions énergétiques renouvelables sur le territoire et leur potentiel de développement.', + points: 0.8, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.1.2.3', + nom: 'Adopter et présenter une méthodologie claire', + points: 1, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_1.1.2.3.1', + nom: 'Les unités utilisées sont celles exigées réglementairement', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.3.2', + nom: 'Expliciter la prise en compte ou non des émissions indirectes', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.3.3', + nom: 'Expliciter les sources et les données (année, acteurs, périmètres)', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.1.2.4', + nom: 'Réaliser un diagnostic allant au-delà des exigences réglementaires', + points: 1, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_1.1.2.4.1', + nom: 'Prendre en compte les émissions indirectes', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.4.2', + nom: 'Identifier les concentrations des principaux polluants et les populations exposées à des dépassements de normes', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.4.3', + nom: "Détailler finement l'analyse de chaque secteur", + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.1.2.5', + nom: 'Valoriser les résultats en interne et en externe', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_1.1.2.5.1', + nom: 'Analyser les évolutions constatées', + points: 0.28571428571428575, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.5.2', + nom: "Suivre l'évolution de la consommation en fonction des énergies", + points: 0.28571428571428575, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.5.3', + nom: 'Présenter les indicateurs aux agents et aux élus', + points: 0.28571428571428575, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.5.4', + nom: "Réaliser l'appropriation des résultats par les communes pour les diagnostics à l’échelle de l’EPCI", + points: 0.28571428571428575, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.5.5', + nom: 'Communiquer les indicateurs aux acteurs du territoire et aux citoyens', + points: 0.28571428571428575, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.5.6', + nom: 'Utiliser les indicateurs pour prioriser les actions et orienter la politique de la collectivité', + points: 0.28571428571428575, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.2.5.7', + nom: 'Mettre à jour régulièrement les indicateurs', + points: 0.28571428571428575, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_1.1.3', + nom: "Réaliser un diagnostic de vulnérabilité et s’engager dans un programme d'adaptation au changement climatique du territoire", + points: 8, + pourcentage: 26.666666666666668, + actions_enfant: [ + { + action_id: 'cae_1.1.3.1', + nom: 'Formaliser l’intérêt de la collectivité dans sa volonté de réduire la vulnérabilité du territoire au changement climatique', + points: 0.8, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_1.1.3.1.1', + nom: 'Prendre en compte les études réalisées au niveau régional ou interrégional (SRCAE/SRADDET, études MEDCIE ou autre), voire national (PNACC2)', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.3.1.2', + nom: 'Allouer un budget et/ou des moyens humains', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.1.3.2', + nom: 'Connaître la vulnérabilité du territoire au changement climatique', + points: 0.8, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_1.1.3.2.1', + nom: 'Connaître les évolutions climatiques du territoire', + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.3.2.2', + nom: 'Connaître les impacts économiques du changement climatique sur le territoire', + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.3.2.3', + nom: 'Connaître les impacts sociaux du changement climatique sur le territoire', + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.3.2.4', + nom: 'Connaître les impacts en termes de biodiversité', + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.3.2.5', + nom: 'Connaître les impacts sur les réseaux : eau, assainissement, approvisionnement en énergie', + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.3.2.6', + nom: 'Connaître les impacts sur l’aménagement : îlots de chaleurs urbains', + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.1.3.3', + nom: 'Adopter un programme d’actions d’adaptation et intégrer les effets du changement climatique dans les compétences et les politiques de la collectivité', + points: 3.2, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'cae_1.1.3.3.1', + nom: 'Définir un programme d’actions spécifique ou intégrer de façon transversale forte l’adaptation dans le programme d’actions climat-air-énergie', + points: 1.0666666666666669, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.3.3.2', + nom: 'Valoriser l’étude de vulnérabilité et communiquer en priorité auprès des acteurs leviers de changement', + points: 1.0666666666666669, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.3.3.3', + nom: 'Intégrer les éléments de résilience climatique dans les documents de planification structurants', + points: 1.0666666666666669, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.1.3.4', + nom: 'Mettre en place un pilotage opérationnel de suivi et d’évaluation de la politique territoriale d’adaptation au changement climatique', + points: 3.2, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'cae_1.1.3.4.1', + nom: 'Structurer et mettre en œuvre une démarche de suivi-évaluation', + points: 1.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.1.3.4.2', + nom: 'Réaliser une revue de suivi périodique pour mesurer les progrès et l’état d’avancement de la politique d’adaptation au changement climatique', + points: 1.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + { + action_id: 'cae_1.2', + nom: 'Planification sectorielle', + points: 44, + pourcentage: 44, + actions_enfant: [ + { + action_id: 'cae_1.2.1', + nom: 'Mettre en place un schéma directeur des énergies et des réseaux de chaleur', + points: 10, + pourcentage: 22.727272727272727, + actions_enfant: [ + { + action_id: 'cae_1.2.1.1', + nom: 'Organiser le pilotage du schéma directeur des énergies et des réseaux de chaleur', + points: 0.5, + pourcentage: 5, + actions_enfant: [ + { + action_id: 'cae_1.2.1.1.1', + nom: 'Désigner un élu référent et un technicien responsable', + points: 0.16666666666666669, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.1.1.2', + nom: 'Déléguer la compétence schéma directeur des énergies et des réseaux de chaleur à l’intercommunalité', + points: 0.16666666666666669, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.1.1.3', + nom: "Prendre la décision (délibérer) de réaliser l'étude en interne ou de confier une mission externe", + points: 0.16666666666666669, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.1.2', + nom: 'Étudier la faisabilité de développement des réseaux de chaleur sur le territoire', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_1.2.1.2.1', + nom: 'Étudier la faisabilité des réseaux de chaleur alimentés en énergies renouvelables et de récupération', + points: 1, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.1.2.2', + nom: 'Élargir la réflexion en menant une étude de faisabilité de création d’un réseau de chaleur alimentant les bâtiments publics et privés.', + points: 1, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.1.3', + nom: 'Étudier les potentiels de développement des énergies renouvelables et de récupération sur le territoire', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_1.2.1.3.1', + nom: 'Prendre en compte et quantifier tous les potentiels de développement', + points: 1, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.1.3.2', + nom: "Établir un plan d'approvisionnement territorial en bois énergie (collectivités métropolitaines)", + points: 1, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.1.4', + nom: "Établir un schéma directeur pour la création/extension-densification d'un réseau de chaleur (collectivités métropolitaines)", + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_1.2.1.4.1', + nom: 'Prendre en compte de manière globale tous les projets présents sur le territoire (HLM, gros ensembles, industrie…)', + points: 1, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.1.4.2', + nom: "Prévoir l'extension du réseau de chaleur et l'évolution vers un mix énergétique supérieur à 50 % d’énergies renouvelables", + points: 1, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.1.5', + nom: 'Déterminer les secteurs géographiques prioritaires de développement des énergies renouvelables et de récupération', + points: 2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.1.6', + nom: 'Coordonner les différentes démarches de planification sectorielle', + points: 1, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_1.2.1.6.1', + nom: 'Intégrer les secteurs prioritaires de développement des énergies renouvelables et de récupération aux documents d’urbanisme et dans les projets d’aménagement', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.1.6.2', + nom: 'En présence d’un réseau de chaleur, étudier l’intérêt de procéder à son classement et le faire si cela est pertinent', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.1.6.3', + nom: 'Intégrer des mesures de maîtrise de la demande en énergie', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.1.7', + nom: 'Communiquer les résultats et associer les acteurs du territoire', + points: 0.5, + pourcentage: 5, + actions_enfant: [ + { + action_id: 'cae_1.2.1.7.1', + nom: 'Mettre à disposition de l’ensemble des parties prenantes du territoire la programmation énergétique', + points: 0.125, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.1.7.2', + nom: 'Soigner la portée et la forme des études réalisées', + points: 0.125, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.1.7.3', + nom: "Associer les décideurs, les représentants d'intérêts et la société civile", + points: 0.125, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.1.7.4', + nom: 'Associer les investisseurs potentiels', + points: 0.125, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_1.2.2', + nom: 'Organiser les mobilités sur le territoire', + points: 12, + pourcentage: 27.27272727272727, + actions_enfant: [ + { + action_id: 'cae_1.2.2.1', + nom: 'Acter la volonté politique de mettre en place une démarche de planification des déplacements', + points: 1.2, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_1.2.2.1.1', + nom: 'Prendre la compétence d’organisation de la mobilité', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.1.2', + nom: 'Décider de réaliser la démarche de planification des déplacements (PDM, PDMS)', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.1.3', + nom: "Disposer d’une planification antérieure ou s'approprier les enjeux et proposition lors de l’élaboration des documents structurants par l’intercommunalité", + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.2.2', + nom: 'Établir un diagnostic mobilité dans une approche concertée', + points: 1.8, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_1.2.2.2.1', + nom: 'Quantifier les flux de mobilité grâce à des comptages et/ou une modélisation et identifier les zones à enjeux importants', + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.2.2', + nom: 'Traduire de façon spatialisée les orientations', + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.2.3', + nom: 'Évaluer les GES et polluants atmosphériques liés aux déplacements sur le périmètre du plan de mobilité', + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.2.4', + nom: 'Associer les acteurs du territoire dans une procédure concertée lors de l’élaboration ou révision du plan de mobilité', + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.2.5', + nom: 'Vérifier la compatibilité avec le PCAET ou prendre en compte les PCAET s’il y en a plusieurs dans le périmètre du plan de mobilité', + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.2.6', + nom: 'Assurer une coordination stratégique et opérationnelle entre l’AOM locale et la région pour définir la politique de mobilité', + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.2.7', + nom: 'Soumettre le plan pour avis aux AOM limitrophes afin d’améliorer la collaboration au-delà du ressort territorial', + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.2.8', + nom: 'Mettre en cohérence la politique de mobilité avec celle de l’urbanisme local, déclinée par le plan local d’urbanisme (PLU)', + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.2.9', + nom: 'Bien identifier et intégrer a minima les enjeux de mobilité dans les documents de planification et programmes existants (PLU, PLH, PDMS …)', + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.2.3', + nom: 'Planifier des actions pour limiter l’usage de la voiture individuelle', + points: 3.6, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_1.2.2.3.1', + nom: 'Expliciter les mesures pour diminuer à la source les besoins de déplacements motorisés', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.3.2', + nom: 'Préciser le raccordement aux transports en commun des zones génératrices de trafic mal desservies', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.3.3', + nom: 'Planifier de façon raisonnée le stationnement', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.3.4', + nom: "Préciser les mesures pour développer le covoiturage et l'autopartage (parkings, places réservées...), le déploiement de services vélos et la mobilité électrique", + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.3.5', + nom: 'Expliciter les mesures pour ralentir ou diminuer le trafic motorisé', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.2.4', + nom: 'Prioriser le développement des modes alternatifs de déplacement à la voiture dans la planification', + points: 1.8, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_1.2.2.4.1', + nom: 'Planifier le réseau piétonnier', + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.4.2', + nom: "Planifier les chemins menant à l'école et la gestion de l’espace autour des écoles", + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.4.3', + nom: 'Planifier le réseau cyclable', + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.4.4', + nom: 'Planifier la continuité des itinéraires cyclables et piétons', + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.4.5', + nom: 'Planifier les transports publics (lignes, arrêts, etc.)', + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.4.6', + nom: 'Porter attention à l’intermodalité dans la planification', + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.4.7', + nom: "Favoriser le développement du covoiturage et de l'autopartage", + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.4.8', + nom: 'Organiser et optimiser les usages des véhicules électriques', + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.4.9', + nom: 'Envisager l’hippomobilité pour certains usages spécifiques', + points: 0.2, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.2.5', + nom: 'Suivre les actions mises en œuvre et atteindre des résultats significatifs', + points: 3.6, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_1.2.2.5.1', + nom: 'Intégrer des mesures organisationnelles et de suivi', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.5.2', + nom: 'Évaluer le document au moins tous les 5 ans', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.5.3', + nom: 'Créer un observatoire des déplacements', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.5.4', + nom: 'Diminuer ou stabiliser les déplacements en voiture particulière', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.2.5.5', + nom: 'Obtenir un impact bénéfique de la programmation sur la diminution de la pollution atmosphérique', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_1.2.3', + nom: 'Définir et mettre en oeuvre la stratégie de prévention et de gestion des déchets', + points: 10, + pourcentage: 22.727272727272727, + actions_enfant: [ + { + action_id: 'cae_1.2.3.1', + nom: 'Définir une stratégie de prévention et de gestion des déchets et sensibiliser les acteurs à la prévention et au tri des déchets', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_1.2.3.1.1', + nom: 'Communiquer régulièrement vers la population et les acteurs socio-économiques pour inciter à la réduction des déchets', + points: 0.33333333333333337, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.1.2', + nom: 'Pratiquer et rendre visible la collecte séparée des emballages et papiers dans tous les lieux publics', + points: 0.33333333333333337, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.1.3', + nom: "Disposer d'un programme local de prévention", + points: 0.33333333333333337, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.1.4', + nom: 'Établir un règlement de collecte, suivre les coûts du service, établir un rapport annuel sur les coûts et performances du service', + points: 0.33333333333333337, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.1.5', + nom: 'Suivre les coûts du service, établir un rapport annuel sur les coûts et performances du service', + points: 0.33333333333333337, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.1.6', + nom: 'Prévenir (sensibilisation des agents, des services, etc.) et gérer les déchets conforme à la réglementation, réemployer et recycler les déchets occasionnés par les construction/déconstruction des bâtiments, respecter l’obligation de tri 5 flux pour les services (inter)communaux.', + points: 0.33333333333333337, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.3.2', + nom: 'Mettre en œuvre une politique locale de prévention et de gestion des déchets ambitieuse et tournée vers l’économie circulaire', + points: 5, + pourcentage: 50, + actions_enfant: [ + { + action_id: 'cae_1.2.3.2.1', + nom: 'Engager des actions allant au-delà des obligations réglementaires et mobiliser les acteurs pour réduire, réutiliser, réparer, recycler, valoriser les ressources/les déchets', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.10', + nom: 'Animer les entreprises du territoire (compétence collecte)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.11', + nom: 'Etudier la fréquence, les itinéraires de collecte et la motorisation des véhicules dédiés à la collecte des déchets (compétence collecte)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.12', + nom: 'Mettre en place une tarification incitative à la prévention et au recyclage (compétence traitement)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.13', + nom: 'Insérer des clauses de réduction annuelle des quantités incinérées et enfouies dans les contrats de Délégation de Service Public (DSP) (compétence traitement)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.14', + nom: 'Augmenter le recyclage / les nouvelles filières de valorisation matière (hors TMB) (plâtre, encombrants, meubles/bois) (compétence traitement)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.15', + nom: 'Etendre les consignes de tri à tous les plastiques (compétence traitement)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.16', + nom: 'Privilégier les débouchés locaux pour minimiser le transport et permettre un développement économique local (compétence traitement)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.17', + nom: 'Tri des macro-déchets en amont des incinérateurs et décharges pour retirer ceux qui peuvent être recyclés (compétence traitement)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.18', + nom: "Disposer d'une installation de valorisation des déchets organiques (compostage ou méthanisation) (compétence traitement)", + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.19', + nom: 'Etudier et mettre en place les transferts possibles par voie ferroviaire ou fluviale des déchets entre les sites de regroupement et les sites de traitement (compétence traitement)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.2', + nom: 'Engager une démarche de prévention ambitieuse', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.20', + nom: 'Mettre en place des actions de prévention et de réduction des déchets au sein des services (hors compétences collecte et traitement)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.21', + nom: 'Animer les entreprises du territoire', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.22', + nom: "Prendre en compte l'objectif national de recycler 70% des déchets du BTP et mettre en œuvre des actions pour y contribuer", + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.3', + nom: 'Travailler en étroite collaboration avec ses partenaires et participer à la construction des objectifs de la stratégie et du programme d’actions en cas de transfert de compétences (partiel ou total)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.4', + nom: 'Mettre en place la tarification incitative (compétence collecte)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.5', + nom: 'Favoriser le réemploi et la réutilisation (compétence collecte)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.6', + nom: 'Développer les zones de réemploi en déchèterie et/ou accompagner la création d’une recyclerie attenante à une déchèterie, etc. (compétence collecte)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.7', + nom: 'Optimiser le service de collecte (compétence collecte)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.8', + nom: 'Mettre en œuvre des filière réemploi ou de nouvelles filières de recyclage en déchèterie (compétence collecte)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.2.9', + nom: 'Définir la limite du service public et articuler public/offre privée (compétence collecte)', + points: 0.2272727272727273, + pourcentage: 4.545454545454546, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.3.3', + nom: 'Suivre annuellement et atteindre les objectifs', + points: 3, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_1.2.3.3.1', + nom: 'Produire moins de déchets ménagers et assimilés que la moyenne nationale, voire moins que les territoires pionniers en France', + points: 1, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.3.2', + nom: 'Diminuer la production des déchets ménagers et assimilés', + points: 0.5, + pourcentage: 16.666666666666664, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.3.3', + nom: 'Produire moins d’ordures ménagères résiduelles que la moyenne nationale, voire moins que les territoires pionniers en France', + points: 0.5, + pourcentage: 16.666666666666664, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.3.4', + nom: 'Atteindre un % de valorisation matière et organique des déchets ménagers et assimilés supérieur à la moyenne nationale, voire supérieur au meilleur score Territoire Engagé Climat-Air-Énergie', + points: 0.5, + pourcentage: 16.666666666666664, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.3.3.5', + nom: 'Progresser dans le taux de recyclage des déchets du BTP', + points: 0.5, + pourcentage: 16.666666666666664, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_1.2.4', + nom: 'Planifier la rénovation des bâtiments résidentiels et tertiaires et la construction durable sur le territoire', + points: 12, + pourcentage: 27.27272727272727, + actions_enfant: [ + { + action_id: 'cae_1.2.4.1', + nom: 'Prendre en compte les enjeux climat-air-énergie dans la stratégie "habitat"', + points: 1.8, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_1.2.4.1.1', + nom: "Disposer d'un Programme Local de l'Habitat (PLH) n’ayant pas plus de 6 ans et anticiper son renouvellement", + points: 0.36, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.4.1.2', + nom: "Prendre en compte les enjeux environnementaux dans le programme local de l'habitat (PLH)", + points: 0.36, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.4.1.3', + nom: "Intégrer dans le diagnostic du Programme Local de l'Habitat (ou équivalent) des éléments sur la performance énergétique du parc bâti", + points: 0.36, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.4.1.4', + nom: "Indiquer la rénovation thermique de l'habitat comme un objectif prioritaire du Programme Local de l'Habitat", + points: 0.36, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.4.1.5', + nom: "Identifier l'adaptation au changement climatique (et plus particulièrement le confort d'été) comme une thématique à fort enjeu", + points: 0.36, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.4.2', + nom: "Disposer d'une stratégie pour la rénovation des locaux tertiaires", + points: 1.2, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_1.2.4.2.1', + nom: "Disposer d'un diagnostic sur l'état du parc bâti tertiaire du territoire", + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.4.2.2', + nom: "Disposer d'un document cadre visant à qualifier/inciter la construction et la rénovation performante des locaux tertiaires", + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.4.3', + nom: 'Construire la politique sur le bâtiment de façon transversale et intégrée avec les autres thématiques et acteurs', + points: 3, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_1.2.4.3.1', + nom: 'Mobiliser les parties prenantes de son territoire directement concernées par la construction et la rénovation performante (BBC ou équivalent) pour construire sa politique', + points: 0.6, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.4.3.2', + nom: 'Limiter l’étalement urbain de la politique de l’habitat et du tertiaire', + points: 0.6, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.4.3.3', + nom: "Définir des zones préférentielles de développement dans le Programme Local de l'Habitat cohérentes avec la mobilité durable", + points: 0.6, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.4.3.4', + nom: 'Contextualiser et prioriser la politique de la collectivité par rapport aux enjeux forts/spécifiques du territoire', + points: 0.6, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.4.3.5', + nom: "Faciliter l’appropriation par les communes (déclinaison des objectifs, articulation avec les PLU et les projets communaux, travail d'animation)", + points: 0.6, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.4.4', + nom: 'Fixer des niveaux de performance élevés à atteindre pour les constructions et les rénovations des bâtiments', + points: 2.4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_1.2.4.4.1', + nom: "Fixer des objectifs chiffrés en matière de rénovation thermique et de construction neuve dans le Programme Local de l'Habitat (ou équivalent)", + points: 0.48, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.4.4.2', + nom: "Faire référence à des labels de performance dans le Programme Local de l'Habitat (ou équivalent)", + points: 0.48, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.4.4.3', + nom: 'Définir également des objectifs chiffrés et des critères de performance pour les bâtiments tertiaires', + points: 0.48, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.4.4.4', + nom: "Viser l'amélioration de la qualité de l'air intérieur des bâtiments", + points: 0.48, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.2.4.4.5', + nom: "Viser le confort d'été des bâtiments", + points: 0.48, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.4.5', + nom: 'Associer à la planification des dispositifs opérationnels et financiers', + points: 2.4, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.2.4.6', + nom: 'Observer et évaluer la progression de la construction et de la rénovation performante sur le territoire', + points: 1.2, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + { + action_id: 'cae_1.3', + nom: 'Urbanisme', + points: 26, + pourcentage: 26, + actions_enfant: [ + { + action_id: 'cae_1.3.1', + nom: "Utiliser les documents d'urbanisme pour assurer la mise en œuvre des objectifs climat-air-énergie et lutter contre l'artificialisation des sols", + points: 12, + pourcentage: 46.15384615384615, + actions_enfant: [ + { + action_id: 'cae_1.3.1.1', + nom: 'Organiser le pilotage des documents d’urbanisme', + points: 1.2, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_1.3.1.1.1', + nom: "Disposer d’un élu et si possible (selon la taille de la collectivité) d’un cadre responsable de l’urbanisme (urbaniste) ainsi que d'une commission politique ad hoc", + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.1.2', + nom: 'Intégrer l’élu en charge du Plan Climat dans la commission pré-citée', + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.1.3', + nom: 'Impliquer les autres élus concernés par l’aménagement du territoire', + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.1.4', + nom: 'Sensibiliser/former les élus et techniciens aux enjeux croisés de l’urbanisme durable et de l’énergie', + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.1.5', + nom: "Mobiliser l'ensemble des services techniques pour favoriser une approche transversale des politiques locales dans les documents d'urbanisme", + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.1.6', + nom: 'Travailler/Dialoguer régulièrement avec d’autres acteurs sur ce thème : EPCI, communes membres, agences d’urbanisme, bailleurs sociaux, chambres consulaires, CAUE, etc.', + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.3.1.2', + nom: 'Réaliser les études nécessaires à l’intégration des thématiques climat-air-énergie', + points: 2.4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_1.3.1.2.1', + nom: 'Réaliser des analyses croisées des enjeux climat-air-énergie et urbains', + points: 0.48, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.2.2', + nom: 'Utiliser des outils cartographiques pour illustrer les enjeux et les dynamiques de son territoire', + points: 0.48, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.2.3', + nom: 'Intégrer dans le rapport de présentation du PLU/SCOT un état des lieux de la situation en matière d’émissions de gaz à effet de serre, de consommations et productions énergétiques, d’émissions de polluants atmosphériques, des vulnérabilités climatiques', + points: 0.48, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.2.4', + nom: 'Analyser le potentiel de densification (identification des friches, des dents creuses, etc.)', + points: 0.48, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.2.5', + nom: "Disposer d'un inventaire des capacités de stationnement de véhicules motorisés, de véhicules hybrides et électriques et de vélos des parcs ouverts au public et des possibilités de mutualisation de ces capacités", + points: 0.48, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.3.1.3', + nom: 'Mettre la politique d’urbanisme et les objectifs de développement en cohérence avec la politique climat-air-énergie', + points: 2.4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_1.3.1.3.1', + nom: "Intégrer dans le PADD des engagements clairs pour l'adaptation et l'atténuation par rapport au changement climatique", + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.3.2', + nom: "Disposer d'une stratégie multicritère et prendre en compte les zones de bruits et les zones d’émissions de polluants atmosphériques pour limiter l’impact sur la population (évitement ou aménagements spécifiques pour limiter les nuisances)", + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.3.3', + nom: 'Articuler la stratégie d’urbanisme avec le schéma directeur de l’énergie s’il existe', + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.3.4', + nom: 'Identifier une hiérarchie de développement urbain en fonction d’un niveau de desserte en transports collectifs et/ou de voies pour modes actifs', + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.3.5', + nom: 'Lier la stratégie d’urbanisation avec la proximité et les capacités des autres réseaux (énergétique, eau/assainissement)', + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.3.6', + nom: 'Prioriser les dents creuses et les friches dans les stratégies d’aménagement pour limiter l’étalement urbain', + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.3.1.4', + nom: 'Transcrire les engagements climat-air-énergie dans les volets opposables des documents d’urbanisme', + points: 2.4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_1.3.1.4.1', + nom: "Utiliser les orientations d'aménagement et de programmation (OAP) du PLU pour favoriser le développement durable des secteurs clés", + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.4.2', + nom: 'Subdiviser les zones à urbaniser ou urbaines pour adapter finement le règlement à chaque zone à enjeu du territoire', + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.4.3', + nom: 'Comptabiliser et rationaliser les zones à ouvrir à l’urbanisation', + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.4.4', + nom: "Disposer de documents cartographiques déterminants mettant en évidence les secteurs pouvant faire l'objet de prescriptions énergétiques ou urbaines particulières, cartes stratégiques air, trame verte et bleue", + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.4.5', + nom: "Contribuer explicitement dans les règlement du PLU et le DOO du SCOT (en dictant certaines règles au PLU le cas échéant) à la lutte et à l'adaptation au changement climatique, ainsi qu'à la préservation de la qualité de l'air", + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.4.6', + nom: 'Utiliser les nouvelles possibilités Grenelle, ALUR et TECV', + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.3.1.5', + nom: 'Connaître et protéger les espaces naturels, agricoles et forestiers de l’artificialisation des sols via les documents d’urbanisme et la politique foncière associée', + points: 1.8, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_1.3.1.5.1', + nom: 'Réaliser un suivi (mutualisé à l’échelle intercommunale) du foncier et des bâtiments agricoles, réaliser des diagnostics fonciers participatifs', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.5.2', + nom: 'Afficher clairement la stratégie de protection des espaces naturels, agricoles et forestiers dans le PLU/SCOT (PADD)', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.5.3', + nom: "Reconnaître la valeur du foncier naturel, agricole, forestier dans les documents d'urbanisme et de planification", + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.5.4', + nom: "Limiter l’artificialisation des sols sur le long terme, avec la mise en place de dispositifs réglementaires de protection et d’outils d'intervention foncière", + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.3.1.6', + nom: 'Suivre des indicateurs relatifs à l’urbanisme durable et atteindre les objectifs fixés', + points: 1.8, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_1.3.1.6.1', + nom: 'Disposer d’un indicateur de compacité des formes urbaines qui évolue positivement', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.6.2', + nom: 'pas de diminution du % de surfaces naturelles et agricoles par rapport à la surface totale de la collectivité', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.6.3', + nom: 'Diminuer la surface annuelle artificialisée (moyenne sur plusieurs années si le suivi n’est pas annuel)', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.1.6.4', + nom: 'Atteindre les objectifs de modération de la consommation d’espace et de lutte contre l’étalement urbain fixés dans le PLU ou le SCOT', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_1.3.2', + nom: "Transcrire les enjeux climat-air-énergie et de préservation des ressources naturelles dans les opérations d'aménagement", + points: 10, + pourcentage: 38.46153846153847, + actions_enfant: [ + { + action_id: 'cae_1.3.2.1', + nom: 'S’organiser pour bien piloter les opérations d’aménagement', + points: 1, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_1.3.2.1.1', + nom: 'Mettre en place un Système de Management d’Opération (SMO) pour la conduite et le suivi des projets', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.2.1.2', + nom: 'Mettre en place un dialogue partenarial et pluridisciplinaire en interne et en externe (CAUE, ALEC, agence d’urbanisme, espace conseil France Rénov, …) institutionnalisé (convention ou autres dispositifs cadrant la relation)', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.2.1.3', + nom: 'Recourir à un assistant à maîtrise d’ouvrage doté de compétences climat-air-énergie si besoin de renforcer les compétences internes', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.3.2.2', + nom: 'Adopter une approche multithématique dans le diagnostic et la conception des projets urbains', + points: 1, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_1.3.2.2.1', + nom: "Demander une approche intégrée de type AEU2 pour une analyse croisée des enjeux climat-air-énergie et urbains pour tous les projets d'urbanisme opérationnel maîtrisés par la collectivité", + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.2.2.2', + nom: 'Réaliser des études de prédéfinition des projets urbains et étude de l’approvisionnement énergétique et des productions d’énergie (y compris potentiel de développement des énergies renouvelable) pour les sites à enjeux (friches qui se libèrent en centre-bourg ou ville, extensions urbaines prévues dans le document d’urbanisme, etc.)', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.2.2.3', + nom: "Utiliser des outils de modélisation climat-air-énergie (de type Analyse de Cycle Vie sur l'échelle quartier dès la conception) pour aider à la décision", + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.3.2.3', + nom: 'Elaborer un document "cadre" pour systématiser la qualité environnementale des opérations maîtrisées par la collectivité', + points: 1.5, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_1.3.2.3.1', + nom: 'Définir des préconisations à l’échelle du quartier ou de la ville inspirées notamment des outils nationaux existants (cahiers thématiques AEU2, label national Ecoquartier, HQE-Performance quartier…)', + points: 0.5, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.2.3.2', + nom: "Définir des critères à l’échelle du bâtiment : BEPos, label E+/C-, Maison passive, BBC, Effinergie, Ecodom, HQE avec objectifs énergie ou air définis, label bâtiment biosourcé, chauffage très performant (flamme verte 7 étoiles pour le bois ou équivalent) ou valorisation des rejets thermiques, confort d'été, qualité de l'air intérieur...", + points: 0.5, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.2.3.3', + nom: "Utiliser ce document comme base de discussions et de réflexions entre les acteurs et l'adapter/décliner dans différents documents de conception opérationnels des projets (plan masse, notice environnementale, cahier des charges, cahier de prescriptions...)", + points: 0.5, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.3.2.4', + nom: 'Assurer la maîtrise d’ouvrage publique ou semi-publique des opérations d’aménagement clés pour mieux prendre en compte les enjeux climat-air-énergie et la préservation des ressources naturelles', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_1.3.2.4.1', + nom: 'Mettre en place une politique foncière active (droit de préemption urbain, zone d’aménagement différé -ZAD-, participation à un établissement foncier local –EPFL-...)', + points: 1, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.2.4.2', + nom: "Intégrer des exigences climat-air-énergie dans les opérations d'aménagement clés (lotissements publics ou zones d’aménagement concertées) et les inscrire dans les cahiers des charges de cession de terrain", + points: 1, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.3.2.5', + nom: 'Intégrer des exigences climat-air-énergie dans tous les appels d’offre d’urbanisme et les cahiers des charges de cession des terrains', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_1.3.2.5.1', + nom: "Intègrer dans ses critères de choix des offres l'impact environnemental de la proposition : kWh économisé, émissions de CO2 ou émissions/exposition aux polluants atmosphériques, etc.", + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.2.5.2', + nom: 'Utiliser des spécifications techniques pour fixer des objectifs de performances environnementales, de manière prescriptive, à l’échelle de la ville, du quartier et du bâtiment.', + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.2.5.3', + nom: "Intègrer dans les critères de jugement des offres les références environnementales et les pratiques internes de l'entreprise candidate (expérience requise en HQE ou équivalent, label de performance énergétique, formation à l’AEU2, certification ISO 14001/9001 de l’entreprise, démarche d'éco-responsabilité interne...)", + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.2.5.4', + nom: 'Donner un caractère contraignant aux exigences (prescriptions et non simples recommandations, inscription dans les documents contractuels et opposables, contrôle, sanction prévue en cas de non-respect)', + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.3.2.6', + nom: "Organiser la gestion des déchets des chantiers d'aménagement en partenariat avec les aménageurs", + points: 0.5, + pourcentage: 5, + actions_enfant: [ + { + action_id: 'cae_1.3.2.6.1', + nom: "Fixer un objectif de recyclage à l'échelle des projets", + points: 0.25, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.2.6.2', + nom: "Mettre en place une plateforme locale de récupération/échanges de matériaux de construction / démolition ou de terres excavées (à l'échelle territoriale ou du projet)", + points: 0.25, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.3.2.7', + nom: 'Contrôler l’efficacité et le respect des exigences', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_1.3.2.7.1', + nom: "Diffuser réellement les documents cadres et référentiels créés dans les services, s'assurer qu'ils sont appropriés et appliqués par les acteurs concernés", + points: 0.4, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.2.7.2', + nom: "Mettre en place une approche d'amélioration continue pour améliorer les outils (référentiel, charte, etc.) selon le retour d'expérience", + points: 0.4, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.2.7.3', + nom: 'Prévoir le suivi réel des performances climat-air-énergie des bâtiments occupés pour certaines opérations emblématiques (instrumentation, prestation dédiée et soutenue/exigée par la collectivité)', + points: 0.4, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.2.7.4', + nom: "Montrer que l'intégration de critères environnementaux dans les consultations a déjà abouti réellement à faire basculer le choix en faveur du candidat le plus exemplaire sur ces aspects", + points: 0.4, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.2.7.5', + nom: 'Obtenir une reconnaissance nationale ou régionale d’une ou plusieurs opérations, certification d’une démarche (label économie circulaire, label éco-quartier…) ou de résultats obtenus, retombées presse ou visites de site par des acteurs extérieurs', + points: 0.4, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_1.3.3', + nom: 'Accompagner et contrôler les travaux de construction et de rénovation', + points: 4, + pourcentage: 15.384615384615385, + actions_enfant: [ + { + action_id: 'cae_1.3.3.1', + nom: 'Organiser toute la chaîne des acteurs en charge de l’instruction à l’octroi des permis de construire pour une attention accrue sur la thématique climat-air-énergie', + points: 1.2, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_1.3.3.1.1', + nom: "Disposer d'une organisation claire avec responsabilités attribuées (interne et/ou externe)", + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.3.1.2', + nom: "Associer le service “énergie” qui formule un avis sur l'autorisation d'urbanisme", + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.3.1.3', + nom: 'Adopter des directives, instructions de service, cahiers des charges énergie/environnement pour les instructeurs, formulaires appropriés', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.3.1.4', + nom: 'Former/Sensibiliser les instructeurs et/ou tout autre personne en contact avec les pétitionnaires (secrétaire de mairie)', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.3.1.5', + nom: "Mettre en place d'aires de mise en valeur de l’architecture et du patrimoine (AVAP) pour établir un consensus en amont dans les secteurs où la protection du patrimoine architectural représente un frein fort à la rénovation énergétique du bâti", + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.3.3.2', + nom: 'Diffuser de l’information à l’occasion des demandes d’autorisation', + points: 0.4, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_1.3.3.2.1', + nom: 'Joindre aux formulaires de demande de permis de construire des plaquettes de présentation des acteurs ressources du territoire sur le logement (espace conseil France Rénov, CAUE, ADIL...) ou de recommandations (avec exemples locaux)', + points: 0.2, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.3.2.2', + nom: 'Prendre des rendez-vous avec un conseiller France Rénov ou le CAUE pour chaque demande de permis de construire', + points: 0.2, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.3.3.3', + nom: 'Vérifier le respect des exigences autant que possible', + points: 1.6, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'cae_1.3.3.3.1', + nom: 'Surveiller le respect de la réglementation thermique (pour les éléments visibles sur les plans et via les attestations de conformité) et prendre en compte les vulnérabilités du territoire au changement climatique', + points: 0.2666666666666667, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.3.3.2', + nom: 'Surveiller le respect des prescriptions en matière de mobilité dans les contrats de droits privés', + points: 0.2666666666666667, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.3.3.3', + nom: 'Surveiller les pièces justificatives du respect des critères de performance environnementale dans le cas de la bonification des droits à construire', + points: 0.2666666666666667, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.3.3.4', + nom: 'Effectuer au moins deux contrôles par an sur le terrain par instructeur', + points: 0.2666666666666667, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.3.3.5', + nom: 'Porter attention à la rénovation embarquée (vérification des justifications)', + points: 0.2666666666666667, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_1.3.3.3.6', + nom: 'Renvoyer vers les structures compétentes pour effectuer le suivi des consommations énergétiques avant et après travaux', + points: 0.2666666666666667, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_1.3.3.4', + nom: 'Suivre les attestations de conformité', + points: 0.8, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + ], + level: 1, + action_type: ActionType.AXE, + }, + { + action_id: 'cae_2', + nom: 'Patrimoine de la collectivité', + points: 64, + pourcentage: 12.8, + actions_enfant: [ + { + action_id: 'cae_2.1', + nom: 'Suivi et stratégie patrimoniale', + points: 24, + pourcentage: 37.5, + actions_enfant: [ + { + action_id: 'cae_2.1.1', + nom: 'Mettre en place une comptabilité énergétique et des émissions de GES des bâtiments publics', + points: 10, + pourcentage: 41.66666666666667, + actions_enfant: [ + { + action_id: 'cae_2.1.1.1', + nom: 'Mettre en place un socle de connaissance initiale sur son patrimoine', + points: 1.5, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_2.1.1.1.1', + nom: 'Établir une liste de tous les bâtiments et équipements', + points: 0.2142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.1.2', + nom: "Réaliser l'inventaire des contrats d’exploitation ou de maintenance de chaque bâtiment, et des principaux travaux effectués depuis leur livraison", + points: 0.2142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.1.3', + nom: 'Identifier les gros consommateurs (viser les bâtiments générant 50% des consommations) et réaliser un audit énergétique.', + points: 0.2142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.1.4', + nom: 'Effectuer un relevé des surfaces chauffées et/ou climatisées', + points: 0.2142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.1.5', + nom: "Identifier tous les contrats de fourniture d'énergie", + points: 0.2142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.1.6', + nom: "Saisir toutes les factures d'énergie des 3 dernières années (ou demander aux gestionnaires du réseau de distribution un détail pluriannuel des consommations des bâtiments de la collectivité si pas de suivi existant)", + points: 0.2142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.1.7', + nom: 'Partager et co-construire les objectifs et le diagnostic avec les partenaires si la gestion des bâtiments est déléguée', + points: 0.2142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.1.2', + nom: 'S’organiser pour effectuer le suivi régulier des consommations énergétiques du patrimoine bâti', + points: 0.5, + pourcentage: 5, + actions_enfant: [ + { + action_id: 'cae_2.1.1.2.1', + nom: "Déterminer la personne/structure chargée d'effectuer le relevé de la consommation énergétique (tous les agents énergétiques)", + points: 0.125, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.2.2', + nom: "Déterminer la personne/structure à qui il faut transmettre la consommation d'énergie pour la détermination de l'indice énergétique", + points: 0.125, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.2.3', + nom: 'Mener une réflexion sur le type et le positionnement des compteurs et sous-compteurs', + points: 0.125, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.2.4', + nom: 'Indiquer les tâches dans la fiche de poste gestionnaire des bâtiments et équipements', + points: 0.125, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.1.3', + nom: 'Faire un bilan complet, allant au-delà de la réglementation', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.1.1.3.1', + nom: "Augmenter chaque année la part de bâtiments diagnostiqués, jusqu'à connaissance quasi-totale du patrimoine", + points: 0.25, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.3.2', + nom: 'Élargir le bilan aux bâtiments communaux pour les EPCI, notamment en zone rurale ou faiblement dotés en patrimoine', + points: 0.25, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.3.3', + nom: 'Corriger les indices énergétiques du climat (chaleur ou besoin en climatisation), et les décomposer en chaleur/froid, électricité, CO2', + points: 0.25, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.3.4', + nom: "Détailler l'analyse du type d'utilisation d'électricité", + points: 0.25, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.3.5', + nom: "Effectuer un relevé des consommations d'eau en distinguant les consommations d'eau chaude et en identifiant les principaux bâtiments appropriés à une production d'eau chaude solaire collective", + points: 0.25, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.3.6', + nom: 'Etudier les matériaux et les techniques de construction et de finition', + points: 0.25, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.3.7', + nom: "Réaliser un bilan initial de la qualité de l'air intérieur des bâtiments, identifier les éléments ou comportements émissifs ou dégradant la qualité de l'air", + points: 0.25, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.3.8', + nom: "Compléter l'analyse par des visites et des entretiens avec les utilisateurs", + points: 0.25, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.1.4', + nom: 'Effectuer un suivi des consommations régulier et multi-flux', + points: 1.5, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_2.1.1.4.1', + nom: 'Saisir tous les gros consommateurs', + points: 0.5, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.4.2', + nom: 'Effectuer le relevé chaque mois pour les bâtiments les plus consommateurs/les grandes installations ; effectuer des relevés périodiques pour les installations plus petites (surface chauffée < 500 m2).', + points: 0.5, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.4.3', + nom: "Mesurer régulièrement la qualité de l'air intérieur (a minima mesure du confinement via indicateur du CO2 une fois par an) dans les bâtiments abritant des populations sensibles. Aller au-delà du renouvellement de la surveillance règlementaire tous les 7 ans dans les ERP.", + points: 0.5, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.1.5', + nom: 'Elargir le périmètre des bâtiments pris en compte', + points: 0.5, + pourcentage: 5, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.1.6', + nom: "Optimiser le suivi, l'entretien et l'exploitation des installations techniques", + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.1.1.6.1', + nom: "Assurer l'optimisation de l'exploitation par un spécialiste au cours des 4 dernières années", + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.6.2', + nom: 'Intégrer des clauses d’intéressement aux contrats d’exploitation/maintenance des installations techniques d’énergie', + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.6.3', + nom: 'Confier une mission de suivi d’exploitation à un bureau d’étude pour les collectivités non dotées des compétences suffisantes en interne', + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.6.4', + nom: 'Mettre en place un outil performant de suivi lorsque le patrimoine le justifie (bâtiments complexes, consommations importantes)', + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.1.7', + nom: 'Communiquer', + points: 1, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_2.1.1.7.1', + nom: "Afficher le diagnostic de performance énergétique (DPE) sur des bâtiments non concernés par l'obligation d'affichage", + points: 0.25, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.7.2', + nom: "Transmettre aux concierges, gardiens d'immeubles et/ou utilisateurs des bâtiments l'évaluation de la comptabilité énergétique (feed-back à leurs efforts)", + points: 0.25, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.7.3', + nom: 'Ajouter le reporting des consommations du patrimoine dans le rapport annuel Développement Durable, s’il existe.', + points: 0.25, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.1.7.4', + nom: "Faire un bilan annuel par bâtiment de la dépense d'énergie de la commune et en présenter une synthèse aux élus et aux services", + points: 0.25, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.1.8', + nom: "Identifier le potentiel d'économie (énergie et coût) et de développement des énergies renouvelables", + points: 1, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_2.1.2', + nom: 'Elaborer une stratégie patrimoniale incluant un programme de rénovation', + points: 8, + pourcentage: 33.33333333333333, + actions_enfant: [ + { + action_id: 'cae_2.1.2.1', + nom: 'Acter la volonté politique de mettre en place une stratégie patrimoniale ou un plan de rénovation', + points: 0.4, + pourcentage: 5, + actions_enfant: [ + { + action_id: 'cae_2.1.2.1.1', + nom: "Disposer d'une délibération politique", + points: 0.13333333333333336, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.2.1.2', + nom: "Disposer d'une décision budgétaire (enveloppe de travaux ou enveloppe d’ingénierie pour prestation externe d’élaboration de la stratégie)", + points: 0.13333333333333336, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.2.1.3', + nom: 'Affecter des ressources humaines en interne', + points: 0.13333333333333336, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.2.2', + nom: 'Mettre en œuvre une stratégie de rationalisation de son patrimoine', + points: 2.4, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_2.1.2.2.1', + nom: 'Réaliser l’état des lieux technique et des usages (occupation), des besoins et de leurs dynamiques, en intégrant les éléments renseignés sur la plateforme OPERAT dans le cadre des exigences du décret tertiaire', + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.2.2.2', + nom: 'Adopter et mettre en œuvre la stratégie de rationalisation avec des premières réalisations', + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.2.2.3', + nom: 'Parvenir à maîtriser les surfaces de son patrimoine, idéalement les réduire', + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.2.2.4', + nom: 'Réaffecter pour tout ou partie dans le programme de rénovation le produit des cessions', + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.2.3', + nom: 'Être ambitieux et opérationnel dans la stratégie de rénovation', + points: 2.4, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_2.1.2.3.1', + nom: 'Définir des objectifs de long terme (2050) et court moyen terme (2030) et tracer une trajectoire cible avec les rythmes et performances à atteindre pour la massification de la rénovation énergétique du patrimoine communal (objectifs quantifiés en nombre ou % de bâtiments à rénover, avec un échéancier) sur la base d’un état des lieux initial', + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.2.3.2', + nom: "Intégrer dans le programme d’actions des mesures d’urgence/court terme (les bâtiments principaux sont traités en priorité) et des mesures à long terme pour les équipements ayant un potentiel d'économie (type de mesures, coûts prévus, moment de la mise en œuvre) ainsi qu'une estimation des potentiels d'économie d’énergie et de gaz à effet de serre et une estimation de la production d’énergies renouvelables générée", + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.2.3.3', + nom: 'Associer le programme à une programmation pluriannuelle des investissements (PPI)', + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.2.3.4', + nom: 'Viser a minima le niveau BBC-rénovation en Métropole (éventuellement en plusieurs étapes « BBC-compatibles ») et une consommation énergétique inférieure à 300 kWhEP/m².an dans les DOM (correspondant à la classe A du DPE-G pour les bâtiments tertiaires existants sauf santé et hôtels) pour les rénovations', + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.2.4', + nom: 'Elaborer la stratégie dans une approche transversale climat-air-énergie', + points: 1.2, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_2.1.2.4.1', + nom: "Prévoir des travaux permettant une meilleure adaptation du bâti au changement climatique (confort d'été, risques naturels...)", + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.2.4.2', + nom: "Limiter les antagonismes entre l'amélioration de la performance énergétique et la qualité de l'air intérieur et extérieur", + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.2.4.3', + nom: 'Favoriser le recours aux filières locales d’écorénovation, contribuer à la montée en compétences des professionnels locaux', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.2.5', + nom: 'Étudier des moyens de financement innovants pour la mise en œuvre du plan pluriannuel de travaux', + points: 0.8, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_2.1.2.5.1', + nom: 'Utiliser les Certificats d’Economie d’Énergie (CEE)', + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.2.5.2', + nom: 'Mettre en œuvre un contrat de performance énergétique (CPE), par exemple via un marché public de partenariat énergétique', + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.2.5.3', + nom: 'Mettre en œuvre un dispositif de type INTRACTING, forme de convention de performance interne à la collectivité (CPE interne)', + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.2.5.4', + nom: 'Instaurer un fonds local d’aide aux travaux via les ressources issues du développement des énergies renouvelables sur le territoire ou fonds d’amorçage gérés par l’EPCI', + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.2.6', + nom: 'Suivre et adapter le plan pluriannuel de travaux', + points: 0.8, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_2.1.2.6.1', + nom: 'Renforcer le suivi énergétique des bâtiments concernés par le plan (si la compétence gestion et suivi est déléguée, la collectivité suit activement les activités du gestionnaire et dispose d’une vision de la situation existante). Le suivi est a minima annuel pour les bâtiments ciblés par le décret tertiaire.', + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.2.6.2', + nom: "Suivre un ratio financier sur l'effort de rénovation en euros travaux/m² de surface totale (bâtiments régulés thermiquement)", + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.2.6.3', + nom: 'Vérifier l’atteinte des objectifs du plan et adapter/renforcer les actions si nécessaire', + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.2.6.4', + nom: "Mettre en évidence et communiquer sur les économies d'énergie et réduction de GES engendrées par les actions effectuées", + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_2.1.3', + nom: 'Etre exemplaire sur les bâtiments publics neufs et rénovés', + points: 6, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_2.1.3.1', + nom: 'Délibérer et inscrire les niveaux de performance dans un document cadre', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_2.1.3.1.1', + nom: 'Décider de la réalisation', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.1.2', + nom: 'Elaborer un document "cadre" pour la qualité environnementale de ses bâtiments', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.3.2', + nom: 'Définir des règles d’usages des bâtiments publics', + points: 0.6, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.3.3', + nom: 'Définir des niveaux de performances ambitieux', + points: 1.8, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_2.1.3.3.1', + nom: 'Les constructions neuves sont passives ou à énergie positive et à haute performance environnementale', + points: 0.15000000000000002, + pourcentage: 8.333333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.3.10', + nom: 'Des mesures sur l’éclairage sont prises', + points: 0.15000000000000002, + pourcentage: 8.333333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.3.11', + nom: 'La végétalisation des abords, voire des murs ou des toitures, est privilégiée (dans une approche multicritère dans le choix des essences : risques d’allergies, biodiversité, production alimentaire, entretien…)', + points: 0.15000000000000002, + pourcentage: 8.333333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.3.12', + nom: 'Si existant et si nécessaire en fonction des besoins du bâtiment, le raccordement à un réseau de chaleur/froid utilisant des énergies renouvelables a été pris en compte', + points: 0.15000000000000002, + pourcentage: 8.333333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.3.2', + nom: 'Les rénovations visent un niveau de consommation à atteindre', + points: 0.15000000000000002, + pourcentage: 8.333333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.3.3', + nom: 'Les niveaux de performances et les pratiques recommandées font référence à des labels ou référentiels de qualité reconnus au niveau national ou régional', + points: 0.15000000000000002, + pourcentage: 8.333333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.3.4', + nom: 'Le confort d’été est pris en compte mais le recours à la climatisation est limité en été, notamment par l’architecture bioclimatique et l’optimisation de la ventilation naturelle (brasseur d’air).', + points: 0.15000000000000002, + pourcentage: 8.333333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.3.5', + nom: 'Les risques amplifiés par le changement climatique (risques inondations ou retrait-gonflement des argiles par exemple) sont pris en compte de manière forte dans la conception des bâtiments pour limiter leur vulnérabilité', + points: 0.15000000000000002, + pourcentage: 8.333333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.3.6', + nom: 'Les matériaux utilisés ont une faible énergie grise, sont locaux, recyclés ou recyclables facilement', + points: 0.15000000000000002, + pourcentage: 8.333333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.3.7', + nom: 'Les chantiers sont respectueux de l’environnement', + points: 0.15000000000000002, + pourcentage: 8.333333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.3.8', + nom: 'Des mesures en faveur de la qualité de l’air intérieur sont prises', + points: 0.15000000000000002, + pourcentage: 8.333333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.3.9', + nom: 'Des mesures sur les économies d’eau et la gestion des eaux pluviales ont été prises', + points: 0.15000000000000002, + pourcentage: 8.333333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.3.4', + nom: 'Construire ou rénover un ou des bâtiments exemplaires', + points: 1.8, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_2.1.3.4.1', + nom: 'Le(s) bâtiment(s) concerné(s) respecte(nt) les niveaux de performance fixées dans le document cadre, voire au-delà', + points: 0.9, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.4.2', + nom: 'L’opération a été l’occasion de former des professionnels et de sensibiliser les habitants', + points: 0.9, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.3.5', + nom: 'Intégrer ces niveaux de performance dans les appels d’offres', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_2.1.3.5.1', + nom: "Intégrer dans les critères de choix des offres, l'analyse du cycle de vie comme outil d'aide à la décision pour les constructions ou les rénovations", + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.5.2', + nom: 'Utiliser des spécifications techniques pour fixer des objectifs de performances environnementales, de manière prescriptive', + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.5.3', + nom: "Intégrer dans les critères de jugement des offres les références environnementales et les pratiques internes de l'entreprise candidate", + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.5.4', + nom: 'Le niveau de performance doit être supérieur au niveau réglementaire en vigueur', + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.5.5', + nom: "L'intégration de critères environnementaux dans les consultations a déjà abouti réellement à faire basculer le choix en faveur du candidat le plus exemplaire sur ces aspects", + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.1.3.6', + nom: 'Généraliser les opérations exemplaires et diffuser les bonnes pratiques', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_2.1.3.6.1', + nom: 'Mettre en place un système de management pour le suivi des projets de construction et de rénovation (responsabilités, pilotage, tableau de bord, suivi...)', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.6.2', + nom: 'Diffuser réellement les documents cadres et référentiels créés dans les services, appropriés par les acteurs concernés, et appliqués systématiquement', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.6.3', + nom: 'Veiller à la qualité environnementale du/des projets', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.1.3.6.4', + nom: "Inciter et encourager les communes de l'intercommunalité à mettre en place des projets exemplaires (diffusion documents cadres, guides d’usages, objectifs, etc).", + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + { + action_id: 'cae_2.2', + nom: 'Valeurs cibles énergétiques et climatiques', + points: 30, + pourcentage: 46.875, + actions_enfant: [ + { + action_id: 'cae_2.2.1', + nom: "Augmenter l'efficacité énergétique pour la chaleur et le rafraîchissement des bâtiments publics", + points: 6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.2.1.1', + nom: 'Mettre en place des actions de sobriété pour limiter les besoins en chauffage et climatisation', + points: 0.9, + pourcentage: 15, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.1.2', + nom: "Mettre en place des indicateurs en kWh/m2/an d'énergie primaire par catégories de bâtiments pour les usages chaleur/rafraîchissement et les comparer avec des valeurs de références locales", + points: 0.3, + pourcentage: 5, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.1.3', + nom: 'Mettre en place des actions d’efficacité énergétique pour la chaleur et le rafraîchissement du patrimoine spécifique', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_2.2.1.3.1', + nom: 'Mener des études spécifiques pour diminuer les consommations de ces équipements et mettre en place des actions', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.2.1.3.2', + nom: 'Favoriser des installations de production de froid performantes', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.1.4', + nom: 'Rénover les bâtiments les plus énergivores', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.2.1.4.1', + nom: 'Ne plus avoir de bâtiments de catégorie F ou G (DPE énergie)', + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.2.1.4.2', + nom: 'Posséder au moins 30% de bâtiment en classe A ou B à court terme', + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.1.5', + nom: 'Constater la baisse des consommations moyennes globales des bâtiments publics', + points: 3, + pourcentage: 50, + actions_enfant: [ + { + action_id: 'cae_2.2.1.5.1', + nom: 'Diminuer ses consommations en kWh/hab (kWh/m² pour les EPCI)', + points: 1.5, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.2.1.5.2', + nom: 'Inscrire cette diminution dans le rythme imposé par le décret tertiaire', + points: 1.5, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_2.2.2', + nom: "Augmenter l'efficacité énergétique pour l'électricité des bâtiments publics", + points: 6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.2.2.1', + nom: 'Mettre en place des actions de sobriété pour limiter les besoins en électricité', + points: 0.9, + pourcentage: 15, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.2.2', + nom: "Mettre en place des indicateurs en kWh/m2/an d'énergie primaire par catégories de bâtiments pour les usages électriques et les comparer avec des valeurs de références locales.", + points: 0.3, + pourcentage: 5, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.2.3', + nom: 'Mettre en place des actions d’efficacité énergétique sur l’électricité pour le patrimoine spécifique', + points: 0.6, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.2.4', + nom: 'Rénover les bâtiments les plus énergivores', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.2.2.4.1', + nom: 'Ne plus avoir de bâtiments de catégorie F ou G (DPE énergie)', + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.2.2.4.2', + nom: 'Posséder au moins 30% de bâtiment en classe A ou B à court terme', + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.2.5', + nom: 'Constater la baisse des consommations moyennes globales des bâtiments publics', + points: 3, + pourcentage: 50, + actions_enfant: [ + { + action_id: 'cae_2.2.2.5.1', + nom: 'Diminuer ses consommations en kWh/hab (kWh/m² pour les EPCI)', + points: 1.5, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.2.2.5.2', + nom: 'Inscrire cette diminution dans le rythme imposé par le décret tertiaire', + points: 1.5, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_2.2.3', + nom: 'Augmenter la part de consommation en énergies renouvelables et de récupération pour la chaleur et le rafraîchissement des bâtiments publics', + points: 6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.2.3.1', + nom: 'Utiliser les énergies renouvelables et de récupération locales en priorité (selon gisement)', + points: 0.9, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_2.2.3.1.1', + nom: 'Mobiliser le potentiel de récupération de chaleur fatale dans et à proximité du patrimoine de la collectivité', + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.2.3.1.2', + nom: "Favoriser le recours à la géothermie profonde s'il y a un gisement", + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.2.3.1.3', + nom: "Privilégier le bois local si la collectivité dispose de chaufferies bois pour ses bâtiments et équipements : suivi d'un indicateur pour la part de bois local dans l'approvisionnement (issu d'un rayon d'approvisionnement de 100 km max.)", + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.3.2', + nom: 'Si la collectivité dispose de chaufferies bois pour ses bâtiments et équipements, privilégier le bois certifié', + points: 0.3, + pourcentage: 5, + actions_enfant: [ + { + action_id: 'cae_2.2.3.2.1', + nom: 'Obtenir une certification du bois local au minimum au niveau moyen régional', + points: 0.15, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.2.3.2.2', + nom: 'Le bois importé provient à 100% de forêts gérées durablement (PEFC, FSC...)', + points: 0.15, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.3.3', + nom: "Prendre en compte la qualité de l'air dans ses choix", + points: 0.3, + pourcentage: 5, + actions_enfant: [ + { + action_id: 'cae_2.2.3.3.1', + nom: 'Privilégier lorsque cela est possible la chaleur sans combustion comme la récupération de chaleur fatale (cf. mesure 3.2.1), la géothermie, le solaire...', + points: 0.15, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.2.3.3.2', + nom: 'Porter une attention particulière au traitement des fumées des installations biomasse collective, allant au-delà de la réglementation', + points: 0.15, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.3.4', + nom: 'Suivre et atteindre une part d’énergie renouvelable et de récupération conséquente pour la chaleur et le rafraîchissement des bâtiments publics', + points: 4.5, + pourcentage: 75, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_2.2.4', + nom: "Augmenter la part de consommation en énergies renouvelables pour l'électricité des bâtiments publics", + points: 6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.2.4.1', + nom: 'Délibérer et monter en compétences sur le sujet', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.2.4.1.1', + nom: "Avoir délibéré sur la décision de construire des installations de production d'électricité, en précisant le financement prévu", + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.2.4.1.2', + nom: "Prendre connaissance des différentes offres existantes des fournisseurs d'électricité et s'organiser pour consulter le marché", + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.4.2', + nom: 'Installer des équipements de production d’électricité renouvelable', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.2.4.2.1', + nom: "Avoir des installations de production d'électricité renouvelable existantes", + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.2.4.2.2', + nom: 'Vendre prioritairement à des acteurs (acheteurs, fournisseurs) proposant une offre renouvelable de haute qualité', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.2.4.2.3', + nom: 'Etudier l’auto-consommation et la mettre en œuvre sur les installations où elle est pertinente', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.2.4.2.4', + nom: 'Dans les DOM, installer ou favoriser les moyens de production avec stockage de l’électricité', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.4.3', + nom: 'Atteindre une part élevée d’électricité renouvelable produite par les installations de la collectivité', + points: 2.4, + pourcentage: 40, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.4.4', + nom: 'Acheter de l’électricité renouvelable', + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_2.2.5', + nom: 'Limiter les émissions de gaz à effet de serre des bâtiments publics', + points: 6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.2.5.1', + nom: 'Effectuer des bilans GES plus complets que la réglementation ne l’impose', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.2.5.1.1', + nom: "Fixer des cibles en termes d'émissions de GES pour les bâtiments non soumis aux règlementations thermiques ou au DPE (comme les piscines ou les patinoires)", + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.2.5.1.2', + nom: "Aller plus loin que le DPE ou le bilan GES « patrimoine et compétences » réglementaires pour effectuer le bilan GES de ses bâtiments (bilan GES sur émissions directes et indirectes en distinguant par exemple les usages de l'électricité)", + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.5.2', + nom: 'Limiter les émissions de GES liées à la production de froid', + points: 1.8, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_2.2.5.2.1', + nom: 'Etudier des dispositifs bioclimatiques et tous les paramètres du confort thermique pour limiter le recours à la climatisation.', + points: 0.9, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.2.5.2.2', + nom: 'Porter une attention particulière au pouvoir de réchauffement global (PRG) des fluides frigorigènes utilisés, à la qualité des opérations de maintenance (installateur qualifié, suivi des quantités de fluides rechargées, récupération des fluides, pertes minimes...) et au traitement en fin de vie de ces équipements.', + points: 0.9, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.5.3', + nom: 'Réduire les émissions de GES sur l’ensemble du cycle de vie des bâtiments publics', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_2.2.5.3.1', + nom: 'Evaluer des émissions de GES liés aux produits et matériaux de construction utilisés dans les bâtiments publics', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.2.5.3.2', + nom: "Utiliser l'analyse du cycle de vie comme outil d'aide à la décision pour les constructions ou les rénovations", + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.5.4', + nom: 'Réduire la part des bâtiments F ou G (classification DPE pour les gaz à effet de serre) en rénovant les bâtiments les plus énergivores', + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.2.5.5', + nom: 'Augmenter la part des bâtiments A ou B (classification DPE pour les gaz à effet de serre)', + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + { + action_id: 'cae_2.3', + nom: "Eclairage public et économie d'eau dans les bâtiments", + points: 10, + pourcentage: 15.625, + actions_enfant: [ + { + action_id: 'cae_2.3.1', + nom: "Optimiser l'éclairage public", + points: 6, + pourcentage: 60, + actions_enfant: [ + { + action_id: 'cae_2.3.1.1', + nom: 'Réaliser un diagnostic de l’éclairage public', + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.3.1.2', + nom: 'Mettre en place des actions de sobriété sur l’éclairage public en priorité', + points: 0.9, + pourcentage: 15, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.3.1.3', + nom: 'Délibérer et mettre en œuvre un plan d’optimisation de l’éclairage public', + points: 2.4, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'cae_2.3.1.3.1', + nom: "Mettre en œuvre de mesures d'amélioration des performances issues du diagnostic", + points: 0.3, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.1.3.2', + nom: "Formaliser des exigences/objectifs en matière d'entretien/maintenance dans un document dédié (contrat de maintenance, régie...)", + points: 0.3, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.1.3.3', + nom: "Inscrire des mesures de limitation des consommations énergétiques dans un document formalisé, un plan pluriannuel d’optimisation (Schéma directeur d'aménagement lumière / Plan lumière, Plan d’aménagement Lumière ou autre document...)", + points: 0.3, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.1.3.4', + nom: 'Porter une attention à la concertation avec la population et à la valorisation de la démarche', + points: 0.3, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.1.3.5', + nom: 'Identifier les enseignes lumineuses illégales et prendre des mesures d’accompagnement pour y remédier (prise en compte de l’énergie dans le règlement local de publicité quand il existe)', + points: 0.3, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.1.3.6', + nom: 'Intégrer une opération de portage collectif (EPCI, syndicat d’énergie, Agence locale de l’énergie) sur l’optimisation de l’éclairage public', + points: 0.3, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.1.3.7', + nom: 'Porter une attention au dimensionnement et à la performance des décorations de Noël', + points: 0.3, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.1.3.8', + nom: 'Respecter les prescriptions techniques de l’arrêté du 27 décembre 2018 relatif à la prévention, à la réduction et à la limitation des nuisances lumineuses', + points: 0.3, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.3.1.4', + nom: 'Suivre et atteindre les objectifs fixés en matière d’éclairage public', + points: 1.5, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_2.3.1.4.1', + nom: 'Comparer l’indicateur de consommation/habitant avec les valeurs de références (10% des points):', + points: 0.75, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.1.4.2', + nom: 'Suivre le coût total et le coût rapporté à l’habitant de l’éclairage public (dépenses énergétiques)', + points: 0.75, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_2.3.2', + nom: "Economiser l'eau dans les bâtiments publics", + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.3.2.1', + nom: 'Réaliser un diagnostic précis des consommations d’eau et des conduites d’eau de l’ensemble des bâtiments publics et des grands consommateurs', + points: 0.4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.3.2.1.1', + nom: "Réaliser un diagnostic des consommations d'eau de chaque bâtiment public et des grands consommateurs (fontaines, piscines, etc.)", + points: 0.2, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.2.1.2', + nom: 'Equiper les compteurs des bâtiments publics de télé-relève', + points: 0.2, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.3.2.2', + nom: 'Formaliser l’engagement de la collectivité à réduire ses consommations', + points: 0.1, + pourcentage: 5, + actions_enfant: [ + { + action_id: 'cae_2.3.2.2.1', + nom: "Décider de l'installation des appareils et robinets économes en eau", + points: 0.03333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.2.2.2', + nom: "Décider de vérifier et d'optimiser continuellement la consommation d'eau", + points: 0.03333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.2.2.3', + nom: "S'engager pour un objectif chiffré de réduction des consommations d'eau", + points: 0.03333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.3.2.3', + nom: 'Sensibiliser et informer les utilisateurs des bâtiments publics', + points: 0.1, + pourcentage: 5, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.3.2.4', + nom: 'Mettre en œuvre les actions et suivre les consommations', + points: 0.8, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'cae_2.3.2.4.1', + nom: 'Relever des valeurs de consommations à une fréquence qui dépend de la consommation', + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.2.4.2', + nom: "Installer les appareils et robinets économes dans les bâtiments de la collectivité les plus consommateurs d'eau", + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.2.4.3', + nom: 'Identifier un service technique pour effectuer les réparations en cas de fuite', + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.2.4.4', + nom: 'Porter une attention particulière sur les piscines', + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.2.4.5', + nom: 'Régler les poussoirs sur des durées courtes dans les bâtiments accueillant du jeune public et éduquer les enfants à économiser l’eau (et ne pas jouer avec)', + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.2.4.6', + nom: "Récupérer les eaux pluviales en toiture pour l'utilisation dans le bâtiment ou les espaces verts", + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.3.2.5', + nom: 'Etre exemplaire sur les consommations d’eau', + points: 0.6, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_2.3.2.5.1', + nom: 'Diminuer les consommations/m2 par rapport aux années précédentes et communiquer officiellement (ex : rapport de développement durable, bilan énergie/GES...)', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.2.5.2', + nom: 'Pour les piscines, attester de leur performance par un suivi précis mensuel avec un indicateur adapté', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_2.3.3', + nom: 'Gérer sa voirie durablement', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.3.3.1', + nom: 'Connaître son patrimoine (voirie)', + points: 0.3, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_2.3.3.1.1', + nom: 'Mettre en place et tenir à jour un SIG répertoriant les voiries', + points: 0.1, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.3.1.2', + nom: 'Connaître la longueur totale de voirie gérée par la collectivité', + points: 0.1, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.3.1.3', + nom: "Collecter des informations qualitatives sur l'état de chaque voirie", + points: 0.1, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.3.3.2', + nom: 'Former/sensibiliser les agents en charge de la voirie', + points: 0.3, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_2.3.3.2.1', + nom: 'Former les agents pour limiter les impacts environnementaux des projets de voirie', + points: 0.1, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.3.2.2', + nom: 'Créer des échanges entre les agents du service voirie avec le service "mobilité/transport" (sur des projets particuliers et de manière plus transversale) pour une politique cohérente visant le développement cyclable/TC et la juste part de la voiture', + points: 0.1, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.3.2.3', + nom: "Inscrire la baisse de l'impact environnemental des projets voirie comme un objectif du service", + points: 0.1, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.3.3.3', + nom: 'Adopter une politique préventive limitant les interventions lourdes', + points: 0.4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.3.3.3.1', + nom: 'Privilégier le préventif plutôt que le curatif dans la programmation des travaux, afin de limiter les interventions lourdes', + points: 0.13333333333333336, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.3.3.2', + nom: 'Prendre en compte les impacts du changement climatique dans les critères de durabilité des voiries et techniques de mise en oeuvre', + points: 0.13333333333333336, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.3.3.3', + nom: 'Coordonner des travaux entre les différents services et partenaires (réseaux énergétiques, télécom, assainissement, eau, espaces verts...) pour limiter les interventions', + points: 0.13333333333333336, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.3.3.4', + nom: "Limiter l'impact environnemental des matériaux de voirie", + points: 0.4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.3.3.4.1', + nom: "Renforcer l'usage des matériaux suivants dans ces chantiers : matériaux perméables, recyclés, à faible albédo, à basse température de mise en oeuvre (enrobés à froid ou tiède...), liants végétaux", + points: 0.1, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.3.4.2', + nom: "Utiliser des outils d'aides à la décision et à la gestion de projet :", + points: 0.1, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.3.4.3', + nom: 'Prévoir et pratiquer la valorisation des déchets issus des voiries en fin de vie (tri à la source, recyclage...)', + points: 0.1, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.3.4.4', + nom: "Inscrire des critères environnementaux dans les appels d'offres des chantiers voirie", + points: 0.1, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.3.3.5', + nom: 'Anticiper et encourager les changements de comportement et le report modal via la politique voirie', + points: 0.2, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_2.3.3.5.1', + nom: "Dans les projets neufs, adapter les gabarits aux usages, limiter l'emprise de la voirie réservée aux voitures (normes minimales).", + points: 0.1, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.3.5.2', + nom: 'Limiter la création de nouvelles voiries au strict nécessaire', + points: 0.1, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_2.3.3.6', + nom: "Témoigner de la baisse de l'impact environnemental de sa politique voirie", + points: 0.4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_2.3.3.6.1', + nom: "Suivre de manière chiffrée l'avancement de sa politique et se fixer des objectifs", + points: 0.2, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_2.3.3.6.2', + nom: 'Suivre un indicateur visant la sobriété', + points: 0.2, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + ], + level: 1, + action_type: ActionType.AXE, + }, + { + action_id: 'cae_3', + nom: 'Approvisionnement énergie, eau, assainissement', + points: 94, + pourcentage: 18.8, + actions_enfant: [ + { + action_id: 'cae_3.1', + nom: "Organisation de la distribution d'énergie et services associés", + points: 20, + pourcentage: 21.27659574468085, + actions_enfant: [ + { + action_id: 'cae_3.1.1', + nom: "Optimiser le service public de la distribution d'énergie", + points: 10, + pourcentage: 50, + actions_enfant: [ + { + action_id: 'cae_3.1.1.1', + nom: 'Connaître les enjeux de la distribution d’énergie sur le territoire', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_3.1.1.1.1', + nom: 'Connaître les enjeux de la distribution d’énergie sur son territoire', + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.1.1.2', + nom: 'Demander au syndicat d’énergie ou au concessionnaire/gestionnaire du réseau les informations utiles à sa politique énergie', + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.1.1.3', + nom: 'Suivre les concessions par des personnes dédiées et spécialisées', + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.1.1.4', + nom: 'Connaître les provisions pour renouvellement le cas échéant', + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.1.1.2', + nom: 'Impliquer les acteurs de la distribution d’énergie de manière transversale', + points: 1, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_3.1.1.2.1', + nom: 'Les concessionnaires prennent ou ont pris une part active aux travaux du PCAET ou équivalent (signature de charte, participation aux ateliers…)', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.1.2.2', + nom: 'Mettre en place un comité consultatif spécifique au réseau de chaleur/froid', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.1.2.3', + nom: 'S’assurer de la bonne représentativité́ de l’ensemble des acteurs et notamment de la présence des représentants des usagers et des abonnés.', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.1.1.3', + nom: 'Intégrer des critères d’efficacité énergétique et de développement des énergies renouvelable dans le service public de distribution d’énergie', + points: 3, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_3.1.1.3.1', + nom: 'Pour les réseaux de chauffage/froid urbain, être attentif à la performance environnementale dans le choix de son concessionnaire et inscrire des exigences dans le contrat et les avenants qui les lient', + points: 1, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.1.3.2', + nom: "Demander aux concessionnaires de préciser dans leurs rapports annuels les mesures d'amélioration des performances énergétiques réalisées et l'état des réflexions et actions sur les smart grid ou l’injection du bio-méthane dans le réseau gaz", + points: 1, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.1.3.3', + nom: 'En régie, afficher et formaliser la performance énergétique du service et sa contribution à la politique MDE et EnR de la collectivité', + points: 1, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.1.1.4', + nom: 'Définir et piloter une stratégie en matière d’optimisation des réseaux pour dialoguer plus efficacement avec les acteurs spécialisés', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_3.1.1.4.1', + nom: 'Définir un plan stratégique / une feuille de route propre à la collectivité', + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.1.4.2', + nom: 'Suivre et mettre à jour le schéma de cohérence de développement des réseaux de distribution d’énergie du PCAET', + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.1.4.3', + nom: 'Piloter et suivre de manière globale sa politique énergétique en exploitant les données des différents réseaux (électricité, gaz, chaleur/froid)', + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.1.4.4', + nom: 'Produire des documents synthétisés/appropriés sur ce sujet', + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.1.1.5', + nom: 'Mettre en œuvre un programme localisé de maîtrise de l’énergie avec les gestionnaires/concessionnaires des réseaux', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_3.1.1.5.1', + nom: "Oeuvrer (via l’autorité concédante le cas échéant) pour la mise en place d'un service de flexibilité local auprès du gestionnaire de réseau (étude en cours ou service en place), appelé également « boucle énergétique locale » ou équivalent", + points: 0.6666666666666667, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.1.5.2', + nom: 'Accompagner des projet pilotes en auto-consommation d’électricité renouvelable pour augmenter les taux d’auto-consommation et d’auto-production (juste dimensionnement, synchronisation de la consommation avec la production, opération collective…)', + points: 0.6666666666666667, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.1.5.3', + nom: 'Participer à des projets de smartgrid', + points: 0.6666666666666667, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_3.1.2', + nom: 'Inciter à la réduction des consommations et à l’achat d’électricité verte avec les fournisseurs et syndicats d’énergie', + points: 10, + pourcentage: 50, + actions_enfant: [ + { + action_id: 'cae_3.1.2.1', + nom: 'Inciter à l’achat d’électricité renouvelable', + points: 3, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_3.1.2.1.1', + nom: "S'engager à mener une politique active de promotion des achats d'électricité verte auprès de ses habitants et acteurs socio-économiques pour augmenter la demande", + points: 1, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.2.1.2', + nom: "Faire la promotion et informer les habitants et les entreprises de la possibilité d'acheter de l'électricité verte et sur les critères de qualité à respecter", + points: 1, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.2.1.3', + nom: "Encourager et soutenir les démarches de groupement d'achats d'électricité verte des acteurs publics et privés (réunion d'information/formation/cahier des charges...)", + points: 1, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.1.2.2', + nom: 'Utiliser la facturation de l’énergie pour encourager les comportements économes (selon marge d’actions)', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_3.1.2.2.1', + nom: 'Faire apparaitre de manière évidente dans les objectifs politiques des fournisseurs locaux (factures) des principes de tarification des agents énergétiques favorisant un comportement économe en énergie', + points: 1, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.2.2.2', + nom: "Indiquer une valeur de référence (moyenne nationale ou régionale d'un ménage-type), l'évolution des consommations par rapport aux années précédentes, des recommandations ou des sites-ressources sur les factures d'électricité, de gaz ou chauffage urbain", + points: 1, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.1.2.3', + nom: 'Développer les prestations en matière de maîtrise de l’énergie et d’énergie renouvelable proposées par les acteurs de l’énergie', + points: 3, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_3.1.2.3.1', + nom: "Bénéficier et/ou solliciter son syndicat pour mettre en place des services en matière de MDE et d'ENR", + points: 0.75, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.2.3.2', + nom: 'Les fournisseurs d’énergie (gaz, chaleur, électricité, en lien avec la collectivité) proposent aux clients des prestations de services dans le domaine de la MDE et des ENR', + points: 0.75, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.2.3.3', + nom: 'Se fixer des objectifs de performances et d’amélioration de ces services', + points: 0.75, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.2.3.4', + nom: 'Accompagner des projets pilotes d’auto-consommation d’électricité renouvelable', + points: 0.75, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.1.2.4', + nom: 'Suivre l’efficacité des actions menées', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_3.1.2.4.1', + nom: "Se rapprocher des fournisseurs actifs de son territoire pour connaître et orienter les offres proposées sur son territoire et suivre le volume d'électricité verte acheté à l'échelle du territoire (habitants et acteurs socio-professionnels publics et privés)", + points: 0.6666666666666667, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.2.4.2', + nom: 'Possèder une offre 100% renouvelable et augmenter la proportion de clients sur ce produit', + points: 0.6666666666666667, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.1.2.4.3', + nom: 'Augmenter le volume des prestations fournies', + points: 0.6666666666666667, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + { + action_id: 'cae_3.2', + nom: 'Production énergétique locale', + points: 32, + pourcentage: 34.04255319148936, + actions_enfant: [ + { + action_id: 'cae_3.2.1', + nom: 'Récupérer la chaleur industrielle, pratiquer la cogénération, utiliser les réseaux de chaleur/froid comme vecteur', + points: 12, + pourcentage: 37.5, + actions_enfant: [ + { + action_id: 'cae_3.2.1.1', + nom: 'Evaluer le potentiel de récupération de chaleur et de cogénération', + points: 3.6, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_3.2.1.1.1', + nom: 'Approfondir la connaissance du tissu industriel présent sur leur territoire', + points: 0.45, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.2.1.1.2', + nom: 'Se rapprocher auprès des industries a priori pertinentes et des gros consommateurs', + points: 0.45, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.2.1.1.3', + nom: 'Identifier des projets existants et de sites ainsi que des zones de demande en chaleur/froid', + points: 0.45, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.2.1.1.4', + nom: 'Réaliser une évaluation qualitative des rejets thermiques des entreprises industrielles', + points: 0.45, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.2.1.1.5', + nom: 'Réaliser une évaluation quantitative du potentiel à travers une étude de potentiel préalable récente', + points: 0.45, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.2.1.1.6', + nom: 'Faire une étude sur le potentiel en auto-consommation', + points: 0.45, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.2.1.1.7', + nom: 'Réaliser une étude de potentiel de micro-cogénération', + points: 0.45, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.2.1.1.8', + nom: 'Réaliser une étude de potentiel d’injection vers un réseau de chaleur existant, potentiel pour réaliser des (micro) réseaux de chaleur/froid', + points: 0.45, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.2.1.2', + nom: 'Soutenir les installations de récupération de chaleur industrielle et de cogénération sur le territoire', + points: 3.6, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_3.2.1.2.1', + nom: 'Se fixer des dispositions contraignantes et des objectifs de développement dans la programmation énergétique de la collectivité', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.2.1.2.2', + nom: 'Conseiller activement les porteurs de projets de territoire', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.2.1.2.3', + nom: 'Permettre aux entreprises de se rencontrer et d’identifier des synergies potentielles relatives à la récupération de chaleur', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.2.1.2.4', + nom: 'Soutenir une campagne / un programme de promotion de la micro-cogénération', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.2.1.2.5', + nom: 'Participer financièrement aux installations lorsque la desserte concerne un réseau de chaleur urbain', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.2.1.3', + nom: 'Suivre le développement de la récupération de chaleur et de la cogénération et atteindre les objectifs fixés', + points: 4.8, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'cae_3.2.1.3.1', + nom: 'Des installations sont en fonctionnement sur le territoire', + points: 1.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.2.1.3.2', + nom: 'Epuiser le potentiel de récupération de la chaleur industrielle identifié', + points: 1.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.2.1.3.3', + nom: 'Epuiser le potentiel principal de cogénération (hors micro-cogénération)', + points: 1.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.2.1.3.4', + nom: "Réaliser l'injection vers un réseau de chaleur à proximité", + points: 1.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_3.2.2', + nom: "Augmenter l'utilisation des énergies renouvelables pour la chaleur et le rafraîchissement", + points: 12, + pourcentage: 37.5, + actions_enfant: [ + { + action_id: 'cae_3.2.2.1', + nom: 'Utiliser les réseaux de chaleur pour atteindre les objectifs fixés en matière de chaleur renouvelable', + points: 6, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.2.2.2', + nom: 'Atteindre les objectifs fixés en matière de couverture des besoins de chaleur et de rafraichissement du territoire par les énergies renouvelables', + points: 6, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_3.2.3', + nom: "Augmenter la production d'électricité issue d'énergies renouvelables sur le territoire", + points: 8, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_3.2.3.1', + nom: "Augmenter progressivement la production d'électricité renouvelable", + points: 1.6, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.2.3.2', + nom: 'Diversifier les sources de production d’électricité renouvelable', + points: 2.4, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_3.2.3.2.1', + nom: 'Susciter les projets citoyens et/ou encadrer l’intervention d’un développeur extérieur pour réaliser et exploiter un équipement dédié à la production d’électricité', + points: 0.8, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.2.3.2.2', + nom: 'La puissance photovoltaïque installée sur le territoire vise des seuils (dans la description)', + points: 0.8, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.2.3.2.3', + nom: 'Mettre en fonctionnement des installations éoliennes ou hydroélectriques sur le territoire', + points: 0.8, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.2.3.3', + nom: 'Atteindre une part élevée d’électricité renouvelable', + points: 4, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + { + action_id: 'cae_3.3', + nom: "Gestion de l'eau, des espaces verts, des déchets du territoire", + points: 42, + pourcentage: 44.680851063829785, + actions_enfant: [ + { + action_id: 'cae_3.3.1', + nom: "Optimiser l’efficacité des installations d'eau potable (énergie et ressource)", + points: 6, + pourcentage: 14.285714285714285, + actions_enfant: [ + { + action_id: 'cae_3.3.1.1', + nom: "Définir la recherche de l'efficacité énergétique comme un objectif dans les contrats de DSP ou l'inscrire dans la stratégie de la régie", + points: 0.9, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_3.3.1.1.1', + nom: "Demander la recherche de l’efficacité énergétique dans les contrats de DSP ou l'inscrire dans la stratégie de la régie", + points: 0.45, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.1.1.2', + nom: "Determiner les indices les plus importants dans le cadre d'une analyse et proposer des mesures d'amélioration de l'efficacité énergétique", + points: 0.45, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.1.2', + nom: 'Conseiller et former, de façon fréquente, les acteurs du secteur', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_3.3.1.2.1', + nom: 'Dispenser des formations à destination des acteurs du secteur', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.1.2.2', + nom: 'Coopérer avec des associations spécialisées', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.1.3', + nom: "Mettre en œuvre des mesures concrètes visant l'amélioration et l'optimisation de l'efficacité énergétique des installations d'eau potable", + points: 1.5, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_3.3.1.3.1', + nom: 'Exploiter complétement le potentiel des sources situées en hauteur', + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.1.3.2', + nom: "Exploiter totalement le potentiel de production d'électricité par turbinage", + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.1.3.3', + nom: 'Avoir un rendement élévé sur les pompes à grande capacité dans des conditions hydrauliques adéquates', + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.1.3.4', + nom: 'Optimiser les stations de traitement', + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.1.3.5', + nom: 'Mettre à disposition un budget approprié pour les travaux courants de réparation de casses et programmer un budget de renouvellement pluriannuel', + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.1.4', + nom: 'Mettre en place des mesures incitatives pour faire économiser l’eau aux usagers', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_3.3.1.4.1', + nom: "Définir dans les objectifs politiques du distributeur d'eau l'utilisation économe de l'eau par les clients et les intégrer dans la stratégie commerciale", + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.1.4.2', + nom: 'Utiliser de la facture comme moyen de sensibilisation', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.1.4.3', + nom: 'Mettre en place des tarifs linéaires ou une tarification progressive (pas de rabais de quantité)', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.1.4.4', + nom: 'Encourager via des actions les comportements et équipements économes en eau', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.1.4.5', + nom: "Promouvoir l'utilisation des eaux pluviales avec une attention particulière accordée à leur qualité", + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.1.5', + nom: 'Anticiper le renouvellement des installations', + points: 0.6, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.1.6', + nom: 'Suivre les consommations d’énergie et d’eau suite à la mise en œuvre des mesures', + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_3.3.2', + nom: "Optimiser le potentiel énergétique des systèmes d'assainissement", + points: 12, + pourcentage: 28.57142857142857, + actions_enfant: [ + { + action_id: 'cae_3.3.2.1', + nom: 'Réaliser un état des lieux de l’efficacité des systèmes d’assainissement et formaliser les objectifs', + points: 1.2, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_3.3.2.1.1', + nom: "Effectuer une analyse de l'efficacité énergétique des installations de collecte et d'épuration des eaux usées", + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.2.1.2', + nom: "Demander dans les contrats de DSP la recherche de l’efficacité énergétique des stations d'épuration ou l'inscrire dans la stratégie de la régie", + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.2.2', + nom: 'Analyser le potentiel de récupération de chaleur sur les eaux usées', + points: 1.2, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.2.3', + nom: 'Analyser le potentiel de valorisation des boues d’épuration', + points: 1.2, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_3.3.2.3.1', + nom: 'Réaliser une étude sur les possibilités de valorisation des boues', + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.2.3.2', + nom: "Etre attentif à l'actualisation des données et conclusions de l'étude sur les possibilités de valorisation des boues", + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.2.4', + nom: 'Réaliser les travaux d’amélioration de l’efficacité énergétique du système d’assainissement', + points: 2.4, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.2.5', + nom: 'Réaliser les travaux de valorisation énergétique des systèmes d’assainissement', + points: 2.4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_3.3.2.5.1', + nom: 'Avoir réalisé ou être en phase de construction des installations de récupération de chaleur sur les eaux usées ou épurées', + points: 1.2, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.2.5.2', + nom: 'Mettre en place un dispositif de valorisation des boues d’épuration et dépasser le simple respect de la règlementation dans sa mise en œuvre', + points: 1.2, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.2.6', + nom: 'Suivre régulièrement les actions et évaluer leurs effets', + points: 3.6, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_3.3.2.6.1', + nom: "Suivre l'effet des mesures pour améliorer l’efficacité énergétique des systèmes d’assainissement par des indicateurs", + points: 1.2000000000000002, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.2.6.2', + nom: 'Suivre un indicateur mesurant la production de chaleur de récupération sur les eaux usées en MWh/an.', + points: 1.2000000000000002, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.2.6.3', + nom: 'Suivre un indicateur de valorisation des boues d’épuration, montrant la progression de la collectivité', + points: 1.2000000000000002, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_3.3.3', + nom: 'Optimiser la gestion des eaux pluviales', + points: 6, + pourcentage: 14.285714285714285, + actions_enfant: [ + { + action_id: 'cae_3.3.3.1', + nom: 'Connaître les enjeux locaux de la gestion des eaux pluviales et des inondations sur son territoire', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_3.3.3.1.1', + nom: 'Sensibiliser élus et technicien à la gestion intégrée des eaux pluviales par des solutions compensatoires de rétention ou infiltration à la parcelle', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.1.2', + nom: 'Cartographier les zones inondables', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.1.3', + nom: 'Réaliser un schéma directeur d’assainissement et du pluvial', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.1.4', + nom: 'Modéliser les comportements des fleuves et des eaux pluviales', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.3.2', + nom: 'Informer la population des enjeux et des solutions permettant de limiter le ruissellement', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_3.3.3.2.1', + nom: 'Informer sur les zones à risques et sur les comportements à adopter en cas d’inondation', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.2.2', + nom: 'Informer sur la gestion intégrée des eaux pluviales : documents et/ou réunions d’informations spécialement conçus pour les particuliers', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.2.3', + nom: "Mettre en place des mesures d'incitations des particuliers pour la récupération des eaux pluviales", + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.3.3', + nom: 'Réduire les émissions de polluants et le ruissellement à la source, au-delà des compétences du service en charge de la gestion des eaux pluviales', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_3.3.3.3.1', + nom: 'Adapter le choix des revêtements de chaussées et autres matériaux urbains (matériaux neutres)', + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.3.2', + nom: 'Utiliser des peintures de sols et autres matériaux sans adjuvants toxiques', + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.3.3', + nom: 'Modifier les pratiques locales de nettoyage des rues (fréquence accrue du nettoyage) et sensibiliser sur la nécessité de ne pas rejeter de détritus sur la voie publique', + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.3.4', + nom: 'En métropole, utiliser de manière plus réfléchie les produits de déneigement et de déverglaçage', + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.3.5', + nom: 'Améliorer l’efficacité des systèmes de dépollution des systèmes industriels producteurs de fumée et améliorer la gestion des aires de stockage industrielles', + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.3.6', + nom: 'Faire participer les services urbanisme, espaces verts et transport à l’atteinte des objectifs en matière de gestion intégrée des eaux pluviales', + points: 0.2, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.3.4', + nom: 'Utiliser le règlement d’assainissement pour gérer les eaux pluviales au plus près de leur point de chute', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_3.3.3.4.1', + nom: "Intégrer au règlement d'assainissement des normes permettant de limiter le ruissellement des eaux pluviales et la surcharge des collecteurs d’assainissement", + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.4.2', + nom: "Appliquer systématiquement les mesures du règlement d'assainissement", + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.4.3', + nom: "Mettre en place des mesures particulières sur certaines zones pour limiter les risques d'inondation par ruissellement qui peuvent être amplifiés par le changement climatique", + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.3.5', + nom: 'Mener une politique ferme de prévention des inondations et de protection du milieu récepteur', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_3.3.3.5.1', + nom: "Participer activement à l'élaboration d'une politique de gestion des inondations", + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.5.2', + nom: 'Mettre en place un centre de contrôle des installations d’assainissement et pluvial', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.5.3', + nom: 'Couvrir toutes les zones concernées par le risques inondations par un PPRI', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.5.4', + nom: 'Interdire les constructions dans les zones à fort risques', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.5.5', + nom: 'Mettre en place la taxe GEMAPI', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.3.6', + nom: 'Devenir exemplaire sur l’ensemble du territoire', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_3.3.3.6.1', + nom: 'Avoir mis en place sur le territoire de nombreux ouvrages de gestion alternative des eaux pluviales', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.6.2', + nom: "Evaluer la proportion du territoire équipée d'un système séparatif ou de rétention/infiltration à la parcelle", + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.3.6.3', + nom: 'Traiter les rejets urbains par temps de pluie (de temps de retour au moins mensuel) avant rejet au milieu naturel', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_3.3.4', + nom: 'Préserver la biodiversité du territoire et développer des espaces verts', + points: 6, + pourcentage: 14.285714285714285, + actions_enfant: [ + { + action_id: 'cae_3.3.4.1', + nom: 'Connaître l’état de la biodiversité et connaître les enjeux liés aux espaces verts sur son territoire (obligations réglementaires)', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_3.3.4.1.1', + nom: 'Identifier les réservoirs et corridors écologiques et assurer la mise en œuvre de la trame verte et bleue', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.1.2', + nom: 'Etudier les impacts du plan d’action du plan climat / des actions menées dans le cadre de la politique climat air énergie sur la biodiversité', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.4.2', + nom: 'Sensibiliser à l’importance et à la fragilité de la biodiversité et aux enjeux liés aux espaces verts', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_3.3.4.2.1', + nom: 'Mettre en place des actions de sensibilisation aux différents publics à la biodiversité', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.2.2', + nom: 'Mettre en valeur les informations et actions locales relatives à la biodiversité dans ses supports de communication', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.2.3', + nom: 'Participer à la réalisation des pratiques de gestion des espaces verts.', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.2.4', + nom: 'Organiser de sessions de sensibilisation / formation en interne sur la gestion différenciée des espaces verts et les pratiques alternatives aux produits phytosanitaires', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.4.3', + nom: 'Réduire les impacts de l’éclairage sur la biodiversité nocturne', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_3.3.4.3.1', + nom: 'Etre en relation avec les associations environnementales locales, syndicat d’énergie ou autres partenaires pour faire le lien entre la politique d’éclairage public et le respect de la biodiversité', + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.3.2', + nom: 'Réaliser une trame sombre (ou trame noire)', + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.3.3', + nom: 'Organiser un événement contre la pollution lumineuse', + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.3.4', + nom: 'Obtenir le label « Villes et villages étoilés » de l’ANPCEN', + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.3.5', + nom: 'Suivre la réglementation relative à l’éclairage des enseignes', + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.4.4', + nom: 'Mettre en place une gestion différenciée des espaces verts et des pratiques alternatives aux produits phytosanitaires sur le territoire', + points: 0.9, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_3.3.4.4.1', + nom: 'Pratiquer la gestion différenciée des espaces verts et systématiser les pratiques alternatives aux produits phytosanitaires', + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.4.2', + nom: 'Sensibiliser les habitants à la gestion différenciée et aux pratiques alternatives aux produits phytosanitaires', + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.4.3', + nom: 'Utiliser des espèces rustiques et adaptées au contexte local, y compris dans la perspective du changement climatique.', + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.4.5', + nom: 'Prendre en compte la biodiversité dans une approche transversale', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_3.3.4.5.1', + nom: 'Travailler ensemble pour mener la politique de préservation de la biodiversité (réunion commune, relecture itérative des documents…)', + points: 0.08571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.5.2', + nom: 'Intègrer les enjeux et les objectifs de la démarche climat-air-énergie dans l’élaboration de la trame verte et bleue (et vice-versa)', + points: 0.08571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.5.3', + nom: 'Définir des critères environnementaux pour orienter les porteurs de projet', + points: 0.08571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.5.4', + nom: 'Concilier trame verte et bleue avec densification des espaces urbains', + points: 0.08571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.5.5', + nom: 'Décider d’un seuil maximal d’imperméabilisation des sols pour tout projet d’aménagement de construction, de rénovation ou d’agrandissement sur le territoire', + points: 0.08571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.5.6', + nom: 'Utiliser le coefficient de biotope par surface dans le PLU', + points: 0.08571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.5.7', + nom: 'Intégrer la vulnérabilité des espèces au changement climatique à la stratégie d’adaptation du territoire', + points: 0.08571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.4.6', + nom: 'Mettre en place des actions de préservation de la biodiversité contribuant à l’adaptation au changement climatique et à l’amélioration du cadre de vie', + points: 0.9, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_3.3.4.6.1', + nom: 'Restaurer des zones humides', + points: 0.225, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.6.2', + nom: 'Végétaliser des bâtiments (toitures, façades…) en prenant en compte la biodiversité', + points: 0.225, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.6.3', + nom: 'Déminéraliser des espaces urbains non bâtis (cours d’école, d’immeubles, voiries)', + points: 0.225, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.6.4', + nom: 'Mettre en place des actions de valorisation écologique des espaces publics', + points: 0.225, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.4.7', + nom: 'Utiliser des outils de contractualisation opérationnels pour la mise en œuvre de la trame verte et bleue', + points: 0.9, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_3.3.4.7.1', + nom: 'Mettre en place un outil de contractualisation à l’échelle parcellaire', + points: 0.45, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.7.2', + nom: 'Mettre en place ou promouvoir des outils contractuels à une échelle plus large', + points: 0.45, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.4.8', + nom: 'Suivre l’évolution de la biodiversité et la gestion des espaces verts', + points: 0.9, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_3.3.4.8.1', + nom: 'Faire contribuer les services de la collectivité en lien avec les espaces verts ou l’entretien du réseau routier au comptage de la biodiversité et au suivi de son évolution', + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.8.2', + nom: 'Suivre l’évolution de la biodiversité à travers un observatoire ou un atlas dynamique de la biodiversité locale, en partenariat avec une association ou un autre organisme du territoire', + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.4.8.3', + nom: "Suivre les quantités annuelles d'engrais et d'eau pour les espaces verts et les faire diminuer", + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_3.3.5', + nom: 'Valoriser les déchets résiduels et les biodéchets', + points: 12, + pourcentage: 28.57142857142857, + actions_enfant: [ + { + action_id: 'cae_3.3.5.1', + nom: 'Effectuer un état des lieux du potentiel d’optimisation de la valorisation énergétique des déchets', + points: 3.6, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_3.3.5.1.1', + nom: 'Evaluer finement la quantité de biogaz émis dans les centres d’enfouissement techniques', + points: 0.6000000000000001, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.5.1.2', + nom: "Disposer d'une analyse sur l'augmentation de l'efficacité énergétique de l'UIOM", + points: 0.6000000000000001, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.5.1.3', + nom: 'Etudier le potentiel de méthanisation sur les biodéchets, intégrant des synergies avec les gros producteurs de biodéchets et les agriculteurs pour une vision globale des gisements', + points: 0.6000000000000001, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.5.1.4', + nom: 'Etudier la faisabilité sur la mise en place de la collecte sélective des biodéchets des ménages', + points: 0.6000000000000001, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.5.1.5', + nom: "Etudier les possibilités d'injection du biométhane valorisé dans le réseau ou dans des véhicules", + points: 0.6000000000000001, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.5.1.6', + nom: 'Etudier les possibilités de production et de valorisation de bio-carburants à partir des biodéchets locaux', + points: 0.6000000000000001, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.5.2', + nom: 'Valoriser l’énergie issue de la gestion des déchets', + points: 3.6, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_3.3.5.2.1', + nom: "Valoriser la chaleur de l'UIOM (utilisation complète, en interne et/ou vente à l'extérieur) et suivre le % réel de valorisation énergétique/déchets entrants", + points: 0.4, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.5.2.2', + nom: "Valoriser la chaleur résiduelle (cogénération) si l'UIOM produit de l'électricité", + points: 0.4, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.5.2.3', + nom: "Valoriser la chaleur ou l'électricité dans l'unité de combustion de CSR (pour les DOM)", + points: 0.4, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.5.2.4', + nom: 'Optimiser le captage du biogaz issu des centres d’enfouissement', + points: 0.4, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.5.2.5', + nom: 'Valoriser le biogaz issu du centre d’enfouissement', + points: 0.4, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.5.2.6', + nom: 'Mettre en place une gestion intégrée des différents biodéchets du territoire, avec une part de valorisation énergétique (méthanisation, combustion ou agro-carburants)', + points: 0.4, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.5.2.7', + nom: 'Promouvoir les bonnes pratiques de compostage auprès des particuliers', + points: 0.4, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.5.2.8', + nom: "Contrôler l'interdiction du brûlage à l'air libre des déchets verts et mener de nombreuses actions sur le sujet", + points: 0.4, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.5.2.9', + nom: "Trouver des débouchés pour l'ensemble de l'énergie produite et pour le compost", + points: 0.4, + pourcentage: 11.111111111111112, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_3.3.5.3', + nom: 'Suivre les objectifs et atteindre un haut niveau de valorisation des déchets', + points: 4.8, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'cae_3.3.5.3.1', + nom: "Avoir un rendement de l'UIOM élevé", + points: 1.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.5.3.2', + nom: "Les centres de stockage des déchets ménagers et assimilés font l'objet d'une valorisation énergétique du biogaz >75%", + points: 1.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.5.3.3', + nom: "Augmenter la production d’électricité et de chaleur en kWh produit à partir de biodéchets pour l'ensemble du territoire (ménages et activités économiques, agricoles...) ou à défaut la quantité en kg/hab.an de biodéchets ménagers et assimilés issus de collecte sélective valorisés", + points: 1.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_3.3.5.3.4', + nom: 'Témoigner des performances par des indicateurs de suivi de la politique de compostage', + points: 1.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + ], + level: 1, + action_type: ActionType.AXE, + }, + { + action_id: 'cae_4', + nom: 'Mobilité', + points: 96, + pourcentage: 19.2, + actions_enfant: [ + { + action_id: 'cae_4.1', + nom: 'Promotion et suivi de la mobilité durable sur le territoire et en interne', + points: 16, + pourcentage: 16.666666666666664, + actions_enfant: [ + { + action_id: 'cae_4.1.1', + nom: 'Promouvoir et suivre les pratiques multimodales sur le territoire', + points: 10, + pourcentage: 62.5, + actions_enfant: [ + { + action_id: 'cae_4.1.1.1', + nom: 'Connaître les parts modales sur son territoire', + points: 1, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.1.1.2', + nom: 'S’organiser pour mener une politique d’information et de sensibilisation sur la mobilité durable', + points: 1, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.1.1.2.1', + nom: "Formaliser une politique d'information et de sensibilisation des habitants, intégrant notamment des liens avec la qualité de l’air", + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.1.2.2', + nom: "Disposer d'un budget et de moyens humains dédiés à l’information sur la mobilité durable", + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.1.2.3', + nom: 'Travailler a minima avec les autres collectivités et les Autorités Organisatrices des Mobilités afin de développer l’intermodalité (promotion des autres modes de transports disponibles au départ ou à destination, etc.)', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.1.1.3', + nom: 'Promouvoir l’intermodalité et les modes de transports alternatifs à la voiture individuelle sous des formes et vers des cibles variées', + points: 1.5, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_4.1.1.3.1', + nom: "Promouvoir et soutenir les modes alternatifs à la voiture individuelle et l'intermodalité", + points: 0.375, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.1.3.2', + nom: "Promouvoir et soutenir le télétravail, les vidéo-conférences, l’aménagement des horaires de travail pour limiter les déplacements et faciliter l'usage des transports en commun, ou modes actifs", + points: 0.375, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.1.3.3', + nom: 'Promouvoir et soutenir les Plans de mobilité dans les entreprises (PDME - Plans de mobilité employeur) et les plans de mobilité employeur communs pour les entreprises situées sur un même site.', + points: 0.375, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.1.3.4', + nom: "Promouvoir et soutenir l'usage des véhicules électriques, au biogaz ou à hydrogène de manière raisonnée et complémentaire aux modes alternatifs", + points: 0.375, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.1.1.4', + nom: 'Créer un lieu/service dédié à l’information sur l’éco-mobilité', + points: 1.5, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_4.1.1.4.1', + nom: 'Centraliser l’information disponible dans un lieu dédié à la mobilité ou diffusée par un service unique', + points: 0.75, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.1.4.2', + nom: 'Développer des services d’information individualisée de mobilité auprès des usagers', + points: 0.75, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.1.1.5', + nom: 'Travailler avec les acteurs de la mobilité à l’échelle du bassin de vie', + points: 1, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.1.1.6', + nom: 'Vérifier la progression des parts modales des modes de transports alternatifs à la voiture, atteindre des valeurs exemplaires et les communiquer', + points: 4, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'cae_4.1.1.6.1', + nom: "Analyser la progression des parts modales dans le temps et les comparer avec les parts modales moyennes à l'échelle nationale (ou régionale pour les DOM) ou encore de collectivités exemplaires", + points: 1.3333333333333335, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.1.6.2', + nom: 'Avoir de bonnes performances', + points: 1.3333333333333335, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.1.6.3', + nom: "Communiquer et valoriser l'exemplarité de la politique de mobilité durable menée", + points: 1.3333333333333335, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_4.1.2', + nom: 'Promouvoir la mobilité durable en interne au sein de la collectivité', + points: 6, + pourcentage: 37.5, + actions_enfant: [ + { + action_id: 'cae_4.1.2.1', + nom: 'Réaliser un diagnostic de ses besoins et de sa flotte de véhicules', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.1.2.1.1', + nom: 'Evaluer ses besoins en matière de véhicules motorisés', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.1.2', + nom: 'Réaliser un bilan économique de son poste « déplacements »', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.1.3', + nom: 'Réaliser un diagnostic de la flotte de véhicules', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.1.2.2', + nom: 'Engager une politique de mobilité durable au sein de la collectivité', + points: 0.9, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_4.1.2.2.1', + nom: 'S’engager politiquement en faveur d’un Plan de Mobilité', + points: 0.18, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.2.2', + nom: "Encourager le personnel à l'éco-mobilité", + points: 0.18, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.2.3', + nom: 'Prendre des directives concernant la priorité aux trajets en transports publics, à vélo, à pied pour les déplacements domicile-travail et/ou professionnels seulement', + points: 0.18, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.2.4', + nom: 'Justifier les déplacements professionnels en avion et voiture (soumis à une autorisation préalable), et les déplacements des élus municipaux, dont les frais font l’objet d’une prise en charge par la collectivité', + points: 0.18, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.2.5', + nom: 'Intégrer dans les directives d’achats des critères d’efficacité énergétique et des carburants faiblement émetteurs en CO2 et polluants atmosphériques', + points: 0.18, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.1.2.3', + nom: "Former à l'éco-conduite et renouveler sa flotte de véhicules", + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.1.2.3.1', + nom: 'Proposer une offre de formation de type "Eco-drive" aux agents', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.3.2', + nom: 'Renouveler la flotte de véhicules', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.1.2.4', + nom: 'Optimiser, rationaliser les déplacements au sein de la collectivité', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.1.2.4.1', + nom: "Optimiser ou rationaliser les trajets et les circuits en installant des systèmes de géolocalisation et des logiciels d'optimisation des déplacements", + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.4.2', + nom: 'Mettre en place en interne des dispositifs de covoiturage ou de mutualisation des véhicules et des trajets entre les services, et limiter les véhicules de fonction au sein de la collectivité', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.4.3', + nom: 'Réfléchir à une réorganisation des activités moins génératrices de flux', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.1.2.5', + nom: 'Mettre en place des mesures incitatives', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.1.2.5.1', + nom: 'Réglementer les places de stationnement devant les bâtiments communaux', + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.5.2', + nom: 'Faire la promotion du co-voiturage pour les employés et faciliter le stationnement pour les covoitureurs', + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.5.3', + nom: 'Encourager le télétravail et les vidéo-conférences', + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.5.4', + nom: 'Aménager les horaires pour faciliter l’usage des modes actifs ou TC', + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.5.5', + nom: 'Déployer d’autres mesures incitatives', + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.1.2.6', + nom: 'Mettre à disposition des moyens physiques dans la majorité des lieux de travail', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.1.2.6.1', + nom: "Proposer des places de stationnement attrayantes et sécurisées pour les vélos, situées à un endroit optimal près de l'entrée", + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.6.2', + nom: 'Acheter et mettre à disposition des agents des vélos de service ou de vélos de fonction', + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.6.3', + nom: "Donner la possibilité de suspendre/sécher l'équipement cycliste (casque, pèlerine), douches/vestiaires", + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.6.4', + nom: 'Déployer une offre de voiture en auto-partage', + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.6.5', + nom: 'Disposer de matériels de visioconférence et d’audioconférence performants', + points: 0.12, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.1.2.7', + nom: 'Inciter financièrement les agents à l’usage des modes actifs / TC', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.1.2.7.1', + nom: 'Mettre à disposition et utiliser des titres de transports publics non nominatifs pour les déplacements professionnels', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.7.2', + nom: 'Mettre à disposition des employés des contributions pour des abonnements transports publics ou location vélo allant au-delà des obligations réglementaires', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.7.3', + nom: "Mettre en place le forfait mobilité durable ou le remboursement des frais d'alimentation d'un véhicule électrique personnel (voiture ou vélo à assistance électrique) utilisé dans le cadre du travail", + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.1.2.8', + nom: 'Atteindre les objectifs et communiquer sur les actions engagées', + points: 1.5, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_4.1.2.8.1', + nom: 'Faire diminuer les consommations annuelles', + points: 0.16666666666666663, + pourcentage: 11.111111111111109, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.8.2', + nom: 'Faire diminuer les émissions de polluants atmosphériques associés à l’usage de la flotte de véhicules', + points: 0.16666666666666663, + pourcentage: 11.111111111111109, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.8.3', + nom: 'Faire augmenter le pourcentage d’agents formés à l’éco-conduite', + points: 0.16666666666666663, + pourcentage: 11.111111111111109, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.8.4', + nom: 'Réaliser des enquêtes périodiques sur les critères du Plan de mobilité et sur la répartition modale', + points: 0.16666666666666663, + pourcentage: 11.111111111111109, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.8.5', + nom: 'Réduire les déplacements liés à son activité', + points: 0.16666666666666663, + pourcentage: 11.111111111111109, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.8.6', + nom: 'Faire augmenter la part des déplacements professionnels sans voiture', + points: 0.16666666666666663, + pourcentage: 11.111111111111109, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.8.7', + nom: 'Pérenniser les actions écomobiles', + points: 0.16666666666666663, + pourcentage: 11.111111111111109, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.8.8', + nom: 'Intégrer et utiliser les résultats des enquêtes dans les processus d’amélioration', + points: 0.16666666666666663, + pourcentage: 11.111111111111109, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.1.2.8.9', + nom: 'Communiquer sur son exemplarité', + points: 0.16666666666666663, + pourcentage: 11.111111111111109, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + { + action_id: 'cae_4.2', + nom: 'Rationalisation des déplacements motorisés', + points: 30, + pourcentage: 31.25, + actions_enfant: [ + { + action_id: 'cae_4.2.1', + nom: 'Élaborer une politique de stationnement volontariste', + points: 8, + pourcentage: 26.666666666666668, + actions_enfant: [ + { + action_id: 'cae_4.2.1.1', + nom: 'Réaliser un diagnostic de l’offre de stationnement et des pratiques', + points: 0.8, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.2.1.1.1', + nom: "Réaliser un diagnostic de l'offre en stationnement", + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.1.2', + nom: 'Réaliser un inventaire des pratiques actuelles', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.2.1.2', + nom: 'Mettre en place une stratégie sur les zones analysées', + points: 1.6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_4.2.1.2.1', + nom: 'Mettre en place une politique de stationnement dans le centre-ville et/ ou les zones de forte pression (commerces de quartier, etc.)', + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.2.2', + nom: 'Mettre en place une tarification différenciée si besoin', + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.2.3', + nom: "Pour les communes en zones rurale, mettre l'accent sur la sensibilisation et l’information auprès des habitants sur le besoin de gérer l’usage de la voiture et de marquer les places réservées au stationnement et le développement de zones bleues le cas échéant autour des zones de trafic.", + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.2.4', + nom: 'Faire respecter la réglementation via de la prévention et de la verbalisation', + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.2.1.3', + nom: "Favoriser les véhicules et les espaces de stationnement plus respectueux de l'environnement", + points: 1.6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_4.2.1.3.1', + nom: 'Mettre en place une tarification et une signalisation différenciée selon la qualité environnementale des véhicules (co-voiturage, véhicules peu émetteurs, etc.)', + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.3.2', + nom: "Installer des bornes ou services de recharge pour les véhicules électriques sur les sites stratégiques, et dans les ensembles d'habitations et locaux tertiaires (anticipant ou allant plus loin que les obligations réglementaires), en veillant à la cohérence avec la stratégie de rationalisation du stationnement établie", + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.3.3', + nom: 'Mettre en place un système de guidage pour limiter la recherche de place (si nécessaire)', + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.3.4', + nom: 'Ombrager les espaces de stationnement pour limiter le recours à la climatisation, tout en limitant l’imperméabilisation des sols', + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.2.1.4', + nom: "Repenser la stratégie de stationnement afin de favoriser l'intermodalité et le recours aux modes actifs de déplacement", + points: 2.4, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_4.2.1.4.1', + nom: "Inscrire des objectifs maximaux de stationnement privé dans les documents d'urbanisme", + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.4.2', + nom: 'Ne pas favoriser la voiture à tout prix en centre-ville ou dans les situations complexes en terme de stationnement', + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.4.3', + nom: "Encourager le stationnement dans les parkings souterrains ou fermés plutôt qu'en voirie", + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.4.4', + nom: 'Réserver une partie des places « libérées » en voirie aux personnes à mobilité réduite, afin d’améliorer leur accessibilité.', + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.4.5', + nom: 'Convertir les places de stationnement sur voirie situées juste avant un passage piéton en espace de stationnement cyclable', + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.4.6', + nom: 'Affecter les recettes du stationnement payant pour la mobilité durable', + points: 0.4, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.2.1.5', + nom: 'Elargir la réflexion sur le stationnement', + points: 0.8, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.2.1.5.1', + nom: 'Intégrer à la réflexion le stationnement de nuit et le stationnement privé (pour les nouvelles places), réglementer le stationnement en dehors des zones centrales ou de forte attractivité', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.5.2', + nom: 'Mettre en place des espaces de stationnement dans une perspective d’usages multiples (scolaire, commercial, associatif)', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.2.1.6', + nom: 'Evaluer et communiquer sur la politique de stationnement', + points: 0.8, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.2.1.6.1', + nom: 'Mener des enquêtes périodiques sur le taux de rotation et sur la régularité du stationnement', + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.6.2', + nom: 'Analyser le taux d’occupation dans le centre-ville', + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.6.3', + nom: 'Suivre un indicateur en nombre de place de stationnement par habitant et le comparer à des valeurs de références, pour viser un juste dimensionnement de l’offre selon le contexte et les modes alternatifs disponibles', + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.6.4', + nom: 'Prouver l’efficacité de la tarification sur le trafic', + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.6.5', + nom: 'Utiliser et intégrer les résultats des enquêtes dans les processus d’amélioration', + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.1.6.6', + nom: 'Communiquer les résultats aux acteurs du territoire', + points: 0.13333333333333336, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_4.2.2', + nom: "Réguler le trafic, réduire la vitesse et valoriser l'espace public", + points: 16, + pourcentage: 53.333333333333336, + actions_enfant: [ + { + action_id: 'cae_4.2.2.1', + nom: 'Identifier les zones génératrices de déplacements et traversées par des flux importants', + points: 3.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_4.2.2.1.1', + nom: 'Identifier les points noirs (accidentologie)', + points: 0.5333333333333334, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.2.1.2', + nom: 'Identifier les axes où la congestion est importante et/ou avec un risque de bouchons', + points: 0.5333333333333334, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.2.1.3', + nom: 'Identifier où la collectivité a des voies réservées au transport public', + points: 0.5333333333333334, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.2.1.4', + nom: 'Repérer les zones génératrices de déplacements et les axes de circulation importants', + points: 0.5333333333333334, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.2.1.5', + nom: 'Identifier les zones où il est nécessaire de mettre en place des zones apaisées (zone résidentielles, proximité des écoles, cœur de bourg, …)', + points: 0.5333333333333334, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.2.1.6', + nom: 'Réaliser des actions de concertation en amont avec la population pour l’identification des besoins et des ressentis', + points: 0.5333333333333334, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.2.2.2', + nom: 'Mettre en place des outils de gestion du trafic', + points: 4, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_4.2.2.2.1', + nom: 'Formaliser une stratégie de gestion du trafic différenciée selon les zones (centre, périphérie, axes principaux, zones résidentielles, rues commerciales…)', + points: 1.3333333333333335, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.2.2.2', + nom: 'Mettre en place un outil de suivi du trafic (en temps réel dans l’idéal) et utiliser des données pour l’amélioration de la politique de mobilité et notamment sur les évolutions des tracés des voies bus (pour les collectivités traversées par des flux importants et/ou celles dotées de transport en commun)', + points: 1.3333333333333335, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.2.2.3', + nom: 'Valoriser les données pour mieux anticiper les difficultés à venir et notamment favoriser le transport public, réduire les bouchons, les pollutions et les risques d’accidents', + points: 1.3333333333333335, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.2.2.3', + nom: 'Réaménager et restructurer la voirie et les espaces publics afin de créer des zones de circulation apaisée', + points: 5.6, + pourcentage: 35, + actions_enfant: [ + { + action_id: 'cae_4.2.2.3.1', + nom: 'Réaménager et restructurer la voirie et les espaces publics (trame viaire, organisation et signalétique) dans les zones présentant des problématiques de conflits (zones hostiles) piétons/cyclistes/automobilistes', + points: 1.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.2.3.2', + nom: 'Installer une signalisation favorisant la réduction des vitesses et la valorisation des commerces de proximité', + points: 1.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.2.3.3', + nom: 'Mettre en place une signalisation aux entrées de ville pour signaler la politique générale de la ville', + points: 1.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.2.3.4', + nom: 'Collaborer avec les acteurs du territoire et des citoyens pour la mise en place des actions', + points: 1.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.2.2.4', + nom: 'Evaluer les actions en faveur de la régulation du trafic et la valorisation de l’espace public', + points: 3.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_4.2.2.4.1', + nom: 'Avoir de nombreux axes intégrés dans l’outil de gestion du trafic', + points: 0.8, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.2.4.2', + nom: 'Avoir un pourcentage important de voirie apaisée', + points: 0.8, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.2.4.3', + nom: 'Évaluer et suivre les actions mises en œuvre avec des enquêtes périodiques', + points: 0.8, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.2.4.4', + nom: "Utiliser les résultats des enquêtes et les intégrer dans les processus d'amélioration", + points: 0.8, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_4.2.3', + nom: 'Optimiser la logistique et la gestion des flux de marchandises sur le territoire', + points: 6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_4.2.3.1', + nom: 'Engager une concertation avec les acteurs locaux pour identifier les flux de marchandises et les besoins', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_4.2.3.1.1', + nom: 'Identifier, contacter et mettre en relation les différents acteurs de la logistique sur le territoire (collectivités, transporteurs, clients, chargeurs, commerçants et citoyens) y compris les opérateurs portuaires', + points: 0.17142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.1.2', + nom: 'Dresser une cartographie des flux (intégrant aussi le trafic engendré par le transit des poids lourds)', + points: 0.17142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.1.3', + nom: 'Réaliser un état des lieux sur la livraison de marchandises sur le territoire (flux, nature, en intégrant notamment les opérateurs portuaires et la problématique des livraisons liées au e-commerce, notamment celles assurées par des véhicules utilitaires légers) et les besoins de stationnement associés', + points: 0.17142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.1.4', + nom: "Connaître et sensibiliser les entreprises aux enjeux du « dernier kilomètre » dans la distribution de marchandises et de l’impact sur la qualité de l’air des véhicules utilitaires et des poids lourds anciens (notamment pour s'adapter à la mise en place éventuelle de zone à circulation restreinte)", + points: 0.17142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.1.5', + nom: 'Identifier un interlocuteur au sein de la collectivité pour traiter du sujet', + points: 0.17142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.1.6', + nom: 'Identifier les circuits-courts de proximité pertinents et favoriser leur déploiement autour des bassins de vie', + points: 0.17142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.1.7', + nom: 'Réaliser des études sur l’optimisation énergétique des équipements du port, sur les besoins de formation des grutiers, des chauffeurs, etc.', + points: 0.17142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.2.3.2', + nom: "Intégrer des orientations en faveur de l'optimisation du transport de marchandises à l'échelle du territoire dans les documents de planification", + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_4.2.3.2.1', + nom: 'Intégrer des actions précises sur le transport de marchandises en ville dans le PDU', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.2.2', + nom: 'Orienter les projets d’équipements en faveur de l’optimisation du transport de marchandises à l’échelle du territoire dans le SCOT par exemple le report modal du routier vers le rail ou le fluvial (ou maritime et cabotage)', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.2.3', + nom: "Optimiser les schémas logistiques urbains par rapport à leur impact sur la qualité de l'air", + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.2.3.3', + nom: 'Se doter de la compétence "gestion des marchandises"', + points: 0.3, + pourcentage: 5, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.2.3.4', + nom: "Réglementer, encadrer, soutenir et faire appliquer l'optimisation de la gestion des flux de marchandises sur le territoire", + points: 1.8, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_4.2.3.4.1', + nom: "Réglementer afin d'organiser l'accès au centre-ville (plage horaire, différenciation selon les performances environnementales des véhicules, etc), voire mise en place d'une zone à circulation restreinte en zone PPA", + points: 0.2571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.4.2', + nom: 'Proposer des solutions alternatives de transport de marchandises', + points: 0.2571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.4.3', + nom: 'Mettre en place des centres de distribution urbaine (pour les collectivités > 50 000 habitants) et des points relais (dans des commerces, des entreprises ou des équipements spécialisés)', + points: 0.2571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.4.4', + nom: 'Mettre en place des services mutualisés de livraison (acteurs économiques, établissements publics et des particuliers)', + points: 0.2571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.4.5', + nom: 'Encourager la mutualisation des services', + points: 0.2571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.4.6', + nom: 'En milieu rural, cibler les acteurs clés par exemple les agriculteurs pour réaliser des actions pour optimiser le transport de marchandises', + points: 0.2571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.4.7', + nom: 'En présence d’un port, Réaliser des actions spécifiques', + points: 0.2571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.2.3.5', + nom: 'Repenser la stratégie de stationnement des véhicules de marchandises', + points: 0.9, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_4.2.3.5.1', + nom: "Proposer un réseau cohérent et suffisant d'aires de livraison", + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.5.2', + nom: "Réglementer sur la durée et la plage horaire autorisée pour éviter les heures de pointe et limiter les conflits d'usage", + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.5.3', + nom: 'Contrôler le bon fonctionnement des aires de livraisons (respect, juste dimensionnement et localisation)', + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.2.3.6', + nom: 'Inciter et soutenir les acteurs du territoire dans un cadre formalisé', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.2.3.6.1', + nom: 'Élaborer une charte locale "logistique urbaine" reprenant les principes du cadre national, avec plan d\'actions sur les GES et les polluants atmosphériques', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.6.2', + nom: 'S\'engager avec l\'ADEME dans une démarche "engagement volontaire collectivités", qui cible la logistique urbaine durable', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.6.3', + nom: "Engager une démarche environnementale de type charte « Objectif CO2 » pour inciter les transporteurs à optimiser leur activité en termes d'émissions de GES", + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.2.3.6.4', + nom: 'Inciter les chargeurs à s’engager dans une démarche volontaire FRET 21 ou EVCOM pour leur permettre de réduire l’impact environnemental de leurs transports', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + { + action_id: 'cae_4.3', + nom: 'Mobilité alternative', + points: 50, + pourcentage: 52.083333333333336, + actions_enfant: [ + { + action_id: 'cae_4.3.1', + nom: 'Développer le réseau piétonnier', + points: 12, + pourcentage: 24, + actions_enfant: [ + { + action_id: 'cae_4.3.1.1', + nom: "Se doter d’outils pour adopter une stratégie de développement du réseau piétonnier s'appuyant sur un apaisement de la circulation", + points: 2.4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_4.3.1.1.1', + nom: 'Voter et adopter un budget pour le développement et l’amélioration du réseau', + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.1.1.2', + nom: 'Désigner un responsable des cheminements pour piétons', + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.1.1.3', + nom: "Évaluer le ressenti des piétons sur l'usage de ce mode de déplacements", + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.1.1.4', + nom: 'Élaborer un schéma directeur de la mobilité piétonne', + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.1.2', + nom: 'Améliorer prioritairement la situation des zones à forts enjeux', + points: 2.4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_4.3.1.2.1', + nom: "Identifier les zones à enjeux importants en matière de mobilité piétonne (centre, zones résidentielles) et mettre en place des mesures (aménagement et signalétique) visant à l'apaisement de celles-ci (zones limitées à 30 km/h, zone de rencontres…)", + points: 1.2, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.1.2.2', + nom: 'Repérer les points noirs pouvant freiner le développement de la mobilité piétonne dans certaines zones et les traiter', + points: 1.2, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.1.3', + nom: 'Densifier et améliorer globalement la qualité du réseau piéton sur le territoire', + points: 3.6, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_4.3.1.3.1', + nom: "Densifier le réseau piéton en veillant à garantir un maillage desservant efficacement l'ensemble des lieux à forte fréquentation, les détours et lacunes", + points: 1.2000000000000002, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.1.3.2', + nom: "S'appuyer sur la signalisation afin d'accompagner et guider les piétons", + points: 1.2000000000000002, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.1.3.3', + nom: "Accompagner les personnes à mobilité réduite (par ex. abaissement des trottoirs) plus que le minimum requis (outil : schémas d'accessibilité)", + points: 1.2000000000000002, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.1.4', + nom: 'Devenir un territoire exemplaire en matière de mobilité piétonne', + points: 3.6, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_4.3.1.4.1', + nom: 'Se saisir des outils réglementaires, avec des scénarios ambitieux (large périmètre géographique, suffisamment de catégories de véhicules visés par les restrictions…) et des moyens de contrôle (respect par les usagers)', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.1.4.2', + nom: 'Créer une ou plusieurs aires piétonnes', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.1.4.3', + nom: 'Initier des opérations d’usage dynamique de la voirie', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.1.4.4', + nom: "Attester de l'exemplarité par l’augmentation du nombre de piétons", + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.1.4.5', + nom: 'Communiquer autour des actions phares mises en place en faveur des piétons', + points: 0.72, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_4.3.2', + nom: 'Développer le réseau et les infrastructures cyclables', + points: 16, + pourcentage: 32, + actions_enfant: [ + { + action_id: 'cae_4.3.2.1', + nom: 'Connaître et analyser les déplacements et stationnements cyclistes du territoire', + points: 1.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.3.2.1.1', + nom: 'Analyser la situation en particulier à proximité des entreprises, magasins, lieux touristiques, installations fortement fréquentées', + points: 0.8, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.1.2', + nom: 'Mener des enquêtes périodiques sur la part modale des cyclistes et utiliser les études réalisées par d’autres organismes', + points: 0.8, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.2.2', + nom: 'Consulter et informer les habitants', + points: 0.8, + pourcentage: 5, + actions_enfant: [ + { + action_id: 'cae_4.3.2.2.1', + nom: 'Évaluer le ressenti des habitants au regard du mode de déplacement cycliste', + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.2.2', + nom: 'Evaluer les besoins des cyclistes', + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.2.3', + nom: 'Informer les cyclistes sur le réseau existant', + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.2.4', + nom: 'Faire connaître les nouvelles règles du décret PAMA 2015 et verbaliser les enfreintes', + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.2.3', + nom: 'Adopter un schéma directeur cyclable', + points: 1.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.3.2.3.1', + nom: 'Disposer d’un schéma directeur cyclable', + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.3.2', + nom: "Désigner au sein de l'administration un responsable du réseau cyclable et stationnement cyclable", + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.3.3', + nom: 'Voter et adopter un budget pour le développement du réseau et des places de stationnement structurant', + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.2.4', + nom: 'Mettre en œuvre son schéma directeur cyclable', + points: 4, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_4.3.2.4.1', + nom: 'Disposer de la compétence pour mettre en œuvre des actions', + points: 0.4444444444444444, + pourcentage: 11.11111111111111, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.4.2', + nom: 'Anticiper et/ou réduire les conflits d’usage', + points: 0.4444444444444444, + pourcentage: 11.11111111111111, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.4.3', + nom: 'Traiter les discontinuités cyclables', + points: 0.4444444444444444, + pourcentage: 11.11111111111111, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.4.4', + nom: "Densifier le réseau cyclable en veillant à garantir un maillage desservant efficacement l'ensemble des lieux à forte fréquentation (notamment touristique)", + points: 0.4444444444444444, + pourcentage: 11.11111111111111, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.4.5', + nom: 'Limiter les détours et les obstacles pour les cyclistes en retravaillant le plan de circulation des voiries', + points: 0.4444444444444444, + pourcentage: 11.11111111111111, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.4.6', + nom: 'Eliminer les endroits dangereux à la circulation cycliste (autour des écoles, traversée des routes principales, etc.), sécuriser et différencier les réseaux', + points: 0.4444444444444444, + pourcentage: 11.11111111111111, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.4.7', + nom: "S'appuyer sur la signalisation des itinéraires afin d'accompagner et guider les cyclistes et penser le réseau cyclable conjointement aux autres réseaux de modes actifs de déplacements afin de favoriser l'intermodalité", + points: 0.4444444444444444, + pourcentage: 11.11111111111111, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.4.8', + nom: "S'assurer de la qualité des aménagements cyclables et de leur entretien", + points: 0.4444444444444444, + pourcentage: 11.11111111111111, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.4.9', + nom: 'Réaliser des enquêtes périodiques (comptages) et auprès d’un panel de cycliste (sondages, entretiens, …) pour évaluer l’évolution des pratiques', + points: 0.4444444444444444, + pourcentage: 11.11111111111111, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.2.5', + nom: 'Proposer des offres de stationnement vélo de qualité', + points: 2.4, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_4.3.2.5.1', + nom: 'Proposer des locaux vélos sécurisés, équipés et accessibles dans tous les lieux d’attractivité', + points: 0.8, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.5.2', + nom: 'Soutenir des installations privées en particulier autour des hôtels et des complexes touristiques', + points: 0.8, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.5.3', + nom: 'Sécuriser les stationnements en particulier à proximité de pôles multimodaux, des écoles et commerces principaux', + points: 0.8, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.2.6', + nom: 'Développer un ou des réseaux express vélo (REV) pour faciliter les déplacements entre les grandes villes et leur périphérie', + points: 0.8, + pourcentage: 5, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.2.7', + nom: 'Suivre et évaluer les résultats', + points: 4.8, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_4.3.2.7.1', + nom: 'Augmenter le % de voirie aménagée ou à défaut la longueur cumulée de pistes cyclables pour 1000 habitants', + points: 1.6, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.7.2', + nom: 'Augmenter le nombre de places de stationnement vélo pour 100 habitants', + points: 1.6, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.2.7.3', + nom: 'Augmenter le passage de vélos sur les pistes (nombre par jour)', + points: 1.6, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_4.3.3', + nom: 'Proposer une offre de transports publics attractive et de qualité', + points: 14, + pourcentage: 28.000000000000004, + actions_enfant: [ + { + action_id: 'cae_4.3.3.1', + nom: 'S’organiser en interne', + points: 0.7, + pourcentage: 5, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.3.2', + nom: 'Évaluer et analyser les besoins en transports collectifs', + points: 1.4, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.3.3.2.1', + nom: "Se rapprocher des AOM (autorités organisatrices de la mobilité) locales afin d'évaluer les besoins des usagers actuels", + points: 0.28, + pourcentage: 20.000000000000004, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.3.2.2', + nom: 'Classer ses besoins par ordre de priorité', + points: 0.28, + pourcentage: 20.000000000000004, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.3.2.3', + nom: 'Identifier les principaux générateurs de déplacement', + points: 0.28, + pourcentage: 20.000000000000004, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.3.2.4', + nom: "Présenter les résultats de l'analyse", + points: 0.28, + pourcentage: 20.000000000000004, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.3.2.5', + nom: 'Pour les collectivités concernées (littoral, DOM…), intègrer au diagnostic l’offre maritime/fluviale.', + points: 0.28, + pourcentage: 20.000000000000004, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.3.3', + nom: 'Orienter l’achat de véhicules des transports publics et le renouvellement de flotte vers les carburants alternatifs (bioGNV, électrique et hydrogène)', + points: 4.2, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_4.3.3.3.1', + nom: 'Déployer des flottes de transport public à très faibles émissions en adaptant le choix du carburant alternatif aux ressources du territoire', + points: 1.4000000000000004, + pourcentage: 33.33333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.3.3.2', + nom: 'Augmenter le % de véhicules faiblement émetteurs', + points: 1.4000000000000004, + pourcentage: 33.33333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.3.3.3', + nom: 'S’engager dans une opération type « Objectif CO2 les transporteurs s’engagent »', + points: 1.4000000000000004, + pourcentage: 33.33333333333334, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.3.4', + nom: "Améliorer l'efficacité du réseau de transports collectifs en collaboration avec les AOM et les principaux générateurs de déplacements", + points: 2.1, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_4.3.3.4.1', + nom: "Optimiser l'offre existante", + points: 0.30000000000000004, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.3.4.2', + nom: 'Donner la priorité aux transports publics dans le trafic, en lien avec les collectivités compétentes en matière de voirie', + points: 0.30000000000000004, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.3.4.3', + nom: "Développer des systèmes d'information réactifs pour informer en temps réel ou quasiment les usagers de l'état du trafic sur le réseau de TC", + points: 0.30000000000000004, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.3.4.4', + nom: "Prendre des mesures pour assurer la fiabilité lors d'événements climatiques extrêmes, et la qualité des transports", + points: 0.30000000000000004, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.3.4.5', + nom: 'Associer les principaux générateurs de déplacements à la réflexion, travailler en amont avec eux afin de les sensibiliser et les inciter à ajuster leur organisation et leurs horaires', + points: 0.30000000000000004, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.3.4.6', + nom: "Adapter et/ou améliorer l'accessibilité de l'offre de transports publics aux PMR", + points: 0.30000000000000004, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.3.4.7', + nom: 'S’engager dans une opération type « Objectif CO2 les transporteurs s’engagent »', + points: 0.30000000000000004, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.3.5', + nom: 'Diversifier l’offre de transport collectif, pour plus de souplesse', + points: 2.8, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.3.6', + nom: 'Mettre en place une tarification adaptée', + points: 1.4, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.3.3.6.1', + nom: 'Créer une billettique unique', + points: 0.4666666666666666, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.3.6.2', + nom: "Mettre en place une offre de cartes journalières pour les transports publics et gratuité des transports en commun en cas d'épisodes de pollution", + points: 0.4666666666666666, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.3.6.3', + nom: 'Adapter la tarification aux enjeux sociaux / aux classes d’âges', + points: 0.4666666666666666, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.3.7', + nom: 'Evaluer et communiquer les résultats', + points: 1.4, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.3.3.7.1', + nom: "Évaluer la progression de l'utilisation des transports publics", + points: 0.4666666666666666, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.3.7.2', + nom: "Utiliser les résultats des enquêtes et les intégrer dans les processus d'amélioration", + points: 0.4666666666666666, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.3.7.3', + nom: 'Communiquer sur les résultats', + points: 0.4666666666666666, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_4.3.4', + nom: "Développer l'offre multimodale et l'intermodalité", + points: 8, + pourcentage: 16, + actions_enfant: [ + { + action_id: 'cae_4.3.4.1', + nom: 'Analyser les besoins et l’offre multimodale existante', + points: 1.2, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_4.3.4.1.1', + nom: 'Analyser la situation en matière de co-voiturage, d’auto-partage, de location de vélos et services associés', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.4.1.2', + nom: 'Connaître les enjeux de l’intermodalité et formaliser la volonté de faciliter l’intermodalité dans un document', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.4.1.3', + nom: 'Mettre à disposition des moyens pour la mise en œuvre d’actions en faveur de la multi-modalité et de l’intermodalité (budget alloué, personnel identifié)', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.4.2', + nom: 'Faciliter le changement de mode de transport', + points: 1.6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_4.3.4.2.1', + nom: 'Développer des parkings relais (P+R)', + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.4.2.2', + nom: 'Autoriser et faciliter l’embarquement des vélos dans les transports en commun lorsque les conditions d’exploitation le permettent', + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.4.2.3', + nom: 'Mettre en place une tarification et une billettique unique/coordonnée entre les différentes offres de transport', + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.4.2.4', + nom: 'Installer un pôle d’échanges multimodal, combinant en même lieu plusieurs modes de transport alternatifs différents', + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.4.3', + nom: "Développer l'usage de la voiture partagée", + points: 1.6, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.4.4', + nom: 'Equiper les habitants en vélo', + points: 1.6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_4.3.4.4.1', + nom: 'Développer des offres de locations vélo afin de provoquer l’essai par la population', + points: 0.8, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.4.4.2', + nom: 'Aider directement les habitants', + points: 0.8, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.4.5', + nom: 'Accompagner les cyclistes avec des services associés au vélo', + points: 1.2, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_4.3.4.5.1', + nom: "Encourager l'apprentissage du vélo et inciter la réappropriation des deux roues notamment en milieu rural", + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.4.5.2', + nom: "Soutenir les vélos-écoles pour déployer leurs missions d'accompagnement et d'apprentissage du vélo", + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.4.5.3', + nom: 'Encourager le marquage des vélos « bicycode » et informer sur les meilleures astuces contre le vol', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.4.5.4', + nom: 'Soutenir les ateliers de réparation, les associations de recyclage, les coursiers à vélo, les maisons du vélo, etc.', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.4.5.5', + nom: 'Développer des démarches innovantes autour des services vélos (vélos spéciaux, familiaux et vélo cargo)', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_4.3.4.6', + nom: 'Suivre et atteindre les objectifs fixés', + points: 0.8, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_4.3.4.6.1', + nom: "Constater l'augmentation de la pratique du co-voiturage et de l’auto-partage", + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.4.6.2', + nom: "Constater de l'augmentation du parc de vélos en partage (vélo libre-service ou location longue durée)", + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.4.6.3', + nom: 'Réaliser des enquêtes périodiques', + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_4.3.4.6.4', + nom: "Utiliser les résultats des enquêtes et les intégrer dans le processus d'amélioration", + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + ], + level: 1, + action_type: ActionType.AXE, + }, + { + action_id: 'cae_5', + nom: 'Organisation interne', + points: 46, + pourcentage: 9.2, + actions_enfant: [ + { + action_id: 'cae_5.1', + nom: 'Gouvernance', + points: 26, + pourcentage: 56.52173913043478, + actions_enfant: [ + { + action_id: 'cae_5.1.1', + nom: 'Organiser les ressources humaines pour mener la politique climat-air-énergie', + points: 6, + pourcentage: 23.076923076923077, + actions_enfant: [ + { + action_id: 'cae_5.1.1.1', + nom: 'Doter la politique climat-air-énergie de moyens humains', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_5.1.1.1.1', + nom: "Disposer d'une ou plusieurs personnes responsables des questions climat-air-énergie au niveau technique", + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.1.1.2', + nom: 'Attribuer une mission de conseil à des personnes ou entreprises externes spécialisées (par exemple conseiller France Rénov, Agence de mobilité, Agence locale, association spécialisée, ...) ou procéder à un recrutement en interne si les ressources humaines sont insuffisantes.', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.1.1.3', + nom: 'Désigner un chef de projet climat-air-énergie', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.1.1.2', + nom: 'Décliner finement les responsabilités et les référents', + points: 1.8, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_5.1.1.2.1', + nom: 'Des référents par service sont identifiés pour les différents sujets', + points: 0.6000000000000001, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.1.2.2', + nom: 'Identifier une ou des personnes pour garantir le bon fonctionnement des services et fournir des services spécifiques en cas de phénomènes extrêmes liés au changement climatique (canicule, tempête...).', + points: 0.6000000000000001, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.1.2.3', + nom: 'Compléter systématiquement les instructions de travail et les fiches de poste pour les agents concernés avec des tâches couvrant l’ensemble des thématiques climat-air-énergie (urbanisme, bâtiments, mobilité, adaptation, etc.)', + points: 0.6000000000000001, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.1.1.3', + nom: 'Travailler en transversalité', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_5.1.1.3.1', + nom: "Aménager le poste du chef de projet climat-air-énergie pour lui permettre de se consacrer pleinement à sa mission et de travailler en transversalité et de manière légitime avec les autres services (positionnement stratégique dans l'organigramme)", + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.1.3.2', + nom: "Disposer d'une équipe projet transversale, pilotée par le chef de projet, chargée d’assurer la mise en œuvre de la stratégie climat-air-énergie ; elle se réunit régulièrement et dynamise la démarche en interne", + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.1.3.3', + nom: 'Avoir des DGS, DGA et/ou DST qui sont impliqués et contribuent au portage et soutiennent le chef de projet (notamment vis à vis de la transversalité et de la mobilisation des autres agents)', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.1.3.4', + nom: 'Former ponctuellement des groupes de travail techniques mêlant différent services selon les besoins et projets', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.1.1.4', + nom: 'Mesurer l’efficacité de l’organisation interne et l’ajuster si nécessaire', + points: 1.8, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_5.1.1.4.1', + nom: 'Mettre en place une organisation interne qui permet une circulation rapide des informations', + points: 0.36, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.1.4.2', + nom: 'Évaluer si le personnel et des référents spécialisés sont actifs et efficaces', + points: 0.36, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.1.4.3', + nom: "Les agents améliorent la qualité de l'organisation", + points: 0.36, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.1.4.4', + nom: 'Les fiches de postes sont complétées et améliorées', + points: 0.36, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.1.4.5', + nom: 'Le nombre d’équivalents temps plein (ETP) dédiés à la mise en œuvre de la politique climat-air-énergie est maintenu ou en augmentation', + points: 0.36, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_5.1.2', + nom: 'Assurer le pilotage et le portage de la politique climat-air-énergie', + points: 6, + pourcentage: 23.076923076923077, + actions_enfant: [ + { + action_id: 'cae_5.1.2.1', + nom: 'Définir un comité de pilotage transversal et légitime', + points: 2.1, + pourcentage: 35, + actions_enfant: [ + { + action_id: 'cae_5.1.2.1.1', + nom: 'Identifier un⸱e élu⸱e référent⸱e en charge de la politique climat-air-énergie', + points: 0.3500000000000001, + pourcentage: 16.66666666666667, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.2.1.2', + nom: 'Légitimer la composition et le rôle du comité de pilotage par une décision de l’organe délibérant de la collectivité, de l’exécutif ou un autre document formel ayant fait l’objet de l’approbation du ou de la Président(e)/Maire de la collectivité', + points: 0.3500000000000001, + pourcentage: 16.66666666666667, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.2.1.3', + nom: 'Intégrer le comité de pilotage de manière pérenne dans le fonctionnement de la collectivité et dans les organes de direction politique', + points: 0.3500000000000001, + pourcentage: 16.66666666666667, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.2.1.4', + nom: 'Identifier les pilotes techniques et politiques. En cas de COPIL conjoint ville-intercommunalité, des élus des deux collectivités participent et contribuent au comité de pilotage', + points: 0.3500000000000001, + pourcentage: 16.66666666666667, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.2.1.5', + nom: 'Réunir au sein du comité de pilotage des élus et personnes référentes dans des thématiques variées, non restreintes uniquement à l’énergie ou l’environnement (mobilité, aménagement, énergie, eau, assainissement, organisation interne, partenariats et coopération, finances, etc.) afin de traiter les questions climat air énergie de façon transversale', + points: 0.3500000000000001, + pourcentage: 16.66666666666667, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.2.1.6', + nom: 'Réunir d’autres acteurs du territoire au sein du comité de pilotage (associations, organismes institutionnels, etc)', + points: 0.3500000000000001, + pourcentage: 16.66666666666667, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.1.2.2', + nom: 'Elaborer et valider les objectifs de la politique climat air énergie en comité de pilotage', + points: 2.1, + pourcentage: 35, + actions_enfant: [ + { + action_id: 'cae_5.1.2.2.1', + nom: 'Réunir le comité de pilotage au minimum 2 fois par an avec ordre du jour puis rédiger un compte rendu de ses décisions', + points: 0.42, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.2.2.2', + nom: 'Élaborer ou décider des objectifs climat air énergie au sein du comité de pilotage (a minima dans les 6 axes du référentiel)', + points: 0.42, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.2.2.3', + nom: 'Donner au comité de pilotage un rôle véritablement moteur pour la politique climat-air-énergie (décisions constructives et ambitieuses, lancement de nouvelles études ou actions…); Impulser via celui-ci une dynamique positive auprès des services', + points: 0.42, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.2.2.4', + nom: 'Porter les objectifs au plus haut niveau par les élus (maire ou président de la collectivité) et au sein des instances décisionnaires', + points: 0.42, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.2.2.5', + nom: 'Le/la Maire / Président(e) participe à certaines réunions (voire assure une présidence ou une co-présidence du COPIL) pour prouver l’implication politique au plus haut niveau dans la démarche', + points: 0.42, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.1.2.3', + nom: 'Assurer la mise en œuvre effective des décisions prises', + points: 1.8, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_5.1.2.3.1', + nom: 'Organiser le comité de pilotage pour suivre la mise en œuvre effective des décisions prises (tableau de suivi par exemple)', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.2.3.2', + nom: 'Le comité de pilotage attribue des missions externes pour la réalisation des actions', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.2.3.3', + nom: 'Les directeurs de service, et notamment DGS, DGA et/ou DST apportent du soutien au comité de pilotage pour la mise en place opérationnelle des décisions (relais au sein des différents services notamment)', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.2.3.4', + nom: 'Le comité de pilotage veille à la bonne compréhension par les habitants et usagers du territoire des décisions prises (information par voie de presse, participation des membres du comité de pilotage à des réunions publiques, etc.)', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_5.1.3', + nom: 'Former et mobiliser les élus et les services sur les thématiques climat-air-énergie', + points: 6, + pourcentage: 23.076923076923077, + actions_enfant: [ + { + action_id: 'cae_5.1.3.1', + nom: 'Accompagner les élus et les agents dans la pratique des éco-gestes quotidiens', + points: 0.3, + pourcentage: 5, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.1.3.2', + nom: 'Formaliser le plan de formation/sensibilisation des agents et des élus', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_5.1.3.2.1', + nom: 'Décliner un plan de formation/sensibilisation pour chacun (techniciens, directeurs, élus, …) en fonction de ses besoins et de son degré d’implication dans l’atteinte des objectifs du programme d’actions climat-air-énergie de la collectivité et du territoire', + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.3.2.2', + nom: "Rendre visibles et varier dans la liste des formations proposées celles en lien avec le climat, l'air ou l'énergie", + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.1.3.3', + nom: 'Accompagner les élus et les agents sur des thématiques particulières', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_5.1.3.3.1', + nom: "Les agents ont analysé l'impact du changement climatique sur leurs activités et sont accompagnés pour s'y adapter", + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.3.3.2', + nom: "Traiter le sujet de la qualité de l'air de manière transversale et ne pas le cantonner au service santé", + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.1.3.4', + nom: 'Mettre en œuvre le plan de formation/sensibilisation climat-air-énergie', + points: 1.8, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_5.1.3.4.1', + nom: 'Encourager réellement les activités de formation/sensibilisation (prendre les frais à sa charge, attribuer le temps nécessaire)', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.3.4.2', + nom: 'Les personnes identifiées participent effectivement aux formations climat-air-énergie sur lesquelles elles se sont positionnées', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.3.4.3', + nom: 'La liste des formations effectivement réalisées sur le sujet climat-air-énergie est variée (plusieurs thématiques et services concernés)', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.3.4.4', + nom: 'Intégrer un système d’évaluation dans les formations', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.1.3.5', + nom: 'Engager et motiver les élus et les agents', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_5.1.3.5.1', + nom: 'Fixer collectivement ou par service des objectifs concernant la performance climat air énergie de la collectivité (ils sont fixés par écrit, sont mesurables et ont un délai)', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.3.5.2', + nom: "Disposer d'un système de reconnaissance des initiatives (individuelles ou collectives) ou de l'atteinte des objectifs", + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.3.5.3', + nom: "Les agents font part de leurs idées d'améliorations (objectifs ou bonnes pratiques)", + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.3.5.4', + nom: 'Organiser des évènements "festifs" ou mettre en place un dispositif d’émulation pour former et sensibiliser les agents et les élus (concours inter-services, semaines de l\'efficacité énergétique, semaine de la lutte contre le changement climatique ou de la qualité de l\'air, etc.)', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.3.5.5', + nom: 'Les élus participent régulièrement à des visites de site, des conférences, etc.', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.1.3.6', + nom: 'Evaluer et valoriser l’efficacité des actions de formation et de mobilisation', + points: 0.9, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_5.1.3.6.1', + nom: 'Valoriser l’atteinte des objectifs de performances ou les bonnes pratiques des services (newsletter, bulletin de paie, intranet, etc.)', + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.3.6.2', + nom: 'Porter à connaissance de l’ensemble des services de la collectivité le plan de formation (formations proposées) et le bilan quantitatif et qualitatif des formations (nombre de sessions, nombre d’inscrits, évaluation de la satisfaction des stagiaires, ...)', + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.3.6.3', + nom: 'Suivre et mesurer l’efficacité des formations/sensibilisation à travers des indicateurs spécifiques (évaluation des acquis de la formation, évaluation du passage à l’action suite à la formation, enquête de satisfaction, etc.)', + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_5.1.4', + nom: "Suivre l'avancement et évaluer régulièrement la politique climat-air-énergie", + points: 8, + pourcentage: 30.76923076923077, + actions_enfant: [ + { + action_id: 'cae_5.1.4.1', + nom: 'Se doter d’outils et de moyens pour suivre et évaluer son plan d’action', + points: 1.6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_5.1.4.1.1', + nom: 'Disposer d’un tableau de bord opérationnel pour le suivi du plan d’action', + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.4.1.2', + nom: 'Prévoir précisément les modalités du suivi', + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.4.1.3', + nom: 'Constituer et mettre en place une instance spécifique de suivi-évaluation', + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.4.1.4', + nom: "Planifier l'information des résultats annuels au public", + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.1.4.2', + nom: 'Suivre et évaluer régulièrement l’atteinte des objectifs', + points: 3.2, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'cae_5.1.4.2.1', + nom: "Disposer d'un suivi effectif : Vérifier l'atteinte des objectifs régulièrement pour l’ensemble des thématiques climat-air-énergie à travers des indicateurs qualitatifs et quantitatifs (pas de fréquents reports et espacements des réunions de suivi)", + points: 1.0666666666666669, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.4.2.2', + nom: "Actualiser annuellement le calendrier, le budget, les personnes responsables et l'état d'avancement des actions", + points: 1.0666666666666669, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.4.2.3', + nom: 'Partager le tableau de bord au sein de l’équipe projet qui le renseigne et le fait évoluer', + points: 1.0666666666666669, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.1.4.3', + nom: 'Communiquer et informer les acteurs du territoire de l’avancement du programme d’actions', + points: 2.4, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_5.1.4.3.1', + nom: 'Synthétiser les résultats des actions', + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.4.3.2', + nom: 'Publier les résultats et le suivi annuel', + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.4.3.3', + nom: "Intégrer des acteurs du territoire (habitants, acteurs socio-économiques) au dispositif d'évaluation par exemple dans une instance spécifique (évaluation participative)", + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.4.3.4', + nom: "Aller au-delà de l'exigence règlementaire de mise à disposition, au bout de 3 ans, d'un rapport au public sur la mise en œuvre du PCAET", + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.1.4.4', + nom: 'Faire évoluer son programme d’actions grâce au dispositif de suivi et d’évaluation', + points: 0.8, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_5.1.4.4.1', + nom: "Actualiser le programme d'actions et l'adapter chaque année", + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.1.4.4.2', + nom: "Mettre en place un cycle d'amélioration continue (objectif-planification-réalisation-contrôle-objectif)", + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + { + action_id: 'cae_5.2', + nom: 'Finances et commande publique', + points: 20, + pourcentage: 43.47826086956522, + actions_enfant: [ + { + action_id: 'cae_5.2.1', + nom: 'Financer la politique Climat Air Energie et réaliser une évaluation climat du budget', + points: 12, + pourcentage: 60, + actions_enfant: [ + { + action_id: 'cae_5.2.1.1', + nom: 'Sensibiliser les élu.e.s et former les équipes à la prise en compte de la politique climat-air-énergie dans le processus d’élaboration budgétaire', + points: 2.4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_5.2.1.1.1', + nom: 'Sensibiliser l’ensemble des élu.e.s à l’importance de piloter la politique climat-air-énergie dans ses aspects budgétaires, et leur présenter l’intérêt de réaliser une évaluation climat du budget', + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.1.1.2', + nom: 'Nommer une équipe transversale pour prendre en charge les aspects budgétaires liés à la politique climat-air-énergie', + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.1.1.3', + nom: "Former l'équipe en charge des aspects budgétaires liés à la politique climat-air-énergie sur l’évaluation climat du budget, la budgétisation de la politique climat-air-énergie, et aux dispositifs de financement de cette politique", + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.1.1.4', + nom: 'Sensibiliser l’ensemble des services à l’importance de prendre en compte les enjeux climat-air-énergie lors de toute programmation de dépenses', + points: 0.6, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.2.1.2', + nom: 'Attribuer un budget pour la politique climat-air-énergie', + points: 3, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_5.2.1.2.1', + nom: 'Faire correspondre à chaque étape de la construction de la politique climat-air-énergie un budget : action de sensibilisation, de communication, diagnostic, suivi, évaluation, programme d’actions. Ce budget de la politique climat-air-énergie est traduit en une trajectoire annuelle de dépenses.', + points: 1, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.1.2.2', + nom: 'Disposer d’un plan pluriannuel d’investissement qui intègre des actions climat-air-énergie en lien avec ses documents de programme', + points: 1, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.1.2.3', + nom: 'Allouer le budget chaque année par le conseil de la collectivité.', + points: 1, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.2.1.3', + nom: 'Réaliser chaque année une évaluation climat du budget', + points: 1.8, + pourcentage: 15, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.2.1.4', + nom: 'Analyser les marges de manœuvre budgétaires de la collectivité sur la base de l’évaluation climat du budget', + points: 1.2, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.2.1.5', + nom: 'Diversifier les modes de financement pour atteindre les objectifs climat air énergie et innover', + points: 1.2, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_5.2.1.5.1', + nom: 'La collectivité étudie l’ensemble des sources de financement possibles pour les actions de sa politique climat-air-énergie.', + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.1.5.2', + nom: 'La collectivité fait preuve d’innovation pour le financement des actions de sa politique climat-air-énergie (CEE, CPE, MDE et réaffectation de recettes, projets citoyens)', + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.2.1.6', + nom: 'Suivre annuellement le budget', + points: 1.2, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_5.2.1.6.1', + nom: 'Suivre annuellement le budget total pour la politique climat-air-énergie par un indicateur en euros/an/habitant', + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.1.6.2', + nom: 'Orienter les dépenses budgétaires grâce à l’analyse des marges de manœuvre tirée de l’évaluation climat du budget', + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.2.1.7', + nom: 'Être cohérent dans sa politique de soutien financier', + points: 1.2, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_5.2.1.7.1', + nom: 'Apporter du soutien financier à des thématiques environnementales variées, à des cibles variées et sous différentes formes', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.1.7.2', + nom: "Disposer d'un règlement des aides clair et bien le diffuser", + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.1.7.3', + nom: 'Ne pas octroyer d’aides pour des projets en contradiction avec les enjeux climatiques et énergétiques', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.1.7.4', + nom: "Pratiquer l'éco-conditionnement des aides habituelles de la collectivité lorsque cela est possible (bonification, différenciation des montants d’aides selon des critères)", + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_5.2.2', + nom: "Etre exemplaire en matière d'écoresponsabilité de la commande publique", + points: 8, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'cae_5.2.2.1', + nom: "S'organiser et mobiliser en interne", + points: 0.8, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_5.2.2.1.1', + nom: 'Identifier un agent référent en interne : cet agent a été formé sur les possibilités d\'intégration du développement durable dans les marchés publics (référent "achat durable”)', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.2.1.2', + nom: 'Sensibiliser et mobiliser les élus, les inciter à adopter une politique volontariste : connaissance de la logique cycle de vie des produits et services et de la notion de coût du cycle de vie, connaissance des éco-labels', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.2.2.2', + nom: 'Voter une délibération sur la mise en œuvre de clauses environnementales (et sociales) dans les marchés publics', + points: 0.8, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_5.2.2.2.1', + nom: "Décider de prendre en compte les aspects énergie et environnement, notamment l'impact énergétique et GES de la fabrication et du transport des marchandises, et les coûts globaux lors des achats, incluant la consommation d’énergie à l’utilisation (délibération, note de services)", + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.2.2.2', + nom: 'Mettre à disposition des agents et élus des directives générales avec critères pour les marchés publics', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.2.2.3', + nom: 'Faire usage de sobriété pour éviter certains achats', + points: 0.4, + pourcentage: 5, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.2.2.4', + nom: 'Mener les actions simples', + points: 0.8, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_5.2.2.4.1', + nom: 'Identifier et changer les pratiques pour les produits faciles à éviter ou substituer', + points: 0.2666666666666667, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.2.4.2', + nom: "Effectuer les achats d'articles en papier (papier à imprimer, papier hygiénique), de détergents et d'appareils de bureau selon des critères écologiques (exemple : écolabel et notamment écolabel européen)", + points: 0.2666666666666667, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.2.4.3', + nom: 'Privilégier les produits de saison, locaux et biologiques pour les évènements ponctuels organisés par la collectivité, les achats alimentaires', + points: 0.2666666666666667, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.2.2.5', + nom: 'Contribuer à un réseau local achats responsables', + points: 0.4, + pourcentage: 5, + actions_enfant: [ + { + action_id: 'cae_5.2.2.5.1', + nom: "Entrer dans un réseau local d'achats responsables et y participer activement", + points: 0.2, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.2.5.2', + nom: 'Favoriser les plateformes locales de distribution', + points: 0.2, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.2.2.6', + nom: 'Adopter une délibération définissant un plan pour les achats responsables, recenser les pratiques, effectuer un état des lieux de la production locale', + points: 1.6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_5.2.2.6.1', + nom: "Connaître et formaliser dans un document (listing) l'étendue de l'offre locale pour répondre aux besoins de la collectivité (producteurs, fournisseurs...)", + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.2.6.2', + nom: "Identifier dans cette délibération, les pratiques d'achats et les améliorations à apporter", + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.2.6.3', + nom: 'Détailler les directives pour les achats dans les domaines du matériel du bureau, entretien des bâtiments, véhicules et mobilité, matériaux de construction', + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.2.2.7', + nom: "Appliquer des clauses environnementales variées et systématiser la logique cycle de vie des produits et services, afin de déterminer les dispositions environnementales pertinentes selon les familles d'achat", + points: 1.6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_5.2.2.7.1', + nom: "Inviter les candidats à répondre aux appels d'offres de manière électronique", + points: 0.22857142857142862, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.2.7.2', + nom: 'Évaluer les fournisseurs sur l’application de leurs engagements environnementaux pendant le déroulement de leur prestation (par exemple prestataires de restauration collective ou travaux)', + points: 0.22857142857142862, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.2.7.3', + nom: 'Encourager la fourniture du bilan GES des produits/services achetés dans les appels d’offres', + points: 0.22857142857142862, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.2.7.4', + nom: "Effectuer l'entretien des bâtiments et des espaces publics selon des critères écologiques", + points: 0.22857142857142862, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.2.7.5', + nom: 'Effectuer le choix des matériaux de construction selon des critères écologiques (le bois est notamment systématiquement étudié) et repose sur les gisements locaux (Pisé, paille, etc.)', + points: 0.22857142857142862, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.2.7.6', + nom: "Choisir les techniques et matériaux de finition, ainsi que le mobilier pour limiter la pollution de l'air intérieur (faibles émissions de COV et formaldéhydes notamment), soit en privilégiant des produits avec étiquette A+, soit en achetant des produits d’occasion", + points: 0.22857142857142862, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.2.7.7', + nom: 'Inclure la prise en compte de la durée de vie et de la fin de vie des produits achetés dans les critères d’achats', + points: 0.22857142857142862, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.2.2.8', + nom: "Participer à l'amélioration de l'offre en services et produits responsables / entraîner les acteurs locaux", + points: 0.4, + pourcentage: 5, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_5.2.2.9', + nom: "Passer au crible l'ensemble des achats publics", + points: 1.2, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_5.2.2.9.1', + nom: '% des marchés (en nombre) intégrant des clauses environnementales (et sociales) dans les spécifications techniques ou les critères d’attribution en augmentation', + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_5.2.2.9.2', + nom: '% des marchés (en €) intégrant des clauses environnementales (et sociales) dans les spécifications techniques ou les critères d’attribution en augmentation', + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + ], + level: 1, + action_type: ActionType.AXE, + }, + { + action_id: 'cae_6', + nom: 'Coopération, communication', + points: 100, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.1', + nom: 'Stratégie de coopération et de communication', + points: 14, + pourcentage: 14.000000000000002, + actions_enfant: [ + { + action_id: 'cae_6.1.1', + nom: 'Développer une stratégie partenariale multi-niveaux', + points: 6, + pourcentage: 42.857142857142854, + actions_enfant: [ + { + action_id: 'cae_6.1.1.1', + nom: 'Identifier les acteurs clés à associer', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_6.1.1.1.1', + nom: 'Identifier et cartographier les acteurs clés (privés et publics, interne et externe) à associer', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.1.1.2', + nom: 'Inscrire la coopération dans les fiches de poste des agents concernés (missions identifiées et temps associé)', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.1.1.2', + nom: 'Echanger et s’impliquer dans des projets à l’échelle extra-locale', + points: 1.5, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_6.1.1.2.1', + nom: "Coopérer avec les territoires voisins (communes ou EPCI limitrophes) sur l'inter-territoriale ou à une autre échelle (Parcs naturels régionaux, Pays…)", + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.1.2.2', + nom: "Echanger et coopérer avec les institutions nationales et régionales impliquées dans les PCAET, SRCAE/SRADDET et PPA (DREAL, DDT, Ministère de l'écologie...)", + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.1.2.3', + nom: "Echanger et coopérer avec les chambres consulaires et plateformes d'information spécifiques aux différents acteurs du territoire", + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.1.2.4', + nom: 'Participer aux groupes de travail dans les services régionaux spécialisés en matière d’énergie climat air (ASQUA, EIE, AASQA, etc)', + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.1.2.5', + nom: 'Participer aux commissions de suivi des sites stratégiques pour veiller à la qualité environnementale', + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.1.1.3', + nom: 'Formaliser la stratégie partenariale', + points: 1.5, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_6.1.1.3.1', + nom: 'Planifier le dialogue et la collaboration à travers des accords de partenariat formalisés', + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.1.3.2', + nom: 'Renforcer les engagements demandés aux partenaires et les impliquer dans le suivi et l’évaluation de la politique climat air énergie', + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.1.3.3', + nom: 'Proposer un accompagnement technique vis-à-vis des partenaires', + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.1.3.4', + nom: 'Voter et budgéter le plan de coopération (valables sur plusieurs années)', + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.1.3.5', + nom: 'Avoir mis en oeuvre au moins 2 partenariats significatifs et multi-acteurs dans le domaine climat-air-énergie durant les 4 dernières années', + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.1.1.4', + nom: 'S’impliquer dans l’évolution du cadre réglementaire et législatif climat air énergie', + points: 0.9, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_6.1.1.4.1', + nom: 'Interpeller les acteurs sur les blocages législatifs et réglementaires rencontrés', + points: 0.225, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.1.4.2', + nom: 'Interpeller officiellement le niveau national voire européen sur les blocages rencontrés', + points: 0.225, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.1.4.3', + nom: 'Proposer les évolutions législatives, réglementaires et autres initiatives', + points: 0.225, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.1.4.4', + nom: 'Prendre position et/ou mener des actions lors de procédures de consultation ordinaires (lois, ordonnances, planifications, infrastructures de transport, etc.) attestées par des documents écrits', + points: 0.225, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.1.1.5', + nom: 'Mettre en place des actions au niveau international', + points: 1.5, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_6.1.1.5.1', + nom: 'S’engager dans des projets européens (LIFE, Interreg…)', + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.1.5.2', + nom: 'Sensibiliser les élus, agents et acteurs du territoire aux enjeux de la coopération décentralisée (via des expositions par exemple)', + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.1.5.3', + nom: 'Intégrer les questions climat air énergie dans les accords existants de coopération décentralisée', + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.1.5.4', + nom: 'Monter un ou plusieurs projets de coopération décentralisée sur les thématiques climat air énergie', + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.1.5.5', + nom: "Budgéter l'aide au développement et les projets de coopération décentralisée (% du budget consacré à ce sujet)", + points: 0.3, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_6.1.2', + nom: "Renforcer la coopération au sein de l'intercommunalité", + points: 4, + pourcentage: 28.57142857142857, + actions_enfant: [ + { + action_id: 'cae_6.1.2.1', + nom: 'Partager une stratégie climat-air-énergie commune', + points: 0.8, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.1.2.1.1', + nom: 'Echanger/relayer/diffuser des données, des documents et des bonnes pratiques entre EPCI et communes membres, concernant leur politique climat air énergie', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.2.1.2', + nom: 'Etre à l’initiative ou participer à des rencontres ponctuelles bilatérales commune/intercommunalité en lien avec le climat, l’air et l’énergie', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.1.2.2', + nom: 'Connaître les rôles de chacun en matière de climat, d’air et d’énergie', + points: 0.8, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.1.2.2.1', + nom: 'Sur les thématiques en lien avec le climat, l’air et l’énergie, les rôles et compétences de chacun (intercommunalité/commune) sont clairs', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.2.2.2', + nom: 'Les interlocuteurs climat-air-énergie principaux dans chaque collectivité sont connus et ont été rencontrés', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.1.2.3', + nom: 'Initier et/ou participer à des actions mutualisées sur le territoire', + points: 1.6, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'cae_6.1.2.3.1', + nom: 'EPCI : la collectivité est animatrice sur le sujet climat-air-énergie sur son territoire.', + points: 0.8, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.2.3.2', + nom: 'Commune : la collectivité est force de proposition auprès de l’intercommunalité pour la mise en place d’actions mutualisées et participe régulièrement aux actions collectives proposées par son EPCI.', + points: 0.8, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.1.2.4', + nom: 'Systématiser la coopération intercommunale et donner l’exemple sur le territoire', + points: 0.8, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.1.2.4.1', + nom: 'EPCI: Mettre en place un outil global pour accompagner les communes membres sur les thématique climat-air-énergie', + points: 0.16, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.2.4.2', + nom: 'EPCI: Réflechir sur de nouveaux outils juridico-financiers pour faciliter le passage à l’acte des communes', + points: 0.16, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.2.4.3', + nom: 'EPCI: Institutionnaliser les réunions thématiques avec les communes membres', + points: 0.16, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.2.4.4', + nom: 'Commune: Elle donne l’exemple au sein de l’EPCI', + points: 0.16, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.2.4.5', + nom: 'Commune: Participation quasi-systématique aux actions proposées par l’EPCI', + points: 0.16, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_6.1.3', + nom: 'Développer un plan de communication pour chaque cible du territoire', + points: 4, + pourcentage: 28.57142857142857, + actions_enfant: [ + { + action_id: 'cae_6.1.3.1', + nom: 'Connaître les besoins, identifier les cibles prioritaires et budgéter le plan de communication', + points: 0.8, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.1.3.1.1', + nom: 'Connaître les besoins en information et identifier des différents publics cibles', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.3.1.2', + nom: 'Définir le budget, les ressources humaines et le calendrier (dates ou périodicité) prévus pour les manifestations et actions de communication', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.1.3.2', + nom: 'Décliner l’identité climat air énergie de la collectivité dans les différents supports de communication', + points: 1.2, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_6.1.3.2.1', + nom: 'Prendre en compte la thématique climat air énergie dans la charte graphique de la collectivité', + points: 0.17142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.3.2.2', + nom: 'Mettre en avant des déclarations claires relatives aux questions énergétiques et climatiques sur le site internet de la collectivité', + points: 0.17142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.3.2.3', + nom: 'Mentionner régulièrement les démarches et actions climat air énergie dans les différents supports de communication établis et/ou utilisés par la collectivité', + points: 0.17142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.3.2.4', + nom: 'Exploiter les moyens de communication existants pour diffuser les informations', + points: 0.17142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.3.2.5', + nom: 'Mettre en avant des installations et projets exemplaires dans le secteur des énergies renouvelables et de la lutte contre le changement climatique', + points: 0.17142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.3.2.6', + nom: 'Promouvoir la sobriété et l’efficacité énergétiques dans tous les documents de communication et pédagogiques de la collectivité, notamment ses rapports d’engagements et d’objectifs', + points: 0.17142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.3.2.7', + nom: 'Etre cohérent dans le travail quotidien et les décisions prises', + points: 0.17142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.1.3.3', + nom: 'Donner du poids et crédibiliser les actions de la collectivité dans sa communication', + points: 0.4, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.1.3.4', + nom: 'Décliner le plan de communication pour chaque cible du territoire', + points: 1.2, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_6.1.3.4.1', + nom: 'Mettre en place des supports de communication différenciés selon les cibles (contenu, médias et lieux de diffusion...)', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.3.4.2', + nom: "Pour les collectivités comptant moins de 15 000 hab, mutualiser l’élaboration de supports de communication avec d'autres collectivités.", + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.3.4.3', + nom: 'Mettre en place des actions (évènements) nombreuses et variées (lieux, formes, horaires) sur les thèmes climat-air-énergie.', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.1.3.5', + nom: 'Contrôler et évaluer l’efficacité du plan de communication', + points: 0.4, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_6.1.3.5.1', + nom: "Evaluer et contrôler de l'efficacité des actions par des enquêtes auprès des différentes cibles", + points: 0.13333333333333336, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.3.5.2', + nom: "Etre identifié depuis l'extérieur et depuis l'intérieur comme étant une \"collectivité engagée et/ou novatrice dans les secteurs de l'énergie, de l'environnement et du climat\"", + points: 0.13333333333333336, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.1.3.5.3', + nom: 'Communiquer aux acteurs du territoire les démarches et actions climat air énergie menées sur le territoire (Territoire Engagé, TEPOS, PCAET…) et leur mettre à disposition le suivi et l’évaluation de ces démarches (transparence de la collectivité)', + points: 0.13333333333333336, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + { + action_id: 'cae_6.2', + nom: 'Bâtiments résidentiels et tertiaires', + points: 34, + pourcentage: 34, + actions_enfant: [ + { + action_id: 'cae_6.2.1', + nom: "Coopérer avec les acteurs professionnels du bâtiment et de l'immobilier", + points: 10, + pourcentage: 29.411764705882355, + actions_enfant: [ + { + action_id: 'cae_6.2.1.1', + nom: "Disposer d'une connaissance fine des acteurs du bâtiment et de l'immobilier privé et les sensibiliser aux enjeux climat-air-énergie", + points: 3, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_6.2.1.1.1', + nom: "Se doter d’une bonne connaissance des acteurs du bâtiment et de l'immobilier privé de son territoire", + points: 0.6, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.1.1.2', + nom: 'Informer les acteurs du bâtiment et de l’immobilier sur la politique énergétique et climatique de la collectivité et sur les objectifs à atteindre dans le secteur du bâtiment et de la mobilité pour les différentes cibles (propriétaires occupants ou bailleurs, logements individuels ou collectifs…)', + points: 0.6, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.1.1.3', + nom: 'Informer les acteurs du bâtiment et de l’immobilier sur la vulnérabilité du territoire au changement climatique', + points: 0.6, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.1.1.4', + nom: 'Informer les acteurs du bâtiment et de l’immobilier des dispositifs mis en place au niveau régional et local ainsi que des formations disponibles, en s’appuyant sur les acteurs de la formation professionnelle de son territoire', + points: 0.6, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.1.1.5', + nom: 'Informer les aménageurs sur les dispositifs permettant de développer les usages cyclables', + points: 0.6, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.2.1.2', + nom: 'Animer et inciter les acteurs à qualifier leurs pratiques', + points: 3, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_6.2.1.2.1', + nom: 'Favoriser l’animation des acteurs avec mise en place de dispositifs variés (ateliers, visites, rencontres, formation) afin de créer une culture commune sur le territoire', + points: 1, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.1.2.2', + nom: 'Favoriser la mise en réseau des professionnels du bâtiment et leur visibilité au travers du label RGE', + points: 1, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.1.2.3', + nom: 'Favoriser les exonérations fiscales (taxe foncière) et bonification des droits à construire pour inciter les acteurs privés à la construction (promoteurs/investisseurs) et à la rénovation durable', + points: 1, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.2.1.3', + nom: 'Les bailleurs sociaux sont engagés aux côtés de la collectivité dans des actions particulièrement ambitieuses', + points: 2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.2.1.4', + nom: 'Disposer d’une stratégie de mobilisation des professionnels du bâtiment et de l’immobilier formalisée', + points: 2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_6.2.2', + nom: 'Prévenir et lutter contre la précarité énergétique', + points: 6, + pourcentage: 17.647058823529413, + actions_enfant: [ + { + action_id: 'cae_6.2.2.1', + nom: 'Réaliser un état des lieux de la précarité énergétique liée au logement et à la mobilité sur le territoire', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.2.2.1.1', + nom: 'Disposer de la liste des acteurs intervenants sur la thématique de précarité, susceptibles d’intégrer la question de la précarité énergétique liée au logement et à la mobilité sur le territoire', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.2.1.2', + nom: "Réaliser un diagnostic afin d'identifier et caractériser les ménages en situation de précarité énergétique", + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.2.1.3', + nom: 'Cartographier les zones d’intervention (OPAH, PIG, programme de rénovation urbaine...) et les comparer aux zones où statistiquement il peut y avoir de la précarité', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.2.2.2', + nom: 'Adopter une stratégie de lutte contre la précarité énergétique liée au logement et à la mobilité', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.2.2.2.1', + nom: 'Introduire la lutte contre la précarité énergétique comme un enjeu prioritaire de la politique du territoire dans les différents documents directeurs (PLH, PDU…)', + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.2.2.2', + nom: 'Fixer et formaliser dans les documents du territoire des objectifs et des orientations en matière de lutte contre la précarité énergétique et de recherche de baisse des charges pour les usagers', + points: 0.6, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.2.2.3', + nom: 'Fédérer les acteurs autour de la problématique de la précarité énergétique afin d’initier la prévention contre la précarité énergétique', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.2.2.3.1', + nom: 'Coordonner et fédérer les acteurs locaux gravitant autour de la précarité énergétique pour le logement et pour la mobilité', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.2.3.2', + nom: 'Sensibiliser les élus et les services à la lutte contre la précarité énergétique', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.2.3.3', + nom: 'Informer et sensibiliser les ménages sur la précarité énergétique liée au logement, à la mobilité', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.2.3.4', + nom: 'Sensibiliser et communiquer sur les outils existants', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.2.3.5', + nom: "Sensibiliser les acteurs et les habitants sur les enjeux sanitaires liés à une mauvaise qualité de l'air intérieur", + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.2.2.4', + nom: "Formaliser une offre d'outils à destination des ménages en situation de précarité", + points: 2.4, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'cae_6.2.2.4.1', + nom: 'Développer et proposer une aide financière locale à destination des ménages en situation de précarité énergétique', + points: 0.48, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.2.4.2', + nom: "Mettre en place des actions de suivi et d'accompagnement des ménages précaires", + points: 0.48, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.2.4.3', + nom: "Mettre en place des actions conjointes avec les acteurs de l'hébergement pour diminuer la facture énergétique des logements et les inciter à des constructions et rénovations performantes, à recourir aux solutions énergétiques les moins onéreuses", + points: 0.48, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.2.4.4', + nom: 'Utiliser les outils existants et en créer des nouveaux', + points: 0.48, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.2.4.5', + nom: "Monter des partenariats pour proposer/élaborer une offre de solutions alternatives afin d'éviter les déplacements contraints en véhicule individuel pour les publics précaires", + points: 0.48, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_6.2.3', + nom: 'Accompagner les particuliers pour la rénovation et la construction durable de leur logement (habitat individuel et collectif)', + points: 10, + pourcentage: 29.411764705882355, + actions_enfant: [ + { + action_id: 'cae_6.2.3.1', + nom: 'Disposer de services d’information climat-air-énergie visibles et accessibles pour le particulier', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.2.3.1.1', + nom: "Promouvoir activement l'offre d'information et de conseils", + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.3.1.2', + nom: "Disposer de structures d'accueil centrales, ouvertes au moins une fois par semaine", + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.3.1.3', + nom: "Disposer d’un service d'information neutre pour les questions concernant le climat, l'air et l'énergie dans le bâtiment pour les particuliers", + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.3.1.4', + nom: "Simplifier l’accès à ces services d'information (lieu, prix) pour le grand public", + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.2.3.2', + nom: 'Adresser des conseils pour la rénovation BBC notamment, et la construction, à des cibles variées', + points: 2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.2.3.3', + nom: 'Accompagner le particulier jusqu’aux travaux de rénovation énergétique', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.2.3.3.1', + nom: "S'appuyer a minima sur les missions de son espace conseil France Rénov pour guider le particulier dans son parcours de rénovation de son logement.", + points: 1, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.3.3.2', + nom: 'Disposer d’un espace conseil France Rénov actif sur son territoire pour accompagner le particulier jusqu’aux travaux, qui inclut des prestations avancées', + points: 1, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.2.3.4', + nom: 'Soutenir financièrement le particulier', + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.2.3.4.1', + nom: 'Des aides financières ponctuelles existent à la rénovation niveau BBC (notamment) et la construction durable', + points: 0.6666666666666667, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.3.4.2', + nom: "Mettre en place des programmes de financement globaux, cohérents et partenariaux, ou pour certains publics ANRU, OPAH, PIG, CLE ou équivalents pour une massification des actions de rénovation de l'habitat", + points: 0.6666666666666667, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.3.4.3', + nom: 'Couvrir par les aides financières des publics ANAH et hors ANAH', + points: 0.6666666666666667, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.2.3.5', + nom: 'Mesurer les résultats de l’accompagnement', + points: 1, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_6.2.3.5.1', + nom: 'Contrôler les résultats des consultations', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.3.5.2', + nom: 'Nombre de consultations et temps accordé pour le conseil', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.3.5.3', + nom: 'Communiquer et transmettre les indicateurs à ceux qui en font la demande, et en particulier les communes', + points: 0.33333333333333337, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.2.3.6', + nom: "Mettre en place un dispositif de suivi des projets subventionnés pour analyser l'efficacité des moyens investis", + points: 1, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_6.2.4', + nom: 'Accompagner les acteurs du secteur tertiaire pour la rénovation et la construction durable de leurs locaux', + points: 8, + pourcentage: 23.52941176470588, + actions_enfant: [ + { + action_id: 'cae_6.2.4.1', + nom: 'Disposer de services d’information climat-air-énergie visibles et accessibles pour les acteurs tertiaires', + points: 1.6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.2.4.1.1', + nom: "Promouvoir activement l'offre d'information et de conseils en partenariat avec les acteurs spécialisés", + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.4.1.2', + nom: "Disposer de structures d'accueil centrales, ouvertes au moins une fois par semaine", + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.4.1.3', + nom: "Disposer d’un service d'information neutre pour les questions concernant le climat, l'air et l'énergie dans le bâtiment pour le secteur tertiaire privé", + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.4.1.4', + nom: "Simplifier l’accès à ces services d'information (lieu, prix) pour les acteurs tertiaires", + points: 0.4, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.2.4.2', + nom: 'Aller au-delà du conseil ponctuel pour la rénovation durable du secteur tertitaire privé', + points: 2.4, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_6.2.4.2.1', + nom: 'Accompagner concrètement les entreprises du secteur tertiaire (TPE/PME et commerçants notamment) et les artisans pour améliorer la performance climat-air-énergie de leurs locaux en partenariat avec les acteurs spécialisés (chambres consulaires...)', + points: 1.2, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.4.2.2', + nom: 'Soutenir spécifiquement les entreprises tertiaires > 1000 m² soumises aux obligations du "Décret Tertiaire"', + points: 1.2, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.2.4.3', + nom: 'Rationaliser et mutualiser la construction de nouveaux locaux tertiaires', + points: 0.8, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_6.2.4.3.1', + nom: 'Mettre en relation les disponibilités (recensement de bureaux délaissés/inoccupés) et les besoins en bureaux ou salles de réunion des principales TPE/PME et collectivités, afin d’optimiser l’utilisation des locaux existants.', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.4.3.2', + nom: 'Favoriser l’implantation d’activité de co-working sur le territoire', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.2.4.4', + nom: "Inciter à la limitation des consommations d'électricité spécifique propres au secteur tertiaire", + points: 0.8, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_6.2.4.4.1', + nom: 'Aider à la mise en place d’un système de management énergétique et inciter à la certification des entreprises (ISO 50 001, ISO 26 000…)', + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.4.4.2', + nom: "Sensibiliser et diffuser les bonnes pratiques en matière d'utilisation sobre des technologiques numériques, de l'éclairage, des équipements de réfrigération dans les commerces...", + points: 0.4, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.2.4.5', + nom: 'Coopérer avec les autres acteurs du tertiaire public sur le territoire (enseignement, hôpitaux, services administratifs...)', + points: 0.8, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.2.4.6', + nom: "Mesurer les résultats de l’activité d'accompagnement", + points: 1.6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.2.4.6.1', + nom: 'Le nombre de consultations émanant des acteurs tertiaires privés est en augmentation', + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.4.6.2', + nom: "Des locaux tertiaires rénovés (BBC rénovation) ou neufs exemplaires (E+C-, certification HQE…), ayant fait l'objet du soutien de la collectivité, sont présents sur le territoire", + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.2.4.6.3', + nom: 'Suivre le respect des obligations de performance du décret tertiaire sur son territoire', + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + { + action_id: 'cae_6.3', + nom: 'Activités économiques', + points: 18, + pourcentage: 18, + actions_enfant: [ + { + action_id: 'cae_6.3.1', + nom: 'Favoriser les activités économiques durables', + points: 8, + pourcentage: 44.44444444444444, + actions_enfant: [ + { + action_id: 'cae_6.3.1.1', + nom: 'Partager la stratégie, les connaissances et les enjeux liés aux entreprises au sein de la collectivité', + points: 1.2, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_6.3.1.1.1', + nom: 'Travailler en transversalité entre le service/chef de projet développement économique (ou équivalent) et d’autres services, sur des projets communs', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.1.1.2', + nom: 'Définir précisément le champ d’exercice de la compétence « développement économique »', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.1.1.3', + nom: 'Disposer d’un argumentaire clair pour inciter les entreprises à mettre en place des actions en faveur de la transition énergétique et climatique', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.3.1.2', + nom: 'Capitaliser et travailler en partenariat avec les acteurs spécialisés', + points: 1.6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.3.1.2.1', + nom: 'Identifier les acteurs spécialisés au contact des entreprises, connaître leurs actions et leur présenter la politique climat-air-énergie de la collectivité', + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.1.2.2', + nom: 'Recenser les bonnes pratiques des entreprises du territoire, les entreprises « locomotives » pouvant servir de relais et d’exemples', + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.1.2.3', + nom: "Formations des développeurs d’entreprises sur les enjeux et bonnes pratiques climat-air-énergie en entreprise ; travailler avec eux pour identifier et hiérarchiser les enjeux les plus importants à porter auprès des entreprises, et intégrer ensuite ces thématiques dans les documents d'accueil ou services d'accompagnement proposés par la collectivité", + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.3.1.3', + nom: "Améliorer la qualité et la mixité des zones d'activités économiques", + points: 1.6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.3.1.3.1', + nom: "Mettre en place et qualifier les missions des gestionnaires de zones d'activités pour un aménagement adapté et inclusif", + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.1.3.2', + nom: "Décliner des orientations stratégiques fortes en matière de localisation et de qualité environnementale des zones d'activités dans les documents d’urbanisme", + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.1.3.3', + nom: 'Faire certifier les zones d’activités (norme ISO 14001 / règlement EMAS)', + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.3.1.4', + nom: 'Impliquer les entreprises dans des projets d’écologie industrielle structurés et collectifs', + points: 2, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_6.3.1.4.1', + nom: 'Identifier les périmètres pertinents pour développer le concept d’écologie industrielle et inviter les entreprises à identifier les synergies possibles', + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.1.4.2', + nom: "Elaborer un document pour formaliser les engagements des entreprises dans un projet d'écologie industrielle/économie circulaire", + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.1.4.3', + nom: "S'impliquer ou soutenir l'utilisation de la démarche territoriale/label \"économie circulaire\" à l'échelle pertinente", + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.1.4.4', + nom: 'Dans les DOM, Réaliser des actions spécifiques pour la filière "bateau"', + points: 0.5, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.3.1.5', + nom: 'Maintenir une dynamique économique, en adéquation avec les besoins d’une société bas carbone', + points: 1.6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.3.1.5.1', + nom: 'Renforcer le rôle de relais des commerçants et artisans auprès de leurs clients, pour modifier les habitudes de consommation', + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.1.5.2', + nom: 'Soutenir l’artisanat et les commerces de proximité', + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.1.5.3', + nom: 'Maintenir ou développer l’attractivité économique de son territoire, en adéquation avec les besoins d’une société bas carbone', + points: 0.5333333333333334, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_6.3.2', + nom: 'Développer un tourisme durable', + points: 4, + pourcentage: 22.22222222222222, + actions_enfant: [ + { + action_id: 'cae_6.3.2.1', + nom: 'Identifier les enjeux et les bonnes pratiques en matière de tourisme durable sur le territoire', + points: 0.4, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_6.3.2.1.1', + nom: "Identifier les pratiques de tourisme durable dans l'offre existante notamment les établissements labellisés (ex : Ecolabel européen).", + points: 0.13333333333333336, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.1.2', + nom: 'Identifier les acteurs touristiques clés sur le territoire, les professionnels volontaires et les axes de progression', + points: 0.13333333333333336, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.1.3', + nom: 'Connaître les impacts environnementaux des activités touristiques locales et leur vulnérabilité au changement climatique et formaliser les enjeux prioritaires au regard de ce diagnostic, en concertation avec les acteurs concernés', + points: 0.13333333333333336, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.3.2.2', + nom: 'Mobiliser les acteurs du tourisme', + points: 0.6, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_6.3.2.2.1', + nom: 'Engager l’Office de Tourisme dans une démarche éco-responsable', + points: 0.1, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.2.2', + nom: 'Valoriser par l’office de tourisme des acteurs du tourisme engagés dans une démarche de tourisme durable', + points: 0.1, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.2.3', + nom: 'Sensibiliser aux enjeux climat-air-énergie, l’ensemble des acteurs professionnels et associatifs', + points: 0.1, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.2.4', + nom: 'Accueillir de façon responsable, sensibiliser et impliquer les travailleurs saisonniers', + points: 0.1, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.2.5', + nom: 'Développer un programme de formation à la réduction des émissions de gaz à effet de serre, des consommations énergétiques et la protection de l’environnement pour ces acteurs et favoriser le partage des bonnes pratiques', + points: 0.1, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.2.6', + nom: "Sensibiliser les touristes aux enjeux du tourisme durable et inciter aux bonnes pratiques (publicité pour des infrastructures touristiques durables, incitation à l'utilisation de transports collectifs, tri des déchets, etc.) via des campagnes de communication, l'organisation d'événements sur les sites touristiques, ...", + points: 0.1, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.3.2.3', + nom: 'Développer une offre touristique de haute qualité environnementale (hors mobilité)', + points: 1, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_6.3.2.3.1', + nom: "Développer des activités touristiques au contenu pédagogique permettant l'éducation à l'environnement et aux enjeux climat air énergie, en particulier à destination des jeunes", + points: 0.2, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.3.2', + nom: "Créer des partenariats visant l’information et la sensibilisation aux enjeux énergie climat sur le territoire ou tout autre particularité environnementale du territoire ainsi que les produits locaux, la promotion de l'artisanat local, etc. entre professionnels de l'hébergement et de la restauration et les autres acteurs du territoire", + points: 0.2, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.3.3', + nom: "Augmenter le nombre de structures touristiques labellisées (Ecolabel européen notamment), par exemple en soutenant une opération collective d'éco labellisation de professionnels de la restauration et de l'hébergement", + points: 0.2, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.3.4', + nom: "Soutenir la création d'entreprises œuvrant pour le tourisme durable par le biais d'appels à projets, de valorisation médiatique, de soutiens financiers", + points: 0.2, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.3.5', + nom: 'Créer des événements touristiques sur le territoire éco-responsables au travers un engagement via une charte et visant la certification ISO 20121:2012 (évènements intégrant le développement durable)', + points: 0.2, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.3.2.4', + nom: 'Mettre en place une offre globale de mobilité durable en lien avec le tourisme', + points: 1, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_6.3.2.4.1', + nom: 'Faciliter l’accès pour se rendre sur le territoire par les transports en commun. Promouvoir l’usage des transports en commun sur tous les supports de communication', + points: 0.16666666666666669, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.4.2', + nom: 'Faciliter l’accès à l’intérieur du territoire aux activités/hébergements par les transports en commun. Promouvoir l’usage des transports en commun sur tous les supports de communication', + points: 0.16666666666666669, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.4.3', + nom: 'Identifier et remettre en état / développer les circuits de randonnée pédestres et cyclables touristiques sur le territoire', + points: 0.16666666666666669, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.4.4', + nom: "Interdire/contraindre fortement l'accès aux véhicules motorisés sur une ou des parties particulièrement sensibles et fréquentées du territoire", + points: 0.16666666666666669, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.4.5', + nom: 'Création de circuits touristiques sans voiture, de services de mobilité en particulier pour le “dernier kilomètre” en lien avec les hébergements', + points: 0.16666666666666669, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.4.6', + nom: 'Prendre en compte le déplacement des saisonniers dans l’offre de transports et de logements', + points: 0.16666666666666669, + pourcentage: 16.666666666666668, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.3.2.5', + nom: 'Intégrer et formaliser de manière ambitieuse l’enjeu du tourisme durable dans la vision climat air énergie du territoire', + points: 1, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_6.3.2.5.1', + nom: 'Porter une offre touristique durable et adaptée au changement climatique dans le discours politique et les documents de planification', + points: 0.2, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.5.2', + nom: 'Adhérer collectivement à des chartes à l’échelle du territoire', + points: 0.2, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.5.3', + nom: "Présence d'orientations stratégiques fortes en matière de qualité environnementale des zones d'activités touristiques", + points: 0.2, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.5.4', + nom: "Créer une taxe locale sur les prestations touristiques et de loisirs pour financer des projets d'adaptation sur le territoire", + points: 0.2, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.2.5.5', + nom: 'Gérer de façon durable les zones de baignade et/ou les stations de ski et les distinguer par une labellisation', + points: 0.2, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_6.3.3', + nom: "Contribuer à l'innovation et l'excellence sur la thématique climat-air-énergie", + points: 6, + pourcentage: 33.33333333333333, + actions_enfant: [ + { + action_id: 'cae_6.3.3.1', + nom: 'Mener une veille pro-active sur les acteurs et projets phares', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.3.3.1.1', + nom: "Recenser les acteurs privés et ceux de la recherche, de l'enseignement supérieur, de la formation professionnelle (GRETA, lycée agricole, CFA, MFR…), qui sont susceptibles de mener des projets sur les thématiques climat-air-énergie (situés sur le territoire ou à proximité de celui-ci pour le milieu rural)", + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.3.1.2', + nom: 'Rencontrer des acteurs pour étudier des partenariats sur des projets concrets et/ou des axes de recherches et de formations', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.3.1.3', + nom: 'Recenser les principaux appels à projets, notamment européens, et informer les acteurs du territoire qui seraient susceptibles d’y répondre', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.3.3.2', + nom: 'Formaliser l’engagement de la collectivité dans le soutien des projets des acteurs privés', + points: 0.6, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.3.3.3', + nom: 'Participer à des études et des recherches pour faire progresser les connaissances et techniques', + points: 1.5, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_6.3.3.3.1', + nom: "Mener des études et recherches avec les organismes de formation (stagiaires, apprentis), les établissements d'enseignements supérieurs ou de recherche", + points: 0.75, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.3.3.2', + nom: 'Se proposer comme territoire test/pilote pour des projets de recherche/expérimentation', + points: 0.75, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.3.3.4', + nom: 'S’investir et se mobiliser concrètement sur des réalisations ambitieuses', + points: 1.5, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_6.3.3.4.1', + nom: 'Les projets soutenus vont au-delà de la réglementation, intègrent des performances environnementales et climatiques chiffrées, dans une approche transversale et sont menés dans une approche participative.', + points: 0.2142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.3.4.2', + nom: "Organiser des réunions régulières entre la maîtrise d'ouvrage privée, la maîtrise d'œuvre et la collectivité", + points: 0.2142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.3.4.3', + nom: "La collectivité a tiré vers le haut les objectifs fixés pour le projet et a aidé à mettre en place un dispositif d'évaluation des performances du projet", + points: 0.2142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.3.4.4', + nom: 'Formuler des avis techniques ou organisationnels sur le projet', + points: 0.2142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.3.4.5', + nom: 'Mobiliser des outils ou du personnel de la collectivité pour suivre le projet et fournir des conseils', + points: 0.2142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.3.4.6', + nom: 'Communiquer sur le projet', + points: 0.2142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.3.4.7', + nom: 'Permettre la formation de partenariats entre les acteurs décrits précédemment (privés, enseignement, recherche, …), en les mettant en relation grâce à son rôle d’animateur, médiateur', + points: 0.2142857142857143, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.3.3.5', + nom: 'Etre un territoire d’innovation et d’excellence sur certaines thématiques', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.3.3.5.1', + nom: "Etre membre d’un pôle de compétitivité, pôle d'excellence rural, cluster et/ou etre lauréat d’un appel à projet sur le développement durable, notamment européen (LIFE, H2020, etc...)", + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.3.5.2', + nom: "Existance d'une offre de formation locale et diversifiée (thématiques et niveaux de qualification) aux métiers utiles à la transition énergétique et climatique", + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.3.3.5.3', + nom: 'Se positionner clairement contre les grands projets nuisibles en matière d’impacts sur le climat, la qualité de l’air ou la consommation d’énergie ou l’utilisation des terres agricoles sous l’influence de son territoire', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + { + action_id: 'cae_6.4', + nom: 'Agriculture, forêt', + points: 18, + pourcentage: 18, + actions_enfant: [ + { + action_id: 'cae_6.4.1', + nom: 'Soutenir une agriculture et une alimentation plus durable', + points: 12, + pourcentage: 66.66666666666666, + actions_enfant: [ + { + action_id: 'cae_6.4.1.1', + nom: 'Réaliser un diagnostic agricole et alimentaire de son territoire', + points: 1.2, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.4.1.2', + nom: 'Animer son territoire sur le sujet de l’agriculture et de l’alimentation durable', + points: 1.2, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_6.4.1.2.1', + nom: 'Initier une concertation entre les acteurs (réunions professionnelles, réunions publiques…)', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.2.2', + nom: 'Mener des actions de sensibilisation (réunions publiques, films, intervenants extérieurs, théâtre, expos, défis Famille à alimentation positive…)', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.2.3', + nom: 'Mettre en relation les acteurs', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.4.1.3', + nom: 'Améliorer la performance environnementale de la production agricole', + points: 1.8, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_6.4.1.3.1', + nom: 'Favoriser le développement de pratiques agroécologiques, l’installation de producteurs bios/ avec des pratiques agro-écologiques, favoriser les conversions en bio, soutenir les groupements locaux d’agriculture biologique (GAB)', + points: 0.6000000000000001, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.3.2', + nom: 'Encourager les filières locales à rentrer dans des logiques de performance environnementale et d’écoconception', + points: 0.6000000000000001, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.3.3', + nom: 'Travailler avec les AOC, IGP, marques régionales etc. pour qualifier les productions', + points: 0.6000000000000001, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.4.1.4', + nom: 'Reterritorialiser l’alimentation de la collectivité et contribuer à sa résilience alimentaire', + points: 1.8, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_6.4.1.4.1', + nom: 'Accompagner la diversification des productions agricoles locales pour répondre aux besoins du territoire (légumes secs, fruits et légumes frais de saison, etc.)', + points: 0.225, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.4.2', + nom: 'Intégrer les questions d’approvisionnement alimentaire (durable) dans les réflexions urbanistiques : types de commerces, marchés de détails et marché de gros (MIN), accès aux modes doux…', + points: 0.225, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.4.3', + nom: 'Favoriser l’accès à la terre et les regroupements de producteurs locaux pour optimiser la logistique du dernier kilomètre et l’installation de boutiques paysans', + points: 0.225, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.4.4', + nom: 'Valoriser les produits locaux / filières locales de qualité (création de marché de producteurs locaux, guide, cartographie…)', + points: 0.225, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.4.5', + nom: 'En milieu urbain, accompagner l’installation de fermes urbaines durables ; de jardins partagés ou pédagogiques, des ruches (dans le respect de la biodiversité locale de pollinisateurs), les plantations comestibles en milieu urbain, encourager la multiplication des potagers privés (sensibiliser aux pratiques agro-écologiques, enjeux environnementaux et sanitaires)', + points: 0.225, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.4.6', + nom: 'Favoriser / soutenir les initiatives d’accès à tous à une alimentation saine et durable. Faire se rencontrer les acteurs de l’alimentation, de la santé et du social', + points: 0.225, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.4.7', + nom: 'Mettre en place ou soutenir les actions de sensibilisation du grand public à l’alimentation durable', + points: 0.225, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.4.8', + nom: 'Préserver les terres agricoles via les documents d’urbanisme', + points: 0.225, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.4.1.5', + nom: 'Modifier les habitudes alimentaires, notamment dans la restauration collective, en respectant les obligations de la loi EGalim et en s’engageant plus loin', + points: 1.8, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_6.4.1.5.1', + nom: 'Revoir les approvisionnements en restauration collective publique', + points: 0.225, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.5.2', + nom: 'Informer les convives sur l’origine, la saisonnalité et la qualité des produits servis (Egalim et autres critères de qualité / durabilité); mettre en place un affichage environnemental et nutritionnel des menus', + points: 0.225, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.5.3', + nom: 'Diversifier les apports alimentaires, en cohérence avec les nouvelles recommandations de Santé Publique France', + points: 0.225, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.5.4', + nom: 'Lutter contre le gaspillage alimentaire (ajuster les quantités aux besoins, sensibiliser les convives, organiser des pesées annuelles sur une semaine, etc.)', + points: 0.225, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.5.5', + nom: 'Lors des achats de matériels/rénovations importantes, réfléchir sur la globalité du repas (besoin en légumerie, cuisson basse température, contenants de différentes tailles pour les petites/grandes faims, salade bar, …)', + points: 0.225, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.5.6', + nom: "Former les cuisinier·es et le personnel de cantine à l'introduction de produits bio locaux et à la diversification des protéines, et plus globalement aux enjeux environnementaux, et leur fournir un corpus de recettes adaptées à la restauration collective. Les former également aux démarches de réduction du gaspillage alimentaire.", + points: 0.225, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.5.7', + nom: 'Former les acheteur·ses et les gestionnaires impliqué·es dans la restauration collective aux questions environnementales, sociales, sanitaires de l’alimentation, aux achats bios/locaux et aux démarches de réduction du gaspillage alimentaire.', + points: 0.225, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.5.8', + nom: 'Mener des actions spécifiques en restauration scolaire', + points: 0.225, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.4.1.6', + nom: 'Participer concrètement à des installations et au maintien des pratiques agricoles durables', + points: 1.8, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_6.4.1.6.1', + nom: 'Créer une régie agricole et/ou utiliser de baux environnementaux', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.6.2', + nom: 'Acquérir, mettre en réserve ou mettre à disposition du foncier en partenariats avec des associations (exemple Foncière Terre de Liens)', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.6.3', + nom: 'Installer des porteurs de projets exemplaires et créer des espaces-test', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.6.4', + nom: 'dans les DOM, les mesures spécifiques DOM plan Ecophyto sont déclinées/soutenues localement', + points: 0.45, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.4.1.7', + nom: 'Adopter une vision globale grâce à la formalisation d’un Projet Alimentaire Territorial (PAT)', + points: 0.6, + pourcentage: 5, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.4.1.8', + nom: 'Mesurer et atteindre des objectifs ambitieux en matière d’agriculture et d’alimentation durable', + points: 1.8, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_6.4.1.8.1', + nom: "Mettre en place et suivre des indicateurs en matière d'intrants (fréquence, quantité, produits...) selon les cultures, soutien et suivi technique des rendements/coûts/impacts environnementaux d’espaces test agricoles…", + points: 0.36, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.8.2', + nom: 'En restauration collective, sur le gaspillage alimentaire, atteindre l’objectif de 50% de réduction par rapport à la référence nationale du secteur', + points: 0.36, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.8.3', + nom: 'S’engager à au moins 75% de l’alimentation en restauration collective qui soit de qualité ou durable, dont au moins 40% issus de l’agriculture biologique et 50% issue de produits locaux ; poursuivre la diversification alimentaire.', + points: 0.36, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.8.4', + nom: 'Mettre en place un programme pour l’accès à tous à une alimentation saine et durable', + points: 0.36, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.1.8.5', + nom: 'Avoir un pourcentage élevé de Surface Agricole Utile en agricultue biologique.', + points: 0.36, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_6.4.2', + nom: "Soutenir l'utilisation durable des forêts et des espaces boisés", + points: 6, + pourcentage: 33.33333333333333, + actions_enfant: [ + { + action_id: 'cae_6.4.2.1', + nom: 'Sensibiliser élus, services et acteurs du territoire aux enjeux liés à la forêt et aux espaces boisés', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_6.4.2.1.1', + nom: 'Sensibiliser les élus et services de la collectivité et les particuliers à la gestion durable de la forêt et à l’utilisation du bois énergie sur le territoire, de façon complémentaire aux usages matériaux', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.1.2', + nom: 'Sensibiliser les élus à l’utilisation du bois matériau, notamment à l’utilisation du bois dans la construction', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.1.3', + nom: 'Sensibilises élus à l’utilisation optimale du bois', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.1.4', + nom: 'Sensibiliser les élus à la lutte contre la déforestation importée', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.4.2.2', + nom: 'Lutter contre la déforestation importée', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_6.4.2.2.1', + nom: 'Etre attentif à la provenance du bois pour ses fournitures', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.2.2', + nom: 'Dresser une liste des produits alimentaires dont la production est cause de déforestation (par exemple : soja, huile de palme, bœuf et se coproduits, cacao, hévéa) et contrôler leur provenance et les méthodes de production lorsqu’ils sont utilisés pour la restauration publique', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.4.2.3', + nom: 'Réaliser des diagnostics, connaître les enjeux liés à la forêt et aux espaces boisés sur son territoire', + points: 0.9, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_6.4.2.3.1', + nom: 'Réaliser un diagnostic pour identifier les attentes, les besoins, les pratiques et la nature des activités forestières, y compris pour leur adaptation au changement climatique', + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.3.2', + nom: 'Réaliser un diagnostic de la forêt', + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.3.3', + nom: 'Etudier les différents potentiels de la forêt et des espaces boisés dans le cadre d’une démarche territoriale concertée', + points: 0.30000000000000004, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.4.2.4', + nom: 'Formaliser sa stratégie dans des documents de planification dédiés à la forêt et dans les documents d’urbanisme', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_6.4.2.4.1', + nom: 'La collectivité met en œuvre avec les acteurs du territoire un plan de préservation et de valorisation de la forêt', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.4.2', + nom: 'Prendre en compte les zones boisées dans les documents d’urbanisme (zonage approprié, espaces boisés classés, éléments remarquables à protéger et repérés dans les documents graphiques)', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.4.3', + nom: 'Articuler sa stratégie avec les politiques locales de développement (Chartes de Pays, etc.) et les autres dispositifs de gestion forestière (schémas régionaux de gestion forestière, plan de développement de massif) en co-construction avec les acteurs locaux concernés (ex : les Chartes forestières)', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.4.4', + nom: 'Pérenniser un pilotage multi-partenarial de la politique de préservation et de valorisation de la forêt', + points: 0.15, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.4.2.5', + nom: 'Mettre en place les actions définies dans le plan de préservation et valorisation de la forêt permettant une mobilisation durable de bois et un renforcement durable des puits de carbone dans les forêts (biomasse et sols)', + points: 0.9, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_6.4.2.5.1', + nom: 'Protéger les forêts de l’artificialisation des sols et favoriser la restauration des forêts impactées par des évènements extrêmes', + points: 0.18, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.5.2', + nom: 'Favoriser le regroupement forestier', + points: 0.18, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.5.3', + nom: 'Mettre en place des actions pour favoriser l’élaboration des documents de gestion ciblant une production de bois de qualité et encourageant des pratiques sylvicoles comme la conversion des taillis en futaies ; l’amélioration sylvicole des accrus forestiers et en raisonnant les pratiques pouvant avoir des impacts négatifs sur les stocks de carbone du sol', + points: 0.18, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.5.4', + nom: 'Mettre en place des mesures pour favoriser la séquestration de carbone dans les forêts et les espaces boisés (ex : îlots de sénescence, arbres morts...).', + points: 0.18, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.5.5', + nom: 'Mettre en place des actions favorisant l’utilisation optimale du bois (tri du bois, chantiers groupés).', + points: 0.18, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.4.2.6', + nom: 'Prendre en charge, promouvoir et soutenir le développement d’une filière bois-construction locale et à haute performance environnementale', + points: 0.9, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_6.4.2.6.1', + nom: 'Soutenir la structuration et l’optimisation de la filière bois', + points: 0.225, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.6.2', + nom: 'Engager une opération de construction / rénovation bois en adaptant les spécifications techniques aux caractéristiques du bois local', + points: 0.225, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.6.3', + nom: 'Accompagner les acteurs de la filière bois du territoire pour pénétrer le marché de la construction bois sur le territoire et au-delà', + points: 0.225, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.6.4', + nom: 'Porter des actions d’augmentation de la demande, notamment des actions de communication (et de formation) vers les constructeurs de bâtiment, les architectes et maîtres d’œuvre, les particuliers qui font construire', + points: 0.225, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.4.2.7', + nom: 'Prendre en charge, promouvoir et soutenir le développement d’une filière bois-énergie à haute performance environnementale', + points: 0.9, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'cae_6.4.2.7.1', + nom: 'Accompagner le développement d’une offre et d’une demande collective en bois-énergie sur le territoire adapté aux ressources disponibles dans le territoire (réflexion globale et complémentaire avec la filière bois-construction, utilisation de la ressource bocagère…) ; puis développer et sécuriser la filière d’approvisionnement bois-énergie locale en s’appuyant sur la complémentarité des filières et le principe d’utilisation de bois en cascade.', + points: 0.45, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.7.2', + nom: 'Participer à une filière bois énergie sur un bassin plus vaste (selon la ressource en bois disponible sur son territoire)', + points: 0.45, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.4.2.8', + nom: 'Suivre et atteindre ses objectifs en matière de forêt et d’espaces boisés', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_6.4.2.8.1', + nom: 'Connaître le % de surfaces forestières certifiées', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.4.2.8.2', + nom: 'Suivre la séquestration carbone de la forêt et d’autres indicateurs', + points: 0.3, + pourcentage: 50, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + { + action_id: 'cae_6.5', + nom: 'Société civile', + points: 16, + pourcentage: 16, + actions_enfant: [ + { + action_id: 'cae_6.5.1', + nom: 'Mobiliser la société civile en développant la concertation', + points: 6, + pourcentage: 37.5, + actions_enfant: [ + { + action_id: 'cae_6.5.1.1', + nom: 'Définir une organisation et identifier des axes de travail pour entretenir une culture de la collaboration sur le territoire', + points: 2.1, + pourcentage: 35, + actions_enfant: [ + { + action_id: 'cae_6.5.1.1.1', + nom: 'Connaître les différents niveaux d’implication des citoyens : l’information, la consultation, la concertation, la co-production, la codécision, l’auto-gestion', + points: 0.525, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.1.1.2', + nom: 'Formaliser les « règles du jeu » de la concertation : les objectifs et le pouvoir d’influence des instances sont définis clairement, les droits et les devoirs de chacun (collectivité / citoyens) sont annoncés, par exemple dans une charte', + points: 0.525, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.1.1.3', + nom: 'Définir un/des groupes de travail sur des thèmes variés : climat, air, énergie, déchets, eau, assainissement, mobilité…', + points: 0.525, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.1.1.4', + nom: "Institutionnaliser la collaboration entre les habitants et la collectivité sur les thèmes relevant de l'énergie et du climat en définissant un organe participatif et/de concertation ou en se basant sur les groupes de travail déjà existants (qualifier les Conseils de quartier, Conseils de développement, …)", + points: 0.525, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.5.1.2', + nom: 'Conduire une concertation régulière et pérenne', + points: 2.7, + pourcentage: 45, + actions_enfant: [ + { + action_id: 'cae_6.5.1.2.1', + nom: 'Animer et mobiliser régulièrement (au moins trois fois par an) les habitants lors d’ateliers thématiques ou autour de projets particuliers (plan vélo, rénovation d’une école, etc.).', + points: 0.3375, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.1.2.2', + nom: "S'organiser pour faire participer des publics variés en mobilisant des canaux de communication et des formats de concertation variés et adaptés au différents publics", + points: 0.3375, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.1.2.3', + nom: 'Adapter les processus de concertation des habitants au travail collaboratif et à l’expression de la parole de chacun.', + points: 0.3375, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.1.2.4', + nom: 'Mettre en place des formats participatifs favorisant les initiatives avec un budget et des moyens dédiés : budget participatifs, appels à projets, etc.', + points: 0.3375, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.1.2.5', + nom: 'Mobiliser les instances de concertation régulières (conseil de quartier, conseil de développement, ...) pour participer à la construction du PCAET et les tenir informés au moins une fois par an de l’avancée du plan d’actions', + points: 0.3375, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.1.2.6', + nom: 'Impliquer les citoyens sur des questions concrètes qui les concernent directement (à l’échelle du bâtiment, du quartier par exemple), mais également sur des éléments plus stratégiques (contribution à la « vision » globale du territoire dans une approche de transition énergétique)', + points: 0.3375, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.1.2.7', + nom: 'Allouer des délais et des moyens suffisants aux mécanismes participatifs pour une implication de qualité', + points: 0.3375, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.1.2.8', + nom: 'Prévoir si nécessaire une expertise externe afin d’animer les séances, de produire des comptes rendus rapidement, de disposer de lieux conviviaux et adaptés, de matériels informatiques et audiovisuels de qualité.', + points: 0.3375, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.5.1.3', + nom: 'Utiliser les contributions des instances de concertation', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.5.1.3.1', + nom: 'Le travail des habitants est reconnu et rendu public (plaquette de synthèse, article de presse...)', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.1.3.2', + nom: 'Faire systématiquement un retour aux instances participatives pour rendre compte des arbitrages faits au regard des contributions et présenter l’avancée des projets.', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.1.3.3', + nom: 'Evaluer de façon régulière les dispositifs de concertation', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.1.3.4', + nom: "Voter au moins une décision par an par l'organe délibérant de la collectivité issue du travail des groupes de travail", + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_6.5.2', + nom: "Inciter les citoyens et les relais d'opinions à une consommation responsable, limiter l'emprise de la publicité", + points: 6, + pourcentage: 37.5, + actions_enfant: [ + { + action_id: 'cae_6.5.2.1', + nom: "S'organiser en interne et localement pour sensibiliser les habitants", + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_6.5.2.1.1', + nom: 'une personne au sein de la collectivité est spécifiquement chargée des actions de sensibilisation auprès des habitants et est formée aux questions de changement de comportement', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.2.1.2', + nom: 'Définir un budget pour les actions de promotion des comportements éco-responsables des citoyens', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.2.1.3', + nom: 'Dédier un lieu à la sensibilisation climat-air-énergie (il est visible et accessible)', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.5.2.2', + nom: 'Informer et mobiliser les relais d’opinions (partis politiques, associations, ONG)', + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_6.5.2.2.1', + nom: "Les relais d'opinion connaissent les objectifs et les axes de la politique climat-air-énergie de la collectivité", + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.2.2.2', + nom: "Convier les relais d'opinions aux groupes de travail", + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.2.2.3', + nom: "Le nombre d'associations environnementales est important, elles font des propositions constructives, régulières et sont soutenues par la collectivité (convention de partenariat, mise en place de forum des associations, etc.). En fonction du tissu associatif local, les relais d’opinions sont variés d’un territoire à l’autre.", + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.5.2.3', + nom: 'Sensibiliser les habitants sur l’éco-consommation et les éco-gestes', + points: 1.8, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.5.2.4', + nom: 'Montrer l’exemple lors des évènements', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.5.2.4.1', + nom: 'A l\'occasion de manifestations ou à l\'occasion de récompenses à des jeux ou objets "promotionnels", des objets incitant aux comportements éco-responsables sont privilégiés', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.2.4.2', + nom: 'Mettre en place des “ponts” entre les différents postes de consommation', + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.2.4.3', + nom: "Réaliser de manière éco-responsable la tenue des évènements des relais d'opinions", + points: 0.4, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.5.2.5', + nom: 'Limiter l’emprise de la publicité', + points: 1.2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.5.2.5.1', + nom: 'Sensibiliser les habitants à travers des actions rapides et efficaces', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.2.5.2', + nom: "Faire respecter les obligations concernant les enseignes lumineuses et l'affichage par exemple en s’appuyant sur les associations locales pour vous accompagner dans le travail de recensement et de sensibilisation", + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.2.5.3', + nom: 'Mettre en place une taxe locale sur les enseignes et publicités extérieures (TPLE)', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.2.5.4', + nom: 'Devenir une ville sans publicité en instaurant une Zone de Publicité Restreinte', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.2.5.5', + nom: 'Mettre en place un règlement local de publicité (RLP)', + points: 0.24, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.5.2.6', + nom: "Soutenir l’éco-consommation locale, notamment via un système d'échange local ou une monnaie locale", + points: 0.6, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'cae_6.5.2.6.1', + nom: 'Initier la création d’une monnaie locale ou soutenir les associations à l’initiative de ces projets', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.2.6.2', + nom: 'Informer les habitants de l’intérêt d’une monnaie locale', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.2.6.3', + nom: 'Développer des circuits de proximité et favoriser les initiatives de consommation alternative', + points: 0.2, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + { + action_id: 'cae_6.5.3', + nom: "Développer des actions d'éducation et de sensibilisation dans les établissements scolaires et centres de petite enfance", + points: 4, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'cae_6.5.3.1', + nom: 'Rencontrer les acteurs locaux de l’éducation et la petite enfance et s’organiser pour mener des actions communes', + points: 1.2, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'cae_6.5.3.1.1', + nom: 'Définir le budget et les ressources humaines prévus pour les actions de sensibilisation climat-air-énergie dans les écoles et structures d’accueil de jeunes enfants', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.1.2', + nom: 'Présenter les enjeux et la politique climat-air-énergie de la collectivité aux enseignants et professionnels de la petite enfance', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.1.3', + nom: 'Identifier les bonnes pratiques, ressources et projets déjà mis en place dans les structures et les besoins d’accompagnement', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.1.4', + nom: 'Faire travailler les acteurs de l’éducation et de la petite enfance en réseau sur ces sujets (groupe de travail, formation collective…)', + points: 0.3, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.5.3.2', + nom: 'Sensibiliser les enfants aux enjeux climat-air-énergie et à l’éco-citoyenneté', + points: 0.8, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.5.3.2.1', + nom: 'Participer et soutenir la journée ou semaine-évènement sur le climat, l’air ou l’énergie', + points: 0.1, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.2.2', + nom: 'Participer et soutenir le défi inter-écoles ou inter-classes sur le thème de l’énergie, la mobilité, le tri des déchets…', + points: 0.1, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.2.3', + nom: 'Participer et soutenir la visite d’une vélo-station, d’un centre de tri des déchets, d’un jardin partagé…', + points: 0.1, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.2.4', + nom: "Soutenir l'implication des élèves et des enseignants dans le diagnostic, le suivi et les mesures prises pour améliorer la qualité de l'air intérieur", + points: 0.1, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.2.5', + nom: "Soutenir l'implication des élèves dans les projets climat-air-énergie de la collectivité", + points: 0.1, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.2.6', + nom: 'Participer à la réalisation d’une vidéo participative, réalisation d’une exposition en lien avec l’énergie, l’air ou le climat', + points: 0.1, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.2.7', + nom: 'Soutenir les appels à projets en direction des établissements pour inciter à la mise en place d’actions pédagogiques climat-air-énergie', + points: 0.1, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.2.8', + nom: 'Soutenir la labellisation « éco-école »', + points: 0.1, + pourcentage: 12.5, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.5.3.3', + nom: 'Mettre en place des lignes de bus pédestre ou cycliste dans le cadre d’un Plan de déplacement établissement scolaire (PDES)', + points: 0.8, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.5.3.3.1', + nom: 'Identifier et localiser des parents et élèves volontaires', + points: 0.16, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.3.2', + nom: 'Organiser une journée test', + points: 0.16, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.3.3', + nom: 'Matérialiser des arrêts et itinéraires des pédibus/vélobus', + points: 0.16, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.3.4', + nom: 'Soutenir une offre d’équipements à toutes les écoles participantes', + points: 0.16, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.3.5', + nom: "Participer à l'analyse et à la valorisation des retours d’expériences", + points: 0.16, + pourcentage: 20, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.5.3.4', + nom: 'Pérenniser et massifier la sensibilisation', + points: 0.4, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'cae_6.5.3.5', + nom: 'Suivre les résultats et atteindre les objectifs fixés', + points: 0.8, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'cae_6.5.3.5.1', + nom: 'Avoir un % élevé (> 50%) d’élèves concernés par une démarche de sensibilisation/action', + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.5.2', + nom: 'Avoir une part d’établissements scolaires couverts par un PDES ou un pédibus/vélobus en augmentation', + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.5.3', + nom: 'Contrôler l’efficacité des actions mises en place', + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + { + action_id: 'cae_6.5.3.5.4', + nom: 'Avoir une reconnaissance via un dispositif de labellisation (éco-école, écolo crèche...) ou des retombées presse (article de presse…)', + points: 0.2, + pourcentage: 25, + actions_enfant: [], + level: 5, + action_type: ActionType.TACHE, + }, + ], + level: 4, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 3, + action_type: ActionType.ACTION, + }, + ], + level: 2, + action_type: ActionType.SOUS_AXE, + }, + ], + level: 1, + action_type: ActionType.AXE, + }, + ], +}; diff --git a/backend/src/referentiels/models/samples/deeper-referentiel.ts b/backend/src/referentiels/models/samples/deeper-referentiel.ts new file mode 100644 index 0000000000..0dbd34ac4e --- /dev/null +++ b/backend/src/referentiels/models/samples/deeper-referentiel.ts @@ -0,0 +1,106 @@ +import { ActionType } from '../action-type.enum'; +import { ReferentielActionType } from '../referentiel-action.dto'; + +export const deeperReferentiel: ReferentielActionType = { + action_id: 'eci', + points: 100, + level: 0, + action_type: ActionType.REFERENTIEL, + actions_enfant: [ + { + action_id: 'eci_1', + points: 30, + level: 1, + action_type: ActionType.ACTION, + actions_enfant: [ + { + action_id: 'eci_1.1', + points: 10, + level: 2, + action_type: ActionType.SOUS_ACTION, + actions_enfant: [], + }, + { + action_id: 'eci_1.2', + points: 20, + level: 2, + action_type: ActionType.SOUS_ACTION, + actions_enfant: [], + }, + ], + }, + { + action_id: 'eci_2', + points: 70, + level: 1, + action_type: ActionType.ACTION, + actions_enfant: [ + { + action_id: 'eci_2.0', + points: 0, + level: 2, + action_type: ActionType.SOUS_ACTION, + actions_enfant: [], + }, + { + action_id: 'eci_2.1', + points: 65, + level: 2, + action_type: ActionType.SOUS_ACTION, + actions_enfant: [ + { + action_id: 'eci_2.1.0', + points: 0, + level: 3, + action_type: ActionType.TACHE, + actions_enfant: [], + }, + { + action_id: 'eci_2.1.1', + points: 40, + level: 3, + action_type: ActionType.TACHE, + actions_enfant: [], + }, + { + action_id: 'eci_2.1.2', + points: 25, + level: 3, + action_type: ActionType.TACHE, + actions_enfant: [], + }, + ], + }, + { + action_id: 'eci_2.2', + points: 5, + level: 2, + action_type: ActionType.SOUS_ACTION, + actions_enfant: [ + { + action_id: 'eci_2.2.1', + points: 2, + level: 3, + action_type: ActionType.TACHE, + actions_enfant: [], + }, + { + action_id: 'eci_2.2.2', + points: 1.5, + level: 3, + action_type: ActionType.TACHE, + actions_enfant: [], + }, + { + action_id: 'eci_2.2.3', + points: 1.5, + level: 3, + action_type: ActionType.TACHE, + actions_enfant: [], + }, + ], + }, + ], + }, + ], +}; diff --git a/backend/src/referentiels/models/samples/eci-referentiel.ts b/backend/src/referentiels/models/samples/eci-referentiel.ts new file mode 100644 index 0000000000..c295ed8d89 --- /dev/null +++ b/backend/src/referentiels/models/samples/eci-referentiel.ts @@ -0,0 +1,3409 @@ +import { ActionType } from '../action-type.enum'; +import { ReferentielActionType } from '../referentiel-action.dto'; + +export const eciReferentiel: ReferentielActionType = { + action_id: 'eci', + nom: 'Économie Circulaire', + points: 500, + pourcentage: null, + level: 0, + action_type: ActionType.REFERENTIEL, + actions_enfant: [ + { + action_id: 'eci_1', + nom: "Définition d'une stratégie globale de la politique économie circulaire et inscription dans le territoire", + points: 90, + pourcentage: 18, + actions_enfant: [ + { + action_id: 'eci_1.1', + nom: 'Définir une stratégie globale de la politique Economie Circulaire et assurer un portage politique fort', + points: 30, + pourcentage: 33.33333333333333, + actions_enfant: [ + { + action_id: 'eci_1.1.1', + nom: "S'engager politiquement et mettre en place des moyens", + points: 6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_1.1.1.1', + nom: 'Identifier un élu référent en charge de la politique Economie Circulaire', + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.1.2', + nom: 'Engager la politique Economie Circulaire - Formaliser une vision et des engagements économie circulaire', + points: 1.8, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.1.3', + nom: 'Désigner un chef de projet économie circulaire', + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.1.4', + nom: "Identifier l'équipe technique", + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.1.5', + nom: 'Allouer un budget à la politique économie circulaire', + points: 0.6, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_1.1.2', + nom: "Réaliser le diagnostic de l'économie circulaire", + points: 6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_1.1.2.1', + nom: "Identifier les enjeux et objectifs en lien avec l'économie circulaire dans les documents de planification existants", + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.2.2', + nom: 'Intégrer dans le diagnostic une analyse des secteurs économiques', + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.2.3', + nom: 'Intégrer dans le diagnostic une analyse des enjeux environnementaux', + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.2.4', + nom: 'Intégrer dans le diagnostic une analyse des enjeux sociaux', + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.2.5', + nom: 'Réaliser un recensement des acteurs et des initiatives', + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_1.1.3', + nom: 'Élargir la gouvernance en interne et en externe', + points: 6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_1.1.3.1', + nom: 'Mettre en place un comité de pilotage interne élargi', + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.3.2', + nom: 'Mettre en place une gouvernance élargie avec les représentants des acteurs du territoire (société civile, acteurs publics, acteurs économiques)', + points: 1.8, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.3.3', + nom: 'Mettre en place des groupes de travail pour la construction des actions économie circulaire', + points: 3, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_1.1.4', + nom: "Adopter une stratégie et un programme d'actions Économie Circulaire", + points: 6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_1.1.4.1', + nom: 'Intégrer dans la stratégie les enjeux économiques, environnementaux et sociaux', + points: 0.9, + pourcentage: 15, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.4.10', + nom: "Intégrer dans le programme d'actions des actions sur le pilier écologie industrielle et territoriale de l'économie circulaire", + points: 0.24, + pourcentage: 4, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.4.11', + nom: "Intégrer dans le programme d'actions des actions sur le pilier économie de la fonctionnalité de l'économie circulaire", + points: 0.24, + pourcentage: 4, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.4.12', + nom: "Intégrer dans le programme d'actions des actions sur le pilier consommation responsable de l'économie circulaire", + points: 0.24, + pourcentage: 4, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.4.13', + nom: "Intégrer dans le programme d'actions des actions sur le pilier allongement de la durée d'usage de l'économie circulaire", + points: 0.24, + pourcentage: 4, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.4.14', + nom: "Intégrer dans le programme d'actions des actions sur le pilier recyclage de l'économie circulaire", + points: 0.24, + pourcentage: 4, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.4.2', + nom: 'Fixer dans la stratégie des caps à court, moyen et long terme', + points: 0.9, + pourcentage: 15, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.4.3', + nom: 'Cibler dans la stratégie la société civile, les acteurs publics et les acteurs économiques', + points: 0.9, + pourcentage: 15, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.4.4', + nom: "Couvrir dans la stratégie tous les axes de l'économie circulaire", + points: 0.9, + pourcentage: 15, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.4.5', + nom: "Intégrer dans le programme d'actions des actions vers la société civile", + points: 0.24, + pourcentage: 4, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.4.6', + nom: "Intégrer dans le programme d'actions des actions vers les acteurs publics", + points: 0.24, + pourcentage: 4, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.4.7', + nom: "Intégrer dans le programme d'actions des actions vers les acteurs économiques", + points: 0.24, + pourcentage: 4, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.4.8', + nom: "Intégrer dans le programme d'actions des actions sur le pilier approvisionnement durable de l'économie circulaire", + points: 0.24, + pourcentage: 4, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.4.9', + nom: "Intégrer dans le programme d'actions des actions sur le pilier éco-conception de l'économie circulaire", + points: 0.24, + pourcentage: 4, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_1.1.5', + nom: 'Mettre en œuvre et valoriser les actions', + points: 6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_1.1.5.1', + nom: 'Valoriser des actions antérieures à la stratégie', + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.5.2', + nom: "Valoriser plus de 20% des actions issues du programme d'actions", + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.5.3', + nom: "Valoriser plus de 50% des actions issues du programme d'actions", + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.1.5.4', + nom: "Couvrir les différents piliers de l'économie circulaire avec le programme d'actions réalisé", + points: 2.4, + pourcentage: 40, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + { + action_id: 'eci_1.2', + nom: "Développer une démarche transversale avec l'ensemble des politiques de la collectivité", + points: 30, + pourcentage: 33.33333333333333, + actions_enfant: [ + { + action_id: 'eci_1.2.1', + nom: 'Former en interne', + points: 6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_1.2.1.1', + nom: 'Définir un programme de formation économie circulaire', + points: 0.6, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.2.1.2', + nom: 'Inclure dans le programme de formation des formations économie circulaire pour les élus et les techniciens', + points: 1.8, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.2.1.3', + nom: "Disposer de plus de 20% des unités de gestion qui ont au moins 1 salarié formé à l'économie circulaire", + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.2.1.4', + nom: "Former le DGA/DGS à l'économie circulaire", + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.2.1.5', + nom: "Former plus de 20% des élus à l'économie circulaire", + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_1.2.2', + nom: 'Mettre en place une transversalité des actions et des projets', + points: 6, + pourcentage: 20, + actions_enfant: [], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_1.2.3', + nom: "Intégrer l'économie circulaire dans les politiques territoriales", + points: 6, + pourcentage: 20, + actions_enfant: [], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_1.2.4', + nom: 'Mettre en place une transversalité inter-collectivités', + points: 12, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'eci_1.2.4.1', + nom: 'Partager avec les EPCI les observations sur les gisements de déchets à optimiser', + points: 3, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.2.4.2', + nom: "Accompagner collectivement les EPCI adhérents vers la construction d'actions sur leurs autres compétences", + points: 3, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.2.4.3', + nom: "Réaliser des actions de prévention et de sobriété en amont de la production de déchets dans le cadre d'une compétence", + points: 3, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.2.4.4', + nom: 'Réaliser des actions de prévention et de sobriété en amont de la production de déchets dans le cadre de plusieurs compétences', + points: 3, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + { + action_id: 'eci_1.3', + nom: 'Suivre, évaluer et améliorer le déploiement de la politique Économie Circulaire', + points: 30, + pourcentage: 33.33333333333333, + actions_enfant: [ + { + action_id: 'eci_1.3.1', + nom: "Déterminer des indicateurs spécifiques dotés d'objectifs", + points: 15, + pourcentage: 50, + actions_enfant: [ + { + action_id: 'eci_1.3.1.1', + nom: 'Identifier les indicateurs de résultat', + points: 7.5, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.3.1.2', + nom: "Identifier les indicateurs d'impact", + points: 3.75, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.3.1.3', + nom: "Identifier les indicateurs spécifiques par secteur stratégique (en lien avec l'orientation 3.1)", + points: 3.75, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_1.3.2', + nom: 'Effectuer le bilan et ajuster les actions', + points: 15, + pourcentage: 50, + actions_enfant: [ + { + action_id: 'eci_1.3.2.1', + nom: 'Réaliser le bilan', + points: 6, + pourcentage: 40, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.3.2.2', + nom: 'Partager le bilan avec la gouvernance', + points: 1.5, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.3.2.3', + nom: "Communiquer sur le bilan à l'externe", + points: 3, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_1.3.2.4', + nom: "Mettre à jour régulièrement le programme d'actions au regard, notamment, de l'évaluation", + points: 4.5, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + ], + level: 1, + action_type: ActionType.AXE, + }, + { + action_id: 'eci_2', + nom: 'Développement des services de réduction, collecte et valorisation des déchets', + points: 80, + pourcentage: 16, + actions_enfant: [ + { + action_id: 'eci_2.1', + nom: "Disposer d'un programme de prévention des déchets", + points: 10, + pourcentage: 12.5, + actions_enfant: [ + { + action_id: 'eci_2.1.0', + nom: 'Respecter la réglementation en matière de prévention de déchets', + points: 0, + pourcentage: 0, + actions_enfant: [], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_2.1.1', + nom: 'Mettre en œuvre les actions du PLPDMA', + points: 4, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'eci_2.1.1.1', + nom: "Déployer 3 à 9 actions sur l'année", + points: 0.5714285714285715, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.1.1.2', + nom: "Déployer 10 à 14 actions sur l'année", + points: 0.5714285714285715, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.1.1.3', + nom: 'Déployer 15 actions ou plus', + points: 0.5714285714285715, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.1.1.4', + nom: "Exploiter 1 ou 2 axes du guide PLPDMA de l'ADEME", + points: 0.5714285714285715, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.1.1.5', + nom: "Exploiter 3 ou 4 axes du guide PLPDMA de l'ADEME", + points: 0.5714285714285715, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.1.1.6', + nom: "Exploiter 5 ou 6 axes du guide PLPDMA de l'ADEME", + points: 0.5714285714285715, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.1.1.7', + nom: "Exploiter au moins 7 axes du guide PLPDMA de l'ADEME", + points: 0.5714285714285715, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_2.1.2', + nom: "Disposer d'une commission consultative d'élaboration et de suivi (CCES) élargie", + points: 2, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_2.1.2.1', + nom: 'Organiser au moins 1 réunion de la CCES par an', + points: 1, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.1.2.2', + nom: 'Élargir la composition de la CCES au-delà des élus', + points: 1, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_2.1.3', + nom: 'Suivre le PLPDMA', + points: 4, + pourcentage: 40, + actions_enfant: [], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + { + action_id: 'eci_2.2', + nom: "Améliorer l'efficience du système de collecte", + points: 15, + pourcentage: 18.75, + actions_enfant: [ + { + action_id: 'eci_2.2.0', + nom: 'Respecter la réglementation en matière de collecte des déchets', + points: 0, + pourcentage: 0, + actions_enfant: [], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_2.2.1', + nom: "Connaitre l'état du service public de collecte des déchets", + points: 3, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_2.2.1.1', + nom: "Disposer d'une analyse actualisée par rapport à l'état du système de collecte sur le taux d'utilisation du service", + points: 1, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.2.1.2', + nom: "Disposer d'une analyse actualisée par rapport à l'état du système de collecte sur l'évaluation du parc de déchèteries", + points: 1, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.2.1.3', + nom: "Disposer d'une étude préalable à la mise en place de solutions alternatives pour diminuer les flux traités", + points: 1, + pourcentage: 33.33333333333333, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_2.2.2', + nom: "Définir un plan d'actions", + points: 4.5, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'eci_2.2.2.1', + nom: "Disposer d'un plan d'actions en cours d'élaboration", + points: 2.25, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.2.2.2', + nom: "Disposer d'un plan d'actions validé par les élus", + points: 2.25, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_2.2.3', + nom: "Mettre en œuvre le plan d'actions et communiquer", + points: 7.5, + pourcentage: 50, + actions_enfant: [ + { + action_id: 'eci_2.2.3.1', + nom: "Disposer de bac pucés et contrôler l'accès aux déchèteries", + points: 1.5, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.2.3.2', + nom: 'Optimiser le réseau de déchèteries', + points: 1.5, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.2.3.3', + nom: "Développer l'accueil de nouvelles filières en déchèteries (liées aux REP ou non)", + points: 1.5, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.2.3.4', + nom: "Généraliser l'accès de tous à un ou des dispositifs de tri à la source des biodéchets", + points: 1.5, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.2.3.5', + nom: 'Étendre les consignes de tri', + points: 1.5, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + { + action_id: 'eci_2.3', + nom: 'Améliorer la valorisation des déchets (dont organiques)', + points: 20, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'eci_2.3.0', + nom: 'Respecter la règlementation en matière de traitement pour la valorisation des déchets', + points: 5, + pourcentage: 25, + actions_enfant: [], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_2.3.1', + nom: 'Connaitre les flux', + points: 5, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'eci_2.3.1.1', + nom: 'Connaitre les flux de déchets', + points: 2, + pourcentage: 40, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.3.1.2', + nom: "Disposer d'un état des lieux de l'utilisation des filières de traitement existantes", + points: 1, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.3.1.3', + nom: "Etudier l'optimisation des filières de traitement envisageables", + points: 2, + pourcentage: 40, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_2.3.2', + nom: "Concrétiser les solutions issues des études d'optimisation", + points: 5, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'eci_2.3.2.1', + nom: "Concrétiser au moins une solution et avoir concrétisé moins d'un tiers des solutions retenues dans l’étude", + points: 1.25, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.3.2.2', + nom: 'Concrétiser entre un tiers et deux tiers des solutions', + points: 1.25, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.3.2.3', + nom: 'Concrétiser plus de deux tiers des solutions', + points: 1.25, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.3.2.4', + nom: 'Toutes les solutions ont été concrétisées', + points: 1.25, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_2.3.3', + nom: 'Suivre et accompagner les installations de traitement / Suivre les installations de traitement et leurs performances en termes de valorisation', + points: 5, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'eci_2.3.3.1', + nom: "Mesurer l'effet de l'accompagnement / Mettre en place le suivi de toutes les installations de traitement sous maîtrise d'ouvrage de la collectivité", + points: 1, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.3.3.2', + nom: 'Valoriser au moins 50% des déchets', + points: 1, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.3.3.3', + nom: 'Valoriser au moins 60% des déchets', + points: 0.5, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.3.3.4', + nom: 'Valoriser au moins 70% des déchets', + points: 1.25, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.3.3.5', + nom: 'Valoriser au moins 80% des déchets', + points: 0.75, + pourcentage: 15, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.3.3.6', + nom: 'Valoriser au moins 90% des déchets', + points: 0.5, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + { + action_id: 'eci_2.4', + nom: 'Réduire les impacts environnementaux et sociaux de la gestion des déchets', + points: 20, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'eci_2.4.0', + nom: 'Respecter la règlementation', + points: 0, + pourcentage: 0, + actions_enfant: [], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_2.4.1', + nom: 'Identifier les pistes de réduction des impacts', + points: 4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_2.4.1.1', + nom: 'Programmer une étude pour identifier les pistes de réduction des impacts', + points: 0.8, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.4.1.2', + nom: "Réaliser l'étude et identifier les pistes de réduction des impacts", + points: 1.2, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.4.1.3', + nom: "S'approprier et prioriser les actions d'optimisation", + points: 2, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_2.4.2', + nom: 'Gérer les impacts de la collecte des déchets', + points: 4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_2.4.2.1', + nom: "Mettre en place le plan d'actions", + points: 0.6, + pourcentage: 15, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.4.2.2', + nom: "Chiffer les objectifs du plan d'actions", + points: 0.6, + pourcentage: 15, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.4.2.3', + nom: 'Démarrer la mise en œuvre des actions', + points: 1.6, + pourcentage: 40, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.4.2.4', + nom: 'Mettre en place le pilotage de la progression des actions', + points: 1.2, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_2.4.3', + nom: 'Mettre en place le report modal de la collecte des déchets', + points: 2, + pourcentage: 10, + actions_enfant: [], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_2.4.4', + nom: 'Gérer les impacts du traitement des déchets', + points: 6, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'eci_2.4.4.1', + nom: "Mettre en place le plan d'actions", + points: 0.9, + pourcentage: 15, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.4.4.2', + nom: "Chiffrer les objectifs du plan d'actions", + points: 0.9, + pourcentage: 15, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.4.4.3', + nom: 'Démarrer la mise en œuvre des actions', + points: 2.4, + pourcentage: 40, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.4.4.4', + nom: 'Mettre en place le pilotage de la progression des actions', + points: 1.8, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_2.4.5', + nom: 'Communiquer sur les impacts', + points: 4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_2.4.5.1', + nom: 'Planifier les actions de communication', + points: 1, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.4.5.2', + nom: 'Réaliser une communication', + points: 1, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.4.5.3', + nom: "Réaliser une concertation (réunions d'information, échanges avec les parties prenantes, etc.)", + points: 1, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.4.5.4', + nom: 'Communiquer pour prévenir les comportements indésirables', + points: 1, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + { + action_id: 'eci_2.5', + nom: 'Créer du lien avec les acteurs économiques du territoire pour créer des dynamiques sur leurs déchets', + points: 15, + pourcentage: 18.75, + actions_enfant: [ + { + action_id: 'eci_2.5.1', + nom: 'Informer les acteurs économiques', + points: 3.75, + pourcentage: 25, + actions_enfant: [], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_2.5.2', + nom: 'Conseiller les acteurs économiques', + points: 7.5, + pourcentage: 50, + actions_enfant: [ + { + action_id: 'eci_2.5.2.1', + nom: 'Identifier les critères de priorisation des acteurs économiques à conseiller', + points: 1.875, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.5.2.2', + nom: 'Conseiller tous les acteurs économiques ciblés', + points: 3.75, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.5.2.3', + nom: "Disposer d'un taux de satisfaction élevé auprès d'au moins 59% des acteurs économiques conseillés", + points: 1.875, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_2.5.3', + nom: 'Structurer et mettre en réseau les acteurs', + points: 3.75, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'eci_2.5.3.1', + nom: "Mettre en place des moyens pour identifier ou fédérer des réseaux d'acteurs sur le territoire", + points: 1.2500000000000002, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.5.3.2', + nom: 'Mettre en place des moyens pour accompagner les projets dans leur définition', + points: 1.2500000000000002, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_2.5.3.3', + nom: 'Mettre en place des moyens pour soutenir le déploiement des projets', + points: 1.2500000000000002, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + ], + level: 1, + action_type: ActionType.AXE, + }, + { + action_id: 'eci_3', + nom: "Déploiement des autres piliers de l'économie circulaire dans les territoires", + points: 180, + pourcentage: 36, + actions_enfant: [ + { + action_id: 'eci_3.1', + nom: "Identifier et développer des filières/domaines à enjeux en lien avec l'économie circulaire sur le territoire", + points: 35, + pourcentage: 19.444444444444446, + actions_enfant: [ + { + action_id: 'eci_3.1.1', + nom: "Réaliser le diagnostic des filière(s) à enjeux d'économie circulaire", + points: 11.666666666666668, + pourcentage: 33.333333333333336, + actions_enfant: [ + { + action_id: 'eci_3.1.1.1', + nom: 'Prioriser la filière (les filières) à diagnostiquer', + points: 4.666666666666668, + pourcentage: 40.00000000000001, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.1.1.2', + nom: "Disposer d'un diagnostic de filière(s) à enjeux d'économie circulaire en cours de réalisation", + points: 2.333333333333334, + pourcentage: 20.000000000000004, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.1.1.3', + nom: "Disposer d'un diagnostic de filière(s) à enjeux d'économie circulaire finalisé", + points: 2.333333333333334, + pourcentage: 20.000000000000004, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.1.1.4', + nom: 'Partager le diagnostic avec les acteurs clés des filières étudiées', + points: 2.333333333333334, + pourcentage: 20.000000000000004, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.1.2', + nom: "Construire un plan d'actions spécifique", + points: 11.666666666666668, + pourcentage: 33.333333333333336, + actions_enfant: [ + { + action_id: 'eci_3.1.2.1', + nom: "Construire le plan d'actions", + points: 3.5000000000000004, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.1.2.2', + nom: "Co-construire le plan d'action avec les acteurs clés des filières", + points: 2.333333333333334, + pourcentage: 20.000000000000004, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.1.2.3', + nom: "Valider le plan d'actions", + points: 2.333333333333334, + pourcentage: 20.000000000000004, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.1.2.4', + nom: "Réaliser les actions du plan d'actions", + points: 3.5000000000000004, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.1.3', + nom: "Piloter et suivre les résultats du plan d'actions", + points: 11.666666666666668, + pourcentage: 33.333333333333336, + actions_enfant: [ + { + action_id: 'eci_3.1.3.1', + nom: 'Définir un protocole de suivi', + points: 3.8888888888888897, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.1.3.2', + nom: 'Recueillir les données', + points: 3.8888888888888897, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.1.3.3', + nom: "Analyser l'évolution des indicateurs et ajuster le plan d'actions", + points: 3.8888888888888897, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + { + action_id: 'eci_3.2', + nom: 'Réaliser des achats responsables', + points: 25, + pourcentage: 13.88888888888889, + actions_enfant: [ + { + action_id: 'eci_3.2.0', + nom: 'Mettre en place le Schéma de promotion des achats publics socialement et écologiquement responsables (SPASER)', + points: 0, + pourcentage: 0, + actions_enfant: [], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.2.1', + nom: "Définir la politique d'achats responsables et sensibiliser", + points: 6.25, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'eci_3.2.1.1', + nom: "Décider d'engager une structuration de sa politique d'achats responsables", + points: 0.625, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.2.1.2', + nom: "Disposer d'une politique d'achats responsable structurée", + points: 1.25, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.2.1.3', + nom: 'Réaliser une cartographie des achats', + points: 1.25, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.2.1.4', + nom: 'Sensibiliser et former à la pratique des achats responsables au sein de la collectivité', + points: 3.125, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.2.2', + nom: "Intégrer des dispositions relevant de l'économie circulaire", + points: 12.5, + pourcentage: 50, + actions_enfant: [ + { + action_id: 'eci_3.2.2.1', + nom: "Disposer d'au moins 30% des marchés publics incluant des dispositions environnementales", + points: 3.125, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.2.2.2', + nom: "Disposer d'au moins 60% des marchés publics incluant des dispositions environnementales", + points: 3.125, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.2.2.3', + nom: "Disposer d'au moins 30% des marchés publics incluant des dispositions sociales", + points: 6.25, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.2.3', + nom: 'Pérenniser la démarche', + points: 6.25, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'eci_3.2.3.1', + nom: 'Mettre en place un tableau de bord', + points: 2.5, + pourcentage: 40, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.2.3.2', + nom: "Participer au réseau d'acheteurs", + points: 1.875, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.2.3.3', + nom: "Promouvoir les achats responsables auprès des élus et des acheteurs du territoire qui n'ont pas encore adopté des pratiques d'achats responsables", + points: 1.875, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + { + action_id: 'eci_3.3', + nom: 'Soutenir et accompagner la consommation responsable et la sobriété des acteurs du territoire', + points: 25, + pourcentage: 13.88888888888889, + actions_enfant: [ + { + action_id: 'eci_3.3.1', + nom: 'Communiquer et sensibiliser à la consommation responsable et à la sobriété', + points: 6.25, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'eci_3.3.1.1', + nom: 'Disposer de support(s) de communication recensant les solutions de consommation sobre et responsable sur la territoire', + points: 1.25, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.3.1.2', + nom: 'Organiser des ateliers de sensibilisation à la consommation sobre et responsable', + points: 1.875, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.3.1.3', + nom: 'Soutenir financièrement ou organiser des évènements mettant en avant la consommation responsable et la sobriété', + points: 3.125, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.3.2', + nom: 'Promouvoir et lancer au sein de la collectivité une dynamique relative à la consommation responsable et à la sobriété', + points: 6.25, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'eci_3.3.2.1', + nom: 'Sensibiliser les élus et les techniciens', + points: 1.5625, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.3.2.2', + nom: 'Former les élus et les techniciens', + points: 1.5625, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.3.2.3', + nom: "Disposer d'une liste d’actions à décliner dans chaque service formé", + points: 1.5625, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.3.2.4', + nom: "Formaliser dans un document une vision et un plan d'actions de la collectivité sur la consommation responsable et la sobriété", + points: 1.5625, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.3.3', + nom: 'Agir pour la consommation responsable et la sobriété dans le cadre de ses compétences', + points: 6.25, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'eci_3.3.3.1', + nom: "Réaliser des actions à destination d'établissements scolaires", + points: 1.25, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.3.3.2', + nom: 'Réaliser des actions sur au moins 1 autre compétence de la collectivité', + points: 1.25, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.3.3.3', + nom: 'Réaliser des actions sur au moins 3 compétences de la collectivité', + points: 1.875, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.3.3.4', + nom: 'Réaliser des actions de façon transversale qui concernent toutes les compétences de la collectivité', + points: 1.875, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.3.4', + nom: 'Accompagner les acteurs externes sur des actions de consommation responsable et de sobriété', + points: 6.25, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'eci_3.3.4.1', + nom: 'Mettre en place au moins une action', + points: 1.25, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.3.4.2', + nom: 'Mettre en place un ensemble d’actions vers une cible', + points: 2.5, + pourcentage: 40, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.3.4.3', + nom: "Mettre en place un ensemble d’actions vers l'ensemble des cibles clés du territoire", + points: 2.5, + pourcentage: 40, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + { + action_id: 'eci_3.4', + nom: "Soutenir et accompagner l'écoconception des produits et des services du territoire", + points: 25, + pourcentage: 13.88888888888889, + actions_enfant: [ + { + action_id: 'eci_3.4.1', + nom: 'Animer le réseau', + points: 7.5, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'eci_3.4.1.1', + nom: 'Organiser au moins un évènement par an avec les entreprises du territoire', + points: 0.375, + pourcentage: 5, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.4.1.2', + nom: 'Organiser au moins 2 évènements par an avec les entreprises du territoire', + points: 1.125, + pourcentage: 15, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.4.1.3', + nom: 'Organiser au moins 3 évènements par an avec les entreprises du territoire', + points: 2.25, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.4.1.4', + nom: 'Organiser au moins 4 évènements par an avec les entreprises du territoire', + points: 3.75, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.4.2', + nom: 'Encourager la collaboration entreprises-établissements de formation', + points: 6.25, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'eci_3.4.2.1', + nom: 'Etablir la liste des établissements du territoire qui dispensent une formation en écoconception', + points: 1.25, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.4.2.2', + nom: "Disposer au moins d'un partenariat avec un organisme/entreprise conclu sous l’égide de la collectivité abordant le développement de l'écoconception", + points: 5, + pourcentage: 80, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.4.3', + nom: 'Accompagner les entreprises', + points: 7.5, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'eci_3.4.3.1', + nom: "Accompagner les entreprises au travers d'opérations collectives", + points: 3.75, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.4.3.2', + nom: "Accompagner les entreprises au travers d'un accompagnement individuel", + points: 3.75, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.4.4', + nom: 'Ecoconcevoir les projets à impacts', + points: 3.75, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'eci_3.4.4.1', + nom: "Disposer d'une méthodologie d'écoconception des projets à impact", + points: 1.875, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.4.4.2', + nom: 'Mettre en œuvre la pensée cycle de vie sur les projets structurants', + points: 1.875, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + { + action_id: 'eci_3.5', + nom: "Soutenir et accompagner les projets d'Ecologie Industrielle et Territoriale (EIT)", + points: 25, + pourcentage: 13.88888888888889, + actions_enfant: [ + { + action_id: 'eci_3.5.1', + nom: 'Elaborer la stratégie et structurer en interne', + points: 5, + pourcentage: 20, + actions_enfant: [], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.5.2', + nom: 'Mettre en réseau les acteurs et mettre en place une gouvernance', + points: 5, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_3.5.2.1', + nom: 'Réaliser au moins une action', + points: 1.25, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.5.2.2', + nom: 'Réaliser au moins 2 actions', + points: 1.25, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.5.2.3', + nom: 'Réaliser au moins 3 actions', + points: 1.25, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.5.2.4', + nom: 'Réaliser au moins 4 actions', + points: 1.25, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.5.3', + nom: 'Accompagner opérationnellement les projets', + points: 7.5, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'eci_3.5.3.1', + nom: 'Financer ou internaliser un animateur EIT', + points: 0.75, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.5.3.2', + nom: "Contribuer à l'identification de nouvelles synergies", + points: 1.5, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.5.3.3', + nom: 'Mettre en œuvre au moins une synergie par an', + points: 0.75, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.5.3.4', + nom: 'Mettre en œuvre au moins 2 synergies par an', + points: 1.5, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.5.3.5', + nom: 'Mettre en œuvre 3 synergies ou plus par an', + points: 1.5, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.5.3.6', + nom: "Intégrer l'EIT dans les projets d'aménagement du territoire (zones d'activités)", + points: 0.75, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.5.3.7', + nom: 'Au moins une synergie mise en œuvre sur les activités de la collectivité', + points: 0.75, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.5.4', + nom: 'Pérenniser et partager les expériences', + points: 7.5, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'eci_3.5.4.1', + nom: 'Transférer le pilotage de la démarche', + points: 3, + pourcentage: 40, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.5.4.2', + nom: "Disposer d'un poste salarié dédié", + points: 3, + pourcentage: 40, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.5.4.3', + nom: 'Renseigner les projets EIT sur la plateforme ELIPSE et SYNAPSE et communiquer', + points: 1.5, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + { + action_id: 'eci_3.6', + nom: "Soutenir et accompagner l'économie de la fonctionnalité et de la coopération", + points: 25, + pourcentage: 13.88888888888889, + actions_enfant: [ + { + action_id: 'eci_3.6.1', + nom: 'Sensibiliser et former', + points: 3.75, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'eci_3.6.1.1', + nom: 'Engager une formation du personnel de la collectivité', + points: 0.9375, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.6.1.2', + nom: 'Avoir formé des personnes de la collectivité', + points: 0.9375, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.6.1.3', + nom: 'Engager une sensibilisation des acteurs du territoire', + points: 0.9375, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.6.1.4', + nom: 'Sensibiliser les acteurs du territoire', + points: 0.9375, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.6.2', + nom: 'Soutenir les entreprises du territoire et construire des réponses aux enjeux de politique publique adaptées aux différents usages', + points: 8.75, + pourcentage: 35, + actions_enfant: [ + { + action_id: 'eci_3.6.2.1', + nom: "Participer à des actions d'animation des entreprises", + points: 1.75, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.6.2.2', + nom: "Adhérer à une structure d'animation des acteurs du territoire (Clubs EFC, groupes d'acteurs...)", + points: 0.875, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.6.2.3', + nom: 'En plus d’une éventuelle cotisation, s’impliquer financièrement dans le fonctionnement et le développement de la structure d’animation', + points: 1.75, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.6.2.4', + nom: "Intégrer des critères d'économie de la fonctionnalité et de la coopération dans la commande publique", + points: 4.375, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.6.3', + nom: 'Coopérer dans une dynamique d’écosystèmes entre acteurs publics et privés dans le cadre des projets coopératifs territoriaux', + points: 7.5, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'eci_3.6.3.1', + nom: "Faire émerger un projet coopératif territorial d'économie de la fonctionnalité et de la coopération ou participer à un projet", + points: 3.75, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.6.3.2', + nom: "Piloter et stabiliser un écosystème coopératif territorial d'économie de la fonctionnalité et de la coopération", + points: 3.75, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.6.4', + nom: 'Evaluer les effets', + points: 5, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_3.6.4.1', + nom: 'Identifier les effets à évaluer', + points: 1.25, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.6.4.2', + nom: "Identifier les modalités d'évaluation", + points: 1.25, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.6.4.3', + nom: 'Mettre en place une évaluation', + points: 2.5, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + { + action_id: 'eci_3.7', + nom: "Soutenir et accompagner la recherche, l'innovation et l'expérimentation", + points: 20, + pourcentage: 11.11111111111111, + actions_enfant: [ + { + action_id: 'eci_3.7.1', + nom: 'Accompagner non financièrement des programmes', + points: 5, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'eci_3.7.1.1', + nom: "Accepter des sollicitations pour des programmes d'études ou de R&I", + points: 2, + pourcentage: 40, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.7.1.2', + nom: "S'impliquer dans le suivi des travaux", + points: 1, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.7.1.3', + nom: "S'approprier les résultats afin d'améliorer ses pratiques", + points: 2, + pourcentage: 40, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_3.7.2', + nom: 'Financer des projets de R&I', + points: 15, + pourcentage: 75, + actions_enfant: [ + { + action_id: 'eci_3.7.2.1', + nom: "Disposer d'au moins 1 projet en tant que collectivité < 100 000 habitants ou entre 2 à 9 projets en tant que collectivité > 100 000 habitants", + points: 7.5, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_3.7.2.2', + nom: "Disposer d'au moins 2 projets en tant que collectivité < 100 000 habitants ou au moins 10 projets en tant que collectivité > 100 000 habitants", + points: 7.5, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + ], + level: 1, + action_type: ActionType.AXE, + }, + { + action_id: 'eci_4', + nom: 'Outils financiers du changement de comportement', + points: 60, + pourcentage: 12, + actions_enfant: [ + { + action_id: 'eci_4.1', + nom: 'Connaître les coûts de la gestion des déchets pour maîtriser les dépenses publiques', + points: 20, + pourcentage: 33.33333333333333, + actions_enfant: [ + { + action_id: 'eci_4.1.0', + nom: 'Rédiger le rapport annuel SPPGD', + points: 0, + pourcentage: 0, + actions_enfant: [ + { + action_id: 'eci_4.1.0.1', + nom: 'Rédiger le rapport annuel', + points: 0, + pourcentage: 60, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_4.1.0.2', + nom: 'Rédiger le rapport annuel avec tous les éléments du décret et le publier en ligne', + points: 0, + pourcentage: 40, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_4.1.1', + nom: 'Connaître la structure des coûts de la gestion des déchets', + points: 4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_4.1.1.1', + nom: 'Réaliser la matrice des coûts', + points: 2.4, + pourcentage: 60, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_4.1.1.2', + nom: "Positionner les résultats de la matrice des coûts par rapport à d'autres collectivités", + points: 1.6, + pourcentage: 40, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_4.1.2', + nom: "Etudier les pistes d'optimisation", + points: 6, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'eci_4.1.2.1', + nom: 'Analyser la matrice des coûts', + points: 4.8, + pourcentage: 80, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_4.1.2.2', + nom: 'Réaliser une étude au cours des deux dernières années écoulées', + points: 1.2, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_4.1.3', + nom: 'Agir pour optimiser les dépenses publiques de gestion de déchets', + points: 6, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'eci_4.1.3.1', + nom: "Mettre en œuvre jusqu'à 50% des actions suite à l'étude", + points: 1.5, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_4.1.3.2', + nom: "Mettre en œuvre plus de 50% des actions suite à l'étude", + points: 3, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_4.1.3.3', + nom: "Mettre en œuvre toutes les actions suite à l'étude", + points: 1.5, + pourcentage: 25, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_4.1.4', + nom: "Communiquer sur la démarche d'optimisation", + points: 4, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_4.1.4.1', + nom: 'Communiquer sur le positionnement et les résultats', + points: 2, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_4.1.4.2', + nom: "Communiquer sur les objectifs et la démarche d'amélioration", + points: 2, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + { + action_id: 'eci_4.2', + nom: "Mettre en place un système de financement qui encourage l'adhésion aux pratiques de l'économie circulaire", + points: 20, + pourcentage: 33.33333333333333, + actions_enfant: [ + { + action_id: 'eci_4.2.1', + nom: 'Facturer des usagers non ménagers', + points: 2.5, + pourcentage: 12.5, + actions_enfant: [ + { + action_id: 'eci_4.2.1.1', + nom: 'Engager la mise en place de la redevance spéciale', + points: 1.25, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_4.2.1.2', + nom: 'Couvrir toutes les communes du territoire avec la redevance spéciale', + points: 1.25, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_4.2.2', + nom: 'Etudier le potentiel de mise en place de la Tarification incitative (Ti)', + points: 2, + pourcentage: 10, + actions_enfant: [ + { + action_id: 'eci_4.2.2.1', + nom: "Engager l'étude de la mise en place de la tarification incitative (phase de lancement)", + points: 0.6666666666666667, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_4.2.2.2', + nom: "Disposer d'une étude de mise en place de la tarification incitative en cours de réalisation (phase de réalisation)", + points: 0.6666666666666667, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_4.2.2.3', + nom: "Disposer d'une étude de mise en place de la tarification incitative réalisée (étude terminée)", + points: 0.6666666666666667, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_4.2.3', + nom: 'Mettre en œuvre la Redevance Spéciale incitative pour les usagers non ménagers', + points: 3, + pourcentage: 15, + actions_enfant: [ + { + action_id: 'eci_4.2.3.1', + nom: 'Inclure une part variable dans la redevance spéciale en fonction des levées et/ou pesées', + points: 1.5, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_4.2.3.2', + nom: 'Différencier la redevance spéciale en fonction des flux', + points: 1.5, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_4.2.4', + nom: 'Mettre en œuvre la Tarification incitative (TI) pour tous les usagers', + points: 2.5, + pourcentage: 12.5, + actions_enfant: [ + { + action_id: 'eci_4.2.4.1', + nom: 'Lancer la mise en place de la tarification incitative', + points: 0.75, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_4.2.4.2', + nom: 'Couvrir toute la population de la collectivité avec la tarification incitative', + points: 1.75, + pourcentage: 70, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_4.2.5', + nom: 'Mettre en place la Tarification incitative (TI) du second niveau', + points: 10, + pourcentage: 50, + actions_enfant: [ + { + action_id: 'eci_4.2.5.1', + nom: 'Inclure une part variable en fonction de sa production de déchets dans la facturation des adhérents', + points: 5, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_4.2.5.2', + nom: 'Différencier la facturation des adhérents en fonction des flux', + points: 5, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + { + action_id: 'eci_4.3', + nom: "Promouvoir et mettre en place des outils financiers en faveur de l'économie circulaire à destination des autres acteurs du territoire notamment pour promouvoir la sobriété", + points: 20, + pourcentage: 33.33333333333333, + actions_enfant: [ + { + action_id: 'eci_4.3.1', + nom: 'Réaliser une veille', + points: 4, + pourcentage: 20, + actions_enfant: [], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_4.3.2', + nom: 'Communiquer sur les moyens de financement', + points: 4, + pourcentage: 20, + actions_enfant: [], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_4.3.3', + nom: 'Accompagner les acteurs du territoire', + points: 7, + pourcentage: 35, + actions_enfant: [ + { + action_id: 'eci_4.3.3.1', + nom: 'Mettre en place des moyens pour identifier les acteurs en recherche de financements', + points: 2.3333333333333335, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_4.3.3.2', + nom: 'Mettre en place des moyens pour accompagner les acteurs sur la recherche de financements', + points: 2.3333333333333335, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_4.3.3.3', + nom: 'Accompagner des projets visant à développer de nouveaux modèles économiques', + points: 2.3333333333333335, + pourcentage: 33.333333333333336, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_4.3.4', + nom: "Financer des projets sur le sujet de l'économie circulaire", + points: 5, + pourcentage: 25, + actions_enfant: [ + { + action_id: 'eci_4.3.4.1', + nom: 'Disposer de document de référence présentant les modalités de financement', + points: 1, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_4.3.4.2', + nom: 'Lister les projets', + points: 1.5, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_4.3.4.3', + nom: 'Mettre en cohérence les subventions allouées aux acteurs du territoire au regard de la sobriété', + points: 2.5, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + ], + level: 1, + action_type: ActionType.AXE, + }, + { + action_id: 'eci_5', + nom: 'Coopération et engagement', + points: 90, + pourcentage: 18, + actions_enfant: [ + { + action_id: 'eci_5.1', + nom: 'Actions dirigées vers le Grand Public et les associations', + points: 30, + pourcentage: 33.33333333333333, + actions_enfant: [ + { + action_id: 'eci_5.1.1', + nom: 'La collectivité informe et sensibilise le grand public', + points: 6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_5.1.1.1', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier approvisionnement durable', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.1.1.2', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier éco-conception', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.1.1.3', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier écologie industrielle et territoriale (EIT)', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.1.1.4', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier économie de la fonctionnalité', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.1.1.5', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier consommation responsable', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.1.1.6', + nom: "Réaliser au moins 1 ou 2 actions sur le pilier allongement de la durée d'usage", + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.1.1.7', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier recyclage', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_5.1.2', + nom: "Aider à l'action en direction du grand public", + points: 12, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'eci_5.1.2.1', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier approvisionnement durable', + points: 1.7142857142857144, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.1.2.2', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier éco-conception', + points: 1.7142857142857144, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.1.2.3', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier écologie industrielle et territoriale (EIT)', + points: 1.7142857142857144, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.1.2.4', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier économie de la fonctionnalité', + points: 1.7142857142857144, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.1.2.5', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier consommation responsable', + points: 1.7142857142857144, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.1.2.6', + nom: "Réaliser au moins 1 ou 2 actions sur le pilier allongement de la durée d'usage", + points: 1.7142857142857144, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.1.2.7', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier recyclage', + points: 1.7142857142857144, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_5.1.3', + nom: "Fédérer les acteurs du territoire dont l'action vise le Grand Public", + points: 12, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'eci_5.1.3.1', + nom: 'Réaliser une enquête sur les besoins des acteurs', + points: 2.4, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.1.3.2', + nom: 'Analyser les besoins', + points: 2.4, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.1.3.3', + nom: 'Créer un ou des espaces communs de dialogue pour les acteurs du territoire', + points: 2.4, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.1.3.4', + nom: "Disposer d'accord(s) avec un ou plusieurs acteurs grand public du territoire", + points: 2.4, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.1.3.5', + nom: 'Publier les indicateurs de réussite des partenariats', + points: 2.4, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + { + action_id: 'eci_5.2', + nom: 'Actions dirigées vers les autres collectivités du territoire', + points: 30, + pourcentage: 33.33333333333333, + actions_enfant: [ + { + action_id: 'eci_5.2.1', + nom: 'Informer, sensibiliser et former les autres collectivités de son territoire', + points: 6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_5.2.1.1', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier approvisionnement durable', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.2.1.2', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier éco-conception', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.2.1.3', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier écologie industrielle et territoriale (EIT)', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.2.1.4', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier économie de la fonctionnalité', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.2.1.5', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier consommation responsable', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.2.1.6', + nom: "Réaliser au moins 1 ou 2 actions sur le pilier allongement de la durée d'usage", + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.2.1.7', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier recyclage', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_5.2.2', + nom: "Aider à l'action des autres collectivités de son territoire", + points: 12, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'eci_5.2.2.1', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier approvisionnement durable', + points: 1.7142857142857144, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.2.2.2', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier éco-conception', + points: 1.7142857142857144, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.2.2.3', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier écologie industrielle et territoriale (EIT)', + points: 1.7142857142857144, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.2.2.4', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier économie de la fonctionnalité', + points: 1.7142857142857144, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.2.2.5', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier consommation responsable', + points: 1.7142857142857144, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.2.2.6', + nom: "Réaliser au moins 1 ou 2 actions sur le pilier allongement de la durée d'usage", + points: 1.7142857142857144, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.2.2.7', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier recyclage', + points: 1.7142857142857144, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_5.2.3', + nom: 'Structurer des partenariats avec les EPCI supras et infras présents sur le territoire', + points: 12, + pourcentage: 40, + actions_enfant: [ + { + action_id: 'eci_5.2.3.1', + nom: 'Identifier les collectivités à potentiel de collaboration', + points: 2.4, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.2.3.2', + nom: 'Identifier les enjeux', + points: 3.6, + pourcentage: 30, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.2.3.3', + nom: 'Conclure un/des accord(s) avec une ou plusieurs collectivités du territoire', + points: 6, + pourcentage: 50, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + { + action_id: 'eci_5.3', + nom: 'Actions dirigées vers les acteurs économiques (TPE/PME, grandes entreprises, commerçants, artisans, … y compris associations à activité économique et acteurs économiques publics : type CHU, EHPAD, SEM, ...)', + points: 30, + pourcentage: 33.33333333333333, + actions_enfant: [ + { + action_id: 'eci_5.3.1', + nom: 'Informer et former les acteurs économiques', + points: 6, + pourcentage: 20, + actions_enfant: [ + { + action_id: 'eci_5.3.1.1', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier approvisionnement durable', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.1.2', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier éco-conception', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.1.3', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier écologie industrielle et territoriale (EIT)', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.1.4', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier économie de la fonctionnalité', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.1.5', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier consommation responsable', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.1.6', + nom: "Réaliser au moins 1 ou 2 actions sur le pilier allongement de la durée d'usage", + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.1.7', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier recyclage', + points: 0.8571428571428572, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_5.3.2', + nom: "Aider à l'action à destination des acteurs économiques", + points: 15, + pourcentage: 50, + actions_enfant: [ + { + action_id: 'eci_5.3.2.1', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier approvisionnement durable', + points: 2.1428571428571432, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.2.2', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier éco-conception', + points: 2.1428571428571432, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.2.3', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier écologie industrielle et territoriale (EIT)', + points: 2.1428571428571432, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.2.4', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier économie de la fonctionnalité', + points: 2.1428571428571432, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.2.5', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier consommation responsable', + points: 2.1428571428571432, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.2.6', + nom: "Réaliser au moins 1 ou 2 actions sur le pilier allongement de la durée d'usage", + points: 2.1428571428571432, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.2.7', + nom: 'Réaliser au moins 1 ou 2 actions sur le pilier recyclage', + points: 2.1428571428571432, + pourcentage: 14.285714285714288, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + { + action_id: 'eci_5.3.3', + nom: 'Fédérer les acteurs économiques', + points: 9, + pourcentage: 30, + actions_enfant: [ + { + action_id: 'eci_5.3.3.1', + nom: 'Établir une cartographie de représentants locaux à potentiel de partenariat', + points: 0.9, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.3.2', + nom: "Construire des accords avec les représentants d'acteurs économiques sur 1 à 2 piliers", + points: 1.35, + pourcentage: 15.000000000000002, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.3.3', + nom: "Construire des accords avec les représentants d'acteurs économiques sur 3 à 4 piliers", + points: 1.35, + pourcentage: 15.000000000000002, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.3.4', + nom: "Construire des accords avec les représentants d'acteurs économiques sur 5 à 7 piliers", + points: 1.8, + pourcentage: 20, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.3.5', + nom: 'Suivre les indicateurs des partenariats', + points: 2.7, + pourcentage: 30.000000000000004, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + { + action_id: 'eci_5.3.3.6', + nom: 'Communiquer les résultats', + points: 0.9, + pourcentage: 10, + actions_enfant: [], + level: 4, + action_type: ActionType.TACHE, + }, + ], + level: 3, + action_type: ActionType.SOUS_ACTION, + }, + ], + level: 2, + action_type: ActionType.ACTION, + }, + ], + level: 1, + action_type: ActionType.AXE, + }, + ], +}; diff --git a/backend/src/referentiels/models/samples/simple-referentiel.ts b/backend/src/referentiels/models/samples/simple-referentiel.ts new file mode 100644 index 0000000000..76aac8efe0 --- /dev/null +++ b/backend/src/referentiels/models/samples/simple-referentiel.ts @@ -0,0 +1,62 @@ +import { ActionType } from '../action-type.enum'; +import { ReferentielActionType } from '../referentiel-action.dto'; + +export const simpleReferentiel: ReferentielActionType = { + action_id: 'eci', + points: 100, + level: 0, + action_type: ActionType.REFERENTIEL, + actions_enfant: [ + { + action_id: 'eci_1', + points: 30, + level: 1, + action_type: ActionType.ACTION, + actions_enfant: [ + { + action_id: 'eci_1.1', + points: 10, + level: 2, + action_type: ActionType.SOUS_ACTION, + actions_enfant: [], + }, + { + action_id: 'eci_1.2', + points: 20, + level: 2, + action_type: ActionType.SOUS_ACTION, + actions_enfant: [], + }, + ], + }, + { + action_id: 'eci_2', + points: 70, + level: 1, + action_type: ActionType.ACTION, + actions_enfant: [ + { + action_id: 'eci_2.0', + points: 0, + level: 2, + action_type: ActionType.SOUS_ACTION, + actions_enfant: [], + }, + { + action_id: 'eci_2.1', + points: 65, + level: 2, + action_type: ActionType.SOUS_ACTION, + actions_enfant: [], + }, + { + action_id: 'eci_2.2', + points: 5, + level: 2, + action_type: ActionType.SOUS_ACTION, + actions_enfant: [], + }, + ], + }, + ], +}; diff --git a/backend/src/referentiels/referentiels.module.ts b/backend/src/referentiels/referentiels.module.ts new file mode 100644 index 0000000000..a672a8dbb9 --- /dev/null +++ b/backend/src/referentiels/referentiels.module.ts @@ -0,0 +1,22 @@ +import { Module } from '@nestjs/common'; +import { AuthModule } from '../auth/auth.module'; +import { CollectivitesModule } from '../collectivites/collectivites.module'; +import { CommonModule } from '../common/common.module'; +import { PersonnalisationsModule } from '../personnalisations/personnalisations.module'; +import { ReferentielsScoringController } from './controllers/referentiels-scoring.controller'; +import { ReferentielsController } from './controllers/referentiels.controller'; +import ReferentielsScoringService from './services/referentiels-scoring.service'; +import ReferentielsService from './services/referentiels.service'; + +@Module({ + imports: [ + AuthModule, + CollectivitesModule, + CommonModule, + PersonnalisationsModule, + ], + providers: [ReferentielsService, ReferentielsScoringService], + exports: [ReferentielsService, ReferentielsScoringService], + controllers: [ReferentielsController, ReferentielsScoringController], +}) +export class ReferentielsModule {} diff --git a/backend/src/referentiels/services/referentiels-scoring.service.spec.ts b/backend/src/referentiels/services/referentiels-scoring.service.spec.ts new file mode 100644 index 0000000000..3c476cbee1 --- /dev/null +++ b/backend/src/referentiels/services/referentiels-scoring.service.spec.ts @@ -0,0 +1,2078 @@ +import { Test } from '@nestjs/testing'; +import { AuthService } from '../../auth/services/auth.service'; +import { + CollectiviteTypeEnum, + IdentiteCollectivite, +} from '../../collectivites/models/collectivite.models'; +import CollectivitesService from '../../collectivites/services/collectivites.service'; +import DatabaseService from '../../common/services/database.service'; +import { roundTo } from '../../common/services/number.helper'; +import { GetPersonnalitionConsequencesResponseType } from '../../personnalisations/models/get-personnalisation-consequences.response'; +import { GetPersonnalisationReponsesResponseType } from '../../personnalisations/models/get-personnalisation-reponses.response'; +import { caePersonnalisationRegles } from '../../personnalisations/models/samples/cae-personnalisation-regles.sample'; +import ExpressionParserService from '../../personnalisations/services/expression-parser.service'; +import PersonnalisationsService from '../../personnalisations/services/personnalisations-service'; +import { GetActionStatutsResponseType } from '../models/get-action-statuts.response'; +import { caeReferentiel } from '../models/samples/cae-referentiel'; +import { deeperReferentiel } from '../models/samples/deeper-referentiel'; +import { eciReferentiel } from '../models/samples/eci-referentiel'; +import { simpleReferentiel } from '../models/samples/simple-referentiel'; +import ReferentielsScoringService from './referentiels-scoring.service'; +import ReferentielsService from './referentiels.service'; + +describe('ReferentielsScoringService', () => { + let referentielsScoringService: ReferentielsScoringService; + let personnalisationService: PersonnalisationsService; + + beforeEach(async () => { + const moduleRef = await Test.createTestingModule({ + providers: [ + ReferentielsScoringService, + PersonnalisationsService, + ExpressionParserService, + ], + }) + .useMocker((token) => { + if ( + token === DatabaseService || + token === AuthService || + token === ReferentielsService || + token === CollectivitesService + ) { + return {}; + } + }) + .compile(); + + referentielsScoringService = moduleRef.get(ReferentielsScoringService); + personnalisationService = moduleRef.get(PersonnalisationsService); + }); + + describe('computeScoreMap', () => { + it('notation_when_one_tache_is_fait', async () => { + const personnalisationConsequences: GetPersonnalitionConsequencesResponseType = + {}; + const actionStatuts: GetActionStatutsResponseType = { + 'eci_1.1': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + }; + + const scoresMap = referentielsScoringService.computeScoreMap( + simpleReferentiel, + personnalisationConsequences, + actionStatuts, + 1, + ); + + const scoreLength = Object.keys(scoresMap).length; + expect(scoreLength).toEqual(8); + + expect(scoresMap['eci_1.1']).toEqual({ + action_id: 'eci_1.1', + point_fait: 10, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 0.0, + point_potentiel: 10, + point_referentiel: 10, + concerne: true, + total_taches_count: 1, + completed_taches_count: 1, + fait_taches_avancement: 1, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: true, + }); + + expect(scoresMap['eci_1']).toEqual({ + action_id: 'eci_1', + point_fait: 10, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 20, + point_potentiel: 30, + point_referentiel: 30, + concerne: true, + total_taches_count: 2, + completed_taches_count: 1, + fait_taches_avancement: 1, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect(scoresMap['eci_2']).toEqual({ + action_id: 'eci_2', + point_fait: 0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 70, + point_potentiel: 70, + point_referentiel: 70, + concerne: true, + total_taches_count: 3, + completed_taches_count: 0, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect(scoresMap['eci']).toEqual({ + action_id: 'eci', + point_fait: 10, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 90, + point_potentiel: 100, + point_referentiel: 100, + concerne: true, + total_taches_count: 5, + completed_taches_count: 1, + fait_taches_avancement: 1, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + }); + + it('notation_when_one_tache_is_fait_avancement_detaille_non_renseigne', async () => { + const personnalisationConsequences: GetPersonnalitionConsequencesResponseType = + {}; + const actionStatuts: GetActionStatutsResponseType = { + 'eci_1.1': { + concerne: true, + avancement: 'fait', + avancement_detaille: null, + }, + }; + + const scoresMap = referentielsScoringService.computeScoreMap( + simpleReferentiel, + personnalisationConsequences, + actionStatuts, + 1, + ); + + const scoreLength = Object.keys(scoresMap).length; + expect(scoreLength).toEqual(8); + + expect(scoresMap['eci_1.1']).toEqual({ + action_id: 'eci_1.1', + point_fait: 10, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 0.0, + point_potentiel: 10, + point_referentiel: 10, + concerne: true, + total_taches_count: 1, + completed_taches_count: 1, + fait_taches_avancement: 1, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: true, + }); + + expect(scoresMap['eci_1']).toEqual({ + action_id: 'eci_1', + point_fait: 10, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 20, + point_potentiel: 30, + point_referentiel: 30, + concerne: true, + total_taches_count: 2, + completed_taches_count: 1, + fait_taches_avancement: 1, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect(scoresMap['eci_2']).toEqual({ + action_id: 'eci_2', + point_fait: 0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 70, + point_potentiel: 70, + point_referentiel: 70, + concerne: true, + total_taches_count: 3, + completed_taches_count: 0, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect(scoresMap['eci']).toEqual({ + action_id: 'eci', + point_fait: 10, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 90, + point_potentiel: 100, + point_referentiel: 100, + concerne: true, + total_taches_count: 5, + completed_taches_count: 1, + fait_taches_avancement: 1, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + }); + + it('notation_when_one_tache_is_programme', async () => { + const personnalisationConsequences: GetPersonnalitionConsequencesResponseType = + {}; + const actionStatuts: GetActionStatutsResponseType = { + 'eci_1.1': { + concerne: true, + avancement: 'programme', + avancement_detaille: [0, 1, 0], + }, + }; + + const scoresMap = referentielsScoringService.computeScoreMap( + simpleReferentiel, + personnalisationConsequences, + actionStatuts, + 1, + ); + + const scoreLength = Object.keys(scoresMap).length; + expect(scoreLength).toEqual(8); + + expect(scoresMap['eci_1.1']).toEqual({ + action_id: 'eci_1.1', + point_fait: 0, + point_programme: 10, + point_pas_fait: 0.0, + point_non_renseigne: 0.0, + point_potentiel: 10, + point_referentiel: 10, + concerne: true, + total_taches_count: 1, + completed_taches_count: 1, + fait_taches_avancement: 0, + programme_taches_avancement: 1, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: true, + }); + + expect(scoresMap['eci_1']).toEqual({ + action_id: 'eci_1', + point_fait: 0, + point_programme: 10, + point_pas_fait: 0.0, + point_non_renseigne: 20, + point_potentiel: 30, + point_referentiel: 30, + concerne: true, + total_taches_count: 2, + completed_taches_count: 1, + fait_taches_avancement: 0, + programme_taches_avancement: 1, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect(scoresMap['eci_2']).toEqual({ + action_id: 'eci_2', + point_fait: 0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 70, + point_potentiel: 70, + point_referentiel: 70, + concerne: true, + total_taches_count: 3, + completed_taches_count: 0, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect(scoresMap['eci']).toEqual({ + action_id: 'eci', + point_fait: 0, + point_programme: 10, + point_pas_fait: 0.0, + point_non_renseigne: 90, + point_potentiel: 100, + point_referentiel: 100, + concerne: true, + total_taches_count: 5, + completed_taches_count: 1, + fait_taches_avancement: 0, + programme_taches_avancement: 1, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + }); + + it('notation_when_one_tache_is_pas_fait', async () => { + const personnalisationConsequences: GetPersonnalitionConsequencesResponseType = + {}; + const actionStatuts: GetActionStatutsResponseType = { + 'eci_1.1': { + concerne: true, + avancement: 'pas_fait', + avancement_detaille: [0, 0, 1], + }, + }; + + const scoresMap = referentielsScoringService.computeScoreMap( + simpleReferentiel, + personnalisationConsequences, + actionStatuts, + 1, + ); + + const scoreLength = Object.keys(scoresMap).length; + expect(scoreLength).toEqual(8); + + expect(scoresMap['eci_1.1']).toEqual({ + action_id: 'eci_1.1', + point_fait: 0, + point_programme: 0, + point_pas_fait: 10.0, + point_non_renseigne: 0.0, + point_potentiel: 10, + point_referentiel: 10, + concerne: true, + total_taches_count: 1, + completed_taches_count: 1, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 1, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: true, + }); + + expect(scoresMap['eci_1']).toEqual({ + action_id: 'eci_1', + point_fait: 0, + point_programme: 0, + point_pas_fait: 10, + point_non_renseigne: 20, + point_potentiel: 30, + point_referentiel: 30, + concerne: true, + total_taches_count: 2, + completed_taches_count: 1, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 1, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect(scoresMap['eci_2']).toEqual({ + action_id: 'eci_2', + point_fait: 0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 70, + point_potentiel: 70, + point_referentiel: 70, + concerne: true, + total_taches_count: 3, + completed_taches_count: 0, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect(scoresMap['eci']).toEqual({ + action_id: 'eci', + point_fait: 0, + point_programme: 0, + point_pas_fait: 10, + point_non_renseigne: 90, + point_potentiel: 100, + point_referentiel: 100, + concerne: true, + total_taches_count: 5, + completed_taches_count: 1, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 1, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + }); + + it('notation_when_one_tache_has_detailed_avancement', async () => { + const personnalisationConsequences: GetPersonnalitionConsequencesResponseType = + {}; + const actionStatuts: GetActionStatutsResponseType = { + 'eci_1.1': { + concerne: true, + avancement: 'detaille', + avancement_detaille: [0.2, 0.7, 0.1], + }, + }; + + const scoresMap = referentielsScoringService.computeScoreMap( + simpleReferentiel, + personnalisationConsequences, + actionStatuts, + 1, + ); + + const scoreLength = Object.keys(scoresMap).length; + expect(scoreLength).toEqual(8); + + expect(scoresMap['eci_1.1']).toEqual({ + action_id: 'eci_1.1', + point_fait: 2, + point_programme: 7, + point_pas_fait: 1, + point_non_renseigne: 0.0, + point_potentiel: 10, + point_referentiel: 10, + concerne: true, + total_taches_count: 1, + completed_taches_count: 1, + fait_taches_avancement: 0.2, + programme_taches_avancement: 0.7, + pas_fait_taches_avancement: 0.1, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: true, + }); + + expect(scoresMap['eci_1']).toEqual({ + action_id: 'eci_1', + point_fait: 2, + point_programme: 7, + point_pas_fait: 1, + point_non_renseigne: 20, + point_potentiel: 30, + point_referentiel: 30, + concerne: true, + total_taches_count: 2, + completed_taches_count: 1, + fait_taches_avancement: 0.2, + programme_taches_avancement: 0.7, + pas_fait_taches_avancement: 0.1, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect(scoresMap['eci_2']).toEqual({ + action_id: 'eci_2', + point_fait: 0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 70, + point_potentiel: 70, + point_referentiel: 70, + concerne: true, + total_taches_count: 3, + completed_taches_count: 0, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect(scoresMap['eci']).toEqual({ + action_id: 'eci', + point_fait: 2, + point_programme: 7, + point_pas_fait: 1, + point_non_renseigne: 90, + point_potentiel: 100, + point_referentiel: 100, + concerne: true, + total_taches_count: 5, + completed_taches_count: 1, + fait_taches_avancement: 0.2, + programme_taches_avancement: 0.7, + pas_fait_taches_avancement: 0.1, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + }); + + it('notation_when_one_tache_is_non_concerne', async () => { + const personnalisationConsequences: GetPersonnalitionConsequencesResponseType = + {}; + const actionStatuts: GetActionStatutsResponseType = { + 'eci_1.1': { + concerne: false, + avancement: 'non_renseigne', + avancement_detaille: null, + }, + }; + + const scoresMap = referentielsScoringService.computeScoreMap( + simpleReferentiel, + personnalisationConsequences, + actionStatuts, + 1, + ); + + const scoreLength = Object.keys(scoresMap).length; + expect(scoreLength).toEqual(8); + + expect(scoresMap['eci_1.1']).toEqual({ + action_id: 'eci_1.1', + point_fait: 0, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: 0.0, + point_potentiel: 0, + point_referentiel: 10, + concerne: false, + total_taches_count: 1, + completed_taches_count: 1, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 1, + desactive: false, + point_potentiel_perso: null, + renseigne: true, + }); + + // Redistribution des points + expect(scoresMap['eci_1.2']).toEqual({ + action_id: 'eci_1.2', + point_fait: 0, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: 30, + point_potentiel: 30, + point_referentiel: 20, + concerne: true, + total_taches_count: 1, + completed_taches_count: 0, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect(scoresMap['eci_1']).toEqual({ + action_id: 'eci_1', + point_fait: 0, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: 30, + point_potentiel: 30, + point_referentiel: 30, + concerne: true, + total_taches_count: 2, + completed_taches_count: 1, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 1, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect(scoresMap['eci_2']).toEqual({ + action_id: 'eci_2', + point_fait: 0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 70, + point_potentiel: 70, + point_referentiel: 70, + concerne: true, + total_taches_count: 3, + completed_taches_count: 0, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect(scoresMap['eci']).toEqual({ + action_id: 'eci', + point_fait: 0, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: 100, + point_potentiel: 100, + point_referentiel: 100, + concerne: true, + total_taches_count: 5, + completed_taches_count: 1, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 1, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + }); + + it('notation_when_an_action_of_action_level_becomes_non_concernee', async () => { + const personnalisationConsequences: GetPersonnalitionConsequencesResponseType = + {}; + const actionStatuts: GetActionStatutsResponseType = { + 'eci_1.1': { + concerne: false, + avancement: 'non_renseigne', + avancement_detaille: null, + }, + 'eci_1.2': { + concerne: false, + avancement: 'non_renseigne', + avancement_detaille: null, + }, + }; + + const scoresMap = referentielsScoringService.computeScoreMap( + simpleReferentiel, + personnalisationConsequences, + actionStatuts, + 1, + ); + + const scoreLength = Object.keys(scoresMap).length; + expect(scoreLength).toEqual(8); + + expect(scoresMap['eci_1.1']).toEqual({ + action_id: 'eci_1.1', + point_fait: 0, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: 0.0, + point_potentiel: 0, + point_referentiel: 10, + concerne: false, + total_taches_count: 1, + completed_taches_count: 1, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 1, + desactive: false, + point_potentiel_perso: null, + renseigne: true, + }); + + expect(scoresMap['eci_1.2']).toEqual({ + action_id: 'eci_1.2', + point_fait: 0, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: 0, + point_potentiel: 0, + point_referentiel: 20, + concerne: false, + total_taches_count: 1, + completed_taches_count: 1, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 1, + desactive: false, + point_potentiel_perso: null, + renseigne: true, + }); + + expect(scoresMap['eci_1']).toEqual({ + action_id: 'eci_1', + point_fait: 0, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: 0, + point_potentiel: 0, + point_referentiel: 30, + concerne: false, + total_taches_count: 2, + completed_taches_count: 2, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 2, + desactive: false, + point_potentiel_perso: null, + renseigne: true, + }); + + expect(scoresMap['eci_2']).toEqual({ + action_id: 'eci_2', + point_fait: 0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 70, + point_potentiel: 70, + point_referentiel: 70, + concerne: true, + total_taches_count: 3, + completed_taches_count: 0, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect(scoresMap['eci']).toEqual({ + action_id: 'eci', + point_fait: 0, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: 70, + point_potentiel: 70, + point_referentiel: 100, + concerne: true, + total_taches_count: 5, + completed_taches_count: 2, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 2, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + }); + + it('notation_should_not_redistribute_points_on_taches_reglementaires', async () => { + const personnalisationConsequences: GetPersonnalitionConsequencesResponseType = + {}; + const actionStatuts: GetActionStatutsResponseType = { + 'eci_2.1': { + concerne: false, + avancement: 'non_renseigne', + avancement_detaille: null, + }, + 'eci_2.2': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + }; + + const scoresMap = referentielsScoringService.computeScoreMap( + simpleReferentiel, + personnalisationConsequences, + actionStatuts, + 1, + ); + + const scoreLength = Object.keys(scoresMap).length; + expect(scoreLength).toEqual(8); + + expect(scoresMap['eci_2.0']).toEqual({ + action_id: 'eci_2.0', + point_fait: 0, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: 0.0, + point_potentiel: 0, + point_referentiel: 0, + concerne: true, + total_taches_count: 1, + completed_taches_count: 0, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, // WARNING: in python code, it is true but seems to be a mistake + }); + + // Désactivé donc point potentiel à 0 + expect(scoresMap['eci_2.1']).toEqual({ + action_id: 'eci_2.1', + point_fait: 0, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: 0, + point_potentiel: 0, + point_referentiel: 65, + concerne: false, + total_taches_count: 1, + completed_taches_count: 1, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 1, + desactive: false, + point_potentiel_perso: null, + renseigne: true, + }); + + // Points de eci_2.1 sont redistribués sur eci_2.2 + expect(scoresMap['eci_2.2']).toEqual({ + action_id: 'eci_2.2', + point_fait: 70, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: 0, + point_potentiel: 70, + point_referentiel: 5, + concerne: true, + total_taches_count: 1, + completed_taches_count: 1, + fait_taches_avancement: 1, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: true, + }); + + expect(scoresMap['eci_2']).toEqual({ + action_id: 'eci_2', + point_fait: 70, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 0, + point_potentiel: 70, + point_referentiel: 70, + concerne: true, + total_taches_count: 3, + completed_taches_count: 2, + fait_taches_avancement: 1, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 1, + desactive: false, + point_potentiel_perso: null, + renseigne: true, + }); + + expect(scoresMap['eci']).toEqual({ + action_id: 'eci', + point_fait: 70, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: 30, + point_potentiel: 100, + point_referentiel: 100, + concerne: true, + total_taches_count: 5, + completed_taches_count: 2, + fait_taches_avancement: 1, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 1, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + }); + + it('notation_should_redistribute_non_concernee_points_if_depth_is_greater_than_action_depth', async () => { + const personnalisationConsequences: GetPersonnalitionConsequencesResponseType = + {}; + + const actionStatuts: GetActionStatutsResponseType = { + 'eci_2.2.1': { + concerne: false, + avancement: 'non_renseigne', + avancement_detaille: null, + }, + 'eci_2.2.2': { + concerne: false, + avancement: 'non_renseigne', + avancement_detaille: null, + }, + 'eci_2.2.3': { + concerne: false, + avancement: 'non_renseigne', + avancement_detaille: null, + }, + 'eci_1.1': { + concerne: true, + avancement: 'programme', + avancement_detaille: [0, 1, 0], + }, + }; + + const scoresMap = referentielsScoringService.computeScoreMap( + deeperReferentiel, + personnalisationConsequences, + actionStatuts, + 1, + ); + + const scoreLength = Object.keys(scoresMap).length; + expect(scoreLength).toEqual(14); + + expect(scoresMap['eci_2.2']).toEqual({ + action_id: 'eci_2.2', + point_fait: 0, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: 0, + point_potentiel: 0, + point_referentiel: 5, + completed_taches_count: 3, + total_taches_count: 3, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 3, + concerne: false, + point_potentiel_perso: null, + desactive: false, + renseigne: true, + }); + + // point_referentiel of 2.2 is redistributed on 2.1 + expect(scoresMap['eci_2.1']).toEqual({ + action_id: 'eci_2.1', + point_fait: 0, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: 70, + point_potentiel: 70, + point_referentiel: 65, + completed_taches_count: 0, + total_taches_count: 3, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + concerne: true, + point_potentiel_perso: null, + desactive: false, + renseigne: false, + }); + + expect(scoresMap['eci_2.1.0']).toEqual({ + action_id: 'eci_2.1.0', + point_fait: 0, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: 0, + point_potentiel: 0, + point_referentiel: 0, + completed_taches_count: 0, + total_taches_count: 1, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + concerne: true, + point_potentiel_perso: null, + desactive: false, + renseigne: false, + }); + + expect(scoresMap['eci_2.1.1']).toEqual({ + action_id: 'eci_2.1.1', + point_fait: 0, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: roundTo((40 / 65) * 70, 3), + point_potentiel: roundTo((40 / 65) * 70, 3), + point_referentiel: 40, + completed_taches_count: 0, + total_taches_count: 1, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + concerne: true, + point_potentiel_perso: null, + desactive: false, + renseigne: false, + }); + + expect(scoresMap['eci_2.1.2']).toEqual({ + action_id: 'eci_2.1.2', + point_fait: 0, + point_programme: 0, + point_pas_fait: 0, + point_non_renseigne: roundTo((25 / 65) * 70, 3), + point_potentiel: roundTo((25 / 65) * 70, 3), + point_referentiel: 25, + completed_taches_count: 0, + total_taches_count: 1, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + concerne: true, + point_potentiel_perso: null, + desactive: false, + renseigne: false, + }); + + // axe 2 point_fait should remain unchanged + expect(scoresMap['eci_2']).toEqual({ + action_id: 'eci_2', + point_fait: 0, + point_pas_fait: 0, + point_programme: 0, + point_non_renseigne: 70, + point_potentiel: 70, + point_referentiel: 70, + completed_taches_count: 3, + total_taches_count: 7, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 3, + concerne: true, + point_potentiel_perso: null, + desactive: false, + renseigne: false, + }); + + // root point_fait should remain unchanged + expect(scoresMap['eci']).toEqual({ + action_id: 'eci', + point_fait: 0, + point_programme: 10, + point_pas_fait: 0, + point_non_renseigne: 90, + point_potentiel: 100, + point_referentiel: 100, + completed_taches_count: 4, + total_taches_count: 9, + fait_taches_avancement: 0, + programme_taches_avancement: 1, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 3, + concerne: true, + point_potentiel_perso: null, + desactive: false, + renseigne: false, + }); + }); + + it('notation_when_one_action_is_desactivee', async () => { + const personnalisationConsequences: GetPersonnalitionConsequencesResponseType = + { + eci_1: { + desactive: true, + score_formule: null, + potentiel_perso: null, + }, + }; + const actionStatuts: GetActionStatutsResponseType = { + 'eci_2.2': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + }; + + const scoresMap = referentielsScoringService.computeScoreMap( + simpleReferentiel, + personnalisationConsequences, + actionStatuts, + 1, + ); + + // Only action eci_1 should de desactive and potentiel reduced to 0 + expect(scoresMap['eci_1'].desactive).toEqual(true); + expect(scoresMap['eci_1'].point_potentiel_perso).toEqual(null); + // Point potentiel is impacted by desactivation + expect(scoresMap['eci_1'].point_potentiel).toEqual(0); + // Point referentiel is not impacted by desactivation + expect(scoresMap['eci_1'].point_referentiel).toEqual(30); + + // Consequences on action children should affect point_potentiel (reduced to 0) but not point_potentiel_perso that is null + expect(scoresMap['eci_1.1'].desactive).toEqual(true); + expect(scoresMap['eci_1.1'].point_potentiel_perso).toEqual(null); + // Point potentiel is impacted by desactivation + expect(scoresMap['eci_1.1'].point_potentiel).toEqual(0); + // Point referentiel is not impacted by desactivation + expect(scoresMap['eci_1.1'].point_referentiel).toEqual(10); + expect(scoresMap['eci_1.2'].desactive).toEqual(true); + expect(scoresMap['eci_1.2'].point_potentiel_perso).toEqual(null); + // Point potentiel is impacted by desactivation + expect(scoresMap['eci_1.2'].point_potentiel).toEqual(0); + // Point referentiel is not impacted by desactivation + expect(scoresMap['eci_1.2'].point_referentiel).toEqual(20); + + // Consequences should also affect action parent potentiel points + expect(scoresMap['eci'].point_potentiel).toEqual(70); + // Consequences should not affect parent point referentiel, desactive and point_potentiel_perso + expect(scoresMap['eci'].desactive).toEqual(false); + expect(scoresMap['eci'].point_potentiel_perso).toEqual(null); + expect(scoresMap['eci'].point_referentiel).toEqual(100); + + // Check scores are still calculated correctly + expect(scoresMap['eci'].point_fait).toEqual(5); + expect(scoresMap['eci_2.2'].point_fait).toEqual(5); + }); + + it('notation_when_one_action_is_reduced', async () => { + const personnalisationConsequences: GetPersonnalitionConsequencesResponseType = + { + eci_1: { + desactive: null, + score_formule: null, + potentiel_perso: 0.2, // Action eci_1 officially worse 30 points, so will be reduced to 6 points + }, + }; + const actionStatuts: GetActionStatutsResponseType = { + 'eci_1.1': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + }; + + const scoresMap = referentielsScoringService.computeScoreMap( + simpleReferentiel, + personnalisationConsequences, + actionStatuts, + 1, + ); + + // Actions eci_1.1 and eci_1.2 should also have been reduced with a factor of 0.2 + expect(scoresMap['eci_1.1']).toEqual({ + action_id: 'eci_1.1', + point_fait: 2.0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 0.0, + point_potentiel: 2.0, + point_referentiel: 10, + concerne: true, + total_taches_count: 1, + completed_taches_count: 1, + fait_taches_avancement: 1, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: true, + }); + + expect(scoresMap['eci_1.2']).toEqual({ + action_id: 'eci_1.2', + point_fait: 0.0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 4.0, + point_potentiel: 4.0, + point_referentiel: 20, + concerne: true, + total_taches_count: 1, + completed_taches_count: 0, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect(scoresMap['eci_1']).toEqual({ + action_id: 'eci_1', + point_fait: 2.0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 4.0, + point_potentiel: 6.0, + point_referentiel: 30, + concerne: true, + total_taches_count: 2, + completed_taches_count: 1, + fait_taches_avancement: 1, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: 6.0, + renseigne: false, + }); + + expect(scoresMap['eci']).toEqual({ + action_id: 'eci', + point_fait: 2.0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 74.0, + point_potentiel: 76.0, + point_referentiel: 100, + concerne: true, + total_taches_count: 5, + completed_taches_count: 1, + fait_taches_avancement: 1, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + }); + + it('notation_when_one_action_is_increased', async () => { + const personnalisationConsequences: GetPersonnalitionConsequencesResponseType = + { + eci_1: { + desactive: null, + score_formule: null, + potentiel_perso: 1.2, // Action eci_1 officially worse 30 points, so will be increased to 36 points + }, + }; + const actionStatuts: GetActionStatutsResponseType = { + 'eci_1.1': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + }; + + const scoresMap = referentielsScoringService.computeScoreMap( + simpleReferentiel, + personnalisationConsequences, + actionStatuts, + 1, + ); + + // Actions eci_1.1 and eci_1.2 should also have been reduced with a factor of 1.2 + expect(scoresMap['eci_1.1']).toEqual({ + action_id: 'eci_1.1', + point_fait: 12.0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 0.0, + point_potentiel: 12.0, // 10 * 1.2 + point_referentiel: 10, + concerne: true, + total_taches_count: 1, + completed_taches_count: 1, + fait_taches_avancement: 1, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: true, + }); + + expect(scoresMap['eci_1.2']).toEqual({ + action_id: 'eci_1.2', + point_fait: 0.0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 24.0, + point_potentiel: 24.0, // 20 * 1.2 + point_referentiel: 20, + concerne: true, + total_taches_count: 1, + completed_taches_count: 0, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect(scoresMap['eci_1']).toEqual({ + action_id: 'eci_1', + point_fait: 12.0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 24.0, + point_potentiel: 36, // (30 * 1.2) + point_referentiel: 30, + concerne: true, + total_taches_count: 2, + completed_taches_count: 1, + fait_taches_avancement: 1, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: 36.0, // Consequence applied here ! (30 * 1.2) + renseigne: false, + }); + + expect(scoresMap['eci']).toEqual({ + action_id: 'eci', + point_fait: 12.0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 94.0, + point_potentiel: 106.0, // (70 from eci_2 and 36 from eci_1) + point_referentiel: 100, + concerne: true, + total_taches_count: 5, + completed_taches_count: 1, + fait_taches_avancement: 1, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + }); + + it('notation_when_potentiel_perso_formule_is_given', async () => { + const personnalisationConsequences: GetPersonnalitionConsequencesResponseType = + { + eci_1: { + desactive: null, + score_formule: 'min(score(eci_1), score(eci_2))', + potentiel_perso: null, + }, + }; + const actionStatuts: GetActionStatutsResponseType = { + 'eci_2.2': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], // 5 points + }, + 'eci_1.1': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], // 10 points + }, + 'eci_1.2': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], // 20 points + }, + }; + + const scoresMap = referentielsScoringService.computeScoreMap( + simpleReferentiel, + personnalisationConsequences, + actionStatuts, + 1, + ); + + // Action eci_2 should not have been changed + expect(scoresMap['eci_2']).toEqual({ + action_id: 'eci_2', + point_fait: 5, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 65, + point_potentiel: 70, + point_referentiel: 70, + concerne: true, + total_taches_count: 3, + completed_taches_count: 1, + fait_taches_avancement: 1, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + + expect( + roundTo( + scoresMap['eci_1'].point_fait! / scoresMap['eci_1'].point_potentiel!, + 5, + ), + ).toEqual( + roundTo( + scoresMap['eci_2'].point_fait! / scoresMap['eci_2'].point_potentiel!, + 5, + ), + ); + + expect(scoresMap['eci_1'].point_fait).toEqual(2.143); + expect(scoresMap['eci_1.1'].point_fait).toEqual(0.714); + expect(scoresMap['eci_1.2'].point_fait).toEqual(1.429); + expect(scoresMap['eci'].point_fait).toEqual(7.143); + }); + + it('eci_desactivation_of_sous_action_242_should_redistribute_points_amongst_siblings', async () => { + const personnalisationConsequences: GetPersonnalitionConsequencesResponseType = + { + 'eci_2.4.2': { + desactive: true, + score_formule: null, + potentiel_perso: null, + }, + }; + const actionStatuts: GetActionStatutsResponseType = {}; + + const scoresMap = referentielsScoringService.computeScoreMap( + eciReferentiel, + personnalisationConsequences, + actionStatuts, + 2, + ); + + expect(scoresMap['eci_2.4.2']).toEqual({ + action_id: 'eci_2.4.2', + point_fait: 0.0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 0.0, + point_potentiel: 0.0, + point_referentiel: 4, + concerne: false, + total_taches_count: 4, + completed_taches_count: 4, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 4, + desactive: true, + point_potentiel_perso: null, + renseigne: true, + }); + + // Points correctement redistribués + expect(scoresMap['eci_2.4.0'].point_potentiel).toEqual(0); // action réglementaire + expect(scoresMap['eci_2.4.1'].point_potentiel).toEqual(5); // 4 + 1 + expect(scoresMap['eci_2.4.2'].point_potentiel).toEqual(0); // désactivé + expect(scoresMap['eci_2.4.3'].point_potentiel).toEqual(3); // 2 + 1 + expect(scoresMap['eci_2.4.4'].point_potentiel).toEqual(7); // 6 + 1 + expect(scoresMap['eci_2.4.5'].point_potentiel).toEqual(5); // 4 + 1 + + // Toujours 20 points pour eci_2.4 + expect(scoresMap['eci_2.4']).toEqual({ + action_id: 'eci_2.4', + point_fait: 0.0, + point_programme: 0.0, + point_pas_fait: 0.0, + point_non_renseigne: 20.0, + point_potentiel: 20.0, + point_referentiel: 20, + concerne: true, + total_taches_count: 17, + completed_taches_count: 4, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 4, + desactive: false, + point_potentiel_perso: null, + renseigne: false, + }); + }); + + it('cae_321_when_recuperation_cogeneration_is_NON', async () => { + const reponses: GetPersonnalisationReponsesResponseType = { + recuperation_cogeneration: false, + }; + const collectiviteInfo: IdentiteCollectivite = { + type: CollectiviteTypeEnum.COMMUNE, + soustype: null, + population_tags: [], + drom: false, + }; + const personnalisationConsequences = + await personnalisationService.getPersonnalisationConsequences( + caePersonnalisationRegles, + reponses, + collectiviteInfo, + ); + + const actionStatuts: GetActionStatutsResponseType = {}; + + const scoresMap = referentielsScoringService.computeScoreMap( + caeReferentiel, + personnalisationConsequences, + actionStatuts, + 3, + ); + + // Si la récupération recuperation_cogeneration est NON, alors, cae_3.2.1.2 et cae_3.2.1.3 sont désactivées et cae_3.2.1.1 vaut 2 points + expect(scoresMap['cae_3.2.1.2'].point_potentiel).toEqual(0); + expect(scoresMap['cae_3.2.1.2'].desactive).toEqual(true); + expect(scoresMap['cae_3.2.1.3'].concerne).toEqual(false); + expect(scoresMap['cae_3.2.1.3'].point_potentiel).toEqual(0); + expect(scoresMap['cae_3.2.1.3'].desactive).toEqual(true); + expect(scoresMap['cae_3.2.1.3'].concerne).toEqual(false); + + expect(scoresMap['cae_3.2.1'].point_potentiel_perso).toEqual(2); + expect(scoresMap['cae_3.2.1'].point_potentiel).toEqual(2); + expect(scoresMap['cae_3.2.1.1'].point_potentiel).toEqual(2); + expect(scoresMap['cae_3.2.1.1.1'].point_potentiel).toEqual(0.25); + }); + + it('cae_631_when_dev_eco_2_is_0', async () => { + const reponses: GetPersonnalisationReponsesResponseType = { + dev_eco_2: 0.0, + }; + const collectiviteInfo: IdentiteCollectivite = { + type: CollectiviteTypeEnum.COMMUNE, + soustype: null, + population_tags: [], + drom: false, + }; + const personnalisationConsequences = + await personnalisationService.getPersonnalisationConsequences( + caePersonnalisationRegles, + reponses, + collectiviteInfo, + ); + + const actionStatuts: GetActionStatutsResponseType = {}; + + const scoresMap = referentielsScoringService.computeScoreMap( + caeReferentiel, + personnalisationConsequences, + actionStatuts, + 3, + ); + + expect(scoresMap['cae_6.3.1'].point_potentiel).toEqual(2); + expect(scoresMap['cae_6.3.1'].point_potentiel_perso).toEqual(2); + }); + + it('cae_631_when_cae_6314_if_dev_eco_4_is_NON', async () => { + /* + En l’absence de tissu économique propice à l’émergence de projets d’écologie industrielle, le score de la 6.3.1.4 + est réduit à 0 et son statut est "non concerné" : les 2 points liés sont affectés à la 6.3.1.3 et la 6.3.1.5 + + Lié aux règles de personnalisation sur 6.3.1.4, 6.3.1.3, 6.3.1.5. On n'utilise pas la redistributin automatique de potentiel dans ce cas + + Scénario testé: + --------------- + si reponse(dev_eco_4, NON) alors + - 6.3.1.1 proportion 15% => 15% + - 6.3.1.2 proportion 20% => 20% + - 6.3.1.3 proportion 20% => 32.5% + - 6.3.1.4 proportion 25% => Désactivé, non-concerné, 0% + - 6.3.1.5 proportion 20% => 32.5% + */ + + const reponses: GetPersonnalisationReponsesResponseType = { + dev_eco_4: false, + }; + const collectiviteInfo: IdentiteCollectivite = { + type: CollectiviteTypeEnum.COMMUNE, + soustype: null, + population_tags: [], + drom: false, + }; + const personnalisationConsequences = + await personnalisationService.getPersonnalisationConsequences( + caePersonnalisationRegles, + reponses, + collectiviteInfo, + ); + + const actionStatuts: GetActionStatutsResponseType = {}; + + const scoresMap = referentielsScoringService.computeScoreMap( + caeReferentiel, + personnalisationConsequences, + actionStatuts, + 3, + ); + + expect(scoresMap['cae_6.3.1.4'].desactive).toEqual(true); + expect(scoresMap['cae_6.3.1.4'].point_potentiel).toEqual(0); + expect(scoresMap['cae_6.3.1.4'].concerne).toEqual(false); + + // Pas de redistribution automatique de potentiel (car on a des règles de personnalisation) donc les points de cae_6.3.1.1 et cae_6.3.1.2 restent inchangés + expect(scoresMap['cae_6.3.1.1'].point_potentiel).toEqual( + scoresMap['cae_6.3.1.1'].point_referentiel, + ); + expect(scoresMap['cae_6.3.1.2'].point_potentiel).toEqual( + scoresMap['cae_6.3.1.2'].point_referentiel, + ); + + // Les points de cae_6.3.1.3 et cae_6.3.1.5 ont été augmentés de 1 point chacun (facteur 1.625 dans les règles de personnalisation) + expect(scoresMap['cae_6.3.1.3'].point_potentiel).toEqual( + (scoresMap['cae_6.3.1.3'].point_referentiel || 0) + 1, + ); + expect(scoresMap['cae_6.3.1.3'].point_potentiel).toEqual( + (scoresMap['cae_6.3.1.3'].point_referentiel || 0) * 1.625, + ); + expect(scoresMap['cae_6.3.1.5'].point_potentiel).toEqual( + (scoresMap['cae_6.3.1.5'].point_referentiel || 0) + 1, + ); + expect(scoresMap['cae_6.3.1.5'].point_potentiel).toEqual( + (scoresMap['cae_6.3.1.5'].point_referentiel || 0) * 1.625, + ); + + // Les points de cae_6.3.1 restent inchangés + expect(scoresMap['cae_6.3.1'].point_potentiel).toEqual( + scoresMap['cae_6.3.1'].point_referentiel, + ); + }); + + it('cae_641_when_localosation_dom_and_SAU_OUI', async () => { + /* + Reduction de 50% de la 6.4.1 & transfert de qqes points de la 6.4.1.6 à la 6.4.1.8. + La note du référentiel actuel est à 15 %. Pour les collectivités DOM, la note de la sous-action passe à 20 % de 6 points (12 * 0.5). + La note du référentiel actuel est à 15 %. Pour les collectivités DOM, la note de la sous-action passe à 10 % de 6 points (12 * 0.5). + + Scénario testé: + --------------- + si identite(localisation, DOM) alors + - 6.4.1.1, 6.4.1.2, 6.4.1.3, 6.4.1.4, 6.4.1.5 et 6.4.1.7 inchangées + - 6.4.1.6 passe de 15% à 20% + - 6.4.1.8 passe de 15% à 10% + */ + + const reponses: GetPersonnalisationReponsesResponseType = { + SAU: true, + }; + const collectiviteInfo: IdentiteCollectivite = { + type: CollectiviteTypeEnum.COMMUNE, + soustype: null, + population_tags: [], + drom: true, + }; + const personnalisationConsequences = + await personnalisationService.getPersonnalisationConsequences( + caePersonnalisationRegles, + reponses, + collectiviteInfo, + ); + + const actionStatuts: GetActionStatutsResponseType = {}; + + const scoresMap = referentielsScoringService.computeScoreMap( + caeReferentiel, + personnalisationConsequences, + actionStatuts, + 3, + ); + + expect(scoresMap['cae_6.4.1'].point_potentiel).toEqual( + (scoresMap['cae_6.4.1'].point_referentiel || 0) * 0.5, + ); + expect(scoresMap['cae_6.4.1'].point_potentiel_perso).toEqual( + (scoresMap['cae_6.4.1'].point_referentiel || 0) * 0.5, + ); + + // Seulement affecté par la réduction de potentiel du parent pour ces actions + const actionIdsWithoutAugmentation = [ + 'cae_6.4.1.1', + 'cae_6.4.1.2', + 'cae_6.4.1.3', + 'cae_6.4.1.4', + 'cae_6.4.1.5', + 'cae_6.4.1.7', + ]; + actionIdsWithoutAugmentation.forEach((actionId) => { + expect(scoresMap[actionId].point_potentiel).toEqual( + (scoresMap[actionId].point_referentiel || 0) * 0.5, + ); + }); + + // 6.4.1.6 passe de 15% à 20% + expect(scoresMap['cae_6.4.1.6'].point_potentiel).toEqual( + ((scoresMap['cae_6.4.1'].point_potentiel || 0) * 20) / 100, + ); + expect(scoresMap['cae_6.4.1.6'].point_potentiel).toEqual(1.2); + + // 6.4.1.8 passe de 15% à 10% + expect(scoresMap['cae_6.4.1.8'].point_potentiel).toEqual( + ((scoresMap['cae_6.4.1'].point_potentiel || 0) * 10) / 100, + ); + expect(scoresMap['cae_6.4.1.8'].point_potentiel).toEqual(0.6); + }); + + it('cae_621_when_type_commune', async () => { + /* + Reduction potentiel cae 6.2.1 liee logement-habitat + + Si la collectivité est une commune, alors la réduction de potentiel est proportionnelle à la part dans l’EPCI compétent en matière de politique du logement et du cadre de vie, dans la limite de 2 points restant minimum. + Si la commune participe au conseil d’administration d'un bailleur social, le potentiel, possiblement réduit est + augmenté d'un point sur la 6.2.1 + */ + + const collectiviteInfo: IdentiteCollectivite = { + type: CollectiviteTypeEnum.COMMUNE, + soustype: null, + population_tags: [], + drom: false, + }; + const actionStatuts: GetActionStatutsResponseType = {}; + + /** + Cas 1 : Si une commune est à 10 % de l'EPCI et qu'elle participe au conseil d'administration d'un bailleur social, elle est notée sur 3 points + ------ + si identite(type, commune) et reponse(habitat_3, OUI) et reponse(habitat_2, 10%) + - cae 6.2.1 est réduite à 2 points et on lui ajoute 1 point, donc a un potentiel de 3 points + */ + + const reponsesCas1: GetPersonnalisationReponsesResponseType = { + habitat_3: true, + habitat_2: 0.1, + }; + const personnalisationConsequencesCas1 = + await personnalisationService.getPersonnalisationConsequences( + caePersonnalisationRegles, + reponsesCas1, + collectiviteInfo, + ); + + const scoresMapCas1 = referentielsScoringService.computeScoreMap( + caeReferentiel, + personnalisationConsequencesCas1, + actionStatuts, + 3, + ); + + expect(scoresMapCas1['cae_6.2.1'].point_potentiel).toEqual(3); + + /** + Cas 2 : Si une commune est à 50 % de l'EPCI et qu'elle participe au conseil d'administration d'un bailleur social, elle est notée sur 6 points + ------- + si identite(type, commune) et reponse(habitat_3, OUI) et reponse(habitat_2, 50%) + - cae 6.2.1 est réduite de 50% et on lui ajoute 1 point, donc a un potentiel de 6 points + */ + + const reponsesCas2: GetPersonnalisationReponsesResponseType = { + habitat_3: true, + habitat_2: 0.5, + }; + const personnalisationConsequencesCas2 = + await personnalisationService.getPersonnalisationConsequences( + caePersonnalisationRegles, + reponsesCas2, + collectiviteInfo, + ); + const scoresMapCas2 = referentielsScoringService.computeScoreMap( + caeReferentiel, + personnalisationConsequencesCas2, + actionStatuts, + 3, + ); + + expect(scoresMapCas2['cae_6.2.1'].point_potentiel).toEqual(6); + + /** + Cas 3 : Si une commune est à 10 % de l'EPCI et qu'elle ne participe pas au conseil d'administration d'un bailleur social, elle est notée sur 2 points + ------ + si identite(type, commune) et reponse(habitat_3, NON) et reponse(habitat_2, 10%) + - cae 6.2.1 est réduite à 2 points et on ne lui rajoute pas de points, donc a un potentiel de 2 points + */ + + const reponsesCas3: GetPersonnalisationReponsesResponseType = { + habitat_3: false, + habitat_2: 0.1, + }; + const personnalisationConsequencesCas3 = + await personnalisationService.getPersonnalisationConsequences( + caePersonnalisationRegles, + reponsesCas3, + collectiviteInfo, + ); + const scoresMapCas3 = referentielsScoringService.computeScoreMap( + caeReferentiel, + personnalisationConsequencesCas3, + actionStatuts, + 3, + ); + + expect(scoresMapCas3['cae_6.2.1'].point_potentiel).toEqual(2); + }); + + it('cae_335_with_score_taken_into_account', async () => { + /* + Overide du score de cae_3.3.5 liée au score obtenue à l'action cae_1.2.3 + + Pour une commune, la note est réduite à 2 points en l'absence de la compétence traitement des déchets. + Pour un EPCI ayant transféré la compétence traitement des déchets à un syndicat compétent en la matière, la note est réduite proportionnelle à sa participation dans ce syndicat, dans la limite de 2 points restants. + Pour favoriser la prévention des déchets, la note attribuée à cette action ne peut dépasser celle obtenue dans l'action 1.2.3. + */ + + const communeInfo: IdentiteCollectivite = { + type: CollectiviteTypeEnum.COMMUNE, + soustype: null, + population_tags: [], + drom: false, + }; + const epciInfo: IdentiteCollectivite = { + type: CollectiviteTypeEnum.EPCI, + soustype: null, + population_tags: [], + drom: false, + }; + + /** + Cas 1 : Si commune avec compétence traitement déchets, il n'y a pas de réduction de potentiel. + ------ + + Quand reponse(dechets_2, OUI), cae_1.2.3 est réduit de 0.75, et est donc notée sur 7.5 points au lieu de 10 points. + La sous-action cae_1.2.3.3 représente 30% de l'action donc est noté sur 30% de 7.5 points, ce qui fait 2.25 points. + La sous-action cae_3.3.5.3 vaut initiallement 4.8 points + Chaque tâche de cette sous-saction vaut 1.2 points, donc si une tâche est faite, score_realise(cae_3.3.5) = 1.2 + */ + + const actionStatutsCas1: GetActionStatutsResponseType = { + 'cae_1.2.3.3.1': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + 'cae_1.2.3.3.2': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + 'cae_1.2.3.3.3': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + 'cae_1.2.3.3.4': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + 'cae_1.2.3.3.5': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + 'cae_3.3.5.3.1': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + }; + + const reponsesCas1: GetPersonnalisationReponsesResponseType = { + dechets_1: false, + dechets_2: true, + dechets_3: false, + }; + const personnalisationConsequencesCas1 = + await personnalisationService.getPersonnalisationConsequences( + caePersonnalisationRegles, + reponsesCas1, + communeInfo, + ); + + const scoresMapCas1 = referentielsScoringService.computeScoreMap( + caeReferentiel, + personnalisationConsequencesCas1, + actionStatutsCas1, + 3, + ); + + expect(scoresMapCas1['cae_1.2.3'].point_fait).toEqual(2.25); + expect(scoresMapCas1['cae_3.3.5'].point_fait).toEqual(1.2); + + /** + Cas 2 : Si commune avec compétence déchets, il n'y a pas de réduction de potentiel mais le score de la 3.3.5 est majoré par celui de la 1.2.3 + La sous-action cae_3.3.5.3 vaut initialement 4.8 points + Chaque tâche de cette sous-saction vaut 1.2 points, donc si une tâche est faite, score_realise(cae_3.3.5) = 1.2 + Aucune réponse pour cae_1.2.3 => score_realise(cae_1.2.3) = 0 + La majoration du score de la 3.3.5 par la 1.2.3 entraîne donc que la 3.3.5 vaut a un score réalisé de 0 point. + */ + + const actionStatutsCas2: GetActionStatutsResponseType = { + 'cae_3.3.5.3.1': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + }; + + const reponsesCas2: GetPersonnalisationReponsesResponseType = { + dechets_2: true, + }; + const personnalisationConsequencesCas2 = + await personnalisationService.getPersonnalisationConsequences( + caePersonnalisationRegles, + reponsesCas2, + communeInfo, + ); + + const scoresMapCas2 = referentielsScoringService.computeScoreMap( + caeReferentiel, + personnalisationConsequencesCas2, + actionStatutsCas2, + 3, + ); + + expect(scoresMapCas2['cae_1.2.3'].point_fait).toEqual(0); + expect(scoresMapCas2['cae_3.3.5'].point_fait).toEqual(0); // Au lieu de 1.2 ! + + /** + Cas 3 : Si EPCI sans compétence déchets et participation dans syndicat compétent de 10% et points_fait(cae_1.2.3, 2.25) alors potentiel(cae_3.3.5) = 2 + Quand reponse(dechets_2, NON), cae_1.2.3.3 est réduite de 75% et donc notée sur 2.25 points au lieu de 3 points + Si toutes les tâches sont faites, alors le score réalisé de cae_1.2.3 est de 2.25 + */ + + const actionStatutsCas3: GetActionStatutsResponseType = { + 'cae_1.2.3.3.1': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + 'cae_1.2.3.3.2': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + 'cae_1.2.3.3.3': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + 'cae_1.2.3.3.4': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + 'cae_1.2.3.3.5': { + concerne: true, + avancement: 'fait', + avancement_detaille: [1, 0, 0], + }, + }; + + const reponsesCas3: GetPersonnalisationReponsesResponseType = { + dechets_1: true, + dechets_2: false, + dechets_4: 0.1, + }; + + const personnalisationConsequencesCas3 = + await personnalisationService.getPersonnalisationConsequences( + caePersonnalisationRegles, + reponsesCas3, + epciInfo, + ); + + const scoresMapCas3 = referentielsScoringService.computeScoreMap( + caeReferentiel, + personnalisationConsequencesCas3, + actionStatutsCas3, + 3, + ); + + expect(scoresMapCas3['cae_1.2.3'].point_fait).toEqual(2.25); + expect(scoresMapCas3['cae_3.3.5'].point_fait).toEqual(0); + expect(scoresMapCas3['cae_3.3.5'].point_potentiel).toEqual(2.0); + + /** + Cas 4 : Si EPCI et non concernée à la 3.3.5, la règle n'a pas de conséquence + */ + + const actionStatutsCas4: GetActionStatutsResponseType = {}; + for (let i = 1; i < 7; i++) { + actionStatutsCas4[`cae_3.3.5.1.${i}`] = { + concerne: false, + avancement: 'detaille', + avancement_detaille: [0, 0, 0], + }; + } + for (let i = 1; i < 10; i++) { + actionStatutsCas4[`cae_3.3.5.2.${i}`] = { + concerne: false, + avancement: 'detaille', + avancement_detaille: [0, 0, 0], + }; + } + for (let i = 1; i < 5; i++) { + actionStatutsCas4[`cae_3.3.5.3.${i}`] = { + concerne: false, + avancement: 'detaille', + avancement_detaille: [0, 0, 0], + }; + } + + const reponsesCas4: GetPersonnalisationReponsesResponseType = { + dechets_2: false, + dechets_4: 0.1, + }; + const personnalisationConsequencesCas4 = + await personnalisationService.getPersonnalisationConsequences( + caePersonnalisationRegles, + reponsesCas4, + epciInfo, + ); + + const scoresMapCas4 = referentielsScoringService.computeScoreMap( + caeReferentiel, + personnalisationConsequencesCas4, + actionStatutsCas4, + 3, + ); + + expect(scoresMapCas4['cae_3.3.5'].concerne).toEqual(false); + expect(scoresMapCas4['cae_3.3.5'].point_potentiel).toEqual(0); + }); + }); +}); diff --git a/backend/src/referentiels/services/referentiels-scoring.service.ts b/backend/src/referentiels/services/referentiels-scoring.service.ts new file mode 100644 index 0000000000..55df8a0e01 --- /dev/null +++ b/backend/src/referentiels/services/referentiels-scoring.service.ts @@ -0,0 +1,857 @@ +import { HttpException, Injectable, Logger, NotFoundException } from '@nestjs/common'; +import { and, asc, desc, eq, like, lte, SQL, SQLWrapper } from 'drizzle-orm'; +import * as _ from 'lodash'; +import { NiveauAcces, SupabaseJwtPayload } from '../../auth/models/auth.models'; +import { AuthService } from '../../auth/services/auth.service'; +import { CollectiviteAvecType } from '../../collectivites/models/collectivite.models'; +import CollectivitesService from '../../collectivites/services/collectivites.service'; +import DatabaseService from '../../common/services/database.service'; +import { roundTo } from '../../common/services/number.helper'; +import { GetPersonnalitionConsequencesResponseType } from '../../personnalisations/models/get-personnalisation-consequences.response'; +import ExpressionParserService from '../../personnalisations/services/expression-parser.service'; +import PersonnalisationsService from '../../personnalisations/services/personnalisations-service'; +import { ActionScoreType } from '../models/action-score.dto'; +import { actionStatutTable, ActionStatutType } from '../models/action-statut.table'; +import { ActionType } from '../models/action-type.enum'; +import { clientScoresTable } from '../models/client-scores.table'; +import { GetActionScoresResponseType } from '../models/get-action-scores.response'; +import { GetActionStatutsResponseType } from '../models/get-action-statuts.response'; +import { GetCheckScoresResponseType } from '../models/get-check-scores.response'; +import { historiqueActionStatutTable } from '../models/historique-action-statut.table'; +import { ReferentielActionAvecScoreType } from '../models/referentiel-action-avec-score.dto'; +import { ReferentielActionType } from '../models/referentiel-action.dto'; +import { ReferentielType } from '../models/referentiel.enum'; +import ReferentielsService from './referentiels.service'; + +@Injectable() +export default class ReferentielsScoringService { + private readonly logger = new Logger(ReferentielsScoringService.name); + + constructor( + private readonly authService: AuthService, + private readonly collectivitesService: CollectivitesService, + private readonly databaseService: DatabaseService, + private readonly referentielsService: ReferentielsService, + private readonly personnalisationService: PersonnalisationsService, + private readonly expressionParserService: ExpressionParserService, + ) {} + + async checkCollectiviteAndReferentielWithAccess( + collectiviteId: number, + referentielId: ReferentielType, + date?: string, + tokenInfo?: SupabaseJwtPayload, + niveauAccesMinimum = NiveauAcces.LECTURE + ): Promise { + + // Check read access if a date is given (historical data) + if (tokenInfo && date) { + await this.authService.verifieAccesAuxCollectivites( + tokenInfo, + [collectiviteId], + niveauAccesMinimum, + ); + } + await this.referentielsService.checkReferentielExists(referentielId); + + return this.collectivitesService.getCollectiviteAvecType(collectiviteId); + } + + buildReferentielAvecScore( + referentiel: ReferentielActionType, + ): ReferentielActionAvecScoreType { + const referentielAvecScore: ReferentielActionAvecScoreType = { + ...referentiel, + score: { + action_id: referentiel.action_id!, + point_referentiel: !_.isNil(referentiel.points) + ? referentiel.points + : null, + point_potentiel: null, + point_potentiel_perso: null, + point_fait: null, + point_pas_fait: null, + point_non_renseigne: null, + point_programme: null, + concerne: true, + completed_taches_count: null, + total_taches_count: 1, + fait_taches_avancement: null, + programme_taches_avancement: null, + pas_fait_taches_avancement: null, + pas_concerne_taches_avancement: null, + desactive: false, + renseigne: true, + }, + actions_enfant: [], + }; + referentiel.actions_enfant.forEach((actionEnfant) => { + const actionEnfantAvecScore = + this.buildReferentielAvecScore(actionEnfant); + referentielAvecScore.actions_enfant.push(actionEnfantAvecScore); + }); + const totalTachesCount = referentielAvecScore.actions_enfant.length + ? referentielAvecScore.actions_enfant.reduce( + (acc, enfant) => acc + (enfant.score.total_taches_count || 1), + 0, + ) + : 1; + referentielAvecScore.score.total_taches_count = totalTachesCount; + + return referentielAvecScore; + } + + appliquePersonnalisationPotentielPerso( + referentielActionAvecScore: ReferentielActionAvecScoreType, + personnalisationConsequences: GetPersonnalitionConsequencesResponseType, + potentielPerso?: number, + ) { + let recursivePotentielPerso = potentielPerso; + const actionPersonnalisationConsequences = + personnalisationConsequences[referentielActionAvecScore.action_id!]; + // Si il y a un potentiel perso on l'applique et on le propagera aux enfants + if (!_.isNil(actionPersonnalisationConsequences?.potentiel_perso)) { + recursivePotentielPerso = + actionPersonnalisationConsequences.potentiel_perso * + (potentielPerso || 1); + referentielActionAvecScore.score.point_potentiel_perso = + recursivePotentielPerso * + (referentielActionAvecScore.score.point_referentiel || 0); + } + + if ( + !_.isNil(recursivePotentielPerso) && + referentielActionAvecScore.score.point_referentiel + ) { + referentielActionAvecScore.score.point_potentiel = + recursivePotentielPerso * + referentielActionAvecScore.score.point_referentiel; + } + + referentielActionAvecScore.actions_enfant.forEach((actionEnfant) => { + this.appliquePersonnalisationPotentielPerso( + actionEnfant, + personnalisationConsequences, + recursivePotentielPerso, + ); + }); + + // Maintenant qu'on l'a appliqué aux enfants, on recalcule le potentiel perso du parent s'il n'a pas déjà été calculé + if (_.isNil(referentielActionAvecScore.score.point_potentiel)) { + if (referentielActionAvecScore.actions_enfant.length) { + referentielActionAvecScore.score.point_potentiel = + referentielActionAvecScore.actions_enfant.reduce((acc, enfant) => { + if (_.isNil(enfant.score.point_potentiel)) { + return acc + (enfant.score.point_referentiel || 0); + } + return acc + enfant.score.point_potentiel; + }, 0); + } else { + referentielActionAvecScore.score.point_potentiel = + referentielActionAvecScore.score.point_referentiel || 0; + } + } + } + + appliquePersonnalisationDesactivation( + referentielActionAvecScore: ReferentielActionAvecScoreType, + personnalisationConsequences: GetPersonnalitionConsequencesResponseType, + parentDesactivation?: boolean, + ) { + const actionPersonnalisationConsequences = + personnalisationConsequences[referentielActionAvecScore.action_id!]; + // Si le parent n'est pas déjà désactivé et il y a une desactivation on l'applique et on le propagera aux enfants + if (!parentDesactivation && actionPersonnalisationConsequences?.desactive) { + parentDesactivation = actionPersonnalisationConsequences?.desactive; + } + referentielActionAvecScore.score.desactive = parentDesactivation || false; + if (referentielActionAvecScore.score.desactive) { + // Si l'action est désactivée, on place le flag concerné à false + referentielActionAvecScore.score.concerne = false; + } + + referentielActionAvecScore.actions_enfant.forEach((actionEnfant) => { + this.appliquePersonnalisationDesactivation( + actionEnfant, + personnalisationConsequences, + parentDesactivation, + ); + }); + } + + appliqueActionStatutNonConcerneEtRemonteAuxParents( + referentielActionAvecScore: ReferentielActionAvecScoreType, + actionStatuts: GetActionStatutsResponseType, + parentConcerne: boolean = true, + ) { + const actionStatut = actionStatuts[referentielActionAvecScore.action_id!]; + // Si le parent n'est pas déjà désactivé et il y a une desactivation on l'applique et on le propagera aux enfants + if (parentConcerne && actionStatut && !actionStatut.concerne) { + parentConcerne = actionStatut.concerne; + } + + // On applique parent concerne que si il est à faut + // Ceci afin d'éviter de réactiver une action qui a été désactivée par une règle de personnalisation + if (!parentConcerne) { + referentielActionAvecScore.score.concerne = parentConcerne; + } + + referentielActionAvecScore.actions_enfant.forEach((actionEnfant) => { + this.appliqueActionStatutNonConcerneEtRemonteAuxParents( + actionEnfant, + actionStatuts, + parentConcerne, + ); + }); + + // Maintant qu'on l'a appliqué aux enfants, on remonte aux parents + // Si tous ces enfants sont non concernés, alors il est non concerné + if ( + referentielActionAvecScore.actions_enfant.length && + referentielActionAvecScore.actions_enfant.every( + (enfant) => !enfant.score.concerne, + ) + ) { + this.logger.log( + `Tous les enfants de ${referentielActionAvecScore.action_id} sont non concernés, donc il est non concerné`, + ); + referentielActionAvecScore.score.concerne = false; + } + } + + redistribuePotentielActionsDesactiveesNonConcernees( + referentielActionAvecScore: ReferentielActionAvecScoreType, + actionLevel: number, + ) { + // Appelle recursif sur les enfants pour commencer par le bas de l'arbre + referentielActionAvecScore.actions_enfant.forEach((actionEnfant) => { + this.redistribuePotentielActionsDesactiveesNonConcernees( + actionEnfant, + actionLevel, + ); + }); + + if (!referentielActionAvecScore.score.concerne) { + // WARNING: on ne peut pas encore le mettre à 0 car on doit redistribuer les points + //referentielActionAvecScore.score.point_potentiel = 0; + } else { + // On ne redistribue que pour les enfants de type sous-actions et taches + // Autrement dit, que pour un parent au moins de type action + if (referentielActionAvecScore.level >= actionLevel) { + // On ne redistribue qu'aux actions concernées et qui n'ont pas un potentiel à 0' + const enfantsConcernes: ReferentielActionAvecScoreType[] = []; + referentielActionAvecScore.actions_enfant.forEach((enfant) => { + if (enfant.score.concerne) { + if (enfant.score.point_potentiel) { + enfantsConcernes.push(enfant); + } else { + } + } + }); + + if (enfantsConcernes.length) { + const pointsARedistribuer = + referentielActionAvecScore.actions_enfant.reduce((acc, enfant) => { + if (!enfant.score.concerne) { + const actionPointARedistribuer = + enfant.score.point_potentiel || 0; + return acc + actionPointARedistribuer; + } + return acc; + }, 0); + + const pointsParEnfant = pointsARedistribuer / enfantsConcernes.length; + /*this.logger.log( + `Points à redistribuer pour les ${enfantsConcernes.length} enfants actifs (sur ${referentielActionAvecScore.actions_enfant.length}) de l'action ${referentielActionAvecScore.action_id}: ${pointsParEnfant}`, + );*/ + enfantsConcernes.forEach((enfant) => { + if (_.isNil(enfant.score.point_potentiel)) { + this.logger.warn( + `Potentiel non renseigné pour ${enfant.action_id}, ne devrait pas être le cas à cette étape`, + ); + enfant.score.point_potentiel = + enfant.score.point_referentiel || 0; + } + const nouveauPotentiel = + enfant.score.point_potentiel + pointsParEnfant; + const redistributionFactor = + nouveauPotentiel / enfant.score.point_potentiel; + this.appliqueRedistributionPotentiel(enfant, redistributionFactor); + }); + } else { + // TODO: que doit-on faire ? + } + } + + // On met à jour le potentiel du parent + if (referentielActionAvecScore.actions_enfant.length) { + const potentielParent = + referentielActionAvecScore.actions_enfant.reduce( + (acc, enfant) => + acc + + (enfant.score.concerne ? enfant.score.point_potentiel || 0 : 0), + 0, + ); + referentielActionAvecScore.score.point_potentiel = potentielParent; + } + } + } + + appliqueRedistributionPotentiel( + referentielActionAvecScore: ReferentielActionAvecScoreType, + redistributionFactor: number, + ) { + referentielActionAvecScore.score.point_potentiel = + referentielActionAvecScore.score.point_potentiel! * redistributionFactor; + referentielActionAvecScore.actions_enfant.forEach((actionEnfant) => { + this.appliqueRedistributionPotentiel(actionEnfant, redistributionFactor); + }); + } + + appliqueActionAvancementEtRemonteAuxParents( + referentielActionAvecScore: ReferentielActionAvecScoreType, + actionStatuts: GetActionStatutsResponseType, + ) { + referentielActionAvecScore.actions_enfant.forEach((actionEnfant) => { + this.appliqueActionAvancementEtRemonteAuxParents( + actionEnfant, + actionStatuts, + ); + }); + + // voir fonction update_action_scores_from_status + if (!referentielActionAvecScore.score.concerne) { + referentielActionAvecScore.score.point_fait = 0; + referentielActionAvecScore.score.point_pas_fait = 0; + referentielActionAvecScore.score.point_programme = 0; + referentielActionAvecScore.score.point_potentiel = 0; + referentielActionAvecScore.score.point_non_renseigne = 0; + referentielActionAvecScore.score.completed_taches_count = + referentielActionAvecScore.score.total_taches_count; + referentielActionAvecScore.score.fait_taches_avancement = 0; + referentielActionAvecScore.score.programme_taches_avancement = 0; + referentielActionAvecScore.score.pas_fait_taches_avancement = 0; + referentielActionAvecScore.score.pas_concerne_taches_avancement = + referentielActionAvecScore.score.total_taches_count; + referentielActionAvecScore.score.renseigne = true; + /* todo: + point_potentiel_perso=tache_points_personnalise + if is_personnalise and not is_desactive + else None, + */ + } else { + const actionStatut = actionStatuts[referentielActionAvecScore.action_id!]; + if (actionStatut && actionStatut.avancement_detaille?.length === 3) { + const pointsPotentiel = + referentielActionAvecScore.score.point_potentiel || + referentielActionAvecScore.score.point_referentiel || + 0; + const pourcentageFait = actionStatut.avancement_detaille[0]; + const pourcentageProgramme = actionStatut.avancement_detaille[1]; + const pourcentagePasFait = actionStatut.avancement_detaille[2]; + referentielActionAvecScore.score.point_fait = + pourcentageFait * pointsPotentiel; + referentielActionAvecScore.score.point_pas_fait = + pourcentagePasFait * pointsPotentiel; + referentielActionAvecScore.score.point_programme = + pourcentageProgramme * pointsPotentiel; + referentielActionAvecScore.score.point_non_renseigne = 0; + referentielActionAvecScore.score.completed_taches_count = + referentielActionAvecScore.score.total_taches_count; + referentielActionAvecScore.score.fait_taches_avancement = + pourcentageFait * referentielActionAvecScore.score.total_taches_count; + referentielActionAvecScore.score.programme_taches_avancement = + pourcentageProgramme * + referentielActionAvecScore.score.total_taches_count; + referentielActionAvecScore.score.pas_fait_taches_avancement = + pourcentagePasFait * + referentielActionAvecScore.score.total_taches_count; + referentielActionAvecScore.score.pas_concerne_taches_avancement = 0; + referentielActionAvecScore.score.renseigne = true; + + // Il s'agit d'une tache sans statut, tous les points sont non renseignés + } else if (!referentielActionAvecScore.actions_enfant?.length) { + referentielActionAvecScore.score.point_fait = 0; + referentielActionAvecScore.score.point_pas_fait = 0; + referentielActionAvecScore.score.point_programme = 0; + referentielActionAvecScore.score.point_non_renseigne = + referentielActionAvecScore.score.point_potentiel; + referentielActionAvecScore.score.completed_taches_count = 0; + referentielActionAvecScore.score.fait_taches_avancement = 0; + referentielActionAvecScore.score.programme_taches_avancement = 0; + referentielActionAvecScore.score.pas_fait_taches_avancement = 0; + referentielActionAvecScore.score.pas_concerne_taches_avancement = 0; + referentielActionAvecScore.score.renseigne = false; + } else { + this.mergeScoresEnfants( + referentielActionAvecScore.score, + referentielActionAvecScore.actions_enfant.map( + (enfant) => enfant.score, + ), + ); + } + } + } + + mergeScoresEnfants( + scoreParent: ActionScoreType, + scoreEnfants: ActionScoreType[], + ) { + // Les autres propriétés ont déjà été calculées + scoreParent.point_pas_fait = scoreEnfants.reduce( + (acc, enfant) => acc + (enfant.point_pas_fait || 0), + 0, + ); + scoreParent.point_fait = scoreEnfants.reduce( + (acc, enfant) => acc + (enfant.point_fait || 0), + 0, + ); + scoreParent.point_programme = scoreEnfants.reduce( + (acc, enfant) => acc + (enfant.point_programme || 0), + 0, + ); + scoreParent.point_non_renseigne = scoreEnfants.reduce( + (acc, enfant) => acc + (enfant.point_non_renseigne || 0), + 0, + ); + scoreParent.completed_taches_count = scoreEnfants.reduce( + (acc, enfant) => acc + (enfant.completed_taches_count || 0), + 0, + ); + scoreParent.fait_taches_avancement = scoreEnfants.reduce( + (acc, enfant) => acc + (enfant.fait_taches_avancement || 0), + 0, + ); + scoreParent.programme_taches_avancement = scoreEnfants.reduce( + (acc, enfant) => acc + (enfant.programme_taches_avancement || 0), + 0, + ); + scoreParent.pas_fait_taches_avancement = scoreEnfants.reduce( + (acc, enfant) => acc + (enfant.pas_fait_taches_avancement || 0), + 0, + ); + scoreParent.pas_concerne_taches_avancement = scoreEnfants.reduce( + (acc, enfant) => acc + (enfant.pas_concerne_taches_avancement || 0), + 0, + ); + if (scoreParent.concerne && scoreParent.point_non_renseigne > 0) { + scoreParent.renseigne = false; + } + } + + appliquePersonnalisationScore( + referentielActionAvecScore: ReferentielActionAvecScoreType, + personnalisationConsequences: GetPersonnalitionConsequencesResponseType, + scoreMap: { [key: string]: number }, + overridenScoreFactor?: number, + ) { + const actionPersonnalisationConsequences = + personnalisationConsequences[referentielActionAvecScore.action_id!]; + // Si il y a un potentiel perso on l'applique et on le propagera aux enfants + if ( + !_.isNil(actionPersonnalisationConsequences?.score_formule) && + referentielActionAvecScore.score.point_potentiel // if point_potentiel equals 0., no worthy reduction + ) { + const originalScore = scoreMap[referentielActionAvecScore.action_id!]; + const overridenScore = + this.expressionParserService.parseAndEvaluateExpression( + actionPersonnalisationConsequences.score_formule, + null, + null, + scoreMap, + ) as number; + + if (!_.isNil(overridenScore) && originalScore > 0) { + overridenScoreFactor = overridenScore / originalScore; + } + } + + if (!_.isNil(overridenScoreFactor)) { + referentielActionAvecScore.score.point_fait = + (referentielActionAvecScore.score.point_fait || 0) * + overridenScoreFactor; + } + + referentielActionAvecScore.actions_enfant.forEach((actionEnfant) => { + this.appliquePersonnalisationScore( + actionEnfant, + personnalisationConsequences, + scoreMap, + overridenScoreFactor, + ); + }); + + // Maintenant qu'on a appliqué aux enfants, on reactualise les points des parents + if (referentielActionAvecScore.actions_enfant.length) { + referentielActionAvecScore.score.point_fait = + referentielActionAvecScore.actions_enfant.reduce( + (acc, enfant) => acc + (enfant.score.point_fait || 0), + 0, + ); + } + } + + appliqueRounding( + referentielActionAvecScore: ReferentielActionAvecScoreType, + ndigits: number = 3, + ) { + referentielActionAvecScore.actions_enfant.forEach((actionEnfant) => { + this.appliqueRounding(actionEnfant, ndigits); + }); + + referentielActionAvecScore.score.point_potentiel = roundTo( + referentielActionAvecScore.score.point_potentiel, + ndigits, + ); + referentielActionAvecScore.score.point_fait = roundTo( + referentielActionAvecScore.score.point_fait, + ndigits, + ); + referentielActionAvecScore.score.point_programme = roundTo( + referentielActionAvecScore.score.point_programme, + ndigits, + ); + referentielActionAvecScore.score.point_non_renseigne = roundTo( + referentielActionAvecScore.score.point_non_renseigne, + ndigits, + ); + referentielActionAvecScore.score.point_pas_fait = roundTo( + referentielActionAvecScore.score.point_pas_fait, + ndigits, + ); + referentielActionAvecScore.score.point_referentiel = roundTo( + referentielActionAvecScore.score.point_referentiel, + ndigits, + ); + if (referentielActionAvecScore.score.point_potentiel_perso) { + referentielActionAvecScore.score.point_potentiel_perso = roundTo( + referentielActionAvecScore.score.point_potentiel_perso, + ndigits, + ); + } + } + + fillAvancementDetailleFromAvancement( + actionStatut: Pick, + ) { + if (actionStatut.avancement === 'fait') { + actionStatut.avancement_detaille = [1, 0, 0]; + } else if (actionStatut.avancement === 'programme') { + actionStatut.avancement_detaille = [0, 1, 0]; + } else if (actionStatut.avancement === 'pas_fait') { + actionStatut.avancement_detaille = [0, 0, 1]; + } else if (!actionStatut.avancement_detaille) { + actionStatut.avancement_detaille = [0, 0, 0]; + } + } + + + async getReferentielActionStatuts( + referentielId: ReferentielType, + collectiviteId: number, + date?: string, + tokenInfo?: SupabaseJwtPayload, + noCheck?: boolean, + ): Promise { + const getActionStatuts: GetActionStatutsResponseType = {}; + + this.logger.log( + `Getting collectivite ${collectiviteId} action statuts for referentiel ${referentielId} and date ${date}`, + ); + + if( !noCheck) { + await this.checkCollectiviteAndReferentielWithAccess(collectiviteId, referentielId, date, tokenInfo); + } + + const table = date ? historiqueActionStatutTable : actionStatutTable; + + const actionStatutsConditions: (SQLWrapper | SQL)[] = [ + eq(table.collectivite_id, collectiviteId), + like(table.action_id, `${referentielId}%`), + ]; + if (date) { + actionStatutsConditions.push(lte(table.modified_at, date)); + } + // TODO: colonne referentiel dans les actionStatutTable ? + const referentielActionStatuts = await this.databaseService.db + .select() + .from(table) + .where(and(...actionStatutsConditions)) + .orderBy(asc(table.action_id), desc(table.modified_at)); + this.logger.log( + `${referentielActionStatuts.length} statuts trouvees pour le referentiel ${referentielId} et la collectivite ${collectiviteId}`, + ); + referentielActionStatuts.forEach((actionStatut) => { + if (!getActionStatuts[actionStatut.action_id]) { + getActionStatuts[actionStatut.action_id] = actionStatut; + this.fillAvancementDetailleFromAvancement(actionStatut); + } else { + // On ne garde que le dernier statut, déjà pris en compte par l'orderBy + } + }); + + return getActionStatuts; + } + + async computeScoreForCollectivite( + referentielId: ReferentielType, + collectiviteId: number, + date?: string, + tokenInfo?: SupabaseJwtPayload, + noCheck?: boolean, + ): Promise { + this.logger.log( + `Calcul du score de la collectivité ${collectiviteId} pour le referentiel ${referentielId} à la date ${date}`, + ); + + let collectiviteInfo: undefined | CollectiviteAvecType; + if (!noCheck) { + collectiviteInfo = await this.checkCollectiviteAndReferentielWithAccess(collectiviteId, referentielId, date, tokenInfo); + } + + const referentiel = await this.referentielsService.getReferentiel( + referentielId, + true, + ); + + const personnalisationConsequences = + await this.personnalisationService.getPersonnalisationConsequencesForCollectivite( + collectiviteId, + { + date, + referentiel: referentielId as ReferentielType, + }, + undefined, // already checked + collectiviteInfo + ); + + const actionStatuts = await this.getReferentielActionStatuts( + referentielId, + collectiviteId, + date, + ); + + const actionLevel = referentiel.ordered_item_types.indexOf( + ActionType.ACTION, + ); + if (actionLevel === -1) { + throw new HttpException( + `Action type ${ActionType.ACTION} not found for referentiel ${referentielId}`, + 500, + ); + } + return this.computeScore( + referentiel.items_tree!, + personnalisationConsequences, + actionStatuts, + actionLevel, + ); + } + + fillScoreMap( + score: ReferentielActionAvecScoreType, + scoreMap: GetActionScoresResponseType, + ) { + scoreMap[score.action_id!] = score.score; + score.actions_enfant.forEach((actionEnfant) => { + this.fillScoreMap(actionEnfant, scoreMap); + }); + return scoreMap; + } + + fillScorePercentageMap( + score: ReferentielActionAvecScoreType, + scorePercentageMap: { [actionId: string]: number }, + ) { + scorePercentageMap[score.action_id!] = score.score.point_potentiel + ? (score.score.point_fait || 0) / score.score.point_potentiel + : 0; + score.actions_enfant.forEach((actionEnfant) => { + this.fillScorePercentageMap(actionEnfant, scorePercentageMap); + }); + return scorePercentageMap; + } + + computeScoreMap( + referentiel: ReferentielActionType, + personnalisationConsequences: GetPersonnalitionConsequencesResponseType, + actionStatuts: GetActionStatutsResponseType, + actionLevel: number, + ): GetActionScoresResponseType { + const score = this.computeScore( + referentiel, + personnalisationConsequences, + actionStatuts, + actionLevel, + ); + + const getActionScores: GetActionScoresResponseType = {}; + this.fillScoreMap(score, getActionScores); + return getActionScores; + } + + computeScore( + referentiel: ReferentielActionType, + personnalisationConsequences: GetPersonnalitionConsequencesResponseType, + actionStatuts: GetActionStatutsResponseType, + actionLevel: number, + ): ReferentielActionAvecScoreType { + + const actionStatutsKeys = Object.keys(actionStatuts); + for (const actionStatutKey of actionStatutsKeys) { + const actionStatut = actionStatuts[actionStatutKey]; + // force le remplissage de l'avancement détaillé si il n'est pas renseigné + this.fillAvancementDetailleFromAvancement(actionStatut); + } + + const referentielAvecScore = this.buildReferentielAvecScore(referentiel); + + const scoreMap: GetActionScoresResponseType = {}; + this.fillScoreMap(referentielAvecScore, scoreMap); + + // On applique recursivement le facteur de potentiel perso + this.appliquePersonnalisationPotentielPerso( + referentielAvecScore, + personnalisationConsequences, + ); + + // On applique recursivement la desactivation liée à la personnalisation + // la desactivation mais également le flag concerné à false + this.appliquePersonnalisationDesactivation( + referentielAvecScore, + personnalisationConsequences, + ); + + this.fillScoreMap(referentielAvecScore, scoreMap); + + // On désactive les actions non concernées + // on remonte aux parents pour les rendre non concernés si tous les enfants sont non concernés + this.appliqueActionStatutNonConcerneEtRemonteAuxParents( + referentielAvecScore, + actionStatuts, + ); + + // On redistribue les points liés aux actions désactivées et non concernées aux action frères/soeurs + this.redistribuePotentielActionsDesactiveesNonConcernees( + referentielAvecScore, + actionLevel, + ); + + // On prend en compte les avancements des actions + this.appliqueActionAvancementEtRemonteAuxParents( + referentielAvecScore, + actionStatuts, + ); + + // personalisation scores + const scorePercentages = this.fillScorePercentageMap( + referentielAvecScore, + {}, + ); + this.appliquePersonnalisationScore( + referentielAvecScore, + personnalisationConsequences, + scorePercentages, + ); + + this.appliqueRounding(referentielAvecScore); + + return referentielAvecScore; + } + + async getClientScoresForCollectivite( + referentielId: ReferentielType, + collectiviteId: number, + ): Promise<{ + date: string; + scoresMap: GetActionScoresResponseType + }> { + this.logger.log( + `Récupération des scores de la collectivité ${collectiviteId} pour le referentiel ${referentielId}`, + ); + + const getActionScoresResponse: GetActionScoresResponseType = {}; + + const scores = await this.databaseService.db + .select() + .from(clientScoresTable) + .where( + and(eq(clientScoresTable.referentiel, referentielId), + eq(clientScoresTable.collectiviteId, collectiviteId) + ) + ) + if (!scores.length) { + throw new NotFoundException( + `No scores found for referentiel ${referentielId} and collectivite ${collectiviteId}` + ); + } + + if (!scores[0].payloadTimestamp || !scores[0].scores) { + throw new HttpException(`Invalid scores for referentiel ${referentielId} and collectivite ${collectiviteId}`, 500); + } + + const scoreList = scores[0].scores as ActionScoreType[]; + scoreList.forEach((score) => { + getActionScoresResponse[score.action_id] = score; + }); + + return { + date: scores[0].payloadTimestamp.toISOString(), + scoresMap: getActionScoresResponse + } + } + + async checkScoreForCollectivite( + referentielId: ReferentielType, + collectiviteId: number, + ): Promise { + this.logger.log( + `Vérification du score de la collectivité ${collectiviteId} pour le referentiel ${referentielId}`, + ); + + const savedScoreResult = await this.getClientScoresForCollectivite(referentielId, collectiviteId); + + const scores = await this.computeScoreForCollectivite(referentielId, collectiviteId, savedScoreResult.date); + const scoreMap = this.fillScoreMap(scores, {}); + const getReferentielScores: GetCheckScoresResponseType = { + date: savedScoreResult.date, + differences: {}, + }; + const actionIds = Object.keys(scoreMap); + actionIds.forEach((actionId) => { + const savedScore = savedScoreResult.scoresMap[actionId]; + if (!_.isEqual(savedScore, scoreMap[actionId])) { + const savedScoreDiff: any = {}; + let scoreMapDiff: any = {}; + + const scoreMapKeys = [...new Set(Object.keys(scoreMap[actionId]).concat(Object.keys(savedScore || {}))).values()]; + let hasDiff = false; + if (savedScore) { + for (const key of scoreMapKeys) { + // We ignore renseigne (weird value in python) and point_potentiel_perso for now + if (key !== 'renseigne' && key !== 'point_potentiel_perso') { + // @ts-ignore + if (!_.isEqual(savedScore[key],scoreMap[actionId][key])) { + hasDiff = true; + // @ts-ignore + savedScoreDiff[key] = savedScore[key]; + // @ts-ignore + scoreMapDiff[key] = scoreMap[actionId][key]; + } + } + } + } else { + scoreMapDiff = scoreMap[actionId]; + } + + if (hasDiff) { + getReferentielScores.differences[actionId] = { + sauvegarde: savedScoreDiff, + calcule: scoreMapDiff, + }; + } + } + }); + return getReferentielScores; + } +} diff --git a/backend/src/referentiels/services/referentiels.service.spec.ts b/backend/src/referentiels/services/referentiels.service.spec.ts new file mode 100644 index 0000000000..f4cca87034 --- /dev/null +++ b/backend/src/referentiels/services/referentiels.service.spec.ts @@ -0,0 +1,156 @@ +import { Test } from '@nestjs/testing'; +import DatabaseService from '../../common/services/database.service'; +import { ActionDefinitionAvecParentType } from '../models/action-definition.table'; +import { ActionType } from '../models/action-type.enum'; +import ReferentielsService from './referentiels.service'; + +describe('ReferentielsService', () => { + let referentielsService: ReferentielsService; + + beforeEach(async () => { + const moduleRef = await Test.createTestingModule({ + providers: [ReferentielsService], + }) + .useMocker((token) => { + if (token === DatabaseService) { + return {}; + } + }) + .compile(); + + referentielsService = moduleRef.get(ReferentielsService); + }); + + describe('buildReferentielTree', () => { + it('une tache réglementaire', async () => { + const actionDefinitions: ActionDefinitionAvecParentType[] = [ + { + action_id: 'eci', + parent_action_id: null, + }, + { + action_id: 'eci_1', + parent_action_id: 'eci', + points: 30, + }, + { + action_id: 'eci_1.0', + parent_action_id: 'eci_1', + pourcentage: 0, + }, + { + action_id: 'eci_1.1', + parent_action_id: 'eci_1', + }, + { + action_id: 'eci_1.2', + parent_action_id: 'eci_1', + }, + { + action_id: 'eci_2', + parent_action_id: 'eci', + points: 70, + }, + { + action_id: 'eci_2.1', + parent_action_id: 'eci_2', + pourcentage: 20, + }, + { + action_id: 'eci_2.2', + parent_action_id: 'eci_2', + pourcentage: 30, + }, + { + action_id: 'eci_2.3', + parent_action_id: 'eci_2', + pourcentage: 50, + }, + ]; + const orderedActionTypes: ActionType[] = [ + ActionType.REFERENTIEL, + ActionType.ACTION, + ActionType.SOUS_ACTION, + ActionType.TACHE, + ]; + const referentielTree = referentielsService.buildReferentielTree( + actionDefinitions, + orderedActionTypes + ); + expect(referentielTree).toEqual({ + action_id: 'eci', + points: 100, + level: 0, + action_type: ActionType.REFERENTIEL, + actions_enfant: [ + { + action_id: 'eci_1', + points: 30, + pourcentage: 30, + level: 1, + action_type: ActionType.ACTION, + actions_enfant: [ + { + action_id: 'eci_1.0', + points: 0, + pourcentage: 0, + level: 2, + action_type: ActionType.SOUS_ACTION, + actions_enfant: [], + }, + { + action_id: 'eci_1.1', + points: 15, + pourcentage: 50, + level: 2, + action_type: ActionType.SOUS_ACTION, + actions_enfant: [], + }, + { + action_id: 'eci_1.2', + points: 15, + pourcentage: 50, + level: 2, + action_type: ActionType.SOUS_ACTION, + actions_enfant: [], + }, + ], + }, + { + action_id: 'eci_2', + points: 70, + pourcentage: 70, + level: 1, + action_type: ActionType.ACTION, + actions_enfant: [ + { + action_id: 'eci_2.1', + points: 14, + pourcentage: 20, + level: 2, + action_type: ActionType.SOUS_ACTION, + actions_enfant: [], + }, + { + action_id: 'eci_2.2', + points: 21, + pourcentage: 30, + level: 2, + action_type: ActionType.SOUS_ACTION, + actions_enfant: [], + }, + { + action_id: 'eci_2.3', + points: 35, + pourcentage: 50, + level: 2, + action_type: ActionType.SOUS_ACTION, + actions_enfant: [], + }, + ], + }, + ], + }); + }); + }); +}); diff --git a/backend/src/referentiels/services/referentiels.service.ts b/backend/src/referentiels/services/referentiels.service.ts new file mode 100644 index 0000000000..0ce5f8d2b3 --- /dev/null +++ b/backend/src/referentiels/services/referentiels.service.ts @@ -0,0 +1,230 @@ +import { + HttpException, + HttpStatus, + Injectable, + Logger, + NotFoundException, +} from '@nestjs/common'; +import { asc, eq, getTableColumns } from 'drizzle-orm'; +import * as _ from 'lodash'; +import DatabaseService from '../../common/services/database.service'; +import { + ActionDefinitionAvecParentType, + actionDefinitionTable, +} from '../models/action-definition.table'; +import { actionRelationTable } from '../models/action-relation.table'; +import { ActionType } from '../models/action-type.enum'; +import { GetReferentielResponseType } from '../models/get-referentiel.response'; +import { ReferentielActionType } from '../models/referentiel-action.dto'; +import { referentielList, ReferentielType } from '../models/referentiel.enum'; + +@Injectable() +export default class ReferentielsService { + private readonly logger = new Logger(ReferentielsService.name); + + constructor(private readonly databaseService: DatabaseService) {} + + buildReferentielTree( + actionDefinitions: ActionDefinitionAvecParentType[], + orderedActionTypes: ActionType[] + ): ReferentielActionType { + const rootAction = actionDefinitions.find( + (action) => !action.parent_action_id + ); + if (!rootAction) { + throw new NotFoundException(`Referentiel not found`); + } + const { parent_action_id, ...rootActionSansParent } = rootAction; + const referentiel: ReferentielActionType = { + ...rootActionSansParent, + level: 0, + action_type: orderedActionTypes[0], + actions_enfant: [], + }; + this.attacheActionsEnfant( + referentiel, + actionDefinitions, + orderedActionTypes, + referentiel.level + ); + + return referentiel; + } + + attacheActionsEnfant( + referentiel: ReferentielActionType, + actionDefinitions: ActionDefinitionAvecParentType[], + orderActionTypes: ActionType[], + currentLevel: number + ): void { + const actionsEnfant = actionDefinitions.filter( + (action) => action.parent_action_id === referentiel.action_id + ); + + if (actionsEnfant.length) { + const levelEnfant = currentLevel + 1; + if (levelEnfant >= orderActionTypes.length) { + throw new HttpException( + `Action level ${levelEnfant} non consistent with referentiel action types: ${orderActionTypes.join( + ',' + )}`, + HttpStatus.INTERNAL_SERVER_ERROR + ); + } + const actionTypeEnfant = orderActionTypes[levelEnfant]; + + const equiPercentage = actionsEnfant.every( + (action) => !action.pourcentage && _.isNil(action.points) + ); + if (equiPercentage) { + // Enlève les actions réglementaires avec un pourcentage à 0 + const enfantSansPourcentage = actionsEnfant.filter((action) => + _.isNil(action.pourcentage) + ); + actionsEnfant.forEach((action) => { + if (_.isNil(action.pourcentage)) { + action.pourcentage = 100 / enfantSansPourcentage.length; + } + }); + } else { + // + const hasPourcentage = actionsEnfant.some( + (action) => action.pourcentage + ); + if (hasPourcentage) { + const totalPourcentage = actionsEnfant.reduce( + (acc, action) => acc + (action.pourcentage || 0), + 0 + ); + if (totalPourcentage !== 100) { + throw new HttpException( + `Total pourcentage des actions enfant de ${referentiel.action_id} doit être égal à 100`, + HttpStatus.INTERNAL_SERVER_ERROR + ); + } + } + } + + actionsEnfant.forEach((actionEnfant) => { + const { parent_action_id, ...actionEnfantSansParent } = actionEnfant; + const actionEnfantDansReferentiel: ReferentielActionType = { + ...actionEnfantSansParent, + actions_enfant: [], + level: levelEnfant, + action_type: actionTypeEnfant, + }; + if ( + _.isNil(actionEnfantDansReferentiel.points) && + !_.isNil(actionEnfantDansReferentiel.pourcentage) && + !_.isNil(referentiel.points) + ) { + actionEnfantDansReferentiel.points = + (referentiel.points * actionEnfantDansReferentiel.pourcentage) / + 100; + if (actionEnfantDansReferentiel.action_id === 'cae_3.1.2.3.1') { + this.logger.log( + `Calcul du score de ${actionEnfantDansReferentiel.action_id} : ${referentiel.points} * ${actionEnfantDansReferentiel.pourcentage} / 100 = ${actionEnfantDansReferentiel.points}` + ); + } + } + referentiel.actions_enfant.push(actionEnfantDansReferentiel); + this.attacheActionsEnfant( + actionEnfantDansReferentiel, + actionDefinitions, + orderActionTypes, + levelEnfant + ); + }); + + // Maintenant que la recursion est terminée, on recalcule le score du parent + if (referentiel.actions_enfant.length > 0) { + if (_.isNil(referentiel.points)) { + // Only if not already computed + + referentiel.points = referentiel.actions_enfant.reduce( + (acc, action) => acc + (action.points || 0), + 0 + ); + } + referentiel.actions_enfant.forEach((action) => { + if (action.points && referentiel.points) { + action.pourcentage = (action.points / referentiel.points) * 100; + } + }); + } + } + } + + async checkReferentielExists(referentielId: ReferentielType): Promise { + if (!referentielList.includes(referentielId)) { + throw new NotFoundException(`Referentiel ${referentielId} not found`); + } + } + + async getReferentiel( + referentielId: ReferentielType, + uniquementPourScoring?: boolean + ): Promise { + this.logger.log( + `Recherche des actions pour le referentiel ${referentielId}` + ); + + await this.checkReferentielExists(referentielId); + + const colonnes = uniquementPourScoring + ? { + action_id: actionDefinitionTable.action_id, + nom: actionDefinitionTable.nom, + points: actionDefinitionTable.points, + pourcentage: actionDefinitionTable.pourcentage, + } + : getTableColumns(actionDefinitionTable); + const actionDefinitions = await this.databaseService.db + .select({ + ...colonnes, + parent_action_id: actionRelationTable.parent, + }) + .from(actionDefinitionTable) + .leftJoin( + actionRelationTable, + eq(actionDefinitionTable.action_id, actionRelationTable.id) + ) + .where( + eq(actionDefinitionTable.referentiel, referentielId as ReferentielType) // TODO: à enlever lorsque ce sera une table plutot qu'un enum + ) + .orderBy(asc(actionDefinitionTable.action_id)); + this.logger.log( + `${actionDefinitions.length} actions trouvees pour le referentiel ${referentielId}` + ); + + // TODO: get it from referentiel table + let orderedActionTypes: ActionType[] = [ + ActionType.REFERENTIEL, + ActionType.AXE, + ActionType.SOUS_AXE, + ActionType.ACTION, + ActionType.SOUS_ACTION, + ActionType.TACHE, + ]; + if (referentielId === 'eci') { + // Pas de sous axes pour l'ECI + orderedActionTypes = [ + ActionType.REFERENTIEL, + ActionType.AXE, + ActionType.ACTION, + ActionType.SOUS_ACTION, + ActionType.TACHE, + ]; + } + + const actionsTree = this.buildReferentielTree( + actionDefinitions, + orderedActionTypes + ); + + return { + items_tree: actionsTree, + ordered_item_types: orderedActionTypes, + }; + } +} diff --git a/backend/test/auth/auth-utils.ts b/backend/test/auth/auth-utils.ts new file mode 100644 index 0000000000..9ed0aa8dba --- /dev/null +++ b/backend/test/auth/auth-utils.ts @@ -0,0 +1,17 @@ +import { createClient, SupabaseClient } from '@supabase/supabase-js'; +import { YOLO_DODO_CREDENTIALS } from './test-users.samples'; +let supabase: SupabaseClient; + +export const getYoloDodoToken = async (): Promise => { + if (!supabase) { + supabase = createClient( + process.env.SUPABASE_URL!, + process.env.SUPABASE_ANON_KEY! + ); + } + const signinResponse = await supabase.auth.signInWithPassword( + YOLO_DODO_CREDENTIALS + ); + const yoloDodoToken = signinResponse.data.session?.access_token || ''; + return yoloDodoToken; +}; diff --git a/backend/test/common/app-utils.ts b/backend/test/common/app-utils.ts new file mode 100644 index 0000000000..3601a32aeb --- /dev/null +++ b/backend/test/common/app-utils.ts @@ -0,0 +1,15 @@ +import { ZodValidationPipe } from '@anatine/zod-nestjs/src/lib/zod-validation-pipe'; +import { INestApplication } from '@nestjs/common'; +import { Test } from '@nestjs/testing'; +import { AppModule } from '../../src/app.module'; + +export const getTestApp = async (): Promise => { + const moduleRef = await Test.createTestingModule({ + imports: [AppModule], + }).compile(); + + const app = moduleRef.createNestApplication(); + app.useGlobalPipes(new ZodValidationPipe()); + await app.init(); + return app; +}; diff --git a/backend/test/personnalisations/personnalisations.e2e-spec.ts b/backend/test/personnalisations/personnalisations.e2e-spec.ts new file mode 100644 index 0000000000..ef0d7f4a70 --- /dev/null +++ b/backend/test/personnalisations/personnalisations.e2e-spec.ts @@ -0,0 +1,124 @@ +import { INestApplication } from '@nestjs/common'; +import { default as request } from 'supertest'; +import { GetPersonnalitionConsequencesResponseType } from '../../src/personnalisations/models/get-personnalisation-consequences.response'; +import { GetPersonnalisationReglesResponseType } from '../../src/personnalisations/models/get-personnalisation-regles.response'; +import { getYoloDodoToken } from '../auth/auth-utils'; +import { getTestApp } from '../common/app-utils'; + +describe('Personnalisations routes', () => { + let app: INestApplication; + let yoloDodoToken: string; + + beforeAll(async () => { + app = await getTestApp(); + yoloDodoToken = await getYoloDodoToken(); + }); + + it(`Récupération publique des règles`, async () => { + const response = await request(app.getHttpServer()) + .get('/personnalisations/regles') + .expect(200); + expect( + (response.body as GetPersonnalisationReglesResponseType).regles.length + ).toBeGreaterThan(0); + }); + + it(`Récupération publique des règles avec filtre sur le référentiel`, async () => { + const response = await request(app.getHttpServer()) + .get('/personnalisations/regles?referentiel=cae') + .expect(200); + const getPersonnalisationregles = + response.body as GetPersonnalisationReglesResponseType; + const caeRegles = getPersonnalisationregles.regles.filter((regle) => + regle.action_id.startsWith('cae') + ); + expect(getPersonnalisationregles.regles.length).toBe(caeRegles.length); + }); + + it(`Récupération publique des règles avec référentiel invalide`, async () => { + const response = await request(app.getHttpServer()) + .get('/personnalisations/regles?referentiel=invalid') + .expect(400); + expect( + response.body.message[0].startsWith('referentiel: Invalid enum value.') + ).toBe(true); + }); + + it(`Récupération des réponses courantes d'une collectivité sans token`, async () => { + const response = await request(app.getHttpServer()) + .get('/collectivites/1/personnalisations/reponses') + .expect(401); + }); + + it(`Récupération des réponses courantes d'une collectivité avec token anonyme`, async () => { + const response = await request(app.getHttpServer()) + .get('/collectivites/1/personnalisations/reponses') + .set('Authorization', `Bearer ${process.env.SUPABASE_ANON_KEY}`) + .expect(200) + .expect({ EP_1: 'EP_1_b', dechets_1: true, habitat_2: 0.8 }); + }); + + it(`Récupération des réponses historiques d'une collectivité avec token anonyme`, async () => { + const response = await request(app.getHttpServer()) + .get( + '/collectivites/1/personnalisations/reponses?date=2020-01-02T00:00:00Z' + ) + .set('Authorization', `Bearer ${process.env.SUPABASE_ANON_KEY}`) + .expect(401); + }); + + it(`Récupération des réponses historiques d'une collectivité avec date invalide`, async () => { + const response = await request(app.getHttpServer()) + .get('/collectivites/1/personnalisations/reponses?date=2020-01-02T00:') + .set('Authorization', `Bearer ${process.env.SUPABASE_ANON_KEY}`) + .expect(400) + .expect({ + message: ['date: Invalid datetime'], + error: 'Bad Request', + statusCode: 400, + }); + }); + + it(`Récupération des réponses historiques d'une collectivité avec utilisateur autorisé`, async () => { + const response = await request(app.getHttpServer()) + .get( + '/collectivites/1/personnalisations/reponses?date=2020-01-02T00:00:00Z' + ) + .set('Authorization', `Bearer ${yoloDodoToken}`) + .expect(200) + .expect({ EP_1: 'EP_1_a', dechets_1: false, habitat_2: 0.7 }); + }); + + it(`Récupération des conséquences de personnalisation d'une collectivité sans token`, async () => { + const response = await request(app.getHttpServer()) + .get('/collectivites/1/personnalisations/consequences') + .expect(401); + }); + + it(`Récupération des conséquences de personnalisation d'une collectivité avec utilisateur autorisé`, async () => { + const response = await request(app.getHttpServer()) + .get( + '/collectivites/1/personnalisations/consequences?date=2020-01-02T00:00:00Z' + ) + .set('Authorization', `Bearer ${yoloDodoToken}`) + .expect(200); + const getPersonnalisationConsequences: GetPersonnalitionConsequencesResponseType = + response.body; + + // Do not check the whole response, just a few values + expect(getPersonnalisationConsequences['eci_3.7.1']).toEqual({ + desactive: null, + score_formule: null, + potentiel_perso: 3, + }); + expect(getPersonnalisationConsequences['eci_4.2.1']).toEqual({ + desactive: true, + score_formule: null, + potentiel_perso: null, + }); + }); + + afterAll(async () => { + await app.close(); + }); +}); diff --git a/backend/test/referentiels/referentiels-scoring.e2e-spec.ts b/backend/test/referentiels/referentiels-scoring.e2e-spec.ts new file mode 100644 index 0000000000..70f976bc6c --- /dev/null +++ b/backend/test/referentiels/referentiels-scoring.e2e-spec.ts @@ -0,0 +1,218 @@ +import { INestApplication } from '@nestjs/common'; +import { default as request } from 'supertest'; +import { GetActionStatutsResponseType } from '../../src/referentiels/models/get-action-statuts.response'; +import { GetReferentielScoresResponseType } from '../../src/referentiels/models/get-referentiel-scores.response'; +import { getYoloDodoToken } from '../auth/auth-utils'; +import { getTestApp } from '../common/app-utils'; + +describe('Referentiels scoring routes', () => { + let app: INestApplication; + let yoloDodoToken: string; + + beforeAll(async () => { + app = await getTestApp(); + yoloDodoToken = await getYoloDodoToken(); + }); + + it(`Récupération des statuts des actions sans token non autorisée`, async () => { + const response = await request(app.getHttpServer()) + .get('/collectivites/1/referentiels/cae/action-statuts') + .expect(401); + }); + + it(`Récupération anonyme des statuts des actions`, async () => { + const response = await request(app.getHttpServer()) + .get('/collectivites/1/referentiels/cae/action-statuts') + .set('Authorization', `Bearer ${process.env.SUPABASE_ANON_KEY}`) + .expect(200); + const actionStatuts = response.body as GetActionStatutsResponseType; + expect(Object.keys(actionStatuts).length).toBe(2); + expect(actionStatuts['cae_1.1.1.1.1']).toEqual({ + collectivite_id: 1, + action_id: 'cae_1.1.1.1.1', + avancement: 'fait', + avancement_detaille: [1, 0, 0], + concerne: true, + modified_by: '17440546-f389-4d4f-bfdb-b0c94a1bd0f9', + modified_at: '2020-01-01 00:00:01+00', + }); + }); + + it(`Récupération anonyme des statuts des actions pour une collectivite inconnue`, async () => { + const response = await request(app.getHttpServer()) + .get('/collectivites/10000000/referentiels/cae/action-statuts') + .set('Authorization', `Bearer ${process.env.SUPABASE_ANON_KEY}`) + .expect(404) + .expect({ + message: + "Commune avec l'identifiant de collectivite 10000000 introuvable", + error: 'Not Found', + statusCode: 404, + }); + }); + + it(`Récupération anonyme des statuts des actions d'un référentiel inconnu`, async () => { + const response = await request(app.getHttpServer()) + .get('/collectivites/1/referentiels/inconnu/action-statuts') + .set('Authorization', `Bearer ${process.env.SUPABASE_ANON_KEY}`) + .expect(404) + .expect({ + message: 'Referentiel inconnu not found', + error: 'Not Found', + statusCode: 404, + }); + }); + + it(`Récupération anonyme des historiques de statuts des actions non autorisé`, async () => { + const response = await request(app.getHttpServer()) + .get( + '/collectivites/1/referentiels/cae/action-statuts?date=2020-01-02T00:00:01Z' + ) + .set('Authorization', `Bearer ${process.env.SUPABASE_ANON_KEY}`) + .expect(401); + }); + + it(`Récupération des historiques de statuts des actions pour un utilisateur autorisé`, async () => { + const response = await request(app.getHttpServer()) + .get( + '/collectivites/1/referentiels/cae/action-statuts?date=2020-01-02T00:00:01Z' + ) + .set('Authorization', `Bearer ${yoloDodoToken}`) + .expect(200); + const actionStatuts = response.body as GetActionStatutsResponseType; + expect(Object.keys(actionStatuts).length).toBe(1); + expect(actionStatuts['cae_1.1.1.1.1']).toEqual({ + collectivite_id: 1, + action_id: 'cae_1.1.1.1.1', + avancement: 'fait', + avancement_detaille: [1, 0, 0], + concerne: true, + modified_at: '2020-01-01 00:00:01+00', + modified_by: null, + previous_avancement: null, + previous_avancement_detaille: null, + previous_concerne: null, + previous_modified_at: null, + previous_modified_by: null, + }); + }); + + it(`Récupération du score d'un référentiel sans token non autorisée`, async () => { + const response = await request(app.getHttpServer()) + .get('/collectivites/1/referentiels/cae/scores') + .expect(401); + }); + + it(`Récupération anonyme du score d'un référentiel`, async () => { + const response = await request(app.getHttpServer()) + .get('/collectivites/1/referentiels/cae/scores') + .set('Authorization', `Bearer ${process.env.SUPABASE_ANON_KEY}`) + .expect(200); + const referentielScores = response.body as GetReferentielScoresResponseType; + const { actions_enfant, ...referentielScoreWithoutActionsEnfant } = + referentielScores.scores; + expect(actions_enfant.length).toBe(6); + expect(referentielScoreWithoutActionsEnfant).toEqual({ + action_id: 'cae', + nom: 'Climat Air Énergie', + points: 500, + pourcentage: null, + level: 0, + action_type: 'referentiel', + score: { + action_id: 'cae', + point_referentiel: 500, + point_potentiel: 490.9, + point_potentiel_perso: null, + point_fait: 0.36, + point_pas_fait: 0.03, + point_non_renseigne: 490.3, + point_programme: 0.21, + concerne: true, + completed_taches_count: 2, + total_taches_count: 1120, + fait_taches_avancement: 1.2, + programme_taches_avancement: 0.7, + pas_fait_taches_avancement: 0.1, + pas_concerne_taches_avancement: 0, + desactive: false, + renseigne: false, + }, + }); + }); + + it(`Récupération anonyme du score d'un référentiel pour une collectivite inconnue`, async () => { + const response = await request(app.getHttpServer()) + .get('/collectivites/10000000/referentiels/cae/scores') + .set('Authorization', `Bearer ${process.env.SUPABASE_ANON_KEY}`) + .expect(404) + .expect({ + message: + "Commune avec l'identifiant de collectivite 10000000 introuvable", + error: 'Not Found', + statusCode: 404, + }); + }); + + it(`Récupération anonyme du score d'un référentiel inconnu`, async () => { + const response = await request(app.getHttpServer()) + .get('/collectivites/1/referentiels/inconnu/scores') + .set('Authorization', `Bearer ${process.env.SUPABASE_ANON_KEY}`) + .expect(404) + .expect({ + message: 'Referentiel inconnu not found', + error: 'Not Found', + statusCode: 404, + }); + }); + + it(`Récupération anonyme de l'historique du score d'un référentiel non autorisée`, async () => { + const response = await request(app.getHttpServer()) + .get('/collectivites/1/referentiels/cae/scores?date=2019-01-01T00:00:01Z') + .set('Authorization', `Bearer ${process.env.SUPABASE_ANON_KEY}`) + .expect(401); + }); + + it(`Récupération de l'historique du score d'un référentiel pour un utilisateur autorisé`, async () => { + const response = await request(app.getHttpServer()) + .get('/collectivites/1/referentiels/cae/scores?date=2019-01-01T00:00:01Z') + .set('Authorization', `Bearer ${yoloDodoToken}`) + .expect(200); + const referentielScores = response.body as GetReferentielScoresResponseType; + const { actions_enfant, ...referentielScoreWithoutActionsEnfant } = + referentielScores.scores; + expect(referentielScores.date).toBe('2019-01-01T00:00:01Z'); + expect(actions_enfant.length).toBe(6); + expect(referentielScoreWithoutActionsEnfant).toEqual({ + action_id: 'cae', + nom: 'Climat Air Énergie', + points: 500, + pourcentage: null, + level: 0, + action_type: 'referentiel', + score: { + action_id: 'cae', + point_referentiel: 500, + point_potentiel: 496.5, + point_potentiel_perso: null, + point_fait: 0, + point_pas_fait: 0, + point_non_renseigne: 496.5, + point_programme: 0, + concerne: true, + completed_taches_count: 0, + total_taches_count: 1120, + fait_taches_avancement: 0, + programme_taches_avancement: 0, + pas_fait_taches_avancement: 0, + pas_concerne_taches_avancement: 0, + desactive: false, + renseigne: false, + }, + }); + }); + + afterAll(async () => { + await app.close(); + }); +}); diff --git a/backend/test/referentiels/referentiels.e2e-spec.ts b/backend/test/referentiels/referentiels.e2e-spec.ts new file mode 100644 index 0000000000..94266ff169 --- /dev/null +++ b/backend/test/referentiels/referentiels.e2e-spec.ts @@ -0,0 +1,44 @@ +import { INestApplication } from '@nestjs/common'; +import { default as request } from 'supertest'; +import { ReferentielActionType } from '../../src/referentiels/models/referentiel-action.dto'; +import { getTestApp } from '../common/app-utils'; + +describe('Referentiels routes', () => { + let app: INestApplication; + + beforeAll(async () => { + app = await getTestApp(); + }); + + it(`Récupération publique du référentiel`, async () => { + const response = await request(app.getHttpServer()) + .get('/referentiels/cae') + .expect(200); + const referentiel = response.body as ReferentielActionType; + const { actions_enfant, ...referentielWithoutActionsEnfant } = referentiel; + expect(actions_enfant.length).toBe(6); + expect(referentielWithoutActionsEnfant).toEqual({ + action_id: 'cae', + action_type: 'referentiel', + level: 0, + nom: 'Climat Air Énergie', + points: 500, + pourcentage: null, + }); + }); + + it(`Référentiel inconnu`, async () => { + const response = await request(app.getHttpServer()) + .get('/referentiels/inconnu') + .expect(404) + .expect({ + message: 'Referentiel inconnu not found', + error: 'Not Found', + statusCode: 404, + }); + }); + + afterAll(async () => { + await app.close(); + }); +}); diff --git a/business/tests/e2e/test_evaluation_scenarios.py b/business/tests/e2e/test_evaluation_scenarios.py index b2cbaff846..f1607a5fb4 100644 --- a/business/tests/e2e/test_evaluation_scenarios.py +++ b/business/tests/e2e/test_evaluation_scenarios.py @@ -1,11 +1,11 @@ from business.utils.models.action_score import ActionScore -from business.utils.models.action_statut import ( - ActionStatut, - DetailedAvancement, -) +from business.utils.models.action_statut import (ActionStatut, + DetailedAvancement) from business.utils.models.actions import ActionId -from business.utils.models.personnalisation import ActionPersonnalisationConsequence +from business.utils.models.personnalisation import \ + ActionPersonnalisationConsequence from business.utils.models.reponse import Reponse + from .fixtures import * commune_id = 1 @@ -88,6 +88,7 @@ def test_cae_321_when_recuperation_cogeneration_is_NON( == scores_cae["cae_3.2.1"].point_potentiel_perso == 2.0 ) + assert scores_cae["cae_3.2.1.1.1"].point_potentiel == 0.25 assert scores_cae["cae_3.2.1.1"].point_potentiel == 2.0 assert scores_cae["cae_3.2.1.2"].point_potentiel == 0 assert scores_cae["cae_3.2.1.3"].point_potentiel == 0 @@ -145,6 +146,7 @@ def test_cae_631_when_cae_6314_if_dev_eco_4_is_NON( == scores_cae["cae_6.3.1.2"].point_referentiel ) + # cae_6.3.1.3 and cae_6.3.1.5 have been augmented of 1 point each assert ( scores_cae["cae_6.3.1.3"].point_potentiel @@ -209,12 +211,20 @@ def test_cae_641_when_localosation_dom_and_SAU_OUI( scores_cae["cae_6.4.1.6"].point_potentiel == scores_cae["cae_6.4.1"].point_potentiel * 20 / 100 ) + assert ( + scores_cae["cae_6.4.1.6"].point_potentiel + == 1.2 + ) # 6.4.1.8 passe de 15% à 10% assert ( scores_cae["cae_6.4.1.8"].point_potentiel == scores_cae["cae_6.4.1"].point_potentiel * 10 / 100 ) + assert ( + scores_cae["cae_6.4.1.8"].point_potentiel + == 0.6 + ) def test_cae_621_when_type_commune(test_post_personnalize, test_post_evaluate): @@ -254,8 +264,8 @@ def test_cae_621_when_type_commune(test_post_personnalize, test_post_evaluate): # Cas 3 : Si une commune est à 10 % de l'EPCI et qu'elle ne participe pas au conseil d'administration d'un bailleur social, elle est notée sur 2 points # ------ - # si identite(type, commune) et reponse(habitat_3, OUI) et reponse(habitat_2, 10%) - # - cae 6.2.1 est réduite à 2 points et on lui ajoute 1 point, donc a un potentiel de 3 points + # si identite(type, commune) et reponse(habitat_3, NON) et reponse(habitat_2, 10%) + # - cae 6.2.1 est réduite à 2 points et on ne lui rajoute pas de points, donc a un potentiel de 2 points reponses = [Reponse("habitat_3", "NON"), Reponse("habitat_2", 0.1)] consequences = test_post_personnalize( reponses, diff --git a/business/tests/unit/evaluation/test_compute_referentiel_scores_for_collectivite.py b/business/tests/unit/evaluation/test_compute_referentiel_scores_for_collectivite.py index 8ea3e2f887..e64a9655b0 100644 --- a/business/tests/unit/evaluation/test_compute_referentiel_scores_for_collectivite.py +++ b/business/tests/unit/evaluation/test_compute_referentiel_scores_for_collectivite.py @@ -1,23 +1,17 @@ import math + import pytest +from tests.utils.referentiel_factory import (make_action_children, + make_action_points) +from business.evaluation.evaluation.action_point_tree import ActionPointTree +from business.evaluation.evaluation.compute_scores import compute_scores from business.utils.models.action_score import ActionScore -from business.utils.models.action_statut import ( - ActionStatut, - DetailedAvancement, -) -from business.evaluation.evaluation.action_point_tree import ( - ActionPointTree, -) -from business.evaluation.evaluation.compute_scores import ( - compute_scores, -) +from business.utils.models.action_statut import (ActionStatut, + DetailedAvancement) from business.utils.models.actions import ActionId -from business.utils.models.personnalisation import ActionPersonnalisationConsequence -from tests.utils.referentiel_factory import ( - make_action_children, - make_action_points, -) +from business.utils.models.personnalisation import \ + ActionPersonnalisationConsequence @pytest.fixture @@ -1231,3 +1225,8 @@ def test_notation_when_potentiel_perso_formule_is_given(simple_point_tree_refere / actual_scores[ActionId("eci_2")].point_potentiel, rel_tol=3 ) + + assert actual_scores[ActionId("eci_1")].point_fait == 2.143 + assert actual_scores[ActionId("eci_1.1")].point_fait == 0.714 + assert actual_scores[ActionId("eci_1.2")].point_fait == 1.429 + assert actual_scores[ActionId("eci")].point_fait == 7.143 \ No newline at end of file diff --git a/business/tests/unit/personnalisation/test_execute_personnalisation_regles.py b/business/tests/unit/personnalisation/test_execute_personnalisation_regles.py index a9c6deec95..7b83e62220 100644 --- a/business/tests/unit/personnalisation/test_execute_personnalisation_regles.py +++ b/business/tests/unit/personnalisation/test_execute_personnalisation_regles.py @@ -1,15 +1,10 @@ -from business.utils.models.identite import IdentiteCollectivite -from business.utils.models.reponse import Reponse -from business.evaluation.personnalisation.regles_parser import ReglesParser from business.evaluation.personnalisation.execute_personnalisation_regles import ( - execute_personnalisation_regles, - ActionPersonnalisationConsequence, -) -from business.utils.models.regles import ( - ActionRegles, - Regle, -) + ActionPersonnalisationConsequence, execute_personnalisation_regles) +from business.evaluation.personnalisation.regles_parser import ReglesParser from business.utils.models.actions import ActionId +from business.utils.models.identite import IdentiteCollectivite +from business.utils.models.regles import ActionRegles, Regle +from business.utils.models.reponse import Reponse def test_execute_personnalisation_regles_when_all_reponses_are_given(): @@ -124,3 +119,28 @@ def test_execute_personnalisation_regles_with_reduction_depends_on_score(): score_formule="min(score(cae_1.2.3), 0.16666666666666666)", ) } + +def test_execute_personnalisation_regles_without_answer(): + regles_parser = ReglesParser( + [ + ActionRegles( + ActionId("cae_6.3.1"), + [ + Regle( + "si identite(type, commune) alors max (reponse(dev_eco_2), 2/8) \n", + "reduction", + ), + ], + ) + ] + ) + reponses = [Reponse("dev_eco_4", "NON")] + identite = IdentiteCollectivite(type={"commune"}) + + assert execute_personnalisation_regles(regles_parser, reponses, identite) == { + ActionId("cae_6.3.1"): ActionPersonnalisationConsequence( + desactive=None, + potentiel_perso=None, + score_formule=None, + ) + } diff --git a/data_layer/seed/fakes/13-insert_fake_statut_and_score.sql b/data_layer/seed/fakes/13-insert_fake_statut_and_score.sql index 8663b2041d..b2bfe37d7d 100644 --- a/data_layer/seed/fakes/13-insert_fake_statut_and_score.sql +++ b/data_layer/seed/fakes/13-insert_fake_statut_and_score.sql @@ -3,8 +3,8 @@ -- - 11-insert_fake_epcis.sql -- - 10-insert_fake_user.sql insert into - action_statut(collectivite_id, action_id, avancement, concerne, modified_by) - values (1, 'cae_1.1.1.1.1', 'fait', true, '17440546-f389-4d4f-bfdb-b0c94a1bd0f9'); + action_statut(collectivite_id, action_id, avancement, concerne, modified_by, modified_at) + values (1, 'cae_1.1.1.1.1', 'fait', true, '17440546-f389-4d4f-bfdb-b0c94a1bd0f9', '2020-01-01 00:00:01'); insert into action_statut(collectivite_id, action_id, avancement, avancement_detaille, concerne, modified_by) diff --git a/data_layer/seed/fakes/15-insert_fake_indicateurs.sql b/data_layer/seed/fakes/15-insert_fake_indicateurs.sql index 360d679011..8a0855fd67 100644 --- a/data_layer/seed/fakes/15-insert_fake_indicateurs.sql +++ b/data_layer/seed/fakes/15-insert_fake_indicateurs.sql @@ -37,6 +37,11 @@ INSERT INTO public.indicateur_source (id, libelle) VALUES ('rare', 'RARE-OREC'); INSERT INTO public.indicateur_source_metadonnee (id, source_id, date_version, nom_donnees, diffuseur, producteur, methodologie, limites) VALUES (2, 'rare', '2024-07-18T00:00:00.000Z', '', 'OREC', '', 'Scope 1&2 (approche cadastrale)', ''); +-- Insertion de la source snbc +INSERT INTO public.indicateur_source (id, libelle) VALUES ('snbc', 'SNBC'); +INSERT INTO public.indicateur_source_metadonnee (id, source_id, date_version, nom_donnees, diffuseur, producteur, methodologie, limites) +VALUES (3, 'snbc', '2024-07-11T00:00:00.000Z', 'SNBC', 'ADEME', 'ADEME', '', ''); + -- Insertion pour le calcul de la trajectoire snbc. Cas du pays du Laon insert into public.indicateur_valeur (indicateur_id, collectivite_id, date_valeur, metadonnee_id, resultat, resultat_commentaire, objectif, objectif_commentaire) diff --git a/data_layer/seed/fakes/20-insert-fake-reponse.sql b/data_layer/seed/fakes/20-insert-fake-reponse.sql index 7d309abf45..382c1fe47b 100644 --- a/data_layer/seed/fakes/20-insert-fake-reponse.sql +++ b/data_layer/seed/fakes/20-insert-fake-reponse.sql @@ -1,11 +1,23 @@ -- Repone binaire -insert into reponse_binaire(collectivite_id, question_id, reponse) -values (1, 'dechets_1', true); +insert into reponse_binaire(collectivite_id, question_id, reponse, modified_at) +values (1, 'dechets_1', false, '2020-01-01 00:00:00'); +insert into reponse_binaire(collectivite_id, question_id, reponse, modified_at) +values (1, 'dechets_1', true, '2020-01-01 00:00:01') on conflict (collectivite_id, question_id) do update +set reponse = excluded.reponse, + modified_at = excluded.modified_at; -- Reponse proportion -insert into reponse_proportion(collectivite_id, question_id, reponse) -values (1, 'habitat_2', 0.8); +insert into reponse_proportion(collectivite_id, question_id, reponse, modified_at) +values (1, 'habitat_2', 0.7, '2020-01-01 00:00:00'); +insert into reponse_proportion(collectivite_id, question_id, reponse, modified_at) +values (1, 'habitat_2', 0.8, '2020-01-01 00:00:01') on conflict (collectivite_id, question_id) do update +set reponse = excluded.reponse, + modified_at = excluded.modified_at; -- Reponse choix -insert into reponse_choix(collectivite_id, question_id, reponse) -values (1, 'EP_1', 'EP_1_b'); \ No newline at end of file +insert into reponse_choix(collectivite_id, question_id, reponse, modified_at) +values (1, 'EP_1', 'EP_1_a', '2020-01-01 00:00:00'); +insert into reponse_choix(collectivite_id, question_id, reponse, modified_at) +values (1, 'EP_1', 'EP_1_b', '2020-01-01 00:00:01') on conflict (collectivite_id, question_id) do update +set reponse = excluded.reponse, + modified_at = excluded.modified_at; \ No newline at end of file diff --git a/package.json b/package.json index 3a8c36e8ff..5d0c0bda81 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "archiver": "^7.0.1", "async-retry": "^1.3.3", "axios": "^1.6.0", + "chevrotain": "^10.5.0", "classnames": "^2.3.1", "date-fns": "^2.16.1", "dompurify": "^2.4.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 40893ecafa..f330f9db24 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -137,6 +137,9 @@ importers: axios: specifier: ^1.6.0 version: 1.7.7 + chevrotain: + specifier: ^10.5.0 + version: 10.5.0 classnames: specifier: ^2.3.1 version: 2.5.1 @@ -1352,6 +1355,18 @@ packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@chevrotain/cst-dts-gen@10.5.0': + resolution: {integrity: sha512-lhmC/FyqQ2o7pGK4Om+hzuDrm9rhFYIJ/AXoQBeongmn870Xeb0L6oGEiuR8nohFNL5sMaQEJWCxr1oIVIVXrw==} + + '@chevrotain/gast@10.5.0': + resolution: {integrity: sha512-pXdMJ9XeDAbgOWKuD1Fldz4ieCs6+nLNmyVhe2gZVqoO7v8HXuHYs5OV2EzUtbuai37TlOAQHrTDvxMnvMJz3A==} + + '@chevrotain/types@10.5.0': + resolution: {integrity: sha512-f1MAia0x/pAVPWH/T73BJVyO2XU5tI4/iE7cnxb7tqdNTNhQI3Uq3XkqcoteTmD4t1aM0LbHCJOhgIDn07kl2A==} + + '@chevrotain/utils@10.5.0': + resolution: {integrity: sha512-hBzuU5+JjB2cqNZyszkDHZgOSrUUT8V3dhgRl8Q9Gp6dAj/H5+KILGjbhDpc3Iy9qmqlm/akuOI2ut9VUtzJxQ==} + '@colors/colors@1.5.0': resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} @@ -5590,6 +5605,9 @@ packages: check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + chevrotain@10.5.0: + resolution: {integrity: sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A==} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -10362,6 +10380,9 @@ packages: regenerator-transform@0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} + regexp-to-ast@0.5.0: + resolution: {integrity: sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==} + regexp.prototype.flags@1.5.2: resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} engines: {node: '>= 0.4'} @@ -13126,6 +13147,21 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} + '@chevrotain/cst-dts-gen@10.5.0': + dependencies: + '@chevrotain/gast': 10.5.0 + '@chevrotain/types': 10.5.0 + lodash: 4.17.21 + + '@chevrotain/gast@10.5.0': + dependencies: + '@chevrotain/types': 10.5.0 + lodash: 4.17.21 + + '@chevrotain/types@10.5.0': {} + + '@chevrotain/utils@10.5.0': {} + '@colors/colors@1.5.0': optional: true @@ -19349,6 +19385,15 @@ snapshots: dependencies: get-func-name: 2.0.2 + chevrotain@10.5.0: + dependencies: + '@chevrotain/cst-dts-gen': 10.5.0 + '@chevrotain/gast': 10.5.0 + '@chevrotain/types': 10.5.0 + '@chevrotain/utils': 10.5.0 + lodash: 4.17.21 + regexp-to-ast: 0.5.0 + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -25398,6 +25443,8 @@ snapshots: dependencies: '@babel/runtime': 7.25.6 + regexp-to-ast@0.5.0: {} + regexp.prototype.flags@1.5.2: dependencies: call-bind: 1.0.7