0

I am writing a trigger on a child (M-D relationship) where if the child object had duplicate records, update the count of duplicate on the Master. The duplicate child is determined if there is a lookup field match. The Lookup field here is Itm__c

The specific issue that I am stuck is
inv.Duplicate__c = inv.Invce_lns__r.size();

This returns me list of all the child records on the Master. How will I be able to just have count of duplicates, I mean after the map.

Here is the code:

trigger DuplicateInvceLns on Invce_Lne__c (before insert,before update,after insert, After Delete, After Undelete) {

    Set<Id> setInvceIds = new Set<Id>();
    Set<Id> ivtmp = new Set<Id>();
    Map<Id,Invce_Lne__c> inl = new Map<Id,Invce_Lne__c>();


    for(Invce_Lne__c iv : Trigger.new){
        ivtmp.add(Invce__c);
    }

    for(Invce_Lne__c invcelne : [select Id,Name,Itm__c, Invce__c from Invce_Lne__c where Invce__c IN : ivtmp])
        inl.put(invcelne.Itm__c, invcelne);


        for(Invce_Lne__c invcelne : Trigger.new)
        {
            if(invl.containsKey(invcelne.Itm__c)){
                 if(Trigger.isInsert || Trigger.isUndelete){
            setInvceIds.add(invcelne.Invce__c);
            system.debug(invcelne.Invce__c);
            system.debug(setInvceIds);
                 }
        }

           else if(Trigger.isDelete){
           setInvceIds.add(invcelne.Invce__c); 
           system.debug(setInvceIds); 
        }
    }
    List<Invce__c> lstInvce = [Select Id,name, (select id from Invce_Lns__r) from Invce__c where Id IN :setInvceIds];
    for(Invce__c inv : lstInvce)
    {
        inv.Duplicate__c = inv.Invce_lns__r.size();
        system.debug(inv.OrderApi__Invoice_lines__r.size());
    }
    update lstInvce;
}
1
  • So, if there is more than one child pointing to the same Itm__c, it is a duplicate?
    – sfdcfox
    Sep 27 '17 at 23:11
1

It looks like you want a simple aggregate query:

trigger DuplicateInvceLns on Invce_Lne__c (after insert, after update, after delete, after undelete) {
    // Initialize invoice map/Aggregate Invoice Ids
    Map<Id, Invce__c> invoices = new Map<Id, Invce__c>();
    if(Trigger.new != null) {
        for(Invce_Lne__c record: Trigger.new) {
            invoices.put(record.Invce__c, new Invce__c(Id=record.Invce__c, Duplicate__c=0));
        }
    }
    if(Trigger.old != null) {
        for(Invce_Lne__c record: Trigger.old) {
            invoices.put(record.Invce__c, new Invce__c(Id=record.Invce__c, Duplicate__c=0));
        }
    }
    // Query for duplicates
    for(AggregateReult result: [
        SELECT COUNT(Id) dups, Itm__c itemId, Invce__c invoiceId
        FROM Invce_Lne__c
        WHERE Invce__c = :invoices.keySet()
        GROUP BY Itm__c, Invce__c
        HAVING COUNT(Id) > 1
    ]) {
        // Increment Duplicate counter
        invoices.get((Id)result.get('invoiceId')).Duplicate__c +=
            ((Decimal)result.get('dups')) - 1;
    }
    // Update records
    update invoices.values();
}

I typically refer to this pattern as the Aggregate-Query-Update pattern.

Note that this trigger doesn't consider the first Itm__c a duplicate (hence, the - 1 in the code). You can remove this if you like, although I find this nomenclature confusing (there is only one duplicate if you have two of an item).

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.