From bd45eb52a25b98a3269faf741097e2e7c2dfc2f7 Mon Sep 17 00:00:00 2001 From: pro Date: Fri, 23 Jan 2026 17:33:26 +0900 Subject: [PATCH] =?UTF-8?q?fix:GetPeriodTaxInvoiceSalesList/PurchaseList?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TaxType, DateType 필수 파라미터 추가 - SimpleTaxInvoiceEx 응답 구조에 맞게 파싱 수정 - AmountTotal, TaxTotal, TotalAmount 필드 사용 - 과세유형/영수청구 코드 정수형 처리 추가 --- .../Barobill/HometaxController.php | 115 +++++++++--------- 1 file changed, 57 insertions(+), 58 deletions(-) diff --git a/app/Http/Controllers/Barobill/HometaxController.php b/app/Http/Controllers/Barobill/HometaxController.php index 7d7293dd..5bdee3df 100644 --- a/app/Http/Controllers/Barobill/HometaxController.php +++ b/app/Http/Controllers/Barobill/HometaxController.php @@ -85,7 +85,7 @@ public function index(Request $request): View|Response } /** - * 매출 세금계산서 목록 조회 (GetTaxInvoiceSalesListEx) + * 매출 세금계산서 목록 조회 (GetPeriodTaxInvoiceSalesList) */ public function sales(Request $request): JsonResponse { @@ -94,19 +94,21 @@ 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:면세 // 현재 테넌트의 바로빌 회원 정보 조회 $tenantId = session('selected_tenant_id', self::HEADQUARTERS_TENANT_ID); $barobillMember = BarobillMember::where('tenant_id', $tenantId)->first(); $userId = $barobillMember?->barobill_id ?? ''; - $result = $this->callSoap('GetTaxInvoiceSalesListEx', [ - 'ID' => $userId, + $result = $this->callSoap('GetPeriodTaxInvoiceSalesList', [ + 'UserID' => $userId, + 'TaxType' => $taxType, + 'DateType' => 1, // 1:작성일 기준 'StartDate' => $startDate, 'EndDate' => $endDate, 'CountPerPage' => $limit, - 'CurrentPage' => $page, - 'OrderDirection' => 2 // 2: 내림차순 + 'CurrentPage' => $page ]); if (!$result['success']) { @@ -167,7 +169,7 @@ public function sales(Request $request): JsonResponse } /** - * 매입 세금계산서 목록 조회 (GetTaxInvoicePurchaseListEx) + * 매입 세금계산서 목록 조회 (GetPeriodTaxInvoicePurchaseList) */ public function purchases(Request $request): JsonResponse { @@ -176,19 +178,21 @@ 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:면세 // 현재 테넌트의 바로빌 회원 정보 조회 $tenantId = session('selected_tenant_id', self::HEADQUARTERS_TENANT_ID); $barobillMember = BarobillMember::where('tenant_id', $tenantId)->first(); $userId = $barobillMember?->barobill_id ?? ''; - $result = $this->callSoap('GetTaxInvoicePurchaseListEx', [ - 'ID' => $userId, + $result = $this->callSoap('GetPeriodTaxInvoicePurchaseList', [ + 'UserID' => $userId, + 'TaxType' => $taxType, + 'DateType' => 1, // 1:작성일 기준 'StartDate' => $startDate, 'EndDate' => $endDate, 'CountPerPage' => $limit, - 'CurrentPage' => $page, - 'OrderDirection' => 2 // 2: 내림차순 + 'CurrentPage' => $page ]); if (!$result['success']) { @@ -292,7 +296,7 @@ private function getProperty(object $obj, string $prop, mixed $default = ''): mi } /** - * 세금계산서 파싱 + * 세금계산서 파싱 (PagedTaxInvoiceEx -> SimpleTaxInvoiceEx) */ private function parseInvoices($resultData, string $type = 'sales'): array { @@ -301,73 +305,65 @@ private function parseInvoices($resultData, string $type = 'sales'): array $totalTax = 0; $rawList = []; - // TI.asmx 응답 구조: TaxInvoiceSalesList / TaxInvoicePurchaseList - $listProperty = $type === 'sales' ? 'TaxInvoiceSalesList' : 'TaxInvoicePurchaseList'; - $itemProperty = $type === 'sales' ? 'TaxInvoiceSales' : 'TaxInvoicePurchase'; - if (isset($resultData->$listProperty) && isset($resultData->$listProperty->$itemProperty)) { - $rawList = is_array($resultData->$listProperty->$itemProperty) - ? $resultData->$listProperty->$itemProperty - : [$resultData->$listProperty->$itemProperty]; + // PagedTaxInvoiceEx 응답 구조: SimpleTaxInvoiceExList -> SimpleTaxInvoiceEx + if (isset($resultData->SimpleTaxInvoiceExList) && isset($resultData->SimpleTaxInvoiceExList->SimpleTaxInvoiceEx)) { + $rawList = is_array($resultData->SimpleTaxInvoiceExList->SimpleTaxInvoiceEx) + ? $resultData->SimpleTaxInvoiceExList->SimpleTaxInvoiceEx + : [$resultData->SimpleTaxInvoiceExList->SimpleTaxInvoiceEx]; } foreach ($rawList as $item) { - $supplyAmount = floatval($this->getProperty($item, 'SupplyAmount', 0)); - $taxAmount = floatval($this->getProperty($item, 'TaxAmount', 0)); + // SimpleTaxInvoiceEx는 AmountTotal, TaxTotal, TotalAmount 사용 + $supplyAmount = floatval($this->getProperty($item, 'AmountTotal', 0)); + $taxAmount = floatval($this->getProperty($item, 'TaxTotal', 0)); + $total = floatval($this->getProperty($item, 'TotalAmount', 0)); + if ($total == 0) { + $total = $supplyAmount + $taxAmount; + } $totalAmount += $supplyAmount; $totalTax += $taxAmount; - // 날짜 포맷팅 - WriteDate 또는 IssueDate 사용 + // 날짜 포맷팅 - WriteDate 또는 IssueDT 사용 $writeDate = $this->getProperty($item, 'WriteDate', ''); if (empty($writeDate)) { - $writeDate = $this->getProperty($item, 'IssueDate', ''); + $writeDate = $this->getProperty($item, 'IssueDT', ''); } $formattedDate = ''; if (!empty($writeDate) && strlen($writeDate) >= 8) { $formattedDate = substr($writeDate, 0, 4) . '-' . substr($writeDate, 4, 2) . '-' . substr($writeDate, 6, 2); } - // 과세유형 - TaxType 또는 TaxKind 사용 + // 과세유형 (int: 1=과세, 2=영세, 3=면세) $taxType = $this->getProperty($item, 'TaxType', ''); - if (empty($taxType)) { - $taxType = $this->getProperty($item, 'TaxKind', ''); - } - // 발급유형 - IssueType 또는 IssueDirection 사용 - $issueType = $this->getProperty($item, 'IssueType', ''); - if (empty($issueType)) { - $issueType = $this->getProperty($item, 'IssueDirection', ''); - } - - // 영수/청구 - PurposeType 또는 PurposeCode 사용 + // 영수/청구 (int: 1=영수, 2=청구) $purposeType = $this->getProperty($item, 'PurposeType', ''); - if (empty($purposeType)) { - $purposeType = $this->getProperty($item, 'PurposeCode', ''); - } $invoices[] = [ - 'ntsConfirmNum' => $this->getProperty($item, 'NTSConfirmNum', ''), + 'ntsConfirmNum' => $this->getProperty($item, 'NTSSendKey', ''), 'writeDate' => $writeDate, 'writeDateFormatted' => $formattedDate, + 'issueDT' => $this->getProperty($item, 'IssueDT', ''), 'invoicerCorpNum' => $this->getProperty($item, 'InvoicerCorpNum', ''), 'invoicerCorpName' => $this->getProperty($item, 'InvoicerCorpName', ''), + 'invoicerCEOName' => $this->getProperty($item, 'InvoicerCEOName', ''), 'invoiceeCorpNum' => $this->getProperty($item, 'InvoiceeCorpNum', ''), 'invoiceeCorpName' => $this->getProperty($item, 'InvoiceeCorpName', ''), + 'invoiceeCEOName' => $this->getProperty($item, 'InvoiceeCEOName', ''), 'supplyAmount' => $supplyAmount, 'supplyAmountFormatted' => number_format($supplyAmount), 'taxAmount' => $taxAmount, 'taxAmountFormatted' => number_format($taxAmount), - 'totalAmount' => $supplyAmount + $taxAmount, - 'totalAmountFormatted' => number_format($supplyAmount + $taxAmount), + 'totalAmount' => $total, + 'totalAmountFormatted' => number_format($total), 'taxType' => $taxType, 'taxTypeName' => $this->getTaxTypeName($taxType), - 'issueType' => $issueType, - 'issueTypeName' => $this->getIssueTypeName($issueType), 'purposeType' => $purposeType, 'purposeTypeName' => $this->getPurposeTypeName($purposeType), 'modifyCode' => $this->getProperty($item, 'ModifyCode', ''), 'remark' => $this->getProperty($item, 'Remark1', ''), - 'collectDate' => $this->getProperty($item, 'CollectDate', ''), + 'itemName' => $this->getProperty($item, 'ItemName', ''), ]; } @@ -424,40 +420,43 @@ private function getCollectTypeCode(string $type): int } /** - * 과세유형 코드 -> 명칭 + * 과세유형 코드 -> 명칭 (1:과세, 2:영세, 3:면세) */ - private function getTaxTypeName(string $code): string + private function getTaxTypeName(mixed $code): string { + $code = (string)$code; return match($code) { - '01' => '과세', - '02' => '영세', - '03' => '면세', - default => $code + '1', '01' => '과세', + '2', '02' => '영세', + '3', '03' => '면세', + default => $code ?: '-' }; } /** * 발급유형 코드 -> 명칭 */ - private function getIssueTypeName(string $code): string + private function getIssueTypeName(mixed $code): string { + $code = (string)$code; return match($code) { - '01' => '정발행', - '02' => '역발행', - '03' => '위수탁', - default => $code + '1', '01' => '정발행', + '2', '02' => '역발행', + '3', '03' => '위수탁', + default => $code ?: '-' }; } /** - * 영수/청구 코드 -> 명칭 + * 영수/청구 코드 -> 명칭 (1:영수, 2:청구) */ - private function getPurposeTypeName(string $code): string + private function getPurposeTypeName(mixed $code): string { + $code = (string)$code; return match($code) { - '01' => '영수', - '02' => '청구', - default => $code + '1', '01' => '영수', + '2', '02' => '청구', + default => $code ?: '-' }; }