0

I am trying to extend the functionality of the Force.com Cookbook "Preventing Duplicate Records from Saving" trigger found at http://developer.force.com/cookbook/recipe/preventing-duplicate-records-from-saving.

I need to evaluate on two fields: Name and Type__c. Type__c is a picklist field. A record with the same Name but a different Type__c should not be treated as a duplicate. Only inserts and updates to match the same Name and Type__c as an existing record should error.

Below is what I've started, but I don't know if I am doing it correctly. Can you please help me with my code? I am new to developing. The "for" loop at the end doesn't evaluate for Type__c because I'm not sure how to go about it. I'm also not sure if "vendorMap.put(vendor.Type__c, vendor);" in the middle is the correct way to evaluate for Type__c.

trigger VendorTrigger on Vendor__c (after insert, after update, after undelete, after delete,before insert, before update, before delete) {

if(trigger.isBefore && trigger.isInsert || trigger.isUpdate) {
    Map<String, Vendor__c> vendorMap = new Map<String, Vendor__c>();
    for (Vendor__c vendor : System.Trigger.new) {

        // Make sure we don't treat a Name and Type__c that  
        // isn't changing during an update as a duplicate.  

        if ((vendor.Name != null && vendor.Type__c != null) &&
                (System.Trigger.isInsert ||
                (vendor.Name != System.Trigger.oldMap.get(vendor.Id).Name &&
                 vendor.Type__c != System.Trigger.oldMap.get(vendor.Id).Type__c))) {

            // Make sure another new vendor isn't also a duplicate  

            if (vendorMap.containsKey(vendor.Name) && vendorMap.containsKey(vendor.Type__c)) {
                vendor.Name.addError('Another new vendor has the same Name and Type combination.');
            } else {
                vendorMap.put(vendor.Name, vendor);
                vendorMap.put(vendor.Type__c, vendor);
            }
        }
    }

    // Using a single database query, find all the vendors in      
    // the database that have the same Name and Type__c as any     
    // of the vendors being inserted or updated.  

    for (Vendor__c vendor : [SELECT Name, Type__c 
                             FROM Vendor__c 
                             WHERE Name
                             IN :vendorMap.KeySet()]) {
                                 Vendor__c newVendor = vendorMap.get(vendor.Name);
                                 newVendor.Name.addError('A vendor matching the Name and Type combination already exists.');
                             }
}

}

2 Answers 2

1

After discussing with Tyles the solution to his problem is this:

Adding a new map called typeMap

Map<String, Vendor__c> typeMap = new Map<String, Vendor__c>();

This line of code vendorMap.put(vendor.Type__c, vendor); should be changed to typeMap.put(vendor.Type__c, vendor);

for (Vendor__c vendor : [SELECT Name, Type__c 
                             FROM Vendor__c 
                             WHERE Name
                             IN :vendorMap.KeySet() AND Type__c IN :typeMap.KeySet()]) {
                                 Vendor__c newVendor = vendorMap.get(vendor.Name);
                                 newVendor.Name.addError('A vendor matching the Name and Type combination already exists.');
}
7
  • Thank you for your explanation. Where would the typeMap be placed in the code? Also, what's the approach to resolve an error that Type__c is an invalid type for the map?
    – Tyler
    Jan 14, 2015 at 20:15
  • You will have to declare the typeMap under the vendorMap. Sorry, my bad I will update my answer, the typeMap should be Map<String,Vendor> and not Map<Type__c, Vendor>. In the key value of the map you need to put the correct data type. Jan 14, 2015 at 20:26
  • Thank you for the update. I am now getting "Illegal assignment from Vendor__c to List<String>" for "List<String> types = typeMap.get(newVendor.Type__c);" in the for loop. How would you resolve this?
    – Tyler
    Jan 14, 2015 at 20:45
  • can you write List<String> types = String.valueOf(typeMap.get(newVendor.Type__c)); Jan 14, 2015 at 20:49
  • Throws the same error of "Illegal assignment from String to List<String>".
    – Tyler
    Jan 14, 2015 at 20:52
3

If you can wait until Spring 15, this problem may be resolvable with clicks, not code with Duplicate Management feature (which is available for custom objects such as your Vendor__c)

See http://releasenotes.docs.salesforce.com/en-us/spring15/release-notes/matching_rules_create.htm for how duplicate matching rules are defined

See http://releasenotes.docs.salesforce.com/en-us/spring15/release-notes/duplicate_rules_create.htm for what actions are available to the user when a duplicate occurs

See http://releasenotes.docs.salesforce.com/en-us/spring15/release-notes/rn_sales_duplicate_management_intro.htm for general notes and limitations

Note that duplicate management, if retrofitted into existing duplicate-checking triggers/trigger handlers will free up SOQL calls in your app

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .