add import export and items
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import '../helper/storage_keys.dart';
|
||||
import 'anwendung_model.dart';
|
||||
import 'bauteil_model.dart';
|
||||
import 'kauf_filament_model.dart';
|
||||
|
||||
class BackupModel {
|
||||
static const keys = [
|
||||
StorageKeys.filamente,
|
||||
StorageKeys.anwendungen,
|
||||
StorageKeys.bauteile,
|
||||
StorageKeys.materialien,
|
||||
];
|
||||
final Map<String, List<Map<String, dynamic>>> data;
|
||||
|
||||
const BackupModel(this.data);
|
||||
|
||||
String encode() => const JsonEncoder.withIndent(' ').convert({
|
||||
'format': 'ertl_filament_verwaltung',
|
||||
'version': 1,
|
||||
'exportiertAm': DateTime.now().toUtc().toIso8601String(),
|
||||
'daten': data,
|
||||
});
|
||||
|
||||
factory BackupModel.decode(String source) {
|
||||
try {
|
||||
final json =
|
||||
jsonDecode(source.replaceFirst(RegExp(r'^\uFEFF'), '')) as Map;
|
||||
if (json['format'] != 'ertl_filament_verwaltung' ||
|
||||
json['version'] != 1) {
|
||||
throw const FormatException();
|
||||
}
|
||||
final raw = json['daten'] as Map;
|
||||
final data = <String, List<Map<String, dynamic>>>{
|
||||
for (final key in keys)
|
||||
key: (raw[key] as List)
|
||||
.map((item) => Map<String, dynamic>.from(item as Map))
|
||||
.toList(),
|
||||
};
|
||||
final filamentIds = <String>{};
|
||||
for (final json in data[StorageKeys.filamente]!) {
|
||||
final item = KaufFilamentModel.fromJson(json);
|
||||
if (item.filamentId.isEmpty ||
|
||||
!filamentIds.add(item.filamentId) ||
|
||||
item.material.trim().isEmpty ||
|
||||
!_positive(item.gewichtGramm) ||
|
||||
!_nonNegative(item.preis)) {
|
||||
throw const FormatException();
|
||||
}
|
||||
}
|
||||
final profileIds = <String>{};
|
||||
for (final json in data[StorageKeys.anwendungen]!) {
|
||||
final item = AnwendungModel.fromJson(json);
|
||||
if (item.anwendungId.isEmpty ||
|
||||
!profileIds.add(item.anwendungId) ||
|
||||
item.filamentId.isEmpty ||
|
||||
!_positive(item.druckTemperatur) ||
|
||||
!_nonNegative(item.druckbettTemperatur) ||
|
||||
(item.bauraumTemperatur != null &&
|
||||
!_nonNegative(item.bauraumTemperatur!))) {
|
||||
throw const FormatException();
|
||||
}
|
||||
}
|
||||
final partIds = <String>{};
|
||||
for (final json in data[StorageKeys.bauteile]!) {
|
||||
final item = BauteilModel.fromJson(json);
|
||||
if (item.bauteilId.isEmpty ||
|
||||
!partIds.add(item.bauteilId) ||
|
||||
item.name.trim().isEmpty ||
|
||||
item.druckdauerMinuten <= 0 ||
|
||||
!_positive(item.gewichtGramm) ||
|
||||
!_nonNegative(item.abfallGramm) ||
|
||||
item.filamente.isEmpty ||
|
||||
item.filamente.any(
|
||||
(entry) =>
|
||||
entry.filamentId.isEmpty ||
|
||||
!_nonNegative(entry.verbrauchGramm),
|
||||
)) {
|
||||
throw const FormatException();
|
||||
}
|
||||
if (item.fotoBase64 != null) base64Decode(item.fotoBase64!);
|
||||
}
|
||||
final materials = data[StorageKeys.materialien]!;
|
||||
if (materials.isNotEmpty) {
|
||||
if (materials.length != 1) throw const FormatException();
|
||||
final values = (materials.single['werte'] as List).cast<String>();
|
||||
if (values.any((value) => value.trim().isEmpty) ||
|
||||
values.map((value) => value.toLowerCase()).toSet().length !=
|
||||
values.length) {
|
||||
throw const FormatException();
|
||||
}
|
||||
}
|
||||
return BackupModel(data);
|
||||
} catch (_) {
|
||||
throw const FormatException(
|
||||
'Ungültige oder nicht unterstützte Datensicherung. Bitte eine vollständige JSON-Datei dieser App auswählen.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static bool _nonNegative(num value) => value.isFinite && value >= 0;
|
||||
static bool _positive(num? value) =>
|
||||
value != null && value.isFinite && value > 0;
|
||||
}
|
||||
Reference in New Issue
Block a user