4 maneiras de como tornar um flexfield somente leitura no Oracle EBS
Eduardo Schurtz 20 de outubro de 2017 6 comentários ebs
Como criar um flexfield somente leitura? Essa é uma dúvida comum entre os profissionais Oracle E-Business Suite.
Com esse tipo de flexfield conseguimos impedir que ele sofra alterações, geralmente por questões de segurança.
Em um primeiro momento, pode parecer algo simples e rápido de se fazer, mas quando essa necessidade chega de verdade, descobrimos que não é bem assim.
Como um aluno do meu curso me procurou essa semana com essa dúvida e sei que muita gente pode precisar um dia, resolvi criar esse artigo com algumas maneiras de atingir esse objetivo.
Infelizmente não tem uma maneira "ideal", vai depender muito das suas necessidades.
Os flexfields do Oracle EBS podem ser utilizados em telas Forms e telas OAF (WEB), então as soluções podem variar.
Se você quer conhecer alguns desses procedimentos, acompanhe esse artigo para saber mais como criar um flexfield somente leitura utilizando:
Conjunto de valores do tipo SPECIAL
Oracle OAF Personalization
Método #1. Conjunto de valores do tipo SPECIAL
Essa talvez seja uma das opções mais antigas e disseminadas.
Nela é necessário criar um novo conjunto de valores do tipo SPECIAL, sendo assim, caso o seu flexfield já possua um conjunto de valores associado, essa solução não poderá ser utilizada.
Um outro detalhe também é que ela só funciona para forms.
#1. Criar um conjunto de valores do tipo SPECIAL:
? Caminho: Application Developer » Application » Validation » Set
#2. Na validação (botão "Edit Information"), configurar da seguinte maneira:
Event: Edit
Function: FND SQL "BEGIN NULL; END;"
Event: Validate
#3. Associar esse novo conjunto de valores ao seu flexfield:
? Caminho: Application Developer » Flexfield » Descriptive » Segments
#4. Pronto, agora você definiu o seu flexfield somente leitura, ou seja, é READ ONLY e não permite alterações:
Método #2. Regras de segurança
Uma outra opção é a criação de regras de segurança, a viabilidade dessa alternativa vai depender muito do conteúdo que o flexfield pode receber e de suas características.
Em um conjunto de valores podemos definir regras de segurança para impedir que determinados valores sejam informados no flexfield.
Com essa "trava" às vezes conseguimos atingir o objetivo de não permitir que um flexfield seja alterado, já que a regra de segurança não vai mostrar os valores válidos que foram definidos no conjunto de valores.
Objetivo: Impedir que um flexfield que armazena o número de uma ordem de venda seja alterado para uma determinada responsabilidade.
O setup ficaria assim:
#1. Criar o value set que listará as ordens de venda do OM:
Informar os dados da validação:
#2. Definir as regras de segurança para o conjunto de valores:
? Caminho: System Administrator » Security » Responsibility » ValueSet » Define
#2.1 Pesquisar pelo conjunto de valores criado acima:
#2.2 Configurar as regras de segurança conforme abaixo:
1. Name: Nome para a regra
2. Description: Descrição para a regra
3. Message: Mensagem para a regra
4. Type Include: É necessário que tenha uma linha de "Include", mesmo que fique em branco
5. Type Exclude: Aqui é o range de valores que queremos eliminar. Como o value set é apenas numérico, informei os limites mínimo e máximo para abranger todas as possibilidades
6. Botão Assign: Aqui informamos para quais responsabilidades as regras valerão, mas esse passo não é obrigatório:
#3. Associar o conjunto de valores ao flexfield:
Clicar no botão "Open" para abrir a tela abaixo e efetuar as configurações finais:
OBS: O checkbox "Security Enabled" precisa estar marcado
E está feito, mais uma possibilidade de flexfield somente leitura.
Ao abrir o flexfield do form de Condições de Pagamento, o flexfield está desabilitado para alterações:
Como nesse meu exemplo o flexfield só armazena números, fica mais fácil controlar o range de possibilidades, então esse seria um bom candidato para o uso de regras de segurança.
Lembrando que só é possível definir regras de segurança para conjuntos de valores dos tipos Independent, Dependent ou Table.
Para telas OAF as regras até funcionam, ou seja, nenhum valor estará disponível para que seja inserido no flexfield, mas até onde eu vi, ainda é possível limpar o conteúdo do campo e salvar.
E o próprio EBS mostra uma mensagem de alerta quando configuramos um flexfield assim, dizendo que não é compatível com telas OAF.
Então para o OAF é mais fácil alcançar esse objetivo com personalização, que explicarei logo abaixo.
Com personalização conseguimos atingir esse objetivo com facilidade no OAF, mas no Forms não é tão simples.
Abaixo falo sobre ambos os casos.
Método #3. OAF (OA Framework)
Nas telas OAF, de qualquer forma, precisamos do Personalization para habilitar os flexfields, então para deixar um flexfield somente leitura, só precisamos de uma personalização.
Utilizarei como exemplo o cadastro de fornecedores.
#1. Personalizar a tela de fornecedores:
? Caminho: Payables » Suppliers » Entry
OBS: Para facilitar, vou utilizar o mesmo flexfield já criado acima.
Escolha um fornecedor e clique em "Update":
#2. Na tela que irá abrir com o fornecedor selecionado, no canto superior direito, clique em "Personalize Page":
#3. Na área "Personalization Structure", clique em "Complete View", pesquise por "flex" para encontrar o flexfield e clique no lápis da linha encontrada (coluna "Personalize"):
#4. Nesse exemplo vou colocar essa personalização no nível de responsabilidade:
Em "Segment List", temos que informar os flexfields (segmentos) a serem mostrados, no formato:
CONTEXT|SEGMENT1|SEGMENT2|SEGMENT3…|SEGMENTN
O primeiro elemento é o contexto do flexfield, depois cada um dos flexfields que serão mostrados.
O separador é o "|" (pipe).
Para tornar um flexfield somente leitura, é só concatenar com a string ($RO$):
No exemplo ficou assim:
Global Data Elements|Orders($RO$)
Se existissem mais segmentos, era só ir concatenando um a um.
O resultado é esse abaixo, perceba que aparece apenas o texto do flexfield, sem um campo para poder editá-lo:
Método #4. Form Personalization
Infelizmente não conseguimos alterar propriedades de flexfields via form Personalization, mas como ele é muito poderoso, existe uma alternativa que dependendo do cenário, pode ser bem útil.
A ideia é validar se o conteúdo do flexfield foi alterado.
Farei isso primeiramente armazenando o conteúdo do flexfield logo que entrar no registro, depois comparando no momento da validação, se o conteúdo armazenado é diferente do conteúdo atual.
Como exemplo vou utilizar a tela de condições de pagamento.
#1. Na primeira regra criamos uma variável local na trigger WHEN-NEW-FORM-INSTANCE:
#2. Na segunda regra armazenamos o conteúdo do flexfield logo que o registro recebe o cursor, utilizando a trigger WHEN-NEW-RECORD-INSTANCE:
Utilizei na condição a variável de sistema :SYSTEM.RECORD_STATUS, para garantir que o registro é válido e foi retornado do banco.
#3. Na terceira e última regra validamos se o conteúdo do flexfield foi alterado, utilizando a trigger WHEN-VALIDATE-RECORD:
Se os valores estiverem diferentes, acontece o seguinte:
#1. O flexfield recebe novamente o valor inicial
#2. Uma mensagem é mostrada para o usuário:
#3. Um comando RAISE é efetuado para abortar a operação e impedir que o processo continue
E esse foi o método utilizando o Form Personalization para tornar um flexfield somente leitura.
Essa lógica que utilizei pode ser adaptada para várias outras situações, o céu é o limite quando se trata de personalizações. ? (Veja alguns outros exemplos nesse artigo sobre EBS Personalization).
⚠️ Importante: Toda vez que for criar personalizações no Forms para manipular flexfields, teste muito bem antes, com vários cenários e situações. Flexfields no Forms não se dão muito bem com o Form Personalization.
Método #5. CUSTOM.PLL (Dica bônus)
Eram apenas 4 maneiras, mas acabei adicionando essa como bônus. ?
Essa opção é apenas para Forms e vai exigir conhecimento técnico, já que será necessário customizar a biblioteca CUSTOM.PLL.
Uma outra desvantagem dessa alternativa é que ela não permite alterar apenas um flexfield, ou seja, todos ficarão somente leitura.
O código é esse abaixo:
FND_DESCR_FLEX.UPDATE_DEFINITION (
block      => 'MTL_SYSTEM_ITEMS'
, field      => 'DF_MIR'
, enabled    => 'N'
, read_only  => 'Y'
FND_DESCR_FLEX.UPDATE_DEFINITION ( block => 'MTL_SYSTEM_ITEMS' , field => 'DF_MIR' , enabled => 'N' , read_only => 'Y' );
Você informa o nome do bloco no parâmetro "block" e o nome do campo padrão que armazena os flexfields no Forms, o nome pode variar, como "DF". Essas informações você consegue no menu "Examine".
Conclusão sobre as maneiras de como tornar um flexfield somente leitura
Como mencionei no começo do artigo, não existe uma solução única, você vai ter que analisar o seu caso e escolher as alternativas que melhor se adaptam com a necessidade.
Lembre de sempre testar muito antes de colocar em produção, os exemplos acima estão bem simples e foram criados apenas para demonstração.
Se você tiver alguma outra solução, por favor, deixe nos comentários que vai ser legal adicionar mais uma ao artigo.
E se você gostou desse conteúdo e acha que ele pode ser útil para outras pessoas, compartilhe com seus contatos (É só escolher a sua rede social favorita abaixo e clicar).
Artigo anterior Variáveis de Sistema: Tudo o que você precisa saber para começar a usar em forms e personalizações
Próximo artigo O que são flexfields do Oracle EBS
Nossa, completão hein? Muito bom!
Esse ficou mesmo. Valeu Genilto! Abs
Tem uma outra alternativa, usando o SPEL. Você faz uma configuração de permissões, grants, funções, etc… e faz a personalização no nível de site usando o SPEL. Aí depois é só ir criando grants para as responsabilidades, a personalização não mexe mais.
Infelizmente não é algo muito simples de explicar e nem de fazer, mas é possível.
https://uploads.disquscdn.com/images/227f6ae49ae258bbe46c8dd0b62d0ec0c2f6f599cc5874c248fb4f8fa46a4628.jpg
Fui fazer o passo 1 e deu o erro abaixo:
APP-FND-01564: Erro ORACLE 911 em fdxsql
Causa: Ocorreu um erro em fdxsql, porque ORA-00911: caractere inválido.
A instrução SQL que estava sendo executada no momento do erro era: ¿BEGIN e foi executada pelo arquivo &ERRFILE.