-1

I need to write a trigger which should be fired based on prior value of a field:

I have three custom objects:

  • Call__c -- is Master object
  • Call_Objective__c -- detail object to Call__c
  • Call_Asset__c -- detail object to Call__c

In Call__c I have a picklist field called Status__c which have values like "In Progress", "Not Started" and "Complete".

My requirement is,

I will set the status of a Call record as "Complete". Next time if a user tries to create/Edit/Delete the Call Objectives or Call Assets(details of the Call__c object) he should get an error like " Call is already completed, you should not modify/Delete the Detail records".

Here is the code:

trigger CallPlanObjProtectionTrigger on Call_Objective__c (before insert, before update, before delete) {

  for(Call_Objective__c CO : trigger.new) { 

    if(trigger.isDelete){ 

      if(Trigger.oldMap.get(CO.Id).Call_Status__c == 'Complete') { 

        CO.addError('Call Status Completed. Should not delete Call Object'); 

      } 
    } 
  } 
}

Thanks in Advance

  • Please post what you have tried so far. – AslamK Nov 12 '15 at 7:07
  • welcome to the SFDC community. prior to asking the question please go through the how to ask a good question in help section. this community is all about helping you what you are missing with your current code. you need to share your current implementation. This community is not all about reading the requirements and write the code for you. we can guide you for your existing code but we can't write code for you. – Himanshu Nov 12 '15 at 8:05
  • Here is the code I have tried till now. But I am getting error even at the time of changing status to Complete. But I need to throw the error only after Status set to Complete once. trigger CallPlanObjProtectionTrigger on Call_Objective__c (before insert, before update, before delete) { for(Call_Objective__c CO : trigger.new) { if(trigger.isDelete){ if(Trigger.oldMap.get(CO.Id).Call_Status__c == 'Complete') { CO.addError('Call Status Completed. Should not delete Call Object'); } } } } – chaitanya sfdc Nov 12 '15 at 8:13
  • Are you trying to check the Call_Status__c field on the Call_Objective__c record or its parent Call__c record as per your posted question? Here it seems you are checking the Call_status__c value of the Call_0bjective__c itself. – AslamK Nov 12 '15 at 8:56
  • I made some edits to the question, including: making the title more descriptive. In general "I need to do x with a trigger" is not going to help you find an answer, or help others after you use the answers to their benefit. I also pasted the code from your comment into the question. Please read the help topic How to Ask for guidance on asking questions here. And welcome! salesforce.stackexchange.com/help/how-to-ask – pchittum Nov 12 '15 at 9:17
2

The typical way to handle editing/deleting a record would be to use the sharing model, or what is also sometimes referred to as record-level security.

Record access has 5 types of permission.

  • View
  • Edit
  • Share
  • Transfer Ownership
  • Delete

I remember these by the acronym VESTD.

The owner of the record is VESTD and can perform all of these actions (depending on their object permissions of course. If their profile does not grant Delete perms, they cannot delete, for instance. You can also make a queue be an owner. If a queue is an owner, then every user that is member of the queue is VESTD.

Finally, if you're not the owner, the most you will ever be able to do with that record is View and Edit. Share, Delete, and Transfer Ownership are always only reserved for Owner.

You can also go to Setup > Security > Sharing Settings and set the organization wide default sharing for an object. Custom objects support three levels: Private, Public Read-only, and Public Read/Write.

Finally, administrators always have full access to data in the org. Their only restriction for data visibility is field security and encrypted fields. But that doesn't apply here.

So taking all that in, here is how I would use this no-code solution to solve your problem.

  1. Set the org-wide default sharing for Call__c to Public Read-only.
  2. Create a new queue called Call is Complete. Add no users to the queue.
  3. Create a workflow rule to do the following so that when Call__c is saved and Status__c is Complete, the Call is Complete queue is set in the Owner field.

This will prevent anyone from editing or deleting the Call__c record or either of its children once the "Complete" value is set in the Status__c field.

Note: because of making Call_Objective__c and Call_Asset__c related to Call__c with master-detail relationships, you cannot use the sharing model to only set those to be editable or not. They will always follow the sharing permissions of the parent record. So to use the sharing model independently on these children, you would need to change the relationships to Lookup relationships. But don't take that step lightly.

I would advise you to do a lot more reading on the sharing model. It is purpose built for exactly what you are trying to do. Even if this solution won't work, trying to build anything in Force.com without understanding sharing will make you solve problems in ways you shouldn't. Start here. Then go to salesforce help and search for "sharing" and read as much as you can. There are also several articles and white papers on sharing in the salesforce developer portal.

For more on understanding relationships, this isn't a bad page to read.

Sharing and relationships go hand in hand, so you will need to understand them both to solve your problem in the best possible way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.