import 'account_model.dart'; class AccountTreeNode { final int id; final String code; final String name; final String? accountType; final int? parentId; final int? level; final List children; const AccountTreeNode({ required this.id, required this.code, required this.name, this.accountType, this.parentId, this.level, this.children = const [], }); factory AccountTreeNode.fromJson(Map json) { return AccountTreeNode( id: json['id'] as int, code: json['code'] as String, name: json['name'] as String, accountType: json['account_type'] as String?, parentId: json['parent_id'] as int?, level: json['level'] as int?, children: (json['children'] as List?) ?.map((child) => AccountTreeNode.fromJson(child as Map)) .toList() ?? [], ); } Map toJson() { return { 'id': id, 'code': code, 'name': name, 'account_type': accountType, 'parent_id': parentId, 'level': level, 'children': children.map((child) => child.toJson()).toList(), }; } /// بررسی می‌کند که آیا این حساب فرزند دارد یا نه bool get hasChildren => children.isNotEmpty; /// دریافت تمام حساب‌های قابل انتخاب (بدون فرزند) به صورت تخت List getSelectableAccounts() { List selectable = []; if (!hasChildren) { selectable.add(this); } else { for (final child in children) { selectable.addAll(child.getSelectableAccounts()); } } return selectable; } /// دریافت تمام حساب‌ها به صورت تخت (شامل همه سطوح) List getAllAccounts() { List all = [this]; for (final child in children) { all.addAll(child.getAllAccounts()); } return all; } /// جستجو در درخت حساب‌ها بر اساس نام یا کد List searchAccounts(String query) { final lowerQuery = query.toLowerCase(); return getAllAccounts().where((account) { return account.name.toLowerCase().contains(lowerQuery) || account.code.toLowerCase().contains(lowerQuery); }).toList(); } /// آیا این نود قابل انتخاب است؟ (فقط leaf nodes) bool get isSelectable => !hasChildren; /// نمایش نام کامل با کد String get displayName => '$code - $name'; /// تبدیل به Account Account toAccount() { return Account( id: id, code: code, name: name, accountType: accountType ?? 'accounting_document', parentId: parentId, ); } @override String toString() { return displayName; } @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is AccountTreeNode && other.id == id; } @override int get hashCode => id.hashCode; }