cashumit/lib/services/firefly_api_service.dart

136 lines
4.4 KiB
Dart

// lib/services/firefly_api_service.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
import '../models/firefly_account.dart';
class FireflyApiService {
/// Mengambil daftar akun dari Firefly III API.
///
/// [baseUrl] adalah URL dasar instance Firefly III (e.g., https://firefly.yourdomain.com).
/// [accessToken] adalah Personal Access Token pengguna.
/// [type] adalah filter opsional untuk tipe akun (e.g., 'asset', 'revenue').
static Future<List<FireflyAccount>> fetchAccounts({
required String baseUrl,
required String accessToken,
String? type,
}) async {
final uri =
type != null ? Uri.parse('$baseUrl/api/v1/accounts?type=$type') : Uri.parse('$baseUrl/api/v1/accounts');
print('DEBUG: Memanggil API untuk mengambil akun. URL: $uri');
final response = await http.get(
uri,
headers: {
'Authorization': 'Bearer $accessToken',
'Accept': 'application/json',
},
);
print('DEBUG: Respons API diterima. Status Code: ${response.statusCode}');
if (response.statusCode == 200) {
final dynamic responseBody = json.decode(response.body);
print('DEBUG: Isi respons (data): ${responseBody['data']}');
if (responseBody is Map<String, dynamic> && responseBody.containsKey('data')) {
final List accountsJson = responseBody['data'] as List;
print('DEBUG: Jumlah akun ditemukan: ${accountsJson.length}');
final List<FireflyAccount> accounts = accountsJson
.map((accountJson) => FireflyAccount.fromJson(accountJson))
.toList();
print('DEBUG: Akun berhasil diparsing. Jumlah akun: ${accounts.length}');
return accounts;
} else {
print('DEBUG: Format respons tidak sesuai harapan. Isi lengkap: $responseBody');
throw Exception('Format respons API tidak sesuai');
}
} else {
// Handle error - misalnya, lempar exception
print('Gagal mengambil akun: ${response.statusCode} - ${response.body}');
throw Exception('Gagal mengambil akun: ${response.statusCode}');
}
}
/// Mengirim transaksi dummy ke Firefly III API.
///
/// [baseUrl] adalah URL dasar instance Firefly III.
/// [accessToken] adalah Personal Access Token pengguna.
/// [sourceId] dan [destinationId] adalah ID akun yang valid.
/// [type] adalah tipe transaksi (default 'deposit').
static Future<bool> submitDummyTransaction({
required String baseUrl,
required String accessToken,
required String sourceId,
required String destinationId,
String type = 'deposit',
String description = 'Pengeluaran Dummy via Flutter App',
String date = '2025-08-19', // Gunakan format ISO 8601
String amount = '50.00',
}) async {
final uri = Uri.parse('$baseUrl/api/v1/transactions');
final payload = jsonEncode({
"transactions": [
{
"type": type,
"date": date,
"amount": amount,
"description": description,
"source_id": sourceId,
"destination_id": destinationId,
}
]
});
print('DEBUG: Mengirim transaksi. URL: $uri, Payload: $payload');
final response = await http.post(
uri,
headers: {
'Authorization': 'Bearer $accessToken',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: payload,
);
print('DEBUG: Respons API transaksi diterima. Status Code: ${response.statusCode}');
if (response.statusCode == 200 || response.statusCode == 201) {
print('Transaksi berhasil dikirim!');
return true;
} else {
print('Gagal mengirim transaksi: ${response.statusCode} - ${response.body}');
return false;
}
}
/// Menguji koneksi ke Firefly III.
static Future<bool> testConnection({required String baseUrl}) async {
try {
final response = await http.get(Uri.parse('$baseUrl/api/v1/about'));
return response.statusCode == 200;
} catch (e) {
return false;
}
}
/// Menguji autentikasi dengan token.
static Future<bool> testAuthentication({required String baseUrl, required String accessToken}) async {
try {
final response = await http.get(
Uri.parse('$baseUrl/api/v1/about/user'),
headers: {
'Authorization': 'Bearer $accessToken',
'Accept': 'application/json',
},
);
return response.statusCode == 200;
} catch (e) {
return false;
}
}
}