quarta-feira, 23 de dezembro de 2015

Problemas com Update em Custom Settings, no Salesforce.com

Estava trabalhando recentemente em uma demanda, em que eu deveria alterar, via código Apex, o valor de alguns campos de uma Custom Settings. Como já havia feito a operação de consulta de dados de uma Custom Settings com certa facilidade anteriormente, imaginei ser bem tranquila também a atualização. E realmente é! A questão é que tive alguns problemas para realizar essa operação de Update.

Caso tenha chegado até aqui, sem muito conhecimento do que são as Custom Settings, acesse o link abaixo para maiores informações:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_custom_settings.htm

Inicialmente, antes de resolver o problema, precisamos de ter ciência da hierarquia das Custom Settings:
- Geral de toda Org;
- Específica de um Perfil de Usuário;
- Específica de um Usuário;

Bem, conhecendo a hierarquia, realizei alguns teste e verifiquei as formas de buscar os dados das Custom Settings:

MinhaCustomSetting__c settings = MinhaCustomSetting__c.getInstance();
Dessa forma eu buscava o valor padrão para o meu usuário, sempre respeitando a hierarquia. Isto é, se houvesse um valor para meu usuário, este seria retornado. Caso não, retornaria do perfil do meu usuário. Caso não, retornaria o valor geral da Org.


MinhaCustomSetting__c settings = MinhaCustomSetting__c.getInstance('IdDoUsuario');
Dessa forma eu recebia o valor padrão de Custom Setting para o usuário indicado, sempre respeitando a hierarquia.

MinhaCustomSetting__c settings = MinhaCustomSetting__c.getInstance('IdDoPerfil');
Busca os valores padrões para o perfil, se existir, caso não, retornará os valores padrões da Org;

MinhaCustomSetting__c settings = MinhaCustomSetting__c.getOrgDefaults();
Busca os valores padrões da Org, independente de usuário ou perfil;

MinhaCustomSetting__c settings = MinhaCustomSetting__c.getValues('IdDoUsuario');
Busca os valores do usuário como um todo. A diferença para o getInstance('IdDoUsuario') é que se houver (no getInstance) 2 campos, 1 preenchido e o outro não, será feita uma busca, para cima na hierarquia até encontrar um valor para a variável não preenchida. Já para o getValues('IdDoUsuario') irá retornar os valores do usuário, independente do preenchimento;

MinhaCustomSetting__c settings = MinhaCustomSetting__c.getValues('IdDoPerfil');
Busca os valores do por perfil, com a mesma lógica do getValues('IdDoUsuario');

Com essas informações, comecei a escrever o código para buscar os dados relacionados ao meu usuário, na Custom Settings:


           MinhaCustomSetting__c settings = MinhaCustomSetting__c.getInstance();  
           settings.Campo__c = 'Novo valor';  
           update settings;  

Porém, ao executar esse código, percebi que o valor do campo "Campo__c" não era atualizado. Após realizar diversos testes, percebi que ao fazer acessar os dados com o getInstance() sem parâmetro, o objeto settings, instancia o MinhaCustomSetting__c com o campo ID nulo. E por esse motivo o Update não funcionava. Afinal, é impossível atualizar algo, sem seu respectivo ID. 
Diante dessa situação, resolvi realizar outros testes e ficou claro que somente seria instanciado o objeto com o ID, quando houvesse a referência hierárquica criada. Por exemplo: 

- Geral de toda Org: Referenciado;
- Específica de um Perfil de Usuário: Referenciado;

- Específica de um Usuário: Não referenciado;

Com o cenário acima, qual dos abaixo, retornaria o ID?


 MinhaCustomSetting__c setting1 = MinhaCustomSetting__c.getInstance();  
 System.debug('setting1: ' + setting1.id);  
 //Não retorna ID pois pega os valores pela hierarquia  
   
 MinhaCustomSetting__c setting2 = MinhaCustomSetting__c.getInstance(UserInfo.getUserId());  
 System.debug('setting2: ' + setting2.id);  
 //Não retorna ID pois não criei uma referencia direta por usuário  
   
 MinhaCustomSetting__c setting3 = MinhaCustomSetting__c.getInstance(UserInfo.getProfileId());  
 System.debug('setting3: ' + setting3.id);  
 //Retorna o ID pois criei uma referência para o perfil  
   
 MinhaCustomSetting__c setting4 = MinhaCustomSetting__c.getOrgDefaults();  
 System.debug('setting4: ' + setting4.id);  
 //Retorna o ID, pois há uma referência para toda ORG  
   
 MinhaCustomSetting__c setting5 = MinhaCustomSetting__c.getValues(UserInfo.getUserId());  
 System.debug('setting5: ' + setting5.id);  
 //Exceção é levantada, pois não há referência para o usuário e o settings5 é null;  
   
 MinhaCustomSetting__c setting6 = MinhaCustomSetting__c.getValues(UserInfo.getProfileId());  
 System.debug('setting6: ' + setting6.id);  
 //Retorna o ID, pois criei uma referência por perfil  


Isto é, quando há uma referência completa, o ID é retornado e é possível realizar o Update. No meu exemplo inicial, alterei a utilização do getInstance() para getOrgDefaults(), pois me atenderia melhor.
Para finalizar, é importante ressaltar que são coisas diferentes o fato de retornar o ID e o procedimento de retornar os valores hierarquicamente. 

Caso ainda tenha dúvidas, é só postar nos comentários que tentarei responder.

Nenhum comentário: