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
Aivaras GeraltauskasAivaras Geraltauskas 

Update failed. First exception on row 0; first error: MISSING_ARGUMENT, Id not specified in an update call

Hi, Would anyone know what the issue is here. I am getting an error: Update failed. First exception on row 0; first error: MISSING_ARGUMENT, Id not specified in an update call. Error is in expression '{!multiInvoice}' in component <apex:commandButton> in page womultiinvoice: Class.woMultiInvoice.multiInvoice: line 138, column 1

The apex code is below:

public class woMultiInvoice {
    private ApexPages.StandardSetController standardSetController;
    public list<workOrder> woListSelected{get; set;}
    public string PONumber{get;set;}
    
    public woMultiInvoice(ApexPages.StandardSetController standardSetController){
        this.standardSetController = standardSetController;
        List<workOrder> selectedListViewRecords = (List<workOrder>) standardSetController.getSelected();
        woListSelected = [select id, locationId, AccountId, WorkOrderNumber, Contract__c, AgreedLabourRate__c, PartsQtyCustomerCharge__c, CustomerReport__c,
                          FirstHourCharge__c, FirstHourRate__c, GeneralLabour__c, HoursCustomerQty__c, TotalLabourPrice__c, Description, Make__c, Model__c, SerialNo__c,
                          (select id, WorkOrderId, Invoice__c, QuantityConsumed, UnitPrice, Product2.Name, Description, TotalPrice__c
                          from ProductsConsumed where invoice__c=null)
                          from WorkOrder where id in:selectedListViewRecords];
    }
    
