diff --git a/app/Http/Controllers/Barobill/HometaxController.php b/app/Http/Controllers/Barobill/HometaxController.php index 2c72044c..dd725795 100644 --- a/app/Http/Controllers/Barobill/HometaxController.php +++ b/app/Http/Controllers/Barobill/HometaxController.php @@ -253,36 +253,215 @@ public function purchases(Request $request): JsonResponse } /** - * 홈택스 수집 요청 + * 홈택스 스크래핑 서비스 등록 URL 조회 * - * 참고: 홈택스 수집 API는 별도 서비스 구독이 필요할 수 있습니다. - * 현재는 바로빌에 등록된 세금계산서만 조회합니다. + * 바로빌에서 홈택스 스크래핑을 신청하기 위한 URL을 반환합니다. */ - public function requestCollect(Request $request): JsonResponse + public function getScrapRequestUrl(Request $request): JsonResponse { - // 홈택스 수집 API는 별도 구독 필요 - 현재 미지원 안내 - return response()->json([ - 'success' => false, - 'error' => '홈택스 수집 기능은 별도 서비스 구독이 필요합니다. 바로빌에 등록된 세금계산서는 매출/매입 탭에서 조회 가능합니다.' - ]); + try { + $tenantId = session('selected_tenant_id', self::HEADQUARTERS_TENANT_ID); + $barobillMember = BarobillMember::where('tenant_id', $tenantId)->first(); + $userId = $barobillMember?->barobill_id ?? ''; + + $result = $this->callSoap('GetTaxInvoiceScrapRequestURL', [ + 'UserID' => $userId + ]); + + if (!$result['success']) { + return response()->json([ + 'success' => false, + 'error' => $result['error'], + 'error_code' => $result['error_code'] ?? null + ]); + } + + // 결과가 URL 문자열이면 성공 + $url = $result['data']; + if (is_string($url) && filter_var($url, FILTER_VALIDATE_URL)) { + return response()->json([ + 'success' => true, + 'data' => ['url' => $url] + ]); + } + + // 숫자면 에러코드 + if (is_numeric($url) && $url < 0) { + return response()->json([ + 'success' => false, + 'error' => $this->getErrorMessage((int)$url), + 'error_code' => (int)$url + ]); + } + + return response()->json([ + 'success' => true, + 'data' => ['url' => (string)$url] + ]); + } catch (\Throwable $e) { + Log::error('홈택스 스크래핑 URL 조회 오류: ' . $e->getMessage()); + return response()->json([ + 'success' => false, + 'error' => '서버 오류: ' . $e->getMessage() + ]); + } } /** - * 수집 상태 확인 + * 홈택스 스크래핑 갱신 요청 * - * 참고: 홈택스 수집 상태 API는 별도 서비스 구독이 필요할 수 있습니다. + * 홈택스에서 최신 데이터를 다시 수집하도록 요청합니다. + */ + public function refreshScrap(Request $request): JsonResponse + { + try { + $tenantId = session('selected_tenant_id', self::HEADQUARTERS_TENANT_ID); + $barobillMember = BarobillMember::where('tenant_id', $tenantId)->first(); + $userId = $barobillMember?->barobill_id ?? ''; + + $result = $this->callSoap('RefreshTaxInvoiceScrap', [ + 'UserID' => $userId + ]); + + if (!$result['success']) { + return response()->json([ + 'success' => false, + 'error' => $result['error'], + 'error_code' => $result['error_code'] ?? null + ]); + } + + $code = $result['data']; + if (is_numeric($code)) { + if ($code < 0) { + return response()->json([ + 'success' => false, + 'error' => $this->getErrorMessage((int)$code), + 'error_code' => (int)$code + ]); + } + return response()->json([ + 'success' => true, + 'message' => '홈택스 데이터 수집이 요청되었습니다. 잠시 후 다시 조회해주세요.' + ]); + } + + return response()->json([ + 'success' => true, + 'message' => '홈택스 데이터 수집이 요청되었습니다.' + ]); + } catch (\Throwable $e) { + Log::error('홈택스 스크래핑 갱신 오류: ' . $e->getMessage()); + return response()->json([ + 'success' => false, + 'error' => '서버 오류: ' . $e->getMessage() + ]); + } + } + + /** + * 서비스 상태 진단 + * + * 바로빌 API 연결 및 홈택스 서비스 상태를 확인합니다. + */ + public function diagnose(Request $request): JsonResponse + { + try { + $tenantId = session('selected_tenant_id', self::HEADQUARTERS_TENANT_ID); + $barobillMember = BarobillMember::where('tenant_id', $tenantId)->first(); + $userId = $barobillMember?->barobill_id ?? ''; + $memberCorpNum = $barobillMember?->biz_no ?? ''; + + $diagnostics = [ + 'config' => [ + 'certKey' => !empty($this->certKey) ? substr($this->certKey, 0, 8) . '...' : '미설정', + 'corpNum' => $this->corpNum ?? '미설정', + 'isTestMode' => $this->isTestMode, + 'baseUrl' => $this->baseUrl + ], + 'member' => [ + 'userId' => $userId ?: '미설정', + 'bizNo' => $memberCorpNum ?: '미설정', + 'corpName' => $barobillMember?->corp_name ?? '미설정' + ], + 'tests' => [] + ]; + + // 테스트 1: 홈택스 스크래핑 URL 조회 (서비스 활성화 확인용) + $scrapUrlResult = $this->callSoap('GetTaxInvoiceScrapRequestURL', ['UserID' => $userId]); + $diagnostics['tests']['scrapRequestUrl'] = [ + 'method' => 'GetTaxInvoiceScrapRequestURL', + 'success' => $scrapUrlResult['success'], + 'result' => $scrapUrlResult['success'] + ? (is_string($scrapUrlResult['data']) ? '성공 (URL 반환)' : $scrapUrlResult['data']) + : ($scrapUrlResult['error'] ?? '오류') + ]; + + // 테스트 2: 매출 세금계산서 조회 (기간: 최근 1개월) + $salesResult = $this->callSoap('GetPeriodTaxInvoiceSalesList', [ + 'UserID' => $userId, + 'TaxType' => 0, + 'DateType' => 1, + 'StartDate' => date('Ymd', strtotime('-1 month')), + 'EndDate' => date('Ymd'), + 'CountPerPage' => 1, + 'CurrentPage' => 1 + ]); + $diagnostics['tests']['salesList'] = [ + 'method' => 'GetPeriodTaxInvoiceSalesList', + 'success' => $salesResult['success'], + 'result' => $salesResult['success'] + ? ($this->checkErrorCode($salesResult['data']) + ? $this->getErrorMessage($this->checkErrorCode($salesResult['data'])) + : '성공') + : ($salesResult['error'] ?? '오류') + ]; + + // 테스트 3: 회원사 로그인 URL 조회 (기본 연결 확인용) + $loginUrlResult = $this->callSoap('GetLoginURL', ['UserID' => $userId]); + $diagnostics['tests']['loginUrl'] = [ + 'method' => 'GetLoginURL', + 'success' => $loginUrlResult['success'], + 'result' => $loginUrlResult['success'] + ? (is_string($loginUrlResult['data']) ? '성공 (URL 반환)' : $loginUrlResult['data']) + : ($loginUrlResult['error'] ?? '오류') + ]; + + return response()->json([ + 'success' => true, + 'data' => $diagnostics + ]); + } catch (\Throwable $e) { + Log::error('홈택스 서비스 진단 오류: ' . $e->getMessage()); + return response()->json([ + 'success' => false, + 'error' => '서버 오류: ' . $e->getMessage() + ]); + } + } + + /** + * 홈택스 수집 요청 (미지원 안내) + */ + public function requestCollect(Request $request): JsonResponse + { + // 홈택스 스크래핑 갱신으로 대체 + return $this->refreshScrap($request); + } + + /** + * 수집 상태 확인 (미지원 안내) */ public function collectStatus(Request $request): JsonResponse { - // 홈택스 수집 상태 API는 별도 구독 필요 - 현재 미지원 안내 return response()->json([ 'success' => true, 'data' => [ 'salesLastCollectDate' => '', 'purchaseLastCollectDate' => '', 'isCollecting' => false, - 'collectStateText' => '미지원', - 'message' => '홈택스 수집 기능은 별도 서비스 구독이 필요합니다.' + 'collectStateText' => '확인 필요', + 'message' => '서비스 상태 진단 기능을 사용하여 홈택스 연동 상태를 확인해주세요.' ] ]); } diff --git a/resources/views/barobill/hometax/index.blade.php b/resources/views/barobill/hometax/index.blade.php index 5a1a5e88..ed5d4e8a 100644 --- a/resources/views/barobill/hometax/index.blade.php +++ b/resources/views/barobill/hometax/index.blade.php @@ -72,6 +72,9 @@ requestCollect: '{{ route("barobill.hometax.request-collect") }}', collectStatus: '{{ route("barobill.hometax.collect-status") }}', export: '{{ route("barobill.hometax.export") }}', + scrapUrl: '{{ route("barobill.hometax.scrap-url") }}', + refreshScrap: '{{ route("barobill.hometax.refresh-scrap") }}', + diagnose: '{{ route("barobill.hometax.diagnose") }}', }; const CSRF_TOKEN = '{{ csrf_token() }}'; @@ -334,6 +337,11 @@ className="flex items-center gap-2 px-4 py-2 bg-blue-100 text-blue-700 rounded-l const [dateFrom, setDateFrom] = useState(currentMonth.from); const [dateTo, setDateTo] = useState(currentMonth.to); + // 진단 관련 상태 + const [showDiagnoseModal, setShowDiagnoseModal] = useState(false); + const [diagnoseResult, setDiagnoseResult] = useState(null); + const [diagnosing, setDiagnosing] = useState(false); + // 초기 로드 useEffect(() => { loadData(); @@ -469,6 +477,49 @@ className="flex items-center gap-2 px-4 py-2 bg-blue-100 text-blue-700 rounded-l } }; + // 서비스 진단 + const handleDiagnose = async () => { + setShowDiagnoseModal(true); + setDiagnosing(true); + setDiagnoseResult(null); + + try { + const res = await fetch(API.diagnose); + const data = await res.json(); + if (data.success) { + setDiagnoseResult(data.data); + } else { + setDiagnoseResult({ error: data.error || '진단 실패' }); + } + } catch (err) { + setDiagnoseResult({ error: '서버 통신 오류: ' + err.message }); + } finally { + setDiagnosing(false); + } + }; + + // 홈택스 스크래핑 새로고침 + const handleRefreshScrap = async () => { + try { + const res = await fetch(API.refreshScrap, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRF-TOKEN': CSRF_TOKEN + } + }); + const data = await res.json(); + if (data.success) { + notify(data.message || '홈택스 데이터 수집이 요청되었습니다.', 'success'); + loadData(); + } else { + notify(data.error || '수집 요청 실패', 'error'); + } + } catch (err) { + notify('수집 요청 오류: ' + err.message, 'error'); + } + }; + // 이번 달 버튼 const handleThisMonth = () => { const dates = getMonthDates(0); @@ -496,6 +547,15 @@ className="flex items-center gap-2 px-4 py-2 bg-blue-100 text-blue-700 rounded-l
홈택스에 신고된 세금계산서 매입/매출 내역 조회
{test.method}
++ {test.result} +
+💡 문제 해결 안내
+