feat:홈택스 세금계산서 자동 증분 동기화
페이지 로드 시 바로빌 API를 백그라운드에서 호출하여 신규 데이터를 자동 동기화. 수동 데이터소스 토글/저장 버튼 제거, 항상 로컬 DB에서 즉시 표시 후 증분 동기화. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1360,6 +1360,84 @@ public function sync(Request $request, HometaxSyncService $syncService): JsonRes
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 자동 증분 동기화
|
||||
* 마지막 동기화 시점 이후의 데이터만 바로빌 API에서 가져와 로컬 DB에 저장
|
||||
*/
|
||||
public function autoSync(Request $request, HometaxSyncService $syncService): JsonResponse
|
||||
{
|
||||
try {
|
||||
$tenantId = session('selected_tenant_id', self::HEADQUARTERS_TENANT_ID);
|
||||
$type = $request->input('type', 'sales'); // 'sales' 또는 'purchase'
|
||||
$barobillMember = BarobillMember::where('tenant_id', $tenantId)->first();
|
||||
|
||||
if (!$barobillMember) {
|
||||
return response()->json(['success' => true, 'skipped' => true, 'reason' => 'no_member']);
|
||||
}
|
||||
|
||||
// 마지막 동기화 시간 확인
|
||||
$lastFetchField = $type === 'sales' ? 'last_sales_fetch_at' : 'last_purchases_fetch_at';
|
||||
$lastFetch = $barobillMember->$lastFetchField;
|
||||
|
||||
// 10분 이내에 이미 동기화했으면 스킵
|
||||
if ($lastFetch && $lastFetch->diffInMinutes(now()) < 10) {
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'skipped' => true,
|
||||
'reason' => 'recent_sync',
|
||||
'lastSyncAt' => $syncService->getLastSyncTime($tenantId, $type),
|
||||
'lastFetchAt' => $lastFetch->format('Y-m-d H:i:s'),
|
||||
]);
|
||||
}
|
||||
|
||||
// 증분 범위 계산: 마지막 동기화일 -1일 ~ 오늘
|
||||
$startDate = $lastFetch
|
||||
? $lastFetch->copy()->subDay()->format('Ymd')
|
||||
: date('Ymd', strtotime('-1 month'));
|
||||
$endDate = date('Ymd');
|
||||
|
||||
// 기존 sync 로직 재사용: API 호출 → DB 저장
|
||||
$apiMethod = $type === 'sales' ? 'sales' : 'purchases';
|
||||
$apiRequest = new Request([
|
||||
'startDate' => $startDate,
|
||||
'endDate' => $endDate,
|
||||
'dateType' => 1, // 작성일자 기준
|
||||
'limit' => 500,
|
||||
]);
|
||||
|
||||
$apiResponse = $this->$apiMethod($apiRequest);
|
||||
$apiData = json_decode($apiResponse->getContent(), true);
|
||||
|
||||
$syncResult = ['inserted' => 0, 'updated' => 0, 'total' => 0];
|
||||
|
||||
if ($apiData['success'] && !empty($apiData['data']['invoices'])) {
|
||||
$syncResult = $syncService->syncInvoices(
|
||||
$apiData['data']['invoices'],
|
||||
$tenantId,
|
||||
$type
|
||||
);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'skipped' => false,
|
||||
'data' => $syncResult,
|
||||
'hasNewData' => ($syncResult['inserted'] ?? 0) > 0,
|
||||
'lastSyncAt' => $syncService->getLastSyncTime($tenantId, $type),
|
||||
'lastFetchAt' => now()->format('Y-m-d H:i:s'),
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('홈택스 자동동기화 오류: ' . $e->getMessage());
|
||||
// 자동동기화 실패는 치명적이지 않음 - 로컬 데이터는 정상 표시됨
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'skipped' => true,
|
||||
'reason' => 'error',
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 세금계산서 메모 업데이트
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user