Files
worker/lib/features/account/domain/entities/user_info.dart
Phuoc Nguyen 0708ed7d6f update info
2025-11-20 10:12:24 +07:00

236 lines
5.9 KiB
Dart

/// Domain Entity: UserInfo
///
/// Represents complete user information fetched from the API.
/// This is a plain Dart class matching the app's entity pattern.
library;
import 'package:worker/core/database/models/enums.dart';
/// UserInfo Entity
///
/// Contains all user account information including:
/// - Personal details (name, email, phone, CCCD)
/// - Role and status
/// - Loyalty program data (tier, points)
/// - Company information
/// - ERPNext integration data
class UserInfo {
/// Unique user identifier (name field from ERPNext)
final String userId;
/// Full name
final String fullName;
/// Email address
final String? email;
/// Phone number
final String? phoneNumber;
/// User role
final UserRole role;
/// Account status
final UserStatus status;
/// Current loyalty tier
final LoyaltyTier loyaltyTier;
/// Total loyalty points earned (lifetime)
final int totalPoints;
/// Available points for redemption
final int availablePoints;
/// Points expiring soon
final int expiringPoints;
/// Avatar image URL
final String? avatarUrl;
/// Company name
final String? companyName;
/// Tax identification number
final String? taxId;
/// Address
final String? address;
/// CCCD/ID card number
final String? cccd;
/// Referral code
final String? referralCode;
/// ERPNext customer ID
final String? erpnextCustomerId;
/// Account creation timestamp
final DateTime createdAt;
/// Last update timestamp
final DateTime updatedAt;
const UserInfo({
required this.userId,
required this.fullName,
this.email,
this.phoneNumber,
required this.role,
required this.status,
required this.loyaltyTier,
required this.totalPoints,
required this.availablePoints,
required this.expiringPoints,
this.avatarUrl,
this.companyName,
this.taxId,
this.address,
this.cccd,
this.referralCode,
this.erpnextCustomerId,
required this.createdAt,
required this.updatedAt,
});
/// Check if user is active
bool get isActive => status == UserStatus.active;
/// Check if user is pending approval
bool get isPending => status == UserStatus.pending;
/// Check if user has company info
bool get hasCompanyInfo =>
companyName != null && companyName!.isNotEmpty;
/// Get user initials for avatar fallback
String get initials {
final nameParts = fullName.trim().split(' ');
if (nameParts.isEmpty) return '?';
if (nameParts.length == 1) {
return nameParts[0].substring(0, 1).toUpperCase();
}
// First letter of first name + first letter of last name
return '${nameParts.first.substring(0, 1)}${nameParts.last.substring(0, 1)}'
.toUpperCase();
}
/// Get tier display name
String get tierDisplayName {
switch (loyaltyTier) {
case LoyaltyTier.titan:
return 'Titan';
case LoyaltyTier.diamond:
return 'Diamond';
case LoyaltyTier.platinum:
return 'Platinum';
case LoyaltyTier.gold:
return 'Gold';
case LoyaltyTier.silver:
return 'Silver';
case LoyaltyTier.bronze:
return 'Bronze';
}
}
/// Copy with method for immutability
UserInfo copyWith({
String? userId,
String? fullName,
String? email,
String? phoneNumber,
UserRole? role,
UserStatus? status,
LoyaltyTier? loyaltyTier,
int? totalPoints,
int? availablePoints,
int? expiringPoints,
String? avatarUrl,
String? companyName,
String? taxId,
String? address,
String? cccd,
String? referralCode,
String? erpnextCustomerId,
DateTime? createdAt,
DateTime? updatedAt,
}) {
return UserInfo(
userId: userId ?? this.userId,
fullName: fullName ?? this.fullName,
email: email ?? this.email,
phoneNumber: phoneNumber ?? this.phoneNumber,
role: role ?? this.role,
status: status ?? this.status,
loyaltyTier: loyaltyTier ?? this.loyaltyTier,
totalPoints: totalPoints ?? this.totalPoints,
availablePoints: availablePoints ?? this.availablePoints,
expiringPoints: expiringPoints ?? this.expiringPoints,
avatarUrl: avatarUrl ?? this.avatarUrl,
companyName: companyName ?? this.companyName,
taxId: taxId ?? this.taxId,
address: address ?? this.address,
cccd: cccd ?? this.cccd,
referralCode: referralCode ?? this.referralCode,
erpnextCustomerId: erpnextCustomerId ?? this.erpnextCustomerId,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt,
);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is UserInfo &&
other.userId == userId &&
other.fullName == fullName &&
other.email == email &&
other.phoneNumber == phoneNumber &&
other.role == role &&
other.status == status &&
other.loyaltyTier == loyaltyTier &&
other.totalPoints == totalPoints &&
other.availablePoints == availablePoints &&
other.expiringPoints == expiringPoints &&
other.avatarUrl == avatarUrl &&
other.companyName == companyName &&
other.taxId == taxId &&
other.address == address &&
other.cccd == cccd &&
other.referralCode == referralCode &&
other.erpnextCustomerId == erpnextCustomerId;
}
@override
int get hashCode {
return Object.hash(
userId,
fullName,
email,
phoneNumber,
role,
status,
loyaltyTier,
totalPoints,
availablePoints,
expiringPoints,
avatarUrl,
companyName,
taxId,
address,
cccd,
referralCode,
erpnextCustomerId,
);
}
@override
String toString() {
return 'UserInfo(userId: $userId, fullName: $fullName, '
'role: $role, status: $status, loyaltyTier: $loyaltyTier, '
'totalPoints: $totalPoints, availablePoints: $availablePoints)';
}
}