Files
worker/lib/features/loyalty/domain/entities/redeemed_gift.dart
2025-10-24 11:31:48 +07:00

208 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)';
}
}