SAP 리베이트 계약 현황 — 계약 기간은 끝났는데 정산은 안 끝났다
유효기간이 끝나도 시스템은 스스로 "이제 정산하세요"라고 말해주지 않습니다. 계약별 발생액과 기지급액을 맞대어 놓고, 아직 안 끝난 계약만 골라내는 화면입니다.
고객 리베이트 계약은 대개 1년 단위로 등록됩니다. 그 1년 동안 청구가 쌓이고, 쌓인 매출실적에 조건율을 곱해 리베이트가 계산되고, 분기마다 또는 계약이 끝나는 시점에 정산이 실행됩니다. 문제는 계약 유효기간이 끝난다고 시스템이 저절로 "이 계약은 이제 정산해야 합니다"라고 알려주지는 않는다는 점입니다. 최종정산(VBOF)을 실행하기 전까지는 발생액이 계속 잔액으로 남아 있을 뿐이고, 계약 건수가 수십 건을 넘어가면 담당자가 어느 계약을 놓쳤는지 눈으로 훑어보기 어려워집니다.
이 화면은 앞서 공개한 매출 가격조건 현황(조건 레코드의 유효기간 임박·만료를 보는 화면)과는 판정축이 다릅니다. 가격조건은 유효기간 하나만 보면 상태가 정해지지만, 리베이트 계약은 유효기간과 잔여발생액 두 축을 함께 봐야 "계약은 끝났는데 아직 정산이 안 된 건"을 가려낼 수 있습니다. SAP 표준 리베이트 계약(VBO1) 데이터 구조를 그대로 이어받아, 누적매출실적 → 발생리베이트(예상) → 기지급액 → 잔여발생액의 흐름과 선등록·진행중·정산예정·정산완료 4단계 상태를 화면에서 계산해 보여주도록 OpenUI5 화면으로 확장한 것이 ZLSD0090입니다. 실제 구동 화면 5종을 함께 공개합니다.
SAP 표준 기능을 그대로 이어받은 부분
- 계약 원천 — 계약 헤더(
KONA)와 조건레코드(KONP) 구조를 그대로 사용 - 정산 이력 — 리베이트 지급/정산 인덱스(
VBOX) 구조를 그대로 사용 - 실행 — 계약 생성/변경/조회는
VBO1·VBO2·VBO3, 최종정산은VBOF가 담당 - 매출실적 집계 — 청구 문서 전기 시 갱신되는 리베이트 관련 통계 구조를 그대로 이어받음
| 항목 | 내용 |
|---|---|
| 업무 영역 | 영업(SD) · 리베이트 계약 · 정산 모니터링 |
| Namespace | zui5.rebate |
| 셸 구조 | 조회조건 영역(우측 조회) + 계약 목록, 기본정보·월별 매출실적·정산이력 상세 Dialog |
| 화면 수 | 조회 화면 1개 + 상세 다이얼로그(탭 3개) |
| 대응 T-code | VBO1·VBO2·VBO3(계약 생성/변경/조회), VBOF(최종정산) |
| 성격 | 조회·모니터링형 — 계약 등록·정산 실행은 표준 트랜잭션이 담당 |
| UI 테마 | sap_horizon 단일 적용 |
실제 화면 5종 둘러보기
계약유형·판매조직·고객·정산상태·조회 기준일을 넣고 조회하면 계약이 목록으로 뜹니다 → 계약번호로 다시 좁혀보고 → 계약을 골라 기본정보·월별 매출실적·정산이력을 확인합니다.
아래는 실제로 앱을 실행해 기능을 눌러 가며 캡처한 화면입니다. 이미지를 클릭하면 원본 크기로 확대됩니다.
조작 방법
- 계약번호·계약유형·판매조직·고객·정산상태는 필터로 좁혀볼 수 있으며, 계약번호·고객은 코드나 이름 일부만 입력해도 부분일치로 걸립니다.
- 조회 기준일 기본값은 오늘입니다. 날짜를 바꾸면 그 시점 기준으로 정산상태가 다시 계산됩니다.
- 조회조건 입력필드에서 Enter 를 눌러도 바로 재조회됩니다. 조회·초기화 버튼은 조회조건 영역 오른쪽 끝에 있습니다.
- 목록에서 행을 클릭하면 상세 다이얼로그가 열립니다. 기본정보·월별 매출실적·정산이력 세 탭을 오갑니다.
- 정산이력이 없는 계약(아직 한 번도 정산되지 않은 계약)은 "정산 이력이 없습니다"로 표시됩니다.
- 목록은 CSV 다운로드로 내려받습니다. 현재 필터링된 결과만 담기며, UTF-8 BOM 이 붙어 엑셀에서 한글이 깨지지 않습니다.
정산 상태 4단계 판정 로직
이 화면의 핵심은 목록이 아니라 조회 기준일 대비 재계산입니다. 표준 트랜잭션은 계약 유효기간이 끝나도 자동으로 "정산 필요" 표시를 하지 않으므로, 이 화면이 유효기간과 잔여발생액 두 축을 함께 보고 담당자가 놓치기 쉬운 상태를 대신 판정합니다.
| 상태 | 판정 조건 |
|---|---|
| 선등록 | 조회 기준일이 유효개시일보다 이름 (계약은 등록되었으나 개시 전) |
| 진행중 | 조회 기준일이 유효기간 내 (매출실적이 계속 누적되는 중) |
| 정산예정 | 유효종료일이 지났고 잔여발생액이 0보다 큼 (최종정산 미실행) |
| 정산완료 | 유효종료일이 지났고 잔여발생액이 0 (최종정산 완료) |
유효기간만으로는 판정할 수 없는 이유
유효기간만 보면 계약기간이 끝난 계약은 전부 "만료"로 묶이지만, 그중 상당수는 아직 리베이트가 정산되지 않은 채 잔액으로 남아 있습니다. 잔여발생액이라는 두 번째 축을 더해야 "정산까지 끝난 계약"과 "정산이 필요한 계약"을 구분할 수 있고, 후자만 상단 경고 스트립으로 따로 알립니다.
리베이트 발생액 계산 5단계
계약 하나의 발생액이 얼마인지 확정하기까지, 화면이 참고자료로 정리한 처리 흐름입니다.
| 단계 | 내용 |
|---|---|
| ① 청구 실적 집계 | 계약 유효기간 내 청구 문서에서 발생한 매출실적을 월 단위로 집계합니다. |
| ② 누적매출실적 산출 | 집계된 월별 실적을 계약 시작일부터 조회 시점까지 합산합니다. |
| ③ 조건 적용 | 매출액 기준(%) 계약은 누적매출실적 × 조건율, 정액 계약은 환산단위 × 단가로 계산하고, 계약한도액이 있으면 그 값으로 상한을 둡니다. |
| ④ 기지급액 차감 | 부분정산·최종정산 이력의 합계를 발생리베이트에서 차감해 잔여발생액을 구합니다. |
| ⑤ 상태 판정 | 위 4단계 판정 로직으로 화면 표시 상태를 재계산합니다. |
실제 정산 실행(리베이트 크레딧 메모 발행)은 표준 트랜잭션(VBOF)이 담당하며, 이 화면은 그 이전 단계의 수치를 투명하게 보여주는 역할만 합니다.
조회조건
| 필드 | 필수 | 설명 |
|---|---|---|
| 계약번호 | 선택 | 부분일치, Enter 로 즉시 조회 |
| 계약유형 | 선택 | 데이터에 존재하는 값만 자동으로 목록에 노출 |
| 판매조직 | 선택 | 데이터에 존재하는 값만 자동으로 목록에 노출 |
| 고객 | 선택 | 고객코드 또는 고객명 부분일치 |
| 정산상태 | 선택 | 전체/선등록/진행중/정산예정/정산완료 |
| 조회 기준일 | 선택 | 기본값 오늘. 정산상태 재계산의 기준 |
결과 컬럼
| 컬럼 | 의미 · 표시 |
|---|---|
| 계약번호 · 계약유형 | 코드 + 명칭 |
| 판매조직 · 고객 | 코드 + 명칭 |
| 조건유형 · 조건율/단가 | 매출액 기준(%) 또는 정액(원/단위) |
| 유효개시일 · 유효종료일 | YYYY-MM-DD |
| 누적매출실적 | 월별 매출실적 합계, 우측정렬 |
| 발생리베이트(예상) | 누적매출실적에 조건을 적용한 계산값 |
| 기지급액 | 정산이력 합계 |
| 잔여발생액 | 발생리베이트 − 기지급액 |
| 정산진행률 | 기지급액 / 발생리베이트 (%) |
| 정산상태 | 선등록/진행중/정산예정/정산완료 + D-day |
| 최종정산일 · 변경자 | 가장 최근 정산일자, 최종 변경 이력 |
SAP 표준 기능 매핑
이 화면이 조회하는 데이터와 판정 기준은 SAP 표준 리베이트 처리 구조를 그대로 이어받습니다. 표준 실행은 VBO1·VBO2·VBO3(계약 생성·변경·조회)과 VBOF(최종정산)가 담당하고, 이 화면은 그 결과를 정산 진행 관점에서 확장한 것입니다 — 실행 자체를 대체하지 않습니다.
| 표준 기능 | T-code | 본 화면과의 관계 |
|---|---|---|
| 리베이트 계약 생성/변경/조회 | VBO1 · VBO2 · VBO3 | 본 화면이 조회하는 원천 계약 데이터 |
| 리베이트 최종정산 | VBOF | 정산예정 상태인 계약이 실행 대상 |
| 조건유형 마스터 | V/06 하위 설정 | 조건유형(BO01/BO02/BO03) 코드/명칭 표시에 사용 |
참고 CDS 뷰
운영 서비스로 연결할 때는 계약 헤더·조건·정산이력을 결합한 뷰로 서빙하는 구성을 제안합니다.
@AbapCatalog.sqlViewName: 'ZLSDREBATE'
@EndUserText.label: '리베이트 계약 현황 조회용 (Z)'
define view Z_C_RebateAgreementStatus
as select from kona as Agreement
inner join konp as Condition on Condition.knumh = Agreement.knumh
left outer join vbox as Settlement on Settlement.knuma_pi = Agreement.knuma
{
key Agreement.knuma as AgreementNo,
Agreement.botyp as AgreementType,
Agreement.vkorg as SalesOrg,
Agreement.datab as ValidFrom,
Agreement.datbi as ValidTo,
Agreement.bonba as CapAmount,
Condition.kschl as ConditionType,
Condition.kbetr as Rate,
sum(Settlement.bonba) as PaidAmount,
// 발생리베이트는 누적매출실적(별도 집계) × Rate 로 애플리케이션 레이어에서 계산,
// CapAmount 가 있으면 상한 적용
case when Agreement.datbi < $session.system_date and sum(Settlement.bonba) < 0
then 'DUE' else 'ACTIVE' end as StatusHint
}
group by Agreement.knuma, Agreement.botyp, Agreement.vkorg,
Agreement.datab, Agreement.datbi, Agreement.bonba,
Condition.kschl, Condition.kbetr
매핑 이해를 돕기 위한 참고용 설계입니다. 실제 도입 시에는 누적매출실적 집계 원천(청구 실적 갱신 구조)과 정산이력 테이블의 커스터마이징 여부를 함께 확인해야 합니다.
OpenUI5 구성
| 기능 | 사용 컨트롤 |
|---|---|
| 화면 골격 | sap.f.DynamicPage — 조회조건 헤더 + 결과 그리드 |
| 조회조건 | sap.m.FlexBox(wrap) — 좁은 화면에서 버튼이 overflow 메뉴에 숨는 것을 피하려 OverflowToolbar 대신 사용, 우측 끝에 조회 버튼 고정 |
| 결과 그리드 | sap.ui.table.Table — 컬럼 15개, selectionBehavior=RowOnly로 행 클릭 즉시 상세 진입 |
| 상세 | sap.m.Dialog + IconTabBar(기본정보 · 월별 매출실적 · 정산이력) + sap.m.Table |
| 모델 | ModelMock — localdata JSON 을 fetch + Promise 로 제공(OData 미구현) |
| 포맷 | 금액·조건율·상태·D-day·진행률 표시 포맷터 |
파일 구성
| 경로 | 역할 |
|---|---|
index.html | OpenUI5 부트스트랩 — sap_horizon · lodash · moment |
Component.js | 디바이스 모델 초기화 |
manifest.json | 앱 디스크립터 — 앱 ID(zui5.rebate) · ko 로케일 |
view/Main.view.xml · view/DetailDialog.fragment.xml | 조회조건 · 결과 그리드 · 상세 다이얼로그(3탭) |
controller/Main.controller.js | 정산상태 재계산 · 조회 · 상세 · CSV |
model/ModelMock.js | localdata JSON 읽기(Promise) |
model/formatter.js | 금액 · 조건율 · 상태 · D-day · 진행률 표시 포맷 |
i18n/i18n_ko.properties | ko 로케일 리소스 |
localdata/rebate.json | 리베이트 계약 46건(월별 매출실적·정산이력 포함) 검증용 데이터 |
운영 전환 시에는 ModelMock 내부만 실제 서비스 호출로 바꾸면 화면과 판정 로직은 그대로 씁니다.
검증 결과
화면 구성에 쓴 데이터는 리베이트 계약 46건(정산예정 8건 · 진행중 24건 · 정산완료 14건)이며, 발생액·정산액 항등식까지 전수 검증했습니다.
| 검증 항목 | 결과 |
|---|---|
| Σ(월별 매출실적) = 누적매출실적 (46건 전수) | 통과 |
| 누적매출실적 × 조건율 [계약한도액 상한 적용] = 발생리베이트(예상) | 통과 |
| Σ(정산이력 금액) = 기지급액 | 통과 |
| 발생리베이트 − 기지급액 = 잔여발생액 | 통과 |
| 기지급액 ≤ 발생리베이트 (초과지급 없음, 46건 전수) | 통과 |
| XML/JSON 전체 파싱 · i18n 키 누락 0건 · 이벤트 핸들러 미구현 0건 | 통과 |
| 조회 버튼이 조회조건 영역 오른쪽 끝에 위치 | 통과 |
| Enter 키 입력으로 즉시 재조회 | 통과 |
| 적용 테마 sap_horizon 확인 | 통과 |
| 화면 렌더링 — 실브라우저에서 조회 → 필터 → 상세(3탭) 실동작 후 캡처 | 5/5 |
고객·계약번호·금액은 모두 검증용 데이터입니다.
자주 묻는 질문
이 화면에서 실제 최종정산(VBOF)을 실행할 수 있나요?
아니요. 이 화면은 조회·모니터링 전용이며, 실제 정산 실행은 표준 트랜잭션(VBOF 등)에서 이루어집니다.
"발생리베이트(예상)" 금액은 확정 금액인가요?
아닙니다. 조회 시점까지 집계된 매출실적을 기준으로 계산한 예상치이며, 계약기간이 남아있는 계약은 이후 매출실적에 따라 달라질 수 있습니다.
"정산예정" 상태는 무엇을 의미하나요?
계약 유효기간(유효종료일)이 지났지만 잔여발생액이 남아 있어 최종정산이 아직 실행되지 않은 계약입니다. 우선 확인이 필요합니다.
계약한도액(Cap)이 설정된 계약은 어떻게 계산되나요?
매출실적 기준으로 계산한 발생리베이트가 계약한도액을 초과하면 한도액으로 상한(capping)을 적용합니다.