+ Start a Discussion
Arundhati DebArundhati Deb 
Hi

I have a scenario where the account currency and opportunity currency can be different. The opportunity currency should be the same as opportunity owner currency. I have to write a trigger for it. Can anyone help me with it.
Highly appreciated.
Best Answer chosen by Arundhati Deb
Abdul KhatriAbdul Khatri
@Arundhati

I see some issues with your code so here is your code with some corrections.
 
public static void Opportunitycurrency (List<Opportunity> newOptyList) {
        
        List<Id> oppOwnerIds = new List<Id>();
        for(Opportunity opp: newOptyList)
        {
            if(opp.OwnerId != null)
            {  
                oppOwnerIds.add(opp.OwnerId); 
            }
        }
        
        Map<Id, User> userList = new Map<Id, User>([SELECT Id, Name, CurrencyIsoCode FROM User WHERE Id IN :oppOwnerIds]);
        
        for(Opportunity opp: newOptyList)
        {
            if(opp.type != 'Renewal')
            {
                opp.currencyisocode=userList.get(opp.OwnerId).currencyisocode;
            }
        }
    }

 
nishwalnishwal 

 If @isTest(SeeAllData=false) working for anyone?

I have annotated the class as well as the method but the testmethod can see the existing data.

Here is simple code snippet. Assertion is getting failed for me...

@isTest(SeeAllData=false)
private class testAnnotationSeeAllData {

static testmethod void myUnitTest()
{
Test.startTest();
List<User> lstUsers = [Select Id, Name From User Where IsActive= true Limit 100];
System.assert(lstUsers.size() == 0);
Test.stopTest();
}
}

tried in api version 24 and 25 both. and Developer Org and Sandbox.


is there anyone who is experiencing the same problem?

Best Answer chosen by Admin (Salesforce Developers) 
bob_buzzardbob_buzzard

Users aren't considered data for this purpose.  The following doc page:

 

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_data_access.htm

 

details which data will still be visible to your test - user is on that list.

Leticia Monteiro Freitas 4Leticia Monteiro Freitas 4 
Hello, I'm trying to make a Lightning component that makes a search in Account and returns results. But, I get the following error:
My variable input_text gets undefiened, even after user get.component. 
Can anyone help me?


User-added image
My code:
Class:

/*Versão 3.00 - US_179 - Leticia Freitas - 13/11 
Classe que recebe uma string, determina se é um cpf ou um cnpj e a partir dele, realiza a busca dessa conta. 
Caso exista o registro, retorna as informações: Nome, Tipo de Documento (CPF ou CNPJ), Número do documento, Número do Documento Formatado, Logradouro, CEP, Cidade e Estado.
*/

public class CEC_SearchAccount{   
     
    
    
    public static List<Account> getfoundAccount(String Key, String documentType)
    {
       List<Account> Conta  = [Select ID, Name, DocumentType__c,DocumentNumber__c,FormattedDocument__c,BillingAddress from Account 
       where DocumentNumber__c =:Key  AND DocumentType__c =:documentType];

            return Conta;
         
           
        
    }
    
    public static void getvalidCPF(String CPF)
    {
        /* Cálcula se o cpf é valido através do cálculo dos digitos validadores.*/
        integer value; 
        integer coeff = 10, sum, rest;
        String dig10,dig11;
        
        
        //Calcula o primeiro digito validador do CPF
        for(integer i=0; i<9;i++)
        {
            value = Integer.valueOf(CPF.substring(i,1))* coeff;
            coeff--;
            sum =   sum + value ;
        }
        
        rest = 11 - math.mod(sum,11);
        if((rest == 10) || (rest == 11))
        {
            dig10 = '0';
        }else{
            dig10 = String.valueOf(rest);
        }
        
        sum = 0;
        coeff = 11;
        value = 0;
        
        for(integer i=0;i<10;i++)
        {
            value = Integer.valueOf(CPF.substring(i,1))*coeff;
            coeff--;
            sum = sum + value;
            
        }   
        rest = 11 - math.mod(sum,11);
        
        if((rest == 10) || (rest==11))
        {
            dig11 = '0';
        }else{
            dig11=String.valueOf(rest);
        }
        
        // Validate if the calculus match
        if((dig11 == cpf.substring(0,11)) && (dig10 == cpf.substring(0,10)))
        {
           String documentType = 'CPF';
            getfoundAccount(CPF,documentType);
        }else{
         system.debug('CNPJ iNVÁLIDO');
        }
    }
    
    
    
