수익성 분석

프로모션 증분 공헌이익 점검 — 할인 행사가 정말 이익을 남겼는지 기준선·잠식·선취까지 걷어내 확인하는 수익성 분석

증분 수량 · 할인 잠식 · 직접 판촉비 · 후속 4주 선취 수요 감소 · 판촉 수익률과 손익분기 증분 수량 · 제품군·채널 요약 · 15개 대사식 — 소개 영상과 실제 화면 7종, 그리고 CDS 코드까지

소개 영상블로그 목차 순서대로 · 자막 포함8개 장면첫 화면 → 조회조건 → 점검 필요 → 손익 요인 → 제품군·채널 → 상세 → 대사 → 유의사항

도입 포인트 — 이 앱을 사용해야 하는 이유

판촉 행사가 끝나면 늘 같은 질문이 남습니다. 정말 이익이 남았나, 평소에 팔릴 것을 싸게 판 것은 아닌가, 행사 뒤에 판매가 꺼지지는 않았나. 지금은 이 세 답이 매출 증가율 · 엑셀 계산 · 담당자의 기억으로 흩어져 있습니다. 이 화면은 세 답을 한 행에 붙여, 행사 사후 평가를 만드는 손일을 줄이고 “성공이었다”는 말이 어디까지 맞는지 확인할 순서를 정해 줍니다.

한 줄 요약 — 행사 기간 매출은 누구나 셉니다. 이 화면의 값은 그 다음에 있습니다: 평소에도 팔렸을 기준선을 걷어내 증분만 보고, 할인 잠식과 판촉비와 후속 4주 선취를 비용으로 세워 남은 공헌이익을 계산합니다. 그리고 그 숫자가 15개 대사식과 어긋나지 않는지 전수로 검산합니다. 점검 필요 표시는 원인을 단정하지 않으며 최종 판단은 회사와 감사인이 합니다.

핵심 포인트 여덟 가지

포인트고객이 얻는 것지금 방식이라면
① 늘어난 판매량이 아니라 증분만 봅니다행사 실적에서 평소에도 팔렸을 기준선 수량을 빼, 행사 때문에 더 팔린 수량(증분)과 그 공헌이익만 따로 셉니다.행사 기간 매출이 지난해보다 늘었다는 보고서로 성공을 판단합니다.
② 할인 잠식을 비용으로 세웁니다기준선 수량 × (정상가 − 행사 단가) 를 할인 잠식액으로 잡아, 원래 살 사람에게 준 할인을 숨기지 않습니다.할인율만 보고 마진이 줄었다는 사실은 알아도 얼마인지는 엑셀로 따로 계산합니다.
③ 행사가 끝난 뒤 4주까지 봅니다후속 4주 실적이 기준선보다 줄어든 만큼(선취 수요 감소)을 정상 단위 공헌이익으로 곱해 한 번 더 뺍니다.행사 종료일에 평가를 끝내 미리 당겨 판 수요를 알아채지 못합니다.
④ 손익 요인 네 가지를 나란히증분 공헌이익·할인 잠식·직접 판촉비·선취 감소를 행마다 금액과 산식으로 보여 주고, 합이 선취 반영 순 공헌이익과 같은지 검산합니다.요인마다 다른 리포트를 열어 숫자를 맞춥니다.
⑤ 판촉 수익률과 손익분기 증분 수량선취 반영 순 공헌이익 ÷ 투입 비용 합계로 수익률을 내고, 손익분기에 필요한 증분 수량과 실제를 견줍니다.'얼마나 팔았어야 본전이었나' 를 행사가 끝난 뒤에야 계산합니다.
⑥ 제품군·채널로 묶어 봅니다제품군 6개·채널 5개로 같은 지표를 합산하고, 점검 필요 행사 비율이 높거나 합계가 음수이면 그 자리를 표시합니다.행사 단위 점검 결과를 사람이 손으로 묶어 보고합니다.
⑦ 예외는 분리하고 대사는 전수로후속 4주 실적이 아직 없는 행사는 판정에서 빼 따로 세고, 15개 대사식을 전수로 돌려 차이 0 을 확인합니다.집계가 덜 끝난 행사가 섞여 합계가 조용히 틀어집니다.
⑧ 원인을 단정하지 않는 점검 도구점검 필요는 확인 순서를 정해 주는 표시일 뿐 원인을 단정하지 않습니다. 최종 판단은 회사와 감사인이 합니다.화면이 결론을 내려 버려 검토가 생략됩니다.

사례로 보는 효과 — 증분 공헌이익 8.4억이 1.3억이 되는 과정

