enum WorkOrderStatus { open, completed; String get databaseValue => name; static WorkOrderStatus fromDatabase(String value) { return WorkOrderStatus.values.firstWhere( (status) => status.name == value, orElse: () => WorkOrderStatus.open, ); } } enum PhotoKind { before, after; String get databaseValue => name; static PhotoKind fromDatabase(String value) { return value == PhotoKind.after.name ? PhotoKind.after : PhotoKind.before; } } class TaskPhoto { const TaskPhoto({required this.id, required this.path, required this.kind}); final String id; final String path; final PhotoKind kind; } class TaskPart { const TaskPart({required this.id, required this.name, required this.price}); final String id; final String name; final int price; } class WorkTask { const WorkTask({ required this.id, required this.title, required this.observation, required this.position, this.photos = const [], this.parts = const [], }); final String id; final String title; final String observation; final int position; final List photos; final List parts; List get beforePhotos => photos.where((photo) => photo.kind == PhotoKind.before).toList(); List get afterPhotos => photos.where((photo) => photo.kind == PhotoKind.after).toList(); int get partsTotal => parts.fold(0, (total, part) => total + part.price); } class WorkOrderDetails { const WorkOrderDetails({ this.client = '', this.phone = '', this.address = '', }); final String client; final String phone; final String address; bool get isComplete => client.trim().isNotEmpty && phone.trim().isNotEmpty && address.trim().isNotEmpty; WorkOrderDetails copyWith({String? client, String? phone, String? address}) { return WorkOrderDetails( client: client ?? this.client, phone: phone ?? this.phone, address: address ?? this.address, ); } } class WorkOrder { const WorkOrder({ required this.id, required this.title, required this.createdAt, required this.updatedAt, required this.status, this.details = const WorkOrderDetails(), this.laborCost = 0, this.completedAt, this.recipientEmail, this.pdfPath, this.tasks = const [], }); final String id; final String title; final DateTime createdAt; final DateTime updatedAt; final DateTime? completedAt; final WorkOrderStatus status; final WorkOrderDetails details; final int laborCost; final String? recipientEmail; final String? pdfPath; final List tasks; bool get isCompleted => status == WorkOrderStatus.completed; int get totalPhotos => tasks.fold(0, (total, task) => total + task.photos.length); int get totalPartsCost => tasks.fold(0, (total, task) => total + task.partsTotal); int get totalCost => laborCost + totalPartsCost; WorkOrder copyWith({ String? title, DateTime? updatedAt, DateTime? completedAt, WorkOrderStatus? status, WorkOrderDetails? details, int? laborCost, String? recipientEmail, String? pdfPath, List? tasks, }) { return WorkOrder( id: id, title: title ?? this.title, createdAt: createdAt, updatedAt: updatedAt ?? this.updatedAt, completedAt: completedAt ?? this.completedAt, status: status ?? this.status, details: details ?? this.details, laborCost: laborCost ?? this.laborCost, recipientEmail: recipientEmail ?? this.recipientEmail, pdfPath: pdfPath ?? this.pdfPath, tasks: tasks ?? this.tasks, ); } }