315 lines
6.9 KiB
Dart
315 lines
6.9 KiB
Dart
/// 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<String, dynamic> 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<String, dynamic> 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<String> 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<String>? 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)';
|
|
}
|
|
}
|