수입 솔루션 · 컨테이너 체화·지체 비용

수입 체화·지체 비용 다차원 분석 — 선사·입항지·월로 돌려 보고 예정 대비 차이를 요인으로 가르는 수입 물류비 리포트

큐브 집계 · 끌어다 놓는 축 · 칸에서 컨테이너 라인까지의 드릴스루 · 예정 대비 차이와 일곱 요인분해 · 행에 남는 변동 사유 · 숫자를 모델에 맡기지 않는 AI 분석 · 스스로 도는 AI 에이전트 — 소개 영상과 실제 화면 33종, 그리고 CDS 코드까지

소개 영상블로그 목차 순서대로 · 자막 포함

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

수입 담당자가 월말에 가장 자주 받는 질문은 "이번 달 체화료와 지체료가 왜 예정보다 많이 나왔나" 입니다. 비용은 선사 청구서, 터미널 보관료 정산서, 포워더 자료에 흩어져 있고, 각각 일 요율과 무료기간과 청구 통화가 다릅니다. 지금은 이 자료를 엑셀에 모아 선사별 · 입항지별로 다시 합산하고, 합계가 맞는지 확인하는 데 시간을 씁니다. 정작 중요한 "얼마가 예정을 넘었고 그 이유가 무엇인가" 는 그 뒤에야 이야기됩니다.

이 화면은 그 자리를 다릅니다. 컨테이너 라인에서 체화료 · 지체료 · 보관료 · 기타 추가비용을 계산해 한 큐브로 묶고, 선사 · 입항지 · 터미널 · 입항월 같은 축을 끌어다 놓으며 보게 합니다. 예정과 비교하면 총차이가 일곱 요인으로 갈라지고, 숫자 칸을 누르면 컨테이너 라인으로 내려갑니다. 구매 오더 · 입고 · 송장 문서의 표준 데이터를 이어받는 조회·점검 도구이며, 표준 실행은 SAP 표준 T-code 가 담당하고 이 화면은 조회·검증 관점을 더해 확장합니다.

한 줄 요약 — 체화·지체 비용을 선사 · 입항지 · 월로 돌려 보다가 칸 하나로 컨테이너 라인까지 내려가고, 예정 대비 차이를 일곱 요인으로 가르는 다차원 분석 리포트입니다.

핵심 포인트 여덟 가지

핵심 포인트고객이 얻는 것지금 방식이라면
① 축을 바꿔도 합계가 갈라지지 않는 피벗선사 · 입항지 · 터미널 · 입항월 등 11개 차원을 끌어다 놓아 행 3단계 · 열 2단계로 봅니다. 서버를 다시 부르지 않고 한 큐브에서 다시 묶습니다.선사 청구서, 포워더 자료, 터미널 정산서를 따로 엑셀 피벗으로 만들고 합계를 다시 맞춥니다.
② 칸에서 컨테이너 라인까지숫자 칸을 누르면 그 금액을 만든 컨테이너 라인이 열리고 칸 값과 라인 합이 같은지 바로 보입니다.청구서 번호와 선하증권 번호를 찾아 표준 화면과 엑셀을 번갈아 대조합니다.
③ 예정 대비 차이를 같은 표에서비교 기준을 예정으로 바꾸면 같은 표에 실적 · 예정 · 차이 · 증감률이 붙습니다. 금액과 비율을 둘 다 넘는 칸만 색이 입혀집니다.실적 리포트와 예정 대비 리포트를 따로 만들고 기준이 서로 다른 채로 회의에 들어갑니다.
④ 총차이를 일곱 요인으로물량 · 무료기간 · 지연일수 · 일 요율 · 환율 · 기타비용 · 미계획을 한 줄씩 나누고, 합이 총차이와 같은지 매번 검산합니다."왜 늘었나" 를 엑셀로 풀며 산식이 사람마다 달라집니다.
⑤ 변동 사유를 그 행에 남긴다통관 서류 · 검사 대기 · 운송 차량 · 공장 일정 같은 사유가 조회 범위와 행 경로에 묶여 남아, 축을 바꾸거나 다음 달에도 따라옵니다.같은 질문을 매달 다시 하고 지난달 답은 메일함에서 찾습니다.
⑥ 역할별 요약과 AI 분석CFO · 구매 · 물류 · 자금 책임자별로 앞세우는 지표가 바뀝니다. AI 분석은 서비스가 계산한 숫자만 문장으로 옮깁니다.역할마다 보고서를 따로 만들고, 숫자를 누가 만든 것인지 따져야 합니다.
⑦ 사람이 열지 않아도 도는 감시규칙마다 임계값과 받을 역할이 붙어, 걸리면 그 역할의 눈으로 다시 쓴 보고가 대기함에 올라갑니다. 하루 한 번 제한은 서버가 판정합니다.비용이 튄 날 아무도 화면을 열지 않으면 다음 정산서에서야 알게 됩니다.
⑧ 표준 문서와 이어 맞추는 점검구매 오더 · 입고 · 송장 문서가 가진 같은 필드를 이어받아 표준 T-code 로 원천을 다시 확인하는 길을 둡니다. 레이아웃은 이름 붙여 저장합니다.표준 화면과 엑셀 사이에 숫자를 옮겨 적다가 어긋납니다.

사례로 보는 효과

검증용 샘플 데이터(컨테이너 라인 3,880건 · 선하증권 2,221건 · 6개월)에서 체화·지체 비용 실적은 47.00억원, 예정은 29.97억원으로 +17.03억원(+56.8%) 차이가 났습니다. 합계만 보면 "비용이 늘었다" 에서 끝납니다. 요인분해로 가르자 지연일수 요인이 +13.09억원으로 총차이의 76.8% 를 차지했고, 예정에 없던 라인(미계획) 250건이 +3.08억원, 일 요율 +0.84억원, 기타비용 +0.60억원, 환율 +0.19억원, 무료기간 +350만원이었으며 물량은 −0.80억원으로 비용을 줄였습니다. 일곱 요인의 합은 총차이와 1원도 어긋나지 않았습니다.

무료기간은 전체로는 +350만원으로 작아 보이지만, 선사별로 내려가면 한 선사에서 +1.44억원이 나오고 다른 선사에서 상쇄됩니다. 같은 합계 뒤에 다른 이야기가 있다는 뜻입니다. 숫자의 정합성은 라인 3,880건 전수에서 확인했습니다(본문 "숫자를 믿을 수 있는가" 참고).

도입하면 달라지는 것

  • 월 정산 준비 — 선사별 · 입항지별 합산과 예정 대비 표가 한 화면에서 나와 엑셀 취합이 줄어듭니다.
  • 회의의 주제 — "어느 숫자가 맞나" 가 아니라 "어느 요인을 줄일 것인가" 를 이야기합니다. 지연일수가 큰 선사 · 입항지 · 지연 사유가 바로 보입니다.
  • 선사 협상 자료 — 무료기간 조건이 비용에 준 영향을 선사별로 보여 줄 수 있습니다.
  • 기록의 연속성 — 변동 사유와 레이아웃이 남아 같은 설명을 다시 하지 않습니다.
  • 놓치지 않는 점검 — 임계값을 넘은 선사 · 터미널 · 통화가 대기함에 올라옵니다.

이런 회사에 맞습니다

컨테이너로 원자재 · 부품 · 상품을 정기적으로 들여오고, 선사 · 포워더 · 터미널이 여러 곳이며, 외화(달러 · 유로 · 위안 등)로 청구되는 체화료와 지체료가 월 단위로 쌓이는 제조 · 유통 회사에 맞습니다. 수입 담당 · 물류 담당 · 구매 담당 · 자금 담당이 같은 숫자를 서로 다른 관점으로 보고 싶을 때, 그리고 경영지원 조직이 비용이 늘어난 이유를 요인으로 설명받고 싶을 때 쓰입니다. 컨테이너 반출 · 반납 일자 같은 물류 이벤트를 SAP 에 어떤 형태로든 갖고 있어야 하며, 이 부분은 도입 시점에 확인할 대상입니다.

실행 화면

