feat(#168): API couples de garde parent (liste + couple courant).
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -5,7 +5,7 @@ import {
|
||||
NotFoundException,
|
||||
} from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { In, Repository } from 'typeorm';
|
||||
import { In, IsNull, Repository } from 'typeorm';
|
||||
import { Parents } from 'src/entities/parents.entity';
|
||||
import { DossierFamille } from 'src/entities/dossier_famille.entity';
|
||||
import { RoleType, Users } from 'src/entities/users.entity';
|
||||
@@ -20,6 +20,8 @@ import {
|
||||
import { ParentsChildren } from 'src/entities/parents_children.entity';
|
||||
import { Children } from 'src/entities/children.entity';
|
||||
import { UpdateParentFicheAdminDto } from './dto/update-parent-fiche-admin.dto';
|
||||
import { AmChildren } from 'src/entities/am_children.entity';
|
||||
import { CouplesGardeResponseDto } from './dto/couples-garde.dto';
|
||||
|
||||
@Injectable()
|
||||
export class ParentsService {
|
||||
@@ -32,6 +34,8 @@ export class ParentsService {
|
||||
private readonly dossierFamilleRepository: Repository<DossierFamille>,
|
||||
@InjectRepository(ParentsChildren)
|
||||
private readonly parentsChildrenRepository: Repository<ParentsChildren>,
|
||||
@InjectRepository(AmChildren)
|
||||
private readonly amChildrenRepository: Repository<AmChildren>,
|
||||
) {}
|
||||
|
||||
// Création d’un parent
|
||||
@@ -505,4 +509,108 @@ export class ParentsService {
|
||||
}
|
||||
return raw.map((r: { id: string }) => r.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liste les couples de garde (enfant ↔ AM) du parent connecté — ticket #168.
|
||||
* Un couple = un placement actif dans enfants_assistantes_maternelles pour un enfant du parent.
|
||||
*/
|
||||
async listerCouplesGarde(parentUserId: string): Promise<CouplesGardeResponseDto> {
|
||||
const parent = await this.parentsRepository.findOne({
|
||||
where: { user_id: parentUserId },
|
||||
});
|
||||
if (!parent) {
|
||||
throw new NotFoundException('Parent introuvable');
|
||||
}
|
||||
|
||||
const liensEnfants = await this.parentsChildrenRepository.find({
|
||||
where: { parentId: parentUserId },
|
||||
select: ['enfantId'],
|
||||
});
|
||||
const enfantIds = liensEnfants.map((l) => l.enfantId);
|
||||
if (enfantIds.length === 0) {
|
||||
return { couples: [], couple_courant_id: null };
|
||||
}
|
||||
|
||||
const placements = await this.amChildrenRepository.find({
|
||||
where: { enfantId: In(enfantIds), date_fin: IsNull() },
|
||||
relations: ['child', 'am', 'am.user'],
|
||||
order: { date_debut: 'ASC' },
|
||||
});
|
||||
|
||||
let idCourant = parent.id_placement_garde_courant ?? null;
|
||||
const idsValides = new Set(placements.map((p) => p.id));
|
||||
if (idCourant && !idsValides.has(idCourant)) {
|
||||
idCourant = null;
|
||||
await this.parentsRepository.update(
|
||||
{ user_id: parentUserId },
|
||||
{ id_placement_garde_courant: null },
|
||||
);
|
||||
}
|
||||
if (!idCourant && placements.length === 1) {
|
||||
idCourant = placements[0].id;
|
||||
}
|
||||
|
||||
const couples = placements.map((p) => {
|
||||
const amUser = p.am?.user;
|
||||
return {
|
||||
id: p.id,
|
||||
enfant: {
|
||||
id: p.child.id,
|
||||
prenom: p.child.first_name ?? null,
|
||||
nom: p.child.last_name ?? null,
|
||||
photo_url: p.child.photo_url ?? null,
|
||||
},
|
||||
am: {
|
||||
id: p.amId,
|
||||
prenom: amUser?.prenom ?? null,
|
||||
nom: amUser?.nom ?? null,
|
||||
photo_url: amUser?.photo_url ?? null,
|
||||
},
|
||||
courant: idCourant != null && p.id === idCourant,
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
couples,
|
||||
couple_courant_id: idCourant,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Persiste le couple de garde actif pour le parent — ticket #168.
|
||||
*/
|
||||
async definirCoupleGardeCourant(
|
||||
parentUserId: string,
|
||||
coupleId: string,
|
||||
): Promise<CouplesGardeResponseDto> {
|
||||
const parent = await this.parentsRepository.findOne({
|
||||
where: { user_id: parentUserId },
|
||||
});
|
||||
if (!parent) {
|
||||
throw new NotFoundException('Parent introuvable');
|
||||
}
|
||||
|
||||
const placement = await this.amChildrenRepository.findOne({
|
||||
where: { id: coupleId, date_fin: IsNull() },
|
||||
});
|
||||
if (!placement) {
|
||||
throw new NotFoundException('Couple de garde introuvable ou inactif');
|
||||
}
|
||||
|
||||
const lien = await this.parentsChildrenRepository.findOne({
|
||||
where: { parentId: parentUserId, enfantId: placement.enfantId },
|
||||
});
|
||||
if (!lien) {
|
||||
throw new BadRequestException(
|
||||
'Ce couple ne concerne pas un enfant rattaché à ce parent',
|
||||
);
|
||||
}
|
||||
|
||||
await this.parentsRepository.update(
|
||||
{ user_id: parentUserId },
|
||||
{ id_placement_garde_courant: coupleId },
|
||||
);
|
||||
|
||||
return this.listerCouplesGarde(parentUserId);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user