Files
sam-docs/dev/dev_plans/account-ledger-service-migration-plan.md

11 KiB

계정별원장 서비스 이관 기획서

작성일: 2026-03-20 상태: 기획 확정, API 완료 대상: MNG → API + React (서비스 이관) 위치: 서비스 > 회계관리 > 계정별원장


1. 개요

1.1 목적

MNG 백오피스의 계정별원장 조회 기능을 서비스(API + React)로 이관한다. MNG는 Controller에서 직접 DB 조회 → API는 Service-First 패턴의 REST API + React 구조로 재구현한다.

1.2 배경

  • MNG 회계/세무관리 > 계정별원장 메뉴로 기존 구현 완료 (2026-03-19)
  • API에 AccountLedgerService + AccountLedgerController가 기존에 존재하나, MNG 대비 기능이 부족
  • MNG Controller에 카드거래 상세 조회, 분리전표(split) 필터링 등의 로직이 직접 구현됨
  • API 보강 후 React에서 동일 기능을 구현할 수 있도록 한다

1.3 이관 범위

구분 MNG (현재) API + React (이관 후)
백엔드 Controller 직접 DB 조회 AccountLedgerService (보강 완료)
프론트 Blade + React (@verbatim) React (Next.js)
인증 세션 기반 (session('selected_tenant_id')) Bearer 토큰 + BelongsToTenant
API 문서 없음 Swagger

2. 현재 MNG 기능 분석

2.1 데이터 소스

계정별원장은 journal_entries + journal_entry_lines 테이블 기반으로 조회한다. 카드거래, 홈택스 분개 등은 이미 일반전표(journal)에 포함되어 있으므로 UNION 불필요.

journal_entry_lines (분개 행)
    ├── JOIN journal_entries (전표 마스터)
    ├── LEFT JOIN trading_partners (거래처 사업자번호)
    └── 추가 조회: barobill_card_transactions (카드 상세)
                   barobill_card_transaction_splits (분리 전표 유효성)

2.2 MNG 기능 목록

기능 MNG 메서드 API 대응
페이지 렌더링 index() React 라우트
데이터 조회 list() GET /api/v1/account-ledger
카드거래 상세 fetchCardTransactions() (private) Service 내부 메서드
이월잔액 계산 calculateCarryForward() (private) Service 내부 메서드
분리전표 필터링 list() 내부 로직 filterSplitLines() (private)
전표 드릴다운 프론트에서 별도 API 호출 GET /api/v1/general-journal-entries/{id}
계정과목 목록 MNG 내부 API GET /api/v1/account-subjects
인쇄 window.print() React에서 동일

2.3 MNG ↔ API 차이점 (보강 전/후)

항목 MNG API (보강 전) API (보강 후)
source_type COALESCE(je.source_type, 'journal') 하드코딩 'journal' COALESCE 사용
source_key 응답에 포함 미포함 포함
카드거래 상세 (card_tx) 포함 미포함 포함
분리전표 필터링 포함 미포함 포함
거래처명 카드 가맹점 대체 포함 미포함 포함

3. API 보강 내역 (완료)

3.1 수정 파일

파일 변경 내용
api/app/Services/AccountLedgerService.php 4개 기능 추가

3.2 추가된 기능

1) source_type 동적 조회

// 변경 전
DB::raw("'journal' as source_type")

// 변경 후
DB::raw("COALESCE(je.source_type, 'journal') as source_type")

2) source_key 필드 추가

  • 쿼리 select에 'je.source_key' 추가
  • 카드거래 매칭, 분리전표 판별에 사용

3) 분리전표 필터링 (filterSplitLines)

  • barobill_card_transaction_splits 테이블에서 유효한 split ID만 조회
  • 무효한 분리전표 행 제거
  • 분리전표가 존재하는 원본 전표 행 제거

4) 카드거래 상세 조회 (fetchCardTransactions)

  • source_type === 'ecard_transaction'인 행의 source_key를 파싱
  • barobill_card_transactions 테이블에서 카드번호, 카드사, 가맹점, 공제/불공제 등 조회
  • 카드 가맹점명이 있으면 trading_partner_name 대체

4. API 엔드포인트

4.1 계정별원장 조회

Method Path 설명
GET /api/v1/account-ledger 계정별원장 데이터 조회

4.2 요청 파라미터

파라미터 타입 필수 설명
start_date string(date) Y 조회 시작일
end_date string(date) Y 조회 종료일
account_code string Y 계정과목 코드

4.3 응답 구조

interface AccountLedgerResponse {
  success: boolean;
  message: string;
  data: {
    account: {
      code: string;       // "81100"
      name: string;       // "복리후생비"
      category: string;   // "expense"
    } | null;
    period: {
      start_date: string;
      end_date: string;
    };
    carry_forward: {
      debit: number;
      credit: number;
      balance: number;
    };
    monthly_data: MonthlyData[];
    grand_total: {
      debit: number;
      credit: number;
      balance: number;
    };
  };
}

interface MonthlyData {
  month: string;            // "2026-03"
  items: LedgerItem[];
  subtotal: { debit: number; credit: number };
  cumulative: { debit: number; credit: number };
}

interface LedgerItem {
  date: string;
  description: string | null;
  trading_partner_name: string | null;
  biz_no: string | null;
  debit_amount: number;
  credit_amount: number;
  balance: number;
  source_type: string;       // 'journal' | 'ecard_transaction' | 'bank_transaction' 등
  source_id: number;
  card_tx: CardTransaction | null;
}

interface CardTransaction {
  card_num: string;           // "1234567890123456"
  card_company_name: string;  // "삼성카드"
  merchant_name: string;      // "스타벅스 강남점"
  merchant_biz_num: string;   // "1234567890"
  deduction_type: string;     // "deductible" | "non_deductible"
  supply_amount: number;      // 공급가액
  tax_amount: number;         // 세액
  approval_amount: number;    // 승인금액
}

4.4 관련 API

API 용도
GET /api/v1/account-subjects 계정과목 목록 (필터 드롭다운)
GET /api/v1/account-subjects?selectable=true 입력 가능 계정과목만 (depth=3)
GET /api/v1/general-journal-entries/{id} 전표 상세 (드릴다운)

5. React 구현 요구사항

5.1 화면 구성

┌──────────────────────────────────────────────┐
│ 📖 계정별원장                          [인쇄] │
├──────────────────────────────────────────────┤
│ 조회기간: [시작일] ~ [종료일]                   │
│ 계정과목: [코드/이름 검색 드롭다운]    [조회]   │
├──────────────────────────────────────────────┤
│ 81100 복리후생비  (2026-01-01 ~ 2026-03-20)  │
├──────┬────────┬──────┬──────┬──────┬──────┬──────┤
│ 날짜 │ 적요   │거래처│사업자│ 차변 │ 대변 │ 잔액 │
├──────┼────────┼──────┼──────┼──────┼──────┼──────┤
│  -   │이월잔액│      │      │   0  │   0  │   0  │
├──────┼────────┼──────┼──────┼──────┼──────┼──────┤
│01-11 │복리후생│      │      │160000│      │160000│
│  ... │  ...   │      │      │  ... │  ... │ ...  │
├──────┼────────┼──────┼──────┼──────┼──────┼──────┤
│      │ 2026-01 계    │      │합계  │      │      │
│      │ 누 계         │      │합계  │      │      │
├──────┼────────┼──────┼──────┼──────┼──────┼──────┤
│      │ 총 합 계      │      │합계  │합계  │최종  │
└──────┴────────┴──────┴──────┴──────┴──────┴──────┘

5.2 핵심 기능

기능 설명
조회 필터 기간(date range) + 계정과목 검색 (코드/이름 자동완성)
이월잔액 조회 시작일 이전 누적 잔액 (첫 행에 표시)
월별 소계/누계 월이 바뀔 때마다 소계 행 + 누계 행
잔액 계산 자산/비용 = 차변-대변, 부채/자본/수익 = 대변-차변
카드거래 표시 card_tx 있으면 카드 아이콘 + 공제/불공제 배지 + 카드사·끝4자리
드릴다운 행 클릭 → 전표 상세 모달 (journal/ecard_transaction/bank_transaction)
인쇄 CSS @media print 활용, 조회 조건 영역 숨김

5.3 잔액 계산 규칙

계정 카테고리 정상 방향 잔액 =
asset (자산) 차변 차변 - 대변
expense (비용) 차변 차변 - 대변
liability (부채) 대변 대변 - 차변
capital (자본) 대변 대변 - 차변
revenue (수익) 대변 대변 - 차변

5.4 드릴다운 로직

행 클릭 시 source_type 기반 분기:
├── 'journal' | 'ecard_transaction' | 'bank_transaction'
│   → GET /api/v1/general-journal-entries/{source_id}
│   → 전표 상세 모달 (분개 라인 테이블 + 카드정보)
│
└── 'hometax'
    → 홈택스 세금계산서 상세 (별도 API 필요 시 추후 추가)

5.5 카드거래 표시 규격

card_tx가 존재하는 행은 다음과 같이 표시:

  • 적요 셀: 💳 아이콘 + 적요 텍스트 + [공제]/[불공제] 배지
  • 적요 셀 하단: 카드사명 ····끝4자리 (서브텍스트)
  • 거래처 셀: card_tx.merchant_name 우선 (없으면 trading_partner_name)
  • 사업자번호 셀: card_tx.merchant_biz_num 우선

6. MNG 참고 화면

MNG(백오피스)에 동일 기능이 구현되어 있다. 화면 레이아웃과 UX를 참고한다.

MNG 개발서버: https://admin.codebridge-x.com → 회계/세무관리 > 계정별원장

6.1 MNG 소스 참고 파일

파일 설명
mng/app/Http/Controllers/Finance/AccountLedgerController.php 전체 로직 (카드, split 포함)
mng/resources/views/finance/account-ledger.blade.php React 컴포넌트 (UI 참고)

관련 문서


최종 업데이트: 2026-03-20