diff --git a/app/Http/Controllers/Finance/PayableController.php b/app/Http/Controllers/Finance/PayableController.php new file mode 100644 index 00000000..f8dac82d --- /dev/null +++ b/app/Http/Controllers/Finance/PayableController.php @@ -0,0 +1,181 @@ +input('search')) { + $query->where(function ($q) use ($search) { + $q->where('vendor_name', 'like', "%{$search}%") + ->orWhere('invoice_no', 'like', "%{$search}%"); + }); + } + + if ($status = $request->input('status')) { + if ($status !== 'all') { + $query->where('status', $status); + } + } + + if ($category = $request->input('category')) { + if ($category !== 'all') { + $query->where('category', $category); + } + } + + $payables = $query->orderBy('created_at', 'desc') + ->get() + ->map(function ($item) { + return [ + 'id' => $item->id, + 'vendorName' => $item->vendor_name, + 'invoiceNo' => $item->invoice_no, + 'issueDate' => $item->issue_date?->format('Y-m-d'), + 'dueDate' => $item->due_date?->format('Y-m-d'), + 'category' => $item->category, + 'amount' => $item->amount, + 'paidAmount' => $item->paid_amount, + 'status' => $item->status, + 'description' => $item->description, + 'memo' => $item->memo, + ]; + }); + + $all = Payable::forTenant($tenantId)->get(); + + $totalAmount = $all->sum('amount'); + $totalPaid = $all->sum('paid_amount'); + $overdueAmount = $all->where('status', 'overdue')->sum(function ($item) { + return $item->amount - $item->paid_amount; + }); + + $stats = [ + 'totalAmount' => $totalAmount, + 'totalPaid' => $totalPaid, + 'totalUnpaid' => $totalAmount - $totalPaid, + 'overdueAmount' => $overdueAmount, + 'count' => $all->count(), + ]; + + return response()->json([ + 'success' => true, + 'data' => $payables, + 'stats' => $stats, + ]); + } + + public function store(Request $request): JsonResponse + { + $request->validate([ + 'vendorName' => 'required|string|max:100', + 'invoiceNo' => 'required|string|max:50', + 'amount' => 'required|integer|min:0', + ]); + + $tenantId = session('selected_tenant_id', 1); + + Payable::create([ + 'tenant_id' => $tenantId, + 'vendor_name' => $request->input('vendorName'), + 'invoice_no' => $request->input('invoiceNo'), + 'issue_date' => $request->input('issueDate'), + 'due_date' => $request->input('dueDate'), + 'category' => $request->input('category', '사무용품'), + 'amount' => $request->input('amount', 0), + 'paid_amount' => 0, + 'status' => 'unpaid', + 'description' => $request->input('description'), + 'memo' => $request->input('memo'), + ]); + + return response()->json([ + 'success' => true, + 'message' => '미지급금이 등록되었습니다.', + ]); + } + + public function update(Request $request, int $id): JsonResponse + { + $tenantId = session('selected_tenant_id', 1); + $payable = Payable::forTenant($tenantId)->findOrFail($id); + + $request->validate([ + 'vendorName' => 'required|string|max:100', + 'invoiceNo' => 'required|string|max:50', + 'amount' => 'required|integer|min:0', + ]); + + $payable->update([ + 'vendor_name' => $request->input('vendorName'), + 'invoice_no' => $request->input('invoiceNo'), + 'issue_date' => $request->input('issueDate'), + 'due_date' => $request->input('dueDate'), + 'category' => $request->input('category'), + 'amount' => $request->input('amount'), + 'status' => $request->input('status', $payable->status), + 'description' => $request->input('description'), + 'memo' => $request->input('memo'), + ]); + + return response()->json([ + 'success' => true, + 'message' => '미지급금이 수정되었습니다.', + ]); + } + + public function pay(Request $request, int $id): JsonResponse + { + $tenantId = session('selected_tenant_id', 1); + $payable = Payable::forTenant($tenantId)->findOrFail($id); + + $request->validate([ + 'payAmount' => 'required|integer|min:1', + ]); + + $payAmount = $request->input('payAmount'); + $remaining = $payable->amount - $payable->paid_amount; + + if ($payAmount > $remaining) { + return response()->json([ + 'success' => false, + 'message' => '지급액이 잔액을 초과합니다.', + ], 422); + } + + $newPaid = $payable->paid_amount + $payAmount; + $newStatus = $newPaid >= $payable->amount ? 'paid' : 'partial'; + + $payable->update([ + 'paid_amount' => $newPaid, + 'status' => $newStatus, + ]); + + return response()->json([ + 'success' => true, + 'message' => '지급 처리되었습니다.', + ]); + } + + public function destroy(int $id): JsonResponse + { + $tenantId = session('selected_tenant_id', 1); + $payable = Payable::forTenant($tenantId)->findOrFail($id); + $payable->delete(); + + return response()->json([ + 'success' => true, + 'message' => '미지급금이 삭제되었습니다.', + ]); + } +} diff --git a/app/Http/Controllers/Finance/ReceivableController.php b/app/Http/Controllers/Finance/ReceivableController.php new file mode 100644 index 00000000..e836ffb2 --- /dev/null +++ b/app/Http/Controllers/Finance/ReceivableController.php @@ -0,0 +1,182 @@ +input('search')) { + $query->where(function ($q) use ($search) { + $q->where('customer_name', 'like', "%{$search}%") + ->orWhere('invoice_no', 'like', "%{$search}%"); + }); + } + + if ($status = $request->input('status')) { + if ($status !== 'all') { + $query->where('status', $status); + } + } + + if ($category = $request->input('category')) { + if ($category !== 'all') { + $query->where('category', $category); + } + } + + $receivables = $query->orderBy('created_at', 'desc') + ->get() + ->map(function ($item) { + return [ + 'id' => $item->id, + 'customerName' => $item->customer_name, + 'invoiceNo' => $item->invoice_no, + 'issueDate' => $item->issue_date?->format('Y-m-d'), + 'dueDate' => $item->due_date?->format('Y-m-d'), + 'category' => $item->category, + 'amount' => $item->amount, + 'collectedAmount' => $item->collected_amount, + 'status' => $item->status, + 'description' => $item->description, + 'memo' => $item->memo, + ]; + }); + + $allQuery = Receivable::forTenant($tenantId); + $all = (clone $allQuery)->get(); + + $totalAmount = $all->sum('amount'); + $totalCollected = $all->sum('collected_amount'); + $overdueAmount = $all->where('status', 'overdue')->sum(function ($item) { + return $item->amount - $item->collected_amount; + }); + + $stats = [ + 'totalAmount' => $totalAmount, + 'totalCollected' => $totalCollected, + 'totalOutstanding' => $totalAmount - $totalCollected, + 'overdueAmount' => $overdueAmount, + 'count' => $all->count(), + ]; + + return response()->json([ + 'success' => true, + 'data' => $receivables, + 'stats' => $stats, + ]); + } + + public function store(Request $request): JsonResponse + { + $request->validate([ + 'customerName' => 'required|string|max:100', + 'invoiceNo' => 'required|string|max:50', + 'amount' => 'required|integer|min:0', + ]); + + $tenantId = session('selected_tenant_id', 1); + + $receivable = Receivable::create([ + 'tenant_id' => $tenantId, + 'customer_name' => $request->input('customerName'), + 'invoice_no' => $request->input('invoiceNo'), + 'issue_date' => $request->input('issueDate'), + 'due_date' => $request->input('dueDate'), + 'category' => $request->input('category', '서비스'), + 'amount' => $request->input('amount', 0), + 'collected_amount' => 0, + 'status' => 'outstanding', + 'description' => $request->input('description'), + 'memo' => $request->input('memo'), + ]); + + return response()->json([ + 'success' => true, + 'message' => '미수금이 등록되었습니다.', + ]); + } + + public function update(Request $request, int $id): JsonResponse + { + $tenantId = session('selected_tenant_id', 1); + $receivable = Receivable::forTenant($tenantId)->findOrFail($id); + + $request->validate([ + 'customerName' => 'required|string|max:100', + 'invoiceNo' => 'required|string|max:50', + 'amount' => 'required|integer|min:0', + ]); + + $receivable->update([ + 'customer_name' => $request->input('customerName'), + 'invoice_no' => $request->input('invoiceNo'), + 'issue_date' => $request->input('issueDate'), + 'due_date' => $request->input('dueDate'), + 'category' => $request->input('category'), + 'amount' => $request->input('amount'), + 'status' => $request->input('status', $receivable->status), + 'description' => $request->input('description'), + 'memo' => $request->input('memo'), + ]); + + return response()->json([ + 'success' => true, + 'message' => '미수금이 수정되었습니다.', + ]); + } + + public function collect(Request $request, int $id): JsonResponse + { + $tenantId = session('selected_tenant_id', 1); + $receivable = Receivable::forTenant($tenantId)->findOrFail($id); + + $request->validate([ + 'collectAmount' => 'required|integer|min:1', + ]); + + $collectAmount = $request->input('collectAmount'); + $remaining = $receivable->amount - $receivable->collected_amount; + + if ($collectAmount > $remaining) { + return response()->json([ + 'success' => false, + 'message' => '수금액이 잔액을 초과합니다.', + ], 422); + } + + $newCollected = $receivable->collected_amount + $collectAmount; + $newStatus = $newCollected >= $receivable->amount ? 'collected' : 'partial'; + + $receivable->update([ + 'collected_amount' => $newCollected, + 'status' => $newStatus, + ]); + + return response()->json([ + 'success' => true, + 'message' => '수금 처리되었습니다.', + ]); + } + + public function destroy(int $id): JsonResponse + { + $tenantId = session('selected_tenant_id', 1); + $receivable = Receivable::forTenant($tenantId)->findOrFail($id); + $receivable->delete(); + + return response()->json([ + 'success' => true, + 'message' => '미수금이 삭제되었습니다.', + ]); + } +} diff --git a/app/Http/Controllers/Finance/RefundController.php b/app/Http/Controllers/Finance/RefundController.php new file mode 100644 index 00000000..83938748 --- /dev/null +++ b/app/Http/Controllers/Finance/RefundController.php @@ -0,0 +1,176 @@ +input('search')) { + $query->where(function ($q) use ($search) { + $q->where('customer_name', 'like', "%{$search}%") + ->orWhere('product_name', 'like', "%{$search}%"); + }); + } + + if ($status = $request->input('status')) { + if ($status !== 'all') { + $query->where('status', $status); + } + } + + if ($type = $request->input('type')) { + if ($type !== 'all') { + $query->where('type', $type); + } + } + + $refunds = $query->orderBy('created_at', 'desc') + ->get() + ->map(function ($item) { + return [ + 'id' => $item->id, + 'type' => $item->type, + 'customerName' => $item->customer_name, + 'requestDate' => $item->request_date?->format('Y-m-d'), + 'productName' => $item->product_name, + 'originalAmount' => $item->original_amount, + 'refundAmount' => $item->refund_amount, + 'reason' => $item->reason, + 'status' => $item->status, + 'processDate' => $item->process_date?->format('Y-m-d'), + 'note' => $item->note, + ]; + }); + + $all = Refund::forTenant($tenantId)->get(); + + $stats = [ + 'pending' => $all->where('status', 'pending')->count(), + 'completed' => $all->where('status', 'completed')->count(), + 'rejected' => $all->where('status', 'rejected')->count(), + 'totalRefunded' => $all->whereIn('status', ['completed', 'approved'])->sum('refund_amount'), + ]; + + return response()->json([ + 'success' => true, + 'data' => $refunds, + 'stats' => $stats, + ]); + } + + public function store(Request $request): JsonResponse + { + $request->validate([ + 'customerName' => 'required|string|max:100', + 'productName' => 'required|string|max:100', + 'originalAmount' => 'required|integer|min:0', + 'type' => 'required|in:refund,cancel', + ]); + + $tenantId = session('selected_tenant_id', 1); + + Refund::create([ + 'tenant_id' => $tenantId, + 'type' => $request->input('type', 'refund'), + 'customer_name' => $request->input('customerName'), + 'request_date' => $request->input('requestDate'), + 'product_name' => $request->input('productName'), + 'original_amount' => $request->input('originalAmount', 0), + 'refund_amount' => 0, + 'reason' => $request->input('reason'), + 'status' => 'pending', + 'note' => $request->input('note'), + ]); + + return response()->json([ + 'success' => true, + 'message' => '환불/해지 요청이 등록되었습니다.', + ]); + } + + public function update(Request $request, int $id): JsonResponse + { + $tenantId = session('selected_tenant_id', 1); + $refund = Refund::forTenant($tenantId)->findOrFail($id); + + $request->validate([ + 'customerName' => 'required|string|max:100', + 'productName' => 'required|string|max:100', + 'originalAmount' => 'required|integer|min:0', + ]); + + $refund->update([ + 'type' => $request->input('type', $refund->type), + 'customer_name' => $request->input('customerName'), + 'request_date' => $request->input('requestDate'), + 'product_name' => $request->input('productName'), + 'original_amount' => $request->input('originalAmount'), + 'refund_amount' => $request->input('refundAmount', $refund->refund_amount), + 'reason' => $request->input('reason'), + 'status' => $request->input('status', $refund->status), + 'process_date' => $request->input('processDate'), + 'note' => $request->input('note'), + ]); + + return response()->json([ + 'success' => true, + 'message' => '환불/해지 요청이 수정되었습니다.', + ]); + } + + public function process(Request $request, int $id): JsonResponse + { + $tenantId = session('selected_tenant_id', 1); + $refund = Refund::forTenant($tenantId)->findOrFail($id); + + $request->validate([ + 'action' => 'required|in:approved,completed,rejected', + ]); + + $action = $request->input('action'); + $today = now()->format('Y-m-d'); + + if ($action === 'rejected') { + $refund->update([ + 'status' => 'rejected', + 'refund_amount' => 0, + 'process_date' => $today, + 'note' => $request->input('note'), + ]); + } else { + $refund->update([ + 'status' => $action, + 'refund_amount' => $request->input('refundAmount', 0), + 'process_date' => $today, + 'note' => $request->input('note'), + ]); + } + + return response()->json([ + 'success' => true, + 'message' => '처리되었습니다.', + ]); + } + + public function destroy(int $id): JsonResponse + { + $tenantId = session('selected_tenant_id', 1); + $refund = Refund::forTenant($tenantId)->findOrFail($id); + $refund->delete(); + + return response()->json([ + 'success' => true, + 'message' => '환불/해지 요청이 삭제되었습니다.', + ]); + } +} diff --git a/app/Http/Controllers/Finance/TradingPartnerController.php b/app/Http/Controllers/Finance/TradingPartnerController.php new file mode 100644 index 00000000..8641b078 --- /dev/null +++ b/app/Http/Controllers/Finance/TradingPartnerController.php @@ -0,0 +1,178 @@ +input('search')) { + $query->where(function ($q) use ($search) { + $q->where('name', 'like', "%{$search}%") + ->orWhere('manager', 'like', "%{$search}%"); + }); + } + + if ($type = $request->input('type')) { + if ($type !== 'all') { + $query->where('type', $type); + } + } + + if ($category = $request->input('category')) { + if ($category !== 'all') { + $query->where('category', $category); + } + } + + if ($status = $request->input('status')) { + if ($status !== 'all') { + $query->where('status', $status); + } + } + + $partners = $query->orderBy('created_at', 'desc') + ->get() + ->map(function ($partner) { + return [ + 'id' => $partner->id, + 'name' => $partner->name, + 'type' => $partner->type, + 'category' => $partner->category, + 'bizNo' => $partner->biz_no, + 'bankAccount' => $partner->bank_account, + 'contact' => $partner->contact, + 'email' => $partner->email, + 'manager' => $partner->manager, + 'managerPhone' => $partner->manager_phone, + 'status' => $partner->status, + 'memo' => $partner->memo, + ]; + }); + + $allPartners = TradingPartner::forTenant($tenantId); + $stats = [ + 'total' => (clone $allPartners)->count(), + 'vendor' => (clone $allPartners)->where('type', 'vendor')->count(), + 'freelancer' => (clone $allPartners)->where('type', 'freelancer')->count(), + 'active' => (clone $allPartners)->where('status', 'active')->count(), + ]; + + return response()->json([ + 'success' => true, + 'data' => $partners, + 'stats' => $stats, + ]); + } + + public function store(Request $request): JsonResponse + { + $request->validate([ + 'name' => 'required|string|max:100', + 'type' => 'required|in:vendor,freelancer', + 'category' => 'required|string|max:50', + ]); + + $tenantId = session('selected_tenant_id', 1); + + $partner = TradingPartner::create([ + 'tenant_id' => $tenantId, + 'name' => $request->input('name'), + 'type' => $request->input('type', 'vendor'), + 'category' => $request->input('category', '기타'), + 'biz_no' => $request->input('bizNo'), + 'bank_account' => $request->input('bankAccount'), + 'contact' => $request->input('contact'), + 'email' => $request->input('email'), + 'manager' => $request->input('manager'), + 'manager_phone' => $request->input('managerPhone'), + 'status' => $request->input('status', 'active'), + 'memo' => $request->input('memo'), + ]); + + return response()->json([ + 'success' => true, + 'message' => '거래처가 등록되었습니다.', + 'data' => [ + 'id' => $partner->id, + 'name' => $partner->name, + 'type' => $partner->type, + 'category' => $partner->category, + 'bizNo' => $partner->biz_no, + 'bankAccount' => $partner->bank_account, + 'contact' => $partner->contact, + 'email' => $partner->email, + 'manager' => $partner->manager, + 'managerPhone' => $partner->manager_phone, + 'status' => $partner->status, + 'memo' => $partner->memo, + ], + ]); + } + + public function update(Request $request, int $id): JsonResponse + { + $tenantId = session('selected_tenant_id', 1); + $partner = TradingPartner::forTenant($tenantId)->findOrFail($id); + + $request->validate([ + 'name' => 'required|string|max:100', + 'type' => 'required|in:vendor,freelancer', + 'category' => 'required|string|max:50', + ]); + + $partner->update([ + 'name' => $request->input('name'), + 'type' => $request->input('type'), + 'category' => $request->input('category'), + 'biz_no' => $request->input('bizNo'), + 'bank_account' => $request->input('bankAccount'), + 'contact' => $request->input('contact'), + 'email' => $request->input('email'), + 'manager' => $request->input('manager'), + 'manager_phone' => $request->input('managerPhone'), + 'status' => $request->input('status', 'active'), + 'memo' => $request->input('memo'), + ]); + + return response()->json([ + 'success' => true, + 'message' => '거래처가 수정되었습니다.', + 'data' => [ + 'id' => $partner->id, + 'name' => $partner->name, + 'type' => $partner->type, + 'category' => $partner->category, + 'bizNo' => $partner->biz_no, + 'bankAccount' => $partner->bank_account, + 'contact' => $partner->contact, + 'email' => $partner->email, + 'manager' => $partner->manager, + 'managerPhone' => $partner->manager_phone, + 'status' => $partner->status, + 'memo' => $partner->memo, + ], + ]); + } + + public function destroy(int $id): JsonResponse + { + $tenantId = session('selected_tenant_id', 1); + $partner = TradingPartner::forTenant($tenantId)->findOrFail($id); + $partner->delete(); + + return response()->json([ + 'success' => true, + 'message' => '거래처가 삭제되었습니다.', + ]); + } +} diff --git a/app/Models/Finance/Payable.php b/app/Models/Finance/Payable.php new file mode 100644 index 00000000..6338f334 --- /dev/null +++ b/app/Models/Finance/Payable.php @@ -0,0 +1,39 @@ + 'integer', + 'paid_amount' => 'integer', + 'issue_date' => 'date', + 'due_date' => 'date', + ]; + + public function scopeForTenant($query, $tenantId) + { + return $query->where('tenant_id', $tenantId); + } +} diff --git a/app/Models/Finance/Receivable.php b/app/Models/Finance/Receivable.php new file mode 100644 index 00000000..bb449af0 --- /dev/null +++ b/app/Models/Finance/Receivable.php @@ -0,0 +1,39 @@ + 'integer', + 'collected_amount' => 'integer', + 'issue_date' => 'date', + 'due_date' => 'date', + ]; + + public function scopeForTenant($query, $tenantId) + { + return $query->where('tenant_id', $tenantId); + } +} diff --git a/app/Models/Finance/Refund.php b/app/Models/Finance/Refund.php new file mode 100644 index 00000000..3ac0d404 --- /dev/null +++ b/app/Models/Finance/Refund.php @@ -0,0 +1,39 @@ + 'integer', + 'refund_amount' => 'integer', + 'request_date' => 'date', + 'process_date' => 'date', + ]; + + public function scopeForTenant($query, $tenantId) + { + return $query->where('tenant_id', $tenantId); + } +} diff --git a/app/Models/Finance/TradingPartner.php b/app/Models/Finance/TradingPartner.php new file mode 100644 index 00000000..b9c11c81 --- /dev/null +++ b/app/Models/Finance/TradingPartner.php @@ -0,0 +1,38 @@ +where('status', 'active'); + } + + public function scopeForTenant($query, $tenantId) + { + return $query->where('tenant_id', $tenantId); + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index a46a4728..b9d84580 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -9,6 +9,8 @@ use App\Observers\FileObserver; use App\Services\SidebarMenuService; use Illuminate\Database\Eloquent\Relations\Relation; +use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\View; use Illuminate\Support\ServiceProvider; @@ -38,6 +40,17 @@ public function boot(): void 'department' => Department::class, ]); + // 일회성 메뉴명 변경: 협력사관리 → 거래처 관리 + if (! Cache::has('menu_rename_partner_to_vendor')) { + $updated = DB::table('menus') + ->where('tenant_id', 1) + ->whereIn('name', ['협력사관리', '협력사 관리']) + ->update(['name' => '거래처 관리']); + if ($updated > 0) { + Cache::put('menu_rename_partner_to_vendor', true, now()->addYear()); + } + } + // 사이드바에 메뉴 데이터 전달 View::composer('partials.sidebar', function ($view) { $menuService = app(SidebarMenuService::class); diff --git a/database/seeders/PartnerMenuRenameSeeder.php b/database/seeders/PartnerMenuRenameSeeder.php index 2b2efa90..ee6aef1d 100644 --- a/database/seeders/PartnerMenuRenameSeeder.php +++ b/database/seeders/PartnerMenuRenameSeeder.php @@ -6,8 +6,8 @@ use Illuminate\Database\Seeder; /** - * 영업파트너 관리 메뉴 이름 변경 시더 - * - "영업파트너 관리" → "파트너 관리" + * 메뉴 이름 변경 시더 + * - "협력사관리" / "협력사 관리" → "거래처 관리" */ class PartnerMenuRenameSeeder extends Seeder { @@ -15,17 +15,26 @@ public function run(): void { $tenantId = 1; - // "영업파트너 관리" 메뉴 찾아서 이름 변경 + // "협력사관리" 또는 "협력사 관리" 메뉴 찾아서 이름 변경 $menu = Menu::where('tenant_id', $tenantId) - ->where('name', '영업파트너 관리') + ->where(function ($q) { + $q->where('name', '협력사관리') + ->orWhere('name', '협력사 관리'); + }) ->first(); if ($menu) { - $menu->name = '파트너 관리'; + $oldName = $menu->name; + $menu->name = '거래처 관리'; $menu->save(); - $this->command->info('메뉴 이름 변경: 영업파트너 관리 → 파트너 관리'); + $this->command->info("메뉴 이름 변경: {$oldName} → 거래처 관리"); } else { - $this->command->warn('영업파트너 관리 메뉴를 찾을 수 없습니다.'); + $this->command->warn('협력사관리 메뉴를 찾을 수 없습니다. 현재 메뉴 목록:'); + Menu::where('tenant_id', $tenantId) + ->whereNull('parent_id') + ->orderBy('sort_order') + ->get(['id', 'name', 'url']) + ->each(fn ($m) => $this->command->line(" - [{$m->id}] {$m->name} ({$m->url})")); } } } diff --git a/database/seeders/PayableMenuRenameSeeder.php b/database/seeders/PayableMenuRenameSeeder.php new file mode 100644 index 00000000..78c7db6e --- /dev/null +++ b/database/seeders/PayableMenuRenameSeeder.php @@ -0,0 +1,35 @@ +where(function ($q) { + $q->where('name', '채무관리') + ->orWhere('name', '채무 관리'); + }) + ->first(); + + if ($menu) { + $oldName = $menu->name; + $menu->name = '미지급금 관리'; + $menu->save(); + $this->command->info("메뉴 이름 변경: {$oldName} → 미지급금 관리"); + } else { + $this->command->warn('채무관리 메뉴를 찾을 수 없습니다.'); + Menu::where('tenant_id', $tenantId) + ->whereNull('parent_id') + ->orderBy('sort_order') + ->get(['id', 'name', 'url']) + ->each(fn ($m) => $this->command->line(" - [{$m->id}] {$m->name} ({$m->url})")); + } + } +} diff --git a/database/seeders/ReceivableMenuRenameSeeder.php b/database/seeders/ReceivableMenuRenameSeeder.php new file mode 100644 index 00000000..35c452c3 --- /dev/null +++ b/database/seeders/ReceivableMenuRenameSeeder.php @@ -0,0 +1,35 @@ +where(function ($q) { + $q->where('name', '채권관리') + ->orWhere('name', '채권 관리'); + }) + ->first(); + + if ($menu) { + $oldName = $menu->name; + $menu->name = '미수금 관리'; + $menu->save(); + $this->command->info("메뉴 이름 변경: {$oldName} → 미수금 관리"); + } else { + $this->command->warn('채권관리 메뉴를 찾을 수 없습니다.'); + Menu::where('tenant_id', $tenantId) + ->whereNull('parent_id') + ->orderBy('sort_order') + ->get(['id', 'name', 'url']) + ->each(fn ($m) => $this->command->line(" - [{$m->id}] {$m->name} ({$m->url})")); + } + } +} diff --git a/database/seeders/RefundMenuRenameSeeder.php b/database/seeders/RefundMenuRenameSeeder.php new file mode 100644 index 00000000..334f9a0c --- /dev/null +++ b/database/seeders/RefundMenuRenameSeeder.php @@ -0,0 +1,35 @@ +where(function ($q) { + $q->where('name', '환불관리') + ->orWhere('name', '환불 관리'); + }) + ->first(); + + if ($menu) { + $oldName = $menu->name; + $menu->name = '환불/해지 관리'; + $menu->save(); + $this->command->info("메뉴 이름 변경: {$oldName} → 환불/해지 관리"); + } else { + $this->command->warn('환불관리 메뉴를 찾을 수 없습니다.'); + Menu::where('tenant_id', $tenantId) + ->whereNull('parent_id') + ->orderBy('sort_order') + ->get(['id', 'name', 'url']) + ->each(fn ($m) => $this->command->line(" - [{$m->id}] {$m->name} ({$m->url})")); + } + } +} diff --git a/resources/views/finance/partners.blade.php b/resources/views/finance/partners.blade.php index e97598c7..8ab8d2dd 100644 --- a/resources/views/finance/partners.blade.php +++ b/resources/views/finance/partners.blade.php @@ -1,6 +1,6 @@ @extends('layouts.app') -@section('title', '일반 거래처') +@section('title', '거래처 관리') @push('styles')