SAP 매출세금계산서 발행 — 전표 한 건에서 계산서 한 장까지
세금계산서를 아직 끊지 않은 AR 전표를 찾아, 공급자·공급받는자 정보를 마스터에서 채워 한 건씩 발행하는 화면입니다.
세금계산서를 발행하려면 전표 금액만으로는 부족합니다. 공급자와 공급받는자 정보가 모두 필요합니다.
사업자번호, 상호, 대표자, 사업장 주소, 업태, 종목까지 양쪽 모두 채워야 한 장이 완성됩니다. 이 값들은 이미 SAP 안에 있습니다. 공급자는 사업장 마스터에, 공급받는자는 고객 마스터에 들어 있습니다. 이 화면은 전표를 고르면 양쪽 정보를 마스터에서 끌어와 계산서 형태로 펼쳐 주고, 담당자와 e-Mail 만 채우면 발행으로 넘깁니다. 그리고 발행한 건은 다음 조회에서 사라집니다.
SAP 표준 구조를 그대로 이어받은 부분
- 대상 조회 —
BSID·BSAD의 AR 전표,ZSB_HEADER로 발행 이력 제외 - 금액 —
BSET의FWBAS(공급가액) ·FWSTE(세액) - 공급자 —
J_1BBRANCH(사업자번호·대표자·업태·종목) ·ADRC(상호·주소) - 공급받는자 —
KNA1의STCD2·J_1KFREPRE·J_1KFTBUS·J_1KFTIND
| 항목 | 내용 |
|---|---|
| 업무 영역 | 재무회계(FI-AR) · 세금계산서 발행 |
| Namespace | zui5.taxinv |
| 셸 구조 | 조회조건 영역(우측 조회) + 미발행 전표 목록, 발행 팝업 |
| 화면 수 | 조회 화면 1개 + 세금계산서 발행 팝업 |
| 데이터 | AR 전표 26건 · 세금코드 4종 · 고객 4곳 (마이너스 2건) |
| 성격 | 조회·발행형 — 발행은 외부 연계가 수행 |
| UI 테마 | sap_horizon 단일 적용 |
실제 화면 11종 둘러보기
미발행 전표를 조회해 한 건을 고르면 → 팝업에 양쪽 마스터 정보가 채워지고 → 담당자만 넣어 발행합니다.
아래는 실제로 앱을 실행해 기능을 눌러 가며 캡처한 화면입니다. 이미지를 클릭하면 원본 크기로 확대됩니다.
조작 방법
- Document date 와 Tax code 범위를 확인합니다. 둘 다 필수 조건입니다.
- 조회하면 아직 계산서를 끊지 않은 전표만 나옵니다. 발행된 건은 자동으로 빠집니다.
- 마이너스로 표시된 건은 반품 영세율 건입니다. BSET 없음 표시로 이유를 확인합니다.
- 전표를 한 건만 골라 세금계산서 발행을 누릅니다. 두 건 이상이면 막힙니다.
- 팝업에서 공급자·공급받는자 정보가 자동으로 채워집니다. 담당자와 e-Mail 을 입력합니다.
- 품목·규격·수량·비고를 확인하고 발행하면 승인번호가 돌아옵니다.
조회·금액 산출 규칙
조회 조건과 금액 산출에 실무에서 나온 예외 규칙이 두 가지 들어 있습니다.
조회 : 세금계산서 미발행 AR 전표
BSID / BSAD
bukrs = 회사코드 bupla in Business Place
kunnr in Customer bldat in Document date
budat in Posting date belnr in Document No.
mwskz in Tax code (AA ~ AJ)
→ ZSB_HEADER 를 참조해 이미 발행된 건은 제외
금액 : BSET
FWBAS = 공급가액 FWSTE = 세액
※ 반품 빌링 대응 (CR1810040007)
BSET 에 데이터가 없고 TAX CODE 가 AI(영세)이면서
SHKZG 가 H(대변)인 경우 → 금액에 마이너스 부호 적용
품목·규격·수량 (CR1812140009)
BSAD 의 KIDNO + BSID 의 KIDNO 를 추출해 중복 제거 후
SD 함수로 품목 정보 수신
발행
선택 라인 없음 → "선택된 라인이 없습니다"
2건 이상 선택 → "세금계산서는 한건씩만 발행할 수 있습니다."
1건이면 → 발행 팝업 → 외부 연계 발행| 항목 | 산식 · 규칙 |
|---|---|
| 대상 한정 | AR 전표 중 발행 이력이 없는 건 |
| 세금코드 범위 | AA ~ AJ (사양서 지정 필수 조건) |
| 공급가액 · 세액 | 세액 테이블의 FWBAS · FWSTE |
| 마이너스 처리 | BSET 없음 + AI(영세) + 대변(H) → 부호 반전 |
| 품목 정보 | KIDNO 로 SD 함수 호출해 품목·규격·수량 수신 |
| 발행 단위 | 한 건씩만 — 계산서는 전표 하나에 한 장 |
| 발행 후 | 발행 이력에 기록되어 다음 조회에서 제외 |
BSET 없음을 화면에 표시하는 이유
금액이 마이너스로 나오는 이유를 담당자가 알아야 합니다. 숫자만 다르면 데이터 오류로 의심하지만, BSET 없음 표시가 함께 보이면 반품 영세율 건이라는 것이 드러납니다. 규칙을 코드 안에만 두지 않고 화면에 남기면 인수인계와 문의 대응이 쉬워집니다.
발행 팝업 구성 3영역
계산서 한 장에 필요한 값은 세 곳에서 모입니다.
| 영역 | 원천 | 자동으로 채워지는 값 | 직접 입력 |
|---|---|---|---|
| 공급자 | J_1BBRANCH · ADRC | 사업자번호 · 상호 · 대표자 · 주소 · 업태 · 종목 | 담당자 · e-Mail · 전화번호는 직접 입력 |
| 공급받는자 | KNA1 | 사업자번호 · 상호 · 대표자 · 주소 · 업태 · 종목 | 담당자 · e-Mail · 전화 · 종사업장번호 입력 |
| 계산서 본문 | 전표 · BSET · 빌링 | 전표번호 · 작성일자 · 세금코드 · 금액 | 품목 · 규격 · 수량 · 비고 수정 가능 |
마스터에 있는 값은 손대지 않고, 회사가 매번 정하는 담당자 정보만 입력받습니다.
조회조건
| 필드 | 필수 | 설명 |
|---|---|---|
| Company code | 필수 | 대상 회사코드 |
| Document date | 필수 | 기본값 당월 1일 ~ 오늘 |
| Tax code | 필수 | AA ~ AJ 범위 |
| Business Place · Customer | 선택 | 사업장·고객으로 범위 축소 |
| Posting Date · Document No. | 선택 | 전기일과 전표번호 |
| Sales Office | 선택 | 영업소 |
결과 컬럼
| 컬럼 | 의미 · 표시 |
|---|---|
| Business Place | 사업장 코드와 명칭 — 세금계산서 발행 단위 |
| DocumentNo · Fiscal Yr | AR 전표 키 |
| Doc..Date · Pstng Date | 증빙일과 전기일 |
| Customer · Customer명 | 공급받는자 |
| Tax Code · Tax code명 | 세금코드와 명칭 |
| 차대 | 차변/대변 — 반품 판정에 사용 |
| Base Amt · Amount · 합계 | 공급가액·세액과 합계. 마이너스는 △ 표기 |
| BSET | 세액 테이블 데이터 없음 표시 |
| Text · Sales Off. | 적요와 영업소 |
| 품목 · 규격 · 수량 | 빌링에서 받아온 정보 |
보조 기능
| 컬럼 | 의미 · 표시 |
|---|---|
| 선택 요약 | 선택 건수와 합계. 2건 이상이면 붉게 |
| 발행 팝업 | 마스터 정보 자동 구성 + 담당자 입력 |
| CSV | 조회 결과를 사양서 컬럼 순서 그대로 내려받기 |
SAP 표준 기능 매핑
발행은 외부 시스템이 수행합니다. 이 화면은 필요한 값을 모아 넘기고 이력을 남깁니다.
| 표준 | 역할 | 이 화면에서의 확장 |
|---|---|---|
BSID · BSAD | 미결·반제 AR 전표 | 발행 대상 원천 |
BSET | 세액 데이터 | 공급가액·세액 제공. 없으면 마이너스 판정 근거 |
J_1BBRANCH | 사업장 | 공급자 사업자번호·대표자·업태·종목 |
KNA1 | 고객 마스터 | 공급받는자 정보 일체 |
VBRK · SD 함수 | 빌링 문서 | 품목·규격·수량 |
FB03 · KD03 | 전표·고객 조회 | 전표번호·고객 더블클릭 시 이동 |
운영 데이터 소스 매핑
| 항목 | SAP 원천 | 비고 |
|---|---|---|
| AR 전표 | BSID · BSAD | BUKRS · BUPLA · GJAHR · BELNR · KUNNR · MWSKZ · SHKZG |
| 세액 | BSET | FWBAS · FWSTE |
| 발행 이력 | ZSB_HEADER | 이미 발행된 건 제외 기준 |
| 공급자 | J_1BBRANCH · ADRC | STCD2 · KR_REPRES · KR_BUSTYPE · KR_INDTYPE · NAME1 · CITY1 |
| 공급받는자 | KNA1 | STCD2 · NAME1 · J_1KFREPRE · ORT02 · STRAS · J_1KFTBUS · J_1KFTIND |
| 세금코드 명 | T007S | 세금코드 텍스트 |
도입 시 확인이 필요한 부분
세금코드 범위는 회사마다 다릅니다. 사양서는 AA~AJ 를 쓰지만 면세·불공제 코드가 다른 대역에 있으면 조회 조건을 함께 조정해야 합니다. 발행 시스템 연계 규격(승인번호 체계, 재발행·수정발행 처리)과 종사업장 번호 사용 여부도 영업·세무 담당과 먼저 정하는 편이 좋습니다.
참고 CDS 뷰
발행 대상을 조회할 때는 전표에 세액과 양쪽 마스터를 붙인 뷰가 편합니다.
@AbapCatalog.sqlViewName: 'ZCTAXINV'
@EndUserText.label: '세금계산서 발행 대상 (Z)'
define view Z_C_TAX_INVOICE_TARGET
as select from bsid as Item
left outer join bset as Tax on Item.bukrs = Tax.bukrs
and Item.belnr = Tax.belnr
and Item.gjahr = Tax.gjahr
left outer join kna1 as Customer on Item.kunnr = Customer.kunnr
left outer join j_1bbranch as Branch on Item.bukrs = Branch.bukrs
and Item.bupla = Branch.branch
left outer join t007s as TaxText on Item.mwskz = TaxText.mwskz
and TaxText.spras = 'K'
{
key Item.bukrs as Bukrs,
key Item.bupla as BusinessPlace,
key Item.gjahr as Gjahr,
key Item.belnr as Belnr,
Item.bldat as DocumentDate,
Item.budat as PostingDate,
Item.kunnr as Customer,
Customer.name1 as CustomerName,
Customer.stcd2 as CustomerTaxNo,
Branch.stcd2 as SupplierTaxNo,
Item.mwskz as TaxCode,
TaxText.text1 as TaxCodeName,
Item.shkzg as DebitCredit,
// BSET 가 없는 영세 대변 건은 부호를 반대로
case when Tax.fwbas is null and Item.mwskz = 'AI' and Item.shkzg = 'H'
then Item.dmbtr * -1 else Tax.fwbas end as BaseAmount,
Tax.fwste as TaxAmount,
Item.sgtxt as ItemText,
Item.kidno as PaymentRef
}발행 대상을 조회할 때 쓰는 참고용 설계입니다. 반제 전표는 BSAD 를 union 하고, 발행 이력 테이블로 제외 처리를 더합니다.
OpenUI5 구성
| 기능 | 사용 컨트롤 |
|---|---|
| 화면 골격 | sap.m.Page + 조회조건 영역 · 전표 목록 |
| 조회조건 | sap.m.Input · DatePicker · ComboBox — 우측 끝에 조회 |
| 전표 목록 | sap.ui.table.Table — 사업장·전표번호·연도 3컬럼 고정 |
| 마이너스 강조 | sap.m.ObjectStatus + RowSettings.highlight |
| 선택 제약 | 선택 요약 색으로 한 건 여부 표시 |
| 발행 팝업 | Fragment + sap.ui.layout.Splitter — 공급자·공급받는자 좌우 배치 |
| CSV | Blob + UTF-8 BOM — 사양서 컬럼 순서 |
공급자와 공급받는자를 좌우로 나눈 이유
실제 세금계산서 양식이 그렇게 생겼기 때문입니다. 위아래로 쌓으면 항목이 같은 이름끼리 멀어져 어느 쪽 사업자번호인지 헷갈립니다. 좌우로 두면 양식과 같은 배치라 눈으로 대조하기 쉽고, 비어 있는 담당자 칸도 한눈에 보입니다.
파일 구성
| 경로 | 역할 |
|---|---|
manifest.json | 앱 디스크립터 — 앱 ID(zui5.taxinv) · ko 로케일 · sap_horizon |
Component.js | 조회조건 모델 · 결과 모델 초기화 |
view/Main.view.xml | 조회화면 + 미발행 전표 목록 |
view/IssueDialog.fragment.xml | 세금계산서 발행 팝업 |
controller/Main.controller.js | 조회 · 선택 제약 · 발행 · CSV |
model/ModelMock.js | 미발행 조회 · 마스터 구성 · 발행 시뮬레이션 |
model/formatter.js | 금액(△ 표기) · 일자 · 차대 · BSET · 발행상태 포맷터 |
i18n/i18n_ko.properties | ko 로케일 리소스 — 사양서 메시지 원문 포함 |
localdata/taxinv.json | AR 전표·마스터 시뮬레이션 데이터 |
검증 결과
화면 구성에 쓴 데이터는 세금코드가 섞인 미발행 AR 전표와 마스터입니다.
| 데이터 | 규모 | 구성 |
|---|---|---|
| AR 전표 | 26건 | 세금코드 4종 · 고객 4곳 · 사업장 2곳 |
| 금액 | 공급가 92,000,000원 | 세액 6,790,000 · 마이너스 2건 |
| 특수 케이스 | 2건 | BSET 없는 AI 대변 건 (반품 빌링) |
| 검증 항목 | 결과 |
|---|---|
| 세금코드가 AA~AJ 범위 · 정의 목록에 존재 | 통과 |
| 사업장·고객·영업소가 마스터에 존재 | 통과 |
| 증빙일이 조회 기간 내 (당월 1일 ~ 오늘) | 통과 |
| BSET 없는 건은 AI + 대변(H) 조합만 | 통과 |
| BSET 없는 AI 대변 건은 공급가액이 마이너스 | 통과 |
| 세액 = 공급가액 × 세율 · 영세·면세는 0 | 통과 |
| 합계 = 공급가액 + 세액 | 통과 |
| 전표번호·KIDNO 중복 없음 · 모두 미발행 | 통과 |
| 공급자·공급받는자 마스터가 계산서 필수 항목 보유 | 통과 |
| 화면 렌더링 — 목록 → 제약 2종 → 팝업 → 발행 → 제외 | 11/11 |
고객·사업자번호·금액은 모두 검증용 데이터입니다.
자주 묻는 질문
왜 한 건씩만 발행하나요?
세금계산서는 전표 하나에 한 장이 대응하기 때문입니다. 여러 건을 묶어야 한다면 그것은 합산 처리의 몫이고, 이 화면은 이미 정리된 전표를 계산서로 옮기는 단계입니다. 사양서에도 두 건 이상이면 막도록 돼 있습니다.
반품 건은 왜 마이너스로 나오나요?
영세율 반품 건은 세액 테이블에 데이터가 남지 않습니다. 그래서 금액만 보면 일반 매출과 구분되지 않아, 계산서가 플러스로 발행될 수 있습니다. 세금코드가 영세이면서 대변인 경우 부호를 반대로 적용해 실제 방향을 반영합니다. 실무에서 나온 변경 요청으로 추가된 규칙입니다.
담당자 e-Mail 을 필수로 둔 이유는?
발행된 계산서가 전달될 주소이기 때문입니다. 비운 채로 발행하면 계산서는 만들어졌는데 상대방이 받지 못해, 나중에 재발행하거나 따로 보내야 합니다. 발행 전에 막는 편이 손이 덜 갑니다.
발행한 건은 어디로 가나요?
발행 이력 테이블에 기록되고 다음 조회부터 목록에서 빠집니다. 그래서 화면에 남아 있는 건이 곧 아직 끊지 않은 건입니다. 발행 여부를 따로 확인할 필요가 없습니다.
SAP 표준 기능과 어떻게 이어지나요?
전표와 세액은 BSID·BSAD·BSET 표준 구조 그대로이고, 공급자·공급받는자 정보도 사업장과 고객 마스터에서 가져옵니다. 이 화면은 그 값들을 계산서 형태로 모아 외부 발행 시스템에 넘기고, 돌아온 승인번호를 이력에 남기는 역할을 합니다.