price policy

This commit is contained in:
Phuoc Nguyen
2025-11-26 14:44:17 +07:00
parent a07f165f0c
commit 88ac2f2f07
14 changed files with 588 additions and 654 deletions

View File

@@ -1,158 +1,115 @@
/// Data Model: Price Document Model
/// Data Model: Price Document
///
/// Data layer model for price policy documents.
/// Handles JSON serialization and conversion to/from domain entity.
/// Data model for price policy documents from API.
library;
import 'package:worker/features/price_policy/domain/entities/price_document.dart';
/// Price Document Model
///
/// Used in the data layer for:
/// - JSON serialization/deserialization from API
/// - Conversion to domain entity
/// - Local storage (if needed)
/// Price document data model
class PriceDocumentModel {
/// Unique document ID
final String id;
/// Document title
final String title;
/// Document description
final String description;
/// Date the document was published (ISO 8601 string)
final String publishedDate;
/// Type of document (pdf or excel)
final String documentType;
/// Category (policy or priceList)
final String category;
/// URL to download the document
final String downloadUrl;
final String fileUrl;
/// Optional file size display string
final String? fileSize;
/// Last updated timestamp
final String updatedAt;
/// Constructor
const PriceDocumentModel({
required this.id,
required this.title,
required this.description,
required this.publishedDate,
required this.documentType,
required this.category,
required this.downloadUrl,
this.fileSize,
required this.fileUrl,
required this.updatedAt,
});
/// Create model from JSON
/// Create from JSON
factory PriceDocumentModel.fromJson(Map<String, dynamic> json) {
return PriceDocumentModel(
id: json['id'] as String,
title: json['title'] as String,
description: json['description'] as String,
publishedDate: json['published_date'] as String,
documentType: json['document_type'] as String,
category: json['category'] as String,
downloadUrl: json['download_url'] as String,
fileSize: json['file_size'] as String?,
title: json['title'] as String? ?? '',
fileUrl: json['file_url'] as String? ?? '',
updatedAt: json['updated_at'] as String? ?? '',
);
}
/// Convert model to JSON
/// Convert to JSON
Map<String, dynamic> toJson() {
return {
'id': id,
'title': title,
'description': description,
'published_date': publishedDate,
'document_type': documentType,
'category': category,
'download_url': downloadUrl,
'file_size': fileSize,
'file_url': fileUrl,
'updated_at': updatedAt,
};
}
/// Convert model to domain entity
PriceDocument toEntity() {
/// Convert to domain entity
PriceDocument toEntity(DocumentCategory category) {
return PriceDocument(
id: id,
title: title,
description: description,
publishedDate: DateTime.parse(publishedDate),
documentType: _parseDocumentType(documentType),
category: _parseCategory(category),
downloadUrl: downloadUrl,
fileSize: fileSize,
fileUrl: fileUrl,
updatedAt: _parseDateTime(updatedAt),
category: category,
);
}
/// Create model from domain entity
/// Parse datetime string from API format
/// Format: "2025-11-26 11:36:43"
DateTime _parseDateTime(String dateTimeStr) {
try {
// Replace space with 'T' for ISO 8601 format
final isoFormat = dateTimeStr.trim().replaceFirst(' ', 'T');
return DateTime.parse(isoFormat);
} catch (e) {
// If parsing fails, return current datetime
return DateTime.now();
}
}
/// Create from domain entity
factory PriceDocumentModel.fromEntity(PriceDocument entity) {
return PriceDocumentModel(
id: entity.id,
title: entity.title,
description: entity.description,
publishedDate: entity.publishedDate.toIso8601String(),
documentType: _documentTypeToString(entity.documentType),
category: _categoryToString(entity.category),
downloadUrl: entity.downloadUrl,
fileSize: entity.fileSize,
fileUrl: entity.fileUrl,
updatedAt: _formatDateTime(entity.updatedAt),
);
}
/// Parse document type from string
static DocumentType _parseDocumentType(String type) {
switch (type.toLowerCase()) {
case 'pdf':
return DocumentType.pdf;
case 'excel':
return DocumentType.excel;
default:
return DocumentType.pdf;
}
}
/// Parse category from string
static DocumentCategory _parseCategory(String category) {
switch (category.toLowerCase()) {
case 'policy':
return DocumentCategory.policy;
case 'pricelist':
case 'price_list':
return DocumentCategory.priceList;
default:
return DocumentCategory.policy;
}
}
/// Convert document type to string
static String _documentTypeToString(DocumentType type) {
switch (type) {
case DocumentType.pdf:
return 'pdf';
case DocumentType.excel:
return 'excel';
}
}
/// Convert category to string
static String _categoryToString(DocumentCategory category) {
switch (category) {
case DocumentCategory.policy:
return 'policy';
case DocumentCategory.priceList:
return 'priceList';
}
/// Format datetime to API format
static String _formatDateTime(DateTime dateTime) {
return '${dateTime.year}-'
'${dateTime.month.toString().padLeft(2, '0')}-'
'${dateTime.day.toString().padLeft(2, '0')} '
'${dateTime.hour.toString().padLeft(2, '0')}:'
'${dateTime.minute.toString().padLeft(2, '0')}:'
'${dateTime.second.toString().padLeft(2, '0')}';
}
@override
String toString() {
return 'PriceDocumentModel(id: $id, title: $title, category: $category, '
'documentType: $documentType, publishedDate: $publishedDate)';
return 'PriceDocumentModel(title: $title, fileUrl: $fileUrl, updatedAt: $updatedAt)';
}
}
/// API Response wrapper
class PricingApiResponse {
/// List of price documents
final List<PriceDocumentModel> message;
const PricingApiResponse({required this.message});
/// Create from JSON
factory PricingApiResponse.fromJson(Map<String, dynamic> json) {
final messageList = json['message'] as List<dynamic>? ?? [];
return PricingApiResponse(
message: messageList
.map((item) => PriceDocumentModel.fromJson(item as Map<String, dynamic>))
.toList(),
);
}
/// Convert to JSON
Map<String, dynamic> toJson() {
return {
'message': message.map((doc) => doc.toJson()).toList(),
};
}
}