0

I am writing trigger to update an order line item of order related to an Account when an invoice line item is inserted corresponding to that order line item. Problem is whenever a loop is iterating over order line item its showing null pointer exception when i am adding an order line item to list if my outer map contains account key and its not null.

object structure is Account(Master) --> Order(child) --> OrderLineItem(child of Order) Account(Master) --> Invoice(child) --> InvoiceLineItem(child of Invoice)

here is my code:

public with sharing class InvoiceLineItemHandler {

    public static void updateOrderLineItems(List<Invoice_Line_Item__c> listOfInvLineItems)
    {
        Map<Id,Map<Id,List<Order_Line_Item__c>>> mapofolineItems = new Map<Id,Map<Id,List<Order_Line_Item__c>>>();
        Map<Id,Order_Line_Item__c> orderlinemap = new Map<Id,Order_Line_Item__c>();
        Set<Id> accId = new Set<Id>();
        List<Order_Line_Item__c> olineitemstoUpdate = new List<Order_Line_Item__c>(); 
        List<Order_Line_Item__c> olistitem = new List<Order_Line_Item__c>();

       for(Invoice_Line_Item__c ili : listOfInvLineItems)
        {
            system.debug('this is inside first if');
            if(ili.AccountId__c != null)
               accId.add(ili.AccountId__c);
            system.debug('this is accid'+accId);
        }
        for(Order_Line_Item__c oli : [Select id, Amount__c,Order__r.AccountId,Order__r.Id,Order_Line_Number__c,Quantity__c from Order_Line_Item__c where Order__r.AccountId in:accId])
        {
            system.debug('inside for');
            if(mapofolineItems.containsKey(oli.Order__r.AccountId) && mapofolineItems.get(oli.Order__r.AccountId) != null){

                system.debug('this is inside if 2');
                olineitemstoUpdate = mapofolineItems.get(oli.Order__r.AccountId).get(oli.Order__r.Id);
                system.debug('this is olineitems at line number 25'+olineitemstoUpdate);
                olineitemstoUpdate.add(oli);
                mapofolineItems.get(oli.Order__r.AccountId).put(oli.Order__r.Id,olineitemstoUpdate);
                system.debug('this is map of account to order and order line items'+mapofolineItems);
            }
            else
            {
                mapofolineItems.put(oli.Order__r.AccountId, new Map<Id,List<Order_line_Item__c>> {oli.Order__r.id => olineitemstoUpdate});
                system.debug('this is map of account to order and order line items for else condition'+mapofolineItems);
            }
        }

        olistitem = new List<Order_Line_Item__c>();
        for(Invoice_Line_Item__c invlines: [Select id, Amount__c,Order_Line_No__c, Quantity__c,Invoice__r.Account__r.id from Invoice_Line_Item__c where Invoice__r.Account__r.Id in:accId])
           {
                  for(Order_Line_Item__c olic : olineitemstoUpdate)
                  {
                      if(olic.Order_Line_Number__c == invlines.Order_Line_No__c && olic.Quantity__c == invlines.Quantity__c)
                         olic.Payment_Status__c = 'Paid';
                         olistitem.add(olic);
                  }
           }

        orderlinemap = new Map<Id,Order_Line_Item__c>();
        orderlinemap.putall(olistitem);
        if(orderlinemap.size()>0)
        {
            try
              {
              update orderlinemap.values();
              system.debug('this is updated order line items'+orderlinemap.values());
              }
             catch(DMLException e)
             {
              system.debug('updation failed'+e.getMessage());
             }
        }
    }

}

and my line of error is :

 if(mapofolineItems.containsKey(oli.Order__r.AccountId) && mapofolineItems.get(oli.Order__r.AccountId) != null){

                system.debug('this is inside if 2');
                olineitemstoUpdate = mapofolineItems.get(oli.Order__r.AccountId).get(oli.Order__r.Id);
                system.debug('this is olineitems at line number 25'+olineitemstoUpdate);
                **olineitemstoUpdate.add(oli);**
2
  • 1
    I'm unable to reproduce this error, but I thought it might have arisen from your Order_Line_Item__c record(s) not being related to an Order (i.e. Order__c is blank, which would make oli.Order__r null). Honestly though, this code seems to be doing a lot of unnecessary work. The problematic bit, mapofolineItems, is never used outside of the loop that populates it (and every Account, Order pair would contain all of your line items). – Derek F Dec 6 '19 at 17:56
  • I got ur point derek but how should i connect order with invoice so that i am looping only inside required order record and not outside it. – Ashutosh Srivastava Dec 6 '19 at 18:17
0

I would build a map of Order Line Items by a composite key (concatenation of Account Id and the Order Line Number). Then I would iterate over the Invoice Line Items and for each Invoice Line Item, get the corresponding Order Line Item and do the processing.

First we get all the account IDs to query their Order Line Items:

Set<Id> allAccountIDs = new Set<Id>();
for (Invoice_Line_Item__c ili : listOfInvLineItems) {
    allAccountIDs.add(ili.AccountId__c);
}
// the following is not necessary unless 
// you have Invoice Line Item that are not linked to any account!
allAccountIDs.remove(null); 

Build the Order Line Items map by a composite key:

Map<String, Order_Line_Item__c> oliByAccLineNo = new Map<String, Order_Line_Item__c>(); 
for (Order_Line_Item__c oli : [
        SELECT Order_Line_Number__c, Quantity__c
        FROM Order_Line_Items__r
        WHERE Order__r.AccountId = :allAccountIDs
    ]) {
    String key = Order__r.AccountId + '|' + oli.Order_Line_Number__c;
    oliByAccLineNo.put(key, oli);
}

Then, iterate over the Invoice Line Items and update the matching Order Line Items, and finally update them:

List<Order_Line_Item__c> olisForUpdate = new List<Order_Line_Item__c>();
for (Invoice_Line_Item__c ili : listOfInvLineItems) {
    String key = ili.AccountId__c + '|' + ili.Order_Line_No__c;
    Order_Line_Item__c oli : oliByAccLineNo.get(key);
    if (oli != null && oli.Quantity__c == ili.Quantity__c) {
        oli.Payment_Status__c = 'Paid';
        olisForUpdate.add(oli);
    }
}
update(olisForUpdate);
5
  • Not working, again on updating its looking for exact order id with which its related and if not founding its not updating anything. – Ashutosh Srivastava Dec 8 '19 at 7:59
  • On which line did you have the error? – Hengky Ilawan Dec 8 '19 at 9:58
  • if i debug map which u r using for putting values like on this line oliByAccLineNo.put(key, oli); then i get null values in key in places where my oli is not related to order id. – Ashutosh Srivastava Dec 8 '19 at 10:11
  • Could you put some more details on your object model between those objects? How come your order line item can be not related to an order. – Hengky Ilawan Dec 8 '19 at 13:41
  • okay so i have solved it myself.. the issue in my code was actually i was notin any specific order in which the order line item is related. it was searching all the orders and their line items. the orders which were not related to the line items were throwing errors in loop. i have written my object model in question details given above. thanks by the way hengky for your help. – Ashutosh Srivastava Dec 8 '19 at 19:45

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.