Ir para o conteúdo

CDS - Anotações e Metadata Extensions

O que são Anotações?

Anotações são metadados que enriquecem as CDS Views com informações semânticas, comportamentais e de apresentação. São fundamentais para integração com frameworks como SAP Fiori, OData e Analytics.

Sintaxe Básica

@AnnotationName: value
@AnnotationName.property: value
@AnnotationName: { property1: value1, property2: value2 }

Categorias de Anotações

1. Anotações Técnicas

Access Control

// Verificar autorização
@AccessControl.authorizationCheck: #CHECK

// Não verificar (apenas desenvolvimento/demo)
@AccessControl.authorizationCheck: #NOT_REQUIRED

// Verificar apenas com privilégio específico
@AccessControl.authorizationCheck: #PRIVILEGED_ONLY

ABAP Catalog

// Buffering (cache)
@AbapCatalog.buffering.status: #ACTIVE
@AbapCatalog.buffering.type: #GENERIC
@AbapCatalog.buffering.numberOfKeyFields: 1

// Compiler
@AbapCatalog.compiler.compareFilter: true

2. Anotações de Apresentação

End User Text

@EndUserText.label: 'Customer Master Data'
@EndUserText.quickInfo: 'Complete customer information'

define view entity ZI_Customer
  as select from kna1
{
  key kunnr as CustomerId,

      @EndUserText.label: 'Customer Name'
      @EndUserText.quickInfo: 'Full name of the customer'
      name1 as CustomerName
}

UI Annotations

@UI.headerInfo: {
  typeName: 'Customer',
  typeNamePlural: 'Customers',
  title: { value: 'CustomerName' }
}

