270 lines
9.0 KiB
Dart
270 lines
9.0 KiB
Dart
import 'package:appwrite/appwrite.dart';
|
|
import 'package:appwrite/models.dart' as models;
|
|
import 'package:flutter/material.dart';
|
|
import 'package:geolocator/geolocator.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:get_storage/get_storage.dart';
|
|
import 'package:intl/intl.dart';
|
|
import '../../utils/extensions/static_helper.dart';
|
|
import '../../data/repository/location_repository.dart';
|
|
import '../../data/repository/appwrite_repository.dart';
|
|
import '../login/login_view.dart';
|
|
import '../tanklist/tanklist_view.dart';
|
|
|
|
class TankController extends GetxController {
|
|
final _dataBox = GetStorage('MyUserStorage');
|
|
//AppWrite API-REST get Data
|
|
final AppwriteRepository _authRepository = AppwriteRepository();
|
|
// GEOLOCATING Services
|
|
final LocationRepository _locationRepository = LocationRepository();
|
|
|
|
// Rx-Variablen für die UI, um auf Änderungen zu reagieren
|
|
final circleAvatarUserChar = 'A'.obs;
|
|
final userNameToDisplay = 'Test User'.obs;
|
|
final Rx<Position?> currentPosition = Rx<Position?>(null);
|
|
final Rx<bool> isLoading = false.obs;
|
|
final Rx<String?> errorMessage = Rx<String?>(null);
|
|
final rxOrtString = '?'.obs;
|
|
final rxSessionIdString = '?'.obs;
|
|
final rxSummePreisString = '0.00'.obs;
|
|
// TextEditingController für die Formulareingaben
|
|
final formKeyTank = GlobalKey<FormState>();
|
|
bool isFormValid = false;
|
|
DateTime? _selectedDateTime;
|
|
final dateController = TextEditingController();
|
|
final f = DateFormat('yyyy-MM-dd');
|
|
final kilometerStandEdittingController = TextEditingController();
|
|
final mengeController = TextEditingController();
|
|
final pricePerLiterController = TextEditingController();
|
|
final ortController = TextEditingController();
|
|
|
|
final FocusNode firstFocusNode = FocusNode(); // Deklariere den FocusNode
|
|
|
|
// Methode für das ausgewählte Datum
|
|
Future<void> selectDateTime(BuildContext context) async {
|
|
// 1. Datum auswählen
|
|
final DateTime? pickedDate = await showDatePicker(
|
|
context: context,
|
|
initialDate: _selectedDateTime ?? DateTime.now(),
|
|
firstDate: DateTime(2000),
|
|
lastDate: DateTime(2101),
|
|
);
|
|
_selectedDateTime = pickedDate;
|
|
if (_selectedDateTime != null) {
|
|
dateController.text = _selectedDateTime!.toIso8601String().substring(
|
|
0,
|
|
10,
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Methode zum Abrufen des Standorts.
|
|
Future<void> fetchCurrentLocation() async {
|
|
isLoading.value = true;
|
|
errorMessage.value = null;
|
|
try {
|
|
final Position position = await _locationRepository.getCurrentPosition();
|
|
currentPosition.value = position;
|
|
final double latitude = position.latitude;
|
|
final double longitude = position.longitude;
|
|
// Hier kannst du die Logik hinzufügen, um den Standort zu verwenden, z.B.
|
|
// den Standort in der UI anzuzeigen oder an einen Server zu senden.
|
|
var map = {'lat': latitude, 'lng': longitude};
|
|
rxOrtString.value = await _locationRepository.getNearbyLocation(map);
|
|
ortController.text = rxOrtString.value;
|
|
// Print Standortinformationen in der Konsole
|
|
print('Nearby Location: ${rxOrtString.value}');
|
|
print('Current Position: Latitude: $latitude, Longitude: $longitude');
|
|
} catch (e) {
|
|
// Hier fängst du die Fehler aus dem Repository auf
|
|
errorMessage.value = e.toString();
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
update();
|
|
}
|
|
|
|
void clearTextEditingController() {
|
|
formKeyTank.currentState!.reset();
|
|
// Den Fokus wieder auf das erste Feld legen
|
|
FocusScope.of(Get.context!).requestFocus(firstFocusNode);
|
|
// TextEditingController zurücksetzen
|
|
_selectedDateTime = null; // Datum zurücksetzen
|
|
dateController.clear();
|
|
kilometerStandEdittingController.clear();
|
|
mengeController.clear();
|
|
pricePerLiterController.clear();
|
|
ortController.clear();
|
|
}
|
|
|
|
String? validateKilometerStand(String? value) {
|
|
if (value == null || value.isEmpty) {
|
|
return 'Bitte Kilometerstand eingeben';
|
|
}
|
|
if (!GetUtils.isNum(value)) {
|
|
return 'Bitte geben Sie eine gültige Zahl ein';
|
|
}
|
|
return null;
|
|
}
|
|
|
|
String? validateMenge(String? value) {
|
|
if (value == null || value.isEmpty) {
|
|
return 'Bitte Menge eingeben';
|
|
}
|
|
if (!GetUtils.isNum(value)) {
|
|
return 'Bitte geben Sie eine gültige Zahl ein';
|
|
}
|
|
return null;
|
|
}
|
|
|
|
String? validatePricePerLiter(String? value) {
|
|
if (value == null || value.isEmpty) {
|
|
return 'Bitte Preis pro Liter eingeben';
|
|
}
|
|
if (!GetUtils.isNum(value)) {
|
|
return 'Bitte geben Sie eine gültige Zahl ein';
|
|
}
|
|
return null;
|
|
}
|
|
|
|
String? validateOrt(String? value) {
|
|
if (value == null || value.isEmpty) {
|
|
return 'Bitte Ort eingeben...';
|
|
}
|
|
return null;
|
|
}
|
|
|
|
//Go to Login Page
|
|
void logoutSessionAndGoToLoginPage() async {
|
|
// Handle logout logic here
|
|
print('Logout session and go to login page');
|
|
// Clear GetStorage session ID
|
|
StaticHelper.removeFromStorage();
|
|
print('Session ID removed from GetStorage');
|
|
await _authRepository.logout();
|
|
Get.offAndToNamed(LoginPage.namedRoute);
|
|
StaticHelper.getMySnackeBar(
|
|
'Logout', 'Sie wurden abgemeldet!', Colors.blue);
|
|
}
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
// Rufe den Standort direkt beim Initialisieren des Controllers ab, falls gewünscht.
|
|
fetchCurrentLocation();
|
|
}
|
|
|
|
@override
|
|
void onReady() async {
|
|
super.onReady();
|
|
if (_dataBox.hasData('sessionId')) {
|
|
rxSessionIdString(_dataBox.read('sessionId').toString());
|
|
}
|
|
await getCurrentLoggedinUser();
|
|
FocusScope.of(Get.context!).requestFocus(firstFocusNode);
|
|
print('TankController is ready');
|
|
}
|
|
|
|
Future<void> getCurrentLoggedinUser() async {
|
|
await _authRepository.getCurrentUser.then((models.User user) {
|
|
// Hier kannst du den Benutzernamen und das Avatar-Zeichen setzen
|
|
userNameToDisplay.value = user.name;
|
|
circleAvatarUserChar.value = user.name.substring(0, 1).toUpperCase();
|
|
}).catchError((error) {
|
|
print('Fehler beim Abrufen des Benutzers: $error');
|
|
});
|
|
}
|
|
|
|
@override
|
|
void onClose() {
|
|
dateController.dispose();
|
|
kilometerStandEdittingController.dispose();
|
|
mengeController.dispose();
|
|
pricePerLiterController.dispose();
|
|
ortController.dispose();
|
|
firstFocusNode.dispose(); // Dispose den FocusNode
|
|
}
|
|
|
|
void updateSumPrice() {
|
|
final double menge = double.tryParse(mengeController.text) ?? 0.0;
|
|
final double pricePerLiter =
|
|
double.tryParse(pricePerLiterController.text) ?? 0.0;
|
|
final double sumPrice = menge * pricePerLiter;
|
|
rxSummePreisString.value = sumPrice.toStringAsFixed(
|
|
2,
|
|
); // Formatieren auf 2 Dezimalstellen
|
|
}
|
|
|
|
void saveTankstopp() async {
|
|
bool isErrorBySaving = false;
|
|
String messageToUser = '';
|
|
isFormValid = formKeyTank.currentState!.validate();
|
|
if (!isFormValid) {
|
|
print('Formular ist ungültig');
|
|
messageToUser = 'Bitte überprüfen Sie Ihre Eingaben.';
|
|
Get.snackbar(
|
|
'Fehler',
|
|
messageToUser,
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
duration: const Duration(seconds: 2),
|
|
);
|
|
return;
|
|
} else {
|
|
print('Formular ist gültig');
|
|
formKeyTank.currentState!.save();
|
|
try {
|
|
//creatiung a tank stop
|
|
await _authRepository.createTankStop({
|
|
'userId': _dataBox.read('userId'),
|
|
'date': f.format(DateTime.parse(dateController.text)),
|
|
'odometer': kilometerStandEdittingController.text,
|
|
'liters': mengeController.text,
|
|
'pricePerLiter': pricePerLiterController.text,
|
|
'location': ortController.text,
|
|
}).then((models.Document document) {
|
|
print('Tankstopp erfolgreich gespeichert: ${document.data}');
|
|
messageToUser = 'Tankstopp erfolgreich gespeichert!';
|
|
isErrorBySaving = false;
|
|
})
|
|
// Handle specific Appwrite exceptions
|
|
.catchError((error) {
|
|
isErrorBySaving = true;
|
|
if (error is AppwriteException) {
|
|
// Handle specific Appwrite exceptions
|
|
messageToUser = 'Appwrite Fehler: ${error.message}';
|
|
print('Appwrite Fehler: ${error.message}');
|
|
} else {
|
|
// Handle other types of errors
|
|
messageToUser = 'Allgemeiner Fehler: $error';
|
|
print('Allgemeiner Fehler: $error');
|
|
}
|
|
print('Fehler bei der speicherung: $error');
|
|
});
|
|
}
|
|
// Handle any other exceptions that might occur
|
|
catch (e) {
|
|
isErrorBySaving = true;
|
|
messageToUser = 'Fehler beim Speichern des Tankstopps: $e';
|
|
print('Fehler beim speichern: $e');
|
|
}
|
|
if (!isErrorBySaving) {
|
|
clearTextEditingController();
|
|
}
|
|
// Handle button press logic here
|
|
String title = isErrorBySaving ? 'Fehler' : 'Erfolg';
|
|
Get.snackbar(
|
|
title,
|
|
messageToUser,
|
|
backgroundColor: isErrorBySaving ? Colors.red : Colors.green,
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
duration: const Duration(seconds: 4),
|
|
);
|
|
}
|
|
}
|
|
|
|
goToTankStopsView() async {
|
|
clearTextEditingController();
|
|
await Get.offAndToNamed(TanklistPage.namedRoute);
|
|
}
|
|
}
|