+ Start a Discussion

Updating custom object RecordType in trigger not working correctly

Hi all - 

I am using  trigger to create some roll-up like behavior on a look-up relationship.  The trigger counts the number of InventoryItem__c objects associated to the SalesOrderLineItem__c (SOLI) object and updates a field on the SOLI.  I also want to run some logic that will change the RecordType of the SOLI object if the number of inventory items attached is equal to the number of items ordered.

My issue is that the trigger will not update the RecordType on the SOLI object to "locked", even when the code to lock the record is executed.  If I run my trigger logic in the Execute Anonymous window the RecordType is updated as expected, but when the logic executes from the trigger the RecordType is unchanged.

If I take a locked record and remove inventory from it the trigger will update the SOLI object to use the unlocked record type.

I can't figure out where I'm going wrong here, any help would be appreciated.

Here is the logic from the Execute Anonymous window.  The logic matches what is in the trigger, but I've updated it here to look for one specific SOLI record rather than to use the trigger new and old maps.

//unique soli Object Ids
    private  Set<Id>  soliIdSet = new Set<Id>();

    //hold list of soli Record to be update
    private List<SalesOrderLineItem__c>  soliListUpdatable = new List<SalesOrderLineItem__c>();
    private RecordType locked;
    private RecordType unlocked;
    private List<RecordType> rtList = [SELECT Name, Id From RecordType WHERE SobjectType = 'SalesOrderLineItem__c'];
            for(RecordType rT:rtList){
              if(rT.Name == 'Locked')
                locked = rT;
              if(rT.Name == 'Unlocked')
                unlocked = rT;
            }//end for loop

    //select the soli list
    Map<ID,SalesOrderLineItem__c> soliMap = new Map<ID,SalesOrderLineItem__c> ([Select Id, Quantity_Shipped__c, Quantity__c, RecordTypeId from SalesOrderLineItem__c WHERE ID IN :soliIdSet]);

    for(SalesOrderLineItem__c soliObj : [Select ID,(Select ID FROM Inventory_Items__r) from SalesOrderLineItem__c WHERE ID IN :soliIdSet]){

        soliMap.get(soliObj.ID).Quantity_Shipped__c = soliObj.Inventory_Items__r.size();//assigning Size
        if(soliMap.get(soliObj.ID).Quantity_Shipped__c == soliMap.get(soliObj.ID).Quantity__c){
          soliMap.get(soliObj.ID).RecordTypeId = locked.Id;
          soliMap.get(soliObj.ID).RecordTypeId = unlocked.Id;
        System.debug('After recordtype update: ' + soliMap.get(soliObj.ID));
    if(soliListUpdatable != NULL && soliListUpdatable.size() > 0)
        System.debug('The updateable solilist: ' + soliListUpdatable);
        UPDATE soliListUpdatable;

I've been trying a few things and it seems like the trigger is working ok if I modify the inventoryitem object form the standard SF edit page.  But the recordtype change to lock isn't working when the inventoryitem objects are modified from a controller extension.  

Here is the code for my controller extension (I made the method that updated the inventoryitem object bold):

public class shipOrder_v0_3 {
public Sales_Order__c order {get; set;}
public List<SalesOrderLineItem__c> soliList {get; set;}
List<SalesOrderLineItem__c> soliIdList {get; set;}
public SalesOrderLineItem__c soli {get; set;}
public String shipQty {get; set;}
Map<String,Decimal> shipQtyMap {get; set;}
Map<String,Decimal> boQtyMap {get; set;}
public List<String> inventoryList {get; set;}
public Map<String, List<wInventoryItem>> availableInventoryMap;
public Map<String, List<wInventoryItem>> selectedInventoryMap {get; set;}
public String shipDate {get; set;}
public String trackingNumber {get; set;}
//public List<wLineItem> itemList {get; set;}
public Shipment__c shipment {get; set;}
public String currentLineItem {get; set;}
public List<wInventoryItem> currentLineItemList {get; set;}
public List<Map<String, List<wInventoryItem>>> selectedMapList {get; set;}
ApexPages.StandardSetController setCon;

    public shipOrder_v0_3(ApexPages.StandardSetController controller2) {
      String orderId = ApexPages.currentPage().getParameters().get('id');
      order = [SELECT Id, Name, Shipping_Method__c,Collect_Account__c, Status__c, Ship_Collect__c,Ship_To__c, (SELECT Id, Name, Quantity__c, Quantity_Shipped__c FROM Sales_Order_Line_Items__r)
               FROM Sales_Order__c WHERE ID = :orderId LIMIT 1];
       soliIdList = (List<SalesOrderLineItem__c>)controller2.getSelected();
      Set<Id> idList = new Set<Id>{};
      //this is a test variable to try and get the VF page to display map data as desired
      selectedMapList = new List<Map<String, List<wInventoryItem>>>{};
      String idset;
      //setCon = controller2;
      System.debug('The number of selected records: ' +controller2.getSelected().size());
      soliList = new List<SalesOrderLineItem__c>{};
      //define the details of the shipment object that will be inserted into the database
      shipment = new Shipment__c(Sales_Order__c = order.Id, Address__c = order.Ship_To__c,Collect_Account__c = order.Collect_Account__c, Shipping_Method__c = order.Shipping_Method__c);
      soli = new SalesOrderLineItem__c();
      shipQtyMap = new Map<String, Decimal>{};
      boQtyMap = new Map<String, Decimal>{};
      for(SalesOrderLineItem__c asoli:soliIdList){
        idset += asoli.Id +',';
        System.debug('The idList:' + idList);
      //***********this if statement is to assist development. it should be deleted when development is finished*********************
       System.debug('soliList was empty');
      }  //*********** end this if statement is to assist development. it should be deleted when development is finished*********************
      //itemList = new List<wLineItem>{};
      for(SalesOrderLineItem__c soli:createSoliQuery(idList)){
        boQtyMap.put(soli.Name, soli.Quantity_BO__c);
       // wLineItem lineItem = new wLineItem(soli);
       // itemList.add(lineItem);
      System.debug('************** SOLIList: ' + soliList + 'availableInventoryMap: ' + availableInventoryMap + 'ShipQTYMap: ' + shipQtyMap);
      System.debug('************** boQTYMap: ' + boQtyMap);
      //System.debug('***************** lineItem list: ' + itemList);
    } // end constructor

    //***************Code for Adding/Removing line items to/from the selected inventory map *****************************************
  // displays the selected items
  public PageReference addToTempSelected() {
    String selectKey = ApexPages.currentPage().getParameters().get('selectKey');
    // if selectedInventoryMap is null, create a new map and add a null list for each sales order line item selected for shipment
    //System.debug('The current selected line item = ' + currentLineItem + 'CurrentLineitemList: ' + currentLineItemList);
    if(selectedInventoryMap == null){
      //System.debug('selectedInventoryMap is null!');
      selectedInventoryMap = new Map<String, List<wInventoryItem>>{};
      for(SalesOrderLineItem__c soli:soliList){
        selectedInventoryMap.put(soli.Name,new List<wInventoryItem>{});
      }//end for loop
    }//end if
    // Instantiate a new temporary list to add user slected inventory to
    List<wInventoryItem> tempSelectedList = new List<wInventoryItem> {};
    tempSelectedList = selectedInventoryMap.get(currentLineItem);

    List<wInventoryItem> tempList = availableInventoryMap.get(currentLineItem) ;
    Decimal selectedQty = tempSelectedList.size();
    System.debug('Value of shipQtyMap for ' + currentLineItem + ' = ' + shipQtyMap.get(currentLineItem));
    //System.debug('tempSelectedList size before add: ' + tempSelectedList.size());
    for(Integer i =0;i< tempList.size();i++) {
      if(tempList[i].item.SerialNumber__c == selectKey) {
        selectedQty += 1;
        System.debug('added to tempList: '+ tempList[i]+ 'selectedQty: ' +selectedQty);
        if(selectedQty > boQtyMap.get(currentLineItem)){
          system.debug('**************** You have tried to add too much inventory *************');
          throw new InvalidShipQtyException('Sufficient inventory has already been added to this line item to fulfill the order - unable to attach additional inventory');
        }catch(InvalidShipQtyException isqe){
          tempList[i].selected = false;
          selectedQty -= 1;
        }//end if 
    }// end for loop
    shipQtyMap.put(currentLineItem, selectedQty);
    System.debug('tempSelectedList after add: ' + tempSelectedList.size() + 'ShipQtyMap value for '+ currentLineItem +' : ' + shipQtyMap.get(currentLineItem));
    selectedInventoryMap.put(currentLineItem, tempSelectedList);
    return null;
  } // end method addToTempSelected
  // This method cycles through the list of selected inventory items and removes those that have
  // been un-selected by the user
  public Pagereference removeSelection(){
    System.debug('removeIndex: '+ ApexPages.currentPage().getParameters().get('removeIndex'));
    String index = ApexPages.currentPage().getParameters().get('removeIndex');
    String key = ApexPages.currentPage().getParameters().get('removeKey');
    System.debug('removekey: ' + key);
    List<wInventoryItem> tempSelectedList = selectedInventoryMap.get(key);
    List<wInventoryItem> tempList = availableInventoryMap.get(key);
    System.debug('Map: ' + selectedInventoryMap + ' List: ' + tempSelectedList);
    for(Integer i = 0;i<tempSelectedList.size();i++){
      System.debug('Iteration number: ' + i);
      if(index == tempSelectedList[i].item.SerialNumber__c){
        tempSelectedList[i].selected = false;
        for(wInventoryItem wItem:tempList){
          if(index == tempList[i].item.SerialNumber__c){
            tempList[i].selected = false;
          } // end if to change selected status in results area
        }  // end for loop to update selected status
      } // end if
    }// end for loop
    return null; 
    } //end method removeSelection
    //***************END Selected products add/remove code******************************************
    public PageReference selectInventory(){
      currentLineitem = ApexPages.currentPage().getParameters().get('lineItem');
      System.debug('selectInventory called! ' + currentLineItem + 'From Param: ' + ApexPages.currentPage().getParameters().get('lineItem'));
      currentLineitemList = availableInventoryMap.get(currentLineItem);
      return null;
    public PageReference doShip(){
      System.debug('Do ship called');
        Database.SaveResult sr = Database.Insert(shipment);
        //if the shipment object is inserted successfully attach specified inventory items and update Sales Order, Sales Order Line Item,
        //and inventory items with shipment ID
          System.debug('*****************************From doShip: Shipment ID= ' + sr.getId());
          for(SalesOrderLineItem__c soli:soliList){
            System.debug('SOLI: ' + soli + ' : key in map?: '+ selectedInventoryMap.containsKey(soli.Name));
              List<InventoryItem__c> itemList = new List<InventoryItem__c>{};
              List<wInventoryItem> tempItemList = selectedInventoryMap.get(soli.Name);
              System.debug('Selected QTY for' + soli.Name + ' = ' + tempItemList.size());
              soli.Shipped_Date__c = shipment.Shipment_Date__c;
              soli.Quantity_Shipped__c += shipQtyMap.get(soli.Name);

              System.debug('shipQtymap value for ' + soli.Name +': ' + shipQtyMap.get(soli.Name) + 'soli qty value: '+ soli.Quantity_Shipped__c);
              for(wInventoryItem item:tempItemList){
                item.item.Shipment__c = shipment.Id;
                item.item.Date_Shipped__c = shipment.Shipment_Date__c;
                item.item.Sales_Order_Product__c = soli.Id;
                item.item.Status__c = 'sold';
              }//end nested for loop
              update itemList;

            }// end if
          }// end for loop
          update soliList;
          System.debug('Page should redirect 1');
          PageReference detail = new ApexPages.StandardController(order).view();
          System.debug('Page should redirect 2');
          return detail;
          }// end if
      }catch(Exception e){
      return null;
    }// end method doShip

    public Map<String, List<wInventoryItem>> getavailableInventoryMap(){
      return availableInventoryMap;
    }//end getavailableInventoryMap
    public void setInventory(List<SalesOrderLineItem__c> soliList){
      if(availableInventoryMap == null)
        availableInventoryMap = new Map<String, List<wInventoryItem>>{};
      for(SalesOrderLineItem__c soli:soliList){
        System.debug('From setinventory: ' + soli);
        List<InventoryItem__c> anItemList = [SELECT Product__c, Name, Activation_Code__c, Sales_Order_Product__c, Shipment__c, Status__c, SerialNumber__c, Product__r.ProductCode, ProductCode__c
                                             From InventoryItem__c WHERE Product__c = :soli.product__r.id AND Status__c = 'inventory' ORDER BY SerialNumber__c];
        System.debug('from setinventory: ' + anItemList[0].ProductCode__c);
        List<wInventoryItem> wItemList = new List<wInventoryItem>{};
        for(InventoryItem__c item:anItemList){
          wItemList.add(new wInventoryItem(item));
        }// end nested for loop;
        availableInventoryMap.put(soli.Name, wItemList);
      }//end for loop
    }//end method setInventory
    //This method checks all the line items of the order to determine if the entire order is shipped
    //if the order is shipped the status is updated to 6-Shipped
    private void updateOrderStatus(){
      boolean allShipped = true;
      System.debug('updateOrderStatusCalled - Order Id : ' + order.Id + 'Status: ' + order.Status__c);
        for(SalesOrderLineItem__c soli:order.Sales_Order_Line_Items__r){
          System.debug(soli.Name +' Shipped QTY: ' + soli.Quantity_Shipped__c +'!! Order QTY: '+ soli.Quantity__c);
          //if(shipQtyMap.get(soli.Id) != null && Integer.valueOf(shipQtyMap.get(soli.Id)) > 0 ){
           if(shipQtyMap.get(soli.Name) != null && shipQtyMap.get(soli.Name) > 0 ){
             System.debug('This line item is being shipped in this shipment: '+ soli.name);
             if(soli.Quantity_Shipped__c + shipQtyMap.get(soli.Name)  != soli.Quantity__c){
               allShipped =false;
               order.Status__c = '5.5 - Partial Shipment';
               System.debug('allShipped? ' + allShipped);
               } // end if
             }else if(soli.Quantity_Shipped__c != soli.Quantity__c){
               System.debug( 'Soli shipped QTY: ' + soli.Quantity_Shipped__c + ' Soli qty: ' + soli.Quantity__c);
               allShipped = false;
               System.debug('All BO for this line item is fullfilled! - ' + soli.Name);
             }//end if-else
        }//end for loop
          order.Status__c = '6 - Shipped';
        }//end if
        System.debug('The so details: ' + order);
        update order;
      }catch(DMLException e){
      }// end try-catch
    }//end method updateOrderStatus

    //method to create discountSchedule dataBase query
   public List<SalesOrderLineItem__c> createSoliQuery(Set<Id> sList){
       List<Schema.FieldSetMember> shippingInformation= SObjectType.SalesOrderLineItem__c.FieldSets.Shipping_Information.getFields();
       String query = 'SELECT ';
        for(Schema.FieldSetMember f : shippingInformation) {
            query += f.getFieldPath() + ', ';
        query += 'Id, Product__r.Id FROM SalesOrderLineItem__c WHERE Id IN :sList';
        return Database.query(query);
    public class InvalidShipQtyException extends Exception{
    } // end inner-class

   // ******************** Inner  Classes ********************************************************
    // This code is used to process the required workflow when a WebPort Connects product is purchased.
    private class WPCService{
      private ServiceContract createWPCServiceAgreement(String ActivationCode){
        ServiceContract s1 = new ServiceContract(name = ActivationCode); 
        return s1;
    } // end class WPCService
    /*This is our wrapper/container class. A container class is a class, a data
    structure, or an abstract data type whose instances are collections of other
    objects. In this example a wrapper class contains  */
    public class wInventoryItem{

    public Boolean selected{ get; set; }
    public SalesOrderLineItem__c soli{ get; set;}
    //public Map<String, String> parameters {get; set;}
    public InventoryItem__c item {get; set;}
    //public List<String> serialNumbersList {get; set;}
    //public Boolean multiItem{ get; set;}

    public wInventoryItem(InventoryItem__c inventory){
        //soli = sLineItem;
        selected = false;
        item = inventory;
        //Parameters = new Map<String, String>{'shipQty' => '', 'startItem' => '', 'endItem' => ''};
       // multiItem = false;
    } //end constructor
   } //end inner class wInventory
    /* public class wLineItem {

    public Boolean selected{ get; set; }
    public SalesOrderLineItem__c soli{ get; set;}
    public Map<String, String> parameters {get; set;}
    public List<InventoryItem__c> inventoryList {get; set;}
    public List<String> serialNumbersList {get; set;}
    public Boolean multiItem{ get; set;}

    public wLineItem(SalesOrderLineItem__c sLineItem){
        soli = sLineItem;
        inventoryList = new List<InventoryItem__c>{};
        Parameters = new Map<String, String>{'shipQty' => '', 'startItem' => '', 'endItem' => ''};
        multiItem = false;
   } //end inner class wProduct */