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:
ElPoyo
2025-10-10 19:20:38 +02:00
parent aae68f8ab7
commit 4128ddc34a
13 changed files with 850 additions and 299 deletions

View File

@@ -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,

View File

@@ -6,7 +6,7 @@ class EventOption {
final String details;
final double valMin;
final double valMax;
final List<DocumentReference> eventTypes;
final List<String> eventTypes; // Changé de List<DocumentReference> à List<String>
EventOption({
required this.id,
@@ -25,7 +25,7 @@ class EventOption {
valMin: (map['valMin'] ?? 0.0).toDouble(),
valMax: (map['valMax'] ?? 0.0).toDouble(),
eventTypes: (map['eventTypes'] as List<dynamic>? ?? [])
.whereType<DocumentReference>()
.map((e) => e.toString()) // Convertit en String (supporte IDs et références)
.toList(),
);
}