You need to sign in to do that
Don't have an account?
bohemianguy100
bulk update failed: duplicate id
I was testing my trigger in dataloader and received the following error:
Error:
SalesInvoiceTotalsToOpportunity: execution of AfterUpdate
caused by: System.ListException: Duplicate id in list: 006S0000003fw8pIAA
Trigger.SalesInvoiceTotalsToOpportunity: line 55, column 2
trigger SalesInvoiceTotalsToOpportunity on Sales_Invoice__c (after insert, after update) { Set<Id> opIds = new Set<Id>(); for (Sales_Invoice__c si : Trigger.new) { opIds.add(si.Opportunity__c); } List<Sales_Invoice__c> salesInvoiceList = [Select Opportunity__c, Date__c, Payment_Posting_Date__c, Subtotal__c, Amount_Paid__c From Sales_Invoice__c Where Opportunity__c in: opIds]; Map<Id, List<Sales_Invoice__c>> oppyToSalesInvoiceMap = new Map<Id, List<Sales_Invoice__c>>(); for (Sales_Invoice__c salesInvoice : salesInvoiceList) { List<Sales_Invoice__c> salesInvoices = oppyToSalesInvoiceMap.get(salesInvoice.Opportunity__c); if (salesInvoices == null) { salesInvoices = new List<Sales_Invoice__c>(); oppyToSalesInvoiceMap.put(salesInvoice.Opportunity__c, salesInvoices); } salesInvoices.add(salesInvoice); } List<Opportunity> opps = [Select Date_Paid__c, Date_Invoiced__c, Total_Invoiced_Amt__c, Total_Paid_Amt__c From Opportunity Where Id in: opIds]; List<Opportunity> oppsToUpdate = new List<Opportunity>(); for (Id oppyId : oppyToSalesInvoiceMap.keySet()) { Decimal invoicedAmt = 0; Decimal totalPaid = 0; List<Sales_Invoice__c> salesInvoices = oppyToSalesInvoiceMap.get(oppyId); for (Sales_Invoice__c salesInvoice : salesInvoices) { invoicedAmt = invoicedAmt + salesInvoice.Subtotal__c; totalPaid = totalPaid + salesInvoice.Amount_Paid__c; } for (Opportunity o : opps) { o.Total_Invoiced_Amt__c = invoicedAmt; o.Total_Paid_Amt__c = totalPaid; oppsToUpdate.add(o); } } update oppsToUpdate; }
How can I correct the trigger so it will work in bulk mode?
Thanks.
Hi,
Instead of storing in the List, store the values in the "Set". Duplicate errors will be avoided automatically.
Thanks
I'm not quite sure I understand. A set of opportunities is not allowed:
Set<Opportunity> oppsToUpdate = new Set<Opportunity>();
I assume you mean to use the set elsewhere. Can you explain?
Thanks.
Hi,
I would simply replace the list by a map, maps don't store duplicate Id(s). Bear in mind that the latest record will be kept in the map so if there are differences between the 2 (or more) opportunity occurances you will not keep track of the changes.
Hope this helps.
Kr,
Fred
I changed to using a map as suggested and I'm not getting an error when updating using dataloader, but my invoice totals are incorrrect. However, if I just update one record the invoice totals are correct. Not sure why the totals are off when run in batch.
I'm totally all the invoices for a specific opportunity. So, if there are three invoices for Opportunity A, I add the totals for the 3 invoices and update the total into the opportunity. Again, this works for a single opportunity, but when I am running in batch for multiple opportunities, the summations are not correct. Do you see where the error is occurring in my code?
Thanks.
Strange, everything looks good but I’m not used with inner maps so I might be missing something.
One thought, if Opportunity has a master child relationship with Sales_Invoice__c you could use a roll-up summary field on opportunity instead of using a trigger.
Kr,
Fred.