211 lines
5.5 KiB
Dart
211 lines
5.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:uuid/uuid.dart';
|
|
|
|
import '../models/kauf_filament_model.dart';
|
|
import '../models/bauteil_model.dart';
|
|
import '../helper/storage_keys.dart';
|
|
import '../helper/filament_bestand.dart';
|
|
import '../helper/display_formats.dart';
|
|
import '../helper/input_validators.dart';
|
|
import '../services/get_storage_services.dart';
|
|
|
|
class HomeController extends GetxController {
|
|
static const storageKey = StorageKeys.filamente;
|
|
|
|
final storage = Get.find<GetStorageService>();
|
|
final uuid = const Uuid();
|
|
|
|
final filamente = <KaufFilamentModel>[].obs;
|
|
final verbrauch = <String, double>{}.obs;
|
|
|
|
void loadVerbrauch() {
|
|
verbrauch.assignAll(
|
|
FilamentBestand.verbrauch(
|
|
storage.getModelList(StorageKeys.bauteile).map(BauteilModel.fromJson),
|
|
),
|
|
);
|
|
}
|
|
|
|
double? restgewicht(KaufFilamentModel filament) {
|
|
final gewicht = filament.gewichtGramm;
|
|
return gewicht == null
|
|
? null
|
|
: gewicht - (verbrauch[filament.filamentId] ?? 0);
|
|
}
|
|
|
|
final formKey = GlobalKey<FormState>();
|
|
final pageScrollController = ScrollController();
|
|
final formScrollController = ScrollController();
|
|
|
|
final haendlerController = TextEditingController();
|
|
final farbeController = TextEditingController();
|
|
final preisController = TextEditingController();
|
|
final markeController = TextEditingController();
|
|
final gewichtController = TextEditingController();
|
|
|
|
final kaufdatum = DateTime.now().obs;
|
|
final material = 'PLA'.obs;
|
|
final editingId = RxnString();
|
|
|
|
final materialien = [
|
|
'PLA',
|
|
'PLA+',
|
|
'PLA light',
|
|
'PLA-CF',
|
|
'PLA+',
|
|
'PETG',
|
|
'PETG-CF',
|
|
'ABS',
|
|
'ASA',
|
|
'TPU',
|
|
'Sonstiges',
|
|
];
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
loadFilamente();
|
|
}
|
|
|
|
void loadFilamente() {
|
|
loadVerbrauch();
|
|
final data = storage.getModelList(storageKey);
|
|
|
|
filamente.assignAll(data.map(KaufFilamentModel.fromJson));
|
|
|
|
sortFilamente();
|
|
}
|
|
|
|
void sortFilamente() {
|
|
filamente.sort((a, b) => b.kaufdatum.compareTo(a.kaufdatum));
|
|
}
|
|
|
|
Future<void> persist() async {
|
|
await storage.saveModelList(
|
|
storageKey,
|
|
filamente.map((f) => f.toJson()).toList(),
|
|
);
|
|
}
|
|
|
|
Future<void> saveFilament() async {
|
|
if (!formKey.currentState!.validate()) return;
|
|
|
|
final preis = double.tryParse(
|
|
preisController.text.trim().replaceAll(',', '.'),
|
|
);
|
|
|
|
if (preis == null || !preis.isFinite || preis < 0) {
|
|
Get.snackbar('Ungültiger Preis', 'Bitte Preis überprüfen.');
|
|
return;
|
|
}
|
|
|
|
loadVerbrauch();
|
|
final gewicht = InputValidators.number(gewichtController.text);
|
|
final bereitsVerbraucht = editingId.value == null
|
|
? 0
|
|
: (verbrauch[editingId.value!] ?? 0);
|
|
if (gewicht == null ||
|
|
!gewicht.isFinite ||
|
|
gewicht <= 0 ||
|
|
gewicht < bereitsVerbraucht) {
|
|
Get.snackbar(
|
|
'Ungültiges Gewicht',
|
|
'Das Startgewicht muss positiv sein und mindestens dem bereits gebuchten Verbrauch entsprechen.',
|
|
);
|
|
return;
|
|
}
|
|
|
|
final filament = KaufFilamentModel(
|
|
filamentId: editingId.value ?? uuid.v4(),
|
|
marke: markeController.text.trim(),
|
|
kaufdatum: kaufdatum.value,
|
|
haendler: haendlerController.text.trim(),
|
|
material: material.value,
|
|
preis: preis,
|
|
farbe: farbeController.text.trim(),
|
|
gewicht: gewicht.toString(),
|
|
);
|
|
|
|
if (editingId.value == null) {
|
|
filamente.add(filament);
|
|
} else {
|
|
final index = filamente.indexWhere(
|
|
(f) => f.filamentId == editingId.value,
|
|
);
|
|
|
|
if (index < 0) {
|
|
Get.snackbar('Fehler', 'Datensatz nicht gefunden.');
|
|
return;
|
|
}
|
|
|
|
filamente[index] = filament;
|
|
}
|
|
|
|
sortFilamente();
|
|
await persist();
|
|
resetForm();
|
|
}
|
|
|
|
Future<void> editFilament(KaufFilamentModel filament) async {
|
|
editingId.value = filament.filamentId;
|
|
kaufdatum.value = filament.kaufdatum;
|
|
markeController.text = filament.marke;
|
|
haendlerController.text = filament.haendler;
|
|
material.value = filament.material;
|
|
preisController.text = filament.preis.toStringAsFixed(2);
|
|
farbeController.text = filament.farbe;
|
|
gewichtController.text = filament.gewichtGramm == null
|
|
? filament.gewicht
|
|
: DisplayFormats.number(filament.gewichtGramm!);
|
|
|
|
final scroll = formScrollController.hasClients
|
|
? formScrollController
|
|
: pageScrollController;
|
|
if (scroll.hasClients) {
|
|
await scroll.animateTo(
|
|
0,
|
|
duration: const Duration(milliseconds: 300),
|
|
curve: Curves.easeOutCubic,
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> duplicateFilament(KaufFilamentModel filament) async {
|
|
filamente.add(filament.copyWith(filamentId: uuid.v4()));
|
|
|
|
sortFilamente();
|
|
await persist();
|
|
}
|
|
|
|
Future<void> deleteFilament(String filamentId) async {
|
|
filamente.removeWhere((f) => f.filamentId == filamentId);
|
|
if (editingId.value == filamentId) resetForm();
|
|
await persist();
|
|
}
|
|
|
|
void resetForm() {
|
|
editingId.value = null;
|
|
haendlerController.clear();
|
|
markeController.clear();
|
|
farbeController.clear();
|
|
preisController.clear();
|
|
kaufdatum.value = DateTime.now();
|
|
material.value = 'PLA';
|
|
gewichtController.clear();
|
|
formKey.currentState?.reset();
|
|
}
|
|
|
|
@override
|
|
void onClose() {
|
|
pageScrollController.dispose();
|
|
formScrollController.dispose();
|
|
haendlerController.dispose();
|
|
markeController.dispose();
|
|
farbeController.dispose();
|
|
preisController.dispose();
|
|
gewichtController.dispose();
|
|
super.onClose();
|
|
}
|
|
}
|