    public static void getvalidCNPJ(String CNPJ)
    {
        integer value;
        integer coeff=12,sum,rest;
        String dig13,dig14;
               
        for(integer i = 0; i < 12;i++)
        {
            value = Integer.valueOf(CNPJ.substring(i,1)) * coeff;
            coeff--;
            sum = sum + value;
        }
        
        rest =Math.mod(sum,11);
        
        if((rest == 0) || (rest == 1))
        {
            dig13 = '0';
        }else{
            dig13 = String.valueOf(11 - rest);
        }
        
        // Calculando o segundo digito verificador do CNPJ
        
        rest=0;
        coeff=13;
        
        for(integer i = 0;i<13;i++)
        {
            value = Integer.valueOf(CNPJ.substring(i,1)) * coeff;
            coeff--;
            sum = sum + value;
        }
        
        rest = math.mod(sum,11);
        
        if((rest == 0) || (rest == 1))
        {
            dig14 = '0';
        }else{
            dig14 = String.valueOf(11 - rest);
        }
        
        if((CNPJ.substring(0,13) == dig13) && (CNPJ.substring(0,14)== dig14))
        {
           String documentType ='CNPJ';
            getfoundAccount(CNPJ, documentType);
        }else{
            //
        }
    }
    
    @AuraEnabled
    Public static void getvalidKey(String text)
    {
        /*Após ler a string de caracteres, o sistema chama a função de cpf ou cnpj conformo o tamanho da string */
        system.debug('Chegou na função da classe agora o/');
        //integer tamanho = text.length();
        system.debug('Tamanho:');
        system.debug('Texto:'+text);
        
        system.debug(text.length());
            
        if(text.length() == 11)
        {
            getvalidCPF(text);
        }else if(text.length() == 14)
        {
            getvalidCNPJ(text);
        }else{
            system.debug('CPF/CNPJ Inválido');
        }
    }
    
 }

Controller:
({
    /* Dentro da ação de clicar no botão, a classe controladora aponta para a função validKey*/
   
    handleClick : function(component, event, helper) {
        var action = component.get("c.getvalidKey"); 
        
        var input_text = component.get("v.searchText");
        console.log("input_text"+ input_text);
        debugger;
        action.setParams({"text":input_text});
        
        action.setCallback(this,function(response)
        {
          var state = response.getState();x
        if(component.isValid() && STATE==Sucess){
            component.set("v.acctList",response.getReturnValue());
        }
        });
        $A.enqueueAction(action);
    }
})

Cmp:
<aura:component controller="CEC_SearchAccount" implements="force:appHostable">
   
    <aura:attribute name="acctList" type="Account[]" />
    <lightning:input name="searchText" label="Insira o CPF ou CNPJ" />
    <lightning:button variant="brand" label="Buscar" onclick="{!c.handleClick}"/>
    
    
    <aura:iteration items="{!v.acctList}" var="a">
        <p>{!a.Name},{!a.Type}</p>
    </aura:iteration>
    
</aura:component>
Best Answer chosen by Leticia Monteiro Freitas 4
Raj VakatiRaj Vakati
Change your componet like below 
 
 <aura:component controller="CEC_SearchAccount" implements="force:appHostable">
   
    <aura:attribute name="acctList" type="Account[]" />
    <lightning:input aura:id="searchText" name="searchText" label="Enter some text" onblur="{! c.handleBlur }"/>
<lightning:button variant="brand" label="Buscar" onclick="{!c.handleClick}"/>
    
    
    <aura:iteration items="{!v.acctList}" var="a">
        <p>{!a.Name},{!a.Type}</p>
    </aura:iteration>
    
