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
vasantqvasantq 

Help writing a trigger to reparent another parent in a master-detail relationship

I'm trying to write a trigger than initiates itself when a checkbox is checked.

 

The trigger will basically go and clear some fields in the record. I've already coded this portion:

 

trigger ReparentToNextPlanningWeek on Innovation_Planning__c (before update) {
    for (Innovation_Planning__c IP : Trigger.new) {
        if(IP.Carryover__c == TRUE) {
            IP.Status__c = NULL;
            IP.Percent_Complete__c = NULL;
            IP.Carryover_Count__c = IP.Carryover_Count__c+1;
            IP.Carryover__c = FALSE;
        }
    }
}

 

I also want this trigger to look into the "Planning Week" object, and reparent itself to the next week's planning record. For example, if the current Innovation Planning record exists as a master-detail to the "03-03-2013" Planning Week record, I'd now like for the trigger to be reparented to the "03-10-2013" Planning Week record. Please note that the dates are always 7 days out and occur on Sundays. Perhaps this could be used in the logic?

 

Basically, I have no idea how to write a trigger that reparents itself to another record in the parent object.

 

Can someone please help?

Vinit_KumarVinit_Kumar

Couple of questions here :-

 

1.) If there are more than one records for 03-10-2013 which one you want the current child to be reparented.I mean what is the condition for that.

 

2.) What is the name of relatiohsip field on child object.

 

 

 

MellowRenMellowRen

vasantq

 

Obviously, I don't know the names of your objects or fields but hopefully from this will be enough to show you a method of doing what you want. BTW, I have assumed that your "Planning Week" object has a Date field which contains the starting date of the planning week (just because it makes it a lot easier to write the below). If you don't have such a field then you could either add one to your data structure or if the name of the record contains the date you can modify the code with some text-date conversions to make it work.

 

My example code has no error checking. For this kind of trigger you should probably do things like ensure the "next" Planning Week actually exists before reparenting the Innovation_Planning record, etc, etc.

 

Finally, a Master-Detail field needs to specifically be set up to allow reparenting—there's a checkbox in the edit field page. I am pretty sure, although not 100%, that this restriction cannot be overridden by apex code so make sure the checkbox is selected.

 

trigger ReparentToNextPlanningWeek on Innovation_Planning__c (before update) {

    private date nextPWDate;
    private Planning_Week__c currPW;
    private Planning_Week__c nextPW;

    for (Innovation_Planning__c IP : Trigger.new) {
        if(IP.Carryover__c == TRUE) {
            IP.Status__c = NULL;
            IP.Percent_Complete__c = NULL;
            IP.Carryover_Count__c = IP.Carryover_Count__c+1;
            IP.Carryover__c = FALSE;
            
            // Find next Planning_Week and reparent
            currPW = [SELECT ID, StartDate__c FROM Planning_Week__c WHERE  ID = :IP.Planning_WeekID LIMIT 1];
            nextPWDate = currPW.StartDate__c.addDays(7);
            nextPW = [SELECT ID FROM Planning_Week__c WHERE  StartDate__c = :nextPWDate LIMIT 1];
            IP.Planning_WeekID = nextPW.ID;
        }
    }
}

 

Good luck.

 

MellowRen

vasantqvasantq

Answers:

 

Here's the schema diagram:

 

http://oi49.tinypic.com/2hfqic3.jpg

 

1. There should only be one 03-10-2013 record. I've essentially designated planning weeks, almost like Sprints in the Agile sense. So all values should be distinct.

 

2. The name is the same as what's on the parent: "Planning Week".

vasantqvasantq

Let me try your code. Its a great start! Thank you. Btw, here's the schema diagram:

 

http://oi49.tinypic.com/2hfqic3.jpg

vasantqvasantq

I tried tweaking your code to fit the data structure that I have:

 

