From 58f777196c95222c1bd443e9c715f8e29a122a9a Mon Sep 17 00:00:00 2001 From: Chris Rolfe <31963724+cjrolfe@users.noreply.github.com> Date: Fri, 5 Apr 2024 09:07:43 +0100 Subject: [PATCH] Merge pull request #160 * Platform Event Created * Update Animal_Shelter_Starter.permissionset-meta.xml * Trigger Flows for PE * Controller Created * Controller Test Class * Badge Component * Update animalBadge.js * Added Test Component * Updates * Updates to PE * Updates to Flow * Removed Test Component * Final Updates * Update AnimalBadgeController.cls * Final Updates * Update animalBadge.css * Update animalBadge.html --- .../default/classes/AnimalBadgeController.cls | 73 +++++++++++++++++++ .../AnimalBadgeController.cls-meta.xml | 5 ++ .../classes/AnimalBadgeControllerTest.cls | 51 +++++++++++++ .../AnimalBadgeControllerTest.cls-meta.xml | 5 ++ .../Animal_Record_Page.flexipage-meta.xml | 6 ++ ...Action_Create_Platform_Event.flow-meta.xml | 58 +++++++++++++++ ..._Alert_Create_Platform_Event.flow-meta.xml | 58 +++++++++++++++ ...dition_Create_Platform_Event.flow-meta.xml | 58 +++++++++++++++ .../animalBadge/__tests__/animalBadge.test.js | 25 +++++++ .../default/lwc/animalBadge/animalBadge.css | 13 ++++ .../default/lwc/animalBadge/animalBadge.html | 24 ++++++ .../default/lwc/animalBadge/animalBadge.js | 68 +++++++++++++++++ .../lwc/animalBadge/animalBadge.js-meta.xml | 21 ++++++ .../Badge_Update_Event__e.object-meta.xml | 9 +++ .../fields/Record_ID__c.field-meta.xml | 14 ++++ .../fields/Update_Type__c.field-meta.xml | 14 ++++ ...mal_Shelter_Starter.permissionset-meta.xml | 9 +++ 17 files changed, 511 insertions(+) create mode 100644 force-app/main/default/classes/AnimalBadgeController.cls create mode 100644 force-app/main/default/classes/AnimalBadgeController.cls-meta.xml create mode 100644 force-app/main/default/classes/AnimalBadgeControllerTest.cls create mode 100644 force-app/main/default/classes/AnimalBadgeControllerTest.cls-meta.xml create mode 100644 force-app/main/default/flows/Animal_Action_Create_Platform_Event.flow-meta.xml create mode 100644 force-app/main/default/flows/Animal_Alert_Create_Platform_Event.flow-meta.xml create mode 100644 force-app/main/default/flows/Condition_Create_Platform_Event.flow-meta.xml create mode 100644 force-app/main/default/lwc/animalBadge/__tests__/animalBadge.test.js create mode 100644 force-app/main/default/lwc/animalBadge/animalBadge.css create mode 100644 force-app/main/default/lwc/animalBadge/animalBadge.html create mode 100644 force-app/main/default/lwc/animalBadge/animalBadge.js create mode 100644 force-app/main/default/lwc/animalBadge/animalBadge.js-meta.xml create mode 100644 force-app/main/default/objects/Badge_Update_Event__e/Badge_Update_Event__e.object-meta.xml create mode 100644 force-app/main/default/objects/Badge_Update_Event__e/fields/Record_ID__c.field-meta.xml create mode 100644 force-app/main/default/objects/Badge_Update_Event__e/fields/Update_Type__c.field-meta.xml diff --git a/force-app/main/default/classes/AnimalBadgeController.cls b/force-app/main/default/classes/AnimalBadgeController.cls new file mode 100644 index 00000000..e2b687a0 --- /dev/null +++ b/force-app/main/default/classes/AnimalBadgeController.cls @@ -0,0 +1,73 @@ +/** + * @File Name : AnimalBadgeController.cls + * @Description : + * @Author : Chris Rolfe (Salesforce) + * @Last Modified By : + * @Last Modified On : + * @Modification Log : + * Ver Date Author Modification + * 1.0 01/04/2024 Chris Rolfe (Salesforce) Initial Version +**/ +public with sharing class AnimalBadgeController { + + @AuraEnabled(cacheable=true) + public static Map getRelatedBadges(Id animalId) { + Map badges = new Map{ + 'Alert' => false, + 'Condition' => false, + 'Nutrition' => false, + 'Exercise' => false, + 'Treatment' => false, + 'Vaccination' => false + }; + + // Check for Alerts with no end date + if(Schema.sObjectType.animalshelters__Animal_Alert__c.isAccessible() && Schema.sObjectType.animalshelters__Animal_Alert__c.fields.Animalshelters__End_Date_Time__c.isAccessible()) { + List alerts = [SELECT Id + FROM animalshelters__Animal_Alert__c + WHERE animalshelters__Animal__c = :animalId + AND animalshelters__End_Date_Time__c = null + WITH SECURITY_ENFORCED]; + // System.debug(alerts); + if(!alerts.isEmpty()) { + badges.put('Alert', true); + } + } + + // Check for Condiitons that have no end date + if(Schema.sObjectType.animalshelters__Condition__c.isAccessible() && Schema.sObjectType.animalshelters__Condition__c.fields.Animalshelters__End_Date_Time__c.isAccessible()) { + List conditions = [SELECT Id + FROM animalshelters__Condition__c + WHERE animalshelters__Animal__c = :animalId + AND animalshelters__End_Date_Time__c = null + WITH SECURITY_ENFORCED]; + // System.debug(conditions); + if(!conditions.isEmpty()) { + badges.put('Condition', true); + } + } + + // Check for Action Records and RecordTypes + if(Schema.sObjectType.animalshelters__Animal_Action__c.isAccessible() && Schema.sObjectType.animalshelters__Animal_Action__c.fields.animalshelters__Treatment_Type__c.isAccessible() && Schema.sObjectType.animalshelters__Animal_Action__c.fields.animalshelters__Action_Completed__c.isAccessible()) { + List actions = [SELECT Id, RecordType.Name, animalshelters__Treatment_Type__c + FROM animalshelters__Animal_Action__c + WHERE animalshelters__Animal__c = :animalId + AND animalshelters__Action_Completed__c = false + WITH SECURITY_ENFORCED]; + // System.debug(actions); + for(animalshelters__Animal_Action__c action : actions) { + if(action.RecordType.Name == 'Nutrition') { + badges.put('Nutrition', true); + } else if(action.RecordType.Name == 'Exercise'){ + badges.put('Exercise', true); + } else if(action.RecordType.Name == 'Treatment' && action.animalshelters__Treatment_Type__c == 'Vaccination'){ + badges.put('Vaccination', true); + } else if(action.RecordType.Name == 'Treatment' && action.animalshelters__Treatment_Type__c != 'Vaccination'){ + badges.put('Treatment', true); + } + } + //System.debug(badges); + } + return badges; + } +} \ No newline at end of file diff --git a/force-app/main/default/classes/AnimalBadgeController.cls-meta.xml b/force-app/main/default/classes/AnimalBadgeController.cls-meta.xml new file mode 100644 index 00000000..019e8509 --- /dev/null +++ b/force-app/main/default/classes/AnimalBadgeController.cls-meta.xml @@ -0,0 +1,5 @@ + + + 59.0 + Active + \ No newline at end of file diff --git a/force-app/main/default/classes/AnimalBadgeControllerTest.cls b/force-app/main/default/classes/AnimalBadgeControllerTest.cls new file mode 100644 index 00000000..ff300c96 --- /dev/null +++ b/force-app/main/default/classes/AnimalBadgeControllerTest.cls @@ -0,0 +1,51 @@ +@isTest +private class AnimalBadgeControllerTest { + + @IsTest static void testNoBadges() { + // Set Up Test Data + animalshelters__Animal__c testAnimal = new animalshelters__Animal__c(animalshelters__Animal_Name__c = 'Test Animal', animalshelters__Date_of_Arrival__c = Date.today()); + insert testAnimal; + + //Test with no badges + Test.startTest(); + Map badges = AnimalBadgeController.getRelatedBadges(testAnimal.Id); + Test.stopTest(); + + //Verify Results + System.assertEquals(false, badges.get('Alert'), 'Expected no alert'); + System.assertEquals(false, badges.get('Condition'), 'Expected no Condition'); + System.assertEquals(false, badges.get('Nutrition'), 'Expected no Nutrition'); + System.assertEquals(false, badges.get('Exercise'), 'Expected no Exercise'); + System.assertEquals(false, badges.get('Treatment'), 'Expected no Treatment'); + } + + @IsTest static void testWithBadges() { + // Set Up Test Data + animalshelters__Animal__c testAnimal = new animalshelters__Animal__c(animalshelters__Animal_Name__c = 'Test Animal', animalshelters__Date_of_Arrival__c = Date.today()); + insert testAnimal; + + animalshelters__Animal_Alert__c alert = new animalshelters__Animal_Alert__c(animalshelters__Animal__c = testAnimal.Id, animalshelters__Start_Date_Time__c = Date.today(), animalshelters__Type__c = 'General', animalshelters__Alert_Message__c = 'Test'); + animalshelters__Condition__c condition = new animalshelters__Condition__c(animalshelters__Animal__c = testAnimal.Id, animalshelters__Start_Date__c = Date.today()); + insert alert; + insert condition; + + //Create a dummy record type for Action + Id recordTypeId = Schema.SObjectType.animalshelters__Animal_Action__c.getRecordTypeInfosByName().get('Exercise').getRecordTypeId(); + animalshelters__Animal_Action__c action = new animalshelters__Animal_Action__c(animalshelters__Animal__c = testAnimal.Id, animalshelters__Date_Time_of_Action__c= Date.today(), animalshelters__Description__c = 'Test', RecordTypeId = recordTypeId); + insert action; + + //Test with Badges + Test.startTest(); + Map badges = AnimalBadgeController.getRelatedBadges(testAnimal.Id); + Test.stopTest(); + + //Verify Results + System.assertEquals(true, badges.get('Alert'), 'Expected an alert'); + System.assertEquals(true, badges.get('Condition'), 'Expected a Condition'); + System.assertEquals(false, badges.get('Nutrition'), 'Expected no Nutrition'); + System.assertEquals(true, badges.get('Exercise'), 'Expected an Exercise'); + System.assertEquals(false, badges.get('Treatment'), 'Expected no Treatment'); + + } + +} \ No newline at end of file diff --git a/force-app/main/default/classes/AnimalBadgeControllerTest.cls-meta.xml b/force-app/main/default/classes/AnimalBadgeControllerTest.cls-meta.xml new file mode 100644 index 00000000..f5e18fd1 --- /dev/null +++ b/force-app/main/default/classes/AnimalBadgeControllerTest.cls-meta.xml @@ -0,0 +1,5 @@ + + + 60.0 + Active + diff --git a/force-app/main/default/flexipages/Animal_Record_Page.flexipage-meta.xml b/force-app/main/default/flexipages/Animal_Record_Page.flexipage-meta.xml index 52358f43..871abb60 100644 --- a/force-app/main/default/flexipages/Animal_Record_Page.flexipage-meta.xml +++ b/force-app/main/default/flexipages/Animal_Record_Page.flexipage-meta.xml @@ -2317,6 +2317,12 @@ Facet + + + animalBadge + animalshelters_animalBadge + + diff --git a/force-app/main/default/flows/Animal_Action_Create_Platform_Event.flow-meta.xml b/force-app/main/default/flows/Animal_Action_Create_Platform_Event.flow-meta.xml new file mode 100644 index 00000000..96c1244e --- /dev/null +++ b/force-app/main/default/flows/Animal_Action_Create_Platform_Event.flow-meta.xml @@ -0,0 +1,58 @@ + + + 60.0 + [Animal Shelter Starter] - Creates a Platform Event for Badge Update on record create or update + Default + Animal Action - Create Platform Event {!$Flow.CurrentDateTime} + + + BuilderType + + LightningFlowBuilder + + + + CanvasMode + + AUTO_LAYOUT_CANVAS + + + + OriginBuilderType + + LightningFlowBuilder + + + AutoLaunchedFlow + + Create_Platform_Event + + 176 + 323 + + Record_ID__c + + $Record.Animal__r.Id + + + + Update_Type__c + + Action + + + Badge_Update_Event__e + true + + + 50 + 0 + + Create_Platform_Event + + Animal_Action__c + CreateAndUpdate + RecordAfterSave + + Active + diff --git a/force-app/main/default/flows/Animal_Alert_Create_Platform_Event.flow-meta.xml b/force-app/main/default/flows/Animal_Alert_Create_Platform_Event.flow-meta.xml new file mode 100644 index 00000000..1ca67f14 --- /dev/null +++ b/force-app/main/default/flows/Animal_Alert_Create_Platform_Event.flow-meta.xml @@ -0,0 +1,58 @@ + + + 60.0 + [Animal Shelters Starter] - Creates a Platform Event for Badge Update when Alert records are Created or Updated + Default + Animal Alert - Create Platform Event {!$Flow.CurrentDateTime} + + + BuilderType + + LightningFlowBuilder + + + + CanvasMode + + AUTO_LAYOUT_CANVAS + + + + OriginBuilderType + + LightningFlowBuilder + + + AutoLaunchedFlow + + Create_Platform_Event + + 176 + 323 + + Record_ID__c + + $Record.Animal__r.Id + + + + Update_Type__c + + Alert + + + Badge_Update_Event__e + true + + + 50 + 0 + + Create_Platform_Event + + Animal_Alert__c + CreateAndUpdate + RecordAfterSave + + Active + diff --git a/force-app/main/default/flows/Condition_Create_Platform_Event.flow-meta.xml b/force-app/main/default/flows/Condition_Create_Platform_Event.flow-meta.xml new file mode 100644 index 00000000..bbf515c3 --- /dev/null +++ b/force-app/main/default/flows/Condition_Create_Platform_Event.flow-meta.xml @@ -0,0 +1,58 @@ + + + 60.0 + [Animal Shelter Starter] - Creates a Platform Event for Badge Update on record create or update + Default + Condition - Create Platform Event {!$Flow.CurrentDateTime} + + + BuilderType + + LightningFlowBuilder + + + + CanvasMode + + AUTO_LAYOUT_CANVAS + + + + OriginBuilderType + + LightningFlowBuilder + + + AutoLaunchedFlow + + Create_Platform_Event + + 176 + 323 + + Record_ID__c + + $Record.Animal__r.Id + + + + Update_Type__c + + Condition + + + Badge_Update_Event__e + true + + + 50 + 0 + + Create_Platform_Event + + Condition__c + CreateAndUpdate + RecordAfterSave + + Active + diff --git a/force-app/main/default/lwc/animalBadge/__tests__/animalBadge.test.js b/force-app/main/default/lwc/animalBadge/__tests__/animalBadge.test.js new file mode 100644 index 00000000..475f66c7 --- /dev/null +++ b/force-app/main/default/lwc/animalBadge/__tests__/animalBadge.test.js @@ -0,0 +1,25 @@ +import { createElement } from 'lwc'; +import AnimalBadge from 'c/animalBadge'; + +describe('c-animal-badge', () => { + afterEach(() => { + // The jsdom instance is shared across test cases in a single file so reset the DOM + while (document.body.firstChild) { + document.body.removeChild(document.body.firstChild); + } + }); + + it('TODO: test case generated by CLI command, please fill in test logic', () => { + // Arrange + const element = createElement('c-animal-badge', { + is: AnimalBadge + }); + + // Act + document.body.appendChild(element); + + // Assert + // const div = element.shadowRoot.querySelector('div'); + expect(1).toBe(1); + }); +}); \ No newline at end of file diff --git a/force-app/main/default/lwc/animalBadge/animalBadge.css b/force-app/main/default/lwc/animalBadge/animalBadge.css new file mode 100644 index 00000000..534fd2d9 --- /dev/null +++ b/force-app/main/default/lwc/animalBadge/animalBadge.css @@ -0,0 +1,13 @@ +.badge { + display: inline-block; + padding: 2px; + border-radius: 5px; + color: white; + margin-right: 10px; +} +.alert { background-color: red; } +.condition { background-color: grey; } +.nutrition { background-color: green; } +.exercise { background-color: orange; } +.treatment { background-color: blue; } +.vaccination { background-color: pink; } \ No newline at end of file diff --git a/force-app/main/default/lwc/animalBadge/animalBadge.html b/force-app/main/default/lwc/animalBadge/animalBadge.html new file mode 100644 index 00000000..7d1eaebc --- /dev/null +++ b/force-app/main/default/lwc/animalBadge/animalBadge.html @@ -0,0 +1,24 @@ + \ No newline at end of file diff --git a/force-app/main/default/lwc/animalBadge/animalBadge.js b/force-app/main/default/lwc/animalBadge/animalBadge.js new file mode 100644 index 00000000..fd8de6cf --- /dev/null +++ b/force-app/main/default/lwc/animalBadge/animalBadge.js @@ -0,0 +1,68 @@ +/** + * @description : Animal Badges - Displays badges for various Animal Statuses + * @author : Chris Rolfe + * @group : + * @last modified on : 01-04-2024 + * @last modified by : Chris Rolfe +**/ +import { LightningElement, api, wire } from 'lwc'; +import { subscribe, unsubscribe, onError, setDebugFlag, isEmpEnabled } from 'lightning/empApi'; +import { refreshApex } from '@salesforce/apex'; +import getRelatedBadges from '@salesforce/apex/AnimalBadgeController.getRelatedBadges'; + +export default class AnimalBadge extends LightningElement { + @api recordId; + badges = {}; + channelName = '/event/Badge_Update_Event__e'; + subscription = {}; + wiredBadgesResult; + + //Get initial statuses of Badges for current Animal + @wire(getRelatedBadges, {animalId: '$recordId'}) + wiredBadges(response) { + this.wiredBadgesResult = response; + const { data, error } = response; + if (data) { + this.badges = data; + console.log('Badges: ', data); + } else if (error) { + console.error(error); + } + } + + // Initial Component Setup + connectedCallback() { + this.registerErrorListener(); + this.subscribeToPE(); + } + + disconnectedCallback() { + // Invoke unsubscribe + unsubscribe(this.subscription, response => { + console.log('Unsubscribed from: ', response.channel); + }); + } + + // Subscribe to Platform Event + subscribeToPE() { + const messageCallback = (response) => { + console.log('New message received: ', JSON.stringify(response)); + // Check if the event is for the current Animal + if (response.data.payload.animalshelters__Record_ID__c === this.recordId){ + refreshApex(this.wiredBadgesResult); + } + }; + subscribe(this.channelName, -1, messageCallback).then(response => { + console.log('Subscription request sent to: ', JSON.stringify(response.channel)); + this.subscription = response; + }); + } + + registerErrorListener() { + // Invoke onError empApi method + onError((error) => { + console.log('Received error from server: ', JSON.stringify(error)); + // Error contains the server-side error + }); + } +} \ No newline at end of file diff --git a/force-app/main/default/lwc/animalBadge/animalBadge.js-meta.xml b/force-app/main/default/lwc/animalBadge/animalBadge.js-meta.xml new file mode 100644 index 00000000..100b8c12 --- /dev/null +++ b/force-app/main/default/lwc/animalBadge/animalBadge.js-meta.xml @@ -0,0 +1,21 @@ + + + 59.0 + true +Animal Badges +Displays badges for various Animal Statuses + + lightning__RecordPage + + + + + animalshelters__Animal__c + + + + + + + + \ No newline at end of file diff --git a/force-app/main/default/objects/Badge_Update_Event__e/Badge_Update_Event__e.object-meta.xml b/force-app/main/default/objects/Badge_Update_Event__e/Badge_Update_Event__e.object-meta.xml new file mode 100644 index 00000000..77eaa244 --- /dev/null +++ b/force-app/main/default/objects/Badge_Update_Event__e/Badge_Update_Event__e.object-meta.xml @@ -0,0 +1,9 @@ + + + Deployed + [Animal Shelter Starter] - Used to capture changes to Animal Badge statuses. Triggered by Flows on Animal Action, Alert and Condition objects. Passes Animal Record Id + HighVolume + + Badge Updates + PublishAfterCommit + diff --git a/force-app/main/default/objects/Badge_Update_Event__e/fields/Record_ID__c.field-meta.xml b/force-app/main/default/objects/Badge_Update_Event__e/fields/Record_ID__c.field-meta.xml new file mode 100644 index 00000000..6fa09b28 --- /dev/null +++ b/force-app/main/default/objects/Badge_Update_Event__e/fields/Record_ID__c.field-meta.xml @@ -0,0 +1,14 @@ + + + Record_ID__c + The Record ID of the Animal related to the object initiating the event + false + false + false + false + + 18 + false + Text + false + diff --git a/force-app/main/default/objects/Badge_Update_Event__e/fields/Update_Type__c.field-meta.xml b/force-app/main/default/objects/Badge_Update_Event__e/fields/Update_Type__c.field-meta.xml new file mode 100644 index 00000000..6a661d8a --- /dev/null +++ b/force-app/main/default/objects/Badge_Update_Event__e/fields/Update_Type__c.field-meta.xml @@ -0,0 +1,14 @@ + + + Update_Type__c + Future Use - The Update Type + false + false + false + false + + 100 + false + Text + false + diff --git a/force-app/main/default/permissionsets/Animal_Shelter_Starter.permissionset-meta.xml b/force-app/main/default/permissionsets/Animal_Shelter_Starter.permissionset-meta.xml index e64d5580..0053eacb 100644 --- a/force-app/main/default/permissionsets/Animal_Shelter_Starter.permissionset-meta.xml +++ b/force-app/main/default/permissionsets/Animal_Shelter_Starter.permissionset-meta.xml @@ -1530,6 +1530,15 @@ Assessment__c true + + true + false + false + true + false + Badge_Update_Event__e + false + true true