• Sohan Shirodkar
  • NEWBIE
  • 20 Points
  • Member since 2018

  • Chatter
    Feed
  • 0
    Best Answers
  • 3
    Likes Received
  • 0
    Likes Given
  • 12
    Questions
  • 5
    Replies
I came across this (https://help.salesforce.com/articleView?id=sharing_across_objects.htm&type=5)article on built-in sharing. There is a statement which says : 
Salesforce provides implicit sharing between accounts and child records (opportunities, cases, and contacts), and for various groups of portal users.

Although, only opportunities, cases and contacts are mentioned here, does this also apply to child accounts in an account hierarchy? 
I have private OWD on accounts. Will the owner of parent account have access to child accounts which he/she does not own?
I have used case-assignment rules to assign cases automatically to the right user/queue based on certain conditions. 

Recently I was going through Trailhead content on omni-channel and various routing mechanisms (skill based, queue based). Following statement from trailhead confuses me : "Omni-Channel always assigns cases to the right support agents, and customers are happy with customer service. ".

If we already have case-assignment rules in place, why do we need omni-channel queue based routing? How are the two things different?
I am writing a test class for apex schedular which schedules a batch class to send out emails. Following is the code snippet:
Test.startTest();
String CRON = '0 0 9 * * ?';
String jobId = System.schedule('Lead Followup Reminder Emails Schedular', CRON, new LeadFollowupBatchSchedular());
Test.stopTest();
System.debug('After stopTest');
System.assertEquals(3,LeadFollowupBatch.emailCounter);
//LeadFollowupBatch.emailCounter is a @testVisible variable from batch class scheduled by apex, whose value is set within finish() of that batch
As per documentation, schedule apex will run immediately after Test.stopTest() synchronously. In my case, it is running after assert statements, because of which assert statements are failing. 

I have a System.debug() in batch class finish method. The content of that debug statement appears after "After stopTest', which certainly means scheduler class is not scheduled properly. Even if I check the state of scheduled job using jobId, it returns 'Waiting' and not 'Complete'.

 
I am writing a unit test class for batch apex which makes API callout for each record in the batch.

 
Test.setMock(HttpCalloutMock.class, new TestMockHTTpResponseFactory());        
Test.startTest();        
CAS_TW_New batch = new CAS_TW_New();
DataBase.executeBatch(batch,5); 
Test.stopTest();
Integer count = [SELECT Count() FROM ObjectSF WHERE REQUESTFLAG__c = 'Already sent'];
System.assert(count == 30);

This always fails with System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out. This exception occurs when we have a DML operation before making API callout. I have inspected debug logs, but found no such DML.

The batch class only fails in a test class, but perfectly works outside the context of a test class. Any advice would be appreciated.
Email Message records are consuming a lot of storage in my org. If I try to delete through developer console it throws "insufficient access rights on object id" error.

An article here (https://help.salesforce.com/articleView?id=emailadmin_enhanced_email_considerations.htm&type=5) says:
"The email sender and an admin with the appropriate permissions can delete an email message."

Can someone help me understand what is that "appropriate permission" which admins need to delete an Email Message record?
PMD extension in VS Code is reporting this issue:
Validate CRUD permission before SOQL/DML operation

I can handle this by using something of this sort:
if (Schema.sObjectType.Contact.fields.Email.isAccessible()) {
   Contact c = [SELECT Email FROM Contact WHERE Id= :Id];
}

However my codebase is huge and I cannot repeat this snippet everywhere. Also, the number of fields to be checked, similar to Email field, is large.

Hence, I want to write a generic utility method for this which will take as argumet the object name and a set of field names. 
public static Boolean hasFieldReadAccess(String objectName, Set<String> fields){
        Schema.SObjectType obj = Schema.getGlobalDescribe().get(objectName);
        for(String field: fields){
            Schema.SObjectField sObjectField = obj.getDescribe().fields.getMap().get(field);
            if(!sObjectField.getDescribe().isAccessible()){
                return false;
            }
        }
        return true;
    }
However, when I call this method at the lin where PMD reports issue, it does not show it as resolved. Even if I directly include the following line, the issue is not resolved:
if(Schema.getGlobalDescribe().get('Contact').getDescribe().fields.getMap().get('Email').getDescribe().isAccessible()){
 //SOQL here
}

Any idea what is going wrong here? Does PMD only recognize the first code snippet for resolving the issue?

 
<lightning:treeGrid aura:id="accountsTreeComponent"
                    columns="{!v.gridColumns}"
            	    data="{!v.gridData}"
                    keyField="accountId"
                    expandedRows="{! v.gridExpandedRows }"
                    isLoading="{! v.isLoading }"
                    ontoggle="{! c.handleRowToggle }"
                    onrowselection="{!c.onRowSelection}"/>

This is how I am using treegrid component.

When I expand a treegrid row, and then collapse it, automatically onrowselection event is fired, which calls onRowSelection action handler in JS controller.

I have made an important observation. This issue occurs in the following scenario:
1) Expand a row (onrowtoggle fired)
2) Select a child row(onrowselection fired)
3) Collapse the parent row (onrowtoggle fired + onrowselection fired)
I believe step 3 internally deselects the child row selected in step 2 which results in firing of onrowselect event. This is certainly a faulty behaviour.

