Release version 1.0.0

This commit is contained in:
2025-09-16 21:48:33 +02:00
commit a6d27c5f21
165 changed files with 8385 additions and 0 deletions

113
lib/models/refuel.dart Normal file
View File

@@ -0,0 +1,113 @@
import 'dart:convert';
import 'vehicle.dart';
class Refuel {
final String? id;
final String vehicleId;
final FuelType fuelType;
final double liters;
final double pricePerLiter;
final double totalPrice;
final int mileage;
final String? note;
final DateTime? createdAt;
Refuel({
this.id,
required this.vehicleId,
required this.fuelType,
required this.liters,
required this.pricePerLiter,
required this.totalPrice,
required this.mileage,
this.note,
this.createdAt,
});
Refuel copyWith({
String? id,
String? vehicleId,
FuelType? fuelType,
double? liters,
double? pricePerLiter,
double? totalPrice,
int? mileage,
String? note,
DateTime? createdAt,
}) {
return Refuel(
id: id ?? this.id,
vehicleId: vehicleId ?? this.vehicleId,
fuelType: fuelType ?? this.fuelType,
liters: liters ?? this.liters,
pricePerLiter: pricePerLiter ?? this.pricePerLiter,
totalPrice: totalPrice ?? this.totalPrice,
mileage: mileage ?? this.mileage,
note: note ?? this.note,
createdAt: createdAt ?? this.createdAt,
);
}
Map<String, dynamic> toApiMap() {
return {
'vehicleId': vehicleId,
'fuelType': fuelType.name,
'note': note,
'liters': liters,
'pricePerLiter': pricePerLiter,
'totalPrice': totalPrice,
'mileage': mileage,
};
}
factory Refuel.fromApi(Map<String, dynamic> map) {
return Refuel(
id: map['id'] as String?,
vehicleId: map['vehicleId'] as String,
fuelType:
FuelType.values.firstWhere((e) => e.name == map['fuelType'] as String),
note: map['note'] as String?,
liters: (map['liters'] as num).toDouble(),
pricePerLiter: (map['pricePerLiter'] as num).toDouble(),
totalPrice: (map['totalPrice'] as num).toDouble(),
mileage: (map['mileage'] as num).toInt(),
createdAt: map['createdAt'] != null
? DateTime.tryParse(map['createdAt'] as String)
: null,
);
}
Map<String, dynamic> toMap() => {
'id': id,
'vehicleId': vehicleId,
'fuelType': fuelType.name,
'note': note,
'liters': liters,
'pricePerLiter': pricePerLiter,
'totalPrice': totalPrice,
'mileage': mileage,
'createdAt': createdAt?.toIso8601String(),
};
factory Refuel.fromMap(Map<String, dynamic> map) {
return Refuel(
id: map['id'] as String?,
vehicleId: map['vehicleId'] as String,
fuelType:
FuelType.values.firstWhere((e) => e.name == map['fuelType'] as String),
note: map['note'] as String?,
liters: (map['liters'] as num).toDouble(),
pricePerLiter: (map['pricePerLiter'] as num).toDouble(),
totalPrice: (map['totalPrice'] as num).toDouble(),
mileage: (map['mileage'] as num).toInt(),
createdAt: map['createdAt'] != null
? DateTime.tryParse(map['createdAt'] as String)
: null,
);
}
String toJson() => jsonEncode(toMap());
factory Refuel.fromJson(String source) =>
Refuel.fromMap(jsonDecode(source) as Map<String, dynamic>);
}

235
lib/models/service.dart Normal file
View File

