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
Scott Janis 20Scott Janis 20 

Test Class for a Opp Line Item Trigger

How can I write a text class for this code. 

trigger MDP_Tgr_OpportunityLineItem_Before on OpportunityLineItem (before insert, before update, before delete) {
    system.debug('invoking the before trigger of OpportunityLineItem');
    // for update
    if(trigger.isUpdate || trigger.isInsert){
      if(trigger.isInsert){
          MDP_Tgr_OppLine_Handler.assignOppFieldValuesToOLI(trigger.new);
        }
        if(trigger.isUpdate) {
            MDP_Tgr_OppLine_Handler.updateTitle(trigger.new);
            MDP_Tgr_OppLine_Handler.checkFieldValueChange(trigger.new, trigger.oldMap);
        }
        MDP_Tgr_OppLine_Handler.updateOracleOverride(trigger.new);  
         //MDP_Tgr_OppLine_Handler.checkTotalNEP(trigger.new, trigger.newMap);    // moved to after trigger
    }
    if(trigger.isDelete){      
      system.debug('in the Delete');  
        MDP_Tgr_OppLine_Handler.operativeAPIProfileGotError(trigger.old);
        MDP_Tgr_OppLine_Handler.insertOppLineItemRecToTempCustObj(trigger.old);
    }
}
AnkaiahAnkaiah (Salesforce Developers) 
Hi Scott,

Can you share the MDP_Tgr_OppLine_Handler class will help you with code.

Thanks!!
Scott Janis 20Scott Janis 20
public class MDP_Tgr_OppLine_Handler {
  // declare class level variables
  public static string profileName = MDP_Utils.profileName(UserInfo.getProfileId());          // holds the Profile Name of the logged in User

  /**
  * @author        Sulabh Kapoor
  * @date          02/15/2018
  * @description   method to restict changes on the OpportunityLineItem once it is moved to the status of Insertion
  * @param         list<OpportunityLineItem> lstOLI, Map<ID, OpportunityLineItem> oldMapOLI
  * @return        null
  */
  public static void checkFieldValueChange(list<OpportunityLineItem> lstOLI, map<ID, OpportunityLineItem> oldMapOLI){
    system.debug('in the checkFieldValueChange() method of MDP_Tgr_OppLine_Handler class');
    // field set which has all the fields which are locked for any updates
    List<Schema.FieldSetMember> fieldsetMembers = MDP_Utils.readFieldSet('OLI_FieldsLockedAfterClosedStage', 'OpportunityLineItem');

    // iterate over the opportunitylineitem list and check if the current logged in user is allowed to make an update
    // 1. if the Order is/ was yet not invoiced then Ad Ops, Business Managers and Sys Admins can make an update
    // 2. if the Order is/ was Ready to Bill or invoiced, then only Integration, Business Manager and Admin user can make an update
    for(OpportunityLineItem oli : lstOLI){
      system.debug('oli.Issue_Ready_To_Bill__c' + oli.Issue_Ready_To_Bill__c);
      system.debug('oli.Issue_Is_Invoiced__c' + oli.Issue_Is_Invoiced__c);
      System.debug('profileName' + profileName);
      //Start: SF2-825 - Shridhar Hegde
      oli.Quantity = 1.00;
      //End: SF2-825 - Shridhar Hegde
      if(
        oli.Opp_Record_Type__c == MDP_Utils.PRINT_OP_RT_ID
        &&
        (oli.Opp_Stage__c == MDP_Utils.PRINT_OPP_100_WON || oldMapOLI.get(oli.Id).Opp_Stage__c == MDP_Utils.PRINT_OPP_100_WON)
        &&
        (
          (
            (oli.Issue_Ready_To_Bill__c || oli.Issue_Is_Invoiced__c)
            &&
            (profileName != MDP_Utils.SYS_ADMIN && profileName != MDP_Utils.INTEGRATION && profileName != MDP_Utils.BUSINESS_MGR)
          )
          ||
          (!oli.Issue_Is_Invoiced__c && profileName != MDP_Utils.SYS_ADMIN && profileName != MDP_Utils.AD_OPS && profileName != MDP_Utils.INTEGRATION && profileName != MDP_Utils.BUSINESS_MGR)
        )
      ){

            System.debug('@@@' + fieldsetMembers);

        for(Schema.FieldSetMember field: fieldsetMembers) {
          System.debug('New Value '+(oli.get(field.getFieldPath())) + ' Previous Value -- ' + oldMapOLI.get(oli.id).get(field.getFieldPath()));
          if(oli.get(field.getFieldPath()) != oldMapOLI.get(oli.id).get(field.getFieldPath())){
            system.debug('You are not allowed to make modifications to the Order which is already Inserted --- '+oli.id);
            oli.addError(system.label.MDP_FieldLockError);
          }
        }
      }
    }
    system.debug('end of the checkFieldValueChange() method of MDP_Tgr_Opportunity_Handler class');
  }

