4

I am trying to write a trigger that will take a user's input into a text field Orders__c.Site_Code__c and find the account which has the matching value in Account.Site_Code__c.

My trigger passes its test with 100% coverage but when trying to create a new Orders__c I get the following error:

Apex trigger PullOrderSiteAccount caused an unexpected exception, contact your administrator: PullOrderSiteAccount: execution of AfterInsert caused by: System.StringException: Invalid id: 1234: External entry point

Where did I go wrong?

--snip-- Working trigger!

trigger PullOrderSiteAccount on Orders__c (before insert) {

Set<String> codes = new Set<String>();
for (Orders__c o : trigger.new) codes.add(o.Site_Code__c);

Map<String, Account> siteAccounts = new Map<String, Account>();
for (Account a : [
    SELECT Site_Code__c FROM Account
    WHERE Site_Code__c IN :codes
]) siteAccounts.put(a.Site_Code__c, a);

       for (Orders__c o : Trigger.new)
    {
        Account siteAccount = siteAccounts.get(o.Site_Code__c);
       Id parentId = (siteAccount == null) ? null : siteAccount.Id;
        o.Site_Account__c = parentId;
    }
}

updated:

This now works!

3
  • Your test coverage dropped because you don't have any matching records.
    – Adrian Larson
    Commented May 17, 2016 at 18:04
  • I had alluded to multiple matches at the end of my post, now addressed in further detail.
    – Adrian Larson
    Commented May 17, 2016 at 19:07
  • please ask your new question as a separate question in SFSE - showing latest code
    – cropredy
    Commented May 17, 2016 at 20:42

1 Answer 1

4

The Site_Code__c values are String type. You need Map<String, Account> as your collection type. So:

Set<String> codes = new Set<String>();
for (Orders__c order : trigger.new) codes.add(order.Site_Code__c);

Map<String, Account> siteAccounts = new Map<String, Account>();
for (Account record : [
    SELECT Site_Code__c FROM Account
    WHERE Site_Code__c IN :codes
]) siteAccounts.put(record.Site_Code__c, record);

for (Orders__c order : Trigger.new)
{
    Account siteAccount = siteAccounts.get(order.Site_Code__c);
    Id parentId = (siteAccount == null) ? null : siteAccount.Id;
    order.Site_Account__c = parentId;
}

The above assumes Site_Code__c is a unique field for Account. If not, you need to do Map<Id, List<Account>> and figure out what to do if there is more than one match.

In more detail, that second scenario would look like:

Set<String> codes; // same as above
Map<String, List<Account>> siteAccounts = new Map<String, List<Account>>();
for (Account record : [/*query*/])
{
    if (!siteAccounts.containsKey(record.Site_Code__c))
        siteAccounts.put(record.Site_Code__c, new List<Account>());
    siteAccounts.get(record.Site_Code__c).add(record);
}
for (Orders__c order : trigger.new)
{
    List<Account> matchingAccounts = siteAccounts.get(order.Site_Code__c);
    Id parentId = (matchingAccounts != null && matchingAccounts.size() == 1) ?
        matchingAccounts[0].Id : null;
    order.Site_Account__c = parentId;
}
6
  • please see update at bottom of question
    – JaredT
    Commented May 17, 2016 at 17:27
  • @jatuttle0 You just need to make it before insert instead.
    – Adrian Larson
    Commented May 17, 2016 at 17:38
  • @jatuttle0 You can Use Before Insert has a DML Event ..if All Accounts are already There ..Atleast DML count will be reduced
    – user40138
    Commented May 17, 2016 at 18:59
  • Updating OP with another inquiry
    – JaredT
    Commented May 17, 2016 at 18:59
  • I have extended the inquiry into a new question salesforce.stackexchange.com/questions/122362/…
    – JaredT
    Commented May 18, 2016 at 14:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .