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
Gwirizanani SinoiaGwirizanani Sinoia 

appending the parent record number to the child record and count the child records againt the parent

Hi all,

i have business case where I have two objects in a masterdetail relationship. My objective is to be able to append parent record auto number field to the child record number
  ie Parent record number Pr01 and child record number 1. The main thing is the  child record number is a count of how many child records are associated with that particular parent. For Example
Lets say PR01 is related to a three child records then the child record number should be PR01.1 the next PR01.2 and so on
Thanks in advance
Best Answer chosen by Gwirizanani Sinoia
Steven NsubugaSteven Nsubuga
Refacting the trigger
Trigger CountSons on DadSon__c (before insert) {
    
    Set<Id> dadIds = new Set<Id>();
	Map<String, List<DadSon__c>> dadSons = new Map<String, List<DadSon__c>>();
	
    for (DadSon__c son : Trigger.new) {
        dadIds.add(son.Parent__c);
		
		List<DadSon__c> sons = dadSons.get(son.Parent__c);
        if (sons == null) {
            sons = new List<DadSon__c>();
        }
        sons.add(son);
        dadSons.put(son.Parent__c, sons);
    }
    Map<Id, Dad__c> dadNames = new Map<Id, Dad__c>([SELECT Id, Name FROM Dad__c WHERE Id IN :dadIds]);

    List<AggregateResult> ars = [SELECT Parent__c, count(Id) FROM DadSon__c WHERE Parent__c IN :dadIds group by Parent__c];
    Map<String, Integer> dadSonsCount = new Map<String, Integer>();
    for (AggregateResult ar : ars) {
        dadSonsCount.put(String.valueOf(ar.get('Parent__c')), Integer.valueOf(ar.get('expr0')));
    }
    
    for (DadSon__c son : Trigger.new) {
        if (dadSonsCount.get(son.Parent__c) == null) {
            dadSonsCount.put(son.Parent__c, 0);
        }
    }

    for (List<DadSon__c> sons : dadSons.values()) {
        for (Integer s = 1; s < sons.size() + 1; s++) {
            DadSon__c son = sons.get(s-1);
            integer index = Trigger.new.indexOf(son);
            Trigger.new.get(index).Name_Combo__c = dadNames.get(son.Parent__c).Name + '.' + (dadSonsCount.get(son.Parent__c) + s);
        }
    }
}
updated test class
@isTest
private class CountSonsTest {

    @isTest static void testTrigger(){
    
        // Create parent records
        List<Dad__c> dads = new List<Dad__c>();
        for (Integer s = 1; s < 3; s++) {
            Dad__c dad = new Dad__c();
            dads.add(dad);
        }
        insert dads;
        
        // Create child records
        List<DadSon__c> sons = new List<DadSon__c>();
        for (Integer s = 0; s < 2; s++) {
            DadSon__c son = new DadSon__c(Parent__c = dads[s].Id);
            sons.add(son);
        }
        insert sons;
        
        List<DadSon__c> sons2 = [SELECT Parent__r.Name, Name_Combo__c FROM DadSon__c];
        for (DadSon__c son : sons2) {
            System.assertEquals(son.Parent__r.Name + '.1', son.Name_Combo__c);
        }
        
        // Create additional child records for 1 of the dads
        List<DadSon__c> sons3 = new List<DadSon__c>();
        for (Integer s = 0; s < 2; s++) {
            DadSon__c son = new DadSon__c(Parent__c = dads[0].Id);
            sons3.add(son);
        }
        insert sons3;
        
        List<DadSon__c> sons4 = [SELECT Parent__r.Name, Name_Combo__c FROM DadSon__c WHERE Parent__c =:dads[0].Id order by Name_Combo__c ASC];
        for (Integer i = 1; i < sons4.size() + 1; i++) {
            System.assertEquals(sons4[i-1].Parent__r.Name + '.' + i, sons4[i-1].Name_Combo__c);
        }
    }
}


 

All Answers

