2

I am getting:

"FATAL_ERROR|System.TypeException: DML operation INSERT not allowed on Group" error on an apex trigger (line 43)

when I am logging in as any other user except System Admin. I am not really sure how to handle CRUD permissions on Group.

trigger CAP_AG_ProjectShare on CAP_AG_Project__c(after insert,after update) {
Set<Group> allGroups = new Set<Group>();
Set<ID> deleteProjectSharesIdSet = new Set<ID>();
List<CAP_AG_Project__share> projectShares = New List<CAP_AG_Project__share>(); 
List<CAP_AG_Project__share> deleteprojectShares = New List<CAP_AG_Project__share>();
map<String,List<Id>> groupToProjectMembers = new map<String,List<Id>>();
map<String,List<Id>> groupToProjectToDelete = new map<String,List<Id>>();
LIST<ID> ownerIdsSet = new LIST<ID>();

for(CAP_AG_Project__c project: trigger.new){
    if(project.CAP_AG_Country__c != Null && project.CAP_AG_Private_Project__c != true){ 
        if(project.CAP_AG_Country__c.trim().length()>0){
            String cleanCountryName = project.CAP_AG_Country__c.trim().left(40);
            String namePrefixedCountryName = ('CTRY_' + cleanCountryName.replace('.','_').replace(' ','_').replace('-','').replace('(','').replace(')','').replace('\'','').replace(',','').replace('__','_')).left(40);
            namePrefixedCountryName=namePrefixedCountryName.removeEnd('_');
            allGroups.add(new Group(DeveloperName=namePrefixedCountryName,Name=('Country - ' + cleanCountryName).left(40)));
            if(!groupToProjectMembers.containsKey(namePrefixedCountryName)){
                groupToProjectMembers.put(namePrefixedCountryName,new List<Id>());
            }
            groupToProjectMembers.get(namePrefixedCountryName).add(project.Id);
        }
    }
    if((Trigger.IsInsert && project.CAP_AG_Private_Project__c == true)
        || (Trigger.IsUpdate && project.CAP_AG_Private_Project__c == true)
        || (Trigger.IsUpdate && !(trigger.oldmap).isEmpty() && trigger.oldmap.get(project.id) != null && trigger.oldmap.get(project.id).CAP_AG_Country__c != null && 
            trigger.oldmap.get(project.id).CAP_AG_Country__c != project.CAP_AG_Country__c)
      )
    {
        ownerIdsSet.add(project.OwnerId);
        deleteProjectSharesIdSet.add(project.id);
    }
}

for(CAP_AG_Project__share projShare: [Select id,UserOrGroupID,ParentId,AccessLevel from CAP_AG_Project__share where ParentId IN: deleteProjectSharesIdSet and UserOrGroupID NOT IN :ownerIdsSet and RowCause = 'Manual'])
{
    deleteProjectShares.add(projShare);
}
if(!deleteProjectShares.isEmpty())
{
    database.delete(deleteProjectShares);
}

***database.upsert(new List<Group>(allGroups),Schema.Group.Name);***
for(Group g:allGroups){
    if(groupToProjectMembers.containsKey(g.DeveloperName)){
        For(Id projectId : groupToProjectMembers.get(g.DeveloperName)){
            projectShares.add(new CAP_AG_Project__share(UserOrGroupID=g.id, ParentId=projectId,AccessLevel='Read'));
        }
    }
}
database.insert(projectShares);
}

Please help me understand where I am going wrong.

1

1 Answer 1

3

Groups are a type of setup object in salesforce with special behavior. Can you try moving the group dml to a future method and see if that does the trick?

I think the issue is that you're doing a delete on line 40, and then doing the insert.

According to the documentation here's what they say about groups:

You can only insert and update a group in a transaction with other sObjects. Other DML operations aren’t allowed.

To read more about setup objects go here

1
  • thank you so much for your response. The actual issue turned out to be a class on Opportunity which was triggering this trigger on Project on update. The method in this class had a future annotation (as it is required to update groups) but it was getting called multiple times resulting in multiple transactions. Fixed it and now the trigger works perfectly.
    – Nishi
    Commented May 29, 2019 at 9:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .