/// Domain Entity: Price Document /// /// Pure business entity representing a price policy or price list document. /// This entity is framework-independent and contains only business logic. library; /// Price policy document entity class PriceDocument { /// Unique document ID final String id; /// Document title final String title; /// Document description final String description; /// Date the document was published final DateTime publishedDate; /// Type of document (PDF or Excel) final DocumentType documentType; /// Category (policy or price list) final DocumentCategory category; /// URL to download the document final String downloadUrl; /// Optional file size display string final String? fileSize; /// Constructor const PriceDocument({ required this.id, required this.title, required this.description, required this.publishedDate, required this.documentType, required this.category, required this.downloadUrl, this.fileSize, }); /// Check if document is a PDF bool get isPdf => documentType == DocumentType.pdf; /// Check if document is an Excel file bool get isExcel => documentType == DocumentType.excel; /// Check if document is a policy document bool get isPolicy => category == DocumentCategory.policy; /// Check if document is a price list bool get isPriceList => category == DocumentCategory.priceList; /// Get formatted published date (dd/MM/yyyy) String get formattedDate { return '${publishedDate.day.toString().padLeft(2, '0')}/' '${publishedDate.month.toString().padLeft(2, '0')}/' '${publishedDate.year}'; } /// Get formatted date with prefix based on category String get formattedDateWithPrefix { final prefix = isPolicy ? 'Công bố' : 'Cập nhật'; return '$prefix: $formattedDate'; } /// Get icon name based on document type String get iconName => documentType == DocumentType.pdf ? 'PDF' : 'Excel'; /// Copy with method for immutability PriceDocument copyWith({ String? id, String? title, String? description, DateTime? publishedDate, DocumentType? documentType, DocumentCategory? category, String? downloadUrl, String? fileSize, }) { return PriceDocument( id: id ?? this.id, title: title ?? this.title, description: description ?? this.description, publishedDate: publishedDate ?? this.publishedDate, documentType: documentType ?? this.documentType, category: category ?? this.category, downloadUrl: downloadUrl ?? this.downloadUrl, fileSize: fileSize ?? this.fileSize, ); } /// Equality operator @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is PriceDocument && other.id == id && other.title == title && other.description == description && other.publishedDate == publishedDate && other.documentType == documentType && other.category == category && other.downloadUrl == downloadUrl && other.fileSize == fileSize; } /// Hash code @override int get hashCode { return Object.hash( id, title, description, publishedDate, documentType, category, downloadUrl, fileSize, ); } /// String representation @override String toString() { return 'PriceDocument(id: $id, title: $title, description: $description, ' 'publishedDate: $publishedDate, documentType: $documentType, ' 'category: $category, downloadUrl: $downloadUrl, fileSize: $fileSize)'; } } /// Document type enum enum DocumentType { pdf, excel } /// Document category enum enum DocumentCategory { policy, // Chính sách giá priceList, // Bảng giá } // Extension for display extension DocumentTypeX on DocumentType { String get displayName { switch (this) { case DocumentType.pdf: return 'PDF'; case DocumentType.excel: return 'Excel'; } } } extension DocumentCategoryX on DocumentCategory { String get displayName { switch (this) { case DocumentCategory.policy: return 'Chính sách giá'; case DocumentCategory.priceList: return 'Bảng giá'; } } }