Add backup and restore functionality for rental data in settings
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
@@ -5,7 +5,6 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:rental_income_tracker/models/app_settings.dart';
|
||||
import 'package:rental_income_tracker/models/monthly_rent_record.dart';
|
||||
import 'package:rental_income_tracker/services/notification_service.dart';
|
||||
@@ -417,7 +416,7 @@ class RentController extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> exportJson() async {
|
||||
String _buildBackupJson() {
|
||||
final records = _records.values.toList()
|
||||
..sort((a, b) {
|
||||
final byYear = a.year.compareTo(b.year);
|
||||
@@ -433,14 +432,72 @@ class RentController extends ChangeNotifier {
|
||||
'records': records.map((e) => e.toJson()).toList(),
|
||||
};
|
||||
|
||||
final jsonString = const JsonEncoder.withIndent(' ').convert(payload);
|
||||
final dir = await getApplicationDocumentsDirectory();
|
||||
return const JsonEncoder.withIndent(' ').convert(payload);
|
||||
}
|
||||
|
||||
Future<String> exportBackupToDirectory(String directoryPath) async {
|
||||
final jsonString = _buildBackupJson();
|
||||
final timestamp = DateFormat('yyyyMMdd_HHmmss').format(DateTime.now());
|
||||
final file = File('${dir.path}/rent_tracker_export_$timestamp.json');
|
||||
final normalizedDirectory = directoryPath.endsWith(Platform.pathSeparator)
|
||||
? directoryPath.substring(0, directoryPath.length - 1)
|
||||
: directoryPath;
|
||||
final file = File(
|
||||
'$normalizedDirectory${Platform.pathSeparator}rent_tracker_backup_$timestamp.json',
|
||||
);
|
||||
await file.writeAsString(jsonString);
|
||||
return file.path;
|
||||
}
|
||||
|
||||
Future<void> _restoreFromPayload(Map<String, dynamic> payload) async {
|
||||
final settingsJson = payload['settings'] as Map<String, dynamic>?;
|
||||
final recordsJson = payload['records'] as List<dynamic>?;
|
||||
if (settingsJson == null || recordsJson == null) {
|
||||
throw StateError('Backup file is missing settings or records.');
|
||||
}
|
||||
|
||||
_settings = AppSettings.fromJson(settingsJson);
|
||||
final restoredRecords = <String, MonthlyRentRecord>{};
|
||||
for (final item in recordsJson) {
|
||||
final record = MonthlyRentRecord.fromJson(item as Map<String, dynamic>);
|
||||
restoredRecords[record.key] = record;
|
||||
}
|
||||
_records = restoredRecords;
|
||||
|
||||
await _storageService.saveSettings(_settings);
|
||||
await _storageService.saveRecords(_records);
|
||||
await _notificationService.cancelAll();
|
||||
await _syncNotificationScheduleForCurrentMonth();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<String> importBackupFromFile(String filePath) async {
|
||||
_errorMessage = null;
|
||||
_setLoading(true);
|
||||
|
||||
try {
|
||||
final file = File(filePath);
|
||||
if (!await file.exists()) {
|
||||
throw StateError('Selected backup file could not be found.');
|
||||
}
|
||||
|
||||
final raw = await file.readAsString();
|
||||
final payload = jsonDecode(raw) as Map<String, dynamic>;
|
||||
|
||||
await _restoreFromPayload(payload);
|
||||
|
||||
return file.path;
|
||||
} catch (err, stackTrace) {
|
||||
if (kDebugMode) {
|
||||
debugPrint('[RentController] importBackupFromFile failed: $err');
|
||||
debugPrint(stackTrace.toString());
|
||||
}
|
||||
_errorMessage = err.toString();
|
||||
rethrow;
|
||||
} finally {
|
||||
_setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
List<RentTableRow> buildRowsForSelectedYear() {
|
||||
final now = DateTime.now();
|
||||
final maxMonth = _selectedYear < now.year
|
||||
|
||||
Reference in New Issue
Block a user