amoriai/lib/models/menu_model.dart

217 lines
5.2 KiB
Dart

import 'package:hive/hive.dart';
part 'menu_model.g.dart';
@HiveType(typeId: 2)
class MenuModel extends HiveObject {
@HiveField(0)
String id;
@HiveField(1)
String name;
@HiveField(2)
String description;
@HiveField(3)
double price;
@HiveField(4)
String category;
@HiveField(5)
List<String> ingredients;
@HiveField(6)
List<String> allergens;
@HiveField(7)
String spiceLevel;
@HiveField(8)
bool isVegetarian;
@HiveField(9)
bool isVegan;
@HiveField(10)
bool isHalal;
@HiveField(11)
String? imageUrl;
@HiveField(12)
double rating;
@HiveField(13)
int reviewCount;
@HiveField(14)
bool isAvailable;
@HiveField(15)
DateTime createdAt;
@HiveField(16)
DateTime updatedAt;
MenuModel({
required this.id,
required this.name,
required this.description,
required this.price,
required this.category,
this.ingredients = const [],
this.allergens = const [],
this.spiceLevel = 'mild',
this.isVegetarian = false,
this.isVegan = false,
this.isHalal = true,
this.imageUrl,
this.rating = 0.0,
this.reviewCount = 0,
this.isAvailable = true,
required this.createdAt,
required this.updatedAt,
});
factory MenuModel.fromJson(Map<String, dynamic> json) {
return MenuModel(
id: json['id'] as String,
name: json['name'] as String,
description: json['description'] as String,
price: (json['price'] as num).toDouble(),
category: json['category'] as String,
ingredients: List<String>.from(json['ingredients'] ?? []),
allergens: List<String>.from(json['allergens'] ?? []),
spiceLevel: json['spiceLevel'] as String? ?? 'mild',
isVegetarian: json['isVegetarian'] as bool? ?? false,
isVegan: json['isVegan'] as bool? ?? false,
isHalal: json['isHalal'] as bool? ?? true,
imageUrl: json['imageUrl'] as String?,
rating: (json['rating'] as num?)?.toDouble() ?? 0.0,
reviewCount: json['reviewCount'] as int? ?? 0,
isAvailable: json['isAvailable'] as bool? ?? true,
createdAt: DateTime.parse(json['createdAt'] as String),
updatedAt: DateTime.parse(json['updatedAt'] as String),
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'description': description,
'price': price,
'category': category,
'ingredients': ingredients,
'allergens': allergens,
'spiceLevel': spiceLevel,
'isVegetarian': isVegetarian,
'isVegan': isVegan,
'isHalal': isHalal,
'imageUrl': imageUrl,
'rating': rating,
'reviewCount': reviewCount,
'isAvailable': isAvailable,
'createdAt': createdAt.toIso8601String(),
'updatedAt': updatedAt.toIso8601String(),
};
}
MenuModel copyWith({
String? id,
String? name,
String? description,
double? price,
String? category,
List<String>? ingredients,
List<String>? allergens,
String? spiceLevel,
bool? isVegetarian,
bool? isVegan,
bool? isHalal,
String? imageUrl,
double? rating,
int? reviewCount,
bool? isAvailable,
DateTime? createdAt,
DateTime? updatedAt,
}) {
return MenuModel(
id: id ?? this.id,
name: name ?? this.name,
description: description ?? this.description,
price: price ?? this.price,
category: category ?? this.category,
ingredients: ingredients ?? this.ingredients,
allergens: allergens ?? this.allergens,
spiceLevel: spiceLevel ?? this.spiceLevel,
isVegetarian: isVegetarian ?? this.isVegetarian,
isVegan: isVegan ?? this.isVegan,
isHalal: isHalal ?? this.isHalal,
imageUrl: imageUrl ?? this.imageUrl,
rating: rating ?? this.rating,
reviewCount: reviewCount ?? this.reviewCount,
isAvailable: isAvailable ?? this.isAvailable,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt,
);
}
String get formattedPrice {
return 'Rp ${price.toStringAsFixed(0).replaceAllMapped(
RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'),
(Match m) => '${m[1]}.',
)}';
}
List<String> get dietaryTags {
List<String> tags = [];
if (isVegetarian) tags.add('Vegetarian');
if (isVegan) tags.add('Vegan');
if (isHalal) tags.add('Halal');
return tags;
}
String get spiceLevelEmoji {
switch (spiceLevel.toLowerCase()) {
case 'mild':
return '🌶️';
case 'medium':
return '🌶️🌶️';
case 'hot':
return '🌶️🌶️🌶️';
case 'very hot':
return '🌶️🌶️🌶️🌶️';
default:
return '';
}
}
bool hasAllergen(String allergen) {
return allergens.any((a) => a.toLowerCase() == allergen.toLowerCase());
}
bool isCompatibleWithPreferences(List<String> userAllergies, String dietaryRestriction) {
// Check allergies
for (String allergy in userAllergies) {
if (hasAllergen(allergy)) {
return false;
}
}
// Check dietary restrictions
switch (dietaryRestriction.toLowerCase()) {
case 'vegetarian':
return isVegetarian;
case 'vegan':
return isVegan;
case 'halal':
return isHalal;
default:
return true;
}
}
}