검증용 샘플의 판정 대상 행사 28건(후속 4주 실적이 없는 2건 제외)을 단계별로 걷어 보면 이렇습니다. 증분 공헌이익만 보면 26건이 흑자이고 합계는 8.38억원입니다. 여기서 할인 잠식 4.57억원과 직접 판촉비 1.81억원을 빼면 행사 순 공헌이익은 20건이 흑자, 합계 2.00억원이 됩니다. 마지막으로 후속 4주 선취 감소 0.70억원까지 빼면 흑자 행사는 18건, 선취 반영 순 공헌이익 합계는 1.30억원입니다. 투입 비용 합계 7.08억원 기준 판촉 수익률은 18.31% 입니다.

행사 하나를 보면 차이는 더 분명합니다. 정상가 대비 50% 할인 행사 두 건은 증분 수량이 늘어도 단위 공헌이익이 0 이하라 팔수록 손해였고, 다른 한 건은 행사 기간만 보면 1,530만원 흑자였지만 후속 4주 수요 감소를 반영하자 406만원 적자로 돌아섰습니다. 매출 증가율만 봤다면 모두 “성공한 행사”로 보였을 숫자입니다. 다만 이 표시는 점검 필요일 뿐, 가격 입력 오류인지 의도된 미끼 상품인지는 화면이 판단하지 않고 확인 순서만 정해 줍니다.

행사 하나마다
증분 공헌이익 = (실적 수량 − 기준선 수량) × 행사 단위 공헌이익  ·  할인 잠식 = 기준선 수량 × (정상가 − 행사 단가)

선취 감소 = max(후속 4주 기준선 − 후속 4주 실적, 0) × 정상 단위 공헌이익  ·  선취 반영 순 공헌이익 = 증분 공헌이익 − 할인 잠식 − 직접 판촉비 − 선취 감소

판촉 수익률 = 선취 반영 순 공헌이익 ÷ (직접 판촉비 + 할인 잠식 + 선취 감소) × 100. 네 요인의 합이 선취 반영 순 공헌이익과 어긋나면 화면의 대사 결과에 차이 건수로 드러납니다.

도입하면 달라지는 것

  • 행사 평가의 시점 — 종료일이 아니라 후속 4주까지 본 뒤에 판정하므로 미리 당겨 판 수요가 이익으로 보이지 않습니다.
  • 회의의 주제 — “얼마나 팔았나”가 아니라 “얼마가 남았나, 어디가 약한가”를 이야기합니다.
  • 제품군·채널 비교 — 같은 지표가 제품군 6개·채널 5개로 합산되어 약한 자리가 한눈에 보입니다.
  • 숫자를 믿는 근거 — 15개 대사식과 의도적 예외가 화면에 그대로 나와 “이 숫자 맞아?”에 바로 답할 수 있습니다.

실행 화면

실제로 돌아가는 화면 7종을 순서대로 싣습니다. 그림을 누르면 크게 볼 수 있고, 화면마다 무엇을 하는 자리인지 아래에 적었습니다. 숫자는 모두 가상의 검증용 샘플에서 나온 것이라 화면끼리 서로 맞춰 보셔도 됩니다.

조회하고 걸러내기

처음 열었을 때 — 요약 지표와 행사 30건
처음 열었을 때 — 요약 지표와 행사 30건 — 회계연도 2026 으로 행사 30건을 조회한 첫 화면입니다. 위쪽 요약에 증분 공헌이익·할인 잠식·직접 판촉비·선취 감소·선취 반영 순 공헌이익 합계가 백만원 단위로 나옵니다.

조회조건은 회계연도·제품군·채널·행사 시작일 범위·점검 결과이고, 조회 버튼은 조건 영역 오른쪽 끝에 있습니다. 회계연도 입력 칸에서 Enter 키를 눌러도 조회됩니다. 요약 지표는 후속 4주 실적이 없는 예외 행사를 빼고 더합니다.

점검 필요만 조회
점검 필요만 조회 — 점검 결과를 점검 필요로 고르고 조회하면 적자이거나 수익률이 기준에 못 미치는 행사 12건만 남습니다.

점검 필요는 네 가지로 나뉩니다. 단가가 변동비 이하인 행사, 행사 기간만 보면 흑자지만 후속 4주 선취 감소를 반영하면 적자인 행사, 행사 순 공헌이익이 적자인 행사, 흑자지만 수익률이 기준(10.00%)에 못 미치는 행사입니다. 표시는 원인을 단정하지 않고 확인 순서만 정해 줍니다.

요인과 요약

손익 요인 명세 탭
손익 요인 명세 탭 — 행사마다 증분 공헌이익·할인 잠식·직접 판촉비·선취 수요 감소 네 요인을 금액과 산식으로 나란히 보여 줍니다.

