Skip to content

Commit

Permalink
feat(frontend): export valid users
Browse files Browse the repository at this point in the history
  • Loading branch information
pYassine committed Jan 16, 2025
1 parent fe87bef commit 8729042
Show file tree
Hide file tree
Showing 21 changed files with 344 additions and 168 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ export class StatsPrivateController {
);
}

// Get reporting
@AllowUserStructureRoles("responsable", "admin", "simple")
@Get("reporting-questions")
public async getReportingQuestions(
Expand Down
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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()
Expand All @@ -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<void> {
const startTime = new Date();

Expand Down Expand Up @@ -121,6 +132,7 @@ export class ExportStructureUsagersController {
await this.usagersService.exportByChunks(
user.structureId,
5000,
statut,
processChunk
);

Expand Down
132 changes: 71 additions & 61 deletions packages/backend/src/usagers/services/usagers.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
UsagerTypeDom,
UsagerDecision,
Usager,
UsagersFilterCriteriaStatut,
} from "@domifa/common";
import { UsagerHistoryStateService } from "./usagerHistoryState.service";
import { StructureUsagerExport } from "./xlsx-structure-usagers-renderer";
Expand Down Expand Up @@ -250,76 +251,85 @@ export class UsagersService {
public async exportByChunks(
structureId: number,
chunkSize: number = 5000,
statut: UsagersFilterCriteriaStatut,
processChunk: (chunk: StructureUsagerExport[]) => Promise<void>
): Promise<void> {
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;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export enum UsagersFilterCriteriaStatut {
TOUS = "TOUS",
VALIDE = "VALIDE",
INSTRUCTION = "INSTRUCTION",
ATTENTE_DECISION = "ATTENTE_DECISION",
REFUS = "REFUS",
RADIE = "RADIE",
}
1 change: 1 addition & 0 deletions packages/common/src/search/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
export * from "./CriteriaSearchField.enum";
export * from "./SortValues.type";
export * from "./Timings.type";
export * from "./UsagersFilterCriteriaStatut.enum";
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
Filtrer les <span class="text-primary"> {{ nbResults }} </span>
<ng-container
*ngIf="
filters.statut === 'RADIE' &&
filters.statut === UsagersFilterCriteriaStatut.RADIE &&
usagersRadiesTotalCount !== usagersRadiesLoadedCount
"
>
Expand All @@ -22,7 +22,10 @@
</p>

<div
*ngIf="filters.statut === 'TOUS' || filters.statut === 'VALIDE'"
*ngIf="
filters.statut === UsagersFilterCriteriaStatut.TOUS ||
filters.statut === UsagersFilterCriteriaStatut.VALIDE
"
class="d-md-inline-block d-block me-2 text-md-start text-center my-1"
>
<button
Expand Down Expand Up @@ -79,7 +82,10 @@
</div>

<div
*ngIf="filters.statut === 'TOUS' || filters.statut === 'VALIDE'"
*ngIf="
filters.statut === UsagersFilterCriteriaStatut.TOUS ||
filters.statut === UsagersFilterCriteriaStatut.VALIDE
"
class="d-md-inline-block d-block me-2 text-md-start text-center my-1"
>
<button
Expand Down Expand Up @@ -131,7 +137,7 @@
</div>

<div
*ngIf="filters.statut === 'RADIE'"
*ngIf="filters.statut === UsagersFilterCriteriaStatut.RADIE"
class="d-md-inline-block d-block me-2 text-md-start text-center my-1"
>
<button
Expand Down Expand Up @@ -182,7 +188,7 @@
</div>
</div>
<div
*ngIf="filters.statut !== 'REFUS'"
*ngIf="filters.statut !== UsagersFilterCriteriaStatut.REFUS"
class="d-md-inline-block d-block me-2 text-md-start text-center my-1"
>
<button
Expand Down Expand Up @@ -235,7 +241,7 @@
</div>

<div
*ngIf="filters.statut === 'INSTRUCTION'"
*ngIf="filters.statut === UsagersFilterCriteriaStatut.INSTRUCTION"
class="d-md-inline-block d-block me-2 text-md-start text-center my-1"
>
<button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";

import { ManageUsagersModule } from "../../manage-usagers.module";
import { CriteriaSearchField } from "@domifa/common";
import {
CriteriaSearchField,
UsagersFilterCriteriaStatut,
} from "@domifa/common";

describe("ManageFiltersComponent", () => {
let component: ManageFiltersComponent;
Expand All @@ -30,7 +33,7 @@ describe("ManageFiltersComponent", () => {
lastInteractionDate: null,
sortKey: "NOM",
sortValue: "asc",
statut: "VALIDE",
statut: UsagersFilterCriteriaStatut.VALIDE,
};

fixture.detectChanges();
Expand All @@ -52,7 +55,10 @@ describe("ManageFiltersComponent", () => {
});

it("devrait inclure PASSAGE quand statut est TOUS", () => {
component.filters = { ...component.filters, statut: "TOUS" };
component.filters = {
...component.filters,
statut: UsagersFilterCriteriaStatut.TOUS,
};
const result = component.getSortKeys();
expect(result).toContainEqual({
id: "PASSAGE",
Expand All @@ -62,7 +68,10 @@ describe("ManageFiltersComponent", () => {
});

it("devrait inclure PASSAGE quand statut est VALIDE", () => {
component.filters = { ...component.filters, statut: "VALIDE" };
component.filters = {
...component.filters,
statut: UsagersFilterCriteriaStatut.VALIDE,
};
const result = component.getSortKeys();
expect(result).toContainEqual({
id: "PASSAGE",
Expand All @@ -72,7 +81,10 @@ describe("ManageFiltersComponent", () => {
});

it("ne devrait pas inclure PASSAGE pour les autres statuts", () => {
component.filters = { ...component.filters, statut: "RADIE" };
component.filters = {
...component.filters,
statut: UsagersFilterCriteriaStatut.RADIE,
};
const result = component.getSortKeys();
expect(result).not.toContainEqual({
id: "PASSAGE",
Expand All @@ -84,20 +96,32 @@ describe("ManageFiltersComponent", () => {

describe("getEcheanceLabel", () => {
it('devrait retourner "radiation" quand statut est RADIE', () => {
component.filters = { ...component.filters, statut: "RADIE" };
component.filters = {
...component.filters,
statut: UsagersFilterCriteriaStatut.RADIE,
};
expect(component.getEcheanceLabel()).toBe("radiation");
});

it('devrait retourner "refus" quand statut est REFUS', () => {
component.filters = { ...component.filters, statut: "REFUS" };
component.filters = {
...component.filters,
statut: UsagersFilterCriteriaStatut.REFUS,
};
expect(component.getEcheanceLabel()).toBe("refus");
});

it('devrait retourner "échéance" pour tout autre statut', () => {
component.filters = { ...component.filters, statut: "VALIDE" };
component.filters = {
...component.filters,
statut: UsagersFilterCriteriaStatut.VALIDE,
};
expect(component.getEcheanceLabel()).toBe("échéance");

component.filters = { ...component.filters, statut: "TOUS" };
component.filters = {
...component.filters,
statut: UsagersFilterCriteriaStatut.TOUS,
};
expect(component.getEcheanceLabel()).toBe("échéance");

component.filters = { ...component.filters, statut: undefined };
Expand Down
Loading

0 comments on commit 8729042

Please sign in to comment.