수입 재고 저가평가(NRV) 다차원 분석 — IAS 2 평가충당금이 왜 늘었는지 요인으로 가르는 월말 평가 점검
피벗 축 전환 · 셀에서 원천 평가 라인까지 드릴스루 · 예측 대비 차이와 일곱 요인 분해 · 행에 남는 변동 사유 · 숫자를 모델에 맡기지 않는 AI 분석 · 스스로 도는 AI 에이전트 — 소개 영상과 실제 화면 34종, 그리고 CDS 코드까지
소개 영상블로그 목차 순서대로 · 자막 포함
도입 포인트 — 이 앱을 사용해야 하는 이유
월말 재고 평가 회의의 질문은 늘 같습니다. 평가충당금이 예측보다 얼마나 늘었나, 왜 늘었나, 누가 무엇을 확인해야 하나. 수입 재고는 여기에 외화 단가와 환율, 운임 · 관세 같은 부대비용이 겹쳐 원가가 정해지고, 예상 판매가에서 판매비용을 뺀 순실현가능가치(NRV)와 비교해 충당금이 정해집니다. IAS 2 재고자산(K-IFRS 제1002호)은 재고자산을 원가와 순실현가능가치 중 작은 금액으로 측정하도록 요구하고, 외화 거래의 원화 환산은 IAS 21 환율변동효과(K-IFRS 제1021호)와 맞닿아 있습니다.
지금은 구매오더(ME23N), 자재 문서(MB51), 송장(MIR4), 자재 가격 분석(CKM3)을 번갈아 열고 엑셀에서 로트별 원가와 NRV 를 다시 맞춰 보는 방식이 많습니다. 이 앱은 그 자리에 같은 데이터를 한 번 묶은 큐브를 놓고, 축을 바꿔 가며 보고, 칸에서 원천 평가 라인까지 내려가고, 예측과의 차이를 일곱 요인으로 가르는 점검 화면을 더합니다. 표준 실행은 SAP 표준 T-code 가 담당하고, 이 화면은 조회 · 검증 관점을 더해 확장합니다.
핵심 포인트 일곱 가지
| 핵심 포인트 | 고객이 얻는 것 | 지금 방식이라면 |
|---|---|---|
| ① 축을 바꿔도 합계가 갈라지지 않는 피벗 | 공급사 · 원산지 · 자재그룹 · 플랜트 등 11개 차원을 끌어다 놓아 행 3단계 · 열 2단계로 봅니다. 모든 축이 같은 큐브에서 나옵니다. | 축마다 엑셀 피벗을 따로 만들고, 합계가 다르면 어느 시트가 맞는지부터 따집니다. |
| ② 칸에서 원천 평가 라인까지 | 숫자를 누르면 그 금액을 만든 입고 로트 라인이 열리고, 라인 합계가 칸 금액과 같은지 바로 보입니다. | 구매오더 · 자재 문서 · 송장 화면을 차례로 열어 로트를 찾고 단가를 손으로 대조합니다. |
| ③ 예측 대비 차이를 일곱 요인으로 | 수량 · 외화 단가 · 환율 · 부대비용 · 예상 판매가 · 판매비용 · 예측 없던 로트로 가르고, 요인 합이 총차이와 같은지 매번 검산합니다. | 충당금이 늘었다는 합계만 보고, 이유는 담당자의 설명과 엑셀에 의존합니다. |
| ④ 변동 사유가 행에 남는다 | 사유는 조회 범위와 행 경로에 묶여 저장되어 축을 바꿔도, 다음 달에도 그 행에 따라옵니다. | 같은 질문을 매달 다시 하고, 지난달 답은 메일함에서 찾습니다. |
| ⑤ 사람이 열지 않아도 도는 감시 | 규칙마다 임계값과 받을 사람(CFO · 구매 · 자금 · 물류)이 붙어, 걸리면 보고가 대기함에 올라갑니다. | 숫자가 나빠진 날 아무도 화면을 열지 않으면 그대로 지나갑니다. |
| ⑥ 회의 자료를 바로 | 보고 있는 범위의 표와 요인 차트를 담은 PowerPoint 보고서가 브라우저에서 바로 만들어집니다. | 화면을 캡처하고 숫자를 옮겨 적어 보고서를 다시 만듭니다. |
| ⑦ 숫자는 모델에 맡기지 않는 AI | 금액과 비율은 서비스가 큐브에서 계산하고, 해설은 그 숫자를 읽어 쓸 뿐입니다. 근거 표를 화면에서 펼쳐 볼 수 있습니다. | AI 가 만든 숫자를 보고서에 써도 되는지부터 따져야 합니다. |
사례로 보는 효과 — 평가충당금 12.6억 증가의 이유
검증용 샘플 데이터(2026년 4월~9월, 입고 라인 2,900건 · 평가 문서 974건) 기준으로 평가충당금은 예측 7,002.5백만원에서 실적 8,257.8백만원으로 +1,255.3백만원(+17.9%) 늘었습니다. 합계 리포트는 여기까지 말해 줍니다. 이 앱은 그 다음을 답합니다 — 일곱 요인으로 가르자 증가분의 약 66%(+831.9)가 예측 시점에 없던 로트에서 났고, 그 다음이 예상 판매가 하락(+537.1)이었습니다. 수량과 환율, 부대비용은 합쳐도 작았습니다.
| 요인 | 증감(백만원) | 읽는 법 |
|---|---|---|
| 예측 없던 로트 | +831.9 | 직전 평가 때 계획에 없던 입고 로트 325건에서 새로 생긴 충당금입니다. |
| 예상 판매가 | +537.1 | 판매가 전망이 내려가 NRV 가 줄어든 몫입니다. |
| 외화 취득 단가 | −128.7 | 취득 단가가 예측보다 낮아져 충당금을 줄인 몫입니다. |
| 재고 수량 | +17.9 | 수량 변화만의 영향입니다. |
| 환율 | +1.8 | 환율 변동만의 영향입니다. |
| 부대비용 단가 | −3.7 | 운임 · 관세 등 확정 단가 변화의 영향입니다. |
| 추정 판매비용 | −1.1 | 판매비용 단가 변화의 영향입니다. |
| 합계 | +1,255.3 | 예측 7,002.5 → 실적 8,257.8. 총차이와 같습니다(검산 0원). |
요인분해는 이렇게 셉니다
예측값에서 실적값으로 가면서 한 번에 한 요인씩 실제 값으로 바꾸고, 그때마다 라인 단위 식 수량 × max(0, 장부 원가 − NRV) 을 다시 계산합니다. 바뀐 만큼이 그 요인의 몫입니다.
모든 단계가 이어져 있으므로 일곱 몫을 더하면 총차이와 정확히 같아집니다. 그래서 잔차가 구조적으로 0 이고, 화면이 매번 “요인 합 − 총차이 = 0원” 을 적어 검산합니다.
요인의 크기는 샘플 데이터의 가정값에서 나온 것이며, 실제 환경의 크기를 말하는 것이 아닙니다. 중요한 것은 같은 화면에서 “어느 요인이 얼마” 가 바로 나온다는 점입니다.
도입하면 달라지는 것
- 월말 평가 준비 — 요인분해 · 사유 · 보고서가 한 화면에서 나오므로 엑셀 취합과 캡처 작업이 줄어듭니다.
- 회의의 주제 — “어느 시트 숫자가 맞나” 가 아니라 “어느 로트를 어떻게 할 것인가” 를 이야기합니다.
- 다음 달로 이어지는 기록 — 사유와 레이아웃이 남아, 매달 같은 설명을 처음부터 다시 하지 않습니다.
- 놓치는 날이 없는 감시 — 아무도 화면을 열지 않은 날에도 규칙에 걸린 숫자는 받을 사람에게 올라갑니다.
이런 회사에 맞습니다
해외에서 원자재 · 상품을 들여오며 외화 결제와 운임 · 관세 같은 부대비용이 원가에 얹히는 회사, 월말 재고 평가를 엑셀로 맞추고 있는 재무 · 원가 조직, 그리고 구매 · 자금 · 물류가 평가 숫자를 함께 확인해야 하는 경영지원 조직에 맞습니다. 평가 결과는 점검 자료이며, 충당금 인식과 환입의 최종 판단은 회사와 감사인이 합니다.
실행 화면
실제로 돌아가는 화면 34종을 사용 순서대로 싣습니다. 그림을 누르면 크게 볼 수 있고, 화면마다 무엇을 하는 자리이고 어떻게 읽는지를 아래에 적었습니다. 모든 캡처는 가상의 검증용 샘플 데이터로 찍었습니다.
사용 방법
- 조회조건을 넣습니다. 회사코드(필수)와 시작 · 종료 기간(필수)을 고르고, 필요하면 공급사 · 자재그룹 같은 차원 값을 여러 개 골라 범위를 좁힙니다. 비워 두면 전체입니다.
- 조회를 누릅니다. 조회조건 영역 오른쪽 끝의 조회 버튼을 누르거나 입력칸에서 Enter 를 누릅니다. 자동 조회는 저장한 레이아웃에서 지정한 경우에만 화면을 열 때 실행됩니다.
- 요약을 봅니다. 임원 요약에서 평가충당금 · 충당금률 · 장부 원가 · NRV 를 예측과 함께 보고, 역할을 바꿔 앞세우는 지표를 바꿉니다.
- 축과 탭을 옮깁니다. 차원 칩을 끌어다 놓아 행 · 열을 짜고, 표시 항목 · 금액 단위 · 비교 기준을 바꿉니다. 결과 영역에서는 표와 막대 · 요인 워터폴을 오갑니다.
- 행이나 칸을 눌러 내려갑니다. 숫자 칸을 누르면 원천 평가 라인이 열리고, 차이 모드에서 행 이름을 누르면 그 범위로 요인분해가 계산되며, 사유 칸을 누르면 변동 사유를 적습니다.
- 내보냅니다. 결과 영역의 CSV 버튼은 피벗을, 드릴스루 창의 CSV 버튼은 읽은 원천 라인을 내려받습니다. AI 분석 창에서는 PPTX 보고서를 만듭니다.
무엇으로 만들었나
화면은 OpenUI5 표준 컨트롤과 직접 그린 SVG 차트로만 짰고, 서비스 쪽은 OData V2 규격을 따르는 서비스 한 벌입니다. 아래는 모델 구성 수준으로 적은 구성입니다.
| 자리 | 무엇 | 왜 그렇게 두었나 |
|---|---|---|
| 화면 컨트롤 | OpenUI5 표준 컨트롤, 차원 칩 끌어다 놓기, SVG 차트 | 외부 차트 라이브러리를 들이지 않아 반입 심사가 필요 없고, 차트와 표가 같은 숫자를 씁니다. |
| 집계 · 판정 로직 | 큐브 묶기, 계산항목 식, 차이 색 판정, 요인분해 호출 | 묶기는 브라우저가, 금액과 비율 계산은 서비스가 맡아 숫자의 출처를 하나로 둡니다. |
| 데이터 서비스 | OData V2 서비스 1개 · 엔티티셋 16개 · 펑션 3개 | 큐브 · 예측 · 원천 라인 · 차원 목록 · 사유와 레이아웃(쓰기) · 에이전트 기록을 한 서비스에서 줍니다. 읽기는 $filter 로 범위를 좁힙니다. |
| 쓰기 | 변동 사유와 레이아웃을 생성 · 수정 · 삭제로 저장 | 새로 고쳐도 사유와 배치가 남도록 서비스에 저장합니다. |
| 연결 실패 처리 | 서비스에 붙지 못하면 메시지 상자로 알림 | 빈 화면 대신 원인을 먼저 알립니다. |
| 테마 | sap_horizon | SAP 표준 화면과 같은 결의 색과 글꼴을 씁니다. |
SAP 표준 기능을 그대로 이어받은 부분. 구매오더 조건 · 입고 자재 문서 · 송장 · 자재 평가의 표준 데이터 구조를 그대로 이어받아 쓰고, 별도의 평가 체계를 새로 만들지 않습니다. 평가 실행과 원장 반영은 SAP 표준 T-code 가 담당하고, 이 화면은 그 결과를 여러 축으로 조회하고 검증하는 관점을 더합니다.
| 항목 | 내용 |
|---|---|
| 솔루션 | 수입 솔루션 |
| 업무 영역 | 수입 재고 평가 · 저가 평가(NRV) 점검 |
| 관련 기준서 | IAS 2 재고자산(K-IFRS 제1002호) · IAS 21 환율변동효과(K-IFRS 제1021호) |
| SAP 표준 T-code | ME23N · MIGO · MB51 · MIRO · MIR4 · MB5B · MMBE · CKM3 |
| 화면 성격 | 다차원 큐브 분석 리포트(피벗 · 드릴스루 · 차이 요인분해) |
| 테마 | sap_horizon |
처음 열었을 때
조회조건부터 피벗까지가 한 화면에 세로로 쌓입니다. 머리 영역은 접을 수 있어서, 축을 짜는 동안에는 펼쳐 두고 숫자를 볼 때는 접어 표와 차트를 넓게 씁니다.