@@ -0,0 +1,235 @@
import 'dart:convert';
class ServiceRecord {
final String? id;
final String vehicleId;
final ServiceType serviceType;
final String? customType;
final String? itemName;
final double cost;
final int mileage;
final String? shop;
final bool selfService;
final String? note;
final List<String> photos;
final DateTime? date;
final DateTime? createdAt;
ServiceRecord({
this.id,
required this.vehicleId,
required this.serviceType,
this.customType,
this.itemName,
required this.cost,
required this.mileage,
this.shop,
this.selfService = false,
this.note,
List<String>? photos,
this.date,
this.createdAt,
}) : photos = photos ?? [];
String get displayType =>
serviceType == ServiceType.other && customType != null && customType!.isNotEmpty
? customType!
: serviceType.label;
ServiceRecord copyWith({
String? id,
String? vehicleId,
ServiceType? serviceType,
String? customType,
String? itemName,
double? cost,
int? mileage,
String? shop,
bool? selfService,
String? note,
List<String>? photos,
DateTime? date,
DateTime? createdAt,
}) {
return ServiceRecord(
id: id ?? this.id,
vehicleId: vehicleId ?? this.vehicleId,
serviceType: serviceType ?? this.serviceType,
customType: customType ?? this.customType,
itemName: itemName ?? this.itemName,
cost: cost ?? this.cost,
mileage: mileage ?? this.mileage,
shop: shop ?? this.shop,
selfService: selfService ?? this.selfService,
note: note ?? this.note,
photos: photos ?? List.of(this.photos),
date: date ?? this.date,
createdAt: createdAt ?? this.createdAt,
);
}
Map<String, dynamic> toApiMap() {
return {
'vehicleId': vehicleId,
'serviceType': serviceType.apiValue,
if (customType != null && customType!.isNotEmpty) 'customType': customType,
if (itemName != null) 'itemName': itemName,
'cost': cost,
'mileage': mileage,
if (shop != null && shop!.isNotEmpty) 'shop': shop,
if (selfService) 'selfService': true,
if (note != null) 'note': note,
'photos': photos,
if (date != null) 'date': date!.toUtc().toIso8601String(),
};
}
factory ServiceRecord.fromApi(Map<String, dynamic> map) {
return ServiceRecord(
id: map['id'] as String?,
vehicleId: map['vehicleId'] as String,
serviceType: ServiceTypeX.fromApi(map['serviceType'] as String),
customType: map['customType'] as String?,
itemName: map['itemName'] as String?,
cost: (map['cost'] as num).toDouble(),
mileage: (map['mileage'] as num).toInt(),
shop: map['shop'] as String?,
selfService: map['selfService'] as bool? ?? false,
note: map['note'] as String?,
photos: map['photos'] != null
? List<String>.from(map['photos'] as List)
: [],
date: map['date'] != null
? DateTime.tryParse(map['date'] as String)
: null,
createdAt: map['createdAt'] != null
? DateTime.tryParse(map['createdAt'] as String)
: null,
);
}
Map<String, dynamic> toMap() => {
'id': id,
'vehicleId': vehicleId,
'serviceType': serviceType.apiValue,
'customType': customType,
'itemName': itemName,
'cost': cost,
'mileage': mileage,
'shop': shop,
'selfService': selfService,
'note': note,
'photos': photos,
'date': date?.toIso8601String(),
'createdAt': createdAt?.toIso8601String(),
};
factory ServiceRecord.fromMap(Map<String, dynamic> map) {
return ServiceRecord(
id: map['id'] as String?,
vehicleId: map['vehicleId'] as String,
serviceType: ServiceTypeX.fromApi(map['serviceType'] as String),
customType: map['customType'] as String?,
itemName: map['itemName'] as String?,
cost: (map['cost'] as num).toDouble(),
mileage: (map['mileage'] as num).toInt(),
shop: map['shop'] as String?,
selfService: map['selfService'] as bool? ?? false,
note: map['note'] as String?,
photos: map['photos'] != null
? List<String>.from(map['photos'] as List)
: [],
date: map['date'] != null
? DateTime.tryParse(map['date'] as String)
: null,
createdAt: map['createdAt'] != null
? DateTime.tryParse(map['createdAt'] as String)
: null,
);
}
String toJson() => jsonEncode(toMap());
factory ServiceRecord.fromJson(String source) =>
ServiceRecord.fromMap(jsonDecode(source) as Map<String, dynamic>);
}
enum ServiceType {
airFilter,
oilFilter,
fuelFilter,
cabinFilter,
motorOil,
brakePadFront,
brakePadRear,
sparkPlug,
coolant,
tireChange,
battery,
other,
}
extension ServiceTypeX on ServiceType {
String get label {
switch (this) {
case ServiceType.airFilter:
return 'Air Filter';
case ServiceType.oilFilter:
return 'Oil Filter';
case ServiceType.fuelFilter:
return 'Fuel Filter';
case ServiceType.cabinFilter:
return 'Cabin Filter';
case ServiceType.motorOil:
return 'Motor Oil';
case ServiceType.brakePadFront:
return 'Brake Pads (Front)';
case ServiceType.brakePadRear:
return 'Brake Pads (Rear)';
case ServiceType.sparkPlug:
return 'Spark Plugs';
case ServiceType.coolant:
return 'Coolant';
case ServiceType.tireChange:
return 'Tire Change';
case ServiceType.battery:
return 'Battery';
case ServiceType.other:
return 'Other';
}
}
String get apiValue {
switch (this) {
case ServiceType.airFilter:
return 'air_filter';
case ServiceType.oilFilter:
return 'oil_filter';
case ServiceType.fuelFilter:
return 'fuel_filter';
case ServiceType.cabinFilter:
return 'cabin_filter';
case ServiceType.motorOil:
return 'motor_oil';
case ServiceType.brakePadFront:
return 'brake_pad_front';
case ServiceType.brakePadRear:
return 'brake_pad_rear';
case ServiceType.sparkPlug:
return 'spark_plug';
case ServiceType.coolant:
return 'coolant';
case ServiceType.tireChange:
return 'tire_change';
case ServiceType.battery:
return 'battery';
case ServiceType.other:
return 'other';
}
}
static ServiceType fromApi(String value) {
return ServiceType.values.firstWhere(
(e) => e.apiValue == value,
orElse: () => ServiceType.other);
}
}

