256 lines
8.0 KiB
Dart
256 lines
8.0 KiB
Dart
/// Project Submission Model
|
|
///
|
|
/// Data model for project submission from API responses.
|
|
/// Based on API response from building_material.building_material.api.project.get_detail
|
|
library;
|
|
|
|
import 'package:worker/features/projects/domain/entities/project_submission.dart';
|
|
|
|
/// Project File Model
|
|
class ProjectFileModel {
|
|
/// Unique file identifier (API: name)
|
|
final String id;
|
|
|
|
/// Full URL to the file (API: file_url)
|
|
final String fileUrl;
|
|
|
|
const ProjectFileModel({
|
|
required this.id,
|
|
required this.fileUrl,
|
|
});
|
|
|
|
/// Create from JSON (API response)
|
|
factory ProjectFileModel.fromJson(Map<String, dynamic> json) {
|
|
return ProjectFileModel(
|
|
id: json['name'] as String,
|
|
fileUrl: json['file_url'] as String,
|
|
);
|
|
}
|
|
|
|
/// Convert to JSON
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'name': id,
|
|
'file_url': fileUrl,
|
|
};
|
|
}
|
|
|
|
/// Convert to entity
|
|
ProjectFile toEntity() {
|
|
return ProjectFile(
|
|
id: id,
|
|
fileUrl: fileUrl,
|
|
);
|
|
}
|
|
|
|
/// Create from entity
|
|
factory ProjectFileModel.fromEntity(ProjectFile entity) {
|
|
return ProjectFileModel(
|
|
id: entity.id,
|
|
fileUrl: entity.fileUrl,
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Project Submission Model
|
|
class ProjectSubmissionModel {
|
|
/// Unique submission identifier (API: name)
|
|
final String submissionId;
|
|
|
|
/// Project name/title (API: designed_area)
|
|
final String designedArea;
|
|
|
|
/// Design area value in square meters (API: design_area)
|
|
final double designArea;
|
|
|
|
/// Submission/request date (API: request_date)
|
|
final DateTime requestDate;
|
|
|
|
/// Status label - Vietnamese (API: status)
|
|
final String status;
|
|
|
|
/// Rejection reason if rejected (API: reason_for_rejection)
|
|
final String? reasonForRejection;
|
|
|
|
/// Status color indicator (API: status_color)
|
|
final String statusColor;
|
|
|
|
/// Project address (API: address_of_project)
|
|
final String? addressOfProject;
|
|
|
|
/// Project owner name (API: project_owner)
|
|
final String? projectOwner;
|
|
|
|
/// Design firm name (API: design_firm)
|
|
final String? designFirm;
|
|
|
|
/// Construction contractor name (API: contruction_contractor)
|
|
final String? constructionContractor;
|
|
|
|
/// Products included in the design (API: products_included_in_the_design)
|
|
final String? productsIncludedInTheDesign;
|
|
|
|
/// Project progress ID reference (API: project_progress)
|
|
final String? projectProgress;
|
|
|
|
/// Expected commencement date (API: expected_commencement_date)
|
|
final DateTime? expectedCommencementDate;
|
|
|
|
/// Project description (API: description)
|
|
final String? description;
|
|
|
|
/// Workflow state (API: workflow_state)
|
|
final String? workflowState;
|
|
|
|
/// Whether the submission can be modified (API: is_allow_modify)
|
|
final bool isAllowModify;
|
|
|
|
/// Whether the submission can be cancelled (API: is_allow_cancel)
|
|
final bool isAllowCancel;
|
|
|
|
/// List of attached files (API: files_list)
|
|
final List<ProjectFileModel> filesList;
|
|
|
|
const ProjectSubmissionModel({
|
|
required this.submissionId,
|
|
required this.designedArea,
|
|
required this.designArea,
|
|
required this.requestDate,
|
|
required this.status,
|
|
this.reasonForRejection,
|
|
required this.statusColor,
|
|
this.addressOfProject,
|
|
this.projectOwner,
|
|
this.designFirm,
|
|
this.constructionContractor,
|
|
this.productsIncludedInTheDesign,
|
|
this.projectProgress,
|
|
this.expectedCommencementDate,
|
|
this.description,
|
|
this.workflowState,
|
|
this.isAllowModify = false,
|
|
this.isAllowCancel = false,
|
|
this.filesList = const [],
|
|
});
|
|
|
|
/// Create from JSON (API response)
|
|
/// Handles both list response and detail response formats
|
|
factory ProjectSubmissionModel.fromJson(Map<String, dynamic> json) {
|
|
// Parse expected_commencement_date
|
|
DateTime? expectedDate;
|
|
final expectedDateStr = json['expected_commencement_date'] as String?;
|
|
if (expectedDateStr != null && expectedDateStr.isNotEmpty) {
|
|
try {
|
|
expectedDate = DateTime.parse(expectedDateStr);
|
|
} catch (_) {}
|
|
}
|
|
|
|
// Parse files_list
|
|
final filesListJson = json['files_list'] as List<dynamic>?;
|
|
final filesList = filesListJson
|
|
?.map((f) => ProjectFileModel.fromJson(f as Map<String, dynamic>))
|
|
.toList() ??
|
|
[];
|
|
|
|
return ProjectSubmissionModel(
|
|
submissionId: json['name'] as String,
|
|
designedArea: json['designed_area'] as String,
|
|
designArea: (json['design_area'] as num).toDouble(),
|
|
requestDate: DateTime.parse(json['request_date'] as String),
|
|
status: json['status'] as String,
|
|
reasonForRejection: json['reason_for_rejection'] as String?,
|
|
statusColor: json['status_color'] as String,
|
|
addressOfProject: json['address_of_project'] as String?,
|
|
projectOwner: json['project_owner'] as String?,
|
|
designFirm: json['design_firm'] as String?,
|
|
constructionContractor: json['contruction_contractor'] as String?,
|
|
productsIncludedInTheDesign:
|
|
json['products_included_in_the_design'] as String?,
|
|
projectProgress: json['project_progress'] as String?,
|
|
expectedCommencementDate: expectedDate,
|
|
description: json['description'] as String?,
|
|
workflowState: json['workflow_state'] as String?,
|
|
isAllowModify: json['is_allow_modify'] as bool? ?? false,
|
|
isAllowCancel: json['is_allow_cancel'] as bool? ?? false,
|
|
filesList: filesList,
|
|
);
|
|
}
|
|
|
|
/// Convert to JSON
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'name': submissionId,
|
|
'designed_area': designedArea,
|
|
'design_area': designArea,
|
|
'request_date': requestDate.toIso8601String(),
|
|
'status': status,
|
|
'reason_for_rejection': reasonForRejection,
|
|
'status_color': statusColor,
|
|
'address_of_project': addressOfProject,
|
|
'project_owner': projectOwner,
|
|
'design_firm': designFirm,
|
|
'contruction_contractor': constructionContractor,
|
|
'products_included_in_the_design': productsIncludedInTheDesign,
|
|
'project_progress': projectProgress,
|
|
'expected_commencement_date':
|
|
expectedCommencementDate?.toIso8601String(),
|
|
'description': description,
|
|
'workflow_state': workflowState,
|
|
'is_allow_modify': isAllowModify,
|
|
'is_allow_cancel': isAllowCancel,
|
|
'files_list': filesList.map((f) => f.toJson()).toList(),
|
|
};
|
|
}
|
|
|
|
/// Convert to entity
|
|
ProjectSubmission toEntity() {
|
|
return ProjectSubmission(
|
|
submissionId: submissionId,
|
|
designedArea: designedArea,
|
|
designArea: designArea,
|
|
requestDate: requestDate,
|
|
status: status,
|
|
reasonForRejection: reasonForRejection,
|
|
statusColor: statusColor,
|
|
addressOfProject: addressOfProject,
|
|
projectOwner: projectOwner,
|
|
designFirm: designFirm,
|
|
constructionContractor: constructionContractor,
|
|
productsIncludedInTheDesign: productsIncludedInTheDesign,
|
|
projectProgress: projectProgress,
|
|
expectedCommencementDate: expectedCommencementDate,
|
|
description: description,
|
|
workflowState: workflowState,
|
|
isAllowModify: isAllowModify,
|
|
isAllowCancel: isAllowCancel,
|
|
filesList: filesList.map((f) => f.toEntity()).toList(),
|
|
);
|
|
}
|
|
|
|
/// Create from entity
|
|
factory ProjectSubmissionModel.fromEntity(ProjectSubmission entity) {
|
|
return ProjectSubmissionModel(
|
|
submissionId: entity.submissionId,
|
|
designedArea: entity.designedArea,
|
|
designArea: entity.designArea,
|
|
requestDate: entity.requestDate,
|
|
status: entity.status,
|
|
reasonForRejection: entity.reasonForRejection,
|
|
statusColor: entity.statusColor,
|
|
addressOfProject: entity.addressOfProject,
|
|
projectOwner: entity.projectOwner,
|
|
designFirm: entity.designFirm,
|
|
constructionContractor: entity.constructionContractor,
|
|
productsIncludedInTheDesign: entity.productsIncludedInTheDesign,
|
|
projectProgress: entity.projectProgress,
|
|
expectedCommencementDate: entity.expectedCommencementDate,
|
|
description: entity.description,
|
|
workflowState: entity.workflowState,
|
|
isAllowModify: entity.isAllowModify,
|
|
isAllowCancel: entity.isAllowCancel,
|
|
filesList:
|
|
entity.filesList.map((f) => ProjectFileModel.fromEntity(f)).toList(),
|
|
);
|
|
}
|
|
}
|