네 요인 금액을 더하면 선취 반영 순 공헌이익이 되도록 맞춰 두었고, 구성비와 산식 칸이 함께 있어 숫자가 어디서 나왔는지 바로 읽힙니다. 이 합은 대사식 R09 로 전수 검증합니다.

제품군 요약 탭
제품군 요약 탭 — 제품군별 요인 합계와 판촉 수익률, 점검 필요 행사 비율입니다.

비율이 40% 이상이거나 선취 반영 순 공헌이익 합계가 음수이면 그 제품군을 점검 필요로 표시합니다. 예외 행사는 분모와 합계에서 뺍니다.

채널 요약 탭
채널 요약 탭 — 대형마트·온라인몰 등 채널별로 같은 지표를 모아 어느 채널에서 행사 수익이 약한지 봅니다.

제품군과 채널은 같은 행사 판정 행을 서로 다른 축으로 합산한 것이라 두 요약의 순 공헌이익 합계는 같습니다(대사식 R13·R14).

근거까지 내려가기

행 클릭 상세
행 클릭 상세 — 행사 행을 누르면 판정 근거와 손익 요인 명세가 한 창에 모입니다.

제품군·채널 행을 누르면 소속 행사 목록이 열립니다. 손익분기 증분 수량과 실제 증분 수량을 견주면 얼마나 모자랐는지 가늠할 수 있습니다. 닫기 버튼으로 원래 화면으로 돌아옵니다.

대사 결과 탭
대사 결과 탭 — 15개 대사식의 검사 건수와 차이 건수입니다.

후속 4주 실적이 아직 모이지 않은 행사 2건은 의도적 예외로 따로 기록하고, 대사 차이 건수에는 넣지 않습니다.

사용 순서

  1. 조회조건 입력 — 회계연도(필수)를 확인하고 제품군·채널·행사 시작일 범위·점검 결과를 고릅니다. 비워 두면 전체입니다.
  2. 조회 — 조건 영역 오른쪽 끝의 조회 버튼을 누르거나 회계연도 칸에서 Enter 키를 누릅니다.
  3. 요약 확인 — 위쪽 7개 지표로 전체 윤곽을 봅니다.
  4. 탭 이동 — 행사 판정 → 손익 요인 명세 → 제품군 요약 → 채널 요약 → 대사 결과 순으로 근거까지 좁혀 갑니다.
  5. 행 클릭 상세 — 행을 누르면 손익 요인이나 소속 행사가 상세 창에 열립니다.
  6. CSV 내려받기 — 현재 탭의 결과를 UTF-8 CSV 로 내려받습니다.

점검 결과가 정해지는 규칙

판정 조건결과다음에 확인할 곳
후속 4주 실적이 아직 모이지 않은 행사정상 · EXC-POST (의도적 예외)판정과 합계에서 빼고, 집계 뒤 다시 조회합니다.
행사 단가가 단위 변동비 이하점검 필요 · PRM-LOSS가격 조건과 변동비 산정 근거를 원천에서 확인합니다.
행사 기간은 흑자이나 선취 반영 후 적자점검 필요 · PRM-DIP후속 4주 실적과 기준선 산정을 확인합니다.
행사 순 공헌이익이 음수점검 필요 · PRM-NEG증분 수량이 손익분기에 얼마나 모자랐는지 확인합니다.
흑자이나 판촉 수익률이 기준(10.00%) 미만점검 필요 · PRM-LOW판촉비 집행 내역과 할인율 설정을 확인합니다.
선취 반영 후에도 수익률이 기준 이상정상 · PRM-GAIN조치 없음

검증 결과 — 15개 대사식과 예외 1종

검증용 샘플은 가상의 제품군 6개 · 채널 5개 · 행사 30건 · 손익 요인 120행입니다. 대사식 15개는 모두 차이 0 이고(R11 최대 차이는 소수 둘째 자리 반올림 폭 이내), 후속 4주 실적이 없는 행사 2건은 R16 에 의도적 예외로 따로 기록했습니다. 별도의 독립 계산 스크립트로도 다시 확인했습니다.

