header('HX-Request')) { return response('', 200)->header('HX-Redirect', route('sales.prospects.index')); } $filters = [ 'search' => $request->get('search'), 'status' => $request->get('status'), 'registered_by' => $request->get('registered_by'), ]; $prospects = $this->service->getProspects($filters)->paginate(20); $stats = $this->service->getStats(); return view('sales.prospects.index', compact('prospects', 'stats')); } /** * 등록 폼 */ public function create(Request $request): View|Response { // HTMX 요청이면 JavaScript 로드를 위해 전체 페이지로 리다이렉트 if ($request->header('HX-Request')) { return response('', 200)->header('HX-Redirect', route('sales.prospects.create')); } return view('sales.prospects.create'); } /** * 등록 처리 */ public function store(Request $request) { $validated = $request->validate([ 'business_number' => 'required|string|max:20', 'company_name' => 'required|string|max:100', 'ceo_name' => 'nullable|string|max:50', 'contact_phone' => 'nullable|string|max:20', 'contact_email' => 'nullable|email|max:100', 'address' => 'nullable|string|max:500', 'business_card' => 'nullable|image|max:5120', 'memo' => 'nullable|string|max:1000', ]); // 등록 가능 여부 확인 $checkResult = $this->service->canRegister($validated['business_number']); if (!$checkResult['can_register']) { return redirect()->back() ->withInput() ->with('error', $checkResult['reason']); } // 등록자는 현재 로그인 사용자 $validated['registered_by'] = auth()->id(); $this->service->register( $validated, $request->file('business_card') ); return redirect()->route('sales.prospects.index') ->with('success', '명함이 등록되었습니다. 2개월간 영업권이 유효합니다.'); } /** * 상세 페이지 */ public function show(int $id): View { $prospect = TenantProspect::with(['registeredBy', 'tenant', 'convertedBy']) ->findOrFail($id); return view('sales.prospects.show', compact('prospect')); } /** * 수정 폼 */ public function edit(int $id): View { $prospect = TenantProspect::findOrFail($id); // 이미 전환된 경우 수정 불가 if ($prospect->isConverted()) { return redirect()->route('sales.prospects.show', $id) ->with('error', '이미 테넌트로 전환된 영업권은 수정할 수 없습니다.'); } return view('sales.prospects.edit', compact('prospect')); } /** * 수정 처리 */ public function update(Request $request, int $id) { $prospect = TenantProspect::findOrFail($id); // 이미 전환된 경우 수정 불가 if ($prospect->isConverted()) { return redirect()->route('sales.prospects.show', $id) ->with('error', '이미 테넌트로 전환된 영업권은 수정할 수 없습니다.'); } $validated = $request->validate([ 'company_name' => 'required|string|max:100', 'ceo_name' => 'nullable|string|max:50', 'contact_phone' => 'nullable|string|max:20', 'contact_email' => 'nullable|email|max:100', 'address' => 'nullable|string|max:500', 'business_card' => 'nullable|image|max:5120', 'id_card' => 'nullable|image|max:5120', 'bankbook' => 'nullable|image|max:5120', 'memo' => 'nullable|string|max:1000', ]); $this->service->update( $prospect, $validated, $request->file('business_card'), $request->file('id_card'), $request->file('bankbook') ); return redirect()->route('sales.prospects.show', $id) ->with('success', '영업권 정보가 수정되었습니다.'); } /** * 삭제 처리 */ public function destroy(int $id) { $prospect = TenantProspect::findOrFail($id); // 이미 전환된 경우 삭제 불가 if ($prospect->isConverted()) { return redirect()->route('sales.prospects.index') ->with('error', '이미 테넌트로 전환된 영업권은 삭제할 수 없습니다.'); } // 본인 또는 관리자만 삭제 가능 if ($prospect->registered_by !== auth()->id()) { // TODO: 관리자 권한 체크 추가 } $prospect->delete(); return redirect()->route('sales.prospects.index') ->with('success', '영업권이 삭제되었습니다.'); } /** * 테넌트 전환 */ public function convert(int $id) { $prospect = TenantProspect::findOrFail($id); // 이미 전환된 경우 if ($prospect->isConverted()) { return redirect()->route('sales.prospects.show', $id) ->with('error', '이미 테넌트로 전환되었습니다.'); } // 만료된 경우 if ($prospect->isExpired()) { return redirect()->route('sales.prospects.show', $id) ->with('error', '만료된 영업권은 전환할 수 없습니다.'); } $tenant = $this->service->convertToTenant($prospect, auth()->id()); return redirect()->route('sales.prospects.show', $id) ->with('success', "테넌트로 전환되었습니다. (테넌트 ID: {$tenant->id})"); } /** * 사업자번호 중복 체크 (AJAX) */ public function checkBusinessNumber(Request $request) { $businessNumber = $request->get('business_number'); $excludeId = $request->get('exclude_id'); $result = $this->service->canRegister($businessNumber, $excludeId); return response()->json($result); } /** * 첨부 이미지 삭제 (AJAX) */ public function deleteAttachment(Request $request, int $id) { $prospect = TenantProspect::findOrFail($id); // 이미 전환된 경우 수정 불가 if ($prospect->isConverted()) { return response()->json(['success' => false, 'message' => '전환된 영업권은 수정할 수 없습니다.'], 403); } $type = $request->get('type'); $allowedTypes = ['business_card', 'id_card', 'bankbook']; if (!in_array($type, $allowedTypes)) { return response()->json(['success' => false, 'message' => '잘못된 요청입니다.'], 400); } $result = $this->service->deleteAttachment($prospect, $type); if ($result) { return response()->json(['success' => true, 'message' => '이미지가 삭제되었습니다.']); } return response()->json(['success' => false, 'message' => '삭제할 이미지가 없습니다.'], 404); } }