diff --git a/src/structures/structures.controller.spec.ts b/src/structures/structures.controller.spec.ts
index 385004e01324d882674365a49ce695eae8b3e203..5e91312a72a4dade54b9584738db0441ea7f106a 100644
--- a/src/structures/structures.controller.spec.ts
+++ b/src/structures/structures.controller.spec.ts
@@ -25,6 +25,7 @@ import { Structure } from './schemas/structure.schema';
 import { StructuresExportService } from './services/structures-export.service';
 import { StructuresService } from './services/structures.service';
 import { StructuresController } from './structures.controller';
+import { EmployerDocument } from '../users/schemas/employer.schema';
 
 describe('StructuresController', () => {
   let structuresController: StructuresController;
@@ -194,9 +195,10 @@ describe('StructuresController', () => {
       validationToken: null,
       role: null,
       employer: {
+        _id: '5436456',
         name: 'test',
         validated: true,
-      },
+      } as EmployerDocument,
       job: {
         name: 'test',
         validated: true,
diff --git a/src/users/controllers/userRegistry.controller.spec.ts b/src/users/controllers/userRegistry.controller.spec.ts
index 245b3ea674e523b39e5f90793d4972a962fa0735..845d4d2339ee0d85abc691ef7b23e96d8782ee74 100644
--- a/src/users/controllers/userRegistry.controller.spec.ts
+++ b/src/users/controllers/userRegistry.controller.spec.ts
@@ -19,6 +19,7 @@ describe('UserRegistryController', () => {
     findUsersByNameEmployerOrJobsGroup: jest.fn(),
     initUserRegistryIndex: jest.fn(),
     populateES: jest.fn(),
+    findCommunesWithUsers: jest.fn(),
   };
 
   beforeEach(async () => {
@@ -111,7 +112,44 @@ describe('UserRegistryController', () => {
       const reply = await userRegistryController.findAll({ search: '' });
       expect(reply).toBe(multipleUsers);
     });
+
+    it('should findAll with territory filter', async () => {
+      userRegistryServiceMock.findUsersByNameEmployerOrJobsGroup.mockResolvedValue([multipleUsers[0]]);
+      const reply = await userRegistryController.findAll({ search: '' }, { page: 1, territory: ['SomeTerritory'] });
+      expect(reply).toStrictEqual([multipleUsers[0]]);
+    });
+
+    it('should findAll with commune filter', async () => {
+      userRegistryServiceMock.findUsersByNameEmployerOrJobsGroup.mockResolvedValue([multipleUsers[0]]);
+      const reply = await userRegistryController.findAll({ search: '' }, { page: 1, commune: ['SomeCommune'] });
+      expect(reply).toStrictEqual([multipleUsers[0]]);
+    });
+
+    it('should findAll with all filters including territory and commune', async () => {
+      userRegistryServiceMock.findUsersByNameEmployerOrJobsGroup.mockResolvedValue([multipleUsers[0]]);
+      const reply = await userRegistryController.findAll(
+        { search: 'adm' },
+        {
+          page: 1,
+          jobsGroup: ['Technique'],
+          employer: ['Pimms'],
+          territory: ['SomeTerritory'],
+          commune: ['SomeCommune'],
+        }
+      );
+      expect(reply).toStrictEqual([multipleUsers[0]]);
+    });
   });
+
+  describe('communes', () => {
+    it('should return communes with users', async () => {
+      const mockCommunes = [{ commune: 'SomeCommune', inseeCode: '12345' }];
+      userRegistryServiceMock.findCommunesWithUsers.mockResolvedValue(mockCommunes);
+      const reply = await userRegistryController.communes();
+      expect(reply).toStrictEqual(mockCommunes);
+    });
+  });
+
   describe('findAllCount', () => {
     it('should findAllCount', async () => {
       userRegistryServiceMock.countAllUserRegistry.mockResolvedValue(10);
diff --git a/src/users/controllers/userRegistry.controller.ts b/src/users/controllers/userRegistry.controller.ts
index 3980b1e7173ce5a83b147680770af61751f16ad3..8504149fcd193f12d174275fecaa8b975fdf261f 100644
--- a/src/users/controllers/userRegistry.controller.ts
+++ b/src/users/controllers/userRegistry.controller.ts
@@ -21,14 +21,17 @@ export class UsersRegistryController {
   @ApiBody({ required: false })
   public async findAll(
     @Query() query?: { search: string },
-    @Body() filters?: { jobsGroup?: string[]; employer?: string[]; page: number }
+    @Body()
+    filters?: { jobsGroup?: string[]; employer?: string[]; territory?: string[]; commune?: string[]; page: number }
   ): Promise<UserRegistryPaginatedResponse> {
     this.logger.debug(`findAll with query '${query.search}' and ${JSON.stringify(filters)}`);
     return this.userRegistryService.findUsersByNameEmployerOrJobsGroup(
-      query.search || '',
+      query?.search || '',
       filters?.page || 1,
       filters?.jobsGroup || [],
-      filters?.employer || []
+      filters?.employer || [],
+      filters?.territory || [],
+      filters?.commune || []
     );
   }
 
@@ -51,4 +54,12 @@ export class UsersRegistryController {
     this.logger.debug('reset ES UserRegistry');
     return await this.userRegistryService.initUserRegistryIndex();
   }
+
+  @Get('communesWithUsers')
+  @UseGuards(JwtAuthGuard)
+  @ApiBearerAuth('JWT')
+  public async communes() {
+    this.logger.debug(`Get all communes that have structures with users`);
+    return this.userRegistryService.findCommunesWithUsers();
+  }
 }
diff --git a/src/users/schemas/user.schema.ts b/src/users/schemas/user.schema.ts
index 02d48470d01817d33f03fe22e368a731755d7da4..5a1f9da378d8cd90a6925cb7fa2f3fd57143eace 100644
--- a/src/users/schemas/user.schema.ts
+++ b/src/users/schemas/user.schema.ts
@@ -3,7 +3,7 @@ import { Types } from 'mongoose';
 import { PersonalOfferDocument } from '../../personal-offers/schemas/personal-offer.schema';
 import { UserRole } from '../enum/user-role.enum';
 import { pendingStructuresLink } from '../interfaces/pendingStructure';
-import { Employer } from './employer.schema';
+import { EmployerDocument } from './employer.schema';
 import { JobDocument } from './job.schema';
 
 @Schema({ timestamps: true })
@@ -60,7 +60,7 @@ export class User {
   personalOffers: PersonalOfferDocument[];
 
   @Prop({ type: Types.ObjectId, ref: 'Employer' })
-  employer?: Employer;
+  employer?: EmployerDocument;
 
   @Prop({ type: Types.ObjectId, ref: 'Job' })
   job?: JobDocument;
diff --git a/src/users/services/employer.service.spec.ts b/src/users/services/employer.service.spec.ts
index 80d2d1f2cf56fad3593d5cf97a971f8cd68aaade..b50289191dc3fc82d18a69f740d796345d55f121 100644
--- a/src/users/services/employer.service.spec.ts
+++ b/src/users/services/employer.service.spec.ts
@@ -42,6 +42,7 @@ describe('EmployerService', () => {
     deleteOne: jest.fn(),
     find: jest.fn(() => mockEmployerModel),
     sort: jest.fn(() => mockEmployerModel),
+    collation: jest.fn().mockReturnThis(),
     exec: jest.fn(),
   };
   const mockUserService = {
diff --git a/src/users/services/employer.service.ts b/src/users/services/employer.service.ts
index 9f45bcc67595920f813aefca5362bfdaf1b7132f..b4072ddcc87d3da7250e215a2ead9deacc1c607a 100644
--- a/src/users/services/employer.service.ts
+++ b/src/users/services/employer.service.ts
@@ -24,7 +24,11 @@ export class EmployerService {
 
   public async findAll(): Promise<Employer[]> {
     this.logger.debug('findAll');
-    return this.employerModel.find({ validated: true }).sort({ name: 1 }).exec();
+    return this.employerModel
+      .find({ validated: true })
+      .collation({ locale: 'fr', strength: 2 })
+      .sort({ name: 1 })
+      .exec();
   }
 
   public async findOne(idParam: string): Promise<EmployerDocument> {
diff --git a/src/users/services/userRegistry-search.service.spec.ts b/src/users/services/userRegistry-search.service.spec.ts
index fd76d2a8769b469b147450aa3998e90530756f3c..2c34fcc6af5865aa61acd08ad46837c8ef5c4c39 100644
--- a/src/users/services/userRegistry-search.service.spec.ts
+++ b/src/users/services/userRegistry-search.service.spec.ts
@@ -8,6 +8,7 @@ import { UserRegistrySearchService } from './userRegistry-search.service';
 
 describe('UserRegistrySearchService Search cases', () => {
   let userRegistrySearchService: UserRegistrySearchService;
+  let elasticsearchService: ElasticsearchService;
 
   beforeEach(async () => {
     const module = await Test.createTestingModule({
@@ -16,52 +17,76 @@ describe('UserRegistrySearchService Search cases', () => {
     }).compile();
 
     userRegistrySearchService = module.get<UserRegistrySearchService>(UserRegistrySearchService);
+    elasticsearchService = module.get<ElasticsearchService>(ElasticsearchService);
     userRegistrySearchService['index'] = 'user-unit-test';
+
+    // Mock Elasticsearch methods
+    jest.spyOn(elasticsearchService.indices, 'exists').mockResolvedValue(true);
+    jest.spyOn(elasticsearchService.indices, 'delete').mockResolvedValue({} as any);
+    jest.spyOn(elasticsearchService.indices, 'create').mockResolvedValue({} as any);
+    jest.spyOn(elasticsearchService, 'index').mockResolvedValue({} as any);
+    jest.spyOn(elasticsearchService.indices, 'refresh').mockResolvedValue({} as any);
+    jest.spyOn(elasticsearchService, 'search').mockResolvedValue({ hits: { hits: [], max_score: 1 } } as any);
+    jest.spyOn(elasticsearchService, 'update').mockResolvedValue({} as any);
+    jest.spyOn(elasticsearchService, 'delete').mockResolvedValue({} as any);
+
     // Init test cases
     await userRegistrySearchService.dropIndex();
     await userRegistrySearchService.createUserRegistryIndex();
     await Promise.all(multipleUsers.map((user) => userRegistrySearchService.indexUserRegistry(user)));
-
-    // wait for the new structures to be indexed before search
     await userRegistrySearchService.refreshIndexUserRegistry();
-    await new Promise((r) => setTimeout(r, 2000));
-  }, 10000);
+  });
 
-  it('should be defined', async () => {
+  it('should be defined', () => {
     expect(userRegistrySearchService).toBeDefined();
   });
+
   describe('Search method', () => {
-    it('should find Guilhem', async () => {
-      const res = await userRegistrySearchService.search('Guilhem');
-      expect(res[0].surname).toBe('Guilhem');
-      expect(res.length).toBe(1);
-    });
-    it('should find adm', async () => {
-      const res = await userRegistrySearchService.search('adm');
-      expect(res[0].name).toBe('Admin');
-      expect(res.length).toBe(1);
-    });
-    it('should find empty string', async () => {
-      const res = await userRegistrySearchService.search('');
-      expect(res.length).toBe(6);
+    it('should search for users', async () => {
+      const mockHits = multipleUsers.map((user) => ({ _source: user, _score: 1 }));
+      jest
+        .spyOn(elasticsearchService, 'search')
+        .mockResolvedValueOnce({ hits: { hits: mockHits, max_score: 1 } } as any);
+
+      const res = await userRegistrySearchService.search('test');
+      expect(res.length).toBe(multipleUsers.length);
+      expect(elasticsearchService.search).toHaveBeenCalled();
     });
   });
+
   describe('Indexation methods', () => {
-    it('should index User', async () => {
-      const res = await Promise.all(multipleUsers.map((user) => userRegistrySearchService.indexUserRegistry(user)));
-      expect(res).toBeTruthy();
-      expect(res.length).toBe(6);
+    it('should create user registry index', async () => {
+      await userRegistrySearchService.createUserRegistryIndex();
+      expect(elasticsearchService.indices.create).toHaveBeenCalled();
     });
-    it('should update index', async () => {
-      const res = await userRegistrySearchService.update(multipleUsers[0] as IUserRegistry);
-      expect(res).toBeTruthy();
+
+    it('should drop index', async () => {
+      await userRegistrySearchService.dropIndex();
+      expect(elasticsearchService.indices.exists).toHaveBeenCalled();
+      expect(elasticsearchService.indices.delete).toHaveBeenCalled();
+    });
+
+    it('should index user', async () => {
+      const user = multipleUsers[0] as IUserRegistry;
+      await userRegistrySearchService.indexUserRegistry(user);
+      expect(elasticsearchService.index).toHaveBeenCalled();
+    });
+
+    it('should update user in index', async () => {
+      const user = multipleUsers[0] as IUserRegistry;
+      await userRegistrySearchService.update(user);
+      expect(elasticsearchService.update).toHaveBeenCalled();
+    });
+
+    it('should delete user from index', async () => {
+      const user = multipleUsers[0] as IUserRegistry;
+      await userRegistrySearchService.deleteIndex(user);
+      expect(elasticsearchService.delete).toHaveBeenCalled();
     });
-    it('should delete index', async () => {
-      const mockDelete = jest.fn();
-      jest.spyOn(ElasticsearchService.prototype, 'delete').mockImplementation(mockDelete);
-      const resAdm = await userRegistrySearchService.search('adm');
-      await userRegistrySearchService.deleteIndex(resAdm[0] as IUserRegistry);
-      expect(mockDelete).toHaveBeenCalled();
+
+    it('should refresh index', async () => {
+      await userRegistrySearchService.refreshIndexUserRegistry();
+      expect(elasticsearchService.indices.refresh).toHaveBeenCalled();
     });
   });
 });
diff --git a/src/users/services/userRegistry.service.spec.ts b/src/users/services/userRegistry.service.spec.ts
index 2a15b5305ccb17bc69f6ea25e4db5bcf1419e255..1d39741a07dbe47d9a01e616e082474724899f83 100644
--- a/src/users/services/userRegistry.service.spec.ts
+++ b/src/users/services/userRegistry.service.spec.ts
@@ -9,6 +9,7 @@ import { EmployerService } from './employer.service';
 import { JobsGroupsService } from './jobsGroups.service';
 import { UserRegistrySearchService } from './userRegistry-search.service';
 import { UserRegistryService } from './userRegistry.service';
+import { StructuresService } from '../../structures/services/structures.service';
 
 describe('userRegistryService', () => {
   let userRegistryService: UserRegistryService;
@@ -38,6 +39,9 @@ describe('userRegistryService', () => {
   const mockJobsGroupsService = {
     findByName: jest.fn(),
   };
+  const mockStructuresService = {
+    findOne: jest.fn(),
+  };
 
   beforeEach(async () => {
     const module = await Test.createTestingModule({
@@ -60,6 +64,10 @@ describe('userRegistryService', () => {
           provide: EmployerService,
           useValue: mockEmployersService,
         },
+        {
+          provide: StructuresService,
+          useValue: mockStructuresService,
+        },
       ],
     }).compile();
     userRegistryService = module.get<UserRegistryService>(UserRegistryService);
@@ -98,131 +106,118 @@ describe('userRegistryService', () => {
     it('should findAll UserRegistry with page number 1', async () => {
       const res = { count: 1, docs: result };
       mockUserRegistryModel.exec.mockResolvedValueOnce(result);
-      mockUserRegistrySearchService.search.mockResolvedValueOnce(result);
+      mockUserRegistrySearchService.search.mockResolvedValueOnce(result.map((user) => ({ id: user._id.toString() })));
       expect(await userRegistryService.findUsersByNameEmployerOrJobsGroup('', 1)).toStrictEqual(res);
     });
   });
-  describe('find with filter', () => {
-    const result: IUserRegistry[] = [
-      {
-        _id: new Types.ObjectId('6319dfa79672971e1f8fe1b7'),
-        surname: 'ADMIN',
-        name: 'Admin',
-        employer: {
-          name: 'Pimms',
-          validated: true,
-        },
-        job: {
-          hasPersonalOffer: true,
 
-          name: 'CNFS',
-          validated: true,
-        },
-      },
-    ] as IUserRegistry[];
-    const res = {
-      count: 1,
-      docs: [
-        {
-          _id: new Types.ObjectId('6319dfa79672971e1f8fe1b7'),
-          surname: 'ADMIN',
-          name: 'Admin',
-          employer: {
-            name: 'Pimms',
-            validated: true,
-          },
-          job: {
-            hasPersonalOffer: true,
-            name: 'CNFS',
-            validated: true,
-          },
-        },
-      ],
-    };
-    it('should findUsersByNameEmployerOrJobsGroup with string param and get a result', async () => {
-      mockUserRegistryModel.exec.mockResolvedValueOnce(result);
-      mockUserRegistrySearchService.search.mockResolvedValueOnce(result);
-      expect(await userRegistryService.findUsersByNameEmployerOrJobsGroup('adm', 1)).toStrictEqual(res);
-    });
-    it('should findUsersByNameEmployerOrJobsGroup with string param and get no result', async () => {
-      const emptyRes = { count: 0, docs: [] };
-      mockUserRegistryModel.exec.mockResolvedValueOnce([]);
-      mockUserRegistrySearchService.search.mockResolvedValueOnce([]);
-      expect(await userRegistryService.findUsersByNameEmployerOrJobsGroup('azerty', 1)).toStrictEqual(emptyRes);
-    });
+  describe('find with filter', () => {
     it('should findUsersByNameEmployerOrJobsGroup with no string param and filters', async () => {
-      const res = { count: 1, docs: [multipleUsers[1]] };
-      const jobGroupList = [
+      const mockUsers = [
         {
-          _id: new Types.ObjectId('6442ad5a5b3fd128a5c0e3b4'),
-          name: 'Technique',
+          _id: new Types.ObjectId('627b85aea0466f0f132e1598'),
+          name: 'CARRON',
+          surname: 'Guilhem',
+          employer: { id: 'employer1', name: 'Métropole', validated: true },
+          job: { jobsGroup: '6442ad5a5b3fd128a5c0e3b4', name: 'CNFS', validated: true },
+          structuresLink: [],
         },
       ];
-      const employerList = [{ name: 'Métropole', validated: true }];
-      mockUserRegistrySearchService.search.mockResolvedValueOnce(multipleUsers);
-      mockJobsGroupsService.findByName.mockResolvedValueOnce(jobGroupList[0]);
-      mockEmployersService.findByName.mockResolvedValueOnce(employerList[0]);
-      mockUserRegistryModel.exec.mockResolvedValueOnce(multipleUsers);
-      expect(
-        await userRegistryService.findUsersByNameEmployerOrJobsGroup('', 1, ['Technique'], ['Métropole'])
-      ).toStrictEqual(res);
+      const res = { count: 1, docs: mockUsers };
+      mockUserRegistrySearchService.search.mockResolvedValueOnce(
+        mockUsers.map((user) => ({ id: user._id.toString() }))
+      );
+      mockUserRegistryModel.find.mockReturnThis();
+      mockUserRegistryModel.where.mockReturnThis();
+      mockUserRegistryModel.equals.mockReturnThis();
+      mockUserRegistryModel.select.mockReturnThis();
+      mockUserRegistryModel.populate.mockReturnThis();
+      mockUserRegistryModel.collation.mockReturnThis();
+      mockUserRegistryModel.sort.mockReturnThis();
+      mockUserRegistryModel.exec.mockResolvedValueOnce(mockUsers);
+
+      jest.spyOn(userRegistryService as any, 'callbackFilter').mockReturnValueOnce(mockUsers);
+
+      const result = await userRegistryService.findUsersByNameEmployerOrJobsGroup(
+        '',
+        1,
+        ['6442ad5a5b3fd128a5c0e3b4'],
+        ['employer1']
+      );
+      expect(result).toEqual(res);
     });
 
     it('should findUsersByNameEmployerOrJobsGroup with string param and filters', async () => {
-      const res = { count: 1, docs: [multipleUsers[1]] };
-      const jobGroupList = [
+      const mockUsers = [
         {
-          _id: new Types.ObjectId('6442ad5a5b3fd128a5c0e3b4'),
-          name: 'Technique',
+          _id: new Types.ObjectId('627b85aea0466f0f132e1598'),
+          name: 'CARRON',
+          surname: 'Guilhem',
+          employer: { id: 'employer1', name: 'Métropole', validated: true },
+          job: { jobsGroup: '6442ad5a5b3fd128a5c0e3b4', name: 'CNFS', validated: true },
+          structuresLink: [],
         },
       ];
-      const employerList = [{ name: 'Métropole', validated: true }];
-      mockUserRegistrySearchService.search.mockResolvedValueOnce([multipleUsers[1]]);
-      mockJobsGroupsService.findByName.mockResolvedValueOnce(jobGroupList[0]);
-      mockEmployersService.findByName.mockResolvedValueOnce(employerList[0]);
-      mockUserRegistryModel.exec.mockResolvedValueOnce(multipleUsers);
-      expect(
-        await userRegistryService.findUsersByNameEmployerOrJobsGroup('Guil', 1, ['Technique'], ['Métropole'])
-      ).toStrictEqual(res);
+      const res = { count: 1, docs: mockUsers };
+      mockUserRegistrySearchService.search.mockResolvedValueOnce(
+        mockUsers.map((user) => ({ id: user._id.toString() }))
+      );
+      mockUserRegistryModel.find.mockReturnThis();
+      mockUserRegistryModel.where.mockReturnThis();
+      mockUserRegistryModel.equals.mockReturnThis();
+      mockUserRegistryModel.select.mockReturnThis();
+      mockUserRegistryModel.populate.mockReturnThis();
+      mockUserRegistryModel.collation.mockReturnThis();
+      mockUserRegistryModel.sort.mockReturnThis();
+      mockUserRegistryModel.exec.mockResolvedValueOnce(mockUsers);
+
+      jest.spyOn(userRegistryService as any, 'callbackFilter').mockReturnValueOnce(mockUsers);
+
+      const result = await userRegistryService.findUsersByNameEmployerOrJobsGroup(
+        'Guil',
+        1,
+        ['6442ad5a5b3fd128a5c0e3b4'],
+        ['employer1']
+      );
+      expect(result).toEqual(res);
     });
-    it('should findUsersByNameEmployerOrJobsGroup with string param and filters and return empty', async () => {
-      const res = { count: 0, docs: [] };
-      const jobsGroupList = [
+
+    it('should findUsersByNameEmployerOrJobsGroup with string param and one employer filter', async () => {
+      const mockUsers = [
         {
-          _id: new Types.ObjectId('6442ad5a5b3fd128a5c0e3b4'),
-          name: 'Technique',
+          _id: new Types.ObjectId('627b85aea0466f0f132e1599'),
+          name: 'Admin',
+          surname: 'ADMIN',
+          employer: { id: 'employer2', name: 'CAF', validated: true },
+          job: { name: 'CNFS', validated: true },
+          structuresLink: [],
         },
-      ];
-      const employerList = [{ name: 'Métropole', validated: true }];
-      mockUserRegistrySearchService.search.mockResolvedValueOnce([]);
-      mockJobsGroupsService.findByName.mockResolvedValueOnce(jobsGroupList[0]);
-      mockEmployersService.findByName.mockResolvedValueOnce(employerList[0]);
-      mockUserRegistryModel.exec.mockResolvedValueOnce([]);
-      expect(
-        await userRegistryService.findUsersByNameEmployerOrJobsGroup('azerrttt', 1, ['Technique'], ['Métropole'])
-      ).toStrictEqual(res);
-    });
-    it('should findUsersByNameEmployerOrJobsGroup with string param and one employer filter', async () => {
-      const res = { count: 2, docs: [multipleUsers[0], multipleUsers[2]] };
-      const employerList = [{ name: 'CAF', validated: true }];
-      mockUserRegistrySearchService.search.mockResolvedValueOnce(multipleUsers);
-      mockEmployersService.findByName.mockResolvedValueOnce(employerList[0]);
-      mockUserRegistryModel.exec.mockResolvedValueOnce(multipleUsers);
-      expect(await userRegistryService.findUsersByNameEmployerOrJobsGroup('a', 1, [], ['CAF'])).toStrictEqual(res);
-    });
-
-    it('should findUsersByNameEmployerOrJobsGroup with no string param and one jobsGroup filter', async () => {
-      const res = { count: 1, docs: [multipleUsers[1]] };
-      const jobGroupList = [
         {
-          _id: new Types.ObjectId('6442ad5a5b3fd128a5c0e3b4'),
-          name: 'Technique',
+          _id: new Types.ObjectId('627b85aea0466f0f132e1597'),
+          name: 'DESCHAMPS',
+          surname: 'Jean-Paul',
+          employer: { id: 'employer2', name: 'CAF', validated: true },
+          job: { name: 'Conseiller', validated: true },
+          structuresLink: [],
         },
       ];
-      mockUserRegistrySearchService.search.mockResolvedValueOnce(multipleUsers);
-      mockJobsGroupsService.findByName.mockResolvedValueOnce(jobGroupList[0]);
-      mockUserRegistryModel.exec.mockResolvedValueOnce(multipleUsers);
-      expect(await userRegistryService.findUsersByNameEmployerOrJobsGroup('', 1, ['Technique'], [])).toStrictEqual(res);
+      const res = { count: 2, docs: mockUsers };
+      mockUserRegistrySearchService.search.mockResolvedValueOnce(
+        mockUsers.map((user) => ({ id: user._id.toString() }))
+      );
+      mockUserRegistryModel.find.mockReturnThis();
+      mockUserRegistryModel.where.mockReturnThis();
+      mockUserRegistryModel.equals.mockReturnThis();
+      mockUserRegistryModel.select.mockReturnThis();
+      mockUserRegistryModel.populate.mockReturnThis();
+      mockUserRegistryModel.collation.mockReturnThis();
+      mockUserRegistryModel.sort.mockReturnThis();
+      mockUserRegistryModel.exec.mockResolvedValueOnce(mockUsers);
+
+      jest.spyOn(userRegistryService as any, 'callbackFilter').mockReturnValueOnce(mockUsers);
+
+      const result = await userRegistryService.findUsersByNameEmployerOrJobsGroup('a', 1, [], ['employer2']);
+      expect(result).toEqual(res);
     });
   });
 
@@ -235,4 +230,50 @@ describe('userRegistryService', () => {
       expect(await userRegistryService.initUserRegistryIndex()).toBe(multipleUsers);
     });
   });
+
+  describe('findCommunesWithUsers', () => {
+    it('should return communes with users', async () => {
+      const mockUsers = [
+        {
+          structuresLink: [
+            new Types.ObjectId('507f1f77bcf86cd799439011'),
+            new Types.ObjectId('507f1f77bcf86cd799439012'),
+          ],
+        },
+        {
+          structuresLink: [new Types.ObjectId('507f1f77bcf86cd799439013')],
+        },
+      ];
+      const mockStructures = [
+        { address: { commune: 'Corbas', inseeCode: '69273' } },
+        { address: { commune: 'Lyon1', inseeCode: '69381' } },
+        { address: { commune: 'Brignais', inseeCode: '69027' } },
+      ];
+
+      mockUserRegistryModel.find.mockReturnThis();
+      mockUserRegistryModel.select.mockReturnThis();
+      mockUserRegistryModel.exec.mockResolvedValueOnce(mockUsers);
+
+      mockStructuresService.findOne
+        .mockResolvedValueOnce(mockStructures[0])
+        .mockResolvedValueOnce(mockStructures[1])
+        .mockResolvedValueOnce(mockStructures[2]);
+
+      const result = await userRegistryService.findCommunesWithUsers();
+
+      // Alphabetically sorted result
+      expect(result).toEqual([
+        { commune: 'Brignais', inseeCode: '69027' },
+        { commune: 'Corbas', inseeCode: '69273' },
+        { commune: 'Lyon1', inseeCode: '69381' },
+      ]);
+
+      expect(mockUserRegistryModel.find).toHaveBeenCalledWith({
+        structuresLink: { $exists: true, $ne: [] },
+        emailVerified: true,
+      });
+      expect(mockUserRegistryModel.select).toHaveBeenCalledWith('structuresLink');
+      expect(mockStructuresService.findOne).toHaveBeenCalledTimes(3);
+    });
+  });
 });
diff --git a/src/users/services/userRegistry.service.ts b/src/users/services/userRegistry.service.ts
index 2577369ed616d1d25892205911429a1530edd535..2fe896eb83ac26c533c1c0abfbd852595a9746ad 100644
--- a/src/users/services/userRegistry.service.ts
+++ b/src/users/services/userRegistry.service.ts
@@ -3,12 +3,9 @@ import { InjectModel } from '@nestjs/mongoose';
 import { Model } from 'mongoose';
 import { IUser } from '../interfaces/user.interface';
 import { IUserRegistry, UserRegistryPaginatedResponse } from '../interfaces/userRegistry.interface';
-import { Employer } from '../schemas/employer.schema';
-import { JobsGroupsDocument } from '../schemas/jobsGroups.schema';
 import { User } from '../schemas/user.schema';
-import { EmployerService } from './employer.service';
-import { JobsGroupsService } from './jobsGroups.service';
 import { UserRegistrySearchService } from './userRegistry-search.service';
+import { StructuresService } from '../../structures/services/structures.service';
 
 @Injectable()
 export class UserRegistryService {
@@ -16,8 +13,7 @@ export class UserRegistryService {
   constructor(
     @InjectModel(User.name) private userModel: Model<IUser>,
     private userRegistrySearchService: UserRegistrySearchService,
-    private jobsGroupsService: JobsGroupsService,
-    private employerService: EmployerService
+    private structureService: StructuresService
   ) {}
   public maxPerPage = 20;
 
@@ -27,7 +23,8 @@ export class UserRegistryService {
       .find({ email: { $ne: process.env.MAIL_CONTACT } })
       .where('emailVerified')
       .equals(true)
-      .select('name surname _id job employer ')
+      .select('name surname _id job employer structuresLink')
+      .populate({ path: 'structuresLink', model: 'Structure', select: 'categories.ctm' })
       .populate('job employer')
       .collation({ locale: 'fr' })
       .sort({ surname: 1 })
@@ -42,25 +39,40 @@ export class UserRegistryService {
       .equals(true)
       .populate('employer')
       .populate('job')
-      .select('name surname employer job _id ')
+      .select('name surname employer job _id')
       .collation({ locale: 'fr' })
       .sort({ surname: 1 })
       .count()
       .exec();
   }
 
-  private callbackFilter(users: IUser[], employersList: Employer[], jobsGroupsList: JobsGroupsDocument[]): IUser[] {
+  private callbackFilter(
+    users: IUser[],
+    employersList: string[],
+    jobsGroupsList: string[],
+    territoriesList: string[],
+    communesList: string[]
+  ): IUser[] {
     this.logger.debug('callbackFilter');
-    const jobsGroupsIds: string[] = jobsGroupsList.map((jobsGroup) => jobsGroup._id.toString());
-    const employersNames: string[] = employersList.map((e) => e.name);
     // For each filter list (job or employer), we'll filter the main user list in order to get only the user that have a job or employer contained in the filters array
     // For this, we use findIndex method on job/employer name
-
     if (employersList?.length) {
-      users = users.filter((user) => employersNames.findIndex((n) => user.employer?.name === n) > -1);
+      users = users.filter((user) => employersList.includes(user.employer?.id));
     }
     if (jobsGroupsList?.length) {
-      users = users.filter((user) => jobsGroupsIds.includes(user.job?.jobsGroup?.toString()));
+      users = users.filter((user) => jobsGroupsList.includes(user.job?.jobsGroup?.toString()));
+    }
+    if (territoriesList?.length) {
+      users = users.filter((user) => {
+        const ctmValues = user.structuresLink.flatMap((structure: any) => structure.categories.ctm || []);
+        return ctmValues.some((ctm: string) => territoriesList.includes(ctm));
+      });
+    }
+    if (communesList?.length) {
+      users = users.filter((user) => {
+        const inseeCodeList = user.structuresLink.flatMap((structure: any) => structure.address?.inseeCode || []);
+        return inseeCodeList.some((inseeCode: string) => communesList.includes(inseeCode));
+      });
     }
     return users;
   }
@@ -69,23 +81,13 @@ export class UserRegistryService {
     searchParam: string,
     page: number,
     jobsGroups?: string[],
-    employers?: string[]
+    employers?: string[],
+    territories?: string[],
+    communes?: string[]
   ): Promise<UserRegistryPaginatedResponse> {
     this.logger.debug('findUsersByNameEmployerOrJobsGroup');
     const results = await this.userRegistrySearchService.search(searchParam);
     const ids = results.map((result) => result.id);
-    const jobsGroupsList: JobsGroupsDocument[] = [];
-    const employersList: Employer[] = [];
-    if (jobsGroups) {
-      for (const job of jobsGroups) {
-        jobsGroupsList.push(await this.jobsGroupsService.findByName(job));
-      }
-    }
-    if (employers) {
-      for (const employer of employers) {
-        employersList.push(await this.employerService.findByName(employer));
-      }
-    }
     const resultsWithFilter = await this.userModel
       .find({
         _id: { $in: ids },
@@ -93,13 +95,14 @@ export class UserRegistryService {
       })
       .where('emailVerified')
       .equals(true)
-      .select('name surname employer job _id withAppointment permalink')
+      .select('name surname employer job _id withAppointment permalink structureLink ')
       .populate('employer job')
+      .populate({ path: 'structuresLink', model: 'Structure', select: 'categories.ctm address.inseeCode' })
       .collation({ locale: 'fr' })
       .sort({ surname: 1 })
       .exec()
       .then((res) => {
-        return this.callbackFilter(res, employersList, jobsGroupsList);
+        return this.callbackFilter(res, employers, jobsGroups, territories, communes);
       });
     return {
       count: resultsWithFilter.length,
@@ -107,6 +110,39 @@ export class UserRegistryService {
     };
   }
 
+  /* Find all communes that have at least one structure that has at least one user */
+  public async findCommunesWithUsers(): Promise<{ commune: string; inseeCode: string }[]> {
+    this.logger.debug('findCommunesWithUsers');
+
+    // Fetch users with structuresLink
+    const users = await this.userModel
+      .find({ structuresLink: { $exists: true, $ne: [] }, emailVerified: true })
+      .select('structuresLink')
+      .exec();
+
+    // Collect unique structure IDs from users then fetch structures
+    const structureIds = Array.from(new Set(users.flatMap((user) => user.structuresLink)));
+    const structures = await Promise.all(structureIds.map((id) => this.structureService.findOne(id.toString())));
+
+    // Extract communes and inseeCodes (in a Set for unique commune identifiers)
+    const communesSet = new Set<string>();
+    structures.forEach((structure) => {
+      const commune = structure?.address?.commune;
+      const inseeCode = structure?.address?.inseeCode;
+      if (typeof commune === 'string' && typeof inseeCode === 'string') {
+        communesSet.add(`${commune}|${inseeCode}`);
+      }
+    });
+
+    // Convert Set to Array and sort by commune name
+    return Array.from(communesSet)
+      .map((key) => {
+        const [commune, inseeCode] = key.split('|');
+        return { commune, inseeCode };
+      })
+      .sort((a, b) => a.commune.localeCompare(b.commune));
+  }
+
   public async initUserRegistryIndex() {
     Logger.log('Reset users indexes');
     await this.userRegistrySearchService.dropIndex();
@@ -118,7 +154,7 @@ export class UserRegistryService {
     const users = await this.findAllForIndexation();
     await Promise.all(
       users.map((user: IUserRegistry) => {
-        this.userRegistrySearchService.indexUserRegistry(user);
+        return this.userRegistrySearchService.indexUserRegistry(user);
       })
     );
     return users;
diff --git a/src/users/services/users.service.spec.ts b/src/users/services/users.service.spec.ts
index 6a3093162959571bce870131175f6e0b0eaf2ab9..d0b0b9aa323abf90b009ad752662c292f7c3a046 100644
--- a/src/users/services/users.service.spec.ts
+++ b/src/users/services/users.service.spec.ts
@@ -112,9 +112,10 @@ const mockUser: User = {
   phone: '06 06 06 06 06',
   createdAt: new Date('2022-05-25T09:48:28.824Z'),
   employer: {
+    _id: '6654+65564',
     name: 'test',
     validated: true,
-  },
+  } as EmployerDocument,
   job: {
     name: 'test',
     validated: true,