0

i am creating three child records when a record is created on parent object using process builder. now, i am writing a trigger to update 'status__c = closed' field on parent object when status of three child record's is marked as 'completed'. below is my apex method

public class StatusClosedHandler { 
    public static void statuschange(List<Id> RecordId){ 
        integer count = 0; 
        List<Service_Request__c> srequest = new List<Service_Request__c>();
        for(Service_Line__c sl : [Select id, Name, Status__c,Line_Type__c, Service_Request__r.Status__c,Service_Request__r.Name from Service_Line__c WHERE Service_Request__c = :RecordId[i] ]){
            if(sl.Status__c == 'Completed'){ 
                count++;
            } 
            if(count == 3){
                Service_Request__c sr = new Service_Request__c();
                sr.id = sl.Service_Request__c;
                sr.status__c = 'Closed';
                srequest.add(sr);
            } 
        }

        update srequest;
    } 
}

and my trigger to call this method is :

trigger StatusClosedfinal on Service_Line__c (after update) {
    if(Trigger.isAfter && Trigger.isUpdate){ 
        List<Id> sLine = new List<Id>();
        for(Service_Line__c  i:trigger.new) {
            sLine.add(i.Id);
        }
        StatusClosedHandler.statuschange(sLine); 
    } 
}

when i am running method in anonymous window and passing parent id as a list, it's updating the status, but not while runnig the trigger. ​​​​​​​please help

  • In :RecordId[i], what is i? don't do SOQLs inside a loop (as part of the for its ok, but the [i] would suggest you are iterating somewhere and increasing the value of i – Sergio Alcocer May 19 at 8:50
  • Please ignore that, intially i was running a loop to query based on the record id count but that wasn't a right approach, i forgot to edit that. sorry – MikeT May 19 at 9:01
1

Below code is unnecessary in your trigger

List<Id> sLine = new List<Id>();
for(Service_Line__c  i:trigger.new) {
   sLine.add(i.Id);
}

Simply pass trigger.new to the handler and change the handler's method signature

public static void statuschange(List<Service_Line__c> ServiceLines){

After that, you would not need to have the SOQL with for and it would be

for(Service_Line__c serviceline: ServiceLines){


Other thing that could be related to your problem is Service_Request__c fields are not queried. You should run a soql on Service_Request__c and put them in a map with SErviceRequestId as key. SELECT id, Status, ... otherfields FROM Service_Request__c WHERE id in [ServiceRequestIds_frm_Service_Lines] (You can build Service request id from service lines by looping through)

Basic update to your handler class will be

public class StatusClosedHandler { 
    public static void statuschangeList<Service_Line__c> ServiceLines){ 
       Set<Id> servicerequestIds = new Set<Id>();
       for(Serivce_Line__c sl: ServiceLines) servicerequestIds.add(sl.Service_Request__c);
       // query service request records
       Map<Id, Service_request__c> servicerequestmap = New Map<Id, Service_REquest__c>([SELECT Id, Status FROM Service_Request__c WHERE Id in: servicerequestids]);
        integer count = 0; 
        List<Service_Request__c> srequest = new List<Service_Request__c>();
        for(Service_Line__c sl : ServiceLines]){
            if(sl.Status__c == 'Completed'){ 
                count++;                     
            } 
            if(count == 3){
                Service_Request__c sr = servicerequestmap.get(sl.Service_Request__c);
                sr.status__c = 'Closed';
                srequest.add(sr);
            } 
        }

        update srequest;
    } 
}

Edit

Problem: Parent should be completed when all children status are completed.

Solution

  1. Best solution here would be, to have a custom field Children completed field (boolean) on Service_Request__c and increment it each time a child status is completed.

  2. Have process builder on Service Request object, and check if the counter is 3, then set the status to completed.

    if(sl.Status__c == 'Completed'){ Service_Request__c sr = servicerequestmap.get(sl.Service_Request__c); sr.Children_Completed__c += 1; srequest.add(sr); }

and below if condition will not be required then.

2nd edit

Just been thinking about your updated requirements, a trigger itself seems unnecessary now. :-)

You just need two process builders ,

  1. one on ServiceLine , check status, and if completed, increment parent's 'children completed' fields.
  2. Second process builder on service request, and check if the 'children completed' counter is 3, then update its status to completed.
| improve this answer | |
  • Thank you so much mate but here it's a master-detail relationship do you think this query would work? for(Service_Request__c sr: [Select id, Status__c, (select id, Status__c from Service_Lines__r) FROM Service_Request__c WHERE id in [ServiceRequestIds_frm_Service_Lines]]) – MikeT May 19 at 9:44
  • Why do you want to have the above query? You are updating status of parent i.e.Service_request__c and that's all. You don't need the above query. – Mahmood May 19 at 9:47
  • you mean i should be doing a normal query like this List<Status_Request__c> sRequest = [SELECT id, Status__c FROM Service_Request__c WHERE id in [ServiceRequestIds_frm_Service_Lines] – MikeT May 19 at 9:53
  • No. Please check my code that I provided. Above I created a Map (Map<Id, Service_request__c> servicerequestmap = New Map<Id, Service_REquest__c>([SELECT Id, Status FROM Service_Request__c WHERE Id in: servicerequestids]);) and ServiceRequestIds were created earlier. – Mahmood May 19 at 9:55
  • ServiceRequestIds were created using this code for(Serivce_Line__c sl: ServiceLines) servicerequestIds.add(sl.Service_Request__c); – Mahmood May 19 at 9:59

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.