import 'dart:convert'; import '../utils/app_time.dart'; class Task { Task({ required this.id, required this.ticketId, required this.taskNumber, required this.title, required this.description, required this.officeId, required this.status, required this.priority, required this.queueOrder, required this.createdAt, required this.creatorId, required this.startedAt, required this.completedAt, // new optional metadata fields this.requestedBy, this.notedBy, this.receivedBy, this.requestType, this.requestTypeOther, this.requestCategory, this.actionTaken, }); final String id; final String? ticketId; final String? taskNumber; final String title; final String description; final String? officeId; final String status; final int priority; final int? queueOrder; final DateTime createdAt; final String? creatorId; final DateTime? startedAt; final DateTime? completedAt; // Optional client/user metadata final String? requestedBy; final String? notedBy; final String? receivedBy; /// Optional request metadata added later in lifecycle. final String? requestType; final String? requestTypeOther; final String? requestCategory; // JSON serialized rich text for action taken (Quill Delta JSON encoded) final String? actionTaken; /// Helper that indicates whether a completed task still has missing /// metadata such as signatories or action details. The parameter is used /// by UI to surface a warning icon/banner when a task has been closed but /// the user skipped filling out all fields. bool get hasIncompleteDetails { if (status != 'completed') return false; bool empty(String? v) => v == null || v.trim().isEmpty; return empty(requestedBy) || empty(notedBy) || empty(receivedBy) || empty(actionTaken); } factory Task.fromMap(Map map) { return Task( id: map['id'] as String, ticketId: map['ticket_id'] as String?, taskNumber: map['task_number'] as String?, title: map['title'] as String? ?? 'Task', description: map['description'] as String? ?? '', officeId: map['office_id'] as String?, status: map['status'] as String? ?? 'queued', priority: map['priority'] as int? ?? 1, queueOrder: map['queue_order'] as int?, createdAt: AppTime.parse(map['created_at'] as String), creatorId: map['creator_id'] as String?, startedAt: map['started_at'] == null ? null : AppTime.parse(map['started_at'] as String), completedAt: map['completed_at'] == null ? null : AppTime.parse(map['completed_at'] as String), requestType: map['request_type'] as String?, requestTypeOther: map['request_type_other'] as String?, requestCategory: map['request_category'] as String?, requestedBy: map['requested_by'] as String?, notedBy: map['noted_by'] as String?, receivedBy: map['received_by'] as String?, actionTaken: (() { final at = map['action_taken']; if (at == null) return null; if (at is String) return at; try { return jsonEncode(at); } catch (_) { return at.toString(); } })(), ); } }