Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion force-app/main/default/classes/SummitEventsContactMatching.cls
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ public without sharing class SummitEventsContactMatching {
doCRUD crud = new doCRUD();

if (matches.isEmpty() && noMatchBehavior.startsWithIgnoreCase('Create')) {
//remove values of mappings set to match only so that they are not inserted into the new record
newObj = removeMatchOnlyFields(newObj, customMappingType, mappings, sObjectType);
crud.addRecord(newObj);
reg.put(fieldAPIName, newObj.Id);
reg.put(newFieldAPIName, true);
Expand Down Expand Up @@ -292,7 +294,7 @@ public without sharing class SummitEventsContactMatching {
mappedMatchingMethods = new Map<String, List<SObject>>();
if (mappedMatchingMethods.isEmpty()) {
if (matchingMethods.size() > 0) {
String query = 'SELECT Source_Value__c, Source_Type__c, ' + fieldAPIName + ', ' + sourceValue + ' FROM ' + namespace + sObjectType + ' WHERE ' + fieldAPIName + ' IN :matchingMethods';
String query = 'SELECT Source_Value__c, Source_Type__c, Matching_Only__c, ' + fieldAPIName + ', ' + sourceValue + ' FROM ' + namespace + sObjectType + ' WHERE ' + fieldAPIName + ' IN :matchingMethods';
List<SObject> results = Database.query(query);
for (SObject mapping : results) {
String method = (String) mapping.get(fieldAPIName);
Expand Down Expand Up @@ -375,6 +377,36 @@ public without sharing class SummitEventsContactMatching {
return record;
}

@TestVisible
private static SObject removeMatchOnlyFields(SObject record, String matchingMethod, Map<String, List<SObject>> mappings, String sObjectType) {
String namespace = SummitEventsNamespace.StrTokenNSPrefix('');
String objFieldAPIName = getFieldAPINameForObjectType(sObjectType);

if (mappings.containsKey(matchingMethod)) {
List<SObject> mappingList = mappings.get(matchingMethod);
for (SObject mapping : mappingList) {
Boolean matchingOnly = (Boolean) mapping.get(namespace + 'Matching_Only__c');
if (matchingOnly != null && matchingOnly) {
String fieldAPIName = (String) mapping.get(namespace + objFieldAPIName);
// Set the field to null to remove it from the record before insert
record.put(fieldAPIName, null);
}
}
}
return record;
}

private static String getFieldAPINameForObjectType(String sObjectType) {
if (sObjectType.equals('Contact')) {
return 'Contact_Field_API_Name__c';
} else if (sObjectType.equals('Account')) {
return 'Person_Account_Field_API_Name__c';
} else if (sObjectType.equals('Lead')) {
return 'Lead_Field_API_Name__c';
}
return null;
}

private static Account makePerson(Summit_Events_Registration__c reg, String customMappingType, Map<String, List<SObject>> contactMappings) {
Account personAccount = new Account();
Boolean personAccountActive = SummitEventsShared.personAccountsEnabled();
Expand Down
43 changes: 16 additions & 27 deletions force-app/main/default/classes/SummitEventsRegistration.cls
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,6 @@ public class SummitEventsRegistration {
List<Summit_Events_Registration__c> affectedRegs = new List<Summit_Events_Registration__c>();

String namespace = SummitEventsNamespace.StrTokenNSPrefix('');

//Tags that need a little TLC to turn them into real links
List<String> emailTags = new List<String>{
'UG_Parking_Pass_Link__c',
'Add_To_Calendar_Link__c',
'Event_Registration_Cancel_Link__c',
'Add_to_Apple_Calendar__c',
'Add_To_Google_Calendar_Link__c',
'Add_to_Outlook_Calendar__c',
'Add_To_Outlook_Web_Calendar__c',
'Add_To_Yahoo_Calendar__c'
};

//Add the namespace to the email tags so that both namespaced and non-namespaced version work
if (String.isNotBlank(namespace)) {
List<String> emailTagsPackaged = new List<String>();
for (String tag : emailTags) {
emailTagsPackaged.add(namespace + tag);
}
emailTags.addAll(emailTagsPackaged);
}

//Delineator of content in the email templase
String originalTemplate = '[[DONT_DELETE_CONTENT_HERE]]';

Expand Down Expand Up @@ -155,12 +133,23 @@ public class SummitEventsRegistration {
found = '';
}

//replace all hooks with found values from registration
if (emailTags.contains(matcher2.group(1))) {
//Fix formula links that are encoded with the following format: _HL_ENCODED_[link URL]_HL__blank_HL_[link text]_HL_
if (found.startsWith('_HL_ENCODED_') && found.endsWith('_HL__blank_HL_')) {
found = found.replace('_HL_ENCODED_', '<a href="');
found = found.replace('_HL__blank_HL_', '</a>');
found = found.replace('_HL_', ' target="_blank">');
found = found.replace('%20target=', '');
found = found.replace(' target=', '');
found = found.replace('_HL_', '" target="_blank">');
}

//Fix any image links that are encoded with the following format: _IM1_[image source]_IM2_[alt text]_IM3_[height]_IM4_[width]_IM5_
if (found.startsWith('_IM1_') && found.endsWith('_IM5_')) {
found = found.replace('_IM1_', '<img src="');
found = found.replace('_IM2_', '" alt="');
found = found.replace('_IM3_', '" style="height:');
found = found.replace('_IM4_', 'px; width:');
found = found.replace('_IM5_', 'px;" border="0" ');
found += '/>';
}

emailContent = matcher2.replaceAll(found);
Expand Down Expand Up @@ -229,7 +218,7 @@ public class SummitEventsRegistration {
t.Description = emailMessage + '\n\n' + t.Description;
}
doCRUD crudToDo = new doCRUD();
crudToDo.savTask(activityUpdates);
crudToDo.saveTask(activityUpdates);
}
}

Expand Down Expand Up @@ -280,7 +269,7 @@ public class SummitEventsRegistration {

private without sharing class doCRUD {

public void savTask(List<Task> taskToSave) {
public void saveTask(List<Task> taskToSave) {
try {
insert taskToSave;
} catch (Exception e) {
Expand Down
216 changes: 216 additions & 0 deletions force-app/test/default/classes/SummitEventsContactMatching_TEST.cls
Original file line number Diff line number Diff line change
Expand Up @@ -267,4 +267,220 @@ public class SummitEventsContactMatching_TEST {
System.assertEquals(newDate, result5.get('Birthdate'), 'The Birthdate field should be set to 2021-01-05');
Test.stopTest();
}

@IsTest
static void testRemoveMatchOnlyFields() {
// Create a mock Contact with some fields populated
Contact testContact = new Contact(
FirstName = 'Test',
LastName = 'Contact',
Email = 'test@example.com',
Title = 'Manager',
Department = 'Sales'
);

// Create mock mappings with one field marked as Matching_Only__c = true
String namespace = SummitEventsNamespace.StrTokenNSPrefix('');
Map<String, List<SObject>> mockMappings = new Map<String, List<SObject>>();
List<Summit_Events_Contact_Matching_Mapping__mdt> mappingList = new List<Summit_Events_Contact_Matching_Mapping__mdt>();

// Create a mapping that is match-only (should be removed)
Summit_Events_Contact_Matching_Mapping__mdt matchOnlyMapping = new Summit_Events_Contact_Matching_Mapping__mdt(
DeveloperName = 'Title_Match_Only',
MasterLabel = 'Title Match Only',
Source_Type__c = 'Field',
Contact_Field_API_Name__c = 'Title',
Contact_Matching_Method__c = 'TestMethod',
Matching_Only__c = true
);
mappingList.add(matchOnlyMapping);

// Create a mapping that is NOT match-only (should be kept)
Summit_Events_Contact_Matching_Mapping__mdt regularMapping = new Summit_Events_Contact_Matching_Mapping__mdt(
DeveloperName = 'Department_Regular',
MasterLabel = 'Department Regular',
Source_Type__c = 'Field',
Contact_Field_API_Name__c = 'Department',
Contact_Matching_Method__c = 'TestMethod',
Matching_Only__c = false
);
mappingList.add(regularMapping);

mockMappings.put('TestMethod', mappingList);

Test.startTest();
// Verify fields are set before calling removeMatchOnlyFields
System.assertEquals('Manager', testContact.Title, 'Title should be Manager before removal');
System.assertEquals('Sales', testContact.Department, 'Department should be Sales before removal');

// Call the removeMatchOnlyFields method
SObject result = SummitEventsContactMatching.removeMatchOnlyFields(testContact, 'TestMethod', mockMappings, 'Contact');

// Verify that the match-only field (Title) was removed
System.assertEquals(null, result.get('Title'), 'Title should be null after removeMatchOnlyFields');

// Verify that the regular field (Department) was NOT removed
System.assertEquals('Sales', result.get('Department'), 'Department should still be Sales after removeMatchOnlyFields');

// Verify other fields remain intact
System.assertEquals('Test', result.get('FirstName'), 'FirstName should remain Test');
System.assertEquals('Contact', result.get('LastName'), 'LastName should remain Contact');
System.assertEquals('test@example.com', result.get('Email'), 'Email should remain test@example.com');

Test.stopTest();
}

@IsTest
static void testRemoveMatchOnlyFieldsForLead() {
// Create a mock Lead with some fields populated
Lead testLead = new Lead(
FirstName = 'Test',
LastName = 'Lead',
Email = 'testlead@example.com',
Company = 'Test Company',
Title = 'CEO',
Industry = 'Technology'
);

// Create mock mappings with Lead-specific fields
String namespace = SummitEventsNamespace.StrTokenNSPrefix('');
Map<String, List<SObject>> mockMappings = new Map<String, List<SObject>>();
List<Summit_Events_Lead_Matching_Mapping__mdt> leadMappingList = new List<Summit_Events_Lead_Matching_Mapping__mdt>();

// Create a match-only mapping for Lead (should be removed)
Summit_Events_Lead_Matching_Mapping__mdt matchOnlyMapping = new Summit_Events_Lead_Matching_Mapping__mdt(
DeveloperName = 'Title_Match_Only',
MasterLabel = 'Title Match Only',
Source_Type__c = 'Field',
Lead_Field_API_Name__c = 'Title',
Lead_Matching_Method__c = 'TestLeadMethod',
Matching_Only__c = true
);
leadMappingList.add(matchOnlyMapping);

// Create a regular mapping (should be kept)
Summit_Events_Lead_Matching_Mapping__mdt regularMapping = new Summit_Events_Lead_Matching_Mapping__mdt(
DeveloperName = 'Industry_Regular',
MasterLabel = 'Industry Regular',
Source_Type__c = 'Field',
Lead_Field_API_Name__c = 'Industry',
Lead_Matching_Method__c = 'TestLeadMethod',
Matching_Only__c = false
);
leadMappingList.add(regularMapping);

mockMappings.put('TestLeadMethod', leadMappingList);

Test.startTest();
// Verify fields are set before calling removeMatchOnlyFields
System.assertEquals('CEO', testLead.Title, 'Title should be CEO before removal');
System.assertEquals('Technology', testLead.Industry, 'Industry should be Technology before removal');

// Call the removeMatchOnlyFields method for Lead
SObject result = SummitEventsContactMatching.removeMatchOnlyFields(testLead, 'TestLeadMethod', mockMappings, 'Lead');

// Verify that the match-only field (Title) was removed
System.assertEquals(null, result.get('Title'), 'Title should be null after removeMatchOnlyFields');

// Verify that the regular field (Industry) was NOT removed
System.assertEquals('Technology', result.get('Industry'), 'Industry should still be Technology after removeMatchOnlyFields');

// Verify other fields remain intact
System.assertEquals('Test', result.get('FirstName'), 'FirstName should remain Test');
System.assertEquals('Lead', result.get('LastName'), 'LastName should remain Lead');
System.assertEquals('testlead@example.com', result.get('Email'), 'Email should remain testlead@example.com');
System.assertEquals('Test Company', result.get('Company'), 'Company should remain Test Company');

Test.stopTest();
}

@IsTest
static void testRemoveMatchOnlyFieldsForAccount() {
// Only run this test if Person Accounts are enabled
Boolean personAccountsEnabled = SummitEventsShared.personAccountsEnabled();
if (!personAccountsEnabled) {
// Skip this test in orgs without Person Accounts
System.assert(true, 'Skipping Person Account test - Person Accounts not enabled');
return;
}

// Create a mock Account (for Person Account testing)
Account testAccount = new Account(
Name = 'Test Account',
Industry = 'Education',
Type = 'Prospect'
);

// Create mock mappings with Account-specific fields
String namespace = SummitEventsNamespace.StrTokenNSPrefix('');
Map<String, List<SObject>> mockMappings = new Map<String, List<SObject>>();
List<Summit_Events_Person_Matching_Mapping__mdt> accountMappingList = new List<Summit_Events_Person_Matching_Mapping__mdt>();

// Create a match-only mapping for Account (should be removed)
Summit_Events_Person_Matching_Mapping__mdt matchOnlyMapping = new Summit_Events_Person_Matching_Mapping__mdt(
DeveloperName = 'Type_Match_Only',
MasterLabel = 'Type Match Only',
Source_Type__c = 'Field',
Person_Account_Field_API_Name__c = 'Type',
Person_Account_Matching_Method__c = 'TestAccountMethod',
Matching_Only__c = true
);
accountMappingList.add(matchOnlyMapping);

// Create a regular mapping (should be kept)
Summit_Events_Person_Matching_Mapping__mdt regularMapping = new Summit_Events_Person_Matching_Mapping__mdt(
DeveloperName = 'Industry_Regular',
MasterLabel = 'Industry Regular',
Source_Type__c = 'Field',
Person_Account_Field_API_Name__c = 'Industry',
Person_Account_Matching_Method__c = 'TestAccountMethod',
Matching_Only__c = false
);
accountMappingList.add(regularMapping);

mockMappings.put('TestAccountMethod', accountMappingList);

Test.startTest();
// Verify fields are set before calling removeMatchOnlyFields
System.assertEquals('Prospect', testAccount.Type, 'Type should be Prospect before removal');
System.assertEquals('Education', testAccount.Industry, 'Industry should be Education before removal');

// Call the removeMatchOnlyFields method for Account
SObject result = SummitEventsContactMatching.removeMatchOnlyFields(testAccount, 'TestAccountMethod', mockMappings, 'Account');

// Verify that the match-only field (Type) was removed
System.assertEquals(null, result.get('Type'), 'Type should be null after removeMatchOnlyFields');

// Verify that the regular field (Industry) was NOT removed
System.assertEquals('Education', result.get('Industry'), 'Industry should still be Education after removeMatchOnlyFields');

// Verify other fields remain intact
System.assertEquals('Test Account', result.get('Name'), 'Name should remain Test Account');

Test.stopTest();
}

@IsTest
static void testRemoveMatchOnlyFieldsWithNoMappings() {
// Test case where no mappings exist for the method
Contact testContact = new Contact(
FirstName = 'Test',
LastName = 'Contact',
Email = 'test@example.com',
Title = 'Manager'
);

Map<String, List<SObject>> mockMappings = new Map<String, List<SObject>>();

Test.startTest();
// Call the removeMatchOnlyFields method with non-existent method name
SObject result = SummitEventsContactMatching.removeMatchOnlyFields(testContact, 'NonExistentMethod', mockMappings, 'Contact');

// Verify that nothing changed when no mappings exist
System.assertEquals('Manager', result.get('Title'), 'Title should remain Manager when no mappings exist');
System.assertEquals('Test', result.get('FirstName'), 'FirstName should remain Test');
System.assertEquals('Contact', result.get('LastName'), 'LastName should remain Contact');

Test.stopTest();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class SummitEventsRegistration_TEST {
email2.Event__c = seaTestInstances[1].Event__c;
email2.Action_Status__c = 'Registered';
email2.Action_Sub_status__c = 'In Progress';
email2.Email_Content__c = 'Sample text here {!Registrant_Last_Name__c} {!Add_To_Calendar_Link__c}';
email2.Email_Content__c = 'Sample text here {!Registrant_Last_Name__c} {!Add_To_Calendar_Link__c} {!Registrant_QR_Code_Image_URL__c}';
email2.Letterhead_HTML__c = 'Letterhead goes here<br/>[[DONT_DELETE_CONTENT_HERE]]';
email2.BCC_Email__c = 'bcc@example.com';
insert email2;
Expand Down