사용 방법

  1. 조회조건 입력 — 회사코드(필수)와 시작 · 종료 입항월(필수)을 정합니다. 선사 · 입항지 · 터미널 같은 차원 값은 선택 사항이며 비우면 전체입니다. 조회 전에도 틀이 먼저 보입니다.
  2. 조회 — 조회조건 영역 오른쪽 끝의 조회 버튼을 누르거나 입력칸에서 Enter 키를 누릅니다. 기본 레이아웃에 자동 조회를 지정했다면 열자마자 조회된 상태로 시작합니다.
  3. 요약 확인 — 임원 요약에서 역할(CFO · 구매 · 물류 · 자금)을 바꾸면 앞세우는 지표와 쪼개 보는 차원이 바뀝니다. 다시 조회하지 않습니다.
  4. 축 이동 — 차원 칩을 행 축(최대 3단계) · 열 축(최대 2단계)으로 끌어다 놓거나 칩의 화살표 버튼으로 옮깁니다. 표시 항목 · 금액 단위 · 비교 기준도 같은 줄에서 바꿉니다.
  5. 칸 클릭 상세 — 숫자 칸을 누르면 그 금액을 만든 컨테이너 라인이 열리고, 칸의 값과 읽은 라인의 합이 같은지 표시됩니다. 비교를 예정으로 바꾼 뒤 행 이름을 누르면 요인 워터폴이 열립니다.
  6. 분석 기능 — AI 분석 · AI 에이전트 · 레이아웃 버튼은 화면 위쪽에, 변동 사유는 차이가 난 행의 "사유 쓰기" 에 있습니다.
  7. 내려받기 — 피벗과 원천 라인 목록은 CSV, 현재 범위의 표와 차트는 PPTX 보고서 로 내려받습니다.

무엇으로 만들었나

자리무엇왜 그렇게 두었나
화면 컨트롤OpenUI5 표준 컨트롤(sap_horizon 테마)과 직접 그린 SVG 차트외부 차트 라이브러리를 들이지 않아 사내망 · 보안 검토에서 걸리는 것이 없습니다.
큐브 재집계조회 때 읽은 큐브를 축에 따라 브라우저에서 다시 묶는 로직축을 바꿀 때마다 서버를 부르지 않아 응답이 즉시이고, 같은 큐브에서 나오므로 합계가 갈라지지 않습니다.
비용 계산 · 요인분해 · 판정서비스 쪽 로직 파일(체화 · 지체 · 보관 비용식, 순차 대체 요인분해, 감시 규칙, 해설)숫자는 서비스가 정하고 화면은 배치만 합니다. 검증용 서비스도 같은 로직 파일을 그대로 씁니다.
OData 서비스 구성화면은 OData V2 모델 하나만 바라보고 서비스 주소는 앱 설정의 선언을 따릅니다. 큐브 · 예정 · 원천 라인 · 차원 · 측정값 · 계산항목 · 사유 · 레이아웃 · 에이전트 데이터를 각각 읽고 쓰며, 요인분해 · AI 해설 · 에이전트 실행은 서비스 함수로 부릅니다.운영에서는 서비스 주소만 바꾸면 같은 화면이 SAP 서비스에 붙습니다. 화면 코드는 검증용 서버를 알지 못합니다.
테마sap_horizonS/4HANA 의 Fiori 화면과 같은 결의 외형을 씁니다.
SAP 표준 기능을 그대로 이어받은 부분 — 구매 오더 · 입고 · 송장 문서가 가진 공급사 · 구매 오더 번호 · 통화 · 일자 필드를 그대로 이어받습니다. 표준 실행은 SAP 표준 T-code 가 담당하고, 이 화면은 조회·검증 관점을 더해 확장합니다.

앱 정보

항목내용
솔루션수입 솔루션
업무 영역수입 물류비 분석 — 컨테이너 체화 · 지체 비용
관련 기준서 · 대상 영역대상 영역: 컨테이너 체화·지체 비용 (선사 · 터미널 부대비용)
SAP 표준 T-codeME23N · MIGO · MIRO · MIR4 · MB51 · FBL1N · FB03
Namespacezui5.impdemur
화면 성격다차원 분석 리포트 (조회 · 점검 도구)
데이터 연동OData V2 서비스 (검증용 샘플 데이터로 동작 확인)
테마sap_horizon

처음 열었을 때

조회 전에도 틀이 보이고, 조회하면 한 화면에 피벗과 차트가 함께 뜹니다. 아래 네 장은 처음 열었을 때의 흐름입니다.

조회 전 틀
조회 전 틀 — 조회를 누르기 전에도 조회조건 · 분석 축 · 임원 요약 · 피벗 틀이 먼저 보입니다.

조회조건은 회사코드(필수)와 시작·종료 기간, 선택 사항인 차원 값입니다. 조회 버튼은 조회조건 영역의 오른쪽 끝에 있고 입력칸에서 Enter 키로도 조회됩니다. 머리 영역은 접을 수 있습니다.

조회 직후 — 피벗과 차트
조회 직후 — 피벗과 차트 — 조회하면 선사 › 청구 통화 행 축 × 입항월 열 축의 피벗과 오른쪽 차트가 함께 나옵니다.

금액은 기본 백만원 단위이고, 표시 항목은 체화·지체 비용 합계입니다. 왼쪽 위 막대는 같은 값을 직접 그린 SVG 차트입니다. 칸 수 1,579는 차원 조합 수이며 원천 라인 3,880건이 여기로 묶였습니다.

분석 축 — 끌어다 놓은 뒤
분석 축 — 끌어다 놓은 뒤 — 입항지 칩을 행 축 맨 앞으로 끌어다 놓자 서버 호출 없이 행이 입항지 › 선사 › 청구 통화로 바뀌었습니다.

칩은 끌어다 놓거나 칩의 화살표 버튼으로 옮깁니다. 행 축은 최대 3단계, 열 축은 최대 2단계입니다. 축을 바꿔도 총합은 변하지 않습니다.

머리 영역을 접은 상태
머리 영역을 접은 상태 — 조회조건과 분석 축을 접으면 요약 한 줄만 남아 결과 영역이 넓어집니다.

접힌 줄에는 회사코드 · 기간과 현재 행·열 축이 남습니다. 펼치지 않고도 지금 무엇을 보고 있는지 알 수 있습니다.

경영 요약 — 역할이 바뀌면 같은 큐브가 다른 질문에 답한다

임원 요약은 역할 네 개(CFO · 구매 책임자 · 물류 책임자 · 자금 책임자)를 바꿀 때마다 앞세우는 지표와 쪼개 보는 차원이 함께 바뀝니다. 다시 조회하지 않습니다.

임원 요약 — CFO
임원 요약 — CFO — 역할이 CFO 이면 입항지 기준 합계가 먼저 나오고, 예정 대비 초과가 큰 입항지부터 줄을 세웁니다.

핵심 지표 네 개는 합계 · 선사 청구 합계 · 기타 추가비용 · 컨테이너(TEU)당 비용이며 각각 예정과 차이가 붙습니다. 이 샘플에서는 부산항이 예정보다 7.09억원 많아 맨 위에 있습니다.

임원 요약 — 구매 책임자
임원 요약 — 구매 책임자 — 구매 책임자는 공급사 기준으로 같은 숫자를 다시 쪼개 봅니다.

역할을 바꿔도 다시 조회하지 않습니다. 앞세우는 지표와 쪼개 보는 차원이 같은 큐브에서 바뀔 뿐입니다.

임원 요약 — 물류 책임자
임원 요약 — 물류 책임자 — 물류 책임자는 선사 기준 체화료를 먼저 봅니다.

표시 항목이 체화료로 바뀌고 지표도 체화료 · 지체료 · 보관료 · 유료 초과일 쪽으로 옮겨 갑니다.

임원 요약 — 자금 책임자
임원 요약 — 자금 책임자 — 자금 책임자는 청구 통화 기준으로 환율이 닿는 비용을 봅니다.

외화 청구는 환율이 곱해져 원화가 되므로 통화별로 쪼개 보는 것이 출발점입니다. 서로 다른 통화는 합산하지 않고 원화로 환산한 값을 씁니다.

축 전환과 범위 — 서버를 다시 부르지 않는다

차원 칩을 끌어다 놓으면 브라우저가 큐브를 다시 묶습니다. 값 다중 선택, 단계 보기, 차트까지 한 큐브에서 나오므로 합계가 어긋날 자리가 없습니다.

차원 값 다중 선택
차원 값 다중 선택 — 시간 외 차원마다 값을 여러 개 고를 수 있습니다.

차원 안에서는 or, 차원 사이에서는 and 입니다. 값마다 코드와 이름이 붙고 큐브에 있는 값만 올라옵니다. 선사 세 곳과 입항지 두 곳을 골랐습니다.

범위를 좁힌 결과
범위를 좁힌 결과 — 고른 값만 남아 피벗과 차트가 같은 범위로 줄었습니다.

조회조건 영역의 버튼에 "2개 차원 선택" 으로 요약이 남습니다. 범위를 좁혀도 서버를 다시 부르지 않고 큐브 안에서 걸러냅니다.

단계 보기
단계 보기 — 단계 보기를 켜면 앞 열 대비 증감만 보여 줍니다.

월별 추이에서 어느 달에 비용이 튀었는지 읽기 좋습니다. 켜고 끄는 것은 표시 방식일 뿐 큐브 값은 같습니다.

막대 차트 — 표시 항목 바꾸기
막대 차트 — 표시 항목 바꾸기 — 표시 항목을 체화료로 바꾸면 표와 막대 차트가 같은 값으로 함께 바뀝니다.

