import 'package:cloud_firestore/cloud_firestore.dart'; enum RegistrationType { ordinary, overtime, oncall, travel, } enum SyncStatus { synced, pending, conflict, } class TimeBreak { final DateTime startTime; final DateTime endTime; final int duration; // in minutes TimeBreak({ required this.startTime, required this.endTime, required this.duration, }); factory TimeBreak.fromMap(Map map) { return TimeBreak( startTime: (map['startTime'] as Timestamp).toDate(), endTime: (map['endTime'] as Timestamp).toDate(), duration: map['duration'] ?? 0, ); } Map toMap() { return { 'startTime': Timestamp.fromDate(startTime), 'endTime': Timestamp.fromDate(endTime), 'duration': duration, }; } } class TimeRegistration { final String id; final String userId; final String organizationId; final DateTime startTime; final DateTime? endTime; final int duration; // in minutes final RegistrationType type; final String? projectId; final String? customerId; final String? comment; final List breaks; final DateTime createdAt; final DateTime updatedAt; final String createdBy; final String? lastModifiedBy; final List deviations; final bool isManual; final SyncStatus syncStatus; TimeRegistration({ required this.id, required this.userId, required this.organizationId, required this.startTime, this.endTime, required this.duration, this.type = RegistrationType.ordinary, this.projectId, this.customerId, this.comment, this.breaks = const [], required this.createdAt, required this.updatedAt, required this.createdBy, this.lastModifiedBy, this.deviations = const [], this.isManual = false, this.syncStatus = SyncStatus.synced, }); factory TimeRegistration.fromFirestore(DocumentSnapshot doc) { final data = doc.data() as Map; return TimeRegistration( id: doc.id, userId: data['userId'] ?? '', organizationId: data['organizationId'] ?? '', startTime: (data['startTime'] as Timestamp).toDate(), endTime: data['endTime'] != null ? (data['endTime'] as Timestamp).toDate() : null, duration: data['duration'] ?? 0, type: _parseType(data['type']), projectId: data['projectId'], customerId: data['customerId'], comment: data['comment'], breaks: (data['breaks'] as List?) ?.map((b) => TimeBreak.fromMap(b as Map)) .toList() ?? [], createdAt: (data['createdAt'] as Timestamp).toDate(), updatedAt: (data['updatedAt'] as Timestamp).toDate(), createdBy: data['createdBy'] ?? '', lastModifiedBy: data['lastModifiedBy'], deviations: List.from(data['deviations'] ?? []), isManual: data['isManual'] ?? false, syncStatus: _parseSyncStatus(data['syncStatus']), ); } Map toFirestore() { return { 'userId': userId, 'organizationId': organizationId, 'startTime': Timestamp.fromDate(startTime), 'endTime': endTime != null ? Timestamp.fromDate(endTime!) : null, 'duration': duration, 'type': type.name, 'projectId': projectId, 'customerId': customerId, 'comment': comment, 'breaks': breaks.map((b) => b.toMap()).toList(), 'createdAt': Timestamp.fromDate(createdAt), 'updatedAt': Timestamp.fromDate(updatedAt), 'createdBy': createdBy, 'lastModifiedBy': lastModifiedBy, 'deviations': deviations, 'isManual': isManual, 'syncStatus': syncStatus.name, }; } static RegistrationType _parseType(String? typeString) { switch (typeString) { case 'overtime': return RegistrationType.overtime; case 'oncall': return RegistrationType.oncall; case 'travel': return RegistrationType.travel; default: return RegistrationType.ordinary; } } static SyncStatus _parseSyncStatus(String? statusString) { switch (statusString) { case 'pending': return SyncStatus.pending; case 'conflict': return SyncStatus.conflict; default: return SyncStatus.synced; } } int get totalBreakMinutes { return breaks.fold(0, (sum, b) => sum + b.duration); } int get netWorkMinutes { return duration - totalBreakMinutes; } bool get isActive { return endTime == null; } TimeRegistration copyWith({ String? userId, String? organizationId, DateTime? startTime, DateTime? endTime, int? duration, RegistrationType? type, String? projectId, String? customerId, String? comment, List? breaks, DateTime? updatedAt, String? lastModifiedBy, List? deviations, bool? isManual, SyncStatus? syncStatus, }) { return TimeRegistration( id: id, userId: userId ?? this.userId, organizationId: organizationId ?? this.organizationId, startTime: startTime ?? this.startTime, endTime: endTime ?? this.endTime, duration: duration ?? this.duration, type: type ?? this.type, projectId: projectId ?? this.projectId, customerId: customerId ?? this.customerId, comment: comment ?? this.comment, breaks: breaks ?? this.breaks, createdAt: createdAt, updatedAt: updatedAt ?? this.updatedAt, createdBy: createdBy, lastModifiedBy: lastModifiedBy ?? this.lastModifiedBy, deviations: deviations ?? this.deviations, isManual: isManual ?? this.isManual, syncStatus: syncStatus ?? this.syncStatus, ); } }