sexta-feira, 6 de maio de 2016

Apex: Acessando ID de um Tipo de Registro, pelo nome, sem query SOQL

É comum ao desenvolver uma classe ou trigger Apex, no Salesforce, precisarmos de pegar o ID de um Tipo de Registro, para inserirmos um novo registro daquele tipo ou mesmo para fazermos uma consulta de registros daquele tipo. 
Bem, há uma forma bem simples de buscar um determinado Tipo de Registro, pelo nome, sem a necessidade de uma consulta SOQL. Veja:


 Schema.Sobjecttype.Account.getRecordTypeInfosByName().get('Pessoa Física').getRecordTypeId();  



Observe que basta colocar o nome do Objeto (Account, nesse exemplo) e no get o nome do tipo de registro (Pessoa Física).


 Id idRtPF = Schema.Sobjecttype.Account.getRecordTypeInfosByName().get('Pessoa Física').getRecordTypeId();  
 Account conta = new Account(Name='Joao Silva', RecordTypeId = idRtPF);  
 insert conta;  


Ao usar essa instrução, ao invés de fazer uma consulta ao objeto RecordType, você se distanciará dos limites de governança (governor limits) e deixará seu código mais elegante.


ATUALIZAÇÃO IMPORTANTE:

Na release Summer ’18 a Salesforce adicionou o método Schema.DescribeSObjectResult.getRecordTypeInfosByDeveloperName(). Com esse, é possível pegar o id do Tipo de Registro pelo Developer Name. Isso é interessante para evitar problemas com Orgs multi idioma ou alterações do Label do tipo de registro. Veja o exemplo anterior com o novo método:


 Id idRtPF = Schema.SObjectType.Account.getRecordTypeInfosByDeveloperName().get('PessoaFisica').getRecordTypeId();
 Account conta = new Account(Name='Joao Silva', RecordTypeId = idRtPF);  
 insert conta;  



* Precisa de um suporte ou consultoria com a plataforma Salesforce? Entre em contato conosco - CbCloud: http://www.cbcloud.com.br/ - Somos parceiros Gold Salesforce.



quinta-feira, 5 de maio de 2016

Dica rápida Apex: Como acessar a URL da instancia da sua Org - SFDC

Essa é uma dica rápida, para programador Salesforce Apex. Para se ter acesso a URL básica da sua Org Salesforce, basta usar o seguinte comando em seu código:


 String url = System.Url.getSalesforceBaseURL().toExternalForm();  



Ao usar o , teremos o seguinte retorno (de acordo com o servidor que está sua instância):


 https://na17.salesforce.com (Produção)  
 https://cs20.salesforce.com (Sandbox)  


E usar da forma que precisar. Por exemplo:


 String url = System.Url.getSalesforceBaseURL().toExternalForm();  
 PageReference pr = new PageReference(url);  




quinta-feira, 28 de abril de 2016

Simulando códigos APEX para testes com Test.isRunningTest() - SFDC

Em algumas situações (talvez até raras), temos dificuldade ou até mesmo impossibilidade de gerar uma massa de dados que nos permita cobrir (com testes unitários) o nosso código Apex, no Salesforce. 

Em casos como esse, seria ideal fazermos um código "fake" apenas para nossa classe de testes unitários e o código real para nossa aplicação. Para essas situações, usamos o método estático isRunningTest, da classe Test. Ele retorna true, se estiver sendo executado apartir de uma classe de testes e false, se for apartir de uma aplicação normal. Com o isRunningTest, portanto, é possível verificar, em meio à nossa lógica de negócio, se vamos usar um código real ou apenas para testes.

Um exemplo clássico é quando precisamos acessar o PriceBook padrão (StandardPriceBook). Como não conseguimos criá-lo em uma classe de testes, para ser usado na classe de regra de negócio, usaremos uma combinação do isRunningTest com getStandardPricebookId, da classe Test (que já conhecemos melhor através do post Criando registros do catálogo de preço (PriceBookEntry) padrão em classes de teste Apex). Veja a seguir como ficou meu método em uma classe de regra de negócio:


 id idPriceBook = null;  
 if (Test.isRunningTest())  
      idPriceBook = Test.getStandardPricebookId();  
 else {  
   PriceBook pb = [SELECT id FROM PriceBook2 WHERE IsActive = true AND IsStandard = true];  
   idPriceBook = pb.id;  
 }  

Perceba que quando esse código for chamado por uma classe de testes, irá executar o IF, porém, se for chamado por uma execução comum, irá executar o ELSE. E dessa forma conseguirei cobrir completamente a minha classe de negócio.

E esse mesmo código, de forma mais resumida:


 id idPriceBook = Test.isRunningTest() ? Test.getStandardPricebookId() : [SELECT id FROM PriceBook2 WHERE IsActive = true AND IsStandard = true][0].id;  


Por hoje é só!



sábado, 23 de abril de 2016

Lendo parâmetros de uma URL no Salesforce

