refactor:영업관리 데이터를 DB 테이블로 변경
- 모델 추가: SalesPartner, SalesTenantManagement, SalesScenarioChecklist, SalesConsultation - 모델 위치 이동: app/Models/ → app/Models/Sales/ - 컨트롤러 수정: 캐시 대신 DB 모델 사용 - 뷰 수정: Eloquent 모델 속성 사용 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,15 +3,19 @@
|
||||
namespace App\Http\Controllers\Sales;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Sales\SalesScenarioChecklist;
|
||||
use App\Models\Sales\SalesTenantManagement;
|
||||
use App\Models\Tenants\Tenant;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\View\View;
|
||||
|
||||
/**
|
||||
* 영업 시나리오 관리 컨트롤러
|
||||
*
|
||||
* 영업 진행 및 매니저 상담 프로세스의 시나리오 모달과 체크리스트를 관리합니다.
|
||||
* 데이터는 sales_scenario_checklists 테이블에 저장됩니다.
|
||||
*/
|
||||
class SalesScenarioController extends Controller
|
||||
{
|
||||
@@ -25,8 +29,14 @@ public function salesScenario(int $tenantId, Request $request): View|Response
|
||||
$currentStep = (int) $request->input('step', 1);
|
||||
$icons = config('sales_scenario.icons');
|
||||
|
||||
// 체크리스트 진행 상태 조회
|
||||
$progress = $this->getChecklistProgress($tenantId, 'sales');
|
||||
// 테넌트 영업 관리 정보 조회 또는 생성
|
||||
$management = SalesTenantManagement::findOrCreateByTenant($tenantId);
|
||||
|
||||
// 체크리스트 진행 상태 조회 (DB에서)
|
||||
$progress = SalesScenarioChecklist::calculateProgress($tenantId, 'sales', $steps);
|
||||
|
||||
// 진행률 업데이트
|
||||
$management->updateProgress('sales', $progress['percentage']);
|
||||
|
||||
// HTMX 요청이면 단계 콘텐츠만 반환
|
||||
if ($request->header('HX-Request') && $request->has('step')) {
|
||||
@@ -38,6 +48,7 @@ public function salesScenario(int $tenantId, Request $request): View|Response
|
||||
'progress' => $progress,
|
||||
'scenarioType' => 'sales',
|
||||
'icons' => $icons,
|
||||
'management' => $management,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -48,6 +59,7 @@ public function salesScenario(int $tenantId, Request $request): View|Response
|
||||
'progress' => $progress,
|
||||
'scenarioType' => 'sales',
|
||||
'icons' => $icons,
|
||||
'management' => $management,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -61,8 +73,14 @@ public function managerScenario(int $tenantId, Request $request): View|Response
|
||||
$currentStep = (int) $request->input('step', 1);
|
||||
$icons = config('sales_scenario.icons');
|
||||
|
||||
// 체크리스트 진행 상태 조회
|
||||
$progress = $this->getChecklistProgress($tenantId, 'manager');
|
||||
// 테넌트 영업 관리 정보 조회 또는 생성
|
||||
$management = SalesTenantManagement::findOrCreateByTenant($tenantId);
|
||||
|
||||
// 체크리스트 진행 상태 조회 (DB에서)
|
||||
$progress = SalesScenarioChecklist::calculateProgress($tenantId, 'manager', $steps);
|
||||
|
||||
// 진행률 업데이트
|
||||
$management->updateProgress('manager', $progress['percentage']);
|
||||
|
||||
// HTMX 요청이면 단계 콘텐츠만 반환
|
||||
if ($request->header('HX-Request') && $request->has('step')) {
|
||||
@@ -74,6 +92,7 @@ public function managerScenario(int $tenantId, Request $request): View|Response
|
||||
'progress' => $progress,
|
||||
'scenarioType' => 'manager',
|
||||
'icons' => $icons,
|
||||
'management' => $management,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -84,13 +103,14 @@ public function managerScenario(int $tenantId, Request $request): View|Response
|
||||
'progress' => $progress,
|
||||
'scenarioType' => 'manager',
|
||||
'icons' => $icons,
|
||||
'management' => $management,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 체크리스트 항목 토글 (HTMX)
|
||||
*/
|
||||
public function toggleChecklist(Request $request): Response
|
||||
public function toggleChecklist(Request $request): JsonResponse
|
||||
{
|
||||
$request->validate([
|
||||
'tenant_id' => 'required|integer|exists:tenants,id',
|
||||
@@ -106,28 +126,23 @@ public function toggleChecklist(Request $request): Response
|
||||
$checkpointId = $request->input('checkpoint_id');
|
||||
$checked = $request->boolean('checked');
|
||||
|
||||
// 캐시 키 생성
|
||||
$cacheKey = "scenario_checklist:{$tenantId}:{$scenarioType}";
|
||||
// 체크리스트 토글 (DB에 저장)
|
||||
SalesScenarioChecklist::toggle(
|
||||
$tenantId,
|
||||
$scenarioType,
|
||||
$stepId,
|
||||
$checkpointId,
|
||||
$checked,
|
||||
auth()->id()
|
||||
);
|
||||
|
||||
// 현재 체크리스트 상태 조회
|
||||
$checklist = cache()->get($cacheKey, []);
|
||||
// 진행률 재계산
|
||||
$steps = config("sales_scenario.{$scenarioType}_steps");
|
||||
$progress = SalesScenarioChecklist::calculateProgress($tenantId, $scenarioType, $steps);
|
||||
|
||||
// 체크리스트 상태 업데이트
|
||||
$key = "{$stepId}_{$checkpointId}";
|
||||
if ($checked) {
|
||||
$checklist[$key] = [
|
||||
'checked_at' => now()->toDateTimeString(),
|
||||
'checked_by' => auth()->id(),
|
||||
];
|
||||
} else {
|
||||
unset($checklist[$key]);
|
||||
}
|
||||
|
||||
// 캐시에 저장 (30일 유지)
|
||||
cache()->put($cacheKey, $checklist, now()->addDays(30));
|
||||
|
||||
// 진행률 계산
|
||||
$progress = $this->calculateProgress($tenantId, $scenarioType);
|
||||
// 테넌트 영업 관리 정보 업데이트
|
||||
$management = SalesTenantManagement::findOrCreateByTenant($tenantId);
|
||||
$management->updateProgress($scenarioType, $progress['percentage']);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
@@ -139,74 +154,14 @@ public function toggleChecklist(Request $request): Response
|
||||
/**
|
||||
* 진행률 조회
|
||||
*/
|
||||
public function getProgress(int $tenantId, string $type): Response
|
||||
public function getProgress(int $tenantId, string $type): JsonResponse
|
||||
{
|
||||
$progress = $this->calculateProgress($tenantId, $type);
|
||||
$steps = config("sales_scenario.{$type}_steps");
|
||||
$progress = SalesScenarioChecklist::calculateProgress($tenantId, $type, $steps);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'progress' => $progress,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 체크리스트 진행 상태 조회
|
||||
*/
|
||||
private function getChecklistProgress(int $tenantId, string $scenarioType): array
|
||||
{
|
||||
$cacheKey = "scenario_checklist:{$tenantId}:{$scenarioType}";
|
||||
|
||||
return cache()->get($cacheKey, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* 진행률 계산
|
||||
*/
|
||||
private function calculateProgress(int $tenantId, string $scenarioType): array
|
||||
{
|
||||
$steps = config("sales_scenario.{$scenarioType}_steps");
|
||||
$checklist = $this->getChecklistProgress($tenantId, $scenarioType);
|
||||
|
||||
$totalCheckpoints = 0;
|
||||
$completedCheckpoints = 0;
|
||||
$stepProgress = [];
|
||||
|
||||
foreach ($steps as $step) {
|
||||
$stepCompleted = 0;
|
||||
$stepTotal = count($step['checkpoints']);
|
||||
$totalCheckpoints += $stepTotal;
|
||||
|
||||
foreach ($step['checkpoints'] as $checkpoint) {
|
||||
$key = "{$step['id']}_{$checkpoint['id']}";
|
||||
if (isset($checklist[$key])) {
|
||||
$completedCheckpoints++;
|
||||
$stepCompleted++;
|
||||
}
|
||||
}
|
||||
|
||||
$stepProgress[$step['id']] = [
|
||||
'total' => $stepTotal,
|
||||
'completed' => $stepCompleted,
|
||||
'percentage' => $stepTotal > 0 ? round(($stepCompleted / $stepTotal) * 100) : 0,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'total' => $totalCheckpoints,
|
||||
'completed' => $completedCheckpoints,
|
||||
'percentage' => $totalCheckpoints > 0 ? round(($completedCheckpoints / $totalCheckpoints) * 100) : 0,
|
||||
'steps' => $stepProgress,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 단계의 체크포인트 체크 여부 확인
|
||||
*/
|
||||
public function isCheckpointChecked(int $tenantId, string $scenarioType, int $stepId, string $checkpointId): bool
|
||||
{
|
||||
$checklist = $this->getChecklistProgress($tenantId, $scenarioType);
|
||||
$key = "{$stepId}_{$checkpointId}";
|
||||
|
||||
return isset($checklist[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user