Thursday, July 18, 2019

How to use salesforce REST API to fetch the data using encrypted field in filter Criteria

According to Salesforce doc: https://help.salesforce.com/articleView?id=security_pe_considerations_general.htm&type=5 (https://help.salesforce.com/articleView?id=security_pe_considerations_general.htm&type=5)

Encrypted fields that use the probabilistic encryption scheme can’t be used with the following SOQL and SOSL clauses and functions:
  • Aggregate functions such as MAX(), MIN(), and COUNT_DISTINCT()
  • WHERE clause
  • GROUP BY clause
  • ORDER BY clause

Consider whether you can replace a WHERE clause in a SOQL query with a FIND query in SOSL.

One of the most common problems encountered is the restriction around including encrypted fields in the where clause of a SOQL statement. A SOSL find statement can sometimes be used in lieu of a SOQL statement.

Implementation:

@RestResource(urlMapping='/GetOpportunityFromClientNumber/*')
global with sharing class WebServiceToGetOpportunity {
    /*********************************************************************************
    * @description  use this method to get the Opportunity Id and Opportunity owner id using client number
    * @return       OpportunityWrapper
    *********************************************************************************/
    @HttpGet
    global static void opportunityDetailFromCLientNumber() {
        String strURL = RestContext.request.requestURI;
        String[] strURLSplit = strURL.Split('/');
        // grab the client number the request      
        String clientNumber = strURLSplit[strURLSplit.size()-1];
        OpportunityWrapper oppWrap;
        List<Opportunity> lstOppRecord;
        try {
            //SOSL to retrieve the Account Id on the basis of client number
            List<List<SObject>> lstSobject = [FIND :clientNumber IN ALL FIELDS Returning Account (Id,Client_Number__c)];
            if(lstSobject != null && !lstSobject[0].isEmpty()){
                List<Account> searchAccounts = (List<Account>)lstSobject[0];
                //SOQL to fetch the associated opportunities with the Account Id
                lstOppRecord =  [SELECT Id,Account.Client_Number__c,OwnerId
                                 FROM Opportunity
                                 WHERE AccountId=:searchAccounts[0].Id AND IsWon=false AND LastModifiedDate >= LAST_N_MONTHS:2
                                 ORDER BY CreatedDate DESC LIMIT 1];
             
                if(!lstOppRecord.isEmpty() && lstOppRecord != null){
                    //fill the wrapper with Opportunity Id and Opportunity owner corporate key
                    oppWrap = new OpportunityWrapper(lstOppRecord[0].Id,lstOppRecord[0].OwnerId);
                    RestContext.response.responseBody = Blob.valueOf(oppWrap);
                }else{
                    //Exception when No Opportunity exist with Client Number in Salesforce'
                    createExceptionResponse(404,'NOT_FOUND','No Opportunity exist with Client Number '+clientNumber+' in Salesforce');
                }
            }else{
                //Exception when Client Number not exist in Salesforce'
                createExceptionResponse(404,'NOT_FOUND','Client Number '+clientNumber+' not exist in Salesforce');
            }       
        }catch(Exception e){ createExceptionResponse(500,'BAD_REQUEST',e.getMessage());} //something else happened                             
    }
 
    /*********************************************************************************
    * @description  use this method to create the RestContext Exception
    *********************************************************************************/
    global static void createExceptionResponse(Integer sfStatusCode,String sf_ErrorCode,String sf_Message){
        RestContext.response.statusCode = sfStatusCode;
        SalesforceError[] errs = new SalesforceError[]{ new SalesforceError(sf_ErrorCode, sf_Message)};
            RestContext.response.responseBody = Blob.valueOf(JSON.serialize(errs));
        system.debug('RestContext'+JSON.serialize(errs)); 
    }
 
    /*********************************************************************************
    * @description  use this class to serilize opportunity id and OwnerId
    *********************************************************************************/
    global class OpportunityWrapper{
        public String sf_OpportunityId;
        public String sf_OpportunityOwnerId;
     
        public OpportunityWrapper(String sf_OpportunityId,String sf_OpportunityOwnerId){
            this.sf_OpportunityId=sf_OpportunityId;
            this.sf_OpportunityOwnerId=sf_OpportunityOwnerId; 
        }
    } 
    /*********************************************************************************
    * @description  use this class to serilize the salesforce error response structure
    *********************************************************************************/ 
    global class SalesforceError {
        public String errorCode;
        public String message;
        public SalesforceError(String errorCode, string message){
            this.errorCode = errorCode;
            this.message = message;
        }
    }
}

Output:

No comments:

Post a Comment