How can I prevent this or at least handle it?
I could not find anything in the documentation on this topic.

The scenario is as follows. I have a 3 step approval process, second step of which is conditionally dependent on a picklist Priority. It states "if Priority value is High then enter this approval step, else proceed to next step". A record with High priority value submiited for approval and is currently pending for approval at step 1.

Now, I replace High value with value 1. Then, I also update the step 2 condition of approval process with value 1. Replacing a value globally replaces that field value on all existing records. My question is, what will be the effect on above record under approval? Will it proceed to step 2 with new replaced value i.e. 1?
I have an HTML Email Template containing two merge fields at the end: 
[{!Case.Thread_Id}]

{!EmailMessage.TextBody}

When I reply to an email and select this email template, it resolves the thread id part properly.

But when the email is actually sent, the thread_id merge field is empty. Outlook shows the thread id right at the bottom of the email, oustide the email template body.

What am I doing wrong?

FYI, the plain text version of the template is copied over from HTML version. Thread_Id merge field not resolved in HTML email template
I have an HTML Email Template containing two merge fields at the end: 
First question is related to checking "Create" permission on object before creating a record of that object. I have referred this  module on Trailhead in which following code snippet is used for checking Create permission.
if (!Schema.sObjectType.Opportunity.fields.Amount.isCreateable()){
    ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,'Error: Insufficient Access'));
    return null;
  }
  Opportunity o = new Opportunity(Amount=500);
  insert o;
They have just checked for "Amount" field's create permission which implicitly checks for Opportunity object create permission. But what if we have a long list of fields on Opportunity object which are assigned during object creation. Are we going to check for each one of them in the if statement? It is absolutely unrealistic. How do we implement this check in real world?

Same thing also applies to isAccessible() method. Please recommend me how to implement these checks for a long list of fields in real world scenarios.
 
I am testing my POST REST API service in apex. 
​​​​ RestRequest request = new RestRequest();
 request.requestURI = MY_API_ENDPOINT;
 request.httpMethod = 'POST';
 request.addHeader('Content-Type', 'application/json');
 String jsonBody = '<some_json_here>';
 request.requestBody = Blob.valueOf(jsonBody);

 RestContext.request = request;

/*
 * assertions here
*/
The json string I will be using is lengthy. I can simply form a string inline in the code by use '+' operator repetatively. But what is the best way of doing this?
 
I have built a REST API POST service in apex. The way I am deserializing the recieved JSON request is as follows.
RestRequest request = RestContext.request;
String jsonBody = request.requestBody.toString();
jsonBody = String.escapeSingleQuotes(jsonBody);

