function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Pairin MasonPairin Mason 

Issue - DML not Allowed on CaseTeamMember/ QueueSobject Objects

Hi there,

Is there a way to config permissions allowing users with 'Customer Community User' profile to be able perform DML on the CaseTeamMember object and select info from QueueSobject Objects.  I couldn't find anything that works under the profile 'Object Settings'.

I'm building VF pages that allow external customers to create a new case and add/remove Collaborators into/from their opened cases.

CaseTeamMember newCaseMember = new CaseTeamMember();
		newCaseMember.ParentId = caseId;
		newCaseMember.MemberId = cons[0].Id;
		newCaseMember.TeamRoleId = [SELECT Name, Id FROM CaseTeamRole WHERE Name =: 'Case Member'].Id;
		insert newCaseMember;
QueueSobject cOwner = [Select SobjectType, Queue.Id, Queue.Name, Id From QueueSobject Where Queue.Name =: 'Incoming Cases' limit 1];

Thank you,

 

Best Answer chosen by Pairin Mason
Jason HardyJason Hardy
A couple of different ways you can do it. The easiest is to run the entire class without sharing. To do that, you would initialize your class like this:
public without sharing class myClass{
}
That would be the simple way of doing it, and for short term it should work well; however, the safer approach is to execute certain portions without sharing. 

I have a full utility class that is setup with Objects (Programming objects, not Salesforce objects). The master object "class" is cleverly called "UtilityClass" and there are sub classes that can be initialized again, one of them is setup without sharing, and I do DML that a particular user might not have access to via that class. Might be a bit advanced for you, but here is the outline if you should choose to use it later:
/**
 * @author: Jason Hardy 
 * @description: This class will contain reusable methods
 **/
