SAP

이익센터(PRCTR) vs 코스트센터 — 손익이냐 비용이냐 #shorts #SAP #CO

📖 개요 — 왜 이 둘을 구분해야 하는가

"우리 모바일 사업부, 이번 분기에 흑자였나요?"라는 질문에 코스트센터 리포트만으로 답하려다 막힌 경험이 있다면 이 글이 도움이 됩니다. 코스트센터(Cost Center)와 이익센터(Profit Center)는 SAP 관리회계(CO)의 대표적인 조직 단위지만, 목적이 근본적으로 다릅니다. 이 글을 끝까지 읽으면 다음을 할 수 있습니다.

  • 비용귀속 단위(코스트센터)와 손익책임 단위(이익센터)의 역할 차이를 설명할 수 있다
  • 사업부 손익을 보려면 왜 이익센터가 필요한지 데이터 구조(ACDOCA) 관점에서 이해한다
  • CDS View와 ABAP으로 두 단위의 실적을 직접 조회하는 예제를 작성할 수 있다

📚 미리 알아두면 좋은 배경

재무회계(FI)와 관리회계(CO)의 차이, 총계정원장 전표의 기본 구조(계정·금액·차대변)를 알고 있으면 수월합니다. ABAP SQL과 CDS View 문법을 한 번이라도 다뤄봤다면 예제 코드를 그대로 따라올 수 있습니다. 중급 난이도이지만 회계 지식이 얕아도 비유 중심으로 설명하므로 개발자도 읽을 수 있게 구성했습니다.

🔧 환경과 버전

이 글의 예제는 SAP S/4HANA 2023 온프레미스(ABAP Platform 7.58) 기준입니다. S/4HANA에서는 FI와 CO 실적이 통합 저널 테이블 ACDOCA에 함께 기록되며, 이익센터(PRCTR)와 코스트센터(KOSTL) 필드가 같은 라인에 존재합니다. 반면 ECC 6.0에서는 이익센터 실적이 별도 테이블(GLPCT 등)에 이관 방식으로 쌓였기 때문에 조회 로직이 다릅니다. 마스터 데이터는 코스트센터 CSKS, 이익센터 CEPC 테이블이며, 표준 CDS 인터페이스 뷰로는 I_CostCenter, I_ProfitCenter가 제공됩니다. 개발 도구는 ADT(Eclipse) 사용을 권장합니다.

💡 핵심 개념 — 가계부와 사업장부의 차이

코스트센터는 가계부의 지출 페이지와 같습니다. "마케팅팀이 이번 달 광고비로 얼마를 썼는가"처럼 비용이 어디에서 발생했는지를 책임자 단위로 모으는 그릇입니다. 수익은 원칙적으로 코스트센터에 귀속되지 않으므로, 코스트센터 리포트를 아무리 들여다봐도 "얼마 벌었는지"는 나오지 않습니다.

이익센터는 자영업자의 사업장부입니다. 매출과 비용을 한 페이지에 적어 남는 게 있는지(손익)를 따집니다. 사업부·제품군·지역처럼 "하나의 작은 회사처럼 평가하고 싶은 단위"를 이익센터로 잡으면, 매출 전표와 비용 전표가 모두 그 이익센터로 흘러들어 손익계산서를 사업부 단위로 쪼개 볼 수 있습니다.

두 단위는 경쟁 관계가 아니라 계층 관계입니다. 일반적으로 코스트센터 마스터에 이익센터를 지정해 두면, 코스트센터로 귀속된 비용이 자동으로 해당 이익센터에도 반영됩니다.

구분코스트센터이익센터
관점비용귀속 (어디서 썼나)손익책임 (얼마 남았나)
담는 것비용 중심수익 + 비용
전형적 단위부서·팀·설비사업부·제품군·지역
책임자 질문"예산 안에서 썼는가""이익을 냈는가"
주요 필드KOSTLPRCTR

결론부터 말하면 — 사업부 손익을 보려면 이익센터가 필요합니다. 코스트센터는 그 손익의 비용 쪽 디테일을 채워주는 하위 그릇입니다.

💻 실전 예제 — 가전 제조사 한빛전자 시나리오

가상의 제조사 한빛전자를 예로 듭니다. 모바일 사업부를 이익센터 PHB-MOB로 잡고, 그 아래 코스트센터 C4100(모바일 마케팅), C4200(모바일 개발)을 배정한 구조입니다.

1단계 — 코스트센터별 비용 집계 CDS View

먼저 "어디서 얼마를 썼는지"를 보는 기본 뷰입니다. ACDOCA에서 코스트센터가 채워진 라인만 모읍니다.

@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: '코스트센터별 비용 집계'
define view entity ZHB_C_CctrExpense
  as select from acdoca
  association [0..1] to I_CostCenter as _Cctr
    on  $projection.CostCenter    = _Cctr.CostCenter
    and $projection.ControllingArea = _Cctr.ControllingArea
{
  key rbukrs        as CompanyCode,
  key kokrs         as ControllingArea,
  key kostl         as CostCenter,
  key gjahr         as FiscalYear,
      @Semantics.amount.currencyCode: 'Currency'
      sum( hsl )    as ExpenseAmount,
      rhcur         as Currency,
      _Cctr
}
where rldnr  = '0L'      -- 대표 원장
  and kostl is not initial
group by rbukrs, kokrs, kostl, gjahr, rhcur

이 뷰로 C4100의 광고비 총액은 확인할 수 있지만, 모바일 사업부의 매출은 어디에도 없습니다. 코스트센터의 한계가 바로 여기입니다.

2단계 — 사업부 손익 조회 ABAP (에러 처리·로깅 포함)

