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!

  • Your test coverage dropped because you don't have any matching records. – Adrian Larson May 17 '16 at 18:04
  • I had alluded to multiple matches at the end of my post, now addressed in further detail. – Adrian Larson May 17 '16 at 19:07
  • please ask your new question as a separate question in SFSE - showing latest code – cropredy May 17 '16 at 20:42
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;
}
  • please see update at bottom of question – JaredT May 17 '16 at 17:27
  • @jatuttle0 You just need to make it before insert instead. – Adrian Larson May 17 '16 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 May 17 '16 at 18:59
  • Updating OP with another inquiry – JaredT May 17 '16 at 18:59
  • I have extended the inquiry into a new question salesforce.stackexchange.com/questions/122362/… – JaredT May 18 '16 at 14:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.