A whole bunch of changes

This commit is contained in:
Courtney Arnold 2026-08-15 17:52:25 -05:00
parent 901ec678a3
commit 956231048e
122 changed files with 5442 additions and 914 deletions

View file

@ -267,6 +267,67 @@ class DatabaseService {
return copied.path;
}
/// Soft-deletes every active vehicle and fuel entry — as if the user had
/// deleted each one individually (see [softDeleteVehicle]/
/// [softDeleteFuelEntry] for why these aren't real `DELETE`s: the
/// tombstones are what let the deletion propagate to other synced devices
/// on the next sync, rather than the rows just being silently re-imported
/// from the cloud copy). Also empties the local receipts folder outright
/// rather than deleting file-by-file, to catch any orphaned file a
/// tracked path might have missed.
Future<void> purgeAllData(DateTime deletedAt) async {
final ts = deletedAt.millisecondsSinceEpoch;
await _db.update(
'fuel_entries',
{'deleted_at': ts, 'updated_at': ts, 'dirty': 1},
where: 'deleted_at IS NULL',
);
await _db.update(
'vehicles',
{'deleted_at': ts, 'updated_at': ts, 'dirty': 1},
where: 'deleted_at IS NULL',
);
if (await receiptsDirectory.exists()) {
await receiptsDirectory.delete(recursive: true);
}
await receiptsDirectory.create(recursive: true);
}
/// Soft-deletes every active fuel entry (across all vehicles) whose
/// [FuelEntry.date] falls within [start]–[end] inclusive, and returns
/// their local receipt image paths so the caller can clean those files up
/// too. Vehicles are left untouched — a date range only makes sense
/// against the fuel entries logged against them, not the vehicles
/// themselves.
Future<List<String>> purgeFuelEntriesInRange(
DateTime start,
DateTime end,
DateTime deletedAt,
) async {
final rangeStart = DateTime(start.year, start.month, start.day).millisecondsSinceEpoch;
final rangeEndExclusive =
DateTime(end.year, end.month, end.day).add(const Duration(days: 1)).millisecondsSinceEpoch;
final ts = deletedAt.millisecondsSinceEpoch;
final rows = await _db.query(
'fuel_entries',
where: 'deleted_at IS NULL AND date >= ? AND date < ?',
whereArgs: [rangeStart, rangeEndExclusive],
);
final localPaths =
rows.map((r) => r['receipt_image_path'] as String?).whereType<String>().toList();
await _db.update(
'fuel_entries',
{'deleted_at': ts, 'updated_at': ts, 'dirty': 1},
where: 'deleted_at IS NULL AND date >= ? AND date < ?',
whereArgs: [rangeStart, rangeEndExclusive],
);
return localPaths;
}
Future<void> deleteReceiptImageFile(String? path) async {
if (path == null) return;
final file = File(path);