RAP na prática: criando uma app transacional do zero com Managed Scenario
Por que RAP?
Se você ainda cria telas SAP via SE80 com MVC clássico ou dynpros, este artigo é pra você. O RAP (RESTful Application Programming Model) é o modelo oficial da SAP para desenvolvimento de aplicações modernas no S/4HANA Cloud — e no on-premise a partir do 2022.
A premissa é simples: você modela seus dados via CDS Views, declara o comportamento via Behavior Definition, e o framework cuida do resto — draft handling, locking, etag, OData exposure.
O que vamos construir
Uma aplicação de gerenciamento de ordens de serviço com as operações:
Create, Update, Delete
Validação de campo obrigatório
Action customizada:
AprovarExposição via OData V4 + Fiori Elements List Report / Object Page
Passo 1 — CDS View base
@AbapCatalog.sqlViewName: 'ZI_ORDEM_SERV'
@AccessControl.authorizationCheck: #CHECK
define view entity ZI_OrdemServico
as select from zordem_servico
{
key ordem_id as OrdemId,
descricao as Descricao,
status as Status,
case situacao
when 'AB' then 'Em Aberto'
when 'FI' then 'Finalizado'
when 'CA' then 'Cancelado'
else ''
end as LabelSituacao,
data_abertura as DataAbertura,
responsavel as Responsavel
}Passo 2 — Behavior Definition (Managed)
managed implementation in class zbp_i_ordemservico unique;
define behavior for ZI_OrdemServico alias OrdemServico
persistent table zordem_servico
lock master
{
create; update; delete;
field ( readonly ) OrdemId;
field ( mandatory ) Descricao, Responsavel;
action Aprovar result [1] $self;
validation ValidarStatus on save { field Status; }
draft determine action Prepare;
draft action Edit;
draft action Activate;
draft action Discard;
draft action Resume;
}Passo 3 — Behavior Implementation
O método aprovar é simples: muda o Status para APROVADO e retorna a instância atualizada. Ele e a validação ValidarStatus (declarada no Passo 2) vivem na local handler class, que herda de cl_abap_behavior_handler:
CLASS lhc_ordemservico DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS ValidarStatus FOR VALIDATE ON SAVE
IMPORTING keys FOR OrdemServico~ValidarStatus.
METHODS Aprovar FOR MODIFY
IMPORTING keys FOR ACTION OrdemServico~Aprovar RESULT result.
ENDCLASS.
CLASS lhc_ordemservico IMPLEMENTATION.
METHOD ValidarStatus.
READ ENTITIES OF zi_ordemservico IN LOCAL MODE
ENTITY OrdemServico
FIELDS ( Status )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_ordens).
LOOP AT lt_ordens INTO DATA(ls_ordem).
IF ls_ordem-Status IS INITIAL. " ajuste a regra ao seu domínio
APPEND VALUE #( %tky = ls_ordem-%tky ) TO failed-ordemservico.
APPEND VALUE #(
%tky = ls_ordem-%tky
%msg = new_message_with_text(
severity = if_abap_behv_message=>severity-error
text = 'Status é obrigatório' )
%element-Status = if_abap_behv=>mk-on
) TO reported-ordemservico.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD aprovar.
READ ENTITIES OF zi_ordemservico IN LOCAL MODE
ENTITY OrdemServico
FIELDS ( Status )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_ordens).
MODIFY ENTITIES OF zi_ordemservico IN LOCAL MODE
ENTITY OrdemServico
UPDATE FIELDS ( Status )
WITH VALUE #( FOR ls_ordem IN lt_ordens
( %tky = ls_ordem-%tky
Status = 'APROVADO' ) ).
READ ENTITIES OF zi_ordemservico IN LOCAL MODE
ENTITY OrdemServico ALL FIELDS
WITH CORRESPONDING #( keys )
RESULT DATA(lt_result).
result = VALUE #( FOR ls IN lt_result
( %tky = ls-%tky
%param = ls ) ).
ENDMETHOD.
ENDCLASS.Passo 4 — Service Definition e Binding
@EndUserText.label: 'Ordens de Serviço'
define service ZUI_ORDEMSERVICO {
expose ZI_OrdemServico as OrdemServico;
}Publique como OData V4 - UI no Service Binding, ative e acesse direto pelo Fiori Launchpad.
Passo 5 — Anotações de UI (List Report / Object Page)
Sem annotations @UI, o Fiori Elements abre vazio — sem colunas nem layout. Crie uma Metadata Extension para dar forma ao List Report e ao Object Page, mantendo a UI separada da view (Clean Core):
@Metadata.layer: #CUSTOMER
@UI.headerInfo: {
typeName: 'Ordem de Serviço',
typeNamePlural: 'Ordens de Serviço',
title: { type: #STANDARD, value: 'OrdemId' },
description: { type: #STANDARD, value: 'Descricao' }
}
annotate entity ZI_OrdemServico with
{
@UI.facet: [
{ id: 'Geral', purpose: #STANDARD, type: #IDENTIFICATION_REFERENCE,
label: 'Dados Gerais', position: 10 }
]
@UI: { lineItem: [{ position: 10 }], identification: [{ position: 10 }],
selectionField: [{ position: 10 }] }
OrdemId;
@UI: { lineItem: [{ position: 20 }], identification: [{ position: 20 }] }
Descricao;
@UI: { lineItem: [{ position: 30 }], identification: [{ position: 30 }] }
LabelSituacao;
@UI: { lineItem: [{ position: 40 }], identification: [{ position: 40 }] }
DataAbertura;
@UI: { lineItem: [{ position: 50 }], identification: [{ position: 50 }] }
Responsavel;
}Pré-requisito: adicione @Metadata.allowExtensions: true no topo da CDS view do Passo 1 para que ela aceite a extensão acima.
Resultado
Com poucos passos de código declarativo, você tem uma aplicação completa com draft, lock, validação e action customizada — pronta para publicar no Fiori Launchpad sem uma única tela ABAP clássica.
Comentários 0
Ainda sem comentários
Seja o primeiro a comentar este artigo.
Entre na conversa
Faça login para deixar seu comentário neste artigo.