다크모드
청구·수납 상세 역할 분리 — BE 참고 매뉴얼
상위 정본: 재무·회계·세무 > 회계 정본의 용어·흐름·분개·불변식. 이 문서는 청구와 수납 모듈의 구현 계약을 구체화한다.
독자: BE 개발자/AI. 청구=문서 vs 수납=원장 데이터 계약·청구액 정본·부과항목 도출. 정본 spec:
docs/superpowers/specs/2026-06-28-invoicing-collecting-role-split.md. as-built 2026-06-28.
1. 회계 도메인 분리
- 청구(Billing) = 발행시점 동결 문서. 매출인식 + 세금계산서/계산서 발행 근거. 데이터: 부과 항목별 명세(과세/면세 구분·단가·부과원금·VAT)·부과 합계·청구액·분개(E2). 불변(발행 후).
- 수납(Collection) = 라이브 AR 원장. 현금수취 + FIFO 충당 + aging. 데이터: 차수별 미수·수납·잔액(이월)·수납내역·선수금·연체료(E3)·조정(E7). 입금마다 변동.
- 단일 소스 원칙: 부과항목·부과요약·분개 = 청구 / 차수충당·수납내역·선수금·연체 = 수납. (메가시트 SheetReadBillingArt 폐기로 중복 제거.)
2. 청구액(payable) = 정본 bridge
청구액 = useCollectingDetail.totals.payable = max(0, 받을금액(미수+연체) − 선수금). 두 시트 헤드라인 공통. 재계산 금지(기존 캐논).- ⚠ 부과 합계(grandTotal) ≠ 청구액: grandTotal = 당기+이월 부과(공급대가, 연체·선수금 미반영). 청구 상세는 둘 다 표기하되 라벨 구분(청구액 vs 합계 부과금).
3. 부과 항목 명세 도출 (READ)
useInvoicingDetail.itemsFor(selection):
- charge별
allocationBreakdown(charge, axis, key)→ 부과원금(cellTotal) + 메타(name·taxCategory·chargeBasis). - 단가 = chargePrincipal/totalWeight(배분단가/산정단가) · 부과기준값 = Σ basisQuantity · VAT = 과세면
vatRateAt(date)×원금 · 부과액 = 원금+VAT. - 불변식: Σ(부과원금)===current.supplyTotal · Σ(과세 VAT)===current.vat.
- ⚠ 조정/할증/할인은 charge-config 레벨(데모 0) — READ 명세엔 미포함. 단가/조정 편집은 항목설정 API(부과항목 명세 아님).
- BE 계약: 실 BE는 세금계산서 항목 단위로 부과원금·VAT 보유 → 동일 itemsFor 형태로 제공. 다과세-charge 시 per-item VAT 반올림(Σ=계산서 VAT) 처리 필요.
4. 데이터 계약 (시트별)
- 청구 상세:
useInvoicingDetail.detailFor(header·current·forward·grandTotal·journal) +itemsFor(부과항목) +payable(수납 재사용). - 수납 상세:
useCollectingDetail.detailFor(identity·totals·periods·receipts·advance·adjustments).
5. 테스트
__tests__/invoicingItems.spec.js(Σ부과원금=supplyTotal·Σ과세VAT=current.vat·세금구분·결정성·사용량 charge).