trigger ReparentToNextPlanningWeek on Innovation_Planning__c (before update) {

    private date nextPWDate;
    private Planning_Week__c currPW;
    private Planning_Week__c nextPW;
    
    for (Innovation_Planning__c IP : Trigger.new) {
        if(IP.Carryover__c == TRUE) {
            IP.Status__c = NULL;
            IP.Percent_Complete__c = NULL;
            IP.Carryover_Count__c = IP.Carryover_Count__c+1;
            IP.Carryover__c = FALSE;
            
            currPW = [SELECT ID, Week__c FROM Planning_Week__c WHERE  ID = :IP.Planning_Week__cID LIMIT 1];
            nextPWDate = currPW.Planning_Week__c.addDays(7);
            nextPW = [SELECT ID FROM Planning_Week__c WHERE  Week__c = :nextPWDate LIMIT 1];
            IP.Planning_WeekID = nextPW.ID;
        }
    }
}

 

I ran into this problem:

 

Error: Compile Error: Invalid field Planning_Week__cID for SObject Innovation_Planning__c at line 14 column 77

Naidu PothiniNaidu Pothini
trigger ReparentToNextPlanningWeek on Innovation_Planning__c (before update) 
{
    List<Id> pwIds = new List<Id>();

    for (Innovation_Planning__c IP : Trigger.new)
    {
      if(IP.Carryover__c == TRUE)
      {
        pwIds.add(IP.Planning_Week__c);
      }
    }

    Map<Id, Planning_Week__c> pwMap = new Map<Id, Planning_Week__c>([SELECT Id, Week__c FROM Planning_Week__c WHERE  ID IN :pwIds]);//updated

    Map<Id, Date> pwDateMap = new Map<Id, Date>();

    for(Planning_Week__c pw : pwMap.values())
    {
      pwDateMap.put(pw.Id, pw.Week__c.addDays(7));
    }

    Map<Id, Planning_Week__c> pwNextMap = new Map<Id, Planning_Week__c>([SELECT ID, Week__c FROM Planning_Week__c WHERE  Week__c IN :pwDateMap.values()]);
    Map<Id, Id> pwFinalMap = new Map<Id, Id>();

    for (Planning_Week__c pw1 :  pwMap.values())
    {
      for(Planning_Week__c pw2 : pwNextMap.values())
      {
        if(pwDateMap.get(pw1.Id) == pw2.Week__c)
        {
          pwFinalMap.put(pw1.Id, pw2.Id);
        }
      }
    }

    for (Innovation_Planning__c IP : Trigger.new)
    {
        if(IP.Carryover__c == TRUE)
        {
            IP.Status__c = NULL;
            IP.Percent_Complete__c = NULL;
            IP.Carryover_Count__c = IP.Carryover_Count__c+1;
            IP.Carryover__c = FALSE;
            IP.Planning_WeekID = pwFinalMap.get(IP.Planning_Week__c);
        }
    }
}

 I have bulkified this code.. please try this... check the Field API names.

MellowRenMellowRen
A quick look at your data structure. Line 14 :
…WHERE ID = :IP.Planning_Week__c LIMIT…

and again at line 17:
IP.Planning_Week__c = nextPW.ID;

Oh, and line 15 should be:
nextPWDate = currPW.Week__c.addDays(7);
snovvblindsnovvblind

I'm getting the following issue:

 

Error: Compile Error: Variable does not exist: IP.Planning_Week__c at line 10 column 124

 

I can't figure it out. Planning_Week__c in the Innovation Planning Object is a valid field.

MellowRenMellowRen

snovvblind

 

Neither NaiduPothini’s nor my example code references IP.Planning_Week__c at line 10 so it’s a bit hard to troubleshoot with just the error message. Feel free to post your version of the code. A few obvious questions:

 

  1. Are you sure you spelt “Planning Week” in the object the same way? [Sorry]
  2. Similarly, double-check the API name of the field, is it “Planning_Week__c”? Many of us re-edit the field label and forget to change the API name to match.
  3. Have you defined the variable “IP” in the trigger?
  4. Has the field “Planning_Week__c” been set as reparentable?

Regards

MellowRen