1

Check my code below, I am trying to insert a value into an Account field but I am getting an error.

Apex trigger StatusTrigger caused an unexpected exception, contact your administrator: StatusTrigger: execution of AfterUpdate caused by: System.DmlException: Insert failed. First exception on row 0 with id 001R000000tShDwIAK; first error: INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call: [Id]: Trigger.StatusTrigger: line 49, column

My code is this:

trigger StatusTrigger on Opportunity (after insert, after update, after delete) {  
Set<Id> accountIds = new Set<Id>();

Double noOfActiveOpp = 0;
Double noOfInactiveOpp = 0;
Double noOfOpenOpp = 0;
Double noOfLostOpp = 0;
Double noOfOpp = 0;

for (Opportunity op : Trigger.new) {
   accountIds.add(op.AccountId);
}

List<Account> oppList = [select id, (select id from opportunities) from account where id in: accountIds];

for(Account a : [select id, (select id, StageName, Service_End_Date__c from opportunities) from account where id in: accountIds]) {
    for(Opportunity opp : a.opportunities) {

        system.debug(opp.id);

        if(opp.StageName == 'Closed Won') {
            if(opp.Service_End_Date__c < Date.parse(date.today().format())) {
                noOfActiveOpp += 1;
            } else if(opp.Service_End_Date__c > Date.parse(date.today().format())) {
                noOfInactiveOpp += 1;
            }
        } else if(opp.StageName == 'Closed Lost') {
            noOfLostOpp += 1;
        } else {
            noOfOpenOpp += 1;
        }
    }
    noOfOpp = a.Opportunities.size();
}

for(Account a : [select id, (select id from opportunities) from account where id in: accountIds]) {
    noOfOpp = a.Opportunities.size();

    if(noOfActiveOpp == noOfOpp) {
        a.Client_Account_Status__c = 'Active';
    } else if(noOfInactiveOpp == noOfOpp) {
        a.Client_Account_Status__c = 'Inactive';
    } else if(noOfOpenOpp == noOfOpp) {
        a.Client_Account_Status__c = 'Open';
    } else {
        a.Client_Account_Status__c = 'Lost';
    }

    insert a;
}
}

I believe the error is coming from the last statement(The insert statement).

2

Your code

for(Account a : [select id, (select id from opportunities) from account where id in: accountIds]) {
    noOfOpp = a.Opportunities.size();

    if(noOfActiveOpp == noOfOpp) {
        a.Client_Account_Status__c = 'Active';
    } else if(noOfInactiveOpp == noOfOpp) {
        a.Client_Account_Status__c = 'Inactive';
    } else if(noOfOpenOpp == noOfOpp) {
        a.Client_Account_Status__c = 'Open';
    } else {
        a.Client_Account_Status__c = 'Lost';
    }

    insert a;
}

should be

List<Account> accoutns = [select id, (select id from opportunities) from account where id in: accountIds];
for(Account a : accoutns ) {
    noOfOpp = a.Opportunities.size();

    if(noOfActiveOpp == noOfOpp) {
        a.Client_Account_Status__c = 'Active';
    } else if(noOfInactiveOpp == noOfOpp) {
        a.Client_Account_Status__c = 'Inactive';
    } else if(noOfOpenOpp == noOfOpp) {
        a.Client_Account_Status__c = 'Open';
    } else {
        a.Client_Account_Status__c = 'Lost';
    }
}
update accounts;

The problem in your code is in insert a;. First of all, you should perform DML on a list instead of one item. Second - you just read Account from SF, and you try to insert it. You should update it instead.

1

It looks like you're wanting to update a field on the accounts rather than insert a new account, the insert a; line will be causing this part of the error:

System.DmlException: Insert failed. First exception on row 0 with id 001R000000tShDwIAK; first error: INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call:

Instead of Insert you'll likely want to use the update dml statement.

One thing to note in your code however is that you are calling a dml statement from within a for loop which goes against salesforce's best practice - theres some helpful guides around these practices here in the salesforce documentation (in your example #2 should be helpful).

You're also querying the Accounts for the given opportunities multiple times, you could query the accounts once up front which you are doing and then use that list (in your case oppList) to perform your for loop to count the Opportunities and then update the Client_Account_Status__c field accordingly.

A final thing to note is that the counts being calculated are for all accounts rather than per account therefore you will likely get the incorrect opportunity counts for each account if more than one opportunity is updated at once.

  • I assume we answered simultaneously :-) – Andrii Muzychuk Mar 24 '16 at 12:48

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.