선사별 체화료(Demurrage)만 보면 라인베이 쉬핑이 가장 크고 합계 기준과는 순서가 다릅니다. 차트는 외부 라이브러리 없이 직접 그린 SVG 이고, 표와 차트 사이 손잡이로 너비를 나눌 수 있으며 그 비율은 브라우저에 남습니다.

칸에서 컨테이너 라인까지

리포트에서 가장 비싼 질문은 "이 숫자 맞아?" 입니다. 칸을 누르면 그 금액을 만든 컨테이너 라인이 열리고, 칸 금액과 라인 합이 같은지 그 자리에서 보입니다.

칸에서 컨테이너 라인으로
칸에서 컨테이너 라인으로 — 숫자 칸을 누르면 그 금액을 만든 컨테이너 라인이 열립니다.

행 경로와 열 조합이 그대로 조회 조건이 됩니다. 머리에 칸의 값 · 읽은 라인의 합 · 일치 여부가 나오고 기본 500행씩 읽습니다. 라인마다 입항일 · 반출일 · 반납일 · 일수 · 요율 · 환율 · 체화료 · 지체료 · 보관료가 보입니다.

차이 모드에서의 드릴스루
차이 모드에서의 드릴스루 — 차이를 보고 있어도 칸을 누르면 같은 원천 라인으로 내려갑니다.

이 칸의 값 89.3(백만원)은 읽은 라인 66건의 차이 합과 같습니다. 선사 · 청구 통화 · 입항월이 질의 조건으로 머리에 적힙니다.

검산과 입항월 요약
검산과 입항월 요약 — 검산 패널은 큐브 합계와 원천 라인 합계를 측정값마다 나란히 놓습니다.

일곱 측정값의 차이가 모두 0입니다. 아래 입항월별 요약은 라인 수와 선하증권 수, 체화료 · 지체료 · 보관료 · 합계를 보여 줍니다.

계산항목 — 전기되지 않는 단계

체화료 + 지체료처럼 전기되지 않지만 보고 싶은 단계는 계산항목으로 정의합니다. 식은 서비스가 들고 있고 화면은 고른 항목만 보여 줍니다.

계산항목 — 선사 청구 합계
계산항목 — 선사 청구 합계 — 체화료 + 지체료처럼 전기되지 않는 단계를 계산항목으로 골라 행으로 봅니다.

계산항목은 토큰 식으로 정의되어 서비스가 계산합니다. 선사가 청구하는 몫만 따로 보고 싶을 때 씁니다.

계산항목 — 컨테이너당 유료 초과일
계산항목 — 컨테이너당 유료 초과일 — 컨테이너(TEU)당 유료 초과일은 비용 구조를 일수로 읽게 해 줍니다.

무료기간을 넘긴 일수의 합을 물량으로 나눈 값입니다. 금액 대신 일수로 보면 요율이 달라도 어디서 오래 묶였는지 비교됩니다.

예정 대비 차이 — 같은 표가 점검 자료가 된다

비교 기준을 예정으로 바꾸면 같은 표가 점검 자료가 됩니다. 칸마다 차이와 증감률이 붙고, 차트는 워터폴로 바뀌어 총차이를 일곱 요인으로 가르며, 차이가 난 행에는 사유를 남깁니다.

예정 대비 차이 — 같은 표가 차이 표로
예정 대비 차이 — 같은 표가 차이 표로 — 비교를 예정으로 바꾸면 칸마다 실적 · 예정 · 차이 · 증감률이 붙습니다.

색은 비용이 늘었는지가 아니라 비용 부담에 준 영향 방향으로 칠하며, 금액과 비율 임계를 둘 다 넘을 때만 입힙니다. 임계는 화면에서 고칩니다.

요인 워터폴 — 예정에서 실적까지
요인 워터폴 — 예정에서 실적까지 — 행 이름을 누르면 그 범위의 총차이가 일곱 요인으로 나뉘는 워터폴이 나옵니다.

파란 막대는 예정과 실적, 붉은 막대는 비용을 늘린 요인, 초록 막대는 줄인 요인입니다. 맨 아래 검산 줄이 요인 합 − 총차이 = 0원임을 매번 보여 줍니다.

변동 사유 쓰기
변동 사유 쓰기 — 차이가 난 행의 "사유 쓰기" 를 누르면 사유 구분과 내용을 적는 창이 열립니다.

창에는 행 경로와 차이 금액 · 증감률이 함께 보입니다. 구분은 통관 서류 · 검사 대기 · 운송 차량 · 공장 일정 · 선적서류 지연 · 환율 · 기타입니다.

사유 저장 후
사유 저장 후 — 저장하면 해당 행에 "사유 있음" 이 표시됩니다.

사유의 키는 조회 범위와 행 경로입니다. 축을 바꾸거나 다시 펼쳐도 같은 행이면 따라오고 CSV · AI 분석 근거에 함께 실립니다.

AI 분석과 보고서

AI 분석은 지금 보고 있는 범위를 읽어 요약합니다. 숫자는 모델이 만들지 않고, 넘긴 근거를 화면에서 펼쳐 확인합니다.

AI 분석 — 요약과 점검 대상
AI 분석 — 요약과 점검 대상 — AI 분석은 지금 범위의 숫자를 읽어 요약과 점검 대상을 씁니다.

모델이 연결되지 않은 기본 상태에서는 규칙 기반 해설이 나옵니다. 금액과 비율은 서비스가 계산한 값이고 해설은 그 값을 문장으로 옮길 뿐입니다. 이미 사유가 적힌 행은 건너뜁니다.

AI 근거 표
AI 근거 표 — 해설에 쓴 숫자의 근거 표를 펼쳐 볼 수 있습니다.

축 · 값 · 라인 수 · 예정 · 실적 · 차이 · 주된 요인이 한 줄씩 나옵니다. 여기서 PPTX 보고서 버튼으로 현재 범위의 표와 차트를 담은 PowerPoint 를 내려받습니다.

AI 에이전트 — 사람이 열지 않아도 감시한다

감시 규칙은 임계값과 받을 역할이 붙어 있습니다. 걸리면 그 역할의 눈으로 다시 쓴 보고가 대기함에 올라갑니다.

AI 에이전트 — 감시 규칙
AI 에이전트 — 감시 규칙 — 규칙마다 임계값 · 받을 역할 · 사용 여부가 있고 화면에서 고쳐 저장합니다.

이 샘플의 규칙은 다섯 개입니다. 선사 유료 초과일 · 환율 영향 · 터미널 비용 초과 · 선사 무료기간 조건 · 공급사 서류 관련 지연 비용입니다.

에이전트 실행
에이전트 실행 — "지금 실행" 을 누르면 규칙을 돌려 걸린 건을 대기함에 올립니다.

이 실행에서는 다섯 규칙이 모두 걸려 대기함에 5건이 올라갔습니다. 열어 둔 동안 한 시간마다 도는 화면 타이머도 있고 기본은 꺼짐입니다.

대기함 — 받을 역할의 눈으로
대기함 — 받을 역할의 눈으로 — 대기함의 보고는 규칙에 지정된 역할 관점으로 다시 쓰여 있습니다.

제목과 본문에 규칙명 · 걸린 건수 · 대상 · 수치가 들어 있습니다. 심각도에 따라 표시가 다릅니다.

활동 기록 — 하루 한 번 제한
활동 기록 — 하루 한 번 제한 — 같은 날 두 번째 실행은 한도에 걸려 새 보고 없이 기록만 남습니다.

기록에는 시각 · 호출 주체(사람 · 화면 타이머 · 배치) · 상태 · 규칙 수 · 걸린 수가 남습니다. 하루 한 번 제한은 화면이 아니라 서버가 판정합니다.

레이아웃 저장과 복원

자주 쓰는 구성은 이름을 붙여 저장합니다. 기본으로 지정하면 열 때 그 배치로 시작합니다.

레이아웃 저장 · 불러오기
레이아웃 저장 · 불러오기 — 축 · 조회조건 · 측정값 · 표시 행 수 · 접힘 상태를 이름 붙여 저장합니다.

기본 레이아웃과 "열 때 자동 조회" 를 지정할 수 있습니다. 이름 바꾸기와 삭제는 목록의 버튼으로 합니다.

저장하려는 배치
저장하려는 배치 — 입항지 › 선사 › 청구 통화로 짜 둔 배치를 저장합니다.

저장한 뒤 이 배치를 기본으로 지정해 두면 다음에 열 때 그 배치로 시작합니다.

새로 고친 뒤 복원
새로 고친 뒤 복원 — 브라우저를 새로 고쳐도 저장한 레이아웃이 그대로 복원됩니다.

자동 조회를 함께 지정했다면 열자마자 조회된 상태로 시작합니다. 레이아웃은 서비스에 저장되어 다른 브라우저에서도 같습니다.

좁은 화면과 한계