    public PageReference multiInvoice(){
        
        //place the woListSelected back into the VF page for the Invoicer to review the records
        
        
        //system.debug(selectedListViewRecords);
        list<workOrder> woList;
        set<id> AccountIdSet = new set<id>();
        map<Account, list<workOrder>> invoiceMap = new map <Account, list<workOrder>>();
        
        for(workOrder wo: woListSelected){
            AccountIdSet.add(wo.AccountId);
        }
        system.debug('Number of Contracts in Set: '+AccountIdSet.size());
        
        for(Account acc: [select id from Account where id in:AccountIdSet]){
            woList = new list<WorkOrder>();
            for(workOrder wo: woListSelected){
                if( wo.AccountId ==acc.id)woList.add(wo);
            }
            invoiceMap.put(acc, woList);
        }
        
        
        list<workOrder> woToInvoice = new list<workOrder>();
        list<ProductConsumed> partsList = new list<ProductConsumed>();
        list<timeSheetEntry> labourList = new list<timeSheetEntry>();
        list<InvoiceLineItem__c> invItmList = new list<InvoiceLineItem__c>();
        invoice__c inv = new invoice__c();
        
        for(Account acc:invoiceMap.keyset()){
            woToInvoice = invoiceMap.get(acc);
            partsList = [select id, WorkOrderId, Invoice__c, QuantityConsumed, UnitPrice, Product2.Name, Description, TotalPrice__c
                         from ProductConsumed where invoice__c=null and workOrderId in:woToInvoice];
            
            labourList = [select id, WorkOrderId, Invoice__c, TotalTime__c, NormalTime__c, Overtime__c, OverTimeCharge__c, FirstHour__c, StandardTimeCharge__c
                          from timeSheetEntry where invoice__c=null and workOrderId in:woToInvoice];
            
            inv = new invoice__c(Type__c ='Service Invoice', Cust_Order_No__c = PONumber, Customer_Account_Name__c = acc.id, VAT_Code__c='G',
                                 Invoice_To__c = acc.id);
            insert inv;
            system.debug(inv);
            
            list<InvoiceLineItem__c>partLinesList = new list<InvoiceLineItem__c>();
            list<InvoiceLineItem__c>LabourLinesList = new list<InvoiceLineItem__c>();
            
            for(WorkOrder wo: woToInvoice){
                inv.Contract__c = wo.Contract__c;
                system.debug(wo.ProductsConsumed);
                if(!partsList.isEmpty()){
                    
                    InvoiceLineItem__c invItmParts;
                    for(ProductConsumed pc : partsList){
                        if(pc.WorkOrderId == wo.id){
                            invItmParts = new InvoiceLineItem__c(Name = wo.WorkOrderNumber+' - Parts', Invoice__c = inv.id);
                            invItmParts.Description__c = pc.Product2.Name+' - '+pc.Description;
                            invItmParts.Price__c = pc.UnitPrice;
                            invItmParts.Quantity__c = pc.QuantityConsumed;
                            pc.Invoice__c = inv.id;
                            partLinesList.add(invItmParts);
                            //update wo.ProductsConsumed; 
                        }
                    }
                }
                system.debug(wo.TimeSheetEntries);
                if(!labourList.isEmpty()){
                    InvoiceLineItem__c invItmLabour;
                    for(TimesheetEntry tse: labourList){
                        if(tse.WorkOrderId == wo.id){
                            if(tse.FirstHour__c >0){
                                invItmLabour = new InvoiceLineItem__c(Name = wo.WorkOrderNumber+' - Labour', Invoice__c = inv.id);
                                invItmLabour.Description__c = 'Labour - First Hour';
                                invItmLabour.Quantity__c = tse.FirstHour__c;
                                invItmLabour.Price__c = wo.FirstHourRate__c;
                                LabourLinesList.add(invItmLabour);                 
                            }
                            if(tse.StandardTimeCharge__c >0){
                                invItmLabour = new InvoiceLineItem__c(Name = wo.WorkOrderNumber+' - Labour', Invoice__c = inv.id);
                                invItmLabour.Description__c = 'Labour';
                                invItmLabour.Quantity__c = tse.StandardTimeCharge__c;
                                invItmLabour.Price__c = wo.AgreedLabourRate__c;
                                LabourLinesList.add(invItmLabour);
                            }
                            if(tse.OverTimeCharge__c >0){
                                invItmLabour = new InvoiceLineItem__c(Name = wo.WorkOrderNumber+' - Labour', Invoice__c = inv.id);
                                invItmLabour.Description__c = 'Labour - OOH';
                                invItmLabour.Quantity__c = tse.OverTimeCharge__c;
                                invItmLabour.Price__c = wo.OOHRate__c;
                                LabourLinesList.add(invItmLabour);
                            }
                            tse.Invoice__c =  inv.id;
                        }
                        //update wo.TimeSheetEntries;
                    }
                    
                }
                
                wo.InvoiceStatus__c = 'Invoiced';
                wo.Invoice__c = inv.id;

                
            }
            insert partLinesList;
            insert LabourLinesList;
            update partsList;
            update labourList;
            
            map<id, ServiceAppointment> SAMap = new map<id,ServiceAppointment>([select id, ParentRecordId from ServiceAppointment where ParentRecordId in:woToInvoice]);
            list<ServiceReport> sReportList = [select id, ParentId, CONTENTVERSIONDOCUMENTID, CONTENTVERSIONDOCUMENT.ContentDocumentId from ServiceReport where ParentId in:SAMap.keySet()];
            list<contentDocumentLink> cdlList = new list<contentDocumentLink>();
            for(serviceReport sr: SReportList){
                ServiceAppointment sa = SAMap.get(sr.ParentId);
                contentDocumentLink cdl = new contentDocumentLink();
                cdl.LinkedEntityId = inv.id;
                cdl.ContentDocumentId = sr.CONTENTVERSIONDOCUMENT.ContentDocumentId;
                cdlList.add(cdl);                
                
            }
            insert cdlList;
            
        }

        update woListSelected;
        update inv;
        system.debug(inv.id);
        
        PageReference reloadPage = new PageReference ('/lightning/r/Invoice__c/'+inv.id+'/view');
        system.debug(reloadPage);
        reloadPage.setRedirect(true);
        return reloadPage;
    
    }

 
AnudeepAnudeep (Salesforce Developers) 
Hi Aivaras, 

As far as I know, the issue lies in the below part of the code. The error 'Id not specified in an update call' usually occurs when the ID in where clause is not properly mapped to the ID field meaning 'selectedListViewRecords' might not be returning a list of Ids

Can you verify if selectedListViewRecords is actually returning list of Ids by adding a system.debug statement after line no 8? You can also try hard coding the Id in the SOQL query just to narrow the issue down
 
List<workOrder> selectedListViewRecords = (List<workOrder>) standardSetController.getSelected();
        woListSelected = [select id, locationId, AccountId, WorkOrderNumber, Contract__c, AgreedLabourRate__c, PartsQtyCustomerCharge__c, CustomerReport__c,
                          FirstHourCharge__c, FirstHourRate__c, GeneralLabour__c, HoursCustomerQty__c, TotalLabourPrice__c, Description, Make__c, Model__c, SerialNo__c,
                          (select id, WorkOrderId, Invoice__c, QuantityConsumed, UnitPrice, Product2.Name, Description, TotalPrice__c
                          from ProductsConsumed where invoice__c=null)
                          from WorkOrder where id in:selectedListViewRecords];
    }

If you find the information provided above helpful, please mark this answer as Best. It may help others in the community. Thank You!

Anudeep