251 lines
7.5 KiB
Dart
251 lines
7.5 KiB
Dart
// lib/screens/transaction_screen.dart
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import '../models/firefly_account.dart';
|
|
import '../services/firefly_api_service.dart';
|
|
|
|
class TransactionScreen extends StatefulWidget {
|
|
const TransactionScreen({super.key});
|
|
|
|
@override
|
|
State<TransactionScreen> createState() => _TransactionScreenState();
|
|
}
|
|
|
|
class _TransactionScreenState extends State<TransactionScreen> {
|
|
List<FireflyAccount> _revenueAccounts = [];
|
|
List<FireflyAccount> _assetAccounts = [];
|
|
FireflyAccount? _selectedSourceAccount;
|
|
FireflyAccount? _selectedDestinationAccount;
|
|
|
|
bool _isLoading = false;
|
|
String _message = '';
|
|
|
|
String? _fireflyUrl;
|
|
String? _accessToken;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_loadCredentialsAndAccounts();
|
|
}
|
|
|
|
/// Memuat kredensial dari shared preferences dan kemudian memuat akun.
|
|
Future<void> _loadCredentialsAndAccounts() async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final url = prefs.getString('firefly_url');
|
|
final token = prefs.getString('firefly_token');
|
|
|
|
if (url == null || token == null || url.isEmpty || token.isEmpty) {
|
|
setState(() {
|
|
_message = 'Kredensial Firefly III belum dikonfigurasi. Silakan atur di menu konfigurasi.';
|
|
});
|
|
return;
|
|
}
|
|
|
|
setState(() {
|
|
_fireflyUrl = url;
|
|
_accessToken = token;
|
|
});
|
|
|
|
// Jika kredensial ada, lanjutkan untuk memuat akun
|
|
_loadAccounts();
|
|
}
|
|
|
|
/// Memuat daftar akun sumber (revenue) dan tujuan (asset) dari API.
|
|
Future<void> _loadAccounts() async {
|
|
if (_fireflyUrl == null || _accessToken == null) {
|
|
return;
|
|
}
|
|
|
|
setState(() {
|
|
_isLoading = true;
|
|
_message = 'Memuat daftar akun...';
|
|
});
|
|
|
|
try {
|
|
// Mengambil akun revenue
|
|
final revenueAccounts = await FireflyApiService.fetchAccounts(
|
|
baseUrl: _fireflyUrl!,
|
|
accessToken: _accessToken!,
|
|
type: 'revenue',
|
|
);
|
|
|
|
// Mengambil akun asset
|
|
final assetAccounts = await FireflyApiService.fetchAccounts(
|
|
baseUrl: _fireflyUrl!,
|
|
accessToken: _accessToken!,
|
|
type: 'asset',
|
|
);
|
|
|
|
setState(() {
|
|
_revenueAccounts = revenueAccounts;
|
|
_assetAccounts = assetAccounts;
|
|
// Reset pilihan jika daftar akun berubah
|
|
_selectedSourceAccount = null;
|
|
_selectedDestinationAccount = null;
|
|
_message = 'Daftar akun berhasil dimuat.';
|
|
});
|
|
} catch (error) {
|
|
setState(() {
|
|
_message = 'Gagal memuat akun: $error';
|
|
});
|
|
} finally {
|
|
setState(() {
|
|
_isLoading = false;
|
|
});
|
|
}
|
|
}
|
|
|
|
/// Mengirim transaksi dummy menggunakan akun yang dipilih.
|
|
Future<void> _submitTransaction() async {
|
|
if (_fireflyUrl == null || _accessToken == null) {
|
|
setState(() {
|
|
_message = 'Kredensial tidak lengkap.';
|
|
return;
|
|
}
|
|
);
|
|
}
|
|
if (_selectedSourceAccount == null || _selectedDestinationAccount == null) {
|
|
setState(() {
|
|
_message = 'Silakan pilih akun sumber dan tujuan.';
|
|
});
|
|
return;
|
|
}
|
|
|
|
setState(() {
|
|
_isLoading = true;
|
|
_message = 'Mengirim transaksi...';
|
|
});
|
|
|
|
try {
|
|
final success = await FireflyApiService.submitDummyTransaction(
|
|
baseUrl: _fireflyUrl!,
|
|
accessToken: _accessToken!,
|
|
sourceId: _selectedSourceAccount!.id,
|
|
destinationId: _selectedDestinationAccount!.id,
|
|
type: 'deposit', // Sesuaikan dengan logika bisnis
|
|
description: 'Transaksi Dummy dari Aplikasi Flutter',
|
|
);
|
|
|
|
setState(() {
|
|
_message = success != null
|
|
? 'Transaksi berhasil dikirim!'
|
|
: 'Gagal mengirim transaksi. Periksa log.';
|
|
});
|
|
} catch (error) {
|
|
setState(() {
|
|
_message = 'Terjadi kesalahan: $error';
|
|
});
|
|
} finally {
|
|
setState(() {
|
|
_isLoading = false;
|
|
});
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: const Text('Kirim Transaksi ke Firefly III'),
|
|
actions: [
|
|
IconButton(
|
|
icon: const Icon(Icons.settings),
|
|
onPressed: () {
|
|
// Navigasi ke ConfigScreen
|
|
Navigator.pushNamed(context, '/config');
|
|
},
|
|
),
|
|
],
|
|
),
|
|
body: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
// Pesan status
|
|
if (_message.isNotEmpty)
|
|
Text(_message,
|
|
style: TextStyle(
|
|
color: _message.contains('berhasil')
|
|
? Colors.green
|
|
: (_message.contains('belum') || _message.contains('tidak')) ? Colors.orange : Colors.red)),
|
|
const SizedBox(height: 10),
|
|
|
|
if (_fireflyUrl != null && _accessToken != null) ...[
|
|
// Dropdown untuk Akun Sumber (Revenue)
|
|
const Text('Pilih Akun Sumber (Revenue):',
|
|
style: TextStyle(fontWeight: FontWeight.bold)),
|
|
DropdownButton<FireflyAccount>(
|
|
isExpanded: true,
|
|
hint: const Text('Pilih akun sumber'),
|
|
value: _selectedSourceAccount,
|
|
items: _revenueAccounts.map((account) {
|
|
return DropdownMenuItem<FireflyAccount>(
|
|
value: account,
|
|
child: Text(account.name),
|
|
);
|
|
}).toList(),
|
|
onChanged: (account) {
|
|
setState(() {
|
|
_selectedSourceAccount = account;
|
|
});
|
|
},
|
|
),
|
|
const SizedBox(height: 20),
|
|
|
|
// Dropdown untuk Akun Tujuan (Asset)
|
|
const Text('Pilih Akun Tujuan (Asset):',
|
|
style: TextStyle(fontWeight: FontWeight.bold)),
|
|
DropdownButton<FireflyAccount>(
|
|
isExpanded: true,
|
|
hint: const Text('Pilih akun tujuan'),
|
|
value: _selectedDestinationAccount,
|
|
items: _assetAccounts.map((account) {
|
|
return DropdownMenuItem<FireflyAccount>(
|
|
value: account,
|
|
child: Text(account.name),
|
|
);
|
|
}).toList(),
|
|
onChanged: (account) {
|
|
setState(() {
|
|
_selectedDestinationAccount = account;
|
|
});
|
|
},
|
|
),
|
|
const SizedBox(height: 20),
|
|
|
|
// Tombol untuk memuat ulang akun
|
|
ElevatedButton.icon(
|
|
onPressed: _isLoading ? null : _loadAccounts,
|
|
icon: const Icon(Icons.refresh),
|
|
label: const Text('Muat Ulang Akun'),
|
|
),
|
|
const SizedBox(height: 10),
|
|
|
|
// Tombol untuk mengirim transaksi
|
|
ElevatedButton.icon(
|
|
onPressed: _isLoading ? null : _submitTransaction,
|
|
icon: const Icon(Icons.send),
|
|
label: const Text('Kirim Transaksi Dummy'),
|
|
),
|
|
const SizedBox(height: 20),
|
|
],
|
|
|
|
// Status dan pesan loading
|
|
if (_isLoading)
|
|
const Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
CircularProgressIndicator(),
|
|
SizedBox(width: 10),
|
|
Text('Sedang diproses...'),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
} |