Files
Kifi/kifi-app/lib/features/transactions/data/repository.dart
2026-08-24 18:38:46 +05:30

247 lines
8.4 KiB
Dart

import 'dart:convert';
import 'package:dio/dio.dart';
import '../../../../core/network/dio_client.dart';
import 'models.dart';
class ApiRepository {
final Dio dio = DioClient().dio;
Future<List<Category>> getCategories() async {
final response = await dio.get('/categories');
return (response.data as List).map((j) => Category.fromJson(j)).toList();
}
Future<Category> addCategory(Category category) async {
final response = await dio.post('/categories', data: category.toJson());
return Category.fromJson(response.data);
}
Future<List<Transaction>> getTransactions() async {
final response = await dio.get('/transactions');
return (response.data as List).map((j) => Transaction.fromJson(j)).toList();
}
Future<Map<String, dynamic>> searchTransactions({
String? type,
int? walletId,
int? categoryId,
String? startDate,
String? endDate,
String? search,
int page = 0,
int size = 20,
}) async {
final queryParams = {
if (type != null) 'type': type,
if (walletId != null) 'walletId': walletId,
if (categoryId != null) 'categoryId': categoryId,
if (startDate != null) 'startDate': startDate,
if (endDate != null) 'endDate': endDate,
if (search != null && search.isNotEmpty) 'search': search,
'page': page,
'size': size,
};
final response = await dio.get('/transactions/search', queryParameters: queryParams);
final content = (response.data['content'] as List).map((j) => Transaction.fromJson(j)).toList();
final totalElements = response.data['totalElements'] as int;
final totalPages = response.data['totalPages'] as int;
return {
'content': content,
'totalElements': totalElements,
'totalPages': totalPages,
};
}
Future<Transaction> addTransaction(Transaction transaction) async {
final response = await dio.post('/transactions', data: transaction.toJson());
return Transaction.fromJson(response.data);
}
Future<Transaction> updateTransaction(Transaction transaction) async {
final response = await dio.put('/transactions/${transaction.id}', data: transaction.toJson());
return Transaction.fromJson(response.data);
}
Future<void> deleteTransaction(int id) async {
await dio.delete('/transactions/$id');
}
Future<TransactionAttachment> addAttachment(int transactionId, String fileName, String contentType, String base64Content) async {
final bytes = base64Decode(base64Content);
final formData = FormData.fromMap({
'file': MultipartFile.fromBytes(bytes, filename: fileName, contentType: DioMediaType.parse(contentType)),
});
final response = await dio.post('/transactions/$transactionId/attachments', data: formData);
return TransactionAttachment.fromJson(response.data);
}
Future<void> deleteAttachment(int attachmentId) async {
await dio.delete('/transactions/attachments/$attachmentId');
}
Future<Transaction> closeInvestment(int transactionId, double maturityAmount, DateTime closingDate, int toWalletId) async {
final response = await dio.put('/transactions/$transactionId/close-investment', data: {
'maturityAmount': maturityAmount,
'closingDate': closingDate.toIso8601String().split('T')[0],
'toWalletId': toWalletId,
});
return Transaction.fromJson(response.data);
}
// Budgets
Future<List<Budget>> getBudgets() async {
try {
final response = await dio.get('/budgets');
if (response.data is List) {
return (response.data as List).map((j) => Budget.fromJson(j)).toList();
} else if (response.data is Map && response.data.containsKey('data')) {
return (response.data['data'] as List).map((j) => Budget.fromJson(j)).toList();
}
return [];
} catch (e) {
print('Error fetching budgets: $e');
return [];
}
}
Future<Budget> addOrUpdateBudget(Budget budget) async {
final response = await dio.post('/budgets', data: budget.toJson());
return Budget.fromJson(response.data);
}
// Recurring Transactions
Future<List<RecurringTransaction>> getRecurringTransactions() async {
final response = await dio.get('/recurring-transactions');
return (response.data as List).map((j) => RecurringTransaction.fromJson(j)).toList();
}
Future<RecurringTransaction> addRecurringTransaction(RecurringTransaction rt) async {
final response = await dio.post('/recurring-transactions', data: rt.toJson());
return RecurringTransaction.fromJson(response.data);
}
Future<void> deleteRecurringTransaction(int id) async {
await dio.delete('/recurring-transactions/$id');
}
// Reports
Future<List<int>> exportTransactions() async {
final response = await dio.get(
'/reports/export',
options: Options(responseType: ResponseType.bytes),
);
return response.data;
}
// Wallets
Future<List<Wallet>> getWallets() async {
final response = await dio.get('/wallets');
return (response.data as List).map((j) => Wallet.fromJson(j)).toList();
}
Future<Wallet> createWallet({
required String name,
String nature = 'CASH',
double initialBalance = 0.0,
String? initialBalanceDate,
String currency = 'INR',
String? icon,
String? color,
String? subNature,
double? creditLimit,
double? fixedAmount,
String? paymentCycle,
int? cycleDate,
}) async {
final response = await dio.post('/wallets', data: {
'name': name,
'nature': nature,
'initialBalance': initialBalance,
if (initialBalanceDate != null) 'initialBalanceDate': initialBalanceDate,
'currency': currency,
'icon': icon,
'color': color,
if (subNature != null) 'subNature': subNature,
if (creditLimit != null) 'creditLimit': creditLimit,
if (fixedAmount != null) 'fixedAmount': fixedAmount,
if (paymentCycle != null) 'paymentCycle': paymentCycle,
if (cycleDate != null) 'cycleDate': cycleDate,
});
return Wallet.fromJson(response.data);
}
Future<Wallet> editWallet({
required int id,
String? name,
String? nature,
String? icon,
String? color,
double? initialBalance,
String? initialBalanceDate,
String? subNature,
double? creditLimit,
double? fixedAmount,
String? paymentCycle,
int? cycleDate,
}) async {
final response = await dio.put('/wallets/$id', data: {
if (name != null) 'name': name,
if (nature != null) 'nature': nature,
if (icon != null) 'icon': icon,
if (color != null) 'color': color,
if (initialBalance != null) 'initialBalance': initialBalance,
if (initialBalanceDate != null) 'initialBalanceDate': initialBalanceDate,
if (subNature != null) 'subNature': subNature,
if (creditLimit != null) 'creditLimit': creditLimit,
if (fixedAmount != null) 'fixedAmount': fixedAmount,
if (paymentCycle != null) 'paymentCycle': paymentCycle,
if (cycleDate != null) 'cycleDate': cycleDate,
});
return Wallet.fromJson(response.data);
}
Future<void> deleteWallet(int id) async {
try {
await dio.delete('/wallets/$id');
} on DioException catch (e) {
if (e.response != null && e.response!.data != null && e.response!.data is Map) {
throw Exception(e.response!.data['error'] ?? 'Failed to delete wallet');
}
throw Exception('Failed to delete wallet');
}
}
Future<void> inviteUserToWallet(int walletId, String email) async {
await dio.post('/wallets/$walletId/invite', data: {'email': email});
}
Future<List<WalletInvitation>> getInvitations() async {
final response = await dio.get('/wallets/invitations');
return (response.data as List).map((x) => WalletInvitation.fromJson(x)).toList();
}
Future<void> acceptInvitation(int invitationId) async {
await dio.post('/wallets/invitations/$invitationId/accept');
}
Future<void> rejectInvitation(int invitationId) async {
await dio.post('/wallets/invitations/$invitationId/reject');
}
Future<List<WalletMember>> getWalletMembers(int walletId) async {
final response = await dio.get('/wallets/$walletId/members');
return (response.data as List).map((x) => WalletMember.fromJson(x)).toList();
}
Future<void> removeWalletMember(int walletId, int memberId) async {
await dio.delete('/wallets/$walletId/members/$memberId');
}
Future<List<String>> getKnownContacts() async {
final response = await dio.get('/wallets/user-contacts');
return (response.data as List).map((x) => x.toString()).toList();
}
}