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
Linas ZiciusLinas Zicius 

prevent from deleting contact if it has assets

Hi developers,
I was wondering is it possible to prevent from deleting contact record if it has assets related to it? Success community says that trigger is an option. If trigger is the only option, could you help me with that?
Thanks a ton.

Best Answer chosen by Linas Zicius
Jainam ContractorJainam Contractor

 
Hi Linas,

I assume the Contact Lookup API name is Contact__c. Try the below code and let me know if it works
 
trigger DontDeleteContact on Contact (before delete) {
    Set<Id> ConId = Trigger.OldMap.keyset();
    //map<Id, List<sObject>> IDListMap = new map<Id, List<sObject>>();
    /*for(Contact C : Trigger.Old){
        ConId.add(C.Id);
    }*/
    List<Asset> AssetList = [select id, name, contactid from Asset where contactid IN :ConId];
    List<Order> OrderList = [select id, Contact__c from Order WHERE Contact__c IN :ConId];
    for(Contact C : Trigger.Old){
        if(AssetList != NULL && AssetList.size() >0){
            for(Asset A : AssetList){
                if(C.Id == A.contactid){
                    C.addError('Contact have an existing related Asset. Hence it can not be deleted');
                }
            }
        }
        if(OrderList != NULL && OrderList.size() > 0){
            for(Order O : OrderList){
                if(C.Id == O.Contact__c){
                    C.addError('Contact have an existing related Order. Hence it can not be deleted');
                }
            }
        }   
    }
}

Please let me know if it works. Mark it as the best asnwer if it solved your problem.

Thanks,
Jainam Contractor,
Salesforce Consultant,
Varasi LLC
www.varasi.com
 

All Answers

Jainam ContractorJainam Contractor
Hi Linas,

Understood your roadblock. Can you please check the below code and let me know if it helps.
 
trigger DontDeleteContact on Contact (before delete) {
    list<Id> ConId = new list<Id>();
    map<Id, List<sObject>> IDListMap = new map<Id, List<sObject>>();
    for(Contact C : Trigger.Old){
        ConId.add(C.Id);
    }
    for(Asset A : [select id, name, contactid from Asset where contactid IN :ConId]){
        for(Contact C : Trigger.Old){
            if(C.Id == A.contactid){
                c.addError('Contact have an existing related Asset. Hence it can not be deleted');
            }
        }
    }
}

Please let me know if i was able to remove the roadbloack for you. Please mark it as a solution if it solved the purpose.

Thanks & Regards,
Jainam Contractor,
Salesforce Consultant,
Varasi LLC
www.varasi.com
Linas ZiciusLinas Zicius

Hi Jainam,

Sorry for late reply. Thanks a lot for your help, I will try this and will get back to you.

Thanks again, Linas

Linas ZiciusLinas Zicius

Dear Jainam,

wow, thanks a ton, works like a charm! Could you help a little bit more, I need the same functionality just if the contact has any Orders, than it cannot be deleted as well. The whole idea is that if the Contact has Orders or/and Assets ir cannot be deleted. 

Thank you very much in advance.
Linas

Jainam ContractorJainam Contractor
Hi Linas,

Please check the below code and let me know if it works for you...
 
trigger DontDeleteContact on Contact (before delete) {
    Set<Id> ConId = Trigger.OldMap.keyset();
    //map<Id, List<sObject>> IDListMap = new map<Id, List<sObject>>();
    /*for(Contact C : Trigger.Old){
        ConId.add(C.Id);
    }*/
    List<Asset> AssetList = [select id, name, contactid from Asset where contactid IN :ConId];
    List<Order> OrderList = [select id, BillToContactId, CustomerAuthorizedById, ShipToContactId from Order WHERE 
                             ShipToContactId IN :ConId OR BillToContactId IN :ConId OR CustomerAuthorizedById IN :ConId];
    for(Asset A : AssetList){
        for(Order O : OrderList){
            for(Contact C : Trigger.Old){
                if(C.Id == A.contactid){
                    C.addError('Contact have an existing related Asset. Hence it can not be deleted');
                }
                if(C.Id == O.BillToContactId || C.Id == O.CustomerAuthorizedById || C.Id == O.ShipToContactId){
                    C.addError('Contact have an existing related Order. Hence it can not be deleted');
                }
            }
        }
    }
}

Please mark this as the best answer if it solved your purpose.

Cheers...!!!:)

Let me know if you need more assistance.

