diff --git a/src/structures/services/structures.service.spec.ts b/src/structures/services/structures.service.spec.ts
index 2836627dcca9f7de919c592c4a4b3af026d5ed40..362e8df5110198fa4906041ab5575c77037fef0e 100644
--- a/src/structures/services/structures.service.spec.ts
+++ b/src/structures/services/structures.service.spec.ts
@@ -365,6 +365,9 @@ describe('StructuresService', () => {
         nbScanners: 1,
         otherDescription: null,
         personalOffers: [],
+        categories: {
+          onlineProcedures: ['caf'],
+        },
       },
     ]);
 
@@ -373,12 +376,12 @@ describe('StructuresService', () => {
       expect(res.length).toBe(1);
     });
     it('should find 1 structure', async () => {
-      const res = await structureService.searchForStructures('a', [[{ nbPrinters: '1' }, { '': 'baseSkills' }]]);
+      const res = await structureService.searchForStructures('a', [[{ nbPrinters: '1' }, { onlineProcedures: 'caf' }]]);
       expect(res.length).toBe(1);
     });
-    it('should find 1 structure', async () => {
-      const res = await structureService.searchForStructures('a', [[{ '': 'baseSkills' }]]);
-      expect(res.length).toBe(1);
+    it('should find 0 structure with personalOffer', async () => {
+      const res = await structureService.searchForStructures('a', [[{ onlineProcedures: 'caf' }]], null, true);
+      expect(res.length).toBe(0);
     });
     it('should find 1 structure', async () => {
       const res = await structureService.searchForStructures('a');
diff --git a/src/structures/services/structures.service.ts b/src/structures/services/structures.service.ts
index efc500f24cbb7a15fb33868a23d98eda61fb9c3e..5b8c5651275ed8b9acfbdc929f551abe39022ba7 100644
--- a/src/structures/services/structures.service.ts
+++ b/src/structures/services/structures.service.ts
@@ -27,6 +27,7 @@ import { Address } from '../schemas/address.schema';
 import { Structure, StructureDocument } from '../schemas/structure.schema';
 import { StructuresSearchService } from './structures-search.service';
 import { JobsService } from '../../users/services/jobs.service';
+import { User } from '../../users/schemas/user.schema';
 
 @Injectable()
 export class StructuresService {
@@ -53,7 +54,7 @@ export class StructuresService {
     text: string,
     filters?: Array<any>,
     fields?: string[],
-    useStructureOffers?: boolean,
+    onlyOffersWithAppointment?: boolean,
     limit?: number
   ): Promise<StructureDocument[]> {
     this.logger.debug(
@@ -120,7 +121,9 @@ export class StructuresService {
     }
 
     // Filter offers using structure offers and structure members personalOffers
-    structures = this.filterOnOffers(structures, andFiltersOnOffers, useStructureOffers);
+    if (andFiltersOnOffers.length) {
+      structures = await this.filterOnOffers(structures, andFiltersOnOffers, onlyOffersWithAppointment);
+    }
 
     return structures.sort((a, b) => ids.indexOf(a.id) - ids.indexOf(b.id));
   }
@@ -131,16 +134,11 @@ export class StructuresService {
    * @param andFiltersOnOffers
    * @returns StructureDocument[]
    */
-  private filterOnOffers(
+  private async filterOnOffers(
     structures: StructureDocument[],
     andFiltersOnOffers: Array<any>,
-    useStructureOffers: boolean
-  ): StructureDocument[] {
-    structures.forEach((structure) => {
-      // set structure offers and social workers personalOffers in structure.categoriesWithPersonalOffers
-      this.setCategoriesWithPersonalOffers(structure, useStructureOffers);
-    });
-
+    onlyOffersWithAppointment: boolean
+  ): Promise<StructureDocument[]> {
     // Build filters on offers from andFiltersOnOffers
     const filtersOnOffers = { onlineProcedures: [], baseSkills: [], advancedSkills: [] };
     andFiltersOnOffers.forEach((element) => {
@@ -149,6 +147,12 @@ export class StructuresService {
       if ('advancedSkills' in element) filtersOnOffers.advancedSkills.push(element.advancedSkills);
     });
 
+    // Set structure offers and social workers personalOffers in structure.categoriesWithPersonalOffers
+    const setCategoriesPromises = structures.map((structure) =>
+      this.setCategoriesWithPersonalOffers(structure, onlyOffersWithAppointment)
+    );
+    await Promise.all(setCategoriesPromises);
+
     // Filter structures on offers checking structure offers and structure social workers offers
     return structures.filter(
       (structure) =>
@@ -168,43 +172,68 @@ export class StructuresService {
    * set structure offers and structure social workers personalOffers in non-persistant property structure.categoriesWithPersonalOffers
    * @param structure
    */
-  public setCategoriesWithPersonalOffers(structure: StructureDocument, useStructureOffers: boolean) {
-    // Get structure offers
-    if (useStructureOffers) {
-      structure.categoriesWithPersonalOffers = {
-        onlineProcedures: structure.categories?.onlineProcedures || [],
-        baseSkills: structure.categories?.baseSkills || [],
-        advancedSkills: structure.categories?.advancedSkills || [],
-      };
-    } else {
+  public async setCategoriesWithPersonalOffers(structure: StructureDocument, onlyOffersWithAppointment: boolean) {
+    if (onlyOffersWithAppointment) {
       // Ignore structure offers (for orientation rdv, structure offers must be ignored: we filter only on personalOffers of the structure)
       structure.categoriesWithPersonalOffers = {
         onlineProcedures: [],
         baseSkills: [],
         advancedSkills: [],
       };
+    } else {
+      // Get structure offers
+      structure.categoriesWithPersonalOffers = {
+        onlineProcedures: structure.categories?.onlineProcedures || [],
+        baseSkills: structure.categories?.baseSkills || [],
+        advancedSkills: structure.categories?.advancedSkills || [],
+      };
     }
 
-    // Get offers for each structure social worker personalOffers
-    structure.personalOffers?.forEach((personalOffer) => {
-      if (!personalOffer.categories) {
-        throw new Error(`personalOffer not populated for structure ${structure.structureName} : ${personalOffer}`);
-      }
+    // Promise.all to wait for execution of all asynchronous operations
+    await Promise.all(
+      (structure.personalOffers || []).map(async (personalOffer) => {
+        if (!personalOffer.categories) {
+          throw new Error(`personalOffer not populated for structure ${structure.structureName} : ${personalOffer}`);
+        }
 
-      // use lodash _.union fonction to concat array without duplicates
-      structure.categoriesWithPersonalOffers.onlineProcedures = _.union(
-        structure.categoriesWithPersonalOffers.onlineProcedures,
-        personalOffer.categories.onlineProcedures
-      );
-      structure.categoriesWithPersonalOffers.baseSkills = _.union(
-        structure.categoriesWithPersonalOffers.baseSkills,
-        personalOffer.categories.baseSkills
-      );
-      structure.categoriesWithPersonalOffers.advancedSkills = _.union(
-        structure.categoriesWithPersonalOffers.advancedSkills,
-        personalOffer.categories.advancedSkills
-      );
-    });
+        // If we only want personalOffers from user with appointment
+        if (onlyOffersWithAppointment) {
+          const user = await this.userService.findByPersonalOfferId(personalOffer._id);
+          if (!user) {
+            Logger.log(
+              `No user with personalOffer ${personalOffer._id} for structure ${structure.structureName} (${structure._id}) !`,
+              StructuresService.name
+            );
+            return;
+          }
+          if (!user.structuresLink.includes(structure._id)) {
+            Logger.log(
+              `Inconsistent personalOffer skipped: user ${user.name} ${user.surname} (${user._id}) has personalOffer ${personalOffer._id} for structure ${structure.structureName} (${structure._id}) but is not (anymore) member of the structure !`,
+              StructuresService.name
+            );
+            return;
+          }
+          // If user is without appointment, skip this personalOffer
+          if (!User.getWithAppointment(user)) {
+            return;
+          }
+        }
+
+        // use lodash _.union fonction to concat array without duplicates
+        structure.categoriesWithPersonalOffers.onlineProcedures = _.union(
+          structure.categoriesWithPersonalOffers.onlineProcedures,
+          personalOffer.categories.onlineProcedures
+        );
+        structure.categoriesWithPersonalOffers.baseSkills = _.union(
+          structure.categoriesWithPersonalOffers.baseSkills,
+          personalOffer.categories.baseSkills
+        );
+        structure.categoriesWithPersonalOffers.advancedSkills = _.union(
+          structure.categoriesWithPersonalOffers.advancedSkills,
+          personalOffer.categories.advancedSkills
+        );
+      })
+    );
   }
 
   public async create(email: string, structure: StructureDto): Promise<Structure> {
@@ -1265,9 +1294,8 @@ export class StructuresService {
     structure.hasUserWithAppointmentDN = false;
     let conseillerNumFranceServices = false;
 
-    owners.forEach((owner) => {
-      // Check if owner has withAppointment and a job with personnalOffer (user may have changed his job after choosing withAppointment)
-      if (owner.withAppointment && owner.job?.hasPersonalOffer) {
+    owners.forEach((owner: User) => {
+      if (User.getWithAppointment(owner)) {
         structure.hasUserWithAppointmentDN = true;
       }
       // If user has job 'Conseiller numérique' ou 'Conseillère numérique'
diff --git a/src/structures/structures.controller.ts b/src/structures/structures.controller.ts
index 71e4be67e9fd0d6265b5d58df47f7c406134ed82..7f467b9b7b4e7c085d6978352be2c729b74a96a9 100644
--- a/src/structures/structures.controller.ts
+++ b/src/structures/structures.controller.ts
@@ -101,7 +101,7 @@ export class StructuresController {
       query.query,
       body ? body.filters : null,
       null,
-      body?.useStructureOffers || null,
+      body?.onlyOffersWithAppointment || false,
       body?.limit || null
     );
   }
diff --git a/src/users/schemas/user.schema.ts b/src/users/schemas/user.schema.ts
index 462e719803bc55a90de3577d85ea05a1323ab6f1..c850621c819deb256743bb8edaa1a4d18115c7a5 100644
--- a/src/users/schemas/user.schema.ts
+++ b/src/users/schemas/user.schema.ts
@@ -2,7 +2,7 @@ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
 import { Types } from 'mongoose';
 import { PersonalOfferDocument } from '../../personal-offers/schemas/personal-offer.schema';
 import { Employer } from './employer.schema';
-import { Job, JobDocument } from './job.schema';
+import { JobDocument } from './job.schema';
 import { UserRole } from '../enum/user-role.enum';
 import { pendingStructuresLink } from '../interfaces/pendingStructure';
 
@@ -73,6 +73,19 @@ export class User {
 
   @Prop({ default: null })
   lastLoginDate: Date;
+
+  // Document methods
+  // static because object method would need to create a constructor and get an actual User instance (cf. https://stackoverflow.com/a/42899705 )
+
+  // Get if owner can have appointment
+  static getWithAppointment(user: User) {
+    if (user.job && !user.job.name) {
+      throw new Error(`job not populated for user ${user.surname} : ${user.job}`);
+    }
+    // Also check user has a job with personnalOffer (user may have changed his job after choosing withAppointment)
+    // and also check if user has personalOffers (otherwise they can't have appointment)
+    return user.withAppointment && user.job?.hasPersonalOffer && user.personalOffers?.length;
+  }
 }
 
 export const UserSchema = SchemaFactory.createForClass(User);
diff --git a/src/users/services/users.service.ts b/src/users/services/users.service.ts
index 37777eced25c36e317e89384669cd911971914d9..f4100c58eb6b15bca86b58549dbd98f90f279ca3 100644
--- a/src/users/services/users.service.ts
+++ b/src/users/services/users.service.ts
@@ -972,6 +972,7 @@ export class UsersService {
       .findOne({
         personalOffers: { $all: [new Types.ObjectId(id)] },
       })
+      .populate('job')
       .populate('personalOffers')
       .exec();
   }