# 카드사용내역 ## 개요 카드사용내역은 바로빌 SOAP API를 통해 카드사 거래내역을 실시간 조회하고, 회계 분류(계정과목 지정), 분개(1거래→N계정과목), 거래 숨김, 금액 수정, 수동 거래 등록 등을 지원하는 기능입니다. - **라우트**: `GET /finance/card-transactions` → 바로빌 EcardController로 리다이렉트 - **실제 페이지**: `GET /barobill/ecard` - **UI 기술**: React 18 + Babel (브라우저 트랜스파일링) ## 파일 구조 ``` mng/ ├── app/Http/Controllers/ │ ├── Barobill/ │ │ └── EcardController.php # 메인 컨트롤러 (바로빌 연동) │ └── Finance/ │ └── CardTransactionController.php # 수동 거래내역 컨트롤러 ├── app/Models/Barobill/ │ ├── CardTransaction.php # 바로빌 카드거래 모델 │ ├── CardTransactionSplit.php # 거래 분개 모델 │ ├── CardTransactionHide.php # 거래 숨김 모델 │ └── CardTransactionAmountLog.php # 금액 수정 이력 모델 ├── app/Models/Finance/ │ └── CardTransaction.php # 수동 입력 거래 모델 └── resources/views/ ├── barobill/ecard/ │ └── index.blade.php # 바로빌 카드거래 React 페이지 └── finance/ └── card-transactions.blade.php # 수동 거래내역 React 페이지 api/ └── database/migrations/ ├── 2026_01_23_150000_create_barobill_card_transactions_table.php ├── 2026_01_23_160000_create_barobill_card_transaction_splits_table.php ├── 2026_02_05_100003_create_card_transactions_table.php ├── 2026_02_05_200100_create_barobill_card_transaction_amount_logs_table.php └── 2026_02_05_500000_create_barobill_card_transaction_hides_table.php ``` ## 라우트 ### 바로빌 카드거래 (메인) ```php // routes/web.php (barobill/ecard prefix) GET / → index() React 페이지 렌더링 GET /cards → cards() 등록된 카드 목록 GET /transactions → transactions() 거래내역 조회 (API+DB 병합) GET /account-codes → accountCodes() 계정과목 목록 POST /save → save() 거래 저장 (회계 분류) POST /export → exportExcel() Excel 내보내기 GET /splits → splits() 분개 내역 조회 POST /splits → saveSplits() 분개 저장 DELETE /splits → deleteSplits() 분개 삭제 POST /manual → storeManual() 수동 거래 등록 PUT /manual/{id} → updateManual() 수동 거래 수정 DELETE /manual/{id} → destroyManual() 수동 거래 삭제 POST /hide → hideTransaction() 거래 숨김 POST /restore → restoreTransaction() 거래 숨김 해제 GET /hidden → hiddenTransactions() 숨긴 거래 목록 ``` ### 수동 거래내역 (보조) ```php // routes/web.php (card-transactions prefix) GET /list → index() 수동 거래 목록 POST /store → store() 수동 거래 등록 PUT /{id} → update() 수동 거래 수정 DELETE /{id} → destroy() 수동 거래 삭제 ``` ## 컨트롤러 ### EcardController (바로빌 카드거래) | 메서드 | HTTP | 설명 | |--------|------|------| | `index()` | GET | React 페이지 렌더링 (HX-Redirect 적용) | | `cards()` | GET | 바로빌 등록 카드 목록 (SOAP API) | | `transactions()` | GET | **거래내역 조회** (API + DB 병합) | | `accountCodes()` | GET | 계정과목 목록 | | `save()` | POST | 거래 저장 (계정과목 지정) | | `exportExcel()` | POST | Excel 내보내기 | | `splits()` | GET | 분개 내역 조회 | | `saveSplits()` | POST | 분개 저장 | | `deleteSplits()` | DELETE | 분개 삭제 | | `storeManual()` | POST | 수동 거래 등록 | | `updateManual()` | PUT | 수동 거래 수정 | | `destroyManual()` | DELETE | 수동 거래 삭제 | | `hideTransaction()` | POST | 거래 숨김 처리 | | `restoreTransaction()` | POST | 거래 숨김 해제 | | `hiddenTransactions()` | GET | 숨긴 거래 목록 | ### CardTransactionController (수동 거래) | 메서드 | HTTP | 설명 | |--------|------|------| | `index()` | GET | 수동 거래 목록 (필터, 통계 포함) | | `store()` | POST | 거래 등록 | | `update()` | PUT | 거래 수정 | | `destroy()` | DELETE | 거래 삭제 (Soft Delete) | ## 바로빌 SOAP API 연동 ### 사용 SOAP 메서드 | WSDL | 메서드 | 기능 | |------|--------|------| | CARD.asmx | `GetRegisteredCard` | 등록된 카드 목록 조회 | | CARD.asmx | `GetPeriodCardLog` | 기간별 카드거래 내역 조회 | ### 테넌트별 서버 모드 ``` BarobillMember.server_mode → 'test' 또는 'production' → BarobillConfig 재로드 → SOAP 클라이언트 재초기화 ``` ## 핵심 로직 ### 거래내역 조회 흐름 (transactions) ``` React 컴포넌트 (카드/기간 선택) ↓ GET /barobill/ecard/transactions ↓ 1. BarobillMember 조회 (바로빌 인증 정보) ↓ 2. 테넌트별 서버 모드 적용 (test/production) ↓ 3. SOAP 호출: GetPeriodCardLog (바로빌 API) ↓ 4. DB 저장된 거래와 병합 (barobill_card_transactions) ↓ 5. 숨긴 거래 표시 (barobill_card_transaction_hides) ↓ 6. 분개 데이터 병합 (barobill_card_transaction_splits) ↓ 7. 수동 거래 병합 ↓ 8. 정렬 + JSON 응답 ``` ### 거래 고유 키 (unique_key) ```php // CardTransaction (Barobill) 모델 return implode('|', [ $this->card_num, $this->use_dt, // 사용일시 $this->approval_num, $this->approval_amount, ]); ``` ### 거래 금액 처리 ``` approval_type = '1' → 승인 (+ 금액) approval_type = '2' → 취소 (- 금액) modified_supply_amount, modified_tax → 금액 수정 시 원본 대신 사용 ``` ### 분개 저장 흐름 ``` React (분개 모달) ↓ POST /barobill/ecard/splits { originalUniqueKey: "카드번호|사용일시|승인번호|금액", originalData: { cardNum, useDt, ... }, splits: [ { amount: 50000, accountCode: "1000", accountName: "당좌예금" }, { amount: 50000, accountCode: "2000", accountName: "미수금" } ] } ↓ 기존 분개 삭제 → 새 분개 생성 × N ``` ## 모델 ### CardTransaction (Barobill) **테이블**: `barobill_card_transactions` | 필드 | 타입 | 설명 | |------|------|------| | `tenant_id` | bigint | 테넌트 ID | | `card_num` | string | 카드번호 (하이픈 없음) | | `card_company` / `card_company_name` | string | 카드사 코드/명 | | `use_dt` | string | 사용일시 (YYYYMMDDHHMMSS) | | `use_date` / `use_time` | string | 사용일/시간 분리 | | `approval_num` | string | 승인번호 | | `approval_type` | string | 1=승인, 2=취소 | | `approval_amount` | decimal | 승인금액 | | `tax` / `service_charge` | decimal | 세금/봉사료 | | `merchant_name` / `merchant_biz_num` | string | 가맹점명/사업자번호 | | `account_code` / `account_name` | string | 계정과목 코드/명 | | `modified_supply_amount` / `modified_tax` | decimal | 수정 공급가/세액 | | `is_manual` | boolean | 수동 입력 여부 | - **Unique Index**: `[tenant_id, card_num, use_dt, approval_num, approval_amount]` ### CardTransactionSplit **테이블**: `barobill_card_transaction_splits` | 필드 | 타입 | 설명 | |------|------|------| | `original_unique_key` | string(200) | 원본 거래 고유 키 | | `split_amount` | decimal | 분개 금액 | | `split_supply_amount` / `split_tax` | decimal | 공급가/세액 | | `account_code` / `account_name` | string | 계정과목 | | `deduction_type` / `evidence_name` | string | 공제구분/증빙명 | | `sort_order` | int | 정렬 순서 | ### CardTransactionHide **테이블**: `barobill_card_transaction_hides` | 필드 | 타입 | 설명 | |------|------|------| | `original_unique_key` | string | 거래 고유 키 | | `card_num` / `use_date` / `approval_num` | string | 원본 거래 정보 | | `original_amount` / `merchant_name` | string | 원본 금액/가맹점 | | `hidden_by` | bigint | 숨김 처리 사용자 | ### CardTransactionAmountLog **테이블**: `barobill_card_transaction_amount_logs` | 필드 | 타입 | 설명 | |------|------|------| | `card_transaction_id` | bigint | 카드거래 FK | | `before_supply_amount` / `before_tax` | decimal | 수정 전 금액 | | `after_supply_amount` / `after_tax` | decimal | 수정 후 금액 | | `modified_by` / `modified_by_name` | string | 수정자 | | `ip_address` | string | 수정 IP | ### CardTransaction (Finance - 수동) **테이블**: `card_transactions` | 필드 | 타입 | 설명 | |------|------|------| | `tenant_id` | bigint | 테넌트 ID | | `card_id` | bigint | 법인카드 FK | | `transaction_date` | date | 거래일 | | `time` | string | 거래시간 (HH:MM) | | `merchant` | string(200) | 가맹점명 | | `category` | string | 카테고리 | | `amount` | bigint | 금액 | | `approval_no` | string | 승인번호 | | `status` | enum | approved / cancelled | ## 뷰 구성 (React) ### card-transactions.blade.php (수동 거래) ``` ┌─ 페이지 헤더 ────────────────────── │ Excel 내보내기 | 거래 추가 버튼 │ ├─ 통계 카드 (4열) ────────────────── │ 조회 건수 | 총 사용금액 | 승인 금액 | 취소 금액 │ ├─ 카테고리 사용현황 (수평 바) ────── │ 식비 | 교통비 | 접대비 | ... (금액 순 정렬) │ ├─ 필터 영역 ──────────────────────── │ 검색 | 카드 선택 | 카테고리 | 기간 | 상태(전체/승인/취소) │ ├─ 거래 목록 (날짜별 그룹) ────────── │ 날짜 헤더 (건수, 소계) │ ├─ 가맹점명 + 카테고리 아이콘 │ ├─ 시간, 카드명, 카테고리라벨 │ ├─ 금액 (승인=빨강, 취소=파랑) │ └─ 수정/삭제 버튼 │ └─ 등록/수정 모달 카드, 날짜, 시간, 가맹점명, 카테고리 금액, 승인번호, 상태, 메모 ``` ### 카테고리 목록 | 카테고리 | 아이콘 | 색상 | |---------|--------|------| | 식비 | Utensils | amber | | 교통비 | Car | blue | | 운영비 | Settings | gray | | 마케팅비 | Megaphone | purple | | 사무용품 | Paperclip | teal | | 도서/교육 | BookOpen | indigo | | 접대비 | Wine | rose | | 장비구매 | Monitor | cyan | | 기타 | MoreHorizontal | gray | ## HTMX 호환성 - React 기반 페이지이므로 **HX-Redirect 필요** - `@push('scripts')` 블록에 React/Babel 스크립트 포함 - HTMX 네비게이션 시 전체 페이지 리로드 필수