  /**
  * @author        Ramakrishna Singara
  * @date          03/28/2018
  * @description   method to create records on Temp OLI Object when the OLI is deleted
  * @param         list<OpportunityLineItem> lstOLI
  * @return        null
  */
  public static void insertOppLineItemRecToTempCustObj(list<OpportunityLineItem> lstOLI) {
    system.debug('in the insertOppLineItemRecToTempCustObj() method of MDP_Tgr_OppLine_Handler class');
    list<Temp_Opportunity_Line_Item__c> lstTempOLIObj = new list<Temp_Opportunity_Line_Item__c>(); // holds the Temp OLI records
    system.debug('lstOLI : - '+lstOLI.size());
    system.debug('lstOLI : - '+lstOLI);

    list<Temp_OLI_Field_Mapping__mdt> fldMapList = [select Source_Field_API__c, Target_Field_API__c from Temp_OLI_Field_Mapping__mdt];

    for(OpportunityLineItem oli : lstOLI){
      Temp_Opportunity_Line_Item__c tempOliObj = new Temp_Opportunity_Line_Item__c();
      sObject sourceObj = (sObject) oli;
      sObject targetObj = (sObject) tempOliObj;
      //sourceObj = (sObject)oli;
      //for(Temp_OLI_Field_Mapping__mdt fm : [select Source_Field_API__c, Target_Field_API__c from Temp_OLI_Field_Mapping__mdt]){
      for(Temp_OLI_Field_Mapping__mdt fm : fldMapList){
        system.debug('source Obj : - '+sourceObj.get(fm.Source_Field_API__c));
        //system.debug('target Obj : - '+targetObj.put(fm.Target_Field_API__c, sourceObj.get(fm.Source_Field_API__c)));
        //sourceObj.get(fm.Source_Field_API__c);

        targetObj.put(fm.Target_Field_API__c, sourceObj.get(fm.Source_Field_API__c));
        system.debug('sourceObj : - '+sourceObj);
        system.debug('targetObj : - '+targetObj);
      }

      tempOLIObj = (Temp_Opportunity_Line_Item__c) targetObj;
      lstTempOLIObj.add(tempOLIObj);
    }
    system.debug('lstTempOLIObj : - '+lstTempOLIObj.size());
    system.debug('lstTempOLIObj : - '+lstTempOLIObj);
    // Check the Temp OLI List is not Empty
    if(!lstTempOLIObj.isEmpty()){
      Database.Saveresult[] dbSave = database.insert(lstTempOLIObj, false);
      MDP_ErrorHelper.processSaveResults(dbSave, 'MDP_Tgr_OppLine_Handler', 'insertOppLineItemRecToTempCustObj()', lstTempOLIObj, 'OpportunityId__c');
    }

    /*list<Temp_Opportunity_Line_Item__c> lstTempOLIObj = new list<Temp_Opportunity_Line_Item__c>(); // holds the Temp OLI records

    // Iterate OLI to prepare Temp OLI records
    for(OpportunityLineItem oli : lstOLI){
      Temp_Opportunity_Line_Item__c tempOLIObj = new Temp_Opportunity_Line_Item__c();
      tempOLIObj.Ad_Unit__c = oli.Ad_Unit__c;
      tempOLIObj.Brand__c = oli.Brand__c;
      tempOLIObj.Color__c = oli.Color__c;
      tempOLIObj.Copy_Split_Type__c = oli.Copy_Split_Type__c;
      tempOLIObj.Coupon__c = oli.Coupon__c;
      tempOLIObj.Creative_Received_Date__c = oli.Creative_Received_Date__c;
      tempOLIObj.Current_Billed_Amount__c = oli.Current_Billed_Amount__c;
      tempOLIObj.Customer_Transaction_Line_ID__c = oli.Customer_Transaction_Line_ID__c;
      tempOLIObj.Custom_Ad_Unit_Lines__c = oli.Custom_Ad_Unit_Lines__c;
      tempOLIObj.Description__c = oli.Description;
      tempOLIObj.Distribution_Requirements__c = oli.Distribution_Requirements__c;
      tempOLIObj.Exclude_from_PIB_Reporting__c = oli.Exclude_from_PIB_Reporting__c;
      tempOLIObj.HasQuantitySchedule__c = oli.HasQuantitySchedule;
      tempOLIObj.HasRevenueSchedule__c = oli.HasRevenueSchedule;
      tempOLIObj.HasSchedule__c = oli.HasSchedule;
      tempOLIObj.Height__c = oli.Height__c;
      tempOLIObj.Historical_MU__c = oli.Historical_MU__c;
      tempOLIObj.Historical_NEP__c = oli.Historical_NEP__c;
      tempOLIObj.Historical_Order__c = oli.Historical_Order__c;
      tempOLIObj.Insert_Type__c = oli.Insert_Type__c;
      tempOLIObj.Invoice_line_Description__c = oli.Invoice_line_Description__c;
      tempOLIObj.Is_Cloned__c = oli.Is_Cloned__c;
      tempOLIObj.Legacy_MU_ID__c = oli.Legacy_MU_ID__c;
      tempOLIObj.Length__c = oli.Length__c;
      tempOLIObj.Line_Item_Number__c = oli.Line_Item_Number__c;
      tempOLIObj.ListPrice__c = oli.ListPrice;
      tempOLIObj.Name = oli.Name;
      tempOLIObj.NEP__c = oli.NEP__c;
      tempOLIObj.Open_Rate__c = oli.Open_Rate__c;
      tempOLIObj.OpportunityId__c = oli.OpportunityId;
      tempOLIObj.OpportunityLineItem_Id__c = oli.id;
      tempOLIObj.Oracle_Natural_Account__c = oli.Oracle_Natural_Account__c;
      tempOLIObj.Order_Received_Date__c = oli.Order_Received_Date__c;
      tempOLIObj.Original_Billed_Amount__c = oli.Original_Billed_Amount__c;
      tempOLIObj.Page_Number__c = oli.Page_Number__c;
      tempOLIObj.PIB_Code_Override__c = oli.PIB_Code_Override__c;
      tempOLIObj.Positioning_Comments__c = oli.Positioning_Comments__c;
      tempOLIObj.Premium_Position__c = oli.Premium_Position__c;
      tempOLIObj.Premium_Rate_Override__c = oli.Premium_Rate_Override__c;
      tempOLIObj.PricebookEntryId__c = oli.PricebookEntryId;
      tempOLIObj.Price_Override_Reason__c = oli.Price_Override_Reason__c;
      tempOLIObj.Product2Id__c = oli.Product2Id;
      tempOLIObj.ProductCode__c = oli.ProductCode;
      tempOLIObj.Production_Comments__c = oli.Production_Comments__c;
      tempOLIObj.Production_Cost_Billed_Rate__c = oli.Production_Cost_Billed_Rate__c;
      tempOLIObj.Production_Cost_Full_Rate__c = oli.Production_Cost_Full_Rate__c;
      tempOLIObj.Production_Cost_Type__c = oli.Production_Cost_Type__c;
      tempOLIObj.PubStudio_Distr_Code__c = oli.PubStudio_Distr_Code__c;
      tempOLIObj.PubStudio_Headline__c = oli.PubStudio_Headline__c;
      tempOLIObj.PubStudio_Press_Type__c = oli.PubStudio_Press_Type__c;
      tempOLIObj.PubStudio_Unit_Type__c = oli.PubStudio_Unit_Type__c;
      tempOLIObj.Quantity__c = oli.Quantity;
      tempOLIObj.Regional_Circulation__c = oli.Regional_Circulation__c;
      tempOLIObj.Run_Type__c = oli.Run_Type__c;
      tempOLIObj.R_L_Page_Indicator__c = oli.R_L_Page_Indicator__c;
      tempOLIObj.Sales_Rep__c = oli.Sales_Rep__c;
      tempOLIObj.ServiceDate__c = oli.ServiceDate;
      tempOLIObj.sfxId__c = oli.sfxId__c;
      tempOLIObj.Shape__c = oli.Shape__c;
      tempOLIObj.Sides__c = oli.Sides__c;
      tempOLIObj.SortOrder__c = oli.SortOrder;
      tempOLIObj.Space_Extension_Date__c = oli.Space_Extension_Date__c;
      tempOLIObj.Spread_Indicator__c = oli.Spread_Indicator__c;
      tempOLIObj.Stage__c = oli.Stage__c;
      tempOLIObj.Title_Pricing__c = oli.Title_Pricing__c;
      tempOLIObj.TotalPrice__c = oli.TotalPrice;
      tempOLIObj.UnitPrice__c = oli.UnitPrice;
      tempOLIObj.Weight__c = oli.Weight__c;
      tempOLIObj.Width__c = oli.Width__c;
      // Add to List
      lstTempOLIObj.add(tempOLIObj);
    }
    // Check the Temp OLI List is not Empty
    if(!lstTempOLIObj.isEmpty()){
      Database.Saveresult[] dbSave = database.insert(lstTempOLIObj, false);
      MDP_ErrorHelper.processSaveResults(dbSave, 'MDP_Tgr_OppLine_Handler', 'insertOppLineItemRecToTempCustObj()', lstTempOLIObj, 'OpportunityId__c');
    }*/
    system.debug('End insertOppLineItemRecToTempCustObj() method of MDP_Tgr_OppLine_Handler class');
  }

