class MenuItem { final int itemId; final int categoryId; final String categoryName; 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.categoryName, 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 json) { return MenuItem( itemId: (json["ItemID"] ?? json["itemid"] as num?)?.toInt() ?? 0, categoryId: (json["ItemCategoryID"] ?? json["itemcategoryid"] as num?)?.toInt() ?? 0, categoryName: (json["ItemCategoryName"] ?? json["itemcategoryname"] as String?) ?? "", name: (json["ItemName"] ?? json["itemname"] as String?) ?? "", description: (json["ItemDescription"] ?? json["itemdescription"] as String?) ?? "", parentItemId: (json["ItemParentItemID"] ?? json["itemparentitemid"] as num?)?.toInt() ?? 0, price: (json["ItemPrice"] ?? json["itemprice"] as num?)?.toDouble() ?? 0.0, isActive: _parseBool(json["ItemIsActive"] ?? json["itemisactive"]), isCheckedByDefault: _parseBool(json["ItemIsCheckedByDefault"] ?? json["itemischeckedbydefault"]), requiresChildSelection: _parseBool(json["ItemRequiresChildSelection"] ?? json["itemrequireschildselection"]), maxNumSelectionReq: (json["ItemMaxNumSelectionReq"] ?? json["itemmaxnumselectionreq"] as num?)?.toInt() ?? 0, isCollapsible: _parseBool(json["ItemIsCollapsible"] ?? json["itemiscollapsible"]), sortOrder: (json["ItemSortOrder"] ?? 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; }