2026-01-27 18:59:45 +09:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers\Sales;
|
|
|
|
|
|
|
|
|
|
use App\Http\Controllers\Controller;
|
2026-01-29 06:42:32 +09:00
|
|
|
use App\Models\Sales\SalesTenantManagement;
|
2026-01-29 06:47:37 +09:00
|
|
|
use App\Models\Sales\TenantProspect;
|
2026-01-28 20:15:38 +09:00
|
|
|
use App\Models\Tenants\Tenant;
|
2026-01-28 21:45:11 +09:00
|
|
|
use App\Models\User;
|
|
|
|
|
use Illuminate\Http\JsonResponse;
|
2026-01-27 18:59:45 +09:00
|
|
|
use Illuminate\Http\Request;
|
|
|
|
|
use Illuminate\View\View;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 영업관리 대시보드 컨트롤러
|
|
|
|
|
*/
|
|
|
|
|
class SalesDashboardController extends Controller
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* 대시보드 화면
|
|
|
|
|
*/
|
|
|
|
|
public function index(Request $request): View
|
2026-01-27 19:28:48 +09:00
|
|
|
{
|
|
|
|
|
$data = $this->getDashboardData($request);
|
|
|
|
|
|
|
|
|
|
return view('sales.dashboard.index', $data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* HTMX 부분 새로고침용 데이터 반환
|
|
|
|
|
*/
|
|
|
|
|
public function refresh(Request $request): View
|
|
|
|
|
{
|
|
|
|
|
$data = $this->getDashboardData($request);
|
|
|
|
|
|
|
|
|
|
return view('sales.dashboard.partials.data-container', $data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 대시보드 데이터 조회
|
|
|
|
|
*/
|
|
|
|
|
private function getDashboardData(Request $request): array
|
2026-01-27 18:59:45 +09:00
|
|
|
{
|
|
|
|
|
// 기간 설정
|
|
|
|
|
$period = $request->input('period', 'month'); // month or custom
|
|
|
|
|
$year = $request->input('year', now()->year);
|
|
|
|
|
$month = $request->input('month', now()->month);
|
|
|
|
|
|
2026-01-27 19:06:36 +09:00
|
|
|
// 기간 설정 모드일 경우
|
|
|
|
|
if ($period === 'custom') {
|
|
|
|
|
$startDate = $request->input('start_date', now()->startOfMonth()->format('Y-m-d'));
|
|
|
|
|
$endDate = $request->input('end_date', now()->format('Y-m-d'));
|
|
|
|
|
} else {
|
|
|
|
|
$startDate = now()->startOfMonth()->format('Y-m-d');
|
|
|
|
|
$endDate = now()->endOfMonth()->format('Y-m-d');
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-27 18:59:45 +09:00
|
|
|
// 통계 데이터 (임시 데이터 - 추후 실제 데이터로 교체)
|
|
|
|
|
$stats = [
|
|
|
|
|
'total_membership_fee' => 0, // 총 가입비
|
|
|
|
|
'total_commission' => 0, // 총 수당
|
|
|
|
|
'commission_rate' => 0, // 지급 승인 완료 비율
|
|
|
|
|
'total_contracts' => 0, // 전체 건수
|
|
|
|
|
'pending_membership_approval' => 0, // 가입 승인 대기
|
|
|
|
|
'pending_payment_approval' => 0, // 지급 승인 대기
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// 역할별 수당 상세
|
|
|
|
|
$commissionByRole = [
|
|
|
|
|
[
|
|
|
|
|
'name' => '판매자',
|
|
|
|
|
'rate' => 20,
|
|
|
|
|
'amount' => 0,
|
|
|
|
|
'color' => 'green',
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'name' => '관리자',
|
|
|
|
|
'rate' => 5,
|
|
|
|
|
'amount' => 0,
|
|
|
|
|
'color' => 'blue',
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'name' => '매뉴제작 협업수당',
|
|
|
|
|
'rate' => null, // 별도
|
|
|
|
|
'amount' => null, // 운영팀 산정
|
|
|
|
|
'color' => 'red',
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// 총 가입비 대비 수당
|
|
|
|
|
$totalCommissionRatio = 0;
|
|
|
|
|
|
2026-01-27 19:14:29 +09:00
|
|
|
// 수익 및 테넌트 관리 통계 (임시 데이터 - 추후 실제 데이터로 교체)
|
|
|
|
|
$tenantStats = [
|
|
|
|
|
'total_tenants' => 0, // 관리 테넌트
|
|
|
|
|
'total_membership_revenue' => 0, // 총 가입비 실적
|
|
|
|
|
'total_commission_accumulated' => 0, // 누적 가입비 수당
|
|
|
|
|
'confirmed_commission' => 0, // 확정 가입비 수당
|
|
|
|
|
];
|
|
|
|
|
|
2026-01-29 06:47:37 +09:00
|
|
|
// 테넌트 목록 (가망고객에서 전환된 테넌트만)
|
|
|
|
|
// 전환된 가망고객의 tenant_id 목록 조회
|
|
|
|
|
$convertedTenantIds = TenantProspect::whereNotNull('tenant_id')
|
|
|
|
|
->where('status', TenantProspect::STATUS_CONVERTED)
|
|
|
|
|
->pluck('tenant_id')
|
|
|
|
|
->toArray();
|
|
|
|
|
|
|
|
|
|
// 전환된 테넌트만 조회
|
|
|
|
|
$tenants = Tenant::whereIn('id', $convertedTenantIds)
|
2026-01-28 20:15:38 +09:00
|
|
|
->orderBy('created_at', 'desc')
|
|
|
|
|
->get();
|
|
|
|
|
|
2026-01-29 06:42:32 +09:00
|
|
|
// 각 테넌트의 영업 관리 정보 로드
|
|
|
|
|
$tenantIds = $tenants->pluck('id')->toArray();
|
|
|
|
|
$managements = SalesTenantManagement::whereIn('tenant_id', $tenantIds)
|
|
|
|
|
->with('manager')
|
|
|
|
|
->get()
|
|
|
|
|
->keyBy('tenant_id');
|
|
|
|
|
|
2026-01-29 07:05:45 +09:00
|
|
|
// HQ 매니저 목록 (드롭다운용) - 본인 제외
|
|
|
|
|
$allManagers = User::whereHas('tenants', function ($query) {
|
|
|
|
|
$query->where('tenant_type', 'HQ');
|
|
|
|
|
})->where('id', '!=', auth()->id())
|
|
|
|
|
->get(['id', 'name', 'email']);
|
|
|
|
|
|
2026-01-27 19:28:48 +09:00
|
|
|
return compact(
|
2026-01-27 18:59:45 +09:00
|
|
|
'stats',
|
|
|
|
|
'commissionByRole',
|
|
|
|
|
'totalCommissionRatio',
|
2026-01-27 19:14:29 +09:00
|
|
|
'tenantStats',
|
2026-01-28 20:15:38 +09:00
|
|
|
'tenants',
|
2026-01-29 06:42:32 +09:00
|
|
|
'managements',
|
2026-01-29 07:05:45 +09:00
|
|
|
'allManagers',
|
2026-01-27 18:59:45 +09:00
|
|
|
'period',
|
|
|
|
|
'year',
|
2026-01-27 19:06:36 +09:00
|
|
|
'month',
|
|
|
|
|
'startDate',
|
|
|
|
|
'endDate'
|
2026-01-27 19:28:48 +09:00
|
|
|
);
|
2026-01-27 18:59:45 +09:00
|
|
|
}
|
2026-01-28 21:45:11 +09:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 매니저 지정 변경
|
|
|
|
|
*/
|
|
|
|
|
public function assignManager(int $tenantId, Request $request): JsonResponse
|
|
|
|
|
{
|
|
|
|
|
$request->validate([
|
|
|
|
|
'manager_id' => 'required|integer',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$tenant = Tenant::findOrFail($tenantId);
|
|
|
|
|
$managerId = $request->input('manager_id');
|
|
|
|
|
|
2026-01-29 06:42:32 +09:00
|
|
|
// 테넌트 영업 관리 정보 조회 또는 생성
|
|
|
|
|
$management = SalesTenantManagement::findOrCreateByTenant($tenantId);
|
2026-01-28 21:45:11 +09:00
|
|
|
|
|
|
|
|
if ($managerId === 0) {
|
|
|
|
|
// 본인으로 설정 (현재 로그인 사용자)
|
|
|
|
|
$manager = auth()->user();
|
2026-01-29 06:42:32 +09:00
|
|
|
$management->update([
|
|
|
|
|
'manager_user_id' => $manager->id,
|
|
|
|
|
]);
|
2026-01-28 21:45:11 +09:00
|
|
|
} else {
|
|
|
|
|
// 특정 매니저 지정
|
|
|
|
|
$manager = User::find($managerId);
|
|
|
|
|
if (!$manager) {
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => false,
|
|
|
|
|
'message' => '매니저를 찾을 수 없습니다.',
|
|
|
|
|
], 404);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-29 06:42:32 +09:00
|
|
|
$management->update([
|
|
|
|
|
'manager_user_id' => $manager->id,
|
|
|
|
|
]);
|
2026-01-28 21:45:11 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'manager' => [
|
|
|
|
|
'id' => $manager->id,
|
|
|
|
|
'name' => $manager->name,
|
|
|
|
|
],
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 매니저 목록 조회 (드롭다운용)
|
|
|
|
|
*/
|
|
|
|
|
public function getManagers(Request $request): JsonResponse
|
|
|
|
|
{
|
|
|
|
|
// HQ 테넌트의 사용자 중 매니저 역할이 있는 사용자 조회
|
|
|
|
|
$managers = User::whereHas('tenants', function ($query) {
|
|
|
|
|
$query->where('tenant_type', 'HQ');
|
|
|
|
|
})->get(['id', 'name', 'email']);
|
|
|
|
|
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'managers' => $managers,
|
|
|
|
|
]);
|
|
|
|
|
}
|
2026-01-27 18:59:45 +09:00
|
|
|
}
|