Steven NsubugaSteven Nsubuga
Use a formula field on the child object. Assuming that the master detail field is Dad__c, then the formula syntax is
Dad__r.Name + '.' +  Name

 
Akshay_DhimanAkshay_Dhiman
Hi Gwirizanani,

If two objects in a master-detail relationship then create Rollup Summary field on Parent Object to COUNT child Record.
Refer this to implements Rollup summary fields:

https://trailhead.salesforce.com/en/modules/point_click_business_logic/units/roll_up_summary_fields


  Write Trigger to resolve this Problem(Let's say PR01 is related to a three child record then the child record number should be PR01.1 the next PR01.2 and so on)
     
 if you found this answer helpful then please mark it as best answer so it can help others.   

   Thanks 
   Akshay 
Gwirizanani SinoiaGwirizanani Sinoia
Hi all,

thank you for response

@Steven Nsubuga Formula field only concatenates two fields unfortunately that does not offer a count according to the business requirements.
@Akshay_Dhiman Roll up Summary Field you can not use filter criteria to reference another field to be able to do an accurate count. unfortunately that does not work. As you know you can not use a formula field in your filter criteria.

Thanks guys for your input.
Steven NsubugaSteven Nsubuga

To suit your scenario, I have created 2 objects, Dad__c and DadSon__c. DadSon__c has a Master Detail field to Dad__c, the field API name is Parent__c. Dad__c's standard Name field is an Auto Number field, with Display Format  as PR{00}

I created a Text field called Number Combo (Name_Combo__c) on DadSon__c that will contain the desired name. For ease of testing, the standard Name field on DadSon__c is an Auto Number field, it is not used at all.
Next I wrote a before insert trigger, whose code is shared below, as well as a test class. 
trigger

Trigger CountSons on DadSon__c (before insert) {
    
    Set<Id> dadIds = new Set<Id>();

    for (DadSon__c son : Trigger.new) {
        dadIds.add(son.Parent__c);
    }
    Map<Id, Dad__c> dadNames = new Map<Id, Dad__c>([SELECT Id, Name FROM Dad__c WHERE Id IN :dadIds]);

    Map<String, List<DadSon__c>> dadSons = new Map<String, List<DadSon__c>>();
    for (DadSon__c son : Trigger.new) {
        List<DadSon__c> sons = dadSons.get(son.Parent__c);
        if (sons == null) {
            sons = new List<DadSon__c>();
        }
        sons.add(son);
        dadSons.put(son.Parent__c, sons);
    }

    List<AggregateResult> ars = [SELECT Parent__c, count(Id) FROM DadSon__c WHERE Parent__c IN :dadIds group by Parent__c];
    Map<String, Integer> dadSonsCount = new Map<String, Integer>();
    for (AggregateResult ar : ars) {
        dadSonsCount.put(String.valueOf(ar.get('Parent__c')), Integer.valueOf(ar.get('expr0')));
    }
    
    for (DadSon__c son : Trigger.new) {
        if (dadSonsCount.get(son.Parent__c) == null) {
            dadSonsCount.put(son.Parent__c, 0);
        }
    }

    for (List<DadSon__c> sons : dadSons.values()) {
        for (Integer s = 1; s < sons.size() + 1; s++) {
            DadSon__c son = sons.get(s-1);
            integer index = Trigger.new.indexOf(son);
            Trigger.new.get(index).Name_Combo__c = dadNames.get(son.Parent__c).Name + '.' + (dadSonsCount.get(son.Parent__c) + s);
        }
    }
}


test class
 

@isTest
private class CountSonsTest {

    @isTest static void testTrigger(){
    
        // Create parent records
        List<Dad__c> dads = new List<Dad__c>();
        for (Integer s = 1; s < 3; s++) {
            Dad__c dad = new Dad__c();
            dads.add(dad);
        }
        insert dads;
        
        // Create child records
        List<DadSon__c> sons = new List<DadSon__c>();
        for (Integer s = 0; s < 2; s++) {
            DadSon__c son = new DadSon__c(Parent__c = dads[s].Id);
            sons.add(son);
        }
        insert sons;
        
        List<DadSon__c> sons2 = [SELECT Parent__r.Name, Name_Combo__c FROM DadSon__c];
        for (DadSon__c son : sons2) {
            // There is only 1 child record per parent
            System.assertEquals(son.Parent__r.Name + '.1', son.Name_Combo__c);
        }
    }
}
Steven NsubugaSteven Nsubuga
Refacting the trigger
Trigger CountSons on DadSon__c (before insert) {
    
    Set<Id> dadIds = new Set<Id>();
	Map<String, List<DadSon__c>> dadSons = new Map<String, List<DadSon__c>>();
	
    for (DadSon__c son : Trigger.new) {
        dadIds.add(son.Parent__c);
		
		List<DadSon__c> sons = dadSons.get(son.Parent__c);
        if (sons == null) {
            sons = new List<DadSon__c>();
        }
        sons.add(son);
        dadSons.put(son.Parent__c, sons);
    }
    Map<Id, Dad__c> dadNames = new Map<Id, Dad__c>([SELECT Id, Name FROM Dad__c WHERE Id IN :dadIds]);

    List<AggregateResult> ars = [SELECT Parent__c, count(Id) FROM DadSon__c WHERE Parent__c IN :dadIds group by Parent__c];
    Map<String, Integer> dadSonsCount = new Map<String, Integer>();
    for (AggregateResult ar : ars) {
        dadSonsCount.put(String.valueOf(ar.get('Parent__c')), Integer.valueOf(ar.get('expr0')));
    }
    
    for (DadSon__c son : Trigger.new) {
        if (dadSonsCount.get(son.Parent__c) == null) {
            dadSonsCount.put(son.Parent__c, 0);
        }
    }

    for (List<DadSon__c> sons : dadSons.values()) {
        for (Integer s = 1; s < sons.size() + 1; s++) {
            DadSon__c son = sons.get(s-1);
            integer index = Trigger.new.indexOf(son);
            Trigger.new.get(index).Name_Combo__c = dadNames.get(son.Parent__c).Name + '.' + (dadSonsCount.get(son.Parent__c) + s);
        }
    }
}
updated test class
@isTest
private class CountSonsTest {

    @isTest static void testTrigger(){
    
        // Create parent records
        List<Dad__c> dads = new List<Dad__c>();
        for (Integer s = 1; s < 3; s++) {
            Dad__c dad = new Dad__c();
            dads.add(dad);
        }
        insert dads;
        
        // Create child records
        List<DadSon__c> sons = new List<DadSon__c>();
        for (Integer s = 0; s < 2; s++) {
            DadSon__c son = new DadSon__c(Parent__c = dads[s].Id);
            sons.add(son);
        }
        insert sons;
        
        List<DadSon__c> sons2 = [SELECT Parent__r.Name, Name_Combo__c FROM DadSon__c];
        for (DadSon__c son : sons2) {
            System.assertEquals(son.Parent__r.Name + '.1', son.Name_Combo__c);
        }
        
        // Create additional child records for 1 of the dads
        List<DadSon__c> sons3 = new List<DadSon__c>();
        for (Integer s = 0; s < 2; s++) {
            DadSon__c son = new DadSon__c(Parent__c = dads[0].Id);
            sons3.add(son);
        }
        insert sons3;
        
        List<DadSon__c> sons4 = [SELECT Parent__r.Name, Name_Combo__c FROM DadSon__c WHERE Parent__c =:dads[0].Id order by Name_Combo__c ASC];
        for (Integer i = 1; i < sons4.size() + 1; i++) {
            System.assertEquals(sons4[i-1].Parent__r.Name + '.' + i, sons4[i-1].Name_Combo__c);
        }
    }
}


 
This was selected as the best answer
Gwirizanani SinoiaGwirizanani Sinoia
Thanks @ 
Steven Nsubuga. Amazing!
Steven NsubugaSteven Nsubuga
My pleasure @Gwirizanani Sinoia, I enjoyed the challenge!!