ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • CDS Consumption Entity 어노테이션 정리
    SAP 2026. 5. 12. 18:35

     

    CDS Consumption Entity — 어노테이션 완전 정리

    1. @UI — 화면 레이아웃 제어

    Fiori Elements 화면(List Report, Object Page)의 구조를 선언하는 가장 핵심적인 어노테이션 그룹.

    ① @UI.headerInfo — 오브젝트 페이지 헤더

    @UI.headerInfo: {
      typeName:       'Sales Order',
      typeNamePlural: 'Sales Orders',
      title:       { type: #STANDARD,    value: 'SalesOrderId' },
      description: { type: #ASSOCIATED, value: '_Customer.CustomerName' }
    }
    속성 설명
    typeName string 단수 레이블
    typeNamePlural string 복수 레이블
    title.type #STANDARD #ASSOCIATED 타이틀 소스 유형
    title.value field name 타이틀로 사용할 필드
    description.value field / assoc path 부제목 필드
    imageUrl field name 이미지 URL 필드

    ② @UI.lineItem — 리스트 화면 컬럼

    @UI.lineItem: [
      { position: 10, label: '주문번호', importance: #HIGH },
      { position: 20, label: '금액',    importance: #MEDIUM },
      { type: #FOR_ACTION, dataAction: 'approve', label: '승인' }  -- 액션 버튼
    ]
    속성 주요 값 설명
    position 숫자 (10, 20, 30…) 컬럼 순서
    label string 컬럼 헤더 레이블
    importance #HIGH #MEDIUM #LOW 모바일 화면 표시 우선순위
    hidden true / false 컬럼 숨김
    type #STANDARD #FOR_ACTION #WITH_INTENT_BASED_NAVIGATION 항목 유형
    dataAction action name RAP 액션 이름 (type=#FOR_ACTION)
    criticality field name 상태 색상 소스 필드
    criticalityRepresentation #WITH_ICON #WITHOUT_ICON 아이콘 표시 여부
    url field name 하이퍼링크 URL 소스 필드

    ③ @UI.selectionField — 검색 조건 필드

    @UI.selectionField: [{ position: 10 }]
    SalesOrderId,
    
    @UI.selectionField: [{ position: 20 }]
    CustomerName,
    속성 설명
    position 검색 조건 영역에서의 순서

    ④ @UI.facet — 오브젝트 페이지 섹션 구성

    @UI.facet: [
      { id: 'GeneralInfo', type: #IDENTIFICATION_REFERENCE,
        label: '기본 정보', position: 10 },
      { id: 'LineItems',   type: #LINEITEM_REFERENCE,
        label: '항목 목록', position: 20,
        targetElement: '_Items' }
    ]
    type 값 설명
    #IDENTIFICATION_REFERENCE @UI.identification 필드 그룹 표시
    #FIELDGROUP_REFERENCE @UI.fieldGroup 필드 그룹 표시
    #LINEITEM_REFERENCE 연관 엔티티의 @UI.lineItem 테이블 표시
    #COLLECTION 여러 facet을 하나의 탭으로 묶기

    ⑤ @UI.identification — 오브젝트 페이지 기본 필드

    @UI.identification: [{ position: 10, label: '주문번호' }]
    SalesOrderId,

    ⑥ @UI.fieldGroup — 필드 그룹 정의

    @UI.fieldGroup: [{ qualifier: 'PriceInfo', position: 10, label: '가격 정보' }]
    Amount,
    
    @UI.fieldGroup: [{ qualifier: 'PriceInfo', position: 20 }]
    CurrencyCode,
    💡 facet에서 참조: { type: #FIELDGROUP_REFERENCE, targetQualifier: 'PriceInfo' } 로 연결

    ⑦ @UI.hidden — 필드 숨김

    @UI.hidden: true
    CurrencyCode,

    ⑧ @UI.dataPoint — KPI / 수치 강조 표시

    @UI.dataPoint: {
      qualifier:    'TotalAmountPoint',
      title:        '총 금액',
      criticality:  'StatusCriticality'
    }

    ⑨ @UI.chart — 차트 설정 (Analytical List Page)

    @UI.chart: {
      chartType:   #BAR,
      title:       '월별 매출',
      dimensions:  [{ dimension: 'PostingMonth' }],
      measures:    [{ measure: 'Amount' }]
    }

    ⑩ @UI.presentationVariant — 기본 정렬/그룹 설정

    @UI.presentationVariant: [{
      sortOrder: [{ by: 'CreationDate', direction: #DESC }],
      groupBy:   ['CompanyCode'],
      maxItems:  100
    }]

    ⑪ @UI.selectionVariant — 기본 필터 값 설정

    @UI.selectionVariant: [{
      qualifier:        'OpenOrders',
      filter:           'Status EQ ''OPEN'''
    }]

    2. @Consumption — 필터·검색 제어

    ① @Consumption.filter — 필터 동작 상세 제어

    @Consumption.filter: {
      selectionType:  #SINGLE,    -- #SINGLE / #MULTIPLE / #INTERVAL
      mandatory:       false,
      defaultValue:    'OPEN',
      hidden:          false
    }
    속성 설명
    selectionType #SINGLE #MULTIPLE #INTERVAL 단일 / 복수 / 범위 선택
    mandatory true / false 필수 입력 여부
    defaultValue string 기본값
    hidden true / false 필터 숨김
    multipleSelections true / false 다중 선택 활성화

    ② @Consumption.valueHelpDefinition — 값 도움말 연결

    @Consumption.valueHelpDefinition: [{
      entity: {
        name:    'I_BusinessPartner',
        element: 'BusinessPartner'
      },
      label:            '거래처',
      useForValidation: true
    }]

    ③ @Consumption.derivedAspect — 파생 필드 설정

    @Consumption.derivedAspect: #PROCESS_AFTER

    ④ @Consumption.semanticObject — 내비게이션 연결

    @Consumption.semanticObject: 'SalesOrder'

    3. @Semantics — 필드 의미 선언

    필드의 업무적 의미를 선언하여 Fiori에서 단위/통화 연결, 이메일·전화 링크 등을 자동 처리.

    어노테이션 사용 예시 설명
    @Semantics.amount.currencyCode 'CurrencyCode' 금액 필드 — 통화 코드 필드 연결
    @Semantics.quantity.unitOfMeasure 'Unit' 수량 필드 — 단위 필드 연결
    @Semantics.currencyCode true 통화 코드 필드임을 선언
    @Semantics.unitOfMeasure true 단위 필드임을 선언
    @Semantics.calendar.year true 연도 필드
    @Semantics.calendar.month true 월 필드
    @Semantics.calendar.yearMonth true 년월(YYYYMM) 필드
    @Semantics.calendar.date true 날짜 필드
    @Semantics.language true 언어 코드 필드
    @Semantics.text true 텍스트(설명) 필드임을 선언
    @Semantics.name.fullName true Full Name 필드
    @Semantics.contact.email { usage: #TO } 이메일 필드 (클릭 시 메일 링크)
    @Semantics.contact.phone { usage: #WORK } 전화번호 필드
    @Semantics.systemDate.createdAt true 생성 타임스탬프
    @Semantics.systemDate.lastChangedAt true 최종 변경 타임스탬프
    @Semantics.user.createdBy true 생성자
    @Semantics.user.lastChangedBy true 최종 변경자
    @Semantics.imageUrl true 이미지 URL 필드
    @Semantics.url true 하이퍼링크 URL 필드
    @Semantics.mimeType true MIME 타입 필드 (첨부파일)
    @Semantics.largeObject { mimeType: '...', acceptableMimeTypes: [...] } BLOB 필드 (첨부파일 업로드)

    4. @ObjectModel — 모델 동작 정의

    어노테이션 사용 예시 설명
    @ObjectModel.usageType { serviceQuality: #A, sizeCategory: #M, dataClass: #TRANSACTIONAL } Interface View에서 사용 유형 선언
    @ObjectModel.text.element ['StatusText'] 코드 필드에 대한 텍스트 필드 연결
    @ObjectModel.text.association '_StatusVH' 코드 텍스트를 Association으로 연결
    @ObjectModel.foreignKey.association '_Customer' 외래 키 Association 선언
    @ObjectModel.representativeKey true 해당 키가 대표 키임을 선언
    @ObjectModel.query.implementedBy 'ABAP:ZCL_QUERY_PROVIDER' Query Provider 클래스 연결
    @ObjectModel.virtualElement true AMDP Scalar Function 등 가상 필드 선언
    @ObjectModel.virtualElementCalculatedBy 'ABAP:ZCL_CALC' 가상 필드 계산 클래스 연결
    @ObjectModel.dataCategory #TEXT #VALUE_HELP #HIERARCHY 뷰 데이터 카테고리
    @ObjectModel.compositionRoot true RAP Composition Root 선언
    @ObjectModel.entityChangeStateId field name ETag 필드 지정
    @Search.searchable: true      -- View 레벨: 검색 대상 선언
    
    @Search.defaultSearchElement: true
    @Search.fuzzinessThreshold: 0.8
    SalesOrderId,
    어노테이션 설명
    @Search.searchable View 전체를 검색 대상으로 선언 (View 레벨)
    @Search.defaultSearchElement 검색 창 입력 시 기본 검색 대상 필드
    @Search.fuzzinessThreshold 오타 허용 수준 (0.0 ~ 1.0, 높을수록 정확)
    @Search.ranking #HIGH #MEDIUM #LOW — 검색 결과 순위 가중치

    6. @EndUserText — 레이블·설명

    @EndUserText.label: '판매 오더'        -- View 또는 필드 레이블
    @EndUserText.quickInfo: '판매 오더 조회 화면'  -- 툴팁 설명
    💡 @EndUserText.label@UI.lineItem.label이 없을 때 컬럼 헤더로 자동 사용됨.

    7. @AccessControl — 권한 제어

    @AccessControl.authorizationCheck: #CHECK          -- DCL 기반 권한 체크
    @AccessControl.authorizationCheck: #NOT_REQUIRED   -- 권한 체크 없음 (개발·테스트 시)
    @AccessControl.authorizationCheck: #PRIVILEGED_ONLY  -- 특수 권한만
    ⚠️ 운영 배포 시 반드시 #CHECK로 설정하고 DCL(Access Control) 객체를 작성해야 함.

    8. @OData — OData 노출 제어

    어노테이션 사용 예시 설명
    @OData.entityType.name 'SalesOrderType' OData Entity Type 이름 지정
    @OData.publish true OData 서비스 자동 생성 (V2 레거시)
    💡 OData V4(RAP)에서는 @OData 직접 사용보다 Service Definition(define service)으로 노출을 제어하는 것이 권장됨.

    9. @Aggregation — 집계 동작

    @Aggregation.default: #SUM    -- 기본 집계 방식
    Amount,
    
    @Aggregation.default: #MAX
    MaxAmount,
    설명
    #SUM 합산
    #MIN 최솟값
    #MAX 최댓값
    #AVG 평균
    #COUNT_DISTINCT 중복 제외 카운트
    #NONE 집계 불가 (기본값)
    #FORMULA 수식 기반 집계

    10. @Analytics — 분석 앱 전용

    @Analytics.dataCategory: #CUBE           -- Analytical Query 대상 선언
    @Analytics.dataExtraction.enabled: true  -- 데이터 추출 허용
    어노테이션 설명
    @Analytics.dataCategory: #CUBE Analytical Query / Embedded Analytics 뷰 선언
    @Analytics.dataCategory: #DIMENSION 차원(마스터 데이터) 뷰
    @Analytics.dataCategory: #FACT 팩트(트랜잭션) 뷰
    @Analytics.internalName 분석 내부 이름 지정
    @Analytics.dataExtraction.enabled BW, Datasphere 등 데이터 추출 허용

    11. 종합 예시 코드

    @EndUserText.label: '판매 오더 조회'
    @AccessControl.authorizationCheck: #NOT_REQUIRED
    @Search.searchable: true
    
    @UI.headerInfo: {
      typeName:       'Sales Order',
      typeNamePlural: 'Sales Orders',
      title:       { type: #STANDARD, value: 'SalesOrderId' },
      description: { type: #ASSOCIATED, value: '_Customer.CustomerName' }
    }
    
    @UI.presentationVariant: [{
      sortOrder: [{ by: 'CreationDate', direction: #DESC }]
    }]
    
    define root view entity ZC_SalesOrder
      provider contract transactional_query
      as projection on ZI_SalesOrder
    {
      -- ① 리스트 + 오브젝트 페이지 공통 키
      @UI.facet: [
        { id: 'Main',  type: #IDENTIFICATION_REFERENCE, label: '기본 정보', position: 10 },
        { id: 'Items', type: #LINEITEM_REFERENCE,        label: '오더 항목', position: 20,
          targetElement: '_Items' }
      ]
    
      @UI.lineItem:       [{ position: 10, label: '오더번호', importance: #HIGH }]
      @UI.identification: [{ position: 10 }]
      @Search.defaultSearchElement: true
      key SalesOrderId,
    
      -- ② 텍스트 필드 (코드 연결)
      @UI.lineItem:       [{ position: 20 }]
      @UI.identification: [{ position: 20 }]
      @ObjectModel.text.association: '_StatusVH'
      StatusCode,
    
      -- ③ 금액 필드
      @UI.lineItem:       [{ position: 30, label: '총 금액' }]
      @UI.identification: [{ position: 30 }]
      @Semantics.amount.currencyCode: 'CurrencyCode'
      @Aggregation.default: #SUM
      TotalAmount,
    
      -- ④ 통화 코드 (숨김)
      @UI.hidden: true
      @Semantics.currencyCode: true
      CurrencyCode,
    
      -- ⑤ 날짜
      @UI.lineItem:       [{ position: 40, label: '생성일' }]
      @Semantics.calendar.date: true
      CreationDate,
    
      -- ⑥ 검색 필터 필드
      @UI.selectionField: [{ position: 10 }]
      @Consumption.filter: { selectionType: #INTERVAL, mandatory: false }
      @Consumption.valueHelpDefinition: [{ entity: { name: 'I_CompanyCode', element: 'CompanyCode' } }]
      CompanyCode,
    
      @UI.selectionField: [{ position: 20 }]
      @Consumption.filter: { selectionType: #SINGLE }
      StatusCode,
    
      -- ⑦ Association 노출
      _Customer,
      _Items,
      _StatusVH
    }
    💡 레이어 원칙: @Semantics·@ObjectModel은 Interface View(ZI_*)에, @UI·@Consumption은 Consumption View(ZC_*)에 집중 배치하는 것이 유지보수에 유리.
    ⚠️ @UI.facet은 Consumption View의 key 필드 바로 위에 선언하거나 View 레벨에 선언해야 정상 렌더링됨.
    #SAP #ABAP #CDS #ConsumptionView #FioriElements #ODataV4 #UIAnnotation
Designed by Tistory.