Files
sam-manage/app/Http/Controllers/Credit/CreditController.php
2026-02-25 11:45:01 +09:00

402 lines
13 KiB
PHP

<?php
namespace App\Http\Controllers\Credit;
use App\Http\Controllers\Controller;
use App\Models\Coocon\CooconConfig;
use App\Models\Credit\CreditInquiry;
use App\Services\Coocon\CooconService;
use App\Services\Nts\NtsBusinessService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\View\View;
/**
* 신용평가 컨트롤러
*/
class CreditController extends Controller
{
/**
* 신용평가 조회 이력 목록
*/
public function inquiry(Request $request): View|Response
{
if ($request->header('HX-Request')) {
return response('', 200)->header('HX-Redirect', route('credit.inquiry.index'));
}
$service = new CooconService;
$hasConfig = $service->hasConfig();
// 검색 조건
$query = CreditInquiry::query()
->with('user:id,name')
->orderBy('inquired_at', 'desc');
// 사업자번호 검색
if ($request->filled('company_key')) {
$companyKey = preg_replace('/[^0-9]/', '', $request->input('company_key'));
$query->where('company_key', 'like', "%{$companyKey}%");
}
// 기간 검색
if ($request->filled('start_date')) {
$query->where('inquired_at', '>=', $request->input('start_date').' 00:00:00');
}
if ($request->filled('end_date')) {
$query->where('inquired_at', '<=', $request->input('end_date').' 23:59:59');
}
// 이슈 있는 것만
if ($request->boolean('has_issue')) {
$query->withIssues();
}
$inquiries = $query->paginate(20)->withQueryString();
return view('credit.inquiry.index', [
'hasConfig' => $hasConfig,
'apiTypes' => CooconService::API_NAMES,
'inquiries' => $inquiries,
'filters' => [
'company_key' => $request->input('company_key'),
'start_date' => $request->input('start_date'),
'end_date' => $request->input('end_date'),
'has_issue' => $request->boolean('has_issue'),
],
]);
}
/**
* 신용정보 조회 및 저장 API
*/
public function search(Request $request): JsonResponse
{
$request->validate([
'company_key' => 'required|string|max:20',
]);
$companyKey = preg_replace('/[^0-9]/', '', $request->input('company_key'));
$cooconService = new CooconService;
if (! $cooconService->hasConfig()) {
return response()->json([
'success' => false,
'error' => '쿠콘 API 설정이 없습니다. 설정을 먼저 등록해주세요.',
], 400);
}
// 전체 신용정보 조회 (쿠콘 API)
$apiResult = $cooconService->getAllCreditInfo($companyKey);
// 국세청 사업자등록 상태 조회
$ntsService = new NtsBusinessService;
$ntsResult = $ntsService->getBusinessStatus($companyKey);
// DB에 저장 (tenant_id는 세션에서 가져옴)
$inquiry = CreditInquiry::createFromApiResponse(
$companyKey,
$apiResult,
$ntsResult,
auth()->id(),
session('selected_tenant_id')
);
return response()->json([
'success' => true,
'data' => $apiResult,
'nts' => $ntsResult,
'inquiry_key' => $inquiry->inquiry_key,
'inquiry_id' => $inquiry->id,
'company_key' => $companyKey,
'company_info' => [
'company_name' => $inquiry->company_name,
'ceo_name' => $inquiry->ceo_name,
'company_address' => $inquiry->company_address,
'business_type' => $inquiry->business_type,
'business_item' => $inquiry->business_item,
'nts_status' => $inquiry->nts_status,
'nts_status_label' => $inquiry->nts_status_label,
'nts_tax_type' => $inquiry->nts_tax_type,
],
]);
}
/**
* 특정 조회 이력의 원본 데이터 조회
*/
public function getRawData(string $inquiryKey): JsonResponse
{
$inquiry = CreditInquiry::where('inquiry_key', $inquiryKey)->firstOrFail();
return response()->json([
'success' => true,
'data' => $inquiry->getAllRawData(),
'inquiry' => [
'id' => $inquiry->id,
'inquiry_key' => $inquiry->inquiry_key,
'company_key' => $inquiry->company_key,
'formatted_company_key' => $inquiry->formatted_company_key,
'company_name' => $inquiry->company_name,
'ceo_name' => $inquiry->ceo_name,
'company_address' => $inquiry->company_address,
'business_type' => $inquiry->business_type,
'business_item' => $inquiry->business_item,
'nts_status' => $inquiry->nts_status,
'nts_status_label' => $inquiry->nts_status_label,
'nts_tax_type' => $inquiry->nts_tax_type,
'inquired_at' => $inquiry->inquired_at->format('Y-m-d H:i:s'),
'status' => $inquiry->status,
'total_issue_count' => $inquiry->total_issue_count,
],
]);
}
/**
* 특정 조회 이력의 리포트 데이터 조회 (가공된 형태)
*/
public function getReportData(string $inquiryKey): JsonResponse
{
$inquiry = CreditInquiry::where('inquiry_key', $inquiryKey)->firstOrFail();
// TODO: CreditReportTransformer 서비스를 통해 데이터 가공
// 현재는 원본 데이터 그대로 반환
$reportData = $this->transformToReportFormat($inquiry);
return response()->json([
'success' => true,
'data' => $reportData,
'inquiry' => [
'id' => $inquiry->id,
'inquiry_key' => $inquiry->inquiry_key,
'company_key' => $inquiry->company_key,
'formatted_company_key' => $inquiry->formatted_company_key,
'inquired_at' => $inquiry->inquired_at->format('Y-m-d H:i:s'),
],
]);
}
/**
* 리포트 형식으로 데이터 변환 (임시 구현)
*/
private function transformToReportFormat(CreditInquiry $inquiry): array
{
$rawData = $inquiry->getAllRawData();
return [
'company_info' => [
'company_key' => $inquiry->formatted_company_key,
'company_name' => $inquiry->company_name ?? '-',
'ceo_name' => $inquiry->ceo_name ?? '-',
'company_address' => $inquiry->company_address ?? '-',
'business_type' => $inquiry->business_type ?? '-',
'business_item' => $inquiry->business_item ?? '-',
'establishment_date' => $inquiry->establishment_date?->format('Y-m-d') ?? '-',
'inquired_at' => $inquiry->inquired_at->format('Y년 m월 d일 H:i'),
],
'nts_info' => [
'status' => $inquiry->nts_status ?? '-',
'status_label' => $inquiry->nts_status_label,
'tax_type' => $inquiry->nts_tax_type ?? '-',
'closure_date' => $inquiry->nts_closure_date?->format('Y-m-d') ?? null,
'is_active' => $inquiry->isNtsActive(),
],
'summary' => [
'total_issue_count' => $inquiry->total_issue_count,
'has_issue' => $inquiry->has_issue,
'short_term_overdue_cnt' => $inquiry->short_term_overdue_cnt,
'negative_info_kci_cnt' => $inquiry->negative_info_kci_cnt,
'negative_info_pb_cnt' => $inquiry->negative_info_pb_cnt,
'negative_info_cb_cnt' => $inquiry->negative_info_cb_cnt,
'suspension_info_cnt' => $inquiry->suspension_info_cnt,
'workout_cnt' => $inquiry->workout_cnt,
],
'details' => $rawData,
];
}
/**
* 조회 이력 삭제
*/
public function deleteInquiry(int $id): JsonResponse
{
$inquiry = CreditInquiry::findOrFail($id);
$inquiry->delete();
return response()->json([
'success' => true,
'message' => '조회 이력이 삭제되었습니다.',
]);
}
/**
* 설정 관리 페이지
*/
public function settings(Request $request): View|Response
{
if ($request->header('HX-Request')) {
return response('', 200)->header('HX-Redirect', route('credit.settings.index'));
}
$configs = CooconConfig::orderBy('environment')
->orderBy('is_active', 'desc')
->orderBy('created_at', 'desc')
->get();
return view('credit.settings.index', [
'configs' => $configs,
]);
}
/**
* 설정 생성 폼
*/
public function createConfig(): View
{
return view('credit.settings.create');
}
/**
* 설정 저장
*/
public function storeConfig(Request $request): JsonResponse
{
$validated = $request->validate([
'name' => 'required|string|max:100',
'environment' => 'required|in:test,production',
'api_key' => 'required|string|max:100',
'base_url' => 'required|url|max:255',
'description' => 'nullable|string',
'is_active' => 'boolean',
]);
// 같은 환경에서 활성화된 설정이 이미 있으면 비활성화
if ($validated['is_active'] ?? false) {
CooconConfig::where('environment', $validated['environment'])
->where('is_active', true)
->update(['is_active' => false]);
}
$config = CooconConfig::create($validated);
return response()->json([
'success' => true,
'message' => '설정이 저장되었습니다.',
'data' => $config,
]);
}
/**
* 설정 수정 폼
*/
public function editConfig(int $id): View
{
$config = CooconConfig::findOrFail($id);
return view('credit.settings.edit', [
'config' => $config,
]);
}
/**
* 설정 업데이트
*/
public function updateConfig(Request $request, int $id): JsonResponse
{
$config = CooconConfig::findOrFail($id);
$validated = $request->validate([
'name' => 'required|string|max:100',
'environment' => 'required|in:test,production',
'api_key' => 'required|string|max:100',
'base_url' => 'required|url|max:255',
'description' => 'nullable|string',
'is_active' => 'boolean',
]);
// 같은 환경에서 활성화된 설정이 이미 있으면 비활성화 (자기 자신 제외)
if ($validated['is_active'] ?? false) {
CooconConfig::where('environment', $validated['environment'])
->where('is_active', true)
->where('id', '!=', $id)
->update(['is_active' => false]);
}
$config->update($validated);
return response()->json([
'success' => true,
'message' => '설정이 수정되었습니다.',
'data' => $config,
]);
}
/**
* 설정 삭제
*/
public function deleteConfig(int $id): JsonResponse
{
$config = CooconConfig::findOrFail($id);
$config->delete();
return response()->json([
'success' => true,
'message' => '설정이 삭제되었습니다.',
]);
}
/**
* 설정 활성화/비활성화 토글
*/
public function toggleConfig(int $id): JsonResponse
{
$config = CooconConfig::findOrFail($id);
if (! $config->is_active) {
// 같은 환경에서 활성화된 설정이 이미 있으면 비활성화
CooconConfig::where('environment', $config->environment)
->where('is_active', true)
->update(['is_active' => false]);
}
$config->update(['is_active' => ! $config->is_active]);
return response()->json([
'success' => true,
'message' => $config->is_active ? '설정이 활성화되었습니다.' : '설정이 비활성화되었습니다.',
'is_active' => $config->is_active,
]);
}
/**
* API 연결 테스트
*/
public function testConnection(Request $request): JsonResponse
{
$request->validate([
'company_key' => 'required|string|max:20',
]);
$companyKey = $request->input('company_key');
$service = new CooconService;
if (! $service->hasConfig()) {
return response()->json([
'success' => false,
'error' => '쿠콘 API 설정이 없습니다.',
], 400);
}
// 신용요약정보 API로 테스트
$result = $service->getCreditSummary($companyKey);
return response()->json([
'success' => $result['success'],
'message' => $result['success'] ? 'API 연결 테스트 성공' : 'API 연결 테스트 실패',
'result' => $result,
]);
}
}