207 lines
5.6 KiB
Dart
207 lines
5.6 KiB
Dart
import 'dart:convert';
|
|
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
|
|
class Trip {
|
|
final String? id;
|
|
final String title;
|
|
final String description;
|
|
final String location;
|
|
final DateTime startDate;
|
|
final DateTime endDate;
|
|
final double? budget;
|
|
final List<String> participants;
|
|
final String createdBy;
|
|
final DateTime createdAt;
|
|
final DateTime updatedAt;
|
|
final String status;
|
|
|
|
Trip({
|
|
this.id,
|
|
required this.title,
|
|
required this.description,
|
|
required this.location,
|
|
required this.startDate,
|
|
required this.endDate,
|
|
this.budget,
|
|
required this.participants,
|
|
required this.createdBy,
|
|
required this.createdAt,
|
|
required this.updatedAt,
|
|
this.status = 'draft',
|
|
});
|
|
|
|
// NOUVELLE MÉTHODE HELPER pour convertir n'importe quel format de date
|
|
static DateTime _parseDateTime(dynamic value) {
|
|
if (value == null) return DateTime.now();
|
|
|
|
// Si c'est déjà un Timestamp Firebase
|
|
if (value is Timestamp) {
|
|
return value.toDate();
|
|
}
|
|
|
|
// Si c'est un int (millisecondes depuis epoch)
|
|
if (value is int) {
|
|
return DateTime.fromMillisecondsSinceEpoch(value);
|
|
}
|
|
|
|
// Si c'est un String (ISO 8601)
|
|
if (value is String) {
|
|
return DateTime.parse(value);
|
|
}
|
|
|
|
// Si c'est déjà un DateTime
|
|
if (value is DateTime) {
|
|
return value;
|
|
}
|
|
|
|
// Par défaut
|
|
return DateTime.now();
|
|
}
|
|
|
|
// Constructeur pour créer un Trip depuis un Map (utile pour Firebase)
|
|
factory Trip.fromMap(Map<String, dynamic> map, String id) {
|
|
try {
|
|
return Trip(
|
|
id: id,
|
|
title: map['title'] as String? ?? '',
|
|
description: map['description'] as String? ?? '',
|
|
location: map['location'] as String? ?? '',
|
|
startDate: _parseDateTime(map['startDate']),
|
|
endDate: _parseDateTime(map['endDate']),
|
|
budget: (map['budget'] as num?)?.toDouble(),
|
|
createdBy: map['createdBy'] as String? ?? '',
|
|
participants: List<String>.from(map['participants'] as List? ?? []),
|
|
createdAt: _parseDateTime(map['createdAt']),
|
|
updatedAt: _parseDateTime(map['updatedAt']),
|
|
status: map['status'] as String? ?? 'draft',
|
|
);
|
|
} catch (e) {
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
// MODIFIÉ : Convertir en Map avec Timestamp pour Firestore
|
|
Map<String, dynamic> toMap() {
|
|
return {
|
|
'title': title,
|
|
'description': description,
|
|
'location': location,
|
|
'startDate': Timestamp.fromDate(startDate),
|
|
'endDate': Timestamp.fromDate(endDate),
|
|
'budget': budget,
|
|
'participants': participants,
|
|
'createdBy': createdBy,
|
|
'createdAt': Timestamp.fromDate(createdAt),
|
|
'updatedAt': Timestamp.fromDate(updatedAt),
|
|
'status': status,
|
|
};
|
|
}
|
|
|
|
// Méthode pour convertir un Trip en JSON
|
|
String toJson() {
|
|
return json.encode(toMap());
|
|
}
|
|
|
|
// Méthode pour créer une copie avec des modifications
|
|
Trip copyWith({
|
|
String? id,
|
|
String? title,
|
|
String? description,
|
|
String? location,
|
|
DateTime? startDate,
|
|
DateTime? endDate,
|
|
double? budget,
|
|
List<String>? participants,
|
|
String? createdBy,
|
|
DateTime? createdAt,
|
|
DateTime? updatedAt,
|
|
String? status,
|
|
}) {
|
|
return Trip(
|
|
id: id ?? this.id,
|
|
title: title ?? this.title,
|
|
description: description ?? this.description,
|
|
location: location ?? this.location,
|
|
startDate: startDate ?? this.startDate,
|
|
endDate: endDate ?? this.endDate,
|
|
budget: budget ?? this.budget,
|
|
participants: participants ?? this.participants,
|
|
createdBy: createdBy ?? this.createdBy,
|
|
createdAt: createdAt ?? this.createdAt,
|
|
updatedAt: updatedAt ?? this.updatedAt,
|
|
status: status ?? this.status,
|
|
);
|
|
}
|
|
|
|
// Méthode pour obtenir la durée du voyage en jours
|
|
int get durationInDays {
|
|
return endDate.difference(startDate).inDays + 1;
|
|
}
|
|
|
|
// Méthode pour vérifier si le voyage est en cours
|
|
bool get isActive {
|
|
final now = DateTime.now();
|
|
return status == 'active' &&
|
|
now.isAfter(startDate) &&
|
|
now.isBefore(endDate.add(Duration(days: 1)));
|
|
}
|
|
|
|
// Méthode pour vérifier si le voyage est à venir
|
|
bool get isUpcoming {
|
|
final now = DateTime.now();
|
|
return status == 'active' && now.isBefore(startDate);
|
|
}
|
|
|
|
// Méthode pour vérifier si le voyage est terminé
|
|
bool get isCompleted {
|
|
final now = DateTime.now();
|
|
return status == 'completed' ||
|
|
(status == 'active' && now.isAfter(endDate));
|
|
}
|
|
|
|
// Méthode pour obtenir le budget par participant
|
|
double? get budgetPerParticipant {
|
|
if (budget == null || participants.isEmpty) return null;
|
|
return budget! / (participants.length + 1);
|
|
}
|
|
|
|
// Méthode pour obtenir le nombre total de participants (incluant le créateur)
|
|
int get totalParticipants {
|
|
return participants.length + 1;
|
|
}
|
|
|
|
// Méthode pour formater les dates
|
|
String get formattedDates {
|
|
return '${startDate.day}/${startDate.month}/${startDate.year} - ${endDate.day}/${endDate.month}/${endDate.year}';
|
|
}
|
|
|
|
// Méthode pour obtenir le statut formaté
|
|
String get formattedStatus {
|
|
switch (status) {
|
|
case 'draft':
|
|
return 'Brouillon';
|
|
case 'active':
|
|
return 'Actif';
|
|
case 'completed':
|
|
return 'Terminé';
|
|
case 'cancelled':
|
|
return 'Annulé';
|
|
default:
|
|
return 'Inconnu';
|
|
}
|
|
}
|
|
|
|
@override
|
|
String toString() {
|
|
return 'Trip(id: $id, title: $title, location: $location, status: $status)';
|
|
}
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (identical(this, other)) return true;
|
|
return other is Trip && other.id == id;
|
|
}
|
|
|
|
@override
|
|
int get hashCode => id.hashCode;
|
|
} |