update
This commit is contained in:
176
lib/features/home/domain/entities/promotion.dart
Normal file
176
lib/features/home/domain/entities/promotion.dart
Normal file
@@ -0,0 +1,176 @@
|
||||
/// Domain Entity: Promotion
|
||||
///
|
||||
/// Represents a promotional offer or campaign displayed on the home screen.
|
||||
/// This entity contains all information needed to display promotion banners.
|
||||
///
|
||||
/// This is a pure domain entity with no external dependencies.
|
||||
library;
|
||||
|
||||
/// Promotion status enum
|
||||
enum PromotionStatus {
|
||||
/// Currently active promotion
|
||||
active,
|
||||
|
||||
/// Promotion starting in the future
|
||||
upcoming,
|
||||
|
||||
/// Expired promotion
|
||||
expired;
|
||||
}
|
||||
|
||||
/// Promotion Entity
|
||||
///
|
||||
/// Contains all information needed to display a promotion:
|
||||
/// - Basic info (title, description)
|
||||
/// - Visual assets (image URL)
|
||||
/// - Validity period
|
||||
/// - Optional discount information
|
||||
class Promotion {
|
||||
/// Unique promotion ID
|
||||
final String id;
|
||||
|
||||
/// Promotion title
|
||||
final String title;
|
||||
|
||||
/// Detailed description
|
||||
final String description;
|
||||
|
||||
/// Banner/cover image URL
|
||||
final String imageUrl;
|
||||
|
||||
/// Promotion start date
|
||||
final DateTime startDate;
|
||||
|
||||
/// Promotion end date
|
||||
final DateTime endDate;
|
||||
|
||||
/// Optional discount percentage (e.g., 30 for 30%)
|
||||
final int? discountPercentage;
|
||||
|
||||
/// Optional discount amount
|
||||
final double? discountAmount;
|
||||
|
||||
/// Optional terms and conditions
|
||||
final String? terms;
|
||||
|
||||
/// Optional link to detailed page
|
||||
final String? detailsUrl;
|
||||
|
||||
/// Constructor
|
||||
const Promotion({
|
||||
required this.id,
|
||||
required this.title,
|
||||
required this.description,
|
||||
required this.imageUrl,
|
||||
required this.startDate,
|
||||
required this.endDate,
|
||||
this.discountPercentage,
|
||||
this.discountAmount,
|
||||
this.terms,
|
||||
this.detailsUrl,
|
||||
});
|
||||
|
||||
/// Get current promotion status
|
||||
PromotionStatus get status {
|
||||
final now = DateTime.now();
|
||||
|
||||
if (now.isBefore(startDate)) {
|
||||
return PromotionStatus.upcoming;
|
||||
} else if (now.isAfter(endDate)) {
|
||||
return PromotionStatus.expired;
|
||||
} else {
|
||||
return PromotionStatus.active;
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if promotion is currently active
|
||||
bool get isActive => status == PromotionStatus.active;
|
||||
|
||||
/// Get days remaining until expiry (null if expired or upcoming)
|
||||
int? get daysRemaining {
|
||||
if (status != PromotionStatus.active) return null;
|
||||
|
||||
return endDate.difference(DateTime.now()).inDays;
|
||||
}
|
||||
|
||||
/// Format discount display text
|
||||
String? get discountText {
|
||||
if (discountPercentage != null) {
|
||||
return 'Giảm $discountPercentage%';
|
||||
} else if (discountAmount != null) {
|
||||
return 'Giảm ${discountAmount?.toStringAsFixed(0) ?? '0'}₫';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Copy with method for immutability
|
||||
Promotion copyWith({
|
||||
String? id,
|
||||
String? title,
|
||||
String? description,
|
||||
String? imageUrl,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
int? discountPercentage,
|
||||
double? discountAmount,
|
||||
String? terms,
|
||||
String? detailsUrl,
|
||||
}) {
|
||||
return Promotion(
|
||||
id: id ?? this.id,
|
||||
title: title ?? this.title,
|
||||
description: description ?? this.description,
|
||||
imageUrl: imageUrl ?? this.imageUrl,
|
||||
startDate: startDate ?? this.startDate,
|
||||
endDate: endDate ?? this.endDate,
|
||||
discountPercentage: discountPercentage ?? this.discountPercentage,
|
||||
discountAmount: discountAmount ?? this.discountAmount,
|
||||
terms: terms ?? this.terms,
|
||||
detailsUrl: detailsUrl ?? this.detailsUrl,
|
||||
);
|
||||
}
|
||||
|
||||
/// Equality operator
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is Promotion &&
|
||||
other.id == id &&
|
||||
other.title == title &&
|
||||
other.description == description &&
|
||||
other.imageUrl == imageUrl &&
|
||||
other.startDate == startDate &&
|
||||
other.endDate == endDate &&
|
||||
other.discountPercentage == discountPercentage &&
|
||||
other.discountAmount == discountAmount &&
|
||||
other.terms == terms &&
|
||||
other.detailsUrl == detailsUrl;
|
||||
}
|
||||
|
||||
/// Hash code
|
||||
@override
|
||||
int get hashCode {
|
||||
return Object.hash(
|
||||
id,
|
||||
title,
|
||||
description,
|
||||
imageUrl,
|
||||
startDate,
|
||||
endDate,
|
||||
discountPercentage,
|
||||
discountAmount,
|
||||
terms,
|
||||
detailsUrl,
|
||||
);
|
||||
}
|
||||
|
||||
/// String representation
|
||||
@override
|
||||
String toString() {
|
||||
return 'Promotion(id: $id, title: $title, description: $description, '
|
||||
'imageUrl: $imageUrl, startDate: $startDate, endDate: $endDate, '
|
||||
'discountPercentage: $discountPercentage, discountAmount: $discountAmount, '
|
||||
'terms: $terms, detailsUrl: $detailsUrl)';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user