  /**
  * @author        Ramakrishna Singara
  * @date          03/30/2018
  * @description   method to throw error, if the Operative API profile user is try to delete the Opportunity line item.
  * @param         list<OpportunityLineItem> lstOLI
  * @return        null
  */
  public static void operativeAPIProfileGotError(list<OpportunityLineItem> lstOLI) {
    system.debug('in the operativeAPIProfileGotError() method of MDP_Tgr_OppLine_Handler class');

    for(OpportunityLineItem oli : lstOLI){
      if(profileName == MDP_Utils.OPERATIVE_API){
        system.debug('Operative API cannot delete OLI records - '+oli.Id);
        oli.addError('Operative API cannot delete OLI records');

      }
    }
    system.debug('end of the operativeAPIProfileGotError() method of MDP_Tgr_Opportunity_Handler class');
  }


  public static void updateOracleOverride(list<OpportunityLineItem> lstOLI){
    system.debug('in the updateOracleOverride() method of MDP_Tgr_OppLine_Handler class');
    // if we have a Production Cost oli, update the Oracle_Override__c field based on it's Associated_Product__c

    set<id> productIDs = new set<id>();
    for(OpportunityLineItem oli1 : lstOLI){
      if(oli1.Product2ID <> null && oli1.Associated_Product__c <> null){
        productIDs.add(oli1.Product2ID);
      }
    }
    map<id, Product2> productMap = new map<id, Product2>([SELECT ID, Name, Ad_Unit__c FROM Product2 WHERE ID IN :productIDs]);

    set<id> assocIDs = new set<id>();
    for(OpportunityLineItem oli2 : lstOLI){
      Product2 p = productMap.get(oli2.Product2Id);
      if(p <> null && p.Ad_Unit__c == 'Production Cost' && oli2.Associated_Product__c <> null){
        assocIDs.add(oli2.Associated_Product__c);
      }
    }

    if (!assocIDs.isEmpty()){
      map<id, OpportunityLineItem> assocMap = new map<id, OpportunityLineItem>([Select ID, Ad_Type__c, Price_Override_Reason__c, Product2.Ad_Unit__c, Run_Type__c
                       FROM OpportunityLineItem WHERE ID IN :assocIDs]);

      for(OpportunityLineItem oli : lstOLI){
        Product2 p = productMap.get(oli.Product2Id);

        if(p <> null && p.Ad_Unit__c == 'Production Cost' && oli.Associated_Product__c <> null){
          OpportunityLineItem aOLI = assocMap.get(oli.Associated_Product__c);

          if (aOLI <> null) {
            if( aOLI.Price_Override_Reason__c == 'House Ad' ) {
              oli.Oracle_Override__c = '508200';
            } else if ( aOLI.Ad_Type__c == 'Direct Media - 3' &&
                  ( aOLI.Product2.Ad_Unit__c == 'Insert' || aOLI.Product2.Ad_Unit__c == 'Onsert')) {
              oli.Oracle_Override__c = '406200';
            } else if( aOLI.Run_Type__c == 'Regional' &&
                  ( aOLI.Product2.Ad_Unit__c == 'Insert' || aOLI.Product2.Ad_Unit__c == 'Onsert')) {
              oli.Oracle_Override__c = '406100';
            } else if( aOLI.Run_Type__c == 'National' &&
                  ( aOLI.Product2.Ad_Unit__c == 'Insert' || aOLI.Product2.Ad_Unit__c == 'Onsert')) {
              oli.Oracle_Override__c = '406000';
            } else if( aOLI.Ad_Type__c == 'Travel - Back of Book' || aOLI.Ad_Type__c == 'Travel - Display - 1') {
              oli.Oracle_Override__c = '405080';
            } else if( aOLI.Ad_Type__c == 'Transitional Pricing - 8') {
              oli.Oracle_Override__c = '405240';
            } else if( aOLI.Ad_Type__c == 'Direct Media - 3') {
              oli.Oracle_Override__c = '405040';
            } else if( aOLI.Ad_Type__c == 'Back of Book - 5') {
              oli.Oracle_Override__c = '405060';
            } else if( aOLI.Ad_Type__c == 'Display - 1' && aOLI.Run_Type__c == 'Regional') {
              oli.Oracle_Override__c = '405020';
            } else if( aOLI.Ad_Type__c == 'Display - 1' && aOLI.Run_Type__c == 'National') {
              oli.Oracle_Override__c = '405000';
            } else oli.Oracle_Override__c = null;
          }
        }
      }
    }
    system.debug('end of the updateOracleOverride() method of MDP_Tgr_Opportunity_Handler class');
  }