번호대사 항목최대 차이검사 건수차이 건수
R01정상가 × (1 − 할인율) = 행사 단가 (행사 명세)0300
R02기준선 일평균 × 행사 일수 = 기준선 수량0300
R03행사 실적 수량 − 기준선 수량 = 증분 수량0300
R04증분 수량 × 행사 단위 공헌이익 = 증분 공헌이익0300
R05기준선 수량 × (정상가 − 행사 단가) = 할인 잠식액0300
R06증분 공헌이익 − 할인 잠식 − 직접 판촉비 = 행사 순 공헌이익0300
R07(행사 기간 공헌이익 − 기준선 공헌이익) − 판촉비 = 행사 순 공헌이익0300
R08행사 순 공헌이익 − 선취 감소 공헌이익 = 선취 반영 순 공헌이익0280
R09요인 명세 금액 합계 = 선취 반영 순 공헌이익0280
R10직접 판촉비 + 할인 잠식 + 선취 감소 공헌이익 = 투입 비용 합계0280
R11선취 반영 순 공헌이익 ÷ 투입 비용 합계 = 판촉 수익률 (소수 둘째 자리 반올림)0.004881280
R12선취 반영 순 공헌이익이 음수인 행사 = 증분 수량이 손익분기 증분 수량보다 작은 행사0260
R13제품군 순 공헌이익 합계 = 행사 순 공헌이익 합계010
R14채널 순 공헌이익 합계 = 행사 순 공헌이익 합계010
R15제품군·채널 점검 필요 행사 수 합계 = 행사 판정의 점검 필요 건수020
R16후속 4주 실적 미집계 행사 (선취 반영 판정 제외)022

SAP 표준 기능 확장 포인트

이 화면은 SAP 표준을 대체하지 않습니다. 표준이 이미 잘하는 일은 표준에 맡기고, 표준이 끊기는 자리만 이어 붙이는 쪽으로 만들었습니다. 어디까지가 표준이고 어디서부터 이 화면인지를 먼저 적습니다.

표준으로 되는 것과 안 되는 것

하고 싶은 일SAP 표준표준에서 걸리는 자리이 화면이 하는 일
수익성 분석 보고서KE30실적 집계 중심이라 행사 단위 기준선·잠식이 없습니다행사 단위로 기준선과 잠식을 걷어낸 증분을 더합니다
개별 항목 확인KE24항목 단위라 행사로 묶어 보려면 따로 합쳐야 합니다행사 행에서 합계 근거를 확인할 자리를 이어 줍니다
행사 기간 실적 수량VA03 · VF03오더·청구 단위라 행사 기간 합계는 사람이 모읍니다행사 기간·후속 4주 수량을 행사 행에 모읍니다
가격·할인 조건VK13조건 레코드는 있어도 행사와 실적을 잇는 화면이 없습니다정상가·행사 단가·할인율 대응을 한 행에 둡니다
증분 판정없음표준에 없습니다. 보통 엑셀로 만듭니다기준선을 걷은 증분과 잠식·선취를 계산하고 검산합니다
행사 사후 평가 기록없음점검 결과를 남길 곳이 따로 없습니다점검 코드와 내용을 행에 남기고 CSV 로 내려받습니다

표준 기능과 이어 쓰는 순서

  1. 화면에서 점검 필요 행사를 고릅니다. 제품군·채널 요약으로 약한 자리를 먼저 찾습니다.
  2. 합계를 표준 수익성 보고서(KE30)와 맞춰 봅니다. 제품군·채널 합계가 어긋나면 기간·조회 범위부터 확인합니다.
  3. 개별 항목(KE24)으로 내려가 판촉비와 매출의 원천 전기를 확인합니다.
  4. 행사 기간 수량의 원천 오더·청구(VA03 · VF03)를, 단가·할인이 설정대로 적용됐는지 조건(VK13)을 확인합니다.

표준에 없는 자리

기준선을 걷어낸 증분 판정과 후속 4주 선취 반영은 표준에 없습니다. 이 화면이 그 계산을 하고, 계산에 쓴 가정(기준선 산정 방식, 관찰 기간 4주, 수익률 기준 10%)을 모두 샘플 값으로 밝혀 둡니다. 운영에서는 이 가정을 회사 기준에 맞춰 정해야 하며, 그 결정이 도입에서 가장 큰 일입니다.

정해야 할 것정하지 않으면결정 주체
기준선 산정 방식행사 효과가 과대·과소 평가되어 첫 회의에서 막힙니다기획팀 · CO
판촉비 계정 매핑직접 판촉비가 누락되거나 이중으로 잡힙니다회계팀
선취 관찰 기간·반영 여부행사 뒤 수요 감소를 보는 기준이 사람마다 달라집니다기획팀
판촉 수익률 기준점검 필요 표시 범위가 현업 감각과 어긋납니다경영지원
제품군·채널 구분집계 단위가 달라 표준 보고서와 합계가 어긋납니다CO · 영업
후속 실적 집계 시점미집계 행사가 판정에 섞입니다영업관리

OData 서비스 계약

