update database
This commit is contained in:
151
lib/features/account/domain/entities/audit_log.dart
Normal file
151
lib/features/account/domain/entities/audit_log.dart
Normal file
@@ -0,0 +1,151 @@
|
||||
/// Domain Entity: Audit Log
|
||||
///
|
||||
/// Represents an audit trail entry for system activities.
|
||||
library;
|
||||
|
||||
/// Audit Log Entity
|
||||
///
|
||||
/// Contains information about a system action:
|
||||
/// - User and action details
|
||||
/// - Entity affected
|
||||
/// - Change tracking
|
||||
/// - Session information
|
||||
class AuditLog {
|
||||
/// Unique log identifier
|
||||
final String logId;
|
||||
|
||||
/// User ID who performed the action
|
||||
final String? userId;
|
||||
|
||||
/// Action performed (create, update, delete, login, etc.)
|
||||
final String action;
|
||||
|
||||
/// Entity type affected (user, order, product, etc.)
|
||||
final String? entityType;
|
||||
|
||||
/// Entity ID affected
|
||||
final String? entityId;
|
||||
|
||||
/// Old value (before change)
|
||||
final Map<String, dynamic>? oldValue;
|
||||
|
||||
/// New value (after change)
|
||||
final Map<String, dynamic>? newValue;
|
||||
|
||||
/// IP address of the user
|
||||
final String? ipAddress;
|
||||
|
||||
/// User agent string
|
||||
final String? userAgent;
|
||||
|
||||
/// Timestamp of the action
|
||||
final DateTime timestamp;
|
||||
|
||||
const AuditLog({
|
||||
required this.logId,
|
||||
this.userId,
|
||||
required this.action,
|
||||
this.entityType,
|
||||
this.entityId,
|
||||
this.oldValue,
|
||||
this.newValue,
|
||||
this.ipAddress,
|
||||
this.userAgent,
|
||||
required this.timestamp,
|
||||
});
|
||||
|
||||
/// Check if log has old value
|
||||
bool get hasOldValue => oldValue != null && oldValue!.isNotEmpty;
|
||||
|
||||
/// Check if log has new value
|
||||
bool get hasNewValue => newValue != null && newValue!.isNotEmpty;
|
||||
|
||||
/// Check if action is create
|
||||
bool get isCreate => action.toLowerCase() == 'create';
|
||||
|
||||
/// Check if action is update
|
||||
bool get isUpdate => action.toLowerCase() == 'update';
|
||||
|
||||
/// Check if action is delete
|
||||
bool get isDelete => action.toLowerCase() == 'delete';
|
||||
|
||||
/// Check if action is login
|
||||
bool get isLogin => action.toLowerCase() == 'login';
|
||||
|
||||
/// Check if action is logout
|
||||
bool get isLogout => action.toLowerCase() == 'logout';
|
||||
|
||||
/// Get changed fields
|
||||
List<String> get changedFields {
|
||||
if (!hasOldValue || !hasNewValue) return [];
|
||||
|
||||
final changed = <String>[];
|
||||
for (final key in newValue!.keys) {
|
||||
if (oldValue!.containsKey(key) && oldValue![key] != newValue![key]) {
|
||||
changed.add(key);
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
/// Get time since action
|
||||
Duration get timeSinceAction {
|
||||
return DateTime.now().difference(timestamp);
|
||||
}
|
||||
|
||||
/// Copy with method for immutability
|
||||
AuditLog copyWith({
|
||||
String? logId,
|
||||
String? userId,
|
||||
String? action,
|
||||
String? entityType,
|
||||
String? entityId,
|
||||
Map<String, dynamic>? oldValue,
|
||||
Map<String, dynamic>? newValue,
|
||||
String? ipAddress,
|
||||
String? userAgent,
|
||||
DateTime? timestamp,
|
||||
}) {
|
||||
return AuditLog(
|
||||
logId: logId ?? this.logId,
|
||||
userId: userId ?? this.userId,
|
||||
action: action ?? this.action,
|
||||
entityType: entityType ?? this.entityType,
|
||||
entityId: entityId ?? this.entityId,
|
||||
oldValue: oldValue ?? this.oldValue,
|
||||
newValue: newValue ?? this.newValue,
|
||||
ipAddress: ipAddress ?? this.ipAddress,
|
||||
userAgent: userAgent ?? this.userAgent,
|
||||
timestamp: timestamp ?? this.timestamp,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is AuditLog &&
|
||||
other.logId == logId &&
|
||||
other.userId == userId &&
|
||||
other.action == action &&
|
||||
other.entityType == entityType &&
|
||||
other.entityId == entityId;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return Object.hash(
|
||||
logId,
|
||||
userId,
|
||||
action,
|
||||
entityType,
|
||||
entityId,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AuditLog(logId: $logId, userId: $userId, action: $action, '
|
||||
'entityType: $entityType, entityId: $entityId, timestamp: $timestamp)';
|
||||
}
|
||||
}
|
||||
179
lib/features/account/domain/entities/payment_reminder.dart
Normal file
179
lib/features/account/domain/entities/payment_reminder.dart
Normal file
@@ -0,0 +1,179 @@
|
||||
/// Domain Entity: Payment Reminder
|
||||
///
|
||||
/// Represents a payment reminder for an unpaid invoice.
|
||||
library;
|
||||
|
||||
/// Reminder type enum
|
||||
enum ReminderType {
|
||||
/// Initial reminder before due date
|
||||
initial,
|
||||
|
||||
/// Reminder on due date
|
||||
dueDate,
|
||||
|
||||
/// First reminder after due date
|
||||
firstOverdue,
|
||||
|
||||
/// Second reminder after due date
|
||||
secondOverdue,
|
||||
|
||||
/// Final warning
|
||||
finalWarning;
|
||||
|
||||
/// Get display name for reminder type
|
||||
String get displayName {
|
||||
switch (this) {
|
||||
case ReminderType.initial:
|
||||
return 'Initial Reminder';
|
||||
case ReminderType.dueDate:
|
||||
return 'Due Date Reminder';
|
||||
case ReminderType.firstOverdue:
|
||||
return 'First Overdue';
|
||||
case ReminderType.secondOverdue:
|
||||
return 'Second Overdue';
|
||||
case ReminderType.finalWarning:
|
||||
return 'Final Warning';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Payment Reminder Entity
|
||||
///
|
||||
/// Contains information about a payment reminder:
|
||||
/// - Invoice reference
|
||||
/// - Reminder content
|
||||
/// - Delivery status
|
||||
/// - Scheduling
|
||||
class PaymentReminder {
|
||||
/// Unique reminder identifier
|
||||
final String reminderId;
|
||||
|
||||
/// Invoice ID this reminder is for
|
||||
final String invoiceId;
|
||||
|
||||
/// User ID receiving the reminder
|
||||
final String userId;
|
||||
|
||||
/// Reminder type
|
||||
final ReminderType reminderType;
|
||||
|
||||
/// Reminder subject
|
||||
final String subject;
|
||||
|
||||
/// Reminder message
|
||||
final String message;
|
||||
|
||||
/// Reminder has been read
|
||||
final bool isRead;
|
||||
|
||||
/// Reminder has been sent
|
||||
final bool isSent;
|
||||
|
||||
/// Scheduled send timestamp
|
||||
final DateTime? scheduledAt;
|
||||
|
||||
/// Actual send timestamp
|
||||
final DateTime? sentAt;
|
||||
|
||||
/// Read timestamp
|
||||
final DateTime? readAt;
|
||||
|
||||
const PaymentReminder({
|
||||
required this.reminderId,
|
||||
required this.invoiceId,
|
||||
required this.userId,
|
||||
required this.reminderType,
|
||||
required this.subject,
|
||||
required this.message,
|
||||
required this.isRead,
|
||||
required this.isSent,
|
||||
this.scheduledAt,
|
||||
this.sentAt,
|
||||
this.readAt,
|
||||
});
|
||||
|
||||
/// Check if reminder is pending (scheduled but not sent)
|
||||
bool get isPending => !isSent && scheduledAt != null;
|
||||
|
||||
/// Check if reminder is overdue to be sent
|
||||
bool get isOverdueToSend {
|
||||
if (isSent || scheduledAt == null) return false;
|
||||
return DateTime.now().isAfter(scheduledAt!);
|
||||
}
|
||||
|
||||
/// Check if reminder is unread
|
||||
bool get isUnread => !isRead;
|
||||
|
||||
/// Get time until scheduled send
|
||||
Duration? get timeUntilSend {
|
||||
if (scheduledAt == null || isSent) return null;
|
||||
final duration = scheduledAt!.difference(DateTime.now());
|
||||
return duration.isNegative ? null : duration;
|
||||
}
|
||||
|
||||
/// Get time since sent
|
||||
Duration? get timeSinceSent {
|
||||
if (sentAt == null) return null;
|
||||
return DateTime.now().difference(sentAt!);
|
||||
}
|
||||
|
||||
/// Copy with method for immutability
|
||||
PaymentReminder copyWith({
|
||||
String? reminderId,
|
||||
String? invoiceId,
|
||||
String? userId,
|
||||
ReminderType? reminderType,
|
||||
String? subject,
|
||||
String? message,
|
||||
bool? isRead,
|
||||
bool? isSent,
|
||||
DateTime? scheduledAt,
|
||||
DateTime? sentAt,
|
||||
DateTime? readAt,
|
||||
}) {
|
||||
return PaymentReminder(
|
||||
reminderId: reminderId ?? this.reminderId,
|
||||
invoiceId: invoiceId ?? this.invoiceId,
|
||||
userId: userId ?? this.userId,
|
||||
reminderType: reminderType ?? this.reminderType,
|
||||
subject: subject ?? this.subject,
|
||||
message: message ?? this.message,
|
||||
isRead: isRead ?? this.isRead,
|
||||
isSent: isSent ?? this.isSent,
|
||||
scheduledAt: scheduledAt ?? this.scheduledAt,
|
||||
sentAt: sentAt ?? this.sentAt,
|
||||
readAt: readAt ?? this.readAt,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is PaymentReminder &&
|
||||
other.reminderId == reminderId &&
|
||||
other.invoiceId == invoiceId &&
|
||||
other.userId == userId &&
|
||||
other.reminderType == reminderType &&
|
||||
other.isRead == isRead &&
|
||||
other.isSent == isSent;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return Object.hash(
|
||||
reminderId,
|
||||
invoiceId,
|
||||
userId,
|
||||
reminderType,
|
||||
isRead,
|
||||
isSent,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PaymentReminder(reminderId: $reminderId, invoiceId: $invoiceId, '
|
||||
'reminderType: $reminderType, isSent: $isSent, isRead: $isRead)';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user