Files
flutter_tank_web_app/lib/controller/edit_controller.dart
T
2026-09-25 17:50:01 +02:00

226 lines
6.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../helper/helper.dart' as helper;
import '../models/locationiq_model.dart';
//import '../models/tank_model.dart';
//import '../services/appwrite_service.dart';
import '../models/tank_guru_directus_model.dart';
import '../services/directus_service.dart';
import '../services/geolocation_service.dart';
import '../services/location_iq_service.dart';
import '../pages/home_view.dart';
class EditController extends GetxController {
final DirectusService directusService = DirectusService();
// Form controllers
final dateController = TextEditingController();
final odometerController = TextEditingController();
final litersController = TextEditingController();
final pricePerLiterController = TextEditingController();
final locationController = TextEditingController();
// Observable states
final isLoading = false.obs;
final isNewEntry = true.obs;
final calculatedTotal = '0.00'.obs;
final isLoadingLocation = false.obs;
TankGuruDirectusModel? editingTankModel;
LocationIQ? currentLocationIQ;
String currentUserIdentId = helper.kCurrentUserIdentId; // Use the current user identId from helper
@override
void onInit() {
super.onInit();
// Check if we're editing or creating new
if (Get.arguments != null) {
editingTankModel = Get.arguments as TankGuruDirectusModel;
isNewEntry.value = false;
_loadExistingData();
} else {
isNewEntry.value = true;
_setDefaultDate();
_requestLocationIQ();
}
// Add listeners for automatic calculation
litersController.addListener(_calculateTotal);
pricePerLiterController.addListener(_calculateTotal);
}
void _loadExistingData() {
dateController.text = editingTankModel!.tankDate!;
odometerController.text = editingTankModel!.odometer!;
litersController.text = editingTankModel!.liter!;
pricePerLiterController.text = editingTankModel!.pricePerLiter!;
locationController.text = editingTankModel!.standort!;
calculatedTotal.value = editingTankModel!.szPriceTotal!;
}
void _setDefaultDate() {
final now = DateTime.now();
dateController.text =
'${now.year}-${now.month.toString().padLeft(2, '0')}-${now.day.toString().padLeft(2, '0')}';
}
Future<void> _requestLocationIQ() async {
var geolocationService = GeolocationService();
var locationIQService = LocationIQService();
isLoadingLocation.value = true;
try {
await geolocationService.getCurrentLocation();
if (geolocationService.hasLocation) {
print(
'Aktuelle Position: ${geolocationService.latitude}, ${geolocationService.longitude}',
);
await locationIQService.fetchLocationIQ(
geolocationService.latitude,
geolocationService.longitude,
);
currentLocationIQ = locationIQService.locationIQ;
locationController.text =
currentLocationIQ?.address?.shortAddress ?? '';
} else {
throw Exception('Standort nicht verfügbar');
}
} catch (e) {
Get.snackbar(
"Fehler",
"Standort konnte nicht abgerufen werden: $e",
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.red[100],
colorText: Colors.red[900],
);
print("Fehler beim Abrufen des Standorts: $e");
locationController.text = '';
} finally {
isLoadingLocation.value = false;
}
}
void _calculateTotal() {
final liters =
double.tryParse(litersController.text.replaceAll(',', '.')) ?? 0.0;
final pricePerLiter =
double.tryParse(pricePerLiterController.text.replaceAll(',', '.')) ??
0.0;
calculatedTotal.value = (liters * pricePerLiter).toStringAsFixed(2);
print('$liters L * $pricePerLiter €/L = ${calculatedTotal.value} €');
}
Future<void> selectDate(BuildContext context) async {
final DateTime? picked = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2020),
lastDate: DateTime.now(),
builder: (context, child) {
return Theme(
data: ThemeData.light().copyWith(
colorScheme: ColorScheme.light(
primary: Colors.blueGrey[700]!,
onPrimary: Colors.white,
),
),
child: child!,
);
},
);
if (picked != null) {
dateController.text =
'${picked.year}-${picked.month.toString().padLeft(2, '0')}-${picked.day.toString().padLeft(2, '0')}';
}
}
Future<void> saveTankEntry() async {
if (!_validateForm()) {
Get.snackbar(
'Validierungsfehler',
'Bitte füllen Sie alle Pflichtfelder aus',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.red[100],
colorText: Colors.red[900],
);
return;
}
isLoading.value = true;
try {
final userId = currentUserIdentId;
if (userId == '') {
throw Exception('Benutzer nicht eingeloggt');
}
final data = {
'UserIdentId': userId,
'TankDate': dateController.text,
'Odometer': odometerController.text,
'Liter': litersController.text.replaceAll(',', '.'),
'PricePerLiter': pricePerLiterController.text.replaceAll(',', '.'),
'Standort': locationController.text,
};
bool success;
if (isNewEntry.value) {
success = await directusService.createDocumentInTable(data);
} else {
success = await directusService.updateDocumentInTable(
editingTankModel!.iD,
data,
);
}
if (success) {
Get.snackbar(
'Erfolgreich',
isNewEntry.value
? 'Tankeintrag erstellt'
: 'Tankeintrag aktualisiert',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.green[100],
colorText: Colors.green[900],
);
Get.offAllNamed(HomePage.namedRoute, arguments: {'userIdentId': userId});
} else {
throw Exception('Speichern fehlgeschlagen');
}
} catch (e) {
Get.snackbar(
'Fehler',
'Beim Speichern ist ein Fehler aufgetreten: $e',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.red[100],
colorText: Colors.red[900],
);
} finally {
isLoading.value = false;
}
}
bool _validateForm() {
return dateController.text.isNotEmpty &&
odometerController.text.isNotEmpty &&
litersController.text.isNotEmpty &&
pricePerLiterController.text.isNotEmpty;
}
@override
void onClose() {
dateController.dispose();
odometerController.dispose();
litersController.dispose();
pricePerLiterController.dispose();
locationController.dispose();
super.onClose();
}
void gotToList() {
Get.offAllNamed(HomePage.namedRoute, arguments: {'userIdentId': currentUserIdentId});
}
}