다크모드
수납 집합 완납 + 계약별 수납 — FE 메인테이너
독자: FE 메인테이너/AI. 집합(유닛/멤버) 완납 fan-out 및 펼침 계약 행 수납 흐름·파일 위치·undo·확장 포인트. 정본 spec:
docs/superpowers/specs/2026-06-24-collecting-aggregate-fullpay-policy-design.md. 관련: [[tenancy-axes-billing-tables.md]] · [[collecting-detail-sheet.md]].
흐름
- 집합 행 [완납] →
openFullPayment({ ...fullPaymentBreakdown(axis, key, filterScope), label })→selectedFullPayment적재 →command="show-modal" commandfor="dialog-collecting-fullpayment"→DialogCollectingFullPaymentArt.- [완납] 버튼 비활성 조건:
:disabled="totalOutstanding <= 0". 완납 커밋 후totalOutstanding이 0으로 갱신되면 버튼이 자동으로 비활성화됨. 미수가 다시 발생하면 활성 복귀.
- [완납] 버튼 비활성 조건:
- 다이얼로그 [완납 확인] →
commitFullPayment→confirmedemit → 테이블onFullPaid(토스트 +undoSnapshot {type:'receipts', receiptIds}). - 펼침 계약 행 [수납] — 제목 클릭 vs 액션 버튼 분리:
- 계약명(제목) 클릭 →
openContractDetail(contractCode)→sheet-collecting-detail-art(충당순서·백데이트·감면 세밀 조정). - [수납] 버튼 클릭 →
useContractQuickCollect(공유 컴포저블) 인라인 quick-collect 모드 진입. 미수금 prefill → 금액 직접 입력(부분·초과 가능) → Enter 확정 / Esc 취소 / ✓버튼 확정. 확정 시recordReceipt(contractCode)호출(계약 단일소스 — 집합 집계 자동 반영). 초과분은 선수금 처리. - [수납] 버튼 비활성 조건:
:disabled="contract.outstanding <= 0".
- 계약명(제목) 클릭 →
- 일괄 모드(canon) = 행 체크 → [선택 완납] →
commitBatch→ 선택 행마다commitFullPayment.
파일
- 컴포저블:
src/composables/useCollectingFullPayment.js(fullPaymentBreakdown/commitFullPayment). - 컴포저블:
src/composables/useContractQuickCollect.js— 계약 행 인라인 quick-collect 공유 컴포저블. 유닛·멤버·계약 탭 펼침 계약 행에서 공유 사용.recordReceipt(contractCode)호출. - 공유 상태:
src/components/billing/_core/console/collecting/selectedFullPayment.js(selectedFullPaymentref +openFullPayment). - 다이얼로그:
src/components/billing/_core/console/collecting/DialogCollectingFullPaymentArt.vue(iddialog-collecting-fullpayment). - 탭:
src/components/billing/_core/console/collecting/unit/blocks/DynamicTableOrg.vue(유닛 집합 [완납]·펼침 계약 행 [수납] 인라인·제목 클릭 시트·일괄 완납-선택·다이얼로그 마운트). - 탭:
src/components/billing/_core/console/collecting/member/blocks/DynamicTableOrg.vue(멤버 집합 동일 패턴). - 탭:
src/components/billing/_core/console/collecting/contract/blocks/DynamicTableOrg.vue(계약 탭 atom 행 [수납] 인라인·제목 클릭 시트). - 테스트:
src/composables/__tests__/useCollectingFullPayment.spec.js.
undo
undoLastCollect가 두 형태 처리: {type:'receipts', receiptIds} (완납·canon) → cancelReceipt 루프 / Array (non-canon mock) → row 객체 복원.
수납일 (읽기전용)
DialogCollectingFullPaymentArt의 수납일은 표시 전용(편집 불가) — paymentDate(new CalendarDate(2025,12,15) 데모 고정·실서비스는 today)를 displayDate로 읽기전용 표시(<input disabled readonly>). 편집 DatePicker 제거 이유: 날짜 변경이 "타임머신(완납액 재산정)"으로 오해되나 실제로는 receivedAt stamp만 바뀜. 소급/연체료 정산은 계약 상세 시트(수납일 replay) 소관. 목록 as-of 타임머신은 별도 슬라이스(미구현).
확장
- non-canon(mock) 경로는 기존 인라인 수납 유지(canon만 완납 정책).
filterScope(current|forwarded|all)는 부모 toolbar에서 주입(prop) —fullPaymentBreakdownscope 인자로 그대로 전달.- 멤버 탭은
fullPaymentBreakdown('member', row.key, filterScope)+label: row.memberDisplayName으로 호출. 나머지 흐름 유닛과 동일.