1

I have 2 objects Proposal & Proposal Line Item(Child of Proposal).

In Proposal Line Item object I do not want any duplicates on the basis of 2 lookup fields (i.e ProposalID & ProductID).

I already have a trigger on "Proposal Line Item" records insertion which is checking for the already existing records and is not inserting any new one if there is already a combination of the ProductID & ProposalID . Instead it is updating the already available records with new field values if any field has a modified value in excel.

I am facing the issue if the excel file which has the list of new records contains any duplicate combination of the above two fields. While inserting the excel file it is not checking for the duplicates in file and is inserting all of the records. I know we can remove the duplicates from excel file in few steps. But since users are not following this approach which is why this requirement has come.

If there is a duplicate at 1st and 3rd row in excel then 1st one can be inserted and the 3rd one should not be inserted. Is there any way to overcome this issue?

Below is the trigger code.

Trigger

Trigger APTPS_ProposalLineItemTrigger1 on Proposal_Line_Item__c (After Insert , After Update) 
{
    IF(Trigger.IsAfter && (Trigger.IsInsert || Trigger.IsUpdate))
    {
         IF(APTS_ProposalLineItemTriggerHandler1.DoUpdate) 
         {
            APTS_ProposalLineItemTriggerHandler1.DoUpdate = False;
            APTS_ProposalLineItemTriggerHandler1.AfterInsertHandler(Trigger.New);
         }
    }
}

Class

Public Class APTS_ProposalLineItemTriggerHandler1
{
    Public Static Map<String, Schema.SObjectField> FieldMap;    
    Public Static Boolean DoUpdate = TRUE;

    Public Static Void AfterInsertHandler(List<Proposal_Line_Item__c> ListPLIs)
    {        
        Set<String> SetMPN = New Set<String>();
        Set<Id> SetProposalId = New Set<Id>();
        List<Proposal_Line_Item__c> ListUpdatePropLines = New List<Proposal_Line_Item__c>();
        List<Proposal_Line_Item__c> ListDeletePropLines = New List<Proposal_Line_Item__c>();
        //List<Proposal_Line_Item__c> DuplicateIdinExcel = New List<Proposal_Line_Item__c>();
        Map<String , Proposal_Line_Item__c> MapMPNPLI = New Map<String, Proposal_Line_Item__c>();        

        FOR(Proposal_Line_Item__c NewPLI : ListPLIs)
        {
            IF(NewPLI.Product__Id__c != NULL)
            {
                SetMPN.Add(NewPLI.Product__Id__c);
                SetProposalId.Add(NewPLI.Proposal__Id__c);
            }
        }

        IF(SetMPN.Size()>0)
        {
            List<Proposal_Line_Item__c> ListPLI = Database.Query(GetAllFields('Proposal_Line_Item__c') + ' FROM Proposal_Line_Item__c WHERE Product__Id__c IN :SetMPN AND Proposal__Id__c IN :SetProposalId AND ID NOT IN: ListPLIs');            

            FOR(Proposal_Line_Item__c PLI : ListPLI)
            {
                MapMPNPLI.Put(PLI.Proposal__Id__c + PLI.Product__Id__c , PLI);
            }

            FOR(Proposal_Line_Item__c NewPLI : ListPLIs )
            {
                Proposal_Line_Item__c ExistingLine = MapMPNPLI.Get(NewPLI.Proposal__Id__c + NewPLI.Product__Id__c);

                IF(ExistingLine != NULL)
                {
                    FOR(String Key : FieldMap.KeySet())
                    {
                        IF(FieldMap.Get(Key).GetDescribe().IsUpdateable())
                        {
                            ExistingLine.Put(Key, NewPLI.Get(Key));
                        }
                    }
                    ListUpdatePropLines.Add(ExistingLine);
                    ListDeletePropLines.Add(NewPLI);
                }
            }

            IF(ListUpdatePropLines.Size()>0)
            {
                Update ListUpdatePropLines;            
            }
            IF(ListDeletePropLines.Size()>0)
            {             
                ListDeletePropLines = [Select ID FROM Proposal_Line_Item__c WHERE ID IN :ListDeletePropLines]; 
                Delete ListDeletePropLines;
            }         
        }
        APTS_ProposalLineItemTriggerHandler1.DoUpdate = TRUE;
    }

    //This method will Get all the Fields of an Object
    Public Static String GetAllFields(String ObjectName)
    {
        String Query;
        Map<String , Schema.SObjectType> SchemaMap = Schema.GetGlobalDescribe();
        FieldMap = SchemaMap.Get(ObjectName).GetDescribe().Fields.GetMap();
        String CommaSepratedFields = '';

        FOR(String FieldName : FieldMap.KeySet())
        {
            IF(CommaSepratedFields == NULL || CommaSepratedFields == '')
            {
                CommaSepratedFields = FieldName;
            }
            ELSE
            {
                CommaSepratedFields = CommaSepratedFields + ', ' + FieldName;
            }
        }

        Query = 'Select ' + CommaSepratedFields;
        Return Query;
    }
}
0

Yes you can easily do this. Update your if condition and put an else condition

IF(ExistingLine != NULL)
  {
        FOR(String Key : FieldMap.KeySet())
        {
              IF(FieldMap.Get(Key).GetDescribe().IsUpdateable())
              {
                   ExistingLine.Put(Key, NewPLI.Get(Key));
              }
        }
     ListUpdatePropLines.Add(ExistingLine);
     ListDeletePropLines.Add(NewPLI);
}
else
{
    MapMPNPLI.Put(NewPLI.Proposal__Id__c + NewPLI.Product__Id__c , NewPLI.ID);
}

So if in this process if next time you get same key you can easily handle that.

  • On adding the else statement in the code I am receiving the error as 'Record is Read-Only' for all the records if I am inserting less than 200 records. And If I am inserting more than 240 records then it is inserting first 200 records and for the last 40 records again it is throwing the same error as 'Record is Read-Only'. – Ruchi Jun 15 '16 at 8:50
  • @Ruchi thats because now if you get same value in another row then you update newly inserted record which are not allowed. Now you have two options here either use before insert or keep all current record Id in set and if you found same record then skip that in update. – Tushar Sharma Jun 15 '16 at 8:58
  • If I use before update then also I am getting the new exception as 'DML statement cannot operate on trigger.new or trigger.old'. I will try your second option now. – Ruchi Jun 15 '16 at 10:09

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.