import 'package:dartz/dartz.dart'; import '../../../core/errors/failures.dart'; import '../../../domain/entities/company_hierarchy.dart'; import '../../../models/company_model.dart'; import '../../repositories/company_repository.dart'; import '../base_usecase.dart'; /// 회사 계층 구조 조회 파라미터 class GetCompanyHierarchyParams { final bool includeInactive; const GetCompanyHierarchyParams({ this.includeInactive = false, }); } /// 회사 계층 구조 조회 UseCase class GetCompanyHierarchyUseCase extends UseCase { // 레포지토리 기반으로 마이그레이션 final CompanyRepository _companyRepository; GetCompanyHierarchyUseCase(this._companyRepository); @override Future> call(GetCompanyHierarchyParams params) async { try { // 레포지토리에서 전체 회사(계층 구성용) 조회 final companiesEither = await _companyRepository.getCompanyHierarchy( includeInactive: params.includeInactive, ); final hierarchy = companiesEither.fold( (failure) => throw failure, (companies) => _buildHierarchy(companies), ); return Right(hierarchy); } on ServerFailure catch (e) { return Left(ServerFailure( message: e.message, originalError: e, )); } catch (e) { return Left(UnknownFailure( message: '회사 계층 구조 조회 중 오류가 발생했습니다.', originalError: e, )); } } /// 회사 목록을 계층 구조로 변환 CompanyHierarchy _buildHierarchy(List companies) { // 루트 회사들 찾기 (parent_company_id가 null인 회사들) final rootCompanies = companies.where((c) => c.parentCompanyId == null).toList(); // 계층 구조 생성 final children = rootCompanies.map((company) => _buildCompanyNode(company, companies, 0) ).toList(); return CompanyHierarchy( id: '0', name: 'Root', children: children, totalDescendants: _countDescendants(children), ); } /// 회사 노드 생성 (재귀) CompanyHierarchy _buildCompanyNode( Company company, List allCompanies, int level, ) { // 자식 회사들 찾기 final childCompanies = allCompanies .where((c) => c.parentCompanyId == company.id) .toList(); // 자식 노드들 생성 final children = childCompanies .map((child) => _buildCompanyNode(child, allCompanies, level + 1)) .toList(); return CompanyHierarchy( id: company.id.toString(), name: company.name, parentId: company.parentCompanyId?.toString(), children: children, level: level, fullPath: _buildPath(company, allCompanies), totalDescendants: _countDescendants(children), ); } /// 경로 생성 String _buildPath(Company company, List allCompanies) { final path = [company.name]; Company? current = company; while (current?.parentCompanyId != null) { final parent = allCompanies.firstWhere( (c) => c.id == current!.parentCompanyId, orElse: () => Company( id: 0, name: '', ), ); if (parent.id == 0) break; path.insert(0, parent.name); current = parent; } return '/${path.join('/')}'; } /// 자손 수 계산 int _countDescendants(List children) { int count = children.length; for (final child in children) { count += child.totalDescendants; } return count; } }