diff --git a/dev-tools/update-dependencies b/dev-tools/update-dependencies index 9bc0a96..6cf7fb4 100755 --- a/dev-tools/update-dependencies +++ b/dev-tools/update-dependencies @@ -7,5 +7,5 @@ rm -Rf fflib-apex-common/ git clone https://github.com/apex-enterprise-patterns/fflib-apex-mocks.git git clone https://github.com/apex-enterprise-patterns/fflib-apex-common.git -sfdx force:source:deploy -p ./fflib-apex-mocks/sfdx-source -sfdx force:source:deploy -p ./fflib-apex-common/sfdx-source \ No newline at end of file +sfdx project deploy start -c --source-dir ./fflib-apex-mocks/sfdx-source +sfdx project deploy start -c --source-dir ./fflib-apex-common/sfdx-source \ No newline at end of file diff --git a/sfdx-source/apex-extensions/main/triggerHandler/classes/fflib_TriggerContext.cls b/sfdx-source/apex-extensions/main/triggerHandler/classes/fflib_TriggerContext.cls index 5062870..89bdeea 100644 --- a/sfdx-source/apex-extensions/main/triggerHandler/classes/fflib_TriggerContext.cls +++ b/sfdx-source/apex-extensions/main/triggerHandler/classes/fflib_TriggerContext.cls @@ -95,6 +95,41 @@ public virtual inherited sharing class fflib_TriggerContext return triggerOperation; } + public Set getChangedFields() + { + Set result = new Set(); + for (SObject newRecord : getRecords()) + { + Id recordId = (Id) newRecord.get('Id'); + if (getExistingRecords() == null || !getExistingRecords().containsKey(recordId)) continue; + + SObject oldRecord = getExistingRecords().get(recordId); + Map oldValuesByFieldName = oldRecord.getPopulatedFieldsAsMap(); + Map newValuesByFieldName = newRecord.getPopulatedFieldsAsMap(); + Set fieldNames = new Set(); + fieldNames.addAll(oldValuesByFieldName.keySet()); + fieldNames.addAll(newValuesByFieldName.keySet()); + for (String fieldName : fieldNames) + { + if (oldValuesByFieldName.containsKey(fieldName) == false + && newValuesByFieldName.containsKey(fieldName) == false) continue; + + if ((oldValuesByFieldName.containsKey(fieldName) == false + && newValuesByFieldName.containsKey(fieldName)) + || + (oldValuesByFieldName.containsKey(fieldName) + && newValuesByFieldName.containsKey(fieldName) == false) + || + (oldValuesByFieldName.get(fieldName) != newValuesByFieldName.get(fieldName)) + ) + { + result.add(fieldName); + } + } + } + return result; + } + /** * Detects whether any values in context records have changed for given field as string * Returns list of SObject records that have changes in the specified fields diff --git a/sfdx-source/apex-extensions/tests/classes/triggerHandler/fflib_TriggerHandlerTest.cls b/sfdx-source/apex-extensions/tests/classes/triggerHandler/fflib_TriggerHandlerTest.cls index 053a8db..b1e5d00 100644 --- a/sfdx-source/apex-extensions/tests/classes/triggerHandler/fflib_TriggerHandlerTest.cls +++ b/sfdx-source/apex-extensions/tests/classes/triggerHandler/fflib_TriggerHandlerTest.cls @@ -137,7 +137,40 @@ private class fflib_TriggerHandlerTest // THEN it should only return the changed records Map resultMap = new Map(result); System.Assert.areEqual(1, result.size()); - System.Assert.istrue(resultMap.containsKey(idLuke)); + System.Assert.isTrue(resultMap.containsKey(idLuke)); + } + + @IsTest + private static void itShouldReturnTheChangedFields() + { + // GIVEN a domain with old and changed records + + Id idLuke = fflib_IDGenerator.generate(Account.SObjectType); + Id idHan = fflib_IDGenerator.generate(Account.SObjectType); + Id idLeia = fflib_IDGenerator.generate(Account.SObjectType); + List oldRecords = new List + { + new Account(Id = idLuke, Name = 'Luke', Description = 'Jedi'), + new Account(Id = idHan, Name = 'Han', Description = 'Pilot'), + new Account(Id = idLeia, Name = 'Leia') + }; + + List newRecords = oldRecords.deepClone(true, true, true); + newRecords.get(0).Name = 'Luke SkyWalker'; + newRecords.get(0).Description = 'Jedi Master'; + newRecords.get(1).Name = 'Han Solo'; + newRecords.get(1).Description = null; + + fflib_TriggerContext ctx = new fflib_TriggerContext(newRecords); + ctx.existingRecords = new Map(oldRecords); + + // WHEN we create a domain with ExistingRecords and request the changed records + Set result = ctx.getChangedFields(); + + // THEN it should only return the changed records + System.Assert.areEqual(2, result.size()); + System.Assert.isTrue(result.contains('Name')); + System.Assert.isTrue(result.contains('Description')); } @IsTest