From b790dfe36e00756e55ff7e6e9904e21cefb00cae Mon Sep 17 00:00:00 2001 From: TTalex Date: Fri, 20 Sep 2024 18:36:12 +0200 Subject: [PATCH] working autoaffiliate poc for FC and existing users --- api/src/controllers/citizen.controller.ts | 80 +++++++++++++++++++ .../repositories/affiliation.repository.ts | 11 ++- website/src/apiMob/CitizenService.ts | 11 +++ website/src/pages/redirection.ts | 28 +++++-- 4 files changed, 121 insertions(+), 9 deletions(-) diff --git a/api/src/controllers/citizen.controller.ts b/api/src/controllers/citizen.controller.ts index 689af86..f1d99db 100644 --- a/api/src/controllers/citizen.controller.ts +++ b/api/src/controllers/citizen.controller.ts @@ -42,6 +42,7 @@ import { CitizenCreate, Funder, CitizenFilter, + AffiliationCreate, } from '../models'; import {InternalServerError} from '../validationError'; import { @@ -295,6 +296,85 @@ export class CitizenController { } } + /** + * autoaffiliate connected citizen + * @param data has token needed to affiliate connected citizen + */ + @authenticate(AUTH_STRATEGY.KEYCLOAK, AUTH_STRATEGY.API_KEY) + @authorize({ + allowedRoles: [Roles.SUPERVISORS, Roles.MANAGERS, Roles.API_KEY, Roles.CITIZENS], + }) + @post('/v1/citizens/{citizenId}/autoaffiliate', { + 'x-controller-name': 'Citizens', + summary: 'Affilie directement un citoyen à une entreprise', + security: SECURITY_SPEC_API_KEY_KC_PASSWORD, + responses: { + [StatusCode.NoContent]: { + description: "L'affiliation est validée", + }, + ...defaultSwaggerError, + }, + }) + async createAffiliation( + @param.path.string('citizenId', { + description: `L'identifiant du citoyen`, + }) + citizenId: string, + @requestBody({ + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + enterpriseId: { + type: 'string', + example: "Identifiant de l'entreprise professionnelle du citoyen", + }, + }, + }, + }, + }, + }) + data: { + enterpriseId: string; + }, + ): Promise { + try { + //const user = this.currentUser; + // TODO: should probably check that current user is allowed (a.k.a is the citizen), here or in interceptor + let citizen: Citizen | null = await this.citizenService.getCitizenWithAffiliationById(citizenId); + + Logger.debug(CitizenController.name, this.createAffiliation.name, 'citizen', citizen); + + if (citizen.affiliation && citizen.affiliation.id) { + // Affiliation already exists, erase it with this one + // IDEA: maybe be smarter here ? This is pretty brutal + await this.affiliationRepository.updateById(citizen.affiliation.id, { + status: AFFILIATION_STATUS.AFFILIATED, + enterpriseId: data.enterpriseId, + enterpriseEmail: null + }); + } else { + + citizen.affiliation = {enterpriseId: data.enterpriseId} as Affiliation + + // TODO: Not adding an entrepriseEmail doesn't seem to cause too many issues, but it might be smart to put one anyway + // ^ Especially if this results in a stuck user trying to update his profile (will entrepriseEmail be mandatory ?) + //citizen.affiliation.enterpriseEmail = citizen.personalInformation.email + const affiliation: Affiliation = await this.affiliationRepository.createAffiliation( + citizen, + false, // hasManualAffiliation + true // isAutoAffiliated + ); + + citizen.affiliation = affiliation + } + } catch (error) { + Logger.error(CitizenController.name, this.createAffiliation.name, 'Error', error); + throw error; + } + } + /** * disaffiliate citizen by id * @param citizenId id citizen diff --git a/api/src/repositories/affiliation.repository.ts b/api/src/repositories/affiliation.repository.ts index 3d3ad44..3ae9107 100644 --- a/api/src/repositories/affiliation.repository.ts +++ b/api/src/repositories/affiliation.repository.ts @@ -26,12 +26,13 @@ export class AffiliationRepository extends DefaultCrudRepository< * Creates affiliation based on enterpriseEmail, enterpriseId and enterprise manual affiliation * @param citizen Citizen * @param hasManualAffiliation boolean + * @param isAutoAffiliated boolean * @returns Promise */ - async createAffiliation(citizen: Citizen, hasManualAffiliation: boolean): Promise { - // Create object : affiliation + async createAffiliation(citizen: Citizen, hasManualAffiliation: boolean, isAutoAffiliated?: boolean): Promise { + // Create object : affiliation const rawAffiliation: Affiliation = new Affiliation(citizen.affiliation); - // Set enterpriseEmail & enterpriseId to null if not present + // Set enterpriseEmail & enterpriseId to null if not present rawAffiliation.enterpriseEmail = rawAffiliation?.enterpriseEmail || null; rawAffiliation.enterpriseId = rawAffiliation?.enterpriseId || null; @@ -45,6 +46,10 @@ export class AffiliationRepository extends DefaultCrudRepository< rawAffiliation.status = AFFILIATION_STATUS.UNKNOWN; } + if (isAutoAffiliated) { + rawAffiliation.status = AFFILIATION_STATUS.AFFILIATED; + } + // Assign citizenId rawAffiliation.citizenId = citizen.id; diff --git a/website/src/apiMob/CitizenService.ts b/website/src/apiMob/CitizenService.ts index 73b23d0..3dc1624 100644 --- a/website/src/apiMob/CitizenService.ts +++ b/website/src/apiMob/CitizenService.ts @@ -121,6 +121,17 @@ export const requestCitizenAffiliation = async ( return data; }; +export const requestCitizenAutoAffiliation = async ( + citizenId: string, + enterpriseId: string +): Promise<{}> => { + const { data } = await https.post( + `v1/citizens/${citizenId}/autoaffiliate`, + JSON.stringify({ enterpriseId }) + ); + return data; +}; + export const requestCitizenDesaffiliation = async ( citizenId: string ): Promise<{}> => { diff --git a/website/src/pages/redirection.ts b/website/src/pages/redirection.ts index aa4ab19..2a04d83 100644 --- a/website/src/pages/redirection.ts +++ b/website/src/pages/redirection.ts @@ -2,17 +2,33 @@ import { navigate } from 'gatsby'; import { useRoleAccepted } from '@utils/keycloakUtils'; import { browser } from '@utils/helpers'; +import { useSession, useUser } from '../context'; +import { requestCitizenAutoAffiliation } from '@api/CitizenService'; +import { useQueryParam, StringParam } from 'use-query-params'; import { Roles } from '../constants'; const IndexPage = () => { - if (browser) { - const isSupervisor = useRoleAccepted(Roles.SUPERVISORS); - const isManager = useRoleAccepted(Roles.MANAGERS); + // TODO: adding useUser and useQueryParams might have an effect on performances + // This might be important for a page that is only supposed to redirect users + // Maybe there is a way to be smarter and only check userContext if autoaffiliate param is present ? + const { citizen, userFunder, refetchCitizen } = useUser(); + const [entrepriseId] = useQueryParam('autoaffiliate', StringParam); - isSupervisor || isManager - ? navigate('/mon-dashboard') - : navigate('/recherche'); + if (browser) { + if (entrepriseId && citizen) { + requestCitizenAutoAffiliation(citizen.id, entrepriseId).then(() => { + refetchCitizen() + navigate('/recherche/?tab=AideEmployeur') + }) + } else { + const isSupervisor = useRoleAccepted(Roles.SUPERVISORS); + const isManager = useRoleAccepted(Roles.MANAGERS); + + isSupervisor || isManager + ? navigate('/mon-dashboard') + : navigate('/recherche'); + } } return null; };