/// Domain Entity: User /// /// Represents a user account in the Worker application. /// Contains authentication, profile, and loyalty information. library; /// User role enum enum UserRole { /// Customer/worker user customer, /// Sales representative sales, /// System administrator admin, /// Accountant accountant, /// Designer designer; } /// User status enum enum UserStatus { /// Account pending approval pending, /// Active account active, /// Suspended account suspended, /// Rejected account rejected; } /// Loyalty tier enum enum LoyaltyTier { /// No tier none, /// Gold tier (entry level) gold, /// Platinum tier (mid level) platinum, /// Diamond tier (highest level) diamond; /// Get display name for tier String get displayName { switch (this) { case LoyaltyTier.none: return 'NONE'; case LoyaltyTier.gold: return 'GOLD'; case LoyaltyTier.platinum: return 'PLATINUM'; case LoyaltyTier.diamond: return 'DIAMOND'; } } } /// Company information class CompanyInfo { /// Company name final String? name; /// Tax identification number final String? taxId; /// Company address final String? address; /// Business type final String? businessType; /// Business license number final String? licenseNumber; const CompanyInfo({ this.name, this.taxId, this.address, this.businessType, this.licenseNumber, }); /// Create from JSON map factory CompanyInfo.fromJson(Map json) { return CompanyInfo( name: json['name'] as String?, taxId: json['tax_id'] as String?, address: json['address'] as String?, businessType: json['business_type'] as String?, licenseNumber: json['license_number'] as String?, ); } /// Convert to JSON map Map toJson() { return { 'name': name, 'tax_id': taxId, 'address': address, 'business_type': businessType, 'license_number': licenseNumber, }; } } /// User Entity /// /// Represents a complete user profile including: /// - Authentication credentials /// - Personal information /// - Company details (if applicable) /// - Loyalty program membership /// - Referral information class User { /// Unique user identifier final String userId; /// Phone number (used for login) final String phoneNumber; /// Full name final String fullName; /// Email address final String? email; /// User role final UserRole role; /// Account status final UserStatus status; /// Current loyalty tier final LoyaltyTier loyaltyTier; /// Total loyalty points final int totalPoints; /// Company information (optional) final CompanyInfo? companyInfo; /// CCCD/ID card number final String? cccd; /// Attachment URLs (ID cards, licenses, etc.) final List attachments; /// Address final String? address; /// Avatar URL final String? avatarUrl; /// Referral code (unique for this user) final String? referralCode; /// ID of user who referred this user final String? referredBy; /// ERPNext customer ID final String? erpnextCustomerId; /// Account creation timestamp final DateTime createdAt; /// Last update timestamp final DateTime updatedAt; /// Last login timestamp final DateTime? lastLoginAt; const User({ required this.userId, required this.phoneNumber, required this.fullName, this.email, required this.role, required this.status, required this.loyaltyTier, required this.totalPoints, this.companyInfo, this.cccd, required this.attachments, this.address, this.avatarUrl, this.referralCode, this.referredBy, this.erpnextCustomerId, required this.createdAt, required this.updatedAt, this.lastLoginAt, }); /// 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 => companyInfo != null && companyInfo!.name != null; /// Check if user is an admin bool get isAdmin => role == UserRole.admin; /// Check if user is a customer bool get isCustomer => role == UserRole.customer; /// Get display name for user String get displayName => fullName; /// Copy with method for immutability User copyWith({ String? userId, String? phoneNumber, String? fullName, String? email, UserRole? role, UserStatus? status, LoyaltyTier? loyaltyTier, int? totalPoints, CompanyInfo? companyInfo, String? cccd, List? attachments, String? address, String? avatarUrl, String? referralCode, String? referredBy, String? erpnextCustomerId, DateTime? createdAt, DateTime? updatedAt, DateTime? lastLoginAt, }) { return User( userId: userId ?? this.userId, phoneNumber: phoneNumber ?? this.phoneNumber, fullName: fullName ?? this.fullName, email: email ?? this.email, role: role ?? this.role, status: status ?? this.status, loyaltyTier: loyaltyTier ?? this.loyaltyTier, totalPoints: totalPoints ?? this.totalPoints, companyInfo: companyInfo ?? this.companyInfo, cccd: cccd ?? this.cccd, attachments: attachments ?? this.attachments, address: address ?? this.address, avatarUrl: avatarUrl ?? this.avatarUrl, referralCode: referralCode ?? this.referralCode, referredBy: referredBy ?? this.referredBy, erpnextCustomerId: erpnextCustomerId ?? this.erpnextCustomerId, createdAt: createdAt ?? this.createdAt, updatedAt: updatedAt ?? this.updatedAt, lastLoginAt: lastLoginAt ?? this.lastLoginAt, ); } @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is User && other.userId == userId && other.phoneNumber == phoneNumber && other.fullName == fullName && other.email == email && other.role == role && other.status == status && other.loyaltyTier == loyaltyTier && other.totalPoints == totalPoints && other.cccd == cccd && other.address == address && other.avatarUrl == avatarUrl && other.referralCode == referralCode && other.referredBy == referredBy && other.erpnextCustomerId == erpnextCustomerId; } @override int get hashCode { return Object.hash( userId, phoneNumber, fullName, email, role, status, loyaltyTier, totalPoints, cccd, address, avatarUrl, referralCode, referredBy, erpnextCustomerId, ); } @override String toString() { return 'User(userId: $userId, phoneNumber: $phoneNumber, fullName: $fullName, ' 'role: $role, status: $status, loyaltyTier: $loyaltyTier, totalPoints: $totalPoints)'; } }