Thanks & Regards,
Jainam Contractor,
Salesforce Consultant,
Varasi LLC
www.varasi.com
Linas ZiciusLinas Zicius
Hi Jainam, hmm, unfortunately this new version is not working... I can delete contact if it has asset or order or both.. :( I have copied and pasted everything like you wrote, and deleted the previous trigger. I really appreciate your help. Linas
Jainam ContractorJainam Contractor
Hi Linas,

I have made some changes to the code. Can you please try that and let me know if it works.
 
trigger DontDeleteContact on Contact (before delete) {
    Set<Id> ConId = Trigger.OldMap.keyset();
    //map<Id, List<sObject>> IDListMap = new map<Id, List<sObject>>();
    /*for(Contact C : Trigger.Old){
        ConId.add(C.Id);
    }*/
    List<Asset> AssetList = [select id, name, contactid from Asset where contactid IN :ConId];
    List<Order> OrderList = [select id, BillToContactId, CustomerAuthorizedById, ShipToContactId from Order WHERE 
                             ShipToContactId IN :ConId OR BillToContactId IN :ConId OR CustomerAuthorizedById IN :ConId];
    for(Contact C : Trigger.Old){
        if(AssetList != NULL && AssetList.size() >0){
            for(Asset A : AssetList){
                if(C.Id == A.contactid){
                    C.addError('Contact have an existing related Asset. Hence it can not be deleted');
                }
            }
        }
        if(OrderList != NULL && OrderList.size() > 0){
            for(Order O : OrderList){
                if(C.Id == O.BillToContactId || C.Id == O.CustomerAuthorizedById || C.Id == O.ShipToContactId){
                    C.addError('Contact have an existing related Order. Hence it can not be deleted');
                }
            }
        }   
    }
}
Please let me know if it works or you need more assistance.

Mark it as the best answer if it solved your purpose.

Thanks,
Jainam Contractor,
Salesforce Consultant,
Varasi LLC
www.varasi.com
 
Linas ZiciusLinas Zicius
Thanks again Jainam, with this code, it doesn't let me to delete contact if it has asset, but when I delete asset and leave only order in the contact, then it let's me to delete contact. It is the first time I am working with a trigger, so I am not a pro, but as I see you address some fields in order, so I have an assumption, that those fields are empty in our case, I mean we don't use it, so these are the fields which are mandatory in Order record and all those records have these fields filled: Field Label / Field Name (API) / Data Type Account Name / Account / Lookup(Account) Contact / Contact__c / Lookup(Contact) (with controlling field Account) Order Start Date / EffectiveDate / Date Order Number / OrderNumber / Auto Number Status / Status / Picklist Hope my assumption is right and hope it will help. If it is too difficult to address, then we could leave it as is, with only blocking if contact has assets, but it would be very useful and helpful for me to have a full solution. Thank you very much Jainam. BR, Linas
Jainam ContractorJainam Contractor
Hi Linas,

What is the field API name that you are using for Contact on the Order Object. I have assumed you might have used some of the Standard Lookup fields. If there is some Custom field for Lookup between Order and Contact then let me know what it is so that i can help.

And it would be possible in both the Scenario whether there is Asset/ Order we can block user from deleting contact.

Please give the API name of the field used for Contact Lookup on Order.

Thanks,
Jainam Contractor
Jainam ContractorJainam Contractor

 
Hi Linas,

I assume the Contact Lookup API name is Contact__c. Try the below code and let me know if it works
 
trigger DontDeleteContact on Contact (before delete) {
    Set<Id> ConId = Trigger.OldMap.keyset();
    //map<Id, List<sObject>> IDListMap = new map<Id, List<sObject>>();
    /*for(Contact C : Trigger.Old){
        ConId.add(C.Id);
    }*/
    List<Asset> AssetList = [select id, name, contactid from Asset where contactid IN :ConId];
    List<Order> OrderList = [select id, Contact__c from Order WHERE Contact__c IN :ConId];
    for(Contact C : Trigger.Old){
        if(AssetList != NULL && AssetList.size() >0){
            for(Asset A : AssetList){
                if(C.Id == A.contactid){
                    C.addError('Contact have an existing related Asset. Hence it can not be deleted');
                }
            }
        }
        if(OrderList != NULL && OrderList.size() > 0){
            for(Order O : OrderList){
                if(C.Id == O.Contact__c){
                    C.addError('Contact have an existing related Order. Hence it can not be deleted');
                }
            }
        }   
    }
}

Please let me know if it works. Mark it as the best asnwer if it solved your problem.

Thanks,
Jainam Contractor,
Salesforce Consultant,
Varasi LLC
www.varasi.com
 
This was selected as the best answer
Linas ZiciusLinas Zicius

This is absolutelly amazing, works like a charm! Thank you.
As it is first trigger in my life, could you please advise me how to move trigger to production? And how to make code coverage by tests? I know the metadata tools only theoretically.

Thanks so much.

Linas

Jainam ContractorJainam Contractor
Hi Linas,

Can you please close this trail by marking the answer as the solution and start a new trail as the subject of this matter is solved and it should confuse the other community users.

Create a new trail for Deployment and Testing and me or some other community members would help you on the same. This is a developer community best practice.

Please let me know the URL of the new trail and then i can help you on the same.

Thanks,
Jainam Contractor
Linas ZiciusLinas Zicius

Yes, sure, thanks a lot Jainam for your help. Can I post link to this thread in the success community, where I have opened same question and people guided me here?

Linas

Jainam ContractorJainam Contractor
Yes definitely you can do so.

Also you can create a new thread here as well if that doesn't work out.

BR,
Jainam