- Add MenuItem model with hierarchical structure support - Implement recursive menu browsing with infinite depth support - Add ExpansionTile for collapsible modifier sections - Implement radio/checkbox logic based on ItemMaxNumSelectionReq - Add automatic pre-selection for ItemIsCheckedByDefault items - Implement validation for ItemRequiresChildSelection and max limits - Add recursive price calculation across all depth levels - Support intelligent selection behavior (radio groups, parent/child deselection) - Add proper error messaging for validation failures - Connect menu items API endpoint - Update navigation flow to menu browse after service point selection
60 lines
1.9 KiB
Dart
60 lines
1.9 KiB
Dart
class MenuItem {
|
|
final int itemId;
|
|
final int categoryId;
|
|
final String name;
|
|
final String description;
|
|
final int parentItemId;
|
|
final double price;
|
|
final bool isActive;
|
|
final bool isCheckedByDefault;
|
|
final bool requiresChildSelection;
|
|
final int maxNumSelectionReq;
|
|
final bool isCollapsible;
|
|
final int sortOrder;
|
|
|
|
const MenuItem({
|
|
required this.itemId,
|
|
required this.categoryId,
|
|
required this.name,
|
|
required this.description,
|
|
required this.parentItemId,
|
|
required this.price,
|
|
required this.isActive,
|
|
required this.isCheckedByDefault,
|
|
required this.requiresChildSelection,
|
|
required this.maxNumSelectionReq,
|
|
required this.isCollapsible,
|
|
required this.sortOrder,
|
|
});
|
|
|
|
factory MenuItem.fromJson(Map<String, dynamic> json) {
|
|
return MenuItem(
|
|
itemId: (json["ItemID"] as num).toInt(),
|
|
categoryId: (json["ItemCategoryID"] as num).toInt(),
|
|
name: (json["ItemName"] as String?) ?? "",
|
|
description: (json["ItemDescription"] as String?) ?? "",
|
|
parentItemId: (json["ItemParentItemID"] as num?)?.toInt() ?? 0,
|
|
price: (json["ItemPrice"] as num?)?.toDouble() ?? 0.0,
|
|
isActive: _parseBool(json["ItemIsActive"]),
|
|
isCheckedByDefault: _parseBool(json["ItemIsCheckedByDefault"]),
|
|
requiresChildSelection: _parseBool(json["ItemRequiresChildSelection"]),
|
|
maxNumSelectionReq: (json["ItemMaxNumSelectionReq"] as num?)?.toInt() ?? 0,
|
|
isCollapsible: _parseBool(json["ItemIsCollapsible"]),
|
|
sortOrder: (json["ItemSortOrder"] as num?)?.toInt() ?? 0,
|
|
);
|
|
}
|
|
|
|
static bool _parseBool(dynamic value) {
|
|
if (value == null) return false;
|
|
if (value is bool) return value;
|
|
if (value is num) return value != 0;
|
|
if (value is String) {
|
|
final lower = value.toLowerCase();
|
|
return lower == "true" || lower == "1";
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool get isRootItem => parentItemId == 0;
|
|
bool get isModifier => parentItemId != 0;
|
|
}
|