창이 좁아도 차트를 숨기지 않고 표 아래로 내립니다. 조합이 상한을 넘으면 범위를 좁히라고 안내합니다.

좁은 화면 — 390px
좁은 화면 — 390px — 창이 좁으면 차트를 표 아래로 내려 쌓아 휴대폰에서도 같은 리포트를 봅니다.

가로 스크롤 없이 한 줄 폭에 맞춥니다. 조회 버튼과 머리 영역도 그대로 동작합니다.

좁은 화면의 피벗
좁은 화면의 피벗 — 피벗은 한 열씩 보이고 아래에 차트가 이어집니다.

칸을 누르면 같은 드릴스루가 전체 화면 대화상자로 열립니다.

범위 상한 안내
범위 상한 안내 — 행 · 열 조합이 상한을 넘으면 반쯤 그린 표 대신 범위를 좁히라고 안내합니다.

행 축은 3단계까지입니다. 열 조합은 36개까지이고 넘으면 더 추가하지 못하게 막습니다.

화면 뒤에서 일어나는 일

조회 버튼은 한 번에 큐브(차원 조합별 측정값 7종)와 예정 큐브, 차원 · 측정값 · 계산항목 정의, 입항월 요약, 검산 결과를 읽어 옵니다. 그 뒤의 모든 조작 — 축 이동, 값 선택, 단계 보기, 비교 전환, 역할 전환 — 은 읽어 둔 큐브를 브라우저가 다시 묶는 일이라 서버를 부르지 않습니다. 서버를 다시 부르는 때는 칸을 눌러 원천 라인을 읽을 때, 요인분해와 AI 해설을 요청할 때, 사유 · 레이아웃을 저장할 때, 에이전트를 실행할 때뿐입니다.

비용 계산 — 컨테이너 라인에서 한 칸까지

비용은 컨테이너 라인마다 아래 식으로 계산하고, 라인의 합이 큐브 칸이 됩니다. 일 요율과 무료기간은 선사와의 계약 조건이므로 회사마다 다르며, 이 샘플은 가정값을 썼습니다.

항목산식설명
체화료TEU × max(0, 반출까지 일수 − 체화 무료기간) × 체화 일 요율 × 환율입항 뒤 컨테이너가 터미널 안에 머문 기간 중 무료기간을 넘긴 날
지체료TEU × max(0, 반납까지 일수 − 지체 무료기간) × 지체 일 요율 × 환율반출한 컨테이너를 빈 채 돌려주기까지 무료기간을 넘긴 날
보관료TEU × max(0, 반출까지 일수 − 보관 무료기간) × 보관 일 요율터미널 보관(CY)에 대한 원화 청구분
기타 추가비용라인에 직접 붙은 금액검사 · 재작업 · 추가 운송 등 일수로 계산되지 않는 비용
합계체화료 + 지체료 + 보관료 + 기타 추가비용표시 항목의 기본값

예정 대비 차이 판정

판정 조건결과 상태사용자 조치
차이의 절대 금액과 비율이 모두 임계 이상이고 비용이 늘어난 방향붉게 표시 — 점검 필요요인 워터폴로 원인 요인을 확인하고 "사유 쓰기"
금액과 비율 중 하나만 임계 이상색 없음 (정보)필요하면 임계를 조정
임계 이상이면서 비용이 줄어든 방향초록 표시 — 개선줄어든 이유가 반복 가능한 것인지 확인
예정 라인이 없는 컨테이너 라인"미계획" 요인으로 분리발주 · 입항 계획이 빠졌는지 확인
칸의 값과 읽은 라인의 합이 다름드릴스루 머리에 불일치 표시검산 패널에서 측정값별 차이를 확인
같은 날 에이전트를 두 번째로 실행"한도" 상태로 기록만 남김다음 날 실행하거나 규칙을 조정

요인분해 — 합이 총차이와 같다

컨테이너 라인마다 예정 값을 실적 값으로 한 요인씩 바꿔 가며 금액이 얼마나 움직이는지 잽니다. 순서는 물량 → 무료기간 → 지연일수 → 일 요율 → 환율 → 기타비용이고, 예정이 없는 라인은 통째로 미계획 요인에 넣습니다. 한 번에 한 요인만 바꾸므로 교차항이 따로 남지 않고, 일곱 요인의 합이 총차이와 1원도 어긋나지 않습니다. 화면은 워터폴 맨 아래에 "요인 합 − 총차이 = 0원" 을 매번 보여 줍니다.

요인무엇이 바뀐 몫인가
물량 (QTY)컨테이너 물량(TEU)이 예정과 달랐던 몫
무료기간 (FREE)선사 계약의 무료기간 조건이 예정과 달랐던 몫
지연일수 (DAYS)반출까지 · 반납까지 일수가 예정보다 길었던 몫
일 요율 (RATE)체화 · 지체 · 보관 일 요율이 달랐던 몫
환율 (FX)청구 통화의 환율이 예정 환율과 달랐던 몫
기타비용 (OTH)일수로 계산되지 않는 추가비용 차이
미계획 (UNPLAN)예정 라인이 없던 컨테이너의 전체 비용

조회조건

필드필수기본값$filter 로 가는 모습
회사코드필수1000Bukrs eq '1000'
시작 기간 (입항월)필수202604Period ge '202604'
종료 기간 (입항월)필수202609Period le '202609'
차원 값 (선사 · 포워더 · 터미널 · 컨테이너 유형 · 입항지 · 청구 통화 · 인코텀즈 · 지연 사유 · 공급사)선택전체차원마다 or, 차원 사이는 and
표시 항목 / 금액 단위 / 비교선택합계 / 백만원 / 실적만화면 설정 — 서버를 부르지 않음
금액 임계 / 비율 임계선택100만원 / 10%화면 설정 — 색 판정에만 쓰임

결과 컬럼

컬럼의미산출
행 / 열선택한 차원 경로와 입항월 등 열 조합큐브 재집계
실적선택한 표시 항목의 값큐브 칸의 합
예정같은 칸의 비교 기준 값예정 큐브 칸의 합
차이 / 차이율실적 − 예정, 차이 ÷ 예정화면에서 계산 (요인은 서비스)
사유차이가 난 행에 남긴 사유 구분과 내용사유 저장소의 행 경로 키
라인 · B/L칸을 만든 컨테이너 라인 수와 선하증권 수드릴스루 머리
유료 초과 TEU일무료기간을 넘긴 일수 × TEU 의 합측정값 7종 중 하나

좁은 화면에서 달라지는 것

창 폭이 좁으면 표와 차트가 위아래로 쌓이고 피벗은 한 열씩 보입니다. 칸을 누르면 드릴스루가 전체 화면 대화상자로 열립니다. 가로 스크롤이 생기지 않으며, 행 · 열 조합이 상한(열 36개 · 행 노드 1,500개)을 넘으면 반쯤 그린 표 대신 범위를 좁히라고 안내합니다.

파일 구성

Component.js · manifest.json · index.html
controller/   Main.controller.js · BaseController.js
view/         Main.view.xml · fragment/ (Agent · Ai · Drill · Layout · Reason)
model/        cube.js (큐브 재집계) · chart.js (SVG 차트) · layout.js · formatter.js · pptx.js (보고서 생성) · ErrorHandler.js
i18n/         한국어 텍스트
odata/        서비스 정의 · 로직 파일 · 샘플 데이터(json)
media/        소개 영상 · 포스터 · 재생 지점

SAP 표준 기능 확장 포인트 — 표준 T-code 와 어떻게 연계되는지

표준 실행은 SAP 표준 T-code 가 담당하고, 이 화면은 조회·검증 관점을 더해 확장합니다. 그래서 기존 표준 화면과 리포트를 없앨 필요가 없습니다. 표준 화면은 계속 문서 단위 확인과 처리에 쓰고, 이 화면은 그 위에서 여러 축으로 묶어 비교하는 일을 맡습니다.

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

하고 싶은 일표준 T-code표준 화면이 하는 일이 앱이 더하는 관점
구매 오더에 건 부대비용 조건 확인ME23N발주 단위로 조건을 보여 줍니다.선사 · 터미널 · 입항지 · 월 같은 여러 축으로 묶어 같은 조건의 예정 금액을 비교합니다.
컨테이너가 들어온 입고 문서 확인MIGO · MB51자재문서 단위로 입고일과 수량을 확인합니다.입고일과 반출 · 반납 일자를 한 라인에 놓고 무료기간 안팎을 가릅니다.
선사 · 터미널 청구서 검증MIRO · MIR4송장 단위로 입력하고 표시합니다.청구서 번호가 붙은 라인을 모아 청구 통화 · 선사 단위로 합산해 예정과 맞춥니다.
선사별 미지급 · 지급 확인FBL1N공급사 개별 항목을 보여 줍니다.분석에서 본 선사 합계를 개별 항목으로 이어서 확인합니다.
회계 전표 확인FB03전표 한 건을 보여 줍니다.분석 결과의 청구서 번호에서 전표로 내려가 원천을 확인합니다.
선사 · 입항지 · 월별 다차원 비교(표준 화면 조합 + 엑셀)화면을 오가며 사람이 합산합니다.같은 큐브에서 축을 끌어다 놓으며 봅니다.
예정 대비 차이의 요인 가르기(표준 화면 조합 + 엑셀)보통 엑셀 별도 작업입니다.일곱 요인으로 나누고 합이 총차이와 같은지 검산합니다.