이익센터 관점으로 전환해 수익과 비용을 한 번에 읽는 클래스입니다. 데이터가 없을 때 예외를 던지고, 결과 건수를 로그로 남깁니다.

CLASS zhb_cl_pctr_pnl DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    TYPES: BEGIN OF ty_pnl_line,
             prctr  TYPE prctr,
             racct  TYPE racct,
             amount TYPE fins_vhcur12,
           END OF ty_pnl_line,
           tt_pnl TYPE STANDARD TABLE OF ty_pnl_line WITH EMPTY KEY.
    METHODS get_division_pnl
      IMPORTING iv_bukrs      TYPE bukrs
                iv_gjahr      TYPE gjahr
                iv_prctr      TYPE prctr
      RETURNING VALUE(rt_pnl) TYPE tt_pnl
      RAISING   zhb_cx_pnl_no_data.
ENDCLASS.

CLASS zhb_cl_pctr_pnl IMPLEMENTATION.
  METHOD get_division_pnl.
    " 이익센터에는 수익 계정과 비용 계정이 모두 귀속된다
    SELECT prctr, racct, SUM( hsl ) AS amount
      FROM acdoca
      WHERE rldnr  = '0L'
        AND rbukrs = @iv_bukrs
        AND gjahr  = @iv_gjahr
        AND prctr  = @iv_prctr
      GROUP BY prctr, racct
      INTO CORRESPONDING FIELDS OF TABLE @rt_pnl.

    IF rt_pnl IS INITIAL.
      RAISE EXCEPTION NEW zhb_cx_pnl_no_data(
        textid = zhb_cx_pnl_no_data=>no_postings ).
    ENDIF.

    " 애플리케이션 로그 기록 (BAL)
    DATA(lo_log) = cl_bali_log=>create( ).
    lo_log->add_item( cl_bali_free_text_setter=>create(
      severity = if_bali_constants=>c_severity_status
      text     = |PnL rows: { lines( rt_pnl ) } for { iv_prctr }| ) ).
  ENDMETHOD.
ENDCLASS.

PHB-MOB로 조회하면 매출 계정(4xxxxx)과 비용 계정(5xxxxx)이 함께 리턴되어, 차감하면 사업부 영업이익이 나옵니다. 같은 쿼리를 kostl로 바꾸면 수익 라인이 사라지는 것을 직접 비교해 보면 개념이 확실해집니다.

3단계 — 프로덕션 수준: 권한 제어와 성능

실무 배포 시에는 이익센터 권한(권한 오브젝트 K_PCA)을 DCL로 걸고, 집계를 DB로 푸시다운합니다.

@EndUserText.label: '이익센터 손익 뷰 접근 제어'
@MappingRole: true
define role ZHB_C_PctrPnl_DCL {
  grant select on ZHB_C_PctrPnl
    where ( ProfitCenter ) =
      aspect pfcg_auth( K_PCA, PRCTR, ACTVT = '03' );
}

성능 관점에서는 (1) 원장·회사코드·연도를 항상 필수 파라미터로 강제해 ACDOCA 풀스캔을 막고, (2) 집계는 CDS/SQL 레벨에서 끝내 애플리케이션 서버로 로우 데이터를 끌어오지 않는 것이 일반적으로 권장됩니다. 테스트는 cl_cds_test_environment로 ACDOCA를 테스트 더블로 대체해, 수익·비용 혼합 라인이 이익센터 기준으로 올바르게 합산되는지 단위 테스트로 검증하세요.

⚠️ 자주 하는 실수와 해결법

Q1. 코스트센터 리포트에 매출이 안 보입니다. 설정 오류인가요?
아닙니다. 설계상 정상입니다. 수익은 코스트센터가 아니라 이익센터(또는 CO-PA/마진 분석)로 흐르는 것이 표준 동작입니다. 사업부 손익이 목적이라면 이익센터 리포트로 전환하세요.

Q2. 이익센터가 비어 있는 전표가 생깁니다.
코스트센터 마스터(CSKS)에 이익센터가 미배정이거나, 파생 규칙이 없는 계정에 전기된 경우입니다. 기본 이익센터(더미) 설정과 문서 분할(Document Splitting) 구성을 점검하고, 미배정 전표는 기간 마감 전에 재배정하는 운영 루틴을 두는 것이 좋습니다.

Q3. ECC에서 쓰던 이익센터 조회 로직이 S/4HANA에서 안 맞습니다.
ECC는 이익센터 실적을 별도 테이블에 이관해 쌓았지만, S/4HANA는 ACDOCA 한 곳에서 실시간으로 봅니다. 구 테이블 직접 조회 코드는 ACDOCA 기반으로 재작성하세요.

Q4. 조직 개편으로 코스트센터의 이익센터 배정을 바꿨더니 과거 실적이 흔들립니다.
배정 변경은 소급 적용되지 않는 것이 일반적입니다. 기간 구분을 명확히 하고, 과거 비교가 필요하면 변경 전후를 별도 축(예: 대체 계층)으로 관리하세요.

🚀 여기서 더 나아가기

사업부 손익까지 왔다면 다음 관심사는 자연스럽게 제품·고객 단위 수익성입니다. S/4HANA의 마진 분석(Margin Analysis)은 이익센터보다 더 잘게 손익을 쪼개 줍니다. 그 밖에 이익센터 간 내부거래 정산, Universal Allocation을 통한 비용 배부, 세그먼트 보고와 이익센터의 관계를 이어서 살펴보면 CO 조직 설계의 큰 그림이 완성됩니다.

댓글 0

아직 댓글이 없습니다.