</aura:component>
 
Controller:
({
    /* Dentro da ação de clicar no botão, a classe controladora aponta para a função validKey*/
   
    handleClick : function(component, event, helper) {
        var action = component.get("c.getvalidKey"); 
        

var input_text = component.find("searchText").get("v.value"); 
       
        console.log("input_text"+ input_text);
        debugger;
        action.setParams({"text":input_text});
        
        action.setCallback(this,function(response)
        {
          var state = response.getState();x
        if(component.isValid() && STATE==Sucess){
            component.set("v.acctList",response.getReturnValue());
        }
        });
        $A.enqueueAction(action);
    }
})

 
Matthew HofmannMatthew Hofmann 
Hello,

I'm creating an Apex class that creates a Salesforce File record and associates it with a parent record. I'm having a problem creating the association (ContentDocumentLink) record.

Here is what I'm doing:
  • Create a ContentVersion record. This creates a ContentDocument record automatically if you leave the ContentVersion.ContentDocumentId field blank. (https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_contentdocument.htm - "To create a document, create a new version via the ContentVersion object without setting the ContentDocumentId. This automatically creates a parent document record.")
  • Insert ContentVersion record
  • DEBUG: Confirm ContentVersion.ContentDocumentId is set (Here is where the problem is because it is NULL; however if I SOQL query ContentVersion after the Apex completes, ContentVersion.ContentDocumentId is set and the corresponding ContentDocument record exists)
  • Create ContentDocumentLink record (commented out because it fails because ContentDocumentLink.ContentDocumentId is a required field)
  • Insert ContentDocumentLink record (commented out because it fails because ContentDocumentLink.ContentDocumentId is a required field)
Here is the code:
public class FileController {
    
    @AuraEnabled
    public static Id saveTheFile(Id parentId, String fileName, String base64Data, String contentType, Id contentDocumentId) { 
        base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8');
        
        ContentVersion cv = new ContentVersion();
        cv.ContentLocation = 'S';
        cv.ContentDocumentId = contentDocumentId;
        cv.VersionData = EncodingUtil.base64Decode(base64Data);
        cv.Title = fileName;
        cv.PathOnClient = filename;
        
        insert cv;
        
        //***This DEBUG statement must return an Id for the rest of the code to work***
        System.debug('contentDocumentId='+cv.ContentDocumentId);               
        
        //ContentDocumentLink cdl = new ContentDocumentLink();
        //cdl.ContentDocumentId = cv.ContentDocumentId;
        //cdl.LinkedEntityId = parentId;
        //cdl.ShareType = 'I';
        
        //insert cdl;
        
        return cv.Id;
    }

    @AuraEnabled
    public static Id saveTheFile(Id parentId, String fileName, String base64Data, String contentType) {         
        return saveTheFile(parentId, fileName, base64Data, contentType, NULL);
    }
}

Does anyone know what I'm doing wrong, not considering, etc?
Appreciate any thoughts and input!
Best Answer chosen by Matthew Hofmann
VineetKumarVineetKumar
Interesting..

Well the culprit in your code is the null value and way you are using it to assign the value to ContentDocumentLink.contentDocumentId.
You should query the content version object again to get the contentDocumentId (which is generated after the parent document is inserted by default because of you passing of null value).
Something like below :
ContentDocumentLink cdl = new ContentDocumentLink();
cdl.ContentDocumentId = [SELECT Id, ContentDocumentId FROM ContentVersion WHERE Id =: cv.Id].ContentDocumentId;
cdl.LinkedEntityId = '00590000000a6dP';
cdl.ShareType = 'V';
insert cdl;

As per the salesforce documentation lines higlighted by you, "To create a document, create a new version via the ContentVersion object without setting the ContentDocumentId. This automatically creates a parent document record." it does create the parent document record as expected, but the contentDocumentId is still null in above initialised object. Id doesn't get updated automatically to the object instance. Infact you will have to pull out the corresponding Id as done in the above snippet.

