quinta-feira, 4 de fevereiro de 2010

Me mandaram: permitir a edição de um campo JOIN na tela

Essa uma das solicitações mais comuns que vejo nos projetos Siebel. Em algum momento da sua vida de consultor, um cliente vai pedir para você tornar editável aquele campinho na tela do Contato (campo este que você traz via JOIN de uma outra tabela do Siebel).

No momento que isso acontecer, provavelmente você vai pensar em dizer: "NOSSA! VC É UM GÊNIO MESMO, NÃO É?! PORQUE EU NÃO TIVE ESSA IDÉIA BRILHANTE?! AH SIM, LEMBREI... É PORQUE É IMPOSSÍVEL!"

Tapa na cara do cliente sabichão

Pois é... É difícil ser consultor... Mas antes de despejar tudo que você pensa, ou dizer ao cliente que não é possível fazer, irei dar a vocês não só uma, nem duas, mas TRÊS opções para solucionar este problema. Antes disso, segue a nossa sessão tecnês:

Dois tipos de JOIN
  1. Joins comuns: Aquelas que agente configura dentro de um BC, apontando para uma tabela e setando o join specification. A partir desse tipo de Join, é possível criar Fields, para trazer informações de outras tabelas para dentro de um determinado BC. Extremamente útil, mas possúi limitações:
    • Uma Join (ao contrário das JOINS de queries SQL) somente podem ser utilizadas quando o relacionamento entre a tabela do BC e a tabela relacionada é 1:1.
    • Um Field criado com base numa Join comum é Read-Only (somente leitura).
  2. Joins implicitas: Estas são joins especiais no Siebel, e possuem algumas propriedades bastante interessantes:
    • Estas joins (ao contrário das normais) não estão definidas dentro dos BCs. Estas joins existem devido ao relacionamento das tabelas do Siebel. Vamos tomar como exemplo o BC Contact do Siebel: Apesar de a maioria dos Fields deste BC serem baseados na tabela S_CONTACT, a table deste BC é na realidade a S_PARTY. Como a tabela S_CONTACT é uma filha direta (1:1) da tabela S_PARTY, existe uma join implicita entre estas tabelas.
    • A beleza das joins implicitas não para por ai: Os Fields que são baseados em joins implicitas são editáveis e o Siebel trata isso tudo dentro do seu core, editando cada tabela filha e criando registros novos, caso necessário.



Parte que interessa

Obviamente iremos tratar aqui dos casos de joins comuns. Portanto, para você que sobreviveu ao sermão técnico, seguem as três soluções para edição de campos baseados em JOIN:

SOLUÇÃO #1: Não implementar lógica alguma.

Esta parece ser uma opção idiota, mas trata-se de uma boa solução. O Siebel permite uma série de soluções para o mesmo problema e o melhor que temos a fazer é escolher a solução mais limpa, que facilita manutenção e não cria impactos de performance.
O que se pode fazer é configurar um drilldown que direciona o usuário para a tela da entidade que deve ser alterada. Após alterada a informação, o usuário pode voltar para a tela anterior utilizando o thread applet ou mesmo o back do browser.
Um BA habilidoso consegue vender esta idéia facilmente para os clientes, entretanto, há sempre os clientes filhos da puta exigentes. Para tais, seguem as próximas soluções.


SOLUÇÃO #2: Criar script para alterar em background

Isto é o que eu chamo de SOLUÇÃO DE MERDA! Pense bem na idiotice desta solução: Ao invés de ter um único campo para editar, você deverá criar um novo campo no BC principal. Este campo deverá ser mapeado na tela (como se fosse o campo join - mas não é). Após isso, você deverá criar um script no evento de SetFieldValue para editar o campo do BC destino, mantendo o mesmo valor em ambos os BCs. Até aqui OK (porco, mas não é tão mal...). Mas aqui vão os complicometros:
E se eu alterar o valor diretamente no BC destino? Solução: Cria a mesma lógica no BC destino para fazer a edição inversa e manter os campos iguais.
E se der erro no WriteRecord? Solução: Repensar a lógica e colocar a chamada para setar o campo do BC destino no WriteRecord.
E se eu carregar dados via EIM? PQP que merda - EIM é nivel banco!
E se eu for apenas um consultor mediano?
E se eu largar esse projeto logo?
E se estiver chovendo lá fora? AHHH MEU DEUS ONDE EU FUI ME METER?!
CALMA! Leia a solução 3...


SOLUÇÃO #3: Magic Solution - MVF 1:1

Humm Magic Solution! IT'S HOT BABY!
Mas pera um pouco ai!
MVF 1:1, é isso mesmo?
Multivalue field um para um!?
Campo multivalorado com relacionamento um para um com o BC
principal?
SIM, porra! Vamo parar com perguntas retóricas... É isso mesmo!
Acabei criando esta solução por acidente, quando estava trabalhando com MVLs e MVFs em um BC. Eu queria criar alguns campos calculados malucos e para realizar alguns testes, coloquei o campo MVF na applet (apenas para verificar se o seu valor estava de acordo com o esperado). Este campo era baseado num MVL (Multivalue link) que eu havia configurado propositalmente para ser 1:1 com o BC Principal. Ao aparecer na tela... PASMEM!!! O campo estava editável !!! Eu obviamente fiz um teste de atualização e ao mudar o valor do campo... PASMEM!!! Não houve erro! Fiz a query na tabela destino e... PASMEM!!! o campo estava realmente alterado. UMA BELEZA!. Segue o passo a passo detalhado para implementação desta solução:

Campo Join MVF editável:

Passo 1: Criar um Link entre o BC Principal e o BC Destino. Deve haver um ou mais campos que garantam o relacionamento 1:1. Como já existe uma join no BC, é muito provável que no BC Principal exista um campo "XPTO Id" que serve de Foreign Key para o BC Destino.

Passo 2: Criar MVL (Multivalue Link) no BC principal, utilizando o Link do passo 1. Não esqueça de setar o Source Field, de acordo com o campo usado no Link criado no passo 1.

Passo 3: Criar um MVF (Multivalue Field) Baseado no MVL do passo 2.

Passo 4: Mapear o MVField no Applet.

Passo 5: Compilar tudo e correr para o abraço.


Exemplo:
Permitir a edição de campos do contato que está associado a um membro (diretamente na tela de membros)

1. Link criado entre o BC LOY Member e o Contact.


2. MVL criado no BC LOY Member, com base no link do item 1. Observe que foi setado o "Primary ID Field" e o flag "Use Primary Join". Isto é importantíssimo para que não haja problemas de performance. Utilize sempre que o relacionamento entre as entidades permitir.


3. MVF Criado


4. Resultado na tela