From 6280c9be455d37ba1f6d9778d6bf9932a4ca9fc7 Mon Sep 17 00:00:00 2001 From: salesforce-suyash-more Date: Wed, 31 Jul 2024 15:32:12 +0530 Subject: [PATCH 1/3] Changes made in BDI_DataImportService.cls to update contact fields Code added in BDI_DataImportService.cls to ensure all relevant fields of contact are updated --- .../default/classes/BDI_DataImportService.cls | 74 +++++++++++++++++-- 1 file changed, 67 insertions(+), 7 deletions(-) diff --git a/force-app/main/default/classes/BDI_DataImportService.cls b/force-app/main/default/classes/BDI_DataImportService.cls index 46dffa4d66c..722bef5dc49 100644 --- a/force-app/main/default/classes/BDI_DataImportService.cls +++ b/force-app/main/default/classes/BDI_DataImportService.cls @@ -1333,11 +1333,11 @@ global with sharing class BDI_DataImportService { dataImport.Account1Imported__c = acc.Id; } } - // set c1's primary affilation + // Set C1's fields first if (dataImport.Account1Imported__c != null) { Contact c1 = ContactFromDi(dataImport, 1); - if (c1 != null && c1.Primary_Affiliation__c != dataImport.Account1Imported__c) { - c1.Primary_Affiliation__c = dataImport.Account1Imported__c; + if (c1 != null) { + updateContactFieldsForImport(c1, dataImport, 'Contact1_'); if (mapConIdToConUpdate.get(c1.Id) == null) { mapConIdToConUpdate.put(c1.Id, c1); } @@ -1345,6 +1345,27 @@ global with sharing class BDI_DataImportService { } } + // Update contacts to ensure all relevant fields are updated + if (mapConIdToConUpdate.size() > 0) { + UTIL_DMLService.updateRecords(mapConIdToConUpdate.values()); + } + + // Set C1's primary affiliation separately to avoid conflicts + for (DataImport__c dataImport : listDI) { + if (dataImport.Account1Imported__c != null) { + Contact c1 = ContactFromDi(dataImport, 1); + if (c1 != null && c1.Primary_Affiliation__c != dataImport.Account1Imported__c) { + c1.Primary_Affiliation__c = dataImport.Account1Imported__c; + mapConIdToConUpdate.put(c1.Id, c1); + } + } + } + + // Now update the Contacts again to set their Affiliations + if (mapConIdToConUpdate.size() > 0) { + UTIL_DMLService.updateRecords(mapConIdToConUpdate.values()); + } + // create/update our A2's listAccUpsert.clear(); listDIUpsert.clear(); @@ -1403,11 +1424,11 @@ global with sharing class BDI_DataImportService { dataImport.Account2Imported__c = acc.Id; } } - // set c2's primary affilation + // Set C2's fields first if (dataImport.Account2Imported__c != null) { Contact c2 = ContactFromDi(dataImport, 2); - if (c2 != null && c2.Primary_Affiliation__c != dataImport.Account2Imported__c) { - c2.Primary_Affiliation__c = dataImport.Account2Imported__c; + if (c2 != null) { + updateContactFieldsForImport(c2, dataImport, 'Contact2_'); if (mapConIdToConUpdate.get(c2.Id) == null) { mapConIdToConUpdate.put(c2.Id, c2); } @@ -1415,12 +1436,51 @@ global with sharing class BDI_DataImportService { } } - // now update the Contacts to create their Affiliations + // Update contacts to ensure all relevant fields are updated + if (mapConIdToConUpdate.size() > 0) { + UTIL_DMLService.updateRecords(mapConIdToConUpdate.values()); + } + + // Set C2's primary affiliation separately to avoid conflicts + for (DataImport__c dataImport : listDI) { + if (dataImport.Account2Imported__c != null) { + Contact c2 = ContactFromDi(dataImport, 2); + if (c2 != null && c2.Primary_Affiliation__c != dataImport.Account2Imported__c) { + c2.Primary_Affiliation__c = dataImport.Account2Imported__c; + mapConIdToConUpdate.put(c2.Id, c2); + } + } + } + // now update the Contacts again to set their Affiliations if (mapConIdToConUpdate.size() > 0) { UTIL_DMLService.updateRecords(mapConIdToConUpdate.values()); } } + private void updateContactFieldsForImport(Contact contact, DataImport__c dataImport, String contactPrefix) { + if (dataImport.get(contactPrefix + 'Home_Phone__c') != null) { + contact.HomePhone = (String) dataImport.get(contactPrefix + 'Home_Phone__c'); + } + if (dataImport.get(contactPrefix + 'Work_Phone__c') != null) { + contact.Phone = (String) dataImport.get(contactPrefix + 'Work_Phone__c'); + } + if (dataImport.get(contactPrefix + 'Mobile_Phone__c') != null) { + contact.MobilePhone = (String) dataImport.get(contactPrefix + 'Mobile_Phone__c'); + } + if (dataImport.get(contactPrefix + 'Other_Phone__c') != null) { + contact.OtherPhone = (String) dataImport.get(contactPrefix + 'Other_Phone__c'); + } + if (dataImport.get(contactPrefix + 'Personal_Email__c') != null) { + contact.Email = (String) dataImport.get(contactPrefix + 'Personal_Email__c'); + } + if (dataImport.get(contactPrefix + 'Work_Email__c') != null) { + contact.npe01__WorkEmail__c = (String) dataImport.get(contactPrefix + 'Work_Email__c'); + } + if (dataImport.get(contactPrefix + 'Alternate_Email__c') != null) { + contact.npe01__AlternateEmail__c = (String) dataImport.get(contactPrefix + 'Alternate_Email__c'); + } + } + /******************************************************************************************************* * @description returns the field name of the Account CustomID field for Account1 or Account2 in the * Data Import object. From fd08a7b2e0da1d439f351685afe19f3f9e03512e Mon Sep 17 00:00:00 2001 From: salesforce-suyash-more Date: Mon, 5 Aug 2024 14:40:27 +0530 Subject: [PATCH 2/3] test method added in BDI_DataImportService_TEST.cls test method 'testImportAccounts' added in BDI_DataImportService_TEST.cls --- .../classes/BDI_DataImportService_TEST.cls | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/force-app/main/default/classes/BDI_DataImportService_TEST.cls b/force-app/main/default/classes/BDI_DataImportService_TEST.cls index 79688b55642..7936a983da6 100644 --- a/force-app/main/default/classes/BDI_DataImportService_TEST.cls +++ b/force-app/main/default/classes/BDI_DataImportService_TEST.cls @@ -239,6 +239,145 @@ private with sharing class BDI_DataImportService_TEST { BDI_DataImportService.anyFieldsPopulatedForObjectMapping(testDI1, testFieldMap, fieldsToIgnore2)); } + @isTest + private static void testImportAccounts() { + // Create test Data Import Settings + Data_Import_Settings__c diSettings = new Data_Import_Settings__c( + Field_Mapping_Method__c = 'Data Import Field Mapping', + Donation_Matching_Rule__c = 'Donation_Amount__c;Donation_Date__c', + Donation_Matching_Behavior__c = 'ExactMatchOrCreate' + ); + insert diSettings; + + // Create test data imports using UTIL_UnitTestData_TEST + List testDataImports = UTIL_UnitTestData_TEST.createDIRecordsInANewGEBatch(50); + for (Integer i = 0; i < testDataImports.size(); i++) { + testDataImports[i].Account1_Name__c = 'Test Account ' + i; + testDataImports[i].Contact1_Firstname__c = 'FirstName' + i; + testDataImports[i].Contact1_Lastname__c = 'LastName' + i; + testDataImports[i].Contact1_Personal_Email__c = 'email' + i + '@example.com'; + testDataImports[i].Account2_Name__c = 'Test Account 2 ' + i; + testDataImports[i].Contact2_Firstname__c = 'FirstName2' + i; + testDataImports[i].Contact2_Lastname__c = 'LastName2' + i; + testDataImports[i].Contact2_Personal_Email__c = 'email2' + i + '@example.com'; + testDataImports[i].Contact2_Work_Email__c = 'workemail2' + i + '@example.com'; + testDataImports[i].Contact2_Alternate_Email__c = 'alt2' + i + '@example.com'; + testDataImports[i].Contact2_Mobile_Phone__c = '222-333-4444'; + testDataImports[i].Contact2_Other_Phone__c = '555-666-7777'; + testDataImports[i].Contact2_Personal_Email__c = 'email2' + i + '@example.com'; + testDataImports[i].Contact1_Firstname__c = 'FirstName2' + i; + testDataImports[i].Contact1_Lastname__c = 'LastName2' + i; + testDataImports[i].Contact1_Personal_Email__c = 'email2' + i + '@example.com'; + testDataImports[i].Contact1_Work_Email__c = 'workemail2' + i + '@example.com'; + testDataImports[i].Contact1_Alternate_Email__c = 'alt2' + i + '@example.com'; + testDataImports[i].Contact1_Mobile_Phone__c = '222-333-4444'; + testDataImports[i].Contact1_Other_Phone__c = '555-666-7777'; + testDataImports[i].Contact1_Personal_Email__c = 'email2' + i + '@example.com'; + } + insert testDataImports; + + // Extract batch ID from the first DataImport record + Id batchId = testDataImports[0].NPSP_Data_Import_Batch__c; + + // Create an instance of BDI_PerfLogger with required parameters + Integer countRecords = testDataImports.size(); + BDI_PerfLogger perfLogger = new BDI_PerfLogger(batchId, countRecords); + + // Create an instance of BDI_DataImportService + BDI_DataImportService service = new BDI_DataImportService(false, BDI_MappingServiceAdvanced.getInstance()); + service.listDI = testDataImports; + + // Inject the data import settings and performance logger + service.injectDataImportSettings(diSettings); + BDI_DataImportService.injectPerfLogger(perfLogger); + + // Create test Data Import records + List testDataImportss = new List(); + for (Integer i = 0; i < 5; i++) { + DataImport__c dataImport = new DataImport__c( + NPSP_Data_Import_Batch__c = testDataImports[0].NPSP_Data_Import_Batch__c, + Account1_Name__c = 'Test Account ' + i, + Contact1_Firstname__c = 'FirstName' + i, + Contact1_Lastname__c = 'LastName' + i, + Contact1_Personal_Email__c = 'email' + i + '@example.com', + Account2_Name__c = 'Test Account 2 ' + i, + Contact2_Firstname__c = 'FirstName2' + i, + Contact2_Lastname__c = 'LastName2' + i, + Contact2_Personal_Email__c = 'email2' + i + '@example.com', + Status__c = 'Ready' // Adding a status to avoid null status + ); + testDataImportss.add(dataImport); + } + insert testDataImportss; + + service.listDI = testDataImportss; + + // Create Accounts to ensure matching + List accounts = new List(); + for (Integer i = 0; i < 5; i++) { + Account acc = new Account( + Name = 'Test Account ' + i + ); + accounts.add(acc); + } + insert accounts; + + // Create Contacts to ensure matching + List contacts = new List(); + for (Integer i = 0; i < 5; i++) { + Contact con1 = new Contact( + FirstName = 'FirstName' + i, + LastName = 'LastName' + i, + Email = 'email' + i + '@example.com', + AccountId = accounts[i].Id + ); + Contact con2 = new Contact( + FirstName = 'FirstName2' + i, + LastName = 'LastName2' + i, + Email = 'email2' + i + '@example.com', + AccountId = accounts[i].Id + ); + contacts.add(con1); + contacts.add(con2); + } + insert contacts; + + // Assign created contact IDs to the data import records + for (Integer i = 0; i < 5; i++) { + testDataImportss[i].Contact1Imported__c = contacts[i*2].Id; + testDataImportss[i].Contact2Imported__c = contacts[i*2+1].Id; + } + update testDataImportss; + + // Ensure the service has the necessary contact service + BDI_ContactService contactService = new BDI_ContactService(service); + service.contactService = contactService; + + // Explicitly set mapDIIdToC1 to ensure contacts are available + for (DataImport__c dataImport : testDataImportss) { + for (Contact con : contacts) { + if (con.Id == dataImport.Contact1Imported__c) { + contactService.mapDIIdToC1.put(dataImport.Id, con); + } + if (con.Id == dataImport.Contact2Imported__c) { + contactService.mapDIIdToC2.put(dataImport.Id, con); + } + } + } + + // Call the method to be tested + Test.startTest(); + service.importAccounts(); + Test.stopTest(); + + // Add assertions to verify the Account and Contact records were created/updated as expected + List accounts1 = [SELECT Id, Name, Phone FROM Account WHERE Name LIKE 'Test Account%']; + System.assert(accounts1.size() > 0, 'Accounts should be created'); + + List contactList = [SELECT Id, FirstName, LastName, Email FROM Contact WHERE LastName LIKE 'LastName%']; + System.assert(contactList.size() > 0, 'Contacts should be created'); + } + // Helpers //////////// From 4b438a4d0514e436bce6e782743e52ad11e405ff Mon Sep 17 00:00:00 2001 From: salesforce-suyash-more Date: Mon, 5 Aug 2024 16:04:30 +0530 Subject: [PATCH 3/3] made properties test visible --- force-app/main/default/classes/BDI_ContactService.cls | 4 ++-- force-app/main/default/classes/BDI_DataImportService.cls | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/force-app/main/default/classes/BDI_ContactService.cls b/force-app/main/default/classes/BDI_ContactService.cls index d315585fa9f..c36bdbd7c0e 100644 --- a/force-app/main/default/classes/BDI_ContactService.cls +++ b/force-app/main/default/classes/BDI_ContactService.cls @@ -55,12 +55,12 @@ public with sharing class BDI_ContactService { /******************************************************************************************************* * @description cached map to get Contact1 for a DI */ - private Map mapDIIdToC1; + @TestVisible private Map mapDIIdToC1; /******************************************************************************************************* * @description cached map to get Contact2 for a DI */ - private Map mapDIIdToC2; + @TestVisible private Map mapDIIdToC2; /******************************************************************************************************* * @description map that holds multiple DIKeys for each Contact diff --git a/force-app/main/default/classes/BDI_DataImportService.cls b/force-app/main/default/classes/BDI_DataImportService.cls index 722bef5dc49..116715ceae8 100644 --- a/force-app/main/default/classes/BDI_DataImportService.cls +++ b/force-app/main/default/classes/BDI_DataImportService.cls @@ -416,7 +416,7 @@ global with sharing class BDI_DataImportService { /******************************************************************************************************* * @description holds the Contact Service class for use during processing */ - private BDI_ContactService contactService { get; private set; } + @TestVisible private BDI_ContactService contactService { get; private set; } /******************************************************************************************************* * @description holds the Additional Object Service class for use during processing @@ -1260,6 +1260,7 @@ global with sharing class BDI_DataImportService { * @description importing or updating Account1 and Account2, and setting the contacts' Primary Affiliation. * @return void */ + @TestVisible private void importAccounts() { // first, try to match our existing Accounts