SAP 생산 수불 분석 — 들어온 것과 나간 것이 맞는가
자재문서를 올려 수불 원천을 만들고, 자재별 입출고와 공정 단계별 재고 흐름을 한 앱에서 확인하는 화면입니다.
재고가 맞지 않는다는 말은 어딘가에서 들어오거나 나간 기록이 빠졌다는 뜻입니다. 기초 재고에 입고를 더하고 출고를 빼면 기말 재고가 나와야 합니다.
반도체처럼 공정이 길고 외주가 섞이면 자재문서만으로는 흐름이 잘 보이지 않습니다. 이 앱은 자재문서를 엑셀로 올려 수불 원천을 만들고, 자재별 기초·입출고·기말·재공 수량을 조회하며, 원자재에서 제품까지 공정 단계별 재고 흐름을 한 장의 공정 맵으로 보여 줍니다. 실제로 구동해 캡처한 화면 3종을 함께 공개합니다.
SAP 표준 기능을 그대로 이어받은 부분
- 자재문서 — 자재문서번호(belnr)·전기일(budat)·이동유형
- 자재 — 자재코드·명칭·자재유형·단위
- 저장위치·공급처 — 출발(storage_supplier)과 도착(to_storage_supplier)
- 생산 — 오더번호·로트(lotId)·프로젝트
- 수량 — 기초·기간 입출고·기말, 재공(WIP)·스크랩
| 항목 | 내용 |
|---|---|
| 기반 T-code | MB51 · MB5B |
| 업무 영역 | 생산(PP) · 자재 관리(MM) |
| Namespace | pp003_materialflow |
| 셸 구조 | sap.tnt.ToolPage + 왼쪽 메뉴 5개(자재문서 업로드 · 자재문서 조회 · 생산 flow · 재고 flow SJ · 재고 flow SIC) |
| 데이터 | ZFCMC_F02_C015A(자재문서 수불) + 함수임포트 funcGetTotalQty · funcGetFlowFromTo · funcGetSumQty · funcImportTempFile · funcSaveTempFile |
| 성격 | 엑셀 업로드(임시 저장 → 확정) + 조회 |
| 시각화 | SVG 공정 맵(자체 컨트롤) · 원자재 계열별 흐름 네트워크(vis-network) |
| UI 테마 | sap_horizon 단일 적용 |
실제 화면 3종 둘러보기
자재문서를 올리고 → 자재별 수불을 조회하고 → 공정 맵에서 어느 단계에 재고가 쌓였는지 짚습니다.
아래는 서버에 올린 앱을 실제 브라우저로 열어 메뉴를 눌러 가며 캡처한 화면입니다. 이미지를 클릭하면 원본 크기로 확대됩니다. 데이터는 시연용 목업입니다.
원자재 계열별(SJ·SIC) 흐름 네트워크는 기초·기말 재고와 이동 경로 데이터가 있어야 그려지는 화면이라, 시연 데이터로 구동한 이번 공개 화면에서는 제외했습니다. 화면 구성은 아래 OpenUI5 구성과 수불 산식에 정리했습니다.
조작 방법
- 왼쪽 메뉴 1-1. 자재문서 업로드에서 [찾아보기]로 엑셀을 고릅니다. 양식은 [템플릿 다운로드]로 받습니다.
- 올라온 목록을 확인하고 [저장]으로 확정합니다. 다시 고르려면 [취소], 목록을 다시 읽으려면 [갱신]을 누릅니다.
- 지난 업로드는 [업로드 이력조회]에서 확인합니다.
- 1-2. 자재문서 조회에서 조건을 입력하고 [조회]를 누릅니다. 자주 쓰는 조건은 변형(Standard ▾)으로 저장합니다.
- 목록에서 기초 + 기간 입고 − 기간 출고 = 기말이 맞는지 봅니다. 맞지 않는 자재는 이동유형 열로 원인을 찾습니다.
- 2-1. 생산 flow에서 공정 단계별 기초→기말 증감을 봅니다. 단계를 누르면 자재문서 조회로 넘어갑니다.
- 2-2. 재고 flow(SJ·SIC)에서 원자재 계열별로 저장위치·외주처 사이의 이동을 네트워크로 따라갑니다.
- 각 화면의 다운로드 버튼으로 결과를 엑셀로 내려받습니다.
수불 산식
재고는 더하고 빼는 것으로만 변합니다. 앱은 기간 이동을 성격별로 나눠 두어 어느 이동이 기말을 바꿨는지 추적할 수 있게 했습니다.
기말 수량(qty) = 기초 수량(start_qty) + 기간 수량(period_qty)
기간 수량 = 입고(period_in_qty) − 출고(period_out_qty)
± 타계정 입고·출고(period_tain_qty · period_taout_qty)
± 이동유형별 수량(551 · 701 · 901 · 903 · 905 · 915)
재공(WIP) 기초 start_wip_qty → 기말 wip_qty (투입 wip_in_qty · stock_wip_in_qty)
스크랩 기초 start_scrap_qty → 기말 scrap_qty (반출 scrap_out_qty)
공정 맵 라벨 [계열] 기초 → 기말 (기말 − 기초)
흐름 네트워크의 크기 규칙
원자재 계열별 네트워크는 수량을 로트 단위로 환산해 노드 크기와 선 굵기를 정합니다. PC 단위는 수량 ÷ 250, 그 밖의 단위는 수량 ÷ 125,000 으로 환산하고, 노드는 30~100 사이로 제한하며 선은 최소 1로 그립니다. 입출고 수량과 재공 수량이 모두 0인 이동은 그리지 않아, 실제로 움직인 경로만 남습니다.
처리 단계
| 단계 | 처리 | 비고 |
|---|---|---|
| 1. 파일 선택 | 엑셀을 고르면 임시 저장키(ifkey, GUID)로 업로드 | 양식은 템플릿 다운로드 |
| 2. 임시 반영 | funcImportTempFile 이 파일을 읽어 업로드 목록에 적재 | 처리상태 대기·진행·완료 |
| 3. 확정·취소 | [저장] → funcSaveTempFile 로 저장키 단위 확정, [취소]는 저장키를 비우고 목록 초기화 | [업로드 이력조회]로 추적 |
| 4. 수불 조회 | 조회조건 → ZFCMC_F02_C015A 목록 → funcGetSumQty 로 같은 조건의 합계 수량 | 필터를 그대로 넘겨 목록과 합계 일치 |
| 5. 공정 맵 | funcGetTotalQty 결과를 저장위치 코드(1000·1010·2000~2050·제품)로 공정 단계에 배정 | SJ(1000) · SiC(1010) 계열 분리 |
| 6. 흐름 네트워크 | funcGetFlowFromTo(project=SJ·SIC) → 기초·기말·재공과 이동 경로를 노드·선으로 변환 | vis-network 로 그림 |
조회조건
| 필드 | 필수 | 설명 |
|---|---|---|
material | 선택 | 자재코드 |
material_tx | 선택 | 자재명 |
project | 선택 | 원자재 계열(SJ · SIC) |
storage_supplier_tx | 선택 | 출발 저장위치·공급처 |
to_storage_supplier_tx | 선택 | 도착 저장위치·공급처 |
meins | 선택 | 단위(PC · EA 등) |
mtart | 선택 | 자재유형 |
bwart_tx | 선택 | 이동유형명 |
lotId | 선택 | 로트 |
belnr | 선택 | 자재문서번호 |
orderNo | 선택 | 생산·외주 오더번호 |
결과 컬럼
| 구분 | 컬럼 | 의미 |
|---|---|---|
| 식별 | ifkey · material · material_tx · budat | 저장키 · 자재 · 명칭 · 전기일 |
| 경로 | storage_supplier_tx → to_storage_supplier_tx | 출발 → 도착 위치 |
| 재고 | start_qty · period_qty · qty | 기초 · 기간 · 기말 |
| 입출고 | period_in_qty · period_out_qty · period_tain_qty · period_taout_qty | 입고 · 출고 · 타계정 입고 · 타계정 출고 |
| 이동유형별 | period_551_qty · period_701_qty · period_901_qty · period_903_qty · period_905_qty · period_915_qty | 폐기 · 실사 차이 · 회사 정의 이동유형 |
| 재공·스크랩 | start_wip_qty · wip_qty · wip_in_qty · stock_wip_in_qty · start_scrap_qty · scrap_qty · scrap_out_qty | 재공과 스크랩의 기초 · 기말 · 투입 · 반출 |
| 속성 | project · mtart · meins · bwart · orderNo · lotId | 계열 · 자재유형 · 단위 · 이동유형 · 오더 · 로트 |
SAP 표준 기능 매핑
| 표준 | 역할 | 이 화면에서의 확장 |
|---|---|---|
MB51 | 자재문서 목록 | 공정 단계 기준 수불 목록 |
MB5B | 기간별 재고 수불 | 기초 · 기말 수량 |
MIGO | 입출고 처리 | 자재문서 원천(엑셀 업로드로 보완) |
CO03 · COOIS | 생산오더 · 재공 | 오더번호 · 재공 수량 |
MSEG · MKPF | 자재문서 라인 · 헤더 | 수불 원천 |
MARD · T156 | 저장위치 재고 · 이동유형 설정 | 공정 단계 배정 · 입출고 구분 |
도입 시 확인이 필요한 부분
공정 맵은 저장위치 코드를 공정 단계로 읽습니다. 저장위치 체계가 공정과 1:1로 맞지 않는 회사라면 저장위치 → 공정 단계 매핑표를 먼저 정해야 합니다. 외주처로 나간 재고를 사내 재고로 볼지 외주 단계로 볼지도 수불 기준에 따라 달라집니다.
참고 CDS 뷰
@AbapCatalog.sqlViewName: 'ZCMATFLOW'
@EndUserText.label: '생산 수불 분석 (Z)'
define view Z_C_MATERIAL_FLOW
as select from mseg as Line
inner join mkpf as Header on Line.mblnr = Header.mblnr
and Line.mjahr = Header.mjahr
left outer join makt as MatText on Line.matnr = MatText.matnr
and MatText.spras = 'K'
{
key Line.werks as Plant,
key Line.matnr as Material,
key Line.lgort as StorageLocation, -- 공정 단계로 매핑
key Header.budat as PostingDate,
MatText.maktx as MaterialName,
Line.bwart as MovementType,
Line.aufnr as OrderNo,
Line.charg as LotId,
sum( case when Line.shkzg = 'S' then Line.menge else 0 end ) as ReceiptQty,
sum( case when Line.shkzg = 'H' then Line.menge else 0 end ) as IssueQty,
Line.meins as Uom
// 기초·기말 재고는 기간 누계에서 산출, 이동유형(551·701·9xx)은 소비 뷰에서 열로 분리
}
group by Line.werks, Line.matnr, Line.lgort, Header.budat, MatText.maktx,
Line.bwart, Line.aufnr, Line.charg, Line.meins
매핑 이해를 돕기 위한 참고용 설계입니다. 실제 도입 시에는 운영 환경 설정과 릴리즈에 맞춰 조정합니다.
OpenUI5 구성
| 기능 | 사용 컨트롤 · 구현 |
|---|---|
| 화면 골격 | sap.tnt.ToolPage + sap.tnt.SideNavigation — 메뉴 옆에 화면별 건수 표시 |
| 화면 전환 | sap.m.routing.Router — 해시에 timestamp 를 붙여 같은 메뉴를 다시 눌러도 항상 새로 조회 |
| 자재문서 업로드 | sap.m.semantic.FullscreenPage + sap.ui.unified.FileUploader + 업로드 목록 |
| 자재문서 조회 | sap.f.DynamicPage + FilterBar · VariantManagement + sap.m.Table |
| 공정 맵 | 자체 컨트롤 PlantMap · LocationMap · TextMap — SVG 경로로 공정 노드와 흐르는 선을 그림 |
| 흐름 네트워크 | vischart_network_control — vis-network 를 감싼 UI5 컨트롤(nodes · edges) |
| 내보내기 | 엑셀 다운로드(업로드 목록 · 조회 목록 · 네트워크 노드) |
공정 맵을 SVG 컨트롤로 만든 이유
공정 순서는 회사마다 고정돼 있어 자동 배치 그래프보다 사람이 정한 위치가 읽기 쉽습니다. 좌표와 경로를 XML 뷰에 선언하는 SVG 컨트롤로 만들면 공정이 바뀌어도 뷰 파일만 고치면 되고, 수량 라벨은 일반 UI5 바인딩으로 채울 수 있습니다.
파일 구성
| 경로 | 역할 |
|---|---|
webapp/manifest.json | 앱 디스크립터 — 라우팅 6개 · OData 서비스 |
webapp/view/Root.view.xml | ToolPage · 왼쪽 메뉴 |
webapp/view/Upload-matdoc.view.xml | 자재문서 업로드 |
webapp/view/List-data.view.xml | 자재문서 조회 |
webapp/view/List-flowSummary.view.xml | 생산 flow 공정 맵 |
webapp/view/List-flow-sj.view.xml · List-flow-sic.view.xml | 원자재 계열별 흐름 네트워크 |
webapp/controls/PlantMap.js · LocationMap.js · TextMap.js | SVG 공정 맵 컨트롤 |
webapp/view/vischart/vischart_network_control.js | vis-network 래핑 컨트롤 |
webapp/js/vis-network-min.js | vis-network 라이브러리 |
webapp/localdata/ZFCMC_F02_C015*.json | 수불 목업 데이터 |
검증 결과
| 검증 항목 | 결과 |
|---|---|
| 메뉴 5개 전환 — 라우팅 오류 없음 | 5/5 |
| 자재문서 업로드 목록 표시 — 메뉴 건수(25건)와 일치 | 통과 |
| 자재문서 조회 — 조회 후 목록 25건 · 컬럼 37개 표시 | 통과 |
| 생산 flow — 공정 노드 12개 렌더링 · 수량 라벨 바인딩 | 통과 |
| 공정 노드 클릭 → 자재문서 조회로 이동 | 통과 |
| 캡처 시점 로딩(busy) 표시 없음 | 3/3 |
| 재고 flow(SJ·SIC) 네트워크 | 시연 데이터 없음 — 공개 화면 제외 |
| 테마 런타임 확인 | sap_horizon |
자주 묻는 질문
수불이 안 맞으면 무엇을 먼저 보나요?
기간 경계의 자재문서를 봅니다. 월말에 처리했는데 전기일이 다음 달로 넘어간 건이 있으면 두 달 모두에서 차이가 납니다. 자재문서 조회에서 전기일(budat)과 이동유형으로 좁혀 보면 빠르게 찾을 수 있습니다.
업로드한 엑셀은 바로 반영되나요?
아닙니다. 파일을 고르면 먼저 임시 저장키(ifkey)로 올라가 표에서 내용을 확인할 수 있고, [저장]을 눌러야 확정됩니다. 잘못 골랐으면 [취소]로 목록을 비우고 다시 올리며, 지난 업로드는 [업로드 이력조회]로 확인합니다.
타계정 입출고와 9xx 이동유형은 왜 따로 보나요?
구매·생산처럼 정상 흐름이 아닌 이동은 수불 차이의 주된 원인입니다. 타계정 입출고(tain·taout), 폐기(551), 실사 차이(701), 회사가 정의한 9xx 이동유형을 열로 분리해 두면 어느 성격의 이동이 기말을 바꿨는지 바로 보입니다.
공정 맵의 숫자는 무엇인가요?
각 공정 단계의 기초 재고 → 기말 재고(증감) 입니다. 원자재는 SJ와 SiC 두 계열로 나눠 표시하고, 단계를 누르면 해당 공정 키워드로 자재문서 조회 화면으로 넘어갑니다.
SAP 표준 기능과 어떻게 이어지나요?
자재 이동은 표준 MM 이 자재문서로 기록합니다. 이 앱은 그 자재문서를 공정 단계 기준으로 다시 묶어 기초·입출고·기말 흐름과 재공 수량을 한 화면에서 보도록 만든 조회형 확장입니다.