Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

W-14398313 data import incorrectly update contact fields #7246

Merged
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
4 changes: 2 additions & 2 deletions force-app/main/default/classes/BDI_ContactService.cls
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ public with sharing class BDI_ContactService {
/*******************************************************************************************************
* @description cached map to get Contact1 for a DI
*/
private Map<Id, Contact> mapDIIdToC1;
@TestVisible private Map<Id, Contact> mapDIIdToC1;

/*******************************************************************************************************
* @description cached map to get Contact2 for a DI
*/
private Map<Id, Contact> mapDIIdToC2;
@TestVisible private Map<Id, Contact> mapDIIdToC2;

/*******************************************************************************************************
* @description map that holds multiple DIKeys for each Contact
Expand Down
77 changes: 69 additions & 8 deletions force-app/main/default/classes/BDI_DataImportService.cls
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1333,18 +1334,39 @@ 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);
}
}
}
}

// 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();
Expand Down Expand Up @@ -1403,24 +1425,63 @@ 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);
}
}
}
}

// 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.
Expand Down
139 changes: 139 additions & 0 deletions force-app/main/default/classes/BDI_DataImportService_TEST.cls
Original file line number Diff line number Diff line change
Expand Up @@ -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<DataImport__c> 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<DataImport__c> testDataImportss = new List<DataImport__c>();
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<Account> accounts = new List<Account>();
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<Contact> contacts = new List<Contact>();
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<Account> accounts1 = [SELECT Id, Name, Phone FROM Account WHERE Name LIKE 'Test Account%'];
System.assert(accounts1.size() > 0, 'Accounts should be created');

List<Contact> contactList = [SELECT Id, FirstName, LastName, Email FROM Contact WHERE LastName LIKE 'LastName%'];
System.assert(contactList.size() > 0, 'Contacts should be created');
}

// Helpers
////////////

Expand Down
Loading