290 lines
7.4 KiB
Dart
290 lines
7.4 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;
|
|
|
|
/// Date of birth
|
|
final DateTime? dateOfBirth;
|
|
|
|
/// Gender
|
|
final String? gender;
|
|
|
|
/// ID card front image URL
|
|
final String? idCardFront;
|
|
|
|
/// ID card back image URL
|
|
final String? idCardBack;
|
|
|
|
/// Certificate image URLs
|
|
final List<String> certificates;
|
|
|
|
/// Membership verification status text
|
|
final String? membershipStatus;
|
|
|
|
/// Membership status color indicator
|
|
final String? membershipStatusColor;
|
|
|
|
/// Whether user is verified
|
|
final bool isVerified;
|
|
|
|
/// Whether to display credential verification form
|
|
final bool credentialDisplay;
|
|
|
|
/// 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.dateOfBirth,
|
|
this.gender,
|
|
this.idCardFront,
|
|
this.idCardBack,
|
|
this.certificates = const [],
|
|
this.membershipStatus,
|
|
this.membershipStatusColor,
|
|
this.isVerified = false,
|
|
this.credentialDisplay = false,
|
|
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,
|
|
DateTime? dateOfBirth,
|
|
String? gender,
|
|
String? idCardFront,
|
|
String? idCardBack,
|
|
List<String>? certificates,
|
|
String? membershipStatus,
|
|
String? membershipStatusColor,
|
|
bool? isVerified,
|
|
bool? credentialDisplay,
|
|
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,
|
|
dateOfBirth: dateOfBirth ?? this.dateOfBirth,
|
|
gender: gender ?? this.gender,
|
|
idCardFront: idCardFront ?? this.idCardFront,
|
|
idCardBack: idCardBack ?? this.idCardBack,
|
|
certificates: certificates ?? this.certificates,
|
|
membershipStatus: membershipStatus ?? this.membershipStatus,
|
|
membershipStatusColor: membershipStatusColor ?? this.membershipStatusColor,
|
|
isVerified: isVerified ?? this.isVerified,
|
|
credentialDisplay: credentialDisplay ?? this.credentialDisplay,
|
|
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)';
|
|
}
|
|
}
|