Skip to content

부과요약서 — FE 메인테이너 참고

관리비 상용화 보고서 확충 트랙(2026-07-11, B-2). 설계 정본: docs/superpowers/specs/2026-07-11-period-tag-minors-reports-xlsx-design.md §B-2. 데이터 계약은 docs/handoff/backend/report-charge-summary.md 참고. 총괄표 FE handoff(report-summary-table.md) 패턴을 그대로 복제.

⚠️ 이름 충돌 주의 — 이 문서(부과요약서)와 총괄표(report-summary-table.md)는 이름이 매우 비슷하지만 별개 화면이다. 컴포저블 useChargeSummary(부과요약서, 본 문서) vs useChargeSummaryTable(총괄표) — 철자 하나(Table) 차이. 인쇄 라우트도 /document/report/charge-summary-view(총괄표 인쇄, 기존 ChargeSummaryView.vue) vs /document/report/charge-summary-brief-view(부과요약서 인쇄, 신규 ChargeSummaryBriefView.vue, "brief" 접미사로 구분). 새 코드를 배선할 때 반드시 어느 쪽인지 파일명·경로 끝까지 확인할 것 — 자동완성으로 useChargeSummaryTable을 잘못 import하기 쉽다.


1. 라우트 / feature 게이트

1-1. 콘솔 탭

신규 탭 없음 — 기존 보고서 탭 내부 세그먼트로 편입. ReportKindTabsAtoKINDS 배열에서 4번째(산출표·총괄표·부과내역서 다음, 수납현황 앞).

1-2. 페이지 라우트 (buildLineRoutes.js)

js
'report/charge-summary': () => import('../views/service-charge/actual/console/report/charge-summary/IndexView.vue')

provisional에는 없음(라우트 게이트, buildLineRoutes.spec.js).

1-3. 인쇄 문서 라우트

/document/report/charge-summary-brief-view → views/document/report/ChargeSummaryBriefView.vue

feature 게이트 없음(document 앱 공통 패턴). 상단 경고 참고 — charge-summary-view(접미사 없음)는 총괄표 인쇄 뷰.

1-4. i18n

신규 키 없음.


2. 데이터 컴포저블 — useChargeSummary

위치: src/composables/useChargeSummary.js. useChargeSummaryTable()(총괄표 컴포저블) 하나만 소비하는 얇은 재투영 레이어 — 자체 상태 없음.

API 시그니처:

  • summaryRows()kapt().rows(총괄표 K-apt 뷰 항목행) + share(구성비, 표시용) 필드. 각 원소 chargeCode·name·total·unitPrice·share.
  • summaryTotals()columnTotals()(총괄표 열 합계) 전체 + totalArea·vatPerArea(K-apt 파생).
  • formatAmount → 재-export.

3. 보고서 종 세그먼트

부과내역서 handoff §3과 동일 컴포넌트(ReportKindTabsAto) — KINDS 배열에 { key: 'charge-summary', label: '부과요약서', path: '...report/charge-summary' }가 부과내역서 다음·수납현황 앞에 위치.


4. 컴포넌트 구조

  • src/views/service-charge/actual/console/report/charge-summary/IndexView.vue
  • src/components/service-charge/actual/console/report/charge-summary/MainOrg.vue — 웹조회: 항목별 표(합계·구성비·㎡당 단가) + 세전/부가세/당월합계 + 미납·선수금·청구액 + [시트][인쇄].
  • src/views/document/report/ChargeSummaryBriefView.vue — 인쇄 문서 뷰.

pct(x) = (x*100).toFixed(1)+'%' — 화면·인쇄 양쪽에서 동일한 로컬 포맷 함수로 share(0~1 raw fraction)를 퍼센트 문자열로 변환(컴포넌트 로컬, 컴포저블 반환값이 아님 — §6 xlsx 절과 대조).


5. 인쇄 뷰 패턴

ChargeSummaryBriefView.vue는 산출표·부과내역서·수납현황과 동일한 print-a4-portrait-flow-scoped(190mm)를 재사용. 항목 수가 적어 보통 1장에 끝난다.


6. [시트] — xlsxExport 유틸 계약 + raw fraction 주의

js
const XLSX_COLUMNS = [
  { key: "name", label: "항목" },
  { key: "total", label: "부과총액" },
  { key: "share", label: "구성비" },
  { key: "unitPrice", label: "㎡당 단가(원)" },
];
const downloadXlsx = () =>
  exportXlsx({
    fileName: `부과요약서-${periodLabelOf("service-charge", "actual")}.xlsx`,
    sheetName: "부과요약서",
    columns: XLSX_COLUMNS,
    rows: rows.value,
  });

⚠️ 명기할 주의(구성비 export 표기): share는 화면에서는 pct()로 "24.5%" 문자열로 렌더링하지만, 엑셀로 내보낼 때는 0~1 사이 raw fraction(예: 0.245) 그대로 기록한다rows.value(컴포저블 원본, 퍼센트 문자열이 아님)를 그대로 넘기기 때문이다. 이는 실수가 아니라 의도된 결정이다 — 엑셀은 0~1 소수를 "백분율" 셀 서식으로 지정하면 자동으로 24.5%처럼 표시하는 네이티브 기능이 있고, 반대로 문자열 "24.5%"를 넣으면 엑셀이 숫자로 인식하지 못해 합산·서식 적용이 불가능해진다. 신규 소비처를 만들 때 "화면과 다르게 보인다"고 착각해 pct(r.share)로 바꾸지 말 것.


7. 알려진 미해결 사항

  • 이름 충돌 주의(상단 경고) — useChargeSummary vs useChargeSummaryTable, charge-summary-view vs charge-summary-brief-view.
  • document 앱 셸 no-print 갭 — 총괄표 §6와 동일 근거로 스코프 밖.
  • 기간범위·층/블록 축 필터 없음 — backend handoff §4 참고.

8. 테스트 위치

  • src/composables/__tests__/useChargeSummary.spec.js — 불변식 4종(backend handoff §3 대응).
  • src/router/__tests__/buildLineRoutes.spec.js — actual 전용 라우트 게이트.
  • src/components/service-charge/actual/console/report/__tests__/XlsxWiring.spec.js[시트] 배선 스모크(부과요약서 케이스 포함).
  • Playwright 라이브 실측: 세그먼트 4번째 위치, [시트] 다운로드(엑셀 열어 구성비 셀 raw fraction 확인), 인쇄 뷰 개봉.

9. 확장 절차

docs/handoff/frontend/report-summary-table.md §8(8단계) 참고 — 본 문서(부과요약서)는 1단계(탭 등록)를 생략하고 KINDS 배열 추가만으로 완성됐다(3단계가 useChargeSummary, 4단계가 이 MainOrg.vue).