Compare commits
4 Commits
16001f695b
...
59919834b9
| Author | SHA1 | Date | |
|---|---|---|---|
| 59919834b9 | |||
| cf6acbae7c | |||
| 7951c38d4d | |||
| 77d952a6f7 |
@ -552,7 +552,8 @@ export class AuthService {
|
||||
: undefined;
|
||||
enfant.photo_url = urlPhoto || undefined;
|
||||
enfant.status = enfantDto.date_naissance ? StatutEnfantType.SANS_GARDE : StatutEnfantType.A_NAITRE;
|
||||
enfant.consent_photo = false;
|
||||
enfant.consent_photo = !!enfantDto.consent_photo;
|
||||
enfant.consent_photo_at = enfant.consent_photo ? new Date() : null!;
|
||||
enfant.is_multiple = enfantDto.grossesse_multiple || false;
|
||||
|
||||
const enfantEnregistre = await manager.save(Children, enfant);
|
||||
@ -1074,6 +1075,12 @@ export class AuthService {
|
||||
if (enfantDto.grossesse_multiple !== undefined) {
|
||||
enfant.is_multiple = enfantDto.grossesse_multiple;
|
||||
}
|
||||
if (enfantDto.consent_photo !== undefined) {
|
||||
enfant.consent_photo = !!enfantDto.consent_photo;
|
||||
enfant.consent_photo_at = enfant.consent_photo
|
||||
? new Date()
|
||||
: null!;
|
||||
}
|
||||
|
||||
if (enfantDto.photo_base64 && enfantDto.photo_filename) {
|
||||
enfant.photo_url = await this.sauvegarderPhotoDepuisBase64(
|
||||
|
||||
@ -59,5 +59,14 @@ export class EnfantInscriptionDto {
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
grossesse_multiple?: boolean;
|
||||
|
||||
@ApiProperty({
|
||||
example: true,
|
||||
required: false,
|
||||
description: 'Consentement affichage / stockage photo (colonne enfants.consentement_photo)',
|
||||
})
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
consent_photo?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@ -120,7 +120,13 @@ export class EnfantsService {
|
||||
const child = await this.childrenRepository.findOne({ where: { id } });
|
||||
if (!child) throw new NotFoundException('Enfant introuvable');
|
||||
|
||||
await this.childrenRepository.update(id, dto);
|
||||
const patch: Partial<Children> = { ...dto } as Partial<Children>;
|
||||
if (dto.consent_photo !== undefined) {
|
||||
patch.consent_photo = dto.consent_photo;
|
||||
patch.consent_photo_at = dto.consent_photo ? new Date() : null!;
|
||||
}
|
||||
|
||||
await this.childrenRepository.update(id, patch);
|
||||
return this.findOne(id, currentUser);
|
||||
}
|
||||
|
||||
|
||||
@ -48,17 +48,28 @@ class EnfantAdminModel {
|
||||
}
|
||||
}
|
||||
|
||||
final photoUrl = json['photo_url'] as String? ?? json['photoUrl'] as String?;
|
||||
final hasPhoto = (photoUrl ?? '').trim().isNotEmpty;
|
||||
// L'inscription parent exigeait le consentement pour envoyer la photo, mais
|
||||
// le back a longtemps forcé consent_photo=false (voir reprise_mapper).
|
||||
final consentFromApi = _parseBool(json['consent_photo']) ||
|
||||
_parseBool(json['consentement_photo']) ||
|
||||
_parseBool(json['consentPhoto']);
|
||||
|
||||
return EnfantAdminModel(
|
||||
id: (json['id'] ?? '').toString(),
|
||||
firstName: json['first_name'] as String?,
|
||||
lastName: json['last_name'] as String?,
|
||||
gender: json['gender'] as String?,
|
||||
birthDate: _dateString(json['birth_date']),
|
||||
dueDate: _dateString(json['due_date']),
|
||||
status: normalizeEnfantStatus(json['status']?.toString()),
|
||||
photoUrl: json['photo_url'] as String?,
|
||||
consentPhoto: json['consent_photo'] == true,
|
||||
isMultiple: json['is_multiple'] == true,
|
||||
firstName: json['first_name'] as String? ?? json['prenom'] as String?,
|
||||
lastName: json['last_name'] as String? ?? json['nom'] as String?,
|
||||
gender: json['gender'] as String? ?? json['genre'] as String?,
|
||||
birthDate: _dateString(json['birth_date'] ?? json['date_naissance']),
|
||||
dueDate: _dateString(json['due_date'] ?? json['date_prevue_naissance']),
|
||||
status: normalizeEnfantStatus(
|
||||
(json['status'] ?? json['statut'])?.toString(),
|
||||
),
|
||||
photoUrl: photoUrl,
|
||||
consentPhoto: consentFromApi || hasPhoto,
|
||||
isMultiple: _parseBool(json['is_multiple']) ||
|
||||
_parseBool(json['est_multiple']),
|
||||
parentLinks: links,
|
||||
);
|
||||
}
|
||||
@ -76,6 +87,15 @@ class EnfantAdminModel {
|
||||
};
|
||||
}
|
||||
|
||||
static bool _parseBool(dynamic value) {
|
||||
if (value == true || value == 1) return true;
|
||||
if (value is String) {
|
||||
final s = value.trim().toLowerCase();
|
||||
return s == 'true' || s == '1' || s == 't' || s == 'yes';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static String? _dateString(dynamic v) {
|
||||
if (v == null) return null;
|
||||
if (v is String) return v.split('T').first;
|
||||
|
||||
@ -478,6 +478,25 @@ class UserService {
|
||||
return EnfantAdminModel.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
static Future<void> deleteEnfant(String enfantId) async {
|
||||
final response = await http.delete(
|
||||
Uri.parse('${ApiConfig.baseUrl}${ApiConfig.enfants}/$enfantId'),
|
||||
headers: await _headers(),
|
||||
);
|
||||
if (response.statusCode != 200 && response.statusCode != 204) {
|
||||
throw Exception(_extractErrorMessage(response.body, 'Erreur suppression enfant'));
|
||||
}
|
||||
}
|
||||
|
||||
/// AM dont la liste d'enfants actifs contient [enfantId] (API actuelle).
|
||||
static Future<AssistanteMaternelleModel?> findAmForEnfant(String enfantId) async {
|
||||
final ams = await getAssistantesMaternelles();
|
||||
for (final am in ams) {
|
||||
if (am.children.any((c) => c.id == enfantId)) return am;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static ParentModel _parentModelFromBody(String body) {
|
||||
final decoded = jsonDecode(body);
|
||||
return ParentModel.fromJson(
|
||||
|
||||
@ -167,6 +167,7 @@ class ParentRegistrationPayload {
|
||||
final map = <String, dynamic>{
|
||||
'genre': apiGenres.contains(c.genre) ? c.genre : 'Autre',
|
||||
'grossesse_multiple': c.multipleBirth,
|
||||
'consent_photo': c.photoConsent,
|
||||
};
|
||||
|
||||
final prenom = c.firstName.trim();
|
||||
@ -198,6 +199,9 @@ class ParentRegistrationPayload {
|
||||
map['photo_base64'] = photo.$1;
|
||||
map['photo_filename'] = photo.$2;
|
||||
}
|
||||
// Consentement photo enfant (le back l'ignore encore à l'inscription —
|
||||
// à brancher côté API ; en attendant le front admin infère via photo).
|
||||
map['consent_photo'] = c.photoConsent;
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@ -44,8 +44,8 @@ class RepriseMapper {
|
||||
lastName: e.lastName ?? '',
|
||||
dob: dob,
|
||||
genre: e.gender ?? '',
|
||||
// Inscription initiale exigeait la coche pour envoyer la photo ; le back
|
||||
// ne persistait pas toujours consent_photo — on pré-coche si photo en base.
|
||||
// Legacy : dossiers inscrits avant #144 avaient consent_photo=false malgré une photo.
|
||||
// On pré-coche encore si photo en base pour ne pas bloquer la reprise.
|
||||
photoConsent: e.consentPhoto || hasPhoto,
|
||||
multipleBirth: e.estMultiple,
|
||||
isUnbornChild: isUnborn,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -64,6 +64,7 @@ class AdminChildrenAffiliationPanel extends StatelessWidget {
|
||||
final c = children[i];
|
||||
return AdminEnfantUserCard.fromSummary(
|
||||
c,
|
||||
onCardTap: () => onOpen(c),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.visibility_outlined),
|
||||
|
||||
@ -14,6 +14,7 @@ class AdminUserCard extends StatefulWidget {
|
||||
final Color? infoColor;
|
||||
final String? vigilanceTooltip;
|
||||
final VoidCallback? onCardTap;
|
||||
final EdgeInsetsGeometry? margin;
|
||||
|
||||
const AdminUserCard({
|
||||
super.key,
|
||||
@ -28,6 +29,7 @@ class AdminUserCard extends StatefulWidget {
|
||||
this.infoColor,
|
||||
this.vigilanceTooltip,
|
||||
this.onCardTap,
|
||||
this.margin,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -59,7 +61,7 @@ class _AdminUserCardState extends State<AdminUserCard> {
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
hoverColor: const Color(0x149CC5C0),
|
||||
child: Card(
|
||||
margin: const EdgeInsets.only(bottom: 12),
|
||||
margin: widget.margin ?? const EdgeInsets.only(bottom: 12),
|
||||
elevation: 0,
|
||||
color: widget.backgroundColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user