fix:바로빌 계좌 입출금내역 긴 기간 검색 시 데이터 누락 수정
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\View\View;
|
||||
use Carbon\Carbon;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
/**
|
||||
@@ -344,41 +345,11 @@ public function transactions(Request $request): JsonResponse
|
||||
return $this->getAllAccountsTransactions($userId, $startDate, $endDate, $page, $limit, $savedData, $overrideData, $tenantId, $manualTransactions);
|
||||
}
|
||||
|
||||
// 단일 계좌 조회
|
||||
$result = $this->callSoap('GetPeriodBankAccountTransLog', [
|
||||
'ID' => $userId,
|
||||
'BankAccountNum' => $bankAccountNum,
|
||||
'StartDate' => $startDate,
|
||||
'EndDate' => $endDate,
|
||||
'TransDirection' => 1, // 1:전체
|
||||
'CountPerPage' => $limit,
|
||||
'CurrentPage' => $page,
|
||||
'OrderDirection' => 2 // 2:내림차순
|
||||
]);
|
||||
// 단일 계좌 조회 - 기간을 월별로 분할하여 SOAP API 호출 (긴 기간 에러 방지)
|
||||
$fetched = $this->fetchAccountTransactions($userId, $bankAccountNum, $startDate, $endDate);
|
||||
|
||||
if (!$result['success']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $result['error'],
|
||||
'error_code' => $result['error_code'] ?? null
|
||||
]);
|
||||
}
|
||||
|
||||
$resultData = $result['data'];
|
||||
|
||||
// 에러 코드 체크
|
||||
$errorCode = $this->checkErrorCode($resultData);
|
||||
if ($errorCode && !in_array($errorCode, [-25005, -25001])) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => $this->getErrorMessage($errorCode),
|
||||
'error_code' => $errorCode
|
||||
]);
|
||||
}
|
||||
|
||||
// 데이터가 없는 경우
|
||||
if ($errorCode && in_array($errorCode, [-25005, -25001])) {
|
||||
// API 데이터 없어도 수동 건은 표시
|
||||
// API 데이터가 없는 경우 (수동 건만 표시)
|
||||
if (empty($fetched['logs'])) {
|
||||
$manualLogs = $this->convertManualToLogs($manualTransactions);
|
||||
$baseBalance = $this->findBaseBalance($tenantId, $startDate, $bankAccountNum);
|
||||
$recalcLogs = $this->recalcManualBalances($manualLogs['logs'], $baseBalance);
|
||||
@@ -392,8 +363,12 @@ public function transactions(Request $request): JsonResponse
|
||||
]);
|
||||
}
|
||||
|
||||
// 데이터 파싱 (저장된 계정과목 + 오버라이드 병합)
|
||||
$logs = $this->parseTransactionLogs($resultData, '', $savedData, $tenantId);
|
||||
// 월별 청크 결과를 합쳐서 파싱
|
||||
$fakeData = new \stdClass();
|
||||
$fakeData->BankAccountLogList = new \stdClass();
|
||||
$fakeData->BankAccountLogList->BankAccountTransLog = $fetched['logs'];
|
||||
|
||||
$logs = $this->parseTransactionLogs($fakeData, '', $savedData, $tenantId);
|
||||
|
||||
// 수동 입력 건 병합 (중복 제거: 수동 거래와 동일한 API 거래는 제외)
|
||||
$manualLogs = $this->convertManualToLogs($manualTransactions);
|
||||
@@ -418,15 +393,21 @@ public function transactions(Request $request): JsonResponse
|
||||
'count' => count($mergedLogs),
|
||||
];
|
||||
|
||||
// 클라이언트 사이드 페이지네이션
|
||||
$totalCount = count($mergedLogs);
|
||||
$maxPageNum = (int)ceil($totalCount / $limit);
|
||||
$startIndex = ($page - 1) * $limit;
|
||||
$paginatedLogs = array_slice($mergedLogs, $startIndex, $limit);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => [
|
||||
'logs' => $mergedLogs,
|
||||
'logs' => $paginatedLogs,
|
||||
'pagination' => [
|
||||
'currentPage' => $resultData->CurrentPage ?? 1,
|
||||
'countPerPage' => $resultData->CountPerPage ?? 50,
|
||||
'maxPageNum' => $resultData->MaxPageNum ?? 1,
|
||||
'maxIndex' => $resultData->MaxIndex ?? 0
|
||||
'currentPage' => $page,
|
||||
'countPerPage' => $limit,
|
||||
'maxPageNum' => $maxPageNum,
|
||||
'maxIndex' => $totalCount
|
||||
],
|
||||
'summary' => $mergedSummary
|
||||
]
|
||||
@@ -473,30 +454,21 @@ private function getAllAccountsTransactions(string $userId, string $startDate, s
|
||||
$accNum = $acc->BankAccountNum ?? '';
|
||||
if (empty($accNum) || (is_numeric($accNum) && $accNum < 0)) continue;
|
||||
|
||||
$accResult = $this->callSoap('GetPeriodBankAccountTransLog', [
|
||||
'ID' => $userId,
|
||||
'BankAccountNum' => $accNum,
|
||||
'StartDate' => $startDate,
|
||||
'EndDate' => $endDate,
|
||||
'TransDirection' => 1,
|
||||
'CountPerPage' => 1000,
|
||||
'CurrentPage' => 1,
|
||||
'OrderDirection' => 2
|
||||
]);
|
||||
// 기간을 월별로 분할하여 SOAP API 호출 (긴 기간 에러 방지)
|
||||
$fetched = $this->fetchAccountTransactions($userId, $accNum, $startDate, $endDate);
|
||||
|
||||
if ($accResult['success']) {
|
||||
$accData = $accResult['data'];
|
||||
$errorCode = $this->checkErrorCode($accData);
|
||||
if (!empty($fetched['logs'])) {
|
||||
$fakeData = new \stdClass();
|
||||
$fakeData->BankAccountLogList = new \stdClass();
|
||||
$fakeData->BankAccountLogList->BankAccountTransLog = $fetched['logs'];
|
||||
|
||||
if (!$errorCode || in_array($errorCode, [-25005, -25001])) {
|
||||
$parsed = $this->parseTransactionLogs($accData, $acc->BankName ?? '', $savedData, $tenantId);
|
||||
foreach ($parsed['logs'] as $log) {
|
||||
$log['bankName'] = $acc->BankName ?? $this->getBankName($acc->BankCode ?? '');
|
||||
$allLogs[] = $log;
|
||||
}
|
||||
$totalDeposit += $parsed['summary']['totalDeposit'];
|
||||
$totalWithdraw += $parsed['summary']['totalWithdraw'];
|
||||
$parsed = $this->parseTransactionLogs($fakeData, $acc->BankName ?? '', $savedData, $tenantId);
|
||||
foreach ($parsed['logs'] as $log) {
|
||||
$log['bankName'] = $acc->BankName ?? $this->getBankName($acc->BankCode ?? '');
|
||||
$allLogs[] = $log;
|
||||
}
|
||||
$totalDeposit += $parsed['summary']['totalDeposit'];
|
||||
$totalWithdraw += $parsed['summary']['totalWithdraw'];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -692,6 +664,98 @@ private function getErrorMessage(int $errorCode): string
|
||||
return $messages[$errorCode] ?? '바로빌 API 오류: ' . $errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 긴 기간을 월별 청크로 분할 (바로빌 API 기간 제한 대응)
|
||||
* YYYYMMDD 형식의 시작/종료일을 받아 월별 [start, end] 배열 반환
|
||||
*/
|
||||
private function splitDateRangeMonthly(string $startDate, string $endDate): array
|
||||
{
|
||||
$start = Carbon::createFromFormat('Ymd', $startDate)->startOfDay();
|
||||
$end = Carbon::createFromFormat('Ymd', $endDate)->endOfDay();
|
||||
|
||||
$chunks = [];
|
||||
$cursor = $start->copy();
|
||||
|
||||
while ($cursor->lte($end)) {
|
||||
$chunkStart = $cursor->copy();
|
||||
$chunkEnd = $cursor->copy()->endOfMonth()->startOfDay();
|
||||
|
||||
// 마지막 청크: 종료일이 월말보다 이전이면 종료일 사용
|
||||
if ($chunkEnd->gt($end)) {
|
||||
$chunkEnd = $end->copy()->startOfDay();
|
||||
}
|
||||
|
||||
$chunks[] = [
|
||||
'start' => $chunkStart->format('Ymd'),
|
||||
'end' => $chunkEnd->format('Ymd'),
|
||||
];
|
||||
|
||||
// 다음 월 1일로 이동
|
||||
$cursor = $chunkEnd->copy()->addDay()->startOfMonth();
|
||||
}
|
||||
|
||||
return $chunks;
|
||||
}
|
||||
|
||||
/**
|
||||
* 단일 계좌의 거래 내역을 기간 분할하여 조회
|
||||
* 긴 기간도 월별로 나누어 SOAP API 호출 후 병합
|
||||
*/
|
||||
private function fetchAccountTransactions(string $userId, string $accNum, string $startDate, string $endDate): array
|
||||
{
|
||||
$chunks = $this->splitDateRangeMonthly($startDate, $endDate);
|
||||
$allRawLogs = [];
|
||||
$lastSuccessData = null;
|
||||
|
||||
foreach ($chunks as $chunk) {
|
||||
$result = $this->callSoap('GetPeriodBankAccountTransLog', [
|
||||
'ID' => $userId,
|
||||
'BankAccountNum' => $accNum,
|
||||
'StartDate' => $chunk['start'],
|
||||
'EndDate' => $chunk['end'],
|
||||
'TransDirection' => 1,
|
||||
'CountPerPage' => 1000,
|
||||
'CurrentPage' => 1,
|
||||
'OrderDirection' => 2
|
||||
]);
|
||||
|
||||
if (!$result['success']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$chunkData = $result['data'];
|
||||
$errorCode = $this->checkErrorCode($chunkData);
|
||||
|
||||
// 데이터 없음(-25005, -25001)은 건너뜀, 기타 에러도 건너뜀 (다른 월은 성공할 수 있음)
|
||||
if ($errorCode && !in_array($errorCode, [-25005, -25001])) {
|
||||
Log::debug("바로빌 API 기간 분할 - 에러 발생 ({$chunk['start']}~{$chunk['end']}): {$errorCode}");
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($errorCode && in_array($errorCode, [-25005, -25001])) {
|
||||
continue; // 데이터 없음
|
||||
}
|
||||
|
||||
// 로그 추출
|
||||
$rawLogs = [];
|
||||
if (isset($chunkData->BankAccountLogList) && isset($chunkData->BankAccountLogList->BankAccountTransLog)) {
|
||||
$logs = $chunkData->BankAccountLogList->BankAccountTransLog;
|
||||
$rawLogs = is_array($logs) ? $logs : [$logs];
|
||||
}
|
||||
|
||||
foreach ($rawLogs as $log) {
|
||||
$allRawLogs[] = $log;
|
||||
}
|
||||
|
||||
$lastSuccessData = $chunkData;
|
||||
}
|
||||
|
||||
return [
|
||||
'logs' => $allRawLogs,
|
||||
'lastData' => $lastSuccessData,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 은행 코드 -> 은행명 변환
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user