Search code examples
salesforceadminsalesforce-lightningsalesforce-service-cloud

Salesforce User with a certain profile can only delete contact base on Account.field__c and the user.field__c is the same


Salesforce User with a certain profile can only delete contact base on Account.field__c and the user.field__c is the same.

do you guys have any ideas on how to do this. I need the user to delete a record if the contact records Account.field__c is the same as the users field__c. I have tried a validation rule:

I also give the user's profile a delete access on the contact object.

AND(
OR(
$Profile.Name = "HA Customer Care - External/Agents",
$Profile.Name = "HA Customer Care - Internal"
),
TEXT($User.ps_BookingOfficeID__c) != Account.ps_BookingOffice__r.Name
)

Solution

  • Validation rules don't fire on delete, only insert/update. You need a before delete trigger. Or flow.

    Something like this (except this is just for answer purposes, a proper "pro" solution would have a separate trigger handler class)

    trigger ContactTrigger on Contact(before delete){
        if(Trigger.isBefore && Trigger.isDelete){
            validateDeletes(trigger.old);
        }
        
        public static void validateDeletes(List<Contact> contacts){
            User u = [SELECT Profile.Name, ps_BookingOfficeID__c
                FROM User
                WHERE Id = :UserInfo.getUserId()];
            // These 2 profiles need extra checks when deleting.
            // Anybody else can delete whatever they need.
            Set<String> restricted = new Set<String>('HA Customer Care - External/Agents', 'HA Customer Care - Internal');
            if(!restricted.contains(u.Profile.Name){
                return;
            }
    
            Map<Id, Account> accs = new Map<Id, Account>([SELECT Id
                FROM Account
                WHERE Id IN 
                    (
                        SELECT AccountId 
                        FROM Contact 
                        WHERE Id IN :contacts
                    ) 
                    AND ps_BookingOffice__r.Name != :u.ps_BookingOfficeID__c]);
            for(Contact c : contacts){
                if(c.AccountId == null){
                    c.addError('You can\'t delete this private contact because we can\'t determine which office they would belong to');
                } else if(accs.containsKey(c.AccountId){
                    c.addError('This contact does not belong to your office');
                }
            }
        }
    }