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
cambart14cambart14 

Linking a New Child Record to an Existing Parent Record Before Insert

Hello!  We have a custom object (Invoice__c)  that is the child in a master-detail relationship with Accounts.  Accounts have a unique number system housed in the SGN_Number__c field that is also on the invoice information that we get from our ERP system.  When we insert invoices into Salesforce.com we do not want to manually map each invoice to the correct account (using the SGN Number) in Excel, but would rather have an Apex trigger automatically find the right accound and populate the account ID into the Invoice__c lookup field (Account__c). 

I have written the below trigger, but cannot seem to get it to work.

trigger updateInvoiceAccount on Oracle_Sales_History__c (before insert) {

    //get the SGNs and store it in a set.
    set<String> accountSGN = new set<String>();
    for(Invoice__c i: trigger.new){
            accountSGN.add(i.SGN_Number__c);
    }

    //query the account records and get the associated ids.
    map<string, Account> accountMap = new map<string, Account>([SELECT Id from Account where Id IN: accountSGN]);

    //update the account value based on the SGN in the record.
    for(Invoice__c i: trigger.new){
            i.Account__c = accountMap.get(i.SGN_Number__c).Id;    
    }

}

Thanks,
cambart14
Best Answer chosen by cambart14
Hargobind_SinghHargobind_Singh
I've made following changes to your trigger:

1. Handle situations where you might not have value in SGN_Number__c field (first For Loop)
2. Query, based on SGN_Number__c from Accounts, not based on IDs, am assuming that you are matching based on a unique code in SGN_Number__C field, so you wont be able to create a map directly as that map would be created taking ID as a key, where-as you might want to take SGN_Number__c field as key
3. Add a KeyNotFound condition in your for loop before updating to avoid null value error.
4. I've added a case-check, assuming that SGN_number is alphanumeric.

Here is the updated code:

trigger TempTrigger on Invoice__c (before insert) {

    //get the SGNs and store it in a set.
    set<String> accountSGN = new set<String>();
    for(Invoice__c i: trigger.new){
        if(i.SGN_Number__c !=null && i.SGN_Number__c.trim().length()>0){
         accountSGN.add(i.SGN_Number__c);
        }
    }

    //query the account records and get the associated ids.
    map<string, Account> accountMap = new map<string, Account>();
    for(Account a: [SELECT Id, SGN_Number__c from Account where SGN_Number__c IN: accountSGN]){
     accountMap.put(a.SGN_Number__c.toUpperCase(), a);
    }

    //update the account value based on the SGN in the record.
    for(Invoice__c i: trigger.new){
        if(i.SGN_Number__c !=null && i.SGN_Number__c.trim().length()>0 && accountMap.containsKey(i.SGN_Number__c.toUpperCase())){
            i.Account__c = accountMap.get(i.SGN_Number__c.toUpperCase()).Id;   
        }
    }
}


All Answers

Ramu_SFDCRamu_SFDC
Try the below code

trigger updateInvoiceAccount on Oracle_Sales_History__c (before insert) {

    //get the SGNs and store it in a set.
    set<String> accountSGN = new set<String>();
    for(Invoice__c i: trigger.new){
            accountSGN.add(i.SGN_Number__c);
    }

    //query the account records and get the associated ids.
    map<string, Account> accountMap = new map<string, Account>();
List<Account> AccountList=new List<Account>([SELECT Id,SGN_Number__c from Account where Id IN: accountSGN]);
for(Account acc:AccountList){
accountMap.put(acc.SGN_Number__c,acc);
}

    //update the account value based on the SGN in the record.
    for(Invoice__c i: trigger.new){
            i.Account__c = accountMap.get(i.SGN_Number__c).Id;   
    }

}


cambart14cambart14
Thanks Ramu for the revisions, but I am getting this error when trying to insert a record: "FATAL ERROR | Attempt to de-reference a null object"
Hargobind_SinghHargobind_Singh
I've made following changes to your trigger:

1. Handle situations where you might not have value in SGN_Number__c field (first For Loop)
2. Query, based on SGN_Number__c from Accounts, not based on IDs, am assuming that you are matching based on a unique code in SGN_Number__C field, so you wont be able to create a map directly as that map would be created taking ID as a key, where-as you might want to take SGN_Number__c field as key
3. Add a KeyNotFound condition in your for loop before updating to avoid null value error.
4. I've added a case-check, assuming that SGN_number is alphanumeric.

Here is the updated code:

trigger TempTrigger on Invoice__c (before insert) {

    //get the SGNs and store it in a set.
    set<String> accountSGN = new set<String>();
    for(Invoice__c i: trigger.new){
        if(i.SGN_Number__c !=null && i.SGN_Number__c.trim().length()>0){
         accountSGN.add(i.SGN_Number__c);
        }
    }

    //query the account records and get the associated ids.
    map<string, Account> accountMap = new map<string, Account>();
    for(Account a: [SELECT Id, SGN_Number__c from Account where SGN_Number__c IN: accountSGN]){
     accountMap.put(a.SGN_Number__c.toUpperCase(), a);
    }

    //update the account value based on the SGN in the record.
    for(Invoice__c i: trigger.new){
        if(i.SGN_Number__c !=null && i.SGN_Number__c.trim().length()>0 && accountMap.containsKey(i.SGN_Number__c.toUpperCase())){
            i.Account__c = accountMap.get(i.SGN_Number__c.toUpperCase()).Id;   
        }
    }
}


This was selected as the best answer
cambart14cambart14
Thank you hs1, that worked perfectly!