202 lines
4.8 KiB
Dart
202 lines
4.8 KiB
Dart
/// Domain Entity: Redeemed Gift
|
|
///
|
|
/// Represents a gift that has been redeemed by a user.
|
|
library;
|
|
|
|
import 'gift_catalog.dart';
|
|
|
|
/// Gift status enum
|
|
enum GiftStatus {
|
|
/// Gift is active and can be used
|
|
active,
|
|
|
|
/// Gift has been used
|
|
used,
|
|
|
|
/// Gift has expired
|
|
expired,
|
|
|
|
/// Gift has been cancelled
|
|
cancelled;
|
|
|
|
/// Get display name for status
|
|
String get displayName {
|
|
switch (this) {
|
|
case GiftStatus.active:
|
|
return 'Active';
|
|
case GiftStatus.used:
|
|
return 'Used';
|
|
case GiftStatus.expired:
|
|
return 'Expired';
|
|
case GiftStatus.cancelled:
|
|
return 'Cancelled';
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Redeemed Gift Entity
|
|
///
|
|
/// Contains information about a redeemed gift:
|
|
/// - Gift details
|
|
/// - Voucher code and QR code
|
|
/// - Usage tracking
|
|
/// - Expiry dates
|
|
class RedeemedGift {
|
|
/// Unique gift identifier
|
|
final String giftId;
|
|
|
|
/// User ID who redeemed the gift
|
|
final String userId;
|
|
|
|
/// Catalog ID of the gift
|
|
final String catalogId;
|
|
|
|
/// Gift name (snapshot at redemption time)
|
|
final String name;
|
|
|
|
/// Gift description
|
|
final String? description;
|
|
|
|
/// Voucher code
|
|
final String? voucherCode;
|
|
|
|
/// QR code image URL
|
|
final String? qrCodeImage;
|
|
|
|
/// Gift type/category
|
|
final GiftCategory giftType;
|
|
|
|
/// Points cost (snapshot at redemption time)
|
|
final int pointsCost;
|
|
|
|
/// Cash value (snapshot at redemption time)
|
|
final double? cashValue;
|
|
|
|
/// Expiry date
|
|
final DateTime? expiryDate;
|
|
|
|
/// Gift status
|
|
final GiftStatus status;
|
|
|
|
/// Redemption timestamp
|
|
final DateTime redeemedAt;
|
|
|
|
/// Usage timestamp
|
|
final DateTime? usedAt;
|
|
|
|
/// Location where gift was used
|
|
final String? usedLocation;
|
|
|
|
/// Reference number when used (e.g., order ID)
|
|
final String? usedReference;
|
|
|
|
const RedeemedGift({
|
|
required this.giftId,
|
|
required this.userId,
|
|
required this.catalogId,
|
|
required this.name,
|
|
this.description,
|
|
this.voucherCode,
|
|
this.qrCodeImage,
|
|
required this.giftType,
|
|
required this.pointsCost,
|
|
this.cashValue,
|
|
this.expiryDate,
|
|
required this.status,
|
|
required this.redeemedAt,
|
|
this.usedAt,
|
|
this.usedLocation,
|
|
this.usedReference,
|
|
});
|
|
|
|
/// Check if gift is active
|
|
bool get isActive => status == GiftStatus.active;
|
|
|
|
/// Check if gift is used
|
|
bool get isUsed => status == GiftStatus.used;
|
|
|
|
/// Check if gift is expired
|
|
bool get isExpired =>
|
|
status == GiftStatus.expired ||
|
|
(expiryDate != null && DateTime.now().isAfter(expiryDate!));
|
|
|
|
/// Check if gift can be used
|
|
bool get canBeUsed => isActive && !isExpired;
|
|
|
|
/// Check if gift is expiring soon (within 7 days)
|
|
bool get isExpiringSoon {
|
|
if (expiryDate == null || isExpired) return false;
|
|
final daysUntilExpiry = expiryDate!.difference(DateTime.now()).inDays;
|
|
return daysUntilExpiry > 0 && daysUntilExpiry <= 7;
|
|
}
|
|
|
|
/// Get days until expiry
|
|
int? get daysUntilExpiry {
|
|
if (expiryDate == null) return null;
|
|
final days = expiryDate!.difference(DateTime.now()).inDays;
|
|
return days > 0 ? days : 0;
|
|
}
|
|
|
|
/// Copy with method for immutability
|
|
RedeemedGift copyWith({
|
|
String? giftId,
|
|
String? userId,
|
|
String? catalogId,
|
|
String? name,
|
|
String? description,
|
|
String? voucherCode,
|
|
String? qrCodeImage,
|
|
GiftCategory? giftType,
|
|
int? pointsCost,
|
|
double? cashValue,
|
|
DateTime? expiryDate,
|
|
GiftStatus? status,
|
|
DateTime? redeemedAt,
|
|
DateTime? usedAt,
|
|
String? usedLocation,
|
|
String? usedReference,
|
|
}) {
|
|
return RedeemedGift(
|
|
giftId: giftId ?? this.giftId,
|
|
userId: userId ?? this.userId,
|
|
catalogId: catalogId ?? this.catalogId,
|
|
name: name ?? this.name,
|
|
description: description ?? this.description,
|
|
voucherCode: voucherCode ?? this.voucherCode,
|
|
qrCodeImage: qrCodeImage ?? this.qrCodeImage,
|
|
giftType: giftType ?? this.giftType,
|
|
pointsCost: pointsCost ?? this.pointsCost,
|
|
cashValue: cashValue ?? this.cashValue,
|
|
expiryDate: expiryDate ?? this.expiryDate,
|
|
status: status ?? this.status,
|
|
redeemedAt: redeemedAt ?? this.redeemedAt,
|
|
usedAt: usedAt ?? this.usedAt,
|
|
usedLocation: usedLocation ?? this.usedLocation,
|
|
usedReference: usedReference ?? this.usedReference,
|
|
);
|
|
}
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (identical(this, other)) return true;
|
|
|
|
return other is RedeemedGift &&
|
|
other.giftId == giftId &&
|
|
other.userId == userId &&
|
|
other.catalogId == catalogId &&
|
|
other.voucherCode == voucherCode &&
|
|
other.status == status;
|
|
}
|
|
|
|
@override
|
|
int get hashCode {
|
|
return Object.hash(giftId, userId, catalogId, voucherCode, status);
|
|
}
|
|
|
|
@override
|
|
String toString() {
|
|
return 'RedeemedGift(giftId: $giftId, name: $name, voucherCode: $voucherCode, '
|
|
'status: $status, redeemedAt: $redeemedAt)';
|
|
}
|
|
}
|