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;
}
}