Showing posts with label SOSL. Show all posts
Showing posts with label SOSL. Show all posts

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: