177 lines
4.3 KiB
Dart
177 lines
4.3 KiB
Dart
/// 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)';
|
|
}
|
|
}
|