  /**
   * @author        Ramakrishna Singara
   * @date          03/04/2018
   * @description   method to Assign Opportunity field values to OLI field.
   * @param         list<OpportunityLineItem> lstOLI
   * @return        null
   */
  public static void assignOppFieldValuesToOLI(list<OpportunityLineItem> lstOLI) {
    Set<Id> oppIds = new Set<Id>();
    Map<Id, Product2> products = new Map<Id, Product2>();
    Set<Id> titleIds = new set<ID>();
    Set<String> currencyCodes = new Set<String> {'USD'};
    Map<Id, List<PriceBookEntry>> fullPagePbeByTitle = new Map<Id, List<PriceBookEntry>>();
    Map<Id, PriceBookEntry> allPbeByProduct = new Map<Id, PriceBookEntry>();

    // Iterate Opportunity line item and prepare opportunity IDs set
    for (OpportunityLineItem oli : lstOLI) {
      oppIds.add(oli.OpportunityId);
      products.put(oli.Product2Id, null);
    }

    Map<Id, Opportunity> opportunities = new Map<Id, Opportunity>(
      [SELECT Id, Name, CurrencyIsoCode, RecordTypeId, RecordType.Name, Brand__c, Issue__c, Title__c, Title__r.Name
      FROM Opportunity
      WHERE Id IN: oppIds]
    );

    for (Opportunity opp : opportunities.values()) {
      titleIds.add(opp.Title__c);
      currencyCodes.add(opp.CurrencyIsoCode);
    }

    for (PricebookEntry pbe : [SELECT Id, Name, Pricebook2Id, PriceBook2.Account__r.Name, PriceBook2.isActive, Product2Id, Product2.Title__c, Product2.Ad_Unit__c,
                               Product2.Name, Product2.IsActive, Product2.Non_Standard_Product__c, UnitPrice, IsActive, CurrencyIsoCode
                               FROM PricebookEntry
                               WHERE PriceBook2.Account__r.Name =: MDP_Utils.MDP_ACTIVE_PRICEBOOK_NAME and PriceBook2.isActive = true
                  AND CurrencyIsoCode IN :currencyCodes
                  AND (((Product2.Ad_Unit__c = :MDP_Utils.PRODUCT_FULL_PAGE OR Product2.Ad_Unit__c = :MDP_Utils.PRODUCT_FULL_PAGE_BW) AND Product2.Title__c in :titleIds)
                                                                                                                                      OR Product2Id IN :products.keySet())]) {
      if (products.get(pbe.Product2Id) == null) {
        products.put(pbe.Product2Id, new Product2(
                 Id = pbe.Product2Id,
                 Name = pbe.Product2.Name,
                 IsActive = pbe.Product2.IsActive,
                 Non_Standard_Product__c = pbe.Product2.Non_Standard_Product__c,
                 Title__c = pbe.Product2.Title__c,
                 Ad_Unit__c = pbe.Product2.Ad_Unit__c
                 ));
      }

      if ((pbe.Product2.Ad_Unit__c == MDP_Utils.PRODUCT_FULL_PAGE || pbe.Product2.Ad_Unit__c == MDP_Utils.PRODUCT_FULL_PAGE_BW) && titleIds.contains(pbe.Product2.Title__c)) {
        if (fullPagePbeByTitle.get(pbe.Product2.Title__c) == null) {
          fullPagePbeByTitle.put(pbe.Product2.Title__c, new List<PriceBookEntry>());
        }
        fullPagePbeByTitle.get(pbe.Product2.Title__c).add(pbe);
      }
      allPbeByProduct.put(pbe.Product2Id, pbe);
    }

    Boolean useFullPagePrice;
    Boolean useColored;

    for (OpportunityLineItem oli : lstOLI) {
      useFullPagePrice = false;
      if (opportunities.containskey(oli.OpportunityId)) {

        Opportunity opp = opportunities.get(oli.OpportunityId);
        oli.Quantity = 1.00;
        // oli.Discount = 0.00; This is causing test classes to fail when inserting a OLISchedule, moving it to lightning component instead.
        oli.Opp_Record_Type_Name__c = opp.RecordType.Name;
        oli.Issue__c = opp.Issue__c;
        oli.Brand__c = opp.Brand__c;

        for (Schema.PicklistEntry ple : OpportunityLineItem.Title_PL__c.getDescribe().getPicklistValues()) {
          if (ple.getLabel() == opp.Title__r.Name) {
            oli.Title_PL__c = ple.getValue();
            break;
          }
        }

        if (oli.Run_Type__c == MDP_Utils.OPP_RUN_TYPE_REGIONAL ||
            (products.get(oli.Product2Id) != null &&
             (products.get(oli.Product2Id).Ad_Unit__c == 'Insert' ||
              products.get(oli.Product2Id).Ad_Unit__c == 'Onsert' ||
              products.get(oli.Product2Id).Non_Standard_Product__c))) {
          useFullPagePrice = true;
        }

        if (useFullPagePrice && opp.Title__c != null && fullPagePbeByTitle.containsKey(opp.Title__c)) {
          useColored = (!products.get(oli.Product2Id).Ad_Unit__c.endsWithIgnoreCase('B&W'));
          for (PriceBookEntry pbe : fullPagePbeByTitle.get(opp.Title__c)) {
            if (opp.CurrencyIsoCode == pbe.CurrencyIsoCode &&
             ((useColored && pbe.Product2.Ad_Unit__c == MDP_Utils.PRODUCT_FULL_PAGE) ) || (!useColored && pbe.Product2.Ad_Unit__c == MDP_Utils.PRODUCT_FULL_PAGE_BW)) {
              oli.Open_Rate__c = pbe.UnitPrice;
              break;
            }
          }
        } else {
          if (allPbeByProduct.containsKey(oli.Product2Id)) {
            oli.Open_Rate__c = allPbeByProduct.get(oli.Product2Id).UnitPrice;
          }
        }
      }
    }
  }






// This might not be required as OpportunityId cannot be modified on an OLI.
  public static void updateTitle(list<OpportunityLineItem> lstOLI) {
    List<Schema.PicklistEntry> picklistEntries = OpportunityLineItem.Title_PL__c.getDescribe().getPicklistValues();
    Map<Id, Opportunity> opps = new Map<Id, Opportunity>();

    for (OpportunityLineItem oli : lstOLI) {
      opps.put(oli.OpportunityId, null);
    }

    opps.putAll([SELECT Title__r.Name FROM Opportunity WHERE Id IN :opps.keySet()]);

    Opportunity opp;
    for (OpportunityLineItem oli : lstOLI) {
      if (opps.containsKey(oli.OpportunityId)) {
        opp = opps.get(oli.OpportunityId);
        if (oli.Title_PL__c != null && opp.Title__r.Name == oli.Title_PL__c) {
          break;
        }

        for (Schema.PicklistEntry ple : picklistEntries) {
          if (ple.getLabel() == opp.Title__r.Name) {
            oli.Title_PL__c = ple.getValue();
            break;
          }
        }
      }
    }
  }

