Files
worker/lib/features/price_policy/domain/entities/price_document.dart
Phuoc Nguyen 88ac2f2f07 price policy
2025-11-26 14:44:17 +07:00

152 lines
4.0 KiB
Dart

/// 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;
import 'package:equatable/equatable.dart';
/// Price policy document entity
class PriceDocument extends Equatable {
/// Document title
final String title;
/// URL to download the document
final String fileUrl;
/// Date the document was last updated
final DateTime updatedAt;
/// Category (policy or price list)
final DocumentCategory category;
/// Local file path after download (in-memory cache for current session)
final String? filePath;
/// Constructor
const PriceDocument({
required this.title,
required this.fileUrl,
required this.updatedAt,
required this.category,
this.filePath,
});
/// Get document type based on file extension
DocumentType get documentType {
final lowerUrl = fileUrl.toLowerCase();
if (lowerUrl.endsWith('.pdf')) {
return DocumentType.pdf;
} else if (lowerUrl.endsWith('.xlsx') ||
lowerUrl.endsWith('.xls') ||
lowerUrl.endsWith('.csv')) {
return DocumentType.excel;
}
return DocumentType.excel; // Default to excel
}
/// 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 '${updatedAt.day.toString().padLeft(2, '0')}/'
'${updatedAt.month.toString().padLeft(2, '0')}/'
'${updatedAt.year}';
}
/// Get formatted date with time (dd/MM/yyyy HH:mm)
String get formattedDateTime {
return '$formattedDate ${updatedAt.hour.toString().padLeft(2, '0')}:'
'${updatedAt.minute.toString().padLeft(2, '0')}';
}
/// 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? title,
String? fileUrl,
DateTime? updatedAt,
DocumentCategory? category,
String? filePath,
}) {
return PriceDocument(
title: title ?? this.title,
fileUrl: fileUrl ?? this.fileUrl,
updatedAt: updatedAt ?? this.updatedAt,
category: category ?? this.category,
filePath: filePath ?? this.filePath,
);
}
/// Equatable props for equality comparison
@override
List<Object?> get props => [title, fileUrl, updatedAt, category, filePath];
/// String representation
@override
String toString() {
return 'PriceDocument(title: $title, fileUrl: $fileUrl, '
'updatedAt: $updatedAt, category: $category, filePath: $filePath)';
}
}
/// Document type enum
enum DocumentType { pdf, excel }
/// Document category enum
enum DocumentCategory {
policy, // Chính sách giá (PRICING_RULE)
priceList, // Bảng giá (PRICE_LIST)
}
// 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á';
}
}
/// Get API parameter value for this category
String get apiValue {
switch (this) {
case DocumentCategory.policy:
return 'PRICING_RULE';
case DocumentCategory.priceList:
return 'PRICE_LIST';
}
}
}