class AdminInventoryItem { final int id; final int userId; final String username; final String userEmail; final int productId; final String productName; final String? productCanonicalName; final int? categoryId; final String? categoryPath; final double quantity; final String unit; final String? location; final String? brand; final String? receiptName; final String? suitableFor; final String? comment; const AdminInventoryItem({ required this.id, required this.userId, required this.username, required this.userEmail, required this.productId, required this.productName, this.productCanonicalName, this.categoryId, this.categoryPath, required this.quantity, required this.unit, this.location, this.brand, this.receiptName, this.suitableFor, this.comment, }); String get displayName { final canonical = productCanonicalName?.trim(); if (canonical != null && canonical.isNotEmpty) return canonical; return productName; } factory AdminInventoryItem.fromJson(Map json) { final user = (json['user'] as Map?) ?? const {}; final product = (json['product'] as Map?) ?? const {}; final names = []; dynamic current = product['categoryRef']; while (current is Map) { final name = current['name']?.toString().trim(); if (name != null && name.isNotEmpty) { names.insert(0, name); } current = current['parent']; } return AdminInventoryItem( id: json['id'] as int, userId: json['userId'] as int, username: user['username'] as String? ?? '', userEmail: user['email'] as String? ?? '', productId: json['productId'] as int, productName: product['name'] as String? ?? '', productCanonicalName: product['canonicalName'] as String?, categoryId: (product['categoryId'] as num?)?.toInt(), categoryPath: names.isEmpty ? null : names.join(' > '), quantity: double.tryParse(json['quantity']?.toString() ?? '0') ?? 0, unit: json['unit'] as String? ?? '', location: json['location'] as String?, brand: json['brand'] as String?, receiptName: json['receiptName'] as String?, suitableFor: json['suitableFor'] as String?, comment: json['comment'] as String?, ); } }