  // ++ WSL - OMS Integration Code - 5/7/2018
  public static void sendROBMessagesForDelete(OpportunityLineItem[] deletedOLIs) {

    if (!Trigger.isDelete) return;

    Set<Id> oppIds = new Set<Id>();
    for (OpportunityLineItem oli : deletedOLIs) {
      if (String.isNotBlank(oli.OMS_Component_Key__c)) {
        oppIds.add(oli.OpportunityId);
      }
    }
    Map<Id, Opportunity> oppMap = new Map<Id, Opportunity>(
      [select Issue__r.Is_Issue_Invoiced__c,
          Title__r.Is_TCS_Title__c,
          Title__r.Last_TCS_Issue__c,
          Issue__r.Issue_Cover_Date__c ,
          Issue__r.OMS_Ad_Records_Lock_Out__c
        from Opportunity where Id in :oppIds]);

    Id outboundRTId = MDP_RecordTypeUtil.getRecordTypeIdByName('OMS_Message__c', 'Outbound');
    OMS_Message__c[] messageRecords = new List<OMS_Message__c>();
    for (OpportunityLineItem oli : deletedOLIs) {
      Opportunity opp = oppMap.get(oli.OpportunityId);
      if (opp == null) continue;
      if (!opp.Issue__r.Is_Issue_Invoiced__c && OMS_Util.isTCSOpportunity(opp) && (opp.Issue__r.OMS_Ad_Records_Lock_Out__c == null || System.today() <= opp.Issue__r.OMS_Ad_Records_Lock_Out__c)) {
        messageRecords.add(OMS_Util.generateOMSRecordForOLI('Delete', oli, outboundRTId));
      }

    }
    insert messageRecords;
  }

