diff --git a/database/seeders/ReorganizeFinanceMenuSeeder.php b/database/seeders/ReorganizeFinanceMenuSeeder.php new file mode 100644 index 00000000..86b5e9b3 --- /dev/null +++ b/database/seeders/ReorganizeFinanceMenuSeeder.php @@ -0,0 +1,373 @@ + ['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}개 메뉴 이동"); + } +}