feat:재무/영업 메뉴 대분류 재구성 시더 추가
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
373
database/seeders/ReorganizeFinanceMenuSeeder.php
Normal file
373
database/seeders/ReorganizeFinanceMenuSeeder.php
Normal file
@@ -0,0 +1,373 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Commons\Menu;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class ReorganizeFinanceMenuSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$tenantId = 1;
|
||||
|
||||
// ==============================
|
||||
// 1. 새 대분류 그룹 생성
|
||||
// ==============================
|
||||
$newGroups = [
|
||||
'재무/자금관리' => ['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}개 메뉴 이동");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user