  public static void sendROBMessages(OpportunityLineItem[] olis,
      Map<Id, OpportunityLineItem> enhancedOLIMap, Map<Id, OpportunityLineItem> oldOLIMap) {

    Id outboundRTId = MDP_RecordTypeUtil.getRecordTypeIdByName('OMS_Message__c', 'Outbound');
    OMS_Message__c[] messageRecords = new List<OMS_Message__c>();
    for (OpportunityLineItem oli : olis) {
      OpportunityLineItem enhancedOLI = enhancedOLIMap.get(oli.Id);
      if (enhancedOLI.Opportunity.Probability < 90
          || !OMS_Util.isTCSOpportunity(enhancedOLI.Opportunity)
          || enhancedOLI.Opportunity.Issue__r.Is_Issue_Invoiced__c
          || (enhancedOLI.Opportunity.Issue__r.OMS_Ad_Records_Lock_Out__c != null && System.today() > enhancedOLI.Opportunity.Issue__r.OMS_Ad_Records_Lock_Out__c)
          || !OMS_Util.isValidProduct(enhancedOLI.Product_Name__c)) {
        continue;
      }

      if (Trigger.isInsert) {
        messageRecords.add(OMS_Util.generateOMSRecordForOLI('Create', enhancedOLI, outboundRTId));
      } else if (Trigger.isUpdate) {
        if (isOLIChanged(oli, oldOLIMap.get(oli.Id))) {
          String crudOperation = String.isBlank(oli.OMS_Component_Key__c) ? 'Create' : 'Update';
          messageRecords.add(OMS_Util.generateOMSRecordForOLI(crudOperation, enhancedOLI, outboundRTId));
        }
      }

    }
    insert messageRecords;
  }