Esse mais um post rápido e simples para exemplificar como ler os dados passados pela URL, em páginas Visualforce ou classes controller Apex. Para contextualizar estamos falando da QueryString, que são aqueles parâmetros que passamos em uma URL:

 https://c.cs20.visual.force.com/apex/CotacaoAceite?Id=01pm0000000Bf0q&Valor=3&Outros=Teste  

Nessa URL acima, o que seriam os parâmetros?


Parâmetro Valor
ID 01pm0000000Bf0q
Valor 3
Outros Teste

*O símbolo & é entendido com um separador entre os parâmetros.

Bem, agora vamos ao que interessa. Como ler os valores em uma página Visualforce ou em uma classe controller Apex do SFDC?

Visualforce:


 {!$CurrentPage.parameters.ID}  
 <br/>  
 {!$CurrentPage.parameters.Valor}  
 <br/>  
 {!$CurrentPage.parameters.Outros}  
 <br/>  


Apex:


 Id idItem = ApexPages.CurrentPage().GetParameters().get('id');  
 String valor = ApexPages.CurrentPage().GetParameters().get('Valor');  
 String outros = ApexPages.CurrentPage().GetParameters().get('Outros');  


Bem, é isso aí!




quarta-feira, 20 de abril de 2016

GUID no Salesforce

Hoje irei compartilhar uma pequena função Apex para gerar um código GUID no Salesforce. GUID significa Globally unique identifier. Em português Indentificador global único. Isto é, uma código único que é gerado para identificar alguma coisa. Normalmente é usado para identificar registros em sistemas diferentes, em processos de integração. Bem, o que vamos gerar a seguir ficará assim:


 4b033118-86a6-8941-c6e2-ad1015509c6c  

O SFDC, por padrão, diferente de outras plataformas de desenvolvimento, não possui uma classe padrão para gerar os GUID. Após algumas pesquisas encontrei em alguns fóruns um código simples e interessante, que compartilho a seguir:


 global class Guid{   
   global static String generate(){   
     Blob b = Crypto.GenerateAESKey(128);  
     String h = EncodingUtil.ConvertTohex(b);  
     String guid = h.SubString(0,8)+ '-' + h.SubString(8,12) + '-' + h.SubString(12,16) + '-' + h.SubString(16,20) + '-' + h.substring(20);  
     return guid;  
   }  
 }  


Li também que esse código não seria tão perfeito, pois poderia gerar GUID repetidos. Dessa forma, fiz a classe de teste a seguir e não constatei nenhum código repetido:


 @isTest  
 private class GuidTest{  
   static testMethod void test(){  
     boolean erro = false;  
     Set<String> lista = new Set<String>();  
     for (integer i = 0; i < 100000; i++){  
       String uid = Guid.generate();  
       if (lista.contains(uid)){  
         System.debug(i);  
         System.debug(lista.Size());  
         System.debug('GUID: ' + uid);  
         erro = true;  
         break;  
       }  
       else  
         lista.add(uid);  
     }  
     System.assert(!erro, 'A classe GUID gerou um valor duplicado!');  
   }    
 }  

Veja que gerei cem mil UIDs e nenhum duplicou. Me pareceu bem confiável! Porém, se alguém encontrar alguma falha, comente aqui no post. 

Por hoje é só!




terça-feira, 19 de abril de 2016

Habilitando envio de e-mails na Org Salesforce

Uma situação corriqueira que nos deparamos ao inciar os trabalhos em uma nova Org Salesforce, é que alguns e-mails que programamos ou configuramos o envio, acabam não sendo enviados. 

Acesse a opção de Configuração da sua Org e siga o passo-a-passo para habilitar o envio de e-mail:



Menu Administrar / Administração de email / Capacidade de entrega.

Em seguida, marque a opção "Todos os emails" na opção Nível de acesso.




Por fim, basta clicar em Salvar para que sua Org envie emails normalmente! 



quarta-feira, 6 de abril de 2016

Tamanho médio de um registro no Salesforce

Esses dias me deparei com uma situação onde a ORG de um dos nossos clientes estava quase atingindo o limite (em MBs) do espaço disponível na ORG. Ao acessar a opção de "Uso do armazenamento" (Menu: Configurações/Gerenciamento de dados/Uso do armazenamento) verifiquei em um dos objetos que aproximadamente 50 mil registros consumiam 100 mb de espaço. Ao verificar outros objetos, tanto maiores como menores, a proporcionalidade era a mesma. 

Resolvi realizar algumas pesquisas e encontrei diversos artigos e pessoas comentando exatamente o mesmo. Para cada registro (na grande maioria dos casos) no Salesforce, consome-se 2KB de espaço na sua ORG.

É necessário olhar o lado positivo de tudo, certo? Então, a parte positiva é que fica fácil calcular quanto de espaço será necessário, em cada novo projeto, expansão ou para política de expurgo. 

O ruim é que se consome muito espaço para registros pequenos. Em caso de objetos apenas para relacionamento (N-para-N), por exemplo, é um espaço muito grande por registro.

Vi uma ideia cobrando uma solução para o problema. Mas ainda está pouco votada. Quem quiser apoiar a iniciativa: Charge fairly for storing small objects. Eu apoiei!