• Christi Kane gobucks
  • NEWBIE
  • 20 Points
  • Member since 2020
  • Developer II
  • YRCW

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 3
    Questions
  • 5
    Replies
I am in visual flow, and creating a formula, based on sales channel criteria, to put in the appropriate email (currently in sandbox they are all my emails). It keeps telling me the syntax is invalid. Help! TIA.

IF({!UserSalesChannel}<>"Local",
CASE({!UserSalesChannel},
          “Corporate”, "ckane606@comcast.net",
          “3PL”, "christi.kane16@gmail.com",
          “HNRY”, "christimkane@gmail.com",
          “YRCW”, "alyssa112277@gmail.com",
           "christi.kane@yrcw.com"),
IF({!UserSalesChannel}="Local",
CASE({!UserDivision},
“1”, "ckane606@comcast.net",
“2”, "christi.kane16@gmail.com",
“3”, "christimkane@gmail.com",
“4”, "alyssa112277@gmail.com",
"Christi.kane@yrcw.com"), “Christi.kane@yrcw.com))
 
Our partner only covered 60% of the code before they were furloughed (COVID stuff). I see that the exeptions weren't covered. Below is the controller class and then the test class as it exists now. I'm stumped how to add to it to catch the exceptions.
CLASS:
public class wv6_TruckloadQuoteController{
    
    public static FINAL String QMP_GETQUOTE_ENDPOINT = 'api/csm/sls/qmb/v1/basicQuotes';
    public static FINAL Integer TIMEOUT_VAL =120000;//120000;
    public static FINAL String STR_QMB_GETQUOTE_METHOD = 'GET';
    public static FINAL String CONTENT_TYPE = 'Content-Type';
    public static FINAL String APPLICATION_JSON = 'application/json';
    public static FINAL String STR_ENVIRONMENT ='environment';
    public static FINAL String STR_ACCEPT ='Accept';
    public static FINAL String STR_AUTHORIZATION = 'Authorization';
    public static FINAL String STR_BASIC = 'BASIC';
    public static FINAL String STR_GENERATE_QUOTE_BOOLEAN = 'True';
    
    // method used to make callout and get the response
    @auraEnabled
    public static wv6_BasicQuotesResult fetchDataOnSubmit(Quote__c quoteObj){
        system.debug('quoteObj>>'+quoteObj);
        String customerName = '';
        if(quoteObj != null){
            if(quoteObj.Account__c != null){
                customerName = [select name from account where id =: quoteObj.Account__c limit 1].name;
            }
        }
        //make callout to get data. have used 'Get Quote -- The Big Bambino' params mentioned in Quotey Mcboaty API docs.
        API_Endpoints__mdt endpointDetails = RestAPIUtils.getAPI_EndpointsFromMetadata('ESB',null);
        if(endpointDetails==null || endpointDetails.Endpoint_URL__c=='')
            throw new AuraHandledException('No API Details found from metadatatype.');
        HttpRequest request = new HttpRequest();
        string paramStr = '/?';
        
        paramStr += 'orig_zip=' + quoteObj.Origin_Postal_Code_Text__c  ;
        paramStr += '&'+ 'dest_zip='+ quoteObj.Destination_Postal_Code_Text__c ;
        paramStr += '&'+ 'weight='+ quoteObj.Weight__c ;
        paramStr += '&'+ 'miles='+ quoteObj.Miles__c ; // need to check the value
        system.debug('miles--->'+quoteObj.Miles__c);
        //paramStr += '&'+ 'user_id='+ 3 ; // need to check the value
        //paramStr += '&'+ 'ae_id='+ 1000 ; // need to check the value
        paramStr += '&'+ 'pickup_date='+ String.valueOf(quoteObj.Pickup_Date__c);//'2019-01-06' ;
        //paramStr += '&'+ 'customer_name='+ customerName ;
        paramStr += '&'+ 'generate_quote_id='+STR_GENERATE_QUOTE_BOOLEAN;
        
        system.debug('paramStr>>'+paramStr);
        request.setHeader(STR_ENVIRONMENT, endpointDetails.ESB_Environment__c);
        request.setHeader(CONTENT_TYPE, APPLICATION_JSON);
        request.setTimeout(TIMEOUT_VAL);
        Blob headerValue = Blob.valueOf(endpointDetails.Username__c + ':' + endpointDetails.Password__c);
        String authorizationHeader = STR_BASIC+' ' + EncodingUtil.base64Encode(headerValue);
        request.setHeader(STR_AUTHORIZATION, authorizationHeader);
        request.setHeader(STR_ACCEPT, APPLICATION_JSON);
        request.setEndpoint(endpointDetails.Endpoint_URL__c + QMP_GETQUOTE_ENDPOINT + paramStr);
        request.setMethod(STR_QMB_GETQUOTE_METHOD);
        
        Http h = new Http();
        
        HTTPResponse response;
        system.debug('req>>'+request);
        try{
            response = h.send(request);
        }catch(Exception e){
            throw new AuraHandledException('Callout Error: There was an error retrieving your quote. Please call HNRY for a quote.   '  
                                           +e.getMessage()+'  '
                                           + e.getStackTraceString());
            
        }
        // Parse the JSON response
        if(response <> null){
            if (response.getStatusCode() != 200) {
                System.debug('The status code returned was not expected: ' +
                             response.getStatusCode() + ' ' + response.getStatus());
                throw new AuraHandledException('Error from Endpoint:'+response.getStatusCode()+' '
                                               + response.getStatus());
            } else{
                System.debug('response>>'+response.getBody());
                
                String strResponse = response.getBody();
                System.debug('strResponse==> ' +strResponse);
                
                wv6_BasicQuotesResult quoteResult = wv6_BasicQuotesResult.parse(response.getBody());
                wv6_BasicQuotesResult quoteResultFinal = quoteResult;
                try{
                    String market_codeOrigSTR = '';
                    String market_codeDestSTR = '';
                    
                    //get market codes from A or B or C, whatever is returned for origin
                    if(quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.A <> null && quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.A <> null){
                        market_codeOrigSTR = quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.A.market_code;
                    }else if(quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.C <> null && quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.C <> null){
                        market_codeOrigSTR = quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.C.market_code;
                    }else if(quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.B <> null && quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.B <> null){
                        market_codeOrigSTR = quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.B.market_code;
                    }
                    
                    //get market code from A or B or C, whatever is returned for destination
                    if(quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.A <> null && quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.A <> null){
                        market_codeDestSTR = quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.A.market_code;
                    }else if(quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.C <> null && quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.C <> null){
                        market_codeDestSTR = quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.C.market_code;
                    }else if(quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.B <> null && quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.B <> null){
                        market_codeDestSTR = quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.B.market_code;
                    }
                    
                    
                    // update response JSON marketCode field API names to access dynamically in lightning fo nearby_markets num_loads, num_trucks, etc
                    String strToRemove = '"'+market_codeOrigSTR+'":';
                    String strToReplace = '"'+'mrktNearByOrig'+'":';
                    String strUpdatedResponse = strResponse.replaceFirst(strToRemove,strToReplace);
                    
                    strToRemove = '"'+market_codeDestSTR+'":';
                    strToReplace = '"'+'mrktNearByDest'+'":';
                    String finalResponse = strUpdatedResponse.replaceFirst(strToRemove,strToReplace);
                    
                    quoteResultFinal = wv6_BasicQuotesResult.parse(finalResponse);
                    
                }catch(Exception e){
                    throw new AuraHandledException('Error parsing nearby markets/major metros:'+ e.getMessage());
                }                
                                System.debug('response>>'+quoteResultFinal.basicQuoteOutput.pricing_details.nearby_markets.orig);
                return quoteResultFinal;
            }
        }
        return null;
        
    }
    
    // method used to save Quote .
    @auraEnabled
    public static Id saveQuote(Quote__c quoteObj){
        try{
            insert quoteObj;
            return quoteObj.Id;
        }catch(Exception e){
            throw new AuraHandledException('Error saving Quote Record:'+ e.getMessage());
        }  
    }
    
    //Fetches the user details - profile and public group
    @auraEnabled
    public static userDetails getUserDetails(){
        try{
            userDetails result = new userDetails();
            Id profileId = userinfo.getProfileId();
            result.profileName=[Select Id,Name from Profile where Id=:profileId].Name;
            system.debug('ProfileName'+result.profileName);
            return result;
        }catch(Exception e){
            system.debug('Error in fetching user details:'+ e.getMessage());
            return null;
        }  
    }
    public class userDetails{
        @AuraEnabled public String profileName;
    }
}
//TEST CLASS BELOW:
@isTest
public class wv6_TruckloadQuoteControllerTest {
    @TestSetup static void createTestData(){
        
        
        wv6_TestDataFactory.createAccountRecord();    //create test case & related records
        Account getAccount = [Select Id from Account Limit 1];
        Quote__c quoteTest =new Quote__c();
        quoteTest.Account__c=getAccount.Id;
        insert quoteTest;
    }