define view entity ZC_Customer
  as select from ZI_Customer
{
  @UI.lineItem: [{ position: 10, importance: #HIGH }]
  @UI.identification: [{ position: 10 }]
  key CustomerId,

  @UI.lineItem: [{ position: 20, importance: #HIGH }]
  @UI.identification: [{ position: 20 }]
  CustomerName,

  @UI.lineItem: [{ position: 30 }]
  Country
}

3. Anotações Semânticas

Currency e Amount

define view entity ZI_SalesOrder
  as select from vbak
{
  key vbeln as SalesOrderId,

      // Valor monetário
      @Semantics.amount.currencyCode: 'Currency'
      netwr as NetValue,

      // Código de moeda
      @Semantics.currencyCode: true
      waers as Currency
}

Quantity e Unit

define view entity ZI_Product
  as select from mara
{
  key matnr as ProductId,

      // Quantidade
      @Semantics.quantity.unitOfMeasure: 'BaseUnit'
      ntgew as NetWeight,

      // Unidade de medida
      @Semantics.unitOfMeasure: true
      meins as BaseUnit
}

Textos e Datas

define view entity ZI_Customer
  as select from kna1
{
  key kunnr as CustomerId,

      // Texto descritivo
      @Semantics.text: true
      name1 as CustomerName,

      // Nome comercial
      @Semantics.name.fullName: true
      name1 as FullName,

      // Endereço
      @Semantics.address.street: true
      stras as Street,

      @Semantics.address.city: true
      ort01 as City,

      @Semantics.address.zipCode: true
      pstlz as PostalCode
}

4. Anotações de Analytics

Analytics Annotations

@Analytics.dataCategory: #CUBE
@Analytics.dataExtraction.enabled: true

define view entity ZI_SalesAnalytics
  as select from vbak as SalesOrder

  association [0..1] to ZI_Customer as _Customer
    on $projection.CustomerId = _Customer.CustomerId
{
  // Dimensões
  @Analytics.dimension: true
  key SalesOrder.vbeln as SalesOrderId,

  @Analytics.dimension: true
  SalesOrder.kunnr as CustomerId,

  @Analytics.dimension: true
  SalesOrder.erdat as CreationDate,

  // Medidas
  @Analytics.measure: true
  @Aggregation.default: #SUM
  @Semantics.amount.currencyCode: 'Currency'
  SalesOrder.netwr as NetValue,

  @Semantics.currencyCode: true
  SalesOrder.waers as Currency,

  _Customer
}

Metadata Extensions

Metadata Extensions permitem separar anotações de UI da definição da view, promovendo reutilização e manutenibilidade.

Ativar Metadata Extension na View

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Customer Data'
@Metadata.allowExtensions: true          // Habilitar extensões

define view entity ZI_Customer
  as select from kna1
{
  key kunnr as CustomerId,
      name1 as CustomerName,
      land1 as Country,
      ort01 as City
}

Criar Metadata Extension

@Metadata.layer: #CUSTOMER

annotate view ZI_Customer with
{
  // Anotações de Header
  @UI.headerInfo: {
    typeName: 'Customer',
    typeNamePlural: 'Customers',
    title: { value: 'CustomerName' },
    description: { value: 'CustomerId' }
  }
  CustomerId;

  // Anotações de Campos
  @UI: {
    lineItem: [{ position: 10, importance: #HIGH }],
    identification: [{ position: 10 }],
    selectionField: [{ position: 10 }]
  }
  @EndUserText.label: 'Customer Number'
  CustomerId;

  @UI: {
    lineItem: [{ position: 20, importance: #HIGH }],
    identification: [{ position: 20 }],
    selectionField: [{ position: 20 }]
  }
  @EndUserText.label: 'Name'
  CustomerName;

  @UI: {
    lineItem: [{ position: 30 }],
    identification: [{ position: 30 }]
  }
  @EndUserText.label: 'Country'
  Country;

  @UI: {
    lineItem: [{ position: 40 }],
    identification: [{ position: 40 }]
  }
  @EndUserText.label: 'City'
  City;
}

Layers de Metadata

// Diferentes camadas de extensão
@Metadata.layer: #CORE          // Nível mais baixo (SAP)
@Metadata.layer: #LOCALIZATION  // Localização
@Metadata.layer: #INDUSTRY      // Indústria específica
@Metadata.layer: #PARTNER       // Partner
@Metadata.layer: #CUSTOMER      // Cliente (mais alta prioridade)

Anotações para OData

Anotações OData Básicas

@OData.publish: true
@OData.entitySet.name: 'Customers'
@OData.entityType.name: 'Customer'

define view entity ZC_Customer
  as select from ZI_Customer
{
  @OData.property.name: 'CustomerID'
  key CustomerId,

  @OData.property.name: 'Name'
  CustomerName,

  @OData.property.name: 'CountryCode'
  Country
}

Anotações de Navegação

define view entity ZC_SalesOrder
  as select from ZI_SalesOrder
{
  key SalesOrderId,
      CustomerId,

      // Exposição de associação para OData
      @OData.association.navigation: true
      _Customer,

      @OData.association.navigation: true
      _Items
}

Exemplo Completo: View com Anotações Completas

View Base

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Sales Order'
@Metadata.allowExtensions: true

define view entity ZI_SalesOrder
  as select from vbak as SalesOrder

  association [0..1] to ZI_Customer as _Customer
    on $projection.CustomerId = _Customer.CustomerId

  association [0..*] to ZI_SalesOrderItem as _Items
    on $projection.SalesOrderId = _Items.SalesOrderId
{
  key SalesOrder.vbeln as SalesOrderId,

      SalesOrder.erdat as CreationDate,

      SalesOrder.erzet as CreationTime,

      SalesOrder.ernam as CreatedBy,

      SalesOrder.kunnr as CustomerId,

      @Semantics.amount.currencyCode: 'Currency'
      SalesOrder.netwr as NetValue,

      @Semantics.currencyCode: true
      SalesOrder.waers as Currency,

      SalesOrder.vkorg as SalesOrganization,

      SalesOrder.vtweg as DistributionChannel,

      SalesOrder.spart as Division,

      // Associações
      _Customer,
      _Items
}

Metadata Extension

@Metadata.layer: #CUSTOMER
@UI: {
  headerInfo: {
    typeName: 'Sales Order',
    typeNamePlural: 'Sales Orders',
    title: { value: 'SalesOrderId' },
    description: { value: 'CustomerName' }
  },
  presentationVariant: [{
    sortOrder: [{ by: 'CreationDate', direction: #DESC }],
    visualizations: [{type: #AS_LINEITEM}]
  }]
}

annotate view ZI_SalesOrder with
{
  @UI.facet: [
    {
      id: 'GeneralInfo',
      type: #COLLECTION,
      label: 'General Information',
      position: 10
    },
    {
      id: 'BasicData',
      parentId: 'GeneralInfo',
      type: #FIELDGROUP_REFERENCE,
      label: 'Basic Data',
      targetQualifier: 'BasicData',
      position: 10
    },
    {
      id: 'Amounts',
      parentId: 'GeneralInfo',
      type: #FIELDGROUP_REFERENCE,
      label: 'Amounts',
      targetQualifier: 'Amounts',
      position: 20
    },
    {
      id: 'Items',
      type: #LINEITEM_REFERENCE,
      label: 'Items',
      position: 20,
      targetElement: '_Items'
    }
  ]
  SalesOrderId;

  @UI: {
    lineItem: [{ position: 10, importance: #HIGH }],
    identification: [{ position: 10 }],
    selectionField: [{ position: 10 }]
  }
  @EndUserText.label: 'Sales Order'
  SalesOrderId;

  @UI: {
    lineItem: [{ position: 20, importance: #HIGH }],
    fieldGroup: [{ qualifier: 'BasicData', position: 10 }]
  }
  @EndUserText.label: 'Creation Date'
  CreationDate;

  @UI: {
    fieldGroup: [{ qualifier: 'BasicData', position: 20 }]
  }
  @EndUserText.label: 'Creation Time'
  CreationTime;

  @UI: {
    fieldGroup: [{ qualifier: 'BasicData', position: 30 }]
  }
  @EndUserText.label: 'Created By'
  CreatedBy;

  @UI: {
    lineItem: [{ position: 30, importance: #HIGH }],
    identification: [{ position: 20 }],
    selectionField: [{ position: 20 }]
  }
  @EndUserText.label: 'Customer'
  CustomerId;

  @UI: {
    lineItem: [{ position: 40, importance: #HIGH }],
    fieldGroup: [{ qualifier: 'Amounts', position: 10 }]
  }
  @EndUserText.label: 'Net Value'
  NetValue;

  @UI: {
    fieldGroup: [{ qualifier: 'Amounts', position: 20 }]
  }
  @EndUserText.label: 'Currency'
  Currency;

  @UI: {
    fieldGroup: [{ qualifier: 'BasicData', position: 40 }]
  }
  @EndUserText.label: 'Sales Organization'
  SalesOrganization;
}

Search Help

@Search.defaultSearchElement: true
@Search.fuzzinessThreshold: 0.8

define view entity ZI_Customer
  as select from kna1
{
  @Search.defaultSearchElement: true
  @Search.ranking: #HIGH
  key kunnr as CustomerId,

  @Search.defaultSearchElement: true
  @Search.ranking: #HIGH
  name1 as CustomerName,

  @Search.defaultSearchElement: true
  @Search.ranking: #MEDIUM
  ort01 as City
}

Anotações de Validação

Value Help

define view entity ZI_SalesOrder
  as select from vbak
{
  key vbeln as SalesOrderId,

  @Consumption.valueHelpDefinition: [{
    entity: {
      name: 'ZI_Customer',
      element: 'CustomerId'
    }
  }]
  kunnr as CustomerId,

  @Consumption.valueHelpDefinition: [{
    entity: {
      name: 'ZI_Currency',
      element: 'CurrencyCode'
    }
  }]
  waers as Currency
}

Filtros de Seleção

@Consumption.filter.mandatory: true
@Consumption.filter.selectionType: #SINGLE
@Consumption.filter.defaultValue: 'DE'

define view entity ZI_Customer
  as select from kna1
{
  key kunnr as CustomerId,
      name1 as CustomerName,
      land1 as Country
}

Exercícios Práticos

Exercício 1: Anotações Básicas

Adicione anotações semânticas completas a uma view de produtos: - Quantidade com unidade - Peso com unidade - Textos descritivos

Exercício 2: Metadata Extension

Crie uma Metadata Extension para uma view de pedidos com: - Header Info - Facets (abas) - LineItem - FieldGroups

Exercício 3: Analytics

Configure uma view para analytics com dimensões e medidas.


Próximos Passos

Na próxima página, aprenderemos sobre Funções e Expressões em CDS, incluindo cálculos, agregações e lógica condicional.