104
lib/models/vehicle.dart Normal file
View File

@@ -0,0 +1,104 @@
import 'dart:convert';
enum FuelType { diesel, gasoline95, gasoline98, other }
extension FuelTypeX on FuelType {
String get label {
switch (this) {
case FuelType.diesel:
return 'Diesel';
case FuelType.gasoline95:
return 'Gasoline 95';
case FuelType.gasoline98:
return 'Gasoline 98';
case FuelType.other:
return 'Other';
}
}
static FuelType fromIndex(int index) => FuelType.values[index];
}
class Vehicle {
final String? id;
final String name;
final String registrationPlate;
final FuelType fuelType;
final String? note;
final bool isDefault;
Vehicle({
this.id,
required this.name,
required this.registrationPlate,
required this.fuelType,
this.note,
this.isDefault = false,
});
Vehicle copyWith({
String? id,
String? name,
String? registrationPlate,
FuelType? fuelType,
String? note,
bool? isDefault,
}) {
return Vehicle(
id: id ?? this.id,
name: name ?? this.name,
registrationPlate: registrationPlate ?? this.registrationPlate,
fuelType: fuelType ?? this.fuelType,
note: note ?? this.note,
isDefault: isDefault ?? this.isDefault,
);
}
Map<String, dynamic> toApiMap() {
return {
'name': name,
'registrationPlate': registrationPlate,
'fuelType': fuelType.name,
'note': note,
'isDefault': isDefault,
};
}
factory Vehicle.fromApi(Map<String, dynamic> map) {
return Vehicle(
id: map['id'] as String?,
name: map['name'] as String,
registrationPlate: map['registrationPlate'] as String,
fuelType: FuelType.values
.firstWhere((e) => e.name == map['fuelType'] as String),
note: map['note'] as String?,
isDefault: map['isDefault'] as bool? ?? false,
);
}
Map<String, dynamic> toMap() => {
'id': id,
'name': name,
'registrationPlate': registrationPlate,
'fuelType': fuelType.index,
'note': note,
'isDefault': isDefault,
};
factory Vehicle.fromMap(Map<String, dynamic> map) {
return Vehicle(
id: map['id'] as String?,
name: map['name'] as String,
registrationPlate: map['registrationPlate'] as String,
fuelType: map['fuelType'] is int
? FuelTypeX.fromIndex(map['fuelType'] as int)
: FuelType.values
.firstWhere((e) => e.name == map['fuelType'] as String),
note: map['note'] as String?,
isDefault: map['isDefault'] as bool? ?? false,
);
}
String toJson() => jsonEncode(toMap());
factory Vehicle.fromJson(String source) => Vehicle.fromMap(jsonDecode(source));
}