빈 화면을 주지 않습니다. 틀이 먼저 서 있어서 처음 여는 사람도 무엇을 고르면 무엇이 채워지는지 봅니다. 회사코드 1000, 기간 2026.04 ~ 2026.09 가 기본값이고 조회 버튼은 조회조건 영역의 오른쪽 끝에 있습니다.

행은 자재그룹과 판매가 근거, 열은 평가월이 기본 배치입니다. 값은 백만원 단위의 평가충당금이며, 오른쪽 차트는 같은 값을 그립니다. 이후 축을 바꾸는 일은 서버를 다시 부르지 않고 브라우저에서 합니다.

칩을 끌어다 놓거나 화살표 버튼으로 옮깁니다. 행 축은 최대 3단계, 열 축은 최대 2단계까지 쌓입니다. 쓰지 않는 차원은 왼쪽 칸에 모아 둡니다.

서버를 다시 부르지 않으므로 반응이 즉시입니다. 행 · 열 바꾸기와 기본 축 버튼으로 언제든 되돌릴 수 있고, 총합은 축을 바꿔도 같습니다.

표와 차트를 넓게 보고 싶을 때 접습니다. 접힌 줄에는 지금 어떤 범위를 보고 있는지가 남아 있어, 범위를 잊은 채 숫자를 읽는 일을 막습니다.
경영 요약 — 역할마다 앞세우는 숫자가 다르다
임원 요약은 역할을 바꾸면 앞세우는 지표가 바뀝니다. 같은 큐브에서 나온 숫자이므로 역할을 바꿔도 다시 조회하지 않습니다.

예측 초과 상위와 미달 상위가 나란히 보여 어디부터 볼지 정해 줍니다. 충당금률은 평가충당금을 장부 원가로 나눈 비율이며 샘플 기준 4.69% 입니다.

어느 공급사에서 들여온 로트가 NRV 아래로 내려갔는지를 먼저 봅니다. 구매 조건 재협상이나 발주 조정이 필요한 후보를 고르는 자리입니다.

외화 통화별로 예측 대비 증감을 확인합니다. 환율 요인이 작은지 큰지를 통화마다 보고, 헤지나 결제 시점 논의의 근거로 씁니다.

체류가 긴 플랜트를 먼저 점검합니다. 오래 쌓인 재고는 평가 때 먼저 점검할 대상이므로 출고 · 이동 계획의 우선순위를 정하는 데 씁니다.
축 전환과 범위
차원은 열 개가 넘고, 각 차원은 값을 여러 개 골라 범위를 좁힐 수 있습니다. 어떻게 쌓고 좁혀도 합계가 갈라지지 않는 것이 이 절의 기준입니다.

열 조합이 36개를 넘으면 더 추가할 수 없습니다. 표가 읽을 수 없을 만큼 넓어지는 것을 막기 위한 상한이며, 넘었을 때 안내가 뜨는 모습은 마지막 절에서 봅니다.

같은 차원 안에서는 or, 차원 사이에서는 and 로 묶입니다. 선택한 범위는 조회 조건 요약 줄에 그대로 표시됩니다.

범위를 좁혀도 같은 큐브에서 거르는 것이므로 합계가 일관됩니다. 좁힌 상태에서 요인분해를 보면 그 범위의 차이만 가릅니다.

차트는 외부 라이브러리 없이 SVG 로 직접 그립니다. 표와 같은 숫자를 쓰므로 둘이 어긋나는 일이 없습니다.

바꾼 너비는 브라우저가 기억합니다. 표를 넓게 보다가 차트를 키워 발표 화면으로 쓰는 식으로 바꿔 씁니다.
칸에서 원천 평가 라인까지
이 앱의 신뢰는 “칸 금액을 만든 라인을 바로 볼 수 있다” 에서 나옵니다. 칸을 누르면 그 칸의 조건이 그대로 질의가 되어 원천 평가 라인이 열립니다.

한 번에 읽는 만큼만 가져오고, 맨 위에 읽은 건수와 전체 건수(100 / 455)를 적습니다. 일부만 읽은 동안에는 칸 금액과 라인 합계의 대조가 보류되고, 더 읽기와 모두 읽기 버튼으로 이어서 받습니다.

질의 조건이 머리에 함께 표시되어, 같은 조건을 표준 화면에서 다시 걸어 볼 수 있습니다. 합계가 어긋나면 그 자체가 오류 신호입니다. 샘플 검증에서는 확인한 칸 5개 모두 같았습니다.

차이 칸이 모두 0 이면 큐브가 원천을 그대로 묶은 것입니다. 이 표의 값은 서비스가 계산해 돌려줍니다.
계산항목
순실현가능가치나 충당금률은 어떤 라인에도 저장되어 있지 않고, 다른 값에서 계산해야 나옵니다. 그래서 차원이 아니라 식으로 정의해 표시 항목 목록에 함께 올렸습니다.

식은 서비스가 정의하고 화면은 합산과 배치만 합니다. 어느 축으로 묶어도 같은 식이 적용됩니다.

