feat:바로빌 계좌 거래내역 적요/내용 수정 기능 추가

- BankTransactionOverride 모델 추가 (오버라이드 데이터 관리)
- EaccountController에 saveOverride 엔드포인트 추가
- parseTransactionLogs에서 오버라이드 데이터 병합 로직 추가
- 프론트엔드에 TransactionEditModal 컴포넌트 추가
- 적요 셀 클릭 시 수정 모달 표시
- 오버라이드된 항목 시각적 표시 (배경색, 수정 배지)
- 원본 복원 기능 포함

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
김보곤
2026-02-06 09:57:55 +09:00
parent 5bd0b288a7
commit fd0b8d8536
4 changed files with 415 additions and 14 deletions

View File

@@ -7,6 +7,7 @@
use App\Models\Barobill\BarobillConfig;
use App\Models\Barobill\BarobillMember;
use App\Models\Barobill\BankTransaction;
use App\Models\Barobill\BankTransactionOverride;
use App\Models\Tenants\Tenant;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -309,9 +310,12 @@ public function transactions(Request $request): JsonResponse
// DB에서 저장된 계정과목 데이터 조회
$savedData = BankTransaction::getByDateRange($tenantId, $startDate, $endDate, $bankAccountNum ?: null);
// 오버라이드 데이터 (수정된 적요/내용) 조회
$overrideData = null;
// 전체 계좌 조회: 빈 값이면 모든 계좌의 거래 내역 조회
if (empty($bankAccountNum)) {
return $this->getAllAccountsTransactions($userId, $startDate, $endDate, $page, $limit, $savedData);
return $this->getAllAccountsTransactions($userId, $startDate, $endDate, $page, $limit, $savedData, $overrideData, $tenantId);
}
// 단일 계좌 조회
@@ -358,8 +362,8 @@ public function transactions(Request $request): JsonResponse
]);
}
// 데이터 파싱 (저장된 계정과목 병합)
$logs = $this->parseTransactionLogs($resultData, '', $savedData);
// 데이터 파싱 (저장된 계정과목 + 오버라이드 병합)
$logs = $this->parseTransactionLogs($resultData, '', $savedData, $tenantId);
return response()->json([
'success' => true,
@@ -386,7 +390,7 @@ public function transactions(Request $request): JsonResponse
/**
* 전체 계좌의 거래 내역 조회
*/
private function getAllAccountsTransactions(string $userId, string $startDate, string $endDate, int $page, int $limit, $savedData = null): JsonResponse
private function getAllAccountsTransactions(string $userId, string $startDate, string $endDate, int $page, int $limit, $savedData = null, $overrideData = null, int $tenantId = 1): JsonResponse
{
// 먼저 계좌 목록 조회
$accountResult = $this->callSoap('GetBankAccountEx', ['AvailOnly' => 0]);
@@ -432,7 +436,7 @@ private function getAllAccountsTransactions(string $userId, string $startDate, s
$errorCode = $this->checkErrorCode($accData);
if (!$errorCode || in_array($errorCode, [-25005, -25001])) {
$parsed = $this->parseTransactionLogs($accData, $acc->BankName ?? '', $savedData);
$parsed = $this->parseTransactionLogs($accData, $acc->BankName ?? '', $savedData, $tenantId);
foreach ($parsed['logs'] as $log) {
$log['bankName'] = $acc->BankName ?? $this->getBankName($acc->BankCode ?? '');
$allLogs[] = $log;
@@ -476,11 +480,12 @@ private function getAllAccountsTransactions(string $userId, string $startDate, s
}
/**
* 거래 내역 파싱 (저장된 계정과목 병합)
* 거래 내역 파싱 (저장된 계정과목 + 오버라이드 병합)
*/
private function parseTransactionLogs($resultData, string $defaultBankName = '', $savedData = null): array
private function parseTransactionLogs($resultData, string $defaultBankName = '', $savedData = null, int $tenantId = 1): array
{
$logs = [];
$uniqueKeys = [];
$totalDeposit = 0;
$totalWithdraw = 0;
@@ -491,6 +496,22 @@ private function parseTransactionLogs($resultData, string $defaultBankName = '',
: [$resultData->BankAccountLogList->BankAccountTransLog];
}
// 1단계: 모든 고유 키 수집
foreach ($rawLogs as $log) {
$bankAccountNum = $log->BankAccountNum ?? '';
$transDT = $log->TransDT ?? '';
$deposit = (int) floatval($log->Deposit ?? 0);
$withdraw = (int) floatval($log->Withdraw ?? 0);
$balance = (int) floatval($log->Balance ?? 0);
$uniqueKey = implode('|', [$bankAccountNum, $transDT, $deposit, $withdraw, $balance]);
$uniqueKeys[] = $uniqueKey;
}
// 2단계: 오버라이드 데이터 일괄 조회
$overrides = BankTransactionOverride::getByUniqueKeys($tenantId, $uniqueKeys);
// 3단계: 각 로그 처리
foreach ($rawLogs as $log) {
$deposit = floatval($log->Deposit ?? 0);
$withdraw = floatval($log->Withdraw ?? 0);
@@ -525,6 +546,15 @@ private function parseTransactionLogs($resultData, string $defaultBankName = '',
// 고유 키 생성하여 저장된 데이터와 매칭 (숫자는 정수로 변환하여 형식 통일)
$uniqueKey = implode('|', [$bankAccountNum, $transDT, (int) $deposit, (int) $withdraw, (int) $balance]);
$savedItem = $savedData?->get($uniqueKey);
$override = $overrides->get($uniqueKey);
// 원본 적요/내용
$originalSummary = $fullSummary;
$originalCast = $savedItem?->cast ?? '';
// 오버라이드 적용 (수정된 값이 있으면 사용)
$displaySummary = $override?->modified_summary ?? $originalSummary;
$displayCast = $override?->modified_cast ?? $originalCast;
$logItem = [
'transDate' => $transDate,
@@ -538,15 +568,18 @@ private function parseTransactionLogs($resultData, string $defaultBankName = '',
'withdrawFormatted' => number_format($withdraw),
'balance' => $balance,
'balanceFormatted' => number_format($balance),
'summary' => $fullSummary,
// 저장된 상대계좌예금주명 우선 사용 (직접 입력 가능)
'cast' => $savedItem?->cast ?? '',
'summary' => $displaySummary,
'originalSummary' => $originalSummary,
'cast' => $displayCast,
'originalCast' => $originalCast,
'memo' => $log->Memo ?? '',
'transOffice' => $log->TransOffice ?? '',
// 저장된 계정과목 정보 병합
'accountCode' => $savedItem?->account_code ?? '',
'accountName' => $savedItem?->account_name ?? '',
'isSaved' => $savedItem !== null,
'isOverridden' => $override !== null,
'uniqueKey' => $uniqueKey,
];
$logs[] = $logItem;
@@ -965,6 +998,53 @@ public function exportExcel(Request $request): StreamedResponse|JsonResponse
}
}
/**
* 거래내역 적요/내용 오버라이드 저장
*/
public function saveOverride(Request $request): JsonResponse
{
try {
$tenantId = session('selected_tenant_id', self::HEADQUARTERS_TENANT_ID);
$validated = $request->validate([
'uniqueKey' => 'required|string|max:100',
'modifiedSummary' => 'nullable|string|max:200',
'modifiedCast' => 'nullable|string|max:200',
]);
$result = BankTransactionOverride::saveOverride(
$tenantId,
$validated['uniqueKey'],
$validated['modifiedSummary'] ?? null,
$validated['modifiedCast'] ?? null
);
if ($result === null) {
return response()->json([
'success' => true,
'message' => '오버라이드가 삭제되었습니다.',
'deleted' => true
]);
}
return response()->json([
'success' => true,
'message' => '오버라이드가 저장되었습니다.',
'data' => [
'id' => $result->id,
'modifiedSummary' => $result->modified_summary,
'modifiedCast' => $result->modified_cast,
]
]);
} catch (\Throwable $e) {
Log::error('오버라이드 저장 오류: ' . $e->getMessage());
return response()->json([
'success' => false,
'error' => '저장 오류: ' . $e->getMessage()
], 500);
}
}
/**
* SOAP 호출
*/