global virtual class UtilityClass
{
	public virtual class utilityMethods
	{
		/**
		 * @author Jason Hardy
		 * @description Attempts a DML operation such as inserts, deletes, etc.
		 * @param dmlsobject the DML objects that are going to be used in the operation
		 * @param operationType The type of operation (e.g. insert)
		 * @return List of sobjects after the operation
		 */
		public list<sObject> attemptDML(list<sObject> records, String operationType)
		{
			try
			{
				if(operationType.equalsIgnoreCase('insert'))
				{
					insert records;
				}
				if(operationType.equalsIgnoreCase('update'))
				{
					update records;
				}
				if(operationType.equalsIgnoreCase('upsert'))
				{
					update records;
				}
				if(operationType.equalsIgnoreCase('delete'))
				{
					delete records;
				}
			}
			catch(Exception e)
	    	{
	    		system.debug(LoggingLevel.Error,e);
	    		system.debug(LoggingLevel.Error,e.getMessage());
	    		system.debug(LoggingLevel.Error,e.getStackTraceString());
	    		system.debug(LoggingLevel.Error,records);
	    		records.clear();
	    	}
			return records;
		}
	
	/**
	 * @author: Jason Hardy
	 * @description: This class contains methods that will allow methods to be executed without sharing
	 **/
	public without sharing class utilityMethodsNoSharing extends UtilityMethods
	{		
		/**
		 * @author Jason Hardy
		 * @description This method will attempt to carryout dml operations without sharing
		 * @param records The records that will be processed
		 * @param operationType What kind of operation will take place on the records 
		 * @return List of sobjects after the operation
		 **/
		public list<sObject> attemptDMLWithoutSharing(list<sObject> records, String operationType)
		{
			if(!records.isEmpty())
			{
				system.debug(LoggingLevel.Error,'# Records to insert:'+records.size());
				system.debug(LoggingLevel.Error,'sObject type:'+records[0].getSObjectType());
				return attemptDML(records,operationType);
			}
			else
			{
				return new list<sObject>();
			}
		}
	}
}
Here is the way you would initalize it and use it:
UtilityClass.utilityMethodsNoSharing umns = new UtilityClass.utilityMethodsNoSharing();
CaseTeamMember newCaseMember = new CaseTeamMember();
		newCaseMember.ParentId = caseId;
		newCaseMember.MemberId = cons[0].Id;
		newCaseMember.TeamRoleId = [SELECT Name, Id FROM CaseTeamRole WHERE Name =: 'Case Member'].Id;
        umns.attemptDMLWithoutSharing((new CaseTeamMember []{newCaseMember}),'insert');
Again this might be over kill for what you've described right now.

All Answers

Jason HardyJason Hardy
A couple of different ways you can do it. The easiest is to run the entire class without sharing. To do that, you would initialize your class like this:
public without sharing class myClass{
}
That would be the simple way of doing it, and for short term it should work well; however, the safer approach is to execute certain portions without sharing. 

I have a full utility class that is setup with Objects (Programming objects, not Salesforce objects). The master object "class" is cleverly called "UtilityClass" and there are sub classes that can be initialized again, one of them is setup without sharing, and I do DML that a particular user might not have access to via that class. Might be a bit advanced for you, but here is the outline if you should choose to use it later:
/**
 * @author: Jason Hardy 
 * @description: This class will contain reusable methods
 **/
global virtual class UtilityClass
{
	public virtual class utilityMethods
	{
		/**
		 * @author Jason Hardy
		 * @description Attempts a DML operation such as inserts, deletes, etc.
		 * @param dmlsobject the DML objects that are going to be used in the operation
		 * @param operationType The type of operation (e.g. insert)
		 * @return List of sobjects after the operation
		 */
		public list<sObject> attemptDML(list<sObject> records, String operationType)
		{
			try
			{
				if(operationType.equalsIgnoreCase('insert'))
				{
					insert records;
				}
				if(operationType.equalsIgnoreCase('update'))
				{
					update records;
				}
				if(operationType.equalsIgnoreCase('upsert'))
				{
					update records;
				}
				if(operationType.equalsIgnoreCase('delete'))
				{
					delete records;
				}
			}
			catch(Exception e)
	    	{
	    		system.debug(LoggingLevel.Error,e);
	    		system.debug(LoggingLevel.Error,e.getMessage());
	    		system.debug(LoggingLevel.Error,e.getStackTraceString());
	    		system.debug(LoggingLevel.Error,records);
	    		records.clear();
	    	}
			return records;
		}
	
	/**
	 * @author: Jason Hardy
	 * @description: This class contains methods that will allow methods to be executed without sharing
	 **/
	public without sharing class utilityMethodsNoSharing extends UtilityMethods
	{		
		/**
		 * @author Jason Hardy
		 * @description This method will attempt to carryout dml operations without sharing
		 * @param records The records that will be processed
		 * @param operationType What kind of operation will take place on the records 
		 * @return List of sobjects after the operation
		 **/
		public list<sObject> attemptDMLWithoutSharing(list<sObject> records, String operationType)
		{
			if(!records.isEmpty())
			{
				system.debug(LoggingLevel.Error,'# Records to insert:'+records.size());
				system.debug(LoggingLevel.Error,'sObject type:'+records[0].getSObjectType());
				return attemptDML(records,operationType);
			}
			else
			{
				return new list<sObject>();
			}
		}
	}
}
Here is the way you would initalize it and use it:
UtilityClass.utilityMethodsNoSharing umns = new UtilityClass.utilityMethodsNoSharing();
CaseTeamMember newCaseMember = new CaseTeamMember();
		newCaseMember.ParentId = caseId;
		newCaseMember.MemberId = cons[0].Id;
		newCaseMember.TeamRoleId = [SELECT Name, Id FROM CaseTeamRole WHERE Name =: 'Case Member'].Id;
        umns.attemptDMLWithoutSharing((new CaseTeamMember []{newCaseMember}),'insert');
Again this might be over kill for what you've described right now.
This was selected as the best answer
Pairin MasonPairin Mason
Thank you very much Jason for such a quick response and well-explained example.