/// Domain Entity: Project Submission /// /// Represents a completed project submitted for loyalty points. /// Based on API response from building_material.building_material.api.project.get_detail library; import 'package:equatable/equatable.dart'; /// Project File Entity /// /// Represents an uploaded file attached to a project submission. class ProjectFile extends Equatable { /// Unique file identifier (API: name) final String id; /// Full URL to the file (API: file_url) final String fileUrl; const ProjectFile({ required this.id, required this.fileUrl, }); @override List get props => [id, fileUrl]; } /// Project Submission Entity /// /// Contains information about a completed project submission. /// Mapped from API response: /// - name -> submissionId /// - designed_area -> designedArea (project name/title) /// - address_of_project -> addressOfProject /// - project_owner -> projectOwner /// - design_firm -> designFirm /// - contruction_contractor -> constructionContractor /// - design_area -> designArea (area value in m²) /// - products_included_in_the_design -> productsIncludedInTheDesign /// - project_progress -> projectProgress (ID reference) /// - expected_commencement_date -> expectedCommencementDate /// - description -> description /// - request_date -> requestDate /// - workflow_state -> workflowState /// - reason_for_rejection -> reasonForRejection /// - status -> status (Vietnamese label) /// - status_color -> statusColor /// - is_allow_modify -> isAllowModify /// - is_allow_cancel -> isAllowCancel /// - files_list -> filesList class ProjectSubmission extends Equatable { /// Unique submission identifier (API: name) final String submissionId; /// Project name/title (API: designed_area) final String designedArea; /// 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; /// Design area value in square meters (API: design_area) final double designArea; /// 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; /// Submission/request date (API: request_date) final DateTime requestDate; /// Workflow state (API: workflow_state) /// e.g., "Pending approval", "Approved", "Rejected", "Cancelled" final String? workflowState; /// Rejection reason if rejected (API: reason_for_rejection) final String? reasonForRejection; /// Status label - Vietnamese (API: status) /// e.g., "Chờ phê duyệt", "Đã được phê duyệt", "Từ chối", "HỦY BỎ" final String status; /// Status color indicator (API: status_color) /// Values: "Warning", "Success", "Danger" final String statusColor; /// 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 filesList; const ProjectSubmission({ required this.submissionId, required this.designedArea, this.addressOfProject, this.projectOwner, this.designFirm, this.constructionContractor, required this.designArea, this.productsIncludedInTheDesign, this.projectProgress, this.expectedCommencementDate, this.description, required this.requestDate, this.workflowState, this.reasonForRejection, required this.status, required this.statusColor, this.isAllowModify = false, this.isAllowCancel = false, this.filesList = const [], }); /// Check if submission is pending approval bool get isPending => statusColor == 'Warning'; /// Check if submission is approved bool get isApproved => statusColor == 'Success'; /// Check if submission is rejected or cancelled bool get isRejected => statusColor == 'Danger'; /// Copy with method for immutability ProjectSubmission copyWith({ String? submissionId, String? designedArea, String? addressOfProject, String? projectOwner, String? designFirm, String? constructionContractor, double? designArea, String? productsIncludedInTheDesign, String? projectProgress, DateTime? expectedCommencementDate, String? description, DateTime? requestDate, String? workflowState, String? reasonForRejection, String? status, String? statusColor, bool? isAllowModify, bool? isAllowCancel, List? filesList, }) { return ProjectSubmission( submissionId: submissionId ?? this.submissionId, designedArea: designedArea ?? this.designedArea, addressOfProject: addressOfProject ?? this.addressOfProject, projectOwner: projectOwner ?? this.projectOwner, designFirm: designFirm ?? this.designFirm, constructionContractor: constructionContractor ?? this.constructionContractor, designArea: designArea ?? this.designArea, productsIncludedInTheDesign: productsIncludedInTheDesign ?? this.productsIncludedInTheDesign, projectProgress: projectProgress ?? this.projectProgress, expectedCommencementDate: expectedCommencementDate ?? this.expectedCommencementDate, description: description ?? this.description, requestDate: requestDate ?? this.requestDate, workflowState: workflowState ?? this.workflowState, reasonForRejection: reasonForRejection ?? this.reasonForRejection, status: status ?? this.status, statusColor: statusColor ?? this.statusColor, isAllowModify: isAllowModify ?? this.isAllowModify, isAllowCancel: isAllowCancel ?? this.isAllowCancel, filesList: filesList ?? this.filesList, ); } @override List get props => [ submissionId, designedArea, addressOfProject, projectOwner, designFirm, constructionContractor, designArea, productsIncludedInTheDesign, projectProgress, expectedCommencementDate, description, requestDate, workflowState, reasonForRejection, status, statusColor, isAllowModify, isAllowCancel, filesList, ]; @override String toString() { return 'ProjectSubmission(submissionId: $submissionId, designedArea: $designedArea, ' 'designArea: $designArea, status: $status, statusColor: $statusColor)'; } }