Let me know if this helps.
L0bster1L0bster1 

I want to automatically convert new leads into contacts. I have a trigger on Lead after update that will bulk convert 100 leads at a time. The problem I have  is that my marketing automation tool pushes new leads into Salesforce in batches of 200 at a time. When I try to import 200 leads, the bulk convert fails due to a too many DML 151 error.

 

I read that the convertlead function can only handle 100 records at a time. How can I edit the code to handle 200 imports at a time? Is it possible?

 

Thanks in advance.

 

trigger AutoConvert on Lead (after update) {

for(Lead myLead: Trigger.new){ if(Trigger.new[0].isConverted == false) { Database.LeadConvert lc = new database.LeadConvert(); lc.setLeadId(myLead.Id); lc.convertedStatus = 'Qualified'; //Database.ConvertLead(lc,true); lc.setDoNotCreateOpportunity(true); Database.LeadConvertResult lcr = Database.convertLead(lc); System.assert(lcr.isSuccess()); }}}

 

Best Answer chosen by Admin (Salesforce Developers) 
Jerun JoseJerun Jose

Instead of passing one lead value at a time to the convertLead method, you can pass a list of lead values. From the documentation at

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_dml_convertLead.htm
you can do something like

LeadConvertResult[] Database.convertLead(LeadConvert[] leadsToConvert, Boolean opt_allOrNone)

 

Also, you trigger is not designed for bulk operations. Use the updated trigger below and modify it as necessary.

 

trigger AutoConvert on Lead (after update) {
	list<Lead> LeadsToConvert = new list<Lead>();
	for(Lead myLead: Trigger.new){
		if(!myLead.isConverted)
			LeadsToConvert.add(myLead);
	}

	list<Database.LeadConvert> leadConverts = new list<Database.LeadConvert>();
	for(Lead myLead : LeadsToConvert){
		Database.LeadConvert lc = new database.LeadConvert();
		lc.setLeadId(myLead.Id);
		lc.convertedStatus = 'Qualified';
		//Database.ConvertLead(lc,true);
		lc.setDoNotCreateOpportunity(true);
		leadConverts.add(lc);
	}

	if(!leadConverts.isEmpty()){
		for(Integer i = 0; i <= leadConverts.size()/100 ; i++){
			list<Database.LeadConvert> tempList = new list<Database.LeadConvert>();
			Integer startIndex = i*100;
			Integer endIndex = ((startIndex+100) < leadConverts.size()) ? startIndex+100: leadConverts.size();
			for(Integer j=startIndex;j<endIndex;j++){
				tempList.add(leadConverts[j]);
			}
			Database.LeadConvertResult[] lcrList = Database.convertLead(tempList, false);
			for(Database.LeadConvertResult lcr : lcrList)
				System.assert(lcr.isSuccess());
		}
	}
}

 

 Edit - forgot the part about max 100 records for convertLead. Updated the apex code for it

Joe Rodden 7Joe Rodden 7 
Fairly new so bear with me. I've written a class that throws an error message for any duplicate emails on Contacts. While writing the test I thought I'd covered everything the original class does however I'm only ending up with 85% code coverage. I'd like to figure out how to get to 100. 

Class (the lines that aren't covered are bolded and underlined):
 
public class Contact_CheckEmail {

    List<Contact> contacts = new List<Contact>();
    
    public Contact_CheckEmail(List<Contact> trigCon){
       contacts = trigCon; 
    }
    

    public void checkEmail(){
    Set<String> emailSet = new Set<String>();
    
    for(Contact c : contacts){
        
        emailSet.add(c.Email);
    
    }
    
    List<Contact> duplicateEmail = [SELECT Email FROM Contact WHERE Email IN: emailSet];
    
    Set<String> duplicateEmailId = new Set<String>();
    
    for(Contact c : duplicateEmail) {
    
        duplicateEmailId.add(c.Email);
    
    }

    for(Contact c: contacts){
        if(duplicateEmailId.contains(c.Email)){
               c.addError('Email already exists.');
        
        }
    
    }
    
}
}


Test Class:
@isTest
public class Test_CheckEmail {
    
    @isTest static void EmailCheckTest(){
        
        Account acc = new Account();
        acc.Name = 'TestAccount';
        insert acc;
        
        List<Contact> contacts = new List<Contact>();
        for( Integer i = 0;i < 1; i++){
            String iString = String.valueof(i);
            Contact myCon = new Contact();
            myCon.LastName = 'iString';
            myCon.AccountId = acc.Id;
            myCon.Email = 'fakeman@fake.com';
            contacts.add(myCon);
        }
        
        try{
        insert contacts;
        }
        catch (Exception e){
            Boolean expectedException = e.getMessage().contains('Email already exists.') ? true : false;
            System.assertEquals(expectedException, true);
        }
        
        List<Contact> contacts2 = new List<Contact>();
        for( Integer i = 0;i < 1; i++){
            String iString = String.valueof(i);
            Contact myCon = new Contact();
            myCon.LastName = 'iString';
            myCon.AccountId = acc.Id;
            myCon.Email = iString + '@fake.com';
            contacts2.add(myCon);
        }
        
        try{
        insert contacts2;
        }
        catch (Exception e){
            Boolean expectedException = e.getMessage().contains('Email already exists.') ? true : false;
            System.assertEquals(expectedException, false);
        }
        
        
        
    }

}

 
Best Answer chosen by Joe Rodden 7
Khan AnasKhan Anas (Salesforce Developers) 
Hi Joe,

Greetings to you!

Please use the below code, I have checked in my org and it is covering 100%
 
@isTest
public class Test_CheckEmail {
    
    @isTest static void EmailCheckTest(){        
        Account acc = new Account();
        acc.Name = 'TestAccount';
        insert acc;
        
        List<Contact> contacts = new List<Contact>();
        for( Integer i = 0;i < 1; i++){
            String iString = String.valueof(i);
            Contact myCon = new Contact();
            myCon.LastName = 'iString';
            myCon.AccountId = acc.Id;
            myCon.Email = 'fakeman@fake.com';
            contacts.add(myCon);
        }
        
        try{
            insert contacts;
        }
        catch (Exception e){
            Boolean expectedException = e.getMessage().contains('Email already exists.') ? true : false;
            System.assertEquals(expectedException, true);
        }
        
        List<Contact> contacts2 = new List<Contact>();
        for( Integer i = 0;i < 1; i++){
            String iString = String.valueof(i);
            Contact myCon = new Contact();
            myCon.LastName = 'iString';
            myCon.AccountId = acc.Id;
            myCon.Email = iString + '@fake.com';
            contacts2.add(myCon);
        }
        
        try{
            insert contacts2;
        }
        catch (Exception e){
            Boolean expectedException = e.getMessage().contains('Email already exists.') ? true : false;
            System.assertEquals(expectedException, false);
        }
        
        Contact_CheckEmail cce = new Contact_CheckEmail(contacts2);
        cce.checkEmail();
    }
}


I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in the future.

Thanks and Regards,
Khan Anas
fredkafredka 
Hi.  I am trying to assign a queue as the case owner.. In a Case Before Trigger, I am have the following.  The case owner is getting updated if the abm__c field is populated.. however, it does not get updated with the queue if that field is null.

Account_Team__c at = aMap.get(c.AccountId);
                // Only change the owner if the Account Team has
                // an ABM and the ABM is an active user. Once assigned
                // set the flag Assigned to ABM
            if (string.isNotBlank(at.abm__c)) {
                if (at.abm__r.IsActive) {
                    c.ownerid = at.abm__c;
                    c.Assigned_To_ABM__c = true;                    
                }
             }
              else {
                c.ownerid = abmQueue[0].Id;
                }

Any help woudl be greatly appreciated!!

Fred
Best Answer chosen by fredka
_Zach Boyd_Zach Boyd
I have not used the QueueSObject class before, however I see that it has a QueueId field. Try using that and the owner should be assigned properly.

https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_queuesobject.htm

 
pooja biswaspooja biswas 
Hi
I have university as parent object & college as child object.
There is a master-detail relationship defined on child object i.e college

I have a parent-child soql as follows
List<University__c> univList=[select Name,(select Name from colleges__r) from university__c];
system.debug(univList);

Also I have a child-parent soql as follows
List<college__c> univList=[select Name,university__r.Name from college__c
system.debug(univList);

when I execute the parent-child query I do not get any child related records .
Also when I execute child-parent query I do get the name of the college but the university ID I get but I want the university name also not the ID

please let me know.

Thanks
pooja
 
Best Answer chosen by pooja biswas
Banwari kevatBanwari kevat
Hi pooja,
   Please try this piece of code in developer console. I think you would get what tou want.
For parent-child soql
for(University__c u: [select Name,(select Name from colleges__r) from university__c])
{   
    for(College__c c:u.Colleges__r)
         System.debug('University Name:'+u.Name+'   College Name:'+c.Name);
}
This code will give you all universities name and colleges under university


And
For child-Parent soql
For(College__c c:[select Name,university__r.Name,university__c from college__c])
{
  system.debug('College Name:'+c.Name+'     University Name:'+c.university__r.Name);
}
This code will give you all colleges name with respected university.

Please choose best answer if your problem has been resolved.

Regards,
Banwari K



 
Dagny FernandesDagny Fernandes 
I have a REST service but i am not able to cover this class. 
Below is my code, need help ASAP.

Thanks You in advance.
@RestResource(urlMapping='/AttachPDF/*')
global class ServiceInvoiceRedirectController {
	
	@HttpGet
        global static void AttachPDFtoRecordREST() {
        	List<Id> accId = new List<Id>();
        	List<String> emailList = new List<String>();
            RestRequest req = RestContext.request;
            id recordId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);

            PageReference pdfPage = new PageReference('/apex/ServiceInvoicePDF?Id='+recordId);
            pdfPage.getParameters().put('id',recordId);
            Blob pdf = pdfPage.getContentAsPdf(); //!Test.isRunningTest() ? pdfPage.getContentAsPdf() : Blob.ValueOf('dummy text');
            
			//List of accoutn Id's of related project
            for(Account_Project_Junction__c accPrjJunRec: [SELECT Id,Project__c,Account__c From Account_Project_Junction__c WHERE Project__c =: recordId]){
            	accId.add(accPrjJunRec.Account__c);
            }
            
            //List of email id's of the selected account's
            for(Contact conRec: [SELECT Id,AccountID,Email,Is_Primary_Contact__c From Contact where AccountID IN: accId AND Is_Primary_Contact__c = true]){
            	if(conRec.Email != null){
            		emailList.add(conRec.Email);
            	}
            }
            
            Project__c prjRec = [Select Id,Name from Project__c where Id =: recordId];
            //Insert Invoice record for related project
	        Invoice__c invoRec = new Invoice__c();
	        invoRec.RecordTypeId = Constants_PicklistVariables.serInvoice; 
	        invoRec.Project__c = recordId;
	        
	        try{
	        insert invoRec;
	        }catch(Exception e){
	            System.debug('Invoice=Exception-->'+e);
	        }
	        System.debug('Invoice=invoRec.id-->'+invoRec);
	        
	        //Insert Attacment to the invoice        
	        Attachment a = New Attachment();
	        a.body = pdf;
	        a.parentID = invoRec.id;
	        a.ContentType  = 'application/pdf';
	        a.Name = 'SER-INV-'+invoRec.id+'.pdf';
	        try{
	        insert a;
	        }catch(Exception e){
	            System.debug('Attachment=Exception-->'+e);
	        }
	        
	        //Create the email attachment
	    	Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
	    	efa.setFileName('SER-INV-'+invoRec.id+'.pdf');//Pleace ad pdf name from contact name project and oppty concatinate 
		    efa.setContentType('application/pdf');
		    efa.setBody(pdf);
		    
		    // Create the Singal Email Message
		    Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
		    email.setSubject('Service Invoice Notification');
		    String[] CCEmails = emailList;
			email.setToAddresses(CCEmails);
		    //email.setToAddresses(new String[] { 'developer@extentor.com' });//add Contact email id
		    email.setPlainTextBody( 'Dear:Sir/Madam <br/> Please Find Attachment your financial report Attached with this email.');
		    email.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});
		    
		    // Sends the email
		    Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
            
        }

        // call this method from your Batch Apex
        global static void attachPdfToRecord( Id recordId, String sessionId )
        {
        	System.debug('recordId==>'+recordId);
        	System.debug('sessionId==>'+sessionId);
        	System.debug('Iam in REST API Call method');
            HttpRequest req = new HttpRequest();
            req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/apexrest/AttachPDF/'+recordId);
            req.setMethod('GET');
            req.setHeader('Authorization', 'OAuth ' + sessionId);

            Http http = new Http();
            HttpResponse response = http.send(req);    
        }
        
}

Test class:
@isTest(seeAllData=false)
global class Test_ServiceInvoiceRedirectController{
   
    static testMethod void testDoGet() {
		Account acc= InitialTestData.createAccount('Raj');
        insert acc;
        
        Contact contact1=InitialTestData.createContact(acc.id,'Sen','raj@gmail.com');
        insert contact1;
        
        Opportunity_Deal__c oppdeal=InitialTestData.createOpportunityDeal('Opp1',acc.id,contact1.id,false,'Quote');
        insert oppdeal;
        
        Project__c project1=InitialTestData.createPlotProject('Pro',acc.id,'Submitted',oppdeal.id);
        insert project1;
        
    RestRequest req = new RestRequest(); 
    RestResponse res = new RestResponse();

    // pass the req and resp objects to the method     
    req.requestURI = URL.getSalesforceBaseUrl().toExternalForm()+'/services/apexrest/AttachPDF/'+project1.Id;  
    req.httpMethod = 'GET';

    ServiceInvoiceRedirectController.attachPdfToRecord results = ServiceInvoiceRedirectController.AttachPDFtoRecordREST(req,res);

    System.assertEquals('true', results.success);
    System.assertEquals(10, results.records.size());
    System.assertEquals('Query executed successfully.', results.message);

  }
	
}
Best Answer chosen by Dagny Fernandes
Dagny FernandesDagny Fernandes
Thanks a lot @Roy Luo for your help the above code throwing the null value in the response RestRequest req = RestContext.request; req was null but it coverd the attachPdfToRecord method. this helped a lot to complet the code coverage below is the complete test code 

the importent was the "req" url gives the record id to get that id was importent*

Mock Test Class:(The same code)
 
@isTest
public class Test_MockAttachPDFtoRecordHttpResponce implements HttpCalloutMock 
{

        public HTTPResponse respond(HTTPRequest req) 
        {  
                // Create a fake response
                HttpResponse res = new HttpResponse();
                
                return res;
        }
}



Test Class
@isTest(seeAllData=false)
private class Test_ServiceInvoiceRedirectController{
    
    static Account testAccount;
    static Contact testContact;
    static Opportunity_Deal__c testOpportunity;
    static Project__c testNewProject;
    static User testUser;
    
	
    Static void init(){
        
        //Account
        testAccount = InitialTestData.createAccount('TestAccount');
        insert testAccount;
        //Contact
        testContact = InitialTestData.createContact(testAccount.Id,'TestName','testContact@eamil.com');
        insert testContact;
        //User
        testUser = InitialTestData.createUser('TestLast', 'TestFirst', 'userProfile@testuser.com', 'System Administrator');
        insert testUser;
        //Opportunity
        testOpportunity = InitialTestData.createOpportunityDeal('TestOpportunity', TestAccount.Id, testContact.Id, False, 'Presentation');
        insert testOpportunity;
        //Project
        testNewProject = InitialTestData.createNewProject('testProject',TestAccount.Id,'Verified',testOpportunity.Id);
        insert testNewProject;
     }
    
    static testMethod void attachPdfToRecord()
    {
        init();
        Test.startTest();
        
        //mock up your test data
		Test.setMock(HttpCalloutMock.class, new Test_MockAttachPDFtoRecordHttpResponce()); 
		String sessionId=UserInfo.getSessionId();
        ServiceInvoiceRedirectController.attachPdfToRecord(testNewProject.Id, sessionId); 
        Test.stopTest();

    }
    
    static testMethod void AttachPDFtoRecord_Test()
    {
        init();
        Test.startTest();
        RestRequest req = new RestRequest(); 
    	RestResponse res = new RestResponse();
        
        req.requestURI = '/services/apexrest/AttachPDF/';  
        req.addParameter('recordId', testNewProject.id);
    	req.httpMethod = 'GET';  
        RestContext.request = req;
    	RestContext.response = res;
        ServiceInvoiceRedirectController.AttachPDFtoRecordREST();
        
    }
        
}

 
Peter BölkePeter Bölke 
Hello,

i need to get the picklist value for Field Reason of the Case-Objekt. Those vary depending on the record type. I found this on the net, but i am getting an Error 401

function:
@AuraEnabled
    public static List<reasonObject> getReasonRest(Id eId){
        System.debug(eId);
        Map<String,String> sessionAttributes = Auth.SessionManagement.getCurrentSession();
        System.debug('Session '+sessionAttributes.get('SessionId'));
        Id rType = [SELECT id, RecordTypeId FROM Case WHERE ID = :eId].RecordTypeId;
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        String host = System.Url.getSalesforceBaseURL().toExternalForm();
        String url = host + '/services/data/v43.0/ui-api/object-info/Case/picklist-values/'+rType+'/Reason';
        //String url = host + '/ui-api/object-info/Case/picklist-values/'+rType+'/Reason';
        System.debug(url);
        request.setEndpoint(url);
        request.setMethod('GET');  
        request.setHeader('Authorization', 'OAuth '+sessionAttributes.get('SessionId'));
        HttpResponse response;        
        response = http.send(request);
        System.debug('response ' + response);
        Map<String, Object> meta = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
        system.debug(meta);
		List<reasonObject> optionsList = new List<reasonObject>();
        //optionsList.add(new SelectOption('--None--', ''));
        if(meta.containsKey('values')){                                
                for(Object o: (List<Object> )meta.get('values')){
                    Map<String, object > temp = (Map<String, object>)o;        
                    System.debug((String)temp.get('label')+ ' ' + (String)temp.get('value'));
                    reasonObject ro = new reasonObject();
                    ro.label=(String)temp.get('label');
                    ro.value=(String)temp.get('value');
                    //optionsList.add(new SelectOption((String)temp.get('label'), (String)temp.get('value')));
                    optionsList.add(ro);
                }
            }
        return optionsList;
    }
Error
System.HttpResponse[Status=Unauthorized, StatusCode=401]
Any suggestions on this?
Is there a better solution for Lightning components?

regards
Peter
Best Answer chosen by Peter Bölke
Khan AnasKhan Anas (Salesforce Developers) 
Hi Peter,

I trust you are doing very well. It is a pleasure to be in touch with you again.

The Session Id for Lightning is restricted from most API calls. According to this document (https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/apex_api_calls.htm#apex_api_calls) :

"By security policy, sessions created by Lightning components aren’t enabled for API access. This prevents even your Apex code from making API calls to Salesforce. Using a named credential for specific API calls allows you to carefully and selectively bypass this security restriction.
The restrictions on API-enabled sessions aren’t accidental. Carefully review any code that uses a named credential to ensure you’re not creating a vulnerability."

You need to use a Connected App and Named Credential to enable access to the APIs. Please refer to the below tutorial which might help you further.

https://eltoroit.herokuapp.com/Blog.app?page=ETLC_APIsFromApex

https://sfdcpanther.wordpress.com/2018/02/05/how-to-call-salesforce-api-from-lightning-component/


I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in future.

Thanks and Regards,
Khan Anas