import 'package:superport_v2/core/common/models/paginated_result.dart'; import '../../domain/entities/approval.dart'; class ApprovalDto { ApprovalDto({ this.id, required this.approvalNo, this.transactionNo, required this.status, this.currentStep, required this.requester, required this.requestedAt, this.decidedAt, this.note, this.isActive = true, this.isDeleted = false, this.steps = const [], this.histories = const [], this.createdAt, this.updatedAt, }); final int? id; final String approvalNo; final String? transactionNo; final ApprovalStatusDto status; final ApprovalStepDto? currentStep; final ApprovalRequesterDto requester; final DateTime requestedAt; final DateTime? decidedAt; final String? note; final bool isActive; final bool isDeleted; final List steps; final List histories; final DateTime? createdAt; final DateTime? updatedAt; factory ApprovalDto.fromJson(Map json) { return ApprovalDto( id: json['id'] as int?, approvalNo: json['approval_no'] as String, transactionNo: json['transaction'] is Map ? (json['transaction']['transaction_no'] as String?) : json['transaction_no'] as String?, status: ApprovalStatusDto.fromJson( (json['status'] as Map? ?? const {}), ), currentStep: json['current_step'] is Map ? ApprovalStepDto.fromJson( json['current_step'] as Map, ) : null, requester: ApprovalRequesterDto.fromJson( (json['requester'] as Map? ?? const {}), ), requestedAt: _parseDate(json['requested_at']) ?? DateTime.now(), decidedAt: _parseDate(json['decided_at']), note: json['note'] as String?, isActive: (json['is_active'] as bool?) ?? true, isDeleted: (json['is_deleted'] as bool?) ?? false, steps: (json['steps'] as List? ?? []) .whereType>() .map(ApprovalStepDto.fromJson) .toList(), histories: (json['histories'] as List? ?? []) .whereType>() .map(ApprovalHistoryDto.fromJson) .toList(), createdAt: _parseDate(json['created_at']), updatedAt: _parseDate(json['updated_at']), ); } Approval toEntity() => Approval( id: id, approvalNo: approvalNo, transactionNo: transactionNo ?? '-', status: status.toEntity(), currentStep: currentStep?.toEntity(), requester: requester.toEntity(), requestedAt: requestedAt, decidedAt: decidedAt, note: note, isActive: isActive, isDeleted: isDeleted, steps: steps.map((e) => e.toEntity()).toList(), histories: histories.map((e) => e.toEntity()).toList(), createdAt: createdAt, updatedAt: updatedAt, ); static PaginatedResult parsePaginated(Map? json) { final items = (json?['items'] as List? ?? []) .whereType>() .map(ApprovalDto.fromJson) .map((dto) => dto.toEntity()) .toList(); return PaginatedResult( items: items, page: json?['page'] as int? ?? 1, pageSize: json?['page_size'] as int? ?? items.length, total: json?['total'] as int? ?? items.length, ); } } class ApprovalStatusDto { ApprovalStatusDto({required this.id, required this.name, this.color}); final int id; final String name; final String? color; factory ApprovalStatusDto.fromJson(Map json) { return ApprovalStatusDto( id: json['id'] as int? ?? json['status_id'] as int? ?? 0, name: json['name'] as String? ?? json['status_name'] as String? ?? '-', color: json['color'] as String?, ); } ApprovalStatus toEntity() => ApprovalStatus(id: id, name: name, color: color); } class ApprovalRequesterDto { ApprovalRequesterDto({ required this.id, required this.employeeNo, required this.name, }); final int id; final String employeeNo; final String name; factory ApprovalRequesterDto.fromJson(Map json) { return ApprovalRequesterDto( id: json['id'] as int? ?? json['employee_id'] as int? ?? 0, employeeNo: json['employee_no'] as String? ?? '-', name: json['name'] as String? ?? json['employee_name'] as String? ?? '-', ); } ApprovalRequester toEntity() => ApprovalRequester(id: id, employeeNo: employeeNo, name: name); } class ApprovalApproverDto { ApprovalApproverDto({ required this.id, required this.employeeNo, required this.name, }); final int id; final String employeeNo; final String name; factory ApprovalApproverDto.fromJson(Map json) { return ApprovalApproverDto( id: json['id'] as int? ?? json['approver_id'] as int? ?? 0, employeeNo: json['employee_no'] as String? ?? '-', name: json['name'] as String? ?? json['employee_name'] as String? ?? '-', ); } ApprovalApprover toEntity() => ApprovalApprover(id: id, employeeNo: employeeNo, name: name); } class ApprovalStepDto { ApprovalStepDto({ this.id, required this.stepOrder, required this.approver, required this.status, required this.assignedAt, this.decidedAt, this.note, }); final int? id; final int stepOrder; final ApprovalApproverDto approver; final ApprovalStatusDto status; final DateTime assignedAt; final DateTime? decidedAt; final String? note; factory ApprovalStepDto.fromJson(Map json) { return ApprovalStepDto( id: json['id'] as int?, stepOrder: json['step_order'] as int? ?? 0, approver: ApprovalApproverDto.fromJson( (json['approver'] as Map? ?? const {}), ), status: ApprovalStatusDto.fromJson( (json['status'] as Map? ?? const {}), ), assignedAt: _parseDate(json['assigned_at']) ?? DateTime.now(), decidedAt: _parseDate(json['decided_at']), note: json['note'] as String?, ); } ApprovalStep toEntity() => ApprovalStep( id: id, stepOrder: stepOrder, approver: approver.toEntity(), status: status.toEntity(), assignedAt: assignedAt, decidedAt: decidedAt, note: note, ); } class ApprovalHistoryDto { ApprovalHistoryDto({ this.id, required this.action, this.fromStatus, required this.toStatus, required this.approver, required this.actionAt, this.note, }); final int? id; final ApprovalActionDto action; final ApprovalStatusDto? fromStatus; final ApprovalStatusDto toStatus; final ApprovalApproverDto approver; final DateTime actionAt; final String? note; factory ApprovalHistoryDto.fromJson(Map json) { return ApprovalHistoryDto( id: json['id'] as int?, action: ApprovalActionDto.fromJson( (json['action'] as Map? ?? const {}), ), fromStatus: json['from_status'] is Map ? ApprovalStatusDto.fromJson( json['from_status'] as Map, ) : null, toStatus: ApprovalStatusDto.fromJson( (json['to_status'] as Map? ?? const {}), ), approver: ApprovalApproverDto.fromJson( (json['approver'] as Map? ?? const {}), ), actionAt: _parseDate(json['action_at']) ?? DateTime.now(), note: json['note'] as String?, ); } ApprovalHistory toEntity() => ApprovalHistory( id: id, action: action.toEntity(), fromStatus: fromStatus?.toEntity(), toStatus: toStatus.toEntity(), approver: approver.toEntity(), actionAt: actionAt, note: note, ); } class ApprovalActionDto { ApprovalActionDto({required this.id, required this.name}); final int id; final String name; factory ApprovalActionDto.fromJson(Map json) { return ApprovalActionDto( id: json['id'] as int? ?? json['action_id'] as int? ?? 0, name: json['name'] as String? ?? json['action_name'] as String? ?? '-', ); } ApprovalAction toEntity() => ApprovalAction(id: id, name: name); } DateTime? _parseDate(Object? value) { if (value == null) return null; if (value is DateTime) return value; if (value is String) return DateTime.tryParse(value); return null; }