Files
Kifi/kifi-app/lib/features/transactions/data/models.dart
2026-08-16 20:13:21 +05:30

359 lines
10 KiB
Dart

class Category {
final int id;
final String name;
final String? iconName;
Category({required this.id, required this.name, this.iconName});
factory Category.fromJson(Map<String, dynamic> json) {
return Category(
id: json['id'],
name: json['name'],
iconName: json['iconName'],
);
}
Map<String, dynamic> toJson() => {'name': name, 'iconName': iconName};
}
class TransactionItem {
final int? id;
final String name;
final double amount;
TransactionItem({this.id, required this.name, required this.amount});
factory TransactionItem.fromJson(Map<String, dynamic> json) {
return TransactionItem(
id: json['id'],
name: json['name'],
amount: (json['amount'] is int) ? (json['amount'] as int).toDouble() : json['amount'],
);
}
Map<String, dynamic> toJson() => {
'name': name,
'amount': amount,
};
}
class TransactionAttachment {
final int id;
final String fileName;
final String filePath;
final String contentType;
TransactionAttachment({required this.id, required this.fileName, required this.filePath, required this.contentType});
factory TransactionAttachment.fromJson(Map<String, dynamic> json) {
return TransactionAttachment(
id: json['id'],
fileName: json['fileName'],
filePath: json['filePath'],
contentType: json['contentType'],
);
}
}
class Transaction {
final int id;
final int? categoryId;
final int? fromWalletId;
final int? toWalletId;
final String? type; // 'INCOME' or 'EXPENSE' or 'INVESTMENT' (kept for backward compatibility during migration)
final double amount;
final DateTime date;
final String? description;
final String? notes;
final String? investmentStatus;
final double? maturityAmount;
final double? profitLoss;
final DateTime? closingDate;
final DateTime? dueDate;
final String? alertSchedule;
final String? alertTime;
final List<TransactionItem>? items;
final List<TransactionAttachment>? attachments;
Transaction({
required this.id,
this.categoryId,
this.fromWalletId,
this.toWalletId,
this.type,
required this.amount,
required this.date,
this.description,
this.notes,
this.investmentStatus,
this.maturityAmount,
this.profitLoss,
this.closingDate,
this.dueDate,
this.alertSchedule,
this.alertTime,
this.items,
this.attachments,
});
factory Transaction.fromJson(Map<String, dynamic> json) {
return Transaction(
id: json['id'],
categoryId: json['categoryId'],
fromWalletId: json['fromWalletId'],
toWalletId: json['toWalletId'],
type: json['type'],
amount: (json['amount'] is int) ? (json['amount'] as int).toDouble() : json['amount'],
date: DateTime.parse(json['date']),
description: json['description'],
notes: json['notes'],
investmentStatus: json['investmentStatus'],
maturityAmount: json['maturityAmount'] != null ? ((json['maturityAmount'] is int) ? (json['maturityAmount'] as int).toDouble() : json['maturityAmount']) : null,
profitLoss: json['profitLoss'] != null ? ((json['profitLoss'] is int) ? (json['profitLoss'] as int).toDouble() : json['profitLoss']) : null,
closingDate: json['closingDate'] != null ? DateTime.parse(json['closingDate']) : null,
dueDate: json['dueDate'] != null ? DateTime.parse(json['dueDate']) : null,
alertSchedule: json['alertSchedule'],
alertTime: json['alertTime'],
items: json['items'] != null ? (json['items'] as List).map((i) => TransactionItem.fromJson(i)).toList() : null,
attachments: json['attachments'] != null ? (json['attachments'] as List).map((i) => TransactionAttachment.fromJson(i)).toList() : null,
);
}
Map<String, dynamic> toJson() {
final map = <String, dynamic>{
'categoryId': categoryId,
'fromWalletId': fromWalletId,
'toWalletId': toWalletId,
'type': type,
'amount': amount,
'date': date.toIso8601String().split('T')[0],
'description': description,
'notes': notes,
'investmentStatus': investmentStatus,
'maturityAmount': maturityAmount,
'profitLoss': profitLoss,
'closingDate': closingDate?.toIso8601String().split('T')[0],
'dueDate': dueDate?.toIso8601String().split('T')[0],
'alertSchedule': alertSchedule,
'alertTime': alertTime,
};
if (items != null) {
map['items'] = items!.map((i) => i.toJson()).toList();
}
return map;
}
}
class Budget {
final int id;
final int? categoryId;
final int? walletId;
final double monthlyLimit;
final bool isShared;
Budget({required this.id, this.categoryId, this.walletId, required this.monthlyLimit, this.isShared = false});
factory Budget.fromJson(Map<String, dynamic> json) {
double limit = 0.0;
if (json['monthlyLimit'] != null) {
if (json['monthlyLimit'] is num) {
limit = (json['monthlyLimit'] as num).toDouble();
} else if (json['monthlyLimit'] is String) {
limit = double.tryParse(json['monthlyLimit']) ?? 0.0;
}
}
int parseId(dynamic val, [int defaultVal = 0]) {
if (val == null) return defaultVal;
if (val is int) return val;
if (val is num) return val.toInt();
if (val is String) return int.tryParse(val) ?? double.tryParse(val)?.toInt() ?? defaultVal;
return defaultVal;
}
return Budget(
id: parseId(json['id']),
categoryId: json['categoryId'] != null ? parseId(json['categoryId']) : null,
walletId: json['walletId'] != null ? parseId(json['walletId']) : null,
monthlyLimit: limit,
isShared: json['isShared'] ?? false,
);
}
Map<String, dynamic> toJson() => {
'categoryId': categoryId,
'walletId': walletId,
'monthlyLimit': monthlyLimit,
'isShared': isShared,
};
}
class RecurringTransaction {
final int id;
final int? categoryId;
final int? fromWalletId;
final int? toWalletId;
final String type;
final double amount;
final String frequency; // DAILY, WEEKLY, MONTHLY
final DateTime? nextExecutionDate;
final DateTime? endDate;
final String? status;
final String? description;
RecurringTransaction({
required this.id,
this.categoryId,
this.fromWalletId,
this.toWalletId,
required this.type,
required this.amount,
required this.frequency,
this.nextExecutionDate,
this.endDate,
this.status,
this.description,
});
factory RecurringTransaction.fromJson(Map<String, dynamic> json) {
return RecurringTransaction(
id: json['id'],
categoryId: json['categoryId'],
fromWalletId: json['fromWalletId'],
toWalletId: json['toWalletId'],
type: json['type'],
amount: (json['amount'] is int) ? (json['amount'] as int).toDouble() : json['amount'],
frequency: json['frequency'],
nextExecutionDate: json['nextExecutionDate'] != null ? DateTime.parse(json['nextExecutionDate']) : null,
endDate: json['endDate'] != null ? DateTime.parse(json['endDate']) : null,
status: json['status'],
description: json['description'],
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'categoryId': categoryId,
'fromWalletId': fromWalletId,
'toWalletId': toWalletId,
'type': type,
'amount': amount,
'frequency': frequency,
'nextExecutionDate': nextExecutionDate?.toIso8601String(),
'endDate': endDate?.toIso8601String(),
'status': status ?? 'ACTIVE',
'description': description,
};
}
}
class Wallet {
final int id;
final String name;
final int ownerId;
final String? nature;
final double balance;
final String? currency;
final String? icon;
final String? color;
Wallet({
required this.id,
required this.name,
required this.ownerId,
this.nature,
this.balance = 0.0,
this.currency,
this.icon,
this.color,
});
factory Wallet.fromJson(Map<String, dynamic> json) {
int parseId(dynamic val, [int defaultVal = 0]) {
if (val == null) return defaultVal;
if (val is int) return val;
if (val is num) return val.toInt();
if (val is String) return int.tryParse(val) ?? double.tryParse(val)?.toInt() ?? defaultVal;
return defaultVal;
}
double parseDouble(dynamic val, [double defaultVal = 0.0]) {
if (val == null) return defaultVal;
if (val is num) return val.toDouble();
if (val is String) return double.tryParse(val) ?? defaultVal;
return defaultVal;
}
return Wallet(
id: parseId(json['id']),
name: json['name'],
ownerId: parseId(json['ownerId']),
nature: json['nature'],
balance: parseDouble(json['balance']),
currency: json['currency'],
icon: json['icon'],
color: json['color'],
);
}
Map<String, dynamic> toJson() => {
'name': name,
'nature': nature,
'currency': currency,
'initialBalance': balance, // Note: backend uses initialBalance on creation
'icon': icon,
'color': color,
};
}
class WalletInvitation {
final int id;
final int walletId;
final int inviterId;
final String inviteeEmail;
final String status;
final String createdAt;
WalletInvitation({
required this.id,
required this.walletId,
required this.inviterId,
required this.inviteeEmail,
required this.status,
required this.createdAt,
});
factory WalletInvitation.fromJson(Map<String, dynamic> json) {
return WalletInvitation(
id: json['id'],
walletId: json['walletId'],
inviterId: json['inviterId'],
inviteeEmail: json['inviteeEmail'],
status: json['status'],
createdAt: json['createdAt'] ?? '',
);
}
}
class WalletMember {
final int userId;
final String email;
final String role;
final String joinedAt;
WalletMember({
required this.userId,
required this.email,
required this.role,
required this.joinedAt,
});
factory WalletMember.fromJson(Map<String, dynamic> json) {
return WalletMember(
userId: json['userId'],
email: json['email'],
role: json['role'],
joinedAt: json['joinedAt'] ?? '',
);
}
}