화면은 manifest 에 선언한 상대 경로의 OData V2 서비스 하나만 부릅니다. 서비스 이름은 소문자 promoprofit_srv 이고 엔티티셋 5개(PromoSet · FactorSet · GroupSet · ChannelSet · ReconSet)와 펑션 2개(GetMinRoi · GetMaxRoi)를 노출합니다. 조회조건은 모두 $filter 로, 정렬·페이징은 $orderby · $top · $skip 으로 보내고 총건수는 $inlinecount=allpages 로 받습니다. 날짜 범위 조건은 서비스가 직접 처리합니다.

CDS 구성

이 사례의 화면은 샘플 데이터를 서비스가 들고 계산합니다. 데모라서 되는 일이고, 운영 데이터에서는 그렇게 하지 않습니다. 운영으로 올릴 때 가장 먼저 하는 일이 계산을 CDS 로 내리는 것입니다. 아래는 그때 만드는 뷰의 스케치입니다.

코드는 스케치입니다. 필드 이름과 표준 뷰 이름은 릴리스·환경에 따라 다르므로, 그대로 붙여 넣기 전에 View Browser(F2170) 로 실제 이름을 확인해야 합니다. 확인이 필요한 자리는 주석에 적어 두었습니다.

뷰 레이어 구성

레이어뷰하는 일왜 나누나
기준ZPRM_COSTMAP판촉비 계정 → 비용 구분 매핑계정은 늘 늘어납니다. 코드에 박으면 늘어날 때마다 개발자를 부르게 됩니다.
기준ZI_PromoEvent행사 코드·기간·정상가·행사 단가행사 원천이 바뀌어도 이 뷰만 고치면 됩니다.
계산ZI_PromoBaseline행사 직전 일평균 기준선기준선 산정 방식은 회사가 정하므로 따로 뺍니다.
계산ZI_PromoActual행사 기간·후속 4주 실적과 미집계 표시미집계 행사를 판정에서 빼는 규칙을 한 곳에 둡니다.
큐브ZI_PromoProfit증분·잠식·판촉비·선취화면이 들고 계산하던 일을 DB 로 내립니다.
소비ZC_PromoProfitCheck점검 결과·OData 노출점검 기준(수익률 10%)을 한 번만 정의합니다.
권한ZI_PROMOGROUPSUM (DCL)제품군 권한집계를 읽는 자리에 걸어야 뺄셈으로 새지 않습니다.

① 판촉비 계정 매핑 테이블

행사에 직접 쓴 광고·진열·수수료가 어느 계정인지 정하는 자리입니다. 직접 판촉비가 이중으로 잡히거나 빠지면 모든 행사의 수익률이 같이 틀어지므로 운영 전환에서 가장 먼저 합의해야 하는 항목입니다. 유효기간을 둔 이유는 계정 체계가 바뀌어도 과거 행사 판정이 달라지지 않게 하려는 것입니다.

" ────────────────────────────────────────────────────────────────
"  ZPRM_COSTMAP — 판촉비 계정 → 행사 비용 구분 매핑 (투명 테이블)
"  구분: 1 광고  2 진열  3 판매수수료  4 기타 직접비
" ────────────────────────────────────────────────────────────────
define table zprm_costmap {
  key client     : abap.clnt not null;
  key bukrs      : bukrs not null;
  key saknr      : saknr not null;          " 판촉비 계정 (확인 필요: 계정 체계)
  key valid_from : abap.dats not null;
      valid_to   : abap.dats;
      cost_kind  : abap.char(1);            " 1 광고 / 2 진열 / 3 수수료 / 4 기타
      direct     : abap_boolean;            " 직접 판촉비로 셀지 여부
}
" 매핑에 없는 계정은 직접 판촉비 0 으로 떨어지므로, 마감 전에 미분류 계정 점검 목록을 따로 둔다.

② 행사 마스터와 기간 뷰

행사 코드·기간·대상 제품군·채널을 한 줄로 세우는 기준 뷰입니다. 행사 정보가 어느 테이블에 있는지는 회사마다 다르므로 원천 선택은 확인 필요로 남겨 두었습니다.

