diff --git a/packages/backend/src/stats/controllers/stats.private.controller.ts b/packages/backend/src/stats/controllers/stats.private.controller.ts index 20324b1e5d..a94e2a0772 100644 --- a/packages/backend/src/stats/controllers/stats.private.controller.ts +++ b/packages/backend/src/stats/controllers/stats.private.controller.ts @@ -78,7 +78,6 @@ export class StatsPrivateController { ); } - // Get reporting @AllowUserStructureRoles("responsable", "admin", "simple") @Get("reporting-questions") public async getReportingQuestions( diff --git a/packages/backend/src/usagers/controllers/export-structure-usagers.controller.ts b/packages/backend/src/usagers/controllers/export-structure-usagers.controller.ts index 015faab11b..1c37b089cc 100644 --- a/packages/backend/src/usagers/controllers/export-structure-usagers.controller.ts +++ b/packages/backend/src/usagers/controllers/export-structure-usagers.controller.ts @@ -1,4 +1,11 @@ -import { Controller, Get, Res, UseGuards } from "@nestjs/common"; +import { + Controller, + Get, + Param, + ParseEnumPipe, + Res, + UseGuards, +} from "@nestjs/common"; import { AuthGuard } from "@nestjs/passport"; import { ApiBearerAuth, ApiTags } from "@nestjs/swagger"; import { Response } from "express"; @@ -20,6 +27,8 @@ import * as XLSX from "xlsx"; import { AppLogsService } from "../../modules/app-logs/app-logs.service"; import { domifaConfig } from "../../config"; +import { UsagersFilterCriteriaStatut } from "@domifa/common"; + @UseGuards(AuthGuard("jwt"), AppUserGuard) @ApiTags("export") @ApiBearerAuth() @@ -30,11 +39,13 @@ export class ExportStructureUsagersController { private readonly appLogsService: AppLogsService ) {} - @Get("") + @Get(":statut") @AllowUserStructureRoles("responsable", "admin") public async export( @CurrentUser() user: UserStructureAuthenticated, - @Res() res: Response + @Res() res: Response, + @Param("statut", new ParseEnumPipe(UsagersFilterCriteriaStatut)) + statut: UsagersFilterCriteriaStatut ): Promise { const startTime = new Date(); @@ -121,6 +132,7 @@ export class ExportStructureUsagersController { await this.usagersService.exportByChunks( user.structureId, 5000, + statut, processChunk ); diff --git a/packages/backend/src/usagers/services/usagers.service.ts b/packages/backend/src/usagers/services/usagers.service.ts index 3179ad0a0e..a7c54424fe 100644 --- a/packages/backend/src/usagers/services/usagers.service.ts +++ b/packages/backend/src/usagers/services/usagers.service.ts @@ -26,6 +26,7 @@ import { UsagerTypeDom, UsagerDecision, Usager, + UsagersFilterCriteriaStatut, } from "@domifa/common"; import { UsagerHistoryStateService } from "./usagerHistoryState.service"; import { StructureUsagerExport } from "./xlsx-structure-usagers-renderer"; @@ -250,76 +251,85 @@ export class UsagersService { public async exportByChunks( structureId: number, chunkSize: number = 5000, + statut: UsagersFilterCriteriaStatut, processChunk: (chunk: StructureUsagerExport[]) => Promise ): Promise { let skip = 0; let total = 0; - const [{ count }] = await usagerRepository.query( - `SELECT COUNT(*) as count FROM usager WHERE "structureId" = $1`, - [structureId] - ); + const params: any[] = [structureId]; + let whereClause = 'u."structureId" = $1'; + + if (statut !== UsagersFilterCriteriaStatut.TOUS) { + params.push(statut); + whereClause += ` AND u.statut = $${params.length}`; + } + + const countQuery = ` + SELECT COUNT(*) as count + FROM usager u + ${whereClause} + `; + + const [{ count }] = await usagerRepository.query(countQuery, params); const query = ` - SELECT - u."customRef", - u.ref, - u.nom, - u.prenom, - u.surnom, - u.sexe, - u."dateNaissance", - u."villeNaissance", - u.langue, - u.nationalite, - u.email, - u.telephone, - u."ayantsDroits", - u."typeDom", - u."datePremiereDom", - u.decision, - u.historique, - u."lastInteraction", - u.options, - u."numeroDistribution", - JSON_BUILD_OBJECT( - 'usagerUUID', e."usagerUUID", - 'structureId', e."structureId", - 'usagerRef', e."usagerRef", - 'domiciliation', e.domiciliation, - 'commentaires', e.commentaires, - 'typeMenage', e."typeMenage", - 'revenus', e.revenus, - 'revenusDetail', e."revenusDetail", - 'orientation', e.orientation, - 'orientationDetail', e."orientationDetail", - 'liencommune', e.liencommune, - 'liencommuneDetail', e."liencommuneDetail", - 'residence', e.residence, - 'residenceDetail', e."residenceDetail", - 'cause', e.cause, - 'causeDetail', e."causeDetail", - 'rattachement', e.rattachement, - 'raison', e.raison, - 'raisonDetail', e."raisonDetail", - 'accompagnement', e.accompagnement, - 'accompagnementDetail', e."accompagnementDetail", - 'situationPro', e."situationPro", - 'situationProDetail', e."situationProDetail" - ) as entretien - FROM usager u - LEFT JOIN usager_entretien e ON e."usagerUUID" = u.uuid - WHERE u."structureId" = $1 - ORDER BY u.nom ASC - LIMIT $2 OFFSET $3 - `; + SELECT + u."customRef", + u.ref, + u.nom, + u.prenom, + u.surnom, + u.sexe, + u."dateNaissance", + u."villeNaissance", + u.langue, + u.nationalite, + u.email, + u.telephone, + u."ayantsDroits", + u."typeDom", + u."datePremiereDom", + u.decision, + u.historique, + u."lastInteraction", + u.options, + u."numeroDistribution", + JSON_BUILD_OBJECT( + 'usagerUUID', e."usagerUUID", + 'structureId', e."structureId", + 'usagerRef', e."usagerRef", + 'domiciliation', e.domiciliation, + 'commentaires', e.commentaires, + 'typeMenage', e."typeMenage", + 'revenus', e.revenus, + 'revenusDetail', e."revenusDetail", + 'orientation', e.orientation, + 'orientationDetail', e."orientationDetail", + 'liencommune', e.liencommune, + 'liencommuneDetail', e."liencommuneDetail", + 'residence', e.residence, + 'residenceDetail', e."residenceDetail", + 'cause', e.cause, + 'causeDetail', e."causeDetail", + 'rattachement', e.rattachement, + 'raison', e.raison, + 'raisonDetail', e."raisonDetail", + 'accompagnement', e.accompagnement, + 'accompagnementDetail', e."accompagnementDetail", + 'situationPro', e."situationPro", + 'situationProDetail', e."situationProDetail" + ) as entretien + FROM usager u + LEFT JOIN usager_entretien e ON e."usagerUUID" = u.uuid + ${whereClause} + ORDER BY u.uuid ASC + LIMIT $${params.length + 1} OFFSET $${params.length + 2} + `; while (true) { - const chunk = await usagerRepository.query(query, [ - structureId, - chunkSize, - skip, - ]); + const queryParams = [...params, chunkSize, skip]; + const chunk = await usagerRepository.query(query, queryParams); if (chunk.length === 0) { break; diff --git a/packages/common/src/search/types/UsagersFilterCriteriaStatut.enum.ts b/packages/common/src/search/types/UsagersFilterCriteriaStatut.enum.ts new file mode 100644 index 0000000000..e0e49f534b --- /dev/null +++ b/packages/common/src/search/types/UsagersFilterCriteriaStatut.enum.ts @@ -0,0 +1,8 @@ +export enum UsagersFilterCriteriaStatut { + TOUS = "TOUS", + VALIDE = "VALIDE", + INSTRUCTION = "INSTRUCTION", + ATTENTE_DECISION = "ATTENTE_DECISION", + REFUS = "REFUS", + RADIE = "RADIE", +} diff --git a/packages/common/src/search/types/index.ts b/packages/common/src/search/types/index.ts index 42f01ad4ee..08fa2e722b 100644 --- a/packages/common/src/search/types/index.ts +++ b/packages/common/src/search/types/index.ts @@ -2,3 +2,4 @@ export * from "./CriteriaSearchField.enum"; export * from "./SortValues.type"; export * from "./Timings.type"; +export * from "./UsagersFilterCriteriaStatut.enum"; diff --git a/packages/frontend/src/app/modules/manage-usagers/components/manage-filters/manage-filters.component.html b/packages/frontend/src/app/modules/manage-usagers/components/manage-filters/manage-filters.component.html index f2dd13e0dd..2f7da0367f 100644 --- a/packages/frontend/src/app/modules/manage-usagers/components/manage-filters/manage-filters.component.html +++ b/packages/frontend/src/app/modules/manage-usagers/components/manage-filters/manage-filters.component.html @@ -10,7 +10,7 @@ Filtrer les {{ nbResults }} @@ -22,7 +22,10 @@

+   +