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
Patrick G. BrownPatrick G. Brown 

Trigger to add master record id based on values from detail record id

I have a trigger to create a Monthly Outreach record that looks to be correct, but I continue to run into a required field error.  Here is an example of my error:

Image of error

I have a master record (Outreach Target) with two identical values (see below) that I'm manually adding to this child record for the purposes of matching.  Those two fields are Location ID and Year Submitted.  My trigger is attempting to add a parent Outreach Target record ID the child Monthly Outreach record by querying the Outreach Target object and searching for a record with matching criteria.  The criteria is unique, so my SOQL query will only find one record.

Here is the master record who's Id I'm attempting to add to my child Monthly Outreach record:

Master Record

Here is my trigger:
 
trigger SetOutreachTarget on Monthly_Outreaches__c (after insert, after update) {
    for (Monthly_Outreaches__c mo : Trigger.new) {
        String moy = mo.Year__c;
        String moa = mo.Location_ID__c;
        List<Outreach_Target__c> ot = [SELECT Id FROM Outreach_Target__c WHERE Outreach_Target_Year__c = :moy AND Location_ID__c = :moa];        
        if(ot.size()>0){
            mo.Outreach_Target__c = ot[0].Id;}
    }
}

I've even tried hard-coding the master record ID into the query to guarantee I'm finding the matching record, but I continue to get the required field error.  Can anyone please help me solve this issue?



 
Mahesh DMahesh D
Hi Patrick,

Please check the latest code:

Here I considered:
(1) Naming Convention.
(2) Alignment.
(3) Bulkified the trigger.
(4) Added comments.

 
trigger SetOutreachTarget on Monthly_Outreaches__c (before insert, before update) {
	
	String locStrSet = new Set<String>();
	String otYearStrSet = new Set<String>();
	
	//Iteratethrough the input records.
	for (Monthly_Outreaches__c mo : Trigger.new) {
		if(mo.Location_ID__c != null)
			locStrSet.add(mo.Location_ID__c);
		if(mo.Year__c != null)
			otYearStrSet.add(mo.Year__c);
	}
	
	// Check if the Set is empty or not.
	if(!locStrSet.isEmpty()) {
		Map<String, Id> otMap = new Map<String, Id>();
		for(Outreach_Target__c ot: [SELECT Id FROM Outreach_Target__c WHERE Outreach_Target_Year__c IN :otYearStrSet AND Location_ID__c IN :locStrSet]) {
			String keyStr = ot.Location_ID__c + ot.Outreach_Target_Year__c;
			otMap.put(keyStr, ot.Id);
		}
		
		for (Monthly_Outreaches__c mo : Trigger.new) {
			String keyStr = mo.Location_ID__c + mo.Year__c;
			
			if(otMap.get(keyStr) != null) {
				mo.Outreach_Target__c = otMap.get(keyStr);
			}
		}
	}
}

Note: I couldn't test this as I don't have full setup of above objects in my org.
 

Please do let me know if it helps you.

Regards,
Mahesh
Patrick G. BrownPatrick G. Brown
Hey Mahesh, thank you so much for taking to time to look at this.  Unfortunately, I received an error ...Illegal assignment from Set <String> to String on line 3.  I'm going to try to work through it, but any advice is welcomed.

You did several things to improve my code and that is extremely helpful.  Thanks again for taking a look at it.
Mahesh DMahesh D
Hi Patrick,

Please find the modified code:
 
trigger SetOutreachTarget on Monthly_Outreaches__c (before insert, before update) {
    
    Set<String> locStrSet = new Set<String>();
    Set<String> otYearStrSet = new Set<String>();
    
    //Iteratethrough the input records.
    for (Monthly_Outreaches__c mo : Trigger.new) {
        if(mo.Location_ID__c != null)
            locStrSet.add(mo.Location_ID__c);
        if(mo.Year__c != null)
            otYearStrSet.add(mo.Year__c);
    }
    
    // Check if the Set is empty or not.
    if(!locStrSet.isEmpty()) {
        Map<String, Id> otMap = new Map<String, Id>();
        for(Outreach_Target__c ot: [SELECT Id, Outreach_Target_Year__c, Location_ID__c 
                                        FROM Outreach_Target__c WHERE Outreach_Target_Year__c IN :otYearStrSet AND Location_ID__c IN :locStrSet]) {
            String keyStr = ot.Location_ID__c + ot.Outreach_Target_Year__c;
            otMap.put(keyStr, ot.Id);
        }
        
        for (Monthly_Outreaches__c mo : Trigger.new) {
            String keyStr = mo.Location_ID__c + mo.Year__c;
            
            if(otMap.get(keyStr) != null) {
                mo.Outreach_Target__c = otMap.get(keyStr);
            }
        }
    }
}

Please do let me know if it helps you.

Regards,
Mahesh
Patrick G. BrownPatrick G. Brown
Mahesh, thank you again!  It's still not working (your code produces no errors...I'm just still running into the required field issue) and I think I understand why.  I don't believe the trigger is firing because when I save the record, before the trigger can fire, it's being blocked by the required field.  My problem is that this field is a master-detail field and I can't make it unrequired, obviously.  Based on the nature of this relationship, it has to be a master-detail and can't be a lookup, unfortunately.

Do you know any tricks to get around this?  I've read about other ways to circumvent this, but none of them really apply to my situation.

 
Patrick G. BrownPatrick G. Brown
And I do want to add another comment...I have noticed that if I put any value in the Outreach Target field, the trigger DOES work and updates the value with the correct value as a result of the query.  So a solution may be to set a default value in the Outreach Target field, then allow the trigger to "fix" it.  I'm not opposed to creating a generic Outreach Target for this purpose, but am at a loss as to how I would default that value in the master detail field.