['icon' => 'currency-dollar', 'sort' => 6], '회계/세무관리' => ['icon' => 'calculator', 'sort' => 7], '카드/차량관리' => ['icon' => 'credit-card', 'sort' => 8], '정산관리' => ['icon' => 'cash', 'sort' => 9], '고객/거래처/채권관리' => ['icon' => 'users', 'sort' => 10], '영업/매출관리' => ['icon' => 'briefcase', 'sort' => 11], '시스템/설정/내부관리' => ['icon' => 'settings', 'sort' => 12], ]; $parentIds = []; foreach ($newGroups as $name => $config) { $existing = Menu::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('name', $name) ->whereNull('parent_id') ->first(); if ($existing) { $parentIds[$name] = $existing->id; $this->command->info("기존 그룹 사용: {$name} (id: {$existing->id})"); } else { $menu = Menu::create([ 'tenant_id' => $tenantId, 'parent_id' => null, 'name' => $name, 'url' => null, 'icon' => $config['icon'], 'sort_order' => $config['sort'], 'is_active' => true, ]); $parentIds[$name] = $menu->id; $this->command->info("새 그룹 생성: {$name} (id: {$menu->id}, sort: {$config['sort']})"); } } // ============================== // 2. 메뉴 이동 및 이름 변경 정의 // ============================== // [현재 이름 => [새 부모 그룹, 새 sort_order, 새 이름(null이면 변경 없음), 새 URL(null이면 변경 없음)]] $menuMoves = [ // --- 재무/자금관리 --- '재무 대시보드' => ['재무/자금관리', 1, null, null], '일일자금일보' => ['재무/자금관리', 2, null, null], '자금계획일정' => ['재무/자금관리', 3, null, null], '보유계좌관리' => ['재무/자금관리', 4, null, null], '계좌입출금내역' => ['재무/자금관리', 5, null, null], // --- 회계/세무관리 --- '일반전표입력' => ['회계/세무관리', 1, null, null], '전자세금계산서' => ['회계/세무관리', 2, null, null], '홈택스 매출/매입' => ['회계/세무관리', 3, '홈택스매출/매입', null], '부가세관리' => ['회계/세무관리', 4, null, null], // --- 카드/차량관리 --- '법인카드관리' => ['카드/차량관리', 1, null, null], '카드사용내역' => ['카드/차량관리', 2, null, null], '법인차량관리' => ['카드/차량관리', 3, '차량목록', '/finance/corporate-vehicles'], // 차량일지는 아래에서 별도 생성 '차량정비이력' => ['카드/차량관리', 5, '정비이력', null], // --- 정산관리 --- '영업수수료 정산' => ['정산관리', 1, '영업수수료정산', null], '컨설팅비용 정산' => ['정산관리', 2, '컨설팅비용정산', null], '고객사 정산' => ['정산관리', 3, '고객사정산', null], '구독료 정산' => ['정산관리', 4, '구독료정산', null], // --- 고객/거래처/채권관리 --- '거래처 관리' => ['고객/거래처/채권관리', 1, '거래처관리', null], '고객사관리' => ['고객/거래처/채권관리', 2, null, null], '채권관리' => ['고객/거래처/채권관리', 3, '미수금관리', null], '채무관리' => ['고객/거래처/채권관리', 4, '미지급금관리', null], '환불관리' => ['고객/거래처/채권관리', 5, '환불/해지관리', null], // --- 영업/매출관리 --- (영업관리의 자식 중) // 대시보드는 이름이 겹칠 수 있으므로 ID로 처리 // --- 시스템/설정/내부관리 --- // 바로빌본사(15501)는 parent → child로 변환 (아래 별도 처리) ]; // ============================== // 3. 메뉴 이동 실행 // ============================== $movedCount = 0; foreach ($menuMoves as $currentName => [$groupName, $sortOrder, $newName, $newUrl]) { $menu = Menu::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('name', $currentName) ->where('is_active', true) ->first(); if (! $menu) { $this->command->warn("메뉴 없음: {$currentName}"); continue; } $updates = [ 'parent_id' => $parentIds[$groupName], 'sort_order' => $sortOrder, ]; if ($newName) { $updates['name'] = $newName; } if ($newUrl) { $updates['url'] = $newUrl; } $menu->update($updates); $displayName = $newName ?? $currentName; $this->command->info(" 이동: {$currentName} → {$groupName}/{$displayName} (sort: {$sortOrder})"); $movedCount++; } // ============================== // 4. 차량일지 메뉴 이동 또는 생성 // ============================== $vehicleLog = Menu::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('name', '차량일지') ->first(); if ($vehicleLog) { $vehicleLog->update([ 'parent_id' => $parentIds['카드/차량관리'], 'sort_order' => 4, ]); $this->command->info(' 이동: 차량일지 → 카드/차량관리 (sort: 4)'); } else { Menu::create([ 'tenant_id' => $tenantId, 'parent_id' => $parentIds['카드/차량관리'], 'name' => '차량일지', 'url' => '/finance/vehicle-logs', 'icon' => 'clipboard-list', 'sort_order' => 4, 'is_active' => true, ]); $this->command->info(' 신규: 차량일지 → 카드/차량관리 (sort: 4)'); } // ============================== // 5. 영업관리 자식 메뉴 이동 (ID 기반) // ============================== $salesMoves = [ // [현재 ID or name, new sort, new name] ['대시보드', 1, '영업관리 대시보드'], // 15576 ['파트너 관리', 2, '파트너관리'], // 15515 ['영업파트너 승인', 3, '영업파트너승인'], // 15584 ['상품관리', 4, null], // 15581 ['세일즈 사이트', 5, '세일즈사이트'], // 15567 ['렌딩페이지', 6, '랜딩페이지'], // 15568 ]; // 현재 영업관리(15514) 그룹의 자식들 중에서 검색 $salesParent = Menu::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('name', '영업관리') ->whereNull('parent_id') ->first(); if ($salesParent) { $salesChildren = Menu::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('parent_id', $salesParent->id) ->get(); foreach ($salesMoves as [$name, $sort, $rename]) { $child = $salesChildren->firstWhere('name', $name); if ($child) { $updates = [ 'parent_id' => $parentIds['영업/매출관리'], 'sort_order' => $sort, ]; if ($rename) { $updates['name'] = $rename; } $child->update($updates); $displayName = $rename ?? $name; $this->command->info(" 이동: {$name} → 영업/매출관리/{$displayName} (sort: {$sort})"); } else { $this->command->warn(" 영업관리 자식 없음: {$name}"); } } // 영업관리의 나머지 자식들도 영업/매출관리로 이동 $remainingSales = Menu::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('parent_id', $salesParent->id) ->get(); $nextSort = 10; foreach ($remainingSales as $child) { $child->update([ 'parent_id' => $parentIds['영업/매출관리'], 'sort_order' => $nextSort++, ]); $this->command->info(" 이동(잔여): {$child->name} → 영업/매출관리 (sort: ".($nextSort - 1).')'); } } // ============================== // 6. 시스템/설정/내부관리 - 바로빌 관련 메뉴 이동 // ============================== $sysGroupId = $parentIds['시스템/설정/내부관리']; // 바로빌본사(15501) → 자식 메뉴로 변환 $barobillHQ = Menu::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('name', '바로빌본사') ->whereNull('parent_id') ->first(); if ($barobillHQ) { // 바로빌본사의 자식들 먼저 이동 $hqChildren = Menu::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('parent_id', $barobillHQ->id) ->get(); // 회원사관리, 바로빌설정을 시스템/설정/내부관리로 이동 $hqMoves = [ '회원사관리' => 2, '바로빌설정' => 3, ]; foreach ($hqChildren as $child) { $sort = $hqMoves[$child->name] ?? 10; $child->update([ 'parent_id' => $sysGroupId, 'sort_order' => $sort, ]); $this->command->info(" 이동: {$child->name} → 시스템/설정/내부관리 (sort: {$sort})"); } // 바로빌본사 자체를 자식 메뉴로 변환 $barobillHQ->update([ 'parent_id' => $sysGroupId, 'url' => '/barobill/ecard', 'sort_order' => 1, ]); $this->command->info(' 변환: 바로빌본사 → 시스템/설정/내부관리/바로빌본사 (sort: 1)'); } // 바로빌(15504)의 자식들 이동 $barobillTenant = Menu::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('name', '바로빌') ->whereNull('parent_id') ->first(); if ($barobillTenant) { $tenantMoves = [ '사용량조회' => 4, '과금관리' => 5, ]; $barobillChildren = Menu::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('parent_id', $barobillTenant->id) ->get(); foreach ($barobillChildren as $child) { $sort = $tenantMoves[$child->name] ?? 10; $child->update([ 'parent_id' => $sysGroupId, 'sort_order' => $sort, ]); $this->command->info(" 이동: {$child->name} → 시스템/설정/내부관리 (sort: {$sort})"); } // 바로빌 부모 비활성화 $barobillTenant->update(['is_active' => false]); $this->command->info(" 비활성화: 바로빌 (id: {$barobillTenant->id})"); } // 시스템(15518)의 자식도 이동 $sysOld = Menu::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('name', '시스템') ->whereNull('parent_id') ->where('sort_order', 11) ->first(); if ($sysOld) { $sysOldChildren = Menu::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('parent_id', $sysOld->id) ->get(); $nextSort = 20; foreach ($sysOldChildren as $child) { $child->update([ 'parent_id' => $sysGroupId, 'sort_order' => $nextSort++, ]); $this->command->info(" 이동: {$child->name} → 시스템/설정/내부관리 (sort: ".($nextSort - 1).')'); } $sysOld->update(['is_active' => false]); $this->command->info(" 비활성화: 시스템 (id: {$sysOld->id})"); } // ============================== // 7. 빈 부모 그룹 비활성화 // ============================== $oldParents = ['재무관리', '영업관리']; foreach ($oldParents as $name) { $parent = Menu::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('name', $name) ->whereNull('parent_id') ->first(); if ($parent) { // 자식이 남아있는지 확인 $remaining = Menu::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('parent_id', $parent->id) ->where('is_active', true) ->count(); if ($remaining === 0) { $parent->update(['is_active' => false]); $this->command->info(" 비활성화: {$name} (id: {$parent->id})"); } else { $this->command->warn(" 유지: {$name} - 자식 {$remaining}개 남음"); } } } // ============================== // 8. 결과 출력 // ============================== $this->command->info(''); $this->command->info('=== 새 메뉴 구조 ==='); foreach ($newGroups as $name => $config) { $children = Menu::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('parent_id', $parentIds[$name]) ->where('is_active', true) ->orderBy('sort_order') ->get(['name', 'url', 'sort_order']); $this->command->info("📁 {$name}"); foreach ($children as $i => $child) { $prefix = $i === $children->count() - 1 ? ' └─' : ' ├─'; $this->command->info("{$prefix} {$child->name} → {$child->url}"); } } $this->command->info(''); $this->command->info("완료: {$movedCount}개 메뉴 이동"); } }