Modif de l'affichage des données d'un événement et de l'afichage de la création/édition
Options sont maintenant géres dans firebase
This commit is contained in:
		| @@ -72,62 +72,129 @@ class EventModel { | ||||
|   }); | ||||
|  | ||||
|   factory EventModel.fromMap(Map<String, dynamic> map, String id) { | ||||
|     final List<dynamic> workforceRefs = map['workforce'] ?? []; | ||||
|     final Timestamp? startTimestamp = map['StartDateTime'] as Timestamp?; | ||||
|     final Timestamp? endTimestamp = map['EndDateTime'] as Timestamp?; | ||||
|     try { | ||||
|       // Gestion sécurisée des références workforce | ||||
|       final List<dynamic> workforceRefs = map['workforce'] ?? []; | ||||
|       final List<DocumentReference> safeWorkforce = []; | ||||
|  | ||||
|     final docsRaw = map['documents'] ?? []; | ||||
|     final docs = docsRaw is List | ||||
|         ? docsRaw.map<Map<String, String>>((e) { | ||||
|       for (var ref in workforceRefs) { | ||||
|         if (ref is DocumentReference) { | ||||
|           safeWorkforce.add(ref); | ||||
|         } else { | ||||
|           print('Warning: Invalid workforce reference in event $id: $ref'); | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       // Gestion sécurisée des timestamps | ||||
|       final Timestamp? startTimestamp = map['StartDateTime'] as Timestamp?; | ||||
|       final Timestamp? endTimestamp = map['EndDateTime'] as Timestamp?; | ||||
|  | ||||
|       final DateTime startDate = startTimestamp?.toDate() ?? DateTime.now(); | ||||
|       final DateTime endDate = endTimestamp?.toDate() ?? | ||||
|           startDate.add(const Duration(hours: 1)); | ||||
|  | ||||
|       // Gestion sécurisée des documents | ||||
|       final docsRaw = map['documents'] ?? []; | ||||
|       final List<Map<String, String>> docs = []; | ||||
|  | ||||
|       if (docsRaw is List) { | ||||
|         for (var e in docsRaw) { | ||||
|           try { | ||||
|             if (e is Map) { | ||||
|               return Map<String, String>.from(e); | ||||
|               docs.add(Map<String, String>.from(e)); | ||||
|             } else if (e is String) { | ||||
|               final fileName = Uri.decodeComponent( | ||||
|                 e.split('/').last.split('?').first, | ||||
|               ); | ||||
|               return {'name': fileName, 'url': e}; | ||||
|             } else { | ||||
|               return {}; | ||||
|               docs.add({'name': fileName, 'url': e}); | ||||
|             } | ||||
|           }).toList() | ||||
|         : <Map<String, String>>[]; | ||||
|     final optionsRaw = map['options'] ?? []; | ||||
|     final options = optionsRaw is List | ||||
|         ? optionsRaw.map<Map<String, dynamic>>((e) { | ||||
|           } catch (docError) { | ||||
|             print('Warning: Failed to parse document in event $id: $docError'); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       // Gestion sécurisée des options | ||||
|       final optionsRaw = map['options'] ?? []; | ||||
|       final List<Map<String, dynamic>> options = []; | ||||
|  | ||||
|       if (optionsRaw is List) { | ||||
|         for (var e in optionsRaw) { | ||||
|           try { | ||||
|             if (e is Map) { | ||||
|               return Map<String, dynamic>.from(e); | ||||
|             } else { | ||||
|               return {}; | ||||
|               options.add(Map<String, dynamic>.from(e)); | ||||
|             } | ||||
|           }).toList() | ||||
|         : <Map<String, dynamic>>[]; | ||||
|     return EventModel( | ||||
|       id: id, | ||||
|       name: map['Name'] ?? '', | ||||
|       description: map['Description'] ?? '', | ||||
|       startDateTime: startTimestamp?.toDate() ?? DateTime.now(), | ||||
|       endDateTime: endTimestamp?.toDate() ?? | ||||
|           DateTime.now().add(const Duration(hours: 1)), | ||||
|       basePrice: (map['BasePrice'] ?? map['Price'] ?? 0.0).toDouble(), | ||||
|       installationTime: map['InstallationTime'] ?? 0, | ||||
|       disassemblyTime: map['DisassemblyTime'] ?? 0, | ||||
|       eventTypeId: map['EventType'] is DocumentReference | ||||
|           ? (map['EventType'] as DocumentReference).id | ||||
|           : map['EventType'] ?? '', | ||||
|       eventTypeRef: map['EventType'] is DocumentReference | ||||
|           ? map['EventType'] as DocumentReference | ||||
|           : null, | ||||
|       customerId: map['customer'] is DocumentReference | ||||
|           ? (map['customer'] as DocumentReference).id | ||||
|           : '', | ||||
|       address: map['Address'] ?? '', | ||||
|       latitude: (map['Latitude'] ?? 0.0).toDouble(), | ||||
|       longitude: (map['Longitude'] ?? 0.0).toDouble(), | ||||
|       workforce: workforceRefs.whereType<DocumentReference>().toList(), | ||||
|       documents: docs, | ||||
|       options: options, | ||||
|       status: eventStatusFromString(map['status'] as String?), | ||||
|     ); | ||||
|           } catch (optionError) { | ||||
|             print('Warning: Failed to parse option in event $id: $optionError'); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       // Gestion sécurisée de l'EventType | ||||
|       String eventTypeId = ''; | ||||
|       DocumentReference? eventTypeRef; | ||||
|  | ||||
|       if (map['EventType'] is DocumentReference) { | ||||
|         eventTypeRef = map['EventType'] as DocumentReference; | ||||
|         eventTypeId = eventTypeRef.id; | ||||
|       } else if (map['EventType'] is String) { | ||||
|         eventTypeId = map['EventType'] as String; | ||||
|       } | ||||
|  | ||||
|       // Gestion sécurisée du customer | ||||
|       String customerId = ''; | ||||
|       if (map['customer'] is DocumentReference) { | ||||
|         customerId = (map['customer'] as DocumentReference).id; | ||||
|       } else if (map['customer'] is String) { | ||||
|         customerId = map['customer'] as String; | ||||
|       } | ||||
|  | ||||
|       return EventModel( | ||||
|         id: id, | ||||
|         name: (map['Name'] ?? '').toString().trim(), | ||||
|         description: (map['Description'] ?? '').toString(), | ||||
|         startDateTime: startDate, | ||||
|         endDateTime: endDate, | ||||
|         basePrice: _parseDouble(map['BasePrice'] ?? map['Price'] ?? 0.0), | ||||
|         installationTime: _parseInt(map['InstallationTime'] ?? 0), | ||||
|         disassemblyTime: _parseInt(map['DisassemblyTime'] ?? 0), | ||||
|         eventTypeId: eventTypeId, | ||||
|         eventTypeRef: eventTypeRef, | ||||
|         customerId: customerId, | ||||
|         address: (map['Address'] ?? '').toString(), | ||||
|         latitude: _parseDouble(map['Latitude'] ?? 0.0), | ||||
|         longitude: _parseDouble(map['Longitude'] ?? 0.0), | ||||
|         workforce: safeWorkforce, | ||||
|         documents: docs, | ||||
|         options: options, | ||||
|         status: eventStatusFromString(map['status'] as String?), | ||||
|       ); | ||||
|     } catch (e) { | ||||
|       print('Error parsing event $id: $e'); | ||||
|       print('Event data: $map'); | ||||
|       rethrow; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Méthodes utilitaires pour le parsing sécurisé | ||||
|   static double _parseDouble(dynamic value) { | ||||
|     if (value is double) return value; | ||||
|     if (value is int) return value.toDouble(); | ||||
|     if (value is String) { | ||||
|       final parsed = double.tryParse(value); | ||||
|       if (parsed != null) return parsed; | ||||
|     } | ||||
|     return 0.0; | ||||
|   } | ||||
|  | ||||
|   static int _parseInt(dynamic value) { | ||||
|     if (value is int) return value; | ||||
|     if (value is double) return value.toInt(); | ||||
|     if (value is String) { | ||||
|       final parsed = int.tryParse(value); | ||||
|       if (parsed != null) return parsed; | ||||
|     } | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
|   Map<String, dynamic> toMap() { | ||||
| @@ -139,8 +206,12 @@ class EventModel { | ||||
|       'BasePrice': basePrice, | ||||
|       'InstallationTime': installationTime, | ||||
|       'DisassemblyTime': disassemblyTime, | ||||
|       'EventType': eventTypeId.isNotEmpty ? FirebaseFirestore.instance.collection('eventTypes').doc(eventTypeId) : null, | ||||
|       'customer': customerId.isNotEmpty ? FirebaseFirestore.instance.collection('customers').doc(customerId) : null, | ||||
|       'EventType': eventTypeId.isNotEmpty | ||||
|           ? FirebaseFirestore.instance.collection('eventTypes').doc(eventTypeId) | ||||
|           : null, | ||||
|       'customer': customerId.isNotEmpty | ||||
|           ? FirebaseFirestore.instance.collection('customers').doc(customerId) | ||||
|           : null, | ||||
|       'Address': address, | ||||
|       'Position': GeoPoint(latitude, longitude), | ||||
|       'Latitude': latitude, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 ElPoyo
					ElPoyo