docs:재무/자금관리 개발문서 작성 (5개 기능)
- 재무 대시보드 (finance-dashboard.md) - 일일자금일보 (daily-fund-report.md) - 자금계획일정 (fund-schedules.md) - 보유계좌관리 (bank-accounts.md) - 계좌입출금내역 (account-transactions.md) - README.md (전체 개요)
This commit is contained in:
82
features/finance/README.md
Normal file
82
features/finance/README.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# 재무/자금관리 기능
|
||||
|
||||
## 개요
|
||||
|
||||
SAM 프로젝트의 재무/자금관리 모듈은 회사의 자금 흐름을 종합적으로 관리하는 시스템입니다.
|
||||
바로빌 API 연동을 통한 실시간 거래 조회, 계좌 관리, 자금 계획, 전표 관리 기능을 제공합니다.
|
||||
|
||||
## 메뉴 구성
|
||||
|
||||
| 메뉴 | 경로 | 설명 | UI 기술 |
|
||||
|------|------|------|---------|
|
||||
| [재무 대시보드](./finance-dashboard.md) | `/finance/dashboard` | 자금 현황 종합 요약 | Blade + JS |
|
||||
| [일일자금일보](./daily-fund-report.md) | `/finance/daily-fund` | 기간별 계좌 입출금 현황 보고서 | React 18 |
|
||||
| [자금계획일정](./fund-schedules.md) | `/finance/fund-schedules` | 입금/지급 예정 일정 관리 | Blade |
|
||||
| [보유계좌관리](./bank-accounts.md) | `/finance/accounts` | 회사 은행계좌 정보 관리 | Blade + HTMX |
|
||||
| [계좌입출금내역](./account-transactions.md) | `/finance/account-transactions` | 바로빌 연동 거래 조회 및 회계 분류 | React 18 |
|
||||
|
||||
## 아키텍처
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 재무 대시보드 │
|
||||
│ (총 잔액, 예정 수입/지출, 최근 거래, 계좌별 잔액) │
|
||||
└──────────┬──────────────────┬──────────────────┬────────┘
|
||||
│ │ │
|
||||
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
|
||||
│ 보유계좌관리 │ │ 자금계획일정 │ │ 계좌입출금내역 │
|
||||
│ (계좌 CRUD) │ │ (일정 CRUD) │ │(바로빌 연동) │
|
||||
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
|
||||
│ │ │
|
||||
┌──────▼──────────────────▼──────────────────▼──────┐
|
||||
│ 데이터베이스 │
|
||||
│ bank_accounts, fund_schedules, │
|
||||
│ barobill_bank_transactions, journal_entries │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 주요 기술 스택
|
||||
|
||||
| 기술 | 용도 |
|
||||
|------|------|
|
||||
| Laravel 11 (PHP 8.3) | 백엔드 프레임워크 |
|
||||
| Blade + Tailwind CSS | 서버 렌더링 UI (대시보드, 계좌관리, 자금일정) |
|
||||
| React 18 + Babel | 클라이언트 렌더링 UI (자금일보, 입출금내역) |
|
||||
| HTMX | 부분 페이지 업데이트 (계좌 목록 등) |
|
||||
| Barobill SOAP API | 은행 거래 실시간 연동 |
|
||||
| MySQL 8.0 | 데이터 저장 |
|
||||
|
||||
## 데이터 흐름
|
||||
|
||||
```
|
||||
바로빌 SOAP API ──→ barobill_bank_transactions ──→ 계좌입출금내역
|
||||
──→ 일일자금일보
|
||||
──→ 재무 대시보드
|
||||
|
||||
사용자 입력 ──→ bank_accounts ──→ 보유계좌관리
|
||||
──→ 재무 대시보드
|
||||
|
||||
사용자 입력 ──→ fund_schedules ──→ 자금계획일정
|
||||
──→ 재무 대시보드
|
||||
```
|
||||
|
||||
## 공통 모델
|
||||
|
||||
| 모델 | 테이블 | 역할 |
|
||||
|------|--------|------|
|
||||
| `Finance\BankAccount` | `bank_accounts` | 보유 계좌 정보 |
|
||||
| `Finance\FundSchedule` | `fund_schedules` | 자금 일정 |
|
||||
| `Finance\DailyFundTransaction` | `daily_fund_transactions` | 일일자금 거래 |
|
||||
| `Finance\DailyFundMemo` | `daily_fund_memos` | 일일자금 메모 |
|
||||
| `Barobill\BankTransaction` | `barobill_bank_transactions` | 바로빌 거래내역 |
|
||||
| `Barobill\BankTransactionOverride` | `barobill_bank_transaction_overrides` | 거래 수정 |
|
||||
| `Barobill\BankTransactionSplit` | `barobill_bank_transaction_splits` | 거래 분개 |
|
||||
| `Barobill\AccountCode` | `account_codes` | 계정과목 |
|
||||
|
||||
## 서비스 클래스
|
||||
|
||||
| 서비스 | 파일 | 주요 역할 |
|
||||
|--------|------|----------|
|
||||
| `BankAccountService` | `app/Services/BankAccountService.php` | 계좌 CRUD, 통계, 바로빌 연동 |
|
||||
| `FundScheduleService` | `app/Services/FundScheduleService.php` | 일정 CRUD, 캘린더, 월별 요약 |
|
||||
| `FcmApiService` | `app/Services/FcmApiService.php` | FCM 푸시 발송 (간접 관련) |
|
||||
339
features/finance/account-transactions.md
Normal file
339
features/finance/account-transactions.md
Normal file
@@ -0,0 +1,339 @@
|
||||
# 계좌입출금내역
|
||||
|
||||
## 개요
|
||||
|
||||
계좌입출금내역은 바로빌 SOAP API를 통해 은행 거래내역을 실시간으로 조회하고,
|
||||
회계 분류(계정과목 지정), 분개(1거래→N계정과목), 수동 거래 등록 등을 지원하는 기능입니다.
|
||||
|
||||
- **라우트**: `GET /finance/account-transactions`
|
||||
- **UI 기술**: React 18 + Babel (브라우저 트랜스파일링)
|
||||
- **컨트롤러**: `EaccountController` (1,772줄)
|
||||
|
||||
## 파일 구조
|
||||
|
||||
```
|
||||
mng/
|
||||
├── app/Http/Controllers/Barobill/
|
||||
│ └── EaccountController.php # 메인 컨트롤러 (1772줄, 16개+ 메서드)
|
||||
├── app/Models/Barobill/
|
||||
│ ├── BankTransaction.php # 바로빌 거래내역 모델
|
||||
│ ├── BankTransactionOverride.php # 거래 수정(적요/내용)
|
||||
│ ├── BankTransactionSplit.php # 거래 분개
|
||||
│ ├── AccountCode.php # 계정과목 마스터
|
||||
│ ├── BarobillConfig.php # 바로빌 API 설정
|
||||
│ └── BarobillMember.php # 테넌트별 바로빌 연동 정보
|
||||
└── resources/views/barobill/eaccount/
|
||||
└── index.blade.php # React 기반 단일 페이지
|
||||
```
|
||||
|
||||
## 라우트
|
||||
|
||||
### 웹 라우트
|
||||
|
||||
```php
|
||||
// routes/web.php
|
||||
Route::get('/finance/account-transactions', [EaccountController::class, 'index']);
|
||||
```
|
||||
|
||||
### API 라우트
|
||||
|
||||
```php
|
||||
// routes/web.php (barobill/eaccount prefix)
|
||||
GET /accounts → 등록된 계좌 목록 (바로빌)
|
||||
GET /latest-balances → 계좌별 최신 잔액 (DB)
|
||||
GET /transactions → 거래내역 조회 (API + DB 병합)
|
||||
GET /account-codes → 계정과목 목록 (테넌트별)
|
||||
GET /account-codes/all → 전체 계정과목
|
||||
POST /account-codes → 계정과목 등록
|
||||
PUT /account-codes/{id} → 계정과목 수정
|
||||
DELETE /account-codes/{id} → 계정과목 삭제
|
||||
POST /save → 거래 저장 (회계 분류)
|
||||
GET /export → Excel 내보내기
|
||||
POST /save-override → 거래 적요/내용 수정
|
||||
POST /manual → 수동 거래 등록
|
||||
PUT /manual/{id} → 수동 거래 수정
|
||||
DELETE /manual/{id} → 수동 거래 삭제
|
||||
GET /splits → 분개 내역 조회
|
||||
POST /splits → 분개 저장
|
||||
DELETE /splits → 분개 삭제
|
||||
```
|
||||
|
||||
## 컨트롤러
|
||||
|
||||
### EaccountController
|
||||
|
||||
| 메서드 | HTTP | 설명 |
|
||||
|--------|------|------|
|
||||
| `__construct()` | - | SOAP 클라이언트 초기화 (BarobillConfig) |
|
||||
| `index()` | GET | React 페이지 렌더링 (HX-Redirect 적용) |
|
||||
| `accounts()` | GET | 바로빌 등록 계좌 목록 |
|
||||
| `latestBalances()` | GET | DB 기반 최신 잔액 |
|
||||
| `transactions()` | GET | **거래내역 조회** (API + DB 병합) |
|
||||
| `accountCodes()` | GET | 계정과목 목록 |
|
||||
| `accountCodesAll()` | GET | 전체 계정과목 |
|
||||
| `accountCodeStore()` | POST | 계정과목 등록 |
|
||||
| `accountCodeUpdate()` | PUT | 계정과목 수정 |
|
||||
| `accountCodeDestroy()` | DELETE | 계정과목 삭제 |
|
||||
| `save()` | POST | 거래 저장 (계정과목 지정) |
|
||||
| `exportExcel()` | GET | Excel 내보내기 |
|
||||
| `saveOverride()` | POST | 적요/내용 수정 (override) |
|
||||
| `storeManual()` | POST | 수동 거래 등록 |
|
||||
| `updateManual()` | PUT | 수동 거래 수정 |
|
||||
| `destroyManual()` | DELETE | 수동 거래 삭제 |
|
||||
| `splits()` | GET | 분개 내역 조회 |
|
||||
| `saveSplits()` | POST | 분개 저장 |
|
||||
| `deleteSplits()` | DELETE | 분개 삭제 |
|
||||
|
||||
## 바로빌 SOAP API 연동
|
||||
|
||||
### 설정 구조
|
||||
|
||||
```
|
||||
BarobillConfig (barobill_configs 테이블)
|
||||
├─ environment: 'test' 또는 'production'
|
||||
├─ cert_key: 인증서 키
|
||||
├─ corp_num: 법인번호
|
||||
└─ base_url: SOAP URL
|
||||
|
||||
BarobillMember (barobill_members 테이블)
|
||||
├─ tenant_id: 테넌트별 분리
|
||||
├─ barobill_id: 바로빌 로그인 ID
|
||||
├─ barobill_pwd: 암호화된 비밀번호
|
||||
└─ server_mode: 'test' 또는 'production' (테넌트별)
|
||||
```
|
||||
|
||||
### 사용 SOAP 메서드
|
||||
|
||||
| WSDL | 메서드 | 기능 |
|
||||
|------|--------|------|
|
||||
| BANKACCOUNT.asmx | `GetBankAccountEx` | 등록된 계좌 목록 |
|
||||
| BANKACCOUNT.asmx | `GetPeriodBankAccountTransLog` | 기간별 거래내역 조회 |
|
||||
|
||||
### 에러 코드
|
||||
|
||||
| 코드 | 의미 |
|
||||
|------|------|
|
||||
| `-25005` | 데이터 없음 (정상) |
|
||||
| `-25001` | 데이터 없음 (정상) |
|
||||
| 기타 | 에러 메시지 반환 |
|
||||
|
||||
## 핵심 로직
|
||||
|
||||
### 거래내역 조회 흐름 (transactions)
|
||||
|
||||
```
|
||||
React 컴포넌트 (날짜/계좌 선택)
|
||||
↓
|
||||
GET /barobill/eaccount/transactions
|
||||
↓
|
||||
1. BarobillMember 조회 (barobill_id)
|
||||
↓
|
||||
2. 테넌트별 서버 모드 적용
|
||||
└─ BarobillConfig 재로드 → SOAP 클라이언트 재초기화
|
||||
↓
|
||||
3. [단일 계좌 조회]
|
||||
├─ DB 조회: barobill_bank_transactions (저장된 데이터)
|
||||
├─ SOAP 호출: GetPeriodBankAccountTransLog
|
||||
├─ Override 데이터 병합 (수정된 적요)
|
||||
├─ 수동 거래 병합 (중복 제거)
|
||||
├─ 분개 데이터 병합
|
||||
├─ 잔액 재계산 (기간 전 잔액 기준)
|
||||
└─ 정렬 (최신순) + 페이지네이션
|
||||
↓
|
||||
4. [전체 계좌 조회]
|
||||
├─ GetBankAccountEx로 계좌 목록 조회
|
||||
├─ 각 계좌별로 3번 반복
|
||||
└─ 모든 거래 병합 및 정렬
|
||||
↓
|
||||
5. JSON 응답
|
||||
```
|
||||
|
||||
### 거래 고유 키 (unique_key)
|
||||
|
||||
```php
|
||||
// BankTransaction 모델
|
||||
return implode('|', [
|
||||
$this->bank_account_num,
|
||||
$this->trans_dt, // 거래일시
|
||||
(int) $this->deposit,
|
||||
(int) $this->withdraw,
|
||||
(int) $this->balance,
|
||||
]);
|
||||
```
|
||||
|
||||
### 분개 저장 흐름
|
||||
|
||||
```
|
||||
React (분개 모달)
|
||||
↓
|
||||
POST /barobill/eaccount/splits
|
||||
{
|
||||
originalUniqueKey: "계좌번호|거래일시|입금|출금|잔액",
|
||||
originalData: { bankAccountNum, transDate, ... },
|
||||
splits: [
|
||||
{ amount: 50000, accountCode: "1000", accountName: "당좌예금" },
|
||||
{ amount: 50000, accountCode: "2000", accountName: "미수금" }
|
||||
]
|
||||
}
|
||||
↓
|
||||
기존 분개 삭제 → 새 분개 생성 × N
|
||||
```
|
||||
|
||||
### Override 저장 로직
|
||||
|
||||
```
|
||||
POST /barobill/eaccount/save-override
|
||||
{
|
||||
uniqueKey: "거래 고유 키",
|
||||
modifiedSummary: "수정된 적요",
|
||||
modifiedCast: "수정된 내용"
|
||||
}
|
||||
↓
|
||||
BankTransactionOverride::saveOverride()
|
||||
→ 둘 다 null이면 delete
|
||||
→ 아니면 upsert
|
||||
```
|
||||
|
||||
## 모델
|
||||
|
||||
### BankTransaction (Barobill)
|
||||
|
||||
**테이블**: `barobill_bank_transactions`
|
||||
|
||||
| 필드 | 설명 |
|
||||
|------|------|
|
||||
| `tenant_id` | 테넌트 ID |
|
||||
| `bank_account_num` | 계좌번호 (하이픈 없음) |
|
||||
| `bank_code` / `bank_name` | 은행 코드/명 |
|
||||
| `trans_date` | 거래일 (YYYYMMDD) |
|
||||
| `trans_time` | 거래시간 (HHMMSS) |
|
||||
| `trans_dt` | 거래일시 (trans_date + trans_time) |
|
||||
| `deposit` / `withdraw` | 입금액 / 출금액 |
|
||||
| `balance` | 거래 후 잔액 |
|
||||
| `summary` / `cast` | 적요 / 내용 |
|
||||
| `account_code` / `account_name` | 계정과목 코드/명 |
|
||||
| `is_manual` | 수동 입력 여부 |
|
||||
|
||||
### BankTransactionOverride
|
||||
|
||||
**테이블**: `barobill_bank_transaction_overrides`
|
||||
|
||||
| 필드 | 설명 |
|
||||
|------|------|
|
||||
| `unique_key` | 거래 고유 키 |
|
||||
| `modified_summary` | 수정된 적요 |
|
||||
| `modified_cast` | 수정된 내용 |
|
||||
|
||||
### BankTransactionSplit
|
||||
|
||||
**테이블**: `barobill_bank_transaction_splits`
|
||||
|
||||
| 필드 | 설명 |
|
||||
|------|------|
|
||||
| `original_unique_key` | 원본 거래 고유 키 |
|
||||
| `split_amount` | 분개 금액 |
|
||||
| `account_code` / `account_name` | 계정과목 |
|
||||
| `description` / `memo` | 설명 / 메모 |
|
||||
| `sort_order` | 정렬 순서 |
|
||||
| `bank_account_num` / `trans_dt` / `trans_date` | 원본 거래 정보 |
|
||||
| `original_deposit` / `original_withdraw` | 원본 금액 |
|
||||
|
||||
### AccountCode
|
||||
|
||||
**테이블**: `account_codes`
|
||||
|
||||
| 필드 | 설명 |
|
||||
|------|------|
|
||||
| `code` | 계정과목 코드 (예: "1000") |
|
||||
| `name` | 계정과목명 (예: "당좌예금") |
|
||||
| `category` | 분류 (자산, 부채, 자본 등) |
|
||||
| `sort_order` | 정렬 순서 |
|
||||
| `is_active` | 활성 여부 |
|
||||
|
||||
### BarobillConfig
|
||||
|
||||
**테이블**: `barobill_configs`
|
||||
|
||||
| 필드 | 설명 |
|
||||
|------|------|
|
||||
| `name` | 설정명 |
|
||||
| `environment` | 'test' 또는 'production' |
|
||||
| `cert_key` | 바로빌 인증서 키 |
|
||||
| `corp_num` | 법인번호 |
|
||||
| `is_active` | 활성 여부 |
|
||||
|
||||
### BarobillMember
|
||||
|
||||
**테이블**: `barobill_members`
|
||||
|
||||
| 필드 | 설명 |
|
||||
|------|------|
|
||||
| `tenant_id` | 테넌트 ID |
|
||||
| `biz_no` | 사업자번호 |
|
||||
| `barobill_id` / `barobill_pwd` | 바로빌 로그인 정보 |
|
||||
| `server_mode` | 'test' 또는 'production' |
|
||||
| `status` | active / inactive / pending |
|
||||
|
||||
## 뷰 구성 (React)
|
||||
|
||||
### index.blade.php
|
||||
|
||||
```
|
||||
┌─ 테넌트 정보 카드 (Blade) ──────────
|
||||
│ 회사명, 사업자번호, 바로빌 ID
|
||||
│ 바로빌 미연동 경고 (조건부)
|
||||
│
|
||||
├─ React 앱 (#eaccount-root) ─────────
|
||||
│ ├─ 계좌 선택 드롭다운
|
||||
│ ├─ 기간 선택 (이번달, 지난달, D-2~5월 버튼)
|
||||
│ │
|
||||
│ ├─ 통계 카드 ──────────
|
||||
│ │ 총 입금 | 총 출금 | 거래 건수
|
||||
│ │
|
||||
│ ├─ 거래 테이블 ────────
|
||||
│ │ 번호 | 거래일시 | 적요 | 입금 | 출금 | 잔액 | 계정과목
|
||||
│ │ ├─ 인라인 편집 (적요, 계정과목)
|
||||
│ │ ├─ 수동 거래: 보라색 표시
|
||||
│ │ ├─ 숨긴 거래: 회색 처리
|
||||
│ │ └─ 분개된 거래: 파란색 표시
|
||||
│ │
|
||||
│ ├─ 수동 거래 등록 모달 ──
|
||||
│ │ 날짜, 시간, 입금/출금, 금액, 적요, 계정과목
|
||||
│ │
|
||||
│ ├─ 분개 모달 ──────────
|
||||
│ │ 원본 거래 정보 → N개 분개 항목
|
||||
│ │
|
||||
│ └─ 내보내기/저장 버튼
|
||||
│
|
||||
└─ API 엔드포인트 상수 (Blade에서 정의)
|
||||
```
|
||||
|
||||
### React 주요 기능
|
||||
|
||||
| 기능 | 설명 |
|
||||
|------|------|
|
||||
| 계좌별 조회 | 드롭다운에서 계좌 선택 |
|
||||
| 기간 선택 | 월 단위 버튼 (이번달 ~ D-5월) |
|
||||
| 인라인 편집 | 적요, 계정과목 직접 수정 |
|
||||
| 분개 | 1거래 → N계정과목 분할 |
|
||||
| 수동 입력 | API 미제공 거래 추가 |
|
||||
| 거래 숨김 | 특정 거래 숨기기/복원 |
|
||||
| Excel 내보내기 | 조회 데이터 다운로드 |
|
||||
| 잔액 재계산 | 기간 전 잔액 기준 자동 계산 |
|
||||
|
||||
## 데이터베이스 테이블 요약
|
||||
|
||||
| 테이블 | 역할 | 마이그레이션 (API) |
|
||||
|--------|------|-------------------|
|
||||
| `barobill_bank_transactions` | 거래내역 저장 | `2026_01_23_130000_...` |
|
||||
| `barobill_bank_transaction_overrides` | 적요/내용 수정 | `2026_02_06_095159_...` |
|
||||
| `barobill_bank_transaction_splits` | 분개 데이터 | `2026_02_06_200000_...` |
|
||||
| `account_codes` | 계정과목 마스터 | - |
|
||||
| `barobill_members` | 테넌트별 연동 정보 | - |
|
||||
| `barobill_configs` | API 설정 (환경별) | - |
|
||||
|
||||
## HTMX 호환성
|
||||
|
||||
- React 기반 페이지이므로 **HX-Redirect 필요**
|
||||
- `@push('scripts')` 블록에 React/Babel 스크립트 포함
|
||||
- HTMX 네비게이션 시 전체 페이지 리로드 필수
|
||||
254
features/finance/bank-accounts.md
Normal file
254
features/finance/bank-accounts.md
Normal file
@@ -0,0 +1,254 @@
|
||||
# 보유계좌관리
|
||||
|
||||
## 개요
|
||||
|
||||
보유계좌관리는 회사의 은행계좌 정보를 중앙 집중식으로 관리하는 기능입니다.
|
||||
계좌 등록/수정/삭제, 잔액 조회, 바로빌 연동 최신 잔액 업데이트를 지원합니다.
|
||||
|
||||
- **라우트**: `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로 처리
|
||||
201
features/finance/daily-fund-report.md
Normal file
201
features/finance/daily-fund-report.md
Normal file
@@ -0,0 +1,201 @@
|
||||
# 일일자금일보
|
||||
|
||||
## 개요
|
||||
|
||||
일일자금일보는 기간별 계좌 입출금 현황을 조회하고 일별 보고서를 생성하는 기능입니다.
|
||||
바로빌에서 수집된 은행 거래 데이터를 기반으로 날짜별, 계좌별 입출금 집계를 제공합니다.
|
||||
|
||||
- **라우트**: `GET /finance/daily-fund`
|
||||
- **UI 기술**: React 18 + Babel (브라우저 트랜스파일링)
|
||||
|
||||
## 파일 구조
|
||||
|
||||
```
|
||||
mng/
|
||||
├── app/Http/Controllers/Finance/
|
||||
│ └── DailyFundController.php # 메인 컨트롤러 (6개 메서드)
|
||||
├── app/Models/Finance/
|
||||
│ ├── DailyFundTransaction.php # 수동 거래내역 모델
|
||||
│ └── DailyFundMemo.php # 일별 메모 모델
|
||||
├── app/Models/Barobill/
|
||||
│ ├── BankTransaction.php # 바로빌 거래내역 모델
|
||||
│ └── BankTransactionOverride.php # 거래 수정 이력
|
||||
└── resources/views/finance/
|
||||
└── daily-fund.blade.php # React 기반 UI
|
||||
```
|
||||
|
||||
## 라우트
|
||||
|
||||
```php
|
||||
// routes/web.php (finance prefix 그룹 내)
|
||||
Route::get('/daily-fund', [DailyFundController::class, 'index'])->name('daily-fund');
|
||||
|
||||
// API 엔드포인트 (동일 컨트롤러)
|
||||
Route::get('/daily-fund/period-report', [DailyFundController::class, 'periodReport']);
|
||||
Route::post('/daily-fund', [DailyFundController::class, 'store']);
|
||||
Route::put('/daily-fund/{id}', [DailyFundController::class, 'update']);
|
||||
Route::delete('/daily-fund/{id}', [DailyFundController::class, 'destroy']);
|
||||
Route::post('/daily-fund/memo', [DailyFundController::class, 'saveMemo']);
|
||||
```
|
||||
|
||||
## 컨트롤러
|
||||
|
||||
### DailyFundController
|
||||
|
||||
| 메서드 | HTTP | 설명 |
|
||||
|--------|------|------|
|
||||
| `index()` | GET | 특정 날짜 거래내역 조회 |
|
||||
| `store()` | POST | 거래내역 수동 등록 |
|
||||
| `update()` | PUT | 거래내역 수정 |
|
||||
| `destroy()` | DELETE | 거래내역 삭제 |
|
||||
| `saveMemo()` | POST | 일별 메모 저장 |
|
||||
| `periodReport()` | GET | **기간별 일일자금일보** (핵심) |
|
||||
|
||||
### periodReport() 핵심 로직
|
||||
|
||||
```
|
||||
QueryString: start_date, end_date (YYYYMMDD)
|
||||
↓
|
||||
BarobillBankTransaction 조회 (trans_date 범위)
|
||||
↓
|
||||
BankTransactionOverride 병합 (수정된 적요/내용)
|
||||
↓
|
||||
unique_key 기준 중복 제거
|
||||
↓
|
||||
날짜별 그룹핑 + 계좌별 입출금 집계
|
||||
↓
|
||||
JSON 응답
|
||||
```
|
||||
|
||||
**응답 구조**:
|
||||
```json
|
||||
{
|
||||
"dailyReports": [
|
||||
{
|
||||
"date": "20260211",
|
||||
"dateFormatted": "2026년 2월 11일 수요일",
|
||||
"accounts": [
|
||||
{ "bankName": "우리은행", "accountNum": "1002-xxx", "deposit": 5000000, "withdraw": 1000000, "balance": 50000000 }
|
||||
],
|
||||
"deposits": [
|
||||
{ "time": "0930", "bankName": "우리은행", "summary": "급여입금", "cast": "본사", "amount": 5000000, "balance": 50000000 }
|
||||
],
|
||||
"withdrawals": [ ... ],
|
||||
"totalDeposit": 5000000,
|
||||
"totalWithdraw": 1000000
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 뷰 구성 (React)
|
||||
|
||||
### daily-fund.blade.php
|
||||
|
||||
```
|
||||
┌─ 기간 선택 컴포넌트 ────────────
|
||||
│ 날짜 입력 (start_date ~ end_date)
|
||||
│ 월별 단축키 (이번달, 지난달 등)
|
||||
│
|
||||
├─ 일별 보고서 반복 렌더링 ────────
|
||||
│ ┌─ 날짜 헤더 ──────────
|
||||
│ │ 2026년 2월 11일 수요일
|
||||
│ │
|
||||
│ ├─ 계좌별 요약 테이블 ──
|
||||
│ │ 은행명 | 계좌번호 | 입금 | 출금 | 잔액
|
||||
│ │
|
||||
│ ├─ 입금 상세 내역 ─────
|
||||
│ │ 시간 | 은행 | 적요 | 내용 | 금액 | 잔액
|
||||
│ │
|
||||
│ └─ 출금 상세 내역 ─────
|
||||
│ 시간 | 은행 | 적요 | 내용 | 금액 | 잔액
|
||||
│
|
||||
└─ 인쇄 버튼
|
||||
```
|
||||
|
||||
## 데이터 흐름
|
||||
|
||||
```
|
||||
React Component (기간 선택)
|
||||
↓ fetch GET /finance/daily-fund/period-report
|
||||
DailyFundController::periodReport()
|
||||
↓
|
||||
BarobillBankTransaction 조회
|
||||
↓ (trans_date 범위 필터)
|
||||
BankTransactionOverride 병합
|
||||
↓ (수정된 적요/내용 덮어쓰기)
|
||||
unique_key 기준 중복 제거
|
||||
↓
|
||||
날짜별 + 계좌별 그룹핑
|
||||
↓ (입금/출금 분류, 계좌별 집계)
|
||||
JSON 응답
|
||||
↓
|
||||
React 렌더링 (테이블, 통계)
|
||||
```
|
||||
|
||||
## 데이터베이스 테이블
|
||||
|
||||
### barobill_bank_transactions (주 데이터)
|
||||
|
||||
| 컬럼 | 타입 | 설명 |
|
||||
|------|------|------|
|
||||
| `tenant_id` | bigint | 테넌트 ID |
|
||||
| `bank_account_num` | string | 계좌번호 |
|
||||
| `bank_name` | string | 은행명 |
|
||||
| `trans_date` | string | 거래일 (YYYYMMDD) |
|
||||
| `trans_time` | string | 거래시간 (HHMM) |
|
||||
| `deposit` | decimal | 입금액 |
|
||||
| `withdraw` | decimal | 출금액 |
|
||||
| `balance` | decimal | 거래 후 잔액 |
|
||||
| `summary` | string | 적요 |
|
||||
| `cast` | string | 내용 |
|
||||
|
||||
### daily_fund_transactions (수동 입력)
|
||||
|
||||
| 컬럼 | 타입 | 설명 |
|
||||
|------|------|------|
|
||||
| `tenant_id` | bigint | 테넌트 ID |
|
||||
| `transaction_date` | date | 거래일 |
|
||||
| `type` | enum | income / expense |
|
||||
| `amount` | decimal | 금액 |
|
||||
| `description` | string | 설명 |
|
||||
|
||||
### daily_fund_memos
|
||||
|
||||
| 컬럼 | 타입 | 설명 |
|
||||
|------|------|------|
|
||||
| `tenant_id` | bigint | 테넌트 ID |
|
||||
| `memo_date` | date | 메모 날짜 |
|
||||
| `memo` | text | 메모 내용 |
|
||||
| `author` | string | 작성자 |
|
||||
|
||||
## 핵심 로직
|
||||
|
||||
### 거래 중복 제거
|
||||
|
||||
```php
|
||||
->unique(fn($tx) => $tx->unique_key)
|
||||
// unique_key = bank_account_num|trans_dt|deposit|withdraw|balance
|
||||
```
|
||||
|
||||
### 오버라이드 병합
|
||||
|
||||
```php
|
||||
BankTransactionOverride::getByUniqueKeys($keys)
|
||||
// → modified_summary, modified_cast로 원본 적요/내용 덮어쓰기
|
||||
// → is_overridden 플래그 설정
|
||||
```
|
||||
|
||||
### 일별 집계
|
||||
|
||||
```
|
||||
거래 목록 → trans_date 기준 그룹핑
|
||||
→ 각 날짜: 계좌별 분류
|
||||
→ 입금 합계, 출금 합계 계산
|
||||
→ 최종 잔액: DESC 정렬 첫 거래의 balance 값
|
||||
```
|
||||
|
||||
## HTMX 호환성
|
||||
|
||||
- React 기반 페이지이므로 HX-Redirect 필요
|
||||
- `@push('scripts')` 블록에 React/Babel 스크립트 포함
|
||||
190
features/finance/finance-dashboard.md
Normal file
190
features/finance/finance-dashboard.md
Normal file
@@ -0,0 +1,190 @@
|
||||
# 재무 대시보드
|
||||
|
||||
## 개요
|
||||
|
||||
재무 대시보드는 회사의 자금 현황을 한눈에 파악할 수 있는 종합 화면입니다.
|
||||
총 잔액, 예정 수입/지출, 최근 거래내역, 계좌별 잔액 등을 요약하여 표시합니다.
|
||||
|
||||
- **라우트**: `GET /finance/dashboard`
|
||||
- **라우트 이름**: `finance.dashboard`
|
||||
- **UI 기술**: Blade + JavaScript (HTMX 불필요)
|
||||
|
||||
## 파일 구조
|
||||
|
||||
```
|
||||
mng/
|
||||
├── app/Http/Controllers/Finance/
|
||||
│ └── FinanceDashboardController.php # 메인 컨트롤러
|
||||
├── app/Services/
|
||||
│ ├── BankAccountService.php # 계좌 데이터 서비스
|
||||
│ └── FundScheduleService.php # 자금일정 데이터 서비스
|
||||
├── app/Models/
|
||||
│ ├── Finance/
|
||||
│ │ ├── BankAccount.php # 계좌 모델
|
||||
│ │ └── FundSchedule.php # 자금일정 모델
|
||||
│ └── Barobill/
|
||||
│ ├── BankTransaction.php # 바로빌 거래내역
|
||||
│ ├── BankTransactionOverride.php # 거래 수정 이력
|
||||
│ └── CardTransaction.php # 바로빌 카드거래
|
||||
└── resources/views/finance/
|
||||
└── dashboard.blade.php # 메인 뷰
|
||||
```
|
||||
|
||||
## 라우트
|
||||
|
||||
```php
|
||||
// routes/web.php (finance prefix 그룹 내)
|
||||
Route::get('/dashboard', [FinanceDashboardController::class, 'index'])->name('dashboard');
|
||||
```
|
||||
|
||||
## 컨트롤러
|
||||
|
||||
### FinanceDashboardController
|
||||
|
||||
| 메서드 | HTTP | 반환 | 설명 |
|
||||
|--------|------|------|------|
|
||||
| `index()` | GET | View | 대시보드 메인 페이지 |
|
||||
|
||||
### index() 데이터 수집
|
||||
|
||||
```php
|
||||
public function index(): View
|
||||
{
|
||||
// 1. 계좌 요약 (총 잔액, 계좌 수)
|
||||
$accountSummary = $this->bankAccountService->getSummary();
|
||||
|
||||
// 2. 자금일정 요약 (7일 내 일정 건수)
|
||||
$scheduleSummary = $this->fundScheduleService->getSummary();
|
||||
|
||||
// 3. 이번 달 수입/지출 요약
|
||||
$monthlySummary = $this->fundScheduleService->getMonthlySummary($year, $month);
|
||||
|
||||
// 4. 향후 7일 자금 일정
|
||||
$upcomingSchedules = $this->fundScheduleService->getUpcomingSchedules(7);
|
||||
|
||||
// 5. 최근 7일 은행 거래내역 (최대 10건)
|
||||
$recentTransactions = BarobillBankTransaction::where(...)
|
||||
->limit(10)->get();
|
||||
|
||||
// 6. 최근 7일 카드 사용내역 (최대 10건)
|
||||
$recentCardTransactions = BarobillCardTransaction::where(...)
|
||||
->limit(10)->get();
|
||||
|
||||
// 7. 활성 계좌 잔액 목록
|
||||
$accountBalances = BankAccount::active()->ordered()->get();
|
||||
}
|
||||
```
|
||||
|
||||
## 뷰 구성
|
||||
|
||||
### dashboard.blade.php
|
||||
|
||||
| 섹션 | 내용 | 데이터 소스 |
|
||||
|------|------|------------|
|
||||
| 페이지 헤더 | 제목 + 현재 날짜 + 네비게이션 버튼 | - |
|
||||
| 요약 카드 (4개) | 총 잔액 / 예정 수입 / 예정 지출 / 7일내 일정 | `accountSummary`, `monthlySummary`, `scheduleSummary` |
|
||||
| 월별 자금 일정 요약 | 수입/지출/순수익 (완료/예정 분리) | `monthlySummary` |
|
||||
| 계좌별 잔액 패널 | 활성 계좌 목록 + 잔액 | `accountBalances` |
|
||||
| 향후 7일 자금 일정 | 예정 일정 (수입/지출 색상 구분) | `upcomingSchedules` |
|
||||
| 최근 거래내역 | 7일 은행 거래내역 테이블 | `recentTransactions` |
|
||||
| 최근 카드 사용내역 | 7일 카드 거래 테이블 | `recentCardTransactions` |
|
||||
|
||||
### JavaScript 기능
|
||||
|
||||
```javascript
|
||||
// 계좌 잔액 실시간 새로고침
|
||||
function refreshAccountBalances() {
|
||||
// GET /barobill/eaccount/latest-balances
|
||||
// → 바로빌 DB에서 최신 잔액 조회
|
||||
// → DOM 업데이트 (잔액 수치 변경)
|
||||
// → 로딩/완료 상태 피드백
|
||||
}
|
||||
```
|
||||
|
||||
## 데이터 흐름
|
||||
|
||||
```
|
||||
FinanceDashboardController::index()
|
||||
│
|
||||
├─ BankAccountService::getSummary()
|
||||
│ └─ bank_accounts (총 계좌 수, 총 잔액, 은행별 그룹)
|
||||
│
|
||||
├─ FundScheduleService::getSummary()
|
||||
│ └─ fund_schedules (예정 건수, 예정 수입/지출)
|
||||
│
|
||||
├─ FundScheduleService::getMonthlySummary()
|
||||
│ └─ fund_schedules (월별 수입/지출, 완료/예정 분리)
|
||||
│
|
||||
├─ FundScheduleService::getUpcomingSchedules(7)
|
||||
│ └─ fund_schedules (향후 7일 예정 일정)
|
||||
│
|
||||
├─ BarobillBankTransaction 조회
|
||||
│ └─ barobill_bank_transactions (최근 7일, 10건)
|
||||
│ └─ BankTransactionOverride 병합 (수정된 적요)
|
||||
│
|
||||
├─ BarobillCardTransaction 조회
|
||||
│ └─ barobill_card_transactions (최근 7일, 10건)
|
||||
│
|
||||
└─ BankAccount::active()->ordered()
|
||||
└─ bank_accounts (계좌별 잔액)
|
||||
```
|
||||
|
||||
## 서비스 반환 구조
|
||||
|
||||
### BankAccountService::getSummary()
|
||||
|
||||
```php
|
||||
[
|
||||
'total_accounts' => int, // 활성 계좌 수
|
||||
'total_balance' => float, // 총 잔액
|
||||
'formatted_total_balance' => str, // "1,000,000원"
|
||||
'by_bank' => [ // 은행별 상세
|
||||
'bank_name' => ['count' => int, 'total' => float]
|
||||
]
|
||||
]
|
||||
```
|
||||
|
||||
### FundScheduleService::getSummary()
|
||||
|
||||
```php
|
||||
[
|
||||
'pending_count' => int, // 예정 건수
|
||||
'pending_income' => float, // 예정 수입
|
||||
'pending_expense' => float, // 예정 지출
|
||||
'upcoming_7days' => int // 7일 내 일정 건수
|
||||
]
|
||||
```
|
||||
|
||||
### FundScheduleService::getMonthlySummary()
|
||||
|
||||
```php
|
||||
[
|
||||
'year' => int, 'month' => int,
|
||||
'total_count' => int,
|
||||
'income' => [
|
||||
'count' => int, 'total' => float,
|
||||
'pending' => float, 'completed' => float
|
||||
],
|
||||
'expense' => [
|
||||
'count' => int, 'total' => float,
|
||||
'pending' => float, 'completed' => float
|
||||
],
|
||||
'net' => float // 순수익 (수입 - 지출)
|
||||
]
|
||||
```
|
||||
|
||||
## 관련 데이터베이스 테이블
|
||||
|
||||
| 테이블 | 용도 |
|
||||
|--------|------|
|
||||
| `bank_accounts` | 계좌 잔액, 계좌 수 통계 |
|
||||
| `fund_schedules` | 자금 일정 요약, 예정 수입/지출 |
|
||||
| `barobill_bank_transactions` | 최근 은행 거래내역 |
|
||||
| `barobill_card_transactions` | 최근 카드 사용내역 |
|
||||
| `barobill_bank_transaction_overrides` | 거래 수정 이력 병합 |
|
||||
|
||||
## HTMX 호환성
|
||||
|
||||
- 순수 Blade 템플릿 (복잡한 JavaScript 없음)
|
||||
- HX-Redirect 불필요
|
||||
- JavaScript는 `refreshAccountBalances()` 함수만 포함
|
||||
235
features/finance/fund-schedules.md
Normal file
235
features/finance/fund-schedules.md
Normal file
@@ -0,0 +1,235 @@
|
||||
# 자금계획일정
|
||||
|
||||
## 개요
|
||||
|
||||
자금계획일정은 입금 예정/지급 예정 일정을 등록, 관리하고 월별 캘린더 뷰로 확인하는 기능입니다.
|
||||
반복 일정, 월별 복사, 상태 관리(예정/완료/취소) 기능을 지원합니다.
|
||||
|
||||
- **라우트**: `GET /finance/fund-schedules`
|
||||
- **라우트 이름**: `finance.fund-schedules.index`
|
||||
- **UI 기술**: Blade 템플릿
|
||||
|
||||
## 파일 구조
|
||||
|
||||
```
|
||||
mng/
|
||||
├── app/Http/Controllers/
|
||||
│ ├── Finance/
|
||||
│ │ └── FundScheduleController.php # 웹 컨트롤러 (5개 메서드)
|
||||
│ └── Api/Admin/
|
||||
│ └── FundScheduleController.php # API 컨트롤러
|
||||
├── app/Services/
|
||||
│ └── FundScheduleService.php # 비즈니스 로직 (13개+ 공개 메서드)
|
||||
├── app/Models/Finance/
|
||||
│ └── FundSchedule.php # ORM 모델
|
||||
└── resources/views/finance/fund-schedules/
|
||||
├── index.blade.php # 캘린더 뷰
|
||||
├── create.blade.php # 등록 폼
|
||||
├── edit.blade.php # 수정 폼
|
||||
└── show.blade.php # 상세보기
|
||||
```
|
||||
|
||||
## 라우트
|
||||
|
||||
### 웹 라우트
|
||||
|
||||
```php
|
||||
// routes/web.php (finance prefix 그룹 내)
|
||||
Route::get('/fund-schedules', [FundScheduleController::class, 'index'])->name('fund-schedules.index');
|
||||
Route::get('/fund-schedules/create', [..., 'create'])->name('fund-schedules.create');
|
||||
Route::get('/fund-schedules/{id}', [..., 'show'])->name('fund-schedules.show');
|
||||
Route::get('/fund-schedules/{id}/edit', [..., 'edit'])->name('fund-schedules.edit');
|
||||
|
||||
// 호환성 리다이렉트
|
||||
Route::get('/fund-schedule', fn() => redirect()->route('finance.fund-schedules.index'));
|
||||
```
|
||||
|
||||
### API 라우트
|
||||
|
||||
```php
|
||||
// routes/api.php (admin/fund-schedules prefix)
|
||||
GET / → index() 목록 (페이지네이션)
|
||||
GET /calendar → calendar() 월별 캘린더 데이터
|
||||
GET /summary → summary() 요약 통계
|
||||
GET /upcoming → upcoming() 예정 일정
|
||||
POST /copy → copy() 월별 일정 복사
|
||||
GET /{id} → show() 상세 조회
|
||||
POST / → store() 생성
|
||||
PUT /{id} → update() 수정
|
||||
DELETE /{id} → destroy() 삭제
|
||||
```
|
||||
|
||||
## 컨트롤러
|
||||
|
||||
### FundScheduleController (웹)
|
||||
|
||||
| 메서드 | 설명 | 데이터 흐름 |
|
||||
|--------|------|------------|
|
||||
| `index()` | 캘린더 뷰 | year, month → `getCalendarData()` → `getMonthlySummary()` → View |
|
||||
| `create()` | 등록 폼 | 계좌 목록, 타입/상태/반복 옵션 → View |
|
||||
| `edit(id)` | 수정 폼 | ID로 일정 조회 → View |
|
||||
| `show(id)` | 상세보기 | ID로 일정 조회 → View |
|
||||
|
||||
## 서비스 클래스
|
||||
|
||||
### FundScheduleService
|
||||
|
||||
| 메서드 | 매개변수 | 설명 |
|
||||
|--------|---------|------|
|
||||
| `getSchedules()` | filters, perPage | 필터링 목록 (페이지네이션) |
|
||||
| `getSchedulesForMonth()` | year, month | 월별 일정 조회 |
|
||||
| `getSchedulesForDate()` | date | 특정 날짜 일정 |
|
||||
| `getUpcomingSchedules()` | days=30 | 향후 N일 예정 일정 |
|
||||
| `getScheduleById()` | id, withTrashed | 단일 조회 |
|
||||
| `createSchedule()` | data | 생성 (tenant_id, created_by 자동) |
|
||||
| `updateSchedule()` | schedule, data | 수정 (updated_by 자동) |
|
||||
| `deleteSchedule()` | schedule | Soft Delete |
|
||||
| `restoreSchedule()` | schedule | 복원 |
|
||||
| `forceDeleteSchedule()` | schedule | 영구 삭제 |
|
||||
| `markAsCompleted()` | schedule, amount, date | 완료 처리 |
|
||||
| `markAsCancelled()` | schedule | 취소 처리 |
|
||||
| `copySchedulesToMonth()` | src→tgt year/month | 월별 일정 복사 (말일 처리) |
|
||||
| `bulkDelete()` | ids | 일괄 삭제 |
|
||||
| `bulkUpdateStatus()` | ids, status | 일괄 상태 변경 |
|
||||
| `getMonthlySummary()` | year, month | 월별 요약 |
|
||||
| `getCalendarData()` | year, month | 캘린더용 날짜별 그룹핑 |
|
||||
| `getSummary()` | - | 전체 요약 |
|
||||
|
||||
## 모델
|
||||
|
||||
### FundSchedule
|
||||
|
||||
**테이블**: `fund_schedules`
|
||||
|
||||
#### 상수 정의
|
||||
|
||||
```php
|
||||
// 일정 유형
|
||||
TYPE_INCOME = 'income' // 입금 예정
|
||||
TYPE_EXPENSE = 'expense' // 지급 예정
|
||||
|
||||
// 상태
|
||||
STATUS_PENDING = 'pending' // 예정
|
||||
STATUS_COMPLETED = 'completed' // 완료
|
||||
STATUS_CANCELLED = 'cancelled' // 취소
|
||||
|
||||
// 반복 규칙
|
||||
RECURRENCE_DAILY = 'daily'
|
||||
RECURRENCE_WEEKLY = 'weekly'
|
||||
RECURRENCE_MONTHLY = 'monthly'
|
||||
RECURRENCE_YEARLY = 'yearly'
|
||||
```
|
||||
|
||||
#### 주요 필드
|
||||
|
||||
| 필드 | 타입 | 설명 |
|
||||
|------|------|------|
|
||||
| `tenant_id` | bigint | 테넌트 ID |
|
||||
| `title` | string | 일정 제목 |
|
||||
| `description` | text | 설명 |
|
||||
| `schedule_type` | enum | income / expense |
|
||||
| `scheduled_date` | date | 예정 날짜 |
|
||||
| `amount` | decimal(15,2) | 예정 금액 |
|
||||
| `currency` | string | 통화 (KRW) |
|
||||
| `related_bank_account_id` | bigint | 관련 계좌 ID |
|
||||
| `counterparty` | string | 거래처 |
|
||||
| `category` | string | 카테고리 |
|
||||
| `status` | enum | pending / completed / cancelled |
|
||||
| `is_recurring` | boolean | 반복 여부 |
|
||||
| `recurrence_rule` | string | 반복 규칙 |
|
||||
| `recurrence_end_date` | date | 반복 종료일 |
|
||||
| `completed_date` | date | 실제 완료일 |
|
||||
| `completed_amount` | decimal(15,2) | 실제 금액 |
|
||||
| `created_by` / `updated_by` / `deleted_by` | bigint | 작업자 |
|
||||
|
||||
#### 주요 Scope
|
||||
|
||||
```php
|
||||
->income() // TYPE_INCOME만
|
||||
->expense() // TYPE_EXPENSE만
|
||||
->pending() // STATUS_PENDING만
|
||||
->completed() // STATUS_COMPLETED만
|
||||
->forMonth(year, month) // 특정 월의 일정
|
||||
->dateBetween(s, e) // 날짜 범위
|
||||
->ordered() // scheduled_date 정렬
|
||||
```
|
||||
|
||||
#### 주요 Accessor
|
||||
|
||||
```php
|
||||
$schedule->formatted_amount // "100만원" 형식
|
||||
$schedule->type_label // "입금 예정"
|
||||
$schedule->status_label // "예정"
|
||||
$schedule->type_color_class // Tailwind 색상 클래스
|
||||
$schedule->status_color_class // Tailwind 색상 클래스
|
||||
```
|
||||
|
||||
## 뷰 구성
|
||||
|
||||
### index.blade.php (캘린더 뷰)
|
||||
|
||||
```
|
||||
┌─ 페이지 헤더 ──────────────────────
|
||||
│ 제목: "자금계획일정"
|
||||
│ 버튼: "일정 등록"
|
||||
│
|
||||
├─ 월별 요약 카드 (4열) ────────────
|
||||
│ 입금 예정 | 지급 예정 | 순 자금 흐름 | 총 일정
|
||||
│
|
||||
├─ 캘린더 섹션 ─────────────────────
|
||||
│ ├─ 헤더: 월 네비게이션 (< 2026년 2월 >)
|
||||
│ ├─ 요일 헤더 (일~토)
|
||||
│ └─ 날짜 그리드 (일별 일정 표시)
|
||||
│ ├─ 입금: 초록 배지
|
||||
│ ├─ 지출: 빨강 배지
|
||||
│ └─ 클릭 시 일정 상세
|
||||
│
|
||||
└─ 일정 등록/수정 모달 (JavaScript)
|
||||
```
|
||||
|
||||
## 핵심 로직
|
||||
|
||||
### 월별 복사 (copySchedulesToMonth)
|
||||
|
||||
```
|
||||
원본 월의 모든 일정 조회
|
||||
↓
|
||||
대상 월로 복사 (말일 처리)
|
||||
예) 1월 31일 → 2월 28일 (윤년이면 29일)
|
||||
↓
|
||||
새 일정 생성 (상태: pending으로 초기화)
|
||||
```
|
||||
|
||||
### 월별 요약 (getMonthlySummary)
|
||||
|
||||
```php
|
||||
[
|
||||
'year' => 2026, 'month' => 2,
|
||||
'total_count' => 15,
|
||||
'income' => [
|
||||
'count' => 5, 'total' => 10000000,
|
||||
'pending' => 7000000, 'completed' => 3000000
|
||||
],
|
||||
'expense' => [
|
||||
'count' => 10, 'total' => 8000000,
|
||||
'pending' => 5000000, 'completed' => 3000000
|
||||
],
|
||||
'net' => 2000000 // 수입 - 지출
|
||||
]
|
||||
```
|
||||
|
||||
### 캘린더 데이터 (getCalendarData)
|
||||
|
||||
```php
|
||||
// 날짜별 그룹핑
|
||||
[
|
||||
'2026-02-05' => [ {일정1}, {일정2} ],
|
||||
'2026-02-06' => [ {일정3} ],
|
||||
...
|
||||
]
|
||||
```
|
||||
|
||||
## HTMX 호환성
|
||||
|
||||
- 순수 Blade 템플릿 (HX-Redirect 불필요)
|
||||
- JavaScript는 모달 열기/닫기 함수만 포함
|
||||
Reference in New Issue
Block a user