열로도 세울 수 있어서, 평가월마다 비율이 어떻게 움직였는지 한 줄로 봅니다.
예측 대비 차이 — 같은 표가 월말 평가 회의 자료가 된다
비교 기준을 예측으로 바꾸면 같은 표가 차이 리포트가 됩니다. 차이가 어디서 났는지는 워터폴과 요인분해로, 왜 났는지는 사유 기록으로 이어집니다.

금액과 비율이 둘 다 임계를 넘을 때만 색이 칠해집니다. 기본 임계는 100만원과 10퍼센트이며, 이 값은 가정값이므로 회사 기준에 맞게 바꿉니다.

사유는 조회 범위와 행 경로를 키로 저장되므로 축 배치를 바꾸거나 새로 고친 뒤에도 같은 행에 따라옵니다. 사유가 적힌 행은 AI 분석이 점검 대상에서 빼 줍니다.

붉은색은 충당금을 늘린 요인, 초록색은 줄인 요인입니다. 아래 검산 줄이 요인 합과 총차이의 차이를 적으며, 정상이면 0원입니다.

자재그룹이나 공급사처럼 쪼개서 보면 같은 일곱 요인이 그 범위의 몫으로 나뉩니다. 전체 범위로 버튼으로 되돌립니다.
AI 분석과 보고서
AI 분석은 숫자를 만들지 않습니다. 서비스가 큐브에서 계산한 값을 읽어 해설로 옮길 뿐이며, 어떤 숫자를 근거로 썼는지 표로 펼쳐 볼 수 있습니다.

요약 문장에는 평가 문서 수와 원천 라인 수, 충당금 합계가 함께 적힙니다. 사유가 이미 적힌 차이는 점검 대상에서 건너뜁니다.

해설의 모든 금액과 비율은 이 표에 있는 값입니다. 모델을 쓰지 않는 규칙 기반 해설로도 같은 근거가 나옵니다.

외부 라이브러리 없이 압축과 XML 을 직접 만들어 서버에 파일을 올리지 않습니다. 내려받은 파일은 PowerPoint 형식 검사에서 6장으로 열렸습니다.
AI 에이전트
규칙에 걸린 숫자를 사람이 열기 전에 먼저 알려 주는 장치입니다. 규칙마다 받을 사람이 정해져 있어 보고가 알아서 갈립니다.

임계값은 이 화면에서 바꿔 저장합니다. 값은 모두 가정값이며, 운영 연결 때 회사 기준으로 정합니다.

역할별로 걸러 볼 수 있습니다. 같은 숫자라도 받는 사람에 따라 문장이 달라집니다.

하루에 한 번만 도는 규칙이라 두 번째 실행은 제한으로 판정되어 기록됩니다. 사람이 누른 것인지 배치가 호출한 것인지도 함께 남습니다.
레이아웃 저장과 복원
자주 쓰는 배치를 이름 붙여 저장해 두면 다음에 열 때 그 배치로 시작합니다.

기본 레이아웃과 자동 조회를 지정할 수 있습니다.

저장한 행 축이 그대로 복원됩니다. 매달 같은 배치로 보는 사람은 화면을 열자마자 숫자를 봅니다.
좁은 화면과 범위 상한
휴대폰 폭에서는 영역이 세로로 쌓이고, 표가 너무 넓어지는 조합은 그리기 전에 막습니다.

조회 버튼과 차원 칩이 그대로 쓰입니다. 위에서 아래로 읽는 순서입니다.

표는 가로로 스크롤됩니다. 차트는 폭을 꽉 채워 표 아래에서 같은 값을 보여 줍니다.