MyDataClass data = (myDataClass )System.JSON.deserialize(jsonBody, MyDataClass.class);
Issue over here is that, if the JSON contains any key having value containing double-quotes(") or backslashes(\), the deserialization fails and I get an error response. When using POSTMAN, this is not a hurdle because POSTMAN immediately shows an error on the UI for such key-value pairs and doesn't allow us to make a request. But if we are making a call through code then this is problametic. 

I am currently using String.escapeSingleQuotes(), but not sure if this is of any use here.

Can I use replaceAll method as follows to escape all backslashes?:
jsonBody.replaceALl('\\','\\\\');
If so can I use a similar way to escape all double-quotes?
I have used case-assignment rules to assign cases automatically to the right user/queue based on certain conditions. 

Recently I was going through Trailhead content on omni-channel and various routing mechanisms (skill based, queue based). Following statement from trailhead confuses me : "Omni-Channel always assigns cases to the right support agents, and customers are happy with customer service. ".

If we already have case-assignment rules in place, why do we need omni-channel queue based routing? How are the two things different?
<lightning:treeGrid aura:id="accountsTreeComponent"
                    columns="{!v.gridColumns}"
            	    data="{!v.gridData}"
                    keyField="accountId"
                    expandedRows="{! v.gridExpandedRows }"
                    isLoading="{! v.isLoading }"
                    ontoggle="{! c.handleRowToggle }"
                    onrowselection="{!c.onRowSelection}"/>

This is how I am using treegrid component.

When I expand a treegrid row, and then collapse it, automatically onrowselection event is fired, which calls onRowSelection action handler in JS controller.

I have made an important observation. This issue occurs in the following scenario:
1) Expand a row (onrowtoggle fired)
2) Select a child row(onrowselection fired)
3) Collapse the parent row (onrowtoggle fired + onrowselection fired)
I believe step 3 internally deselects the child row selected in step 2 which results in firing of onrowselect event. This is certainly a faulty behaviour.

How can I prevent this or at least handle it?
I am writing a test class for apex schedular which schedules a batch class to send out emails. Following is the code snippet:
Test.startTest();
String CRON = '0 0 9 * * ?';
String jobId = System.schedule('Lead Followup Reminder Emails Schedular', CRON, new LeadFollowupBatchSchedular());
Test.stopTest();
System.debug('After stopTest');
System.assertEquals(3,LeadFollowupBatch.emailCounter);
//LeadFollowupBatch.emailCounter is a @testVisible variable from batch class scheduled by apex, whose value is set within finish() of that batch
As per documentation, schedule apex will run immediately after Test.stopTest() synchronously. In my case, it is running after assert statements, because of which assert statements are failing. 

I have a System.debug() in batch class finish method. The content of that debug statement appears after "After stopTest', which certainly means scheduler class is not scheduled properly. Even if I check the state of scheduled job using jobId, it returns 'Waiting' and not 'Complete'.

 
Email Message records are consuming a lot of storage in my org. If I try to delete through developer console it throws "insufficient access rights on object id" error.

An article here (https://help.salesforce.com/articleView?id=emailadmin_enhanced_email_considerations.htm&type=5) says:
"The email sender and an admin with the appropriate permissions can delete an email message."

Can someone help me understand what is that "appropriate permission" which admins need to delete an Email Message record?
Hi,

I am working with a lightning:treegrid component.
The onrowselection attribute of lightning:treegrid invokes a method on js controller whenever a row is selected/deselected.
I am able to fetch the currently selected rows using the getSelectedRows() method.
But if I deselect a row, I am not able to find its Id or row data (which is deselected) in the js controller.

Aura:
<lightning:treeGrid columns="{!v.gridColumns}"
                                    data="{!v.gridData}"
                                    keyField="idRef"
                                    aura:id="productTree"
                                    expandedRows="{! v.gridExpandedRows }"
                                    onrowselection="{! c.getSelectedRows}"
                                    ontoggle = "{!c.handleToggle}"
                                    selectedRows = "{!v.selectedIds}"
                                    isLoading="{! v.isLoading }"
                                    />

JS:
getSelectedRows: function(cmp, event, helper) {
       //get selected rows
        var curRows = event.getParam('selectedRows');

       //how to get the row that is deselected
    }

Can anyone please help?

Regards,
Nidhi Sharma
I could not find anything in the documentation on this topic.

The scenario is as follows. I have a 3 step approval process, second step of which is conditionally dependent on a picklist Priority. It states "if Priority value is High then enter this approval step, else proceed to next step". A record with High priority value submiited for approval and is currently pending for approval at step 1.

Now, I replace High value with value 1. Then, I also update the step 2 condition of approval process with value 1. Replacing a value globally replaces that field value on all existing records. My question is, what will be the effect on above record under approval? Will it proceed to step 2 with new replaced value i.e. 1?