T-code 별 연계 지점

T-code이름연계
ME23N구매 오더 표시구매 오더 번호와 공급사(선사 · 포워더)를 이어받습니다. 예정 비용을 오더의 조건으로 두는 회사는 예정 금액의 원천이 되며, 분석 결과의 오더 번호에서 ME23N 으로 가 조건을 다시 확인합니다. 표준에 남길 일: 발주 변경 · 조건 수정.
MIGO입고 처리입고 문서의 입고일 · 수량을 이어받아 컨테이너 반출일과 선후를 맞춰 봅니다. 분석에서 입고 문서로 가는 길은 MB51 이 담당합니다. 표준에 남길 일: 입고 전기 · 취소.
MIRO송장 입력선사 청구서 번호가 있는 송장을 이어받습니다. 체화 · 지체 청구를 별도 오더로 받는지 계획외 부대비용으로 받는지는 회사 방식에 달라 확인 필요입니다. 표준에 남길 일: 송장 전기 · 지급 보류.
MIR4송장 헤더 표시분석의 청구서 번호에서 송장 헤더를 열어 청구액과 이 화면의 합계를 맞춰 봅니다.
MB51자재문서 목록입고 문서를 기간 · 자재 단위로 조회해 이 화면의 입항월 합계와 라인 수를 대사하는 지점입니다.
FBL1N공급사 개별 항목선사 계정의 미결 · 반제 항목을 보여 주어 이 화면의 선사 합계를 지급 쪽에서 확인합니다. 표준에 남길 일: 지급 실행 · 반제.
FB03전표 표시송장이 만든 회계 전표를 열어 계정 · 금액을 확인합니다. 법정 · 감사 · 세무 신고 대응은 계속 표준 전표 기준으로 합니다(세무 신고는 회사와 세무 대리인 · 관세사).

운영으로 옮긴다고 기존 리포트를 없앨 필요는 없습니다. 한 분기쯤은 이 화면의 합계와 기존 리포트의 합계를 나란히 두고 맞추며, 어긋나는 라인은 위 T-code 로 원천을 확인합니다. 이 화면은 법정 · 감사 · 세무 신고용 숫자를 만들지 않습니다.

S/4HANA 분석 스택과의 자리

S/4HANA 에는 CDS 뷰 기반의 분석 쿼리와 Fiori 분석 앱, Analysis for Office 같은 도구가 있습니다. 이 앱은 그 경쟁 관계가 아니라 같은 계열의 한 층입니다. 아래 CDS 구성처럼 큐브 뷰와 분석 쿼리를 두면 같은 데이터를 Analysis for Office 에서도 열 수 있고, 이 화면은 그중 축 끌어다 놓기 · 드릴스루 · 요인분해 · 사유 기록 · 에이전트를 한 화면에 모은 형태입니다. 어느 표준 Fiori 앱이 체화·지체 비용을 직접 다루는지는 확인하지 못해 이름을 적지 않았으며, 도입 시 확인할 사항입니다.

확장 포인트 — 운영에서 실제로 손대는 자리

자리무엇을 손대나비고
선사별 무료기간 · 요율선사 · 컨테이너 유형 · 유효기간별 체화 · 지체 · 보관 조건 표회사마다 계약이 달라 가정값을 쓰지 않고 실제 조건으로 채웁니다.
컨테이너 이벤트 일자입항일 · 반출일 · 반납일을 담는 원천(물류 시스템 연동 또는 사용자 정의 필드)표준 MM 에는 없는 값이라 가장 먼저 정해야 합니다. 확인 필요.
부대비용 조건 유형청구서 · 오더에서 체화 · 지체 · 보관 · 기타 금액을 구분하는 조건 유형 매핑매핑이 바뀌면 큐브의 측정값 구분이 바뀝니다.
확장 필드터미널 · 입항지 · 지연 사유 같은 차원을 늘리려면 원천 문서의 확장 필드나 매핑 표 사용차원은 뷰에 선언된 만큼만 화면에 올라옵니다.
환율 유형청구 통화를 원화로 바꿀 때 쓰는 환율 유형과 기준일입항일 · 반출일 · 청구일 중 무엇으로 환산할지 정해야 합니다.
권한회사코드 · 구매 조직 · 플랜트 같은 표준 권한 객체를 집계 단계에 적용드릴스루에만 걸면 합계로 남의 숫자가 드러납니다.
감시 규칙임계값 · 받을 역할 · 사용 여부화면에서 고치고 서비스에 저장됩니다.

분석 지표 정의표

지표산식 · 판정 기준대응 기능원천 데이터비고
체화료TEU × max(0, 반출까지 일수 − 체화 무료기간) × 체화 일 요율 × 환율피벗 · 드릴스루컨테이너 이벤트 일자 · 선사 조건 · 환율일 요율은 계약 조건
지체료TEU × max(0, 반납까지 일수 − 지체 무료기간) × 지체 일 요율 × 환율피벗 · 드릴스루컨테이너 이벤트 일자 · 선사 조건 · 환율
보관료TEU × max(0, 반출까지 일수 − 보관 무료기간) × 보관 일 요율피벗 · 드릴스루터미널 보관 조건원화 청구
유료 초과 TEU일TEU × (체화 · 지체 · 보관 중 무료기간을 넘긴 일수의 합)계산항목 · 에이전트 R01계산 결과선사 간 비교용
선사 청구 합계체화료 + 지체료계산항목계산 결과선사 · 대리점 청구분
예정 대비 차이실적 − 예정, 임계는 금액과 비율을 모두 넘을 때차이 모드 · 워터폴예정 큐브임계는 화면에서 조정
요인 7종순차 대체(물량 → 무료기간 → 지연일수 → 일 요율 → 환율 → 기타 → 미계획)요인 워터폴라인별 실적 · 예정합 = 총차이

CDS 구성

아래는 같은 구조를 S/4HANA 에 만들 때의 스케치입니다. 이 화면은 검증용 샘플 데이터로 동작하며, 컨테이너 이벤트 일자의 원천 테이블 이름 · 표준 뷰 이름은 회사 환경에서 확인해야 해서 코드에 "확인 필요" 로 표시했습니다. 이름 규칙은 뷰 ZI_(기본) · ZC_(소비), 테이블은 zimp_ 접두를 씁니다.

뷰 레이어 구성

레이어뷰 · 객체하는 일왜 나누나
기준zimp_dem_terms선사 · 컨테이너 유형별 무료기간과 일 요율계약 갱신을 코드 변경 없이 반영
라인(기본)ZI_ImpDemurLine이벤트 일자 · 오더 · 조건을 잇고 라인별 일수와 비용 계산드릴스루의 원천이며 비용식이 한 곳에만 있음
큐브ZI_ImpDemurCube차원 조합별 측정값 합산집계 부하를 라인 조회와 분리
예정ZI_ImpDemurPlan같은 모양의 예정 값칸마다 짝을 맞추고 요인분해를 가능하게 함
쿼리ZC_ImpDemurQuery필터 · 행 · 열 후보 선언화면 범위와 데이터 범위를 분리
권한ZI_ImpDemurLine (DCL)회사코드 권한 적용집계 단계에서 걸어 합계 추정을 막음
서비스ZC_ImpDemurSrvOData 로 노출화면 쪽 변경을 서비스 주소 교체로 한정

① 조건 테이블 — 무료기간과 일 요율

선사 · 컨테이너 유형 · 유효기간별 계약 조건을 코드가 아니라 표로 둡니다. 계약이 갱신될 때마다 뷰를 고치지 않아도 되고, 현업이 유지할 수 있는 유일한 자리입니다.

