fix: Récupérer l'opération active depuis la table operations
- Corrige l'erreur SQL 'Unknown column fk_operation in users' - L'opération active est récupérée depuis operations.chk_active = 1 - Jointure avec users pour filtrer par entité de l'admin créateur - Query: SELECT o.id FROM operations o INNER JOIN users u ON u.fk_entite = o.fk_entite WHERE u.id = ? AND o.chk_active = 1
This commit is contained in:
@@ -89,17 +89,13 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
|
||||
// Helpers de validation
|
||||
String? _validateNumero(String? value) {
|
||||
debugPrint('🔍 [VALIDATOR] _validateNumero appelé avec: "$value"');
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
debugPrint('❌ [VALIDATOR] Numéro vide -> retourne erreur');
|
||||
return 'Le numéro est obligatoire';
|
||||
}
|
||||
final numero = int.tryParse(value.trim());
|
||||
if (numero == null || numero <= 0) {
|
||||
debugPrint('❌ [VALIDATOR] Numéro invalide: $value -> retourne erreur');
|
||||
return 'Numéro invalide';
|
||||
}
|
||||
debugPrint('✅ [VALIDATOR] Numéro valide: $numero');
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -166,30 +162,11 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
super.initState();
|
||||
|
||||
try {
|
||||
debugPrint('=== DEBUT PassageFormDialog.initState ===');
|
||||
|
||||
// Accéder à la settingsBox (déjà ouverte dans l'app)
|
||||
_settingsBox = Hive.box(AppKeys.settingsBoxName);
|
||||
|
||||
// Initialize controllers with passage data if available
|
||||
final passage = widget.passage;
|
||||
debugPrint('Passage reçu: ${passage != null}');
|
||||
|
||||
if (passage != null) {
|
||||
debugPrint('Passage ID: ${passage.id}');
|
||||
debugPrint('Passage fkType: ${passage.fkType}');
|
||||
debugPrint('Passage numero: ${passage.numero}');
|
||||
debugPrint('Passage rueBis: ${passage.rueBis}');
|
||||
debugPrint('Passage rue: ${passage.rue}');
|
||||
debugPrint('Passage ville: ${passage.ville}');
|
||||
debugPrint('Passage name: ${passage.name}');
|
||||
debugPrint('Passage email: ${passage.email}');
|
||||
debugPrint('Passage phone: ${passage.phone}');
|
||||
debugPrint('Passage montant: ${passage.montant}');
|
||||
debugPrint('Passage remarque: ${passage.remarque}');
|
||||
debugPrint('Passage fkHabitat: ${passage.fkHabitat}');
|
||||
debugPrint('Passage fkTypeReglement: ${passage.fkTypeReglement}');
|
||||
}
|
||||
|
||||
_selectedPassageType = passage?.fkType;
|
||||
_showForm = false; // Toujours commencer par la sélection de type
|
||||
@@ -199,8 +176,6 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
// Section Adresse : ouverte si nouveau passage, fermée si modification
|
||||
_isAddressSectionExpanded = passage == null;
|
||||
|
||||
debugPrint('Initialisation des controllers...');
|
||||
|
||||
// S'assurer que toutes les valeurs null deviennent des chaînes vides
|
||||
String numero = passage?.numero.toString() ?? '';
|
||||
String rueBis = passage?.rueBis.toString() ?? '';
|
||||
@@ -222,7 +197,6 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
|
||||
// Si nouveau passage, charger les valeurs mémorisées de la dernière adresse
|
||||
if (passage == null) {
|
||||
debugPrint('Nouveau passage: chargement des valeurs mémorisées...');
|
||||
numero = _settingsBox.get('lastPassageNumero', defaultValue: '') as String;
|
||||
rueBis = _settingsBox.get('lastPassageRueBis', defaultValue: '') as String;
|
||||
rue = _settingsBox.get('lastPassageRue', defaultValue: '') as String;
|
||||
@@ -231,8 +205,6 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
_fkHabitat = _settingsBox.get('lastPassageFkHabitat', defaultValue: 1) as int;
|
||||
appt = _settingsBox.get('lastPassageAppt', defaultValue: '') as String;
|
||||
niveau = _settingsBox.get('lastPassageNiveau', defaultValue: '') as String;
|
||||
|
||||
debugPrint('Valeurs chargées: numero="$numero", rue="$rue", ville="$ville"');
|
||||
}
|
||||
|
||||
// Initialiser la date de passage
|
||||
@@ -242,20 +214,6 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
final String timeFormatted =
|
||||
'${_passedAt.hour.toString().padLeft(2, '0')}:${_passedAt.minute.toString().padLeft(2, '0')}';
|
||||
|
||||
debugPrint('Valeurs pour controllers:');
|
||||
debugPrint(' numero: "$numero"');
|
||||
debugPrint(' rueBis: "$rueBis"');
|
||||
debugPrint(' rue: "$rue"');
|
||||
debugPrint(' ville: "$ville"');
|
||||
debugPrint(' name: "$name"');
|
||||
debugPrint(' email: "$email"');
|
||||
debugPrint(' phone: "$phone"');
|
||||
debugPrint(' montant: "$montant"');
|
||||
debugPrint(' remarque: "$remarque"');
|
||||
debugPrint(' passedAt: "$_passedAt"');
|
||||
debugPrint(' dateFormatted: "$dateFormatted"');
|
||||
debugPrint(' timeFormatted: "$timeFormatted"');
|
||||
|
||||
_numeroController = TextEditingController(text: numero);
|
||||
_rueBisController = TextEditingController(text: rueBis);
|
||||
_rueController = TextEditingController(text: rue);
|
||||
@@ -280,12 +238,8 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
debugPrint('=== FIN PassageFormDialog.initState ===');
|
||||
} catch (e, stackTrace) {
|
||||
debugPrint('=== ERREUR PassageFormDialog.initState ===');
|
||||
debugPrint('Erreur: $e');
|
||||
debugPrint('StackTrace: $stackTrace');
|
||||
debugPrint('❌ Erreur initState PassageFormDialog: $e\n$stackTrace');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
@@ -334,20 +288,11 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
}
|
||||
|
||||
void _handleSubmit() async {
|
||||
debugPrint('🔵 [SUBMIT] Début _handleSubmit');
|
||||
|
||||
if (_isSubmitting) {
|
||||
debugPrint('⚠️ [SUBMIT] Déjà en cours de soumission, abandon');
|
||||
return;
|
||||
}
|
||||
|
||||
debugPrint('🔵 [SUBMIT] Vérification de l\'état du formulaire');
|
||||
debugPrint('🔵 [SUBMIT] _formKey: $_formKey');
|
||||
debugPrint('🔵 [SUBMIT] _formKey.currentState: ${_formKey.currentState}');
|
||||
if (_isSubmitting) return;
|
||||
|
||||
// Validation avec protection contre le null
|
||||
if (_formKey.currentState == null) {
|
||||
debugPrint('❌ [SUBMIT] ERREUR: _formKey.currentState est null !');
|
||||
debugPrint('❌ _formKey.currentState est null');
|
||||
if (mounted) {
|
||||
await ResultDialog.show(
|
||||
context: context,
|
||||
@@ -358,14 +303,9 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
return;
|
||||
}
|
||||
|
||||
debugPrint('🔵 [SUBMIT] Validation du formulaire...');
|
||||
final isValid = _formKey.currentState!.validate();
|
||||
debugPrint('🔵 [SUBMIT] Résultat validation: $isValid');
|
||||
|
||||
if (!isValid) {
|
||||
debugPrint('⚠️ [SUBMIT] Validation échouée, abandon');
|
||||
|
||||
// Afficher un dialog d'erreur clair à l'utilisateur
|
||||
if (mounted) {
|
||||
await ResultDialog.show(
|
||||
context: context,
|
||||
@@ -376,109 +316,73 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
return;
|
||||
}
|
||||
|
||||
debugPrint('✅ [SUBMIT] Validation OK, appel _savePassage()');
|
||||
await _savePassage();
|
||||
debugPrint('🔵 [SUBMIT] Fin _handleSubmit');
|
||||
}
|
||||
|
||||
Future<void> _savePassage() async {
|
||||
debugPrint('🟢 [SAVE] Début _savePassage');
|
||||
if (_isSubmitting) return;
|
||||
|
||||
if (_isSubmitting) {
|
||||
debugPrint('⚠️ [SAVE] Déjà en cours de soumission, abandon');
|
||||
return;
|
||||
}
|
||||
|
||||
debugPrint('🟢 [SAVE] Mise à jour état _isSubmitting = true');
|
||||
setState(() {
|
||||
_isSubmitting = true;
|
||||
});
|
||||
|
||||
// Afficher l'overlay de chargement
|
||||
debugPrint('🟢 [SAVE] Affichage overlay de chargement');
|
||||
final overlay = LoadingSpinOverlayUtils.show(
|
||||
context: context,
|
||||
message: 'Enregistrement en cours...',
|
||||
);
|
||||
|
||||
try {
|
||||
debugPrint('🟢 [SAVE] Récupération utilisateur actuel');
|
||||
final currentUser = widget.userRepository.getCurrentUser();
|
||||
debugPrint('🟢 [SAVE] currentUser: ${currentUser?.id} - ${currentUser?.name}');
|
||||
|
||||
if (currentUser == null) {
|
||||
debugPrint('❌ [SAVE] ERREUR: Utilisateur non connecté');
|
||||
throw Exception("Utilisateur non connecté");
|
||||
}
|
||||
|
||||
debugPrint('🟢 [SAVE] Récupération opération active');
|
||||
final currentOperation = widget.operationRepository.getCurrentOperation();
|
||||
debugPrint('🟢 [SAVE] currentOperation: ${currentOperation?.id} - ${currentOperation?.name}');
|
||||
|
||||
if (currentOperation == null && widget.passage == null) {
|
||||
debugPrint('❌ [SAVE] ERREUR: Aucune opération active trouvée');
|
||||
throw Exception("Aucune opération active trouvée");
|
||||
}
|
||||
|
||||
// Déterminer les valeurs de montant et type de règlement selon le type de passage
|
||||
debugPrint('🟢 [SAVE] Calcul des valeurs finales');
|
||||
debugPrint('🟢 [SAVE] _selectedPassageType: $_selectedPassageType');
|
||||
|
||||
final String finalMontant =
|
||||
(_selectedPassageType == 1 || _selectedPassageType == 5)
|
||||
? _montantController.text.trim().replaceAll(',', '.')
|
||||
: '0';
|
||||
debugPrint('🟢 [SAVE] finalMontant: $finalMontant');
|
||||
|
||||
// Déterminer le type de règlement final selon le type de passage
|
||||
final int finalTypeReglement;
|
||||
if (_selectedPassageType == 1 || _selectedPassageType == 5) {
|
||||
// Pour les types 1 et 5, utiliser la valeur sélectionnée (qui a été validée)
|
||||
finalTypeReglement = _fkTypeReglement;
|
||||
} else {
|
||||
// Pour tous les autres types, forcer "Non renseigné"
|
||||
finalTypeReglement = 4;
|
||||
}
|
||||
debugPrint('🟢 [SAVE] finalTypeReglement: $finalTypeReglement');
|
||||
|
||||
// Déterminer la valeur de nbPassages selon le type de passage
|
||||
final int finalNbPassages;
|
||||
if (widget.passage != null) {
|
||||
// Modification d'un passage existant
|
||||
if (_selectedPassageType == 2) {
|
||||
// Type 2 (À finaliser) : toujours incrémenter
|
||||
finalNbPassages = widget.passage!.nbPassages + 1;
|
||||
} else {
|
||||
// Autres types : mettre à 1 si actuellement 0, sinon conserver
|
||||
final currentNbPassages = widget.passage!.nbPassages;
|
||||
finalNbPassages = currentNbPassages == 0 ? 1 : currentNbPassages;
|
||||
}
|
||||
} else {
|
||||
// Nouveau passage : toujours 1
|
||||
finalNbPassages = 1;
|
||||
}
|
||||
debugPrint('🟢 [SAVE] finalNbPassages: $finalNbPassages');
|
||||
|
||||
// Récupérer les coordonnées GPS pour un nouveau passage
|
||||
String finalGpsLat = '0.0';
|
||||
String finalGpsLng = '0.0';
|
||||
if (widget.passage == null) {
|
||||
// Nouveau passage : tenter de récupérer la position GPS actuelle
|
||||
debugPrint('🟢 [SAVE] Récupération de la position GPS...');
|
||||
try {
|
||||
final position = await LocationService.getCurrentPosition();
|
||||
if (position != null) {
|
||||
finalGpsLat = position.latitude.toString();
|
||||
finalGpsLng = position.longitude.toString();
|
||||
debugPrint('🟢 [SAVE] GPS récupéré: lat=$finalGpsLat, lng=$finalGpsLng');
|
||||
} else {
|
||||
debugPrint('🟢 [SAVE] GPS non disponible, utilisation de 0.0 (l\'API utilisera le géocodage)');
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('⚠️ [SAVE] Erreur récupération GPS: $e - l\'API utilisera le géocodage');
|
||||
}
|
||||
} catch (_) {}
|
||||
} else {
|
||||
// Modification : conserver les coordonnées existantes
|
||||
finalGpsLat = widget.passage!.gpsLat;
|
||||
finalGpsLng = widget.passage!.gpsLng;
|
||||
}
|
||||
@@ -537,38 +441,25 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
isSynced: false,
|
||||
);
|
||||
|
||||
// Sauvegarder le passage d'abord
|
||||
debugPrint('🟢 [SAVE] Préparation sauvegarde passage');
|
||||
// Sauvegarder le passage
|
||||
PassageModel? savedPassage;
|
||||
if (widget.passage == null || widget.passage!.id == 0) {
|
||||
// Création d'un nouveau passage (passage null OU id=0)
|
||||
debugPrint('🟢 [SAVE] Création d\'un nouveau passage');
|
||||
savedPassage = await widget.passageRepository.createPassageWithReturn(passageData);
|
||||
debugPrint('🟢 [SAVE] Passage créé avec ID: ${savedPassage?.id}');
|
||||
|
||||
if (savedPassage == null) {
|
||||
debugPrint('❌ [SAVE] ERREUR: savedPassage est null après création');
|
||||
throw Exception("Échec de la création du passage");
|
||||
}
|
||||
} else {
|
||||
// Mise à jour d'un passage existant
|
||||
debugPrint('🟢 [SAVE] Mise à jour passage existant ID: ${widget.passage!.id}');
|
||||
await widget.passageRepository.updatePassage(passageData);
|
||||
debugPrint('🟢 [SAVE] Mise à jour réussie');
|
||||
savedPassage = passageData;
|
||||
}
|
||||
|
||||
// Garantir le type non-nullable après la vérification
|
||||
final confirmedPassage = savedPassage;
|
||||
debugPrint('✅ [SAVE] Passage sauvegardé avec succès ID: ${confirmedPassage.id}');
|
||||
|
||||
// Mémoriser l'adresse pour la prochaine création de passage
|
||||
debugPrint('🟢 [SAVE] Mémorisation adresse');
|
||||
await _saveLastPassageAddress();
|
||||
|
||||
// Propager la résidence aux autres passages de l'immeuble si nécessaire
|
||||
if (_fkHabitat == 2 && _residenceController.text.trim().isNotEmpty) {
|
||||
debugPrint('🟢 [SAVE] Propagation résidence à l\'immeuble');
|
||||
await _propagateResidenceToBuilding(confirmedPassage);
|
||||
}
|
||||
|
||||
@@ -605,16 +496,12 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
final paymentSuccess = await _attemptTapToPayWithPassage(confirmedPassage, montant);
|
||||
|
||||
if (paymentSuccess) {
|
||||
// Fermer le formulaire en cas de succès
|
||||
if (mounted) {
|
||||
Navigator.of(context, rootNavigator: false).pop();
|
||||
widget.onSuccess?.call();
|
||||
}
|
||||
} else {
|
||||
debugPrint('⚠️ Paiement Tap to Pay échoué - formulaire reste ouvert');
|
||||
// Ne pas fermer le formulaire en cas d'échec
|
||||
// L'utilisateur peut réessayer ou annuler
|
||||
}
|
||||
// Si échec, le formulaire reste ouvert pour réessayer
|
||||
},
|
||||
onQRCodeCompleted: () {
|
||||
// Pour QR Code: fermer le formulaire après l'affichage du QR
|
||||
@@ -667,17 +554,10 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
}
|
||||
}
|
||||
} catch (e, stackTrace) {
|
||||
// Masquer le loading
|
||||
debugPrint('❌ [SAVE] ERREUR CAPTURÉE');
|
||||
debugPrint('❌ [SAVE] Type erreur: ${e.runtimeType}');
|
||||
debugPrint('❌ [SAVE] Message erreur: $e');
|
||||
debugPrint('❌ [SAVE] Stack trace:\n$stackTrace');
|
||||
|
||||
debugPrint('❌ Erreur sauvegarde passage: $e\n$stackTrace');
|
||||
LoadingSpinOverlayUtils.hideSpecific(overlay);
|
||||
|
||||
// Afficher l'erreur
|
||||
final errorMessage = ApiException.fromError(e).message;
|
||||
debugPrint('❌ [SAVE] Message d\'erreur formaté: $errorMessage');
|
||||
|
||||
if (mounted) {
|
||||
await ResultDialog.show(
|
||||
@@ -687,23 +567,17 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
debugPrint('🟢 [SAVE] Bloc finally - Nettoyage');
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isSubmitting = false;
|
||||
});
|
||||
debugPrint('🟢 [SAVE] _isSubmitting = false');
|
||||
}
|
||||
debugPrint('🟢 [SAVE] Fin _savePassage');
|
||||
}
|
||||
}
|
||||
|
||||
/// Mémoriser l'adresse du passage pour la prochaine création
|
||||
Future<void> _saveLastPassageAddress() async {
|
||||
try {
|
||||
debugPrint('🟡 [ADDRESS] Début mémorisation adresse');
|
||||
debugPrint('🟡 [ADDRESS] _settingsBox.isOpen: ${_settingsBox.isOpen}');
|
||||
|
||||
await _settingsBox.put('lastPassageNumero', _numeroController.text.trim());
|
||||
await _settingsBox.put('lastPassageRueBis', _rueBisController.text.trim());
|
||||
await _settingsBox.put('lastPassageRue', _rueController.text.trim());
|
||||
@@ -712,61 +586,34 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
await _settingsBox.put('lastPassageFkHabitat', _fkHabitat);
|
||||
await _settingsBox.put('lastPassageAppt', _apptController.text.trim());
|
||||
await _settingsBox.put('lastPassageNiveau', _niveauController.text.trim());
|
||||
|
||||
debugPrint('✅ [ADDRESS] Adresse mémorisée avec succès');
|
||||
} catch (e, stackTrace) {
|
||||
debugPrint('❌ [ADDRESS] Erreur lors de la mémorisation: $e');
|
||||
debugPrint('❌ [ADDRESS] Stack trace:\n$stackTrace');
|
||||
} catch (e) {
|
||||
debugPrint('❌ Erreur mémorisation adresse: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Propager la résidence aux autres passages de l'immeuble (fkType=2, même adresse, résidence vide)
|
||||
Future<void> _propagateResidenceToBuilding(PassageModel savedPassage) async {
|
||||
try {
|
||||
debugPrint('🟡 [PROPAGATE] Début propagation résidence');
|
||||
|
||||
final passagesBox = Hive.box<PassageModel>(AppKeys.passagesBoxName);
|
||||
debugPrint('🟡 [PROPAGATE] passagesBox.isOpen: ${passagesBox.isOpen}');
|
||||
debugPrint('🟡 [PROPAGATE] passagesBox.length: ${passagesBox.length}');
|
||||
|
||||
final residence = _residenceController.text.trim();
|
||||
debugPrint('🟡 [PROPAGATE] résidence: "$residence"');
|
||||
|
||||
// Clé d'adresse du passage sauvegardé
|
||||
final addressKey = '${savedPassage.numero}|${savedPassage.rueBis}|${savedPassage.rue}|${savedPassage.ville}';
|
||||
debugPrint('🟡 [PROPAGATE] addressKey: "$addressKey"');
|
||||
|
||||
int updatedCount = 0;
|
||||
|
||||
// Parcourir tous les passages
|
||||
for (int i = 0; i < passagesBox.length; i++) {
|
||||
final passage = passagesBox.getAt(i);
|
||||
if (passage != null) {
|
||||
// Vérifier les critères
|
||||
final passageAddressKey = '${passage.numero}|${passage.rueBis}|${passage.rue}|${passage.ville}';
|
||||
|
||||
if (passage.id != savedPassage.id && // Pas le passage actuel
|
||||
passage.fkHabitat == 2 && // Appartement
|
||||
passageAddressKey == addressKey && // Même adresse
|
||||
passage.residence.trim().isEmpty) { // Résidence vide
|
||||
|
||||
debugPrint('🟡 [PROPAGATE] Mise à jour passage ID: ${passage.id}');
|
||||
// Mettre à jour la résidence dans Hive
|
||||
if (passage.id != savedPassage.id &&
|
||||
passage.fkHabitat == 2 &&
|
||||
passageAddressKey == addressKey &&
|
||||
passage.residence.trim().isEmpty) {
|
||||
final updatedPassage = passage.copyWith(residence: residence);
|
||||
await passagesBox.put(passage.key, updatedPassage);
|
||||
updatedCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updatedCount > 0) {
|
||||
debugPrint('✅ [PROPAGATE] Résidence propagée à $updatedCount passage(s)');
|
||||
} else {
|
||||
debugPrint('✅ [PROPAGATE] Aucun passage à mettre à jour');
|
||||
}
|
||||
} catch (e, stackTrace) {
|
||||
debugPrint('❌ [PROPAGATE] Erreur lors de la propagation: $e');
|
||||
debugPrint('❌ [PROPAGATE] Stack trace:\n$stackTrace');
|
||||
} catch (e) {
|
||||
debugPrint('❌ Erreur propagation résidence: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -780,24 +627,110 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
if (currentUser != null && currentUser.fkEntite != null) {
|
||||
final userAmicale = widget.amicaleRepository.getAmicaleById(currentUser.fkEntite!);
|
||||
if (userAmicale != null) {
|
||||
// Si chkLotActif = false (0), on ne doit pas afficher le type Lot (5)
|
||||
showLotType = userAmicale.chkLotActif;
|
||||
debugPrint('Amicale ${userAmicale.name}: chkLotActif = $showLotType');
|
||||
}
|
||||
}
|
||||
|
||||
// Filtrer les types de passages en fonction de chkLotActif
|
||||
final filteredTypes = Map<int, Map<String, dynamic>>.from(AppKeys.typesPassages);
|
||||
if (!showLotType) {
|
||||
filteredTypes.remove(5); // Retirer le type "Lot" si chkLotActif = 0
|
||||
debugPrint('Type Lot (5) masqué car chkLotActif = false');
|
||||
filteredTypes.remove(5);
|
||||
}
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Afficher les infos du passage si modification
|
||||
if (widget.passage != null) ...[
|
||||
// Adresse du passage
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.primary.withOpacity(0.05),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary.withOpacity(0.2),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Adresse principale
|
||||
Text(
|
||||
'${widget.passage!.numero} ${widget.passage!.rueBis} ${widget.passage!.rue}'.trim().replaceAll(RegExp(r'\s+'), ' '),
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
widget.passage!.ville,
|
||||
style: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: theme.colorScheme.onSurface.withOpacity(0.7),
|
||||
),
|
||||
),
|
||||
// Infos appartement si fkHabitat == 2
|
||||
if (widget.passage!.fkHabitat == 2) ...[
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
if (widget.passage!.niveau.isNotEmpty) ...[
|
||||
Icon(Icons.stairs, size: 16, color: theme.colorScheme.primary),
|
||||
const SizedBox(width: 4),
|
||||
Text('Niveau ${widget.passage!.niveau}'),
|
||||
const SizedBox(width: 12),
|
||||
],
|
||||
if (widget.passage!.appt.isNotEmpty) ...[
|
||||
Icon(Icons.door_front_door, size: 16, color: theme.colorScheme.primary),
|
||||
const SizedBox(width: 4),
|
||||
Text('Appt ${widget.passage!.appt}'),
|
||||
],
|
||||
],
|
||||
),
|
||||
],
|
||||
// Afficher le nom de l'habitant (pour maison et appartement)
|
||||
if (widget.passage!.name.isNotEmpty) ...[
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.person, size: 16, color: theme.colorScheme.primary),
|
||||
const SizedBox(width: 4),
|
||||
Expanded(child: Text(widget.passage!.name)),
|
||||
],
|
||||
),
|
||||
],
|
||||
// Afficher la remarque si renseignée
|
||||
if (widget.passage!.remarque.isNotEmpty) ...[
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(Icons.note, size: 16, color: theme.colorScheme.primary),
|
||||
const SizedBox(width: 4),
|
||||
Expanded(
|
||||
child: Text(
|
||||
widget.passage!.remarque,
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
fontStyle: FontStyle.italic,
|
||||
color: theme.colorScheme.onSurface.withOpacity(0.7),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Divider(),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
Text(
|
||||
'Type de passage',
|
||||
widget.passage != null
|
||||
? 'Choisir le nouveau type de ce passage'
|
||||
: 'Type de passage',
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: theme.colorScheme.primary,
|
||||
@@ -810,7 +743,7 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
childAspectRatio:
|
||||
MediaQuery.of(context).size.width < 600 ? 1.8 : 2.5,
|
||||
MediaQuery.of(context).size.width < 600 ? 1.4 : 2.5,
|
||||
crossAxisSpacing: 12,
|
||||
mainAxisSpacing: 12,
|
||||
),
|
||||
@@ -821,7 +754,6 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
final typeData = filteredTypes[typeId];
|
||||
|
||||
if (typeData == null) {
|
||||
debugPrint('ERREUR: typeData null pour typeId: $typeId');
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
@@ -881,8 +813,7 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
),
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
debugPrint('ERREUR dans itemBuilder pour index $index: $e');
|
||||
} catch (_) {
|
||||
return const SizedBox();
|
||||
}
|
||||
},
|
||||
@@ -893,9 +824,6 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
|
||||
Widget _buildPassageForm() {
|
||||
try {
|
||||
debugPrint('=== DEBUT _buildPassageForm ===');
|
||||
|
||||
debugPrint('Building Form...');
|
||||
return Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
@@ -1362,11 +1290,8 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
],
|
||||
),
|
||||
);
|
||||
} catch (e, stackTrace) {
|
||||
debugPrint('=== ERREUR _buildPassageForm ===');
|
||||
debugPrint('Erreur: $e');
|
||||
debugPrint('StackTrace: $stackTrace');
|
||||
|
||||
} catch (e) {
|
||||
debugPrint('❌ Erreur _buildPassageForm: $e');
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
@@ -1526,17 +1451,10 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (!_showForm) ...[
|
||||
() {
|
||||
debugPrint('Building passage type selection...');
|
||||
return _buildPassageTypeSelection();
|
||||
}(),
|
||||
] else ...[
|
||||
() {
|
||||
debugPrint('Building passage form...');
|
||||
return _buildPassageForm();
|
||||
}(),
|
||||
],
|
||||
if (!_showForm)
|
||||
_buildPassageTypeSelection()
|
||||
else
|
||||
_buildPassageForm(),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -1690,10 +1608,9 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
);
|
||||
|
||||
// Envoyer la mise à jour à l'API (sera fait de manière asynchrone)
|
||||
widget.passageRepository.updatePassage(updatedPassage).then((_) {
|
||||
debugPrint('✅ Passage mis à jour avec stripe_payment_id: $paymentIntentId');
|
||||
}).catchError((error) {
|
||||
debugPrint('❌ Erreur mise à jour passage: $error');
|
||||
widget.passageRepository.updatePassage(updatedPassage).catchError((error) {
|
||||
debugPrint('❌ Erreur mise à jour passage stripe: $error');
|
||||
return false;
|
||||
});
|
||||
|
||||
setState(() {
|
||||
@@ -1720,7 +1637,7 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
|
||||
return false;
|
||||
} catch (e) {
|
||||
debugPrint('Erreur Tap to Pay: $e');
|
||||
debugPrint('❌ Erreur Tap to Pay: $e');
|
||||
if (mounted) {
|
||||
await ResultDialog.show(
|
||||
context: context,
|
||||
@@ -1735,10 +1652,7 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
try {
|
||||
debugPrint('=== DEBUT PassageFormDialog.build ===');
|
||||
|
||||
final isMobile = _isMobile(context);
|
||||
debugPrint('Platform mobile détectée: $isMobile');
|
||||
|
||||
if (isMobile) {
|
||||
// Mode plein écran pour mobile
|
||||
@@ -1786,12 +1700,8 @@ class _PassageFormDialogState extends State<PassageFormDialog> {
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (e, stackTrace) {
|
||||
debugPrint('=== ERREUR PassageFormDialog.build ===');
|
||||
debugPrint('Erreur: $e');
|
||||
debugPrint('StackTrace: $stackTrace');
|
||||
|
||||
// Retourner un widget d'erreur simple
|
||||
} catch (e) {
|
||||
debugPrint('❌ Erreur PassageFormDialog.build: $e');
|
||||
return Dialog(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
@@ -1980,9 +1890,7 @@ class _TapToPayFlowDialogState extends State<_TapToPayFlowDialog> {
|
||||
|
||||
// Annuler le PaymentIntent si créé pour permettre une nouvelle tentative
|
||||
if (shouldCancelPayment && _paymentIntentId != null) {
|
||||
StripeTapToPayService.instance.cancelPayment(_paymentIntentId!).catchError((cancelError) {
|
||||
debugPrint('⚠️ Erreur annulation PaymentIntent: $cancelError');
|
||||
});
|
||||
StripeTapToPayService.instance.cancelPayment(_paymentIntentId!).catchError((_) {});
|
||||
}
|
||||
|
||||
setState(() {
|
||||
|
||||
Reference in New Issue
Block a user