@AbapCatalog.viewEnhancementCategory: [#NONE]
@EndUserText.label: '행사 기준 — 코드 · 기간 · 대상'
define view entity ZI_PromoEvent
  as select from zprm_event as e          " 확인 필요: 행사 계약/조건 원천 테이블
{
  key e.promo_id                          as PromoId,
      e.bukrs                             as CompanyCode,
      e.prod_grp                          as ProdGrp,
      e.channel                           as Channel,
      e.start_date                        as StartDate,
      e.end_date                          as EndDate,
      dats_days_between( e.start_date, e.end_date ) + 1  as Days,
      e.list_price                        as ListPrice,
      e.disc_rate                         as DiscRate,
      cast( e.list_price * ( 100 - e.disc_rate ) / 100 as abap.dec(15,0) ) as PromoPrice
}

③ 기준선 뷰 — 행사 직전 일평균

행사가 없었다면 팔렸을 수량을 가늠하는 자리입니다. 샘플은 행사 직전 28일의 일평균을 쓰지만, 계절성·요일·직전 행사 영향을 걸러내는 방식은 회사가 정해야 합니다. 기준선이 바뀌면 증분·잠식이 같이 바뀌므로 이 뷰 하나만 고치면 되게 따로 뺐습니다.

@EndUserText.label: '행사 기준선 — 직전 28일 일평균'
define view entity ZI_PromoBaseline
  as select from ZI_PromoEvent as ev
    inner join   ZI_DailySales   as s            " 확인 필요: 일별 판매 수량 뷰(청구/CO-PA)
      on  s.ProdGrp  = ev.ProdGrp
      and s.Channel  = ev.Channel
      and s.PostDate >= dats_add_days( ev.StartDate, -28, 'INITIAL' )
      and s.PostDate <  ev.StartDate
{
  key ev.PromoId,
      cast( sum( s.Qty ) / 28 as abap.int4 )  as BaseDaily,
      cast( sum( s.Qty ) / 28 * ev.Days as abap.int4 ) as BaseQty
      // 직전 기간에 다른 행사가 겹치면 기준선이 부풀므로 제외 조건이 필요하다 (확인 필요)
}
group by ev.PromoId, ev.Days

④ 행사 기간 실적과 후속 4주 실적

행사 기간 수량과 종료 뒤 4주 수량을 한 번에 모읍니다. 후속 4주가 아직 끝나지 않은 행사는 미집계 표시를 달아 판정에서 빼고, 집계가 끝난 뒤 다시 조회하게 합니다.

@EndUserText.label: '행사 실적 — 행사 기간과 후속 4주'
define view entity ZI_PromoActual
  as select from ZI_PromoEvent as ev
    left outer join ZI_DailySales as s
      on  s.ProdGrp = ev.ProdGrp and s.Channel = ev.Channel
{
  key ev.PromoId,
      sum( case when s.PostDate between ev.StartDate and ev.EndDate
                then s.Qty else 0 end )                                  as ActQty,
      sum( case when s.PostDate between dats_add_days( ev.EndDate, 1, 'INITIAL' )
                                    and dats_add_days( ev.EndDate, 28, 'INITIAL' )
                then s.Qty else 0 end )                                  as PostAct,
      // 후속 4주가 기준일을 넘기면 미집계 — 판정에서 제외
      case when dats_add_days( ev.EndDate, 28, 'INITIAL' ) > $session.system_date
           then 'X' else '' end                                          as ExcFlag
}
group by ev.PromoId, ev.EndDate

⑤ 판정 큐브 — 증분·잠식·선취·수익률

화면이 계산하던 일을 DB 로 내리는 핵심 뷰입니다. 증분·잠식·직접 판촉비·선취를 한 곳에서 정의하므로 화면과 표준 보고서가 같은 산식을 봅니다.

@EndUserText.label: '행사 증분 공헌이익 판정'
define view entity ZI_PromoProfit
  as select from ZI_PromoEvent    as ev
    inner join   ZI_PromoBaseline as bl on bl.PromoId = ev.PromoId
    inner join   ZI_PromoActual   as ac on ac.PromoId = ev.PromoId
    inner join   ZI_PromoCost     as pc on pc.PromoId = ev.PromoId   " 직접 판촉비 합계(매핑 적용)
{
  key ev.PromoId,
      ev.ProdGrp, ev.Channel, ev.StartDate,
      ac.ActQty - bl.BaseQty                                   as IncQty,
      ( ac.ActQty - bl.BaseQty ) * ( ev.PromoPrice - ev.VarCost ) as IncCm,
      bl.BaseQty * ( ev.ListPrice - ev.PromoPrice )            as CannibAmt,
      pc.PromoCost,
      // 선취 감소: 후속 4주 기준선 - 실적 (0 미만은 0) x 정상 단위 공헌이익
      greatest( bl.PostBase - ac.PostAct, 0 ) * ( ev.ListPrice - ev.VarCost ) as DipCm
      // AdjCm = IncCm - CannibAmt - PromoCost - DipCm
      // Roi   = AdjCm / ( PromoCost + CannibAmt + DipCm ) * 100
}

⑥ 소비 뷰 — 점검 결과와 OData 노출

점검 결과를 정하는 자리입니다. 기준 수익률 10% 는 샘플 값이고 점검 필요는 원인을 단정하지 않는 표시입니다. 이 뷰를 OData V2 서비스로 노출하면 화면은 그대로 붙습니다.

@EndUserText.label: '프로모션 증분 공헌이익 점검'
@OData.publish: true                      " 확인 필요: 릴리스에 따라 서비스 정의/바인딩으로 대체
define view entity ZC_PromoProfitCheck
  as select from ZI_PromoProfit
{
  key PromoId, ProdGrp, Channel, StartDate,
      IncQty, IncCm, CannibAmt, PromoCost, DipCm,
      IncCm - CannibAmt - PromoCost - DipCm                    as AdjCm,
      case
        when ExcFlag = 'X'                                     then 'EXC-POST'
        when PromoPrice <= VarCost                             then 'PRM-LOSS'
        when ( IncCm - CannibAmt - PromoCost ) > 0
         and ( IncCm - CannibAmt - PromoCost - DipCm ) < 0     then 'PRM-DIP'
        when ( IncCm - CannibAmt - PromoCost ) < 0             then 'PRM-NEG'
        when RoiPct < 10                                       then 'PRM-LOW'
        else 'PRM-GAIN'
      end                                                      as CheckCode
}

⑦ 제품군·채널 요약과 권한(DCL)

같은 판정 뷰를 제품군·채널로 합산합니다. 권한은 집계를 읽는 자리에 걸어야 합계에서 뺄셈으로 남의 숫자가 드러나는 일이 없습니다.

@EndUserText.label: '제품군별 행사 요약'
define view entity ZI_PromoGroupSum
  as select from ZC_PromoProfitCheck
{
  key ProdGrp,
      count( * )                                  as PromoCnt,
      sum( case when CheckCode <> 'EXC-POST' then 1 else 0 end ) as JudgeCnt,
      sum( case when CheckCode like 'PRM-%' and CheckCode <> 'PRM-GAIN' then 1 else 0 end ) as NeedCnt,
      sum( AdjCm )                                as AdjTot
}
group by ProdGrp

@EndUserText.label: '행사 요약 권한'
@MappingRole: true
define role ZI_PROMOGROUPSUM {
  grant select on ZI_PromoGroupSum
    where ( ProdGrp ) = aspect pfcg_auth( ZPRM_GRP, ZPRMGRP, ACTVT = '03' );   " 확인 필요: 권한 오브젝트
}

한 가지 더. 기준선 뷰는 가장 많이 고쳐지는 자리입니다. 기준선을 어떻게 잡느냐에 따라 증분·잠식이 함께 움직이므로, 정의를 바꾸기 전에 어느 행사의 판정이 달라지는지 먼저 비교해 보는 편이 낫습니다.

자주 묻는 질문

도입 상담과 데모에서 받는 질문을 세 묶음으로 나눠 적었습니다.

기준과 산식

이 점검은 어떤 회계기준에 따른 것인가요?

특정 기준서를 적용하는 화면이 아닙니다. 수익성 분석 중 판촉 행사의 수익성을 점검하는 화면이며 관련 기준서 표기는 없음(-)이고 적용 시기·경과규정도 해당 없습니다.

점검 필요로 표시되면 문제가 확정된 것인가요?

아닙니다. 선취 반영 후 순 공헌이익이 음수이거나 판촉 수익률이 기준에 못 미친다는 뜻일 뿐 원인은 단정하지 않습니다. 이 화면은 점검 도구이며 최종 판단은 회사와 감사인이 합니다.

기준선은 어떻게 정하나요?

샘플에서는 행사 직전 일평균 수량에 행사 일수를 곱해 기준선으로 삼았습니다. 운영에서는 계절성·요일·직전 행사 영향을 어떻게 걸러낼지 회사가 정해야 하며 확인 필요 항목으로 남겨 두었습니다.

할인 잠식은 무엇인가요?

행사가 없어도 팔렸을 기준선 수량에 준 할인액입니다. 기준선 수량 × (정상가 − 행사 단가) 로 계산하며, 증분 수량이 클수록 상대적으로 작게 느껴지지만 금액은 그대로 비용 쪽에 들어갑니다.

선취 수요 감소는 왜 빼나요?

행사 때 미리 사 둔 고객은 행사 뒤에 덜 사는 경우가 있어서입니다. 후속 4주 실적이 기준선보다 줄어든 만큼 정상 단위 공헌이익을 곱해 추가로 뺍니다. 관찰 기간 4주와 반영 여부는 회사 정책으로 정합니다.

후속 4주 실적이 아직 없는 행사는 어떻게 되나요?

의도적 예외로 분리합니다. 판정과 합계, 대사 차이 건수에서 빠지고 대사 결과 탭에 따로 기록되므로 집계가 끝난 뒤 다시 조회해 주세요.

판촉 수익률 기준 10%는 바꿀 수 있나요?

샘플 값입니다. 운영에서는 회사의 기대 수익률에 맞춰 서비스 쪽에서 정하면 되며, 바꿔도 화면과 OData 구조는 그대로입니다.

손익분기 증분 수량은 어떻게 읽나요?

잠식·판촉비·선취 감소를 모두 메우려면 필요한 증분 수량입니다. 실제 증분 수량이 이보다 작으면 선취 반영 순 공헌이익이 음수가 되므로, 얼마나 모자랐는지 가늠하는 용도로 봅니다.

행사 단가가 변동비 이하이면 어떻게 표시되나요?

팔수록 단위 공헌이익이 줄거나 음수가 되므로 점검 필요(PRM-LOSS)로 표시합니다. 가격 조건 입력 오류인지 의도된 미끼 상품인지는 화면이 판단하지 않고 확인 필요로 남깁니다.

제품군·채널 요약의 점검 필요는 어떻게 정해지나요?

판정 대상 행사 중 점검 필요 행사의 비율이 40% 이상이거나 선취 반영 순 공헌이익 합계가 음수이면 점검 필요로 표시합니다. 예외 행사는 분모와 합계에서 뺍니다.

화면과 데이터

금액 단위는 무엇인가요?

표의 금액은 원 단위, 위쪽 요약 지표는 백만원 단위입니다. 대사식은 원 단위 값으로 계산합니다.

실제 데이터와 연결하려면 무엇을 바꾸나요?

서버 쪽 서비스 구현만 교체하면 됩니다. 화면은 manifest 에 선언한 상대 경로의 OData V2 서비스만 바라보므로, 같은 엔티티셋·프로퍼티 이름으로 실데이터를 내려주면 화면 수정은 필요 없습니다.

샘플 데이터는 실제 고객 자료인가요?

아닙니다. 가상의 제품군 6개·채널 5개·행사 30건으로 만든 검증용 데이터이며 실제 고객사의 금액이나 거래처는 쓰지 않았습니다.

날짜 조건은 어떻게 처리되나요?

행사 시작일 범위를 $filter 로 보내면 서비스가 날짜 비교를 직접 처리합니다. 시작일만 또는 종료일만 넣어도 동작하고, 비우면 조건을 만들지 않습니다.

조회 버튼은 어디에 있나요?

조회조건 영역의 가장 오른쪽 끝에 있고 초기화 버튼이 옆에 있습니다. 회계연도 입력 칸에서 Enter 키를 눌러도 조회됩니다.

행 클릭 상세 창에서는 무엇을 볼 수 있나요?

행사 행에서는 네 가지 손익 요인과 산식을, 제품군·채널 행에서는 소속 행사 목록을 봅니다. 닫기 버튼으로 돌아옵니다.

CSV 로 내려받을 수 있나요?

현재 탭에 조회된 결과를 UTF-8 CSV 로 내려받습니다. 필터가 적용된 상태 그대로 저장됩니다.

대사 결과 탭에서 차이 건수가 0이 아니면 어떻게 하나요?

대사식 좌변과 우변이 달랐다는 뜻이므로 원천 자료나 집계 로직을 확인해야 합니다. 샘플에서는 정합성 대사 15건이 모두 0이고, 의도적 예외 2건만 별도 행으로 나옵니다.

운영과 연동

서비스 연결에 실패하면 어떻게 되나요?

메타데이터 실패·요청 실패·빈 응답을 구분해 안내 창을 띄웁니다. 앱 본체에는 샘플 데이터나 샘플 서버 참조가 없습니다.

표준 수익성 분석(KE30)과 무엇이 다른가요?

표준 보고서는 실적 집계를 보여 주고, 이 화면은 행사 단위로 기준선·잠식·선취를 걷어낸 증분 관점을 더합니다. 합계는 표준 보고서와 대조해 확인하시기 바랍니다.

OData 서비스 이름과 경로는 어떻게 되나요?

서비스 이름은 소문자 promoprofit_srv 이고 manifest 의 mainService 에 상대 경로로 선언되어 있습니다. 설명서의 OData 구성에서 엔티티셋 행을 눌러 요청 예시를 복사할 수 있습니다.

이 화면의 결과로 회계 처리를 결정해도 되나요?

그렇게 쓰시면 안 됩니다. 분류·집계·대사를 돕는 조회·점검 도구이며 최종 판단은 회사와 감사인이 합니다.