Files
EM2_ERP/em2rp/lib/models/event_model.dart
2025-10-10 19:20:38 +02:00

226 lines
6.8 KiB
Dart

import 'package:cloud_firestore/cloud_firestore.dart';
enum EventStatus {
confirmed,
canceled,
waitingForApproval,
}
String eventStatusToString(EventStatus status) {
switch (status) {
case EventStatus.confirmed:
return 'CONFIRMED';
case EventStatus.canceled:
return 'CANCELED';
case EventStatus.waitingForApproval:
default:
return 'WAITING_FOR_APPROVAL';
}
}
EventStatus eventStatusFromString(String? status) {
switch (status) {
case 'CONFIRMED':
return EventStatus.confirmed;
case 'CANCELED':
return EventStatus.canceled;
case 'WAITING_FOR_APPROVAL':
default:
return EventStatus.waitingForApproval;
}
}
class EventModel {
final String id;
final String name;
final String description;
final DateTime startDateTime;
final DateTime endDateTime;
final double basePrice;
final int installationTime;
final int disassemblyTime;
final String eventTypeId;
final DocumentReference? eventTypeRef;
final String customerId;
final String address;
final double latitude;
final double longitude;
final List<DocumentReference> workforce;
final List<Map<String, String>> documents;
final List<Map<String, dynamic>> options;
final EventStatus status;
EventModel({
required this.id,
required this.name,
required this.description,
required this.startDateTime,
required this.endDateTime,
required this.basePrice,
required this.installationTime,
required this.disassemblyTime,
required this.eventTypeId,
this.eventTypeRef,
required this.customerId,
required this.address,
required this.latitude,
required this.longitude,
required this.workforce,
required this.documents,
this.options = const [],
this.status = EventStatus.waitingForApproval,
});
factory EventModel.fromMap(Map<String, dynamic> map, String id) {
try {
// Gestion sécurisée des références workforce
final List<dynamic> workforceRefs = map['workforce'] ?? [];
final List<DocumentReference> safeWorkforce = [];
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) {
docs.add(Map<String, String>.from(e));
} else if (e is String) {
final fileName = Uri.decodeComponent(
e.split('/').last.split('?').first,
);
docs.add({'name': fileName, 'url': 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) {
options.add(Map<String, dynamic>.from(e));
}
} 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() {
return {
'Name': name,
'Description': description,
'StartDateTime': Timestamp.fromDate(startDateTime),
'EndDateTime': Timestamp.fromDate(endDateTime),
'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,
'Address': address,
'Position': GeoPoint(latitude, longitude),
'Latitude': latitude,
'Longitude': longitude,
'workforce': workforce,
'documents': documents,
'options': options,
'status': eventStatusToString(status),
};
}
}