import 'package:equatable/equatable.dart'; import 'package:hive_ce/hive.dart'; import '../../utils/id_generator.dart'; import 'category.dart'; import 'tag.dart'; part 'transaction_record.g.dart'; @HiveType(typeId: 1002) /// Модель записи о транзакции - основной элемент учета бюджета /// Содержит все детали финансовой операции class TransactionRecord extends Equatable { /// Уникальный идентификатор транзакции @HiveField(0) final String id; @HiveField(1) /// Ссылка на категорию транзакции final Category category; @HiveField(2) /// Опциональная ссылка на тег (может быть null) final Tag? tag; @HiveField(3) /// Сумма транзакции (отрицательная для расходов) final double amount; @HiveField(4) /// Дата и время совершения операции final DateTime dateTime; @HiveField(5) /// Название продавца/получателя средств final String vendor; @HiveField(6) /// Валюта операции (код валюты, например "RUB", "USD") final String currency; @HiveField(8) /// Дата и время последнего обновления объекта final DateTime updatedAt; /// Конструктор с обязательными параметрами TransactionRecord({ String? id, required this.category, this.tag, required this.amount, required this.dateTime, required this.vendor, required this.currency, DateTime? updatedAt, // Добавлено поле updatedAt, теперь необязательное }) : id = id ?? IdGenerator.generateId(), updatedAt = updatedAt ?? DateTime.now(); // Устанавливаем текущее время по умолчанию /// Преобразование объекта в Map Map toMap() { return { 'id': id, // Добавляем id в map для fromMap 'category': category.toMap(), 'tag': tag?.toMap(), 'amount': amount, 'dateTime': dateTime.toIso8601String(), 'vendor': vendor, 'currency': currency, 'updatedAt': updatedAt.toIso8601String(), // Добавлено updatedAt в Map }; } /// Создание объекта из Map factory TransactionRecord.fromMap(Map map) { return TransactionRecord( id: map['id'], category: Category.fromMap(map['category']), tag: map['tag'] != null ? Tag.fromMap(map['tag']) : null, amount: map['amount'], dateTime: DateTime.parse(map['dateTime']), vendor: map['vendor'], currency: map['currency'], updatedAt: DateTime.parse( map['updatedAt'], ), // Добавлено updatedAt при создании из Map ); } /// Вспомогательный геттер для определения типа операции /// (доход/расход) на основе категории bool get isIncome => category.isIncome; /// Метод для создания копии объекта с возможностью изменения полей TransactionRecord copyWith({ String? id, Category? category, Tag? tag, double? amount, DateTime? dateTime, String? vendor, String? currency, String? userId, }) { return TransactionRecord( id: id ?? this.id, category: category ?? this.category, tag: tag ?? this.tag, amount: amount ?? this.amount, dateTime: dateTime ?? this.dateTime, vendor: vendor ?? this.vendor, currency: currency ?? this.currency, updatedAt: DateTime.now(), // Обновляем updatedAt при каждом копировании ); } // Используем Equatable для сравнения объектов по их свойствам. // В данном случае, мы считаем записи транзакций уникальными по их 'id'. @override List get props => [id]; }