" ─────────────────────────────────────────────────────────────
" zimp_dem_terms : 선사 · 컨테이너 유형별 무료기간과 일 요율
" 역할   : 체화 · 지체 · 보관 비용식에 들어가는 계약 조건을 코드가 아니라 표로 둔다.
" 나눈 이유 : 요율과 무료기간은 계약이 바뀔 때마다 달라진다. 뷰에 숫자를 박으면
"            계약 갱신 때마다 전송(TR)이 나가야 한다. 표로 두면 현업이 유지한다.
" ─────────────────────────────────────────────────────────────
@EndUserText.label : '수입 체화·지체 조건'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #C
@AbapCatalog.dataMaintenance : #ALLOWED
define table zimp_dem_terms {
  key mandt      : mandt not null;
  key carrier    : lifnr not null;              " 선사 (공급사 마스터)
  key cntr_type  : abap.char(4) not null;       " 20GP / 40GP / 40HC
  key valid_from : abap.dats not null;
  valid_to       : abap.dats;
  free_dem       : abap.int2;                   " 체화 무료기간(일)
  free_det       : abap.int2;                   " 지체 무료기간(일)
  free_stor      : abap.int2;                   " 보관 무료기간(일)
  currency       : waers;                       " 청구 통화
  @Semantics.amount.currencyCode : 'zimp_dem_terms.currency'
  dem_rate       : abap.curr(11,2);             " 체화 일 요율(TEU당)
  @Semantics.amount.currencyCode : 'zimp_dem_terms.currency'
  det_rate       : abap.curr(11,2);             " 지체 일 요율(TEU당)
  @Semantics.amount.currencyCode : 'zimp_dem_terms.currency'
  stor_rate      : abap.curr(11,2);             " 보관 일 요율(TEU당)
}

② 컨테이너 라인 뷰 — 일수와 조건을 한 줄에

이 뷰에서 라인의 일수(반출까지 · 반납까지)와 적용 조건이 결정됩니다. 비용식을 큐브가 아니라 라인 가까이에 두는 이유는 드릴스루의 칸 값과 라인 합이 같아야 하기 때문입니다.