    public static testmethod void test_fetchDataOnSubmit(){
        Test.startTest();  
        Quote__c quoteTest = [Select Id,Account__c,Origin_Postal_Code_Text__c,Origin_City__c,Origin_State__c,
                              Destination_Postal_Code_Text__c,Destination_City__c, Miles__c, Destination_State__c,
                              Weight__c,Pickup_Date__c from Quote__c Limit 1];
        Test.setMock(HttpCalloutMock.class, new wv6_TruckLoadQuoteRequestMock());
        wv6_TruckloadQuoteController.fetchDataOnSubmit(quoteTest);
        Test.stopTest();
    }
}
public class wv6_ContactTriggerHandler {

    public static FINAL String STR_PreventDeleteWithoutMerge_ERROR = Label.PreventDeleteWithoutMerge;
    
    public static FINAL Boolean hasPermission = FeatureManagement.checkPermission('Allow_Contact_Deletes');

    public static void checkDeletePermissions(List<Contact> contactList, Map<Id,Contact> oldContactMap){
        
        if(hasPermission) // user is authorized to delete without using Merge
            return;
        
        for(Contact c : oldContactMap.values()){
            if(!Test.isRunningTest() && c.MasterRecordId == null){
                c.addError(STR_PreventDeleteWithoutMerge_ERROR);                  
            }
        }
        
    }
}
I am in visual flow, and creating a formula, based on sales channel criteria, to put in the appropriate email (currently in sandbox they are all my emails). It keeps telling me the syntax is invalid. Help! TIA.

IF({!UserSalesChannel}<>"Local",
CASE({!UserSalesChannel},
          “Corporate”, "ckane606@comcast.net",
          “3PL”, "christi.kane16@gmail.com",
          “HNRY”, "christimkane@gmail.com",
          “YRCW”, "alyssa112277@gmail.com",
           "christi.kane@yrcw.com"),
IF({!UserSalesChannel}="Local",
CASE({!UserDivision},
“1”, "ckane606@comcast.net",
“2”, "christi.kane16@gmail.com",
“3”, "christimkane@gmail.com",
“4”, "alyssa112277@gmail.com",
"Christi.kane@yrcw.com"), “Christi.kane@yrcw.com))
 
public class wv6_ContactTriggerHandler {

    public static FINAL String STR_PreventDeleteWithoutMerge_ERROR = Label.PreventDeleteWithoutMerge;
    
    public static FINAL Boolean hasPermission = FeatureManagement.checkPermission('Allow_Contact_Deletes');

    public static void checkDeletePermissions(List<Contact> contactList, Map<Id,Contact> oldContactMap){
        
        if(hasPermission) // user is authorized to delete without using Merge
            return;
        
        for(Contact c : oldContactMap.values()){
            if(!Test.isRunningTest() && c.MasterRecordId == null){
                c.addError(STR_PreventDeleteWithoutMerge_ERROR);                  
            }
        }
        
    }
}
Hi, I'm starting a specific post for this topic. 

I'm getting the following message on step 9. 

Challenge Not yet complete... here's what's wrong: 
The 'Opp Stage by Adventure' report does not appear to be configured correctly. Make sure it has the correct report type, groupings, filters and chart type.

It is ironic to get to the end and get stuck on charts which I do all the time. :) Ok, here are the instructions:

Give sales reps a visual indicator to compare product performance. First, create a summary report on opportunities named Opp Stage by Adventure. Filter it by Product Date within the past year. For the purpose of this superbadge, assume this date range is 1/1/2026-12/31/2026. Second, add a stacked vertical bar chart of the number of explorers by product name, grouped by stage, to your summary report. Finally, add this chart to your Lightning Adventure Record Page with the label Adventure Stage Comparison. To ensure that this chart isn’t accidentally displayed to customers, add it to a new section called Adventure Comparison.

And, here is what I have. 

I have a Summary Report of "Opportunities with Adventures". In the data model, each Opportunnity corresponds to 1 Explorer from what I can tell per the data model. I've grouped the report by adventure and stage. I have not grouped by Explorer (which is a Contact Role on each Opportunity). I have tried that though and still got the same error. Note also that I'm using "Adventure Date" instead of Procuct Date per the instructions since Product has been renamed to Adventure. 

Opp Stage by Adventure Report



Chart Editor

In the Lightning Record page for Adventure, I've created a custom tab called "Adventure Comparison" and added in the chart called " Adventure Stage Comparison". I've also tried flipping those names, but I still got the same error. 

Adventure Chart in Lightning Record

Any hints would be appreciated. :)