add price policy

This commit is contained in:
Phuoc Nguyen
2025-11-03 11:20:09 +07:00
parent c0527a086c
commit 21c1c3372c
53 changed files with 7160 additions and 2361 deletions

View File

@@ -0,0 +1,166 @@
/// 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á';
}
}
}

View File

@@ -0,0 +1,50 @@
/// Domain Repository Interface: Price Policy Repository
///
/// Defines the contract for price policy document data operations.
/// This is an abstract interface following the Repository Pattern.
///
/// The actual implementation will be in the data layer.
/// This allows for dependency inversion and easier testing.
library;
import 'package:worker/features/price_policy/domain/entities/price_document.dart';
/// Price Policy Repository Interface
///
/// Provides methods to:
/// - Get all price policy documents
/// - Filter documents by category
/// - Fetch individual document details
///
/// Implementation will be in data/repositories/price_policy_repository_impl.dart
abstract class PricePolicyRepository {
/// Get all price policy documents
///
/// Returns list of [PriceDocument] objects.
/// Returns empty list if no documents available.
///
/// This should fetch from local cache first, then sync with server.
/// Documents should be ordered by published date (newest first).
Future<List<PriceDocument>> getAllDocuments();
/// Get documents filtered by category
///
/// Returns list of [PriceDocument] objects matching the [category].
/// Returns empty list if no matching documents.
///
/// [category] - The category to filter by (policy or priceList)
Future<List<PriceDocument>> getDocumentsByCategory(DocumentCategory category);
/// Get a specific document by ID
///
/// Returns [PriceDocument] if found, null otherwise.
///
/// [documentId] - The unique identifier of the document
Future<PriceDocument?> getDocumentById(String documentId);
/// Refresh documents from server
///
/// Force refresh documents from remote source.
/// Updates local cache after successful fetch.
Future<List<PriceDocument>> refreshDocuments();
}