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