• Livia Pimentel
  • NEWBIE
  • 40 Points
  • Member since 2021

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 9
    Questions
  • 7
    Replies
Hello, everyone!

I am trying to implement a test class for a trigger, that calls a http method (which comes from this tutorial: https://cloud.google.com/architecture/calling-protected-cloud-functions) .

In my case, everytime when the custom object 'Proposta__c' is updated, the GCPManageCustomersService method is called. Basically, this class implements the calling of a cloud functions that was set up by following the aforementioned tutorial.

When implementing the ' GCPMockHTTPResponseGenerator' class on my test class 'GCPManageCustomersServiceTest', I always get assertion errors on the following lines:
 
System.assertEquals(1, asyncJobList.size());
        
System.assertEquals(true, mock.methodCalled);

Below, I show you the complete test class:
 
@isTest
public class GCPManageCustomersServiceTest {

    static testmethod void testQueueable() {

        GCPMockHttpResponseGenerator mock = new GCPMockHttpResponseGenerator(); 
        

        Test.setMock(HttpCalloutMock.class, mock);
        
        Test.startTest();
        
        PriceBook2 pb_se_conv = new PriceBook2();
		pb_se_conv.Name = 'SE/CO - CONV';
        pb_se_conv.Pre_o_2023_R_MWh__c = 123.45;
        insert pb_se_conv;
        
        PriceBook2 pb_se_I0 = new PriceBook2();
		pb_se_I0.Name = 'SE/CO - I0';
        insert pb_se_I0;
        
        PriceBook2 pb_se_I100 = new PriceBook2();
		pb_se_I100.Name = 'SE/CO - I100';
        insert pb_se_I100;
        
        PriceBook2 pb_se_I5 = new PriceBook2();
		pb_se_I5.Name = 'SE/CO - I5';
        insert pb_se_I5;
        
        PriceBook2 pb_se_INE = new PriceBook2();
		pb_se_INE.Name = 'SE/CO - INE';
        insert pb_se_INE;
        
        
        PriceBook2 pb_NE_conv = new PriceBook2();
        pb_NE_conv.Name = 'NE/CO - CONV';
        insert pb_NE_conv;
                
        PriceBook2 pb_NE_I0 = new PriceBook2();
        pb_NE_I0.Name = 'NE/CO - I0';
        insert pb_NE_I0;
                
        PriceBook2 pb_NE_I100 = new PriceBook2();
        pb_NE_I100.Name = 'NE/CO - I100';
        insert pb_NE_I100;
                
        PriceBook2 pb_NE_I5 = new PriceBook2();
        pb_NE_I5.Name = 'NE/CO - I5';
        insert pb_NE_I5;
                
        PriceBook2 pb_NE_INE = new PriceBook2();
        pb_NE_INE.Name = 'NE/CO - INE';
        insert pb_NE_INE;
        
        PriceBook2 pb_S_conv = new PriceBook2();
        pb_S_conv.Name = 'S/CO - CONV';
        insert pb_S_conv;
                
        PriceBook2 pb_S_I0 = new PriceBook2();
        pb_S_I0.Name = 'S/CO - I0';
        insert pb_S_I0;
                
        PriceBook2 pb_S_I100 = new PriceBook2();
        pb_S_I100.Name = 'S/CO - I100';
        insert pb_S_I100;
                
        PriceBook2 pb_S_I5 = new PriceBook2();
        pb_S_I5.Name = 'S/CO - I5';
        insert pb_S_I5;
                
        PriceBook2 pb_S_INE = new PriceBook2();
        pb_S_INE.Name = 'S/CO - INE';
        insert pb_S_INE;
        
        PriceBook2 pb_N_conv = new PriceBook2();
        pb_N_conv.Name = 'N/CO - CONV';
        insert pb_N_conv;
                
        PriceBook2 pb_N_I0 = new PriceBook2();
        pb_N_I0.Name = 'N/CO - I0';
        insert pb_N_I0;
                
        PriceBook2 pb_N_I100 = new PriceBook2();
        pb_N_I100.Name = 'N/CO - I100';
        insert pb_N_I100;
                
        PriceBook2 pb_N_I5 = new PriceBook2();
        pb_N_I5.Name = 'N/CO - I5';
        insert pb_N_I5;
                
        PriceBook2 pb_N_INE = new PriceBook2();
        pb_N_INE.Name = 'N/CO - INE';
        insert pb_N_INE;        
        
        
        

        
        Account acc = new Account();
        acc.Name = 'ACC2';
        acc.OwnerId = UserInfo.getUserId();
        
        insert acc;
        
        
        Opportunity opp = new Opportunity();
        opp.Name = 'TEST OPP 27_05_22';
        opp.AccountId = acc.Id;
        opp.CloseDate = date.today();
        opp.StageName = 'Proposta';
        
        insert opp;
        
        RFQ__c rfq = new RFQ__c();
        rfq.Oportunidade__c = opp.Id;
        rfq.Respons_vel__c = UserInfo.getUserId();
        date inicio = date.today();
        rfq.In_cio_Suprimento__c = date.today();
        rfq.Validade_Suprimento__c = inicio.addMonths(15);
        
        rfq.Tipo_de_Energia__c = 'Conv';
        
        rfq.Ponto_de_Entrega__c = 'SE/CO';
        
        insert rfq;
        
        
        RFQ__c rfq_inserted = [SELECT Id, Ponto_de_Entrega__c, Tipo_de_Energia__c FROM RFQ__c WHERE Id=:rfq.Id];
      
        
        Proposta__c proposta_first = [SELECT Name, Id,Pre_o_Ano1_Tabela__c, Cat_logo_de_pre_os__c FROM Proposta__c WHERE RFQ__c=:rfq_inserted.Id];
        
        proposta_first.CNPJ__c = '123456';
        
        update proposta_first;
        
        Test.stopTest();
        
        List<AsyncApexJob> asyncJobList =
            [select id, ApexClass.Name, JobType, Status from AsyncApexJob];
        
        PriceBook2 pb_correspondente = [SELECT Id, Name from PriceBook2 WHERE Id=:proposta_first.Cat_logo_de_pre_os__c];
                  
        System.assertEquals(pb_correspondente.Name, 'SE/CO - CONV' );  
        
        System.assertEquals(proposta_first.Pre_o_Ano1_Tabela__c, 123.45 ); 
        
       
        
        
        System.assertEquals(1, asyncJobList.size());
        
        System.assertEquals(true, mock.methodCalled);
        
        
            
        
    }
}

Finally, the trigger that does the http callout:
 
trigger updatePricesProposal on Proposta__c (after update){
    
    if (Trigger.isUpdate){
     
        
        for (Proposta__c prop : Trigger.new){
            
            List <Proposta__c> prop_list  =  new List <Proposta__c>();
            
            prop_list.add(prop);
           
            String serialisedProp = JSON.serialize(prop_list);
            
            try{
                
                Proposta__c old_prop = Trigger.oldMap.get(prop.Id);
                              
                if(prop.Cat_logo_de_pre_os__c != null && old_prop.Tempo_Botao_Preco__c.format('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'') != prop.Tempo_Botao_Preco__c.format('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'')  ){
                
                GCPManageCustomersService gcpService = new GCPManageCustomersService(serialisedProp, 'update');
                    
                ID jobID = System.enqueueJob(gcpService);               
                
                }
                
                
                
            }catch(Exception e){
                
                           
                
                
            }
                    
            
        }        
        
        
    } 
            

}

I appreciate any help you can provide.

Best regards,
Hello, everyone! 

I was wondering if there is a way of calling a Google Cloud Function's result from Salesforce using apex.

Basically, I want to call a cloud function right after creating an Account. So, the calling of the Cloud Function would be inside a trigger.

Thank you. I appreciate any help you can provide.

Best regards,

Lìvia; 
Hello, I am trying to implement some triggers in my org, but I am having some issues related to the error message shown in this post's title.

The complete error message is the following:

"System.DmlException: Update failed. First exception on row 0 with id a05HZ0000001vCLYAY; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, List has no rows for assignment to SObject: []"

It happens on line 43 of the following test class:
 
@isTest
public with sharing class testclass_closedRfqOpp {
    public testclass_closedRfqOpp(){
        
        
    }
    // test method
    @isTest
    public static void method_closedRfq(){
        
       // initialization
       // 
       list<user> u =[select id from user where alias='lpime'];
        
       Test.startTest(); 
       Account acc = new Account();
       acc.name = 'Conta TesteAAAA 10/03';
       acc.OwnerId = u[0].id;
        
       insert acc;
           
       Opportunity opp = new Opportunity();
       opp.name = 'OportunidadeAAAA Teste 10/03';    
       opp.Tipo_de_Opera_o__c = 'Venda';
       opp.AccountId = acc.Id;
        
       opp.StageName = 'Qualificação';
       
       opp.CloseDate = date.today();
        
       insert opp; 
        
       RFQ__c rfq = new RFQ__c();
       rfq.Oportunidade__c = opp.Id;
       rfq.In_cio_Suprimento__c = date.today();
       rfq.Validade_Suprimento__c  = date.today();
  		
       insert rfq;
        
       rfq.Status_da_RFQ__c = 'Perdida';
           
         
       update rfq; // ERROR
     
        
       Opportunity opp_a = [SELECT Id, StageName FROM Opportunity WHERE Id=:rfq.Oportunidade__c];
       
       
       system.assertEquals('Closed Lost', opp_a.StageName);
        
        
        Test.stopTest();
                
        
    }

}

I have the following "after update" triggers on the RFQ object:

Trigger 1:
 
trigger total_rfq_proposta on RFQ__c (after update) {
  
        if (Trigger.isAfter) {
            
            
        if (Trigger.isUpdate) {
            
       
           RFQHandler.updateRFQ(Trigger.new);
           
            
        }
            
}
        
       
}

Trigger 2:
 
trigger closedRfqOpp on RFQ__c (after update) {
    
        
        for(RFQ__c rfq:trigger.new){
            
            Opportunity opp = [select id, StageName from Opportunity where id=:rfq.Oportunidade__c AND id!= null];
            
            if(opp != null){
                
                if(rfq.Status_da_RFQ__c == 'Perdida'){
              	                
                 opp.StageName = 'Closed Lost';
            	
                 update opp;
                 
            }
                
                
                
            }
            
            
        }
        
  
}

Trigger 3:
 
trigger rfqsCanceledNegociationLostOpp on RFQ__c (after update) {
    
    
     for(RFQ__c rfq:trigger.new){
            
         Opportunity opp = [select id, StageName from Opportunity where id=:rfq.Oportunidade__c AND id!= null];
         
         
         if (opp != null){
             
             if(rfq.Status_da_RFQ__c == 'Fechada'){              
                opp.StageName = 'Closed Won';
                update opp;           
       		  }
         
           if(rfq.Status_da_RFQ__c == 'Em Jogo'){              
                opp.StageName = 'Negociação';
                update opp;           
       		  }
           
            
            
            if(rfq.Status_da_RFQ__c == 'Perdida' | rfq.Status_da_RFQ__c == 'Fechada' ){
                
                 List <RFQ__c> rfqs_opp = new List<RFQ__c>();
              	
                rfqs_opp = [select id, Status_da_RFQ__c from RFQ__c where Oportunidade__c=:rfq.Oportunidade__c AND id!=null];
                 
                for(RFQ__c el_rfq:rfqs_opp){
                    
                    if(el_rfq.id != rfq.id & el_rfq.id!= null){
                        
                        el_rfq.Status_da_RFQ__c = 'Cancelada';
                        update el_rfq;
                        
                    }
                }
                 
            }
             
             
             
         }
         
         	
        }
    

}

I appreciate any help you can provide.

Thank you,

Lívia.
Hello, everyone.

I am developing a trigger which has a complicated logic. To deal with this complexity, I am using 3 different Apex classes inside my trigger in the following way:

TRIGGER: 
 
trigger total_rfq_proposta on RFQ__c (after update) {
  
        if (Trigger.isAfter) {
        if (Trigger.isUpdate) {
            
           //HelloWorld.helloWorld2( Trigger.new );
              
           RFQHandler.updateRFQ(Trigger.new);                   
        }            
}
             
}

RFQHandler CLASS:
 
public class RFQHandler{



public static double assignMonthVolumes(integer indice_ano, integer flag_month , RFQ__c rfq) {} ....


public static double getMonthlyVolumes(integer year, integer indice_ano ,RFQ__c rfq){}...


public static double getYearlyVolumes(integer year, integer indice_ano ,RFQ__c rfq){}...


// This is the "main" function
  
public static void updateRFQ(List <RFQ__c> rfqs){
        
        
        for(RFQ__c rfq : rfqs){
            
            if(rfq!=null){
                
                
           
            
            
     Proposta__c proposal = [SELECT Id, Total_RFQ_MWm__c	from Proposta__c WHERE RFQ__c=:rfq.id];
        
     if(proposal != null){
            
            double total_2022_MWm = 0;
            double total_2023_MWm = 0;
            double total_2024_MWm = 0;
            double total_2025_MWm = 0;
            double total_2026_MWm = 0;
            double total_2027_MWm = 0;
            
            // Lista que guardará todos os anos referentes à RFQ           
            list <integer> years = new list <integer>(); 
            
            Date d1 = rfq.In_cio_Suprimento__c;
            
            
            // ex.: inicio = novembro de 2022 || fim = julho de 2024
            while(d1.year() <= rfq.Validade_Suprimento__c.year()){
                
                years.add(d1.Year());    
                d1 = d1.addYears(1);
                
                
            }
            
            // Dicionário que aponta quais anos correspondem a Ano1/Ano2/Ano3 ... etc
          	map <String, Integer> mapa_anos = new map <String, Integer>(); 
            
            // Mapeando os anos correspondentes à RFQ em questão:
            // years = lista contendo todos os anos (integers)
            for(integer value : years){
                
                integer indice = years.indexof(value);
                
                switch on indice{
                    
                    when(0){
                        
                        mapa_anos.put('Ano1',value);
                        
                    }when(1){
                        
                        mapa_anos.put('Ano2',value);
                        
                    }
                    when(2){
                        
                        mapa_anos.put('Ano3',value);
                        
                    }
                    when(3){
                        
                        mapa_anos.put('Ano4',value);
                        
                    }when(4){
                        
                        mapa_anos.put('Ano5',value);
                        
                    }when(5){
                        
                        mapa_anos.put('Ano6',value);
                        
                    }              
                    
                    
                    
                }
                               
                                   
            }
          								          
     
            integer count = 0;
                
            for(integer ano : mapa_anos.values()){
                                                        
                 // Para cada string "Ano1 / Ano2 / Ano3 ...."
                 // Verifica qual que é o ano correspondente e atribui os volumes de acordo com a posição deles (Ano1/Ano2/Ano3 ...)  
                                       
                    integer indice_ano = mapa_anos.values().indexof(ano); // Índice do ano correspondente
                
                	system.debug(indice_ano);
                
                	system.debug(rfq.Name);
                    
                    switch on ano{
                        
                        when 2022{
                           
                           double valor_anual =  getYearlyVolumes(2022,indice_ano, rfq);                        
                           double valor_mensal = getMonthlyVolumes(2022, indice_ano, rfq);
          					
                            if(valor_anual != 0){
                                
                                proposal.Total_RFQ_MWm__c = valor_anual;                               
                                update proposal;
                                                        
                            }else{
                            
                                proposal.Total_RFQ_MWm__c = valor_mensal;                         
                                update proposal;
                                
                            }
                            
                        }
                        
                        when 2023{
                            
                            
                            
                            
                        }
                        
                        
                        when 2024{
                            
                            
                            
                            
                        }when 2025{
                            
                            
                            
                        }when 2026{
                            
                            
                            
                        }when 2027{
                            
                            
                            
                        }
                        
                        
                        
                    }                  
                   
                                       
                    
                    
                }
          
                                       
                
     
            
            
        }
        
    
            }
            
            
        }
        
        
        
    }
    
    


}

OBS: I am not posting all the classes, otherwise this post would be too extensive.


PROBLEM:

In this scenario, I am having the  following problem when testing my Trigger:

Inside RFQHandler --> void updateRFQ, when calling the functions getYearlyVolumes and getMonthlyVolumes like shown below
 
double valor_anual =  getYearlyVolumes(2022,indice_ano, rfq);                 
double valor_mensal = getMonthlyVolumes(2022, indice_ano, rfq);

The following error messages appear:

System.DmlException: Update failed. First exception on row 0 with id a05HZ0000001mdhYAA; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, total_rfq_proposta: execution of AfterUpdate

caused by: System.NullPointerException: Attempt to de-reference a null object

Class.RFQHandler.getYearlyVolumes: line 958, column 1
Class.RFQHandler.updateRFQ: line 1196, column 1
Trigger.total_rfq_proposta: line 8, column 1: []


I am having trouble figuring out why this is happening.

Any help would be deeply appreciated.

Thank you,

Lívia.
Hi, everyone!

In our organization, we are interested in concentrating on Salesforce the exchange of e-mail messages between our team and our customers. 

So, my question is the following:

Is there a way of allowing users to receive and send email messages both only on Salesforce? We have already tried the email-to-case approach, using the e-mail address of our organization to log those messages into Salesforce. Nevertheless, this only allow us to receive e-mails, not send them.

Any help will be appreciated.

Best regards,
Hello, everyone.

Is it possible to create a Visualforce page in which the user chooses how many fields appear? For instance, let's say that initially there is a field named "quantity of products", and the user chooses 3. So, after that, 3 fields appear:

Product 1: __
Product 2: __
Product 3: __


Thanks in advance.

 
Hi, everyone!

I want to create a table that will be located inside of an object's page layout. The example of how the table should be is shown on the image below. In this table, there should be a column that allows the user to insert values that will be used to determine a certain numeric field of my object throught a formula. 

Since I don't have access to Apex classes because my Edition doesn't allow it (I'm using Professional Edition), I wonder if there is a way of creating such table without it. Is it possible to create it without having to create Apex Classes?

Thanks!
User-added image 
Hi, everyone.

At the page of a custom object that I have created there is a related list in which objects named "Flexibilidades Contratuais" can be created/accessed/edited/deleted (see the image below). These objects have more than one field, but they don't appear on the list.

I am not beeing able to make these fields visible on the list. I have already tried clicking on the gear icon that appears when clicking on the list, but haven't found a solution with it.

Is there a way of making these fields visible?

Thanks in advance.

Livia.
User-added image
 
Hello, everyone. 

I am new to Salesforce (I've began studying it about 1 month ago). 

There are some projects that I intend to implement on my Salesforce Professional Edition, but I am stuck due to some limitations. Since I don't have much experience with the platform, I wonder if the community of developpers could help me confirm if, in fact, my edition doesn't allow me to develop them, and if I need to upgrade my edition.

The implementations are described below:

1) Send scheduled email alerts

We want to send e-mail alerts when expiration dates of opportunities' contracts are approaching. In this context, we want to send weekly emails corresponding to each opportunity.

I've tried to do this by using Flow and Process Builder. Nevertheless, I always get the error message shown on this topic https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000BuOazSAF (bear with me...the french community seamed more active, so I tried to ask for help in french :) - google translator required). 

TL DR.: Error message = "insufficient access rights on cross-reference id"

2) Build a list of e-mails

The objective here is to make the sending of email messages more transparent. For example, if a sales representant sends an email to an opportunity, we want to make this message visible on Salesforce. At each opportunity page, there would be a "e-mails" tab, where we could show these messages.

3) Access data from external sources 

