Files
sam-docs/features/finance/bank-accounts.md
김보곤 2950038b72 docs:재무/자금관리 개발문서 작성 (5개 기능)
- 재무 대시보드 (finance-dashboard.md)
- 일일자금일보 (daily-fund-report.md)
- 자금계획일정 (fund-schedules.md)
- 보유계좌관리 (bank-accounts.md)
- 계좌입출금내역 (account-transactions.md)
- README.md (전체 개요)
2026-02-11 16:17:48 +09:00

255 lines
8.4 KiB
Markdown

# 보유계좌관리
## 개요
보유계좌관리는 회사의 은행계좌 정보를 중앙 집중식으로 관리하는 기능입니다.
계좌 등록/수정/삭제, 잔액 조회, 바로빌 연동 최신 잔액 업데이트를 지원합니다.
- **라우트**: `GET /finance/accounts`
- **라우트 이름**: `finance.accounts.index`
- **UI 기술**: Blade + HTMX
## 파일 구조
```
mng/
├── app/Http/Controllers/
│ ├── Finance/
│ │ └── BankAccountController.php # 웹 컨트롤러
│ └── Api/Admin/
│ └── BankAccountController.php # API 컨트롤러
├── app/Services/
│ └── BankAccountService.php # 비즈니스 로직
├── app/Models/Finance/
│ ├── BankAccount.php # 계좌 모델
│ └── BankTransaction.php # 거래내역 모델
└── resources/views/finance/accounts/
├── index.blade.php # 목록 페이지
├── create.blade.php # 등록 폼
├── edit.blade.php # 수정 폼
├── show.blade.php # 상세 (거래내역 포함)
└── partials/
└── table.blade.php # 테이블 partial (HTMX)
```
## 라우트
### 웹 라우트
```php
// routes/web.php (finance prefix 그룹 내)
Route::get('/accounts', [BankAccountController::class, 'index'])->name('accounts.index');
Route::get('/accounts/create', [..., 'create'])->name('accounts.create');
Route::get('/accounts/{id}', [..., 'show'])->name('accounts.show');
Route::get('/accounts/{id}/edit', [..., 'edit'])->name('accounts.edit');
```
### API 라우트
```php
// routes/api.php (admin/bank-accounts prefix)
GET /all 전체 계좌 (드롭다운용)
GET /summary 요약 통계
GET / 목록 (페이지네이션)
POST / 신규 등록
GET /{id} 상세 조회
PUT /{id} 수정
DELETE /{id} 삭제 (Soft Delete)
POST /{id}/restore 복원
DELETE /{id}/force 영구 삭제 (슈퍼관리자만)
POST /{id}/toggle-active 활성/비활성 토글
GET /{id}/transactions 거래내역 조회
POST /bulk-delete 일괄 삭제
POST /bulk-restore 일괄 복원
```
## 컨트롤러
### BankAccountController (웹)
| 메서드 | 설명 | 특이사항 |
|--------|------|---------|
| `index()` | 계좌 목록 | HTMX 감지 → HX-Redirect (JS 실행 보장) |
| `create()` | 등록 폼 | - |
| `show(id)` | 상세 + 거래내역 | 바로빌 거래 연동 |
| `edit(id)` | 수정 폼 | 404 에러 처리 |
## 서비스 클래스
### BankAccountService
| 메서드 | 설명 |
|--------|------|
| `getAccounts(filters, perPage)` | 목록 (페이지네이션) + 바로빌 최신 거래일 |
| `getAllAccounts()` | 모든 활성 계좌 (드롭다운용) |
| `getStatsByBank()` | 은행별 통계 |
| `getAccountById(id, withTrashed)` | 단일 조회 |
| `createAccount(data)` | 신규 등록 |
| `updateAccount(account, data)` | 수정 |
| `deleteAccount(account)` | Soft Delete |
| `restoreAccount(account)` | 복원 |
| `forceDeleteAccount(account)` | 영구 삭제 |
| `toggleActive(account)` | 활성/비활성 토글 |
| `getTransactions(accountId, filters, perPage)` | 계좌별 거래내역 |
| `getSummary()` | 전체 요약 (총 계좌 수, 총 잔액) |
| `bulkDelete(ids)` | 일괄 삭제 |
| `bulkRestore(ids)` | 일괄 복원 |
**바로빌 연동**: `getAccounts()` 실행 시 서브쿼리로 `barobill_bank_transactions` 테이블의 최신 거래 날짜/시간을 조회하여 계좌 데이터에 병합합니다.
```php
// 계좌번호 매칭: 하이픈 제거
REPLACE(account_number, '-', '') = barobill_bank_transactions.bank_account_num
```
## 모델
### BankAccount
**테이블**: `bank_accounts`
#### 주요 필드
| 필드 | 타입 | 설명 |
|------|------|------|
| `tenant_id` | bigint | 테넌트 ID |
| `bank_code` | string | 은행 코드 (000=한국은행, 020=우리은행 등) |
| `bank_name` | string | 은행명 |
| `account_number` | string | 계좌번호 (하이픈 포함) |
| `account_holder` | string | 예금주명 |
| `account_name` | string | 계좌 별칭 |
| `account_type` | string | 예금종류 (보통예금, 정기예금, 적금) |
| `balance` | decimal(15,2) | 현재 잔액 |
| `currency` | string | 통화 (KRW) |
| `opened_at` | date | 개설일자 |
| `last_transaction_at` | datetime | 최종 거래일시 |
| `branch_name` | string | 지점명 |
| `memo` | text | 메모 |
| `status` | string | active / inactive |
| `is_primary` | boolean | 대표계좌 여부 |
| `sort_order` | int | 정렬 순서 |
#### Traits
- `BelongsToTenant` - 테넌트 기반 자동 필터링
- `SoftDeletes` - Soft Delete 지원
#### 주요 Scope
```php
->active() // status = 'active'
->primary() // is_primary = true
->byBank($name) // 은행별 필터
->byType($type) // 예금종류별 필터
->ordered() // sort_order 정렬
```
#### 주요 Accessor
```php
$account->formatted_balance // "1억 2,345만원" 형식
$account->masked_account_number // "110-***-5678"
```
## 뷰 구성
### index.blade.php
```
┌─ 페이지 헤더 ──────────────────────
│ 제목: "보유계좌관리"
│ 버튼: "계좌 등록" (파란색)
├─ 요약 카드 (3열) ─────────────────
│ 총 계좌 수 | 총 잔액 | 은행 수
├─ 테이블 컨테이너 ─────────────────
│ ├─ 헤더: 검색, 상태 필터
│ └─ HTMX 로드 영역 (#accounts-table)
│ └─ GET /admin/bank-accounts/
├─ partials/table.blade.php ────────
│ 컬럼: 은행 | 계좌번호 | 예금종류 | 잔액 | 개설일자 | 최종처리일시 | 작업
│ ├─ 활성 항목: 수정/삭제 버튼
│ └─ 삭제된 항목: 복원/영구삭제 (opacity-50 bg-red-50)
└─ JavaScript: refreshAccountBalances()
└─ GET /barobill/eaccount/latest-balances
└─ DOM에서 잔액 실시간 업데이트
```
### 테이블 Partial 특징
| 컬럼 | 특이사항 |
|------|---------|
| 은행 | `show/{id}` 링크 |
| 예금종류 | 컬러 배지 (보통예금=파랑, 정기=보라, 적금=초록) |
| 잔액 | `data-account-number` 속성으로 동적 업데이트 |
| 최종처리일시 | 바로빌 거래일 또는 로컬 데이터 |
| 작업 | HTMX 기반 토글/삭제/복원 |
## 데이터 흐름
```
사용자 (브라우저)
BankAccountController::index()
BankAccountService::getSummary()
↓ (bank_accounts: 총 계좌 수, 총 잔액)
View: finance/accounts/index
├─ 요약 카드 표시
├─ HTMX 테이블 로드
│ ↓
│ Api\Admin\BankAccountController
│ ↓
│ BankAccountService::getAccounts()
│ │ ↓
│ │ bank_accounts + 바로빌 최신 거래일 서브쿼리
│ └─ JSON/HTML 반환
└─ refreshAccountBalances()
EaccountController::latestBalances()
barobill_bank_transactions (최신 잔액)
DOM 업데이트
```
## 데이터베이스 스키마
### bank_accounts
**마이그레이션**: `api/database/migrations/2025_12_17_120001_create_bank_accounts_table.php`
```sql
CREATE TABLE bank_accounts (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
tenant_id BIGINT NOT NULL,
bank_code VARCHAR(10),
bank_name VARCHAR(50),
account_number VARCHAR(50),
account_holder VARCHAR(100),
account_name VARCHAR(100),
account_type VARCHAR(20),
balance DECIMAL(15,2) DEFAULT 0,
currency VARCHAR(3) DEFAULT 'KRW',
opened_at DATE,
last_transaction_at DATETIME,
branch_name VARCHAR(100),
memo TEXT,
status VARCHAR(20) DEFAULT 'active',
is_primary BOOLEAN DEFAULT FALSE,
sort_order INT DEFAULT 0,
created_by BIGINT, updated_by BIGINT, deleted_by BIGINT,
created_at TIMESTAMP, updated_at TIMESTAMP, deleted_at TIMESTAMP
);
```
## HTMX 호환성
- Blade + HTMX 기반 (HX-Redirect 사용 - JavaScript 있음)
- 테이블은 HTMX partial로 동적 로드
- 토글/삭제/복원 액션은 HTMX로 처리