Files
tasq/lib/models/task.model.dart
2026-04-27 06:20:39 +08:00

160 lines
5.6 KiB
Dart

import 'dart:convert';
import 'package:brick_offline_first_with_supabase/brick_offline_first_with_supabase.dart';
import 'package:brick_sqlite/brick_sqlite.dart';
import 'package:brick_supabase/brick_supabase.dart';
import '../utils/app_time.dart';
@ConnectOfflineFirstWithSupabase(
supabaseConfig: SupabaseSerializable(tableName: 'tasks'),
)
class Task extends OfflineFirstWithSupabaseModel {
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;
final String? requestedBy;
final String? notedBy;
final String? receivedBy;
final String? requestType;
final String? requestTypeOther;
final String? requestCategory;
// JSON-encoded Quill Delta stored as plain string.
final String? actionTaken;
final String? cancellationReason;
final DateTime? cancelledAt;
final bool itJobPrinted;
final DateTime? itJobPrintedAt;
final String? itJobReceivedById;
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,
this.requestedBy,
this.notedBy,
this.receivedBy,
this.requestType,
this.requestTypeOther,
this.requestCategory,
this.actionTaken,
this.cancellationReason,
this.cancelledAt,
this.itJobPrinted = false,
this.itJobPrintedAt,
this.itJobReceivedById,
});
@Supabase(ignore: true)
@Sqlite(ignore: true)
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Task &&
runtimeType == other.runtimeType &&
id == other.id &&
ticketId == other.ticketId &&
taskNumber == other.taskNumber &&
title == other.title &&
description == other.description &&
officeId == other.officeId &&
status == other.status &&
priority == other.priority &&
queueOrder == other.queueOrder &&
createdAt == other.createdAt &&
creatorId == other.creatorId &&
startedAt == other.startedAt &&
completedAt == other.completedAt &&
requestedBy == other.requestedBy &&
notedBy == other.notedBy &&
receivedBy == other.receivedBy &&
requestType == other.requestType &&
requestTypeOther == other.requestTypeOther &&
requestCategory == other.requestCategory &&
actionTaken == other.actionTaken &&
cancellationReason == other.cancellationReason &&
cancelledAt == other.cancelledAt &&
itJobPrinted == other.itJobPrinted &&
itJobPrintedAt == other.itJobPrintedAt &&
itJobReceivedById == other.itJobReceivedById;
@Supabase(ignore: true)
@Sqlite(ignore: true)
@override
int get hashCode => Object.hash(
id, ticketId, taskNumber, title, description, officeId, status, priority,
queueOrder, createdAt, creatorId, startedAt, completedAt, requestedBy,
notedBy, receivedBy, requestType, requestTypeOther, requestCategory,
Object.hash(actionTaken, cancellationReason, cancelledAt,
itJobPrinted, itJobPrintedAt, itJobReceivedById),
);
@Supabase(ignore: true)
@Sqlite(ignore: true)
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<String, dynamic> 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?,
cancellationReason: map['cancellation_reason'] as String?,
cancelledAt: map['cancelled_at'] == null
? null : AppTime.parse(map['cancelled_at'] as String),
itJobPrinted: map['it_job_printed'] as bool? ?? false,
itJobPrintedAt: map['it_job_printed_at'] == null
? null : AppTime.parse(map['it_job_printed_at'] as String),
itJobReceivedById: map['it_job_received_by_id'] 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(); }
})(),
);
}
}