We want to access data contained on Google Cloud Big Query and Google Sheets. Note: We don't have access to Salesforce API on Professional Edition.


Actually, I think that the main question here is: 

What can developpers do on Salesforce Professional Edition? 

As a begginer, I am finding a lot of barriers. The things I was able to do so far are the following:

Change Pages' Layouts
Create New Objects and Fields
Create Email Alerts

Things I identified that I can't do:

Create Apex Classes
Create Customized Metadata
Access external API's
 
Hello, everyone!

I am trying to implement a test class for a trigger, that calls a http method (which comes from this tutorial: https://cloud.google.com/architecture/calling-protected-cloud-functions) .

In my case, everytime when the custom object 'Proposta__c' is updated, the GCPManageCustomersService method is called. Basically, this class implements the calling of a cloud functions that was set up by following the aforementioned tutorial.

When implementing the ' GCPMockHTTPResponseGenerator' class on my test class 'GCPManageCustomersServiceTest', I always get assertion errors on the following lines:
 
System.assertEquals(1, asyncJobList.size());
        
System.assertEquals(true, mock.methodCalled);

Below, I show you the complete test class:
 
@isTest
public class GCPManageCustomersServiceTest {

    static testmethod void testQueueable() {

        GCPMockHttpResponseGenerator mock = new GCPMockHttpResponseGenerator(); 
        

        Test.setMock(HttpCalloutMock.class, mock);
        
        Test.startTest();
        
        PriceBook2 pb_se_conv = new PriceBook2();
		pb_se_conv.Name = 'SE/CO - CONV';
        pb_se_conv.Pre_o_2023_R_MWh__c = 123.45;
        insert pb_se_conv;
        
        PriceBook2 pb_se_I0 = new PriceBook2();
		pb_se_I0.Name = 'SE/CO - I0';
        insert pb_se_I0;
        
        PriceBook2 pb_se_I100 = new PriceBook2();
		pb_se_I100.Name = 'SE/CO - I100';
        insert pb_se_I100;
        
        PriceBook2 pb_se_I5 = new PriceBook2();
		pb_se_I5.Name = 'SE/CO - I5';
        insert pb_se_I5;
        
        PriceBook2 pb_se_INE = new PriceBook2();
		pb_se_INE.Name = 'SE/CO - INE';
        insert pb_se_INE;
        
        
        PriceBook2 pb_NE_conv = new PriceBook2();
        pb_NE_conv.Name = 'NE/CO - CONV';
        insert pb_NE_conv;
                
        PriceBook2 pb_NE_I0 = new PriceBook2();
        pb_NE_I0.Name = 'NE/CO - I0';
        insert pb_NE_I0;
                
        PriceBook2 pb_NE_I100 = new PriceBook2();
        pb_NE_I100.Name = 'NE/CO - I100';
        insert pb_NE_I100;
                
        PriceBook2 pb_NE_I5 = new PriceBook2();
        pb_NE_I5.Name = 'NE/CO - I5';
        insert pb_NE_I5;
                
        PriceBook2 pb_NE_INE = new PriceBook2();
        pb_NE_INE.Name = 'NE/CO - INE';
        insert pb_NE_INE;
        
        PriceBook2 pb_S_conv = new PriceBook2();
        pb_S_conv.Name = 'S/CO - CONV';
        insert pb_S_conv;
                
        PriceBook2 pb_S_I0 = new PriceBook2();
        pb_S_I0.Name = 'S/CO - I0';
        insert pb_S_I0;
                
        PriceBook2 pb_S_I100 = new PriceBook2();
        pb_S_I100.Name = 'S/CO - I100';
        insert pb_S_I100;
                
        PriceBook2 pb_S_I5 = new PriceBook2();
        pb_S_I5.Name = 'S/CO - I5';
        insert pb_S_I5;
                
        PriceBook2 pb_S_INE = new PriceBook2();
        pb_S_INE.Name = 'S/CO - INE';
        insert pb_S_INE;
        
        PriceBook2 pb_N_conv = new PriceBook2();
        pb_N_conv.Name = 'N/CO - CONV';
        insert pb_N_conv;
                
        PriceBook2 pb_N_I0 = new PriceBook2();
        pb_N_I0.Name = 'N/CO - I0';
        insert pb_N_I0;
                
        PriceBook2 pb_N_I100 = new PriceBook2();
        pb_N_I100.Name = 'N/CO - I100';
        insert pb_N_I100;
                
        PriceBook2 pb_N_I5 = new PriceBook2();
        pb_N_I5.Name = 'N/CO - I5';
        insert pb_N_I5;
                
        PriceBook2 pb_N_INE = new PriceBook2();
        pb_N_INE.Name = 'N/CO - INE';
        insert pb_N_INE;        
        
        
        

        
        Account acc = new Account();
        acc.Name = 'ACC2';
        acc.OwnerId = UserInfo.getUserId();
        
        insert acc;
        
        
        Opportunity opp = new Opportunity();
        opp.Name = 'TEST OPP 27_05_22';
        opp.AccountId = acc.Id;
        opp.CloseDate = date.today();
        opp.StageName = 'Proposta';
        
        insert opp;
        
        RFQ__c rfq = new RFQ__c();
        rfq.Oportunidade__c = opp.Id;
        rfq.Respons_vel__c = UserInfo.getUserId();
        date inicio = date.today();
        rfq.In_cio_Suprimento__c = date.today();
        rfq.Validade_Suprimento__c = inicio.addMonths(15);
        
        rfq.Tipo_de_Energia__c = 'Conv';
        
        rfq.Ponto_de_Entrega__c = 'SE/CO';
        
        insert rfq;
        
        
        RFQ__c rfq_inserted = [SELECT Id, Ponto_de_Entrega__c, Tipo_de_Energia__c FROM RFQ__c WHERE Id=:rfq.Id];
      
        
        Proposta__c proposta_first = [SELECT Name, Id,Pre_o_Ano1_Tabela__c, Cat_logo_de_pre_os__c FROM Proposta__c WHERE RFQ__c=:rfq_inserted.Id];
        
        proposta_first.CNPJ__c = '123456';
        
        update proposta_first;
        
        Test.stopTest();
        
        List<AsyncApexJob> asyncJobList =
            [select id, ApexClass.Name, JobType, Status from AsyncApexJob];
        
        PriceBook2 pb_correspondente = [SELECT Id, Name from PriceBook2 WHERE Id=:proposta_first.Cat_logo_de_pre_os__c];
                  
        System.assertEquals(pb_correspondente.Name, 'SE/CO - CONV' );  
        
        System.assertEquals(proposta_first.Pre_o_Ano1_Tabela__c, 123.45 ); 
        
       
        
        
        System.assertEquals(1, asyncJobList.size());
        
        System.assertEquals(true, mock.methodCalled);
        
        
            
        
    }
}

Finally, the trigger that does the http callout:
 
trigger updatePricesProposal on Proposta__c (after update){
    
    if (Trigger.isUpdate){
     
        
        for (Proposta__c prop : Trigger.new){
            
            List <Proposta__c> prop_list  =  new List <Proposta__c>();
            
            prop_list.add(prop);
           
            String serialisedProp = JSON.serialize(prop_list);
            
            try{
                
                Proposta__c old_prop = Trigger.oldMap.get(prop.Id);
                              
                if(prop.Cat_logo_de_pre_os__c != null && old_prop.Tempo_Botao_Preco__c.format('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'') != prop.Tempo_Botao_Preco__c.format('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'')  ){
                
                GCPManageCustomersService gcpService = new GCPManageCustomersService(serialisedProp, 'update');
                    
                ID jobID = System.enqueueJob(gcpService);               
                
                }
                
                
                
            }catch(Exception e){
                
                           
                
                
            }
                    
            
        }        
        
        
    } 
            

}

I appreciate any help you can provide.

Best regards,
Hello, everyone.

I am developing a trigger which has a complicated logic. To deal with this complexity, I am using 3 different Apex classes inside my trigger in the following way:

TRIGGER: 
 
trigger total_rfq_proposta on RFQ__c (after update) {
  
        if (Trigger.isAfter) {
        if (Trigger.isUpdate) {
            
           //HelloWorld.helloWorld2( Trigger.new );
              
           RFQHandler.updateRFQ(Trigger.new);                   
        }            
}
             
}

RFQHandler CLASS:
 
public class RFQHandler{



public static double assignMonthVolumes(integer indice_ano, integer flag_month , RFQ__c rfq) {} ....


public static double getMonthlyVolumes(integer year, integer indice_ano ,RFQ__c rfq){}...


public static double getYearlyVolumes(integer year, integer indice_ano ,RFQ__c rfq){}...


// This is the "main" function
  
public static void updateRFQ(List <RFQ__c> rfqs){
        
        
        for(RFQ__c rfq : rfqs){
            
            if(rfq!=null){
                
                
           
            
            
     Proposta__c proposal = [SELECT Id, Total_RFQ_MWm__c	from Proposta__c WHERE RFQ__c=:rfq.id];
        
     if(proposal != null){
            
            double total_2022_MWm = 0;
            double total_2023_MWm = 0;
            double total_2024_MWm = 0;
            double total_2025_MWm = 0;
            double total_2026_MWm = 0;
            double total_2027_MWm = 0;
            
            // Lista que guardará todos os anos referentes à RFQ           
            list <integer> years = new list <integer>(); 
            
            Date d1 = rfq.In_cio_Suprimento__c;
            
            
            // ex.: inicio = novembro de 2022 || fim = julho de 2024
            while(d1.year() <= rfq.Validade_Suprimento__c.year()){
                
                years.add(d1.Year());    
                d1 = d1.addYears(1);
                
                
            }
            
            // Dicionário que aponta quais anos correspondem a Ano1/Ano2/Ano3 ... etc
          	map <String, Integer> mapa_anos = new map <String, Integer>(); 
            
            // Mapeando os anos correspondentes à RFQ em questão:
            // years = lista contendo todos os anos (integers)
            for(integer value : years){
                
                integer indice = years.indexof(value);
                
                switch on indice{
                    
                    when(0){
                        
                        mapa_anos.put('Ano1',value);
                        
                    }when(1){
                        
                        mapa_anos.put('Ano2',value);
                        
                    }
                    when(2){
                        
                        mapa_anos.put('Ano3',value);
                        
                    }
                    when(3){
                        
                        mapa_anos.put('Ano4',value);
                        
                    }when(4){
                        
                        mapa_anos.put('Ano5',value);
                        
                    }when(5){
                        
                        mapa_anos.put('Ano6',value);
                        
                    }              
                    
                    
                    
                }
                               
                                   
            }
          								          
     
            integer count = 0;
                
            for(integer ano : mapa_anos.values()){
                                                        
                 // Para cada string "Ano1 / Ano2 / Ano3 ...."
                 // Verifica qual que é o ano correspondente e atribui os volumes de acordo com a posição deles (Ano1/Ano2/Ano3 ...)  
                                       
                    integer indice_ano = mapa_anos.values().indexof(ano); // Índice do ano correspondente
                
                	system.debug(indice_ano);
                
                	system.debug(rfq.Name);
                    
                    switch on ano{
                        
                        when 2022{
                           
                           double valor_anual =  getYearlyVolumes(2022,indice_ano, rfq);                        
                           double valor_mensal = getMonthlyVolumes(2022, indice_ano, rfq);
          					
                            if(valor_anual != 0){
                                
                                proposal.Total_RFQ_MWm__c = valor_anual;                               
                                update proposal;
                                                        
                            }else{
                            
                                proposal.Total_RFQ_MWm__c = valor_mensal;                         
                                update proposal;
                                
                            }
                            
                        }
                        
                        when 2023{
                            
                            
                            
                            
                        }
                        
                        
                        when 2024{
                            
                            
                            
                            
                        }when 2025{
                            
                            
                            
                        }when 2026{
                            
                            
                            
                        }when 2027{
                            
                            
                            
                        }
                        
                        
                        
                    }                  
                   
                                       
                    
                    
                }
          
                                       
                
     
            
            
        }
        
    
            }
            
            
        }
        
        
        
    }
    
    


}

OBS: I am not posting all the classes, otherwise this post would be too extensive.


PROBLEM:

In this scenario, I am having the  following problem when testing my Trigger:

Inside RFQHandler --> void updateRFQ, when calling the functions getYearlyVolumes and getMonthlyVolumes like shown below
 
double valor_anual =  getYearlyVolumes(2022,indice_ano, rfq);                 
double valor_mensal = getMonthlyVolumes(2022, indice_ano, rfq);

The following error messages appear:

System.DmlException: Update failed. First exception on row 0 with id a05HZ0000001mdhYAA; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, total_rfq_proposta: execution of AfterUpdate

caused by: System.NullPointerException: Attempt to de-reference a null object

Class.RFQHandler.getYearlyVolumes: line 958, column 1
Class.RFQHandler.updateRFQ: line 1196, column 1
Trigger.total_rfq_proposta: line 8, column 1: []


I am having trouble figuring out why this is happening.

Any help would be deeply appreciated.

Thank you,

Lívia.
Hi, everyone!

In our organization, we are interested in concentrating on Salesforce the exchange of e-mail messages between our team and our customers. 

So, my question is the following:

Is there a way of allowing users to receive and send email messages both only on Salesforce? We have already tried the email-to-case approach, using the e-mail address of our organization to log those messages into Salesforce. Nevertheless, this only allow us to receive e-mails, not send them.

Any help will be appreciated.

Best regards,
Hello, everyone.

Is it possible to create a Visualforce page in which the user chooses how many fields appear? For instance, let's say that initially there is a field named "quantity of products", and the user chooses 3. So, after that, 3 fields appear:

Product 1: __
Product 2: __
Product 3: __


Thanks in advance.

 
Hi, everyone.

At the page of a custom object that I have created there is a related list in which objects named "Flexibilidades Contratuais" can be created/accessed/edited/deleted (see the image below). These objects have more than one field, but they don't appear on the list.

I am not beeing able to make these fields visible on the list. I have already tried clicking on the gear icon that appears when clicking on the list, but haven't found a solution with it.

Is there a way of making these fields visible?

Thanks in advance.

Livia.
User-added image
 
Hello, everyone. 

I am new to Salesforce (I've began studying it about 1 month ago). 

There are some projects that I intend to implement on my Salesforce Professional Edition, but I am stuck due to some limitations. Since I don't have much experience with the platform, I wonder if the community of developpers could help me confirm if, in fact, my edition doesn't allow me to develop them, and if I need to upgrade my edition.

The implementations are described below:

1) Send scheduled email alerts

We want to send e-mail alerts when expiration dates of opportunities' contracts are approaching. In this context, we want to send weekly emails corresponding to each opportunity.

I've tried to do this by using Flow and Process Builder. Nevertheless, I always get the error message shown on this topic https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000BuOazSAF (bear with me...the french community seamed more active, so I tried to ask for help in french :) - google translator required). 

TL DR.: Error message = "insufficient access rights on cross-reference id"

2) Build a list of e-mails

The objective here is to make the sending of email messages more transparent. For example, if a sales representant sends an email to an opportunity, we want to make this message visible on Salesforce. At each opportunity page, there would be a "e-mails" tab, where we could show these messages.

3) Access data from external sources 

We want to access data contained on Google Cloud Big Query and Google Sheets. Note: We don't have access to Salesforce API on Professional Edition.


Actually, I think that the main question here is: 

What can developpers do on Salesforce Professional Edition? 

As a begginer, I am finding a lot of barriers. The things I was able to do so far are the following:

Change Pages' Layouts
Create New Objects and Fields
Create Email Alerts

Things I identified that I can't do:

Create Apex Classes
Create Customized Metadata
Access external API's