  private static Boolean isOLIChanged(OpportunityLineItem oli, OpportunityLineItem oldOLI) {
    return oli.Product2Id != oldOLI.Product2Id
      || oli.Ad_Type__c != oldOLI.Ad_Type__c
      || oli.Run_Type__c != oldOLI.Run_Type__c
      || oli.Shape__c != oldOLI.Shape__c
      || oli.Insert_Type__c != oldOLI.Insert_Type__c
      || oli.Sides__c != oldOLI.Sides__c
      || oli.Geo_Codes__c != oldOLI.Geo_Codes__c;
  }
  // -- WSL - OMS Integration code - 5/7/2018

  // ++ TLM - OMS Integration Code - 5/3/2018
  public static void sendIOMessages(OpportunityLineItem[] records, Map<Id, OpportunityLineItem> oldOLIMap) {
    OMSIntegrationSettings__c settings = OMSIntegrationSettings__c.getInstance();
    OMS_Message__c[] omsMessages = new List<OMS_Message__c>();
    Id outboundRTId = MDP_RecordTypeUtil.getRecordTypeIdByName('OMS_Message__c', 'Outbound');

    set<string> oppID = new set<string>();
    for (OpportunityLineItem olix : records) {
      oppID.add(olix.OpportunityID);
    }

    map<ID, Opportunity> omsMap = new map<ID, Opportunity>([SELECT Id, Issue__r.Is_Issue_Invoiced__c, ContractId, Contract.Agency__c, Contract.Agency__r.OMS_Id__c, Issue__r.OMS_Ad_Records_Lock_Out__c
                                FROM Opportunity WHERE Id IN : oppID]);

    for (OpportunityLineItem oli : records) {
      OpportunityLineItem oldOli = oldOLIMap.get(oli.Id);
      Opportunity o = omsMap.get(oli.OpportunityId);

      // don't process the record if missing the OMS_Component_Key__c
      if (oli.OMS_Component_Key__c == null || o.Issue__r.Is_Issue_Invoiced__c || (o.Issue__r.OMS_Ad_Records_Lock_Out__c != null && System.today() > o.Issue__r.OMS_Ad_Records_Lock_Out__c))
        continue;

      if (o.ContractId <> null && o.Contract.Agency__c <> null && String.isNotBlank(o.Contract.Agency__r.OMS_Id__c)) {
        if (oli.OMS_IO_Sync_Stage__c == null || oli.OMS_IO_Sync_Stage__c == 'Not Started' || oli.OMS_IO_Sync_Stage__c == 'Error') {
          OMS_Message__c omsMessage = new OMS_Message__c(
            Message_Type__c = 'io',
            Origin__c = 'Meredith SFDC',
            CRUD_Operation__c = 'Create',
            Record_Id__c = oli.Id,
            RecordTypeId = outboundRTId,
            To_Queue__c = settings.To_OMS_Data_Queue__c);
          omsMessages.add(omsMessage);
        }
      }
    }

    insert omsMessages;
  }
  // -- TLM - OMS Integration Code - 5/3/2018
  // added By Banani - 1053
  public static void checkTotalNEP(List<OpportunityLineItem> lstNewOLI, map<ID, OpportunityLineItem> mapNewOLI) {
    System.debug('---------- in MDP_Tgr_OppLine_Handler.checkTotalNEP ----------');
    Id recTypeId = Schema.SObjectType.Opportunity.getRecordTypeInfosByName().get('Print').getRecordTypeId();
    Set<String> issueId = new Set<String>();

    System.debug('---------- mapNewOLI: ' + mapNewOLI );
    List<OpportunityLineItem> listWithOppRecId = [Select id,Issue__c,NEP__c,opportunity.recordTypeId from OpportunityLineItem where id in :mapNewOLI.keySet()];
    // get opp ids, query opp rectypeId and map<opId, recordt>
    map<id,OpportunityLineItem> oliMap = new map<id,OpportunityLineItem>();
    for (OpportunityLineItem oli : listWithOppRecId /*lstNewOLI*/) {
      if (oli.opportunity.recordTypeId == recTypeId) {
        issueId.add(oli.Issue__c);
        oliMap.put(oli.Issue__c, oli);
      }
    }
    //System.debug('---------- issueId ' + issueId + ' ----- oliMap: ' + oliMap );
    if (issueId.isEmpty()) return;                       // no need to continue if we don't have any qualifying opportunities.

    //List<Issue__c> issueList = [SELECT id, maximum_nep__c, name,
        //                            (SELECT id,Estimated_NEP__c,probability from opportunities__r where probability >=90 and recordTypeId = :recTypeId)
        //                            FROM issue__c WHERE id in:issueId and Limited_Ad__c = true];
    List<Issue__c> issueList = [SELECT id, maximum_nep__c, name,
                                    (SELECT id,Estimated_NEP__c,probability from opportunities__r where recordTypeId = :recTypeId)
                                    FROM issue__c WHERE id in:issueId and Limited_Ad__c = true];
    // calucuate the NEP Totals by Opportunity ID
    //System.debug('---------- issueList: ' + issueList );
    Issue__c failedIssue;
    if (!issueList.isEmpty()) {
      for (Issue__c thisissue : issueList ) {
        Decimal totalNep = 0;
        Decimal currentOliNep = 0;
        for (Opportunity thisOpp : thisIssue.opportunities__r) {
          if (thisOpp.Estimated_NEP__c <> null && thisOpp.probability >= 90) totalNep += thisOpp.Estimated_NEP__c;
          if (thisOpp.id == oliMap.get(thisIssue.id).opportunityId && thisOpp.probability >= 90 )
            currentOliNep = oliMap.get(thisIssue.id).NEP__c;                                //add current nep of OLI if its opportunity probability >= 90.0
        }
        totalNep += currentOliNep;
        System.debug('---------- totalNep: ' + totalNep + thisissue.maximum_nep__c);
        if (thisissue.maximum_nep__c < totalNep) {
                    failedIssue = thisIssue;
          //oppMap.get(thisissue.id).addError('This book is currently full. Please contact your Production Manager to see if additional space is available');
        }
      }
    }

        if (failedIssue == null) {
            return;
        }

        for (OpportunityLineItem oli : lstNewOLI) {                          //don't calculate NEP when probabilty changes 90% to 100% or 100% to 90%
            if (failedIssue.Id == oli.Issue__c){
              string errMessage = 'The ' + failedIssue.Name + ' issue is currently full. Please contact your Production Manager to see if additional space is available.';
                oli.addError(errMessage);
                break;
            }
        }
  }
}