" ─────────────────────────────────────────────────────────────
" ZI_ImpDemurLine : 컨테이너 라인 기본 뷰 (실적)
" 역할   : 구매 오더 · 송장 · 컨테이너 이벤트 일자를 한 줄(컨테이너 라인)로 잇고
"          일수와 비용을 라인 단위로 계산한다. 큐브는 이 줄을 합치기만 한다.
" 나눈 이유 : 비용식을 큐브가 아니라 라인에서 계산해야 드릴스루로 내려갔을 때
"            칸의 값과 라인의 합이 같다. 식이 한 곳에만 있어 어긋날 자리가 없다.
" ─────────────────────────────────────────────────────────────
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: '수입 컨테이너 라인 - 체화·지체 비용'
@ObjectModel.usageType: { serviceQuality: #C, sizeCategory: #XL, dataClass: #TRANSACTIONAL }
define view entity ZI_ImpDemurLine
  as select from zimp_cntr_evt as evt                 " 컨테이너 이벤트(입항·반출·반납 일자) - 확인 필요
    inner join   ekko          as po   on po.ebeln = evt.ebeln
    left outer join zimp_dem_terms as trm
         on  trm.carrier   = evt.carrier
         and trm.cntr_type = evt.cntr_type
         and trm.valid_from <= evt.arr_date
         and ( trm.valid_to  >= evt.arr_date or trm.valid_to = '00000000' )
  association [0..1] to I_Supplier as _Carrier on _Carrier.Supplier = $projection.Carrier
{
  key evt.bukrs                                   as CompanyCode,
  key evt.blno                                    as BillOfLading,
  key evt.itemno                                  as ItemNo,
      concat( substring( evt.arr_date, 1, 6 ), '' ) as ArrivalMonth,   " 입항월 YYYYMM
      evt.carrier                                 as Carrier,
      evt.port                                    as Port,
      evt.terminal                                as Terminal,
      evt.cntr_type                               as ContainerType,
      po.ebeln                                    as PurchaseOrder,
      evt.teu                                     as Teu,
      dats_days_between( evt.arr_date, evt.out_date ) as ClearDays,   " 반출까지
      dats_days_between( evt.out_date, evt.ret_date ) as HoldDays,    " 반납까지
      trm.free_dem                                as FreeDem,
      trm.free_det                                as FreeDet,
      trm.free_stor                               as FreeStor,
      trm.currency                                as BillCurrency,
      @Semantics.amount.currencyCode: 'BillCurrency'
      trm.dem_rate                                as DemRate,
      @Semantics.amount.currencyCode: 'BillCurrency'
      trm.det_rate                                as DetRate,
      _Carrier
}

③ 분석 큐브 — 차원과 측정값

라인 비용을 입항월 · 선사 · 터미널 · 입항지 · 컨테이너 유형 · 청구 통화별로 합칩니다. 통화 환산은 환율 유형과 기준일이 정해지는 쿼리 단계로 미룹니다.

" ─────────────────────────────────────────────────────────────
" ZI_ImpDemurCube : 분석 큐브 (차원 + 측정값)
" 역할   : 라인 비용을 차원 조합(입항월 · 선사 · 터미널 ...)별로 합친다.
"          화면의 CubeSet 한 행이 이 뷰의 한 행(측정값 한 가지)에 해당한다.
" 나눈 이유 : 라인 뷰는 드릴스루 전용, 큐브는 집계 전용으로 분리하면
"            집계가 느려져도 라인 조회가 영향을 받지 않는다.
" ─────────────────────────────────────────────────────────────
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #CHECK
@Analytics.dataCategory: #CUBE
@EndUserText.label: '수입 체화·지체 비용 큐브'
define view entity ZI_ImpDemurCube
  as select from ZI_ImpDemurLine as l
{
  key l.CompanyCode,
  key l.ArrivalMonth,
  key l.Carrier,
  key l.Terminal,
  key l.Port,
  key l.ContainerType,
  key l.BillCurrency,

  @Semantics.amount.currencyCode: 'ReportingCurrency'
  @DefaultAggregation: #SUM
  cast( sum( cast( l.Teu as abap.dec(15,3) )
       * cast( case when l.ClearDays > l.FreeDem then l.ClearDays - l.FreeDem else 0 end as abap.dec(5,0) )
       * l.DemRate )                                  as abap.curr(15,0) ) as DemurrageAmount,   " 환율 환산은 쿼리 단계에서
  @Semantics.amount.currencyCode: 'ReportingCurrency'
  @DefaultAggregation: #SUM
  cast( sum( cast( l.Teu as abap.dec(15,3) )
       * cast( case when l.HoldDays > l.FreeDet then l.HoldDays - l.FreeDet else 0 end as abap.dec(5,0) )
       * l.DetRate )                                  as abap.curr(15,0) ) as DetentionAmount,
  @DefaultAggregation: #SUM
  sum( l.Teu )                                        as Teu,
  cast( 'KRW' as abap.cuky )                          as ReportingCurrency
}
group by l.CompanyCode, l.ArrivalMonth, l.Carrier, l.Terminal, l.Port, l.ContainerType, l.BillCurrency

④ 예정 뷰 — 실적과 같은 모양의 비교 기준

예정은 실적과 같은 키 · 같은 비용식을 써야 칸마다 짝이 맞습니다. 예정이 없는 라인은 요인분해에서 "미계획" 으로 분리됩니다.

" ─────────────────────────────────────────────────────────────
" ZI_ImpDemurPlan : 예정 뷰 (비교 기준)
" 역할   : 같은 차원 · 같은 비용식으로 예정 일수와 예정 요율을 계산한다.
" 나눈 이유 : 예정이 실적과 같은 모양이어야 칸마다 짝이 맞고, 요인분해가
"            "예정 값을 실적 값으로 하나씩 바꾸는" 방식으로 돌 수 있다.
"            예정이 없는 컨테이너는 짝이 없어 "미계획" 요인으로 분리된다.
" ─────────────────────────────────────────────────────────────
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #CHECK
@Analytics.dataCategory: #FACT
@EndUserText.label: '수입 체화·지체 예정'
define view entity ZI_ImpDemurPlan
  as select from zimp_cntr_plan as p                  " 입항 계획·예정 일수 (확인 필요)
{
  key p.bukrs        as CompanyCode,
  key p.blno         as BillOfLading,
  key p.itemno       as ItemNo,
      p.plan_clear_days   as PlanClearDays,
      p.plan_hold_days    as PlanHoldDays,
      p.plan_free_dem     as PlanFreeDem,
      p.plan_free_det     as PlanFreeDet,
      p.plan_teu          as PlanTeu,
      p.plan_currency     as PlanCurrency,
      @Semantics.amount.currencyCode: 'PlanCurrency'
      p.plan_dem_rate     as PlanDemRate,
      @Semantics.amount.currencyCode: 'PlanCurrency'
      p.plan_det_rate     as PlanDetRate
}

⑤ 분석 쿼리 — 화면에 보이는 범위

어떤 차원이 필수 필터이고 어떤 차원이 행 · 열 후보인지 정합니다. 차원을 늘릴 때 손대는 곳입니다.

" ─────────────────────────────────────────────────────────────
" ZC_ImpDemurQuery : 분석 쿼리 (화면과 Analysis for Office 가 읽는 뷰)
" 역할   : 어떤 차원이 필터로 올라오고 어떤 차원이 행 · 열 후보인지 선언한다.
" 나눈 이유 : 큐브는 가능한 것의 전부이고, 쿼리는 사용자에게 보이는 것의 범위다.
"            차원을 늘리는 일은 이 뷰의 주석을 고치는 일이 된다.
" ─────────────────────────────────────────────────────────────
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: '수입 체화·지체 비용 분석'
@Analytics.query: true
@Metadata.allowExtensions: true
define view entity ZC_ImpDemurQuery
  as select from ZI_ImpDemurCube
{
  @Consumption.filter: { selectionType: #SINGLE, mandatory: true }
  @AnalyticsDetails.query.axis: #FREE
  key CompanyCode,
  @Consumption.filter: { selectionType: #INTERVAL, mandatory: true }
  @AnalyticsDetails.query.axis: #COLUMNS
  key ArrivalMonth,
  @Consumption.filter.selectionType: #MULTIPLE
  @AnalyticsDetails.query.axis: #ROWS
  key Carrier,
  @AnalyticsDetails.query.axis: #FREE
  key Port,
  @AnalyticsDetails.query.axis: #FREE
  key Terminal,
  @AnalyticsDetails.query.axis: #FREE
  key ContainerType,
  @AnalyticsDetails.query.axis: #FREE
  key BillCurrency,

  @AnalyticsDetails.query.decimals: 0
  DemurrageAmount,
  @AnalyticsDetails.query.decimals: 0
  DetentionAmount,
  Teu
}

⑥ 접근 제어 — 집계 단계에 건다

권한은 라인 뷰에 걸어야 큐브 · 쿼리가 모두 같은 기준을 따릅니다. 권한 객체는 회사의 권한 설계에 맞게 바꿉니다.

" ─────────────────────────────────────────────────────────────
" ZI_ImpDemurLine : 접근 제어 (DCL)
" 역할   : 회사코드 권한이 없는 사용자는 해당 회사의 라인을 읽지 못한다.
" 나눈 이유 : 집계 단계에 권한을 걸어야 한다. 드릴스루에만 걸면 합계와 라인 합의
"            차이로 남의 숫자를 추정할 수 있다. 큐브 · 쿼리는 이 뷰를 읽으므로 같이 걸린다.
" ─────────────────────────────────────────────────────────────
@EndUserText.label: '수입 체화·지체 라인 접근 제어'
@MappingRole: true
define role ZI_ImpDemurLine {
  grant select on ZI_ImpDemurLine
    where ( CompanyCode ) = aspect pfcg_auth( F_BKPF_BUK, BUKRS, ACTVT = '03' );
}

⑦ 서비스 정의 — 밖으로 내보내는 것

노출할 뷰만 적습니다. 바인딩을 게시한 뒤 화면의 서비스 주소만 바꾸면 같은 화면이 붙습니다.

" ─────────────────────────────────────────────────────────────
" ZC_ImpDemurSrv : 서비스 정의
" 역할   : 분석 쿼리를 OData 서비스로 내보낸다. 서비스 바인딩(OData V2 - UI)을 만들고
"          게시하면 /IWFND/MAINT_SERVICE 에서 활성화를 확인할 수 있다.
" 나눈 이유 : 서비스 정의에 노출할 뷰만 적어 두면 나머지는 밖으로 나가지 않는다.
"            화면 쪽은 manifest 의 서비스 주소만 이 서비스로 바꾸면 된다.
" ─────────────────────────────────────────────────────────────
@EndUserText.label: '수입 체화·지체 비용 서비스'
define service ZC_ImpDemurSrv {
  expose ZC_ImpDemurQuery  as CubeSet;
  expose ZI_ImpDemurLine   as ItemSet;
  expose ZI_ImpDemurPlan   as PlanSet;
}

운영 시점에 해야 할 일

개발보다 정하는 일이 많습니다. 아래는 코드가 아니라 합의입니다.

해야 할 일무엇을 정하나정하지 않으면누가
컨테이너 이벤트 원천입항 · 반출 · 반납 일자를 어느 시스템에서 어떤 키로 받는지일수를 계산할 수 없어 비용이 0 으로 나옵니다.물류 · IT
선사 계약 조건 입력선사 · 컨테이너 유형별 무료기간 · 일 요율 · 유효기간샘플 가정값으로 계산되어 청구서와 어긋납니다.수입 · 구매
부대비용 조건 유형청구서의 체화 · 지체 · 보관 · 기타를 어느 조건 유형으로 구분하는지측정값 구분이 안 되어 합계만 나옵니다.회계 · 구매
환율 유형과 기준일입항일 · 반출일 · 청구일 중 무엇으로 환산하는지환율 요인이 청구서 금액과 맞지 않습니다.자금 · 회계
예정(비교 기준) 확정예정 일수 · 요율을 어느 계획 자료에서 가져오는지"예정이 왜 이 숫자냐" 가 반복되고 미계획이 크게 나옵니다.수입 · 기획
차원 범위화면에 올릴 차원과 값 코드 체계나중에 늘리려면 뷰를 고쳐 다시 전송해야 합니다.현업 · IT
권한 설계회사코드 · 구매 조직 등 권한 기준전사 합계와 자기 몫의 차이로 남의 숫자가 추정됩니다.보안 · 권한
성능 기준조회 범위 상한, 인덱스, 응답 시간 목표한 번에 너무 넓은 기간을 읽어 응답이 느려집니다.Basis · IT
대사 체계표준 T-code 와 합계를 맞추는 항목 · 주기화면 숫자와 표준 숫자가 어긋날 때 원인을 못 찾습니다.회계 · 수입
전송(TR) 순서테이블 → 라인 뷰 → 큐브 · 예정 → 쿼리 → 권한 → 서비스의존 순서가 어긋나 활성화가 실패합니다.IT
서비스 활성화와 주소 교체서비스 게시, 활성화 확인, 앱 설정의 서비스 주소 교체화면이 검증용 데이터를 계속 읽습니다.IT
에이전트 배치감시 규칙을 하루 한 번 돌릴 배치 등록과 알림 대상화면을 열 때만 점검이 돕니다.IT · 수입

숫자를 믿을 수 있는가 — 검증 결과

검증용 샘플 데이터(컨테이너 라인 3,880건)를 전수로 돌린 결과입니다. 앞의 "사례로 보는 효과" 의 숫자가 모두 이 검증을 통과한 값입니다.

대사식검사 건수차이 건수
라인 합계 = 체화료 + 지체료 + 보관료 + 기타 (실적 · 예정)7,7600
체화료 · 지체료 · 보관료를 일수 · 요율 · 환율로 다시 계산3,8800
큐브 합계 = 원천 라인 합계 (측정값 7종)70
요인 7종의 합 = 총차이 (라인별)3,8800
드릴스루 칸 값 = 읽은 라인 합 (대표 4칸)40
서비스 계약 · 화면 동작 자동 점검390

예정이 없는 컨테이너 라인 250건(308,082,115원)은 오류가 아니라 의도적 예외입니다. 요인분해에서 "미계획" 으로 분리했으며 위 차이 건수와 별개입니다.

운영 데이터로 갈 때

운영에서는 컨테이너 라인이 월 수만 건에서 수십만 건이 될 수 있습니다. 집계는 화면이 아니라 큐브 뷰(데이터베이스)에서 하고, 조회 기간과 회사코드를 필수 파라미터로 둡니다. 큐브는 입항월 · 선사 · 터미널 단위로 미리 합쳐 두고, 원천 라인은 칸을 눌렀을 때만 기본 500행씩 읽습니다. 응답 시간 목표는 조회 3초, 드릴스루 2초 안팎을 출발점으로 두고 실제 규모에서 다시 정합니다. 이 목표는 검증용 샘플에서 측정한 값이 아니라 설계 기준입니다.

자주 묻는 질문

도입을 검토할 때 자주 나오는 질문을 네 묶음으로 모았습니다.

숫자와 산식

체화료 · 지체료 · 보관료는 어떻게 계산하나요?

라인마다 TEU × 무료기간을 넘긴 일수 × 일 요율에 청구 통화의 환율을 곱합니다. 체화료와 지체료는 외화 청구를 환율로 원화로 바꾸고, 보관료는 원화 요율을 그대로 씁니다. 기타 추가비용은 일수로 계산되지 않는 금액을 라인에 직접 붙인 값입니다.

이 샘플의 요율과 무료기간은 가정값이며, 실제 값은 선사와의 계약 조건에 따릅니다.

무료기간은 어떻게 반영되나요?

반출까지 일수와 반납까지 일수에서 무료기간을 뺀 값이 0 보다 클 때만 비용이 생깁니다. 체화 · 지체 · 보관이 각자 무료기간을 갖습니다. 무료기간이 예정과 달랐던 몫은 요인분해에서 "무료기간" 요인으로 따로 보입니다.

외화와 환율은 어떻게 처리하나요?

청구 통화별로 환율을 곱해 원화로 바꾼 값으로 합산합니다. 서로 다른 통화를 그대로 더하지 않습니다. 환율이 예정 환율과 달랐던 몫은 "환율" 요인으로 분리됩니다. 어느 날짜의 환율을 쓸지는 운영 시점에 정할 일입니다.

칸의 숫자를 믿을 수 있는지 어떻게 확인하나요?

칸을 누르면 그 금액을 만든 컨테이너 라인이 열리고, 머리에 칸의 값과 읽은 라인의 합이 함께 나옵니다. 검산 패널은 큐브 합계와 원천 라인 합계를 측정값 7종마다 나란히 놓습니다. 샘플에서는 모두 차이가 0 입니다.

예정(비교 기준)은 어디서 오나요?

샘플에서는 라인마다 예정 일수 · 예정 요율을 가진 예정 데이터입니다. 운영에서는 입항 계획이나 이전 기간 평균 같은 회사가 정한 기준에서 가져와야 하며, 어느 자료를 예정으로 삼을지는 도입 때 가장 먼저 정할 일 중 하나입니다.

요인분해는 어떻게 합이 총차이와 같아지나요?

라인마다 예정 값을 실적 값으로 한 요인씩 순서대로 바꿔 가며 금액 변화를 요인에 배정합니다. 한 번에 하나만 바꾸므로 교차항이 따로 남지 않습니다. 예정이 없는 라인은 통째로 미계획 요인입니다. 샘플의 3,880개 라인 모두에서 합과 총차이가 같았습니다.

화면과 조작

조회조건에서 꼭 넣어야 하는 것은 무엇인가요?

회사코드와 시작 · 종료 입항월입니다. 선사 · 입항지 · 터미널 같은 차원 값은 선택이며 비우면 전체입니다. 입력칸에서 Enter 키로도 조회됩니다.

행과 열 축은 몇 단계까지 쓸 수 있나요?

행 축은 최대 3단계, 열 축은 최대 2단계입니다. 열 조합이 36개를 넘으면 더 추가하지 못하게 막고 범위를 좁히라고 안내합니다. 축을 바꿔도 총합은 변하지 않습니다.

레이아웃은 어디에 저장되나요?

축 · 조회조건 · 표시 항목 · 접힘 상태를 이름 붙여 서비스에 저장하므로 다른 브라우저에서도 같게 보입니다. 기본 레이아웃과 "열 때 자동 조회" 를 지정할 수 있습니다.

금액 단위와 내려받기는 어떻게 되나요?

금액 단위는 원 · 천원 · 백만원 · 억원 중에서 고릅니다(기본 백만원). 피벗과 원천 라인 목록은 CSV 로, 현재 범위의 표와 차트는 PowerPoint 보고서로 내려받습니다.

분석 기능

AI 분석은 숫자를 만드나요?

아닙니다. 금액과 비율은 서비스가 큐브에서 계산하고, 해설은 그 값을 문장으로 옮길 뿐입니다. 기본은 모델이 연결되지 않은 규칙 기반 해설이며, 모델 연결은 서비스 설정에서만 켜고 기본은 꺼짐입니다. 해설에 쓴 숫자의 근거 표를 화면에서 펼쳐 볼 수 있습니다.

AI 에이전트는 무엇을 하고 왜 하루 한 번인가요?

감시 규칙(샘플은 5개)을 돌려 임계를 넘은 건을 대기함에 올리고, 받을 역할의 관점으로 다시 쓴 보고를 남깁니다. 같은 날 두 번째 실행은 서버가 한도로 판정해 새 보고 없이 기록만 남겨, 알림이 쌓이는 것을 막습니다.

변동 사유는 어떻게 남고 어디까지 따라오나요?

사유의 키는 조회 범위와 행 경로입니다. 축을 바꾸거나 다시 펼쳐도 같은 행이면 따라오고, CSV 와 AI 분석 근거에도 함께 실립니다. 이미 사유가 적힌 행은 AI 점검 대상에서 건너뜁니다.

계산항목은 무엇이고 직접 만들 수 있나요?

체화료 + 지체료 같은 식을 서비스가 계산하는 항목입니다. 샘플은 선사 청구 합계 · 체화료 비중 · 합계 계산 · TEU당 비용 · TEU당 유료 초과일 5개를 두었고, 새 계산항목은 서비스의 정의 목록에 식을 추가하는 방식입니다. 화면에서 임의 식을 입력하는 기능은 없습니다.

차이에 색이 칠해지는 기준은 무엇인가요?

차이의 절대 금액이 금액 임계 이상이고 비율이 비율 임계 이상일 때만 입힙니다. 기본은 100만원과 10% 이고 화면에서 고칩니다. 비용이 늘어난 방향은 붉게, 줄어든 방향은 초록으로 칠합니다.

요인 워터폴은 무엇을 보여 주나요?

행 이름을 누르면 그 범위의 예정에서 실적까지가 일곱 요인으로 나뉜 막대로 나옵니다. 붉은 막대는 비용을 늘린 요인, 초록 막대는 줄인 요인이며 맨 아래 검산 줄이 요인 합 − 총차이 = 0원을 매번 보여 줍니다.

도입과 운영

도입하면 어떤 효과가 있고 누가 쓰나요?

수입 · 물류 · 구매 · 자금 담당과 경영지원 조직이 같은 숫자를 서로 다른 관점으로 봅니다. 월 정산 때 엑셀로 합산하던 선사별 · 입항지별 표와 예정 대비 요인 설명을 한 화면에서 만듭니다. 시간 절감 같은 수치는 회사마다 달라 이 글에서 약속하지 않습니다.

적용 시기와 범위는 어떻게 되나요?

이 글의 숫자는 가상 회사 1000 의 2026년 4월~9월 입항분 검증용 샘플 데이터에서 나온 것입니다. 운영에서 읽는 기간과 회사 범위는 서비스 구성과 권한에 따르며, 실제 적용 시점은 도입 때 정합니다.

표준 T-code 와는 어떤 관계인가요?

표준 실행은 SAP 표준 T-code 가 담당하고, 이 화면은 조회·검증 관점을 더해 확장합니다. 구매 오더는 ME23N, 입고는 MIGO · MB51, 송장은 MIRO · MIR4, 공급사 항목은 FBL1N, 전표는 FB03 에서 확인합니다. 기존 리포트를 없앨 필요는 없습니다.

데이터 원천은 무엇이고 정합성은 어떻게 지키나요?

구매 오더 · 입고 · 송장 문서의 표준 데이터에 컨테이너 이벤트 일자(입항 · 반출 · 반납)와 선사 계약 조건이 더해집니다. 이벤트 일자의 원천은 표준 MM 에 없어 회사 환경에서 확인해야 합니다. 정합성은 라인 합 = 큐브 합 등 대사식을 전수로 돌려 지킵니다.

권한과 보안은 어떻게 하나요?

회사코드 같은 표준 권한 객체를 라인 뷰(집계 단계)에 겁니다. 드릴스루에만 걸면 합계와의 차이로 남의 숫자가 추정될 수 있습니다. 화면은 외부 라이브러리를 쓰지 않고, AI 모델은 기본 꺼짐이라 외부로 나가는 전송이 없습니다.

대용량 데이터에서도 되나요?

집계는 데이터베이스의 큐브 뷰에서 하고 조회 기간과 회사코드를 필수로 둡니다. 원천 라인은 칸을 눌렀을 때만 기본 500행씩 읽습니다. 샘플은 라인 3,880건이므로 운영 규모의 응답 시간은 실제 환경에서 측정해야 합니다.

조건 유형이나 매핑이 바뀌면 어떻게 하나요?

선사 조건은 조건 테이블에서, 부대비용 구분은 조건 유형 매핑에서 고칩니다. 매핑이 바뀌면 측정값 구분이 바뀌므로 이후 기간부터 적용하고 지난 기간은 다시 계산할지 정해야 합니다. 변경 전후 합계를 표준 T-code 로 한 번 맞춰 보는 것을 권합니다.

운영 연결까지 어떤 절차가 필요한가요?

컨테이너 이벤트 원천 확정 → 선사 조건 입력 → 뷰 전송 순서대로 활성화 → 서비스 게시 → 앱 설정의 서비스 주소 교체 → 한 기간을 표준 화면과 병행 대사 순서입니다. 소요 시간은 이벤트 원천의 준비 상태에 크게 좌우되어 이 글에서 단정하지 않습니다.

이 화면의 결과를 회계 · 세무 판단의 최종 근거로 써도 되나요?

이 화면은 집계와 대사를 돕는 점검 도구입니다. 최종 판단은 회사와 감사인이 하고, 관세 · 세무 신고는 회사와 세무 대리인 · 관세사가 확인합니다. 법정 · 감사 대응 숫자는 표준 전표 기준으로 유지해 주세요.