- BarobillSoapService: PHP SoapClient 기반 SOAP 래퍼 (회원/계좌/카드/인증서) - BarobillBankSyncService: 은행 거래내역 SOAP 조회 → DB 캐시 동기화 - BarobillCardSyncService: 카드 거래내역 SOAP 조회 → DB 캐시 동기화 - HometaxSyncService: 홈택스 세금계산서 upsert 동기화 - BarobillSyncController: 동기화/회원/인증서/잔액 API 11개 엔드포인트 - SyncBarobillDataJob: 매일 06:00/06:30 자동 동기화 스케줄러 - BarobillController.status() 보강: 실제 계좌/카드 수 표시
117 lines
4.0 KiB
PHP
117 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Barobill;
|
|
|
|
use App\Models\Barobill\HometaxInvoice;
|
|
use App\Services\Service;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
/**
|
|
* 홈택스 세금계산서 동기화 서비스 (API 독립 구현)
|
|
*
|
|
* MNG의 HometaxSyncService 패턴을 참고하여 독립 작성.
|
|
* 바로빌 API 응답 데이터를 로컬 DB에 upsert한다.
|
|
*/
|
|
class HometaxSyncService extends Service
|
|
{
|
|
/**
|
|
* API 응답 데이터를 로컬 DB에 동기화
|
|
*
|
|
* @param array $invoices API에서 받은 세금계산서 목록
|
|
* @param int $tenantId 테넌트 ID
|
|
* @param string $invoiceType 'sales' 또는 'purchase'
|
|
* @return array 동기화 결과
|
|
*/
|
|
public function syncInvoices(array $invoices, int $tenantId, string $invoiceType): array
|
|
{
|
|
$result = [
|
|
'inserted' => 0,
|
|
'updated' => 0,
|
|
'failed' => 0,
|
|
'total' => count($invoices),
|
|
];
|
|
|
|
if (empty($invoices)) {
|
|
return $result;
|
|
}
|
|
|
|
DB::beginTransaction();
|
|
|
|
try {
|
|
foreach ($invoices as $apiData) {
|
|
if (empty($apiData['ntsConfirmNum'])) {
|
|
$result['failed']++;
|
|
|
|
continue;
|
|
}
|
|
|
|
$modelData = HometaxInvoice::fromApiData($apiData, $tenantId, $invoiceType);
|
|
|
|
$existing = HometaxInvoice::withoutGlobalScopes()
|
|
->where('tenant_id', $tenantId)
|
|
->where('nts_confirm_num', $modelData['nts_confirm_num'])
|
|
->where('invoice_type', $invoiceType)
|
|
->first();
|
|
|
|
if ($existing) {
|
|
$existing->update([
|
|
'write_date' => $modelData['write_date'],
|
|
'issue_date' => $modelData['issue_date'],
|
|
'invoicer_corp_num' => $modelData['invoicer_corp_num'],
|
|
'invoicer_corp_name' => $modelData['invoicer_corp_name'],
|
|
'invoicer_ceo_name' => $modelData['invoicer_ceo_name'],
|
|
'invoicee_corp_num' => $modelData['invoicee_corp_num'],
|
|
'invoicee_corp_name' => $modelData['invoicee_corp_name'],
|
|
'invoicee_ceo_name' => $modelData['invoicee_ceo_name'],
|
|
'supply_amount' => $modelData['supply_amount'],
|
|
'tax_amount' => $modelData['tax_amount'],
|
|
'total_amount' => $modelData['total_amount'],
|
|
'tax_type' => $modelData['tax_type'],
|
|
'purpose_type' => $modelData['purpose_type'],
|
|
'item_name' => $modelData['item_name'],
|
|
'remark' => $modelData['remark'],
|
|
'synced_at' => now(),
|
|
]);
|
|
$result['updated']++;
|
|
} else {
|
|
HometaxInvoice::create($modelData);
|
|
$result['inserted']++;
|
|
}
|
|
}
|
|
|
|
DB::commit();
|
|
|
|
Log::info('[HometaxSync] 동기화 완료', [
|
|
'tenant_id' => $tenantId,
|
|
'invoice_type' => $invoiceType,
|
|
'result' => $result,
|
|
]);
|
|
} catch (\Throwable $e) {
|
|
DB::rollBack();
|
|
Log::error('[HometaxSync] 동기화 실패', [
|
|
'tenant_id' => $tenantId,
|
|
'invoice_type' => $invoiceType,
|
|
'error' => $e->getMessage(),
|
|
]);
|
|
throw $e;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* 마지막 동기화 시간 조회
|
|
*/
|
|
public function getLastSyncTime(int $tenantId, string $invoiceType): ?string
|
|
{
|
|
$lastSync = HometaxInvoice::withoutGlobalScopes()
|
|
->where('tenant_id', $tenantId)
|
|
->where('invoice_type', $invoiceType)
|
|
->orderByDesc('synced_at')
|
|
->value('synced_at');
|
|
|
|
return $lastSync?->format('Y-m-d H:i:s');
|
|
}
|
|
}
|