fix:바로빌 홈택스 API 파라미터 오류 수정
- TaxType: 0(전체) → 1(과세+영세), 3(면세) 각각 조회 후 합침 (바로빌 API에서 TaxType=0은 미지원) - DateType: 1(작성일) → 3(전송일자)로 변경 (권장사항) - 에러 메시지 업데이트: - -11010: 과세형태 오류 안내 - -10008: 날짜형식 오류 안내 (YYYYMMDD) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -120,6 +120,11 @@ public function index(Request $request): View|Response
|
||||
|
||||
/**
|
||||
* 매출 세금계산서 목록 조회 (GetPeriodTaxInvoiceSalesList)
|
||||
*
|
||||
* 바로빌 API 참고:
|
||||
* - TaxType: 1(과세+영세), 3(면세) 만 가능 (0은 미지원)
|
||||
* - DateType: 3(전송일자) 권장
|
||||
* - 전체 조회 시 1, 3을 각각 조회하여 합침
|
||||
*/
|
||||
public function sales(Request $request): JsonResponse
|
||||
{
|
||||
@@ -128,7 +133,7 @@ public function sales(Request $request): JsonResponse
|
||||
$endDate = $request->input('endDate', date('Ymd'));
|
||||
$page = (int)$request->input('page', 1);
|
||||
$limit = (int)$request->input('limit', 50);
|
||||
$taxType = (int)$request->input('taxType', 0); // 0:전체, 1:과세, 2:영세, 3:면세
|
||||
$taxType = (int)$request->input('taxType', 0); // 0:전체, 1:과세+영세, 3:면세
|
||||
|
||||
// 현재 테넌트의 바로빌 회원 정보 조회
|
||||
$tenantId = session('selected_tenant_id', self::HEADQUARTERS_TENANT_ID);
|
||||
@@ -150,63 +155,78 @@ public function sales(Request $request): JsonResponse
|
||||
]);
|
||||
}
|
||||
|
||||
$result = $this->callSoap('GetPeriodTaxInvoiceSalesList', [
|
||||
// CorpNum은 callSoap에서 파트너사 사업자번호로 자동 설정
|
||||
'UserID' => $userId,
|
||||
'TaxType' => $taxType,
|
||||
'DateType' => 1, // 1:작성일 기준
|
||||
'StartDate' => $startDate,
|
||||
'EndDate' => $endDate,
|
||||
'CountPerPage' => $limit,
|
||||
'CurrentPage' => $page
|
||||
]);
|
||||
// TaxType이 0(전체)인 경우 1(과세+영세)과 3(면세)를 각각 조회하여 합침
|
||||
$taxTypesToQuery = ($taxType === 0) ? [1, 3] : [$taxType];
|
||||
$allInvoices = [];
|
||||
$totalSummary = ['totalAmount' => 0, 'totalTax' => 0, 'totalSum' => 0, 'count' => 0];
|
||||
$lastPagination = ['currentPage' => $page, 'countPerPage' => $limit, 'maxPageNum' => 1, 'maxIndex' => 0];
|
||||
|
||||
if (!$result['success']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $result['error'],
|
||||
'error_code' => $result['error_code'] ?? null
|
||||
foreach ($taxTypesToQuery as $queryTaxType) {
|
||||
$result = $this->callSoap('GetPeriodTaxInvoiceSalesList', [
|
||||
'UserID' => $userId,
|
||||
'TaxType' => $queryTaxType, // 1: 과세+영세, 3: 면세
|
||||
'DateType' => 3, // 3: 전송일자 기준 (권장)
|
||||
'StartDate' => $startDate,
|
||||
'EndDate' => $endDate,
|
||||
'CountPerPage' => $limit,
|
||||
'CurrentPage' => $page
|
||||
]);
|
||||
}
|
||||
|
||||
$resultData = $result['data'];
|
||||
if (!$result['success']) {
|
||||
// 첫 번째 조회 실패 시 에러 반환
|
||||
if (empty($allInvoices)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $result['error'],
|
||||
'error_code' => $result['error_code'] ?? null
|
||||
]);
|
||||
}
|
||||
continue; // 이미 일부 데이터가 있으면 계속 진행
|
||||
}
|
||||
|
||||
// 에러 코드 체크
|
||||
$errorCode = $this->checkErrorCode($resultData);
|
||||
if ($errorCode && !in_array($errorCode, [-60005, -60001])) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $this->getErrorMessage($errorCode),
|
||||
'error_code' => $errorCode
|
||||
]);
|
||||
}
|
||||
$resultData = $result['data'];
|
||||
$errorCode = $this->checkErrorCode($resultData);
|
||||
|
||||
// 데이터가 없는 경우
|
||||
if ($errorCode && in_array($errorCode, [-60005, -60001])) {
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => [
|
||||
'invoices' => [],
|
||||
'summary' => ['totalAmount' => 0, 'totalTax' => 0, 'count' => 0],
|
||||
'pagination' => ['currentPage' => 1, 'maxPageNum' => 1]
|
||||
]
|
||||
]);
|
||||
}
|
||||
// 에러 코드 체크 (데이터 없음 외의 에러)
|
||||
if ($errorCode && !in_array($errorCode, [-60005, -60001])) {
|
||||
if (empty($allInvoices)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $this->getErrorMessage($errorCode),
|
||||
'error_code' => $errorCode
|
||||
]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 데이터 파싱
|
||||
$parsed = $this->parseInvoices($resultData, 'sales');
|
||||
// 데이터가 있는 경우 파싱
|
||||
if (!$errorCode || !in_array($errorCode, [-60005, -60001])) {
|
||||
$parsed = $this->parseInvoices($resultData, 'sales');
|
||||
$allInvoices = array_merge($allInvoices, $parsed['invoices']);
|
||||
$totalSummary['totalAmount'] += $parsed['summary']['totalAmount'];
|
||||
$totalSummary['totalTax'] += $parsed['summary']['totalTax'];
|
||||
$totalSummary['totalSum'] += $parsed['summary']['totalSum'] ?? ($parsed['summary']['totalAmount'] + $parsed['summary']['totalTax']);
|
||||
$totalSummary['count'] += $parsed['summary']['count'];
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => [
|
||||
'invoices' => $parsed['invoices'],
|
||||
'pagination' => [
|
||||
// 페이지네이션 정보 업데이트 (마지막 조회 결과 사용)
|
||||
$lastPagination = [
|
||||
'currentPage' => $resultData->CurrentPage ?? 1,
|
||||
'countPerPage' => $resultData->CountPerPage ?? 50,
|
||||
'maxPageNum' => $resultData->MaxPageNum ?? 1,
|
||||
'maxIndex' => $resultData->MaxIndex ?? 0
|
||||
],
|
||||
'summary' => $parsed['summary']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// 작성일 기준으로 정렬 (최신순)
|
||||
usort($allInvoices, fn($a, $b) => strcmp($b['writeDate'] ?? '', $a['writeDate'] ?? ''));
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => [
|
||||
'invoices' => $allInvoices,
|
||||
'pagination' => $lastPagination,
|
||||
'summary' => $totalSummary
|
||||
]
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
@@ -220,6 +240,11 @@ public function sales(Request $request): JsonResponse
|
||||
|
||||
/**
|
||||
* 매입 세금계산서 목록 조회 (GetPeriodTaxInvoicePurchaseList)
|
||||
*
|
||||
* 바로빌 API 참고:
|
||||
* - TaxType: 1(과세+영세), 3(면세) 만 가능 (0은 미지원)
|
||||
* - DateType: 3(전송일자) 권장
|
||||
* - 전체 조회 시 1, 3을 각각 조회하여 합침
|
||||
*/
|
||||
public function purchases(Request $request): JsonResponse
|
||||
{
|
||||
@@ -228,7 +253,7 @@ public function purchases(Request $request): JsonResponse
|
||||
$endDate = $request->input('endDate', date('Ymd'));
|
||||
$page = (int)$request->input('page', 1);
|
||||
$limit = (int)$request->input('limit', 50);
|
||||
$taxType = (int)$request->input('taxType', 0); // 0:전체, 1:과세, 2:영세, 3:면세
|
||||
$taxType = (int)$request->input('taxType', 0); // 0:전체, 1:과세+영세, 3:면세
|
||||
|
||||
// 현재 테넌트의 바로빌 회원 정보 조회
|
||||
$tenantId = session('selected_tenant_id', self::HEADQUARTERS_TENANT_ID);
|
||||
@@ -250,63 +275,78 @@ public function purchases(Request $request): JsonResponse
|
||||
]);
|
||||
}
|
||||
|
||||
$result = $this->callSoap('GetPeriodTaxInvoicePurchaseList', [
|
||||
// CorpNum은 callSoap에서 파트너사 사업자번호로 자동 설정
|
||||
'UserID' => $userId,
|
||||
'TaxType' => $taxType,
|
||||
'DateType' => 1, // 1:작성일 기준
|
||||
'StartDate' => $startDate,
|
||||
'EndDate' => $endDate,
|
||||
'CountPerPage' => $limit,
|
||||
'CurrentPage' => $page
|
||||
]);
|
||||
// TaxType이 0(전체)인 경우 1(과세+영세)과 3(면세)를 각각 조회하여 합침
|
||||
$taxTypesToQuery = ($taxType === 0) ? [1, 3] : [$taxType];
|
||||
$allInvoices = [];
|
||||
$totalSummary = ['totalAmount' => 0, 'totalTax' => 0, 'totalSum' => 0, 'count' => 0];
|
||||
$lastPagination = ['currentPage' => $page, 'countPerPage' => $limit, 'maxPageNum' => 1, 'maxIndex' => 0];
|
||||
|
||||
if (!$result['success']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $result['error'],
|
||||
'error_code' => $result['error_code'] ?? null
|
||||
foreach ($taxTypesToQuery as $queryTaxType) {
|
||||
$result = $this->callSoap('GetPeriodTaxInvoicePurchaseList', [
|
||||
'UserID' => $userId,
|
||||
'TaxType' => $queryTaxType, // 1: 과세+영세, 3: 면세
|
||||
'DateType' => 3, // 3: 전송일자 기준 (권장)
|
||||
'StartDate' => $startDate,
|
||||
'EndDate' => $endDate,
|
||||
'CountPerPage' => $limit,
|
||||
'CurrentPage' => $page
|
||||
]);
|
||||
}
|
||||
|
||||
$resultData = $result['data'];
|
||||
if (!$result['success']) {
|
||||
// 첫 번째 조회 실패 시 에러 반환
|
||||
if (empty($allInvoices)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $result['error'],
|
||||
'error_code' => $result['error_code'] ?? null
|
||||
]);
|
||||
}
|
||||
continue; // 이미 일부 데이터가 있으면 계속 진행
|
||||
}
|
||||
|
||||
// 에러 코드 체크
|
||||
$errorCode = $this->checkErrorCode($resultData);
|
||||
if ($errorCode && !in_array($errorCode, [-60005, -60001])) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $this->getErrorMessage($errorCode),
|
||||
'error_code' => $errorCode
|
||||
]);
|
||||
}
|
||||
$resultData = $result['data'];
|
||||
$errorCode = $this->checkErrorCode($resultData);
|
||||
|
||||
// 데이터가 없는 경우
|
||||
if ($errorCode && in_array($errorCode, [-60005, -60001])) {
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => [
|
||||
'invoices' => [],
|
||||
'summary' => ['totalAmount' => 0, 'totalTax' => 0, 'count' => 0],
|
||||
'pagination' => ['currentPage' => 1, 'maxPageNum' => 1]
|
||||
]
|
||||
]);
|
||||
}
|
||||
// 에러 코드 체크 (데이터 없음 외의 에러)
|
||||
if ($errorCode && !in_array($errorCode, [-60005, -60001])) {
|
||||
if (empty($allInvoices)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $this->getErrorMessage($errorCode),
|
||||
'error_code' => $errorCode
|
||||
]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 데이터 파싱
|
||||
$parsed = $this->parseInvoices($resultData, 'purchase');
|
||||
// 데이터가 있는 경우 파싱
|
||||
if (!$errorCode || !in_array($errorCode, [-60005, -60001])) {
|
||||
$parsed = $this->parseInvoices($resultData, 'purchase');
|
||||
$allInvoices = array_merge($allInvoices, $parsed['invoices']);
|
||||
$totalSummary['totalAmount'] += $parsed['summary']['totalAmount'];
|
||||
$totalSummary['totalTax'] += $parsed['summary']['totalTax'];
|
||||
$totalSummary['totalSum'] += $parsed['summary']['totalSum'] ?? ($parsed['summary']['totalAmount'] + $parsed['summary']['totalTax']);
|
||||
$totalSummary['count'] += $parsed['summary']['count'];
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => [
|
||||
'invoices' => $parsed['invoices'],
|
||||
'pagination' => [
|
||||
// 페이지네이션 정보 업데이트 (마지막 조회 결과 사용)
|
||||
$lastPagination = [
|
||||
'currentPage' => $resultData->CurrentPage ?? 1,
|
||||
'countPerPage' => $resultData->CountPerPage ?? 50,
|
||||
'maxPageNum' => $resultData->MaxPageNum ?? 1,
|
||||
'maxIndex' => $resultData->MaxIndex ?? 0
|
||||
],
|
||||
'summary' => $parsed['summary']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// 작성일 기준으로 정렬 (최신순)
|
||||
usort($allInvoices, fn($a, $b) => strcmp($b['writeDate'] ?? '', $a['writeDate'] ?? ''));
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => [
|
||||
'invoices' => $allInvoices,
|
||||
'pagination' => $lastPagination,
|
||||
'summary' => $totalSummary
|
||||
]
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
@@ -482,10 +522,11 @@ public function diagnose(Request $request): JsonResponse
|
||||
];
|
||||
|
||||
// 테스트 2: 매출 세금계산서 조회 (기간: 최근 1개월)
|
||||
// TaxType: 1(과세+영세), 3(면세) 만 가능 / DateType: 3(전송일자) 권장
|
||||
$salesResult = $this->callSoap('GetPeriodTaxInvoiceSalesList', [
|
||||
'UserID' => $userId,
|
||||
'TaxType' => 0,
|
||||
'DateType' => 1,
|
||||
'TaxType' => 1, // 1: 과세+영세 (0은 미지원)
|
||||
'DateType' => 3, // 3: 전송일자 기준 (권장)
|
||||
'StartDate' => date('Ymd', strtotime('-1 month')),
|
||||
'EndDate' => date('Ymd'),
|
||||
'CountPerPage' => 1,
|
||||
@@ -661,8 +702,8 @@ private function getErrorMessage(int $errorCode): string
|
||||
{
|
||||
$messages = [
|
||||
-10002 => '인증 실패 (-10002). CERTKEY가 올바르지 않거나 만료되었습니다.',
|
||||
-10008 => '등록되지 않은 사용자입니다 (-10008). 바로빌에 등록된 사업자번호/사용자ID를 확인해주세요.',
|
||||
-11010 => '세금계산서 조회 권한이 없습니다 (-11010). 바로빌 사이트에서 서비스 권한을 확인해주세요.',
|
||||
-10008 => '날짜형식이 잘못되었습니다 (-10008). 날짜는 YYYYMMDD 형식(하이픈 제외)으로 입력해주세요.',
|
||||
-11010 => '과세형태(TaxType)가 잘못되었습니다 (-11010). TaxType은 1(과세+영세) 또는 3(면세)만 가능합니다.',
|
||||
-24005 => 'UserID가 필요합니다 (-24005). 바로빌 회원사 ID를 설정해주세요.',
|
||||
-24006 => '조회된 데이터가 없습니다 (-24006).',
|
||||
-25005 => '조회된 데이터가 없습니다 (-25005).',
|
||||
|
||||
Reference in New Issue
Block a user