0
public static void hireContactForm(List < HireForm__c > HireList) {
 List < Contact > contList = new List < Contact > ();
 List < Case > CaseList = new List < Case > ();
 //List<HireForm__c> hireInsertList = new List<HireForm__c>();

 for (HireForm__c hireForm: HireList) {
  if (hireForm.status__c == 'In Progress') {
   Contact con = new Contact();
   con.FirstName = hireForm.First_Name__c;
   con.LastName = hireForm.Last_Name__c;
   con.Phone = hireForm.Phone__c;
   con.Email = hireForm.Email__c;

   contList.add(con);
   //hireForm.Candidate__c = con.id;
  } else {
   hireForm.addError('Select "In Progress" first, then try again');
  }
 }
 insert contList;
 Integer i = 0;
 for (HireForm__c hr: hireList) {
  if (hr.status__c == 'In Progress') {
   hr.Candidate__c = contList[i].id;
  }
 }
 for (Contact cont: contList) {
  Case cases = new Case();
  cases.Status = 'New';
  cases.ContactId = cont.Id;
  caseList.add(cases);
 }
 insert caseList;
}

public static void hireContactFormForUpdate(List < HireForm__c > HireListNew) {
 set < id > contactIdSet = new set < id > ();
 for (HireForm__c hire: HireListNew) {
  contactIdSet.add(hire.Candidate__c);
 }
 List < Case > CaseList = [select id, ContactId from
  case where ContactId in: contactIdSet
 ];
 for (HireForm__c hire: HireListNew) {
  for (Case caseStatus: CaseList) {
   if (hire.Candidate__c == caseStatus.ContactId && hire.status__c == 'Completed') {
    caseStatus.Status = 'Closed';
   }
   update caseStatus;
  }
 }
}

public static void caseUpdate(List < Case > caseList) {
 Set < id > caseIds = new Set < id > ();
 Set < id > candIds = new Set < id > ();

 for (Case c: caseList) {
  caseIds.add(c.ContactId);
 }
 for (HireForm__c hireList: [Select candidate__c
   from HireForm__c
   where candidate__c in: caseIds
   and status__c = 'Completed'
  ]) {

  candIds.add(hireList.Candidate__c);
 }
 for (Case updateCaseList: caseList) {
  if (updateCaseList.ContactId != NULL) {
   if (!candIds.contains(updateCaseList.ContactId)) {
    if (updateCaseList.Status == 'Closed') {
     updateCaseList.addError('You can not close the case until hire form is completed');
    }
   }
  }
 }
}

//Trigger
trigger ContactFormTrigger on HireForm__c(before insert, before update) {
 if (Trigger.isBefore && Trigger.isInsert) {
  AccountContact.hireContactForm(Trigger.new);
 }
 if (Trigger.isBefore && Trigger.isUpdate) {
  AccountContact.hireContactFormForUpdate(Trigger.new);
 }
}

trigger HireCaseForm on Case(before update) {
 if (Trigger.isBefore && Trigger.isUpdate) {
  AccountContact.caseUpdate(Trigger.new);
 }
}
 Error:Apex trigger ContactFormTrigger caused an unexpected exception, contact your administrator: ContactFormTrigger: execution of BeforeUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id 5002v00002aKMAXAA4; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, You can not close the case until hire form is completed: []: Class.AccountContact.hireContactFormForUpdate: line 246..

This is the error I am getting when I am updating the field to 'completed' so why it is invoking the other method's trigger. I have got stuck on this for more than three days.

Ganesa Vijayakumar
  • 2,422
  • 5
  • 28
  • 41

1 Answers1

1

5002v00002aKMAXAA4 would be a Case Id (anything that starts with 500 is Case)

Your error message includes hint where it failed (Class.AccountContact.hireContactFormForUpdate).

And in that method you have

for (HireForm__c hire: HireListNew) {
  for (Case caseStatus: CaseList) {
   if (hire.Candidate__c == caseStatus.ContactId && hire.status__c == 'Completed') {
    caseStatus.Status = 'Closed';
   }
   update caseStatus;
  }
 }

And you wrote "error I am getting when I am updating the field to 'completed'". It looks like Salesforce is doing exactly what it's being told to. Hire completed -> your code tries to close all cases -> somebody wrote a validation on Case that prevents you.

Yes, validation, it's from a val. rule, not from a trigger. You should check the validation rule. If you run your code with a debug log you should see the validation rule and next to it the values SF used to evaluate it. It'll look bit like this, you want the part in bold:

enter image description here

My guess is that validation fires because at this time hire.Status__c is not yet "Completed". You probably picked wrong trigger keywords. Is this method running in "before update" or "after update"?

Logically should be "after". "Befores" are for field prepopulation, all kinds of checks that are too complex to do with validation rules etc. "Afters" are for side effects (updating related records, sending notifications to external systems). Mass closing related cases is a side effect for me.

eyescream
  • 18,088
  • 2
  • 34
  • 46
  • Thanku @eyescream i got my mistake. yup trigger was on before and i did make some change in my code and make the replace the before with after. – Mohd Nabeel Nov 22 '19 at 04:27
  • just wanted a little explanation that when i am commenting my second trigger which is on case then it is working fine even on before trigger, Can you please tell me why? And yes there are no validation rules on case i have checked it. – Mohd Nabeel Nov 22 '19 at 04:31
  • Run with debug logging or dev console open, find section similar to my screenshot and 1 line above it there should be something like `VALIDATION_RULE|03d0C000000D7je|StatusMustMatchParentStatus`. That'd be val rule id which you can paste to url in SF. Or a Tooling API query (you have tick a checkbox on bottom of Query Editor tab in Developer Console), use fields from https://developer.salesforce.com/docs/atlas.en-us.api_tooling.meta/api_tooling/tooling_api_objects_validationrule.htm – eyescream Nov 22 '19 at 07:18