136 lines
4.4 KiB
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;
|
|
}
|
|
}
|
|
} |