열 조합이 42개로 상한 36개를 넘은 경우입니다. 읽을 수 없는 표를 그리지 않고 열 축을 줄이거나 차원 값을 골라 범위를 좁히도록 안내합니다.
화면 뒤에서 일어나는 일
조회를 누르면 서비스에서 큐브와 예측을 한 번 읽어 와 브라우저가 들고 있고, 축을 바꾸는 모든 조작은 그 위에서 일어납니다. 칸을 눌러 원천 라인으로 내려갈 때만 서비스를 다시 부릅니다. 이때 칸의 조건이 그대로 조회 조건이 됩니다.
저가 평가 판정 규칙
라인(입고 로트) 단위로 장부 원가와 NRV 를 비교해 평가충당금을 계산하고, 그 합을 큐브에 묶습니다. 아래 판정은 모두 “점검 필요” 수준의 안내이며, 충당금 인식과 환입의 최종 판단은 회사와 감사인이 합니다.
| 판정 조건 | 결과 상태 | 사용자 조치 |
|---|---|---|
| MT당 장부 원가 > MT당 NRV | 저가 평가 라인 — 평가충당금 = 수량 × (장부 원가 − NRV) | 원천 라인에서 판매가 근거와 체류 구간을 확인 |
| MT당 장부 원가 ≤ MT당 NRV | 충당금 0 — NRV 여유율 표시 | 필요하면 NRV 여유율이 낮은 행을 점검 |
| 금액 차이와 비율 차이가 둘 다 임계 초과(기본 100만원 · 10퍼센트) | 칸을 붉은색(영향 증가) 또는 초록색(영향 감소)으로 표시 | 변동 사유 입력 또는 요인분해로 원인 확인 |
| 예측에 없던 로트 | 요인 “예측 없던 로트” 로 분리 | 로트 단위 드릴스루로 입고 사유 확인 |
| 감시 규칙 임계 초과 | 대기함에 받을 역할 관점의 보고 등록 | 역할별 점검 후 사유 기록 |
| 하루에 두 번째 에이전트 실행 | 제한됨(LIMITED)으로 기록 | 다음 날 다시 실행 |
산출 순서
- 외화 취득 원가 = 수량 × 외화 취득 단가
- MT당 장부 원가 = 외화 단가 × 환율 + 부대비용 단가(운임 · 관세 · 통관 등 확정 단가)
- MT당 NRV = 예상 판매 단가 − 추정 판매비용 단가
- 평가충당금 = 수량 × max(0, MT당 장부 원가 − MT당 NRV)
- 충당금률 = 평가충당금 ÷ 장부 원가 × 100, NRV 여유율 = (예상 판매가액 − 추정 판매비용 − 장부 원가) ÷ 장부 원가 × 100
요인분해 처리 단계와 대사식
예측값에서 실적값으로 한 번에 한 요인씩 바꿔 같은 식을 다시 계산합니다. 요인은 재고 수량 · 외화 취득 단가 · 환율 · 부대비용 단가 · 예상 판매가 · 추정 판매비용 · 예측 없던 로트의 일곱 가지이며, 요인 합은 총차이와 정확히 같습니다. 만드는 쪽에서는 아래 대사식을 전수로 돌립니다.
- 큐브 합계 = 원천 라인 합계(평가월 × 측정값)
- 예측 큐브 합계 = 원천 라인 예측 열 합계
- 라인 충당금 재계산 = 저장된 충당금
- 요인 합 − 총차이 = 0
조회조건
| 필드 | 필수 | 기본값 | 서비스 조건($filter) |
|---|---|---|---|
| 회사코드 | 필수 | 1000 | Bukrs eq '1000' |
| 시작 기간 | 필수 | 2026.04 | Period ge '202604' |
| 종료 기간 | 필수 | 2026.09 | Period le '202609' |
| 차원 값(다중 선택) | 선택 | 전체 | 큐브에서 읽은 뒤 브라우저에서 거릅니다(차원 안 or · 차원 간 and). 드릴스루는 차원 조건을 $filter 로 보냅니다. |
| 표시 항목 · 금액 단위 · 비교 · 단계 보기 | 선택 | 평가충당금 · 백만원 · 실적만 · 끔 | 화면 표시 설정(서버 호출 없음) |
| 금액 임계 · 비율 임계 | 선택 | 1,000,000원 · 10퍼센트 | 화면 표시 설정. 가정값이므로 회사 기준에 맞게 조정 |
| 표시 행 수 · 원천 라인 읽는 단위 | 선택 | 14 · 500 | 드릴스루는 $top 으로 전달 |
결과 컬럼
| 컬럼 | 의미 | 산출식 |
|---|---|---|
| 행 트리 | 선택한 행 축 순서대로 내려가는 계층 | - |
| 열 머리글 | 열 축 값(평가월 등) 조합 | - |
| 값 | 선택한 표시 항목의 합 | 큐브 합 또는 계산항목 식 |
| 예측 · 실적 · 차이 · 차이율 | 차이 모드에서 칸마다 표시 | 차이 = 실적 − 예측, 차이율 = 차이 ÷ 예측 |
| 사유 | 변동 사유 입력 상태 | 사유 있음 / 사유 쓰기 |
좁은 화면에서 달라지는 것
- 영역 쌓기 — 조회조건 · 축 보드 · 표 · 차트가 세로로 쌓이고 차트는 표 아래로 내려갑니다.
- 표 스크롤 — 표는 가로로 스크롤되고 칸 누르기는 그대로 됩니다.
- 범위 상한 — 열 조합이 36개를 넘으면 표를 그리지 않고 범위를 좁히도록 안내합니다.
파일 구성
(앱 폴더)
├─ index.html · Component.js · manifest.json · readme.html
├─ i18n/ 화면 글자
├─ view/ 화면 · 드릴스루 · 사유 · AI · 에이전트 · 레이아웃 창
├─ controller/ 화면 제어
├─ model/ 큐브 묶기 · 차트 · 레이아웃 · PPTX 만들기 · 서식 · 오류 처리
├─ css/ 스타일
├─ media/ 소개 영상 · 포스터 · 재생 지점 목록
└─ odata/ 서비스 정의 · 서비스 로직 · 샘플 데이터
SAP 표준 기능 확장 포인트
이 앱은 SAP 표준을 대체하지 않습니다. 표준 실행은 SAP 표준 T-code 가 담당하고, 이 화면은 조회 · 검증 관점을 더해 확장합니다. 어디까지가 표준이고 어디서부터 이 앱인지를 먼저 적습니다.
표준으로 되는 것과 안 되는 것
| 하고 싶은 일 | SAP 표준 | 표준에서 걸리는 자리 | 이 앱이 하는 일 |
|---|---|---|---|
| 구매오더 조건 · 외화 단가 확인 | ME23N | 오더를 한 건씩 열어 봅니다 | 평가 라인에 외화 단가 · 환율 · 부대비용 단가가 한 줄로 붙어 있습니다 |
| 입고 수량 · 입고일 확인 | MB51 · MIGO | 자재 문서 목록에는 평가 비교가 없습니다 | 입고 로트 단위로 NRV 비교와 충당금까지 이어 줍니다 |
| 자재 평가 단가 분석 | CKM3 | 자재 단위 분석이라 공급사 · 원산지 같은 축으로 바꿔 보기 어렵습니다 | 같은 평가를 11개 차원으로 끌어다 놓아 봅니다 |
| 일자별 재고 수량 · 금액 | MB5B · MMBE | 수량 · 금액 현황 중심이고 NRV 비교는 따로 해야 합니다 | NRV 와 충당금률을 계산항목으로 함께 둡니다 |
| 예측 대비 차이의 원인 분해 | 없음 | 같은 형태의 요인분해 화면이 없어 보통 엑셀로 만듭니다(확인 필요) | 일곱 요인으로 가르고 합계를 검산합니다 |
| 차이 사유 기록 | 전표 적요 | 전표 단위라 집계 행에는 붙일 곳이 없습니다 | 조회 범위 + 행 경로를 키로 사유를 남깁니다 |
| 이상 징후 알림 | SM36 배치 + 메일 | 잡은 돌지만 누가 봐야 하는지는 사람이 판단합니다 | 규칙마다 받을 사람이 붙어 있어 수신자가 갈립니다 |
T-code 별 연계 지점
이 앱이 표준 거래의 어느 자리를 이어받는지를 적었습니다. 운영에 올릴 때 “기존 화면을 없애야 하느냐” 는 질문이 꼭 나오는데, 대부분은 없애지 않고 둡니다. 평가 실행과 원장 반영, 감사와 세무 신고 대응은 표준 거래가 맡는 편이 안전합니다. 두 화면을 오가는 방법은 단순합니다 — 이 앱의 드릴스루 라인에서 번호를 집어 표준 T-code 로 원천을 확인하고, 표준 화면에서 본 값은 같은 조건으로 이 앱에서 다시 봅니다.
| T-code | 이름 | 연계 |
|---|---|---|
ME23N | 구매오더 조회 | 외화 단가 · 인코텀즈 · 부대비용 조건의 원천입니다. 평가 라인의 외화 단가 · 통화를 오더 조건과 맞춰 보는 대사 지점이며, 이 앱 결과의 라인 번호를 가지고 오더를 열어 확인합니다. |
MIGO · MB51 | 자재 문서 처리 · 자재 문서 목록 | 입고 수량과 입고일의 원천입니다. 드릴스루 라인의 입고 수량 합계가 MB51 의 같은 조건 합계와 같아야 합니다. |
MIRO · MIR4 | 송장 입력 · 송장 조회 | 부대비용 확정 단가와 송장 금액을 맞춰 보는 자리입니다. 송장이 늦게 들어오면 부대비용 단가가 바뀌어 장부 원가 요인으로 나타납니다. |
MB5B · MMBE | 일자별 재고 · 재고 현황 | 평가일 기준 수량과 금액을 맞춰 보는 자리입니다. 큐브의 장부 원가 합계와 비교해 평가 범위가 같은지 확인합니다. |
CKM3 | 자재 가격 분석 | 월말 평가 단가의 원천을 보는 자리입니다. 이 앱의 장부 원가와 평가 단가가 다르면 어느 단계에서 갈렸는지 요인분해로 좁힙니다(확인 필요). |
SM36 · SM37 | 배치 잡 등록 · 조회 | 에이전트를 사람 없이 돌리는 자리입니다. 잡이 에이전트 실행 호출을 두드리면 화면에서 누른 것과 똑같이 조회 · 판단 · 기록이 일어납니다. |
SE16N | 테이블 조회 | 검수 단계에서 큐브 숫자를 원천과 맞춰 볼 때 씁니다. 운영에서는 일반 사용자에게 열지 않는 것이 보통입니다. |
요구사항 매핑표
| 기준서 | 요구사항 | 대응 기능 | 원천 데이터 | 비고 |
|---|---|---|---|---|
| IAS 2 재고자산(K-IFRS 제1002호) | 원가와 순실현가능가치 중 작은 금액으로 측정 | 저가 평가 판정 · 평가충당금 · NRV 계산항목 | 자재 평가 단가 · 구매오더 조건 · 입고 문서 | 문단번호는 원문 확인 후 기입 — 확인 필요 |
| IAS 2 재고자산(K-IFRS 제1002호) | 취득원가 구성(매입가 · 수입 관세 등 부대비용) | MT당 장부 원가 · 부대비용 요인 | 구매오더 조건 · 송장 | 관세율 · 부대비용은 샘플의 가정값 |
| IAS 2 재고자산(K-IFRS 제1002호) | 순실현가능가치(예상 판매가 − 추정 판매비용) | NRV · NRV 여유율 · 판매가 근거 차원 | 판매 계약 · 시세 자료(확인 필요) | 판매가 근거 4종은 샘플 분류 |
| IAS 21 환율변동효과(K-IFRS 제1021호) | 외화 거래의 원화 환산 | 환율 요인 · 외화 취득 단가 요인 | 외화 단가 · 환율 | 환율은 샘플의 가정값 |
| IAS 2 재고자산(K-IFRS 제1002호) | 평가손실 인식과 환입에 관한 정보 | 변동 사유 · 감시 규칙 · 대기함 | 화면 입력 · 서비스 계산 | 공시 문구는 회사와 감사인이 판단 |
S/4HANA 분석 스택과의 자리
S/4HANA 에서는 CDS 로 만든 분석 쿼리를 표준 분석 화면이 그대로 띄워 줍니다. 이 앱을 올리기 전에 표준 스택으로 먼저 되는지를 확인하는 편이 좋습니다. 확인하지 못한 Fiori 앱 이름은 적지 않았습니다.
| 표준 자리 | 무엇을 하나 | 이 앱과의 관계 |
|---|---|---|
| CDS 분석 쿼리 | @Analytics.query 로 만든 쿼리를 표준 분석 화면이 그대로 띄웁니다 | 아래 CDS 구성의 쿼리 뷰를 만들어 두면 이 앱 없이도 축을 바꿔 볼 수 있습니다. 드릴스루 · 사유 · 요인분해가 필요 없다면 거기서 끝내도 됩니다. |
| 표준 Fiori 분석 앱 | 분석 쿼리를 피벗으로 띄움 | 릴리스에 따라 앱 이름과 제공 범위가 달라 확인 필요입니다. 축 끌어다 놓기까지는 표준으로 되고, 갈리는 자리는 변동 사유 · 요인분해 · 에이전트입니다. |
| Analysis for Microsoft Office | 같은 쿼리를 엑셀에서 피벗으로 | 엑셀로 내보내 다시 가공하는 업무가 많다면 이쪽을 함께 열어 두는 편이 낫습니다. |
확장 포인트 — 운영에서 실제로 손대는 자리
- 집계 레이어를 CDS 로 내린다. 이 사례는 평가 라인 2,900건을 서비스가 들고 있고, 큐브 13,966행을 브라우저가 묶습니다. 운영 데이터에서는 그렇게 못 합니다. 아래 CDS 구성처럼 큐브 뷰를 만들어 DB 에서 집계합니다.
- 부대비용 조건 유형을 매핑한다. 운임 · 보험 · 관세 · 통관비가 구매오더 조건의 어느 유형에 들어 있는지는 회사마다 다릅니다. 매핑 테이블을 하나 두고 거기서 읽습니다(확인 필요).
- 예상 판매가 · 판매비용의 출처를 정한다. NRV 는 이 두 값에서 나옵니다. 판매 계약 단가를 쓸지, 시세를 쓸지, 어느 시점 값을 쓸지가 정해지지 않으면 “NRV 가 왜 이 숫자냐” 가 끝나지 않습니다.
- 예측 원천을 확정한다. 이 사례의 예측은 직전 평가 때의 가정값입니다. 운영에서는 직전 평가 결과를 스냅숏으로 남기는 방식이 보통이며, 어느 시점의 스냅숏을 기준으로 삼을지 정해야 합니다.
- 환율 기준 시점을 정한다. 장부 원가의 환율이 취득 시점인지 평가일인지에 따라 환율 요인의 의미가 달라집니다.
- 권한을 표준 객체로 건다. 리포트가 로트까지 내려가므로 회사코드 · 플랜트 권한이 그대로 걸려야 합니다. CDS 에 DCL 을 붙입니다.
- 에이전트를 배치에 건다.
SM36에 잡을 등록해 월말 평가 기간에 매일 한 번 돌리는 것이 보통입니다. 보낼 사람과 임계값은 화면에서 고칩니다.
권한에서 흔히 놓치는 자리. 집계 화면은 권한이 없어도 합계가 보이는 수가 있습니다. 어느 플랜트 권한이 없는 사람이 전체 합계는 볼 수 있고 드릴스루만 막히면, 그 사람은 뺄셈으로 다른 플랜트의 숫자를 알아냅니다. 그래서 권한은 드릴스루가 아니라 큐브를 읽는 자리에 겁니다.
CDS 구성
이 사례의 화면은 서비스가 들고 있는 평가 라인 2,900건을 브라우저가 묶습니다. 데모라서 되는 일이고, 운영 데이터에서는 그렇게 하지 않습니다. 운영으로 올릴 때 가장 먼저 하는 일이 집계를 CDS 로 내리는 것입니다. 아래는 그때 만드는 객체들을 레이어 순서대로 적은 것입니다.
코드는 스케치입니다. 필드 이름과 표준 뷰 이름은 릴리스 · 환경에 따라 다르므로 그대로 붙여 넣기 전에 View Browser 로 실제 이름을 확인해야 합니다. 확인이 필요한 자리는 주석에 적어 두었습니다.
뷰 레이어 구성
| 레이어 | 뷰 | 하는 일 | 왜 나누나 |
|---|---|---|---|
| 기준 | ZIMP_NRVMAP | 판매가 근거 · 체류 구간 · 부대비용 조건 분류 매핑 | 분류는 늘 바뀝니다. 코드에 박으면 바뀔 때마다 개발자를 부르게 됩니다. |
| 기준 | ZIMP_NRVSNAP | 직전 평가 결과 스냅숏(예측의 원천) | 예측은 전표에서 나오지 않는 유일한 자료라, 어느 시점 값인지 남겨야 합니다. |
| 기초 | ZI_ImportNrvLot | 입고 로트 한 줄에 장부 원가 · NRV · 충당금을 계산 | 식을 한 곳에만 두어 큐브와 드릴스루가 같은 값을 보게 합니다. |
| 차원 | ZI_ImportNrvSupplier | 공급사 한 행 + 이름 | 큐브에서 join 을 한 번만 걸고 값 도움말이 이 뷰 하나를 보게 합니다. |
| 큐브(실적) | ZI_ImportNrvActualCube | 로트 라인을 차원 조합으로 집계 | 화면이 들고 묶던 일을 DB 로 내립니다. |
| 큐브(예측) | ZI_ImportNrvPlanCube | 스냅숏을 같은 키 모양으로 집계 | 키가 어긋나면 예측이 실적 옆에 붙지 않고 따로 뜹니다. |
| 쿼리 | ZC_ImportNrvQuery | 행 · 열 축 기본 배치와 계산 측정값 | 표준 분석 화면과 Analysis for Office 가 그대로 띄웁니다. |
| 권한 | ZI_IMPORTNRVCUBE (DCL) | 회사코드 · 플랜트 | 집계를 읽는 자리에 걸어야 뺄셈으로 새지 않습니다. |
| 서비스 | ZUI_ImportNrvAnalysis | 쿼리를 OData 서비스로 게시 | 화면이 부르는 주소를 한 곳에서 관리합니다. |
① 분류 매핑 테이블과 예측 스냅숏 테이블
판매가 근거 · 체류 구간 · 부대비용 조건이 어느 묶음에 속하는지를 정하는 자리입니다. 리포트의 모든 분류가 여기서 갈리므로 운영 전환에서 가장 먼저 합의해야 하는 항목입니다. 유효기간을 둔 이유는 분류 체계가 바뀌어도 과거 평가 숫자가 흔들리지 않게 하기 위해서입니다. 스냅숏 테이블은 예측의 원천입니다.
" ────────────────────────────────────────────────────────────────
" ZIMP_NRVMAP — 분류 → 묶음 매핑 (투명 테이블)
" ZIMP_NRVSNAP — 직전 평가 스냅숏 (예측의 원천)
" 코드에 박지 않는 이유 : 분류는 늘 바뀌고, 바뀔 때마다 개발자를
" 부르게 만들면 리포트가 금방 낡는다.
" ────────────────────────────────────────────────────────────────
@EndUserText.label : '재고 평가 분류 매핑'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #C " 고객 유지 — 전송(TR)으로 옮긴다
@AbapCatalog.dataMaintenance : #ALLOWED " 유지보수 뷰를 함께 만들어 둔다
define table zimp_nrvmap {
key mandt : mandt not null;
key map_type : abap.char(8) not null; " BASIS 판매가 근거 · BUCKET 체류 구간 · COND 부대비용 조건
key source_key : abap.char(20) not null; " 원천 값(조건 유형 코드 등)
key valid_from : abap.dats not null;
valid_to : abap.dats;
group_key : abap.char(10); " 리포트에서 쓸 묶음 코드
group_text : abap.char(40);
}
@EndUserText.label : '재고 평가 스냅숏(예측)'
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A " 평가 때마다 쌓이는 업무 데이터
define table zimp_nrvsnap {
key mandt : mandt not null;
key bukrs : bukrs not null;
key snap_ver : abap.char(6) not null; " 직전 평가 시점(YYYYMM)
key matnr : matnr not null;
key lot_key : abap.char(20) not null; " 입고 로트(자재 문서 + 품목)
eval_period : abap.char(6);
qty : abap.quan(13,3);
cost_unit : abap.curr(15,2);
nrv_unit : abap.curr(15,2);
waers : waers;
}
② 공급사 차원 뷰
분류 기준에 공급사 이름을 붙이는 뷰입니다. 차원 뷰를 따로 두면 큐브에서 join 을 한 번만 걸 수 있고, 값 도움말과 텍스트가 이 뷰 하나를 봅니다. 아래 참조 뷰 이름은 릴리스에 따라 다를 수 있어 View Browser 로 실제 이름을 확인한 뒤 씁니다(확인 필요).
" ────────────────────────────────────────────────────────────────
" ZI_ImportNrvSupplier — 공급사 차원
" 공급사 하나당 한 행. 이름은 표준 공급사 뷰에서 가져온다.
" 참조 뷰 이름은 릴리스마다 다를 수 있으므로 확인 필요.
" ────────────────────────────────────────────────────────────────
@AbapCatalog.viewEnhancementCategory : [#NONE]
@AccessControl.authorizationCheck : #NOT_REQUIRED
@EndUserText.label : '수입 공급사 차원'
@Analytics.dataCategory : #DIMENSION
@ObjectModel.representativeKey : 'Supplier'
define view entity ZI_ImportNrvSupplier
as select from I_Supplier as Sup
{
@ObjectModel.text.element : [ 'SupplierName' ]
key Sup.Supplier as Supplier,
@Semantics.text : true
Sup.SupplierName as SupplierName,
@EndUserText.label : '공급사 국가'
Sup.Country as Country
}
③ 입고 로트 기초 뷰
장부 원가와 NRV, 평가충당금을 한 곳에서만 계산하는 뷰입니다. 큐브도 드릴스루도 이 뷰를 읽으므로 칸 금액과 라인 합계가 같아질 수밖에 없는 구조가 됩니다. 외화 단가를 원화로 바꾸는 환산도 여기서 한 번만 합니다. 필드 이름과 조인 키는 환경마다 다르므로 스케치입니다.
" ────────────────────────────────────────────────────────────────
" ZI_ImportNrvLot — 입고 로트 기초 뷰
" 입고 로트 한 줄에 외화 단가 · 환율 · 부대비용 · NRV · 충당금을 계산한다.
" 식은 이 뷰에만 둔다. 큐브와 드릴스루가 같은 값을 보게 하려는 것이다.
" 조인 키와 부대비용 · 판매가 원천은 환경마다 다르므로 확인 필요.
" ────────────────────────────────────────────────────────────────
@AbapCatalog.viewEnhancementCategory : [#NONE]
@AccessControl.authorizationCheck : #CHECK
@EndUserText.label : '수입 재고 평가 로트'
define view entity ZI_ImportNrvLot
with parameters
p_evaldate : abap.dats
as select from ekpo as Po
inner join ekko as Hd on Hd.ebeln = Po.ebeln
inner join mseg as Gr on Gr.ebeln = Po.ebeln
and Gr.ebelp = Po.ebelp
and Gr.bwart = '101' " 입고
{
key Gr.mblnr as MaterialDocument,
key Gr.zeile as MaterialDocumentItem,
Hd.bukrs as CompanyCode,
Hd.lifnr as Supplier,
Po.werks as Plant,
Po.matkl as MaterialGroup,
Hd.waers as DocCurrency,
Gr.budat_mkpf as GoodsReceiptDate,
Gr.menge as Quantity,
Po.meins as BaseUnit,
" 외화 단가를 원화로 — 환산 기준일은 취득일. 평가일로 바꾸려면
" exchange_rate_date 를 $parameters.p_evaldate 로 교체한다(합의 사항).
currency_conversion(
amount => Po.netpr,
source_currency => Hd.waers,
target_currency => cast( 'KRW' as abap.cuky ),
exchange_rate_date => Gr.budat_mkpf,
exchange_rate_type => 'M',
error_handling => 'SET_TO_NULL' ) as CostUnitBase
" 부대비용 단가 · 예상 판매 단가 · 추정 판매비용 단가는 각각
" 송장 조건 / 판매 계약(시세) 원천에서 같은 방식으로 붙인다.
" NrvUnit = SellUnit - SellCostUnit
" AllowAmount = case when CostUnit > NrvUnit
" then Quantity * ( CostUnit - NrvUnit ) else 0 end
}
④ 실적 큐브
차원 조합마다 한 행입니다. group by 에 올린 필드가 곧 리포트에서 쓸 수 있는 차원이 됩니다. 여기에 없는 차원은 화면에서 끌어다 놓을 수 없습니다. 아래 키 모양이 예측 큐브와 같아야 두 값이 한 칸에 나란히 붙습니다.
" ────────────────────────────────────────────────────────────────
" ZI_ImportNrvActualCube — 실적 큐브
" 차원 조합마다 한 행. 입고 로트 라인을 DB 에서 더해 올린다.
" 화면이 들고 묶던 일을 여기로 내리는 것이 운영 전환의 핵심이다.
" ────────────────────────────────────────────────────────────────
@AbapCatalog.viewEnhancementCategory : [#NONE]
@AccessControl.authorizationCheck : #CHECK " ← DCL 을 반드시 붙인다
@EndUserText.label : '수입 재고 저가평가 큐브(실적)'
@Analytics.dataCategory : #CUBE
define view entity ZI_ImportNrvActualCube
with parameters
p_evaldate : abap.dats
as select from ZI_ImportNrvLot( p_evaldate : $parameters.p_evaldate ) as Lot
association [0..1] to ZI_ImportNrvSupplier as _Supplier
on _Supplier.Supplier = $projection.Supplier
{
key Lot.CompanyCode as CompanyCode,
key left( cast( Lot.GoodsReceiptDate as abap.char(8) ), 6 ) as EvalPeriod,
key Lot.Supplier as Supplier,
key Lot.Plant as Plant,
key Lot.MaterialGroup as MaterialGroup,
_Supplier,
" ── 측정값
@DefaultAggregation : #SUM
@Semantics.amount.currencyCode : 'Currency'
sum( Lot.AllowAmount ) as AllowanceAmount,
@DefaultAggregation : #SUM
@Semantics.amount.currencyCode : 'Currency'
sum( Lot.CostAmount ) as CostAmount,
@DefaultAggregation : #SUM
count( * ) as LotCount,
cast( 'KRW' as abap.cuky ) as Currency
}
group by
Lot.CompanyCode,
left( cast( Lot.GoodsReceiptDate as abap.char(8) ), 6 ),
Lot.Supplier, Lot.Plant, Lot.MaterialGroup
⑤ 예측 큐브
직전 평가 스냅숏을 실적 큐브와 같은 키 모양으로 집계합니다. 두 큐브의 키가 어긋나면 예측이 실적 옆에 붙지 않고 따로 뜹니다. 어느 시점의 스냅숏을 기준으로 삼을지는 파라미터로 받아 화면에서 고르게 합니다.
" ────────────────────────────────────────────────────────────────
" ZI_ImportNrvPlanCube — 예측 큐브 (직전 평가 스냅숏)
" 실적 큐브와 키 모양이 같아야 한다. 다르면 두 값이 한 칸에 붙지 않는다.
" ────────────────────────────────────────────────────────────────
@AbapCatalog.viewEnhancementCategory : [#NONE]
@AccessControl.authorizationCheck : #CHECK
@EndUserText.label : '수입 재고 저가평가 큐브(예측)'
@Analytics.dataCategory : #CUBE
define view entity ZI_ImportNrvPlanCube
with parameters
p_snapver : abap.char(6)
as select from zimp_nrvsnap as Snap
{
key Snap.bukrs as CompanyCode,
key Snap.eval_period as EvalPeriod,
key Snap.lot_key as LotKey,
@DefaultAggregation : #SUM
@Semantics.amount.currencyCode : 'Currency'
sum( case when Snap.cost_unit > Snap.nrv_unit
then Snap.qty * ( Snap.cost_unit - Snap.nrv_unit )
else 0 end ) as PlannedAllowance,
Snap.waers as Currency
}
where Snap.snap_ver = $parameters.p_snapver
group by Snap.bukrs, Snap.eval_period, Snap.lot_key, Snap.waers
⑥ 분석 쿼리
행 · 열 축의 기본 배치와 필터, 계산 측정값을 정하는 뷰입니다. 이 뷰를 만들어 두면 표준 분석 화면과 Analysis for Office 가 같은 쿼리를 그대로 띄웁니다. 충당금률처럼 식으로 나오는 값은 여기에 계산 측정값으로 둡니다.
" ────────────────────────────────────────────────────────────────
" ZC_ImportNrvQuery — 분석 쿼리
" 행 · 열 기본 배치와 계산 측정값. 표준 분석 화면이 그대로 띄운다.
" ────────────────────────────────────────────────────────────────
@AccessControl.authorizationCheck : #CHECK
@EndUserText.label : '수입 재고 저가평가 분석'
@Analytics.query : true
@Metadata.ignorePropagatedAnnotations : true
define view entity ZC_ImportNrvQuery
with parameters
@Environment.systemField : #SYSTEM_DATE
p_evaldate : abap.dats
as select from ZI_ImportNrvActualCube( p_evaldate : $parameters.p_evaldate )
{
@AnalyticsDetails.query.axis : #ROWS
@AnalyticsDetails.query.display : #KEY_TEXT
@Consumption.filter : { selectionType : #RANGE, multipleSelections : true }
key MaterialGroup,
@AnalyticsDetails.query.axis : #ROWS
@Consumption.filter : { selectionType : #RANGE, multipleSelections : true }
key Supplier,
@AnalyticsDetails.query.axis : #COLUMNS
@Consumption.filter : { mandatory : true, selectionType : #INTERVAL }
key EvalPeriod,
@AnalyticsDetails.query.axis : #COLUMNS
@EndUserText.label : '평가충당금'
AllowanceAmount,
@EndUserText.label : '장부 원가'
CostAmount,
@EndUserText.label : '충당금률(%)'
@AnalyticsDetails.query.formula : 'AllowanceAmount / CostAmount * 100'
@AnalyticsDetails.query.decimals : 2
cast( 0 as abap.dec(9,2) ) as AllowanceRate
}
⑦ 권한 (DCL)
집계 화면에서 권한을 드릴스루에만 걸면, 권한 없는 사람이 전체 합계와 자기 몫의 차이를 빼서 다른 플랜트의 숫자를 알아냅니다. 그래서 큐브를 읽는 자리에 겁니다. 권한 객체 이름은 환경 표준을 확인합니다(확인 필요).
" ────────────────────────────────────────────────────────────────
" ZI_IMPORTNRVCUBE — 권한 (DCL)
" 권한을 드릴스루에만 걸면 뺄셈으로 다른 플랜트의 숫자가 드러난다.
" 그래서 큐브를 읽는 자리에 건다.
" ────────────────────────────────────────────────────────────────
@EndUserText.label : '수입 재고 평가 큐브 권한'
@MappingRole : true
define role ZI_IMPORTNRVCUBE {
grant select on ZI_ImportNrvActualCube
where ( CompanyCode ) = aspect pfcg_auth ( F_BKPF_BUK, BUKRS, ACTVT = '03' )
and ( Plant ) = aspect pfcg_auth ( M_MSEG_WWA, WERKS, ACTVT = '03' );
}
⑧ 서비스 정의
쿼리를 OData 서비스로 게시하는 자리입니다. 서비스 바인딩에서 OData V2 를 선택해 게시하고, 활성화 후 화면 쪽 manifest.json 의 서비스 주소를 이 주소로 바꿉니다. 이 단계는 환경마다 절차가 달라 운영 시점에 정합니다.
" ────────────────────────────────────────────────────────────────
" ZUI_ImportNrvAnalysis — 서비스 정의
" 서비스 바인딩(OData V2)은 ADT 에서 만들어 게시한다.
" ────────────────────────────────────────────────────────────────
@EndUserText.label : '수입 재고 저가평가 분석 서비스'
define service ZUI_ImportNrvAnalysis {
expose ZC_ImportNrvQuery as NrvQuery;
}
운영 시점에 해야 할 일
개발보다 정하는 일이 많습니다. 아래 표의 왼쪽은 대부분 코딩이 아니라 합의입니다.
| 해야 할 일 | 무엇을 정하나 | 정하지 않으면 | 누가 |
|---|---|---|---|
| 분류 매핑 | 판매가 근거 · 체류 구간 · 부대비용 조건의 분류와 묶음 | 리포트 분류가 기존 평가 보고서와 어긋나 첫 회의에서 막힙니다 | 원가 · 회계팀 |
| 부대비용 조건 유형 | 운임 · 보험 · 관세 · 통관비가 구매오더 조건의 어느 유형인지 | 부대비용 단가가 비어 장부 원가가 낮게 나옵니다 | 구매 · 원가팀 |
| 예상 판매가 · 판매비용 출처 | 판매 계약 단가 · 시세 중 무엇을 어느 시점에 쓸지 | “NRV 가 왜 이 숫자냐” 가 반복됩니다 | 영업 · 재무 |
| 환율 유형 · 환산 시점 | 환율 유형과 취득일 · 평가일 중 기준 | 환율 요인의 의미가 사람마다 달라집니다 | 자금 · 회계팀 |
| 부호 규칙 · 단위 | 충당금은 비용 방향 양수로 둘지, MT 환산 기준은 무엇인지 | 손익 방향이 뒤집히거나 수량을 잘못 더합니다 | 회계 · 물류 |
| 예측 원천 확정 | 직전 평가 스냅숏의 시점과 보관 방식 | 예측이 매번 달라져 차이를 비교할 수 없습니다 | 재무팀 |
| 차원 범위 | 큐브 group by 에 올릴 차원(원산지 · 용도 등) | 나중에 뷰를 고치고 다시 전송해야 합니다 | 현업 · 개발 |
| 권한 설계 | 회사코드 · 플랜트 중 무엇으로 자를지, 전체 합계를 누구까지 볼지 | 뺄셈으로 다른 플랜트 숫자가 새어 나갑니다 | 보안 · 권한 |
| 성능 기준 | 한 번 조회가 몇 초까지 허용되는지 | 운영 첫날 “느리다” 로 되돌아옵니다 | Basis · 현업 |
| 대사 체계 | 표준 T-code 와 맞출 항목과 주기 | 숫자를 믿지 않아 아무도 쓰지 않습니다 | 회계팀 |
| 전송(TR) 순서 | 테이블 → 차원 → 기초 → 큐브 → 쿼리 → DCL → 서비스 | 이송 중 활성화 오류가 납니다 | 개발 |
| 서비스 활성화 · 주소 교체 | 서비스 게시와 화면 설정의 서비스 주소 교체 | 화면이 데모 데이터를 계속 읽습니다 | 개발 · Basis |
| 배치 등록 | SM36 잡 주기와 대상 범위 | 에이전트가 사람이 열 때만 돕니다 | Basis · 현업 |
숫자를 믿을 수 있는가 — 검증 결과
리포트에서 가장 비싼 질문은 “이 숫자 맞아?” 입니다. 그래서 만드는 쪽에서 먼저 대사식을 세워 두고 전수로 돌렸습니다. 아래는 이 사례(가상 샘플 데이터) 기준 결과이며, 도입 포인트의 사례와 같은 숫자입니다.
| 대사식 | 검사 건수 | 차이 |
|---|---|---|
| 큐브 합계 = 원천 라인 합계(평가월 × 측정값) | 48 | 0 |
| 예측 큐브 합계 = 원천 라인 예측 열 합계 | 48 | 0 |
| 라인 충당금 재계산 = 저장 충당금 | 2,900 | 0 |
| 요인 합 − 총차이(전체 · 평가월 · 자재그룹 · 공급사 범위) | 17 | 0 |
| 검산 엔티티 차이(큐브 합계 − 라인 합계) | 8 | 0 |
모든 대사식이 차이 0 입니다. 의도적으로 섞어 둔 예외는 “예측 없던 로트” 325건이며, 오류가 아니라 요인으로 분리해 합계에 포함했습니다. 화면 쪽은 이와 별도로 브라우저 자동화로 돌려 확인했습니다 — 축을 바꿔도 합계가 변하지 않는지, 칸 금액과 라인 합계가 같은지, 요인 합이 총차이와 같은지입니다.
운영 데이터로 갈 때 — 입고 로트가 천만 건이면
이 사례는 평가 라인 2,900건이 큐브 13,966행이 됩니다. 로트가 천만 건이 되어도 큐브 행 수는 로트 건수가 아니라 차원 조합 수를 따라갑니다. 문제는 조합이 많을 때입니다.
| 구간 | 어떻게 되나 | 무엇을 손보나 |
|---|---|---|
| 큐브 수천 행 | 지금 방식 그대로 — 브라우저가 들고 묶어도 걸리지 않습니다 | 손볼 것 없음 |
| 큐브 수만 행 | 축을 바꿀 때 눈에 띄게 걸립니다 | CDS 에서 집계 수준을 올립니다(쓰지 않는 차원을 빼거나 기간을 묶음) |
| 큐브 수십만 행 | 브라우저가 들고 있을 수 없습니다 | 묶기를 서비스로 옮기고 필요한 조합만 받습니다 |
| 원천 라인 조회 | 전체를 내리면 수백 MB 가 됩니다 | $top 으로 500행만 받고 건수는 $inlinecount 로 숫자만 받습니다 |
| 입고 로트 천만 건 | 큐브 행 수는 로트 건수가 아니라 차원 조합 수를 따라갑니다 | 조회 기간과 회사코드를 필수 파라미터로 두고, 기간 · 플랜트 인덱스를 확인합니다 |
자주 묻는 질문
도입 상담과 데모에서 자주 나오는 질문들입니다. 네 묶음으로 나눠 적었습니다.
숫자와 산식
평가충당금은 어떻게 계산합니까?
입고 로트 한 줄마다 수량 × max(0, MT당 장부 원가 − MT당 NRV) 로 계산합니다. 장부 원가는 외화 단가에 환율을 곱하고 부대비용 확정 단가를 더한 값이고, NRV 는 예상 판매 단가에서 추정 판매비용 단가를 뺀 값입니다.
장부 원가가 NRV 이하이면 그 줄의 충당금은 0 입니다. 큐브는 이 줄들을 차원 조합으로 더한 것이라, 어느 축으로 묶어도 합계가 같습니다.
칸 금액과 원천 라인 합계가 정말 같습니까?
같습니다. 큐브가 원천 평가 라인을 더해 만든 값이기 때문입니다. 샘플 검증에서 확인한 칸 5개 모두 칸을 눌렀을 때 열리는 라인 합계와 같았고, 큐브 48개 조합(평가월 6개 × 측정값 8개)을 원천 라인 합계와 전수로 대조해 차이가 0 이었습니다.
이것을 눈으로 확인할 수 있게 드릴스루 맨 위에 건수와 합계를 적어 둡니다. 라인을 일부만 읽은 동안에는 대조를 보류하고 그렇다고 알려 줍니다.
요인분해의 합이 정말 총차이와 같습니까?
같습니다. 우연이 아니라 그렇게 되는 방식을 골랐습니다. 예측값에서 실적값으로 한 번에 한 요인씩 실제 값으로 바꾸면서 같은 식을 다시 계산하므로, 각 단계의 차이를 모두 더하면 처음과 끝의 차이가 됩니다.
그래서 잔차가 구조적으로 0 입니다. 화면 맨 아래 검산 줄에 “요인 합 − 총차이” 가 적히고, 17개 범위(전체 · 평가월 · 자재그룹 · 공급사)에서 모두 0 이었습니다.
요인의 순서를 바꾸면 요인별 금액이 달라지지 않습니까?
달라질 수 있습니다. 순차 대입은 요인을 어떤 순서로 바꾸느냐에 따라 요인별 몫이 조금씩 달라지는 방식입니다. 이 앱은 수량 → 외화 단가 → 환율 → 부대비용 → 예상 판매가 → 판매비용 → 예측 없던 로트 순서를 고정해 두었습니다.
달라지지 않는 것은 합계입니다. 순서가 어떻든 요인 합은 총차이와 같습니다. 순서를 회사 기준으로 바꾸고 싶다면 합의가 필요한 항목입니다.
“예측 없던 로트” 는 무엇입니까?
직전 평가 때의 예측에 없었다가 이번 평가에 새로 잡힌 입고 로트입니다. 샘플에는 325건이 의도적으로 섞여 있고, 이 몫은 다른 여섯 요인으로 나눌 수 없어 따로 한 줄로 세웁니다.
사례에서 증가분의 약 66%가 여기에서 났습니다. 이 요인이 크면 단가나 환율이 아니라 입고 계획과 예측이 어긋났는지를 먼저 봅니다.
충당금률은 왜 4.69% 입니까? 기준이 있습니까?
샘플 전체 범위에서 평가충당금을 장부 원가로 나눈 값입니다. 기준이 있는 값이 아니라 샘플 데이터의 결과이며, 임계값과 마찬가지로 가정값입니다.
운영에서는 회사의 평가 정책에 따라 판단 기준을 정합니다. 이 앱은 비율을 계산해 보여 줄 뿐 좋고 나쁨을 단정하지 않습니다.
화면과 조작
축을 바꿀 때마다 서버를 다시 부릅니까?
아닙니다. 조회를 누르면 큐브와 예측을 한 번 읽어 오고, 이후 행 · 열을 바꾸는 조작은 브라우저가 들고 있는 데이터 위에서 합니다. 검증에서도 축을 바꾼 뒤 서버 요청이 0건이고 총합이 같음을 확인했습니다.
칸을 눌러 원천 라인으로 내려갈 때만 서비스를 다시 부릅니다.
행 · 열을 몇 단계까지 쌓을 수 있습니까?
행 축은 3단계, 열 축은 2단계입니다. 열 조합이 36개를 넘으면 더 추가할 수 없고, 이미 넘은 경우에는 표를 그리지 않고 범위를 좁히라는 안내를 띄웁니다. 샘플에서는 열 조합이 42개일 때 이 안내가 떴습니다.
반쯤 그린 표를 주면 그 표를 믿게 되기 때문에 그리지 않는 쪽을 택했습니다.
차이가 음수인데 초록으로 보이기도 합니다. 맞습니까?
맞습니다. 색은 금액 부호가 아니라 충당금에 준 영향으로 칠합니다. 충당금을 늘린 방향은 붉은색, 줄인 방향은 초록색입니다. 그리고 금액 차이와 비율 차이가 둘 다 임계를 넘을 때만 색이 입혀집니다(기본 100만원 · 10퍼센트, 가정값).
임계값 아래의 작은 차이에는 색이 없어서, 색이 있는 칸만 보면 점검 대상이 걸러집니다.
변동 사유는 어디에 저장됩니까? 축을 바꾸면 사라집니까?
서비스에 저장되고, 키는 조회 범위와 행 경로입니다. 그래서 축 배치를 바꾸거나 트리를 다시 펼쳐도 같은 행이면 사유가 따라오고, 새로 고친 뒤에도 남습니다. 샘플 검증에서 저장 후 새로 고침해도 사유가 유지됨을 확인했습니다.
사유가 적힌 차이는 AI 분석이 점검 대상에서 건너뜁니다.
휴대폰에서도 쓸 수 있습니까?
390px 폭에서 영역이 세로로 쌓이고 차트가 표 아래로 내려가는 것을 확인했습니다. 표는 가로로 스크롤됩니다. 다만 축을 짜는 작업은 큰 화면이 편해서, 휴대폰은 숫자를 확인하고 사유를 보는 용도에 가깝습니다.
AI 분석과 에이전트
AI 가 숫자를 만들어 냅니까?
아닙니다. 금액과 비율은 서비스가 큐브에서 계산하고, 해설은 그 숫자를 읽어 문장으로 옮길 뿐입니다. 해설에 쓴 숫자의 근거 표를 화면에서 펼쳐 볼 수 있습니다.
기본 설정은 규칙 기반 해설이라 외부 모델이 없어도 같은 근거로 동작합니다.
AI 에이전트는 무엇을 합니까?
감시 규칙 여섯 개를 돌려, 임계값을 넘은 항목을 받을 역할(CFO · 구매 · 자금 · 물류) 관점의 보고로 대기함에 올립니다. 실행할 때마다 시각 · 호출 주체 · 판정이 활동 기록에 남습니다.
하루에 한 번만 도는 규칙이라 같은 날 두 번째 실행은 제한으로 기록됩니다. 임계값은 화면에서 바꿔 저장합니다.
에이전트를 사람이 누르지 않아도 돌릴 수 있습니까?
서비스의 에이전트 실행 호출이 화면의 버튼과 같은 일을 하므로, 배치 잡이 그 호출을 주기적으로 두드리면 됩니다. 호출 주체가 기록에 남아 사람이 누른 것과 구분됩니다.
실제 배치 등록은 SM36 에서 하며 주기와 대상 범위는 운영 시점에 정합니다.
PowerPoint 보고서는 어디서 만들어집니까?
브라우저 안에서 만들어집니다. 외부 라이브러리 없이 압축과 XML 을 직접 만들기 때문에 서버에 파일을 올리지 않습니다. 현재 보고 있는 범위의 표와 요인 워터폴을 담고, 내려받은 파일은 형식 검사에서 6장으로 열렸습니다.
도입과 운영
이 화면이 표준 평가 화면을 대체합니까?
대체하지 않습니다. 평가 실행과 원장 반영은 SAP 표준 T-code 가 담당하고, 이 화면은 그 결과를 여러 축으로 조회하고 검증하는 관점을 더합니다. 기존 화면도 그대로 두는 것이 보통이며, 감사와 세무 신고 대응은 표준 거래에 두는 편이 안전합니다.
충당금 인식과 환입의 최종 판단은 누가 합니까?
이 화면은 분류 · 집계 · 대사를 돕는 점검 도구이며 최종 판단은 회사와 감사인이 합니다. 세무 신고에 쓰는 금액은 회사와 세무 대리인이 따로 확정합니다. 화면의 판정 문구도 “점검 필요” 수준의 안내입니다.
언제부터 적용해야 합니까?
이 글에서 확인된 사실은 재고자산을 원가와 순실현가능가치 중 작은 금액으로 측정하도록 한 기준서의 원칙뿐입니다. 시행일과 경과 규정, 회사별 적용 범위는 원문과 회계 정책을 확인한 뒤 정합니다. 이 앱은 기준이 정해진 뒤 그 기준에 맞는 점검을 돕는 도구입니다.
샘플의 값은 실제 값입니까?
아닙니다. 공급사 · 문서번호 · 단가 · 환율 · 임계값은 모두 가상이며, 임계값과 비율은 가정값입니다. 사례의 요인별 금액도 샘플의 결과이고 실제 환경의 크기를 말하지 않습니다.
외화와 환율은 어떻게 처리합니까?
취득 단가는 외화로 들고 있다가 환율을 곱해 원화 장부 원가를 만듭니다. 환율은 요인분해의 독립된 요인이라 환율이 바뀐 영향만 따로 보입니다. 환율 유형과 취득일 · 평가일 중 어느 시점을 쓸지는 운영 시점에 정할 항목입니다.
샘플에서는 환율도 가정값입니다.
운영 시스템에 연결하는 절차와 소요는 어떻게 됩니까?
순서는 정해져 있습니다. 먼저 분류와 환율 · 판매가 원천에 대한 합의를 하고, CDS 객체를 만들어 이송하고, 서비스를 게시한 뒤 화면의 서비스 주소를 바꿉니다. 합의 항목이 많아서 개발 일정보다 합의 일정이 소요를 좌우하는 경우가 많습니다.
구체적인 기간은 환경마다 달라 이 글에서는 말하지 않습니다.
권한은 어떻게 걸립니까?
CDS 에 DCL 을 붙여 회사코드와 플랜트 권한을 표준 권한 객체로 따릅니다. 별도의 권한 체계를 만들지 않습니다.
한 가지 주의가 있습니다. 권한을 드릴스루에만 걸면 전체 합계와 자기 몫의 차이로 다른 플랜트 숫자가 드러납니다. 그래서 큐브를 읽는 자리에 거는 것을 기본으로 합니다.
데이터가 아주 많으면 느려지지 않습니까?
데모는 서비스가 평가 라인을 들고 브라우저가 큐브를 묶는 구조라 운영 규모에서는 쓰지 않습니다. 운영에서는 집계를 CDS 로 내려 DB 가 묶게 하고, 조회 기간 · 회사코드를 필수로 두며, 원천 라인은 500행씩 나눠 읽습니다. 큐브 행 수는 로트 건수가 아니라 차원 조합 수를 따라가므로 조합이 지나치게 많아지지 않게 차원 범위를 정합니다.
분류 체계가 바뀌면 어떻게 됩니까?
분류는 매핑 테이블에서 읽으므로 코드를 고치지 않고 테이블 행만 바꿉니다. 유효기간을 두어 과거 평가 숫자가 흔들리지 않게 합니다. 정기적으로 손이 가는 곳은 사실상 이 매핑 하나입니다. 새 분류가 생기고 매핑을 적지 않으면 ‘미분류’ 로 떨어져 합계가 어긋나므로 확인 절차를 둡니다.
숫자가 기존 보고서와 다르면 어떻게 확인합니까?
순서가 있습니다.
① 조회 범위가 같은지 봅니다 — 회사코드, 기간, 평가일. 가장 흔한 원인입니다.
② 분류 매핑과 환율 기준 시점을 봅니다.
③ 드릴스루 라인의 건수와 합계를 표준 T-code 의 같은 조건과 맞춥니다.
④ 그래도 다르면 요인분해로 어느 요인에서 갈렸는지 좁힙니다.
리포트를 더 만드는 것보다 축을 바꾸게 하는 편이 낫습니까?
공급사별 · 자재그룹별 · 플랜트별로 리포트를 따로 만들면 숫자가 어긋나는 지점이 함께 늘어납니다. 큐브를 한 번 올려 두면 축은 보는 사람이 바꾸고, 칸에서 원천 라인까지 같은 숫자로 이어집니다. 새로운 관점이 필요할 때 리포트를 새로 만드는 대신 차원 하나를 더하면 됩니다.