feat(#159/#160): suppressions métier dashboard — API + UI (squash develop).
Matrice PO #154 : supprimer dossiers famille/AM, parents, enfants et comptes staff avec règles métier (placements clôturés, sans_enfant, cascade foyer, droits gestionnaire/admin). Poubelle en liste, dialogues de confirmation, garde-fou gestionnaire→gestionnaire. Inclut polish hauteur modale fiche AM.
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:p_tits_pas/models/dossier_list_item.dart';
|
||||
import 'package:p_tits_pas/models/parent_model.dart';
|
||||
import 'package:p_tits_pas/services/auth_service.dart';
|
||||
import 'package:p_tits_pas/services/user_service.dart';
|
||||
import 'package:p_tits_pas/utils/staff_deletion_rights.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_parent_edit_modal.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/admin_user_card.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/suppression_confirm_dialog.dart';
|
||||
import 'package:p_tits_pas/widgets/admin/common/user_list.dart';
|
||||
|
||||
class ParentManagementWidget extends StatefulWidget {
|
||||
@@ -23,16 +27,24 @@ class _ParentManagementWidgetState extends State<ParentManagementWidget> {
|
||||
bool _isLoading = false;
|
||||
String? _error;
|
||||
List<ParentModel> _parents = [];
|
||||
bool _canDelete = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadRights();
|
||||
_loadParents();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() => super.dispose();
|
||||
|
||||
Future<void> _loadRights() async {
|
||||
final user = await AuthService.getCurrentUser();
|
||||
if (!mounted) return;
|
||||
setState(() => _canDelete = canDeleteMetier(user?.role));
|
||||
}
|
||||
|
||||
Future<void> _loadParents() async {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
@@ -54,6 +66,67 @@ class _ParentManagementWidgetState extends State<ParentManagementWidget> {
|
||||
}
|
||||
}
|
||||
|
||||
bool _isLastParent(ParentModel parent) {
|
||||
final co = parent.coParent?.id.trim();
|
||||
if (co != null && co.isNotEmpty) return false;
|
||||
final num = (parent.user.numeroDossier ?? '').trim();
|
||||
if (num.isEmpty) return true;
|
||||
return !_parents.any((other) {
|
||||
if (other.user.id == parent.user.id) return false;
|
||||
return (other.user.numeroDossier ?? '').trim() == num;
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _confirmDelete(ParentModel parent) async {
|
||||
final num = (parent.user.numeroDossier ?? '').trim();
|
||||
final name = formatDossierPersonLabel(
|
||||
nom: parent.user.nom,
|
||||
prenom: parent.user.prenom,
|
||||
email: parent.user.email,
|
||||
);
|
||||
final last = _isLastParent(parent);
|
||||
final enfants = ParentModel.foyerChildrenCount(parent, _parents);
|
||||
final footnotes = last
|
||||
? <String>[
|
||||
if (num.isNotEmpty) 'Dernier parent du dossier $num.',
|
||||
if (num.isEmpty) 'Dernier parent du dossier.',
|
||||
'Les $enfants enfant(s) rattaché(s) seront aussi supprimés.',
|
||||
]
|
||||
: <String>[
|
||||
if (num.isNotEmpty)
|
||||
'Ce parent sera retiré du dossier $num.',
|
||||
'Les enfants restent avec le co-parent.',
|
||||
];
|
||||
|
||||
final confirmed = await showSuppressionConfirmDialog(
|
||||
context,
|
||||
title: 'Supprimer le parent',
|
||||
subtitle: num.isEmpty ? null : 'Dossier $num',
|
||||
people: [SuppressionPersonLine.parent(name)],
|
||||
footnotes: footnotes,
|
||||
);
|
||||
if (!confirmed || !mounted) return;
|
||||
|
||||
try {
|
||||
final result = await UserService.deleteUser(parent.user.id);
|
||||
if (!mounted) return;
|
||||
final msg = (result['message'] ?? 'Parent supprimé.').toString();
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg)));
|
||||
await _loadParents();
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
e is Exception
|
||||
? e.toString().replaceFirst('Exception: ', '')
|
||||
: 'Erreur suppression',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final query = widget.searchQuery.toLowerCase();
|
||||
@@ -90,6 +163,8 @@ class _ParentManagementWidgetState extends State<ParentManagementWidget> {
|
||||
_openParentDetails(parent);
|
||||
},
|
||||
),
|
||||
if (_canDelete)
|
||||
suppressionIconButton(onPressed: () => _confirmDelete(parent)),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user